replicas-cli 0.2.278 → 0.2.280

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/README.md CHANGED
@@ -50,6 +50,9 @@ Connect to a workspace via SSH.
50
50
  ### `replicas interact`
51
51
  Launch the interactive terminal dashboard — a full TUI alternative to the web dashboard. View workspaces, chat with agents, monitor environment status, and create workspaces without leaving the terminal.
52
52
 
53
+ ### Coding agents
54
+ Use `replicas claude-auth` or `replicas codex-auth` to connect Claude Code or Codex credentials. Cursor uses a Cursor API key configured in Coding Agents settings.
55
+
53
56
  ## Configuration
54
57
 
55
58
  Create a `replicas.json` or `replicas.yaml` file in your repository root:
package/dist/index.mjs CHANGED
@@ -7559,11 +7559,33 @@ var VALID_AGENT_PROVIDERS = ["claude", "codex", "cursor", "relay"];
7559
7559
  function isValidAgentProvider(value) {
7560
7560
  return VALID_AGENT_PROVIDERS.some((p) => p === value);
7561
7561
  }
7562
+ var AGENT_PROVIDER_OPTIONS = [
7563
+ {
7564
+ value: "claude",
7565
+ label: "Claude Code",
7566
+ description: "Use Claude Code for tasks"
7567
+ },
7568
+ {
7569
+ value: "codex",
7570
+ label: "OpenAI Codex",
7571
+ description: "Use OpenAI Codex for tasks"
7572
+ },
7573
+ {
7574
+ value: "cursor",
7575
+ label: "Cursor",
7576
+ description: "Use Cursor for tasks"
7577
+ },
7578
+ {
7579
+ value: "relay",
7580
+ label: "Relay",
7581
+ description: "Orchestrating agent that delegates to Claude Code and Codex subagents"
7582
+ }
7583
+ ];
7562
7584
  var VALID_THINKING_LEVELS = ["low", "medium", "high", "max"];
7563
7585
  function isValidThinkingLevel(value) {
7564
7586
  return VALID_THINKING_LEVELS.some((l) => l === value);
7565
7587
  }
