replicas-cli 0.2.407 → 0.2.408

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.mjs +51 -16
  2. package/package.json +1 -1
package/dist/index.mjs CHANGED
@@ -22655,7 +22655,7 @@ replicas computer browser-state /tmp/after-click.png
22655
22655
  replicas computer record start /tmp/demo.mp4 --fps 60
22656
22656
  # ... do stuff ...
22657
22657
  replicas computer record stop
22658
- replicas media upload /tmp/demo.mp4
22658
+ replicas media upload /tmp/demo.mp4 --name "Demo recording"
22659
22659
  \`\`\`
22660
22660
 
22661
22661
  ## Command reference
@@ -22745,7 +22745,7 @@ Starts an ffmpeg screen recorder and returns only after ffmpeg has written the f
22745
22745
  Only one recording at a time. Re-running \`start\` while one is active fails - call \`stop\` first.
22746
22746
 
22747
22747
  ### \`replicas computer record stop\`
22748
- SIGINTs ffmpeg, verifies that the process has finalized the MP4, then prints the output path. A finalization timeout preserves the recording state so \`stop\` can be retried safely. Upload it with \`replicas media upload <path>\` to share it.
22748
+ SIGINTs ffmpeg, verifies that the process has finalized the MP4, then prints the output path. A finalization timeout preserves the recording state so \`stop\` can be retried safely. Upload it with \`replicas media upload <path> --name "<name>"\` to share it.
22749
22749
 
22750
22750
  ## Patterns
22751
22751
 
@@ -22790,7 +22790,7 @@ For tasks the user wants proof of:
22790
22790
  replicas computer record start /tmp/walkthrough.mp4
22791
22791
  # ... your work ...
22792
22792
  replicas computer record stop
22793
- replicas media upload /tmp/walkthrough.mp4
22793
+ replicas media upload /tmp/walkthrough.mp4 --name "Walkthrough recording"
22794
22794
  \`\`\`
22795
22795
  Then embed the printed \`![\u2026](\u2026)\` line in your chat reply. See \`MEDIA.md\`.
22796
22796
 
@@ -22991,7 +22991,7 @@ gh pr review 123 --request-changes --body "Changes needed"
22991
22991
  GitHub does NOT have a public API for uploading images to PRs/issues. When you need to include images:
22992
22992
  - Do NOT use placeholder image URLs
22993
22993
  - Do NOT commit screenshots as files to the repository
22994
- - Run \`replicas media upload <image> --share\` and put the printed \`Forge embed\` Markdown in the PR body or comment
22994
+ - Run \`replicas media upload <image> --name "<display name>" --share\` and put the printed \`Forge embed\` Markdown in the PR body or comment
22995
22995
  - For video, embed a shared poster image linked to the recording's **View in Replicas** URL; GitHub does not reliably render externally hosted video inline
22996
22996
  - Treat the public URL as an opt-in bearer capability; revoke it with \`replicas media revoke <media-id>\` only when the user asks or the media should stop rendering \u2014 revoking breaks embeds already posted on the PR
22997
22997
  - If you were triggered from Slack, also upload the image to the Slack thread so the user can see it directly
@@ -23572,10 +23572,26 @@ If none of these apply, don't upload.
23572
23572
  ## Uploading to Replicas
23573
23573
 
23574
23574
  \`\`\`bash
23575
- replicas media upload <path-to-file> [<path-to-file> ...]
23575
+ replicas media upload <path-to-file> --name "<display name>" [<path-to-file> --name "<display name>" ...]
23576
23576
  \`\`\`
23577
23577
 
23578
- Pass one or more file paths. Uploading several files in a single invocation is preferred over running the command repeatedly \u2014 it's faster and keeps the output grouped.
23578
+ Pass one or more file paths, each with a required \`--name\` (see below). Uploading several files in a single invocation is preferred over running the command repeatedly: it's faster and keeps the output grouped.
23579
+
23580
+ ### Name each upload
23581
+
23582
+ \`--name\` is **required** and sets the short, human-readable display name shown in the Replicas dashboard (the backend still tracks the asset by UUID). Make it descriptive of the content, e.g. \`login-page\`, \`checkout-error\`, or \`db-latency-chart\`. Never use a generic value like \`screenshot\` or \`image\`.
23583
+
23584
+ \`\`\`bash
23585
+ replicas media upload /tmp/shot.png --name "Login page after fix"
23586
+ \`\`\`
23587
+
23588
+ Pass one \`--name\` per file, in the same order as the file paths:
23589
+
23590
+ \`\`\`bash
23591
+ replicas media upload /tmp/before.png /tmp/after.png --name "Before fix" --name "After fix"
23592
+ \`\`\`
23593
+
23594
+ Names are normalized to hyphen-case (spaces become hyphens, e.g. \`Login page\` is stored as \`login-page\`). Give every asset a **distinct** name \u2014 duplicates are not rejected, but Replicas keeps the first as-is and adds a \`-1\`, \`-2\` suffix to later collisions, which produces confusing lists, so pick unique names yourself.
23579
23595
 
23580
23596
  For each file, the CLI prints two lines:
23581
23597
 
@@ -23587,7 +23603,7 @@ Match each "View in Replicas" line to the embed line directly above it \u2014 th
23587
23603
  Pass \`--share\` only when the media must render on an external forge:
23588
23604
 
23589
23605
  \`\`\`bash
23590
- replicas media upload screenshot.png --share
23606
+ replicas media upload screenshot.png --name "Login page" --share
23591
23607
  \`\`\`
23592
23608
 
23593
23609
  This prints an additional \`Forge embed\` Markdown line backed by an opt-in public bearer URL. Anyone with that unguessable URL can view the asset until it is rotated or revoked. Use \`replicas media share <media-id>\` to rotate it and \`replicas media revoke <media-id>\` to revoke it.
@@ -23757,7 +23773,7 @@ Never paste the \`api.tryreplicas.com/v1/media/<id>\` URL into a Linear body or
23757
23773
  GitHub has **no public API** for uploading attachments to PRs or issues. Its web UI uses an undocumented internal endpoint that API clients must not emulate. For screenshots, explicitly create a forge share and put the printed \`Forge embed\` Markdown directly in the PR body or comment, followed by the dashboard link:
23758
23774
 
23759
23775
  \`\`\`bash
23760
- replicas media upload /tmp/screenshot.png --share
23776
+ replicas media upload /tmp/screenshot.png --name "PR screenshot" --share
23761
23777
  \`\`\`
23762
23778
 
23763
23779
  GitHub does not reliably render arbitrary external videos as inline players. For a recording:
@@ -23811,13 +23827,14 @@ Auto-detected from the filename extension:
23811
23827
  For other extensions, pass \`--kind image|video|audio\` explicitly. The kind applies to every file in that invocation, so group files of the same kind together:
23812
23828
 
23813
23829
  \`\`\`bash
23814
- replicas media upload diagram.svg --kind image
23815
- replicas media upload chart-a.svg chart-b.svg --kind image
23830
+ replicas media upload diagram.svg --name "Architecture diagram" --kind image
23831
+ replicas media upload chart-a.svg chart-b.svg --name "Latency chart" --name "Error rate chart" --kind image
23816
23832
  \`\`\`
23817
23833
 
23818
23834
  ## Options
23819
23835
 
23820
23836
  - \`--kind <image|video|audio>\` \u2014 override auto-detection
23837
+ - \`--name <name>\`: required display name shown in the dashboard, one per file in order
23821
23838
  - \`--session-id <id>\` \u2014 associate the upload with a specific session
23822
23839
  - \`--share\`: create a revocable public bearer URL for a forge image embed
23823
23840
  `;
