@gajae-code/coding-agent 0.18.5 → 0.18.7

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 (133) hide show
  1. package/CHANGELOG.md +140 -0
  2. package/dist/types/capability/types.d.ts +4 -0
  3. package/dist/types/cli-commands.d.ts +10 -0
  4. package/dist/types/cli-ordinary.d.ts +13 -0
  5. package/dist/types/cli.d.ts +12 -3
  6. package/dist/types/commands/contribution-prep.d.ts +0 -3
  7. package/dist/types/commands/sdk.d.ts +3 -0
  8. package/dist/types/commands/update.d.ts +1 -0
  9. package/dist/types/config/model-profile-activation.d.ts +19 -0
  10. package/dist/types/config/settings.d.ts +4 -0
  11. package/dist/types/coordinator-mcp/session-reaper.d.ts +5 -0
  12. package/dist/types/discovery/helpers.d.ts +2 -2
  13. package/dist/types/edit/modes/replace.d.ts +3 -3
  14. package/dist/types/edit/streaming.d.ts +2 -2
  15. package/dist/types/exec/bash-shell-supervisor.d.ts +12 -0
  16. package/dist/types/runtime-mcp/elicitation.d.ts +12 -0
  17. package/dist/types/sdk/broker/discovery.d.ts +8 -0
  18. package/dist/types/sdk/broker/ensure.d.ts +1 -0
  19. package/dist/types/sdk/broker/lifecycle-ledger.d.ts +4 -0
  20. package/dist/types/sdk/broker/lifecycle.d.ts +9 -0
  21. package/dist/types/sdk/broker/runtime.d.ts +1 -1
  22. package/dist/types/sdk/broker/task-artifact-owner-validation.d.ts +55 -0
  23. package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +1 -1
  24. package/dist/types/sdk/bus/telegram-daemon.d.ts +4 -2
  25. package/dist/types/sdk/cli/diagnostics-cli.d.ts +18 -0
  26. package/dist/types/sdk/diagnostics/observe-broker.d.ts +185 -0
  27. package/dist/types/sdk/host/control/operations.d.ts +1 -1
  28. package/dist/types/sdk/host/host.d.ts +6 -0
  29. package/dist/types/sdk/index.d.ts +1 -0
  30. package/dist/types/sdk/router/session-router.d.ts +9 -0
  31. package/dist/types/sdk/session.d.ts +13 -0
  32. package/dist/types/session/agent-session.d.ts +5 -1
  33. package/dist/types/session/internal/managed-session-storage.d.ts +11 -1
  34. package/dist/types/session/internal/task-artifact-owner-access.d.ts +17 -0
  35. package/dist/types/session/internal/task-artifact-owner-transcript.d.ts +3 -0
  36. package/dist/types/session/session-retirement.d.ts +47 -0
  37. package/dist/types/session/session-storage.d.ts +0 -46
  38. package/dist/types/session/session-transcript-header.d.ts +2 -0
  39. package/dist/types/session/task-artifact-owner-codec.d.ts +107 -0
  40. package/dist/types/session/task-artifact-owner-retirement.d.ts +7 -0
  41. package/dist/types/session/task-artifact-owner.d.ts +10 -0
  42. package/dist/types/tools/ask-contract.d.ts +75 -254
  43. package/dist/types/tools/bash.d.ts +1 -1
  44. package/package.json +7 -7
  45. package/scripts/build-sdk-package-smoke.ts +5 -0
  46. package/scripts/resident-memory-bench.ts +174 -20
  47. package/src/capability/index.ts +1 -0
  48. package/src/capability/types.ts +4 -0
  49. package/src/cli/config-cli.ts +8 -18
  50. package/src/cli/public-command-entry.ts +5 -0
  51. package/src/cli/ssh-cli.ts +6 -3
  52. package/src/cli/web-search-cli.ts +9 -3
  53. package/src/cli-commands.ts +14 -0
  54. package/src/cli-main.ts +7 -8
  55. package/src/cli-ordinary.ts +197 -0
  56. package/src/cli.ts +25 -182
  57. package/src/commands/contribution-prep.ts +1 -3
  58. package/src/commands/sdk.ts +171 -21
  59. package/src/commands/update.ts +15 -1
  60. package/src/config/file-lock.ts +91 -2
  61. package/src/config/model-profile-activation.ts +70 -4
  62. package/src/config/model-profile-contract.ts +4 -1
  63. package/src/config/model-profiles.ts +23 -31
  64. package/src/config/model-resolver.ts +9 -1
  65. package/src/config/settings.ts +44 -4
  66. package/src/coordinator-mcp/event-webhook.ts +19 -14
  67. package/src/coordinator-mcp/policy.ts +14 -4
  68. package/src/coordinator-mcp/server.ts +142 -7
  69. package/src/coordinator-mcp/session-reaper.ts +9 -1
  70. package/src/defaults/gjc/skills/deep-interview/SKILL.md +1 -1
  71. package/src/discovery/helpers.ts +9 -3
  72. package/src/discovery/ssh.ts +8 -3
  73. package/src/edit/modes/replace.ts +6 -6
  74. package/src/edit/streaming.ts +15 -15
  75. package/src/exec/bash-shell-supervisor.ts +60 -3
  76. package/src/gjc-runtime/gc-runtime.ts +2 -1
  77. package/src/hindsight/config.ts +9 -3
  78. package/src/internal-urls/docs-index.generated.ts +11 -10
  79. package/src/memories/index.ts +8 -2
  80. package/src/modes/acp/acp-agent.ts +724 -370
  81. package/src/modes/components/tool-execution.ts +1 -1
  82. package/src/prompts/tools/ask.md +2 -0
  83. package/src/runtime-mcp/client.ts +13 -4
  84. package/src/runtime-mcp/elicitation.ts +142 -0
  85. package/src/sdk/broker/broker.ts +54 -1
  86. package/src/sdk/broker/daemon-entry.ts +67 -6
  87. package/src/sdk/broker/discovery.ts +8 -0
  88. package/src/sdk/broker/ensure.ts +156 -20
  89. package/src/sdk/broker/lifecycle-ledger.ts +110 -12
  90. package/src/sdk/broker/lifecycle.ts +334 -348
  91. package/src/sdk/broker/runtime.ts +5 -1
  92. package/src/sdk/broker/task-artifact-owner-validation.ts +259 -0
  93. package/src/sdk/broker/transport.ts +5 -1
  94. package/src/sdk/bus/chat-daemon-control.ts +2 -2
  95. package/src/sdk/bus/chat-daemon-runtime.ts +3 -0
  96. package/src/sdk/bus/index.ts +3 -3
  97. package/src/sdk/bus/telegram-daemon-contract.ts +1 -1
  98. package/src/sdk/bus/telegram-daemon-control.ts +15 -12
  99. package/src/sdk/bus/telegram-daemon.ts +38 -3
  100. package/src/sdk/cli/diagnostics-cli.ts +247 -0
  101. package/src/sdk/diagnostics/observe-broker.ts +654 -0
  102. package/src/sdk/host/control/dispatch.ts +52 -4
  103. package/src/sdk/host/control/operations.ts +1 -1
  104. package/src/sdk/host/host.ts +6 -0
  105. package/src/sdk/host/session-runtime.test.ts +83 -4
  106. package/src/sdk/host/session-runtime.ts +15 -7
  107. package/src/sdk/index.ts +1 -0
  108. package/src/sdk/lifecycle-session.ts +1 -0
  109. package/src/sdk/mcp/server.ts +15 -3
  110. package/src/sdk/protocol/operation-registry.ts +1 -1
  111. package/src/sdk/router/session-router.ts +26 -3
  112. package/src/sdk/session.ts +51 -8
  113. package/src/session/agent-session.ts +169 -43
  114. package/src/session/blob-store.ts +78 -33
  115. package/src/session/internal/managed-session-storage.ts +203 -4
  116. package/src/session/internal/task-artifact-owner-access.ts +229 -0
  117. package/src/session/internal/task-artifact-owner-transcript.ts +68 -0
  118. package/src/session/session-retirement.ts +155 -0
  119. package/src/session/session-storage.ts +1 -160
  120. package/src/session/session-transcript-header.ts +17 -0
  121. package/src/session/task-artifact-owner-codec.ts +578 -0
  122. package/src/session/task-artifact-owner-retirement.ts +475 -0
  123. package/src/session/task-artifact-owner.ts +289 -0
  124. package/src/setup/hermes/templates/operator-instructions.v1.md +19 -1
  125. package/src/setup/hermes-setup.ts +4 -1
  126. package/src/slash-commands/builtin-registry.ts +8 -5
  127. package/src/tools/ask-contract.test.ts +76 -1
  128. package/src/tools/ask-contract.ts +57 -6
  129. package/src/tools/ask.ts +16 -7
  130. package/src/tools/bash.ts +38 -29
  131. package/src/tools/descriptors.test.ts +29 -0
  132. package/src/tools/tool-catalog.generated.ts +7 -4
  133. package/src/web/search/index.ts +2 -2
