replicas-cli 0.2.35 → 0.2.39

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 (2) hide show
  1. package/dist/index.js +291 -29
  2. package/package.json +2 -1
package/dist/index.js CHANGED
@@ -7326,9 +7326,9 @@ __export(index_exports, {
7326
7326
  CLI_VERSION: () => CLI_VERSION
7327
7327
  });
7328
7328
  module.exports = __toCommonJS(index_exports);
7329
- var import_config15 = require("dotenv/config");
7329
+ var import_config17 = require("dotenv/config");
7330
7330
  var import_commander = require("commander");
7331
- var import_chalk16 = __toESM(require("chalk"));
7331
+ var import_chalk17 = __toESM(require("chalk"));
7332
7332
 
7333
7333
  // src/commands/login.ts
7334
7334
  var import_http = __toESM(require("http"));
@@ -7404,6 +7404,33 @@ function getIdeCommand() {
7404
7404
  const config2 = readConfig();
7405
7405
  return config2?.ide_command || "code";
7406
7406
  }
7407
+ function isAgentMode() {
7408
+ if (!import_fs.default.existsSync(CONFIG_FILE)) {
7409
+ return false;
7410
+ }
7411
+ try {
7412
+ const data = import_fs.default.readFileSync(CONFIG_FILE, "utf-8");
7413
+ const parsed = JSON.parse(data);
7414
+ return !!parsed.engine_secret && !!parsed.workspace_id;
7415
+ } catch {
7416
+ return false;
7417
+ }
7418
+ }
7419
+ function readAgentConfig() {
7420
+ if (!import_fs.default.existsSync(CONFIG_FILE)) {
7421
+ return null;
7422
+ }
7423
+ try {
7424
+ const data = import_fs.default.readFileSync(CONFIG_FILE, "utf-8");
7425
+ const parsed = JSON.parse(data);
7426
+ if (parsed.engine_secret && parsed.workspace_id && parsed.organization_id) {
7427
+ return parsed;
7428
+ }
7429
+ return null;
7430
+ } catch {
7431
+ return null;
7432
+ }
7433
+ }
7407
7434
 
7408
7435
  // src/lib/supabase.ts
7409
7436
  var import_supabase_js = require("@supabase/supabase-js");
