@gajae-code/coding-agent 0.15.4 → 0.15.6

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.
Files changed (174) hide show
  1. package/CHANGELOG.md +46 -2
  2. package/dist/types/async/job-manager.d.ts +83 -0
  3. package/dist/types/cli/auth-gateway-cli.d.ts +17 -0
  4. package/dist/types/cli/model-presets-cli.d.ts +9 -0
  5. package/dist/types/cli/update-cli.d.ts +27 -5
  6. package/dist/types/commands/auth-gateway.d.ts +3 -0
  7. package/dist/types/commands/gc.d.ts +13 -0
  8. package/dist/types/commands/model-presets.d.ts +21 -0
  9. package/dist/types/config/autorouting-tier-map.d.ts +99 -0
  10. package/dist/types/config/file-lock.d.ts +49 -2
  11. package/dist/types/config/internal/model-preset-registry-test-state.d.ts +4 -0
  12. package/dist/types/config/internal/model-preset-registry-test-support.d.ts +3 -0
  13. package/dist/types/config/keybindings.d.ts +3 -2
  14. package/dist/types/config/model-preset-registry.d.ts +368 -0
  15. package/dist/types/config/model-profile-activation.d.ts +39 -0
  16. package/dist/types/config/model-profiles.d.ts +5 -3
  17. package/dist/types/config/model-registry.d.ts +11 -5
  18. package/dist/types/config/settings-schema.d.ts +9 -0
  19. package/dist/types/coordinator-mcp/model-preset.d.ts +7 -5
  20. package/dist/types/coordinator-mcp/projection-scan.d.ts +46 -0
  21. package/dist/types/extensibility/extensions/types.d.ts +4 -4
  22. package/dist/types/extensibility/shared-events.d.ts +2 -0
  23. package/dist/types/gjc-runtime/empty-delete-gc.d.ts +58 -0
  24. package/dist/types/gjc-runtime/gc-runtime.d.ts +2 -0
  25. package/dist/types/gjc-runtime/session-state-lock.d.ts +35 -6
  26. package/dist/types/gjc-runtime/session-state-sidecar.d.ts +6 -0
  27. package/dist/types/index.d.ts +1 -0
  28. package/dist/types/main.d.ts +3 -1
  29. package/dist/types/modes/components/jobs-overlay-model.d.ts +4 -2
  30. package/dist/types/modes/jobs-observer.d.ts +36 -0
  31. package/dist/types/sdk/broker/broker.d.ts +3 -0
  32. package/dist/types/sdk/bus/kind-aware-reconciliation.d.ts +3 -0
  33. package/dist/types/sdk/bus/prompt-reconciliation.d.ts +4 -0
  34. package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +8 -1
  35. package/dist/types/sdk/cli/session-cli.d.ts +42 -1
  36. package/dist/types/sdk/client/discovery.d.ts +1 -0
  37. package/dist/types/sdk/host/host.d.ts +2 -0
  38. package/dist/types/sdk/host/model-pin.d.ts +7 -2
  39. package/dist/types/sdk/host/sdk-run-capability.d.ts +1 -0
  40. package/dist/types/sdk/host/session-runtime.d.ts +19 -1
  41. package/dist/types/sdk/prompt-deadline-manager.d.ts +11 -1
  42. package/dist/types/sdk/protocol/adapter-validation.d.ts +2 -0
  43. package/dist/types/sdk/router/session-router.d.ts +9 -0
  44. package/dist/types/session/account-inventory.d.ts +1 -0
  45. package/dist/types/session/agent-session.d.ts +19 -5
  46. package/dist/types/session/fold-coordinator.d.ts +201 -0
  47. package/dist/types/session/internal/managed-session-storage.d.ts +4 -3
  48. package/dist/types/session/sdk-run-capability-internal.d.ts +7 -0
  49. package/dist/types/session/sdk-run-capability.d.ts +2 -0
  50. package/dist/types/telemetry/control.d.ts +11 -0
  51. package/dist/types/telemetry/events.d.ts +20 -0
  52. package/dist/types/telemetry/index.d.ts +3 -0
  53. package/dist/types/telemetry/transport.d.ts +22 -0
  54. package/dist/types/tools/bash-interactive.d.ts +23 -0
  55. package/dist/types/tools/index.d.ts +6 -5
  56. package/dist/types/tools/path-utils.d.ts +5 -6
  57. package/dist/types/tools/tmux-self-injection-guard.d.ts +15 -0
  58. package/dist/types/web/search/providers/base.d.ts +9 -4
  59. package/dist/types/web/search/providers/xai.d.ts +2 -1
  60. package/dist/types/web/search/types.d.ts +14 -0
  61. package/package.json +10 -7
  62. package/scripts/generate-hotkeys-docs.ts +4 -0
  63. package/scripts/generate-sdk-operation-inventory.ts +3 -3
  64. package/src/async/job-manager.ts +671 -39
  65. package/src/cli/auth-broker-cli.ts +40 -12
  66. package/src/cli/auth-gateway-cli.ts +273 -97
  67. package/src/cli/config-cli.ts +2 -2
  68. package/src/cli/fast-help.ts +3 -0
  69. package/src/cli/model-presets-cli.ts +100 -0
  70. package/src/cli/update-cli.ts +142 -6
  71. package/src/cli.ts +6 -2
  72. package/src/commands/auth-gateway.ts +12 -8
  73. package/src/commands/gc.ts +19 -0
  74. package/src/commands/model-presets.ts +24 -0
  75. package/src/commands/sdk.ts +5 -0
  76. package/src/config/autorouting-tier-map.ts +33 -0
  77. package/src/config/file-lock-gc.ts +9 -4
  78. package/src/config/file-lock.ts +775 -59
  79. package/src/config/internal/model-preset-registry-test-state.ts +28 -0
  80. package/src/config/internal/model-preset-registry-test-support.ts +11 -0
  81. package/src/config/keybindings.ts +6 -2
  82. package/src/config/model-preset-registry.ts +2799 -0
  83. package/src/config/model-profile-activation.ts +115 -28
  84. package/src/config/model-profile-contract.ts +4 -1
  85. package/src/config/model-profiles.ts +56 -14
  86. package/src/config/model-registry.ts +1028 -123
  87. package/src/config/settings-schema.ts +11 -0
  88. package/src/config/settings.ts +6 -1
  89. package/src/coordinator-mcp/model-preset.ts +32 -17
  90. package/src/coordinator-mcp/policy.ts +1 -1
  91. package/src/coordinator-mcp/projection-scan.ts +571 -0
  92. package/src/coordinator-mcp/server.ts +19 -24
  93. package/src/coordinator-mcp/session-reaper.ts +9 -3
  94. package/src/extensibility/extensions/loader.ts +0 -1
  95. package/src/extensibility/extensions/types.ts +4 -2
  96. package/src/extensibility/gjc-plugins/runtime-adapters.ts +1 -0
  97. package/src/extensibility/shared-events.ts +2 -0
  98. package/src/gjc-runtime/empty-delete-gc.ts +301 -0
  99. package/src/gjc-runtime/gc-render.ts +29 -0
  100. package/src/gjc-runtime/gc-runtime.ts +174 -11
  101. package/src/gjc-runtime/launch-worktree.ts +44 -7
  102. package/src/gjc-runtime/ralplan-runtime.ts +14 -1
  103. package/src/gjc-runtime/session-state-lock.ts +1242 -141
  104. package/src/gjc-runtime/session-state-sidecar.ts +76 -3
  105. package/src/gjc-runtime/tmux-sessions.ts +145 -48
  106. package/src/index.ts +1 -0
  107. package/src/internal-urls/docs-index.generated.ts +14 -13
  108. package/src/lsp/config.ts +4 -3
  109. package/src/lsp/path-trust.ts +12 -6
  110. package/src/main.ts +9 -2
  111. package/src/modes/acp/acp-agent.ts +11 -5
  112. package/src/modes/components/jobs-overlay-model.ts +99 -16
  113. package/src/modes/components/model-selector.ts +158 -18
  114. package/src/modes/components/status-line/segments.ts +6 -1
  115. package/src/modes/controllers/extension-ui-controller.ts +1 -1
  116. package/src/modes/controllers/input-controller.ts +23 -6
  117. package/src/modes/interactive-mode.ts +14 -1
  118. package/src/modes/jobs-observer.ts +149 -16
  119. package/src/modes/prompt-action-autocomplete.ts +26 -47
  120. package/src/modes/runtime-init.ts +1 -1
  121. package/src/modes/utils/injected-user-submission.ts +15 -1
  122. package/src/prompts/tools/bash.md +2 -2
  123. package/src/prompts/tools/fold-receipt.md +3 -0
  124. package/src/prompts/tools/job.md +1 -1
  125. package/src/sdk/acp/adapter.ts +17 -2
  126. package/src/sdk/broker/broker.ts +48 -21
  127. package/src/sdk/broker/lifecycle.ts +32 -6
  128. package/src/sdk/bus/chat-daemon-control.ts +2 -2
  129. package/src/sdk/bus/chat-daemon-runtime.ts +11 -1
  130. package/src/sdk/bus/kind-aware-reconciliation.ts +46 -8
  131. package/src/sdk/bus/prompt-reconciliation.ts +33 -6
  132. package/src/sdk/bus/slack-conversation.ts +5 -1
  133. package/src/sdk/bus/telegram-daemon-contract.ts +8 -1
  134. package/src/sdk/cli/session-cli.ts +161 -5
  135. package/src/sdk/client/discovery.ts +3 -1
  136. package/src/sdk/host/control/dispatch.ts +3 -0
  137. package/src/sdk/host/host.ts +7 -0
  138. package/src/sdk/host/model-pin.ts +185 -25
  139. package/src/sdk/host/sdk-run-capability.ts +1 -0
  140. package/src/sdk/host/session-runtime.test.ts +1240 -107
  141. package/src/sdk/host/session-runtime.ts +1029 -115
  142. package/src/sdk/prompt-deadline-manager.ts +16 -1
  143. package/src/sdk/protocol/adapter-validation.ts +27 -0
  144. package/src/sdk/protocol/operation-inventory.generated.json +2 -2
  145. package/src/sdk/protocol/operation-registry.ts +4 -1
  146. package/src/sdk/router/session-router.ts +297 -111
  147. package/src/sdk/session.ts +83 -12
  148. package/src/session/account-inventory.ts +27 -11
  149. package/src/session/agent-session.ts +887 -95
  150. package/src/session/fold-coordinator.ts +433 -0
  151. package/src/session/internal/managed-session-storage.ts +64 -26
  152. package/src/session/sdk-run-capability-internal.ts +15 -0
  153. package/src/session/sdk-run-capability.ts +2 -0
  154. package/src/session/session-manager.ts +29 -10
  155. package/src/setup/provider-presets.json +1 -1
  156. package/src/slash-commands/helpers/credential-switch.ts +6 -1
  157. package/src/task/executor.ts +19 -3
  158. package/src/telemetry/control.ts +26 -0
  159. package/src/telemetry/events.ts +142 -0
  160. package/src/telemetry/index.ts +3 -0
  161. package/src/telemetry/transport.ts +87 -0
  162. package/src/tools/bash-interactive.ts +182 -85
  163. package/src/tools/bash.ts +786 -67
  164. package/src/tools/index.ts +7 -5
  165. package/src/tools/path-utils.ts +77 -29
  166. package/src/tools/tmux-self-injection-guard.ts +359 -0
  167. package/src/tools/tool-catalog.generated.ts +1 -1
  168. package/src/web/search/provider.ts +120 -11
  169. package/src/web/search/providers/anthropic.ts +89 -17
  170. package/src/web/search/providers/base.ts +9 -4
  171. package/src/web/search/providers/gemini.ts +87 -15
  172. package/src/web/search/providers/openai-compatible.ts +23 -8
  173. package/src/web/search/providers/xai.ts +98 -12
  174. package/src/web/search/types.ts +16 -0
