replicas-engine 0.1.474 → 0.1.476
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/src/index.js +12 -124
- package/package.json +1 -1
package/dist/src/index.js
CHANGED
|
@@ -582,7 +582,7 @@ var WORKSPACE_SIZES = ["small", "large"];
|
|
|
582
582
|
var INVALID_WORKSPACE_SIZE_ERROR = `Invalid size: must be one of ${WORKSPACE_SIZES.join(", ")}`;
|
|
583
583
|
|
|
584
584
|
// ../shared/src/e2b.ts
|
|
585
|
-
var E2B_TEMPLATE_NAME = "replicas-sandbox-2026-07-
|
|
585
|
+
var E2B_TEMPLATE_NAME = "replicas-sandbox-2026-07-22-v1";
|
|
586
586
|
|
|
587
587
|
// ../shared/src/runtime-env.ts
|
|
588
588
|
function shellQuotePosix(value) {
|
|
@@ -1776,7 +1776,7 @@ Pass one or more file paths. Uploading several files in a single invocation is p
|
|
|
1776
1776
|
For each file, the CLI prints two lines:
|
|
1777
1777
|
|
|
1778
1778
|
1. \`\` \u2014 the chat embed (renders inline in Replicas chat **only** \u2014 see below).
|
|
1779
|
-
2. \`View in Replicas: <deep-link>\` \u2014 a per-file dashboard URL of the form \`https://tryreplicas.com/workspaces/<workspace-id>?
|
|
1779
|
+
2. \`View in Replicas: <deep-link>\` \u2014 a per-file dashboard URL of the form \`https://tryreplicas.com/workspaces/<workspace-id>?media=<media-id>\` that opens directly to that specific file.
|
|
1780
1780
|
|
|
1781
1781
|
Match each "View in Replicas" line to the embed line directly above it \u2014 that's the deep link for that file.
|
|
1782
1782
|
|
|
@@ -1794,7 +1794,7 @@ This prints an additional \`Forge embed\` Markdown line backed by an opt-in publ
|
|
|
1794
1794
|
|---|---|---|
|
|
1795
1795
|
| \`https://api.tryreplicas.com/v1/media/<id>\` (inside \`\`) | Authenticated API redirect to a presigned blob \u2014 requires the Replicas chat session | **Only** in the Replicas chat reply. Nowhere else. |
|
|
1796
1796
|
| \`https://api.tryreplicas.com/v1/media/public/<id>/<token>\` | Opt-in public bearer URL printed by \`--share\` | GitHub image embeds only. |
|
|
1797
|
-
| \`https://tryreplicas.com/workspaces/<workspace-id>?
|
|
1797
|
+
| \`https://tryreplicas.com/workspaces/<workspace-id>?media=<media-id>\` | Public dashboard deep link that opens the media file in the workspace | Everywhere external \u2014 Slack, GitHub, Linear, PR bodies, comments, emails. |
|
|
1798
1798
|
|
|
1799
1799
|
### NEVER link the API redirect URL outside the Replicas chat reply
|
|
1800
1800
|
|
|
@@ -1812,14 +1812,12 @@ This rule has no exceptions:
|
|
|
1812
1812
|
When you reference an uploaded file from anywhere outside the Replicas chat reply, the link must be the dashboard form:
|
|
1813
1813
|
|
|
1814
1814
|
\`\`\`
|
|
1815
|
-
https://tryreplicas.com/workspaces/<workspace-id>?
|
|
1815
|
+
https://tryreplicas.com/workspaces/<workspace-id>?media=<media-id>
|
|
1816
1816
|
\`\`\`
|
|
1817
1817
|
|
|
1818
|
-
|
|
1819
|
-
- \`mode=media\` opens the media tab in the dashboard.
|
|
1820
|
-
- \`media=<media-id>\` scrolls to and opens that specific file.
|
|
1818
|
+
The \`media=<media-id>\` query param opens that specific file in the workspace.
|
|
1821
1819
|
|
|
1822
|
-
|
|
1820
|
+
When you have a specific file in mind, never link the bare workspace URL without the \`media=<id>\` param.
|
|
1823
1821
|
|
|
1824
1822
|
Always render as a markdown / mrkdwn hyperlink labeled **View in Replicas** \u2014 never paste a raw URL.
|
|
1825
1823
|
|
|
@@ -1827,14 +1825,14 @@ Always render as a markdown / mrkdwn hyperlink labeled **View in Replicas** \u20
|
|
|
1827
1825
|
|
|
1828
1826
|
Include each markdown embed line **verbatim** where you want that file to render inline. The chat substitutes each one with an embedded image, video, or audio player. Multiple embeds can appear in a single reply.
|
|
1829
1827
|
|
|
1830
|
-
After (or alongside) the embeds, include a \`[View in Replicas](<deep-link>)\` hyperlink for each file using the per-file dashboard URL from the CLI. This lets the user
|
|
1828
|
+
After (or alongside) the embeds, include a \`[View in Replicas](<deep-link>)\` hyperlink for each file using the per-file dashboard URL from the CLI. This lets the user open the specific item in the workspace.
|
|
1831
1829
|
|
|
1832
1830
|
## On external platforms \u2014 upload natively AND link the dashboard
|
|
1833
1831
|
|
|
1834
1832
|
Sharing media externally is a **two-step requirement** for every file:
|
|
1835
1833
|
|
|
1836
1834
|
1. **Upload the raw bytes natively to that platform** so the recipient sees the media embedded inline in the message itself.
|
|
1837
|
-
2. **Link the Replicas dashboard deep link** (\`?
|
|
1835
|
+
2. **Link the Replicas dashboard deep link** (\`?media=<id>\` form) so the user can jump straight to the file in the workspace.
|
|
1838
1836
|
|
|
1839
1837
|
A link alone is not enough. A native upload alone is not enough. Do both.
|
|
1840
1838
|
|
|
@@ -1874,7 +1872,7 @@ curl -s -X POST "https://slack.com/api/files.completeUploadExternal" \\
|
|
|
1874
1872
|
\\"files\\": [{\\"id\\": \\"$FILE_ID\\", \\"title\\": \\"Screenshot\\"}],
|
|
1875
1873
|
\\"channel_id\\": \\"CHANNEL_ID\\",
|
|
1876
1874
|
\\"thread_ts\\": \\"THREAD_TS\\",
|
|
1877
|
-
\\"initial_comment\\": \\"<https://tryreplicas.com/workspaces/<workspace-id>?
|
|
1875
|
+
\\"initial_comment\\": \\"<https://tryreplicas.com/workspaces/<workspace-id>?media=<media-id>|View in Replicas>\\"
|
|
1878
1876
|
}"
|
|
1879
1877
|
\`\`\`
|
|
1880
1878
|
|
|
@@ -1934,7 +1932,7 @@ curl -s -X PUT "$UPLOAD_URL" \\
|
|
|
1934
1932
|
--data-binary @"$FILE"
|
|
1935
1933
|
|
|
1936
1934
|
# 3. Reference assetUrl inline in the comment body, alongside the dashboard link.
|
|
1937
|
-
BODY=$(printf '\\n\\n[View in Replicas](https://tryreplicas.com/workspaces/%s?
|
|
1935
|
+
BODY=$(printf '\\n\\n[View in Replicas](https://tryreplicas.com/workspaces/%s?media=%s)' \\
|
|
1938
1936
|
"$ASSET_URL" "$WORKSPACE_ID" "$MEDIA_ID")
|
|
1939
1937
|
|
|
1940
1938
|
jq -n \\
|
|
@@ -4745,7 +4743,6 @@ function loadEngineEnv() {
|
|
|
4745
4743
|
WORKSPACE_ROOT: join2(HOME_DIR, "workspaces"),
|
|
4746
4744
|
// Runtime: may not be set during warming
|
|
4747
4745
|
WORKSPACE_ID: readEnv("WORKSPACE_ID"),
|
|
4748
|
-
WORKSPACE_BRANCH_NAME: readEnv("WORKSPACE_BRANCH_NAME"),
|
|
4749
4746
|
LINEAR_SESSION_ID: readEnv("LINEAR_SESSION_ID"),
|
|
4750
4747
|
LINEAR_ACCESS_TOKEN: readEnv("LINEAR_ACCESS_TOKEN"),
|
|
4751
4748
|
SLACK_BOT_TOKEN: readEnv("SLACK_BOT_TOKEN"),
|
|
@@ -5695,84 +5692,6 @@ var GitService = class {
|
|
|
5695
5692
|
}
|
|
5696
5693
|
return branches;
|
|
5697
5694
|
}
|
|
5698
|
-
async setBranchNameAndCheckout(name) {
|
|
5699
|
-
ENGINE_ENV.WORKSPACE_BRANCH_NAME = name;
|
|
5700
|
-
return this.initializeGitRepository();
|
|
5701
|
-
}
|
|
5702
|
-
async initializeGitRepository() {
|
|
5703
|
-
const workspaceName = ENGINE_ENV.WORKSPACE_BRANCH_NAME;
|
|
5704
|
-
if (!workspaceName) {
|
|
5705
|
-
console.info("No WORKSPACE_BRANCH_NAME set \u2014 skipping branch checkout");
|
|
5706
|
-
return {
|
|
5707
|
-
success: true,
|
|
5708
|
-
repos: []
|
|
5709
|
-
};
|
|
5710
|
-
}
|
|
5711
|
-
const repos = await this.listRepositories();
|
|
5712
|
-
if (repos.length === 0) {
|
|
5713
|
-
return {
|
|
5714
|
-
success: true,
|
|
5715
|
-
repos: []
|
|
5716
|
-
};
|
|
5717
|
-
}
|
|
5718
|
-
const results = [];
|
|
5719
|
-
for (const repo of repos) {
|
|
5720
|
-
if (!this.pathExists(repo.path)) {
|
|
5721
|
-
results.push({ name: repo.name, success: true, currentBranch: repo.defaultBranch });
|
|
5722
|
-
continue;
|
|
5723
|
-
}
|
|
5724
|
-
try {
|
|
5725
|
-
const baselineState = {
|
|
5726
|
-
name: repo.name,
|
|
5727
|
-
path: repo.path,
|
|
5728
|
-
defaultBranch: repo.defaultBranch,
|
|
5729
|
-
currentBranch: repo.defaultBranch,
|
|
5730
|
-
prUrls: [],
|
|
5731
|
-
gitDiff: null,
|
|
5732
|
-
startHooksCompleted: false
|
|
5733
|
-
};
|
|
5734
|
-
const persistedState = await loadRepoState(repo.name);
|
|
5735
|
-
const persistedBranch = persistedState?.currentBranch;
|
|
5736
|
-
if (persistedBranch && await branchExists(persistedBranch, repo.path)) {
|
|
5737
|
-
const currentBranch = await getCurrentBranch(repo.path);
|
|
5738
|
-
if (currentBranch !== persistedBranch) {
|
|
5739
|
-
await this.checkoutWithoutHooks([persistedBranch], repo.path);
|
|
5740
|
-
}
|
|
5741
|
-
results.push({
|
|
5742
|
-
name: repo.name,
|
|
5743
|
-
success: true,
|
|
5744
|
-
currentBranch: persistedBranch,
|
|
5745
|
-
resumed: true
|
|
5746
|
-
});
|
|
5747
|
-
continue;
|
|
5748
|
-
}
|
|
5749
|
-
await this.checkoutWithoutHooks([repo.defaultBranch], repo.path);
|
|
5750
|
-
const branchName = await this.findAvailableBranchName(workspaceName, repo.path);
|
|
5751
|
-
await this.checkoutWithoutHooks(["-b", branchName], repo.path);
|
|
5752
|
-
await saveRepoState(repo.name, { currentBranch: branchName }, baselineState);
|
|
5753
|
-
results.push({
|
|
5754
|
-
name: repo.name,
|
|
5755
|
-
success: true,
|
|
5756
|
-
currentBranch: branchName,
|
|
5757
|
-
resumed: false
|
|
5758
|
-
});
|
|
5759
|
-
} catch (error) {
|
|
5760
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
5761
|
-
results.push({
|
|
5762
|
-
name: repo.name,
|
|
5763
|
-
success: false,
|
|
5764
|
-
currentBranch: repo.defaultBranch,
|
|
5765
|
-
error: errorMessage
|
|
5766
|
-
});
|
|
5767
|
-
}
|
|
5768
|
-
}
|
|
5769
|
-
const failed = results.filter((result) => !result.success);
|
|
5770
|
-
return {
|
|
5771
|
-
success: failed.length === 0,
|
|
5772
|
-
repos: results,
|
|
5773
|
-
error: failed.length > 0 ? `Git init failed for ${failed.length} repo(s)` : void 0
|
|
5774
|
-
};
|
|
5775
|
-
}
|
|
5776
5695
|
getGitDiffStats(repoPath, defaultBranch) {
|
|
5777
5696
|
return this.diffStatsInFlight.run(repoPath, async () => {
|
|
5778
5697
|
try {
|
|
@@ -6110,20 +6029,6 @@ var GitService = class {
|
|
|
6110
6029
|
return null;
|
|
6111
6030
|
}
|
|
6112
6031
|
}
|
|
6113
|
-
async findAvailableBranchName(baseName, cwd) {
|
|
6114
|
-
const sanitizedBaseName = this.sanitizeBranchName(baseName);
|
|
6115
|
-
if (!await branchExists(sanitizedBaseName, cwd)) {
|
|
6116
|
-
return sanitizedBaseName;
|
|
6117
|
-
}
|
|
6118
|
-
return `${sanitizedBaseName}-${Date.now()}`;
|
|
6119
|
-
}
|
|
6120
|
-
checkoutWithoutHooks(args, cwd) {
|
|
6121
|
-
return runGitCommand(["-c", "core.hooksPath=/dev/null", "checkout", ...args], cwd);
|
|
6122
|
-
}
|
|
6123
|
-
sanitizeBranchName(name) {
|
|
6124
|
-
const normalized = name.toLowerCase().replace(/[^a-z0-9._/-]+/g, "-").replace(/\/{2,}/g, "/").replace(/^-+|-+$/g, "");
|
|
6125
|
-
return normalized || "replicas";
|
|
6126
|
-
}
|
|
6127
6032
|
async refreshRepoMetadata(repo, currentBranch, startHooksCompleted, persistedState, observedBranches, includeDiffs = false) {
|
|
6128
6033
|
const prResult = await this.getPullRequestUrl(repo.name, repo.path, currentBranch, persistedState);
|
|
6129
6034
|
let prUrls = persistedState?.prUrls ?? [];
|
|
@@ -9906,7 +9811,7 @@ var DEFAULT_CODEX_ARGS = ["app-server", "--listen", "stdio://"];
|
|
|
9906
9811
|
var MIN_CODEX_CLI_VERSION = "0.144.6";
|
|
9907
9812
|
var CODEX_UPGRADE_TIMEOUT_MS = 12e4;
|
|
9908
9813
|
var codexCliVersionEnsured = null;
|
|
9909
|
-
var ENGINE_PACKAGE_VERSION = "0.1.
|
|
9814
|
+
var ENGINE_PACKAGE_VERSION = "0.1.476";
|
|
9910
9815
|
var INITIALIZE_METHOD = "initialize";
|
|
9911
9816
|
var INITIALIZED_NOTIFICATION = "initialized";
|
|
9912
9817
|
var ACCOUNT_LOGIN_START_METHOD = "account/login/start";
|
|
@@ -15927,9 +15832,6 @@ var TerminalService = class {
|
|
|
15927
15832
|
var terminalService = new TerminalService();
|
|
15928
15833
|
|
|
15929
15834
|
// src/v1-routes.ts
|
|
15930
|
-
var setWorkspaceNameSchema = z6.object({
|
|
15931
|
-
name: z6.string().min(1).max(48)
|
|
15932
|
-
});
|
|
15933
15835
|
var imageMediaTypeSchema = z6.enum(IMAGE_MEDIA_TYPES);
|
|
15934
15836
|
var createPreviewSchema = z6.object({
|
|
15935
15837
|
port: z6.number().int().min(1).max(65535),
|
|
@@ -16716,17 +16618,7 @@ data: ${JSON.stringify("Terminal session not found")}
|
|
|
16716
16618
|
}
|
|
16717
16619
|
});
|
|
16718
16620
|
app2.post("/workspace-name", async (c) => {
|
|
16719
|
-
|
|
16720
|
-
const body = setWorkspaceNameSchema.parse(await c.req.json());
|
|
16721
|
-
const result = await gitService.setBranchNameAndCheckout(body.name);
|
|
16722
|
-
return c.json({
|
|
16723
|
-
success: result.success,
|
|
16724
|
-
repos: result.repos.map((r) => ({ name: r.name, branch: r.currentBranch, resumed: r.resumed ?? false }))
|
|
16725
|
-
});
|
|
16726
|
-
} catch (error) {
|
|
16727
|
-
const details = error instanceof Error ? error.message : "Unknown error";
|
|
16728
|
-
return c.json(jsonError("Failed to set workspace name", details), 400);
|
|
16729
|
-
}
|
|
16621
|
+
return c.json({ success: true, repos: [] });
|
|
16730
16622
|
});
|
|
16731
16623
|
app2.get("/previews", async (c) => {
|
|
16732
16624
|
try {
|
|
@@ -17167,10 +17059,6 @@ serve(
|
|
|
17167
17059
|
console.log(`Replicas Engine running on port ${info.port}`);
|
|
17168
17060
|
}
|
|
17169
17061
|
await timeStartupStep("wait_for_initialization_gate", waitForInitializationGate);
|
|
17170
|
-
const gitResult = await timeStartupStep("git_initialize", () => gitService.initializeGitRepository());
|
|
17171
|
-
if (!gitResult.success && gitResult.error) {
|
|
17172
|
-
console.warn(`Git initialization warning: ${gitResult.error}`);
|
|
17173
|
-
}
|
|
17174
17062
|
if (!IS_WARMING_MODE) {
|
|
17175
17063
|
await timeStartupStep("replicas_config_initialize", () => replicasConfigService.initialize());
|
|
17176
17064
|
}
|