replicas-engine 0.1.289 → 0.1.291
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 +96 -34
- package/package.json +1 -1
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-09-
|
|
289
|
+
var E2B_TEMPLATE_NAME = "replicas-sandbox-2026-06-09-v5";
|
|
290
290
|
|
|
291
291
|
// ../shared/src/runtime-env.ts
|
|
292
292
|
function parsePosixEnvFile(content) {
|
|
@@ -4747,7 +4747,7 @@ async function registerDesktopPreview() {
|
|
|
4747
4747
|
|
|
4748
4748
|
// src/services/chat/chat-service.ts
|
|
4749
4749
|
import { existsSync as existsSync7 } from "fs";
|
|
4750
|
-
import { appendFile as
|
|
4750
|
+
import { appendFile as appendFile4, copyFile, mkdir as mkdir11, readFile as readFile9, rename as rename2, rm } from "fs/promises";
|
|
4751
4751
|
import { homedir as homedir12 } from "os";
|
|
4752
4752
|
import { join as join14 } from "path";
|
|
4753
4753
|
import { randomUUID as randomUUID5 } from "crypto";
|
|
@@ -6594,7 +6594,7 @@ var AspClient = class {
|
|
|
6594
6594
|
// src/managers/codex-asp/app-server-process.ts
|
|
6595
6595
|
var DEFAULT_CODEX_BINARY = "codex";
|
|
6596
6596
|
var DEFAULT_CODEX_ARGS = ["app-server", "--listen", "stdio://"];
|
|
6597
|
-
var ENGINE_PACKAGE_VERSION = "0.1.
|
|
6597
|
+
var ENGINE_PACKAGE_VERSION = "0.1.291";
|
|
6598
6598
|
var INITIALIZE_METHOD = "initialize";
|
|
6599
6599
|
var INITIALIZED_NOTIFICATION = "initialized";
|
|
6600
6600
|
var ACCOUNT_LOGIN_START_METHOD = "account/login/start";
|
|
@@ -7396,11 +7396,56 @@ var TranscriptUpdateCoalescer = class {
|
|
|
7396
7396
|
}
|
|
7397
7397
|
};
|
|
7398
7398
|
|
|
7399
|
+
// src/managers/codex-asp/codex-history-file.ts
|
|
7400
|
+
import { appendFile as appendFile3, readFile as readFile8 } from "fs/promises";
|
|
7401
|
+
function parseCodexHistoryJsonl(content) {
|
|
7402
|
+
const events = [];
|
|
7403
|
+
let transcript = null;
|
|
7404
|
+
for (const event of parseAgentEventJsonl(content)) {
|
|
7405
|
+
if (event.type !== CODEX_ASP_TRANSCRIPT_UPDATED_EVENT_TYPE) {
|
|
7406
|
+
events.push(event);
|
|
7407
|
+
continue;
|
|
7408
|
+
}
|
|
7409
|
+
const delta = event.payload.transcriptDelta;
|
|
7410
|
+
if (isCodexAspTranscriptDelta(delta)) {
|
|
7411
|
+
transcript = applyCodexAspTranscriptDelta(transcript, delta);
|
|
7412
|
+
} else if (isCodexAspTranscript(event.payload.transcript)) {
|
|
7413
|
+
transcript = event.payload.transcript;
|
|
7414
|
+
}
|
|
7415
|
+
}
|
|
7416
|
+
return { events, transcript };
|
|
7417
|
+
}
|
|
7418
|
+
var CodexHistoryFile = class {
|
|
7419
|
+
constructor(filePath) {
|
|
7420
|
+
this.filePath = filePath;
|
|
7421
|
+
}
|
|
7422
|
+
filePath;
|
|
7423
|
+
writeChain = Promise.resolve();
|
|
7424
|
+
/** Best-effort ordered append; failures must not disrupt the turn. */
|
|
7425
|
+
append(event) {
|
|
7426
|
+
this.writeChain = this.writeChain.then(() => appendFile3(this.filePath, JSON.stringify(event) + "\n", "utf-8")).catch((error) => {
|
|
7427
|
+
console.error("[CodexHistoryFile] Failed to append event:", error);
|
|
7428
|
+
});
|
|
7429
|
+
}
|
|
7430
|
+
async load() {
|
|
7431
|
+
try {
|
|
7432
|
+
const content = await readFile8(this.filePath, "utf-8");
|
|
7433
|
+
return parseCodexHistoryJsonl(content);
|
|
7434
|
+
} catch (error) {
|
|
7435
|
+
if (!(error && typeof error === "object" && "code" in error && error.code === "ENOENT")) {
|
|
7436
|
+
console.error("[CodexHistoryFile] Failed to load history file:", error);
|
|
7437
|
+
}
|
|
7438
|
+
return { events: [], transcript: null };
|
|
7439
|
+
}
|
|
7440
|
+
}
|
|
7441
|
+
};
|
|
7442
|
+
|
|
7399
7443
|
// src/managers/codex-asp/codex-asp-manager.ts
|
|
7400
7444
|
var CodexAspManager = class extends CodingAgentManager {
|
|
7401
7445
|
currentThreadId = null;
|
|
7402
7446
|
activeTurnId = null;
|
|
7403
7447
|
threadAttached = false;
|
|
7448
|
+
historyFile;
|
|
7404
7449
|
historyEvents = [];
|
|
7405
7450
|
codexAspTranscript = null;
|
|
7406
7451
|
lastEmittedTranscripts = /* @__PURE__ */ new Map();
|
|
@@ -7412,12 +7457,18 @@ var CodexAspManager = class extends CodingAgentManager {
|
|
|
7412
7457
|
});
|
|
7413
7458
|
constructor(options) {
|
|
7414
7459
|
super(options);
|
|
7460
|
+
this.historyFile = options.historyFilePath ? new CodexHistoryFile(options.historyFilePath) : null;
|
|
7415
7461
|
this.initializeManager(this.processMessageInternal.bind(this));
|
|
7416
7462
|
}
|
|
7417
7463
|
async initialize() {
|
|
7418
|
-
|
|
7419
|
-
|
|
7464
|
+
const replayed = await this.historyFile?.load();
|
|
7465
|
+
if (replayed) {
|
|
7466
|
+
this.historyEvents.push(...replayed.events);
|
|
7467
|
+
if (replayed.transcript) {
|
|
7468
|
+
this.mergeTranscriptSnapshot(replayed.transcript);
|
|
7469
|
+
}
|
|
7420
7470
|
}
|
|
7471
|
+
this.currentThreadId = this.initialSessionId ?? replayed?.transcript?.threadId ?? null;
|
|
7421
7472
|
}
|
|
7422
7473
|
async interruptActiveTurn() {
|
|
7423
7474
|
if (!this.currentThreadId || !this.activeTurnId) {
|
|
@@ -8131,9 +8182,13 @@ var CodexAspManager = class extends CodingAgentManager {
|
|
|
8131
8182
|
type,
|
|
8132
8183
|
payload
|
|
8133
8184
|
};
|
|
8134
|
-
this.
|
|
8185
|
+
this.trackHistoryEvent(event);
|
|
8135
8186
|
return event;
|
|
8136
8187
|
}
|
|
8188
|
+
trackHistoryEvent(event) {
|
|
8189
|
+
this.historyEvents.push(event);
|
|
8190
|
+
this.historyFile?.append(event);
|
|
8191
|
+
}
|
|
8137
8192
|
emitTranscriptUpdated(threadId, options = {}) {
|
|
8138
8193
|
this.transcriptUpdateCoalescer.schedule(threadId, options);
|
|
8139
8194
|
}
|
|
@@ -8226,11 +8281,13 @@ var CodexAspManager = class extends CodingAgentManager {
|
|
|
8226
8281
|
this.lastEmittedTranscripts.delete(emittedThreadId);
|
|
8227
8282
|
}
|
|
8228
8283
|
}
|
|
8229
|
-
|
|
8284
|
+
const event = {
|
|
8230
8285
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
8231
8286
|
type: CODEX_ASP_TRANSCRIPT_UPDATED_EVENT_TYPE,
|
|
8232
8287
|
payload: updatePayload
|
|
8233
|
-
}
|
|
8288
|
+
};
|
|
8289
|
+
this.historyFile?.append(event);
|
|
8290
|
+
this.onEvent(event);
|
|
8234
8291
|
}
|
|
8235
8292
|
handleRateLimits(rateLimits) {
|
|
8236
8293
|
const snapshot = extractRateLimitsSnapshot(rateLimits);
|
|
@@ -8251,7 +8308,7 @@ var CodexAspManager = class extends CodingAgentManager {
|
|
|
8251
8308
|
emitQuotaStatus(snapshot, force = false) {
|
|
8252
8309
|
const event = this.quotaStatus.apply(snapshot, force);
|
|
8253
8310
|
if (!event) return;
|
|
8254
|
-
this.
|
|
8311
|
+
this.trackHistoryEvent(event);
|
|
8255
8312
|
this.onEvent(event);
|
|
8256
8313
|
}
|
|
8257
8314
|
emitCodexTokenUsage(tokenUsage, model) {
|
|
@@ -8271,7 +8328,7 @@ var CodexAspManager = class extends CodingAgentManager {
|
|
|
8271
8328
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
8272
8329
|
});
|
|
8273
8330
|
const event = this.emitContextUsage(payload);
|
|
8274
|
-
this.
|
|
8331
|
+
this.trackHistoryEvent(event);
|
|
8275
8332
|
}
|
|
8276
8333
|
};
|
|
8277
8334
|
|
|
@@ -8881,6 +8938,12 @@ var ENGINE_DIR2 = join14(homedir12(), ".replicas", "engine");
|
|
|
8881
8938
|
var CHATS_FILE = join14(ENGINE_DIR2, "chats.json");
|
|
8882
8939
|
var CLAUDE_HISTORY_DIR = join14(ENGINE_DIR2, "claude-histories");
|
|
8883
8940
|
var RELAY_HISTORY_DIR = join14(ENGINE_DIR2, "relay-histories");
|
|
8941
|
+
var CODEX_HISTORY_DIR = join14(ENGINE_DIR2, "codex-histories");
|
|
8942
|
+
var HISTORY_DIR_BY_PROVIDER = {
|
|
8943
|
+
claude: CLAUDE_HISTORY_DIR,
|
|
8944
|
+
relay: RELAY_HISTORY_DIR,
|
|
8945
|
+
codex: CODEX_HISTORY_DIR
|
|
8946
|
+
};
|
|
8884
8947
|
var CHAT_SENDERS_DIR = join14(ENGINE_DIR2, "chat-senders");
|
|
8885
8948
|
var CODEX_AUTH_PATH2 = join14(homedir12(), ".codex", "auth.json");
|
|
8886
8949
|
var CHATS_BACKUP_FILE = `${CHATS_FILE}.bak`;
|
|
@@ -8981,6 +9044,7 @@ var ChatService = class {
|
|
|
8981
9044
|
await mkdir11(ENGINE_DIR2, { recursive: true });
|
|
8982
9045
|
await mkdir11(CLAUDE_HISTORY_DIR, { recursive: true });
|
|
8983
9046
|
await mkdir11(RELAY_HISTORY_DIR, { recursive: true });
|
|
9047
|
+
await mkdir11(CODEX_HISTORY_DIR, { recursive: true });
|
|
8984
9048
|
await mkdir11(CHAT_SENDERS_DIR, { recursive: true });
|
|
8985
9049
|
const persisted = await this.loadChats();
|
|
8986
9050
|
for (const chat of persisted) {
|
|
@@ -9083,14 +9147,14 @@ var ChatService = class {
|
|
|
9083
9147
|
}
|
|
9084
9148
|
async appendSender(chatId, sender) {
|
|
9085
9149
|
try {
|
|
9086
|
-
await
|
|
9150
|
+
await appendFile4(this.senderFilePath(chatId), JSON.stringify(sender) + "\n", "utf-8");
|
|
9087
9151
|
} catch (error) {
|
|
9088
9152
|
console.error("[ChatService] Failed to append sender record:", error);
|
|
9089
9153
|
}
|
|
9090
9154
|
}
|
|
9091
9155
|
async readSenders(chatId) {
|
|
9092
9156
|
try {
|
|
9093
|
-
const content = await
|
|
9157
|
+
const content = await readFile9(this.senderFilePath(chatId), "utf-8");
|
|
9094
9158
|
const lines = content.split("\n").filter((line) => line.trim().length > 0);
|
|
9095
9159
|
const senders = [];
|
|
9096
9160
|
for (const line of lines) {
|
|
@@ -9227,10 +9291,7 @@ var ChatService = class {
|
|
|
9227
9291
|
return descendants;
|
|
9228
9292
|
}
|
|
9229
9293
|
async deleteHistoryFile(persisted) {
|
|
9230
|
-
|
|
9231
|
-
const dir = persisted.provider === "claude" ? CLAUDE_HISTORY_DIR : RELAY_HISTORY_DIR;
|
|
9232
|
-
await rm(join14(dir, `${persisted.id}.jsonl`), { force: true });
|
|
9233
|
-
}
|
|
9294
|
+
await rm(join14(HISTORY_DIR_BY_PROVIDER[persisted.provider], `${persisted.id}.jsonl`), { force: true });
|
|
9234
9295
|
await rm(this.senderFilePath(persisted.id), { force: true });
|
|
9235
9296
|
}
|
|
9236
9297
|
async getChatHistory(chatId) {
|
|
@@ -9306,6 +9367,7 @@ var ChatService = class {
|
|
|
9306
9367
|
} else {
|
|
9307
9368
|
provider = new CodexAspManager({
|
|
9308
9369
|
workingDirectory: this.workingDirectory,
|
|
9370
|
+
historyFilePath: join14(CODEX_HISTORY_DIR, `${persisted.id}.jsonl`),
|
|
9309
9371
|
initialSessionId: persisted.providerSessionId,
|
|
9310
9372
|
onSaveSessionId: saveSession,
|
|
9311
9373
|
onTurnComplete: onProviderTurnComplete,
|
|
@@ -9446,7 +9508,7 @@ var ChatService = class {
|
|
|
9446
9508
|
}
|
|
9447
9509
|
async loadChats() {
|
|
9448
9510
|
try {
|
|
9449
|
-
const content = await
|
|
9511
|
+
const content = await readFile9(CHATS_FILE, "utf-8");
|
|
9450
9512
|
return parsePersistedChatsContent(content);
|
|
9451
9513
|
} catch (error) {
|
|
9452
9514
|
if (error && typeof error === "object" && "code" in error && error.code === "ENOENT") {
|
|
@@ -9461,7 +9523,7 @@ var ChatService = class {
|
|
|
9461
9523
|
console.error("[ChatService] Failed to quarantine corrupt chats file:", renameError);
|
|
9462
9524
|
}
|
|
9463
9525
|
try {
|
|
9464
|
-
const backupContent = await
|
|
9526
|
+
const backupContent = await readFile9(CHATS_BACKUP_FILE, "utf-8");
|
|
9465
9527
|
return parsePersistedChatsContent(backupContent);
|
|
9466
9528
|
} catch (backupError) {
|
|
9467
9529
|
if (backupError && typeof backupError === "object" && "code" in backupError && backupError.code === "ENOENT") {
|
|
@@ -9546,7 +9608,7 @@ var ChatService = class {
|
|
|
9546
9608
|
|
|
9547
9609
|
// src/services/repo-file-service.ts
|
|
9548
9610
|
import { execFile as execFile2 } from "child_process";
|
|
9549
|
-
import { readFile as
|
|
9611
|
+
import { readFile as readFile10, realpath, stat as stat2 } from "fs/promises";
|
|
9550
9612
|
import { join as join15, resolve, extname } from "path";
|
|
9551
9613
|
var CACHE_TTL_MS = 3e4;
|
|
9552
9614
|
var SEARCH_TIMEOUT_MS = 15e3;
|
|
@@ -9736,7 +9798,7 @@ var RepoFileService = class {
|
|
|
9736
9798
|
tooLarge: true
|
|
9737
9799
|
};
|
|
9738
9800
|
}
|
|
9739
|
-
const content = await
|
|
9801
|
+
const content = await readFile10(fullPath, "utf-8");
|
|
9740
9802
|
return {
|
|
9741
9803
|
repoName,
|
|
9742
9804
|
path: filePath,
|
|
@@ -9814,11 +9876,11 @@ var RepoFileService = class {
|
|
|
9814
9876
|
// src/v1-routes.ts
|
|
9815
9877
|
import { Hono } from "hono";
|
|
9816
9878
|
import { z as z2 } from "zod";
|
|
9817
|
-
import { readdir as readdir6, stat as stat4, readFile as
|
|
9879
|
+
import { readdir as readdir6, stat as stat4, readFile as readFile15 } from "fs/promises";
|
|
9818
9880
|
import { join as join20, resolve as resolve2 } from "path";
|
|
9819
9881
|
|
|
9820
9882
|
// src/services/upload-chat-transcripts.ts
|
|
9821
|
-
import { readdir as readdir3, readFile as
|
|
9883
|
+
import { readdir as readdir3, readFile as readFile11 } from "fs/promises";
|
|
9822
9884
|
import { basename, join as join16 } from "path";
|
|
9823
9885
|
import { homedir as homedir13 } from "os";
|
|
9824
9886
|
var ENGINE_DIR3 = join16(homedir13(), ".replicas", "engine");
|
|
@@ -9854,7 +9916,7 @@ async function flushAllChatTranscripts() {
|
|
|
9854
9916
|
return { flushed, failed };
|
|
9855
9917
|
}
|
|
9856
9918
|
async function uploadOne(chatId, filePath) {
|
|
9857
|
-
const bytes = await
|
|
9919
|
+
const bytes = await readFile11(filePath);
|
|
9858
9920
|
if (bytes.byteLength === 0) return;
|
|
9859
9921
|
const form = new FormData();
|
|
9860
9922
|
form.append("chat_id", chatId);
|
|
@@ -9871,7 +9933,7 @@ async function uploadOne(chatId, filePath) {
|
|
|
9871
9933
|
}
|
|
9872
9934
|
|
|
9873
9935
|
// src/services/canvas-service.ts
|
|
9874
|
-
import { readdir as readdir4, readFile as
|
|
9936
|
+
import { readdir as readdir4, readFile as readFile12, stat as stat3 } from "fs/promises";
|
|
9875
9937
|
import { homedir as homedir14 } from "os";
|
|
9876
9938
|
import { basename as basename2, join as join17 } from "path";
|
|
9877
9939
|
var CANVAS_DIRECTORIES = [
|
|
@@ -9936,10 +9998,10 @@ var CanvasService = class {
|
|
|
9936
9998
|
}
|
|
9937
9999
|
try {
|
|
9938
10000
|
if (isTextKind(kind)) {
|
|
9939
|
-
const content = await
|
|
10001
|
+
const content = await readFile12(filePath, "utf-8");
|
|
9940
10002
|
return { filename: safe, kind, sizeBytes, mimeType, content };
|
|
9941
10003
|
}
|
|
9942
|
-
const buf = await
|
|
10004
|
+
const buf = await readFile12(filePath);
|
|
9943
10005
|
return { filename: safe, kind, sizeBytes, mimeType, base64: buf.toString("base64") };
|
|
9944
10006
|
} catch {
|
|
9945
10007
|
continue;
|
|
@@ -9952,12 +10014,12 @@ var canvasService = new CanvasService();
|
|
|
9952
10014
|
|
|
9953
10015
|
// src/services/warm-hooks-service.ts
|
|
9954
10016
|
import { spawn as spawn4 } from "child_process";
|
|
9955
|
-
import { readFile as
|
|
10017
|
+
import { readFile as readFile14 } from "fs/promises";
|
|
9956
10018
|
import { existsSync as existsSync8 } from "fs";
|
|
9957
10019
|
import { join as join19 } from "path";
|
|
9958
10020
|
|
|
9959
10021
|
// src/services/warm-hook-logs-service.ts
|
|
9960
|
-
import { mkdir as mkdir12, readFile as
|
|
10022
|
+
import { mkdir as mkdir12, readFile as readFile13, writeFile as writeFile6, readdir as readdir5, appendFile as appendFile5, unlink as unlink3 } from "fs/promises";
|
|
9961
10023
|
import { homedir as homedir15 } from "os";
|
|
9962
10024
|
import { join as join18 } from "path";
|
|
9963
10025
|
var LOGS_DIR2 = join18(homedir15(), ".replicas", "warm-hook-logs");
|
|
@@ -10017,7 +10079,7 @@ var WarmHookLogsService = class {
|
|
|
10017
10079
|
continue;
|
|
10018
10080
|
}
|
|
10019
10081
|
try {
|
|
10020
|
-
const raw = await
|
|
10082
|
+
const raw = await readFile13(join18(LOGS_DIR2, file), "utf-8");
|
|
10021
10083
|
const stored = JSON.parse(raw);
|
|
10022
10084
|
logs.push(withPreview2(stored));
|
|
10023
10085
|
} catch {
|
|
@@ -10042,11 +10104,11 @@ var WarmHookLogsService = class {
|
|
|
10042
10104
|
}
|
|
10043
10105
|
async appendCurrentRunLog(chunk) {
|
|
10044
10106
|
if (!chunk) return;
|
|
10045
|
-
await
|
|
10107
|
+
await appendFile5(CURRENT_RUN_LOG, chunk, "utf-8");
|
|
10046
10108
|
}
|
|
10047
10109
|
async getCurrentRunLog() {
|
|
10048
10110
|
try {
|
|
10049
|
-
return await
|
|
10111
|
+
return await readFile13(CURRENT_RUN_LOG, "utf-8");
|
|
10050
10112
|
} catch (err) {
|
|
10051
10113
|
if (err.code === "ENOENT") return null;
|
|
10052
10114
|
throw err;
|
|
@@ -10055,7 +10117,7 @@ var WarmHookLogsService = class {
|
|
|
10055
10117
|
async getFullOutput(hookType, hookName) {
|
|
10056
10118
|
const filename = hookType === "global" ? GLOBAL_FILENAME : hookType === "environment" ? ENVIRONMENT_HOOK_LOG_FILENAME : repoHookLogFilename(hookName);
|
|
10057
10119
|
try {
|
|
10058
|
-
const raw = await
|
|
10120
|
+
const raw = await readFile13(join18(LOGS_DIR2, filename), "utf-8");
|
|
10059
10121
|
const stored = JSON.parse(raw);
|
|
10060
10122
|
if (stored.hookType !== hookType || stored.hookName !== hookName) {
|
|
10061
10123
|
return null;
|
|
@@ -10079,7 +10141,7 @@ async function readRepoWarmHook(repoPath) {
|
|
|
10079
10141
|
continue;
|
|
10080
10142
|
}
|
|
10081
10143
|
try {
|
|
10082
|
-
const raw = await
|
|
10144
|
+
const raw = await readFile14(configPath, "utf-8");
|
|
10083
10145
|
const config = parseReplicasConfigString(raw, filename);
|
|
10084
10146
|
if (!config.warmHook) {
|
|
10085
10147
|
return null;
|
|
@@ -11042,7 +11104,7 @@ function createV1Routes(deps) {
|
|
|
11042
11104
|
const limit = Math.min(parseInt(c.req.query("limit") || "500", 10), 5e3);
|
|
11043
11105
|
let content;
|
|
11044
11106
|
try {
|
|
11045
|
-
content = await
|
|
11107
|
+
content = await readFile15(filePath, "utf-8");
|
|
11046
11108
|
} catch {
|
|
11047
11109
|
return c.json(jsonError("Log session not found"), 404);
|
|
11048
11110
|
}
|