@gajae-code/coding-agent 0.12.21 → 0.13.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 (222) hide show
  1. package/CHANGELOG.md +67 -2
  2. package/dist/types/cli/args.d.ts +5 -2
  3. package/dist/types/cli/root-flags.d.ts +246 -0
  4. package/dist/types/cli.d.ts +11 -19
  5. package/dist/types/commands/daemon.d.ts +0 -30
  6. package/dist/types/commands/launch.d.ts +11 -19
  7. package/dist/types/commands/quick-lane.d.ts +32 -0
  8. package/dist/types/commands/sdk.d.ts +21 -15
  9. package/dist/types/config/file-lock-gc.d.ts +2 -0
  10. package/dist/types/config/model-equivalence.d.ts +20 -0
  11. package/dist/types/config/model-profile-activation.d.ts +62 -17
  12. package/dist/types/config/model-profiles.d.ts +10 -0
  13. package/dist/types/config/model-registry.d.ts +68 -1
  14. package/dist/types/config/model-resolver.d.ts +15 -4
  15. package/dist/types/config/models-config-schema.d.ts +7 -2
  16. package/dist/types/config/provider-selection-policy.d.ts +62 -0
  17. package/dist/types/config/settings-schema.d.ts +36 -78
  18. package/dist/types/config/settings.d.ts +2 -0
  19. package/dist/types/edit/renderer.d.ts +5 -2
  20. package/dist/types/edit/streaming.d.ts +13 -0
  21. package/dist/types/extensibility/custom-tools/types.d.ts +2 -0
  22. package/dist/types/extensibility/extensions/compact-handler.d.ts +2 -1
  23. package/dist/types/extensibility/extensions/types.d.ts +3 -0
  24. package/dist/types/gjc-runtime/gc-runtime.d.ts +19 -5
  25. package/dist/types/internal-urls/local-protocol.d.ts +1 -0
  26. package/dist/types/modes/components/model-selector.d.ts +0 -2
  27. package/dist/types/modes/components/provider-order-context.d.ts +45 -0
  28. package/dist/types/modes/components/provider-order-editor.d.ts +24 -0
  29. package/dist/types/modes/components/settings-defs.d.ts +5 -1
  30. package/dist/types/modes/components/settings-selector.d.ts +2 -0
  31. package/dist/types/quick-lane/classify.d.ts +40 -0
  32. package/dist/types/runtime/stt-settings-setup.d.ts +18 -0
  33. package/dist/types/sdk/broker/broker.d.ts +56 -2
  34. package/dist/types/sdk/broker/operation-receipt-ledger.d.ts +25 -0
  35. package/dist/types/sdk/broker/session-index.d.ts +83 -2
  36. package/dist/types/sdk/broker/state-version.d.ts +1 -1
  37. package/dist/types/sdk/bus/notification-service.d.ts +6 -0
  38. package/dist/types/sdk/bus/prompt-reconciliation.d.ts +8 -1
  39. package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +4 -1
  40. package/dist/types/sdk/bus/telegram-daemon.d.ts +26 -0
  41. package/dist/types/sdk/cli/rows.d.ts +98 -0
  42. package/dist/types/sdk/cli/session-cli.d.ts +35 -3
  43. package/dist/types/sdk/elevation/allowlist.d.ts +20 -0
  44. package/dist/types/sdk/elevation/audit.d.ts +93 -0
  45. package/dist/types/sdk/elevation/capability.d.ts +3 -0
  46. package/dist/types/sdk/elevation/digest.d.ts +72 -0
  47. package/dist/types/sdk/elevation/dispatch-receipt.d.ts +85 -0
  48. package/dist/types/sdk/elevation/grant-ledger.d.ts +163 -0
  49. package/dist/types/sdk/elevation/owner.d.ts +48 -0
  50. package/dist/types/sdk/guides/cache.d.ts +98 -0
  51. package/dist/types/sdk/guides/catalog.d.ts +156 -0
  52. package/dist/types/sdk/guides/cli.d.ts +39 -0
  53. package/dist/types/sdk/guides/manifest.d.ts +66 -0
  54. package/dist/types/sdk/guides/verify.d.ts +66 -0
  55. package/dist/types/sdk/host/control/dispatch.d.ts +8 -0
  56. package/dist/types/sdk/host/control/index.d.ts +1 -1
  57. package/dist/types/sdk/host/control/operations.d.ts +3 -2
  58. package/dist/types/sdk/host/query/cursor.d.ts +10 -0
  59. package/dist/types/sdk/host/query/handlers.d.ts +21 -0
  60. package/dist/types/sdk/host/session-runtime.d.ts +9 -0
  61. package/dist/types/sdk/mcp/server.d.ts +2 -2
  62. package/dist/types/sdk/prompt-status.d.ts +11 -0
  63. package/dist/types/sdk/session.d.ts +4 -0
  64. package/dist/types/sdk/transport/index.d.ts +1 -0
  65. package/dist/types/sdk/transport/relay.d.ts +1 -0
  66. package/dist/types/sdk/transport/serve-cli.d.ts +20 -1
  67. package/dist/types/session/agent-session.d.ts +32 -18
  68. package/dist/types/session/blob-store.d.ts +13 -7
  69. package/dist/types/session/fallback-chain-controller.d.ts +15 -0
  70. package/dist/types/session/internal/managed-session-storage.d.ts +25 -1
  71. package/dist/types/session/internal/session-memory-sidecar.d.ts +5 -5
  72. package/dist/types/session/session-manager.d.ts +139 -10
  73. package/dist/types/session/session-storage.d.ts +48 -0
  74. package/dist/types/setup/provider-onboarding.d.ts +7 -1
  75. package/dist/types/slash-commands/builtin-registry.d.ts +14 -0
  76. package/dist/types/stt/setup.d.ts +2 -0
  77. package/dist/types/task/executor.d.ts +10 -2
  78. package/dist/types/tools/browser/runtime-diagnostics.d.ts +65 -0
  79. package/dist/types/tools/browser/tab-protocol.d.ts +4 -0
  80. package/dist/types/tools/browser/tab-supervisor.d.ts +2 -0
  81. package/dist/types/tools/browser/tab-worker.d.ts +2 -0
  82. package/dist/types/tools/browser.d.ts +2 -0
  83. package/dist/types/tools/image-gen.d.ts +14 -18
  84. package/dist/types/tools/index.d.ts +2 -0
  85. package/dist/types/tools/resource-gc.d.ts +2 -0
  86. package/dist/types/utils/pasted-image-path.d.ts +6 -0
  87. package/package.json +9 -9
  88. package/scripts/generate-sdk-operation-inventory.ts +8 -0
  89. package/scripts/run-test-manifest.ts +61 -21
  90. package/scripts/verify-gjc-sdk-canonicalization.ts +9 -4
  91. package/src/cli/args.ts +62 -9
  92. package/src/cli/completion-cli.ts +1 -0
  93. package/src/cli/fast-help.ts +1 -0
  94. package/src/cli/root-flags.ts +100 -0
  95. package/src/cli/setup-cli.ts +6 -2
  96. package/src/cli.ts +42 -65
  97. package/src/commands/acp.ts +1 -1
  98. package/src/commands/daemon.ts +2 -31
  99. package/src/commands/gc.ts +1 -1
  100. package/src/commands/launch.ts +8 -129
  101. package/src/commands/quick-lane.ts +51 -0
  102. package/src/commands/sdk.ts +200 -26
  103. package/src/commands/setup.ts +4 -2
  104. package/src/config/file-lock-gc.ts +4 -1
  105. package/src/config/model-equivalence.ts +76 -7
  106. package/src/config/model-profile-activation.ts +1115 -265
  107. package/src/config/model-profiles.ts +134 -2
  108. package/src/config/model-registry.ts +352 -50
  109. package/src/config/model-resolver.ts +289 -38
  110. package/src/config/models-config-schema.ts +11 -4
  111. package/src/config/provider-selection-policy.ts +146 -0
  112. package/src/config/settings-schema.ts +50 -77
  113. package/src/config/settings.ts +40 -0
  114. package/src/coordinator-mcp/server.ts +32 -2
  115. package/src/edit/renderer.ts +175 -223
  116. package/src/edit/streaming.ts +108 -1
  117. package/src/export/html/index.ts +57 -7
  118. package/src/extensibility/custom-tools/types.ts +2 -0
  119. package/src/extensibility/extensions/compact-handler.ts +3 -2
  120. package/src/extensibility/extensions/runner.ts +6 -0
  121. package/src/extensibility/extensions/types.ts +3 -0
  122. package/src/gjc-runtime/gc-runtime.ts +379 -20
  123. package/src/gjc-runtime/launch-worktree.ts +5 -1
  124. package/src/gjc-runtime/team-runtime.ts +59 -2
  125. package/src/gjc-runtime/tmux-owner-isolation.ts +19 -0
  126. package/src/gjc-runtime/ultragoal-receipt-freshness.ts +16 -1
  127. package/src/internal-urls/docs-index.generated.ts +17 -13
  128. package/src/internal-urls/local-protocol.ts +1 -0
  129. package/src/main.ts +40 -3
  130. package/src/memories/index.ts +4 -2
  131. package/src/modes/acp/acp-agent.ts +235 -91
  132. package/src/modes/components/model-selector.ts +206 -42
  133. package/src/modes/components/provider-order-context.ts +197 -0
  134. package/src/modes/components/provider-order-editor.ts +441 -0
  135. package/src/modes/components/settings-defs.ts +21 -1
  136. package/src/modes/components/settings-selector.ts +45 -2
  137. package/src/modes/components/tool-execution.ts +47 -15
  138. package/src/modes/controllers/command-controller.ts +6 -3
  139. package/src/modes/controllers/extension-ui-controller.ts +2 -0
  140. package/src/modes/controllers/input-controller.ts +73 -2
  141. package/src/modes/controllers/selector-controller.ts +260 -153
  142. package/src/modes/prompt-suggestion-controller.ts +1 -1
  143. package/src/modes/runtime-init.ts +1 -0
  144. package/src/modes/utils/ui-helpers.ts +18 -0
  145. package/src/prompts/tools/browser.md +1 -0
  146. package/src/quick-lane/classify.ts +257 -0
  147. package/src/rlm/index.ts +1 -1
  148. package/src/runtime/stt-settings-setup.ts +57 -0
  149. package/src/sdk/acp/adapter.ts +2 -1
  150. package/src/sdk/broker/broker.ts +780 -12
  151. package/src/sdk/broker/lifecycle.ts +70 -29
  152. package/src/sdk/broker/operation-receipt-ledger.ts +144 -0
  153. package/src/sdk/broker/session-index.ts +463 -48
  154. package/src/sdk/broker/state-version.ts +13 -9
  155. package/src/sdk/broker/transport.ts +14 -1
  156. package/src/sdk/bus/index.ts +34 -13
  157. package/src/sdk/bus/kind-aware-reconciliation.ts +21 -2
  158. package/src/sdk/bus/notification-service.ts +47 -1
  159. package/src/sdk/bus/prompt-reconciliation.ts +22 -3
  160. package/src/sdk/bus/telegram-daemon-contract.ts +4 -1
  161. package/src/sdk/bus/telegram-daemon.ts +54 -3
  162. package/src/sdk/cli/rows.ts +247 -0
  163. package/src/sdk/cli/session-cli.ts +930 -79
  164. package/src/sdk/elevation/allowlist.ts +54 -0
  165. package/src/sdk/elevation/audit.ts +208 -0
  166. package/src/sdk/elevation/capability.ts +41 -0
  167. package/src/sdk/elevation/digest.ts +129 -0
  168. package/src/sdk/elevation/dispatch-receipt.ts +184 -0
  169. package/src/sdk/elevation/grant-ledger.ts +1142 -0
  170. package/src/sdk/elevation/owner.ts +109 -0
  171. package/src/sdk/guides/cache.ts +363 -0
  172. package/src/sdk/guides/catalog.ts +554 -0
  173. package/src/sdk/guides/cli.ts +235 -0
  174. package/src/sdk/guides/manifest.ts +152 -0
  175. package/src/sdk/guides/verify.ts +178 -0
  176. package/src/sdk/host/control/dispatch.ts +49 -1
  177. package/src/sdk/host/control/index.ts +1 -0
  178. package/src/sdk/host/control/operations.ts +8 -1
  179. package/src/sdk/host/query/cursor.ts +47 -3
  180. package/src/sdk/host/query/handlers.ts +155 -2
  181. package/src/sdk/host/sdk-surface-parity.test.ts +1 -0
  182. package/src/sdk/host/session-runtime.test.ts +391 -1
  183. package/src/sdk/host/session-runtime.ts +308 -73
  184. package/src/sdk/host/surface-policy.ts +3 -0
  185. package/src/sdk/host/websocket-transport.ts +7 -1
  186. package/src/sdk/mcp/server.ts +88 -15
  187. package/src/sdk/prompt-status.ts +8 -0
  188. package/src/sdk/protocol/operation-inventory.generated.json +62 -0
  189. package/src/sdk/protocol/operation-registry.ts +3 -2
  190. package/src/sdk/session.ts +87 -39
  191. package/src/sdk/transport/index.ts +1 -0
  192. package/src/sdk/transport/relay.ts +3 -0
  193. package/src/sdk/transport/serve-cli.ts +111 -24
  194. package/src/secrets/obfuscator.ts +92 -12
  195. package/src/session/agent-session.ts +322 -93
  196. package/src/session/blob-store.ts +60 -8
  197. package/src/session/fallback-chain-controller.ts +35 -0
  198. package/src/session/internal/managed-session-scope.ts +25 -3
  199. package/src/session/internal/managed-session-storage.ts +574 -73
  200. package/src/session/internal/session-memory-sidecar.ts +19 -29
  201. package/src/session/session-manager.ts +2166 -743
  202. package/src/session/session-storage.ts +715 -48
  203. package/src/setup/provider-onboarding.ts +19 -3
  204. package/src/setup/provider-presets.json +3 -1
  205. package/src/slash-commands/builtin-registry.ts +85 -3
  206. package/src/stt/downloader.ts +2 -3
  207. package/src/stt/setup.ts +29 -4
  208. package/src/task/executor.ts +22 -18
  209. package/src/task/index.ts +24 -1
  210. package/src/tools/archive-reader.ts +11 -2
  211. package/src/tools/browser/runtime-diagnostics.ts +249 -0
  212. package/src/tools/browser/tab-protocol.ts +4 -0
  213. package/src/tools/browser/tab-supervisor.ts +5 -0
  214. package/src/tools/browser/tab-worker.ts +36 -1
  215. package/src/tools/browser.ts +7 -0
  216. package/src/tools/image-gen.ts +110 -166
  217. package/src/tools/index.ts +2 -0
  218. package/src/tools/read.ts +1 -1
  219. package/src/tools/resource-gc.ts +6 -1
  220. package/src/tools/tool-catalog.generated.ts +5 -1
  221. package/src/utils/pasted-image-path.ts +93 -0
  222. package/src/web/search/index.ts +3 -3
