@agimon-ai/doompi 0.0.1-alpha.88 → 0.0.1-alpha.89
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/builders/server/runtime.cjs +10 -0
- package/dist/src/builders/server/runtime.cjs.map +1 -1
- package/dist/src/builders/server/runtime.mjs +10 -0
- package/dist/src/builders/server/runtime.mjs.map +1 -1
- package/dist/src/cli/server/run.cjs +54 -11
- package/dist/src/cli/server/run.cjs.map +1 -1
- package/dist/src/cli/server/run.mjs +54 -11
- package/dist/src/cli/server/run.mjs.map +1 -1
- package/package.json +14 -14
|
@@ -197,6 +197,15 @@ async function runServerRuntime(options, runtime) {
|
|
|
197
197
|
requestSessionApi: (scope, request) => requestSessionApi(scope, request),
|
|
198
198
|
...computerUse === void 0 ? {} : { computerUse }
|
|
199
199
|
});
|
|
200
|
+
const stopPersistSessionNames = hub.onEvent((event) => {
|
|
201
|
+
if (event.kind !== "upsert") return;
|
|
202
|
+
const record = openSessions.list().find((entry) => entry.sessionId === event.session.id);
|
|
203
|
+
if (record === void 0 || record.name === event.session.name) return;
|
|
204
|
+
openSessions.add({
|
|
205
|
+
...record,
|
|
206
|
+
name: event.session.name
|
|
207
|
+
});
|
|
208
|
+
});
|
|
200
209
|
let harnessContext;
|
|
201
210
|
let cockpit;
|
|
202
211
|
let remoteRuntime;
|
|
@@ -772,6 +781,7 @@ async function runServerRuntime(options, runtime) {
|
|
|
772
781
|
}
|
|
773
782
|
} finally {
|
|
774
783
|
shuttingDown = true;
|
|
784
|
+
stopPersistSessionNames();
|
|
775
785
|
clearInterval(eventLoopMonitor);
|
|
776
786
|
await bounded(telemetry.recordEvent("doompi_server.shutdown"), "shutdown telemetry", notice);
|
|
777
787
|
await Promise.allSettled([cockpit?.close()]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.cjs","names":["createServerTelemetry","path","piAgentDirectory","createWorkspaceRegistry","createOpenSessionRegistry","createHarnessTelemetry","createHeadlessSessionManager","publishHeadlessSelectionStatus","readMinorModeCatalog","createComputerUseBinding","createHeadlessHub","fs","resolveSessionIdentity","crypto","os","globalDoomConfigDirectory","createWebCompositions","readSyncRegistration","resolveServerBundleSource","loadMajorModesConfig","resolveLayers","loadServerBundle","loadMcpBundle","readSyncDrift","readSyncState","createRemoteRuntime","WebSocket","findRepositoryRoot","resolveSyncLocation","HARNESS_STATE_POINTER","HARNESS_STATE_KEYS","filterHookDisabledLayers","serveSessionApis","buildHarnessContext","serveHeadlessServer","listSavedSessions","readSqliteTranscript"],"sources":["../../../../src/builders/server/runtime.ts"],"sourcesContent":["import crypto from 'node:crypto';\nimport fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\n\nimport { globalDoomConfigDirectory } from '@agimon-ai/doompi-config/config';\nimport { filterHookDisabledLayers, loadMajorModesConfig, resolveLayers } from '@agimon-ai/doompi-config/majorModes';\nimport { createHeadlessHub, type HeadlessHub } from '@agimon-ai/doompi-core/headlessHub';\nimport { serveHeadlessServer } from '@agimon-ai/doompi-core/headlessServer';\nimport type { HeadlessSessionHost, HeadlessSessionHostOptions } from '@agimon-ai/doompi-core/headlessSessionHost';\nimport { createHeadlessSessionManager } from '@agimon-ai/doompi-core/headlessSessionManager';\nimport {\n createOpenSessionRegistry,\n createWorkspaceRegistry,\n listSavedSessions,\n readSqliteTranscript,\n} from '@agimon-ai/doompi-core/history';\nimport type { OpenSessionRecord } from '@agimon-ai/doompi-core/history';\nimport type {\n DoomHubSessionApiRequest,\n DoomHubSessionCreateRequest,\n DoomHubSessionScope,\n} from '@agimon-ai/doompi-core/hubChannel';\nimport { loadMcpBundle, type LoadedMcpBundle } from '@agimon-ai/doompi-core/mcpFacet';\nimport { serveSessionApis, type PackageApiServer } from '@agimon-ai/doompi-core/packageApiServer';\nimport { piAgentDirectory } from '@agimon-ai/doompi-core/piSettings';\nimport { createRemoteRuntime, type RemoteRuntime } from '@agimon-ai/doompi-core/remoteRuntime';\nimport type { HeadlessSessionManager } from '@agimon-ai/doompi-core/runtimeHeadlessSessionManager';\nimport { createHarnessTelemetry } from '@agimon-ai/doompi-core/runtimeLogSinkTelemetry';\nimport { loadServerBundle, resolveServerBundleSource } from '@agimon-ai/doompi-core/serverFacet';\nimport { createServerTelemetry } from '@agimon-ai/doompi-core/serverTelemetry';\nimport { resolveSyncLocation } from '@agimon-ai/doompi-core/syncLocation';\nimport { readSyncRegistration } from '@agimon-ai/doompi-core/syncRegistration';\nimport { createWebCompositions } from '@agimon-ai/doompi-core/webCompositions';\nimport { readMinorModeCatalog } from '@agimon-ai/doompi-minor-mode';\nimport WebSocket from 'ws';\n\nimport { HARNESS_STATE_KEYS, HARNESS_STATE_POINTER } from '../../composition/harnessState';\nimport { findRepositoryRoot } from '../../composition/repository';\nimport { readSyncDrift } from '../../composition/syncDrift';\nimport { readSyncState } from '../../composition/syncState';\nimport { buildHarnessContext } from '../cli/harnessContext';\nimport { createComputerUseBinding } from './computerUseBinding';\nimport { publishHeadlessSelectionStatus } from './selectionStatus';\nimport { resolveSessionIdentity } from './sessionArguments';\nimport type { ServeOptions, ServerRuntimeEnvironment } from './types';\nconst TELEMETRY_SHUTDOWN_TIMEOUT_MS = 2_000;\n\nasync function bounded(operation: Promise<unknown>, label: string, notice: (message: string) => void): Promise<void> {\n let timeout: NodeJS.Timeout | undefined;\n try {\n await Promise.race([\n operation,\n new Promise<void>((resolve) => {\n timeout = setTimeout(resolve, TELEMETRY_SHUTDOWN_TIMEOUT_MS);\n }),\n ]);\n } catch (error) {\n notice(`${label} failed: ${error instanceof Error ? error.message : String(error)}`);\n } finally {\n if (timeout) clearTimeout(timeout);\n }\n}\n\nexport async function runServerRuntime(options: ServeOptions, runtime: ServerRuntimeEnvironment): Promise<number> {\n const { cwd: baseCwd, environment: baseEnvironment, notice, resolveHarnessOptions, signal, syncWorkspace } = runtime;\n const telemetry = createServerTelemetry({ cwd: baseCwd, env: baseEnvironment, warn: notice });\n const serverDirectory = path.join(piAgentDirectory(baseEnvironment), 'server');\n const workspaces = createWorkspaceRegistry({ directory: serverDirectory, onNotice: notice });\n // Beside the journals it names, because a record pointing at a sessions\n // directory it is not stored next to is a record that can outlive its target.\n const openSessions = createOpenSessionRegistry({\n directory: serverDirectory,\n onNotice: notice,\n });\n let nextEventLoopTick = performance.now() + 1_000;\n const eventLoopMonitor = setInterval(() => {\n const now = performance.now();\n const delay = Math.max(0, now - nextEventLoopTick);\n nextEventLoopTick = now + 1_000;\n if (delay >= 100)\n void telemetry\n .recordEvent('doompi_server.event_loop_delay', { duration_ms: Math.round(delay) })\n .catch((error: unknown) => notice(`event loop telemetry failed: ${String(error)}`));\n }, 1_000);\n eventLoopMonitor.unref();\n const harnessTelemetry = createHarnessTelemetry({\n cwd: baseCwd,\n env: baseEnvironment,\n warn: notice,\n deferSpans: true,\n });\n const baseSessionManager = createHeadlessSessionManager({\n publishSelectionStatus: publishHeadlessSelectionStatus,\n contextGroups: (context) =>\n (readMinorModeCatalog(context)?.list() ?? [])\n .filter(({ state }) => state.activation === 'active')\n .map(({ descriptor }) => ({ id: descriptor.id, label: descriptor.label, kind: 'minor' })),\n });\n type SessionSetup = {\n cleanup: () => Promise<void>;\n bundle: Awaited<ReturnType<typeof loadServerBundle>>;\n mcpBundle: LoadedMcpBundle;\n };\n type SessionArtifacts = SessionSetup & { apis: PackageApiServer };\n const pendingSessions = new Map<string, SessionSetup>();\n const sessionArtifacts = new Map<string, SessionArtifacts>();\n let mountSessionApis:\n | ((options: HeadlessSessionHostOptions, host: HeadlessSessionHost) => Promise<PackageApiServer>)\n | undefined;\n /**\n * Shutdown runs every session through the same close path a user-initiated\n * close uses, so without this the registry would be emptied by the very event\n * it exists to survive.\n */\n let shuttingDown = false;\n\n const closeManagedSession = async (sessionId: string): Promise<void> => {\n if (!shuttingDown) openSessions.remove(sessionId);\n const artifacts = sessionArtifacts.get(sessionId);\n sessionArtifacts.delete(sessionId);\n webCompositions?.remove({ scope: 'session', sessionId });\n const failures: unknown[] = [];\n try {\n await artifacts?.apis.close();\n } catch (error) {\n failures.push(error);\n }\n try {\n await artifacts?.cleanup();\n } catch (error) {\n failures.push(error);\n }\n try {\n await baseSessionManager.closeSession(sessionId);\n } catch (error) {\n failures.push(error);\n }\n if (failures.length > 0) throw new AggregateError(failures, `Session '${sessionId}' shutdown failed`);\n };\n\n const sessionManager: HeadlessSessionManager = {\n async create(sessionOptions) {\n const setup = pendingSessions.get(sessionOptions.sessionId);\n let host: HeadlessSessionHost;\n try {\n host = await baseSessionManager.create(sessionOptions);\n } catch (error) {\n if (setup !== undefined && pendingSessions.delete(sessionOptions.sessionId))\n await setup.cleanup().catch((cleanupError: unknown) => notice(String(cleanupError)));\n throw error;\n }\n if (setup === undefined || mountSessionApis === undefined) return host;\n try {\n const apis = await mountSessionApis(sessionOptions, host);\n pendingSessions.delete(sessionOptions.sessionId);\n sessionArtifacts.set(sessionOptions.sessionId, { ...setup, apis });\n return host;\n } catch (error) {\n pendingSessions.delete(sessionOptions.sessionId);\n await baseSessionManager\n .closeSession(sessionOptions.sessionId)\n .catch((closeError: unknown) => notice(String(closeError)));\n await setup.cleanup().catch((cleanupError: unknown) => notice(String(cleanupError)));\n throw error;\n }\n },\n get: (sessionId) => baseSessionManager.get(sessionId),\n sessions: () => baseSessionManager.sessions(),\n closeSession: closeManagedSession,\n async close() {\n const ids = baseSessionManager.sessions().map((session) => session.runtime.sessionId);\n const outcomes = await Promise.allSettled(ids.map((id) => closeManagedSession(id)));\n const failures = outcomes\n .filter((outcome): outcome is PromiseRejectedResult => outcome.status === 'rejected')\n .map((outcome) => outcome.reason);\n if (failures.length > 0) throw new AggregateError(failures, 'Headless session shutdown failed');\n },\n };\n\n let requestSessionApi: (\n scope: DoomHubSessionScope,\n request: DoomHubSessionApiRequest,\n ) => Promise<Response> = async () => Response.json({ error: 'Session API unavailable.' }, { status: 404 });\n let openSession: (\n request: DoomHubSessionCreateRequest,\n sessionId?: string,\n ) => Promise<DoomHubSessionScope> = async () => {\n throw new Error('The cockpit session service is not ready.');\n };\n let admitWorkspace: (root: string) => Promise<{ id: string; root: string; available: boolean }> = async () => {\n throw new Error('Workspace admission is not ready.');\n };\n const computerUse = await createComputerUseBinding();\n let hub!: HeadlessHub;\n hub = createHeadlessHub({\n manager: sessionManager,\n admitWorkspace: (root) => admitWorkspace(root),\n onWorkspaceRemoved: (workspaceId) => {\n workspaces.remove(workspaceId);\n webCompositions?.remove({ scope: 'workspace', workspaceId });\n },\n createSession: (request) => openSession(request),\n sessionReservations: {\n read(id, parentSessionId) {\n if (!cockpit) throw new Error('Session setup is not ready.');\n return cockpit.sessionReservations.read(id, parentSessionId);\n },\n async prepare(id, parentSessionId, cwd) {\n if (!cockpit) throw new Error('Session setup is not ready.');\n return cockpit.sessionReservations.prepare(id, parentSessionId, cwd);\n },\n async complete(id, parentSessionId) {\n if (!cockpit) throw new Error('Session setup is not ready.');\n return cockpit.sessionReservations.complete(id, parentSessionId);\n },\n },\n onNotice: notice,\n hubToken: () => attachToken,\n requestSessionApi: (scope, request) => requestSessionApi(scope, request),\n ...(computerUse === undefined ? {} : { computerUse }),\n });\n let harnessContext: Awaited<ReturnType<typeof buildHarnessContext>> | undefined;\n let cockpit: Awaited<ReturnType<typeof serveHeadlessServer>> | undefined;\n let remoteRuntime: RemoteRuntime | undefined;\n let attachToken: string | undefined;\n let webCompositions: ReturnType<typeof createWebCompositions> | undefined;\n\n try {\n await telemetry.runInSpan('doompi_server.startup', {}, async () => {\n const token = fs.readFileSync(options.tokenFile, 'utf8').trim();\n if (!token) throw new Error('The attach token file is empty.');\n attachToken = token;\n\n const resolved = resolveSessionIdentity(options.agentArgs, {\n sessionId: options.sessionId ?? crypto.randomUUID(),\n sessionName: options.sessionName,\n });\n\n const homeDirectory = baseEnvironment.HOME ?? os.homedir();\n const globalRoot = globalDoomConfigDirectory(homeDirectory);\n webCompositions = createWebCompositions(path.join(globalRoot, 'server'), notice);\n const loadComposition = async (\n root: string,\n scope: 'global' | 'workspace' | 'session',\n selection?: { root: string; majorMode: string; activeLayers: string[] },\n ) => {\n const registration = readSyncRegistration(root, homeDirectory);\n const source = resolveServerBundleSource({ registration });\n if (source.kind !== 'descriptor')\n throw new Error(`Run the scoped DoomPi sync for '${root}' before opening it.`);\n const selected =\n selection ??\n (() => {\n const config = loadMajorModesConfig(root, homeDirectory);\n const majorMode = config.defaultMajorMode;\n return { root, majorMode, activeLayers: resolveLayers(config, majorMode) };\n })();\n return loadServerBundle(scope, {\n ...source,\n ...selected,\n retainCandidates: scope === 'session',\n onNotice: notice,\n });\n };\n const loadSessionMcp = async (\n root: string,\n selection: { majorMode: string; activeLayers: readonly string[] },\n ): Promise<LoadedMcpBundle> => {\n const registration = readSyncRegistration(root, homeDirectory);\n if (registration?.mcpBundle === undefined)\n throw new Error(`Run the scoped DoomPi sync for '${root}' before opening its MCP runtime.`);\n return loadMcpBundle({\n directory: path.dirname(registration.mcpBundle.path),\n generation: registration.generation,\n fingerprint: registration.mcpBundle.fingerprint,\n descriptorSha256: registration.mcpBundle.sha256,\n majorMode: selection.majorMode,\n activeLayers: selection.activeLayers,\n retainCandidates: true,\n onNotice: notice,\n });\n };\n const sharedApiContext = {\n homeDirectory,\n environment: baseEnvironment,\n hubToken: token,\n sessionService: hub.sessionService,\n directEvents: hub.directEvents,\n repositories: () =>\n hub.workspaces().map((workspace) => ({\n id: workspace.id,\n path: workspace.root,\n name: workspace.root.split('/').at(-1) ?? workspace.id,\n active: hub.snapshot().some((session) => session.workspaceId === workspace.id),\n })),\n resolveRepository: (id: string) => hub.workspaces().find((workspace) => workspace.id === id)?.root,\n readRepositorySync: (id: string) => {\n const root = hub.workspaces().find((workspace) => workspace.id === id)?.root;\n if (!root) return undefined;\n const drift = readSyncDrift({ repoRoot: root, homeDirectory, requireWebBundle: true });\n const state = readSyncState(root, homeDirectory);\n return { ...drift, mcpProjection: state?.fileState.mcpProjection };\n },\n onNotice: notice,\n };\n const globalBundle = await loadComposition(globalRoot, 'global');\n webCompositions.publishShell(readSyncRegistration(globalRoot, homeDirectory)!);\n remoteRuntime = createRemoteRuntime({\n homeDirectory,\n registrationToken: token,\n bundleTrust: () => webCompositions?.shellTrust(),\n onNotice: notice,\n forward: async (request) => {\n if (!cockpit || !attachToken)\n return Response.json({ error: 'The headless server is not ready.' }, { status: 503 });\n const from = new URL(request.url);\n const headers = new Headers(request.headers);\n headers.set('x-doompi-token', attachToken);\n return fetch(\n new URL(`${from.pathname}${from.search}`, cockpit.url),\n new Request(request, { headers, redirect: 'manual' }),\n );\n },\n connectProtocol: (pathname) => {\n if (!cockpit || !attachToken) throw new Error('The headless protocol listener is not ready.');\n const url = new URL(pathname, cockpit.url);\n url.protocol = 'ws:';\n return new WebSocket(url, { headers: { 'x-doompi-token': attachToken } });\n },\n });\n await hub.mountFacets(globalBundle.facets, {\n ...sharedApiContext,\n scope: 'global',\n remoteControl: { fetch: (request: Request) => remoteRuntime!.fetchLocal(request) },\n });\n webCompositions.publish(\n { scope: 'global' },\n readSyncRegistration(globalRoot, homeDirectory)!,\n hub.channelTypes(),\n );\n const admissions = new Map<string, Promise<{ id: string; root: string; available: boolean }>>();\n admitWorkspace = async (from) => {\n const root = fs.realpathSync(findRepositoryRoot(from));\n const id = resolveSyncLocation(root, homeDirectory).identity.worktreeId;\n const existing = hub.workspaces().find((workspace) => workspace.id === id);\n if (existing !== undefined && existing.available !== false) return { ...existing, available: true };\n const pending = admissions.get(id);\n if (pending) return pending;\n const wasRemembered = workspaces.list().some((workspace) => workspace.id === id);\n if (!wasRemembered) workspaces.add({ id, root });\n hub.registerWorkspace({ id, root, available: false });\n const admission = (async () => {\n const syncEnvironment: NodeJS.ProcessEnv = { ...baseEnvironment, DOOMPI_ROOT: root };\n for (const key of [HARNESS_STATE_POINTER, ...Object.values(HARNESS_STATE_KEYS)]) delete syncEnvironment[key];\n await syncWorkspace(root, syncEnvironment);\n const bundle = await loadComposition(root, 'workspace');\n await hub.mountFacets(bundle.facets, {\n ...sharedApiContext,\n scope: 'workspace',\n workspaceId: id,\n workspaceRoot: root,\n cwd: root,\n resolveRepository: (requestedId) => (requestedId === id ? root : undefined),\n });\n webCompositions?.publish(\n { scope: 'workspace', workspaceId: id },\n readSyncRegistration(root, homeDirectory)!,\n hub.channelTypes(),\n );\n return { id, root, available: true };\n })();\n admissions.set(id, admission);\n try {\n return await admission;\n } catch (error) {\n if (!wasRemembered) {\n await hub.removeWorkspace(id);\n workspaces.remove(id);\n }\n throw error;\n } finally {\n admissions.delete(id);\n }\n };\n for (const record of openSessions.list()) {\n if (workspaces.list().some((workspace) => workspace.id === record.workspaceId)) continue;\n try {\n const root = fs.realpathSync(findRepositoryRoot(record.cwd));\n const id = resolveSyncLocation(root, homeDirectory).identity.worktreeId;\n if (id === record.workspaceId) workspaces.add({ id, root });\n else\n notice(\n `Session '${record.sessionId}' no longer resolves to its recorded workspace; skipping registration.`,\n );\n } catch (error) {\n notice(\n `Session '${record.sessionId}' workspace could not be registered: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n for (const workspace of workspaces.list()) {\n hub.registerWorkspace({ ...workspace, available: false });\n try {\n const root = fs.realpathSync(findRepositoryRoot(workspace.root));\n const id = resolveSyncLocation(root, homeDirectory).identity.worktreeId;\n if (root !== workspace.root || id !== workspace.id) {\n notice(\n `Workspace '${workspace.root}' no longer resolves to its recorded identity; leaving it unavailable.`,\n );\n continue;\n }\n await admitWorkspace(workspace.root);\n } catch (error) {\n notice(\n `Workspace '${workspace.root}' could not be restored: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n\n const sessionHostOptions = (\n context: Awaited<ReturnType<typeof buildHarnessContext>>,\n bundle: Awaited<ReturnType<typeof loadServerBundle>>,\n mcpBundle: LoadedMcpBundle,\n identity: {\n sessionId: string;\n sessionName: string;\n parentSessionId?: string;\n sessionProvenance?: string;\n },\n workspaceId?: string,\n ): HeadlessSessionHostOptions => {\n const policyOptions = context.options;\n const sessionSelection = {\n root: policyOptions.repoRoot,\n majorMode: policyOptions.majorMode,\n activeLayers: context.selectedLayers,\n domains: policyOptions.domains,\n profile: context.profile,\n state: { 'minor-mode': [] },\n };\n return {\n cwd: policyOptions.cwd,\n repoRoot: policyOptions.repoRoot,\n sessionId: identity.sessionId,\n workspaceId: workspaceId ?? resolveSyncLocation(policyOptions.repoRoot, homeDirectory).identity.worktreeId,\n sessionName: identity.sessionName,\n webComposition: webCompositions?.publish(\n { scope: 'session', sessionId: identity.sessionId },\n readSyncRegistration(policyOptions.repoRoot, homeDirectory)!,\n hub.channelTypes(),\n ),\n ...(identity.parentSessionId === undefined ? {} : { parentSessionId: identity.parentSessionId }),\n ...(identity.sessionProvenance === undefined ? {} : { sessionProvenance: identity.sessionProvenance }),\n agentArgs: policyOptions.piArgs,\n environment: Object.freeze({ ...context.environment }),\n selection: sessionSelection,\n selectionOverrides: (['majorMode', 'domains', 'profile'] as const).filter((axis) => {\n const flag = axis === 'majorMode' ? '--major-mode' : `--${axis}`;\n return (\n identity.sessionId === resolved.identity.sessionId &&\n resolved.agentArgs.some((arg) => arg === flag || arg.startsWith(`${flag}=`))\n );\n }),\n inheritedSelection: () => {\n const environment = { ...baseEnvironment };\n for (const key of [HARNESS_STATE_POINTER, ...Object.values(HARNESS_STATE_KEYS)]) delete environment[key];\n const defaults = resolveHarnessOptions({\n args: ['--cwd', policyOptions.cwd],\n cwd: policyOptions.cwd,\n environment,\n });\n return { majorMode: defaults.majorMode, domains: defaults.domains, profile: defaults.profile };\n },\n candidates: bundle.descriptor.entries,\n mcpPlugins: mcpBundle.plugins,\n resolveSelection: (requested) => {\n const config = loadMajorModesConfig(policyOptions.repoRoot, policyOptions.homeDirectory);\n return {\n ...requested,\n activeLayers: filterHookDisabledLayers(\n config,\n resolveLayers(config, requested.majorMode),\n policyOptions.hooks,\n ),\n };\n },\n onNotice: notice,\n };\n };\n\n mountSessionApis = (sessionOptions, host) =>\n serveSessionApis({\n sessionId: sessionOptions.sessionId,\n cwd: sessionOptions.cwd,\n environment: sessionOptions.environment,\n directEvents: hub.directEvents,\n ...(computerUse === undefined\n ? {}\n : {\n computerUse: {\n get available() {\n return computerUse.available;\n },\n get enabled() {\n return computerUse.enabled === true;\n },\n authorize: (headers: Headers) => computerUse.authorize?.(headers) === true,\n claim: () => computerUse.claimSession?.(sessionOptions.sessionId),\n subscribe: (listener: () => void) => computerUse.subscribe?.(listener) ?? (() => undefined),\n },\n }),\n hubToken: token,\n sessionService: hub.sessionService,\n pluginRegistry: hub.pluginRegistry,\n apis: [],\n facets: pendingSessions.get(sessionOptions.sessionId)?.bundle.facets ?? [],\n workspaceId: sessionOptions.workspaceId,\n workspaceRoot: sessionOptions.repoRoot,\n homeDirectory,\n mountChannel: (channel) => {\n const dispose = hub.registerChannel(channel, { scope: 'session', sessionId: sessionOptions.sessionId });\n return { mounted: true, dispose };\n },\n prepareFacets: host.prepareFacets,\n activateFacets: host.activateFacets,\n canDispatch: host.canDispatch,\n telemetry,\n onNotice: notice,\n });\n\n requestSessionApi = async (scope, request) => {\n const session = hub.session(scope.sessionId);\n const artifacts = sessionArtifacts.get(scope.sessionId);\n if (session === undefined || session.cwd !== scope.cwd || artifacts === undefined)\n return Response.json({ error: 'Session not found.' }, { status: 404 });\n if (!/^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/u.test(request.basePath))\n return Response.json({ error: 'Invalid session API base path.' }, { status: 400 });\n if (!request.path.startsWith('/') || request.path.startsWith('//') || request.path.includes('#'))\n return Response.json({ error: 'Invalid session API path.' }, { status: 400 });\n const body = request.body === null || request.body === undefined ? undefined : request.body;\n return artifacts.apis.request(\n new Request(`http://doompi.local/api/plugins/${request.basePath}${request.path}`, {\n method: request.method,\n headers: request.headers,\n ...(body === undefined ? {} : { body }),\n ...(request.signal === undefined ? {} : { signal: request.signal }),\n }),\n );\n };\n\n if (!options.noSession) {\n harnessContext = await buildHarnessContext(\n resolveHarnessOptions({ args: resolved.agentArgs, cwd: baseCwd, environment: baseEnvironment }),\n harnessTelemetry,\n );\n const activeHarnessContext = harnessContext;\n try {\n await admitWorkspace(harnessContext.options.repoRoot);\n const initialBundle = await loadComposition(harnessContext.options.repoRoot, 'session', {\n root: harnessContext.options.repoRoot,\n majorMode: harnessContext.options.majorMode,\n activeLayers: harnessContext.selectedLayers,\n });\n const initialMcpBundle = await loadSessionMcp(harnessContext.options.repoRoot, {\n majorMode: harnessContext.options.majorMode,\n activeLayers: harnessContext.selectedLayers,\n });\n pendingSessions.set(resolved.identity.sessionId, {\n cleanup: () => activeHarnessContext.cleanup(),\n bundle: initialBundle,\n mcpBundle: initialMcpBundle,\n });\n await hub.create(sessionHostOptions(harnessContext, initialBundle, initialMcpBundle, resolved.identity));\n } catch (error) {\n pendingSessions.delete(resolved.identity.sessionId);\n await activeHarnessContext.cleanup().catch((cleanupError: unknown) => notice(String(cleanupError)));\n throw error;\n }\n await bounded(harnessTelemetry.flush(), 'initial composition telemetry flush', notice);\n }\n\n const reservedOpens = new Map<string, Promise<DoomHubSessionScope>>();\n openSession = async (request, sessionId) => {\n request.signal?.throwIfAborted();\n if (request.reservationId !== undefined) {\n if (!request.parentSessionId || !cockpit) throw new Error('A reserved session requires its owning parent.');\n const prepared = await cockpit.sessionReservations.prepare(\n request.reservationId,\n request.parentSessionId,\n request.cwd,\n );\n if (sessionId !== undefined && sessionId !== prepared.sessionId)\n throw new Error('Reserved session identity cannot change.');\n sessionId = prepared.sessionId;\n const existing = hub.session(sessionId);\n if (existing) {\n if (existing.cwd !== prepared.cwd || existing.parentSessionId !== request.parentSessionId)\n throw new Error('Reserved session target does not match.');\n return { sessionId, cwd: existing.cwd, workspaceId: existing.workspaceId };\n }\n if (openSessions.list().some((record) => record.sessionId === sessionId))\n throw new Error('Resume the recorded session instead of recreating it.');\n const pending = reservedOpens.get(sessionId);\n if (pending) return pending;\n request = { ...request, cwd: prepared.cwd };\n }\n const identity = {\n sessionId: sessionId ?? crypto.randomUUID(),\n sessionName: request.name,\n parentSessionId: request.parentSessionId,\n sessionProvenance: request.sessionProvenance,\n };\n const inheritedWorkspaceId =\n request.sessionProvenance === 'worktree' && request.parentSessionId\n ? (hub.session(request.parentSessionId)?.workspaceId ??\n openSessions.list().find((record) => record.sessionId === request.parentSessionId)?.workspaceId)\n : undefined;\n if (request.sessionProvenance === 'worktree' && inheritedWorkspaceId === undefined)\n throw new Error('Worktree session requires its parent workspace.');\n const start = (async (): Promise<DoomHubSessionScope> => {\n const childIdentity = resolveSessionIdentity([], identity);\n const childEnvironment = { ...baseEnvironment };\n for (const key of [HARNESS_STATE_POINTER, ...Object.values(HARNESS_STATE_KEYS)]) delete childEnvironment[key];\n const childContext = await buildHarnessContext(\n resolveHarnessOptions({\n args: ['--cwd', request.cwd, ...childIdentity.agentArgs],\n cwd: request.cwd,\n environment: childEnvironment,\n }),\n harnessTelemetry,\n );\n try {\n if (inheritedWorkspaceId === undefined) {\n await admitWorkspace(childContext.options.repoRoot);\n } else {\n const inheritedWorkspace = hub\n .workspaces()\n .find((workspace) => workspace.id === inheritedWorkspaceId && workspace.available !== false);\n if (inheritedWorkspace === undefined) throw new Error('Worktree parent workspace is unavailable.');\n const syncEnvironment: NodeJS.ProcessEnv = {\n ...baseEnvironment,\n DOOMPI_ROOT: childContext.options.repoRoot,\n };\n for (const key of [HARNESS_STATE_POINTER, ...Object.values(HARNESS_STATE_KEYS)])\n delete syncEnvironment[key];\n await syncWorkspace(childContext.options.repoRoot, syncEnvironment);\n }\n const bundle = await loadComposition(childContext.options.repoRoot, 'session', {\n root: childContext.options.repoRoot,\n majorMode: childContext.options.majorMode,\n activeLayers: childContext.selectedLayers,\n });\n const mcpBundle = await loadSessionMcp(childContext.options.repoRoot, {\n majorMode: childContext.options.majorMode,\n activeLayers: childContext.selectedLayers,\n });\n request.signal?.throwIfAborted();\n pendingSessions.set(identity.sessionId, { cleanup: () => childContext.cleanup(), bundle, mcpBundle });\n const created = await hub.create(\n sessionHostOptions(childContext, bundle, mcpBundle, identity, inheritedWorkspaceId),\n );\n request.signal?.throwIfAborted();\n if (created.workspaceId !== undefined) {\n const saved = openSessions.add({\n sessionId: created.id,\n workspaceId: created.workspaceId,\n cwd: created.cwd,\n name: created.name,\n createdAt: created.createdAt,\n ...(created.parentSessionId === undefined ? {} : { parentSessionId: created.parentSessionId }),\n ...(created.sessionProvenance === undefined ? {} : { sessionProvenance: created.sessionProvenance }),\n });\n if (saved === false) throw new Error('The new session could not be durably recorded.');\n }\n return { sessionId: identity.sessionId, cwd: childContext.options.cwd, workspaceId: created.workspaceId };\n } catch (error) {\n if (hub.session(identity.sessionId)) await hub.closeSession(identity.sessionId);\n else {\n pendingSessions.delete(identity.sessionId);\n await childContext.cleanup().catch((cleanupError: unknown) => notice(String(cleanupError)));\n }\n throw error;\n }\n })();\n if (request.reservationId !== undefined) reservedOpens.set(identity.sessionId, start);\n try {\n return await start;\n } finally {\n if (reservedOpens.get(identity.sessionId) === start) reservedOpens.delete(identity.sessionId);\n }\n };\n });\n\n const workspaceResumes = new Map<string, Promise<string>>();\n cockpit = await serveHeadlessServer({\n port: options.webPort,\n headlessHub: hub,\n token: attachToken,\n sessionMcpPublicOrigin: () => remoteRuntime?.remote.publicOrigin(),\n sessionMcpStateDir: serverDirectory,\n sessionMcpPublicOriginRevision: () => remoteRuntime?.remote.publicOriginRevision() ?? 0,\n isSessionPersisted: (sessionId, cwd) =>\n openSessions.list().some((record) => record.sessionId === sessionId && record.cwd === cwd),\n workspaceHistory: (workspaceId) => {\n const workspaceRoot = hub\n .workspaces()\n .find((workspace) => workspace.id === workspaceId && workspace.available !== false)?.root;\n if (!workspaceRoot) throw new Error('Workspace not found.');\n return listSavedSessions(\n path.join(serverDirectory, 'sessions'),\n workspaceRoot,\n new Set(hub.snapshot().map((active) => active.id)),\n );\n },\n resumeWorkspaceSession: async (workspaceId, targetSessionId) => {\n const key = `${workspaceId}\\0${targetSessionId}`;\n const pending = workspaceResumes.get(key);\n if (pending) return pending;\n const resume = (async () => {\n const workspaceRoot = hub\n .workspaces()\n .find((workspace) => workspace.id === workspaceId && workspace.available !== false)?.root;\n if (!workspaceRoot) throw new Error('Workspace not found.');\n const saved = await listSavedSessions(\n path.join(serverDirectory, 'sessions'),\n workspaceRoot,\n new Set(hub.snapshot().map((active) => active.id)),\n );\n const target = saved.find((item) => item.id === targetSessionId);\n if (!target) throw new Error('Saved Pi thread not found in this workspace.');\n await openSession({ cwd: workspaceRoot, name: target.name ?? 'untitled' }, target.id);\n return target.id;\n })();\n workspaceResumes.set(key, resume);\n try {\n return await resume;\n } finally {\n workspaceResumes.delete(key);\n }\n },\n sessionHistory: (session) => {\n const workspaceRoot = hub.workspaces().find((workspace) => workspace.id === session.workspaceId)?.root;\n if (!workspaceRoot) throw new Error('Session workspace not found.');\n return listSavedSessions(\n path.join(piAgentDirectory(baseEnvironment), 'server', 'sessions'),\n workspaceRoot,\n new Set(hub.snapshot().map((active) => active.id)),\n );\n },\n readDormantTranscript: (record, request, context) => {\n const workspaceRoot = hub.workspaces().find((workspace) => workspace.id === record.workspaceId)?.root;\n if (!workspaceRoot) throw new Error('Saved transcript unavailable.');\n return readSqliteTranscript(\n path.join(piAgentDirectory(baseEnvironment), 'server', 'sessions', `${record.sessionId}.sqlite`),\n request,\n context,\n { sessionId: record.sessionId, workspaceRoot },\n );\n },\n restartSession: async (session) => {\n const workspaceRoot = hub.workspaces().find((workspace) => workspace.id === session.workspaceId)?.root;\n if (!workspaceRoot) throw new Error('Session workspace not found.');\n const syncEnvironment: NodeJS.ProcessEnv = { ...baseEnvironment, DOOMPI_ROOT: workspaceRoot };\n for (const key of [HARNESS_STATE_POINTER, ...Object.values(HARNESS_STATE_KEYS)]) delete syncEnvironment[key];\n try {\n await syncWorkspace(workspaceRoot, syncEnvironment);\n } catch (error) {\n notice(`Workspace sync failed before restart: ${error instanceof Error ? error.message : String(error)}`);\n throw new Error('Workspace sync failed; the session is still running.', { cause: error });\n }\n await hub.closeSession(session.id);\n await openSession(\n {\n cwd: session.cwd,\n name: session.name,\n ...(session.parentSessionId === undefined ? {} : { parentSessionId: session.parentSessionId }),\n ...(session.sessionProvenance === undefined ? {} : { sessionProvenance: session.sessionProvenance }),\n },\n session.id,\n );\n },\n resumeSession: async (session, targetSessionId) => {\n const workspaceRoot = hub.workspaces().find((workspace) => workspace.id === session.workspaceId)?.root;\n if (!workspaceRoot) throw new Error('Session workspace not found.');\n const saved = await listSavedSessions(\n path.join(piAgentDirectory(baseEnvironment), 'server', 'sessions'),\n workspaceRoot,\n new Set(hub.snapshot().map((active) => active.id)),\n );\n const target = saved.find((item) => item.id === targetSessionId);\n if (!target) throw new Error('Saved Pi thread not found in this workspace.');\n await hub.closeSession(session.id);\n await openSession({ cwd: session.cwd, name: target.name ?? 'untitled' }, target.id);\n return target.id;\n },\n dormantSessions: () => openSessions.list(),\n removeDormantSession: (record: OpenSessionRecord) => openSessions.remove(record.sessionId),\n reviveSession: async (record: OpenSessionRecord) => {\n // A failed wake may be transient, for example while another server still\n // owns the journal. Keep the record so the user can retry after resolving\n // the conflict instead of losing the session from the cockpit.\n await openSession(\n {\n cwd: record.cwd,\n name: record.name,\n ...(record.parentSessionId === undefined ? {} : { parentSessionId: record.parentSessionId }),\n ...(record.sessionProvenance === undefined ? {} : { sessionProvenance: record.sessionProvenance }),\n },\n record.sessionId,\n );\n },\n requestAsset: (request) => webCompositions?.request(request) ?? Promise.resolve(undefined),\n compositions: () => ({\n global: webCompositions?.get({ scope: 'global' }),\n publicKey: webCompositions?.publicKey(),\n shell: webCompositions?.shellTrust(),\n workspaces: hub.workspaces().map((workspace) => ({\n ...workspace,\n webComposition: webCompositions?.get({ scope: 'workspace', workspaceId: workspace.id }),\n })),\n }),\n telemetry,\n onNotice: notice,\n });\n notice(`protocol on ${cockpit.url}/api/ws`);\n let resolveShutdown!: (exitCode: number) => void;\n const shutdown = new Promise<number>((resolve) => {\n resolveShutdown = resolve;\n });\n const stop = (): void => resolveShutdown(0);\n signal.addEventListener('abort', stop, { once: true });\n if (signal.aborted) stop();\n try {\n return await shutdown;\n } finally {\n signal.removeEventListener('abort', stop);\n }\n } finally {\n shuttingDown = true;\n clearInterval(eventLoopMonitor);\n await bounded(telemetry.recordEvent('doompi_server.shutdown'), 'shutdown telemetry', notice);\n await Promise.allSettled([cockpit?.close()]);\n await bounded(remoteRuntime?.close() ?? Promise.resolve(), 'remote control shutdown', notice);\n try {\n await hub.close();\n } catch (error) {\n notice(error instanceof Error ? error.message : String(error));\n }\n try {\n await sessionManager.close();\n } catch (error) {\n notice(error instanceof Error ? error.message : String(error));\n }\n computerUse?.close?.();\n webCompositions?.close();\n const pendingCleanups = [...pendingSessions.values()].map((setup) => setup.cleanup());\n pendingSessions.clear();\n await Promise.allSettled(pendingCleanups);\n await bounded(harnessTelemetry.flush(), 'harness telemetry flush', notice);\n await bounded(harnessTelemetry.shutdown(), 'harness telemetry shutdown', notice);\n await bounded(telemetry.flush(), 'server telemetry flush', notice);\n await bounded(telemetry.shutdown(), 'server telemetry shutdown', notice);\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"runtime.cjs","names":["createServerTelemetry","path","piAgentDirectory","createWorkspaceRegistry","createOpenSessionRegistry","createHarnessTelemetry","createHeadlessSessionManager","publishHeadlessSelectionStatus","readMinorModeCatalog","createComputerUseBinding","createHeadlessHub","fs","resolveSessionIdentity","crypto","os","globalDoomConfigDirectory","createWebCompositions","readSyncRegistration","resolveServerBundleSource","loadMajorModesConfig","resolveLayers","loadServerBundle","loadMcpBundle","readSyncDrift","readSyncState","createRemoteRuntime","WebSocket","findRepositoryRoot","resolveSyncLocation","HARNESS_STATE_POINTER","HARNESS_STATE_KEYS","filterHookDisabledLayers","serveSessionApis","buildHarnessContext","serveHeadlessServer","listSavedSessions","readSqliteTranscript"],"sources":["../../../../src/builders/server/runtime.ts"],"sourcesContent":["import crypto from 'node:crypto';\nimport fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\n\nimport { globalDoomConfigDirectory } from '@agimon-ai/doompi-config/config';\nimport { filterHookDisabledLayers, loadMajorModesConfig, resolveLayers } from '@agimon-ai/doompi-config/majorModes';\nimport { createHeadlessHub, type HeadlessHub } from '@agimon-ai/doompi-core/headlessHub';\nimport { serveHeadlessServer } from '@agimon-ai/doompi-core/headlessServer';\nimport type { HeadlessSessionHost, HeadlessSessionHostOptions } from '@agimon-ai/doompi-core/headlessSessionHost';\nimport { createHeadlessSessionManager } from '@agimon-ai/doompi-core/headlessSessionManager';\nimport {\n createOpenSessionRegistry,\n createWorkspaceRegistry,\n listSavedSessions,\n readSqliteTranscript,\n} from '@agimon-ai/doompi-core/history';\nimport type { OpenSessionRecord } from '@agimon-ai/doompi-core/history';\nimport type {\n DoomHubSessionApiRequest,\n DoomHubSessionCreateRequest,\n DoomHubSessionScope,\n} from '@agimon-ai/doompi-core/hubChannel';\nimport { loadMcpBundle, type LoadedMcpBundle } from '@agimon-ai/doompi-core/mcpFacet';\nimport { serveSessionApis, type PackageApiServer } from '@agimon-ai/doompi-core/packageApiServer';\nimport { piAgentDirectory } from '@agimon-ai/doompi-core/piSettings';\nimport { createRemoteRuntime, type RemoteRuntime } from '@agimon-ai/doompi-core/remoteRuntime';\nimport type { HeadlessSessionManager } from '@agimon-ai/doompi-core/runtimeHeadlessSessionManager';\nimport { createHarnessTelemetry } from '@agimon-ai/doompi-core/runtimeLogSinkTelemetry';\nimport { loadServerBundle, resolveServerBundleSource } from '@agimon-ai/doompi-core/serverFacet';\nimport { createServerTelemetry } from '@agimon-ai/doompi-core/serverTelemetry';\nimport { resolveSyncLocation } from '@agimon-ai/doompi-core/syncLocation';\nimport { readSyncRegistration } from '@agimon-ai/doompi-core/syncRegistration';\nimport { createWebCompositions } from '@agimon-ai/doompi-core/webCompositions';\nimport { readMinorModeCatalog } from '@agimon-ai/doompi-minor-mode';\nimport WebSocket from 'ws';\n\nimport { HARNESS_STATE_KEYS, HARNESS_STATE_POINTER } from '../../composition/harnessState';\nimport { findRepositoryRoot } from '../../composition/repository';\nimport { readSyncDrift } from '../../composition/syncDrift';\nimport { readSyncState } from '../../composition/syncState';\nimport { buildHarnessContext } from '../cli/harnessContext';\nimport { createComputerUseBinding } from './computerUseBinding';\nimport { publishHeadlessSelectionStatus } from './selectionStatus';\nimport { resolveSessionIdentity } from './sessionArguments';\nimport type { ServeOptions, ServerRuntimeEnvironment } from './types';\nconst TELEMETRY_SHUTDOWN_TIMEOUT_MS = 2_000;\n\nasync function bounded(operation: Promise<unknown>, label: string, notice: (message: string) => void): Promise<void> {\n let timeout: NodeJS.Timeout | undefined;\n try {\n await Promise.race([\n operation,\n new Promise<void>((resolve) => {\n timeout = setTimeout(resolve, TELEMETRY_SHUTDOWN_TIMEOUT_MS);\n }),\n ]);\n } catch (error) {\n notice(`${label} failed: ${error instanceof Error ? error.message : String(error)}`);\n } finally {\n if (timeout) clearTimeout(timeout);\n }\n}\n\nexport async function runServerRuntime(options: ServeOptions, runtime: ServerRuntimeEnvironment): Promise<number> {\n const { cwd: baseCwd, environment: baseEnvironment, notice, resolveHarnessOptions, signal, syncWorkspace } = runtime;\n const telemetry = createServerTelemetry({ cwd: baseCwd, env: baseEnvironment, warn: notice });\n const serverDirectory = path.join(piAgentDirectory(baseEnvironment), 'server');\n const workspaces = createWorkspaceRegistry({ directory: serverDirectory, onNotice: notice });\n // Beside the journals it names, because a record pointing at a sessions\n // directory it is not stored next to is a record that can outlive its target.\n const openSessions = createOpenSessionRegistry({\n directory: serverDirectory,\n onNotice: notice,\n });\n let nextEventLoopTick = performance.now() + 1_000;\n const eventLoopMonitor = setInterval(() => {\n const now = performance.now();\n const delay = Math.max(0, now - nextEventLoopTick);\n nextEventLoopTick = now + 1_000;\n if (delay >= 100)\n void telemetry\n .recordEvent('doompi_server.event_loop_delay', { duration_ms: Math.round(delay) })\n .catch((error: unknown) => notice(`event loop telemetry failed: ${String(error)}`));\n }, 1_000);\n eventLoopMonitor.unref();\n const harnessTelemetry = createHarnessTelemetry({\n cwd: baseCwd,\n env: baseEnvironment,\n warn: notice,\n deferSpans: true,\n });\n const baseSessionManager = createHeadlessSessionManager({\n publishSelectionStatus: publishHeadlessSelectionStatus,\n contextGroups: (context) =>\n (readMinorModeCatalog(context)?.list() ?? [])\n .filter(({ state }) => state.activation === 'active')\n .map(({ descriptor }) => ({ id: descriptor.id, label: descriptor.label, kind: 'minor' })),\n });\n type SessionSetup = {\n cleanup: () => Promise<void>;\n bundle: Awaited<ReturnType<typeof loadServerBundle>>;\n mcpBundle: LoadedMcpBundle;\n };\n type SessionArtifacts = SessionSetup & { apis: PackageApiServer };\n const pendingSessions = new Map<string, SessionSetup>();\n const sessionArtifacts = new Map<string, SessionArtifacts>();\n let mountSessionApis:\n | ((options: HeadlessSessionHostOptions, host: HeadlessSessionHost) => Promise<PackageApiServer>)\n | undefined;\n /**\n * Shutdown runs every session through the same close path a user-initiated\n * close uses, so without this the registry would be emptied by the very event\n * it exists to survive.\n */\n let shuttingDown = false;\n\n const closeManagedSession = async (sessionId: string): Promise<void> => {\n if (!shuttingDown) openSessions.remove(sessionId);\n const artifacts = sessionArtifacts.get(sessionId);\n sessionArtifacts.delete(sessionId);\n webCompositions?.remove({ scope: 'session', sessionId });\n const failures: unknown[] = [];\n try {\n await artifacts?.apis.close();\n } catch (error) {\n failures.push(error);\n }\n try {\n await artifacts?.cleanup();\n } catch (error) {\n failures.push(error);\n }\n try {\n await baseSessionManager.closeSession(sessionId);\n } catch (error) {\n failures.push(error);\n }\n if (failures.length > 0) throw new AggregateError(failures, `Session '${sessionId}' shutdown failed`);\n };\n\n const sessionManager: HeadlessSessionManager = {\n async create(sessionOptions) {\n const setup = pendingSessions.get(sessionOptions.sessionId);\n let host: HeadlessSessionHost;\n try {\n host = await baseSessionManager.create(sessionOptions);\n } catch (error) {\n if (setup !== undefined && pendingSessions.delete(sessionOptions.sessionId))\n await setup.cleanup().catch((cleanupError: unknown) => notice(String(cleanupError)));\n throw error;\n }\n if (setup === undefined || mountSessionApis === undefined) return host;\n try {\n const apis = await mountSessionApis(sessionOptions, host);\n pendingSessions.delete(sessionOptions.sessionId);\n sessionArtifacts.set(sessionOptions.sessionId, { ...setup, apis });\n return host;\n } catch (error) {\n pendingSessions.delete(sessionOptions.sessionId);\n await baseSessionManager\n .closeSession(sessionOptions.sessionId)\n .catch((closeError: unknown) => notice(String(closeError)));\n await setup.cleanup().catch((cleanupError: unknown) => notice(String(cleanupError)));\n throw error;\n }\n },\n get: (sessionId) => baseSessionManager.get(sessionId),\n sessions: () => baseSessionManager.sessions(),\n closeSession: closeManagedSession,\n async close() {\n const ids = baseSessionManager.sessions().map((session) => session.runtime.sessionId);\n const outcomes = await Promise.allSettled(ids.map((id) => closeManagedSession(id)));\n const failures = outcomes\n .filter((outcome): outcome is PromiseRejectedResult => outcome.status === 'rejected')\n .map((outcome) => outcome.reason);\n if (failures.length > 0) throw new AggregateError(failures, 'Headless session shutdown failed');\n },\n };\n\n let requestSessionApi: (\n scope: DoomHubSessionScope,\n request: DoomHubSessionApiRequest,\n ) => Promise<Response> = async () => Response.json({ error: 'Session API unavailable.' }, { status: 404 });\n let openSession: (\n request: DoomHubSessionCreateRequest,\n sessionId?: string,\n ) => Promise<DoomHubSessionScope> = async () => {\n throw new Error('The cockpit session service is not ready.');\n };\n let admitWorkspace: (root: string) => Promise<{ id: string; root: string; available: boolean }> = async () => {\n throw new Error('Workspace admission is not ready.');\n };\n const computerUse = await createComputerUseBinding();\n let hub!: HeadlessHub;\n hub = createHeadlessHub({\n manager: sessionManager,\n admitWorkspace: (root) => admitWorkspace(root),\n onWorkspaceRemoved: (workspaceId) => {\n workspaces.remove(workspaceId);\n webCompositions?.remove({ scope: 'workspace', workspaceId });\n },\n createSession: (request) => openSession(request),\n sessionReservations: {\n read(id, parentSessionId) {\n if (!cockpit) throw new Error('Session setup is not ready.');\n return cockpit.sessionReservations.read(id, parentSessionId);\n },\n async prepare(id, parentSessionId, cwd) {\n if (!cockpit) throw new Error('Session setup is not ready.');\n return cockpit.sessionReservations.prepare(id, parentSessionId, cwd);\n },\n async complete(id, parentSessionId) {\n if (!cockpit) throw new Error('Session setup is not ready.');\n return cockpit.sessionReservations.complete(id, parentSessionId);\n },\n },\n onNotice: notice,\n hubToken: () => attachToken,\n requestSessionApi: (scope, request) => requestSessionApi(scope, request),\n ...(computerUse === undefined ? {} : { computerUse }),\n });\n const stopPersistSessionNames = hub.onEvent((event) => {\n if (event.kind !== 'upsert') return;\n const record = openSessions.list().find((entry) => entry.sessionId === event.session.id);\n if (record === undefined || record.name === event.session.name) return;\n openSessions.add({ ...record, name: event.session.name });\n });\n let harnessContext: Awaited<ReturnType<typeof buildHarnessContext>> | undefined;\n let cockpit: Awaited<ReturnType<typeof serveHeadlessServer>> | undefined;\n let remoteRuntime: RemoteRuntime | undefined;\n let attachToken: string | undefined;\n let webCompositions: ReturnType<typeof createWebCompositions> | undefined;\n\n try {\n await telemetry.runInSpan('doompi_server.startup', {}, async () => {\n const token = fs.readFileSync(options.tokenFile, 'utf8').trim();\n if (!token) throw new Error('The attach token file is empty.');\n attachToken = token;\n\n const resolved = resolveSessionIdentity(options.agentArgs, {\n sessionId: options.sessionId ?? crypto.randomUUID(),\n sessionName: options.sessionName,\n });\n\n const homeDirectory = baseEnvironment.HOME ?? os.homedir();\n const globalRoot = globalDoomConfigDirectory(homeDirectory);\n webCompositions = createWebCompositions(path.join(globalRoot, 'server'), notice);\n const loadComposition = async (\n root: string,\n scope: 'global' | 'workspace' | 'session',\n selection?: { root: string; majorMode: string; activeLayers: string[] },\n ) => {\n const registration = readSyncRegistration(root, homeDirectory);\n const source = resolveServerBundleSource({ registration });\n if (source.kind !== 'descriptor')\n throw new Error(`Run the scoped DoomPi sync for '${root}' before opening it.`);\n const selected =\n selection ??\n (() => {\n const config = loadMajorModesConfig(root, homeDirectory);\n const majorMode = config.defaultMajorMode;\n return { root, majorMode, activeLayers: resolveLayers(config, majorMode) };\n })();\n return loadServerBundle(scope, {\n ...source,\n ...selected,\n retainCandidates: scope === 'session',\n onNotice: notice,\n });\n };\n const loadSessionMcp = async (\n root: string,\n selection: { majorMode: string; activeLayers: readonly string[] },\n ): Promise<LoadedMcpBundle> => {\n const registration = readSyncRegistration(root, homeDirectory);\n if (registration?.mcpBundle === undefined)\n throw new Error(`Run the scoped DoomPi sync for '${root}' before opening its MCP runtime.`);\n return loadMcpBundle({\n directory: path.dirname(registration.mcpBundle.path),\n generation: registration.generation,\n fingerprint: registration.mcpBundle.fingerprint,\n descriptorSha256: registration.mcpBundle.sha256,\n majorMode: selection.majorMode,\n activeLayers: selection.activeLayers,\n retainCandidates: true,\n onNotice: notice,\n });\n };\n const sharedApiContext = {\n homeDirectory,\n environment: baseEnvironment,\n hubToken: token,\n sessionService: hub.sessionService,\n directEvents: hub.directEvents,\n repositories: () =>\n hub.workspaces().map((workspace) => ({\n id: workspace.id,\n path: workspace.root,\n name: workspace.root.split('/').at(-1) ?? workspace.id,\n active: hub.snapshot().some((session) => session.workspaceId === workspace.id),\n })),\n resolveRepository: (id: string) => hub.workspaces().find((workspace) => workspace.id === id)?.root,\n readRepositorySync: (id: string) => {\n const root = hub.workspaces().find((workspace) => workspace.id === id)?.root;\n if (!root) return undefined;\n const drift = readSyncDrift({ repoRoot: root, homeDirectory, requireWebBundle: true });\n const state = readSyncState(root, homeDirectory);\n return { ...drift, mcpProjection: state?.fileState.mcpProjection };\n },\n onNotice: notice,\n };\n const globalBundle = await loadComposition(globalRoot, 'global');\n webCompositions.publishShell(readSyncRegistration(globalRoot, homeDirectory)!);\n remoteRuntime = createRemoteRuntime({\n homeDirectory,\n registrationToken: token,\n bundleTrust: () => webCompositions?.shellTrust(),\n onNotice: notice,\n forward: async (request) => {\n if (!cockpit || !attachToken)\n return Response.json({ error: 'The headless server is not ready.' }, { status: 503 });\n const from = new URL(request.url);\n const headers = new Headers(request.headers);\n headers.set('x-doompi-token', attachToken);\n return fetch(\n new URL(`${from.pathname}${from.search}`, cockpit.url),\n new Request(request, { headers, redirect: 'manual' }),\n );\n },\n connectProtocol: (pathname) => {\n if (!cockpit || !attachToken) throw new Error('The headless protocol listener is not ready.');\n const url = new URL(pathname, cockpit.url);\n url.protocol = 'ws:';\n return new WebSocket(url, { headers: { 'x-doompi-token': attachToken } });\n },\n });\n await hub.mountFacets(globalBundle.facets, {\n ...sharedApiContext,\n scope: 'global',\n remoteControl: { fetch: (request: Request) => remoteRuntime!.fetchLocal(request) },\n });\n webCompositions.publish(\n { scope: 'global' },\n readSyncRegistration(globalRoot, homeDirectory)!,\n hub.channelTypes(),\n );\n const admissions = new Map<string, Promise<{ id: string; root: string; available: boolean }>>();\n admitWorkspace = async (from) => {\n const root = fs.realpathSync(findRepositoryRoot(from));\n const id = resolveSyncLocation(root, homeDirectory).identity.worktreeId;\n const existing = hub.workspaces().find((workspace) => workspace.id === id);\n if (existing !== undefined && existing.available !== false) return { ...existing, available: true };\n const pending = admissions.get(id);\n if (pending) return pending;\n const wasRemembered = workspaces.list().some((workspace) => workspace.id === id);\n if (!wasRemembered) workspaces.add({ id, root });\n hub.registerWorkspace({ id, root, available: false });\n const admission = (async () => {\n const syncEnvironment: NodeJS.ProcessEnv = { ...baseEnvironment, DOOMPI_ROOT: root };\n for (const key of [HARNESS_STATE_POINTER, ...Object.values(HARNESS_STATE_KEYS)]) delete syncEnvironment[key];\n await syncWorkspace(root, syncEnvironment);\n const bundle = await loadComposition(root, 'workspace');\n await hub.mountFacets(bundle.facets, {\n ...sharedApiContext,\n scope: 'workspace',\n workspaceId: id,\n workspaceRoot: root,\n cwd: root,\n resolveRepository: (requestedId) => (requestedId === id ? root : undefined),\n });\n webCompositions?.publish(\n { scope: 'workspace', workspaceId: id },\n readSyncRegistration(root, homeDirectory)!,\n hub.channelTypes(),\n );\n return { id, root, available: true };\n })();\n admissions.set(id, admission);\n try {\n return await admission;\n } catch (error) {\n if (!wasRemembered) {\n await hub.removeWorkspace(id);\n workspaces.remove(id);\n }\n throw error;\n } finally {\n admissions.delete(id);\n }\n };\n for (const record of openSessions.list()) {\n if (workspaces.list().some((workspace) => workspace.id === record.workspaceId)) continue;\n try {\n const root = fs.realpathSync(findRepositoryRoot(record.cwd));\n const id = resolveSyncLocation(root, homeDirectory).identity.worktreeId;\n if (id === record.workspaceId) workspaces.add({ id, root });\n else\n notice(\n `Session '${record.sessionId}' no longer resolves to its recorded workspace; skipping registration.`,\n );\n } catch (error) {\n notice(\n `Session '${record.sessionId}' workspace could not be registered: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n for (const workspace of workspaces.list()) {\n hub.registerWorkspace({ ...workspace, available: false });\n try {\n const root = fs.realpathSync(findRepositoryRoot(workspace.root));\n const id = resolveSyncLocation(root, homeDirectory).identity.worktreeId;\n if (root !== workspace.root || id !== workspace.id) {\n notice(\n `Workspace '${workspace.root}' no longer resolves to its recorded identity; leaving it unavailable.`,\n );\n continue;\n }\n await admitWorkspace(workspace.root);\n } catch (error) {\n notice(\n `Workspace '${workspace.root}' could not be restored: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n\n const sessionHostOptions = (\n context: Awaited<ReturnType<typeof buildHarnessContext>>,\n bundle: Awaited<ReturnType<typeof loadServerBundle>>,\n mcpBundle: LoadedMcpBundle,\n identity: {\n sessionId: string;\n sessionName: string;\n parentSessionId?: string;\n sessionProvenance?: string;\n },\n workspaceId?: string,\n ): HeadlessSessionHostOptions => {\n const policyOptions = context.options;\n const sessionSelection = {\n root: policyOptions.repoRoot,\n majorMode: policyOptions.majorMode,\n activeLayers: context.selectedLayers,\n domains: policyOptions.domains,\n profile: context.profile,\n state: { 'minor-mode': [] },\n };\n return {\n cwd: policyOptions.cwd,\n repoRoot: policyOptions.repoRoot,\n sessionId: identity.sessionId,\n workspaceId: workspaceId ?? resolveSyncLocation(policyOptions.repoRoot, homeDirectory).identity.worktreeId,\n sessionName: identity.sessionName,\n webComposition: webCompositions?.publish(\n { scope: 'session', sessionId: identity.sessionId },\n readSyncRegistration(policyOptions.repoRoot, homeDirectory)!,\n hub.channelTypes(),\n ),\n ...(identity.parentSessionId === undefined ? {} : { parentSessionId: identity.parentSessionId }),\n ...(identity.sessionProvenance === undefined ? {} : { sessionProvenance: identity.sessionProvenance }),\n agentArgs: policyOptions.piArgs,\n environment: Object.freeze({ ...context.environment }),\n selection: sessionSelection,\n selectionOverrides: (['majorMode', 'domains', 'profile'] as const).filter((axis) => {\n const flag = axis === 'majorMode' ? '--major-mode' : `--${axis}`;\n return (\n identity.sessionId === resolved.identity.sessionId &&\n resolved.agentArgs.some((arg) => arg === flag || arg.startsWith(`${flag}=`))\n );\n }),\n inheritedSelection: () => {\n const environment = { ...baseEnvironment };\n for (const key of [HARNESS_STATE_POINTER, ...Object.values(HARNESS_STATE_KEYS)]) delete environment[key];\n const defaults = resolveHarnessOptions({\n args: ['--cwd', policyOptions.cwd],\n cwd: policyOptions.cwd,\n environment,\n });\n return { majorMode: defaults.majorMode, domains: defaults.domains, profile: defaults.profile };\n },\n candidates: bundle.descriptor.entries,\n mcpPlugins: mcpBundle.plugins,\n resolveSelection: (requested) => {\n const config = loadMajorModesConfig(policyOptions.repoRoot, policyOptions.homeDirectory);\n return {\n ...requested,\n activeLayers: filterHookDisabledLayers(\n config,\n resolveLayers(config, requested.majorMode),\n policyOptions.hooks,\n ),\n };\n },\n onNotice: notice,\n };\n };\n\n mountSessionApis = (sessionOptions, host) =>\n serveSessionApis({\n sessionId: sessionOptions.sessionId,\n cwd: sessionOptions.cwd,\n environment: sessionOptions.environment,\n directEvents: hub.directEvents,\n ...(computerUse === undefined\n ? {}\n : {\n computerUse: {\n get available() {\n return computerUse.available;\n },\n get enabled() {\n return computerUse.enabled === true;\n },\n authorize: (headers: Headers) => computerUse.authorize?.(headers) === true,\n claim: () => computerUse.claimSession?.(sessionOptions.sessionId),\n subscribe: (listener: () => void) => computerUse.subscribe?.(listener) ?? (() => undefined),\n },\n }),\n hubToken: token,\n sessionService: hub.sessionService,\n pluginRegistry: hub.pluginRegistry,\n apis: [],\n facets: pendingSessions.get(sessionOptions.sessionId)?.bundle.facets ?? [],\n workspaceId: sessionOptions.workspaceId,\n workspaceRoot: sessionOptions.repoRoot,\n homeDirectory,\n mountChannel: (channel) => {\n const dispose = hub.registerChannel(channel, { scope: 'session', sessionId: sessionOptions.sessionId });\n return { mounted: true, dispose };\n },\n prepareFacets: host.prepareFacets,\n activateFacets: host.activateFacets,\n canDispatch: host.canDispatch,\n telemetry,\n onNotice: notice,\n });\n\n requestSessionApi = async (scope, request) => {\n const session = hub.session(scope.sessionId);\n const artifacts = sessionArtifacts.get(scope.sessionId);\n if (session === undefined || session.cwd !== scope.cwd || artifacts === undefined)\n return Response.json({ error: 'Session not found.' }, { status: 404 });\n if (!/^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/u.test(request.basePath))\n return Response.json({ error: 'Invalid session API base path.' }, { status: 400 });\n if (!request.path.startsWith('/') || request.path.startsWith('//') || request.path.includes('#'))\n return Response.json({ error: 'Invalid session API path.' }, { status: 400 });\n const body = request.body === null || request.body === undefined ? undefined : request.body;\n return artifacts.apis.request(\n new Request(`http://doompi.local/api/plugins/${request.basePath}${request.path}`, {\n method: request.method,\n headers: request.headers,\n ...(body === undefined ? {} : { body }),\n ...(request.signal === undefined ? {} : { signal: request.signal }),\n }),\n );\n };\n\n if (!options.noSession) {\n harnessContext = await buildHarnessContext(\n resolveHarnessOptions({ args: resolved.agentArgs, cwd: baseCwd, environment: baseEnvironment }),\n harnessTelemetry,\n );\n const activeHarnessContext = harnessContext;\n try {\n await admitWorkspace(harnessContext.options.repoRoot);\n const initialBundle = await loadComposition(harnessContext.options.repoRoot, 'session', {\n root: harnessContext.options.repoRoot,\n majorMode: harnessContext.options.majorMode,\n activeLayers: harnessContext.selectedLayers,\n });\n const initialMcpBundle = await loadSessionMcp(harnessContext.options.repoRoot, {\n majorMode: harnessContext.options.majorMode,\n activeLayers: harnessContext.selectedLayers,\n });\n pendingSessions.set(resolved.identity.sessionId, {\n cleanup: () => activeHarnessContext.cleanup(),\n bundle: initialBundle,\n mcpBundle: initialMcpBundle,\n });\n await hub.create(sessionHostOptions(harnessContext, initialBundle, initialMcpBundle, resolved.identity));\n } catch (error) {\n pendingSessions.delete(resolved.identity.sessionId);\n await activeHarnessContext.cleanup().catch((cleanupError: unknown) => notice(String(cleanupError)));\n throw error;\n }\n await bounded(harnessTelemetry.flush(), 'initial composition telemetry flush', notice);\n }\n\n const reservedOpens = new Map<string, Promise<DoomHubSessionScope>>();\n openSession = async (request, sessionId) => {\n request.signal?.throwIfAborted();\n if (request.reservationId !== undefined) {\n if (!request.parentSessionId || !cockpit) throw new Error('A reserved session requires its owning parent.');\n const prepared = await cockpit.sessionReservations.prepare(\n request.reservationId,\n request.parentSessionId,\n request.cwd,\n );\n if (sessionId !== undefined && sessionId !== prepared.sessionId)\n throw new Error('Reserved session identity cannot change.');\n sessionId = prepared.sessionId;\n const existing = hub.session(sessionId);\n if (existing) {\n if (existing.cwd !== prepared.cwd || existing.parentSessionId !== request.parentSessionId)\n throw new Error('Reserved session target does not match.');\n return { sessionId, cwd: existing.cwd, workspaceId: existing.workspaceId };\n }\n if (openSessions.list().some((record) => record.sessionId === sessionId))\n throw new Error('Resume the recorded session instead of recreating it.');\n const pending = reservedOpens.get(sessionId);\n if (pending) return pending;\n request = { ...request, cwd: prepared.cwd };\n }\n const identity = {\n sessionId: sessionId ?? crypto.randomUUID(),\n sessionName: request.name,\n parentSessionId: request.parentSessionId,\n sessionProvenance: request.sessionProvenance,\n };\n const inheritedWorkspaceId =\n request.sessionProvenance === 'worktree' && request.parentSessionId\n ? (hub.session(request.parentSessionId)?.workspaceId ??\n openSessions.list().find((record) => record.sessionId === request.parentSessionId)?.workspaceId)\n : undefined;\n if (request.sessionProvenance === 'worktree' && inheritedWorkspaceId === undefined)\n throw new Error('Worktree session requires its parent workspace.');\n const start = (async (): Promise<DoomHubSessionScope> => {\n const childIdentity = resolveSessionIdentity([], identity);\n const childEnvironment = { ...baseEnvironment };\n for (const key of [HARNESS_STATE_POINTER, ...Object.values(HARNESS_STATE_KEYS)]) delete childEnvironment[key];\n const childContext = await buildHarnessContext(\n resolveHarnessOptions({\n args: ['--cwd', request.cwd, ...childIdentity.agentArgs],\n cwd: request.cwd,\n environment: childEnvironment,\n }),\n harnessTelemetry,\n );\n try {\n if (inheritedWorkspaceId === undefined) {\n await admitWorkspace(childContext.options.repoRoot);\n } else {\n const inheritedWorkspace = hub\n .workspaces()\n .find((workspace) => workspace.id === inheritedWorkspaceId && workspace.available !== false);\n if (inheritedWorkspace === undefined) throw new Error('Worktree parent workspace is unavailable.');\n const syncEnvironment: NodeJS.ProcessEnv = {\n ...baseEnvironment,\n DOOMPI_ROOT: childContext.options.repoRoot,\n };\n for (const key of [HARNESS_STATE_POINTER, ...Object.values(HARNESS_STATE_KEYS)])\n delete syncEnvironment[key];\n await syncWorkspace(childContext.options.repoRoot, syncEnvironment);\n }\n const bundle = await loadComposition(childContext.options.repoRoot, 'session', {\n root: childContext.options.repoRoot,\n majorMode: childContext.options.majorMode,\n activeLayers: childContext.selectedLayers,\n });\n const mcpBundle = await loadSessionMcp(childContext.options.repoRoot, {\n majorMode: childContext.options.majorMode,\n activeLayers: childContext.selectedLayers,\n });\n request.signal?.throwIfAborted();\n pendingSessions.set(identity.sessionId, { cleanup: () => childContext.cleanup(), bundle, mcpBundle });\n const created = await hub.create(\n sessionHostOptions(childContext, bundle, mcpBundle, identity, inheritedWorkspaceId),\n );\n request.signal?.throwIfAborted();\n if (created.workspaceId !== undefined) {\n const saved = openSessions.add({\n sessionId: created.id,\n workspaceId: created.workspaceId,\n cwd: created.cwd,\n name: created.name,\n createdAt: created.createdAt,\n ...(created.parentSessionId === undefined ? {} : { parentSessionId: created.parentSessionId }),\n ...(created.sessionProvenance === undefined ? {} : { sessionProvenance: created.sessionProvenance }),\n });\n if (saved === false) throw new Error('The new session could not be durably recorded.');\n }\n return { sessionId: identity.sessionId, cwd: childContext.options.cwd, workspaceId: created.workspaceId };\n } catch (error) {\n if (hub.session(identity.sessionId)) await hub.closeSession(identity.sessionId);\n else {\n pendingSessions.delete(identity.sessionId);\n await childContext.cleanup().catch((cleanupError: unknown) => notice(String(cleanupError)));\n }\n throw error;\n }\n })();\n if (request.reservationId !== undefined) reservedOpens.set(identity.sessionId, start);\n try {\n return await start;\n } finally {\n if (reservedOpens.get(identity.sessionId) === start) reservedOpens.delete(identity.sessionId);\n }\n };\n });\n\n const workspaceResumes = new Map<string, Promise<string>>();\n cockpit = await serveHeadlessServer({\n port: options.webPort,\n headlessHub: hub,\n token: attachToken,\n sessionMcpPublicOrigin: () => remoteRuntime?.remote.publicOrigin(),\n sessionMcpStateDir: serverDirectory,\n sessionMcpPublicOriginRevision: () => remoteRuntime?.remote.publicOriginRevision() ?? 0,\n isSessionPersisted: (sessionId, cwd) =>\n openSessions.list().some((record) => record.sessionId === sessionId && record.cwd === cwd),\n workspaceHistory: (workspaceId) => {\n const workspaceRoot = hub\n .workspaces()\n .find((workspace) => workspace.id === workspaceId && workspace.available !== false)?.root;\n if (!workspaceRoot) throw new Error('Workspace not found.');\n return listSavedSessions(\n path.join(serverDirectory, 'sessions'),\n workspaceRoot,\n new Set(hub.snapshot().map((active) => active.id)),\n );\n },\n resumeWorkspaceSession: async (workspaceId, targetSessionId) => {\n const key = `${workspaceId}\\0${targetSessionId}`;\n const pending = workspaceResumes.get(key);\n if (pending) return pending;\n const resume = (async () => {\n const workspaceRoot = hub\n .workspaces()\n .find((workspace) => workspace.id === workspaceId && workspace.available !== false)?.root;\n if (!workspaceRoot) throw new Error('Workspace not found.');\n const saved = await listSavedSessions(\n path.join(serverDirectory, 'sessions'),\n workspaceRoot,\n new Set(hub.snapshot().map((active) => active.id)),\n );\n const target = saved.find((item) => item.id === targetSessionId);\n if (!target) throw new Error('Saved Pi thread not found in this workspace.');\n await openSession({ cwd: workspaceRoot, name: target.name ?? 'untitled' }, target.id);\n return target.id;\n })();\n workspaceResumes.set(key, resume);\n try {\n return await resume;\n } finally {\n workspaceResumes.delete(key);\n }\n },\n sessionHistory: (session) => {\n const workspaceRoot = hub.workspaces().find((workspace) => workspace.id === session.workspaceId)?.root;\n if (!workspaceRoot) throw new Error('Session workspace not found.');\n return listSavedSessions(\n path.join(piAgentDirectory(baseEnvironment), 'server', 'sessions'),\n workspaceRoot,\n new Set(hub.snapshot().map((active) => active.id)),\n );\n },\n readDormantTranscript: (record, request, context) => {\n const workspaceRoot = hub.workspaces().find((workspace) => workspace.id === record.workspaceId)?.root;\n if (!workspaceRoot) throw new Error('Saved transcript unavailable.');\n return readSqliteTranscript(\n path.join(piAgentDirectory(baseEnvironment), 'server', 'sessions', `${record.sessionId}.sqlite`),\n request,\n context,\n { sessionId: record.sessionId, workspaceRoot },\n );\n },\n restartSession: async (session) => {\n const workspaceRoot = hub.workspaces().find((workspace) => workspace.id === session.workspaceId)?.root;\n if (!workspaceRoot) throw new Error('Session workspace not found.');\n const syncEnvironment: NodeJS.ProcessEnv = { ...baseEnvironment, DOOMPI_ROOT: workspaceRoot };\n for (const key of [HARNESS_STATE_POINTER, ...Object.values(HARNESS_STATE_KEYS)]) delete syncEnvironment[key];\n try {\n await syncWorkspace(workspaceRoot, syncEnvironment);\n } catch (error) {\n notice(`Workspace sync failed before restart: ${error instanceof Error ? error.message : String(error)}`);\n throw new Error('Workspace sync failed; the session is still running.', { cause: error });\n }\n await hub.closeSession(session.id);\n await openSession(\n {\n cwd: session.cwd,\n name: session.name,\n ...(session.parentSessionId === undefined ? {} : { parentSessionId: session.parentSessionId }),\n ...(session.sessionProvenance === undefined ? {} : { sessionProvenance: session.sessionProvenance }),\n },\n session.id,\n );\n },\n resumeSession: async (session, targetSessionId) => {\n const workspaceRoot = hub.workspaces().find((workspace) => workspace.id === session.workspaceId)?.root;\n if (!workspaceRoot) throw new Error('Session workspace not found.');\n const saved = await listSavedSessions(\n path.join(piAgentDirectory(baseEnvironment), 'server', 'sessions'),\n workspaceRoot,\n new Set(hub.snapshot().map((active) => active.id)),\n );\n const target = saved.find((item) => item.id === targetSessionId);\n if (!target) throw new Error('Saved Pi thread not found in this workspace.');\n await hub.closeSession(session.id);\n await openSession({ cwd: session.cwd, name: target.name ?? 'untitled' }, target.id);\n return target.id;\n },\n dormantSessions: () => openSessions.list(),\n removeDormantSession: (record: OpenSessionRecord) => openSessions.remove(record.sessionId),\n reviveSession: async (record: OpenSessionRecord) => {\n // A failed wake may be transient, for example while another server still\n // owns the journal. Keep the record so the user can retry after resolving\n // the conflict instead of losing the session from the cockpit.\n await openSession(\n {\n cwd: record.cwd,\n name: record.name,\n ...(record.parentSessionId === undefined ? {} : { parentSessionId: record.parentSessionId }),\n ...(record.sessionProvenance === undefined ? {} : { sessionProvenance: record.sessionProvenance }),\n },\n record.sessionId,\n );\n },\n requestAsset: (request) => webCompositions?.request(request) ?? Promise.resolve(undefined),\n compositions: () => ({\n global: webCompositions?.get({ scope: 'global' }),\n publicKey: webCompositions?.publicKey(),\n shell: webCompositions?.shellTrust(),\n workspaces: hub.workspaces().map((workspace) => ({\n ...workspace,\n webComposition: webCompositions?.get({ scope: 'workspace', workspaceId: workspace.id }),\n })),\n }),\n telemetry,\n onNotice: notice,\n });\n notice(`protocol on ${cockpit.url}/api/ws`);\n let resolveShutdown!: (exitCode: number) => void;\n const shutdown = new Promise<number>((resolve) => {\n resolveShutdown = resolve;\n });\n const stop = (): void => resolveShutdown(0);\n signal.addEventListener('abort', stop, { once: true });\n if (signal.aborted) stop();\n try {\n return await shutdown;\n } finally {\n signal.removeEventListener('abort', stop);\n }\n } finally {\n shuttingDown = true;\n stopPersistSessionNames();\n clearInterval(eventLoopMonitor);\n await bounded(telemetry.recordEvent('doompi_server.shutdown'), 'shutdown telemetry', notice);\n await Promise.allSettled([cockpit?.close()]);\n await bounded(remoteRuntime?.close() ?? Promise.resolve(), 'remote control shutdown', notice);\n try {\n await hub.close();\n } catch (error) {\n notice(error instanceof Error ? error.message : String(error));\n }\n try {\n await sessionManager.close();\n } catch (error) {\n notice(error instanceof Error ? error.message : String(error));\n }\n computerUse?.close?.();\n webCompositions?.close();\n const pendingCleanups = [...pendingSessions.values()].map((setup) => setup.cleanup());\n pendingSessions.clear();\n await Promise.allSettled(pendingCleanups);\n await bounded(harnessTelemetry.flush(), 'harness telemetry flush', notice);\n await bounded(harnessTelemetry.shutdown(), 'harness telemetry shutdown', notice);\n await bounded(telemetry.flush(), 'server telemetry flush', notice);\n await bounded(telemetry.shutdown(), 'server telemetry shutdown', notice);\n }\n}\n"],"mappings":"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"}
|
|
@@ -189,6 +189,15 @@ async function runServerRuntime(options, runtime) {
|
|
|
189
189
|
requestSessionApi: (scope, request) => requestSessionApi(scope, request),
|
|
190
190
|
...computerUse === void 0 ? {} : { computerUse }
|
|
191
191
|
});
|
|
192
|
+
const stopPersistSessionNames = hub.onEvent((event) => {
|
|
193
|
+
if (event.kind !== "upsert") return;
|
|
194
|
+
const record = openSessions.list().find((entry) => entry.sessionId === event.session.id);
|
|
195
|
+
if (record === void 0 || record.name === event.session.name) return;
|
|
196
|
+
openSessions.add({
|
|
197
|
+
...record,
|
|
198
|
+
name: event.session.name
|
|
199
|
+
});
|
|
200
|
+
});
|
|
192
201
|
let harnessContext;
|
|
193
202
|
let cockpit;
|
|
194
203
|
let remoteRuntime;
|
|
@@ -764,6 +773,7 @@ async function runServerRuntime(options, runtime) {
|
|
|
764
773
|
}
|
|
765
774
|
} finally {
|
|
766
775
|
shuttingDown = true;
|
|
776
|
+
stopPersistSessionNames();
|
|
767
777
|
clearInterval(eventLoopMonitor);
|
|
768
778
|
await bounded(telemetry.recordEvent("doompi_server.shutdown"), "shutdown telemetry", notice);
|
|
769
779
|
await Promise.allSettled([cockpit?.close()]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.mjs","names":[],"sources":["../../../../src/builders/server/runtime.ts"],"sourcesContent":["import crypto from 'node:crypto';\nimport fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\n\nimport { globalDoomConfigDirectory } from '@agimon-ai/doompi-config/config';\nimport { filterHookDisabledLayers, loadMajorModesConfig, resolveLayers } from '@agimon-ai/doompi-config/majorModes';\nimport { createHeadlessHub, type HeadlessHub } from '@agimon-ai/doompi-core/headlessHub';\nimport { serveHeadlessServer } from '@agimon-ai/doompi-core/headlessServer';\nimport type { HeadlessSessionHost, HeadlessSessionHostOptions } from '@agimon-ai/doompi-core/headlessSessionHost';\nimport { createHeadlessSessionManager } from '@agimon-ai/doompi-core/headlessSessionManager';\nimport {\n createOpenSessionRegistry,\n createWorkspaceRegistry,\n listSavedSessions,\n readSqliteTranscript,\n} from '@agimon-ai/doompi-core/history';\nimport type { OpenSessionRecord } from '@agimon-ai/doompi-core/history';\nimport type {\n DoomHubSessionApiRequest,\n DoomHubSessionCreateRequest,\n DoomHubSessionScope,\n} from '@agimon-ai/doompi-core/hubChannel';\nimport { loadMcpBundle, type LoadedMcpBundle } from '@agimon-ai/doompi-core/mcpFacet';\nimport { serveSessionApis, type PackageApiServer } from '@agimon-ai/doompi-core/packageApiServer';\nimport { piAgentDirectory } from '@agimon-ai/doompi-core/piSettings';\nimport { createRemoteRuntime, type RemoteRuntime } from '@agimon-ai/doompi-core/remoteRuntime';\nimport type { HeadlessSessionManager } from '@agimon-ai/doompi-core/runtimeHeadlessSessionManager';\nimport { createHarnessTelemetry } from '@agimon-ai/doompi-core/runtimeLogSinkTelemetry';\nimport { loadServerBundle, resolveServerBundleSource } from '@agimon-ai/doompi-core/serverFacet';\nimport { createServerTelemetry } from '@agimon-ai/doompi-core/serverTelemetry';\nimport { resolveSyncLocation } from '@agimon-ai/doompi-core/syncLocation';\nimport { readSyncRegistration } from '@agimon-ai/doompi-core/syncRegistration';\nimport { createWebCompositions } from '@agimon-ai/doompi-core/webCompositions';\nimport { readMinorModeCatalog } from '@agimon-ai/doompi-minor-mode';\nimport WebSocket from 'ws';\n\nimport { HARNESS_STATE_KEYS, HARNESS_STATE_POINTER } from '../../composition/harnessState';\nimport { findRepositoryRoot } from '../../composition/repository';\nimport { readSyncDrift } from '../../composition/syncDrift';\nimport { readSyncState } from '../../composition/syncState';\nimport { buildHarnessContext } from '../cli/harnessContext';\nimport { createComputerUseBinding } from './computerUseBinding';\nimport { publishHeadlessSelectionStatus } from './selectionStatus';\nimport { resolveSessionIdentity } from './sessionArguments';\nimport type { ServeOptions, ServerRuntimeEnvironment } from './types';\nconst TELEMETRY_SHUTDOWN_TIMEOUT_MS = 2_000;\n\nasync function bounded(operation: Promise<unknown>, label: string, notice: (message: string) => void): Promise<void> {\n let timeout: NodeJS.Timeout | undefined;\n try {\n await Promise.race([\n operation,\n new Promise<void>((resolve) => {\n timeout = setTimeout(resolve, TELEMETRY_SHUTDOWN_TIMEOUT_MS);\n }),\n ]);\n } catch (error) {\n notice(`${label} failed: ${error instanceof Error ? error.message : String(error)}`);\n } finally {\n if (timeout) clearTimeout(timeout);\n }\n}\n\nexport async function runServerRuntime(options: ServeOptions, runtime: ServerRuntimeEnvironment): Promise<number> {\n const { cwd: baseCwd, environment: baseEnvironment, notice, resolveHarnessOptions, signal, syncWorkspace } = runtime;\n const telemetry = createServerTelemetry({ cwd: baseCwd, env: baseEnvironment, warn: notice });\n const serverDirectory = path.join(piAgentDirectory(baseEnvironment), 'server');\n const workspaces = createWorkspaceRegistry({ directory: serverDirectory, onNotice: notice });\n // Beside the journals it names, because a record pointing at a sessions\n // directory it is not stored next to is a record that can outlive its target.\n const openSessions = createOpenSessionRegistry({\n directory: serverDirectory,\n onNotice: notice,\n });\n let nextEventLoopTick = performance.now() + 1_000;\n const eventLoopMonitor = setInterval(() => {\n const now = performance.now();\n const delay = Math.max(0, now - nextEventLoopTick);\n nextEventLoopTick = now + 1_000;\n if (delay >= 100)\n void telemetry\n .recordEvent('doompi_server.event_loop_delay', { duration_ms: Math.round(delay) })\n .catch((error: unknown) => notice(`event loop telemetry failed: ${String(error)}`));\n }, 1_000);\n eventLoopMonitor.unref();\n const harnessTelemetry = createHarnessTelemetry({\n cwd: baseCwd,\n env: baseEnvironment,\n warn: notice,\n deferSpans: true,\n });\n const baseSessionManager = createHeadlessSessionManager({\n publishSelectionStatus: publishHeadlessSelectionStatus,\n contextGroups: (context) =>\n (readMinorModeCatalog(context)?.list() ?? [])\n .filter(({ state }) => state.activation === 'active')\n .map(({ descriptor }) => ({ id: descriptor.id, label: descriptor.label, kind: 'minor' })),\n });\n type SessionSetup = {\n cleanup: () => Promise<void>;\n bundle: Awaited<ReturnType<typeof loadServerBundle>>;\n mcpBundle: LoadedMcpBundle;\n };\n type SessionArtifacts = SessionSetup & { apis: PackageApiServer };\n const pendingSessions = new Map<string, SessionSetup>();\n const sessionArtifacts = new Map<string, SessionArtifacts>();\n let mountSessionApis:\n | ((options: HeadlessSessionHostOptions, host: HeadlessSessionHost) => Promise<PackageApiServer>)\n | undefined;\n /**\n * Shutdown runs every session through the same close path a user-initiated\n * close uses, so without this the registry would be emptied by the very event\n * it exists to survive.\n */\n let shuttingDown = false;\n\n const closeManagedSession = async (sessionId: string): Promise<void> => {\n if (!shuttingDown) openSessions.remove(sessionId);\n const artifacts = sessionArtifacts.get(sessionId);\n sessionArtifacts.delete(sessionId);\n webCompositions?.remove({ scope: 'session', sessionId });\n const failures: unknown[] = [];\n try {\n await artifacts?.apis.close();\n } catch (error) {\n failures.push(error);\n }\n try {\n await artifacts?.cleanup();\n } catch (error) {\n failures.push(error);\n }\n try {\n await baseSessionManager.closeSession(sessionId);\n } catch (error) {\n failures.push(error);\n }\n if (failures.length > 0) throw new AggregateError(failures, `Session '${sessionId}' shutdown failed`);\n };\n\n const sessionManager: HeadlessSessionManager = {\n async create(sessionOptions) {\n const setup = pendingSessions.get(sessionOptions.sessionId);\n let host: HeadlessSessionHost;\n try {\n host = await baseSessionManager.create(sessionOptions);\n } catch (error) {\n if (setup !== undefined && pendingSessions.delete(sessionOptions.sessionId))\n await setup.cleanup().catch((cleanupError: unknown) => notice(String(cleanupError)));\n throw error;\n }\n if (setup === undefined || mountSessionApis === undefined) return host;\n try {\n const apis = await mountSessionApis(sessionOptions, host);\n pendingSessions.delete(sessionOptions.sessionId);\n sessionArtifacts.set(sessionOptions.sessionId, { ...setup, apis });\n return host;\n } catch (error) {\n pendingSessions.delete(sessionOptions.sessionId);\n await baseSessionManager\n .closeSession(sessionOptions.sessionId)\n .catch((closeError: unknown) => notice(String(closeError)));\n await setup.cleanup().catch((cleanupError: unknown) => notice(String(cleanupError)));\n throw error;\n }\n },\n get: (sessionId) => baseSessionManager.get(sessionId),\n sessions: () => baseSessionManager.sessions(),\n closeSession: closeManagedSession,\n async close() {\n const ids = baseSessionManager.sessions().map((session) => session.runtime.sessionId);\n const outcomes = await Promise.allSettled(ids.map((id) => closeManagedSession(id)));\n const failures = outcomes\n .filter((outcome): outcome is PromiseRejectedResult => outcome.status === 'rejected')\n .map((outcome) => outcome.reason);\n if (failures.length > 0) throw new AggregateError(failures, 'Headless session shutdown failed');\n },\n };\n\n let requestSessionApi: (\n scope: DoomHubSessionScope,\n request: DoomHubSessionApiRequest,\n ) => Promise<Response> = async () => Response.json({ error: 'Session API unavailable.' }, { status: 404 });\n let openSession: (\n request: DoomHubSessionCreateRequest,\n sessionId?: string,\n ) => Promise<DoomHubSessionScope> = async () => {\n throw new Error('The cockpit session service is not ready.');\n };\n let admitWorkspace: (root: string) => Promise<{ id: string; root: string; available: boolean }> = async () => {\n throw new Error('Workspace admission is not ready.');\n };\n const computerUse = await createComputerUseBinding();\n let hub!: HeadlessHub;\n hub = createHeadlessHub({\n manager: sessionManager,\n admitWorkspace: (root) => admitWorkspace(root),\n onWorkspaceRemoved: (workspaceId) => {\n workspaces.remove(workspaceId);\n webCompositions?.remove({ scope: 'workspace', workspaceId });\n },\n createSession: (request) => openSession(request),\n sessionReservations: {\n read(id, parentSessionId) {\n if (!cockpit) throw new Error('Session setup is not ready.');\n return cockpit.sessionReservations.read(id, parentSessionId);\n },\n async prepare(id, parentSessionId, cwd) {\n if (!cockpit) throw new Error('Session setup is not ready.');\n return cockpit.sessionReservations.prepare(id, parentSessionId, cwd);\n },\n async complete(id, parentSessionId) {\n if (!cockpit) throw new Error('Session setup is not ready.');\n return cockpit.sessionReservations.complete(id, parentSessionId);\n },\n },\n onNotice: notice,\n hubToken: () => attachToken,\n requestSessionApi: (scope, request) => requestSessionApi(scope, request),\n ...(computerUse === undefined ? {} : { computerUse }),\n });\n let harnessContext: Awaited<ReturnType<typeof buildHarnessContext>> | undefined;\n let cockpit: Awaited<ReturnType<typeof serveHeadlessServer>> | undefined;\n let remoteRuntime: RemoteRuntime | undefined;\n let attachToken: string | undefined;\n let webCompositions: ReturnType<typeof createWebCompositions> | undefined;\n\n try {\n await telemetry.runInSpan('doompi_server.startup', {}, async () => {\n const token = fs.readFileSync(options.tokenFile, 'utf8').trim();\n if (!token) throw new Error('The attach token file is empty.');\n attachToken = token;\n\n const resolved = resolveSessionIdentity(options.agentArgs, {\n sessionId: options.sessionId ?? crypto.randomUUID(),\n sessionName: options.sessionName,\n });\n\n const homeDirectory = baseEnvironment.HOME ?? os.homedir();\n const globalRoot = globalDoomConfigDirectory(homeDirectory);\n webCompositions = createWebCompositions(path.join(globalRoot, 'server'), notice);\n const loadComposition = async (\n root: string,\n scope: 'global' | 'workspace' | 'session',\n selection?: { root: string; majorMode: string; activeLayers: string[] },\n ) => {\n const registration = readSyncRegistration(root, homeDirectory);\n const source = resolveServerBundleSource({ registration });\n if (source.kind !== 'descriptor')\n throw new Error(`Run the scoped DoomPi sync for '${root}' before opening it.`);\n const selected =\n selection ??\n (() => {\n const config = loadMajorModesConfig(root, homeDirectory);\n const majorMode = config.defaultMajorMode;\n return { root, majorMode, activeLayers: resolveLayers(config, majorMode) };\n })();\n return loadServerBundle(scope, {\n ...source,\n ...selected,\n retainCandidates: scope === 'session',\n onNotice: notice,\n });\n };\n const loadSessionMcp = async (\n root: string,\n selection: { majorMode: string; activeLayers: readonly string[] },\n ): Promise<LoadedMcpBundle> => {\n const registration = readSyncRegistration(root, homeDirectory);\n if (registration?.mcpBundle === undefined)\n throw new Error(`Run the scoped DoomPi sync for '${root}' before opening its MCP runtime.`);\n return loadMcpBundle({\n directory: path.dirname(registration.mcpBundle.path),\n generation: registration.generation,\n fingerprint: registration.mcpBundle.fingerprint,\n descriptorSha256: registration.mcpBundle.sha256,\n majorMode: selection.majorMode,\n activeLayers: selection.activeLayers,\n retainCandidates: true,\n onNotice: notice,\n });\n };\n const sharedApiContext = {\n homeDirectory,\n environment: baseEnvironment,\n hubToken: token,\n sessionService: hub.sessionService,\n directEvents: hub.directEvents,\n repositories: () =>\n hub.workspaces().map((workspace) => ({\n id: workspace.id,\n path: workspace.root,\n name: workspace.root.split('/').at(-1) ?? workspace.id,\n active: hub.snapshot().some((session) => session.workspaceId === workspace.id),\n })),\n resolveRepository: (id: string) => hub.workspaces().find((workspace) => workspace.id === id)?.root,\n readRepositorySync: (id: string) => {\n const root = hub.workspaces().find((workspace) => workspace.id === id)?.root;\n if (!root) return undefined;\n const drift = readSyncDrift({ repoRoot: root, homeDirectory, requireWebBundle: true });\n const state = readSyncState(root, homeDirectory);\n return { ...drift, mcpProjection: state?.fileState.mcpProjection };\n },\n onNotice: notice,\n };\n const globalBundle = await loadComposition(globalRoot, 'global');\n webCompositions.publishShell(readSyncRegistration(globalRoot, homeDirectory)!);\n remoteRuntime = createRemoteRuntime({\n homeDirectory,\n registrationToken: token,\n bundleTrust: () => webCompositions?.shellTrust(),\n onNotice: notice,\n forward: async (request) => {\n if (!cockpit || !attachToken)\n return Response.json({ error: 'The headless server is not ready.' }, { status: 503 });\n const from = new URL(request.url);\n const headers = new Headers(request.headers);\n headers.set('x-doompi-token', attachToken);\n return fetch(\n new URL(`${from.pathname}${from.search}`, cockpit.url),\n new Request(request, { headers, redirect: 'manual' }),\n );\n },\n connectProtocol: (pathname) => {\n if (!cockpit || !attachToken) throw new Error('The headless protocol listener is not ready.');\n const url = new URL(pathname, cockpit.url);\n url.protocol = 'ws:';\n return new WebSocket(url, { headers: { 'x-doompi-token': attachToken } });\n },\n });\n await hub.mountFacets(globalBundle.facets, {\n ...sharedApiContext,\n scope: 'global',\n remoteControl: { fetch: (request: Request) => remoteRuntime!.fetchLocal(request) },\n });\n webCompositions.publish(\n { scope: 'global' },\n readSyncRegistration(globalRoot, homeDirectory)!,\n hub.channelTypes(),\n );\n const admissions = new Map<string, Promise<{ id: string; root: string; available: boolean }>>();\n admitWorkspace = async (from) => {\n const root = fs.realpathSync(findRepositoryRoot(from));\n const id = resolveSyncLocation(root, homeDirectory).identity.worktreeId;\n const existing = hub.workspaces().find((workspace) => workspace.id === id);\n if (existing !== undefined && existing.available !== false) return { ...existing, available: true };\n const pending = admissions.get(id);\n if (pending) return pending;\n const wasRemembered = workspaces.list().some((workspace) => workspace.id === id);\n if (!wasRemembered) workspaces.add({ id, root });\n hub.registerWorkspace({ id, root, available: false });\n const admission = (async () => {\n const syncEnvironment: NodeJS.ProcessEnv = { ...baseEnvironment, DOOMPI_ROOT: root };\n for (const key of [HARNESS_STATE_POINTER, ...Object.values(HARNESS_STATE_KEYS)]) delete syncEnvironment[key];\n await syncWorkspace(root, syncEnvironment);\n const bundle = await loadComposition(root, 'workspace');\n await hub.mountFacets(bundle.facets, {\n ...sharedApiContext,\n scope: 'workspace',\n workspaceId: id,\n workspaceRoot: root,\n cwd: root,\n resolveRepository: (requestedId) => (requestedId === id ? root : undefined),\n });\n webCompositions?.publish(\n { scope: 'workspace', workspaceId: id },\n readSyncRegistration(root, homeDirectory)!,\n hub.channelTypes(),\n );\n return { id, root, available: true };\n })();\n admissions.set(id, admission);\n try {\n return await admission;\n } catch (error) {\n if (!wasRemembered) {\n await hub.removeWorkspace(id);\n workspaces.remove(id);\n }\n throw error;\n } finally {\n admissions.delete(id);\n }\n };\n for (const record of openSessions.list()) {\n if (workspaces.list().some((workspace) => workspace.id === record.workspaceId)) continue;\n try {\n const root = fs.realpathSync(findRepositoryRoot(record.cwd));\n const id = resolveSyncLocation(root, homeDirectory).identity.worktreeId;\n if (id === record.workspaceId) workspaces.add({ id, root });\n else\n notice(\n `Session '${record.sessionId}' no longer resolves to its recorded workspace; skipping registration.`,\n );\n } catch (error) {\n notice(\n `Session '${record.sessionId}' workspace could not be registered: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n for (const workspace of workspaces.list()) {\n hub.registerWorkspace({ ...workspace, available: false });\n try {\n const root = fs.realpathSync(findRepositoryRoot(workspace.root));\n const id = resolveSyncLocation(root, homeDirectory).identity.worktreeId;\n if (root !== workspace.root || id !== workspace.id) {\n notice(\n `Workspace '${workspace.root}' no longer resolves to its recorded identity; leaving it unavailable.`,\n );\n continue;\n }\n await admitWorkspace(workspace.root);\n } catch (error) {\n notice(\n `Workspace '${workspace.root}' could not be restored: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n\n const sessionHostOptions = (\n context: Awaited<ReturnType<typeof buildHarnessContext>>,\n bundle: Awaited<ReturnType<typeof loadServerBundle>>,\n mcpBundle: LoadedMcpBundle,\n identity: {\n sessionId: string;\n sessionName: string;\n parentSessionId?: string;\n sessionProvenance?: string;\n },\n workspaceId?: string,\n ): HeadlessSessionHostOptions => {\n const policyOptions = context.options;\n const sessionSelection = {\n root: policyOptions.repoRoot,\n majorMode: policyOptions.majorMode,\n activeLayers: context.selectedLayers,\n domains: policyOptions.domains,\n profile: context.profile,\n state: { 'minor-mode': [] },\n };\n return {\n cwd: policyOptions.cwd,\n repoRoot: policyOptions.repoRoot,\n sessionId: identity.sessionId,\n workspaceId: workspaceId ?? resolveSyncLocation(policyOptions.repoRoot, homeDirectory).identity.worktreeId,\n sessionName: identity.sessionName,\n webComposition: webCompositions?.publish(\n { scope: 'session', sessionId: identity.sessionId },\n readSyncRegistration(policyOptions.repoRoot, homeDirectory)!,\n hub.channelTypes(),\n ),\n ...(identity.parentSessionId === undefined ? {} : { parentSessionId: identity.parentSessionId }),\n ...(identity.sessionProvenance === undefined ? {} : { sessionProvenance: identity.sessionProvenance }),\n agentArgs: policyOptions.piArgs,\n environment: Object.freeze({ ...context.environment }),\n selection: sessionSelection,\n selectionOverrides: (['majorMode', 'domains', 'profile'] as const).filter((axis) => {\n const flag = axis === 'majorMode' ? '--major-mode' : `--${axis}`;\n return (\n identity.sessionId === resolved.identity.sessionId &&\n resolved.agentArgs.some((arg) => arg === flag || arg.startsWith(`${flag}=`))\n );\n }),\n inheritedSelection: () => {\n const environment = { ...baseEnvironment };\n for (const key of [HARNESS_STATE_POINTER, ...Object.values(HARNESS_STATE_KEYS)]) delete environment[key];\n const defaults = resolveHarnessOptions({\n args: ['--cwd', policyOptions.cwd],\n cwd: policyOptions.cwd,\n environment,\n });\n return { majorMode: defaults.majorMode, domains: defaults.domains, profile: defaults.profile };\n },\n candidates: bundle.descriptor.entries,\n mcpPlugins: mcpBundle.plugins,\n resolveSelection: (requested) => {\n const config = loadMajorModesConfig(policyOptions.repoRoot, policyOptions.homeDirectory);\n return {\n ...requested,\n activeLayers: filterHookDisabledLayers(\n config,\n resolveLayers(config, requested.majorMode),\n policyOptions.hooks,\n ),\n };\n },\n onNotice: notice,\n };\n };\n\n mountSessionApis = (sessionOptions, host) =>\n serveSessionApis({\n sessionId: sessionOptions.sessionId,\n cwd: sessionOptions.cwd,\n environment: sessionOptions.environment,\n directEvents: hub.directEvents,\n ...(computerUse === undefined\n ? {}\n : {\n computerUse: {\n get available() {\n return computerUse.available;\n },\n get enabled() {\n return computerUse.enabled === true;\n },\n authorize: (headers: Headers) => computerUse.authorize?.(headers) === true,\n claim: () => computerUse.claimSession?.(sessionOptions.sessionId),\n subscribe: (listener: () => void) => computerUse.subscribe?.(listener) ?? (() => undefined),\n },\n }),\n hubToken: token,\n sessionService: hub.sessionService,\n pluginRegistry: hub.pluginRegistry,\n apis: [],\n facets: pendingSessions.get(sessionOptions.sessionId)?.bundle.facets ?? [],\n workspaceId: sessionOptions.workspaceId,\n workspaceRoot: sessionOptions.repoRoot,\n homeDirectory,\n mountChannel: (channel) => {\n const dispose = hub.registerChannel(channel, { scope: 'session', sessionId: sessionOptions.sessionId });\n return { mounted: true, dispose };\n },\n prepareFacets: host.prepareFacets,\n activateFacets: host.activateFacets,\n canDispatch: host.canDispatch,\n telemetry,\n onNotice: notice,\n });\n\n requestSessionApi = async (scope, request) => {\n const session = hub.session(scope.sessionId);\n const artifacts = sessionArtifacts.get(scope.sessionId);\n if (session === undefined || session.cwd !== scope.cwd || artifacts === undefined)\n return Response.json({ error: 'Session not found.' }, { status: 404 });\n if (!/^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/u.test(request.basePath))\n return Response.json({ error: 'Invalid session API base path.' }, { status: 400 });\n if (!request.path.startsWith('/') || request.path.startsWith('//') || request.path.includes('#'))\n return Response.json({ error: 'Invalid session API path.' }, { status: 400 });\n const body = request.body === null || request.body === undefined ? undefined : request.body;\n return artifacts.apis.request(\n new Request(`http://doompi.local/api/plugins/${request.basePath}${request.path}`, {\n method: request.method,\n headers: request.headers,\n ...(body === undefined ? {} : { body }),\n ...(request.signal === undefined ? {} : { signal: request.signal }),\n }),\n );\n };\n\n if (!options.noSession) {\n harnessContext = await buildHarnessContext(\n resolveHarnessOptions({ args: resolved.agentArgs, cwd: baseCwd, environment: baseEnvironment }),\n harnessTelemetry,\n );\n const activeHarnessContext = harnessContext;\n try {\n await admitWorkspace(harnessContext.options.repoRoot);\n const initialBundle = await loadComposition(harnessContext.options.repoRoot, 'session', {\n root: harnessContext.options.repoRoot,\n majorMode: harnessContext.options.majorMode,\n activeLayers: harnessContext.selectedLayers,\n });\n const initialMcpBundle = await loadSessionMcp(harnessContext.options.repoRoot, {\n majorMode: harnessContext.options.majorMode,\n activeLayers: harnessContext.selectedLayers,\n });\n pendingSessions.set(resolved.identity.sessionId, {\n cleanup: () => activeHarnessContext.cleanup(),\n bundle: initialBundle,\n mcpBundle: initialMcpBundle,\n });\n await hub.create(sessionHostOptions(harnessContext, initialBundle, initialMcpBundle, resolved.identity));\n } catch (error) {\n pendingSessions.delete(resolved.identity.sessionId);\n await activeHarnessContext.cleanup().catch((cleanupError: unknown) => notice(String(cleanupError)));\n throw error;\n }\n await bounded(harnessTelemetry.flush(), 'initial composition telemetry flush', notice);\n }\n\n const reservedOpens = new Map<string, Promise<DoomHubSessionScope>>();\n openSession = async (request, sessionId) => {\n request.signal?.throwIfAborted();\n if (request.reservationId !== undefined) {\n if (!request.parentSessionId || !cockpit) throw new Error('A reserved session requires its owning parent.');\n const prepared = await cockpit.sessionReservations.prepare(\n request.reservationId,\n request.parentSessionId,\n request.cwd,\n );\n if (sessionId !== undefined && sessionId !== prepared.sessionId)\n throw new Error('Reserved session identity cannot change.');\n sessionId = prepared.sessionId;\n const existing = hub.session(sessionId);\n if (existing) {\n if (existing.cwd !== prepared.cwd || existing.parentSessionId !== request.parentSessionId)\n throw new Error('Reserved session target does not match.');\n return { sessionId, cwd: existing.cwd, workspaceId: existing.workspaceId };\n }\n if (openSessions.list().some((record) => record.sessionId === sessionId))\n throw new Error('Resume the recorded session instead of recreating it.');\n const pending = reservedOpens.get(sessionId);\n if (pending) return pending;\n request = { ...request, cwd: prepared.cwd };\n }\n const identity = {\n sessionId: sessionId ?? crypto.randomUUID(),\n sessionName: request.name,\n parentSessionId: request.parentSessionId,\n sessionProvenance: request.sessionProvenance,\n };\n const inheritedWorkspaceId =\n request.sessionProvenance === 'worktree' && request.parentSessionId\n ? (hub.session(request.parentSessionId)?.workspaceId ??\n openSessions.list().find((record) => record.sessionId === request.parentSessionId)?.workspaceId)\n : undefined;\n if (request.sessionProvenance === 'worktree' && inheritedWorkspaceId === undefined)\n throw new Error('Worktree session requires its parent workspace.');\n const start = (async (): Promise<DoomHubSessionScope> => {\n const childIdentity = resolveSessionIdentity([], identity);\n const childEnvironment = { ...baseEnvironment };\n for (const key of [HARNESS_STATE_POINTER, ...Object.values(HARNESS_STATE_KEYS)]) delete childEnvironment[key];\n const childContext = await buildHarnessContext(\n resolveHarnessOptions({\n args: ['--cwd', request.cwd, ...childIdentity.agentArgs],\n cwd: request.cwd,\n environment: childEnvironment,\n }),\n harnessTelemetry,\n );\n try {\n if (inheritedWorkspaceId === undefined) {\n await admitWorkspace(childContext.options.repoRoot);\n } else {\n const inheritedWorkspace = hub\n .workspaces()\n .find((workspace) => workspace.id === inheritedWorkspaceId && workspace.available !== false);\n if (inheritedWorkspace === undefined) throw new Error('Worktree parent workspace is unavailable.');\n const syncEnvironment: NodeJS.ProcessEnv = {\n ...baseEnvironment,\n DOOMPI_ROOT: childContext.options.repoRoot,\n };\n for (const key of [HARNESS_STATE_POINTER, ...Object.values(HARNESS_STATE_KEYS)])\n delete syncEnvironment[key];\n await syncWorkspace(childContext.options.repoRoot, syncEnvironment);\n }\n const bundle = await loadComposition(childContext.options.repoRoot, 'session', {\n root: childContext.options.repoRoot,\n majorMode: childContext.options.majorMode,\n activeLayers: childContext.selectedLayers,\n });\n const mcpBundle = await loadSessionMcp(childContext.options.repoRoot, {\n majorMode: childContext.options.majorMode,\n activeLayers: childContext.selectedLayers,\n });\n request.signal?.throwIfAborted();\n pendingSessions.set(identity.sessionId, { cleanup: () => childContext.cleanup(), bundle, mcpBundle });\n const created = await hub.create(\n sessionHostOptions(childContext, bundle, mcpBundle, identity, inheritedWorkspaceId),\n );\n request.signal?.throwIfAborted();\n if (created.workspaceId !== undefined) {\n const saved = openSessions.add({\n sessionId: created.id,\n workspaceId: created.workspaceId,\n cwd: created.cwd,\n name: created.name,\n createdAt: created.createdAt,\n ...(created.parentSessionId === undefined ? {} : { parentSessionId: created.parentSessionId }),\n ...(created.sessionProvenance === undefined ? {} : { sessionProvenance: created.sessionProvenance }),\n });\n if (saved === false) throw new Error('The new session could not be durably recorded.');\n }\n return { sessionId: identity.sessionId, cwd: childContext.options.cwd, workspaceId: created.workspaceId };\n } catch (error) {\n if (hub.session(identity.sessionId)) await hub.closeSession(identity.sessionId);\n else {\n pendingSessions.delete(identity.sessionId);\n await childContext.cleanup().catch((cleanupError: unknown) => notice(String(cleanupError)));\n }\n throw error;\n }\n })();\n if (request.reservationId !== undefined) reservedOpens.set(identity.sessionId, start);\n try {\n return await start;\n } finally {\n if (reservedOpens.get(identity.sessionId) === start) reservedOpens.delete(identity.sessionId);\n }\n };\n });\n\n const workspaceResumes = new Map<string, Promise<string>>();\n cockpit = await serveHeadlessServer({\n port: options.webPort,\n headlessHub: hub,\n token: attachToken,\n sessionMcpPublicOrigin: () => remoteRuntime?.remote.publicOrigin(),\n sessionMcpStateDir: serverDirectory,\n sessionMcpPublicOriginRevision: () => remoteRuntime?.remote.publicOriginRevision() ?? 0,\n isSessionPersisted: (sessionId, cwd) =>\n openSessions.list().some((record) => record.sessionId === sessionId && record.cwd === cwd),\n workspaceHistory: (workspaceId) => {\n const workspaceRoot = hub\n .workspaces()\n .find((workspace) => workspace.id === workspaceId && workspace.available !== false)?.root;\n if (!workspaceRoot) throw new Error('Workspace not found.');\n return listSavedSessions(\n path.join(serverDirectory, 'sessions'),\n workspaceRoot,\n new Set(hub.snapshot().map((active) => active.id)),\n );\n },\n resumeWorkspaceSession: async (workspaceId, targetSessionId) => {\n const key = `${workspaceId}\\0${targetSessionId}`;\n const pending = workspaceResumes.get(key);\n if (pending) return pending;\n const resume = (async () => {\n const workspaceRoot = hub\n .workspaces()\n .find((workspace) => workspace.id === workspaceId && workspace.available !== false)?.root;\n if (!workspaceRoot) throw new Error('Workspace not found.');\n const saved = await listSavedSessions(\n path.join(serverDirectory, 'sessions'),\n workspaceRoot,\n new Set(hub.snapshot().map((active) => active.id)),\n );\n const target = saved.find((item) => item.id === targetSessionId);\n if (!target) throw new Error('Saved Pi thread not found in this workspace.');\n await openSession({ cwd: workspaceRoot, name: target.name ?? 'untitled' }, target.id);\n return target.id;\n })();\n workspaceResumes.set(key, resume);\n try {\n return await resume;\n } finally {\n workspaceResumes.delete(key);\n }\n },\n sessionHistory: (session) => {\n const workspaceRoot = hub.workspaces().find((workspace) => workspace.id === session.workspaceId)?.root;\n if (!workspaceRoot) throw new Error('Session workspace not found.');\n return listSavedSessions(\n path.join(piAgentDirectory(baseEnvironment), 'server', 'sessions'),\n workspaceRoot,\n new Set(hub.snapshot().map((active) => active.id)),\n );\n },\n readDormantTranscript: (record, request, context) => {\n const workspaceRoot = hub.workspaces().find((workspace) => workspace.id === record.workspaceId)?.root;\n if (!workspaceRoot) throw new Error('Saved transcript unavailable.');\n return readSqliteTranscript(\n path.join(piAgentDirectory(baseEnvironment), 'server', 'sessions', `${record.sessionId}.sqlite`),\n request,\n context,\n { sessionId: record.sessionId, workspaceRoot },\n );\n },\n restartSession: async (session) => {\n const workspaceRoot = hub.workspaces().find((workspace) => workspace.id === session.workspaceId)?.root;\n if (!workspaceRoot) throw new Error('Session workspace not found.');\n const syncEnvironment: NodeJS.ProcessEnv = { ...baseEnvironment, DOOMPI_ROOT: workspaceRoot };\n for (const key of [HARNESS_STATE_POINTER, ...Object.values(HARNESS_STATE_KEYS)]) delete syncEnvironment[key];\n try {\n await syncWorkspace(workspaceRoot, syncEnvironment);\n } catch (error) {\n notice(`Workspace sync failed before restart: ${error instanceof Error ? error.message : String(error)}`);\n throw new Error('Workspace sync failed; the session is still running.', { cause: error });\n }\n await hub.closeSession(session.id);\n await openSession(\n {\n cwd: session.cwd,\n name: session.name,\n ...(session.parentSessionId === undefined ? {} : { parentSessionId: session.parentSessionId }),\n ...(session.sessionProvenance === undefined ? {} : { sessionProvenance: session.sessionProvenance }),\n },\n session.id,\n );\n },\n resumeSession: async (session, targetSessionId) => {\n const workspaceRoot = hub.workspaces().find((workspace) => workspace.id === session.workspaceId)?.root;\n if (!workspaceRoot) throw new Error('Session workspace not found.');\n const saved = await listSavedSessions(\n path.join(piAgentDirectory(baseEnvironment), 'server', 'sessions'),\n workspaceRoot,\n new Set(hub.snapshot().map((active) => active.id)),\n );\n const target = saved.find((item) => item.id === targetSessionId);\n if (!target) throw new Error('Saved Pi thread not found in this workspace.');\n await hub.closeSession(session.id);\n await openSession({ cwd: session.cwd, name: target.name ?? 'untitled' }, target.id);\n return target.id;\n },\n dormantSessions: () => openSessions.list(),\n removeDormantSession: (record: OpenSessionRecord) => openSessions.remove(record.sessionId),\n reviveSession: async (record: OpenSessionRecord) => {\n // A failed wake may be transient, for example while another server still\n // owns the journal. Keep the record so the user can retry after resolving\n // the conflict instead of losing the session from the cockpit.\n await openSession(\n {\n cwd: record.cwd,\n name: record.name,\n ...(record.parentSessionId === undefined ? {} : { parentSessionId: record.parentSessionId }),\n ...(record.sessionProvenance === undefined ? {} : { sessionProvenance: record.sessionProvenance }),\n },\n record.sessionId,\n );\n },\n requestAsset: (request) => webCompositions?.request(request) ?? Promise.resolve(undefined),\n compositions: () => ({\n global: webCompositions?.get({ scope: 'global' }),\n publicKey: webCompositions?.publicKey(),\n shell: webCompositions?.shellTrust(),\n workspaces: hub.workspaces().map((workspace) => ({\n ...workspace,\n webComposition: webCompositions?.get({ scope: 'workspace', workspaceId: workspace.id }),\n })),\n }),\n telemetry,\n onNotice: notice,\n });\n notice(`protocol on ${cockpit.url}/api/ws`);\n let resolveShutdown!: (exitCode: number) => void;\n const shutdown = new Promise<number>((resolve) => {\n resolveShutdown = resolve;\n });\n const stop = (): void => resolveShutdown(0);\n signal.addEventListener('abort', stop, { once: true });\n if (signal.aborted) stop();\n try {\n return await shutdown;\n } finally {\n signal.removeEventListener('abort', stop);\n }\n } finally {\n shuttingDown = true;\n clearInterval(eventLoopMonitor);\n await bounded(telemetry.recordEvent('doompi_server.shutdown'), 'shutdown telemetry', notice);\n await Promise.allSettled([cockpit?.close()]);\n await bounded(remoteRuntime?.close() ?? Promise.resolve(), 'remote control shutdown', notice);\n try {\n await hub.close();\n } catch (error) {\n notice(error instanceof Error ? error.message : String(error));\n }\n try {\n await sessionManager.close();\n } catch (error) {\n notice(error instanceof Error ? error.message : String(error));\n }\n computerUse?.close?.();\n webCompositions?.close();\n const pendingCleanups = [...pendingSessions.values()].map((setup) => setup.cleanup());\n pendingSessions.clear();\n await Promise.allSettled(pendingCleanups);\n await bounded(harnessTelemetry.flush(), 'harness telemetry flush', notice);\n await bounded(harnessTelemetry.shutdown(), 'harness telemetry shutdown', notice);\n await bounded(telemetry.flush(), 'server telemetry flush', notice);\n await bounded(telemetry.shutdown(), 'server telemetry shutdown', notice);\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"runtime.mjs","names":[],"sources":["../../../../src/builders/server/runtime.ts"],"sourcesContent":["import crypto from 'node:crypto';\nimport fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\n\nimport { globalDoomConfigDirectory } from '@agimon-ai/doompi-config/config';\nimport { filterHookDisabledLayers, loadMajorModesConfig, resolveLayers } from '@agimon-ai/doompi-config/majorModes';\nimport { createHeadlessHub, type HeadlessHub } from '@agimon-ai/doompi-core/headlessHub';\nimport { serveHeadlessServer } from '@agimon-ai/doompi-core/headlessServer';\nimport type { HeadlessSessionHost, HeadlessSessionHostOptions } from '@agimon-ai/doompi-core/headlessSessionHost';\nimport { createHeadlessSessionManager } from '@agimon-ai/doompi-core/headlessSessionManager';\nimport {\n createOpenSessionRegistry,\n createWorkspaceRegistry,\n listSavedSessions,\n readSqliteTranscript,\n} from '@agimon-ai/doompi-core/history';\nimport type { OpenSessionRecord } from '@agimon-ai/doompi-core/history';\nimport type {\n DoomHubSessionApiRequest,\n DoomHubSessionCreateRequest,\n DoomHubSessionScope,\n} from '@agimon-ai/doompi-core/hubChannel';\nimport { loadMcpBundle, type LoadedMcpBundle } from '@agimon-ai/doompi-core/mcpFacet';\nimport { serveSessionApis, type PackageApiServer } from '@agimon-ai/doompi-core/packageApiServer';\nimport { piAgentDirectory } from '@agimon-ai/doompi-core/piSettings';\nimport { createRemoteRuntime, type RemoteRuntime } from '@agimon-ai/doompi-core/remoteRuntime';\nimport type { HeadlessSessionManager } from '@agimon-ai/doompi-core/runtimeHeadlessSessionManager';\nimport { createHarnessTelemetry } from '@agimon-ai/doompi-core/runtimeLogSinkTelemetry';\nimport { loadServerBundle, resolveServerBundleSource } from '@agimon-ai/doompi-core/serverFacet';\nimport { createServerTelemetry } from '@agimon-ai/doompi-core/serverTelemetry';\nimport { resolveSyncLocation } from '@agimon-ai/doompi-core/syncLocation';\nimport { readSyncRegistration } from '@agimon-ai/doompi-core/syncRegistration';\nimport { createWebCompositions } from '@agimon-ai/doompi-core/webCompositions';\nimport { readMinorModeCatalog } from '@agimon-ai/doompi-minor-mode';\nimport WebSocket from 'ws';\n\nimport { HARNESS_STATE_KEYS, HARNESS_STATE_POINTER } from '../../composition/harnessState';\nimport { findRepositoryRoot } from '../../composition/repository';\nimport { readSyncDrift } from '../../composition/syncDrift';\nimport { readSyncState } from '../../composition/syncState';\nimport { buildHarnessContext } from '../cli/harnessContext';\nimport { createComputerUseBinding } from './computerUseBinding';\nimport { publishHeadlessSelectionStatus } from './selectionStatus';\nimport { resolveSessionIdentity } from './sessionArguments';\nimport type { ServeOptions, ServerRuntimeEnvironment } from './types';\nconst TELEMETRY_SHUTDOWN_TIMEOUT_MS = 2_000;\n\nasync function bounded(operation: Promise<unknown>, label: string, notice: (message: string) => void): Promise<void> {\n let timeout: NodeJS.Timeout | undefined;\n try {\n await Promise.race([\n operation,\n new Promise<void>((resolve) => {\n timeout = setTimeout(resolve, TELEMETRY_SHUTDOWN_TIMEOUT_MS);\n }),\n ]);\n } catch (error) {\n notice(`${label} failed: ${error instanceof Error ? error.message : String(error)}`);\n } finally {\n if (timeout) clearTimeout(timeout);\n }\n}\n\nexport async function runServerRuntime(options: ServeOptions, runtime: ServerRuntimeEnvironment): Promise<number> {\n const { cwd: baseCwd, environment: baseEnvironment, notice, resolveHarnessOptions, signal, syncWorkspace } = runtime;\n const telemetry = createServerTelemetry({ cwd: baseCwd, env: baseEnvironment, warn: notice });\n const serverDirectory = path.join(piAgentDirectory(baseEnvironment), 'server');\n const workspaces = createWorkspaceRegistry({ directory: serverDirectory, onNotice: notice });\n // Beside the journals it names, because a record pointing at a sessions\n // directory it is not stored next to is a record that can outlive its target.\n const openSessions = createOpenSessionRegistry({\n directory: serverDirectory,\n onNotice: notice,\n });\n let nextEventLoopTick = performance.now() + 1_000;\n const eventLoopMonitor = setInterval(() => {\n const now = performance.now();\n const delay = Math.max(0, now - nextEventLoopTick);\n nextEventLoopTick = now + 1_000;\n if (delay >= 100)\n void telemetry\n .recordEvent('doompi_server.event_loop_delay', { duration_ms: Math.round(delay) })\n .catch((error: unknown) => notice(`event loop telemetry failed: ${String(error)}`));\n }, 1_000);\n eventLoopMonitor.unref();\n const harnessTelemetry = createHarnessTelemetry({\n cwd: baseCwd,\n env: baseEnvironment,\n warn: notice,\n deferSpans: true,\n });\n const baseSessionManager = createHeadlessSessionManager({\n publishSelectionStatus: publishHeadlessSelectionStatus,\n contextGroups: (context) =>\n (readMinorModeCatalog(context)?.list() ?? [])\n .filter(({ state }) => state.activation === 'active')\n .map(({ descriptor }) => ({ id: descriptor.id, label: descriptor.label, kind: 'minor' })),\n });\n type SessionSetup = {\n cleanup: () => Promise<void>;\n bundle: Awaited<ReturnType<typeof loadServerBundle>>;\n mcpBundle: LoadedMcpBundle;\n };\n type SessionArtifacts = SessionSetup & { apis: PackageApiServer };\n const pendingSessions = new Map<string, SessionSetup>();\n const sessionArtifacts = new Map<string, SessionArtifacts>();\n let mountSessionApis:\n | ((options: HeadlessSessionHostOptions, host: HeadlessSessionHost) => Promise<PackageApiServer>)\n | undefined;\n /**\n * Shutdown runs every session through the same close path a user-initiated\n * close uses, so without this the registry would be emptied by the very event\n * it exists to survive.\n */\n let shuttingDown = false;\n\n const closeManagedSession = async (sessionId: string): Promise<void> => {\n if (!shuttingDown) openSessions.remove(sessionId);\n const artifacts = sessionArtifacts.get(sessionId);\n sessionArtifacts.delete(sessionId);\n webCompositions?.remove({ scope: 'session', sessionId });\n const failures: unknown[] = [];\n try {\n await artifacts?.apis.close();\n } catch (error) {\n failures.push(error);\n }\n try {\n await artifacts?.cleanup();\n } catch (error) {\n failures.push(error);\n }\n try {\n await baseSessionManager.closeSession(sessionId);\n } catch (error) {\n failures.push(error);\n }\n if (failures.length > 0) throw new AggregateError(failures, `Session '${sessionId}' shutdown failed`);\n };\n\n const sessionManager: HeadlessSessionManager = {\n async create(sessionOptions) {\n const setup = pendingSessions.get(sessionOptions.sessionId);\n let host: HeadlessSessionHost;\n try {\n host = await baseSessionManager.create(sessionOptions);\n } catch (error) {\n if (setup !== undefined && pendingSessions.delete(sessionOptions.sessionId))\n await setup.cleanup().catch((cleanupError: unknown) => notice(String(cleanupError)));\n throw error;\n }\n if (setup === undefined || mountSessionApis === undefined) return host;\n try {\n const apis = await mountSessionApis(sessionOptions, host);\n pendingSessions.delete(sessionOptions.sessionId);\n sessionArtifacts.set(sessionOptions.sessionId, { ...setup, apis });\n return host;\n } catch (error) {\n pendingSessions.delete(sessionOptions.sessionId);\n await baseSessionManager\n .closeSession(sessionOptions.sessionId)\n .catch((closeError: unknown) => notice(String(closeError)));\n await setup.cleanup().catch((cleanupError: unknown) => notice(String(cleanupError)));\n throw error;\n }\n },\n get: (sessionId) => baseSessionManager.get(sessionId),\n sessions: () => baseSessionManager.sessions(),\n closeSession: closeManagedSession,\n async close() {\n const ids = baseSessionManager.sessions().map((session) => session.runtime.sessionId);\n const outcomes = await Promise.allSettled(ids.map((id) => closeManagedSession(id)));\n const failures = outcomes\n .filter((outcome): outcome is PromiseRejectedResult => outcome.status === 'rejected')\n .map((outcome) => outcome.reason);\n if (failures.length > 0) throw new AggregateError(failures, 'Headless session shutdown failed');\n },\n };\n\n let requestSessionApi: (\n scope: DoomHubSessionScope,\n request: DoomHubSessionApiRequest,\n ) => Promise<Response> = async () => Response.json({ error: 'Session API unavailable.' }, { status: 404 });\n let openSession: (\n request: DoomHubSessionCreateRequest,\n sessionId?: string,\n ) => Promise<DoomHubSessionScope> = async () => {\n throw new Error('The cockpit session service is not ready.');\n };\n let admitWorkspace: (root: string) => Promise<{ id: string; root: string; available: boolean }> = async () => {\n throw new Error('Workspace admission is not ready.');\n };\n const computerUse = await createComputerUseBinding();\n let hub!: HeadlessHub;\n hub = createHeadlessHub({\n manager: sessionManager,\n admitWorkspace: (root) => admitWorkspace(root),\n onWorkspaceRemoved: (workspaceId) => {\n workspaces.remove(workspaceId);\n webCompositions?.remove({ scope: 'workspace', workspaceId });\n },\n createSession: (request) => openSession(request),\n sessionReservations: {\n read(id, parentSessionId) {\n if (!cockpit) throw new Error('Session setup is not ready.');\n return cockpit.sessionReservations.read(id, parentSessionId);\n },\n async prepare(id, parentSessionId, cwd) {\n if (!cockpit) throw new Error('Session setup is not ready.');\n return cockpit.sessionReservations.prepare(id, parentSessionId, cwd);\n },\n async complete(id, parentSessionId) {\n if (!cockpit) throw new Error('Session setup is not ready.');\n return cockpit.sessionReservations.complete(id, parentSessionId);\n },\n },\n onNotice: notice,\n hubToken: () => attachToken,\n requestSessionApi: (scope, request) => requestSessionApi(scope, request),\n ...(computerUse === undefined ? {} : { computerUse }),\n });\n const stopPersistSessionNames = hub.onEvent((event) => {\n if (event.kind !== 'upsert') return;\n const record = openSessions.list().find((entry) => entry.sessionId === event.session.id);\n if (record === undefined || record.name === event.session.name) return;\n openSessions.add({ ...record, name: event.session.name });\n });\n let harnessContext: Awaited<ReturnType<typeof buildHarnessContext>> | undefined;\n let cockpit: Awaited<ReturnType<typeof serveHeadlessServer>> | undefined;\n let remoteRuntime: RemoteRuntime | undefined;\n let attachToken: string | undefined;\n let webCompositions: ReturnType<typeof createWebCompositions> | undefined;\n\n try {\n await telemetry.runInSpan('doompi_server.startup', {}, async () => {\n const token = fs.readFileSync(options.tokenFile, 'utf8').trim();\n if (!token) throw new Error('The attach token file is empty.');\n attachToken = token;\n\n const resolved = resolveSessionIdentity(options.agentArgs, {\n sessionId: options.sessionId ?? crypto.randomUUID(),\n sessionName: options.sessionName,\n });\n\n const homeDirectory = baseEnvironment.HOME ?? os.homedir();\n const globalRoot = globalDoomConfigDirectory(homeDirectory);\n webCompositions = createWebCompositions(path.join(globalRoot, 'server'), notice);\n const loadComposition = async (\n root: string,\n scope: 'global' | 'workspace' | 'session',\n selection?: { root: string; majorMode: string; activeLayers: string[] },\n ) => {\n const registration = readSyncRegistration(root, homeDirectory);\n const source = resolveServerBundleSource({ registration });\n if (source.kind !== 'descriptor')\n throw new Error(`Run the scoped DoomPi sync for '${root}' before opening it.`);\n const selected =\n selection ??\n (() => {\n const config = loadMajorModesConfig(root, homeDirectory);\n const majorMode = config.defaultMajorMode;\n return { root, majorMode, activeLayers: resolveLayers(config, majorMode) };\n })();\n return loadServerBundle(scope, {\n ...source,\n ...selected,\n retainCandidates: scope === 'session',\n onNotice: notice,\n });\n };\n const loadSessionMcp = async (\n root: string,\n selection: { majorMode: string; activeLayers: readonly string[] },\n ): Promise<LoadedMcpBundle> => {\n const registration = readSyncRegistration(root, homeDirectory);\n if (registration?.mcpBundle === undefined)\n throw new Error(`Run the scoped DoomPi sync for '${root}' before opening its MCP runtime.`);\n return loadMcpBundle({\n directory: path.dirname(registration.mcpBundle.path),\n generation: registration.generation,\n fingerprint: registration.mcpBundle.fingerprint,\n descriptorSha256: registration.mcpBundle.sha256,\n majorMode: selection.majorMode,\n activeLayers: selection.activeLayers,\n retainCandidates: true,\n onNotice: notice,\n });\n };\n const sharedApiContext = {\n homeDirectory,\n environment: baseEnvironment,\n hubToken: token,\n sessionService: hub.sessionService,\n directEvents: hub.directEvents,\n repositories: () =>\n hub.workspaces().map((workspace) => ({\n id: workspace.id,\n path: workspace.root,\n name: workspace.root.split('/').at(-1) ?? workspace.id,\n active: hub.snapshot().some((session) => session.workspaceId === workspace.id),\n })),\n resolveRepository: (id: string) => hub.workspaces().find((workspace) => workspace.id === id)?.root,\n readRepositorySync: (id: string) => {\n const root = hub.workspaces().find((workspace) => workspace.id === id)?.root;\n if (!root) return undefined;\n const drift = readSyncDrift({ repoRoot: root, homeDirectory, requireWebBundle: true });\n const state = readSyncState(root, homeDirectory);\n return { ...drift, mcpProjection: state?.fileState.mcpProjection };\n },\n onNotice: notice,\n };\n const globalBundle = await loadComposition(globalRoot, 'global');\n webCompositions.publishShell(readSyncRegistration(globalRoot, homeDirectory)!);\n remoteRuntime = createRemoteRuntime({\n homeDirectory,\n registrationToken: token,\n bundleTrust: () => webCompositions?.shellTrust(),\n onNotice: notice,\n forward: async (request) => {\n if (!cockpit || !attachToken)\n return Response.json({ error: 'The headless server is not ready.' }, { status: 503 });\n const from = new URL(request.url);\n const headers = new Headers(request.headers);\n headers.set('x-doompi-token', attachToken);\n return fetch(\n new URL(`${from.pathname}${from.search}`, cockpit.url),\n new Request(request, { headers, redirect: 'manual' }),\n );\n },\n connectProtocol: (pathname) => {\n if (!cockpit || !attachToken) throw new Error('The headless protocol listener is not ready.');\n const url = new URL(pathname, cockpit.url);\n url.protocol = 'ws:';\n return new WebSocket(url, { headers: { 'x-doompi-token': attachToken } });\n },\n });\n await hub.mountFacets(globalBundle.facets, {\n ...sharedApiContext,\n scope: 'global',\n remoteControl: { fetch: (request: Request) => remoteRuntime!.fetchLocal(request) },\n });\n webCompositions.publish(\n { scope: 'global' },\n readSyncRegistration(globalRoot, homeDirectory)!,\n hub.channelTypes(),\n );\n const admissions = new Map<string, Promise<{ id: string; root: string; available: boolean }>>();\n admitWorkspace = async (from) => {\n const root = fs.realpathSync(findRepositoryRoot(from));\n const id = resolveSyncLocation(root, homeDirectory).identity.worktreeId;\n const existing = hub.workspaces().find((workspace) => workspace.id === id);\n if (existing !== undefined && existing.available !== false) return { ...existing, available: true };\n const pending = admissions.get(id);\n if (pending) return pending;\n const wasRemembered = workspaces.list().some((workspace) => workspace.id === id);\n if (!wasRemembered) workspaces.add({ id, root });\n hub.registerWorkspace({ id, root, available: false });\n const admission = (async () => {\n const syncEnvironment: NodeJS.ProcessEnv = { ...baseEnvironment, DOOMPI_ROOT: root };\n for (const key of [HARNESS_STATE_POINTER, ...Object.values(HARNESS_STATE_KEYS)]) delete syncEnvironment[key];\n await syncWorkspace(root, syncEnvironment);\n const bundle = await loadComposition(root, 'workspace');\n await hub.mountFacets(bundle.facets, {\n ...sharedApiContext,\n scope: 'workspace',\n workspaceId: id,\n workspaceRoot: root,\n cwd: root,\n resolveRepository: (requestedId) => (requestedId === id ? root : undefined),\n });\n webCompositions?.publish(\n { scope: 'workspace', workspaceId: id },\n readSyncRegistration(root, homeDirectory)!,\n hub.channelTypes(),\n );\n return { id, root, available: true };\n })();\n admissions.set(id, admission);\n try {\n return await admission;\n } catch (error) {\n if (!wasRemembered) {\n await hub.removeWorkspace(id);\n workspaces.remove(id);\n }\n throw error;\n } finally {\n admissions.delete(id);\n }\n };\n for (const record of openSessions.list()) {\n if (workspaces.list().some((workspace) => workspace.id === record.workspaceId)) continue;\n try {\n const root = fs.realpathSync(findRepositoryRoot(record.cwd));\n const id = resolveSyncLocation(root, homeDirectory).identity.worktreeId;\n if (id === record.workspaceId) workspaces.add({ id, root });\n else\n notice(\n `Session '${record.sessionId}' no longer resolves to its recorded workspace; skipping registration.`,\n );\n } catch (error) {\n notice(\n `Session '${record.sessionId}' workspace could not be registered: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n for (const workspace of workspaces.list()) {\n hub.registerWorkspace({ ...workspace, available: false });\n try {\n const root = fs.realpathSync(findRepositoryRoot(workspace.root));\n const id = resolveSyncLocation(root, homeDirectory).identity.worktreeId;\n if (root !== workspace.root || id !== workspace.id) {\n notice(\n `Workspace '${workspace.root}' no longer resolves to its recorded identity; leaving it unavailable.`,\n );\n continue;\n }\n await admitWorkspace(workspace.root);\n } catch (error) {\n notice(\n `Workspace '${workspace.root}' could not be restored: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n\n const sessionHostOptions = (\n context: Awaited<ReturnType<typeof buildHarnessContext>>,\n bundle: Awaited<ReturnType<typeof loadServerBundle>>,\n mcpBundle: LoadedMcpBundle,\n identity: {\n sessionId: string;\n sessionName: string;\n parentSessionId?: string;\n sessionProvenance?: string;\n },\n workspaceId?: string,\n ): HeadlessSessionHostOptions => {\n const policyOptions = context.options;\n const sessionSelection = {\n root: policyOptions.repoRoot,\n majorMode: policyOptions.majorMode,\n activeLayers: context.selectedLayers,\n domains: policyOptions.domains,\n profile: context.profile,\n state: { 'minor-mode': [] },\n };\n return {\n cwd: policyOptions.cwd,\n repoRoot: policyOptions.repoRoot,\n sessionId: identity.sessionId,\n workspaceId: workspaceId ?? resolveSyncLocation(policyOptions.repoRoot, homeDirectory).identity.worktreeId,\n sessionName: identity.sessionName,\n webComposition: webCompositions?.publish(\n { scope: 'session', sessionId: identity.sessionId },\n readSyncRegistration(policyOptions.repoRoot, homeDirectory)!,\n hub.channelTypes(),\n ),\n ...(identity.parentSessionId === undefined ? {} : { parentSessionId: identity.parentSessionId }),\n ...(identity.sessionProvenance === undefined ? {} : { sessionProvenance: identity.sessionProvenance }),\n agentArgs: policyOptions.piArgs,\n environment: Object.freeze({ ...context.environment }),\n selection: sessionSelection,\n selectionOverrides: (['majorMode', 'domains', 'profile'] as const).filter((axis) => {\n const flag = axis === 'majorMode' ? '--major-mode' : `--${axis}`;\n return (\n identity.sessionId === resolved.identity.sessionId &&\n resolved.agentArgs.some((arg) => arg === flag || arg.startsWith(`${flag}=`))\n );\n }),\n inheritedSelection: () => {\n const environment = { ...baseEnvironment };\n for (const key of [HARNESS_STATE_POINTER, ...Object.values(HARNESS_STATE_KEYS)]) delete environment[key];\n const defaults = resolveHarnessOptions({\n args: ['--cwd', policyOptions.cwd],\n cwd: policyOptions.cwd,\n environment,\n });\n return { majorMode: defaults.majorMode, domains: defaults.domains, profile: defaults.profile };\n },\n candidates: bundle.descriptor.entries,\n mcpPlugins: mcpBundle.plugins,\n resolveSelection: (requested) => {\n const config = loadMajorModesConfig(policyOptions.repoRoot, policyOptions.homeDirectory);\n return {\n ...requested,\n activeLayers: filterHookDisabledLayers(\n config,\n resolveLayers(config, requested.majorMode),\n policyOptions.hooks,\n ),\n };\n },\n onNotice: notice,\n };\n };\n\n mountSessionApis = (sessionOptions, host) =>\n serveSessionApis({\n sessionId: sessionOptions.sessionId,\n cwd: sessionOptions.cwd,\n environment: sessionOptions.environment,\n directEvents: hub.directEvents,\n ...(computerUse === undefined\n ? {}\n : {\n computerUse: {\n get available() {\n return computerUse.available;\n },\n get enabled() {\n return computerUse.enabled === true;\n },\n authorize: (headers: Headers) => computerUse.authorize?.(headers) === true,\n claim: () => computerUse.claimSession?.(sessionOptions.sessionId),\n subscribe: (listener: () => void) => computerUse.subscribe?.(listener) ?? (() => undefined),\n },\n }),\n hubToken: token,\n sessionService: hub.sessionService,\n pluginRegistry: hub.pluginRegistry,\n apis: [],\n facets: pendingSessions.get(sessionOptions.sessionId)?.bundle.facets ?? [],\n workspaceId: sessionOptions.workspaceId,\n workspaceRoot: sessionOptions.repoRoot,\n homeDirectory,\n mountChannel: (channel) => {\n const dispose = hub.registerChannel(channel, { scope: 'session', sessionId: sessionOptions.sessionId });\n return { mounted: true, dispose };\n },\n prepareFacets: host.prepareFacets,\n activateFacets: host.activateFacets,\n canDispatch: host.canDispatch,\n telemetry,\n onNotice: notice,\n });\n\n requestSessionApi = async (scope, request) => {\n const session = hub.session(scope.sessionId);\n const artifacts = sessionArtifacts.get(scope.sessionId);\n if (session === undefined || session.cwd !== scope.cwd || artifacts === undefined)\n return Response.json({ error: 'Session not found.' }, { status: 404 });\n if (!/^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/u.test(request.basePath))\n return Response.json({ error: 'Invalid session API base path.' }, { status: 400 });\n if (!request.path.startsWith('/') || request.path.startsWith('//') || request.path.includes('#'))\n return Response.json({ error: 'Invalid session API path.' }, { status: 400 });\n const body = request.body === null || request.body === undefined ? undefined : request.body;\n return artifacts.apis.request(\n new Request(`http://doompi.local/api/plugins/${request.basePath}${request.path}`, {\n method: request.method,\n headers: request.headers,\n ...(body === undefined ? {} : { body }),\n ...(request.signal === undefined ? {} : { signal: request.signal }),\n }),\n );\n };\n\n if (!options.noSession) {\n harnessContext = await buildHarnessContext(\n resolveHarnessOptions({ args: resolved.agentArgs, cwd: baseCwd, environment: baseEnvironment }),\n harnessTelemetry,\n );\n const activeHarnessContext = harnessContext;\n try {\n await admitWorkspace(harnessContext.options.repoRoot);\n const initialBundle = await loadComposition(harnessContext.options.repoRoot, 'session', {\n root: harnessContext.options.repoRoot,\n majorMode: harnessContext.options.majorMode,\n activeLayers: harnessContext.selectedLayers,\n });\n const initialMcpBundle = await loadSessionMcp(harnessContext.options.repoRoot, {\n majorMode: harnessContext.options.majorMode,\n activeLayers: harnessContext.selectedLayers,\n });\n pendingSessions.set(resolved.identity.sessionId, {\n cleanup: () => activeHarnessContext.cleanup(),\n bundle: initialBundle,\n mcpBundle: initialMcpBundle,\n });\n await hub.create(sessionHostOptions(harnessContext, initialBundle, initialMcpBundle, resolved.identity));\n } catch (error) {\n pendingSessions.delete(resolved.identity.sessionId);\n await activeHarnessContext.cleanup().catch((cleanupError: unknown) => notice(String(cleanupError)));\n throw error;\n }\n await bounded(harnessTelemetry.flush(), 'initial composition telemetry flush', notice);\n }\n\n const reservedOpens = new Map<string, Promise<DoomHubSessionScope>>();\n openSession = async (request, sessionId) => {\n request.signal?.throwIfAborted();\n if (request.reservationId !== undefined) {\n if (!request.parentSessionId || !cockpit) throw new Error('A reserved session requires its owning parent.');\n const prepared = await cockpit.sessionReservations.prepare(\n request.reservationId,\n request.parentSessionId,\n request.cwd,\n );\n if (sessionId !== undefined && sessionId !== prepared.sessionId)\n throw new Error('Reserved session identity cannot change.');\n sessionId = prepared.sessionId;\n const existing = hub.session(sessionId);\n if (existing) {\n if (existing.cwd !== prepared.cwd || existing.parentSessionId !== request.parentSessionId)\n throw new Error('Reserved session target does not match.');\n return { sessionId, cwd: existing.cwd, workspaceId: existing.workspaceId };\n }\n if (openSessions.list().some((record) => record.sessionId === sessionId))\n throw new Error('Resume the recorded session instead of recreating it.');\n const pending = reservedOpens.get(sessionId);\n if (pending) return pending;\n request = { ...request, cwd: prepared.cwd };\n }\n const identity = {\n sessionId: sessionId ?? crypto.randomUUID(),\n sessionName: request.name,\n parentSessionId: request.parentSessionId,\n sessionProvenance: request.sessionProvenance,\n };\n const inheritedWorkspaceId =\n request.sessionProvenance === 'worktree' && request.parentSessionId\n ? (hub.session(request.parentSessionId)?.workspaceId ??\n openSessions.list().find((record) => record.sessionId === request.parentSessionId)?.workspaceId)\n : undefined;\n if (request.sessionProvenance === 'worktree' && inheritedWorkspaceId === undefined)\n throw new Error('Worktree session requires its parent workspace.');\n const start = (async (): Promise<DoomHubSessionScope> => {\n const childIdentity = resolveSessionIdentity([], identity);\n const childEnvironment = { ...baseEnvironment };\n for (const key of [HARNESS_STATE_POINTER, ...Object.values(HARNESS_STATE_KEYS)]) delete childEnvironment[key];\n const childContext = await buildHarnessContext(\n resolveHarnessOptions({\n args: ['--cwd', request.cwd, ...childIdentity.agentArgs],\n cwd: request.cwd,\n environment: childEnvironment,\n }),\n harnessTelemetry,\n );\n try {\n if (inheritedWorkspaceId === undefined) {\n await admitWorkspace(childContext.options.repoRoot);\n } else {\n const inheritedWorkspace = hub\n .workspaces()\n .find((workspace) => workspace.id === inheritedWorkspaceId && workspace.available !== false);\n if (inheritedWorkspace === undefined) throw new Error('Worktree parent workspace is unavailable.');\n const syncEnvironment: NodeJS.ProcessEnv = {\n ...baseEnvironment,\n DOOMPI_ROOT: childContext.options.repoRoot,\n };\n for (const key of [HARNESS_STATE_POINTER, ...Object.values(HARNESS_STATE_KEYS)])\n delete syncEnvironment[key];\n await syncWorkspace(childContext.options.repoRoot, syncEnvironment);\n }\n const bundle = await loadComposition(childContext.options.repoRoot, 'session', {\n root: childContext.options.repoRoot,\n majorMode: childContext.options.majorMode,\n activeLayers: childContext.selectedLayers,\n });\n const mcpBundle = await loadSessionMcp(childContext.options.repoRoot, {\n majorMode: childContext.options.majorMode,\n activeLayers: childContext.selectedLayers,\n });\n request.signal?.throwIfAborted();\n pendingSessions.set(identity.sessionId, { cleanup: () => childContext.cleanup(), bundle, mcpBundle });\n const created = await hub.create(\n sessionHostOptions(childContext, bundle, mcpBundle, identity, inheritedWorkspaceId),\n );\n request.signal?.throwIfAborted();\n if (created.workspaceId !== undefined) {\n const saved = openSessions.add({\n sessionId: created.id,\n workspaceId: created.workspaceId,\n cwd: created.cwd,\n name: created.name,\n createdAt: created.createdAt,\n ...(created.parentSessionId === undefined ? {} : { parentSessionId: created.parentSessionId }),\n ...(created.sessionProvenance === undefined ? {} : { sessionProvenance: created.sessionProvenance }),\n });\n if (saved === false) throw new Error('The new session could not be durably recorded.');\n }\n return { sessionId: identity.sessionId, cwd: childContext.options.cwd, workspaceId: created.workspaceId };\n } catch (error) {\n if (hub.session(identity.sessionId)) await hub.closeSession(identity.sessionId);\n else {\n pendingSessions.delete(identity.sessionId);\n await childContext.cleanup().catch((cleanupError: unknown) => notice(String(cleanupError)));\n }\n throw error;\n }\n })();\n if (request.reservationId !== undefined) reservedOpens.set(identity.sessionId, start);\n try {\n return await start;\n } finally {\n if (reservedOpens.get(identity.sessionId) === start) reservedOpens.delete(identity.sessionId);\n }\n };\n });\n\n const workspaceResumes = new Map<string, Promise<string>>();\n cockpit = await serveHeadlessServer({\n port: options.webPort,\n headlessHub: hub,\n token: attachToken,\n sessionMcpPublicOrigin: () => remoteRuntime?.remote.publicOrigin(),\n sessionMcpStateDir: serverDirectory,\n sessionMcpPublicOriginRevision: () => remoteRuntime?.remote.publicOriginRevision() ?? 0,\n isSessionPersisted: (sessionId, cwd) =>\n openSessions.list().some((record) => record.sessionId === sessionId && record.cwd === cwd),\n workspaceHistory: (workspaceId) => {\n const workspaceRoot = hub\n .workspaces()\n .find((workspace) => workspace.id === workspaceId && workspace.available !== false)?.root;\n if (!workspaceRoot) throw new Error('Workspace not found.');\n return listSavedSessions(\n path.join(serverDirectory, 'sessions'),\n workspaceRoot,\n new Set(hub.snapshot().map((active) => active.id)),\n );\n },\n resumeWorkspaceSession: async (workspaceId, targetSessionId) => {\n const key = `${workspaceId}\\0${targetSessionId}`;\n const pending = workspaceResumes.get(key);\n if (pending) return pending;\n const resume = (async () => {\n const workspaceRoot = hub\n .workspaces()\n .find((workspace) => workspace.id === workspaceId && workspace.available !== false)?.root;\n if (!workspaceRoot) throw new Error('Workspace not found.');\n const saved = await listSavedSessions(\n path.join(serverDirectory, 'sessions'),\n workspaceRoot,\n new Set(hub.snapshot().map((active) => active.id)),\n );\n const target = saved.find((item) => item.id === targetSessionId);\n if (!target) throw new Error('Saved Pi thread not found in this workspace.');\n await openSession({ cwd: workspaceRoot, name: target.name ?? 'untitled' }, target.id);\n return target.id;\n })();\n workspaceResumes.set(key, resume);\n try {\n return await resume;\n } finally {\n workspaceResumes.delete(key);\n }\n },\n sessionHistory: (session) => {\n const workspaceRoot = hub.workspaces().find((workspace) => workspace.id === session.workspaceId)?.root;\n if (!workspaceRoot) throw new Error('Session workspace not found.');\n return listSavedSessions(\n path.join(piAgentDirectory(baseEnvironment), 'server', 'sessions'),\n workspaceRoot,\n new Set(hub.snapshot().map((active) => active.id)),\n );\n },\n readDormantTranscript: (record, request, context) => {\n const workspaceRoot = hub.workspaces().find((workspace) => workspace.id === record.workspaceId)?.root;\n if (!workspaceRoot) throw new Error('Saved transcript unavailable.');\n return readSqliteTranscript(\n path.join(piAgentDirectory(baseEnvironment), 'server', 'sessions', `${record.sessionId}.sqlite`),\n request,\n context,\n { sessionId: record.sessionId, workspaceRoot },\n );\n },\n restartSession: async (session) => {\n const workspaceRoot = hub.workspaces().find((workspace) => workspace.id === session.workspaceId)?.root;\n if (!workspaceRoot) throw new Error('Session workspace not found.');\n const syncEnvironment: NodeJS.ProcessEnv = { ...baseEnvironment, DOOMPI_ROOT: workspaceRoot };\n for (const key of [HARNESS_STATE_POINTER, ...Object.values(HARNESS_STATE_KEYS)]) delete syncEnvironment[key];\n try {\n await syncWorkspace(workspaceRoot, syncEnvironment);\n } catch (error) {\n notice(`Workspace sync failed before restart: ${error instanceof Error ? error.message : String(error)}`);\n throw new Error('Workspace sync failed; the session is still running.', { cause: error });\n }\n await hub.closeSession(session.id);\n await openSession(\n {\n cwd: session.cwd,\n name: session.name,\n ...(session.parentSessionId === undefined ? {} : { parentSessionId: session.parentSessionId }),\n ...(session.sessionProvenance === undefined ? {} : { sessionProvenance: session.sessionProvenance }),\n },\n session.id,\n );\n },\n resumeSession: async (session, targetSessionId) => {\n const workspaceRoot = hub.workspaces().find((workspace) => workspace.id === session.workspaceId)?.root;\n if (!workspaceRoot) throw new Error('Session workspace not found.');\n const saved = await listSavedSessions(\n path.join(piAgentDirectory(baseEnvironment), 'server', 'sessions'),\n workspaceRoot,\n new Set(hub.snapshot().map((active) => active.id)),\n );\n const target = saved.find((item) => item.id === targetSessionId);\n if (!target) throw new Error('Saved Pi thread not found in this workspace.');\n await hub.closeSession(session.id);\n await openSession({ cwd: session.cwd, name: target.name ?? 'untitled' }, target.id);\n return target.id;\n },\n dormantSessions: () => openSessions.list(),\n removeDormantSession: (record: OpenSessionRecord) => openSessions.remove(record.sessionId),\n reviveSession: async (record: OpenSessionRecord) => {\n // A failed wake may be transient, for example while another server still\n // owns the journal. Keep the record so the user can retry after resolving\n // the conflict instead of losing the session from the cockpit.\n await openSession(\n {\n cwd: record.cwd,\n name: record.name,\n ...(record.parentSessionId === undefined ? {} : { parentSessionId: record.parentSessionId }),\n ...(record.sessionProvenance === undefined ? {} : { sessionProvenance: record.sessionProvenance }),\n },\n record.sessionId,\n );\n },\n requestAsset: (request) => webCompositions?.request(request) ?? Promise.resolve(undefined),\n compositions: () => ({\n global: webCompositions?.get({ scope: 'global' }),\n publicKey: webCompositions?.publicKey(),\n shell: webCompositions?.shellTrust(),\n workspaces: hub.workspaces().map((workspace) => ({\n ...workspace,\n webComposition: webCompositions?.get({ scope: 'workspace', workspaceId: workspace.id }),\n })),\n }),\n telemetry,\n onNotice: notice,\n });\n notice(`protocol on ${cockpit.url}/api/ws`);\n let resolveShutdown!: (exitCode: number) => void;\n const shutdown = new Promise<number>((resolve) => {\n resolveShutdown = resolve;\n });\n const stop = (): void => resolveShutdown(0);\n signal.addEventListener('abort', stop, { once: true });\n if (signal.aborted) stop();\n try {\n return await shutdown;\n } finally {\n signal.removeEventListener('abort', stop);\n }\n } finally {\n shuttingDown = true;\n stopPersistSessionNames();\n clearInterval(eventLoopMonitor);\n await bounded(telemetry.recordEvent('doompi_server.shutdown'), 'shutdown telemetry', notice);\n await Promise.allSettled([cockpit?.close()]);\n await bounded(remoteRuntime?.close() ?? Promise.resolve(), 'remote control shutdown', notice);\n try {\n await hub.close();\n } catch (error) {\n notice(error instanceof Error ? error.message : String(error));\n }\n try {\n await sessionManager.close();\n } catch (error) {\n notice(error instanceof Error ? error.message : String(error));\n }\n computerUse?.close?.();\n webCompositions?.close();\n const pendingCleanups = [...pendingSessions.values()].map((setup) => setup.cleanup());\n pendingSessions.clear();\n await Promise.allSettled(pendingCleanups);\n await bounded(harnessTelemetry.flush(), 'harness telemetry flush', notice);\n await bounded(harnessTelemetry.shutdown(), 'harness telemetry shutdown', notice);\n await bounded(telemetry.flush(), 'server telemetry flush', notice);\n await bounded(telemetry.shutdown(), 'server telemetry shutdown', notice);\n }\n}\n"],"mappings":"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"}
|
|
@@ -2,13 +2,65 @@ const require_runtime = require("../../../_virtual/_rolldown/runtime.cjs");
|
|
|
2
2
|
const require_harnessOptions = require("../harnessOptions.cjs");
|
|
3
3
|
const require_index = require("../../composition/syncDrift/index.cjs");
|
|
4
4
|
const require_runtime$1 = require("../../builders/server/runtime.cjs");
|
|
5
|
-
const require_workflow = require("../commands/sync/workflow.cjs");
|
|
6
5
|
const require_options = require("./options.cjs");
|
|
6
|
+
let node_child_process = require("node:child_process");
|
|
7
7
|
let node_os = require("node:os");
|
|
8
8
|
node_os = require_runtime.__toESM(node_os, 1);
|
|
9
9
|
let _agimon_ai_doompi_config_config = require("@agimon-ai/doompi-config/config");
|
|
10
10
|
//#region src/cli/server/run.ts
|
|
11
11
|
const DOOMPI_ROOT_ENV = "DOOMPI_ROOT";
|
|
12
|
+
const SYNC_CHILD_SCRIPT = `
|
|
13
|
+
const [workflowUrl, root, globalFlag] = process.argv.slice(1);
|
|
14
|
+
try {
|
|
15
|
+
const { runSync } = await import(workflowUrl);
|
|
16
|
+
let output = '';
|
|
17
|
+
const code = await runSync(globalFlag === '1' ? ['sync', '--global'] : ['sync'], process.env, root, {
|
|
18
|
+
write(chunk) {
|
|
19
|
+
output += String(chunk);
|
|
20
|
+
return true;
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
if (code !== 0) {
|
|
24
|
+
process.stderr.write(output.trim() || \`Workspace sync exited with code \${String(code)}\`);
|
|
25
|
+
process.exitCode = code;
|
|
26
|
+
}
|
|
27
|
+
} catch (error) {
|
|
28
|
+
process.stderr.write(error instanceof Error ? error.message : String(error));
|
|
29
|
+
process.exitCode = 1;
|
|
30
|
+
}
|
|
31
|
+
`;
|
|
32
|
+
function syncWorkflowUrl() {
|
|
33
|
+
const extension = require("url").pathToFileURL(__filename).href.endsWith(".ts") ? "ts" : "mjs";
|
|
34
|
+
return new URL(`../commands/sync/workflow.${extension}`, require("url").pathToFileURL(__filename).href).href;
|
|
35
|
+
}
|
|
36
|
+
function runSyncProcess(root, syncEnvironment, global) {
|
|
37
|
+
const environment = global ? {
|
|
38
|
+
...syncEnvironment,
|
|
39
|
+
[DOOMPI_ROOT_ENV]: root
|
|
40
|
+
} : syncEnvironment;
|
|
41
|
+
return new Promise((resolve, reject) => {
|
|
42
|
+
(0, node_child_process.execFile)(process.execPath, [
|
|
43
|
+
...process.execArgv,
|
|
44
|
+
"--input-type=module",
|
|
45
|
+
"--eval",
|
|
46
|
+
SYNC_CHILD_SCRIPT,
|
|
47
|
+
syncWorkflowUrl(),
|
|
48
|
+
root,
|
|
49
|
+
global ? "1" : "0"
|
|
50
|
+
], {
|
|
51
|
+
cwd: root,
|
|
52
|
+
env: environment,
|
|
53
|
+
encoding: "utf8"
|
|
54
|
+
}, (error, stdout, stderr) => {
|
|
55
|
+
if (!error) {
|
|
56
|
+
resolve();
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
const detail = `${stderr || stdout}`.trim();
|
|
60
|
+
reject(new Error(detail || `Workspace sync exited with code ${String(error.code ?? 1)}`));
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
}
|
|
12
64
|
async function runServer(args) {
|
|
13
65
|
const options = require_options.parseServeOptions(args);
|
|
14
66
|
const environment = Object.freeze({ ...process.env });
|
|
@@ -19,16 +71,7 @@ async function runServer(args) {
|
|
|
19
71
|
requireFreshSources: false,
|
|
20
72
|
requireWebBundle: true
|
|
21
73
|
}).fresh) return;
|
|
22
|
-
|
|
23
|
-
const environment = global ? {
|
|
24
|
-
...syncEnvironment,
|
|
25
|
-
[DOOMPI_ROOT_ENV]: root
|
|
26
|
-
} : syncEnvironment;
|
|
27
|
-
const code = await require_workflow.runSync(global ? ["sync", "--global"] : ["sync"], environment, root, { write(chunk) {
|
|
28
|
-
output += String(chunk);
|
|
29
|
-
return true;
|
|
30
|
-
} });
|
|
31
|
-
if (code !== 0) throw new Error(output.trim() || `Workspace sync exited with code ${String(code)}`);
|
|
74
|
+
await runSyncProcess(root, syncEnvironment, global);
|
|
32
75
|
};
|
|
33
76
|
const controller = new AbortController();
|
|
34
77
|
const stop = () => controller.abort();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.cjs","names":["parseServeOptions","readSyncDrift","
|
|
1
|
+
{"version":3,"file":"run.cjs","names":["parseServeOptions","readSyncDrift","globalDoomConfigDirectory","os","runServerRuntime"],"sources":["../../../../src/cli/server/run.ts"],"sourcesContent":["import { execFile } from 'node:child_process';\nimport os from 'node:os';\n\nimport { globalDoomConfigDirectory } from '@agimon-ai/doompi-config/config';\n\nimport { runServerRuntime } from '../../builders/server/runtime';\nimport { readSyncDrift } from '../../composition/syncDrift';\nimport { resolveHarnessOptions } from '../harnessOptions';\nimport { parseServeOptions } from './options';\n\nconst DOOMPI_ROOT_ENV = 'DOOMPI_ROOT';\nconst SYNC_CHILD_SCRIPT = `\nconst [workflowUrl, root, globalFlag] = process.argv.slice(1);\ntry {\n const { runSync } = await import(workflowUrl);\n let output = '';\n const code = await runSync(globalFlag === '1' ? ['sync', '--global'] : ['sync'], process.env, root, {\n write(chunk) {\n output += String(chunk);\n return true;\n },\n });\n if (code !== 0) {\n process.stderr.write(output.trim() || \\`Workspace sync exited with code \\${String(code)}\\`);\n process.exitCode = code;\n }\n} catch (error) {\n process.stderr.write(error instanceof Error ? error.message : String(error));\n process.exitCode = 1;\n}\n`;\n\nfunction syncWorkflowUrl(): string {\n const extension = import.meta.url.endsWith('.ts') ? 'ts' : 'mjs';\n return new URL(`../commands/sync/workflow.${extension}`, import.meta.url).href;\n}\n\nfunction runSyncProcess(root: string, syncEnvironment: NodeJS.ProcessEnv, global: boolean): Promise<void> {\n const environment = global ? { ...syncEnvironment, [DOOMPI_ROOT_ENV]: root } : syncEnvironment;\n return new Promise((resolve, reject) => {\n execFile(\n process.execPath,\n [\n ...process.execArgv,\n '--input-type=module',\n '--eval',\n SYNC_CHILD_SCRIPT,\n syncWorkflowUrl(),\n root,\n global ? '1' : '0',\n ],\n { cwd: root, env: environment, encoding: 'utf8' },\n (error, stdout, stderr) => {\n if (!error) {\n resolve();\n return;\n }\n const detail = `${stderr || stdout}`.trim();\n reject(new Error(detail || `Workspace sync exited with code ${String(error.code ?? 1)}`));\n },\n );\n });\n}\nexport async function runServer(args: readonly string[]): Promise<number> {\n const options = parseServeOptions(args);\n const environment = Object.freeze({ ...process.env });\n const syncRuntime = async (root: string, syncEnvironment: NodeJS.ProcessEnv, global = false): Promise<void> => {\n const runtimeDrift = readSyncDrift({\n repoRoot: root,\n homeDirectory: syncEnvironment.HOME,\n requireFreshSources: false,\n requireWebBundle: true,\n });\n if (runtimeDrift.fresh) return;\n await runSyncProcess(root, syncEnvironment, global);\n };\n const controller = new AbortController();\n const stop = () => controller.abort();\n process.on('SIGINT', stop);\n process.on('SIGTERM', stop);\n // An IPC parent owns this server's lifetime. Its channel closes even when the\n // parent is killed before it can forward a termination signal.\n process.on('disconnect', stop);\n try {\n await syncRuntime(globalDoomConfigDirectory(environment.HOME ?? os.homedir()), environment, true);\n return await runServerRuntime(options, {\n cwd: process.cwd(),\n environment,\n signal: controller.signal,\n resolveHarnessOptions,\n notice: (message) => void process.stderr.write(`[doompi-server] ${message}\\n`),\n syncWorkspace: syncRuntime,\n });\n } finally {\n process.off('SIGINT', stop);\n process.off('SIGTERM', stop);\n process.off('disconnect', stop);\n }\n}\n"],"mappings":";;;;;;;;;;AAUA,MAAM,kBAAkB;AACxB,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;AAqB1B,SAAS,kBAA0B;CACjC,MAAM,YAAA,QAAA,KAAA,CAAA,CAAA,cAAA,UAAA,CAAA,CAAA,KAA4B,SAAS,KAAK,IAAI,OAAO;CAC3D,OAAO,IAAI,IAAI,6BAA6B,aAAA,QAAA,KAAA,CAAA,CAAA,cAAA,UAAA,CAAA,CAAA,IAA4B,CAAC,CAAC;AAC5E;AAEA,SAAS,eAAe,MAAc,iBAAoC,QAAgC;CACxG,MAAM,cAAc,SAAS;EAAE,GAAG;GAAkB,kBAAkB;CAAK,IAAI;CAC/E,OAAO,IAAI,SAAS,SAAS,WAAW;EACtC,CAAA,GAAA,mBAAA,SAAA,CACE,QAAQ,UACR;GACE,GAAG,QAAQ;GACX;GACA;GACA;GACA,gBAAgB;GAChB;GACA,SAAS,MAAM;EACjB,GACA;GAAE,KAAK;GAAM,KAAK;GAAa,UAAU;EAAO,IAC/C,OAAO,QAAQ,WAAW;GACzB,IAAI,CAAC,OAAO;IACV,QAAQ;IACR;GACF;GACA,MAAM,SAAS,GAAG,UAAU,SAAS,KAAK;GAC1C,OAAO,IAAI,MAAM,UAAU,mCAAmC,OAAO,MAAM,QAAQ,CAAC,GAAG,CAAC;EAC1F,CACF;CACF,CAAC;AACH;AACA,eAAsB,UAAU,MAA0C;CACxE,MAAM,UAAUA,gBAAAA,kBAAkB,IAAI;CACtC,MAAM,cAAc,OAAO,OAAO,EAAE,GAAG,QAAQ,IAAI,CAAC;CACpD,MAAM,cAAc,OAAO,MAAc,iBAAoC,SAAS,UAAyB;EAO7G,IANqBC,cAAAA,cAAc;GACjC,UAAU;GACV,eAAe,gBAAgB;GAC/B,qBAAqB;GACrB,kBAAkB;EACpB,CACe,CAAC,CAAC,OAAO;EACxB,MAAM,eAAe,MAAM,iBAAiB,MAAM;CACpD;CACA,MAAM,aAAa,IAAI,gBAAgB;CACvC,MAAM,aAAa,WAAW,MAAM;CACpC,QAAQ,GAAG,UAAU,IAAI;CACzB,QAAQ,GAAG,WAAW,IAAI;CAG1B,QAAQ,GAAG,cAAc,IAAI;CAC7B,IAAI;EACF,MAAM,aAAA,GAAYC,gCAAAA,0BAAAA,CAA0B,YAAY,QAAQC,QAAAA,QAAG,QAAQ,CAAC,GAAG,aAAa,IAAI;EAChG,OAAO,MAAMC,kBAAAA,iBAAiB,SAAS;GACrC,KAAK,QAAQ,IAAI;GACjB;GACA,QAAQ,WAAW;GACnB,uBAAA,uBAAA;GACA,SAAS,YAAY,KAAK,QAAQ,OAAO,MAAM,mBAAmB,QAAQ,GAAG;GAC7E,eAAe;EACjB,CAAC;CACH,UAAU;EACR,QAAQ,IAAI,UAAU,IAAI;EAC1B,QAAQ,IAAI,WAAW,IAAI;EAC3B,QAAQ,IAAI,cAAc,IAAI;CAChC;AACF"}
|
|
@@ -1,12 +1,64 @@
|
|
|
1
1
|
import { resolveHarnessOptions } from "../harnessOptions.mjs";
|
|
2
2
|
import { readSyncDrift } from "../../composition/syncDrift/index.mjs";
|
|
3
3
|
import { runServerRuntime } from "../../builders/server/runtime.mjs";
|
|
4
|
-
import { runSync } from "../commands/sync/workflow.mjs";
|
|
5
4
|
import { parseServeOptions } from "./options.mjs";
|
|
5
|
+
import { execFile } from "node:child_process";
|
|
6
6
|
import os from "node:os";
|
|
7
7
|
import { globalDoomConfigDirectory } from "@agimon-ai/doompi-config/config";
|
|
8
8
|
//#region src/cli/server/run.ts
|
|
9
9
|
const DOOMPI_ROOT_ENV = "DOOMPI_ROOT";
|
|
10
|
+
const SYNC_CHILD_SCRIPT = `
|
|
11
|
+
const [workflowUrl, root, globalFlag] = process.argv.slice(1);
|
|
12
|
+
try {
|
|
13
|
+
const { runSync } = await import(workflowUrl);
|
|
14
|
+
let output = '';
|
|
15
|
+
const code = await runSync(globalFlag === '1' ? ['sync', '--global'] : ['sync'], process.env, root, {
|
|
16
|
+
write(chunk) {
|
|
17
|
+
output += String(chunk);
|
|
18
|
+
return true;
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
|
+
if (code !== 0) {
|
|
22
|
+
process.stderr.write(output.trim() || \`Workspace sync exited with code \${String(code)}\`);
|
|
23
|
+
process.exitCode = code;
|
|
24
|
+
}
|
|
25
|
+
} catch (error) {
|
|
26
|
+
process.stderr.write(error instanceof Error ? error.message : String(error));
|
|
27
|
+
process.exitCode = 1;
|
|
28
|
+
}
|
|
29
|
+
`;
|
|
30
|
+
function syncWorkflowUrl() {
|
|
31
|
+
const extension = import.meta.url.endsWith(".ts") ? "ts" : "mjs";
|
|
32
|
+
return new URL(`../commands/sync/workflow.${extension}`, import.meta.url).href;
|
|
33
|
+
}
|
|
34
|
+
function runSyncProcess(root, syncEnvironment, global) {
|
|
35
|
+
const environment = global ? {
|
|
36
|
+
...syncEnvironment,
|
|
37
|
+
[DOOMPI_ROOT_ENV]: root
|
|
38
|
+
} : syncEnvironment;
|
|
39
|
+
return new Promise((resolve, reject) => {
|
|
40
|
+
execFile(process.execPath, [
|
|
41
|
+
...process.execArgv,
|
|
42
|
+
"--input-type=module",
|
|
43
|
+
"--eval",
|
|
44
|
+
SYNC_CHILD_SCRIPT,
|
|
45
|
+
syncWorkflowUrl(),
|
|
46
|
+
root,
|
|
47
|
+
global ? "1" : "0"
|
|
48
|
+
], {
|
|
49
|
+
cwd: root,
|
|
50
|
+
env: environment,
|
|
51
|
+
encoding: "utf8"
|
|
52
|
+
}, (error, stdout, stderr) => {
|
|
53
|
+
if (!error) {
|
|
54
|
+
resolve();
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
const detail = `${stderr || stdout}`.trim();
|
|
58
|
+
reject(new Error(detail || `Workspace sync exited with code ${String(error.code ?? 1)}`));
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
}
|
|
10
62
|
async function runServer(args) {
|
|
11
63
|
const options = parseServeOptions(args);
|
|
12
64
|
const environment = Object.freeze({ ...process.env });
|
|
@@ -17,16 +69,7 @@ async function runServer(args) {
|
|
|
17
69
|
requireFreshSources: false,
|
|
18
70
|
requireWebBundle: true
|
|
19
71
|
}).fresh) return;
|
|
20
|
-
|
|
21
|
-
const environment = global ? {
|
|
22
|
-
...syncEnvironment,
|
|
23
|
-
[DOOMPI_ROOT_ENV]: root
|
|
24
|
-
} : syncEnvironment;
|
|
25
|
-
const code = await runSync(global ? ["sync", "--global"] : ["sync"], environment, root, { write(chunk) {
|
|
26
|
-
output += String(chunk);
|
|
27
|
-
return true;
|
|
28
|
-
} });
|
|
29
|
-
if (code !== 0) throw new Error(output.trim() || `Workspace sync exited with code ${String(code)}`);
|
|
72
|
+
await runSyncProcess(root, syncEnvironment, global);
|
|
30
73
|
};
|
|
31
74
|
const controller = new AbortController();
|
|
32
75
|
const stop = () => controller.abort();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.mjs","names":[],"sources":["../../../../src/cli/server/run.ts"],"sourcesContent":["import os from 'node:os';\n\nimport { globalDoomConfigDirectory } from '@agimon-ai/doompi-config/config';\n\nimport { runServerRuntime } from '../../builders/server/runtime';\nimport { readSyncDrift } from '../../composition/syncDrift';\nimport {
|
|
1
|
+
{"version":3,"file":"run.mjs","names":[],"sources":["../../../../src/cli/server/run.ts"],"sourcesContent":["import { execFile } from 'node:child_process';\nimport os from 'node:os';\n\nimport { globalDoomConfigDirectory } from '@agimon-ai/doompi-config/config';\n\nimport { runServerRuntime } from '../../builders/server/runtime';\nimport { readSyncDrift } from '../../composition/syncDrift';\nimport { resolveHarnessOptions } from '../harnessOptions';\nimport { parseServeOptions } from './options';\n\nconst DOOMPI_ROOT_ENV = 'DOOMPI_ROOT';\nconst SYNC_CHILD_SCRIPT = `\nconst [workflowUrl, root, globalFlag] = process.argv.slice(1);\ntry {\n const { runSync } = await import(workflowUrl);\n let output = '';\n const code = await runSync(globalFlag === '1' ? ['sync', '--global'] : ['sync'], process.env, root, {\n write(chunk) {\n output += String(chunk);\n return true;\n },\n });\n if (code !== 0) {\n process.stderr.write(output.trim() || \\`Workspace sync exited with code \\${String(code)}\\`);\n process.exitCode = code;\n }\n} catch (error) {\n process.stderr.write(error instanceof Error ? error.message : String(error));\n process.exitCode = 1;\n}\n`;\n\nfunction syncWorkflowUrl(): string {\n const extension = import.meta.url.endsWith('.ts') ? 'ts' : 'mjs';\n return new URL(`../commands/sync/workflow.${extension}`, import.meta.url).href;\n}\n\nfunction runSyncProcess(root: string, syncEnvironment: NodeJS.ProcessEnv, global: boolean): Promise<void> {\n const environment = global ? { ...syncEnvironment, [DOOMPI_ROOT_ENV]: root } : syncEnvironment;\n return new Promise((resolve, reject) => {\n execFile(\n process.execPath,\n [\n ...process.execArgv,\n '--input-type=module',\n '--eval',\n SYNC_CHILD_SCRIPT,\n syncWorkflowUrl(),\n root,\n global ? '1' : '0',\n ],\n { cwd: root, env: environment, encoding: 'utf8' },\n (error, stdout, stderr) => {\n if (!error) {\n resolve();\n return;\n }\n const detail = `${stderr || stdout}`.trim();\n reject(new Error(detail || `Workspace sync exited with code ${String(error.code ?? 1)}`));\n },\n );\n });\n}\nexport async function runServer(args: readonly string[]): Promise<number> {\n const options = parseServeOptions(args);\n const environment = Object.freeze({ ...process.env });\n const syncRuntime = async (root: string, syncEnvironment: NodeJS.ProcessEnv, global = false): Promise<void> => {\n const runtimeDrift = readSyncDrift({\n repoRoot: root,\n homeDirectory: syncEnvironment.HOME,\n requireFreshSources: false,\n requireWebBundle: true,\n });\n if (runtimeDrift.fresh) return;\n await runSyncProcess(root, syncEnvironment, global);\n };\n const controller = new AbortController();\n const stop = () => controller.abort();\n process.on('SIGINT', stop);\n process.on('SIGTERM', stop);\n // An IPC parent owns this server's lifetime. Its channel closes even when the\n // parent is killed before it can forward a termination signal.\n process.on('disconnect', stop);\n try {\n await syncRuntime(globalDoomConfigDirectory(environment.HOME ?? os.homedir()), environment, true);\n return await runServerRuntime(options, {\n cwd: process.cwd(),\n environment,\n signal: controller.signal,\n resolveHarnessOptions,\n notice: (message) => void process.stderr.write(`[doompi-server] ${message}\\n`),\n syncWorkspace: syncRuntime,\n });\n } finally {\n process.off('SIGINT', stop);\n process.off('SIGTERM', stop);\n process.off('disconnect', stop);\n }\n}\n"],"mappings":";;;;;;;;AAUA,MAAM,kBAAkB;AACxB,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;AAqB1B,SAAS,kBAA0B;CACjC,MAAM,YAAY,YAAY,IAAI,SAAS,KAAK,IAAI,OAAO;CAC3D,OAAO,IAAI,IAAI,6BAA6B,aAAa,YAAY,GAAG,CAAC,CAAC;AAC5E;AAEA,SAAS,eAAe,MAAc,iBAAoC,QAAgC;CACxG,MAAM,cAAc,SAAS;EAAE,GAAG;GAAkB,kBAAkB;CAAK,IAAI;CAC/E,OAAO,IAAI,SAAS,SAAS,WAAW;EACtC,SACE,QAAQ,UACR;GACE,GAAG,QAAQ;GACX;GACA;GACA;GACA,gBAAgB;GAChB;GACA,SAAS,MAAM;EACjB,GACA;GAAE,KAAK;GAAM,KAAK;GAAa,UAAU;EAAO,IAC/C,OAAO,QAAQ,WAAW;GACzB,IAAI,CAAC,OAAO;IACV,QAAQ;IACR;GACF;GACA,MAAM,SAAS,GAAG,UAAU,SAAS,KAAK;GAC1C,OAAO,IAAI,MAAM,UAAU,mCAAmC,OAAO,MAAM,QAAQ,CAAC,GAAG,CAAC;EAC1F,CACF;CACF,CAAC;AACH;AACA,eAAsB,UAAU,MAA0C;CACxE,MAAM,UAAU,kBAAkB,IAAI;CACtC,MAAM,cAAc,OAAO,OAAO,EAAE,GAAG,QAAQ,IAAI,CAAC;CACpD,MAAM,cAAc,OAAO,MAAc,iBAAoC,SAAS,UAAyB;EAO7G,IANqB,cAAc;GACjC,UAAU;GACV,eAAe,gBAAgB;GAC/B,qBAAqB;GACrB,kBAAkB;EACpB,CACe,CAAC,CAAC,OAAO;EACxB,MAAM,eAAe,MAAM,iBAAiB,MAAM;CACpD;CACA,MAAM,aAAa,IAAI,gBAAgB;CACvC,MAAM,aAAa,WAAW,MAAM;CACpC,QAAQ,GAAG,UAAU,IAAI;CACzB,QAAQ,GAAG,WAAW,IAAI;CAG1B,QAAQ,GAAG,cAAc,IAAI;CAC7B,IAAI;EACF,MAAM,YAAY,0BAA0B,YAAY,QAAQ,GAAG,QAAQ,CAAC,GAAG,aAAa,IAAI;EAChG,OAAO,MAAM,iBAAiB,SAAS;GACrC,KAAK,QAAQ,IAAI;GACjB;GACA,QAAQ,WAAW;GACnB;GACA,SAAS,YAAY,KAAK,QAAQ,OAAO,MAAM,mBAAmB,QAAQ,GAAG;GAC7E,eAAe;EACjB,CAAC;CACH,UAAU;EACR,QAAQ,IAAI,UAAU,IAAI;EAC1B,QAAQ,IAAI,WAAW,IAAI;EAC3B,QAAQ,IAAI,cAAc,IAAI;CAChC;AACF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agimon-ai/doompi",
|
|
3
|
-
"version": "0.0.1-alpha.
|
|
3
|
+
"version": "0.0.1-alpha.89",
|
|
4
4
|
"description": "Opinionated, composable Pi distribution for scoped agent tools, skills, MCP servers, and developer workflows.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -277,19 +277,19 @@
|
|
|
277
277
|
"registry": "https://registry.npmjs.org/"
|
|
278
278
|
},
|
|
279
279
|
"dependencies": {
|
|
280
|
-
"@agimon-ai/doompi-autostop": "0.0.1-alpha.
|
|
281
|
-
"@agimon-ai/doompi-cache": "0.0.1-alpha.
|
|
282
|
-
"@agimon-ai/doompi-config": "0.0.1-alpha.
|
|
283
|
-
"@agimon-ai/doompi-core": "0.0.1-alpha.
|
|
284
|
-
"@agimon-ai/doompi-domain": "0.0.1-alpha.
|
|
285
|
-
"@agimon-ai/doompi-major-mode": "0.0.1-alpha.
|
|
286
|
-
"@agimon-ai/doompi-minor-mode": "0.0.1-alpha.
|
|
287
|
-
"@agimon-ai/doompi-notification": "0.0.1-alpha.
|
|
288
|
-
"@agimon-ai/doompi-profile": "0.0.1-alpha.
|
|
289
|
-
"@agimon-ai/doompi-session": "0.0.1-alpha.
|
|
290
|
-
"@agimon-ai/doompi-skill": "0.0.1-alpha.
|
|
280
|
+
"@agimon-ai/doompi-autostop": "0.0.1-alpha.63",
|
|
281
|
+
"@agimon-ai/doompi-cache": "0.0.1-alpha.52",
|
|
282
|
+
"@agimon-ai/doompi-config": "0.0.1-alpha.85",
|
|
283
|
+
"@agimon-ai/doompi-core": "0.0.1-alpha.86",
|
|
284
|
+
"@agimon-ai/doompi-domain": "0.0.1-alpha.64",
|
|
285
|
+
"@agimon-ai/doompi-major-mode": "0.0.1-alpha.64",
|
|
286
|
+
"@agimon-ai/doompi-minor-mode": "0.0.1-alpha.86",
|
|
287
|
+
"@agimon-ai/doompi-notification": "0.0.1-alpha.63",
|
|
288
|
+
"@agimon-ai/doompi-profile": "0.0.1-alpha.64",
|
|
289
|
+
"@agimon-ai/doompi-session": "0.0.1-alpha.10",
|
|
290
|
+
"@agimon-ai/doompi-skill": "0.0.1-alpha.64",
|
|
291
291
|
"@agimon-ai/doompi-telemetry": "0.0.1-alpha.80",
|
|
292
|
-
"@agimon-ai/doompi-ui": "0.0.1-alpha.
|
|
292
|
+
"@agimon-ai/doompi-ui": "0.0.1-alpha.86",
|
|
293
293
|
"@agimon-ai/doompi-web-security": "0.0.1-alpha.43",
|
|
294
294
|
"@deepseek-ai/cordis": "4.0.2",
|
|
295
295
|
"@earendil-works/chord": "0.87.1",
|
|
@@ -315,7 +315,7 @@
|
|
|
315
315
|
"yaml": "2.9.1"
|
|
316
316
|
},
|
|
317
317
|
"devDependencies": {
|
|
318
|
-
"@agimon-ai/doompi-runner": "0.0.1-alpha.
|
|
318
|
+
"@agimon-ai/doompi-runner": "0.0.1-alpha.86",
|
|
319
319
|
"@agimon-ai/vibe-lint-plugin-doom-cli": "0.0.1-alpha.15",
|
|
320
320
|
"@earendil-works/pi-ai": "0.87.1",
|
|
321
321
|
"@earendil-works/pi-client": "0.87.1",
|