theclawbay 0.3.25 → 0.3.26
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/README.md +4 -4
- package/dist/commands/setup.js +212 -133
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# theclawbay
|
|
2
2
|
|
|
3
|
-
CLI for connecting Codex
|
|
3
|
+
CLI for connecting Codex, OpenClaw, OpenCode, Kilo, and experimental Trae to The Claw Bay.
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
@@ -16,9 +16,9 @@ Get your API key from `https://theclawbay.com/dashboard`.
|
|
|
16
16
|
theclawbay setup --api-key <apiKey>
|
|
17
17
|
```
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
In an interactive terminal, setup shows one picker for Codex, OpenClaw, OpenCode, Kilo, and Windows Trae.
|
|
20
|
+
Detected integrations are preselected when recommended, undetected ones stay visible but cannot be selected,
|
|
21
|
+
and you can toggle items with arrow keys plus `Enter` or by pressing their number.
|
|
22
22
|
|
|
23
23
|
## Optional
|
|
24
24
|
|
package/dist/commands/setup.js
CHANGED
|
@@ -40,7 +40,7 @@ const SHELL_END = "# theclawbay-shell-managed:end";
|
|
|
40
40
|
const OPENCLAW_PROVIDER_ID = DEFAULT_PROVIDER_ID;
|
|
41
41
|
const HISTORY_PROVIDER_NEUTRALIZE_SOURCES = new Set(["openai", "theclawbay-wan", DEFAULT_PROVIDER_ID]);
|
|
42
42
|
const HISTORY_PROVIDER_DB_MIGRATE_SOURCES = ["openai", "theclawbay-wan"];
|
|
43
|
-
const
|
|
43
|
+
const SETUP_CLIENT_IDS = ["codex", "openclaw", "opencode", "kilo", "trae"];
|
|
44
44
|
const TRAE_PATCH_MARKER = "theclawbay-trae-patch";
|
|
45
45
|
const TRAE_BUNDLE_BACKUP_SUFFIX = ".theclawbay-managed-backup";
|
|
46
46
|
const TRAE_TARGET_FUNCTION_START = "async setOriginModelListMapAndCache(e,t=!0){";
|
|
@@ -175,7 +175,7 @@ function shellQuote(value) {
|
|
|
175
175
|
function modelDisplayName(modelId) {
|
|
176
176
|
return MODEL_DISPLAY_NAMES[modelId] ?? modelId;
|
|
177
177
|
}
|
|
178
|
-
function
|
|
178
|
+
function parseSetupClientFlags(raw) {
|
|
179
179
|
if (!raw)
|
|
180
180
|
return null;
|
|
181
181
|
const parts = raw
|
|
@@ -184,46 +184,51 @@ function parseOptionalClientFlags(raw) {
|
|
|
184
184
|
.filter(Boolean);
|
|
185
185
|
const selected = new Set();
|
|
186
186
|
for (const part of parts) {
|
|
187
|
-
if (part
|
|
188
|
-
continue;
|
|
189
|
-
if (OPTIONAL_SETUP_CLIENT_IDS.includes(part)) {
|
|
187
|
+
if (SETUP_CLIENT_IDS.includes(part)) {
|
|
190
188
|
selected.add(part);
|
|
191
189
|
continue;
|
|
192
190
|
}
|
|
193
|
-
throw new Error(`unknown client "${part}". Supported values:
|
|
191
|
+
throw new Error(`unknown client "${part}". Supported values: ${SETUP_CLIENT_IDS.join(", ")}.`);
|
|
194
192
|
}
|
|
195
193
|
return selected;
|
|
196
194
|
}
|
|
197
|
-
async function
|
|
198
|
-
const
|
|
199
|
-
|
|
200
|
-
if (detected.length === 0 || !process.stdin.isTTY || !process.stdout.isTTY) {
|
|
195
|
+
async function promptForSetupClients(clients) {
|
|
196
|
+
const selected = new Set(clients.filter((client) => client.detected && client.recommended).map((client) => client.id));
|
|
197
|
+
if (!process.stdin.isTTY || !process.stdout.isTTY) {
|
|
201
198
|
return selected;
|
|
202
199
|
}
|
|
203
|
-
const options =
|
|
200
|
+
const options = clients.map((client) => ({
|
|
204
201
|
...client,
|
|
205
|
-
checked: selected.has(client.id),
|
|
202
|
+
checked: client.detected && selected.has(client.id),
|
|
206
203
|
}));
|
|
207
204
|
return new Promise((resolve) => {
|
|
208
205
|
let cursor = 0;
|
|
209
206
|
let settled = false;
|
|
207
|
+
let hint = clients.some((client) => client.detected)
|
|
208
|
+
? "Detected integrations are preselected. Undetected ones stay visible but disabled."
|
|
209
|
+
: "No supported local clients are detected yet. Continue will just save your managed config and API key env.";
|
|
210
210
|
const stdin = process.stdin;
|
|
211
211
|
const stdout = process.stdout;
|
|
212
212
|
const wasRaw = stdin.isRaw;
|
|
213
|
+
const continueIndex = options.length;
|
|
213
214
|
const clearScreen = () => {
|
|
214
215
|
stdout.write("\x1b[2J\x1b[H");
|
|
215
216
|
};
|
|
217
|
+
const selectedCount = () => options.filter((option) => option.checked).length;
|
|
216
218
|
const render = () => {
|
|
217
219
|
clearScreen();
|
|
218
|
-
stdout.write("
|
|
219
|
-
stdout.write(
|
|
220
|
+
stdout.write("Choose local clients to configure\n");
|
|
221
|
+
stdout.write(`Use ↑/↓ to move, Enter to toggle the highlighted integration, or press 1-${options.length} to toggle directly.\n`);
|
|
222
|
+
stdout.write("Move to Continue and press Enter when you're ready.\n\n");
|
|
220
223
|
for (const [index, option] of options.entries()) {
|
|
221
224
|
const pointer = index === cursor ? ">" : " ";
|
|
222
|
-
const mark = option.checked ? "[x]" : "[ ]";
|
|
223
|
-
const badge = option.recommended ? "recommended" : "optional";
|
|
224
|
-
stdout.write(`${pointer} ${mark} ${option.label} ${badge}\n`);
|
|
225
|
+
const mark = option.detected ? (option.checked ? "[x]" : "[ ]") : "[-]";
|
|
226
|
+
const badge = option.detected ? (option.recommended ? "recommended" : "optional") : "not detected";
|
|
227
|
+
stdout.write(`${pointer} ${index + 1}. ${mark} ${option.label} ${badge}\n`);
|
|
225
228
|
}
|
|
226
|
-
|
|
229
|
+
const continuePointer = cursor === continueIndex ? ">" : " ";
|
|
230
|
+
stdout.write(`${continuePointer} Continue with ${selectedCount()} selected integration${selectedCount() === 1 ? "" : "s"}\n`);
|
|
231
|
+
stdout.write(`\n${hint}\n`);
|
|
227
232
|
};
|
|
228
233
|
const finish = () => {
|
|
229
234
|
if (settled)
|
|
@@ -238,34 +243,66 @@ async function promptForOptionalClients(clients) {
|
|
|
238
243
|
const finalSelection = new Set(options.filter((option) => option.checked).map((option) => option.id));
|
|
239
244
|
resolve(finalSelection);
|
|
240
245
|
};
|
|
246
|
+
const toggleOption = (index) => {
|
|
247
|
+
const option = options[index];
|
|
248
|
+
if (!option)
|
|
249
|
+
return;
|
|
250
|
+
cursor = index;
|
|
251
|
+
if (!option.detected) {
|
|
252
|
+
hint = `${option.label} is not detected on this machine yet, so it cannot be selected.`;
|
|
253
|
+
render();
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
option.checked = !option.checked;
|
|
257
|
+
hint = `${option.label} ${option.checked ? "selected" : "cleared"}.`;
|
|
258
|
+
render();
|
|
259
|
+
};
|
|
241
260
|
const onKeypress = (_str, key) => {
|
|
242
261
|
if (key.ctrl && key.name === "c") {
|
|
243
262
|
stdout.write("\x1b[?25h");
|
|
244
263
|
process.exit(130);
|
|
245
264
|
}
|
|
246
265
|
if (key.name === "up" || key.name === "k") {
|
|
247
|
-
cursor = (cursor - 1 + options.length) % options.length;
|
|
266
|
+
cursor = (cursor - 1 + options.length + 1) % (options.length + 1);
|
|
248
267
|
render();
|
|
249
268
|
return;
|
|
250
269
|
}
|
|
251
270
|
if (key.name === "down" || key.name === "j") {
|
|
252
|
-
cursor = (cursor + 1) % options.length;
|
|
271
|
+
cursor = (cursor + 1) % (options.length + 1);
|
|
253
272
|
render();
|
|
254
273
|
return;
|
|
255
274
|
}
|
|
256
275
|
if (key.name === "space") {
|
|
257
|
-
|
|
258
|
-
|
|
276
|
+
if (cursor === continueIndex) {
|
|
277
|
+
finish();
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
toggleOption(cursor);
|
|
281
|
+
return;
|
|
282
|
+
}
|
|
283
|
+
const directSelection = Number.parseInt(key.sequence ?? "", 10);
|
|
284
|
+
if (Number.isInteger(directSelection) && directSelection >= 1 && directSelection <= options.length) {
|
|
285
|
+
toggleOption(directSelection - 1);
|
|
259
286
|
return;
|
|
260
287
|
}
|
|
261
288
|
if (key.name === "a") {
|
|
262
|
-
const
|
|
263
|
-
|
|
289
|
+
const detectedOptions = options.filter((option) => option.detected);
|
|
290
|
+
const nextValue = detectedOptions.some((option) => !option.checked);
|
|
291
|
+
for (const option of detectedOptions)
|
|
264
292
|
option.checked = nextValue;
|
|
293
|
+
hint = `${nextValue ? "Selected" : "Cleared"} all detected integrations.`;
|
|
265
294
|
render();
|
|
266
295
|
return;
|
|
267
296
|
}
|
|
268
297
|
if (key.name === "return" || key.name === "enter") {
|
|
298
|
+
if (cursor === continueIndex) {
|
|
299
|
+
finish();
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
toggleOption(cursor);
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
if (key.name === "c") {
|
|
269
306
|
finish();
|
|
270
307
|
}
|
|
271
308
|
};
|
|
@@ -277,10 +314,10 @@ async function promptForOptionalClients(clients) {
|
|
|
277
314
|
render();
|
|
278
315
|
});
|
|
279
316
|
}
|
|
280
|
-
function
|
|
281
|
-
const {
|
|
317
|
+
function resolveSetupClientSelection(params) {
|
|
318
|
+
const { setupClients, flagSelection, skipPrompt } = params;
|
|
282
319
|
if (flagSelection) {
|
|
283
|
-
for (const client of
|
|
320
|
+
for (const client of setupClients) {
|
|
284
321
|
if (!flagSelection.has(client.id))
|
|
285
322
|
continue;
|
|
286
323
|
if (!client.detected) {
|
|
@@ -289,10 +326,10 @@ function resolveOptionalClientSelection(params) {
|
|
|
289
326
|
}
|
|
290
327
|
return Promise.resolve(flagSelection);
|
|
291
328
|
}
|
|
292
|
-
const defaults = new Set(
|
|
329
|
+
const defaults = new Set(setupClients.filter((client) => client.detected && client.recommended).map((client) => client.id));
|
|
293
330
|
if (skipPrompt)
|
|
294
331
|
return Promise.resolve(defaults);
|
|
295
|
-
return
|
|
332
|
+
return promptForSetupClients(setupClients);
|
|
296
333
|
}
|
|
297
334
|
async function fetchBackendModelIds(backendUrl, apiKey) {
|
|
298
335
|
const url = `${trimTrailingSlash(backendUrl)}/api/codex-auth/v1/proxy/v1/models`;
|
|
@@ -334,6 +371,21 @@ function kiloStorageCandidates() {
|
|
|
334
371
|
}
|
|
335
372
|
return candidates;
|
|
336
373
|
}
|
|
374
|
+
async function detectCodexClient() {
|
|
375
|
+
if (hasCommand("codex"))
|
|
376
|
+
return true;
|
|
377
|
+
const candidates = [
|
|
378
|
+
node_path_1.default.join(paths_1.codexDir, "config.toml"),
|
|
379
|
+
node_path_1.default.join(paths_1.codexDir, "auth.json"),
|
|
380
|
+
node_path_1.default.join(paths_1.codexDir, "history.jsonl"),
|
|
381
|
+
node_path_1.default.join(paths_1.codexDir, "sessions"),
|
|
382
|
+
];
|
|
383
|
+
for (const candidate of candidates) {
|
|
384
|
+
if (await pathExists(candidate))
|
|
385
|
+
return true;
|
|
386
|
+
}
|
|
387
|
+
return false;
|
|
388
|
+
}
|
|
337
389
|
async function detectKiloClient() {
|
|
338
390
|
if (hasCommand("kilo"))
|
|
339
391
|
return true;
|
|
@@ -691,155 +743,184 @@ class SetupCommand extends base_command_1.BaseCommand {
|
|
|
691
743
|
throw new Error('API key is required. Run "theclawbay setup --api-key <key>".');
|
|
692
744
|
const backendRaw = flags.backend ?? (0, api_key_1.tryInferBackendUrlFromApiKey)(apiKey) ?? managed?.backendUrl ?? DEFAULT_BACKEND_URL;
|
|
693
745
|
const backendUrl = normalizeUrl(backendRaw, "--backend");
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
const
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
apiKey,
|
|
707
|
-
});
|
|
708
|
-
const stateDbMigration = await (0, codex_history_migration_1.migrateStateDbProviders)({
|
|
709
|
-
codexHome: paths_1.codexDir,
|
|
710
|
-
targetProvider: DEFAULT_PROVIDER_ID,
|
|
711
|
-
sourceProviders: HISTORY_PROVIDER_DB_MIGRATE_SOURCES,
|
|
712
|
-
});
|
|
713
|
-
const modelCacheMigration = await (0, codex_model_cache_migration_1.ensureCodexModelCacheHasGpt54)({
|
|
714
|
-
codexHome: paths_1.codexDir,
|
|
715
|
-
});
|
|
716
|
-
const optionalClients = [
|
|
746
|
+
const [codexDetected, kiloDetected, traeDetected] = await Promise.all([
|
|
747
|
+
detectCodexClient(),
|
|
748
|
+
detectKiloClient(),
|
|
749
|
+
detectTraeClient(),
|
|
750
|
+
]);
|
|
751
|
+
const setupClients = [
|
|
752
|
+
{
|
|
753
|
+
id: "codex",
|
|
754
|
+
label: "Codex CLI, VS Code extension, and Codex app",
|
|
755
|
+
detected: codexDetected,
|
|
756
|
+
recommended: true,
|
|
757
|
+
},
|
|
717
758
|
{
|
|
718
759
|
id: "openclaw",
|
|
719
760
|
label: "OpenClaw",
|
|
720
761
|
detected: hasCommand("openclaw"),
|
|
721
762
|
recommended: true,
|
|
722
|
-
command: "openclaw",
|
|
723
763
|
},
|
|
724
764
|
{
|
|
725
765
|
id: "opencode",
|
|
726
766
|
label: "OpenCode",
|
|
727
767
|
detected: hasCommand("opencode"),
|
|
728
768
|
recommended: true,
|
|
729
|
-
command: "opencode",
|
|
730
769
|
},
|
|
731
770
|
{
|
|
732
771
|
id: "kilo",
|
|
733
772
|
label: "Kilo Code",
|
|
734
|
-
detected:
|
|
773
|
+
detected: kiloDetected,
|
|
735
774
|
recommended: true,
|
|
736
|
-
command: "kilo",
|
|
737
775
|
},
|
|
738
776
|
{
|
|
739
777
|
id: "trae",
|
|
740
778
|
label: "Trae (experimental)",
|
|
741
|
-
detected:
|
|
779
|
+
detected: traeDetected,
|
|
742
780
|
recommended: false,
|
|
743
|
-
command: "Trae",
|
|
744
781
|
},
|
|
745
782
|
];
|
|
746
|
-
const
|
|
747
|
-
|
|
748
|
-
flagSelection:
|
|
783
|
+
const selectedSetupClients = await resolveSetupClientSelection({
|
|
784
|
+
setupClients,
|
|
785
|
+
flagSelection: parseSetupClientFlags(flags.clients),
|
|
749
786
|
skipPrompt: flags.yes,
|
|
750
787
|
});
|
|
788
|
+
let resolved = null;
|
|
789
|
+
if (selectedSetupClients.size > 0) {
|
|
790
|
+
resolved = await resolveModels(backendUrl, apiKey);
|
|
791
|
+
}
|
|
792
|
+
await (0, config_1.writeManagedConfig)({ backendUrl, apiKey });
|
|
793
|
+
const updatedShellFiles = await persistApiKeyEnv(apiKey);
|
|
794
|
+
let codexConfigPath = null;
|
|
795
|
+
let updatedVsCodeEnvFiles = [];
|
|
796
|
+
let sessionMigration = null;
|
|
797
|
+
let authSeed = null;
|
|
798
|
+
let stateDbMigration = null;
|
|
799
|
+
let modelCacheMigration = null;
|
|
751
800
|
let openClawConfigPath = null;
|
|
752
801
|
let openClawCliWarning = null;
|
|
753
802
|
let openCodePath = null;
|
|
754
803
|
let kiloConfigPath = null;
|
|
755
804
|
let traeBundlePathPatched = null;
|
|
756
|
-
if (
|
|
805
|
+
if (selectedSetupClients.has("codex")) {
|
|
806
|
+
codexConfigPath = await writeCodexConfig({ backendUrl, model: resolved?.model ?? DEFAULT_CODEX_MODEL, apiKey });
|
|
807
|
+
updatedVsCodeEnvFiles = await persistVsCodeServerEnvSource();
|
|
808
|
+
sessionMigration = await (0, codex_history_migration_1.migrateSessionProviders)({
|
|
809
|
+
codexHome: paths_1.codexDir,
|
|
810
|
+
migrationStateFile: MIGRATION_STATE_FILE,
|
|
811
|
+
neutralizeSources: HISTORY_PROVIDER_NEUTRALIZE_SOURCES,
|
|
812
|
+
});
|
|
813
|
+
authSeed = await (0, codex_auth_seeding_1.ensureCodexApiKeyAuth)({
|
|
814
|
+
codexHome: paths_1.codexDir,
|
|
815
|
+
apiKey,
|
|
816
|
+
});
|
|
817
|
+
stateDbMigration = await (0, codex_history_migration_1.migrateStateDbProviders)({
|
|
818
|
+
codexHome: paths_1.codexDir,
|
|
819
|
+
targetProvider: DEFAULT_PROVIDER_ID,
|
|
820
|
+
sourceProviders: HISTORY_PROVIDER_DB_MIGRATE_SOURCES,
|
|
821
|
+
});
|
|
822
|
+
modelCacheMigration = await (0, codex_model_cache_migration_1.ensureCodexModelCacheHasGpt54)({
|
|
823
|
+
codexHome: paths_1.codexDir,
|
|
824
|
+
});
|
|
825
|
+
}
|
|
826
|
+
if (selectedSetupClients.has("openclaw")) {
|
|
757
827
|
const openClawResult = await setupOpenClaw({
|
|
758
828
|
backendUrl,
|
|
759
|
-
model: resolved
|
|
760
|
-
models: resolved
|
|
829
|
+
model: resolved?.model ?? DEFAULT_CODEX_MODEL,
|
|
830
|
+
models: resolved?.models ?? [{ id: DEFAULT_CODEX_MODEL, name: modelDisplayName(DEFAULT_CODEX_MODEL) }],
|
|
761
831
|
apiKey,
|
|
762
832
|
});
|
|
763
833
|
openClawConfigPath = openClawResult.configPath;
|
|
764
834
|
openClawCliWarning = openClawResult.cliWarning ?? null;
|
|
765
835
|
}
|
|
766
|
-
if (
|
|
836
|
+
if (selectedSetupClients.has("opencode")) {
|
|
767
837
|
openCodePath = await writeOpenCodeConfig({
|
|
768
838
|
backendUrl,
|
|
769
|
-
model: resolved
|
|
770
|
-
models: resolved
|
|
839
|
+
model: resolved?.model ?? DEFAULT_CODEX_MODEL,
|
|
840
|
+
models: resolved?.models ?? [{ id: DEFAULT_CODEX_MODEL, name: modelDisplayName(DEFAULT_CODEX_MODEL) }],
|
|
771
841
|
apiKey,
|
|
772
842
|
});
|
|
773
843
|
}
|
|
774
|
-
if (
|
|
844
|
+
if (selectedSetupClients.has("kilo")) {
|
|
775
845
|
kiloConfigPath = await writeKiloConfig({
|
|
776
846
|
backendUrl,
|
|
777
|
-
model: resolved
|
|
778
|
-
models: resolved
|
|
847
|
+
model: resolved?.model ?? DEFAULT_CODEX_MODEL,
|
|
848
|
+
models: resolved?.models ?? [{ id: DEFAULT_CODEX_MODEL, name: modelDisplayName(DEFAULT_CODEX_MODEL) }],
|
|
779
849
|
apiKey,
|
|
780
850
|
});
|
|
781
851
|
}
|
|
782
|
-
if (
|
|
852
|
+
if (selectedSetupClients.has("trae")) {
|
|
783
853
|
traeBundlePathPatched = await patchTraeBundle({
|
|
784
854
|
backendUrl,
|
|
785
|
-
model: resolved
|
|
855
|
+
model: resolved?.model ?? DEFAULT_CODEX_MODEL,
|
|
786
856
|
apiKey,
|
|
787
|
-
models: resolved
|
|
857
|
+
models: resolved?.models ?? [{ id: DEFAULT_CODEX_MODEL, name: modelDisplayName(DEFAULT_CODEX_MODEL) }],
|
|
788
858
|
});
|
|
789
859
|
}
|
|
790
860
|
this.log("Setup complete");
|
|
791
861
|
this.log(`- Managed config: ${paths_1.managedConfigPath}`);
|
|
792
862
|
this.log(`- Backend: ${backendUrl}`);
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
this.log("- Recommended base setup: Codex CLI, Codex VS Code extension, and the Codex app");
|
|
796
|
-
if (resolved.note)
|
|
797
|
-
this.log(resolved.note);
|
|
798
|
-
if (sessionMigration.rewritten > 0) {
|
|
799
|
-
this.log(`- Conversations: updated ${sessionMigration.rewritten}/${sessionMigration.scanned} local sessions for cross-provider visibility.`);
|
|
800
|
-
}
|
|
801
|
-
else if (sessionMigration.fastSkipped) {
|
|
802
|
-
this.log("- Conversations: already migrated (fast check).");
|
|
803
|
-
}
|
|
804
|
-
else {
|
|
805
|
-
this.log("- Conversations: no local sessions required migration.");
|
|
806
|
-
}
|
|
807
|
-
if (sessionMigration.retimed > 0) {
|
|
808
|
-
this.log(`- Conversation ordering: repaired timestamps on ${sessionMigration.retimed} local sessions.`);
|
|
863
|
+
if (selectedSetupClients.size === 0) {
|
|
864
|
+
this.log("- Local clients: none selected; saved managed config and API key env only.");
|
|
809
865
|
}
|
|
810
|
-
if (
|
|
811
|
-
this.log(
|
|
812
|
-
}
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
this.log(`-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
this.log(
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
866
|
+
if (resolved?.note)
|
|
867
|
+
this.log(resolved.note);
|
|
868
|
+
this.log(`- API key env: ${ENV_FILE}`);
|
|
869
|
+
this.log(`- Shell profiles updated: ${updatedShellFiles.join(", ")}`);
|
|
870
|
+
if (selectedSetupClients.has("codex")) {
|
|
871
|
+
this.log(`- Codex: configured (${codexConfigPath})`);
|
|
872
|
+
if (resolved)
|
|
873
|
+
this.log(`- Codex model: ${resolved.model}`);
|
|
874
|
+
this.log(`- VS Code env hooks updated: ${updatedVsCodeEnvFiles.join(", ")}`);
|
|
875
|
+
if (sessionMigration?.rewritten) {
|
|
876
|
+
this.log(`- Conversations: updated ${sessionMigration.rewritten}/${sessionMigration.scanned} local sessions for cross-provider visibility.`);
|
|
877
|
+
}
|
|
878
|
+
else if (sessionMigration?.fastSkipped) {
|
|
879
|
+
this.log("- Conversations: already migrated (fast check).");
|
|
880
|
+
}
|
|
881
|
+
else if (sessionMigration) {
|
|
882
|
+
this.log("- Conversations: no local sessions required migration.");
|
|
883
|
+
}
|
|
884
|
+
if ((sessionMigration?.retimed ?? 0) > 0) {
|
|
885
|
+
this.log(`- Conversation ordering: repaired timestamps on ${sessionMigration?.retimed ?? 0} local sessions.`);
|
|
886
|
+
}
|
|
887
|
+
if ((stateDbMigration?.updated ?? 0) > 0) {
|
|
888
|
+
this.log(`- Conversation cache: relabeled ${stateDbMigration?.updated ?? 0} local Codex history rows for The Claw Bay.`);
|
|
889
|
+
}
|
|
890
|
+
else if ((stateDbMigration?.failed.length ?? 0) > 0) {
|
|
891
|
+
const detail = stateDbMigration?.warning ? ` ${stateDbMigration.warning}` : "";
|
|
892
|
+
this.log(`- Conversation cache: could not update local Codex history DB.${detail}`);
|
|
893
|
+
}
|
|
894
|
+
if (modelCacheMigration?.action === "seeded") {
|
|
895
|
+
this.log("- Codex model cache: added GPT-5.4 to the local picker cache.");
|
|
896
|
+
}
|
|
897
|
+
else if (modelCacheMigration?.action === "created") {
|
|
898
|
+
this.log("- Codex model cache: created a local picker cache with GPT-5.4.");
|
|
899
|
+
}
|
|
900
|
+
else if (modelCacheMigration?.action === "refreshed") {
|
|
901
|
+
this.log("- Codex model cache: refreshed the local picker cache for GPT-5.4.");
|
|
902
|
+
}
|
|
903
|
+
else if (modelCacheMigration?.action === "already_seeded") {
|
|
904
|
+
this.log("- Codex model cache: GPT-5.4 was already seeded locally.");
|
|
905
|
+
}
|
|
906
|
+
else if (modelCacheMigration?.action === "already_present") {
|
|
907
|
+
this.log("- Codex model cache: GPT-5.4 already existed locally.");
|
|
908
|
+
}
|
|
909
|
+
else if (modelCacheMigration?.warning) {
|
|
910
|
+
this.log(`- Codex model cache: ${modelCacheMigration.warning}`);
|
|
911
|
+
}
|
|
912
|
+
else if (modelCacheMigration) {
|
|
913
|
+
this.log("- Codex model cache: no change.");
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
else if (codexDetected) {
|
|
917
|
+
this.log("- Codex: detected but skipped");
|
|
834
918
|
}
|
|
835
919
|
else {
|
|
836
|
-
this.log("- Codex
|
|
920
|
+
this.log("- Codex: not detected (skipped)");
|
|
837
921
|
}
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
this.log(`- VS Code env hooks updated: ${updatedVsCodeEnvFiles.join(", ")}`);
|
|
841
|
-
const openClawDetected = optionalClients.find((client) => client.id === "openclaw")?.detected ?? false;
|
|
842
|
-
if (selectedOptionalClients.has("openclaw")) {
|
|
922
|
+
const openClawDetected = setupClients.find((client) => client.id === "openclaw")?.detected ?? false;
|
|
923
|
+
if (selectedSetupClients.has("openclaw")) {
|
|
843
924
|
this.log(`- OpenClaw: configured (${openClawConfigPath})`);
|
|
844
925
|
if (openClawCliWarning)
|
|
845
926
|
this.log(`- OpenClaw: ${openClawCliWarning}`);
|
|
@@ -850,8 +931,8 @@ class SetupCommand extends base_command_1.BaseCommand {
|
|
|
850
931
|
else {
|
|
851
932
|
this.log("- OpenClaw: not detected (skipped)");
|
|
852
933
|
}
|
|
853
|
-
const openCodeDetected =
|
|
854
|
-
if (
|
|
934
|
+
const openCodeDetected = setupClients.find((client) => client.id === "opencode")?.detected ?? false;
|
|
935
|
+
if (selectedSetupClients.has("opencode")) {
|
|
855
936
|
this.log(`- OpenCode: configured (${openCodePath})`);
|
|
856
937
|
}
|
|
857
938
|
else if (openCodeDetected) {
|
|
@@ -860,8 +941,7 @@ class SetupCommand extends base_command_1.BaseCommand {
|
|
|
860
941
|
else {
|
|
861
942
|
this.log("- OpenCode: not detected (skipped)");
|
|
862
943
|
}
|
|
863
|
-
|
|
864
|
-
if (selectedOptionalClients.has("kilo")) {
|
|
944
|
+
if (selectedSetupClients.has("kilo")) {
|
|
865
945
|
this.log(`- Kilo Code: configured (${kiloConfigPath})`);
|
|
866
946
|
}
|
|
867
947
|
else if (kiloDetected) {
|
|
@@ -870,10 +950,9 @@ class SetupCommand extends base_command_1.BaseCommand {
|
|
|
870
950
|
else {
|
|
871
951
|
this.log("- Kilo Code: not detected (skipped)");
|
|
872
952
|
}
|
|
873
|
-
|
|
874
|
-
if (selectedOptionalClients.has("trae")) {
|
|
953
|
+
if (selectedSetupClients.has("trae")) {
|
|
875
954
|
this.log(`- Trae: experimental bundle patch installed (${traeBundlePathPatched})`);
|
|
876
|
-
this.log(`- Trae: replaced Builder and SoloCoder model lists with ${resolved
|
|
955
|
+
this.log(`- Trae: replaced Builder and SoloCoder model lists with ${resolved?.models.length ?? 1} TheClawBay models.`);
|
|
877
956
|
this.log(`- Trae: restart Trae and select a TheClawBay model inside Trae to test it.`);
|
|
878
957
|
}
|
|
879
958
|
else if (traeDetected) {
|
|
@@ -882,22 +961,22 @@ class SetupCommand extends base_command_1.BaseCommand {
|
|
|
882
961
|
else {
|
|
883
962
|
this.log("- Trae: not detected (skipped)");
|
|
884
963
|
}
|
|
885
|
-
if (authSeed
|
|
964
|
+
if (authSeed?.action === "seeded") {
|
|
886
965
|
this.log("- Codex login state: seeded local API-key auth for Codex UI.");
|
|
887
966
|
}
|
|
888
|
-
else if (authSeed
|
|
967
|
+
else if (authSeed?.action === "updated") {
|
|
889
968
|
this.log("- Codex login state: refreshed the Claw Bay API-key auth seed.");
|
|
890
969
|
}
|
|
891
|
-
else if (authSeed
|
|
970
|
+
else if (authSeed?.action === "already_seeded") {
|
|
892
971
|
this.log("- Codex login state: the Claw Bay API-key auth was already seeded.");
|
|
893
972
|
}
|
|
894
|
-
else if (authSeed
|
|
973
|
+
else if (authSeed?.action === "already_present") {
|
|
895
974
|
this.log("- Codex login state: preserved existing local Codex auth.");
|
|
896
975
|
}
|
|
897
|
-
else if (authSeed
|
|
976
|
+
else if (authSeed?.warning) {
|
|
898
977
|
this.log(`- Codex login state: ${authSeed.warning}`);
|
|
899
978
|
}
|
|
900
|
-
else {
|
|
979
|
+
else if (authSeed) {
|
|
901
980
|
this.log("- Codex login state: no change.");
|
|
902
981
|
}
|
|
903
982
|
this.log("Next: restart terminal/VS Code window only if you rely on the The Claw Bay API key in your own scripts.");
|
|
@@ -917,7 +996,7 @@ SetupCommand.flags = {
|
|
|
917
996
|
}),
|
|
918
997
|
clients: core_1.Flags.string({
|
|
919
998
|
required: false,
|
|
920
|
-
description: "
|
|
999
|
+
description: "Detected local clients to configure: codex, openclaw, opencode, kilo, trae",
|
|
921
1000
|
}),
|
|
922
1001
|
yes: core_1.Flags.boolean({
|
|
923
1002
|
required: false,
|