replicas-engine 0.1.500 → 0.1.501

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 +147 -135
  2. package/package.json +1 -1
package/dist/src/index.js CHANGED
@@ -611,7 +611,7 @@ var WORKSPACE_SIZES = ["small", "large"];
611
611
  var INVALID_WORKSPACE_SIZE_ERROR = `Invalid size: must be one of ${WORKSPACE_SIZES.join(", ")}`;
612
612
 
613
613
  // ../shared/src/e2b.ts
614
- var E2B_TEMPLATE_NAME = "replicas-sandbox-2026-07-25-v2";
614
+ var E2B_TEMPLATE_NAME = "replicas-sandbox-2026-07-25-v3";
615
615
 
616
616
  // ../shared/src/runtime-env.ts
617
617
  function shellQuotePosix(value) {
@@ -4855,7 +4855,6 @@ function loadEngineEnv() {
4855
4855
  ANTHROPIC_API_KEY: readEnv("ANTHROPIC_API_KEY"),
4856
4856
  OPENAI_API_KEY: readEnv("OPENAI_API_KEY"),
4857
4857
  CURSOR_API_KEY: readEnv("CURSOR_API_KEY"),
4858
- OPENROUTER_API_KEY: readEnv("OPENROUTER_API_KEY"),
4859
4858
  CLAUDE_CODE_USE_BEDROCK: readEnv("CLAUDE_CODE_USE_BEDROCK"),
4860
4859
  AWS_ACCESS_KEY_ID: readEnv("AWS_ACCESS_KEY_ID"),
4861
4860
  AWS_SECRET_ACCESS_KEY: readEnv("AWS_SECRET_ACCESS_KEY"),
@@ -6299,22 +6298,29 @@ var engineLogger = new EngineLogger();
6299
6298
  // src/services/replicas-config-service.ts
6300
6299
  import { readFile as readFile6, appendFile, writeFile as writeFile4, mkdir as mkdir6 } from "fs/promises";
6301
6300
  import { existsSync as existsSync3 } from "fs";
6302
- import { join as join9 } from "path";
6303
- import { homedir as homedir7 } from "os";
6301
+ import { join as join10 } from "path";
6302
+ import { homedir as homedir8 } from "os";
6304
6303
  import { spawn as spawn2 } from "child_process";
6305
6304
 
6306
6305
  // src/services/environment-details-service.ts
6307
6306
  import { mkdir as mkdir4, readFile as readFile4 } from "fs/promises";
6308
6307
  import { existsSync as existsSync2 } from "fs";
6308
+ import { homedir as homedir6 } from "os";
6309
+ import { join as join8 } from "path";
6310
+
6311
+ // src/managers/agent-auth-paths.ts
6309
6312
  import { homedir as homedir5 } from "os";
6310
6313
  import { join as join7 } from "path";
6311
- var REPLICAS_DIR = join7(homedir5(), ".replicas");
6312
- var DETAILS_FILE = join7(REPLICAS_DIR, "environment-details.json");
6313
- var CLAUDE_CREDENTIALS_PATH = join7(homedir5(), ".claude", ".credentials.json");
6314
- var CODEX_AUTH_PATH = join7(homedir5(), ".codex", "auth.json");
6315
6314
  var OPENCODE_AUTH_PATH = join7(homedir5(), ".local", "share", "opencode", "auth.json");
6316
- var GH_HOSTS_PATH = join7(homedir5(), ".config", "gh", "hosts.yml");
6317
- var GIT_CREDENTIALS_PATH = join7(homedir5(), ".git-credentials");
6315
+ var PI_AUTH_PATH = join7(homedir5(), ".pi", "agent", "auth.json");
6316
+
6317
+ // src/services/environment-details-service.ts
6318
+ var REPLICAS_DIR = join8(homedir6(), ".replicas");
6319
+ var DETAILS_FILE = join8(REPLICAS_DIR, "environment-details.json");
6320
+ var CLAUDE_CREDENTIALS_PATH = join8(homedir6(), ".claude", ".credentials.json");
6321
+ var CODEX_AUTH_PATH = join8(homedir6(), ".codex", "auth.json");
6322
+ var GH_HOSTS_PATH = join8(homedir6(), ".config", "gh", "hosts.yml");
6323
+ var GIT_CREDENTIALS_PATH = join8(homedir6(), ".git-credentials");
6318
6324
  function detectClaudeAuthMethod() {
6319
6325
  if (existsSync2(CLAUDE_CREDENTIALS_PATH)) {
6320
6326
  return "oauth";
@@ -6344,10 +6350,10 @@ function detectCursorAuthMethod() {
6344
6350
  return ENGINE_ENV.CURSOR_API_KEY ? "api_key" : "none";
6345
6351
  }
6346
6352
  function detectOpencodeAuthMethod() {
6347
- return existsSync2(OPENCODE_AUTH_PATH) || ENGINE_ENV.OPENROUTER_API_KEY ? "api_key" : "none";
6353
+ return existsSync2(OPENCODE_AUTH_PATH) ? "api_key" : "none";
6348
6354
  }
6349
6355
  function detectPiAuthMethod() {
6350
- return ENGINE_ENV.OPENROUTER_API_KEY ? "api_key" : "none";
6356
+ return existsSync2(PI_AUTH_PATH) ? "api_key" : "none";
6351
6357
  }
6352
6358
  async function detectGitIdentityConfigured() {
6353
6359
  try {
@@ -6520,8 +6526,8 @@ var environmentDetailsService = new EnvironmentDetailsService();
6520
6526
 
6521
6527
  // src/services/start-hook-logs-service.ts
6522
6528
  import { mkdir as mkdir5, readFile as readFile5, writeFile as writeFile3, readdir as readdir2 } from "fs/promises";
6523
- import { homedir as homedir6 } from "os";
6524
- import { join as join8 } from "path";
6529
+ import { homedir as homedir7 } from "os";
6530
+ import { join as join9 } from "path";
6525
6531
 
6526
6532
  // src/services/hook-log-files.ts
6527
6533
  import { createHash } from "crypto";
@@ -6533,7 +6539,7 @@ function repoHookLogFilename(repoName) {
6533
6539
  }
6534
6540
 
6535
6541
  // src/services/start-hook-logs-service.ts
6536
- var LOGS_DIR = join8(homedir6(), ".replicas", "start-hook-logs");
6542
+ var LOGS_DIR = join9(homedir7(), ".replicas", "start-hook-logs");
6537
6543
  function withPreview(stored) {
6538
6544
  const preview = buildHookOutputPreview(stored.output);
6539
6545
  return { ...stored, ...preview };
@@ -6571,7 +6577,7 @@ var StartHookLogsService = class {
6571
6577
  await this.ensureDir();
6572
6578
  const log = { hookType, hookName, repoName: hookName, ...entry };
6573
6579
  const filename = hookType === "environment" ? ENVIRONMENT_HOOK_LOG_FILENAME : repoHookLogFilename(hookName);
6574
- await writeFile3(join8(LOGS_DIR, filename), `${JSON.stringify(log, null, 2)}
6580
+ await writeFile3(join9(LOGS_DIR, filename), `${JSON.stringify(log, null, 2)}
6575
6581
  `, "utf-8");
6576
6582
  }
6577
6583
  async saveEnvironmentLog(entry) {
@@ -6596,7 +6602,7 @@ var StartHookLogsService = class {
6596
6602
  continue;
6597
6603
  }
6598
6604
  try {
6599
- const raw = await readFile5(join8(LOGS_DIR, file), "utf-8");
6605
+ const raw = await readFile5(join9(LOGS_DIR, file), "utf-8");
6600
6606
  const stored = normalizeStored(JSON.parse(raw));
6601
6607
  if (stored) {
6602
6608
  logs.push(withPreview(stored));
@@ -6615,7 +6621,7 @@ var StartHookLogsService = class {
6615
6621
  async getFullOutput(hookType, hookName) {
6616
6622
  const filename = hookType === "environment" ? ENVIRONMENT_HOOK_LOG_FILENAME : repoHookLogFilename(hookName);
6617
6623
  try {
6618
- const raw = await readFile5(join8(LOGS_DIR, filename), "utf-8");
6624
+ const raw = await readFile5(join9(LOGS_DIR, filename), "utf-8");
6619
6625
  const stored = normalizeStored(JSON.parse(raw));
6620
6626
  if (!stored || stored.hookType !== hookType || stored.hookName !== hookName) {
6621
6627
  return null;
@@ -6632,7 +6638,7 @@ var StartHookLogsService = class {
6632
6638
  var startHookLogsService = new StartHookLogsService();
6633
6639
 
6634
6640
  // src/services/replicas-config-service.ts
6635
- var START_HOOKS_LOG = join9(homedir7(), ".replicas", "startHooks.log");
6641
+ var START_HOOKS_LOG = join10(homedir8(), ".replicas", "startHooks.log");
6636
6642
  var START_HOOKS_RUNNING_PROMPT = `IMPORTANT - Start Hooks Running:
6637
6643
  Start hooks are shell commands/scripts set by repository owners that run on workspace startup.
6638
6644
  These hooks are currently executing in the background. You can:
@@ -6643,7 +6649,7 @@ The start hooks may install dependencies, build projects, or perform other setup
6643
6649
  If your task depends on setup being complete, check the log file before proceeding.`;
6644
6650
  async function readReplicasConfigFromDir(dirPath) {
6645
6651
  for (const filename of REPLICAS_CONFIG_FILENAMES) {
6646
- const configPath = join9(dirPath, filename);
6652
+ const configPath = join10(dirPath, filename);
6647
6653
  if (!existsSync3(configPath)) {
6648
6654
  continue;
6649
6655
  }
@@ -6713,7 +6719,7 @@ var ReplicasConfigService = class {
6713
6719
  const logLine = `[${timestamp}] ${message}
6714
6720
  `;
6715
6721
  try {
6716
- await mkdir6(join9(homedir7(), ".replicas"), { recursive: true });
6722
+ await mkdir6(join10(homedir8(), ".replicas"), { recursive: true });
6717
6723
  await appendFile(START_HOOKS_LOG, logLine, "utf-8");
6718
6724
  } catch (error) {
6719
6725
  console.error("Failed to write to start hooks log:", error);
@@ -6725,7 +6731,7 @@ var ReplicasConfigService = class {
6725
6731
  command: params.content,
6726
6732
  label: "env start hook",
6727
6733
  repoName: "environment",
6728
- cwd: homedir7(),
6734
+ cwd: homedir8(),
6729
6735
  timeout: params.timeoutMs ?? DEFAULT_START_HOOK_TIMEOUT_MS,
6730
6736
  onOutputChunk: params.onOutputChunk
6731
6737
  });
@@ -6848,7 +6854,7 @@ var ReplicasConfigService = class {
6848
6854
  this.hooksCompleted = false;
6849
6855
  this.hooksFailed = false;
6850
6856
  try {
6851
- await mkdir6(join9(homedir7(), ".replicas"), { recursive: true });
6857
+ await mkdir6(join10(homedir8(), ".replicas"), { recursive: true });
6852
6858
  await writeFile4(
6853
6859
  START_HOOKS_LOG,
6854
6860
  `=== Start Hooks Execution Log ===
@@ -7043,11 +7049,11 @@ var replicasConfigService = new ReplicasConfigService();
7043
7049
 
7044
7050
  // src/services/event-service.ts
7045
7051
  import { mkdir as mkdir7 } from "fs/promises";
7046
- import { homedir as homedir8 } from "os";
7047
- import { join as join10 } from "path";
7052
+ import { homedir as homedir9 } from "os";
7053
+ import { join as join11 } from "path";
7048
7054
  import { randomUUID } from "crypto";
7049
- var ENGINE_DIR = join10(homedir8(), ".replicas", "engine");
7050
- var EVENTS_FILE = join10(ENGINE_DIR, "events.jsonl");
7055
+ var ENGINE_DIR = join11(homedir9(), ".replicas", "engine");
7056
+ var EVENTS_FILE = join11(ENGINE_DIR, "events.jsonl");
7051
7057
  var EventService = class {
7052
7058
  subscribers = /* @__PURE__ */ new Map();
7053
7059
  writer = new StreamWriter();
@@ -7081,9 +7087,9 @@ var eventService = new EventService();
7081
7087
  import { mkdir as mkdir8, readFile as readFile7 } from "fs/promises";
7082
7088
  import { existsSync as existsSync4 } from "fs";
7083
7089
  import { randomUUID as randomUUID2 } from "crypto";
7084
- import { homedir as homedir9 } from "os";
7085
- import { dirname as dirname2, join as join11 } from "path";
7086
- var PREVIEW_PORTS_FILE = join11(homedir9(), ".replicas", "preview-ports.json");
7090
+ import { homedir as homedir10 } from "os";
7091
+ import { dirname as dirname2, join as join12 } from "path";
7092
+ var PREVIEW_PORTS_FILE = join12(homedir10(), ".replicas", "preview-ports.json");
7087
7093
  async function readPreviewsFile() {
7088
7094
  try {
7089
7095
  if (!existsSync4(PREVIEW_PORTS_FILE)) {
@@ -7195,8 +7201,8 @@ async function registerDesktopPreview() {
7195
7201
  // src/services/chat/chat-service.ts
7196
7202
  import { existsSync as existsSync7 } from "fs";
7197
7203
  import { appendFile as appendFile3, copyFile, mkdir as mkdir14, readFile as readFile14, rename as rename2, rm as rm2 } from "fs/promises";
7198
- import { homedir as homedir14 } from "os";
7199
- import { join as join24 } from "path";
7204
+ import { homedir as homedir15 } from "os";
7205
+ import { join as join25 } from "path";
7200
7206
  import { randomUUID as randomUUID5 } from "crypto";
7201
7207
 
7202
7208
  // src/managers/claude-manager.ts
@@ -7204,9 +7210,9 @@ import {
7204
7210
  query
7205
7211
  } from "@anthropic-ai/claude-agent-sdk";
7206
7212
  import { randomUUID as randomUUID4 } from "crypto";
7207
- import { dirname as dirname4, join as join14 } from "path";
7213
+ import { dirname as dirname4, join as join15 } from "path";
7208
7214
  import { mkdir as mkdir10 } from "fs/promises";
7209
- import { homedir as homedir11 } from "os";
7215
+ import { homedir as homedir12 } from "os";
7210
7216
 
7211
7217
  // src/utils/linear-converter.ts
7212
7218
  function linearThoughtToResponse(thought) {
@@ -7592,8 +7598,8 @@ function extractPlanFromCodexAspNotification(notification) {
7592
7598
  // src/utils/image-utils.ts
7593
7599
  import { randomUUID as randomUUID3 } from "crypto";
7594
7600
  import { mkdir as mkdir9, unlink as unlink2, writeFile as writeFile5 } from "fs/promises";
7595
- import { homedir as homedir10 } from "os";
7596
- import { join as join12 } from "path";
7601
+ import { homedir as homedir11 } from "os";
7602
+ import { join as join13 } from "path";
7597
7603
  function isImageMediaType(value) {
7598
7604
  return IMAGE_MEDIA_TYPES.includes(value);
7599
7605
  }
@@ -7693,14 +7699,14 @@ async function normalizeImages(images) {
7693
7699
  }
7694
7700
  return normalized;
7695
7701
  }
7696
- async function saveNormalizedImagesToTempFiles(images, tempImageDir = join12(homedir10(), ".replicas", "codex", "temp-images")) {
7702
+ async function saveNormalizedImagesToTempFiles(images, tempImageDir = join13(homedir11(), ".replicas", "codex", "temp-images")) {
7697
7703
  await mkdir9(tempImageDir, { recursive: true });
7698
7704
  const tempPaths = [];
7699
7705
  try {
7700
7706
  for (const image of images) {
7701
7707
  const ext = image.source.media_type.split("/")[1] || "png";
7702
7708
  const filename = `img_${randomUUID3()}.${ext}`;
7703
- const filepath = join12(tempImageDir, filename);
7709
+ const filepath = join13(tempImageDir, filename);
7704
7710
  await writeFile5(filepath, Buffer.from(image.source.data, "base64"));
7705
7711
  tempPaths.push(filepath);
7706
7712
  }
@@ -8285,7 +8291,7 @@ function reportCommandProtectionBlock(options) {
8285
8291
 
8286
8292
  // src/services/skill-registry-service.ts
8287
8293
  import { readFile as readFile8, readdir as readdir3, stat as stat2 } from "fs/promises";
8288
- import { dirname as dirname3, isAbsolute, join as join13, relative, resolve } from "path";
8294
+ import { dirname as dirname3, isAbsolute, join as join14, relative, resolve } from "path";
8289
8295
  var REGISTRY_ROOT_DIR = ".replicas/skill-registries";
8290
8296
  var REGISTRY_MANIFEST = "manifest.json";
8291
8297
  async function getSkillRegistryInventory(homeDir) {
@@ -8346,10 +8352,10 @@ async function scanRegistry(registryDir) {
8346
8352
  }
8347
8353
  async function findSkillCollections(registryDir) {
8348
8354
  const candidateRoots = [
8349
- { source: "skills", root: join13(registryDir, "skills") },
8350
- { source: "agents", root: join13(registryDir, ".agents", "skills") },
8351
- { source: "codex", root: join13(registryDir, ".codex", "skills") },
8352
- { source: "claude", root: join13(registryDir, ".claude", "skills") }
8355
+ { source: "skills", root: join14(registryDir, "skills") },
8356
+ { source: "agents", root: join14(registryDir, ".agents", "skills") },
8357
+ { source: "codex", root: join14(registryDir, ".codex", "skills") },
8358
+ { source: "claude", root: join14(registryDir, ".claude", "skills") }
8353
8359
  ];
8354
8360
  const collections = [];
8355
8361
  for (const { source, root } of candidateRoots) {
@@ -8363,9 +8369,9 @@ async function findSkillCollections(registryDir) {
8363
8369
  async function findSkillDirsInRoot(root) {
8364
8370
  const skillDirs = [];
8365
8371
  for (const dirent of await safeReadDir(root)) {
8366
- const skillDir = join13(root, dirent.name);
8372
+ const skillDir = join14(root, dirent.name);
8367
8373
  if (!await isDirectoryDirent(dirent, skillDir)) continue;
8368
- if (await fileExists(join13(skillDir, "SKILL.md"))) {
8374
+ if (await fileExists(join14(skillDir, "SKILL.md"))) {
8369
8375
  skillDirs.push(skillDir);
8370
8376
  }
8371
8377
  }
@@ -8375,9 +8381,9 @@ async function findTopLevelSkills(registryDir) {
8375
8381
  const skills = [];
8376
8382
  for (const dirent of await safeReadDir(registryDir)) {
8377
8383
  if (dirent.name.startsWith(".") || dirent.name === "skills" || dirent.name === "plugins") continue;
8378
- const skillDir = join13(registryDir, dirent.name);
8384
+ const skillDir = join14(registryDir, dirent.name);
8379
8385
  if (!await isDirectoryDirent(dirent, skillDir)) continue;
8380
- if (await fileExists(join13(skillDir, "SKILL.md"))) {
8386
+ if (await fileExists(join14(skillDir, "SKILL.md"))) {
8381
8387
  skills.push({ source: "root", skillDir });
8382
8388
  }
8383
8389
  }
@@ -8388,10 +8394,10 @@ async function findClaudePluginRoots(registryDir) {
8388
8394
  async function walk(dir) {
8389
8395
  for (const dirent of await safeReadDir(dir)) {
8390
8396
  if (dirent.name === ".git") continue;
8391
- const child = join13(dir, dirent.name);
8397
+ const child = join14(dir, dirent.name);
8392
8398
  if (!await isDirectoryDirent(dirent, child)) continue;
8393
8399
  if (dirent.name === ".claude-plugin") {
8394
- if (await fileExists(join13(child, "plugin.json"))) {
8400
+ if (await fileExists(join14(child, "plugin.json"))) {
8395
8401
  roots.push(dirname3(child));
8396
8402
  }
8397
8403
  continue;
@@ -8403,7 +8409,7 @@ async function findClaudePluginRoots(registryDir) {
8403
8409
  return uniqueStrings(roots);
8404
8410
  }
8405
8411
  async function hasCodexMarketplace(registryDir) {
8406
- return await fileExists(join13(registryDir, ".agents", "plugins", "marketplace.json")) || await fileExists(join13(registryDir, ".codex", "plugins", "marketplace.json"));
8412
+ return await fileExists(join14(registryDir, ".agents", "plugins", "marketplace.json")) || await fileExists(join14(registryDir, ".codex", "plugins", "marketplace.json"));
8407
8413
  }
8408
8414
  async function installCodexRegistryPlugins(client, inventory) {
8409
8415
  const cwds = inventory.codexMarketplaceCwds;
@@ -8453,10 +8459,10 @@ function isSkillRegistryEntry(value) {
8453
8459
  return "index" in value && typeof value.index === "number" && "name" in value && typeof value.name === "string" && "url" in value && typeof value.url === "string" && "checkoutPath" in value && typeof value.checkoutPath === "string";
8454
8460
  }
8455
8461
  function getRegistryRoot(homeDir) {
8456
- return join13(homeDir, REGISTRY_ROOT_DIR);
8462
+ return join14(homeDir, REGISTRY_ROOT_DIR);
8457
8463
  }
8458
8464
  function getManifestPath(homeDir) {
8459
- return join13(getRegistryRoot(homeDir), REGISTRY_MANIFEST);
8465
+ return join14(getRegistryRoot(homeDir), REGISTRY_MANIFEST);
8460
8466
  }
8461
8467
  function emptyInventory(registryRoot) {
8462
8468
  return {
@@ -8803,7 +8809,7 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
8803
8809
  authRetrying = false;
8804
8810
  constructor(options) {
8805
8811
  super(options);
8806
- this.historyFilePath = options.historyFilePath ?? join14(homedir11(), ".replicas", "claude", "history.jsonl");
8812
+ this.historyFilePath = options.historyFilePath ?? join15(homedir12(), ".replicas", "claude", "history.jsonl");
8807
8813
  this.historyFile = new CodexHistoryFile(this.historyFilePath);
8808
8814
  this.systemPromptOverride = options.systemPromptOverride;
8809
8815
  this.toolsOverride = options.tools;
@@ -9735,7 +9741,7 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
9735
9741
 
9736
9742
  // src/managers/codex-asp/codex-asp-manager.ts
9737
9743
  import { readdir as readdir4 } from "fs/promises";
9738
- import { join as join16 } from "path";
9744
+ import { join as join17 } from "path";
9739
9745
 
9740
9746
  // src/managers/codex-asp/app-server-process.ts
9741
9747
  import { spawn as spawn3 } from "child_process";
@@ -9936,7 +9942,7 @@ var DEFAULT_CODEX_ARGS = ["app-server", "--listen", "stdio://"];
9936
9942
  var MIN_CODEX_CLI_VERSION = "0.144.6";
9937
9943
  var CODEX_UPGRADE_TIMEOUT_MS = 12e4;
9938
9944
  var codexCliVersionEnsured = null;
9939
- var ENGINE_PACKAGE_VERSION = "0.1.500";
9945
+ var ENGINE_PACKAGE_VERSION = "0.1.501";
9940
9946
  var INITIALIZE_METHOD = "initialize";
9941
9947
  var INITIALIZED_NOTIFICATION = "initialized";
9942
9948
  var ACCOUNT_LOGIN_START_METHOD = "account/login/start";
@@ -10861,16 +10867,16 @@ var TranscriptUpdateCoalescer = class {
10861
10867
  };
10862
10868
 
10863
10869
  // src/services/chat/history-paths.ts
10864
- import { homedir as homedir12 } from "os";
10865
- import { join as join15 } from "path";
10866
- var ENGINE_DIR2 = join15(homedir12(), ".replicas", "engine");
10867
- var CHATS_FILE = join15(ENGINE_DIR2, "chats.json");
10868
- var CLAUDE_HISTORY_DIR = join15(ENGINE_DIR2, "claude-histories");
10869
- var RELAY_HISTORY_DIR = join15(ENGINE_DIR2, "relay-histories");
10870
- var CODEX_HISTORY_DIR = join15(ENGINE_DIR2, "codex-histories");
10871
- var CURSOR_HISTORY_DIR = join15(ENGINE_DIR2, "cursor-histories");
10872
- var OPENCODE_HISTORY_DIR = join15(ENGINE_DIR2, "opencode-histories");
10873
- var PI_HISTORY_DIR = join15(ENGINE_DIR2, "pi-histories");
10870
+ import { homedir as homedir13 } from "os";
10871
+ import { join as join16 } from "path";
10872
+ var ENGINE_DIR2 = join16(homedir13(), ".replicas", "engine");
10873
+ var CHATS_FILE = join16(ENGINE_DIR2, "chats.json");
10874
+ var CLAUDE_HISTORY_DIR = join16(ENGINE_DIR2, "claude-histories");
10875
+ var RELAY_HISTORY_DIR = join16(ENGINE_DIR2, "relay-histories");
10876
+ var CODEX_HISTORY_DIR = join16(ENGINE_DIR2, "codex-histories");
10877
+ var CURSOR_HISTORY_DIR = join16(ENGINE_DIR2, "cursor-histories");
10878
+ var OPENCODE_HISTORY_DIR = join16(ENGINE_DIR2, "opencode-histories");
10879
+ var PI_HISTORY_DIR = join16(ENGINE_DIR2, "pi-histories");
10874
10880
  var HISTORY_DIR_BY_PROVIDER = {
10875
10881
  claude: CLAUDE_HISTORY_DIR,
10876
10882
  relay: RELAY_HISTORY_DIR,
@@ -10916,7 +10922,7 @@ async function readCodexAspThreadHistory(threadId) {
10916
10922
  }
10917
10923
  for (const entry of entries) {
10918
10924
  if (!entry.isFile() || !entry.name.endsWith(".jsonl")) continue;
10919
- const history = await new CodexHistoryFile(join16(CODEX_HISTORY_DIR, entry.name)).load();
10925
+ const history = await new CodexHistoryFile(join17(CODEX_HISTORY_DIR, entry.name)).load();
10920
10926
  const transcript = history.transcriptsByThreadId.get(threadId);
10921
10927
  if (transcript) {
10922
10928
  return {
@@ -12133,7 +12139,7 @@ var CodexAspManager = class extends CodingAgentManager {
12133
12139
 
12134
12140
  // src/managers/cursor-manager.ts
12135
12141
  import { mkdir as mkdir11, readFile as readFile10, readdir as readdir5 } from "fs/promises";
12136
- import { basename, dirname as dirname5, extname, join as join17 } from "path";
12142
+ import { basename, dirname as dirname5, extname, join as join18 } from "path";
12137
12143
  import { parse as parseYaml2 } from "yaml";
12138
12144
  import { Agent as CursorAgent } from "@cursor/sdk";
12139
12145
  var CURSOR_SLASH_COMMANDS_CACHE_MS = 3e4;
@@ -12192,7 +12198,7 @@ async function listCursorCommandsInDirectory(directory) {
12192
12198
  const name = basename(entry.name, ".md");
12193
12199
  let description;
12194
12200
  try {
12195
- description = extractCursorCommandDescription(await readFile10(join17(directory, entry.name), "utf8"));
12201
+ description = extractCursorCommandDescription(await readFile10(join18(directory, entry.name), "utf8"));
12196
12202
  } catch (error) {
12197
12203
  console.warn("[CursorManager] Failed to read slash command file:", error);
12198
12204
  }
@@ -12214,7 +12220,7 @@ var CursorManager = class extends CodingAgentManager {
12214
12220
  slashCommandsRequest = null;
12215
12221
  constructor(options) {
12216
12222
  super(options);
12217
- this.historyFilePath = options.historyFilePath ?? join17(ENGINE_ENV.HOME_DIR, ".replicas", "cursor", "history.jsonl");
12223
+ this.historyFilePath = options.historyFilePath ?? join18(ENGINE_ENV.HOME_DIR, ".replicas", "cursor", "history.jsonl");
12218
12224
  this.historyFile = new CodexHistoryFile(this.historyFilePath);
12219
12225
  this.initializeManager(this.processMessageInternal.bind(this));
12220
12226
  }
@@ -12265,7 +12271,7 @@ var CursorManager = class extends CodingAgentManager {
12265
12271
  this.slashCommandsRequest ??= (async () => {
12266
12272
  try {
12267
12273
  const repoDirectories = await getAgentAdditionalDirectories();
12268
- const commandDirectories = [this.workingDirectory, ...repoDirectories, ENGINE_ENV.HOME_DIR].map((directory) => join17(directory, ".cursor", "commands"));
12274
+ const commandDirectories = [this.workingDirectory, ...repoDirectories, ENGINE_ENV.HOME_DIR].map((directory) => join18(directory, ".cursor", "commands"));
12269
12275
  const commands = mergeSlashCommands(
12270
12276
  ...await Promise.all(commandDirectories.map(listCursorCommandsInDirectory))
12271
12277
  );
@@ -12514,7 +12520,7 @@ ${request.message}` : request.message;
12514
12520
  // src/managers/opencode-manager.ts
12515
12521
  import { existsSync as existsSync6 } from "fs";
12516
12522
  import { mkdir as mkdir12, readFile as readFile11 } from "fs/promises";
12517
- import { delimiter, dirname as dirname6, join as join18 } from "path";
12523
+ import { delimiter, dirname as dirname6, join as join19 } from "path";
12518
12524
  import { randomBytes as randomBytes2 } from "crypto";
12519
12525
  import { fileURLToPath } from "url";
12520
12526
  import { Agent } from "undici";
@@ -12524,8 +12530,7 @@ import {
12524
12530
  createOpencodeServer
12525
12531
  } from "@opencode-ai/sdk/v2";
12526
12532
  var OPENCODE_SHIM_DIR = dirname6(fileURLToPath(new URL("../../scripts/opencode", import.meta.url)));
12527
- var OPENCODE_CONFIG_PATH = join18(ENGINE_ENV.HOME_DIR, ".config", "opencode", "opencode.json");
12528
- var OPENCODE_AUTH_PATH2 = join18(ENGINE_ENV.HOME_DIR, ".local", "share", "opencode", "auth.json");
12533
+ var OPENCODE_CONFIG_PATH = join19(ENGINE_ENV.HOME_DIR, ".config", "opencode", "opencode.json");
12529
12534
  var OPENCODE_FETCH_DISPATCHER = new Agent({ headersTimeout: 0, bodyTimeout: 0 });
12530
12535
  var OPENCODE_SERVER_STARTUP_TIMEOUT_MS = 3e4;
12531
12536
  var OPENCODE_WORKSPACE_PERMISSION = {
@@ -12559,11 +12564,11 @@ var opencodeAuthSchema = z5.record(z5.string(), z5.object({
12559
12564
  type: z5.string().optional(),
12560
12565
  key: z5.string().optional()
12561
12566
  }));
12562
- async function hasOpenCodeGoCredentials() {
12563
- if (!existsSync6(OPENCODE_AUTH_PATH2)) return false;
12567
+ async function hasOpencodeCredentials(provider) {
12568
+ if (!existsSync6(OPENCODE_AUTH_PATH)) return false;
12564
12569
  try {
12565
- const auth = opencodeAuthSchema.safeParse(JSON.parse(await readFile11(OPENCODE_AUTH_PATH2, "utf8")));
12566
- return auth.success && auth.data[OPENCODE_GO_PROVIDER]?.type === "api" && Boolean(auth.data[OPENCODE_GO_PROVIDER]?.key);
12570
+ const auth = opencodeAuthSchema.safeParse(JSON.parse(await readFile11(OPENCODE_AUTH_PATH, "utf8")));
12571
+ return auth.success && auth.data[provider]?.type === "api" && Boolean(auth.data[provider]?.key);
12567
12572
  } catch {
12568
12573
  return false;
12569
12574
  }
@@ -12573,7 +12578,7 @@ function getOpenCodeGoModel(model) {
12573
12578
  }
12574
12579
  async function opencodeConfig(model) {
12575
12580
  let config;
12576
- if (await hasOpenCodeGoCredentials()) {
12581
+ if (await hasOpencodeCredentials(OPENCODE_GO_PROVIDER)) {
12577
12582
  config = {
12578
12583
  enabled_providers: [OPENCODE_GO_PROVIDER],
12579
12584
  model: `${OPENCODE_GO_PROVIDER}/${model}`,
@@ -12587,10 +12592,7 @@ async function opencodeConfig(model) {
12587
12592
  model: `openrouter/${model}`,
12588
12593
  provider: {
12589
12594
  openrouter: {
12590
- models: Object.fromEntries(models.map((candidate) => [candidate, {}])),
12591
- options: {
12592
- apiKey: "{env:OPENROUTER_API_KEY}"
12593
- }
12595
+ models: Object.fromEntries(models.map((candidate) => [candidate, {}]))
12594
12596
  }
12595
12597
  },
12596
12598
  permission: OPENCODE_WORKSPACE_PERMISSION,
@@ -12754,7 +12756,7 @@ var OpencodeManager = class extends CodingAgentManager {
12754
12756
  constructor(options) {
12755
12757
  super(options);
12756
12758
  this.sessionId = options.initialSessionId;
12757
- this.historyFilePath = options.historyFilePath ?? join18(ENGINE_ENV.HOME_DIR, ".replicas", "opencode", "history.jsonl");
12759
+ this.historyFilePath = options.historyFilePath ?? join19(ENGINE_ENV.HOME_DIR, ".replicas", "opencode", "history.jsonl");
12758
12760
  this.historyFile = new CodexHistoryFile(this.historyFilePath);
12759
12761
  this.initializeManager(this.processMessageInternal.bind(this));
12760
12762
  }
@@ -12825,7 +12827,7 @@ var OpencodeManager = class extends CodingAgentManager {
12825
12827
  return this.slashCommandsRequest;
12826
12828
  }
12827
12829
  async ensureClient(model) {
12828
- const providerId = await hasOpenCodeGoCredentials() ? OPENCODE_GO_PROVIDER : "openrouter";
12830
+ const providerId = await hasOpencodeCredentials(OPENCODE_GO_PROVIDER) ? OPENCODE_GO_PROVIDER : "openrouter";
12829
12831
  if (this.client && this.providerId !== providerId) {
12830
12832
  this.eventAbortController?.abort();
12831
12833
  this.server?.close();
@@ -12838,7 +12840,7 @@ var OpencodeManager = class extends CodingAgentManager {
12838
12840
  if (this.client && (providerId === OPENCODE_GO_PROVIDER || this.configuredModels.has(configuredModel))) {
12839
12841
  return this.client;
12840
12842
  }
12841
- if (!ENGINE_ENV.OPENROUTER_API_KEY && this.providerId !== OPENCODE_GO_PROVIDER) {
12843
+ if (this.providerId !== OPENCODE_GO_PROVIDER && !await hasOpencodeCredentials("openrouter")) {
12842
12844
  throw new Error("OpenCode Go or OpenRouter credentials are not configured for Opencode in this workspace.");
12843
12845
  }
12844
12846
  this.eventAbortController?.abort();
@@ -13245,7 +13247,7 @@ var OpencodeManager = class extends CodingAgentManager {
13245
13247
 
13246
13248
  // src/managers/pi-manager.ts
13247
13249
  import { mkdir as mkdir13 } from "fs/promises";
13248
- import { dirname as dirname7, join as join19 } from "path";
13250
+ import { dirname as dirname7, join as join20 } from "path";
13249
13251
  import {
13250
13252
  AuthStorage,
13251
13253
  createAgentSession,
@@ -13285,7 +13287,7 @@ var PiManager = class extends CodingAgentManager {
13285
13287
  historyFile;
13286
13288
  constructor(options) {
13287
13289
  super(options);
13288
- this.historyFilePath = options.historyFilePath ?? join19(PI_HISTORY_DIR, `${Date.now()}.jsonl`);
13290
+ this.historyFilePath = options.historyFilePath ?? join20(PI_HISTORY_DIR, `${Date.now()}.jsonl`);
13289
13291
  this.historyFile = new CodexHistoryFile(this.historyFilePath);
13290
13292
  this.initializeManager(this.processMessageInternal.bind(this));
13291
13293
  }
@@ -13312,6 +13314,13 @@ var PiManager = class extends CodingAgentManager {
13312
13314
  await this.initialized;
13313
13315
  return mergeSlashCommands(...(this.session?.promptTemplates ?? []).map((template) => createProviderSlashCommand("pi", template.name, template.description)).filter((command) => Boolean(command)));
13314
13316
  }
13317
+ async enqueueMessage(request) {
13318
+ await this.initialized;
13319
+ if (!this.session && !await this.getOpenRouterApiKey()) {
13320
+ throw new Error("OpenRouter authentication is missing for Pi. Add an OpenRouter API key in Settings \u2192 Coding agents.");
13321
+ }
13322
+ return this.messageQueue.enqueue(request);
13323
+ }
13315
13324
  dispose() {
13316
13325
  this.unsubscribe?.();
13317
13326
  this.unsubscribe = null;
@@ -13329,9 +13338,9 @@ var PiManager = class extends CodingAgentManager {
13329
13338
  }
13330
13339
  return this.session;
13331
13340
  }
13332
- const apiKey = ENGINE_ENV.OPENROUTER_API_KEY;
13341
+ const authStorage = AuthStorage.create(PI_AUTH_PATH);
13342
+ const apiKey = await this.getOpenRouterApiKey(authStorage);
13333
13343
  if (!apiKey) throw new Error("OpenRouter API key is not configured for Pi.");
13334
- const authStorage = AuthStorage.inMemory({ openrouter: { type: "api_key", key: apiKey } });
13335
13344
  const modelRegistry = ModelRegistry.create(authStorage);
13336
13345
  const openRouterModels = modelRegistry.getAll().filter((candidate) => candidate.provider === "openrouter");
13337
13346
  const modelTemplate = openRouterModels[0];
@@ -13361,7 +13370,7 @@ var PiManager = class extends CodingAgentManager {
13361
13370
  const sessionManager = this.initialSessionId ? SessionManager.open(this.initialSessionId, PI_HISTORY_DIR, this.workingDirectory) : SessionManager.create(this.workingDirectory, PI_HISTORY_DIR);
13362
13371
  const resourceLoader = new DefaultResourceLoader({
13363
13372
  cwd: this.workingDirectory,
13364
- agentDir: join19(ENGINE_ENV.HOME_DIR, ".pi", "agent"),
13373
+ agentDir: join20(ENGINE_ENV.HOME_DIR, ".pi", "agent"),
13365
13374
  extensionFactories: [registerCommandProtection(this.workingDirectory)],
13366
13375
  appendSystemPrompt: [this.buildCombinedInstructions() ?? ""]
13367
13376
  });
@@ -13383,6 +13392,10 @@ var PiManager = class extends CodingAgentManager {
13383
13392
  this.unsubscribe = this.session.subscribe((event) => this.handleEvent(event));
13384
13393
  return this.session;
13385
13394
  }
13395
+ async getOpenRouterApiKey(authStorage = AuthStorage.create(PI_AUTH_PATH)) {
13396
+ const credential = authStorage.get("openrouter");
13397
+ return credential?.type === "api_key" ? credential.key : void 0;
13398
+ }
13386
13399
  handleEvent(event) {
13387
13400
  const payload = eventPayload(event);
13388
13401
  this.recordHistoryEvent(`pi-${event.type}`, payload, this.historyFile);
@@ -14066,18 +14079,18 @@ var keepAliveService = new KeepAliveService();
14066
14079
 
14067
14080
  // src/services/canvas-service.ts
14068
14081
  import { readdir as readdir6, readFile as readFile12, stat as stat3 } from "fs/promises";
14069
- import { homedir as homedir13 } from "os";
14070
- import { join as join20 } from "path";
14082
+ import { homedir as homedir14 } from "os";
14083
+ import { join as join21 } from "path";
14071
14084
  var GLOBAL_CANVAS_DIRECTORIES = [
14072
- join20(homedir13(), ".claude", "plans"),
14073
- join20(process.env.XDG_DATA_HOME ?? join20(homedir13(), ".local", "share"), "opencode", "plans"),
14074
- join20(homedir13(), ".replicas", "canvas")
14085
+ join21(homedir14(), ".claude", "plans"),
14086
+ join21(process.env.XDG_DATA_HOME ?? join21(homedir14(), ".local", "share"), "opencode", "plans"),
14087
+ join21(homedir14(), ".replicas", "canvas")
14075
14088
  ];
14076
14089
  async function canvasDirectories() {
14077
14090
  const repositories = await gitService.listRepositories().catch(() => []);
14078
14091
  return [
14079
14092
  ...GLOBAL_CANVAS_DIRECTORIES,
14080
- ...repositories.map((repository) => join20(repository.path, ".opencode", "plans"))
14093
+ ...repositories.map((repository) => join21(repository.path, ".opencode", "plans"))
14081
14094
  ];
14082
14095
  }
14083
14096
  var CanvasService = class {
@@ -14097,7 +14110,7 @@ var CanvasService = class {
14097
14110
  const { kind } = classifyCanvasFilename(entry.name);
14098
14111
  let sizeBytes = 0;
14099
14112
  try {
14100
- const s = await stat3(join20(directory, entry.name));
14113
+ const s = await stat3(join21(directory, entry.name));
14101
14114
  sizeBytes = s.size;
14102
14115
  } catch {
14103
14116
  continue;
@@ -14112,7 +14125,7 @@ var CanvasService = class {
14112
14125
  if (!safe) return null;
14113
14126
  const { kind, mimeType } = classifyCanvasFilename(safe);
14114
14127
  for (const directory of await canvasDirectories()) {
14115
- const filePath = join20(directory, safe);
14128
+ const filePath = join21(directory, safe);
14116
14129
  let sizeBytes = 0;
14117
14130
  let updatedAt = "";
14118
14131
  try {
@@ -14249,13 +14262,13 @@ async function reconcileCanvasItems(filenames) {
14249
14262
 
14250
14263
  // src/services/upload-chat-transcripts.ts
14251
14264
  import { readdir as readdir7, readFile as readFile13 } from "fs/promises";
14252
- import { basename as basename2, join as join22 } from "path";
14265
+ import { basename as basename2, join as join23 } from "path";
14253
14266
 
14254
14267
  // src/services/chat/chat-senders.ts
14255
- import { join as join21 } from "path";
14256
- var CHAT_SENDERS_DIR = join21(ENGINE_DIR2, "chat-senders");
14268
+ import { join as join22 } from "path";
14269
+ var CHAT_SENDERS_DIR = join22(ENGINE_DIR2, "chat-senders");
14257
14270
  function chatMessageSendersFilePath(chatId) {
14258
- return join21(CHAT_SENDERS_DIR, `${chatId}.jsonl`);
14271
+ return join22(CHAT_SENDERS_DIR, `${chatId}.jsonl`);
14259
14272
  }
14260
14273
  function parseChatMessageSendersJsonl(content) {
14261
14274
  return content.split("\n").flatMap((line) => {
@@ -14271,9 +14284,9 @@ function parseChatMessageSendersJsonl(content) {
14271
14284
 
14272
14285
  // src/services/upload-chat-transcripts.ts
14273
14286
  var HISTORY_DIRS = [
14274
- join22(ENGINE_DIR2, "claude-histories"),
14275
- join22(ENGINE_DIR2, "relay-histories"),
14276
- join22(ENGINE_DIR2, "codex-histories")
14287
+ join23(ENGINE_DIR2, "claude-histories"),
14288
+ join23(ENGINE_DIR2, "relay-histories"),
14289
+ join23(ENGINE_DIR2, "codex-histories")
14277
14290
  ];
14278
14291
  async function flushAllChatTranscripts(chatsById = /* @__PURE__ */ new Map()) {
14279
14292
  let flushed = 0;
@@ -14290,7 +14303,7 @@ async function flushAllChatTranscripts(chatsById = /* @__PURE__ */ new Map()) {
14290
14303
  if (!entry.endsWith(".jsonl")) continue;
14291
14304
  const chatId = basename2(entry, ".jsonl");
14292
14305
  tasks.push(
14293
- uploadChatTranscript(chatId, join22(dir, entry), chatsById.get(chatId)).then(() => {
14306
+ uploadChatTranscript(chatId, join23(dir, entry), chatsById.get(chatId)).then(() => {
14294
14307
  flushed++;
14295
14308
  }).catch((err) => {
14296
14309
  failed++;
@@ -14380,7 +14393,7 @@ async function flushRepoState() {
14380
14393
  // src/services/upload-engine-logs.ts
14381
14394
  import { createReadStream } from "fs";
14382
14395
  import { readdir as readdir8, stat as stat4 } from "fs/promises";
14383
- import { join as join23 } from "path";
14396
+ import { join as join24 } from "path";
14384
14397
  var MAX_ENGINE_LOG_FLUSH_SESSIONS = 10;
14385
14398
  var MAX_ENGINE_LOG_FLUSH_BYTES = 5 * 1024 * 1024;
14386
14399
  var ENGINE_LOG_FLUSH_TIMEOUT_MS = 2e4;
@@ -14409,7 +14422,7 @@ async function flushAllEngineLogs() {
14409
14422
  const candidates = (await Promise.all(filenames.slice(0, MAX_ENGINE_LOG_FLUSH_SESSIONS).map(async (filename) => {
14410
14423
  try {
14411
14424
  const sessionId = filename.slice(0, -".log".length);
14412
- const filePath = join23(LOG_DIR, filename);
14425
+ const filePath = join24(LOG_DIR, filename);
14413
14426
  const fileStat = await runBeforeDeadline(() => stat4(filePath), deadline);
14414
14427
  if (!fileStat.isFile()) {
14415
14428
  skipped++;
@@ -14505,17 +14518,16 @@ async function uploadEngineLog(input, timeoutMs) {
14505
14518
  }
14506
14519
 
14507
14520
  // src/services/chat/chat-service.ts
14508
- var CODEX_AUTH_PATH2 = join24(homedir14(), ".codex", "auth.json");
14509
- var OPENCODE_AUTH_PATH3 = join24(homedir14(), ".local", "share", "opencode", "auth.json");
14521
+ var CODEX_AUTH_PATH2 = join25(homedir15(), ".codex", "auth.json");
14510
14522
  var CHATS_BACKUP_FILE = `${CHATS_FILE}.bak`;
14511
14523
  function isCodexAvailable() {
14512
14524
  return existsSync7(CODEX_AUTH_PATH2) || Boolean(ENGINE_ENV.OPENAI_API_KEY);
14513
14525
  }
14514
14526
  function isOpencodeAvailable() {
14515
- return existsSync7(OPENCODE_AUTH_PATH3) || Boolean(ENGINE_ENV.OPENROUTER_API_KEY);
14527
+ return existsSync7(OPENCODE_AUTH_PATH);
14516
14528
  }
14517
14529
  function isPiAvailable() {
14518
- return Boolean(ENGINE_ENV.OPENROUTER_API_KEY);
14530
+ return existsSync7(PI_AUTH_PATH);
14519
14531
  }
14520
14532
  function isCursorAvailable() {
14521
14533
  return Boolean(ENGINE_ENV.CURSOR_API_KEY);
@@ -14972,7 +14984,7 @@ var ChatService = class {
14972
14984
  return descendants;
14973
14985
  }
14974
14986
  async deleteHistoryFile(persisted) {
14975
- await rm2(join24(HISTORY_DIR_BY_PROVIDER[persisted.provider], `${persisted.id}.jsonl`), { force: true });
14987
+ await rm2(join25(HISTORY_DIR_BY_PROVIDER[persisted.provider], `${persisted.id}.jsonl`), { force: true });
14976
14988
  await rm2(chatMessageSendersFilePath(persisted.id), { force: true });
14977
14989
  }
14978
14990
  async getChatHistory(chatId, page = {}) {
@@ -15048,7 +15060,7 @@ var ChatService = class {
15048
15060
  if (persisted.provider === "claude") {
15049
15061
  provider = new ClaudeManager({
15050
15062
  workingDirectory: this.workingDirectory,
15051
- historyFilePath: join24(CLAUDE_HISTORY_DIR, `${persisted.id}.jsonl`),
15063
+ historyFilePath: join25(CLAUDE_HISTORY_DIR, `${persisted.id}.jsonl`),
15052
15064
  initialSessionId: persisted.providerSessionId,
15053
15065
  onSaveSessionId: saveSession,
15054
15066
  onTurnComplete: onProviderTurnComplete,
@@ -15057,7 +15069,7 @@ var ChatService = class {
15057
15069
  } else if (persisted.provider === "relay") {
15058
15070
  provider = new RelayManager({
15059
15071
  workingDirectory: this.workingDirectory,
15060
- historyFilePath: join24(RELAY_HISTORY_DIR, `${persisted.id}.jsonl`),
15072
+ historyFilePath: join25(RELAY_HISTORY_DIR, `${persisted.id}.jsonl`),
15061
15073
  initialSessionId: persisted.providerSessionId,
15062
15074
  onSaveSessionId: saveSession,
15063
15075
  onTurnComplete: onProviderTurnComplete,
@@ -15071,7 +15083,7 @@ var ChatService = class {
15071
15083
  } else if (persisted.provider === "cursor") {
15072
15084
  provider = new CursorManager({
15073
15085
  workingDirectory: this.workingDirectory,
15074
- historyFilePath: join24(CURSOR_HISTORY_DIR, `${persisted.id}.jsonl`),
15086
+ historyFilePath: join25(CURSOR_HISTORY_DIR, `${persisted.id}.jsonl`),
15075
15087
  initialSessionId: persisted.providerSessionId,
15076
15088
  onSaveSessionId: saveSession,
15077
15089
  onTurnComplete: onProviderTurnComplete,
@@ -15080,7 +15092,7 @@ var ChatService = class {
15080
15092
  } else if (persisted.provider === "opencode") {
15081
15093
  provider = new OpencodeManager({
15082
15094
  workingDirectory: this.workingDirectory,
15083
- historyFilePath: join24(OPENCODE_HISTORY_DIR, `${persisted.id}.jsonl`),
15095
+ historyFilePath: join25(OPENCODE_HISTORY_DIR, `${persisted.id}.jsonl`),
15084
15096
  initialSessionId: persisted.providerSessionId,
15085
15097
  onSaveSessionId: saveSession,
15086
15098
  onTurnComplete: onProviderTurnComplete,
@@ -15089,7 +15101,7 @@ var ChatService = class {
15089
15101
  } else if (persisted.provider === "pi") {
15090
15102
  provider = new PiManager({
15091
15103
  workingDirectory: this.workingDirectory,
15092
- historyFilePath: join24(PI_HISTORY_DIR, `${persisted.id}.jsonl`),
15104
+ historyFilePath: join25(PI_HISTORY_DIR, `${persisted.id}.jsonl`),
15093
15105
  initialSessionId: persisted.providerSessionId,
15094
15106
  onSaveSessionId: saveSession,
15095
15107
  onTurnComplete: onProviderTurnComplete,
@@ -15098,7 +15110,7 @@ var ChatService = class {
15098
15110
  } else {
15099
15111
  provider = new CodexAspManager({
15100
15112
  workingDirectory: this.workingDirectory,
15101
- historyFilePath: join24(CODEX_HISTORY_DIR, `${persisted.id}.jsonl`),
15113
+ historyFilePath: join25(CODEX_HISTORY_DIR, `${persisted.id}.jsonl`),
15102
15114
  initialSessionId: persisted.providerSessionId,
15103
15115
  onSaveSessionId: saveSession,
15104
15116
  onTurnComplete: onProviderTurnComplete,
@@ -15247,7 +15259,7 @@ var ChatService = class {
15247
15259
  });
15248
15260
  uploadChatTranscript(
15249
15261
  chatId,
15250
- join24(HISTORY_DIR_BY_PROVIDER[chat.persisted.provider], `${chatId}.jsonl`),
15262
+ join25(HISTORY_DIR_BY_PROVIDER[chat.persisted.provider], `${chatId}.jsonl`),
15251
15263
  this.toSummary(chat)
15252
15264
  ).catch((err) => {
15253
15265
  console.error("[ChatService] Failed to upload chat transcript:", { chatId, err });
@@ -15383,7 +15395,7 @@ var ChatService = class {
15383
15395
  // src/services/repo-file-service.ts
15384
15396
  import { execFile as execFile2 } from "child_process";
15385
15397
  import { readFile as readFile15, realpath, stat as stat5 } from "fs/promises";
15386
- import { join as join25, resolve as resolve2, extname as extname2 } from "path";
15398
+ import { join as join26, resolve as resolve2, extname as extname2 } from "path";
15387
15399
  var CACHE_TTL_MS = 3e4;
15388
15400
  var SEARCH_TIMEOUT_MS = 15e3;
15389
15401
  var MAX_CONTENT_BYTES = 256 * 1024;
@@ -15543,7 +15555,7 @@ var RepoFileService = class {
15543
15555
  const repo = repos.find((r) => r.name === repoName);
15544
15556
  if (!repo) return null;
15545
15557
  try {
15546
- const fullPath = await realpath(resolve2(join25(repo.path, filePath)));
15558
+ const fullPath = await realpath(resolve2(join26(repo.path, filePath)));
15547
15559
  const repoRoot = await realpath(repo.path);
15548
15560
  const repoPrefix = repoRoot.endsWith("/") ? repoRoot : repoRoot + "/";
15549
15561
  if (!fullPath.startsWith(repoPrefix) && fullPath !== repoRoot) return null;
@@ -15651,20 +15663,20 @@ var RepoFileService = class {
15651
15663
  import { Hono } from "hono";
15652
15664
  import { z as z7 } from "zod";
15653
15665
  import { readdir as readdir10, stat as stat6, readFile as readFile18 } from "fs/promises";
15654
- import { join as join28, resolve as resolve3 } from "path";
15666
+ import { join as join29, resolve as resolve3 } from "path";
15655
15667
 
15656
15668
  // src/services/warm-hooks-service.ts
15657
15669
  import { spawn as spawn4 } from "child_process";
15658
15670
  import { readFile as readFile17 } from "fs/promises";
15659
15671
  import { existsSync as existsSync8 } from "fs";
15660
- import { join as join27 } from "path";
15672
+ import { join as join28 } from "path";
15661
15673
 
15662
15674
  // src/services/warm-hook-logs-service.ts
15663
15675
  import { mkdir as mkdir15, readFile as readFile16, writeFile as writeFile6, readdir as readdir9, appendFile as appendFile4, unlink as unlink3 } from "fs/promises";
15664
- import { homedir as homedir15 } from "os";
15665
- import { join as join26 } from "path";
15666
- var LOGS_DIR2 = join26(homedir15(), ".replicas", "warm-hook-logs");
15667
- var CURRENT_RUN_LOG = join26(LOGS_DIR2, "current-run.log");
15676
+ import { homedir as homedir16 } from "os";
15677
+ import { join as join27 } from "path";
15678
+ var LOGS_DIR2 = join27(homedir16(), ".replicas", "warm-hook-logs");
15679
+ var CURRENT_RUN_LOG = join27(LOGS_DIR2, "current-run.log");
15668
15680
  var GLOBAL_FILENAME = "global.json";
15669
15681
  function withPreview2(stored) {
15670
15682
  const preview = buildHookOutputPreview(stored.output);
@@ -15681,7 +15693,7 @@ var WarmHookLogsService = class {
15681
15693
  hookName: "organization",
15682
15694
  ...entry
15683
15695
  };
15684
- await writeFile6(join26(LOGS_DIR2, GLOBAL_FILENAME), `${JSON.stringify(log, null, 2)}
15696
+ await writeFile6(join27(LOGS_DIR2, GLOBAL_FILENAME), `${JSON.stringify(log, null, 2)}
15685
15697
  `, "utf-8");
15686
15698
  }
15687
15699
  async saveEnvironmentHookLog(entry) {
@@ -15691,7 +15703,7 @@ var WarmHookLogsService = class {
15691
15703
  hookName: "environment",
15692
15704
  ...entry
15693
15705
  };
15694
- await writeFile6(join26(LOGS_DIR2, ENVIRONMENT_HOOK_LOG_FILENAME), `${JSON.stringify(log, null, 2)}
15706
+ await writeFile6(join27(LOGS_DIR2, ENVIRONMENT_HOOK_LOG_FILENAME), `${JSON.stringify(log, null, 2)}
15695
15707
  `, "utf-8");
15696
15708
  }
15697
15709
  async saveRepoHookLog(repoName, entry) {
@@ -15701,7 +15713,7 @@ var WarmHookLogsService = class {
15701
15713
  hookName: repoName,
15702
15714
  ...entry
15703
15715
  };
15704
- await writeFile6(join26(LOGS_DIR2, repoHookLogFilename(repoName)), `${JSON.stringify(log, null, 2)}
15716
+ await writeFile6(join27(LOGS_DIR2, repoHookLogFilename(repoName)), `${JSON.stringify(log, null, 2)}
15705
15717
  `, "utf-8");
15706
15718
  }
15707
15719
  async getAllLogs() {
@@ -15720,7 +15732,7 @@ var WarmHookLogsService = class {
15720
15732
  continue;
15721
15733
  }
15722
15734
  try {
15723
- const raw = await readFile16(join26(LOGS_DIR2, file), "utf-8");
15735
+ const raw = await readFile16(join27(LOGS_DIR2, file), "utf-8");
15724
15736
  const stored = JSON.parse(raw);
15725
15737
  logs.push(withPreview2(stored));
15726
15738
  } catch {
@@ -15758,7 +15770,7 @@ var WarmHookLogsService = class {
15758
15770
  async getFullOutput(hookType, hookName) {
15759
15771
  const filename = hookType === "global" ? GLOBAL_FILENAME : hookType === "environment" ? ENVIRONMENT_HOOK_LOG_FILENAME : repoHookLogFilename(hookName);
15760
15772
  try {
15761
- const raw = await readFile16(join26(LOGS_DIR2, filename), "utf-8");
15773
+ const raw = await readFile16(join27(LOGS_DIR2, filename), "utf-8");
15762
15774
  const stored = JSON.parse(raw);
15763
15775
  if (stored.hookType !== hookType || stored.hookName !== hookName) {
15764
15776
  return null;
@@ -15777,7 +15789,7 @@ var warmHookLogsService = new WarmHookLogsService();
15777
15789
  // src/services/warm-hooks-service.ts
15778
15790
  async function readRepoWarmHook(repoPath) {
15779
15791
  for (const filename of REPLICAS_CONFIG_FILENAMES) {
15780
- const configPath = join27(repoPath, filename);
15792
+ const configPath = join28(repoPath, filename);
15781
15793
  if (!existsSync8(configPath)) {
15782
15794
  continue;
15783
15795
  }
@@ -17010,7 +17022,7 @@ data: ${JSON.stringify("Terminal session not found")}
17010
17022
  const logFiles = files.filter((f) => f.endsWith(".log"));
17011
17023
  const sessions = await Promise.all(
17012
17024
  logFiles.map(async (filename) => {
17013
- const filePath = join28(LOG_DIR, filename);
17025
+ const filePath = join29(LOG_DIR, filename);
17014
17026
  const fileStat = await stat6(filePath);
17015
17027
  const sessionId = filename.replace(/\.log$/, "");
17016
17028
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "replicas-engine",
3
- "version": "0.1.500",
3
+ "version": "0.1.501",
4
4
  "description": "Lightweight API server for Replicas workspaces",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",