@gajae-code/coding-agent 0.15.5 → 0.16.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 (272) hide show
  1. package/CHANGELOG.md +85 -1
  2. package/dist/types/async/job-manager.d.ts +83 -0
  3. package/dist/types/cli/args.d.ts +2 -0
  4. package/dist/types/cli/auth-gateway-cli.d.ts +17 -0
  5. package/dist/types/cli/model-presets-cli.d.ts +9 -0
  6. package/dist/types/cli/root-flags.d.ts +14 -0
  7. package/dist/types/cli/update-cli.d.ts +15 -0
  8. package/dist/types/cli.d.ts +7 -0
  9. package/dist/types/commands/auth-gateway.d.ts +3 -0
  10. package/dist/types/commands/gc.d.ts +13 -0
  11. package/dist/types/commands/launch.d.ts +10 -0
  12. package/dist/types/commands/model-presets.d.ts +21 -0
  13. package/dist/types/config/autorouting-tier-map.d.ts +120 -0
  14. package/dist/types/config/file-lock.d.ts +54 -2
  15. package/dist/types/config/internal/model-preset-registry-test-state.d.ts +4 -0
  16. package/dist/types/config/internal/model-preset-registry-test-support.d.ts +3 -0
  17. package/dist/types/config/keybindings.d.ts +3 -2
  18. package/dist/types/config/model-preset-registry.d.ts +368 -0
  19. package/dist/types/config/model-profile-activation.d.ts +39 -0
  20. package/dist/types/config/model-profiles.d.ts +5 -3
  21. package/dist/types/config/model-registry.d.ts +17 -5
  22. package/dist/types/config/settings-schema.d.ts +19 -1
  23. package/dist/types/config/settings.d.ts +2 -0
  24. package/dist/types/coordinator-mcp/model-preset.d.ts +7 -5
  25. package/dist/types/coordinator-mcp/projection-scan.d.ts +54 -0
  26. package/dist/types/crash/record-loader.d.ts +15 -0
  27. package/dist/types/extensibility/extensions/types.d.ts +2 -5
  28. package/dist/types/gjc-runtime/empty-delete-gc.d.ts +58 -0
  29. package/dist/types/gjc-runtime/gc-runtime.d.ts +2 -0
  30. package/dist/types/gjc-runtime/launch-worktree-reservation.d.ts +21 -0
  31. package/dist/types/gjc-runtime/managed-owner-supervisor.d.ts +2 -0
  32. package/dist/types/gjc-runtime/session-state-lock.d.ts +35 -6
  33. package/dist/types/gjc-runtime/session-state-sidecar.d.ts +72 -1
  34. package/dist/types/gjc-runtime/tmux-owner-isolation.d.ts +1 -0
  35. package/dist/types/gjc-runtime/tmux-sessions.d.ts +27 -0
  36. package/dist/types/index.d.ts +1 -0
  37. package/dist/types/main.d.ts +3 -1
  38. package/dist/types/master-mode/context.d.ts +21 -0
  39. package/dist/types/master-mode/first-request.d.ts +34 -0
  40. package/dist/types/master-mode/snapshot.d.ts +32 -0
  41. package/dist/types/modes/components/frictionless-onboarding-selector.d.ts +10 -0
  42. package/dist/types/modes/components/jobs-overlay-model.d.ts +4 -2
  43. package/dist/types/modes/components/oauth-selector.d.ts +1 -0
  44. package/dist/types/modes/components/status-line/model-name.d.ts +18 -0
  45. package/dist/types/modes/components/status-line/priority-row.d.ts +34 -0
  46. package/dist/types/modes/components/status-line/segments.d.ts +10 -0
  47. package/dist/types/modes/jobs-observer.d.ts +36 -0
  48. package/dist/types/modes/print-mode.d.ts +17 -0
  49. package/dist/types/modes/ui-language.d.ts +7 -1
  50. package/dist/types/sdk/broker/broker.d.ts +80 -1
  51. package/dist/types/sdk/broker/endpoint-authority.d.ts +24 -0
  52. package/dist/types/sdk/broker/index.d.ts +3 -0
  53. package/dist/types/sdk/broker/lifecycle.d.ts +26 -0
  54. package/dist/types/sdk/broker/master-capability.d.ts +10 -0
  55. package/dist/types/sdk/broker/session-index.d.ts +40 -11
  56. package/dist/types/sdk/broker/session-scope.d.ts +72 -0
  57. package/dist/types/sdk/broker/spawn-authority.d.ts +201 -0
  58. package/dist/types/sdk/broker/spawn-substrate.d.ts +30 -0
  59. package/dist/types/sdk/broker/state-version.d.ts +4 -1
  60. package/dist/types/sdk/broker/worktree-occupancy.d.ts +28 -0
  61. package/dist/types/sdk/bus/chat-daemon-control.d.ts +3 -0
  62. package/dist/types/sdk/bus/index.d.ts +6 -0
  63. package/dist/types/sdk/bus/kind-aware-reconciliation.d.ts +3 -0
  64. package/dist/types/sdk/bus/prompt-reconciliation.d.ts +4 -0
  65. package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +1 -1
  66. package/dist/types/sdk/cli/index.d.ts +1 -0
  67. package/dist/types/sdk/cli/master-cli.d.ts +63 -0
  68. package/dist/types/sdk/cli/rows.d.ts +4 -3
  69. package/dist/types/sdk/cli/session-cli.d.ts +18 -2
  70. package/dist/types/sdk/client/client.d.ts +3 -2
  71. package/dist/types/sdk/client/discovery.d.ts +1 -0
  72. package/dist/types/sdk/host/control/dispatch.d.ts +10 -0
  73. package/dist/types/sdk/host/control/index.d.ts +1 -1
  74. package/dist/types/sdk/host/control/operations.d.ts +2 -0
  75. package/dist/types/sdk/host/control/runtime-gate.d.ts +21 -7
  76. package/dist/types/sdk/host/host.d.ts +10 -0
  77. package/dist/types/sdk/host/model-pin.d.ts +7 -2
  78. package/dist/types/sdk/host/sdk-run-capability.d.ts +1 -0
  79. package/dist/types/sdk/host/session-runtime.d.ts +67 -1
  80. package/dist/types/sdk/lifecycle/broker-client.d.ts +6 -0
  81. package/dist/types/sdk/lifecycle/service.d.ts +15 -3
  82. package/dist/types/sdk/lifecycle-session.d.ts +2 -0
  83. package/dist/types/sdk/prompt-deadline-manager.d.ts +11 -1
  84. package/dist/types/sdk/protocol/adapter-validation.d.ts +2 -0
  85. package/dist/types/sdk/router/session-router.d.ts +11 -0
  86. package/dist/types/sdk/session.d.ts +16 -0
  87. package/dist/types/sdk/startup-capability.d.ts +2 -1
  88. package/dist/types/session/account-inventory.d.ts +1 -0
  89. package/dist/types/session/agent-session.d.ts +24 -7
  90. package/dist/types/session/credential-store-errors.d.ts +1 -0
  91. package/dist/types/session/fold-coordinator.d.ts +201 -0
  92. package/dist/types/session/sdk-run-capability-internal.d.ts +7 -0
  93. package/dist/types/session/sdk-run-capability.d.ts +2 -0
  94. package/dist/types/session/session-manager.d.ts +65 -0
  95. package/dist/types/session/yield-queue.d.ts +5 -4
  96. package/dist/types/setup/frictionless-onboarding.d.ts +1 -0
  97. package/dist/types/telemetry/control.d.ts +11 -0
  98. package/dist/types/telemetry/events.d.ts +20 -0
  99. package/dist/types/telemetry/index.d.ts +3 -0
  100. package/dist/types/telemetry/transport.d.ts +22 -0
  101. package/dist/types/tools/bash-interactive.d.ts +23 -0
  102. package/dist/types/tools/bash.d.ts +4 -0
  103. package/dist/types/tools/gh.d.ts +8 -0
  104. package/dist/types/tools/index.d.ts +10 -5
  105. package/dist/types/web/search/providers/base.d.ts +9 -4
  106. package/dist/types/web/search/providers/xai.d.ts +2 -1
  107. package/dist/types/web/search/types.d.ts +14 -0
  108. package/package.json +10 -7
  109. package/scripts/generate-hotkeys-docs.ts +4 -0
  110. package/scripts/generate-sdk-operation-inventory.ts +9 -3
  111. package/scripts/verify-gjc-sdk-canonicalization.ts +35 -1
  112. package/src/async/job-manager.ts +671 -39
  113. package/src/cli/accounts-cli.ts +9 -5
  114. package/src/cli/args.ts +17 -0
  115. package/src/cli/auth-broker-cli.ts +40 -12
  116. package/src/cli/auth-gateway-cli.ts +273 -97
  117. package/src/cli/config-cli.ts +2 -2
  118. package/src/cli/fast-help.ts +4 -0
  119. package/src/cli/model-presets-cli.ts +100 -0
  120. package/src/cli/root-flags.ts +5 -0
  121. package/src/cli/update-cli.ts +117 -16
  122. package/src/cli.ts +6 -2
  123. package/src/commands/auth-gateway.ts +12 -8
  124. package/src/commands/gc.ts +19 -0
  125. package/src/commands/launch.ts +86 -18
  126. package/src/commands/model-presets.ts +24 -0
  127. package/src/commands/sdk.ts +113 -21
  128. package/src/config/autorouting-tier-map.ts +44 -0
  129. package/src/config/file-lock-gc.ts +9 -4
  130. package/src/config/file-lock.ts +890 -99
  131. package/src/config/internal/model-preset-registry-test-state.ts +28 -0
  132. package/src/config/internal/model-preset-registry-test-support.ts +11 -0
  133. package/src/config/keybindings.ts +6 -2
  134. package/src/config/model-preset-registry.ts +2795 -0
  135. package/src/config/model-profile-activation.ts +115 -28
  136. package/src/config/model-profile-contract.ts +4 -1
  137. package/src/config/model-profiles.ts +56 -14
  138. package/src/config/model-registry.ts +1044 -122
  139. package/src/config/model-resolver.ts +5 -0
  140. package/src/config/settings-schema.ts +19 -1
  141. package/src/config/settings.ts +11 -1
  142. package/src/coordinator-mcp/model-preset.ts +32 -17
  143. package/src/coordinator-mcp/projection-scan.ts +592 -0
  144. package/src/coordinator-mcp/question-state.ts +9 -11
  145. package/src/coordinator-mcp/server.ts +111 -42
  146. package/src/coordinator-mcp/session-reaper.ts +9 -3
  147. package/src/crash/index-store.ts +2 -0
  148. package/src/crash/record-loader.ts +10 -0
  149. package/src/extensibility/extensions/loader.ts +0 -1
  150. package/src/extensibility/extensions/types.ts +2 -3
  151. package/src/extensibility/gjc-plugins/runtime-adapters.ts +1 -0
  152. package/src/gjc-runtime/empty-delete-gc.ts +301 -0
  153. package/src/gjc-runtime/gc-render.ts +29 -0
  154. package/src/gjc-runtime/gc-runtime.ts +174 -11
  155. package/src/gjc-runtime/launch-worktree-reservation.ts +242 -0
  156. package/src/gjc-runtime/managed-owner-supervisor.ts +63 -51
  157. package/src/gjc-runtime/session-state-lock.ts +1321 -147
  158. package/src/gjc-runtime/session-state-sidecar.ts +1004 -25
  159. package/src/gjc-runtime/tmux-owner-isolation-cli.ts +4 -7
  160. package/src/gjc-runtime/tmux-owner-isolation.ts +2 -2
  161. package/src/gjc-runtime/tmux-sessions.ts +252 -13
  162. package/src/hooks/skill-state.ts +6 -0
  163. package/src/index.ts +1 -0
  164. package/src/internal-urls/docs-index.generated.ts +14 -13
  165. package/src/internal-urls/issue-pr-protocol.ts +4 -2
  166. package/src/lsp/config.ts +4 -3
  167. package/src/lsp/path-trust.ts +12 -6
  168. package/src/main.ts +66 -4
  169. package/src/master-mode/context.ts +50 -0
  170. package/src/master-mode/first-request.ts +65 -0
  171. package/src/master-mode/snapshot.ts +205 -0
  172. package/src/modes/acp/acp-agent.ts +616 -161
  173. package/src/modes/components/footer.ts +4 -2
  174. package/src/modes/components/frictionless-onboarding-selector.ts +48 -2
  175. package/src/modes/components/jobs-overlay-model.ts +99 -16
  176. package/src/modes/components/model-selector.ts +158 -18
  177. package/src/modes/components/oauth-selector.ts +6 -1
  178. package/src/modes/components/settings-selector.ts +1 -0
  179. package/src/modes/components/status-line/model-name.ts +53 -0
  180. package/src/modes/components/status-line/priority-row.ts +107 -0
  181. package/src/modes/components/status-line/segments.ts +29 -10
  182. package/src/modes/components/tool-status-header.ts +151 -15
  183. package/src/modes/controllers/extension-ui-controller.ts +1 -1
  184. package/src/modes/controllers/input-controller.ts +51 -6
  185. package/src/modes/controllers/selector-controller.ts +191 -96
  186. package/src/modes/interactive-mode.ts +14 -1
  187. package/src/modes/jobs-observer.ts +149 -16
  188. package/src/modes/print-mode.ts +64 -0
  189. package/src/modes/runtime-init.ts +1 -1
  190. package/src/modes/ui-language.ts +49 -2
  191. package/src/modes/utils/injected-user-submission.ts +15 -1
  192. package/src/prompts/system/master-mode.md +28 -0
  193. package/src/prompts/tools/bash.md +2 -2
  194. package/src/prompts/tools/fold-receipt.md +3 -0
  195. package/src/prompts/tools/job.md +1 -1
  196. package/src/sdk/acp/adapter.ts +17 -2
  197. package/src/sdk/broker/broker.ts +1671 -34
  198. package/src/sdk/broker/endpoint-authority.ts +86 -0
  199. package/src/sdk/broker/ensure.ts +5 -0
  200. package/src/sdk/broker/index.ts +3 -0
  201. package/src/sdk/broker/lifecycle.ts +217 -46
  202. package/src/sdk/broker/master-capability.ts +232 -0
  203. package/src/sdk/broker/session-index.ts +121 -17
  204. package/src/sdk/broker/session-scope.ts +272 -0
  205. package/src/sdk/broker/spawn-authority.ts +1031 -0
  206. package/src/sdk/broker/spawn-substrate.ts +548 -0
  207. package/src/sdk/broker/state-version.ts +26 -14
  208. package/src/sdk/broker/transport.ts +1 -0
  209. package/src/sdk/broker/worktree-occupancy.ts +90 -0
  210. package/src/sdk/bus/chat-daemon-control.ts +5 -2
  211. package/src/sdk/bus/chat-daemon-runtime.ts +46 -5
  212. package/src/sdk/bus/index.ts +51 -4
  213. package/src/sdk/bus/kind-aware-reconciliation.ts +36 -6
  214. package/src/sdk/bus/prompt-reconciliation.ts +28 -4
  215. package/src/sdk/bus/slack-conversation.ts +5 -1
  216. package/src/sdk/bus/telegram-daemon-contract.ts +1 -1
  217. package/src/sdk/cli/index.ts +1 -0
  218. package/src/sdk/cli/master-cli.ts +259 -0
  219. package/src/sdk/cli/rows.ts +11 -8
  220. package/src/sdk/cli/session-cli.ts +276 -6
  221. package/src/sdk/client/client.ts +14 -8
  222. package/src/sdk/client/discovery.ts +3 -1
  223. package/src/sdk/host/control/dispatch.ts +101 -37
  224. package/src/sdk/host/control/index.ts +2 -0
  225. package/src/sdk/host/control/operations.ts +2 -0
  226. package/src/sdk/host/control/runtime-gate.ts +203 -11
  227. package/src/sdk/host/host.ts +27 -2
  228. package/src/sdk/host/model-pin.ts +185 -25
  229. package/src/sdk/host/sdk-run-capability.ts +1 -0
  230. package/src/sdk/host/session-runtime.test.ts +581 -43
  231. package/src/sdk/host/session-runtime.ts +655 -101
  232. package/src/sdk/lifecycle/broker-client.ts +28 -0
  233. package/src/sdk/lifecycle/service.ts +279 -20
  234. package/src/sdk/lifecycle-session.ts +10 -2
  235. package/src/sdk/prompt-deadline-manager.ts +16 -1
  236. package/src/sdk/protocol/adapter-validation.ts +27 -0
  237. package/src/sdk/protocol/operation-inventory.generated.json +53 -2
  238. package/src/sdk/protocol/operation-registry.ts +17 -4
  239. package/src/sdk/router/session-router.ts +294 -154
  240. package/src/sdk/session.ts +440 -167
  241. package/src/sdk/startup-capability.ts +1 -0
  242. package/src/session/account-inventory.ts +27 -11
  243. package/src/session/agent-session.ts +1292 -180
  244. package/src/session/blob-store.ts +15 -5
  245. package/src/session/credential-store-errors.ts +2 -0
  246. package/src/session/fold-coordinator.ts +433 -0
  247. package/src/session/internal/managed-session-storage.ts +153 -78
  248. package/src/session/sdk-run-capability-internal.ts +15 -0
  249. package/src/session/sdk-run-capability.ts +2 -0
  250. package/src/session/session-manager.ts +342 -28
  251. package/src/session/yield-queue.ts +24 -10
  252. package/src/setup/frictionless-onboarding.ts +2 -0
  253. package/src/setup/provider-presets.json +1 -1
  254. package/src/slash-commands/helpers/credential-switch.ts +6 -1
  255. package/src/task/executor.ts +19 -3
  256. package/src/telemetry/control.ts +26 -0
  257. package/src/telemetry/events.ts +1268 -0
  258. package/src/telemetry/index.ts +3 -0
  259. package/src/telemetry/transport.ts +87 -0
  260. package/src/tools/bash-interactive.ts +182 -85
  261. package/src/tools/bash.ts +1028 -109
  262. package/src/tools/gh.ts +104 -48
  263. package/src/tools/github-cache.ts +2 -2
  264. package/src/tools/index.ts +11 -5
  265. package/src/tools/tool-catalog.generated.ts +1 -1
  266. package/src/web/search/provider.ts +120 -11
  267. package/src/web/search/providers/anthropic.ts +89 -17
  268. package/src/web/search/providers/base.ts +9 -4
  269. package/src/web/search/providers/gemini.ts +87 -15
  270. package/src/web/search/providers/openai-compatible.ts +23 -8
  271. package/src/web/search/providers/xai.ts +98 -12
  272. package/src/web/search/types.ts +16 -0
