@gajae-code/coding-agent 0.11.11 → 0.12.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.
Files changed (182) hide show
  1. package/CHANGELOG.md +49 -3
  2. package/dist/types/cli/read-cli.d.ts +1 -0
  3. package/dist/types/commands/deep-interview.d.ts +9 -0
  4. package/dist/types/commands/harness.d.ts +22 -0
  5. package/dist/types/commands/read.d.ts +6 -0
  6. package/dist/types/config/model-registry.d.ts +4 -0
  7. package/dist/types/config/provider-auth-health.d.ts +14 -0
  8. package/dist/types/config/provider-ranking.d.ts +59 -0
  9. package/dist/types/config/settings-schema.d.ts +29 -1
  10. package/dist/types/config/settings.d.ts +2 -0
  11. package/dist/types/extensibility/extensions/types.d.ts +22 -2
  12. package/dist/types/extensibility/shared-events.d.ts +6 -0
  13. package/dist/types/gjc-runtime/deep-interview-ambiguity.d.ts +5 -12
  14. package/dist/types/gjc-runtime/deep-interview-recorder.d.ts +17 -32
  15. package/dist/types/gjc-runtime/deep-interview-stage.d.ts +37 -0
  16. package/dist/types/gjc-runtime/deep-interview-state.d.ts +4 -135
  17. package/dist/types/gjc-runtime/gc-runtime.d.ts +1 -1
  18. package/dist/types/gjc-runtime/memory-guard-owner-claims.d.ts +47 -0
  19. package/dist/types/gjc-runtime/ralplan-runtime.d.ts +52 -1
  20. package/dist/types/gjc-runtime/state-writer.d.ts +5 -46
  21. package/dist/types/gjc-runtime/team-launch.d.ts +1 -1
  22. package/dist/types/gjc-runtime/team-runtime.d.ts +2 -1
  23. package/dist/types/gjc-runtime/team-store.d.ts +12 -0
  24. package/dist/types/gjc-runtime/team-worker-memory-guard.d.ts +92 -0
  25. package/dist/types/gjc-runtime/tmux-owner-isolation.d.ts +7 -0
  26. package/dist/types/gjc-runtime/ultragoal-receipt-freshness.d.ts +8 -0
  27. package/dist/types/gjc-runtime/workflow-manifest.d.ts +3 -5
  28. package/dist/types/internal-urls/local-root-gc.d.ts +2 -0
  29. package/dist/types/main.d.ts +1 -1
  30. package/dist/types/memories/index.d.ts +2 -0
  31. package/dist/types/modes/acp/acp-agent.d.ts +8 -0
  32. package/dist/types/modes/components/assistant-message.d.ts +3 -1
  33. package/dist/types/modes/components/irc-sidebar.d.ts +41 -0
  34. package/dist/types/modes/components/read-tool-group.d.ts +4 -4
  35. package/dist/types/modes/components/session-observer-overlay.d.ts +4 -0
  36. package/dist/types/modes/components/settings-selector.d.ts +2 -0
  37. package/dist/types/modes/components/tool-execution.d.ts +8 -0
  38. package/dist/types/modes/controllers/event-controller.d.ts +3 -0
  39. package/dist/types/modes/interactive-mode.d.ts +2 -0
  40. package/dist/types/modes/irc-observation-ledger.d.ts +17 -1
  41. package/dist/types/modes/types.d.ts +2 -0
  42. package/dist/types/modes/utils/ui-helpers.d.ts +16 -0
  43. package/dist/types/runtime-mcp/smithery-auth.d.ts +5 -0
  44. package/dist/types/sdk/broker/lifecycle.d.ts +5 -0
  45. package/dist/types/sdk/bus/control-drain-lease.d.ts +52 -0
  46. package/dist/types/sdk/bus/index.d.ts +15 -1
  47. package/dist/types/sdk/bus/kind-aware-reconciliation.d.ts +37 -0
  48. package/dist/types/sdk/bus/prompt-reconciliation.d.ts +2 -1
  49. package/dist/types/sdk/bus/reconciliation-store.d.ts +65 -0
  50. package/dist/types/sdk/host/control/operations.d.ts +1 -1
  51. package/dist/types/sdk/host/host.d.ts +2 -0
  52. package/dist/types/sdk/host/query/handlers.d.ts +5 -0
  53. package/dist/types/session/agent-session.d.ts +44 -10
  54. package/dist/types/session/memory-guard-checkpoint-participant.d.ts +69 -0
  55. package/dist/types/session/session-manager.d.ts +25 -13
  56. package/dist/types/session/streaming-output.d.ts +60 -5
  57. package/dist/types/skill-state/active-state.d.ts +0 -4
  58. package/dist/types/skill-state/workflow-hud.d.ts +3 -0
  59. package/dist/types/tools/browser/launch.d.ts +7 -0
  60. package/dist/types/tools/fetch.d.ts +17 -1
  61. package/dist/types/tools/output-meta.d.ts +21 -1
  62. package/dist/types/tools/read-internals.d.ts +12 -0
  63. package/dist/types/tools/read.d.ts +45 -1
  64. package/dist/types/tools/resource-gc.d.ts +4 -0
  65. package/dist/types/tools/tool-result.d.ts +7 -1
  66. package/package.json +9 -13
  67. package/scripts/benchmark-sticky-viewport-pr1.ts +239 -0
  68. package/scripts/capture-sticky-viewport-showcase.ts +292 -0
  69. package/scripts/generate-sdk-operation-inventory.ts +2 -0
  70. package/scripts/verify-gjc-sdk-canonicalization.ts +122 -18
  71. package/scripts/verify-sticky-viewport-showcase.ts +611 -0
  72. package/src/capability/index.ts +8 -0
  73. package/src/cli/read-cli.ts +2 -1
  74. package/src/cli.ts +1 -0
  75. package/src/commands/deep-interview.ts +29 -9
  76. package/src/commands/harness.ts +35 -12
  77. package/src/commands/read.ts +11 -2
  78. package/src/commands/team.ts +1 -1
  79. package/src/config/model-registry.ts +21 -2
  80. package/src/config/provider-auth-health.ts +42 -0
  81. package/src/config/provider-ranking.ts +119 -0
  82. package/src/config/settings-schema.ts +23 -1
  83. package/src/config/settings.ts +246 -108
  84. package/src/defaults/gjc/skills/deep-interview/SKILL.md +229 -82
  85. package/src/defaults/gjc/skills/ralplan/SKILL.md +58 -25
  86. package/src/defaults/gjc/skills/team/SKILL.md +1 -1
  87. package/src/defaults/gjc/skills/ultragoal/SKILL.md +25 -15
  88. package/src/eval/py/executor.ts +7 -2
  89. package/src/extensibility/extensions/types.ts +28 -4
  90. package/src/extensibility/shared-events.ts +5 -0
  91. package/src/gjc-runtime/deep-interview-ambiguity.ts +47 -82
  92. package/src/gjc-runtime/deep-interview-recorder.ts +227 -310
  93. package/src/gjc-runtime/deep-interview-runtime.ts +109 -270
  94. package/src/gjc-runtime/deep-interview-stage.ts +1016 -0
  95. package/src/gjc-runtime/deep-interview-state.ts +12 -943
  96. package/src/gjc-runtime/gc-render.ts +1 -0
  97. package/src/gjc-runtime/gc-runtime.ts +11 -1
  98. package/src/gjc-runtime/memory-guard-owner-claims.ts +389 -0
  99. package/src/gjc-runtime/ralplan-runtime.ts +742 -85
  100. package/src/gjc-runtime/state-runtime.ts +2 -1
  101. package/src/gjc-runtime/state-writer.ts +70 -222
  102. package/src/gjc-runtime/team-launch.ts +34 -5
  103. package/src/gjc-runtime/team-runtime.ts +970 -33
  104. package/src/gjc-runtime/team-store.ts +32 -0
  105. package/src/gjc-runtime/team-worker-memory-guard.ts +363 -0
  106. package/src/gjc-runtime/team-workers.ts +1 -0
  107. package/src/gjc-runtime/tmux-owner-isolation.ts +18 -0
  108. package/src/gjc-runtime/ultragoal-receipt-freshness.ts +20 -0
  109. package/src/gjc-runtime/ultragoal-runtime.ts +13 -7
  110. package/src/gjc-runtime/workflow-manifest.generated.json +97 -350
  111. package/src/gjc-runtime/workflow-manifest.ts +34 -179
  112. package/src/hooks/native-skill-hook.ts +17 -4
  113. package/src/hooks/skill-state.ts +1 -23
  114. package/src/internal-urls/docs-index.generated.ts +8 -9
  115. package/src/internal-urls/local-root-gc.ts +127 -0
  116. package/src/main.ts +9 -5
  117. package/src/memories/index.ts +10 -0
  118. package/src/modes/DESIGN.md +47 -0
  119. package/src/modes/acp/acp-agent.ts +43 -7
  120. package/src/modes/acp/acp-event-mapper.ts +14 -7
  121. package/src/modes/acp/acp-mode.ts +39 -3
  122. package/src/modes/components/assistant-message.ts +123 -22
  123. package/src/modes/components/irc-sidebar.ts +176 -62
  124. package/src/modes/components/model-selector.ts +61 -4
  125. package/src/modes/components/oauth-selector.ts +42 -12
  126. package/src/modes/components/read-tool-group.ts +82 -14
  127. package/src/modes/components/session-observer-overlay.ts +187 -32
  128. package/src/modes/components/settings-selector.ts +60 -18
  129. package/src/modes/components/tool-execution.ts +138 -27
  130. package/src/modes/controllers/event-controller.ts +109 -27
  131. package/src/modes/controllers/extension-ui-controller.ts +19 -2
  132. package/src/modes/controllers/input-controller.ts +18 -3
  133. package/src/modes/controllers/selector-controller.ts +83 -37
  134. package/src/modes/interactive-mode.ts +62 -3
  135. package/src/modes/irc-observation-ledger.ts +71 -15
  136. package/src/modes/runtime-init.ts +19 -2
  137. package/src/modes/types.ts +2 -0
  138. package/src/modes/utils/ui-helpers.ts +94 -1
  139. package/src/prompts/agents/architect.md +9 -1
  140. package/src/prompts/agents/critic.md +9 -0
  141. package/src/prompts/system/system-prompt.md +0 -1
  142. package/src/prompts/tools/read.md +4 -2
  143. package/src/runtime-mcp/smithery-auth.ts +17 -2
  144. package/src/runtime-mcp/smithery-connect.ts +11 -1
  145. package/src/sdk/broker/lifecycle.ts +25 -6
  146. package/src/sdk/bus/control-drain-lease.ts +104 -0
  147. package/src/sdk/bus/index.ts +341 -38
  148. package/src/sdk/bus/kind-aware-reconciliation.ts +242 -0
  149. package/src/sdk/bus/prompt-reconciliation.ts +2 -1
  150. package/src/sdk/bus/reconciliation-store.ts +224 -0
  151. package/src/sdk/host/control/dispatch.ts +5 -1
  152. package/src/sdk/host/control/operations.ts +1 -1
  153. package/src/sdk/host/host.ts +23 -1
  154. package/src/sdk/host/query/handlers.ts +55 -0
  155. package/src/sdk/mcp/server.ts +46 -18
  156. package/src/sdk/protocol/operation-inventory.generated.json +29 -0
  157. package/src/sdk/protocol/operation-registry.ts +7 -2
  158. package/src/sdk/session.ts +13 -1
  159. package/src/session/agent-session.ts +466 -50
  160. package/src/session/memory-guard-checkpoint-participant.ts +131 -0
  161. package/src/session/session-manager.ts +764 -17
  162. package/src/session/streaming-output.ts +262 -43
  163. package/src/setup/provider-onboarding.ts +19 -4
  164. package/src/skill-state/active-state.ts +0 -10
  165. package/src/skill-state/workflow-hud.ts +25 -2
  166. package/src/skill-state/workflow-mutation-guard.ts +65 -7
  167. package/src/tools/ask.ts +89 -69
  168. package/src/tools/browser/launch.ts +41 -6
  169. package/src/tools/fetch.ts +114 -23
  170. package/src/tools/output-meta.ts +176 -9
  171. package/src/tools/path-utils.ts +5 -1
  172. package/src/tools/read-internals.ts +44 -0
  173. package/src/tools/read.ts +1542 -310
  174. package/src/tools/resource-gc.ts +182 -18
  175. package/src/tools/tool-result.ts +14 -1
  176. package/src/web/search/providers/codex.ts +1 -1
  177. package/dist/types/gjc-runtime/deep-interview-draft.d.ts +0 -8
  178. package/dist/types/gjc-runtime/deep-interview-payload.d.ts +0 -41
  179. package/dist/types/gjc-runtime/deep-interview-repair.d.ts +0 -17
  180. package/src/gjc-runtime/deep-interview-draft.ts +0 -843
  181. package/src/gjc-runtime/deep-interview-payload.ts +0 -262
  182. package/src/gjc-runtime/deep-interview-repair.ts +0 -1674
