@agentproto/runtime 5.8.0 → 5.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,17 +1,17 @@
1
1
  import { DoctypeSpec } from '@agentproto/manifest';
2
- import { h as WorktreeIsolationMode, i as SpawnAttachMode, j as SpawnDedupeMode, R as ResolvedModelRole } from './config-Gz7q9yfJ.js';
3
- export { k as DEFAULT_MODEL_ROLES, M as MODEL_ROLE_REF_PREFIX, l as ModelRoleContext, m as ModelRoleEntry, n as ModelRoleSource, o as ModelRoleValue, p as ModelRolesConfig, q as listModelRoles, r as parseModelRoleRef, s as resolveModelRole } from './config-Gz7q9yfJ.js';
2
+ import { h as WorktreeIsolationMode, i as SpawnAttachMode, j as SpawnDedupeMode, R as ResolvedModelRole } from './config-Dsmv-jri.js';
3
+ export { k as DEFAULT_MODEL_ROLES, M as MODEL_ROLE_REF_PREFIX, l as ModelRoleContext, m as ModelRoleEntry, n as ModelRoleSource, o as ModelRoleValue, p as ModelRolesConfig, q as listModelRoles, r as parseModelRoleRef, s as resolveModelRole } from './config-Dsmv-jri.js';
4
4
  import { B as BuildHeartbeatAgent } from './heartbeat-BJtxbDb9.js';
5
5
  export { H as HeartbeatAgent, a as HeartbeatRunner, R as RuntimeEvent, b as RuntimeEvents, p as parseDuration } from './heartbeat-BJtxbDb9.js';
6
- import { M as MessageUrgency, S as SessionEvent, a as SessionEventType, b as SessionEventBus, c as SessionsRegistry, C as CompletionPolicySupervisor, T as TaskLedger, d as SessionDescriptor, e as SessionEndReason, A as ActivityPolicySlice, f as ActivityListFilter, g as ActivityRecord, h as ActivityTurnSession, i as ActivityPrSession, j as ActivityWorkflowRunSlice, P as PrResolvedState, k as ActivityTaskSlice, W as WorktreeProvisioner, l as AgentsMdResolution, U as UserPreset, R as RestartPolicy, m as SandboxAppServeSpec, n as WorktreeField, o as AgentSessionLike, p as UsageReadContext, q as UsageReadResult, r as MessageKind, s as SessionMessage, t as AgentStreamEvent, u as SessionUsage, v as ToolCallRecord, w as StatsSessionDescriptor, x as ProcRow, y as ProvisionInFlight, z as ProvisionTracker, B as UsageRollup, D as RemainingQuotaReader, Q as QuotaReadableProfile, E as UsageSnapshotRecord, F as SessionAwaitingQuestion, G as PolicyRunState, H as PtyFactory, I as WorktreeAutoReclaimer } from './sessions-SrISpFsH.js';
7
- export { J as ActivityKind, K as ActivitySource, L as ActivityState, N as ActivityWaitingOn, O as AnthropicReaderConfig, V as AnthropicRemainingQuotaReader, X as AttachPolicyInput, Y as CommandGroupStats, Z as CommitSpec, _ as DEFAULT_WORKTREE_ISOLATION, $ as DEFAULT_WORKTREE_PROVISION_CONCURRENCY, a0 as EagerResumeFailReason, a1 as EagerResumeOutcome, a2 as EagerResumeSkipReason, a3 as GateSpec, a4 as HostInfo, a5 as JudgeGateSpec, a6 as LabeledProcessStatsReport, a7 as LabeledSessionStats, a8 as MAX_MESSAGE_DATA_BYTES, a9 as MESSAGE_KINDS, aa as MESSAGE_PREAMBLE, ab as MESSAGE_TAG, ac as MESSAGE_URGENCIES, ad as MessageDeliveryVia, ae as MessageFilter, af as MessageRelation, ag as MessageTreeNode, ah as OnFailSpec, ai as OrphanGroup, aj as PendingPermission, ak as PermissionRespondInput, al as PermissionRespondResult, am as PolicyRunStatus, an as PricingResolver, ao as ProcessDetail, ap as ProcessStatsReport, aq as ProcessStatsService, ar as QuotaStoreFile, as as QuotaStoreOptions, at as RegisterBrowserInput, au as RegisterSessionInput, av as RemainingQuota, aw as ResourceStats, ax as ResumeDisabledError, ay as SESSION_END_REASONS, az as SESSION_ID_ENV, aA as SessionCurrentPhase, aB as SessionKind, aC as SessionMessageFrom, aD as SessionOutcome, aE as SessionOutcomeArtifact, aF as SessionOutcomeCompact, aG as SessionOutcomeLink, aH as SessionResourceStats, aI as SessionSnapshots, aJ as SessionStatus, aK as ShellGateSpec, aL as SpawnAgentInput, aM as SpawnSessionInput, aN as StatsDetail, aO as StoredProfileQuota, aP as TASK_STATUSES, aQ as TaskCaller, aR as TaskChangedEvent, aS as TaskClaimInput, aT as TaskCreateInput, aU as TaskGateOutcome, aV as TaskGateRunner, aW as TaskLedgerRegistry, aX as TaskLedgerSessionSlice, aY as TaskListFilter, aZ as TaskRecord, a_ as TaskStatus, a$ as TaskUpdateInput, b0 as TaskVerification, b1 as TaskVerifySupervisor, b2 as TaskWriteResult, b3 as TokenPricing, b4 as UsageBucket, b5 as UsageComputeInput, b6 as UsageDetail, b7 as UsageSource, b8 as UserPresetsFile, b9 as WORKSPACE_SLUG_ENV, ba as WORKTREE_ISOLATION_ENV, bb as WORKTREE_PROVISION_CONCURRENCY_ENV, bc as WorktreeDecision, bd as WorktreeProvisionOutcome, be as WorktreeProvisionPhase, bf as WorktreeProvisionProgress, bg as WorktreeProvisionRequest, bh as WorktreeRequest, bi as activityCounts, bj as compactOutcome, bk as createProcessStatsService, bl as createSessionMessage, bm as createSupervisorTaskGateRunner, bn as createTaskLedger, bo as decideWorktreeIsolation, bp as deleteUserPreset, bq as deriveSessionOutcome, br as deriveSessionUsage, bs as escapeHumanPrompt, bt as escapeMessageBody, bu as filterActivities, bv as getProcessStatsService, bw as getUserPreset, bx as isClosedTaskStatus, by as isKnownSessionEndReason, bz as isMessageAllowed, bA as isProviderLimitError, bB as isTerminalActivityState, bC as listUserPresets, bD as loadQuotaStore, bE as loadUserPresets, bF as loadWorktreeIsolation, bG as matchesMessageFilter, bH as messageFrom, bI as mintMessageId, bJ as normalizeCommand, bK as normalizeWorktreeField, bL as parseAnthropicRateLimitHeaders, bM as parseTaskStatus, bN as parseWindow, bO as parseWorktreeIsolationMode, bP as pickUsageDetail, bQ as policyToActivities, bR as policyWatchesSession, bS as prToActivities, bT as projectSessionUsage, bU as readProfileQuota, bV as recordProfileQuota, bW as renderInboxDigest, bX as renderSessionMessage, bY as renderSessionMessages, bZ as resolveRelation, b_ as rollupUsage, b$ as sanitizeLabel, c0 as saveUserPreset, c1 as trackWorktreeProvision, c2 as turnToActivities, c3 as userPresetsPath, c4 as workflowToActivities } from './sessions-SrISpFsH.js';
8
- import { R as RouteSpec, P as Posture, C as ContextProfile, a as CanonicalPosture } from './session-config-DxIIuJFY.js';
9
- export { A as AuthMethod, D as DeclaredAdapterMode, E as EffortLevel, S as SessionConfig, c as composeMode, d as decomposeMode } from './session-config-DxIIuJFY.js';
6
+ import { M as MessageUrgency, S as SessionEvent, a as SessionEventType, b as SessionEventBus, c as SessionsRegistry, C as CompletionPolicySupervisor, T as TaskLedger, d as SessionDescriptor, e as SessionEndReason, A as ActivityPolicySlice, f as ActivityListFilter, g as ActivityRecord, h as ActivityTurnSession, i as ActivityPrSession, j as ActivityWorkflowRunSlice, P as PrResolvedState, k as ActivityTaskSlice, W as WorktreeProvisioner, l as AgentsMdResolution, U as UserPreset, R as RestartPolicy, m as SandboxAppServeSpec, n as WorktreeField, o as AgentSessionLike, p as UsageReadContext, q as UsageReadResult, r as MessageKind, s as SessionMessage, t as AgentStreamEvent, u as SessionUsage, v as ToolCallRecord, w as PendingPromptView, x as StatsSessionDescriptor, y as ProcRow, z as ProvisionInFlight, B as ProvisionTracker, D as SessionCrashReason, E as UsageRollup, F as RemainingQuotaReader, Q as QuotaReadableProfile, G as UsageSnapshotRecord, H as SessionAwaitingQuestion, I as PolicyRunState, J as PtyFactory, K as WorktreeAutoReclaimer } from './sessions-BdgU9X6P.js';
7
+ export { L as ActivityKind, N as ActivitySource, O as ActivityState, V as ActivityWaitingOn, X as AnthropicReaderConfig, Y as AnthropicRemainingQuotaReader, Z as AttachPolicyInput, _ as CommandGroupStats, $ as CommitSpec, a0 as DEFAULT_WORKTREE_ISOLATION, a1 as DEFAULT_WORKTREE_PROVISION_CONCURRENCY, a2 as EagerResumeFailReason, a3 as EagerResumeOutcome, a4 as EagerResumeSkipReason, a5 as GateSpec, a6 as HostInfo, a7 as JudgeGateSpec, a8 as LabeledProcessStatsReport, a9 as LabeledSessionStats, aa as MAX_MESSAGE_DATA_BYTES, ab as MESSAGE_KINDS, ac as MESSAGE_PREAMBLE, ad as MESSAGE_TAG, ae as MESSAGE_URGENCIES, af as MessageDeliveryVia, ag as MessageFilter, ah as MessageRelation, ai as MessageTreeNode, aj as NO_OUTPUT_STALL_TURN_ERROR, ak as OnFailSpec, al as OrphanGroup, am as PendingPermission, an as PermissionRespondInput, ao as PermissionRespondResult, ap as PolicyRunStatus, aq as PricingResolver, ar as ProcessDetail, as as ProcessStatsReport, at as ProcessStatsService, au as QuotaStoreFile, av as QuotaStoreOptions, aw as RegisterBrowserInput, ax as RegisterSessionInput, ay as RemainingQuota, az as ResourceStats, aA as ResumeDisabledError, aB as SESSION_END_REASONS, aC as SESSION_ID_ENV, aD as SessionCurrentPhase, aE as SessionKind, aF as SessionMessageFrom, aG as SessionOutcome, aH as SessionOutcomeArtifact, aI as SessionOutcomeCompact, aJ as SessionOutcomeLink, aK as SessionResourceStats, aL as SessionSnapshots, aM as SessionStatus, aN as ShellGateSpec, aO as SpawnAgentInput, aP as SpawnSessionInput, aQ as StatsDetail, aR as StoredProfileQuota, aS as TASK_STATUSES, aT as TaskCaller, aU as TaskChangedEvent, aV as TaskClaimInput, aW as TaskCreateInput, aX as TaskGateOutcome, aY as TaskGateRunner, aZ as TaskLedgerRegistry, a_ as TaskLedgerSessionSlice, a$ as TaskListFilter, b0 as TaskRecord, b1 as TaskStatus, b2 as TaskUpdateInput, b3 as TaskVerification, b4 as TaskVerifySupervisor, b5 as TaskWriteResult, b6 as TokenPricing, b7 as UsageBucket, b8 as UsageComputeInput, b9 as UsageDetail, ba as UsageSource, bb as UserPresetsFile, bc as WORKSPACE_SLUG_ENV, bd as WORKTREE_ISOLATION_ENV, be as WORKTREE_PROVISION_CONCURRENCY_ENV, bf as WorktreeDecision, bg as WorktreeProvisionOutcome, bh as WorktreeProvisionPhase, bi as WorktreeProvisionProgress, bj as WorktreeProvisionRequest, bk as WorktreeRequest, bl as activityCounts, bm as compactOutcome, bn as createProcessStatsService, bo as createSessionMessage, bp as createSupervisorTaskGateRunner, bq as createTaskLedger, br as decideWorktreeIsolation, bs as deleteUserPreset, bt as deriveSessionOutcome, bu as deriveSessionUsage, bv as escapeHumanPrompt, bw as escapeMessageBody, bx as filterActivities, by as getProcessStatsService, bz as getUserPreset, bA as isClosedTaskStatus, bB as isKnownSessionEndReason, bC as isMessageAllowed, bD as isProviderLimitError, bE as isTerminalActivityState, bF as listUserPresets, bG as loadQuotaStore, bH as loadUserPresets, bI as loadWorktreeIsolation, bJ as matchesMessageFilter, bK as messageFrom, bL as mintMessageId, bM as normalizeCommand, bN as normalizeWorktreeField, bO as parseAnthropicRateLimitHeaders, bP as parseTaskStatus, bQ as parseWindow, bR as parseWorktreeIsolationMode, bS as pickUsageDetail, bT as policyToActivities, bU as policyWatchesSession, bV as prToActivities, bW as projectSessionUsage, bX as readProfileQuota, bY as recordProfileQuota, bZ as renderInboxDigest, b_ as renderSessionMessage, b$ as renderSessionMessages, c0 as resolveRelation, c1 as rollupUsage, c2 as sanitizeLabel, c3 as saveUserPreset, c4 as trackWorktreeProvision, c5 as turnToActivities, c6 as userPresetsPath, c7 as workflowToActivities } from './sessions-BdgU9X6P.js';
8
+ import { R as RouteSpec, P as Posture, C as ContextProfile, a as CanonicalPosture } from './session-config-BUDM7T1B.js';
9
+ export { A as AuthMethod, D as DeclaredAdapterMode, E as EffortLevel, S as SessionConfig, c as composeMode, d as decomposeMode } from './session-config-BUDM7T1B.js';
10
10
  import { AcpMcpServer } from '@agentproto/acp';