7566
- function getProviderDisplayName(provider) {
7588
+ function getProviderDisplayName(provider, variant = "short") {
7567
7589
  switch (provider) {
7568
7590
  case "codex":
7569
7591
  return "Codex";
@@ -7572,7 +7594,7 @@ function getProviderDisplayName(provider) {
7572
7594
  case "relay":
7573
7595
  return "Relay";
7574
7596
  case "claude":
7575
- return "Claude";
7597
+ return variant === "long" ? "Claude Code" : "Claude";
7576
7598
  }
7577
7599
  }
7578
7600
 
@@ -7602,6 +7624,10 @@ var CODEX_ASP_ITEM_ID_PAYLOAD_KEY = "codexAspItemId";
7602
7624
  var CODEX_QUOTA_STATUS_EVENT_TYPE = "codex-quota-status";
7603
7625
 
7604
7626
  // ../shared/src/pricing.ts
7627
+ var INTEGRATION_SOURCES = ["slack", "linear", "github", "gitlab"];
7628
+ var SYSTEMIC_SOURCES = ["api", "automation"];
7629
+ var INTEGRATION_SOURCES_SQL = INTEGRATION_SOURCES.map((s) => `'${s}'`).join(", ");
7630
+ var SYSTEMIC_SOURCES_SQL = SYSTEMIC_SOURCES.map((s) => `'${s}'`).join(", ");
7605
7631
  var PLANS = {
7606
7632
  hobby: {
7607
7633
  id: "hobby",
@@ -9238,7 +9264,7 @@ var HOOK_EXEC_MAX_BUFFER_BYTES = 10 * 1024 * 1024;
9238
9264
  var REPLICAS_CONFIG_FILENAMES = ["replicas.json", "replicas.yaml", "replicas.yml"];
9239
9265
 
9240
9266
  // ../shared/src/cli-version.ts
9241
- var CLI_VERSION = "0.2.278";
9267
+ var CLI_VERSION = "0.2.280";
9242
9268
 
9243
9269
  // ../shared/src/engine/environment.ts
9244
9270
  var DESKTOP_NOVNC_PORT = 6080;
@@ -9349,7 +9375,7 @@ function workspaceConfigWithPrFollowups(config2, prFollowups = config2?.capabili
9349
9375
  }
9350
9376
  var WORKSPACE_FILE_UPLOAD_MAX_SIZE_BYTES = 20 * 1024 * 1024;
9351
9377
  var WORKSPACE_FILE_CONTENT_MAX_SIZE_BYTES = 1 * 1024 * 1024;
9352
- var WORKSPACE_SIDEBAR_VIEWS = ["owned", "shared", "team", "integrations", "automated"];
9378
+ var WORKSPACE_SIDEBAR_VIEWS = ["owned", "shared", "team", "automated"];
9353
9379
  var WORKSPACE_STATUS_FILTERS = ["active", "sleeping", "preparing", "failed"];
9354
9380
  var DEFAULT_STATUS_FILTERS = [...WORKSPACE_STATUS_FILTERS];
9355
9381
  var DEFAULT_WORKSPACE_FILTERS = {
@@ -12585,6 +12611,16 @@ Update available: ${currentVersion} \u2192 ${latestVersion}`));
12585
12611
  // src/commands/replica.ts
12586
12612
  import chalk15 from "chalk";
12587
12613
  import prompts3 from "prompts";
12614
+ var REPLICA_AGENT_PROVIDERS = VALID_AGENT_PROVIDERS.filter((provider) => provider !== "relay");
12615
+ function parseReplicaAgent(value) {
12616
+ if (!value) return void 0;
12617
+ const normalized = value.trim().toLowerCase();
12618
+ if (isValidAgentProvider(normalized) && normalized !== "relay") {
12619
+ return normalized;
12620
+ }
12621
+ console.log(chalk15.red(`Invalid coding agent: ${value}. Must be one of: ${REPLICA_AGENT_PROVIDERS.join(", ")}`));
12622
+ process.exit(1);
12623
+ }
12588
12624
  function formatDate(dateString) {
12589
12625
  return new Date(dateString).toLocaleString();
12590
12626
  }
@@ -12785,7 +12821,7 @@ async function replicaCreateCommand(name, options) {
12785
12821
  let replicaName = name;
12786
12822
  let message = options.message;
12787
12823
  let selectedEnvironmentId = options.environment?.trim();
12788
- let codingAgent = options.agent;
12824
+ let codingAgent = parseReplicaAgent(options.agent);
12789
12825
  if (replicaName && /\s/.test(replicaName)) {
12790
12826
  console.log(chalk15.red("Replica name cannot contain spaces."));
12791
12827
  process.exit(1);
@@ -12842,21 +12878,14 @@ async function replicaCreateCommand(name, options) {
12842
12878
  type: "select",
12843
12879
  name: "agent",
12844
12880
  message: "Select coding agent:",
12845
- choices: [
12846
- { title: "Claude", value: "claude" },
12847
- { title: "Codex", value: "codex" }
12848
- ],
12881
+ choices: AGENT_PROVIDER_OPTIONS.filter((option) => option.value !== "relay").map((option) => ({ title: option.label, value: option.value })),
12849
12882
  initial: 0
12850
12883
  });
12851
12884
  if (!response2.agent) {
12852
12885
  console.log(chalk15.yellow("\nCancelled."));
12853
12886
  return;
12854
12887
  }
12855
- codingAgent = response2.agent;
12856
- }
12857
- if (!codingAgent || !["claude", "codex"].includes(codingAgent)) {
12858
- console.log(chalk15.red(`Invalid coding agent: ${codingAgent}. Must be one of: claude, codex`));
12859
- process.exit(1);
12888
+ codingAgent = parseReplicaAgent(response2.agent);
12860
12889
  }
12861
12890
  const body = {
12862
12891
  name: replicaName,
@@ -12907,11 +12936,7 @@ async function replicaSendCommand(id, options) {
12907
12936
  message
12908
12937
  };
12909
12938
  if (options.agent) {
12910
- if (!["claude", "codex"].includes(options.agent)) {
12911
- console.log(chalk15.red(`Invalid coding agent: ${options.agent}. Must be one of: claude, codex`));
12912
- process.exit(1);
12913
- }
12914
- body.coding_agent = options.agent;
12939
+ body.coding_agent = parseReplicaAgent(options.agent);
12915
12940
  }
12916
12941
  const response = await orgAuthenticatedFetch(
12917
12942
  `/v1/replica/${id}/send`,
@@ -15934,11 +15959,6 @@ ${parsed.userPrompt}` });
15934
15959
 
15935
15960
  // src/interactive/components/ChatMessage.tsx
15936
15961
  import { Fragment as Fragment3, jsx as jsx6, jsxs as jsxs6 } from "@opentui/react/jsx-runtime";
15937
- var AGENT_LABELS = {
15938
- claude: "Claude",
15939
- codex: "Codex",
15940
- relay: "Relay"
15941
- };
15942
15962
  function truncate4(text, maxLen) {
15943
15963
  return text.length > maxLen ? text.slice(0, maxLen - 1) + "\u2026" : text;
15944
15964
  }
@@ -16085,7 +16105,7 @@ function ChatMessage({ message, provider }) {
16085
16105
  }
16086
16106
  case "agent":
16087
16107
  return /* @__PURE__ */ jsxs6("box", { flexDirection: "column", paddingX: 1, children: [
16088
- /* @__PURE__ */ jsx6("text", { children: /* @__PURE__ */ jsx6("span", { fg: "#3eeba3", children: /* @__PURE__ */ jsx6("strong", { children: AGENT_LABELS[provider] }) }) }),
16108
+ /* @__PURE__ */ jsx6("text", { children: /* @__PURE__ */ jsx6("span", { fg: "#3eeba3", children: /* @__PURE__ */ jsx6("strong", { children: getProviderDisplayName(provider) }) }) }),
16089
16109
  /* @__PURE__ */ jsx6(
16090
16110
  "markdown",
16091
16111
  {
@@ -16193,7 +16213,8 @@ function ChatArea({
16193
16213
  isProcessing,
16194
16214
  loading,
16195
16215
  agentAvailable,
16196
- agentLabel
16216
+ agentLabel,
16217
+ agentConnectHelp
16197
16218
  }) {
16198
16219
  const textareaRef = useRef2(null);
16199
16220
  const scrollboxRef = useRef2(null);
@@ -16345,9 +16366,8 @@ function ChatArea({
16345
16366
  ) }),
16346
16367
  !agentAvailable && /* @__PURE__ */ jsx7("box", { paddingX: 1, height: 1, children: /* @__PURE__ */ jsx7("text", { children: /* @__PURE__ */ jsxs7("span", { fg: "#d97706", children: [
16347
16368
  agentLabel,
16348
- " is not connected. Run `replicas ",
16349
- agentLabel === "Codex" ? "codex-auth" : "claude-auth",
16350
- "` to connect."
16369
+ " is not connected. ",
16370
+ agentConnectHelp
16351
16371
  ] }) }) }),
16352
16372
  /* @__PURE__ */ jsxs7(
16353
16373
  "box",
@@ -16707,7 +16727,8 @@ function WorkspaceInfo({ status, workspaceName, workspaceId, focused, loading, a
16707
16727
  const env = rawEnv && agentAvailability ? {
16708
16728
  ...rawEnv,
16709
16729
  claudeAuthMethod: agentAvailability.claude.available ? rawEnv.claudeAuthMethod : "none",
16710
- codexAuthMethod: agentAvailability.codex.available ? rawEnv.codexAuthMethod : "none"
16730
+ codexAuthMethod: agentAvailability.codex.available ? rawEnv.codexAuthMethod : "none",
16731
+ cursorAuthMethod: agentAvailability.cursor.available ? rawEnv.cursorAuthMethod : "none"
16711
16732
  } : rawEnv;
16712
16733
  const dashboardItem = findItem("dashboard");
16713
16734
  const wakeItem = findItem("wake");
@@ -16768,7 +16789,7 @@ function WorkspaceInfo({ status, workspaceName, workspaceId, focused, loading, a
16768
16789
  onClick: () => handleAction(wakeItem)
16769
16790
  }
16770
16791
  ),
16771
- (status.isClaudeProcessing || status.isCodexProcessing || status.isRelayProcessing) && /* @__PURE__ */ jsxs8("box", { backgroundColor: "#1a1500", paddingX: 1, marginX: 1, marginBottom: 1, children: [
16792
+ (status.isClaudeProcessing || status.isCodexProcessing || status.isCursorProcessing || status.isRelayProcessing) && /* @__PURE__ */ jsxs8("box", { backgroundColor: "#1a1500", paddingX: 1, marginX: 1, marginBottom: 1, children: [
16772
16793
  status.isClaudeProcessing && /* @__PURE__ */ jsx8("text", { children: /* @__PURE__ */ jsxs8("span", { fg: "#ffaa00", children: [
16773
16794
  "\u25C6",
16774
16795
  " Claude thinking..."
@@ -16777,6 +16798,10 @@ function WorkspaceInfo({ status, workspaceName, workspaceId, focused, loading, a
16777
16798
  "\u25C6",
16778
16799
  " Codex thinking..."
16779
16800
  ] }) }),
16801
+ status.isCursorProcessing && /* @__PURE__ */ jsx8("text", { children: /* @__PURE__ */ jsxs8("span", { fg: "#ffaa00", children: [
16802
+ "\u25C6",
16803
+ " Cursor thinking..."
16804
+ ] }) }),
16780
16805
  status.isRelayProcessing && /* @__PURE__ */ jsx8("text", { children: /* @__PURE__ */ jsxs8("span", { fg: "#ffaa00", children: [
16781
16806
  "\u25C6",
16782
16807
  " Relay thinking..."
@@ -16790,6 +16815,10 @@ function WorkspaceInfo({ status, workspaceName, workspaceId, focused, loading, a
16790
16815
  /* @__PURE__ */ jsxs8("box", { flexDirection: "row", justifyContent: "space-between", paddingX: 1, backgroundColor: "#111111", children: [
16791
16816
  /* @__PURE__ */ jsx8("text", { children: /* @__PURE__ */ jsx8("span", { fg: "#cccccc", children: "Codex" }) }),
16792
16817
  /* @__PURE__ */ jsx8("text", { children: AUTH_METHOD_LABELS[env.codexAuthMethod] ? /* @__PURE__ */ jsx8("span", { fg: "#3eeba3", children: AUTH_METHOD_LABELS[env.codexAuthMethod] }) : /* @__PURE__ */ jsx8("span", { fg: "#ff4444", children: "\u2717" }) })
16818
+ ] }),
16819
+ /* @__PURE__ */ jsxs8("box", { flexDirection: "row", justifyContent: "space-between", paddingX: 1, backgroundColor: "#111111", children: [
16820
+ /* @__PURE__ */ jsx8("text", { children: /* @__PURE__ */ jsx8("span", { fg: "#cccccc", children: "Cursor" }) }),
16821
+ /* @__PURE__ */ jsx8("text", { children: AUTH_METHOD_LABELS[env.cursorAuthMethod] ? /* @__PURE__ */ jsx8("span", { fg: "#3eeba3", children: AUTH_METHOD_LABELS[env.cursorAuthMethod] }) : /* @__PURE__ */ jsx8("span", { fg: "#ff4444", children: "\u2717" }) })
16793
16822
  ] })
16794
16823
  ] }),
16795
16824
  /* @__PURE__ */ jsx8(Section, { title: "View", children: (() => {
@@ -17027,6 +17056,12 @@ var authValue = {
17027
17056
  monolithUrl: MONOLITH_URL5,
17028
17057
  queryClient
17029
17058
  };
17059
+ function getAgentConnectHelp(provider) {
17060
+ if (provider === "codex") return "Run `replicas codex-auth` to connect.";
17061
+ if (provider === "cursor") return "Add a Cursor API key in Coding Agents settings.";
17062
+ if (provider === "relay") return "Configure Relay in Coding Agents settings.";
17063
+ return "Run `replicas claude-auth` to connect.";
17064
+ }
17030
17065
  function App() {
17031
17066
  return /* @__PURE__ */ jsx11(ReplicasAuthProvider, { value: authValue, children: /* @__PURE__ */ jsxs9(ToastProvider, { children: [
17032
17067
  /* @__PURE__ */ jsx11(AppInner, {}),
@@ -17112,8 +17147,9 @@ function AppInner() {
17112
17147
  const selectedChat = chats.find((c) => c.id === resolvedChatId) ?? null;
17113
17148
  const isProcessing = mockThinking || (selectedChat?.processing ?? false);
17114
17149
  const selectedAgent = selectedChat?.provider ?? "claude";
17115
- const agentAvailable = agentAvailability ? selectedAgent === "codex" ? agentAvailability.codex.available : agentAvailability.claude.available : true;
17116
- const agentLabel = selectedAgent === "codex" ? "Codex" : "Claude Code";
17150
+ const agentAvailable = agentAvailability ? selectedAgent === "codex" ? agentAvailability.codex.available : selectedAgent === "cursor" ? agentAvailability.cursor.available : selectedAgent === "relay" ? agentAvailability.relay.available : agentAvailability.claude.available : true;
17151
+ const agentLabel = getProviderDisplayName(selectedAgent, "long");
17152
+ const agentConnectHelp = getAgentConnectHelp(selectedAgent);
17117
17153
  const displayMessages = useMemo6(() => {
17118
17154
  if (isMockSelected) return mockMessages;
17119
17155
  const rawEvents = historyData?.events ?? [];
@@ -17309,7 +17345,7 @@ function AppInner() {
17309
17345
  return;
17310
17346
  }
17311
17347
  if (!agentAvailable) {
17312
- toast.error(new Error(`${agentLabel} is not connected. Run \`replicas ${selectedAgent === "codex" ? "codex-auth" : "claude-auth"}\` to connect.`));
17348
+ toast.error(new Error(`${agentLabel} is not connected. ${agentConnectHelp}`));
17313
17349
  return;
17314
17350
  }
17315
17351
  sendMessageMutation.mutate({
@@ -17317,7 +17353,7 @@ function AppInner() {
17317
17353
  planMode: taskMode === "plan"
17318
17354
  });
17319
17355
  },
17320
- [selectedWorkspaceId, resolvedChatId, isMockSelected, sendMessageMutation, taskMode, agentAvailable, agentLabel, selectedAgent, toast.error]
17356
+ [selectedWorkspaceId, resolvedChatId, isMockSelected, sendMessageMutation, taskMode, agentAvailable, agentLabel, agentConnectHelp, toast.error]
17321
17357
  );
17322
17358
  return /* @__PURE__ */ jsxs9("box", { flexDirection: "column", width: "100%", height: "100%", backgroundColor: "#000000", children: [
17323
17359
  /* @__PURE__ */ jsxs9("box", { flexDirection: "row", flexGrow: 1, backgroundColor: "#000000", children: [
@@ -17362,7 +17398,8 @@ function AppInner() {
17362
17398
  isProcessing,
17363
17399
  loading: loadingMessages,
17364
17400
  agentAvailable,
17365
- agentLabel
17401
+ agentLabel,
17402
+ agentConnectHelp
17366
17403
  }
17367
17404
  ) : selectedWorkspaceId && statusData?.status === "sleeping" ? /* @__PURE__ */ jsxs9(
17368
17405
  "box",
@@ -18130,7 +18167,7 @@ program.command("get <id>").description("Get replica details by ID").action(asyn
18130
18167
  process.exit(1);
18131
18168
  }
18132
18169
  });
18133
- program.command("create [name]").description("Create a new replica").option("-m, --message <message>", "Initial message for the replica").option("-e, --environment <environment>", "Environment ID").option("-a, --agent <agent>", "Coding agent (claude, codex)").action(async (name, options) => {
18170
+ program.command("create [name]").description("Create a new replica").option("-m, --message <message>", "Initial message for the replica").option("-e, --environment <environment>", "Environment ID").option("-a, --agent <agent>", "Coding agent (claude, codex, cursor)").action(async (name, options) => {
18134
18171
  try {
18135
18172
  await replicaCreateCommand(name, options);
18136
18173
  } catch (error) {
@@ -18142,7 +18179,7 @@ program.command("create [name]").description("Create a new replica").option("-m,
18142
18179
  process.exit(1);
18143
18180
  }
18144
18181
  });
18145
- program.command("send <id>").description("Send a message to a replica").option("-m, --message <message>", "Message to send").option("-a, --agent <agent>", "Coding agent (claude, codex)").action(async (id, options) => {
18182
+ program.command("send <id>").description("Send a message to a replica").option("-m, --message <message>", "Message to send").option("-a, --agent <agent>", "Coding agent (claude, codex, cursor)").action(async (id, options) => {
18146
18183
  try {
18147
18184
  await replicaSendCommand(id, options);
18148
18185
  } catch (error) {
@@ -18203,7 +18240,7 @@ automation.command("get <id>").description("Get automation details by ID").actio
18203
18240
  process.exit(1);
18204
18241
  }
18205
18242
  });
18206
- automation.command("create [name]").description("Create a new automation").option("-p, --prompt <prompt>", "Prompt for the automation").option("-e, --environment <environment>", "Environment name or ID").option("--trigger-cron <schedule>", 'Cron schedule expression (e.g. "0 9 * * 1-5")').option("--trigger-cron-timezone <timezone>", "Timezone for cron trigger (default: UTC)").option("--trigger-github <event>", 'GitHub event (e.g. "pull_request.opened")').option("--trigger-github-repos <repos>", "Comma-separated repo names to filter GitHub trigger").option("--lifecycle <policy>", "Workspace lifecycle: delete_when_done, delete_after_inactivity, default").option("--auto-stop-minutes <minutes>", "Inactivity timeout in minutes (3-1440, requires --lifecycle delete_after_inactivity)").option("--pr-followups", "Allow follow-up actions on matching PRs").option("--agent-provider <provider>", 'Coding agent to use: claude, codex, relay (or "none" to inherit org default)').option("--model <model>", 'Model identifier (must be valid for --agent-provider; pass "none" to clear)').option("--thinking-level <level>", 'Thinking/reasoning level: low, medium, high, max (or "none" to clear)').option("--plan-mode", "Run automation messages in plan mode").option("--goal-mode", "Set automation messages as Codex goals").option("--fast-mode", "Run automation messages in fast mode").option("--personal", "Create a personal automation owned by the authenticated user").option("--disabled", "Create in disabled state").action(async (name, options) => {
18243
+ automation.command("create [name]").description("Create a new automation").option("-p, --prompt <prompt>", "Prompt for the automation").option("-e, --environment <environment>", "Environment name or ID").option("--trigger-cron <schedule>", 'Cron schedule expression (e.g. "0 9 * * 1-5")').option("--trigger-cron-timezone <timezone>", "Timezone for cron trigger (default: UTC)").option("--trigger-github <event>", 'GitHub event (e.g. "pull_request.opened")').option("--trigger-github-repos <repos>", "Comma-separated repo names to filter GitHub trigger").option("--lifecycle <policy>", "Workspace lifecycle: delete_when_done, delete_after_inactivity, default").option("--auto-stop-minutes <minutes>", "Inactivity timeout in minutes (3-1440, requires --lifecycle delete_after_inactivity)").option("--pr-followups", "Allow follow-up actions on matching PRs").option("--agent-provider <provider>", 'Coding agent to use: claude, codex, cursor, relay (or "none" to inherit org default)').option("--model <model>", 'Model identifier (must be valid for --agent-provider; pass "none" to clear)').option("--thinking-level <level>", 'Thinking/reasoning level: low, medium, high, max (or "none" to clear)').option("--plan-mode", "Run automation messages in plan mode").option("--goal-mode", "Set automation messages as Codex goals").option("--fast-mode", "Run automation messages in fast mode").option("--personal", "Create a personal automation owned by the authenticated user").option("--disabled", "Create in disabled state").action(async (name, options) => {
18207
18244
  try {
18208
18245
  await automationCreateCommand(name, {
18209
18246
  ...options,
@@ -18218,7 +18255,7 @@ automation.command("create [name]").description("Create a new automation").optio
18218
18255
  process.exit(1);
18219
18256
  }
18220
18257
  });
18221
- automation.command("edit <id>").description("Edit an existing automation").option("-n, --name <name>", "New name").option("-p, --prompt <prompt>", "New prompt").option("-e, --enabled <enabled>", "Enable or disable (true/false)").option("--trigger-cron <schedule>", "Set cron schedule (replaces existing triggers)").option("--trigger-cron-timezone <timezone>", "Timezone for cron trigger").option("--trigger-github <event>", "Set GitHub event (replaces existing triggers)").option("--trigger-github-repos <repos>", "Comma-separated repo names to filter GitHub trigger").option("--environment <environment>", "Environment name or ID").option("--lifecycle <policy>", "Workspace lifecycle: delete_when_done, delete_after_inactivity, default").option("--auto-stop-minutes <minutes>", "Inactivity timeout in minutes (3-1440, requires --lifecycle delete_after_inactivity)").option("--pr-followups <enabled>", "Allow follow-up actions on matching PRs (true/false)", parseBooleanOption).option("--agent-provider <provider>", 'Coding agent to use: claude, codex, relay (or "none" to inherit org default)').option("--model <model>", 'Model identifier (must be valid for --agent-provider; pass "none" to clear)').option("--thinking-level <level>", 'Thinking/reasoning level: low, medium, high, max (or "none" to clear)').option("--plan-mode <enabled>", "Run automation messages in plan mode (true/false)", parseBooleanOption).option("--goal-mode <enabled>", "Set automation messages as Codex goals (true/false)", parseBooleanOption).option("--fast-mode <enabled>", "Run automation messages in fast mode (true/false)", parseBooleanOption).action(async (id, options) => {
18258
+ automation.command("edit <id>").description("Edit an existing automation").option("-n, --name <name>", "New name").option("-p, --prompt <prompt>", "New prompt").option("-e, --enabled <enabled>", "Enable or disable (true/false)").option("--trigger-cron <schedule>", "Set cron schedule (replaces existing triggers)").option("--trigger-cron-timezone <timezone>", "Timezone for cron trigger").option("--trigger-github <event>", "Set GitHub event (replaces existing triggers)").option("--trigger-github-repos <repos>", "Comma-separated repo names to filter GitHub trigger").option("--environment <environment>", "Environment name or ID").option("--lifecycle <policy>", "Workspace lifecycle: delete_when_done, delete_after_inactivity, default").option("--auto-stop-minutes <minutes>", "Inactivity timeout in minutes (3-1440, requires --lifecycle delete_after_inactivity)").option("--pr-followups <enabled>", "Allow follow-up actions on matching PRs (true/false)", parseBooleanOption).option("--agent-provider <provider>", 'Coding agent to use: claude, codex, cursor, relay (or "none" to inherit org default)').option("--model <model>", 'Model identifier (must be valid for --agent-provider; pass "none" to clear)').option("--thinking-level <level>", 'Thinking/reasoning level: low, medium, high, max (or "none" to clear)').option("--plan-mode <enabled>", "Run automation messages in plan mode (true/false)", parseBooleanOption).option("--goal-mode <enabled>", "Set automation messages as Codex goals (true/false)", parseBooleanOption).option("--fast-mode <enabled>", "Run automation messages in fast mode (true/false)", parseBooleanOption).action(async (id, options) => {
18222
18259
  try {
18223
18260
  await automationEditCommand(id, options);
18224
18261
  } catch (error) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "replicas-cli",
3
- "version": "0.2.278",
3
+ "version": "0.2.280",
4
4
  "description": "CLI for managing Replicas workspaces - SSH into cloud dev environments with automatic port forwarding",
5
5
  "main": "dist/index.mjs",
6
6
  "bin": {