replicas-cli 0.3.104 → 0.3.106
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 +39 -38
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -24527,7 +24527,7 @@ Every Replicas workspace is a remote Linux VM. Repositories are cloned under \`~
|
|
|
24527
24527
|
|
|
24528
24528
|
Hooks run with \`bash -lc\` from \`~/workspaces\` (the parent of every repository checkout), so start scripts with \`cd ~/workspaces/<repo-name>\`. A repository may also ship its own \`replicas.json\` / \`replicas.yaml\` with \`startHook\`, \`warmHook\`, and \`systemPrompt\`; repository hooks run after the environment hooks. Prefer proposing environment hooks unless the repository already manages its own.
|
|
24529
24529
|
|
|
24530
|
-
|
|
24530
|
+
Forks inherit everything their parent sets; never propose putting repository-specific setup in an environment other environments fork from.
|
|
24531
24531
|
|
|
24532
24532
|
## Progress and the setup run
|
|
24533
24533
|
|
|
@@ -24735,7 +24735,6 @@ After \`propose\` succeeds, mark the \`propose\` step completed and send one mes
|
|
|
24735
24735
|
- <two to four findings about the codebase that shaped the configuration, written for a person>
|
|
24736
24736
|
|
|
24737
24737
|

|
|
24738
|
-
[View in Canvas](<View in Replicas URL>)
|
|
24739
24738
|
|
|
24740
24739
|
**Proposed configuration**
|
|
24741
24740
|
Review the start hook, warm hook, system prompt, variables, and automations in the Environment panel on the right. Edit anything inline, then select **Save configuration**. Ask me here if you want changes and I will revise the proposal.
|
|
@@ -25185,6 +25184,12 @@ var REFERENCE8 = `# Media (Screenshots, GIFs, Recordings, Audio, HTML)
|
|
|
25185
25184
|
|
|
25186
25185
|
This is the single source of truth for delivering screenshots, GIFs, screen recordings, generated diagrams, audio clips, and self-contained HTML pages through Replicas and external surfaces (Slack, Linear, GitHub, GitLab).
|
|
25187
25186
|
|
|
25187
|
+
## Always
|
|
25188
|
+
|
|
25189
|
+
- Every picture, GIF, recording, or HTML page you mention in your reply to the user shows up in that reply: paste its printed \`\` or \`HTML page\` line on its own line. Do this even when you also posted it to a PR, Slack, Linear, or GitLab, and even when the task came from one of them.
|
|
25190
|
+
- Never send the user somewhere else to see it ("see the Canvas", "check the media tab"). Uploads also appear in the Canvas's media folder, so they stay there for later.
|
|
25191
|
+
- Keep the whole \`replicas media upload\` output. Don't pipe it through \`tail\`, \`grep\`, or \`head\`; you need every line it prints.
|
|
25192
|
+
|
|
25188
25193
|
## Prerequisites
|
|
25189
25194
|
|
|
25190
25195
|
The \`replicas\` CLI is pre-installed and authenticated in your workspace. No additional setup is needed.
|
|
@@ -25253,7 +25258,7 @@ If none of these apply, don't upload.
|
|
|
25253
25258
|
\`replicas media upload\` is always the first delivery action. When the current task has an external destination, every other delivery step follows only after that command succeeds. For every file:
|
|
25254
25259
|
|
|
25255
25260
|
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 an embed plus a per-file dashboard link. Every image gets a public link, so its printed embed works in chat and on GitHub.
|
|
25256
|
-
2. Include the printed embed line in the Replicas chat reply
|
|
25261
|
+
2. Include the printed embed line in the Replicas chat reply. HTML uses its printed page link instead of an image embed.
|
|
25257
25262
|
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 image's printed public embed.
|
|
25258
25263
|
4. Put the **View in Replicas** dashboard link next to the destination embed as a secondary link.
|
|
25259
25264
|
5. Check each destination response. If its upload or public link fails, say so explicitly and keep the dashboard link; never claim that a dashboard link is an inline embed.
|
|
@@ -25294,21 +25299,13 @@ Names are normalized to hyphen-case (spaces become hyphens, e.g. \`Login page\`
|
|
|
25294
25299
|
|
|
25295
25300
|
For each media file, the CLI prints an embed line and a dashboard link:
|
|
25296
25301
|
|
|
25297
|
-
1. Images always print \`\`, using the \`--name\` you passed. This public, stable link works in Replicas chat, GitHub, and anywhere else Markdown images render. No flag is needed.
|
|
25303
|
+
2. Video and audio print \`Replicas chat embed: \` by default; this authenticated URL renders inline in Replicas chat **only** \u2014 see below. \`--access public\` prints a public link instead, \`[<name>](<public-url>)\`, which plays in Replicas chat and opens the video anywhere else. Never put a video inside \`\` or a \`<video>\` tag on GitHub: it shows as a broken image or disappears. Videos also print the PR line to paste once you have a GIF, already linked to the video.
|
|
25299
25304
|
3. \`View in Replicas: <deep-link>\` is a per-file dashboard URL of the form \`https://app.replicas.dev/workspaces/<workspace-id>?mode=media&media=<media-id>\` that opens directly to that specific file.
|
|
25300
25305
|
|
|
25301
25306
|
Match each "View in Replicas" line to the embed line directly above it \u2014 that's the deep link for that file.
|
|
25302
25307
|
|
|
25303
|
-
HTML uploads print an \`HTML page\` Markdown link instead of an image embed.
|
|
25304
|
-
|
|
25305
|
-
For an HTML page that should stay inside the Replicas organization, create an authenticated link:
|
|
25306
|
-
|
|
25307
|
-
\`\`\`bash
|
|
25308
|
-
replicas media upload recap.html --name "Visual recap" --access organization
|
|
25309
|
-
\`\`\`
|
|
25310
|
-
|
|
25311
|
-
The printed \`Forge link (organization only)\` opens a dedicated page. Signed-in organization members go straight to it; signed-out members sign in and return to the page.
|
|
25308
|
+
HTML uploads print an \`HTML page\` Markdown link instead of an image embed. It previews the page inside Replicas chat only. They also print a \`Forge link (organization only)\` to use everywhere else: it opens a dedicated page, where signed-in organization members go straight to the report and signed-out members sign in first.
|
|
25312
25309
|
|
|
25313
25310
|
Video and audio stay private unless they must play without Replicas sign-in; then pass \`--access public\` (alias \`--share\`):
|
|
25314
25311
|
|
|
@@ -25325,7 +25322,7 @@ Permanently delete an upload with \`replicas media delete <media-id>\`. The back
|
|
|
25325
25322
|
| URL | What it is | Where it's allowed |
|
|
25326
25323
|
|---|---|---|
|
|
25327
25324
|
| \`https://api.replicas.dev/v1/media/<id>\` (inside \`\`) | Authenticated API redirect printed for private video, audio, and HTML \u2014 requires the Replicas chat session | **Only** in the Replicas chat reply. Nowhere else. |
|
|
25328
|
-
| \`https://replicas.dev/organizations/<organization-id>/media/<media-id>\` | Organization-only page printed
|
|
25325
|
+
| \`https://app.replicas.dev/organizations/<organization-id>/media/<media-id>\` | Organization-only page (\`Forge link\`) printed for every HTML upload, and for video or audio with \`--access organization\` | Pull requests and other places where every viewer belongs to the Replicas organization. |
|
|
25329
25326
|
| \`https://api.replicas.dev/v1/media/public/<id>/<token>\` | Public bearer URL printed for every image, and for video or audio with \`--access public\` | The Replicas chat reply and GitHub embeds. |
|
|
25330
25327
|
| \`https://app.replicas.dev/workspaces/<workspace-id>?mode=media&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. |
|
|
25331
25328
|
|
|
@@ -25343,7 +25340,7 @@ This rule has no exceptions:
|
|
|
25343
25340
|
|
|
25344
25341
|
### ALWAYS link a Replicas web URL \u2014 never the authenticated API URL \u2014 when referencing media externally
|
|
25345
25342
|
|
|
25346
|
-
For an
|
|
25343
|
+
For an HTML page, use its printed \`Forge link\`. For other authenticated media references, use the dashboard form:
|
|
25347
25344
|
|
|
25348
25345
|
\`\`\`
|
|
25349
25346
|
https://app.replicas.dev/workspaces/<workspace-id>?mode=media&media=<media-id>
|
|
@@ -25361,8 +25358,6 @@ Include each markdown embed line **verbatim** where you want that file to render
|
|
|
25361
25358
|
|
|
25362
25359
|
Never reply with only dashboard links (for example a "Links:" list of \`?mode=media&media=\` URLs) in place of the embeds: a dashboard link renders as plain text, so the user sees nothing inline. This applies even when the task came from Slack, Linear, GitHub, or GitLab; the chat reply still gets the embeds.
|
|
25363
25360
|
|
|
25364
|
-
After (or alongside) the embeds, include a \`[View in Canvas](<deep-link>)\` hyperlink for each file using the per-file dashboard URL printed by the CLI as **View in Replicas**. Keep that URL unchanged so it opens the specific media item in the workspace's Canvas. External messages still label this dashboard link **View in Replicas**.
|
|
25365
|
-
|
|
25366
25361
|
## On external platforms: embed the file AND link the dashboard
|
|
25367
25362
|
|
|
25368
25363
|
After \`replicas media upload\` succeeds, external delivery has two required follow-up steps for every file:
|
|
@@ -25494,7 +25489,7 @@ gh pr edit 456 --body-file /tmp/pr-body.md
|
|
|
25494
25489
|
gh pr comment 456 --body-file /tmp/comment.md
|
|
25495
25490
|
\`\`\`
|
|
25496
25491
|
|
|
25497
|
-
GitHub does not play external videos inline, so show motion with a GIF (see *Make a GIF from a recording* above); its printed embed animates inline like any image. Videos stay private. When the full recording is also worth watching, upload the MP4 too and
|
|
25492
|
+
GitHub does not play external videos inline, so show motion with a GIF (see *Make a GIF from a recording* above); its printed embed animates inline like any image. Videos stay private. When the full recording is also worth watching, upload the MP4 too and paste the PR line it prints, with your GIF's link filled in. The GIF links to the recording's **View in Replicas** URL, or to its public link when you passed \`--access public\`. When a still is enough, use a poster instead (\`ffmpeg -i /tmp/demo.mp4 -frames:v 1 /tmp/demo-poster.png\`), uploaded like any image:
|
|
25498
25493
|
|
|
25499
25494
|
\`\`\`markdown
|
|
25500
25495
|
[](<recording-dashboard-url>)
|
|
@@ -25502,7 +25497,7 @@ GitHub does not play external videos inline, so show motion with a GIF (see *Mak
|
|
|
25502
25497
|
|
|
25503
25498
|
Public links are unauthenticated bearer capabilities. Revoke with \`replicas media revoke <media-id>\` **only** when the user asks or the media should intentionally stop rendering; never as routine post-task cleanup, since revoking breaks every embed already posted on the PR.
|
|
25504
25499
|
|
|
25505
|
-
For a self-contained HTML report, upload it
|
|
25500
|
+
For a self-contained HTML report, upload it 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.
|
|
25506
25501
|
|
|
25507
25502
|
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.
|
|
25508
25503
|
|
|
@@ -25554,7 +25549,7 @@ replicas media upload chart-a.svg chart-b.svg --name "Latency chart" --name "Err
|
|
|
25554
25549
|
- \`--kind <image|video|audio|html>\` \u2014 override auto-detection
|
|
25555
25550
|
- \`--name <name>\`: required display name shown in the dashboard, one per file in order
|
|
25556
25551
|
- \`--session-id <id>\` \u2014 associate the upload with a specific session
|
|
25557
|
-
- \`--access organization|public\`: for video
|
|
25552
|
+
- \`--access organization|public\`: for video and audio, print an organization-only link or create a public bearer URL. Images are always public, and HTML always gets an organization-only link
|
|
25558
25553
|
- \`--share\`: alias for \`--access public\`; not supported for HTML
|
|
25559
25554
|
`;
|
|
25560
25555
|
var MEDIA_ABILITY = {
|
|
@@ -25997,7 +25992,7 @@ replicas environment delete <id-or-name> [--force]
|
|
|
25997
25992
|
\`\`\`
|
|
25998
25993
|
|
|
25999
25994
|
Notes:
|
|
26000
|
-
- Environments resolve by **name or UUID**.
|
|
25995
|
+
- Environments resolve by **name or UUID**. A fork inherits its parent's setup and can override or hide any of it.
|
|
26001
25996
|
- An env needs a repo to back a workspace with code. If you \`create\` without \`--repository\`, the CLI prompts; in non-interactive contexts pass \`-r\`.
|
|
26002
25997
|
|
|
26003
25998
|
### Environment variables
|
|
@@ -28765,7 +28760,7 @@ var headlessAgentRequestSchema = external_exports.object({
|
|
|
28765
28760
|
});
|
|
28766
28761
|
|
|
28767
28762
|
// ../shared/src/cli-version.ts
|
|
28768
|
-
var CLI_VERSION = "0.3.
|
|
28763
|
+
var CLI_VERSION = "0.3.106";
|
|
28769
28764
|
|
|
28770
28765
|
// ../shared/src/version.ts
|
|
28771
28766
|
function compareVersions(v1, v2) {
|
|
@@ -31617,8 +31612,8 @@ async function resolveEnvironmentId(input) {
|
|
|
31617
31612
|
}
|
|
31618
31613
|
return resolved.id;
|
|
31619
31614
|
}
|
|
31620
|
-
function printEnvironment(env
|
|
31621
|
-
console.log(import_chalk20.default.white(` ${env.name}
|
|
31615
|
+
function printEnvironment(env) {
|
|
31616
|
+
console.log(import_chalk20.default.white(` ${env.name}`));
|
|
31622
31617
|
console.log(import_chalk20.default.gray(` ID: ${env.id}`));
|
|
31623
31618
|
if (env.description) {
|
|
31624
31619
|
console.log(import_chalk20.default.gray(` Description: ${env.description}`));
|
|
@@ -31636,7 +31631,7 @@ function printEnvironment(env, isBase = false) {
|
|
|
31636
31631
|
async function environmentListCommand() {
|
|
31637
31632
|
ensureOrgApiAuthenticated();
|
|
31638
31633
|
const response = await orgAuthenticatedFetch("/v1/environments");
|
|
31639
|
-
output(response, ({ environments
|
|
31634
|
+
output(response, ({ environments }) => {
|
|
31640
31635
|
if (environments.length === 0) {
|
|
31641
31636
|
console.log(import_chalk20.default.yellow("\nNo environments found.\n"));
|
|
31642
31637
|
return;
|
|
@@ -31644,7 +31639,7 @@ async function environmentListCommand() {
|
|
|
31644
31639
|
console.log(import_chalk20.default.green(`
|
|
31645
31640
|
Environments (${environments.length}):
|
|
31646
31641
|
`));
|
|
31647
|
-
for (const env of environments) printEnvironment(env
|
|
31642
|
+
for (const env of environments) printEnvironment(env);
|
|
31648
31643
|
});
|
|
31649
31644
|
}
|
|
31650
31645
|
async function environmentGetCommand(idOrName) {
|
|
@@ -32297,7 +32292,7 @@ async function replicaCreateCommand(name, options) {
|
|
|
32297
32292
|
let replicaName = name;
|
|
32298
32293
|
let message2 = options.message;
|
|
32299
32294
|
const environmentInput = options.environment?.trim();
|
|
32300
|
-
let selectedEnvironmentId = environmentInput === "global" ?
|
|
32295
|
+
let selectedEnvironmentId = environmentInput === "global" ? (await orgAuthenticatedFetch("/v1/environments/global")).environment.id : environmentInput && await resolveEnvironmentId(environmentInput);
|
|
32301
32296
|
let codingAgent = parseReplicaAgent(options.agent);
|
|
32302
32297
|
if (replicaName && /\s/.test(replicaName)) {
|
|
32303
32298
|
throw new Error("Replica name cannot contain spaces.");
|
|
@@ -32328,7 +32323,7 @@ async function replicaCreateCommand(name, options) {
|
|
|
32328
32323
|
choices: environments.map((env) => ({
|
|
32329
32324
|
title: env.name,
|
|
32330
32325
|
value: env.id,
|
|
32331
|
-
description:
|
|
32326
|
+
description: `${env.repository_ids?.length ?? 0} repositories`
|
|
32332
32327
|
}))
|
|
32333
32328
|
});
|
|
32334
32329
|
const answer = response2.environment;
|
|
@@ -33975,10 +33970,11 @@ var MEDIA_ACCESS_VALUES = ["organization", "public"];
|
|
|
33975
33970
|
function publicMediaUrl(mediaId, token) {
|
|
33976
33971
|
return `${MONOLITH_URL}/v1/media/public/${mediaId}/${token}`;
|
|
33977
33972
|
}
|
|
33978
|
-
var MEDIA_DELIVERY_HINT = "Next: paste each
|
|
33979
|
-
|
|
33980
|
-
|
|
33981
|
-
return
|
|
33973
|
+
var MEDIA_DELIVERY_HINT = "Next: paste each media line above (``, `[\u2026](\u2026)`, or `HTML page`) verbatim into your Replicas chat reply so it renders inline; View in Replicas links are secondary and never replace it. Slack, Linear, and GitLab also need a native upload of the file bytes; see the replicas-agent skill's references/MEDIA.md.";
|
|
33974
|
+
var markdownLabel = (name) => name.replace(/[[\]]/g, "");
|
|
33975
|
+
function formatMediaEmbed(name, media2, publicUrl) {
|
|
33976
|
+
if (publicUrl) return `${media2.kind === MEDIA_KIND.IMAGE ? "!" : ""}[${markdownLabel(name)}](${publicUrl})`;
|
|
33977
|
+
return `Replicas chat embed: `;
|
|
33982
33978
|
}
|
|
33983
33979
|
async function shareMedia(mediaId) {
|
|
33984
33980
|
const { token } = await agentFetch(`/v1/engine/media/${mediaId}/share`, {
|
|
@@ -34034,7 +34030,7 @@ async function uploadOne(filePath, displayName, kind, options) {
|
|
|
34034
34030
|
method: "POST",
|
|
34035
34031
|
body: form
|
|
34036
34032
|
});
|
|
34037
|
-
return
|
|
34033
|
+
return media2;
|
|
34038
34034
|
}
|
|
34039
34035
|
async function mediaUploadCommand(filePaths, options) {
|
|
34040
34036
|
if (filePaths.length === 0) {
|
|
@@ -34072,7 +34068,7 @@ async function mediaUploadCommand(filePaths, options) {
|
|
|
34072
34068
|
);
|
|
34073
34069
|
const shareResults = await Promise.allSettled(
|
|
34074
34070
|
results.map(
|
|
34075
|
-
(result, i) => result.status === "fulfilled" && shared[i] ? shareMedia(result.value.
|
|
34071
|
+
(result, i) => result.status === "fulfilled" && shared[i] ? shareMedia(result.value.id) : Promise.resolve(null)
|
|
34076
34072
|
)
|
|
34077
34073
|
);
|
|
34078
34074
|
const config3 = readAgentConfig();
|
|
@@ -34081,7 +34077,7 @@ async function mediaUploadCommand(filePaths, options) {
|
|
|
34081
34077
|
for (let i = 0; i < results.length; i++) {
|
|
34082
34078
|
const result = results[i];
|
|
34083
34079
|
if (result.status === "fulfilled") {
|
|
34084
|
-
const
|
|
34080
|
+
const media2 = result.value;
|
|
34085
34081
|
const shareResult = shareResults[i];
|
|
34086
34082
|
const publicUrl = shareResult?.status === "fulfilled" ? shareResult.value ?? void 0 : void 0;
|
|
34087
34083
|
if (shared[i]) {
|
|
@@ -34101,8 +34097,9 @@ async function mediaUploadCommand(filePaths, options) {
|
|
|
34101
34097
|
name: names[i],
|
|
34102
34098
|
media: media2,
|
|
34103
34099
|
public_url: publicUrl,
|
|
34104
|
-
embed: media2.kind === MEDIA_KIND.HTML ? `HTML page: [${
|
|
34105
|
-
|
|
34100
|
+
embed: media2.kind === MEDIA_KIND.HTML ? `HTML page: [${markdownLabel(names[i])}](${MONOLITH_URL}/v1/media/${media2.id})` : !shared[i] || publicUrl ? formatMediaEmbed(names[i], media2, publicUrl) : void 0,
|
|
34101
|
+
// The HTML page link above only works inside Replicas chat, so HTML always gets a link that works elsewhere.
|
|
34102
|
+
organization_url: media2.kind === MEDIA_KIND.HTML || options.access === "organization" && !shared[i] ? getOrganizationMediaUrl(media2.organization_id, media2.id) : void 0,
|
|
34106
34103
|
dashboard_url: config3?.workspace_id ? getWorkspaceDashboardUrl(config3.workspace_id, { mode: "media", mediaId: media2.id }) : void 0
|
|
34107
34104
|
});
|
|
34108
34105
|
} else {
|
|
@@ -34117,6 +34114,10 @@ async function mediaUploadCommand(filePaths, options) {
|
|
|
34117
34114
|
console.log(`Forge link (organization only): [View ${upload.name}](${upload.organization_url})`);
|
|
34118
34115
|
}
|
|
34119
34116
|
if (upload.dashboard_url) console.log(`View in Replicas: ${upload.dashboard_url}`);
|
|
34117
|
+
if (upload.media.kind === MEDIA_KIND.VIDEO) {
|
|
34118
|
+
const videoLink = upload.public_url ?? upload.dashboard_url;
|
|
34119
|
+
console.log(`GitHub can't play videos. For a PR, make a GIF with \`replicas media gif ${upload.file}\`, upload it, and paste it linked to this video: [](${videoLink})`);
|
|
34120
|
+
}
|
|
34120
34121
|
}
|
|
34121
34122
|
if (uploads.some((upload) => upload.embed)) console.log(`
|
|
34122
34123
|
${MEDIA_DELIVERY_HINT}`);
|