@vibiz/cli 0.2.0 → 0.2.1
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/dist/{chunk-GSHNECVT.js → chunk-J4RTAA72.js} +48 -29
- package/dist/src-IAT2AUWC.js +3376 -0
- package/dist/vibiz.js +145 -44
- package/package.json +1 -1
- package/dist/src-2CVAECWM.js +0 -3392
package/dist/vibiz.js
CHANGED
|
@@ -6,11 +6,12 @@ import {
|
|
|
6
6
|
formatUnits,
|
|
7
7
|
formatUsd,
|
|
8
8
|
mergeEnvFile
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-J4RTAA72.js";
|
|
10
10
|
|
|
11
11
|
// packages/cli/src/main.ts
|
|
12
12
|
import { spawn } from "node:child_process";
|
|
13
|
-
import { chmod, mkdir, readFile as
|
|
13
|
+
import { chmod, mkdir as mkdir2, readFile as readFile3, writeFile as writeFile3 } from "node:fs/promises";
|
|
14
|
+
import { dirname as dirname5, join as join8 } from "node:path";
|
|
14
15
|
import { format } from "node:util";
|
|
15
16
|
|
|
16
17
|
// packages/cli/src/commands.ts
|
|
@@ -1639,7 +1640,7 @@ async function browserLogin(io, api, deps) {
|
|
|
1639
1640
|
await forget(io, pendingPath);
|
|
1640
1641
|
io.log(
|
|
1641
1642
|
`
|
|
1642
|
-
\u2713 Logged in to ${body.account?.name ?? "your account"} as "${body.key?.name ?? "cli"}" (${body.key?.access
|
|
1643
|
+
\u2713 Logged in to ${body.account?.name ?? "your account"} as "${body.key?.name ?? "cli"}" (${body.key?.access === "agent" ? "Limited access" : "full access"}). Saved to ${configFile(dir)}`
|
|
1643
1644
|
);
|
|
1644
1645
|
return;
|
|
1645
1646
|
}
|
|
@@ -2424,7 +2425,8 @@ var PROJECT_FILE = "vibiz.json";
|
|
|
2424
2425
|
var HELP = `vibiz \u2014 website, database and sign-in for a new business, in one command
|
|
2425
2426
|
|
|
2426
2427
|
vibiz login log in from the browser: prints a link, you click
|
|
2427
|
-
Authorize
|
|
2428
|
+
Authorize (Full access by default, or Limited),
|
|
2429
|
+
and the new key is saved here
|
|
2428
2430
|
[--key <vz_sk_\u2026>] [--api <url>] [--no-browser] or save a key you already have
|
|
2429
2431
|
vibiz signup the same as login: no account yet? one is opened
|
|
2430
2432
|
for you on the way
|
|
@@ -2448,43 +2450,44 @@ var HELP = `vibiz \u2014 website, database and sign-in for a new business, in on
|
|
|
2448
2450
|
schema and no production rows, own sign-in, own AI
|
|
2449
2451
|
key) into .env.development.local
|
|
2450
2452
|
vibiz dev -- <command\u2026> run a command with the development env, no file
|
|
2451
|
-
vibiz env [--write <file>] the PRODUCTION env (
|
|
2453
|
+
vibiz env [--write <file>] the PRODUCTION env (full-access keys only), to paste into
|
|
2452
2454
|
a host outside Vibiz; agents use \`vibiz dev\`
|
|
2453
2455
|
vibiz export [--code] [--db] [--csv] [--env production|development] [-o file.zip]
|
|
2454
2456
|
take the app elsewhere, or keep a backup: its source
|
|
2455
2457
|
with a guide (VIBIZ-EXPORT.md, .env.example), the
|
|
2456
2458
|
database as SQL that psql restores (--csv: tables as
|
|
2457
|
-
CSV). Default: all there is. Production data needs
|
|
2458
|
-
|
|
2459
|
+
CSV). Default: all there is. Production data needs a
|
|
2460
|
+
full-access key; Limited keys default to development
|
|
2459
2461
|
[--deployment <id>] [--secrets] [--no-wait] another deployment's code; --secrets also
|
|
2460
2462
|
writes the env's values to their own file (owner, asks)
|
|
2461
2463
|
vibiz domains [--json] your own domains: status, and the DNS records to add
|
|
2462
|
-
vibiz domains add <domain> [--elsewhere] connect one you own (
|
|
2464
|
+
vibiz domains add <domain> [--elsewhere] connect one you own (Limited keys: analytics counts it now;
|
|
2463
2465
|
sign-in trusts it once its TXT record is in, or an owner
|
|
2464
2466
|
confirms); HTTPS turns on by
|
|
2465
2467
|
itself. --elsewhere: the app runs on another host
|
|
2466
2468
|
vibiz domains verify <domain> check its DNS (and its TXT proof) again now
|
|
2467
|
-
vibiz domains remove <domain> disconnect it (
|
|
2469
|
+
vibiz domains remove <domain> disconnect it (full-access keys)
|
|
2468
2470
|
vibiz domains search <name> find a domain to buy, with prices (sellshelf, sellshelf.app)
|
|
2469
2471
|
vibiz domains buy <domain> [--years 1] [--yes]
|
|
2470
|
-
buy it from your credits for this project (
|
|
2472
|
+
buy it from your credits for this project (full-access keys,
|
|
2473
|
+
or Limited keys up to the owner's per-domain limit;
|
|
2471
2474
|
registered to the saved domain owner details)
|
|
2472
2475
|
vibiz domains owned [--json] domains this account bought: expiry, auto-renew
|
|
2473
|
-
vibiz domains renew <domain> [--years 1] renew now from credits (
|
|
2476
|
+
vibiz domains renew <domain> [--years 1] renew now from credits (full-access keys)
|
|
2474
2477
|
vibiz domains auto-renew <domain> on|off renew from credits 30 days before expiry (default on)
|
|
2475
|
-
vibiz domains transfer-code <domain> the code to move it to another registrar (
|
|
2478
|
+
vibiz domains transfer-code <domain> the code to move it to another registrar (full-access keys)
|
|
2476
2479
|
vibiz domains owner [--input <json>] [--open]
|
|
2477
2480
|
the domain owner details (the legal registrant), saved
|
|
2478
2481
|
once; --input sets them, --open edits in the console
|
|
2479
2482
|
vibiz auth [--dev] [--json] how people sign in: providers, callback URLs, email
|
|
2480
|
-
(production for
|
|
2483
|
+
(production for full-access keys; --dev the development copy)
|
|
2481
2484
|
vibiz auth providers add <google|github|vercel> [--own --client-id <id>] [--dev]
|
|
2482
2485
|
turn on a social sign-in; --own uses your OAuth app,
|
|
2483
2486
|
its secret from <PROVIDER>_CLIENT_SECRET or a prompt
|
|
2484
2487
|
vibiz auth providers rm <provider> [--dev] turn one off
|
|
2485
2488
|
vibiz auth domains <a.com,b.com|none> [--dev] only these email domains may sign up
|
|
2486
2489
|
vibiz company [--dev] [--json] the business behind this project: status, what blocks
|
|
2487
|
-
filing, the next step (production for
|
|
2490
|
+
filing, the next step (production for full-access keys)
|
|
2488
2491
|
vibiz company draft --file company.json [--dev] create or replace the draft (docs/COMPANY.md)
|
|
2489
2492
|
vibiz company submit [--dev] file it; production shows the price and asks you to
|
|
2490
2493
|
type the company's name (real filing, real fees)
|
|
@@ -2492,7 +2495,7 @@ var HELP = `vibiz \u2014 website, database and sign-in for a new business, in on
|
|
|
2492
2495
|
vibiz company docs [download <id>] [--dev] formation documents, or a short-lived download link
|
|
2493
2496
|
vibiz company simulate <formation|ein> development only: complete that step at the sandbox
|
|
2494
2497
|
vibiz payments [--dev] [--json] take payments: balance, getting paid, the next step
|
|
2495
|
-
(production for
|
|
2498
|
+
(production for full-access keys; --dev test mode)
|
|
2496
2499
|
vibiz payments products [--dev] the catalog; add one with
|
|
2497
2500
|
products add <name> --amount <cents> [--interval month|year] [--lookup-key k]
|
|
2498
2501
|
vibiz payments checkout <price_id|lookup_key> --success-url <u> --cancel-url <u> [--user id]
|
|
@@ -2524,7 +2527,7 @@ var HELP = `vibiz \u2014 website, database and sign-in for a new business, in on
|
|
|
2524
2527
|
vibiz social accounts [--dev] [--json] connected accounts and their ids
|
|
2525
2528
|
vibiz social post "<text>" --to <account,\u2026> [--media <file|url>]\u2026 [--at <iso>] [--draft]
|
|
2526
2529
|
[--opt key=value]\u2026 [--dev] publish now, schedule or draft; a live post asks you to
|
|
2527
|
-
confirm (
|
|
2530
|
+
confirm (a Limited key's post waits for the owner)
|
|
2528
2531
|
vibiz social posts [--status s] [--dev] posts, newest first
|
|
2529
2532
|
vibiz social approve|reject|cancel <post> [--dev] decide a waiting post, or cancel one
|
|
2530
2533
|
vibiz social campaigns [--dev] ad campaigns with budget and spend
|
|
@@ -2540,13 +2543,13 @@ var HELP = `vibiz \u2014 website, database and sign-in for a new business, in on
|
|
|
2540
2543
|
vibiz connectors ops <name> [--json] its operations: risk, on/off, parameters
|
|
2541
2544
|
vibiz connectors enable|disable <name> <op\u2026> allow (or stop) operations
|
|
2542
2545
|
vibiz connectors secret <name> <VAR> [--dev] set a key from $VAR or a hidden prompt; never printed.
|
|
2543
|
-
Production needs
|
|
2546
|
+
Production needs a full-access key
|
|
2544
2547
|
vibiz connectors call <name> <op> [key=value\u2026] [--body '<json>'] [--dev] [--approval <id>]
|
|
2545
2548
|
call it; dangerous operations (and production writes)
|
|
2546
|
-
by
|
|
2549
|
+
by a Limited key wait for the owner's approval
|
|
2547
2550
|
vibiz connectors check <name> [--dev] does the key work
|
|
2548
2551
|
vibiz connectors logs <name> [--dev] recent calls (no content)
|
|
2549
|
-
vibiz connectors approvals | approve <id> | deny <id> calls waiting for the owner (
|
|
2552
|
+
vibiz connectors approvals | approve <id> | deny <id> calls waiting for the owner (full-access key)
|
|
2550
2553
|
vibiz connect where does this app deploy? how that host gets its env
|
|
2551
2554
|
vibiz run -- <command\u2026> with VIBIZ_APP_KEY set (a server, a container, CI): run
|
|
2552
2555
|
the command with the app's env; any language
|
|
@@ -2555,7 +2558,7 @@ var HELP = `vibiz \u2014 website, database and sign-in for a new business, in on
|
|
|
2555
2558
|
vibiz hosts hosts outside Vibiz that get the env server to server
|
|
2556
2559
|
vibiz hosts add <host> <app> [field=value\u2026] [--dev]
|
|
2557
2560
|
connect your own host so Vibiz keeps its env in sync
|
|
2558
|
-
(
|
|
2561
|
+
(full-access key): vercel, netlify, render, railway, fly,
|
|
2559
2562
|
heroku, cloudflare-workers, cloudflare-pages,
|
|
2560
2563
|
github-actions. The token comes from the host's usual
|
|
2561
2564
|
variable (VERCEL_TOKEN, FLY_API_TOKEN\u2026) or a hidden
|
|
@@ -2569,7 +2572,7 @@ var HELP = `vibiz \u2014 website, database and sign-in for a new business, in on
|
|
|
2569
2572
|
what went wrong for visitors, then sessions to watch
|
|
2570
2573
|
vibiz replay <id> [--json] one session's signals and a link to watch it
|
|
2571
2574
|
vibiz projects list your projects
|
|
2572
|
-
Web data (billed per call
|
|
2575
|
+
Web data (billed per call; every run is kept: vibiz runs, console \u25B8 Web data)
|
|
2573
2576
|
vibiz scrape <url> [--json] one page as markdown
|
|
2574
2577
|
vibiz design <url> [--out design.md] [--tailwind] [--shadcn] [--css] [--own] [--pages /a,/b]
|
|
2575
2578
|
a site's design: type scale, colors, radii, spacing,
|
|
@@ -2634,7 +2637,7 @@ var HELP = `vibiz \u2014 website, database and sign-in for a new business, in on
|
|
|
2634
2637
|
recent messages (sender and subject only)
|
|
2635
2638
|
vibiz email unforward <address@domain|domain> [inbox]
|
|
2636
2639
|
stop forwarding to one inbox, one address, or (domain
|
|
2637
|
-
alone) the whole domain (
|
|
2640
|
+
alone) the whole domain (full-access keys)
|
|
2638
2641
|
vibiz email setup set up newsletters: the sending address news.<project>\u2026
|
|
2639
2642
|
(verifies in minutes). Then the owner adds the postal
|
|
2640
2643
|
address: vibiz email settings set --postal-address "\u2026"
|
|
@@ -2654,7 +2657,7 @@ var HELP = `vibiz \u2014 website, database and sign-in for a new business, in on
|
|
|
2654
2657
|
vibiz email broadcast list|stats <id>|review <id>|test <id> [--to a,b]|cancel <id>|resume <id>
|
|
2655
2658
|
vibiz email broadcast create --subject s --file body.md [--list l] [--segment s] [--html]
|
|
2656
2659
|
[--preview-text t] [--from-name n] [--name n] (edit <id> takes the same flags)
|
|
2657
|
-
vibiz email broadcast send <id> [--at <ISO time>] $0.001 an email;
|
|
2660
|
+
vibiz email broadcast send <id> [--at <ISO time>] $0.001 an email; Limited keys get the owner's
|
|
2658
2661
|
review link unless the owner set an allowance
|
|
2659
2662
|
vibiz email automation list|runs <id>|activate <id>|pause <id>
|
|
2660
2663
|
vibiz email automation create --file automation.json {name, trigger, steps, exit_event}
|
|
@@ -2687,11 +2690,12 @@ var HELP = `vibiz \u2014 website, database and sign-in for a new business, in on
|
|
|
2687
2690
|
vibiz billing [--json] the account's credits: balance, card, auto-recharge
|
|
2688
2691
|
vibiz billing top-up <dollars> [--open] a payment link to add credits (a person pays there)
|
|
2689
2692
|
vibiz billing history [--kind usage,topup] what came in and what used it
|
|
2690
|
-
vibiz billing auto-recharge on|off [--threshold 5] [--amount 25] (
|
|
2693
|
+
vibiz billing auto-recharge on|off [--threshold 5] [--amount 25] (full-access key)
|
|
2691
2694
|
vibiz metrics [--period 7d] [--json] request counts, error rate and latency by capability
|
|
2692
|
-
vibiz keys [create <name> [--
|
|
2693
|
-
named API keys, one per person or agent
|
|
2694
|
-
|
|
2695
|
+
vibiz keys [create <name> [--limited] | access <id> full|limited | revoke <id>]
|
|
2696
|
+
named API keys, one per person or agent: full
|
|
2697
|
+
access by default; Limited ones never move live
|
|
2698
|
+
money or read production secrets
|
|
2695
2699
|
vibiz admin metrics [--period 7d] [--json] [--open] the platform view (admin key)
|
|
2696
2700
|
vibiz mcp serve the Vibiz tools to AI agents (MCP, stdio)
|
|
2697
2701
|
vibiz mcp add --clients "<client>[,\u2026]" connect a coding agent to the remote MCP server once:
|
|
@@ -2757,6 +2761,7 @@ function printDomains(io, list2, only) {
|
|
|
2757
2761
|
io.log(` ${x.next_step}`);
|
|
2758
2762
|
}
|
|
2759
2763
|
}
|
|
2764
|
+
var accessLabel = (access) => access === "agent" ? "Limited access" : "full access";
|
|
2760
2765
|
var BUY_DOMAIN_COMMANDS = /* @__PURE__ */ new Set([
|
|
2761
2766
|
"search",
|
|
2762
2767
|
"buy",
|
|
@@ -3339,6 +3344,7 @@ async function runCli(argv2, io) {
|
|
|
3339
3344
|
"keep-values": { type: "boolean", default: false },
|
|
3340
3345
|
grace: { type: "string" },
|
|
3341
3346
|
owner: { type: "boolean", default: false },
|
|
3347
|
+
limited: { type: "boolean", default: false },
|
|
3342
3348
|
own: { type: "boolean", default: false },
|
|
3343
3349
|
"client-id": { type: "string" },
|
|
3344
3350
|
file: { type: "string" },
|
|
@@ -3472,7 +3478,7 @@ async function runCli(argv2, io) {
|
|
|
3472
3478
|
return;
|
|
3473
3479
|
}
|
|
3474
3480
|
io.log(`${me.account.name} (${me.account.id})`);
|
|
3475
|
-
io.log(` key ${me.key.name} ${me.key.prefix}\u2026 ${me.key.access}`);
|
|
3481
|
+
io.log(` key ${me.key.name} ${me.key.prefix}\u2026 ${accessLabel(me.key.access)}`);
|
|
3476
3482
|
const saved = await readLogin(io, io.configDir ?? CONFIG_DIR);
|
|
3477
3483
|
io.log(` api ${io.env.VIBIZ_API_URL || saved.apiUrl || DEFAULT_API_URL}`);
|
|
3478
3484
|
return;
|
|
@@ -4269,7 +4275,7 @@ ${link.url}`
|
|
|
4269
4275
|
${JSON.stringify(a.request)}`
|
|
4270
4276
|
);
|
|
4271
4277
|
}
|
|
4272
|
-
if (list2.length) io.log("Approve with
|
|
4278
|
+
if (list2.length) io.log("Approve with a full-access key: vibiz connectors approve <id>");
|
|
4273
4279
|
});
|
|
4274
4280
|
return;
|
|
4275
4281
|
}
|
|
@@ -5072,16 +5078,25 @@ The credits show in \`vibiz billing\` a few seconds after paying.`
|
|
|
5072
5078
|
const vibiz2 = await io.client();
|
|
5073
5079
|
const [sub, arg] = positionals;
|
|
5074
5080
|
if (sub === "create") {
|
|
5075
|
-
if (!arg) throw new Error("usage: vibiz keys create <name> [--
|
|
5076
|
-
const key = await vibiz2.apiKeys.create(arg, { access: values.
|
|
5081
|
+
if (!arg) throw new Error("usage: vibiz keys create <name> [--limited]");
|
|
5082
|
+
const key = await vibiz2.apiKeys.create(arg, { access: values.limited ? "agent" : "owner" });
|
|
5077
5083
|
io.log(
|
|
5078
|
-
`${key.name} ${key.id} ${key.access}
|
|
5084
|
+
`${key.name} ${key.id} ${accessLabel(key.access)}
|
|
5079
5085
|
${key.secret}
|
|
5080
5086
|
|
|
5081
5087
|
Store the key now: it is not shown again.`
|
|
5082
5088
|
);
|
|
5083
5089
|
return;
|
|
5084
5090
|
}
|
|
5091
|
+
if (sub === "access") {
|
|
5092
|
+
const level = positionals[2];
|
|
5093
|
+
if (!arg || level !== "full" && level !== "limited") {
|
|
5094
|
+
throw new Error("usage: vibiz keys access <key id> full|limited");
|
|
5095
|
+
}
|
|
5096
|
+
const k = await vibiz2.apiKeys.setAccess(arg, level === "full" ? "owner" : "agent");
|
|
5097
|
+
io.log(`${k.name} (${k.id}) now has ${accessLabel(k.access)}.`);
|
|
5098
|
+
return;
|
|
5099
|
+
}
|
|
5085
5100
|
if (sub === "revoke") {
|
|
5086
5101
|
if (!arg) throw new Error("usage: vibiz keys revoke <key id>");
|
|
5087
5102
|
await vibiz2.apiKeys.revoke(arg);
|
|
@@ -5090,7 +5105,7 @@ Store the key now: it is not shown again.`
|
|
|
5090
5105
|
}
|
|
5091
5106
|
for (const k of await vibiz2.apiKeys.list()) {
|
|
5092
5107
|
io.log(
|
|
5093
|
-
`${k.id} ${k.name.padEnd(20)} ${k.prefix}\u2026 ${(k.access
|
|
5108
|
+
`${k.id} ${k.name.padEnd(20)} ${k.prefix}\u2026 ${accessLabel(k.access).padEnd(14)} ${k.revoked_at ? "revoked" : "active"}`
|
|
5094
5109
|
);
|
|
5095
5110
|
}
|
|
5096
5111
|
return;
|
|
@@ -5110,7 +5125,7 @@ Store the key now: it is not shown again.`
|
|
|
5110
5125
|
return;
|
|
5111
5126
|
}
|
|
5112
5127
|
case "docs": {
|
|
5113
|
-
const { DOC_TOPICS, DOCS } = await import("./src-
|
|
5128
|
+
const { DOC_TOPICS, DOCS } = await import("./src-IAT2AUWC.js");
|
|
5114
5129
|
const topic = positionals[0];
|
|
5115
5130
|
if (!topic || !DOC_TOPICS.includes(topic)) {
|
|
5116
5131
|
for (const t of DOC_TOPICS) io.log(` vibiz docs ${t.padEnd(13)} ${DOCS[t].title}`);
|
|
@@ -5135,7 +5150,7 @@ ${DOCS[topic].body}`);
|
|
|
5135
5150
|
if (positionals[0])
|
|
5136
5151
|
throw new Error('usage: vibiz mcp (serve over stdio) | vibiz mcp add --clients "<client>"');
|
|
5137
5152
|
io.local();
|
|
5138
|
-
const { serveStdio } = await import("./src-
|
|
5153
|
+
const { serveStdio } = await import("./src-IAT2AUWC.js");
|
|
5139
5154
|
await serveStdio({ version: cliVersion() });
|
|
5140
5155
|
return;
|
|
5141
5156
|
}
|
|
@@ -5158,6 +5173,13 @@ function cliErrorLines(err) {
|
|
|
5158
5173
|
if (err instanceof VibizApiError) {
|
|
5159
5174
|
const out = [`\u2715 ${err.message} (${err.code})`];
|
|
5160
5175
|
const d = err.details;
|
|
5176
|
+
const problems = (Array.isArray(d?.problems) ? d.problems : []).filter(
|
|
5177
|
+
(p) => typeof p?.message === "string" && !err.message.includes(p.message.replace(/[.\s]+$/, ""))
|
|
5178
|
+
);
|
|
5179
|
+
for (const p of problems.slice(0, 10)) out.push(` \u2022 ${p.message}`);
|
|
5180
|
+
if (typeof d?.field === "string" && d.field && !err.message.includes(d.field) && !problems.length) {
|
|
5181
|
+
out.push(` field: ${d.field}`);
|
|
5182
|
+
}
|
|
5161
5183
|
if (d?.approval_id) out.push(` approval_id: ${d.approval_id}`);
|
|
5162
5184
|
if (d?.next_step) out.push(` ${d.next_step}`);
|
|
5163
5185
|
if (d?.console_url && !d.next_step?.includes(d.console_url)) out.push(` ${d.console_url}`);
|
|
@@ -5254,10 +5276,54 @@ async function aiKeysCommand(io, args, values) {
|
|
|
5254
5276
|
}
|
|
5255
5277
|
}
|
|
5256
5278
|
|
|
5279
|
+
// packages/cli/src/update-check.ts
|
|
5280
|
+
import { mkdir, readFile as readFile2, writeFile as writeFile2 } from "node:fs/promises";
|
|
5281
|
+
import { join as join7 } from "node:path";
|
|
5282
|
+
var DAY_MS = 24 * 60 * 60 * 1e3;
|
|
5283
|
+
var LATEST_URL = "https://registry.npmjs.org/@vibiz/cli/latest";
|
|
5284
|
+
function isNewer(latest, current) {
|
|
5285
|
+
const parse = (v) => /^\d+\.\d+\.\d+$/.test(v) ? v.split(".").map(Number) : null;
|
|
5286
|
+
const a = parse(latest);
|
|
5287
|
+
const b = parse(current);
|
|
5288
|
+
if (!a || !b) return false;
|
|
5289
|
+
for (let i = 0; i < 3; i++) {
|
|
5290
|
+
if (a[i] !== b[i]) return (a[i] ?? 0) > (b[i] ?? 0);
|
|
5291
|
+
}
|
|
5292
|
+
return false;
|
|
5293
|
+
}
|
|
5294
|
+
function updateNotice(latest, current) {
|
|
5295
|
+
if (!isNewer(latest, current)) return null;
|
|
5296
|
+
return [
|
|
5297
|
+
`A newer Vibiz CLI is out: ${current} \u2192 ${latest}. Some commands may be missing from this one.`,
|
|
5298
|
+
"Update: npm install -g @vibiz/cli@latest (then refresh the agent skills: vibiz skills add --global)"
|
|
5299
|
+
].join("\n");
|
|
5300
|
+
}
|
|
5301
|
+
async function latestVersion(configDir, env, fetchImpl = fetch, now = Date.now()) {
|
|
5302
|
+
if (env.VIBIZ_NO_UPDATE_CHECK || env.CI) return null;
|
|
5303
|
+
const file = join7(configDir, "update-check.json");
|
|
5304
|
+
let cache = null;
|
|
5305
|
+
try {
|
|
5306
|
+
cache = JSON.parse(await readFile2(file, "utf8"));
|
|
5307
|
+
} catch {
|
|
5308
|
+
}
|
|
5309
|
+
if (cache && now - cache.checkedAt < DAY_MS) return cache.latest;
|
|
5310
|
+
try {
|
|
5311
|
+
const res = await fetchImpl(LATEST_URL, { signal: AbortSignal.timeout(1500) });
|
|
5312
|
+
if (!res.ok) return cache?.latest ?? null;
|
|
5313
|
+
const { version } = await res.json();
|
|
5314
|
+
if (typeof version !== "string") return cache?.latest ?? null;
|
|
5315
|
+
await mkdir(configDir, { recursive: true });
|
|
5316
|
+
await writeFile2(file, JSON.stringify({ checkedAt: now, latest: version }));
|
|
5317
|
+
return version;
|
|
5318
|
+
} catch {
|
|
5319
|
+
return cache?.latest ?? null;
|
|
5320
|
+
}
|
|
5321
|
+
}
|
|
5322
|
+
|
|
5257
5323
|
// packages/cli/src/main.ts
|
|
5258
5324
|
async function readJson2(path) {
|
|
5259
5325
|
try {
|
|
5260
|
-
return JSON.parse(await
|
|
5326
|
+
return JSON.parse(await readFile3(path, "utf8"));
|
|
5261
5327
|
} catch {
|
|
5262
5328
|
return null;
|
|
5263
5329
|
}
|
|
@@ -5316,7 +5382,7 @@ var terminal = {
|
|
|
5316
5382
|
out: (text) => void process.stdout.write(text),
|
|
5317
5383
|
err: (text) => void process.stderr.write(text),
|
|
5318
5384
|
env: process.env,
|
|
5319
|
-
client: async () => new Vibiz(await login()),
|
|
5385
|
+
client: async () => new Vibiz({ ...await login(), client: `vibiz-cli/${cliVersion()}` }),
|
|
5320
5386
|
aiClient: async (project) => {
|
|
5321
5387
|
const { apiKey, baseUrl } = await login();
|
|
5322
5388
|
const headers = project ? { "x-vibiz-project": project } : void 0;
|
|
@@ -5332,19 +5398,46 @@ var terminal = {
|
|
|
5332
5398
|
});
|
|
5333
5399
|
},
|
|
5334
5400
|
project: async () => {
|
|
5335
|
-
|
|
5336
|
-
|
|
5337
|
-
|
|
5401
|
+
for (let dir = process.cwd(); ; dir = dirname5(dir)) {
|
|
5402
|
+
const linked = await readJson2(join8(dir, PROJECT_FILE));
|
|
5403
|
+
if (linked?.project_id) return linked.project_id;
|
|
5404
|
+
if (dirname5(dir) === dir) break;
|
|
5405
|
+
}
|
|
5406
|
+
const list2 = await new Vibiz(await login()).projects.list();
|
|
5407
|
+
const wanted = process.env.VIBIZ_PROJECT?.trim().toLowerCase();
|
|
5408
|
+
if (wanted) {
|
|
5409
|
+
const p = list2.find((x) => [x.id, x.slug, x.name.toLowerCase()].includes(wanted));
|
|
5410
|
+
if (p) return p.id;
|
|
5411
|
+
throw new Error(`No project "${process.env.VIBIZ_PROJECT}" on this account.`);
|
|
5412
|
+
}
|
|
5413
|
+
const lines = list2.map((p, i) => ` ${i + 1}. ${p.name} (${p.slug}, ${p.id})`);
|
|
5414
|
+
if (list2.length && process.stdin.isTTY) {
|
|
5415
|
+
console.error(`No ${PROJECT_FILE} here. Which project?
|
|
5416
|
+
${lines.join("\n")}`);
|
|
5417
|
+
const n = Number(await promptLine("Number (Enter to cancel): "));
|
|
5418
|
+
const p = list2[n - 1];
|
|
5419
|
+
if (!p) throw new Error("Cancelled.");
|
|
5420
|
+
const link = (await promptLine(`Link this folder to ${p.name} (writes ${PROJECT_FILE})? [y/N] `)).trim().toLowerCase();
|
|
5421
|
+
if (link === "y" || link === "yes") {
|
|
5422
|
+
await writeFile3(PROJECT_FILE, `${JSON.stringify({ project_id: p.id }, null, 2)}
|
|
5423
|
+
`);
|
|
5424
|
+
}
|
|
5425
|
+
return p.id;
|
|
5426
|
+
}
|
|
5427
|
+
throw new Error(
|
|
5428
|
+
list2.length ? `No ${PROJECT_FILE} here. Run it in the app's folder, or name the project: VIBIZ_PROJECT=<slug> vibiz \u2026
|
|
5429
|
+
${lines.join("\n")}` : `No ${PROJECT_FILE} here and no projects yet. Run: vibiz init <name>`
|
|
5430
|
+
);
|
|
5338
5431
|
},
|
|
5339
5432
|
promptHidden,
|
|
5340
5433
|
promptLine,
|
|
5341
5434
|
openUrl,
|
|
5342
5435
|
local: () => ({
|
|
5343
5436
|
cwd: () => process.cwd(),
|
|
5344
|
-
readFile:
|
|
5345
|
-
writeFile:
|
|
5437
|
+
readFile: readFile3,
|
|
5438
|
+
writeFile: writeFile3,
|
|
5346
5439
|
chmod,
|
|
5347
|
-
mkdir,
|
|
5440
|
+
mkdir: mkdir2,
|
|
5348
5441
|
exec: (cmd, args, env, opts) => {
|
|
5349
5442
|
const child = spawn(cmd, args, { stdio: "inherit", env });
|
|
5350
5443
|
if (opts?.forwardSignals) {
|
|
@@ -5364,8 +5457,16 @@ var argv = process.argv.slice(2);
|
|
|
5364
5457
|
if (argv[0] === "--version" || argv[0] === "-v") {
|
|
5365
5458
|
console.log(cliVersion());
|
|
5366
5459
|
} else {
|
|
5367
|
-
|
|
5460
|
+
const latest = latestVersion(CONFIG_DIR, process.env);
|
|
5461
|
+
const notice = async () => {
|
|
5462
|
+
const v = await latest;
|
|
5463
|
+
const text = v && updateNotice(v, cliVersion());
|
|
5464
|
+
if (text) console.error(`
|
|
5465
|
+
${text}`);
|
|
5466
|
+
};
|
|
5467
|
+
runCli(argv, terminal).then(notice).catch(async (err) => {
|
|
5368
5468
|
for (const line of cliErrorLines(err)) console.error(line);
|
|
5469
|
+
await notice();
|
|
5369
5470
|
process.exit(1);
|
|
5370
5471
|
});
|
|
5371
5472
|
}
|
package/package.json
CHANGED