gearbox-code 0.1.6 → 0.1.8
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 +50 -68
- package/dist/cli.mjs +520 -175
- package/install.ps1 +93 -0
- package/install.sh +10 -0
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -1,111 +1,93 @@
|
|
|
1
|
-
#
|
|
1
|
+
# gearbox
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
## Install
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
macOS, Linux, WSL:
|
|
6
6
|
|
|
7
|
+
```bash
|
|
8
|
+
curl -fsSL https://unpkg.com/gearbox-code@latest/install.sh | bash
|
|
7
9
|
```
|
|
8
|
-
⚙ gearbox
|
|
9
|
-
coding harness · sonnet-4.6
|
|
10
|
-
──────────────────────────────────────────────────────────
|
|
11
|
-
|
|
12
|
-
› add a --json flag to the CLI and cover it with a test
|
|
13
10
|
|
|
14
|
-
|
|
11
|
+
Windows PowerShell:
|
|
15
12
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
✓ edit_file src/cli.tsx
|
|
19
|
-
✓ run_shell bun test
|
|
20
|
-
9 pass · 0 fail
|
|
21
|
-
|
|
22
|
-
⏺ Done — flag added with a passing test.
|
|
23
|
-
|
|
24
|
-
╭──────────────────────────────────────────────────────────╮
|
|
25
|
-
│ › ask gearbox to build or fix something │
|
|
26
|
-
╰──────────────────────────────────────────────────────────╯
|
|
27
|
-
gearbox · sonnet-4.6 · 18,432 tok · ⏎ send ctrl+c quit
|
|
13
|
+
```powershell
|
|
14
|
+
irm https://unpkg.com/gearbox-code@latest/install.ps1 | iex
|
|
28
15
|
```
|
|
29
16
|
|
|
30
|
-
|
|
17
|
+
These installers do not use `sudo`, admin privileges, or `npm install -g`.
|
|
18
|
+
They install Gearbox into a user-owned directory, create the `gearbox` command,
|
|
19
|
+
then start onboarding before the coding app opens.
|
|
20
|
+
|
|
21
|
+
Run without installing:
|
|
31
22
|
|
|
32
23
|
```bash
|
|
33
|
-
|
|
34
|
-
gearbox auth add <api-key> # paste-detects common providers when possible
|
|
35
|
-
# or: gearbox auth add <provider> <api-key>
|
|
36
|
-
# or: gearbox auth import # import keys from env/cloud credentials
|
|
37
|
-
bun start # or: bun run src/cli.tsx
|
|
38
|
-
bun start -- --model gemini-flash # pick a model
|
|
24
|
+
npx gearbox-code@latest
|
|
39
25
|
```
|
|
40
26
|
|
|
41
|
-
|
|
27
|
+
## First Run
|
|
28
|
+
|
|
29
|
+
Gearbox needs one provider account before it opens the coding app. The installer
|
|
30
|
+
runs setup automatically. You can also run it yourself:
|
|
42
31
|
|
|
43
32
|
```bash
|
|
44
|
-
|
|
33
|
+
gearbox onboard
|
|
45
34
|
```
|
|
46
35
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
One command, no sudo, no npm global permissions:
|
|
36
|
+
Common setup commands:
|
|
50
37
|
|
|
51
38
|
```bash
|
|
52
|
-
|
|
39
|
+
gearbox auth add <api-key> # auto-detects known key prefixes
|
|
40
|
+
gearbox auth add <provider> <api-key> # anthropic, openai, google, deepseek, openrouter, groq, xai, mistral...
|
|
41
|
+
gearbox auth import # import credentials from env/cloud config
|
|
42
|
+
gearbox auth providers # list supported providers
|
|
53
43
|
```
|
|
54
44
|
|
|
55
|
-
|
|
56
|
-
`gearbox-code` tarball, and creates a user-owned `gearbox` command in
|
|
57
|
-
`~/.local/bin`.
|
|
58
|
-
|
|
59
|
-
Then:
|
|
45
|
+
After setup:
|
|
60
46
|
|
|
61
47
|
```bash
|
|
62
|
-
|
|
63
|
-
|
|
48
|
+
cd ~/your-project
|
|
49
|
+
gearbox
|
|
64
50
|
```
|
|
65
51
|
|
|
66
|
-
|
|
67
|
-
add to your shell config.
|
|
52
|
+
No account configured means no fake/demo model: Gearbox runs onboarding first.
|
|
68
53
|
|
|
69
|
-
|
|
54
|
+
## Uninstall
|
|
55
|
+
|
|
56
|
+
macOS, Linux, WSL:
|
|
70
57
|
|
|
71
58
|
```bash
|
|
72
|
-
|
|
59
|
+
rm -f ~/.local/bin/gearbox
|
|
60
|
+
rm -rf ~/.local/share/gearbox
|
|
73
61
|
```
|
|
74
62
|
|
|
75
|
-
|
|
76
|
-
for git checkouts.
|
|
63
|
+
Windows PowerShell:
|
|
77
64
|
|
|
78
|
-
|
|
65
|
+
```powershell
|
|
66
|
+
Remove-Item "$env:LOCALAPPDATA\Gearbox" -Recurse -Force
|
|
67
|
+
```
|
|
79
68
|
|
|
80
|
-
|
|
69
|
+
If you previously installed with npm global:
|
|
81
70
|
|
|
82
71
|
```bash
|
|
83
|
-
|
|
84
|
-
bun run src/cli.tsx
|
|
72
|
+
npm uninstall -g gearbox-code
|
|
85
73
|
```
|
|
86
74
|
|
|
87
|
-
|
|
75
|
+
## What It Is
|
|
88
76
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
```
|
|
77
|
+
Gearbox is a terminal coding agent that can use the model accounts you already
|
|
78
|
+
pay for. It supports provider accounts, local credential storage, model routing,
|
|
79
|
+
session history, file edits, shell commands, and permission gates.
|
|
93
80
|
|
|
94
|
-
|
|
81
|
+
Supported setup paths include API keys, detected env/cloud credentials, Azure,
|
|
82
|
+
and provider CLIs where available.
|
|
95
83
|
|
|
96
84
|
## Develop
|
|
97
85
|
|
|
86
|
+
Requires [Bun](https://bun.sh).
|
|
87
|
+
|
|
98
88
|
```bash
|
|
99
|
-
bun
|
|
89
|
+
bun install
|
|
90
|
+
bun run src/cli.tsx
|
|
91
|
+
bun test
|
|
100
92
|
bun run typecheck
|
|
101
93
|
```
|
|
102
|
-
|
|
103
|
-
## Principles
|
|
104
|
-
|
|
105
|
-
- **Open + free.** MIT. No paid dependencies, no hosted backend, no telemetry. The only cost is your own model calls on your own keys.
|
|
106
|
-
- **Beautiful + calm.** One accent color, generous spacing, consistent glyphs. The whole look lives in `src/ui/theme.ts`.
|
|
107
|
-
- **Routing-ready.** Model choice happens in exactly one place (`src/model/selector.ts`); the router drops in there later with no changes upstream. See [`CLAUDE.md`](./CLAUDE.md).
|
|
108
|
-
|
|
109
|
-
## Status
|
|
110
|
-
|
|
111
|
-
v0.1 — streaming agent loop, real file + shell tools, a polished Ink TUI, multi-provider support, accounts + spend ledger, BM25 context retrieval, and basic per-task routing (classify → quality bar → cheapest winner). The richer routing engine (shadow-eval, credit/limit/plan scoring, per-repo calibration) is next (`DESIGN.md`).
|
package/dist/cli.mjs
CHANGED
|
@@ -63894,8 +63894,18 @@ var require_src6 = __commonJS((exports) => {
|
|
|
63894
63894
|
});
|
|
63895
63895
|
|
|
63896
63896
|
// src/proc.ts
|
|
63897
|
+
var exports_proc = {};
|
|
63898
|
+
__export(exports_proc, {
|
|
63899
|
+
write: () => writeFile,
|
|
63900
|
+
which: () => which,
|
|
63901
|
+
spawnSyncProc: () => spawnSyncProc,
|
|
63902
|
+
spawnProc: () => spawnProc,
|
|
63903
|
+
readStream: () => readStream,
|
|
63904
|
+
Glob: () => Glob
|
|
63905
|
+
});
|
|
63897
63906
|
import { spawn, spawnSync as nodeSpawnSync, execFileSync } from "node:child_process";
|
|
63898
63907
|
import { readdirSync as readdirSync2, statSync as statSync2 } from "node:fs";
|
|
63908
|
+
import { writeFile } from "node:fs/promises";
|
|
63899
63909
|
import { resolve as resolve6 } from "node:path";
|
|
63900
63910
|
function which(bin) {
|
|
63901
63911
|
try {
|
|
@@ -64270,6 +64280,13 @@ var init_onboarding = __esm(() => {
|
|
|
64270
64280
|
});
|
|
64271
64281
|
|
|
64272
64282
|
// src/agent/cli-backend.ts
|
|
64283
|
+
var exports_cli_backend = {};
|
|
64284
|
+
__export(exports_cli_backend, {
|
|
64285
|
+
subscriptionEnv: () => subscriptionEnv,
|
|
64286
|
+
runCliTask: () => runCliTask,
|
|
64287
|
+
parseCliLines: () => parseCliLines,
|
|
64288
|
+
buildCliArgs: () => buildCliArgs
|
|
64289
|
+
});
|
|
64273
64290
|
function newState() {
|
|
64274
64291
|
return { text: "", usage: { inputTokens: 0, outputTokens: 0 }, rates: new Map, toolNames: new Map };
|
|
64275
64292
|
}
|
|
@@ -64407,6 +64424,22 @@ function buildCliArgs(binary, prompt, opts = {}) {
|
|
|
64407
64424
|
args.push("--resume", opts.sessionId);
|
|
64408
64425
|
return args;
|
|
64409
64426
|
}
|
|
64427
|
+
function parseCliLines(binary, lines, onEvent) {
|
|
64428
|
+
const state = newState();
|
|
64429
|
+
for (const line of lines) {
|
|
64430
|
+
const t2 = line.trim();
|
|
64431
|
+
if (!t2)
|
|
64432
|
+
continue;
|
|
64433
|
+
let obj;
|
|
64434
|
+
try {
|
|
64435
|
+
obj = JSON.parse(t2);
|
|
64436
|
+
} catch {
|
|
64437
|
+
continue;
|
|
64438
|
+
}
|
|
64439
|
+
mapCliEvent(binary, obj, state, onEvent);
|
|
64440
|
+
}
|
|
64441
|
+
return finalize(state);
|
|
64442
|
+
}
|
|
64410
64443
|
function finalize(state) {
|
|
64411
64444
|
return { messages: [], usage: state.usage, sessionId: state.sessionId, costUSD: state.costUSD, rates: [...state.rates.values()] };
|
|
64412
64445
|
}
|
|
@@ -70267,7 +70300,8 @@ var import_react20 = __toESM(require_react(), 1);
|
|
|
70267
70300
|
// node_modules/ink/build/hooks/use-focus-manager.js
|
|
70268
70301
|
var import_react21 = __toESM(require_react(), 1);
|
|
70269
70302
|
// src/cli.tsx
|
|
70270
|
-
import {
|
|
70303
|
+
import { createInterface } from "node:readline/promises";
|
|
70304
|
+
import { execFileSync as execFileSync4, spawnSync } from "node:child_process";
|
|
70271
70305
|
import { resolve as resolve11 } from "node:path";
|
|
70272
70306
|
import { existsSync as existsSync8 } from "node:fs";
|
|
70273
70307
|
|
|
@@ -121288,6 +121322,9 @@ function pickDefaultModel(preferredId) {
|
|
|
121288
121322
|
return wanted;
|
|
121289
121323
|
return MODELS.find((m2) => providerAvailable(m2.provider));
|
|
121290
121324
|
}
|
|
121325
|
+
function anyProviderAvailable() {
|
|
121326
|
+
return MODELS.some((m2) => providerAvailable(m2.provider));
|
|
121327
|
+
}
|
|
121291
121328
|
|
|
121292
121329
|
// src/model/selector.ts
|
|
121293
121330
|
class FixedSelector {
|
|
@@ -131808,7 +131845,7 @@ var uiMessagesSchema = lazyValidator3(() => zodSchema7(exports_external.array(ex
|
|
|
131808
131845
|
})).nonempty("Messages array must not be empty")));
|
|
131809
131846
|
|
|
131810
131847
|
// src/tools.ts
|
|
131811
|
-
import { readFile, writeFile, readdir, stat as stat2 } from "node:fs/promises";
|
|
131848
|
+
import { readFile, writeFile as writeFile2, readdir, stat as stat2 } from "node:fs/promises";
|
|
131812
131849
|
import { existsSync as existsSync3 } from "node:fs";
|
|
131813
131850
|
import { resolve as resolve7, relative, isAbsolute } from "node:path";
|
|
131814
131851
|
// node_modules/diff/libesm/diff/base.js
|
|
@@ -132171,7 +132208,7 @@ function createTools(onEvent) {
|
|
|
132171
132208
|
if (!await requestPermission({ kind: "write", title: exists ? "Overwrite a file" : "Create a file", detail: path }))
|
|
132172
132209
|
throw new Error(DENIED);
|
|
132173
132210
|
const before2 = exists ? await readFile(abs, "utf8") : "";
|
|
132174
|
-
await
|
|
132211
|
+
await writeFile2(abs, content, "utf8");
|
|
132175
132212
|
const diff2 = computeDiff(before2, content);
|
|
132176
132213
|
return { summary: `wrote ${path} (${diffStat(diff2)})`, diff: diff2 };
|
|
132177
132214
|
}
|
|
@@ -132187,7 +132224,7 @@ function createTools(onEvent) {
|
|
|
132187
132224
|
if (!await requestPermission({ kind: "edit", title: "Edit a file", detail: path }))
|
|
132188
132225
|
throw new Error(DENIED);
|
|
132189
132226
|
const after2 = before2.replace(find2, replace2);
|
|
132190
|
-
await
|
|
132227
|
+
await writeFile2(abs, after2, "utf8");
|
|
132191
132228
|
const diff2 = computeDiff(before2, after2);
|
|
132192
132229
|
return { summary: `edited ${path} (${diffStat(diff2)})`, diff: diff2 };
|
|
132193
132230
|
}
|
|
@@ -133686,6 +133723,235 @@ function ActivityRail({ items, width }) {
|
|
|
133686
133723
|
]
|
|
133687
133724
|
}, undefined, true, undefined, this);
|
|
133688
133725
|
}
|
|
133726
|
+
function SetupSplash({ state, width, skin, splashSize }) {
|
|
133727
|
+
const providers = featuredApiKeyProviders().slice(0, width >= 92 ? 12 : 8);
|
|
133728
|
+
const left = providers.filter((_, i2) => i2 % 2 === 0);
|
|
133729
|
+
const right = providers.filter((_, i2) => i2 % 2 === 1);
|
|
133730
|
+
const detected = state.importable.length + state.cloudImportable.length;
|
|
133731
|
+
const panelWidth = Math.min(Math.max(width - 4, 12), 104);
|
|
133732
|
+
const showTwoCols = panelWidth >= 82;
|
|
133733
|
+
const firstColumn = showTwoCols ? left : providers;
|
|
133734
|
+
const secondColumn = showTwoCols ? right : [];
|
|
133735
|
+
const providerLine = (id, label) => /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
|
|
133736
|
+
color: color.dim,
|
|
133737
|
+
children: [
|
|
133738
|
+
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
|
|
133739
|
+
color: color.accent,
|
|
133740
|
+
children: [
|
|
133741
|
+
"/account add ",
|
|
133742
|
+
id
|
|
133743
|
+
]
|
|
133744
|
+
}, undefined, true, undefined, this),
|
|
133745
|
+
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
|
|
133746
|
+
color: color.faint,
|
|
133747
|
+
children: [
|
|
133748
|
+
" ",
|
|
133749
|
+
label
|
|
133750
|
+
]
|
|
133751
|
+
}, undefined, true, undefined, this)
|
|
133752
|
+
]
|
|
133753
|
+
}, id, true, undefined, this);
|
|
133754
|
+
return /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
|
|
133755
|
+
flexDirection: "column",
|
|
133756
|
+
alignItems: "center",
|
|
133757
|
+
children: [
|
|
133758
|
+
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(MascotSplash, {
|
|
133759
|
+
skin,
|
|
133760
|
+
size: splashSize
|
|
133761
|
+
}, undefined, false, undefined, this),
|
|
133762
|
+
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
|
|
133763
|
+
marginTop: 1,
|
|
133764
|
+
flexDirection: "column",
|
|
133765
|
+
alignItems: "center",
|
|
133766
|
+
children: [
|
|
133767
|
+
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
|
|
133768
|
+
color: color.accent,
|
|
133769
|
+
bold: true,
|
|
133770
|
+
children: "GEARBOX"
|
|
133771
|
+
}, undefined, false, undefined, this),
|
|
133772
|
+
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
|
|
133773
|
+
color: color.text,
|
|
133774
|
+
children: "one terminal, every model account you already pay for"
|
|
133775
|
+
}, undefined, false, undefined, this),
|
|
133776
|
+
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
|
|
133777
|
+
color: color.faint,
|
|
133778
|
+
children: "Set up one provider. Gearbox routes from there."
|
|
133779
|
+
}, undefined, false, undefined, this)
|
|
133780
|
+
]
|
|
133781
|
+
}, undefined, true, undefined, this),
|
|
133782
|
+
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
|
|
133783
|
+
marginTop: 1,
|
|
133784
|
+
width: panelWidth,
|
|
133785
|
+
borderStyle: "round",
|
|
133786
|
+
borderColor: color.accentDim,
|
|
133787
|
+
paddingX: 2,
|
|
133788
|
+
paddingY: 1,
|
|
133789
|
+
flexDirection: "column",
|
|
133790
|
+
children: [
|
|
133791
|
+
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
|
|
133792
|
+
justifyContent: "space-between",
|
|
133793
|
+
children: [
|
|
133794
|
+
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
|
|
133795
|
+
color: color.text,
|
|
133796
|
+
bold: true,
|
|
133797
|
+
children: "start here"
|
|
133798
|
+
}, undefined, false, undefined, this),
|
|
133799
|
+
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
|
|
133800
|
+
color: detected ? color.ok : color.faint,
|
|
133801
|
+
children: detected ? `${detected} detected` : "no account yet"
|
|
133802
|
+
}, undefined, false, undefined, this)
|
|
133803
|
+
]
|
|
133804
|
+
}, undefined, true, undefined, this),
|
|
133805
|
+
detected ? /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
|
|
133806
|
+
marginTop: 1,
|
|
133807
|
+
children: [
|
|
133808
|
+
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
|
|
133809
|
+
color: color.ok,
|
|
133810
|
+
children: [
|
|
133811
|
+
glyph.on,
|
|
133812
|
+
" "
|
|
133813
|
+
]
|
|
133814
|
+
}, undefined, true, undefined, this),
|
|
133815
|
+
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
|
|
133816
|
+
color: color.text,
|
|
133817
|
+
children: "Credentials found on this machine: "
|
|
133818
|
+
}, undefined, false, undefined, this),
|
|
133819
|
+
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
|
|
133820
|
+
color: color.accent,
|
|
133821
|
+
children: "/account import"
|
|
133822
|
+
}, undefined, false, undefined, this)
|
|
133823
|
+
]
|
|
133824
|
+
}, undefined, true, undefined, this) : null,
|
|
133825
|
+
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
|
|
133826
|
+
marginTop: 1,
|
|
133827
|
+
flexDirection: showTwoCols ? "row" : "column",
|
|
133828
|
+
children: [
|
|
133829
|
+
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
|
|
133830
|
+
flexDirection: "column",
|
|
133831
|
+
width: showTwoCols ? Math.floor((panelWidth - 6) / 2) : undefined,
|
|
133832
|
+
children: [
|
|
133833
|
+
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
|
|
133834
|
+
color: color.faint,
|
|
133835
|
+
children: "API key"
|
|
133836
|
+
}, undefined, false, undefined, this),
|
|
133837
|
+
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
|
|
133838
|
+
color: color.text,
|
|
133839
|
+
children: [
|
|
133840
|
+
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
|
|
133841
|
+
color: color.accent,
|
|
133842
|
+
children: "/account add <api-key>"
|
|
133843
|
+
}, undefined, false, undefined, this),
|
|
133844
|
+
" auto-detect when possible"
|
|
133845
|
+
]
|
|
133846
|
+
}, undefined, true, undefined, this),
|
|
133847
|
+
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
|
|
133848
|
+
color: color.text,
|
|
133849
|
+
children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
|
|
133850
|
+
color: color.accent,
|
|
133851
|
+
children: "/account add <provider> <api-key>"
|
|
133852
|
+
}, undefined, false, undefined, this)
|
|
133853
|
+
}, undefined, false, undefined, this)
|
|
133854
|
+
]
|
|
133855
|
+
}, undefined, true, undefined, this),
|
|
133856
|
+
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
|
|
133857
|
+
flexDirection: "column",
|
|
133858
|
+
marginLeft: showTwoCols ? 4 : 0,
|
|
133859
|
+
marginTop: showTwoCols ? 0 : 1,
|
|
133860
|
+
children: [
|
|
133861
|
+
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
|
|
133862
|
+
color: color.faint,
|
|
133863
|
+
children: "Subscriptions and cloud"
|
|
133864
|
+
}, undefined, false, undefined, this),
|
|
133865
|
+
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
|
|
133866
|
+
color: color.text,
|
|
133867
|
+
children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
|
|
133868
|
+
color: color.accent,
|
|
133869
|
+
children: "/account add azure <endpoint> <api-key>"
|
|
133870
|
+
}, undefined, false, undefined, this)
|
|
133871
|
+
}, undefined, false, undefined, this),
|
|
133872
|
+
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
|
|
133873
|
+
color: color.text,
|
|
133874
|
+
children: [
|
|
133875
|
+
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
|
|
133876
|
+
color: color.accent,
|
|
133877
|
+
children: "/account add claude"
|
|
133878
|
+
}, undefined, false, undefined, this),
|
|
133879
|
+
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
|
|
133880
|
+
color: color.faint,
|
|
133881
|
+
children: " "
|
|
133882
|
+
}, undefined, false, undefined, this),
|
|
133883
|
+
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
|
|
133884
|
+
color: color.accent,
|
|
133885
|
+
children: "/account add codex"
|
|
133886
|
+
}, undefined, false, undefined, this)
|
|
133887
|
+
]
|
|
133888
|
+
}, undefined, true, undefined, this)
|
|
133889
|
+
]
|
|
133890
|
+
}, undefined, true, undefined, this)
|
|
133891
|
+
]
|
|
133892
|
+
}, undefined, true, undefined, this),
|
|
133893
|
+
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
|
|
133894
|
+
marginTop: 1,
|
|
133895
|
+
children: /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
|
|
133896
|
+
color: color.faint,
|
|
133897
|
+
children: glyph.rule.repeat(Math.max(panelWidth - 6, 20))
|
|
133898
|
+
}, undefined, false, undefined, this)
|
|
133899
|
+
}, undefined, false, undefined, this),
|
|
133900
|
+
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
|
|
133901
|
+
marginTop: 1,
|
|
133902
|
+
flexDirection: showTwoCols ? "row" : "column",
|
|
133903
|
+
children: [
|
|
133904
|
+
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
|
|
133905
|
+
flexDirection: "column",
|
|
133906
|
+
width: showTwoCols ? Math.floor((panelWidth - 6) / 2) : undefined,
|
|
133907
|
+
children: [
|
|
133908
|
+
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
|
|
133909
|
+
color: color.faint,
|
|
133910
|
+
children: "Common providers"
|
|
133911
|
+
}, undefined, false, undefined, this),
|
|
133912
|
+
firstColumn.map((p) => providerLine(p.id, p.label))
|
|
133913
|
+
]
|
|
133914
|
+
}, undefined, true, undefined, this),
|
|
133915
|
+
secondColumn.length ? /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
|
|
133916
|
+
flexDirection: "column",
|
|
133917
|
+
marginLeft: 4,
|
|
133918
|
+
children: [
|
|
133919
|
+
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
|
|
133920
|
+
color: color.faint,
|
|
133921
|
+
children: " "
|
|
133922
|
+
}, undefined, false, undefined, this),
|
|
133923
|
+
secondColumn.map((p) => providerLine(p.id, p.label))
|
|
133924
|
+
]
|
|
133925
|
+
}, undefined, true, undefined, this) : null
|
|
133926
|
+
]
|
|
133927
|
+
}, undefined, true, undefined, this),
|
|
133928
|
+
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
|
|
133929
|
+
marginTop: 1,
|
|
133930
|
+
justifyContent: "space-between",
|
|
133931
|
+
children: [
|
|
133932
|
+
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
|
|
133933
|
+
color: color.faint,
|
|
133934
|
+
children: "Full catalog: "
|
|
133935
|
+
}, undefined, false, undefined, this),
|
|
133936
|
+
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
|
|
133937
|
+
color: color.accent,
|
|
133938
|
+
children: "/onboard providers"
|
|
133939
|
+
}, undefined, false, undefined, this),
|
|
133940
|
+
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
|
|
133941
|
+
color: color.faint,
|
|
133942
|
+
children: " Help: "
|
|
133943
|
+
}, undefined, false, undefined, this),
|
|
133944
|
+
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
|
|
133945
|
+
color: color.accent,
|
|
133946
|
+
children: "/account"
|
|
133947
|
+
}, undefined, false, undefined, this)
|
|
133948
|
+
]
|
|
133949
|
+
}, undefined, true, undefined, this)
|
|
133950
|
+
]
|
|
133951
|
+
}, undefined, true, undefined, this)
|
|
133952
|
+
]
|
|
133953
|
+
}, undefined, true, undefined, this);
|
|
133954
|
+
}
|
|
133689
133955
|
function App2({ selector: initialSelector, runner, fullscreen = false, resumeId }) {
|
|
133690
133956
|
const { exit } = use_app_default();
|
|
133691
133957
|
const { stdin, isRawModeSupported, setRawMode } = use_stdin_default();
|
|
@@ -135727,176 +135993,92 @@ function App2({ selector: initialSelector, runner, fullscreen = false, resumeId
|
|
|
135727
135993
|
const hero = /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
|
|
135728
135994
|
flexDirection: "column",
|
|
135729
135995
|
alignItems: "center",
|
|
135730
|
-
children:
|
|
135731
|
-
|
|
135732
|
-
|
|
135733
|
-
|
|
135734
|
-
|
|
135735
|
-
|
|
135736
|
-
|
|
135737
|
-
|
|
135738
|
-
|
|
135739
|
-
|
|
135740
|
-
|
|
135741
|
-
|
|
135742
|
-
|
|
135743
|
-
|
|
135744
|
-
|
|
135745
|
-
|
|
135746
|
-
|
|
135747
|
-
|
|
135748
|
-
|
|
135749
|
-
|
|
135750
|
-
|
|
135751
|
-
|
|
135752
|
-
|
|
135753
|
-
|
|
135754
|
-
|
|
135755
|
-
|
|
135756
|
-
|
|
135757
|
-
|
|
135758
|
-
|
|
135759
|
-
|
|
135760
|
-
|
|
135761
|
-
|
|
135762
|
-
|
|
135763
|
-
|
|
135764
|
-
|
|
135765
|
-
|
|
135766
|
-
|
|
135767
|
-
|
|
135768
|
-
|
|
135769
|
-
|
|
135770
|
-
|
|
135771
|
-
|
|
135772
|
-
|
|
135773
|
-
|
|
135774
|
-
|
|
135775
|
-
|
|
135776
|
-
|
|
135777
|
-
|
|
135778
|
-
|
|
135779
|
-
|
|
135780
|
-
|
|
135781
|
-
|
|
135782
|
-
|
|
135783
|
-
|
|
135784
|
-
|
|
135785
|
-
|
|
135786
|
-
|
|
135787
|
-
|
|
135788
|
-
|
|
135789
|
-
|
|
135790
|
-
|
|
135791
|
-
|
|
135792
|
-
|
|
135793
|
-
|
|
135794
|
-
|
|
135795
|
-
|
|
135796
|
-
|
|
135797
|
-
|
|
135798
|
-
|
|
135799
|
-
|
|
135800
|
-
|
|
135801
|
-
|
|
135802
|
-
|
|
135803
|
-
|
|
135804
|
-
|
|
135805
|
-
|
|
135806
|
-
|
|
135807
|
-
|
|
135808
|
-
|
|
135809
|
-
|
|
135810
|
-
|
|
135811
|
-
|
|
135812
|
-
|
|
135813
|
-
|
|
135814
|
-
|
|
135815
|
-
|
|
135816
|
-
onboardingState.hasClaudeCli ? "/account add claude" : "",
|
|
135817
|
-
onboardingState.hasClaudeCli && onboardingState.hasCodexCli ? " · " : "",
|
|
135818
|
-
onboardingState.hasCodexCli ? "/account add codex" : ""
|
|
135819
|
-
]
|
|
135820
|
-
}, undefined, true, undefined, this) : null
|
|
135821
|
-
]
|
|
135822
|
-
}, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(jsx_dev_runtime12.Fragment, {
|
|
135823
|
-
children: [
|
|
135824
|
-
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
|
|
135825
|
-
marginTop: 1,
|
|
135826
|
-
children: [
|
|
135827
|
-
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
|
|
135828
|
-
color: color.dim,
|
|
135829
|
-
children: "talk or type "
|
|
135830
|
-
}, undefined, false, undefined, this),
|
|
135831
|
-
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
|
|
135832
|
-
color: color.faint,
|
|
135833
|
-
children: [
|
|
135834
|
-
glyph.bullet,
|
|
135835
|
-
" "
|
|
135836
|
-
]
|
|
135837
|
-
}, undefined, true, undefined, this),
|
|
135838
|
-
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
|
|
135839
|
-
color: color.accentDim,
|
|
135840
|
-
children: "/"
|
|
135841
|
-
}, undefined, false, undefined, this),
|
|
135842
|
-
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
|
|
135843
|
-
color: color.dim,
|
|
135844
|
-
children: "commands "
|
|
135845
|
-
}, undefined, false, undefined, this),
|
|
135846
|
-
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
|
|
135847
|
-
color: color.accentDim,
|
|
135848
|
-
children: "@"
|
|
135849
|
-
}, undefined, false, undefined, this),
|
|
135850
|
-
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
|
|
135851
|
-
color: color.dim,
|
|
135852
|
-
children: "files "
|
|
135853
|
-
}, undefined, false, undefined, this),
|
|
135854
|
-
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
|
|
135855
|
-
color: color.accentDim,
|
|
135856
|
-
children: "!"
|
|
135857
|
-
}, undefined, false, undefined, this),
|
|
135858
|
-
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
|
|
135859
|
-
color: color.dim,
|
|
135860
|
-
children: "shell"
|
|
135861
|
-
}, undefined, false, undefined, this)
|
|
135862
|
-
]
|
|
135863
|
-
}, undefined, true, undefined, this),
|
|
135864
|
-
firstRunRef.current ? /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
|
|
135865
|
-
marginTop: 1,
|
|
135866
|
-
flexDirection: "column",
|
|
135867
|
-
alignItems: "center",
|
|
135868
|
-
children: [
|
|
135869
|
-
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
|
|
135870
|
-
color: color.faint,
|
|
135871
|
-
children: [
|
|
135872
|
-
"new here? press ",
|
|
135873
|
-
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
|
|
135874
|
-
color: color.accent,
|
|
135875
|
-
children: "?"
|
|
135876
|
-
}, undefined, false, undefined, this),
|
|
135877
|
-
" for shortcuts · ",
|
|
135878
|
-
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
|
|
135879
|
-
color: color.accent,
|
|
135880
|
-
children: "shift+tab"
|
|
135881
|
-
}, undefined, false, undefined, this),
|
|
135882
|
-
" cycles modes · ",
|
|
135883
|
-
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
|
|
135884
|
-
color: color.accent,
|
|
135885
|
-
children: "⌃Y"
|
|
135886
|
-
}, undefined, false, undefined, this),
|
|
135887
|
-
" copies the last reply"
|
|
135888
|
-
]
|
|
135889
|
-
}, undefined, true, undefined, this),
|
|
135890
|
-
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
|
|
135891
|
-
color: color.faint,
|
|
135892
|
-
children: "/config inline on for terminal scrollback · /keys for shortcuts"
|
|
135893
|
-
}, undefined, false, undefined, this)
|
|
135894
|
-
]
|
|
135895
|
-
}, undefined, true, undefined, this) : null
|
|
135896
|
-
]
|
|
135897
|
-
}, undefined, true, undefined, this)
|
|
135898
|
-
]
|
|
135899
|
-
}, undefined, true, undefined, this);
|
|
135996
|
+
children: setupRequired ? /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(SetupSplash, {
|
|
135997
|
+
state: onboardingState,
|
|
135998
|
+
width,
|
|
135999
|
+
skin: ghostSkin,
|
|
136000
|
+
splashSize
|
|
136001
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(jsx_dev_runtime12.Fragment, {
|
|
136002
|
+
children: [
|
|
136003
|
+
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(MascotSplash, {
|
|
136004
|
+
skin: ghostSkin,
|
|
136005
|
+
size: splashSize
|
|
136006
|
+
}, undefined, false, undefined, this),
|
|
136007
|
+
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
|
|
136008
|
+
marginTop: 1,
|
|
136009
|
+
children: [
|
|
136010
|
+
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
|
|
136011
|
+
color: color.dim,
|
|
136012
|
+
children: "talk or type "
|
|
136013
|
+
}, undefined, false, undefined, this),
|
|
136014
|
+
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
|
|
136015
|
+
color: color.faint,
|
|
136016
|
+
children: [
|
|
136017
|
+
glyph.bullet,
|
|
136018
|
+
" "
|
|
136019
|
+
]
|
|
136020
|
+
}, undefined, true, undefined, this),
|
|
136021
|
+
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
|
|
136022
|
+
color: color.accentDim,
|
|
136023
|
+
children: "/"
|
|
136024
|
+
}, undefined, false, undefined, this),
|
|
136025
|
+
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
|
|
136026
|
+
color: color.dim,
|
|
136027
|
+
children: "commands "
|
|
136028
|
+
}, undefined, false, undefined, this),
|
|
136029
|
+
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
|
|
136030
|
+
color: color.accentDim,
|
|
136031
|
+
children: "@"
|
|
136032
|
+
}, undefined, false, undefined, this),
|
|
136033
|
+
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
|
|
136034
|
+
color: color.dim,
|
|
136035
|
+
children: "files "
|
|
136036
|
+
}, undefined, false, undefined, this),
|
|
136037
|
+
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
|
|
136038
|
+
color: color.accentDim,
|
|
136039
|
+
children: "!"
|
|
136040
|
+
}, undefined, false, undefined, this),
|
|
136041
|
+
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
|
|
136042
|
+
color: color.dim,
|
|
136043
|
+
children: "shell"
|
|
136044
|
+
}, undefined, false, undefined, this)
|
|
136045
|
+
]
|
|
136046
|
+
}, undefined, true, undefined, this),
|
|
136047
|
+
firstRunRef.current ? /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
|
|
136048
|
+
marginTop: 1,
|
|
136049
|
+
flexDirection: "column",
|
|
136050
|
+
alignItems: "center",
|
|
136051
|
+
children: [
|
|
136052
|
+
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
|
|
136053
|
+
color: color.faint,
|
|
136054
|
+
children: [
|
|
136055
|
+
"new here? press ",
|
|
136056
|
+
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
|
|
136057
|
+
color: color.accent,
|
|
136058
|
+
children: "?"
|
|
136059
|
+
}, undefined, false, undefined, this),
|
|
136060
|
+
" for shortcuts · ",
|
|
136061
|
+
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
|
|
136062
|
+
color: color.accent,
|
|
136063
|
+
children: "shift+tab"
|
|
136064
|
+
}, undefined, false, undefined, this),
|
|
136065
|
+
" cycles modes · ",
|
|
136066
|
+
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
|
|
136067
|
+
color: color.accent,
|
|
136068
|
+
children: "⌃Y"
|
|
136069
|
+
}, undefined, false, undefined, this),
|
|
136070
|
+
" copies the last reply"
|
|
136071
|
+
]
|
|
136072
|
+
}, undefined, true, undefined, this),
|
|
136073
|
+
/* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Text, {
|
|
136074
|
+
color: color.faint,
|
|
136075
|
+
children: "/config inline on for terminal scrollback · /keys for shortcuts"
|
|
136076
|
+
}, undefined, false, undefined, this)
|
|
136077
|
+
]
|
|
136078
|
+
}, undefined, true, undefined, this) : null
|
|
136079
|
+
]
|
|
136080
|
+
}, undefined, true, undefined, this)
|
|
136081
|
+
}, undefined, false, undefined, this);
|
|
135900
136082
|
const paletteJsx = pickerRows.length || cmdMatches.length || fileMatches.length ? /* @__PURE__ */ jsx_dev_runtime12.jsxDEV(Box_default, {
|
|
135901
136083
|
flexDirection: "column",
|
|
135902
136084
|
children: [
|
|
@@ -136099,8 +136281,153 @@ function App2({ selector: initialSelector, runner, fullscreen = false, resumeId
|
|
|
136099
136281
|
var jsx_dev_runtime13 = __toESM(require_jsx_dev_runtime(), 1);
|
|
136100
136282
|
process.env.LANG = process.env.LANG || "en_US.UTF-8";
|
|
136101
136283
|
process.env.LC_ALL = process.env.LC_ALL || "en_US.UTF-8";
|
|
136102
|
-
var VERSION16 = "0.1.
|
|
136284
|
+
var VERSION16 = "0.1.8";
|
|
136103
136285
|
var args = process.argv.slice(2);
|
|
136286
|
+
async function runCliOnboarding() {
|
|
136287
|
+
const { listAccounts: listAccounts2 } = await Promise.resolve().then(() => (init_store(), exports_store));
|
|
136288
|
+
const { importableEnvCreds: importableEnvCreds2, importEnvCred: importEnvCred2, importableCloudCreds: importableCloudCreds2, importCloudCred: importCloudCred2 } = await Promise.resolve().then(() => (init_detect(), exports_detect));
|
|
136289
|
+
const { addApiKeyAccount: addApiKeyAccount2, addAzureAccount: addAzureAccount2, addAzureFoundryAccount: addAzureFoundryAccount2, addByPastedKey: addByPastedKey2, testAccount: testAccount2, addableProviders: addableProviders2, addCliAccount: addCliAccount2, cliAuthStatus: cliAuthStatus2, cliLoginArgs: cliLoginArgs2 } = await Promise.resolve().then(() => (init_onboard(), exports_onboard));
|
|
136290
|
+
const { subscriptionEnv: subscriptionEnv2 } = await Promise.resolve().then(() => (init_cli_backend(), exports_cli_backend));
|
|
136291
|
+
const { detectProviderByKey: detectProviderByKey2 } = await Promise.resolve().then(() => (init_catalog(), exports_catalog));
|
|
136292
|
+
const { which: which2 } = await Promise.resolve().then(() => (init_proc(), exports_proc));
|
|
136293
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
136294
|
+
const ask = async (q) => (await rl.question(q)).trim();
|
|
136295
|
+
const providerRows = () => addableProviders2().map((p) => ` ${p.id.padEnd(16)} ${p.label}`).join(`
|
|
136296
|
+
`);
|
|
136297
|
+
const testAndReport = async (account) => {
|
|
136298
|
+
console.log("Testing credential...");
|
|
136299
|
+
const t2 = await testAccount2(account);
|
|
136300
|
+
console.log(t2.ok ? `OK: ${t2.message}` : `Stored, but the test failed: ${t2.message}`);
|
|
136301
|
+
};
|
|
136302
|
+
const addSubscription = async (provider) => {
|
|
136303
|
+
const res = addCliAccount2(provider);
|
|
136304
|
+
console.log(res.message);
|
|
136305
|
+
if (!res.ok || !res.account || res.account.auth.kind !== "cli")
|
|
136306
|
+
return false;
|
|
136307
|
+
const bin = res.account.auth.binary;
|
|
136308
|
+
const profile = res.account.auth.loginProfile;
|
|
136309
|
+
let status = await cliAuthStatus2(bin, profile);
|
|
136310
|
+
if (!status.loggedIn) {
|
|
136311
|
+
console.log(`Starting ${bin} sign-in...`);
|
|
136312
|
+
const r2 = spawnSync(bin, cliLoginArgs2(bin), { stdio: "inherit", env: subscriptionEnv2(bin, profile) });
|
|
136313
|
+
if ((r2.status ?? 1) !== 0)
|
|
136314
|
+
return false;
|
|
136315
|
+
status = await cliAuthStatus2(bin, profile);
|
|
136316
|
+
}
|
|
136317
|
+
if (!status.loggedIn) {
|
|
136318
|
+
console.log(`${bin} did not report a completed sign-in.`);
|
|
136319
|
+
return false;
|
|
136320
|
+
}
|
|
136321
|
+
console.log(`OK: ${bin} subscription ready${status.detail ? ` (${status.detail})` : ""}`);
|
|
136322
|
+
return true;
|
|
136323
|
+
};
|
|
136324
|
+
try {
|
|
136325
|
+
console.log("");
|
|
136326
|
+
console.log("Gearbox setup");
|
|
136327
|
+
console.log("One provider account is required before the coding app opens.");
|
|
136328
|
+
console.log("");
|
|
136329
|
+
while (!anyProviderAvailable()) {
|
|
136330
|
+
const env3 = importableEnvCreds2();
|
|
136331
|
+
const cloud = importableCloudCreds2();
|
|
136332
|
+
const existing = listAccounts2();
|
|
136333
|
+
if (existing.length)
|
|
136334
|
+
break;
|
|
136335
|
+
console.log("Choose a setup path:");
|
|
136336
|
+
if (env3.length || cloud.length)
|
|
136337
|
+
console.log(" 1) Import detected credentials");
|
|
136338
|
+
console.log(" 2) Paste an API key");
|
|
136339
|
+
console.log(" 3) Choose provider + API key");
|
|
136340
|
+
console.log(" 4) Azure OpenAI / Azure AI Foundry");
|
|
136341
|
+
if (which2("claude"))
|
|
136342
|
+
console.log(" 5) Claude subscription CLI");
|
|
136343
|
+
if (which2("codex"))
|
|
136344
|
+
console.log(" 6) ChatGPT subscription CLI");
|
|
136345
|
+
console.log(" p) Show providers");
|
|
136346
|
+
console.log(" q) Quit setup");
|
|
136347
|
+
console.log("");
|
|
136348
|
+
const choice = (await ask("Selection: ")).toLowerCase();
|
|
136349
|
+
if (choice === "q" || choice === "quit" || choice === "skip") {
|
|
136350
|
+
console.log("");
|
|
136351
|
+
console.log("Setup skipped. Run `gearbox onboard` when you are ready.");
|
|
136352
|
+
return false;
|
|
136353
|
+
}
|
|
136354
|
+
if (choice === "p" || choice === "providers") {
|
|
136355
|
+
console.log("");
|
|
136356
|
+
console.log(providerRows());
|
|
136357
|
+
console.log("");
|
|
136358
|
+
continue;
|
|
136359
|
+
}
|
|
136360
|
+
if (choice === "1" && (env3.length || cloud.length)) {
|
|
136361
|
+
for (const c of env3)
|
|
136362
|
+
await importEnvCred2(c);
|
|
136363
|
+
for (const c of cloud)
|
|
136364
|
+
await importCloudCred2(c);
|
|
136365
|
+
console.log(`Imported ${env3.length + cloud.length} credential${env3.length + cloud.length === 1 ? "" : "s"}.`);
|
|
136366
|
+
break;
|
|
136367
|
+
}
|
|
136368
|
+
if (choice === "2") {
|
|
136369
|
+
const key = await ask("Paste API key: ");
|
|
136370
|
+
if (!key)
|
|
136371
|
+
continue;
|
|
136372
|
+
const detected = detectProviderByKey2(key);
|
|
136373
|
+
if (!detected) {
|
|
136374
|
+
console.log("Could not detect the provider from that key. Use option 3.");
|
|
136375
|
+
continue;
|
|
136376
|
+
}
|
|
136377
|
+
const res = await addByPastedKey2(key);
|
|
136378
|
+
console.log(res.message);
|
|
136379
|
+
if (res.ok && res.account) {
|
|
136380
|
+
await testAndReport(res.account);
|
|
136381
|
+
break;
|
|
136382
|
+
}
|
|
136383
|
+
continue;
|
|
136384
|
+
}
|
|
136385
|
+
if (choice === "3") {
|
|
136386
|
+
console.log("");
|
|
136387
|
+
console.log(providerRows());
|
|
136388
|
+
console.log("");
|
|
136389
|
+
const provider = await ask("Provider id: ");
|
|
136390
|
+
const key = await ask("API key: ");
|
|
136391
|
+
const res = await addApiKeyAccount2(provider, key);
|
|
136392
|
+
console.log(res.message);
|
|
136393
|
+
if (res.ok && res.account) {
|
|
136394
|
+
await testAndReport(res.account);
|
|
136395
|
+
break;
|
|
136396
|
+
}
|
|
136397
|
+
continue;
|
|
136398
|
+
}
|
|
136399
|
+
if (choice === "4") {
|
|
136400
|
+
const endpoint = await ask("Azure resource name or endpoint: ");
|
|
136401
|
+
const key = await ask("API key: ");
|
|
136402
|
+
const apiVersion = await ask("API version (optional): ");
|
|
136403
|
+
const res = /^https?:\/\//i.test(endpoint) ? await addAzureFoundryAccount2(endpoint, key) : await addAzureAccount2(endpoint, key, { apiVersion: apiVersion || undefined });
|
|
136404
|
+
console.log(res.message);
|
|
136405
|
+
if (res.ok && res.account) {
|
|
136406
|
+
await testAndReport(res.account);
|
|
136407
|
+
break;
|
|
136408
|
+
}
|
|
136409
|
+
continue;
|
|
136410
|
+
}
|
|
136411
|
+
if (choice === "5" && which2("claude")) {
|
|
136412
|
+
if (await addSubscription("claude-cli"))
|
|
136413
|
+
break;
|
|
136414
|
+
continue;
|
|
136415
|
+
}
|
|
136416
|
+
if (choice === "6" && which2("codex")) {
|
|
136417
|
+
if (await addSubscription("codex-cli"))
|
|
136418
|
+
break;
|
|
136419
|
+
continue;
|
|
136420
|
+
}
|
|
136421
|
+
console.log("Choose one of the listed options.");
|
|
136422
|
+
}
|
|
136423
|
+
console.log("");
|
|
136424
|
+
console.log("Gearbox is ready.");
|
|
136425
|
+
console.log("Run `gearbox` inside a project.");
|
|
136426
|
+
return true;
|
|
136427
|
+
} finally {
|
|
136428
|
+
rl.close();
|
|
136429
|
+
}
|
|
136430
|
+
}
|
|
136104
136431
|
if (args[0] === "upgrade" || args[0] === "update") {
|
|
136105
136432
|
const root2 = resolve11(import.meta.dir, "..");
|
|
136106
136433
|
if (!existsSync8(resolve11(root2, ".git"))) {
|
|
@@ -136125,6 +136452,7 @@ if (args.includes("--help") || args.includes("-h")) {
|
|
|
136125
136452
|
|
|
136126
136453
|
Usage:
|
|
136127
136454
|
gearbox start in the current directory (it becomes the workspace)
|
|
136455
|
+
gearbox onboard set up a provider before opening the app
|
|
136128
136456
|
gearbox --model <name> start with a specific model
|
|
136129
136457
|
gearbox --continue resume the most recent session in this directory
|
|
136130
136458
|
gearbox upgrade pull the latest version + reinstall deps
|
|
@@ -136139,6 +136467,7 @@ Options:
|
|
|
136139
136467
|
-h, --help this help
|
|
136140
136468
|
|
|
136141
136469
|
Set up at least one provider first:
|
|
136470
|
+
gearbox onboard
|
|
136142
136471
|
gearbox auth add <api-key>
|
|
136143
136472
|
gearbox auth add <provider> <api-key>
|
|
136144
136473
|
gearbox auth import
|
|
@@ -136151,6 +136480,10 @@ if (args.includes("--version") || args.includes("-v")) {
|
|
|
136151
136480
|
console.log(VERSION16);
|
|
136152
136481
|
process.exit(0);
|
|
136153
136482
|
}
|
|
136483
|
+
if (args[0] === "onboard" || args[0] === "setup") {
|
|
136484
|
+
await runCliOnboarding();
|
|
136485
|
+
process.exit(0);
|
|
136486
|
+
}
|
|
136154
136487
|
if (args[0] === "auth") {
|
|
136155
136488
|
const { listAccounts: listAccounts2, loadAccounts: loadAccounts3, removeAccount: removeAccount2 } = await Promise.resolve().then(() => (init_store(), exports_store));
|
|
136156
136489
|
const { importableEnvCreds: importableEnvCreds2, importEnvCred: importEnvCred2, importableCloudCreds: importableCloudCreds2, importCloudCred: importCloudCred2 } = await Promise.resolve().then(() => (init_detect(), exports_detect));
|
|
@@ -136198,6 +136531,18 @@ Importable from your env (gearbox auth import): ${imp.map((c) => c.envVar).join(
|
|
|
136198
136531
|
}
|
|
136199
136532
|
process.exit(0);
|
|
136200
136533
|
}
|
|
136534
|
+
if (!anyProviderAvailable()) {
|
|
136535
|
+
if (process.stdin.isTTY && process.stdout.isTTY && process.env.GEARBOX_SKIP_ONBOARD !== "1") {
|
|
136536
|
+
const ready = await runCliOnboarding();
|
|
136537
|
+
if (!ready || !anyProviderAvailable())
|
|
136538
|
+
process.exit(0);
|
|
136539
|
+
} else {
|
|
136540
|
+
console.log("Gearbox needs one provider before the coding app can open.");
|
|
136541
|
+
console.log("Run: gearbox onboard");
|
|
136542
|
+
console.log("Or: gearbox auth add <api-key>");
|
|
136543
|
+
process.exit(1);
|
|
136544
|
+
}
|
|
136545
|
+
}
|
|
136201
136546
|
var mi = args.indexOf("--model");
|
|
136202
136547
|
var preferred = mi >= 0 ? args[mi + 1] : undefined;
|
|
136203
136548
|
var pinned = preferred ?? loadPrefs().pinnedModel;
|
package/install.ps1
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
$ErrorActionPreference = "Stop"
|
|
2
|
+
|
|
3
|
+
# Public Gearbox installer for Windows PowerShell.
|
|
4
|
+
#
|
|
5
|
+
# Installs the published npm package into user-owned directories:
|
|
6
|
+
# %LOCALAPPDATA%\Gearbox\versions\<version>\cli.mjs
|
|
7
|
+
# %LOCALAPPDATA%\Gearbox\bin\gearbox.cmd
|
|
8
|
+
#
|
|
9
|
+
# It avoids npm global installs, admin privileges, Program Files, and system PATH
|
|
10
|
+
# writes. The user PATH is updated when needed.
|
|
11
|
+
|
|
12
|
+
$PackageName = if ($env:GEARBOX_PACKAGE) { $env:GEARBOX_PACKAGE } else { "gearbox-code" }
|
|
13
|
+
$Version = if ($env:GEARBOX_VERSION) { $env:GEARBOX_VERSION } else { "latest" }
|
|
14
|
+
$InstallRoot = if ($env:GEARBOX_INSTALL_DIR) { $env:GEARBOX_INSTALL_DIR } else { Join-Path $env:LOCALAPPDATA "Gearbox" }
|
|
15
|
+
$BinDir = if ($env:GEARBOX_BIN_DIR) { $env:GEARBOX_BIN_DIR } else { Join-Path $InstallRoot "bin" }
|
|
16
|
+
|
|
17
|
+
function Require-Command($Name, $InstallHint) {
|
|
18
|
+
if (-not (Get-Command $Name -ErrorAction SilentlyContinue)) {
|
|
19
|
+
Write-Error "Gearbox installer needs '$Name'. $InstallHint"
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
Require-Command "node" "Install Node.js, then rerun this installer."
|
|
24
|
+
Require-Command "tar" "Install a current Windows build or Git for Windows, then rerun this installer."
|
|
25
|
+
|
|
26
|
+
$Temp = Join-Path ([System.IO.Path]::GetTempPath()) ("gearbox-install-" + [System.Guid]::NewGuid().ToString("N"))
|
|
27
|
+
New-Item -ItemType Directory -Path $Temp | Out-Null
|
|
28
|
+
|
|
29
|
+
try {
|
|
30
|
+
$MetaUrl = "https://registry.npmjs.org/$PackageName/$Version"
|
|
31
|
+
$MetaFile = Join-Path $Temp "meta.json"
|
|
32
|
+
Write-Host "-> Fetching $PackageName@$Version"
|
|
33
|
+
Invoke-WebRequest -Uri $MetaUrl -OutFile $MetaFile -UseBasicParsing
|
|
34
|
+
|
|
35
|
+
$Meta = Get-Content $MetaFile -Raw | ConvertFrom-Json
|
|
36
|
+
$ResolvedVersion = $Meta.version
|
|
37
|
+
$TarballUrl = $Meta.dist.tarball
|
|
38
|
+
if (-not $ResolvedVersion -or -not $TarballUrl) {
|
|
39
|
+
Write-Error "Could not resolve $PackageName@$Version from npm."
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
$TargetDir = Join-Path (Join-Path $InstallRoot "versions") $ResolvedVersion
|
|
43
|
+
$Archive = Join-Path $Temp "package.tgz"
|
|
44
|
+
$ExtractDir = Join-Path $Temp "extract"
|
|
45
|
+
|
|
46
|
+
Write-Host "-> Downloading $PackageName@$ResolvedVersion"
|
|
47
|
+
Invoke-WebRequest -Uri $TarballUrl -OutFile $Archive -UseBasicParsing
|
|
48
|
+
New-Item -ItemType Directory -Force -Path $ExtractDir, $TargetDir, $BinDir | Out-Null
|
|
49
|
+
tar -xzf $Archive -C $ExtractDir
|
|
50
|
+
|
|
51
|
+
$Cli = Join-Path $ExtractDir "package\dist\cli.mjs"
|
|
52
|
+
if (-not (Test-Path $Cli)) {
|
|
53
|
+
Write-Error "Package did not contain dist/cli.mjs."
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
$TargetCli = Join-Path $TargetDir "cli.mjs"
|
|
57
|
+
Copy-Item $Cli $TargetCli -Force
|
|
58
|
+
|
|
59
|
+
$CmdPath = Join-Path $BinDir "gearbox.cmd"
|
|
60
|
+
$Cmd = @"
|
|
61
|
+
@echo off
|
|
62
|
+
node "$TargetCli" %*
|
|
63
|
+
"@
|
|
64
|
+
Set-Content -Path $CmdPath -Value $Cmd -Encoding ASCII
|
|
65
|
+
|
|
66
|
+
$UserPath = [Environment]::GetEnvironmentVariable("Path", "User")
|
|
67
|
+
$PathParts = @()
|
|
68
|
+
if ($UserPath) { $PathParts = $UserPath -split ";" }
|
|
69
|
+
$AlreadyOnPath = $PathParts | Where-Object { $_ -ieq $BinDir }
|
|
70
|
+
if (-not $AlreadyOnPath) {
|
|
71
|
+
$NextPath = if ($UserPath) { "$UserPath;$BinDir" } else { $BinDir }
|
|
72
|
+
[Environment]::SetEnvironmentVariable("Path", $NextPath, "User")
|
|
73
|
+
$env:Path = "$env:Path;$BinDir"
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
Write-Host ""
|
|
77
|
+
Write-Host "Installed Gearbox $ResolvedVersion"
|
|
78
|
+
Write-Host " $CmdPath"
|
|
79
|
+
Write-Host ""
|
|
80
|
+
Write-Host "Run it with: gearbox"
|
|
81
|
+
if (-not $AlreadyOnPath) {
|
|
82
|
+
Write-Host "Open a new terminal if this shell does not pick up the PATH change."
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if ($env:GEARBOX_SKIP_ONBOARD -ne "1") {
|
|
86
|
+
Write-Host ""
|
|
87
|
+
Write-Host "Starting setup..."
|
|
88
|
+
& $CmdPath onboard
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
finally {
|
|
92
|
+
Remove-Item -Recurse -Force $Temp -ErrorAction SilentlyContinue
|
|
93
|
+
}
|
package/install.sh
CHANGED
|
@@ -93,3 +93,13 @@ case ":${PATH}:" in
|
|
|
93
93
|
echo "Then run: gearbox"
|
|
94
94
|
;;
|
|
95
95
|
esac
|
|
96
|
+
|
|
97
|
+
if [[ "${GEARBOX_SKIP_ONBOARD:-}" != "1" ]]; then
|
|
98
|
+
echo ""
|
|
99
|
+
echo "Starting setup..."
|
|
100
|
+
if [[ -r /dev/tty && -w /dev/tty ]]; then
|
|
101
|
+
"${BIN_DIR}/gearbox" onboard < /dev/tty > /dev/tty
|
|
102
|
+
else
|
|
103
|
+
echo "No interactive terminal detected. Run: ${BIN_DIR}/gearbox onboard"
|
|
104
|
+
fi
|
|
105
|
+
fi
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gearbox-code",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.8",
|
|
4
4
|
"description": "A beautiful multi-provider coding harness for the terminal. (Intelligent model routing lands on top of this soon.)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
},
|
|
10
10
|
"files": [
|
|
11
11
|
"dist/cli.mjs",
|
|
12
|
-
"install.sh"
|
|
12
|
+
"install.sh",
|
|
13
|
+
"install.ps1"
|
|
13
14
|
],
|
|
14
15
|
"scripts": {
|
|
15
16
|
"start": "bun run src/cli.tsx",
|