replicas-cli 0.2.35 → 0.2.37

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 +234 -28
  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");
@@ -7951,7 +7978,8 @@ var SANDBOX_PATHS = {
7951
7978
  REPLICAS_DIR: "/home/ubuntu/.replicas",
7952
7979
  REPLICAS_FILES_DIR: "/home/ubuntu/.replicas/files",
7953
7980
  REPLICAS_FILES_DISPLAY_DIR: "~/.replicas/files",
7954
- REPLICAS_RUNTIME_ENV_FILE: "/home/ubuntu/.replicas/runtime-env.sh"
7981
+ REPLICAS_RUNTIME_ENV_FILE: "/home/ubuntu/.replicas/runtime-env.sh",
7982
+ REPLICAS_PREVIEW_PORTS_FILE: "/home/ubuntu/.replicas/preview-ports.json"
7955
7983
  };
7956
7984
 
7957
7985
  // ../shared/src/replicas-config.ts
@@ -7980,7 +8008,7 @@ function getStatusFromExitCode(exitCode) {
7980
8008
  return exitCode === 0 ? "completed" : "failed";
7981
8009
  }
7982
8010
  function parseShellOutput(raw) {
7983
- const exitCodeMatch = raw.match(/^Exit code: (\d+)/);
8011
+ const exitCodeMatch = raw.match(/^Exit code: (\d+)/m) || raw.match(/Process exited with code (\d+)/);
7984
8012
  const exitCode = exitCodeMatch ? parseInt(exitCodeMatch[1], 10) : 0;
7985
8013
  const outputIndex = raw.indexOf("Output:\n");
7986
8014
  const output = outputIndex >= 0 ? raw.slice(outputIndex + "Output:\n".length) : raw;
@@ -8075,10 +8103,10 @@ function parseCodexEvents(events) {
8075
8103
  });
8076
8104
  }
8077
8105
  }
