@agentproto/driver-agent-cli 0.2.0 → 0.4.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/dist/{chunk-YQHVLX6O.mjs → chunk-L6BRNMVP.mjs} +552 -62
- package/dist/chunk-L6BRNMVP.mjs.map +1 -0
- package/dist/index.d.ts +203 -14
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/manifest/index.d.ts +2 -2
- package/dist/manifest/index.mjs +2 -2
- package/dist/{schema-CCSzIDMJ.d.ts → schema-L-2rEB1H.d.ts} +314 -2
- package/package.json +2 -2
- package/dist/chunk-YQHVLX6O.mjs.map +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { A as AgentCliHandle, a as AgentCliRuntime, b as AgentCliDefinition, c as AgentCliClient, d as AgentCliRuntimeSession, R as RuntimeConfig, C as ContinuationStrategyId,
|
|
2
|
-
export {
|
|
1
|
+
import { A as AgentCliHandle, a as AgentCliRuntime, b as AgentCliDefinition, c as AgentCliClient, d as AgentCliPrintConfig, e as AgentCliRuntimeSession, R as RuntimeConfig, C as ContinuationStrategyId, f as AgentCliStartOptions, T as TurnContext, g as ContinuationKeyScope } from './schema-L-2rEB1H.js';
|
|
2
|
+
export { h as AgentCliAuth, i as AgentCliCapabilities, j as AgentCliConnectOptions, k as AgentCliContinuation, l as AgentCliFrontmatter, m as AgentCliInstallMethod, n as AgentCliMcpBlock, o as AgentCliMode, p as AgentCliModels, q as AgentCliOption, r as AgentCliOptionType, s as AgentCliPinnedSessionTuning, t as AgentCliPresetDeclaration, u as AgentCliProtocol, v as AgentCliSession, w as AgentCliSessionMode, x as AgentCliSetupPersist, y as AgentCliSetupSkipIf, z as AgentCliSetupStep, B as AgentCliVersionCheck, D as RuntimeConfigInput, E as agentCliFrontmatterSchema, F as runtimeConfigSchema } from './schema-L-2rEB1H.js';
|
|
3
3
|
import { ChildProcess } from 'node:child_process';
|
|
4
|
+
import { AcpMcpServer, StreamEvent } from '@agentproto/acp';
|
|
4
5
|
export { StreamEvent } from '@agentproto/acp';
|
|
5
6
|
import 'zod';
|
|
6
7
|
|
|
@@ -134,8 +135,41 @@ type AcpPermissionHandler = (params: AcpPermissionRequestParams) => Promise<AcpP
|
|
|
134
135
|
* approved the operator binding once; subsequent tool calls don't
|
|
135
136
|
* re-prompt by default. Hosts that want explicit per-call gating
|
|
136
137
|
* pass their own `onPermissionRequest`.
|
|
138
|
+
*
|
|
139
|
+
* NOT safe to use as-is for a `mode: "plan"` session — see
|
|
140
|
+
* `planModePermissionHandler` below.
|
|
137
141
|
*/
|
|
138
142
|
declare const autoAllowPermissionHandler: AcpPermissionHandler;
|
|
143
|
+
/**
|
|
144
|
+
* Permission handler for a session spawned with `mode: "plan"`.
|
|
145
|
+
*
|
|
146
|
+
* `autoAllowPermissionHandler` picks the first `allow_*` option, but for
|
|
147
|
+
* the plan-mode-exit request that option is always an escalation away
|
|
148
|
+
* from plan (`auto`, `acceptEdits`, or `bypassPermissions` depending on
|
|
149
|
+
* what the wrapper offers) — auto-approving it silently defeats the
|
|
150
|
+
* mode the caller asked for (see the regression this fixes: a `plan`
|
|
151
|
+
* session that wrote a file when prompted to). Noted as a known gap in
|
|
152
|
+
* a naive auto-allow handler when #143 shipped the `CLAUDE_CONFIG_DIR`
|
|
153
|
+
* override that makes `mode: "plan"` take effect in the first place;
|
|
154
|
+
* this closes it.
|
|
155
|
+
*
|
|
156
|
+
* Behaves exactly like `autoAllowPermissionHandler` for every other
|
|
157
|
+
* request. For the plan-mode-exit request specifically, it selects the
|
|
158
|
+
* offered `reject_once` option ("No, keep planning") so the wrapper
|
|
159
|
+
* denies the exit with a clean, structured outcome — the tool call
|
|
160
|
+
* fails, the agent stays in plan mode and can keep reasoning or tell
|
|
161
|
+
* the user it's blocked, instead of the turn throwing on a `cancelled`
|
|
162
|
+
* outcome. Falls back to `cancelled` if no `reject_once` option is
|
|
163
|
+
* offered (shouldn't happen with the current wrapper, but a safe
|
|
164
|
+
* default beats guessing an allow).
|
|
165
|
+
*
|
|
166
|
+
* This is a deliberate one-way gate: a plan-mode session driven by this
|
|
167
|
+
* handler can never escalate itself out of plan mode. A caller that
|
|
168
|
+
* wants a human (or a policy engine) to approve that escalation must
|
|
169
|
+
* supply its own `onPermissionRequest` — this handler is only the
|
|
170
|
+
* default for callers that don't.
|
|
171
|
+
*/
|
|
172
|
+
declare const planModePermissionHandler: AcpPermissionHandler;
|
|
139
173
|
interface AcpProtocolOptions {
|
|
140
174
|
child: ChildProcess;
|
|
141
175
|
cwd: string;
|
|
@@ -145,27 +179,44 @@ interface AcpProtocolOptions {
|
|
|
145
179
|
version?: string;
|
|
146
180
|
};
|
|
147
181
|
/** Called when the agent asks for permission to run a tool (Write,
|
|
148
|
-
* Bash, ...). Defaults to `autoAllowPermissionHandler
|
|
182
|
+
* Bash, ...). Defaults to `autoAllowPermissionHandler`, or
|
|
183
|
+
* `planModePermissionHandler` when `requestedMode === "plan"`. Pass a
|
|
149
184
|
* custom handler to plumb requests through a UI / governance
|
|
150
185
|
* policy. Throwing or returning a rejected promise bubbles to the
|
|
151
186
|
* agent as an internal error. */
|
|
152
187
|
onPermissionRequest?: AcpPermissionHandler;
|
|
188
|
+
/**
|
|
189
|
+
* AIP-45 mode requested at spawn (`opts.config.mode` in
|
|
190
|
+
* `define-agent-cli.ts`'s `start()`), if any. Used to pick the default
|
|
191
|
+
* permission handler when `onPermissionRequest` is omitted — see
|
|
192
|
+
* `defaultPermissionHandlerForMode`.
|
|
193
|
+
*/
|
|
194
|
+
requestedMode?: string;
|
|
153
195
|
}
|
|
154
196
|
declare function createAcpProtocolArm(options: AcpProtocolOptions): AgentCliClient;
|
|
155
197
|
|
|
156
198
|
/**
|
|
157
199
|
* AIP-45 protocol arm: `protocol: "print"`.
|
|
158
200
|
*
|
|
159
|
-
* Drives
|
|
160
|
-
*
|
|
161
|
-
* the
|
|
162
|
-
*
|
|
201
|
+
* Drives a headless CLI as one fresh subprocess per turn — no
|
|
202
|
+
* long-lived ACP connection. Simpler than the ACP arm and immune to
|
|
203
|
+
* the stale-proxy race condition: the session object itself never dies
|
|
204
|
+
* between turns; only the per-turn child does.
|
|
205
|
+
*
|
|
206
|
+
* ## Configuration
|
|
163
207
|
*
|
|
164
|
-
* The `
|
|
165
|
-
*
|
|
166
|
-
*
|
|
167
|
-
*
|
|
168
|
-
*
|
|
208
|
+
* The adapter's `print` manifest block declares the CLI's one-shot
|
|
209
|
+
* surface (flags, output format, event taxonomy). When the block is
|
|
210
|
+
* absent, Claude Code defaults are applied for backward compatibility.
|
|
211
|
+
*
|
|
212
|
+
* ## Session tracking
|
|
213
|
+
*
|
|
214
|
+
* The `sessionId` property starts empty (or pre-seeded from
|
|
215
|
+
* `resumeSessionId`) and is updated after the first successful turn
|
|
216
|
+
* from the wire event that carries the session / thread identifier
|
|
217
|
+
* (Claude: `result.session_id`; Mastra: `result.threadId`).
|
|
218
|
+
* Subsequent turns pass the appropriate resume flag so the CLI
|
|
219
|
+
* rehydrates the conversation.
|
|
169
220
|
*/
|
|
170
221
|
|
|
171
222
|
interface PrintArmOptions {
|
|
@@ -177,8 +228,137 @@ interface PrintArmOptions {
|
|
|
177
228
|
env: Record<string, string>;
|
|
178
229
|
/** Pre-seed from `resumeSessionId` so the first turn reattaches. */
|
|
179
230
|
resumeSessionId?: string;
|
|
231
|
+
/** Adapter-declared print surface config. Omit for Claude defaults. */
|
|
232
|
+
printConfig?: AgentCliPrintConfig;
|
|
233
|
+
/**
|
|
234
|
+
* MCP servers to mount into the agent's session. For the `mastracode`
|
|
235
|
+
* print arm (`event_schema: "mastra-jsonl"`) these are written to
|
|
236
|
+
* `<cwd>/.mastracode/mcp.json` before the first turn's spawn (the
|
|
237
|
+
* mastracode CLI has no CLI flag / env var / config-dir override for
|
|
238
|
+
* MCP config — this was exhaustively verified against its source) and
|
|
239
|
+
* restored/removed on `close()`. Ignored for other print schemas
|
|
240
|
+
* (e.g. Claude Code), which don't load MCP config from this path.
|
|
241
|
+
*/
|
|
242
|
+
mcpServers?: AcpMcpServer[];
|
|
180
243
|
}
|
|
181
244
|
declare function createPrintSession(opts: PrintArmOptions): AgentCliRuntimeSession;
|
|
245
|
+
/**
|
|
246
|
+
* Mutable per-stream state for the Mastra Code event mapper.
|
|
247
|
+
* Mastra Code sends the FULL accumulated text on each `message_update`,
|
|
248
|
+
* so we track the previous length to emit only the new portion.
|
|
249
|
+
*
|
|
250
|
+
* Exported so other Mastra Code protocol arms (e.g. the in-process
|
|
251
|
+
* `proprietary` arm in `@agentproto/adapter-mastracode-inprocess`) can
|
|
252
|
+
* reuse the same event mapper instead of reimplementing it — the wire
|
|
253
|
+
* shape here is `AgentControllerEvent` regardless of whether it arrived
|
|
254
|
+
* over a JSONL subprocess pipe or as a live in-process object.
|
|
255
|
+
*/
|
|
256
|
+
interface MastraMapperState {
|
|
257
|
+
lastTextLength: number;
|
|
258
|
+
}
|
|
259
|
+
declare function createMastraMapperState(): MastraMapperState;
|
|
260
|
+
/**
|
|
261
|
+
* Maps a single Mastra Code `AgentControllerEvent` (already a plain
|
|
262
|
+
* object — JSON-parsed from a subprocess line, or handed over directly
|
|
263
|
+
* by an in-process arm) to this repo's {@link StreamEvent} taxonomy.
|
|
264
|
+
* `stderrLines` enriches `error` events for arms that have a real
|
|
265
|
+
* subprocess to report on; pass `[]` when there is none (e.g. the
|
|
266
|
+
* in-process arm).
|
|
267
|
+
*/
|
|
268
|
+
declare function mapMastraEvent(evt: Record<string, unknown>, sessionId: string, stderrLines: string[], state: MastraMapperState): StreamEvent | null;
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* AIP-45 protocol arm: `protocol: "proprietary"`.
|
|
272
|
+
*
|
|
273
|
+
* Loads an NPM adapter package (named in the manifest's `adapter`
|
|
274
|
+
* field) implementing `AgentCliClient`. The package translates the
|
|
275
|
+
* vendor's REPL/proprietary stream into the canonical StreamEvent
|
|
276
|
+
* taxonomy.
|
|
277
|
+
*
|
|
278
|
+
* Unlike the `acp` / `print` arms (built into this package, driving a
|
|
279
|
+
* spawned subprocess), a proprietary arm may not involve a subprocess
|
|
280
|
+
* at all — e.g. an in-process SDK integration. `createAgentCliRuntime`
|
|
281
|
+
* skips the subprocess spawn entirely for `protocol: "proprietary"`
|
|
282
|
+
* (see `define-agent-cli.ts`); this loader has no opinion on whether
|
|
283
|
+
* the loaded package owns a child process, a socket, or nothing.
|
|
284
|
+
*
|
|
285
|
+
* ## Adapter package contract
|
|
286
|
+
*
|
|
287
|
+
* The named package's default export path (its `main`/`exports["."]`)
|
|
288
|
+
* must export a factory:
|
|
289
|
+
*
|
|
290
|
+
* export function createAgentCliClient(
|
|
291
|
+
* definition: AgentCliHandle,
|
|
292
|
+
* ): AgentCliClient | Promise<AgentCliClient>
|
|
293
|
+
*
|
|
294
|
+
* A default export function is accepted as a fallback for adapters
|
|
295
|
+
* that only have one thing to export. The factory receives the full
|
|
296
|
+
* manifest handle so adapter-specific config (models, capabilities,
|
|
297
|
+
* metadata) is available without a second lookup — mirrors the ACP
|
|
298
|
+
* arm receiving `clientInfo` derived from the manifest.
|
|
299
|
+
*/
|
|
300
|
+
|
|
301
|
+
interface ProprietaryProtocolOptions {
|
|
302
|
+
/** NPM package name to load — from manifest.adapter. */
|
|
303
|
+
adapter: string;
|
|
304
|
+
/** Full manifest handle, forwarded verbatim to the loaded factory. */
|
|
305
|
+
definition: AgentCliHandle;
|
|
306
|
+
}
|
|
307
|
+
declare function createProprietaryProtocolArm(options: ProprietaryProtocolOptions): Promise<AgentCliClient>;
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* Shared converter from this repo's generic `AcpMcpServer[]`
|
|
311
|
+
* (`{ name, transport: "stdio"|"http"|"sse", ref? }`) to the
|
|
312
|
+
* `Record<string, McpServerConfig>` shape mastracode expects — both
|
|
313
|
+
* for the in-process SDK config (`MastraCodeConfig.mcpServers`) and
|
|
314
|
+
* for the file-based `.mastracode/mcp.json` the print arm writes.
|
|
315
|
+
*
|
|
316
|
+
* The target type is structurally identical in both contexts:
|
|
317
|
+
* - stdio → `{ command, args?, env? }`
|
|
318
|
+
* - http → `{ url, headers? }`
|
|
319
|
+
* - sse → `{ url }` (mastracode's `McpHttpServerConfig` doc says
|
|
320
|
+
* it handles SSE through the same `url` field, no separate
|
|
321
|
+
* discriminator)
|
|
322
|
+
*
|
|
323
|
+
* Neither `McpServerConfig`/`McpStdioServerConfig`/`McpHttpServerConfig`
|
|
324
|
+
* is exported from `mastracode`'s public surface (only `.`, `./tui`,
|
|
325
|
+
* `./acp`, `./headless`, `./plugin` subpaths are exported — no `./mcp`),
|
|
326
|
+
* so we define a local, structurally-matching type here. TS structural
|
|
327
|
+
* typing means a plain object literal shaped correctly type-checks fine
|
|
328
|
+
* against `MastraCodeConfig.mcpServers` without a named import.
|
|
329
|
+
*
|
|
330
|
+
* Mirrors EXACTLY the same transport→field semantics the ACP arm uses
|
|
331
|
+
* in `toAcpMcpServer` (`@agentproto/acp/client`), just flattened to
|
|
332
|
+
* mastracode's keyed-record shape instead of the ACP wire array.
|
|
333
|
+
*/
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* mastracode's per-server config entry (structural — not imported from
|
|
337
|
+
* `mastracode`, which doesn't export these types from its public
|
|
338
|
+
* surface). Detected structurally by mastracode: `command` present →
|
|
339
|
+
* stdio, `url` present → http. Both keys present → entry is skipped
|
|
340
|
+
* (mastracode's own validation).
|
|
341
|
+
*/
|
|
342
|
+
type MastracodeMcpServerConfig = {
|
|
343
|
+
command: string;
|
|
344
|
+
args?: string[];
|
|
345
|
+
env?: Record<string, string>;
|
|
346
|
+
} | {
|
|
347
|
+
url: string;
|
|
348
|
+
headers?: Record<string, string>;
|
|
349
|
+
};
|
|
350
|
+
/**
|
|
351
|
+
* Convert the repo's compact `AcpMcpServer[]` into mastracode's
|
|
352
|
+
* `Record<string, McpServerConfig>` keyed by server name. Returns
|
|
353
|
+
* `undefined` for an empty/missing input so callers can spread the
|
|
354
|
+
* result conditionally (`...(cond ? { mcpServers } : {})`).
|
|
355
|
+
*
|
|
356
|
+
* On key collision the caller's entry simply overwrites — this matches
|
|
357
|
+
* mastracode's own "higher precedence overrides lower, by server name"
|
|
358
|
+
* merge semantics for both the SDK config field and the file-based
|
|
359
|
+
* load-order.
|
|
360
|
+
*/
|
|
361
|
+
declare function toFileBasedMcpServers(servers: readonly AcpMcpServer[] | undefined): Record<string, MastracodeMcpServerConfig> | undefined;
|
|
182
362
|
|
|
183
363
|
/**
|
|
184
364
|
* Thrown when `RuntimeConfig` references manifest entries that don't
|
|
@@ -187,7 +367,7 @@ declare function createPrintSession(opts: PrintArmOptions): AgentCliRuntimeSessi
|
|
|
187
367
|
* inspecting the message string.
|
|
188
368
|
*/
|
|
189
369
|
declare class RuntimeConfigError extends Error {
|
|
190
|
-
readonly code: "unknown_mode" | "unknown_option" | "option_type_mismatch" | "option_enum_violation" | "option_bounds_violation" | "unsupported_continuation";
|
|
370
|
+
readonly code: "unknown_mode" | "unknown_option" | "option_type_mismatch" | "option_enum_violation" | "option_bounds_violation" | "unsupported_continuation" | "model_denied";
|
|
191
371
|
readonly path: string;
|
|
192
372
|
constructor(code: RuntimeConfigError["code"], path: string, message: string);
|
|
193
373
|
}
|
|
@@ -198,6 +378,15 @@ declare class RuntimeConfigError extends Error {
|
|
|
198
378
|
interface ComposedSpawn {
|
|
199
379
|
binArgs: string[];
|
|
200
380
|
env: Record<string, string>;
|
|
381
|
+
/**
|
|
382
|
+
* Env keys the active mode AND active options declared for deletion
|
|
383
|
+
* (AgentCliMode.env_unset / AgentCliOption.env_unset). Surfaced
|
|
384
|
+
* pure-side so the runtime's `start()` — which owns the process.env
|
|
385
|
+
* merge — can apply the deletions at the one point where the ambient
|
|
386
|
+
* env is actually present (compose starts from `{}` and can't delete
|
|
387
|
+
* what isn't there yet). Empty when nothing declares any.
|
|
388
|
+
*/
|
|
389
|
+
envUnset: string[];
|
|
201
390
|
}
|
|
202
391
|
/**
|
|
203
392
|
* Compose the final spawn args from a manifest + per-call config.
|
|
@@ -384,4 +573,4 @@ declare function configureNativeResume(hooks: NativeResumeHooks): void;
|
|
|
384
573
|
declare const SPEC_NAME: "agentcli-interactive/v1";
|
|
385
574
|
declare const SPEC_VERSION: "0.1.0-alpha";
|
|
386
575
|
|
|
387
|
-
export { type AcpPermissionHandler, type AcpPermissionOutcome, type AcpPermissionRequestParams, type AcquireContext, AgentCliClient, AgentCliDefinition, AgentCliHandle, type AgentCliModelOptions, AgentCliRuntime, AgentCliRuntimeSession, AgentCliStartOptions, type ComposedSpawn, ContinuationKeyScope, type ContinuationStrategy, ContinuationStrategyId, type FileReadingOptions, type ModelLike, type NativeResumeHooks, PROVIDER_KEY_ENV, type PrintArmOptions, type ReleaseContext, type ReleaseOutcome, RuntimeConfig, RuntimeConfigError, SPEC_NAME, SPEC_VERSION, TurnContext, autoAllowPermissionHandler, composePrompt, composeSpawn, configureNativeResume, createAcpProtocolArm, createAgentCliRuntime, createPrintSession, datasetPreamble, defineAgentCli, deriveKeyFromScope, getContinuationStrategy, listContinuationStrategies, makeAgentCliModel, registerContinuationStrategy, resolveCliEnv, resolveContinuationStrategy };
|
|
576
|
+
export { type AcpPermissionHandler, type AcpPermissionOutcome, type AcpPermissionRequestParams, type AcquireContext, AgentCliClient, AgentCliDefinition, AgentCliHandle, type AgentCliModelOptions, AgentCliPrintConfig, AgentCliRuntime, AgentCliRuntimeSession, AgentCliStartOptions, type ComposedSpawn, ContinuationKeyScope, type ContinuationStrategy, ContinuationStrategyId, type FileReadingOptions, type MastraMapperState, type MastracodeMcpServerConfig, type ModelLike, type NativeResumeHooks, PROVIDER_KEY_ENV, type PrintArmOptions, type ProprietaryProtocolOptions, type ReleaseContext, type ReleaseOutcome, RuntimeConfig, RuntimeConfigError, SPEC_NAME, SPEC_VERSION, TurnContext, autoAllowPermissionHandler, composePrompt, composeSpawn, configureNativeResume, createAcpProtocolArm, createAgentCliRuntime, createMastraMapperState, createPrintSession, createProprietaryProtocolArm, datasetPreamble, defineAgentCli, deriveKeyFromScope, getContinuationStrategy, listContinuationStrategies, makeAgentCliModel, mapMastraEvent, planModePermissionHandler, registerContinuationStrategy, resolveCliEnv, resolveContinuationStrategy, toFileBasedMcpServers };
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { RuntimeConfigError, agentCliFrontmatterSchema, autoAllowPermissionHandler, composeSpawn, createAcpProtocolArm, createAgentCliRuntime, createPrintSession, defineAgentCli, resolveContinuationStrategy, runtimeConfigSchema } from './chunk-
|
|
1
|
+
export { RuntimeConfigError, agentCliFrontmatterSchema, autoAllowPermissionHandler, composeSpawn, createAcpProtocolArm, createAgentCliRuntime, createMastraMapperState, createPrintSession, createProprietaryProtocolArm, defineAgentCli, mapMastraEvent, planModePermissionHandler, resolveContinuationStrategy, runtimeConfigSchema, toFileBasedMcpServers } from './chunk-L6BRNMVP.mjs';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* @agentproto/driver-agent-cli v0.1.0-alpha
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/model.ts","../src/continuation/strategies/none.ts","../src/continuation/types.ts","../src/continuation/strategies/pinned-session.ts","../src/continuation/strategies/transcript.ts","../src/continuation/strategies/native-resume.ts","../src/continuation/registry.ts","../src/index.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Agent CLI as a model port — turn ANY AIP-45 agent CLI runtime into a generic\n * `complete({system?, prompt}) → {result}` executor. This is the one bridge that\n * lets the SAME registry (hermes, claude-code, opencode, codex, openclaw, …)\n * back any prompt→completion seam: a report's chapter writer, a corpus\n * distiller, a Mastra tool's judgment step. The executor swaps, the prompts\n * (built by each seam's engine) don't.\n *\n * It drives the CLI over **ACP**: per `complete()` it spawns a fresh session,\n * sends one user turn, concatenates the `text-delta` stream until `turn-end`,\n * then closes. Lives here (not in a product) so seams BELOW the products —\n * `@agentproto/corpus` distill, the CLI — can consume it without importing\n * upward. The runner is injectable so assembly is unit-tested without a binary.\n */\n\nimport type { AgentCliRuntime } from \"./types.js\"\n\n/**\n * The minimal structural model port every seam consumes. Anything with this\n * `complete` shape satisfies the corpus `ReportModelPort` / `DistillPort`-backing\n * model / an AIP `ModelPort` — duck-typed, no nominal coupling.\n */\nexport interface ModelLike {\n complete(req: {\n system?: string\n prompt: string\n [k: string]: unknown\n }): Promise<{ result: string }>\n}\n\n/**\n * The \"file-reading sub-agent\" tier — opt-in across every file-IO-capable\n * executor. When `datasetDir` is set the executor is rooted there and granted\n * its own read tools, so instead of being limited to the excerpts a seam quotes\n * in the prompt it can open the primary sources directly and ground first-hand.\n */\nexport interface FileReadingOptions {\n /** Absolute path to the dataset/source root the executor may read from. */\n datasetDir?: string\n}\n\n/** The instruction prepended to a completion when {@link FileReadingOptions.datasetDir} is set. */\nexport function datasetPreamble(datasetDir: string): string {\n return (\n `You have direct read access to the source files under \\`${datasetDir}\\` ` +\n `(e.g. \\`sources/\\` raw captures, \\`entries/\\` refined notes). Use your ` +\n `file-reading tools to consult the primary sources directly when grounding ` +\n `claims — do not rely only on the excerpts quoted in this prompt.`\n )\n}\n\n/** Compose system + prompt with an optional source-access preamble (shared by every executor). */\nexport function composePrompt(\n system: string | undefined,\n prompt: string,\n datasetDir?: string\n): string {\n const head = datasetDir ? `${datasetPreamble(datasetDir)}\\n\\n` : \"\"\n return system ? `${head}${system}\\n\\n${prompt}` : `${head}${prompt}`\n}\n\n/** Provider keys an agent CLI may route through, forwarded from the parent env by default. */\nexport const PROVIDER_KEY_ENV = [\n \"OPENROUTER_API_KEY\",\n \"ANTHROPIC_API_KEY\",\n \"OPENAI_API_KEY\",\n] as const\n\nexport interface AgentCliModelOptions extends FileReadingOptions {\n /**\n * Env handed to the spawned CLI process — the provider key it routes through.\n * Defaults to forwarding {@link PROVIDER_KEY_ENV} from the parent process env.\n */\n env?: Record<string, string>\n /** Working directory for the CLI process. Defaults to `datasetDir` when set. */\n cwd?: string\n /** Timeout per completion (ms). Default 5 min. */\n timeoutMs?: number\n /**\n * Injectable runner (composed prompt → completion text). Defaults to driving\n * the runtime over ACP. Override in tests to avoid the CLI.\n */\n run?: (prompt: string) => Promise<string>\n}\n\n/** Build the env for the spawned CLI: explicit override, else forwarded provider keys. */\nexport function resolveCliEnv(\n opts: Pick<AgentCliModelOptions, \"env\">\n): Record<string, string> {\n if (opts.env) return opts.env\n const env: Record<string, string> = {}\n for (const k of PROVIDER_KEY_ENV) {\n const v = process.env[k]\n if (v) env[k] = v\n }\n return env\n}\n\n/** Drive one ACP turn on `runtime`, concatenating the text deltas. */\nasync function driveTurn(\n runtime: AgentCliRuntime,\n prompt: string,\n opts: AgentCliModelOptions\n): Promise<string> {\n const controller = new AbortController()\n const timer = setTimeout(\n () => controller.abort(),\n opts.timeoutMs ?? 5 * 60 * 1000\n )\n\n const cwd = opts.cwd ?? opts.datasetDir\n const session = await runtime.start({\n env: resolveCliEnv(opts),\n signal: controller.signal,\n ...(cwd ? { cwd } : {}),\n })\n\n try {\n let text = \"\"\n for await (const evt of session.send({ role: \"user\", content: prompt })) {\n if (evt.kind === \"text-delta\") {\n text += evt.text\n } else if (evt.kind === \"error\") {\n throw new Error(`${runtime.definition.id} model: ${evt.error.message}`)\n } else if (evt.kind === \"turn-end\") {\n if (evt.reason !== \"completed\")\n throw new Error(`${runtime.definition.id} model: turn ${evt.reason}`)\n break\n }\n }\n if (controller.signal.aborted)\n throw new Error(`${runtime.definition.id} model: timed out`)\n return text.trim()\n } finally {\n clearTimeout(timer)\n await session.close()\n }\n}\n\n/**\n * Build a {@link ModelLike} backed by an AIP-45 agent-CLI runtime. Hand it any\n * `*Runtime()` from the registry (Hermes, claude-code, opencode, …); per-CLI\n * presets are one-liners over this.\n */\nexport function makeAgentCliModel(\n runtime: AgentCliRuntime,\n opts: AgentCliModelOptions = {}\n): ModelLike {\n const run = opts.run ?? ((prompt: string) => driveTurn(runtime, prompt, opts))\n return {\n async complete({ system, prompt }) {\n return {\n result: await run(composePrompt(system, prompt, opts.datasetDir)),\n }\n },\n }\n}\n","/**\n * `none` strategy — pre-AIP-45-extension behaviour.\n *\n * Spawn a fresh session per acquire; close it on release. No state,\n * no reuse. The default when a manifest declares no `continuation`\n * block (back-compat for adapters that haven't been updated).\n */\n\nimport type { ContinuationStrategy } from \"../types.js\"\n\nexport const noneStrategy: ContinuationStrategy = {\n id: \"none\",\n async acquire(ctx) {\n return ctx.runtime.start(ctx.startOptions)\n },\n async release(ctx) {\n await ctx.session.close()\n },\n}\n","/**\n * AIP-45 ContinuationStrategy interface.\n *\n * A continuation strategy decides HOW prior conversation turns reach a\n * spawned CLI on subsequent invocations. Built-ins handle:\n *\n * - `none` — fresh session per call (current pre-AIP-45 behaviour)\n * - `pinned-session` — keep the spawned child alive, reuse across turns\n * - `transcript` — caller-supplied preamble prepended to each turn\n * - `native-resume` — pass a session id to the CLI's own `--resume` flag\n *\n * Adapter packages MAY register custom strategies via the registry —\n * for example, a Goose-specific strategy that uses MCP-side session\n * load semantics. Custom strategy ids require a follow-up AIP that\n * opens the `ContinuationStrategyId` enum (so the manifest schema can\n * validate them).\n *\n * The strategy owns the SESSION LIFECYCLE: `acquire` returns a session\n * the caller can `send()` against, and `release` decides whether the\n * session lives on (pinned-session) or closes immediately (none). The\n * runner / generation strategy MUST go through `acquire`/`release` —\n * it MUST NOT call `runtime.start()` / `session.close()` directly when\n * a strategy is active.\n */\n\nimport type {\n AgentCliRuntime,\n AgentCliRuntimeSession,\n AgentCliStartOptions,\n ContinuationKeyScope,\n ContinuationStrategyId,\n RuntimeConfig,\n TurnContext,\n} from \"../types.js\"\n\n/**\n * Per-acquire context the strategy gets. The runner builds this from\n * the manifest, the operator config, and the current turn's identity.\n */\nexport interface AcquireContext {\n runtime: AgentCliRuntime\n /** Already-composed start options (cwd / env / signal / config /\n * turnCtx). Strategies MAY override individual fields when they\n * call `runtime.start(...)` themselves. */\n startOptions: AgentCliStartOptions\n /** Per-call config (already validated against the manifest). */\n config: RuntimeConfig\n /** Identity context for key derivation. */\n turnCtx: TurnContext\n}\n\n/**\n * Strategies can hint to the runner about how the turn played out so\n * the strategy can decide whether to keep the session alive (normal\n * end), reset its TTL but keep it (transient error), or evict it\n * (dead-process error).\n */\nexport type ReleaseOutcome =\n | { kind: \"completed\" }\n | { kind: \"cancelled\" }\n | { kind: \"error\"; reason: \"transient\" | \"fatal\"; message: string }\n\nexport interface ReleaseContext {\n session: AgentCliRuntimeSession\n outcome: ReleaseOutcome\n turnCtx: TurnContext\n}\n\n/**\n * The strategy contract. `acquire` returns a session ready for the\n * caller to `send()` against — fresh OR reused. `release` decides\n * the session's fate. Strategies MAY hold internal state (e.g.\n * the pinned-session map) keyed by `turnCtx`.\n */\nexport interface ContinuationStrategy {\n readonly id: ContinuationStrategyId\n acquire(ctx: AcquireContext): Promise<AgentCliRuntimeSession>\n release(ctx: ReleaseContext): Promise<void>\n}\n\n/**\n * Derive a stable pin key from `turnCtx` according to the manifest's\n * `pinned_session.key_scope`. Missing scope fields downgrade to a\n * less-specific key with a warning — pinning still works, it just\n * collides more.\n *\n * Returns `null` when EVERY scope field the manifest asked for is\n * missing (no key derivable; strategy falls back to per-spawn).\n */\nexport function deriveKeyFromScope(\n scope: ContinuationKeyScope[],\n turnCtx: TurnContext\n): string | null {\n const parts: string[] = []\n for (const s of scope) {\n const v = turnCtx[s]\n if (v) parts.push(`${s}=${v}`)\n }\n return parts.length === 0 ? null : parts.join(\"|\")\n}\n","/**\n * `pinned-session` strategy — keep the spawned child alive across\n * turns so the CLI's in-memory model context carries over.\n *\n * Suitable for manifests that declare `session.mode: persistent` AND\n * `context_carryover: true` (Claude Code, OpenCode, ...). Acquires\n * either reuse a live pinned session or spawn fresh and pin; releases\n * keep the session alive and reset its idle TTL. The strategy\n * auto-evicts after the manifest's `pinned_session.idle_timeout_ms`.\n *\n * The pin key is derived from `turnCtx` according to the manifest's\n * `pinned_session.key_scope` (default: `[conversation, operator]` —\n * different conversations and different operators each get their own\n * child process).\n *\n * Lost on process restart. DB-backed pin persistence is a follow-up\n * (track sessionId in `cli_sessions` table, then optionally fall back\n * to native-resume / transcript on restart).\n */\n\nimport type {\n AgentCliRuntimeSession,\n AgentCliRuntime,\n AgentCliStartOptions,\n} from \"../../types.js\"\nimport type { ContinuationStrategy } from \"../types.js\"\nimport { deriveKeyFromScope } from \"../types.js\"\n\ninterface PinnedEntry {\n session: AgentCliRuntimeSession\n /** Cached so retry-after-eviction can recreate without re-resolving\n * the runtime entry from outside. */\n runtime: AgentCliRuntime\n /** Cached so eviction-and-retry uses the same start options. */\n startOptions: AgentCliStartOptions\n idleTimer: ReturnType<typeof setTimeout> | null\n}\n\nconst DEFAULT_IDLE_TIMEOUT_MS = 30 * 60 * 1000\n\nconst pins = new Map<string, PinnedEntry>()\n\nfunction clearIdleTimer(entry: PinnedEntry): void {\n if (entry.idleTimer) {\n clearTimeout(entry.idleTimer)\n entry.idleTimer = null\n }\n}\n\nfunction scheduleIdleEviction(\n key: string,\n entry: PinnedEntry,\n idleTimeoutMs: number\n): void {\n clearIdleTimer(entry)\n entry.idleTimer = setTimeout(() => {\n pins.delete(key)\n entry.session.close().catch(err => {\n console.warn(\n `[pinned-session] idle close failed for ${key}:`,\n err instanceof Error ? err.message : err\n )\n })\n console.log(\n `[pinned-session] ${key} idle ${idleTimeoutMs / 60_000}m → closed`\n )\n }, idleTimeoutMs)\n // Don't keep the event loop alive just for the idle close — the\n // child will be reaped on process exit anyway. Without `unref`\n // a stale pin would block graceful shutdown.\n entry.idleTimer.unref?.()\n}\n\nfunction evictPin(key: string): void {\n const entry = pins.get(key)\n if (!entry) return\n clearIdleTimer(entry)\n pins.delete(key)\n entry.session.close().catch(err => {\n console.warn(\n `[pinned-session] evict close failed for ${key}:`,\n err instanceof Error ? err.message : err\n )\n })\n}\n\nexport const pinnedSessionStrategy: ContinuationStrategy = {\n id: \"pinned-session\",\n\n async acquire(ctx) {\n const tuning = ctx.runtime.definition.continuation?.pinned_session\n const scope = tuning?.key_scope ?? [\"conversation\", \"operator\"]\n const key = deriveKeyFromScope(scope, ctx.turnCtx)\n const idleTimeoutMs = tuning?.idle_timeout_ms ?? DEFAULT_IDLE_TIMEOUT_MS\n\n if (key === null) {\n // No identity to pin against — fall back to per-spawn behaviour.\n // Warn so the host learns to populate turnCtx.\n console.warn(\n `[pinned-session] turnCtx has no fields matching key_scope ${JSON.stringify(scope)}; falling back to per-spawn (no pin).`\n )\n return ctx.runtime.start(ctx.startOptions)\n }\n\n const existing = pins.get(key)\n if (existing) {\n // Cancel the idle timer — this turn is reusing the pin.\n clearIdleTimer(existing)\n return existing.session\n }\n\n const session = await ctx.runtime.start(ctx.startOptions)\n const entry: PinnedEntry = {\n session,\n runtime: ctx.runtime,\n startOptions: ctx.startOptions,\n idleTimer: null,\n }\n pins.set(key, entry)\n scheduleIdleEviction(key, entry, idleTimeoutMs)\n return session\n },\n\n async release(ctx) {\n // Find the entry by identity — ReleaseContext doesn't carry `runtime`,\n // so we match by session reference. Acceptable since the pin map is small.\n let foundKey: string | null = null\n for (const [k, e] of pins) {\n if (e.session === ctx.session) {\n foundKey = k\n break\n }\n }\n\n if (!foundKey) {\n // Session wasn't pinned (per-spawn fallback path) — close it\n // like the `none` strategy would.\n await ctx.session.close()\n return\n }\n\n const entry = pins.get(foundKey)!\n const tuning = entry.runtime.definition.continuation?.pinned_session\n const idleTimeoutMs = tuning?.idle_timeout_ms ?? DEFAULT_IDLE_TIMEOUT_MS\n\n // Fatal errors → evict so the next turn re-spawns. Transient\n // errors and normal completion → reset the idle TTL and keep.\n // Cancelled (user aborted) is treated like normal completion —\n // the user wanted to stop this turn, not the whole session.\n if (ctx.outcome.kind === \"error\" && ctx.outcome.reason === \"fatal\") {\n evictPin(foundKey)\n return\n }\n\n scheduleIdleEviction(foundKey, entry, idleTimeoutMs)\n },\n}\n\n/**\n * Test helper — drop all pinned entries and clear timers. Not part\n * of the public API; exposed under `__test__` so tests can reset the\n * module's singleton state between runs.\n */\nexport const __test__ = {\n resetPins(): void {\n for (const [k] of pins) evictPin(k)\n },\n pinCount(): number {\n return pins.size\n },\n}\n","/**\n * `transcript` strategy — works for any CLI, including those with\n * `resumable: false` and ephemeral sessions.\n *\n * The driver doesn't know about Mastra memory or the host's\n * conversation log — that's the host's domain. The host supplies the\n * preamble at acquire-time via `startOptions.config.options` (the\n * convention is option id `__transcript`, see below) and the strategy\n * is otherwise identical to `none` — fresh session per acquire,\n * close on release.\n *\n * In practice the host does the prepending itself before calling\n * `runtime.start` (it controls the `message` text). This strategy\n * exists mostly as a NAMED policy choice in the manifest — declaring\n * it tells the host \"use the transcript-replay path for this CLI\"\n * without the host needing to inspect capabilities.\n *\n * Token-costly but stateless and survives API restarts.\n */\n\nimport type { ContinuationStrategy } from \"../types.js\"\n\nexport const transcriptStrategy: ContinuationStrategy = {\n id: \"transcript\",\n async acquire(ctx) {\n return ctx.runtime.start(ctx.startOptions)\n },\n async release(ctx) {\n await ctx.session.close()\n },\n}\n","/**\n * `native-resume` strategy — reattach to the agent's own session by id\n * (ACP `loadSession`, MCP equivalent, or argv-style `--resume`).\n *\n * Two-step lifecycle:\n * 1. **acquire**: look up a persisted sessionId for `turnCtx` via\n * `loadHook`. If found, pass it to `runtime.start` as\n * `resumeSessionId` so the protocol arm reattaches. If not, spawn\n * fresh — and after the session is up, capture the new id from\n * `session.sessionId` and persist it via `saveHook`.\n * 2. **release**: close the spawned process. The session lives in\n * the agent's storage layer (e.g. Claude Code's JSONL files);\n * cold-start resume on the next acquire reads from that store.\n *\n * Hooks are registered once per host process via\n * `configureNativeResume({ load, save })`. Without hooks the strategy\n * degrades to per-spawn behaviour with a one-line warning — it's not\n * fatal because the spawn still works, just without continuity.\n *\n * Requires the manifest to declare `capabilities.resumable: true`\n * AND the agent to advertise the matching protocol capability (e.g.\n * ACP `loadSession: true`). The schema enforces the manifest side at\n * validation; runtime capability mismatch surfaces from the protocol\n * arm as the agent's own error.\n */\n\nimport type { ContinuationStrategy, AcquireContext } from \"../types.js\"\nimport { deriveKeyFromScope } from \"../types.js\"\nimport type { TurnContext } from \"../../types.js\"\n\nexport interface NativeResumeHooks {\n /** Look up a persisted sessionId for the given identity scope. Return\n * undefined when no prior session exists — strategy spawns fresh. */\n load: (turnCtx: TurnContext) => Promise<string | undefined>\n /** Persist a freshly-established sessionId so the next cold start\n * can resume. Called once per \"fresh spawn\" acquire (not per turn).\n * Idempotent / upsert semantics expected on the host side. */\n save: (turnCtx: TurnContext, sessionId: string) => Promise<void>\n /** Optional: drop the persisted entry when a session is detected as\n * unresumable (agent rejected loadSession with a hard error). */\n forget?: (turnCtx: TurnContext) => Promise<void>\n}\n\nlet _hooks: NativeResumeHooks | null = null\n\n/**\n * Register the host's session-id load/save callbacks. Call once at\n * boot. Subsequent calls overwrite — useful in tests; in prod treat\n * the registration as exclusive.\n */\nexport function configureNativeResume(hooks: NativeResumeHooks): void {\n _hooks = hooks\n}\n\n/** Reset to no-hooks. Test helper; not part of public API. */\nexport function __resetNativeResumeForTests(): void {\n _hooks = null\n}\n\nexport const nativeResumeStrategy: ContinuationStrategy = {\n id: \"native-resume\",\n async acquire(ctx: AcquireContext) {\n if (!_hooks) {\n console.warn(\n \"[native-resume] no hooks registered (call configureNativeResume at boot); falling back to per-spawn — no continuity.\"\n )\n return ctx.runtime.start(ctx.startOptions)\n }\n // Use the same key-derivation as pinned-session so a host can\n // declare its scope ONCE in the manifest (`continuation.pinned_session.key_scope`)\n // and have both strategies key off the same identity. Native-resume\n // doesn't have its own key_scope today; it inherits.\n const scope =\n ctx.runtime.definition.continuation?.pinned_session?.key_scope ?? [\n \"conversation\",\n \"operator\",\n ]\n const key = deriveKeyFromScope(scope, ctx.turnCtx)\n if (key === null) {\n console.warn(\n `[native-resume] turnCtx has no fields matching key_scope ${JSON.stringify(scope)}; falling back to per-spawn (no resume).`\n )\n return ctx.runtime.start(ctx.startOptions)\n }\n\n const existingId = await _hooks.load(ctx.turnCtx).catch(err => {\n console.warn(\n `[native-resume] load hook failed for ${key}:`,\n err instanceof Error ? err.message : err\n )\n return undefined\n })\n\n let session\n let resumed = false\n if (existingId) {\n try {\n session = await ctx.runtime.start({\n ...ctx.startOptions,\n resumeSessionId: existingId,\n })\n resumed = true\n } catch (err) {\n // Most likely the agent rejected the id (session expired,\n // wiped, mismatched cwd). Drop the stale pin and spawn fresh\n // so the user gets continuity going forward instead of being\n // stuck on a dead reference.\n console.warn(\n `[native-resume] resume failed for ${key} (id=${existingId.slice(0, 12)}…), starting fresh:`,\n err instanceof Error ? err.message : err\n )\n if (_hooks.forget) {\n await _hooks.forget(ctx.turnCtx).catch(() => undefined)\n }\n session = await ctx.runtime.start(ctx.startOptions)\n }\n } else {\n session = await ctx.runtime.start(ctx.startOptions)\n }\n\n // Persist the established id when this is a NEW session (resume\n // path keeps the same id we already have, no need to re-save).\n // The runtime guarantees session.sessionId reflects the protocol\n // session id when the arm exposes it.\n if (!resumed && session.sessionId) {\n await _hooks.save(ctx.turnCtx, session.sessionId).catch(err => {\n console.warn(\n `[native-resume] save hook failed for ${key}:`,\n err instanceof Error ? err.message : err\n )\n })\n }\n return session\n },\n\n async release(ctx) {\n // The protocol session lives in the agent's own storage; closing\n // the spawned subprocess is fine — `loadSession` on the next\n // acquire reattaches via the persisted id.\n await ctx.session.close()\n },\n}\n","/**\n * Continuation strategy registry.\n *\n * Module-scoped singleton — all built-ins are registered at import\n * time, custom strategies (from adapter packages) register via\n * `registerContinuationStrategy`. The runner looks up by id;\n * unregistered ids throw at acquire-time so the caller fails fast\n * with a clear \"this strategy id isn't registered\" message.\n */\n\nimport type { ContinuationStrategyId } from \"../types.js\"\nimport type { ContinuationStrategy } from \"./types.js\"\nimport { noneStrategy } from \"./strategies/none.js\"\nimport { pinnedSessionStrategy } from \"./strategies/pinned-session.js\"\nimport { transcriptStrategy } from \"./strategies/transcript.js\"\nimport { nativeResumeStrategy } from \"./strategies/native-resume.js\"\n\nconst registry = new Map<ContinuationStrategyId, ContinuationStrategy>()\n\n/**\n * Register (or replace) a continuation strategy. Adapter packages\n * MAY register custom strategies on import — but they MUST first\n * land an AIP that opens the `ContinuationStrategyId` enum so the\n * manifest schema accepts the new id.\n */\nexport function registerContinuationStrategy(\n strategy: ContinuationStrategy\n): void {\n registry.set(strategy.id, strategy)\n}\n\nexport function getContinuationStrategy(\n id: ContinuationStrategyId\n): ContinuationStrategy {\n const s = registry.get(id)\n if (!s) {\n throw new Error(\n `[agent-cli] No continuation strategy registered for id '${id}'. Built-ins: ${Array.from(registry.keys()).join(\", \")}.`\n )\n }\n return s\n}\n\nexport function listContinuationStrategies(): ContinuationStrategyId[] {\n return Array.from(registry.keys())\n}\n\n// Register built-ins eagerly at module load so any importer of the\n// registry sees them. Custom strategies layer on top.\nregisterContinuationStrategy(noneStrategy)\nregisterContinuationStrategy(pinnedSessionStrategy)\nregisterContinuationStrategy(transcriptStrategy)\nregisterContinuationStrategy(nativeResumeStrategy)\n","/**\n * @agentproto/driver-agent-cli — AIP-45 AGENT-CLI.md `defineAgentCli`\n * reference impl.\n *\n * Spec: https://agentproto.sh/docs/aip-45\n *\n * Authoring paths:\n * - TS: `defineAgentCli({...})` → `AgentCliHandle`\n * - MD: `parseAgentCliManifest(src) → agentCliFromManifest({...})` → `AgentCliHandle`\n *\n * Runtime: `createAgentCliRuntime(handle)` → spawn binary, dispatch\n * turns through the protocol arm (acp / mcp / proprietary), normalise\n * events to {@link StreamEvent}.\n */\n\nexport const SPEC_NAME = \"agentcli-interactive/v1\" as const\nexport const SPEC_VERSION = \"0.1.0-alpha\" as const\n\nexport {\n defineAgentCli,\n createAgentCliRuntime,\n} from \"./define-agent-cli.js\"\n// Agent CLI → generic model port: one executor backing every prompt→completion\n// seam (report writer, corpus distiller, Mastra judgment step) over any AIP-45 CLI.\nexport {\n makeAgentCliModel,\n resolveCliEnv,\n composePrompt,\n datasetPreamble,\n PROVIDER_KEY_ENV,\n} from \"./model.js\"\nexport type {\n ModelLike,\n FileReadingOptions,\n AgentCliModelOptions,\n} from \"./model.js\"\n// Exposed so callers can build a sandbox-resident `AgentCliRuntime`\n// against the same protocol layer the host-spawn factory uses, by\n// passing a `ChildProcess`-shaped duck whose stdio is bridged to a\n// remote subprocess (e2b sandbox, ssh, etc.). See guilde's\n// `cli-session-spawn/sandbox-runtime.ts` for a worked example.\nexport {\n createAcpProtocolArm,\n autoAllowPermissionHandler,\n type AcpPermissionHandler,\n type AcpPermissionOutcome,\n type AcpPermissionRequestParams,\n} from \"./protocol/acp-client.js\"\nexport {\n createPrintSession,\n type PrintArmOptions,\n} from \"./protocol/print-arm.js\"\nexport {\n agentCliFrontmatterSchema,\n runtimeConfigSchema,\n type AgentCliFrontmatter,\n type RuntimeConfigInput,\n} from \"./schema.js\"\nexport {\n composeSpawn,\n resolveContinuationStrategy,\n RuntimeConfigError,\n type ComposedSpawn,\n} from \"./manifest/compose.js\"\nexport {\n registerContinuationStrategy,\n getContinuationStrategy,\n listContinuationStrategies,\n} from \"./continuation/registry.js\"\nexport {\n configureNativeResume,\n type NativeResumeHooks,\n} from \"./continuation/strategies/native-resume.js\"\nexport {\n deriveKeyFromScope,\n type ContinuationStrategy,\n type AcquireContext,\n type ReleaseContext,\n type ReleaseOutcome,\n} from \"./continuation/types.js\"\nexport type {\n AgentCliDefinition,\n AgentCliHandle,\n AgentCliProtocol,\n AgentCliSessionMode,\n AgentCliClient,\n AgentCliConnectOptions,\n AgentCliRuntime,\n AgentCliRuntimeSession,\n AgentCliStartOptions,\n AgentCliCapabilities,\n AgentCliInstallMethod,\n AgentCliVersionCheck,\n AgentCliAuth,\n AgentCliSetupStep,\n AgentCliSetupSkipIf,\n AgentCliSetupPersist,\n AgentCliSession,\n AgentCliModels,\n AgentCliMcpBlock,\n AgentCliMode,\n AgentCliOption,\n AgentCliOptionType,\n AgentCliContinuation,\n AgentCliPinnedSessionTuning,\n ContinuationStrategyId,\n ContinuationKeyScope,\n RuntimeConfig,\n TurnContext,\n StreamEvent,\n} from \"./types.js\"\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/model.ts","../src/continuation/strategies/none.ts","../src/continuation/types.ts","../src/continuation/strategies/pinned-session.ts","../src/continuation/strategies/transcript.ts","../src/continuation/strategies/native-resume.ts","../src/continuation/registry.ts","../src/index.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Agent CLI as a model port — turn ANY AIP-45 agent CLI runtime into a generic\n * `complete({system?, prompt}) → {result}` executor. This is the one bridge that\n * lets the SAME registry (hermes, claude-code, opencode, codex, openclaw, …)\n * back any prompt→completion seam: a report's chapter writer, a corpus\n * distiller, a Mastra tool's judgment step. The executor swaps, the prompts\n * (built by each seam's engine) don't.\n *\n * It drives the CLI over **ACP**: per `complete()` it spawns a fresh session,\n * sends one user turn, concatenates the `text-delta` stream until `turn-end`,\n * then closes. Lives here (not in a product) so seams BELOW the products —\n * `@agentproto/corpus` distill, the CLI — can consume it without importing\n * upward. The runner is injectable so assembly is unit-tested without a binary.\n */\n\nimport type { AgentCliRuntime } from \"./types.js\"\n\n/**\n * The minimal structural model port every seam consumes. Anything with this\n * `complete` shape satisfies the corpus `ReportModelPort` / `DistillPort`-backing\n * model / an AIP `ModelPort` — duck-typed, no nominal coupling.\n */\nexport interface ModelLike {\n complete(req: {\n system?: string\n prompt: string\n [k: string]: unknown\n }): Promise<{ result: string }>\n}\n\n/**\n * The \"file-reading sub-agent\" tier — opt-in across every file-IO-capable\n * executor. When `datasetDir` is set the executor is rooted there and granted\n * its own read tools, so instead of being limited to the excerpts a seam quotes\n * in the prompt it can open the primary sources directly and ground first-hand.\n */\nexport interface FileReadingOptions {\n /** Absolute path to the dataset/source root the executor may read from. */\n datasetDir?: string\n}\n\n/** The instruction prepended to a completion when {@link FileReadingOptions.datasetDir} is set. */\nexport function datasetPreamble(datasetDir: string): string {\n return (\n `You have direct read access to the source files under \\`${datasetDir}\\` ` +\n `(e.g. \\`sources/\\` raw captures, \\`entries/\\` refined notes). Use your ` +\n `file-reading tools to consult the primary sources directly when grounding ` +\n `claims — do not rely only on the excerpts quoted in this prompt.`\n )\n}\n\n/** Compose system + prompt with an optional source-access preamble (shared by every executor). */\nexport function composePrompt(\n system: string | undefined,\n prompt: string,\n datasetDir?: string\n): string {\n const head = datasetDir ? `${datasetPreamble(datasetDir)}\\n\\n` : \"\"\n return system ? `${head}${system}\\n\\n${prompt}` : `${head}${prompt}`\n}\n\n/** Provider keys an agent CLI may route through, forwarded from the parent env by default. */\nexport const PROVIDER_KEY_ENV = [\n \"OPENROUTER_API_KEY\",\n \"ANTHROPIC_API_KEY\",\n \"OPENAI_API_KEY\",\n] as const\n\nexport interface AgentCliModelOptions extends FileReadingOptions {\n /**\n * Env handed to the spawned CLI process — the provider key it routes through.\n * Defaults to forwarding {@link PROVIDER_KEY_ENV} from the parent process env.\n */\n env?: Record<string, string>\n /** Working directory for the CLI process. Defaults to `datasetDir` when set. */\n cwd?: string\n /** Timeout per completion (ms). Default 5 min. */\n timeoutMs?: number\n /**\n * Injectable runner (composed prompt → completion text). Defaults to driving\n * the runtime over ACP. Override in tests to avoid the CLI.\n */\n run?: (prompt: string) => Promise<string>\n}\n\n/** Build the env for the spawned CLI: explicit override, else forwarded provider keys. */\nexport function resolveCliEnv(\n opts: Pick<AgentCliModelOptions, \"env\">\n): Record<string, string> {\n if (opts.env) return opts.env\n const env: Record<string, string> = {}\n for (const k of PROVIDER_KEY_ENV) {\n const v = process.env[k]\n if (v) env[k] = v\n }\n return env\n}\n\n/** Drive one ACP turn on `runtime`, concatenating the text deltas. */\nasync function driveTurn(\n runtime: AgentCliRuntime,\n prompt: string,\n opts: AgentCliModelOptions\n): Promise<string> {\n const controller = new AbortController()\n const timer = setTimeout(\n () => controller.abort(),\n opts.timeoutMs ?? 5 * 60 * 1000\n )\n\n const cwd = opts.cwd ?? opts.datasetDir\n const session = await runtime.start({\n env: resolveCliEnv(opts),\n signal: controller.signal,\n ...(cwd ? { cwd } : {}),\n })\n\n try {\n let text = \"\"\n for await (const evt of session.send({ role: \"user\", content: prompt })) {\n if (evt.kind === \"text-delta\") {\n text += evt.text\n } else if (evt.kind === \"error\") {\n throw new Error(`${runtime.definition.id} model: ${evt.error.message}`)\n } else if (evt.kind === \"turn-end\") {\n if (evt.reason !== \"completed\")\n throw new Error(`${runtime.definition.id} model: turn ${evt.reason}`)\n break\n }\n }\n if (controller.signal.aborted)\n throw new Error(`${runtime.definition.id} model: timed out`)\n return text.trim()\n } finally {\n clearTimeout(timer)\n await session.close()\n }\n}\n\n/**\n * Build a {@link ModelLike} backed by an AIP-45 agent-CLI runtime. Hand it any\n * `*Runtime()` from the registry (Hermes, claude-code, opencode, …); per-CLI\n * presets are one-liners over this.\n */\nexport function makeAgentCliModel(\n runtime: AgentCliRuntime,\n opts: AgentCliModelOptions = {}\n): ModelLike {\n const run = opts.run ?? ((prompt: string) => driveTurn(runtime, prompt, opts))\n return {\n async complete({ system, prompt }) {\n return {\n result: await run(composePrompt(system, prompt, opts.datasetDir)),\n }\n },\n }\n}\n","/**\n * `none` strategy — pre-AIP-45-extension behaviour.\n *\n * Spawn a fresh session per acquire; close it on release. No state,\n * no reuse. The default when a manifest declares no `continuation`\n * block (back-compat for adapters that haven't been updated).\n */\n\nimport type { ContinuationStrategy } from \"../types.js\"\n\nexport const noneStrategy: ContinuationStrategy = {\n id: \"none\",\n async acquire(ctx) {\n return ctx.runtime.start(ctx.startOptions)\n },\n async release(ctx) {\n await ctx.session.close()\n },\n}\n","/**\n * AIP-45 ContinuationStrategy interface.\n *\n * A continuation strategy decides HOW prior conversation turns reach a\n * spawned CLI on subsequent invocations. Built-ins handle:\n *\n * - `none` — fresh session per call (current pre-AIP-45 behaviour)\n * - `pinned-session` — keep the spawned child alive, reuse across turns\n * - `transcript` — caller-supplied preamble prepended to each turn\n * - `native-resume` — pass a session id to the CLI's own `--resume` flag\n *\n * Adapter packages MAY register custom strategies via the registry —\n * for example, a Goose-specific strategy that uses MCP-side session\n * load semantics. Custom strategy ids require a follow-up AIP that\n * opens the `ContinuationStrategyId` enum (so the manifest schema can\n * validate them).\n *\n * The strategy owns the SESSION LIFECYCLE: `acquire` returns a session\n * the caller can `send()` against, and `release` decides whether the\n * session lives on (pinned-session) or closes immediately (none). The\n * runner / generation strategy MUST go through `acquire`/`release` —\n * it MUST NOT call `runtime.start()` / `session.close()` directly when\n * a strategy is active.\n */\n\nimport type {\n AgentCliRuntime,\n AgentCliRuntimeSession,\n AgentCliStartOptions,\n ContinuationKeyScope,\n ContinuationStrategyId,\n RuntimeConfig,\n TurnContext,\n} from \"../types.js\"\n\n/**\n * Per-acquire context the strategy gets. The runner builds this from\n * the manifest, the operator config, and the current turn's identity.\n */\nexport interface AcquireContext {\n runtime: AgentCliRuntime\n /** Already-composed start options (cwd / env / signal / config /\n * turnCtx). Strategies MAY override individual fields when they\n * call `runtime.start(...)` themselves. */\n startOptions: AgentCliStartOptions\n /** Per-call config (already validated against the manifest). */\n config: RuntimeConfig\n /** Identity context for key derivation. */\n turnCtx: TurnContext\n}\n\n/**\n * Strategies can hint to the runner about how the turn played out so\n * the strategy can decide whether to keep the session alive (normal\n * end), reset its TTL but keep it (transient error), or evict it\n * (dead-process error).\n */\nexport type ReleaseOutcome =\n | { kind: \"completed\" }\n | { kind: \"cancelled\" }\n | { kind: \"error\"; reason: \"transient\" | \"fatal\"; message: string }\n\nexport interface ReleaseContext {\n session: AgentCliRuntimeSession\n outcome: ReleaseOutcome\n turnCtx: TurnContext\n}\n\n/**\n * The strategy contract. `acquire` returns a session ready for the\n * caller to `send()` against — fresh OR reused. `release` decides\n * the session's fate. Strategies MAY hold internal state (e.g.\n * the pinned-session map) keyed by `turnCtx`.\n */\nexport interface ContinuationStrategy {\n readonly id: ContinuationStrategyId\n acquire(ctx: AcquireContext): Promise<AgentCliRuntimeSession>\n release(ctx: ReleaseContext): Promise<void>\n}\n\n/**\n * Derive a stable pin key from `turnCtx` according to the manifest's\n * `pinned_session.key_scope`. Missing scope fields downgrade to a\n * less-specific key with a warning — pinning still works, it just\n * collides more.\n *\n * Returns `null` when EVERY scope field the manifest asked for is\n * missing (no key derivable; strategy falls back to per-spawn).\n */\nexport function deriveKeyFromScope(\n scope: ContinuationKeyScope[],\n turnCtx: TurnContext\n): string | null {\n const parts: string[] = []\n for (const s of scope) {\n const v = turnCtx[s]\n if (v) parts.push(`${s}=${v}`)\n }\n return parts.length === 0 ? null : parts.join(\"|\")\n}\n","/**\n * `pinned-session` strategy — keep the spawned child alive across\n * turns so the CLI's in-memory model context carries over.\n *\n * Suitable for manifests that declare `session.mode: persistent` AND\n * `context_carryover: true` (Claude Code, OpenCode, ...). Acquires\n * either reuse a live pinned session or spawn fresh and pin; releases\n * keep the session alive and reset its idle TTL. The strategy\n * auto-evicts after the manifest's `pinned_session.idle_timeout_ms`.\n *\n * The pin key is derived from `turnCtx` according to the manifest's\n * `pinned_session.key_scope` (default: `[conversation, operator]` —\n * different conversations and different operators each get their own\n * child process).\n *\n * Lost on process restart. DB-backed pin persistence is a follow-up\n * (track sessionId in `cli_sessions` table, then optionally fall back\n * to native-resume / transcript on restart).\n */\n\nimport type {\n AgentCliRuntimeSession,\n AgentCliRuntime,\n AgentCliStartOptions,\n} from \"../../types.js\"\nimport type { ContinuationStrategy } from \"../types.js\"\nimport { deriveKeyFromScope } from \"../types.js\"\n\ninterface PinnedEntry {\n session: AgentCliRuntimeSession\n /** Cached so retry-after-eviction can recreate without re-resolving\n * the runtime entry from outside. */\n runtime: AgentCliRuntime\n /** Cached so eviction-and-retry uses the same start options. */\n startOptions: AgentCliStartOptions\n idleTimer: ReturnType<typeof setTimeout> | null\n}\n\nconst DEFAULT_IDLE_TIMEOUT_MS = 30 * 60 * 1000\n\nconst pins = new Map<string, PinnedEntry>()\n\nfunction clearIdleTimer(entry: PinnedEntry): void {\n if (entry.idleTimer) {\n clearTimeout(entry.idleTimer)\n entry.idleTimer = null\n }\n}\n\nfunction scheduleIdleEviction(\n key: string,\n entry: PinnedEntry,\n idleTimeoutMs: number\n): void {\n clearIdleTimer(entry)\n entry.idleTimer = setTimeout(() => {\n pins.delete(key)\n entry.session.close().catch(err => {\n console.warn(\n `[pinned-session] idle close failed for ${key}:`,\n err instanceof Error ? err.message : err\n )\n })\n console.log(\n `[pinned-session] ${key} idle ${idleTimeoutMs / 60_000}m → closed`\n )\n }, idleTimeoutMs)\n // Don't keep the event loop alive just for the idle close — the\n // child will be reaped on process exit anyway. Without `unref`\n // a stale pin would block graceful shutdown.\n entry.idleTimer.unref?.()\n}\n\nfunction evictPin(key: string): void {\n const entry = pins.get(key)\n if (!entry) return\n clearIdleTimer(entry)\n pins.delete(key)\n entry.session.close().catch(err => {\n console.warn(\n `[pinned-session] evict close failed for ${key}:`,\n err instanceof Error ? err.message : err\n )\n })\n}\n\nexport const pinnedSessionStrategy: ContinuationStrategy = {\n id: \"pinned-session\",\n\n async acquire(ctx) {\n const tuning = ctx.runtime.definition.continuation?.pinned_session\n const scope = tuning?.key_scope ?? [\"conversation\", \"operator\"]\n const key = deriveKeyFromScope(scope, ctx.turnCtx)\n const idleTimeoutMs = tuning?.idle_timeout_ms ?? DEFAULT_IDLE_TIMEOUT_MS\n\n if (key === null) {\n // No identity to pin against — fall back to per-spawn behaviour.\n // Warn so the host learns to populate turnCtx.\n console.warn(\n `[pinned-session] turnCtx has no fields matching key_scope ${JSON.stringify(scope)}; falling back to per-spawn (no pin).`\n )\n return ctx.runtime.start(ctx.startOptions)\n }\n\n const existing = pins.get(key)\n if (existing) {\n // Cancel the idle timer — this turn is reusing the pin.\n clearIdleTimer(existing)\n return existing.session\n }\n\n const session = await ctx.runtime.start(ctx.startOptions)\n const entry: PinnedEntry = {\n session,\n runtime: ctx.runtime,\n startOptions: ctx.startOptions,\n idleTimer: null,\n }\n pins.set(key, entry)\n scheduleIdleEviction(key, entry, idleTimeoutMs)\n return session\n },\n\n async release(ctx) {\n // Find the entry by identity — ReleaseContext doesn't carry `runtime`,\n // so we match by session reference. Acceptable since the pin map is small.\n let foundKey: string | null = null\n for (const [k, e] of pins) {\n if (e.session === ctx.session) {\n foundKey = k\n break\n }\n }\n\n if (!foundKey) {\n // Session wasn't pinned (per-spawn fallback path) — close it\n // like the `none` strategy would.\n await ctx.session.close()\n return\n }\n\n const entry = pins.get(foundKey)!\n const tuning = entry.runtime.definition.continuation?.pinned_session\n const idleTimeoutMs = tuning?.idle_timeout_ms ?? DEFAULT_IDLE_TIMEOUT_MS\n\n // Fatal errors → evict so the next turn re-spawns. Transient\n // errors and normal completion → reset the idle TTL and keep.\n // Cancelled (user aborted) is treated like normal completion —\n // the user wanted to stop this turn, not the whole session.\n if (ctx.outcome.kind === \"error\" && ctx.outcome.reason === \"fatal\") {\n evictPin(foundKey)\n return\n }\n\n scheduleIdleEviction(foundKey, entry, idleTimeoutMs)\n },\n}\n\n/**\n * Test helper — drop all pinned entries and clear timers. Not part\n * of the public API; exposed under `__test__` so tests can reset the\n * module's singleton state between runs.\n */\nexport const __test__ = {\n resetPins(): void {\n for (const [k] of pins) evictPin(k)\n },\n pinCount(): number {\n return pins.size\n },\n}\n","/**\n * `transcript` strategy — works for any CLI, including those with\n * `resumable: false` and ephemeral sessions.\n *\n * The driver doesn't know about Mastra memory or the host's\n * conversation log — that's the host's domain. The host supplies the\n * preamble at acquire-time via `startOptions.config.options` (the\n * convention is option id `__transcript`, see below) and the strategy\n * is otherwise identical to `none` — fresh session per acquire,\n * close on release.\n *\n * In practice the host does the prepending itself before calling\n * `runtime.start` (it controls the `message` text). This strategy\n * exists mostly as a NAMED policy choice in the manifest — declaring\n * it tells the host \"use the transcript-replay path for this CLI\"\n * without the host needing to inspect capabilities.\n *\n * Token-costly but stateless and survives API restarts.\n */\n\nimport type { ContinuationStrategy } from \"../types.js\"\n\nexport const transcriptStrategy: ContinuationStrategy = {\n id: \"transcript\",\n async acquire(ctx) {\n return ctx.runtime.start(ctx.startOptions)\n },\n async release(ctx) {\n await ctx.session.close()\n },\n}\n","/**\n * `native-resume` strategy — reattach to the agent's own session by id\n * (ACP `loadSession`, MCP equivalent, or argv-style `--resume`).\n *\n * Two-step lifecycle:\n * 1. **acquire**: look up a persisted sessionId for `turnCtx` via\n * `loadHook`. If found, pass it to `runtime.start` as\n * `resumeSessionId` so the protocol arm reattaches. If not, spawn\n * fresh — and after the session is up, capture the new id from\n * `session.sessionId` and persist it via `saveHook`.\n * 2. **release**: close the spawned process. The session lives in\n * the agent's storage layer (e.g. Claude Code's JSONL files);\n * cold-start resume on the next acquire reads from that store.\n *\n * Hooks are registered once per host process via\n * `configureNativeResume({ load, save })`. Without hooks the strategy\n * degrades to per-spawn behaviour with a one-line warning — it's not\n * fatal because the spawn still works, just without continuity.\n *\n * Requires the manifest to declare `capabilities.resumable: true`\n * AND the agent to advertise the matching protocol capability (e.g.\n * ACP `loadSession: true`). The schema enforces the manifest side at\n * validation; runtime capability mismatch surfaces from the protocol\n * arm as the agent's own error.\n */\n\nimport type { ContinuationStrategy, AcquireContext } from \"../types.js\"\nimport { deriveKeyFromScope } from \"../types.js\"\nimport type { TurnContext } from \"../../types.js\"\n\nexport interface NativeResumeHooks {\n /** Look up a persisted sessionId for the given identity scope. Return\n * undefined when no prior session exists — strategy spawns fresh. */\n load: (turnCtx: TurnContext) => Promise<string | undefined>\n /** Persist a freshly-established sessionId so the next cold start\n * can resume. Called once per \"fresh spawn\" acquire (not per turn).\n * Idempotent / upsert semantics expected on the host side. */\n save: (turnCtx: TurnContext, sessionId: string) => Promise<void>\n /** Optional: drop the persisted entry when a session is detected as\n * unresumable (agent rejected loadSession with a hard error). */\n forget?: (turnCtx: TurnContext) => Promise<void>\n}\n\nlet _hooks: NativeResumeHooks | null = null\n\n/**\n * Register the host's session-id load/save callbacks. Call once at\n * boot. Subsequent calls overwrite — useful in tests; in prod treat\n * the registration as exclusive.\n */\nexport function configureNativeResume(hooks: NativeResumeHooks): void {\n _hooks = hooks\n}\n\n/** Reset to no-hooks. Test helper; not part of public API. */\nexport function __resetNativeResumeForTests(): void {\n _hooks = null\n}\n\nexport const nativeResumeStrategy: ContinuationStrategy = {\n id: \"native-resume\",\n async acquire(ctx: AcquireContext) {\n if (!_hooks) {\n console.warn(\n \"[native-resume] no hooks registered (call configureNativeResume at boot); falling back to per-spawn — no continuity.\"\n )\n return ctx.runtime.start(ctx.startOptions)\n }\n // Use the same key-derivation as pinned-session so a host can\n // declare its scope ONCE in the manifest (`continuation.pinned_session.key_scope`)\n // and have both strategies key off the same identity. Native-resume\n // doesn't have its own key_scope today; it inherits.\n const scope =\n ctx.runtime.definition.continuation?.pinned_session?.key_scope ?? [\n \"conversation\",\n \"operator\",\n ]\n const key = deriveKeyFromScope(scope, ctx.turnCtx)\n if (key === null) {\n console.warn(\n `[native-resume] turnCtx has no fields matching key_scope ${JSON.stringify(scope)}; falling back to per-spawn (no resume).`\n )\n return ctx.runtime.start(ctx.startOptions)\n }\n\n const existingId = await _hooks.load(ctx.turnCtx).catch(err => {\n console.warn(\n `[native-resume] load hook failed for ${key}:`,\n err instanceof Error ? err.message : err\n )\n return undefined\n })\n\n let session\n let resumed = false\n if (existingId) {\n try {\n session = await ctx.runtime.start({\n ...ctx.startOptions,\n resumeSessionId: existingId,\n })\n resumed = true\n } catch (err) {\n // Most likely the agent rejected the id (session expired,\n // wiped, mismatched cwd). Drop the stale pin and spawn fresh\n // so the user gets continuity going forward instead of being\n // stuck on a dead reference.\n console.warn(\n `[native-resume] resume failed for ${key} (id=${existingId.slice(0, 12)}…), starting fresh:`,\n err instanceof Error ? err.message : err\n )\n if (_hooks.forget) {\n await _hooks.forget(ctx.turnCtx).catch(() => undefined)\n }\n session = await ctx.runtime.start(ctx.startOptions)\n }\n } else {\n session = await ctx.runtime.start(ctx.startOptions)\n }\n\n // Persist the established id when this is a NEW session (resume\n // path keeps the same id we already have, no need to re-save).\n // The runtime guarantees session.sessionId reflects the protocol\n // session id when the arm exposes it.\n if (!resumed && session.sessionId) {\n await _hooks.save(ctx.turnCtx, session.sessionId).catch(err => {\n console.warn(\n `[native-resume] save hook failed for ${key}:`,\n err instanceof Error ? err.message : err\n )\n })\n }\n return session\n },\n\n async release(ctx) {\n // The protocol session lives in the agent's own storage; closing\n // the spawned subprocess is fine — `loadSession` on the next\n // acquire reattaches via the persisted id.\n await ctx.session.close()\n },\n}\n","/**\n * Continuation strategy registry.\n *\n * Module-scoped singleton — all built-ins are registered at import\n * time, custom strategies (from adapter packages) register via\n * `registerContinuationStrategy`. The runner looks up by id;\n * unregistered ids throw at acquire-time so the caller fails fast\n * with a clear \"this strategy id isn't registered\" message.\n */\n\nimport type { ContinuationStrategyId } from \"../types.js\"\nimport type { ContinuationStrategy } from \"./types.js\"\nimport { noneStrategy } from \"./strategies/none.js\"\nimport { pinnedSessionStrategy } from \"./strategies/pinned-session.js\"\nimport { transcriptStrategy } from \"./strategies/transcript.js\"\nimport { nativeResumeStrategy } from \"./strategies/native-resume.js\"\n\nconst registry = new Map<ContinuationStrategyId, ContinuationStrategy>()\n\n/**\n * Register (or replace) a continuation strategy. Adapter packages\n * MAY register custom strategies on import — but they MUST first\n * land an AIP that opens the `ContinuationStrategyId` enum so the\n * manifest schema accepts the new id.\n */\nexport function registerContinuationStrategy(\n strategy: ContinuationStrategy\n): void {\n registry.set(strategy.id, strategy)\n}\n\nexport function getContinuationStrategy(\n id: ContinuationStrategyId\n): ContinuationStrategy {\n const s = registry.get(id)\n if (!s) {\n throw new Error(\n `[agent-cli] No continuation strategy registered for id '${id}'. Built-ins: ${Array.from(registry.keys()).join(\", \")}.`\n )\n }\n return s\n}\n\nexport function listContinuationStrategies(): ContinuationStrategyId[] {\n return Array.from(registry.keys())\n}\n\n// Register built-ins eagerly at module load so any importer of the\n// registry sees them. Custom strategies layer on top.\nregisterContinuationStrategy(noneStrategy)\nregisterContinuationStrategy(pinnedSessionStrategy)\nregisterContinuationStrategy(transcriptStrategy)\nregisterContinuationStrategy(nativeResumeStrategy)\n","/**\n * @agentproto/driver-agent-cli — AIP-45 AGENT-CLI.md `defineAgentCli`\n * reference impl.\n *\n * Spec: https://agentproto.sh/docs/aip-45\n *\n * Authoring paths:\n * - TS: `defineAgentCli({...})` → `AgentCliHandle`\n * - MD: `parseAgentCliManifest(src) → agentCliFromManifest({...})` → `AgentCliHandle`\n *\n * Runtime: `createAgentCliRuntime(handle)` → spawn binary, dispatch\n * turns through the protocol arm (acp / mcp / proprietary), normalise\n * events to {@link StreamEvent}.\n */\n\nexport const SPEC_NAME = \"agentcli-interactive/v1\" as const\nexport const SPEC_VERSION = \"0.1.0-alpha\" as const\n\nexport {\n defineAgentCli,\n createAgentCliRuntime,\n} from \"./define-agent-cli.js\"\n// Agent CLI → generic model port: one executor backing every prompt→completion\n// seam (report writer, corpus distiller, Mastra judgment step) over any AIP-45 CLI.\nexport {\n makeAgentCliModel,\n resolveCliEnv,\n composePrompt,\n datasetPreamble,\n PROVIDER_KEY_ENV,\n} from \"./model.js\"\nexport type {\n ModelLike,\n FileReadingOptions,\n AgentCliModelOptions,\n} from \"./model.js\"\n// Exposed so callers can build a sandbox-resident `AgentCliRuntime`\n// against the same protocol layer the host-spawn factory uses, by\n// passing a `ChildProcess`-shaped duck whose stdio is bridged to a\n// remote subprocess (e2b sandbox, ssh, etc.). See guilde's\n// `cli-session-spawn/sandbox-runtime.ts` for a worked example.\nexport {\n createAcpProtocolArm,\n autoAllowPermissionHandler,\n planModePermissionHandler,\n type AcpPermissionHandler,\n type AcpPermissionOutcome,\n type AcpPermissionRequestParams,\n} from \"./protocol/acp-client.js\"\nexport {\n createPrintSession,\n mapMastraEvent,\n createMastraMapperState,\n type PrintArmOptions,\n type MastraMapperState,\n} from \"./protocol/print-arm.js\"\n// Generic proprietary-protocol arm loader — dynamically imports the\n// manifest's `adapter` package. Exported so proprietary adapter packages\n// (and their tests) can drive the same loader `createAgentCliRuntime`\n// uses, without duplicating the load-and-validate logic.\nexport {\n createProprietaryProtocolArm,\n type ProprietaryProtocolOptions,\n} from \"./protocol/proprietary.js\"\nexport {\n agentCliFrontmatterSchema,\n runtimeConfigSchema,\n type AgentCliFrontmatter,\n type RuntimeConfigInput,\n} from \"./schema.js\"\nexport {\n toFileBasedMcpServers,\n type MastracodeMcpServerConfig,\n} from \"./mcp-servers.js\"\nexport {\n composeSpawn,\n resolveContinuationStrategy,\n RuntimeConfigError,\n type ComposedSpawn,\n} from \"./manifest/compose.js\"\nexport {\n registerContinuationStrategy,\n getContinuationStrategy,\n listContinuationStrategies,\n} from \"./continuation/registry.js\"\nexport {\n configureNativeResume,\n type NativeResumeHooks,\n} from \"./continuation/strategies/native-resume.js\"\nexport {\n deriveKeyFromScope,\n type ContinuationStrategy,\n type AcquireContext,\n type ReleaseContext,\n type ReleaseOutcome,\n} from \"./continuation/types.js\"\nexport type {\n AgentCliDefinition,\n AgentCliHandle,\n AgentCliProtocol,\n AgentCliSessionMode,\n AgentCliClient,\n AgentCliConnectOptions,\n AgentCliRuntime,\n AgentCliRuntimeSession,\n AgentCliStartOptions,\n AgentCliCapabilities,\n AgentCliInstallMethod,\n AgentCliVersionCheck,\n AgentCliAuth,\n AgentCliSetupStep,\n AgentCliSetupSkipIf,\n AgentCliSetupPersist,\n AgentCliSession,\n AgentCliModels,\n AgentCliMcpBlock,\n AgentCliMode,\n AgentCliOption,\n AgentCliOptionType,\n AgentCliPresetDeclaration,\n AgentCliContinuation,\n AgentCliPinnedSessionTuning,\n AgentCliPrintConfig,\n ContinuationStrategyId,\n ContinuationKeyScope,\n RuntimeConfig,\n TurnContext,\n StreamEvent,\n} from \"./types.js\"\n"]}
|
package/dist/manifest/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export {
|
|
1
|
+
import { l as AgentCliFrontmatter, A as AgentCliHandle } from '../schema-L-2rEB1H.js';
|
|
2
|
+
export { E as agentCliFrontmatterSchema } from '../schema-L-2rEB1H.js';
|
|
3
3
|
import '@agentproto/acp';
|
|
4
4
|
import 'zod';
|
|
5
5
|
|
package/dist/manifest/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { agentCliFrontmatterSchema, defineAgentCli } from '../chunk-
|
|
2
|
-
export { agentCliFrontmatterSchema } from '../chunk-
|
|
1
|
+
import { agentCliFrontmatterSchema, defineAgentCli } from '../chunk-L6BRNMVP.mjs';
|
|
2
|
+
export { agentCliFrontmatterSchema } from '../chunk-L6BRNMVP.mjs';
|
|
3
3
|
import matter from 'gray-matter';
|
|
4
4
|
|
|
5
5
|
/**
|