@@ -0,0 +1,197 @@
1
+ /** Ordinary CLI graph: everything the inert entry must not load eagerly.
2
+ *
3
+ * This module owns the effectful bootstrap (startup timing, stderr drainer,
4
+ * bash-shell worker protocol) plus the unchanged ordinary routing order:
5
+ * bash-shell workers -> darwin malloc re-exec -> internal smoke -> tmux owner
6
+ * isolation -> managed-owner supervisor/admission/recovery -> private sdk
7
+ * stderr drainer -> public family dispatch -> community app -> doctor worker /
8
+ * probe / cli -> full registry. `cli.ts` imports it lazily, only after argv has
9
+ * been proven not to be a `sdk diagnostics` observation. */
10
+
11
+ import { APP_NAME, VERSION } from "@gajae-code/utils/cli-metadata";
12
+ import { startTiming } from "@gajae-code/utils/logger";
13
+ import { commands } from "./cli-commands";
14
+ import {
15
+ BASH_SHELL_RUNTIME_ARG,
16
+ BASH_SHELL_SUPERVISOR_ARG,
17
+ BASH_SHELL_WORKER_ARG,
18
+ } from "./exec/bash-shell-worker-protocol";
19
+ import { runSdkStderrDrainerFromArgv } from "./sdk/broker/stderr-drainer";
20
+
21
+ export { commands };
22
+
23
+ const MANAGED_OWNER_SUPERVISOR_ARG = "--internal-managed-owner-supervisor";
24
+ const MANAGED_OWNER_CHILD_TOKEN_ENV = "GJC_MANAGED_OWNER_CHILD_TOKEN";
25
+ const TMUX_OWNER_ISOLATION_ARG = "--internal-tmux-owner-isolation";
26
+
27
+ // Anchor startup timing before the heavy CLI module graph is loaded so the
28
+ // printed tree includes runtime/bootstrap costs as well as dispatch work.
29
+ if (process.env.GJC_TIMING || process.env.PI_TIMING) {
30
+ startTiming();
31
+ }
32
+
33
+ async function installRuntimeGlobals(writeNoFileWarning?: (text: string) => void): Promise<void> {
34
+ // fetch() deliberately stays on HTTP/1.1. Bun's HTTP/2 client (per-request
35
+ // `protocol: "http2"`) wedges a pooled connection while uploading large
36
+ // request bodies (~300KB): every later request on it waits forever for
37
+ // response headers. Do not re-enable HTTP/2 without re-running that probe.
38
+
39
+ const { warnIfMacOSNoFileLimitTooLow } = await import("./cli/nofile-limit");
40
+ warnIfMacOSNoFileLimitTooLow({ writeStderr: writeNoFileWarning });
41
+
42
+ // Secondary in-process scrub of the macOS malloc-stack-logging vars. The real
43
+ // boundary is the darwin re-exec guard at the top of runOrdinaryCli(): Bun snapshots
44
+ // the spawn-default environment at startup, so deleting these here does NOT clean the
45
+ // env children inherit by default — it only tidies `process.env` for code that
46
+ // reads it directly. Kept as belt-and-braces for the rare re-exec-unavailable
47
+ // fallback; managed spawns already use filterProcessEnv and the native PTY lane
48
+ // strips them independently.
49
+ delete process.env.MallocStackLogging;
50
+ delete process.env.MallocStackLoggingNoCompact;
51
+ }
52
+
53
+ async function dispatchPublicFamily(argv: string[]): Promise<void> {
54
+ const family = argv[0];
55
+ if (family !== "sdk" && family !== "daemon") return;
56
+ const { dispatchPublicCommand } = await import("./cli/public-command-entry");
57
+ const load = commands.find(entry => entry.name === family)!.load;
58
+ await dispatchPublicCommand(argv.slice(1), {
59
+ bin: APP_NAME,
60
+ version: VERSION,
61
+ command: family,
62
+ load,
63
+ setup: report => installRuntimeGlobals(text => report({ code: "macos_nofile_limit_low", successStderr: text })),
64
+ });
65
+ }
66
+
67
+ function isDoctorArgv(argv: readonly string[]): boolean {
68
+ return argv[0] === "doctor";
69
+ }
70
+
71
+ async function runDoctor(argv: string[]): Promise<void> {
72
+ const { runDoctorCli } = await import("./cli/doctor-cli");
73
+ await runDoctorCli(argv.slice(1));
74
+ }
75
+
76
+ /** Run every non-diagnostics command with the original admission order. */
77
+ export async function runOrdinaryCli(argv: string[]): Promise<void> {
78
+ if (argv.length === 1 && argv[0] === BASH_SHELL_WORKER_ARG) {
79
+ const { runBashShellGuardian } = await import("./exec/bash-shell-guardian");
80
+ await runBashShellGuardian();
81
+ return;
82
+ }
83
+ if (argv.length === 1 && argv[0] === BASH_SHELL_SUPERVISOR_ARG) {
84
+ const { runBashShellSupervisor } = await import("./exec/bash-shell-supervisor");
85
+ await runBashShellSupervisor();
86
+ return;
87
+ }
88
+ if (argv.length === 1 && argv[0] === BASH_SHELL_RUNTIME_ARG) {
89
+ const { runBashShellWorker } = await import("./exec/bash-shell-worker");
90
+ await runBashShellWorker();
91
+ return;
92
+ }
93
+ if (
94
+ process.platform === "darwin" &&
95
+ process.env.GJC_MALLOC_ENV_REEXEC === undefined &&
96
+ (process.env.MallocStackLogging !== undefined || process.env.MallocStackLoggingNoCompact !== undefined)
97
+ ) {
98
+ const { reexecWithScrubbedMallocEnv } = await import("./cli/malloc-env-guard");
99
+ const code = await reexecWithScrubbedMallocEnv();
100
+ if (code !== null) {
101
+ process.exitCode = code;
102
+ return;
103
+ }
104
+ }
105
+ if (argv.length === 3 && argv[0] === "internal" && argv[1] === "memory-guard-native-smoke" && argv[2] === "--json") {
106
+ const { runMemoryGuardNativeSmoke } = await import("./cli/native-smoke");
107
+ await runMemoryGuardNativeSmoke();
108
+ return;
109
+ }
110
+ if (argv.length === 1 && argv[0] === TMUX_OWNER_ISOLATION_ARG) {
111
+ const { runTmuxOwnerIsolationCliFromStdin } = await import("./gjc-runtime/tmux-owner-isolation-cli");
112
+ await runTmuxOwnerIsolationCliFromStdin();
113
+ return;
114
+ }
115
+ if (argv.length === 1 && argv[0] === MANAGED_OWNER_SUPERVISOR_ARG) {
116
+ const { runManagedOwnerSupervisor } = await import("./gjc-runtime/managed-owner-supervisor");
117
+ await runManagedOwnerSupervisor();
118
+ return;
119
+ }
120
+ if (process.env[MANAGED_OWNER_CHILD_TOKEN_ENV] !== undefined) {
121
+ const { admitManagedOwnerBeforeCli, completeManagedOwnerRecovery } = await import(
122
+ "./gjc-runtime/managed-owner-admission"
123
+ );
124
+ const admission = await admitManagedOwnerBeforeCli();
125
+ if (admission.kind === "blocked") return;
126
+ if (admission.kind === "recovery") {
127
+ await completeManagedOwnerRecovery(admission.context);
128
+ return;
129
+ }
130
+ }
131
+ if (argv[0] === "sdk" && argv[1] === "stderr-drain-internal") {
132
+ // Private lifecycle stderr drainer: must stay ahead of the public sdk family
133
+ // dispatcher, which would otherwise reject the private argv as a usage error.
134
+ try {
135
+ await runSdkStderrDrainerFromArgv(argv.slice(2));
136
+ } catch {
137
+ process.stderr.write("gjc sdk: invalid internal stderr drainer invocation\n");
138
+ process.exitCode = 2;
139
+ }
140
+ return;
141
+ }
142
+ if (argv[0] === "sdk" || argv[0] === "daemon") {
143
+ await dispatchPublicFamily(argv);
144
+ return;
145
+ }
146
+ if (argv.length === 1 && argv[0] === "--supports-macos-community-app") {
147
+ process.stdout.write("macos-community-app-offer\n");
148
+ return;
149
+ }
150
+ if (argv.length === 1 && argv[0] === "--internal-macos-community-app-offer") {
151
+ try {
152
+ const { offerMacosCommunityApp } = await import("./cli/macos-community-app");
153
+ await offerMacosCommunityApp({ log: message => process.stderr.write(`${message}\n`) });
154
+ } catch {
155
+ const { COMMUNITY_APP_REPOSITORY } = await import("./cli/macos-community-app");
156
+ process.stderr.write(
157
+ `Optional community app offer failed; GJC remains installed. https://github.com/${COMMUNITY_APP_REPOSITORY}\n`,
158
+ );
159
+ }
160
+ return;
161
+ }
162
+ if (argv[0] === "--internal-doctor-worker") {
163
+ // Non-forgeable route: reachable only with the exact per-spawn token env var
164
+ // AND a non-TTY stdin (isRoutableDoctorWorkerInvocation), so a user's own
165
+ // interactive terminal can never land on the worker's confirmation-refusal
166
+ // path merely by passing this argv marker.
167
+ const { isRoutableDoctorWorkerInvocation, runDoctorWorker } = await import("./cli/doctor-worker");
168
+ if (argv.length !== 1 || !isRoutableDoctorWorkerInvocation(process.env, process.stdin.isTTY)) {
169
+ process.stderr.write("gjc doctor: invalid internal worker invocation\n");
170
+ process.exitCode = 2;
171
+ return;
172
+ }
173
+ await runDoctorWorker();
174
+ return;
175
+ }
176
+ if (argv[0] === "--internal-doctor-probe") {
177
+ if (argv.length !== 2 || (argv[1] !== "native" && argv[1] !== "projection")) {
178
+ process.stderr.write("gjc doctor: invalid internal probe invocation\n");
179
+ process.exitCode = 2;
180
+ return;
181
+ }
182
+ try {
183
+ const { runDoctorProbe } = await import("./cli/doctor/probe");
184
+ await runDoctorProbe(argv[1]);
185
+ } catch {
186
+ process.stderr.write("gjc doctor: internal probe unavailable\n");
187
+ process.exitCode = 3;
188
+ }
189
+ return;
190
+ }
191
+ if (isDoctorArgv(argv)) {
192
+ await runDoctor(argv);
193
+ return;
194
+ }
195
+ const { runCliAfterAdmission } = await import("./cli-main");
196
+ await runCliAfterAdmission(argv);
197
+ }
package/src/cli.ts CHANGED
@@ -1,26 +1,20 @@
1
1
  #!/usr/bin/env bun
