@agentproto/runtime 4.0.0 → 4.1.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 +1 -0
- package/dist/app-ui-build.d.ts +96 -0
- package/dist/app-ui-build.mjs +250 -0
- package/dist/app-ui-build.mjs.map +1 -0
- package/dist/app-ui-placeholder.d.ts +73 -0
- package/dist/app-ui-placeholder.mjs +89 -0
- package/dist/app-ui-placeholder.mjs.map +1 -0
- package/dist/config-schema.mjs +93 -83
- package/dist/config-schema.mjs.map +1 -1
- package/dist/config.d.ts +12 -0
- package/dist/config.mjs +93 -83
- package/dist/config.mjs.map +1 -1
- package/dist/index.d.ts +867 -37
- package/dist/index.mjs +2885 -646
- package/dist/index.mjs.map +1 -1
- package/dist/resume-strategies.mjs +7 -0
- package/dist/resume-strategies.mjs.map +1 -1
- package/dist/session-presence.mjs +93 -83
- package/dist/session-presence.mjs.map +1 -1
- package/docs/TRANSMITTER.md +356 -0
- package/docs/mcp-tools/agent_start.md +476 -0
- package/docs/mcp-tools/app_run.md +47 -0
- package/package.json +26 -15
package/dist/index.d.ts
CHANGED
|
@@ -451,13 +451,64 @@ type UsageSource = "adapter" | "computed" | "no-pricing" | "none";
|
|
|
451
451
|
interface TokenPricing {
|
|
452
452
|
inputPer1M: number;
|
|
453
453
|
outputPer1M: number;
|
|
454
|
+
/** Multiplier on `inputPer1M` for cache-read tokens (Anthropic: ~0.1).
|
|
455
|
+
* Absent = 1 (no discount), same default as the catalog. */
|
|
456
|
+
cacheReadMultiplier?: number;
|
|
457
|
+
/** Multiplier on `inputPer1M` for cache-creation tokens (Anthropic:
|
|
458
|
+
* ~1.25). Absent = 1. */
|
|
459
|
+
cacheWriteMultiplier?: number;
|
|
460
|
+
}
|
|
461
|
+
/**
|
|
462
|
+
* Token-detail and activity fields shared by every usage shape below. All
|
|
463
|
+
* optional and never zero-filled: absent means "this source doesn't report
|
|
464
|
+
* it", a present 0 is a measured zero.
|
|
465
|
+
*
|
|
466
|
+
* - `cacheReadTokens` / `cacheWriteTokens`: prompt-cache reads / cache
|
|
467
|
+
* creation, cumulative. Kept OUT of `tokensIn` (which is uncached input
|
|
468
|
+
* only when a cache split is known).
|
|
469
|
+
* - `reasoningTokens`: thinking/reasoning tokens, cumulative. A subset of
|
|
470
|
+
* `tokensOut` for providers that bill them as output (Anthropic).
|
|
471
|
+
* - `turns`: completed turns (the descriptor's `turnsCompleted`).
|
|
472
|
+
* - `toolCalls`: tool calls the daemon observed, cumulative.
|
|
473
|
+
* - `durationMs`: wall time spent inside turns, cumulative.
|
|
474
|
+
*/
|
|
475
|
+
interface UsageDetail {
|
|
476
|
+
cacheReadTokens?: number;
|
|
477
|
+
cacheWriteTokens?: number;
|
|
478
|
+
reasoningTokens?: number;
|
|
479
|
+
turns?: number;
|
|
480
|
+
toolCalls?: number;
|
|
481
|
+
durationMs?: number;
|
|
454
482
|
}
|
|
483
|
+
/** Copy only the present (`number`) `UsageDetail` fields of `src`. */
|
|
484
|
+
declare function pickUsageDetail(src: UsageDetail): UsageDetail;
|
|
455
485
|
/** Pluggable pricing accessor — defaults to the in-repo catalog's
|
|
456
486
|
* `resolvePricing`, overridable in tests. Returns undefined for an
|
|
457
487
|
* unknown model (the caller then tags `no-pricing`). */
|
|
458
488
|
type PricingResolver = (model: string) => TokenPricing | undefined;
|
|
489
|
+
/**
|
|
490
|
+
* What an adapter's usage reader (`readUsage`: hermes state.db, opencode.db,
|
|
491
|
+
* the claude-code transcript JSONL) returns. Every field is cumulative for
|
|
492
|
+
* the session and optional; `null` from the reader means "nothing found".
|
|
493
|
+
*/
|
|
494
|
+
interface UsageReadResult {
|
|
495
|
+
model?: string;
|
|
496
|
+
costUsd?: number;
|
|
497
|
+
tokensIn?: number;
|
|
498
|
+
tokensOut?: number;
|
|
499
|
+
cacheReadTokens?: number;
|
|
500
|
+
cacheWriteTokens?: number;
|
|
501
|
+
reasoningTokens?: number;
|
|
502
|
+
}
|
|
503
|
+
/** Where a reader should look for the session's native store — the spawn's
|
|
504
|
+
* cwd and isolated provider config dir (`CLAUDE_CONFIG_DIR` for
|
|
505
|
+
* claude-code). Readers that key only on the session id ignore it. */
|
|
506
|
+
interface UsageReadContext {
|
|
507
|
+
cwd?: string;
|
|
508
|
+
configDir?: string;
|
|
509
|
+
}
|
|
459
510
|
/** Raw signals gathered over a turn, handed to `deriveSessionUsage`. */
|
|
460
|
-
interface UsageComputeInput {
|
|
511
|
+
interface UsageComputeInput extends UsageDetail {
|
|
461
512
|
/** Requested model id — needed to look up per-token prices. */
|
|
462
513
|
model?: string;
|
|
463
514
|
/** Cost the adapter reported directly (readUsage or usage_update.cost).
|
|
@@ -471,7 +522,7 @@ interface UsageComputeInput {
|
|
|
471
522
|
/** The resolved usage snapshot — the shape `session_usage` returns and the
|
|
472
523
|
* durable `usage_snapshot` transcript record carries. Cost/token fields are
|
|
473
524
|
* omitted when absent so a missing value never reads as a measured zero. */
|
|
474
|
-
interface SessionUsage {
|
|
525
|
+
interface SessionUsage extends UsageDetail {
|
|
475
526
|
model?: string;
|
|
476
527
|
costUsd?: number;
|
|
477
528
|
tokensIn?: number;
|
|
@@ -488,7 +539,7 @@ interface SessionUsage {
|
|
|
488
539
|
*/
|
|
489
540
|
declare function deriveSessionUsage(input: UsageComputeInput, resolve?: PricingResolver): SessionUsage;
|
|
490
541
|
/** Descriptor-shaped fields `projectSessionUsage` reads. */
|
|
491
|
-
interface UsageDescriptorFields {
|
|
542
|
+
interface UsageDescriptorFields extends Omit<UsageDetail, "turns"> {
|
|
492
543
|
model?: string;
|
|
493
544
|
costUsd?: number;
|
|
494
545
|
tokensIn?: number;
|
|
@@ -496,6 +547,8 @@ interface UsageDescriptorFields {
|
|
|
496
547
|
contextSize?: number;
|
|
497
548
|
contextUsed?: number;
|
|
498
549
|
usageSource?: UsageSource;
|
|
550
|
+
/** Surfaced as `turns`. */
|
|
551
|
+
turnsCompleted?: number;
|
|
499
552
|
}
|
|
500
553
|
/**
|
|
501
554
|
* Project a session descriptor's persisted usage fields into the
|
|
@@ -1837,6 +1890,18 @@ interface SessionTurnEndEvent {
|
|
|
1837
1890
|
* a normal, productive turn.
|
|
1838
1891
|
*/
|
|
1839
1892
|
empty?: boolean;
|
|
1893
|
+
/**
|
|
1894
|
+
* The in-band `error` stream event's message text observed during this
|
|
1895
|
+
* turn, when one occurred (see `SessionDescriptor.lastTurnErrorMessage`'s
|
|
1896
|
+
* doc). Present whenever `reason` is `"error"` AND the adapter emitted an
|
|
1897
|
+
* `error`-kind event before ending the stream — including the case where
|
|
1898
|
+
* the generator simply returned with no explicit turn-end and no thrown
|
|
1899
|
+
* exception, which is exactly what left an errored turn indistinguishable
|
|
1900
|
+
* from a clean one before this field existed. Absent when the adapter
|
|
1901
|
+
* reported `reason:"error"` on its own turn-end without a preceding
|
|
1902
|
+
* `error` event, and absent (not empty string) on every non-error turn.
|
|
1903
|
+
*/
|
|
1904
|
+
error?: string;
|
|
1840
1905
|
/**
|
|
1841
1906
|
* True when the turn was not started by a prompt: the agent woke on its
|
|
1842
1907
|
* own (Claude Code's task-notification cycle after a background task
|
|
@@ -2763,6 +2828,90 @@ declare class TunnelRegistry {
|
|
|
2763
2828
|
private loadFromDisk;
|
|
2764
2829
|
}
|
|
2765
2830
|
|
|
2831
|
+
/**
|
|
2832
|
+
* LlmEndpointRegistry — supervised-sidecar manager for the
|
|
2833
|
+
* `@agentproto/llm-endpoint` proxy gateway.
|
|
2834
|
+
*
|
|
2835
|
+
* The daemon spawns the llm-endpoint bin as a CHILD PROCESS (never an
|
|
2836
|
+
* in-process import — the runtime package has zero dependency on
|
|
2837
|
+
* @agentproto/llm-endpoint, exactly like it never imports cloudflared).
|
|
2838
|
+
* This is the single-sidecar analog of {@link TunnelRegistry}: one endpoint,
|
|
2839
|
+
* one port, an in-memory descriptor that tracks pid / port / status /
|
|
2840
|
+
* startedAt, and a start / stop / status lifecycle exposed over MCP.
|
|
2841
|
+
*
|
|
2842
|
+
* Lifecycle (mirrors RemoteController's singleton style — created fresh each
|
|
2843
|
+
* boot, state in memory; the child dies with the daemon so there is nothing
|
|
2844
|
+
* to reconcile on restart):
|
|
2845
|
+
* start(input) → assemble env, spawn `node <bin> serve`, health-probe to
|
|
2846
|
+
* readiness, store descriptor. Idempotent: a call while the
|
|
2847
|
+
* endpoint is already running+healthy returns the existing
|
|
2848
|
+
* descriptor without spawning (like `start_browser`).
|
|
2849
|
+
* status() → descriptor + live `GET /v1/models` health probe.
|
|
2850
|
+
* stop() → SIGTERM the child, mark stopped (mirrors tunnel stop).
|
|
2851
|
+
* shutdown() → stop the child on daemon exit.
|
|
2852
|
+
*
|
|
2853
|
+
* Env on spawn (see {@link assembleLlmEndpointEnv}): the provider API keys
|
|
2854
|
+
* via `injectProviderKeysIntoEnv` (the same store llm-endpoint's own cli.ts
|
|
2855
|
+
* reads), `LLM_ENDPOINT_PORT` (default 18090), and `LLM_ENDPOINT_ACCESS_TOKENS`
|
|
2856
|
+
* when configured. Explicit env passed to `start` always wins.
|
|
2857
|
+
*/
|
|
2858
|
+
type LlmEndpointStatus = "starting" | "running" | "stopped" | "error";
|
|
2859
|
+
/** The `llm_endpoint_status` MCP contract — see {@link LlmEndpointRegistry.status}. */
|
|
2860
|
+
interface LlmEndpointStatusReport {
|
|
2861
|
+
running: boolean;
|
|
2862
|
+
pid: number | null;
|
|
2863
|
+
port: number | null;
|
|
2864
|
+
baseUrl: string | null;
|
|
2865
|
+
healthy: boolean;
|
|
2866
|
+
startedAt: string | null;
|
|
2867
|
+
status: LlmEndpointStatus | "never-started";
|
|
2868
|
+
/** Who is actually serving this endpoint. `"daemon"` — this registry's own
|
|
2869
|
+
* spawn (or nothing at all). `"external"` — a healthy process on the same
|
|
2870
|
+
* port that this registry did NOT spawn (e.g. a launchd KeepAlive
|
|
2871
|
+
* sidecar); `pid` is unknown (always `null`) and `injectedProviders`, if
|
|
2872
|
+
* present, was DERIVED by probing `/v1/models` rather than read off our
|
|
2873
|
+
* own key-injection bookkeeping. */
|
|
2874
|
+
owner: "daemon" | "external";
|
|
2875
|
+
/** Whether upstream links persisted via `llm_endpoint_set_upstream_link`
|
|
2876
|
+
* are actually applied to the process answering this port. Always
|
|
2877
|
+
* `false` for `owner:"external"` — this registry never spawned it, so it
|
|
2878
|
+
* never injected `LLM_ENDPOINT_PROFILE_<UPSTREAM>`; the operator must
|
|
2879
|
+
* configure the external service's own env directly. */
|
|
2880
|
+
linksApplied: boolean;
|
|
2881
|
+
lastError?: string;
|
|
2882
|
+
injectedProviders?: string[];
|
|
2883
|
+
linkedProviders?: string[];
|
|
2884
|
+
/** `@agentproto/llm-endpoint`'s own package version, read from the
|
|
2885
|
+
* resolved bin's `package.json` — best-effort, present only for
|
|
2886
|
+
* `owner:"daemon"` (the version of the code this registry would spawn /
|
|
2887
|
+
* did spawn). Undefined when unresolvable, or for `owner:"external"`
|
|
2888
|
+
* (an adopted process exposes no version of its own to probe). */
|
|
2889
|
+
version?: string;
|
|
2890
|
+
}
|
|
2891
|
+
interface LlmEndpointDescriptor {
|
|
2892
|
+
pid: number | null;
|
|
2893
|
+
port: number;
|
|
2894
|
+
baseUrl: string;
|
|
2895
|
+
status: LlmEndpointStatus;
|
|
2896
|
+
startedAt: string;
|
|
2897
|
+
stoppedAt?: string;
|
|
2898
|
+
lastError?: string;
|
|
2899
|
+
/** Provider names whose keys were injected into the child's env (never values). */
|
|
2900
|
+
injectedProviders?: string[];
|
|
2901
|
+
/** Upstream names mapped to an auth-profile link (`LLM_ENDPOINT_PROFILE_<P>`)
|
|
2902
|
+
* in the child's env. Profile IDS, not secrets — but only the provider names
|
|
2903
|
+
* are surfaced here, mirroring `injectedProviders`. */
|
|
2904
|
+
linkedProviders?: string[];
|
|
2905
|
+
/**
|
|
2906
|
+
* Only populated on the value returned by {@link LlmEndpointRegistry.start}
|
|
2907
|
+
* (never stored on the in-memory descriptor): `true` when the call reused an
|
|
2908
|
+
* already-running/starting child instead of spawning — so the caller can
|
|
2909
|
+
* tell a fresh `start` (new port/tokens applied) from a no-op idempotent hit
|
|
2910
|
+
* (old descriptor returned, nothing new applied). Mirrors `start_browser`.
|
|
2911
|
+
*/
|
|
2912
|
+
wasAlreadyRunning?: boolean;
|
|
2913
|
+
}
|
|
2914
|
+
|
|
2766
2915
|
/**
|
|
2767
2916
|
* RemoteController — owns the gateway's "publish to the internet" state.
|
|
2768
2917
|
*
|
|
@@ -2970,6 +3119,14 @@ interface PairingRecord {
|
|
|
2970
3119
|
/** Set on a pairing made under the retired pair/v1 protocol: listed and
|
|
2971
3120
|
* revocable, never served — its client is told to re-pair. */
|
|
2972
3121
|
legacy?: true;
|
|
3122
|
+
/** Set when this pairing was made under an offer minted with
|
|
3123
|
+
* `agentproto pair offer --host` (PR-C) — i.e. the offering daemon's own
|
|
3124
|
+
* intent, recorded server-side at handshake time from the OfferEntry it
|
|
3125
|
+
* itself created, never from the (unauthenticated) `scope` param a client
|
|
3126
|
+
* presented in the offer URL. Absent for an ordinary remote-control
|
|
3127
|
+
* pairing. Purely informational here — it does not change how this
|
|
3128
|
+
* pairing is served. */
|
|
3129
|
+
scope?: "host";
|
|
2973
3130
|
}
|
|
2974
3131
|
/** Mode of a served channel — first-contact offer vs. an established reconnect. */
|
|
2975
3132
|
type PairingChannelMode = "offer" | "reconnect";
|
|
@@ -3003,12 +3160,21 @@ interface CreatedOffer {
|
|
|
3003
3160
|
* falls back to `HOSTED_RENDEZVOUS_URL`. Surfaced so `pair offer` can flag,
|
|
3004
3161
|
* never silently, that the daemon is relaying through our infrastructure. */
|
|
3005
3162
|
rendezvousIsHostedDefault: boolean;
|
|
3163
|
+
/** Echoes `CreateOfferInput.scope`. `"host"` when minted with `--host`;
|
|
3164
|
+
* absent for a plain offer. */
|
|
3165
|
+
scope?: "host";
|
|
3006
3166
|
}
|
|
3007
3167
|
interface CreateOfferInput {
|
|
3008
3168
|
/** Time-to-live in ms. Default 10 minutes. */
|
|
3009
3169
|
ttlMs?: number;
|
|
3010
3170
|
/** Rendezvous URL override; falls back to the configured default. */
|
|
3011
3171
|
rendezvousUrl?: string;
|
|
3172
|
+
/** Mint a HOST-scoped offer (PR-C): the accepting side may register this
|
|
3173
|
+
* daemon as a driveable host (`devices add`), not just remote-control it.
|
|
3174
|
+
* Recorded on the resulting `OfferEntry`/`PairingRecord` server-side — this
|
|
3175
|
+
* is the authoritative record of what was granted, independent of the
|
|
3176
|
+
* `scope` param an accepting client's offer URL happens to carry. */
|
|
3177
|
+
scope?: "host";
|
|
3012
3178
|
}
|
|
3013
3179
|
interface PairingRegistryDeps {
|
|
3014
3180
|
/** Lazily load (create on first use) the daemon identity. Kept lazy so a
|
|
@@ -3052,17 +3218,174 @@ interface PairingRegistry {
|
|
|
3052
3218
|
createOffer(input?: CreateOfferInput): Promise<CreatedOffer>;
|
|
3053
3219
|
/** All persisted pairings (copies). Loads `pairings.json` on first call. */
|
|
3054
3220
|
list(): Promise<PairingRecord[]>;
|
|
3221
|
+
/** Rename a pairing by fingerprint or name (cosmetic only — no effect on
|
|
3222
|
+
* auth or routing). Returns false when nothing matched; throws on an
|
|
3223
|
+
* empty `newName`. */
|
|
3224
|
+
rename(idOrName: string, newName: string): Promise<boolean>;
|
|
3055
3225
|
/** Drop a pairing by fingerprint or name; stops its rendezvous connections.
|
|
3056
3226
|
* Returns false when nothing matched. */
|
|
3057
3227
|
revoke(idOrName: string): Promise<boolean>;
|
|
3228
|
+
/** Is a channel (offer or reconnect) currently served for this fingerprint? */
|
|
3229
|
+
isOnline(fingerprint: string): boolean;
|
|
3058
3230
|
/** Start standing reconnect connections for every persisted pairing. Call
|
|
3059
3231
|
* after the gateway is up (so the injected `serve` can reach it). */
|
|
3060
3232
|
startAutoconnect(): Promise<void>;
|
|
3061
3233
|
/** Tear down every offer + reconnect connection and served channel. */
|
|
3062
3234
|
shutdown(): Promise<void>;
|
|
3063
3235
|
}
|
|
3236
|
+
/**
|
|
3237
|
+
* Read-only snapshot of `pairings.json` for callers that just want the
|
|
3238
|
+
* persisted records — no `dial`/`serve`/`loadIdentity` deps, no rendezvous
|
|
3239
|
+
* connections started (e.g. `agentproto doctor`'s devices check). Mirrors
|
|
3240
|
+
* `ensureLoaded`'s parse + v1-legacy flagging; never throws — a missing or
|
|
3241
|
+
* malformed file just yields `[]`.
|
|
3242
|
+
*/
|
|
3243
|
+
declare function readPairingsSnapshot(path?: string): Promise<PairingRecord[]>;
|
|
3064
3244
|
declare function createPairingRegistry(deps: PairingRegistryDeps): PairingRegistry;
|
|
3065
3245
|
|
|
3246
|
+
/**
|
|
3247
|
+
* Daemon-side HOST registry (DEVICES-PLAN PR-C) — the "client" half of
|
|
3248
|
+
* pair/v2, living on the daemon so it's reachable over both an HTTP route
|
|
3249
|
+
* and an MCP tool, not just CLI-local bookkeeping (`client-pairings.ts` /
|
|
3250
|
+
* `pair-transport.ts` are that CLI-local equivalent today).
|
|
3251
|
+
*
|
|
3252
|
+
* Where `pairing-registry.ts` is what a daemon uses to let OTHER machines
|
|
3253
|
+
* pair with and remote-control IT, `host-registry.ts` is what a daemon uses
|
|
3254
|
+
* to register and drive OTHER daemons — reverse pairing. `add()` accepts a
|
|
3255
|
+
* HOST-scoped offer (`agentproto pair offer --host`, offer-url.ts's
|
|
3256
|
+
* `scope`), runs the pair/v2 client handshake, and persists the resulting
|
|
3257
|
+
* pair root; `forwardHttp()` dials on demand, reconnecting over the current
|
|
3258
|
+
* (then previous) epoch token exactly like `pair-transport.ts`'s
|
|
3259
|
+
* `openPairChannel`, forwards one HTTP request over the resulting tunnel
|
|
3260
|
+
* client, and closes. There is no standing connection here — unlike
|
|
3261
|
+
* `PairingRegistry`, a `HostRegistry` never autoconnects or keeps a
|
|
3262
|
+
* reconnect loop parked at the broker; every reach-out is a fresh dial.
|
|
3263
|
+
* That also means shutdown needs no teardown: there is nothing standing to
|
|
3264
|
+
* tear down.
|
|
3265
|
+
*
|
|
3266
|
+
* ## The scope gate
|
|
3267
|
+
*
|
|
3268
|
+
* `add()` REFUSES (throws) any offer whose parsed `scope !== "host"` before
|
|
3269
|
+
* ever dialing anything. This is the default-deny gate PR-C exists to add:
|
|
3270
|
+
* an ordinary "remote-control me" offer (today's `pair offer`, no `--host`)
|
|
3271
|
+
* must not silently become a host registration, even though the underlying
|
|
3272
|
+
* wire capability is identical either way (see offer-url.ts's "Offer scope"
|
|
3273
|
+
* and pairing-registry.ts's `OfferEntry.scope` doc comment for why the
|
|
3274
|
+
* offering daemon's OWN server-side record — not the URL's plaintext
|
|
3275
|
+
* `scope` param — is what's authoritative about what it granted). There is
|
|
3276
|
+
* deliberately no override flag.
|
|
3277
|
+
*
|
|
3278
|
+
* Persisted to `hosts.json` (`~/.agentproto/hosts.json` by default) with the
|
|
3279
|
+
* same atomic-write discipline as `pairings.json` (mkdir, write to a
|
|
3280
|
+
* pid-keyed tmp file at 0600, chmod, rename) and the same lazy-load-on-
|
|
3281
|
+
* first-use pattern.
|
|
3282
|
+
*
|
|
3283
|
+
* ## Online tracking
|
|
3284
|
+
*
|
|
3285
|
+
* `isOnline(fingerprint)` mirrors `PairingRegistry.isOnline`: it's true only
|
|
3286
|
+
* while a `forwardHttp()` call for that fingerprint is in flight (a
|
|
3287
|
+
* reference count, incremented on dial and decremented in a `finally`).
|
|
3288
|
+
* There is no live probe backing `list()` — that would make `devices list`
|
|
3289
|
+
* slow/flaky over N hosts — so `list()`'s `online` is only ever true
|
|
3290
|
+
* immediately after (or during) an actual `forwardHttp`/`devices status`
|
|
3291
|
+
* call, never a background heartbeat. That's enough to make `devices list`
|
|
3292
|
+
* show the right thing right after `devices status`/`exec`, which is what
|
|
3293
|
+
* matters for this PR; a standing/autoconnect host connection with a real
|
|
3294
|
+
* liveness signal is PR-D's to build.
|
|
3295
|
+
*/
|
|
3296
|
+
|
|
3297
|
+
/** `hosts.json` format. */
|
|
3298
|
+
declare const HOSTS_VERSION: 1;
|
|
3299
|
+
/** One persisted host — a daemon this daemon can drive. */
|
|
3300
|
+
interface HostRecord {
|
|
3301
|
+
/** The target daemon's identity fingerprint (32 hex). */
|
|
3302
|
+
fingerprint: string;
|
|
3303
|
+
/** Human-facing label; defaults to the fingerprint. */
|
|
3304
|
+
name: string;
|
|
3305
|
+
/** Target daemon's static X25519 public key, standard base64 SPKI DER —
|
|
3306
|
+
* pinned at `add()` time. */
|
|
3307
|
+
daemonX25519Pub: string;
|
|
3308
|
+
/** Target daemon's static Ed25519 public key, standard base64 SPKI DER —
|
|
3309
|
+
* pinned at `add()` time. */
|
|
3310
|
+
daemonEd25519Pub: string;
|
|
3311
|
+
/** Rendezvous endpoint to reach the host through. */
|
|
3312
|
+
rendezvousUrl: string;
|
|
3313
|
+
/** Long-term shared secret (base64), from which epoch routing tokens
|
|
3314
|
+
* derive — same derivation as `PairingRecord.pairRoot`. */
|
|
3315
|
+
pairRoot: string;
|
|
3316
|
+
/** ISO-8601 first-add timestamp. */
|
|
3317
|
+
createdAt: string;
|
|
3318
|
+
/** ISO-8601 of the most recent successful `forwardHttp`. */
|
|
3319
|
+
lastSeen: string;
|
|
3320
|
+
/** Set on a host added under the retired pair/v1 protocol. Present for
|
|
3321
|
+
* parity with `PairingRecord`/`ClientPairing`; pair/v1 offers are refused
|
|
3322
|
+
* by `parseOfferUrl` before `add()` ever sees them, so this is currently
|
|
3323
|
+
* unreachable — kept so a future downgrade path has somewhere to flag it. */
|
|
3324
|
+
legacy?: true;
|
|
3325
|
+
}
|
|
3326
|
+
interface HostRegistryDeps {
|
|
3327
|
+
/** Dial a rendezvous WS and adapt it to a `FrameSink`. Same shape as
|
|
3328
|
+
* `PairingRegistryDeps.dial` — the CLI's `daemonDialRendezvous` satisfies
|
|
3329
|
+
* it directly. Rejects if the dial fails or `signal` aborts. */
|
|
3330
|
+
dial: (wsUrl: string, signal: AbortSignal) => Promise<FrameSink>;
|
|
3331
|
+
/** Path to `hosts.json`. Defaults to `~/.agentproto/hosts.json`. */
|
|
3332
|
+
hostsPath?: string;
|
|
3333
|
+
/** Injectable clock (ms). Defaults to Date.now. */
|
|
3334
|
+
now?: () => number;
|
|
3335
|
+
/** Diagnostic log sink. */
|
|
3336
|
+
log?: (line: string) => void;
|
|
3337
|
+
/** Rendezvous dial ceiling per attempt. Default 15s. */
|
|
3338
|
+
dialTimeoutMs?: number;
|
|
3339
|
+
/** Handshake ceiling per attempt. Default 15s. */
|
|
3340
|
+
handshakeTimeoutMs?: number;
|
|
3341
|
+
}
|
|
3342
|
+
interface ForwardHttpRequest {
|
|
3343
|
+
method: string;
|
|
3344
|
+
path: string;
|
|
3345
|
+
headers?: Record<string, string>;
|
|
3346
|
+
body?: Uint8Array;
|
|
3347
|
+
}
|
|
3348
|
+
interface ForwardHttpResponse {
|
|
3349
|
+
status: number;
|
|
3350
|
+
headers: Record<string, string>;
|
|
3351
|
+
body: Uint8Array;
|
|
3352
|
+
}
|
|
3353
|
+
interface HostRegistry {
|
|
3354
|
+
/**
|
|
3355
|
+
* Accept an offer URL and register the target daemon as a driveable host.
|
|
3356
|
+
* REFUSES (throws a plain `Error`) unless the parsed offer has
|
|
3357
|
+
* `scope === "host"` — no dial is attempted in that case. Otherwise: dials
|
|
3358
|
+
* the offer's rendezvous, runs the pair/v2 client handshake, verifies the
|
|
3359
|
+
* derived peer fingerprint matches the offer's `id` (defence in depth,
|
|
3360
|
+
* mirrors `pair-transport.ts`'s `acceptOffer`), derives the pair root, and
|
|
3361
|
+
* persists a `HostRecord` (upserted by fingerprint — re-adding replaces).
|
|
3362
|
+
*/
|
|
3363
|
+
add(offerUrl: string, name?: string): Promise<{
|
|
3364
|
+
fingerprint: string;
|
|
3365
|
+
name: string;
|
|
3366
|
+
rendezvousUrl: string;
|
|
3367
|
+
}>;
|
|
3368
|
+
/** All persisted hosts (copies). Loads `hosts.json` on first call. */
|
|
3369
|
+
list(): Promise<HostRecord[]>;
|
|
3370
|
+
/** Rename a host (fingerprint or current name). Returns false when nothing
|
|
3371
|
+
* matched; throws on an empty `newName`. */
|
|
3372
|
+
rename(idOrName: string, newName: string): Promise<boolean>;
|
|
3373
|
+
/** Drop a host by fingerprint or name. Returns false when nothing matched. */
|
|
3374
|
+
revoke(idOrName: string): Promise<boolean>;
|
|
3375
|
+
/** Is a `forwardHttp` call for this fingerprint in flight right now? */
|
|
3376
|
+
isOnline(fingerprint: string): boolean;
|
|
3377
|
+
/**
|
|
3378
|
+
* On-demand: dial the host, run the client handshake against the current
|
|
3379
|
+
* epoch's tokens (falling back to the previous epoch, bridging clock
|
|
3380
|
+
* skew — same two-attempt shape as `pair-transport.ts`'s
|
|
3381
|
+
* `openPairChannel`), forward one HTTP request over the resulting tunnel
|
|
3382
|
+
* client, then close. Throws with a re-pair hint if every attempt hangs up
|
|
3383
|
+
* on the hello (likely a pair/v1 peer).
|
|
3384
|
+
*/
|
|
3385
|
+
forwardHttp(idOrName: string, req: ForwardHttpRequest): Promise<ForwardHttpResponse>;
|
|
3386
|
+
}
|
|
3387
|
+
declare function createHostRegistry(deps: HostRegistryDeps): HostRegistry;
|
|
3388
|
+
|
|
3066
3389
|
/**
|
|
3067
3390
|
* Shared types for pluggable sandbox providers.
|
|
3068
3391
|
*
|
|
@@ -4394,6 +4717,18 @@ interface SpawnAgentSessionDeps {
|
|
|
4394
4717
|
* manifest not covering the requested model still reaches the driver,
|
|
4395
4718
|
* same as before this guard existed. */
|
|
4396
4719
|
listCatalogModels?: CatalogModelsLister;
|
|
4720
|
+
/** Ensure the local `llm-endpoint` proxy sidecar (`LlmEndpointRegistry`)
|
|
4721
|
+
* is up before a spawn that bills through it. Without this hook, a spawn
|
|
4722
|
+
* whose resolved gateway is `"llm-endpoint"` assumed the sidecar was
|
|
4723
|
+
* already running (started externally, or via the `llm_endpoint_start`
|
|
4724
|
+
* MCP tool) — a fresh install with `features.llmEndpoint` on but nothing
|
|
4725
|
+
* having called that tool yet would spawn fine and only fail once the
|
|
4726
|
+
* adapter made its first request. Wired to the registry's own
|
|
4727
|
+
* (idempotent) `start()` at the composition root; omitted ⇒ unchanged
|
|
4728
|
+
* pre-existing behavior. Best-effort: a rejection here is swallowed by
|
|
4729
|
+
* the caller, not surfaced as a spawn failure — the adapter's own first
|
|
4730
|
+
* request is left to report the real connection error. */
|
|
4731
|
+
ensureLlmEndpointRunning?: () => Promise<void>;
|
|
4397
4732
|
}
|
|
4398
4733
|
interface SpawnAgentSessionInput {
|
|
4399
4734
|
adapter: string;
|
|
@@ -4455,7 +4790,19 @@ interface SpawnAgentSessionInput {
|
|
|
4455
4790
|
* blank. Not exposed on the MCP `agent_start` tool today — only the
|
|
4456
4791
|
* HTTP route (`sessions restart`) passes this. */
|
|
4457
4792
|
resumeSessionId?: string;
|
|
4458
|
-
|
|
4793
|
+
/** The caller's initial ask — a plain string (the common case, composed
|
|
4794
|
+
* with the role/AGENTS.md/RULES.md preamble below into one string turn),
|
|
4795
|
+
* or a content block / block array (an attachment-bearing first message,
|
|
4796
|
+
* same loose shape `POST /sessions/:id/prompt` accepts). The block form
|
|
4797
|
+
* is a narrow path: composing daemon-synthesized preamble TEXT onto a
|
|
4798
|
+
* turn that opens with an image isn't meaningful string concatenation,
|
|
4799
|
+
* so it SKIPS the whole preamble composition below (role disposition,
|
|
4800
|
+
* AGENTS.md, RULES.md, parent-lineage line, posture-as-prompt fallback)
|
|
4801
|
+
* and is sent to the adapter verbatim — see `effectivePrompt`'s doc.
|
|
4802
|
+
* Acceptable because this path is human/UI-initiated (an attachment
|
|
4803
|
+
* typed into a chat composer), not the orchestrator-driven role spawns
|
|
4804
|
+
* that actually depend on the composed disposition text. */
|
|
4805
|
+
prompt?: string | Record<string, unknown> | unknown[];
|
|
4459
4806
|
label?: string;
|
|
4460
4807
|
/** Explicit session title (SPEC-3 FIX C, `agentproto sessions start
|
|
4461
4808
|
* --title`). When set, it wins over the first-sentence derivation from
|
|
@@ -4955,6 +5302,8 @@ interface BranchGcPlanView {
|
|
|
4955
5302
|
includeReviewed: boolean;
|
|
4956
5303
|
generatedAt: string;
|
|
4957
5304
|
otherRemoteRefs: number;
|
|
5305
|
+
/** true = base-remote `fetch --prune` succeeded; false = failed; null = skipped / no remote. */
|
|
5306
|
+
fetched: boolean | null;
|
|
4958
5307
|
entries: BranchGcPlanEntryView[];
|
|
4959
5308
|
}
|
|
4960
5309
|
/** kind → class → count, and kind → (status | "protected") → count. */
|
|
@@ -5158,12 +5507,10 @@ type AgentAdapterResolver = (slug: string) => Promise<{
|
|
|
5158
5507
|
}): Promise<AgentSessionLike>;
|
|
5159
5508
|
/** Display label for the descriptor's `command` field. */
|
|
5160
5509
|
commandPreview?: string;
|
|
5161
|
-
/** Best-effort per-session usage reader (adapter-specific, e.g. hermes
|
|
5162
|
-
|
|
5163
|
-
|
|
5164
|
-
|
|
5165
|
-
tokensOut?: number;
|
|
5166
|
-
} | null>;
|
|
5510
|
+
/** Best-effort per-session usage reader (adapter-specific, e.g. hermes
|
|
5511
|
+
* state.db, the claude-code transcript JSONL). `ctx` carries the spawn's
|
|
5512
|
+
* cwd + isolated config dir for readers that locate their store by them. */
|
|
5513
|
+
readUsage?: (adapterSessionId: string, ctx?: UsageReadContext) => Promise<UsageReadResult | null>;
|
|
5167
5514
|
/** AIP-45 `options[]` this adapter's manifest declares (id + type only —
|
|
5168
5515
|
* no spawn internals). Lets `session-spawn.ts` fold a config-level
|
|
5169
5516
|
* `defaults.skills` list into `options.skills` using the shape the
|
|
@@ -6320,16 +6667,32 @@ interface SessionDescriptor {
|
|
|
6320
6667
|
* `status` to `"error"` directly (a genuinely terminal row the existing
|
|
6321
6668
|
* crash/error handling already catches). This is the twin gap for a
|
|
6322
6669
|
* turn that fails IN-BAND while the process stays alive: `status` stays
|
|
6323
|
-
* `"running"`, `lastError` stays unset (reserved for `markCrashed`
|
|
6324
|
-
*
|
|
6325
|
-
*
|
|
6326
|
-
*
|
|
6327
|
-
*
|
|
6328
|
-
*
|
|
6329
|
-
*
|
|
6330
|
-
*
|
|
6670
|
+
* `"running"`, `lastError` stays unset (still reserved for `markCrashed`
|
|
6671
|
+
* — see `lastTurnErrorMessage` below for the message text this field's
|
|
6672
|
+
* own turn carries), and nothing else distinguishes the session from
|
|
6673
|
+
* one that simply finished a clean turn and is idle. Folded into the
|
|
6674
|
+
* same "stalled" activity/UI treatment a mid-turn stall gets (see
|
|
6675
|
+
* sessionsTree.logic.ts's `activityFor`) rather than a new state, on
|
|
6676
|
+
* the theory that both mean "the last thing this session did needs a
|
|
6677
|
+
* look, not a re-prompt on faith". Stamped at turn-end when
|
|
6678
|
+
* `turnEndReason === "error"` — including the case where the adapter's
|
|
6679
|
+
* stream generator simply returned after emitting an in-band `error`
|
|
6680
|
+
* event with no explicit turn-end and no thrown exception, which
|
|
6681
|
+
* `runAgentTurn`'s P5 synthetic-reason fallback now classifies as
|
|
6682
|
+
* `"error"` rather than defaulting to `"exited"`. Cleared the moment a
|
|
6683
|
+
* LATER turn completes without one (same reset shape as
|
|
6331
6684
|
* `resumeAttempts`/`restartAttempts`). Detection + signal only. */
|
|
6332
6685
|
lastTurnErroredAt?: string;
|
|
6686
|
+
/** The captured error text for the turn `lastTurnErroredAt` timestamps —
|
|
6687
|
+
* `evt.error.message` off the in-band stream `error` event observed
|
|
6688
|
+
* during that turn (see `runAgentTurn`'s `turnErrorMessage`). Distinct
|
|
6689
|
+
* from `lastError` (reserved for `markCrashed`) and from
|
|
6690
|
+
* `rt.lastErrorMessage` (an internal, cross-turn, never-cleared runtime
|
|
6691
|
+
* field — this one is the public, turn-scoped descriptor projection of
|
|
6692
|
+
* it). Absent when the adapter reported `reason:"error"` on its own
|
|
6693
|
+
* turn-end without a preceding `error`-kind stream event. Stamped and
|
|
6694
|
+
* cleared together with `lastTurnErroredAt`. */
|
|
6695
|
+
lastTurnErrorMessage?: string;
|
|
6333
6696
|
/** True when the LAST completed turn produced zero assistant output and
|
|
6334
6697
|
* zero tool calls (mirrors `SessionTurnEndEvent.empty` — see that
|
|
6335
6698
|
* field's doc). Persisted so `monitorSessionWait`'s synchronous
|
|
@@ -6359,6 +6722,29 @@ interface SessionDescriptor {
|
|
|
6359
6722
|
* the underlying `killedMidTurn`/`endedReason`). The in-place resume path
|
|
6360
6723
|
* never auto-retries the interrupted prompt. */
|
|
6361
6724
|
interrupted?: boolean;
|
|
6725
|
+
/** The `SessionsRegistry.bootId` of the FIRST daemon boot that found this
|
|
6726
|
+
* row interrupted — i.e. which restart cut its turn off. Stamped by the
|
|
6727
|
+
* boot reload (`loadHistorySnapshot`) on an interrupted row that doesn't
|
|
6728
|
+
* carry one yet; dropped whenever the row is interrupted AGAIN (so the next
|
|
6729
|
+
* boot restamps it) and on the next successful turn-end (with the markers it
|
|
6730
|
+
* qualifies). `interruptedAtBoot === registry.bootId` is how the
|
|
6731
|
+
* continue-interrupted verb and boot pass pick "interrupted by the LAST
|
|
6732
|
+
* restart" apart from a stale interruption nobody picked back up. PERSISTED
|
|
6733
|
+
* (unlike the derived `interrupted`) — the boot that stamped it may not be
|
|
6734
|
+
* the one reading it. */
|
|
6735
|
+
interruptedAtBoot?: string;
|
|
6736
|
+
/** How many automatic continue prompts the daemon has sent this row
|
|
6737
|
+
* (`daemon.continueInterruptedOnBoot`) since its last successful turn-end.
|
|
6738
|
+
* Incremented BEFORE the prompt is sent, so a continue turn that itself
|
|
6739
|
+
* gets cut off by another restart still counts; reset on the next
|
|
6740
|
+
* successful turn-end. The boot pass stops at
|
|
6741
|
+
* `MAX_AUTO_CONTINUE_ATTEMPTS` — the no-loop bound for a turn that keeps
|
|
6742
|
+
* taking the daemon down with it. PERSISTED; absent until the first one. */
|
|
6743
|
+
autoContinueAttempts?: number;
|
|
6744
|
+
/** `bootId` of the boot whose pass last auto-continued this row — the
|
|
6745
|
+
* at-most-one-auto-continue-per-restart guard. Reset with
|
|
6746
|
+
* `autoContinueAttempts`. */
|
|
6747
|
+
lastAutoContinueBoot?: string;
|
|
6362
6748
|
/** How many in-place resume attempts have FAILED in a row for this session
|
|
6363
6749
|
* (§5 cap/backoff). Incremented on every failed `maybeResumeAgent` attempt —
|
|
6364
6750
|
* the resume throws, the adapter rejects the id, or the spawn returns null —
|
|
@@ -6717,6 +7103,19 @@ interface SessionDescriptor {
|
|
|
6717
7103
|
/** Cumulative input / output token counts (same source + cadence as costUsd). */
|
|
6718
7104
|
tokensIn?: number;
|
|
6719
7105
|
tokensOut?: number;
|
|
7106
|
+
/** Cumulative prompt-cache read / cache-creation / reasoning tokens, from
|
|
7107
|
+
* the adapter's usage reader (claude-code transcript, hermes state.db,
|
|
7108
|
+
* opencode.db). Absent when the adapter doesn't expose them — never
|
|
7109
|
+
* zero-filled. See `UsageDetail` in usage.ts. */
|
|
7110
|
+
cacheReadTokens?: number;
|
|
7111
|
+
cacheWriteTokens?: number;
|
|
7112
|
+
reasoningTokens?: number;
|
|
7113
|
+
/** Tool calls the daemon observed across completed turns (cumulative).
|
|
7114
|
+
* Stamped at the first turn end, so absent = no turn has finished yet. */
|
|
7115
|
+
toolCalls?: number;
|
|
7116
|
+
/** Wall time spent inside turns, cumulative ms. Same cadence as
|
|
7117
|
+
* `toolCalls`. */
|
|
7118
|
+
durationMs?: number;
|
|
6720
7119
|
/** Context-window size + tokens-in-context from the latest `usage_update`
|
|
6721
7120
|
* event (ACP adapters that report a context window). Refreshed live as
|
|
6722
7121
|
* usage_update events arrive, not just at turn-end. */
|
|
@@ -7636,6 +8035,21 @@ interface SessionsRegistry {
|
|
|
7636
8035
|
reason?: string;
|
|
7637
8036
|
interrupted?: boolean;
|
|
7638
8037
|
}>;
|
|
8038
|
+
/** A currently-RUNNING background task's info plus a tail of its output
|
|
8039
|
+
* file, for the UI's "click a live background-task row to peek at its
|
|
8040
|
+
* output" affordance. Scoped to `SessionDescriptor.backgroundTasks` on
|
|
8041
|
+
* purpose — a settled task is dropped from that list moments after it
|
|
8042
|
+
* reports terminal status (see `noteBackgroundTask`), so this never
|
|
8043
|
+
* becomes an arbitrary-file-read: the caller supplies a `taskId`, never a
|
|
8044
|
+
* path, and only a path the agent itself already reported for a task
|
|
8045
|
+
* still tracked as running is ever read. Returns `null` when the session
|
|
8046
|
+
* or the task is unknown (the caller surfaces 404); `tail` is `null` when
|
|
8047
|
+
* the task has no `outputFile` or the file can't be read (not yet
|
|
8048
|
+
* created, already rotated away, ...). */
|
|
8049
|
+
readBackgroundTaskTail(id: string, taskId: string): {
|
|
8050
|
+
task: SessionBackgroundTask;
|
|
8051
|
+
tail: string | null;
|
|
8052
|
+
} | null;
|
|
7639
8053
|
/** Eagerly resume ONE dead-but-resumable agent-cli session IN PLACE,
|
|
7640
8054
|
* WITHOUT a prompt — the boot-time counterpart to the lazy resume that
|
|
7641
8055
|
* `sendPrompt`/`enqueuePrompt` trigger on the first prompt after a restart
|
|
@@ -7658,6 +8072,17 @@ interface SessionsRegistry {
|
|
|
7658
8072
|
* touching the adapter, so the bounded boot pass can call it per row and
|
|
7659
8073
|
* tally the results. */
|
|
7660
8074
|
resumeOnBoot(id: string): Promise<EagerResumeOutcome>;
|
|
8075
|
+
/** Opaque id unique to this registry instance — one per daemon boot.
|
|
8076
|
+
* Stamped as `interruptedAtBoot` on rows the boot reload finds interrupted,
|
|
8077
|
+
* so `interruptedAtBoot === bootId` means "interrupted by the restart that
|
|
8078
|
+
* preceded THIS boot" (continue-interrupted). */
|
|
8079
|
+
readonly bootId: string;
|
|
8080
|
+
/** Book one automatic continue prompt against `id` (increment
|
|
8081
|
+
* `autoContinueAttempts`, stamp `lastAutoContinueBoot = bootId`) and
|
|
8082
|
+
* persist. Called by the continue-on-boot pass BEFORE it sends, so the
|
|
8083
|
+
* no-loop bound holds even when the continue turn is itself cut off by the
|
|
8084
|
+
* next restart. No-op for an unknown id. */
|
|
8085
|
+
recordAutoContinue(id: string): void;
|
|
7661
8086
|
/** Cancel the in-flight turn on a live agent-cli session and leave the
|
|
7662
8087
|
* session itself alive and idle — the bare "interrupt, no next prompt"
|
|
7663
8088
|
* primitive `sendPrompt`/`enqueuePrompt`'s `opts.interrupt` arm lacks
|
|
@@ -8167,8 +8592,10 @@ interface SpawnAgentInput {
|
|
|
8167
8592
|
/** Optional initial prompt to dispatch immediately. The promise
|
|
8168
8593
|
* the registry returns resolves AFTER the spawn — the prompt
|
|
8169
8594
|
* runs in the background, projecting events into the ring
|
|
8170
|
-
* buffer. Skip to spawn idle.
|
|
8171
|
-
|
|
8595
|
+
* buffer. Skip to spawn idle. A plain string, or a content-block
|
|
8596
|
+
* prompt (attachment-bearing first message) — see
|
|
8597
|
+
* `SpawnAgentSessionInput.prompt`'s doc. */
|
|
8598
|
+
initialPrompt?: string | Record<string, unknown> | unknown[];
|
|
8172
8599
|
/** The daemon-composed SYSTEM slice of {@link initialPrompt} — the part
|
|
8173
8600
|
* it synthesized ahead of the CALLER's ask (role disposition, lineage
|
|
8174
8601
|
* line, AGENTS.md, posture preamble). The adapter still receives the
|
|
@@ -8260,12 +8687,7 @@ interface SpawnAgentInput {
|
|
|
8260
8687
|
* cost/token fields on the descriptor. Adapter-specific (e.g. hermes
|
|
8261
8688
|
* reads its state.db keyed by the adapter session id). Omit for adapters
|
|
8262
8689
|
* with no usage source. */
|
|
8263
|
-
readUsage?: () => Promise<
|
|
8264
|
-
model?: string;
|
|
8265
|
-
costUsd?: number;
|
|
8266
|
-
tokensIn?: number;
|
|
8267
|
-
tokensOut?: number;
|
|
8268
|
-
} | null>;
|
|
8690
|
+
readUsage?: () => Promise<UsageReadResult | null>;
|
|
8269
8691
|
/** Opt this session into Langfuse tracing (prompt/completion + tool spans +
|
|
8270
8692
|
* tokens/cost). Effective opt-in is `trace ?? opts.langfuseTracingDefault ?? false`. */
|
|
8271
8693
|
trace?: boolean;
|
|
@@ -8322,15 +8744,12 @@ type PendingAgentOutcome = {
|
|
|
8322
8744
|
commandPreview?: string;
|
|
8323
8745
|
resumable?: boolean;
|
|
8324
8746
|
nativeTerminalResume?: boolean;
|
|
8325
|
-
readUsage?: () => Promise<
|
|
8326
|
-
model?: string;
|
|
8327
|
-
costUsd?: number;
|
|
8328
|
-
tokensIn?: number;
|
|
8329
|
-
tokensOut?: number;
|
|
8330
|
-
} | null>;
|
|
8747
|
+
readUsage?: () => Promise<UsageReadResult | null>;
|
|
8331
8748
|
/** Dispatched now that the tree + driver session both exist — never
|
|
8332
|
-
* passed to `spawnAgentPending`, which would race the tree.
|
|
8333
|
-
|
|
8749
|
+
* passed to `spawnAgentPending`, which would race the tree. A plain
|
|
8750
|
+
* string, or a content-block prompt (attachment-bearing first
|
|
8751
|
+
* message) — see `SpawnAgentSessionInput.prompt`'s doc. */
|
|
8752
|
+
initialPrompt?: string | Record<string, unknown> | unknown[];
|
|
8334
8753
|
/** The daemon-composed SYSTEM slice of `initialPrompt` (see
|
|
8335
8754
|
* `SpawnAgentInput.initialPromptSystem`) — threaded through the
|
|
8336
8755
|
* placeholder so the deferred dispatch records it as a system turn. */
|
|
@@ -8606,6 +9025,163 @@ declare function runEagerResumePass(opts: {
|
|
|
8606
9025
|
isServed?: (desc: SessionDescriptor) => boolean;
|
|
8607
9026
|
}): Promise<EagerResumeSummary>;
|
|
8608
9027
|
|
|
9028
|
+
/**
|
|
9029
|
+
* Continue-interrupted: pick back up the sessions a daemon restart cut off
|
|
9030
|
+
* mid-turn, by sending each an explicit "continue" prompt.
|
|
9031
|
+
*
|
|
9032
|
+
* Everything below the prompt already exists — the persisted registry is the
|
|
9033
|
+
* snapshot, `maybeResumeAgent` resumes a dead row in place (lazily on its first
|
|
9034
|
+
* prompt, or eagerly at boot via `eager-resume.ts`), and the row keeps the
|
|
9035
|
+
* derived `interrupted` marker until its next successful turn-end. What a
|
|
9036
|
+
* restart does NOT do, by design, is re-run the interrupted prompt (prompts
|
|
9037
|
+
* aren't idempotent). This module is the explicit, opt-in replacement for that:
|
|
9038
|
+
* a NEW prompt that tells the agent its last turn was cut off and to check the
|
|
9039
|
+
* state on disk before carrying on.
|
|
9040
|
+
*
|
|
9041
|
+
* Two callers share one eligibility rule + one sender:
|
|
9042
|
+
* - the manual verb (`session_continue_interrupted` MCP tool,
|
|
9043
|
+
* `POST /sessions/continue-interrupted`, `agentproto sessions
|
|
9044
|
+
* continue-interrupted`) — `mode: "manual"`, dry-run by default;
|
|
9045
|
+
* - the opt-in boot pass (`daemon.continueInterruptedOnBoot`) —
|
|
9046
|
+
* `mode: "boot"`, run by serve.ts right after the eager resume pass.
|
|
9047
|
+
*
|
|
9048
|
+
* Eligibility (both modes): an agent-cli row that is `interrupted` BY THE LAST
|
|
9049
|
+
* RESTART (`interruptedAtBoot === registry.bootId` — a stale interruption from
|
|
9050
|
+
* an older restart that nobody picked up is left alone), resumable under the
|
|
9051
|
+
* attempt cap (`canResume`), and not already busy. The prompt goes through
|
|
9052
|
+
* `enqueuePrompt`, the normal prompt path, so a dead-but-resumable row
|
|
9053
|
+
* lazy-resumes with its billing auth re-resolved exactly as a human prompt
|
|
9054
|
+
* would.
|
|
9055
|
+
*
|
|
9056
|
+
* No-loop rules (boot mode only — a human pressing the button is intent):
|
|
9057
|
+
* - never auto-continue a row whose resume has failed (`resumeAttempts > 0`:
|
|
9058
|
+
* the eager pass, or an earlier attempt, could not bring it back);
|
|
9059
|
+
* - at most one auto-continue per restart (`lastAutoContinueBoot`);
|
|
9060
|
+
* - at most `MAX_AUTO_CONTINUE_ATTEMPTS` auto-continues without a successful
|
|
9061
|
+
* turn-end in between (`autoContinueAttempts`, booked BEFORE sending), so a
|
|
9062
|
+
* continue turn that keeps getting cut off — or keeps taking the daemon
|
|
9063
|
+
* down with it — stops being retried.
|
|
9064
|
+
*
|
|
9065
|
+
* Ordering (boot mode): MUST run after the supervisor is re-armed, same
|
|
9066
|
+
* constraint as `eager-resume.ts` — the continue turn's `turn-end` is exactly
|
|
9067
|
+
* what a re-armed completion policy is waiting for — and after the eager pass,
|
|
9068
|
+
* so a row whose eager resume failed is recognisable (`resumeAttempts`) and
|
|
9069
|
+
* skipped rather than lazily retried.
|
|
9070
|
+
*/
|
|
9071
|
+
|
|
9072
|
+
/** The prompt sent when the caller doesn't supply one. */
|
|
9073
|
+
declare const DEFAULT_CONTINUE_PROMPT: string;
|
|
9074
|
+
/** Transcript provenance for the continue prompt (`opts.source`). */
|
|
9075
|
+
declare const CONTINUE_PROMPT_SOURCE = "daemon:continue-interrupted";
|
|
9076
|
+
/** Cap on automatic continue prompts sent to one row without a successful
|
|
9077
|
+
* turn-end in between (boot mode). 2 = the original interruption gets one
|
|
9078
|
+
* auto-continue, and if a second restart cuts THAT turn off it gets one more;
|
|
9079
|
+
* after that only a human (manual verb) re-sends. */
|
|
9080
|
+
declare const MAX_AUTO_CONTINUE_ATTEMPTS = 2;
|
|
9081
|
+
type ContinueInterruptedSkipReason =
|
|
9082
|
+
/** Unknown id (explicit `ids` filter only). */
|
|
9083
|
+
"unknown"
|
|
9084
|
+
/** Not interrupted at all — no turn was cut off. */
|
|
9085
|
+
| "not-interrupted"
|
|
9086
|
+
/** Interrupted by an EARLIER restart, not the last one. */
|
|
9087
|
+
| "stale-interrupt"
|
|
9088
|
+
/** Not in-place resumable (not agent-cli / missing adapter session / archived). */
|
|
9089
|
+
| "not-resumable"
|
|
9090
|
+
/** Already burned through `MAX_RESUME_ATTEMPTS` failed resumes. */
|
|
9091
|
+
| "resume-cap-exhausted"
|
|
9092
|
+
/** Mid-turn already — someone got there first. */
|
|
9093
|
+
| "busy"
|
|
9094
|
+
/** Boot mode: a resume attempt has failed on this row. */
|
|
9095
|
+
| "resume-failed"
|
|
9096
|
+
/** Boot mode: already auto-continued by this boot. */
|
|
9097
|
+
| "already-auto-continued"
|
|
9098
|
+
/** Boot mode: `MAX_AUTO_CONTINUE_ATTEMPTS` reached without recovering. */
|
|
9099
|
+
| "auto-continue-cap"
|
|
9100
|
+
/** Excluded by the cross-process `isServed` gate (another daemon's row). */
|
|
9101
|
+
| "not-served";
|
|
9102
|
+
type ContinueInterruptedOutcome = {
|
|
9103
|
+
id: string;
|
|
9104
|
+
name?: string;
|
|
9105
|
+
status: "eligible";
|
|
9106
|
+
} | {
|
|
9107
|
+
id: string;
|
|
9108
|
+
name?: string;
|
|
9109
|
+
status: "sent";
|
|
9110
|
+
} | {
|
|
9111
|
+
id: string;
|
|
9112
|
+
name?: string;
|
|
9113
|
+
status: "skipped";
|
|
9114
|
+
reason: ContinueInterruptedSkipReason;
|
|
9115
|
+
} | {
|
|
9116
|
+
id: string;
|
|
9117
|
+
name?: string;
|
|
9118
|
+
status: "failed";
|
|
9119
|
+
error: string;
|
|
9120
|
+
};
|
|
9121
|
+
interface ContinueInterruptedResult {
|
|
9122
|
+
dryRun: boolean;
|
|
9123
|
+
/** The prompt that was (or, on a dry run, would be) sent. */
|
|
9124
|
+
prompt: string;
|
|
9125
|
+
/** The boot the candidates were interrupted before (`registry.bootId`). */
|
|
9126
|
+
bootId: string;
|
|
9127
|
+
/** One entry per considered row — every interrupted row when `ids` is
|
|
9128
|
+
* omitted, every requested id otherwise. Eligible-first ordering matches
|
|
9129
|
+
* the send order (newest activity first). */
|
|
9130
|
+
sessions: ContinueInterruptedOutcome[];
|
|
9131
|
+
/** Counts by outcome status. */
|
|
9132
|
+
eligible: number;
|
|
9133
|
+
sent: number;
|
|
9134
|
+
skipped: number;
|
|
9135
|
+
failed: number;
|
|
9136
|
+
}
|
|
9137
|
+
type ContinueInterruptedMode = "manual" | "boot";
|
|
9138
|
+
/** Decide one row. `undefined` ⇒ eligible. Pure — reads the descriptor only. */
|
|
9139
|
+
declare function continueSkipReason(desc: SessionDescriptor, bootId: string, mode: ContinueInterruptedMode): ContinueInterruptedSkipReason | undefined;
|
|
9140
|
+
/**
|
|
9141
|
+
* List — and unless `dryRun` — continue the sessions interrupted by the last
|
|
9142
|
+
* restart. See the module docblock for eligibility, the no-loop rules, and the
|
|
9143
|
+
* ordering contract. No-throw per row: a send that fails admission (row went
|
|
9144
|
+
* busy, resume refused) is reported as `failed` and the pass carries on.
|
|
9145
|
+
*/
|
|
9146
|
+
declare function continueInterruptedSessions(opts: {
|
|
9147
|
+
registry: Pick<SessionsRegistry, "list" | "get" | "enqueuePrompt" | "bootId" | "recordAutoContinue">;
|
|
9148
|
+
mode: ContinueInterruptedMode;
|
|
9149
|
+
/** Default true: report what would be sent, send nothing. */
|
|
9150
|
+
dryRun?: boolean;
|
|
9151
|
+
/** Restrict to these session ids. Omitted ⇒ every interrupted row. */
|
|
9152
|
+
ids?: readonly string[];
|
|
9153
|
+
/** Custom prompt. Omitted/blank ⇒ `DEFAULT_CONTINUE_PROMPT`. */
|
|
9154
|
+
prompt?: string;
|
|
9155
|
+
/** Max sends in flight at once (each may lazily resume an adapter). Clamped
|
|
9156
|
+
* to ≥1. Default 4, same as the eager pass. */
|
|
9157
|
+
concurrency?: number;
|
|
9158
|
+
/** Cross-process gate — see `runEagerResumePass`. Omitted ⇒ all served. */
|
|
9159
|
+
isServed?: (desc: SessionDescriptor) => boolean;
|
|
9160
|
+
/** Extra visibility filter (a scoped orchestrator's subtree). Rows it
|
|
9161
|
+
* rejects are dropped silently — never reported, never sent. */
|
|
9162
|
+
visible?: (desc: SessionDescriptor) => boolean;
|
|
9163
|
+
}): Promise<ContinueInterruptedResult>;
|
|
9164
|
+
/** Tally of the boot-time continue pass, for the boot-banner line. */
|
|
9165
|
+
interface ContinueOnBootSummary {
|
|
9166
|
+
/** False when `daemon.continueInterruptedOnBoot` is off (nothing ran). */
|
|
9167
|
+
enabled: boolean;
|
|
9168
|
+
/** Rows passing eligibility at selection time — the banner's denominator. */
|
|
9169
|
+
eligible: number;
|
|
9170
|
+
sent: number;
|
|
9171
|
+
skipped: number;
|
|
9172
|
+
failed: number;
|
|
9173
|
+
}
|
|
9174
|
+
/**
|
|
9175
|
+
* The boot pass: `continueInterruptedSessions` in `mode: "boot"`, not a dry
|
|
9176
|
+
* run, reduced to the banner tally. Caller (the gateway handle, invoked from
|
|
9177
|
+
* serve.ts) is responsible for the ordering contract in the module docblock.
|
|
9178
|
+
*/
|
|
9179
|
+
declare function runContinueOnBootPass(opts: {
|
|
9180
|
+
registry: Parameters<typeof continueInterruptedSessions>[0]["registry"];
|
|
9181
|
+
concurrency: number;
|
|
9182
|
+
isServed?: (desc: SessionDescriptor) => boolean;
|
|
9183
|
+
}): Promise<ContinueOnBootSummary>;
|
|
9184
|
+
|
|
8609
9185
|
/**
|
|
8610
9186
|
* Daemon-lane PR provenance STAMPER.
|
|
8611
9187
|
*
|
|
@@ -8820,8 +9396,16 @@ interface InboundWatcher {
|
|
|
8820
9396
|
*
|
|
8821
9397
|
* `mcpServerFactory` (index.ts) rebuilds a fresh McpServer per `/mcp`
|
|
8822
9398
|
* request, so this module never throws — a bad app record must not take
|
|
8823
|
-
* down every other request.
|
|
8824
|
-
* `
|
|
9399
|
+
* down every other request. A collided tool id is still skipped with a
|
|
9400
|
+
* `console.warn` (there's nowhere else for a second panel to live). Every
|
|
9401
|
+
* OTHER failure — a removed app dir, a missing/unreadable `ui.path`, a
|
|
9402
|
+
* failed or in-flight `ui.build` — still mounts the panel, serving a
|
|
9403
|
+
* readable HTML placeholder/error page in place of the real bundle
|
|
9404
|
+
* (app-ui-placeholder.ts) instead of skipping it outright: a `ui://`
|
|
9405
|
+
* resource that silently doesn't exist just shows as a JSON-RPC "resource
|
|
9406
|
+
* not found" in a host, which is what motivated this file's placeholder
|
|
9407
|
+
* page in the first place — a HOST-VISIBLE page, even a stand-in one, beats
|
|
9408
|
+
* a resource the host has to explain away as missing.
|
|
8825
9409
|
*/
|
|
8826
9410
|
|
|
8827
9411
|
/**
|
|
@@ -10295,6 +10879,108 @@ declare function formatToolCall(toolName: string, args: unknown): string;
|
|
|
10295
10879
|
*/
|
|
10296
10880
|
declare function formatToolResult(toolName: string | undefined, result: unknown, isError: boolean): string | null;
|
|
10297
10881
|
|
|
10882
|
+
/**
|
|
10883
|
+
* Pure sizing helper for a `tools/list` response — shared by
|
|
10884
|
+
* `scripts/measure-mcp-tools.mjs` (human-readable before/after report) and
|
|
10885
|
+
* the budget-guard test (`__tests__/tool-schema-budget.test.ts`) so both
|
|
10886
|
+
* measure the exact same thing: the JSON bytes an MCP client actually pays
|
|
10887
|
+
* for per tool (`description` + `inputSchema`), sorted biggest first.
|
|
10888
|
+
*/
|
|
10889
|
+
interface MeasuredToolEntry {
|
|
10890
|
+
name: string;
|
|
10891
|
+
bytes: number;
|
|
10892
|
+
}
|
|
10893
|
+
interface ToolListMeasurement {
|
|
10894
|
+
entries: MeasuredToolEntry[];
|
|
10895
|
+
totalBytes: number;
|
|
10896
|
+
}
|
|
10897
|
+
interface MeasurableTool {
|
|
10898
|
+
name: string;
|
|
10899
|
+
description?: string;
|
|
10900
|
+
inputSchema?: unknown;
|
|
10901
|
+
}
|
|
10902
|
+
/** UTF-8 byte size of the `{description, inputSchema}` JSON a client
|
|
10903
|
+
* receives for one tool — the same two fields `tools/list` sends over the
|
|
10904
|
+
* wire, so this tracks prompt-token cost rather than just character count. */
|
|
10905
|
+
declare function measureTool(tool: MeasurableTool): number;
|
|
10906
|
+
declare function measureToolList(tools: readonly MeasurableTool[]): ToolListMeasurement;
|
|
10907
|
+
|
|
10908
|
+
/**
|
|
10909
|
+
* Long-form MCP tool documentation, read from `docs/mcp-tools/<name>.md`.
|
|
10910
|
+
*
|
|
10911
|
+
* The schema `description` on a tool/field is a contract: what it does, and
|
|
10912
|
+
* the one rule that prevents a wrong call — kept short so `tools/list` stays
|
|
10913
|
+
* cheap. Everything else (edge cases, interactions with other fields,
|
|
10914
|
+
* examples, history) lives here instead, fetched on demand by the `tool_help`
|
|
10915
|
+
* MCP tool (`tool-help-mcp.ts`) and the `agentproto help <tool>` CLI verb
|
|
10916
|
+
* (`packages/cli/src/commands/help.ts`) — both call the two functions below,
|
|
10917
|
+
* so the markdown file is the single source both surfaces read.
|
|
10918
|
+
*
|
|
10919
|
+
* `docs/mcp-tools/` sits at the PACKAGE root (a sibling of `src`/`dist`, not
|
|
10920
|
+
* the repo-level `docs/`) so it ships inside the published npm tarball —
|
|
10921
|
+
* see the `files` array in `package.json`. Resolved relative to this
|
|
10922
|
+
* module's own directory rather than by package name: whether this code is
|
|
10923
|
+
* running from `src` (vitest, no build) or `dist` (built/published), the
|
|
10924
|
+
* module's directory is always a direct child of the package root, so one
|
|
10925
|
+
* `..` reaches it either way — no `require.resolve` needed.
|
|
10926
|
+
*/
|
|
10927
|
+
/** Full markdown help text for `name`, or `undefined` when no doc exists. */
|
|
10928
|
+
declare function getToolHelp(name: string): string | undefined;
|
|
10929
|
+
/** Every tool name with a help doc available — for a "did you mean" list. */
|
|
10930
|
+
declare function listToolHelpTopics(): string[];
|
|
10931
|
+
/** Extract a `## <topic>` section (case-insensitive) up to the next `##`
|
|
10932
|
+
* heading — shared by the `tool_help` MCP tool and the `agentproto help`
|
|
10933
|
+
* CLI verb so both slice a doc identically. `undefined` when no section
|
|
10934
|
+
* with that heading exists. */
|
|
10935
|
+
declare function extractHelpSection(doc: string, topic: string): string | undefined;
|
|
10936
|
+
|
|
10937
|
+
/**
|
|
10938
|
+
* Subtree usage rollup: one session's own usage plus the summed usage of
|
|
10939
|
+
* every session it (transitively) spawned — the shape `session_usage
|
|
10940
|
+
* { includeSubtree: true }` and `GET /sessions/:id/usage?includeSubtree=1`
|
|
10941
|
+
* return.
|
|
10942
|
+
*
|
|
10943
|
+
* Pure over a descriptor list (walked by `parentSessionId`, the same graph
|
|
10944
|
+
* `collectSubtree` uses for orchestrator scoping), so it's unit-testable
|
|
10945
|
+
* without a registry.
|
|
10946
|
+
*
|
|
10947
|
+
* Absent stays absent: a total is the sum of the sessions that REPORT the
|
|
10948
|
+
* field, and is omitted entirely when none of them do — a subtree of
|
|
10949
|
+
* cost-less sessions never reads as a measured $0.
|
|
10950
|
+
*/
|
|
10951
|
+
|
|
10952
|
+
/** Summed usage across the root and all its descendants. */
|
|
10953
|
+
interface SubtreeUsageTotals {
|
|
10954
|
+
/** Sessions counted, root included. */
|
|
10955
|
+
sessions: number;
|
|
10956
|
+
costUsd?: number;
|
|
10957
|
+
tokensIn?: number;
|
|
10958
|
+
tokensOut?: number;
|
|
10959
|
+
cacheReadTokens?: number;
|
|
10960
|
+
cacheWriteTokens?: number;
|
|
10961
|
+
}
|
|
10962
|
+
/** One direct child of the root, with that child's OWN usage (its own
|
|
10963
|
+
* descendants roll up into `subtree`, not here). */
|
|
10964
|
+
interface SubtreeChildUsage {
|
|
10965
|
+
id: string;
|
|
10966
|
+
label?: string;
|
|
10967
|
+
status: SessionDescriptor["status"];
|
|
10968
|
+
costUsd?: number;
|
|
10969
|
+
tokensIn?: number;
|
|
10970
|
+
tokensOut?: number;
|
|
10971
|
+
}
|
|
10972
|
+
interface SessionUsageWithSubtree {
|
|
10973
|
+
self: SessionUsage;
|
|
10974
|
+
subtree: SubtreeUsageTotals;
|
|
10975
|
+
children: SubtreeChildUsage[];
|
|
10976
|
+
}
|
|
10977
|
+
/**
|
|
10978
|
+
* Roll `root`'s usage up over its subtree. `all` should be the FULL
|
|
10979
|
+
* descriptor list (archived included) so an archived intermediate session
|
|
10980
|
+
* doesn't sever the parent→child chain.
|
|
10981
|
+
*/
|
|
10982
|
+
declare function rollupSessionSubtree(root: SessionDescriptor, all: readonly SessionDescriptor[]): SessionUsageWithSubtree;
|
|
10983
|
+
|
|
10298
10984
|
/**
|
|
10299
10985
|
* Dependency-injection surface for MCP credential resolution.
|
|
10300
10986
|
*
|
|
@@ -10399,6 +11085,26 @@ declare function enrichRollupWithProviderQuota(rollup: UsageRollup, window: stri
|
|
|
10399
11085
|
* such lines; skips any malformed or non-`usage_snapshot` line. Never throws. */
|
|
10400
11086
|
declare function readUsageSnapshots(sessionId: string, baseDir?: string): Promise<UsageSnapshotRecord[]>;
|
|
10401
11087
|
|
|
11088
|
+
/**
|
|
11089
|
+
* Smart default for `features.llmEndpoint` (daemon-managed-gateway): an
|
|
11090
|
+
* operator who already configured a named endpoint, an upstream credential
|
|
11091
|
+
* link, or an explicit `llm-endpoint` custom route is clearly USING the
|
|
11092
|
+
* proxy already — booting with the sidecar off (today's default) would
|
|
11093
|
+
* silently break their next `route:{gateway:"llm-endpoint"}` spawn on a
|
|
11094
|
+
* fresh install. An operator who never touched any of that gets the
|
|
11095
|
+
* unchanged, conservative default (off).
|
|
11096
|
+
*
|
|
11097
|
+
* An explicit `configured` value (`config.json`'s `features.llmEndpoint`,
|
|
11098
|
+
* profile-overlaid) always wins, in either direction — this resolver only
|
|
11099
|
+
* fills in the gap when the operator left the flag unset.
|
|
11100
|
+
*/
|
|
11101
|
+
/**
|
|
11102
|
+
* Resolve the EFFECTIVE `features.llmEndpoint` flag. `configured` is the
|
|
11103
|
+
* operator's merged config value (`undefined` when never set in either
|
|
11104
|
+
* `config.json` or the active profile).
|
|
11105
|
+
*/
|
|
11106
|
+
declare function resolveEffectiveLlmEndpointFlag(configured: boolean | undefined): Promise<boolean>;
|
|
11107
|
+
|
|
10402
11108
|
/**
|
|
10403
11109
|
* MCP tools that drive the pairing registry — the daemon's "let a client pair
|
|
10404
11110
|
* with me over an untrusted rendezvous" surface (design: DESIGN §6).
|
|
@@ -10420,6 +11126,90 @@ interface RegisterPairingToolsOptions {
|
|
|
10420
11126
|
}
|
|
10421
11127
|
declare function registerPairingTools(server: McpServer, opts: RegisterPairingToolsOptions): void;
|
|
10422
11128
|
|
|
11129
|
+
/**
|
|
11130
|
+
* Device registry — a read view over `PairingRegistry` (+, when wired,
|
|
11131
|
+
* `HostRegistry`) that presents each pairing/host as a "device" (DEVICES-PLAN
|
|
11132
|
+
* PR-A, hosts added PR-C). A paired CLIENT (today's `pair_offer`/`pair
|
|
11133
|
+
* accept`) gets `role: "client"`; a registered HOST (`pair offer --host` +
|
|
11134
|
+
* `devices add`, host-registry.ts) gets `role: "host"`.
|
|
11135
|
+
*
|
|
11136
|
+
* This is deliberately a thin computed view, not a second store: renaming
|
|
11137
|
+
* and revoking a client device mutate the same `pairings.json`
|
|
11138
|
+
* `PairingRegistry` already owns; a host device mutates the same
|
|
11139
|
+
* `hosts.json` `HostRegistry` — so `pair_*`/`/pairings` and
|
|
11140
|
+
* `device_*`/`/devices` are two surfaces over the same two sources of truth.
|
|
11141
|
+
*/
|
|
11142
|
+
|
|
11143
|
+
type DeviceRole = "client" | "host";
|
|
11144
|
+
type DeviceKind = "browser" | "cli" | "daemon";
|
|
11145
|
+
interface Device {
|
|
11146
|
+
fingerprint: string;
|
|
11147
|
+
name: string;
|
|
11148
|
+
role: DeviceRole;
|
|
11149
|
+
kind: DeviceKind;
|
|
11150
|
+
rendezvous: string;
|
|
11151
|
+
createdAt: string;
|
|
11152
|
+
lastSeen: string;
|
|
11153
|
+
/** A channel (offer or reconnect) is served for this device right now
|
|
11154
|
+
* (client) or a `forwardHttp` call is in flight for it right now (host).
|
|
11155
|
+
* For a host this is NOT a live heartbeat — see host-registry.ts's
|
|
11156
|
+
* "Online tracking" — it only reflects actual recent/current traffic. */
|
|
11157
|
+
online: boolean;
|
|
11158
|
+
/** A pair/v1 pairing: listed and revocable, but can't connect until
|
|
11159
|
+
* re-paired — see `PairingRecord.legacy`. */
|
|
11160
|
+
legacy?: true;
|
|
11161
|
+
/** Set when this device's pairing/host record was granted under a
|
|
11162
|
+
* HOST-scoped offer (`agentproto pair offer --host`) — see
|
|
11163
|
+
* offer-url.ts's "Offer scope". Surfaced from either side of a pairing so
|
|
11164
|
+
* a user can see, from EITHER daemon, which of their pairings/hosts grant
|
|
11165
|
+
* host control. */
|
|
11166
|
+
scope?: "host";
|
|
11167
|
+
}
|
|
11168
|
+
interface DeviceRegistry {
|
|
11169
|
+
/** Every known device. Read-only. */
|
|
11170
|
+
list(): Promise<Device[]>;
|
|
11171
|
+
/** Rename a device (fingerprint or current name) to a new label. Tries the
|
|
11172
|
+
* pairing registry first, then the host registry. Returns false when
|
|
11173
|
+
* nothing matched. */
|
|
11174
|
+
rename(idOrName: string, newName: string): Promise<boolean>;
|
|
11175
|
+
/** Drop a device by fingerprint or name — same effect as `pair revoke` for
|
|
11176
|
+
* a client device, `devices revoke`-of-a-host for a host device. Tries
|
|
11177
|
+
* the pairing registry first, then the host registry. Returns false when
|
|
11178
|
+
* nothing matched. */
|
|
11179
|
+
revoke(idOrName: string): Promise<boolean>;
|
|
11180
|
+
/** Register a host from an offer URL (delegates to `HostRegistry.add`).
|
|
11181
|
+
* Rejects if no `HostRegistry` was wired into this device registry. */
|
|
11182
|
+
add(offerUrl: string, name?: string): Promise<{
|
|
11183
|
+
fingerprint: string;
|
|
11184
|
+
name: string;
|
|
11185
|
+
rendezvousUrl: string;
|
|
11186
|
+
}>;
|
|
11187
|
+
}
|
|
11188
|
+
declare function createDeviceRegistry(pairing: PairingRegistry, hosts?: HostRegistry): DeviceRegistry;
|
|
11189
|
+
|
|
11190
|
+
/**
|
|
11191
|
+
* MCP tools over the device registry (DEVICES-PLAN PR-A/PR-C) — `device_list`
|
|
11192
|
+
* / `device_rename` / `device_revoke` / `device_add`. A view on top of the
|
|
11193
|
+
* same registries `pair_offer`/`pair_list`/`pair_revoke` (pairing-tools.ts)
|
|
11194
|
+
* and host-registry.ts drive; those keep working unchanged. `device_revoke`
|
|
11195
|
+
* has the exact effect of `pair_revoke` for a client device.
|
|
11196
|
+
*
|
|
11197
|
+
* `device_add` (PR-C) registers a HOST from a `--host`-scoped offer URL —
|
|
11198
|
+
* see `HostRegistry.add`'s scope gate (host-registry.ts). It requires the
|
|
11199
|
+
* gateway to have wired a `HostRegistry` into the `DeviceRegistry`; without
|
|
11200
|
+
* one the call rejects with a clear message rather than a missing-tool error
|
|
11201
|
+
* (this repo always wires one when `pairingRegistry` is wired, so that's
|
|
11202
|
+
* only reachable via a deliberate host misconfiguration).
|
|
11203
|
+
*
|
|
11204
|
+
* Registered beside `pair_*` — same closure-rebind pattern; the registry
|
|
11205
|
+
* singleton lives on the gateway.
|
|
11206
|
+
*/
|
|
11207
|
+
|
|
11208
|
+
interface RegisterDeviceToolsOptions {
|
|
11209
|
+
registry: DeviceRegistry;
|
|
11210
|
+
}
|
|
11211
|
+
declare function registerDeviceTools(server: McpServer, opts: RegisterDeviceToolsOptions): void;
|
|
11212
|
+
|
|
10423
11213
|
/**
|
|
10424
11214
|
* Rate-limited failure logging for reconnect loops.
|
|
10425
11215
|
*
|
|
@@ -11257,6 +12047,15 @@ interface SessionWaitResult {
|
|
|
11257
12047
|
* reported one. `"error"` means the adapter reported a failed turn.
|
|
11258
12048
|
* Same three-branch coverage as `empty`. */
|
|
11259
12049
|
reason?: string;
|
|
12050
|
+
/** The matched turn-end's captured error text — `SessionTurnEndEvent.error`
|
|
12051
|
+
* on the ring-replay/bus branches, `SessionDescriptor.lastTurnErrorMessage`
|
|
12052
|
+
* on the sync fast-path (no event object to read there). Present only
|
|
12053
|
+
* when `reason` is `"error"` AND the adapter emitted an in-band `error`
|
|
12054
|
+
* stream event during the turn. Same three-branch coverage as `empty`/
|
|
12055
|
+
* `reason` — this is the field a waiter (a supervisor session, `sessions
|
|
12056
|
+
* wait`, a webhook) needed to actually learn WHY a turn errored instead
|
|
12057
|
+
* of just that it did. */
|
|
12058
|
+
error?: string;
|
|
11260
12059
|
}
|
|
11261
12060
|
/**
|
|
11262
12061
|
* Block until one of the listed sessions fires a matching lifecycle event
|
|
@@ -11406,6 +12205,12 @@ interface CreateGatewayOptions {
|
|
|
11406
12205
|
* to an `enabled: false` summary. Also surfaced in `daemon_health` /
|
|
11407
12206
|
* `GET /health` so an operator can see the effective value. */
|
|
11408
12207
|
resumeSessionsOnBoot?: boolean;
|
|
12208
|
+
/** Opt-in continue-on-boot. Mirrors the `daemon.continueInterruptedOnBoot`
|
|
12209
|
+
* config knob; when true, the `continueInterruptedOnBoot()` handle method
|
|
12210
|
+
* runs the boot continue pass (see `continue-interrupted.ts`); when
|
|
12211
|
+
* false/omitted it short-circuits to an `enabled: false` summary. Surfaced
|
|
12212
|
+
* in `daemon_health` / `GET /health`. */
|
|
12213
|
+
continueInterruptedOnBoot?: boolean;
|
|
11409
12214
|
/** Idle agent-session reaper threshold in ms (PR-6). Mirrors the
|
|
11410
12215
|
* `daemon.idleReapAfterMs` config knob; the CLI resolves it (env >
|
|
11411
12216
|
* config > off) and passes it here. When positive, the gateway starts a
|
|
@@ -11659,6 +12464,17 @@ interface CreateGatewayOptions {
|
|
|
11659
12464
|
* returns) so the injected `serve` can capture the finished gateway.
|
|
11660
12465
|
*/
|
|
11661
12466
|
pairingRegistry?: PairingRegistry;
|
|
12467
|
+
/**
|
|
12468
|
+
* Optional HOST registry (see `createHostRegistry`, DEVICES-PLAN PR-C) —
|
|
12469
|
+
* the reverse-pairing "client" half of pair/v2, living daemon-side. When
|
|
12470
|
+
* wired alongside `pairingRegistry`, the gateway layers registered hosts
|
|
12471
|
+
* into `device_list`/`GET /devices`, and enables the `device_add` MCP tool
|
|
12472
|
+
* plus `POST /devices/add` + `POST /devices/:id/exec`. Unlike
|
|
12473
|
+
* `pairingRegistry`, this registry keeps no standing connections — every
|
|
12474
|
+
* `add`/`forwardHttp` dials fresh — so there is nothing for the gateway to
|
|
12475
|
+
* autoconnect or tear down on shutdown.
|
|
12476
|
+
*/
|
|
12477
|
+
hostRegistry?: HostRegistry;
|
|
11662
12478
|
/** Enable the local LLM Endpoint proxy sidecar (route registration,
|
|
11663
12479
|
* MCP tools, child-process lifecycle). Default false — the endpoint is
|
|
11664
12480
|
* an opt-in feature; when off, the `llm-endpoint` custom route is not
|
|
@@ -11700,6 +12516,10 @@ interface GatewayHandle {
|
|
|
11700
12516
|
* `CreateGatewayOptions.pairingRegistry`. Undefined otherwise. Exposed so
|
|
11701
12517
|
* the CLI can `startAutoconnect()` after boot and `shutdown()` it. */
|
|
11702
12518
|
pairing?: PairingRegistry;
|
|
12519
|
+
/** HOST registry, when one was wired via `CreateGatewayOptions.hostRegistry`
|
|
12520
|
+
* (DEVICES-PLAN PR-C). Undefined otherwise. No autoconnect/shutdown to
|
|
12521
|
+
* call on it — see that option's doc comment. */
|
|
12522
|
+
hosts?: HostRegistry;
|
|
11703
12523
|
/** Per-boot bearer token required on mutating /sessions/* routes
|
|
11704
12524
|
* + WS PTY upgrades. Exposed so an embedding host (e.g. the CLI
|
|
11705
12525
|
* shell that hosts the gateway in-process) can pass it to child
|
|
@@ -11724,6 +12544,16 @@ interface GatewayHandle {
|
|
|
11724
12544
|
resumeSessionsOnBoot(opts?: {
|
|
11725
12545
|
isServed?: (desc: SessionDescriptor) => boolean;
|
|
11726
12546
|
}): Promise<EagerResumeSummary>;
|
|
12547
|
+
/** Run the opt-in continue-on-boot pass and return its tally — a no-op
|
|
12548
|
+
* returning `{ enabled: false, ... }` when the `continueInterruptedOnBoot`
|
|
12549
|
+
* knob is off. serve.ts invokes this right AFTER `resumeSessionsOnBoot()`
|
|
12550
|
+
* (so a row whose eager resume failed is recognisable and skipped) — and
|
|
12551
|
+
* therefore, like it, after the supervisor was re-armed, so a re-armed
|
|
12552
|
+
* completion policy sees the continue turn's turn-end. Same `isServed`
|
|
12553
|
+
* cross-process gate. */
|
|
12554
|
+
continueInterruptedOnBoot(opts?: {
|
|
12555
|
+
isServed?: (desc: SessionDescriptor) => boolean;
|
|
12556
|
+
}): Promise<ContinueOnBootSummary>;
|
|
11727
12557
|
stop(): Promise<void>;
|
|
11728
12558
|
}
|
|
11729
12559
|
/**
|
|
@@ -11740,4 +12570,4 @@ interface GatewayHandle {
|
|
|
11740
12570
|
*/
|
|
11741
12571
|
declare function createGateway(opts: CreateGatewayOptions): Promise<GatewayHandle>;
|
|
11742
12572
|
|
|
11743
|
-
export { type ActivityKind, type ActivityListFilter, type ActivityPolicyLister, type ActivityProjector, type ActivityProjectorRegistry, type ActivityProjectorSession, type ActivityRecord, type ActivitySource, type ActivityState, type ActivityWaitingOn, type ActivityWorkflowLister, AdapterAuthDescriptor, type AdapterCapabilitiesLister, type AdapterInstallResult, type AdapterListEntry, type AgentAdapterInstaller, type AgentAdapterLister, type AgentAdapterResolver, type AgentSessionLike, type AgentStreamEvent, type AnthropicReaderConfig, AnthropicRemainingQuotaReader, type AttachPolicyInput, type AttachSandboxOpts, type AttachSandboxResult, AuthMethod, BUCKETS_ROOT, type BranchGcClass, type BranchGcCoverageView, type BranchGcHoldReason, type BranchGcKind, type BranchGcOutcomeView, type BranchGcPlanEntryView, type BranchGcPlanView, type BranchGcReclaimReason, type BranchGcResult, type BranchGcRunInput, type BranchGcRunner, type BranchGcStatus, type BranchGcSummaryView, type BranchGcTriageVerdict, type BranchGcVerdictInput, type BranchGcVerdictLookupInput, type BranchGcVerdictReader, type BranchGcVerdictRecordView, type BranchGcVerdictRecorder, type BrowserAdapterHandle, type BrowserAdapterInfo, type BrowserAdapterLister, type BrowserAdapterResolver, BuildHeartbeatAgent, CanonicalPosture, type CatalogModelsLister, CatalogModelsQuery, CatalogModelsResponse, type CatalogProviderModel, type CatalogProviderModelsQuery, type CatalogProviderModelsResponse, type CatalogProviderPricing, type ClaudeNativeRef, type CommitSpec, type CompletionPolicySupervisor, ContextProfile, type ConversationIndexRecord, type ConversationNativeRef, type CostBudgetDecision, type CrashDetectSummary, type CrashReaperRegistry, type CreateGatewayOptions, type CreateOfferInput, type CreateReviewRunnerOptions, type CreatedOffer, DEAD_SESSION_STATUSES, DEFAULT_ALWAYS_ON_TOOLS, DEFAULT_BUCKET, DEFAULT_ORCHESTRATOR_TOOLS, DEFAULT_WORKTREE_ISOLATION, type DaemonReviewerHostDeps, DeclaredAdapterOption, type DeclaredAdapterPreset, DefaultsAdapterAuthConfig, type EagerResumeFailReason, type EagerResumeOutcome, type EagerResumeSkipReason, type EagerResumeSummary, EffortLevel, type EnableInput, type EnableResult, GC_REAPABLE_STATES, type GateSpec, type GatewayHandle, type GhRunner, type HarnessPreset, type HarnessPresetValidationDeps, HarnessPresetValidationError, type HarnessPresetsFile, type HermesNativeRef, INBOUND_PROVIDERS, type IdleReapSummary, type IdleReaperRegistry, type InboundEndpoint, type InboundEndpointStore, type InboundEndpointStoreOptions, type InboundEnqueuePrompt, type InboundIsSessionAlive, type InboundMessage, type InboundProvider, type InboundRestartSession, type InboundRouteMode, type InboundRouterDeps, type InboundRouterLog, type InboundSpawnForContact, type InboundWatcher, type JudgeGateSpec, LEGACY_SESSIONS_FILE, type LedgerAnnotations, type LedgerEntry, type LedgerHostMeta, type LocatedConversation, type LocatedConversationByPath, MAX_MESSAGE_DATA_BYTES, MCP_APP_BRIDGE_SCRIPT, MESSAGE_KINDS, MESSAGE_PREAMBLE, MESSAGE_TAG, MESSAGE_URGENCIES, type McpCredentialDeps, type MessageDeliveryVia, type MessageFilter, type MessageKind, type MessageRelation, type MessageTreeNode, type MessageUrgency, type MigrationMarker, type NormalizeInboundResult, type OnFailSpec, type OpenPrResolver, type OrchestratorGatewayDeps, type OrchestratorInjection, type OrchestratorInjector, type OrchestratorInjectorDeps, type OrchestratorMcpServerFactory, type OrchestratorScope, type OrphanReaperRegistry, PAIRINGS_VERSION, POSTURE_NATIVE_ALIASES, POSTURE_PREAMBLES, type PairingChannelContext, type PairingChannelHandle, type PairingChannelMode, type PairingRecord, type PairingRegistry, type PairingRegistryDeps, type PendingPermission, type PermissionRespondInput, type PermissionRespondResult, type PolicyRunState, type PolicyRunStatus, Posture, type PostureResolution, PrLookupError, type PrLookupErrorCode, type PrResolvedState, type PrStateResolver, type PrStatusSnapshot, type PresetInfo, type PricingResolver, type QuotaReadableProfile, type QuotaStoreFile, type QuotaStoreOptions, type ReconnectLogGate, type RegisterBrainToolsOptions, type RegisterBrowserInput, type RegisterPairingToolsOptions, type RegisterReviewToolsOptions, type RegisterSessionInput, type RegisterWebSearchToolsOptions, type RemainingQuota, type RemainingQuotaReader, type RemoteStatus, type ResolveNativeLinkInput, ResolvedAuthSpec, ResumeDisabledError, type ReuseResolution, type ReviewLedger, type ReviewLedgerFilter, type ReviewRun, type ReviewRunInput, type ReviewRunStatus, type ReviewRunner, type ReviewerRunResult, type ReviewerSessionHost, type RouteAwareLaunchConfig, type RouteAwareLaunchConfigInput, RouteSpec, type RuntimeMeta, SESSION_END_REASONS, SESSION_ID_ENV, type SandboxAdapterInfo, type SandboxConnectionDescriptor, type SandboxGcCandidate, type SandboxGcProviderHandle, type SandboxGcReapDeps, type SandboxGcReapResult, type SandboxLedgerEntry, type SandboxLedgerState, type SandboxProviderCapabilities, type SandboxProviderHandle, type SandboxProviderLister, type SandboxProviderResolver, type SandboxReconcileDeps, type SandboxReconcileProviderHandle, type SandboxReconcileResult, type SandboxReconcileRow, type SandboxReconcileVerdict, type ScopeTokenRegistry, SessionConfig, type SessionCurrentPhase, type SessionDescriptor, type SessionEndReason, type SessionKind, type SessionMessage, type SessionMessageFrom, type SessionMessageSentRecord, type SessionObserver, type SessionOutcome, type SessionOutcomeArtifact, type SessionOutcomeCompact, type SessionOutcomeLink, type SessionSnapshots, type SessionStatus, type SessionUsage, type SessionWaitEvent, type SessionWaitResult, type SessionsRegistry, type ShellGateSpec, type SpawnAgentInput, SpawnDefaultsConfig, type SpawnSessionInput, type StallWatchdogRegistry, type StallWatchdogSummary, type StoredProfileQuota, TASK_STATUSES, type TaskCaller, type TaskChangedEvent, type TaskClaimInput, type TaskCreateInput, type TaskGateOutcome, type TaskGateRunner, type TaskLedger, type TaskLedgerRegistry, type TaskLedgerSessionSlice, type TaskListFilter, type TaskRecord, type TaskStatus, type TaskUpdateInput, type TaskVerification, type TaskVerifySupervisor, type TaskWriteResult, type TokenPricing, type TransmitterBinding, type TransmitterBindingStore, type TunnelDescriptor, type TunnelProvider, type TunnelStatus, type UsageBucket, type UsageComputeInput, type UsageRollup, type UsageSnapshotRecord, type UsageSource, UserPreset, WORKSPACE_SLUG_ENV, WORKTREE_ISOLATION_ENV, type WatcherDescriptor, type WatcherStartInput, type WebSearchInput, type WebSearchOutput, type WebSearchResult, type WorkspaceBrainSubscriber, type WorkspaceBrainSubscriberOptions, type WorkspaceBrains, WorkspaceFs, type WorktreeAutoReclaimer, type WorktreeDecision, type WorktreeField, type WorktreeGcClass, type WorktreeGcOutcomeView, type WorktreeGcPlanEntryView, type WorktreeGcReclaimReason, type WorktreeGcResult, type WorktreeGcRunInput, type WorktreeGcRunner, WorktreeIsolationMode, type WorktreeProvisionOutcome, type WorktreeProvisionRequest, type WorktreeProvisioner, type WorktreeRequest, type WorktreeStatusLister, type WorktreeStatusView, activityCounts, addHarnessPreset, appendConversationRecord, attachSandbox, bucketDir, bucketSessionsFile, bucketTranscriptDir, buildCatalogProviderModels, buildMcpConfigSnippet, buildRouteAwareLaunchConfig, canonicalForModeId, claudeProjectSlug, collectGcCandidates, compactOutcome, composeSessionObservers, conversationIndexPath, createActivityProjector, createDaemonReviewerHost, createFileStepCache, createGateway, createInboundEndpointStore, createOrchestratorInjector, createOrchestratorMcpServerFactory, createPairingRegistry, createPrProvenanceReconciler, createReconnectLogGate, createReviewLaneExecutor, createReviewLedger, createReviewRunner, createScopeTokenRegistry, createSessionMessage, createSupervisorTaskGateRunner, createTaskLedger, createWorkspaceBrainSubscriber, createWorkspaceBrains, daemonRegistryDir, decideWorktreeIsolation, declaredPresetToProviderPreset, defaultReviewLedgerRoot, defineBraveSearchHttpDriver, defineSerperHttpDriver, deriveSessionOutcome, deriveSessionUsage, enrichRollupWithProviderQuota, enrichWithRemainingQuota, escapeHumanPrompt, escapeMessageBody, evaluateCostBudget, execGh, fetchPrStatus, filterActivities, findConversationRecord, findNativeMode, findPrForCommit, formatToolCall, formatToolResult, getDefaultHarnessPreset, getHarnessPreset, getMcpCredentialDeps, githubRepoOf, harnessPresetsPath, hostPlaceholders, injectMcpAppBridge, isAgentCliAuthConfigured, isClosedTaskStatus, isKnownSessionEndReason, isMessageAllowed, isProviderLimitError, isSafeBucketSlug, isTerminalActivityState, listBuckets, listHarnessPresets, listPresets, loadHarnessPresets, loadQuotaStore, loadWorktreeIsolation, locateConversationByNativePath, locateConversationBySessionId, makeBrowserAdapterLister, makeSandboxCredsStore, makeSandboxResolver, matchesMessageFilter, messageFrom, migrateLegacySessionsFile, migrationMarkerPath, mintMessageId, monitorPolicyWait, monitorSessionWait, narrowOrchestratorTools, normalizeInbound, normalizeModeId, normalizeRemote, normalizeWorktreeField, parseAnthropicRateLimitHeaders, parsePrUrl, parseTaskStatus, parseWindow, parseWorktreeIsolationMode, policyToActivities, policyWatchesSession, prHeadSha, prToActivities, projectSessionUsage, readConversationIndex, readDaemonRegistry, readProfileQuota, readRegisteredSlugs, readRuntimeMeta, readSandboxLedger, readSessionForBrain, readUsageSnapshots, reapGcEntry, reapOrphanedDescendants, reconcileSandboxLedger, recordProfileQuota, recordSandboxBoot, recordSandboxLiveness, recordSandboxOrigin, recordSandboxState, registerBrainTools, registerBuiltinRoutes, registerPairingTools, registerReviewTools, registerSandboxAttachTool, registerWebSearchTools, removeHarnessPreset, removeSandboxLedgerEntry, renderInboxDigest, renderSessionMessage, renderSessionMessages, repoSlug, resolveBucketSlug, resolveNativeLink, resolvePosture, resolveRelation, resolveReuseFromLedger, resolveReviewerPreset, rollupUsage, runCrashDetectPass, runEagerResumePass, runIdleReapPass, runShellLane, runStallWatchdogPass, sandboxLedgerPath, sanitizeLabel, setDefaultPreset, setMcpCredentialDeps, sweepStaleDaemonRegistry, sweepStaleRuntimeMetas, toWorktreeStatusView, turnToActivities, unlinkDaemonRegistryEntry, unlinkRuntimeMeta, updateHarnessPreset, upsertSandboxLedger, verifyInboundSignature, webSearchTool, withPr, withPrStatus, workflowToActivities, writeDaemonRegistryEntry };
|
|
12573
|
+
export { type ActivityKind, type ActivityListFilter, type ActivityPolicyLister, type ActivityProjector, type ActivityProjectorRegistry, type ActivityProjectorSession, type ActivityRecord, type ActivitySource, type ActivityState, type ActivityWaitingOn, type ActivityWorkflowLister, AdapterAuthDescriptor, type AdapterCapabilitiesLister, type AdapterInstallResult, type AdapterListEntry, type AgentAdapterInstaller, type AgentAdapterLister, type AgentAdapterResolver, type AgentSessionLike, type AgentStreamEvent, type AnthropicReaderConfig, AnthropicRemainingQuotaReader, type AttachPolicyInput, type AttachSandboxOpts, type AttachSandboxResult, AuthMethod, BUCKETS_ROOT, type BranchGcClass, type BranchGcCoverageView, type BranchGcHoldReason, type BranchGcKind, type BranchGcOutcomeView, type BranchGcPlanEntryView, type BranchGcPlanView, type BranchGcReclaimReason, type BranchGcResult, type BranchGcRunInput, type BranchGcRunner, type BranchGcStatus, type BranchGcSummaryView, type BranchGcTriageVerdict, type BranchGcVerdictInput, type BranchGcVerdictLookupInput, type BranchGcVerdictReader, type BranchGcVerdictRecordView, type BranchGcVerdictRecorder, type BrowserAdapterHandle, type BrowserAdapterInfo, type BrowserAdapterLister, type BrowserAdapterResolver, BuildHeartbeatAgent, CONTINUE_PROMPT_SOURCE, CanonicalPosture, type CatalogModelsLister, CatalogModelsQuery, CatalogModelsResponse, type CatalogProviderModel, type CatalogProviderModelsQuery, type CatalogProviderModelsResponse, type CatalogProviderPricing, type ClaudeNativeRef, type CommitSpec, type CompletionPolicySupervisor, ContextProfile, type ContinueInterruptedMode, type ContinueInterruptedOutcome, type ContinueInterruptedResult, type ContinueInterruptedSkipReason, type ContinueOnBootSummary, type ConversationIndexRecord, type ConversationNativeRef, type CostBudgetDecision, type CrashDetectSummary, type CrashReaperRegistry, type CreateGatewayOptions, type CreateOfferInput, type CreateReviewRunnerOptions, type CreatedOffer, DEAD_SESSION_STATUSES, DEFAULT_ALWAYS_ON_TOOLS, DEFAULT_BUCKET, DEFAULT_CONTINUE_PROMPT, DEFAULT_ORCHESTRATOR_TOOLS, DEFAULT_WORKTREE_ISOLATION, type DaemonReviewerHostDeps, DeclaredAdapterOption, type DeclaredAdapterPreset, DefaultsAdapterAuthConfig, type Device, type DeviceKind, type DeviceRegistry, type DeviceRole, type EagerResumeFailReason, type EagerResumeOutcome, type EagerResumeSkipReason, type EagerResumeSummary, EffortLevel, type EnableInput, type EnableResult, type ForwardHttpRequest, type ForwardHttpResponse, GC_REAPABLE_STATES, type GateSpec, type GatewayHandle, type GhRunner, HOSTS_VERSION, type HarnessPreset, type HarnessPresetValidationDeps, HarnessPresetValidationError, type HarnessPresetsFile, type HermesNativeRef, type HostRecord, type HostRegistry, type HostRegistryDeps, INBOUND_PROVIDERS, type IdleReapSummary, type IdleReaperRegistry, type InboundEndpoint, type InboundEndpointStore, type InboundEndpointStoreOptions, type InboundEnqueuePrompt, type InboundIsSessionAlive, type InboundMessage, type InboundProvider, type InboundRestartSession, type InboundRouteMode, type InboundRouterDeps, type InboundRouterLog, type InboundSpawnForContact, type InboundWatcher, type JudgeGateSpec, LEGACY_SESSIONS_FILE, type LedgerAnnotations, type LedgerEntry, type LedgerHostMeta, type LlmEndpointDescriptor, type LlmEndpointStatus, type LlmEndpointStatusReport, type LocatedConversation, type LocatedConversationByPath, MAX_AUTO_CONTINUE_ATTEMPTS, MAX_MESSAGE_DATA_BYTES, MCP_APP_BRIDGE_SCRIPT, MESSAGE_KINDS, MESSAGE_PREAMBLE, MESSAGE_TAG, MESSAGE_URGENCIES, type McpCredentialDeps, type MeasurableTool, type MeasuredToolEntry, type MessageDeliveryVia, type MessageFilter, type MessageKind, type MessageRelation, type MessageTreeNode, type MessageUrgency, type MigrationMarker, type NormalizeInboundResult, type OnFailSpec, type OpenPrResolver, type OrchestratorGatewayDeps, type OrchestratorInjection, type OrchestratorInjector, type OrchestratorInjectorDeps, type OrchestratorMcpServerFactory, type OrchestratorScope, type OrphanReaperRegistry, PAIRINGS_VERSION, POSTURE_NATIVE_ALIASES, POSTURE_PREAMBLES, type PairingChannelContext, type PairingChannelHandle, type PairingChannelMode, type PairingRecord, type PairingRegistry, type PairingRegistryDeps, type PendingPermission, type PermissionRespondInput, type PermissionRespondResult, type PolicyRunState, type PolicyRunStatus, Posture, type PostureResolution, PrLookupError, type PrLookupErrorCode, type PrResolvedState, type PrStateResolver, type PrStatusSnapshot, type PresetInfo, type PricingResolver, type QuotaReadableProfile, type QuotaStoreFile, type QuotaStoreOptions, type ReconnectLogGate, type RegisterBrainToolsOptions, type RegisterBrowserInput, type RegisterDeviceToolsOptions, type RegisterPairingToolsOptions, type RegisterReviewToolsOptions, type RegisterSessionInput, type RegisterWebSearchToolsOptions, type RemainingQuota, type RemainingQuotaReader, type RemoteStatus, type ResolveNativeLinkInput, ResolvedAuthSpec, ResumeDisabledError, type ReuseResolution, type ReviewLedger, type ReviewLedgerFilter, type ReviewRun, type ReviewRunInput, type ReviewRunStatus, type ReviewRunner, type ReviewerRunResult, type ReviewerSessionHost, type RouteAwareLaunchConfig, type RouteAwareLaunchConfigInput, RouteSpec, type RuntimeMeta, SESSION_END_REASONS, SESSION_ID_ENV, type SandboxAdapterInfo, type SandboxConnectionDescriptor, type SandboxGcCandidate, type SandboxGcProviderHandle, type SandboxGcReapDeps, type SandboxGcReapResult, type SandboxLedgerEntry, type SandboxLedgerState, type SandboxProviderCapabilities, type SandboxProviderHandle, type SandboxProviderLister, type SandboxProviderResolver, type SandboxReconcileDeps, type SandboxReconcileProviderHandle, type SandboxReconcileResult, type SandboxReconcileRow, type SandboxReconcileVerdict, type ScopeTokenRegistry, SessionConfig, type SessionCurrentPhase, type SessionDescriptor, type SessionEndReason, type SessionKind, type SessionMessage, type SessionMessageFrom, type SessionMessageSentRecord, type SessionObserver, type SessionOutcome, type SessionOutcomeArtifact, type SessionOutcomeCompact, type SessionOutcomeLink, type SessionSnapshots, type SessionStatus, type SessionUsage, type SessionUsageWithSubtree, type SessionWaitEvent, type SessionWaitResult, type SessionsRegistry, type ShellGateSpec, type SpawnAgentInput, SpawnDefaultsConfig, type SpawnSessionInput, type StallWatchdogRegistry, type StallWatchdogSummary, type StoredProfileQuota, type SubtreeChildUsage, type SubtreeUsageTotals, TASK_STATUSES, type TaskCaller, type TaskChangedEvent, type TaskClaimInput, type TaskCreateInput, type TaskGateOutcome, type TaskGateRunner, type TaskLedger, type TaskLedgerRegistry, type TaskLedgerSessionSlice, type TaskListFilter, type TaskRecord, type TaskStatus, type TaskUpdateInput, type TaskVerification, type TaskVerifySupervisor, type TaskWriteResult, type TokenPricing, type ToolListMeasurement, type TransmitterBinding, type TransmitterBindingStore, type TunnelDescriptor, type TunnelProvider, type TunnelStatus, type UsageBucket, type UsageComputeInput, type UsageDetail, type UsageReadContext, type UsageReadResult, type UsageRollup, type UsageSnapshotRecord, type UsageSource, UserPreset, WORKSPACE_SLUG_ENV, WORKTREE_ISOLATION_ENV, type WatcherDescriptor, type WatcherStartInput, type WebSearchInput, type WebSearchOutput, type WebSearchResult, type WorkspaceBrainSubscriber, type WorkspaceBrainSubscriberOptions, type WorkspaceBrains, WorkspaceFs, type WorktreeAutoReclaimer, type WorktreeDecision, type WorktreeField, type WorktreeGcClass, type WorktreeGcOutcomeView, type WorktreeGcPlanEntryView, type WorktreeGcReclaimReason, type WorktreeGcResult, type WorktreeGcRunInput, type WorktreeGcRunner, WorktreeIsolationMode, type WorktreeProvisionOutcome, type WorktreeProvisionRequest, type WorktreeProvisioner, type WorktreeRequest, type WorktreeStatusLister, type WorktreeStatusView, activityCounts, addHarnessPreset, appendConversationRecord, attachSandbox, bucketDir, bucketSessionsFile, bucketTranscriptDir, buildCatalogProviderModels, buildMcpConfigSnippet, buildRouteAwareLaunchConfig, canonicalForModeId, claudeProjectSlug, collectGcCandidates, compactOutcome, composeSessionObservers, continueInterruptedSessions, continueSkipReason, conversationIndexPath, createActivityProjector, createDaemonReviewerHost, createDeviceRegistry, createFileStepCache, createGateway, createHostRegistry, createInboundEndpointStore, createOrchestratorInjector, createOrchestratorMcpServerFactory, createPairingRegistry, createPrProvenanceReconciler, createReconnectLogGate, createReviewLaneExecutor, createReviewLedger, createReviewRunner, createScopeTokenRegistry, createSessionMessage, createSupervisorTaskGateRunner, createTaskLedger, createWorkspaceBrainSubscriber, createWorkspaceBrains, daemonRegistryDir, decideWorktreeIsolation, declaredPresetToProviderPreset, defaultReviewLedgerRoot, defineBraveSearchHttpDriver, defineSerperHttpDriver, deriveSessionOutcome, deriveSessionUsage, enrichRollupWithProviderQuota, enrichWithRemainingQuota, escapeHumanPrompt, escapeMessageBody, evaluateCostBudget, execGh, extractHelpSection, fetchPrStatus, filterActivities, findConversationRecord, findNativeMode, findPrForCommit, formatToolCall, formatToolResult, getDefaultHarnessPreset, getHarnessPreset, getMcpCredentialDeps, getToolHelp, githubRepoOf, harnessPresetsPath, hostPlaceholders, injectMcpAppBridge, isAgentCliAuthConfigured, isClosedTaskStatus, isKnownSessionEndReason, isMessageAllowed, isProviderLimitError, isSafeBucketSlug, isTerminalActivityState, listBuckets, listHarnessPresets, listPresets, listToolHelpTopics, loadHarnessPresets, loadQuotaStore, loadWorktreeIsolation, locateConversationByNativePath, locateConversationBySessionId, makeBrowserAdapterLister, makeSandboxCredsStore, makeSandboxResolver, matchesMessageFilter, measureTool, measureToolList, messageFrom, migrateLegacySessionsFile, migrationMarkerPath, mintMessageId, monitorPolicyWait, monitorSessionWait, narrowOrchestratorTools, normalizeInbound, normalizeModeId, normalizeRemote, normalizeWorktreeField, parseAnthropicRateLimitHeaders, parsePrUrl, parseTaskStatus, parseWindow, parseWorktreeIsolationMode, pickUsageDetail, policyToActivities, policyWatchesSession, prHeadSha, prToActivities, projectSessionUsage, readConversationIndex, readDaemonRegistry, readPairingsSnapshot, readProfileQuota, readRegisteredSlugs, readRuntimeMeta, readSandboxLedger, readSessionForBrain, readUsageSnapshots, reapGcEntry, reapOrphanedDescendants, reconcileSandboxLedger, recordProfileQuota, recordSandboxBoot, recordSandboxLiveness, recordSandboxOrigin, recordSandboxState, registerBrainTools, registerBuiltinRoutes, registerDeviceTools, registerPairingTools, registerReviewTools, registerSandboxAttachTool, registerWebSearchTools, removeHarnessPreset, removeSandboxLedgerEntry, renderInboxDigest, renderSessionMessage, renderSessionMessages, repoSlug, resolveBucketSlug, resolveEffectiveLlmEndpointFlag, resolveNativeLink, resolvePosture, resolveRelation, resolveReuseFromLedger, resolveReviewerPreset, rollupSessionSubtree, rollupUsage, runContinueOnBootPass, runCrashDetectPass, runEagerResumePass, runIdleReapPass, runShellLane, runStallWatchdogPass, sandboxLedgerPath, sanitizeLabel, setDefaultPreset, setMcpCredentialDeps, sweepStaleDaemonRegistry, sweepStaleRuntimeMetas, toWorktreeStatusView, turnToActivities, unlinkDaemonRegistryEntry, unlinkRuntimeMeta, updateHarnessPreset, upsertSandboxLedger, verifyInboundSignature, webSearchTool, withPr, withPrStatus, workflowToActivities, writeDaemonRegistryEntry };
|