@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
@@ -18,6 +18,8 @@ import * as fsSync from "node:fs";
18
18
  import * as fs from "node:fs/promises";
19
19
  import * as os from "node:os";
20
20
  import * as path from "node:path";
21
+ import { appendReceiptToConfiguredSpool } from "./receipt-spool";
22
+ import type { ReceiptEnvelope } from "./receipts";
21
23
  import type { EventEnvelope, ReceiptFamily, SessionState } from "./types";
22
24
 
23
25
  interface HarnessRootRegistryEntry {
@@ -30,6 +32,18 @@ interface HarnessRootRegistry {
30
32
  roots: HarnessRootRegistryEntry[];
31
33
  }
32
34
 
35
+ export interface HarnessRootRegistryForGc {
36
+ sessionId: string;
37
+ roots: HarnessRootRegistryEntry[];
38
+ }
39
+
40
+ export interface HarnessRootRegistryListingForGc {
41
+ sessionId: string;
42
+ file: string;
43
+ roots: HarnessRootRegistryEntry[];
44
+ error?: string;
45
+ }
46
+
33
47
  interface ResolveHarnessSessionRootOptions {
34
48
  expectedWorkspace?: string;
35
49
  }
@@ -99,6 +113,64 @@ async function writeHarnessRootRegistry(
99
113
  const file = harnessRootRegistryPath(registry.sessionId, env);
100
114
  await writeJsonAtomicPrivate(file, registry);
101
115
  }
116
+
117
+ function parseHarnessRootRegistryForGc(value: unknown, fallbackSessionId: string): HarnessRootRegistryForGc | null {
118
+ if (!value || typeof value !== "object" || Array.isArray(value)) return null;
119
+ const registry = value as Record<string, unknown>;
120
+ if (typeof registry.sessionId !== "string" || !Array.isArray(registry.roots)) return null;
121
+ const roots: HarnessRootRegistryEntry[] = [];
122
+ for (const entry of registry.roots) {
123
+ if (!entry || typeof entry !== "object" || Array.isArray(entry)) return null;
124
+ const rootEntry = entry as Record<string, unknown>;
125
+ if (typeof rootEntry.root !== "string" || typeof rootEntry.updatedAt !== "string") return null;
126
+ roots.push({ root: rootEntry.root, updatedAt: rootEntry.updatedAt });
127
+ }
128
+ return { sessionId: registry.sessionId || fallbackSessionId, roots };
129
+ }
130
+
131
+ /** @internal */
132
+ export async function listHarnessRootRegistriesForGc(
133
+ env: NodeJS.ProcessEnv = process.env,
134
+ ): Promise<HarnessRootRegistryListingForGc[]> {
135
+ const dir = harnessRootRegistryDir(env);
136
+ let entries: string[];
137
+ try {
138
+ entries = await fs.readdir(dir);
139
+ } catch (error) {
140
+ const code = (error as NodeJS.ErrnoException).code;
141
+ if (code === "ENOENT") return [];
142
+ return [{ sessionId: "", file: dir, roots: [], error: (error as Error).message }];
143
+ }
144
+
145
+ const registries: HarnessRootRegistryListingForGc[] = [];
146
+ for (const entry of entries) {
147
+ if (!entry.endsWith(".json")) continue;
148
+ const file = path.join(dir, entry);
149
+ const fallbackSessionId = entry.slice(0, -".json".length);
150
+ try {
151
+ const raw = await fs.readFile(file, "utf8");
152
+ const parsed = parseHarnessRootRegistryForGc(JSON.parse(raw), fallbackSessionId);
153
+ if (!parsed) {
154
+ registries.push({ sessionId: fallbackSessionId, file, roots: [], error: "malformed_registry" });
155
+ continue;
156
+ }
157
+ registries.push({ sessionId: parsed.sessionId, file, roots: parsed.roots });
158
+ } catch (error) {
159
+ registries.push({ sessionId: fallbackSessionId, file, roots: [], error: (error as Error).message });
160
+ }
161
+ }
162
+ return registries;
163
+ }
164
+
165
+ /** @internal */
166
+ export async function rewriteHarnessRootRegistryForGc(file: string, registry: HarnessRootRegistryForGc): Promise<void> {
167
+ await writeJsonAtomicPrivate(file, registry);
168
+ }
169
+
170
+ /** @internal */
171
+ export async function removeHarnessRootRegistryFileForGc(file: string): Promise<void> {
172
+ await fs.rm(file, { force: true });
173
+ }
102
174
  const SESSION_ID_RE = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
103
175
  export const MAX_UNIX_SOCKET_PATH_BYTES = 100;
104
176
 
@@ -227,6 +299,26 @@ async function readJson<T>(file: string): Promise<T | null> {
227
299
  throw error;
228
300
  }
229
301
  }