@@ -24401,7 +24418,7 @@ function formatTurnElapsed(ms) {
24401
24418
  }
24402
24419
 
24403
24420
  // ../shared/src/cli-version.ts
24404
- var CLI_VERSION = "0.2.407";
24421
+ var CLI_VERSION = "0.2.408";
24405
24422
 
24406
24423
  // ../shared/src/version.ts
24407
24424
  function compareVersions(v1, v2) {
@@ -29690,9 +29707,12 @@ function mediaInfo(ext) {
29690
29707
  if (kind !== "image" && kind !== "video" && kind !== "audio") return void 0;
29691
29708
  return { kind, contentType: mimeType };
29692
29709
  }
29710
+ function isMediaKind(value) {
29711
+ return MEDIA_KINDS.some((kind) => kind === value);
29712
+ }
29693
29713
  function resolveKind(ext, override) {
29694
29714
  if (override) {
29695
- if (!MEDIA_KINDS.includes(override)) {
29715
+ if (!isMediaKind(override)) {
29696
29716
  throw new Error(`Invalid kind '${override}'. Must be one of: ${MEDIA_KINDS.join(", ")}`);
29697
29717
  }
29698
29718
  return override;
@@ -29703,7 +29723,7 @@ function resolveKind(ext, override) {
29703
29723
  }
29704
29724
  return inferred;
29705
29725
  }
29706
- async function uploadOne(filePath, options) {
29726
+ async function uploadOne(filePath, displayName, options) {
29707
29727
  const absPath = path5.resolve(filePath);
29708
29728
  if (!fs4.existsSync(absPath)) {
29709
29729
  throw new Error(`File not found: ${absPath}`);
@@ -29723,6 +29743,7 @@ async function uploadOne(filePath, options) {
29723
29743
  form.append("file", new Blob([fs4.readFileSync(absPath)], { type: contentType }), fileName);
29724
29744
  form.append("kind", kind);
29725
29745
  if (options.sessionId) form.append("session_id", options.sessionId);
29746
+ form.append("display_name", displayName);
29726
29747
  const { media } = await agentFetch("/v1/engine/media", {
29727
29748
  method: "POST",
29728
29749
  body: form
@@ -29733,10 +29754,19 @@ async function mediaUploadCommand(filePaths, options) {
29733
29754
  if (filePaths.length === 0) {
29734
29755
  throw new Error("No files specified");
29735
29756
  }
29736
- if (options.kind && !MEDIA_KINDS.includes(options.kind)) {
29757
+ if (options.kind && !isMediaKind(options.kind)) {
29737
29758
  throw new Error(`Invalid kind '${options.kind}'. Must be one of: ${MEDIA_KINDS.join(", ")}`);
29738
29759
  }
29739
- const results = await Promise.allSettled(filePaths.map((p) => uploadOne(p, options)));
29760
+ const names = options.name ?? [];
29761
+ if (names.length !== filePaths.length) {
29762
+ throw new Error(
29763
+ `Each file needs a --name. Got ${filePaths.length} file(s) and ${names.length} --name value(s); pass one --name per file, in order.`
29764
+ );
29765
+ }
29766
+ if (names.some((name) => !name.trim())) {
29767
+ throw new Error("--name must not be empty.");
29768
+ }
29769
+ const results = await Promise.allSettled(filePaths.map((p, i) => uploadOne(p, names[i], options)));
29740
29770
  const config3 = readAgentConfig();
29741
29771
  const failures = [];
29742
29772
  for (let i = 0; i < results.length; i++) {
@@ -37267,7 +37297,12 @@ if (isAgentMode()) {
37267
37297
  }
37268
37298
  });
37269
37299
  const media = program.command("media").description("Share workspace media (screenshots, videos, audio) inline in chat");
37270
- media.command("upload <files...>").description("Upload one or more screenshot, video, or audio files. Multiple files are uploaded concurrently. Prints a markdown embed per file for the assistant reply.").option("-k, --kind <kind>", "Media kind: image, video, or audio (inferred from extension if omitted)").option("-s, --session-id <id>", "Session ID to associate the asset with").option("--share", "Create an opt-in public forge embed URL for each asset").action(async (files, options) => {
37300
+ media.command("upload <files...>").description("Upload one or more screenshot, video, or audio files. Multiple files are uploaded concurrently. Prints a markdown embed per file for the assistant reply.").option("-k, --kind <kind>", "Media kind: image, video, or audio (inferred from extension if omitted)").option("-s, --session-id <id>", "Session ID to associate the asset with").option(
37301
+ "-n, --name <name>",
37302
+ "Required human-facing display name shown in the dashboard. Pass one --name per file, in order.",
37303
+ (value, previous) => [...previous, value],
37304
+ []
37305
+ ).option("--share", "Create an opt-in public forge embed URL for each asset").action(async (files, options) => {
37271
37306
  try {
37272
37307
  await mediaUploadCommand(files, options);
37273
37308
  } catch (error51) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "replicas-cli",
3
- "version": "0.2.407",
3
+ "version": "0.2.408",
4
4
  "description": "CLI for managing Replicas workspaces - SSH into cloud dev environments with automatic port forwarding",
5
5
  "main": "dist/index.mjs",
6
6
  "bin": {