11
11
  import { SandboxMode } from '@agentproto/command-sandbox';
12
12
  import { AdapterHandle, SetupField, AdapterResolver, AdapterLister, CredsStore, HarnessCapabilities, AdapterEntry } from '@agentproto/provider-kit';
13
- import { a as SpawnBrowserMode, S as SpawnDefaultsConfig, b as ResolveHeadlessBrowser, D as DefaultsAdapterAuthConfig, C as ContextContinuityPolicy, c as ResolvedAuthSpec, d as DeclaredAdapterOption, A as AdapterAuthDescriptor } from './spawn-defaults-Cp9SGZex.js';
14
- export { e as AuthEcho, f as AuthResolutionError, g as CLAUDE_CODE_OAUTH_SOURCE, h as CredentialSource, i as DefaultsAdapterConfig, j as DeferredToolsConfig, k as ResolveSubscriptionCredentialInput, l as ResolvedSpawnAuthMaterial, m as ResolvedSpawnDefaults, n as SubscriptionCredentialResolution, o as SubscriptionSourceError, p as credentialFingerprint, q as normalizeSkillsOption, r as resolveAuthSpec, s as resolveDeferredToolsGatewayOption, t as resolveSpawnDefaults, u as resolveSubscriptionCredential } from './spawn-defaults-Cp9SGZex.js';
13
+ import { a as SpawnBrowserMode, S as SpawnDefaultsConfig, b as ResolveHeadlessBrowser, D as DefaultsAdapterAuthConfig, C as ContextContinuityPolicy, c as ResolvedAuthSpec, d as DeclaredAdapterOption, A as AdapterAuthDescriptor } from './spawn-defaults-Dm7nbxcP.js';
14
+ export { e as AuthEcho, f as AuthResolutionError, g as CLAUDE_CODE_OAUTH_SOURCE, h as CredentialSource, i as DefaultsAdapterConfig, j as DeferredToolsConfig, k as ResolveSubscriptionCredentialInput, l as ResolvedSpawnAuthMaterial, m as ResolvedSpawnDefaults, n as SubscriptionCredentialResolution, o as SubscriptionSourceError, p as credentialFingerprint, q as normalizeSkillsOption, r as resolveAuthSpec, s as resolveDeferredToolsGatewayOption, t as resolveSpawnDefaults, u as resolveSubscriptionCredential } from './spawn-defaults-Dm7nbxcP.js';
15
15
  import { CatalogModelsQuery, CatalogModelsResponse } from './catalog-models.js';
16
16
  export { CatalogAdapterInput, CatalogAdapterModelInput, CatalogPricing, CatalogProduct, CatalogRoute, CatalogRouteSummary, CatalogVendor, buildCatalogModels } from './catalog-models.js';
17
17
  import { FooterSession } from './pr-provenance.js';
@@ -23,7 +23,7 @@ import * as _agentproto_tool from '@agentproto/tool';
23
23
  import { ToolContext } from '@agentproto/tool';
24
24
  import { z } from 'zod';
25
25
  import { DriverHandle } from '@agentproto/driver';
26
- import { Attestation, LedgerKey, RubricDigest, PackDigest, ReviewPrRef, LaneResult, ReviewLaneExecutor, LaneOutcome, Attestor, PackLoader } from '@agentproto/review';
26
+ import { Attestation, LedgerKey, RubricDigest, PackDigest, ReviewPrRef, LaneFallback, LaneResult, ReviewLaneExecutor, LaneOutcome, Attestor, PackLoader } from '@agentproto/review';
27
27
  import { BundlesFile } from './bundles.js';
28
28
  import { ImportedMcpsConfig } from './mcp-imports.js';
29
29
  import { CostBudget, AuthProfile, CostBudgetScope } from '@agentproto/auth';
@@ -440,6 +440,112 @@ interface SentinelSpec {
440
440
  * descriptive, same as `group`. */
441
441
  label?: string;
442
442
  }
443
+ /** Declared capabilities of a sentinel provider — pure metadata, surfaced in
444
+ * `list_sentinel_adapters`. Never carries secrets. */
445
+ interface SentinelProviderCapabilities {
446
+ /** Subject schemes it can watch, e.g. `["github"]`, or `["*"]`. */
447
+ subjects: string[];
448
+ /** Can deliver by calling back into the daemon (push ingress). */
449
+ push: boolean;
450
+ /** Supports `poll`/`ack`. */
451
+ poll: boolean;
452
+ /** Events survive daemon downtime (hosted queue). */
453
+ durable: boolean;
454
+ /** Push mode requires a reachable daemon (public URL). */
455
+ needsPublicUrl: boolean;
456
+ requiresAuth: boolean;
457
+ /** Documentation only — surfaced in `list_sentinel_adapters`. */
458
+ typicalLatencyMs: number;
459
+ }
460
+ /** Opaque provider-owned state for one sentinel. Persisted on the
461
+ * `Sentinel` record; round-tripped through `create`/`attach`/`cancel`. */
462
+ interface SentinelHandle {
463
+ provider: string;
464
+ /** Remote id — agentpush subscription id, GitHub hook id, … */
465
+ remoteId?: string;
466
+ /** Poll cursor — agentpush seq, local-gh snapshot hash, … */
467
+ cursor?: string;
468
+ state?: Record<string, unknown>;
469
+ }
470
+ /** How the daemon wants events delivered — passed to `create`/`attach` so a
471
+ * provider can register a webhook (push) or just start polling. */
472
+ type DeliveryPreference = {
473
+ mode: "poll";
474
+ intervalMs: number;
475
+ } | {
476
+ mode: "push";
477
+ /** Public daemon origin the provider should call back into. A push
478
+ * provider that owns its own secret/route (the `webhook` provider)
479
+ * ignores or derives both; absent when no public URL is known. */
480
+ callbackUrl?: string;
481
+ secret?: string;
482
+ };
483
+ /** Extra context the runtime/tools hand to `create` beyond the spec. */
484
+ interface SentinelCreateContext {
485
+ /** The id the store will record this sentinel under (`sen_<ulid>`), minted
486
+ * BEFORE `create` so a provider that stamps it remotely (agentpush's
487
+ * `consumerRef`) names the same sentinel the daemon does. */
488
+ sentinelId?: string;
489
+ }
490
+ /** Whether a provider can operate right now, and if not, why. */
491
+ interface SentinelProviderReadiness {
492
+ ready: boolean;
493
+ /** Human-readable, actionable reason when `ready` is false. */
494
+ reason?: string;
495
+ }
496
+ /**
497
+ * A pluggable adapter that turns a sentinel spec into a stream of
498
+ * {@link SentinelEvent}s. Same registry/adapter-kit pattern as the tunnel and
499
+ * sandbox provider families (`AdapterHandle` gives slug/name/version/
500
+ * description/requiresSetup/check).
501
+ */
502
+ interface SentinelProviderHandle extends AdapterHandle {
503
+ readonly capabilities: SentinelProviderCapabilities;
504
+ /** Credential fields this provider accepts via `setup_sentinel_provider`.
505
+ * Omit (or empty) when the provider needs no credentials. */
506
+ readonly setupFields?: readonly SetupField[];
507
+ /** Start watching. `delivery` tells the provider how the daemon wants
508
+ * events. */
509
+ create(spec: SentinelSpec, delivery: DeliveryPreference, ctx?: SentinelCreateContext): Promise<SentinelHandle>;
510
+ /** Re-attach after a daemon restart (re-point a callback, resume a
511
+ * cursor). */
512
+ attach(handle: SentinelHandle, delivery: DeliveryPreference): Promise<SentinelHandle>;
513
+ cancel(handle: SentinelHandle): Promise<void>;
514
+ status(handle: SentinelHandle): Promise<{
515
+ ok: boolean;
516
+ detail?: string;
517
+ pending?: number;
518
+ }>;
519
+ /** Poll mode: events after `handle.cursor`, oldest first, plus the new
520
+ * cursor. */
521
+ poll?(handle: SentinelHandle, limit: number): Promise<{
522
+ events: SentinelEvent[];
523
+ cursor: string;
524
+ }>;
525
+ ack?(handle: SentinelHandle, cursor: string): Promise<void>;
526
+ /** Push mode: verify + parse one inbound HTTP request into events (called
527
+ * by the `"sentinel"` dialect on `POST /inbound/sentinel-<hookKey>`). */
528
+ parseInbound?(req: {
529
+ rawBody: string;
530
+ headers: Record<string, string | string[] | undefined>;
531
+ }, handle: SentinelHandle): {
532
+ ok: true;
533
+ events: SentinelEvent[];
534
+ } | {
535
+ ok: false;
536
+ reason: string;
537
+ };
538
+ /** Delivery a provider that supports both modes wants by default. Absent =
539
+ * poll when `capabilities.poll`, else push (see {@link deliveryPreferenceFor}). */
540
+ preferredDelivery?(intervalMs: number): DeliveryPreference;
541
+ /** Default `types` for a subject scheme when the spec leaves it undefined. */
542
+ defaultTypes(subject: string): string[];
543
+ /** Optional operational-readiness probe (public URL known, auth scope
544
+ * sufficient, ...). Consulted by `list_sentinel_adapters` and provider
545
+ * auto-selection. Absent = always ready. Never throws — a probe failure
546
+ * is `{ready:false, reason}`. */
547
+ readiness?(): Promise<SentinelProviderReadiness>;
548
+ }
443
549
 
444
550
  /**
445
551
  * SentinelStore — persists `~/.agentproto/sentinels.json` (AIP-60 §2).
@@ -466,6 +572,211 @@ interface SentinelSpec {
466
572
  */
467
573
 
468
574
  type SentinelStatus = "active" | "paused" | "expired" | "orphaned" | "error";
