@agentconnect.md/daemon 1.0.0-rc.322 → 1.0.0-rc.324

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.
@@ -1,4 +1,4 @@
1
- import { o as loadConfig, t as discoverAgents } from "./load-agents-CROyMyq9.js";
1
+ import { o as loadConfig, t as discoverAgents } from "./load-agents-CuXy_Ei1.js";
2
2
  //#region src/cli/agent-list.ts
3
3
  async function runAgentList(opts) {
4
4
  const out = opts.out ?? process.stdout;
@@ -18,4 +18,4 @@ async function runAgentList(opts) {
18
18
  //#endregion
19
19
  export { runAgentList };
20
20
 
21
- //# sourceMappingURL=agent-list-Cs_EgUh5.js.map
21
+ //# sourceMappingURL=agent-list-CE6JNwIB.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"agent-list-Cs_EgUh5.js","names":[],"sources":["../src/cli/agent-list.ts"],"sourcesContent":["import { loadConfig } from '../config/load-config.js'\nimport { discoverAgents } from '../agents/load-agents.js'\n\nexport interface RunAgentListOpts {\n agentsDir?: string\n configPath?: string\n root?: string\n out?: NodeJS.WritableStream\n}\n\n// Read-only view of the local agent directory. Mutating agents (add/remove/\n// enable/disable) is intentionally not a CLI command — agent business config is\n// owned by the Control Plane (agent/upsert + register/ok roster, see\n// cp/cp-agent-registry.ts) or by hand-editing agent.json; the daemon only\n// reconciles what it finds on disk. This lists what that discovery sees.\nexport async function runAgentList(opts: RunAgentListOpts): Promise<void> {\n const out = opts.out ?? process.stdout\n const cfg = loadConfig({\n root: opts.root,\n configPath: opts.configPath,\n optional: true,\n overrides: { agentsDir: opts.agentsDir }\n })\n const agentsDir = cfg.agentsDir!\n const discovered = discoverAgents(agentsDir)\n if (discovered.length === 0) {\n out.write(`no agents found under ${agentsDir}\\n`)\n return\n }\n for (const { agent, dir } of discovered) {\n out.write(`${agent.id}\\t${agent.status}\\t${agent.runtime}\\t${agent.name}\\t${dir}\\n`)\n }\n}\n"],"mappings":";;AAeA,eAAsB,aAAa,MAAuC;CACxE,MAAM,MAAM,KAAK,OAAO,QAAQ;CAOhC,MAAM,YANM,WAAW;EACrB,MAAM,KAAK;EACX,YAAY,KAAK;EACjB,UAAU;EACV,WAAW,EAAE,WAAW,KAAK,UAAU;CACzC,CACoB,CAAC,CAAC;CACtB,MAAM,aAAa,eAAe,SAAS;CAC3C,IAAI,WAAW,WAAW,GAAG;EAC3B,IAAI,MAAM,yBAAyB,UAAU,GAAG;EAChD;CACF;CACA,KAAK,MAAM,EAAE,OAAO,SAAS,YAC3B,IAAI,MAAM,GAAG,MAAM,GAAG,IAAI,MAAM,OAAO,IAAI,MAAM,QAAQ,IAAI,MAAM,KAAK,IAAI,IAAI,GAAG;AAEvF"}
1
+ {"version":3,"file":"agent-list-CE6JNwIB.js","names":[],"sources":["../src/cli/agent-list.ts"],"sourcesContent":["import { loadConfig } from '../config/load-config.js'\nimport { discoverAgents } from '../agents/load-agents.js'\n\nexport interface RunAgentListOpts {\n agentsDir?: string\n configPath?: string\n root?: string\n out?: NodeJS.WritableStream\n}\n\n// Read-only view of the local agent directory. Mutating agents (add/remove/\n// enable/disable) is intentionally not a CLI command — agent business config is\n// owned by the Control Plane (agent/upsert + register/ok roster, see\n// cp/cp-agent-registry.ts) or by hand-editing agent.json; the daemon only\n// reconciles what it finds on disk. This lists what that discovery sees.\nexport async function runAgentList(opts: RunAgentListOpts): Promise<void> {\n const out = opts.out ?? process.stdout\n const cfg = loadConfig({\n root: opts.root,\n configPath: opts.configPath,\n optional: true,\n overrides: { agentsDir: opts.agentsDir }\n })\n const agentsDir = cfg.agentsDir!\n const discovered = discoverAgents(agentsDir)\n if (discovered.length === 0) {\n out.write(`no agents found under ${agentsDir}\\n`)\n return\n }\n for (const { agent, dir } of discovered) {\n out.write(`${agent.id}\\t${agent.status}\\t${agent.runtime}\\t${agent.name}\\t${dir}\\n`)\n }\n}\n"],"mappings":";;AAeA,eAAsB,aAAa,MAAuC;CACxE,MAAM,MAAM,KAAK,OAAO,QAAQ;CAOhC,MAAM,YANM,WAAW;EACrB,MAAM,KAAK;EACX,YAAY,KAAK;EACjB,UAAU;EACV,WAAW,EAAE,WAAW,KAAK,UAAU;CACzC,CACoB,CAAC,CAAC;CACtB,MAAM,aAAa,eAAe,SAAS;CAC3C,IAAI,WAAW,WAAW,GAAG;EAC3B,IAAI,MAAM,yBAAyB,UAAU,GAAG;EAChD;CACF;CACA,KAAK,MAAM,EAAE,OAAO,SAAS,YAC3B,IAAI,MAAM,GAAG,MAAM,GAAG,IAAI,MAAM,OAAO,IAAI,MAAM,QAAQ,IAAI,MAAM,KAAK,IAAI,IAAI,GAAG;AAEvF"}
@@ -1,6 +1,6 @@
1
- import { a as agentChildEnv, i as selectAgent, o as loadConfig } from "./load-agents-CROyMyq9.js";
1
+ import { a as agentChildEnv, i as selectAgent, o as loadConfig } from "./load-agents-CuXy_Ei1.js";
2
2
  import { l as resolveRoot } from "./paths-DEcUO8lC.js";
3
- import { a as prepareWorkspace, f as memoryProviderFor, t as AcpHost, w as resolveRuntimes } from "./acp-host-Dsm0i9DH.js";
3
+ import { T as resolveRuntimes, a as prepareWorkspace, f as memoryProviderFor, t as AcpHost } from "./acp-host-DKkoWiWe.js";
4
4
  import { createInterface } from "node:readline";
5
5
  //#region src/cli/chat.ts
6
6
  function renderUpdate(out) {
@@ -84,4 +84,4 @@ async function runChat(opts) {
84
84
  //#endregion
85
85
  export { renderUpdate, runChat };
86
86
 
87
- //# sourceMappingURL=chat-Cq-5NzYK.js.map
87
+ //# sourceMappingURL=chat-lv_zfcAK.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"chat-Cq-5NzYK.js","names":[],"sources":["../src/cli/chat.ts"],"sourcesContent":["import { createInterface } from 'node:readline'\nimport type { ContentBlock, SessionUpdate } from '@agentclientprotocol/sdk'\nimport { loadConfig } from '../config/load-config.js'\nimport { resolveRuntimes } from '../runtimes/registry.js'\nimport { selectAgent } from '../agents/load-agents.js'\nimport { agentChildEnv } from '../agents/agent-env.js'\nimport { memoryProviderFor } from '../agents/memory-provider.js'\nimport { prepareWorkspace } from '../workspace/workspace-manager.js'\nimport { AcpHost } from '../acp/acp-host.js'\nimport { resolveRoot } from '../paths.js'\n\nexport function renderUpdate(out: NodeJS.WritableStream) {\n return (_sessionId: string, update: SessionUpdate): void => {\n if (update.sessionUpdate === 'agent_message_chunk' && update.content.type === 'text') {\n out.write(update.content.text)\n } else if (update.sessionUpdate === 'tool_call') {\n const title = ('title' in update && update.title) || update.toolCallId || 'tool'\n out.write(`\\n[tool] ${title}\\n`)\n }\n }\n}\n\nexport interface RunChatOpts {\n agentsDir?: string\n agentName?: string\n message?: string\n configPath?: string\n root?: string\n out?: NodeJS.WritableStream\n input?: NodeJS.ReadableStream\n}\n\nexport async function runChat(opts: RunChatOpts): Promise<void> {\n const out = opts.out ?? process.stdout\n const root = resolveRoot(opts.root)\n const cfg = loadConfig({\n root: opts.root,\n configPath: opts.configPath,\n optional: true,\n overrides: { agentsDir: opts.agentsDir }\n })\n const agent = selectAgent(cfg.agentsDir!, opts.agentName)\n\n const runtimes = await resolveRuntimes(cfg, root, { neededRuntimes: [agent.runtime], mode: 'cache-first' })\n const runtime = runtimes[agent.runtime]\n if (!runtime) {\n const available = Object.keys(runtimes).sort().join(', ') || '(none)'\n throw new Error(`runtime \"${agent.runtime}\" not found. Available: ${available}`)\n }\n\n const host = new AcpHost(runtime, {\n onUpdate: renderUpdate(out),\n // Memory-backend env for parity with the daemon (managed disables the runtime's\n // own memory; native redirects it under the agent root).\n env: { ...agentChildEnv(agent), ...memoryProviderFor(agent, runtime).runtimeEnv() },\n configPrefs: {\n model: agent.runtimeOverrides?.model,\n permissionMode: agent.permissionMode,\n reasoningEffort: agent.reasoningEffort,\n fastMode: agent.fastMode\n }\n })\n // The adapter child runs in its own process group (see AcpHost.start), so a\n // terminal Ctrl-C no longer kills it as a side effect — Node's default SIGINT\n // exit would skip the finally below and leak it. Stop the host, then re-exit.\n // Registered BEFORE start(): a first-run `npx -y` runtime download takes long\n // enough that Ctrl-C mid-start is common, and the spawn happens early in start().\n const onSigint = () => {\n void host.stop().finally(() => process.exit(130))\n }\n process.once('SIGINT', onSigint)\n try {\n await host.start()\n const cwd = await prepareWorkspace(agent)\n const sessionId = await host.newSession(cwd)\n\n const send = async (text: string) => {\n const blocks: ContentBlock[] = [{ type: 'text', text }]\n await host.prompt(sessionId, blocks)\n out.write('\\n')\n }\n\n if (typeof opts.message === 'string' && opts.message.length > 0) {\n await send(opts.message)\n return\n }\n\n const rl = createInterface({ input: opts.input ?? process.stdin })\n out.write(`Chatting with ${agent.name} (${agent.id}). Type .exit to quit.\\n> `)\n try {\n for await (const line of rl) {\n const text = line.trim()\n if (text === '.exit' || text === '.quit') break\n if (text.length > 0) await send(text)\n out.write('> ')\n }\n } finally {\n rl.close()\n }\n } finally {\n process.removeListener('SIGINT', onSigint)\n await host.stop()\n }\n}\n"],"mappings":";;;;;AAWA,SAAgB,aAAa,KAA4B;CACvD,QAAQ,YAAoB,WAAgC;EAC1D,IAAI,OAAO,kBAAkB,yBAAyB,OAAO,QAAQ,SAAS,QAC5E,IAAI,MAAM,OAAO,QAAQ,IAAI;OACxB,IAAI,OAAO,kBAAkB,aAAa;GAC/C,MAAM,QAAS,WAAW,UAAU,OAAO,SAAU,OAAO,cAAc;GAC1E,IAAI,MAAM,YAAY,MAAM,GAAG;EACjC;CACF;AACF;AAYA,eAAsB,QAAQ,MAAkC;CAC9D,MAAM,MAAM,KAAK,OAAO,QAAQ;CAChC,MAAM,OAAO,YAAY,KAAK,IAAI;CAClC,MAAM,MAAM,WAAW;EACrB,MAAM,KAAK;EACX,YAAY,KAAK;EACjB,UAAU;EACV,WAAW,EAAE,WAAW,KAAK,UAAU;CACzC,CAAC;CACD,MAAM,QAAQ,YAAY,IAAI,WAAY,KAAK,SAAS;CAExD,MAAM,WAAW,MAAM,gBAAgB,KAAK,MAAM;EAAE,gBAAgB,CAAC,MAAM,OAAO;EAAG,MAAM;CAAc,CAAC;CAC1G,MAAM,UAAU,SAAS,MAAM;CAC/B,IAAI,CAAC,SAAS;EACZ,MAAM,YAAY,OAAO,KAAK,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,IAAI,KAAK;EAC7D,MAAM,IAAI,MAAM,YAAY,MAAM,QAAQ,0BAA0B,WAAW;CACjF;CAEA,MAAM,OAAO,IAAI,QAAQ,SAAS;EAChC,UAAU,aAAa,GAAG;EAG1B,KAAK;GAAE,GAAG,cAAc,KAAK;GAAG,GAAG,kBAAkB,OAAO,OAAO,CAAC,CAAC,WAAW;EAAE;EAClF,aAAa;GACX,OAAO,MAAM,kBAAkB;GAC/B,gBAAgB,MAAM;GACtB,iBAAiB,MAAM;GACvB,UAAU,MAAM;EAClB;CACF,CAAC;CAMD,MAAM,iBAAiB;EACrB,KAAU,KAAK,CAAC,CAAC,cAAc,QAAQ,KAAK,GAAG,CAAC;CAClD;CACA,QAAQ,KAAK,UAAU,QAAQ;CAC/B,IAAI;EACF,MAAM,KAAK,MAAM;EACjB,MAAM,MAAM,MAAM,iBAAiB,KAAK;EACxC,MAAM,YAAY,MAAM,KAAK,WAAW,GAAG;EAE3C,MAAM,OAAO,OAAO,SAAiB;GACnC,MAAM,SAAyB,CAAC;IAAE,MAAM;IAAQ;GAAK,CAAC;GACtD,MAAM,KAAK,OAAO,WAAW,MAAM;GACnC,IAAI,MAAM,IAAI;EAChB;EAEA,IAAI,OAAO,KAAK,YAAY,YAAY,KAAK,QAAQ,SAAS,GAAG;GAC/D,MAAM,KAAK,KAAK,OAAO;GACvB;EACF;EAEA,MAAM,KAAK,gBAAgB,EAAE,OAAO,KAAK,SAAS,QAAQ,MAAM,CAAC;EACjE,IAAI,MAAM,iBAAiB,MAAM,KAAK,IAAI,MAAM,GAAG,2BAA2B;EAC9E,IAAI;GACF,WAAW,MAAM,QAAQ,IAAI;IAC3B,MAAM,OAAO,KAAK,KAAK;IACvB,IAAI,SAAS,WAAW,SAAS,SAAS;IAC1C,IAAI,KAAK,SAAS,GAAG,MAAM,KAAK,IAAI;IACpC,IAAI,MAAM,IAAI;GAChB;EACF,UAAU;GACR,GAAG,MAAM;EACX;CACF,UAAU;EACR,QAAQ,eAAe,UAAU,QAAQ;EACzC,MAAM,KAAK,KAAK;CAClB;AACF"}
1
+ {"version":3,"file":"chat-lv_zfcAK.js","names":[],"sources":["../src/cli/chat.ts"],"sourcesContent":["import { createInterface } from 'node:readline'\nimport type { ContentBlock, SessionUpdate } from '@agentclientprotocol/sdk'\nimport { loadConfig } from '../config/load-config.js'\nimport { resolveRuntimes } from '../runtimes/registry.js'\nimport { selectAgent } from '../agents/load-agents.js'\nimport { agentChildEnv } from '../agents/agent-env.js'\nimport { memoryProviderFor } from '../agents/memory-provider.js'\nimport { prepareWorkspace } from '../workspace/workspace-manager.js'\nimport { AcpHost } from '../acp/acp-host.js'\nimport { resolveRoot } from '../paths.js'\n\nexport function renderUpdate(out: NodeJS.WritableStream) {\n return (_sessionId: string, update: SessionUpdate): void => {\n if (update.sessionUpdate === 'agent_message_chunk' && update.content.type === 'text') {\n out.write(update.content.text)\n } else if (update.sessionUpdate === 'tool_call') {\n const title = ('title' in update && update.title) || update.toolCallId || 'tool'\n out.write(`\\n[tool] ${title}\\n`)\n }\n }\n}\n\nexport interface RunChatOpts {\n agentsDir?: string\n agentName?: string\n message?: string\n configPath?: string\n root?: string\n out?: NodeJS.WritableStream\n input?: NodeJS.ReadableStream\n}\n\nexport async function runChat(opts: RunChatOpts): Promise<void> {\n const out = opts.out ?? process.stdout\n const root = resolveRoot(opts.root)\n const cfg = loadConfig({\n root: opts.root,\n configPath: opts.configPath,\n optional: true,\n overrides: { agentsDir: opts.agentsDir }\n })\n const agent = selectAgent(cfg.agentsDir!, opts.agentName)\n\n const runtimes = await resolveRuntimes(cfg, root, { neededRuntimes: [agent.runtime], mode: 'cache-first' })\n const runtime = runtimes[agent.runtime]\n if (!runtime) {\n const available = Object.keys(runtimes).sort().join(', ') || '(none)'\n throw new Error(`runtime \"${agent.runtime}\" not found. Available: ${available}`)\n }\n\n const host = new AcpHost(runtime, {\n onUpdate: renderUpdate(out),\n // Memory-backend env for parity with the daemon (managed disables the runtime's\n // own memory; native redirects it under the agent root).\n env: { ...agentChildEnv(agent), ...memoryProviderFor(agent, runtime).runtimeEnv() },\n configPrefs: {\n model: agent.runtimeOverrides?.model,\n permissionMode: agent.permissionMode,\n reasoningEffort: agent.reasoningEffort,\n fastMode: agent.fastMode\n }\n })\n // The adapter child runs in its own process group (see AcpHost.start), so a\n // terminal Ctrl-C no longer kills it as a side effect — Node's default SIGINT\n // exit would skip the finally below and leak it. Stop the host, then re-exit.\n // Registered BEFORE start(): a first-run `npx -y` runtime download takes long\n // enough that Ctrl-C mid-start is common, and the spawn happens early in start().\n const onSigint = () => {\n void host.stop().finally(() => process.exit(130))\n }\n process.once('SIGINT', onSigint)\n try {\n await host.start()\n const cwd = await prepareWorkspace(agent)\n const sessionId = await host.newSession(cwd)\n\n const send = async (text: string) => {\n const blocks: ContentBlock[] = [{ type: 'text', text }]\n await host.prompt(sessionId, blocks)\n out.write('\\n')\n }\n\n if (typeof opts.message === 'string' && opts.message.length > 0) {\n await send(opts.message)\n return\n }\n\n const rl = createInterface({ input: opts.input ?? process.stdin })\n out.write(`Chatting with ${agent.name} (${agent.id}). Type .exit to quit.\\n> `)\n try {\n for await (const line of rl) {\n const text = line.trim()\n if (text === '.exit' || text === '.quit') break\n if (text.length > 0) await send(text)\n out.write('> ')\n }\n } finally {\n rl.close()\n }\n } finally {\n process.removeListener('SIGINT', onSigint)\n await host.stop()\n }\n}\n"],"mappings":";;;;;AAWA,SAAgB,aAAa,KAA4B;CACvD,QAAQ,YAAoB,WAAgC;EAC1D,IAAI,OAAO,kBAAkB,yBAAyB,OAAO,QAAQ,SAAS,QAC5E,IAAI,MAAM,OAAO,QAAQ,IAAI;OACxB,IAAI,OAAO,kBAAkB,aAAa;GAC/C,MAAM,QAAS,WAAW,UAAU,OAAO,SAAU,OAAO,cAAc;GAC1E,IAAI,MAAM,YAAY,MAAM,GAAG;EACjC;CACF;AACF;AAYA,eAAsB,QAAQ,MAAkC;CAC9D,MAAM,MAAM,KAAK,OAAO,QAAQ;CAChC,MAAM,OAAO,YAAY,KAAK,IAAI;CAClC,MAAM,MAAM,WAAW;EACrB,MAAM,KAAK;EACX,YAAY,KAAK;EACjB,UAAU;EACV,WAAW,EAAE,WAAW,KAAK,UAAU;CACzC,CAAC;CACD,MAAM,QAAQ,YAAY,IAAI,WAAY,KAAK,SAAS;CAExD,MAAM,WAAW,MAAM,gBAAgB,KAAK,MAAM;EAAE,gBAAgB,CAAC,MAAM,OAAO;EAAG,MAAM;CAAc,CAAC;CAC1G,MAAM,UAAU,SAAS,MAAM;CAC/B,IAAI,CAAC,SAAS;EACZ,MAAM,YAAY,OAAO,KAAK,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,IAAI,KAAK;EAC7D,MAAM,IAAI,MAAM,YAAY,MAAM,QAAQ,0BAA0B,WAAW;CACjF;CAEA,MAAM,OAAO,IAAI,QAAQ,SAAS;EAChC,UAAU,aAAa,GAAG;EAG1B,KAAK;GAAE,GAAG,cAAc,KAAK;GAAG,GAAG,kBAAkB,OAAO,OAAO,CAAC,CAAC,WAAW;EAAE;EAClF,aAAa;GACX,OAAO,MAAM,kBAAkB;GAC/B,gBAAgB,MAAM;GACtB,iBAAiB,MAAM;GACvB,UAAU,MAAM;EAClB;CACF,CAAC;CAMD,MAAM,iBAAiB;EACrB,KAAU,KAAK,CAAC,CAAC,cAAc,QAAQ,KAAK,GAAG,CAAC;CAClD;CACA,QAAQ,KAAK,UAAU,QAAQ;CAC/B,IAAI;EACF,MAAM,KAAK,MAAM;EACjB,MAAM,MAAM,MAAM,iBAAiB,KAAK;EACxC,MAAM,YAAY,MAAM,KAAK,WAAW,GAAG;EAE3C,MAAM,OAAO,OAAO,SAAiB;GACnC,MAAM,SAAyB,CAAC;IAAE,MAAM;IAAQ;GAAK,CAAC;GACtD,MAAM,KAAK,OAAO,WAAW,MAAM;GACnC,IAAI,MAAM,IAAI;EAChB;EAEA,IAAI,OAAO,KAAK,YAAY,YAAY,KAAK,QAAQ,SAAS,GAAG;GAC/D,MAAM,KAAK,KAAK,OAAO;GACvB;EACF;EAEA,MAAM,KAAK,gBAAgB,EAAE,OAAO,KAAK,SAAS,QAAQ,MAAM,CAAC;EACjE,IAAI,MAAM,iBAAiB,MAAM,KAAK,IAAI,MAAM,GAAG,2BAA2B;EAC9E,IAAI;GACF,WAAW,MAAM,QAAQ,IAAI;IAC3B,MAAM,OAAO,KAAK,KAAK;IACvB,IAAI,SAAS,WAAW,SAAS,SAAS;IAC1C,IAAI,KAAK,SAAS,GAAG,MAAM,KAAK,IAAI;IACpC,IAAI,MAAM,IAAI;GAChB;EACF,UAAU;GACR,GAAG,MAAM;EACX;CACF,UAAU;EACR,QAAQ,eAAe,UAAU,QAAQ;EACzC,MAAM,KAAK,KAAK;CAClB;AACF"}
@@ -438,6 +438,7 @@ const RESERVED_MCP_SERVER_NAME = "agentconnect";
438
438
  */
439
439
  const AgentSpec = object({
440
440
  name: string(),
441
+ displayName: string().nullable().optional(),
441
442
  description: string().optional(),
442
443
  runtime: string().optional(),
443
444
  model: string().nullable().optional(),
@@ -632,6 +633,7 @@ const RelayRosterEntry = object({
632
633
  const RelayRosterUpdate = object({ relays: array(RelayRosterEntry) });
633
634
  const RegisterOk = object({
634
635
  routingEpoch: number().int(),
636
+ serverFeatures: array(string()).default([]),
635
637
  assignments: array(RouteAssign),
636
638
  agents: array(AgentSpec.extend({ agentId: string().uuid() })).default([]),
637
639
  crons: array(CronUpsert),
@@ -649,6 +651,119 @@ const RegisterOk = object({
649
651
  });
650
652
  //#endregion
651
653
  //#region ../protocol/dist/frames/hook.js
654
+ /** Decimal wire form for Prisma/GitHub bigint values. */
655
+ const HookBigIntString = string().regex(/^(?:0|[1-9]\d*)$/);
656
+ /** The highest formal-review event one hook permits. */
657
+ const HookReviewPolicy = _enum([
658
+ "off",
659
+ "comment",
660
+ "request_changes",
661
+ "full"
662
+ ]);
663
+ /** External run-reporting transport. `status` is reserved for the later R3. */
664
+ const HookReportingMode = _enum([
665
+ "off",
666
+ "check",
667
+ "status"
668
+ ]);
669
+ /** R2a only admits informational; `required` remains a fail-closed future mode. */
670
+ const HookGateMode = _enum(["informational", "required"]);
671
+ /**
672
+ * Exact config + dispatch identity captured when the CP compiles a hook fire.
673
+ *
674
+ * The relay-facing frames expose these fields individually at top level so an
675
+ * older CP/relay can omit them without making the whole fire undecodable. A
676
+ * consumer MUST have every field before enabling review/reporting; absence is
677
+ * not filled with a revision and therefore fails closed. Action-time RPCs use
678
+ * this complete object so a partially rolled-out tuple cannot authorize an
679
+ * effect.
680
+ */
681
+ const HookConfigSnapshot = object({
682
+ configRevision: HookBigIntString,
683
+ dispatchRevision: HookBigIntString,
684
+ dispatchDaemonId: string().uuid(),
685
+ reviewPolicy: HookReviewPolicy,
686
+ reportingMode: HookReportingMode,
687
+ gateMode: HookGateMode
688
+ });
689
+ /** Optional top-level form used only on rolling-compatible delivery frames. */
690
+ const OptionalHookConfigSnapshot = HookConfigSnapshot.partial();
691
+ /**
692
+ * Trusted, body-free GitHub subject/revision metadata. It is deliberately
693
+ * separate from HookContext: HookContext contains attacker-authored prompt
694
+ * excerpts, whereas this object is cut from a signature-verified payload and
695
+ * fenced to the CP-compiled numeric repo/installation rule.
696
+ *
697
+ * `headSha` is absent for PR issue_comment deliveries because GitHub omits the
698
+ * revision there; the daemon resolves it before `hook/start`. R2a informational
699
+ * checks use `reportSha=headSha` once known.
700
+ */
701
+ const GithubHookMetadata = object({
702
+ repoId: HookBigIntString,
703
+ repoFullName: string().min(1),
704
+ sourceInstallationId: HookBigIntString,
705
+ subjectKind: _enum(["issue", "pull_request"]),
706
+ pullNumber: number().int().positive().optional(),
707
+ headSha: string().min(1).optional(),
708
+ baseSha: string().min(1).optional(),
709
+ reportSha: string().min(1).optional(),
710
+ headRepoFullName: string().min(1).optional(),
711
+ mergeCommitSha: string().min(1).optional(),
712
+ isDraft: boolean().optional(),
713
+ baseChanged: boolean().optional()
714
+ }).superRefine((value, ctx) => {
715
+ if (value.subjectKind === "pull_request" && value.pullNumber === void 0) ctx.addIssue({
716
+ code: "custom",
717
+ path: ["pullNumber"],
718
+ message: "pullNumber is required for a pull_request subject"
719
+ });
720
+ if (value.reportSha !== void 0 && value.headSha === void 0) ctx.addIssue({
721
+ code: "custom",
722
+ path: ["reportSha"],
723
+ message: "reportSha requires an authoritative headSha"
724
+ });
725
+ if (value.reportSha !== void 0 && value.headSha !== void 0 && value.reportSha !== value.headSha) ctx.addIssue({
726
+ code: "custom",
727
+ path: ["reportSha"],
728
+ message: "R2a reports only the authoritative pull head SHA"
729
+ });
730
+ });
731
+ const HookReviewEvent = _enum([
732
+ "COMMENT",
733
+ "REQUEST_CHANGES",
734
+ "APPROVE"
735
+ ]);
736
+ const HookReviewVerdict = _enum([
737
+ "pass",
738
+ "fail",
739
+ "neutral"
740
+ ]);
741
+ /** Short machine code only; raw GitHub/runtime exception text never crosses to reporting. */
742
+ const HookReviewResultCode = string().min(1).max(100).regex(/^[a-z0-9_:-]+$/);
743
+ /**
744
+ * Body-free outcome of one reserved formal-review attempt.
745
+ *
746
+ * `not_submitted` is only legal after a deterministic no-effect failure and
747
+ * lets the CP release the reservation. An uncertain POST remains `ambiguous`
748
+ * until marker reconciliation proves whether GitHub created it.
749
+ */
750
+ const HookReviewResult = discriminatedUnion("state", [
751
+ object({
752
+ state: literal("submitted"),
753
+ reviewId: string().min(1),
754
+ event: HookReviewEvent,
755
+ verdict: HookReviewVerdict,
756
+ commitId: string().min(1)
757
+ }),
758
+ object({
759
+ state: literal("not_submitted"),
760
+ code: HookReviewResultCode
761
+ }),
762
+ object({
763
+ state: literal("ambiguous"),
764
+ code: HookReviewResultCode
765
+ })
766
+ ]);
652
767
  /**
653
768
  * Hook (inbound-webhook trigger) frames — webhook-triggers-and-github-events.md.
654
769
  *
@@ -657,8 +772,8 @@ const RegisterOk = object({
657
772
  * (`rc/hook-assign`, frames/relay-cp.ts); the relay pool is the public ingress
658
773
  * that verifies + matches + dispatches the trigger to the target daemon as an
659
774
  * `rd/msg` `hook` member (frames/relay-daemon.ts). Event payloads never touch
660
- * the CP — the only hook frame on the daemon↔CP control WS is the completion
661
- * report below (pure metadata, mirroring `cron/report`).
775
+ * the CP. R1/R2a add only metadata barriers and action-result control frames;
776
+ * the model-visible body remains relay↔daemon.
662
777
  */
663
778
  /**
664
779
  * The trimmed event envelope a fire carries — bounded excerpts only; the full
@@ -685,21 +800,81 @@ const HookContext = object({
685
800
  truncated: boolean().optional()
686
801
  });
687
802
  /**
688
- * `hook/report` (D→C EVT, fire-and-forget) — the dispatched turn ended; closes
803
+ * `hook/report` (D→C REQ → generic `ack`) — the dispatched turn ended; closes
689
804
  * the `HookRun` row the relay's `rc/run-report` opened. Same discipline as
690
805
  * `cron/report`: scoped (the agent must be placed on the reporting daemon),
691
806
  * latest-wins, lost reports harvested by the HookRunReaper (late arrivals may
692
- * still overwrite `orphaned`). Keyed by `(hookId, deliveryKey)`.
807
+ * still overwrite `orphaned`). The daemon retains a metadata-only outbox entry
808
+ * until ACK. Keyed by `(hookId, deliveryKey)`.
693
809
  */
694
810
  const HookReport = object({
695
811
  hookId: string().uuid(),
696
812
  agentId: string().uuid(),
697
813
  deliveryKey: string().min(1),
814
+ ...OptionalHookConfigSnapshot.shape,
815
+ event: string().min(1).optional(),
816
+ github: GithubHookMetadata.optional(),
698
817
  status: _enum(["success", "failed"]),
699
818
  durationMs: number().int().nonnegative().optional(),
700
819
  sessionId: string().optional(),
701
- reason: string().optional()
820
+ reason: string().optional(),
821
+ reviewAttemptId: string().uuid().optional(),
822
+ reviewResult: HookReviewResult.optional()
823
+ }).superRefine((report, ctx) => {
824
+ if (report.reviewAttemptId === void 0 !== (report.reviewResult === void 0)) ctx.addIssue({
825
+ code: "custom",
826
+ path: report.reviewAttemptId === void 0 ? ["reviewAttemptId"] : ["reviewResult"],
827
+ message: "reviewAttemptId and reviewResult must be reported together"
828
+ });
829
+ });
830
+ /**
831
+ * `hook/start` (D→C REQ) — metadata barrier immediately before an accepted
832
+ * GitHub hook enters the model prompt. A successful reply means the CP durably
833
+ * attached the authoritative revision to the accepted HookRun and, for R2a,
834
+ * advanced its informational projection to in_progress.
835
+ */
836
+ const HookStart = object({
837
+ hookId: string().uuid(),
838
+ agentId: string().uuid(),
839
+ deliveryKey: string().min(1),
840
+ event: string().min(1).optional(),
841
+ github: GithubHookMetadata,
842
+ ...HookConfigSnapshot.shape
843
+ });
844
+ const HookStartOk = object({ accepted: literal(true) });
845
+ /** D→C action-time authorization for one formal GitHub review attempt. */
846
+ const GithubReviewAuthorize = object({
847
+ hookId: string().uuid(),
848
+ deliveryKey: string().min(1),
849
+ attemptId: string().uuid(),
850
+ requestedEvent: HookReviewEvent,
851
+ requestedVerdict: HookReviewVerdict,
852
+ snapshot: HookConfigSnapshot
853
+ });
854
+ /** Trusted target echoed with a broker-only purpose token. Secret: never log. */
855
+ const GithubReviewAuthorized = object({
856
+ attemptId: string().uuid(),
857
+ token: string().min(1),
858
+ ttlSec: number().int().positive(),
859
+ expiresAt: string().datetime(),
860
+ repoId: HookBigIntString,
861
+ repoFullName: string().min(1),
862
+ pullNumber: number().int().positive(),
863
+ expectedHeadSha: string().min(1),
864
+ expectedBaseSha: string().min(1)
702
865
  });
866
+ /**
867
+ * Immediate metadata-only convergence after the daemon's GitHub review POST.
868
+ * Submitted metadata is also repeated on HookReport for lost-REP recovery.
869
+ */
870
+ const GithubReviewResultReport = object({
871
+ hookId: string().uuid(),
872
+ deliveryKey: string().min(1),
873
+ attemptId: string().uuid(),
874
+ snapshot: HookConfigSnapshot,
875
+ result: HookReviewResult
876
+ });
877
+ const GithubReviewResultOk = object({ accepted: literal(true) });
703
878
  //#endregion
704
879
  //#region ../protocol/dist/frames/gitcred.js
705
880
  /**
@@ -1394,6 +1569,12 @@ const FRAME_SCHEMAS = {
1394
1569
  "cron/report": CronReport,
1395
1570
  "cron/run": CronRunNow,
1396
1571
  "hook/report": HookReport,
1572
+ "hook/start": HookStart,
1573
+ "hook/start/ok": HookStartOk,
1574
+ "github/review-authorize": GithubReviewAuthorize,
1575
+ "github/review-authorized": GithubReviewAuthorized,
1576
+ "github/review-result": GithubReviewResultReport,
1577
+ "github/review-result/ok": GithubReviewResultOk,
1397
1578
  "integration/upsert": IntegrationUpsert,
1398
1579
  "integration/remove": IntegrationRemove,
1399
1580
  "integration/channels": IntegrationChannels,
@@ -1489,6 +1670,12 @@ discriminatedUnion("type", [
1489
1670
  frame("cron/report", FRAME_SCHEMAS["cron/report"]),
1490
1671
  frame("cron/run", FRAME_SCHEMAS["cron/run"]),
1491
1672
  frame("hook/report", FRAME_SCHEMAS["hook/report"]),
1673
+ frame("hook/start", FRAME_SCHEMAS["hook/start"]),
1674
+ frame("hook/start/ok", FRAME_SCHEMAS["hook/start/ok"]),
1675
+ frame("github/review-authorize", FRAME_SCHEMAS["github/review-authorize"]),
1676
+ frame("github/review-authorized", FRAME_SCHEMAS["github/review-authorized"]),
1677
+ frame("github/review-result", FRAME_SCHEMAS["github/review-result"]),
1678
+ frame("github/review-result/ok", FRAME_SCHEMAS["github/review-result/ok"]),
1492
1679
  frame("integration/upsert", FRAME_SCHEMAS["integration/upsert"]),
1493
1680
  frame("integration/remove", FRAME_SCHEMAS["integration/remove"]),
1494
1681
  frame("integration/channels", FRAME_SCHEMAS["integration/channels"]),
@@ -1670,6 +1857,7 @@ const RcHookAssign = object({
1670
1857
  kind: _enum(["webhook", "github"]),
1671
1858
  agentId: string().uuid(),
1672
1859
  daemonId: string().uuid(),
1860
+ ...OptionalHookConfigSnapshot.shape,
1673
1861
  sessionMode: _enum([
1674
1862
  "perDelivery",
1675
1863
  "perThread",
@@ -1690,6 +1878,12 @@ const RcHookAssign = object({
1690
1878
  appSlug: string().optional(),
1691
1879
  installationIds: array(string())
1692
1880
  }).optional()
1881
+ }).superRefine((rule, ctx) => {
1882
+ if (rule.dispatchDaemonId !== void 0 && rule.dispatchDaemonId !== rule.daemonId) ctx.addIssue({
1883
+ code: "custom",
1884
+ path: ["dispatchDaemonId"],
1885
+ message: "dispatchDaemonId must equal daemonId on a compiled rule"
1886
+ });
1693
1887
  });
1694
1888
  const RcHookRemove = object({ hookId: string().uuid() });
1695
1889
  const RcRunReport = object({
@@ -1698,9 +1892,17 @@ const RcRunReport = object({
1698
1892
  firedAt: string().datetime(),
1699
1893
  agentId: string().uuid(),
1700
1894
  daemonId: string().uuid().optional(),
1701
- event: string().optional(),
1895
+ ...OptionalHookConfigSnapshot.shape,
1896
+ event: string().min(1).optional(),
1897
+ github: GithubHookMetadata.optional(),
1702
1898
  status: _enum(["accepted", "failed"]),
1703
1899
  reason: string().optional()
1900
+ }).superRefine((report, ctx) => {
1901
+ if (report.daemonId !== void 0 && report.dispatchDaemonId !== void 0 && report.daemonId !== report.dispatchDaemonId) ctx.addIssue({
1902
+ code: "custom",
1903
+ path: ["dispatchDaemonId"],
1904
+ message: "dispatchDaemonId must equal daemonId on a delivery report"
1905
+ });
1704
1906
  });
1705
1907
  const RcGithubInstallation = object({
1706
1908
  installationId: string().min(1),
@@ -1937,6 +2139,9 @@ const RdMsg = discriminatedUnion("source", [
1937
2139
  hookId: string().uuid(),
1938
2140
  deliveryKey: string().min(1),
1939
2141
  firedAt: string().datetime(),
2142
+ ...OptionalHookConfigSnapshot.shape,
2143
+ event: string().min(1).optional(),
2144
+ github: GithubHookMetadata.optional(),
1940
2145
  context: HookContext.optional(),
1941
2146
  target: CronTarget.optional()
1942
2147
  })
@@ -2125,6 +2330,6 @@ function isFrame(type) {
2125
2330
  return (frame) => frame.type === type;
2126
2331
  }
2127
2332
  //#endregion
2128
- export { RELAY_DAEMON_WS_PATH as a, SHARED_CONFIG_ACTION_ID as c, encode as d, MAX_FRAME_BYTES as f, ZodIssueCode as g, RESERVED_MCP_SERVER_NAME as h, RELAY_DAEMON_SUBPROTOCOL as i, buildEnvelope as l, RelayRosterEntry as m, gitRepoLabel as n, buildRelayDaemonFrame as o, MEMORY_INDEX as p, normalizeGitUrl as r, decodeRelayDaemonFrame as s, isFrame as t, decodeEnvelope as u };
2333
+ export { ZodIssueCode as _, RELAY_DAEMON_WS_PATH as a, SHARED_CONFIG_ACTION_ID as c, encode as d, MAX_FRAME_BYTES as f, RESERVED_MCP_SERVER_NAME as g, RelayRosterEntry as h, RELAY_DAEMON_SUBPROTOCOL as i, buildEnvelope as l, HookReport as m, gitRepoLabel as n, buildRelayDaemonFrame as o, MEMORY_INDEX as p, normalizeGitUrl as r, decodeRelayDaemonFrame as s, isFrame as t, decodeEnvelope as u };
2129
2334
 
2130
- //# sourceMappingURL=dist-BG425zHm.js.map
2335
+ //# sourceMappingURL=dist-D97dgR66.js.map