replicas-cli 0.2.483 → 0.2.484

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 +24 -14
  2. package/package.json +1 -1
package/dist/index.mjs CHANGED
@@ -9312,7 +9312,7 @@ Use public access only when the media must render without Replicas authenticatio
9312
9312
  replicas media upload screenshot.png --name "Login page" --access public
9313
9313
  \`\`\`
9314
9314
 
9315
- \`--share\` remains an alias for \`--access public\`. Public access prints an additional \`Forge embed\` for media or \`Forge link\` for HTML, backed by an opt-in 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.
9315
+ \`--share\` remains an alias for \`--access public\`. Public access prints an additional \`Forge embed\` for image, video, or audio media, backed by an opt-in bearer URL. Anyone with that unguessable URL can view the asset until it is rotated or revoked. HTML pages only support organization access. Use \`replicas media share <media-id>\` to rotate a public media URL and \`replicas media revoke <media-id>\` to revoke it.
9316
9316
 
9317
9317
  ## The URLs the CLI gives you \u2014 and where each one is allowed
9318
9318
 
@@ -9320,7 +9320,7 @@ replicas media upload screenshot.png --name "Login page" --access public
9320
9320
  |---|---|---|
9321
9321
  | \`https://api.tryreplicas.com/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. |
9322
9322
  | \`https://tryreplicas.com/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. |
9323
- | \`https://api.tryreplicas.com/v1/media/public/<id>/<token>\` | Opt-in public bearer URL printed by \`--access public\` or \`--share\` | GitHub image embeds and intentionally public HTML page links. |
9323
+ | \`https://api.tryreplicas.com/v1/media/public/<id>/<token>\` | Opt-in public bearer URL printed by \`--access public\` or \`--share\` | GitHub embeds for image, video, or audio media. |
9324
9324
  | \`https://tryreplicas.com/workspaces/<workspace-id>?media=<media-id>\` | Authenticated dashboard deep link that opens the media file in the workspace | Everywhere external \u2014 Slack, GitHub, Linear, PR bodies, comments, emails. |
9325
9325
 
9326
9326
  ### NEVER link the API redirect URL outside the Replicas chat reply
@@ -9496,7 +9496,7 @@ GitHub does not reliably render arbitrary external videos as inline players. For
9496
9496
 
9497
9497
  Public forge shares are bearer capabilities. For private repositories, create one only when the user asked for inline PR media. Revoke with \`replicas media revoke <media-id>\` **only** when the user asks or the media should intentionally stop rendering \u2014 never as routine post-task cleanup, since revoking breaks every embed already posted on the PR.
9498
9498
 
9499
- For a self-contained HTML report, upload it with \`--access organization\` and put the printed \`Forge link\` Markdown in the PR body or comment. GitHub cannot render the page inline, so use the normal link rather than image syntax. Use \`--access public\` only when the user explicitly wants unauthenticated access.
9499
+ For a self-contained HTML report, upload it with \`--access organization\` and put the printed \`Forge link\` Markdown in the PR body or comment. GitHub cannot render the page inline, so use the normal link rather than image syntax. HTML pages cannot be shared publicly.
9500
9500
 
9501
9501
  Do **not** commit screenshots to the repo, use placeholder URLs, expose the authenticated \`/v1/media/<id>\` URL, or automate GitHub's undocumented browser upload flow.
9502
9502
 
@@ -9546,8 +9546,8 @@ replicas media upload chart-a.svg chart-b.svg --name "Latency chart" --name "Err
9546
9546
  - \`--kind <image|video|audio|html>\` \u2014 override auto-detection
9547
9547
  - \`--name <name>\`: required display name shown in the dashboard, one per file in order
9548
9548
  - \`--session-id <id>\` \u2014 associate the upload with a specific session
9549
- - \`--access organization|public\`: create an organization-only page link or a public bearer URL
9550
- - \`--share\`: alias for \`--access public\`
9549
+ - \`--access organization|public\`: create an organization-only link, or a public bearer URL for non-HTML media
9550
+ - \`--share\`: alias for \`--access public\`; not supported for HTML
9551
9551
  `;
