replicas-cli 0.3.2 → 0.3.3

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.cjs +96 -45
  2. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -23646,15 +23646,65 @@ function areUserMessagesWithinMatchWindow(a, b) {
23646
23646
  // ../shared/src/uuid.ts
23647
23647
  var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
23648
23648
 
23649
+ // ../shared/src/automations/github/index.ts
23650
+ var REPO_FILTER_PARAM = {
23651
+ id: "repository_ids",
23652
+ label: "Filter by repository",
23653
+ type: "repository_ids"
23654
+ };
23655
+ var EXCLUDED_ACTORS_PARAM = {
23656
+ id: "excluded_actors",
23657
+ label: "Exclude users",
23658
+ type: "excluded_actors"
23659
+ };
23660
+ var REVIEWER_LOGINS_PARAM = {
23661
+ id: "reviewer_logins",
23662
+ label: "Requested reviewers",
23663
+ type: "reviewer_logins",
23664
+ required: true
23665
+ };
23666
+ var GROUP_PR_EVENTS_PARAM = {
23667
+ id: "group_pr_events",
23668
+ label: "Group PR events to same workspace",
23669
+ type: "boolean"
23670
+ };
23671
+ var REVIEW_REQUESTED_EVENT = "pull_request.review_requested";
23672
+ var GITHUB_TRIGGER = {
23673
+ type: "github",
23674
+ label: "GitHub",
23675
+ description: "Trigger on repository events",
23676
+ icon: "github",
23677
+ events: [
23678
+ { id: "pull_request.opened", label: "PR opened", parameters: [REPO_FILTER_PARAM, EXCLUDED_ACTORS_PARAM, GROUP_PR_EVENTS_PARAM] },
23679
+ { id: "pull_request.synchronize", label: "PR updated (new commits)", parameters: [REPO_FILTER_PARAM, EXCLUDED_ACTORS_PARAM, GROUP_PR_EVENTS_PARAM] },
23680
+ { id: REVIEW_REQUESTED_EVENT, label: "PR review requested", parameters: [REVIEWER_LOGINS_PARAM, REPO_FILTER_PARAM, EXCLUDED_ACTORS_PARAM] },
23681
+ { id: "pull_request.merged", label: "PR merged", parameters: [REPO_FILTER_PARAM, EXCLUDED_ACTORS_PARAM] },
23682
+ { id: "pull_request.closed", label: "PR closed", parameters: [REPO_FILTER_PARAM, EXCLUDED_ACTORS_PARAM] },
23683
+ { id: "pull_request.command", label: "PR command (/replicas run)", parameters: [REPO_FILTER_PARAM, EXCLUDED_ACTORS_PARAM, GROUP_PR_EVENTS_PARAM] }
23684
+ ]
23685
+ };
23686
+
23649
23687
  // ../shared/src/automations/trigger-schemas.ts
23688
+ function getReviewerLoginsError(event, logins) {
23689
+ const isReviewRequested = event === REVIEW_REQUESTED_EVENT;
23690
+ if (isReviewRequested === !!logins?.some((login) => login.trim().replace(/^@+/, ""))) return null;
23691
+ return isReviewRequested ? "The PR review requested trigger needs at least one GitHub username" : "Requested reviewers only apply to the PR review requested trigger";
23692
+ }
23650
23693
  var repositoryTriggerConfigSchema = external_exports.object({
23651
23694
  event: external_exports.string(),
23652
23695
  repository_ids: external_exports.array(external_exports.string().regex(UUID_RE, "must be a repository id")).optional(),
23653
23696
  group_pr_events: external_exports.boolean().optional(),
23654
- excluded_actors: external_exports.array(external_exports.string()).optional()
23697
+ excluded_actors: external_exports.array(external_exports.string()).optional(),
23698
+ reviewer_logins: external_exports.array(external_exports.string()).optional()
23655
23699
  });
23656
23700
  var cronTriggerSchema = external_exports.object({ type: external_exports.literal("cron"), config: external_exports.object({ schedule: external_exports.string(), timezone: external_exports.string().optional() }) });
23657
- var githubTriggerSchema = external_exports.object({ type: external_exports.literal("github"), config: repositoryTriggerConfigSchema });
23701
+ var githubTriggerSchema = external_exports.object({
23702
+ type: external_exports.literal("github"),
23703
+ config: repositoryTriggerConfigSchema.superRefine((config3, ctx) => {
23704
+ const message2 = getReviewerLoginsError(config3.event, config3.reviewer_logins);
23705
+ if (message2) ctx.addIssue({ code: "custom", message: message2, path: ["reviewer_logins"] });
23706
+ })
23707
+ });
23658
23708
  var gitlabTriggerSchema = external_exports.object({ type: external_exports.literal("gitlab"), config: repositoryTriggerConfigSchema });
23659
23709
  var automationTriggerSchema = external_exports.discriminatedUnion("type", [
23660
23710
  cronTriggerSchema,
@@ -23721,9 +23771,22 @@ var mcpWorkloadAuthSchema = external_exports.strictObject({
23721
23771
  type: external_exports.literal("workspace_identity"),
23722
23772
  audience: workspaceAudienceSchema
23723
23773
  });
23774
+ var mcpAuthSchema = external_exports.discriminatedUnion("type", [
23775
+ mcpWorkloadAuthSchema,
23776
+ external_exports.strictObject({ type: external_exports.literal("oauth") })
23777
+ ]);
23724
23778
  function identityTokenUrl() {
23725
23779
  return `http://127.0.0.1:${IDENTITY_PROXY_PORT}${IDENTITY_TOKEN_PATH}`;
23726
23780
  }
23781
+ var engineMcpOAuthTokenRequestSchema = external_exports.object({
23782
+ environment_mcp_id: external_exports.string().uuid(),
23783
+ force_refresh: external_exports.boolean().optional()
23784
+ });
23785
+ var engineMcpOAuthTokenResponseSchema = external_exports.object({
23786
+ url: external_exports.string(),
23787
+ access_token: external_exports.string(),
23788
+ expires_at: external_exports.string().nullable()
23789
+ });
23727
23790
 
23728
23791
  // ../shared/src/routes/environment.ts
23729
23792
  var ENVIRONMENT_MCP_TRANSPORTS = ["stdio", "http", "sse"];
@@ -23733,7 +23796,7 @@ var createEnvironmentMcpRequestSchema = external_exports.object({
23733
23796
  transport: external_exports.enum(ENVIRONMENT_MCP_TRANSPORTS),
23734
23797
  config: external_exports.union([
23735
23798
  external_exports.object({ command: external_exports.string().min(1), args: external_exports.array(external_exports.string()).optional(), env: stringMap.optional() }),
23736
- external_exports.object({ url: external_exports.url(), headers: stringMap.optional(), auth: mcpWorkloadAuthSchema.optional() })
23799
+ external_exports.object({ url: external_exports.url(), headers: stringMap.optional(), auth: mcpAuthSchema.optional() })
23737
23800
  ]).describe("stdio: `{ command, args, env }`. http/sse: `{ url, headers }`.")
23738
23801
  });
23739
23802
  var updateEnvironmentMcpRequestSchema = createEnvironmentMcpRequestSchema.partial();
@@ -24336,7 +24399,7 @@ Trigger shapes:
24336
24399
  { "type": "cron", "config": { "schedule": "0 9 * * 1-5", "timezone": "UTC" } }
24337
24400
  \`\`\`
24338
24401
 
24339
- GitHub events: \`pull_request.opened\`, \`pull_request.synchronize\`, \`pull_request.merged\`, \`pull_request.closed\`. GitLab events: \`merge_request.opened\`, \`merge_request.updated\`, \`merge_request.merged\`, \`merge_request.closed\`. Use one trigger type family per automation and pick the code host the repositories actually live on.
24402
+ GitHub events: \`pull_request.opened\`, \`pull_request.synchronize\`, \`pull_request.review_requested\` (requires a \`reviewer_logins\` list of GitHub usernames), \`pull_request.merged\`, \`pull_request.closed\`. GitLab events: \`merge_request.opened\`, \`merge_request.updated\`, \`merge_request.merged\`, \`merge_request.closed\`. Use one trigger type family per automation and pick the code host the repositories actually live on.
24340
24403
 
24341
24404
  Test the hooks before proposing them: run the drafted warm hook and start hook scripts in this workspace (from \`~/workspaces\`) and fix the earliest failure until both exit 0 on a second run.
24342
24405
 
@@ -28245,7 +28308,7 @@ var headlessAgentRequestSchema = external_exports.object({
28245
28308
  });
28246
28309
 
28247
28310
  // ../shared/src/cli-version.ts
28248
- var CLI_VERSION = "0.3.2";
28311
+ var CLI_VERSION = "0.3.3";
28249
28312
 
28250
28313
  // ../shared/src/version.ts
28251
28314
  function compareVersions(v1, v2) {
@@ -28806,36 +28869,6 @@ function validateAgentSelection(body, existing, modelCatalogs = {}) {
28806
28869
  return createSuccessResult({ agentProvider, model: model2, thinkingLevel: thinkingLevel2 });
28807
28870
  }
28808
28871
 
28809
- // ../shared/src/automations/github/index.ts
28810
- var REPO_FILTER_PARAM = {
28811
- id: "repository_ids",
28812
- label: "Filter by repository",
28813
- type: "repository_ids"
28814
- };
28815
- var EXCLUDED_ACTORS_PARAM = {
28816
- id: "excluded_actors",
28817
- label: "Exclude users",
28818
- type: "excluded_actors"
28819
- };
28820
- var GROUP_PR_EVENTS_PARAM = {
28821
- id: "group_pr_events",
28822
- label: "Group PR events to same workspace",
28823
- type: "boolean"
28824
- };
28825
- var GITHUB_TRIGGER = {
28826
- type: "github",
28827
- label: "GitHub",
28828
- description: "Trigger on repository events",
28829
- icon: "github",
28830
- events: [
28831
- { id: "pull_request.opened", label: "PR opened", parameters: [REPO_FILTER_PARAM, EXCLUDED_ACTORS_PARAM, GROUP_PR_EVENTS_PARAM] },
28832
- { id: "pull_request.synchronize", label: "PR updated (new commits)", parameters: [REPO_FILTER_PARAM, EXCLUDED_ACTORS_PARAM, GROUP_PR_EVENTS_PARAM] },
28833
- { id: "pull_request.merged", label: "PR merged", parameters: [REPO_FILTER_PARAM, EXCLUDED_ACTORS_PARAM] },
28834
- { id: "pull_request.closed", label: "PR closed", parameters: [REPO_FILTER_PARAM, EXCLUDED_ACTORS_PARAM] },
28835
- { id: "pull_request.command", label: "PR command (/replicas run)", parameters: [REPO_FILTER_PARAM, EXCLUDED_ACTORS_PARAM, GROUP_PR_EVENTS_PARAM] }
28836
- ]
28837
- };
28838
-
28839
28872
  // ../shared/src/automations/gitlab/index.ts
28840
28873
  var REPO_FILTER_PARAM2 = {
28841
28874
  id: "repository_ids",
@@ -32506,11 +32539,16 @@ function parseWorkspaceLifecyclePolicyOption(value) {
32506
32539
  if (isAutomationLifecyclePolicy(value)) return value;
32507
32540
  throw new Error(`Invalid lifecycle policy: ${value}. Valid options: ${AUTOMATION_LIFECYCLE_POLICIES.join(", ")}`);
32508
32541
  }
32509
- function parseExcludedActorsOption(value) {
32542
+ function parseActorListOption(value) {
32510
32543
  if (value === void 0) return void 0;
32511
32544
  const actors = value.split(",").map((actor) => actor.trim()).filter(Boolean);
32512
32545
  return actors.length > 0 ? actors : void 0;
32513
32546
  }
32547
+ function validateGithubReviewersOption(options) {
32548
+ if (options.triggerGithubReviewers !== void 0 && !options.triggerGithub) throw new Error("--trigger-github-reviewers requires --trigger-github");
32549
+ const error51 = options.triggerGithub && getReviewerLoginsError(options.triggerGithub, parseActorListOption(options.triggerGithubReviewers));
32550
+ if (error51) throw new Error(`${error51} (--trigger-github-reviewers)`);
32551
+ }
32514
32552
  var DURATION_UNIT_MS = { m: 6e4, h: 36e5, d: 864e5, w: 6048e5 };
32515
32553
  function parseDuration(value) {
32516
32554
  const parts = [...value.trim().toLowerCase().matchAll(/(\d+)\s*([mhdw])/g)];
@@ -32595,6 +32633,7 @@ function formatTrigger(trigger) {
32595
32633
  const config3 = trigger.config;
32596
32634
  const details = [
32597
32635
  config3.repository_ids?.length ? `${config3.repository_ids.length} repo${config3.repository_ids.length > 1 ? "s" : ""} filtered` : null,
32636
+ config3.reviewer_logins?.length ? `reviewers: ${config3.reviewer_logins.join(", ")}` : null,
32598
32637
  config3.excluded_actors?.length ? `exclude: ${config3.excluded_actors.join(", ")}` : null
32599
32638
  ].filter(Boolean);
32600
32639
  return `github: ${config3.event}${details.length > 0 ? ` (${details.join(", ")})` : ""}`;
@@ -32636,13 +32675,15 @@ function buildTriggersFromOptions(options, runAt, repositories) {
32636
32675
  for (const [type, event, repoNames, excludeUsers] of providerTriggers) {
32637
32676
  if (!event) continue;
32638
32677
  const repositoryIds = resolveTriggerRepositoryIds(repositories, repoNames, type);
32639
- const excludedActors = parseExcludedActorsOption(excludeUsers);
32678
+ const excludedActors = parseActorListOption(excludeUsers);
32679
+ const reviewerLogins = type === "github" ? parseActorListOption(options.triggerGithubReviewers) : void 0;
32640
32680
  triggers.push({
32641
32681
  type,
32642
32682
  config: {
32643
32683
  event,
32644
32684
  ...repositoryIds ? { repository_ids: repositoryIds } : {},
32645
- ...excludedActors ? { excluded_actors: excludedActors } : {}
32685
+ ...excludedActors ? { excluded_actors: excludedActors } : {},
32686
+ ...reviewerLogins ? { reviewer_logins: reviewerLogins } : {}
32646
32687
  }
32647
32688
  });
32648
32689
  }
@@ -32854,13 +32895,21 @@ async function promptForTriggers(repositories) {
32854
32895
  name: "excludedActors",
32855
32896
  message: "Exclude GitHub users (comma-separated, optional):"
32856
32897
  });
32857
- const excludedActors = parseExcludedActorsOption(excludedActorsResponse.excludedActors);
32898
+ const excludedActors = parseActorListOption(excludedActorsResponse.excludedActors);
32899
+ const reviewerLogins = eventResponse.event === REVIEW_REQUESTED_EVENT ? parseActorListOption((await ask({
32900
+ type: "text",
32901
+ name: "reviewers",
32902
+ message: "Fire when review is requested from (comma-separated GitHub users):",
32903
+ validate: (value) => parseActorListOption(value) ? true : "Enter at least one GitHub username"
32904
+ })).reviewers) : void 0;
32905
+ if (eventResponse.event === REVIEW_REQUESTED_EVENT && !reviewerLogins) return triggers;
32858
32906
  triggers.push({
32859
32907
  type: "github",
32860
32908
  config: {
32861
32909
  event: eventResponse.event,
32862
32910
  ...triggerRepoIds ? { repository_ids: triggerRepoIds } : {},
32863
- ...excludedActors ? { excluded_actors: excludedActors } : {}
32911
+ ...excludedActors ? { excluded_actors: excludedActors } : {},
32912
+ ...reviewerLogins ? { reviewer_logins: reviewerLogins } : {}
32864
32913
  }
32865
32914
  });
32866
32915
  } else if (typeResponse.type === "gitlab") {
@@ -32889,7 +32938,7 @@ async function promptForTriggers(repositories) {
32889
32938
  name: "excludedActors",
32890
32939
  message: "Exclude GitLab users (comma-separated, optional):"
32891
32940
  });
32892
- const excludedActors = parseExcludedActorsOption(excludedActorsResponse.excludedActors);
32941
+ const excludedActors = parseActorListOption(excludedActorsResponse.excludedActors);
32893
32942
  triggers.push({
32894
32943
  type: "gitlab",
32895
32944
  config: {
@@ -32922,6 +32971,7 @@ async function automationCreateCommand(name, options) {
32922
32971
  if (isNaN(minutes) || minutes < 3 || minutes > 1440) throw new Error("--auto-stop-minutes must be between 3 and 1440");
32923
32972
  }
32924
32973
  if (options.triggerGithubExcludeUsers !== void 0 && !options.triggerGithub) throw new Error("--trigger-github-exclude-users requires --trigger-github");
32974
+ validateGithubReviewersOption(options);
32925
32975
  if (options.triggerGitlabExcludeUsers !== void 0 && !options.triggerGitlab) throw new Error("--trigger-gitlab-exclude-users requires --trigger-gitlab");
32926
32976
  const agentSelection = applyAgentSelection(
32927
32977
  {
@@ -33060,6 +33110,7 @@ async function automationEditCommand(id, options) {
33060
33110
  }
33061
33111
  const replacingTriggers = Boolean(options.triggerCron || options.triggerGithub || options.triggerGitlab);
33062
33112
  if (replacingTriggers && options.triggerGithubExcludeUsers !== void 0 && !options.triggerGithub) throw new Error("--trigger-github-exclude-users requires --trigger-github when replacing triggers");
33113
+ validateGithubReviewersOption(options);
33063
33114
  if (replacingTriggers && options.triggerGitlabExcludeUsers !== void 0 && !options.triggerGitlab) throw new Error("--trigger-gitlab-exclude-users requires --trigger-gitlab when replacing triggers");
33064
33115
  const parsedAgent = {
33065
33116
  agent_provider: parseAgentProviderOption(options.agentProvider),
@@ -33149,8 +33200,8 @@ async function automationEditCommand(id, options) {
33149
33200
  const triggers = buildTriggersFromOptions(options, runAt, repositories);
33150
33201
  body.triggers = triggers;
33151
33202
  } else if (options.triggerGithubExcludeUsers !== void 0 || options.triggerGitlabExcludeUsers !== void 0) {
33152
- const githubExcludedActors = parseExcludedActorsOption(options.triggerGithubExcludeUsers);
33153
- const gitlabExcludedActors = parseExcludedActorsOption(options.triggerGitlabExcludeUsers);
33203
+ const githubExcludedActors = parseActorListOption(options.triggerGithubExcludeUsers);
33204
+ const gitlabExcludedActors = parseActorListOption(options.triggerGitlabExcludeUsers);
33154
33205
  let matchedGithub = options.triggerGithubExcludeUsers === void 0;
33155
33206
  let matchedGitlab = options.triggerGitlabExcludeUsers === void 0;
33156
33207
  body.triggers = existing.automation.triggers.map((trigger) => {
@@ -34026,8 +34077,8 @@ credentials.command("remove <service>").description("Remove stored credentials f
34026
34077
  var automation = program.command("automation").alias("auto").description("Manage automations");
34027
34078
  automation.command("list").description("List all automations").option("-p, --page <page>", "Page number").option("-l, --limit <limit>", "Number of items per page").option("--owner <owner>", "Ownership filter: org, user, all").option("--trigger-type <type>", "Only automations with a trigger of this type (cron, github, gitlab, slack, sentry, custom)").option("--enabled <enabled>", "Only enabled or disabled automations (true/false)").option("--search <search>", "Case-insensitive substring match on the name").option("--background <background>", "Only background (true) or main-list (false) automations").action(run(automationListCommand));
34028
34079
  automation.command("get <id>").description("Get automation details by ID").action(run(automationGetCommand));
34029
- 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("--trigger-github-exclude-users <users>", "Comma-separated GitHub usernames to exclude from triggering (pass empty string to clear the list)").option("--trigger-gitlab <event>", 'GitLab event (e.g. "merge_request.opened")').option("--trigger-gitlab-repos <repos>", "Comma-separated repo names to filter GitLab trigger").option("--trigger-gitlab-exclude-users <users>", "Comma-separated GitLab usernames to exclude from triggering (pass empty string to clear the list)").option("--github-checks <names>", "Comma-separated GitHub check names to create on matching PRs (requires a PR opened/updated trigger)").option("--lifecycle <policy>", "Workspace lifecycle: archive_when_done, sleep_when_done, default").option("--sleep-when-done", "Sleep automation workspaces as soon as the agent finishes").option("--auto-stop-minutes <minutes>", "Inactivity timeout in minutes (3-1440, requires --lifecycle default)").option("--pr-followups", "Allow follow-up actions on matching PRs").option("--agent-provider <provider>", 'Coding agent to use: claude, codex, cursor (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, xhigh, max (or "none" to clear)').option("--plan-mode", "Run automation messages in plan mode").option("--goal-mode", "Set automation messages as goals").option("--fast-mode", "Run automation messages in fast mode").option("--personal", "Create a personal automation owned by the authenticated user").option("--in <duration>", "Run once after this long, e.g. 30m, 2h, 3d, 1w (inside a workspace, defaults --workspace to current)").option("--at <datetime>", "Run once at this ISO-8601 time with timezone, e.g. 2026-10-08T09:00:00-07:00").option("--max-runs <n>", 'Delete the automation after this many runs ("none" for unlimited)').option("--workspace <target>", "Where runs go: new (default, new workspace each run), reuse (one workspace created on the first run), current (this workspace), or a workspace ID").option("--background", "Keep it out of the main automations list (for offhand follow-ups)").option("--disabled", "Create in disabled state").action(run((name, options) => automationCreateCommand(name, { ...options, enabled: !options.disabled })));
34030
- automation.command("edit <id>").description("Edit an existing automation").option("-n, --name <name>", "New name").option("-p, --prompt <prompt>", "New prompt").option("--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("--trigger-github-exclude-users <users>", "Comma-separated GitHub usernames to exclude from triggering (pass empty string to clear the list)").option("--trigger-gitlab <event>", "Set GitLab event (replaces existing triggers)").option("--trigger-gitlab-repos <repos>", "Comma-separated repo names to filter GitLab trigger").option("--trigger-gitlab-exclude-users <users>", "Comma-separated GitLab usernames to exclude from triggering (pass empty string to clear the list)").option("--github-checks <names>", "Comma-separated GitHub check names to create on matching PRs (replaces the current list; pass empty string to remove them)").option("--add-github-checks <names>", "Comma-separated GitHub check names to add, keeping the ones already configured").option("--environment <environment>", "Environment name or ID").option("--lifecycle <policy>", "Workspace lifecycle: archive_when_done, sleep_when_done, default").option("--sleep-when-done", "Sleep automation workspaces as soon as the agent finishes").option("--auto-stop-minutes <minutes>", "Inactivity timeout in minutes (3-1440, requires --lifecycle default)").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 (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, xhigh, 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 goals (true/false)", parseBooleanOption).option("--fast-mode <enabled>", "Run automation messages in fast mode (true/false)", parseBooleanOption).option("--in <duration>", "Replace triggers with a one-time run after this long, e.g. 30m, 2h, 3d, 1w").option("--at <datetime>", "Replace triggers with a one-time run at this ISO-8601 time with timezone").option("--max-runs <n>", 'Delete the automation after this many runs in total ("none" for unlimited)').option("--workspace <target>", "Where runs go: new, reuse, current, or a workspace ID").option("--background <enabled>", "Keep it out of the main automations list (true/false)", parseBooleanOption).action(run(automationEditCommand));
34080
+ 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("--trigger-github-exclude-users <users>", "Comma-separated GitHub usernames to exclude from triggering (pass empty string to clear the list)").option("--trigger-github-reviewers <users>", "Comma-separated GitHub usernames to fire for (required with pull_request.review_requested)").option("--trigger-gitlab <event>", 'GitLab event (e.g. "merge_request.opened")').option("--trigger-gitlab-repos <repos>", "Comma-separated repo names to filter GitLab trigger").option("--trigger-gitlab-exclude-users <users>", "Comma-separated GitLab usernames to exclude from triggering (pass empty string to clear the list)").option("--github-checks <names>", "Comma-separated GitHub check names to create on matching PRs (requires a PR opened/updated trigger)").option("--lifecycle <policy>", "Workspace lifecycle: archive_when_done, sleep_when_done, default").option("--sleep-when-done", "Sleep automation workspaces as soon as the agent finishes").option("--auto-stop-minutes <minutes>", "Inactivity timeout in minutes (3-1440, requires --lifecycle default)").option("--pr-followups", "Allow follow-up actions on matching PRs").option("--agent-provider <provider>", 'Coding agent to use: claude, codex, cursor (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, xhigh, max (or "none" to clear)').option("--plan-mode", "Run automation messages in plan mode").option("--goal-mode", "Set automation messages as goals").option("--fast-mode", "Run automation messages in fast mode").option("--personal", "Create a personal automation owned by the authenticated user").option("--in <duration>", "Run once after this long, e.g. 30m, 2h, 3d, 1w (inside a workspace, defaults --workspace to current)").option("--at <datetime>", "Run once at this ISO-8601 time with timezone, e.g. 2026-10-08T09:00:00-07:00").option("--max-runs <n>", 'Delete the automation after this many runs ("none" for unlimited)').option("--workspace <target>", "Where runs go: new (default, new workspace each run), reuse (one workspace created on the first run), current (this workspace), or a workspace ID").option("--background", "Keep it out of the main automations list (for offhand follow-ups)").option("--disabled", "Create in disabled state").action(run((name, options) => automationCreateCommand(name, { ...options, enabled: !options.disabled })));
34081
+ automation.command("edit <id>").description("Edit an existing automation").option("-n, --name <name>", "New name").option("-p, --prompt <prompt>", "New prompt").option("--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("--trigger-github-exclude-users <users>", "Comma-separated GitHub usernames to exclude from triggering (pass empty string to clear the list)").option("--trigger-github-reviewers <users>", "Comma-separated GitHub usernames to fire for (required with pull_request.review_requested)").option("--trigger-gitlab <event>", "Set GitLab event (replaces existing triggers)").option("--trigger-gitlab-repos <repos>", "Comma-separated repo names to filter GitLab trigger").option("--trigger-gitlab-exclude-users <users>", "Comma-separated GitLab usernames to exclude from triggering (pass empty string to clear the list)").option("--github-checks <names>", "Comma-separated GitHub check names to create on matching PRs (replaces the current list; pass empty string to remove them)").option("--add-github-checks <names>", "Comma-separated GitHub check names to add, keeping the ones already configured").option("--environment <environment>", "Environment name or ID").option("--lifecycle <policy>", "Workspace lifecycle: archive_when_done, sleep_when_done, default").option("--sleep-when-done", "Sleep automation workspaces as soon as the agent finishes").option("--auto-stop-minutes <minutes>", "Inactivity timeout in minutes (3-1440, requires --lifecycle default)").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 (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, xhigh, 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 goals (true/false)", parseBooleanOption).option("--fast-mode <enabled>", "Run automation messages in fast mode (true/false)", parseBooleanOption).option("--in <duration>", "Replace triggers with a one-time run after this long, e.g. 30m, 2h, 3d, 1w").option("--at <datetime>", "Replace triggers with a one-time run at this ISO-8601 time with timezone").option("--max-runs <n>", 'Delete the automation after this many runs in total ("none" for unlimited)').option("--workspace <target>", "Where runs go: new, reuse, current, or a workspace ID").option("--background <enabled>", "Keep it out of the main automations list (true/false)", parseBooleanOption).action(run(automationEditCommand));
34031
34082
  automation.command("run <id>").description("Manually trigger an automation (cron-triggered automations only)").action(run(automationRunCommand));
34032
34083
  automation.command("delete <id>").description("Delete an automation").option("-f, --force", "Skip confirmation prompt").action(run(automationDeleteCommand));
34033
34084
  automation.command("check <checkRunId>").description("Report this automation run's verdict on one of its GitHub checks").requiredOption("--token <token>", "Ownership token for this check, exactly as given in the prompt").requiredOption("--conclusion <conclusion>", "success or failure").requiredOption("--title <title>", "One-line verdict shown on the check").option("--summary <summary>", "What was checked and why it passed or failed").action(run(automationCheckCommand));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "replicas-cli",
3
- "version": "0.3.2",
3
+ "version": "0.3.3",
4
4
  "description": "CLI for managing Replicas workspaces - SSH into cloud dev environments with automatic port forwarding",
5
5
  "main": "dist/index.cjs",
6
6
  "bin": {