@@ -7938,6 +7965,56 @@ Error: ${error instanceof Error ? error.message : "Unknown error"}`));
7938
7965
  var import_chalk6 = __toESM(require("chalk"));
7939
7966
  var import_child_process3 = require("child_process");
7940
7967
 
7968
+ // ../shared/src/pricing.ts
7969
+ var PLANS = {
7970
+ hobby: {
7971
+ id: "hobby",
7972
+ name: "Hobby",
7973
+ monthlyPrice: 0,
7974
+ seatPriceCents: 0,
7975
+ creditsIncluded: 20,
7976
+ features: ["20 hours of usage"]
7977
+ },
7978
+ developer: {
7979
+ id: "developer",
7980
+ name: "Developer",
7981
+ monthlyPrice: 30,
7982
+ seatPriceCents: 3e3,
7983
+ creditsIncluded: 0,
7984
+ features: ["Unlimited usage", "API access ($1/hr)"]
7985
+ },
7986
+ team: {
7987
+ id: "team",
7988
+ name: "Team",
7989
+ monthlyPrice: 120,
7990
+ seatPriceCents: 12e3,
7991
+ creditsIncluded: 0,
7992
+ features: [
7993
+ "Unlimited usage",
7994
+ "API access",
7995
+ "Higher API rate limits",
7996
+ "Warm hooks and pool access",
7997
+ "Optional add-ons for higher resources, warm pools, rate limits, and SOC 2"
7998
+ ]
7999
+ },
8000
+ enterprise: {
8001
+ id: "enterprise",
8002
+ name: "Enterprise",
8003
+ monthlyPrice: 0,
8004
+ seatPriceCents: 0,
8005
+ creditsIncluded: 0,
8006
+ features: [
8007
+ "Unlimited usage",
8008
+ "Custom API rates",
8009
+ "Custom rate limits",
8010
+ "Custom warm hooks and pools",
8011
+ "SOC 2"
8012
+ ]
8013
+ }
8014
+ };
8015
+ var TEAM_PLAN = PLANS.team;
8016
+ var ENTERPRISE_PLAN = PLANS.enterprise;
8017
+
7941
8018
  // ../shared/src/sandbox.ts
7942
8019
  var SANDBOX_LIFECYCLE = {
7943
8020
  AUTO_STOP_MINUTES: 60,
@@ -7951,7 +8028,8 @@ var SANDBOX_PATHS = {
7951
8028
  REPLICAS_DIR: "/home/ubuntu/.replicas",
7952
8029
  REPLICAS_FILES_DIR: "/home/ubuntu/.replicas/files",
7953
8030
  REPLICAS_FILES_DISPLAY_DIR: "~/.replicas/files",
7954
- REPLICAS_RUNTIME_ENV_FILE: "/home/ubuntu/.replicas/runtime-env.sh"
8031
+ REPLICAS_RUNTIME_ENV_FILE: "/home/ubuntu/.replicas/runtime-env.sh",
8032
+ REPLICAS_PREVIEW_PORTS_FILE: "/home/ubuntu/.replicas/preview-ports.json"
7955
8033
  };
7956
8034
 
7957
8035
  // ../shared/src/replicas-config.ts
@@ -7980,7 +8058,7 @@ function getStatusFromExitCode(exitCode) {
7980
8058
  return exitCode === 0 ? "completed" : "failed";
7981
8059
  }
7982
8060
  function parseShellOutput(raw) {
7983
- const exitCodeMatch = raw.match(/^Exit code: (\d+)/);
8061
+ const exitCodeMatch = raw.match(/^Exit code: (\d+)/m) || raw.match(/Process exited with code (\d+)/);
7984
8062
  const exitCode = exitCodeMatch ? parseInt(exitCodeMatch[1], 10) : 0;
7985
8063
  const outputIndex = raw.indexOf("Output:\n");
7986
8064
  const output = outputIndex >= 0 ? raw.slice(outputIndex + "Output:\n".length) : raw;
@@ -8075,10 +8153,10 @@ function parseCodexEvents(events) {
8075
8153
  });
8076
8154
  }
8077
8155
  }
8078
- if (payloadType === "function_call" && (event.payload?.name === "shell" || event.payload?.name === "shell_command")) {
8156
+ if (payloadType === "function_call" && (event.payload?.name === "shell" || event.payload?.name === "shell_command" || event.payload?.name === "exec_command")) {
8079
8157
  const callId = event.payload.call_id;
8080
8158
  const args = safeJsonParse(event.payload.arguments || "{}", {});
8081
- const command = Array.isArray(args.command) ? args.command.join(" ") : args.command || "";
8159
+ const command = args.cmd || (Array.isArray(args.command) ? args.command.join(" ") : args.command) || "";
8082
8160
  const msg = {
8083
8161
  id: `command-${callId || "no-call-id"}-${eventIndex}`,
8084
8162
  type: "command",
@@ -8202,6 +8280,9 @@ function parseClaudeEvents(events, parentToolUseId) {
8202
8280
  if (toolResult && toolResult.tool_use_id) {
8203
8281
  return;
8204
8282
  }
8283
+ if (event.payload.isSynthetic) {
8284
+ return;
8285
+ }
8205
8286
  const textContent = content.filter((c) => c.type === "text").map((c) => c.text || "").join("\n");
8206
8287
  const images = content.filter((c) => c.type === "image" && c.source).map((c) => {
8207
8288
  const source = c.source;
@@ -8250,7 +8331,7 @@ function parseClaudeEvents(events, parentToolUseId) {
8250
8331
  toolName,
8251
8332
  input: toolInput
8252
8333
  });
8253
- if (toolName === "Task") {
8334
+ if (toolName === "Task" || toolName === "Agent") {
8254
8335
  const inputObj = typeof toolInput === "string" ? safeJsonParse2(toolInput, {}) : toolInput;
8255
8336
  const nestedEvents = events.filter((e) => e.payload.parent_tool_use_id === toolUseId).map((e) => ({
8256
8337
  timestamp: e.timestamp,
@@ -8320,6 +8401,16 @@ function parseClaudeEvents(events, parentToolUseId) {
8320
8401
  status: "in_progress",
8321
8402
  timestamp: event.timestamp
8322
8403
  });
8404
+ } else if (toolName === "Skill") {
8405
+ const inputObj = typeof toolInput === "string" ? safeJsonParse2(toolInput, {}) : toolInput;
8406
+ messages.push({
8407
+ id: `skill-${event.timestamp}-${messages.length}`,
8408
+ type: "skill",
8409
+ skillName: inputObj.skill || "unknown",
8410
+ args: inputObj.args,
8411
+ status: "in_progress",
8412
+ timestamp: event.timestamp
8413
+ });
8323
8414
  } else {
8324
8415
  messages.push({
8325
8416
  id: `toolcall-${event.timestamp}-${messages.length}`,
@@ -8376,6 +8467,8 @@ function parseClaudeEvents(events, parentToolUseId) {
8376
8467
  } else if (message.type === "tool_call") {
8377
8468
  message.output = resultContent;
8378
8469
  message.status = status;
8470
+ } else if (message.type === "skill") {
8471
+ message.status = status;
8379
8472
  } else if (message.type === "subagent") {
8380
8473
  message.output = resultContent;
8381
8474
  message.status = status;
@@ -9631,8 +9724,115 @@ Repositories (${response.repositories.length}):
9631
9724
  }
9632
9725
  }
9633
9726
 
9727
+ // src/commands/preview.ts
9728
+ var import_chalk16 = __toESM(require("chalk"));
9729
+
9730
+ // src/lib/agent-api.ts
9731
+ var MONOLITH_URL3 = process.env.MONOLITH_URL || process.env.REPLICAS_MONOLITH_URL || "https://api.replicas.dev";
9732
+ var ENGINE_PORT = process.env.REPLICAS_ENGINE_PORT || "3737";
9733
+ async function agentFetch(path5, options) {
9734
+ const config2 = readAgentConfig();
9735
+ if (!config2) {
9736
+ throw new Error("Agent mode config not found");
9737
+ }
9738
+ const headers = {
9739
+ "Authorization": `Bearer ${config2.engine_secret}`,
9740
+ "X-Workspace-Id": config2.workspace_id,
9741
+ "Content-Type": "application/json",
9742
+ ...options?.headers || {}
9743
+ };
9744
+ const response = await fetch(`${MONOLITH_URL3}${path5}`, {
9745
+ ...options,
9746
+ headers,
9747
+ body: options?.body !== void 0 ? JSON.stringify(options.body) : void 0
9748
+ });
9749
+ if (!response.ok) {
9750
+ const error = await response.json().catch(() => ({ error: "Request failed" }));
9751
+ throw new Error(error.error || `Request failed with status ${response.status}`);
9752
+ }
9753
+ return response.json();
9754
+ }
9755
+ async function engineFetch(path5, options) {
9756
+ const config2 = readAgentConfig();
9757
+ if (!config2) {
9758
+ throw new Error("Agent mode config not found");
9759
+ }
9760
+ const headers = {
9761
+ "X-Replicas-Engine-Secret": config2.engine_secret,
9762
+ "Content-Type": "application/json",
9763
+ ...options?.headers || {}
9764
+ };
9765
+ const response = await fetch(`http://localhost:${ENGINE_PORT}${path5}`, {
9766
+ ...options,
9767
+ headers,
9768
+ body: options?.body !== void 0 ? JSON.stringify(options.body) : void 0
9769
+ });
9770
+ if (!response.ok) {
9771
+ const error = await response.json().catch(() => ({ error: "Request failed" }));
9772
+ throw new Error(error.error || `Request failed with status ${response.status}`);
9773
+ }
9774
+ return response.json();
9775
+ }
9776
+
9777
+ // src/commands/preview.ts
9778
+ async function previewCreateCommand(port, options) {
9779
+ const portNum = parseInt(port, 10);
9780
+ if (isNaN(portNum) || portNum < 1 || portNum > 65535) {
9781
+ throw new Error("Port must be a number between 1 and 65535");
9782
+ }
9783
+ if (isAgentMode()) {
9784
+ const result = await agentFetch("/v1/previews", {
9785
+ method: "POST",
9786
+ body: { port: portNum, authenticated: options.authenticated ?? false }
9787
+ });
9788
+ console.log(result.preview.publicUrl);
9789
+ } else {
9790
+ throw new Error("In human mode, use: replicas preview add <workspaceId> --port <port>");
9791
+ }
9792
+ }
9793
+ async function previewListCommand(workspaceId) {
9794
+ if (isAgentMode()) {
9795
+ const result = await engineFetch("/previews");
9796
+ if (result.previews.length === 0) {
9797
+ console.log("No active previews");
9798
+ return;
9799
+ }
9800
+ for (const preview2 of result.previews) {
9801
+ console.log(`${preview2.port} -> ${preview2.publicUrl}`);
9802
+ }
9803
+ } else {
9804
+ if (!workspaceId) {
9805
+ throw new Error("Workspace ID is required: replicas preview list <workspaceId>");
9806
+ }
9807
+ const result = await orgAuthenticatedFetch(
9808
+ `/v1/workspaces/${workspaceId}/previews`
9809
+ );
9810
+ if (result.previews.length === 0) {
9811
+ console.log(import_chalk16.default.dim("No active previews"));
9812
+ return;
9813
+ }
9814
+ for (const preview2 of result.previews) {
9815
+ console.log(` ${import_chalk16.default.cyan(String(preview2.port))} \u2192 ${import_chalk16.default.underline(preview2.publicUrl)}`);
9816
+ }
9817
+ }
9818
+ }
9819
+ async function previewAddCommand(workspaceId, options) {
9820
+ const portNum = parseInt(options.port, 10);
9821
+ if (isNaN(portNum) || portNum < 1 || portNum > 65535) {
9822
+ throw new Error("Port must be a number between 1 and 65535");
9823
+ }
9824
+ const result = await orgAuthenticatedFetch(
9825
+ `/v1/workspaces/${workspaceId}/previews`,
9826
+ {
9827
+ method: "POST",
9828
+ body: { port: portNum, authenticated: options.authenticated ?? false }
9829
+ }
9830
+ );
9831
+ console.log(import_chalk16.default.green(`Preview created: ${result.preview.publicUrl}`));
9832
+ }
9833
+
9634
9834
  // src/index.ts
