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