@@ -344,6 +344,7 @@ export interface ExtensionContext {
344
344
  cleanedArgs?: string;
345
345
  }) => void;
346
346
  preflightSignal?: AbortSignal;
347
+ sdkRunCapability?: unknown;
347
348
  }): Promise<unknown>;
348
349
  setPlanMode?(on: boolean): unknown;
349
350
  operateGoal?(op: "create" | "get" | "resume" | "pause" | "complete" | "drop", objective?: string): Promise<unknown>;
@@ -492,6 +493,8 @@ export interface AgentStartEvent extends SharedAgentStartEvent {
492
493
  export interface AgentFailedEvent {
493
494
  type: "agent_failed";
494
495
  error: AgentFailureDiagnostic;
496
+ /** Internal SDK queue-owner binding for exact lifecycle attribution. */
497
+ sdkRunToken?: string;
495
498
  /** Attempt correlation for the failing run, when scoped (matches the
496
499
  * agent_start/agent_end scope contract). */
497
500
  scope?: AttemptScope;
@@ -841,8 +844,6 @@ export interface ExtensionAPI {
841
844
  startsOwnRun: boolean;
842
845
  }) => void;
843
846
  preflightSignal?: AbortSignal;
844
- /** Internal SDK correlation owner for an exact queued follow-up. */
845
- sdkRunToken?: string;
846
847
  }): Promise<void>;
