@gajae-code/coding-agent 0.4.5 → 0.5.1

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 (185) hide show
  1. package/CHANGELOG.md +62 -0
  2. package/dist/types/async/job-manager.d.ts +26 -0
  3. package/dist/types/cli/args.d.ts +1 -0
  4. package/dist/types/cli/list-models.d.ts +6 -0
  5. package/dist/types/commands/gc.d.ts +26 -0
  6. package/dist/types/commands/harness.d.ts +3 -0
  7. package/dist/types/config/file-lock-gc.d.ts +5 -0
  8. package/dist/types/config/file-lock.d.ts +7 -0
  9. package/dist/types/config/model-profile-activation.d.ts +11 -2
  10. package/dist/types/config/model-profiles.d.ts +7 -0
  11. package/dist/types/config/model-registry.d.ts +3 -0
  12. package/dist/types/config/model-resolver.d.ts +2 -0
  13. package/dist/types/config/models-config-schema.d.ts +30 -0
  14. package/dist/types/config/settings-schema.d.ts +4 -3
  15. package/dist/types/coordinator/contract.d.ts +1 -1
  16. package/dist/types/defaults/gjc/extensions/grok-build/index.d.ts +1 -0
  17. package/dist/types/defaults/gjc/extensions/grok-cli-vendor/src/index.d.ts +1 -0
  18. package/dist/types/defaults/gjc/extensions/grok-cli-vendor/src/models/catalog.d.ts +25 -0
  19. package/dist/types/defaults/gjc/extensions/grok-cli-vendor/src/payload/sanitize.d.ts +27 -0
  20. package/dist/types/defaults/gjc/extensions/grok-cli-vendor/src/provider/billing.d.ts +8 -0
  21. package/dist/types/defaults/gjc/extensions/grok-cli-vendor/src/provider/register.d.ts +5 -0
  22. package/dist/types/defaults/gjc/extensions/grok-cli-vendor/src/provider/stream.d.ts +10 -0
  23. package/dist/types/defaults/gjc/extensions/grok-cli-vendor/src/provider/usage.d.ts +2 -0
  24. package/dist/types/defaults/gjc/extensions/grok-cli-vendor/src/shared/base-url.d.ts +2 -0
  25. package/dist/types/defaults/gjc/extensions/grok-cli-vendor/src/shared/errors.d.ts +38 -0
  26. package/dist/types/defaults/gjc-grok-cli.d.ts +5 -0
  27. package/dist/types/extensibility/extensions/index.d.ts +1 -0
  28. package/dist/types/extensibility/extensions/prefix-command-bridge.d.ts +35 -0
  29. package/dist/types/gjc-runtime/deep-interview-recorder.d.ts +103 -0
  30. package/dist/types/gjc-runtime/deep-interview-runtime.d.ts +2 -0
  31. package/dist/types/gjc-runtime/deep-interview-state.d.ts +112 -0
  32. package/dist/types/gjc-runtime/gc-render.d.ts +6 -0
  33. package/dist/types/gjc-runtime/gc-runtime.d.ts +134 -0
  34. package/dist/types/gjc-runtime/ledger-event-renderer.d.ts +68 -0
  35. package/dist/types/gjc-runtime/team-gc.d.ts +7 -0
  36. package/dist/types/gjc-runtime/team-runtime.d.ts +5 -1
  37. package/dist/types/gjc-runtime/tmux-common.d.ts +14 -0
  38. package/dist/types/gjc-runtime/tmux-gc.d.ts +7 -0
  39. package/dist/types/gjc-runtime/tmux-sessions.d.ts +13 -0
  40. package/dist/types/harness-control-plane/gc-adapter.d.ts +3 -0
  41. package/dist/types/harness-control-plane/owner.d.ts +8 -1
  42. package/dist/types/harness-control-plane/receipt-spool.d.ts +19 -0
  43. package/dist/types/harness-control-plane/state-machine.d.ts +6 -1
  44. package/dist/types/harness-control-plane/storage.d.ts +20 -0
  45. package/dist/types/harness-control-plane/types.d.ts +4 -0
  46. package/dist/types/hindsight/mental-models.d.ts +5 -5
  47. package/dist/types/modes/components/hook-selector.d.ts +7 -1
  48. package/dist/types/modes/components/model-selector.d.ts +1 -12
  49. package/dist/types/modes/controllers/command-controller.d.ts +1 -0
  50. package/dist/types/modes/rpc/rpc-client.d.ts +2 -2
  51. package/dist/types/modes/rpc/rpc-mode.d.ts +16 -1
  52. package/dist/types/modes/rpc/rpc-types.d.ts +4 -1
  53. package/dist/types/modes/shared/agent-wire/deep-interview-gate.d.ts +13 -0
  54. package/dist/types/modes/shared/agent-wire/session-registry.d.ts +25 -0
  55. package/dist/types/modes/shared/agent-wire/unattended-action-policy.d.ts +2 -0
  56. package/dist/types/sdk.d.ts +5 -0
  57. package/dist/types/session/agent-session.d.ts +3 -1
  58. package/dist/types/session/blob-store.d.ts +59 -4
  59. package/dist/types/session/session-manager.d.ts +24 -6
  60. package/dist/types/session/streaming-output.d.ts +3 -2
  61. package/dist/types/session/tool-choice-queue.d.ts +6 -0
  62. package/dist/types/skill-state/workflow-hud.d.ts +14 -0
  63. package/dist/types/task/receipt.d.ts +1 -0
  64. package/dist/types/task/types.d.ts +7 -0
  65. package/dist/types/thinking-metadata.d.ts +16 -0
  66. package/dist/types/thinking.d.ts +3 -12
  67. package/dist/types/tools/ask.d.ts +15 -1
  68. package/dist/types/tools/index.d.ts +2 -0
  69. package/dist/types/tools/resolve.d.ts +0 -10
  70. package/dist/types/tools/subagent.d.ts +6 -0
  71. package/dist/types/utils/tool-choice.d.ts +14 -1
  72. package/package.json +7 -7
  73. package/src/async/job-manager.ts +52 -0
  74. package/src/cli/args.ts +3 -0
  75. package/src/cli/auth-broker-cli.ts +1 -0
  76. package/src/cli/list-models.ts +13 -1
  77. package/src/cli.ts +9 -4
  78. package/src/commands/gc.ts +22 -0
  79. package/src/commands/harness.ts +43 -5
  80. package/src/commands/launch.ts +2 -2
  81. package/src/commands/session.ts +3 -1
  82. package/src/config/file-lock-gc.ts +181 -0
  83. package/src/config/file-lock.ts +14 -0
  84. package/src/config/model-profile-activation.ts +15 -3
  85. package/src/config/model-profiles.ts +264 -56
  86. package/src/config/model-resolver.ts +9 -6
  87. package/src/config/models-config-schema.ts +1 -0
  88. package/src/config/settings-schema.ts +6 -3
  89. package/src/coordinator/contract.ts +1 -0
  90. package/src/coordinator-mcp/server.ts +513 -26
  91. package/src/cursor.ts +16 -2
  92. package/src/defaults/gjc/agent.models.grok-cli.yml +36 -0
  93. package/src/defaults/gjc/extensions/grok-build/index.ts +1 -0
  94. package/src/defaults/gjc/extensions/grok-build/package.json +7 -0
  95. package/src/defaults/gjc/extensions/grok-cli-vendor/biome.json +39 -0
  96. package/src/defaults/gjc/extensions/grok-cli-vendor/package.json +8 -0
  97. package/src/defaults/gjc/extensions/grok-cli-vendor/src/index.ts +1 -0
  98. package/src/defaults/gjc/extensions/grok-cli-vendor/src/models/catalog.ts +155 -0
  99. package/src/defaults/gjc/extensions/grok-cli-vendor/src/payload/sanitize.ts +361 -0
  100. package/src/defaults/gjc/extensions/grok-cli-vendor/src/provider/billing.ts +57 -0
  101. package/src/defaults/gjc/extensions/grok-cli-vendor/src/provider/register.ts +99 -0
  102. package/src/defaults/gjc/extensions/grok-cli-vendor/src/provider/stream.ts +50 -0
  103. package/src/defaults/gjc/extensions/grok-cli-vendor/src/provider/usage.ts +56 -0
  104. package/src/defaults/gjc/extensions/grok-cli-vendor/src/shared/base-url.ts +36 -0
  105. package/src/defaults/gjc/extensions/grok-cli-vendor/src/shared/errors.ts +44 -0
  106. package/src/defaults/gjc/skills/deep-interview/SKILL.md +131 -113
  107. package/src/defaults/gjc/skills/deep-interview/lateral-review-panel.md +49 -0
  108. package/src/defaults/gjc/skills/team/SKILL.md +3 -2
  109. package/src/defaults/gjc/skills/ultragoal/SKILL.md +8 -2
  110. package/src/defaults/gjc-defaults.ts +7 -0
  111. package/src/defaults/gjc-grok-cli.ts +22 -0
  112. package/src/export/html/index.ts +13 -9
  113. package/src/extensibility/extensions/index.ts +1 -0
  114. package/src/extensibility/extensions/prefix-command-bridge.ts +128 -0
  115. package/src/gjc-runtime/deep-interview-recorder.ts +417 -0
  116. package/src/gjc-runtime/deep-interview-runtime.ts +18 -26
  117. package/src/gjc-runtime/deep-interview-state.ts +324 -0
  118. package/src/gjc-runtime/gc-render.ts +70 -0
  119. package/src/gjc-runtime/gc-runtime.ts +403 -0
  120. package/src/gjc-runtime/ledger-event-renderer.ts +164 -0
  121. package/src/gjc-runtime/ralplan-runtime.ts +58 -7
  122. package/src/gjc-runtime/state-renderer.ts +12 -3
  123. package/src/gjc-runtime/state-runtime.ts +46 -29
  124. package/src/gjc-runtime/team-gc.ts +49 -0
  125. package/src/gjc-runtime/team-runtime.ts +211 -8
  126. package/src/gjc-runtime/tmux-common.ts +29 -0
  127. package/src/gjc-runtime/tmux-gc.ts +176 -0
  128. package/src/gjc-runtime/tmux-sessions.ts +68 -12
  129. package/src/gjc-runtime/ultragoal-runtime.ts +517 -41
  130. package/src/gjc-runtime/workflow-manifest.generated.json +27 -1
  131. package/src/gjc-runtime/workflow-manifest.ts +16 -1
  132. package/src/harness-control-plane/gc-adapter.ts +184 -0
  133. package/src/harness-control-plane/owner.ts +89 -27
  134. package/src/harness-control-plane/receipt-spool.ts +128 -0
  135. package/src/harness-control-plane/state-machine.ts +27 -6
  136. package/src/harness-control-plane/storage.ts +93 -0
  137. package/src/harness-control-plane/types.ts +4 -0
  138. package/src/hindsight/mental-models.ts +17 -16
  139. package/src/internal-urls/docs-index.generated.ts +14 -8
  140. package/src/main.ts +7 -2
  141. package/src/modes/components/assistant-message.ts +26 -14
  142. package/src/modes/components/diff.ts +97 -0
  143. package/src/modes/components/hook-selector.ts +19 -0
  144. package/src/modes/components/model-selector.ts +370 -181
  145. package/src/modes/components/status-line/segments.ts +1 -1
  146. package/src/modes/components/tool-execution.ts +30 -13
  147. package/src/modes/controllers/command-controller.ts +25 -6
  148. package/src/modes/controllers/extension-ui-controller.ts +3 -0
  149. package/src/modes/controllers/selector-controller.ts +34 -42
  150. package/src/modes/rpc/rpc-client.ts +3 -2
  151. package/src/modes/rpc/rpc-mode.ts +187 -39
  152. package/src/modes/rpc/rpc-types.ts +5 -2
  153. package/src/modes/shared/agent-wire/command-dispatch.ts +279 -257
  154. package/src/modes/shared/agent-wire/command-validation.ts +11 -0
  155. package/src/modes/shared/agent-wire/deep-interview-gate.ts +30 -1
  156. package/src/modes/shared/agent-wire/session-registry.ts +109 -0
  157. package/src/modes/shared/agent-wire/unattended-action-policy.ts +24 -0
  158. package/src/modes/shared/agent-wire/unattended-run-controller.ts +23 -3
  159. package/src/modes/shared/agent-wire/unattended-session.ts +16 -1
  160. package/src/sdk.ts +46 -5
  161. package/src/secrets/obfuscator.ts +102 -27
  162. package/src/session/agent-session.ts +179 -25
  163. package/src/session/blob-store.ts +148 -6
  164. package/src/session/session-manager.ts +311 -60
  165. package/src/session/streaming-output.ts +185 -122
  166. package/src/session/tool-choice-queue.ts +23 -0
  167. package/src/setup/hermes/templates/operator-instructions.v1.md +7 -1
  168. package/src/skill-state/workflow-hud.ts +106 -10
  169. package/src/slash-commands/builtin-registry.ts +3 -2
  170. package/src/task/executor.ts +78 -6
  171. package/src/task/receipt.ts +5 -0
  172. package/src/task/render.ts +21 -1
  173. package/src/task/types.ts +8 -0
  174. package/src/thinking-metadata.ts +51 -0
  175. package/src/thinking.ts +26 -46
  176. package/src/tools/ask.ts +56 -1
  177. package/src/tools/bash.ts +1 -1
  178. package/src/tools/index.ts +2 -0
  179. package/src/tools/job.ts +3 -2
  180. package/src/tools/monitor.ts +36 -1
  181. package/src/tools/resolve.ts +93 -18
  182. package/src/tools/subagent-render.ts +9 -0
  183. package/src/tools/subagent.ts +26 -2
  184. package/src/utils/edit-mode.ts +1 -1
  185. package/src/utils/tool-choice.ts +45 -16