575
+ interface Sentinel {
576
+ /** `sen_<ulid>`, daemon-minted. */
577
+ id: string;
578
+ spec: SentinelSpec;
579
+ /** Resolved provider slug (never undefined once created, even when
580
+ * `spec.provider` was left for auto-select). */
581
+ provider: string;
582
+ /** Opaque provider state (remote id, cursor, hook id, …). */
583
+ handle: SentinelHandle;
584
+ status: SentinelStatus;
585
+ createdTs: number;
586
+ lastEventTs?: number;
587
+ eventCount: number;
588
+ lastError?: string;
589
+ /** Last `SEEN_CAP` event ids delivered/skipped for this sentinel — the
590
+ * dedup window (design §2: "last 1000 event ids, dedup across providers/
591
+ * restarts"). */
592
+ seen: string[];
593
+ /** For `spec.until.kind === "subject_terminal"` with more than one
594
+ * `spec.match` clause: the clause subjects that have already seen a
595
+ * terminal event. The sentinel only expires once every clause's subject
596
+ * is present here. Stays `[]` for other `until` kinds (unused) and for a
597
+ * single-clause spec is immediately superseded by expiry on that one
598
+ * clause's terminal event — same behaviour as before multi-clause
599
+ * `match` existed. */
600
+ terminalSubjects: string[];
601
+ /** Concrete event subjects (e.g. `github:o/r#12`) that have already seen a
602
+ * terminal event (PR merged/closed) — any later NON-terminal event for one
603
+ * of them is post-mortem noise (a check_suite failing after the merge) and
604
+ * is parked instead of delivered. Independent of `spec.until`. Absent on
605
+ * sentinels persisted before this field existed. */
606
+ closedSubjects?: string[];
607
+ }
608
+ interface SentinelCreateInput {
609
+ /** Pre-minted id (see {@link mintSentinelId}); minted by the store when
610
+ * omitted. */
611
+ id?: string;
612
+ spec: SentinelSpec;
613
+ provider: string;
614
+ handle: SentinelHandle;
615
+ status?: SentinelStatus;
616
+ }
617
+ type SentinelUpdatePatch = Partial<Pick<Sentinel, "spec" | "provider" | "handle" | "status" | "lastEventTs" | "eventCount" | "lastError" | "terminalSubjects" | "closedSubjects">>;
618
+ /** A `webhook` target's secret sidecar row — the material `signWebhook` and
619
+ * challenge verification need, keyed by the `secretRef` the at-rest target
620
+ * carries. The material NEVER sits inside the `Sentinel` record or any
621
+ * sentinel view (plan §4 W-B task 4); keys are never logged. */
622
+ interface SentinelWebhookSecret {
623
+ /** Current signing secret (`whsec_…`, standard-base64 wire format). */
624
+ secret: string;
625
+ /** Previous secret — kept while a rotation window is open (10 min from
626
+ * `rotatedAt`) so delivery signs with BOTH during renewal. */
627
+ prevSecret?: string;
628
+ /** Wall-clock ms at which `prevSecret` was superseded by `secret`; the
629
+ * dual-sign window is `now - rotatedAt < 10 minutes`. */
630
+ rotatedAt?: number;
631
+ }
632
+ /** What {@link SentinelStore.putSentinelSecret} hands back — the only thing
633
+ * sidecar writes return; never the material. */
634
+ interface SentinelSecretWriteResult {
635
+ ref: string;
636
+ hasPrevSecret: boolean;
637
+ rotatedAt?: number;
638
+ }
639
+ interface SentinelStore {
640
+ get(id: string): Sentinel | undefined;
641
+ list(): Sentinel[];
642
+ create(input: SentinelCreateInput): Sentinel;
643
+ update(id: string, patch: SentinelUpdatePatch): Sentinel | undefined;
644
+ remove(id: string): boolean;
645
+ /** true = first time this event id has been seen for this sentinel
646
+ * (persisted dedup, bounded). Returns true (treat-as-unseen) for an
647
+ * unknown sentinel id — never blocks a caller who already validated the
648
+ * sentinel exists moments earlier.
649
+ *
650
+ * Callers that need at-least-once delivery MUST check {@link isSeen}
651
+ * BEFORE attempting delivery and only call `markSeen` AFTER delivery is
652
+ * handled (delivered or parked) — calling this before delivery and
653
+ * bailing out on a thrown error would dedupe the event out of every
654
+ * future redelivery attempt, silently losing it. */
655
+ markSeen(id: string, eventId: string): boolean;
656
+ /** Read-only check: true = this event id is already in the persisted
657
+ * `seen` window for this sentinel. Never mutates — use this to decide
658
+ * whether an event needs (re)delivery, and only call `markSeen` once
659
+ * delivery has actually been handled. Returns false for an unknown
660
+ * sentinel id (nothing recorded, so nothing has been "seen"). */
661
+ isSeen(id: string, eventId: string): boolean;
662
+ /** Write a webhook secret sidecar row (secret material at rest, 0600
663
+ * sidecar file, keys never logged). When the row's existing `secret`
664
+ * DIFFERS, the old one is kept as `prevSecret` and `rotatedAt` is
665
+ * stamped now — the dual-sign window arithmetic lives on the delivery
666
+ * side. Returns only non-secret metadata; never the secret. */
667
+ putSentinelSecret(ref: string, row: SentinelWebhookSecret): SentinelSecretWriteResult | undefined;
668
+ /** Read a secret sidecar row (delivery path only — never a listing path). */
669
+ getSentinelSecret(ref: string): SentinelWebhookSecret | undefined;
670
+ /** Read-only expiry consultation for `until: {kind:"at"}` — false for
671
+ * every other `until` kind and for an unknown id. Sweeping the status
672
+ * flip belongs to the runtime; this never mutates. */
673
+ isExpired(id: string): boolean;
674
+ /** Solve the `secretRef` for a webhook target: a target still carrying
675
+ * raw `secret` has it moved into the sidecar (fresh ref returned); a
676
+ * target already carrying `secretRef` (at-rest shape) is left as-is and
677
+ * its ref returned. undefined = not a webhook target, or neither
678
+ * secret nor ref present. */
679
+ materializeWebhookTargetRef(target: SentinelTarget): string | undefined;
680
+ /** Synchronous flush for shutdown paths. */
681
+ flushSync(): void;
682
+ }
683
+
684
+ /**
685
+ * SessionFollowStore — persists `~/.agentproto/follows.json`.
686
+ *
687
+ * A "follow" lets one long-lived session (the FOLLOWER) be woken by the
688
+ * lifecycle events of OTHER sessions matched by a selector — including root
689
+ * sessions it did not spawn. The matching engine lives in `session-follow.ts`;
690
+ * this file is only the record shape + persistence.
691
+ *
692
+ * Persistence model mirrors `sentinel-store.ts`: in-memory Map, loaded on
693
+ * construct, debounced atomic write (per-process tmp file + rename, mode
694
+ * 0600), synchronous flush at shutdown. A follow whose follower session no
695
+ * longer exists is KEPT — the follower may be revived.
696
+ */
697
+ /** The event kinds a follow can subscribe to. */
698
+ declare const FOLLOW_EVENTS: readonly ["turn-end", "awaiting-input", "exited", "crashed", "pr-opened", "pr-merged"];
699
+ type FollowEvent = (typeof FOLLOW_EVENTS)[number];
700
+ interface FollowSelector {
701
+ /** Explicit session ids to follow (always match, regardless of `rootOnly`). */
702
+ sessionIds?: string[];
703
+ /** Follow every session that exists at EVENT time (auto-covers sessions
704
+ * spawned after the follow was created). */
705
+ all?: boolean;
706
+ /** Match sessions whose cwd is this path or below it. */
707
+ cwdPrefix?: string;
708
+ /** Only sessions with no `parentSessionId`. Effective default: `true` when
709
+ * `all`, otherwise `false`. Stored resolved. */
710
+ rootOnly?: boolean;
711
+ }
712
+ interface FollowExclude {
713
+ sessionIds?: string[];
714
+ labels?: string[];
715
+ }
716
+ interface SessionFollow {
717
+ /** `fol_<ulid>`, daemon-minted. */
718
+ id: string;
719
+ /** Optional stable caller-chosen key: re-posting the same key updates the
720
+ * existing follow in place (UPSERT). */
721
+ key?: string;
722
+ /** The session that gets woken. */
723
+ follower: string;
724
+ /** ISO-8601 creation time. */
725
+ createdAt: string;
726
+ selector: FollowSelector;
727
+ exclude?: FollowExclude;
728
+ /** Subscribed event kinds. Stored resolved (default: all of them). */
729
+ events: FollowEvent[];
730
+ /** Coalescing window per follower. Default 15000; 0 = next tick. */
731
+ batchMs: number;
732
+ /** Drop turn-ends flagged `empty` (silent no-op turns). Default true. */
733
+ skipEmptyTurns: boolean;
734
+ /** Ignore sessions descending from the follower. Default true. */
735
+ excludeFollowerChildren: boolean;
736
+ }
737
+ /** Fully-resolved input for {@link SessionFollowStore.upsert}. */
738
+ interface SessionFollowInput {
739
+ key?: string;
740
+ follower: string;
741
+ selector: FollowSelector;
742
+ exclude?: FollowExclude;
743
+ events?: readonly FollowEvent[];
744
+ batchMs?: number;
745
+ skipEmptyTurns?: boolean;
746
+ excludeFollowerChildren?: boolean;
747
+ }
748
+ interface SessionFollowStore {
749
+ get(id: string): SessionFollow | undefined;
750
+ /** Look up by id first, then by `key`. */
751
+ find(idOrKey: string): SessionFollow | undefined;
752
+ list(filter?: {
753
+ follower?: string;
754
+ }): SessionFollow[];
755
+ /** UPSERT by `key` when given (keeps `id` + `createdAt`), else create. */
756
+ upsert(input: SessionFollowInput): {
757
+ follow: SessionFollow;
758
+ created: boolean;
759
+ };
760
+ /** Re-point a follow at another follower session (a revived follower). */
761
+ setFollower(id: string, follower: string): SessionFollow | undefined;
762
+ /** Remove by id or key. */
763
+ remove(idOrKey: string): SessionFollow | undefined;
764
+ /** Synchronous flush for shutdown paths. */
765
+ flushSync(): void;
766
+ }
767
+ interface SessionFollowStoreOptions {
768
+ /** Override persist path. Default ~/.agentproto/follows.json (or
769
+ * AGENTPROTO_HOME/follows.json). */
770
+ filePath?: string;
771
+ /** Injectable clock for tests. */
772
+ nowMs?: () => number;
773
+ /** Debounce interval for disk persistence. */
774
+ debounceMs?: number;
775
+ /** Disable disk persistence (unit tests). Default true, unless `false`
776
+ * is passed; an explicit `filePath` implies persistence. */
777
+ persist?: boolean;
778
+ }
779
+ declare function createSessionFollowStore(opts?: SessionFollowStoreOptions): SessionFollowStore;
469
780
 
470
781
  /**
471
782
  * LlmEndpointRegistry — supervised-sidecar manager for the
@@ -1314,19 +1625,37 @@ declare function makeSandboxResolver(credsStore: CredsStore<SandboxCreds>, opts?
1314
1625
  /**
1315
1626
  * Fire-and-forget webhook notifier for session lifecycle events.
1316
1627
  *
1317
- * Each session can register its own `notifyUrl` (via `agent_start`).
1318
- * A global URL can be set via `AGENTPROTO_NOTIFY_URL` env var or
1319
- * `~/.agentproto/notify.json` (env wins). Both are POSTed when an event
1320
- * fires — the union of per-session + global URLs, deduplicated.
1628
+ * Each session can register its own `notifyUrl` (via `agent_start`), with an
1629
+ * optional `notifySecret` (`whsec_...`). A global URL can be set via
1630
+ * `AGENTPROTO_NOTIFY_URL` env var (+ optional `AGENTPROTO_NOTIFY_SECRET`) or
1631
+ * `~/.agentproto/notify.json` `{url, secret?}` (env wins). Both are POSTed
1632
+ * when an event fires — the union of per-session + global URLs, deduplicated
1633
+ * by URL (a URL registered both ways is posted once; the per-session secret
1634
+ * wins over the global one on conflict).
1635
+ *
1636
+ * Signing (opt-in, backward compatible): when a target has a secret, the
1637
+ * POST carries Standard Webhooks headers (`webhook-id` / `webhook-timestamp`
1638
+ * / `webhook-signature`, see `webhook-egress/signing.ts`) — HMAC-SHA256 over
1639
+ * `id.timestamp.body`, the same contract sentinel/MCP Events already use for
1640
+ * egress. A target with no secret is posted exactly as before: unauthenticated,
1641
+ * `Content-Type` only. Existing callers that never set `notifySecret` or a
1642
+ * `secret` in notify.json see zero behavior change.
1321
1643
  *
1322
1644
  * Retry policy: one retry after 2 s on network error. No retry on 4xx/5xx.
1323
1645
  * Timeout: 10 s per attempt. All errors are swallowed — the notifier never
1324
1646
  * throws into the session's hot path.
1647
+ *
1648
+ * Of the daemon-scoped `cron:*` events, ONLY `cron:unhealthy` is relayed (to
1649
+ * the global URL — cron events carry no sessionId). `cron:fired` /
1650
+ * `cron:succeeded` / `cron:failed` stay filtered: relaying every fire would
1651
+ * spam whatever the operator's global URL feeds (e.g. a Telegram relay) on a
1652
+ * schedule that can be every 20 minutes.
1325
1653
  */
1326
1654
 
