replicas-engine 0.1.292 → 0.1.294

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.
Files changed (2) hide show
  1. package/dist/src/index.js +106 -79
  2. 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-10-v1";
289
+ var E2B_TEMPLATE_NAME = "replicas-sandbox-2026-06-10-v3";
290
290
 
291
291
  // ../shared/src/runtime-env.ts
292
292
  function parsePosixEnvFile(content) {
@@ -4753,9 +4753,9 @@ async function registerDesktopPreview() {
4753
4753
 
4754
4754
  // src/services/chat/chat-service.ts
4755
4755
  import { existsSync as existsSync7 } from "fs";
4756
- import { appendFile as appendFile4, copyFile, mkdir as mkdir11, readFile as readFile9, rename as rename2, rm } from "fs/promises";
4757
- import { homedir as homedir12 } from "os";
4758
- import { join as join14 } from "path";
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";
4759
4759
  import { randomUUID as randomUUID5 } from "crypto";
4760
4760
 
4761
4761
  // src/managers/claude-manager.ts
@@ -6600,7 +6600,7 @@ var AspClient = class {
6600
6600
  // src/managers/codex-asp/app-server-process.ts
6601
6601
  var DEFAULT_CODEX_BINARY = "codex";
6602
6602
  var DEFAULT_CODEX_ARGS = ["app-server", "--listen", "stdio://"];
6603
- var ENGINE_PACKAGE_VERSION = "0.1.292";
6603
+ var ENGINE_PACKAGE_VERSION = "0.1.294";
6604
6604
  var INITIALIZE_METHOD = "initialize";
6605
6605
  var INITIALIZED_NOTIFICATION = "initialized";
6606
6606
  var ACCOUNT_LOGIN_START_METHOD = "account/login/start";
@@ -8913,6 +8913,74 @@ var KeepAliveService = class _KeepAliveService {
8913
8913
  };
8914
8914
  var keepAliveService = new KeepAliveService();
8915
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
+
8916
8984
  // src/services/chat/errors.ts
8917
8985
  var ChatNotFoundError = class extends Error {
8918
8986
  constructor(chatId) {
@@ -8940,18 +9008,18 @@ var DuplicateDefaultChatError = class extends Error {
8940
9008
  };
8941
9009
 
8942
9010
  // src/services/chat/chat-service.ts
8943
- var ENGINE_DIR2 = join14(homedir12(), ".replicas", "engine");
8944
- var CHATS_FILE = join14(ENGINE_DIR2, "chats.json");
8945
- var CLAUDE_HISTORY_DIR = join14(ENGINE_DIR2, "claude-histories");
8946
- var RELAY_HISTORY_DIR = join14(ENGINE_DIR2, "relay-histories");
8947
- var CODEX_HISTORY_DIR = join14(ENGINE_DIR2, "codex-histories");
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");
8948
9016
  var HISTORY_DIR_BY_PROVIDER = {
8949
9017
  claude: CLAUDE_HISTORY_DIR,
8950
9018
  relay: RELAY_HISTORY_DIR,
8951
9019
  codex: CODEX_HISTORY_DIR
8952
9020
  };
8953
- var CHAT_SENDERS_DIR = join14(ENGINE_DIR2, "chat-senders");
8954
- var CODEX_AUTH_PATH2 = join14(homedir12(), ".codex", "auth.json");
9021
+ var CHAT_SENDERS_DIR = join15(ENGINE_DIR3, "chat-senders");
9022
+ var CODEX_AUTH_PATH2 = join15(homedir13(), ".codex", "auth.json");
8955
9023
  var CHATS_BACKUP_FILE = `${CHATS_FILE}.bak`;
8956
9024
  function isChatMessageSender(value) {
8957
9025
  if (!isRecord4(value)) return false;
@@ -9047,7 +9115,7 @@ var ChatService = class {
9047
9115
  persistInFlight = false;
9048
9116
  persistQueued = false;
9049
9117
  async initialize() {
9050
- await mkdir11(ENGINE_DIR2, { recursive: true });
9118
+ await mkdir11(ENGINE_DIR3, { recursive: true });
9051
9119
  await mkdir11(CLAUDE_HISTORY_DIR, { recursive: true });
9052
9120
  await mkdir11(RELAY_HISTORY_DIR, { recursive: true });
9053
9121
  await mkdir11(CODEX_HISTORY_DIR, { recursive: true });
@@ -9149,7 +9217,7 @@ var ChatService = class {
9149
9217
  };
9150
9218
  }
9151
9219
  senderFilePath(chatId) {
9152
- return join14(CHAT_SENDERS_DIR, `${chatId}.jsonl`);
9220
+ return join15(CHAT_SENDERS_DIR, `${chatId}.jsonl`);
9153
9221
  }
9154
9222
  async appendSender(chatId, sender) {
9155
9223
  try {
@@ -9160,7 +9228,7 @@ var ChatService = class {
9160
9228
  }
9161
9229
  async readSenders(chatId) {
9162
9230
  try {
9163
- const content = await readFile9(this.senderFilePath(chatId), "utf-8");
9231
+ const content = await readFile10(this.senderFilePath(chatId), "utf-8");
9164
9232
  const lines = content.split("\n").filter((line) => line.trim().length > 0);
9165
9233
  const senders = [];
9166
9234
  for (const line of lines) {
@@ -9297,7 +9365,7 @@ var ChatService = class {
9297
9365
  return descendants;
9298
9366
  }
9299
9367
  async deleteHistoryFile(persisted) {
9300
- await rm(join14(HISTORY_DIR_BY_PROVIDER[persisted.provider], `${persisted.id}.jsonl`), { force: true });
9368
+ await rm(join15(HISTORY_DIR_BY_PROVIDER[persisted.provider], `${persisted.id}.jsonl`), { force: true });
9301
9369
  await rm(this.senderFilePath(persisted.id), { force: true });
9302
9370
  }
9303
9371
  async getChatHistory(chatId) {
@@ -9330,6 +9398,11 @@ var ChatService = class {
9330
9398
  }
9331
9399
  return count;
9332
9400
  }
9401
+ async flushAllChatTranscripts() {
9402
+ return flushAllChatTranscripts(new Map(
9403
+ [...this.chats.entries()].map(([chatId, chat]) => [chatId, this.toSummary(chat)])
9404
+ ));
9405
+ }
9333
9406
  createRuntimeChat(persisted) {
9334
9407
  const saveSession = async (sessionId) => {
9335
9408
  persisted.providerSessionId = sessionId;
@@ -9353,7 +9426,7 @@ var ChatService = class {
9353
9426
  if (persisted.provider === "claude") {
9354
9427
  provider = new ClaudeManager({
9355
9428
  workingDirectory: this.workingDirectory,
9356
- historyFilePath: join14(CLAUDE_HISTORY_DIR, `${persisted.id}.jsonl`),
9429
+ historyFilePath: join15(CLAUDE_HISTORY_DIR, `${persisted.id}.jsonl`),
9357
9430
  initialSessionId: persisted.providerSessionId,
9358
9431
  onSaveSessionId: saveSession,
9359
9432
  onTurnComplete: onProviderTurnComplete,
@@ -9362,7 +9435,7 @@ var ChatService = class {
9362
9435
  } else if (persisted.provider === "relay") {
9363
9436
  provider = new RelayManager({
9364
9437
  workingDirectory: this.workingDirectory,
9365
- historyFilePath: join14(RELAY_HISTORY_DIR, `${persisted.id}.jsonl`),
9438
+ historyFilePath: join15(RELAY_HISTORY_DIR, `${persisted.id}.jsonl`),
9366
9439
  initialSessionId: persisted.providerSessionId,
9367
9440
  onSaveSessionId: saveSession,
9368
9441
  onTurnComplete: onProviderTurnComplete,
@@ -9373,7 +9446,7 @@ var ChatService = class {
9373
9446
  } else {
9374
9447
  provider = new CodexAspManager({
9375
9448
  workingDirectory: this.workingDirectory,
9376
- historyFilePath: join14(CODEX_HISTORY_DIR, `${persisted.id}.jsonl`),
9449
+ historyFilePath: join15(CODEX_HISTORY_DIR, `${persisted.id}.jsonl`),
9377
9450
  initialSessionId: persisted.providerSessionId,
9378
9451
  onSaveSessionId: saveSession,
9379
9452
  onTurnComplete: onProviderTurnComplete,
@@ -9507,6 +9580,13 @@ var ChatService = class {
9507
9580
  });
9508
9581
  monolithService.sendEvent({ type: "agent_response_complete", payload: {} }).catch(() => {
9509
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
+ });
9510
9590
  await this.publishAgentTurnCompleteWebhook(chat);
9511
9591
  }
9512
9592
  getRuntimeChat(chatId) {
@@ -9514,7 +9594,7 @@ var ChatService = class {
9514
9594
  }
9515
9595
  async loadChats() {
9516
9596
  try {
9517
- const content = await readFile9(CHATS_FILE, "utf-8");
9597
+ const content = await readFile10(CHATS_FILE, "utf-8");
9518
9598
  return parsePersistedChatsContent(content);
9519
9599
  } catch (error) {
9520
9600
  if (error && typeof error === "object" && "code" in error && error.code === "ENOENT") {
@@ -9529,7 +9609,7 @@ var ChatService = class {
9529
9609
  console.error("[ChatService] Failed to quarantine corrupt chats file:", renameError);
9530
9610
  }
9531
9611
  try {
9532
- const backupContent = await readFile9(CHATS_BACKUP_FILE, "utf-8");
9612
+ const backupContent = await readFile10(CHATS_BACKUP_FILE, "utf-8");
9533
9613
  return parsePersistedChatsContent(backupContent);
9534
9614
  } catch (backupError) {
9535
9615
  if (backupError && typeof backupError === "object" && "code" in backupError && backupError.code === "ENOENT") {
@@ -9614,8 +9694,8 @@ var ChatService = class {
9614
9694
 
9615
9695
  // src/services/repo-file-service.ts
9616
9696
  import { execFile as execFile2 } from "child_process";
9617
- import { readFile as readFile10, realpath, stat as stat2 } from "fs/promises";
9618
- import { join as join15, resolve, extname } from "path";
9697
+ import { readFile as readFile11, realpath, stat as stat2 } from "fs/promises";
9698
+ import { join as join16, resolve, extname } from "path";
9619
9699
  var CACHE_TTL_MS = 3e4;
9620
9700
  var SEARCH_TIMEOUT_MS = 15e3;
9621
9701
  var MAX_CONTENT_BYTES = 256 * 1024;
@@ -9775,7 +9855,7 @@ var RepoFileService = class {
9775
9855
  const repo = repos.find((r) => r.name === repoName);
9776
9856
  if (!repo) return null;
9777
9857
  try {
9778
- const fullPath = await realpath(resolve(join15(repo.path, filePath)));
9858
+ const fullPath = await realpath(resolve(join16(repo.path, filePath)));
9779
9859
  const repoRoot = await realpath(repo.path);
9780
9860
  const repoPrefix = repoRoot.endsWith("/") ? repoRoot : repoRoot + "/";
9781
9861
  if (!fullPath.startsWith(repoPrefix) && fullPath !== repoRoot) return null;
@@ -9804,7 +9884,7 @@ var RepoFileService = class {
9804
9884
  tooLarge: true
9805
9885
  };
9806
9886
  }
9807
- const content = await readFile10(fullPath, "utf-8");
9887
+ const content = await readFile11(fullPath, "utf-8");
9808
9888
  return {
9809
9889
  repoName,
9810
9890
  path: filePath,
@@ -9885,59 +9965,6 @@ import { z as z2 } from "zod";
9885
9965
  import { readdir as readdir6, stat as stat4, readFile as readFile15 } from "fs/promises";
9886
9966
  import { join as join20, resolve as resolve2 } from "path";
9887
9967
 
9888
- // src/services/upload-chat-transcripts.ts
9889
- import { readdir as readdir3, readFile as readFile11 } from "fs/promises";
9890
- import { basename, join as join16 } from "path";
9891
- import { homedir as homedir13 } from "os";
9892
- var ENGINE_DIR3 = join16(homedir13(), ".replicas", "engine");
9893
- var HISTORY_DIRS = [
9894
- join16(ENGINE_DIR3, "claude-histories"),
9895
- join16(ENGINE_DIR3, "relay-histories")
9896
- ];
9897
- async function flushAllChatTranscripts() {
9898
- let flushed = 0;
9899
- let failed = 0;
9900
- const tasks = [];
9901
- for (const dir of HISTORY_DIRS) {
9902
- let entries;
9903
- try {
9904
- entries = await readdir3(dir);
9905
- } catch {
9906
- continue;
9907
- }
9908
- for (const entry of entries) {
9909
- if (!entry.endsWith(".jsonl")) continue;
9910
- const chatId = basename(entry, ".jsonl");
9911
- tasks.push(
9912
- uploadOne(chatId, join16(dir, entry)).then(() => {
9913
- flushed++;
9914
- }).catch((err) => {
9915
- failed++;
9916
- console.error("[ChatTranscriptUploader] upload failed:", { chatId, err });
9917
- })
9918
- );
9919
- }
9920
- }
9921
- await Promise.all(tasks);
9922
- return { flushed, failed };
9923
- }
9924
- async function uploadOne(chatId, filePath) {
9925
- const bytes = await readFile11(filePath);
9926
- if (bytes.byteLength === 0) return;
9927
- const form = new FormData();
9928
- form.append("chat_id", chatId);
9929
- form.append(
9930
- "file",
9931
- new Blob([new Uint8Array(bytes)], { type: "application/x-ndjson" }),
9932
- "transcript.jsonl"
9933
- );
9934
- const response = await monolithRequest("/v1/engine/chat-transcripts", { body: form });
9935
- if (!response.ok) {
9936
- const errorText = await response.text();
9937
- throw new Error(`upload failed: ${response.status} ${errorText}`);
9938
- }
9939
- }
9940
-
9941
9968
  // src/services/canvas-service.ts
9942
9969
  import { readdir as readdir4, readFile as readFile12, stat as stat3 } from "fs/promises";
9943
9970
  import { homedir as homedir14 } from "os";
@@ -10625,7 +10652,7 @@ function createV1Routes(deps) {
10625
10652
  });
10626
10653
  app2.post("/chat-transcripts/flush-all", async (c) => {
10627
10654
  try {
10628
- const result = await flushAllChatTranscripts();
10655
+ const result = await deps.chatService.flushAllChatTranscripts();
10629
10656
  return c.json(result);
10630
10657
  } catch (error) {
10631
10658
  return c.json(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "replicas-engine",
3
- "version": "0.1.292",
3
+ "version": "0.1.294",
4
4
  "description": "Lightweight API server for Replicas workspaces",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",