@rebasepro/cli 0.9.1-canary.7ba0e49 → 0.9.1-canary.97e305f

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.
@@ -1 +1 @@
1
- export declare function skillsCommand(subcommand: string | undefined, _args: string[]): Promise<void>;
1
+ export declare function skillsCommand(subcommand: string | undefined, rawArgs: string[]): Promise<void>;
package/dist/index.es.js CHANGED
@@ -2477,22 +2477,43 @@ function installForAgent(agentKey, skills, projectDir) {
2477
2477
  }
2478
2478
  return count;
2479
2479
  }
2480
- async function skillsCommand(subcommand, _args) {
2480
+ async function skillsCommand(subcommand, rawArgs) {
2481
2481
  switch (subcommand) {
2482
2482
  case "install":
2483
- await skillsInstall();
2483
+ await skillsInstall(rawArgs);
2484
2484
  break;
2485
2485
  case "--help":
2486
2486
  case void 0:
2487
2487
  printSkillsHelp();
2488
2488
  break;
2489
2489
  default:
2490
- console.log(chalk.red(`Unknown skills subcommand: ${subcommand}`));
2490
+ console.error(chalk.red(`Unknown skills subcommand: ${subcommand}`));
2491
2491
  console.log("");
2492
2492
  printSkillsHelp();
2493
+ process.exit(1);
2493
2494
  }
2494
2495
  }
2495
- async function skillsInstall() {
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 = []) {
2496
2517
  const projectDir = process.cwd();
2497
2518
  let skillsDir;
2498
2519
  try {
@@ -2506,8 +2527,14 @@ async function skillsInstall() {
2506
2527
  console.error(`${chalk.red.bold("ERROR")} No skills found in ${skillsDir}`);
2507
2528
  process.exit(1);
2508
2529
  }
2509
- let agents = detectAgents(projectDir);
2530
+ let agents = parseAgentFlags(rawArgs) ?? detectAgents(projectDir);
2510
2531
  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
+ }
2511
2538
  const choices = Object.entries(AGENTS).map(([key, agent]) => ({
2512
2539
  name: agent.label,
2513
2540
  value: key,
@@ -2549,8 +2576,15 @@ ${chalk.green.bold("Subcommands")}
2549
2576
  ${chalk.blue.bold("install")} Install Rebase agent skills for your AI coding assistant
2550
2577
  Supports: Cursor, Claude Code, Windsurf, Gemini CLI, Antigravity
2551
2578
 
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
+
2552
2584
  ${chalk.green.bold("Examples")}
2553
2585
  ${chalk.cyan("rebase skills install")}
2586
+ ${chalk.cyan("rebase skills install --agent claude")}
2587
+ ${chalk.cyan("rebase skills install --agent claude,cursor")}
2554
2588
  `);
2555
2589
  }
2556
2590
  //#endregion
@@ -2582,9 +2616,16 @@ function loadEnv(projectRoot) {
2582
2616
  }
2583
2617
  return env;
2584
2618
  }
2585
- function resolveBaseUrl(env) {
2586
- const port = env.PORT || env.REBASE_PORT || "3001";
2587
- return env.REBASE_BASE_URL || `http://localhost:${port}`;
2619
+ function resolveBaseUrl(env, projectRoot) {
2620
+ if (env.REBASE_BASE_URL) return env.REBASE_BASE_URL;
2621
+ if (projectRoot) try {
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"}`;
2588
2629
  }
2589
2630
  async function apiKeysCommand(subcommand, rawArgs) {
2590
2631
  if (!subcommand || subcommand === "--help") {
@@ -2609,8 +2650,9 @@ async function apiKeysCommand(subcommand, rawArgs) {
2609
2650
  }
2610
2651
  }
2611
2652
  async function listKeys(_rawArgs) {
2612
- const env = loadEnv(requireProjectRoot());
2613
- const baseUrl = resolveBaseUrl(env);
2653
+ const projectRoot = requireProjectRoot();
2654
+ const env = loadEnv(projectRoot);
2655
+ const baseUrl = resolveBaseUrl(env, projectRoot);
2614
2656
  const serviceKey = env.SERVICE_KEY || env.REBASE_SERVICE_KEY;
2615
2657
  if (!serviceKey) {
2616
2658
  console.error(chalk.red("✗ SERVICE_KEY not found in .env — required for admin operations."));
@@ -2715,8 +2757,9 @@ async function createKey(rawArgs) {
2715
2757
  expires_at = parsed.toISOString();
2716
2758
  }
2717
2759
  }
2718
- const env = loadEnv(requireProjectRoot());
2719
- const baseUrl = resolveBaseUrl(env);
2760
+ const projectRoot = requireProjectRoot();
2761
+ const env = loadEnv(projectRoot);
2762
+ const baseUrl = resolveBaseUrl(env, projectRoot);
2720
2763
  const serviceKey = env.SERVICE_KEY || env.REBASE_SERVICE_KEY;
2721
2764
  if (!serviceKey) {
2722
2765
  console.error(chalk.red("✗ SERVICE_KEY not found in .env — required for admin operations."));
@@ -2773,8 +2816,9 @@ async function revokeKey(rawArgs) {
2773
2816
  console.log(chalk.gray(" Usage: rebase api-keys revoke <key-id>"));
2774
2817
  process.exit(1);
2775
2818
  }
2776
- const env = loadEnv(requireProjectRoot());
2777
- const baseUrl = resolveBaseUrl(env);
2819
+ const projectRoot = requireProjectRoot();
2820
+ const env = loadEnv(projectRoot);
2821
+ const baseUrl = resolveBaseUrl(env, projectRoot);
2778
2822
  const serviceKey = env.SERVICE_KEY || env.REBASE_SERVICE_KEY;
2779
2823
  if (!serviceKey) {
2780
2824
  console.error(chalk.red("✗ SERVICE_KEY not found in .env — required for admin operations."));
@@ -3243,13 +3287,18 @@ function fmtDate(value) {
3243
3287
  */
3244
3288
  var POLL_INTERVAL_MS = 1500;
3245
3289
  var POLL_TIMEOUT_MS = 900 * 1e3;
3290
+ var MAX_SOURCE_UPLOAD_BYTES = 100 * 1024 * 1024;
3246
3291
  function sleep(ms) {
3247
3292
  return new Promise((r) => setTimeout(r, ms));
3248
3293
  }
3249
- function run(cmd, cmdArgs, cwd) {
3294
+ function run(cmd, cmdArgs, cwd, env) {
3250
3295
  return new Promise((resolve, reject) => {
3251
3296
  const child = spawn(cmd, cmdArgs, {
3252
3297
  cwd,
3298
+ env: env ? {
3299
+ ...process.env,
3300
+ ...env
3301
+ } : void 0,
3253
3302
  stdio: [
3254
3303
  "ignore",
3255
3304
  "ignore",
@@ -3279,7 +3328,7 @@ async function createSourceTarball(sourceDir) {
3279
3328
  for (const ignore of [".gitignore", ".rebaseignore"]) if (fs.existsSync(path.join(dir, ignore))) tarArgs.push(`--exclude-from=${ignore}`);
3280
3329
  tarArgs.push(".");
3281
3330
  try {
3282
- await run("tar", tarArgs, dir);
3331
+ await run("tar", tarArgs, dir, { COPYFILE_DISABLE: "1" });
3283
3332
  } catch (e) {
3284
3333
  fail(`Failed to package source: ${e instanceof Error ? e.message : String(e)}`);
3285
3334
  }
@@ -3289,6 +3338,7 @@ async function createSourceTarball(sourceDir) {
3289
3338
  async function uploadSource(url, token, projectId, tarPath) {
3290
3339
  const bytes = fs.readFileSync(tarPath);
3291
3340
  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.");
3292
3342
  console.log(chalk.gray(` Uploading source (${sizeMb} MB)...`));
3293
3343
  const res = await fetch(`${url}/api/functions/deploy/upload?projectId=${encodeURIComponent(projectId)}`, {
3294
3344
  method: "POST",
@@ -4268,6 +4318,8 @@ ${chalk.green.bold("Options")}
4268
4318
  ${chalk.blue("--secret")} Mark a variable write-only ${chalk.gray("(set)")}
4269
4319
  ${chalk.blue("--json")} Machine-readable output
4270
4320
  ${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.")}
4271
4323
  `);
4272
4324
  }
4273
4325
  function printEnvHelpJson() {
@@ -5628,9 +5680,10 @@ async function entry(args) {
5628
5680
  await cloudCommand(effectiveSubcommand, args);
5629
5681
  break;
5630
5682
  default:
5631
- console.log(chalk.red(`Unknown command: ${command}`));
5683
+ console.error(chalk.red(`Unknown command: ${command}`));
5632
5684
  console.log("");
5633
5685
  printHelp();
5686
+ process.exit(1);
5634
5687
  }
5635
5688
  }
5636
5689
  function printHelp() {