2
2
 
3
- import type { CommandEntry } from "@gajae-code/utils/cli";
4
- /** Lightweight CLI bootstrap. Heavy command registration is loaded only after
5
- * security admission; `gjc doctor` stays reachable when normal startup breaks. */
6
- import { APP_NAME, formatBunRuntimeError, MIN_BUN_VERSION, VERSION } from "@gajae-code/utils/dirs";
7
- import { startTiming } from "@gajae-code/utils/logger";
8
- import {
9
- BASH_SHELL_RUNTIME_ARG,
10
- BASH_SHELL_SUPERVISOR_ARG,
11
- BASH_SHELL_WORKER_ARG,
12
- } from "./exec/bash-shell-worker-protocol";
13
- import { runSdkStderrDrainerFromArgv } from "./sdk/broker/stderr-drainer";
14
-
15
- const MANAGED_OWNER_SUPERVISOR_ARG = "--internal-managed-owner-supervisor";
16
- const MANAGED_OWNER_CHILD_TOKEN_ENV = "GJC_MANAGED_OWNER_CHILD_TOKEN";
17
- const TMUX_OWNER_ISOLATION_ARG = "--internal-tmux-owner-isolation";
18
-
19
- // Anchor startup timing before the heavy CLI module graph is loaded so the
20
- // printed tree includes runtime/bootstrap costs as well as dispatch work.
21
- if (process.env.GJC_TIMING || process.env.PI_TIMING) {
22
- startTiming();
23
- }
3
+ /** Inert CLI entry.
4
+ *
5
+ * `bin/gjc.js` imports THIS module, so anything statically imported here runs
6
+ * before argv is inspected. Keep it to pure metadata: the read-only
7
+ * `sdk diagnostics` observation route must not be able to resolve directories,
8
+ * consult NSS for a missing/ambiguous HOME, load the native addon, install
9
+ * runtime globals, re-exec for malloc env vars, run managed-owner admission or
10
+ * recovery, or touch the error-evidence store. Everything effectful lives in
11
+ * `./cli-ordinary`, which is imported lazily for every other command with its
12
+ * original ordering and admission semantics. */
13
+
14
+ import { APP_NAME, formatBunRuntimeError, MIN_BUN_VERSION } from "@gajae-code/utils/cli-metadata";
15
+ import { commands } from "./cli-commands";
16
+
17
+ export { commands };
24
18
 
