(opts: BootServerOptions)
| 209 | } |
| 210 | |
| 211 | async function bootServerInner(opts: BootServerOptions): Promise<BootedServer> { |
| 212 | const skipAutoInit = opts.skipAutoInit ?? false; |
| 213 | const attachUi = opts.attachUiSibling ?? true; |
| 214 | const idleMsOption = opts.idleShutdownMs; |
| 215 | const log = opts.log ?? getLogger('boot'); |
| 216 | |
| 217 | const envLockKind = |
| 218 | process.env.OK_LOCK_KIND === 'mcp-spawned' || process.env.OK_LOCK_KIND === 'interactive' |
| 219 | ? process.env.OK_LOCK_KIND |
| 220 | : undefined; |
| 221 | const lockKind = opts.lockKind ?? envLockKind ?? 'interactive'; |
| 222 | |
| 223 | const { createServer: createHttpServer } = await import('node:http'); |
| 224 | const { updateServerLockPort } = await import('./server-lock.ts'); |
| 225 | |
| 226 | let didAutoInit = false; |
| 227 | if (!skipAutoInit && opts.autoInitFn) { |
| 228 | try { |
| 229 | const initResult = await opts.autoInitFn(); |
| 230 | didAutoInit = Boolean(initResult); |
| 231 | } catch (err) { |
| 232 | log.warn({ err }, 'autoInitFn failed'); |
| 233 | } |
| 234 | } |
| 235 | |
| 236 | const projectDir = opts.projectDir ?? opts.contentDir; |
| 237 | const okDir = resolve(projectDir, OK_DIR); |
| 238 | const configPath = resolve(okDir, 'config.yml'); |
| 239 | if (!existsSync(configPath)) { |
| 240 | const okDirExists = existsSync(okDir); |
| 241 | throw new MissingOkConfigError(okDirExists ? 'config' : 'okdir', projectDir); |
| 242 | } |
| 243 | const gitignorePath = resolve(okDir, '.gitignore'); |
| 244 | if (!existsSync(gitignorePath)) { |
| 245 | console.warn( |
| 246 | `[boot] Note: ${OK_DIR}/.gitignore is missing — per-machine state files in ${OK_DIR}/ may show up as untracked changes. Run \`ok init\` to add the recommended ignore entries.`, |
| 247 | ); |
| 248 | } |
| 249 | |
| 250 | const preflight = opts.gitPreflight ?? assertGitAvailable; |
| 251 | try { |
| 252 | if (opts.gitEnabled !== false) preflight(); |
| 253 | } catch (err) { |
| 254 | if (err instanceof GitNotAvailableError || err instanceof GitTooOldError) { |
| 255 | const detectedVersion = err instanceof GitTooOldError ? err.detected : ''; |
| 256 | const reason = err instanceof GitTooOldError ? 'too_old' : 'not_available'; |
| 257 | emitPreflightFailureSpan(err); |
| 258 | log.warn( |
| 259 | { |
| 260 | event: 'git_preflight_fail', |
| 261 | platform: err.platform, |
| 262 | reason, |
| 263 | detectedVersion, |
| 264 | }, |
| 265 | reason === 'not_available' ? 'git binary not found' : 'git binary too old', |
| 266 | ); |
| 267 | process.stderr.write(`${err.message}\n`); |
| 268 | } |
no test coverage detected