withvibe 0.1.4

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.
Files changed (62) hide show
  1. package/LICENSE +93 -0
  2. package/README.md +67 -0
  3. package/dist/api.js +29 -0
  4. package/dist/api.js.map +1 -0
  5. package/dist/assets/docker-compose.yml +130 -0
  6. package/dist/config.js +48 -0
  7. package/dist/config.js.map +1 -0
  8. package/dist/env-command.js +331 -0
  9. package/dist/env-command.js.map +1 -0
  10. package/dist/exec.js +35 -0
  11. package/dist/exec.js.map +1 -0
  12. package/dist/git-auth.js +64 -0
  13. package/dist/git-auth.js.map +1 -0
  14. package/dist/index.js +42 -0
  15. package/dist/index.js.map +1 -0
  16. package/dist/install/anthropic-validate.js +73 -0
  17. package/dist/install/anthropic-validate.js.map +1 -0
  18. package/dist/install/build-images.js +99 -0
  19. package/dist/install/build-images.js.map +1 -0
  20. package/dist/install/commands/build-images-cmd.js +68 -0
  21. package/dist/install/commands/build-images-cmd.js.map +1 -0
  22. package/dist/install/commands/configure.js +276 -0
  23. package/dist/install/commands/configure.js.map +1 -0
  24. package/dist/install/commands/lifecycle.js +129 -0
  25. package/dist/install/commands/lifecycle.js.map +1 -0
  26. package/dist/install/commands/uninstall.js +88 -0
  27. package/dist/install/commands/uninstall.js.map +1 -0
  28. package/dist/install/commands/upgrade.js +164 -0
  29. package/dist/install/commands/upgrade.js.map +1 -0
  30. package/dist/install/compose-rewriter.js +298 -0
  31. package/dist/install/compose-rewriter.js.map +1 -0
  32. package/dist/install/compose.js +118 -0
  33. package/dist/install/compose.js.map +1 -0
  34. package/dist/install/doctor.js +176 -0
  35. package/dist/install/doctor.js.map +1 -0
  36. package/dist/install/env-file.js +63 -0
  37. package/dist/install/env-file.js.map +1 -0
  38. package/dist/install/exec.js +32 -0
  39. package/dist/install/exec.js.map +1 -0
  40. package/dist/install/images.js +78 -0
  41. package/dist/install/images.js.map +1 -0
  42. package/dist/install/init.js +584 -0
  43. package/dist/install/init.js.map +1 -0
  44. package/dist/install/log.js +15 -0
  45. package/dist/install/log.js.map +1 -0
  46. package/dist/install/paths.js +26 -0
  47. package/dist/install/paths.js.map +1 -0
  48. package/dist/install/ports.js +23 -0
  49. package/dist/install/ports.js.map +1 -0
  50. package/dist/install/register.js +155 -0
  51. package/dist/install/register.js.map +1 -0
  52. package/dist/install/secrets.js +9 -0
  53. package/dist/install/secrets.js.map +1 -0
  54. package/dist/install/state.js +29 -0
  55. package/dist/install/state.js.map +1 -0
  56. package/dist/login.js +56 -0
  57. package/dist/login.js.map +1 -0
  58. package/dist/ports.js +33 -0
  59. package/dist/ports.js.map +1 -0
  60. package/dist/preflight.js +150 -0
  61. package/dist/preflight.js.map +1 -0
  62. package/package.json +38 -0
