replicas-engine 0.1.500 → 0.1.502

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 +170 -136
  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-v4";
615
615
 
616
616
  // ../shared/src/runtime-env.ts
617
617
  function shellQuotePosix(value) {
@@ -772,6 +772,11 @@ var SLASH_COMMANDS = [
772
772
  description: "Set, pause, resume, or clear a task goal.",
773
773
  argumentHint: "<objective | pause | resume | clear>",
774
774
  providers: ["codex"]
775
+ },
776
+ {
777
+ command: "/compact",
778
+ description: "Compact the conversation context.",
779
+ providers: ["codex"]
775
780
  }
776
781
  ];
777
782
  function mergeSlashCommands(...commandGroups) {
@@ -4855,7 +4860,6 @@ function loadEngineEnv() {
4855
4860
  ANTHROPIC_API_KEY: readEnv("ANTHROPIC_API_KEY"),
4856
4861
  OPENAI_API_KEY: readEnv("OPENAI_API_KEY"),
4857
4862
  CURSOR_API_KEY: readEnv("CURSOR_API_KEY"),
4858
- OPENROUTER_API_KEY: readEnv("OPENROUTER_API_KEY"),
4859
4863
  CLAUDE_CODE_USE_BEDROCK: readEnv("CLAUDE_CODE_USE_BEDROCK"),
4860
4864
  AWS_ACCESS_KEY_ID: readEnv("AWS_ACCESS_KEY_ID"),
4861
4865
  AWS_SECRET_ACCESS_KEY: readEnv("AWS_SECRET_ACCESS_KEY"),
@@ -6299,22 +6303,29 @@ var engineLogger = new EngineLogger();
6299
6303
  // src/services/replicas-config-service.ts
6300
6304
  import { readFile as readFile6, appendFile, writeFile as writeFile4, mkdir as mkdir6 } from "fs/promises";
6301
6305
  import { existsSync as existsSync3 } from "fs";
6302
- import { join as join9 } from "path";
6303
- import { homedir as homedir7 } from "os";
6306
+ import { join as join10 } from "path";
6307
+ import { homedir as homedir8 } from "os";
6304
6308
  import { spawn as spawn2 } from "child_process";
6305
6309
 
6306
6310
  // src/services/environment-details-service.ts
6307
6311
  import { mkdir as mkdir4, readFile as readFile4 } from "fs/promises";
6308
6312
  import { existsSync as existsSync2 } from "fs";
6313
+ import { homedir as homedir6 } from "os";
6314
+ import { join as join8 } from "path";
6315
+
6316
+ // src/managers/agent-auth-paths.ts
6309
6317
  import { homedir as homedir5 } from "os";
6310
6318
  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
6319
  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");
6320
+ var PI_AUTH_PATH = join7(homedir5(), ".pi", "agent", "auth.json");
6321
+
6322
+ // src/services/environment-details-service.ts
6323
+ var REPLICAS_DIR = join8(homedir6(), ".replicas");
6324
+ var DETAILS_FILE = join8(REPLICAS_DIR, "environment-details.json");
6325
+ var CLAUDE_CREDENTIALS_PATH = join8(homedir6(), ".claude", ".credentials.json");
6326
+ var CODEX_AUTH_PATH = join8(homedir6(), ".codex", "auth.json");
6327
+ var GH_HOSTS_PATH = join8(homedir6(), ".config", "gh", "hosts.yml");
6328
+ var GIT_CREDENTIALS_PATH = join8(homedir6(), ".git-credentials");
6318
6329
  function detectClaudeAuthMethod() {
6319
6330
  if (existsSync2(CLAUDE_CREDENTIALS_PATH)) {
6320
6331
  return "oauth";
@@ -6344,10 +6355,10 @@ function detectCursorAuthMethod() {
6344
6355
  return ENGINE_ENV.CURSOR_API_KEY ? "api_key" : "none";
6345
6356
  }
6346
6357
  function detectOpencodeAuthMethod() {
6347
- return existsSync2(OPENCODE_AUTH_PATH) || ENGINE_ENV.OPENROUTER_API_KEY ? "api_key" : "none";
6358
+ return existsSync2(OPENCODE_AUTH_PATH) ? "api_key" : "none";
6348
6359
  }
6349
6360
  function detectPiAuthMethod() {
6350
- return ENGINE_ENV.OPENROUTER_API_KEY ? "api_key" : "none";
6361
+ return existsSync2(PI_AUTH_PATH) ? "api_key" : "none";
6351
6362
  }
6352
6363
  async function detectGitIdentityConfigured() {
6353
6364
  try {
@@ -6520,8 +6531,8 @@ var environmentDetailsService = new EnvironmentDetailsService();
6520
6531
 
6521
6532
  // src/services/start-hook-logs-service.ts
6522
6533
  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";
6534
+ import { homedir as homedir7 } from "os";
6535
+ import { join as join9 } from "path";
6525
6536
 
6526
6537
  // src/services/hook-log-files.ts
6527
6538
  import { createHash } from "crypto";
@@ -6533,7 +6544,7 @@ function repoHookLogFilename(repoName) {
6533
6544
  }
6534
6545
 
6535
6546
  // src/services/start-hook-logs-service.ts
6536
- var LOGS_DIR = join8(homedir6(), ".replicas", "start-hook-logs");
6547
+ var LOGS_DIR = join9(homedir7(), ".replicas", "start-hook-logs");
6537
6548
  function withPreview(stored) {
6538
6549
  const preview = buildHookOutputPreview(stored.output);
6539
6550
  return { ...stored, ...preview };
@@ -6571,7 +6582,7 @@ var StartHookLogsService = class {
6571
6582
  await this.ensureDir();
6572
6583
  const log = { hookType, hookName, repoName: hookName, ...entry };
6573
6584
  const filename = hookType === "environment" ? ENVIRONMENT_HOOK_LOG_FILENAME : repoHookLogFilename(hookName);
6574
- await writeFile3(join8(LOGS_DIR, filename), `${JSON.stringify(log, null, 2)}
6585
+ await writeFile3(join9(LOGS_DIR, filename), `${JSON.stringify(log, null, 2)}
6575
6586
  `, "utf-8");
6576
6587
  }
6577
6588
  async saveEnvironmentLog(entry) {
@@ -6596,7 +6607,7 @@ var StartHookLogsService = class {
6596
6607
  continue;
6597
6608
  }
6598
6609
  try {
6599
- const raw = await readFile5(join8(LOGS_DIR, file), "utf-8");
6610
+ const raw = await readFile5(join9(LOGS_DIR, file), "utf-8");
6600
6611
  const stored = normalizeStored(JSON.parse(raw));
6601
6612
  if (stored) {
6602
6613
  logs.push(withPreview(stored));
@@ -6615,7 +6626,7 @@ var StartHookLogsService = class {
6615
6626
  async getFullOutput(hookType, hookName) {
6616
6627
  const filename = hookType === "environment" ? ENVIRONMENT_HOOK_LOG_FILENAME : repoHookLogFilename(hookName);
6617
6628
  try {
6618
- const raw = await readFile5(join8(LOGS_DIR, filename), "utf-8");
6629
+ const raw = await readFile5(join9(LOGS_DIR, filename), "utf-8");
6619
6630
  const stored = normalizeStored(JSON.parse(raw));
6620
6631
  if (!stored || stored.hookType !== hookType || stored.hookName !== hookName) {
6621
6632
  return null;
@@ -6632,7 +6643,7 @@ var StartHookLogsService = class {
6632
6643
  var startHookLogsService = new StartHookLogsService();
6633
6644
 
6634
6645
  // src/services/replicas-config-service.ts
6635
- var START_HOOKS_LOG = join9(homedir7(), ".replicas", "startHooks.log");
6646
+ var START_HOOKS_LOG = join10(homedir8(), ".replicas", "startHooks.log");
6636
6647
  var START_HOOKS_RUNNING_PROMPT = `IMPORTANT - Start Hooks Running:
6637
6648
  Start hooks are shell commands/scripts set by repository owners that run on workspace startup.
6638
6649
  These hooks are currently executing in the background. You can:
@@ -6643,7 +6654,7 @@ The start hooks may install dependencies, build projects, or perform other setup
6643
6654
  If your task depends on setup being complete, check the log file before proceeding.`;
6644
6655
  async function readReplicasConfigFromDir(dirPath) {
6645
6656
  for (const filename of REPLICAS_CONFIG_FILENAMES) {
6646
- const configPath = join9(dirPath, filename);
6657
+ const configPath = join10(dirPath, filename);
6647
6658
  if (!existsSync3(configPath)) {
6648
6659
  continue;
6649
6660
  }
@@ -6713,7 +6724,7 @@ var ReplicasConfigService = class {
6713
6724
  const logLine = `[${timestamp}] ${message}
6714
6725
  `;
6715
6726
  try {
6716
- await mkdir6(join9(homedir7(), ".replicas"), { recursive: true });
6727
+ await mkdir6(join10(homedir8(), ".replicas"), { recursive: true });
6717
6728
  await appendFile(START_HOOKS_LOG, logLine, "utf-8");
6718
6729
  } catch (error) {
6719
6730
  console.error("Failed to write to start hooks log:", error);
@@ -6725,7 +6736,7 @@ var ReplicasConfigService = class {
6725
6736
  command: params.content,
6726
6737
  label: "env start hook",
6727
6738
  repoName: "environment",
6728
- cwd: homedir7(),
6739
+ cwd: homedir8(),
6729
6740
  timeout: params.timeoutMs ?? DEFAULT_START_HOOK_TIMEOUT_MS,
6730
6741
  onOutputChunk: params.onOutputChunk
6731
6742
  });
@@ -6848,7 +6859,7 @@ var ReplicasConfigService = class {
6848
6859
  this.hooksCompleted = false;
6849
6860
  this.hooksFailed = false;
6850
6861
  try {
6851
- await mkdir6(join9(homedir7(), ".replicas"), { recursive: true });
6862
+ await mkdir6(join10(homedir8(), ".replicas"), { recursive: true });
6852
6863
  await writeFile4(
6853
6864
  START_HOOKS_LOG,
6854
6865
  `=== Start Hooks Execution Log ===
@@ -7043,11 +7054,11 @@ var replicasConfigService = new ReplicasConfigService();
7043
7054
 
7044
7055
  // src/services/event-service.ts
7045
7056
  import { mkdir as mkdir7 } from "fs/promises";
7046
- import { homedir as homedir8 } from "os";
7047
- import { join as join10 } from "path";
7057
+ import { homedir as homedir9 } from "os";
7058
+ import { join as join11 } from "path";
7048
7059
  import { randomUUID } from "crypto";
7049
- var ENGINE_DIR = join10(homedir8(), ".replicas", "engine");
7050
- var EVENTS_FILE = join10(ENGINE_DIR, "events.jsonl");
7060
+ var ENGINE_DIR = join11(homedir9(), ".replicas", "engine");
7061
+ var EVENTS_FILE = join11(ENGINE_DIR, "events.jsonl");
7051
7062
  var EventService = class {
7052
7063
  subscribers = /* @__PURE__ */ new Map();
7053
7064
  writer = new StreamWriter();
@@ -7081,9 +7092,9 @@ var eventService = new EventService();
7081
7092
  import { mkdir as mkdir8, readFile as readFile7 } from "fs/promises";
7082
7093
  import { existsSync as existsSync4 } from "fs";
7083
7094
  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");
7095
+ import { homedir as homedir10 } from "os";
7096
+ import { dirname as dirname2, join as join12 } from "path";
7097
+ var PREVIEW_PORTS_FILE = join12(homedir10(), ".replicas", "preview-ports.json");
7087
7098
  async function readPreviewsFile() {
7088
7099
  try {
7089
7100
  if (!existsSync4(PREVIEW_PORTS_FILE)) {
@@ -7195,8 +7206,8 @@ async function registerDesktopPreview() {
7195
7206
  // src/services/chat/chat-service.ts
7196
7207
  import { existsSync as existsSync7 } from "fs";
7197
7208
  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";
7209
+ import { homedir as homedir15 } from "os";
7210
+ import { join as join25 } from "path";
7200
7211
  import { randomUUID as randomUUID5 } from "crypto";
7201
7212
 
7202
7213
  // src/managers/claude-manager.ts
@@ -7204,9 +7215,9 @@ import {
7204
7215
  query
7205
7216
  } from "@anthropic-ai/claude-agent-sdk";
7206
7217
  import { randomUUID as randomUUID4 } from "crypto";
7207
- import { dirname as dirname4, join as join14 } from "path";
7218
+ import { dirname as dirname4, join as join15 } from "path";
7208
7219
  import { mkdir as mkdir10 } from "fs/promises";
7209
- import { homedir as homedir11 } from "os";
7220
+ import { homedir as homedir12 } from "os";
7210
7221
 
7211
7222
  // src/utils/linear-converter.ts
7212
7223
  function linearThoughtToResponse(thought) {
@@ -7592,8 +7603,8 @@ function extractPlanFromCodexAspNotification(notification) {
7592
7603
  // src/utils/image-utils.ts
7593
7604
  import { randomUUID as randomUUID3 } from "crypto";
7594
7605
  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";
7606
+ import { homedir as homedir11 } from "os";
7607
+ import { join as join13 } from "path";
7597
7608
  function isImageMediaType(value) {
7598
7609
  return IMAGE_MEDIA_TYPES.includes(value);
7599
7610
  }
@@ -7693,14 +7704,14 @@ async function normalizeImages(images) {
7693
7704
  }
7694
7705
  return normalized;
7695
7706
  }
7696
- async function saveNormalizedImagesToTempFiles(images, tempImageDir = join12(homedir10(), ".replicas", "codex", "temp-images")) {
7707
+ async function saveNormalizedImagesToTempFiles(images, tempImageDir = join13(homedir11(), ".replicas", "codex", "temp-images")) {
7697
7708
  await mkdir9(tempImageDir, { recursive: true });
7698
7709
  const tempPaths = [];
7699
7710
  try {
7700
7711
  for (const image of images) {
7701
7712
  const ext = image.source.media_type.split("/")[1] || "png";
7702
7713
  const filename = `img_${randomUUID3()}.${ext}`;
7703
- const filepath = join12(tempImageDir, filename);
7714
+ const filepath = join13(tempImageDir, filename);
7704
7715
  await writeFile5(filepath, Buffer.from(image.source.data, "base64"));
7705
7716
  tempPaths.push(filepath);
7706
7717
  }
@@ -8285,7 +8296,7 @@ function reportCommandProtectionBlock(options) {
8285
8296
 
8286
8297
  // src/services/skill-registry-service.ts
8287
8298
  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";
8299
+ import { dirname as dirname3, isAbsolute, join as join14, relative, resolve } from "path";
8289
8300
  var REGISTRY_ROOT_DIR = ".replicas/skill-registries";
8290
8301
  var REGISTRY_MANIFEST = "manifest.json";
8291
8302
  async function getSkillRegistryInventory(homeDir) {
@@ -8346,10 +8357,10 @@ async function scanRegistry(registryDir) {
8346
8357
  }
8347
8358
  async function findSkillCollections(registryDir) {
8348
8359
  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") }
8360
+ { source: "skills", root: join14(registryDir, "skills") },
8361
+ { source: "agents", root: join14(registryDir, ".agents", "skills") },
8362
+ { source: "codex", root: join14(registryDir, ".codex", "skills") },
8363
+ { source: "claude", root: join14(registryDir, ".claude", "skills") }
8353
8364
  ];
8354
8365
  const collections = [];
8355
8366
  for (const { source, root } of candidateRoots) {
@@ -8363,9 +8374,9 @@ async function findSkillCollections(registryDir) {
8363
8374
  async function findSkillDirsInRoot(root) {
8364
8375
  const skillDirs = [];
8365
8376
  for (const dirent of await safeReadDir(root)) {
8366
- const skillDir = join13(root, dirent.name);
8377
+ const skillDir = join14(root, dirent.name);
8367
8378
  if (!await isDirectoryDirent(dirent, skillDir)) continue;
8368
- if (await fileExists(join13(skillDir, "SKILL.md"))) {
8379
+ if (await fileExists(join14(skillDir, "SKILL.md"))) {
8369
8380
  skillDirs.push(skillDir);
8370
8381
  }
8371
8382
  }
@@ -8375,9 +8386,9 @@ async function findTopLevelSkills(registryDir) {
8375
8386
  const skills = [];
8376
8387
  for (const dirent of await safeReadDir(registryDir)) {
8377
8388
  if (dirent.name.startsWith(".") || dirent.name === "skills" || dirent.name === "plugins") continue;
8378
- const skillDir = join13(registryDir, dirent.name);
8389
+ const skillDir = join14(registryDir, dirent.name);
8379
8390
  if (!await isDirectoryDirent(dirent, skillDir)) continue;
8380
- if (await fileExists(join13(skillDir, "SKILL.md"))) {
8391
+ if (await fileExists(join14(skillDir, "SKILL.md"))) {
8381
8392
  skills.push({ source: "root", skillDir });
8382
8393
  }
8383
8394
  }
@@ -8388,10 +8399,10 @@ async function findClaudePluginRoots(registryDir) {
8388
8399
  async function walk(dir) {
8389
8400
  for (const dirent of await safeReadDir(dir)) {
8390
8401
  if (dirent.name === ".git") continue;
8391
- const child = join13(dir, dirent.name);
8402
+ const child = join14(dir, dirent.name);
8392
8403
  if (!await isDirectoryDirent(dirent, child)) continue;
8393
8404
  if (dirent.name === ".claude-plugin") {
8394
- if (await fileExists(join13(child, "plugin.json"))) {
8405
+ if (await fileExists(join14(child, "plugin.json"))) {
8395
8406
  roots.push(dirname3(child));
8396
8407
  }
8397
8408
  continue;
@@ -8403,7 +8414,7 @@ async function findClaudePluginRoots(registryDir) {
8403
8414
  return uniqueStrings(roots);
8404
8415
  }
8405
8416
  async function hasCodexMarketplace(registryDir) {
8406
- return await fileExists(join13(registryDir, ".agents", "plugins", "marketplace.json")) || await fileExists(join13(registryDir, ".codex", "plugins", "marketplace.json"));
8417
+ return await fileExists(join14(registryDir, ".agents", "plugins", "marketplace.json")) || await fileExists(join14(registryDir, ".codex", "plugins", "marketplace.json"));
8407
8418
  }
8408
8419
  async function installCodexRegistryPlugins(client, inventory) {
8409
8420
  const cwds = inventory.codexMarketplaceCwds;
@@ -8453,10 +8464,10 @@ function isSkillRegistryEntry(value) {
8453
8464
  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
8465
  }
8455
8466
  function getRegistryRoot(homeDir) {
8456
- return join13(homeDir, REGISTRY_ROOT_DIR);
8467
+ return join14(homeDir, REGISTRY_ROOT_DIR);
8457
8468
  }
8458
8469
  function getManifestPath(homeDir) {
8459
- return join13(getRegistryRoot(homeDir), REGISTRY_MANIFEST);
8470
+ return join14(getRegistryRoot(homeDir), REGISTRY_MANIFEST);
8460
8471
  }
8461
8472
  function emptyInventory(registryRoot) {
8462
8473
  return {
@@ -8803,7 +8814,7 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
8803
8814
  authRetrying = false;
8804
8815
  constructor(options) {
8805
8816
  super(options);
8806
- this.historyFilePath = options.historyFilePath ?? join14(homedir11(), ".replicas", "claude", "history.jsonl");
8817
+ this.historyFilePath = options.historyFilePath ?? join15(homedir12(), ".replicas", "claude", "history.jsonl");
8807
8818
  this.historyFile = new CodexHistoryFile(this.historyFilePath);
8808
8819
  this.systemPromptOverride = options.systemPromptOverride;
8809
8820
  this.toolsOverride = options.tools;
@@ -9735,7 +9746,7 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
9735
9746
 
9736
9747
  // src/managers/codex-asp/codex-asp-manager.ts
9737
9748
  import { readdir as readdir4 } from "fs/promises";
9738
- import { join as join16 } from "path";
9749
+ import { join as join17 } from "path";
9739
9750
 
9740
9751
  // src/managers/codex-asp/app-server-process.ts
9741
9752
  import { spawn as spawn3 } from "child_process";
@@ -9936,7 +9947,7 @@ var DEFAULT_CODEX_ARGS = ["app-server", "--listen", "stdio://"];
9936
9947
  var MIN_CODEX_CLI_VERSION = "0.144.6";
9937
9948
  var CODEX_UPGRADE_TIMEOUT_MS = 12e4;
9938
9949
  var codexCliVersionEnsured = null;
9939
- var ENGINE_PACKAGE_VERSION = "0.1.500";
9950
+ var ENGINE_PACKAGE_VERSION = "0.1.502";
9940
9951
  var INITIALIZE_METHOD = "initialize";
9941
9952
  var INITIALIZED_NOTIFICATION = "initialized";
9942
9953
  var ACCOUNT_LOGIN_START_METHOD = "account/login/start";
@@ -10230,6 +10241,7 @@ var THREAD_READ_METHOD = "thread/read";
10230
10241
  var THREAD_GOAL_SET_METHOD = "thread/goal/set";
10231
10242
  var THREAD_GOAL_GET_METHOD = "thread/goal/get";
10232
10243
  var THREAD_GOAL_CLEAR_METHOD = "thread/goal/clear";
10244
+ var THREAD_COMPACT_START_METHOD = "thread/compact/start";
10233
10245
  var THREAD_SETTINGS_UPDATE_METHOD = "thread/settings/update";
10234
10246
  var TURN_START_METHOD = "turn/start";
10235
10247
  var TURN_INTERRUPT_METHOD = "turn/interrupt";
@@ -10861,16 +10873,16 @@ var TranscriptUpdateCoalescer = class {
10861
10873
  };
10862
10874
 
10863
10875
  // 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");
10876
+ import { homedir as homedir13 } from "os";
10877
+ import { join as join16 } from "path";
10878
+ var ENGINE_DIR2 = join16(homedir13(), ".replicas", "engine");
10879
+ var CHATS_FILE = join16(ENGINE_DIR2, "chats.json");
10880
+ var CLAUDE_HISTORY_DIR = join16(ENGINE_DIR2, "claude-histories");
10881
+ var RELAY_HISTORY_DIR = join16(ENGINE_DIR2, "relay-histories");
10882
+ var CODEX_HISTORY_DIR = join16(ENGINE_DIR2, "codex-histories");
10883
+ var CURSOR_HISTORY_DIR = join16(ENGINE_DIR2, "cursor-histories");
10884
+ var OPENCODE_HISTORY_DIR = join16(ENGINE_DIR2, "opencode-histories");
10885
+ var PI_HISTORY_DIR = join16(ENGINE_DIR2, "pi-histories");
10874
10886
  var HISTORY_DIR_BY_PROVIDER = {
10875
10887
  claude: CLAUDE_HISTORY_DIR,
10876
10888
  relay: RELAY_HISTORY_DIR,
@@ -10916,7 +10928,7 @@ async function readCodexAspThreadHistory(threadId) {
10916
10928
  }
10917
10929
  for (const entry of entries) {
10918
10930
  if (!entry.isFile() || !entry.name.endsWith(".jsonl")) continue;
10919
- const history = await new CodexHistoryFile(join16(CODEX_HISTORY_DIR, entry.name)).load();
10931
+ const history = await new CodexHistoryFile(join17(CODEX_HISTORY_DIR, entry.name)).load();
10920
10932
  const transcript = history.transcriptsByThreadId.get(threadId);
10921
10933
  if (transcript) {
10922
10934
  return {
@@ -10956,6 +10968,9 @@ function skillsListToSlashCommands(response) {
10956
10968
  }))
10957
10969
  );
10958
10970
  }
10971
+ function isCompactCommand(message) {
10972
+ return /^\/compact$/i.test(message.trim());
10973
+ }
10959
10974
  var CodexAspManager = class extends CodingAgentManager {
10960
10975
  currentThreadId = null;
10961
10976
  activeTurnId = null;
@@ -11019,7 +11034,7 @@ var CodexAspManager = class extends CodingAgentManager {
11019
11034
  const expectedTurnId = this.activeTurnId;
11020
11035
  if (!threadId || !expectedTurnId || !this.messageQueue.isProcessing()) return false;
11021
11036
  if (this.isCompacting()) return false;
11022
- if (getGoalCommand(request.message, request.goalMode)) return false;
11037
+ if (getGoalCommand(request.message, request.goalMode) || isCompactCommand(request.message)) return false;
11023
11038
  const { input, tempImagePaths } = await buildTurnInput(request);
11024
11039
  try {
11025
11040
  const host = await getCodexAspHost();
@@ -11163,6 +11178,19 @@ var CodexAspManager = class extends CodingAgentManager {
11163
11178
  };
11164
11179
  const goalCommand = getGoalCommand(request.message, request.goalMode);
11165
11180
  const dispatch = async () => {
11181
+ if (isCompactCommand(request.message)) {
11182
+ await this.executeAspTurn(request, recordUserMessage, {
11183
+ runTurn: (host, threadId) => this.observeTurn(host, threadId, request, async () => {
11184
+ await host.client.request(
11185
+ THREAD_COMPACT_START_METHOD,
11186
+ { threadId }
11187
+ );
11188
+ return { turn: null, tempImagePaths: [] };
11189
+ }),
11190
+ userMessagePayload: { command: "compact" }
11191
+ });
11192
+ return;
11193
+ }
11166
11194
  if (goalCommand?.type === "clear") {
11167
11195
  await this.executeGoalClearCommand(request, recordUserMessage);
11168
11196
  return;
@@ -12133,7 +12161,7 @@ var CodexAspManager = class extends CodingAgentManager {
12133
12161
 
12134
12162
  // src/managers/cursor-manager.ts
12135
12163
  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";
12164
+ import { basename, dirname as dirname5, extname, join as join18 } from "path";
12137
12165
  import { parse as parseYaml2 } from "yaml";
12138
12166
  import { Agent as CursorAgent } from "@cursor/sdk";
12139
12167
  var CURSOR_SLASH_COMMANDS_CACHE_MS = 3e4;
@@ -12192,7 +12220,7 @@ async function listCursorCommandsInDirectory(directory) {
12192
12220
  const name = basename(entry.name, ".md");
12193
12221
  let description;
12194
12222
  try {
12195
- description = extractCursorCommandDescription(await readFile10(join17(directory, entry.name), "utf8"));
12223
+ description = extractCursorCommandDescription(await readFile10(join18(directory, entry.name), "utf8"));
12196
12224
  } catch (error) {
12197
12225
  console.warn("[CursorManager] Failed to read slash command file:", error);
12198
12226
  }
@@ -12214,7 +12242,7 @@ var CursorManager = class extends CodingAgentManager {
12214
12242
  slashCommandsRequest = null;
12215
12243
  constructor(options) {
12216
12244
  super(options);
12217
- this.historyFilePath = options.historyFilePath ?? join17(ENGINE_ENV.HOME_DIR, ".replicas", "cursor", "history.jsonl");
12245
+ this.historyFilePath = options.historyFilePath ?? join18(ENGINE_ENV.HOME_DIR, ".replicas", "cursor", "history.jsonl");
12218
12246
  this.historyFile = new CodexHistoryFile(this.historyFilePath);
12219
12247
  this.initializeManager(this.processMessageInternal.bind(this));
12220
12248
  }
@@ -12265,7 +12293,7 @@ var CursorManager = class extends CodingAgentManager {
12265
12293
  this.slashCommandsRequest ??= (async () => {
12266
12294
  try {
12267
12295
  const repoDirectories = await getAgentAdditionalDirectories();
12268
- const commandDirectories = [this.workingDirectory, ...repoDirectories, ENGINE_ENV.HOME_DIR].map((directory) => join17(directory, ".cursor", "commands"));
12296
+ const commandDirectories = [this.workingDirectory, ...repoDirectories, ENGINE_ENV.HOME_DIR].map((directory) => join18(directory, ".cursor", "commands"));
12269
12297
  const commands = mergeSlashCommands(
12270
12298
  ...await Promise.all(commandDirectories.map(listCursorCommandsInDirectory))
12271
12299
  );
@@ -12514,7 +12542,7 @@ ${request.message}` : request.message;
12514
12542
  // src/managers/opencode-manager.ts
12515
12543
  import { existsSync as existsSync6 } from "fs";
12516
12544
  import { mkdir as mkdir12, readFile as readFile11 } from "fs/promises";
12517
- import { delimiter, dirname as dirname6, join as join18 } from "path";
12545
+ import { delimiter, dirname as dirname6, join as join19 } from "path";
12518
12546
  import { randomBytes as randomBytes2 } from "crypto";
12519
12547
  import { fileURLToPath } from "url";
12520
12548
  import { Agent } from "undici";
@@ -12524,8 +12552,7 @@ import {
12524
12552
  createOpencodeServer
12525
12553
  } from "@opencode-ai/sdk/v2";
12526
12554
  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");
12555
+ var OPENCODE_CONFIG_PATH = join19(ENGINE_ENV.HOME_DIR, ".config", "opencode", "opencode.json");
12529
12556
  var OPENCODE_FETCH_DISPATCHER = new Agent({ headersTimeout: 0, bodyTimeout: 0 });
12530
12557
  var OPENCODE_SERVER_STARTUP_TIMEOUT_MS = 3e4;
12531
12558
  var OPENCODE_WORKSPACE_PERMISSION = {
@@ -12559,11 +12586,11 @@ var opencodeAuthSchema = z5.record(z5.string(), z5.object({
12559
12586
  type: z5.string().optional(),
12560
12587
  key: z5.string().optional()
12561
12588
  }));
12562
- async function hasOpenCodeGoCredentials() {
12563
- if (!existsSync6(OPENCODE_AUTH_PATH2)) return false;
12589
+ async function hasOpencodeCredentials(provider) {
12590
+ if (!existsSync6(OPENCODE_AUTH_PATH)) return false;
12564
12591
  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);
12592
+ const auth = opencodeAuthSchema.safeParse(JSON.parse(await readFile11(OPENCODE_AUTH_PATH, "utf8")));
12593
+ return auth.success && auth.data[provider]?.type === "api" && Boolean(auth.data[provider]?.key);
12567
12594
  } catch {
12568
12595
  return false;
12569
12596
  }
@@ -12573,7 +12600,7 @@ function getOpenCodeGoModel(model) {
12573
12600
  }
12574
12601
  async function opencodeConfig(model) {
12575
12602
  let config;
12576
- if (await hasOpenCodeGoCredentials()) {
12603
+ if (await hasOpencodeCredentials(OPENCODE_GO_PROVIDER)) {
12577
12604
  config = {
12578
12605
  enabled_providers: [OPENCODE_GO_PROVIDER],
12579
12606
  model: `${OPENCODE_GO_PROVIDER}/${model}`,
@@ -12587,10 +12614,7 @@ async function opencodeConfig(model) {
12587
12614
  model: `openrouter/${model}`,
12588
12615
  provider: {
12589
12616
  openrouter: {
12590
- models: Object.fromEntries(models.map((candidate) => [candidate, {}])),
12591
- options: {
12592
- apiKey: "{env:OPENROUTER_API_KEY}"
12593
- }
12617
+ models: Object.fromEntries(models.map((candidate) => [candidate, {}]))
12594
12618
  }
12595
12619
  },
12596
12620
  permission: OPENCODE_WORKSPACE_PERMISSION,
@@ -12754,7 +12778,7 @@ var OpencodeManager = class extends CodingAgentManager {
12754
12778
  constructor(options) {
12755
12779
  super(options);
12756
12780
  this.sessionId = options.initialSessionId;
12757
- this.historyFilePath = options.historyFilePath ?? join18(ENGINE_ENV.HOME_DIR, ".replicas", "opencode", "history.jsonl");
12781
+ this.historyFilePath = options.historyFilePath ?? join19(ENGINE_ENV.HOME_DIR, ".replicas", "opencode", "history.jsonl");
12758
12782
  this.historyFile = new CodexHistoryFile(this.historyFilePath);
12759
12783
  this.initializeManager(this.processMessageInternal.bind(this));
12760
12784
  }
@@ -12825,7 +12849,7 @@ var OpencodeManager = class extends CodingAgentManager {
12825
12849
  return this.slashCommandsRequest;
12826
12850
  }
12827
12851
  async ensureClient(model) {
12828
- const providerId = await hasOpenCodeGoCredentials() ? OPENCODE_GO_PROVIDER : "openrouter";
12852
+ const providerId = await hasOpencodeCredentials(OPENCODE_GO_PROVIDER) ? OPENCODE_GO_PROVIDER : "openrouter";
12829
12853
  if (this.client && this.providerId !== providerId) {
12830
12854
  this.eventAbortController?.abort();
12831
12855
  this.server?.close();
@@ -12838,7 +12862,7 @@ var OpencodeManager = class extends CodingAgentManager {
12838
12862
  if (this.client && (providerId === OPENCODE_GO_PROVIDER || this.configuredModels.has(configuredModel))) {
12839
12863
  return this.client;
12840
12864
  }
12841
- if (!ENGINE_ENV.OPENROUTER_API_KEY && this.providerId !== OPENCODE_GO_PROVIDER) {
12865
+ if (this.providerId !== OPENCODE_GO_PROVIDER && !await hasOpencodeCredentials("openrouter")) {
12842
12866
  throw new Error("OpenCode Go or OpenRouter credentials are not configured for Opencode in this workspace.");
12843
12867
  }
12844
12868
  this.eventAbortController?.abort();
@@ -13245,7 +13269,7 @@ var OpencodeManager = class extends CodingAgentManager {
13245
13269
 
13246
13270
  // src/managers/pi-manager.ts
13247
13271
  import { mkdir as mkdir13 } from "fs/promises";
13248
- import { dirname as dirname7, join as join19 } from "path";
13272
+ import { dirname as dirname7, join as join20 } from "path";
13249
13273
  import {
13250
13274
  AuthStorage,
13251
13275
  createAgentSession,
@@ -13285,7 +13309,7 @@ var PiManager = class extends CodingAgentManager {
13285
13309
  historyFile;
13286
13310
  constructor(options) {
13287
13311
  super(options);
13288
- this.historyFilePath = options.historyFilePath ?? join19(PI_HISTORY_DIR, `${Date.now()}.jsonl`);
13312
+ this.historyFilePath = options.historyFilePath ?? join20(PI_HISTORY_DIR, `${Date.now()}.jsonl`);
13289
13313
  this.historyFile = new CodexHistoryFile(this.historyFilePath);
13290
13314
  this.initializeManager(this.processMessageInternal.bind(this));
13291
13315
  }
@@ -13312,6 +13336,13 @@ var PiManager = class extends CodingAgentManager {
13312
13336
  await this.initialized;
13313
13337
  return mergeSlashCommands(...(this.session?.promptTemplates ?? []).map((template) => createProviderSlashCommand("pi", template.name, template.description)).filter((command) => Boolean(command)));
13314
13338
  }
13339
+ async enqueueMessage(request) {
13340
+ await this.initialized;
13341
+ if (!this.session && !await this.getOpenRouterApiKey()) {
13342
+ throw new Error("OpenRouter authentication is missing for Pi. Add an OpenRouter API key in Settings \u2192 Coding agents.");
13343
+ }
13344
+ return this.messageQueue.enqueue(request);
13345
+ }
13315
13346
  dispose() {
13316
13347
  this.unsubscribe?.();
13317
13348
  this.unsubscribe = null;
@@ -13329,9 +13360,9 @@ var PiManager = class extends CodingAgentManager {
13329
13360
  }
13330
13361
  return this.session;
13331
13362
  }
13332
- const apiKey = ENGINE_ENV.OPENROUTER_API_KEY;
13363
+ const authStorage = AuthStorage.create(PI_AUTH_PATH);
13364
+ const apiKey = await this.getOpenRouterApiKey(authStorage);
13333
13365
  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
13366
  const modelRegistry = ModelRegistry.create(authStorage);
13336
13367
  const openRouterModels = modelRegistry.getAll().filter((candidate) => candidate.provider === "openrouter");
13337
13368
  const modelTemplate = openRouterModels[0];
@@ -13361,7 +13392,7 @@ var PiManager = class extends CodingAgentManager {
13361
13392
  const sessionManager = this.initialSessionId ? SessionManager.open(this.initialSessionId, PI_HISTORY_DIR, this.workingDirectory) : SessionManager.create(this.workingDirectory, PI_HISTORY_DIR);
13362
13393
  const resourceLoader = new DefaultResourceLoader({
13363
13394
  cwd: this.workingDirectory,
13364
- agentDir: join19(ENGINE_ENV.HOME_DIR, ".pi", "agent"),
13395
+ agentDir: join20(ENGINE_ENV.HOME_DIR, ".pi", "agent"),
13365
13396
  extensionFactories: [registerCommandProtection(this.workingDirectory)],
13366
13397
  appendSystemPrompt: [this.buildCombinedInstructions() ?? ""]
13367
13398
  });
@@ -13383,6 +13414,10 @@ var PiManager = class extends CodingAgentManager {
13383
13414
  this.unsubscribe = this.session.subscribe((event) => this.handleEvent(event));
13384
13415
  return this.session;
13385
13416
  }
13417
+ async getOpenRouterApiKey(authStorage = AuthStorage.create(PI_AUTH_PATH)) {
13418
+ const credential = authStorage.get("openrouter");
13419
+ return credential?.type === "api_key" ? credential.key : void 0;
13420
+ }
13386
13421
  handleEvent(event) {
13387
13422
  const payload = eventPayload(event);
13388
13423
  this.recordHistoryEvent(`pi-${event.type}`, payload, this.historyFile);
@@ -14066,18 +14101,18 @@ var keepAliveService = new KeepAliveService();
14066
14101
 
14067
14102
  // src/services/canvas-service.ts
14068
14103
  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";
14104
+ import { homedir as homedir14 } from "os";
14105
+ import { join as join21 } from "path";
14071
14106
  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")
14107
+ join21(homedir14(), ".claude", "plans"),
14108
+ join21(process.env.XDG_DATA_HOME ?? join21(homedir14(), ".local", "share"), "opencode", "plans"),
14109
+ join21(homedir14(), ".replicas", "canvas")
14075
14110
  ];
14076
14111
  async function canvasDirectories() {
14077
14112
  const repositories = await gitService.listRepositories().catch(() => []);
14078
14113
  return [
14079
14114
  ...GLOBAL_CANVAS_DIRECTORIES,
14080
- ...repositories.map((repository) => join20(repository.path, ".opencode", "plans"))
14115
+ ...repositories.map((repository) => join21(repository.path, ".opencode", "plans"))
14081
14116
  ];
14082
14117
  }
14083
14118
  var CanvasService = class {
@@ -14097,7 +14132,7 @@ var CanvasService = class {
14097
14132
  const { kind } = classifyCanvasFilename(entry.name);
14098
14133
  let sizeBytes = 0;
14099
14134
  try {
14100
- const s = await stat3(join20(directory, entry.name));
14135
+ const s = await stat3(join21(directory, entry.name));
14101
14136
  sizeBytes = s.size;
14102
14137
  } catch {
14103
14138
  continue;
@@ -14112,7 +14147,7 @@ var CanvasService = class {
14112
14147
  if (!safe) return null;
14113
14148
  const { kind, mimeType } = classifyCanvasFilename(safe);
14114
14149
  for (const directory of await canvasDirectories()) {
14115
- const filePath = join20(directory, safe);
14150
+ const filePath = join21(directory, safe);
14116
14151
  let sizeBytes = 0;
14117
14152
  let updatedAt = "";
14118
14153
  try {
@@ -14249,13 +14284,13 @@ async function reconcileCanvasItems(filenames) {
14249
14284
 
14250
14285
  // src/services/upload-chat-transcripts.ts
14251
14286
  import { readdir as readdir7, readFile as readFile13 } from "fs/promises";
14252
- import { basename as basename2, join as join22 } from "path";
14287
+ import { basename as basename2, join as join23 } from "path";
14253
14288
 
14254
14289
  // src/services/chat/chat-senders.ts
14255
- import { join as join21 } from "path";
14256
- var CHAT_SENDERS_DIR = join21(ENGINE_DIR2, "chat-senders");
14290
+ import { join as join22 } from "path";
14291
+ var CHAT_SENDERS_DIR = join22(ENGINE_DIR2, "chat-senders");
14257
14292
  function chatMessageSendersFilePath(chatId) {
14258
- return join21(CHAT_SENDERS_DIR, `${chatId}.jsonl`);
14293
+ return join22(CHAT_SENDERS_DIR, `${chatId}.jsonl`);
14259
14294
  }
14260
14295
  function parseChatMessageSendersJsonl(content) {
14261
14296
  return content.split("\n").flatMap((line) => {
@@ -14271,9 +14306,9 @@ function parseChatMessageSendersJsonl(content) {
14271
14306
 
14272
14307
  // src/services/upload-chat-transcripts.ts
14273
14308
  var HISTORY_DIRS = [
14274
- join22(ENGINE_DIR2, "claude-histories"),
14275
- join22(ENGINE_DIR2, "relay-histories"),
14276
- join22(ENGINE_DIR2, "codex-histories")
14309
+ join23(ENGINE_DIR2, "claude-histories"),
14310
+ join23(ENGINE_DIR2, "relay-histories"),
14311
+ join23(ENGINE_DIR2, "codex-histories")
14277
14312
  ];
14278
14313
  async function flushAllChatTranscripts(chatsById = /* @__PURE__ */ new Map()) {
14279
14314
  let flushed = 0;
@@ -14290,7 +14325,7 @@ async function flushAllChatTranscripts(chatsById = /* @__PURE__ */ new Map()) {
14290
14325
  if (!entry.endsWith(".jsonl")) continue;
14291
14326
  const chatId = basename2(entry, ".jsonl");
14292
14327
  tasks.push(
14293
- uploadChatTranscript(chatId, join22(dir, entry), chatsById.get(chatId)).then(() => {
14328
+ uploadChatTranscript(chatId, join23(dir, entry), chatsById.get(chatId)).then(() => {
14294
14329
  flushed++;
14295
14330
  }).catch((err) => {
14296
14331
  failed++;
@@ -14380,7 +14415,7 @@ async function flushRepoState() {
14380
14415
  // src/services/upload-engine-logs.ts
14381
14416
  import { createReadStream } from "fs";
14382
14417
  import { readdir as readdir8, stat as stat4 } from "fs/promises";
14383
- import { join as join23 } from "path";
14418
+ import { join as join24 } from "path";
14384
14419
  var MAX_ENGINE_LOG_FLUSH_SESSIONS = 10;
14385
14420
  var MAX_ENGINE_LOG_FLUSH_BYTES = 5 * 1024 * 1024;
14386
14421
  var ENGINE_LOG_FLUSH_TIMEOUT_MS = 2e4;
@@ -14409,7 +14444,7 @@ async function flushAllEngineLogs() {
14409
14444
  const candidates = (await Promise.all(filenames.slice(0, MAX_ENGINE_LOG_FLUSH_SESSIONS).map(async (filename) => {
14410
14445
  try {
14411
14446
  const sessionId = filename.slice(0, -".log".length);
14412
- const filePath = join23(LOG_DIR, filename);
14447
+ const filePath = join24(LOG_DIR, filename);
14413
14448
  const fileStat = await runBeforeDeadline(() => stat4(filePath), deadline);
14414
14449
  if (!fileStat.isFile()) {
14415
14450
  skipped++;
@@ -14505,17 +14540,16 @@ async function uploadEngineLog(input, timeoutMs) {
14505
14540
  }
14506
14541
 
14507
14542
  // 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");
14543
+ var CODEX_AUTH_PATH2 = join25(homedir15(), ".codex", "auth.json");
14510
14544
  var CHATS_BACKUP_FILE = `${CHATS_FILE}.bak`;
14511
14545
  function isCodexAvailable() {
14512
14546
  return existsSync7(CODEX_AUTH_PATH2) || Boolean(ENGINE_ENV.OPENAI_API_KEY);
14513
14547
  }
14514
14548
  function isOpencodeAvailable() {
14515
- return existsSync7(OPENCODE_AUTH_PATH3) || Boolean(ENGINE_ENV.OPENROUTER_API_KEY);
14549
+ return existsSync7(OPENCODE_AUTH_PATH);
14516
14550
  }
14517
14551
  function isPiAvailable() {
14518
- return Boolean(ENGINE_ENV.OPENROUTER_API_KEY);
14552
+ return existsSync7(PI_AUTH_PATH);
14519
14553
  }
14520
14554
  function isCursorAvailable() {
14521
14555
  return Boolean(ENGINE_ENV.CURSOR_API_KEY);
@@ -14972,7 +15006,7 @@ var ChatService = class {
14972
15006
  return descendants;
14973
15007
  }
14974
15008
  async deleteHistoryFile(persisted) {
14975
- await rm2(join24(HISTORY_DIR_BY_PROVIDER[persisted.provider], `${persisted.id}.jsonl`), { force: true });
15009
+ await rm2(join25(HISTORY_DIR_BY_PROVIDER[persisted.provider], `${persisted.id}.jsonl`), { force: true });
14976
15010
  await rm2(chatMessageSendersFilePath(persisted.id), { force: true });
14977
15011
  }
14978
15012
  async getChatHistory(chatId, page = {}) {
@@ -15048,7 +15082,7 @@ var ChatService = class {
15048
15082
  if (persisted.provider === "claude") {
15049
15083
  provider = new ClaudeManager({
15050
15084
  workingDirectory: this.workingDirectory,
15051
- historyFilePath: join24(CLAUDE_HISTORY_DIR, `${persisted.id}.jsonl`),
15085
+ historyFilePath: join25(CLAUDE_HISTORY_DIR, `${persisted.id}.jsonl`),
15052
15086
  initialSessionId: persisted.providerSessionId,
15053
15087
  onSaveSessionId: saveSession,
15054
15088
  onTurnComplete: onProviderTurnComplete,
@@ -15057,7 +15091,7 @@ var ChatService = class {
15057
15091
  } else if (persisted.provider === "relay") {
15058
15092
  provider = new RelayManager({
15059
15093
  workingDirectory: this.workingDirectory,
15060
- historyFilePath: join24(RELAY_HISTORY_DIR, `${persisted.id}.jsonl`),
15094
+ historyFilePath: join25(RELAY_HISTORY_DIR, `${persisted.id}.jsonl`),
15061
15095
  initialSessionId: persisted.providerSessionId,
15062
15096
  onSaveSessionId: saveSession,
15063
15097
  onTurnComplete: onProviderTurnComplete,
@@ -15071,7 +15105,7 @@ var ChatService = class {
15071
15105
  } else if (persisted.provider === "cursor") {
15072
15106
  provider = new CursorManager({
15073
15107
  workingDirectory: this.workingDirectory,
15074
- historyFilePath: join24(CURSOR_HISTORY_DIR, `${persisted.id}.jsonl`),
15108
+ historyFilePath: join25(CURSOR_HISTORY_DIR, `${persisted.id}.jsonl`),
15075
15109
  initialSessionId: persisted.providerSessionId,
15076
15110
  onSaveSessionId: saveSession,
15077
15111
  onTurnComplete: onProviderTurnComplete,
@@ -15080,7 +15114,7 @@ var ChatService = class {
15080
15114
  } else if (persisted.provider === "opencode") {
15081
15115
  provider = new OpencodeManager({
15082
15116
  workingDirectory: this.workingDirectory,
15083
- historyFilePath: join24(OPENCODE_HISTORY_DIR, `${persisted.id}.jsonl`),
15117
+ historyFilePath: join25(OPENCODE_HISTORY_DIR, `${persisted.id}.jsonl`),
15084
15118
  initialSessionId: persisted.providerSessionId,
15085
15119
  onSaveSessionId: saveSession,
15086
15120
  onTurnComplete: onProviderTurnComplete,
@@ -15089,7 +15123,7 @@ var ChatService = class {
15089
15123
  } else if (persisted.provider === "pi") {
15090
15124
  provider = new PiManager({
15091
15125
  workingDirectory: this.workingDirectory,
15092
- historyFilePath: join24(PI_HISTORY_DIR, `${persisted.id}.jsonl`),
15126
+ historyFilePath: join25(PI_HISTORY_DIR, `${persisted.id}.jsonl`),
15093
15127
  initialSessionId: persisted.providerSessionId,
15094
15128
  onSaveSessionId: saveSession,
15095
15129
  onTurnComplete: onProviderTurnComplete,
@@ -15098,7 +15132,7 @@ var ChatService = class {
15098
15132
  } else {
15099
15133
  provider = new CodexAspManager({
15100
15134
  workingDirectory: this.workingDirectory,
15101
- historyFilePath: join24(CODEX_HISTORY_DIR, `${persisted.id}.jsonl`),
15135
+ historyFilePath: join25(CODEX_HISTORY_DIR, `${persisted.id}.jsonl`),
15102
15136
  initialSessionId: persisted.providerSessionId,
15103
15137
  onSaveSessionId: saveSession,
15104
15138
  onTurnComplete: onProviderTurnComplete,
@@ -15247,7 +15281,7 @@ var ChatService = class {
15247
15281
  });
15248
15282
  uploadChatTranscript(
15249
15283
  chatId,
15250
- join24(HISTORY_DIR_BY_PROVIDER[chat.persisted.provider], `${chatId}.jsonl`),
15284
+ join25(HISTORY_DIR_BY_PROVIDER[chat.persisted.provider], `${chatId}.jsonl`),
15251
15285
  this.toSummary(chat)
15252
15286
  ).catch((err) => {
15253
15287
  console.error("[ChatService] Failed to upload chat transcript:", { chatId, err });
@@ -15383,7 +15417,7 @@ var ChatService = class {
15383
15417
  // src/services/repo-file-service.ts
15384
15418
  import { execFile as execFile2 } from "child_process";
15385
15419
  import { readFile as readFile15, realpath, stat as stat5 } from "fs/promises";
15386
- import { join as join25, resolve as resolve2, extname as extname2 } from "path";
15420
+ import { join as join26, resolve as resolve2, extname as extname2 } from "path";
15387
15421
  var CACHE_TTL_MS = 3e4;
15388
15422
  var SEARCH_TIMEOUT_MS = 15e3;
15389
15423
  var MAX_CONTENT_BYTES = 256 * 1024;
@@ -15543,7 +15577,7 @@ var RepoFileService = class {
15543
15577
  const repo = repos.find((r) => r.name === repoName);
15544
15578
  if (!repo) return null;
15545
15579
  try {
15546
- const fullPath = await realpath(resolve2(join25(repo.path, filePath)));
15580
+ const fullPath = await realpath(resolve2(join26(repo.path, filePath)));
15547
15581
  const repoRoot = await realpath(repo.path);
15548
15582
  const repoPrefix = repoRoot.endsWith("/") ? repoRoot : repoRoot + "/";
15549
15583
  if (!fullPath.startsWith(repoPrefix) && fullPath !== repoRoot) return null;
@@ -15651,20 +15685,20 @@ var RepoFileService = class {
15651
15685
  import { Hono } from "hono";
15652
15686
  import { z as z7 } from "zod";
15653
15687
  import { readdir as readdir10, stat as stat6, readFile as readFile18 } from "fs/promises";
15654
- import { join as join28, resolve as resolve3 } from "path";
15688
+ import { join as join29, resolve as resolve3 } from "path";
15655
15689
 
15656
15690
  // src/services/warm-hooks-service.ts
15657
15691
  import { spawn as spawn4 } from "child_process";
15658
15692
  import { readFile as readFile17 } from "fs/promises";
15659
15693
  import { existsSync as existsSync8 } from "fs";
15660
- import { join as join27 } from "path";
15694
+ import { join as join28 } from "path";
15661
15695
 
15662
15696
  // src/services/warm-hook-logs-service.ts
15663
15697
  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");
15698
+ import { homedir as homedir16 } from "os";
15699
+ import { join as join27 } from "path";
15700
+ var LOGS_DIR2 = join27(homedir16(), ".replicas", "warm-hook-logs");
15701
+ var CURRENT_RUN_LOG = join27(LOGS_DIR2, "current-run.log");
15668
15702
  var GLOBAL_FILENAME = "global.json";
15669
15703
  function withPreview2(stored) {
15670
15704
  const preview = buildHookOutputPreview(stored.output);
@@ -15681,7 +15715,7 @@ var WarmHookLogsService = class {
15681
15715
  hookName: "organization",
15682
15716
  ...entry
15683
15717
  };
15684
- await writeFile6(join26(LOGS_DIR2, GLOBAL_FILENAME), `${JSON.stringify(log, null, 2)}
15718
+ await writeFile6(join27(LOGS_DIR2, GLOBAL_FILENAME), `${JSON.stringify(log, null, 2)}
15685
15719
  `, "utf-8");
15686
15720
  }
15687
15721
  async saveEnvironmentHookLog(entry) {
@@ -15691,7 +15725,7 @@ var WarmHookLogsService = class {
15691
15725
  hookName: "environment",
15692
15726
  ...entry
15693
15727
  };
15694
- await writeFile6(join26(LOGS_DIR2, ENVIRONMENT_HOOK_LOG_FILENAME), `${JSON.stringify(log, null, 2)}
15728
+ await writeFile6(join27(LOGS_DIR2, ENVIRONMENT_HOOK_LOG_FILENAME), `${JSON.stringify(log, null, 2)}
15695
15729
  `, "utf-8");
15696
15730
  }
15697
15731
  async saveRepoHookLog(repoName, entry) {
@@ -15701,7 +15735,7 @@ var WarmHookLogsService = class {
15701
15735
  hookName: repoName,
15702
15736
  ...entry
15703
15737
  };
15704
- await writeFile6(join26(LOGS_DIR2, repoHookLogFilename(repoName)), `${JSON.stringify(log, null, 2)}
15738
+ await writeFile6(join27(LOGS_DIR2, repoHookLogFilename(repoName)), `${JSON.stringify(log, null, 2)}
15705
15739
  `, "utf-8");
15706
15740
  }
15707
15741
  async getAllLogs() {
@@ -15720,7 +15754,7 @@ var WarmHookLogsService = class {
15720
15754
  continue;
15721
15755
  }
15722
15756
  try {
15723
- const raw = await readFile16(join26(LOGS_DIR2, file), "utf-8");
15757
+ const raw = await readFile16(join27(LOGS_DIR2, file), "utf-8");
15724
15758
  const stored = JSON.parse(raw);
15725
15759
  logs.push(withPreview2(stored));
15726
15760
  } catch {
@@ -15758,7 +15792,7 @@ var WarmHookLogsService = class {
15758
15792
  async getFullOutput(hookType, hookName) {
15759
15793
  const filename = hookType === "global" ? GLOBAL_FILENAME : hookType === "environment" ? ENVIRONMENT_HOOK_LOG_FILENAME : repoHookLogFilename(hookName);
15760
15794
  try {
15761
- const raw = await readFile16(join26(LOGS_DIR2, filename), "utf-8");
15795
+ const raw = await readFile16(join27(LOGS_DIR2, filename), "utf-8");
15762
15796
  const stored = JSON.parse(raw);
15763
15797
  if (stored.hookType !== hookType || stored.hookName !== hookName) {
15764
15798
  return null;
@@ -15777,7 +15811,7 @@ var warmHookLogsService = new WarmHookLogsService();
15777
15811
  // src/services/warm-hooks-service.ts
15778
15812
  async function readRepoWarmHook(repoPath) {
15779
15813
  for (const filename of REPLICAS_CONFIG_FILENAMES) {
15780
- const configPath = join27(repoPath, filename);
15814
+ const configPath = join28(repoPath, filename);
15781
15815
  if (!existsSync8(configPath)) {
15782
15816
  continue;
15783
15817
  }
@@ -17010,7 +17044,7 @@ data: ${JSON.stringify("Terminal session not found")}
17010
17044
  const logFiles = files.filter((f) => f.endsWith(".log"));
17011
17045
  const sessions = await Promise.all(
17012
17046
  logFiles.map(async (filename) => {
17013
- const filePath = join28(LOG_DIR, filename);
17047
+ const filePath = join29(LOG_DIR, filename);
17014
17048
  const fileStat = await stat6(filePath);
17015
17049
  const sessionId = filename.replace(/\.log$/, "");
17016
17050
  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.502",
4
4
  "description": "Lightweight API server for Replicas workspaces",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",