@@ -109,6 +109,59 @@ class Base64StreamEncoder {
109
109
  }
110
110
  }
111
111
 
112
+ async function canonicalizeExportPath(target: string, symlinks = new Set<string>()): Promise<string> {
113
+ const resolved = path.resolve(target);
114
+ const tail: string[] = [];
115
+ let current = resolved;
116
+ while (true) {
117
+ try {
118
+ const real = await fs.realpath(current);
119
+ return tail.length === 0 ? real : path.join(real, ...tail.reverse());
120
+ } catch (error) {
121
+ if (!isEnoent(error)) throw error;
122
+ }
123
+ const stat = await fs.lstat(current).catch(error => {
124
+ if (isEnoent(error)) return undefined;
125
+ throw error;
126
+ });
127
+ if (stat?.isSymbolicLink()) {
128
+ if (symlinks.has(current)) throw new Error("HTML export path contains a symlink loop");
129
+ const linkTarget = await fs.readlink(current);
130
+ return canonicalizeExportPath(
131
+ path.resolve(path.dirname(current), linkTarget, ...tail.slice().reverse()),
132
+ new Set([...symlinks, current]),
133
+ );
134
+ }
135
+ const parent = path.dirname(current);
136
+ if (parent === current) return resolved;
137
+ tail.push(path.basename(current));
138
+ current = parent;
139
+ }
140
+ }
141
+
142
+ async function assertExportDoesNotAliasSource(sourcePath: string, outputPath: string): Promise<void> {
143
+ const sourceResolvedPath = await canonicalizeExportPath(sourcePath);
144
+ const outputResolvedPath = await canonicalizeExportPath(outputPath);
145
+ if (sourceResolvedPath === outputResolvedPath)
146
+ throw new Error("HTML export output must not overwrite the source transcript");
147
+
148
+ const sourceIdentity = await fs.stat(sourcePath).catch(error => {
149
+ if (isEnoent(error)) return undefined;
150
+ throw error;
151
+ });
152
+ const outputIdentity = await fs.stat(outputPath).catch(error => {
153
+ if (isEnoent(error)) return undefined;
154
+ throw error;
155
+ });
156
+ if (
157
+ sourceIdentity &&
158
+ outputIdentity &&
159
+ sourceIdentity.dev === outputIdentity.dev &&
160
+ sourceIdentity.ino === outputIdentity.ino
161
+ )
162
+ throw new Error("HTML export output must not overwrite the source transcript");
163
+ }
164
+
112
165
  async function writeSessionHtml(
113
166
  sm: SessionManager,
114
167
  state: AgentState | undefined,
@@ -121,12 +174,7 @@ async function writeSessionHtml(
121
174
  const markerOffset = themedTemplate.indexOf(marker);
122
175
  if (markerOffset < 0) throw new Error("HTML export template is missing the session-data marker");
123
176
  const sourcePath = sm.getSessionFile();
124
- if (sourcePath) {
125
- const sourceIdentity = await fs.realpath(sourcePath).catch(() => path.resolve(sourcePath));
126
- const outputIdentity = await fs.realpath(outputPath).catch(() => path.resolve(outputPath));
127
- if (sourceIdentity === outputIdentity)
128
- throw new Error("HTML export output must not overwrite the source transcript");
129
- }
177
+ if (sourcePath) await assertExportDoesNotAliasSource(sourcePath, outputPath);
130
178
  const sink = Bun.file(outputPath).writer();
131
179
  const encoder = new Base64StreamEncoder();
132
180
  const writeEncoded = (value: string): void => {
@@ -178,6 +226,7 @@ export async function exportSessionToHtml(
178
226
  /** Export session file to HTML (standalone). */
179
227
  export async function exportFromFile(inputPath: string, options?: ExportOptions | string): Promise<string> {
180
228
  const opts: ExportOptions = typeof options === "string" ? { outputPath: options } : options || {};
229
+ const outputPath = opts.outputPath || `${APP_NAME}-session-${path.basename(inputPath, ".jsonl")}.html`;
181
230
 
182
231
  let sm: SessionManager;
183
232
  const artifactRoot = inputPath.endsWith(".jsonl") ? inputPath.slice(0, -6) : inputPath;
@@ -189,6 +238,8 @@ export async function exportFromFile(inputPath: string, options?: ExportOptions
189
238
  )
190
239
  ).some(Boolean);
191
240
  if (!(await Bun.file(inputPath).exists())) throw new Error(`File not found: ${inputPath}`);
241
+ await assertExportDoesNotAliasSource(inputPath, outputPath);
242
+
192
243
  try {
193
244
  sm = await SessionManager.open(
194
245
  inputPath,
@@ -203,7 +254,6 @@ export async function exportFromFile(inputPath: string, options?: ExportOptions
203
254
  }
204
255
 
205
256
  try {
206
- const outputPath = opts.outputPath || `${APP_NAME}-session-${path.basename(inputPath, ".jsonl")}.html`;
207
257
  await writeSessionHtml(sm, undefined, outputPath, opts.themeName);
208
258
  return outputPath;
209
259
  } finally {
@@ -70,6 +70,8 @@ export interface CustomToolContext {
70
70
  sessionManager: ReadonlySessionManager;
71
71
  /** Model registry - use for API key resolution and model retrieval */
72
72
  modelRegistry: ModelRegistry;
73
+ /** Credential-selection identity for provider authentication. */
74
+ credentialSessionId?: string;
73
75
  /** Current model (may be undefined if no model is selected yet) */
74
76
  model: Model | undefined;
75
77
  /** Whether the agent is idle (not streaming) */
@@ -23,7 +23,8 @@ export async function runExtensionCompact(
23
23
  }
24
24
 
25
25
  interface SetModelCapableSession {
26
- modelRegistry: { getApiKey(model: Model): Promise<string | undefined> };
26
+ credentialSessionId?: string;
27
+ modelRegistry: { getApiKey(model: Model, sessionId?: string): Promise<string | undefined> };
27
28
  setModel(model: Model, role?: string, options?: { cause?: string }): Promise<unknown>;
28
29
  /** Persist effective profile roles and clear its marker for a concrete default selection. */
29
30
  materializeActiveDefaultModelProfileAssignment?(model: Model): boolean;
@@ -39,7 +40,7 @@ interface SetModelCapableSession {
39
40
  * Returns false when no API key is available for the requested model.
40
41
  */
41
42
  export async function runExtensionSetModel(session: SetModelCapableSession, model: Model): Promise<boolean> {
42
- const key = await session.modelRegistry.getApiKey(model);
43
+ const key = await session.modelRegistry.getApiKey(model, session.credentialSessionId);
43
44
  if (!key) return false;
44
45
  await session.setModel(model, "default", { cause: "user-selection" });
45
46
  // A durable profile is replaced by materializing its effective assignments
@@ -197,6 +197,7 @@ export class ExtensionRunner {
197
197
  #attemptRecordStore: AttemptRecordStore | undefined;
198
198
 
199
199
  #getModel: () => Model | undefined = () => undefined;
200
+ #getCredentialSessionId: () => string = () => "";
200
201
  #isIdleFn: () => boolean = () => true;
201
202
  #getActivePromptHandleFn: () => string | undefined = () => undefined;
202
203
  #waitForIdleFn: () => Promise<void> = async () => {};
@@ -323,6 +324,7 @@ export class ExtensionRunner {
323
324
 
324
325
  // Context actions (required)
325
326
  this.#getModel = contextActions.getModel;
327
+ this.#getCredentialSessionId = contextActions.getCredentialSessionId ?? (() => "");
326
328
  this.#isIdleFn = contextActions.isIdle;
327
329
  this.#getActivePromptHandleFn = contextActions.getActivePromptHandle ?? (() => undefined);
328
330
  this.#abortFn = contextActions.abort;
@@ -597,6 +599,7 @@ export class ExtensionRunner {
597
599
 
598
600
  createContext(): ExtensionContext {
599
601
  const getModel = this.#getModel;
602
+ const getCredentialSessionId = this.#getCredentialSessionId;
600
603
  return {
601
604
  ui: this.#uiContext,
602
605
  getContextUsage: () => this.#getContextUsageFn(),
@@ -606,6 +609,9 @@ export class ExtensionRunner {
606
609
  sessionManager: createReadonlySessionManager(this.sessionManager),
607
610
  sessionMetadata: this.sessionMetadata,
608
611
  modelRegistry: this.modelRegistry,
612
+ get credentialSessionId() {
613
+ return getCredentialSessionId();
614
+ },
609
615
  get model() {
610
616
  return getModel();
611
617
  },
@@ -360,6 +360,8 @@ export interface ExtensionContext {
360
360
  sessionMetadata?: ExtensionSessionMetadata;
361
361
  /** Model registry for API key resolution */
362
362
  modelRegistry: ModelRegistry;
363
+ /** Credential-selection identity, distinct from logical/provider cache identity. */
364
+ credentialSessionId?: string;
363
365
  /** Current model (may be undefined) */
364
366
  model: Model | undefined;
365
367
  /** Whether the agent is idle (not streaming) */
@@ -1479,6 +1481,7 @@ export interface ExtensionActions {
1479
1481
  /** Actions for ExtensionContext (ctx.* in event handlers). */
1480
1482
  export interface ExtensionContextActions {
1481
1483
  getModel: () => Model | undefined;
1484
+ getCredentialSessionId?: () => string;
1482
1485
  isIdle: () => boolean;
1483
1486
  /** Stable resource ownership identifier for the active prompt run. */
1484
1487
  getActivePromptHandle?: () => string | undefined;