@parlor/agent-host 0.0.0-stage → 0.2.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.
- package/LICENSE +21 -0
- package/README.md +16 -2
- package/dist/acp.d.ts +165 -0
- package/dist/acp.d.ts.map +1 -0
- package/dist/acp.js +626 -0
- package/dist/acp.js.map +1 -0
- package/dist/adapter-launch.d.ts +7 -0
- package/dist/adapter-launch.d.ts.map +1 -0
- package/dist/adapter-launch.js +35 -0
- package/dist/adapter-launch.js.map +1 -0
- package/dist/agents.d.ts +32 -0
- package/dist/agents.d.ts.map +1 -0
- package/dist/agents.js +132 -0
- package/dist/agents.js.map +1 -0
- package/dist/assertion.d.ts +9 -0
- package/dist/assertion.d.ts.map +1 -0
- package/dist/assertion.js +22 -0
- package/dist/assertion.js.map +1 -0
- package/dist/control.d.ts +106 -0
- package/dist/control.d.ts.map +1 -0
- package/dist/control.js +32 -0
- package/dist/control.js.map +1 -0
- package/dist/daemon.d.ts +50 -0
- package/dist/daemon.d.ts.map +1 -0
- package/dist/daemon.js +543 -0
- package/dist/daemon.js.map +1 -0
- package/dist/dev-host.d.ts +5 -0
- package/dist/dev-host.d.ts.map +1 -0
- package/dist/dev-host.js +29 -0
- package/dist/dev-host.js.map +1 -0
- package/dist/device-list.d.ts +6 -0
- package/dist/device-list.d.ts.map +1 -0
- package/dist/device-list.js +30 -0
- package/dist/device-list.js.map +1 -0
- package/dist/embedded.d.ts +6 -0
- package/dist/embedded.d.ts.map +1 -0
- package/dist/embedded.js +3 -0
- package/dist/embedded.js.map +1 -0
- package/dist/fold.d.ts +38 -0
- package/dist/fold.d.ts.map +1 -0
- package/dist/fold.js +165 -0
- package/dist/fold.js.map +1 -0
- package/dist/grants.d.ts +54 -0
- package/dist/grants.d.ts.map +1 -0
- package/dist/grants.js +157 -0
- package/dist/grants.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -0
- package/dist/json-file.d.ts +6 -0
- package/dist/json-file.d.ts.map +1 -0
- package/dist/json-file.js +35 -0
- package/dist/json-file.js.map +1 -0
- package/dist/lines.d.ts +5 -0
- package/dist/lines.d.ts.map +1 -0
- package/dist/lines.js +9 -0
- package/dist/lines.js.map +1 -0
- package/dist/link-device.d.ts +28 -0
- package/dist/link-device.d.ts.map +1 -0
- package/dist/link-device.js +40 -0
- package/dist/link-device.js.map +1 -0
- package/dist/link.d.ts +52 -0
- package/dist/link.d.ts.map +1 -0
- package/dist/link.js +277 -0
- package/dist/link.js.map +1 -0
- package/dist/lock.d.ts +7 -0
- package/dist/lock.d.ts.map +1 -0
- package/dist/lock.js +105 -0
- package/dist/lock.js.map +1 -0
- package/dist/log.d.ts +3 -0
- package/dist/log.d.ts.map +1 -0
- package/dist/log.js +18 -0
- package/dist/log.js.map +1 -0
- package/dist/main.d.ts +3 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/main.js +520 -0
- package/dist/main.js.map +1 -0
- package/dist/mcp-proxy.d.ts +33 -0
- package/dist/mcp-proxy.d.ts.map +1 -0
- package/dist/mcp-proxy.js +317 -0
- package/dist/mcp-proxy.js.map +1 -0
- package/dist/naming.d.ts +7 -0
- package/dist/naming.d.ts.map +1 -0
- package/dist/naming.js +42 -0
- package/dist/naming.js.map +1 -0
- package/dist/pairing.d.ts +68 -0
- package/dist/pairing.d.ts.map +1 -0
- package/dist/pairing.js +312 -0
- package/dist/pairing.js.map +1 -0
- package/dist/paths.d.ts +19 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +23 -0
- package/dist/paths.js.map +1 -0
- package/dist/policy.d.ts +37 -0
- package/dist/policy.d.ts.map +1 -0
- package/dist/policy.js +60 -0
- package/dist/policy.js.map +1 -0
- package/dist/pool.d.ts +34 -0
- package/dist/pool.d.ts.map +1 -0
- package/dist/pool.js +112 -0
- package/dist/pool.js.map +1 -0
- package/dist/prompter.d.ts +33 -0
- package/dist/prompter.d.ts.map +1 -0
- package/dist/prompter.js +98 -0
- package/dist/prompter.js.map +1 -0
- package/dist/release-main.d.ts +2 -0
- package/dist/release-main.d.ts.map +1 -0
- package/dist/release-main.js +50 -0
- package/dist/release-main.js.map +1 -0
- package/dist/release.d.ts +22 -0
- package/dist/release.d.ts.map +1 -0
- package/dist/release.js +81 -0
- package/dist/release.js.map +1 -0
- package/dist/revoke.d.ts +10 -0
- package/dist/revoke.d.ts.map +1 -0
- package/dist/revoke.js +23 -0
- package/dist/revoke.js.map +1 -0
- package/dist/self.d.ts +7 -0
- package/dist/self.d.ts.map +1 -0
- package/dist/self.js +10 -0
- package/dist/self.js.map +1 -0
- package/dist/service.d.ts +97 -0
- package/dist/service.d.ts.map +1 -0
- package/dist/service.js +205 -0
- package/dist/service.js.map +1 -0
- package/dist/shell-path.d.ts +10 -0
- package/dist/shell-path.d.ts.map +1 -0
- package/dist/shell-path.js +64 -0
- package/dist/shell-path.js.map +1 -0
- package/dist/skeleton-kit.d.ts +8 -0
- package/dist/skeleton-kit.d.ts.map +1 -0
- package/dist/skeleton-kit.js +143 -0
- package/dist/skeleton-kit.js.map +1 -0
- package/dist/spec-kit.d.ts +102 -0
- package/dist/spec-kit.d.ts.map +1 -0
- package/dist/spec-kit.js +372 -0
- package/dist/spec-kit.js.map +1 -0
- package/dist/testing/fake-agent.d.ts +65 -0
- package/dist/testing/fake-agent.d.ts.map +1 -0
- package/dist/testing/fake-agent.js +238 -0
- package/dist/testing/fake-agent.js.map +1 -0
- package/dist/trust.d.ts +20 -0
- package/dist/trust.d.ts.map +1 -0
- package/dist/trust.js +27 -0
- package/dist/trust.js.map +1 -0
- package/dist/turn.d.ts +32 -0
- package/dist/turn.d.ts.map +1 -0
- package/dist/turn.js +650 -0
- package/dist/turn.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +6 -0
- package/dist/version.js.map +1 -0
- package/package.json +57 -3
package/dist/acp.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"acp.js","sourceRoot":"","sources":["../src/acp.ts"],"names":[],"mappings":"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","sourcesContent":["import { spawn } from \"node:child_process\";\nimport { Readable, Writable } from \"node:stream\";\n\nimport {\n agent as acpAgent,\n client as acpClient,\n type ClientContext,\n type ContentBlock,\n type CreateElicitationRequest,\n type CreateElicitationResponse,\n type McpServer,\n type McpServerStdio,\n type PromptRequest,\n methods,\n ndJsonStream,\n PROTOCOL_VERSION,\n RequestError,\n type RequestPermissionRequest,\n type RequestPermissionResponse,\n type SessionModeState,\n type SessionNotification,\n type SessionUpdate,\n type StopReason as AcpStopReason,\n type Stream,\n type ToolCall,\n type ToolCallUpdate,\n type ToolKind as AcpToolKind,\n} from \"@agentclientprotocol/sdk\";\n\nimport { commandOf, launchEnvironment } from \"./adapter-launch.js\";\nimport type { AgentProfile } from \"./agents.js\";\nimport { logEvent } from \"./log.js\";\n\n/**\n * The only file that knows ACP. The v1 adapter speaks ndjson over stdio through\n * `@agentclientprotocol/sdk`; an ACP v2 or HTTP-transport agent implements the same\n * port. No ACP type crosses this file.\n */\nexport interface AgentLauncher {\n /** Spawns the profile (never through a shell), runs `initialize`, reports problems. */\n launch(profile: AgentProfile, options: LaunchOptions): Promise<AgentConnection>;\n}\n\nexport interface LaunchOptions {\n readonly cwd: string;\n readonly env: Readonly<Record<string, string>>;\n readonly signal: AbortSignal;\n}\n\nexport interface AgentConnection {\n readonly capabilities: AgentCapabilities;\n openSession(input: OpenSessionInput): Promise<AgentSession>;\n readonly exited: Promise<AgentExit>;\n /** Kills the whole process group. */\n kill(): Promise<void>;\n}\n\n/** `openSession` would not run the session; `leftOpen` when the agent still holds it. */\nexport class SessionRefused extends Error {\n override readonly name = \"SessionRefused\";\n constructor(\n message: string,\n readonly leftOpen: boolean,\n options?: ErrorOptions,\n ) {\n super(message, options);\n }\n}\n\nexport interface AgentCapabilities {\n readonly resume: boolean;\n readonly close: boolean;\n readonly mcpHttp: boolean;\n /** False until the user logs the agent in on a terminal; `problem` says how. */\n readonly ready: boolean;\n readonly problem?: string | undefined;\n}\n\nexport interface OpenSessionInput {\n readonly cwd: string;\n readonly mcpServers: readonly StdioMcpServer[];\n readonly resume?: string | undefined;\n /** A remote turn never runs in a bypass mode. */\n readonly pinAskMode: boolean;\n readonly strictAsk?: boolean | undefined;\n}\n\nexport interface StdioMcpServer {\n readonly name: string;\n readonly command: string;\n readonly args: readonly string[];\n readonly env: Readonly<Record<string, string>>;\n}\n\nexport interface AgentSession {\n readonly id: string;\n readonly resumed: boolean;\n /**\n * Every update reaches `handlers.update` synchronously and in wire order, and the\n * promise settles only after the last one: the stop is queued behind its chunks.\n */\n prompt(blocks: readonly PromptBlock[], handlers: TurnHandlers): Promise<StopReason>;\n cancel(): Promise<void>;\n close(): Promise<void>;\n}\n\nexport type PromptBlock = { readonly kind: \"text\"; readonly text: string };\n\nexport type StopReason =\n | \"end_turn\"\n | \"max_tokens\"\n | \"max_turn_requests\"\n | \"refusal\"\n | \"cancelled\";\n\nexport interface TurnHandlers {\n update(update: AgentUpdate): void;\n ask(ask: AgentAsk): Promise<AgentAskAnswer>;\n}\n\nexport type ToolKind =\n | \"read\"\n | \"edit\"\n | \"delete\"\n | \"move\"\n | \"search\"\n | \"execute\"\n | \"think\"\n | \"fetch\"\n | \"switch_mode\"\n | \"other\";\n\nexport interface McpToolRef {\n readonly server: string;\n readonly tool: string;\n}\n\nexport type AgentUpdate =\n | { readonly kind: \"text\"; readonly text: string }\n | { readonly kind: \"thought\"; readonly text: string }\n | {\n readonly kind: \"tool_start\";\n readonly toolCallId: string;\n readonly title: string;\n readonly toolKind: ToolKind;\n readonly mcp?: McpToolRef | undefined;\n }\n | {\n readonly kind: \"tool_update\";\n readonly toolCallId: string;\n readonly title?: string | undefined;\n readonly status?: \"pending\" | \"in_progress\" | \"completed\" | \"failed\" | undefined;\n readonly detail?: string | undefined;\n }\n | {\n readonly kind: \"plan\";\n readonly entries: readonly {\n readonly content: string;\n readonly status: \"pending\" | \"in_progress\" | \"completed\";\n }[];\n }\n | { readonly kind: \"mode\"; readonly modeId: string };\n\nexport type AskEffect = \"allow_once\" | \"allow_always\" | \"reject_once\" | \"reject_always\";\n\nexport type AgentAsk =\n | {\n readonly kind: \"permission\";\n readonly toolCallId: string;\n readonly title: string;\n readonly toolKind: ToolKind;\n readonly mcp?: McpToolRef | undefined;\n readonly options: readonly {\n readonly id: string;\n readonly label: string;\n readonly effect: AskEffect;\n }[];\n }\n | {\n readonly kind: \"question\";\n readonly message: string;\n readonly schema: Readonly<Record<string, unknown>>;\n };\n\nexport type AgentAskAnswer =\n | { readonly kind: \"selected\"; readonly optionId: string }\n | {\n readonly kind: \"values\";\n readonly values: Readonly<Record<string, string | number | boolean>>;\n }\n | { readonly kind: \"declined\" }\n | { readonly kind: \"cancelled\" };\n\nexport type AgentExit =\n | { readonly kind: \"killed\" }\n | {\n readonly kind: \"exited\";\n readonly code: number | null;\n readonly stderrTail: string;\n };\n\n/** The bytes an ACP peer reads and writes: a child's stdio, or a test's pipe. */\nexport interface AcpStdio {\n readonly input: ReadableStream<Uint8Array>;\n readonly output: WritableStream<Uint8Array>;\n}\n\nexport interface AgentModes {\n readonly current: string;\n readonly available: readonly string[];\n}\n\n/** The agent side of ACP in this file's own terms, for the fake agent. */\nexport interface AcpAgentHandlers {\n readonly capabilities: Pick<AgentCapabilities, \"resume\" | \"close\" | \"mcpHttp\">;\n newSession(\n input: OpenSessionInput,\n ): Promise<{ readonly id: string; readonly modes?: AgentModes | undefined }>;\n prompt(\n sessionId: string,\n blocks: readonly PromptBlock[],\n peer: {\n update(update: AgentUpdate): Promise<void>;\n ask(ask: AgentAsk): Promise<AgentAskAnswer>;\n readonly cancelled: AbortSignal;\n },\n ): Promise<StopReason>;\n}\n\nconst STDERR_TAIL_BYTES = 4_096;\nconst KILL_GRACE_MS = 2_000;\nconst MAX_DETAIL_CHARS = 4_000;\nconst AUTH_REQUIRED = -32000;\nconst MCP_PREFIX = \"mcp__\";\n\nconst ASK_MODES_BY_PREFERENCE = [\"default\", \"workspace-write\", \"read-only\"];\nconst STRICT_ASK_MODES_BY_PREFERENCE = [\"default\", \"read-only\", \"workspace-write\"];\n\ntype Fields = Readonly<Record<string, unknown>>;\n\nconst isFields = (value: unknown): value is Fields =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nconst TOOL_KINDS: ReadonlySet<string> = new Set<ToolKind>([\n \"read\",\n \"edit\",\n \"delete\",\n \"move\",\n \"search\",\n \"execute\",\n \"think\",\n \"fetch\",\n \"switch_mode\",\n \"other\",\n]);\n\nfunction toolKindOf(kind: AcpToolKind | null | undefined): ToolKind {\n return kind && TOOL_KINDS.has(kind) ? kind : \"other\";\n}\n\nfunction stopReasonOf(reason: AcpStopReason): StopReason {\n return reason;\n}\n\n/**\n * Which MCP server serves a tool call, by the agents' own conventions: Claude Code's\n * `mcp__<server>__<tool>` name, Codex's `mcp.<server>.<tool>` title and raw input.\n */\nfunction mcpRefOf(call: ToolCall | ToolCallUpdate): McpToolRef | undefined {\n const claude = isFields(call._meta?.claudeCode) ? call._meta.claudeCode : undefined;\n const name = typeof claude?.toolName === \"string\" ? claude.toolName : call.name;\n if (name?.startsWith(MCP_PREFIX)) {\n const rest = name.slice(MCP_PREFIX.length);\n const separator = rest.indexOf(\"__\");\n if (separator > 0 && rest.length > separator + 2) {\n return { server: rest.slice(0, separator), tool: rest.slice(separator + 2) };\n }\n }\n const raw = call.rawInput;\n if (\n call.title?.startsWith(\"mcp.\") &&\n isFields(raw) &&\n typeof raw.server === \"string\" &&\n typeof raw.tool === \"string\"\n ) {\n return { server: raw.server, tool: raw.tool };\n }\n return undefined;\n}\n\nfunction readableTitle(title: string, mcp: McpToolRef): string {\n const keys = [\n `${MCP_PREFIX}${mcp.server}__${mcp.tool}`,\n `mcp.${mcp.server}.${mcp.tool}`,\n ];\n return keys.includes(title) ? mcp.tool : title;\n}\n\nfunction detailOf(update: ToolCallUpdate): string | undefined {\n const texts = (update.content ?? []).flatMap((content) =>\n content.type === \"content\" && content.content.type === \"text\"\n ? [content.content.text]\n : [],\n );\n const text = texts.length > 0 ? texts.join(\"\\n\") : update.rawOutput;\n return typeof text === \"string\" && text.trim() !== \"\"\n ? text.slice(0, MAX_DETAIL_CHARS)\n : undefined;\n}\n\nfunction textOf(content: ContentBlock): string | undefined {\n return content.type === \"text\" ? content.text : undefined;\n}\n\nfunction updateOf(update: SessionUpdate): AgentUpdate | undefined {\n switch (update.sessionUpdate) {\n case \"agent_message_chunk\": {\n const text = textOf(update.content);\n return text === undefined ? undefined : { kind: \"text\", text };\n }\n case \"agent_thought_chunk\": {\n const text = textOf(update.content);\n return text === undefined ? undefined : { kind: \"thought\", text };\n }\n case \"tool_call\": {\n const mcp = mcpRefOf(update);\n return {\n kind: \"tool_start\",\n toolCallId: update.toolCallId,\n title: mcp ? readableTitle(update.title, mcp) : update.title,\n toolKind: toolKindOf(update.kind),\n mcp,\n };\n }\n case \"tool_call_update\":\n return {\n kind: \"tool_update\",\n toolCallId: update.toolCallId,\n title: update.title ?? undefined,\n status: update.status ?? undefined,\n detail: detailOf(update),\n };\n case \"plan\":\n return {\n kind: \"plan\",\n entries: update.entries.map((entry) => ({\n content: entry.content,\n status: entry.status,\n })),\n };\n case \"current_mode_update\":\n return { kind: \"mode\", modeId: update.currentModeId };\n default:\n return undefined;\n }\n}\n\nfunction sessionUpdateOf(update: AgentUpdate): SessionUpdate {\n switch (update.kind) {\n case \"text\":\n return {\n sessionUpdate: \"agent_message_chunk\",\n content: { type: \"text\", text: update.text },\n };\n case \"thought\":\n return {\n sessionUpdate: \"agent_thought_chunk\",\n content: { type: \"text\", text: update.text },\n };\n case \"tool_start\":\n return {\n sessionUpdate: \"tool_call\",\n toolCallId: update.toolCallId,\n title: update.title,\n kind: update.toolKind,\n status: \"pending\",\n ...(update.mcp ? { _meta: claudeToolName(update.mcp) } : {}),\n };\n case \"tool_update\":\n return {\n sessionUpdate: \"tool_call_update\",\n toolCallId: update.toolCallId,\n ...(update.title !== undefined ? { title: update.title } : {}),\n ...(update.status !== undefined ? { status: update.status } : {}),\n ...(update.detail !== undefined\n ? {\n content: [\n { type: \"content\", content: { type: \"text\", text: update.detail } },\n ],\n }\n : {}),\n };\n case \"plan\":\n return {\n sessionUpdate: \"plan\",\n entries: update.entries.map((entry) => ({ ...entry, priority: \"medium\" })),\n };\n case \"mode\":\n return { sessionUpdate: \"current_mode_update\", currentModeId: update.modeId };\n }\n}\n\nconst claudeToolName = (mcp: McpToolRef) => ({\n claudeCode: { toolName: `${MCP_PREFIX}${mcp.server}__${mcp.tool}` },\n});\n\ninterface KnownCall {\n readonly title?: string | undefined;\n readonly mcp?: McpToolRef | undefined;\n}\n\nfunction commandIn(rawInput: unknown): string | undefined {\n return isFields(rawInput) && typeof rawInput.command === \"string\"\n ? rawInput.command\n : undefined;\n}\n\nfunction permissionQuestion(askedTitle: string, callDetail: string | undefined): string {\n const detail = callDetail?.trim() ?? \"\";\n if (detail === \"\" || askedTitle.includes(detail)) return askedTitle;\n if (askedTitle.trim() === \"\" || detail.includes(askedTitle)) return detail;\n return `${askedTitle}: ${detail}`;\n}\n\nfunction permissionAskOf(\n request: RequestPermissionRequest,\n known: KnownCall | undefined,\n): AgentAsk {\n const call = request.toolCall;\n const mcp = mcpRefOf(call) ?? known?.mcp;\n const title = call.title ?? \"\";\n return {\n kind: \"permission\",\n toolCallId: call.toolCallId,\n title: permissionQuestion(\n mcp ? readableTitle(title, mcp) : title,\n known?.title ?? commandIn(call.rawInput),\n ),\n toolKind: toolKindOf(call.kind),\n mcp,\n options: request.options.map((option) => ({\n id: option.optionId,\n label: option.name,\n effect: option.kind,\n })),\n };\n}\n\nfunction permissionAnswerOf(\n request: RequestPermissionRequest,\n answer: AgentAskAnswer,\n): RequestPermissionResponse {\n const selected = (optionId: string) => ({\n outcome: { outcome: \"selected\" as const, optionId },\n });\n if (answer.kind === \"selected\") return selected(answer.optionId);\n if (answer.kind === \"declined\") {\n const reject =\n request.options.find((option) => option.kind === \"reject_once\") ??\n request.options.find((option) => option.kind === \"reject_always\");\n if (reject) return selected(reject.optionId);\n }\n return { outcome: { outcome: \"cancelled\" } };\n}\n\nfunction elicitationAnswerOf(answer: AgentAskAnswer): CreateElicitationResponse {\n switch (answer.kind) {\n case \"values\":\n return { action: \"accept\", content: { ...answer.values } };\n case \"selected\":\n return { action: \"accept\", content: {} };\n case \"declined\":\n return { action: \"decline\" };\n case \"cancelled\":\n return { action: \"cancel\" };\n }\n}\n\nfunction stdioServerOf(server: StdioMcpServer): McpServerStdio {\n return {\n name: server.name,\n command: server.command,\n args: [...server.args],\n env: Object.entries(server.env).map(([name, value]) => ({ name, value })),\n };\n}\n\nfunction stdioServersOf(servers: readonly McpServer[] | undefined): StdioMcpServer[] {\n return (servers ?? []).flatMap((server) =>\n \"command\" in server\n ? [\n {\n name: server.name,\n command: server.command,\n args: server.args,\n env: Object.fromEntries(server.env.map((entry) => [entry.name, entry.value])),\n },\n ]\n : [],\n );\n}\n\n/** Takes `session/update` off the wire in order, before the SDK sees the reply after it. */\nfunction tapUpdates(\n stream: Stream,\n deliver: (notification: SessionNotification) => void,\n): Stream {\n return {\n writable: stream.writable,\n readable: stream.readable.pipeThrough(\n new TransformStream({\n transform(message, controller) {\n const fields: unknown = message;\n if (\n isFields(fields) &&\n fields.method === methods.client.session.update &&\n !(\"id\" in fields)\n ) {\n deliver(fields.params as SessionNotification);\n return;\n }\n controller.enqueue(message);\n },\n }),\n ),\n };\n}\n\nfunction tapSends(stream: Stream): Stream {\n const writer = stream.writable.getWriter();\n return {\n readable: stream.readable,\n writable: new WritableStream({\n write(message) {\n const fields: unknown = message;\n if (isFields(fields) && typeof fields.method === \"string\") {\n logEvent(\"acp_send\", { method: fields.method });\n }\n return writer.write(message);\n },\n close: () => writer.close(),\n abort: (reason) => writer.abort(reason),\n }),\n };\n}\n\ninterface LiveState {\n handlers: TurnHandlers | undefined;\n readonly calls: Map<string, KnownCall>;\n readonly pinned: string | undefined;\n}\n\nfunction askingModeOf(modes: SessionModeState, strict: boolean): string | undefined {\n const available = new Set(modes.availableModes.map((mode) => mode.id));\n if (strict) {\n available.add(modes.currentModeId);\n return STRICT_ASK_MODES_BY_PREFERENCE.find((mode) => available.has(mode));\n }\n if (ASK_MODES_BY_PREFERENCE.includes(modes.currentModeId)) return modes.currentModeId;\n return ASK_MODES_BY_PREFERENCE.find((mode) => available.has(mode));\n}\n\nfunction sessionModesOf(modes: AgentModes | undefined): SessionModeState | undefined {\n return modes\n ? {\n currentModeId: modes.current,\n availableModes: modes.available.map((id) => ({ id, name: id })),\n }\n : undefined;\n}\n\nfunction signalExit(pid: number | undefined, signal: NodeJS.Signals) {\n if (pid === undefined) return;\n try {\n process.kill(-pid, signal);\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"ESRCH\") throw error;\n }\n}\n\n/** ACP v1 over stdio. */\nexport function acpLauncher(): AgentLauncher {\n return {\n launch: async (profile, options) => {\n const { command, args } = commandOf(profile);\n const child = spawn(command, [...args], {\n cwd: options.cwd,\n env: await launchEnvironment(profile, options.env),\n detached: true,\n shell: false,\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n });\n let stderr = \"\";\n child.stderr.setEncoding(\"utf8\");\n child.stderr.on(\"data\", (chunk: string) => {\n stderr = (stderr + chunk).slice(-STDERR_TAIL_BYTES);\n });\n let killing = false;\n const exited = new Promise<AgentExit>((resolve) => {\n child.once(\"error\", (error) =>\n resolve({\n kind: \"exited\",\n code: null,\n stderrTail: `${stderr}${error.message}`,\n }),\n );\n child.once(\"exit\", (code) =>\n resolve(\n killing ? { kind: \"killed\" } : { kind: \"exited\", code, stderrTail: stderr },\n ),\n );\n });\n const kill = async () => {\n if (child.exitCode !== null || child.signalCode !== null) return;\n killing = true;\n signalExit(child.pid, \"SIGTERM\");\n const force = setTimeout(() => signalExit(child.pid, \"SIGKILL\"), KILL_GRACE_MS);\n await exited;\n clearTimeout(force);\n };\n if (options.signal.aborted) void kill();\n options.signal.addEventListener(\"abort\", () => void kill(), { once: true });\n\n const sessions = new Map<string, LiveState>();\n const deliver = (notification: SessionNotification) => {\n const state = sessions.get(notification.sessionId);\n if (!state) return;\n const { update } = notification;\n const mapped = updateOf(update);\n if (!mapped) return;\n if (mapped.kind === \"tool_start\") {\n state.calls.set(mapped.toolCallId, { title: mapped.title, mcp: mapped.mcp });\n } else if (mapped.kind === \"tool_update\" && mapped.title) {\n const known = state.calls.get(mapped.toolCallId);\n state.calls.set(mapped.toolCallId, { ...known, title: mapped.title });\n }\n if (mapped.kind === \"mode\" && state.pinned && mapped.modeId !== state.pinned) {\n void context\n .request(methods.agent.session.setMode, {\n sessionId: notification.sessionId,\n modeId: state.pinned,\n })\n .catch(() => undefined);\n }\n state.handlers?.update(mapped);\n };\n const stream = tapUpdates(\n tapSends(\n ndJsonStream(\n Writable.toWeb(child.stdin) as WritableStream<Uint8Array>,\n Readable.toWeb(child.stdout) as ReadableStream<Uint8Array>,\n ),\n ),\n deliver,\n );\n const ask = async (sessionId: string | undefined, question: AgentAsk) => {\n const handlers =\n sessionId === undefined ? undefined : sessions.get(sessionId)?.handlers;\n return handlers ? handlers.ask(question) : ({ kind: \"cancelled\" } as const);\n };\n const connection = acpClient({ name: \"parlor-host\" })\n .onRequest(methods.client.session.requestPermission, async ({ params }) => {\n const known = sessions\n .get(params.sessionId)\n ?.calls.get(params.toolCall.toolCallId);\n const answer = await ask(params.sessionId, permissionAskOf(params, known));\n return permissionAnswerOf(params, answer);\n })\n .onRequest(\n methods.client.elicitation.create,\n async ({ params }: { params: CreateElicitationRequest }) => {\n if (params.mode !== \"form\") return { action: \"cancel\" };\n const sessionId =\n \"sessionId\" in params && typeof params.sessionId === \"string\"\n ? params.sessionId\n : undefined;\n const schema = isFields(params.requestedSchema) ? params.requestedSchema : {};\n const answer = await ask(sessionId, {\n kind: \"question\",\n message: params.message,\n schema,\n });\n return elicitationAnswerOf(answer);\n },\n )\n .connect(stream);\n const context: ClientContext = connection.agent;\n exited.then(\n () => connection.close(),\n () => undefined,\n );\n\n let initialized;\n try {\n initialized = await context.request(methods.agent.initialize, {\n protocolVersion: PROTOCOL_VERSION,\n clientCapabilities: { elicitation: { form: {} } },\n clientInfo: { name: \"parlor-host\", version: \"0.0.0\" },\n });\n } catch (error) {\n await kill();\n const exit = await exited;\n const why =\n exit.kind === \"exited\" && exit.stderrTail ? `: ${exit.stderrTail.trim()}` : \"\";\n throw new Error(`${profile.name} did not start${why}`, { cause: error });\n }\n const agentCapabilities = initialized.agentCapabilities ?? {};\n const capabilities: AgentCapabilities = {\n resume: Boolean(agentCapabilities.sessionCapabilities?.resume),\n close: Boolean(agentCapabilities.sessionCapabilities?.close),\n mcpHttp: agentCapabilities.mcpCapabilities?.http === true,\n ready: true,\n };\n\n const loginProblem = (error: unknown) =>\n error instanceof RequestError && error.code === AUTH_REQUIRED\n ? new Error(\n `${profile.name} is not logged in on this computer: run \\`${profile.binary}\\` in a terminal to log in.`,\n { cause: error },\n )\n : error;\n\n const open = async (input: OpenSessionInput) => {\n const mcpServers = input.mcpServers.map(stdioServerOf);\n if (input.resume && capabilities.resume) {\n try {\n const resumed = await context.request(methods.agent.session.resume, {\n sessionId: input.resume,\n cwd: input.cwd,\n mcpServers,\n });\n return { id: input.resume, modes: resumed.modes, resumed: true };\n } catch {}\n }\n const created = await context.request(methods.agent.session.new, {\n cwd: input.cwd,\n mcpServers,\n });\n return { id: created.sessionId, modes: created.modes, resumed: false };\n };\n\n return {\n capabilities,\n exited,\n kill,\n openSession: async (input) => {\n let opened;\n try {\n opened = await open(input);\n } catch (error) {\n throw loginProblem(error);\n }\n const sessionId = opened.id;\n const close = async (): Promise<boolean> => {\n sessions.delete(sessionId);\n if (!capabilities.close) return false;\n return context.request(methods.agent.session.close, { sessionId }).then(\n () => true,\n () => false,\n );\n };\n const modes = input.pinAskMode ? opened.modes : undefined;\n const pinned = modes\n ? askingModeOf(modes, input.strictAsk === true)\n : undefined;\n if (modes && pinned === undefined) {\n throw new SessionRefused(\n `${profile.name} offers no mode that asks before it acts, so it cannot take a turn from an app.`,\n !(await close()),\n );\n }\n const state: LiveState = { handlers: undefined, calls: new Map(), pinned };\n sessions.set(sessionId, state);\n if (pinned !== undefined && pinned !== modes?.currentModeId) {\n try {\n await context.request(methods.agent.session.setMode, {\n sessionId,\n modeId: pinned,\n });\n } catch (error) {\n throw new SessionRefused(\n `${profile.name} did not switch to a mode that asks before it acts.`,\n !(await close()),\n { cause: error },\n );\n }\n }\n const session: AgentSession = {\n id: sessionId,\n resumed: opened.resumed,\n prompt: async (blocks, handlers) => {\n if (state.handlers)\n throw new Error(\"This session is already answering a prompt.\");\n state.handlers = handlers;\n try {\n const request: PromptRequest = {\n sessionId,\n prompt: blocks.map((block) => ({ type: \"text\", text: block.text })),\n };\n const response = await context.request(\n methods.agent.session.prompt,\n request,\n );\n return stopReasonOf(response.stopReason);\n } finally {\n state.handlers = undefined;\n }\n },\n cancel: () =>\n context\n .notify(methods.agent.session.cancel, { sessionId })\n .catch(() => undefined),\n close: async () => {\n await close();\n },\n };\n return session;\n },\n };\n },\n };\n}\n\n/** Serves `handlers` as an ACP agent on `io`, until the other side hangs up. */\nexport function serveAcpAgent(handlers: AcpAgentHandlers, io: AcpStdio): Promise<void> {\n const running = new Map<string, AbortController>();\n const aliases = new Map<string, string>();\n const idOf = (sessionId: string) => aliases.get(sessionId) ?? sessionId;\n const app = acpAgent({ name: \"parlor-fake-agent\" })\n .onRequest(methods.agent.initialize, () => ({\n protocolVersion: PROTOCOL_VERSION,\n agentCapabilities: {\n loadSession: false,\n mcpCapabilities: { http: handlers.capabilities.mcpHttp, sse: false },\n sessionCapabilities: {\n ...(handlers.capabilities.resume ? { resume: {} } : {}),\n ...(handlers.capabilities.close ? { close: {} } : {}),\n },\n },\n authMethods: [],\n }))\n .onRequest(methods.agent.session.new, async ({ params }) => {\n const { id, modes } = await handlers.newSession({\n cwd: params.cwd,\n mcpServers: stdioServersOf(params.mcpServers),\n pinAskMode: false,\n });\n const state = sessionModesOf(modes);\n return { sessionId: id, ...(state ? { modes: state } : {}) };\n })\n .onRequest(methods.agent.session.resume, async ({ params }) => {\n if (!handlers.capabilities.resume) {\n throw RequestError.methodNotFound(methods.agent.session.resume);\n }\n const { id } = await handlers.newSession({\n cwd: params.cwd,\n mcpServers: stdioServersOf(params.mcpServers),\n pinAskMode: false,\n });\n aliases.set(params.sessionId, id);\n return {};\n })\n .onRequest(methods.agent.session.setMode, () => ({}))\n .onRequest(methods.agent.session.close, () => {\n if (!handlers.capabilities.close) {\n throw RequestError.methodNotFound(methods.agent.session.close);\n }\n return {};\n })\n .onRequest(methods.agent.session.prompt, async ({ params, client }) => {\n const sessionId = params.sessionId;\n const cancelled = new AbortController();\n running.set(sessionId, cancelled);\n try {\n const blocks = params.prompt.flatMap((block): PromptBlock[] =>\n block.type === \"text\" ? [{ kind: \"text\", text: block.text }] : [],\n );\n const stopReason = await handlers.prompt(idOf(sessionId), blocks, {\n update: (update) =>\n client.notify(methods.client.session.update, {\n sessionId,\n update: sessionUpdateOf(update),\n }),\n ask: async (question) => {\n if (question.kind === \"question\") {\n const answer = await client.request(methods.client.elicitation.create, {\n sessionId,\n mode: \"form\",\n message: question.message,\n requestedSchema: question.schema as never,\n });\n if (answer.action === \"accept\") {\n const content = isFields(answer.content) ? answer.content : {};\n return { kind: \"values\", values: content as never };\n }\n return answer.action === \"decline\"\n ? { kind: \"declined\" }\n : { kind: \"cancelled\" };\n }\n const request: RequestPermissionRequest = {\n sessionId,\n toolCall: {\n toolCallId: question.toolCallId,\n title: question.title,\n kind: question.toolKind,\n status: \"pending\",\n ...(question.mcp ? { _meta: claudeToolName(question.mcp) } : {}),\n },\n options: question.options.map((option) => ({\n optionId: option.id,\n name: option.label,\n kind: option.effect,\n })),\n };\n const answer = await client.request(\n methods.client.session.requestPermission,\n request,\n );\n return answer.outcome.outcome === \"selected\"\n ? { kind: \"selected\", optionId: answer.outcome.optionId }\n : { kind: \"cancelled\" };\n },\n cancelled: cancelled.signal,\n });\n return { stopReason };\n } finally {\n running.delete(sessionId);\n }\n })\n .onNotification(methods.agent.session.cancel, ({ params }) => {\n running.get(params.sessionId)?.abort();\n });\n return app.connect(ndJsonStream(io.output, io.input)).closed;\n}\n"]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type AgentProfile } from "./agents.js";
|
|
2
|
+
export declare function commandOf(profile: AgentProfile): {
|
|
3
|
+
readonly command: string;
|
|
4
|
+
readonly args: readonly string[];
|
|
5
|
+
};
|
|
6
|
+
export declare function launchEnvironment(profile: AgentProfile, env: Readonly<Record<string, string>>): Promise<Record<string, string>>;
|
|
7
|
+
//# sourceMappingURL=adapter-launch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter-launch.d.ts","sourceRoot":"","sources":["../src/adapter-launch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAKpE,wBAAgB,SAAS,CAAC,OAAO,EAAE,YAAY,GAAG;IAChD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;CAClC,CAoBA;AAED,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,YAAY,EACrB,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GACpC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAQjC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { ADAPTER_BINARY_ENV } from "./agents.js";
|
|
2
|
+
import { adapterKey, embeddedAdapters } from "./embedded.js";
|
|
3
|
+
import { selfInvocation } from "./self.js";
|
|
4
|
+
import { resolveBinary } from "./shell-path.js";
|
|
5
|
+
export function commandOf(profile) {
|
|
6
|
+
if (profile.launch.kind === "native") {
|
|
7
|
+
return { command: profile.launch.command, args: profile.launch.args };
|
|
8
|
+
}
|
|
9
|
+
const embedded = embeddedAdapters.get(adapterKey(profile.launch));
|
|
10
|
+
if (embedded !== undefined) {
|
|
11
|
+
const self = selfInvocation(["adapter", embedded]);
|
|
12
|
+
return {
|
|
13
|
+
command: self.command,
|
|
14
|
+
args: [...self.args, ...(profile.launch.args ?? [])],
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
return {
|
|
18
|
+
command: "npx",
|
|
19
|
+
args: [
|
|
20
|
+
"--yes",
|
|
21
|
+
`${profile.launch.package}@${profile.launch.version}`,
|
|
22
|
+
...(profile.launch.args ?? []),
|
|
23
|
+
],
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
export async function launchEnvironment(profile, env) {
|
|
27
|
+
const variable = profile.launch.kind === "adapter"
|
|
28
|
+
? ADAPTER_BINARY_ENV[profile.launch.package]
|
|
29
|
+
: undefined;
|
|
30
|
+
if (variable === undefined || env[variable] !== undefined)
|
|
31
|
+
return { ...env };
|
|
32
|
+
const found = await resolveBinary(profile.binary, env.PATH ?? "");
|
|
33
|
+
return found === undefined ? { ...env } : { ...env, [variable]: found };
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=adapter-launch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter-launch.js","sourceRoot":"","sources":["../src/adapter-launch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAqB,MAAM,aAAa,CAAC;AACpE,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD,MAAM,UAAU,SAAS,CAAC,OAAqB;IAI7C,IAAI,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QACrC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;IACxE,CAAC;IACD,MAAM,QAAQ,GAAG,gBAAgB,CAAC,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;IAClE,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,MAAM,IAAI,GAAG,cAAc,CAAC,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAC;QACnD,OAAO;YACL,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;SACrD,CAAC;IACJ,CAAC;IACD,OAAO;QACL,OAAO,EAAE,KAAK;QACd,IAAI,EAAE;YACJ,OAAO;YACP,GAAG,OAAO,CAAC,MAAM,CAAC,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE;YACrD,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;SAC/B;KACF,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,OAAqB,EACrB,GAAqC;IAErC,MAAM,QAAQ,GACZ,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,SAAS;QAC/B,CAAC,CAAC,kBAAkB,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC;QAC5C,CAAC,CAAC,SAAS,CAAC;IAChB,IAAI,QAAQ,KAAK,SAAS,IAAI,GAAG,CAAC,QAAQ,CAAC,KAAK,SAAS;QAAE,OAAO,EAAE,GAAG,GAAG,EAAE,CAAC;IAC7E,MAAM,KAAK,GAAG,MAAM,aAAa,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;IAClE,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,CAAC;AAC1E,CAAC","sourcesContent":["import { ADAPTER_BINARY_ENV, type AgentProfile } from \"./agents.js\";\nimport { adapterKey, embeddedAdapters } from \"./embedded.js\";\nimport { selfInvocation } from \"./self.js\";\nimport { resolveBinary } from \"./shell-path.js\";\n\nexport function commandOf(profile: AgentProfile): {\n readonly command: string;\n readonly args: readonly string[];\n} {\n if (profile.launch.kind === \"native\") {\n return { command: profile.launch.command, args: profile.launch.args };\n }\n const embedded = embeddedAdapters.get(adapterKey(profile.launch));\n if (embedded !== undefined) {\n const self = selfInvocation([\"adapter\", embedded]);\n return {\n command: self.command,\n args: [...self.args, ...(profile.launch.args ?? [])],\n };\n }\n return {\n command: \"npx\",\n args: [\n \"--yes\",\n `${profile.launch.package}@${profile.launch.version}`,\n ...(profile.launch.args ?? []),\n ],\n };\n}\n\nexport async function launchEnvironment(\n profile: AgentProfile,\n env: Readonly<Record<string, string>>,\n): Promise<Record<string, string>> {\n const variable =\n profile.launch.kind === \"adapter\"\n ? ADAPTER_BINARY_ENV[profile.launch.package]\n : undefined;\n if (variable === undefined || env[variable] !== undefined) return { ...env };\n const found = await resolveBinary(profile.binary, env.PATH ?? \"\");\n return found === undefined ? { ...env } : { ...env, [variable]: found };\n}\n"]}
|
package/dist/agents.d.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { AgentInfo } from "@parlor/chat";
|
|
2
|
+
/** The app picks an agent by `id` only, never by command, so no remote party chooses what runs. */
|
|
3
|
+
export interface AgentProfile {
|
|
4
|
+
readonly id: string;
|
|
5
|
+
readonly name: string;
|
|
6
|
+
readonly launch: AgentLaunch;
|
|
7
|
+
/** The CLI behind it, for the installed-and-logged-in check. */
|
|
8
|
+
readonly binary: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* `adapter`: an npm ACP adapter at an exact version, run from the copy this build embeds
|
|
12
|
+
* and else through `npx`. `native`: an agent CLI that speaks ACP itself, found on the login-shell PATH.
|
|
13
|
+
*/
|
|
14
|
+
export type AgentLaunch = {
|
|
15
|
+
readonly kind: "adapter";
|
|
16
|
+
readonly package: string;
|
|
17
|
+
readonly version: string;
|
|
18
|
+
readonly args?: readonly string[] | undefined;
|
|
19
|
+
} | {
|
|
20
|
+
readonly kind: "native";
|
|
21
|
+
readonly command: string;
|
|
22
|
+
readonly args: readonly string[];
|
|
23
|
+
};
|
|
24
|
+
export declare const AGENT_PROFILES: readonly AgentProfile[];
|
|
25
|
+
/** Where each adapter looks for the agent CLI it drives; its own search does not survive a single executable. */
|
|
26
|
+
export declare const ADAPTER_BINARY_ENV: Readonly<Record<string, string>>;
|
|
27
|
+
export declare const DETECT_TIMEOUT_MS = 3000;
|
|
28
|
+
/** Built-ins plus the user's own `agents.json`, which only this computer's user edits. */
|
|
29
|
+
export declare function loadProfiles(file: string): Promise<readonly AgentProfile[]>;
|
|
30
|
+
/** What `hostReport` sends: the installed agents; one that is not installed is left out. */
|
|
31
|
+
export declare function detectAgents(profiles: readonly AgentProfile[]): Promise<AgentInfo[]>;
|
|
32
|
+
//# sourceMappingURL=agents.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../src/agents.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAI9C,mGAAmG;AACnG,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,gEAAgE;IAChE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED;;;GAGG;AACH,MAAM,MAAM,WAAW,GACnB;IACE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;CAC/C,GACD;IACE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;CAClC,CAAC;AAEN,eAAO,MAAM,cAAc,EAAE,SAAS,YAAY,EA2BjD,CAAC;AAEF,iHAAiH;AACjH,eAAO,MAAM,kBAAkB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAG/D,CAAC;AAEF,eAAO,MAAM,iBAAiB,OAAQ,CAAC;AA4CvC,0FAA0F;AAC1F,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,YAAY,EAAE,CAAC,CAkBjF;AAkBD,4FAA4F;AAC5F,wBAAsB,YAAY,CAChC,QAAQ,EAAE,SAAS,YAAY,EAAE,GAChC,OAAO,CAAC,SAAS,EAAE,CAAC,CAwBtB"}
|
package/dist/agents.js
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
import { readFile } from "node:fs/promises";
|
|
3
|
+
import { agentPath } from "./shell-path.js";
|
|
4
|
+
export const AGENT_PROFILES = [
|
|
5
|
+
{
|
|
6
|
+
id: "claude",
|
|
7
|
+
name: "Claude Code",
|
|
8
|
+
launch: {
|
|
9
|
+
kind: "adapter",
|
|
10
|
+
package: "@agentclientprotocol/claude-agent-acp",
|
|
11
|
+
version: "0.93.0",
|
|
12
|
+
},
|
|
13
|
+
binary: "claude",
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
id: "codex",
|
|
17
|
+
name: "Codex",
|
|
18
|
+
launch: {
|
|
19
|
+
kind: "adapter",
|
|
20
|
+
package: "@agentclientprotocol/codex-acp",
|
|
21
|
+
version: "2.2.2",
|
|
22
|
+
},
|
|
23
|
+
binary: "codex",
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
id: "gemini",
|
|
27
|
+
name: "Gemini CLI",
|
|
28
|
+
launch: { kind: "native", command: "gemini", args: ["--acp"] },
|
|
29
|
+
binary: "gemini",
|
|
30
|
+
},
|
|
31
|
+
];
|
|
32
|
+
/** Where each adapter looks for the agent CLI it drives; its own search does not survive a single executable. */
|
|
33
|
+
export const ADAPTER_BINARY_ENV = {
|
|
34
|
+
"@agentclientprotocol/claude-agent-acp": "CLAUDE_CODE_EXECUTABLE",
|
|
35
|
+
"@agentclientprotocol/codex-acp": "CODEX_PATH",
|
|
36
|
+
};
|
|
37
|
+
export const DETECT_TIMEOUT_MS = 3_000;
|
|
38
|
+
const isFields = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
39
|
+
const isStrings = (value) => Array.isArray(value) && value.every((entry) => typeof entry === "string");
|
|
40
|
+
function launchOf(value) {
|
|
41
|
+
if (!isFields(value))
|
|
42
|
+
return undefined;
|
|
43
|
+
if (value.kind === "native" &&
|
|
44
|
+
typeof value.command === "string" &&
|
|
45
|
+
isStrings(value.args)) {
|
|
46
|
+
return { kind: "native", command: value.command, args: value.args };
|
|
47
|
+
}
|
|
48
|
+
if (value.kind === "adapter" &&
|
|
49
|
+
typeof value.package === "string" &&
|
|
50
|
+
typeof value.version === "string" &&
|
|
51
|
+
(value.args === undefined || isStrings(value.args))) {
|
|
52
|
+
return {
|
|
53
|
+
kind: "adapter",
|
|
54
|
+
package: value.package,
|
|
55
|
+
version: value.version,
|
|
56
|
+
args: value.args,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
return undefined;
|
|
60
|
+
}
|
|
61
|
+
function profileOf(value) {
|
|
62
|
+
if (!isFields(value))
|
|
63
|
+
return undefined;
|
|
64
|
+
const launch = launchOf(value.launch);
|
|
65
|
+
const { id, name, binary } = value;
|
|
66
|
+
if (!launch || typeof id !== "string" || typeof name !== "string")
|
|
67
|
+
return undefined;
|
|
68
|
+
if (typeof binary !== "string" || id === "")
|
|
69
|
+
return undefined;
|
|
70
|
+
return { id, name, launch, binary };
|
|
71
|
+
}
|
|
72
|
+
/** Built-ins plus the user's own `agents.json`, which only this computer's user edits. */
|
|
73
|
+
export async function loadProfiles(file) {
|
|
74
|
+
let text;
|
|
75
|
+
try {
|
|
76
|
+
text = await readFile(file, "utf8");
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
if (error.code === "ENOENT")
|
|
80
|
+
return AGENT_PROFILES;
|
|
81
|
+
throw error;
|
|
82
|
+
}
|
|
83
|
+
const listed = JSON.parse(text);
|
|
84
|
+
if (!Array.isArray(listed))
|
|
85
|
+
throw new Error(`${file} must hold a JSON array of agent profiles.`);
|
|
86
|
+
const own = listed.map((entry, at) => {
|
|
87
|
+
const profile = profileOf(entry);
|
|
88
|
+
if (!profile)
|
|
89
|
+
throw new Error(`${file}: entry ${at + 1} is not an agent profile.`);
|
|
90
|
+
return profile;
|
|
91
|
+
});
|
|
92
|
+
const ids = new Set(own.map((profile) => profile.id));
|
|
93
|
+
return [...AGENT_PROFILES.filter((profile) => !ids.has(profile.id)), ...own];
|
|
94
|
+
}
|
|
95
|
+
function versionOf(binary, path) {
|
|
96
|
+
return new Promise((resolve) => {
|
|
97
|
+
execFile(binary, ["--version"], { timeout: DETECT_TIMEOUT_MS, env: { ...process.env, PATH: path } }, (error, stdout) => {
|
|
98
|
+
if (error?.code === "ENOENT")
|
|
99
|
+
resolve("missing");
|
|
100
|
+
else if (error)
|
|
101
|
+
resolve("broken");
|
|
102
|
+
else
|
|
103
|
+
resolve(stdout.trim());
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
/** What `hostReport` sends: the installed agents; one that is not installed is left out. */
|
|
108
|
+
export async function detectAgents(profiles) {
|
|
109
|
+
const path = await agentPath();
|
|
110
|
+
const found = await Promise.all(profiles.map(async (profile) => {
|
|
111
|
+
const output = await versionOf(profile.binary, path);
|
|
112
|
+
if (output === "missing")
|
|
113
|
+
return undefined;
|
|
114
|
+
if (output === "broken") {
|
|
115
|
+
return {
|
|
116
|
+
id: profile.id,
|
|
117
|
+
name: profile.name,
|
|
118
|
+
ready: false,
|
|
119
|
+
problem: `\`${profile.binary} --version\` failed: check that ${profile.name} runs in a terminal.`,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
const version = /\d+\.\d+\.\d+[\w.-]*/.exec(output)?.[0];
|
|
123
|
+
return {
|
|
124
|
+
id: profile.id,
|
|
125
|
+
name: profile.name,
|
|
126
|
+
ready: true,
|
|
127
|
+
...(version ? { version } : {}),
|
|
128
|
+
};
|
|
129
|
+
}));
|
|
130
|
+
return found.filter((agent) => agent !== undefined);
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=agents.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agents.js","sourceRoot":"","sources":["../src/agents.ts"],"names":[],"mappings":"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","sourcesContent":["import { execFile } from \"node:child_process\";\nimport { readFile } from \"node:fs/promises\";\n\nimport type { AgentInfo } from \"@parlor/chat\";\n\nimport { agentPath } from \"./shell-path.js\";\n\n/** The app picks an agent by `id` only, never by command, so no remote party chooses what runs. */\nexport interface AgentProfile {\n readonly id: string;\n readonly name: string;\n readonly launch: AgentLaunch;\n /** The CLI behind it, for the installed-and-logged-in check. */\n readonly binary: string;\n}\n\n/**\n * `adapter`: an npm ACP adapter at an exact version, run from the copy this build embeds\n * and else through `npx`. `native`: an agent CLI that speaks ACP itself, found on the login-shell PATH.\n */\nexport type AgentLaunch =\n | {\n readonly kind: \"adapter\";\n readonly package: string;\n readonly version: string;\n readonly args?: readonly string[] | undefined;\n }\n | {\n readonly kind: \"native\";\n readonly command: string;\n readonly args: readonly string[];\n };\n\nexport const AGENT_PROFILES: readonly AgentProfile[] = [\n {\n id: \"claude\",\n name: \"Claude Code\",\n launch: {\n kind: \"adapter\",\n package: \"@agentclientprotocol/claude-agent-acp\",\n version: \"0.93.0\",\n },\n binary: \"claude\",\n },\n {\n id: \"codex\",\n name: \"Codex\",\n launch: {\n kind: \"adapter\",\n package: \"@agentclientprotocol/codex-acp\",\n version: \"2.2.2\",\n },\n binary: \"codex\",\n },\n {\n id: \"gemini\",\n name: \"Gemini CLI\",\n launch: { kind: \"native\", command: \"gemini\", args: [\"--acp\"] },\n binary: \"gemini\",\n },\n];\n\n/** Where each adapter looks for the agent CLI it drives; its own search does not survive a single executable. */\nexport const ADAPTER_BINARY_ENV: Readonly<Record<string, string>> = {\n \"@agentclientprotocol/claude-agent-acp\": \"CLAUDE_CODE_EXECUTABLE\",\n \"@agentclientprotocol/codex-acp\": \"CODEX_PATH\",\n};\n\nexport const DETECT_TIMEOUT_MS = 3_000;\n\ntype Fields = Readonly<Record<string, unknown>>;\n\nconst isFields = (value: unknown): value is Fields =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nconst isStrings = (value: unknown): value is string[] =>\n Array.isArray(value) && value.every((entry) => typeof entry === \"string\");\n\nfunction launchOf(value: unknown): AgentLaunch | undefined {\n if (!isFields(value)) return undefined;\n if (\n value.kind === \"native\" &&\n typeof value.command === \"string\" &&\n isStrings(value.args)\n ) {\n return { kind: \"native\", command: value.command, args: value.args };\n }\n if (\n value.kind === \"adapter\" &&\n typeof value.package === \"string\" &&\n typeof value.version === \"string\" &&\n (value.args === undefined || isStrings(value.args))\n ) {\n return {\n kind: \"adapter\",\n package: value.package,\n version: value.version,\n args: value.args,\n };\n }\n return undefined;\n}\n\nfunction profileOf(value: unknown): AgentProfile | undefined {\n if (!isFields(value)) return undefined;\n const launch = launchOf(value.launch);\n const { id, name, binary } = value;\n if (!launch || typeof id !== \"string\" || typeof name !== \"string\") return undefined;\n if (typeof binary !== \"string\" || id === \"\") return undefined;\n return { id, name, launch, binary };\n}\n\n/** Built-ins plus the user's own `agents.json`, which only this computer's user edits. */\nexport async function loadProfiles(file: string): Promise<readonly AgentProfile[]> {\n let text: string;\n try {\n text = await readFile(file, \"utf8\");\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === \"ENOENT\") return AGENT_PROFILES;\n throw error;\n }\n const listed: unknown = JSON.parse(text);\n if (!Array.isArray(listed))\n throw new Error(`${file} must hold a JSON array of agent profiles.`);\n const own = listed.map((entry, at) => {\n const profile = profileOf(entry);\n if (!profile) throw new Error(`${file}: entry ${at + 1} is not an agent profile.`);\n return profile;\n });\n const ids = new Set(own.map((profile) => profile.id));\n return [...AGENT_PROFILES.filter((profile) => !ids.has(profile.id)), ...own];\n}\n\nfunction versionOf(binary: string, path: string): Promise<string | \"missing\" | \"broken\"> {\n return new Promise((resolve) => {\n execFile(\n binary,\n [\"--version\"],\n { timeout: DETECT_TIMEOUT_MS, env: { ...process.env, PATH: path } },\n (error, stdout) => {\n if ((error as NodeJS.ErrnoException | null)?.code === \"ENOENT\")\n resolve(\"missing\");\n else if (error) resolve(\"broken\");\n else resolve(stdout.trim());\n },\n );\n });\n}\n\n/** What `hostReport` sends: the installed agents; one that is not installed is left out. */\nexport async function detectAgents(\n profiles: readonly AgentProfile[],\n): Promise<AgentInfo[]> {\n const path = await agentPath();\n const found = await Promise.all(\n profiles.map(async (profile): Promise<AgentInfo | undefined> => {\n const output = await versionOf(profile.binary, path);\n if (output === \"missing\") return undefined;\n if (output === \"broken\") {\n return {\n id: profile.id,\n name: profile.name,\n ready: false,\n problem: `\\`${profile.binary} --version\\` failed: check that ${profile.name} runs in a terminal.`,\n };\n }\n const version = /\\d+\\.\\d+\\.\\d+[\\w.-]*/.exec(output)?.[0];\n return {\n id: profile.id,\n name: profile.name,\n ready: true,\n ...(version ? { version } : {}),\n };\n }),\n );\n return found.filter((agent): agent is AgentInfo => agent !== undefined);\n}\n"]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface AssertionRequest {
|
|
2
|
+
readonly method: "GET" | "POST";
|
|
3
|
+
readonly url: string;
|
|
4
|
+
}
|
|
5
|
+
export declare function hostAssertion(sign: (payload: Uint8Array) => Promise<string>, key: {
|
|
6
|
+
readonly kid: string;
|
|
7
|
+
readonly grantId: string;
|
|
8
|
+
}, request: AssertionRequest, now?: number): Promise<string>;
|
|
9
|
+
//# sourceMappingURL=assertion.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assertion.d.ts","sourceRoot":"","sources":["../src/assertion.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,MAAM,EAAE,KAAK,GAAG,MAAM,CAAC;IAChC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AAED,wBAAsB,aAAa,CACjC,IAAI,EAAE,CAAC,OAAO,EAAE,UAAU,KAAK,OAAO,CAAC,MAAM,CAAC,EAC9C,GAAG,EAAE;IAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,EACvD,OAAO,EAAE,gBAAgB,EACzB,GAAG,GAAE,MAAmB,GACvB,OAAO,CAAC,MAAM,CAAC,CAiBjB"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { HOST_ASSERTION_TTL_MS, HOST_ASSERTION_TYP, HOST_AUDIENCE } from "@parlor/auth";
|
|
3
|
+
const encode = (value) => Buffer.from(JSON.stringify(value)).toString("base64url");
|
|
4
|
+
export async function hostAssertion(sign, key, request, now = Date.now()) {
|
|
5
|
+
const target = new URL(request.url);
|
|
6
|
+
target.search = "";
|
|
7
|
+
target.hash = "";
|
|
8
|
+
const iat = Math.floor(now / 1000);
|
|
9
|
+
const header = encode({ alg: "ES256", typ: HOST_ASSERTION_TYP, kid: key.kid });
|
|
10
|
+
const claims = encode({
|
|
11
|
+
aud: HOST_AUDIENCE,
|
|
12
|
+
gid: key.grantId,
|
|
13
|
+
htm: request.method,
|
|
14
|
+
htu: target.href,
|
|
15
|
+
iat,
|
|
16
|
+
exp: iat + HOST_ASSERTION_TTL_MS / 1000,
|
|
17
|
+
jti: randomUUID(),
|
|
18
|
+
});
|
|
19
|
+
const input = `${header}.${claims}`;
|
|
20
|
+
return `${input}.${await sign(new TextEncoder().encode(input))}`;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=assertion.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assertion.js","sourceRoot":"","sources":["../src/assertion.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAExF,MAAM,MAAM,GAAG,CAAC,KAAc,EAAE,EAAE,CAChC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;AAO3D,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,IAA8C,EAC9C,GAAuD,EACvD,OAAyB,EACzB,GAAG,GAAW,IAAI,CAAC,GAAG,EAAE;IAExB,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACpC,MAAM,CAAC,MAAM,GAAG,EAAE,CAAC;IACnB,MAAM,CAAC,IAAI,GAAG,EAAE,CAAC;IACjB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC;IACnC,MAAM,MAAM,GAAG,MAAM,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,kBAAkB,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC;IAC/E,MAAM,MAAM,GAAG,MAAM,CAAC;QACpB,GAAG,EAAE,aAAa;QAClB,GAAG,EAAE,GAAG,CAAC,OAAO;QAChB,GAAG,EAAE,OAAO,CAAC,MAAM;QACnB,GAAG,EAAE,MAAM,CAAC,IAAI;QAChB,GAAG;QACH,GAAG,EAAE,GAAG,GAAG,qBAAqB,GAAG,IAAI;QACvC,GAAG,EAAE,UAAU,EAAE;KAClB,CAAC,CAAC;IACH,MAAM,KAAK,GAAG,GAAG,MAAM,IAAI,MAAM,EAAE,CAAC;IACpC,OAAO,GAAG,KAAK,IAAI,MAAM,IAAI,CAAC,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;AACnE,CAAC","sourcesContent":["import { randomUUID } from \"node:crypto\";\n\nimport { HOST_ASSERTION_TTL_MS, HOST_ASSERTION_TYP, HOST_AUDIENCE } from \"@parlor/auth\";\n\nconst encode = (value: unknown) =>\n Buffer.from(JSON.stringify(value)).toString(\"base64url\");\n\nexport interface AssertionRequest {\n readonly method: \"GET\" | \"POST\";\n readonly url: string;\n}\n\nexport async function hostAssertion(\n sign: (payload: Uint8Array) => Promise<string>,\n key: { readonly kid: string; readonly grantId: string },\n request: AssertionRequest,\n now: number = Date.now(),\n): Promise<string> {\n const target = new URL(request.url);\n target.search = \"\";\n target.hash = \"\";\n const iat = Math.floor(now / 1000);\n const header = encode({ alg: \"ES256\", typ: HOST_ASSERTION_TYP, kid: key.kid });\n const claims = encode({\n aud: HOST_AUDIENCE,\n gid: key.grantId,\n htm: request.method,\n htu: target.href,\n iat,\n exp: iat + HOST_ASSERTION_TTL_MS / 1000,\n jti: randomUUID(),\n });\n const input = `${header}.${claims}`;\n return `${input}.${await sign(new TextEncoder().encode(input))}`;\n}\n"]}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import type { HostPairing, LocalHostStatus, PairingDevice } from "@parlor/capabilities";
|
|
2
|
+
import type { HostRelease, ServiceClient } from "./service.js";
|
|
3
|
+
export declare const CONTROL_PROTOCOL = 1;
|
|
4
|
+
/**
|
|
5
|
+
* Newline-delimited JSON on a 0600 Unix socket (a named pipe on Windows), spoken by the
|
|
6
|
+
* `parlor-host` CLI and the desktop shell's Rust side. No TCP listener exists.
|
|
7
|
+
*/
|
|
8
|
+
export type ControlRequest = {
|
|
9
|
+
readonly op: "hello";
|
|
10
|
+
readonly client: ServiceClient;
|
|
11
|
+
} | {
|
|
12
|
+
readonly op: "handover";
|
|
13
|
+
readonly binary: string;
|
|
14
|
+
readonly signature: string;
|
|
15
|
+
} | {
|
|
16
|
+
readonly op: "status";
|
|
17
|
+
} | {
|
|
18
|
+
readonly op: "connect";
|
|
19
|
+
readonly appOrigin: string;
|
|
20
|
+
} | {
|
|
21
|
+
readonly op: "begin_local_pairing";
|
|
22
|
+
readonly appOrigin: string;
|
|
23
|
+
} | {
|
|
24
|
+
readonly op: "finish_local_pairing";
|
|
25
|
+
readonly appOrigin: string;
|
|
26
|
+
readonly code: string;
|
|
27
|
+
} | {
|
|
28
|
+
readonly op: "confirm_local_pairing";
|
|
29
|
+
readonly appOrigin: string;
|
|
30
|
+
readonly connect: boolean;
|
|
31
|
+
readonly device?: PairingDevice;
|
|
32
|
+
} | {
|
|
33
|
+
readonly op: "disconnect";
|
|
34
|
+
readonly appOrigin: string;
|
|
35
|
+
} | {
|
|
36
|
+
readonly op: "dev_attach";
|
|
37
|
+
readonly appOrigin: string;
|
|
38
|
+
readonly hostToken: string;
|
|
39
|
+
} | {
|
|
40
|
+
readonly op: "dev_detach";
|
|
41
|
+
readonly appOrigin: string;
|
|
42
|
+
};
|
|
43
|
+
export type ControlOp = ControlRequest["op"];
|
|
44
|
+
export interface GrantSummary {
|
|
45
|
+
readonly appOrigin: string;
|
|
46
|
+
readonly appName: string;
|
|
47
|
+
readonly grantId: string;
|
|
48
|
+
}
|
|
49
|
+
export type ControlFailure = {
|
|
50
|
+
readonly ok: false;
|
|
51
|
+
readonly error: string;
|
|
52
|
+
};
|
|
53
|
+
interface ControlReplies {
|
|
54
|
+
readonly hello: {
|
|
55
|
+
readonly ok: true;
|
|
56
|
+
readonly release: HostRelease;
|
|
57
|
+
};
|
|
58
|
+
readonly handover: {
|
|
59
|
+
readonly ok: true;
|
|
60
|
+
} | {
|
|
61
|
+
readonly ok: false;
|
|
62
|
+
readonly error: "unsigned" | "downgrade";
|
|
63
|
+
};
|
|
64
|
+
readonly status: {
|
|
65
|
+
readonly ok: true;
|
|
66
|
+
readonly status: LocalHostStatus;
|
|
67
|
+
readonly grants: readonly GrantSummary[];
|
|
68
|
+
};
|
|
69
|
+
readonly connect: {
|
|
70
|
+
readonly ok: true;
|
|
71
|
+
};
|
|
72
|
+
readonly begin_local_pairing: {
|
|
73
|
+
readonly ok: true;
|
|
74
|
+
readonly pairing: HostPairing;
|
|
75
|
+
};
|
|
76
|
+
readonly finish_local_pairing: {
|
|
77
|
+
readonly ok: true;
|
|
78
|
+
readonly account: string;
|
|
79
|
+
readonly appName: string;
|
|
80
|
+
readonly matchingCode: string;
|
|
81
|
+
};
|
|
82
|
+
readonly confirm_local_pairing: {
|
|
83
|
+
readonly ok: true;
|
|
84
|
+
} | {
|
|
85
|
+
readonly ok: false;
|
|
86
|
+
readonly error: "declined_locally";
|
|
87
|
+
};
|
|
88
|
+
readonly disconnect: {
|
|
89
|
+
readonly ok: true;
|
|
90
|
+
};
|
|
91
|
+
readonly dev_attach: {
|
|
92
|
+
readonly ok: true;
|
|
93
|
+
};
|
|
94
|
+
readonly dev_detach: {
|
|
95
|
+
readonly ok: true;
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
export type ControlResponse<O extends ControlOp> = ControlReplies[O] | ControlFailure;
|
|
99
|
+
export interface ControlClient {
|
|
100
|
+
send<R extends ControlRequest>(request: R): Promise<ControlResponse<R["op"]>>;
|
|
101
|
+
close(): void;
|
|
102
|
+
}
|
|
103
|
+
/** `undefined` when no daemon answers on the socket. */
|
|
104
|
+
export declare function connectControl(socketPath: string): Promise<ControlClient | undefined>;
|
|
105
|
+
export {};
|
|
106
|
+
//# sourceMappingURL=control.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"control.d.ts","sourceRoot":"","sources":["../src/control.ts"],"names":[],"mappings":"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"}
|
package/dist/control.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { connect } from "node:net";
|
|
2
|
+
import { onLines } from "./lines.js";
|
|
3
|
+
export const CONTROL_PROTOCOL = 1;
|
|
4
|
+
/** `undefined` when no daemon answers on the socket. */
|
|
5
|
+
export async function connectControl(socketPath) {
|
|
6
|
+
const socket = connect(socketPath);
|
|
7
|
+
const connected = await new Promise((resolve) => {
|
|
8
|
+
socket.once("connect", () => resolve(true));
|
|
9
|
+
socket.once("error", () => resolve(false));
|
|
10
|
+
});
|
|
11
|
+
if (!connected) {
|
|
12
|
+
socket.destroy();
|
|
13
|
+
return undefined;
|
|
14
|
+
}
|
|
15
|
+
const waiting = [];
|
|
16
|
+
onLines(socket, (line) => waiting.shift()?.(line));
|
|
17
|
+
socket.on("close", () => {
|
|
18
|
+
for (const reply of waiting.splice(0))
|
|
19
|
+
reply(undefined);
|
|
20
|
+
});
|
|
21
|
+
socket.on("error", () => socket.destroy());
|
|
22
|
+
return {
|
|
23
|
+
send: (request) => new Promise((resolve) => {
|
|
24
|
+
waiting.push((line) => resolve(line === undefined
|
|
25
|
+
? { ok: false, error: "Parlor Host closed the connection." }
|
|
26
|
+
: JSON.parse(line)));
|
|
27
|
+
socket.write(`${JSON.stringify(request)}\n`);
|
|
28
|
+
}),
|
|
29
|
+
close: () => socket.end(),
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=control.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"control.js","sourceRoot":"","sources":["../src/control.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAInC,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAGrC,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC;AAsElC,wDAAwD;AACxD,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,UAAkB;IAElB,MAAM,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IACnC,MAAM,SAAS,GAAG,MAAM,IAAI,OAAO,CAAU,CAAC,OAAO,EAAE,EAAE;QACvD,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;QAC5C,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;IACH,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,CAAC,OAAO,EAAE,CAAC;QACjB,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,OAAO,GAA2C,EAAE,CAAC;IAC3D,OAAO,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;IACnD,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;QACtB,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;YAAE,KAAK,CAAC,SAAS,CAAC,CAAC;IAC1D,CAAC,CAAC,CAAC;IACH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;IAC3C,OAAO;QACL,IAAI,EAAE,CAAC,OAAO,EAAE,EAAE,CAChB,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YACtB,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CACpB,OAAO,CACL,IAAI,KAAK,SAAS;gBAChB,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,oCAAoC,EAAE;gBAC5D,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CACrB,CACF,CAAC;YACF,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC/C,CAAC,CAAC;QACJ,KAAK,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,EAAE;KAC1B,CAAC;AACJ,CAAC","sourcesContent":["import { connect } from \"node:net\";\n\nimport type { HostPairing, LocalHostStatus, PairingDevice } from \"@parlor/capabilities\";\n\nimport { onLines } from \"./lines.js\";\nimport type { HostRelease, ServiceClient } from \"./service.js\";\n\nexport const CONTROL_PROTOCOL = 1;\n\n/**\n * Newline-delimited JSON on a 0600 Unix socket (a named pipe on Windows), spoken by the\n * `parlor-host` CLI and the desktop shell's Rust side. No TCP listener exists.\n */\nexport type ControlRequest =\n | { readonly op: \"hello\"; readonly client: ServiceClient }\n | { readonly op: \"handover\"; readonly binary: string; readonly signature: string }\n | { readonly op: \"status\" }\n | { readonly op: \"connect\"; readonly appOrigin: string }\n | { readonly op: \"begin_local_pairing\"; readonly appOrigin: string }\n | {\n readonly op: \"finish_local_pairing\";\n readonly appOrigin: string;\n readonly code: string;\n }\n | {\n readonly op: \"confirm_local_pairing\";\n readonly appOrigin: string;\n readonly connect: boolean;\n readonly device?: PairingDevice;\n }\n | { readonly op: \"disconnect\"; readonly appOrigin: string }\n | { readonly op: \"dev_attach\"; readonly appOrigin: string; readonly hostToken: string }\n | { readonly op: \"dev_detach\"; readonly appOrigin: string };\n\nexport type ControlOp = ControlRequest[\"op\"];\n\nexport interface GrantSummary {\n readonly appOrigin: string;\n readonly appName: string;\n readonly grantId: string;\n}\n\nexport type ControlFailure = { readonly ok: false; readonly error: string };\n\ninterface ControlReplies {\n readonly hello: { readonly ok: true; readonly release: HostRelease };\n readonly handover:\n | { readonly ok: true }\n | { readonly ok: false; readonly error: \"unsigned\" | \"downgrade\" };\n readonly status: {\n readonly ok: true;\n readonly status: LocalHostStatus;\n readonly grants: readonly GrantSummary[];\n };\n readonly connect: { readonly ok: true };\n readonly begin_local_pairing: { readonly ok: true; readonly pairing: HostPairing };\n readonly finish_local_pairing: {\n readonly ok: true;\n readonly account: string;\n readonly appName: string;\n readonly matchingCode: string;\n };\n readonly confirm_local_pairing:\n | { readonly ok: true }\n | { readonly ok: false; readonly error: \"declined_locally\" };\n readonly disconnect: { readonly ok: true };\n readonly dev_attach: { readonly ok: true };\n readonly dev_detach: { readonly ok: true };\n}\n\nexport type ControlResponse<O extends ControlOp> = ControlReplies[O] | ControlFailure;\n\nexport interface ControlClient {\n send<R extends ControlRequest>(request: R): Promise<ControlResponse<R[\"op\"]>>;\n close(): void;\n}\n\n/** `undefined` when no daemon answers on the socket. */\nexport async function connectControl(\n socketPath: string,\n): Promise<ControlClient | undefined> {\n const socket = connect(socketPath);\n const connected = await new Promise<boolean>((resolve) => {\n socket.once(\"connect\", () => resolve(true));\n socket.once(\"error\", () => resolve(false));\n });\n if (!connected) {\n socket.destroy();\n return undefined;\n }\n const waiting: ((line: string | undefined) => void)[] = [];\n onLines(socket, (line) => waiting.shift()?.(line));\n socket.on(\"close\", () => {\n for (const reply of waiting.splice(0)) reply(undefined);\n });\n socket.on(\"error\", () => socket.destroy());\n return {\n send: (request) =>\n new Promise((resolve) => {\n waiting.push((line) =>\n resolve(\n line === undefined\n ? { ok: false, error: \"Parlor Host closed the connection.\" }\n : JSON.parse(line),\n ),\n );\n socket.write(`${JSON.stringify(request)}\\n`);\n }),\n close: () => socket.end(),\n };\n}\n"]}
|