25
19
  if (Bun.semver.order(Bun.version, MIN_BUN_VERSION) < 0) {
26
20
  process.stderr.write(
@@ -30,175 +24,24 @@ if (Bun.semver.order(Bun.version, MIN_BUN_VERSION) < 0) {
30
24
  }
31
25
  process.title = APP_NAME;
32
26
 
33
- /** Public-family hooks kept available for private-worker tests without loading the full registry. */
34
- export const commands: CommandEntry[] = [
35
- { name: "sdk", load: () => import("./commands/sdk").then(module => module.default) },
36
- { name: "daemon", load: () => import("./commands/daemon").then(module => module.default) },
37
- ];
38
-
39
- async function installRuntimeGlobals(writeNoFileWarning?: (text: string) => void): Promise<void> {
40
- // fetch() deliberately stays on HTTP/1.1. Bun's HTTP/2 client (per-request
41
- // `protocol: "http2"`) wedges a pooled connection while uploading large
42
- // request bodies (~300KB): every later request on it waits forever for
43
- // response headers. Do not re-enable HTTP/2 without re-running that probe.
44
- const { warnIfMacOSNoFileLimitTooLow } = await import("./cli/nofile-limit");
45
- warnIfMacOSNoFileLimitTooLow({ writeStderr: writeNoFileWarning });
46
-
47
- // Secondary in-process scrub of the macOS malloc-stack-logging vars. The real
48
- // boundary is the darwin re-exec guard at the top of runCli(): Bun snapshots the
49
- // spawn-default environment at startup, so deleting these here does NOT clean the
50
- // env children inherit by default — it only tidies `process.env` for code that
51
- // reads it directly. Kept as belt-and-braces for the rare re-exec-unavailable
52
- // fallback; managed spawns already use filterProcessEnv and the native PTY lane
53
- // strips them independently.
54
- delete process.env.MallocStackLogging;
55
- delete process.env.MallocStackLoggingNoCompact;
56
- }
57
-
58
- async function dispatchPublicFamily(argv: string[]): Promise<void> {
59
- const family = argv[0];
60
- if (family !== "sdk" && family !== "daemon") return;
61
- const { dispatchPublicCommand } = await import("./cli/public-command-entry");
62
- const load = commands.find(entry => entry.name === family)!.load;
63
- await dispatchPublicCommand(argv.slice(1), {
64
- bin: APP_NAME,
65
- version: VERSION,
66
- command: family,
67
- load,
68
- setup: report => installRuntimeGlobals(text => report({ code: "macos_nofile_limit_low", successStderr: text })),
69
- });
70
- }
71
-
72
- function isDoctorArgv(argv: readonly string[]): boolean {
73
- return argv[0] === "doctor";
74
- }
75
-
76
- async function runDoctor(argv: string[]): Promise<void> {
77
- const { runDoctorCli } = await import("./cli/doctor-cli");
78
- await runDoctorCli(argv.slice(1));
79
- }
80
-
81
27
  /** Run the CLI with argv excluding process.argv prefix. */
82
28
  export async function runCli(argv: string[]): Promise<void> {
83
- if (argv.length === 1 && argv[0] === BASH_SHELL_WORKER_ARG) {
84
- const { runBashShellGuardian } = await import("./exec/bash-shell-guardian");
85
- await runBashShellGuardian();
86
- return;
87
- }
88
- if (argv.length === 1 && argv[0] === BASH_SHELL_SUPERVISOR_ARG) {
89
- const { runBashShellSupervisor } = await import("./exec/bash-shell-supervisor");
90
- await runBashShellSupervisor();
91
- return;
92
- }
93
- if (argv.length === 1 && argv[0] === BASH_SHELL_RUNTIME_ARG) {
94
- const { runBashShellWorker } = await import("./exec/bash-shell-worker");
95
- await runBashShellWorker();
96
- return;
97
- }
98
- if (
99
- process.platform === "darwin" &&
100
- process.env.GJC_MALLOC_ENV_REEXEC === undefined &&
101
- (process.env.MallocStackLogging !== undefined || process.env.MallocStackLoggingNoCompact !== undefined)
102
- ) {
103
- const { reexecWithScrubbedMallocEnv } = await import("./cli/malloc-env-guard");
104
- const code = await reexecWithScrubbedMallocEnv();
105
- if (code !== null) {
106
- process.exitCode = code;
107
- return;
108
- }
109
- }
110
- if (argv.length === 3 && argv[0] === "internal" && argv[1] === "memory-guard-native-smoke" && argv[2] === "--json") {
111
- const { runMemoryGuardNativeSmoke } = await import("./cli/native-smoke");
112
- await runMemoryGuardNativeSmoke();
113
- return;
114
- }
115
- if (argv.length === 1 && argv[0] === TMUX_OWNER_ISOLATION_ARG) {
116
- const { runTmuxOwnerIsolationCliFromStdin } = await import("./gjc-runtime/tmux-owner-isolation-cli");
117
- await runTmuxOwnerIsolationCliFromStdin();
118
- return;
119
- }
120
- if (argv.length === 1 && argv[0] === MANAGED_OWNER_SUPERVISOR_ARG) {
121
- const { runManagedOwnerSupervisor } = await import("./gjc-runtime/managed-owner-supervisor");
122
- await runManagedOwnerSupervisor();
123
- return;
124
- }
125
- if (process.env[MANAGED_OWNER_CHILD_TOKEN_ENV] !== undefined) {
126
- const { admitManagedOwnerBeforeCli, completeManagedOwnerRecovery } = await import(
127
- "./gjc-runtime/managed-owner-admission"
128
- );
129
- const admission = await admitManagedOwnerBeforeCli();
130
- if (admission.kind === "blocked") return;
131
- if (admission.kind === "recovery") {
132
- await completeManagedOwnerRecovery(admission.context);
133
- return;
134
- }
135
- }
136
- if (argv[0] === "sdk" && argv[1] === "stderr-drain-internal") {
137
- // Private lifecycle stderr drainer: must stay ahead of the public sdk family
138
- // dispatcher, which would otherwise reject the private argv as a usage error.
29
+ // Exact-token diagnostics selector, ahead of every effectful branch. A private
30
+ // worker marker AFTER this prefix is a diagnostics usage error, never a worker
31
+ // dispatch; a private marker BEFORE it is not a diagnostics invocation at all
32
+ // and keeps its ordinary admission below.
33
+ if (argv[0] === "sdk" && argv[1] === "diagnostics") {
139
34
  try {
140
- await runSdkStderrDrainerFromArgv(argv.slice(2));
35
+ const { runDiagnosticsCli } = await import("./sdk/cli/diagnostics-cli");
36
+ await runDiagnosticsCli(argv.slice(2));
141
37
  } catch {
142
- process.stderr.write("gjc sdk: invalid internal stderr drainer invocation\n");
38
+ process.stderr.write("gjc sdk diagnostics: observation unavailable\n");
143
39
  process.exitCode = 2;
144
40
  }
145
41
  return;
146
42
  }
147
- if (argv[0] === "sdk" || argv[0] === "daemon") {
148
- await dispatchPublicFamily(argv);
149
- return;
150
- }
151
- if (argv.length === 1 && argv[0] === "--supports-macos-community-app") {
152
- process.stdout.write("macos-community-app-offer\n");
153
- return;
154
- }
155
- if (argv.length === 1 && argv[0] === "--internal-macos-community-app-offer") {
156
- try {
157
- const { offerMacosCommunityApp } = await import("./cli/macos-community-app");
158
- await offerMacosCommunityApp({ log: message => process.stderr.write(`${message}\n`) });
159
- } catch {
160
- const { COMMUNITY_APP_REPOSITORY } = await import("./cli/macos-community-app");
161
- process.stderr.write(
162
- `Optional community app offer failed; GJC remains installed. https://github.com/${COMMUNITY_APP_REPOSITORY}\n`,
163
- );
164
- }
165
- return;
166
- }
167
- if (argv[0] === "--internal-doctor-worker") {
168
- // Non-forgeable route: reachable only with the exact per-spawn token env var
169
- // AND a non-TTY stdin (isRoutableDoctorWorkerInvocation), so a user's own
170
- // interactive terminal can never land on the worker's confirmation-refusal
171
- // path merely by passing this argv marker.
172
- const { isRoutableDoctorWorkerInvocation, runDoctorWorker } = await import("./cli/doctor-worker");
173
- if (argv.length !== 1 || !isRoutableDoctorWorkerInvocation(process.env, process.stdin.isTTY)) {
174
- process.stderr.write("gjc doctor: invalid internal worker invocation\n");
175
- process.exitCode = 2;
176
- return;
177
- }
178
- await runDoctorWorker();
179
- return;
180
- }
181
- if (argv[0] === "--internal-doctor-probe") {
182
- if (argv.length !== 2 || (argv[1] !== "native" && argv[1] !== "projection")) {
183
- process.stderr.write("gjc doctor: invalid internal probe invocation\n");
184
- process.exitCode = 2;
185
- return;
186
- }
187
- try {
188
- const { runDoctorProbe } = await import("./cli/doctor/probe");
189
- await runDoctorProbe(argv[1]);
190
- } catch {
191
- process.stderr.write("gjc doctor: internal probe unavailable\n");
192
- process.exitCode = 3;
193
- }
194
- return;
195
- }
196
- if (isDoctorArgv(argv)) {
197
- await runDoctor(argv);
198
- return;
199
- }
200
- const { runCliAfterAdmission } = await import("./cli-main");
201
- await runCliAfterAdmission(argv);
43
+ const { runOrdinaryCli } = await import("./cli-ordinary");
44
+ await runOrdinaryCli(argv);
202
45
  }
203
46
 
204
47
  if (import.meta.main) await runCli(process.argv.slice(2));
@@ -9,12 +9,11 @@ export default class ContributionPrep extends Command {
9
9
  static strict = false;
10
10
 
11
11
  static flags = {
12
- "no-spawn": Flags.boolean({ description: "Only write artifacts; do not spawn a fresh GJC worker" }),
13
12
  "source-session-id": Flags.string({ description: "Source session id to record in the manifest" }),
14
13
  "artifact-root": Flags.string({ description: "Directory where contribute-pr artifacts are written" }),
15
14
  };
16
15
 
17
- static examples = ["gjc contribute-pr", "gjc contribute-pr --no-spawn"];
16
+ static examples = ["gjc contribute-pr"];
18
17
 
19
18
  async run(): Promise<void> {
20
19
  const { flags } = await this.parse(ContributionPrep);
@@ -27,7 +26,6 @@ export default class ContributionPrep extends Command {
27
26
  messages: [],
28
27
  },
29
28
  {
30
- spawnWorker: !flags["no-spawn"],
31
29
  artifactRoot: flags["artifact-root"],
32
30
  },
33
31
  );