@@ -1175,7 +1175,63 @@ export declare class SessionManager {
1175
1175
  runWithCwdReadLease<T>(fn: () => Promise<T>): Promise<T>;
1176
1176
  /** Wait for any in-flight exclusive cwd transition to settle. */
1177
1177
  joinCwdTransition(): Promise<void>;
1178
+ closeCwdMoveAdmission(): Promise<void>;
1178
1179
  getCwdGeneration(): number;
1180
+ /**
1181
+ * Register a listener invoked after every committed `moveTo`. Returns an idempotent
1182
+ * unregister handle. Every move surface funnels through `moveTo`, so a single
1183
+ * registration covers `move_session`, `/move`, and SDK/ACP `session.cwd.move`.
1184
+ */
1185
+ registerAfterMoveListener(listener: (move: {
1186
+ previousCwd: string;
1187
+ newCwd: string;
1188
+ previousSessionFile: string | undefined;
1189
+ }) => void | Promise<void>): () => void;
1190
+ registerBeforeMoveListener(listener: (move: {
1191
+ previousCwd: string;
1192
+ newCwd: string;
1193
+ previousSessionFile: string | undefined;
1194
+ newSessionFile: string | undefined;
1195
+ previousCwdIdentity: {
1196
+ dev: bigint;
1197
+ ino: bigint;
1198
+ };
1199
+ newCwdIdentity: {
1200
+ dev: bigint;
1201
+ ino: bigint;
1202
+ };
1203
+ preserveRecoveryJournal?: boolean;
1204
+ }) => void | Promise<void>): () => void;
1205
+ registerMovePublicationListener(listener: (move: {
1206
+ previousCwd: string;
1207
+ newCwd: string;
1208
+ previousSessionFile: string | undefined;
1209
+ newSessionFile: string | undefined;
1210
+ previousCwdIdentity: {
1211
+ dev: bigint;
1212
+ ino: bigint;
1213
+ };
1214
+ newCwdIdentity: {
1215
+ dev: bigint;
1216
+ ino: bigint;
1217
+ };
1218
+ preserveRecoveryJournal?: boolean;
1219
+ }) => void | Promise<void>): () => void;
1220
+ registerMoveAbortListener(listener: (move: {
1221
+ previousCwd: string;
1222
+ newCwd: string;
1223
+ previousSessionFile: string | undefined;
1224
+ newSessionFile: string | undefined;
1225
+ previousCwdIdentity: {
1226
+ dev: bigint;
1227
+ ino: bigint;
1228
+ };
1229
+ newCwdIdentity: {
1230
+ dev: bigint;
1231
+ ino: bigint;
1232
+ };
1233
+ preserveRecoveryJournal?: boolean;
1234
+ }) => void | Promise<void>): () => void;
1179
1235
  static openNoFollowDirectory(dir: string): Promise<fs.promises.FileHandle>;
1180
1236
  /**
1181
1237
  * Claim process-cwd authority for `manager` when it is unowned or the prior
@@ -1215,6 +1271,15 @@ export declare class SessionManager {
1215
1271
  bigint: true;
1216
1272
  }) => Promise<fs.BigIntStats>;
1217
1273
  };
1274
+ expectedSourceIdentity?: {
1275
+ dev: bigint;
1276
+ ino: bigint;
1277
+ };
1278
+ sourceHandle?: {
1279
+ stat: (opts: {
1280
+ bigint: true;
1281
+ }) => Promise<fs.BigIntStats>;
1282
+ };
1218
1283
  }): Promise<void>;
1219
1284
  isPersisted(): boolean;
1220
1285
  stageDefaultModelSelection(model: string, thinkingLevel: string | undefined, options?: {
@@ -15,8 +15,9 @@ export interface YieldDispatcher<P> {
15
15
  export interface YieldQueueOptions {
16
16
  isStreaming: () => boolean;
17
17
  injectStreaming(msg: AgentMessage): void;
18
- injectIdle(messages: AgentMessage[]): Promise<void>;
19
- scheduleIdleFlush(run: () => Promise<void>): void;
18
+ injectIdle(messages: AgentMessage[], signal?: AbortSignal): Promise<void>;
19
+ scheduleIdleFlush(run: (signal?: AbortSignal) => Promise<void>, onSkip: () => void): void;
20
+ getIdleFlushSignal?(): AbortSignal | undefined;
20
21
  }
21
22
  type YieldFlushMode = "streaming" | "idle";
22
23
  export declare class YieldQueue {
@@ -25,8 +26,8 @@ export declare class YieldQueue {
25
26
  register<P>(kind: string, dispatcher: YieldDispatcher<P>): () => void;
26
27
  enqueue<P>(kind: string, entry: P): void;
27
28
  has(kind?: string): boolean;
28
- flush(mode: YieldFlushMode): Promise<void>;
29
- clear(): void;
29
+ flush(mode: YieldFlushMode, signal?: AbortSignal): Promise<void>;
30
+ clear(onDrop?: (kind: string, entries: readonly unknown[]) => void): void;
30
31
  /** Drop only the queued entries of a single kind, leaving other kinds intact. */
31
32
  clearKind(kind: string): void;
32
33
  /**
@@ -68,6 +68,7 @@ export declare function hasCorroboratedRecentEvidence(evidence: readonly Onboard
68
68
  export declare function shouldOfferOnboarding(state: FrictionlessOnboardingState): boolean;
69
69
  export interface AutomaticOnboardingInput {
70
70
  normalInteractive: boolean;
71
+ automation?: boolean;
71
72
  initialMessage?: string;
72
73
  initialMessages: readonly string[];
73
74
  initialImages?: readonly unknown[];
@@ -0,0 +1,11 @@
1
+ /** Process-wide emergency stop; it cannot be enabled by project dotenv files. */
2
+ export declare const TELEMETRY_KILL_SWITCH_ENV: "GJC_DISABLE_TELEMETRY";
3
+ export interface TelemetryStatus {
4
+ enabled: boolean;
5
+ disabledByKillSwitch: boolean;
6
+ reason: "enabled" | "setting_disabled" | "kill_switch";
7
+ }
8
+ export interface TelemetrySettingsReader {
9
+ get(path: "telemetry.enabled"): boolean;
10
+ }
11
+ export declare function getTelemetryStatus(settings: TelemetrySettingsReader): TelemetryStatus;
@@ -0,0 +1,20 @@
1
+ export declare const TELEMETRY_SCHEMA_VERSION: 1;
2
+ export declare const TELEMETRY_INSTALL_ID_FILE: "telemetry-install-id";
3
+ export declare const TELEMETRY_EVENT_NAMES: readonly ["update_check_started", "update_check_completed", "update_install_started", "update_install_completed", "update_install_failed"];
4
+ export type TelemetryEventName = (typeof TELEMETRY_EVENT_NAMES)[number];
5
+ export interface TelemetryEvent {
6
+ schemaVersion: typeof TELEMETRY_SCHEMA_VERSION;
7
+ event: TelemetryEventName;
8
+ installId: string;
9
+ occurredAt: string;
10
+ channel?: "stable" | "nightly";
11
+ result?: "available" | "up_to_date" | "installed" | "failed" | "skipped";
12
+ installMethod?: "bun" | "npm" | "binary" | "migrate";
13
+ }
14
+ /**
15
+ * Serialize only the versioned telemetry allowlist. Unknown fields are never
16
+ * emitted; forbidden fields anywhere in the input fail closed.
17
+ */
18
+ export declare function serializeTelemetryEvent(input: unknown): string;
19
+ /** Load or create a random UUIDv4 that is not derived from machine data. */
20
+ export declare function getTelemetryInstallId(filePath?: string): Promise<string>;
@@ -0,0 +1,3 @@
1
+ export * from "./control";
2
+ export * from "./events";
3
+ export * from "./transport";
@@ -0,0 +1,22 @@
1
+ import { getTelemetryStatus } from "./control";
2
+ import { type TelemetryEvent, type TelemetryEventName } from "./events";
3
+ export declare const TELEMETRY_ENDPOINT: "https://telemetry.gajae.dev/v1/events";
4
+ export declare const TELEMETRY_MAX_IN_FLIGHT: 2;
5
+ export declare const TELEMETRY_TIMEOUT_MS: 1500;
6
+ export declare const TELEMETRY_FLUSH_TIMEOUT_MS: 2000;
7
+ interface TelemetryTransportDependencies {
8
+ fetchImpl?: (input: string | URL, init?: RequestInit) => Promise<Response>;
9
+ endpoint?: string;
10
+ }
11
+ export type TelemetryDetails = Pick<TelemetryEvent, "channel" | "result" | "installMethod">;
12
+ /**
13
+ * Best-effort transport. The caller only schedules work; disabled telemetry,
14
+ * queue saturation, network errors, and non-2xx responses are all ignored.
15
+ */
16
+ export declare function sendTelemetryEvent(settings: Parameters<typeof getTelemetryStatus>[0], event: TelemetryEvent, deps?: TelemetryTransportDependencies): Promise<void>;
17
+ export declare function resetTelemetryTransportForTest(): Promise<void>;
18
+ /** Schedule an event without making telemetry part of the caller's lifecycle. */
19
+ export declare function recordTelemetryEvent(event: TelemetryEventName, details: TelemetryDetails): Promise<void>;
20
+ /** Wait briefly for accepted events so explicit process exits do not drop them. */
21
+ export declare function flushTelemetryEvents(timeoutMs?: 2000): Promise<void>;
22
+ export {};
@@ -6,6 +6,24 @@ export interface BashInteractiveResult extends OutputSummary {
6
6
  cancelled: boolean;
7
7
  timedOut: boolean;
8
8
  }
9
+ /** Live controls handed to the caller once the PTY run owns its session. */
10
+ export interface InteractivePtyControls {
11
+ /**
12
+ * Detach the overlay and settle the foreground call with `foldResult`, leaving
13
+ * the process running and still writing into the sink. Idempotent.
14
+ */
15
+ detachObserver: (foldResult: BashInteractiveResult) => "resolved" | "already-settled";
16
+ /**
17
+ * Resolves with the run's real summary when the process actually ends,
18
+ * regardless of whether the foreground was folded. A folded run is delivered
19
+ * from this, so its result can never be silently dropped.
20
+ */
21
+ terminalCompletion: Promise<BashInteractiveResult>;
22
+ /** Kill the owned process during owner teardown; the observer never calls this. */
23
+ kill: () => void;
24
+ /** Stop forwarding the foreground abort signal after ownership transfers on fold. */
25
+ detachForegroundCancellation: () => void;
26
+ }
9
27
  export declare function runInteractiveBashPty(ui: NonNullable<AgentToolContext["ui"]>, options: {
10
28
  command: string;
11
29
  cwd: string;
@@ -18,4 +36,9 @@ export declare function runInteractiveBashPty(ui: NonNullable<AgentToolContext["
18
36
  spillThreshold?: number;
19
37
  headBytes?: number;
20
38
  settings?: Settings;
39
+ /** Receives live controls once the session is running; used to register a fold. */
40
+ onControls?: (controls: InteractivePtyControls) => void;
41
+ onFoldKey?: () => boolean;
42
+ onDismiss?: () => void;
43
+ onOutput?: (chunk: string) => void;
21
44
  }): Promise<BashInteractiveResult>;
@@ -4,6 +4,7 @@ import * as z from "zod/v4";
4
4
  import { type BashArtifactSaveResult } from "../exec/bash-executor";
5
5
  import type { RenderResultOptions } from "../extensibility/custom-tools/types";
6
6
  import { type Theme } from "../modes/theme/theme";
7
+ import { type SdkSpawnArgs } from "../sdk/cli/master-cli";
7
8
  import type { ToolSession } from ".";
8
9
  import { type OutputMeta } from "./output-meta";
9
10
  export declare const BASH_DEFAULT_PREVIEW_LINES = 10;
@@ -48,6 +49,9 @@ export interface BashToolDetails {
48
49
  export declare function summarizeBashToolActivity(kind: "args" | "result", value: unknown): string | undefined;
49
50
  export interface BashToolOptions {
50
51
  }
52
+ export declare function isStrictDirectSdkSpawnCommand(command: string): boolean;
53
+ export declare function parseDirectSdkSpawnArgs(command: string): SdkSpawnArgs;
54
+ export declare function masterCommandEnvOverrides(env: Record<string, string> | undefined, directMasterSpawn: boolean): Record<string, string>;
51
55
  export declare class BashTool implements AgentTool<BashToolSchema, BashToolDetails> {
52
56
  #private;
53
57
  private readonly session;
@@ -322,6 +322,14 @@ export interface PrDiffFile {
322
322
  changeType: "modified" | "added" | "deleted" | "renamed" | "binary";
323
323
  /** Pre-image path for renames/deletes; same as `path` otherwise. */
324
324
  oldPath?: string;
325
+ /**
326
+ * Set when `path` kept its C-style escaped source form because the quoted
327
+ * token held invalid UTF-8 or a malformed escape; distinguishes it from a
328
+ * valid path whose decoded text looks identical.
329
+ */
330
+ pathEscaped?: boolean;
331
+ /** Same as {@link PrDiffFile.pathEscaped}, for `oldPath`. */
332
+ oldPathEscaped?: boolean;
325
333
  /** Byte offset of the section's `diff --git` line in the unified diff. */
326
334
  startOffset: number;
327
335
  /** Byte offset of the next section (or end-of-text). */
@@ -12,6 +12,7 @@ import type { AgentRegistry } from "../registry/agent-registry";
12
12
  import type { ForkContextSeed, ForkContextSeedOptions, PurgeQueuedCustomMessagesResult } from "../session/agent-session";
13
13
  import type { ArtifactManager } from "../session/artifacts";
14
14
  import type { ClientBridge } from "../session/client-bridge";
15
+ import type { FoldAdapter } from "../session/fold-coordinator";
15
16
  import type { CustomMessage } from "../session/messages";
16
17
  import type { ToolChoiceQueue } from "../session/tool-choice-queue";
17
18
  import type { SkillActiveEntry } from "../skill-state/active-state";
@@ -184,12 +185,12 @@ export interface ToolSession {
184
185
  assertEvalExecutionAllowed?: () => void;
185
186
  /** Track tool-owned eval work so session disposal can await/abort it like direct session eval runs. */
186
187
  trackEvalExecution?<T>(execution: Promise<T>, abortController: AbortController): Promise<T>;
187
- /** Register a safe request handler that asks a managed foreground bash call to fold into a background job. */
188
- registerForegroundBashBackgroundRequestHandler?: (handler: () => void) => () => void;
189
- /** Whether a managed foreground bash call is currently foldable into a background job. */
188
+ /** Register a foldable foreground wait so the fold chord can move it into a background job. */
189
+ registerForegroundFoldParticipant?: (adapter: FoldAdapter) => () => void;
190
+ /** Whether a foreground wait is currently foldable into a background job. */
190
191
  hasForegroundBashBackgroundRequestHandler?: () => boolean;
191
- /** Request that the active managed foreground bash call fold into a background job, if supported. */
192
- requestForegroundBashBackground?: () => boolean;
192
+ /** Request that the active foreground wait fold into a background job, if supported. */
193
+ requestForegroundBashBackground?: () => Promise<boolean>;
193
194
  /** Get the session-owned or inherited async job manager. */
194
195
  getAsyncJobManager?: () => AsyncJobManager | undefined;
195
196
  /** Resolves when the session queues user steering (or `signal` aborts) without consuming it; wait-style tools use this to end their observation early. */
@@ -218,6 +219,10 @@ export interface ToolSession {
218
219
  bashAllowedPrefixes?: string[];
219
220
  /** Restriction policy for sessions that deliberately expose a narrow bash surface. */
220
221
  bashRestrictionProfile?: BashRestrictionProfile;
222
+ /** Process-local master capability injected into direct Bash children only. */
223
+ getMasterBashCapability?: () => string | undefined;
224
+ /** Stable master lineage identity used across session switches and branches. */
225
+ getMasterOwnerSessionId?: () => string | undefined;
221
226
  /** Optional per-session allowlist for tools exposed through search_tool_bm25. */
222
227
  discoverableToolAllowedNames?: readonly string[];
223
228
  /** Throw instead of warn when toolNames contains an unknown name. */
@@ -17,7 +17,10 @@ export declare const SEARXNG_BEARER_CREDENTIAL_PREFIX = "gjc-searxng-bearer:";
17
17
  /**
18
18
  * Shared web search parameters passed to providers.
19
19
  *
20
- * `authStorage` is the **only** credential source providers may consult.
20
+ * `authStorage` is the credential source for canonical providers. Native
21
+ * active-model search may instead use `activeModelContext.resolveCredentials`,
22
+ * which is supplied by ModelRegistry so rotating config credentials and
23
+ * generated headers are refreshed before the request.
21
24
  * Opening a sibling SQLite handle or calling provider-direct refresh helpers
22
25
  * (e.g. `refreshOpenAIOpenAI code backendToken`, `refreshGoogleCloudToken`) is prohibited:
23
26
  * it races the broker's per-credential refresh and POSTs the broker sentinel
@@ -72,8 +75,8 @@ export interface SearchParams {
72
75
  codeExecution?: Record<string, unknown>;
73
76
  urlContext?: Record<string, unknown>;
74
77
  /**
75
- * The single source of truth for credentials. Providers MUST consult this
76
- * handle exclusively (`getApiKey` for bearer-style auth, `getOAuthAccess`
78
+ * The canonical source of truth for credentials. Providers MUST consult this
79
+ * handle (`getApiKey` for bearer-style auth, `getOAuthAccess`
77
80
  * when identity metadata is required). Do not open `AgentStorage` or any
78
81
  * `AuthCredentialStore` directly — that bypasses the broker pipeline and
79
82
  * the per-credential single-flight refresh.
@@ -102,7 +105,9 @@ export declare abstract class SearchProvider {
102
105
  */
103
106
  abstract isAvailable(authStorage: AuthStorage, settings?: SearchProviderSettings): Promise<boolean> | boolean;
104
107
  /**
105
- * Execute a search. Credentials MUST be resolved through `params.authStorage`.
108
+ * Execute a search. Canonical credentials MUST be resolved through
109
+ * `params.authStorage`; active-model credentials MUST use the injected
110
+ * resolver when one is present.
106
111
  */
107
112
  abstract search(params: SearchParams): Promise<SearchResponse>;
108
113
  }
@@ -5,7 +5,7 @@
5
5
  * Endpoint: POST https://api.x.ai/v1/responses
6
6
  */
7
7
  import type { AuthStorage } from "@gajae-code/ai/core";
8
- import type { SearchCitation, SearchResponse } from "../../../web/search/types";
8
+ import type { ActiveSearchModelContext, SearchCitation, SearchResponse } from "../../../web/search/types";
9
9
  import type { SearchParams } from "./base";
10
10
  import { SearchProvider } from "./base";
11
11
  declare const XAI_SEARCH_MODES: readonly ["web", "x", "web_and_x"];
@@ -31,6 +31,7 @@ export interface XaiSearchParams {
31
31
  signal?: AbortSignal;
32
32
  authStorage: AuthStorage;
33
33
  sessionId?: string;
34
+ activeModelContext?: ActiveSearchModelContext;
34
35
  }
35
36
  /** Test seam: the xAI search base URL as resolved from trusted env. */
36
37
  export declare function resolveXaiSearchBaseUrlForTest(): string;
@@ -6,6 +6,16 @@
6
6
  /** Supported web search providers */
7
7
  export type SearchProviderId = "duckduckgo" | "insane" | "exa" | "brave" | "jina" | "kimi" | "zai" | "anthropic" | "perplexity" | "gemini" | "codex" | "xai" | "tavily" | "parallel" | "kagi" | "synthetic" | "searxng" | "openai-compatible";
8
8
  export type WebSearchMode = "on" | "off" | "auto";
9
+ /** Credentials and request headers resolved for the active model. */
10
+ export interface ActiveSearchModelCredentials {
11
+ apiKey?: string;
12
+ headers?: Record<string, string>;
13
+ }
14
+ /** Refresh-aware resolver supplied by the model registry for native search. */
15
+ export type ActiveSearchModelCredentialResolver = (options: {
16
+ sessionId?: string;
17
+ signal?: AbortSignal;
18
+ }) => Promise<ActiveSearchModelCredentials>;
9
19
  export interface ActiveSearchModelContext {
10
20
  provider: string;
11
21
  modelId: string;
@@ -13,6 +23,10 @@ export interface ActiveSearchModelContext {
13
23
  api: string;
14
24
  baseUrl?: string;
15
25
  headers?: Record<string, string>;
26
+ /** Resolve the active model key and current headers before each native search. */
27
+ resolveCredentials?: ActiveSearchModelCredentialResolver;
28
+ /** True when registry-owned auth or transport overrides this active model. */
29
+ ownerAuthOverride?: boolean;
16
30
  webSearch?: WebSearchMode;
17
31
  }
18
32
  export declare const CONFIGURABLE_SEARCH_PROVIDER_IDS: readonly ["duckduckgo", "insane", "exa", "brave", "jina", "kimi", "zai", "anthropic", "perplexity", "gemini", "codex", "xai", "tavily", "parallel", "kagi", "synthetic", "searxng"];
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@gajae-code/coding-agent",
4
- "version": "0.15.5",
4
+ "version": "0.16.0",
5
5
  "description": "Gajae Code CLI with read, bash, edit, write tools and session management",
6
6
  "homepage": "https://gajae-code.com",
7
7
  "author": "Yeachan-Heo and Gajae Code Contributors",
@@ -56,12 +56,12 @@
56
56
  "@agentclientprotocol/sdk": "1.3.0",
57
57
  "@babel/parser": "^7.29.3",
58
58
  "@mozilla/readability": "^0.6.0",
59
- "@gajae-code/stats": "0.15.5",
60
- "@gajae-code/agent-core": "0.15.5",
61
- "@gajae-code/ai": "0.15.5",
62
- "@gajae-code/natives": "0.15.5",
63
- "@gajae-code/tui": "0.15.5",
64
- "@gajae-code/utils": "0.15.5",
59
+ "@gajae-code/stats": "0.16.0",
60
+ "@gajae-code/agent-core": "0.16.0",
61
+ "@gajae-code/ai": "0.16.0",
62
+ "@gajae-code/natives": "0.16.0",
63
+ "@gajae-code/tui": "0.16.0",
64
+ "@gajae-code/utils": "0.16.0",
65
65
  "@puppeteer/browsers": "^2.13.0",
66
66
  "@types/turndown": "5.0.6",
67
67
  "@xterm/headless": "^6.0.0",
@@ -128,6 +128,8 @@
128
128
  "./slash-commands/helpers/mcp": null,
129
129
  "./session/session-manager-internal": null,
130
130
  "./session/session-manager-internal.js": null,
131
+ "./session/sdk-run-capability": null,
132
+ "./session/sdk-run-capability.js": null,
131
133
  "./sdk": {
132
134
  "types": "./dist/types/sdk/index.d.ts",
133
135
  "import": "./src/sdk/index.ts"
@@ -275,6 +277,7 @@
275
277
  "types": "./dist/types/commit/utils/*.d.ts",
276
278
  "import": "./src/commit/utils/*.ts"
277
279
  },
280
+ "./config/internal/*": null,
278
281
  "./config/*": {
279
282
  "types": "./dist/types/config/*.d.ts",
280
283
  "import": "./src/config/*.ts"
@@ -2,6 +2,7 @@ import { readFileSync, writeFileSync } from "node:fs";
2
2
  import * as path from "node:path";
3
3
  import {
4
4
  defaultClipboardPasteImageKeysForPlatform,
5
+ defaultForegroundFoldKeysForPlatform,
5
6
  defaultMessageQueueKeysForPlatform,
6
7
  KEYBINDINGS,
7
8
  } from "../src/config/keybindings";
@@ -27,6 +28,9 @@ function defaultKeys(
27
28
  case "app.clipboard.pasteImage":
28
29
  keys = defaultClipboardPasteImageKeysForPlatform(platform);
29
30
  break;
31
+ case "app.tool.backgroundFold":
32
+ keys = defaultForegroundFoldKeysForPlatform(platform);
33
+ break;
30
34
  default:
31
35
  keys = value.defaultKeys;
32
36
  }
@@ -107,6 +107,12 @@ const LOCKED_EXCLUSIONS: Readonly<Record<string, string>> = {
107
107
  "agent_session:activeMidRunBarrierCountForTests": "read-only test seam, not a user-facing SDK control seam",
108
108
  "agent_session:activeMidRunMaintenanceCountForTests": "read-only test seam, not a user-facing SDK control seam",
109
109
  "agent_session:getPendingNextTurnMessagesForTests": "read-only test seam, not a user-facing SDK control seam",
110
+ "agent_session:queueCoordinatorRuntimeStatePersistForTests":
111
+ "test-only coordinator persistence ordering seam, not a user-facing SDK control seam",
112
+ "agent_session:parkAgentEndForCoordinatorPersistForTests":
113
+ "test-only parked terminal persistence seam, not a user-facing SDK control seam",
114
+ "agent_session:flushParkedAgentEndForCoordinatorPersistForTests":
115
+ "test-only parked terminal flush seam, not a user-facing SDK control seam",
110
116
  "agent_session:setCancelAndSubmitAbortOutcomeProviderForTests":
111
117
  "test-only cancellation seam, not a user-facing SDK control seam",
112
118
  "agent_session:getAgentId": "internal accessor/plumbing, not a user-facing control seam",
@@ -127,11 +133,11 @@ const LOCKED_EXCLUSIONS: Readonly<Record<string, string>> = {
127
133
  "internal ACP lifecycle quiescence plumbing, not a user-facing control seam",
128
134
  "agent_session:getToolByName": "internal accessor/plumbing, not a user-facing control seam",
129
135
  "agent_session:getToolForExecution": "internal accessor/plumbing, not a user-facing control seam",
130
- "agent_session:registerForegroundBashBackgroundRequestHandler":
131
- "internal accessor/plumbing, not a user-facing control seam",
136
+ "agent_session:registerForegroundFoldParticipant": "internal accessor/plumbing, not a user-facing control seam",
132
137
  "agent_session:hasForegroundBashBackgroundRequestHandler":
133
138
  "internal accessor/plumbing, not a user-facing control seam",
134
- "agent_session:requestForegroundBashBackground": "internal accessor/plumbing, not a user-facing control seam",
139
+ "agent_session:requestForegroundBashBackground": "internal accessor/plumbing, not a user-facing SDK control seam",
140
+
135
141
  "agent_session:getSelectedMCPToolNames": "internal accessor/plumbing, not a user-facing control seam",
136
142
  "agent_session:isToolDiscoveryEnabled": "internal accessor/plumbing, not a user-facing control seam",
137
143
  "agent_session:getDiscoverableToolSearchIndex": "internal accessor/plumbing, not a user-facing control seam",
@@ -1567,6 +1567,24 @@ function isTypeOnlyTmuxPrimitiveOccurrence(contents: string, occurrence: TmuxPri
1567
1567
  return /^\s*(?:export\s+)?type\b/.test(contents.slice(lineStart, lineEnd === -1 ? contents.length : lineEnd));
1568
1568
  }
1569
1569
 
1570
+ function isExactTmuxSelfInjectionGuardVerb(
1571
+ file: string,
1572
+ contents: string,
1573
+ occurrence: TmuxPrimitiveOccurrence,
1574
+ ): boolean {
1575
+ if (file !== "packages/coding-agent/src/tools/tmux-self-injection-guard.ts") return false;
1576
+ const declaration = 'const INPUT_VERBS = new Set(["send-keys", "paste-buffer", "send-prefix"]);';
1577
+ const declarationStart = contents.indexOf(declaration);
1578
+ if (declarationStart === -1 || contents.indexOf(declaration, declarationStart + 1) !== -1) return false;
1579
+ const references = [...contents.matchAll(/\bINPUT_VERBS\b/g)];
1580
+ if (references.length !== 2) return false;
1581
+ const guardUse = "INPUT_VERBS.has(invocation.verb)";
1582
+ const guardUseStart = contents.indexOf(guardUse);
1583
+ if (guardUseStart === -1 || contents.indexOf(guardUse, guardUseStart + 1) !== -1) return false;
1584
+ if (!references.some(reference => reference.index === guardUseStart)) return false;
1585
+ return occurrence.start >= declarationStart && occurrence.end <= declarationStart + declaration.length;
1586
+ }
1587
+
1570
1588
  function tmuxMachineBusViolations(file: string, contents: string): string[] {
1571
1589
  if (isGeneratedDocumentationIndex(file)) return [];
1572
1590
  const allowedTeamFallbackRanges =
@@ -1581,7 +1599,8 @@ function tmuxMachineBusViolations(file: string, contents: string): string[] {
1581
1599
  if (
1582
1600
  isExactTeamFallback ||
1583
1601
  isExactTmuxScrollCopyModeSendKeys(file, contents, occurrence) ||
1584
- isTypeOnlyTmuxPrimitiveOccurrence(contents, occurrence)
1602
+ isTypeOnlyTmuxPrimitiveOccurrence(contents, occurrence) ||
1603
+ isExactTmuxSelfInjectionGuardVerb(file, contents, occurrence)
1585
1604
  )
1586
1605
  continue;
1587
1606
  const detail =
@@ -3147,6 +3166,21 @@ fi
3147
3166
  1,
3148
3167
  "tmux send-keys content injection is outside sanctioned process lifecycle",
3149
3168
  );
3169
+ await runSelfTestFixture(
3170
+ {
3171
+ "packages/coding-agent/src/tools/tmux-self-injection-guard.ts":
3172
+ 'const INPUT_VERBS = new Set(["send-keys", "paste-buffer", "send-prefix"]);\nfunction guarded(invocation: { verb: string }): void { if (!INPUT_VERBS.has(invocation.verb)) return; }\n',
3173
+ },
3174
+ 0,
3175
+ );
3176
+ await runSelfTestFixture(
3177
+ {
3178
+ "packages/coding-agent/src/tools/tmux-self-injection-guard.ts":
3179
+ 'const INPUT_VERBS = new Set(["send-keys", "paste-buffer", "send-prefix"]);\nfunction guarded(invocation: { verb: string }): void { if (!INPUT_VERBS.has(invocation.verb)) return; }\nfor (const verb of INPUT_VERBS) Bun.spawnSync(["tmux", verb, "-t", pane, prompt]);\n',
3180
+ },
3181
+ 1,
3182
+ "tmux send-keys content injection is outside sanctioned process lifecycle",
3183
+ );
3150
3184
  await runSelfTestFixture(
3151
3185
  {
3152
3186
  "packages/coding-agent/src/gjc-runtime/team-runtime.ts":