theclawbay 0.3.28 → 0.3.30

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.
@@ -1,5 +1,8 @@
1
1
  import { BaseCommand } from "../lib/base-command";
2
2
  export default class LogoutCommand extends BaseCommand {
3
3
  static description: string;
4
+ static flags: {
5
+ "debug-output": import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
6
+ };
4
7
  run(): Promise<void>;
5
8
  }
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const promises_1 = __importDefault(require("node:fs/promises"));
7
7
  const node_os_1 = __importDefault(require("node:os"));
8
8
  const node_path_1 = __importDefault(require("node:path"));
9
+ const core_1 = require("@oclif/core");
9
10
  const yaml_1 = require("yaml");
10
11
  const base_command_1 = require("../lib/base-command");
11
12
  const codex_auth_seeding_1 = require("../lib/codex-auth-seeding");
@@ -41,6 +42,27 @@ const THECLAWBAY_OPENAI_PROXY_SUFFIX = "/api/codex-auth/v1/proxy/v1";
41
42
  const CONTINUE_MODEL_NAME = "The Claw Bay";
42
43
  const TRAE_PATCH_MARKER = "theclawbay-trae-patch";
43
44
  const TRAE_BUNDLE_BACKUP_SUFFIX = ".theclawbay-managed-backup";
45
+ function formatSummaryList(items) {
46
+ return items.join(", ");
47
+ }
48
+ function logLogoutCompactSummary(params) {
49
+ if (params.revertedTargets.length > 0) {
50
+ params.log(`Reverted: ${formatSummaryList(params.revertedTargets)}`);
51
+ }
52
+ else {
53
+ params.log("Reverted: no local tool changes were found.");
54
+ }
55
+ if (params.sharedConfigChanged) {
56
+ params.log("Shared config: removed your API key env and managed machine setup.");
57
+ }
58
+ else {
59
+ params.log("Shared config: nothing managed needed cleanup.");
60
+ }
61
+ for (const note of params.notes) {
62
+ params.log(`Note: ${note}`);
63
+ }
64
+ params.log("Restart any open terminals or editor windows to clear already-loaded environment.");
65
+ }
44
66
  function removeManagedBlock(source, start, end) {
45
67
  const markerStart = source.indexOf(start);
46
68
  if (markerStart < 0)
@@ -496,41 +518,127 @@ async function cleanupTraeBundle() {
496
518
  class LogoutCommand extends base_command_1.BaseCommand {
497
519
  async run() {
498
520
  await this.runSafe(async () => {
499
- const deletedManagedPaths = (await Promise.all([
500
- removeFileIfExists(paths_1.managedConfigPath),
501
- removeFileIfExists(paths_1.legacyManagedConfigPathClayBay),
502
- removeFileIfExists(paths_1.legacyManagedConfigPathCodexAuth),
503
- ])).filter(Boolean).length;
504
- const removedEnvFile = await removeFileIfExists(ENV_FILE);
505
- const updatedShellFiles = await cleanupShellFiles();
506
- const updatedVsCodeHooks = await cleanupVsCodeHooks();
507
- const updatedCodexConfig = await cleanupCodexConfig();
508
- const updatedContinueConfig = await cleanupContinueConfig();
509
- const updatedClineConfig = await cleanupClineConfig();
510
- const updatedOpenClawConfig = await cleanupOpenClawConfig();
511
- const updatedOpenCodeConfig = await cleanupOpenCodeConfig();
512
- const updatedKiloConfig = await cleanupKiloConfig();
513
- const updatedRooConfig = await cleanupRooConfig();
514
- const updatedTraeBundle = await cleanupTraeBundle();
515
- const updatedAiderConfig = await cleanupAiderConfig();
516
- const sessionMigration = await (0, codex_history_migration_1.migrateSessionProviders)({
517
- codexHome: paths_1.codexDir,
518
- migrationStateFile: MIGRATION_STATE_FILE,
519
- neutralizeSources: HISTORY_PROVIDER_NEUTRALIZE_SOURCES,
520
- });
521
- const stateDbMigration = await (0, codex_history_migration_1.migrateStateDbProviders)({
522
- codexHome: paths_1.codexDir,
523
- targetProvider: OPENAI_PROVIDER_ID,
524
- sourceProviders: HISTORY_PROVIDER_DB_MIGRATE_SOURCES,
525
- });
526
- const authSeedCleanup = await (0, codex_auth_seeding_1.cleanupSeededCodexApiKeyAuth)({
527
- codexHome: paths_1.codexDir,
528
- });
529
- const modelCacheCleanup = await (0, codex_model_cache_migration_1.cleanupSeededCodexModelCache)({
530
- codexHome: paths_1.codexDir,
531
- });
521
+ const { flags } = await this.parse(LogoutCommand);
522
+ const debugOutput = flags["debug-output"];
523
+ const progress = this.createProgressHandle(!debugOutput);
524
+ let deletedManagedPaths = 0;
525
+ let removedEnvFile = false;
526
+ let updatedShellFiles = [];
527
+ let updatedVsCodeHooks = [];
528
+ let updatedCodexConfig = false;
529
+ let updatedContinueConfig = false;
530
+ let updatedClineConfig = false;
531
+ let updatedOpenClawConfig = false;
532
+ let updatedOpenCodeConfig = false;
533
+ let updatedKiloConfig = false;
534
+ let updatedRooConfig = false;
535
+ let updatedTraeBundle = false;
536
+ let updatedAiderConfig = false;
537
+ let sessionMigration;
538
+ let stateDbMigration;
539
+ let authSeedCleanup;
540
+ let modelCacheCleanup;
541
+ try {
542
+ progress.update("Removing shared machine config");
543
+ deletedManagedPaths = (await Promise.all([
544
+ removeFileIfExists(paths_1.managedConfigPath),
545
+ removeFileIfExists(paths_1.legacyManagedConfigPathClayBay),
546
+ removeFileIfExists(paths_1.legacyManagedConfigPathCodexAuth),
547
+ ])).filter(Boolean).length;
548
+ removedEnvFile = await removeFileIfExists(ENV_FILE);
549
+ updatedShellFiles = await cleanupShellFiles();
550
+ updatedVsCodeHooks = await cleanupVsCodeHooks();
551
+ progress.update("Reverting Codex");
552
+ updatedCodexConfig = await cleanupCodexConfig();
553
+ sessionMigration = await (0, codex_history_migration_1.migrateSessionProviders)({
554
+ codexHome: paths_1.codexDir,
555
+ migrationStateFile: MIGRATION_STATE_FILE,
556
+ neutralizeSources: HISTORY_PROVIDER_NEUTRALIZE_SOURCES,
557
+ });
558
+ stateDbMigration = await (0, codex_history_migration_1.migrateStateDbProviders)({
559
+ codexHome: paths_1.codexDir,
560
+ targetProvider: OPENAI_PROVIDER_ID,
561
+ sourceProviders: HISTORY_PROVIDER_DB_MIGRATE_SOURCES,
562
+ });
563
+ authSeedCleanup = await (0, codex_auth_seeding_1.cleanupSeededCodexApiKeyAuth)({
564
+ codexHome: paths_1.codexDir,
565
+ });
566
+ modelCacheCleanup = await (0, codex_model_cache_migration_1.cleanupSeededCodexModelCache)({
567
+ codexHome: paths_1.codexDir,
568
+ });
569
+ progress.update("Reverting Continue");
570
+ updatedContinueConfig = await cleanupContinueConfig();
571
+ progress.update("Reverting Cline");
572
+ updatedClineConfig = await cleanupClineConfig();
573
+ progress.update("Reverting OpenClaw");
574
+ updatedOpenClawConfig = await cleanupOpenClawConfig();
575
+ progress.update("Reverting OpenCode");
576
+ updatedOpenCodeConfig = await cleanupOpenCodeConfig();
577
+ progress.update("Reverting Kilo Code");
578
+ updatedKiloConfig = await cleanupKiloConfig();
579
+ progress.update("Reverting Roo Code");
580
+ updatedRooConfig = await cleanupRooConfig();
581
+ progress.update("Reverting Trae");
582
+ updatedTraeBundle = await cleanupTraeBundle();
583
+ progress.update("Reverting Aider");
584
+ updatedAiderConfig = await cleanupAiderConfig();
585
+ }
586
+ catch (error) {
587
+ progress.fail("Logout failed");
588
+ throw error;
589
+ }
532
590
  delete process.env[ENV_KEY_NAME];
533
- this.log("Logout complete");
591
+ if (!debugOutput && process.stdout.isTTY) {
592
+ progress.succeed("Logout complete");
593
+ }
594
+ else {
595
+ this.log("Logout complete");
596
+ }
597
+ const revertedTargets = [];
598
+ const codexChanged = updatedCodexConfig ||
599
+ updatedVsCodeHooks.length > 0 ||
600
+ sessionMigration.rewritten > 0 ||
601
+ sessionMigration.retimed > 0 ||
602
+ stateDbMigration.updated > 0 ||
603
+ authSeedCleanup.action === "removed" ||
604
+ modelCacheCleanup.action === "removed";
605
+ if (codexChanged)
606
+ revertedTargets.push("Codex");
607
+ if (updatedContinueConfig)
608
+ revertedTargets.push("Continue");
609
+ if (updatedClineConfig)
610
+ revertedTargets.push("Cline");
611
+ if (updatedOpenClawConfig)
612
+ revertedTargets.push("OpenClaw");
613
+ if (updatedOpenCodeConfig)
614
+ revertedTargets.push("OpenCode");
615
+ if (updatedKiloConfig)
616
+ revertedTargets.push("Kilo Code");
617
+ if (updatedRooConfig)
618
+ revertedTargets.push("Roo Code");
619
+ if (updatedTraeBundle)
620
+ revertedTargets.push("Trae");
621
+ if (updatedAiderConfig)
622
+ revertedTargets.push("Aider");
623
+ const summaryNotes = new Set();
624
+ if (stateDbMigration.failed.length > 0) {
625
+ summaryNotes.add(stateDbMigration.warning
626
+ ? `Codex history cache could not be fully restored. ${stateDbMigration.warning}`
627
+ : "Codex history cache could not be fully restored.");
628
+ }
629
+ if (authSeedCleanup.warning)
630
+ summaryNotes.add(authSeedCleanup.warning);
631
+ if (modelCacheCleanup.warning)
632
+ summaryNotes.add(modelCacheCleanup.warning);
633
+ if (!debugOutput) {
634
+ logLogoutCompactSummary({
635
+ log: (message) => this.log(message),
636
+ revertedTargets,
637
+ sharedConfigChanged: deletedManagedPaths > 0 || removedEnvFile || updatedShellFiles.length > 0 || updatedVsCodeHooks.length > 0,
638
+ notes: Array.from(summaryNotes),
639
+ });
640
+ return;
641
+ }
534
642
  this.log(`- Managed configs removed: ${deletedManagedPaths}`);
535
643
  this.log(`- API key env file removed: ${removedEnvFile ? "yes" : "no"}`);
536
644
  this.log(`- Shell profiles updated: ${updatedShellFiles.length ? updatedShellFiles.join(", ") : "none"}`);
@@ -594,4 +702,11 @@ class LogoutCommand extends base_command_1.BaseCommand {
594
702
  }
595
703
  }
596
704
  LogoutCommand.description = "Log out from local The Claw Bay API-key auth on this machine";
705
+ LogoutCommand.flags = {
706
+ "debug-output": core_1.Flags.boolean({
707
+ required: false,
708
+ default: false,
709
+ description: "Show verbose logout details, file paths, and migration notes",
710
+ }),
711
+ };
597
712
  exports.default = LogoutCommand;
@@ -6,6 +6,7 @@ export default class SetupCommand extends BaseCommand {
6
6
  "api-key": import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
7
7
  clients: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
8
8
  yes: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
9
+ "debug-output": import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
9
10
  };
10
11
  run(): Promise<void>;
11
12
  }
@@ -124,6 +124,30 @@ function formatSetupClientLabel(client, hyperlinksEnabled) {
124
124
  }
125
125
  return `${iconAndLabel} - ${client.siteUrl}`;
126
126
  }
127
+ function formatSummaryList(items) {
128
+ return items.join(", ");
129
+ }
130
+ function logSetupCompactSummary(params) {
131
+ const configured = params.setupClients
132
+ .filter((client) => params.selectedSetupClients.has(client.id))
133
+ .map((client) => client.summaryLabel);
134
+ const restartTargets = params.setupClients
135
+ .filter((client) => params.selectedSetupClients.has(client.id) && ["continue", "cline", "roo", "trae"].includes(client.id))
136
+ .map((client) => client.summaryLabel);
137
+ if (configured.length > 0) {
138
+ params.log(`Configured: ${formatSummaryList(configured)}`);
139
+ }
140
+ else {
141
+ params.log("Configured: no local tools selected.");
142
+ }
143
+ params.log("Shared config: saved your API key and managed machine setup.");
144
+ if (restartTargets.length > 0) {
145
+ params.log(`Restart if already open: ${formatSummaryList(restartTargets)}`);
146
+ }
147
+ for (const note of params.notes) {
148
+ params.log(`Note: ${note}`);
149
+ }
150
+ }
127
151
  function localAppDataDir() {
128
152
  if (process.env.LOCALAPPDATA?.trim())
129
153
  return process.env.LOCALAPPDATA;
@@ -1143,6 +1167,7 @@ class SetupCommand extends base_command_1.BaseCommand {
1143
1167
  async run() {
1144
1168
  await this.runSafe(async () => {
1145
1169
  const { flags } = await this.parse(SetupCommand);
1170
+ const debugOutput = flags["debug-output"];
1146
1171
  let managed = null;
1147
1172
  try {
1148
1173
  managed = await (0, config_1.readManagedConfig)();
@@ -1169,6 +1194,7 @@ class SetupCommand extends base_command_1.BaseCommand {
1169
1194
  {
1170
1195
  id: "codex",
1171
1196
  label: "Codex CLI, VS Code extension, and Codex app",
1197
+ summaryLabel: "Codex",
1172
1198
  detected: codexDetected,
1173
1199
  recommended: true,
1174
1200
  icon: "◎",
@@ -1177,6 +1203,7 @@ class SetupCommand extends base_command_1.BaseCommand {
1177
1203
  {
1178
1204
  id: "continue",
1179
1205
  label: "Continue",
1206
+ summaryLabel: "Continue",
1180
1207
  detected: continueDetected,
1181
1208
  recommended: true,
1182
1209
  icon: "▶",
@@ -1185,6 +1212,7 @@ class SetupCommand extends base_command_1.BaseCommand {
1185
1212
  {
1186
1213
  id: "cline",
1187
1214
  label: "Cline",
1215
+ summaryLabel: "Cline",
1188
1216
  detected: clineDetected,
1189
1217
  recommended: true,
1190
1218
  icon: "◈",
@@ -1193,6 +1221,7 @@ class SetupCommand extends base_command_1.BaseCommand {
1193
1221
  {
1194
1222
  id: "openclaw",
1195
1223
  label: "OpenClaw",
1224
+ summaryLabel: "OpenClaw",
1196
1225
  detected: hasCommand("openclaw"),
1197
1226
  recommended: true,
1198
1227
  icon: "🦞",
@@ -1201,6 +1230,7 @@ class SetupCommand extends base_command_1.BaseCommand {
1201
1230
  {
1202
1231
  id: "opencode",
1203
1232
  label: "OpenCode",
1233
+ summaryLabel: "OpenCode",
1204
1234
  detected: hasCommand("opencode"),
1205
1235
  recommended: true,
1206
1236
  icon: "⌘",
@@ -1209,6 +1239,7 @@ class SetupCommand extends base_command_1.BaseCommand {
1209
1239
  {
1210
1240
  id: "kilo",
1211
1241
  label: "Kilo Code",
1242
+ summaryLabel: "Kilo Code",
1212
1243
  detected: kiloDetected,
1213
1244
  recommended: true,
1214
1245
  icon: "⚡",
@@ -1217,6 +1248,7 @@ class SetupCommand extends base_command_1.BaseCommand {
1217
1248
  {
1218
1249
  id: "roo",
1219
1250
  label: "Roo Code",
1251
+ summaryLabel: "Roo Code",
1220
1252
  detected: rooDetected,
1221
1253
  recommended: true,
1222
1254
  icon: "🦘",
@@ -1225,6 +1257,7 @@ class SetupCommand extends base_command_1.BaseCommand {
1225
1257
  {
1226
1258
  id: "trae",
1227
1259
  label: "Trae (experimental)",
1260
+ summaryLabel: "Trae",
1228
1261
  detected: traeDetected,
1229
1262
  recommended: false,
1230
1263
  icon: "△",
@@ -1233,6 +1266,7 @@ class SetupCommand extends base_command_1.BaseCommand {
1233
1266
  {
1234
1267
  id: "aider",
1235
1268
  label: "Aider",
1269
+ summaryLabel: "Aider",
1236
1270
  detected: aiderDetected,
1237
1271
  recommended: true,
1238
1272
  icon: "✦",
@@ -1244,12 +1278,9 @@ class SetupCommand extends base_command_1.BaseCommand {
1244
1278
  flagSelection: parseSetupClientFlags(flags.clients),
1245
1279
  skipPrompt: flags.yes,
1246
1280
  });
1281
+ const progress = this.createProgressHandle(!debugOutput);
1247
1282
  let resolved = null;
1248
- if (selectedSetupClients.size > 0) {
1249
- resolved = await resolveModels(backendUrl, apiKey);
1250
- }
1251
- await (0, config_1.writeManagedConfig)({ backendUrl, apiKey });
1252
- const updatedShellFiles = await persistApiKeyEnv(apiKey);
1283
+ let updatedShellFiles = [];
1253
1284
  let codexConfigPath = null;
1254
1285
  let updatedVsCodeEnvFiles = [];
1255
1286
  let sessionMigration = null;
@@ -1265,90 +1296,143 @@ class SetupCommand extends base_command_1.BaseCommand {
1265
1296
  let rooConfigPaths = [];
1266
1297
  let traeBundlePathPatched = null;
1267
1298
  let aiderConfigPath = null;
1268
- if (selectedSetupClients.has("codex")) {
1269
- codexConfigPath = await writeCodexConfig({ backendUrl, model: resolved?.model ?? DEFAULT_CODEX_MODEL, apiKey });
1270
- updatedVsCodeEnvFiles = await persistVsCodeServerEnvSource();
1271
- sessionMigration = await (0, codex_history_migration_1.migrateSessionProviders)({
1272
- codexHome: paths_1.codexDir,
1273
- migrationStateFile: MIGRATION_STATE_FILE,
1274
- neutralizeSources: HISTORY_PROVIDER_NEUTRALIZE_SOURCES,
1275
- });
1276
- authSeed = await (0, codex_auth_seeding_1.ensureCodexApiKeyAuth)({
1277
- codexHome: paths_1.codexDir,
1278
- apiKey,
1279
- });
1280
- stateDbMigration = await (0, codex_history_migration_1.migrateStateDbProviders)({
1281
- codexHome: paths_1.codexDir,
1282
- targetProvider: DEFAULT_PROVIDER_ID,
1283
- sourceProviders: HISTORY_PROVIDER_DB_MIGRATE_SOURCES,
1284
- });
1285
- modelCacheMigration = await (0, codex_model_cache_migration_1.ensureCodexModelCacheHasGpt54)({
1286
- codexHome: paths_1.codexDir,
1287
- });
1288
- }
1289
- if (selectedSetupClients.has("continue")) {
1290
- continueConfigPath = await writeContinueConfig({
1291
- backendUrl,
1292
- model: resolved?.model ?? DEFAULT_CONTINUE_MODEL,
1293
- apiKey,
1294
- });
1295
- }
1296
- if (selectedSetupClients.has("cline")) {
1297
- clineConfigPaths = await writeClineConfig({
1298
- backendUrl,
1299
- model: resolved?.model ?? DEFAULT_CLINE_MODEL,
1300
- apiKey,
1301
- });
1302
- }
1303
- if (selectedSetupClients.has("openclaw")) {
1304
- const openClawResult = await setupOpenClaw({
1305
- backendUrl,
1306
- model: resolved?.model ?? DEFAULT_CODEX_MODEL,
1307
- models: resolved?.models ?? [{ id: DEFAULT_CODEX_MODEL, name: modelDisplayName(DEFAULT_CODEX_MODEL) }],
1308
- apiKey,
1309
- });
1310
- openClawConfigPath = openClawResult.configPath;
1311
- openClawCliWarning = openClawResult.cliWarning ?? null;
1299
+ try {
1300
+ if (selectedSetupClients.size > 0) {
1301
+ progress.update("Resolving supported models");
1302
+ resolved = await resolveModels(backendUrl, apiKey);
1303
+ }
1304
+ progress.update("Saving shared machine config");
1305
+ await (0, config_1.writeManagedConfig)({ backendUrl, apiKey });
1306
+ updatedShellFiles = await persistApiKeyEnv(apiKey);
1307
+ if (selectedSetupClients.has("codex")) {
1308
+ progress.update("Configuring Codex");
1309
+ codexConfigPath = await writeCodexConfig({ backendUrl, model: resolved?.model ?? DEFAULT_CODEX_MODEL, apiKey });
1310
+ updatedVsCodeEnvFiles = await persistVsCodeServerEnvSource();
1311
+ sessionMigration = await (0, codex_history_migration_1.migrateSessionProviders)({
1312
+ codexHome: paths_1.codexDir,
1313
+ migrationStateFile: MIGRATION_STATE_FILE,
1314
+ neutralizeSources: HISTORY_PROVIDER_NEUTRALIZE_SOURCES,
1315
+ });
1316
+ authSeed = await (0, codex_auth_seeding_1.ensureCodexApiKeyAuth)({
1317
+ codexHome: paths_1.codexDir,
1318
+ apiKey,
1319
+ });
1320
+ stateDbMigration = await (0, codex_history_migration_1.migrateStateDbProviders)({
1321
+ codexHome: paths_1.codexDir,
1322
+ targetProvider: DEFAULT_PROVIDER_ID,
1323
+ sourceProviders: HISTORY_PROVIDER_DB_MIGRATE_SOURCES,
1324
+ });
1325
+ modelCacheMigration = await (0, codex_model_cache_migration_1.ensureCodexModelCacheHasGpt54)({
1326
+ codexHome: paths_1.codexDir,
1327
+ });
1328
+ }
1329
+ if (selectedSetupClients.has("continue")) {
1330
+ progress.update("Configuring Continue");
1331
+ continueConfigPath = await writeContinueConfig({
1332
+ backendUrl,
1333
+ model: resolved?.model ?? DEFAULT_CONTINUE_MODEL,
1334
+ apiKey,
1335
+ });
1336
+ }
1337
+ if (selectedSetupClients.has("cline")) {
1338
+ progress.update("Configuring Cline");
1339
+ clineConfigPaths = await writeClineConfig({
1340
+ backendUrl,
1341
+ model: resolved?.model ?? DEFAULT_CLINE_MODEL,
1342
+ apiKey,
1343
+ });
1344
+ }
1345
+ if (selectedSetupClients.has("openclaw")) {
1346
+ progress.update("Configuring OpenClaw");
1347
+ const openClawResult = await setupOpenClaw({
1348
+ backendUrl,
1349
+ model: resolved?.model ?? DEFAULT_CODEX_MODEL,
1350
+ models: resolved?.models ?? [{ id: DEFAULT_CODEX_MODEL, name: modelDisplayName(DEFAULT_CODEX_MODEL) }],
1351
+ apiKey,
1352
+ });
1353
+ openClawConfigPath = openClawResult.configPath;
1354
+ openClawCliWarning = openClawResult.cliWarning ?? null;
1355
+ }
1356
+ if (selectedSetupClients.has("opencode")) {
1357
+ progress.update("Configuring OpenCode");
1358
+ openCodePath = await writeOpenCodeConfig({
1359
+ backendUrl,
1360
+ model: resolved?.model ?? DEFAULT_CODEX_MODEL,
1361
+ models: resolved?.models ?? [{ id: DEFAULT_CODEX_MODEL, name: modelDisplayName(DEFAULT_CODEX_MODEL) }],
1362
+ apiKey,
1363
+ });
1364
+ }
1365
+ if (selectedSetupClients.has("kilo")) {
1366
+ progress.update("Configuring Kilo Code");
1367
+ kiloConfigPath = await writeKiloConfig({
1368
+ backendUrl,
1369
+ model: resolved?.model ?? DEFAULT_CODEX_MODEL,
1370
+ models: resolved?.models ?? [{ id: DEFAULT_CODEX_MODEL, name: modelDisplayName(DEFAULT_CODEX_MODEL) }],
1371
+ apiKey,
1372
+ });
1373
+ }
1374
+ if (selectedSetupClients.has("roo")) {
1375
+ progress.update("Configuring Roo Code");
1376
+ rooConfigPaths = await writeRooConfig({
1377
+ backendUrl,
1378
+ model: resolved?.model ?? DEFAULT_ROO_MODEL,
1379
+ apiKey,
1380
+ });
1381
+ }
1382
+ if (selectedSetupClients.has("trae")) {
1383
+ progress.update("Configuring Trae");
1384
+ traeBundlePathPatched = await patchTraeBundle({
1385
+ backendUrl,
1386
+ model: resolved?.model ?? DEFAULT_CODEX_MODEL,
1387
+ apiKey,
1388
+ models: resolved?.models ?? [{ id: DEFAULT_CODEX_MODEL, name: modelDisplayName(DEFAULT_CODEX_MODEL) }],
1389
+ });
1390
+ }
1391
+ if (selectedSetupClients.has("aider")) {
1392
+ progress.update("Configuring Aider");
1393
+ aiderConfigPath = await writeAiderConfig({
1394
+ backendUrl,
1395
+ model: resolved?.model ?? DEFAULT_AIDER_MODEL,
1396
+ apiKey,
1397
+ });
1398
+ }
1312
1399
  }
1313
- if (selectedSetupClients.has("opencode")) {
1314
- openCodePath = await writeOpenCodeConfig({
1315
- backendUrl,
1316
- model: resolved?.model ?? DEFAULT_CODEX_MODEL,
1317
- models: resolved?.models ?? [{ id: DEFAULT_CODEX_MODEL, name: modelDisplayName(DEFAULT_CODEX_MODEL) }],
1318
- apiKey,
1319
- });
1400
+ catch (error) {
1401
+ progress.fail("Setup failed");
1402
+ throw error;
1320
1403
  }
1321
- if (selectedSetupClients.has("kilo")) {
1322
- kiloConfigPath = await writeKiloConfig({
1323
- backendUrl,
1324
- model: resolved?.model ?? DEFAULT_CODEX_MODEL,
1325
- models: resolved?.models ?? [{ id: DEFAULT_CODEX_MODEL, name: modelDisplayName(DEFAULT_CODEX_MODEL) }],
1326
- apiKey,
1327
- });
1404
+ if (!debugOutput && process.stdout.isTTY) {
1405
+ progress.succeed("Setup complete");
1328
1406
  }
1329
- if (selectedSetupClients.has("roo")) {
1330
- rooConfigPaths = await writeRooConfig({
1331
- backendUrl,
1332
- model: resolved?.model ?? DEFAULT_ROO_MODEL,
1333
- apiKey,
1334
- });
1407
+ else {
1408
+ this.log("Setup complete");
1335
1409
  }
1410
+ const summaryNotes = new Set();
1411
+ if (resolved?.note)
1412
+ summaryNotes.add(resolved.note);
1336
1413
  if (selectedSetupClients.has("trae")) {
1337
- traeBundlePathPatched = await patchTraeBundle({
1338
- backendUrl,
1339
- model: resolved?.model ?? DEFAULT_CODEX_MODEL,
1340
- apiKey,
1341
- models: resolved?.models ?? [{ id: DEFAULT_CODEX_MODEL, name: modelDisplayName(DEFAULT_CODEX_MODEL) }],
1342
- });
1414
+ summaryNotes.add("Trae uses an experimental patch. Restart Trae and pick a The Claw Bay model to test it.");
1343
1415
  }
1344
- if (selectedSetupClients.has("aider")) {
1345
- aiderConfigPath = await writeAiderConfig({
1346
- backendUrl,
1347
- model: resolved?.model ?? DEFAULT_AIDER_MODEL,
1348
- apiKey,
1416
+ if (openClawCliWarning)
1417
+ summaryNotes.add(openClawCliWarning);
1418
+ if ((stateDbMigration?.failed.length ?? 0) > 0) {
1419
+ summaryNotes.add(stateDbMigration?.warning
1420
+ ? `Codex history cache could not be fully updated. ${stateDbMigration.warning}`
1421
+ : "Codex history cache could not be fully updated.");
1422
+ }
1423
+ if (modelCacheMigration?.warning)
1424
+ summaryNotes.add(modelCacheMigration.warning);
1425
+ if (authSeed?.warning)
1426
+ summaryNotes.add(authSeed.warning);
1427
+ if (!debugOutput) {
1428
+ logSetupCompactSummary({
1429
+ log: (message) => this.log(message),
1430
+ setupClients,
1431
+ selectedSetupClients,
1432
+ notes: Array.from(summaryNotes),
1349
1433
  });
1434
+ return;
1350
1435
  }
1351
- this.log("Setup complete");
1352
1436
  this.log(`- Managed config: ${paths_1.managedConfigPath}`);
1353
1437
  this.log(`- Backend: ${backendUrl}`);
1354
1438
  if (selectedSetupClients.size === 0) {
@@ -1536,5 +1620,10 @@ SetupCommand.flags = {
1536
1620
  default: false,
1537
1621
  description: "Accept the recommended detected setup targets without prompting",
1538
1622
  }),
1623
+ "debug-output": core_1.Flags.boolean({
1624
+ required: false,
1625
+ default: false,
1626
+ description: "Show verbose setup details, file paths, and migration notes",
1627
+ }),
1539
1628
  };
1540
1629
  exports.default = SetupCommand;
@@ -1,5 +1,13 @@
1
1
  import { Command } from "@oclif/core";
2
+ type ProgressHandle = {
3
+ update(message: string): void;
4
+ succeed(message?: string): void;
5
+ fail(message?: string): void;
6
+ stop(): void;
7
+ };
2
8
  export declare abstract class BaseCommand extends Command {
3
9
  protected runSafe(action: () => Promise<void>): Promise<void>;
4
10
  private handleError;
11
+ protected createProgressHandle(enabled: boolean): ProgressHandle;
5
12
  }
13
+ export {};
@@ -27,5 +27,63 @@ class BaseCommand extends core_1.Command {
27
27
  }
28
28
  this.error(String(error));
29
29
  }
30
+ createProgressHandle(enabled) {
31
+ if (!enabled || !process.stdout.isTTY) {
32
+ return {
33
+ update() { },
34
+ succeed() { },
35
+ fail() { },
36
+ stop() { },
37
+ };
38
+ }
39
+ const frames = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
40
+ let message = "";
41
+ let frameIndex = 0;
42
+ let timer = null;
43
+ const render = (prefix) => {
44
+ process.stdout.write(`\r\x1b[2K${prefix} ${message}`);
45
+ };
46
+ const ensureTimer = () => {
47
+ if (timer)
48
+ return;
49
+ timer = setInterval(() => {
50
+ frameIndex = (frameIndex + 1) % frames.length;
51
+ render(frames[frameIndex] ?? frames[0] ?? "•");
52
+ }, 80);
53
+ if (typeof timer.unref === "function")
54
+ timer.unref();
55
+ };
56
+ const clearTimer = () => {
57
+ if (!timer)
58
+ return;
59
+ clearInterval(timer);
60
+ timer = null;
61
+ };
62
+ return {
63
+ update(nextMessage) {
64
+ message = nextMessage;
65
+ ensureTimer();
66
+ render(frames[frameIndex] ?? frames[0] ?? "•");
67
+ },
68
+ succeed(nextMessage) {
69
+ if (nextMessage)
70
+ message = nextMessage;
71
+ clearTimer();
72
+ render("✓");
73
+ process.stdout.write("\n");
74
+ },
75
+ fail(nextMessage) {
76
+ if (nextMessage)
77
+ message = nextMessage;
78
+ clearTimer();
79
+ render("✕");
80
+ process.stdout.write("\n");
81
+ },
82
+ stop() {
83
+ clearTimer();
84
+ process.stdout.write("\r\x1b[2K");
85
+ },
86
+ };
87
+ }
30
88
  }
31
89
  exports.BaseCommand = BaseCommand;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "theclawbay",
3
- "version": "0.3.28",
3
+ "version": "0.3.30",
4
4
  "description": "CLI for connecting Codex, Continue, Cline, OpenClaw, OpenCode, Kilo, Roo Code, Aider, and experimental Trae to The Claw Bay.",
5
5
  "license": "MIT",
6
6
  "bin": {