847
848
  /** Append a custom entry to the session for state persistence (not sent to LLM). */
848
849
  appendEntry<T = unknown>(customType: string, data?: T): void;
@@ -1028,8 +1029,6 @@ export type SendUserMessageHandler = (content: string | (TextContent | ImageCont
1028
1029
  removed?: boolean;
1029
1030
  }) => void;
1030
1031
  preflightSignal?: AbortSignal;
1031
- /** Internal SDK correlation owner for an exact queued follow-up. */
1032
- sdkRunToken?: string;
1033
1032
  }) => void | Promise<void>;
1034
1033
  export type AppendEntryHandler = <T = unknown>(customType: string, data?: T) => void;
1035
1034
  export type GetActiveToolsHandler = () => string[];
@@ -1166,6 +1165,7 @@ export interface ExtensionContextActions {
1166
1165
  cleanedArgs?: string;
1167
1166
  }) => void;
1168
1167
  preflightSignal?: AbortSignal;
1168
+ sdkRunCapability?: unknown;
1169
1169
  }) => Promise<unknown>;
1170
1170
  setPlanMode?: (on: boolean) => unknown;
1171
1171
  operateGoal?: (op: "create" | "get" | "resume" | "pause" | "complete" | "drop", objective?: string) => Promise<unknown>;
