@agenticprimitives/acp 0.0.0-alpha.2
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 +28 -0
- package/bin/acp-stub-agent.mjs +68 -0
- package/dist/host.d.ts +76 -0
- package/dist/host.d.ts.map +1 -0
- package/dist/host.js +209 -0
- package/dist/host.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/protocol.d.ts +253 -0
- package/dist/protocol.d.ts.map +1 -0
- package/dist/protocol.js +32 -0
- package/dist/protocol.js.map +1 -0
- package/package.json +36 -0
- package/spec.md +12 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Agentic Trust Labs
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# @agenticprimitives/acp
|
|
2
|
+
|
|
3
|
+
Run an [Agent Client Protocol](https://agentclientprotocol.com) agent — Claude Code, goose, Codex, any ACP-speaking
|
|
4
|
+
runtime — as a **member of a workspace**, with the workspace deciding what it may do, on chain, at every act.
|
|
5
|
+
|
|
6
|
+
```ts
|
|
7
|
+
import { AcpHost, collectText } from '@agenticprimitives/acp';
|
|
8
|
+
|
|
9
|
+
const host = new AcpHost({ command: 'goose', args: ['acp'] });
|
|
10
|
+
await host.start(); // ACP v1 handshake; another major is refused
|
|
11
|
+
const { sessionId } = await host.newSession(process.cwd(), [
|
|
12
|
+
{ name: 'workspace', command: 'ap', args: ['runtime', 'mcp', '--member', 'goose-1.svc'] },
|
|
13
|
+
]);
|
|
14
|
+
const text = collectText(host, sessionId);
|
|
15
|
+
await host.prompt(sessionId, [{ type: 'text', text: 'mara.me: summarize the retreat plan' }]);
|
|
16
|
+
console.log(text.text());
|
|
17
|
+
await host.stop();
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
What the host does: speaks ACP to the agent it spawned; streams the agent's updates; answers the agent's
|
|
21
|
+
`session/request_permission` by **policy** — a workspace tool (the `workspace` MCP server's) is always allowed because
|
|
22
|
+
the workspace decides when the call arrives as `harness.ask`; a local tool (the agent's own shell or files) is refused
|
|
23
|
+
unless your policy says otherwise. What it never does: offer the agent your files or terminal, or decide a workspace
|
|
24
|
+
act itself.
|
|
25
|
+
|
|
26
|
+
The rest of W1 — the workspace MCP server (`ap runtime mcp`), pairing (`ap runtime join`), the loop (`ap runtime run`)
|
|
27
|
+
— lives in the devkit and the runtime app (spec 400 §5.2). `bin/acp-stub-agent.mjs` is a fixed-behaviour ACP agent
|
|
28
|
+
for tests.
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// A STUB ACP AGENT — speaks Agent Client Protocol v1 over stdio the way a real coding agent does, with none of the
|
|
3
|
+
// intelligence: it exists so the host binding can be tested end to end in CI without goose, and so the live gate has
|
|
4
|
+
// a runtime whose behaviour is fixed. On each prompt it (1) streams a plan and a thought, (2) asks permission for a
|
|
5
|
+
// LOCAL tool (its own shell — the host must refuse by default), (3) asks permission for a WORKSPACE tool (the host
|
|
6
|
+
// allows — the workspace decides), (4) answers with a message that echoes the prompt and says what it was allowed.
|
|
7
|
+
//
|
|
8
|
+
// node bin/acp-stub-agent.mjs (ACP_STUB_VERSION=2 answers protocolVersion 2 — the refusal twin)
|
|
9
|
+
import { createInterface } from 'node:readline';
|
|
10
|
+
|
|
11
|
+
const VERSION = Number(process.env.ACP_STUB_VERSION ?? 1);
|
|
12
|
+
const write = (m) => process.stdout.write(`${JSON.stringify(m)}\n`);
|
|
13
|
+
const notify = (method, params) => write({ jsonrpc: '2.0', method, params });
|
|
14
|
+
let nextId = 1000;
|
|
15
|
+
const pending = new Map();
|
|
16
|
+
const request = (method, params) => new Promise((resolve) => { const id = nextId++; pending.set(id, resolve); write({ jsonrpc: '2.0', id, method, params }); });
|
|
17
|
+
const sessions = new Map();
|
|
18
|
+
|
|
19
|
+
const rl = createInterface({ input: process.stdin });
|
|
20
|
+
rl.on('line', (line) => {
|
|
21
|
+
if (!line.trim()) return;
|
|
22
|
+
let msg; try { msg = JSON.parse(line); } catch { return; }
|
|
23
|
+
if (msg.id !== undefined && msg.method === undefined) { const r = pending.get(msg.id); if (r) { pending.delete(msg.id); r(msg.result ?? msg.error); } return; }
|
|
24
|
+
void handle(msg);
|
|
25
|
+
});
|
|
26
|
+
rl.on('close', () => process.exit(0));
|
|
27
|
+
|
|
28
|
+
async function handle(msg) {
|
|
29
|
+
const { id, method, params } = msg;
|
|
30
|
+
if (method === 'initialize') {
|
|
31
|
+
return write({ jsonrpc: '2.0', id, result: { protocolVersion: VERSION, agentCapabilities: { loadSession: true, promptCapabilities: { embeddedContext: true } }, agentInfo: { name: 'acp-stub-agent', version: '0.1.0' } } });
|
|
32
|
+
}
|
|
33
|
+
if (method === 'session/new') {
|
|
34
|
+
const sessionId = `sess_${Math.random().toString(36).slice(2, 10)}`;
|
|
35
|
+
sessions.set(sessionId, { cwd: params.cwd, mcpServers: params.mcpServers ?? [], turns: 0 });
|
|
36
|
+
return write({ jsonrpc: '2.0', id, result: { sessionId } });
|
|
37
|
+
}
|
|
38
|
+
if (method === 'session/load') {
|
|
39
|
+
sessions.set(params.sessionId, { cwd: params.cwd, mcpServers: params.mcpServers ?? [], turns: 0, loaded: true });
|
|
40
|
+
return write({ jsonrpc: '2.0', id, result: {} });
|
|
41
|
+
}
|
|
42
|
+
if (method === 'session/cancel') return; // a notification; the turn below checks the flag
|
|
43
|
+
if (method === 'session/prompt') {
|
|
44
|
+
const s = sessions.get(params.sessionId);
|
|
45
|
+
if (!s) return write({ jsonrpc: '2.0', id, error: { code: -32602, message: 'unknown session' } });
|
|
46
|
+
s.turns += 1;
|
|
47
|
+
const text = (params.prompt ?? []).filter((b) => b.type === 'text').map((b) => b.text).join('\n');
|
|
48
|
+
notify('session/update', { sessionId: params.sessionId, update: { sessionUpdate: 'plan', entries: [{ content: 'read the workspace', priority: 'high', status: 'pending' }, { content: 'answer', priority: 'high', status: 'pending' }] } });
|
|
49
|
+
notify('session/update', { sessionId: params.sessionId, update: { sessionUpdate: 'agent_thought_chunk', content: { type: 'text', text: 'I will try my shell first, then the workspace.' } } });
|
|
50
|
+
// (2) a LOCAL tool — the host should refuse this by default
|
|
51
|
+
notify('session/update', { sessionId: params.sessionId, update: { sessionUpdate: 'tool_call', toolCallId: 'call_local_1', title: 'Run `rm -rf build`', kind: 'execute', status: 'pending', rawInput: { command: 'rm -rf build' } } });
|
|
52
|
+
const local = await request('session/request_permission', { sessionId: params.sessionId, toolCall: { toolCallId: 'call_local_1', title: 'Run `rm -rf build`', kind: 'execute', status: 'pending', rawInput: { command: 'rm -rf build' } }, options: [{ optionId: 'allow', name: 'Allow', kind: 'allow_once' }, { optionId: 'reject', name: 'Reject', kind: 'reject_once' }] });
|
|
53
|
+
const localAllowed = local?.outcome?.outcome === 'selected' && local.outcome.optionId === 'allow';
|
|
54
|
+
notify('session/update', { sessionId: params.sessionId, update: { sessionUpdate: 'tool_call_update', toolCallId: 'call_local_1', status: localAllowed ? 'completed' : 'failed' } });
|
|
55
|
+
// (3) a WORKSPACE tool — the workspace's MCP server; the host allows, the workspace decides
|
|
56
|
+
const server = s.mcpServers[0]?.name ?? 'workspace';
|
|
57
|
+
const wsCall = { toolCallId: 'call_ws_1', title: `${server}.workspace_ask`, kind: 'fetch', status: 'pending', rawInput: { server, tool: 'workspace_ask', message: text.split('\n').pop() } };
|
|
58
|
+
notify('session/update', { sessionId: params.sessionId, update: { sessionUpdate: 'tool_call', ...wsCall } });
|
|
59
|
+
const ws = await request('session/request_permission', { sessionId: params.sessionId, toolCall: wsCall, options: [{ optionId: 'allow', name: 'Allow', kind: 'allow_once' }, { optionId: 'reject', name: 'Reject', kind: 'reject_once' }] });
|
|
60
|
+
const wsAllowed = ws?.outcome?.outcome === 'selected' && ws.outcome.optionId === 'allow';
|
|
61
|
+
notify('session/update', { sessionId: params.sessionId, update: { sessionUpdate: 'tool_call_update', toolCallId: 'call_ws_1', status: wsAllowed ? 'completed' : 'failed' } });
|
|
62
|
+
// (4) the answer
|
|
63
|
+
const answer = `stub: heard "${text.split('\n').pop()}" · local tool ${localAllowed ? 'ALLOWED' : 'refused'} · workspace tool ${wsAllowed ? 'allowed' : 'REFUSED'}${s.loaded ? ' · session loaded' : ''} · turn ${s.turns}`;
|
|
64
|
+
for (const piece of answer.match(/.{1,24}/g) ?? []) notify('session/update', { sessionId: params.sessionId, update: { sessionUpdate: 'agent_message_chunk', messageId: 'msg_1', content: { type: 'text', text: piece } } });
|
|
65
|
+
return write({ jsonrpc: '2.0', id, result: { stopReason: 'end_turn' } });
|
|
66
|
+
}
|
|
67
|
+
write({ jsonrpc: '2.0', id, error: { code: -32601, message: `unknown method ${method}` } });
|
|
68
|
+
}
|
package/dist/host.d.ts
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { EventEmitter } from 'node:events';
|
|
2
|
+
import { type AgentCapabilities, type ContentBlock, type InitializeResponse, type McpServerStdio, type NewSessionResponse, type PromptResponse, type RequestPermissionRequest, type RequestPermissionResponse, type SessionNotification } from './protocol.js';
|
|
3
|
+
/** How a permission request is answered. `workspace` is any tool the workspace MCP server exposes (always allowed:
|
|
4
|
+
* the workspace decides); `local` is the agent's own file/shell/other tool — the operator's policy. */
|
|
5
|
+
export type PermissionPolicy = (req: RequestPermissionRequest, classified: 'workspace' | 'local') => Promise<RequestPermissionResponse> | RequestPermissionResponse;
|
|
6
|
+
export interface AcpHostOptions {
|
|
7
|
+
/** The agent's command and arguments, e.g. `['goose', 'acp']`, `['claude-code-acp']`, `['codex-acp']`. */
|
|
8
|
+
command: string;
|
|
9
|
+
args?: string[];
|
|
10
|
+
env?: Record<string, string>;
|
|
11
|
+
cwd?: string;
|
|
12
|
+
clientInfo?: {
|
|
13
|
+
name: string;
|
|
14
|
+
version?: string;
|
|
15
|
+
};
|
|
16
|
+
/** The name of the MCP server whose tools are the workspace's — tool calls titled with it are `workspace`. */
|
|
17
|
+
workspaceServerName?: string;
|
|
18
|
+
permission?: PermissionPolicy;
|
|
19
|
+
/** Per-request timeout for the agent's answers to the host's requests (initialize, session/new). A prompt turn has none. */
|
|
20
|
+
requestTimeoutMs?: number;
|
|
21
|
+
/** Where the agent's stderr goes (its own logging). Default: dropped. */
|
|
22
|
+
onStderr?: (line: string) => void;
|
|
23
|
+
}
|
|
24
|
+
export interface AcpHostEvents {
|
|
25
|
+
update: [SessionNotification];
|
|
26
|
+
permission: [RequestPermissionRequest, RequestPermissionResponse];
|
|
27
|
+
exit: [{
|
|
28
|
+
code: number | null;
|
|
29
|
+
signal: NodeJS.Signals | null;
|
|
30
|
+
}];
|
|
31
|
+
/** A line on stdout that was not JSON — an agent printing prose where the protocol is. Reported, never parsed. */
|
|
32
|
+
noise: [string];
|
|
33
|
+
}
|
|
34
|
+
/** The default policy: the workspace's tools are the workspace's to judge (allow); a local tool is REFUSED unless an
|
|
35
|
+
* operator policy says otherwise — a host that quietly allowed an agent's shell would be the click-model bug. */
|
|
36
|
+
export declare const refuseLocalTools: PermissionPolicy;
|
|
37
|
+
export declare class AcpHost extends EventEmitter<AcpHostEvents> {
|
|
38
|
+
private readonly opts;
|
|
39
|
+
private proc;
|
|
40
|
+
private nextId;
|
|
41
|
+
private readonly pending;
|
|
42
|
+
private buffer;
|
|
43
|
+
private agentCapabilities;
|
|
44
|
+
private agentInfo;
|
|
45
|
+
private readonly workspaceServerName;
|
|
46
|
+
private readonly permission;
|
|
47
|
+
constructor(opts: AcpHostOptions);
|
|
48
|
+
/** Spawn the agent and negotiate the protocol. Refuses an agent on another major version. */
|
|
49
|
+
start(): Promise<InitializeResponse>;
|
|
50
|
+
get capabilities(): AgentCapabilities;
|
|
51
|
+
get agent(): InitializeResponse['agentInfo'];
|
|
52
|
+
/** Open a session. The workspace reaches the agent as the MCP server named here (spec 400 §5.2). */
|
|
53
|
+
newSession(cwd: string, mcpServers: McpServerStdio[]): Promise<NewSessionResponse>;
|
|
54
|
+
/** Resume a session the agent remembers — only when it said it can (`loadSession`); otherwise the caller opens a new one. */
|
|
55
|
+
loadSession(sessionId: string, cwd: string, mcpServers: McpServerStdio[]): Promise<boolean>;
|
|
56
|
+
/** One prompt turn. Resolves when the agent ends the turn; updates stream through the `update` event meanwhile. */
|
|
57
|
+
prompt(sessionId: string, prompt: ContentBlock[]): Promise<PromptResponse>;
|
|
58
|
+
cancel(sessionId: string): void;
|
|
59
|
+
stop(): Promise<void>;
|
|
60
|
+
private request;
|
|
61
|
+
private notify;
|
|
62
|
+
private send;
|
|
63
|
+
private onData;
|
|
64
|
+
private dispatch;
|
|
65
|
+
/** The agent's callbacks. Permission by policy; the host machine's files and shell are not offered (§5.1). */
|
|
66
|
+
private answer;
|
|
67
|
+
/** A workspace tool is one the workspace MCP server exposes: agents title MCP tool calls `<server>.<tool>` or name
|
|
68
|
+
* the server in `rawInput`; either mark makes it `workspace`. Anything else is the agent's own. */
|
|
69
|
+
private classify;
|
|
70
|
+
}
|
|
71
|
+
/** A convenience for tests and CLIs: collect the text of a turn as it streams. */
|
|
72
|
+
export declare function collectText(host: AcpHost, sessionId: string): {
|
|
73
|
+
text: () => string;
|
|
74
|
+
stop: () => void;
|
|
75
|
+
};
|
|
76
|
+
//# sourceMappingURL=host.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../src/host.ts"],"names":[],"mappings":"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"}
|
package/dist/host.js
ADDED
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
// THE ACP HOST — runs one ACP-speaking agent as a child process and speaks JSON-RPC 2.0 to it over its stdio.
|
|
2
|
+
//
|
|
3
|
+
// The host is deliberately small and deliberately dumb about authority: it negotiates the protocol, opens sessions,
|
|
4
|
+
// sends prompts, streams the agent's updates to whoever listens, and answers the agent's callbacks by POLICY ports.
|
|
5
|
+
// It offers the agent none of the host machine (`clientCapabilities.fs` / `.terminal` are false — the agent's files
|
|
6
|
+
// and shell are the agent's own) and it decides no workspace question: a workspace tool call is always allowed here
|
|
7
|
+
// because the WORKSPACE decides it, on chain, when the call arrives as `harness.ask` (spec 400 §5.1). What remains for
|
|
8
|
+
// the policy port is the agent's LOCAL tools, which are outside the substrate's authority model by construction.
|
|
9
|
+
//
|
|
10
|
+
// Transport: newline-delimited JSON on stdout/stdin — what every ACP agent ships today. A future framed transport is a
|
|
11
|
+
// second `Transport` implementation, not a change to this file's protocol handling.
|
|
12
|
+
import { spawn } from 'node:child_process';
|
|
13
|
+
import { EventEmitter } from 'node:events';
|
|
14
|
+
import { ACP_ERRORS, ACP_METHODS, ACP_PROTOCOL_VERSION, isNotification, isRequest, isResponse, } from './protocol.js';
|
|
15
|
+
/** The default policy: the workspace's tools are the workspace's to judge (allow); a local tool is REFUSED unless an
|
|
16
|
+
* operator policy says otherwise — a host that quietly allowed an agent's shell would be the click-model bug. */
|
|
17
|
+
export const refuseLocalTools = (req, classified) => {
|
|
18
|
+
const pick = (kinds) => req.options.find((o) => kinds.includes(o.kind));
|
|
19
|
+
const choice = classified === 'workspace' ? pick(['allow_once', 'allow_always']) : pick(['reject_once', 'reject_always']);
|
|
20
|
+
return choice ? { outcome: { outcome: 'selected', optionId: choice.optionId } } : { outcome: { outcome: 'cancelled' } };
|
|
21
|
+
};
|
|
22
|
+
export class AcpHost extends EventEmitter {
|
|
23
|
+
opts;
|
|
24
|
+
proc = null;
|
|
25
|
+
nextId = 1;
|
|
26
|
+
pending = new Map();
|
|
27
|
+
buffer = '';
|
|
28
|
+
agentCapabilities = {};
|
|
29
|
+
agentInfo;
|
|
30
|
+
workspaceServerName;
|
|
31
|
+
permission;
|
|
32
|
+
constructor(opts) {
|
|
33
|
+
super();
|
|
34
|
+
this.opts = opts;
|
|
35
|
+
this.workspaceServerName = opts.workspaceServerName ?? 'workspace';
|
|
36
|
+
this.permission = opts.permission ?? refuseLocalTools;
|
|
37
|
+
}
|
|
38
|
+
/** Spawn the agent and negotiate the protocol. Refuses an agent on another major version. */
|
|
39
|
+
async start() {
|
|
40
|
+
if (this.proc)
|
|
41
|
+
throw new Error('acp host already started');
|
|
42
|
+
const proc = spawn(this.opts.command, this.opts.args ?? [], { cwd: this.opts.cwd, env: { ...process.env, ...(this.opts.env ?? {}) }, stdio: ['pipe', 'pipe', 'pipe'] });
|
|
43
|
+
this.proc = proc;
|
|
44
|
+
proc.stdout.setEncoding('utf8');
|
|
45
|
+
proc.stdout.on('data', (chunk) => this.onData(chunk));
|
|
46
|
+
proc.stderr.setEncoding('utf8');
|
|
47
|
+
proc.stderr.on('data', (chunk) => { for (const line of chunk.split('\n'))
|
|
48
|
+
if (line.trim())
|
|
49
|
+
this.opts.onStderr?.(line); });
|
|
50
|
+
proc.on('exit', (code, signal) => {
|
|
51
|
+
for (const p of this.pending.values())
|
|
52
|
+
p.reject(new Error(`the agent exited (${code ?? signal}) before answering`));
|
|
53
|
+
this.pending.clear();
|
|
54
|
+
this.emit('exit', { code, signal });
|
|
55
|
+
});
|
|
56
|
+
const init = (await this.request(ACP_METHODS.initialize, {
|
|
57
|
+
protocolVersion: ACP_PROTOCOL_VERSION,
|
|
58
|
+
clientCapabilities: { fs: { readTextFile: false, writeTextFile: false }, terminal: false },
|
|
59
|
+
clientInfo: this.opts.clientInfo ?? { name: '@agenticprimitives/acp' },
|
|
60
|
+
}));
|
|
61
|
+
if (typeof init?.protocolVersion !== 'number' || Math.floor(init.protocolVersion) !== ACP_PROTOCOL_VERSION) {
|
|
62
|
+
await this.stop();
|
|
63
|
+
throw new Error(`the agent speaks ACP protocol version ${String(init?.protocolVersion)}; this host speaks ${ACP_PROTOCOL_VERSION}`);
|
|
64
|
+
}
|
|
65
|
+
this.agentCapabilities = init.agentCapabilities ?? {};
|
|
66
|
+
this.agentInfo = init.agentInfo;
|
|
67
|
+
return init;
|
|
68
|
+
}
|
|
69
|
+
get capabilities() { return this.agentCapabilities; }
|
|
70
|
+
get agent() { return this.agentInfo; }
|
|
71
|
+
/** Open a session. The workspace reaches the agent as the MCP server named here (spec 400 §5.2). */
|
|
72
|
+
async newSession(cwd, mcpServers) {
|
|
73
|
+
return (await this.request(ACP_METHODS.newSession, { cwd, mcpServers }));
|
|
74
|
+
}
|
|
75
|
+
/** Resume a session the agent remembers — only when it said it can (`loadSession`); otherwise the caller opens a new one. */
|
|
76
|
+
async loadSession(sessionId, cwd, mcpServers) {
|
|
77
|
+
if (!this.agentCapabilities.loadSession)
|
|
78
|
+
return false;
|
|
79
|
+
await this.request(ACP_METHODS.loadSession, { sessionId, cwd, mcpServers });
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
/** One prompt turn. Resolves when the agent ends the turn; updates stream through the `update` event meanwhile. */
|
|
83
|
+
async prompt(sessionId, prompt) {
|
|
84
|
+
return (await this.request(ACP_METHODS.prompt, { sessionId, prompt }, 0));
|
|
85
|
+
}
|
|
86
|
+
cancel(sessionId) { this.notify(ACP_METHODS.cancel, { sessionId }); }
|
|
87
|
+
async stop() {
|
|
88
|
+
const proc = this.proc;
|
|
89
|
+
if (!proc)
|
|
90
|
+
return;
|
|
91
|
+
this.proc = null;
|
|
92
|
+
proc.stdin.end();
|
|
93
|
+
await new Promise((resolve) => {
|
|
94
|
+
const t = setTimeout(() => { proc.kill('SIGKILL'); resolve(); }, 2000);
|
|
95
|
+
proc.once('exit', () => { clearTimeout(t); resolve(); });
|
|
96
|
+
proc.kill('SIGTERM');
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
// ─── wire ──────────────────────────────────────────────────────────────────────────────────────────────────
|
|
100
|
+
request(method, params, timeoutMs = this.opts.requestTimeoutMs ?? 30_000) {
|
|
101
|
+
const id = this.nextId++;
|
|
102
|
+
const msg = { jsonrpc: '2.0', id, method, params };
|
|
103
|
+
return new Promise((resolve, reject) => {
|
|
104
|
+
const p = { resolve, reject };
|
|
105
|
+
if (timeoutMs > 0)
|
|
106
|
+
p.timer = setTimeout(() => { this.pending.delete(id); reject(new Error(`${method}: the agent did not answer within ${timeoutMs} ms`)); }, timeoutMs);
|
|
107
|
+
this.pending.set(id, p);
|
|
108
|
+
this.send(msg);
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
notify(method, params) { this.send({ jsonrpc: '2.0', method, params }); }
|
|
112
|
+
send(msg) {
|
|
113
|
+
if (!this.proc)
|
|
114
|
+
throw new Error('acp host not started');
|
|
115
|
+
this.proc.stdin.write(`${JSON.stringify(msg)}\n`);
|
|
116
|
+
}
|
|
117
|
+
onData(chunk) {
|
|
118
|
+
this.buffer += chunk;
|
|
119
|
+
let nl;
|
|
120
|
+
while ((nl = this.buffer.indexOf('\n')) >= 0) {
|
|
121
|
+
const line = this.buffer.slice(0, nl).trim();
|
|
122
|
+
this.buffer = this.buffer.slice(nl + 1);
|
|
123
|
+
if (!line)
|
|
124
|
+
continue;
|
|
125
|
+
let msg;
|
|
126
|
+
try {
|
|
127
|
+
msg = JSON.parse(line);
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
this.emit('noise', line);
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
if (typeof msg !== 'object' || msg === null || msg.jsonrpc !== '2.0') {
|
|
134
|
+
this.emit('noise', line);
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
void this.dispatch(msg);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
async dispatch(msg) {
|
|
141
|
+
if (isResponse(msg)) {
|
|
142
|
+
const p = this.pending.get(msg.id);
|
|
143
|
+
if (!p)
|
|
144
|
+
return;
|
|
145
|
+
this.pending.delete(msg.id);
|
|
146
|
+
if (p.timer)
|
|
147
|
+
clearTimeout(p.timer);
|
|
148
|
+
if (msg.error)
|
|
149
|
+
p.reject(new Error(`${msg.error.message} (${msg.error.code})`));
|
|
150
|
+
else
|
|
151
|
+
p.resolve(msg.result);
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
if (isNotification(msg)) {
|
|
155
|
+
if (msg.method === ACP_METHODS.update)
|
|
156
|
+
this.emit('update', msg.params);
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
const req = msg;
|
|
160
|
+
if (isRequest(req)) {
|
|
161
|
+
try {
|
|
162
|
+
const result = await this.answer(req);
|
|
163
|
+
this.send({ jsonrpc: '2.0', id: req.id, result });
|
|
164
|
+
}
|
|
165
|
+
catch (e) {
|
|
166
|
+
const err = e;
|
|
167
|
+
this.send({ jsonrpc: '2.0', id: req.id, error: { code: err.code ?? ACP_ERRORS.internal, message: err.message } });
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
/** The agent's callbacks. Permission by policy; the host machine's files and shell are not offered (§5.1). */
|
|
172
|
+
async answer(req) {
|
|
173
|
+
if (req.method === ACP_METHODS.requestPermission) {
|
|
174
|
+
const r = req.params;
|
|
175
|
+
const classified = this.classify(r);
|
|
176
|
+
const out = await this.permission(r, classified);
|
|
177
|
+
this.emit('permission', r, out);
|
|
178
|
+
return out;
|
|
179
|
+
}
|
|
180
|
+
const e = new Error(`${req.method}: not offered by this host — the agent's files and shell are its own (spec 400 §5.1)`);
|
|
181
|
+
e.code = ACP_ERRORS.methodNotFound;
|
|
182
|
+
throw e;
|
|
183
|
+
}
|
|
184
|
+
/** A workspace tool is one the workspace MCP server exposes: agents title MCP tool calls `<server>.<tool>` or name
|
|
185
|
+
* the server in `rawInput`; either mark makes it `workspace`. Anything else is the agent's own. */
|
|
186
|
+
classify(r) {
|
|
187
|
+
const t = r.toolCall;
|
|
188
|
+
const title = String(t.title ?? '');
|
|
189
|
+
const raw = JSON.stringify(t.rawInput ?? '');
|
|
190
|
+
const name = this.workspaceServerName;
|
|
191
|
+
if (title.startsWith(`${name}.`) || title.startsWith(`${name}_`) || title.includes(`(${name})`) || raw.includes(`"${name}"`))
|
|
192
|
+
return 'workspace';
|
|
193
|
+
return 'local';
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
/** A convenience for tests and CLIs: collect the text of a turn as it streams. */
|
|
197
|
+
export function collectText(host, sessionId) {
|
|
198
|
+
let out = '';
|
|
199
|
+
const on = (n) => {
|
|
200
|
+
if (n.sessionId !== sessionId)
|
|
201
|
+
return;
|
|
202
|
+
const u = n.update;
|
|
203
|
+
if (u.sessionUpdate === 'agent_message_chunk' && u.content?.type === 'text')
|
|
204
|
+
out += u.content.text;
|
|
205
|
+
};
|
|
206
|
+
host.on('update', on);
|
|
207
|
+
return { text: () => out, stop: () => { host.off('update', on); } };
|
|
208
|
+
}
|
|
209
|
+
//# sourceMappingURL=host.js.map
|
package/dist/host.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"host.js","sourceRoot":"","sources":["../src/host.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare const PACKAGE_NAME: "@agenticprimitives/acp";
|
|
2
|
+
export declare const PACKAGE_STATUS: "w1-host";
|
|
3
|
+
export declare const SPEC_REF: "specs/400-closing-the-workspace-gap-buzz-and-team-agent-platforms.md";
|
|
4
|
+
export { ACP_PROTOCOL_VERSION, ACP_METHODS, ACP_ERRORS, isRequest, isNotification, isResponse, } from './protocol.js';
|
|
5
|
+
export type { JsonRpcId, JsonRpcRequest, JsonRpcNotification, JsonRpcError, JsonRpcResponse, JsonRpcMessage, Implementation, ClientCapabilities, AgentCapabilities, InitializeRequest, InitializeResponse, McpServerStdio, NewSessionRequest, NewSessionResponse, LoadSessionRequest, ContentBlock, PromptRequest, StopReason, PromptResponse, CancelNotification, ToolKind, ToolCallStatus, ToolCallContent, ToolCall, PlanEntry, SessionUpdate, SessionNotification, PermissionOptionKind, PermissionOption, RequestPermissionRequest, RequestPermissionOutcome, RequestPermissionResponse, } from './protocol.js';
|
|
6
|
+
export { AcpHost, refuseLocalTools, collectText } from './host.js';
|
|
7
|
+
export type { AcpHostOptions, AcpHostEvents, PermissionPolicy } from './host.js';
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAUA,eAAO,MAAM,YAAY,EAAG,wBAAiC,CAAC;AAC9D,eAAO,MAAM,cAAc,EAAG,SAAkB,CAAC;AACjD,eAAO,MAAM,QAAQ,EAAG,sEAA+E,CAAC;AAExG,OAAO,EACL,oBAAoB,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,cAAc,EAAE,UAAU,GACrF,MAAM,eAAe,CAAC;AACvB,YAAY,EACV,SAAS,EAAE,cAAc,EAAE,mBAAmB,EAAE,YAAY,EAAE,eAAe,EAAE,cAAc,EAC7F,cAAc,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,kBAAkB,EAC5F,cAAc,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAClH,cAAc,EAAE,kBAAkB,EAAE,QAAQ,EAAE,cAAc,EAAE,eAAe,EAAE,QAAQ,EAAE,SAAS,EAAE,aAAa,EACjH,mBAAmB,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,wBAAwB,EAAE,wBAAwB,EAC/G,yBAAyB,GAC1B,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACnE,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// @agenticprimitives/acp — the Agent Client Protocol host binding (spec 400 W1).
|
|
2
|
+
//
|
|
3
|
+
// An existing general-purpose runtime that speaks ACP (Claude Code, goose, Codex) is ADMITTED as a workspace MEMBER —
|
|
4
|
+
// walks in without a rewrite; what it may do is the member's grant, whatever the runtime is for: chartered as a `.svc` Smart
|
|
5
|
+
// Agent by the person who brings it (spec 372 S3a), invited like any member, holding a session wire pinned to
|
|
6
|
+
// `harness.ask` (S3c). This package speaks ACP DOWN to the agent it spawns; the agent reaches the workspace UP through
|
|
7
|
+
// the MCP server the host hands it, whose every tool is one wire-signed A2A request as the runtime itself. ACP sits
|
|
8
|
+
// behind A2A — it is a transport binding (ADR-0057), never a second authority model: a read answers against the
|
|
9
|
+
// runtime's standing; a write parks for the steward's mandate; `session/request_permission` is answered by policy,
|
|
10
|
+
// never by a click that grants anything.
|
|
11
|
+
export const PACKAGE_NAME = '@agenticprimitives/acp';
|
|
12
|
+
export const PACKAGE_STATUS = 'w1-host';
|
|
13
|
+
export const SPEC_REF = 'specs/400-closing-the-workspace-gap-buzz-and-team-agent-platforms.md';
|
|
14
|
+
export { ACP_PROTOCOL_VERSION, ACP_METHODS, ACP_ERRORS, isRequest, isNotification, isResponse, } from './protocol.js';
|
|
15
|
+
export { AcpHost, refuseLocalTools, collectText } from './host.js';
|
|
16
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,EAAE;AACF,sHAAsH;AACtH,6HAA6H;AAC7H,8GAA8G;AAC9G,uHAAuH;AACvH,oHAAoH;AACpH,gHAAgH;AAChH,mHAAmH;AACnH,yCAAyC;AACzC,MAAM,CAAC,MAAM,YAAY,GAAG,wBAAiC,CAAC;AAC9D,MAAM,CAAC,MAAM,cAAc,GAAG,SAAkB,CAAC;AACjD,MAAM,CAAC,MAAM,QAAQ,GAAG,sEAA+E,CAAC;AAExG,OAAO,EACL,oBAAoB,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE,cAAc,EAAE,UAAU,GACrF,MAAM,eAAe,CAAC;AASvB,OAAO,EAAE,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC"}
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
/** The protocol version this binding speaks. An agent answering another MAJOR is refused, never coerced. */
|
|
2
|
+
export declare const ACP_PROTOCOL_VERSION: 1;
|
|
3
|
+
export type JsonRpcId = number | string;
|
|
4
|
+
export interface JsonRpcRequest {
|
|
5
|
+
jsonrpc: '2.0';
|
|
6
|
+
id: JsonRpcId;
|
|
7
|
+
method: string;
|
|
8
|
+
params?: unknown;
|
|
9
|
+
}
|
|
10
|
+
export interface JsonRpcNotification {
|
|
11
|
+
jsonrpc: '2.0';
|
|
12
|
+
method: string;
|
|
13
|
+
params?: unknown;
|
|
14
|
+
}
|
|
15
|
+
export interface JsonRpcError {
|
|
16
|
+
code: number;
|
|
17
|
+
message: string;
|
|
18
|
+
data?: unknown;
|
|
19
|
+
}
|
|
20
|
+
export interface JsonRpcResponse {
|
|
21
|
+
jsonrpc: '2.0';
|
|
22
|
+
id: JsonRpcId;
|
|
23
|
+
result?: unknown;
|
|
24
|
+
error?: JsonRpcError;
|
|
25
|
+
}
|
|
26
|
+
export type JsonRpcMessage = JsonRpcRequest | JsonRpcNotification | JsonRpcResponse;
|
|
27
|
+
export declare const isRequest: (m: JsonRpcMessage) => m is JsonRpcRequest;
|
|
28
|
+
export declare const isNotification: (m: JsonRpcMessage) => m is JsonRpcNotification;
|
|
29
|
+
export declare const isResponse: (m: JsonRpcMessage) => m is JsonRpcResponse;
|
|
30
|
+
export interface Implementation {
|
|
31
|
+
name: string;
|
|
32
|
+
version?: string;
|
|
33
|
+
title?: string;
|
|
34
|
+
}
|
|
35
|
+
/** What the CLIENT (the host) offers the agent. This binding offers NOTHING of its own machine: the runtime's files
|
|
36
|
+
* and shell are the runtime's; the workspace is reached through the MCP server the host hands it (§5.2). */
|
|
37
|
+
export interface ClientCapabilities {
|
|
38
|
+
fs?: {
|
|
39
|
+
readTextFile?: boolean;
|
|
40
|
+
writeTextFile?: boolean;
|
|
41
|
+
};
|
|
42
|
+
terminal?: boolean;
|
|
43
|
+
}
|
|
44
|
+
export interface AgentCapabilities {
|
|
45
|
+
loadSession?: boolean;
|
|
46
|
+
promptCapabilities?: {
|
|
47
|
+
image?: boolean;
|
|
48
|
+
audio?: boolean;
|
|
49
|
+
embeddedContext?: boolean;
|
|
50
|
+
};
|
|
51
|
+
mcpCapabilities?: {
|
|
52
|
+
http?: boolean;
|
|
53
|
+
sse?: boolean;
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
export interface InitializeRequest {
|
|
57
|
+
protocolVersion: number;
|
|
58
|
+
clientCapabilities?: ClientCapabilities;
|
|
59
|
+
clientInfo?: Implementation;
|
|
60
|
+
_meta?: Record<string, unknown>;
|
|
61
|
+
}
|
|
62
|
+
export interface InitializeResponse {
|
|
63
|
+
protocolVersion: number;
|
|
64
|
+
agentCapabilities?: AgentCapabilities;
|
|
65
|
+
agentInfo?: Implementation;
|
|
66
|
+
authMethods?: Array<{
|
|
67
|
+
id: string;
|
|
68
|
+
name: string;
|
|
69
|
+
description?: string;
|
|
70
|
+
}>;
|
|
71
|
+
_meta?: Record<string, unknown>;
|
|
72
|
+
}
|
|
73
|
+
/** An MCP server the AGENT spawns for the session (stdio) — how the workspace reaches the agent as tools. */
|
|
74
|
+
export interface McpServerStdio {
|
|
75
|
+
name: string;
|
|
76
|
+
command: string;
|
|
77
|
+
args: string[];
|
|
78
|
+
env?: Array<{
|
|
79
|
+
name: string;
|
|
80
|
+
value: string;
|
|
81
|
+
}>;
|
|
82
|
+
}
|
|
83
|
+
export interface NewSessionRequest {
|
|
84
|
+
cwd: string;
|
|
85
|
+
mcpServers: McpServerStdio[];
|
|
86
|
+
_meta?: Record<string, unknown>;
|
|
87
|
+
}
|
|
88
|
+
export interface NewSessionResponse {
|
|
89
|
+
sessionId: string;
|
|
90
|
+
modes?: unknown;
|
|
91
|
+
configOptions?: unknown;
|
|
92
|
+
_meta?: Record<string, unknown>;
|
|
93
|
+
}
|
|
94
|
+
export interface LoadSessionRequest {
|
|
95
|
+
sessionId: string;
|
|
96
|
+
cwd: string;
|
|
97
|
+
mcpServers: McpServerStdio[];
|
|
98
|
+
}
|
|
99
|
+
export type ContentBlock = {
|
|
100
|
+
type: 'text';
|
|
101
|
+
text: string;
|
|
102
|
+
annotations?: unknown;
|
|
103
|
+
_meta?: Record<string, unknown>;
|
|
104
|
+
} | {
|
|
105
|
+
type: 'resource_link';
|
|
106
|
+
uri: string;
|
|
107
|
+
name: string;
|
|
108
|
+
title?: string;
|
|
109
|
+
description?: string;
|
|
110
|
+
mimeType?: string;
|
|
111
|
+
} | {
|
|
112
|
+
type: 'resource';
|
|
113
|
+
resource: {
|
|
114
|
+
uri: string;
|
|
115
|
+
text?: string;
|
|
116
|
+
mimeType?: string;
|
|
117
|
+
};
|
|
118
|
+
} | {
|
|
119
|
+
type: 'image';
|
|
120
|
+
data: string;
|
|
121
|
+
mimeType: string;
|
|
122
|
+
} | {
|
|
123
|
+
type: 'audio';
|
|
124
|
+
data: string;
|
|
125
|
+
mimeType: string;
|
|
126
|
+
};
|
|
127
|
+
export interface PromptRequest {
|
|
128
|
+
sessionId: string;
|
|
129
|
+
prompt: ContentBlock[];
|
|
130
|
+
_meta?: Record<string, unknown>;
|
|
131
|
+
}
|
|
132
|
+
export type StopReason = 'end_turn' | 'max_tokens' | 'max_turn_requests' | 'refusal' | 'cancelled';
|
|
133
|
+
export interface PromptResponse {
|
|
134
|
+
stopReason: StopReason;
|
|
135
|
+
_meta?: Record<string, unknown>;
|
|
136
|
+
}
|
|
137
|
+
export interface CancelNotification {
|
|
138
|
+
sessionId: string;
|
|
139
|
+
}
|
|
140
|
+
export type ToolKind = 'read' | 'edit' | 'delete' | 'move' | 'search' | 'execute' | 'think' | 'fetch' | 'switch_mode' | 'other';
|
|
141
|
+
export type ToolCallStatus = 'pending' | 'in_progress' | 'completed' | 'failed';
|
|
142
|
+
export type ToolCallContent = {
|
|
143
|
+
type: 'content';
|
|
144
|
+
content: ContentBlock;
|
|
145
|
+
} | {
|
|
146
|
+
type: 'diff';
|
|
147
|
+
path: string;
|
|
148
|
+
oldText?: string | null;
|
|
149
|
+
newText: string;
|
|
150
|
+
} | {
|
|
151
|
+
type: 'terminal';
|
|
152
|
+
terminalId: string;
|
|
153
|
+
};
|
|
154
|
+
export interface ToolCall {
|
|
155
|
+
toolCallId: string;
|
|
156
|
+
title: string;
|
|
157
|
+
kind?: ToolKind;
|
|
158
|
+
status?: ToolCallStatus;
|
|
159
|
+
content?: ToolCallContent[];
|
|
160
|
+
locations?: Array<{
|
|
161
|
+
path: string;
|
|
162
|
+
line?: number | null;
|
|
163
|
+
}>;
|
|
164
|
+
rawInput?: unknown;
|
|
165
|
+
rawOutput?: unknown;
|
|
166
|
+
}
|
|
167
|
+
export interface PlanEntry {
|
|
168
|
+
content: string;
|
|
169
|
+
priority: 'high' | 'medium' | 'low';
|
|
170
|
+
status: 'pending' | 'in_progress' | 'completed';
|
|
171
|
+
}
|
|
172
|
+
export type SessionUpdate = {
|
|
173
|
+
sessionUpdate: 'user_message_chunk';
|
|
174
|
+
content: ContentBlock;
|
|
175
|
+
} | {
|
|
176
|
+
sessionUpdate: 'agent_message_chunk';
|
|
177
|
+
content: ContentBlock;
|
|
178
|
+
messageId?: string;
|
|
179
|
+
} | {
|
|
180
|
+
sessionUpdate: 'agent_thought_chunk';
|
|
181
|
+
content: ContentBlock;
|
|
182
|
+
} | ({
|
|
183
|
+
sessionUpdate: 'tool_call';
|
|
184
|
+
} & ToolCall) | ({
|
|
185
|
+
sessionUpdate: 'tool_call_update';
|
|
186
|
+
} & Partial<ToolCall> & {
|
|
187
|
+
toolCallId: string;
|
|
188
|
+
}) | {
|
|
189
|
+
sessionUpdate: 'plan';
|
|
190
|
+
entries: PlanEntry[];
|
|
191
|
+
} | {
|
|
192
|
+
sessionUpdate: 'available_commands_update';
|
|
193
|
+
availableCommands: unknown[];
|
|
194
|
+
} | {
|
|
195
|
+
sessionUpdate: 'current_mode_update';
|
|
196
|
+
currentModeId: string;
|
|
197
|
+
} | {
|
|
198
|
+
sessionUpdate: 'usage_update';
|
|
199
|
+
used?: number;
|
|
200
|
+
size?: number;
|
|
201
|
+
cost?: {
|
|
202
|
+
amount: number;
|
|
203
|
+
currency: string;
|
|
204
|
+
};
|
|
205
|
+
} | {
|
|
206
|
+
sessionUpdate: string;
|
|
207
|
+
[k: string]: unknown;
|
|
208
|
+
};
|
|
209
|
+
export interface SessionNotification {
|
|
210
|
+
sessionId: string;
|
|
211
|
+
update: SessionUpdate;
|
|
212
|
+
}
|
|
213
|
+
export type PermissionOptionKind = 'allow_once' | 'allow_always' | 'reject_once' | 'reject_always';
|
|
214
|
+
export interface PermissionOption {
|
|
215
|
+
optionId: string;
|
|
216
|
+
name: string;
|
|
217
|
+
kind: PermissionOptionKind;
|
|
218
|
+
}
|
|
219
|
+
export interface RequestPermissionRequest {
|
|
220
|
+
sessionId: string;
|
|
221
|
+
toolCall: Partial<ToolCall> & {
|
|
222
|
+
toolCallId: string;
|
|
223
|
+
};
|
|
224
|
+
options: PermissionOption[];
|
|
225
|
+
}
|
|
226
|
+
export type RequestPermissionOutcome = {
|
|
227
|
+
outcome: 'selected';
|
|
228
|
+
optionId: string;
|
|
229
|
+
} | {
|
|
230
|
+
outcome: 'cancelled';
|
|
231
|
+
};
|
|
232
|
+
export interface RequestPermissionResponse {
|
|
233
|
+
outcome: RequestPermissionOutcome;
|
|
234
|
+
}
|
|
235
|
+
/** The methods, spelled once. */
|
|
236
|
+
export declare const ACP_METHODS: {
|
|
237
|
+
readonly initialize: "initialize";
|
|
238
|
+
readonly newSession: "session/new";
|
|
239
|
+
readonly loadSession: "session/load";
|
|
240
|
+
readonly prompt: "session/prompt";
|
|
241
|
+
readonly cancel: "session/cancel";
|
|
242
|
+
readonly update: "session/update";
|
|
243
|
+
readonly requestPermission: "session/request_permission";
|
|
244
|
+
readonly fsRead: "fs/read_text_file";
|
|
245
|
+
readonly fsWrite: "fs/write_text_file";
|
|
246
|
+
};
|
|
247
|
+
/** JSON-RPC error codes this host answers with when it refuses an agent's callback. */
|
|
248
|
+
export declare const ACP_ERRORS: {
|
|
249
|
+
readonly methodNotFound: -32601;
|
|
250
|
+
readonly invalidParams: -32602;
|
|
251
|
+
readonly internal: -32603;
|
|
252
|
+
};
|
|
253
|
+
//# sourceMappingURL=protocol.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AASA,4GAA4G;AAC5G,eAAO,MAAM,oBAAoB,EAAG,CAAU,CAAC;AAI/C,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,MAAM,CAAC;AACxC,MAAM,WAAW,cAAc;IAAG,OAAO,EAAE,KAAK,CAAC;IAAC,EAAE,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE;AACnG,MAAM,WAAW,mBAAmB;IAAG,OAAO,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE;AACzF,MAAM,WAAW,YAAY;IAAG,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE;AAC/E,MAAM,WAAW,eAAe;IAAG,OAAO,EAAE,KAAK,CAAC;IAAC,EAAE,EAAE,SAAS,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,YAAY,CAAA;CAAE;AAC1G,MAAM,MAAM,cAAc,GAAG,cAAc,GAAG,mBAAmB,GAAG,eAAe,CAAC;AAEpF,eAAO,MAAM,SAAS,MAAO,cAAc,KAAG,CAAC,IAAI,cAAsF,CAAC;AAC1I,eAAO,MAAM,cAAc,MAAO,cAAc,KAAG,CAAC,IAAI,mBAA8E,CAAC;AACvI,eAAO,MAAM,UAAU,MAAO,cAAc,KAAG,CAAC,IAAI,eAAgD,CAAC;AAIrG,MAAM,WAAW,cAAc;IAAG,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE;AAElF;6GAC6G;AAC7G,MAAM,WAAW,kBAAkB;IACjC,EAAE,CAAC,EAAE;QAAE,YAAY,CAAC,EAAE,OAAO,CAAC;QAAC,aAAa,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IACzD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AACD,MAAM,WAAW,iBAAiB;IAChC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,kBAAkB,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAC;QAAC,eAAe,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IACrF,eAAe,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,OAAO,CAAC;QAAC,GAAG,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;CACrD;AACD,MAAM,WAAW,iBAAiB;IAAG,eAAe,EAAE,MAAM,CAAC;IAAC,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IAAC,UAAU,CAAC,EAAE,cAAc,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE;AACrK,MAAM,WAAW,kBAAkB;IAAG,eAAe,EAAE,MAAM,CAAC;IAAC,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IAAC,SAAS,CAAC,EAAE,cAAc,CAAC;IAAC,WAAW,CAAC,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE;AAI5O,6GAA6G;AAC7G,MAAM,WAAW,cAAc;IAAG,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAC;IAAC,GAAG,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE;AAC/H,MAAM,WAAW,iBAAiB;IAAG,GAAG,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,cAAc,EAAE,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE;AACjH,MAAM,WAAW,kBAAkB;IAAG,SAAS,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,aAAa,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE;AACpI,MAAM,WAAW,kBAAkB;IAAG,SAAS,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,cAAc,EAAE,CAAA;CAAE;AAEpG,MAAM,MAAM,YAAY,GACpB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GACtF;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAC7G;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GACjF;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GACjD;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtD,MAAM,WAAW,aAAa;IAAG,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,YAAY,EAAE,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE;AAC7G,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,YAAY,GAAG,mBAAmB,GAAG,SAAS,GAAG,WAAW,CAAC;AACnG,MAAM,WAAW,cAAc;IAAG,UAAU,EAAE,UAAU,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE;AAC3F,MAAM,WAAW,kBAAkB;IAAG,SAAS,EAAE,MAAM,CAAA;CAAE;AAIzD,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,OAAO,GAAG,aAAa,GAAG,OAAO,CAAC;AAChI,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,aAAa,GAAG,WAAW,GAAG,QAAQ,CAAC;AAChF,MAAM,MAAM,eAAe,GACvB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,YAAY,CAAA;CAAE,GAC1C;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACxE;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC;AAC7C,MAAM,WAAW,QAAQ;IACvB,UAAU,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,QAAQ,CAAC;IAAC,MAAM,CAAC,EAAE,cAAc,CAAC;IAC5E,OAAO,CAAC,EAAE,eAAe,EAAE,CAAC;IAAC,SAAS,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC,CAAC;IACvF,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAC;CACzC;AACD,MAAM,WAAW,SAAS;IAAG,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IAAC,MAAM,EAAE,SAAS,GAAG,aAAa,GAAG,WAAW,CAAA;CAAE;AAEpI,MAAM,MAAM,aAAa,GACrB;IAAE,aAAa,EAAE,oBAAoB,CAAC;IAAC,OAAO,EAAE,YAAY,CAAA;CAAE,GAC9D;IAAE,aAAa,EAAE,qBAAqB,CAAC;IAAC,OAAO,EAAE,YAAY,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GACnF;IAAE,aAAa,EAAE,qBAAqB,CAAC;IAAC,OAAO,EAAE,YAAY,CAAA;CAAE,GAC/D,CAAC;IAAE,aAAa,EAAE,WAAW,CAAA;CAAE,GAAG,QAAQ,CAAC,GAC3C,CAAC;IAAE,aAAa,EAAE,kBAAkB,CAAA;CAAE,GAAG,OAAO,CAAC,QAAQ,CAAC,GAAG;IAAE,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC,GACpF;IAAE,aAAa,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,SAAS,EAAE,CAAA;CAAE,GAC/C;IAAE,aAAa,EAAE,2BAA2B,CAAC;IAAC,iBAAiB,EAAE,OAAO,EAAE,CAAA;CAAE,GAC5E;IAAE,aAAa,EAAE,qBAAqB,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,GAC/D;IAAE,aAAa,EAAE,cAAc,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GAC5G;IAAE,aAAa,EAAE,MAAM,CAAC;IAAC,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,CAAC;AACpD,MAAM,WAAW,mBAAmB;IAAG,SAAS,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,aAAa,CAAA;CAAE;AAIjF,MAAM,MAAM,oBAAoB,GAAG,YAAY,GAAG,cAAc,GAAG,aAAa,GAAG,eAAe,CAAC;AACnG,MAAM,WAAW,gBAAgB;IAAG,QAAQ,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,oBAAoB,CAAA;CAAE;AAChG,MAAM,WAAW,wBAAwB;IAAG,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,GAAG;QAAE,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IAAC,OAAO,EAAE,gBAAgB,EAAE,CAAA;CAAE;AAClJ,MAAM,MAAM,wBAAwB,GAAG;IAAE,OAAO,EAAE,UAAU,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,OAAO,EAAE,WAAW,CAAA;CAAE,CAAC;AAC5G,MAAM,WAAW,yBAAyB;IAAG,OAAO,EAAE,wBAAwB,CAAA;CAAE;AAEhF,iCAAiC;AACjC,eAAO,MAAM,WAAW;;;;;;;;;;CAUd,CAAC;AAEX,uFAAuF;AACvF,eAAO,MAAM,UAAU;;;;CAIb,CAAC"}
|
package/dist/protocol.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// THE AGENT CLIENT PROTOCOL, v1 — the wire an ACP-speaking agent (Claude Code, goose, Codex — general-purpose runtimes; the protocol grew up around coding agents, nothing in it is about code) speaks to the
|
|
2
|
+
// host that runs it: JSON-RPC 2.0 over the agent's stdio. Keys are camelCase; discriminator VALUES are snake_case
|
|
3
|
+
// (`sessionUpdate: 'agent_message_chunk'`). Only what the host binding uses is typed here, named as the protocol
|
|
4
|
+
// names it, so a reader can hold this file beside agentclientprotocol.com/protocol/schema and see the same words.
|
|
5
|
+
//
|
|
6
|
+
// What ACP IS in this substrate (spec 400 §5.1): client-to-agent — how a host drives an existing runtime it spawned. What
|
|
7
|
+
// it is NOT: agent-to-agent (that is A2A, the workspace's admitted surface) and never a place authority is decided
|
|
8
|
+
// (`session/request_permission` is a click; the workspace decides on chain).
|
|
9
|
+
/** The protocol version this binding speaks. An agent answering another MAJOR is refused, never coerced. */
|
|
10
|
+
export const ACP_PROTOCOL_VERSION = 1;
|
|
11
|
+
export const isRequest = (m) => 'method' in m && 'id' in m && m.id !== undefined;
|
|
12
|
+
export const isNotification = (m) => 'method' in m && m.id === undefined;
|
|
13
|
+
export const isResponse = (m) => !('method' in m) && 'id' in m;
|
|
14
|
+
/** The methods, spelled once. */
|
|
15
|
+
export const ACP_METHODS = {
|
|
16
|
+
initialize: 'initialize',
|
|
17
|
+
newSession: 'session/new',
|
|
18
|
+
loadSession: 'session/load',
|
|
19
|
+
prompt: 'session/prompt',
|
|
20
|
+
cancel: 'session/cancel',
|
|
21
|
+
update: 'session/update',
|
|
22
|
+
requestPermission: 'session/request_permission',
|
|
23
|
+
fsRead: 'fs/read_text_file',
|
|
24
|
+
fsWrite: 'fs/write_text_file',
|
|
25
|
+
};
|
|
26
|
+
/** JSON-RPC error codes this host answers with when it refuses an agent's callback. */
|
|
27
|
+
export const ACP_ERRORS = {
|
|
28
|
+
methodNotFound: -32601,
|
|
29
|
+
invalidParams: -32602,
|
|
30
|
+
internal: -32603,
|
|
31
|
+
};
|
|
32
|
+
//# sourceMappingURL=protocol.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocol.js","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAAA,8MAA8M;AAC9M,kHAAkH;AAClH,iHAAiH;AACjH,kHAAkH;AAClH,EAAE;AACF,0HAA0H;AAC1H,mHAAmH;AACnH,6EAA6E;AAE7E,4GAA4G;AAC5G,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAU,CAAC;AAW/C,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,CAAiB,EAAuB,EAAE,CAAC,QAAQ,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAK,CAAoB,CAAC,EAAE,KAAK,SAAS,CAAC;AAC1I,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAiB,EAA4B,EAAE,CAAC,QAAQ,IAAI,CAAC,IAAK,CAAoB,CAAC,EAAE,KAAK,SAAS,CAAC;AACvI,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,CAAiB,EAAwB,EAAE,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC;AA4ErG,iCAAiC;AACjC,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,UAAU,EAAE,YAAY;IACxB,UAAU,EAAE,aAAa;IACzB,WAAW,EAAE,cAAc;IAC3B,MAAM,EAAE,gBAAgB;IACxB,MAAM,EAAE,gBAAgB;IACxB,MAAM,EAAE,gBAAgB;IACxB,iBAAiB,EAAE,4BAA4B;IAC/C,MAAM,EAAE,mBAAmB;IAC3B,OAAO,EAAE,oBAAoB;CACrB,CAAC;AAEX,uFAAuF;AACvF,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,cAAc,EAAE,CAAC,KAAK;IACtB,aAAa,EAAE,CAAC,KAAK;IACrB,QAAQ,EAAE,CAAC,KAAK;CACR,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@agenticprimitives/acp",
|
|
3
|
+
"version": "0.0.0-alpha.2",
|
|
4
|
+
"description": "Agent Client Protocol (ACP) host binding: ADMIT an existing general-purpose runtime that speaks ACP (Claude Code, goose, Codex) as a workspace MEMBER, without a rewrite — whose every act in the workspace goes through the standard A2A surface as itself, under a revocable session wire (spec 400 W1 / spec 372 S3). ACP sits behind A2A; it is never a second authority model.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"exports": {
|
|
7
|
+
".": {
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"import": "./dist/index.js"
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
"LICENSE",
|
|
14
|
+
"dist",
|
|
15
|
+
"spec.md",
|
|
16
|
+
"README.md",
|
|
17
|
+
"bin"
|
|
18
|
+
],
|
|
19
|
+
"dependencies": {
|
|
20
|
+
"@agenticprimitives/types": "1.0.0-alpha.25"
|
|
21
|
+
},
|
|
22
|
+
"devDependencies": {
|
|
23
|
+
"vitest": "^4.1.8"
|
|
24
|
+
},
|
|
25
|
+
"publishConfig": {
|
|
26
|
+
"access": "public"
|
|
27
|
+
},
|
|
28
|
+
"license": "MIT",
|
|
29
|
+
"scripts": {
|
|
30
|
+
"build": "tsc -p tsconfig.build.json",
|
|
31
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
32
|
+
"test": "vitest run",
|
|
33
|
+
"test:unit": "vitest run test/unit --passWithNoTests",
|
|
34
|
+
"clean": "rm -rf dist"
|
|
35
|
+
}
|
|
36
|
+
}
|
package/spec.md
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# @agenticprimitives/acp — package spec
|
|
2
|
+
|
|
3
|
+
Spec of record: [specs/400-closing-the-workspace-gap-buzz-and-team-agent-platforms.md](../../specs/400-closing-the-workspace-gap-buzz-and-team-agent-platforms.md) §5
|
|
4
|
+
(W1: the ACP runtime member), on [specs/372-standard-a2a-surface-conformance-and-outsiders.md](../../specs/372-standard-a2a-surface-conformance-and-outsiders.md) S3
|
|
5
|
+
(the authority half: a `.svc` member, its session wire, speaking as itself).
|
|
6
|
+
|
|
7
|
+
Owns the ACP v1 protocol types and the host that runs an ACP agent as a child process: handshake (another major
|
|
8
|
+
version refused), sessions (`session/new`, `session/load` when the agent can), prompt turns with the streamed
|
|
9
|
+
`session/update`s, `session/request_permission` answered by a policy port (workspace tools allowed — the workspace
|
|
10
|
+
decides on chain; local tools refused by default), no host-machine capabilities offered. Does not own the workspace
|
|
11
|
+
MCP server, pairing, the inbound-work poll, the CLI, or any authority artifact. An optional transport binding
|
|
12
|
+
(ADR-0057): depends inward only.
|