@@ -2,7 +2,7 @@
2
2
  * Generic selector component for hooks.
3
3
  * Displays a list of string options with keyboard navigation.
4
4
  */
5
- import { Container, type TUI } from "@gajae-code/tui";
5
+ import { type AutocompleteProvider, Container, type TUI } from "@gajae-code/tui";
6
6
  export interface HookSelectorOptions {
7
7
  tui?: TUI;
8
8
  timeout?: number;
@@ -33,6 +33,12 @@ export interface HookSelectorOptions {
33
33
  optionLabel: string;
34
34
  onSubmit: (text: string) => void;
35
35
  };
36
+ /**
37
+ * Autocomplete provider for the inline custom-input editor. When present,
38
+ * the "Other (type your own)" editor gains the same `@` file-link and `/`
39
+ * completion behavior as the main prompt editor.
40
+ */
41
+ autocompleteProvider?: AutocompleteProvider;
36
42
  }
37
43
  export declare class HookSelectorComponent extends Container {
38
44
  #private;
@@ -5,24 +5,12 @@ import type { GjcModelAssignmentTargetId, ModelRegistry } from "../../config/mod
5
5
  import { type ScopedModelSelection } from "../../config/model-resolver";
6
6
  import type { Settings } from "../../config/settings";
7
7
  type ScopedModelItem = ScopedModelSelection;
8
- export interface ModelAssignmentPreset {
9
- id: "openai-codex";
10
- label: string;
11
- description: string;
12
- assignments: Partial<Record<GjcModelAssignmentTargetId, ThinkingLevel>>;
13
- }
14
8
  export type ModelSelectorSelection = {
15
9
  kind: "assignment";
16
10
  model: Model;
17
11
  role: GjcModelAssignmentTargetId | null;
18
12
  thinkingLevel?: ThinkingLevel;
19
13
  selector?: string;
20
- } | {
21
- kind: "preset";
22
- model: Model;
23
- selector: string;
24
- preset: ModelAssignmentPreset;
25
- assignments: Record<GjcModelAssignmentTargetId, ThinkingLevel>;
26
14
  } | {
27
15
  kind: "profile";
28
16
  profileName: string;
@@ -41,6 +29,7 @@ export declare class ModelSelectorComponent extends Container {
41
29
  constructor(tui: TUI, _currentModel: Model | undefined, settings: Settings, modelRegistry: ModelRegistry, scopedModels: ReadonlyArray<ScopedModelItem>, onSelect: RoleSelectCallback, onCancel: () => void, options?: {
42
30
  temporaryOnly?: boolean;
43
31
  initialSearchInput?: string;
32
+ sessionId?: string;
44
33
  });
45
34
  handleInput(keyData: string): void;
46
35
  getSearchInput(): Input;
@@ -35,3 +35,4 @@ export declare class CommandController {
35
35
  handleContributionPrepCommand(customInstructions?: string): Promise<void>;
36
36
  }
37
37
  export declare function renderProviderSection(details: ProviderDetails, uiTheme: Pick<typeof theme, "fg">): string;
38
+ export declare function renderUsageReports(reports: UsageReport[], uiTheme: typeof theme, nowMs: number, availableWidth: number): string;
@@ -8,7 +8,7 @@ import type { CompactionResult } from "@gajae-code/agent-core/compaction";
8
8
  import type { ImageContent, Model } from "@gajae-code/ai";
9
9
  import type { BashResult } from "../../exec/bash-executor";
10
10
  import type { SessionStats } from "../../session/agent-session";
11
- import type { RpcExtensionUIRequest, RpcHandoffResult, RpcHostToolDefinition, RpcSessionState, RpcUnattendedAccepted, RpcUnattendedDeclaration, RpcWorkflowGate, RpcWorkflowGateResolution } from "./rpc-types";
11
+ import type { RpcExtensionUIRequest, RpcGetStateInclude, RpcHandoffResult, RpcHostToolDefinition, RpcSessionState, RpcUnattendedAccepted, RpcUnattendedDeclaration, RpcWorkflowGate, RpcWorkflowGateResolution } from "./rpc-types";
12
12
  export interface RpcClientOptions {
13
13
  /** Path to the CLI entry point (default: searches for dist/cli.js) */
14
14
  cliPath?: string;
@@ -115,7 +115,7 @@ export declare class RpcClient {
115
115
  /**
116
116
  * Get current session state.
117
117
  */
118
- getState(): Promise<RpcSessionState>;
118
+ getState(include?: RpcGetStateInclude[]): Promise<RpcSessionState>;
119
119
  /**
120
120
  * Set model by provider and ID.
121
121
  */
@@ -1,3 +1,15 @@
1
+ /**
2
+ * RPC mode: Headless operation with JSON stdin/stdout protocol.
3
+ *
4
+ * Used for embedding the agent in other applications.
5
+ * Receives commands as JSON on stdin, outputs events and responses as JSON on stdout.
6
+ *
7
+ * Protocol:
8
+ * - Commands: JSON objects with `type` field, optional `id` for correlation
9
+ * - Responses: JSON objects with `type: "response"`, `command`, `success`, and optional `data`/`error`
10
+ * - Events: AgentSessionEvent objects streamed as they occur
11
+ * - Extension UI: Extension UI requests are emitted, client responds with extension_ui_response
12
+ */
1
13
  import type { ExtensionUIContext, ExtensionUIDialogOptions } from "../../extensibility/extensions";
2
14
  import type { AgentSession } from "../../session/agent-session";
3
15
  import type { RpcExtensionUIRequest, RpcExtensionUIResponse, RpcHostToolCallRequest, RpcHostToolCancelRequest, RpcHostUriCancelRequest, RpcHostUriRequest, RpcResponse } from "./rpc-types";
@@ -7,6 +19,7 @@ export type PendingExtensionRequest = {
7
19
  reject: (error: Error) => void;
8
20
  };
9
21
  type RpcOutput = (obj: RpcResponse | RpcExtensionUIRequest | RpcHostToolCallRequest | RpcHostToolCancelRequest | RpcHostUriRequest | RpcHostUriCancelRequest | object) => void;
22
+ export declare function shouldEmitRpcTitlesForTest(): boolean;
10
23
  export declare function requestRpcEditor(pendingRequests: Map<string, PendingExtensionRequest>, output: RpcOutput, title: string, prefill?: string, dialogOptions?: ExtensionUIDialogOptions, editorOptions?: {
11
24
  promptStyle?: boolean;
12
25
  }): Promise<string | undefined>;
@@ -14,4 +27,6 @@ export declare function requestRpcEditor(pendingRequests: Map<string, PendingExt
14
27
  * Run in RPC mode.
15
28
  * Listens for JSON commands on stdin, outputs events and responses on stdout.
16
29
  */
17
- export declare function runRpcMode(session: AgentSession, setToolUIContext?: (uiContext: ExtensionUIContext, hasUI: boolean) => void): Promise<never>;
30
+ export declare function runRpcMode(session: AgentSession, setToolUIContext?: (uiContext: ExtensionUIContext, hasUI: boolean) => void, options?: {
31
+ listen?: string;
32
+ }): Promise<never>;
@@ -11,6 +11,7 @@ import type { BashResult } from "../../exec/bash-executor";
11
11
  import type { ContextUsage } from "../../extensibility/extensions/types";
12
12
  import type { SessionStats } from "../../session/agent-session";
13
13
  import type { TodoPhase } from "../../tools/todo-write";
14
+ export type RpcGetStateInclude = "tools" | "dumpTools" | "systemPrompt";
14
15
  export type RpcCommand = {
15
16
  id?: string;
16
17
  type: "prompt";
@@ -42,6 +43,7 @@ export type RpcCommand = {
42
43
  } | {
43
44
  id?: string;
44
45
  type: "get_state";
46
+ include?: RpcGetStateInclude[];
45
47
  } | {
46
48
  id?: string;
47
49
  type: "set_todos";
@@ -168,8 +170,9 @@ export interface RpcSessionState {
168
170
  messageCount: number;
169
171
  queuedMessageCount: number;
170
172
  todoPhases: TodoPhase[];
171
- /** For session dump / export (plain-text parity with /dump). */
173
+ /** Optional static system prompt blocks. Omitted by default; request with get_state include ["systemPrompt"]. */
172
174
  systemPrompt?: string[];
175
+ /** Optional static tool schemas. Omitted by default; request with get_state include ["tools"]. */
173
176
  dumpTools?: Array<{
174
177
  name: string;
175
178
  description: string;
@@ -1,6 +1,14 @@
1
1
  import type { OpenGateInput } from "./workflow-gate-broker";
2
2
  /** "Other (type your own)" sentinel, mirroring the interactive ask tool. */
3
3
  export declare const GATE_OTHER_OPTION = "Other (type your own)";
4
+ /** Optional structured deep-interview round metadata supplied by the agent. */
5
+ export interface AskGateDeepInterviewState {
6
+ round_id?: string;
7
+ round: number;
8
+ component: string;
9
+ dimension: string;
10
+ ambiguity: number;
11
+ }
4
12
  export interface AskGateQuestion {
5
13
  id: string;
6
14
  question: string;
@@ -9,6 +17,11 @@ export interface AskGateQuestion {
9
17
  }>;
10
18
  multi?: boolean;
11
19
  recommended?: number;
20
+ /**
21
+ * Structured round metadata. When present it is the authoritative source for gate
22
+ * `stage_state`; when absent, the question text is regex-parsed as a fallback.
23
+ */
24
+ deepInterview?: AskGateDeepInterviewState;
12
25
  }
13
26
  export interface AskGateResult {
14
27
  id: string;
@@ -0,0 +1,25 @@
1
+ export type RpcSessionTransport = "stdio" | "bridge" | "socket";
2
+ export interface RpcSessionRecord {
3
+ sessionId: string;
4
+ pid: number;
5
+ transport: RpcSessionTransport;
6
+ cwd: string;
7
+ model?: string;
8
+ /** ISO-8601 start timestamp. */
9
+ startedAt: string;
10
+ /** Reachable endpoint for persistent transports (issue 09); absent for stdio. */
11
+ endpoint?: string;
12
+ }
13
+ /**
14
+ * Write (or replace) the registry record for a session. The record is written to
15
+ * a same-directory temp file and atomically renamed into place so a concurrent
16
+ * reader never observes (and reaps) a partially-written record.
17
+ */
18
+ export declare function registerRpcSession(record: RpcSessionRecord, agentDir?: string): Promise<string>;
19
+ /** Remove a session's registry record. Best-effort: a missing file is not an error. */
20
+ export declare function unregisterRpcSession(sessionId: string, agentDir?: string): Promise<void>;
21
+ /**
22
+ * List live RPC sessions, reaping records whose process is gone or whose file is
23
+ * unparseable. Returns records sorted by `startedAt` ascending.
24
+ */
25
+ export declare function listRpcSessions(agentDir?: string): Promise<RpcSessionRecord[]>;
@@ -20,6 +20,8 @@ import type { RpcUnattendedActionClass } from "../../rpc/rpc-types";
20
20
  import type { BridgeCommandScope } from "./scopes";
21
21
  /** Coarse command scope -> `command.<scope>` action class. */
22
22
  export declare function actionClassForScope(scope: BridgeCommandScope): RpcUnattendedActionClass;
23
+ /** Runtime list of every v1 action class — membership-validation source for negotiate (#319). */
24
+ export declare const RPC_UNATTENDED_ACTION_CLASSES: readonly RpcUnattendedActionClass[];
23
25
  /**
24
26
  * Classify a (possibly compound / nested) bash command into the most severe
25
27
  * action class across all statements and nested substitutions. Fail-closed.
@@ -40,6 +40,11 @@ export interface CreateAgentSessionOptions {
40
40
  modelPattern?: string;
41
41
  /** Thinking selector. Default: from settings, else unset */
42
42
  thinkingLevel?: ThinkingLevel;
43
+ /** Runtime substitution metadata for the initial model_change session event. */
44
+ modelSubstitution?: {
45
+ requestedModel: Model;
46
+ reason: string;
47
+ };
43
48
  /** Models available for cycling (Ctrl+P in interactive mode) */
44
49
  scopedModels?: ScopedModelSelection[];
45
50
  /** System prompt blocks. Array replaces default, function receives default blocks and returns final blocks. */
@@ -143,7 +143,7 @@ export type AgentSessionEvent = AgentEvent | {
143
143
  };
144
144
  /** Listener function for agent session events */
145
145
  export type AgentSessionEventListener = (event: AgentSessionEvent) => void;
146
- export type AsyncJobSnapshotItem = Pick<AsyncJob, "id" | "type" | "status" | "label" | "startTime" | "metadata">;
146
+ export type AsyncJobSnapshotItem = Pick<AsyncJob, "id" | "type" | "status" | "label" | "startTime" | "endTime" | "metadata">;
147
147
  export interface AsyncJobSnapshot {
148
148
  running: AsyncJobSnapshotItem[];
149
149
  recent: AsyncJobSnapshotItem[];
@@ -678,6 +678,8 @@ export declare class AgentSession {
678
678
  selector?: string;
679
679
  thinkingLevel?: ThinkingLevel;
680
680
  }): Promise<void>;
681
+ setActiveModelProfile(name: string | undefined): void;
682
+ getActiveModelProfile(): string | undefined;
681
683
  /**
682
684
  * Set model temporarily (for this session only).
683
685
  * Validates API key, saves to session log but NOT to settings.
@@ -31,6 +31,14 @@ export declare class BlobStore {
31
31
  /** Check if a blob exists. */
32
32
  has(hash: string): Promise<boolean>;
33
33
  }
34
+ export declare class EphemeralBlobStore extends BlobStore {
35
+ #private;
36
+ constructor(dir: string);
37
+ putSync(data: Buffer): BlobPutResult;
38
+ getSync(hash: string): Buffer | null;
39
+ clear(): void;
40
+ dispose(): void;
41
+ }
34
42
  export declare class MemoryBlobStore extends BlobStore {
35
43
  #private;
36
44
  constructor();
@@ -40,6 +48,13 @@ export declare class MemoryBlobStore extends BlobStore {
40
48
  getSync(hash: string): Buffer | null;
41
49
  has(hash: string): Promise<boolean>;
42
50
  }
51
+ export declare class ResidentBlobMissingError extends Error {
52
+ readonly hash: string;
53
+ readonly kind: "text" | "imageUrl" | "imageData";
54
+ readonly sessionId?: string | undefined;
55
+ readonly sessionFile?: string | undefined;
56
+ constructor(hash: string, kind: "text" | "imageUrl" | "imageData", sessionId?: string | undefined, sessionFile?: string | undefined);
57
+ }
43
58
  /** Check if a data string is a blob reference. */
44
59
  export declare function isBlobRef(data: string): boolean;
45
60
  /** Extract the SHA-256 hash from a blob reference string. */
@@ -63,18 +78,58 @@ export declare function externalizeImageDataSync(blobStore: BlobStore, base64Dat
63
78
  /**
64
79
  * Resolve an externalized provider image data URL back to its original string.
65
80
  * If the data is not a blob reference, returns it unchanged.
66
- * If the blob is missing, logs a warning and returns the reference as-is.
81
+ *
82
+ * LEGACY PERSISTED-IMAGE COMPATIBILITY BOUNDARY: when the persisted blob is missing
83
+ * (e.g. resuming an old session whose image blob was pruned), this warns and returns
84
+ * the reference as-is rather than throwing, so legacy resume degrades gracefully.
85
+ * New resident byte-sensitive TEXT uses the fail-closed path instead
86
+ * (`resolveTextBlobSync` -> `ResidentBlobMissingError`). Do NOT route new byte-sensitive
87
+ * resident data through this warn-and-return path.
67
88
  */
68
89
  export declare function resolveImageDataUrl(blobStore: BlobStore, data: string): Promise<string>;
69
90
  /**
70
91
  * Resolve a blob reference back to base64 data.
71
92
  * If the data is not a blob reference, returns it unchanged.
72
- * If the blob is missing, logs a warning and returns a placeholder.
93
+ *
94
+ * LEGACY PERSISTED-IMAGE COMPATIBILITY BOUNDARY: when the blob is missing this warns
95
+ * and returns the reference as-is (downstream sees an invalid base64 ref but does not
96
+ * crash), preserving legacy-session resume. Byte-sensitive resident TEXT is fail-closed
97
+ * via `resolveTextBlobSync`; do NOT route new byte-sensitive resident data here.
73
98
  */
74
99
  export declare function resolveImageData(blobStore: BlobStore, data: string): Promise<string>;
75
100
  /** Synchronously resolve an externalized provider image data URL back to its original string. */
76
101
  export declare function resolveImageDataUrlSync(blobStore: BlobStore, data: string): string;
77
102
  /** Synchronously resolve a blob reference back to base64 data. */
78
103
  export declare function resolveImageDataSync(blobStore: BlobStore, data: string): string;
79
- /** Synchronously resolve a blob reference back to utf8 text. */
80
- export declare function resolveTextBlobSync(blobStore: BlobStore, data: string): string;
104
+ /**
105
+ * Synchronously resolve a blob reference back to utf8 text.
106
+ *
107
+ * FAIL-CLOSED byte-sensitive path: a missing resident blob throws
108
+ * `ResidentBlobMissingError` rather than degrading, so a missing resident text blob can
109
+ * never silently leak a `blob:sha256:` ref into provider payloads, UI, or exports.
110
+ * (Contrast the legacy persisted-image warn-and-return resolvers above.)
111
+ */
112
+ export declare function resolveTextBlobSync(blobStore: BlobStore, data: string, context?: {
113
+ kind?: "text";
114
+ sessionId?: string;
115
+ sessionFile?: string;
116
+ }): string;
117
+ /**
118
+ * FAIL-CLOSED resident variant of {@link resolveImageDataUrlSync}: a missing resident
119
+ * image-data-url blob throws `ResidentBlobMissingError` ("imageUrl") instead of warn-returning,
120
+ * so resident byte-sensitive provider image data can never leak a `blob:sha256:` ref into
121
+ * materialized entries, context, or provider payloads. The warn-and-return `resolveImageDataUrl*`
122
+ * resolvers remain ONLY for legacy persisted-image resume.
123
+ */
124
+ export declare function resolveResidentImageDataUrlSync(blobStore: BlobStore, data: string, context?: {
125
+ sessionId?: string;
126
+ sessionFile?: string;
127
+ }): string;
128
+ /**
129
+ * FAIL-CLOSED resident variant of {@link resolveImageDataSync}: a missing resident image blob
130
+ * throws `ResidentBlobMissingError` ("imageData") instead of warn-returning a placeholder.
131
+ */
132
+ export declare function resolveResidentImageDataSync(blobStore: BlobStore, data: string, context?: {
133
+ sessionId?: string;
134
+ sessionFile?: string;
135
+ }): string;
@@ -40,6 +40,12 @@ export interface ModelChangeEntry extends SessionEntryBase {
40
40
  model: string;
41
41
  /** Role: "default" or an agent role. Undefined treated as "default" */
42
42
  role?: string;
43
+ /** Requested model before a runtime substitution/fallback, in "provider/modelId" format. */
44
+ previousModel?: string;
45
+ /** Machine-readable reason for runtime model substitution/fallback. */
46
+ reason?: string;
47
+ /** Effective thinking level when the change was recorded. */
48
+ thinkingLevel?: string | null;
43
49
  }
44
50
  export interface ServiceTierChangeEntry extends SessionEntryBase {
45
51
  type: "service_tier_change";
@@ -262,6 +268,7 @@ interface SessionManagerStateSnapshot {
262
268
  flushed: boolean;
263
269
  needsFullRewriteOnNextPersist: boolean;
264
270
  fileEntries: FileEntry[];
271
+ materializedFileEntries: FileEntry[];
265
272
  }
266
273
  export declare class SessionManager {
267
274
  #private;
@@ -270,6 +277,18 @@ export declare class SessionManager {
270
277
  private readonly persist;
271
278
  private readonly storage;
272
279
  private constructor();
280
+ /**
281
+ * Snapshot of the five cache-invalidation revision domains (plan: Lane 1
282
+ * revision contract). Tests assert the invalidation mapping through this;
283
+ * future export/label-view caches key off their respective domains.
284
+ */
285
+ revisionSnapshot(): {
286
+ entry: number;
287
+ leaf: number;
288
+ headerExport: number;
289
+ label: number;
290
+ replayMetadata: number;
291
+ };
273
292
  /** Puts a binary blob into the blob store and returns the blob reference */
274
293
  putBlob(data: Buffer): Promise<BlobPutResult>;
275
294
  captureState(): SessionManagerStateSnapshot;
@@ -388,7 +407,11 @@ export declare class SessionManager {
388
407
  * @param model Model in "provider/modelId" format
389
408
  * @param role Optional role (default: "default")
390
409
  */
391
- appendModelChange(model: string, role?: string): string;
410
+ appendModelChange(model: string, role?: string, metadata?: {
411
+ previousModel?: string;
412
+ reason?: string;
413
+ thinkingLevel?: string | null;
414
+ }): string;
392
415
  /** Append session init metadata (for subagent debugging/replay). Returns entry id. */
393
416
  appendSessionInit(init: {
394
417
  systemPrompt: string;
@@ -480,11 +503,6 @@ export declare class SessionManager {
480
503
  * Get session header.
481
504
  */
482
505
  getHeader(): SessionHeader | null;
483
- /**
484
- * Get all session entries (excludes header). Returns a shallow copy.
485
- * The session is append-only: use appendXXX() to add entries, branch() to
486
- * change the leaf pointer. Entries cannot be modified or deleted.
487
- */
488
506
  getEntries(): SessionEntry[];
489
507
  /**
490
508
  * Get the session as a tree structure. Returns a shallow defensive copy of all entries.
@@ -159,8 +159,9 @@ export declare class OutputSink {
159
159
  #private;
160
160
  constructor(options?: OutputSinkOptions);
161
161
  /**
162
- * Push a chunk of output. The buffer management and onChunk callback run
163
- * synchronously. File sink writes are deferred and serialized internally.
162
+ * Push a chunk of output. Raw bytes are mirrored to artifacts, while the
163
+ * visible retention windows are selected from the sanitized/column-capped
164
+ * stream so production-default display matches the historical processed view.
164
165
  */
165
166
  push(chunk: string): void;
166
167
  createInput(): WritableStream<Uint8Array | string>;
@@ -63,6 +63,12 @@ export declare class ToolChoiceQueue {
63
63
  * lost value at the head of the queue; anything else drops it.
64
64
  */
65
65
  reject(reason: RejectInfo["reason"]): void;
66
+ /**
67
+ * Drop an in-flight yield after runtime tool_choice degradation. This bypasses
68
+ * onRejected so forced directives cannot requeue themselves after the model
69
+ * proved incapable of honoring the forced choice.
70
+ */
71
+ degradeInFlight(reason?: string): string | undefined;
66
72
  /** True if there is an in-flight yield that hasn't been resolved or rejected. */
67
73
  get hasInFlight(): boolean;
68
74
  /** Peek the in-flight directive's onInvoked handler, if any. */
@@ -18,6 +18,8 @@ interface RalplanHudState extends WorkflowGateHudState {
18
18
  stage?: string;
19
19
  waiting?: string;
20
20
  iteration?: number;
21
+ iterationFromIndex?: number;
22
+ stages?: string;
21
23
  verdict?: string;
22
24
  latestSummary?: string;
23
25
  pendingApproval?: boolean;
@@ -61,6 +63,18 @@ interface TeamHudState extends WorkflowGateHudState {
61
63
  };
62
64
  }
63
65
  export declare function buildDeepInterviewHudSummary(state: DeepInterviewHudState): WorkflowHudSummary;
66
+ export interface DeepInterviewHudDeriveOptions {
67
+ phase?: string;
68
+ specStatus?: string;
69
+ updatedAt?: string;
70
+ }
71
+ /**
72
+ * Single source of deep-interview HUD derivation. Reads a complete (normalized)
73
+ * mode-state envelope so recorder, `gjc state write`, reconcile, seed, and handoff
74
+ * all produce identical chips. Topology-aware `target`/`weakest` come from
75
+ * `state.topology`; `legacy_missing` topology omits those chips (no synthetic values).
76
+ */
77
+ export declare function deriveDeepInterviewHud(payload: Record<string, unknown>, options?: DeepInterviewHudDeriveOptions): WorkflowHudSummary;
64
78
  export declare function buildRalplanHudSummary(state: RalplanHudState): WorkflowHudSummary;
65
79
  export declare function buildUltragoalHudSummary(state: UltragoalHudState): WorkflowHudSummary;
66
80
  export declare function buildTeamHudSummary(state: TeamHudState): WorkflowHudSummary;
@@ -28,6 +28,7 @@ export interface TaskResultReceipt {
28
28
  contextTokens?: number;
29
29
  contextWindow?: number;
30
30
  modelOverride?: string | string[];
31
+ modelSubstitutionWarning?: SingleResult["modelSubstitutionWarning"];
31
32
  usage?: SingleResult["usage"];
32
33
  cost?: number;
33
34
  branchName?: string;
@@ -280,6 +280,11 @@ export interface AgentDefinition {
280
280
  source: AgentSource;
281
281
  filePath?: string;
282
282
  }
283
+ export interface ModelSubstitutionWarning {
284
+ requested: string;
285
+ effective: string;
286
+ reason: "auth_unavailable" | "assistant_model_mismatch";
287
+ }
283
288
  /** Progress tracking for a single agent */
284
289
  export interface AgentProgress {
285
290
  index: number;
@@ -316,6 +321,7 @@ export interface AgentProgress {
316
321
  cost: number;
317
322
  durationMs: number;
318
323
  modelOverride?: string | string[];
324
+ modelSubstitutionWarning?: ModelSubstitutionWarning;
319
325
  /** Data extracted by registered subprocess tool handlers (keyed by tool name) */
320
326
  extractedToolData?: Record<string, unknown[]>;
321
327
  /**
@@ -374,6 +380,7 @@ export interface SingleResult {
374
380
  /** Model's context window in tokens, when known. */
375
381
  contextWindow?: number;
376
382
  modelOverride?: string | string[];
383
+ modelSubstitutionWarning?: ModelSubstitutionWarning;
377
384
  error?: string;
378
385
  aborted?: boolean;
379
386
  abortReason?: string;
@@ -0,0 +1,16 @@
1
+ export type ThinkingLevelValue = "inherit" | "off" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max";
2
+ /**
3
+ * Metadata used to render thinking selector values in the coding-agent UI.
4
+ *
5
+ * This module is intentionally provider/native-free so schema generation can
6
+ * import settings metadata before native addons have been built in CI.
7
+ */
8
+ export interface ThinkingLevelMetadata {
9
+ value: ThinkingLevelValue;
10
+ label: string;
11
+ description: string;
12
+ }
13
+ /**
14
+ * Returns display metadata for a thinking selector.
15
+ */
16
+ export declare function getThinkingLevelMetadata(level: ThinkingLevelValue): ThinkingLevelMetadata;
@@ -1,14 +1,7 @@
1
1
  import { type ResolvedThinkingLevel, ThinkingLevel } from "@gajae-code/agent-core/thinking";
2
2
  import { type Effort } from "@gajae-code/ai/model-thinking";
3
3
  import type { Model } from "@gajae-code/ai/types";
4
- /**
5
- * Metadata used to render thinking selector values in the coding-agent UI.
6
- */
7
- export interface ThinkingLevelMetadata {
8
- value: ThinkingLevel;
9
- label: string;
10
- description: string;
11
- }
4
+ export { getThinkingLevelMetadata, type ThinkingLevelMetadata } from "./thinking-metadata";
12
5
  /**
13
6
  * Parses a provider-facing effort value.
14
7
  */
@@ -17,10 +10,6 @@ export declare function parseEffort(value: string | null | undefined): Effort |
17
10
  * Parses an agent-local thinking selector.
18
11
  */
19
12
  export declare function parseThinkingLevel(value: string | null | undefined): ThinkingLevel | undefined;
20
- /**
21
- * Returns display metadata for a thinking selector.
22
- */
23
- export declare function getThinkingLevelMetadata(level: ThinkingLevel): ThinkingLevelMetadata;
24
13
  /**
25
14
  * Converts an agent-local selector into the effort sent to providers.
26
15
  */
@@ -29,3 +18,5 @@ export declare function toReasoningEffort(level: ThinkingLevel | undefined): Eff
29
18
  * Resolves a selector against the current model while preserving explicit "off".
30
19
  */
31
20
  export declare function resolveThinkingLevelForModel(model: Model | undefined, level: ThinkingLevel | undefined): ResolvedThinkingLevel | undefined;
21
+ export declare function clampExplicitThinkingLevelForModel(model: Model | undefined, level: ThinkingLevel | undefined): ThinkingLevel | undefined;
22
+ export declare function formatClampedModelSelector(selector: string, model: Model | undefined): string;
@@ -20,7 +20,7 @@ import * as z from "zod/v4";
20
20
  import type { RenderResultOptions } from "../extensibility/custom-tools/types";
21
21
  import { type Theme } from "../modes/theme/theme";
22
22
  import type { ToolSession } from ".";
23
- declare const askSchema: z.ZodObject<{
23
+ export declare const askSchema: z.ZodObject<{
24
24
  questions: z.ZodArray<z.ZodObject<{
25
25
  id: z.ZodString;
26
26
  question: z.ZodString;
@@ -29,6 +29,13 @@ declare const askSchema: z.ZodObject<{
29
29
  }, z.core.$strip>>;
30
30
  multi: z.ZodOptional<z.ZodBoolean>;
31
31
  recommended: z.ZodOptional<z.ZodNumber>;
32
+ deepInterview: z.ZodOptional<z.ZodObject<{
33
+ round_id: z.ZodOptional<z.ZodString>;
34
+ round: z.ZodNumber;
35
+ component: z.ZodString;
36
+ dimension: z.ZodString;
37
+ ambiguity: z.ZodNumber;
38
+ }, z.core.$strip>>;
32
39
  }, z.core.$strip>>;
33
40
  }, z.core.$strip>;
34
41
  export type AskToolInput = z.infer<typeof askSchema>;
@@ -73,6 +80,13 @@ export declare class AskTool implements AgentTool<typeof askSchema, AskToolDetai
73
80
  }, z.core.$strip>>;
74
81
  multi: z.ZodOptional<z.ZodBoolean>;
75
82
  recommended: z.ZodOptional<z.ZodNumber>;
83
+ deepInterview: z.ZodOptional<z.ZodObject<{
84
+ round_id: z.ZodOptional<z.ZodString>;
85
+ round: z.ZodNumber;
86
+ component: z.ZodString;
87
+ dimension: z.ZodString;
88
+ ambiguity: z.ZodNumber;
89
+ }, z.core.$strip>>;
76
90
  }, z.core.$strip>>;
77
91
  }, z.core.$strip>;
78
92
  readonly strict = true;
@@ -193,6 +193,8 @@ export interface ToolSession {
193
193
  getToolChoiceQueue?(): ToolChoiceQueue;
194
194
  /** Build a model-provider-specific ToolChoice that targets the named tool, or undefined if unsupported. */
195
195
  buildToolChoice?(toolName: string): ToolChoice | undefined;
196
+ /** Build a named tool-choice decision, preserving whether exact named forcing survived capability degradation. */
197
+ buildToolChoiceResult?(toolName: string): import("../utils/tool-choice").NamedToolChoiceResult;
196
198
  /** Steer a hidden custom message into the conversation (e.g. a preview reminder). */
197
199
  steer?(message: {
198
200
  customType: string;
@@ -21,16 +21,6 @@ export interface ResolveToolDetails {
21
21
  label?: string;
22
22
  sourceResultDetails?: unknown;
23
23
  }
24
- /**
25
- * Queue a resolve-protocol handler on the tool-choice queue. Forces the next
26
- * LLM call to invoke the hidden `resolve` tool, wraps the caller's apply/reject
27
- * callbacks into an onInvoked closure that matches the resolve schema, and
28
- * steers a preview reminder so the model understands why.
29
- *
30
- * This is the canonical entry point for any tool that wants preview/apply
31
- * semantics. No session-level abstraction is needed: callers pass their
32
- * apply/reject functions directly.
33
- */
34
24
  export declare function queueResolveHandler(session: ToolSession, options: {
35
25
  label: string;
36
26
  sourceToolName: string;
@@ -46,6 +46,12 @@ export interface SubagentSnapshot {
46
46
  progress?: AgentProgress;
47
47
  /** True when a live in-session progress producer exists for this subagent. */
48
48
  liveProgressAvailable?: boolean;
49
+ /** Model the subagent actually runs on (after any auth fallback). */
50
+ effectiveModel?: string;
51
+ /** Model originally requested via role/preset mapping; differs from effective on fallback. */
52
+ requestedModel?: string;
53
+ /** True when the requested model lacked credentials and fell back to the parent model. */
54
+ modelFellBack?: boolean;
49
55
  }
50
56
  export interface SubagentToolDetails {
51
57
  subagents: SubagentSnapshot[];
@@ -1,7 +1,20 @@
1
- import type { Api, Model, ToolChoice } from "@gajae-code/ai";
1
+ import type { Api, Model, ResolveToolChoiceResult, ToolChoice } from "@gajae-code/ai";
2
2
  /**
3
3
  * Build a provider-aware tool choice that targets one specific tool when supported.
4
4
  * Providers that only expose required/any forcing may still honor named choices by
5
5
  * narrowing their request tool list before transport.
6
6
  */
7
+ export interface NamedToolChoiceResult {
8
+ choice: ToolChoice | undefined;
9
+ exactNamed: boolean;
10
+ resolved?: ResolveToolChoiceResult;
11
+ }
12
+ export declare function buildNamedToolChoiceResult(toolName: string, model?: Model<Api>): NamedToolChoiceResult;
13
+ /**
14
+ * Legacy capability-aware wrapper. May return a lossy `"required"` when named
15
+ * forcing degrades (e.g. Google APIs, or compat `toolChoiceSupport: "required"`),
16
+ * which forces *some* tool rather than `toolName` specifically. Queue directives
17
+ * that need exact tool identity (resolve / todo_write / yield) MUST use
18
+ * `buildNamedToolChoiceResult` and gate on `exactNamed` instead.
19
+ */
7
20
  export declare function buildNamedToolChoice(toolName: string, model?: Model<Api>): ToolChoice | undefined;