replicas-cli 0.2.776 → 0.2.778
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/dist/index.cjs +234 -49
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -7362,7 +7362,7 @@ var require_dist = __commonJS({
|
|
|
7362
7362
|
});
|
|
7363
7363
|
|
|
7364
7364
|
// src/index.ts
|
|
7365
|
-
var
|
|
7365
|
+
var import_config24 = require("dotenv/config");
|
|
7366
7366
|
var import_node_child_process3 = require("child_process");
|
|
7367
7367
|
var import_commander = require("commander");
|
|
7368
7368
|
var import_chalk25 = __toESM(require("chalk"));
|
|
@@ -23535,6 +23535,48 @@ function skillNamesFromCommand(command) {
|
|
|
23535
23535
|
})));
|
|
23536
23536
|
}
|
|
23537
23537
|
|
|
23538
|
+
// ../shared/src/uuid.ts
|
|
23539
|
+
var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
23540
|
+
|
|
23541
|
+
// ../shared/src/automations/trigger-schemas.ts
|
|
23542
|
+
var repositoryTriggerConfigSchema = external_exports.object({
|
|
23543
|
+
event: external_exports.string(),
|
|
23544
|
+
repository_ids: external_exports.array(external_exports.string().regex(UUID_RE, "must be a repository id")).optional(),
|
|
23545
|
+
group_pr_events: external_exports.boolean().optional(),
|
|
23546
|
+
excluded_actors: external_exports.array(external_exports.string()).optional()
|
|
23547
|
+
});
|
|
23548
|
+
var cronTriggerSchema = external_exports.object({ type: external_exports.literal("cron"), config: external_exports.object({ schedule: external_exports.string(), timezone: external_exports.string().optional() }) });
|
|
23549
|
+
var githubTriggerSchema = external_exports.object({ type: external_exports.literal("github"), config: repositoryTriggerConfigSchema });
|
|
23550
|
+
var gitlabTriggerSchema = external_exports.object({ type: external_exports.literal("gitlab"), config: repositoryTriggerConfigSchema });
|
|
23551
|
+
var automationTriggerSchema = external_exports.discriminatedUnion("type", [
|
|
23552
|
+
cronTriggerSchema,
|
|
23553
|
+
githubTriggerSchema,
|
|
23554
|
+
gitlabTriggerSchema,
|
|
23555
|
+
external_exports.object({ type: external_exports.literal("slack"), config: external_exports.object({ event: external_exports.string(), channel_ids: external_exports.array(external_exports.string()).optional(), group_thread_replies: external_exports.boolean().optional() }) }),
|
|
23556
|
+
external_exports.object({ type: external_exports.literal("sentry"), config: external_exports.object({ event: external_exports.string(), project_slugs: external_exports.array(external_exports.string()).optional(), min_level: external_exports.string().optional() }) }),
|
|
23557
|
+
external_exports.object({ type: external_exports.literal("custom"), config: external_exports.object({}) })
|
|
23558
|
+
]);
|
|
23559
|
+
|
|
23560
|
+
// ../shared/src/replicas-mcp.ts
|
|
23561
|
+
var REPLICAS_MCP_SERVER_NAME = "replicas-mcp";
|
|
23562
|
+
var REPLICAS_MCP_TOOLS = {
|
|
23563
|
+
listEnvironments: "list_environments",
|
|
23564
|
+
createAutomation: "create_automation",
|
|
23565
|
+
spawn: "spawn_workspace",
|
|
23566
|
+
relay: "relay_to_workspace",
|
|
23567
|
+
linearStart: "start_linear_session",
|
|
23568
|
+
linearSessionIntent: "register_linear_session_intent"
|
|
23569
|
+
};
|
|
23570
|
+
var automationToolInputSchema = external_exports.object({
|
|
23571
|
+
name: external_exports.string().describe("Short automation name."),
|
|
23572
|
+
prompt: external_exports.string().describe("Prompt each automation run starts with."),
|
|
23573
|
+
environment_id: external_exports.string().describe(`Environment id from \`${REPLICAS_MCP_TOOLS.listEnvironments}\`.`),
|
|
23574
|
+
triggers: external_exports.array(automationTriggerSchema).min(1).describe(
|
|
23575
|
+
'One or more triggers. Cron: `{ "type": "cron", "config": { "schedule": "0 9 * * 1", "timezone": "America/New_York" } }`. GitHub: `{ "type": "github", "config": { "event": "pull_request.opened", "repository_ids": ["<repository uuid>"] } }`.'
|
|
23576
|
+
),
|
|
23577
|
+
description: external_exports.string().optional().describe("One-line summary shown in the dashboard.")
|
|
23578
|
+
});
|
|
23579
|
+
|
|
23538
23580
|
// ../shared/src/default-skills/replicas-agent/abilities/computer.ts
|
|
23539
23581
|
var SECTION = `### Computer use (Linux desktop control)
|
|
23540
23582
|
Drive the workspace's Linux desktop - open a browser, click, type, scroll, screenshot, record - via the \`replicas computer\` CLI. Every Replicas workspace boots with a live H.264 and Opus stream published as an authenticated preview, so a \`Desktop\` tab is always available in the dashboard. Use \`replicas computer info\` to get the viewer URL when you want to share it (e.g. point a user on Slack at the live stream).
|
|
@@ -23804,9 +23846,6 @@ var DOCKER_ABILITY = {
|
|
|
23804
23846
|
referenceFile: { name: "DOCKER.md", content: REFERENCE2 }
|
|
23805
23847
|
};
|
|
23806
23848
|
|
|
23807
|
-
// ../shared/src/uuid.ts
|
|
23808
|
-
var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
23809
|
-
|
|
23810
23849
|
// ../shared/src/routes/environment-setups.ts
|
|
23811
23850
|
var ENVIRONMENT_SETUP_STEPS = [
|
|
23812
23851
|
{ key: "understand", label: "Understand the codebase" },
|
|
@@ -23856,17 +23895,7 @@ var ENVIRONMENT_SETUP_AUTHORED_TRIGGER_TYPES = ["cron", "github", "gitlab"];
|
|
|
23856
23895
|
function isEnvironmentSetupAuthoredTriggerType(type) {
|
|
23857
23896
|
return ENVIRONMENT_SETUP_AUTHORED_TRIGGER_TYPES.some((authored) => authored === type);
|
|
23858
23897
|
}
|
|
23859
|
-
var
|
|
23860
|
-
event: external_exports.string(),
|
|
23861
|
-
repository_ids: external_exports.array(external_exports.string().regex(UUID_RE, "must be a repository id")).optional(),
|
|
23862
|
-
group_pr_events: external_exports.boolean().optional(),
|
|
23863
|
-
excluded_actors: external_exports.array(external_exports.string()).optional()
|
|
23864
|
-
});
|
|
23865
|
-
var proposalTriggerSchema = external_exports.discriminatedUnion("type", [
|
|
23866
|
-
external_exports.object({ type: external_exports.literal("cron"), config: external_exports.object({ schedule: external_exports.string(), timezone: external_exports.string().optional() }) }),
|
|
23867
|
-
external_exports.object({ type: external_exports.literal("github"), config: repositoryTriggerConfigSchema }),
|
|
23868
|
-
external_exports.object({ type: external_exports.literal("gitlab"), config: repositoryTriggerConfigSchema })
|
|
23869
|
-
]);
|
|
23898
|
+
var proposalTriggerSchema = external_exports.discriminatedUnion("type", [cronTriggerSchema, githubTriggerSchema, gitlabTriggerSchema]);
|
|
23870
23899
|
var existingTriggerSchema = external_exports.custom(
|
|
23871
23900
|
(value) => isRecord(value) && typeof value.type === "string" && isRecord(value.config),
|
|
23872
23901
|
"must be an automation trigger"
|
|
@@ -25188,6 +25217,7 @@ Take action *with* Replicas itself \u2014 manage automations, environments (vari
|
|
|
25188
25217
|
|
|
25189
25218
|
Use this when:
|
|
25190
25219
|
- The user asks you to create, edit, run, or delete an automation
|
|
25220
|
+
- The user asks you to come back to something later ("check back on this in a week", "remind me tomorrow", "tell me when CI is green") \u2014 schedule a follow-up (see *Follow-ups and reminders*)
|
|
25191
25221
|
- The user asks you to manage environments, environment variables, or environment files
|
|
25192
25222
|
- The user asks "what envs / repos / automations do I have?"
|
|
25193
25223
|
- The user asks you to scaffold a \`replicas.json\` / \`replicas.yaml\` in a repo
|
|
@@ -25248,6 +25278,7 @@ In agent mode the CLI hides commands that don't make sense for in-workspace agen
|
|
|
25248
25278
|
| "Create a new env for my \`acme/web\` repo" | \`replicas environment create <name> -r acme/web\` |
|
|
25249
25279
|
| "What automations do I have?" | \`replicas automation list\` |
|
|
25250
25280
|
| "Run my nightly automation now" | \`replicas automation run <id>\` |
|
|
25281
|
+
| "Check back on this in a week" | \`replicas automation create ... --in 1w --background --personal\` |
|
|
25251
25282
|
| "Make an automation that runs every weekday at 9am" | \`replicas automation create\` (interactive) or \`--trigger-cron "0 9 * * 1-5"\` |
|
|
25252
25283
|
| "Make an automation that runs when a PR opens on \`acme/web\`" | \`replicas automation create ... --trigger-github pull_request.opened --trigger-github-repos acme/web\` |
|
|
25253
25284
|
| "Make an automation that runs when an MR opens on \`acme/web\`" | \`replicas automation create ... --trigger-gitlab merge_request.opened --trigger-gitlab-repos acme/web\` |
|
|
@@ -25359,6 +25390,26 @@ replicas automation create ... --lifecycle default --auto-stop-minutes 30
|
|
|
25359
25390
|
|
|
25360
25391
|
When the user says "make me an automation that...", default to **picking the environment for them by listing the available envs** and asking only when the user hasn't already pinned one. Same for repos in GitHub triggers. Don't pepper the user with questions you can answer by reading the existing config.
|
|
25361
25392
|
|
|
25393
|
+
### Follow-ups and reminders
|
|
25394
|
+
|
|
25395
|
+
You cannot wait days yourself. When the user asks you to come back to something later, schedule a one-time automation that delivers a prompt back into **this workspace's conversation** at that time, then deletes itself:
|
|
25396
|
+
|
|
25397
|
+
\`\`\`bash
|
|
25398
|
+
replicas automation create "Re-check PR #142 CI" \\
|
|
25399
|
+
--in 1w \\
|
|
25400
|
+
--background --personal \\
|
|
25401
|
+
--prompt "A week ago the user asked me to re-check CI on https://github.com/acme/web/pull/142 (flaky e2e job 'checkout'). Check the latest run, fix it if it is still failing, and summarize the result for the user."
|
|
25402
|
+
\`\`\`
|
|
25403
|
+
|
|
25404
|
+
- \`--in <duration>\` (\`30m\`, \`2h\`, \`3d\`, \`1w\`, \`1d12h\`) or \`--at <ISO-8601 with offset>\` (e.g. "tomorrow at 9am" \u2192 \`--at 2026-10-08T09:00:00-07:00\`, using the user's timezone if you know it; otherwise say which timezone you assumed).
|
|
25405
|
+
- Inside a workspace, one-time follow-ups default to \`--workspace current\`, so you resume with this conversation's context. Inside a workspace, \`--environment\` defaults to this workspace's environment (same repositories), including for \`--workspace new\` and \`reuse\`.
|
|
25406
|
+
- Write \`--prompt\` as instructions to your future self: the links, what to check, what "done" looks like, and how to report back (e.g. reply in the original Slack thread). It runs with no memory of why it was scheduled beyond what you write.
|
|
25407
|
+
- \`--background\` keeps offhand reminders out of the user's main automations list (they are still visible under **Background**). Omit it for things the user should see and manage, such as ongoing monitoring they asked for.
|
|
25408
|
+
- \`--personal\` makes the automation the user's own. Omit it only when the follow-up belongs to the organization.
|
|
25409
|
+
- Recurring with an end: \`--trigger-cron "0 9 * * *" --max-runs 5 --workspace current\` runs daily five times, then deletes itself. \`--workspace reuse\` creates one new workspace on the first run and sends every later run to it; \`--workspace new\` (the default for non-one-time automations) creates a fresh workspace per run.
|
|
25410
|
+
- Only schedule when the user asked for a follow-up or clearly agreed to one; not for "maybe I'll look at this later".
|
|
25411
|
+
- Confirm using the **Next Run** time the CLI prints, not your own arithmetic. Cancel with \`replicas automation delete <id> --force\`; find them with \`replicas automation list --background true\`.
|
|
25412
|
+
|
|
25362
25413
|
### Edit
|
|
25363
25414
|
|
|
25364
25415
|
\`\`\`bash
|
|
@@ -25708,6 +25759,13 @@ function removeTag(text2, tag) {
|
|
|
25708
25759
|
function removeReplicasInstructions(text2) {
|
|
25709
25760
|
return removeTag(text2, REPLICAS_INSTRUCTIONS_TAG);
|
|
25710
25761
|
}
|
|
25762
|
+
var mothershipMcpActions = `These are tools of the \`${REPLICAS_MCP_SERVER_NAME}\` MCP server; their argument names match the envelope fields. Call them directly as tools, never through a shell or the Replicas CLI.
|
|
25763
|
+
- **Spawn** a dedicated workspace for the thread and hand off: \`${REPLICAS_MCP_TOOLS.spawn}\`, with \`environment_id\` when you chose one.
|
|
25764
|
+
- **Relay** a follow-up that is clearly meant for you into the workspace already bound to the thread (pass the envelope's \`user_id\` so it's attributed to its author): \`${REPLICAS_MCP_TOOLS.relay}\`, with \`queue: true\` to queue it.
|
|
25765
|
+
- **List environments**: \`${REPLICAS_MCP_TOOLS.listEnvironments}\`.
|
|
25766
|
+
- **Create an automation**: \`${REPLICAS_MCP_TOOLS.createAutomation}\`, filling its \`confirmation_*\` arguments from the accepting message's envelope.
|
|
25767
|
+
- **Register a Linear session intent**: \`${REPLICAS_MCP_TOOLS.linearSessionIntent}\` with \`comment_id\` and \`action\`.
|
|
25768
|
+
- **Start a Linear session**: \`${REPLICAS_MCP_TOOLS.linearStart}\` with \`issue_id\`, \`agent_session_id\`, and \`prompt\`.`;
|
|
25711
25769
|
|
|
25712
25770
|
// ../shared/src/user-message-attachments.ts
|
|
25713
25771
|
var ATTACHMENT_PLACEHOLDER_REGEX = /^\[\d+ (?:(?:images?|files?)(?: and \d+ files?)? attached|(?:image )?attachments?)\]$/;
|
|
@@ -27829,6 +27887,31 @@ var SLASH_COMMANDS = [
|
|
|
27829
27887
|
}))
|
|
27830
27888
|
];
|
|
27831
27889
|
|
|
27890
|
+
// ../shared/src/terminal.ts
|
|
27891
|
+
var CONTROL_CHARACTERS = /[\u0000-\u001F\u007F-\u009F]/g;
|
|
27892
|
+
function sanitizeTerminalLine(value) {
|
|
27893
|
+
return value.replace(CONTROL_CHARACTERS, " ").trim();
|
|
27894
|
+
}
|
|
27895
|
+
|
|
27896
|
+
// ../shared/src/mothership.ts
|
|
27897
|
+
function mothershipWorkspaceLine(workspaceId, workspaceName, webAppUrl) {
|
|
27898
|
+
return `Workspace: ${sanitizeTerminalLine(workspaceName ?? "") || "Workspace"} (${getWorkspaceDashboardUrl(workspaceId, { webAppUrl })})`;
|
|
27899
|
+
}
|
|
27900
|
+
async function waitForMothershipSpawn(getThreadWorkspace, options) {
|
|
27901
|
+
for (let attempt = 0; attempt < options.attempts; attempt++) {
|
|
27902
|
+
const { workspace_id, workspace_name } = await getThreadWorkspace();
|
|
27903
|
+
if (workspace_id) return `Spawned workspace.
|
|
27904
|
+
${mothershipWorkspaceLine(workspace_id, workspace_name, options.webAppUrl)}`;
|
|
27905
|
+
await new Promise((resolve2) => setTimeout(resolve2, 1e3));
|
|
27906
|
+
}
|
|
27907
|
+
return "Workspace spawn requested. The new workspace will take over this Slack thread.";
|
|
27908
|
+
}
|
|
27909
|
+
function formatMothershipRelayResult(result, webAppUrl) {
|
|
27910
|
+
const folded = result.folded_in ? ` Folded in ${result.folded_in} earlier relay${result.folded_in === 1 ? "" : "s"} that had not started yet.` : "";
|
|
27911
|
+
return `${result.interrupted ? `Interrupted the thread's dedicated workspace and relayed the message.${folded}` : "Relayed to the thread's dedicated workspace."}
|
|
27912
|
+
${mothershipWorkspaceLine(result.workspace_id, result.workspace_name, webAppUrl)}`;
|
|
27913
|
+
}
|
|
27914
|
+
|
|
27832
27915
|
// ../shared/src/replicas-config.ts
|
|
27833
27916
|
var import_yaml = __toESM(require_dist());
|
|
27834
27917
|
|
|
@@ -27841,12 +27924,6 @@ var HOOK_EXEC_MAX_BUFFER_BYTES = 10 * 1024 * 1024;
|
|
|
27841
27924
|
// ../shared/src/replicas-config.ts
|
|
27842
27925
|
var REPLICAS_CONFIG_FILENAMES = ["replicas.json", "replicas.yaml", "replicas.yml"];
|
|
27843
27926
|
|
|
27844
|
-
// ../shared/src/terminal.ts
|
|
27845
|
-
var CONTROL_CHARACTERS = /[\u0000-\u001F\u007F-\u009F]/g;
|
|
27846
|
-
function sanitizeTerminalLine(value) {
|
|
27847
|
-
return value.replace(CONTROL_CHARACTERS, " ").trim();
|
|
27848
|
-
}
|
|
27849
|
-
|
|
27850
27927
|
// ../shared/src/subagent-mcp.ts
|
|
27851
27928
|
var SUBAGENT_MCP_TOOLS = {
|
|
27852
27929
|
getProviders: "get_providers",
|
|
@@ -27873,7 +27950,7 @@ var headlessAgentRequestSchema = external_exports.object({
|
|
|
27873
27950
|
});
|
|
27874
27951
|
|
|
27875
27952
|
// ../shared/src/cli-version.ts
|
|
27876
|
-
var CLI_VERSION = "0.2.
|
|
27953
|
+
var CLI_VERSION = "0.2.778";
|
|
27877
27954
|
|
|
27878
27955
|
// ../shared/src/version.ts
|
|
27879
27956
|
function compareVersions(v1, v2) {
|
|
@@ -27948,6 +28025,41 @@ var linearSessionMetadataSchema = external_exports.object({
|
|
|
27948
28025
|
}).optional()
|
|
27949
28026
|
});
|
|
27950
28027
|
|
|
28028
|
+
// ../shared/src/routes/mothership.ts
|
|
28029
|
+
var MOTHERSHIP_LINEAR_ACTIONS = ["ask", "start"];
|
|
28030
|
+
var mothershipLinearSessionIntentRequestSchema = external_exports.object({
|
|
28031
|
+
comment_id: external_exports.string().trim().min(1).describe("Id of the Linear comment the session will be created on."),
|
|
28032
|
+
action: external_exports.enum(MOTHERSHIP_LINEAR_ACTIONS).describe("`ask` when the comment is a clarifying question, `start` when it is the complete task prompt.")
|
|
28033
|
+
});
|
|
28034
|
+
var mothershipLinearStartRequestSchema = external_exports.object({
|
|
28035
|
+
issue_id: external_exports.string().describe("Linear issue id from the envelope's `issue_id`."),
|
|
28036
|
+
agent_session_id: external_exports.string().describe("Existing Linear agent session id from the envelope's `agent_session_id`."),
|
|
28037
|
+
prompt: external_exports.string().trim().min(1).describe("Complete task prompt for the coding workspace.")
|
|
28038
|
+
});
|
|
28039
|
+
var slackChannelIdSchema = external_exports.string().describe("Slack channel id from the envelope's `channel_id`.");
|
|
28040
|
+
var slackThreadTsSchema = external_exports.string().describe("Slack thread timestamp from the envelope's `thread_ts`.");
|
|
28041
|
+
var mothershipSlackSpawnRequestSchema = external_exports.object({
|
|
28042
|
+
channel_id: slackChannelIdSchema,
|
|
28043
|
+
thread_ts: slackThreadTsSchema,
|
|
28044
|
+
message_ts: external_exports.string().describe("Timestamp of the Slack message that asked for the work (the envelope's `message_ts`). The server verifies this message and its author."),
|
|
28045
|
+
user_id: external_exports.string().describe("Slack user id of that message's author (the envelope's `user_id`). The workspace is attributed to them."),
|
|
28046
|
+
prompt: external_exports.string().describe("Complete task for the new workspace, written so it stands on its own."),
|
|
28047
|
+
environment_id: external_exports.string().optional().describe(`Environment id from \`${REPLICAS_MCP_TOOLS.listEnvironments}\`. Pass it only when clearly confident it fits; omit it to let routing choose or ask the person.`)
|
|
28048
|
+
});
|
|
28049
|
+
var mothershipSlackRelayRequestSchema = external_exports.object({
|
|
28050
|
+
channel_id: slackChannelIdSchema,
|
|
28051
|
+
thread_ts: slackThreadTsSchema,
|
|
28052
|
+
message: external_exports.string().describe("The follow-up to deliver, combining every fresh message that belongs to this update."),
|
|
28053
|
+
user_id: external_exports.string().optional().describe("Slack user id of the follow-up's author (the envelope's `user_id`), so it is attributed to them. Defaults to the thread's original requester."),
|
|
28054
|
+
queue: external_exports.boolean().optional().describe("Set true only when the person explicitly asked for this to happen after the current task finishes. Delivers behind the active turn instead of interrupting it.")
|
|
28055
|
+
});
|
|
28056
|
+
var mothershipAutomationToolInputSchema = automationToolInputSchema.extend({
|
|
28057
|
+
confirmation_channel_id: external_exports.string().describe("`channel_id` from the envelope of the Slack message that accepted the offer."),
|
|
28058
|
+
confirmation_thread_ts: external_exports.string().describe("`thread_ts` from that message's envelope."),
|
|
28059
|
+
confirmation_message_ts: external_exports.string().describe("`message_ts` from that message's envelope."),
|
|
28060
|
+
confirmation_user_id: external_exports.string().describe("`user_id` from that message's envelope.")
|
|
28061
|
+
});
|
|
28062
|
+
|
|
27951
28063
|
// ../shared/src/routes/plugin-catalog.ts
|
|
27952
28064
|
var EXPLICIT_PLUGIN_CATALOG = [
|
|
27953
28065
|
{
|
|
@@ -31175,6 +31287,56 @@ function parseExcludedActorsOption(value) {
|
|
|
31175
31287
|
const actors = value.split(",").map((actor) => actor.trim()).filter(Boolean);
|
|
31176
31288
|
return actors.length > 0 ? actors : void 0;
|
|
31177
31289
|
}
|
|
31290
|
+
var DURATION_UNIT_MS = { m: 6e4, h: 36e5, d: 864e5, w: 6048e5 };
|
|
31291
|
+
function parseDuration(value) {
|
|
31292
|
+
const parts = [...value.trim().toLowerCase().matchAll(/(\d+)\s*([mhdw])/g)];
|
|
31293
|
+
if (parts.length === 0 || parts.map((p) => p[0]).join("") !== value.trim().toLowerCase().replace(/\s+/g, "")) return null;
|
|
31294
|
+
return parts.reduce((total, [, amount, unit]) => total + Number(amount) * DURATION_UNIT_MS[unit], 0);
|
|
31295
|
+
}
|
|
31296
|
+
function resolveRunAt(options, now = Date.now()) {
|
|
31297
|
+
if (options.in && options.at) throw new Error("Use either --in or --at, not both");
|
|
31298
|
+
if (options.in) {
|
|
31299
|
+
const ms = parseDuration(options.in);
|
|
31300
|
+
if (!ms) throw new Error(`Invalid --in duration: ${options.in} (examples: 30m, 2h, 3d, 1w, 1d12h)`);
|
|
31301
|
+
return new Date(now + ms).toISOString();
|
|
31302
|
+
}
|
|
31303
|
+
if (options.at) {
|
|
31304
|
+
const at = new Date(options.at);
|
|
31305
|
+
if (Number.isNaN(at.getTime()) || !/(?:Z|[+-]\d\d:?\d\d)$/i.test(options.at.trim())) {
|
|
31306
|
+
throw new Error(`Invalid --at: ${options.at} (use ISO-8601 with a timezone, e.g. 2026-10-08T09:00:00-07:00)`);
|
|
31307
|
+
}
|
|
31308
|
+
return at.toISOString();
|
|
31309
|
+
}
|
|
31310
|
+
return void 0;
|
|
31311
|
+
}
|
|
31312
|
+
function parseWorkspaceTarget(value) {
|
|
31313
|
+
if (value === void 0) return void 0;
|
|
31314
|
+
if (value === "new") return { reuse_workspace: false, target_workspace_id: null };
|
|
31315
|
+
if (value === "reuse") return { reuse_workspace: true, target_workspace_id: null };
|
|
31316
|
+
if (value === "current") {
|
|
31317
|
+
const workspaceId = readAgentConfig()?.workspace_id;
|
|
31318
|
+
if (!workspaceId) throw new Error("--workspace current only works inside a Replicas workspace");
|
|
31319
|
+
return { reuse_workspace: true, target_workspace_id: workspaceId };
|
|
31320
|
+
}
|
|
31321
|
+
return { reuse_workspace: true, target_workspace_id: value };
|
|
31322
|
+
}
|
|
31323
|
+
function parseMaxRuns(value) {
|
|
31324
|
+
if (value === void 0) return void 0;
|
|
31325
|
+
if (["none", "unlimited"].includes(value.trim().toLowerCase())) return null;
|
|
31326
|
+
const runs = Number(value);
|
|
31327
|
+
if (!Number.isSafeInteger(runs) || runs < 1) throw new Error('--max-runs must be a positive integer or "none"');
|
|
31328
|
+
return runs;
|
|
31329
|
+
}
|
|
31330
|
+
function localTimezone() {
|
|
31331
|
+
return Intl.DateTimeFormat().resolvedOptions().timeZone || "UTC";
|
|
31332
|
+
}
|
|
31333
|
+
function formatDestination(automation2) {
|
|
31334
|
+
if (!automation2.reuse_workspace) return "new workspace each run";
|
|
31335
|
+
return automation2.target_workspace_id ? `workspace ${automation2.target_workspace_id}` : "one workspace, created on the first run";
|
|
31336
|
+
}
|
|
31337
|
+
function formatRuns(automation2) {
|
|
31338
|
+
return automation2.max_runs === null ? `${automation2.run_count} (unlimited)` : `${automation2.run_count} of ${automation2.max_runs} (deletes itself after the last run)`;
|
|
31339
|
+
}
|
|
31178
31340
|
function withExcludedActors(config3, excludedActors) {
|
|
31179
31341
|
const next = { ...config3 };
|
|
31180
31342
|
if (excludedActors?.length) {
|
|
@@ -31207,6 +31369,7 @@ function applyAgentSelection(body, existing) {
|
|
|
31207
31369
|
function formatTrigger(trigger) {
|
|
31208
31370
|
if (trigger.type === "cron") {
|
|
31209
31371
|
const config3 = trigger.config;
|
|
31372
|
+
if (config3.run_at) return `once: ${formatDate2(config3.run_at)}`;
|
|
31210
31373
|
const tz = config3.timezone ? ` (${config3.timezone})` : "";
|
|
31211
31374
|
return `cron: ${config3.schedule}${tz}`;
|
|
31212
31375
|
}
|
|
@@ -31295,6 +31458,9 @@ function printAutomation(automation2) {
|
|
|
31295
31458
|
if (automation2.cron_next_fire_at) {
|
|
31296
31459
|
console.log(import_chalk20.default.gray(` Next Run: ${formatDate2(automation2.cron_next_fire_at)}`));
|
|
31297
31460
|
}
|
|
31461
|
+
console.log(import_chalk20.default.gray(` Runs: ${formatRuns(automation2)}`));
|
|
31462
|
+
console.log(import_chalk20.default.gray(` Workspace: ${formatDestination(automation2)}`));
|
|
31463
|
+
if (automation2.background) console.log(import_chalk20.default.gray(" List: background"));
|
|
31298
31464
|
if (automation2.workspace_lifecycle_policy && automation2.workspace_lifecycle_policy !== "default") {
|
|
31299
31465
|
console.log(import_chalk20.default.gray(` Lifecycle: ${automation2.workspace_lifecycle_policy}`));
|
|
31300
31466
|
}
|
|
@@ -31320,6 +31486,7 @@ async function automationListCommand(options) {
|
|
|
31320
31486
|
if (options.triggerType) params.set("trigger_type", options.triggerType);
|
|
31321
31487
|
if (options.enabled) params.set("enabled", options.enabled);
|
|
31322
31488
|
if (options.search) params.set("search", options.search);
|
|
31489
|
+
if (options.background) params.set("background", options.background);
|
|
31323
31490
|
const query = params.toString();
|
|
31324
31491
|
const response = await orgAuthenticatedFetch(
|
|
31325
31492
|
`/v1/automations${query ? "?" + query : ""}`
|
|
@@ -31372,6 +31539,9 @@ Automation: ${automation2.name}
|
|
|
31372
31539
|
if (automation2.cron_next_fire_at) {
|
|
31373
31540
|
console.log(import_chalk20.default.gray(` Next Run: ${formatDate2(automation2.cron_next_fire_at)}`));
|
|
31374
31541
|
}
|
|
31542
|
+
console.log(import_chalk20.default.gray(` Runs: ${formatRuns(automation2)}`));
|
|
31543
|
+
console.log(import_chalk20.default.gray(` Workspace: ${formatDestination(automation2)}`));
|
|
31544
|
+
console.log(import_chalk20.default.gray(` List: ${automation2.background ? "background" : "main"}`));
|
|
31375
31545
|
if (automation2.workspace_lifecycle_policy) {
|
|
31376
31546
|
console.log(import_chalk20.default.gray(` Lifecycle Policy: ${automation2.workspace_lifecycle_policy}`));
|
|
31377
31547
|
}
|
|
@@ -31510,6 +31680,10 @@ async function promptForTriggers(repositories) {
|
|
|
31510
31680
|
}
|
|
31511
31681
|
async function automationCreateCommand(name, options) {
|
|
31512
31682
|
ensureOrgApiAuthenticated();
|
|
31683
|
+
const runAt = resolveRunAt(options);
|
|
31684
|
+
if (runAt && options.triggerCron) throw new Error("--in/--at cannot be combined with --trigger-cron");
|
|
31685
|
+
const maxRuns = parseMaxRuns(options.maxRuns);
|
|
31686
|
+
const workspaceTarget = parseWorkspaceTarget(options.workspace ?? (runAt && readAgentConfig() ? "current" : void 0));
|
|
31513
31687
|
const lifecyclePolicy = parseAutomationLifecycleOptions(options);
|
|
31514
31688
|
if (options.autoStopMinutes && !lifecyclePolicySupportsAutoStop(lifecyclePolicy ?? "default")) {
|
|
31515
31689
|
console.log(import_chalk20.default.red("--auto-stop-minutes requires --lifecycle default"));
|
|
@@ -31553,7 +31727,8 @@ async function automationCreateCommand(name, options) {
|
|
|
31553
31727
|
`/v1/environments?scope=${options.personal ? "all" : "org"}`
|
|
31554
31728
|
);
|
|
31555
31729
|
const selectableEnvs = envResponse.environments;
|
|
31556
|
-
|
|
31730
|
+
const environmentFromTarget = !options.environment && (!!workspaceTarget?.target_workspace_id || !!readAgentConfig());
|
|
31731
|
+
if (selectableEnvs.length === 0 && !environmentFromTarget) {
|
|
31557
31732
|
console.log(import_chalk20.default.red("No environments found. Please create an environment first."));
|
|
31558
31733
|
process.exit(1);
|
|
31559
31734
|
}
|
|
@@ -31588,7 +31763,9 @@ async function automationCreateCommand(name, options) {
|
|
|
31588
31763
|
automationPrompt = response2.prompt;
|
|
31589
31764
|
}
|
|
31590
31765
|
let selectedEnvironmentId;
|
|
31591
|
-
if (
|
|
31766
|
+
if (environmentFromTarget) {
|
|
31767
|
+
selectedEnvironmentId = void 0;
|
|
31768
|
+
} else if (options.environment) {
|
|
31592
31769
|
selectedEnvironmentId = resolveSelectableEnvironmentId(options.environment, selectableEnvs);
|
|
31593
31770
|
} else {
|
|
31594
31771
|
const envResponse2 = await (0, import_prompts8.default)({
|
|
@@ -31608,6 +31785,9 @@ async function automationCreateCommand(name, options) {
|
|
|
31608
31785
|
selectedEnvironmentId = envResponse2.env;
|
|
31609
31786
|
}
|
|
31610
31787
|
let triggers = [];
|
|
31788
|
+
if (runAt) {
|
|
31789
|
+
triggers.push({ type: "cron", config: { run_at: runAt, timezone: localTimezone() } });
|
|
31790
|
+
}
|
|
31611
31791
|
if (options.triggerCron) {
|
|
31612
31792
|
triggers.push({
|
|
31613
31793
|
type: "cron",
|
|
@@ -31649,7 +31829,7 @@ async function automationCreateCommand(name, options) {
|
|
|
31649
31829
|
}
|
|
31650
31830
|
}
|
|
31651
31831
|
let prFollowups = options.prFollowups === true;
|
|
31652
|
-
if (options.prFollowups === void 0) {
|
|
31832
|
+
if (options.prFollowups === void 0 && process.stdin.isTTY) {
|
|
31653
31833
|
const prFollowupsResponse = await (0, import_prompts8.default)({
|
|
31654
31834
|
type: "confirm",
|
|
31655
31835
|
name: "prFollowups",
|
|
@@ -31662,8 +31842,11 @@ async function automationCreateCommand(name, options) {
|
|
|
31662
31842
|
scope: options.personal ? "user" : "org",
|
|
31663
31843
|
name: automationName,
|
|
31664
31844
|
prompt: automationPrompt,
|
|
31665
|
-
environment_id: selectedEnvironmentId,
|
|
31845
|
+
...selectedEnvironmentId ? { environment_id: selectedEnvironmentId } : {},
|
|
31666
31846
|
triggers,
|
|
31847
|
+
...maxRuns !== void 0 ? { max_runs: maxRuns } : {},
|
|
31848
|
+
...workspaceTarget,
|
|
31849
|
+
...options.background ? { background: true } : {},
|
|
31667
31850
|
enabled: options.enabled !== false,
|
|
31668
31851
|
...options.githubChecks !== void 0 ? { github_check_names: normalizeAutomationGithubCheckNames(options.githubChecks.split(",")) } : {},
|
|
31669
31852
|
config: workspaceConfigWithPrFollowups(void 0, prFollowups),
|
|
@@ -31689,8 +31872,11 @@ Created automation: ${automation2.name}`));
|
|
|
31689
31872
|
console.log(import_chalk20.default.gray(` Triggers: ${automation2.triggers.map(formatTrigger).join(", ")}`));
|
|
31690
31873
|
}
|
|
31691
31874
|
if (automation2.cron_next_fire_at) {
|
|
31692
|
-
console.log(import_chalk20.default.gray(` Next Run: ${formatDate2(automation2.cron_next_fire_at)}`));
|
|
31875
|
+
console.log(import_chalk20.default.gray(` Next Run: ${formatDate2(automation2.cron_next_fire_at)} (${automation2.cron_next_fire_at})`));
|
|
31693
31876
|
}
|
|
31877
|
+
console.log(import_chalk20.default.gray(` Runs: ${formatRuns(automation2)}`));
|
|
31878
|
+
console.log(import_chalk20.default.gray(` Workspace: ${formatDestination(automation2)}`));
|
|
31879
|
+
console.log(import_chalk20.default.gray(` List: ${automation2.background ? "background" : "main"}`));
|
|
31694
31880
|
console.log();
|
|
31695
31881
|
} catch (error51) {
|
|
31696
31882
|
console.error(import_chalk20.default.red(`Error: ${error51 instanceof Error ? error51.message : "Unknown error"}`));
|
|
@@ -31699,6 +31885,10 @@ Created automation: ${automation2.name}`));
|
|
|
31699
31885
|
}
|
|
31700
31886
|
async function automationEditCommand(id, options) {
|
|
31701
31887
|
ensureOrgApiAuthenticated();
|
|
31888
|
+
const runAt = resolveRunAt(options);
|
|
31889
|
+
if (runAt && options.triggerCron) throw new Error("--in/--at cannot be combined with --trigger-cron");
|
|
31890
|
+
const maxRuns = parseMaxRuns(options.maxRuns);
|
|
31891
|
+
const workspaceTarget = parseWorkspaceTarget(options.workspace);
|
|
31702
31892
|
const lifecyclePolicy = parseAutomationLifecycleOptions(options);
|
|
31703
31893
|
if (options.autoStopMinutes) {
|
|
31704
31894
|
const minutes = parseInt(options.autoStopMinutes, 10);
|
|
@@ -31733,7 +31923,7 @@ async function automationEditCommand(id, options) {
|
|
|
31733
31923
|
model: existing.automation.model
|
|
31734
31924
|
});
|
|
31735
31925
|
const body = {};
|
|
31736
|
-
const hasOptions = options.name || options.prompt || options.enabled !== void 0 || options.prFollowups !== void 0 || options.triggerCron || options.triggerGithub || options.triggerGitlab || options.environment || options.triggerGithubExcludeUsers !== void 0 || options.triggerGitlabExcludeUsers !== void 0 || options.githubChecks !== void 0 || options.addGithubChecks !== void 0 || options.lifecycle || options.sleepWhenDone || options.autoStopMinutes || options.agentProvider !== void 0 || options.model !== void 0 || options.thinkingLevel !== void 0 || options.planMode !== void 0 || options.goalMode !== void 0 || options.fastMode !== void 0;
|
|
31926
|
+
const hasOptions = options.name || options.prompt || options.enabled !== void 0 || options.prFollowups !== void 0 || options.triggerCron || options.triggerGithub || options.triggerGitlab || options.environment || options.triggerGithubExcludeUsers !== void 0 || options.triggerGitlabExcludeUsers !== void 0 || options.githubChecks !== void 0 || options.addGithubChecks !== void 0 || options.lifecycle || options.sleepWhenDone || options.autoStopMinutes || options.agentProvider !== void 0 || options.model !== void 0 || options.thinkingLevel !== void 0 || options.planMode !== void 0 || options.goalMode !== void 0 || options.fastMode !== void 0 || runAt !== void 0 || maxRuns !== void 0 || workspaceTarget !== void 0 || options.background !== void 0;
|
|
31737
31927
|
if (!hasOptions) {
|
|
31738
31928
|
const nameResponse = await (0, import_prompts8.default)({
|
|
31739
31929
|
type: "text",
|
|
@@ -31802,8 +31992,11 @@ async function automationEditCommand(id, options) {
|
|
|
31802
31992
|
...normalizeAutomationGithubCheckNames(options.addGithubChecks.split(","))
|
|
31803
31993
|
])];
|
|
31804
31994
|
}
|
|
31805
|
-
if (options.triggerCron || options.triggerGithub || options.triggerGitlab) {
|
|
31995
|
+
if (runAt || options.triggerCron || options.triggerGithub || options.triggerGitlab) {
|
|
31806
31996
|
const triggers = [];
|
|
31997
|
+
if (runAt) {
|
|
31998
|
+
triggers.push({ type: "cron", config: { run_at: runAt, timezone: localTimezone() } });
|
|
31999
|
+
}
|
|
31807
32000
|
if (options.triggerCron) {
|
|
31808
32001
|
triggers.push({
|
|
31809
32002
|
type: "cron",
|
|
@@ -31891,6 +32084,9 @@ async function automationEditCommand(id, options) {
|
|
|
31891
32084
|
if (options.planMode !== void 0) body.plan_mode = options.planMode;
|
|
31892
32085
|
if (options.goalMode !== void 0) body.goal_mode = options.goalMode;
|
|
31893
32086
|
if (options.fastMode !== void 0) body.fast_mode = options.fastMode;
|
|
32087
|
+
if (maxRuns !== void 0) body.max_runs = maxRuns;
|
|
32088
|
+
if (options.background !== void 0) body.background = options.background;
|
|
32089
|
+
Object.assign(body, workspaceTarget);
|
|
31894
32090
|
Object.assign(body, agentSelection);
|
|
31895
32091
|
}
|
|
31896
32092
|
if (Object.keys(body).length === 0) {
|
|
@@ -32560,9 +32756,6 @@ async function serviceLogsCommand(name, options) {
|
|
|
32560
32756
|
}
|
|
32561
32757
|
|
|
32562
32758
|
// src/commands/mothership.ts
|
|
32563
|
-
function workspaceNameForOutput(name) {
|
|
32564
|
-
return sanitizeTerminalLine(name ?? "") || "Workspace";
|
|
32565
|
-
}
|
|
32566
32759
|
async function mothershipMonitorChannelCommand(options) {
|
|
32567
32760
|
const channel = options.channel?.trim();
|
|
32568
32761
|
const approvalChannel = options.approvalChannel?.trim();
|
|
@@ -32608,18 +32801,12 @@ async function mothershipSpawnCommand(options) {
|
|
|
32608
32801
|
method: "POST",
|
|
32609
32802
|
body
|
|
32610
32803
|
});
|
|
32611
|
-
|
|
32612
|
-
|
|
32804
|
+
console.log(await waitForMothershipSpawn(
|
|
32805
|
+
() => agentFetch(
|
|
32613
32806
|
`/v1/agent/mothership/thread-workspace?channel_id=${encodeURIComponent(channel)}&thread_ts=${encodeURIComponent(thread)}`
|
|
32614
|
-
)
|
|
32615
|
-
|
|
32616
|
-
|
|
32617
|
-
Workspace: ${workspaceNameForOutput(result.workspace_name)} (${getWorkspaceDashboardUrl(result.workspace_id, { webAppUrl: process.env.REPLICAS_WEB_URL })})`);
|
|
32618
|
-
return;
|
|
32619
|
-
}
|
|
32620
|
-
await new Promise((resolve2) => setTimeout(resolve2, 1e3));
|
|
32621
|
-
}
|
|
32622
|
-
console.log("Workspace spawn requested. The new workspace will take over this Slack thread.");
|
|
32807
|
+
),
|
|
32808
|
+
{ attempts: 60, webAppUrl: process.env.REPLICAS_WEB_URL }
|
|
32809
|
+
));
|
|
32623
32810
|
}
|
|
32624
32811
|
async function mothershipRelayCommand(options) {
|
|
32625
32812
|
const channel = options.channel?.trim();
|
|
@@ -32640,9 +32827,7 @@ async function mothershipRelayCommand(options) {
|
|
|
32640
32827
|
method: "POST",
|
|
32641
32828
|
body
|
|
32642
32829
|
});
|
|
32643
|
-
|
|
32644
|
-
console.log(`${result.interrupted ? `Interrupted the thread's dedicated workspace and relayed the message.${folded}` : "Relayed to the thread's dedicated workspace."}
|
|
32645
|
-
Workspace: ${workspaceNameForOutput(result.workspace_name)} (${getWorkspaceDashboardUrl(result.workspace_id, { webAppUrl: process.env.REPLICAS_WEB_URL })})`);
|
|
32830
|
+
console.log(formatMothershipRelayResult(result, process.env.REPLICAS_WEB_URL));
|
|
32646
32831
|
}
|
|
32647
32832
|
|
|
32648
32833
|
// src/commands/environment.ts
|
|
@@ -33479,7 +33664,7 @@ program.command("read <id>").description("Read conversation history of a replica
|
|
|
33479
33664
|
}
|
|
33480
33665
|
});
|
|
33481
33666
|
var automation = program.command("automation").alias("auto").description("Manage automations");
|
|
33482
|
-
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").action(async (options) => {
|
|
33667
|
+
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(async (options) => {
|
|
33483
33668
|
try {
|
|
33484
33669
|
await automationListCommand(options);
|
|
33485
33670
|
} catch (error51) {
|
|
@@ -33503,7 +33688,7 @@ automation.command("get <id>").description("Get automation details by ID").actio
|
|
|
33503
33688
|
process.exit(1);
|
|
33504
33689
|
}
|
|
33505
33690
|
});
|
|
33506
|
-
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("--confirmation-channel <id>", "Slack channel containing the Mothership confirmation").option("--confirmation-thread <ts>", "Slack thread containing the Mothership confirmation").option("--confirmation-message-ts <ts>", "Slack timestamp of the Mothership confirmation").option("--confirmation-user <id>", "Slack id of the confirming user").option("--disabled", "Create in disabled state").action(async (name, options) => {
|
|
33691
|
+
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("--confirmation-channel <id>", "Slack channel containing the Mothership confirmation").option("--confirmation-thread <ts>", "Slack thread containing the Mothership confirmation").option("--confirmation-message-ts <ts>", "Slack timestamp of the Mothership confirmation").option("--confirmation-user <id>", "Slack id of the confirming 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(async (name, options) => {
|
|
33507
33692
|
try {
|
|
33508
33693
|
await automationCreateCommand(name, {
|
|
33509
33694
|
...options,
|
|
@@ -33518,7 +33703,7 @@ automation.command("create [name]").description("Create a new automation").optio
|
|
|
33518
33703
|
process.exit(1);
|
|
33519
33704
|
}
|
|
33520
33705
|
});
|
|
33521
|
-
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("--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).action(async (id, options) => {
|
|
33706
|
+
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("--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(async (id, options) => {
|
|
33522
33707
|
try {
|
|
33523
33708
|
await automationEditCommand(id, options);
|
|
33524
33709
|
} catch (error51) {
|