replicas-engine 0.1.291 → 0.1.293
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 +114 -81
- 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-
|
|
289
|
+
var E2B_TEMPLATE_NAME = "replicas-sandbox-2026-06-10-v2";
|
|
290
290
|
|
|
291
291
|
// ../shared/src/runtime-env.ts
|
|
292
292
|
function parsePosixEnvFile(content) {
|
|
@@ -2384,6 +2384,12 @@ function extractToolResultText(content, separator = "\n") {
|
|
|
2384
2384
|
}
|
|
2385
2385
|
return texts.join(separator);
|
|
2386
2386
|
}
|
|
2387
|
+
function normalizeContentBlocks(content) {
|
|
2388
|
+
if (typeof content === "string") {
|
|
2389
|
+
return content ? [{ type: "text", text: content }] : [];
|
|
2390
|
+
}
|
|
2391
|
+
return content ?? [];
|
|
2392
|
+
}
|
|
2387
2393
|
function parseStringField(value) {
|
|
2388
2394
|
if (typeof value !== "string") return null;
|
|
2389
2395
|
const trimmed = value.trim();
|
|
@@ -4747,9 +4753,9 @@ async function registerDesktopPreview() {
|
|
|
4747
4753
|
|
|
4748
4754
|
// src/services/chat/chat-service.ts
|
|
4749
4755
|
import { existsSync as existsSync7 } from "fs";
|
|
4750
|
-
import { appendFile as appendFile4, copyFile, mkdir as mkdir11, readFile as
|
|
4751
|
-
import { homedir as
|
|
4752
|
-
import { join as
|
|
4756
|
+
import { appendFile as appendFile4, copyFile, mkdir as mkdir11, readFile as readFile10, rename as rename2, rm } from "fs/promises";
|
|
4757
|
+
import { homedir as homedir13 } from "os";
|
|
4758
|
+
import { join as join15 } from "path";
|
|
4753
4759
|
import { randomUUID as randomUUID5 } from "crypto";
|
|
4754
4760
|
|
|
4755
4761
|
// src/managers/claude-manager.ts
|
|
@@ -4805,7 +4811,7 @@ function summarizeInput(input) {
|
|
|
4805
4811
|
function convertClaudeEvent(event, linearSessionId) {
|
|
4806
4812
|
if (event.type === "assistant") {
|
|
4807
4813
|
const message = event;
|
|
4808
|
-
const contentBlocks = message.message?.content
|
|
4814
|
+
const contentBlocks = normalizeContentBlocks(message.message?.content);
|
|
4809
4815
|
for (const block of contentBlocks) {
|
|
4810
4816
|
if (block.type === "text" && block.text) {
|
|
4811
4817
|
return {
|
|
@@ -4877,7 +4883,7 @@ function convertClaudeEvent(event, linearSessionId) {
|
|
|
4877
4883
|
}
|
|
4878
4884
|
if (event.type === "user") {
|
|
4879
4885
|
const message = event;
|
|
4880
|
-
const contentBlocks = message.message?.content
|
|
4886
|
+
const contentBlocks = normalizeContentBlocks(message.message?.content);
|
|
4881
4887
|
for (const block of contentBlocks) {
|
|
4882
4888
|
if (block.type === "tool_result") {
|
|
4883
4889
|
const resultText = extractToolResultText(block.content);
|
|
@@ -6594,7 +6600,7 @@ var AspClient = class {
|
|
|
6594
6600
|
// src/managers/codex-asp/app-server-process.ts
|
|
6595
6601
|
var DEFAULT_CODEX_BINARY = "codex";
|
|
6596
6602
|
var DEFAULT_CODEX_ARGS = ["app-server", "--listen", "stdio://"];
|
|
6597
|
-
var ENGINE_PACKAGE_VERSION = "0.1.
|
|
6603
|
+
var ENGINE_PACKAGE_VERSION = "0.1.293";
|
|
6598
6604
|
var INITIALIZE_METHOD = "initialize";
|
|
6599
6605
|
var INITIALIZED_NOTIFICATION = "initialized";
|
|
6600
6606
|
var ACCOUNT_LOGIN_START_METHOD = "account/login/start";
|
|
@@ -8907,6 +8913,74 @@ var KeepAliveService = class _KeepAliveService {
|
|
|
8907
8913
|
};
|
|
8908
8914
|
var keepAliveService = new KeepAliveService();
|
|
8909
8915
|
|
|
8916
|
+
// src/services/upload-chat-transcripts.ts
|
|
8917
|
+
import { readdir as readdir3, readFile as readFile9 } from "fs/promises";
|
|
8918
|
+
import { basename, join as join14 } from "path";
|
|
8919
|
+
import { homedir as homedir12 } from "os";
|
|
8920
|
+
var ENGINE_DIR2 = join14(homedir12(), ".replicas", "engine");
|
|
8921
|
+
var HISTORY_DIRS = [
|
|
8922
|
+
join14(ENGINE_DIR2, "claude-histories"),
|
|
8923
|
+
join14(ENGINE_DIR2, "relay-histories"),
|
|
8924
|
+
join14(ENGINE_DIR2, "codex-histories")
|
|
8925
|
+
];
|
|
8926
|
+
async function flushAllChatTranscripts(chatsById = /* @__PURE__ */ new Map()) {
|
|
8927
|
+
let flushed = 0;
|
|
8928
|
+
let failed = 0;
|
|
8929
|
+
const tasks = [];
|
|
8930
|
+
for (const dir of HISTORY_DIRS) {
|
|
8931
|
+
let entries;
|
|
8932
|
+
try {
|
|
8933
|
+
entries = await readdir3(dir);
|
|
8934
|
+
} catch {
|
|
8935
|
+
continue;
|
|
8936
|
+
}
|
|
8937
|
+
for (const entry of entries) {
|
|
8938
|
+
if (!entry.endsWith(".jsonl")) continue;
|
|
8939
|
+
const chatId = basename(entry, ".jsonl");
|
|
8940
|
+
tasks.push(
|
|
8941
|
+
uploadChatTranscript(chatId, join14(dir, entry), chatsById.get(chatId)).then(() => {
|
|
8942
|
+
flushed++;
|
|
8943
|
+
}).catch((err) => {
|
|
8944
|
+
failed++;
|
|
8945
|
+
console.error("[ChatTranscriptUploader] upload failed:", { chatId, err });
|
|
8946
|
+
})
|
|
8947
|
+
);
|
|
8948
|
+
}
|
|
8949
|
+
}
|
|
8950
|
+
await Promise.all(tasks);
|
|
8951
|
+
return { flushed, failed };
|
|
8952
|
+
}
|
|
8953
|
+
async function uploadChatTranscript(chatId, filePath, chat) {
|
|
8954
|
+
const bytes = await readFile9(filePath);
|
|
8955
|
+
if (bytes.byteLength === 0) return;
|
|
8956
|
+
const form = new FormData();
|
|
8957
|
+
form.append("chat_id", chatId);
|
|
8958
|
+
if (chat) {
|
|
8959
|
+
const metadata = {
|
|
8960
|
+
provider: chat.provider,
|
|
8961
|
+
title: chat.title,
|
|
8962
|
+
createdAt: chat.createdAt,
|
|
8963
|
+
updatedAt: chat.updatedAt,
|
|
8964
|
+
parentChatId: chat.parentChatId
|
|
8965
|
+
};
|
|
8966
|
+
form.append("provider", metadata.provider);
|
|
8967
|
+
form.append("title", metadata.title);
|
|
8968
|
+
form.append("created_at", metadata.createdAt);
|
|
8969
|
+
form.append("updated_at", metadata.updatedAt);
|
|
8970
|
+
if (metadata.parentChatId) form.append("parent_chat_id", metadata.parentChatId);
|
|
8971
|
+
}
|
|
8972
|
+
form.append(
|
|
8973
|
+
"file",
|
|
8974
|
+
new Blob([new Uint8Array(bytes)], { type: "application/x-ndjson" }),
|
|
8975
|
+
"transcript.jsonl"
|
|
8976
|
+
);
|
|
8977
|
+
const response = await monolithRequest("/v1/engine/chat-transcripts", { body: form });
|
|
8978
|
+
if (!response.ok) {
|
|
8979
|
+
const errorText = await response.text();
|
|
8980
|
+
throw new Error(`upload failed: ${response.status} ${errorText}`);
|
|
8981
|
+
}
|
|
8982
|
+
}
|
|
8983
|
+
|
|
8910
8984
|
// src/services/chat/errors.ts
|
|
8911
8985
|
var ChatNotFoundError = class extends Error {
|
|
8912
8986
|
constructor(chatId) {
|
|
@@ -8934,18 +9008,18 @@ var DuplicateDefaultChatError = class extends Error {
|
|
|
8934
9008
|
};
|
|
8935
9009
|
|
|
8936
9010
|
// src/services/chat/chat-service.ts
|
|
8937
|
-
var
|
|
8938
|
-
var CHATS_FILE =
|
|
8939
|
-
var CLAUDE_HISTORY_DIR =
|
|
8940
|
-
var RELAY_HISTORY_DIR =
|
|
8941
|
-
var CODEX_HISTORY_DIR =
|
|
9011
|
+
var ENGINE_DIR3 = join15(homedir13(), ".replicas", "engine");
|
|
9012
|
+
var CHATS_FILE = join15(ENGINE_DIR3, "chats.json");
|
|
9013
|
+
var CLAUDE_HISTORY_DIR = join15(ENGINE_DIR3, "claude-histories");
|
|
9014
|
+
var RELAY_HISTORY_DIR = join15(ENGINE_DIR3, "relay-histories");
|
|
9015
|
+
var CODEX_HISTORY_DIR = join15(ENGINE_DIR3, "codex-histories");
|
|
8942
9016
|
var HISTORY_DIR_BY_PROVIDER = {
|
|
8943
9017
|
claude: CLAUDE_HISTORY_DIR,
|
|
8944
9018
|
relay: RELAY_HISTORY_DIR,
|
|
8945
9019
|
codex: CODEX_HISTORY_DIR
|
|
8946
9020
|
};
|
|
8947
|
-
var CHAT_SENDERS_DIR =
|
|
8948
|
-
var CODEX_AUTH_PATH2 =
|
|
9021
|
+
var CHAT_SENDERS_DIR = join15(ENGINE_DIR3, "chat-senders");
|
|
9022
|
+
var CODEX_AUTH_PATH2 = join15(homedir13(), ".codex", "auth.json");
|
|
8949
9023
|
var CHATS_BACKUP_FILE = `${CHATS_FILE}.bak`;
|
|
8950
9024
|
function isChatMessageSender(value) {
|
|
8951
9025
|
if (!isRecord4(value)) return false;
|
|
@@ -9041,7 +9115,7 @@ var ChatService = class {
|
|
|
9041
9115
|
persistInFlight = false;
|
|
9042
9116
|
persistQueued = false;
|
|
9043
9117
|
async initialize() {
|
|
9044
|
-
await mkdir11(
|
|
9118
|
+
await mkdir11(ENGINE_DIR3, { recursive: true });
|
|
9045
9119
|
await mkdir11(CLAUDE_HISTORY_DIR, { recursive: true });
|
|
9046
9120
|
await mkdir11(RELAY_HISTORY_DIR, { recursive: true });
|
|
9047
9121
|
await mkdir11(CODEX_HISTORY_DIR, { recursive: true });
|
|
@@ -9143,7 +9217,7 @@ var ChatService = class {
|
|
|
9143
9217
|
};
|
|
9144
9218
|
}
|
|
9145
9219
|
senderFilePath(chatId) {
|
|
9146
|
-
return
|
|
9220
|
+
return join15(CHAT_SENDERS_DIR, `${chatId}.jsonl`);
|
|
9147
9221
|
}
|
|
9148
9222
|
async appendSender(chatId, sender) {
|
|
9149
9223
|
try {
|
|
@@ -9154,7 +9228,7 @@ var ChatService = class {
|
|
|
9154
9228
|
}
|
|
9155
9229
|
async readSenders(chatId) {
|
|
9156
9230
|
try {
|
|
9157
|
-
const content = await
|
|
9231
|
+
const content = await readFile10(this.senderFilePath(chatId), "utf-8");
|
|
9158
9232
|
const lines = content.split("\n").filter((line) => line.trim().length > 0);
|
|
9159
9233
|
const senders = [];
|
|
9160
9234
|
for (const line of lines) {
|
|
@@ -9291,7 +9365,7 @@ var ChatService = class {
|
|
|
9291
9365
|
return descendants;
|
|
9292
9366
|
}
|
|
9293
9367
|
async deleteHistoryFile(persisted) {
|
|
9294
|
-
await rm(
|
|
9368
|
+
await rm(join15(HISTORY_DIR_BY_PROVIDER[persisted.provider], `${persisted.id}.jsonl`), { force: true });
|
|
9295
9369
|
await rm(this.senderFilePath(persisted.id), { force: true });
|
|
9296
9370
|
}
|
|
9297
9371
|
async getChatHistory(chatId) {
|
|
@@ -9324,6 +9398,11 @@ var ChatService = class {
|
|
|
9324
9398
|
}
|
|
9325
9399
|
return count;
|
|
9326
9400
|
}
|
|
9401
|
+
async flushAllChatTranscripts() {
|
|
9402
|
+
return flushAllChatTranscripts(new Map(
|
|
9403
|
+
[...this.chats.entries()].map(([chatId, chat]) => [chatId, this.toSummary(chat)])
|
|
9404
|
+
));
|
|
9405
|
+
}
|
|
9327
9406
|
createRuntimeChat(persisted) {
|
|
9328
9407
|
const saveSession = async (sessionId) => {
|
|
9329
9408
|
persisted.providerSessionId = sessionId;
|
|
@@ -9347,7 +9426,7 @@ var ChatService = class {
|
|
|
9347
9426
|
if (persisted.provider === "claude") {
|
|
9348
9427
|
provider = new ClaudeManager({
|
|
9349
9428
|
workingDirectory: this.workingDirectory,
|
|
9350
|
-
historyFilePath:
|
|
9429
|
+
historyFilePath: join15(CLAUDE_HISTORY_DIR, `${persisted.id}.jsonl`),
|
|
9351
9430
|
initialSessionId: persisted.providerSessionId,
|
|
9352
9431
|
onSaveSessionId: saveSession,
|
|
9353
9432
|
onTurnComplete: onProviderTurnComplete,
|
|
@@ -9356,7 +9435,7 @@ var ChatService = class {
|
|
|
9356
9435
|
} else if (persisted.provider === "relay") {
|
|
9357
9436
|
provider = new RelayManager({
|
|
9358
9437
|
workingDirectory: this.workingDirectory,
|
|
9359
|
-
historyFilePath:
|
|
9438
|
+
historyFilePath: join15(RELAY_HISTORY_DIR, `${persisted.id}.jsonl`),
|
|
9360
9439
|
initialSessionId: persisted.providerSessionId,
|
|
9361
9440
|
onSaveSessionId: saveSession,
|
|
9362
9441
|
onTurnComplete: onProviderTurnComplete,
|
|
@@ -9367,7 +9446,7 @@ var ChatService = class {
|
|
|
9367
9446
|
} else {
|
|
9368
9447
|
provider = new CodexAspManager({
|
|
9369
9448
|
workingDirectory: this.workingDirectory,
|
|
9370
|
-
historyFilePath:
|
|
9449
|
+
historyFilePath: join15(CODEX_HISTORY_DIR, `${persisted.id}.jsonl`),
|
|
9371
9450
|
initialSessionId: persisted.providerSessionId,
|
|
9372
9451
|
onSaveSessionId: saveSession,
|
|
9373
9452
|
onTurnComplete: onProviderTurnComplete,
|
|
@@ -9501,6 +9580,13 @@ var ChatService = class {
|
|
|
9501
9580
|
});
|
|
9502
9581
|
monolithService.sendEvent({ type: "agent_response_complete", payload: {} }).catch(() => {
|
|
9503
9582
|
});
|
|
9583
|
+
uploadChatTranscript(
|
|
9584
|
+
chatId,
|
|
9585
|
+
join15(HISTORY_DIR_BY_PROVIDER[chat.persisted.provider], `${chatId}.jsonl`),
|
|
9586
|
+
this.toSummary(chat)
|
|
9587
|
+
).catch((err) => {
|
|
9588
|
+
console.error("[ChatService] Failed to upload chat transcript:", { chatId, err });
|
|
9589
|
+
});
|
|
9504
9590
|
await this.publishAgentTurnCompleteWebhook(chat);
|
|
9505
9591
|
}
|
|
9506
9592
|
getRuntimeChat(chatId) {
|
|
@@ -9508,7 +9594,7 @@ var ChatService = class {
|
|
|
9508
9594
|
}
|
|
9509
9595
|
async loadChats() {
|
|
9510
9596
|
try {
|
|
9511
|
-
const content = await
|
|
9597
|
+
const content = await readFile10(CHATS_FILE, "utf-8");
|
|
9512
9598
|
return parsePersistedChatsContent(content);
|
|
9513
9599
|
} catch (error) {
|
|
9514
9600
|
if (error && typeof error === "object" && "code" in error && error.code === "ENOENT") {
|
|
@@ -9523,7 +9609,7 @@ var ChatService = class {
|
|
|
9523
9609
|
console.error("[ChatService] Failed to quarantine corrupt chats file:", renameError);
|
|
9524
9610
|
}
|
|
9525
9611
|
try {
|
|
9526
|
-
const backupContent = await
|
|
9612
|
+
const backupContent = await readFile10(CHATS_BACKUP_FILE, "utf-8");
|
|
9527
9613
|
return parsePersistedChatsContent(backupContent);
|
|
9528
9614
|
} catch (backupError) {
|
|
9529
9615
|
if (backupError && typeof backupError === "object" && "code" in backupError && backupError.code === "ENOENT") {
|
|
@@ -9608,8 +9694,8 @@ var ChatService = class {
|
|
|
9608
9694
|
|
|
9609
9695
|
// src/services/repo-file-service.ts
|
|
9610
9696
|
import { execFile as execFile2 } from "child_process";
|
|
9611
|
-
import { readFile as
|
|
9612
|
-
import { join as
|
|
9697
|
+
import { readFile as readFile11, realpath, stat as stat2 } from "fs/promises";
|
|
9698
|
+
import { join as join16, resolve, extname } from "path";
|
|
9613
9699
|
var CACHE_TTL_MS = 3e4;
|
|
9614
9700
|
var SEARCH_TIMEOUT_MS = 15e3;
|
|
9615
9701
|
var MAX_CONTENT_BYTES = 256 * 1024;
|
|
@@ -9769,7 +9855,7 @@ var RepoFileService = class {
|
|
|
9769
9855
|
const repo = repos.find((r) => r.name === repoName);
|
|
9770
9856
|
if (!repo) return null;
|
|
9771
9857
|
try {
|
|
9772
|
-
const fullPath = await realpath(resolve(
|
|
9858
|
+
const fullPath = await realpath(resolve(join16(repo.path, filePath)));
|
|
9773
9859
|
const repoRoot = await realpath(repo.path);
|
|
9774
9860
|
const repoPrefix = repoRoot.endsWith("/") ? repoRoot : repoRoot + "/";
|
|
9775
9861
|
if (!fullPath.startsWith(repoPrefix) && fullPath !== repoRoot) return null;
|
|
@@ -9798,7 +9884,7 @@ var RepoFileService = class {
|
|
|
9798
9884
|
tooLarge: true
|
|
9799
9885
|
};
|
|
9800
9886
|
}
|
|
9801
|
-
const content = await
|
|
9887
|
+
const content = await readFile11(fullPath, "utf-8");
|
|
9802
9888
|
return {
|
|
9803
9889
|
repoName,
|
|
9804
9890
|
path: filePath,
|
|
@@ -9879,59 +9965,6 @@ import { z as z2 } from "zod";
|
|
|
9879
9965
|
import { readdir as readdir6, stat as stat4, readFile as readFile15 } from "fs/promises";
|
|
9880
9966
|
import { join as join20, resolve as resolve2 } from "path";
|
|
9881
9967
|
|
|
9882
|
-
// src/services/upload-chat-transcripts.ts
|
|
9883
|
-
import { readdir as readdir3, readFile as readFile11 } from "fs/promises";
|
|
9884
|
-
import { basename, join as join16 } from "path";
|
|
9885
|
-
import { homedir as homedir13 } from "os";
|
|
9886
|
-
var ENGINE_DIR3 = join16(homedir13(), ".replicas", "engine");
|
|
9887
|
-
var HISTORY_DIRS = [
|
|
9888
|
-
join16(ENGINE_DIR3, "claude-histories"),
|
|
9889
|
-
join16(ENGINE_DIR3, "relay-histories")
|
|
9890
|
-
];
|
|
9891
|
-
async function flushAllChatTranscripts() {
|
|
9892
|
-
let flushed = 0;
|
|
9893
|
-
let failed = 0;
|
|
9894
|
-
const tasks = [];
|
|
9895
|
-
for (const dir of HISTORY_DIRS) {
|
|
9896
|
-
let entries;
|
|
9897
|
-
try {
|
|
9898
|
-
entries = await readdir3(dir);
|
|
9899
|
-
} catch {
|
|
9900
|
-
continue;
|
|
9901
|
-
}
|
|
9902
|
-
for (const entry of entries) {
|
|
9903
|
-
if (!entry.endsWith(".jsonl")) continue;
|
|
9904
|
-
const chatId = basename(entry, ".jsonl");
|
|
9905
|
-
tasks.push(
|
|
9906
|
-
uploadOne(chatId, join16(dir, entry)).then(() => {
|
|
9907
|
-
flushed++;
|
|
9908
|
-
}).catch((err) => {
|
|
9909
|
-
failed++;
|
|
9910
|
-
console.error("[ChatTranscriptUploader] upload failed:", { chatId, err });
|
|
9911
|
-
})
|
|
9912
|
-
);
|
|
9913
|
-
}
|
|
9914
|
-
}
|
|
9915
|
-
await Promise.all(tasks);
|
|
9916
|
-
return { flushed, failed };
|
|
9917
|
-
}
|
|
9918
|
-
async function uploadOne(chatId, filePath) {
|
|
9919
|
-
const bytes = await readFile11(filePath);
|
|
9920
|
-
if (bytes.byteLength === 0) return;
|
|
9921
|
-
const form = new FormData();
|
|
9922
|
-
form.append("chat_id", chatId);
|
|
9923
|
-
form.append(
|
|
9924
|
-
"file",
|
|
9925
|
-
new Blob([new Uint8Array(bytes)], { type: "application/x-ndjson" }),
|
|
9926
|
-
"transcript.jsonl"
|
|
9927
|
-
);
|
|
9928
|
-
const response = await monolithRequest("/v1/engine/chat-transcripts", { body: form });
|
|
9929
|
-
if (!response.ok) {
|
|
9930
|
-
const errorText = await response.text();
|
|
9931
|
-
throw new Error(`upload failed: ${response.status} ${errorText}`);
|
|
9932
|
-
}
|
|
9933
|
-
}
|
|
9934
|
-
|
|
9935
9968
|
// src/services/canvas-service.ts
|
|
9936
9969
|
import { readdir as readdir4, readFile as readFile12, stat as stat3 } from "fs/promises";
|
|
9937
9970
|
import { homedir as homedir14 } from "os";
|
|
@@ -10619,7 +10652,7 @@ function createV1Routes(deps) {
|
|
|
10619
10652
|
});
|
|
10620
10653
|
app2.post("/chat-transcripts/flush-all", async (c) => {
|
|
10621
10654
|
try {
|
|
10622
|
-
const result = await flushAllChatTranscripts();
|
|
10655
|
+
const result = await deps.chatService.flushAllChatTranscripts();
|
|
10623
10656
|
return c.json(result);
|
|
10624
10657
|
} catch (error) {
|
|
10625
10658
|
return c.json(
|