replicas-engine 0.1.259 → 0.1.260
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/README.md +6 -6
- package/dist/src/index.js +97 -46
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -31,10 +31,10 @@ Chats:
|
|
|
31
31
|
- `POST /chats/:chatId/messages`
|
|
32
32
|
- `POST /chats/:chatId/interrupt`
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
Canvas:
|
|
35
35
|
|
|
36
|
-
- `GET /
|
|
37
|
-
- `GET /
|
|
36
|
+
- `GET /canvas`
|
|
37
|
+
- `GET /canvas/:filename`
|
|
38
38
|
|
|
39
39
|
Repos and hooks:
|
|
40
40
|
|
|
@@ -93,9 +93,9 @@ Engine persistence locations:
|
|
|
93
93
|
- `~/.replicas/engine/events.jsonl`
|
|
94
94
|
- `~/.replicas/engine-state.json`
|
|
95
95
|
- `~/.replicas/startHooks.log`
|
|
96
|
-
-
|
|
97
|
-
- `~/.claude/plans`
|
|
98
|
-
- `~/.replicas/
|
|
96
|
+
- Canvas read locations (for `/canvas` endpoints):
|
|
97
|
+
- `~/.claude/plans` (where Claude Code writes its plans)
|
|
98
|
+
- `~/.replicas/canvas`
|
|
99
99
|
- Health endpoint readiness signal file:
|
|
100
100
|
- `/var/log/cloud-init-output.log` (if missing, `/health` reports `initializing`)
|
|
101
101
|
|
package/dist/src/index.js
CHANGED
|
@@ -286,7 +286,7 @@ var WORKSPACE_SIZES = ["small", "large"];
|
|
|
286
286
|
var INVALID_WORKSPACE_SIZE_ERROR = `Invalid size: must be one of ${WORKSPACE_SIZES.join(", ")}`;
|
|
287
287
|
|
|
288
288
|
// ../shared/src/e2b.ts
|
|
289
|
-
var E2B_TEMPLATE_NAME = "replicas-sandbox-2026-06-04-
|
|
289
|
+
var E2B_TEMPLATE_NAME = "replicas-sandbox-2026-06-04-v2";
|
|
290
290
|
|
|
291
291
|
// ../shared/src/runtime-env.ts
|
|
292
292
|
function parsePosixEnvFile(content) {
|
|
@@ -1839,6 +1839,29 @@ var MODEL_LABELS = {
|
|
|
1839
1839
|
"gpt-5": "GPT-5"
|
|
1840
1840
|
};
|
|
1841
1841
|
var IMAGE_MEDIA_TYPES = ["image/png", "image/jpeg", "image/gif", "image/webp"];
|
|
1842
|
+
var CANVAS_KIND_BY_EXTENSION = {
|
|
1843
|
+
".md": { kind: "markdown", mimeType: "text/markdown; charset=utf-8" },
|
|
1844
|
+
".markdown": { kind: "markdown", mimeType: "text/markdown; charset=utf-8" },
|
|
1845
|
+
".html": { kind: "html", mimeType: "text/html; charset=utf-8" },
|
|
1846
|
+
".htm": { kind: "html", mimeType: "text/html; charset=utf-8" },
|
|
1847
|
+
".png": { kind: "image", mimeType: "image/png" },
|
|
1848
|
+
".jpg": { kind: "image", mimeType: "image/jpeg" },
|
|
1849
|
+
".jpeg": { kind: "image", mimeType: "image/jpeg" },
|
|
1850
|
+
".gif": { kind: "image", mimeType: "image/gif" },
|
|
1851
|
+
".webp": { kind: "image", mimeType: "image/webp" },
|
|
1852
|
+
".svg": { kind: "image", mimeType: "image/svg+xml" },
|
|
1853
|
+
".mp4": { kind: "video", mimeType: "video/mp4" },
|
|
1854
|
+
".webm": { kind: "video", mimeType: "video/webm" },
|
|
1855
|
+
".mov": { kind: "video", mimeType: "video/quicktime" },
|
|
1856
|
+
".mp3": { kind: "audio", mimeType: "audio/mpeg" },
|
|
1857
|
+
".wav": { kind: "audio", mimeType: "audio/wav" },
|
|
1858
|
+
".ogg": { kind: "audio", mimeType: "audio/ogg" }
|
|
1859
|
+
};
|
|
1860
|
+
function classifyCanvasFilename(filename) {
|
|
1861
|
+
const idx = filename.lastIndexOf(".");
|
|
1862
|
+
const ext = idx === -1 ? "" : filename.slice(idx).toLowerCase();
|
|
1863
|
+
return CANVAS_KIND_BY_EXTENSION[ext] ?? { kind: "other", mimeType: "application/octet-stream" };
|
|
1864
|
+
}
|
|
1842
1865
|
|
|
1843
1866
|
// ../shared/src/engine/v1.ts
|
|
1844
1867
|
var MERGED_MESSAGE_SEPARATOR = "\n\n<!-- replicas:merged -->\n\n";
|
|
@@ -6349,7 +6372,7 @@ var AspClient = class {
|
|
|
6349
6372
|
// src/managers/codex-asp/app-server-process.ts
|
|
6350
6373
|
var DEFAULT_CODEX_BINARY = "codex";
|
|
6351
6374
|
var DEFAULT_CODEX_ARGS = ["app-server", "--listen", "stdio://"];
|
|
6352
|
-
var ENGINE_PACKAGE_VERSION = "0.1.
|
|
6375
|
+
var ENGINE_PACKAGE_VERSION = "0.1.260";
|
|
6353
6376
|
var INITIALIZE_METHOD = "initialize";
|
|
6354
6377
|
var INITIALIZED_NOTIFICATION = "initialized";
|
|
6355
6378
|
var ACCOUNT_LOGIN_START_METHOD = "account/login/start";
|
|
@@ -9904,60 +9927,88 @@ var RepoFileService = class {
|
|
|
9904
9927
|
// src/v1-routes.ts
|
|
9905
9928
|
import { Hono } from "hono";
|
|
9906
9929
|
import { z as z2 } from "zod";
|
|
9907
|
-
import { readdir as readdir6, stat as
|
|
9930
|
+
import { readdir as readdir6, stat as stat5, readFile as readFile14 } from "fs/promises";
|
|
9908
9931
|
import { join as join20, resolve as resolve2 } from "path";
|
|
9909
9932
|
|
|
9910
|
-
// src/services/
|
|
9911
|
-
import { readdir as readdir4, readFile as readFile11 } from "fs/promises";
|
|
9933
|
+
// src/services/canvas-service.ts
|
|
9934
|
+
import { readdir as readdir4, readFile as readFile11, stat as stat4 } from "fs/promises";
|
|
9912
9935
|
import { homedir as homedir14 } from "os";
|
|
9913
9936
|
import { basename, join as join17 } from "path";
|
|
9914
|
-
var
|
|
9937
|
+
var CANVAS_DIRECTORIES = [
|
|
9915
9938
|
join17(homedir14(), ".claude", "plans"),
|
|
9916
|
-
join17(homedir14(), ".replicas", "
|
|
9939
|
+
join17(homedir14(), ".replicas", "canvas")
|
|
9917
9940
|
];
|
|
9918
|
-
|
|
9919
|
-
|
|
9941
|
+
var MAX_CANVAS_FILE_BYTES = 5 * 1024 * 1024;
|
|
9942
|
+
function isTextKind(kind) {
|
|
9943
|
+
return kind === "markdown" || kind === "html";
|
|
9920
9944
|
}
|
|
9921
|
-
function
|
|
9945
|
+
function sanitizeFilename(filename) {
|
|
9922
9946
|
return basename(filename);
|
|
9923
9947
|
}
|
|
9924
|
-
var
|
|
9925
|
-
async
|
|
9926
|
-
const
|
|
9927
|
-
for (const directory of
|
|
9948
|
+
var CanvasService = class {
|
|
9949
|
+
async listItems() {
|
|
9950
|
+
const items = /* @__PURE__ */ new Map();
|
|
9951
|
+
for (const directory of CANVAS_DIRECTORIES) {
|
|
9952
|
+
let entries;
|
|
9928
9953
|
try {
|
|
9929
|
-
|
|
9930
|
-
for (const entry of entries) {
|
|
9931
|
-
if (!entry.isFile()) {
|
|
9932
|
-
continue;
|
|
9933
|
-
}
|
|
9934
|
-
if (!isMarkdownFile(entry.name)) {
|
|
9935
|
-
continue;
|
|
9936
|
-
}
|
|
9937
|
-
planNames.add(entry.name);
|
|
9938
|
-
}
|
|
9954
|
+
entries = await readdir4(directory, { withFileTypes: true });
|
|
9939
9955
|
} catch {
|
|
9956
|
+
continue;
|
|
9957
|
+
}
|
|
9958
|
+
for (const entry of entries) {
|
|
9959
|
+
if (!entry.isFile()) continue;
|
|
9960
|
+
if (entry.name.startsWith(".")) continue;
|
|
9961
|
+
if (items.has(entry.name)) continue;
|
|
9962
|
+
const { kind } = classifyCanvasFilename(entry.name);
|
|
9963
|
+
let sizeBytes = 0;
|
|
9964
|
+
try {
|
|
9965
|
+
const s = await stat4(join17(directory, entry.name));
|
|
9966
|
+
sizeBytes = s.size;
|
|
9967
|
+
} catch {
|
|
9968
|
+
continue;
|
|
9969
|
+
}
|
|
9970
|
+
items.set(entry.name, { filename: entry.name, kind, sizeBytes });
|
|
9940
9971
|
}
|
|
9941
9972
|
}
|
|
9942
|
-
return Array.from(
|
|
9973
|
+
return Array.from(items.values()).sort((a, b) => a.filename.localeCompare(b.filename));
|
|
9943
9974
|
}
|
|
9944
|
-
async
|
|
9945
|
-
const
|
|
9946
|
-
if (!
|
|
9947
|
-
|
|
9948
|
-
|
|
9949
|
-
|
|
9950
|
-
|
|
9975
|
+
async getItem(filename) {
|
|
9976
|
+
const safe = sanitizeFilename(filename);
|
|
9977
|
+
if (!safe || safe !== filename || safe.startsWith(".")) return null;
|
|
9978
|
+
const { kind, mimeType } = classifyCanvasFilename(safe);
|
|
9979
|
+
for (const directory of CANVAS_DIRECTORIES) {
|
|
9980
|
+
const filePath = join17(directory, safe);
|
|
9981
|
+
let sizeBytes = 0;
|
|
9951
9982
|
try {
|
|
9952
|
-
const
|
|
9953
|
-
|
|
9983
|
+
const s = await stat4(filePath);
|
|
9984
|
+
sizeBytes = s.size;
|
|
9954
9985
|
} catch {
|
|
9986
|
+
continue;
|
|
9987
|
+
}
|
|
9988
|
+
if (sizeBytes > MAX_CANVAS_FILE_BYTES) {
|
|
9989
|
+
return {
|
|
9990
|
+
filename: safe,
|
|
9991
|
+
kind,
|
|
9992
|
+
sizeBytes,
|
|
9993
|
+
mimeType,
|
|
9994
|
+
tooLarge: true
|
|
9995
|
+
};
|
|
9996
|
+
}
|
|
9997
|
+
try {
|
|
9998
|
+
if (isTextKind(kind)) {
|
|
9999
|
+
const content = await readFile11(filePath, "utf-8");
|
|
10000
|
+
return { filename: safe, kind, sizeBytes, mimeType, content };
|
|
10001
|
+
}
|
|
10002
|
+
const buf = await readFile11(filePath);
|
|
10003
|
+
return { filename: safe, kind, sizeBytes, mimeType, base64: buf.toString("base64") };
|
|
10004
|
+
} catch {
|
|
10005
|
+
continue;
|
|
9955
10006
|
}
|
|
9956
10007
|
}
|
|
9957
10008
|
return null;
|
|
9958
10009
|
}
|
|
9959
10010
|
};
|
|
9960
|
-
var
|
|
10011
|
+
var canvasService = new CanvasService();
|
|
9961
10012
|
|
|
9962
10013
|
// src/services/warm-hooks-service.ts
|
|
9963
10014
|
import { spawn as spawn4 } from "child_process";
|
|
@@ -10648,31 +10699,31 @@ function createV1Routes(deps) {
|
|
|
10648
10699
|
}
|
|
10649
10700
|
return c.json(result);
|
|
10650
10701
|
});
|
|
10651
|
-
app2.get("/
|
|
10702
|
+
app2.get("/canvas", async (c) => {
|
|
10652
10703
|
try {
|
|
10653
|
-
const
|
|
10654
|
-
return c.json({
|
|
10704
|
+
const items = await canvasService.listItems();
|
|
10705
|
+
return c.json({ items });
|
|
10655
10706
|
} catch (error) {
|
|
10656
10707
|
return c.json(
|
|
10657
|
-
jsonError("Failed to list
|
|
10708
|
+
jsonError("Failed to list canvas items", error instanceof Error ? error.message : "Unknown error"),
|
|
10658
10709
|
500
|
|
10659
10710
|
);
|
|
10660
10711
|
}
|
|
10661
10712
|
});
|
|
10662
|
-
app2.get("/
|
|
10713
|
+
app2.get("/canvas/:filename", async (c) => {
|
|
10663
10714
|
try {
|
|
10664
10715
|
const filename = c.req.param("filename");
|
|
10665
10716
|
if (!filename) {
|
|
10666
10717
|
return c.json(jsonError("Filename required"), 400);
|
|
10667
10718
|
}
|
|
10668
|
-
const
|
|
10669
|
-
if (!
|
|
10670
|
-
return c.json(jsonError("
|
|
10719
|
+
const item = await canvasService.getItem(filename);
|
|
10720
|
+
if (!item) {
|
|
10721
|
+
return c.json(jsonError("Canvas item not found"), 404);
|
|
10671
10722
|
}
|
|
10672
|
-
return c.json(
|
|
10723
|
+
return c.json(item);
|
|
10673
10724
|
} catch (error) {
|
|
10674
10725
|
return c.json(
|
|
10675
|
-
jsonError("Failed to read
|
|
10726
|
+
jsonError("Failed to read canvas item", error instanceof Error ? error.message : "Unknown error"),
|
|
10676
10727
|
500
|
|
10677
10728
|
);
|
|
10678
10729
|
}
|
|
@@ -10986,7 +11037,7 @@ function createV1Routes(deps) {
|
|
|
10986
11037
|
const sessions = await Promise.all(
|
|
10987
11038
|
logFiles.map(async (filename) => {
|
|
10988
11039
|
const filePath = join20(LOG_DIR, filename);
|
|
10989
|
-
const fileStat = await
|
|
11040
|
+
const fileStat = await stat5(filePath);
|
|
10990
11041
|
const sessionId = filename.replace(/\.log$/, "");
|
|
10991
11042
|
return {
|
|
10992
11043
|
sessionId,
|