@gajae-code/coding-agent 0.15.6 → 0.16.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 (270) hide show
  1. package/CHANGELOG.md +99 -0
  2. package/dist/types/async/job-manager.d.ts +32 -1
  3. package/dist/types/browser-backend.d.ts +12 -0
  4. package/dist/types/cli/args.d.ts +2 -0
  5. package/dist/types/cli/root-flags.d.ts +14 -0
  6. package/dist/types/cli/update-cli.d.ts +14 -0
  7. package/dist/types/cli.d.ts +7 -0
  8. package/dist/types/commands/launch.d.ts +10 -0
  9. package/dist/types/commands/sdk.d.ts +2 -0
  10. package/dist/types/config/autorouting-tier-map.d.ts +24 -0
  11. package/dist/types/config/billing-path.d.ts +25 -0
  12. package/dist/types/config/config-schema-version.d.ts +13 -1
  13. package/dist/types/config/file-lock.d.ts +5 -0
  14. package/dist/types/config/model-registry.d.ts +22 -0
  15. package/dist/types/config/settings-schema.d.ts +27 -8
  16. package/dist/types/config/settings.d.ts +2 -0
  17. package/dist/types/coordinator-mcp/projection-scan.d.ts +8 -0
  18. package/dist/types/crash/record-loader.d.ts +15 -0
  19. package/dist/types/extensibility/extensions/types.d.ts +8 -3
  20. package/dist/types/gjc-runtime/launch-worktree-reservation.d.ts +21 -0
  21. package/dist/types/gjc-runtime/launch-worktree.d.ts +25 -1
  22. package/dist/types/gjc-runtime/managed-owner-supervisor.d.ts +2 -0
  23. package/dist/types/gjc-runtime/session-state-lock.d.ts +22 -0
  24. package/dist/types/gjc-runtime/session-state-sidecar.d.ts +66 -1
  25. package/dist/types/gjc-runtime/tmux-owner-isolation.d.ts +1 -0
  26. package/dist/types/gjc-runtime/tmux-sessions.d.ts +27 -0
  27. package/dist/types/main.d.ts +1 -0
  28. package/dist/types/master-mode/context.d.ts +21 -0
  29. package/dist/types/master-mode/first-request.d.ts +34 -0
  30. package/dist/types/master-mode/snapshot.d.ts +32 -0
  31. package/dist/types/modes/acp/acp-agent.d.ts +21 -21
  32. package/dist/types/modes/components/frictionless-onboarding-selector.d.ts +10 -0
  33. package/dist/types/modes/components/model-selector.d.ts +4 -0
  34. package/dist/types/modes/components/oauth-selector.d.ts +1 -0
  35. package/dist/types/modes/components/session-selector.d.ts +1 -1
  36. package/dist/types/modes/components/sessions-dashboard.d.ts +2 -1
  37. package/dist/types/modes/components/status-line/model-name.d.ts +18 -0
  38. package/dist/types/modes/components/status-line/priority-row.d.ts +34 -0
  39. package/dist/types/modes/components/status-line/segments.d.ts +10 -0
  40. package/dist/types/modes/interactive-mode.d.ts +16 -2
  41. package/dist/types/modes/print-mode.d.ts +17 -0
  42. package/dist/types/modes/theme/theme.d.ts +2 -1
  43. package/dist/types/modes/types.d.ts +2 -0
  44. package/dist/types/modes/ui-language.d.ts +7 -1
  45. package/dist/types/sdk/broker/broker.d.ts +79 -2
  46. package/dist/types/sdk/broker/endpoint-authority.d.ts +24 -0
  47. package/dist/types/sdk/broker/ensure.d.ts +3 -0
  48. package/dist/types/sdk/broker/index.d.ts +3 -0
  49. package/dist/types/sdk/broker/lifecycle-ledger.d.ts +6 -0
  50. package/dist/types/sdk/broker/lifecycle.d.ts +40 -0
  51. package/dist/types/sdk/broker/master-capability.d.ts +10 -0
  52. package/dist/types/sdk/broker/session-index.d.ts +40 -11
  53. package/dist/types/sdk/broker/session-scope.d.ts +72 -0
  54. package/dist/types/sdk/broker/spawn-authority.d.ts +201 -0
  55. package/dist/types/sdk/broker/spawn-substrate.d.ts +30 -0
  56. package/dist/types/sdk/broker/startup-budget.d.ts +52 -0
  57. package/dist/types/sdk/broker/state-version.d.ts +21 -1
  58. package/dist/types/sdk/broker/worktree-occupancy.d.ts +28 -0
  59. package/dist/types/sdk/bus/chat-daemon-control.d.ts +3 -0
  60. package/dist/types/sdk/bus/discord-daemon.d.ts +1 -1
  61. package/dist/types/sdk/bus/index.d.ts +9 -1
  62. package/dist/types/sdk/bus/kind-aware-reconciliation.d.ts +1 -1
  63. package/dist/types/sdk/bus/prompt-reconciliation.d.ts +1 -1
  64. package/dist/types/sdk/bus/slack-conversation.d.ts +1 -1
  65. package/dist/types/sdk/bus/slack-daemon.d.ts +1 -1
  66. package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +1 -1
  67. package/dist/types/sdk/cli/index.d.ts +1 -0
  68. package/dist/types/sdk/cli/master-cli.d.ts +63 -0
  69. package/dist/types/sdk/cli/rows.d.ts +12 -5
  70. package/dist/types/sdk/cli/session-cli.d.ts +20 -3
  71. package/dist/types/sdk/client/client.d.ts +3 -2
  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/events.d.ts +1 -0
  77. package/dist/types/sdk/host/host.d.ts +10 -0
  78. package/dist/types/sdk/host/query/cursor.d.ts +4 -2
  79. package/dist/types/sdk/host/query/handlers.d.ts +1 -0
  80. package/dist/types/sdk/host/query/revision-store.d.ts +1 -0
  81. package/dist/types/sdk/host/session-runtime.d.ts +70 -17
  82. package/dist/types/sdk/lifecycle/broker-client.d.ts +6 -0
  83. package/dist/types/sdk/lifecycle/service.d.ts +15 -3
  84. package/dist/types/sdk/lifecycle-session.d.ts +3 -1
  85. package/dist/types/sdk/prompt-deadline-manager.d.ts +2 -5
  86. package/dist/types/sdk/receipt-state.d.ts +2 -0
  87. package/dist/types/sdk/router/session-router.d.ts +6 -0
  88. package/dist/types/sdk/session.d.ts +16 -0
  89. package/dist/types/sdk/startup-capability.d.ts +2 -1
  90. package/dist/types/sdk/turn-result.d.ts +6 -0
  91. package/dist/types/session/agent-session.d.ts +52 -7
  92. package/dist/types/session/credential-store-errors.d.ts +1 -0
  93. package/dist/types/session/fold-coordinator.d.ts +29 -2
  94. package/dist/types/session/session-manager.d.ts +79 -2
  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/tools/ask.d.ts +1 -0
  98. package/dist/types/tools/bash.d.ts +16 -0
  99. package/dist/types/tools/browser/launch.d.ts +10 -0
  100. package/dist/types/tools/browser/registry.d.ts +8 -0
  101. package/dist/types/tools/gh.d.ts +8 -0
  102. package/dist/types/tools/index.d.ts +10 -10
  103. package/dist/types/tools/job.d.ts +3 -1
  104. package/dist/types/utils/external-editor.d.ts +7 -0
  105. package/examples/extensions/README.md +1 -1
  106. package/examples/extensions/pirate.ts +7 -4
  107. package/package.json +7 -7
  108. package/scripts/generate-sdk-operation-inventory.ts +13 -1
  109. package/scripts/verify-gjc-sdk-canonicalization.ts +35 -1
  110. package/src/async/job-manager.ts +107 -9
  111. package/src/browser-backend.ts +29 -0
  112. package/src/cli/accounts-cli.ts +9 -5
  113. package/src/cli/args.ts +17 -0
  114. package/src/cli/fast-help.ts +1 -0
  115. package/src/cli/plugin-cli.ts +29 -0
  116. package/src/cli/root-flags.ts +5 -0
  117. package/src/cli/update-cli.ts +140 -23
  118. package/src/commands/launch.ts +86 -18
  119. package/src/commands/sdk.ts +135 -28
  120. package/src/config/autorouting-tier-map.ts +12 -0
  121. package/src/config/billing-path.ts +42 -0
  122. package/src/config/config-schema-version.ts +18 -1
  123. package/src/config/file-lock.ts +158 -83
  124. package/src/config/model-preset-registry.ts +178 -23
  125. package/src/config/model-profiles.ts +5 -5
  126. package/src/config/model-registry.ts +291 -42
  127. package/src/config/model-resolver.ts +5 -0
  128. package/src/config/settings-schema.ts +27 -8
  129. package/src/config/settings.ts +51 -15
  130. package/src/coordinator-mcp/projection-scan.ts +27 -6
  131. package/src/coordinator-mcp/question-state.ts +9 -11
  132. package/src/coordinator-mcp/server.ts +115 -21
  133. package/src/crash/index-store.ts +2 -0
  134. package/src/crash/record-loader.ts +10 -0
  135. package/src/defaults/gjc/skills/deep-interview/SKILL.md +1 -1
  136. package/src/extensibility/extensions/runner.ts +27 -0
  137. package/src/extensibility/extensions/types.ts +8 -3
  138. package/src/extensibility/gjc-plugins/installer.ts +51 -11
  139. package/src/extensibility/runtime-skill-discovery.ts +110 -3
  140. package/src/extensibility/skills.ts +22 -12
  141. package/src/gjc-runtime/launch-worktree-reservation.ts +242 -0
  142. package/src/gjc-runtime/launch-worktree.ts +285 -4
  143. package/src/gjc-runtime/managed-owner-supervisor.ts +63 -51
  144. package/src/gjc-runtime/session-state-lock.ts +213 -14
  145. package/src/gjc-runtime/session-state-sidecar.ts +938 -39
  146. package/src/gjc-runtime/tmux-owner-isolation-cli.ts +4 -7
  147. package/src/gjc-runtime/tmux-owner-isolation.ts +18 -3
  148. package/src/gjc-runtime/tmux-sessions.ts +252 -13
  149. package/src/hooks/skill-state.ts +6 -0
  150. package/src/internal-urls/docs-index.generated.ts +15 -15
  151. package/src/internal-urls/issue-pr-protocol.ts +4 -2
  152. package/src/main.ts +61 -3
  153. package/src/master-mode/context.ts +50 -0
  154. package/src/master-mode/first-request.ts +65 -0
  155. package/src/master-mode/snapshot.ts +205 -0
  156. package/src/modes/acp/acp-agent.ts +610 -161
  157. package/src/modes/components/footer.ts +4 -2
  158. package/src/modes/components/frictionless-onboarding-selector.ts +48 -2
  159. package/src/modes/components/model-selector.ts +76 -8
  160. package/src/modes/components/oauth-selector.ts +6 -1
  161. package/src/modes/components/session-selector.ts +23 -15
  162. package/src/modes/components/sessions-dashboard.ts +8 -5
  163. package/src/modes/components/settings-selector.ts +1 -0
  164. package/src/modes/components/status-line/model-name.ts +53 -0
  165. package/src/modes/components/status-line/priority-row.ts +107 -0
  166. package/src/modes/components/status-line/segments.ts +23 -9
  167. package/src/modes/components/tool-status-header.ts +151 -15
  168. package/src/modes/controllers/command-controller.ts +1 -1
  169. package/src/modes/controllers/event-controller.ts +30 -4
  170. package/src/modes/controllers/extension-ui-controller.ts +13 -13
  171. package/src/modes/controllers/input-controller.ts +30 -2
  172. package/src/modes/controllers/selector-controller.ts +200 -98
  173. package/src/modes/interactive-mode.ts +36 -12
  174. package/src/modes/print-mode.ts +64 -0
  175. package/src/modes/prompt-action-autocomplete.ts +30 -4
  176. package/src/modes/runtime-init.ts +12 -9
  177. package/src/modes/theme/theme.ts +5 -0
  178. package/src/modes/types.ts +2 -0
  179. package/src/modes/ui-language.ts +49 -2
  180. package/src/modes/utils/ui-helpers.ts +22 -3
  181. package/src/prompts/agent-fragments/browser-aside.md +22 -0
  182. package/src/prompts/system/master-mode.md +28 -0
  183. package/src/prompts/tools/ask.md +1 -1
  184. package/src/prompts/tools/bash.md +1 -0
  185. package/src/prompts/tools/job.md +1 -1
  186. package/src/sdk/acp/adapter.ts +5 -0
  187. package/src/sdk/broker/broker.ts +1646 -27
  188. package/src/sdk/broker/endpoint-authority.ts +86 -0
  189. package/src/sdk/broker/ensure.ts +81 -3
  190. package/src/sdk/broker/index.ts +3 -0
  191. package/src/sdk/broker/lifecycle-ledger.ts +6 -0
  192. package/src/sdk/broker/lifecycle.ts +440 -75
  193. package/src/sdk/broker/master-capability.ts +232 -0
  194. package/src/sdk/broker/session-index.ts +121 -17
  195. package/src/sdk/broker/session-scope.ts +272 -0
  196. package/src/sdk/broker/spawn-authority.ts +1031 -0
  197. package/src/sdk/broker/spawn-substrate.ts +591 -0
  198. package/src/sdk/broker/startup-budget.ts +144 -2
  199. package/src/sdk/broker/state-version.ts +43 -14
  200. package/src/sdk/broker/transport.ts +1 -0
  201. package/src/sdk/broker/worktree-occupancy.ts +90 -0
  202. package/src/sdk/bus/chat-daemon-control.ts +5 -2
  203. package/src/sdk/bus/chat-daemon-runtime.ts +136 -18
  204. package/src/sdk/bus/discord-daemon.ts +50 -10
  205. package/src/sdk/bus/index.ts +84 -7
  206. package/src/sdk/bus/kind-aware-reconciliation.ts +296 -48
  207. package/src/sdk/bus/lifecycle-commands.ts +4 -0
  208. package/src/sdk/bus/notification-service.ts +22 -5
  209. package/src/sdk/bus/prompt-reconciliation.ts +7 -2
  210. package/src/sdk/bus/reconciliation-store.ts +55 -31
  211. package/src/sdk/bus/slack-conversation.ts +1 -1
  212. package/src/sdk/bus/slack-daemon.ts +72 -38
  213. package/src/sdk/bus/telegram-daemon-contract.ts +1 -1
  214. package/src/sdk/cli/index.ts +1 -0
  215. package/src/sdk/cli/master-cli.ts +259 -0
  216. package/src/sdk/cli/rows.ts +41 -15
  217. package/src/sdk/cli/session-cli.ts +297 -26
  218. package/src/sdk/client/client.ts +14 -8
  219. package/src/sdk/host/control/dispatch.ts +101 -40
  220. package/src/sdk/host/control/index.ts +2 -0
  221. package/src/sdk/host/control/operations.ts +2 -0
  222. package/src/sdk/host/control/runtime-gate.ts +203 -11
  223. package/src/sdk/host/events.ts +1 -0
  224. package/src/sdk/host/host.ts +29 -2
  225. package/src/sdk/host/query/cursor.ts +52 -7
  226. package/src/sdk/host/query/handlers.ts +33 -12
  227. package/src/sdk/host/query/revision-store.ts +12 -0
  228. package/src/sdk/host/session-runtime.test.ts +673 -14
  229. package/src/sdk/host/session-runtime.ts +674 -103
  230. package/src/sdk/host/surface-policy.ts +3 -3
  231. package/src/sdk/lifecycle/broker-client.ts +28 -0
  232. package/src/sdk/lifecycle/service.ts +279 -20
  233. package/src/sdk/lifecycle-session.ts +17 -4
  234. package/src/sdk/prompt-deadline-manager.ts +2 -1
  235. package/src/sdk/protocol/operation-inventory.generated.json +105 -3
  236. package/src/sdk/protocol/operation-registry.ts +14 -4
  237. package/src/sdk/receipt-state.ts +10 -0
  238. package/src/sdk/router/session-router.ts +219 -118
  239. package/src/sdk/session.ts +416 -195
  240. package/src/sdk/startup-capability.ts +1 -0
  241. package/src/sdk/turn-result.ts +22 -0
  242. package/src/session/agent-session.ts +1628 -318
  243. package/src/session/blob-store.ts +15 -5
  244. package/src/session/credential-store-errors.ts +2 -0
  245. package/src/session/fold-coordinator.ts +40 -3
  246. package/src/session/internal/managed-session-storage.ts +153 -78
  247. package/src/session/session-manager.ts +850 -97
  248. package/src/session/yield-queue.ts +24 -10
  249. package/src/setup/frictionless-onboarding.ts +2 -0
  250. package/src/slash-commands/builtin-registry.ts +41 -0
  251. package/src/task/executor.ts +9 -4
  252. package/src/telemetry/events.ts +1138 -12
  253. package/src/tools/ask-contract.test.ts +64 -0
  254. package/src/tools/ask-contract.ts +36 -1
  255. package/src/tools/ask.ts +10 -8
  256. package/src/tools/bash-interactive.ts +11 -2
  257. package/src/tools/bash.ts +412 -75
  258. package/src/tools/browser/launch.ts +37 -0
  259. package/src/tools/browser/registry.ts +99 -9
  260. package/src/tools/cron.ts +6 -4
  261. package/src/tools/descriptors.test.ts +15 -0
  262. package/src/tools/descriptors.ts +5 -1
  263. package/src/tools/gh.ts +104 -48
  264. package/src/tools/github-cache.ts +2 -2
  265. package/src/tools/index.ts +10 -6
  266. package/src/tools/job.ts +4 -1
  267. package/src/tools/monitor.ts +12 -9
  268. package/src/tools/resolve.ts +30 -10
  269. package/src/tools/tool-catalog.generated.ts +2 -2
  270. package/src/utils/external-editor.ts +72 -1