9635
- var CLI_VERSION = "0.2.33";
9835
+ var CLI_VERSION = "0.2.39";
9636
9836
  var program = new import_commander.Command();
9637
9837
  program.name("replicas").description("CLI for managing Replicas workspaces").version(CLI_VERSION);
9638
9838
  program.command("login").description("Authenticate with your Replicas account").action(async () => {
@@ -9640,7 +9840,7 @@ program.command("login").description("Authenticate with your Replicas account").
9640
9840
  await loginCommand();
9641
9841
  } catch (error) {
9642
9842
  if (error instanceof Error) {
9643
- console.error(import_chalk16.default.red(`
9843
+ console.error(import_chalk17.default.red(`
9644
9844
  \u2717 ${error.message}
9645
9845
  `));
9646
9846
  }
@@ -9652,7 +9852,7 @@ program.command("init").description("Create a replicas.json or replicas.yaml con
9652
9852
  initCommand(options);
9653
9853
  } catch (error) {
9654
9854
  if (error instanceof Error) {
9655
- console.error(import_chalk16.default.red(`
9855
+ console.error(import_chalk17.default.red(`
9656
9856
  \u2717 ${error.message}
9657
9857
  `));
9658
9858
  }
@@ -9664,7 +9864,7 @@ program.command("logout").description("Clear stored credentials").action(() => {
9664
9864
  logoutCommand();
9665
9865
  } catch (error) {
9666
9866
  if (error instanceof Error) {
9667
- console.error(import_chalk16.default.red(`
9867
+ console.error(import_chalk17.default.red(`
9668
9868
  \u2717 ${error.message}
9669
9869
  `));
9670
9870
  }
@@ -9676,7 +9876,7 @@ program.command("whoami").description("Display current authenticated user").acti
9676
9876
  await whoamiCommand();
9677
9877
  } catch (error) {
9678
9878
  if (error instanceof Error) {
9679
- console.error(import_chalk16.default.red(`
9879
+ console.error(import_chalk17.default.red(`
9680
9880
  \u2717 ${error.message}
9681
9881
  `));
9682
9882
  }
@@ -9688,7 +9888,7 @@ program.command("codex-auth").description("Authenticate Replicas with your Codex
9688
9888
  await codexAuthCommand(options);
9689
9889
  } catch (error) {
9690
9890
  if (error instanceof Error) {
9691
- console.error(import_chalk16.default.red(`
9891
+ console.error(import_chalk17.default.red(`
9692
9892
  \u2717 ${error.message}
9693
9893
  `));
9694
9894
  }
@@ -9700,7 +9900,7 @@ program.command("claude-auth").description("Authenticate Replicas with your Clau
9700
9900
  await claudeAuthCommand(options);
9701
9901
  } catch (error) {
9702
9902
  if (error instanceof Error) {
9703
- console.error(import_chalk16.default.red(`
9903
+ console.error(import_chalk17.default.red(`
9704
9904
  \u2717 ${error.message}
9705
9905
  `));
9706
9906
  }
@@ -9713,7 +9913,7 @@ org.command("switch").description("Switch to a different organization").action(a
9713
9913
  await orgSwitchCommand();
9714
9914
  } catch (error) {
9715
9915
  if (error instanceof Error) {
9716
- console.error(import_chalk16.default.red(`
9916
+ console.error(import_chalk17.default.red(`
9717
9917
  \u2717 ${error.message}
9718
9918
  `));
9719
9919
  }
@@ -9725,7 +9925,7 @@ org.action(async () => {
9725
9925
  await orgCommand();
9726
9926
  } catch (error) {
9727
9927
  if (error instanceof Error) {
9728
- console.error(import_chalk16.default.red(`
9928
+ console.error(import_chalk17.default.red(`
9729
9929
  \u2717 ${error.message}
9730
9930
  `));
9731
9931
  }
@@ -9737,7 +9937,7 @@ program.command("connect <workspace-name>").description("Connect to a workspace
9737
9937
  await connectCommand(workspaceName);
9738
9938
  } catch (error) {
9739
9939
  if (error instanceof Error) {
9740
- console.error(import_chalk16.default.red(`
9940
+ console.error(import_chalk17.default.red(`
9741
9941
  \u2717 ${error.message}
9742
9942
  `));
9743
9943
  }
@@ -9749,7 +9949,7 @@ program.command("code <workspace-name>").description("Open a workspace in VSCode
9749
9949
  await codeCommand(workspaceName);
9750
9950
  } catch (error) {
9751
9951
  if (error instanceof Error) {
9752
- console.error(import_chalk16.default.red(`
9952
+ console.error(import_chalk17.default.red(`
9753
9953
  \u2717 ${error.message}
9754
9954
  `));
9755
9955
  }
@@ -9762,7 +9962,7 @@ config.command("get <key>").description("Get a configuration value").action(asyn
9762
9962
  await configGetCommand(key);
9763
9963
  } catch (error) {
9764
9964
  if (error instanceof Error) {
9765
- console.error(import_chalk16.default.red(`
9965
+ console.error(import_chalk17.default.red(`
9766
9966
  \u2717 ${error.message}
9767
9967
  `));
9768
9968
  }
@@ -9774,7 +9974,7 @@ config.command("set <key> <value>").description("Set a configuration value").act
9774
9974
  await configSetCommand(key, value);
9775
9975
  } catch (error) {
9776
9976
  if (error instanceof Error) {
9777
- console.error(import_chalk16.default.red(`
9977
+ console.error(import_chalk17.default.red(`
9778
9978
  \u2717 ${error.message}
9779
9979
  `));
9780
9980
  }
@@ -9786,7 +9986,7 @@ config.command("list").description("List all configuration values").action(async
9786
9986
  await configListCommand();
9787
9987
  } catch (error) {
9788
9988
  if (error instanceof Error) {
9789
- console.error(import_chalk16.default.red(`
9989
+ console.error(import_chalk17.default.red(`
9790
9990
  \u2717 ${error.message}
9791
9991
  `));
9792
9992
  }
@@ -9798,7 +9998,7 @@ program.command("list").description("List all replicas").option("-p, --page <pag
9798
9998
  await replicaListCommand(options);
9799
9999
  } catch (error) {
9800
10000
  if (error instanceof Error) {
9801
- console.error(import_chalk16.default.red(`
10001
+ console.error(import_chalk17.default.red(`
9802
10002
  \u2717 ${error.message}
9803
10003
  `));
9804
10004
  }
@@ -9810,7 +10010,7 @@ program.command("get <id>").description("Get replica details by ID").action(asyn
9810
10010
  await replicaGetCommand(id);
9811
10011
  } catch (error) {
9812
10012
  if (error instanceof Error) {
9813
- console.error(import_chalk16.default.red(`
10013
+ console.error(import_chalk17.default.red(`
9814
10014
  \u2717 ${error.message}
9815
10015
  `));
9816
10016
  }
@@ -9822,7 +10022,7 @@ program.command("create [name]").description("Create a new replica").option("-m,
9822
10022
  await replicaCreateCommand(name, options);
9823
10023
  } catch (error) {
9824
10024
  if (error instanceof Error) {
9825
- console.error(import_chalk16.default.red(`
10025
+ console.error(import_chalk17.default.red(`
9826
10026
  \u2717 ${error.message}
9827
10027
  `));
9828
10028
  }
@@ -9834,7 +10034,7 @@ program.command("send <id>").description("Send a message to a replica").option("
9834
10034
  await replicaSendCommand(id, options);
9835
10035
  } catch (error) {
9836
10036
  if (error instanceof Error) {
9837
- console.error(import_chalk16.default.red(`
10037
+ console.error(import_chalk17.default.red(`
9838
10038
  \u2717 ${error.message}
9839
10039
  `));
9840
10040
  }
@@ -9846,7 +10046,7 @@ program.command("delete <id>").description("Delete a replica").option("-f, --for
9846
10046
  await replicaDeleteCommand(id, options);
9847
10047
  } catch (error) {
9848
10048
  if (error instanceof Error) {
9849
- console.error(import_chalk16.default.red(`
10049
+ console.error(import_chalk17.default.red(`
9850
10050
  \u2717 ${error.message}
9851
10051
  `));
9852
10052
  }
@@ -9858,7 +10058,7 @@ program.command("read <id>").description("Read conversation history of a replica
9858
10058
  await replicaReadCommand(id, options);
9859
10059
  } catch (error) {
9860
10060
  if (error instanceof Error) {
9861
- console.error(import_chalk16.default.red(`
10061
+ console.error(import_chalk17.default.red(`
9862
10062
  \u2717 ${error.message}
9863
10063
  `));
9864
10064
  }
@@ -9871,7 +10071,7 @@ repos.command("list").description("List all repositories").action(async () => {
9871
10071
  await repositoriesListCommand();
9872
10072
  } catch (error) {
9873
10073
  if (error instanceof Error) {
9874
- console.error(import_chalk16.default.red(`
10074
+ console.error(import_chalk17.default.red(`
9875
10075
  \u2717 ${error.message}
9876
10076
  `));
9877
10077
  }
@@ -9883,13 +10083,75 @@ repos.action(async () => {
9883
10083
  await repositoriesListCommand();
9884
10084
  } catch (error) {
9885
10085
  if (error instanceof Error) {
9886
- console.error(import_chalk16.default.red(`
10086
+ console.error(import_chalk17.default.red(`
9887
10087
  \u2717 ${error.message}
9888
10088
  `));
9889
10089
  }
9890
10090
  process.exit(1);
9891
10091
  }
9892
10092
  });
10093
+ var preview = program.command("preview").description("Manage preview URLs");
10094
+ if (isAgentMode()) {
10095
+ preview.command("create <port>").description("Register a preview port").option(
10096
+ "-a, --authenticated",
10097
+ "Require cookie authentication for this preview. Use for user-facing frontends (e.g. web apps) where you want only logged-in Replicas users to access the preview. Do not use for backend APIs that are called by frontend code, as the frontend cannot forward the auth cookie."
10098
+ ).action(async (port, options) => {
10099
+ try {
10100
+ await previewCreateCommand(port, options);
10101
+ } catch (error) {
10102
+ if (error instanceof Error) {
10103
+ console.error(`Error: ${error.message}`);
10104
+ }
10105
+ process.exit(1);
10106
+ }
10107
+ });
10108
+ preview.command("list").description("List active preview URLs").action(async () => {
10109
+ try {
10110
+ await previewListCommand();
10111
+ } catch (error) {
10112
+ if (error instanceof Error) {
10113
+ console.error(`Error: ${error.message}`);
10114
+ }
10115
+ process.exit(1);
10116
+ }
10117
+ });
10118
+ } else {
10119
+ preview.command("add <workspaceId>").description("Register a preview port for a workspace").requiredOption("-p, --port <port>", "Port number to preview").option(
10120
+ "-a, --authenticated",
10121
+ "Require cookie authentication for this preview. Use for user-facing frontends (e.g. web apps) where you want only logged-in Replicas users to access the preview. Do not use for backend APIs that are called by frontend code, as the frontend cannot forward the auth cookie."
10122
+ ).action(async (workspaceId, options) => {
10123
+ try {
10124
+ await previewAddCommand(workspaceId, options);
10125
+ } catch (error) {
10126
+ if (error instanceof Error) {
10127
+ console.error(import_chalk17.default.red(`
10128
+ \u2717 ${error.message}
10129
+ `));
10130
+ }
10131
+ process.exit(1);
10132
+ }
10133
+ });
10134
+ preview.command("list [workspaceId]").description("List active preview URLs for a workspace").action(async (workspaceId) => {
10135
+ try {
10136
+ await previewListCommand(workspaceId);
10137
+ } catch (error) {
10138
+ if (error instanceof Error) {
10139
+ console.error(import_chalk17.default.red(`
10140
+ \u2717 ${error.message}
10141
+ `));
10142
+ }
10143
+ process.exit(1);
10144
+ }
10145
+ });
10146
+ }
10147
+ if (isAgentMode()) {
10148
+ const previewCmd = program.commands.find((cmd) => cmd.name() === "preview");
10149
+ const cmds = program.commands;
10150
+ cmds.length = 0;
10151
+ if (previewCmd) {
10152
+ cmds.push(previewCmd);
10153
+ }
10154
+ }
9893
10155
  var versionCheckPromise = checkForUpdates(CLI_VERSION);
9894
10156
  program.parse();
9895
10157
  versionCheckPromise.catch(() => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "replicas-cli",
3
- "version": "0.2.35",
3
+ "version": "0.2.39",
4
4
  "description": "CLI for managing Replicas workspaces - SSH into cloud dev environments with automatic port forwarding",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -12,6 +12,7 @@
12
12
  "scripts": {
13
13
  "build": "tsup",
14
14
  "dev": "tsx src/index.ts",
15
+ "dev-pack": "yarn build && node scripts/pack-dev-tarball.mjs",
15
16
  "start": "node dist/index.js",
16
17
  "prepublishOnly": "yarn build"
17
18
  },