@gajae-code/coding-agent 0.18.1 → 0.18.6
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.
- package/CHANGELOG.md +161 -0
- package/dist/types/cli/stats-cli.d.ts +0 -5
- package/dist/types/cli-commands.d.ts +10 -0
- package/dist/types/cli-ordinary.d.ts +13 -0
- package/dist/types/cli.d.ts +12 -3
- package/dist/types/commands/contribution-prep.d.ts +0 -3
- package/dist/types/commands/sdk.d.ts +3 -0
- package/dist/types/commands/update.d.ts +1 -0
- package/dist/types/config/autorouting-tier-map.d.ts +29 -2
- package/dist/types/config/model-profile-activation.d.ts +19 -0
- package/dist/types/config/model-registry.d.ts +16 -1
- package/dist/types/coordinator-mcp/session-reaper.d.ts +5 -0
- package/dist/types/edit/modes/replace.d.ts +3 -3
- package/dist/types/edit/streaming.d.ts +2 -2
- package/dist/types/exa/mcp-client.d.ts +1 -5
- package/dist/types/exec/bash-shell-guardian.d.ts +26 -0
- package/dist/types/exec/bash-shell-supervisor.d.ts +12 -0
- package/dist/types/hashline/parser.d.ts +28 -5
- package/dist/types/modes/acp/acp-agent.d.ts +6 -1
- package/dist/types/sdk/broker/discovery.d.ts +8 -0
- package/dist/types/sdk/broker/ensure.d.ts +1 -0
- package/dist/types/sdk/broker/lifecycle-ledger.d.ts +4 -0
- package/dist/types/sdk/broker/lifecycle.d.ts +6 -1
- package/dist/types/sdk/broker/recovery-backoff.d.ts +62 -0
- package/dist/types/sdk/broker/runtime.d.ts +21 -1
- package/dist/types/sdk/broker/startup-budget.d.ts +5 -1
- package/dist/types/sdk/bus/index.d.ts +1 -0
- package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +1 -1
- package/dist/types/sdk/bus/telegram-daemon.d.ts +1 -0
- package/dist/types/sdk/cli/diagnostics-cli.d.ts +18 -0
- package/dist/types/sdk/diagnostics/observe-broker.d.ts +185 -0
- package/dist/types/sdk/host/control/operations.d.ts +1 -1
- package/dist/types/sdk/host/session-runtime.d.ts +7 -0
- package/dist/types/sdk/index.d.ts +1 -0
- package/dist/types/sdk/prompt-watchdog.d.ts +1 -1
- package/dist/types/sdk/router/session-router.d.ts +2 -0
- package/dist/types/sdk/session.d.ts +13 -0
- package/dist/types/session/agent-session.d.ts +5 -1
- package/dist/types/tools/ask-contract.d.ts +75 -254
- package/dist/types/tools/bash.d.ts +1 -0
- package/package.json +7 -7
- package/scripts/build-sdk-package-smoke.ts +5 -0
- package/src/cli/public-command-entry.ts +5 -0
- package/src/cli/ssh-cli.ts +6 -3
- package/src/cli/stats-cli.ts +4 -36
- package/src/cli/web-search-cli.ts +9 -3
- package/src/cli-commands.ts +14 -0
- package/src/cli-main.ts +4 -8
- package/src/cli-ordinary.ts +197 -0
- package/src/cli.ts +25 -186
- package/src/commands/commit.ts +2 -2
- package/src/commands/contribution-prep.ts +1 -3
- package/src/commands/sdk.ts +60 -2
- package/src/commands/update.ts +15 -1
- package/src/config/autorouting-tier-map.ts +20 -2
- package/src/config/file-lock.ts +91 -2
- package/src/config/model-preset-registry.ts +17 -2
- package/src/config/model-profile-activation.ts +73 -5
- package/src/config/model-profile-contract.ts +4 -1
- package/src/config/model-profiles.ts +29 -29
- package/src/config/model-registry.ts +45 -17
- package/src/config/model-resolver.ts +9 -1
- package/src/coordinator-mcp/event-webhook.ts +19 -14
- package/src/coordinator-mcp/policy.ts +14 -4
- package/src/coordinator-mcp/server.ts +142 -7
- package/src/coordinator-mcp/session-reaper.ts +9 -1
- package/src/defaults/gjc/skills/deep-interview/SKILL.md +1 -1
- package/src/edit/modes/replace.ts +6 -6
- package/src/edit/streaming.ts +15 -15
- package/src/exa/mcp-client.ts +41 -8
- package/src/exec/bash-shell-guardian.ts +184 -34
- package/src/exec/bash-shell-supervisor.ts +60 -3
- package/src/hashline/execute.ts +51 -3
- package/src/hashline/parser.ts +63 -16
- package/src/internal-urls/docs-index.generated.ts +29 -28
- package/src/memories/index.ts +8 -2
- package/src/modes/acp/acp-agent.ts +688 -371
- package/src/modes/components/tool-execution.ts +1 -1
- package/src/modes/controllers/ssh-command-controller.ts +3 -1
- package/src/prompts/tools/ask.md +2 -0
- package/src/sdk/broker/broker.ts +46 -0
- package/src/sdk/broker/daemon-entry.ts +67 -6
- package/src/sdk/broker/discovery.ts +8 -0
- package/src/sdk/broker/ensure.ts +156 -20
- package/src/sdk/broker/lifecycle-ledger.ts +110 -12
- package/src/sdk/broker/lifecycle.ts +108 -34
- package/src/sdk/broker/recovery-backoff.ts +135 -0
- package/src/sdk/broker/runtime.ts +88 -1
- package/src/sdk/broker/startup-budget.ts +6 -1
- package/src/sdk/broker/transport.ts +5 -1
- package/src/sdk/bus/chat-daemon-control.ts +2 -2
- package/src/sdk/bus/index.ts +305 -19
- package/src/sdk/bus/telegram-daemon-contract.ts +1 -1
- package/src/sdk/bus/telegram-daemon-control.ts +15 -12
- package/src/sdk/bus/telegram-daemon.ts +34 -1
- package/src/sdk/cli/diagnostics-cli.ts +247 -0
- package/src/sdk/diagnostics/observe-broker.ts +654 -0
- package/src/sdk/host/control/dispatch.ts +52 -4
- package/src/sdk/host/control/operations.ts +1 -1
- package/src/sdk/host/session-runtime.test.ts +40 -2
- package/src/sdk/host/session-runtime.ts +112 -8
- package/src/sdk/index.ts +1 -0
- package/src/sdk/lifecycle-session.ts +1 -0
- package/src/sdk/prompt-watchdog.ts +17 -4
- package/src/sdk/protocol/operation-registry.ts +1 -1
- package/src/sdk/router/session-router.ts +7 -1
- package/src/sdk/session.ts +37 -8
- package/src/session/agent-session.ts +128 -41
- package/src/session/blob-store.ts +78 -33
- package/src/session/internal/managed-session-storage.ts +119 -3
- package/src/setup/hermes/templates/operator-instructions.v1.md +19 -1
- package/src/setup/hermes-setup.ts +4 -1
- package/src/slash-commands/builtin-registry.ts +8 -5
- package/src/tools/ask-contract.test.ts +76 -1
- package/src/tools/ask-contract.ts +57 -6
- package/src/tools/ask.ts +16 -7
- package/src/tools/bash.ts +77 -29
- package/src/tools/descriptors.test.ts +29 -0
- package/src/tools/tool-catalog.generated.ts +7 -4
- package/src/web/search/index.ts +2 -2
- package/dist/types/cli/grep-cli.d.ts +0 -17
- package/dist/types/cli/shell-cli.d.ts +0 -8
- package/dist/types/commands/grep.d.ts +0 -42
- package/dist/types/commands/shell.d.ts +0 -21
- package/src/cli/grep-cli.ts +0 -160
- package/src/cli/shell-cli.ts +0 -176
- package/src/commands/grep.ts +0 -48
- package/src/commands/shell.ts +0 -29
|
@@ -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
|
-
|
|
4
|
-
|
|
5
|
-
*
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
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,179 +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
|
-
const { installH2Fetch } = await import("@gajae-code/ai/utils/h2-fetch");
|
|
41
|
-
// Activate HTTP/2 for all `fetch()` calls (provider streams, OAuth, model
|
|
42
|
-
// discovery, web tools). Bun's HTTP/2 client is gated on a startup flag we
|
|
43
|
-
// can't toggle from JS, so we patch globalThis.fetch to pass
|
|
44
|
-
// `protocol: "http2"` per request, with transparent HTTP/1.1 fallback on
|
|
45
|
-
// `HTTP2Unsupported`. See @gajae-code/ai/utils/h2-fetch for details.
|
|
46
|
-
installH2Fetch();
|
|
47
|
-
|
|
48
|
-
const { warnIfMacOSNoFileLimitTooLow } = await import("./cli/nofile-limit");
|
|
49
|
-
warnIfMacOSNoFileLimitTooLow({ writeStderr: writeNoFileWarning });
|
|
50
|
-
|
|
51
|
-
// Secondary in-process scrub of the macOS malloc-stack-logging vars. The real
|
|
52
|
-
// boundary is the darwin re-exec guard at the top of runCli(): Bun snapshots the
|
|
53
|
-
// spawn-default environment at startup, so deleting these here does NOT clean the
|
|
54
|
-
// env children inherit by default — it only tidies `process.env` for code that
|
|
55
|
-
// reads it directly. Kept as belt-and-braces for the rare re-exec-unavailable
|
|
56
|
-
// fallback; managed spawns already use filterProcessEnv and the native PTY lane
|
|
57
|
-
// strips them independently.
|
|
58
|
-
delete process.env.MallocStackLogging;
|
|
59
|
-
delete process.env.MallocStackLoggingNoCompact;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
async function dispatchPublicFamily(argv: string[]): Promise<void> {
|
|
63
|
-
const family = argv[0];
|
|
64
|
-
if (family !== "sdk" && family !== "daemon") return;
|
|
65
|
-
const { dispatchPublicCommand } = await import("./cli/public-command-entry");
|
|
66
|
-
const load = commands.find(entry => entry.name === family)!.load;
|
|
67
|
-
await dispatchPublicCommand(argv.slice(1), {
|
|
68
|
-
bin: APP_NAME,
|
|
69
|
-
version: VERSION,
|
|
70
|
-
command: family,
|
|
71
|
-
load,
|
|
72
|
-
setup: report => installRuntimeGlobals(text => report({ code: "macos_nofile_limit_low", successStderr: text })),
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
function isDoctorArgv(argv: readonly string[]): boolean {
|
|
77
|
-
return argv[0] === "doctor";
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
async function runDoctor(argv: string[]): Promise<void> {
|
|
81
|
-
const { runDoctorCli } = await import("./cli/doctor-cli");
|
|
82
|
-
await runDoctorCli(argv.slice(1));
|
|
83
|
-
}
|
|
84
|
-
|
|
85
27
|
/** Run the CLI with argv excluding process.argv prefix. */
|
|
86
28
|
export async function runCli(argv: string[]): Promise<void> {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
if (argv.length === 1 && argv[0] === BASH_SHELL_SUPERVISOR_ARG) {
|
|
93
|
-
const { runBashShellSupervisor } = await import("./exec/bash-shell-supervisor");
|
|
94
|
-
await runBashShellSupervisor();
|
|
95
|
-
return;
|
|
96
|
-
}
|
|
97
|
-
if (argv.length === 1 && argv[0] === BASH_SHELL_RUNTIME_ARG) {
|
|
98
|
-
const { runBashShellWorker } = await import("./exec/bash-shell-worker");
|
|
99
|
-
await runBashShellWorker();
|
|
100
|
-
return;
|
|
101
|
-
}
|
|
102
|
-
if (
|
|
103
|
-
process.platform === "darwin" &&
|
|
104
|
-
process.env.GJC_MALLOC_ENV_REEXEC === undefined &&
|
|
105
|
-
(process.env.MallocStackLogging !== undefined || process.env.MallocStackLoggingNoCompact !== undefined)
|
|
106
|
-
) {
|
|
107
|
-
const { reexecWithScrubbedMallocEnv } = await import("./cli/malloc-env-guard");
|
|
108
|
-
const code = await reexecWithScrubbedMallocEnv();
|
|
109
|
-
if (code !== null) {
|
|
110
|
-
process.exitCode = code;
|
|
111
|
-
return;
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
if (argv.length === 3 && argv[0] === "internal" && argv[1] === "memory-guard-native-smoke" && argv[2] === "--json") {
|
|
115
|
-
const { runMemoryGuardNativeSmoke } = await import("./cli/native-smoke");
|
|
116
|
-
await runMemoryGuardNativeSmoke();
|
|
117
|
-
return;
|
|
118
|
-
}
|
|
119
|
-
if (argv.length === 1 && argv[0] === TMUX_OWNER_ISOLATION_ARG) {
|
|
120
|
-
const { runTmuxOwnerIsolationCliFromStdin } = await import("./gjc-runtime/tmux-owner-isolation-cli");
|
|
121
|
-
await runTmuxOwnerIsolationCliFromStdin();
|
|
122
|
-
return;
|
|
123
|
-
}
|
|
124
|
-
if (argv.length === 1 && argv[0] === MANAGED_OWNER_SUPERVISOR_ARG) {
|
|
125
|
-
const { runManagedOwnerSupervisor } = await import("./gjc-runtime/managed-owner-supervisor");
|
|
126
|
-
await runManagedOwnerSupervisor();
|
|
127
|
-
return;
|
|
128
|
-
}
|
|
129
|
-
if (process.env[MANAGED_OWNER_CHILD_TOKEN_ENV] !== undefined) {
|
|
130
|
-
const { admitManagedOwnerBeforeCli, completeManagedOwnerRecovery } = await import(
|
|
131
|
-
"./gjc-runtime/managed-owner-admission"
|
|
132
|
-
);
|
|
133
|
-
const admission = await admitManagedOwnerBeforeCli();
|
|
134
|
-
if (admission.kind === "blocked") return;
|
|
135
|
-
if (admission.kind === "recovery") {
|
|
136
|
-
await completeManagedOwnerRecovery(admission.context);
|
|
137
|
-
return;
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
if (argv[0] === "sdk" && argv[1] === "stderr-drain-internal") {
|
|
141
|
-
// Private lifecycle stderr drainer: must stay ahead of the public sdk family
|
|
142
|
-
// dispatcher, which would otherwise reject the private argv as a usage error.
|
|
143
|
-
try {
|
|
144
|
-
await runSdkStderrDrainerFromArgv(argv.slice(2));
|
|
145
|
-
} catch {
|
|
146
|
-
process.stderr.write("gjc sdk: invalid internal stderr drainer invocation\n");
|
|
147
|
-
process.exitCode = 2;
|
|
148
|
-
}
|
|
149
|
-
return;
|
|
150
|
-
}
|
|
151
|
-
if (argv[0] === "sdk" || argv[0] === "daemon") {
|
|
152
|
-
await dispatchPublicFamily(argv);
|
|
153
|
-
return;
|
|
154
|
-
}
|
|
155
|
-
if (argv.length === 1 && argv[0] === "--supports-macos-community-app") {
|
|
156
|
-
process.stdout.write("macos-community-app-offer\n");
|
|
157
|
-
return;
|
|
158
|
-
}
|
|
159
|
-
if (argv.length === 1 && argv[0] === "--internal-macos-community-app-offer") {
|
|
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") {
|
|
160
34
|
try {
|
|
161
|
-
const {
|
|
162
|
-
await
|
|
35
|
+
const { runDiagnosticsCli } = await import("./sdk/cli/diagnostics-cli");
|
|
36
|
+
await runDiagnosticsCli(argv.slice(2));
|
|
163
37
|
} catch {
|
|
164
|
-
|
|
165
|
-
process.stderr.write(
|
|
166
|
-
`Optional community app offer failed; GJC remains installed. https://github.com/${COMMUNITY_APP_REPOSITORY}\n`,
|
|
167
|
-
);
|
|
168
|
-
}
|
|
169
|
-
return;
|
|
170
|
-
}
|
|
171
|
-
if (argv[0] === "--internal-doctor-worker") {
|
|
172
|
-
// Non-forgeable route: reachable only with the exact per-spawn token env var
|
|
173
|
-
// AND a non-TTY stdin (isRoutableDoctorWorkerInvocation), so a user's own
|
|
174
|
-
// interactive terminal can never land on the worker's confirmation-refusal
|
|
175
|
-
// path merely by passing this argv marker.
|
|
176
|
-
const { isRoutableDoctorWorkerInvocation, runDoctorWorker } = await import("./cli/doctor-worker");
|
|
177
|
-
if (argv.length !== 1 || !isRoutableDoctorWorkerInvocation(process.env, process.stdin.isTTY)) {
|
|
178
|
-
process.stderr.write("gjc doctor: invalid internal worker invocation\n");
|
|
38
|
+
process.stderr.write("gjc sdk diagnostics: observation unavailable\n");
|
|
179
39
|
process.exitCode = 2;
|
|
180
|
-
return;
|
|
181
40
|
}
|
|
182
|
-
await runDoctorWorker();
|
|
183
|
-
return;
|
|
184
|
-
}
|
|
185
|
-
if (argv[0] === "--internal-doctor-probe") {
|
|
186
|
-
if (argv.length !== 2 || (argv[1] !== "native" && argv[1] !== "projection")) {
|
|
187
|
-
process.stderr.write("gjc doctor: invalid internal probe invocation\n");
|
|
188
|
-
process.exitCode = 2;
|
|
189
|
-
return;
|
|
190
|
-
}
|
|
191
|
-
try {
|
|
192
|
-
const { runDoctorProbe } = await import("./cli/doctor/probe");
|
|
193
|
-
await runDoctorProbe(argv[1]);
|
|
194
|
-
} catch {
|
|
195
|
-
process.stderr.write("gjc doctor: internal probe unavailable\n");
|
|
196
|
-
process.exitCode = 3;
|
|
197
|
-
}
|
|
198
|
-
return;
|
|
199
|
-
}
|
|
200
|
-
if (isDoctorArgv(argv)) {
|
|
201
|
-
await runDoctor(argv);
|
|
202
41
|
return;
|
|
203
42
|
}
|
|
204
|
-
const {
|
|
205
|
-
await
|
|
43
|
+
const { runOrdinaryCli } = await import("./cli-ordinary");
|
|
44
|
+
await runOrdinaryCli(argv);
|
|
206
45
|
}
|
|
207
46
|
|
|
208
47
|
if (import.meta.main) await runCli(process.argv.slice(2));
|
package/src/commands/commit.ts
CHANGED
|
@@ -32,8 +32,8 @@ export default class Commit extends Command {
|
|
|
32
32
|
};
|
|
33
33
|
|
|
34
34
|
await initTheme();
|
|
35
|
-
// The agentic commit flow opens
|
|
36
|
-
// provider
|
|
35
|
+
// The agentic commit flow opens keep-alive sockets to the model
|
|
36
|
+
// provider and spins up an AgentSession with
|
|
37
37
|
// background async-job + extension machinery. `session.dispose()` releases
|
|
38
38
|
// what it can, but Bun's fetch keeps idle connections warm and a few
|
|
39
39
|
// timers (Settings autosave, OAuth refresh) stay armed long enough to
|
|
@@ -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"
|
|
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
|
);
|
package/src/commands/sdk.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type ChildProcess, spawn } from "node:child_process";
|
|
1
2
|
import { createHash } from "node:crypto";
|
|
2
3
|
import * as nodeFs from "node:fs";
|
|
3
4
|
import * as fs from "node:fs/promises";
|
|
@@ -42,6 +43,7 @@ import {
|
|
|
42
43
|
writeSessionLifecycleReady,
|
|
43
44
|
} from "../sdk/broker/lifecycle";
|
|
44
45
|
import { processIncarnation } from "../sdk/broker/process-incarnation";
|
|
46
|
+
import { resolveSdkInternalSpawnCommand } from "../sdk/broker/runtime";
|
|
45
47
|
import { writeBrokerStartupFailureMarker } from "../sdk/broker/startup-failure";
|
|
46
48
|
import { runSdkStderrDrainer } from "../sdk/broker/stderr-drainer";
|
|
47
49
|
import { renderSdkSearchTable, runSdkSearch, runSdkSessionCli } from "../sdk/cli";
|
|
@@ -642,8 +644,7 @@ export async function runSessionHost(
|
|
|
642
644
|
},
|
|
643
645
|
absent.result,
|
|
644
646
|
);
|
|
645
|
-
|
|
646
|
-
throw new Error("SDK startup did not complete before readiness cutoff.");
|
|
647
|
+
return;
|
|
647
648
|
}
|
|
648
649
|
|
|
649
650
|
const rollback = new SdkStartupRollbackTracker();
|
|
@@ -1442,6 +1443,7 @@ export async function runSessionHost(
|
|
|
1442
1443
|
|
|
1443
1444
|
export type SdkInternalArgv =
|
|
1444
1445
|
| { action: "broker-internal"; agentDir: string }
|
|
1446
|
+
| { action: "broker-trampoline-internal"; agentDir: string }
|
|
1445
1447
|
| { action: "session-host-internal" }
|
|
1446
1448
|
| { action: "stderr-drain-internal"; logPath: string; maxBytes: number };
|
|
1447
1449
|
|
|
@@ -1456,6 +1458,14 @@ export function parseSdkInternalArgv(argv: readonly string[]): SdkInternalArgv {
|
|
|
1456
1458
|
isSafeSdkInternalAgentDir(argv[2])
|
|
1457
1459
|
)
|
|
1458
1460
|
return { action: "broker-internal", agentDir: argv[2] };
|
|
1461
|
+
if (
|
|
1462
|
+
argv[0] === "broker-trampoline-internal" &&
|
|
1463
|
+
argv.length === 3 &&
|
|
1464
|
+
argv[1] === "--agent-dir" &&
|
|
1465
|
+
typeof argv[2] === "string" &&
|
|
1466
|
+
isSafeSdkInternalAgentDir(argv[2])
|
|
1467
|
+
)
|
|
1468
|
+
return { action: "broker-trampoline-internal", agentDir: argv[2] };
|
|
1459
1469
|
if (
|
|
1460
1470
|
argv[0] === "stderr-drain-internal" &&
|
|
1461
1471
|
argv.length === 5 &&
|
|
@@ -1495,6 +1505,7 @@ export default class Sdk extends Command {
|
|
|
1495
1505
|
async run(): Promise<void> {
|
|
1496
1506
|
if (
|
|
1497
1507
|
this.argv[0] !== "broker-internal" &&
|
|
1508
|
+
this.argv[0] !== "broker-trampoline-internal" &&
|
|
1498
1509
|
this.argv[0] !== "session-host-internal" &&
|
|
1499
1510
|
this.argv[0] !== "stderr-drain-internal"
|
|
1500
1511
|
) {
|
|
@@ -1597,6 +1608,53 @@ export default class Sdk extends Command {
|
|
|
1597
1608
|
}
|
|
1598
1609
|
|
|
1599
1610
|
const internal = parseSdkInternalArgv(this.argv);
|
|
1611
|
+
if (internal.action === "broker-trampoline-internal") {
|
|
1612
|
+
if (process.platform === "win32") throw new CliParseError("Broker trampoline is unavailable on Windows.");
|
|
1613
|
+
const command = resolveSdkInternalSpawnCommand("broker-internal");
|
|
1614
|
+
let child: ChildProcess;
|
|
1615
|
+
try {
|
|
1616
|
+
child = spawn(command.file, [...command.args, "--agent-dir", internal.agentDir], {
|
|
1617
|
+
detached: true,
|
|
1618
|
+
stdio: ["ignore", "ignore", "inherit"],
|
|
1619
|
+
env: command.env,
|
|
1620
|
+
...(command.kind === "bun-source" ? { cwd: command.cwd } : {}),
|
|
1621
|
+
});
|
|
1622
|
+
} catch (error) {
|
|
1623
|
+
throw new Error("Broker trampoline could not start broker.", { cause: error });
|
|
1624
|
+
}
|
|
1625
|
+
let spawnError: Error | undefined;
|
|
1626
|
+
child.once("error", error => {
|
|
1627
|
+
spawnError = error;
|
|
1628
|
+
});
|
|
1629
|
+
if (child.pid === undefined) throw new Error("Broker trampoline could not start broker.");
|
|
1630
|
+
const incarnation = processIncarnation(child.pid);
|
|
1631
|
+
if (!incarnation) {
|
|
1632
|
+
try {
|
|
1633
|
+
child.kill("SIGKILL");
|
|
1634
|
+
} catch {
|
|
1635
|
+
// The child may already have exited; either way identity was not established.
|
|
1636
|
+
}
|
|
1637
|
+
throw new Error("Broker trampoline could not observe broker identity.");
|
|
1638
|
+
}
|
|
1639
|
+
if (spawnError) throw new Error("Broker trampoline could not start broker.", { cause: spawnError });
|
|
1640
|
+
const stdoutWrite = Promise.withResolvers<void>();
|
|
1641
|
+
process.stdout.write(`${child.pid}\t${incarnation}\n`, error => {
|
|
1642
|
+
if (error) stdoutWrite.reject(error);
|
|
1643
|
+
else stdoutWrite.resolve();
|
|
1644
|
+
});
|
|
1645
|
+
try {
|
|
1646
|
+
await stdoutWrite.promise;
|
|
1647
|
+
} catch (error) {
|
|
1648
|
+
try {
|
|
1649
|
+
child.kill("SIGKILL");
|
|
1650
|
+
} catch {
|
|
1651
|
+
// The child may already have exited; reporting failure remains authoritative.
|
|
1652
|
+
}
|
|
1653
|
+
throw error;
|
|
1654
|
+
}
|
|
1655
|
+
child.unref();
|
|
1656
|
+
return;
|
|
1657
|
+
}
|
|
1600
1658
|
if (internal.action === "broker-internal") usePostmortemSignalExitAuthority();
|
|
1601
1659
|
if (internal.action === "session-host-internal") {
|
|
1602
1660
|
await runSessionHost();
|
package/src/commands/update.ts
CHANGED
|
@@ -13,6 +13,20 @@ import {
|
|
|
13
13
|
} from "../config/update-channel";
|
|
14
14
|
import { initTheme } from "../modes/theme/theme";
|
|
15
15
|
|
|
16
|
+
export async function runUpdateRecoveryCommand(
|
|
17
|
+
recover: () => Promise<void> = () => runManagedNotifyRecovery({}),
|
|
18
|
+
): Promise<void> {
|
|
19
|
+
try {
|
|
20
|
+
await recover();
|
|
21
|
+
} catch (error) {
|
|
22
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
23
|
+
process.stderr.write(
|
|
24
|
+
`Post-update recovery failed: ${reason}. For each configured notification daemon (telegram, discord, or slack), manually run 'gjc daemon stop <kind> --force' and then 'gjc daemon reload <kind>', then run 'gjc notify recovery'.\n`,
|
|
25
|
+
);
|
|
26
|
+
process.exitCode = 1;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
16
30
|
export default class Update extends Command {
|
|
17
31
|
static description = "Check for and install updates";
|
|
18
32
|
|
|
@@ -35,7 +49,7 @@ export default class Update extends Command {
|
|
|
35
49
|
async run(): Promise<void> {
|
|
36
50
|
const { args, flags } = await this.parse(Update);
|
|
37
51
|
if (args.action === "update-recovery") {
|
|
38
|
-
await
|
|
52
|
+
await runUpdateRecoveryCommand();
|
|
39
53
|
return;
|
|
40
54
|
}
|
|
41
55
|
let channel: UpdateChannel | undefined;
|
|
@@ -45,8 +45,9 @@ export const TIER_MAP_VERSION = 1;
|
|
|
45
45
|
|
|
46
46
|
export const CURATED_TIER_LABELS = {
|
|
47
47
|
"anthropic/claude-haiku-4-5": [{ tier: "fast", rank: 1 }],
|
|
48
|
-
"anthropic/claude-sonnet-5": [{ tier: "balanced", rank: 1 }],
|
|
49
|
-
"anthropic/claude-sonnet-
|
|
48
|
+
"anthropic/claude-sonnet-5-5": [{ tier: "balanced", rank: 1 }],
|
|
49
|
+
"anthropic/claude-sonnet-5": [{ tier: "balanced", rank: 2 }],
|
|
50
|
+
"anthropic/claude-sonnet-4-6": [{ tier: "balanced", rank: 3 }],
|
|
50
51
|
"anthropic/claude-opus-5-5": [{ tier: "strong", effort: "high", rank: 1 }],
|
|
51
52
|
"anthropic/claude-opus-5": [{ tier: "strong", effort: "high", rank: 2 }],
|
|
52
53
|
"anthropic/claude-opus-4-8": [{ tier: "strong", effort: "high", rank: 3 }],
|
|
@@ -55,6 +56,7 @@ export const CURATED_TIER_LABELS = {
|
|
|
55
56
|
{ tier: "balanced", effort: "medium", rank: 1 },
|
|
56
57
|
],
|
|
57
58
|
"openai-codex/gpt-6-sol": [{ tier: "strong", effort: "high", rank: 1 }],
|
|
59
|
+
"openai-codex/gpt-6.1-sol": [{ tier: "strong", effort: "high", rank: 2 }],
|
|
58
60
|
"google/gemini-3.5-flash-lite": [{ tier: "fast", rank: 1 }],
|
|
59
61
|
"google/gemini-2.5-flash-lite": [{ tier: "fast", rank: 2 }],
|
|
60
62
|
"google/gemini-3.5-flash": [{ tier: "balanced", rank: 1 }],
|
|
@@ -75,6 +77,22 @@ export const CURATED_TIER_LABELS = {
|
|
|
75
77
|
|
|
76
78
|
/** Generated from packages/ai/src/models.json at feature land: 3936 in-scope baseline skips. */
|
|
77
79
|
export const TIER_MAP_SKIP_LIST = {
|
|
80
|
+
"amazon-bedrock/anthropic.claude-sonnet-5-5": { rationale: "Sonnet 5.5 catalog addition (#6111); not yet curated" },
|
|
81
|
+
"amazon-bedrock/au.anthropic.claude-sonnet-5-5": {
|
|
82
|
+
rationale: "Sonnet 5.5 catalog addition (#6111); not yet curated",
|
|
83
|
+
},
|
|
84
|
+
"amazon-bedrock/eu.anthropic.claude-sonnet-5-5": {
|
|
85
|
+
rationale: "Sonnet 5.5 catalog addition (#6111); not yet curated",
|
|
86
|
+
},
|
|
87
|
+
"amazon-bedrock/global.anthropic.claude-sonnet-5-5": {
|
|
88
|
+
rationale: "Sonnet 5.5 catalog addition (#6111); not yet curated",
|
|
89
|
+
},
|
|
90
|
+
"amazon-bedrock/jp.anthropic.claude-sonnet-5-5": {
|
|
91
|
+
rationale: "Sonnet 5.5 catalog addition (#6111); not yet curated",
|
|
92
|
+
},
|
|
93
|
+
"amazon-bedrock/us.anthropic.claude-sonnet-5-5": {
|
|
94
|
+
rationale: "Sonnet 5.5 catalog addition (#6111); not yet curated",
|
|
95
|
+
},
|
|
78
96
|
"kiro/claude-opus-5-5": { rationale: "post-rebase catalog addition from dev; not yet curated" },
|
|
79
97
|
"kiro/claude-opus-5.5": { rationale: "post-rebase catalog addition from dev; not yet curated" },
|
|
80
98
|
"alibaba-token-plan/qwen3.8-flash": { rationale: "post-rebase catalog addition from dev; not yet curated" },
|