theclawbay 0.3.27 → 0.3.28
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 +1 -2
- package/dist/commands/setup.js +72 -9
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -17,8 +17,7 @@ theclawbay setup --api-key <apiKey>
|
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
In an interactive terminal, setup shows one picker for Codex, Continue, Cline, OpenClaw, OpenCode, Kilo, Roo Code, Aider, and Windows Trae.
|
|
20
|
-
|
|
21
|
-
and you can toggle items with arrow keys plus `Enter` or by pressing their number.
|
|
20
|
+
Each row includes a terminal-friendly icon plus the tool's official site, and you can toggle items with arrow keys plus `Enter` or by pressing their number.
|
|
22
21
|
|
|
23
22
|
History notes:
|
|
24
23
|
|
package/dist/commands/setup.js
CHANGED
|
@@ -81,6 +81,49 @@ function hasCommand(name) {
|
|
|
81
81
|
const result = (0, node_child_process_1.spawnSync)(lookupCommand, [name], { stdio: "ignore" });
|
|
82
82
|
return result.status === 0;
|
|
83
83
|
}
|
|
84
|
+
function supportsTerminalHyperlinks() {
|
|
85
|
+
if (!process.stdout.isTTY)
|
|
86
|
+
return false;
|
|
87
|
+
if (process.env.FORCE_HYPERLINK === "1")
|
|
88
|
+
return true;
|
|
89
|
+
if (process.env.NO_HYPERLINK === "1")
|
|
90
|
+
return false;
|
|
91
|
+
const term = (process.env.TERM ?? "").toLowerCase();
|
|
92
|
+
if (!term || term === "dumb")
|
|
93
|
+
return false;
|
|
94
|
+
const termProgram = (process.env.TERM_PROGRAM ?? "").toLowerCase();
|
|
95
|
+
if (termProgram === "iterm.app" || termProgram === "wezterm" || termProgram === "vscode") {
|
|
96
|
+
return true;
|
|
97
|
+
}
|
|
98
|
+
if (process.env.WT_SESSION ||
|
|
99
|
+
process.env.KITTY_WINDOW_ID ||
|
|
100
|
+
process.env.KONSOLE_VERSION ||
|
|
101
|
+
process.env.VTE_VERSION ||
|
|
102
|
+
process.env.DOMTERM ||
|
|
103
|
+
process.env.TERMINAL_EMULATOR === "JetBrains-JediTerm") {
|
|
104
|
+
return true;
|
|
105
|
+
}
|
|
106
|
+
return term.includes("xterm-kitty") || term.includes("foot") || term.includes("wezterm");
|
|
107
|
+
}
|
|
108
|
+
function formatTerminalHyperlink(label, url) {
|
|
109
|
+
return `\u001B]8;;${url}\u0007${label}\u001B]8;;\u0007`;
|
|
110
|
+
}
|
|
111
|
+
function formatDim(value) {
|
|
112
|
+
return `\u001B[2m${value}\u001B[0m`;
|
|
113
|
+
}
|
|
114
|
+
function officialSiteLabel(siteUrl) {
|
|
115
|
+
const parsed = new URL(siteUrl);
|
|
116
|
+
const hostname = parsed.hostname.replace(/^www\./, "");
|
|
117
|
+
const pathname = parsed.pathname.replace(/\/+$/g, "");
|
|
118
|
+
return pathname && pathname !== "/" ? `${hostname}${pathname}` : hostname;
|
|
119
|
+
}
|
|
120
|
+
function formatSetupClientLabel(client, hyperlinksEnabled) {
|
|
121
|
+
const iconAndLabel = `${client.icon} ${client.label}`;
|
|
122
|
+
if (hyperlinksEnabled) {
|
|
123
|
+
return `${formatTerminalHyperlink(iconAndLabel, client.siteUrl)} ${formatDim(`(${officialSiteLabel(client.siteUrl)})`)}`;
|
|
124
|
+
}
|
|
125
|
+
return `${iconAndLabel} - ${client.siteUrl}`;
|
|
126
|
+
}
|
|
84
127
|
function localAppDataDir() {
|
|
85
128
|
if (process.env.LOCALAPPDATA?.trim())
|
|
86
129
|
return process.env.LOCALAPPDATA;
|
|
@@ -386,12 +429,13 @@ async function promptForSetupClients(clients) {
|
|
|
386
429
|
let cursor = 0;
|
|
387
430
|
let settled = false;
|
|
388
431
|
let hint = clients.some((client) => client.detected)
|
|
389
|
-
? "
|
|
390
|
-
: "No supported local clients are detected yet.
|
|
432
|
+
? "Choose the tools you want to configure."
|
|
433
|
+
: "No supported local clients are detected yet. Apply setup will just save your managed config and API key env.";
|
|
391
434
|
const stdin = process.stdin;
|
|
392
435
|
const stdout = process.stdout;
|
|
393
436
|
const wasRaw = stdin.isRaw;
|
|
394
|
-
const
|
|
437
|
+
const applyIndex = options.length;
|
|
438
|
+
const hyperlinksEnabled = supportsTerminalHyperlinks();
|
|
395
439
|
const clearScreen = () => {
|
|
396
440
|
stdout.write("\x1b[2J\x1b[H");
|
|
397
441
|
};
|
|
@@ -400,15 +444,16 @@ async function promptForSetupClients(clients) {
|
|
|
400
444
|
clearScreen();
|
|
401
445
|
stdout.write("Choose local clients to configure\n");
|
|
402
446
|
stdout.write(`Use ↑/↓ to move, Enter to toggle the highlighted integration, or press 1-${options.length} to toggle directly.\n`);
|
|
403
|
-
stdout.write("
|
|
447
|
+
stdout.write("Each tool name links to its official site when your terminal supports it.\n");
|
|
448
|
+
stdout.write("Move to Apply setup and press Enter when you're ready.\n\n");
|
|
404
449
|
for (const [index, option] of options.entries()) {
|
|
405
450
|
const pointer = index === cursor ? ">" : " ";
|
|
406
451
|
const mark = option.detected ? (option.checked ? "[x]" : "[ ]") : "[-]";
|
|
407
452
|
const badge = option.detected ? (option.recommended ? "recommended" : "optional") : "not detected";
|
|
408
|
-
stdout.write(`${pointer} ${index + 1}. ${mark} ${option
|
|
453
|
+
stdout.write(`${pointer} ${index + 1}. ${mark} ${formatSetupClientLabel(option, hyperlinksEnabled)} ${badge}\n`);
|
|
409
454
|
}
|
|
410
|
-
const
|
|
411
|
-
stdout.write(`${
|
|
455
|
+
const applyPointer = cursor === applyIndex ? ">" : " ";
|
|
456
|
+
stdout.write(`${applyPointer} Apply setup with ${selectedCount()} selected integration${selectedCount() === 1 ? "" : "s"}\n`);
|
|
412
457
|
stdout.write(`\n${hint}\n`);
|
|
413
458
|
};
|
|
414
459
|
const finish = () => {
|
|
@@ -454,7 +499,7 @@ async function promptForSetupClients(clients) {
|
|
|
454
499
|
return;
|
|
455
500
|
}
|
|
456
501
|
if (key.name === "space") {
|
|
457
|
-
if (cursor ===
|
|
502
|
+
if (cursor === applyIndex) {
|
|
458
503
|
finish();
|
|
459
504
|
return;
|
|
460
505
|
}
|
|
@@ -476,7 +521,7 @@ async function promptForSetupClients(clients) {
|
|
|
476
521
|
return;
|
|
477
522
|
}
|
|
478
523
|
if (key.name === "return" || key.name === "enter") {
|
|
479
|
-
if (cursor ===
|
|
524
|
+
if (cursor === applyIndex) {
|
|
480
525
|
finish();
|
|
481
526
|
return;
|
|
482
527
|
}
|
|
@@ -1126,54 +1171,72 @@ class SetupCommand extends base_command_1.BaseCommand {
|
|
|
1126
1171
|
label: "Codex CLI, VS Code extension, and Codex app",
|
|
1127
1172
|
detected: codexDetected,
|
|
1128
1173
|
recommended: true,
|
|
1174
|
+
icon: "◎",
|
|
1175
|
+
siteUrl: "https://openai.com/codex",
|
|
1129
1176
|
},
|
|
1130
1177
|
{
|
|
1131
1178
|
id: "continue",
|
|
1132
1179
|
label: "Continue",
|
|
1133
1180
|
detected: continueDetected,
|
|
1134
1181
|
recommended: true,
|
|
1182
|
+
icon: "▶",
|
|
1183
|
+
siteUrl: "https://continue.dev",
|
|
1135
1184
|
},
|
|
1136
1185
|
{
|
|
1137
1186
|
id: "cline",
|
|
1138
1187
|
label: "Cline",
|
|
1139
1188
|
detected: clineDetected,
|
|
1140
1189
|
recommended: true,
|
|
1190
|
+
icon: "◈",
|
|
1191
|
+
siteUrl: "https://cline.bot",
|
|
1141
1192
|
},
|
|
1142
1193
|
{
|
|
1143
1194
|
id: "openclaw",
|
|
1144
1195
|
label: "OpenClaw",
|
|
1145
1196
|
detected: hasCommand("openclaw"),
|
|
1146
1197
|
recommended: true,
|
|
1198
|
+
icon: "🦞",
|
|
1199
|
+
siteUrl: "https://openclaw.ai",
|
|
1147
1200
|
},
|
|
1148
1201
|
{
|
|
1149
1202
|
id: "opencode",
|
|
1150
1203
|
label: "OpenCode",
|
|
1151
1204
|
detected: hasCommand("opencode"),
|
|
1152
1205
|
recommended: true,
|
|
1206
|
+
icon: "⌘",
|
|
1207
|
+
siteUrl: "https://opencode.ai",
|
|
1153
1208
|
},
|
|
1154
1209
|
{
|
|
1155
1210
|
id: "kilo",
|
|
1156
1211
|
label: "Kilo Code",
|
|
1157
1212
|
detected: kiloDetected,
|
|
1158
1213
|
recommended: true,
|
|
1214
|
+
icon: "⚡",
|
|
1215
|
+
siteUrl: "https://kilo.ai",
|
|
1159
1216
|
},
|
|
1160
1217
|
{
|
|
1161
1218
|
id: "roo",
|
|
1162
1219
|
label: "Roo Code",
|
|
1163
1220
|
detected: rooDetected,
|
|
1164
1221
|
recommended: true,
|
|
1222
|
+
icon: "🦘",
|
|
1223
|
+
siteUrl: "https://roocode.com",
|
|
1165
1224
|
},
|
|
1166
1225
|
{
|
|
1167
1226
|
id: "trae",
|
|
1168
1227
|
label: "Trae (experimental)",
|
|
1169
1228
|
detected: traeDetected,
|
|
1170
1229
|
recommended: false,
|
|
1230
|
+
icon: "△",
|
|
1231
|
+
siteUrl: "https://www.trae.ai",
|
|
1171
1232
|
},
|
|
1172
1233
|
{
|
|
1173
1234
|
id: "aider",
|
|
1174
1235
|
label: "Aider",
|
|
1175
1236
|
detected: aiderDetected,
|
|
1176
1237
|
recommended: true,
|
|
1238
|
+
icon: "✦",
|
|
1239
|
+
siteUrl: "https://aider.chat",
|
|
1177
1240
|
},
|
|
1178
1241
|
];
|
|
1179
1242
|
const selectedSetupClients = await resolveSetupClientSelection({
|
package/package.json
CHANGED