302
+ function isReceiptEnvelope(value: unknown): value is ReceiptEnvelope<unknown> {
303
+ if (!value || typeof value !== "object" || Array.isArray(value)) return false;
304
+ const envelope = value as Record<string, unknown>;
305
+ return (
306
+ typeof envelope.receiptId === "string" &&
307
+ typeof envelope.schemaVersion === "number" &&
308
+ typeof envelope.sessionId === "string" &&
309
+ typeof envelope.family === "string" &&
310
+ typeof envelope.valid === "boolean" &&
311
+ typeof envelope.createdAt === "string" &&
312
+ typeof envelope.source === "string" &&
313
+ envelope.subject !== null &&
314
+ typeof envelope.subject === "object" &&
315
+ envelope.evidence !== null &&
316
+ typeof envelope.evidence === "object" &&
317
+ envelope.artifactHashes !== null &&
318
+ typeof envelope.artifactHashes === "object" &&
319
+ typeof envelope.sha256 === "string"
320
+ );
321
+ }
230
322
 
231
323
  export async function readSessionState(root: string, sessionId: string): Promise<SessionState | null> {
232
324
  return readJson<SessionState>(sessionPaths(root, sessionId).state);
@@ -372,6 +464,7 @@ export async function writeReceiptImmutable(
372
464
  path: file,
373
465
  };
374
466
  await fs.appendFile(paths.receiptsIndex, `${JSON.stringify(entry)}\n`, "utf8");
467
+ if (isReceiptEnvelope(value)) await appendReceiptToConfiguredSpool(value);
375
468
  return entry;
376
469
  }
377
470
 
@@ -210,6 +210,10 @@ export interface Observation {
210
210
  rpcLive?: boolean;
211
211
  /** ISO timestamp of the most recent RPC frame the owner observed, if any. */
212
212
  rpcLastFrameAt?: string | null;
213
+ /** True only when owner/rpc/lifecycle gates indicate a prompt can be submitted now. */
214
+ readyForSubmit?: boolean;
215
+ /** Present when readyForSubmit is false; mirrors submit's nextAllowedActions reason. */
216
+ submitUnavailableReason?: string | null;
213
217
  }
214
218
 
215
219
  /** Input to the deterministic recovery classifier. */
@@ -295,12 +295,12 @@ export function summarizeMentalModel(model: MentalModelSummary): string {
295
295
  * snapshot only; the diff is computed locally for display purposes.
296
296
  *
297
297
  * This is intentionally minimal — for "what changed" at a glance, not for a
298
- * full structural diff. Each side is capped at `MAX_LCS_LINES` lines BEFORE
299
- * the O(n*m) LCS table is built so a long curated model can never hang the
300
- * TUI; output is then capped at `maxLines` so the rendered diff stays
301
- * readable. The cap is signalled inline.
298
+ * full structural diff. Each side is capped at `MAX_LCS_LINES` lines before
299
+ * the Hunt-Szymanski LCS pass so a long curated model can never hang the TUI;
300
+ * output is then capped at `maxLines` so the rendered diff stays readable. The
301
+ * cap is signalled inline.
302
302
  */
303
- /** Hard cap on input line count per side before LCS. Keeps the O(n*m) table tractable. */
303
+ /** Hard cap on input line count per side before LCS. Keeps worst-case repeated-line matching bounded. */
304
304
  export const MAX_LCS_LINES = 1_000;
305
305
 
306
306
  export function diffMentalModelContent(previous: string | null, current: string, maxLines = 200): string {
@@ -346,24 +346,25 @@ export function diffMentalModelContent(previous: string | null, current: string,
346
346
  }
347
347
 
348
348
  function longestCommonSubsequence(a: string[], b: string[]): string[] {
349
- const n = a.length;
350
- const m = b.length;
351
- if (n === 0 || m === 0) return [];
352
- const table: number[][] = Array.from({ length: n + 1 }, () => new Array(m + 1).fill(0));
353
- for (let i = 0; i < n; i++) {
354
- for (let j = 0; j < m; j++) {
355
- table[i + 1][j + 1] = a[i] === b[j] ? table[i][j] + 1 : Math.max(table[i + 1][j], table[i][j + 1]);
349
+ return longestCommonSubsequenceDense(a, b);
350
+ }
351
+
352
+ function longestCommonSubsequenceDense(a: string[], b: string[]): string[] {
353
+ const table: number[][] = Array.from({ length: a.length + 1 }, () => new Array(b.length + 1).fill(0));
354
+ for (let i = 0; i < a.length; i++) {
355
+ for (let j = 0; j < b.length; j++) {
356
+ table[i + 1]![j + 1] = a[i] === b[j] ? table[i]![j]! + 1 : Math.max(table[i + 1]![j]!, table[i]![j + 1]!);
356
357
  }
357
358
  }
358
359
  const out: string[] = [];
359
- let i = n;
360
- let j = m;
360
+ let i = a.length;
361
+ let j = b.length;
361
362
  while (i > 0 && j > 0) {
362
363
  if (a[i - 1] === b[j - 1]) {
363
- out.push(a[i - 1]);
364
+ out.push(a[i - 1]!);
364
365
  i--;
365
366
  j--;
366
- } else if (table[i - 1][j] >= table[i][j - 1]) {
367
+ } else if (table[i - 1]![j]! >= table[i]![j - 1]!) {
367
368
  i--;
368
369
  } else {
369
370
  j--;