acpx 0.4.0 → 0.5.0

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.
Files changed (47) hide show
  1. package/dist/agent-registry-DGw0-3Tc.js +54 -0
  2. package/dist/agent-registry-DGw0-3Tc.js.map +1 -0
  3. package/dist/{cli-5s-E-Y99.js → cli-CLRrs6eQ.js} +8 -12
  4. package/dist/cli-CLRrs6eQ.js.map +1 -0
  5. package/dist/cli.d.ts +2 -2
  6. package/dist/cli.d.ts.map +1 -1
  7. package/dist/cli.js +1018 -1009
  8. package/dist/cli.js.map +1 -1
  9. package/dist/client-DLTWuu4w.d.ts +116 -0
  10. package/dist/client-DLTWuu4w.d.ts.map +1 -0
  11. package/dist/{flags-BkWInxAq.js → flags-BmubjvOw.js} +5 -55
  12. package/dist/flags-BmubjvOw.js.map +1 -0
  13. package/dist/{flows-DnIYoHI1.js → flows-CR7xCmkR.js} +471 -281
  14. package/dist/flows-CR7xCmkR.js.map +1 -0
  15. package/dist/flows.d.ts +5 -9
  16. package/dist/flows.d.ts.map +1 -1
  17. package/dist/flows.js +1 -1
  18. package/dist/{queue-ipc-CgWf63GN.js → ipc-DN6M4Ui9.js} +12 -571
  19. package/dist/ipc-DN6M4Ui9.js.map +1 -0
  20. package/dist/{acp-jsonrpc-C7pPk9Tw.js → jsonrpc-M3y-qzy8.js} +16 -3
  21. package/dist/jsonrpc-M3y-qzy8.js.map +1 -0
  22. package/dist/{output-C58ukIo3.js → output-Di0M9Et8.js} +8 -22
  23. package/dist/output-Di0M9Et8.js.map +1 -0
  24. package/dist/perf-metrics-D9QC81lB.js +568 -0
  25. package/dist/perf-metrics-D9QC81lB.js.map +1 -0
  26. package/dist/{session-BtpTC2pM.js → prompt-turn-Bt8T3SRR.js} +2304 -3632
  27. package/dist/prompt-turn-Bt8T3SRR.js.map +1 -0
  28. package/dist/{output-render-C7w9NZ2H.js → render-BL5ynRkN.js} +7 -6
  29. package/dist/render-BL5ynRkN.js.map +1 -0
  30. package/dist/runtime.d.ts +266 -0
  31. package/dist/runtime.d.ts.map +1 -0
  32. package/dist/runtime.js +984 -0
  33. package/dist/runtime.js.map +1 -0
  34. package/dist/session-BbN0SBgf.js +1488 -0
  35. package/dist/session-BbN0SBgf.js.map +1 -0
  36. package/dist/{types-CeRKmEQ1.d.ts → types-DXxLBQc3.d.ts} +40 -3
  37. package/dist/types-DXxLBQc3.d.ts.map +1 -0
  38. package/package.json +20 -9
  39. package/dist/acp-jsonrpc-C7pPk9Tw.js.map +0 -1
  40. package/dist/cli-5s-E-Y99.js.map +0 -1
  41. package/dist/flags-BkWInxAq.js.map +0 -1
  42. package/dist/flows-DnIYoHI1.js.map +0 -1
  43. package/dist/output-C58ukIo3.js.map +0 -1
  44. package/dist/output-render-C7w9NZ2H.js.map +0 -1
  45. package/dist/queue-ipc-CgWf63GN.js.map +0 -1
  46. package/dist/session-BtpTC2pM.js.map +0 -1
  47. package/dist/types-CeRKmEQ1.d.ts.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-BbN0SBgf.js","names":["fs","applyRequestedModelIfAdvertised","fs","segmentEventPath","activeEventPath","eventsLockPath","recordConversationSessionUpdate","recordConversationClientOperation"],"sources":["../src/cli/session/contracts.ts","../src/cli/session/prompt-runner.ts","../src/cli/session/session-control.ts","../src/cli/session/session-management.ts","../src/perf-metrics-capture.ts","../src/cli/queue/owner-turn-controller.ts","../src/cli/session/queue-owner-process.ts","../src/session/events.ts","../src/cli/session/runtime.ts","../src/cli/session/queue-owner-runtime.ts","../src/session/session.ts"],"sourcesContent":["import type { AcpClient } from \"../../acp/client.js\";\nimport type { SessionAgentOptions } from \"../../runtime/engine/session-options.js\";\nimport type {\n AcpJsonRpcMessage,\n AcpMessageDirection,\n AuthPolicy,\n ClientOperation,\n McpServer,\n NonInteractivePermissionPolicy,\n OutputErrorEmissionPolicy,\n OutputFormatter,\n PermissionMode,\n PromptInput,\n SessionNotification,\n SessionResumePolicy,\n SessionRecord,\n} from \"../../types.js\";\n\ntype TimedRunOptions = {\n timeoutMs?: number;\n};\n\nexport const DEFAULT_QUEUE_OWNER_TTL_MS = 300_000;\n\nexport function normalizeQueueOwnerTtlMs(ttlMs: number | undefined): number {\n if (ttlMs == null) {\n return DEFAULT_QUEUE_OWNER_TTL_MS;\n }\n\n if (!Number.isFinite(ttlMs) || ttlMs < 0) {\n return DEFAULT_QUEUE_OWNER_TTL_MS;\n }\n\n // 0 means keep alive forever (no TTL)\n return Math.round(ttlMs);\n}\n\nexport type RunOnceOptions = {\n agentCommand: string;\n cwd: string;\n prompt: PromptInput;\n mcpServers?: McpServer[];\n permissionMode: PermissionMode;\n nonInteractivePermissions?: NonInteractivePermissionPolicy;\n authCredentials?: Record<string, string>;\n authPolicy?: AuthPolicy;\n outputFormatter: OutputFormatter;\n onAcpMessage?: (direction: AcpMessageDirection, message: AcpJsonRpcMessage) => void;\n onSessionUpdate?: (notification: SessionNotification) => void;\n onClientOperation?: (operation: ClientOperation) => void;\n suppressSdkConsoleErrors?: boolean;\n verbose?: boolean;\n sessionOptions?: SessionAgentOptions;\n promptRetries?: number;\n} & TimedRunOptions;\n\nexport type SessionCreateOptions = {\n agentCommand: string;\n cwd: string;\n name?: string;\n resumeSessionId?: string;\n mcpServers?: McpServer[];\n permissionMode: PermissionMode;\n nonInteractivePermissions?: NonInteractivePermissionPolicy;\n authCredentials?: Record<string, string>;\n authPolicy?: AuthPolicy;\n verbose?: boolean;\n sessionOptions?: SessionAgentOptions;\n} & TimedRunOptions;\n\nexport type SessionSendOptions = {\n sessionId: string;\n prompt: PromptInput;\n resumePolicy?: SessionResumePolicy;\n mcpServers?: McpServer[];\n permissionMode: PermissionMode;\n nonInteractivePermissions?: NonInteractivePermissionPolicy;\n authCredentials?: Record<string, string>;\n authPolicy?: AuthPolicy;\n outputFormatter: OutputFormatter;\n onAcpMessage?: (direction: AcpMessageDirection, message: AcpJsonRpcMessage) => void;\n onSessionUpdate?: (notification: SessionNotification) => void;\n onClientOperation?: (operation: ClientOperation) => void;\n errorEmissionPolicy?: OutputErrorEmissionPolicy;\n suppressSdkConsoleErrors?: boolean;\n verbose?: boolean;\n waitForCompletion?: boolean;\n ttlMs?: number;\n maxQueueDepth?: number;\n client?: AcpClient;\n promptRetries?: number;\n} & TimedRunOptions;\n\nexport type SessionEnsureOptions = {\n agentCommand: string;\n cwd: string;\n name?: string;\n resumeSessionId?: string;\n mcpServers?: McpServer[];\n permissionMode: PermissionMode;\n nonInteractivePermissions?: NonInteractivePermissionPolicy;\n authCredentials?: Record<string, string>;\n authPolicy?: AuthPolicy;\n verbose?: boolean;\n walkBoundary?: string;\n sessionOptions?: SessionAgentOptions;\n} & TimedRunOptions;\n\nexport type SessionCancelOptions = {\n sessionId: string;\n verbose?: boolean;\n};\n\nexport type SessionCancelResult = {\n sessionId: string;\n cancelled: boolean;\n};\n\nexport type SessionSetModeOptions = {\n sessionId: string;\n modeId: string;\n mcpServers?: McpServer[];\n nonInteractivePermissions?: NonInteractivePermissionPolicy;\n authCredentials?: Record<string, string>;\n authPolicy?: AuthPolicy;\n verbose?: boolean;\n} & TimedRunOptions;\n\nexport type SessionSetModelOptions = {\n sessionId: string;\n modelId: string;\n mcpServers?: McpServer[];\n nonInteractivePermissions?: NonInteractivePermissionPolicy;\n authCredentials?: Record<string, string>;\n authPolicy?: AuthPolicy;\n verbose?: boolean;\n} & TimedRunOptions;\n\nexport type SessionSetConfigOptionOptions = {\n sessionId: string;\n configId: string;\n value: string;\n mcpServers?: McpServer[];\n nonInteractivePermissions?: NonInteractivePermissionPolicy;\n authCredentials?: Record<string, string>;\n authPolicy?: AuthPolicy;\n verbose?: boolean;\n} & TimedRunOptions;\n\nexport type SessionCreateWithClientResult = {\n record: SessionRecord;\n client: AcpClient;\n};\n\nexport type { SessionAgentOptions };\n","import { withTimeout } from \"../../async-control.js\";\nimport {\n withConnectedSession,\n type FullConnectedSessionController,\n} from \"../../runtime/engine/connected-session.js\";\nimport {\n setCurrentModelId,\n setDesiredModeId,\n setDesiredModelId,\n} from \"../../session/mode-preference.js\";\nimport { resolveSessionRecord, writeSessionRecord } from \"../../session/persistence.js\";\nimport type {\n AuthPolicy,\n McpServer,\n NonInteractivePermissionPolicy,\n SessionSetConfigOptionResult,\n SessionSetModelResult,\n SessionSetModeResult,\n} from \"../../types.js\";\nimport type { QueueOwnerActiveSessionController } from \"../queue/owner-turn-controller.js\";\n\nexport type ActiveSessionController = QueueOwnerActiveSessionController;\n\nexport type RunSessionSetModeDirectOptions = {\n sessionRecordId: string;\n modeId: string;\n mcpServers?: McpServer[];\n nonInteractivePermissions?: NonInteractivePermissionPolicy;\n authCredentials?: Record<string, string>;\n authPolicy?: AuthPolicy;\n timeoutMs?: number;\n verbose?: boolean;\n onClientAvailable?: (controller: ActiveSessionController) => void;\n onClientClosed?: () => void;\n};\n\nexport type RunSessionSetConfigOptionDirectOptions = {\n sessionRecordId: string;\n configId: string;\n value: string;\n mcpServers?: McpServer[];\n nonInteractivePermissions?: NonInteractivePermissionPolicy;\n authCredentials?: Record<string, string>;\n authPolicy?: AuthPolicy;\n timeoutMs?: number;\n verbose?: boolean;\n onClientAvailable?: (controller: ActiveSessionController) => void;\n onClientClosed?: () => void;\n};\n\nexport type RunSessionSetModelDirectOptions = {\n sessionRecordId: string;\n modelId: string;\n mcpServers?: McpServer[];\n nonInteractivePermissions?: NonInteractivePermissionPolicy;\n authCredentials?: Record<string, string>;\n authPolicy?: AuthPolicy;\n timeoutMs?: number;\n verbose?: boolean;\n onClientAvailable?: (controller: ActiveSessionController) => void;\n onClientClosed?: () => void;\n};\n\nexport async function runSessionSetModeDirect(\n options: RunSessionSetModeDirectOptions,\n): Promise<SessionSetModeResult> {\n const result = await withConnectedSession({\n sessionRecordId: options.sessionRecordId,\n loadRecord: resolveSessionRecord,\n saveRecord: writeSessionRecord,\n mcpServers: options.mcpServers,\n nonInteractivePermissions: options.nonInteractivePermissions,\n authCredentials: options.authCredentials,\n authPolicy: options.authPolicy,\n timeoutMs: options.timeoutMs,\n verbose: options.verbose,\n onClientAvailable: (controller: FullConnectedSessionController) => {\n options.onClientAvailable?.(controller);\n },\n onClientClosed: options.onClientClosed,\n run: async ({ client, sessionId, record }) => {\n await withTimeout(client.setSessionMode(sessionId, options.modeId), options.timeoutMs);\n setDesiredModeId(record, options.modeId);\n },\n });\n\n return {\n record: result.record,\n resumed: result.resumed,\n loadError: result.loadError,\n };\n}\n\nexport async function runSessionSetModelDirect(\n options: RunSessionSetModelDirectOptions,\n): Promise<SessionSetModelResult> {\n const result = await withConnectedSession({\n sessionRecordId: options.sessionRecordId,\n loadRecord: resolveSessionRecord,\n saveRecord: writeSessionRecord,\n mcpServers: options.mcpServers,\n nonInteractivePermissions: options.nonInteractivePermissions,\n authCredentials: options.authCredentials,\n authPolicy: options.authPolicy,\n timeoutMs: options.timeoutMs,\n verbose: options.verbose,\n onClientAvailable: (controller: FullConnectedSessionController) => {\n options.onClientAvailable?.(controller);\n },\n onClientClosed: options.onClientClosed,\n run: async ({ client, sessionId, record }) => {\n await withTimeout(client.setSessionModel(sessionId, options.modelId), options.timeoutMs);\n setDesiredModelId(record, options.modelId);\n setCurrentModelId(record, options.modelId);\n },\n });\n\n return {\n record: result.record,\n resumed: result.resumed,\n loadError: result.loadError,\n };\n}\n\nexport async function runSessionSetConfigOptionDirect(\n options: RunSessionSetConfigOptionDirectOptions,\n): Promise<SessionSetConfigOptionResult> {\n const result = await withConnectedSession({\n sessionRecordId: options.sessionRecordId,\n loadRecord: resolveSessionRecord,\n saveRecord: writeSessionRecord,\n mcpServers: options.mcpServers,\n nonInteractivePermissions: options.nonInteractivePermissions,\n authCredentials: options.authCredentials,\n authPolicy: options.authPolicy,\n timeoutMs: options.timeoutMs,\n verbose: options.verbose,\n onClientAvailable: (controller: FullConnectedSessionController) => {\n options.onClientAvailable?.(controller);\n },\n onClientClosed: options.onClientClosed,\n run: async ({ client, sessionId, record }) => {\n const response = await withTimeout(\n client.setSessionConfigOption(sessionId, options.configId, options.value),\n options.timeoutMs,\n );\n if (options.configId === \"mode\") {\n setDesiredModeId(record, options.value);\n }\n return response;\n },\n });\n\n return {\n record: result.record,\n response: result.value,\n resumed: result.resumed,\n loadError: result.loadError,\n };\n}\n","import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport {\n setCurrentModelId,\n setDesiredModeId,\n setDesiredModelId,\n} from \"../../session/mode-preference.js\";\nimport { resolveSessionRecord, writeSessionRecord, isoNow } from \"../../session/persistence.js\";\nimport type {\n SessionRecord,\n SessionSetConfigOptionResult,\n SessionSetModelResult,\n SessionSetModeResult,\n} from \"../../types.js\";\nimport {\n isProcessAlive,\n terminateProcess,\n terminateQueueOwnerForSession,\n tryCancelOnRunningOwner,\n trySetConfigOptionOnRunningOwner,\n trySetModelOnRunningOwner,\n trySetModeOnRunningOwner,\n} from \"../queue/ipc.js\";\nimport type {\n SessionCancelOptions,\n SessionCancelResult,\n SessionSetConfigOptionOptions,\n SessionSetModelOptions,\n SessionSetModeOptions,\n} from \"./contracts.js\";\nimport {\n runSessionSetConfigOptionDirect,\n runSessionSetModelDirect,\n runSessionSetModeDirect,\n} from \"./prompt-runner.js\";\n\nexport async function cancelSessionPrompt(\n options: SessionCancelOptions,\n): Promise<SessionCancelResult> {\n const cancelled = await tryCancelOnRunningOwner(options);\n return {\n sessionId: options.sessionId,\n cancelled: cancelled === true,\n };\n}\n\nexport async function setSessionMode(\n options: SessionSetModeOptions,\n): Promise<SessionSetModeResult> {\n const submittedToOwner = await trySetModeOnRunningOwner(\n options.sessionId,\n options.modeId,\n options.timeoutMs,\n options.verbose,\n );\n if (submittedToOwner) {\n const record = await resolveSessionRecord(options.sessionId);\n setDesiredModeId(record, options.modeId);\n await writeSessionRecord(record);\n return {\n record,\n resumed: false,\n };\n }\n\n return await runSessionSetModeDirect({\n sessionRecordId: options.sessionId,\n modeId: options.modeId,\n mcpServers: options.mcpServers,\n nonInteractivePermissions: options.nonInteractivePermissions,\n authCredentials: options.authCredentials,\n authPolicy: options.authPolicy,\n timeoutMs: options.timeoutMs,\n verbose: options.verbose,\n });\n}\n\nexport async function setSessionModel(\n options: SessionSetModelOptions,\n): Promise<SessionSetModelResult> {\n const submittedToOwner = await trySetModelOnRunningOwner(\n options.sessionId,\n options.modelId,\n options.timeoutMs,\n options.verbose,\n );\n if (submittedToOwner) {\n const record = await resolveSessionRecord(options.sessionId);\n setDesiredModelId(record, options.modelId);\n setCurrentModelId(record, options.modelId);\n await writeSessionRecord(record);\n return {\n record,\n resumed: false,\n };\n }\n\n return await runSessionSetModelDirect({\n sessionRecordId: options.sessionId,\n modelId: options.modelId,\n mcpServers: options.mcpServers,\n nonInteractivePermissions: options.nonInteractivePermissions,\n authCredentials: options.authCredentials,\n authPolicy: options.authPolicy,\n timeoutMs: options.timeoutMs,\n verbose: options.verbose,\n });\n}\n\nexport async function setSessionConfigOption(\n options: SessionSetConfigOptionOptions,\n): Promise<SessionSetConfigOptionResult> {\n const ownerResponse = await trySetConfigOptionOnRunningOwner(\n options.sessionId,\n options.configId,\n options.value,\n options.timeoutMs,\n options.verbose,\n );\n if (ownerResponse) {\n const record = await resolveSessionRecord(options.sessionId);\n if (options.configId === \"mode\") {\n setDesiredModeId(record, options.value);\n await writeSessionRecord(record);\n }\n return {\n record,\n response: ownerResponse,\n resumed: false,\n };\n }\n\n return await runSessionSetConfigOptionDirect({\n sessionRecordId: options.sessionId,\n configId: options.configId,\n value: options.value,\n mcpServers: options.mcpServers,\n nonInteractivePermissions: options.nonInteractivePermissions,\n authCredentials: options.authCredentials,\n authPolicy: options.authPolicy,\n timeoutMs: options.timeoutMs,\n verbose: options.verbose,\n });\n}\n\nfunction firstAgentCommandToken(command: string): string | undefined {\n const trimmed = command.trim();\n if (!trimmed) {\n return undefined;\n }\n const token = trimmed.split(/\\s+/, 1)[0];\n return token.length > 0 ? token : undefined;\n}\n\nasync function isLikelyMatchingProcess(pid: number, agentCommand: string): Promise<boolean> {\n const expectedToken = firstAgentCommandToken(agentCommand);\n if (!expectedToken) {\n return false;\n }\n\n const procCmdline = `/proc/${pid}/cmdline`;\n try {\n const payload = await fs.readFile(procCmdline, \"utf8\");\n const argv = payload\n .split(\"\\u0000\")\n .map((entry) => entry.trim())\n .filter((entry) => entry.length > 0);\n if (argv.length === 0) {\n return false;\n }\n\n const executableBase = path.basename(argv[0]);\n const expectedBase = path.basename(expectedToken);\n return (\n executableBase === expectedBase || argv.some((entry) => path.basename(entry) === expectedBase)\n );\n } catch {\n return true;\n }\n}\n\nexport async function closeSession(sessionId: string): Promise<SessionRecord> {\n const record = await resolveSessionRecord(sessionId);\n await terminateQueueOwnerForSession(record.acpxRecordId);\n\n if (\n record.pid != null &&\n isProcessAlive(record.pid) &&\n (await isLikelyMatchingProcess(record.pid, record.agentCommand))\n ) {\n await terminateProcess(record.pid);\n }\n\n record.pid = undefined;\n record.closed = true;\n record.closedAt = isoNow();\n await writeSessionRecord(record);\n\n return record;\n}\n","import { AcpClient, type SessionCreateResult } from \"../../acp/client.js\";\nimport { formatErrorMessage } from \"../../acp/error-normalization.js\";\nimport { withInterrupt, withTimeout } from \"../../async-control.js\";\nimport { createSessionConversation } from \"../../session/conversation-model.js\";\nimport { defaultSessionEventLog } from \"../../session/event-log.js\";\nimport { setCurrentModelId, syncAdvertisedModelState } from \"../../session/mode-preference.js\";\nimport {\n absolutePath,\n findGitRepositoryRoot,\n findSessionByDirectoryWalk,\n isoNow,\n normalizeName,\n writeSessionRecord,\n} from \"../../session/persistence.js\";\nimport { normalizeRuntimeSessionId } from \"../../session/runtime-session-id.js\";\nimport type { SessionEnsureResult, SessionRecord } from \"../../types.js\";\nimport { DEFAULT_QUEUE_OWNER_TTL_MS } from \"./contracts.js\";\nimport type {\n SessionAgentOptions,\n SessionCreateOptions,\n SessionCreateWithClientResult,\n SessionEnsureOptions,\n} from \"./contracts.js\";\nimport { setSessionModel } from \"./session-control.js\";\n\nfunction persistSessionOptions(\n record: SessionRecord,\n options: SessionAgentOptions | undefined,\n): void {\n const next =\n options &&\n ({\n model: typeof options.model === \"string\" ? options.model : undefined,\n allowed_tools: Array.isArray(options.allowedTools) ? [...options.allowedTools] : undefined,\n max_turns: typeof options.maxTurns === \"number\" ? options.maxTurns : undefined,\n } satisfies NonNullable<NonNullable<SessionRecord[\"acpx\"]>[\"session_options\"]>);\n\n const hasValues = Boolean(\n next &&\n ((typeof next.model === \"string\" && next.model.trim().length > 0) ||\n (Array.isArray(next.allowed_tools) && next.allowed_tools.length > 0) ||\n typeof next.max_turns === \"number\"),\n );\n\n if (hasValues && next) {\n record.acpx = {\n ...record.acpx,\n session_options: next,\n };\n return;\n }\n\n if (!record.acpx) {\n return;\n }\n\n delete record.acpx.session_options;\n}\n\nasync function applyRequestedModelIfAdvertised(params: {\n client: AcpClient;\n sessionId: string;\n requestedModel: string | undefined;\n models: SessionCreateResult[\"models\"];\n timeoutMs?: number;\n}): Promise<boolean> {\n const requestedModel =\n typeof params.requestedModel === \"string\" ? params.requestedModel.trim() : \"\";\n if (!requestedModel || !params.models) {\n return false;\n }\n if (params.models.currentModelId === requestedModel) {\n return true;\n }\n\n await withTimeout(\n params.client.setSessionModel(params.sessionId, requestedModel),\n params.timeoutMs,\n );\n return true;\n}\n\nasync function createSessionRecordWithClient(\n client: AcpClient,\n options: SessionCreateOptions,\n): Promise<SessionRecord> {\n const cwd = absolutePath(options.cwd);\n await withTimeout(client.start(), options.timeoutMs);\n let sessionId: string;\n let agentSessionId: string | undefined;\n let sessionModels: SessionCreateResult[\"models\"];\n let requestedModelApplied = false;\n\n if (options.resumeSessionId) {\n if (!client.supportsLoadSession()) {\n throw new Error(\n `Agent command \"${options.agentCommand}\" does not support session/load; cannot resume session ${options.resumeSessionId}`,\n );\n }\n\n try {\n const loadedSession = await withTimeout(\n client.loadSession(options.resumeSessionId, cwd),\n options.timeoutMs,\n );\n sessionId = options.resumeSessionId;\n agentSessionId = normalizeRuntimeSessionId(loadedSession.agentSessionId);\n sessionModels = loadedSession.models;\n requestedModelApplied = await applyRequestedModelIfAdvertised({\n client,\n sessionId,\n requestedModel: options.sessionOptions?.model,\n models: sessionModels,\n timeoutMs: options.timeoutMs,\n });\n } catch (error) {\n throw new Error(\n `Failed to resume ACP session ${options.resumeSessionId}: ${formatErrorMessage(error)}`,\n {\n cause: error,\n },\n );\n }\n } else {\n const createdSession = await withTimeout(client.createSession(cwd), options.timeoutMs);\n sessionId = createdSession.sessionId;\n agentSessionId = normalizeRuntimeSessionId(createdSession.agentSessionId);\n sessionModels = createdSession.models;\n requestedModelApplied = await applyRequestedModelIfAdvertised({\n client,\n sessionId,\n requestedModel: options.sessionOptions?.model,\n models: sessionModels,\n timeoutMs: options.timeoutMs,\n });\n }\n\n const lifecycle = client.getAgentLifecycleSnapshot();\n const now = isoNow();\n const record: SessionRecord = {\n schema: \"acpx.session.v1\",\n acpxRecordId: sessionId,\n acpSessionId: sessionId,\n agentSessionId,\n agentCommand: options.agentCommand,\n cwd,\n name: normalizeName(options.name),\n createdAt: now,\n lastUsedAt: now,\n lastSeq: 0,\n lastRequestId: undefined,\n eventLog: defaultSessionEventLog(sessionId),\n closed: false,\n closedAt: undefined,\n pid: lifecycle.pid,\n agentStartedAt: lifecycle.startedAt,\n protocolVersion: client.initializeResult?.protocolVersion,\n agentCapabilities: client.initializeResult?.agentCapabilities,\n ...createSessionConversation(now),\n acpx: {},\n };\n\n persistSessionOptions(record, options.sessionOptions);\n syncAdvertisedModelState(record, sessionModels);\n if (requestedModelApplied) {\n setCurrentModelId(record, options.sessionOptions?.model);\n }\n\n await writeSessionRecord(record);\n return record;\n}\n\nexport async function createSessionWithClient(\n options: SessionCreateOptions,\n): Promise<SessionCreateWithClientResult> {\n const client = new AcpClient({\n agentCommand: options.agentCommand,\n cwd: absolutePath(options.cwd),\n mcpServers: options.mcpServers,\n permissionMode: options.permissionMode,\n nonInteractivePermissions: options.nonInteractivePermissions,\n authCredentials: options.authCredentials,\n authPolicy: options.authPolicy,\n verbose: options.verbose,\n sessionOptions: options.sessionOptions,\n });\n\n try {\n const record = await withInterrupt(\n async () => await createSessionRecordWithClient(client, options),\n async () => {\n await client.close();\n },\n );\n\n return {\n record,\n client,\n };\n } catch (error) {\n await client.close();\n throw error;\n }\n}\n\nexport async function createSession(options: SessionCreateOptions): Promise<SessionRecord> {\n const { record, client } = await createSessionWithClient(options);\n try {\n return record;\n } finally {\n await client.close();\n }\n}\n\nexport async function ensureSession(options: SessionEnsureOptions): Promise<SessionEnsureResult> {\n const cwd = absolutePath(options.cwd);\n const gitRoot = findGitRepositoryRoot(cwd);\n const walkBoundary = options.walkBoundary ?? gitRoot ?? cwd;\n const existing = await findSessionByDirectoryWalk({\n agentCommand: options.agentCommand,\n cwd,\n name: options.name,\n boundary: walkBoundary,\n });\n if (existing) {\n const requestedModel = options.sessionOptions?.model;\n if (requestedModel) {\n const result = await setSessionModel({\n sessionId: existing.acpxRecordId,\n modelId: requestedModel,\n mcpServers: options.mcpServers,\n nonInteractivePermissions: options.nonInteractivePermissions,\n authCredentials: options.authCredentials,\n authPolicy: options.authPolicy,\n timeoutMs: options.timeoutMs,\n verbose: options.verbose,\n });\n return { record: result.record, created: false };\n }\n return {\n record: existing,\n created: false,\n };\n }\n\n const record = await createSession({\n agentCommand: options.agentCommand,\n cwd,\n name: options.name,\n resumeSessionId: options.resumeSessionId,\n mcpServers: options.mcpServers,\n permissionMode: options.permissionMode,\n nonInteractivePermissions: options.nonInteractivePermissions,\n authCredentials: options.authCredentials,\n authPolicy: options.authPolicy,\n timeoutMs: options.timeoutMs,\n verbose: options.verbose,\n sessionOptions: options.sessionOptions,\n });\n\n return {\n record,\n created: true,\n };\n}\n\nexport { DEFAULT_QUEUE_OWNER_TTL_MS };\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { getPerfMetricsSnapshot, resetPerfMetrics } from \"./perf-metrics.js\";\n\nconst PERF_METRICS_FILE_ENV = \"ACPX_PERF_METRICS_FILE\";\n\nlet installed = false;\nlet flushed = false;\nlet captureFilePath: string | undefined;\nlet captureRole = \"cli\";\nlet captureArgv: string[] = [];\nlet captureSequence = 0;\n\ntype CaptureReason = \"checkpoint\" | \"exit\" | \"signal\";\n\nfunction shouldCapture(): boolean {\n return typeof captureFilePath === \"string\" && captureFilePath.trim().length > 0;\n}\n\nfunction buildPayload(reason: CaptureReason): Record<string, unknown> {\n return {\n timestamp: new Date().toISOString(),\n pid: process.pid,\n ppid: process.ppid,\n role: captureRole,\n argv: captureArgv,\n cwd: process.cwd(),\n sequence: captureSequence,\n reason,\n metrics: getPerfMetricsSnapshot(),\n };\n}\n\nfunction writePerfMetricsCapture(reason: CaptureReason, resetAfterWrite: boolean): boolean {\n if (!shouldCapture()) {\n return false;\n }\n\n const payload = buildPayload(reason);\n const metrics = payload.metrics as {\n counters?: Record<string, number>;\n gauges?: Record<string, number>;\n timings?: Record<string, unknown>;\n };\n const hasData =\n Object.keys(metrics.counters ?? {}).length > 0 ||\n Object.keys(metrics.gauges ?? {}).length > 0 ||\n Object.keys(metrics.timings ?? {}).length > 0;\n if (!hasData) {\n return false;\n }\n\n try {\n fs.mkdirSync(path.dirname(captureFilePath!), { recursive: true });\n fs.appendFileSync(captureFilePath!, `${JSON.stringify(payload)}\\n`, \"utf8\");\n captureSequence += 1;\n if (resetAfterWrite) {\n resetPerfMetrics();\n }\n return true;\n } catch {\n // metrics capture is best-effort only\n return false;\n }\n}\n\nexport function checkpointPerfMetricsCapture(): void {\n flushed = false;\n writePerfMetricsCapture(\"checkpoint\", true);\n}\n\nexport function flushPerfMetricsCapture(reason: CaptureReason = \"exit\"): void {\n if (flushed || !shouldCapture()) {\n return;\n }\n flushed = true;\n writePerfMetricsCapture(reason, false);\n}\n\nexport function installPerfMetricsCapture(\n options: {\n argv?: string[];\n role?: string;\n filePath?: string;\n } = {},\n): void {\n captureFilePath = options.filePath ?? process.env[PERF_METRICS_FILE_ENV];\n if (!shouldCapture()) {\n return;\n }\n\n resetPerfMetrics();\n captureRole = options.role ?? captureRole;\n captureArgv = options.argv ?? [];\n captureSequence = 0;\n flushed = false;\n\n if (installed) {\n return;\n }\n installed = true;\n\n process.once(\"exit\", () => {\n flushPerfMetricsCapture(\"exit\");\n });\n for (const signal of [\"SIGINT\", \"SIGTERM\"] as const) {\n const handler = () => {\n flushPerfMetricsCapture(\"signal\");\n process.removeListener(signal, handler);\n process.kill(process.pid, signal);\n };\n process.once(signal, handler);\n }\n}\n\nexport function perfMetricsCaptureFileFromEnv(\n env: NodeJS.ProcessEnv = process.env,\n): string | undefined {\n const value = env[PERF_METRICS_FILE_ENV];\n if (typeof value !== \"string\" || value.trim().length === 0) {\n return undefined;\n }\n return value;\n}\n","import type { SetSessionConfigOptionResponse } from \"@agentclientprotocol/sdk\";\nimport { QueueConnectionError } from \"../../errors.js\";\n\nexport type QueueOwnerTurnState = \"idle\" | \"starting\" | \"active\" | \"closing\";\n\nexport type QueueOwnerActiveSessionController = {\n hasActivePrompt: () => boolean;\n requestCancelActivePrompt: () => Promise<boolean>;\n setSessionMode: (modeId: string) => Promise<void>;\n setSessionModel: (modelId: string) => Promise<void>;\n setSessionConfigOption: (\n configId: string,\n value: string,\n ) => Promise<SetSessionConfigOptionResponse>;\n};\n\ntype QueueOwnerTurnControllerOptions = {\n withTimeout: <T>(run: () => Promise<T>, timeoutMs?: number) => Promise<T>;\n setSessionModeFallback: (modeId: string, timeoutMs?: number) => Promise<void>;\n setSessionModelFallback: (modelId: string, timeoutMs?: number) => Promise<void>;\n setSessionConfigOptionFallback: (\n configId: string,\n value: string,\n timeoutMs?: number,\n ) => Promise<SetSessionConfigOptionResponse>;\n};\n\nexport class QueueOwnerTurnController {\n private readonly options: QueueOwnerTurnControllerOptions;\n private state: QueueOwnerTurnState = \"idle\";\n private pendingCancel = false;\n private activeController?: QueueOwnerActiveSessionController;\n\n constructor(options: QueueOwnerTurnControllerOptions) {\n this.options = options;\n }\n\n get lifecycleState(): QueueOwnerTurnState {\n return this.state;\n }\n\n get hasPendingCancel(): boolean {\n return this.pendingCancel;\n }\n\n beginTurn(): void {\n this.state = \"starting\";\n this.pendingCancel = false;\n }\n\n markPromptActive(): void {\n if (this.state === \"starting\" || this.state === \"active\") {\n this.state = \"active\";\n }\n }\n\n endTurn(): void {\n this.state = \"idle\";\n this.pendingCancel = false;\n }\n\n beginClosing(): void {\n this.state = \"closing\";\n this.pendingCancel = false;\n this.activeController = undefined;\n }\n\n setActiveController(controller: QueueOwnerActiveSessionController): void {\n this.activeController = controller;\n }\n\n clearActiveController(): void {\n this.activeController = undefined;\n }\n\n private assertCanHandleControlRequest(): void {\n if (this.state === \"closing\") {\n throw new QueueConnectionError(\"Queue owner is closing\", {\n detailCode: \"QUEUE_OWNER_SHUTTING_DOWN\",\n origin: \"queue\",\n retryable: true,\n });\n }\n }\n\n async requestCancel(): Promise<boolean> {\n const activeController = this.activeController;\n if (activeController?.hasActivePrompt()) {\n const cancelled = await activeController.requestCancelActivePrompt();\n if (cancelled) {\n this.pendingCancel = false;\n }\n return cancelled;\n }\n\n if (this.state === \"starting\" || this.state === \"active\") {\n this.pendingCancel = true;\n return true;\n }\n\n return false;\n }\n\n async applyPendingCancel(): Promise<boolean> {\n const activeController = this.activeController;\n if (!this.pendingCancel || !activeController || !activeController.hasActivePrompt()) {\n return false;\n }\n\n const cancelled = await activeController.requestCancelActivePrompt();\n if (cancelled) {\n this.pendingCancel = false;\n }\n return cancelled;\n }\n\n async setSessionMode(modeId: string, timeoutMs?: number): Promise<void> {\n this.assertCanHandleControlRequest();\n const activeController = this.activeController;\n if (activeController) {\n await this.options.withTimeout(\n async () => await activeController.setSessionMode(modeId),\n timeoutMs,\n );\n return;\n }\n\n await this.options.setSessionModeFallback(modeId, timeoutMs);\n }\n\n async setSessionModel(modelId: string, timeoutMs?: number): Promise<void> {\n this.assertCanHandleControlRequest();\n const activeController = this.activeController;\n if (activeController) {\n await this.options.withTimeout(\n async () => await activeController.setSessionModel(modelId),\n timeoutMs,\n );\n return;\n }\n\n await this.options.setSessionModelFallback(modelId, timeoutMs);\n }\n\n async setSessionConfigOption(\n configId: string,\n value: string,\n timeoutMs?: number,\n ): Promise<SetSessionConfigOptionResponse> {\n this.assertCanHandleControlRequest();\n const activeController = this.activeController;\n if (activeController) {\n return await this.options.withTimeout(\n async () => await activeController.setSessionConfigOption(configId, value),\n timeoutMs,\n );\n }\n\n return await this.options.setSessionConfigOptionFallback(configId, value, timeoutMs);\n }\n}\n","import { spawn } from \"node:child_process\";\nimport { realpathSync } from \"node:fs\";\nimport type {\n AuthPolicy,\n McpServer,\n NonInteractivePermissionPolicy,\n PermissionMode,\n} from \"../../types.js\";\n\nexport type QueueOwnerRuntimeOptions = {\n sessionId: string;\n mcpServers?: McpServer[];\n permissionMode: PermissionMode;\n nonInteractivePermissions?: NonInteractivePermissionPolicy;\n authCredentials?: Record<string, string>;\n authPolicy?: AuthPolicy;\n suppressSdkConsoleErrors?: boolean;\n verbose?: boolean;\n ttlMs?: number;\n maxQueueDepth?: number;\n promptRetries?: number;\n};\n\ntype SessionSendLike = {\n sessionId: string;\n mcpServers?: McpServer[];\n permissionMode: PermissionMode;\n nonInteractivePermissions?: NonInteractivePermissionPolicy;\n authCredentials?: Record<string, string>;\n authPolicy?: AuthPolicy;\n suppressSdkConsoleErrors?: boolean;\n verbose?: boolean;\n ttlMs?: number;\n maxQueueDepth?: number;\n promptRetries?: number;\n};\n\nexport function sanitizeQueueOwnerExecArgv(\n execArgv: readonly string[] = process.execArgv,\n): string[] {\n const sanitized: string[] = [];\n for (let index = 0; index < execArgv.length; index += 1) {\n const value = execArgv[index];\n if (value === \"--experimental-test-coverage\" || value === \"--test\") {\n continue;\n }\n if (\n value === \"--test-name-pattern\" ||\n value === \"--test-reporter\" ||\n value === \"--test-reporter-destination\"\n ) {\n index += 1;\n continue;\n }\n if (value.startsWith(\"--test-\")) {\n continue;\n }\n if (\n value === \"--inspect\" ||\n value === \"--inspect-brk\" ||\n value === \"--inspect-port\" ||\n value === \"--inspect-publish-uid\" ||\n value.startsWith(\"--inspect=\") ||\n value.startsWith(\"--inspect-brk=\") ||\n value.startsWith(\"--inspect-port=\") ||\n value.startsWith(\"--inspect-publish-uid=\") ||\n value === \"--debug-port\" ||\n value.startsWith(\"--debug-port=\")\n ) {\n if (\n value === \"--inspect\" ||\n value === \"--inspect-brk\" ||\n value === \"--inspect-port\" ||\n value === \"--inspect-publish-uid\" ||\n value === \"--debug-port\"\n ) {\n index += 1;\n }\n continue;\n }\n sanitized.push(value);\n }\n return sanitized;\n}\n\nexport function buildQueueOwnerArgOverride(\n entryPath: string,\n execArgv: readonly string[] = process.execArgv,\n): string | null {\n const sanitized = sanitizeQueueOwnerExecArgv(execArgv);\n if (sanitized.length === 0) {\n return null;\n }\n return JSON.stringify([...sanitized, entryPath, \"__queue-owner\"]);\n}\n\nexport function resolveQueueOwnerSpawnArgs(argv: readonly string[] = process.argv): string[] {\n const override = process.env.ACPX_QUEUE_OWNER_ARGS;\n if (override) {\n const parsed = JSON.parse(override) as unknown;\n if (\n Array.isArray(parsed) &&\n parsed.length > 0 &&\n parsed.every((value) => typeof value === \"string\" && value.length > 0)\n ) {\n return [...parsed];\n }\n throw new Error(\"acpx self-spawn failed: invalid ACPX_QUEUE_OWNER_ARGS\");\n }\n\n const entry = argv[1];\n if (!entry || entry.trim().length === 0) {\n throw new Error(\"acpx self-spawn failed: missing CLI entry path\");\n }\n const resolvedEntry = realpathSync(entry);\n return [resolvedEntry, \"__queue-owner\"];\n}\n\nexport function queueOwnerRuntimeOptionsFromSend(\n options: SessionSendLike,\n): QueueOwnerRuntimeOptions {\n return {\n sessionId: options.sessionId,\n mcpServers: options.mcpServers,\n permissionMode: options.permissionMode,\n nonInteractivePermissions: options.nonInteractivePermissions,\n authCredentials: options.authCredentials,\n authPolicy: options.authPolicy,\n suppressSdkConsoleErrors: options.suppressSdkConsoleErrors,\n verbose: options.verbose,\n ttlMs: options.ttlMs,\n maxQueueDepth: options.maxQueueDepth,\n promptRetries: options.promptRetries,\n };\n}\n\nexport function buildQueueOwnerSpawnOptions(payload: string): {\n detached: true;\n stdio: \"ignore\";\n env: NodeJS.ProcessEnv;\n windowsHide: true;\n} {\n return {\n detached: true,\n stdio: \"ignore\",\n env: {\n ...process.env,\n ACPX_QUEUE_OWNER_PAYLOAD: payload,\n },\n windowsHide: true,\n };\n}\n\nexport function spawnQueueOwnerProcess(options: QueueOwnerRuntimeOptions): void {\n const payload = JSON.stringify(options);\n const child = spawn(\n process.execPath,\n resolveQueueOwnerSpawnArgs(),\n buildQueueOwnerSpawnOptions(payload),\n );\n child.unref();\n}\n","import fs from \"node:fs/promises\";\nimport { isAcpJsonRpcMessage } from \"../acp/jsonrpc.js\";\nimport { isProcessAlive } from \"../cli/queue/lease-store.js\";\nimport { incrementPerfCounter, measurePerf } from \"../perf-metrics.js\";\nimport type { AcpJsonRpcMessage, SessionRecord } from \"../types.js\";\nimport {\n DEFAULT_EVENT_MAX_SEGMENTS,\n DEFAULT_EVENT_SEGMENT_MAX_BYTES,\n sessionBaseDir,\n sessionEventActivePath as activeEventPath,\n sessionEventLockPath as eventsLockPath,\n sessionEventSegmentPath as segmentEventPath,\n} from \"./event-log.js\";\nimport { resolveSessionRecord, writeSessionRecord } from \"./persistence.js\";\n\nconst LOCK_RETRY_MS = 15;\nconst EVENT_LOCK_STALE_MS = 15_000;\n\nasync function ensureSessionDir(): Promise<void> {\n await fs.mkdir(sessionBaseDir(), { recursive: true });\n}\n\nasync function pathExists(filePath: string): Promise<boolean> {\n try {\n await fs.access(filePath);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function statSize(filePath: string): Promise<number> {\n try {\n const stats = await fs.stat(filePath);\n return stats.size;\n } catch {\n return 0;\n }\n}\n\nasync function countExistingSegments(sessionId: string, maxSegments: number): Promise<number> {\n let count = 0;\n\n for (let segment = 1; segment <= maxSegments; segment += 1) {\n if (await pathExists(segmentEventPath(sessionId, segment))) {\n count += 1;\n }\n }\n\n if (await pathExists(activeEventPath(sessionId))) {\n count += 1;\n }\n\n return count;\n}\n\nasync function resolveSessionMaxSegments(sessionId: string): Promise<number> {\n try {\n const record = await resolveSessionRecord(sessionId);\n const configured = record.eventLog.max_segments;\n if (Number.isInteger(configured) && configured > 0) {\n return configured;\n }\n } catch {\n // Fall back to defaults when metadata is unavailable.\n }\n\n return DEFAULT_EVENT_MAX_SEGMENTS;\n}\n\nasync function rotateSegments(sessionId: string, maxSegments: number): Promise<void> {\n const active = activeEventPath(sessionId);\n\n const overflow = segmentEventPath(sessionId, maxSegments);\n await fs.unlink(overflow).catch((error) => {\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") {\n throw error;\n }\n });\n\n for (let segment = maxSegments - 1; segment >= 1; segment -= 1) {\n const from = segmentEventPath(sessionId, segment);\n const to = segmentEventPath(sessionId, segment + 1);\n if (!(await pathExists(from))) {\n continue;\n }\n await fs.rename(from, to);\n }\n\n if (await pathExists(active)) {\n await fs.rename(active, segmentEventPath(sessionId, 1));\n }\n}\n\ntype LockHandle = {\n filePath: string;\n};\n\ntype EventLockPayload = {\n pid?: number;\n created_at?: string;\n};\n\nfunction parseEventLockPayload(raw: string): EventLockPayload {\n try {\n const parsed = JSON.parse(raw) as unknown;\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n return {};\n }\n const record = parsed as Record<string, unknown>;\n return {\n pid: typeof record.pid === \"number\" ? record.pid : undefined,\n created_at: typeof record.created_at === \"string\" ? record.created_at : undefined,\n };\n } catch {\n return {};\n }\n}\n\nasync function removeStaleEventLock(lockPath: string): Promise<boolean> {\n try {\n const payload = await fs.readFile(lockPath, \"utf8\");\n const parsed = parseEventLockPayload(payload);\n const createdAtMs = parsed.created_at ? Date.parse(parsed.created_at) : Number.NaN;\n const lockAgeMs = Number.isFinite(createdAtMs)\n ? Date.now() - createdAtMs\n : Number.POSITIVE_INFINITY;\n const pidAlive = isProcessAlive(parsed.pid);\n if (pidAlive && lockAgeMs <= EVENT_LOCK_STALE_MS) {\n return false;\n }\n await fs.unlink(lockPath);\n incrementPerfCounter(\"session.events.stale_lock_recovered\");\n return true;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") {\n return true;\n }\n return false;\n }\n}\n\nasync function acquireEventsLock(sessionId: string): Promise<LockHandle> {\n await ensureSessionDir();\n const lockPath = eventsLockPath(sessionId);\n const payload = JSON.stringify(\n {\n pid: process.pid,\n created_at: new Date().toISOString(),\n },\n null,\n 2,\n );\n\n for (;;) {\n try {\n await fs.writeFile(lockPath, `${payload}\\n`, {\n encoding: \"utf8\",\n flag: \"wx\",\n });\n return { filePath: lockPath };\n } catch (error) {\n const code = (error as NodeJS.ErrnoException).code;\n if (code !== \"EEXIST\") {\n throw error;\n }\n const recovered = await removeStaleEventLock(lockPath);\n if (recovered) {\n continue;\n }\n await new Promise<void>((resolve) => {\n setTimeout(resolve, LOCK_RETRY_MS);\n });\n }\n }\n}\n\nasync function releaseEventsLock(lock: LockHandle): Promise<void> {\n await fs.unlink(lock.filePath).catch((error) => {\n if ((error as NodeJS.ErrnoException).code !== \"ENOENT\") {\n throw error;\n }\n });\n}\n\ntype SessionEventWriterOptions = {\n maxSegmentBytes?: number;\n maxSegments?: number;\n};\n\ntype AppendOptions = {\n checkpoint?: boolean;\n};\n\nexport class SessionEventWriter {\n private readonly record: SessionRecord;\n private readonly lock: LockHandle;\n private readonly maxSegmentBytes: number;\n private readonly maxSegments: number;\n private activePath: string;\n private activeSizeBytes: number;\n private segmentCount: number;\n private closed = false;\n\n private constructor(\n record: SessionRecord,\n lock: LockHandle,\n options: Required<SessionEventWriterOptions>,\n state: {\n activePath: string;\n activeSizeBytes: number;\n segmentCount: number;\n },\n ) {\n this.record = record;\n this.lock = lock;\n this.maxSegmentBytes = options.maxSegmentBytes;\n this.maxSegments = options.maxSegments;\n this.activePath = state.activePath;\n this.activeSizeBytes = state.activeSizeBytes;\n this.segmentCount = state.segmentCount;\n }\n\n static async open(\n record: SessionRecord,\n options: SessionEventWriterOptions = {},\n ): Promise<SessionEventWriter> {\n const lock = await acquireEventsLock(record.acpxRecordId);\n const maxSegmentBytes =\n options.maxSegmentBytes ??\n record.eventLog.max_segment_bytes ??\n DEFAULT_EVENT_SEGMENT_MAX_BYTES;\n const maxSegments =\n options.maxSegments ?? record.eventLog.max_segments ?? DEFAULT_EVENT_MAX_SEGMENTS;\n const activePath = activeEventPath(record.acpxRecordId);\n const activeSizeBytes = await statSize(activePath);\n const segmentCount =\n Number.isInteger(record.eventLog.segment_count) && record.eventLog.segment_count > 0\n ? record.eventLog.segment_count\n : (await countExistingSegments(record.acpxRecordId, maxSegments)) || 1;\n return new SessionEventWriter(\n record,\n lock,\n {\n maxSegmentBytes,\n maxSegments,\n },\n {\n activePath,\n activeSizeBytes,\n segmentCount,\n },\n );\n }\n\n getRecord(): SessionRecord {\n return this.record;\n }\n\n async appendMessage(message: AcpJsonRpcMessage, options: AppendOptions = {}): Promise<void> {\n await this.appendMessages([message], options);\n }\n\n async appendMessages(messages: AcpJsonRpcMessage[], options: AppendOptions = {}): Promise<void> {\n if (this.closed) {\n throw new Error(\"SessionEventWriter is closed\");\n }\n\n if (messages.length === 0) {\n return;\n }\n\n await ensureSessionDir();\n\n await measurePerf(\"session.events.append_batch\", async () => {\n for (const message of messages) {\n if (!isAcpJsonRpcMessage(message)) {\n throw new Error(\"Attempted to persist invalid ACP JSON-RPC payload\");\n }\n\n const line = `${JSON.stringify(message)}\\n`;\n const lineBytes = Buffer.byteLength(line);\n if (this.activeSizeBytes > 0 && this.activeSizeBytes + lineBytes > this.maxSegmentBytes) {\n await rotateSegments(this.record.acpxRecordId, this.maxSegments);\n this.activePath = activeEventPath(this.record.acpxRecordId);\n this.activeSizeBytes = 0;\n this.segmentCount = Math.min(this.segmentCount + 1, this.maxSegments);\n incrementPerfCounter(\"session.events.rotate\");\n }\n\n await fs.appendFile(this.activePath, line, \"utf8\");\n this.activeSizeBytes += lineBytes;\n\n this.record.lastSeq += 1;\n if (Object.hasOwn(message, \"id\")) {\n const id = (message as { id?: unknown }).id;\n if (typeof id === \"string\" || typeof id === \"number\") {\n this.record.lastRequestId = String(id);\n }\n }\n const writeTs = new Date().toISOString();\n this.record.lastUsedAt = writeTs;\n this.record.eventLog = {\n active_path: this.activePath,\n segment_count: this.segmentCount,\n max_segment_bytes: this.maxSegmentBytes,\n max_segments: this.maxSegments,\n last_write_at: writeTs,\n last_write_error: null,\n };\n }\n });\n\n if (options.checkpoint === true) {\n await writeSessionRecord(this.record);\n }\n }\n\n async checkpoint(): Promise<void> {\n if (this.closed) {\n throw new Error(\"SessionEventWriter is closed\");\n }\n await writeSessionRecord(this.record);\n }\n\n async close(options: AppendOptions = {}): Promise<void> {\n if (this.closed) {\n return;\n }\n\n try {\n if (options.checkpoint !== false) {\n await writeSessionRecord(this.record);\n }\n } finally {\n this.closed = true;\n await releaseEventsLock(this.lock);\n }\n }\n}\n\nexport async function listSessionEvents(sessionId: string): Promise<AcpJsonRpcMessage[]> {\n const maxSegments = await resolveSessionMaxSegments(sessionId);\n const files: string[] = [];\n\n for (let segment = maxSegments; segment >= 1; segment -= 1) {\n const filePath = segmentEventPath(sessionId, segment);\n if (await pathExists(filePath)) {\n files.push(filePath);\n }\n }\n\n const active = activeEventPath(sessionId);\n if (await pathExists(active)) {\n files.push(active);\n }\n\n const events: AcpJsonRpcMessage[] = [];\n for (const filePath of files) {\n const payload = await fs.readFile(filePath, \"utf8\");\n const lines = payload.split(\"\\n\").filter((line) => line.trim().length > 0);\n for (const line of lines) {\n try {\n const parsed = JSON.parse(line);\n if (isAcpJsonRpcMessage(parsed)) {\n events.push(parsed);\n }\n } catch {\n // Skip malformed lines to keep event listing resilient.\n }\n }\n }\n\n return events;\n}\n","import { AcpClient } from \"../../acp/client.js\";\nimport {\n formatErrorMessage,\n isRetryablePromptError,\n normalizeOutputError,\n} from \"../../acp/error-normalization.js\";\nimport { InterruptedError, withInterrupt, withTimeout } from \"../../async-control.js\";\nexport { InterruptedError, TimeoutError } from \"../../async-control.js\";\nimport { formatPerfMetric, measurePerf, startPerfTimer } from \"../../perf-metrics.js\";\nimport { textPrompt } from \"../../prompt-content.js\";\nimport {\n applyConversation,\n applyLifecycleSnapshotToRecord,\n} from \"../../runtime/engine/lifecycle.js\";\nimport { runPromptTurn } from \"../../runtime/engine/prompt-turn.js\";\nimport { connectAndLoadSession } from \"../../runtime/engine/reconnect.js\";\nimport { sessionOptionsFromRecord } from \"../../runtime/engine/session-options.js\";\nimport {\n cloneSessionAcpxState,\n cloneSessionConversation,\n recordClientOperation as recordConversationClientOperation,\n recordPromptSubmission,\n recordSessionUpdate as recordConversationSessionUpdate,\n trimConversationForRuntime,\n} from \"../../session/conversation-model.js\";\nimport { SessionEventWriter } from \"../../session/events.js\";\nimport { absolutePath, isoNow, resolveSessionRecord } from \"../../session/persistence.js\";\nimport type {\n AcpJsonRpcMessage,\n AcpMessageDirection,\n AuthPolicy,\n ClientOperation,\n McpServer,\n NonInteractivePermissionPolicy,\n OutputErrorAcpPayload,\n OutputErrorCode,\n OutputErrorOrigin,\n OutputFormatter,\n PermissionMode,\n PromptInput,\n RunPromptResult,\n SessionNotification,\n SessionResumePolicy,\n SessionSendResult,\n} from \"../../types.js\";\nimport { type QueueOwnerMessage, type QueueTask, waitMs } from \"../queue/ipc.js\";\nimport { type QueueOwnerActiveSessionController } from \"../queue/owner-turn-controller.js\";\nimport type { RunOnceOptions, SessionSendOptions } from \"./contracts.js\";\n\nconst INTERRUPT_CANCEL_WAIT_MS = 2_500;\n\ntype RunSessionPromptOptions = {\n sessionRecordId: string;\n prompt: PromptInput;\n resumePolicy?: SessionResumePolicy;\n mcpServers?: McpServer[];\n permissionMode: PermissionMode;\n nonInteractivePermissions?: NonInteractivePermissionPolicy;\n authCredentials?: Record<string, string>;\n authPolicy?: AuthPolicy;\n outputFormatter: OutputFormatter;\n onAcpMessage?: (direction: AcpMessageDirection, message: AcpJsonRpcMessage) => void;\n onSessionUpdate?: (notification: SessionNotification) => void;\n onClientOperation?: (operation: ClientOperation) => void;\n timeoutMs?: number;\n suppressSdkConsoleErrors?: boolean;\n verbose?: boolean;\n promptRetries?: number;\n onClientAvailable?: (controller: ActiveSessionController) => void;\n onClientClosed?: () => void;\n onPromptActive?: () => Promise<void> | void;\n client?: AcpClient;\n};\n\ntype ActiveSessionController = QueueOwnerActiveSessionController;\n\nclass QueueTaskOutputFormatter implements OutputFormatter {\n private readonly requestId: string;\n private readonly send: (message: QueueOwnerMessage) => void;\n\n constructor(task: QueueTask) {\n this.requestId = task.requestId;\n this.send = task.send;\n }\n\n setContext(_context: { sessionId: string }): void {}\n\n onAcpMessage(message: AcpJsonRpcMessage): void {\n this.send({\n type: \"event\",\n requestId: this.requestId,\n message,\n });\n }\n\n onError(params: {\n code: OutputErrorCode;\n detailCode?: string;\n origin?: OutputErrorOrigin;\n message: string;\n retryable?: boolean;\n acp?: OutputErrorAcpPayload;\n timestamp?: string;\n }): void {\n this.send({\n type: \"error\",\n requestId: this.requestId,\n code: params.code,\n detailCode: params.detailCode,\n origin: params.origin,\n message: params.message,\n retryable: params.retryable,\n acp: params.acp,\n });\n }\n\n flush(): void {}\n}\n\nconst DISCARD_OUTPUT_FORMATTER: OutputFormatter = {\n setContext() {},\n onAcpMessage() {},\n onError() {},\n flush() {},\n};\n\nfunction toPromptResult(\n stopReason: RunPromptResult[\"stopReason\"],\n sessionId: string,\n client: AcpClient,\n): RunPromptResult {\n return {\n stopReason,\n sessionId,\n permissionStats: client.getPermissionStats(),\n };\n}\n\nasync function applyRequestedModelIfAdvertised(params: {\n client: AcpClient;\n sessionId: string;\n requestedModel: string | undefined;\n models: import(\"../../acp/client.js\").SessionCreateResult[\"models\"];\n timeoutMs?: number;\n}): Promise<boolean> {\n const requestedModel =\n typeof params.requestedModel === \"string\" ? params.requestedModel.trim() : \"\";\n if (!requestedModel || !params.models) {\n return false;\n }\n if (params.models.currentModelId === requestedModel) {\n return true;\n }\n\n await withTimeout(\n params.client.setSessionModel(params.sessionId, requestedModel),\n params.timeoutMs,\n );\n return true;\n}\n\nfunction jsonRpcIdKey(value: unknown): string | undefined {\n if (typeof value === \"string\") {\n return `s:${value}`;\n }\n if (typeof value === \"number\" && Number.isFinite(value)) {\n return `n:${value}`;\n }\n return undefined;\n}\n\nfunction extractJsonRpcRequestInfo(\n message: AcpJsonRpcMessage,\n): { idKey: string; method: string } | undefined {\n const candidate = message as { method?: unknown; id?: unknown };\n if (typeof candidate.method !== \"string\") {\n return undefined;\n }\n const idKey = jsonRpcIdKey(candidate.id);\n if (!idKey) {\n return undefined;\n }\n return {\n idKey,\n method: candidate.method,\n };\n}\n\nfunction extractJsonRpcResponseInfo(\n message: AcpJsonRpcMessage,\n): { idKey: string; hasError: boolean } | undefined {\n const candidate = message as { id?: unknown; error?: unknown; result?: unknown };\n const idKey = jsonRpcIdKey(candidate.id);\n if (!idKey) {\n return undefined;\n }\n const hasError = Object.hasOwn(candidate, \"error\");\n const hasResult = Object.hasOwn(candidate, \"result\");\n if (!hasError && !hasResult) {\n return undefined;\n }\n return {\n idKey,\n hasError,\n };\n}\n\nfunction filterRecoverableLoadFallbackOutput(messages: AcpJsonRpcMessage[]): AcpJsonRpcMessage[] {\n const requestMethodById = new Map<string, string>();\n const failedLoadRequestIds = new Set<string>();\n\n for (const message of messages) {\n const request = extractJsonRpcRequestInfo(message);\n if (request) {\n requestMethodById.set(request.idKey, request.method);\n continue;\n }\n\n const response = extractJsonRpcResponseInfo(message);\n if (!response || !response.hasError) {\n continue;\n }\n\n if (requestMethodById.get(response.idKey) === \"session/load\") {\n failedLoadRequestIds.add(response.idKey);\n }\n }\n\n if (failedLoadRequestIds.size === 0) {\n return messages;\n }\n\n return messages.filter((message) => {\n const request = extractJsonRpcRequestInfo(message);\n if (request && request.method === \"session/load\" && failedLoadRequestIds.has(request.idKey)) {\n return false;\n }\n\n const response = extractJsonRpcResponseInfo(message);\n if (response && failedLoadRequestIds.has(response.idKey)) {\n return false;\n }\n\n return true;\n });\n}\n\nfunction emitPromptRetryNotice(params: {\n error: unknown;\n delayMs: number;\n attempt: number;\n maxRetries: number;\n suppressSdkConsoleErrors?: boolean;\n}): void {\n if (params.suppressSdkConsoleErrors) {\n return;\n }\n\n process.stderr.write(\n `[acpx] prompt failed (${formatErrorMessage(params.error)}), retrying in ${params.delayMs}ms ` +\n `(attempt ${params.attempt}/${params.maxRetries})\\n`,\n );\n}\n\nexport async function runQueuedTask(\n sessionRecordId: string,\n task: QueueTask,\n options: {\n sharedClient?: AcpClient;\n verbose?: boolean;\n mcpServers?: McpServer[];\n nonInteractivePermissions?: NonInteractivePermissionPolicy;\n authCredentials?: Record<string, string>;\n authPolicy?: AuthPolicy;\n suppressSdkConsoleErrors?: boolean;\n promptRetries?: number;\n onClientAvailable?: (controller: ActiveSessionController) => void;\n onClientClosed?: () => void;\n onPromptActive?: () => Promise<void> | void;\n },\n): Promise<void> {\n const outputFormatter = task.waitForCompletion\n ? new QueueTaskOutputFormatter(task)\n : DISCARD_OUTPUT_FORMATTER;\n\n try {\n const result = await runSessionPrompt({\n sessionRecordId,\n mcpServers: options.mcpServers,\n prompt: task.prompt ?? textPrompt(task.message),\n permissionMode: task.permissionMode,\n resumePolicy: task.resumePolicy,\n nonInteractivePermissions:\n task.nonInteractivePermissions ?? options.nonInteractivePermissions,\n authCredentials: options.authCredentials,\n authPolicy: options.authPolicy,\n outputFormatter,\n timeoutMs: task.timeoutMs,\n suppressSdkConsoleErrors: task.suppressSdkConsoleErrors ?? options.suppressSdkConsoleErrors,\n verbose: options.verbose,\n promptRetries: options.promptRetries,\n onClientAvailable: options.onClientAvailable,\n onClientClosed: options.onClientClosed,\n onPromptActive: options.onPromptActive,\n client: options.sharedClient,\n });\n\n if (task.waitForCompletion) {\n task.send({\n type: \"result\",\n requestId: task.requestId,\n result,\n });\n }\n } catch (error) {\n const normalizedError = normalizeOutputError(error, {\n origin: \"runtime\",\n detailCode: \"QUEUE_RUNTIME_PROMPT_FAILED\",\n });\n const alreadyEmitted =\n (error as { outputAlreadyEmitted?: unknown }).outputAlreadyEmitted === true;\n if (task.waitForCompletion) {\n task.send({\n type: \"error\",\n requestId: task.requestId,\n code: normalizedError.code,\n detailCode: normalizedError.detailCode,\n origin: normalizedError.origin,\n message: normalizedError.message,\n retryable: normalizedError.retryable,\n acp: normalizedError.acp,\n outputAlreadyEmitted: alreadyEmitted,\n });\n }\n\n if (error instanceof InterruptedError) {\n throw error;\n }\n } finally {\n task.close();\n }\n}\n\nasync function runSessionPrompt(options: RunSessionPromptOptions): Promise<SessionSendResult> {\n const stopTotalTimer = startPerfTimer(\"runtime.prompt.total\");\n const output = options.outputFormatter;\n const record = await measurePerf(\"session.resolve_prompt_record\", async () => {\n return await resolveSessionRecord(options.sessionRecordId);\n });\n const conversation = cloneSessionConversation(record);\n let acpxState = cloneSessionAcpxState(record.acpx);\n const promptMessageId = recordPromptSubmission(conversation, options.prompt, isoNow());\n\n output.setContext({\n sessionId: record.acpxRecordId,\n });\n\n const eventWriter = await measurePerf(\"session.events.open\", async () => {\n return await SessionEventWriter.open(record);\n });\n const pendingMessages: AcpJsonRpcMessage[] = [];\n const pendingConnectOutputMessages: AcpJsonRpcMessage[] = [];\n let bufferingConnectOutput = true;\n let promptTurnActive = false;\n let promptTurnHadSideEffects = false;\n let sawAcpMessage = false;\n let eventWriterClosed = false;\n\n const closeEventWriter = async (checkpoint: boolean): Promise<void> => {\n if (eventWriterClosed) {\n return;\n }\n eventWriterClosed = true;\n await eventWriter.close({ checkpoint });\n };\n\n const flushPendingMessages = async (checkpoint = false): Promise<void> => {\n if (pendingMessages.length === 0) {\n return;\n }\n\n const batch = pendingMessages.splice(0, pendingMessages.length);\n await measurePerf(\"session.events.flush_pending\", async () => {\n await eventWriter.appendMessages(batch, { checkpoint });\n });\n };\n\n const ownClient = options.client == null;\n const client =\n options.client ??\n new AcpClient({\n agentCommand: record.agentCommand,\n cwd: absolutePath(record.cwd),\n mcpServers: options.mcpServers,\n permissionMode: options.permissionMode,\n nonInteractivePermissions: options.nonInteractivePermissions,\n authCredentials: options.authCredentials,\n authPolicy: options.authPolicy,\n suppressSdkConsoleErrors: options.suppressSdkConsoleErrors,\n verbose: options.verbose,\n sessionOptions: sessionOptionsFromRecord(record),\n });\n client.updateRuntimeOptions({\n permissionMode: options.permissionMode,\n nonInteractivePermissions: options.nonInteractivePermissions,\n suppressSdkConsoleErrors: options.suppressSdkConsoleErrors,\n verbose: options.verbose,\n });\n client.setEventHandlers({\n onAcpMessage: (direction, message) => {\n sawAcpMessage = true;\n pendingMessages.push(message);\n options.onAcpMessage?.(direction, message);\n },\n onAcpOutputMessage: (_direction, message) => {\n if (bufferingConnectOutput) {\n pendingConnectOutputMessages.push(message);\n return;\n }\n output.onAcpMessage(message);\n },\n onSessionUpdate: (notification) => {\n if (promptTurnActive) {\n promptTurnHadSideEffects = true;\n }\n acpxState = recordConversationSessionUpdate(conversation, acpxState, notification);\n trimConversationForRuntime(conversation);\n options.onSessionUpdate?.(notification);\n },\n onClientOperation: (operation) => {\n if (promptTurnActive) {\n promptTurnHadSideEffects = true;\n }\n acpxState = recordConversationClientOperation(conversation, acpxState, operation);\n trimConversationForRuntime(conversation);\n options.onClientOperation?.(operation);\n },\n });\n let activeSessionIdForControl = record.acpSessionId;\n let notifiedClientAvailable = false;\n const activeController: ActiveSessionController = {\n hasActivePrompt: () => client.hasActivePrompt(),\n requestCancelActivePrompt: async () => await client.requestCancelActivePrompt(),\n setSessionMode: async (modeId: string) => {\n await client.setSessionMode(activeSessionIdForControl, modeId);\n },\n setSessionModel: async (modelId: string) => {\n await client.setSessionModel(activeSessionIdForControl, modelId);\n },\n setSessionConfigOption: async (configId: string, value: string) => {\n return await client.setSessionConfigOption(activeSessionIdForControl, configId, value);\n },\n };\n\n try {\n return await withInterrupt(\n async () => {\n const connectStartedAt = Date.now();\n const {\n sessionId: activeSessionId,\n resumed,\n loadError,\n } = await measurePerf(\"runtime.connect_and_load\", async () => {\n try {\n return await connectAndLoadSession({\n client,\n record,\n resumePolicy: options.resumePolicy,\n timeoutMs: options.timeoutMs,\n verbose: options.verbose,\n activeController,\n onClientAvailable: (controller) => {\n options.onClientAvailable?.(controller);\n notifiedClientAvailable = true;\n },\n onConnectedRecord: (connectedRecord) => {\n connectedRecord.lastPromptAt = isoNow();\n },\n onSessionIdResolved: (sessionId) => {\n activeSessionIdForControl = sessionId;\n },\n });\n } catch (error) {\n bufferingConnectOutput = false;\n for (const message of pendingConnectOutputMessages) {\n output.onAcpMessage(message);\n }\n pendingConnectOutputMessages.length = 0;\n throw error;\n }\n });\n bufferingConnectOutput = false;\n const connectOutputMessages =\n loadError == null\n ? pendingConnectOutputMessages\n : filterRecoverableLoadFallbackOutput(pendingConnectOutputMessages);\n for (const message of connectOutputMessages) {\n output.onAcpMessage(message);\n }\n pendingConnectOutputMessages.length = 0;\n if (options.verbose) {\n process.stderr.write(\n `[acpx] ${formatPerfMetric(\"prompt.connect_and_load\", Date.now() - connectStartedAt)}\\n`,\n );\n }\n\n output.setContext({\n sessionId: record.acpxRecordId,\n });\n await flushPendingMessages(false);\n\n const maxRetries = options.promptRetries ?? 0;\n let response;\n promptTurnActive = true;\n for (let attempt = 0; ; attempt++) {\n try {\n const promptStartedAt = Date.now();\n response = await measurePerf(\"runtime.prompt.agent_turn\", async () => {\n return await runPromptTurn({\n client,\n sessionId: activeSessionId,\n prompt: options.prompt,\n timeoutMs: options.timeoutMs,\n conversation,\n promptMessageId,\n onPromptStarted:\n attempt === 0 && options.onPromptActive\n ? async () => {\n try {\n await options.onPromptActive?.();\n } catch (error) {\n if (options.verbose) {\n process.stderr.write(\n \"[acpx] onPromptActive hook failed: \" +\n formatErrorMessage(error) +\n \"\\n\",\n );\n }\n }\n }\n : undefined,\n });\n });\n if (options.verbose) {\n process.stderr.write(\n `[acpx] ${formatPerfMetric(\"prompt.agent_turn\", Date.now() - promptStartedAt)}\\n`,\n );\n }\n break;\n } catch (error) {\n const snapshot = client.getAgentLifecycleSnapshot();\n const agentCrashed = snapshot.lastExit?.unexpectedDuringPrompt === true;\n\n if (\n attempt < maxRetries &&\n !agentCrashed &&\n !promptTurnHadSideEffects &&\n isRetryablePromptError(error)\n ) {\n const delayMs = Math.min(1_000 * 2 ** attempt, 10_000);\n emitPromptRetryNotice({\n error,\n delayMs,\n attempt: attempt + 1,\n maxRetries,\n suppressSdkConsoleErrors: options.suppressSdkConsoleErrors,\n });\n await waitMs(delayMs);\n if (!promptTurnHadSideEffects) {\n continue;\n }\n }\n\n promptTurnActive = false;\n applyLifecycleSnapshotToRecord(record, snapshot);\n const lastExit = snapshot.lastExit;\n if (lastExit?.unexpectedDuringPrompt && options.verbose) {\n process.stderr.write(\n \"[acpx] agent disconnected during prompt (\" +\n lastExit.reason +\n \", exit=\" +\n lastExit.exitCode +\n \", signal=\" +\n (lastExit.signal ?? \"none\") +\n \")\\n\",\n );\n }\n\n const normalizedError = normalizeOutputError(error, {\n origin: \"runtime\",\n });\n\n await flushPendingMessages(false).catch(() => {\n // best effort while bubbling prompt failure\n });\n\n output.flush();\n\n record.lastUsedAt = isoNow();\n applyConversation(record, conversation);\n record.acpx = acpxState;\n\n const propagated =\n error instanceof Error ? error : new Error(formatErrorMessage(error));\n (propagated as { outputAlreadyEmitted?: boolean }).outputAlreadyEmitted = sawAcpMessage;\n (propagated as { normalizedOutputError?: unknown }).normalizedOutputError =\n normalizedError;\n throw propagated;\n }\n }\n promptTurnActive = false;\n\n await flushPendingMessages(false);\n output.flush();\n\n const now = isoNow();\n record.lastUsedAt = now;\n record.closed = false;\n record.closedAt = undefined;\n record.protocolVersion = client.initializeResult?.protocolVersion;\n record.agentCapabilities = client.initializeResult?.agentCapabilities;\n applyConversation(record, conversation);\n record.acpx = acpxState;\n applyLifecycleSnapshotToRecord(record, client.getAgentLifecycleSnapshot());\n stopTotalTimer();\n\n return {\n ...toPromptResult(response.stopReason, record.acpxRecordId, client),\n record,\n resumed,\n loadError,\n };\n },\n async () => {\n await client.cancelActivePrompt(INTERRUPT_CANCEL_WAIT_MS);\n applyLifecycleSnapshotToRecord(record, client.getAgentLifecycleSnapshot());\n record.lastUsedAt = isoNow();\n applyConversation(record, conversation);\n record.acpx = acpxState;\n await flushPendingMessages(false).catch(() => {\n // best effort while process is being interrupted\n });\n if (ownClient) {\n await client.close();\n }\n },\n );\n } finally {\n if (options.verbose) {\n process.stderr.write(`[acpx] ${formatPerfMetric(\"prompt.total\", stopTotalTimer())}\\n`);\n } else {\n stopTotalTimer();\n }\n if (notifiedClientAvailable) {\n options.onClientClosed?.();\n }\n client.clearEventHandlers();\n if (ownClient) {\n await client.close();\n }\n applyLifecycleSnapshotToRecord(record, client.getAgentLifecycleSnapshot());\n applyConversation(record, conversation);\n record.acpx = acpxState;\n await flushPendingMessages(false).catch(() => {\n // best effort on close\n });\n await closeEventWriter(true).catch(() => {\n // best effort on close\n });\n }\n}\n\nexport async function runOnce(options: RunOnceOptions): Promise<RunPromptResult> {\n const output = options.outputFormatter;\n let promptTurnActive = false;\n let promptTurnHadSideEffects = false;\n const client = new AcpClient({\n agentCommand: options.agentCommand,\n cwd: absolutePath(options.cwd),\n mcpServers: options.mcpServers,\n permissionMode: options.permissionMode,\n nonInteractivePermissions: options.nonInteractivePermissions,\n authCredentials: options.authCredentials,\n authPolicy: options.authPolicy,\n suppressSdkConsoleErrors: options.suppressSdkConsoleErrors,\n verbose: options.verbose,\n onAcpMessage: options.onAcpMessage,\n onAcpOutputMessage: (_direction, message) => output.onAcpMessage(message),\n onSessionUpdate: (notification) => {\n if (promptTurnActive) {\n promptTurnHadSideEffects = true;\n }\n options.onSessionUpdate?.(notification);\n },\n onClientOperation: (operation) => {\n if (promptTurnActive) {\n promptTurnHadSideEffects = true;\n }\n options.onClientOperation?.(operation);\n },\n sessionOptions: options.sessionOptions,\n });\n\n try {\n return await withInterrupt(\n async () => {\n await measurePerf(\"runtime.exec.start\", async () => {\n await withTimeout(client.start(), options.timeoutMs);\n });\n const createdSession = await measurePerf(\"runtime.exec.create_session\", async () => {\n return await withTimeout(\n client.createSession(absolutePath(options.cwd)),\n options.timeoutMs,\n );\n });\n const sessionId = createdSession.sessionId;\n await applyRequestedModelIfAdvertised({\n client,\n sessionId,\n requestedModel: options.sessionOptions?.model,\n models: createdSession.models,\n timeoutMs: options.timeoutMs,\n });\n\n output.setContext({\n sessionId,\n });\n\n const maxRetries = options.promptRetries ?? 0;\n let response;\n promptTurnActive = true;\n for (let attempt = 0; ; attempt++) {\n try {\n response = await measurePerf(\"runtime.exec.prompt\", async () => {\n return await withTimeout(client.prompt(sessionId, options.prompt), options.timeoutMs);\n });\n break;\n } catch (error) {\n if (\n attempt < maxRetries &&\n !promptTurnHadSideEffects &&\n isRetryablePromptError(error)\n ) {\n const delayMs = Math.min(1_000 * 2 ** attempt, 10_000);\n emitPromptRetryNotice({\n error,\n delayMs,\n attempt: attempt + 1,\n maxRetries,\n suppressSdkConsoleErrors: options.suppressSdkConsoleErrors,\n });\n await waitMs(delayMs);\n if (!promptTurnHadSideEffects) {\n continue;\n }\n }\n promptTurnActive = false;\n throw error;\n }\n }\n promptTurnActive = false;\n output.flush();\n return toPromptResult(response.stopReason, sessionId, client);\n },\n async () => {\n await client.cancelActivePrompt(INTERRUPT_CANCEL_WAIT_MS);\n await client.close();\n },\n );\n } finally {\n await client.close();\n }\n}\n\nexport async function sendSessionDirect(options: SessionSendOptions): Promise<SessionSendResult> {\n return await runSessionPrompt({\n sessionRecordId: options.sessionId,\n prompt: options.prompt,\n mcpServers: options.mcpServers,\n permissionMode: options.permissionMode,\n resumePolicy: options.resumePolicy,\n nonInteractivePermissions: options.nonInteractivePermissions,\n authCredentials: options.authCredentials,\n authPolicy: options.authPolicy,\n outputFormatter: options.outputFormatter,\n onAcpMessage: options.onAcpMessage,\n onSessionUpdate: options.onSessionUpdate,\n onClientOperation: options.onClientOperation,\n timeoutMs: options.timeoutMs,\n suppressSdkConsoleErrors: options.suppressSdkConsoleErrors,\n verbose: options.verbose,\n client: options.client,\n });\n}\n","import { AcpClient } from \"../../acp/client.js\";\nimport { formatErrorMessage } from \"../../acp/error-normalization.js\";\nimport { withTimeout } from \"../../async-control.js\";\nimport { checkpointPerfMetricsCapture } from \"../../perf-metrics-capture.js\";\nimport { setPerfGauge } from \"../../perf-metrics.js\";\nimport { promptToDisplayText } from \"../../prompt-content.js\";\nimport { applyLifecycleSnapshotToRecord } from \"../../runtime/engine/lifecycle.js\";\nimport { sessionOptionsFromRecord } from \"../../runtime/engine/session-options.js\";\nimport {\n absolutePath,\n resolveSessionRecord,\n writeSessionRecord,\n} from \"../../session/persistence.js\";\nimport type { SessionSendOutcome } from \"../../types.js\";\nimport {\n QUEUE_CONNECT_RETRY_MS,\n SessionQueueOwner,\n releaseQueueOwnerLease,\n tryAcquireQueueOwnerLease,\n trySubmitToRunningOwner,\n waitMs,\n} from \"../queue/ipc.js\";\nimport { refreshQueueOwnerLease } from \"../queue/lease-store.js\";\nimport { QueueOwnerTurnController } from \"../queue/owner-turn-controller.js\";\nimport {\n DEFAULT_QUEUE_OWNER_TTL_MS,\n normalizeQueueOwnerTtlMs,\n type SessionSendOptions,\n} from \"./contracts.js\";\nimport {\n runSessionSetConfigOptionDirect,\n runSessionSetModelDirect,\n runSessionSetModeDirect,\n type ActiveSessionController,\n} from \"./prompt-runner.js\";\nimport type { QueueOwnerRuntimeOptions } from \"./queue-owner-process.js\";\nimport { queueOwnerRuntimeOptionsFromSend, spawnQueueOwnerProcess } from \"./queue-owner-process.js\";\nimport { runQueuedTask } from \"./runtime.js\";\n\nconst QUEUE_OWNER_STARTUP_MAX_ATTEMPTS = 120;\nconst QUEUE_OWNER_HEARTBEAT_INTERVAL_MS = 5_000;\n\nasync function submitToRunningOwner(\n options: SessionSendOptions,\n waitForCompletion: boolean,\n): Promise<SessionSendOutcome | undefined> {\n return await trySubmitToRunningOwner({\n sessionId: options.sessionId,\n message: promptToDisplayText(options.prompt),\n prompt: options.prompt,\n permissionMode: options.permissionMode,\n nonInteractivePermissions: options.nonInteractivePermissions,\n outputFormatter: options.outputFormatter,\n errorEmissionPolicy: options.errorEmissionPolicy,\n timeoutMs: options.timeoutMs,\n suppressSdkConsoleErrors: options.suppressSdkConsoleErrors,\n waitForCompletion,\n verbose: options.verbose,\n });\n}\n\nexport async function runSessionQueueOwner(options: QueueOwnerRuntimeOptions): Promise<void> {\n const lease = await tryAcquireQueueOwnerLease(options.sessionId);\n if (!lease) {\n return;\n }\n\n const sessionRecord = await resolveSessionRecord(options.sessionId);\n let owner: SessionQueueOwner | undefined;\n let heartbeatTimer: NodeJS.Timeout | undefined;\n const sharedClient = new AcpClient({\n agentCommand: sessionRecord.agentCommand,\n cwd: absolutePath(sessionRecord.cwd),\n mcpServers: options.mcpServers,\n permissionMode: options.permissionMode,\n nonInteractivePermissions: options.nonInteractivePermissions,\n authCredentials: options.authCredentials,\n authPolicy: options.authPolicy,\n suppressSdkConsoleErrors: options.suppressSdkConsoleErrors,\n verbose: options.verbose,\n sessionOptions: sessionOptionsFromRecord(sessionRecord),\n });\n const ttlMs = normalizeQueueOwnerTtlMs(options.ttlMs);\n const maxQueueDepth = Math.max(1, Math.round(options.maxQueueDepth ?? 16));\n const taskPollTimeoutMs = ttlMs === 0 ? undefined : ttlMs;\n const initialTaskPollTimeoutMs =\n taskPollTimeoutMs == null ? undefined : Math.max(taskPollTimeoutMs, 1_000);\n const turnController = new QueueOwnerTurnController({\n withTimeout: async (run, timeoutMs) => await withTimeout(run(), timeoutMs),\n setSessionModeFallback: async (modeId: string, timeoutMs?: number) => {\n await runSessionSetModeDirect({\n sessionRecordId: options.sessionId,\n modeId,\n mcpServers: options.mcpServers,\n nonInteractivePermissions: options.nonInteractivePermissions,\n authCredentials: options.authCredentials,\n authPolicy: options.authPolicy,\n timeoutMs,\n verbose: options.verbose,\n });\n },\n setSessionModelFallback: async (modelId: string, timeoutMs?: number) => {\n await runSessionSetModelDirect({\n sessionRecordId: options.sessionId,\n modelId,\n mcpServers: options.mcpServers,\n nonInteractivePermissions: options.nonInteractivePermissions,\n authCredentials: options.authCredentials,\n authPolicy: options.authPolicy,\n timeoutMs,\n verbose: options.verbose,\n });\n },\n setSessionConfigOptionFallback: async (configId: string, value: string, timeoutMs?: number) => {\n const result = await runSessionSetConfigOptionDirect({\n sessionRecordId: options.sessionId,\n configId,\n value,\n mcpServers: options.mcpServers,\n nonInteractivePermissions: options.nonInteractivePermissions,\n authCredentials: options.authCredentials,\n authPolicy: options.authPolicy,\n timeoutMs,\n verbose: options.verbose,\n });\n return result.response;\n },\n });\n\n const applyPendingCancel = async (): Promise<boolean> => {\n return await turnController.applyPendingCancel();\n };\n\n const scheduleApplyPendingCancel = (): void => {\n void applyPendingCancel().catch((error) => {\n if (options.verbose) {\n process.stderr.write(\n `[acpx] failed to apply deferred cancel: ${formatErrorMessage(error)}\\n`,\n );\n }\n });\n };\n\n const setActiveController = (controller: ActiveSessionController) => {\n turnController.setActiveController(controller);\n scheduleApplyPendingCancel();\n };\n\n const clearActiveController = () => {\n turnController.clearActiveController();\n };\n\n const runPromptTurn = async <T>(run: () => Promise<T>): Promise<T> => {\n turnController.beginTurn();\n try {\n return await run();\n } finally {\n turnController.endTurn();\n }\n };\n\n try {\n owner = await SessionQueueOwner.start(\n lease,\n {\n cancelPrompt: async () => {\n const accepted = await turnController.requestCancel();\n if (!accepted) {\n return false;\n }\n await applyPendingCancel();\n return true;\n },\n setSessionMode: async (modeId: string, timeoutMs?: number) => {\n await turnController.setSessionMode(modeId, timeoutMs);\n },\n setSessionModel: async (modelId: string, timeoutMs?: number) => {\n await turnController.setSessionModel(modelId, timeoutMs);\n },\n setSessionConfigOption: async (configId: string, value: string, timeoutMs?: number) => {\n return await turnController.setSessionConfigOption(configId, value, timeoutMs);\n },\n },\n {\n maxQueueDepth,\n onQueueDepthChanged: (queueDepth) => {\n setPerfGauge(\"queue.owner.depth\", queueDepth);\n void refreshQueueOwnerLease(lease, { queueDepth }).catch(() => {\n // best effort heartbeat refresh while owner is live\n });\n },\n },\n );\n\n if (options.verbose) {\n process.stderr.write(\n `[acpx] queue owner ready for session ${options.sessionId} (ttlMs=${ttlMs}, maxQueueDepth=${maxQueueDepth})\\n`,\n );\n }\n await refreshQueueOwnerLease(lease, { queueDepth: owner.queueDepth() }).catch(() => {\n // best effort initial heartbeat\n });\n heartbeatTimer = setInterval(() => {\n void refreshQueueOwnerLease(lease, { queueDepth: owner?.queueDepth() ?? 0 }).catch(() => {\n // best effort heartbeat\n });\n }, QUEUE_OWNER_HEARTBEAT_INTERVAL_MS);\n\n let isFirstTask = true;\n while (true) {\n const pollTimeoutMs = isFirstTask ? initialTaskPollTimeoutMs : taskPollTimeoutMs;\n const task = await owner.nextTask(pollTimeoutMs);\n if (!task) {\n break;\n }\n isFirstTask = false;\n\n await runPromptTurn(async () => {\n try {\n await runQueuedTask(options.sessionId, task, {\n sharedClient,\n verbose: options.verbose,\n mcpServers: options.mcpServers,\n nonInteractivePermissions: options.nonInteractivePermissions,\n authCredentials: options.authCredentials,\n authPolicy: options.authPolicy,\n suppressSdkConsoleErrors: options.suppressSdkConsoleErrors,\n promptRetries: options.promptRetries,\n onClientAvailable: setActiveController,\n onClientClosed: clearActiveController,\n onPromptActive: async () => {\n turnController.markPromptActive();\n await applyPendingCancel();\n },\n });\n } finally {\n checkpointPerfMetricsCapture();\n }\n });\n }\n } finally {\n if (heartbeatTimer) {\n clearInterval(heartbeatTimer);\n }\n turnController.beginClosing();\n if (owner) {\n await owner.close();\n }\n await sharedClient.close().catch(() => {\n // best effort while queue owner is shutting down\n });\n try {\n const record = await resolveSessionRecord(options.sessionId);\n applyLifecycleSnapshotToRecord(record, sharedClient.getAgentLifecycleSnapshot());\n await writeSessionRecord(record);\n } catch {\n // best effort — session may already be cleaned up\n }\n await releaseQueueOwnerLease(lease);\n\n if (options.verbose) {\n process.stderr.write(`[acpx] queue owner stopped for session ${options.sessionId}\\n`);\n }\n }\n}\n\nexport async function sendSession(options: SessionSendOptions): Promise<SessionSendOutcome> {\n const waitForCompletion = options.waitForCompletion !== false;\n\n const queuedToOwner = await submitToRunningOwner(options, waitForCompletion);\n if (queuedToOwner) {\n return queuedToOwner;\n }\n\n spawnQueueOwnerProcess(queueOwnerRuntimeOptionsFromSend(options));\n\n for (let attempt = 0; attempt < QUEUE_OWNER_STARTUP_MAX_ATTEMPTS; attempt += 1) {\n const queued = await submitToRunningOwner(options, waitForCompletion);\n if (queued) {\n return queued;\n }\n await waitMs(QUEUE_CONNECT_RETRY_MS);\n }\n\n throw new Error(`Session queue owner failed to start for session ${options.sessionId}`);\n}\n\nexport type { QueueOwnerRuntimeOptions };\nexport { DEFAULT_QUEUE_OWNER_TTL_MS };\n","export * from \"../cli/session/contracts.js\";\nexport * from \"../cli/session/session-management.js\";\nexport * from \"../cli/session/queue-owner-runtime.js\";\nexport * from \"../cli/session/session-control.js\";\nexport * from \"../cli/session/runtime.js\";\nexport {\n DEFAULT_HISTORY_LIMIT,\n findGitRepositoryRoot,\n findSession,\n findSessionByDirectoryWalk,\n listSessions,\n listSessionsForAgent,\n} from \"./persistence.js\";\nexport { isProcessAlive } from \"../cli/queue/ipc.js\";\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { AgentCapabilities, ContentBlock, McpServer, SessionConfigOption } from "@agentclientprotocol/sdk";
1
+ import { AgentCapabilities, AnyMessage, ContentBlock, McpServer, McpServer as McpServer$1, SessionConfigOption, SessionNotification, SetSessionConfigOptionResponse } from "@agentclientprotocol/sdk";
2
2
 
3
3
  //#region src/prompt-content.d.ts
4
4
  type PromptInput = ContentBlock[];
@@ -10,6 +10,23 @@ declare const AUTH_POLICIES: readonly ["skip", "fail"];
10
10
  type AuthPolicy = (typeof AUTH_POLICIES)[number];
11
11
  declare const NON_INTERACTIVE_PERMISSION_POLICIES: readonly ["deny", "fail"];
12
12
  type NonInteractivePermissionPolicy = (typeof NON_INTERACTIVE_PERMISSION_POLICIES)[number];
13
+ type AcpJsonRpcMessage = AnyMessage;
14
+ type AcpMessageDirection = "outbound" | "inbound";
15
+ type PermissionStats = {
16
+ requested: number;
17
+ approved: number;
18
+ denied: number;
19
+ cancelled: number;
20
+ };
21
+ type ClientOperationMethod = "fs/read_text_file" | "fs/write_text_file" | "terminal/create" | "terminal/output" | "terminal/wait_for_exit" | "terminal/kill" | "terminal/release";
22
+ type ClientOperationStatus = "running" | "completed" | "failed";
23
+ type ClientOperation = {
24
+ method: ClientOperationMethod;
25
+ status: ClientOperationStatus;
26
+ summary: string;
27
+ details?: string;
28
+ timestamp: string;
29
+ };
13
30
  type SessionEventLog = {
14
31
  active_path: string;
15
32
  segment_count: number;
@@ -18,6 +35,26 @@ type SessionEventLog = {
18
35
  last_write_at?: string;
19
36
  last_write_error?: string | null;
20
37
  };
38
+ type AcpClientOptions = {
39
+ agentCommand: string;
40
+ cwd: string;
41
+ mcpServers?: McpServer[];
42
+ permissionMode: PermissionMode;
43
+ nonInteractivePermissions?: NonInteractivePermissionPolicy;
44
+ authCredentials?: Record<string, string>;
45
+ authPolicy?: AuthPolicy;
46
+ suppressSdkConsoleErrors?: boolean;
47
+ verbose?: boolean;
48
+ sessionOptions?: {
49
+ model?: string;
50
+ allowedTools?: string[];
51
+ maxTurns?: number;
52
+ };
53
+ onAcpMessage?: (direction: AcpMessageDirection, message: AcpJsonRpcMessage) => void;
54
+ onAcpOutputMessage?: (direction: AcpMessageDirection, message: AcpJsonRpcMessage) => void;
55
+ onSessionUpdate?: (notification: SessionNotification) => void;
56
+ onClientOperation?: (operation: ClientOperation) => void;
57
+ };
21
58
  declare const SESSION_RECORD_SCHEMA: "acpx.session.v1";
22
59
  type SessionMessageImage = {
23
60
  source: string;
@@ -133,5 +170,5 @@ type SessionRecord = {
133
170
  acpx?: SessionAcpxState;
134
171
  };
135
172
  //#endregion
136
- export { SessionRecord as a, PermissionMode as i, McpServer as n, PromptInput as o, NonInteractivePermissionPolicy as r, AuthPolicy as t };
137
- //# sourceMappingURL=types-CeRKmEQ1.d.ts.map
173
+ export { PermissionMode as a, PromptInput as c, NonInteractivePermissionPolicy as i, AuthPolicy as n, PermissionStats as o, McpServer$1 as r, SessionRecord as s, AcpClientOptions as t };
174
+ //# sourceMappingURL=types-DXxLBQc3.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types-DXxLBQc3.d.ts","names":[],"sources":["../src/prompt-content.ts","../src/types.ts"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "acpx",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "Headless CLI client for the Agent Client Protocol (ACP) — talk to coding agents from the command line",
5
5
  "keywords": [
6
6
  "acp",
@@ -29,12 +29,13 @@
29
29
  "type": "module",
30
30
  "exports": {
31
31
  ".": "./dist/cli.js",
32
+ "./runtime": "./dist/runtime.js",
32
33
  "./flows": "./dist/flows.js",
33
34
  "./dist/*": "./dist/*",
34
35
  "./package.json": "./package.json"
35
36
  },
36
37
  "scripts": {
37
- "build": "tsdown src/cli.ts src/flows.ts --format esm --dts --clean --platform node --target node22 --no-fixedExtension",
38
+ "build": "tsdown src/cli.ts src/flows.ts src/runtime.ts --format esm --dts --clean --platform node --target node22 --no-fixedExtension",
38
39
  "build:test": "node -e \"require('node:fs').rmSync('dist-test',{recursive:true,force:true})\" && tsc -p tsconfig.test.json",
39
40
  "check": "pnpm run format:check && pnpm run typecheck && pnpm run lint && pnpm run build && pnpm run viewer:typecheck && pnpm run viewer:build && pnpm run test:coverage",
40
41
  "check:docs": "pnpm run format:docs:check && pnpm run lint:docs",
@@ -59,36 +60,46 @@
59
60
  "test:live": "pnpm run build:test && node --test dist-test/test/cursor-live.integration.js",
60
61
  "typecheck": "tsgo --noEmit",
61
62
  "typecheck:tsc": "tsc --noEmit",
63
+ "viewer": "tsx examples/flows/replay-viewer/server.ts start",
62
64
  "viewer:build": "vite build --config examples/flows/replay-viewer/vite.config.ts",
63
- "viewer:dev": "tsx examples/flows/replay-viewer/server.ts",
64
- "viewer:preview": "tsx examples/flows/replay-viewer/server.ts",
65
+ "viewer:dev": "tsx examples/flows/replay-viewer/server.ts start",
66
+ "viewer:open": "tsx examples/flows/replay-viewer/server.ts start --open",
67
+ "viewer:preview": "tsx examples/flows/replay-viewer/server.ts start",
68
+ "viewer:status": "tsx examples/flows/replay-viewer/server.ts status",
69
+ "viewer:stop": "tsx examples/flows/replay-viewer/server.ts stop",
65
70
  "viewer:typecheck": "tsc -p examples/flows/replay-viewer/tsconfig.json --noEmit && tsc -p examples/flows/replay-viewer/tsconfig.server.json --noEmit"
66
71
  },
67
72
  "dependencies": {
68
73
  "@agentclientprotocol/sdk": "^0.17.0",
69
74
  "commander": "^14.0.3",
70
75
  "skillflag": "^0.1.4",
71
- "tsx": "^4.0.0"
76
+ "tsx": "^4.0.0",
77
+ "zod": "^4.3.6"
72
78
  },
73
79
  "devDependencies": {
74
80
  "@types/node": "^25.3.5",
75
81
  "@types/react": "^19.2.14",
76
82
  "@types/react-dom": "^19.2.3",
77
- "@typescript/native-preview": "7.0.0-dev.20260326.1",
83
+ "@types/react-test-renderer": "^19.1.0",
84
+ "@types/ws": "^8.18.1",
85
+ "@typescript/native-preview": "7.0.0-dev.20260328.1",
78
86
  "@vitejs/plugin-react": "^6.0.1",
79
87
  "@xyflow/react": "^12.10.1",
80
88
  "elkjs": "^0.11.1",
89
+ "fast-json-patch": "^3.1.1",
81
90
  "husky": "^9.1.7",
82
91
  "lint-staged": "^16.3.2",
83
92
  "markdownlint-cli2": "^0.22.0",
84
93
  "oxfmt": "^0.42.0",
85
94
  "oxlint": "^1.51.0",
86
- "oxlint-tsgolint": "^0.17.4",
95
+ "oxlint-tsgolint": "^0.18.1",
87
96
  "react": "^19.2.4",
88
97
  "react-dom": "^19.2.4",
98
+ "react-test-renderer": "^19.2.0",
89
99
  "tsdown": "^0.21.0-beta.2",
90
- "typescript": "^5.7.0",
91
- "vite": "^8.0.3"
100
+ "typescript": "^6.0.2",
101
+ "vite": "^8.0.3",
102
+ "ws": "^8.18.3"
92
103
  },
93
104
  "lint-staged": {
94
105
  "*.{js,ts}": [
@@ -1 +0,0 @@
1
- {"version":3,"file":"acp-jsonrpc-C7pPk9Tw.js","names":[],"sources":["../src/acp-jsonrpc.ts"],"sourcesContent":["import type { AnyMessage } from \"@agentclientprotocol/sdk\";\n\ntype JsonRpcId = string | number | null;\n\nfunction asRecord(value: unknown): Record<string, unknown> | null {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n return null;\n }\n return value as Record<string, unknown>;\n}\n\nfunction hasValidId(value: unknown): value is JsonRpcId {\n return (\n value === null ||\n typeof value === \"string\" ||\n (typeof value === \"number\" && Number.isFinite(value))\n );\n}\n\nfunction isErrorObject(value: unknown): value is { code: number; message: string } {\n const record = asRecord(value);\n return (\n !!record &&\n typeof record.code === \"number\" &&\n Number.isFinite(record.code) &&\n typeof record.message === \"string\"\n );\n}\n\nfunction hasResultOrError(value: Record<string, unknown>): boolean {\n const hasResult = Object.hasOwn(value, \"result\");\n const hasError = Object.hasOwn(value, \"error\");\n if (hasResult && hasError) {\n return false;\n }\n if (!hasResult && !hasError) {\n return false;\n }\n if (hasError && !isErrorObject(value.error)) {\n return false;\n }\n return true;\n}\n\nexport function isAcpJsonRpcMessage(value: unknown): value is AnyMessage {\n const record = asRecord(value);\n if (!record || record.jsonrpc !== \"2.0\") {\n return false;\n }\n\n const hasMethod = typeof record.method === \"string\" && record.method.length > 0;\n const hasId = Object.hasOwn(record, \"id\");\n\n if (hasMethod && !hasId) {\n // Notification\n return true;\n }\n\n if (hasMethod && hasId) {\n // Request\n return hasValidId(record.id);\n }\n\n if (!hasMethod && hasId) {\n // Response\n if (!hasValidId(record.id)) {\n return false;\n }\n return hasResultOrError(record);\n }\n\n return false;\n}\n\nexport function isJsonRpcNotification(message: AnyMessage): boolean {\n return (\n Object.hasOwn(message, \"method\") &&\n typeof (message as { method?: unknown }).method === \"string\" &&\n !Object.hasOwn(message, \"id\")\n );\n}\n\nexport function isSessionUpdateNotification(message: AnyMessage): boolean {\n return (\n isJsonRpcNotification(message) && (message as { method?: unknown }).method === \"session/update\"\n );\n}\n\nexport function parsePromptStopReason(message: AnyMessage): string | undefined {\n if (!Object.hasOwn(message, \"id\") || !Object.hasOwn(message, \"result\")) {\n return undefined;\n }\n const record = asRecord((message as { result?: unknown }).result);\n if (!record) {\n return undefined;\n }\n return typeof record.stopReason === \"string\" ? record.stopReason : undefined;\n}\n\nexport function parseJsonRpcErrorMessage(message: AnyMessage): string | undefined {\n if (!Object.hasOwn(message, \"error\")) {\n return undefined;\n }\n const errorRecord = asRecord((message as { error?: unknown }).error);\n if (!errorRecord || typeof errorRecord.message !== \"string\") {\n return undefined;\n }\n return errorRecord.message;\n}\n"],"mappings":";AAIA,SAAS,SAAS,OAAgD;AAChE,KAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,MAAM,CAC7D,QAAO;AAET,QAAO;;AAGT,SAAS,WAAW,OAAoC;AACtD,QACE,UAAU,QACV,OAAO,UAAU,YAChB,OAAO,UAAU,YAAY,OAAO,SAAS,MAAM;;AAIxD,SAAS,cAAc,OAA4D;CACjF,MAAM,SAAS,SAAS,MAAM;AAC9B,QACE,CAAC,CAAC,UACF,OAAO,OAAO,SAAS,YACvB,OAAO,SAAS,OAAO,KAAK,IAC5B,OAAO,OAAO,YAAY;;AAI9B,SAAS,iBAAiB,OAAyC;CACjE,MAAM,YAAY,OAAO,OAAO,OAAO,SAAS;CAChD,MAAM,WAAW,OAAO,OAAO,OAAO,QAAQ;AAC9C,KAAI,aAAa,SACf,QAAO;AAET,KAAI,CAAC,aAAa,CAAC,SACjB,QAAO;AAET,KAAI,YAAY,CAAC,cAAc,MAAM,MAAM,CACzC,QAAO;AAET,QAAO;;AAGT,SAAgB,oBAAoB,OAAqC;CACvE,MAAM,SAAS,SAAS,MAAM;AAC9B,KAAI,CAAC,UAAU,OAAO,YAAY,MAChC,QAAO;CAGT,MAAM,YAAY,OAAO,OAAO,WAAW,YAAY,OAAO,OAAO,SAAS;CAC9E,MAAM,QAAQ,OAAO,OAAO,QAAQ,KAAK;AAEzC,KAAI,aAAa,CAAC,MAEhB,QAAO;AAGT,KAAI,aAAa,MAEf,QAAO,WAAW,OAAO,GAAG;AAG9B,KAAI,CAAC,aAAa,OAAO;AAEvB,MAAI,CAAC,WAAW,OAAO,GAAG,CACxB,QAAO;AAET,SAAO,iBAAiB,OAAO;;AAGjC,QAAO;;AAGT,SAAgB,sBAAsB,SAA8B;AAClE,QACE,OAAO,OAAO,SAAS,SAAS,IAChC,OAAQ,QAAiC,WAAW,YACpD,CAAC,OAAO,OAAO,SAAS,KAAK;;AAIjC,SAAgB,4BAA4B,SAA8B;AACxE,QACE,sBAAsB,QAAQ,IAAK,QAAiC,WAAW;;AAInF,SAAgB,sBAAsB,SAAyC;AAC7E,KAAI,CAAC,OAAO,OAAO,SAAS,KAAK,IAAI,CAAC,OAAO,OAAO,SAAS,SAAS,CACpE;CAEF,MAAM,SAAS,SAAU,QAAiC,OAAO;AACjE,KAAI,CAAC,OACH;AAEF,QAAO,OAAO,OAAO,eAAe,WAAW,OAAO,aAAa,KAAA;;AAGrE,SAAgB,yBAAyB,SAAyC;AAChF,KAAI,CAAC,OAAO,OAAO,SAAS,QAAQ,CAClC;CAEF,MAAM,cAAc,SAAU,QAAgC,MAAM;AACpE,KAAI,CAAC,eAAe,OAAO,YAAY,YAAY,SACjD;AAEF,QAAO,YAAY"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"cli-5s-E-Y99.js","names":[],"sources":["../src/flows/cli.ts"],"sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { fileURLToPath, pathToFileURL } from \"node:url\";\nimport { InvalidArgumentError, type Command } from \"commander\";\nimport {\n hasExplicitPermissionModeFlag,\n resolveAgentInvocation,\n resolveGlobalFlags,\n resolveOutputPolicy,\n resolvePermissionMode,\n type GlobalFlags,\n} from \"../cli/flags.js\";\nimport type { ResolvedAcpxConfig } from \"../config.js\";\nimport { type FlowDefinition, FlowRunner } from \"../flows.js\";\nimport { permissionModeSatisfies } from \"../permissions.js\";\nimport type { PermissionMode } from \"../types.js\";\n\ntype FlowRunFlags = {\n inputJson?: string;\n inputFile?: string;\n defaultAgent?: string;\n};\n\nconst FLOW_RUNTIME_SPECIFIER = \"acpx/flows\";\nconst TEXT_MODULE_EXTENSIONS = new Set([\".js\", \".mjs\", \".cjs\", \".ts\", \".tsx\", \".mts\", \".cts\"]);\n\nexport async function handleFlowRun(\n flowFile: string,\n flags: FlowRunFlags,\n command: Command,\n config: ResolvedAcpxConfig,\n): Promise<void> {\n const globalFlags = resolveGlobalFlags(command, config);\n const permissionMode = resolvePermissionMode(globalFlags, config.defaultPermissions);\n const outputPolicy = resolveOutputPolicy(globalFlags.format, globalFlags.jsonStrict === true);\n const input = await readFlowInput(flags);\n const flowPath = path.resolve(flowFile);\n const flow = await loadFlowModule(flowPath);\n assertFlowPermissionRequirements(flow, permissionMode, globalFlags);\n\n const runner = new FlowRunner({\n resolveAgent: (profile?: string) => {\n return resolveAgentInvocation(profile ?? flags.defaultAgent, globalFlags, config);\n },\n permissionMode,\n mcpServers: config.mcpServers,\n nonInteractivePermissions: globalFlags.nonInteractivePermissions,\n authCredentials: config.auth,\n authPolicy: globalFlags.authPolicy,\n timeoutMs: globalFlags.timeout,\n ttlMs: globalFlags.ttl,\n verbose: globalFlags.verbose,\n suppressSdkConsoleErrors: outputPolicy.suppressSdkConsoleErrors,\n sessionOptions: {\n model: globalFlags.model,\n allowedTools: globalFlags.allowedTools,\n maxTurns: globalFlags.maxTurns,\n },\n });\n\n const result = await runner.run(flow, input, {\n flowPath,\n });\n\n printFlowRunResult(result, globalFlags);\n}\n\nfunction assertFlowPermissionRequirements(\n flow: FlowDefinition,\n permissionMode: PermissionMode,\n globalFlags: GlobalFlags,\n): void {\n const permissions = flow.permissions;\n if (!permissions) {\n return;\n }\n\n if (permissions.requireExplicitGrant && !hasExplicitPermissionModeFlag(globalFlags)) {\n throw new InvalidArgumentError(\n buildFlowPermissionFailureMessage(flow, permissions.requiredMode, permissions.reason, true),\n );\n }\n\n if (!permissionModeSatisfies(permissionMode, permissions.requiredMode)) {\n throw new InvalidArgumentError(\n buildFlowPermissionFailureMessage(flow, permissions.requiredMode, permissions.reason, false),\n );\n }\n}\n\nfunction buildFlowPermissionFailureMessage(\n flow: FlowDefinition,\n requiredMode: PermissionMode,\n reason?: string,\n explicit = false,\n): string {\n return [\n explicit\n ? `Flow \"${flow.name}\" requires an explicit ${requiredMode} grant.`\n : `Flow \"${flow.name}\" requires permission mode ${requiredMode}.`,\n `Rerun with --${requiredMode}.`,\n ...(reason ? [`Reason: ${reason}`] : []),\n ].join(\" \");\n}\n\nasync function readFlowInput(flags: FlowRunFlags): Promise<unknown> {\n if (flags.inputJson && flags.inputFile) {\n throw new InvalidArgumentError(\"Use only one of --input-json or --input-file\");\n }\n\n if (flags.inputJson) {\n return parseJsonInput(flags.inputJson, \"--input-json\");\n }\n\n if (flags.inputFile) {\n const inputPath = path.resolve(flags.inputFile);\n const payload = await fs.readFile(inputPath, \"utf8\");\n return parseJsonInput(payload, \"--input-file\");\n }\n\n return {};\n}\n\nasync function loadFlowModule(flowPath: string): Promise<FlowDefinition> {\n const extension = path.extname(flowPath).toLowerCase();\n const prepared = await prepareFlowModuleImport(flowPath, extension);\n try {\n const module = await loadFlowRuntimeModule(prepared.flowUrl, extension);\n\n const candidate = findFlowDefinition(module);\n if (!candidate) {\n throw new Error(`Flow module must export a flow object: ${flowPath}`);\n }\n return candidate;\n } finally {\n await prepared.cleanup?.();\n }\n}\n\nasync function prepareFlowModuleImport(\n flowPath: string,\n extension: string,\n): Promise<{\n flowUrl: string;\n cleanup?: () => Promise<void>;\n}> {\n const flowUrl = pathToFileURL(flowPath).href;\n if (!TEXT_MODULE_EXTENSIONS.has(extension)) {\n return { flowUrl };\n }\n\n const source = await fs.readFile(flowPath, \"utf8\");\n if (!source.includes(FLOW_RUNTIME_SPECIFIER)) {\n return { flowUrl };\n }\n\n const runtimeSpecifier = resolveFlowRuntimeImportSpecifier();\n const rewritten = source.replaceAll(\n /([\"'])acpx\\/flows\\1/g,\n (_match, quote: string) => `${quote}${runtimeSpecifier}${quote}`,\n );\n if (rewritten === source) {\n return { flowUrl };\n }\n\n const tempPath = path.join(path.dirname(flowPath), `.acpx-flow-load-${randomUUID()}${extension}`);\n await fs.writeFile(tempPath, rewritten, \"utf8\");\n return {\n flowUrl: pathToFileURL(tempPath).href,\n cleanup: async () => {\n await fs.rm(tempPath, { force: true });\n },\n };\n}\n\nfunction resolveFlowRuntimeImportSpecifier(): string {\n const selfPath = fileURLToPath(import.meta.url);\n\n if (selfPath.endsWith(`${path.sep}src${path.sep}flows${path.sep}cli.ts`)) {\n return new URL(\"../flows.ts\", import.meta.url).href;\n }\n if (selfPath.endsWith(`${path.sep}src${path.sep}flows${path.sep}cli.js`)) {\n return new URL(\"../flows.js\", import.meta.url).href;\n }\n return new URL(\"./flows.js\", import.meta.url).href;\n}\n\nasync function loadFlowRuntimeModule(\n flowUrl: string,\n extension: string,\n): Promise<{\n default?: unknown;\n \"module.exports\"?: unknown;\n}> {\n if (extension === \".ts\" || extension === \".tsx\" || extension === \".mts\" || extension === \".cts\") {\n const { tsImport } = (await import(\"tsx/esm/api\")) as {\n tsImport: (\n specifier: string,\n parentURL: string,\n ) => Promise<{\n default?: unknown;\n \"module.exports\"?: unknown;\n }>;\n };\n return (await tsImport(flowUrl, import.meta.url)) as {\n default?: unknown;\n \"module.exports\"?: unknown;\n };\n }\n\n return (await import(flowUrl)) as {\n default?: unknown;\n \"module.exports\"?: unknown;\n };\n}\n\nfunction findFlowDefinition(module: {\n default?: unknown;\n \"module.exports\"?: unknown;\n}): FlowDefinition | null {\n const candidates = [\n module.default,\n module[\"module.exports\"],\n getNestedDefault(module.default),\n getNestedDefault(module[\"module.exports\"]),\n ];\n\n for (const candidate of candidates) {\n if (isFlowDefinition(candidate)) {\n return candidate;\n }\n }\n\n return null;\n}\n\nfunction getNestedDefault(value: unknown): unknown {\n if (!value || typeof value !== \"object\" || !(\"default\" in value)) {\n return null;\n }\n return (value as { default?: unknown }).default ?? null;\n}\n\nfunction isFlowDefinition(value: unknown): value is FlowDefinition {\n if (!value || typeof value !== \"object\") {\n return false;\n }\n\n const candidate = value as Partial<FlowDefinition>;\n return (\n typeof candidate.name === \"string\" &&\n typeof candidate.startAt === \"string\" &&\n candidate.nodes !== undefined &&\n typeof candidate.nodes === \"object\" &&\n Array.isArray(candidate.edges)\n );\n}\n\nfunction parseJsonInput(raw: string, label: string): unknown {\n try {\n return JSON.parse(raw);\n } catch (error) {\n throw new InvalidArgumentError(\n `${label} must contain valid JSON: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n}\n\nfunction printFlowRunResult(\n result: Awaited<ReturnType<FlowRunner[\"run\"]>>,\n globalFlags: GlobalFlags,\n): void {\n const payload = {\n action: \"flow_run_result\",\n runId: result.state.runId,\n flowName: result.state.flowName,\n runTitle: result.state.runTitle,\n flowPath: result.state.flowPath,\n status: result.state.status,\n currentNode: result.state.currentNode,\n currentNodeType: result.state.currentNodeType,\n currentNodeStartedAt: result.state.currentNodeStartedAt,\n lastHeartbeatAt: result.state.lastHeartbeatAt,\n statusDetail: result.state.statusDetail,\n waitingOn: result.state.waitingOn,\n runDir: result.runDir,\n outputs: result.state.outputs,\n sessionBindings: result.state.sessionBindings,\n };\n\n if (globalFlags.format === \"json\") {\n process.stdout.write(`${JSON.stringify(payload)}\\n`);\n return;\n }\n\n if (globalFlags.format === \"quiet\") {\n process.stdout.write(`${result.state.runId}\\n`);\n return;\n }\n\n process.stdout.write(`runId: ${payload.runId}\\n`);\n process.stdout.write(`flow: ${payload.flowName}\\n`);\n if (payload.runTitle) {\n process.stdout.write(`title: ${payload.runTitle}\\n`);\n }\n process.stdout.write(`status: ${payload.status}\\n`);\n process.stdout.write(`runDir: ${payload.runDir}\\n`);\n if (payload.currentNode) {\n process.stdout.write(`currentNode: ${payload.currentNode}\\n`);\n }\n if (payload.statusDetail) {\n process.stdout.write(`statusDetail: ${payload.statusDetail}\\n`);\n }\n if (payload.waitingOn) {\n process.stdout.write(`waitingOn: ${payload.waitingOn}\\n`);\n }\n process.stdout.write(`${JSON.stringify(payload.outputs, null, 2)}\\n`);\n}\n"],"mappings":";;;;;;;;;AAwBA,MAAM,yBAAyB;AAC/B,MAAM,yBAAyB,IAAI,IAAI;CAAC;CAAO;CAAQ;CAAQ;CAAO;CAAQ;CAAQ;CAAO,CAAC;AAE9F,eAAsB,cACpB,UACA,OACA,SACA,QACe;CACf,MAAM,cAAc,mBAAmB,SAAS,OAAO;CACvD,MAAM,iBAAiB,sBAAsB,aAAa,OAAO,mBAAmB;CACpF,MAAM,eAAe,oBAAoB,YAAY,QAAQ,YAAY,eAAe,KAAK;CAC7F,MAAM,QAAQ,MAAM,cAAc,MAAM;CACxC,MAAM,WAAW,KAAK,QAAQ,SAAS;CACvC,MAAM,OAAO,MAAM,eAAe,SAAS;AAC3C,kCAAiC,MAAM,gBAAgB,YAAY;AA0BnE,oBAJe,MApBA,IAAI,WAAW;EAC5B,eAAe,YAAqB;AAClC,UAAO,uBAAuB,WAAW,MAAM,cAAc,aAAa,OAAO;;EAEnF;EACA,YAAY,OAAO;EACnB,2BAA2B,YAAY;EACvC,iBAAiB,OAAO;EACxB,YAAY,YAAY;EACxB,WAAW,YAAY;EACvB,OAAO,YAAY;EACnB,SAAS,YAAY;EACrB,0BAA0B,aAAa;EACvC,gBAAgB;GACd,OAAO,YAAY;GACnB,cAAc,YAAY;GAC1B,UAAU,YAAY;GACvB;EACF,CAAC,CAE0B,IAAI,MAAM,OAAO,EAC3C,UACD,CAAC,EAEyB,YAAY;;AAGzC,SAAS,iCACP,MACA,gBACA,aACM;CACN,MAAM,cAAc,KAAK;AACzB,KAAI,CAAC,YACH;AAGF,KAAI,YAAY,wBAAwB,CAAC,8BAA8B,YAAY,CACjF,OAAM,IAAI,qBACR,kCAAkC,MAAM,YAAY,cAAc,YAAY,QAAQ,KAAK,CAC5F;AAGH,KAAI,CAAC,wBAAwB,gBAAgB,YAAY,aAAa,CACpE,OAAM,IAAI,qBACR,kCAAkC,MAAM,YAAY,cAAc,YAAY,QAAQ,MAAM,CAC7F;;AAIL,SAAS,kCACP,MACA,cACA,QACA,WAAW,OACH;AACR,QAAO;EACL,WACI,SAAS,KAAK,KAAK,yBAAyB,aAAa,WACzD,SAAS,KAAK,KAAK,6BAA6B,aAAa;EACjE,gBAAgB,aAAa;EAC7B,GAAI,SAAS,CAAC,WAAW,SAAS,GAAG,EAAE;EACxC,CAAC,KAAK,IAAI;;AAGb,eAAe,cAAc,OAAuC;AAClE,KAAI,MAAM,aAAa,MAAM,UAC3B,OAAM,IAAI,qBAAqB,+CAA+C;AAGhF,KAAI,MAAM,UACR,QAAO,eAAe,MAAM,WAAW,eAAe;AAGxD,KAAI,MAAM,WAAW;EACnB,MAAM,YAAY,KAAK,QAAQ,MAAM,UAAU;AAE/C,SAAO,eADS,MAAM,GAAG,SAAS,WAAW,OAAO,EACrB,eAAe;;AAGhD,QAAO,EAAE;;AAGX,eAAe,eAAe,UAA2C;CACvE,MAAM,YAAY,KAAK,QAAQ,SAAS,CAAC,aAAa;CACtD,MAAM,WAAW,MAAM,wBAAwB,UAAU,UAAU;AACnE,KAAI;EAGF,MAAM,YAAY,mBAFH,MAAM,sBAAsB,SAAS,SAAS,UAAU,CAE3B;AAC5C,MAAI,CAAC,UACH,OAAM,IAAI,MAAM,0CAA0C,WAAW;AAEvE,SAAO;WACC;AACR,QAAM,SAAS,WAAW;;;AAI9B,eAAe,wBACb,UACA,WAIC;CACD,MAAM,UAAU,cAAc,SAAS,CAAC;AACxC,KAAI,CAAC,uBAAuB,IAAI,UAAU,CACxC,QAAO,EAAE,SAAS;CAGpB,MAAM,SAAS,MAAM,GAAG,SAAS,UAAU,OAAO;AAClD,KAAI,CAAC,OAAO,SAAS,uBAAuB,CAC1C,QAAO,EAAE,SAAS;CAGpB,MAAM,mBAAmB,mCAAmC;CAC5D,MAAM,YAAY,OAAO,WACvB,yBACC,QAAQ,UAAkB,GAAG,QAAQ,mBAAmB,QAC1D;AACD,KAAI,cAAc,OAChB,QAAO,EAAE,SAAS;CAGpB,MAAM,WAAW,KAAK,KAAK,KAAK,QAAQ,SAAS,EAAE,mBAAmB,YAAY,GAAG,YAAY;AACjG,OAAM,GAAG,UAAU,UAAU,WAAW,OAAO;AAC/C,QAAO;EACL,SAAS,cAAc,SAAS,CAAC;EACjC,SAAS,YAAY;AACnB,SAAM,GAAG,GAAG,UAAU,EAAE,OAAO,MAAM,CAAC;;EAEzC;;AAGH,SAAS,oCAA4C;CACnD,MAAM,WAAW,cAAc,OAAO,KAAK,IAAI;AAE/C,KAAI,SAAS,SAAS,GAAG,KAAK,IAAI,KAAK,KAAK,IAAI,OAAO,KAAK,IAAI,QAAQ,CACtE,QAAO,IAAI,IAAI,eAAe,OAAO,KAAK,IAAI,CAAC;AAEjD,KAAI,SAAS,SAAS,GAAG,KAAK,IAAI,KAAK,KAAK,IAAI,OAAO,KAAK,IAAI,QAAQ,CACtE,QAAO,IAAI,IAAI,eAAe,OAAO,KAAK,IAAI,CAAC;AAEjD,QAAO,IAAI,IAAI,cAAc,OAAO,KAAK,IAAI,CAAC;;AAGhD,eAAe,sBACb,SACA,WAIC;AACD,KAAI,cAAc,SAAS,cAAc,UAAU,cAAc,UAAU,cAAc,QAAQ;EAC/F,MAAM,EAAE,aAAc,MAAM,OAAO;AASnC,SAAQ,MAAM,SAAS,SAAS,OAAO,KAAK,IAAI;;AAMlD,QAAQ,MAAM,OAAO;;AAMvB,SAAS,mBAAmB,QAGF;CACxB,MAAM,aAAa;EACjB,OAAO;EACP,OAAO;EACP,iBAAiB,OAAO,QAAQ;EAChC,iBAAiB,OAAO,kBAAkB;EAC3C;AAED,MAAK,MAAM,aAAa,WACtB,KAAI,iBAAiB,UAAU,CAC7B,QAAO;AAIX,QAAO;;AAGT,SAAS,iBAAiB,OAAyB;AACjD,KAAI,CAAC,SAAS,OAAO,UAAU,YAAY,EAAE,aAAa,OACxD,QAAO;AAET,QAAQ,MAAgC,WAAW;;AAGrD,SAAS,iBAAiB,OAAyC;AACjE,KAAI,CAAC,SAAS,OAAO,UAAU,SAC7B,QAAO;CAGT,MAAM,YAAY;AAClB,QACE,OAAO,UAAU,SAAS,YAC1B,OAAO,UAAU,YAAY,YAC7B,UAAU,UAAU,KAAA,KACpB,OAAO,UAAU,UAAU,YAC3B,MAAM,QAAQ,UAAU,MAAM;;AAIlC,SAAS,eAAe,KAAa,OAAwB;AAC3D,KAAI;AACF,SAAO,KAAK,MAAM,IAAI;UACf,OAAO;AACd,QAAM,IAAI,qBACR,GAAG,MAAM,4BAA4B,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM,GAC5F;;;AAIL,SAAS,mBACP,QACA,aACM;CACN,MAAM,UAAU;EACd,QAAQ;EACR,OAAO,OAAO,MAAM;EACpB,UAAU,OAAO,MAAM;EACvB,UAAU,OAAO,MAAM;EACvB,UAAU,OAAO,MAAM;EACvB,QAAQ,OAAO,MAAM;EACrB,aAAa,OAAO,MAAM;EAC1B,iBAAiB,OAAO,MAAM;EAC9B,sBAAsB,OAAO,MAAM;EACnC,iBAAiB,OAAO,MAAM;EAC9B,cAAc,OAAO,MAAM;EAC3B,WAAW,OAAO,MAAM;EACxB,QAAQ,OAAO;EACf,SAAS,OAAO,MAAM;EACtB,iBAAiB,OAAO,MAAM;EAC/B;AAED,KAAI,YAAY,WAAW,QAAQ;AACjC,UAAQ,OAAO,MAAM,GAAG,KAAK,UAAU,QAAQ,CAAC,IAAI;AACpD;;AAGF,KAAI,YAAY,WAAW,SAAS;AAClC,UAAQ,OAAO,MAAM,GAAG,OAAO,MAAM,MAAM,IAAI;AAC/C;;AAGF,SAAQ,OAAO,MAAM,UAAU,QAAQ,MAAM,IAAI;AACjD,SAAQ,OAAO,MAAM,SAAS,QAAQ,SAAS,IAAI;AACnD,KAAI,QAAQ,SACV,SAAQ,OAAO,MAAM,UAAU,QAAQ,SAAS,IAAI;AAEtD,SAAQ,OAAO,MAAM,WAAW,QAAQ,OAAO,IAAI;AACnD,SAAQ,OAAO,MAAM,WAAW,QAAQ,OAAO,IAAI;AACnD,KAAI,QAAQ,YACV,SAAQ,OAAO,MAAM,gBAAgB,QAAQ,YAAY,IAAI;AAE/D,KAAI,QAAQ,aACV,SAAQ,OAAO,MAAM,iBAAiB,QAAQ,aAAa,IAAI;AAEjE,KAAI,QAAQ,UACV,SAAQ,OAAO,MAAM,cAAc,QAAQ,UAAU,IAAI;AAE3D,SAAQ,OAAO,MAAM,GAAG,KAAK,UAAU,QAAQ,SAAS,MAAM,EAAE,CAAC,IAAI"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"flags-BkWInxAq.js","names":["resolveAgentCommandFromRegistry"],"sources":["../src/agent-registry.ts","../src/cli/flags.ts"],"sourcesContent":["const ACP_ADAPTER_PACKAGE_RANGES = {\n pi: \"^0.0.22\",\n codex: \"^0.10.0\",\n claude: \"^0.24.2\",\n} as const;\n\nexport const AGENT_REGISTRY: Record<string, string> = {\n pi: `npx pi-acp@${ACP_ADAPTER_PACKAGE_RANGES.pi}`,\n openclaw: \"openclaw acp\",\n codex: `npx @zed-industries/codex-acp@${ACP_ADAPTER_PACKAGE_RANGES.codex}`,\n claude: `npx -y @agentclientprotocol/claude-agent-acp@${ACP_ADAPTER_PACKAGE_RANGES.claude}`,\n gemini: \"gemini --acp\",\n cursor: \"cursor-agent acp\",\n copilot: \"copilot --acp --stdio\",\n droid: \"droid exec --output-format acp\",\n iflow: \"iflow --experimental-acp\",\n kilocode: \"npx -y @kilocode/cli acp\",\n kimi: \"kimi acp\",\n kiro: \"kiro-cli-chat acp\",\n opencode: \"npx -y opencode-ai acp\",\n qoder: \"qodercli --acp\",\n qwen: \"qwen --acp\",\n trae: \"traecli acp serve\",\n};\n\nconst AGENT_ALIASES: Record<string, string> = {\n \"factory-droid\": \"droid\",\n factorydroid: \"droid\",\n};\n\nexport const DEFAULT_AGENT_NAME = \"codex\";\n\nexport function normalizeAgentName(value: string): string {\n return value.trim().toLowerCase();\n}\n\nexport function mergeAgentRegistry(overrides?: Record<string, string>): Record<string, string> {\n if (!overrides) {\n return { ...AGENT_REGISTRY };\n }\n\n const merged = { ...AGENT_REGISTRY };\n for (const [name, command] of Object.entries(overrides)) {\n const normalized = normalizeAgentName(name);\n if (!normalized || !command.trim()) {\n continue;\n }\n merged[normalized] = command.trim();\n }\n return merged;\n}\n\nexport function resolveAgentCommand(agentName: string, overrides?: Record<string, string>): string {\n const normalized = normalizeAgentName(agentName);\n const registry = mergeAgentRegistry(overrides);\n return registry[normalized] ?? registry[AGENT_ALIASES[normalized] ?? normalized] ?? agentName;\n}\n\nexport function listBuiltInAgents(overrides?: Record<string, string>): string[] {\n return Object.keys(mergeAgentRegistry(overrides));\n}\n","import path from \"node:path\";\nimport { InvalidArgumentError } from \"commander\";\nimport type { Command } from \"commander\";\nimport {\n DEFAULT_AGENT_NAME,\n resolveAgentCommand as resolveAgentCommandFromRegistry,\n} from \"../agent-registry.js\";\nimport type { ResolvedAcpxConfig } from \"../config.js\";\nimport { DEFAULT_QUEUE_OWNER_TTL_MS } from \"../session.js\";\nimport {\n AUTH_POLICIES,\n NON_INTERACTIVE_PERMISSION_POLICIES,\n OUTPUT_FORMATS,\n type AuthPolicy,\n type NonInteractivePermissionPolicy,\n type OutputFormat,\n type OutputPolicy,\n type PermissionMode,\n} from \"../types.js\";\n\nexport type PermissionFlags = {\n approveAll?: boolean;\n approveReads?: boolean;\n denyAll?: boolean;\n};\n\nexport function hasExplicitPermissionModeFlag(flags: PermissionFlags): boolean {\n return flags.approveAll === true || flags.approveReads === true || flags.denyAll === true;\n}\n\nexport type GlobalFlags = PermissionFlags & {\n agent?: string;\n cwd: string;\n authPolicy?: AuthPolicy;\n nonInteractivePermissions: NonInteractivePermissionPolicy;\n jsonStrict?: boolean;\n suppressReads?: boolean;\n timeout?: number;\n ttl: number;\n verbose?: boolean;\n format: OutputFormat;\n model?: string;\n allowedTools?: string[];\n maxTurns?: number;\n promptRetries?: number;\n};\n\nexport type PromptFlags = {\n session?: string;\n wait?: boolean;\n file?: string;\n};\n\nexport type ExecFlags = {\n file?: string;\n};\n\nexport type SessionsNewFlags = {\n name?: string;\n resumeSession?: string;\n};\n\nexport type SessionsHistoryFlags = {\n limit: number;\n};\n\nexport type StatusFlags = {\n session?: string;\n};\n\nexport function parseOutputFormat(value: string): OutputFormat {\n if (!OUTPUT_FORMATS.includes(value as OutputFormat)) {\n throw new InvalidArgumentError(\n `Invalid format \"${value}\". Expected one of: ${OUTPUT_FORMATS.join(\", \")}`,\n );\n }\n return value as OutputFormat;\n}\n\nexport function parseAuthPolicy(value: string): AuthPolicy {\n if (!AUTH_POLICIES.includes(value as AuthPolicy)) {\n throw new InvalidArgumentError(\n `Invalid auth policy \"${value}\". Expected one of: ${AUTH_POLICIES.join(\", \")}`,\n );\n }\n return value as AuthPolicy;\n}\n\nexport function parseNonInteractivePermissionPolicy(value: string): NonInteractivePermissionPolicy {\n if (!NON_INTERACTIVE_PERMISSION_POLICIES.includes(value as NonInteractivePermissionPolicy)) {\n throw new InvalidArgumentError(\n `Invalid non-interactive permission policy \"${value}\". Expected one of: ${NON_INTERACTIVE_PERMISSION_POLICIES.join(\", \")}`,\n );\n }\n return value as NonInteractivePermissionPolicy;\n}\n\nexport function parseTimeoutSeconds(value: string): number {\n const parsed = Number(value);\n if (!Number.isFinite(parsed) || parsed <= 0) {\n throw new InvalidArgumentError(\"Timeout must be a positive number of seconds\");\n }\n return Math.round(parsed * 1000);\n}\n\nexport function parseTtlSeconds(value: string): number {\n const parsed = Number(value);\n if (!Number.isFinite(parsed) || parsed < 0) {\n throw new InvalidArgumentError(\"TTL must be a non-negative number of seconds\");\n }\n return Math.round(parsed * 1000);\n}\n\nexport function parseSessionName(value: string): string {\n const trimmed = value.trim();\n if (trimmed.length === 0) {\n throw new InvalidArgumentError(\"Session name must not be empty\");\n }\n return trimmed;\n}\n\nexport function parseNonEmptyValue(label: string, value: string): string {\n const trimmed = value.trim();\n if (trimmed.length === 0) {\n throw new InvalidArgumentError(`${label} must not be empty`);\n }\n return trimmed;\n}\n\nexport function parseHistoryLimit(value: string): number {\n const parsed = Number(value);\n if (!Number.isInteger(parsed) || parsed <= 0) {\n throw new InvalidArgumentError(\"Limit must be a positive integer\");\n }\n return parsed;\n}\n\nexport function parseAllowedTools(value: string): string[] {\n const trimmed = value.trim();\n if (trimmed.length === 0) {\n return [];\n }\n\n const items = trimmed.split(\",\").map((item) => item.trim());\n if (items.some((item) => item.length === 0)) {\n throw new InvalidArgumentError(\n \"Allowed tools must be a comma-separated list without empty entries\",\n );\n }\n\n return items;\n}\n\nexport function parseMaxTurns(value: string): number {\n const parsed = Number(value);\n if (!Number.isInteger(parsed) || parsed <= 0) {\n throw new InvalidArgumentError(\"Max turns must be a positive integer\");\n }\n return parsed;\n}\n\nexport function parsePromptRetries(value: string): number {\n const parsed = Number(value);\n if (!Number.isInteger(parsed) || parsed < 0) {\n throw new InvalidArgumentError(\"Prompt retries must be a non-negative integer\");\n }\n return parsed;\n}\n\nexport function resolvePermissionMode(\n flags: PermissionFlags,\n defaultMode: PermissionMode,\n): PermissionMode {\n const selected = [flags.approveAll, flags.approveReads, flags.denyAll].filter(Boolean).length;\n\n if (selected > 1) {\n throw new InvalidArgumentError(\n \"Use only one permission mode: --approve-all, --approve-reads, or --deny-all\",\n );\n }\n\n if (flags.approveAll) {\n return \"approve-all\";\n }\n if (flags.approveReads) {\n return \"approve-reads\";\n }\n if (flags.denyAll) {\n return \"deny-all\";\n }\n\n return defaultMode;\n}\n\nexport function addGlobalFlags(command: Command): Command {\n return command\n .option(\"--agent <command>\", \"Raw ACP agent command (escape hatch)\")\n .option(\"--cwd <dir>\", \"Working directory\", process.cwd())\n .option(\n \"--auth-policy <policy>\",\n \"Authentication policy: skip or fail when auth is required\",\n parseAuthPolicy,\n )\n .option(\"--approve-all\", \"Auto-approve all permission requests\")\n .option(\"--approve-reads\", \"Auto-approve read/search requests and prompt for writes\")\n .option(\"--deny-all\", \"Deny all permission requests\")\n .option(\n \"--non-interactive-permissions <policy>\",\n \"When prompting is unavailable: deny or fail\",\n parseNonInteractivePermissionPolicy,\n )\n .option(\"--format <fmt>\", \"Output format: text, json, quiet\", parseOutputFormat)\n .option(\"--suppress-reads\", \"Suppress raw read-file contents in output\")\n .option(\"--model <id>\", \"Agent model id\")\n .option(\n \"--allowed-tools <list>\",\n 'Allowed tool names as a comma-separated list (use \"\" for no tools)',\n parseAllowedTools,\n )\n .option(\"--max-turns <count>\", \"Maximum turns for the session\", parseMaxTurns)\n .option(\n \"--prompt-retries <count>\",\n \"Retry failed prompt turns on transient errors (default: 0)\",\n parsePromptRetries,\n )\n .option(\n \"--json-strict\",\n \"Strict JSON mode: requires --format json and suppresses non-JSON stderr output\",\n )\n .option(\"--timeout <seconds>\", \"Maximum time to wait for agent response\", parseTimeoutSeconds)\n .option(\n \"--ttl <seconds>\",\n \"Queue owner idle TTL before shutdown (0 = keep alive forever) (default: 300)\",\n parseTtlSeconds,\n )\n .option(\"--verbose\", \"Enable verbose debug logs\");\n}\n\nexport function addSessionOption(command: Command): Command {\n return command\n .option(\"-s, --session <name>\", \"Use named session instead of cwd default\", parseSessionName)\n .option(\n \"--no-wait\",\n \"Queue prompt and return immediately when another prompt is already running\",\n );\n}\n\nexport function addSessionNameOption(command: Command): Command {\n return command.option(\n \"-s, --session <name>\",\n \"Use named session instead of cwd default\",\n parseSessionName,\n );\n}\n\nexport function resolveSessionNameFromFlags(\n flags: StatusFlags,\n command: Command,\n): string | undefined {\n if (flags.session) {\n return flags.session;\n }\n\n // Commander parses options on the parent command when flags appear before the\n // subcommand (e.g. `acpx codex -s foo cancel`). Use optsWithGlobals() so\n // subcommands can still access those values.\n const allOpts = (command as unknown as { optsWithGlobals?: () => unknown }).optsWithGlobals?.();\n if (allOpts && typeof (allOpts as { session?: unknown }).session === \"string\") {\n return parseSessionName((allOpts as { session: string }).session);\n }\n\n const parentOpts = command.parent?.opts?.();\n if (parentOpts && typeof (parentOpts as { session?: unknown }).session === \"string\") {\n return parseSessionName((parentOpts as { session: string }).session);\n }\n\n return undefined;\n}\n\nexport function addPromptInputOption(command: Command): Command {\n return command.option(\"-f, --file <path>\", \"Read prompt text from file path (use - for stdin)\");\n}\n\nexport function resolveGlobalFlags(command: Command, config: ResolvedAcpxConfig): GlobalFlags {\n const opts = command.optsWithGlobals();\n const format = opts.format ?? config.format ?? \"text\";\n const jsonStrict = opts.jsonStrict === true;\n const verbose = opts.verbose === true;\n\n if (jsonStrict && format !== \"json\") {\n throw new InvalidArgumentError(\"--json-strict requires --format json\");\n }\n\n if (jsonStrict && verbose) {\n throw new InvalidArgumentError(\"--json-strict cannot be combined with --verbose\");\n }\n\n return {\n agent: opts.agent,\n cwd: opts.cwd ?? process.cwd(),\n authPolicy: opts.authPolicy ?? config.authPolicy,\n nonInteractivePermissions: opts.nonInteractivePermissions ?? config.nonInteractivePermissions,\n jsonStrict,\n suppressReads: opts.suppressReads === true,\n timeout: opts.timeout ?? config.timeoutMs,\n ttl: opts.ttl ?? config.ttlMs ?? DEFAULT_QUEUE_OWNER_TTL_MS,\n verbose,\n format,\n model: typeof opts.model === \"string\" ? parseNonEmptyValue(\"Model\", opts.model) : undefined,\n allowedTools: Array.isArray(opts.allowedTools) ? opts.allowedTools : undefined,\n maxTurns: typeof opts.maxTurns === \"number\" ? opts.maxTurns : undefined,\n promptRetries: typeof opts.promptRetries === \"number\" ? opts.promptRetries : undefined,\n approveAll: opts.approveAll ? true : undefined,\n approveReads: opts.approveReads ? true : undefined,\n denyAll: opts.denyAll ? true : undefined,\n };\n}\n\nexport function resolveOutputPolicy(format: OutputFormat, jsonStrict: boolean): OutputPolicy {\n return {\n format,\n jsonStrict,\n suppressReads: false,\n suppressNonJsonStderr: jsonStrict,\n queueErrorAlreadyEmitted: format !== \"quiet\",\n suppressSdkConsoleErrors: jsonStrict,\n };\n}\n\nexport function resolveAgentInvocation(\n explicitAgentName: string | undefined,\n globalFlags: GlobalFlags,\n config: ResolvedAcpxConfig,\n): {\n agentName: string;\n agentCommand: string;\n cwd: string;\n} {\n const override = globalFlags.agent?.trim();\n if (override && explicitAgentName) {\n throw new InvalidArgumentError(\"Do not combine positional agent with --agent override\");\n }\n\n const agentName = explicitAgentName ?? config.defaultAgent ?? DEFAULT_AGENT_NAME;\n const agentCommand =\n override && override.length > 0\n ? override\n : resolveAgentCommandFromRegistry(agentName, config.agents);\n\n return {\n agentName,\n agentCommand,\n cwd: path.resolve(globalFlags.cwd),\n };\n}\n"],"mappings":"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"}