replicas-cli 0.2.673 → 0.2.675

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 +36 -41
  2. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -23584,7 +23584,7 @@ gh pr review 123 --request-changes --body "Changes needed"
23584
23584
 
23585
23585
  ## Media in GitHub workflows
23586
23586
 
23587
- Media delivery is owned by \`references/MEDIA.md\`. Read its GitHub section before adding screenshots, recordings, diagrams, or HTML reports to a pull request, issue, review comment, or commit; it covers the Replicas upload, GitHub's inline fallback, and the required **View in Replicas** link.
23587
+ Media delivery is owned by \`references/MEDIA.md\`. Read its GitHub section before adding screenshots, recordings, diagrams, or HTML reports to a pull request, issue, review comment, or commit; it covers public Forge embeds for images and recording previews, organization-only HTML links, and the required **View in Replicas** link.
23588
23588
  `;
23589
23589
  var GITHUB_ABILITY = {
23590
23590
  label: "GitHub",
@@ -23787,7 +23787,7 @@ Upload to Replicas in these cases \u2014 and **only** these cases:
23787
23787
 
23788
23788
  1. **Media you produce.** Any screenshot, screen recording, generated diagram, audio clip, or HTML page you create that the user might want to see. Upload before doing anything else with the file (analyzing, deleting, sending elsewhere). This applies even when you're also sending the file to Slack, Linear, GitHub, or GitLab.
23789
23789
  2. **Files the user explicitly asks you to upload.** If the user sends or points at a file (image, video, audio, HTML) and asks you to upload it, run \`replicas media upload\`. Otherwise leave it alone \u2014 files in the workspace the user did not ask about should not be auto-uploaded as media.
23790
- 3. **Anything you plan to share externally (Slack, Linear, GitHub, GitLab, etc.).** Upload to Replicas *in addition to* the platform's destination upload. Never as a replacement.
23790
+ 3. **Anything you plan to share externally (Slack, Linear, GitHub, GitLab, etc.).** Upload to Replicas first, then follow the destination's delivery path below.
23791
23791
 
23792
23792
  If none of these apply, don't upload.
23793
23793
 
@@ -23797,9 +23797,9 @@ If none of these apply, don't upload.
23797
23797
 
23798
23798
  1. First, run \`replicas media upload\` with the original file. Do not begin any destination upload until the command succeeds. This creates the canonical dashboard copy and prints a chat embed plus a per-file dashboard link. With public access, the printed Forge embed is the chat embed and is also safe to use on GitHub.
23799
23799
  2. Include the printed embed line in the Replicas chat reply, followed by the matching **View in Replicas** link. HTML uses its printed page link instead of an image embed.
23800
- 3. Identify every destination in the task and attempt to upload the same original bytes there. Use the destination's inline representation from the table below; do not replace the file with a Replicas link.
23800
+ 3. Identify every destination in the task and use its inline representation from the table below. Slack, Linear, and GitLab require an upload of the same original bytes; GitHub uses the public Forge embed.
23801
23801
  4. Put the **View in Replicas** dashboard link next to the destination embed as a secondary link.
23802
- 5. Check each destination response. If a native upload is unavailable or fails, say so explicitly and keep the dashboard link; never claim that a link is an inline upload.
23802
+ 5. Check each destination response. If its upload or Forge share fails, say so explicitly and keep the dashboard link; never claim that a dashboard link is an inline embed.
23803
23803
 
23804
23804
  | Destination | Required file delivery | Inline result |
23805
23805
  |---|---|---|
@@ -23807,9 +23807,9 @@ If none of these apply, don't upload.
23807
23807
  | Slack | \`files.getUploadURLExternal\` \u2192 raw-byte POST \u2192 \`files.completeUploadExternal\` | Uploaded file in the channel or thread |
23808
23808
  | Linear | \`fileUpload\` mutation \u2192 presigned upload \u2192 issue/comment mutation | Returned \`assetUrl\` in Markdown |
23809
23809
  | GitLab | Project \`/uploads\` endpoint with the original bytes | Returned GitLab Markdown |
23810
- | GitHub | \`gh\` v2.99.0+ \`--attach\` for images and videos; use a Replicas public forge share as the fallback | Native GitHub attachment URL, or a Forge embed fallback |
23810
+ | GitHub | Replicas public Forge share for an image or recording poster | Printed Forge embed, linked to the recording when needed |
23811
23811
 
23812
- The dashboard link is the subtitle and jump-back path. It is never a substitute for the destination upload.
23812
+ The dashboard link is the subtitle and jump-back path. It is never a substitute for the destination embed.
23813
23813
 
23814
23814
  ## Uploading to Replicas
23815
23815
 
@@ -23838,7 +23838,7 @@ Names are normalized to hyphen-case (spaces become hyphens, e.g. \`Login page\`
23838
23838
  For each media file, the CLI prints an embed line and a dashboard link:
23839
23839
 
23840
23840
  1. Default and organization access print \`Replicas chat embed: ![filename](<api-url>)\`; this authenticated URL renders inline in Replicas chat **only** \u2014 see below.
23841
- 2. Public access (\`--access public\` or \`--share\`) prints \`![filename](<public-url>)\` as the Forge embed instead. This is the public, stable bearer URL for GitHub fallback embeds when native \`--attach\` is unavailable and sharing is authorized.
23841
+ 2. Public access (\`--access public\` or \`--share\`) prints \`![filename](<public-url>)\` as the Forge embed instead. This is the public, stable bearer URL to paste into GitHub when sharing is authorized.
23842
23842
  3. \`View in Replicas: <deep-link>\` is a per-file dashboard URL of the form \`https://app.replicas.dev/workspaces/<workspace-id>?media=<media-id>\` that opens directly to that specific file.
23843
23843
 
23844
23844
  Match each "View in Replicas" line to the embed line directly above it \u2014 that's the deep link for that file.
@@ -23867,7 +23867,7 @@ replicas media upload screenshot.png --name "Login page" --access public
23867
23867
  |---|---|---|
23868
23868
  | \`https://api.replicas.dev/v1/media/<id>\` (inside \`![\u2026](\u2026)\`) | Authenticated API redirect to a presigned blob \u2014 requires the Replicas chat session | **Only** in the Replicas chat reply. Nowhere else. |
23869
23869
  | \`https://replicas.dev/organizations/<organization-id>/media/<media-id>\` | Organization-only page printed by \`--access organization\` | Pull requests and other places where every viewer belongs to the Replicas organization. |
23870
- | \`https://api.replicas.dev/v1/media/public/<id>/<token>\` | Opt-in public bearer URL printed by \`--access public\` or \`--share\` | The Replicas chat reply and GitHub fallback embeds, for image, video, or audio media. |
23870
+ | \`https://api.replicas.dev/v1/media/public/<id>/<token>\` | Opt-in public bearer URL printed by \`--access public\` or \`--share\` | The Replicas chat reply and GitHub embeds, for image, video, or audio media. |
23871
23871
  | \`https://app.replicas.dev/workspaces/<workspace-id>?media=<media-id>\` | Authenticated dashboard deep link that opens the media file in the workspace | Everywhere external: Slack, GitHub, GitLab, Linear, PR bodies, comments, emails. |
23872
23872
 
23873
23873
  ### NEVER link the API redirect URL outside the Replicas chat reply
@@ -23906,12 +23906,12 @@ After (or alongside) the embeds, include a \`[View in Replicas](<deep-link>)\` h
23906
23906
 
23907
23907
  After \`replicas media upload\` succeeds, external delivery has two required follow-up steps for every file:
23908
23908
 
23909
- 1. **Upload the raw bytes through that platform's supported inline path** so the recipient sees the media embedded in the message itself.
23909
+ 1. **Use the destination's inline representation:** upload the raw bytes to Slack, Linear, or GitLab; embed a public Forge share on GitHub.
23910
23910
  2. **Link the Replicas dashboard deep link** (\`?media=<id>\` form) so the user can jump straight to the file in the workspace.
23911
23911
 
23912
- A link alone is not enough. An upload without the dashboard link is not enough. Do both.
23912
+ A dashboard link alone is not enough. An embed without the dashboard link is not enough. Do both.
23913
23913
 
23914
- Slack, Linear, and GitLab receive the original bytes through their native upload APIs. GitHub image and video attachments use \`gh --attach\` when the installed CLI and host support it; use an explicit Replicas public share only as the fallback.
23914
+ Slack, Linear, and GitLab receive the original bytes through their native upload APIs. GitHub uses a Replicas public Forge share for screenshots and recording previews.
23915
23915
 
23916
23916
  ### Slack \u2014 embed natively via the 3-step external file upload flow
23917
23917
 
@@ -24012,44 +24012,28 @@ The same flow works for issue bodies (use \`issueCreate\` / \`issueUpdate\` with
24012
24012
 
24013
24013
  Never paste the \`api.replicas.dev/v1/media/<id>\` URL into a Linear body or comment \u2014 it will render as a broken image to anyone outside your Replicas chat.
24014
24014
 
24015
- ### GitHub: native image and video attachments
24015
+ ### GitHub: inline images and recording previews via Forge
24016
24016
 
24017
- GitHub CLI v2.99.0+ supports a repeatable \`--attach\` flag on \`gh pr create\`, \`gh pr edit\`, and \`gh pr comment\` for GitHub.com and GitHub Enterprise Cloud. It uploads local images and videos to GitHub and writes the resulting attachment URL into the PR body or comment; it requires push access to the repository. GitHub Enterprise Server and unsupported media kinds are not covered by this path. See [GitHub's attachment guide](https://docs.github.com/en/github-cli/github-cli/attaching-files-with-github-cli).
24017
+ Replicas authenticates GitHub with GitHub App tokens, which native GitHub CLI attachment uploads do not support. Do not use \`gh --attach\` for media. Use a public Forge share for images in PR descriptions, issues, and comments.
24018
24018
 
24019
- Check \`gh --version\` before choosing the delivery path. On a supported host with v2.99.0 or later:
24019
+ Create a public share only for a public repository or after explicit consent to publish media from a private repository. If sharing is not authorized, keep the media private and include its **View in Replicas** link, explaining that inline GitHub images require a public share.
24020
24020
 
24021
- 1. Run \`replicas media upload\` with the original file first, without \`--share\`. Keep the matching **View in Replicas** dashboard link for the PR.
24022
- 2. Put each local file path in the Markdown body where the attachment should appear, and place its dashboard link next to it.
24023
- 3. Pass the same original path once with \`--attach\`. GitHub CLI rewrites a matching local reference in place, preserving its alt text; an unreferenced attachment is appended to the body.
24024
-
24025
- \`\`\`markdown
24026
- Before the change:
24027
-
24028
- ![Before state](/tmp/before.png)
24029
- [View in Replicas](https://app.replicas.dev/workspaces/<workspace-id>?media=<before-media-id>)
24030
- \`\`\`
24021
+ 1. Upload the image with public access. This creates both the Replicas dashboard copy and the Forge share:
24031
24022
 
24032
24023
  \`\`\`bash
24033
- gh pr create \\
24034
- --title "Describe the change" \\
24035
- --body-file /tmp/pr-body.md \\
24036
- --attach /tmp/before.png
24037
-
24038
- gh pr edit 456 --body-file /tmp/pr-body.md --attach /tmp/after.png
24039
- gh pr comment 456 --body-file /tmp/comment.md --attach /tmp/result.mp4
24024
+ replicas media upload /tmp/screenshot.png --name "PR screenshot" --access public
24040
24025
  \`\`\`
24041
24026
 
24042
- Repeat \`--attach\` for multiple files, up to 50 per command. For an appended image, add alt text after the path with \`#\`, for example \`--attach './error.png#Error state'\`. To render a video as a player, its local Markdown reference must be the only content in its paragraph. Do not paste a Replicas authenticated API URL into the body, and do not emulate GitHub's undocumented browser upload endpoint.
24043
-
24044
- ### GitHub attachment fallback
24045
-
24046
- If \`--attach\` is unavailable, the target is GitHub Enterprise Server, the file is not an image or video, or the native upload fails, keep the Replicas dashboard link and report the limitation. For an inline screenshot or video poster, create a Replicas public forge share only for a public repository or after explicit consent to publish media from a private repository, then use the printed \`Forge embed\` Markdown:
24027
+ 2. Copy the printed \`![filename](<public-url>)\` Forge embed into the body file, followed by the matching **View in Replicas** link. Use the printed public URL verbatim; never use a local file path, the authenticated API URL, or an expiring storage URL.
24028
+ 3. Create or update the PR using the body file:
24047
24029
 
24048
24030
  \`\`\`bash
24049
- replicas media upload /tmp/screenshot.png --name "PR screenshot" --share
24031
+ gh pr create --title "Describe the change" --body-file /tmp/pr-body.md
24032
+ gh pr edit 456 --body-file /tmp/pr-body.md
24033
+ gh pr comment 456 --body-file /tmp/comment.md
24050
24034
  \`\`\`
24051
24035
 
24052
- For a fallback recording preview, upload the MP4 normally, generate a poster with \`ffmpeg -i /tmp/demo.mp4 -frames:v 1 /tmp/demo-poster.png\`, share the poster, and link its embed to the recording's **View in Replicas** URL:
24036
+ GitHub does not reliably render external videos as inline players. For a recording preview, upload the MP4 normally, generate a poster with \`ffmpeg -i /tmp/demo.mp4 -frames:v 1 /tmp/demo-poster.png\`, upload the poster with \`--access public\`, and link its Forge embed to the recording's **View in Replicas** URL:
24053
24037
 
24054
24038
  \`\`\`markdown
24055
24039
  [![Demo recording](<public-poster-url>)](<recording-dashboard-url>)
@@ -27296,7 +27280,7 @@ var headlessFilesystemAgentResultSchema = external_exports.object({
27296
27280
  });
27297
27281
 
27298
27282
  // ../shared/src/cli-version.ts
27299
- var CLI_VERSION = "0.2.673";
27283
+ var CLI_VERSION = "0.2.675";
27300
27284
 
27301
27285
  // ../shared/src/version.ts
27302
27286
  function compareVersions(v1, v2) {
@@ -30483,6 +30467,16 @@ async function automationCreateCommand(name, options) {
30483
30467
  console.log(import_chalk18.default.red("--trigger-gitlab-exclude-users requires --trigger-gitlab"));
30484
30468
  process.exit(1);
30485
30469
  }
30470
+ const hasConfirmation = options.confirmationChannel || options.confirmationThread || options.confirmationMessageTs || options.confirmationUser;
30471
+ const mothershipConfirmation = options.confirmationChannel && options.confirmationThread && options.confirmationMessageTs && options.confirmationUser ? {
30472
+ channel_id: options.confirmationChannel,
30473
+ thread_ts: options.confirmationThread,
30474
+ message_ts: options.confirmationMessageTs,
30475
+ user_id: options.confirmationUser
30476
+ } : void 0;
30477
+ if (hasConfirmation && !mothershipConfirmation) {
30478
+ throw new Error("Every --confirmation-* option is required when creating an automation from Mothership.");
30479
+ }
30486
30480
  const agentSelection = applyAgentSelection(
30487
30481
  {
30488
30482
  agent_provider: parseAgentProviderOption(options.agentProvider),
@@ -30613,7 +30607,8 @@ async function automationCreateCommand(name, options) {
30613
30607
  ...options.planMode ? { plan_mode: true } : {},
30614
30608
  ...options.goalMode ? { goal_mode: true } : {},
30615
30609
  ...options.fastMode ? { fast_mode: true } : {},
30616
- ...agentSelection
30610
+ ...agentSelection,
30611
+ ...mothershipConfirmation ? { mothership_confirmation: mothershipConfirmation } : {}
30617
30612
  };
30618
30613
  console.log(import_chalk18.default.gray("\nCreating automation..."));
30619
30614
  const response = await orgAuthenticatedFetch("/v1/automations", {
@@ -32413,7 +32408,7 @@ automation.command("get <id>").description("Get automation details by ID").actio
32413
32408
  process.exit(1);
32414
32409
  }
32415
32410
  });
32416
- 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, 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, xhigh, 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) => {
32411
+ 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, 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, xhigh, 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("--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) => {
32417
32412
  try {
32418
32413
  await automationCreateCommand(name, {
32419
32414
  ...options,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "replicas-cli",
3
- "version": "0.2.673",
3
+ "version": "0.2.675",
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": {