@@ -0,0 +1,331 @@
1
+ import { promises as fs } from "node:fs";
2
+ import path from "node:path";
3
+ import chalk from "chalk";
4
+ import ora from "ora";
5
+ import prompts from "prompts";
6
+ import { fetchExportReadiness, fetchLocalBundle, } from "./api.js";
7
+ import { loadConfig, withvibeHome } from "./config.js";
8
+ import { run } from "./exec.js";
9
+ import { confirmGitHubAccount } from "./git-auth.js";
10
+ import { pickFreePorts } from "./ports.js";
11
+ import { runPreflight } from "./preflight.js";
12
+ // Same ${VAR} form the server uses in template compose files.
13
+ const INTERPOLATION_RE = /\$\{([A-Z][A-Z0-9_]*)\}/g;
14
+ function slugify(s) {
15
+ return (s
16
+ .toLowerCase()
17
+ .replace(/[^a-z0-9]+/g, "-")
18
+ .replace(/^-+|-+$/g, "")
19
+ .slice(0, 40) || "env");
20
+ }
21
+ function interpolate(body, vars) {
22
+ return body.replace(INTERPOLATION_RE, (match, key) => {
23
+ return key in vars ? vars[key] : match;
24
+ });
25
+ }
26
+ function renderDotEnv(vars) {
27
+ const lines = ["# Generated by withvibe CLI — edit with care."];
28
+ for (const [k, v] of Object.entries(vars)) {
29
+ const escaped = v
30
+ .replace(/\\/g, "\\\\")
31
+ .replace(/"/g, '\\"')
32
+ .replace(/\n/g, "\\n")
33
+ .replace(/\r/g, "\\r");
34
+ lines.push(`${k}="${escaped}"`);
35
+ }
36
+ return lines.join("\n") + "\n";
37
+ }
38
+ export async function envCommand(envId, opts) {
39
+ const cfg = await loadConfig();
40
+ if (!cfg) {
41
+ console.error(chalk.red("Not logged in."), "Run `withvibe login` first.");
42
+ process.exit(1);
43
+ }
44
+ console.log(chalk.bold("\n▸ Preflight"));
45
+ const { haveCode, macAppPath } = await runPreflight({ autoInstall: true });
46
+ console.log(chalk.bold("\n▸ GitHub authentication"));
47
+ await confirmGitHubAccount();
48
+ console.log(chalk.bold("\n▸ Checking export readiness"));
49
+ await checkExportReadiness(cfg.server, cfg.token, envId, opts.force);
50
+ console.log(chalk.bold("\n▸ Fetching env bundle"));
51
+ const spinner = ora("Contacting server…").start();
52
+ let bundle;
53
+ try {
54
+ bundle = await fetchLocalBundle(cfg.server, cfg.token, envId);
55
+ spinner.succeed(`Loaded "${bundle.env.title}" (${bundle.repos.length} repo${bundle.repos.length === 1 ? "" : "s"})`);
56
+ }
57
+ catch (err) {
58
+ spinner.fail("Failed to fetch bundle");
59
+ console.error(chalk.red(String(err)));
60
+ process.exit(1);
61
+ }
62
+ const envDir = path.join(withvibeHome(), bundle.env.workspaceId, `${slugify(bundle.env.title)}-${bundle.env.id.slice(-6)}`);
63
+ // Repos live as siblings of docker-compose.yml, matching the hosted
64
+ // layout (<envDir>/<repoName>/). Compose files reference repos as
65
+ // `./repo-name`, so any other layout would break volume mounts.
66
+ await fs.mkdir(envDir, { recursive: true });
67
+ console.log(chalk.dim(` → ${envDir}`));
68
+ await cloneAllRepos(bundle.repos, envDir);
69
+ await writeBundleFiles(envDir, bundle);
70
+ await dockerComposeUp(envDir);
71
+ await printServicePorts(envDir);
72
+ const workspacePath = await writeCodeWorkspace(envDir, bundle);
73
+ if (opts.open && haveCode) {
74
+ console.log(chalk.bold("\n▸ Opening VSCode"));
75
+ await openEditor(workspacePath, macAppPath).catch(() => {
76
+ console.log(chalk.yellow(" (failed to launch VSCode — open this file manually:"), workspacePath, chalk.yellow(")"));
77
+ });
78
+ }
79
+ else if (!haveCode) {
80
+ console.log(chalk.yellow("\nVSCode CLI not available — open this file manually:"), workspacePath);
81
+ }
82
+ console.log(chalk.green("\n✓ Env ready."), chalk.dim(envDir));
83
+ }
84
+ async function printServicePorts(envDir) {
85
+ const res = await run("docker", ["compose", "ps", "--format", "json"], { cwd: envDir, streamTo: "pipe" });
86
+ if (res.code !== 0)
87
+ return;
88
+ // `docker compose ps --format json` emits either a JSON array or NDJSON
89
+ // depending on the CLI version. Handle both.
90
+ const text = res.stdout.trim();
91
+ if (!text)
92
+ return;
93
+ const rows = [];
94
+ if (text.startsWith("[")) {
95
+ try {
96
+ rows.push(...JSON.parse(text));
97
+ }
98
+ catch {
99
+ return;
100
+ }
101
+ }
102
+ else {
103
+ for (const line of text.split("\n")) {
104
+ const s = line.trim();
105
+ if (!s)
106
+ continue;
107
+ try {
108
+ rows.push(JSON.parse(s));
109
+ }
110
+ catch {
111
+ // skip malformed line
112
+ }
113
+ }
114
+ }
115
+ // Group published ports by service. A single container may publish
116
+ // multiple host ports (e.g. postgres + metrics), so we keep them all.
117
+ const byService = new Map();
118
+ for (const r of rows) {
119
+ const svc = r.Service || r.Name;
120
+ if (!svc)
121
+ continue;
122
+ const entries = [];
123
+ for (const p of r.Publishers ?? []) {
124
+ if (!p || !p.PublishedPort || !p.TargetPort)
125
+ continue;
126
+ entries.push({ host: p.PublishedPort, container: p.TargetPort });
127
+ }
128
+ if (entries.length === 0)
129
+ continue;
130
+ const existing = byService.get(svc) ?? [];
131
+ existing.push(...entries);
132
+ byService.set(svc, existing);
133
+ }
134
+ if (byService.size === 0) {
135
+ console.log(chalk.dim("\n (No services published any ports to the host.)"));
136
+ return;
137
+ }
138
+ console.log(chalk.bold("\n▸ Services"));
139
+ for (const [svc, ports] of byService) {
140
+ // Dedupe (host, container) pairs in case compose reports them twice
141
+ // for different protocols (tcp + udp) with the same port number.
142
+ const seen = new Set();
143
+ const uniq = ports.filter((p) => {
144
+ const k = `${p.host}-${p.container}`;
145
+ if (seen.has(k))
146
+ return false;
147
+ seen.add(k);
148
+ return true;
149
+ });
150
+ const parts = uniq.map((p) => `${chalk.cyan(`http://localhost:${p.host}`)} ${chalk.dim(`→ container :${p.container}`)}`);
151
+ console.log(` ${chalk.bold(svc)} ${parts.join(" ")}`);
152
+ }
153
+ }
154
+ async function openEditor(workspacePath, macAppPath) {
155
+ // Prefer the `code` CLI shim when it exists — opens in the current window
156
+ // and honors the .code-workspace format natively.
157
+ const codeOnPath = await run("which", ["code"]).catch(() => ({ code: 1 }));
158
+ if (codeOnPath.code === 0) {
159
+ await run("code", [workspacePath], { streamTo: "inherit" });
160
+ return;
161
+ }
162
+ // macOS fallback: launch via `open -a` against the .app bundle.
163
+ if (process.platform === "darwin" && macAppPath) {
164
+ await run("open", ["-a", macAppPath, workspacePath], {
165
+ streamTo: "inherit",
166
+ });
167
+ return;
168
+ }
169
+ throw new Error("No way to launch editor");
170
+ }
171
+ async function checkExportReadiness(server, token, envId, force) {
172
+ const spinner = ora("Inspecting server-side env clones…").start();
173
+ let readiness;
174
+ try {
175
+ readiness = await fetchExportReadiness(server, token, envId);
176
+ }
177
+ catch (err) {
178
+ spinner.fail("Failed to check export readiness");
179
+ console.error(chalk.red(String(err)));
180
+ process.exit(1);
181
+ }
182
+ if (readiness.ready) {
183
+ spinner.succeed("All env repos are committed and pushed");
184
+ return;
185
+ }
186
+ spinner.warn("Some env repos have changes that won't be exported");
187
+ for (const r of readiness.repos) {
188
+ if (r.error) {
189
+ console.log(chalk.yellow(` • ${r.name}: ${r.error}`));
190
+ continue;
191
+ }
192
+ if (r.uncommitted === 0 && r.unpushed === 0)
193
+ continue;
194
+ const parts = [];
195
+ if (r.uncommitted > 0)
196
+ parts.push(`${r.uncommitted} uncommitted file(s)`);
197
+ if (r.unpushed > 0)
198
+ parts.push(`${r.unpushed} unpushed commit(s)`);
199
+ console.log(chalk.yellow(` • ${r.name} (${r.branch}): ${parts.join(", ")}`));
200
+ }
201
+ console.log(chalk.yellow("\nThe local clone pulls from GitHub. Anything not committed and pushed\non the env's branch will NOT appear in your local checkout."));
202
+ console.log(chalk.dim("→ Open the env in the web app, commit & push the changes, then re-run this command."));
203
+ if (force) {
204
+ console.log(chalk.dim("\n--force given, continuing anyway."));
205
+ return;
206
+ }
207
+ const { proceed } = await prompts({
208
+ type: "confirm",
209
+ name: "proceed",
210
+ message: "Continue export anyway?",
211
+ initial: false,
212
+ });
213
+ if (!proceed) {
214
+ console.log(chalk.dim("Aborted."));
215
+ process.exit(0);
216
+ }
217
+ }
218
+ async function cloneAllRepos(repos, envDir) {
219
+ console.log(chalk.bold("\n▸ Cloning repositories"));
220
+ for (const repo of repos) {
221
+ const target = path.join(envDir, repo.name);
222
+ const exists = await fs
223
+ .stat(target)
224
+ .then((s) => s.isDirectory())
225
+ .catch(() => false);
226
+ if (exists) {
227
+ console.log(chalk.dim(` skip ${repo.name} (already cloned)`));
228
+ continue;
229
+ }
230
+ const spinner = ora(`Cloning ${repo.name} (${repo.branch})…`).start();
231
+ const res = await run("git", [
232
+ "clone",
233
+ "--branch",
234
+ repo.branch,
235
+ "--single-branch",
236
+ repo.url,
237
+ target,
238
+ ], { streamTo: "pipe" });
239
+ if (res.code !== 0) {
240
+ spinner.fail(`git clone ${repo.name} failed`);
241
+ console.error(res.stderr);
242
+ if (/Repository not found/i.test(res.stderr) ||
243
+ /Permission denied/i.test(res.stderr) ||
244
+ /Authentication failed/i.test(res.stderr)) {
245
+ console.error(chalk.yellow("\nThis usually means your active GitHub account doesn't have access to this repo.\nTry `gh auth switch` (or `gh auth login`) to pick an account with access, then re-run."));
246
+ }
247
+ process.exit(1);
248
+ }
249
+ spinner.succeed(`Cloned ${repo.name}`);
250
+ }
251
+ }
252
+ async function writeBundleFiles(envDir, bundle) {
253
+ if (bundle.bundle.kind === "none") {
254
+ console.log(chalk.yellow("\n(No compose file for this env — skipping docker setup.)"));
255
+ return;
256
+ }
257
+ console.log(chalk.bold("\n▸ Writing compose files"));
258
+ if (bundle.bundle.kind === "custom") {
259
+ await fs.writeFile(path.join(envDir, "docker-compose.yml"), bundle.bundle.composeFile, "utf-8");
260
+ console.log(chalk.dim(" → docker-compose.yml (custom)"));
261
+ return;
262
+ }
263
+ // Template path: allocate host ports, write .env, materialize assets.
264
+ const t = bundle.bundle;
265
+ const ports = await pickFreePorts(t.portKeys.length);
266
+ const portVars = {};
267
+ t.portKeys.forEach((key, i) => {
268
+ portVars[key] = String(ports[i]);
269
+ });
270
+ const allVars = { ...t.resolvedVars, ...portVars };
271
+ await fs.writeFile(path.join(envDir, "docker-compose.yml"), t.composeFile, "utf-8");
272
+ await fs.writeFile(path.join(envDir, ".env"), renderDotEnv(allVars), "utf-8");
273
+ console.log(chalk.dim(" → docker-compose.yml"));
274
+ console.log(chalk.dim(" → .env"));
275
+ for (const asset of t.assets) {
276
+ const target = path.join(envDir, asset.path);
277
+ const resolved = path.resolve(target);
278
+ if (!resolved.startsWith(path.resolve(envDir) + path.sep)) {
279
+ throw new Error(`Asset path escapes env dir: ${asset.path}`);
280
+ }
281
+ await fs.mkdir(path.dirname(resolved), { recursive: true });
282
+ const content = asset.isTemplate
283
+ ? interpolate(asset.content, allVars)
284
+ : asset.content;
285
+ await fs.writeFile(resolved, content, "utf-8");
286
+ console.log(chalk.dim(` → ${asset.path}`));
287
+ }
288
+ if (t.portKeys.length > 0) {
289
+ console.log(chalk.dim(" allocated host ports:"));
290
+ for (const k of t.portKeys) {
291
+ console.log(chalk.dim(` ${k}=${portVars[k]}`));
292
+ }
293
+ }
294
+ }
295
+ async function dockerComposeUp(envDir) {
296
+ // Skip if there's no compose file at all (bundle.kind === "none" path).
297
+ const hasCompose = await fs
298
+ .stat(path.join(envDir, "docker-compose.yml"))
299
+ .then(() => true)
300
+ .catch(() => false);
301
+ if (!hasCompose)
302
+ return;
303
+ console.log(chalk.bold("\n▸ Starting docker compose (this may take a while on first run)"));
304
+ const res = await run("docker", ["compose", "up", "-d", "--build"], {
305
+ cwd: envDir,
306
+ streamTo: "inherit",
307
+ });
308
+ if (res.code !== 0) {
309
+ console.error(chalk.red(`docker compose exited with code ${res.code}`));
310
+ process.exit(1);
311
+ }
312
+ }
313
+ async function writeCodeWorkspace(envDir, bundle) {
314
+ const folders = [
315
+ { name: "env-root", path: "." },
316
+ ...bundle.repos.map((r) => ({
317
+ name: r.name,
318
+ path: `./${r.name}`,
319
+ })),
320
+ ];
321
+ const workspace = {
322
+ folders,
323
+ settings: {
324
+ "files.exclude": { "**/.DS_Store": true },
325
+ },
326
+ };
327
+ const filePath = path.join(envDir, `${bundle.env.title}.code-workspace`);
328
+ await fs.writeFile(filePath, JSON.stringify(workspace, null, 2), "utf-8");
329
+ return filePath;
330
+ }
331
+ //# sourceMappingURL=env-command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env-command.js","sourceRoot":"","sources":["../src/env-command.ts"],"names":[],"mappings":"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"}
package/dist/exec.js ADDED
@@ -0,0 +1,35 @@
1
+ import { spawn } from "node:child_process";
2
+ // Wrapper over spawn that returns a promise, forwards signals, and optionally
3
+ // streams stdio to the current terminal (for long-running commands like git
4
+ // clone or docker compose up where the user wants to see live progress).
5
+ export function run(cmd, args, opts = {}) {
6
+ return new Promise((resolve, reject) => {
7
+ const stream = opts.streamTo ?? "pipe";
8
+ const child = spawn(cmd, args, {
9
+ stdio: stream === "inherit" ? "inherit" : ["ignore", "pipe", "pipe"],
10
+ ...opts,
11
+ });
12
+ let stdout = "";
13
+ let stderr = "";
14
+ if (stream === "pipe") {
15
+ child.stdout?.on("data", (d) => (stdout += d.toString()));
16
+ child.stderr?.on("data", (d) => (stderr += d.toString()));
17
+ }
18
+ child.on("error", reject);
19
+ child.on("close", (code) => {
20
+ resolve({ stdout, stderr, code: code ?? -1 });
21
+ });
22
+ });
23
+ }
24
+ export async function which(cmd) {
25
+ const finder = process.platform === "win32" ? "where" : "which";
26
+ const res = await run(finder, [cmd]).catch(() => ({ code: 1 }));
27
+ return res.code === 0;
28
+ }
29
+ export async function captureVersion(cmd, args) {
30
+ const res = await run(cmd, args).catch(() => null);
31
+ if (!res || res.code !== 0)
32
+ return null;
33
+ return (res.stdout || res.stderr).trim().split("\n")[0] ?? null;
34
+ }
35
+ //# sourceMappingURL=exec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exec.js","sourceRoot":"","sources":["../src/exec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAqB,MAAM,oBAAoB,CAAC;AAQ9D,8EAA8E;AAC9E,4EAA4E;AAC5E,yEAAyE;AACzE,MAAM,UAAU,GAAG,CACjB,GAAW,EACX,IAAc,EACd,OAAyD,EAAE;IAE3D,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,IAAI,MAAM,CAAC;QACvC,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE;YAC7B,KAAK,EAAE,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;YACpE,GAAG,IAAI;SACR,CAAC,CAAC;QAEH,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,IAAI,MAAM,GAAG,EAAE,CAAC;QAEhB,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;YACtB,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;YAClE,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;QACpE,CAAC;QAED,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC1B,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;YACzB,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC;QAChD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,KAAK,CAAC,GAAW;IACrC,MAAM,MAAM,GAAG,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;IAChE,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAgB,CAAA,CAAC,CAAC;IAC7E,OAAO,GAAG,CAAC,IAAI,KAAK,CAAC,CAAC;AACxB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,GAAW,EACX,IAAc;IAEd,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;IACnD,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACxC,OAAO,CAAC,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;AAClE,CAAC"}
@@ -0,0 +1,64 @@
1
+ import chalk from "chalk";
2
+ import prompts from "prompts";
3
+ import { run, which } from "./exec.js";
4
+ // Extract the active GitHub username from `gh auth status` output. The
5
+ // command prints a human-readable block; the line we care about looks like:
6
+ // ✓ Logged in to github.com account <username> (keyring)
7
+ // or
8
+ // - Active account: true
9
+ // Logged in to github.com as <username> (keyring)
10
+ // We'll match the first "Logged in ... as|account <name>" we see.
11
+ function parseGhAuthStatus(text) {
12
+ const line = text.match(/Logged in to [^\s]+ (?:as|account) ([A-Za-z0-9][A-Za-z0-9-]*)/);
13
+ return line ? line[1] : null;
14
+ }
15
+ /**
16
+ * If `gh` is installed, show the user which GitHub account git will use and
17
+ * offer to switch. This runs BEFORE any `git clone` so a wrong-account
18
+ * mistake surfaces once rather than per-repo.
19
+ *
20
+ * No-op (with a friendly note) when `gh` isn't installed — the user's native
21
+ * git credential helper will handle auth and we can't do much.
22
+ */
23
+ export async function confirmGitHubAccount() {
24
+ if (!(await which("gh"))) {
25
+ console.log(chalk.dim(" (gh CLI not installed — `git clone` will use whichever credentials git finds. If a clone says \"Repository not found\", install gh and run `gh auth login`.)"));
26
+ return;
27
+ }
28
+ const status = await run("gh", ["auth", "status"]);
29
+ // gh writes both success and failure to stderr (annoyingly).
30
+ const combined = `${status.stdout}\n${status.stderr}`;
31
+ const activeUser = parseGhAuthStatus(combined);
32
+ if (!activeUser) {
33
+ console.log(chalk.yellow(" gh is installed but not logged in."));
34
+ const go = await prompts({
35
+ type: "confirm",
36
+ name: "go",
37
+ message: "Run `gh auth login` now?",
38
+ initial: true,
39
+ });
40
+ if (go.go) {
41
+ await run("gh", ["auth", "login"], { streamTo: "inherit" });
42
+ }
43
+ return;
44
+ }
45
+ console.log(` GitHub account in use: ${chalk.bold(activeUser)}`);
46
+ const choice = await prompts({
47
+ type: "select",
48
+ name: "v",
49
+ message: "Continue with this account?",
50
+ choices: [
51
+ { title: `Yes, continue as ${activeUser}`, value: "keep" },
52
+ { title: "Switch account (gh auth switch)", value: "switch" },
53
+ { title: "Log in with a different account (gh auth login)", value: "login" },
54
+ ],
55
+ initial: 0,
56
+ });
57
+ if (choice.v === "switch") {
58
+ await run("gh", ["auth", "switch"], { streamTo: "inherit" });
59
+ }
60
+ else if (choice.v === "login") {
61
+ await run("gh", ["auth", "login"], { streamTo: "inherit" });
62
+ }
63
+ }
64
+ //# sourceMappingURL=git-auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git-auth.js","sourceRoot":"","sources":["../src/git-auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AAEvC,uEAAuE;AACvE,4EAA4E;AAC5E,2DAA2D;AAC3D,KAAK;AACL,2BAA2B;AAC3B,sDAAsD;AACtD,kEAAkE;AAClE,SAAS,iBAAiB,CAAC,IAAY;IACrC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CACrB,+DAA+D,CAChE,CAAC;IACF,OAAO,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAC/B,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB;IACxC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;QACzB,OAAO,CAAC,GAAG,CACT,KAAK,CAAC,GAAG,CACP,gKAAgK,CACjK,CACF,CAAC;QACF,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;IACnD,6DAA6D;IAC7D,MAAM,QAAQ,GAAG,GAAG,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,EAAE,CAAC;IACtD,MAAM,UAAU,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IAE/C,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,CAAC,GAAG,CACT,KAAK,CAAC,MAAM,CAAC,sCAAsC,CAAC,CACrD,CAAC;QACF,MAAM,EAAE,GAAG,MAAM,OAAO,CAAC;YACvB,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,IAAI;YACV,OAAO,EAAE,0BAA0B;YACnC,OAAO,EAAE,IAAI;SACd,CAAC,CAAC;QACH,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;YACV,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,CAAC;QAC9D,CAAC;QACD,OAAO;IACT,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,4BAA4B,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;IAClE,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC;QAC3B,IAAI,EAAE,QAAQ;QACd,IAAI,EAAE,GAAG;QACT,OAAO,EAAE,6BAA6B;QACtC,OAAO,EAAE;YACP,EAAE,KAAK,EAAE,oBAAoB,UAAU,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE;YAC1D,EAAE,KAAK,EAAE,iCAAiC,EAAE,KAAK,EAAE,QAAQ,EAAE;YAC7D,EAAE,KAAK,EAAE,iDAAiD,EAAE,KAAK,EAAE,OAAO,EAAE;SAC7E;QACD,OAAO,EAAE,CAAC;KACX,CAAC,CAAC;IAEH,IAAI,MAAM,CAAC,CAAC,KAAK,QAAQ,EAAE,CAAC;QAC1B,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,CAAC;IAC/D,CAAC;SAAM,IAAI,MAAM,CAAC,CAAC,KAAK,OAAO,EAAE,CAAC;QAChC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC,CAAC;IAC9D,CAAC;AACH,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,42 @@
1
+ #!/usr/bin/env node
2
+ import { readFileSync } from "node:fs";
3
+ import { fileURLToPath } from "node:url";
4
+ import path from "node:path";
5
+ import { Command } from "commander";
6
+ import { registerInstallCommands } from "./install/register.js";
7
+ import { loginCommand } from "./login.js";
8
+ import { envCommand } from "./env-command.js";
9
+ const DEFAULT_SERVER = process.env.WITHVIBE_SERVER || "http://localhost:3000";
10
+ const pkgPath = path.join(path.dirname(fileURLToPath(import.meta.url)), "..", "package.json");
11
+ const pkgVersion = JSON.parse(readFileSync(pkgPath, "utf-8")).version;
12
+ const program = new Command();
13
+ program
14
+ .name("withvibe")
15
+ .description("withvibe — install/manage the server stack and run shared environments locally.")
16
+ .version(pkgVersion)
17
+ .option("-s, --server <url>", "Withvibe web server URL (env: WITHVIBE_SERVER)", DEFAULT_SERVER);
18
+ program
19
+ .command("login")
20
+ .description("Authorize this machine against a withvibe server")
21
+ .option("-f, --force", "Force re-auth even if already logged in", false)
22
+ .action(async (opts) => {
23
+ const { server } = program.opts();
24
+ await loginCommand({ server, force: opts.force });
25
+ });
26
+ program
27
+ .command("env <envId>")
28
+ .description("Set up the given env on this machine and open it in VSCode")
29
+ .option("--no-open", "Don't launch VSCode at the end")
30
+ .option("-f, --force", "Skip the uncommitted/unpushed work warning prompt", false)
31
+ .action(async (envId, opts) => {
32
+ await envCommand(envId, { open: opts.open, force: opts.force });
33
+ });
34
+ // Server-side install/manage commands — flattened onto the root program so
35
+ // users invoke them as `withvibe init`, `withvibe start`, etc. No name
36
+ // collisions with the existing `login` / `env` commands.
37
+ registerInstallCommands(program);
38
+ program.parseAsync().catch((err) => {
39
+ console.error(err);
40
+ process.exit(1);
41
+ });
42
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,MAAM,cAAc,GAClB,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,uBAAuB,CAAC;AAEzD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CACvB,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAC5C,IAAI,EACJ,cAAc,CACf,CAAC;AACF,MAAM,UAAU,GACb,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAyB,CAAC,OAAO,CAAC;AAE9E,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAC9B,OAAO;KACJ,IAAI,CAAC,UAAU,CAAC;KAChB,WAAW,CACV,iFAAiF,CAClF;KACA,OAAO,CAAC,UAAU,CAAC;KACnB,MAAM,CACL,oBAAoB,EACpB,gDAAgD,EAChD,cAAc,CACf,CAAC;AAEJ,OAAO;KACJ,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,kDAAkD,CAAC;KAC/D,MAAM,CAAC,aAAa,EAAE,yCAAyC,EAAE,KAAK,CAAC;KACvE,MAAM,CAAC,KAAK,EAAE,IAAwB,EAAE,EAAE;IACzC,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,EAAsB,CAAC;IACtD,MAAM,YAAY,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;AACpD,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,aAAa,CAAC;KACtB,WAAW,CAAC,4DAA4D,CAAC;KACzE,MAAM,CAAC,WAAW,EAAE,gCAAgC,CAAC;KACrD,MAAM,CACL,aAAa,EACb,mDAAmD,EACnD,KAAK,CACN;KACA,MAAM,CAAC,KAAK,EAAE,KAAa,EAAE,IAAuC,EAAE,EAAE;IACvE,MAAM,UAAU,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;AAClE,CAAC,CAAC,CAAC;AAEL,2EAA2E;AAC3E,uEAAuE;AACvE,yDAAyD;AACzD,uBAAuB,CAAC,OAAO,CAAC,CAAC;AAEjC,OAAO,CAAC,UAAU,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACjC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACnB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,73 @@
1
+ // Validate an Anthropic credential. Two formats are accepted:
2
+ // sk-ant-api* — API key. Live-checked against /v1/messages/count_tokens
3
+ // (doesn't bill).
4
+ // sk-ant-oat* — Claude Max/Pro OAuth token. /v1/messages doesn't accept
5
+ // these (they auth differently), so we accept them on
6
+ // shape alone and let the api route to CLAUDE_CODE_OAUTH_TOKEN.
7
+ //
8
+ // The api code at chat-stream.service.ts:111 detects the prefix and sets
9
+ // the right env var when spawning the claude CLI, so both flavors can live
10
+ // in the ANTHROPIC_API_KEY slot of .env.
11
+ const ENDPOINT = "https://api.anthropic.com/v1/messages/count_tokens";
12
+ const MODEL = "claude-haiku-4-5-20251001";
13
+ export function classifyKey(key) {
14
+ const t = key.trim();
15
+ if (t.startsWith("sk-ant-api"))
16
+ return "api-key";
17
+ if (t.startsWith("sk-ant-oat"))
18
+ return "oauth-token";
19
+ return "unknown";
20
+ }
21
+ export async function validateAnthropicKey(key, timeoutMs = 8000) {
22
+ const kind = classifyKey(key);
23
+ if (kind === "unknown") {
24
+ return {
25
+ ok: false,
26
+ error: "Key must start with `sk-ant-api` (API key) or `sk-ant-oat` (Claude Max/Pro OAuth token).",
27
+ };
28
+ }
29
+ // OAuth tokens can't be checked via /v1/messages/count_tokens — that
30
+ // endpoint is x-api-key only. Trust the shape; the claude CLI will
31
+ // surface a clear error on first run if the token is bad.
32
+ if (kind === "oauth-token")
33
+ return { ok: true, kind };
34
+ const controller = new AbortController();
35
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
36
+ try {
37
+ const res = await fetch(ENDPOINT, {
38
+ method: "POST",
39
+ signal: controller.signal,
40
+ headers: {
41
+ "content-type": "application/json",
42
+ "x-api-key": key,
43
+ "anthropic-version": "2023-06-01",
44
+ },
45
+ body: JSON.stringify({
46
+ model: MODEL,
47
+ messages: [{ role: "user", content: "ping" }],
48
+ }),
49
+ });
50
+ if (res.ok)
51
+ return { ok: true, kind };
52
+ let detail = `HTTP ${res.status}`;
53
+ try {
54
+ const body = (await res.json());
55
+ if (body?.error?.message)
56
+ detail = body.error.message;
57
+ }
58
+ catch {
59
+ // ignore
60
+ }
61
+ return { ok: false, status: res.status, error: detail };
62
+ }
63
+ catch (e) {
64
+ return {
65
+ ok: false,
66
+ error: e.message || "network error",
67
+ };
68
+ }
69
+ finally {
70
+ clearTimeout(timer);
71
+ }
72
+ }
73
+ //# sourceMappingURL=anthropic-validate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anthropic-validate.js","sourceRoot":"","sources":["../../src/install/anthropic-validate.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAC9D,2EAA2E;AAC3E,mCAAmC;AACnC,2EAA2E;AAC3E,uEAAuE;AACvE,iFAAiF;AACjF,EAAE;AACF,yEAAyE;AACzE,2EAA2E;AAC3E,yCAAyC;AAEzC,MAAM,QAAQ,GAAG,oDAAoD,CAAC;AACtE,MAAM,KAAK,GAAG,2BAA2B,CAAC;AAM1C,MAAM,UAAU,WAAW,CAAC,GAAW;IACrC,MAAM,CAAC,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IACrB,IAAI,CAAC,CAAC,UAAU,CAAC,YAAY,CAAC;QAAE,OAAO,SAAS,CAAC;IACjD,IAAI,CAAC,CAAC,UAAU,CAAC,YAAY,CAAC;QAAE,OAAO,aAAa,CAAC;IACrD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,GAAW,EACX,SAAS,GAAG,IAAI;IAEhB,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IAC9B,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,OAAO;YACL,EAAE,EAAE,KAAK;YACT,KAAK,EAAE,0FAA0F;SAClG,CAAC;IACJ,CAAC;IACD,qEAAqE;IACrE,mEAAmE;IACnE,0DAA0D;IAC1D,IAAI,IAAI,KAAK,aAAa;QAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IAEtD,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;IACzC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,SAAS,CAAC,CAAC;IAC9D,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,QAAQ,EAAE;YAChC,MAAM,EAAE,MAAM;YACd,MAAM,EAAE,UAAU,CAAC,MAAM;YACzB,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,WAAW,EAAE,GAAG;gBAChB,mBAAmB,EAAE,YAAY;aAClC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,KAAK,EAAE,KAAK;gBACZ,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;aAC9C,CAAC;SACH,CAAC,CAAC;QACH,IAAI,GAAG,CAAC,EAAE;YAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;QACtC,IAAI,MAAM,GAAG,QAAQ,GAAG,CAAC,MAAM,EAAE,CAAC;QAClC,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAqC,CAAC;YACpE,IAAI,IAAI,EAAE,KAAK,EAAE,OAAO;gBAAE,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC;QACxD,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;QACD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAC1D,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO;YACL,EAAE,EAAE,KAAK;YACT,KAAK,EAAG,CAAW,CAAC,OAAO,IAAI,eAAe;SAC/C,CAAC;IACJ,CAAC;YAAS,CAAC;QACT,YAAY,CAAC,KAAK,CAAC,CAAC;IACtB,CAAC;AACH,CAAC"}