@@ -2,12 +2,50 @@ import { type Component, type ViewportAnchorProvider, type ViewportAnchorRender
2
2
  import type { IrcObservationLedger } from "../irc-observation-ledger";
3
3
  export declare const IRC_SIDEBAR_WIDTH_RATIO = 0.3;
4
4
  export declare const IRC_SIDEBAR_MAX_RENDER_ROWS = 2048;
5
+ export declare const __ircSidebarPerfCounters: {
6
+ enabled: boolean;
7
+ projectionMemoHits: number;
8
+ projectionMemoMisses: number;
9
+ recordsVisited: number;
10
+ sourceBytes: number;
11
+ rows: number;
12
+ styledCacheHits: number;
13
+ styledCacheMisses: number;
14
+ wrapCalls: number;
15
+ snapshot(): {
16
+ projectionMemoHits: number;
17
+ projectionMemoMisses: number;
18
+ recordsVisited: number;
19
+ sourceBytes: number;
20
+ rows: number;
21
+ styledCacheHits: number;
22
+ styledCacheMisses: number;
23
+ wrapCalls: number;
24
+ };
25
+ enable(): void;
26
+ disable(): void;
27
+ reset(): void;
28
+ };
5
29
  /** Computes transcript/sidebar widths while preserving at least half the terminal for the transcript. */
6
30
  export declare function computeIrcSplitWidths(width: number): {
7
31
  leftWidth: number;
8
32
  separatorWidth: number;
9
33
  rightWidth: number;
10
34
  };
35
+ type SemanticLine = Readonly<{
36
+ kind: "header" | "body" | "elision" | "blank";
37
+ text: string;
38
+ sender?: string;
39
+ recipient?: string;
40
+ time?: string;
41
+ }>;
42
+ export type IrcSidebarSemanticProjection = Readonly<{
43
+ token: string;
44
+ lines: readonly SemanticLine[];
45
+ }>;
46
+ /** The authoritative bounded, display-neutral IRC sidebar projection. */
47
+ export declare function getIrcSidebarSemanticProjection(ledger: IrcObservationLedger, width: number): IrcSidebarSemanticProjection;
48
+ export declare function getIrcSidebarSemanticToken(ledger: IrcObservationLedger, width: number): string;
11
49
  export interface IrcSidebarTheme {
12
50
  fg(color: "dim" | "accent", text: string): string;
13
51
  bold(text: string): string;
@@ -26,7 +64,10 @@ export declare class IrcSplitViewComponent implements ViewportAnchorProvider {
26
64
  get visible(): boolean;
27
65
  effectiveSidebarVisible(width?: number): boolean;
28
66
  setVisible(visible: boolean): void;
67
+ invalidateTheme(): void;
68
+ resetSource(): void;
29
69
  render(width: number): string[];
30
70
  renderWithViewportAnchors(width: number): ViewportAnchorRender;
31
71
  invalidate(): void;
32
72
  }
73
+ export {};
@@ -8,12 +8,11 @@ type ReadRenderArgs = {
8
8
  file_path?: string;
9
9
  sel?: string;
10
10
  };
11
- type ReadToolGroupOptions = {
12
- showContentPreview?: boolean;
13
- };
14
11
  export declare class ReadToolGroupComponent extends Container implements ToolExecutionHandle {
15
12
  #private;
16
- constructor(options?: ReadToolGroupOptions);
13
+ constructor(options?: {
14
+ showContentPreview?: boolean;
15
+ });
17
16
  updateArgs(args: ReadRenderArgs, toolCallId?: string): void;
18
17
  updateResult(result: {
19
18
  content: Array<{
@@ -32,5 +31,6 @@ export declare class ReadToolGroupComponent extends Container implements ToolExe
32
31
  */
33
32
  setManuallyExpanded(expanded: boolean): void;
34
33
  getComponent(): Component;
34
+ consumeVisibleTranscriptChange(): boolean;
35
35
  }
36
36
  export {};
@@ -9,4 +9,8 @@ export declare class SessionObserverOverlayComponent extends TranscriptViewerOve
9
9
  refreshFromRegistry(): void;
10
10
  handleInput(keyData: string): void;
11
11
  }
12
+ /**
13
+ * This deliberately remains the eager full-history projection. PR2 owns projection
14
+ * virtualization/incrementalization; source acquisition above only controls snapshot safety.
15
+ */
12
16
  export declare function entriesFromMessages(entries: readonly SessionMessageEntry[]): TranscriptViewerEntry[];
@@ -58,6 +58,8 @@ export interface SettingsCallbacks {
58
58
  getStatusLinePreview?: (width?: number) => string;
59
59
  /** Called when plugins change */
60
60
  onPluginsChanged?: () => void;
61
+ /** Called when an interactive setting cannot be committed. */
62
+ onError?: (message: string) => void;
61
63
  /** Called when settings panel is closed */
62
64
  onCancel: () => void;
63
65
  }
@@ -5,6 +5,8 @@ export interface ToolExecutionOptions {
5
5
  editFuzzyThreshold?: number;
6
6
  editAllowFuzzy?: boolean;
7
7
  hashlineAutoDropPureInsertDuplicates?: boolean;
8
+ /** Internal observer for visible asynchronous renderer mutations. */
9
+ onVisibleTranscriptMutation?: () => void;
8
10
  }
9
11
  export interface ToolExecutionHandle {
10
12
  updateArgs(args: any, toolCallId?: string): void;
@@ -29,6 +31,11 @@ export interface ToolExecutionHandle {
29
31
  * back to {@link setExpanded}.
30
32
  */
31
33
  setManuallyExpanded?(expanded: boolean): void;
34
+ /**
35
+ * Internal capability for dispatchers that need exact synchronous visible-output
36
+ * detection. Optional so existing structural handles remain source compatible.
37
+ */
38
+ consumeVisibleTranscriptChange?(): boolean;
32
39
  }
33
40
  /**
34
41
  * Component that renders a tool call with its result (updateable)
@@ -52,6 +59,7 @@ export declare class ToolExecutionComponent extends Container {
52
59
  details?: any;
53
60
  isError?: boolean;
54
61
  }, isPartial?: boolean, _toolCallId?: string): void;
62
+ consumeVisibleTranscriptChange(): boolean;
55
63
  /**
56
64
  * Stop spinner animation and cleanup resources.
57
65
  */
@@ -3,7 +3,10 @@ import type { InteractiveModeContext } from "../../modes/types";
3
3
  import type { AgentSessionEvent } from "../../session/agent-session";
4
4
  /** Test-only performance counters for advisory baseline tests. */
5
5
  export declare const __eventControllerPerfCounters: {
6
+ enabled: boolean;
6
7
  messageUpdateContentVisits: number;
8
+ enable(): void;
9
+ disable(): void;
7
10
  reset(): void;
8
11
  };
9
12
  export declare class EventController {
@@ -181,6 +181,8 @@ export declare class InteractiveMode implements InteractiveModeContext {
181
181
  }): Promise<void>;
182
182
  flushPendingBashComponents(): void;
183
183
  isKnownSlashCommand(text: string): boolean;
184
+ /** Advances the sticky-viewport source only for semantic transcript output. */
185
+ recordVisibleTranscriptMutation(): void;
184
186
  addMessageToChat(message: AgentMessage, options?: {
185
187
  populateHistory?: boolean;
186
188
  }): Component[];
@@ -1,5 +1,18 @@
1
1
  import type { ParsedIrcMessage } from "./utils/irc-message";
2
2
  type InlineMode = "persistent" | "ephemeral";
3
+ export declare const IRC_OBSERVATION_LEDGER_MAX_RECORDS = 10000;
4
+ export declare const IRC_OBSERVATION_LEDGER_MAX_RETAINED_UTF8_BYTES: number;
5
+ export declare const IRC_OBSERVATION_LEDGER_MAX_SEEN_IDENTITIES = 100000;
6
+ export declare const __ircLedgerPerfCounters: {
7
+ enabled: boolean;
8
+ epochAdvances: number;
9
+ snapshot(): {
10
+ epochAdvances: number;
11
+ };
12
+ enable(): void;
13
+ disable(): void;
14
+ reset(): void;
15
+ };
3
16
  export type IrcObservationRecord = Readonly<ParsedIrcMessage & {
4
17
  mode: InlineMode;
5
18
  observedAt: number;
@@ -10,6 +23,7 @@ export type IrcObservationRecord = Readonly<ParsedIrcMessage & {
10
23
  /** Runtime-only IRC observations. This intentionally has no persistence layer. */
11
24
  export declare class IrcObservationLedger {
12
25
  #private;
26
+ get mutationEpoch(): number;
13
27
  /** Inline observations expire after 10 seconds; closed-panel observations persist inline. */
14
28
  observe(message: ParsedIrcMessage, panelVisibleAtObservation: boolean): IrcObservationRecord | undefined;
15
29
  getRecord(observationId: string): IrcObservationRecord | undefined;
@@ -17,6 +31,8 @@ export declare class IrcObservationLedger {
17
31
  getInlineProjection(now: number): readonly IrcObservationRecord[];
18
32
  /** Returns and clears IDs whose retained payload was released. */
19
33
  drainEvictedObservationIds(): readonly string[];
20
- reset(): void;
34
+ reset(options?: {
35
+ retireCurrentSessionIdentities?: boolean;
36
+ }): void;
21
37
  }
22
38
  export {};
@@ -218,6 +218,8 @@ export interface InteractiveModeContext {
218
218
  getAssistantViewportAnchorId?(message: AssistantMessage): string;
219
219
  findLastAssistantMessage(): AssistantMessage | undefined;
220
220
  extractAssistantText(message: AssistantMessage): string;
221
+ /** Records one semantic visible-transcript mutation for the sticky viewport. */
222
+ recordVisibleTranscriptMutation?(): void;
221
223
  updateEditorTopBorder(): void;
222
224
  updateEditorBorderColor(): void;
223
225
  rebuildChatFromMessages(policy: TranscriptRebuildPolicy): void;
@@ -6,6 +6,22 @@ import { type SessionContext } from "../../session/session-manager";
6
6
  import { type ParsedIrcMessage } from "./irc-message";
7
7
  export type { TranscriptRebuildPolicy } from "../../modes/types";
8
8
  export declare function prepareTranscriptRebuild(ui: TUI, policy: TranscriptRebuildPolicy): void;
9
+ export declare const RESUME_PROGRESS_COMMIT_TIMEOUT_MS = 250;
10
+ export interface ResumeProgressLease {
11
+ readonly committed: Promise<boolean>;
12
+ clear(): void;
13
+ }
14
+ /**
15
+ * Mount a resume loader on the live status rail and wait for its render generation
16
+ * to commit before session I/O begins. The commit is advisory: a stopped or
17
+ * unavailable terminal resolves false and callers continue without blocking.
18
+ *
19
+ * Fail open (no-op lease, committed=false) when the status rail or UI lacks the
20
+ * child-mutation/render-commit surface required to mount progress. Headless and
21
+ * minimal controller contexts keep resume/migration semantics; full interactive
22
+ * TUI containers retain progress-before-switch.
23
+ */
24
+ export declare function acquireResumeProgressLease(ctx: Pick<InteractiveModeContext, "ui" | "statusContainer">): ResumeProgressLease;
9
25
  interface RenderInitialMessagesOptions {
10
26
  preserveExistingChat?: boolean;
11
27
  }
@@ -7,6 +7,11 @@ type SmitheryCliPollResponse = {
7
7
  apiKey?: string;
8
8
  message?: string;
9
9
  };
10
+ /** Test seam: the Smithery origin and env API key as resolved from trusted env. */
11
+ export declare function resolveSmitheryEnvForTest(): {
12
+ url: string;
13
+ apiKey: string | undefined;
14
+ };
10
15
  export declare function getSmitheryLoginUrl(): string;
11
16
  export declare function createSmitheryCliAuthSession(): Promise<SmitheryCliAuthSession>;
12
17
  export declare function pollSmitheryCliAuthSession(sessionId: string, signal?: AbortSignal): Promise<SmitheryCliPollResponse>;
@@ -73,6 +73,11 @@ export interface SessionLifecycleLaunchRequest {
73
73
  export declare function readSessionLifecycleLaunchRequest(value: string | undefined, now?: number): SessionLifecycleLaunchRequest;
74
74
  type CleanupEvidence = BrokerCleanupEvidence;
75
75
  export declare function validateBrokerModelPresetForTest(agentDir: string, requestedProfile: string): string | BrokerResponse;
76
+ /** Test seam: the session-host command override as resolved from trusted env. */
77
+ export declare function sdkSessionCommandOverrideForTest(): {
78
+ file: string;
79
+ args: string[];
80
+ } | undefined;
76
81
  export declare function setProcessIncarnationForTest(broker: Broker, value: ((pid: number) => string | undefined) | undefined): void;
77
82
  /** The child writes this only after its endpoint and semantic ready event are both live. */
78
83
  export declare function writeSessionLifecycleReady(root: string, id: string, effectMarker: string): Promise<void>;
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Ordering seam for an in-band SDK identity transition.
3
+ *
4
+ * A request arrives through predecessor A, so a successful terminal response cannot
5
+ * be published until successor B is ready. Native builds may provide a true
6
+ * send-only connection lease; source/dev builds use the conservative fallback in
7
+ * which the predecessor server remains alive until the terminal write completes.
8
+ */
9
+ export type TerminalSendOutcome = "written" | "disconnected" | "write_failed";
10
+ /** Fence/capability hooks may return false to reject; undefined means ok. */
11
+ export type IdentityControlGateResult = boolean | undefined;
12
+ export type IdentityControlGate = () => IdentityControlGateResult | Promise<IdentityControlGateResult>;
13
+ export interface IdentityControlSuccessPathInput {
14
+ /** Fence predecessor inbound work. The fence must not close its response writer. */
15
+ fence: IdentityControlGate;
16
+ /** Optional explicit proof that the predecessor writer is still usable. */
17
+ ensurePredecessorSendCapable?: IdentityControlGate;
18
+ /** Start successor B and resolve only after its public endpoint is ready. */
19
+ startSuccessor: () => Promise<void>;
20
+ /** Write and flush either the success or non-success terminal response. */
21
+ sendTerminal: () => Promise<TerminalSendOutcome>;
22
+ /** Release predecessor A after the terminal response has settled. */
23
+ stopPredecessor: () => Promise<void>;
24
+ /** Set only when a caller cannot use the retained-writer fallback. */
25
+ requireNativeControlDrain?: boolean;
26
+ }
27
+ export interface IdentityControlTerminalPathInput {
28
+ fenceInbound: IdentityControlGate;
29
+ ensurePredecessorSendCapable?: IdentityControlGate;
30
+ startSuccessorReady: () => Promise<void>;
31
+ sendTerminal: () => Promise<TerminalSendOutcome>;
32
+ stopPredecessor: () => Promise<void>;
33
+ requireNativeControlDrain?: boolean;
34
+ }
35
+ /**
36
+ * Probe the loaded native addon, never an environment flag or a TypeScript shim.
37
+ * Older/source installs intentionally report false so callers can select the
38
+ * retained-writer fallback or fail closed when detach is mandatory.
39
+ */
40
+ export declare function isNativeControlDrainAvailable(): boolean;
41
+ /**
42
+ * Run the only safe ordering for a successful identity-control response.
43
+ *
44
+ * The `finally` is deliberately around both successor startup and terminal
45
+ * delivery: a failed startup must not leave the fenced predecessor alive, and a
46
+ * failed/disconnected terminal write must still release it. When native detach
47
+ * is unavailable the caller is expected to keep A's server up (not call
48
+ * `stopAndWait`) until `sendTerminal` settles.
49
+ */
50
+ export declare function runIdentityControlSuccessPath(input: IdentityControlSuccessPathInput): Promise<TerminalSendOutcome>;
51
+ /** Compatibility spelling used by the host wiring design notes. */
52
+ export declare function runIdentityControlTerminalPath(input: IdentityControlTerminalPathInput): Promise<TerminalSendOutcome>;
@@ -30,6 +30,8 @@ import { type SdkStartupFailure } from "../startup-capability";
30
30
  import { type NotificationConfig } from "./config";
31
31
  import { NotificationSessionController } from "./session-control";
32
32
  import { type EnsureDaemonResult, type RegisterNotificationRootResult } from "./telegram-daemon";
33
+ export type { IdentityControlSuccessPathInput, IdentityControlTerminalPathInput, TerminalSendOutcome, } from "./control-drain-lease";
34
+ export { isNativeControlDrainAvailable, runIdentityControlSuccessPath, runIdentityControlTerminalPath, } from "./control-drain-lease";
33
35
  /** Where a `session_create` should run. Discriminated by `kind`. */
34
36
  export type SessionCreateTarget = {
35
37
  kind: "existing_path";
@@ -297,6 +299,8 @@ interface SessionRuntime {
297
299
  disposeGateListener: () => void;
298
300
  /** Whether notification-only delivery and answer resources are active. */
299
301
  notificationsActive: boolean;
302
+ /** Rejects new SDK frames while a leased terminal response drains. */
303
+ inboundFenced: boolean;
300
304
  /** Set as soon as terminal teardown is requested, before startup settles. */
301
305
  stopping: boolean;
302
306
  /** Recreates notification-only resources after `/notify on`. */
@@ -513,6 +517,17 @@ export declare class EphemeralTurnHost {
513
517
  * an identity for a transport that never became available is false success.
514
518
  */
515
519
  export declare function ensureConfiguredProviderDaemons(settings: Settings, cfg: NotificationConfig, ensureProviderDaemon?: (provider: "discord" | "slack", settings: Settings) => Promise<unknown>): Promise<void>;
520
+ /**
521
+ * Classify whether a session identity event must await notification endpoint startup.
522
+ * Only an interactive selector resume may defer this ancillary startup; all other
523
+ * events, including branches and unknown origins, fail closed to awaiting it.
524
+ */
525
+ export declare function shouldAwaitNotificationStartup(event: {
526
+ type: "session_switch" | "session_branch";
527
+ transition?: {
528
+ origin: string;
529
+ };
530
+ }): boolean;
516
531
  export declare function createNotificationsExtension(api: ExtensionAPI, options?: {
517
532
  settings?: Settings;
518
533
  ensureTelegramDaemon?: (input: {
@@ -539,4 +554,3 @@ export declare function createNotificationsExtension(api: ExtensionAPI, options?
539
554
  readNotificationFile?: (path: string) => Promise<Buffer>;
540
555
  readNotificationDiffStat?: (cwd: string) => Promise<string | undefined>;
541
556
  }): void;
542
- export {};
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Kind-aware invocation reconciliation (prompt | skill) with optional durable store.
3
+ * Preserves Q26 admit/first-terminal/capacity/TTL semantics; indexes and caps are per-kind.
4
+ */
5
+ import { type PromptCorrelation, type PromptReconciliationStatus, type TurnPromptReconciliation } from "./prompt-reconciliation";
6
+ import type { ReconciliationKind, ReconciliationStore } from "./reconciliation-store";
7
+ export type { ReconciliationKind };
8
+ export interface KindCorrelation extends PromptCorrelation {
9
+ kind: ReconciliationKind;
10
+ }
11
+ export interface KindAwareReconciliation {
12
+ admit(kind: ReconciliationKind, clientRef?: string): void;
13
+ releaseAdmission(kind: ReconciliationKind, clientRef?: string): void;
14
+ noteAccepted(kind: ReconciliationKind, correlation: PromptCorrelation, clientRef?: string, extra?: {
15
+ skillName?: string;
16
+ }): Promise<void>;
17
+ noteTransition(kind: ReconciliationKind, correlation: PromptCorrelation | undefined, frame: {
18
+ type: "agent_start" | "agent_end";
19
+ } | {
20
+ type: "agent_failed";
21
+ error: unknown;
22
+ }): Promise<void>;
23
+ lookup(kind: ReconciliationKind, selector: {
24
+ commandId?: string;
25
+ turnId?: string;
26
+ clientRef?: string;
27
+ }): TurnPromptReconciliation;
28
+ cleanup(): void;
29
+ activeCount(kind: ReconciliationKind): number;
30
+ /** Hydrate from durable store (call once at session host start). */
31
+ hydrateFromStore(): Promise<void>;
32
+ }
33
+ export declare function createKindAwareReconciliation(options?: {
34
+ now?: () => number;
35
+ store?: ReconciliationStore | null;
36
+ }): KindAwareReconciliation;
37
+ export type { PromptReconciliationStatus };
@@ -12,7 +12,8 @@
12
12
  * - Terminal records are retained for TERMINAL_TTL_MS and bounded to
13
13
  * TERMINAL_CAPACITY, evicted oldest-terminal-first by terminalAt; only then
14
14
  * does a lookup honestly report `unknown`.
15
- * - The durability floor is the live session process: restart means `unknown`.
15
+ * - Process-local durability floor is the live session process: restart means `unknown`.
16
+ * Session-scoped durable retention (kind-aware store) is provided by reconciliation-store.ts (#3032).
16
17
  * - The clientRef index is session-runtime scoped; a ref conflicts only while
17
18
  * retained and must never be reused as a retry mechanism.
18
19
  * - Terminal transitions settle once: the first terminal outcome wins.
@@ -0,0 +1,65 @@
1
+ import type { PromptCorrelation, PromptReconciliationStatus } from "./prompt-reconciliation";
2
+ export declare const RECONCILIATION_STORE_VERSION = 1;
3
+ export declare const RECONCILIATION_SESSION_ID_PATTERN: RegExp;
4
+ export declare const RECONCILIATION_DIR_NAME = ".sdk-reconciliation";
5
+ export type ReconciliationKind = "prompt" | "skill";
6
+ export interface DurableReconciliationRecord extends PromptCorrelation {
7
+ kind: ReconciliationKind;
8
+ clientRef?: string;
9
+ status: PromptReconciliationStatus;
10
+ error?: {
11
+ code: string;
12
+ message: string;
13
+ };
14
+ acceptedAt: number;
15
+ startedAt?: number;
16
+ terminalAt?: number;
17
+ /** Skill-only safe token; never skill args bodies. */
18
+ skillName?: string;
19
+ }
20
+ export interface ReconciliationStoreDocument {
21
+ version: typeof RECONCILIATION_STORE_VERSION;
22
+ sessionId: string;
23
+ records: DurableReconciliationRecord[];
24
+ }
25
+ export interface ReconciliationStoreFs {
26
+ mkdir(directory: string, options: {
27
+ recursive: true;
28
+ mode: number;
29
+ }): Promise<unknown>;
30
+ readFile(file: string, encoding: "utf8"): Promise<string>;
31
+ writeFile(file: string, data: string, options: {
32
+ mode: number;
33
+ }): Promise<void>;
34
+ rename(from: string, to: string): Promise<void>;
35
+ unlink(file: string): Promise<void>;
36
+ open(file: string, flags: string): Promise<{
37
+ sync(): Promise<void>;
38
+ close(): Promise<void>;
39
+ writeFile(data: string, encoding: "utf8"): Promise<void>;
40
+ }>;
41
+ }
42
+ export declare function isSafeReconciliationSessionId(sessionId: string): boolean;
43
+ /** Derive private store path; throws if sessionId is unsafe (path escape). */
44
+ export declare function reconciliationStorePath(sessionFile: string, sessionId: string): string;
45
+ /**
46
+ * Settle non-terminal durable records after process death: failed/process_restart.
47
+ * Meaning: reconciliation incomplete — not proof of agent failure.
48
+ */
49
+ export declare function settleProcessRestart(records: DurableReconciliationRecord[], now: number): DurableReconciliationRecord[];
50
+ export interface ReconciliationStore {
51
+ readonly path: string | null;
52
+ readonly sessionId: string;
53
+ /** Serialize mutations; reload not required for single-process host (in-memory + write). */
54
+ transact(mutator: (records: DurableReconciliationRecord[]) => DurableReconciliationRecord[]): Promise<void>;
55
+ load(): Promise<DurableReconciliationRecord[]>;
56
+ /** Snapshot currently held in memory after last load/transact. */
57
+ snapshot(): DurableReconciliationRecord[];
58
+ delete(): Promise<void>;
59
+ }
60
+ export declare function createReconciliationStore(options: {
61
+ sessionFile: string | null | undefined;
62
+ sessionId: string;
63
+ fs?: ReconciliationStoreFs;
64
+ now?: () => number;
65
+ }): ReconciliationStore;
@@ -13,7 +13,7 @@ export interface ControlSurface {
13
13
  answerAsk(id: string, answer: ControlValue): Promise<ControlValue> | ControlValue;
14
14
  answerGate(id: string, response: ControlValue, expectedSessionId?: string, idempotencyKey?: string): Promise<ControlValue> | ControlValue;
15
15
  approvePlan(id: string, choice: ControlValue, expectedSessionId?: string): Promise<ControlValue> | ControlValue;
16
- invokeSkill(name: string, args: ControlValue): Promise<ControlValue> | ControlValue;
16
+ invokeSkill(name: string, args: ControlValue, clientRef?: string): Promise<ControlValue> | ControlValue;
17
17
  setPlanMode(on: boolean): Promise<ControlValue> | ControlValue;
18
18
  operateGoal(op: string, objective?: string): Promise<ControlValue> | ControlValue;
19
19
  replaceTodo(items: ControlValue): Promise<ControlValue> | ControlValue;
@@ -7,6 +7,8 @@ export interface SessionSdkHostOptions extends HostEndpointAdapters {
7
7
  query?: (connectionId: string, frame: SdkFrame) => unknown | Promise<unknown>;
8
8
  /** Best-effort diagnostic observation of accepted control/query frames. */
9
9
  onRequest?: SdkRequestObserver;
10
+ /** Runs before a control response is sent; identity transitions use sendTerminal. */
11
+ beforeControlResponse?: (connectionId: string, request: SdkFrame, response: SdkFrame, sendTerminal: () => Promise<void>) => void | Promise<void>;
10
12
  /** Runs only after a successful control response has been sent to the client. */
11
13
  afterControlResponse?: (connectionId: string, request: SdkFrame, response: SdkFrame) => void | Promise<void>;
12
14
  installProviderDefinitions?: (capability: string, definitions: unknown) => void;
@@ -37,6 +37,11 @@ export interface SessionSurface {
37
37
  turnId?: string;
38
38
  clientRef?: string;
39
39
  }): unknown | Promise<unknown>;
40
+ getSkillInvokeStatus?(selector: {
41
+ commandId?: string;
42
+ turnId?: string;
43
+ clientRef?: string;
44
+ }): unknown | Promise<unknown>;
40
45
  /** Q27 effective model-profile catalog from the live session registry. */
41
46
  getModelProfiles?(): unknown[] | Promise<unknown[]>;
42
47
  /** Query rows backed by the session's installed binding map. */
@@ -81,8 +81,10 @@ import type { LoadedCustomCommand } from "../extensibility/custom-commands";
81
81
  import type { CustomTool } from "../extensibility/custom-tools/types";
82
82
  import type { ExtensionRunner } from "../extensibility/extensions";
83
83
  import type { CompactOptions, ContextUsage, ExtensionTranscriptEntry } from "../extensibility/extensions/types";
84
+ import type { SessionSwitchEvent } from "../extensibility/shared-events";
84
85
  import { type Skill, type SkillWarning } from "../extensibility/skills";
85
86
  import { type FileSlashCommand } from "../extensibility/slash-commands";
87
+ import { type MemoryGuardClaimsLease } from "../gjc-runtime/memory-guard-owner-claims";
86
88
  import { GoalRuntime } from "../goals/runtime";
87
89
  import type { Goal, GoalModeState } from "../goals/state";
88
90
  import type { HindsightSessionState } from "../hindsight/state";
@@ -101,6 +103,7 @@ import { type DefaultModelSelectionResult } from "./default-model-selection";
101
103
  export { DefaultModelSelectionRecoveryError } from "./default-model-selection";
102
104
  import type { ClientBridge, ClientBridgePermissionOption, ClientBridgePermissionOutcome, ClientBridgePermissionToolCall } from "./client-bridge";
103
105
  import { type ContributionPrepOptions, type ContributionPrepResult } from "./contribution-prep";
106
+ import type { MemoryGuardRestoreResult } from "./memory-guard-checkpoint-participant";
104
107
  import { type CustomMessage } from "./messages";
105
108
  import type { BranchSummaryEntry, CompactionEntry, NewSessionOptions, PreparedNewSession, RecoveryHydrationContext, RecoveryHydrationPromotionFence, SessionContext, SessionManager, SessionManagerCloseOutcome } from "./session-manager";
106
109
  import { ToolChoiceQueue } from "./tool-choice-queue";
@@ -314,6 +317,24 @@ export interface AgentSessionConfig {
314
317
  /** Optional provider-facing cache identity, distinct from logical session identity. */
315
318
  providerCacheSessionId?: string;
316
319
  }
320
+ export interface AgentSessionMemoryGuardRestoreInput extends Omit<AgentSessionConfig, "sessionManager" | "recoveryHydrationContext"> {
321
+ staged: Extract<MemoryGuardRestoreResult, {
322
+ kind: "staged";
323
+ }>;
324
+ claimsLease: MemoryGuardClaimsLease;
325
+ claimsStateDir: string;
326
+ }
327
+ export interface AgentMemoryGuardPromotionFence extends RecoveryHydrationPromotionFence {
328
+ readonly claimsLease: MemoryGuardClaimsLease;
329
+ }
330
+ export type AgentMemoryGuardRestoreResult = {
331
+ kind: "staged";
332
+ session: AgentSession;
333
+ promotionFence: AgentMemoryGuardPromotionFence;
334
+ } | {
335
+ kind: "blocked";
336
+ reason: "transcript-mismatch" | "hydration-context-mismatch" | "claim-mismatch" | "agent-messages-mismatch";
337
+ };
317
338
  type MidRunMaintenanceLifecycle = Parameters<NonNullable<AgentLoopConfig["maintainContext"]>>[1];
318
339
  /** Options for AgentSession.prompt() */
319
340
  export interface PromptOptions {
@@ -336,8 +357,21 @@ export interface PromptOptions {
336
357
  /**
337
358
  * Invoked after all prompt preflight checks pass and immediately before agent execution begins.
338
359
  * Cancellation before this callback rejects the prompt.
360
+ * Prefer `onPreflightAcceptCommit` for async durable acceptance (#3031/#3032).
339
361
  */
340
362
  onPreflightAccepted?: () => void;
363
+ /**
364
+ * Awaitable durable-accept fence. Called after preflight and before queue mutation
365
+ * or `#promptAgentWithIdleRetry`. SDK bus installs a closure that fsyncs acceptance.
366
+ */
367
+ onPreflightAcceptCommit?: () => void | Promise<void>;
368
+ /** Skill-only: prepared metadata before the durable fence (path/lineCount/cleanedArgs). */
369
+ onSkillPrepared?: (meta: {
370
+ name: string;
371
+ path: string;
372
+ lineCount?: number;
373
+ cleanedArgs?: string;
374
+ }) => void;
341
375
  }
342
376
  /** Result from a handoff operation. */
343
377
  export interface HandoffResult {
@@ -755,10 +789,11 @@ export declare class AgentSession {
755
789
  /** All messages including custom types like BashExecutionMessage */
756
790
  get messages(): AgentMessage[];
757
791
  get transcriptPromptGeneration(): number;
792
+ static restoreFromMemoryGuardCheckpoint(input: AgentSessionMemoryGuardRestoreInput): Promise<AgentMemoryGuardRestoreResult>;
758
793
  /** The immutable recovery authority, present only before external ownership promotion. */
759
794
  get recoveryHydrationContext(): RecoveryHydrationContext | undefined;
760
795
  /** Enables normal session mutations after the owner has published its durable fence and writer lease. */
761
- promoteRecoveryHydrationAfterOwnershipReadyFence(fence: RecoveryHydrationPromotionFence): Promise<void>;
796
+ promoteRecoveryHydrationAfterOwnershipReadyFence(fence: AgentMemoryGuardPromotionFence): Promise<void>;
762
797
  /** Main startup calls this exactly once, after a strict open returned `kind: "opened"`. */
763
798
  continuePersistedHistory(): Promise<void>;
764
799
  buildDisplaySessionContext(): SessionContext;
@@ -787,7 +822,7 @@ export declare class AgentSession {
787
822
  /** Live SDK configuration values exposed through the session query surface. */
788
823
  getSdkConfigItems(): Record<string, string>;
789
824
  setPlanModeState(state: PlanModeState | undefined): void;
790
- invokeSkill(name: string, args?: string, options?: Pick<PromptOptions, "onPreflightAccepted">): Promise<{
825
+ invokeSkill(name: string, args?: string, options?: Pick<PromptOptions, "onPreflightAccepted" | "onPreflightAcceptCommit" | "onSkillPrepared">): Promise<{
791
826
  name: string;
792
827
  path: string;
793
828
  args?: string;
@@ -842,7 +877,7 @@ export declare class AgentSession {
842
877
  * @throws Error if no model selected or no API key available (when not streaming)
843
878
  */
844
879
  prompt(text: string, options?: PromptOptions): Promise<void>;
845
- promptCustomMessage<T = unknown>(message: Pick<CustomMessage<T>, "customType" | "content" | "display" | "details" | "attribution">, options?: Pick<PromptOptions, "streamingBehavior" | "toolChoice" | "followUpQueuePolicy" | "onPreflightAccepted">): Promise<void>;
880
+ promptCustomMessage<T = unknown>(message: Pick<CustomMessage<T>, "customType" | "content" | "display" | "details" | "attribution">, options?: Pick<PromptOptions, "streamingBehavior" | "toolChoice" | "followUpQueuePolicy" | "onPreflightAccepted" | "onPreflightAcceptCommit">): Promise<void>;
846
881
  /**
847
882
  * Queue a steering message to interrupt the agent mid-run.
848
883
  */
@@ -882,6 +917,7 @@ export declare class AgentSession {
882
917
  sendUserMessage(content: string | (TextContent | ImageContent)[], options?: {
883
918
  deliverAs?: "steer" | "followUp";
884
919
  onPreflightAccepted?: () => void;
920
+ onPreflightAcceptCommit?: () => void | Promise<void>;
885
921
  }): Promise<void>;
886
922
  /**
887
923
  * Clear queued messages and return them.
@@ -1065,20 +1101,16 @@ export declare class AgentSession {
1065
1101
  * Get all available models with valid API keys.
1066
1102
  */
1067
1103
  getAvailableModels(): Model[];
1068
- /**
1069
- * Set thinking level.
1070
- * Saves the effective metadata-clamped level to the session, and to settings when requested.
1071
- */
1072
1104
  setThinkingLevel(level: ThinkingLevel | undefined, persist?: boolean): void;
1073
1105
  /**
1074
- * Set thinking level from a control surface. Global changes are durable or rolled back.
1106
+ * Set thinking level from a control surface. Global changes commit before affecting live state.
1075
1107
  */
1076
1108
  setThinkingLevelForControl(level: ThinkingLevel, persist: boolean): Promise<void>;
1077
1109
  getThinkingScopeForControl(): "session" | "global config";
1078
1110
  getThinkingVisibility(): "visible" | "hidden";
1079
1111
  setThinkingVisibility(visibility: "visible" | "hidden", persist?: boolean): void;
1080
1112
  /**
1081
- * Set thinking visibility from a control surface. Global changes are durable or rolled back.
1113
+ * Set thinking visibility from a control surface. Global changes commit before affecting live state.
1082
1114
  */
1083
1115
  setThinkingVisibilityForControl(visibility: "visible" | "hidden", persist: boolean): Promise<void>;
1084
1116
  /**
@@ -1316,7 +1348,9 @@ export declare class AgentSession {
1316
1348
  * Listeners are preserved and will continue receiving events.
1317
1349
  * @returns true if switch completed, false if cancelled by hook
1318
1350
  */
1319
- switchSession(sessionPath: string): Promise<boolean>;
1351
+ switchSession(sessionPath: string, options?: {
1352
+ transition?: SessionSwitchEvent["transition"];
1353
+ }): Promise<boolean>;
1320
1354
  /**
1321
1355
  * Create a branch from a specific entry.
1322
1356
  * Emits before_branch/branch session events to hooks.