8078
- if (payloadType === "function_call" && (event.payload?.name === "shell" || event.payload?.name === "shell_command")) {
8106
+ if (payloadType === "function_call" && (event.payload?.name === "shell" || event.payload?.name === "shell_command" || event.payload?.name === "exec_command")) {
8079
8107
  const callId = event.payload.call_id;
8080
8108
  const args = safeJsonParse(event.payload.arguments || "{}", {});
8081
- const command = Array.isArray(args.command) ? args.command.join(" ") : args.command || "";
8109
+ const command = args.cmd || (Array.isArray(args.command) ? args.command.join(" ") : args.command) || "";
8082
8110
  const msg = {
8083
8111
  id: `command-${callId || "no-call-id"}-${eventIndex}`,
8084
8112
  type: "command",
@@ -8202,6 +8230,9 @@ function parseClaudeEvents(events, parentToolUseId) {
8202
8230
  if (toolResult && toolResult.tool_use_id) {
8203
8231
  return;
8204
8232
  }
8233
+ if (event.payload.isSynthetic) {
8234
+ return;
8235
+ }
8205
8236
  const textContent = content.filter((c) => c.type === "text").map((c) => c.text || "").join("\n");
8206
8237
  const images = content.filter((c) => c.type === "image" && c.source).map((c) => {
8207
8238
  const source = c.source;
@@ -8320,6 +8351,16 @@ function parseClaudeEvents(events, parentToolUseId) {
8320
8351
  status: "in_progress",
8321
8352
  timestamp: event.timestamp
8322
8353
  });
8354
+ } else if (toolName === "Skill") {
8355
+ const inputObj = typeof toolInput === "string" ? safeJsonParse2(toolInput, {}) : toolInput;
8356
+ messages.push({
8357
+ id: `skill-${event.timestamp}-${messages.length}`,
8358
+ type: "skill",
8359
+ skillName: inputObj.skill || "unknown",
8360
+ args: inputObj.args,
8361
+ status: "in_progress",
8362
+ timestamp: event.timestamp
8363
+ });
8323
8364
  } else {
8324
8365
  messages.push({
8325
8366
  id: `toolcall-${event.timestamp}-${messages.length}`,
@@ -8376,6 +8417,8 @@ function parseClaudeEvents(events, parentToolUseId) {
8376
8417
  } else if (message.type === "tool_call") {
8377
8418
  message.output = resultContent;
8378
8419
  message.status = status;
8420
+ } else if (message.type === "skill") {
8421
+ message.status = status;
8379
8422
  } else if (message.type === "subagent") {
8380
8423
  message.output = resultContent;
8381
8424
  message.status = status;
@@ -9631,8 +9674,115 @@ Repositories (${response.repositories.length}):
9631
9674
  }
9632
9675
  }
9633
9676
 
9677
+ // src/commands/preview.ts
9678
+ var import_chalk16 = __toESM(require("chalk"));
9679
+
9680
+ // src/lib/agent-api.ts
9681
+ var MONOLITH_URL3 = process.env.MONOLITH_URL || process.env.REPLICAS_MONOLITH_URL || "https://api.replicas.dev";
9682
+ var ENGINE_PORT = process.env.REPLICAS_ENGINE_PORT || "3737";
9683
+ async function agentFetch(path5, options) {
9684
+ const config2 = readAgentConfig();
9685
+ if (!config2) {
9686
+ throw new Error("Agent mode config not found");
9687
+ }
9688
+ const headers = {
9689
+ "Authorization": `Bearer ${config2.engine_secret}`,
9690
+ "X-Workspace-Id": config2.workspace_id,
9691
+ "Content-Type": "application/json",
9692
+ ...options?.headers || {}
9693
+ };
9694
+ const response = await fetch(`${MONOLITH_URL3}${path5}`, {
9695
+ ...options,
9696
+ headers,
9697
+ body: options?.body !== void 0 ? JSON.stringify(options.body) : void 0
9698
+ });
9699
+ if (!response.ok) {
9700
+ const error = await response.json().catch(() => ({ error: "Request failed" }));
9701
+ throw new Error(error.error || `Request failed with status ${response.status}`);
9702
+ }
9703
+ return response.json();
9704
+ }
9705
+ async function engineFetch(path5, options) {
9706
+ const config2 = readAgentConfig();
9707
+ if (!config2) {
9708
+ throw new Error("Agent mode config not found");
9709
+ }
9710
+ const headers = {
9711
+ "X-Replicas-Engine-Secret": config2.engine_secret,
9712
+ "Content-Type": "application/json",
9713
+ ...options?.headers || {}
9714
+ };
9715
+ const response = await fetch(`http://localhost:${ENGINE_PORT}${path5}`, {
9716
+ ...options,
9717
+ headers,
9718
+ body: options?.body !== void 0 ? JSON.stringify(options.body) : void 0
9719
+ });
9720
+ if (!response.ok) {
9721
+ const error = await response.json().catch(() => ({ error: "Request failed" }));
9722
+ throw new Error(error.error || `Request failed with status ${response.status}`);
9723
+ }
9724
+ return response.json();
9725
+ }
9726
+
9727
+ // src/commands/preview.ts
9728
+ async function previewCreateCommand(port) {
9729
+ const portNum = parseInt(port, 10);
9730
+ if (isNaN(portNum) || portNum < 1 || portNum > 65535) {
9731
+ throw new Error("Port must be a number between 1 and 65535");
9732
+ }
9733
+ if (isAgentMode()) {
9734
+ const result = await agentFetch("/v1/previews", {
9735
+ method: "POST",
9736
+ body: { port: portNum }
9737
+ });
9738
+ console.log(result.preview.publicUrl);
9739
+ } else {
9740
+ throw new Error("In human mode, use: replicas preview add <workspaceId> --port <port>");
9741
+ }
9742
+ }
9743
+ async function previewListCommand(workspaceId) {
9744
+ if (isAgentMode()) {
9745
+ const result = await engineFetch("/previews");
9746
+ if (result.previews.length === 0) {
9747
+ console.log("No active previews");
9748
+ return;
9749
+ }
9750
+ for (const preview2 of result.previews) {
9751
+ console.log(`${preview2.port} -> ${preview2.publicUrl}`);
9752
+ }
9753
+ } else {
9754
+ if (!workspaceId) {
9755
+ throw new Error("Workspace ID is required: replicas preview list <workspaceId>");
9756
+ }
9757
+ const result = await orgAuthenticatedFetch(
9758
+ `/v1/workspaces/${workspaceId}/previews`
9759
+ );
9760
+ if (result.previews.length === 0) {
9761
+ console.log(import_chalk16.default.dim("No active previews"));
9762
+ return;
9763
+ }
9764
+ for (const preview2 of result.previews) {
9765
+ console.log(` ${import_chalk16.default.cyan(String(preview2.port))} \u2192 ${import_chalk16.default.underline(preview2.publicUrl)}`);
9766
+ }
9767
+ }
9768
+ }
9769
+ async function previewAddCommand(workspaceId, options) {
9770
+ const portNum = parseInt(options.port, 10);
9771
+ if (isNaN(portNum) || portNum < 1 || portNum > 65535) {
9772
+ throw new Error("Port must be a number between 1 and 65535");
9773
+ }
9774
+ const result = await orgAuthenticatedFetch(
9775
+ `/v1/workspaces/${workspaceId}/previews`,
9776
+ {
9777
+ method: "POST",
9778
+ body: { port: portNum }
9779
+ }
9780
+ );
9781
+ console.log(import_chalk16.default.green(`Preview created: ${result.preview.publicUrl}`));
9782
+ }
9783
+
9634
9784
  // src/index.ts
9635
- var CLI_VERSION = "0.2.33";
9785
+ var CLI_VERSION = "0.2.37";
9636
9786
  var program = new import_commander.Command();
9637
9787
  program.name("replicas").description("CLI for managing Replicas workspaces").version(CLI_VERSION);
9638
9788
  program.command("login").description("Authenticate with your Replicas account").action(async () => {
@@ -9640,7 +9790,7 @@ program.command("login").description("Authenticate with your Replicas account").
9640
9790
  await loginCommand();
9641
9791
  } catch (error) {
9642
9792
  if (error instanceof Error) {
9643
- console.error(import_chalk16.default.red(`
9793
+ console.error(import_chalk17.default.red(`
9644
9794
  \u2717 ${error.message}
9645
9795
  `));
9646
9796
  }
@@ -9652,7 +9802,7 @@ program.command("init").description("Create a replicas.json or replicas.yaml con
9652
9802
  initCommand(options);
9653
9803
  } catch (error) {
9654
9804
  if (error instanceof Error) {
9655
- console.error(import_chalk16.default.red(`
9805
+ console.error(import_chalk17.default.red(`
9656
9806
  \u2717 ${error.message}
9657
9807
  `));
9658
9808
  }
@@ -9664,7 +9814,7 @@ program.command("logout").description("Clear stored credentials").action(() => {
9664
9814
  logoutCommand();
9665
9815
  } catch (error) {
9666
9816
  if (error instanceof Error) {
9667
- console.error(import_chalk16.default.red(`
9817
+ console.error(import_chalk17.default.red(`
9668
9818
  \u2717 ${error.message}
9669
9819
  `));
9670
9820
  }
@@ -9676,7 +9826,7 @@ program.command("whoami").description("Display current authenticated user").acti
9676
9826
  await whoamiCommand();
9677
9827
  } catch (error) {
9678
9828
  if (error instanceof Error) {
9679
- console.error(import_chalk16.default.red(`
9829
+ console.error(import_chalk17.default.red(`
9680
9830
  \u2717 ${error.message}
9681
9831
  `));
9682
9832
  }
@@ -9688,7 +9838,7 @@ program.command("codex-auth").description("Authenticate Replicas with your Codex
9688
9838
  await codexAuthCommand(options);
9689
9839
  } catch (error) {
9690
9840
  if (error instanceof Error) {
9691
- console.error(import_chalk16.default.red(`
9841
+ console.error(import_chalk17.default.red(`
9692
9842
  \u2717 ${error.message}
9693
9843
  `));
9694
9844
  }
@@ -9700,7 +9850,7 @@ program.command("claude-auth").description("Authenticate Replicas with your Clau
9700
9850
  await claudeAuthCommand(options);
9701
9851
  } catch (error) {
9702
9852
  if (error instanceof Error) {
9703
- console.error(import_chalk16.default.red(`
9853
+ console.error(import_chalk17.default.red(`
9704
9854
  \u2717 ${error.message}
9705
9855
  `));
9706
9856
  }
@@ -9713,7 +9863,7 @@ org.command("switch").description("Switch to a different organization").action(a
9713
9863
  await orgSwitchCommand();
9714
9864
  } catch (error) {
9715
9865
  if (error instanceof Error) {
9716
- console.error(import_chalk16.default.red(`
9866
+ console.error(import_chalk17.default.red(`
9717
9867
  \u2717 ${error.message}
9718
9868
  `));
9719
9869
  }
@@ -9725,7 +9875,7 @@ org.action(async () => {
9725
9875
  await orgCommand();
9726
9876
  } catch (error) {
9727
9877
  if (error instanceof Error) {
9728
- console.error(import_chalk16.default.red(`
9878
+ console.error(import_chalk17.default.red(`
9729
9879
  \u2717 ${error.message}
9730
9880
  `));
9731
9881
  }
@@ -9737,7 +9887,7 @@ program.command("connect <workspace-name>").description("Connect to a workspace
9737
9887
  await connectCommand(workspaceName);
9738
9888
  } catch (error) {
9739
9889
  if (error instanceof Error) {
9740
- console.error(import_chalk16.default.red(`
9890
+ console.error(import_chalk17.default.red(`
9741
9891
  \u2717 ${error.message}
9742
9892
  `));
9743
9893
  }
@@ -9749,7 +9899,7 @@ program.command("code <workspace-name>").description("Open a workspace in VSCode
9749
9899
  await codeCommand(workspaceName);
9750
9900
  } catch (error) {
9751
9901
  if (error instanceof Error) {
9752
- console.error(import_chalk16.default.red(`
9902
+ console.error(import_chalk17.default.red(`
9753
9903
  \u2717 ${error.message}
9754
9904
  `));
9755
9905
  }
@@ -9762,7 +9912,7 @@ config.command("get <key>").description("Get a configuration value").action(asyn
9762
9912
  await configGetCommand(key);
9763
9913
  } catch (error) {
9764
9914
  if (error instanceof Error) {
9765
- console.error(import_chalk16.default.red(`
9915
+ console.error(import_chalk17.default.red(`
9766
9916
  \u2717 ${error.message}
9767
9917
  `));
9768
9918
  }
@@ -9774,7 +9924,7 @@ config.command("set <key> <value>").description("Set a configuration value").act
9774
9924
  await configSetCommand(key, value);
9775
9925
  } catch (error) {
9776
9926
  if (error instanceof Error) {
9777
- console.error(import_chalk16.default.red(`
9927
+ console.error(import_chalk17.default.red(`
9778
9928
  \u2717 ${error.message}
9779
9929
  `));
9780
9930
  }
@@ -9786,7 +9936,7 @@ config.command("list").description("List all configuration values").action(async
9786
9936
  await configListCommand();
9787
9937
  } catch (error) {
9788
9938
  if (error instanceof Error) {
9789
- console.error(import_chalk16.default.red(`
9939
+ console.error(import_chalk17.default.red(`
9790
9940
  \u2717 ${error.message}
9791
9941
  `));
9792
9942
  }
@@ -9798,7 +9948,7 @@ program.command("list").description("List all replicas").option("-p, --page <pag
9798
9948
  await replicaListCommand(options);
9799
9949
  } catch (error) {
9800
9950
  if (error instanceof Error) {
9801
- console.error(import_chalk16.default.red(`
9951
+ console.error(import_chalk17.default.red(`
9802
9952
  \u2717 ${error.message}
9803
9953
  `));
9804
9954
  }
@@ -9810,7 +9960,7 @@ program.command("get <id>").description("Get replica details by ID").action(asyn
9810
9960
  await replicaGetCommand(id);
9811
9961
  } catch (error) {
9812
9962
  if (error instanceof Error) {
9813
- console.error(import_chalk16.default.red(`
9963
+ console.error(import_chalk17.default.red(`
9814
9964
  \u2717 ${error.message}
9815
9965
  `));
9816
9966
  }
@@ -9822,7 +9972,7 @@ program.command("create [name]").description("Create a new replica").option("-m,
9822
9972
  await replicaCreateCommand(name, options);
9823
9973
  } catch (error) {
9824
9974
  if (error instanceof Error) {
9825
- console.error(import_chalk16.default.red(`
9975
+ console.error(import_chalk17.default.red(`
9826
9976
  \u2717 ${error.message}
9827
9977
  `));
9828
9978
  }
@@ -9834,7 +9984,7 @@ program.command("send <id>").description("Send a message to a replica").option("
9834
9984
  await replicaSendCommand(id, options);
9835
9985
  } catch (error) {
9836
9986
  if (error instanceof Error) {
9837
- console.error(import_chalk16.default.red(`
9987
+ console.error(import_chalk17.default.red(`
9838
9988
  \u2717 ${error.message}
9839
9989
  `));
9840
9990
  }
@@ -9846,7 +9996,7 @@ program.command("delete <id>").description("Delete a replica").option("-f, --for
9846
9996
  await replicaDeleteCommand(id, options);
9847
9997
  } catch (error) {
9848
9998
  if (error instanceof Error) {
9849
- console.error(import_chalk16.default.red(`
9999
+ console.error(import_chalk17.default.red(`
9850
10000
  \u2717 ${error.message}
9851
10001
  `));
9852
10002
  }
@@ -9858,7 +10008,7 @@ program.command("read <id>").description("Read conversation history of a replica
9858
10008
  await replicaReadCommand(id, options);
9859
10009
  } catch (error) {
9860
10010
  if (error instanceof Error) {
9861
- console.error(import_chalk16.default.red(`
10011
+ console.error(import_chalk17.default.red(`
9862
10012
  \u2717 ${error.message}
9863
10013
  `));
9864
10014
  }
@@ -9871,7 +10021,7 @@ repos.command("list").description("List all repositories").action(async () => {
9871
10021
  await repositoriesListCommand();
9872
10022
  } catch (error) {
9873
10023
  if (error instanceof Error) {
9874
- console.error(import_chalk16.default.red(`
10024
+ console.error(import_chalk17.default.red(`
9875
10025
  \u2717 ${error.message}
9876
10026
  `));
9877
10027
  }
@@ -9883,13 +10033,69 @@ repos.action(async () => {
9883
10033
  await repositoriesListCommand();
9884
10034
  } catch (error) {
9885
10035
  if (error instanceof Error) {
9886
- console.error(import_chalk16.default.red(`
10036
+ console.error(import_chalk17.default.red(`
9887
10037
  \u2717 ${error.message}
9888
10038
  `));
9889
10039
  }
9890
10040
  process.exit(1);
9891
10041
  }
9892
10042
  });
10043
+ var preview = program.command("preview").description("Manage preview URLs");
10044
+ if (isAgentMode()) {
10045
+ preview.command("create <port>").description("Register a preview port").action(async (port) => {
10046
+ try {
10047
+ await previewCreateCommand(port);
10048
+ } catch (error) {
10049
+ if (error instanceof Error) {
10050
+ console.error(`Error: ${error.message}`);
10051
+ }
10052
+ process.exit(1);
10053
+ }
10054
+ });
10055
+ preview.command("list").description("List active preview URLs").action(async () => {
10056
+ try {
10057
+ await previewListCommand();
10058
+ } catch (error) {
10059
+ if (error instanceof Error) {
10060
+ console.error(`Error: ${error.message}`);
10061
+ }
10062
+ process.exit(1);
10063
+ }
10064
+ });
10065
+ } else {
10066
+ preview.command("add <workspaceId>").description("Register a preview port for a workspace").requiredOption("-p, --port <port>", "Port number to preview").action(async (workspaceId, options) => {
10067
+ try {
10068
+ await previewAddCommand(workspaceId, options);
10069
+ } catch (error) {
10070
+ if (error instanceof Error) {
10071
+ console.error(import_chalk17.default.red(`
10072
+ \u2717 ${error.message}
10073
+ `));
10074
+ }
10075
+ process.exit(1);
10076
+ }
10077
+ });
10078
+ preview.command("list [workspaceId]").description("List active preview URLs for a workspace").action(async (workspaceId) => {
10079
+ try {
10080
+ await previewListCommand(workspaceId);
10081
+ } catch (error) {
10082
+ if (error instanceof Error) {
10083
+ console.error(import_chalk17.default.red(`
10084
+ \u2717 ${error.message}
10085
+ `));
10086
+ }
10087
+ process.exit(1);
10088
+ }
10089
+ });
10090
+ }
10091
+ if (isAgentMode()) {
10092
+ const previewCmd = program.commands.find((cmd) => cmd.name() === "preview");
10093
+ const cmds = program.commands;
10094
+ cmds.length = 0;
10095
+ if (previewCmd) {
10096
+ cmds.push(previewCmd);
10097
+ }
10098
+ }
9893
10099
  var versionCheckPromise = checkForUpdates(CLI_VERSION);
9894
10100
  program.parse();
9895
10101
  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.37",
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
  },