1327
1655
  interface WebhookNotifier {
1328
- /** Register a per-session URL (called from agent_start). */
1329
- register(sessionId: string, url: string): void;
1656
+ /** Register a per-session URL (called from agent_start), with an optional
1657
+ * `whsec_...` secret to sign its deliveries. */
1658
+ register(sessionId: string, url: string, secret?: string): void;
1330
1659
  unregister(sessionId: string): void;
1331
1660
  /** Handler to wire into SessionEventBus.onAny. Fire-and-forget. */
1332
1661
  onSessionEvent(ev: SessionEvent): void;
@@ -2482,8 +2811,8 @@ interface SpawnAgentSessionInput {
2482
2811
  preset?: UserPreset;
2483
2812
  /**
2484
2813
  * Deterministic billing-auth mode + EXPLICIT credential for adapters that
2485
- * declare an env-var vocabulary for it (today: claude-code — see
2486
- * `AgentCliAuth.modes` in `@agentproto/driver-agent-cli`). `mode` wins over
2814
+ * declare it (an `authSubscription` login and/or an API-key `provider`
2815
+ * in their manifest — see `AdapterAuthDescriptor`). `mode` wins over
2487
2816
  * `~/.agentproto/config.json`'s `defaults.adapters.<slug>.auth.mode`
2488
2817
  * (default `"subscription"`); the credential (`token` for `"subscription"`,
2489
2818
  * `apiKey` for `"api-key"`) wins over the config field matching the
@@ -2500,6 +2829,7 @@ interface SpawnAgentSessionInput {
2500
2829
  maxChildren?: number;
2501
2830
  };
2502
2831
  notifyUrl?: string;
2832
+ notifySecret?: string;
2503
2833
  wait?: boolean;
2504
2834
  maxCostUsd?: number;
2505
2835
  /** Windowed cost-budget cap (phase 4). DISTINCT from the scalar `maxCostUsd`
@@ -2530,9 +2860,10 @@ interface SpawnAgentSessionInput {
2530
2860
  promptAppend?: string;
2531
2861
  /** Per-spawn override for the daemon self-mount's deferred/lazy
2532
2862
  * `tools/list` loading (harness-parity item 3 — see `deferred-tools.ts`).
2533
- * Wins over the resolved role's own default (`RoleProfile.deferredTools`
2534
- * — on for `executor`), which in turn only applies when this is
2535
- * omitted. Threaded onto the injected `mcpServers` self-mount ref as
2863
+ * Wins over a harness with native tool search (manifest
2864
+ * `capabilities.nativeToolSearch` ⇒ eager) and the resolved role's own
2865
+ * default (`RoleProfile.deferredTools` — on for `executor`), which only
2866
+ * apply when this is omitted (`resolveSpawnDeferredTools`). Threaded onto the injected `mcpServers` self-mount ref as
2536
2867
  * `?deferred=1|0` (`shouldInjectDaemonSelfMount` path below); has no
2537
2868
  * effect on a caller-supplied `mcpServers` (that URL is the caller's to
2538
2869
  * compose). Omitted entirely ⇒ no override at all — the gateway's own
@@ -3247,6 +3578,13 @@ type AgentAdapterResolver = (slug: string) => Promise<{
3247
3578
  * restart even when a native resume id is available.
3248
3579
  */
3249
3580
  nativeTerminalResume?: boolean;
3581
+ /**
3582
+ * Manifest-declared `capabilities.nativeToolSearch` (AIP-45) — the
3583
+ * harness defers mounted MCP tools behind its own search tool, so the
3584
+ * daemon's self-mount defaults to EAGER for it rather than double-deferring
3585
+ * (see `resolveSpawnDeferredTools`). Omitted/`false` ⇒ role/daemon default.
3586
+ */
3587
+ nativeToolSearch?: boolean;
3250
3588
  } | null>;
3251
3589
  /**
3252
3590
  * UI-safe projection of an AIP-45 `modes[]` entry as surfaced by
@@ -4469,7 +4807,7 @@ declare function runShellLane(input: {
4469
4807
  signal?: AbortSignal;
4470
4808
  }): Promise<LaneOutcome>;
4471
4809
  /** Outcome of one reviewer session's run. */
4472
- type ReviewerRunResult = {
4810
+ type ReviewerRunResult = ({
4473
4811
  status: "ended";
4474
4812
  sessionId: string;
4475
4813
  preset: string;
@@ -4485,6 +4823,12 @@ type ReviewerRunResult = {
4485
4823
  sessionId?: string;
4486
4824
  preset?: string;
4487
4825
  model?: string;
4826
+ }) & {
4827
+ /** Reviewers that were unavailable BEFORE the one in `preset`, in order, each
4828
+ * with its error. Set only when a `fallbackPresets` chain advanced past at
4829
+ * least one reviewer; `preset`/`model`/`sessionId` always name the reviewer
4830
+ * that produced this result. */
4831
+ fallbacks?: LaneFallback[];
4488
4832
  };
4489
4833
  /**
4490
4834
  * The agent-lane executor seam: spawn a reviewer session under a harness
@@ -4495,6 +4839,9 @@ type ReviewerRunResult = {
4495
4839
  interface ReviewerSessionHost {
4496
4840
  run(input: {
4497
4841
  preset: string;
4842
+ /** Tried in order, after `preset`, only when the preceding reviewer was
4843
+ * unavailable (never after a verdict, timeout, or cancel). */
4844
+ fallbackPresets?: string[];
4498
4845
  cwd: string;
4499
4846
  prompt: string;
4500
4847
  label: string;
@@ -5053,6 +5400,12 @@ interface DaemonReviewerHostDeps {
5053
5400
  /** Preset lookups — injectable for tests; default to the real stores. */
5054
5401
  getHarnessPreset?: (id: string) => Promise<HarnessPreset | undefined>;
5055
5402
  getUserPreset?: (id: string) => Promise<UserPreset | undefined>;
5403
+ /** Extra attempts for a lane whose turn ends in a transient error (socket
5404
+ * closed, 5xx, overloaded). Default {@link DEFAULT_LANE_RETRIES}; `0`
5405
+ * disables. Mirrors `config.review.laneRetries`. */
5406
+ laneRetries?: number;
5407
+ /** Auth-profile lookup for the OpenRouter guard — injectable for tests. */
5408
+ getAuthProfile?: (id: string) => Promise<AuthProfile | undefined>;
5056
5409
  }
5057
5410
  /** Resolve a lane's `preset` to spawn fields — harness preset first, then a
5058
5411
  * user preset. `undefined` when neither store knows the id. */
@@ -5703,6 +6056,214 @@ interface SandboxReconcileResult {
5703
6056
  */
5704
6057
  declare function reconcileSandboxLedger(deps: SandboxReconcileDeps): Promise<SandboxReconcileResult>;
5705
6058
 
6059
+ /**
6060
+ * Per-session structured event capture — one append-only JSONL file per
6061
+ * agent-cli session, written at the same tap point where `projectEvent`
6062
+ * (sessions.ts) flattens `StreamEvent`s into the ANSI ring buffer, but
6063
+ * BEFORE that flattening happens. Gives agentproto the Claude-Code
6064
+ * property: a daemon-owned structured transcript that survives a daemon
6065
+ * restart (the ring buffer doesn't) and that any frontend can render,
6066
+ * not just the two adapters `transcript-export.ts` knows how to re-read
6067
+ * from their own native stores.
6068
+ *
6069
+ * File layout: `~/.agentproto/sessions/<sessionId>/events.jsonl` (the
6070
+ * root is overridable via the daemon config's `sessions.eventsDir` — see
6071
+ * `setDefaultSessionsBaseDir`), one JSON object per line: `{seq, ts, kind, ...fields}`.
6072
+ *
6073
+ * PTY (`terminal`) and `command` sessions never call into this writer —
6074
+ * they have no structured event source (see report-transcript-
6075
+ * architecture.md finding C.17), so this module is only ever driven from
6076
+ * `agent-cli` sessions' `runAgentTurn`.
6077
+ */
6078
+
6079
+ /** Point the no-`baseDir` path resolution at `dir`. Called once at daemon
6080
+ * boot from the loaded config (`sessions.eventsDir`); `undefined` restores
6081
+ * the hardcoded `~/.agentproto/sessions` default. Relative paths are
6082
+ * resolved against the home directory. */
6083
+ declare function setDefaultSessionsBaseDir(dir: string | undefined): void;
6084
+ /** The effective default base dir — the configured one, or the hardcoded
6085
+ * `~/.agentproto/sessions`. */
6086
+ declare function defaultTranscriptBaseDir(): string;
6087
+ declare function sessionTranscriptDir(sessionId: string, baseDir?: string): string;
6088
+ declare function sessionEventsPath(sessionId: string, baseDir?: string): string;
6089
+
6090
+ /**
6091
+ * Per-session index sidecar — a compact `<sessionsDir>/<id>/index.json`
6092
+ * projection of every session dir under the sessions store, maintained
6093
+ * best-effort on every write-path event (create/rename/turn-end/exit) and
6094
+ * backfilled at daemon startup for sessions that predate the sidecar.
6095
+ *
6096
+ * WHY: recovering a session by its user-visible label (or its cwd, or an id
6097
+ * prefix) used to require `grep -r` across the whole sessions store and a
6098
+ * hand-rolled parse of a multi-thousand-line `events.jsonl`. Everything was
6099
+ * in the jsonl, but answering "which session was that?" meant loading every
6100
+ * file whole. The sidecar turns that into one small JSON read per session
6101
+ * (`sessions find`) and a single bounded tail read for the "where did we
6102
+ * stop" recap (`sessions recap`).
6103
+ *
6104
+ * INVARIANTS:
6105
+ * - additive: `events.jsonl`'s format is never touched; this is a sidecar.
6106
+ * - best-effort: a failed index write must never fail a session write.
6107
+ * - bounded: reads seek from the end and cap the window ({@link INDEX_TAIL_BYTES});
6108
+ * a whole-file read of `events.jsonl` is never performed here.
6109
+ * - throttled: the registry schedules index writes rather than doing one
6110
+ * per streaming frame (see `scheduleIndexWrite` in sessions.ts).
6111
+ *
6112
+ * Pure by construction apart from the explicit read/write helpers; the
6113
+ * registry owns the scheduling, this module owns the shape and the disk.
6114
+ */
6115
+
6116
+ /** Hard cap on `lastUserPrompt.text`, in characters. */
6117
+ declare const INDEX_MAX_PROMPT = 500;
6118
+ /** Hard cap on `lastOutputText`, in characters. */
6119
+ declare const INDEX_MAX_OUTPUT = 300;
6120
+ /** How many bytes of `events.jsonl` a tail read may pull back from the end.
6121
+ * Bounded so a multi-MB transcript never turns a find/recap into a scan. */
6122
+ declare const INDEX_TAIL_BYTES: number;
6123
+ /** Default page size for `sessions find` / `session_search`. */
6124
+ declare const INDEX_DEFAULT_LIMIT = 20;
6125
+ /** The compact sidecar shape. Every field is optional except `id`/`kind`/
6126
+ * `status`/`alive`/`startedAt`, so a recovered-from-jsonl entry can be
6127
+ * partial without lying about what it knows. */
6128
+ interface SessionIndexEntry {
6129
+ id: string;
6130
+ label?: string;
6131
+ title?: string;
6132
+ renamedByUser?: boolean;
6133
+ kind: string;
6134
+ status: string;
6135
+ alive: boolean;
6136
+ adapter?: string;
6137
+ model?: string;
6138
+ cwd?: string;
6139
+ workspaceSlug?: string;
6140
+ origin?: string;
6141
+ depth?: number;
6142
+ parentSessionId?: string;
6143
+ startedAt: string;
6144
+ lastActivityAt?: string;
6145
+ lastTurnReason?: string;
6146
+ lastUserPrompt?: {
6147
+ ts: string;
6148
+ text: string;
6149
+ };
6150
+ lastOutputText?: string;
6151
+ turnsCompleted?: number;
6152
+ costUsd?: number;
6153
+ }
6154
+ /** One user prompt recovered from a transcript tail. */
6155
+ interface TranscriptPrompt {
6156
+ ts: string;
6157
+ text: string;
6158
+ }
6159
+ /** The bounded tail-read result: parsed prompts, the last assistant run, and
6160
+ * how many bytes were actually read (exposed so a test can prove the read
6161
+ * stayed within {@link INDEX_TAIL_BYTES}). */
6162
+ interface TranscriptTail {
6163
+ prompts: TranscriptPrompt[];
6164
+ lastOutputText?: string;
6165
+ bytesRead: number;
6166
+ /** `ts` of the first parseable record in the window, when it carries one. */
6167
+ firstTs?: string;
6168
+ }
6169
+ /** Absolute path of one session's index sidecar. */
6170
+ declare function sessionIndexPath(sessionId: string, baseDir?: string): string;
6171
+ /** Build the sidecar entry from a live/persisted descriptor, filling the
6172
+ * transcript-derived fields (`lastUserPrompt`/`lastOutputText`) from the
6173
+ * caller when it has them. */
6174
+ declare function indexEntryFromDescriptor(desc: SessionDescriptor, extra?: {
6175
+ lastUserPrompt?: TranscriptPrompt;
6176
+ lastOutputText?: string;
6177
+ }): SessionIndexEntry;
6178
+ /** Read one session's sidecar. Returns undefined on ENOENT, malformed JSON,
6179
+ * or a shape missing its id — never throws. */
6180
+ declare function readSessionIndex(sessionId: string, baseDir?: string): SessionIndexEntry | undefined;
6181
+ /** Atomically write one session's sidecar (tmp + rename). Best-effort:
6182
+ * swallows every error — a failed index write must never fail a session
6183
+ * write. */
6184
+ declare function writeSessionIndex(entry: SessionIndexEntry, baseDir?: string): void;
6185
+ /**
6186
+ * Read the final `maxBytes` of `eventsPath` and extract, in one forward pass,
6187
+ * every `user-prompt` (with its `ts`) and the last non-empty assistant text
6188
+ * run. The window's first line is usually torn; JSON.parse rejects it and it
6189
+ * is skipped. Never reads the whole file.
6190
+ */
6191
+ declare function readTranscriptTail(eventsPath: string, maxBytes?: number): TranscriptTail;
6192
+ /** Recover a partial sidecar entry for a session from its `events.jsonl`
6193
+ * alone — the backfill path for a missing/corrupt index. Returns undefined
6194
+ * when the session dir has no transcript. */
6195
+ declare function deriveIndexFromTranscript(sessionId: string, baseDir?: string): SessionIndexEntry | undefined;
6196
+ /** Every sidecar under `baseDir`, newest activity first. Dirs with a missing
6197
+ * or corrupt index are recovered in memory from their transcript tail so a
6198
+ * find still sees them; this never writes. Best-effort: a readdir failure
6199
+ * returns `[]`. */
6200
+ declare function readAllSessionIndexes(baseDir?: string): SessionIndexEntry[];
6201
+ /** Case-insensitive query match: `id` by prefix, every other searchable field
6202
+ * by substring. An empty query matches everything. */
6203
+ declare function matchesSessionQuery(entry: Pick<SessionIndexEntry, "id" | "label" | "title" | "cwd" | "workspaceSlug">, query: string): boolean;
6204
+ /** Filter + order + cap a set of index entries. `limit` defaults to
6205
+ * {@link INDEX_DEFAULT_LIMIT}. */
6206
+ declare function searchSessionIndexes(entries: readonly SessionIndexEntry[], query: string, opts?: {
6207
+ status?: string;
6208
+ limit?: number;
6209
+ }): SessionIndexEntry[];
6210
+ /** The one-glance "where did we stop" recap — the output an agent needs to
6211
+ * resume. Built from the sidecar plus a bounded tail read of the transcript. */
6212
+ interface SessionRecap {
6213
+ id: string;
6214
+ status: string;
6215
+ alive: boolean;
6216
+ label?: string;
6217
+ title?: string;
6218
+ adapter?: string;
6219
+ model?: string;
6220
+ cwd?: string;
6221
+ workspaceSlug?: string;
6222
+ parentSessionId?: string;
6223
+ children: string[];
6224
+ startedAt: string;
6225
+ lastActivityAt?: string;
6226
+ turnsCompleted?: number;
6227
+ costUsd?: number;
6228
+ lastTurnReason?: string;
6229
+ /** Last K user prompts, oldest → newest. */
6230
+ prompts: TranscriptPrompt[];
6231
+ /** Final assistant text/thought of the last turn (trimmed). */
6232
+ lastOutputText?: string;
6233
+ queuedPrompts?: number;
6234
+ /** The queued prompts with age — see `SessionDescriptor.pendingPrompts`. */
6235
+ pendingPrompts?: readonly PendingPromptView[];
6236
+ }
6237
+ /**
6238
+ * Compose a recap from an index entry + a bounded transcript tail read.
6239
+ * `eventsPath` is read from the end only (≤{@link INDEX_TAIL_BYTES});
6240
+ * `children`/`queuedPrompts` come from the caller (the daemon has them live,
6241
+ * the CLI derives children from the index set).
6242
+ */
6243
+ declare function buildSessionRecap(input: {
6244
+ entry: SessionIndexEntry;
6245
+ eventsPath: string;
6246
+ last?: number;
6247
+ children?: readonly string[];
6248
+ queuedPrompts?: number;
6249
+ pendingPrompts?: readonly PendingPromptView[];
6250
+ }): SessionRecap;
6251
+ /**
6252
+ * Daemon-startup pass: create the sidecar for every session dir that lacks a
6253
+ * valid one, recovering `lastUserPrompt`/`lastOutputText` from the transcript
6254
+ * tail (never a whole-file parse). When `descriptors` are supplied (the live
6255
+ * registry), their authoritative meta fills the entry. Best-effort and
6256
+ * synchronous — a store with thousands of sessions does one readdir plus one
6257
+ * bounded read per missing index, nothing more.
6258
+ */
6259
+ declare function backfillSessionIndexes(baseDir?: string, opts?: {
6260
+ descriptors?: Iterable<SessionDescriptor>;
6261
+ }): {
6262
+ scanned: number;
6263
+ created: number;
6264
+ skipped: number;
6265
+ };
6266
+
5706
6267
  /**
5707
6268
  * Host-level load report - answers "why is this machine on its knees" without
5708
6269
  * a hand-run `top` / `vm_stat` / `iostat` / `ps` / `lsof` session.
@@ -6066,9 +6627,15 @@ declare function runIdleReapPass(opts: {
6066
6627
  * `status:"running"` until the next prompt's RPC fails. A parked session
6067
6628
  * with no next prompt never gets that chance; the crash is silent forever.
6068
6629
  *
6069
- * This pass sweeps the registry, finds agent-cli sessions whose OS process
6070
- * is provably gone (`processAlive === false`, a fresh `process.kill(pid,0)`
6071
- * probe), and MARKS them crashed (`registry.markCrashed`): flips the row to
6630
+ * The same is true one layer up, for a reason a pid probe can never catch:
6631
+ * an ACP wrapper's PROCESS can outlive its own JSON-RPC stream. The stream
6632
+ * ends, `process.kill(pid, 0)` keeps succeeding, and the row reports
6633
+ * `running`/`alive: true` while every prompt rejects "ACP connection
6634
+ * closed". So this pass probes BOTH axes — process liveness AND transport
6635
+ * liveness (`adapterConnected`, from the live session's `isConnected()`).
6636
+ *
6637
+ * This pass sweeps the registry, finds agent-cli sessions provably dead on
6638
+ * either axis, and MARKS them crashed (`registry.markCrashed`): flips the row to
6072
6639
  * `error`/`endedReason:"crashed"`, records a short `lastError`, and clears
6073
6640
  * the dead binding so the row stays lazy-resumable — same shape as
6074
6641
  * idle-reaper's `reapIdle`, except this pass is DISCOVERING a death that
@@ -6111,7 +6678,7 @@ interface CrashReaperRegistry {
6111
6678
  list(opts?: {
6112
6679
  includeArchived?: boolean;
6113
6680
  }): readonly SessionDescriptor[];
6114
- markCrashed(id: string): boolean;
6681
+ markCrashed(id: string, reason?: SessionCrashReason): boolean;
6115
6682
  }
6116
6683
  /**
6117
6684
  * Run one crash-detect sweep. Pure over the registry's own freshly-probed
@@ -6512,52 +7079,66 @@ interface SentinelView {
6512
7079
  }
6513
7080
 
6514
7081
  /**
6515
- * Standard Webhooks `whsec_` signing for webhook egress (W-A of
6516
- * `.plans/sentinel-mcp-events/PLAN.md`).
7082
+ * session-follow — wake a long-lived session (the FOLLOWER) when sessions it
7083
+ * did not necessarily spawn end a turn, await input, exit/crash, or get a PR
7084
+ * opened/merged. No polling: it hangs one `onAny` subscriber off the
7085
+ * in-process session event bus.
6517
7086
  *
6518
- * Contract (frozen §3):
6519
- * - HMAC-SHA256 over `msgId.timestamp.body` (raw bytes; `.update` chained so
6520
- * the body is never re-encoded — payload arrives as `Uint8Array`, I2).
6521
- * - Signature print = standard base64 (NOT base64url): `v1,<b64>`.
6522
- * - HMAC key = the base64 payload DECODED after the `whsec_` prefix.
6523
- * - Multi-secret: space-separated `v1,<sig>` segments (rotation window).
6524
- * - Returns ONLY headers — the caller owns the bytes and signs them again
6525
- * with a fresh timestamp on retry; signing never re-serializes.
7087
+ * Until now events only reached a parent (`supervisor-notify.ts`,
7088
+ * `notifyParentOnCrash`) or the owner of a PR sentinel. A follow is the
7089
+ * generic primitive: a SELECTOR (`sessionIds` / `all` / `cwdPrefix`, minus an
7090
+ * `exclude`) evaluated at EVENT time against the sessions that exist then, so
7091
+ * a session spawned later by anybody is covered automatically.
7092
+ *
7093
+ * Delivery mirrors `supervisor-notify.ts`: matched events are coalesced per
7094
+ * follower within `batchMs` into ONE daemon-attested system message
7095
+ * (`relation:"system"`, `kind:"notice"`, `urgency:"next-turn"`) through
7096
+ * `registry.sendMessage` — an idle follower runs it as its own turn now, a
7097
+ * busy one parks it in its prompt queue as a separate turn. It never
7098
+ * interrupts. The follower's own events are never delivered to itself, and
7099
+ * (by default) neither are its descendants'.
7100
+ *
7101
+ * Dead follower: same approach as `sentinel-runtime.ts` — resume it through
7102
+ * the injected `restartSession` hook (never a deliberately-closed one) and
7103
+ * retry; otherwise park the digest in `~/.agentproto/follows-parked.jsonl`
7104
+ * so the events are not silently lost. The follow record is always kept.
6526
7105
  */
6527
- interface WebhookSignInput {
6528
- /** Stable event id (`evt_…` / verification `msg_verification_…`) — same across retries. */
6529
- msgId: string;
6530
- /** Seconds, Unix epoch (Standard Webhooks wire format). */
6531
- timestamp: number;
6532
- /** Exact bytes — signed once (I2). Caller passes the serialization; signing never re-serializes. */
6533
- payload: Uint8Array;
6534
- /** One or, during a rotation window, two secrets (`whsec_…`). */
6535
- secrets: readonly string[];
7106
+
7107
+ /** The slice of the sessions registry this subscriber needs (structural, like
7108
+ * `SupervisorNotifyRegistry`). */
7109
+ interface SessionFollowRegistry {
7110
+ get(id: string): SessionDescriptor | undefined;
7111
+ sendMessage(msg: SessionMessage, opts?: {
7112
+ source?: string;
7113
+ origin?: string;
7114
+ }): Promise<unknown>;
6536
7115
  }
6537
- type WebhookSignatureHeaders = {
6538
- "webhook-id": string;
6539
- "webhook-timestamp": string;
6540
- "webhook-signature": string;
6541
- };
6542
- /**
6543
- * Encode raw secret bytes into the `whsec_<base64>` wire format.
6544
- * Inverse of {@link decodeWhsecSecret}.
6545
- */
6546
- declare function encodeWhsecSecret(raw: Uint8Array): string;
6547
- /**
6548
- * Decode a `whsec_…` secret to its raw HMAC key: standard-base64 payload
6549
- * after the prefix, which must decode to 24..64 bytes. Returns `null` on any
6550
- * violation (bad prefix, not base64, length out of range). The canonical
6551
- * validator for W-C: a submit failing this is `-32602` upstream; egress
6552
- * surfaces it as a categorized challenge failure.
6553
- */
6554
- declare function decodeWhsecSecret(secret: string): Buffer | null;
6555
- /**
6556
- * Sign exactly the bytes given. Throws `Error` when any secret fails
6557
- * {@link decodeWhsecSecret} (callers must have validated upstream; a bad
6558
- * secret at this point is a programmer error, never silently signed).
6559
- */
6560
- declare function signWebhook(input: WebhookSignInput): WebhookSignatureHeaders;
7116
+ interface WireSessionFollowOptions {
7117
+ registry: SessionFollowRegistry;
7118
+ sessionEvents: SessionEventBus;
7119
+ store: SessionFollowStore;
7120
+ /** Resume a dead follower; resolves to the session id to deliver to.
7121
+ * Omitted → a dead follower's digest is parked. */
7122
+ restartSession?: (sessionId: string) => Promise<string>;
7123
+ /** Last assistant text of a session, for the digest excerpt. Default: the
7124
+ * tail of its `events.jsonl`. */
7125
+ readLastOutput?: (desc: SessionDescriptor) => string | undefined;
7126
+ /** Injectable timers (tests). Default: global `setTimeout`/`clearTimeout`,
7127
+ * resolved at call time so vitest fake timers apply. */
7128
+ setTimer?: (fn: () => void, ms: number) => unknown;
7129
+ clearTimer?: (handle: unknown) => void;
7130
+ /** Parked-digest journal (tests). Default `~/.agentproto/follows-parked.jsonl`. */
7131
+ parkedPath?: string;
7132
+ log?: (line: string) => void;
7133
+ }
7134
+ interface SessionFollowHandle {
7135
+ /** Deliver every pending batch now (or just `followerId`'s). Resolves once
7136
+ * the deliveries settled. */
7137
+ flush(followerId?: string): Promise<void>;
7138
+ /** Unsubscribe and drop pending batches (shutdown). */
7139
+ dispose(): void;
7140
+ }
7141
+ declare function wireSessionFollow(opts: WireSessionFollowOptions): SessionFollowHandle;
6561
7142
 
6562
7143
  /**
6563
7144
  * SSRF-guarded outbound HTTPS POST for webhook egress (W-A of
@@ -6767,6 +7348,316 @@ declare function envelopeClampedBytes(event: McpEventEnvelope): {
6767
7348
  };
6768
7349
  declare function deliverEventEnvelope(replay: DeliveryReplay, event: McpEventEnvelope, deps?: DeliverEventDeps): Promise<DeliveryOutcome>;
6769
7350
 
7351
+ /**
7352
+ * MCP Events registry (W-C of `.plans/sentinel-mcp-events/PLAN.md`, §2/§3).
7353
+ *
7354
+ * One object per provider scheme. Every registration carries the WIRE
7355
+ * `EventDefinition` (name / description / `delivery:["webhook"]` /
7356
+ * `inputSchema` / `payloadSchema` — official doc verbatim, no extra fields)
7357
+ * PLUS the internal `InternalEventMeta`. Two fields on the meta are
7358
+ * MANDATORY by type: `argumentsToMatch` (the missing link between
7359
+ * `document_id`-style subscription args and `SentinelSpec.match`) and
7360
+ * `authorize`. A registration that omits either does not compile.
7361
+ *
7362
+ * `replayable` is INTERNAL only (it drives `cursor:null` for v1) and must
7363
+ * never appear on the wire — the §3 `EventDefinition` has no such field.
7364
+ *
7365
+ * Day-1 scheme: `github`. The definitions are derived from the ACTUAL event
7366
+ * types the providers declare/emit in `sentinel-providers/` (verified with
7367
+ * `rg 'github\.' packages/runtime/src/sentinel-providers`) — NOT from the
7368
+ * illustrative names in the plan's task text. See `GITHUB_SCHEME` below.
7369
+ */
7370
+
7371
+ declare const PRINCIPAL_BRAND: unique symbol;
7372
+ /**
7373
+ * The authenticated caller of a native MCP `events/*` call. REALITY (plan
7374
+ * §1): the root `/mcp` transport authenticates with ONE daemon bearer (or
7375
+ * trusted loopback) and exposes only an optional `callerSessionId` — there is
7376
+ * no per-caller auth-profile principal yet. So v1 has exactly two
7377
+ * constructors; a future W-F multi-tenant widening touches this one file.
7378
+ */
7379
+ type Principal = string & {
7380
+ readonly [PRINCIPAL_BRAND]: true;
7381
+ };
7382
+ declare function daemonBearerPrincipal(): Principal;
7383
+ declare function sessionPrincipal(sessionId: string): Principal;
7384
+ interface EventDefinition {
7385
+ name: string;
7386
+ description: string;
7387
+ delivery: ["webhook"];
7388
+ inputSchema: object;
7389
+ payloadSchema: object;
7390
+ }
7391
+ /** What `argumentsToMatch` produces: explicit Sentinel match clauses plus the
7392
+ * provider slug that can emit the event. `ok:false` becomes `-32602` with a
7393
+ * definition-specific reason. */
7394
+ type ArgumentsResult = {
7395
+ ok: true;
7396
+ matchClauses: SentinelMatchClause[];
7397
+ providerSlug: string;
7398
+ } | {
7399
+ ok: false;
7400
+ reason: string;
7401
+ };
7402
+ interface InternalEventMeta {
7403
+ /** INTERNAL: drives `cursor:null` vs a provider cursor. v1 is all-false. */
7404
+ replayable: boolean;
7405
+ /** Map `inputSchema`-validated args to explicit match clauses (pure). */
7406
+ argumentsToMatch: (args: Record<string, unknown>) => ArgumentsResult;
7407
+ /** Authorization gate for the given principal. */
7408
+ authorize: (args: Record<string, unknown>, principal: Principal) => boolean;
7409
+ }
7410
+ interface EventRegistration {
7411
+ definition: EventDefinition;
7412
+ meta: InternalEventMeta;
7413
+ }
7414
+ interface SchemeRegistry {
7415
+ scheme: string;
7416
+ events: EventRegistration[];
7417
+ }
7418
+ /** Validate subscription args against a definition's `inputSchema`. */
7419
+ declare function validateAgainstInputSchema(schema: object, args: unknown): {
7420
+ ok: true;
7421
+ } | {
7422
+ ok: false;
7423
+ reason: string;
7424
+ };
7425
+ /**
7426
+ * The day-1 github scheme. Types are the ACTUAL `github.*` strings emitted by
7427
+ * `sentinel-providers/local-gh.ts` (the zero-infra provider the plan names):
7428
+ * - github.pull_request.closed
7429
+ * - github.pull_request.synchronize
7430
+ * - github.pull_request_review.submitted
7431
+ * - github.check_suite.completed
7432
+ *
7433
+ * The plan's illustrative `github.pull_request.opened` and
7434
+ * `github.build.failed` do NOT exist in `sentinel-providers/` (opened is only
7435
+ * producible by the push `webhook` provider's normalizer; build.failed exists
7436
+ * nowhere — the closest real signal is `github.check_suite.completed` with
7437
+ * `data.conclusion === "failure"`). Per the plan's own instruction to surface
7438
+ * actual declared values, only real types ship — no fabricated definition.
7439
+ *
7440
+ * `local-gh`'s `defaultTypes()` also lists `github.workflow_run.completed` and
7441
+ * `github.issue_comment.created`, but its poll implementation does not emit
7442
+ * them (documented in `local-gh.ts`); shipping them here would advertise
7443
+ * subscriptions that can never fire, so they are intentionally omitted.
7444
+ */
7445
+ declare const GITHUB_SCHEME: SchemeRegistry;
7446
+ /** Every registered scheme. Adding a scheme = one object + one test row. */
7447
+ declare const EVENT_REGISTRY: readonly SchemeRegistry[];
7448
+ /** The schemes a principal may discover/subscribe to. v1: single tenant, all. */
7449
+ declare function tenantScope(_principal: Principal): readonly SchemeRegistry[];
7450
+ /** Look up a registration by official wire name (all schemes). */
7451
+ declare function findEventDefinition(name: string): EventRegistration | undefined;
7452
+
7453
+ /**
7454
+ * MCP Events adapter (W-C of `.plans/sentinel-mcp-events/PLAN.md`, §2/§3).
7455
+ *
7456
+ * Three methods over the existing Sentinel core — `events/list`,
7457
+ * `events/subscribe`, `events/unsubscribe`. This module owns the subscription
7458
+ * lifecycle; the transport (native JSON-RPC methods + `events:{}` in
7459
+ * `server/discover`) lives in `@agentproto/mcp-server` and is wired in
7460
+ * `runtime/index.ts`.
7461
+ *
7462
+ * INVARIANTS v1 (plan §2, code-verified):
7463
+ * - every event is NON-REPLAYABLE → `cursor` is always `null`, `truncated`
7464
+ * is never set;
7465
+ * - no `read` tool, no separate package, no batching.
7466
+ *
7467
+ * Subscription ids are deterministic (`subscription-id.ts`): subscribe upserts
7468
+ * on identity, unsubscribe RECOMPUTES the id (never an id-lookup). The store
7469
+ * has no CAS and `create()` silently overwrites, so every mutation is
7470
+ * serialized behind an in-process async mutex.
7471
+ */
7472
+
7473
+ declare const DEFAULT_TTL_MS: number;
7474
+ declare const MAX_TTL_MS: number;
7475
+ /** Store minimum lifetime — prevents churn-refresh for a tiny requested TTL. */
7476
+ declare const MIN_TTL_MS: number;
7477
+ /**
7478
+ * `refreshBefore` is the GRANTED EXPIRATION itself (`until.ms` as ISO-8601),
7479
+ * per the official doc — never a pre-expiry hint. `until:{kind:"never"}`
7480
+ * (only granted for `ttlMs: null`) yields `null`.
7481
+ */
7482
+ declare function computeRefreshBefore(until: SentinelUntil): string | null;
7483
+ /**
7484
+ * `ttlMs` mapping (§2):
7485
+ * omitted → default 7d;
7486
+ * number → grant `min(requested, 30d)`, floored at 60s;
7487
+ * null → `until:{kind:"never"}` (no expiration).
7488
+ */
7489
+ declare function untilForTtl(ttlMs: number | null | undefined, now: number): SentinelUntil;
7490
+ /**
7491
+ * An error the native-method transport surfaces verbatim as a JSON-RPC error:
7492
+ * the SDK's request path copies `code` and `data` straight onto the error
7493
+ * response, so no transport-side catch is needed.
7494
+ */
7495
+ declare class McpEventsError extends Error {
7496
+ readonly code: number;
7497
+ readonly data?: Record<string, unknown>;
7498
+ constructor(code: number, message: string, data?: Record<string, unknown>);
7499
+ }
7500
+ interface EventsListRequest {
7501
+ cursor?: string;
7502
+ pageSize?: number;
7503
+ }
7504
+ interface EventsListContext {
7505
+ principal: Principal;
7506
+ }
7507
+ interface EventsListResult {
7508
+ events: EventDefinition[];
7509
+ nextCursor: string | null;
7510
+ }
7511
+ interface EventsSubscribeInput {
7512
+ name: string;
7513
+ arguments: Record<string, unknown>;
7514
+ delivery: {
7515
+ mode: "webhook";
7516
+ url: string;
7517
+ secret: string;
7518
+ };
7519
+ ttlMs?: number | null;
7520
+ /** Refresh/replay handle (null on first subscribe). v1 ignores it: all
7521
+ * events are non-replayable, so it never changes the returned cursor. */
7522
+ cursor?: string | null;
7523
+ }
7524
+ interface EventsSubscribeContext {
7525
+ principal: Principal;
7526
+ store: SentinelStore;
7527
+ resolveProvider: (slug: string) => Promise<SentinelProviderHandle | null>;
7528
+ nowMs?: () => number;
7529
+ /** DI seam (tests): replaces `verifyCallback`'s POST boundary. */
7530
+ verify?: typeof verifyCallback;
7531
+ activeIntervalMs?: number;
7532
+ }
7533
+ interface EventsSubscribeResult {
7534
+ id: `sub_${string}`;
7535
+ refreshBefore: string | null;
7536
+ cursor: string | null;
7537
+ truncated?: boolean;
7538
+ }
7539
+ interface EventsUnsubscribeInput {
7540
+ name: string;
7541
+ arguments: Record<string, unknown>;
7542
+ delivery: {
7543
+ mode: "webhook";
7544
+ url: string;
7545
+ };
7546
+ }
7547
+ interface EventsUnsubscribeContext {
7548
+ principal: Principal;
7549
+ store: SentinelStore;
7550
+ resolveProvider: (slug: string) => Promise<SentinelProviderHandle | null>;
7551
+ }
7552
+ declare function eventsList(r: EventsListRequest, ctx: EventsListContext): Promise<EventsListResult>;
7553
+ declare function eventsSubscribe(input: EventsSubscribeInput, ctx: EventsSubscribeContext): Promise<EventsSubscribeResult>;
7554
+ declare function eventsUnsubscribe(input: EventsUnsubscribeInput, ctx: EventsUnsubscribeContext): Promise<{}>;
7555
+ /**
7556
+ * CloudEvents `SentinelEvent` → the MCP Events wire envelope (official doc
7557
+ * verbatim): `id→eventId`, `type→name`, `time→timestamp`, `data→data` (plus
7558
+ * the `subject`/`summary` projection so the 256 KiB clamp's `{summary,
7559
+ * subject}` replacement never goes blind), and `cursor: null` (v1
7560
+ * non-replayable). No top-level `type` — that field is reserved for protocol
7561
+ * control notifications we never send.
7562
+ */
7563
+ declare function toMcpEvent(event: SentinelEvent): McpEventEnvelope;
7564
+
7565
+ /**
7566
+ * Deterministic MCP Events subscription ids (W-C of
7567
+ * `.plans/sentinel-mcp-events/PLAN.md`, §3 frozen).
7568
+ *
7569
+ * The id is a pure function of the subscription IDENTITY — authenticated
7570
+ * principal + normalized callback URL + event name + subscription arguments —
7571
+ * so the SAME logical subscription always lands on the SAME id. That is what
7572
+ * makes `events/subscribe` idempotent (upsert, never duplicate) and lets
7573
+ * `events/unsubscribe` recompute the id instead of trusting a caller-supplied
7574
+ * one.
7575
+ *
7576
+ * Hashing input is RFC 8785 (JCS) canonical JSON: recursive key sort by
7577
+ * UTF-16 code units, ECMAScript number serialization, Unicode minimization
7578
+ * (literal non-ASCII, control chars escaped). The `args` payload is trustless
7579
+ * input and nested objects are legal, so a plain `JSON.stringify` (key order
7580
+ * dependent) would let `{a:1,b:2}` and `{b:2,a:1}` mint two different
7581
+ * subscriptions for one logical watch — exactly the duplicate the doc warns
7582
+ * against. The canonical form is a single source of truth shared by subscribe
7583
+ * and unsubscribe.
7584
+ */
7585
+ interface SubscriptionIdentity {
7586
+ /** Authenticated principal (`daemon-bearer` or `session:<id>`). */
7587
+ principal: string;
7588
+ /** Callback URL exactly as submitted (identity component; no normalization
7589
+ * beyond what the caller already applied — challenge caching normalizes
7590
+ * separately). */
7591
+ callbackUrl: string;
7592
+ /** Official wire event name, e.g. `github.pull_request.closed`. */
7593
+ eventName: string;
7594
+ /** Subscription arguments (JSON, nested objects legal). */
7595
+ args: Record<string, unknown>;
7596
+ }
7597
+ /**
7598
+ * RFC 8785 (JCS) canonical JSON over a JSON-legal value. Throws on values
7599
+ * JSON cannot carry (`undefined`, functions, non-finite numbers) rather than
7600
+ * silently coercing them — a trustless `args` payload must fail loudly, not
7601
+ * hash to a phantom identity.
7602
+ *
7603
+ * `JSON.stringify` already implements the JCS string and number rules for
7604
+ * well-formed JSON: ECMAScript shortest-round-trip number printing (`-0` →
7605
+ * `"0"`), control-char escaping, literal non-ASCII (Unicode minimization),
7606
+ * and `\uXXXX` for lone surrogates (ES2019 well-formed stringify). Only the
7607
+ * recursive object-key sort is added here.
7608
+ */
7609
+ declare function canonicalizeJcs(value: unknown): string;
7610
+ /** `sub_<hex32>` — sha256 over the JCS canonical identity, first 128 bits. */
7611
+ declare function subscriptionId(identity: SubscriptionIdentity): `sub_${string}`;
7612
+
7613
+ /**
7614
+ * Standard Webhooks `whsec_` signing for webhook egress (W-A of
7615
+ * `.plans/sentinel-mcp-events/PLAN.md`).
7616
+ *
7617
+ * Contract (frozen §3):
7618
+ * - HMAC-SHA256 over `msgId.timestamp.body` (raw bytes; `.update` chained so
7619
+ * the body is never re-encoded — payload arrives as `Uint8Array`, I2).
7620
+ * - Signature print = standard base64 (NOT base64url): `v1,<b64>`.
7621
+ * - HMAC key = the base64 payload DECODED after the `whsec_` prefix.
7622
+ * - Multi-secret: space-separated `v1,<sig>` segments (rotation window).
7623
+ * - Returns ONLY headers — the caller owns the bytes and signs them again
7624
+ * with a fresh timestamp on retry; signing never re-serializes.
7625
+ */
7626
+ interface WebhookSignInput {
7627
+ /** Stable event id (`evt_…` / verification `msg_verification_…`) — same across retries. */
7628
+ msgId: string;
7629
+ /** Seconds, Unix epoch (Standard Webhooks wire format). */
7630
+ timestamp: number;
7631
+ /** Exact bytes — signed once (I2). Caller passes the serialization; signing never re-serializes. */
7632
+ payload: Uint8Array;
7633
+ /** One or, during a rotation window, two secrets (`whsec_…`). */
7634
+ secrets: readonly string[];
7635
+ }
7636
+ type WebhookSignatureHeaders = {
7637
+ "webhook-id": string;
7638
+ "webhook-timestamp": string;
7639
+ "webhook-signature": string;
7640
+ };
7641
+ /**
7642
+ * Encode raw secret bytes into the `whsec_<base64>` wire format.
7643
+ * Inverse of {@link decodeWhsecSecret}.
7644
+ */
7645
+ declare function encodeWhsecSecret(raw: Uint8Array): string;
7646
+ /**
7647
+ * Decode a `whsec_…` secret to its raw HMAC key: standard-base64 payload
7648
+ * after the prefix, which must decode to 24..64 bytes. Returns `null` on any
7649
+ * violation (bad prefix, not base64, length out of range). The canonical
7650
+ * validator for W-C: a submit failing this is `-32602` upstream; egress
7651
+ * surfaces it as a categorized challenge failure.
7652
+ */
7653
+ declare function decodeWhsecSecret(secret: string): Buffer | null;
7654
+ /**
7655
+ * Sign exactly the bytes given. Throws `Error` when any secret fails
7656
+ * {@link decodeWhsecSecret} (callers must have validated upstream; a bad
7657
+ * secret at this point is a programmer error, never silently signed).
7658
+ */
7659
+ declare function signWebhook(input: WebhookSignInput): WebhookSignatureHeaders;
7660
+
6770
7661
  /**
6771
7662
  * SentinelWebhookOutbox — the PERSISTED outbox for `webhook`-target sentinel
6772
7663
  * events (W-B of `.plans/sentinel-mcp-events/PLAN.md`, §4 task 3).
@@ -6887,11 +7778,12 @@ interface SentinelWebhookOutboxOptions {
6887
7778
  }
6888
7779
  /** `sub_<hex32>` — deterministic over (sentinelId, eventId). */
6889
7780
  declare function webhookRequestId(sentinelId: string, eventId: string): `sub_${string}`;
6890
- /** The CloudEvents → MCP-Events-envelope fusion this WP owns (W-C's adapter
6891
- * becomes the canonical owner of the same mapping; this shape is the frozen
6892
- * §3 wire envelope — insertion order stable, so its serialization is
6893
- * byte-stable across restarts). `data` gains `subject`/`summary` so the
6894
- * 256 KiB clamp's `{summary, subject}` replacement never goes blind. */
7781
+ /** The CloudEvents → MCP-Events-envelope fusion. W-C's `mcp-events/adapter.ts`
7782
+ * is now the canonical owner of this mapping (`toMcpEvent`); this alias keeps
7783
+ * the W-B call sites/tests working. The shape is the frozen §3 wire envelope —
7784
+ * insertion order stable, so its serialization is byte-stable across
7785
+ * restarts. `data` gains `subject`/`summary` so the 256 KiB clamp's
7786
+ * `{summary, subject}` replacement never goes blind. */
6895
7787
  declare function toWebhookEnvelope(event: SentinelEvent): McpEventEnvelope;
6896
7788
  declare function createSentinelWebhookOutbox(opts: SentinelWebhookOutboxOptions): SentinelWebhookOutbox;
6897
7789
 
@@ -8259,6 +9151,24 @@ declare function evaluateCostBudget(args: {
8259
9151
  */
8260
9152
 
8261
9153
  type AnySpec = DoctypeSpec<any, any>;
9154
+ /** Build the dead-session restart hook the routing paths share (PR C).
9155
+ * An ended-but-resumable agent-cli row is revived IN PLACE (same id) via
9156
+ * the registry's resume primitive instead of minting a new row — the
9157
+ * sentinel's re-target then no-ops. The flag splits the callers by INTENT:
9158
+ * - the SENTINEL is an AUTOMATIC path — a deliberate end
9159
+ * (operator-completed / steward-*) is never revived in place; it
9160
+ * falls back to today's new-id restart (and the sentinel's own
9161
+ * sessionInfo guard routes deliberate ends to the parent / parking
9162
+ * before this is ever reached).
9163
+ * - INBOUND (watcher + push router) is a HUMAN writing to the session —
9164
+ * explicit intent, so a deliberate end may still be revived in place. */
9165
+ declare function makeRestartForRouting(deps: {
9166
+ sessions: SessionsRegistry;
9167
+ resolveAgentAdapter: AgentAdapterResolver | undefined;
9168
+ }, config: {
9169
+ name: string;
9170
+ allowDeliberateEnd: boolean;
9171
+ }): (id: string) => Promise<string>;
8262
9172
  interface CreateGatewayOptions {
8263
9173
  /** Absolute path to the workspace dir. */
8264
9174
  workspace: string;
@@ -8653,6 +9563,19 @@ interface GatewayHandle {
8653
9563
  continueInterruptedOnBoot(opts?: {
8654
9564
  isServed?: (desc: SessionDescriptor) => boolean;
8655
9565
  }): Promise<ContinueOnBootSummary>;
9566
+ /** Daemon-startup backfill for the per-session index sidecars
9567
+ * (`session-index.ts`): create a compact `index.json` for every session dir
9568
+ * that lacks one, recovering the last prompt/output from the transcript
9569
+ * tail (never a whole-file parse). Synchronous and best-effort — a store
9570
+ * with thousands of sessions pays one readdir plus one bounded read per
9571
+ * missing index. serve.ts calls this once at boot so `agentproto sessions
9572
+ * find`/`recap` answer instantly even for sessions that predate the
9573
+ * sidecar. */
9574
+ backfillSessionIndexes(): {
9575
+ scanned: number;
9576
+ created: number;
9577
+ skipped: number;
9578
+ };
8656
9579
  stop(): Promise<void>;
8657
9580
  }
8658
9581
  /**
@@ -8669,4 +9592,4 @@ interface GatewayHandle {
8669
9592
  */
8670
9593
  declare function createGateway(opts: CreateGatewayOptions): Promise<GatewayHandle>;
8671
9594
 
8672
- export { ActivityListFilter, type ActivityPolicyLister, type ActivityProjector, type ActivityProjectorRegistry, type ActivityProjectorSession, ActivityRecord, type ActivityWorkflowLister, AdapterAuthDescriptor, type AdapterCapabilitiesLister, type AdapterInstallResult, type AdapterListEntry, type AgentAdapterInstaller, type AgentAdapterLister, type AgentAdapterResolver, AgentSessionLike, AgentStreamEvent, type AttachSandboxOpts, type AttachSandboxResult, 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, CLAMP_LIMIT_BYTES, CONTINUE_PROMPT_SOURCE, CanonicalPosture, type CapabilitiesInventory, type CapabilitiesInventoryMcp, type CapabilitiesInventorySkills, type CatalogModelsLister, CatalogModelsQuery, CatalogModelsResponse, type CatalogProviderModel, type CatalogProviderModelsQuery, type CatalogProviderModelsResponse, type CatalogProviderPricing, type ChallengeFailureReason, type ChallengeOutcome, type ClaudeNativeRef, CompletionPolicySupervisor, type ComposeCandidate, ContextProfile, type ContinueInterruptedMode, type ContinueInterruptedOutcome, type ContinueInterruptedResult, type ContinueInterruptedSkipReason, type ContinueOnBootSummary, type ConversationIndexRecord, type ConversationNativeRef, type CostBudgetDecision, type CrashDetectSummary, type CrashReaperRegistry, type CreateGatewayOptions, type CreateJoinTokenInput, type CreateReviewRunnerOptions, type CreatedJoinToken, DEAD_SESSION_STATUSES, DEFAULT_ALWAYS_ON_TOOLS, DEFAULT_BUCKET, DEFAULT_CONTINUE_PROMPT, DEFAULT_HOST_LOAD_BUDGET_MS, DEFAULT_HOST_LOAD_THRESHOLDS, DEFAULT_ORCHESTRATOR_TOOLS, DEVICE_PROMPT_PATH_PREFIX, type DaemonReviewerHostDeps, DeclaredAdapterOption, type DeclaredAdapterPreset, DefaultsAdapterAuthConfig, type DeliveryOutcome, type DeliveryReplay, type DeliveryState, type Device, type DeviceKind, type DeviceMirrorSyncResult, type DeviceMirrorTarget, type DevicePromptSessionsLike, type DeviceRegistry, type DeviceRole, type DiskLoad, type EagerResumeSummary, type EgressDispatcher, type EnableInput, type EnableResult, type FetchHostTurnsResult, type FindComposeCandidateInput, type ForwardHttpRequest, type ForwardHttpResponse, GC_REAPABLE_STATES, type GatewayHandle, type GhRunner, HOSTS_VERSION, HOST_HANDSHAKE_REMEDIATION_HINT, HOST_SCOPE_HEADER, type HarnessPreset, type HarnessPresetValidationDeps, HarnessPresetValidationError, type HarnessPresetsFile, type HermesNativeRef, type HostEventRecord, type HostJoinMeta, type HostLoadCpu, type HostLoadDetail, type HostLoadMemory, type HostLoadReport, type HostLoadService, type HostLoadSwap, type HostLoadThresholds, type HostProbes, type HostProcess, type HostProcessOwner, type HostRecord, type HostRegistry, type HostRegistryDeps, type HostSessionRollup, type HostWarning, type HostWarningKind, 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, JOIN_TOKENS_VERSION, type JoinTokenRecord, type JoinTokenRegistry, type JoinTokenRegistryDeps, LEGACY_SESSIONS_FILE, type LedgerAnnotations, type LedgerEntry, type LedgerHostMeta, type LlmEndpointDescriptor, type LlmEndpointStatus, type LlmEndpointStatusReport, type LocatedConversation, type LocatedConversationByPath, MAX_ATTEMPTS, MAX_AUTO_CONTINUE_ATTEMPTS, MCP_APP_BRIDGE_SCRIPT, type McpCredentialDeps, type McpEventEnvelope, type MeasurableTool, type MeasuredToolEntry, MessageKind, MessageUrgency, type MigrationMarker, type ModelRolesInput, type ModelRolesOutput, type NormalizeInboundResult, type OpenPrResolver, type OrchestratorGatewayDeps, type OrchestratorInjection, type OrchestratorInjector, type OrchestratorInjectorDeps, type OrchestratorMcpServerFactory, type OrchestratorScope, type OrphanReaperRegistry, POSTURE_NATIVE_ALIASES, POSTURE_PREAMBLES, type PersistedOutboxRow, PolicyRunState, Posture, type PostureResolution, PrLookupError, type PrLookupErrorCode, PrResolvedState, type PrStateResolver, type PrStatusSnapshot, type PresetInfo, type ProjectBrowserToolsOptions, type ProjectedBrowserTool, type ProjectedBrowserTools, type ProjectedProvider, type ProjectedToolResult, type PromptHostSessionInput, type PromptHostSessionResult, ProvisionInFlight, QuotaReadableProfile, type RegisterBrainToolsOptions, type RegisterDeviceToolsOptions, type RegisterPairingToolsOptions, type RegisterReviewToolsOptions, type RegisterWebSearchToolsOptions, RemainingQuotaReader, type RemoteStatus, type ResolveNativeLinkInput, ResolvedAuthSpec, ResolvedModelRole, type ReuseResolution, type ReviewComposeContext, type ReviewLedger, type ReviewLedgerFilter, type ReviewRun, type ReviewRunInput, type ReviewRunStatus, type ReviewRunner, type ReviewSignature, type ReviewSigningKey, type ReviewerRunResult, type ReviewerSessionHost, type RouteAwareLaunchConfig, type RouteAwareLaunchConfigInput, RouteSpec, type RuntimeMeta, SIGN_NAMESPACE, 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, type SentinelMatchClause, type SentinelSpec, type SentinelStatus, type SentinelTarget, type SentinelUntil, type SentinelView, type SentinelWebhookOutbox, type SentinelWebhookOutboxOptions, type SentinelWebhookOutboxRow, type SentinelWebhookOutboxStatus, SessionDescriptor, SessionEndReason, SessionMessage, type SessionMessageSentRecord, type SessionObserver, SessionUsage, type SessionUsageWithSubtree, type SessionWaitEvent, type SessionWaitResult, SessionsRegistry, type SkillPackInventoryEntry, type SkillsByHarnessEntry, SpawnDefaultsConfig, SsrfFetchError, type SsrfFetchInit, type SsrfFetchReason, type SsrfFetchResult, type StallWatchdogRegistry, type StallWatchdogSummary, type SubtreeChildUsage, type SubtreeUsageTotals, TaskLedger, type ToolListMeasurement, type TransmitterBinding, type TransmitterBindingStore, type TunnelDescriptor, type TunnelProvider, type TunnelStatus, UsageReadContext, UsageReadResult, UsageRollup, UsageSnapshotRecord, UserPreset, type VerifyCallbackInput, type VerifySignedAttestationResult, type WatcherDescriptor, type WatcherStartInput, type WebSearchInput, type WebSearchOutput, type WebSearchResult, type WebhookSignInput, type WebhookSignatureHeaders, type WorkspaceBrainSubscriber, type WorkspaceBrainSubscriberOptions, type WorkspaceBrains, WorkspaceFs, WorktreeAutoReclaimer, WorktreeField, type WorktreeGcClass, type WorktreeGcOutcomeView, type WorktreeGcPlanEntryView, type WorktreeGcReclaimReason, type WorktreeGcResult, type WorktreeGcRunInput, type WorktreeGcRunner, WorktreeIsolationMode, WorktreeProvisioner, type WorktreeStatusLister, type WorktreeStatusView, addHarnessPreset, allowedSignersLine, appendConversationRecord, attachSandbox, bucketDir, bucketSessionsFile, bucketTranscriptDir, buildCatalogProviderModels, buildHostLoadReport, buildMcpConfigSnippet, buildRouteAwareLaunchConfig, canonicalForModeId, challengeCacheSize, challengeReasonForSsrf, claudeProjectSlug, collectGcCandidates, collectHostSample, composeSessionObservers, composedFromRangeSha, computeHostWarnings, continueInterruptedSessions, continueSkipReason, conversationIndexPath, createActivityProjector, createDaemonReviewerHost, createDefaultHostProbes, createDeviceRegistry, createFileStepCache, createGateway, createHostLoadService, createHostRegistry, createInboundEndpointStore, createJoinTokenRegistry, createOrchestratorInjector, createOrchestratorMcpServerFactory, createPrProvenanceReconciler, createReviewLaneExecutor, createReviewLedger, createReviewPackLoader, createReviewRunner, createScopeTokenRegistry, createSentinelWebhookOutbox, createWorkspaceBrainSubscriber, createWorkspaceBrains, daemonRegistryDir, declaredPresetToProviderPreset, decodeWhsecSecret, defaultBrowserAdapterIds, defaultBrowserAdapterResolution, defaultReviewKeysDir, defaultReviewLedgerRoot, defaultReviewPackCacheDir, defineBraveSearchHttpDriver, defineSerperHttpDriver, deliverEventEnvelope, deliveryBackoffDelay, describeOwner, encodeWhsecSecret, enrichRollupWithProviderQuota, enrichWithRemainingQuota, ensureReviewSigningKey, envelopeClampedBytes, evaluateCostBudget, execGh, extractHelpSection, fetchHostTurns, fetchPrStatus, fileExists, findComposeCandidate, findConversationRecord, findNativeMode, findPrForCommit, formatToolCall, formatToolResult, getDefaultHarnessPreset, getHarnessPreset, getHostLoadService, getMcpCredentialDeps, getToolHelp, githubRepoOf, harnessPresetsPath, hostPlaceholders, hostRecordToMirrorRecord, injectMcpAppBridge, isAgentCliAuthConfigured, isNoSessionPromptFailure, isPubliclyRoutable, isSafeBucketSlug, listBuckets, listHarnessPresets, listPresets, listToolHelpTopics, loadHarnessPresets, loadWorkspaceModelRoles, locateConversationByNativePath, locateConversationBySessionId, makeBrowserAdapterLister, makeSandboxCredsStore, makeSandboxResolver, measureTool, measureToolList, migrateLegacySessionsFile, migrationMarkerPath, mirrorCursorForSession, monitorPolicyWait, monitorSessionWait, narrowOrchestratorTools, normalizeCallbackUrl, normalizeInbound, normalizeModeId, normalizeRemote, parsePrUrl, prHeadSha, projectBrowserTools, promptDeviceSession, promptHostSession, readConversationIndex, readDaemonRegistry, readHostsSnapshot, readRegisteredSlugs, readRuntimeMeta, readSandboxLedger, readSessionForBrain, readUsageSnapshots, reapGcEntry, reapOrphanedDescendants, reconcileSandboxLedger, recordSandboxBoot, recordSandboxLiveness, recordSandboxOrigin, recordSandboxState, registerBrainTools, registerBuiltinRoutes, registerDeviceTools, registerPairingTools, registerReviewTools, registerSandboxAttachTool, registerWebSearchTools, removeHarnessPreset, removeSandboxLedgerEntry, repoSlug, resetChallengeCacheForTests, resolveBucketSlug, resolveDevicePromptMapping, resolveEffectiveLlmEndpointFlag, resolveNativeLink, resolvePosture, resolvePrincipal, resolveReuseFromLedger, resolveReviewerPreset, rollupSessionSubtree, runContinueOnBootPass, runCrashDetectPass, runEagerResumePass, runIdleReapPass, runShellLane, runStallWatchdogPass, sandboxLedgerPath, seedWalkForTranscript, serializeEnvelope, setDefaultPreset, setEgressDispatcherForTests, setMcpCredentialDeps, signAttestation, signWebhook, ssrfFetch, sweepStaleDaemonRegistry, sweepStaleRuntimeMetas, syncDeviceMirror, toWebhookEnvelope, toWorktreeStatusView, unlinkDaemonRegistryEntry, unlinkRuntimeMeta, updateHarnessPreset, upsertSandboxLedger, verifyCallback, verifyInboundSignature, verifySignedAttestation, webSearchTool, webhookRequestId, withPr, withPrStatus, writeDaemonRegistryEntry };
9595
+ export { ActivityListFilter, type ActivityPolicyLister, type ActivityProjector, type ActivityProjectorRegistry, type ActivityProjectorSession, ActivityRecord, type ActivityWorkflowLister, AdapterAuthDescriptor, type AdapterCapabilitiesLister, type AdapterInstallResult, type AdapterListEntry, type AgentAdapterInstaller, type AgentAdapterLister, type AgentAdapterResolver, AgentSessionLike, AgentStreamEvent, type ArgumentsResult, type AttachSandboxOpts, type AttachSandboxResult, 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, CLAMP_LIMIT_BYTES, CONTINUE_PROMPT_SOURCE, CanonicalPosture, type CapabilitiesInventory, type CapabilitiesInventoryMcp, type CapabilitiesInventorySkills, type CatalogModelsLister, CatalogModelsQuery, CatalogModelsResponse, type CatalogProviderModel, type CatalogProviderModelsQuery, type CatalogProviderModelsResponse, type CatalogProviderPricing, type ChallengeFailureReason, type ChallengeOutcome, type ClaudeNativeRef, CompletionPolicySupervisor, type ComposeCandidate, ContextProfile, type ContinueInterruptedMode, type ContinueInterruptedOutcome, type ContinueInterruptedResult, type ContinueInterruptedSkipReason, type ContinueOnBootSummary, type ConversationIndexRecord, type ConversationNativeRef, type CostBudgetDecision, type CrashDetectSummary, type CrashReaperRegistry, type CreateGatewayOptions, type CreateJoinTokenInput, type CreateReviewRunnerOptions, type CreatedJoinToken, DEAD_SESSION_STATUSES, DEFAULT_ALWAYS_ON_TOOLS, DEFAULT_BUCKET, DEFAULT_CONTINUE_PROMPT, DEFAULT_HOST_LOAD_BUDGET_MS, DEFAULT_HOST_LOAD_THRESHOLDS, DEFAULT_ORCHESTRATOR_TOOLS, DEFAULT_TTL_MS, DEVICE_PROMPT_PATH_PREFIX, type DaemonReviewerHostDeps, DeclaredAdapterOption, type DeclaredAdapterPreset, DefaultsAdapterAuthConfig, type DeliveryOutcome, type DeliveryReplay, type DeliveryState, type Device, type DeviceKind, type DeviceMirrorSyncResult, type DeviceMirrorTarget, type DevicePromptSessionsLike, type DeviceRegistry, type DeviceRole, type DiskLoad, EVENT_REGISTRY, type EagerResumeSummary, type EgressDispatcher, type EnableInput, type EnableResult, type EventDefinition, type EventRegistration, type EventsListContext, type EventsListRequest, type EventsListResult, type EventsSubscribeContext, type EventsSubscribeInput, type EventsSubscribeResult, type EventsUnsubscribeContext, type EventsUnsubscribeInput, FOLLOW_EVENTS, type FetchHostTurnsResult, type FindComposeCandidateInput, type FollowEvent, type ForwardHttpRequest, type ForwardHttpResponse, GC_REAPABLE_STATES, GITHUB_SCHEME, type GatewayHandle, type GhRunner, HOSTS_VERSION, HOST_HANDSHAKE_REMEDIATION_HINT, HOST_SCOPE_HEADER, type HarnessPreset, type HarnessPresetValidationDeps, HarnessPresetValidationError, type HarnessPresetsFile, type HermesNativeRef, type HostEventRecord, type HostJoinMeta, type HostLoadCpu, type HostLoadDetail, type HostLoadMemory, type HostLoadReport, type HostLoadService, type HostLoadSwap, type HostLoadThresholds, type HostProbes, type HostProcess, type HostProcessOwner, type HostRecord, type HostRegistry, type HostRegistryDeps, type HostSessionRollup, type HostWarning, type HostWarningKind, INBOUND_PROVIDERS, INDEX_DEFAULT_LIMIT, INDEX_MAX_OUTPUT, INDEX_MAX_PROMPT, INDEX_TAIL_BYTES, 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 InternalEventMeta, JOIN_TOKENS_VERSION, type JoinTokenRecord, type JoinTokenRegistry, type JoinTokenRegistryDeps, LEGACY_SESSIONS_FILE, type LedgerAnnotations, type LedgerEntry, type LedgerHostMeta, type LlmEndpointDescriptor, type LlmEndpointStatus, type LlmEndpointStatusReport, type LocatedConversation, type LocatedConversationByPath, MAX_ATTEMPTS, MAX_AUTO_CONTINUE_ATTEMPTS, MAX_TTL_MS, MCP_APP_BRIDGE_SCRIPT, MIN_TTL_MS, type McpCredentialDeps, type McpEventEnvelope, McpEventsError, type MeasurableTool, type MeasuredToolEntry, MessageKind, MessageUrgency, type MigrationMarker, type ModelRolesInput, type ModelRolesOutput, type NormalizeInboundResult, type OpenPrResolver, type OrchestratorGatewayDeps, type OrchestratorInjection, type OrchestratorInjector, type OrchestratorInjectorDeps, type OrchestratorMcpServerFactory, type OrchestratorScope, type OrphanReaperRegistry, POSTURE_NATIVE_ALIASES, POSTURE_PREAMBLES, type PersistedOutboxRow, PolicyRunState, Posture, type PostureResolution, PrLookupError, type PrLookupErrorCode, PrResolvedState, type PrStateResolver, type PrStatusSnapshot, type PresetInfo, type Principal, type ProjectBrowserToolsOptions, type ProjectedBrowserTool, type ProjectedBrowserTools, type ProjectedProvider, type ProjectedToolResult, type PromptHostSessionInput, type PromptHostSessionResult, ProvisionInFlight, QuotaReadableProfile, type RegisterBrainToolsOptions, type RegisterDeviceToolsOptions, type RegisterPairingToolsOptions, type RegisterReviewToolsOptions, type RegisterWebSearchToolsOptions, RemainingQuotaReader, type RemoteStatus, type ResolveNativeLinkInput, ResolvedAuthSpec, ResolvedModelRole, type ReuseResolution, type ReviewComposeContext, type ReviewLedger, type ReviewLedgerFilter, type ReviewRun, type ReviewRunInput, type ReviewRunStatus, type ReviewRunner, type ReviewSignature, type ReviewSigningKey, type ReviewerRunResult, type ReviewerSessionHost, type RouteAwareLaunchConfig, type RouteAwareLaunchConfigInput, RouteSpec, type RuntimeMeta, SIGN_NAMESPACE, 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 SchemeRegistry, type ScopeTokenRegistry, type SentinelMatchClause, type SentinelSpec, type SentinelStatus, type SentinelTarget, type SentinelUntil, type SentinelView, type SentinelWebhookOutbox, type SentinelWebhookOutboxOptions, type SentinelWebhookOutboxRow, type SentinelWebhookOutboxStatus, SessionDescriptor, SessionEndReason, type SessionFollow, type SessionFollowHandle, type SessionFollowStore, type SessionIndexEntry, SessionMessage, type SessionMessageSentRecord, type SessionObserver, type SessionRecap, SessionUsage, type SessionUsageWithSubtree, type SessionWaitEvent, type SessionWaitResult, SessionsRegistry, type SkillPackInventoryEntry, type SkillsByHarnessEntry, SpawnDefaultsConfig, SsrfFetchError, type SsrfFetchInit, type SsrfFetchReason, type SsrfFetchResult, type StallWatchdogRegistry, type StallWatchdogSummary, type SubscriptionIdentity, type SubtreeChildUsage, type SubtreeUsageTotals, TaskLedger, type ToolListMeasurement, type TranscriptPrompt, type TranscriptTail, type TransmitterBinding, type TransmitterBindingStore, type TunnelDescriptor, type TunnelProvider, type TunnelStatus, UsageReadContext, UsageReadResult, UsageRollup, UsageSnapshotRecord, UserPreset, type VerifyCallbackInput, type VerifySignedAttestationResult, type WatcherDescriptor, type WatcherStartInput, type WebSearchInput, type WebSearchOutput, type WebSearchResult, type WebhookSignInput, type WebhookSignatureHeaders, type WorkspaceBrainSubscriber, type WorkspaceBrainSubscriberOptions, type WorkspaceBrains, WorkspaceFs, WorktreeAutoReclaimer, WorktreeField, type WorktreeGcClass, type WorktreeGcOutcomeView, type WorktreeGcPlanEntryView, type WorktreeGcReclaimReason, type WorktreeGcResult, type WorktreeGcRunInput, type WorktreeGcRunner, WorktreeIsolationMode, WorktreeProvisioner, type WorktreeStatusLister, type WorktreeStatusView, addHarnessPreset, allowedSignersLine, appendConversationRecord, attachSandbox, backfillSessionIndexes, bucketDir, bucketSessionsFile, bucketTranscriptDir, buildCatalogProviderModels, buildHostLoadReport, buildMcpConfigSnippet, buildRouteAwareLaunchConfig, buildSessionRecap, canonicalForModeId, canonicalizeJcs, challengeCacheSize, challengeReasonForSsrf, claudeProjectSlug, collectGcCandidates, collectHostSample, composeSessionObservers, composedFromRangeSha, computeHostWarnings, computeRefreshBefore, continueInterruptedSessions, continueSkipReason, conversationIndexPath, createActivityProjector, createDaemonReviewerHost, createDefaultHostProbes, createDeviceRegistry, createFileStepCache, createGateway, createHostLoadService, createHostRegistry, createInboundEndpointStore, createJoinTokenRegistry, createOrchestratorInjector, createOrchestratorMcpServerFactory, createPrProvenanceReconciler, createReviewLaneExecutor, createReviewLedger, createReviewPackLoader, createReviewRunner, createScopeTokenRegistry, createSentinelWebhookOutbox, createSessionFollowStore, createWorkspaceBrainSubscriber, createWorkspaceBrains, daemonBearerPrincipal, daemonRegistryDir, declaredPresetToProviderPreset, decodeWhsecSecret, defaultBrowserAdapterIds, defaultBrowserAdapterResolution, defaultReviewKeysDir, defaultReviewLedgerRoot, defaultReviewPackCacheDir, defaultTranscriptBaseDir, defineBraveSearchHttpDriver, defineSerperHttpDriver, deliverEventEnvelope, deliveryBackoffDelay, deriveIndexFromTranscript, describeOwner, encodeWhsecSecret, enrichRollupWithProviderQuota, enrichWithRemainingQuota, ensureReviewSigningKey, envelopeClampedBytes, evaluateCostBudget, eventsList, eventsSubscribe, eventsUnsubscribe, execGh, extractHelpSection, fetchHostTurns, fetchPrStatus, fileExists, findComposeCandidate, findConversationRecord, findEventDefinition, findNativeMode, findPrForCommit, formatToolCall, formatToolResult, getDefaultHarnessPreset, getHarnessPreset, getHostLoadService, getMcpCredentialDeps, getToolHelp, githubRepoOf, harnessPresetsPath, hostPlaceholders, hostRecordToMirrorRecord, indexEntryFromDescriptor, injectMcpAppBridge, isAgentCliAuthConfigured, isNoSessionPromptFailure, isPubliclyRoutable, isSafeBucketSlug, listBuckets, listHarnessPresets, listPresets, listToolHelpTopics, loadHarnessPresets, loadWorkspaceModelRoles, locateConversationByNativePath, locateConversationBySessionId, makeBrowserAdapterLister, makeRestartForRouting, makeSandboxCredsStore, makeSandboxResolver, matchesSessionQuery, measureTool, measureToolList, migrateLegacySessionsFile, migrationMarkerPath, mirrorCursorForSession, monitorPolicyWait, monitorSessionWait, narrowOrchestratorTools, normalizeCallbackUrl, normalizeInbound, normalizeModeId, normalizeRemote, parsePrUrl, prHeadSha, projectBrowserTools, promptDeviceSession, promptHostSession, readAllSessionIndexes, readConversationIndex, readDaemonRegistry, readHostsSnapshot, readRegisteredSlugs, readRuntimeMeta, readSandboxLedger, readSessionForBrain, readSessionIndex, readTranscriptTail, readUsageSnapshots, reapGcEntry, reapOrphanedDescendants, reconcileSandboxLedger, recordSandboxBoot, recordSandboxLiveness, recordSandboxOrigin, recordSandboxState, registerBrainTools, registerBuiltinRoutes, registerDeviceTools, registerPairingTools, registerReviewTools, registerSandboxAttachTool, registerWebSearchTools, removeHarnessPreset, removeSandboxLedgerEntry, repoSlug, resetChallengeCacheForTests, resolveBucketSlug, resolveDevicePromptMapping, resolveEffectiveLlmEndpointFlag, resolveNativeLink, resolvePosture, resolvePrincipal, resolveReuseFromLedger, resolveReviewerPreset, rollupSessionSubtree, runContinueOnBootPass, runCrashDetectPass, runEagerResumePass, runIdleReapPass, runShellLane, runStallWatchdogPass, sandboxLedgerPath, searchSessionIndexes, seedWalkForTranscript, serializeEnvelope, sessionEventsPath, sessionIndexPath, sessionPrincipal, sessionTranscriptDir, setDefaultPreset, setDefaultSessionsBaseDir, setEgressDispatcherForTests, setMcpCredentialDeps, signAttestation, signWebhook, ssrfFetch, subscriptionId, sweepStaleDaemonRegistry, sweepStaleRuntimeMetas, syncDeviceMirror, tenantScope, toMcpEvent, toWebhookEnvelope, toWorktreeStatusView, unlinkDaemonRegistryEntry, unlinkRuntimeMeta, untilForTtl, updateHarnessPreset, upsertSandboxLedger, validateAgainstInputSchema, verifyCallback, verifyInboundSignature, verifySignedAttestation, webSearchTool, webhookRequestId, wireSessionFollow, withPr, withPrStatus, writeDaemonRegistryEntry, writeSessionIndex };