@agentproto/runtime 5.2.1 → 5.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/README.md +18 -0
- package/dist/bundles.d.ts +67 -0
- package/dist/bundles.mjs +173 -0
- package/dist/bundles.mjs.map +1 -0
- package/dist/catalog-models.d.ts +2 -3
- package/dist/config-Gz7q9yfJ.d.ts +761 -0
- package/dist/config-schema.d.ts +9 -3
- package/dist/config-schema.mjs +162 -12
- package/dist/config-schema.mjs.map +1 -1
- package/dist/config.d.ts +2 -611
- package/dist/config.mjs +169 -14
- package/dist/config.mjs.map +1 -1
- package/dist/index.d.ts +674 -541
- package/dist/index.mjs +10647 -4135
- package/dist/index.mjs.map +1 -1
- package/dist/mcp-imports.d.ts +73 -1
- package/dist/mcp-imports.mjs +146 -4
- package/dist/mcp-imports.mjs.map +1 -1
- package/dist/resume-strategies.mjs.map +1 -1
- package/dist/{session-config-RyRL2AbD.d.ts → session-config-DxIIuJFY.d.ts} +1 -1
- package/dist/session-presence.mjs +160 -11
- package/dist/session-presence.mjs.map +1 -1
- package/dist/session-story.mjs +1 -0
- package/dist/session-story.mjs.map +1 -1
- package/dist/{sessions-g4fw_zKx.d.ts → sessions-DMzCgTVy.d.ts} +647 -12
- package/dist/{spawn-defaults-CHvz85DD.d.ts → spawn-defaults-Cp9SGZex.d.ts} +103 -2
- package/dist/user-presets.d.ts +5 -3
- package/package.json +43 -30
- package/dist/context-continuity-BfNVbX5W.d.ts +0 -104
|
@@ -0,0 +1,761 @@
|
|
|
1
|
+
import { S as SpawnDefaultsConfig } from './spawn-defaults-Cp9SGZex.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Model roles — ONE place to say "which model does role X use".
|
|
5
|
+
*
|
|
6
|
+
* A role is a dotted name for a job a model does inside agentproto
|
|
7
|
+
* (`review.small`, `review.large`, `review.pr`, `judge.session`, …).
|
|
8
|
+
* Consumers (the repo-maintenance workflow, the session-steward, agent
|
|
9
|
+
* manifests via `model: role:<name>`, and later the CI reviewer and the
|
|
10
|
+
* local push gate) ask for the ROLE instead of hard-coding a model id, so
|
|
11
|
+
* "use GLM for review" is one config edit, not five files in three formats.
|
|
12
|
+
*
|
|
13
|
+
* PRECEDENCE — the single definition (highest first):
|
|
14
|
+
* 1. `input` an explicit workflow/run input (`reviewModelSmall`, …)
|
|
15
|
+
* 2. `workspace` the repo's own `agentproto.json` → `models`
|
|
16
|
+
* 3. `daemon` `~/.agentproto/config.json` → `models`
|
|
17
|
+
* 4. `default` {@link DEFAULT_MODEL_ROLES} below — the only built-in table
|
|
18
|
+
*
|
|
19
|
+
* Every resolution reports which layer won (`source`). A layer value that is
|
|
20
|
+
* empty or not a string / `{ model }` object is skipped, never fatal.
|
|
21
|
+
*
|
|
22
|
+
* This file is pure (no I/O) so the config schema can import it without a
|
|
23
|
+
* cycle; the loaders + the `model_roles` MCP tool live in
|
|
24
|
+
* `model-roles-tools.ts`.
|
|
25
|
+
*/
|
|
26
|
+
/** Object form of a role value: a model id plus optional serving hints. */
|
|
27
|
+
interface ModelRoleEntry {
|
|
28
|
+
model: string;
|
|
29
|
+
/** Router/gateway the model should be reached through (e.g. `openrouter`). */
|
|
30
|
+
route?: string;
|
|
31
|
+
/** Named auth profile to spawn the role's session with. */
|
|
32
|
+
profile?: string;
|
|
33
|
+
}
|
|
34
|
+
/** A role value as written in a config file: a bare model id, or an entry. */
|
|
35
|
+
type ModelRoleValue = string | ModelRoleEntry;
|
|
36
|
+
/** ROLE → value, the shape of the `models` block in every layer. */
|
|
37
|
+
type ModelRolesConfig = Record<string, ModelRoleValue>;
|
|
38
|
+
type ModelRoleSource = "input" | "workspace" | "daemon" | "default";
|
|
39
|
+
/** The built-in defaults — the ONLY hard-coded model ids for these jobs. */
|
|
40
|
+
declare const DEFAULT_MODEL_ROLES: Readonly<Record<string, string>>;
|
|
41
|
+
/** Prefix an agent manifest's `model:` uses to reference a role. */
|
|
42
|
+
declare const MODEL_ROLE_REF_PREFIX = "role:";
|
|
43
|
+
interface ModelRoleContext {
|
|
44
|
+
/** Explicit per-run values keyed by role (layer 1). */
|
|
45
|
+
input?: Record<string, ModelRoleValue | undefined> | undefined;
|
|
46
|
+
/** The workspace/repo `models` block (layer 2). */
|
|
47
|
+
workspace?: Record<string, unknown> | undefined;
|
|
48
|
+
/** The daemon config `models` block (layer 3). */
|
|
49
|
+
daemon?: Record<string, unknown> | undefined;
|
|
50
|
+
}
|
|
51
|
+
interface ResolvedModelRole {
|
|
52
|
+
role: string;
|
|
53
|
+
model: string;
|
|
54
|
+
route?: string;
|
|
55
|
+
profile?: string;
|
|
56
|
+
source: ModelRoleSource;
|
|
57
|
+
}
|
|
58
|
+
/** `role:review.large` → `review.large`; undefined for a non-role string. */
|
|
59
|
+
declare function parseModelRoleRef(ref: string): string | undefined;
|
|
60
|
+
/**
|
|
61
|
+
* Resolve ONE role through the precedence chain. `undefined` only when no
|
|
62
|
+
* layer — including the built-in table — knows the role.
|
|
63
|
+
*/
|
|
64
|
+
declare function resolveModelRole(role: string, ctx?: ModelRoleContext): ResolvedModelRole | undefined;
|
|
65
|
+
/**
|
|
66
|
+
* Every role in play — the built-in ones plus any a layer configures — each
|
|
67
|
+
* resolved with its source, sorted by role name. `roles` narrows the list
|
|
68
|
+
* (an unknown role with no value anywhere is simply omitted).
|
|
69
|
+
*/
|
|
70
|
+
declare function listModelRoles(ctx?: ModelRoleContext, roles?: readonly string[]): ResolvedModelRole[];
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* `~/.agentproto/config.json` — single hand-editable JSON for the
|
|
74
|
+
* agentproto control plane's defaults. Sits alongside the existing
|
|
75
|
+
* surface files (workspaces.json, credentials.json, sessions.json):
|
|
76
|
+
*
|
|
77
|
+
* workspaces.json which directories are workspaces + which is active
|
|
78
|
+
* credentials.json tunnel host bearer tokens (mode 0600)
|
|
79
|
+
* sessions.json last-known snapshot of the registry (informational)
|
|
80
|
+
* config.json daemon defaults: port, bind, allowed origins,
|
|
81
|
+
* tunnel host, feature toggles
|
|
82
|
+
*
|
|
83
|
+
* Resolution order for every daemon knob is:
|
|
84
|
+
* 1. CLI flag (e.g. --port)
|
|
85
|
+
* 2. Env var (where one exists, e.g. AGENTPROTO_TOKEN)
|
|
86
|
+
* 3. config.json
|
|
87
|
+
* 4. Hardcoded default
|
|
88
|
+
*
|
|
89
|
+
* This means a user can call `agentproto config set daemon.port 18791`
|
|
90
|
+
* once and never re-pass `--port 18791` to `serve install` etc. CLI
|
|
91
|
+
* flags still win for one-off overrides.
|
|
92
|
+
*
|
|
93
|
+
* Schema is intentionally narrow + extensible — unknown keys are
|
|
94
|
+
* preserved on save (deep-merge), so a newer CLI writing a new
|
|
95
|
+
* field won't drop one an older CLI doesn't know about. No secrets
|
|
96
|
+
* here; credentials stay in credentials.json (mode 0600).
|
|
97
|
+
*/
|
|
98
|
+
|
|
99
|
+
declare const CONFIG_VERSION: 1;
|
|
100
|
+
interface DaemonConfig {
|
|
101
|
+
/** Absolute path to the workspace the daemon binds to at boot. */
|
|
102
|
+
workspace?: string;
|
|
103
|
+
/** HTTP port. Default 18790. */
|
|
104
|
+
port?: number;
|
|
105
|
+
/** Bind addr. Default 127.0.0.1. */
|
|
106
|
+
bind?: string;
|
|
107
|
+
/** Trusted browser origins for mutating /sessions/* routes (in
|
|
108
|
+
* addition to the hardcoded localhost defaults). */
|
|
109
|
+
allowedOrigins?: string[];
|
|
110
|
+
/** When true, the daemon does NOT auto-trust localhost-on-any-port.
|
|
111
|
+
* Only origins explicitly listed in `allowedOrigins` are allowed.
|
|
112
|
+
* Pair with a curated list (e.g. `["http://localhost:3000"]`) for
|
|
113
|
+
* hardened setups. Default false. */
|
|
114
|
+
strictOrigins?: boolean;
|
|
115
|
+
/** Server label sent in tunnel hello frames. */
|
|
116
|
+
label?: string;
|
|
117
|
+
/** Bearer token gating the gateway at boot (`AuthOptions` with
|
|
118
|
+
* `mode: "bearer"`). Unlike `remote_enable`'s ephemeral quick-tunnel
|
|
119
|
+
* token, this one lives in config.json and survives daemon restarts.
|
|
120
|
+
* Set via `agentproto config set daemon.authToken <token>` (e.g.
|
|
121
|
+
* `$(openssl rand -hex 32)`). Unset ⇒ the gateway boots with
|
|
122
|
+
* `mode: "none"` — fully open on loopback, same as today. */
|
|
123
|
+
authToken?: string;
|
|
124
|
+
/** Opt-in eager resume-on-boot (session-survivability plan §5
|
|
125
|
+
* "Opt-in vs automatic", PR-4). When true, a daemon restart doesn't just
|
|
126
|
+
* leave agent-cli sessions dead-but-lazy-resumable — the boot pass eagerly
|
|
127
|
+
* re-spawns the eligible ones (those that died with
|
|
128
|
+
* `endedReason: "daemon-restart"` and still pass `canResume`) IN PLACE,
|
|
129
|
+
* restoring liveness without waiting for a prompt. Lazy resume-on-prompt is
|
|
130
|
+
* always on regardless of this flag (it costs nothing until someone acts);
|
|
131
|
+
* this flag only controls the *automatic* boot-time pass. Default false: a
|
|
132
|
+
* box-wide restart should not silently relaunch every adapter (cost, spawn
|
|
133
|
+
* storm, credential re-resolution), and default-off also keeps two daemons
|
|
134
|
+
* sharing the workspace buckets from racing to resume the same rows. Set via
|
|
135
|
+
* `agentproto config set daemon.resumeSessionsOnBoot true`. Surfaced in
|
|
136
|
+
* `daemon_health` / `GET /health`. */
|
|
137
|
+
resumeSessionsOnBoot?: boolean;
|
|
138
|
+
/** Opt-in continue-on-boot (continue-interrupted). When true, right after
|
|
139
|
+
* the eager resume pass, the boot sends a "the daemon restarted mid-turn,
|
|
140
|
+
* check the state on disk and continue" prompt to every session the LAST
|
|
141
|
+
* restart interrupted mid-turn (`interrupted: true`) that is resumable,
|
|
142
|
+
* under the resume cap, idle, and whose resume didn't fail. Never loops: at
|
|
143
|
+
* most one auto-continue per restart and `MAX_AUTO_CONTINUE_ATTEMPTS` in a
|
|
144
|
+
* row without a successful turn-end. Default false — the interrupted prompt
|
|
145
|
+
* itself is never auto-retried, and a continue prompt is still a prompt
|
|
146
|
+
* (tokens, side effects), so it's opt-in. The manual
|
|
147
|
+
* `session_continue_interrupted` verb works regardless. Set via
|
|
148
|
+
* `agentproto config set daemon.continueInterruptedOnBoot true`. */
|
|
149
|
+
continueInterruptedOnBoot?: boolean;
|
|
150
|
+
/** Idle agent-session reaper (PR-6). When set to a positive number of
|
|
151
|
+
* milliseconds, the daemon periodically retires agent-cli sessions that have
|
|
152
|
+
* been idle (not busy, not awaiting input, `status:"running"`) longer than
|
|
153
|
+
* this: it SIGTERMs the adapter child to free the process and flips the row
|
|
154
|
+
* to `killed`/`endedReason:"idle-reaped"` — dead-but-lazy-resumable (a later
|
|
155
|
+
* prompt revives it) and, critically, excluded from eager resume-on-boot
|
|
156
|
+
* (#638 gates on `endedReason === "daemon-restart"`), so enabling this makes
|
|
157
|
+
* eager resume safe: only genuinely-recent work survives a restart. Default
|
|
158
|
+
* OFF (unset / 0 / negative ⇒ the reaper never runs). Resolution order
|
|
159
|
+
* mirrors the module docblock: `AGENTPROTO_IDLE_REAP_AFTER_MS` env > this
|
|
160
|
+
* field > off. Set via `agentproto config set daemon.idleReapAfterMs
|
|
161
|
+
* <ms>`. Surfaced in `daemon_health` / `GET /health`. */
|
|
162
|
+
idleReapAfterMs?: number;
|
|
163
|
+
/** Crash-detect sweep interval in ms (crash-detect PR-1). Unlike
|
|
164
|
+
* `idleReapAfterMs`, this is DEFAULT ON (non-destructive observability):
|
|
165
|
+
* the daemon periodically probes every live agent-cli session's OS
|
|
166
|
+
* process (`process.kill(pid, 0)`) and, when it's provably gone with no
|
|
167
|
+
* exit event ever emitted for it, flips the row to
|
|
168
|
+
* `error`/`endedReason:"crashed"` with a `lastError` string — surfacing a
|
|
169
|
+
* death that would otherwise sit silently as `status:"running"` until the
|
|
170
|
+
* next prompt's RPC throws (or forever, for a parked session with no next
|
|
171
|
+
* prompt). Detects only; never restarts or notifies (later PRs). Set to a
|
|
172
|
+
* non-positive value to disable the sweep entirely. Resolution order
|
|
173
|
+
* mirrors `idleReapAfterMs`: `AGENTPROTO_CRASH_DETECT_INTERVAL_MS` env >
|
|
174
|
+
* this field > the hardcoded default (30s). Set via `agentproto config
|
|
175
|
+
* set daemon.crashDetectIntervalMs <ms>`. Surfaced in `daemon_health` /
|
|
176
|
+
* `GET /health`. */
|
|
177
|
+
crashDetectIntervalMs?: number;
|
|
178
|
+
/** Restart-scheduler sweep interval in ms (restart-scheduler PR-2). OFF by
|
|
179
|
+
* default (unset / 0 / negative ⇒ the sweep never runs), unlike
|
|
180
|
+
* `crashDetectIntervalMs` — a positive value here only arms the periodic
|
|
181
|
+
* sweep that EXECUTES an already-scheduled restart; it never opts a
|
|
182
|
+
* session in by itself (that's the per-session `agent_start.restartPolicy`
|
|
183
|
+
* field). Resolution order mirrors `idleReapAfterMs`:
|
|
184
|
+
* `AGENTPROTO_RESTART_SWEEP_INTERVAL_MS` env > this field > off. Set via
|
|
185
|
+
* `agentproto config set daemon.restartSweepIntervalMs <ms>`. Surfaced in
|
|
186
|
+
* `daemon_health` / `GET /health`. */
|
|
187
|
+
restartSweepIntervalMs?: number;
|
|
188
|
+
/** Turn-liveness watchdog threshold in ms (turn-liveness-watchdog
|
|
189
|
+
* chantier). Same shape as `crashDetectIntervalMs`: DEFAULT ON
|
|
190
|
+
* (non-destructive observability). The daemon periodically sweeps every
|
|
191
|
+
* BUSY agent-cli session and, for one that is mid-turn, NOT legitimately
|
|
192
|
+
* `blockedOn` a subagent/command, and has had no adapter activity
|
|
193
|
+
* (`lastActivityAt`) for longer than this threshold, stamps
|
|
194
|
+
* `stalledSinceMs` on the descriptor and emits `session:stalled` —
|
|
195
|
+
* surfacing a dead adapter stream (network drop, hung child — zero
|
|
196
|
+
* frames mid-turn) that would otherwise sit indistinguishable from
|
|
197
|
+
* healthy long work: `status:"running"`, `lastError:null`, no other
|
|
198
|
+
* signal. Conservative by design: a session legitimately blocked on a
|
|
199
|
+
* long tool call is NEVER a candidate, no matter how long it's silent —
|
|
200
|
+
* see `stall-watchdog.ts`'s docblock for why. Detects only; never kills
|
|
201
|
+
* or restarts (this is a later concern, if ever). Set to a non-positive
|
|
202
|
+
* value to disable the sweep entirely. Resolution order mirrors
|
|
203
|
+
* `idleReapAfterMs`: `AGENTPROTO_TURN_STALL_AFTER_MS` env > this field >
|
|
204
|
+
* the hardcoded default (5 min). Set via `agentproto config set
|
|
205
|
+
* daemon.turnStallAfterMs <ms>`. Surfaced in `daemon_health` /
|
|
206
|
+
* `GET /health`. */
|
|
207
|
+
turnStallAfterMs?: number;
|
|
208
|
+
}
|
|
209
|
+
interface TitlerConfig {
|
|
210
|
+
/** Enable the daemon-side session titler. Default false. */
|
|
211
|
+
enabled?: boolean;
|
|
212
|
+
/** OpenRouter model id used to generate titles. Default
|
|
213
|
+
* `z-ai/glm-5.2@openrouter`. Requires `OPENROUTER_API_KEY` in the
|
|
214
|
+
* daemon's environment; without a key the titler falls back to the
|
|
215
|
+
* local (first-prompt-line) title. */
|
|
216
|
+
model?: string;
|
|
217
|
+
}
|
|
218
|
+
interface JevConfig {
|
|
219
|
+
/** Jev (TypeSafe System One) API key. Read by `resolveJevApiKey` BEFORE
|
|
220
|
+
* the `JEV_API_KEY` environment variable: the config file is the
|
|
221
|
+
* primary home for this first-party secret and the env var is the
|
|
222
|
+
* fallback. Secret: redacted by `config_get`. */
|
|
223
|
+
apiKey?: string;
|
|
224
|
+
/** Jev model id. Default `jev-latest`. */
|
|
225
|
+
model?: string;
|
|
226
|
+
/** Jev endpoint override. Default `https://api.typesafe.ai/v1/systemone`. */
|
|
227
|
+
baseUrl?: string;
|
|
228
|
+
}
|
|
229
|
+
interface CatalogSourceConfig {
|
|
230
|
+
/** HTTP(S) URL returning `{ entries: AppCatalogEntry[] }`. */
|
|
231
|
+
url: string;
|
|
232
|
+
}
|
|
233
|
+
interface CatalogConfig {
|
|
234
|
+
/** Remote app-catalog sources merged into `app_catalog`. When set, these
|
|
235
|
+
* win over `sources` in `~/.agentproto/app-catalog.json`. */
|
|
236
|
+
sources?: CatalogSourceConfig[];
|
|
237
|
+
}
|
|
238
|
+
interface TunnelConfig {
|
|
239
|
+
/** Cloud WS URL. When set + autoconnect=true, `agentproto serve`
|
|
240
|
+
* bootstraps with `--connect <host>`. */
|
|
241
|
+
host?: string;
|
|
242
|
+
/** apt_ daemon token to present at the tunnel upgrade. When set,
|
|
243
|
+
* `agentproto serve` uses this BEFORE falling back to
|
|
244
|
+
* credentials.json — handy in profiles where the token-per-host
|
|
245
|
+
* mapping in credentials.json doesn't fit (e.g. host = tunnel URL
|
|
246
|
+
* but credentials were minted against the api URL). */
|
|
247
|
+
token?: string;
|
|
248
|
+
/** Whether `agentproto daemon start` connects the tunnel by
|
|
249
|
+
* default. v0 only — implementer can ignore until daemon needs it. */
|
|
250
|
+
autoconnect?: boolean;
|
|
251
|
+
/**
|
|
252
|
+
* Opt into end-to-end encryption of the outbound `serve --connect` tunnel
|
|
253
|
+
* (design: tunnel-e2e/v1). When true, the daemon negotiates a
|
|
254
|
+
* token-authenticated ephemeral handshake with the host and wraps the tunnel
|
|
255
|
+
* frames in an AEAD box, so even the trusted host loses plaintext visibility.
|
|
256
|
+
* The handshake authenticates both ends against the shared `tunnel.token`, so
|
|
257
|
+
* `token` MUST also be set. Fully backward-compatible: if the host doesn't
|
|
258
|
+
* advertise e2e (an older host), the daemon falls back to today's plaintext
|
|
259
|
+
* tunnel. Unset/false ⇒ plaintext, byte-identical to today. */
|
|
260
|
+
e2e?: boolean;
|
|
261
|
+
}
|
|
262
|
+
interface FeaturesConfig {
|
|
263
|
+
/** Hint that PTY is desired — informational; the daemon still
|
|
264
|
+
* detects node-pty's presence at runtime. */
|
|
265
|
+
pty?: boolean;
|
|
266
|
+
/** Enable the local LLM Endpoint proxy sidecar (route registration,
|
|
267
|
+
* MCP tools, child-process lifecycle). Default false — the endpoint is
|
|
268
|
+
* an opt-in feature; when off, the `llm-endpoint` custom route is not
|
|
269
|
+
* registered and the `llm_endpoint_*` MCP tools are not exposed. */
|
|
270
|
+
llmEndpoint?: boolean;
|
|
271
|
+
/** Expose this daemon's local inference endpoint(s) (the `llmEndpoint`
|
|
272
|
+
* sidecar above) to paired controllers over a HOST-scoped pairing —
|
|
273
|
+
* `GET /device-inference/v1/models` + `POST
|
|
274
|
+
* /device-inference/v1/chat/completions` in http-server.ts. Default
|
|
275
|
+
* false: even with `llmEndpoint` on, a plain remote-control pairing (or
|
|
276
|
+
* `serve --connect`) never gets these routes regardless of this flag —
|
|
277
|
+
* it also requires the pairing itself to be host-scoped (`pair offer
|
|
278
|
+
* --host` + `devices add`). Toggle via `agentproto devices
|
|
279
|
+
* share-inference on|off`. */
|
|
280
|
+
deviceInferenceShare?: boolean;
|
|
281
|
+
/** Opt this daemon in to being usable as an `agent_start({ sandbox:
|
|
282
|
+
* "device:<name>" })` target (DEVICES-PLAN PR-D) — exposes
|
|
283
|
+
* `/device-spawn/*` in http-server.ts, a self-proxy onto this daemon's
|
|
284
|
+
* own `/mcp` + `/sessions/:id/events/stream`. Default false: even with
|
|
285
|
+
* this on, only a HOST-scoped pairing (`pair offer --host` + `devices
|
|
286
|
+
* add`) can reach the routes — a plain remote-control pairing never can,
|
|
287
|
+
* whatever this is set to. Toggle via `agentproto devices allow-spawn
|
|
288
|
+
* on|off`. */
|
|
289
|
+
deviceSpawnAllow?: boolean;
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Policy for `agentproto worktree new` (PLAN.md §1.4 — config carries
|
|
293
|
+
* policy, never state; git itself is the authority for which worktrees
|
|
294
|
+
* exist). This is the fix for the sprawl the plan measured: 31 linked
|
|
295
|
+
* worktrees across 6 different parent directories, because there was no
|
|
296
|
+
* `worktree new` verb and therefore no convention to converge on.
|
|
297
|
+
*/
|
|
298
|
+
/**
|
|
299
|
+
* How the daemon isolates a freshly-spawned agent session into its own git
|
|
300
|
+
* worktree (`agent_start.worktree`):
|
|
301
|
+
* - `"always"` — every depth-0 spawn is provisioned into a worktree,
|
|
302
|
+
* whether or not the caller asked. A cwd that is not in
|
|
303
|
+
* a git repo has nothing to isolate, so it spawns plain.
|
|
304
|
+
* - `"on-request"` — isolate ONLY when the caller passes `worktree`. This
|
|
305
|
+
* is the default and the back-compatible behaviour:
|
|
306
|
+
* today's callers pass nothing and spawn exactly where
|
|
307
|
+
* they asked.
|
|
308
|
+
* - `"never"` — isolation is off; an explicit `worktree` field is
|
|
309
|
+
* REJECTED (loud, not silently ignored) so a caller
|
|
310
|
+
* never believes it got an isolated tree it didn't.
|
|
311
|
+
*/
|
|
312
|
+
type WorktreeIsolationMode = "always" | "on-request" | "never";
|
|
313
|
+
interface WorktreesConfig {
|
|
314
|
+
/**
|
|
315
|
+
* Absolute path new worktrees are created under. Layout:
|
|
316
|
+
* `<root>/<repoName>/<slug>`. Resolution order (mirrors every other
|
|
317
|
+
* knob in this file, see the module docblock): `--root` flag >
|
|
318
|
+
* `AGENTPROTO_WORKTREES_ROOT` env > this field > the hardcoded default
|
|
319
|
+
* `~/.agentproto/worktrees`. The default is a real single root, not
|
|
320
|
+
* "unconfigured" — `worktree new` converges to one place with zero
|
|
321
|
+
* setup, which is the only way the sprawl actually stops (the 6 roots
|
|
322
|
+
* that exist today are 6 people each inventing a default by hand).
|
|
323
|
+
*/
|
|
324
|
+
root?: string;
|
|
325
|
+
/**
|
|
326
|
+
* Policy for `agent_start.worktree` isolation. Resolution order mirrors
|
|
327
|
+
* the module docblock (there is no CLI flag — this is a daemon-side
|
|
328
|
+
* policy read at spawn, not a per-invocation flag):
|
|
329
|
+
* `AGENTPROTO_WORKTREES_ISOLATION` env > this field > the hardcoded
|
|
330
|
+
* default `"on-request"`. `"on-request"` is deliberately the default:
|
|
331
|
+
* any other would break back-compat by isolating callers that never
|
|
332
|
+
* asked (see `worktree-isolation.ts`).
|
|
333
|
+
*/
|
|
334
|
+
isolation?: WorktreeIsolationMode;
|
|
335
|
+
/**
|
|
336
|
+
* Max worktree provisionings running their HEAVY phases (`cloneGlobs`,
|
|
337
|
+
* `depsCmd`, `copyGlobs`, the `worktree.setup` hooks) at once, daemon-wide.
|
|
338
|
+
* A burst of `agent_start({worktree})` spawns otherwise runs that many
|
|
339
|
+
* concurrent `pnpm install`s against one store on one disk (the 2026-09-28
|
|
340
|
+
* incident: load average 170, installs 3.5x slower). The rest wait in a
|
|
341
|
+
* FIFO queue, fair across spawning callers. `git worktree add` and the
|
|
342
|
+
* cheap prep stay unthrottled. Resolution order:
|
|
343
|
+
* `AGENTPROTO_WORKTREES_PROVISION_CONCURRENCY` env > this field > the
|
|
344
|
+
* default `2`. An integer >= 1; `0` means unlimited (the pre-queue
|
|
345
|
+
* behavior). Invalid values fall back to the default.
|
|
346
|
+
*/
|
|
347
|
+
provisionConcurrency?: number;
|
|
348
|
+
/**
|
|
349
|
+
* Per-repo overrides of {@link provisionConcurrency}, additional to (never
|
|
350
|
+
* looser than) the global cap. Keys are an absolute repo-root path (`~/`
|
|
351
|
+
* expands) or a bare repo directory name; values as above. Example:
|
|
352
|
+
* `{ "agentik-studio": 1 }` serializes installs of that repo even when
|
|
353
|
+
* other repos may install two at a time.
|
|
354
|
+
*/
|
|
355
|
+
provisionConcurrencyByRepo?: Record<string, number>;
|
|
356
|
+
/**
|
|
357
|
+
* Optional load guard: hold back starting a NEW heavy segment while the
|
|
358
|
+
* 1-minute load average exceeds `cores x provisionLoadFactor`. Unset / `0`
|
|
359
|
+
* = off (the default). Never blocks when nothing is running, so a loaded
|
|
360
|
+
* host cannot deadlock the queue.
|
|
361
|
+
*/
|
|
362
|
+
provisionLoadFactor?: number;
|
|
363
|
+
}
|
|
364
|
+
/**
|
|
365
|
+
* Policy for `agent_start.attach` — whether a spawn AUTO-attaches to its
|
|
366
|
+
* calling session as parent lineage. `"always"` (the default) nests a
|
|
367
|
+
* spawned child under the session that spawned it whenever that identity is
|
|
368
|
+
* derivable (the trusted `?callerSessionId=` on the daemon self-ref URL, or
|
|
369
|
+
* an explicit `parentSessionId` hint), so a supervisor's executors stop
|
|
370
|
+
* landing as depth-0 orphans. `"on-request"` reverts to the pre-attach
|
|
371
|
+
* behaviour: auto-attribution is off, and a child nests only when the caller
|
|
372
|
+
* explicitly opts in (`attach: true` / `attach: { parent }` / an explicit
|
|
373
|
+
* `parentSessionId`). Either way a per-call `attach: false` forces an
|
|
374
|
+
* independent root, exactly as `worktree: false` opts out of isolation. See
|
|
375
|
+
* `spawn-attach.ts`.
|
|
376
|
+
*/
|
|
377
|
+
type SpawnAttachMode = "always" | "on-request";
|
|
378
|
+
/**
|
|
379
|
+
* Policy for `agent_start`'s IMPLICIT dedupe — what happens when a caller
|
|
380
|
+
* spawns with NO `idempotencyKey` at all (see `spawn-dedupe.ts`):
|
|
381
|
+
* - `"always"` — the daemon DERIVES an implicit key from the spawn's
|
|
382
|
+
* `label` (required — see below) plus a hash of the
|
|
383
|
+
* initial `prompt`, and dedupes a same-adapter/cwd
|
|
384
|
+
* repeat against it exactly as an explicit key would.
|
|
385
|
+
* This is the default, mirroring `attach`'s own
|
|
386
|
+
* "opt-in-only guard is not a guard" precedent above.
|
|
387
|
+
* Deriving needs a `label` to produce anything at all
|
|
388
|
+
* — an unlabelled spawn is untouched, which is what
|
|
389
|
+
* keeps this safe for the fan-out pattern this repo
|
|
390
|
+
* exercises (several agents into one cwd with no
|
|
391
|
+
* shared label): see `spawn-dedupe.ts`'s docblock for
|
|
392
|
+
* the full false-dedup analysis, and PR #803's own
|
|
393
|
+
* no-opt-in label+cwd warning backstop in
|
|
394
|
+
* `session-spawn.ts`, which independently landed on
|
|
395
|
+
* the same label-is-the-signal boundary.
|
|
396
|
+
* - `"on-request"` — no implicit derivation; only an explicit
|
|
397
|
+
* `idempotencyKey` dedupes (today's behaviour,
|
|
398
|
+
* unchanged). A per-call `dedupe: true` still opts in
|
|
399
|
+
* under this policy, mirroring `attach: true`.
|
|
400
|
+
* Either way a per-call `dedupe: false` disables implicit derivation for
|
|
401
|
+
* that one spawn regardless of policy — the escape hatch, mirroring
|
|
402
|
+
* `attach: false` / `worktree: false`. An explicit `idempotencyKey` always
|
|
403
|
+
* wins over a derived one (derivation is only attempted when the caller
|
|
404
|
+
* supplied none).
|
|
405
|
+
*/
|
|
406
|
+
type SpawnDedupeMode = "always" | "on-request";
|
|
407
|
+
interface SpawnConfig {
|
|
408
|
+
/**
|
|
409
|
+
* Attach policy for `agent_start`. Resolution order mirrors the module
|
|
410
|
+
* docblock (no CLI flag — a daemon-side policy read at spawn):
|
|
411
|
+
* `AGENTPROTO_SPAWN_ATTACH` env > this field > the hardcoded default
|
|
412
|
+
* `"always"`. Unlike `worktrees.isolation` (whose default preserves
|
|
413
|
+
* back-compat by NOT isolating), attach defaults ON: an orphaned executor
|
|
414
|
+
* is a bug, not a feature, and the auto-parent is descriptor-only lineage
|
|
415
|
+
* that never relaxes a privilege gate.
|
|
416
|
+
*/
|
|
417
|
+
attach?: SpawnAttachMode;
|
|
418
|
+
/**
|
|
419
|
+
* Implicit-dedupe policy for `agent_start`. Resolution order mirrors
|
|
420
|
+
* `attach` above (no CLI flag — a daemon-side policy read at spawn):
|
|
421
|
+
* `AGENTPROTO_SPAWN_DEDUPE` env > this field > the hardcoded default
|
|
422
|
+
* `"always"`. See {@link SpawnDedupeMode} and `spawn-dedupe.ts` for the
|
|
423
|
+
* full reasoning: a retry-safety guard that only works when a caller
|
|
424
|
+
* remembers to ask for it (`idempotencyKey`) is not a guard — the same
|
|
425
|
+
* argument `attach` already settled for parent lineage.
|
|
426
|
+
*/
|
|
427
|
+
dedupe?: SpawnDedupeMode;
|
|
428
|
+
}
|
|
429
|
+
/**
|
|
430
|
+
* Provenance policy — the opt-in `gh` PATH shim (`gh-provenance-shim.ts`).
|
|
431
|
+
* Off by default. When `wrapGh` is on, every agent session the daemon spawns
|
|
432
|
+
* gets a shim directory prepended to its PATH so that any `gh pr create` the
|
|
433
|
+
* session (or an adapter subprocess shelling out — claude-code, codex, …) runs
|
|
434
|
+
* has a deterministic `@agentproto-bot` provenance footer appended to the
|
|
435
|
+
* created PR's BODY, matching the footer the cloud runner stamps. The TOOL
|
|
436
|
+
* stamps, never the model; commit messages are never touched (the repo's
|
|
437
|
+
* hygiene-check forbids attribution there). Resolution order mirrors
|
|
438
|
+
* `spawn.attach`: `AGENTPROTO_PROVENANCE_WRAP_GH` env > this field > default
|
|
439
|
+
* `false`.
|
|
440
|
+
*/
|
|
441
|
+
interface ProvenanceConfig {
|
|
442
|
+
/** Enable the opt-in `gh` provenance PATH shim for spawned sessions. */
|
|
443
|
+
wrapGh?: boolean;
|
|
444
|
+
}
|
|
445
|
+
/**
|
|
446
|
+
* Approvals policy (`packages/runtime/src/approvals/`, E1a) — config for
|
|
447
|
+
* the `web_click` human decision channel. See `AIP-7-AMENDMENT.md` for the
|
|
448
|
+
* full channel design.
|
|
449
|
+
*/
|
|
450
|
+
interface ApprovalsConfig {
|
|
451
|
+
/**
|
|
452
|
+
* Origins allowed to decide a pending approval through `POST
|
|
453
|
+
* /approvals/:id/decision` (in addition to the daemon's own per-boot
|
|
454
|
+
* bearer token, which is ALWAYS required on that route regardless of
|
|
455
|
+
* this list). Default empty — `web_click` is OFF until at least one
|
|
456
|
+
* origin is configured. Lockout-shaped like `daemon.allowedOrigins`,
|
|
457
|
+
* but a SEPARATE list: the general browser-origin allowlist is not
|
|
458
|
+
* automatically trusted to decide approvals.
|
|
459
|
+
*/
|
|
460
|
+
webOrigins?: string[];
|
|
461
|
+
}
|
|
462
|
+
/**
|
|
463
|
+
* Sentinel auto-link policy (AIP-60 §6, step 4) — whether a PR an executor
|
|
464
|
+
* session opens gets a sentinel created for it automatically.
|
|
465
|
+
*/
|
|
466
|
+
interface SentinelConfig {
|
|
467
|
+
/** Auto-watch a PR when a session opens one (`recordOpenedPr`, fed by
|
|
468
|
+
* `command_execute`'s stamper and both `pr-provenance-reconciler.ts`
|
|
469
|
+
* lanes). When unset, the daemon defaults to `true` only when the
|
|
470
|
+
* `local-gh` provider is available (i.e. `gh auth status` succeeds) —
|
|
471
|
+
* otherwise `false`, logged once. Explicitly setting this always wins
|
|
472
|
+
* over that probe. Per-spawn opt-out: `agent_start.sentinel: false`. */
|
|
473
|
+
autoWatchPrs?: boolean;
|
|
474
|
+
}
|
|
475
|
+
/**
|
|
476
|
+
* Review-primitive host policy (`@agentproto/review` + `review-runner.ts`).
|
|
477
|
+
*/
|
|
478
|
+
interface ReviewConfig {
|
|
479
|
+
/** The owner identity attestation signatures claim (`attestor.signature.
|
|
480
|
+
* principal`) — see `review-signing.ts`'s `resolvePrincipal`. When unset,
|
|
481
|
+
* the daemon falls back to `git config user.email` of the reviewed repo,
|
|
482
|
+
* then a host-derived value; this never blocks signing, it only lets an
|
|
483
|
+
* operator pin one identity across every repo the daemon reviews. */
|
|
484
|
+
principal?: string;
|
|
485
|
+
}
|
|
486
|
+
/**
|
|
487
|
+
* Session-presence policy — how the dashboard triages a session into its
|
|
488
|
+
* `running` / `tending` / `attention` / `quiet` presence state (see
|
|
489
|
+
* `session-presence.ts`). Optional block on `AgentprotoConfig.sessions`.
|
|
490
|
+
*/
|
|
491
|
+
interface SessionsConfig {
|
|
492
|
+
/**
|
|
493
|
+
* How long (seconds) a session stays shown as `running` after its last
|
|
494
|
+
* turn ends, before it settles into `attention`/`quiet`. The grace window
|
|
495
|
+
* is measured from the session's most recent `lastActivityAt` — ANY new
|
|
496
|
+
* event resets it — so a session that just answered does not read as
|
|
497
|
+
* "quiet" the instant its turn finishes, but something that went idle long
|
|
498
|
+
* ago, with nothing waiting on it, settles grey. Resolution order mirrors
|
|
499
|
+
* every other knob in this file (module docblock): env var
|
|
500
|
+
* `AGENTPROTO_SESSIONS_ATTENTION_DELAY_SEC` > this field > the hardcoded
|
|
501
|
+
* default `60`. Absent ⇒ 60s.
|
|
502
|
+
*/
|
|
503
|
+
attentionDelaySec?: number;
|
|
504
|
+
/**
|
|
505
|
+
* Root directory the daemon stores per-session transcripts under — each
|
|
506
|
+
* session's `events.jsonl` lands at `<eventsDir>/<sessionId>/events.jsonl`
|
|
507
|
+
* (and a terminal session's `terminal.jsonl` alongside it). Every
|
|
508
|
+
* reader/writer (transcript writer, `/sessions/:id/events` HTTP routes,
|
|
509
|
+
* exports, tool-call/usage logs) resolves through this single knob.
|
|
510
|
+
* Resolution order mirrors every other knob in this file: relative paths
|
|
511
|
+
* resolve against the home directory. Absent ⇒ the hardcoded default
|
|
512
|
+
* `~/.agentproto/sessions` — zero behaviour change out of the box. A
|
|
513
|
+
* change requires a daemon restart to take effect (and existing sessions'
|
|
514
|
+
* transcripts do NOT move).
|
|
515
|
+
*/
|
|
516
|
+
eventsDir?: string;
|
|
517
|
+
}
|
|
518
|
+
/**
|
|
519
|
+
* Policy for the daemon's own AGENTS.md resolution + injection (WP-R2) —
|
|
520
|
+
* how a spawned session's initial prompt carries the repo's `AGENTS.md`
|
|
521
|
+
* (see `agents-md.ts`). The daemon resolves the nearest `AGENTS.md` walking
|
|
522
|
+
* up from the session's `cwd`, bounded by that repo's git toplevel, and
|
|
523
|
+
* injects one AGENTS.md block after the role disposition whenever the spawn
|
|
524
|
+
* carries a prompt.
|
|
525
|
+
*/
|
|
526
|
+
interface AgentsMdConfig {
|
|
527
|
+
/**
|
|
528
|
+
* Inline-vs-pointer threshold in KiB. A resolved AGENTS.md whose byte size
|
|
529
|
+
* is STRICTLY LESS than `inlineMaxKb` KiB is inlined in full into the
|
|
530
|
+
* spawn's initial prompt, clearly delimited; `>=` the threshold is injected
|
|
531
|
+
* as a short pointer telling the agent to read the file before its first
|
|
532
|
+
* tool call instead. An absent AGENTS.md (nothing found up the walk) injects
|
|
533
|
+
* nothing but is still reported on the descriptor via
|
|
534
|
+
* `SessionDescriptor.agentsMdMode === "absent"`. Resolution order mirrors
|
|
535
|
+
* the module docblock (no CLI flag, and no env override — not part of the
|
|
536
|
+
* approved design): this field > the hardcoded default `8` (KiB).
|
|
537
|
+
*/
|
|
538
|
+
inlineMaxKb?: number;
|
|
539
|
+
}
|
|
540
|
+
interface PairingConfig {
|
|
541
|
+
/** Rendezvous broker WS URL (ws:// or wss://) used by `pair offer` and by
|
|
542
|
+
* autoconnect on boot. When unset, `pair offer` requires an explicit
|
|
543
|
+
* `--rendezvous`. Mirrors `tunnel.host`. */
|
|
544
|
+
rendezvous?: string;
|
|
545
|
+
/** Whether the daemon opens standing rendezvous connections for every
|
|
546
|
+
* persisted pairing on boot (so a paired client can reconnect anytime).
|
|
547
|
+
* Mirrors `tunnel.autoconnect`. Default true when a rendezvous is set. */
|
|
548
|
+
autoconnect?: boolean;
|
|
549
|
+
/** Web pair page for `pair offer --qr` (the offer rides in its fragment).
|
|
550
|
+
* A template with `{fp}` in the HOSTNAME, filled with the daemon
|
|
551
|
+
* fingerprint (one origin per daemon), or a plain http(s) URL (one shared
|
|
552
|
+
* origin). Unset → `https://{fp}.agentproto.cloud/pair`. `--pair-page`
|
|
553
|
+
* overrides it. */
|
|
554
|
+
pairPage?: string;
|
|
555
|
+
}
|
|
556
|
+
/**
|
|
557
|
+
* A user-defined generic ACP agent — the config-file half of
|
|
558
|
+
* `AcpAgentSpec` (the slug is the record key in `acpAgents`, so it's
|
|
559
|
+
* omitted here). Any CLI that already speaks the Agent Client Protocol
|
|
560
|
+
* can be wired with zero code by declaring one of these under
|
|
561
|
+
* `acpAgents.<slug>` in `~/.agentproto/config.json`; the CLI's
|
|
562
|
+
* `acpHandleFromSpec` mints a runnable `AgentCliHandle` from it at
|
|
563
|
+
* resolve time (see `packages/cli/src/registry/acp-generic.ts`). Kept
|
|
564
|
+
* in this package (not the CLI's) so `config.ts` stays the single
|
|
565
|
+
* source of truth for the config surface without a cli→runtime→cli
|
|
566
|
+
* import cycle — the CLI's `AcpAgentSpec` extends this shape.
|
|
567
|
+
*/
|
|
568
|
+
interface AcpAgentConfigEntry {
|
|
569
|
+
/** Display name. Defaults to the slug when omitted. */
|
|
570
|
+
name?: string;
|
|
571
|
+
/** One-line description surfaced in `agentproto acp ls`. */
|
|
572
|
+
description?: string;
|
|
573
|
+
/** Executable to spawn, e.g. "gemini". */
|
|
574
|
+
bin: string;
|
|
575
|
+
/** Extra argv appended after `bin`, e.g. ["--experimental-acp"]. */
|
|
576
|
+
bin_args?: string[];
|
|
577
|
+
/** Extra environment variables for the spawned process. */
|
|
578
|
+
env?: Record<string, string>;
|
|
579
|
+
/** Flag the CLI uses to receive the working directory, if it needs
|
|
580
|
+
* one passed explicitly (most ACP agents take cwd over the wire). */
|
|
581
|
+
cwd_flag?: string;
|
|
582
|
+
/** When true, advertise resumable + native-resume continuation. */
|
|
583
|
+
resumable?: boolean;
|
|
584
|
+
/** Known model ids for the agent (informational + validation hints). */
|
|
585
|
+
models?: {
|
|
586
|
+
default?: string;
|
|
587
|
+
allowed?: string[];
|
|
588
|
+
};
|
|
589
|
+
/** Billing endpoint this CLI's own auth bills (e.g. "mistral",
|
|
590
|
+
* "moonshot", "google") — the provider whose wallet/auth-profile the
|
|
591
|
+
* agent consumes. Lets clients link the harness to that provider's
|
|
592
|
+
* wallets even when no model list is declared. Unset when the CLI's
|
|
593
|
+
* billing target isn't a single known endpoint. */
|
|
594
|
+
provider?: string;
|
|
595
|
+
/** Shown when `bin` is missing from PATH (how to install the CLI). */
|
|
596
|
+
install_hint?: string;
|
|
597
|
+
}
|
|
598
|
+
/**
|
|
599
|
+
* Per-environment connection bundle. A profile overrides specific
|
|
600
|
+
* fields of the top-level `daemon` / `tunnel` / `features` blocks
|
|
601
|
+
* when selected via `--profile <name>` (or the top-level
|
|
602
|
+
* `activeProfile` setting). Missing fields fall through to the
|
|
603
|
+
* top-level config, so a profile only needs to declare what's
|
|
604
|
+
* different — typically just `tunnel.host` + `tunnel.token`.
|
|
605
|
+
*
|
|
606
|
+
* Example:
|
|
607
|
+
* {
|
|
608
|
+
* "daemon": { "workspace": "/code", "port": 18790 },
|
|
609
|
+
* "activeProfile": "local",
|
|
610
|
+
* "profiles": {
|
|
611
|
+
* "local": { "tunnel": { "host": "ws://localhost:3200/connect",
|
|
612
|
+
* "token": "apt_local", "autoconnect": true } },
|
|
613
|
+
* "prod": { "tunnel": { "host": "wss://tunnel.guilde.work/connect",
|
|
614
|
+
* "token": "apt_prod", "autoconnect": true },
|
|
615
|
+
* "daemon": { "port": 18791 } }
|
|
616
|
+
* }
|
|
617
|
+
* }
|
|
618
|
+
*
|
|
619
|
+
* Sandbox daemons generate per-sandbox profile entries at provision
|
|
620
|
+
* time so the daemon inside the sandbox boots with
|
|
621
|
+
* `agentproto serve --profile sandbox-<id>` and no extra plumbing.
|
|
622
|
+
*/
|
|
623
|
+
interface ProfileConfig {
|
|
624
|
+
daemon?: DaemonConfig;
|
|
625
|
+
tunnel?: TunnelConfig;
|
|
626
|
+
features?: FeaturesConfig;
|
|
627
|
+
}
|
|
628
|
+
/**
|
|
629
|
+
* A user-defined named terminal/TUI preset stored in
|
|
630
|
+
* `~/.agentproto/config.json` under `terminalPresets`. Presets keep
|
|
631
|
+
* local launch recipes (argv, env, cwd, name/label) out of shared
|
|
632
|
+
* adapter manifests — e.g. pointing a Claude Code TUI at a local
|
|
633
|
+
* LLM gateway without retyping proxy env vars every spawn.
|
|
634
|
+
*/
|
|
635
|
+
interface TerminalPreset {
|
|
636
|
+
/** Command + args to spawn. When provided, `sessions terminal` can
|
|
637
|
+
* be used without `-- <argv...>`. */
|
|
638
|
+
argv?: string[];
|
|
639
|
+
/** Extra environment variables layered on top of the daemon's
|
|
640
|
+
* inherited process.env. Values MUST be strings. */
|
|
641
|
+
env?: Record<string, string>;
|
|
642
|
+
/** Working directory for the PTY session. Relative paths are
|
|
643
|
+
* resolved against the current working directory at CLI time. */
|
|
644
|
+
cwd?: string;
|
|
645
|
+
/** Workspace slug used for cwd fallback when `cwd` is omitted. */
|
|
646
|
+
workspace?: string;
|
|
647
|
+
/** Stable session name passed to the registry (`name` field). */
|
|
648
|
+
name?: string;
|
|
649
|
+
/** Human-readable label surfaced in session listings. */
|
|
650
|
+
label?: string;
|
|
651
|
+
}
|
|
652
|
+
interface AgentprotoConfig {
|
|
653
|
+
version?: number;
|
|
654
|
+
daemon?: DaemonConfig;
|
|
655
|
+
tunnel?: TunnelConfig;
|
|
656
|
+
features?: FeaturesConfig;
|
|
657
|
+
/** E2E daemon-pairing defaults (rendezvous URL + autoconnect). */
|
|
658
|
+
pairing?: PairingConfig;
|
|
659
|
+
/** Where `agentproto worktree new` creates worktrees. See
|
|
660
|
+
* {@link WorktreesConfig}. */
|
|
661
|
+
worktrees?: WorktreesConfig;
|
|
662
|
+
/** Spawn-time policy (`agent_start`). See {@link SpawnConfig}. */
|
|
663
|
+
spawn?: SpawnConfig;
|
|
664
|
+
/** Session-presence policy for the dashboard. See {@link SessionsConfig}. */
|
|
665
|
+
sessions?: SessionsConfig;
|
|
666
|
+
/** Provenance policy — the opt-in `gh` PATH shim. See {@link ProvenanceConfig}. */
|
|
667
|
+
provenance?: ProvenanceConfig;
|
|
668
|
+
/** Approvals policy — the `web_click` origin allowlist. See {@link ApprovalsConfig}. */
|
|
669
|
+
approvals?: ApprovalsConfig;
|
|
670
|
+
/** Sentinel auto-link policy. See {@link SentinelConfig}. */
|
|
671
|
+
sentinel?: SentinelConfig;
|
|
672
|
+
/** Review-primitive host policy. See {@link ReviewConfig}. */
|
|
673
|
+
review?: ReviewConfig;
|
|
674
|
+
/** Daemon-side AGENTS.md resolution/injection policy. See {@link AgentsMdConfig}. */
|
|
675
|
+
agentsMd?: AgentsMdConfig;
|
|
676
|
+
/** Model roles: ROLE → model id (or `{ model, route?, profile? }`), the
|
|
677
|
+
* one place reviewer/judge models are configured. Layer 3 of the
|
|
678
|
+
* precedence documented in `model-roles.ts` (input > workspace
|
|
679
|
+
* `agentproto.json` > this > built-in default). Role names contain dots,
|
|
680
|
+
* so `getConfigKey`/`setConfigKey` treat everything after `models.` as
|
|
681
|
+
* ONE key (`models.review.pr` → `models["review.pr"]`). */
|
|
682
|
+
models?: ModelRolesConfig;
|
|
683
|
+
/** Daemon-side session titler (`session-titler.ts`). DEFAULT OFF — when
|
|
684
|
+
* `enabled` is not explicitly true the titler is a complete no-op and
|
|
685
|
+
* nothing renames anything. When on, at the end of the FIRST completed
|
|
686
|
+
* turn of a `kind:"agent-cli"` session whose label is still a spawn
|
|
687
|
+
* default (`chat-starter`, `chat-starter-autoprompt`, `agentproto`, empty,
|
|
688
|
+
* or equal to the derived title), the daemon generates a short prosaic
|
|
689
|
+
* title (4-8 words) from the first turn's transcript and renames the
|
|
690
|
+
* session via the same write path as `session_rename`. Generation tries
|
|
691
|
+
* OpenRouter (`model`, default `z-ai/glm-5.2@openrouter`, needs
|
|
692
|
+
* `OPENROUTER_API_KEY`) and falls back locally (first line of the first
|
|
693
|
+
* user prompt, 6 whole words) on any failure. A user-created label is
|
|
694
|
+
* NEVER overwritten, and a session is titled at most once. */
|
|
695
|
+
titler?: TitlerConfig;
|
|
696
|
+
/** Jev judge backend settings (`jev-client.ts`). See {@link JevConfig}. */
|
|
697
|
+
jev?: JevConfig;
|
|
698
|
+
/** App catalog settings (`app-catalog.ts`). See {@link CatalogConfig}. */
|
|
699
|
+
catalog?: CatalogConfig;
|
|
700
|
+
/** Named connection profiles. See `ProfileConfig` for the merge
|
|
701
|
+
* semantics — a profile's fields shallow-override the top-level
|
|
702
|
+
* defaults for the selected run. */
|
|
703
|
+
profiles?: Record<string, ProfileConfig>;
|
|
704
|
+
/** Profile name to use when `--profile` isn't passed. When unset,
|
|
705
|
+
* the top-level `daemon` / `tunnel` blocks are used directly. */
|
|
706
|
+
activeProfile?: string;
|
|
707
|
+
/** Default `skills` + `options` auto-applied to every `agent_start`
|
|
708
|
+
* spawn — global and per-adapter. See `resolveSpawnDefaults` in
|
|
709
|
+
* `spawn-defaults.ts` for the merge precedence with an explicit call.
|
|
710
|
+
* Absent ⇒ current behaviour exactly (no regression). */
|
|
711
|
+
defaults?: SpawnDefaultsConfig;
|
|
712
|
+
/** User-defined generic ACP agents, keyed by adapter slug. Each entry
|
|
713
|
+
* is minted into a runnable handle by the CLI's `acpHandleFromSpec`
|
|
714
|
+
* when `resolveAdapter(slug)` finds no npm adapter package. User
|
|
715
|
+
* entries shadow the curated `ACP_CATALOG` on slug collision. */
|
|
716
|
+
acpAgents?: Record<string, AcpAgentConfigEntry>;
|
|
717
|
+
/** User-defined named terminal/TUI presets. Local-only; never
|
|
718
|
+
* packaged in shared adapter manifests or defaults. */
|
|
719
|
+
terminalPresets?: Record<string, TerminalPreset>;
|
|
720
|
+
/** Unknown keys preserved across save round-trips. */
|
|
721
|
+
[unknown: string]: unknown;
|
|
722
|
+
}
|
|
723
|
+
declare const CONFIG_FILE_PATH: () => string;
|
|
724
|
+
/**
|
|
725
|
+
* Load config.json. Returns an empty object (NOT null) when the file
|
|
726
|
+
* is missing, malformed, or unreadable — callers can `cfg.daemon?.port`
|
|
727
|
+
* safely without null-guards. Errors during a malformed-read are
|
|
728
|
+
* logged once so the user notices the file is broken without the
|
|
729
|
+
* daemon refusing to boot.
|
|
730
|
+
*/
|
|
731
|
+
declare function loadConfig(path?: string): Promise<AgentprotoConfig>;
|
|
732
|
+
/**
|
|
733
|
+
* Write config.json atomically (tmp + rename) so a concurrent
|
|
734
|
+
* `agentproto config edit` can't half-truncate the file. Writes
|
|
735
|
+
* `next` AS-IS — callers are expected to pass the full desired
|
|
736
|
+
* state (loaded the existing config, mutated, passed it back).
|
|
737
|
+
*
|
|
738
|
+
* Earlier versions deep-merged with the on-disk file, but that made
|
|
739
|
+
* deletions impossible: `setConfigKey(cfg, "x", undefined)` would
|
|
740
|
+
* remove the key from memory, then the deep-merge would silently
|
|
741
|
+
* re-add it from disk. The current design trusts the caller's
|
|
742
|
+
* snapshot and uses atomic rename for crash safety.
|
|
743
|
+
*/
|
|
744
|
+
declare function saveConfig(next: AgentprotoConfig, path?: string): Promise<void>;
|
|
745
|
+
/** Split a dotted key into path segments. `models.<role>` is the one
|
|
746
|
+
* exception: role names are themselves dotted (`review.pr`), so everything
|
|
747
|
+
* after `models.` is a single segment. */
|
|
748
|
+
declare function splitConfigPath(dotted: string): string[];
|
|
749
|
+
/**
|
|
750
|
+
* Read a dot-notation key (`daemon.port`) out of a config. Returns
|
|
751
|
+
* `undefined` when any segment is missing.
|
|
752
|
+
*/
|
|
753
|
+
declare function getConfigKey(cfg: AgentprotoConfig, dotted: string): unknown;
|
|
754
|
+
/**
|
|
755
|
+
* Set a dot-notation key in a config. Returns a new object — does
|
|
756
|
+
* NOT mutate. Creates intermediate objects as needed. Setting
|
|
757
|
+
* `value: undefined` is treated as a delete.
|
|
758
|
+
*/
|
|
759
|
+
declare function setConfigKey(cfg: AgentprotoConfig, dotted: string, value: unknown): AgentprotoConfig;
|
|
760
|
+
|
|
761
|
+
export { type ApprovalsConfig as A, loadConfig as B, type CatalogConfig as C, type DaemonConfig as D, saveConfig as E, type FeaturesConfig as F, setConfigKey as G, splitConfigPath as H, type JevConfig as J, MODEL_ROLE_REF_PREFIX as M, type PairingConfig as P, type ResolvedModelRole as R, type SpawnConfig as S, type TunnelConfig as T, type WorktreesConfig as W, type SessionsConfig as a, type ProvenanceConfig as b, type AgentsMdConfig as c, type TitlerConfig as d, type ProfileConfig as e, type AcpAgentConfigEntry as f, type TerminalPreset as g, type WorktreeIsolationMode as h, type SpawnAttachMode as i, type SpawnDedupeMode as j, DEFAULT_MODEL_ROLES as k, type ModelRoleContext as l, type ModelRoleEntry as m, type ModelRoleSource as n, type ModelRoleValue as o, type ModelRolesConfig as p, listModelRoles as q, parseModelRoleRef as r, resolveModelRole as s, type AgentprotoConfig as t, CONFIG_FILE_PATH as u, CONFIG_VERSION as v, type CatalogSourceConfig as w, type ReviewConfig as x, type SentinelConfig as y, getConfigKey as z };
|