@@ -18,6 +18,7 @@ import {
18
18
  syntheticNamespaceCollision,
19
19
  } from "../sdk/model-profile-model";
20
20
  import type { AgentSession } from "../session/agent-session";
21
+ import { bashBackgroundControlError } from "../session/fold-coordinator";
21
22
  import { parseThinkingLevel } from "../thinking";
22
23
  import type { TodoPhase } from "../tools/todo-write";
23
24
 
@@ -68,8 +69,12 @@ export async function initializeExtensions(session: AgentSession, options: Initi
68
69
  runner.initialize(
69
70
  // ExtensionActions
70
71
  {
72
+ // Extension sends are INDEPENDENT producers, never continuations of the
73
+ // current turn: the trusted adapter classifies them so a terminal abort
74
+ // preserves them instead of dropping them as turn-owned work. Extensions
75
+ // never supply this bit themselves.
71
76
  sendMessage: (message, sendOptions) => {
72
- session.sendCustomMessage(message, sendOptions).catch(e => {
77
+ session.sendCustomMessage(message, { ...sendOptions, origin: "external" }).catch(e => {
73
78
  reportSendError("extension_send", e instanceof Error ? e : new Error(String(e)));
74
79
  });
75
80
  },
@@ -154,8 +159,8 @@ export async function initializeExtensions(session: AgentSession, options: Initi
154
159
  session.setFollowUpMode(mode);
155
160
  return true;
156
161
  }
157
- if (kind === "interrupt" && (mode === "immediate" || mode === "wait")) {
158
- session.setInterruptMode(mode);
162
+ if (kind === "tool_interrupt" && (mode === "abort_tools" || mode === "finish_tools")) {
163
+ session.setToolInterruptPolicy(mode);
159
164
  return true;
160
165
  }
161
166
  return false;
@@ -195,6 +200,7 @@ export async function initializeExtensions(session: AgentSession, options: Initi
195
200
  return { bytes: new Uint8Array(await file.slice(start, end).arrayBuffer()), totalBytes: file.size };
196
201
  },
197
202
  getJobs: () => session.getAsyncJobSnapshot(),
203
+ onJobFold: listener => session.onJobFold(listener),
198
204
  setSdkPermissionProvider: provider => session.setSdkPermissionProvider(provider),
199
205
  setSdkClientBridge: bridge => session.setClientBridge(bridge),
200
206
  sdkControl: async (operation, input) => {
@@ -343,12 +349,9 @@ export async function initializeExtensions(session: AgentSession, options: Initi
343
349
  return { retried: true, immediate: true };
344
350
  }
345
351
  case "bash.background": {
346
- if (!(await session.requestForegroundBashBackground()))
347
- throw Object.assign(
348
- new Error("The active bash command cannot be moved to a managed background job."),
349
- { code: "not_foldable" },
350
- );
351
- return { backgrounded: true };
352
+ const outcome = await session.requestForegroundBashBackgroundOutcome("sdk_control");
353
+ if (outcome.status !== "folded") throw bashBackgroundControlError(outcome);
354
+ return { backgrounded: true, jobId: outcome.jobId };
352
355
  }
353
356
  case "compaction.auto.set":
354
357
  session.setAutoCompactionEnabled(input.on === true);
@@ -136,6 +136,7 @@ export type SymbolKey =
136
136
  | "icon.output"
137
137
  | "icon.host"
138
138
  | "icon.session"
139
+ | "icon.star"
139
140
  | "icon.package"
140
141
  | "icon.warning"
141
142
  | "icon.rewind"
@@ -300,6 +301,7 @@ const UNICODE_SYMBOLS: SymbolMap = {
300
301
  "icon.output": "⤴",
301
302
  "icon.host": "🖥",
302
303
  "icon.session": "🆔",
304
+ "icon.star": "★",
303
305
  "icon.package": "📦",
304
306
  "icon.warning": "⚠",
305
307
  "icon.rewind": "↶",
@@ -534,6 +536,7 @@ const NERD_SYMBOLS: SymbolMap = {
534
536
  "icon.host": "\uf109",
535
537
  // pick:  | alt:  
536
538
  "icon.session": "\uf550",
539
+ "icon.star": "\uf005",
537
540
  // pick:  | alt: 
538
541
  "icon.package": "\uf487",
539
542
  // pick:  | alt:  
@@ -722,6 +725,7 @@ const ASCII_SYMBOLS: SymbolMap = {
722
725
  "icon.output": "out:",
723
726
  "icon.host": "host",
724
727
  "icon.session": "id",
728
+ "icon.star": "*",
725
729
  "icon.package": "[P]",
726
730
  "icon.warning": "[!]",
727
731
  "icon.rewind": "<-",
@@ -1496,6 +1500,7 @@ export class Theme {
1496
1500
  output: this.#symbols["icon.output"],
1497
1501
  host: this.#symbols["icon.host"],
1498
1502
  session: this.#symbols["icon.session"],
1503
+ star: this.#symbols["icon.star"],
1499
1504
  package: this.#symbols["icon.package"],
1500
1505
  warning: this.#symbols["icon.warning"],
1501
1506
  rewind: this.#symbols["icon.rewind"],
@@ -41,6 +41,8 @@ export type CompactionQueuedMessage = {
41
41
  text: string;
42
42
  mode: "steer" | "followUp";
43
43
  followUpQueuePolicy?: "sequential";
44
+ /** Composer steers stay one per poll even under `steeringMode: "all"`. */
45
+ steerQueuePolicy?: "sequential";
44
46
  };
45
47
 
46
48
  export type SubmittedUserInput = {
@@ -1,4 +1,4 @@
1
- export const UI_LANGUAGES = ["en", "ko", "ja"] as const;
1
+ export const UI_LANGUAGES = ["en", "ko", "zh", "ja"] as const;
2
2
 
3
3
  export type UiLanguage = (typeof UI_LANGUAGES)[number];
4
4
 
@@ -23,6 +23,7 @@ const ENGLISH_STRINGS = {
23
23
  "settings.language.description": "Language for human-facing interactive UI text",
24
24
  "settings.language.english": "English",
25
25
  "settings.language.korean": "Korean (한국어)",
26
+ "settings.language.chinese": "Chinese (简体中文)",
26
27
  "settings.language.japanese": "Japanese (日本語)",
27
28
  "language.current": "Current UI language:",
28
29
  "language.changed": "UI language changed to",
@@ -52,6 +53,7 @@ const KOREAN_STRINGS: Record<UiStringKey, string> = {
52
53
  "settings.language.description": "사람이 읽는 대화형 UI 텍스트의 언어",
53
54
  "settings.language.english": "English",
54
55
  "settings.language.korean": "한국어",
56
+ "settings.language.chinese": "简体中文",
55
57
  "settings.language.japanese": "日本語",
56
58
  "language.current": "현재 UI 언어:",
57
59
  "language.changed": "UI 언어를 다음으로 변경했습니다:",
@@ -79,21 +81,61 @@ const JAPANESE_STRINGS: Record<UiStringKey, string> = {
79
81
  "settings.language.description": "対話型 UI テキストに使う言語",
80
82
  "settings.language.english": "English",
81
83
  "settings.language.korean": "한국어",
84
+ "settings.language.chinese": "简体中文",
82
85
  "settings.language.japanese": "日本語",
83
86
  "language.current": "現在の UI 言語:",
84
87
  "language.changed": "UI 言語を次に変更しました:",
85
88
  "language.unknown": "不明な言語",
86
89
  };
87
90
 
91
+ const CHINESE_STRINGS: Record<UiStringKey, string> = {
92
+ "settings.title": "设置",
93
+ "settings.navigationHint": "(按 Tab 切换)",
94
+ "settings.selectHint": " Enter:选择 · Esc:返回",
95
+ "settings.preview": "预览:",
96
+ "settings.tab.appearance": "外观",
97
+ "settings.tab.model": "模型",
98
+ "settings.tab.interaction": "交互",
99
+ "settings.tab.context": "上下文",
100
+ "settings.tab.memory": "记忆",
101
+ "settings.tab.editing": "编辑",
102
+ "settings.tab.tools": "工具",
103
+ "settings.tab.tasks": "任务",
104
+ "settings.tab.providers": "提供商",
105
+ "settings.tab.notifications": "通知",
106
+ "settings.tab.plugins": "插件",
107
+ "settings.tab.gjcBundles": "GJC 捆绑包",
108
+ "settings.language.label": "语言",
109
+ "settings.language.description": "面向用户的交互式界面文字所使用的语言",
110
+ "settings.language.english": "English",
111
+ "settings.language.korean": "한국어",
112
+ "settings.language.chinese": "简体中文",
113
+ "settings.language.japanese": "日本語",
114
+ "language.current": "当前界面语言:",
115
+ "language.changed": "界面语言已更改为",
116
+ "language.unknown": "未知语言",
117
+ };
118
+
88
119
  const STRINGS: Record<UiLanguage, Record<UiStringKey, string>> = {
89
120
  en: ENGLISH_STRINGS,
90
121
  ko: KOREAN_STRINGS,
122
+ zh: CHINESE_STRINGS,
91
123
  ja: JAPANESE_STRINGS,
92
124
  };
93
125
 
94
126
  /** User selection is authoritative; invalid or unavailable values deterministically fall back to English. */
95
127
  export function resolveUiLanguage(value: unknown): UiLanguage {
96
- return value === "ko" || value === "ja" ? value : "en";
128
+ return value === "ko" || value === "zh" || value === "ja" ? value : "en";
129
+ }
130
+
131
+ /** Resolve explicit startup preference without allowing an invalid value to block startup. */
132
+ export function resolveExplicitUiLanguage(
133
+ configuredValue: unknown,
134
+ environmentValue: string | undefined,
135
+ ): { language: UiLanguage; hasPreference: boolean } {
136
+ if (configuredValue !== undefined) return { language: resolveUiLanguage(configuredValue), hasPreference: true };
137
+ if (environmentValue === undefined) return { language: "en", hasPreference: false };
138
+ return { language: parseUiLanguage(environmentValue) ?? "en", hasPreference: true };
97
139
  }
98
140
 
99
141
  export function uiString(language: unknown, key: UiStringKey): string {
@@ -104,6 +146,7 @@ export function uiString(language: unknown, key: UiStringKey): string {
104
146
  export const UI_LANGUAGE_LABELS: Record<UiLanguage, string> = {
105
147
  en: "English",
106
148
  ko: "한국어",
149
+ zh: "简体中文",
107
150
  ja: "日本語",
108
151
  };
109
152
 
@@ -117,6 +160,10 @@ const UI_LANGUAGE_ALIASES: Readonly<Record<string, UiLanguage>> = {
117
160
  kor: "ko",
118
161
  korean: "ko",
119
162
  한국어: "ko",
163
+ zh: "zh",
164
+ 中文: "zh",
165
+ 简体中文: "zh",
166
+ chinese: "zh",
120
167
  ja: "ja",
121
168
  jp: "ja",
122
169
  jpn: "ja",
@@ -1091,6 +1091,11 @@ export class UiHelpers {
1091
1091
 
1092
1092
  queueCompactionMessage(text: string, mode: "steer" | "followUp", options?: ComposerSubmissionOptions): void {
1093
1093
  const entry: CompactionQueuedMessage = { text, mode };
1094
+ // A composer steer keeps the same one-per-poll delivery it would have had
1095
+ // without compaction: the mark has to survive the park/replay round trip.
1096
+ if (mode === "steer") {
1097
+ entry.steerQueuePolicy = "sequential";
1098
+ }
1094
1099
  if (mode === "followUp") {
1095
1100
  entry.followUpQueuePolicy = "sequential";
1096
1101
  }
@@ -1115,6 +1120,11 @@ export class UiHelpers {
1115
1120
  return message.followUpQueuePolicy ?? "sequential";
1116
1121
  }
1117
1122
 
1123
+ #compactionSteerQueuePolicy(message: CompactionQueuedMessage): "sequential" | undefined {
1124
+ if (message.mode !== "steer") return undefined;
1125
+ return message.steerQueuePolicy ?? "sequential";
1126
+ }
1127
+
1118
1128
  async #deliverQueuedSkillMessage(message: CompactionQueuedMessage): Promise<boolean> {
1119
1129
  const invocations = parseSkillInvocations(message.text, this.ctx.skillCommands ?? new Map());
1120
1130
  if (invocations.length === 0) {
@@ -1163,7 +1173,10 @@ export class UiHelpers {
1163
1173
  streamingBehavior: message.mode,
1164
1174
  followUpQueuePolicy: this.#compactionFollowUpQueuePolicy(message),
1165
1175
  }
1166
- : { streamingBehavior: message.mode };
1176
+ : {
1177
+ streamingBehavior: message.mode,
1178
+ steerQueuePolicy: this.#compactionSteerQueuePolicy(message),
1179
+ };
1167
1180
  await this.ctx.session.promptCustomMessage(
1168
1181
  {
1169
1182
  customType: SKILL_PROMPT_MESSAGE_TYPE,
@@ -1196,7 +1209,10 @@ export class UiHelpers {
1196
1209
  ? this.ctx.session.followUp(message.text, undefined, {
1197
1210
  followUpQueuePolicy: this.#compactionFollowUpQueuePolicy(message),
1198
1211
  })
1199
- : this.ctx.session.steer(message.text),
1212
+ : this.ctx.session.prompt(message.text, {
1213
+ streamingBehavior: "steer",
1214
+ steerQueuePolicy: this.#compactionSteerQueuePolicy(message),
1215
+ }),
1200
1216
  );
1201
1217
  }
1202
1218
 
@@ -1310,7 +1326,10 @@ export class UiHelpers {
1310
1326
  streamingBehavior: "followUp" as const,
1311
1327
  followUpQueuePolicy: this.#compactionFollowUpQueuePolicy(firstPrompt),
1312
1328
  }
1313
- : { streamingBehavior: "steer" as const };
1329
+ : {
1330
+ streamingBehavior: "steer" as const,
1331
+ steerQueuePolicy: this.#compactionSteerQueuePolicy(firstPrompt),
1332
+ };
1314
1333
  const promptPromise = this.ctx.session.prompt(firstPrompt.text, firstPromptOptions).catch((error: unknown) => {
1315
1334
  disposeFirstPrompt();
1316
1335
  restoreQueue(error);
@@ -0,0 +1,22 @@
1
+ <browser-backend>
2
+ Browser backend: Aside direct CLI. The built-in Puppeteer browser tool is disabled by configuration (`browser.backend: aside`). NEVER use or register an MCP browser server.
3
+
4
+ Routing:
5
+ - Every task that requires a rendered page, authenticated/private browser state, live tabs, browser UI, screenshots, downloads behind cookies, history, saved credentials, or profile data MUST use Bash to invoke the installed Aside CLI.
6
+ - Default to `aside repl '<JavaScript>'` for deterministic Playwright inspection and actions, even when the answer is unknown but the procedure is discoverable from `snapshot(page, { interactive: true })`.
7
+ - Use `aside exec '<prompt>'` only for runtime judgment, source-heavy research, browser-history search, MFA or opaque password autofill, approval/notification waits, long monitoring, multi-site synthesis, routines, or work worth a second model. Continue with `aside exec --session <id> '<follow-up>'`. Use `--account`, `--model`, `--provider`, `--speed`, or `--effort` only when the task requires overriding user defaults.
8
+ - Cookie-free public HTTP content that does not require rendered or authenticated browser state may use GJC `read` directly.
9
+
10
+ Deterministic procedure:
11
+ - Each non-interactive `aside repl '<code>'` shell invocation starts from neutral local JavaScript scope: make it self-contained and do not depend on variables declared in an earlier invocation.
12
+ - Call `listBrowserTabs()`, select by URL/title, `attachBrowserTab(targetId)`, then verify `page.url()` and `await page.title()` before reading or acting. Use `attachActiveBrowserTab()` only when active-tab authority is intentional; use `openTab()` only when no relevant tab exists.
13
+ - Print results with `console.log`; returned and final-expression values are not emitted. Use `snapshot(page, { interactive: true })` before acting, prefer locators/refs, and verify every meaningful action with a fresh URL/title, snapshot diff, screenshot, or file path.
14
+ - Use authenticated `fetch` for cookie-bearing downloads. Prefer dedicated integrations for Gmail, Google Docs/Sheets, YouTube, search, social, PDF, and Office files over manual UI automation.
15
+ - Use `chrome.*` only for task-scoped tabs/windows/bookmarks/tab-groups/history/downloads/top-sites profile operations. Use `cua.*` only when DOM semantics cannot control canvas or visual UI; screenshot before and verify after. Use `captcha.*` only in an authorized user-owned session where automation is permitted.
16
+
17
+ Safety:
18
+ - Aside controls a live authenticated profile. Never print cookies, authorization headers, passwords, OTPs, card values, recovery material, signed URLs, raw task transcripts, private profile paths, or broad inbox/contact/history/session collections.
19
+ - Read, inspect, draft, and preview by default. Sending/posting, accepting invitations, payments/purchases/subscriptions, credential saves, document edits, downloads to an external destination, settings/session/routine/channel changes, and destructive profile operations require explicit user intent for the exact target. Stop before the final side effect when authorization is ambiguous.
20
+ - Permission rules (`allow`, `ask`, `deny`), password access policy, target origin, and file/network/download boundaries remain authoritative and must never be bypassed.
21
+ - Load the installed GJC `aside` skill before a browser job when available; it contains the complete official API inventory and scenario matrix. Never claim browser work ran without the Aside CLI result and verified state.
22
+ </browser-backend>
@@ -0,0 +1,28 @@
1
+ # Master Mode
2
+
3
+ You are running as a GJC master session. You coordinate peer GJC sessions through the local Broker; you never control them directly.
4
+
5
+ ## Discovery and scope
6
+
7
+ - Your launch scope (`repo`, `pwd`, or `global`) bounds which peers you see. Every search result states its requested and resolved scope; trust that envelope, never assume wider visibility.
8
+ - Use `gjc sdk search [--scope repo|pwd|global] [--json]` for explicit scope-filtered discovery. Rows carry index live evidence plus a bounded probe verdict (`reachable`, `unreachable`, `stale`).
9
+ - A `not-in-git-worktree` result is a successful empty answer for `repo` scope outside a Git worktree; it never falls back to another scope.
10
+ - The one-time `<gjc-master-peer-snapshot>` block in your first request is a startup observation, not a live view; re-run `gjc sdk search` before acting on peers.
11
+
12
+ ## Peer orchestration
13
+
14
+ - All peer control is broker-routed and best effort: inspect, status, send, tail, steer, and interrupt through the `gjc sdk session` commands. Pre-existing peers owe you nothing; treat them as independent owners.
15
+ - Read-only first: inspect and observe a peer before sending steering or interrupts.
16
+ - Never steer a peer while its user is mid-turn; wait for the peer to be idle or explicitly awaiting input.
17
+ - Do not invent locks, reservations, or exclusive claims over peers; no such mechanism exists, and pretending otherwise corrupts coordination.
18
+
19
+ ## Spawning children
20
+
21
+ - `gjc sdk spawn --cwd <dir> --prompt <task> [--model <selector>] [--profile <name>] [--idempotency-key <key>]` creates one task-seeded background child through the Broker. It is legal only inside this interactive master session.
22
+ - One idempotency identity produces at most one child and one seed prompt. Reuse of the same key replays the stored outcome; a semantically new task requires a new invocation.
23
+ - Spawn responses carry only safe facts (claim, child session id, substrate kind, seed phase/status). `spawn_in_progress` and `terminal_uncertain` are honest states: never retry them blindly; inspect with `gjc sdk search` / session status instead. For `uncertain_after_send`, repeat the same spawn invocation with its reported `--idempotency-key` to join the original claim rather than create another child.
24
+
25
+ ## Delegation discipline
26
+
27
+ - Give each spawned child one bounded task with explicit acceptance criteria in the seed prompt; monitor via broker-routed status/tail and aggregate results yourself.
28
+ - Clean up children you created with `gjc sdk session raw global --op session.close --json-input '{"sessionId":"<id>"}' --idempotency-key <key>` when their work is integrated. Orphaned children are reaped automatically after the configured grace period, but explicit close is the polite default.
@@ -17,7 +17,7 @@ Asks user when you need clarification or input during task execution.
17
17
  <critical>
18
18
  - **Default to action.** Resolve ambiguity yourself using repo conventions, existing patterns, and reasonable defaults. Exhaust existing sources (code, configs, docs, history) before asking. Only ask when options have materially different tradeoffs the user must decide.
19
19
  - **If multiple choices are acceptable**, pick the most conservative/standard option and proceed; state the choice.
20
- - **Do NOT include "Other" option** — UI automatically adds "Other (type your own)" to every question.
20
+ - **Do NOT include the automatic custom-input control or labels that imitate it** such as "Other (type your own)", "Other (specify)", "type your own", "custom input", or "직접 입력" — UI automatically adds "Other (type your own)" to every question. A plain domain value such as "Other" is allowed when it is a genuine answer, not a request for free text. To collect free text, ask for it in the question body and rely on the automatic Other/custom-input control instead of adding a fake option.
21
21
  </critical>
22
22
 
23
23
  <examples>
@@ -18,6 +18,7 @@ Executes bash command in shell session for terminal operations like git, bun, ca
18
18
  {{/if}}
19
19
  {{#if foregroundFoldEnabled}}
20
20
  - In the interactive TUI, the user can press the fold chord twice (default `Alt+Shift+B`, plus `Cmd+B` on macOS; remappable via the `app.tool.backgroundFold` keybinding) while a foreground command is still running to fold it into a background job. All three command surfaces fold: managed non-PTY bash, editor/ACP client-terminal commands, and PTY-mode commands. A folded command keeps its original timeout and is never killed or restarted by folding; a folded PTY continues output-only, so it stops accepting input. The turn then ends cleanly and a later turn resumes automatically with the command's result, so the interrupted task is finished rather than abandoned. `task`/`subagent` waits are deliberately NOT foldable. Do not instruct users to use raw shell `Ctrl+Z`/`bg` inside the GJC TUI; ownership and output routing are not safe there.
21
+ - A user steer folds the same way: when the user sends a message while a foreground command has already run for at least 2 seconds, the command is folded into a background job and this call returns the background-start result plus the line `Folded into background job <id> because a user steer arrived; the command keeps running with its original timeout and its result will wake a later turn.` The steer is then delivered at this tool boundary, so handle it next; do not re-run the folded command. Steers that arrive within the first 2 seconds let the command finish normally. This applies only while `busyPromptMode` is `steer` and `toolInterruptPolicy` is `abort_tools`.
21
22
  {{/if}}
22
23
  </instruction>
23
24
  {{#if restrictedAllowedPrefixes}}
@@ -2,7 +2,7 @@ Inspects, waits, or cancels async jobs.
2
2
 
3
3
  Background job results are delivered automatically when complete. Jobs that back task subagents should be controlled via the `subagent` tool when it is available; use `job` for non-subagent jobs (async bash, monitors) and as a compatibility fallback. Running job output stays quiet by default to avoid flooding the conversation; use `tail` when you explicitly want to show/reopen retained output. Reach for this tool only when you need to inspect or intervene.
4
4
 
5
- In the interactive TUI, a running foreground command can be folded into a background job by pressing the fold chord twice (default `Alt+Shift+B`, plus `Cmd+B` on macOS; remappable via `app.tool.backgroundFold`). This covers managed non-PTY bash, editor/ACP client-terminal commands, and PTY-mode commands. A folded job keeps its original deadline, is never killed or restarted by folding, and its result wakes a later turn automatically; a folded PTY continues output-only and no longer accepts input. `task`/`subagent` waits are not foldable. Raw shell `Ctrl+Z`/`bg` is not the supported path inside GJC because it bypasses job ownership and output-routing contracts.
5
+ In the interactive TUI, a running foreground command can be folded into a background job by pressing the fold chord twice (default `Alt+Shift+B`, plus `Cmd+B` on macOS; remappable via `app.tool.backgroundFold`), or automatically when the user sends a steer after the command has run for at least 2 seconds (with `busyPromptMode=steer` and `toolInterruptPolicy=abort_tools`). This covers managed non-PTY bash, editor/ACP client-terminal commands, and PTY-mode commands. A folded job keeps its original deadline, is never killed or restarted by folding, and its result wakes a later turn automatically; a folded PTY continues output-only and no longer accepts input. Job listings expose `foldReason` (`steer`, `chord`, `timer`, or `sdk_control`) beside `backgrounded` so you can tell why a job left the foreground. `task`/`subagent` waits are not foldable. Raw shell `Ctrl+Z`/`bg` is not the supported path inside GJC because it bypasses job ownership and output-routing contracts.
6
6
 
7
7
  # Operations
8
8
 
@@ -91,6 +91,11 @@ const ACP_MCP_PRESERVED_LAUNCH_CODES = new Set([
91
91
  "startup_admission_timeout",
92
92
  "ready_then_exited",
93
93
  "endpoint_unreadable",
94
+ "worktree_preparation_timeout",
95
+ "dependency_preparation_timeout",
96
+ "readiness_timeout",
97
+ "spawn_failed",
98
+ "worktree_in_use",
94
99
  ]);
95
100
 
96
101
  /**