@rebasepro/cli 0.9.1-canary.ed943fa → 0.9.1-canary.f0ac103
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/commands/cloud/context.d.ts +6 -0
- package/dist/commands/cloud/deployments.d.ts +1 -0
- package/dist/commands/cloud/power.d.ts +1 -0
- package/dist/commands/skills.d.ts +1 -1
- package/dist/index.es.js +18 -186
- package/dist/index.es.js.map +1 -1
- package/package.json +7 -7
- package/templates/template/config/collections/users.ts +0 -2
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { createRebaseClient } from "@rebasepro/client";
|
|
2
|
+
/** Default hosted control plane (the Rebase Cloud console origin). */
|
|
3
|
+
export declare const DEFAULT_CLOUD_URL = "https://app.rebase.pro";
|
|
2
4
|
/** Project-local link file: <project>/.rebase/cloud.json */
|
|
3
5
|
export declare function projectLinkPath(cwd?: string): string;
|
|
6
|
+
/** Host that a bare `rebase cloud` command should target, if any. */
|
|
7
|
+
export declare function currentContextUrl(): string | undefined;
|
|
4
8
|
/** Persist the active organization id for a host. */
|
|
5
9
|
export declare function setContextOrg(url: string, org: string | undefined): void;
|
|
6
10
|
export declare function getContextOrg(url: string): string | undefined;
|
|
@@ -100,6 +104,8 @@ export declare function initOutputMode(rawArgs: string[]): boolean;
|
|
|
100
104
|
export declare function isJsonMode(): boolean;
|
|
101
105
|
/** Force the mode (tests only — production latches it via `initOutputMode`). */
|
|
102
106
|
export declare function setJsonModeForTest(value: boolean): void;
|
|
107
|
+
/** Write one JSON value to stdout, followed by a newline. */
|
|
108
|
+
export declare function printJson(value: unknown): void;
|
|
103
109
|
/**
|
|
104
110
|
* The one output primitive every new command uses: in JSON mode emit `json`
|
|
105
111
|
* (and nothing else); otherwise run `human`. Keeping the two behind a single
|
|
@@ -19,6 +19,7 @@ export interface DeploymentRow {
|
|
|
19
19
|
gitCommitHash?: string;
|
|
20
20
|
gitCommitMessage?: string;
|
|
21
21
|
}
|
|
22
|
+
export declare function deploymentImage(dep: DeploymentRow): string | null;
|
|
22
23
|
/**
|
|
23
24
|
* The backend's rule EXACTLY: a rollback is honoured only for a successful
|
|
24
25
|
* deploy that recorded an image. Any other row 409s `deploy_not_rollbackable`.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare function skillsCommand(subcommand: string | undefined,
|
|
1
|
+
export declare function skillsCommand(subcommand: string | undefined, _args: string[]): Promise<void>;
|
package/dist/index.es.js
CHANGED
|
@@ -135,8 +135,7 @@ function getPMCommands(pm) {
|
|
|
135
135
|
runWorkspace: (workspace, script) => [
|
|
136
136
|
"pnpm",
|
|
137
137
|
"--filter",
|
|
138
|
-
|
|
139
|
-
"run",
|
|
138
|
+
workspace,
|
|
140
139
|
script
|
|
141
140
|
],
|
|
142
141
|
dlx: (pkg, args) => [
|
|
@@ -943,13 +942,6 @@ async function promptForOptions(rawArgs, pm) {
|
|
|
943
942
|
cloudUrl: resolveCloudUrl(rawArgs)
|
|
944
943
|
};
|
|
945
944
|
}
|
|
946
|
-
if (!process.stdin.isTTY) {
|
|
947
|
-
console.error(chalk.red("Cannot prompt: this is a non-interactive terminal (no TTY)."));
|
|
948
|
-
console.error(chalk.yellow(" Re-run with --yes to accept defaults, passing any choices as flags, e.g.:"));
|
|
949
|
-
console.error(chalk.yellow(` rebase init ${nameArg || "my-app"} --yes --template blog --flavor cms`));
|
|
950
|
-
console.error(chalk.gray(" Options: --template <blog|ecommerce|blank> --flavor <cms|baas> --database-url <url> --install --git"));
|
|
951
|
-
process.exit(1);
|
|
952
|
-
}
|
|
953
945
|
const questions = buildInitQuestions({
|
|
954
946
|
nameArg,
|
|
955
947
|
templateArg,
|
|
@@ -2477,43 +2469,22 @@ function installForAgent(agentKey, skills, projectDir) {
|
|
|
2477
2469
|
}
|
|
2478
2470
|
return count;
|
|
2479
2471
|
}
|
|
2480
|
-
async function skillsCommand(subcommand,
|
|
2472
|
+
async function skillsCommand(subcommand, _args) {
|
|
2481
2473
|
switch (subcommand) {
|
|
2482
2474
|
case "install":
|
|
2483
|
-
await skillsInstall(
|
|
2475
|
+
await skillsInstall();
|
|
2484
2476
|
break;
|
|
2485
2477
|
case "--help":
|
|
2486
2478
|
case void 0:
|
|
2487
2479
|
printSkillsHelp();
|
|
2488
2480
|
break;
|
|
2489
2481
|
default:
|
|
2490
|
-
console.
|
|
2482
|
+
console.log(chalk.red(`Unknown skills subcommand: ${subcommand}`));
|
|
2491
2483
|
console.log("");
|
|
2492
2484
|
printSkillsHelp();
|
|
2493
|
-
process.exit(1);
|
|
2494
2485
|
}
|
|
2495
2486
|
}
|
|
2496
|
-
|
|
2497
|
-
* Agents named explicitly on the command line, e.g. `--agent claude --agent cursor`
|
|
2498
|
-
* (also accepts a comma-separated list). Returns null when none were given.
|
|
2499
|
-
*/
|
|
2500
|
-
function parseAgentFlags(rawArgs) {
|
|
2501
|
-
const requested = [];
|
|
2502
|
-
for (let i = 0; i < rawArgs.length; i++) {
|
|
2503
|
-
if (rawArgs[i] !== "--agent" && rawArgs[i] !== "-a") continue;
|
|
2504
|
-
const value = rawArgs[i + 1];
|
|
2505
|
-
if (value && !value.startsWith("-")) requested.push(...value.split(",").map((v) => v.trim()).filter(Boolean));
|
|
2506
|
-
}
|
|
2507
|
-
if (requested.length === 0) return null;
|
|
2508
|
-
const valid = Object.keys(AGENTS);
|
|
2509
|
-
const unknown = requested.filter((a) => !valid.includes(a));
|
|
2510
|
-
if (unknown.length > 0) {
|
|
2511
|
-
console.error(chalk.red(`Unknown agent(s): ${unknown.join(", ")}. Available: ${valid.join(", ")}`));
|
|
2512
|
-
process.exit(1);
|
|
2513
|
-
}
|
|
2514
|
-
return requested;
|
|
2515
|
-
}
|
|
2516
|
-
async function skillsInstall(rawArgs = []) {
|
|
2487
|
+
async function skillsInstall() {
|
|
2517
2488
|
const projectDir = process.cwd();
|
|
2518
2489
|
let skillsDir;
|
|
2519
2490
|
try {
|
|
@@ -2527,14 +2498,8 @@ async function skillsInstall(rawArgs = []) {
|
|
|
2527
2498
|
console.error(`${chalk.red.bold("ERROR")} No skills found in ${skillsDir}`);
|
|
2528
2499
|
process.exit(1);
|
|
2529
2500
|
}
|
|
2530
|
-
let agents =
|
|
2501
|
+
let agents = detectAgents(projectDir);
|
|
2531
2502
|
if (agents.length === 0) {
|
|
2532
|
-
if (!process.stdin.isTTY) {
|
|
2533
|
-
console.error(chalk.red("Cannot prompt: this is a non-interactive terminal (no TTY)."));
|
|
2534
|
-
console.error(chalk.yellow(` Name the agents explicitly, e.g. rebase skills install --agent ${Object.keys(AGENTS)[0]}`));
|
|
2535
|
-
console.error(chalk.gray(` Available: ${Object.keys(AGENTS).join(", ")}`));
|
|
2536
|
-
process.exit(1);
|
|
2537
|
-
}
|
|
2538
2503
|
const choices = Object.entries(AGENTS).map(([key, agent]) => ({
|
|
2539
2504
|
name: agent.label,
|
|
2540
2505
|
value: key,
|
|
@@ -2576,15 +2541,8 @@ ${chalk.green.bold("Subcommands")}
|
|
|
2576
2541
|
${chalk.blue.bold("install")} Install Rebase agent skills for your AI coding assistant
|
|
2577
2542
|
Supports: Cursor, Claude Code, Windsurf, Gemini CLI, Antigravity
|
|
2578
2543
|
|
|
2579
|
-
${chalk.green.bold("Options")}
|
|
2580
|
-
${chalk.blue("--agent, -a")} Agent(s) to install for, skipping detection and the prompt.
|
|
2581
|
-
Repeat the flag or pass a comma-separated list.
|
|
2582
|
-
Available: ${Object.keys(AGENTS).join(", ")}
|
|
2583
|
-
|
|
2584
2544
|
${chalk.green.bold("Examples")}
|
|
2585
2545
|
${chalk.cyan("rebase skills install")}
|
|
2586
|
-
${chalk.cyan("rebase skills install --agent claude")}
|
|
2587
|
-
${chalk.cyan("rebase skills install --agent claude,cursor")}
|
|
2588
2546
|
`);
|
|
2589
2547
|
}
|
|
2590
2548
|
//#endregion
|
|
@@ -2616,16 +2574,9 @@ function loadEnv(projectRoot) {
|
|
|
2616
2574
|
}
|
|
2617
2575
|
return env;
|
|
2618
2576
|
}
|
|
2619
|
-
function resolveBaseUrl(env
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
const urlFile = path.join(projectRoot, ".rebase-dev-url");
|
|
2623
|
-
if (fs.existsSync(urlFile)) {
|
|
2624
|
-
const devUrl = fs.readFileSync(urlFile, "utf-8").trim();
|
|
2625
|
-
if (devUrl) return devUrl;
|
|
2626
|
-
}
|
|
2627
|
-
} catch {}
|
|
2628
|
-
return `http://localhost:${env.PORT || env.REBASE_PORT || "3001"}`;
|
|
2577
|
+
function resolveBaseUrl(env) {
|
|
2578
|
+
const port = env.PORT || env.REBASE_PORT || "3001";
|
|
2579
|
+
return env.REBASE_BASE_URL || `http://localhost:${port}`;
|
|
2629
2580
|
}
|
|
2630
2581
|
async function apiKeysCommand(subcommand, rawArgs) {
|
|
2631
2582
|
if (!subcommand || subcommand === "--help") {
|
|
@@ -2650,9 +2601,8 @@ async function apiKeysCommand(subcommand, rawArgs) {
|
|
|
2650
2601
|
}
|
|
2651
2602
|
}
|
|
2652
2603
|
async function listKeys(_rawArgs) {
|
|
2653
|
-
const
|
|
2654
|
-
const
|
|
2655
|
-
const baseUrl = resolveBaseUrl(env, projectRoot);
|
|
2604
|
+
const env = loadEnv(requireProjectRoot());
|
|
2605
|
+
const baseUrl = resolveBaseUrl(env);
|
|
2656
2606
|
const serviceKey = env.SERVICE_KEY || env.REBASE_SERVICE_KEY;
|
|
2657
2607
|
if (!serviceKey) {
|
|
2658
2608
|
console.error(chalk.red("✗ SERVICE_KEY not found in .env — required for admin operations."));
|
|
@@ -2757,9 +2707,8 @@ async function createKey(rawArgs) {
|
|
|
2757
2707
|
expires_at = parsed.toISOString();
|
|
2758
2708
|
}
|
|
2759
2709
|
}
|
|
2760
|
-
const
|
|
2761
|
-
const
|
|
2762
|
-
const baseUrl = resolveBaseUrl(env, projectRoot);
|
|
2710
|
+
const env = loadEnv(requireProjectRoot());
|
|
2711
|
+
const baseUrl = resolveBaseUrl(env);
|
|
2763
2712
|
const serviceKey = env.SERVICE_KEY || env.REBASE_SERVICE_KEY;
|
|
2764
2713
|
if (!serviceKey) {
|
|
2765
2714
|
console.error(chalk.red("✗ SERVICE_KEY not found in .env — required for admin operations."));
|
|
@@ -2816,9 +2765,8 @@ async function revokeKey(rawArgs) {
|
|
|
2816
2765
|
console.log(chalk.gray(" Usage: rebase api-keys revoke <key-id>"));
|
|
2817
2766
|
process.exit(1);
|
|
2818
2767
|
}
|
|
2819
|
-
const
|
|
2820
|
-
const
|
|
2821
|
-
const baseUrl = resolveBaseUrl(env, projectRoot);
|
|
2768
|
+
const env = loadEnv(requireProjectRoot());
|
|
2769
|
+
const baseUrl = resolveBaseUrl(env);
|
|
2822
2770
|
const serviceKey = env.SERVICE_KEY || env.REBASE_SERVICE_KEY;
|
|
2823
2771
|
if (!serviceKey) {
|
|
2824
2772
|
console.error(chalk.red("✗ SERVICE_KEY not found in .env — required for admin operations."));
|
|
@@ -3287,18 +3235,13 @@ function fmtDate(value) {
|
|
|
3287
3235
|
*/
|
|
3288
3236
|
var POLL_INTERVAL_MS = 1500;
|
|
3289
3237
|
var POLL_TIMEOUT_MS = 900 * 1e3;
|
|
3290
|
-
var MAX_SOURCE_UPLOAD_BYTES = 100 * 1024 * 1024;
|
|
3291
3238
|
function sleep(ms) {
|
|
3292
3239
|
return new Promise((r) => setTimeout(r, ms));
|
|
3293
3240
|
}
|
|
3294
|
-
function run(cmd, cmdArgs, cwd
|
|
3241
|
+
function run(cmd, cmdArgs, cwd) {
|
|
3295
3242
|
return new Promise((resolve, reject) => {
|
|
3296
3243
|
const child = spawn(cmd, cmdArgs, {
|
|
3297
3244
|
cwd,
|
|
3298
|
-
env: env ? {
|
|
3299
|
-
...process.env,
|
|
3300
|
-
...env
|
|
3301
|
-
} : void 0,
|
|
3302
3245
|
stdio: [
|
|
3303
3246
|
"ignore",
|
|
3304
3247
|
"ignore",
|
|
@@ -3328,7 +3271,7 @@ async function createSourceTarball(sourceDir) {
|
|
|
3328
3271
|
for (const ignore of [".gitignore", ".rebaseignore"]) if (fs.existsSync(path.join(dir, ignore))) tarArgs.push(`--exclude-from=${ignore}`);
|
|
3329
3272
|
tarArgs.push(".");
|
|
3330
3273
|
try {
|
|
3331
|
-
await run("tar", tarArgs, dir
|
|
3274
|
+
await run("tar", tarArgs, dir);
|
|
3332
3275
|
} catch (e) {
|
|
3333
3276
|
fail(`Failed to package source: ${e instanceof Error ? e.message : String(e)}`);
|
|
3334
3277
|
}
|
|
@@ -3338,7 +3281,6 @@ async function createSourceTarball(sourceDir) {
|
|
|
3338
3281
|
async function uploadSource(url, token, projectId, tarPath) {
|
|
3339
3282
|
const bytes = fs.readFileSync(tarPath);
|
|
3340
3283
|
const sizeMb = (bytes.length / 1024 / 1024).toFixed(1);
|
|
3341
|
-
if (bytes.length > MAX_SOURCE_UPLOAD_BYTES) fail(`Source context is ${sizeMb} MB — the upload cap is ${Math.round(MAX_SOURCE_UPLOAD_BYTES / 1024 / 1024)} MB.`, "Trim the build context: exclude sourcemaps (*.map), build output and large assets via .rebaseignore or .gitignore.");
|
|
3342
3284
|
console.log(chalk.gray(` Uploading source (${sizeMb} MB)...`));
|
|
3343
3285
|
const res = await fetch(`${url}/api/functions/deploy/upload?projectId=${encodeURIComponent(projectId)}`, {
|
|
3344
3286
|
method: "POST",
|
|
@@ -4318,8 +4260,6 @@ ${chalk.green.bold("Options")}
|
|
|
4318
4260
|
${chalk.blue("--secret")} Mark a variable write-only ${chalk.gray("(set)")}
|
|
4319
4261
|
${chalk.blue("--json")} Machine-readable output
|
|
4320
4262
|
${chalk.blue("--project, -p")} Project slug ${chalk.gray("(defaults to the linked project)")}
|
|
4321
|
-
|
|
4322
|
-
${chalk.gray("Values are encrypted at rest (AES-256-GCM) and only decrypted at deploy time.")}
|
|
4323
4263
|
`);
|
|
4324
4264
|
}
|
|
4325
4265
|
function printEnvHelpJson() {
|
|
@@ -5228,10 +5168,6 @@ async function webhooksCommand(subcommand, rawArgs) {
|
|
|
5228
5168
|
}
|
|
5229
5169
|
}
|
|
5230
5170
|
async function storageCommand(rawArgs) {
|
|
5231
|
-
const action = rawArgs[2];
|
|
5232
|
-
if (action === "create") return storageCreateCommand(rawArgs);
|
|
5233
|
-
if (action === "attach") return storageAttachCommand(rawArgs);
|
|
5234
|
-
if (action === "--help" || action === "help") return printStorageHelp();
|
|
5235
5171
|
const { client } = await requireClient(rawArgs);
|
|
5236
5172
|
const projectId = await requireProject(rawArgs, client);
|
|
5237
5173
|
try {
|
|
@@ -5256,107 +5192,6 @@ async function storageCommand(rawArgs) {
|
|
|
5256
5192
|
reportError(e, "Failed to list storage");
|
|
5257
5193
|
}
|
|
5258
5194
|
}
|
|
5259
|
-
function printStorageHelp() {
|
|
5260
|
-
console.log("");
|
|
5261
|
-
console.log(chalk.bold(" rebase cloud storage"));
|
|
5262
|
-
console.log("");
|
|
5263
|
-
console.log(" " + chalk.blue.bold("storage") + " List this project's storage");
|
|
5264
|
-
console.log(" " + chalk.blue.bold("storage create") + " Provision platform-managed storage");
|
|
5265
|
-
console.log(" " + chalk.blue.bold("storage attach") + " Attach your own S3-compatible bucket");
|
|
5266
|
-
console.log("");
|
|
5267
|
-
console.log(chalk.gray(" attach options:"));
|
|
5268
|
-
console.log(chalk.gray(" --bucket <name> Bucket name (required)"));
|
|
5269
|
-
console.log(chalk.gray(" --access-key-id <id> Access key ID (required)"));
|
|
5270
|
-
console.log(chalk.gray(" --secret-access-key <s> Secret access key (required)"));
|
|
5271
|
-
console.log(chalk.gray(" --endpoint <url> S3 endpoint; omit for AWS"));
|
|
5272
|
-
console.log(chalk.gray(" --region <region> Region"));
|
|
5273
|
-
console.log(chalk.gray(" --force-path-style Required by MinIO and some gateways"));
|
|
5274
|
-
console.log("");
|
|
5275
|
-
console.log(chalk.gray(" Without either, a tenant falls back to the container filesystem and"));
|
|
5276
|
-
console.log(chalk.gray(" loses uploaded files on its next restart."));
|
|
5277
|
-
console.log("");
|
|
5278
|
-
}
|
|
5279
|
-
async function storageCreateCommand(rawArgs) {
|
|
5280
|
-
const { client } = await requireClient(rawArgs);
|
|
5281
|
-
const projectId = await requireProject(rawArgs, client);
|
|
5282
|
-
try {
|
|
5283
|
-
console.log("");
|
|
5284
|
-
console.log(chalk.gray(" Provisioning managed storage — this creates a bucket and its credentials..."));
|
|
5285
|
-
const res = await client.functions.invoke(`storage-provision/${encodeURIComponent(projectId)}`, void 0, { method: "POST" });
|
|
5286
|
-
const info = res.data ?? res.data;
|
|
5287
|
-
success(`Managed storage provisioned for ${displayProjectRef(rawArgs)}.`);
|
|
5288
|
-
keyValues([
|
|
5289
|
-
["Bucket", info.bucketName],
|
|
5290
|
-
["Region", info.region],
|
|
5291
|
-
["Endpoint", info.endpoint],
|
|
5292
|
-
["Access key", info.accessKeyId]
|
|
5293
|
-
]);
|
|
5294
|
-
console.log("");
|
|
5295
|
-
console.log(chalk.gray(" The secret key is stored encrypted and injected at deploy time; it is not displayed."));
|
|
5296
|
-
console.log(chalk.gray(" Redeploy for the tenant to pick it up: ") + chalk.bold("rebase cloud deploy"));
|
|
5297
|
-
console.log("");
|
|
5298
|
-
} catch (e) {
|
|
5299
|
-
reportError(e, "Failed to provision managed storage");
|
|
5300
|
-
}
|
|
5301
|
-
}
|
|
5302
|
-
async function storageAttachCommand(rawArgs) {
|
|
5303
|
-
const parsed = arg({
|
|
5304
|
-
"--bucket": String,
|
|
5305
|
-
"--access-key-id": String,
|
|
5306
|
-
"--secret-access-key": String,
|
|
5307
|
-
"--endpoint": String,
|
|
5308
|
-
"--region": String,
|
|
5309
|
-
"--force-path-style": Boolean
|
|
5310
|
-
}, {
|
|
5311
|
-
argv: rawArgs.slice(3),
|
|
5312
|
-
permissive: true
|
|
5313
|
-
});
|
|
5314
|
-
const bucket = parsed["--bucket"];
|
|
5315
|
-
const accessKeyId = parsed["--access-key-id"];
|
|
5316
|
-
const secretAccessKey = parsed["--secret-access-key"];
|
|
5317
|
-
const missing = [
|
|
5318
|
-
!bucket && "--bucket",
|
|
5319
|
-
!accessKeyId && "--access-key-id",
|
|
5320
|
-
!secretAccessKey && "--secret-access-key"
|
|
5321
|
-
].filter(Boolean);
|
|
5322
|
-
if (missing.length > 0) fail(`Missing ${missing.join(", ")}.`, "A bucket without credentials cannot be used, and would be stored as though it could. Run `rebase cloud storage --help` for the full list.");
|
|
5323
|
-
const { client } = await requireClient(rawArgs);
|
|
5324
|
-
const projectId = await requireProject(rawArgs, client);
|
|
5325
|
-
try {
|
|
5326
|
-
const existing = (await client.data.collection("storages").find({
|
|
5327
|
-
where: { project: ["==", projectId] },
|
|
5328
|
-
limit: 1
|
|
5329
|
-
})).data[0];
|
|
5330
|
-
const row = {
|
|
5331
|
-
project: projectId,
|
|
5332
|
-
type: "byos",
|
|
5333
|
-
status: "active",
|
|
5334
|
-
s3Bucket: bucket,
|
|
5335
|
-
s3AccessKeyId: accessKeyId,
|
|
5336
|
-
s3SecretAccessKey: secretAccessKey,
|
|
5337
|
-
bucketName: bucket
|
|
5338
|
-
};
|
|
5339
|
-
if (parsed["--endpoint"]) row.s3Endpoint = parsed["--endpoint"];
|
|
5340
|
-
if (parsed["--region"]) {
|
|
5341
|
-
row.s3Region = parsed["--region"];
|
|
5342
|
-
row.region = parsed["--region"];
|
|
5343
|
-
}
|
|
5344
|
-
if (parsed["--force-path-style"]) row.s3ForcePathStyle = true;
|
|
5345
|
-
if (existing?.id) await client.data.collection("storages").update(String(existing.id), row);
|
|
5346
|
-
else await client.data.collection("storages").create(row);
|
|
5347
|
-
success(`Storage attached to ${displayProjectRef(rawArgs)}.`);
|
|
5348
|
-
keyValues([
|
|
5349
|
-
["Bucket", bucket],
|
|
5350
|
-
["Endpoint", parsed["--endpoint"] ?? "AWS S3"],
|
|
5351
|
-
["Region", parsed["--region"] ?? "(default)"]
|
|
5352
|
-
]);
|
|
5353
|
-
console.log("");
|
|
5354
|
-
console.log(chalk.gray(" Redeploy for the tenant to pick it up: ") + chalk.bold("rebase cloud deploy"));
|
|
5355
|
-
console.log("");
|
|
5356
|
-
} catch (e) {
|
|
5357
|
-
reportError(e, "Failed to attach storage");
|
|
5358
|
-
}
|
|
5359
|
-
}
|
|
5360
5195
|
async function clustersCommand(rawArgs) {
|
|
5361
5196
|
const { client } = await requireClient(rawArgs);
|
|
5362
5197
|
try {
|
|
@@ -5677,8 +5512,6 @@ ${chalk.green.bold("Databases")}
|
|
|
5677
5512
|
${chalk.green.bold("Other resources")}
|
|
5678
5513
|
${chalk.blue.bold("webhooks list|create|delete")}
|
|
5679
5514
|
${chalk.blue.bold("storage")} List storage buckets
|
|
5680
|
-
${chalk.blue.bold("storage create")} Provision platform-managed storage
|
|
5681
|
-
${chalk.blue.bold("storage attach")} Attach your own S3-compatible bucket
|
|
5682
5515
|
${chalk.blue.bold("clusters")} List compute clusters
|
|
5683
5516
|
${chalk.blue.bold("billing setup")} Attach a card to the org ${chalk.gray("(one-time, opens browser)")}
|
|
5684
5517
|
${chalk.blue.bold("billing")} Show billing account + card on file
|
|
@@ -5787,10 +5620,9 @@ async function entry(args) {
|
|
|
5787
5620
|
await cloudCommand(effectiveSubcommand, args);
|
|
5788
5621
|
break;
|
|
5789
5622
|
default:
|
|
5790
|
-
console.
|
|
5623
|
+
console.log(chalk.red(`Unknown command: ${command}`));
|
|
5791
5624
|
console.log("");
|
|
5792
5625
|
printHelp();
|
|
5793
|
-
process.exit(1);
|
|
5794
5626
|
}
|
|
5795
5627
|
}
|
|
5796
5628
|
function printHelp() {
|