9552
9552
  var MEDIA_ABILITY = {
9553
9553
  label: "Media",
@@ -10141,7 +10141,7 @@ function formatTurnElapsed(ms) {
10141
10141
  }
10142
10142
 
10143
10143
  // ../shared/src/cli-version.ts
10144
- var CLI_VERSION = "0.2.483";
10144
+ var CLI_VERSION = "0.2.484";
10145
10145
 
10146
10146
  // ../shared/src/version.ts
10147
10147
  function compareVersions(v1, v2) {
@@ -27519,6 +27519,10 @@ var MEDIA_KIND = {
27519
27519
  HTML: "html"
27520
27520
  };
27521
27521
  var MEDIA_KINDS = [MEDIA_KIND.IMAGE, MEDIA_KIND.VIDEO, MEDIA_KIND.AUDIO, MEDIA_KIND.HTML];
27522
+ var PUBLIC_MEDIA_KINDS = [MEDIA_KIND.IMAGE, MEDIA_KIND.VIDEO, MEDIA_KIND.AUDIO];
27523
+ function isPublicMediaKind(value) {
27524
+ return PUBLIC_MEDIA_KINDS.some((kind) => kind === value);
27525
+ }
27522
27526
  var MAX_ENGINE_LOG_BYTES = 50 * 1024 * 1024;
27523
27527
 
27524
27528
  // ../shared/src/sse.ts
@@ -30585,7 +30589,7 @@ function resolveKind(ext, override) {
30585
30589
  }
30586
30590
  return inferred;
30587
30591
  }
30588
- async function uploadOne(filePath, displayName, options) {
30592
+ async function uploadOne(filePath, displayName, kind, options) {
30589
30593
  const absPath = path5.resolve(filePath);
30590
30594
  if (!fs4.existsSync(absPath)) {
30591
30595
  throw new Error(`File not found: ${absPath}`);
@@ -30599,7 +30603,6 @@ async function uploadOne(filePath, displayName, options) {
30599
30603
  }
30600
30604
  const fileName = path5.basename(absPath);
30601
30605
  const ext = path5.extname(absPath).slice(1).toLowerCase();
30602
- const kind = resolveKind(ext, options.kind);
30603
30606
  const contentType = mediaInfo(ext)?.contentType ?? "application/octet-stream";
30604
30607
  const form = new FormData();
30605
30608
  form.append("file", new Blob([fs4.readFileSync(absPath)], { type: contentType }), fileName);
@@ -30634,8 +30637,17 @@ async function mediaUploadCommand(filePaths, options) {
30634
30637
  if (names.some((name) => !name.trim())) {
30635
30638
  throw new Error("--name must not be empty.");
30636
30639
  }
30637
- const results = await Promise.allSettled(filePaths.map((p, i) => uploadOne(p, names[i], options)));
30638
30640
  const publicAccess = options.share || options.access === "public";
30641
+ const kinds = filePaths.map((filePath) => {
30642
+ const ext = path5.extname(filePath).slice(1).toLowerCase();
30643
+ return resolveKind(ext, options.kind);
30644
+ });
30645
+ if (publicAccess && kinds.some((kind) => !isPublicMediaKind(kind))) {
30646
+ throw new Error("HTML pages only support organization access. Use --access organization.");
30647
+ }
30648
+ const results = await Promise.allSettled(
30649
+ filePaths.map((filePath, i) => uploadOne(filePath, names[i], kinds[i], options))
30650
+ );
30639
30651
  const shareResults = publicAccess ? await Promise.allSettled(
30640
30652
  results.map(
30641
30653
  (result) => result.status === "fulfilled" ? shareMedia(result.value.media.id) : Promise.resolve(null)
@@ -30660,9 +30672,7 @@ async function mediaUploadCommand(filePaths, options) {
30660
30672
  if (publicAccess) {
30661
30673
  const shareResult = shareResults[i];
30662
30674
  if (shareResult.status === "fulfilled" && shareResult.value) {
30663
- console.log(
30664
- media.kind === MEDIA_KIND.HTML ? `Forge link: [View ${options.name?.[i] ?? fileName}](${shareResult.value})` : `Forge embed: ![${fileName}](${shareResult.value})`
30665
- );
30675
+ console.log(`Forge embed: ![${fileName}](${shareResult.value})`);
30666
30676
  } else {
30667
30677
  const error51 = shareResult.status === "rejected" ? shareResult.reason : new Error("Missing public share URL");
30668
30678
  failures.push({
@@ -35597,7 +35607,7 @@ if (isAgentMode()) {
35597
35607
  "Required human-facing display name shown in the dashboard. Pass one --name per file, in order.",
35598
35608
  (value, previous) => [...previous, value],
35599
35609
  []
35600
- ).option("--access <access>", "Link access: organization (sign-in required) or public (bearer URL)").option("--share", "Alias for --access public").action(async (files, options) => {
35610
+ ).option("--access <access>", "Link access: organization (sign-in required) or public (non-HTML bearer URL)").option("--share", "Alias for --access public; not supported for HTML").action(async (files, options) => {
35601
35611
  try {
35602
35612
  await mediaUploadCommand(files, options);
35603
35613
  } catch (error51) {
@@ -35609,7 +35619,7 @@ if (isAgentMode()) {
35609
35619
  process.exit(1);
35610
35620
  }
35611
35621
  });
35612
- media.command("share <mediaId>").description("Create or rotate a public forge URL for uploaded media").action(async (mediaId) => {
35622
+ media.command("share <mediaId>").description("Create or rotate a public forge URL for uploaded image, video, or audio media").action(async (mediaId) => {
35613
35623
  try {
35614
35624
  await mediaShareCommand(mediaId);
35615
35625
  } catch (error51) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "replicas-cli",
3
- "version": "0.2.483",
3
+ "version": "0.2.484",
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": {