@@ -148,6 +148,8 @@ export interface AgentStartEvent {
148
148
  export interface AgentEndEvent {
149
149
  type: "agent_end";
150
150
  messages: AgentMessage[];
151
+ /** Internal SDK queue-owner binding for exact lifecycle attribution. */
152
+ sdkRunToken?: string;
151
153
  /** Indicates whether the loop ended normally, suspended, cancelled, or entered maintenance. */
152
154
  stopReason?: "completed" | "paused" | "cancelled" | "maintenance";
153
155
  /** Present for maintenance checkpoints; non-aborted checkpoints are not terminal. */
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Official GC of already-quarantined empty `.gjc-delete-*` receipts.
3
+ * Roots are operator operands — never hardcoded host paths.
4
+ */
5
+ import type { BigIntStats } from "node:fs";
6
+ import { exactUnlinkDirect } from "@gajae-code/natives";
7
+ export declare const EMPTY_DELETE_PREFIX = ".gjc-delete-";
8
+ export interface EmptyDeleteIdentity {
9
+ dev: bigint;
10
+ ino: bigint;
11
+ nlink: bigint;
12
+ size: bigint;
13
+ mtimeNs: bigint;
14
+ parentDev: bigint;
15
+ parentIno: bigint;
16
+ sha256: string;
17
+ }
18
+ export interface EmptyDeleteGcRecord {
19
+ root: string;
20
+ path: string;
21
+ action: "would_remove" | "removed" | "kept" | "skipped";
22
+ reason: string;
23
+ identity?: EmptyDeleteIdentity;
24
+ /** A dry-run candidate is an observation, never deletion authority. */
25
+ observationOnly?: boolean;
26
+ /** Retained-object paths a native direct unlink left behind; operator-recoverable only there. */
27
+ retainedPaths?: {
28
+ detached?: string;
29
+ successor?: string;
30
+ placeholder?: string;
31
+ unknown?: string;
32
+ };
33
+ }
34
+ export interface EmptyDeleteGcReport {
35
+ dry_run: boolean;
36
+ roots: string[];
37
+ records: EmptyDeleteGcRecord[];
38
+ would_remove: number;
39
+ removed: number;
40
+ kept: number;
41
+ skipped: number;
42
+ errors: string[];
43
+ }
44
+ export interface EmptyDeleteGcOptions {
45
+ roots: string[];
46
+ prune: boolean;
47
+ }
48
+ export interface EmptyDeleteGcDependencies {
49
+ /** Internal seam for deterministic collect-to-prune race tests. */
50
+ collect?: (root: string) => Promise<EmptyDeleteGcRecord[]>;
51
+ exactUnlinkDirect?: typeof exactUnlinkDirect;
52
+ }
53
+ export declare function collectEmptyDeleteReceipts(root: string, deps?: {
54
+ lstat?: (file: string, options: {
55
+ bigint: true;
56
+ }) => Promise<BigIntStats>;
57
+ }): Promise<EmptyDeleteGcRecord[]>;
58
+ export declare function runEmptyDeleteGc(options: EmptyDeleteGcOptions, deps?: EmptyDeleteGcDependencies): Promise<EmptyDeleteGcReport>;
@@ -12,6 +12,7 @@
12
12
  * error all mean KEEP — a live process is never signalled or killed.
13
13
  * - Dry-run by default: nothing is deleted unless `--prune`/`--force`.
14
14
  */
15
+ import { type EmptyDeleteGcReport } from "./empty-delete-gc";
15
16
  import { type GcSessionScopeUsage } from "./gc-session-scope";
16
17
  export type GcStore = "harness_leases" | "file_locks" | "tmux_sessions" | "registry_entries" | "local_roots";
17
18
  export declare const GC_STORES: readonly GcStore[];
@@ -127,6 +128,7 @@ export interface GcReport {
127
128
  * PID-liveness axis above is unchanged by its absence or presence.
128
129
  */
129
130
  disk?: GcDiskReport;
131
+ empty_delete_receipts?: EmptyDeleteGcReport;
130
132
  }
131
133
  export interface GcRunResult {
132
134
  stdout: string;
@@ -62,6 +62,12 @@ export declare const SessionStateLockTestHooks: {
62
62
  unqualifiedOwnerIsLocal?: boolean;
63
63
  /** @internal Runs after final live-owner validation and before descriptor rewrite. */
64
64
  afterCurrentOwnerValidation?: (file: string) => void | Promise<void>;
65
+ /** @internal Fault seam immediately before a held owner record rewrite mutates bytes. */
66
+ beforeOwnerRecordRewrite?: (file: string) => void | Promise<void>;
67
+ /** @internal Fault seam immediately before final transition-generation validation. */
68
+ beforeTransitionReleaseLstat?: (transitionDir: string) => void | Promise<void>;
69
+ /** @internal Fault seam immediately before setup generation capture. */
70
+ beforeTransitionSetupLstat?: (transitionDir: string) => void | Promise<void>;
65
71
  /**
66
72
  * @internal Runs after a live owner has been proven and immediately before its
67
73
  * final pathname capture for release. Tests use it to replace the pathname and
@@ -69,10 +75,30 @@ export declare const SessionStateLockTestHooks: {
69
75
  */
70
76
  beforeCurrentOwnerRelease?: (file: string) => void | Promise<void>;
71
77
  beforeLegacyDirectoryRemoval?: (lockDir: string) => void | Promise<void>;
78
+ /** @internal Last quarantine name minted in the current lock cycle (tests). */
79
+ lastQuarantineName?: string;
80
+ /** @internal Count of quarantine names minted in the current lock cycle (tests). */
81
+ quarantineMints?: number;
82
+ /** @internal Force the next mint to this name so leftover-collision tests can plant it. */
83
+ forcedQuarantineName?: string;
84
+ /** @internal Observes bounded acquisition retries without changing their timing. */
85
+ afterAcquireContention?: (lockFile: string, attempt: number, elapsedMs: number) => void;
72
86
  };
73
87
  /** Raised when the lock could not be acquired; callers map it to their own refusal. */
88
+ export type SessionStateLockUnavailableReason = "acquire_timeout" | "legacy_directory_owner_unprovenanced" | "lock_initialization_failed" | "lock_inspection_failed" | "lock_owner_live_or_unverifiable" | "lock_owner_record_fresh" | "lock_owner_record_unprovenanced" | "lock_release_failed" | "transition_claim_timeout" | "unsafe_lock_path_type";
89
+ interface SessionStateLockUnavailableDetails {
90
+ lockPath: string;
91
+ reason: SessionStateLockUnavailableReason;
92
+ attempts?: number;
93
+ elapsedMs?: number;
94
+ cause?: unknown;
95
+ }
74
96
  export declare class SessionStateLockUnavailableError extends Error {
75
- constructor(cause?: unknown);
97
+ readonly lockPath?: string;
98
+ readonly reason?: SessionStateLockUnavailableReason;
99
+ readonly attempts?: number;
100
+ readonly elapsedMs?: number;
101
+ constructor(causeOrDetails?: unknown | SessionStateLockUnavailableDetails);
76
102
  }
77
103
  /**
78
104
  * The identity-bound deletion primitives this lock is built on.
@@ -85,7 +111,7 @@ export declare class SessionStateLockUnavailableError extends Error {
85
111
  * caller proved. A replacement is therefore never deleted, by construction rather than by
86
112
  * a narrower window.
87
113
  */
88
- export type SessionStateLockNativeBindings = Pick<typeof import("@gajae-code/natives"), "exactRemoveDirectoryTree" | "exactUnlink" | "snapshotDirectoryTree">;
114
+ export type SessionStateLockNativeBindings = Pick<typeof import("@gajae-code/natives"), "exactRemoveDirectoryTree" | "exactUnlink" | "exactUnlinkDirect" | "snapshotDirectoryTree">;
89
115
  /** How the deletion primitives are obtained. Throwing means they are unavailable. */
90
116
  type SessionStateLockNativeLoader = () => SessionStateLockNativeBindings;
91
117
  /**
@@ -102,12 +128,15 @@ type SessionStateLockNativeLoader = () => SessionStateLockNativeBindings;
102
128
  */
103
129
  export declare function setSessionStateLockNativeBindings(load: SessionStateLockNativeLoader | undefined): void;
104
130
  /**
105
- * Decide what actually occupies the lock path, without following it.
131
+ * Verified empty leftover at a reserved quarantine name is incomplete debris, not
132
+ * in-progress cleanup.
106
133
  *
107
- * @internal exported as the seam these decisions are tested through: a live legacy
108
- * directory owner must be provably left alone without waiting out a real stale window.
134
+ * Deletion authority is the native identity-bound direct unlink — never a plain
135
+ * pathname unlink. A replacement planted at the reserved name between observation
136
+ * and deletion has a different inode identity and is refused by construction.
109
137
  */
110
- export declare function reclaimStaleSessionStateLock(lockFile: string): Promise<void>;
138
+ export declare function removeVerifiedEmptyQuarantine(directory: string, name: string): Promise<void>;
139
+ export declare function reclaimStaleSessionStateLock(lockFile: string, quarantineName?: string): Promise<void>;
111
140
  /**
112
141
  * Serialize one read-modify-write of `stateFile` against every other holder of
113
142
  * `<stateFile>.lock`.
@@ -195,6 +195,12 @@ export declare function persistCoordinatorRuntimeStateFromEvent(event: RuntimeSt
195
195
  * sidecar never trusts a model-supplied name.
196
196
  */
197
197
  observation?: CoordinatorToolObservation): Promise<void>;
198
+ export declare function persistCoordinatorWorkerIntegrationOutcome(context: RuntimeStateContext, outcome: {
199
+ kind: "worker_integration" | "terminal_persistence";
200
+ status: "completed" | "failed" | "timed_out";
201
+ correlationId?: string;
202
+ error?: string;
203
+ }): Promise<void>;
198
204
  export declare function ownerTerminalContextFromEnvironment(): OwnerTerminalContext | "invalid" | null;
199
205
  export declare function persistCoordinatorRuntimeStateFromPostmortem(reason: postmortem.Reason, context: RuntimeStateContext): Promise<void>;
200
206
  export declare function registerCoordinatorRuntimeStateFinalizer(context: RuntimeStateContext): () => void;
@@ -28,6 +28,7 @@ export * from "./session/session-dump-format";
28
28
  export * from "./session/session-manager";
29
29
  export * from "./task/executor";
30
30
  export type * from "./task/types";
31
+ export * from "./telemetry";
31
32
  export * from "./tools";
32
33
  export * from "./utils/git";
33
34
  export { HookEditorComponent as ExtensionEditorComponent, HookInputComponent as ExtensionInputComponent, HookSelectorComponent as ExtensionSelectorComponent, };
@@ -47,7 +47,9 @@ export interface InteractiveModeNotify {
47
47
  kind: "warn" | "error" | "info";
48
48
  message: string;
49
49
  }
50
- export declare function submitInteractiveInput(mode: Pick<InteractiveMode, "markPendingSubmissionStarted" | "finishPendingSubmission" | "showError" | "checkShutdownRequested" | "waitForAgentEnd">, session: Pick<AgentSession, "prompt" | "promptCustomMessage">, input: SubmittedUserInput): Promise<void>;
50
+ export declare function submitInteractiveInput(mode: Pick<InteractiveMode, "markPendingSubmissionStarted" | "finishPendingSubmission" | "showError" | "checkShutdownRequested" | "waitForAgentEnd">, session: Pick<AgentSession, "prompt" | "promptCustomMessage"> & {
51
+ continuePersistedHistory?: AgentSession["continuePersistedHistory"];
52
+ }, input: SubmittedUserInput): Promise<void>;
51
53
  type StartupModelProfileArgs = {
52
54
  session: AgentSession;
53
55
  settings: Settings;
@@ -7,10 +7,11 @@
7
7
  */
8
8
  import type { SelectItem } from "@gajae-code/tui";
9
9
  import type { JobsSnapshot } from "../jobs-observer";
10
- export type JobRefKind = "monitor" | "cron";
10
+ export type JobRefKind = "monitor" | "cron" | "folded";
11
11
  export interface JobRef {
12
12
  kind: JobRefKind;
13
13
  id: string;
14
+ generation?: string;
14
15
  }
15
16
  /** Compact relative time, e.g. "in 5m", "2m ago", "now". */
16
17
  export declare function formatRelative(targetMs: number | undefined, nowMs?: number): string;
@@ -18,7 +19,8 @@ export declare function formatRelative(targetMs: number | undefined, nowMs?: num
18
19
  export declare function parseJobRef(value: string): JobRef | null;
19
20
  /**
20
21
  * Build the grouped jobs list: monitors first (newest-first), then crons
21
- * (newest-first). The snapshot arrays are already sorted newest-first.
22
+ * (newest-first), then read-only folded jobs. The snapshot arrays are already
23
+ * sorted newest-first where a source has a timestamp.
22
24
  */
23
25
  export declare function buildJobsListItems(snapshot: JobsSnapshot): SelectItem[];
24
26
  /**
@@ -14,11 +14,43 @@
14
14
  */
15
15
  import type { AsyncJob, AsyncJobManager } from "../async";
16
16
  export type JobsWorstState = "none" | "running" | "failed";
17
+ export type JobDeliveryState = "pending" | "delivered" | "failed-visible";
18
+ /** The manager-owned, one-pass job projection consumed by this observer. */
19
+ export interface AsyncJobSnapshotEntry {
20
+ id: string;
21
+ kind: string;
22
+ label: string;
23
+ status: AsyncJob["status"];
24
+ generation: string;
25
+ backgrounded: boolean;
26
+ deliveryState: JobDeliveryState;
27
+ }
28
+ /** Scalar delivery failure evidence that may outlive the AsyncJob record. */
29
+ export interface DeadLetteredJobSnapshotEntry {
30
+ jobId: string;
31
+ generation: string;
32
+ ownerId?: string;
33
+ backgrounded?: boolean;
34
+ attempt: number;
35
+ lastError?: string;
36
+ recordedAt: number;
37
+ }
38
+ export interface AsyncJobsSnapshot {
39
+ jobs: AsyncJobSnapshotEntry[];
40
+ deadLettered: DeadLetteredJobSnapshotEntry[];
41
+ }
17
42
  export interface MonitorJobView {
18
43
  id: string;
19
44
  label: string;
20
45
  status: AsyncJob["status"];
21
46
  startTime: number;
47
+ generation?: string;
48
+ backgrounded?: boolean;
49
+ deliveryState?: JobDeliveryState;
50
+ }
51
+ export interface FoldedJobView extends AsyncJobSnapshotEntry {
52
+ /** Safe diagnostic retained for a dead-lettered delivery, when available. */
53
+ errorText?: string;
22
54
  }
23
55
  export interface CronJobView {
24
56
  id: string;
@@ -34,6 +66,10 @@ export interface CronJobView {
34
66
  export interface JobsSnapshot {
35
67
  monitors: MonitorJobView[];
36
68
  crons: CronJobView[];
69
+ /** Backgrounded work and undeliverable terminal work that must stay visible. */
70
+ foldedJobs?: FoldedJobView[];
71
+ /** Scalar dead-letter evidence retained for diagnostics and red-drill-in. */
72
+ deadLettered?: DeadLetteredJobSnapshotEntry[];
37
73
  activeMonitorCount: number;
38
74
  activeCronCount: number;
39
75
  worstState: JobsWorstState;
@@ -1,5 +1,6 @@
1
1
  import type { NativeDirectoryTreeSnapshot } from "@gajae-code/natives";
2
2
  import type { ModelProfileErrorDetails } from "../../config/model-profile-contract";
3
+ import { type SdkHostModelResolver } from "../host/model-pin";
3
4
  import { type DirectoryMigrationPolicy } from "../session-directory";
4
5
  import { type BrokerDiscovery, type BrokerPublicationObservation, type RedactedBrokerDiscovery } from "./discovery";
5
6
  import { type LifecycleDurableEffectsReceipt, LifecycleLedger, type LifecycleStartupFailureReceipt } from "./lifecycle-ledger";
@@ -11,6 +12,8 @@ export interface BrokerSettings {
11
12
  heartbeatTtlMs?: number;
12
13
  /** Broker-owned migration policy. Client lifecycle frames cannot select it. */
13
14
  resolveDirectoryMigration?: (_cwd: string) => Promise<DirectoryMigrationPolicy>;
15
+ /** Host model resolver override for lifecycle tests and embedders. */
16
+ resolveModelPin?: SdkHostModelResolver;
14
17
  }
15
18
  type ResolvedBrokerSettings = {
16
19
  agentDir: string;
@@ -29,10 +29,13 @@ export interface KindAwareReconciliation {
29
29
  noteTransition(kind: ReconciliationKind, correlation: PromptCorrelation | undefined, frame: {
30
30
  type: "agent_start" | "agent_end";
31
31
  content?: TurnResultContent;
32
+ hasActivity?: boolean;
33
+ outcome?: SdkPromptTerminalOutcome;
32
34
  } | {
33
35
  type: "agent_failed";
34
36
  error: unknown;
35
37
  content?: TurnResultContent;
38
+ hasActivity?: boolean;
36
39
  }): Promise<void>;
37
40
  claimPendingOutcome(kind: ReconciliationKind, correlation: PromptCorrelation, outcome: SdkPromptTerminalOutcome, receiptState?: Extract<ReceiptState, "present" | "missing">): Promise<SdkPromptTerminalOutcome>;
38
41
  finalizeOutcome(kind: ReconciliationKind, correlation: PromptCorrelation, outcome?: SdkPromptTerminalOutcome, recordError?: {
@@ -22,6 +22,7 @@
22
22
  * record that has none, but never changes status, terminalAt, or retention.
23
23
  */
24
24
  import { PROMPT_FAILURE_CODE_MAX, sanitizePromptFailure } from "../prompt-failure";
25
+ import type { SdkPromptTerminalOutcome } from "../prompt-status";
25
26
  import type { ReceiptState } from "../receipt-state";
26
27
  export { PROMPT_FAILURE_CODE_MAX, sanitizePromptFailure };
27
28
  export declare const PROMPT_RECONCILIATION_ACTIVE_CAPACITY = 128;
@@ -102,10 +103,13 @@ export interface PromptReconciliation {
102
103
  } | {
103
104
  type: "agent_end";
104
105
  finalText?: string;
106
+ hasActivity?: boolean;
107
+ outcome?: SdkPromptTerminalOutcome;
105
108
  } | {
106
109
  type: "agent_failed";
107
110
  error: unknown;
108
111
  finalText?: string;
112
+ hasActivity?: boolean;
109
113
  }): void;
110
114
  lookup(selector: {
111
115
  commandId?: string;
@@ -278,8 +278,15 @@ export declare const SDK_LIFECYCLE_ROUTER_PROTOCOL_VERSION = 1;
278
278
  * Generation 177 consumes an exact same-window lean settlement receipt only
279
279
  * after its autonomous ask lead-in publishes successfully, preventing idle
280
280
  * replay without changing the serving protocol.
281
+ * Generation 178: idle publication waits for positioned identity delivery to
282
+ * cross the native writer barrier before the independent broadcast lane.
283
+ * Generation 179 tolerates a bounded consecutive run of refused notification
284
+ * publications in the router instead of cancelling the subscription on the
285
+ * first refusal, so an owner still running the generation-178 router keeps
286
+ * killing a session's mirroring after one transient rejection and must be
287
+ * replaced across this upgrade.
281
288
  */
282
- export declare const DAEMON_GENERATION = 178;
289
+ export declare const DAEMON_GENERATION = 179;
283
290
  /**
284
291
  * Serving-compatibility boundary for daemon lifecycle requests. Epoch 7
285
292
  * requires durable publication receipts and acknowledged attachment dispatch,
@@ -1,5 +1,7 @@
1
1
  import { SessionRouter } from "../router";
2
- export type SdkSessionCliAction = "list" | "inspect" | "send" | "status" | "tail" | "retire" | "raw" | "control" | "query" | "global";
2
+ import { type SdkSessionRowV1 } from "./rows";
3
+ export type SdkSessionCliAction = "list" | "inspect" | "send" | "status" | "tail" | "retire" | "global" | "raw" | "control" | "query" | "global";
4
+ export type SdkSessionListScope = "repo" | "cwd" | "worktree" | "all";
3
5
  export type SdkSessionCliRawKind = "control" | "query" | "global";
4
6
  export interface SdkSessionCliArgs {
5
7
  action?: string;
@@ -13,6 +15,7 @@ export interface SdkSessionCliArgs {
13
15
  jsonInputFile?: string;
14
16
  jsonInputStdin?: boolean;
15
17
  idempotencyKey?: string;
18
+ scope?: string;
16
19
  confirm?: boolean;
17
20
  cursor?: string;
18
21
  wait?: boolean;
@@ -27,6 +30,43 @@ export interface RetainedTranscriptTailReader {
27
30
  readonly size: number;
28
31
  readRange(start: number, end: number): Promise<Uint8Array>;
29
32
  }
33
+ interface WorkspaceIdentity {
34
+ /** Canonical workspace path (realpath when it exists, lexical resolve otherwise). */
35
+ canonicalPath: string;
36
+ /** Canonical containing worktree root; null outside a Git checkout. */
37
+ repoRoot: string | null;
38
+ /** Canonical Git common dir; shared by the main checkout and linked worktrees. */
39
+ commonDir: string | null;
40
+ }
41
+ export interface SdkSessionListSelection {
42
+ scope: SdkSessionListScope;
43
+ selection: WorkspaceIdentity;
44
+ /** Bounded, credential-free descriptor included in list output. */
45
+ descriptor: {
46
+ scope: SdkSessionListScope;
47
+ path: string;
48
+ worktreeRoot?: string;
49
+ commonDir?: string;
50
+ };
51
+ }
52
+ /** Parses `--scope`; missing means `repo`, anything else invalid is a usage error. */
53
+ export declare function parseSessionListScope(value: string | undefined): SdkSessionListScope;
54
+ /**
55
+ * Resolves the list selection from `--repo` (default: process cwd) under the
56
+ * effective scope. Outside Git, `repo`/`worktree` fail typed and actionable —
57
+ * they never broaden to `all`; `cwd` remains an exact canonical match.
58
+ */
59
+ export declare function resolveSessionListSelection(scope: SdkSessionListScope, repoArg: string | undefined): Promise<SdkSessionListSelection>;
60
+ /**
61
+ * Filters fully traversed broker rows by the selection scope. Row workspaces
62
+ * are canonicalized and cached per distinct locator; `repo` matches the shared
63
+ * common dir across the main checkout and linked worktrees, `worktree` the
64
+ * containing worktree only, and `cwd` the exact canonical workspace.
65
+ */
66
+ export declare function filterSessionRowsByScope(rows: readonly SdkSessionRowV1[], scope: SdkSessionListScope, selection: SdkSessionListSelection): Promise<{
67
+ sessions: SdkSessionRowV1[];
68
+ warnings: string[];
69
+ }>;
30
70
  /** Creates a lowercase ULID operation reference for prompt reconciliation. */
31
71
  export declare function createOperationRef(now?: number): string;
32
72
  /** Exported for tests: each status poll must stay inside the caller's wait window. */
@@ -39,3 +79,4 @@ export declare function scanRetainedTranscriptTail(reader: RetainedTranscriptTai
39
79
  export declare function runTail(repo: string, agentDir: string, sessionId: string, args: SdkSessionCliArgs): Promise<unknown>;
40
80
  /** Runs the broker-bound `gjc sdk session` command family without exposing endpoint credentials. */
41
81
  export declare function runSdkSessionCli(args: SdkSessionCliArgs, writeOutput?: (value: unknown) => void, setExitCode?: (exitCode: 1 | 2) => void): Promise<void>;
82
+ export {};
@@ -22,6 +22,7 @@ export declare class SdkDiscoveryError extends Error {
22
22
  constructor(path: string, message: string);
23
23
  }
24
24
  export type SdkSessionEndpointScope = "default" | "chat";
25
+ export declare function endpointDirectory(repo: string, scope?: SdkSessionEndpointScope): string;
25
26
  /** Lists endpoint files and returns individual malformed or unreadable records as warnings. */
26
27
  export declare function listSdkSessionEndpoints(repo: string): Promise<SdkSessionEndpointList>;
27
28
  /** Resolves one per-session SDK endpoint discovery file. */
@@ -36,6 +36,8 @@ export interface SessionSdkHostOptions extends HostEndpointAdapters {
36
36
  query?: (connectionId: string, frame: SdkFrame) => unknown | Promise<unknown>;
37
37
  /** Test/lifecycle seam invoked synchronously before fire-and-forget dispatch. */
38
38
  onFrameAdmitted?: (connectionId: string, frame: SdkFrame) => void;
39
+ /** Synchronously rejects external input while a runtime is being replaced. */
40
+ onFrameAdmission?: (connectionId: string, frame: SdkFrame) => SdkFrame | undefined;
39
41
  /** Best-effort diagnostic observation of accepted control/query frames. */
40
42
  onRequest?: SdkRequestObserver;
41
43
  /** Runs before a control response is sent; identity transitions use sendTerminal. */
@@ -5,7 +5,10 @@ export interface SdkHostModelResolveContext {
5
5
  cwd?: string;
6
6
  }
7
7
  /** Registry loader owned by the SDK host, not by machine-facing adapters. */
8
- export type SdkHostModelRegistryLoader = (context?: SdkHostModelResolveContext) => ModelRegistry | Promise<ModelRegistry>;
8
+ export type SdkHostModelRegistryLoader = ((context?: SdkHostModelResolveContext) => ModelRegistry | Promise<ModelRegistry>) & {
9
+ acquire?: (context?: SdkHostModelResolveContext) => () => void;
10
+ dispose?: () => Promise<void>;
11
+ };
9
12
  /**
10
13
  * Builds an offline model resolver for a single SDK host process.
11
14
  *
@@ -22,7 +25,9 @@ export type SdkHostModelResolution = {
22
25
  model: string;
23
26
  error: string;
24
27
  };
25
- export type SdkHostModelResolver = (raw: unknown, context?: SdkHostModelResolveContext) => Promise<SdkHostModelResolution>;
28
+ export type SdkHostModelResolver = ((raw: unknown, context?: SdkHostModelResolveContext) => Promise<SdkHostModelResolution>) & {
29
+ dispose?: () => Promise<void>;
30
+ };
26
31
  /** Resolve the explicit model pin at the SDK host boundary. */
27
32
  export declare function resolveSdkHostModel(raw: unknown, loadRegistry: SdkHostModelRegistryLoader, context?: SdkHostModelResolveContext): Promise<SdkHostModelResolution>;
28
33
  /** Default resolver used by the SDK broker host. */
@@ -0,0 +1 @@
1
+ export { createSdkRunCapability } from "../../session/sdk-run-capability-internal";
@@ -1,5 +1,6 @@
1
1
  import { type Settings } from "../../config/settings";
2
2
  import type { ExtensionAPI, ExtensionContext } from "../../extensibility/extensions";
3
+ import { type TurnResultContent } from "../turn-result";
3
4
  import { SessionSdkHost, type SessionSdkHostOptions } from "./host";
4
5
  import { type SessionSurface } from "./query";
5
6
  import { type SdkCapabilities, type SdkSurfacePolicy } from "./surface-policy";
@@ -175,6 +176,10 @@ export interface CreateSdkSessionRuntimeOptions {
175
176
  terminalAbortSeams?: SdkOnlyTerminalAbortSeams;
176
177
  /** Callback when a frame is admitted to the runtime (test harness). */
177
178
  onFrameAdmitted?: () => void;
179
+ /** Test-only observation of a genuinely timed-out lifecycle drain. */
180
+ onLifecycleDrainTimeoutForTests?: () => void;
181
+ /** Test-only observation of bounded failure-diagnostic deduplication state. */
182
+ onFailureDiagnosticKeyCountForTests?: (count: number) => void;
178
183
  }
179
184
  export interface InvocationCorrelation {
180
185
  commandId: string;
@@ -190,9 +195,18 @@ export interface InvocationReconciliation {
190
195
  noteAccepted(kind: InvocationKind, correlation: InvocationCorrelation, clientRef?: string): Promise<void>;
191
196
  noteTransition(kind: InvocationKind, correlation: InvocationCorrelation | undefined, frame: {
192
197
  type: "agent_start" | "agent_end";
198
+ content?: TurnResultContent;
199
+ hasActivity?: boolean;
200
+ outcome?: {
201
+ kind: "stopped";
202
+ reason: "cancelled";
203
+ provenance: "client_cancel";
204
+ };
193
205
  } | {
194
206
  type: "agent_failed";
195
207
  error: unknown;
208
+ content?: TurnResultContent;
209
+ hasActivity?: boolean;
196
210
  }): Promise<void>;
197
211
  lookup(kind: InvocationKind, selector: {
198
212
  commandId?: string;
@@ -224,7 +238,11 @@ export interface InvocationReconciliation {
224
238
  }, arg4?: (() => boolean) | {
225
239
  code: string;
226
240
  message: string;
227
- }, arg5?: unknown): Promise<void>;
241
+ }, arg5?: unknown, arg6?: {
242
+ content?: TurnResultContent;
243
+ hasActivity?: boolean;
244
+ outcomeKind?: string;
245
+ }): Promise<void>;
228
246
  markUncertain(kind: InvocationKind, correlation: InvocationCorrelation, isCurrent?: () => boolean, deadlineMaxAt?: number): Promise<void>;
229
247
  }
230
248
  export declare function createInvocationReconciliation(options?: {
@@ -1,5 +1,6 @@
1
1
  import type { KindAwareReconciliation } from "./bus/kind-aware-reconciliation";
2
2
  import type { InvocationCorrelation, InvocationReconciliation } from "./host/session-runtime";
3
+ import type { TurnResultContent } from "./turn-result";
3
4
  type DeadlineReconciliation = InvocationReconciliation | KindAwareReconciliation;
4
5
  export type PromptDeadlineOutcome = {
5
6
  kind: "failed";
@@ -7,6 +8,15 @@ export type PromptDeadlineOutcome = {
7
8
  message: string;
8
9
  provenance: "deadline";
9
10
  };
11
+ export interface PromptTerminalTransitionEvidence {
12
+ content?: TurnResultContent;
13
+ hasActivity?: boolean;
14
+ outcome?: {
15
+ kind: "stopped";
16
+ reason: "cancelled";
17
+ provenance: "client_cancel";
18
+ };
19
+ }
10
20
  export declare class PromptDeadlineManager {
11
21
  #private;
12
22
  constructor(options: {
@@ -28,7 +38,7 @@ export declare class PromptDeadlineManager {
28
38
  noteTerminalTransition(correlation: InvocationCorrelation, pendingFailure?: {
29
39
  code: string;
30
40
  message: string;
31
- }): void;
41
+ }, evidence?: PromptTerminalTransitionEvidence): void;
32
42
  clear(correlation: InvocationCorrelation): void;
33
43
  clearAll(): void;
34
44
  /** For tests: current deadline or undefined if no lease. */
@@ -9,6 +9,8 @@ export type AdapterValidationError = {
9
9
  code: "invalid_reload_component" | "invalid_input";
10
10
  message: string;
11
11
  };
12
+ /** Rejects instruction-bearing controls before correlation or provider work. */
13
+ export declare function validateRequiredPromptText(operation: string, input: Input): AdapterValidationError | undefined;
12
14
  /** Validates controls that adapters must reject before forwarding them to a host. */
13
15
  export declare function validateAdapterControl(operation: string, input: Input): AdapterValidationError | undefined;
14
16
  export {};
@@ -1,6 +1,13 @@
1
1
  import { type SessionIndex } from "../broker/session-index";
2
2
  import { type SdkDispatchContext, type SdkDispatchHandler } from "../client/client";
3
3
  import { type ActivatedPreparedSession } from "../session-activation";
4
+ export interface SessionEndpointIdentity {
5
+ readonly mtimeMs: number;
6
+ readonly mtimeNs: bigint;
7
+ readonly ctimeNs: bigint;
8
+ readonly size: bigint;
9
+ readonly ino: bigint;
10
+ }
4
11
  /**
5
12
  * Exact identity of one attached SDK session endpoint. Providers persist it next to
6
13
  * their conversation state and re-prove it before every resume, so it must be derived
@@ -14,6 +21,8 @@ export declare function sessionAttachmentAuthorityId(input: {
14
21
  endpointMtimeMs: number | undefined;
15
22
  url: string;
16
23
  token: string;
24
+ /** Proven no-follow endpoint identity, when the caller has one. */
25
+ endpointIdentity?: SessionEndpointIdentity;
17
26
  }): string;
18
27
  /** The only capability a provider may retain for an attached SDK session. */
19
28
  export interface SessionAttachment {
@@ -59,6 +59,7 @@ export interface AccountInventoryInput {
59
59
  provider: string;
60
60
  }>;
61
61
  getProviderBaseUrl?: (provider: string) => string | undefined;
62
+ getAuthStorageOwner?: () => object;
62
63
  };
63
64
  sessionId?: string;
64
65
  provider?: string;