replicas-engine 0.1.532 → 0.1.533

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -66,8 +66,8 @@ From `monolith/src/lib/sandbox-helpers.ts` + `monolith/src/lib/workspaces.ts`, t
66
66
  - Git identity (optional but expected for commits):
67
67
  - `git config --global user.name <bot-or-user-name>`
68
68
  - `git config --global user.email <bot-or-user-email>`
69
- - Git credential helper setup when GitHub token is available:
70
- - `git config --global credential.helper store`
69
+ - Managed Git credential helper setup when code-host tokens are available:
70
+ - `git config --global credential.helper ~/.git-credential-replicas`
71
71
  - `~/.git-credentials` with `https://x-access-token:<token>@github.com`
72
72
  - Repository materialization:
73
73
  - clone repositories into `/home/ubuntu/workspaces/<repo-name>`
package/dist/src/index.js CHANGED
@@ -623,7 +623,7 @@ var WORKSPACE_SIZES = ["small", "large"];
623
623
  var INVALID_WORKSPACE_SIZE_ERROR = `Invalid size: must be one of ${WORKSPACE_SIZES.join(", ")}`;
624
624
 
625
625
  // ../shared/src/e2b.ts
626
- var E2B_TEMPLATE_NAME = "replicas-sandbox-2026-07-31-v3";
626
+ var E2B_TEMPLATE_NAME = "replicas-sandbox-2026-07-31-v4";
627
627
 
628
628
  // ../shared/src/runtime-env.ts
629
629
  function shellQuotePosix(value) {
@@ -685,6 +685,15 @@ function parsePosixEnvFile(content) {
685
685
  }
686
686
 
687
687
  // ../shared/src/git.ts
688
+ var GIT_CREDENTIAL_HELPER_FILENAME = ".git-credential-replicas";
689
+ function buildGitCredentialHelperScript(credentialsPath) {
690
+ return `#!/bin/sh
691
+ if [ "$1" = "get" ]; then
692
+ exec git credential-store --file=${shellQuotePosix(credentialsPath)} get
693
+ fi
694
+ exit 0
695
+ `;
696
+ }
688
697
  function parseGitRemote(remoteUrl) {
689
698
  const normalized = remoteUrl.trim().replace(/\/+$/, "").replace(/\.git$/, "");
690
699
  try {
@@ -5216,7 +5225,7 @@ var monolithService = new MonolithService();
5216
5225
 
5217
5226
  // src/utils/file.ts
5218
5227
  import { mkdir, readFile, rename, unlink, writeFile } from "fs/promises";
5219
- import { dirname } from "path";
5228
+ import { dirname, join as join3 } from "path";
5220
5229
 
5221
5230
  // src/utils/async-lock.ts
5222
5231
  var AsyncLock = class {
@@ -5248,6 +5257,14 @@ async function writeSecureCredentialFile(filePath, content, options) {
5248
5257
  }
5249
5258
  await atomicWriteFile(filePath, content, { mode: 384 });
5250
5259
  }
5260
+ async function configureManagedGitCredentialHelper(homeDir) {
5261
+ const credentialsPath = join3(homeDir, ".git-credentials");
5262
+ const helperPath = join3(homeDir, GIT_CREDENTIAL_HELPER_FILENAME);
5263
+ await atomicWriteFile(helperPath, buildGitCredentialHelperScript(credentialsPath), { mode: 448 });
5264
+ await execFileAsync("git", ["config", "--global", "credential.helper", helperPath], {
5265
+ env: { ...process.env, HOME: homeDir }
5266
+ });
5267
+ }
5251
5268
  var credentialFileLock = new AsyncLock();
5252
5269
  function upsertCredentialFileLines(filePath, hosts, lines) {
5253
5270
  return credentialFileLock.run(async () => {
@@ -5277,12 +5294,12 @@ function removeCredentialFileLines(filePath, shouldRemove) {
5277
5294
  // src/git/service.ts
5278
5295
  import { readdir, readFile as readFile3, stat } from "fs/promises";
5279
5296
  import { spawn } from "child_process";
5280
- import { join as join5 } from "path";
5297
+ import { join as join6 } from "path";
5281
5298
 
5282
5299
  // src/utils/state.ts
5283
5300
  import { readFile as readFile2, mkdir as mkdir2 } from "fs/promises";
5284
5301
  import { existsSync } from "fs";
5285
- import { join as join3 } from "path";
5302
+ import { join as join4 } from "path";
5286
5303
  import { homedir as homedir3 } from "os";
5287
5304
 
5288
5305
  // src/utils/type-guards.ts
@@ -5291,8 +5308,8 @@ function isRecord4(value) {
5291
5308
  }
5292
5309
 
5293
5310
  // src/utils/state.ts
5294
- var STATE_DIR = join3(homedir3(), ".replicas");
5295
- var STATE_FILE = join3(STATE_DIR, "engine-state.json");
5311
+ var STATE_DIR = join4(homedir3(), ".replicas");
5312
+ var STATE_FILE = join4(STATE_DIR, "engine-state.json");
5296
5313
  var DEFAULT_STATE = {
5297
5314
  repos: {}
5298
5315
  };
@@ -5390,7 +5407,7 @@ async function saveRepoState(repoName, state, fallbackState) {
5390
5407
 
5391
5408
  // src/git/commands.ts
5392
5409
  import { readFileSync as readFileSync2 } from "fs";
5393
- import { join as join4 } from "path";
5410
+ import { join as join5 } from "path";
5394
5411
  async function runGitCommand(args, cwd, options = {}) {
5395
5412
  const { stdout } = await execFileAsync("git", args, {
5396
5413
  cwd,
@@ -5401,7 +5418,7 @@ async function runGitCommand(args, cwd, options = {}) {
5401
5418
  }
5402
5419
  function readRepoHeadBranch(repoPath) {
5403
5420
  try {
5404
- const contents = readFileSync2(join4(repoPath, ".git", "HEAD"), "utf-8").trim();
5421
+ const contents = readFileSync2(join5(repoPath, ".git", "HEAD"), "utf-8").trim();
5405
5422
  const match = contents.match(/^ref:\s+refs\/heads\/(.+)$/);
5406
5423
  return match ? match[1] : null;
5407
5424
  } catch {
@@ -5463,13 +5480,13 @@ var GitService = class {
5463
5480
  const repos = [];
5464
5481
  let complete = true;
5465
5482
  for (const entry of entries) {
5466
- const fullPath = join5(root, entry);
5483
+ const fullPath = join6(root, entry);
5467
5484
  try {
5468
5485
  const entryStat = await stat(fullPath);
5469
5486
  if (!entryStat.isDirectory()) {
5470
5487
  continue;
5471
5488
  }
5472
- const hasGit = Boolean(await this.safeStat(join5(fullPath, ".git")));
5489
+ const hasGit = Boolean(await this.safeStat(join6(fullPath, ".git")));
5473
5490
  if (!hasGit) {
5474
5491
  continue;
5475
5492
  }
@@ -5660,7 +5677,7 @@ var GitService = class {
5660
5677
  let total = 0;
5661
5678
  for (const path6 of paths) {
5662
5679
  try {
5663
- const contents = await readFile3(join5(repoPath, path6));
5680
+ const contents = await readFile3(join6(repoPath, path6));
5664
5681
  if (contents.length === 0 || contents.includes(0)) {
5665
5682
  continue;
5666
5683
  }
@@ -5843,7 +5860,7 @@ var GitService = class {
5843
5860
  }
5844
5861
  async getGitLabAccessToken(host) {
5845
5862
  try {
5846
- const credentials = await readFile3(join5(ENGINE_ENV.HOME_DIR, ".git-credentials"), "utf-8");
5863
+ const credentials = await readFile3(join6(ENGINE_ENV.HOME_DIR, ".git-credentials"), "utf-8");
5847
5864
  for (const line of credentials.split("\n")) {
5848
5865
  const trimmed = line.trim();
5849
5866
  if (!trimmed) continue;
@@ -6349,7 +6366,7 @@ var infisicalTokenManager = new InfisicalTokenManager();
6349
6366
  // src/utils/logger.ts
6350
6367
  import { mkdir as mkdir3, writeFile as writeFile2 } from "fs/promises";
6351
6368
  import { homedir as homedir4 } from "os";
6352
- import { join as join6 } from "path";
6369
+ import { join as join7 } from "path";
6353
6370
  import { format } from "util";
6354
6371
  import { randomBytes } from "crypto";
6355
6372
 
@@ -6424,7 +6441,7 @@ var StreamWriter = class {
6424
6441
  };
6425
6442
 
6426
6443
  // src/utils/logger.ts
6427
- var LOG_DIR = join6(homedir4(), ".replicas", "logs");
6444
+ var LOG_DIR = join7(homedir4(), ".replicas", "logs");
6428
6445
  var EngineLogger = class {
6429
6446
  _sessionId = null;
6430
6447
  patched = false;
@@ -6435,7 +6452,7 @@ var EngineLogger = class {
6435
6452
  async initialize() {
6436
6453
  await mkdir3(LOG_DIR, { recursive: true });
6437
6454
  this._sessionId = this.createSessionId();
6438
- const logPath = join6(LOG_DIR, `${this._sessionId}.log`);
6455
+ const logPath = join7(LOG_DIR, `${this._sessionId}.log`);
6439
6456
  await writeFile2(logPath, `=== Replicas Engine Session ${this._sessionId} ===
6440
6457
  `, "utf-8");
6441
6458
  this.writer.open(logPath);
@@ -6482,7 +6499,7 @@ var engineLogger = new EngineLogger();
6482
6499
  // src/services/replicas-config-service.ts
6483
6500
  import { readFile as readFile6, appendFile, writeFile as writeFile4, mkdir as mkdir6 } from "fs/promises";
6484
6501
  import { existsSync as existsSync3 } from "fs";
6485
- import { join as join10 } from "path";
6502
+ import { join as join11 } from "path";
6486
6503
  import { homedir as homedir8 } from "os";
6487
6504
  import { spawn as spawn2 } from "child_process";
6488
6505
 
@@ -6490,21 +6507,21 @@ import { spawn as spawn2 } from "child_process";
6490
6507
  import { mkdir as mkdir4, readFile as readFile4 } from "fs/promises";
6491
6508
  import { existsSync as existsSync2 } from "fs";
6492
6509
  import { homedir as homedir6 } from "os";
6493
- import { join as join8 } from "path";
6510
+ import { join as join9 } from "path";
6494
6511
 
6495
6512
  // src/managers/agent-auth-paths.ts
6496
6513
  import { homedir as homedir5 } from "os";
6497
- import { join as join7 } from "path";
6498
- var OPENCODE_AUTH_PATH = join7(homedir5(), ".local", "share", "opencode", "auth.json");
6499
- var PI_AUTH_PATH = join7(homedir5(), ".pi", "agent", "auth.json");
6514
+ import { join as join8 } from "path";
6515
+ var OPENCODE_AUTH_PATH = join8(homedir5(), ".local", "share", "opencode", "auth.json");
6516
+ var PI_AUTH_PATH = join8(homedir5(), ".pi", "agent", "auth.json");
6500
6517
 
6501
6518
  // src/services/environment-details-service.ts
6502
- var REPLICAS_DIR = join8(homedir6(), ".replicas");
6503
- var DETAILS_FILE = join8(REPLICAS_DIR, "environment-details.json");
6504
- var CLAUDE_CREDENTIALS_PATH = join8(homedir6(), ".claude", ".credentials.json");
6505
- var CODEX_AUTH_PATH = join8(homedir6(), ".codex", "auth.json");
6506
- var GH_HOSTS_PATH = join8(homedir6(), ".config", "gh", "hosts.yml");
6507
- var GIT_CREDENTIALS_PATH = join8(homedir6(), ".git-credentials");
6519
+ var REPLICAS_DIR = join9(homedir6(), ".replicas");
6520
+ var DETAILS_FILE = join9(REPLICAS_DIR, "environment-details.json");
6521
+ var CLAUDE_CREDENTIALS_PATH = join9(homedir6(), ".claude", ".credentials.json");
6522
+ var CODEX_AUTH_PATH = join9(homedir6(), ".codex", "auth.json");
6523
+ var GH_HOSTS_PATH = join9(homedir6(), ".config", "gh", "hosts.yml");
6524
+ var GIT_CREDENTIALS_PATH = join9(homedir6(), ".git-credentials");
6508
6525
  function detectClaudeAuthMethod() {
6509
6526
  if (existsSync2(CLAUDE_CREDENTIALS_PATH)) {
6510
6527
  return "oauth";
@@ -6711,7 +6728,7 @@ var environmentDetailsService = new EnvironmentDetailsService();
6711
6728
  // src/services/start-hook-logs-service.ts
6712
6729
  import { mkdir as mkdir5, readFile as readFile5, writeFile as writeFile3, readdir as readdir2 } from "fs/promises";
6713
6730
  import { homedir as homedir7 } from "os";
6714
- import { join as join9 } from "path";
6731
+ import { join as join10 } from "path";
6715
6732
 
6716
6733
  // src/services/hook-log-files.ts
6717
6734
  import { createHash } from "crypto";
@@ -6723,7 +6740,7 @@ function repoHookLogFilename(repoName) {
6723
6740
  }
6724
6741
 
6725
6742
  // src/services/start-hook-logs-service.ts
6726
- var LOGS_DIR = join9(homedir7(), ".replicas", "start-hook-logs");
6743
+ var LOGS_DIR = join10(homedir7(), ".replicas", "start-hook-logs");
6727
6744
  function withPreview(stored) {
6728
6745
  const preview = buildHookOutputPreview(stored.output);
6729
6746
  return { ...stored, ...preview };
@@ -6761,7 +6778,7 @@ var StartHookLogsService = class {
6761
6778
  await this.ensureDir();
6762
6779
  const log = { hookType, hookName, repoName: hookName, ...entry };
6763
6780
  const filename = hookType === "environment" ? ENVIRONMENT_HOOK_LOG_FILENAME : repoHookLogFilename(hookName);
6764
- await writeFile3(join9(LOGS_DIR, filename), `${JSON.stringify(log, null, 2)}
6781
+ await writeFile3(join10(LOGS_DIR, filename), `${JSON.stringify(log, null, 2)}
6765
6782
  `, "utf-8");
6766
6783
  }
6767
6784
  async saveEnvironmentLog(entry) {
@@ -6786,7 +6803,7 @@ var StartHookLogsService = class {
6786
6803
  continue;
6787
6804
  }
6788
6805
  try {
6789
- const raw = await readFile5(join9(LOGS_DIR, file), "utf-8");
6806
+ const raw = await readFile5(join10(LOGS_DIR, file), "utf-8");
6790
6807
  const stored = normalizeStored(JSON.parse(raw));
6791
6808
  if (stored) {
6792
6809
  logs.push(withPreview(stored));
@@ -6805,7 +6822,7 @@ var StartHookLogsService = class {
6805
6822
  async getFullOutput(hookType, hookName) {
6806
6823
  const filename = hookType === "environment" ? ENVIRONMENT_HOOK_LOG_FILENAME : repoHookLogFilename(hookName);
6807
6824
  try {
6808
- const raw = await readFile5(join9(LOGS_DIR, filename), "utf-8");
6825
+ const raw = await readFile5(join10(LOGS_DIR, filename), "utf-8");
6809
6826
  const stored = normalizeStored(JSON.parse(raw));
6810
6827
  if (!stored || stored.hookType !== hookType || stored.hookName !== hookName) {
6811
6828
  return null;
@@ -6822,7 +6839,7 @@ var StartHookLogsService = class {
6822
6839
  var startHookLogsService = new StartHookLogsService();
6823
6840
 
6824
6841
  // src/services/replicas-config-service.ts
6825
- var START_HOOKS_LOG = join10(homedir8(), ".replicas", "startHooks.log");
6842
+ var START_HOOKS_LOG = join11(homedir8(), ".replicas", "startHooks.log");
6826
6843
  var START_HOOKS_RUNNING_PROMPT = `IMPORTANT - Start Hooks Running:
6827
6844
  Start hooks are shell commands/scripts set by repository owners that run on workspace startup.
6828
6845
  These hooks are currently executing in the background. You can:
@@ -6833,7 +6850,7 @@ The start hooks may install dependencies, build projects, or perform other setup
6833
6850
  If your task depends on setup being complete, check the log file before proceeding.`;
6834
6851
  async function readReplicasConfigFromDir(dirPath) {
6835
6852
  for (const filename of REPLICAS_CONFIG_FILENAMES) {
6836
- const configPath = join10(dirPath, filename);
6853
+ const configPath = join11(dirPath, filename);
6837
6854
  if (!existsSync3(configPath)) {
6838
6855
  continue;
6839
6856
  }
@@ -6903,7 +6920,7 @@ var ReplicasConfigService = class {
6903
6920
  const logLine = `[${timestamp}] ${message}
6904
6921
  `;
6905
6922
  try {
6906
- await mkdir6(join10(homedir8(), ".replicas"), { recursive: true });
6923
+ await mkdir6(join11(homedir8(), ".replicas"), { recursive: true });
6907
6924
  await appendFile(START_HOOKS_LOG, logLine, "utf-8");
6908
6925
  } catch (error) {
6909
6926
  console.error("Failed to write to start hooks log:", error);
@@ -7038,7 +7055,7 @@ var ReplicasConfigService = class {
7038
7055
  this.hooksCompleted = false;
7039
7056
  this.hooksFailed = false;
7040
7057
  try {
7041
- await mkdir6(join10(homedir8(), ".replicas"), { recursive: true });
7058
+ await mkdir6(join11(homedir8(), ".replicas"), { recursive: true });
7042
7059
  await writeFile4(
7043
7060
  START_HOOKS_LOG,
7044
7061
  `=== Start Hooks Execution Log ===
@@ -7234,10 +7251,10 @@ var replicasConfigService = new ReplicasConfigService();
7234
7251
  // src/services/event-service.ts
7235
7252
  import { mkdir as mkdir7 } from "fs/promises";
7236
7253
  import { homedir as homedir9 } from "os";
7237
- import { join as join11 } from "path";
7254
+ import { join as join12 } from "path";
7238
7255
  import { randomUUID } from "crypto";
7239
- var ENGINE_DIR = join11(homedir9(), ".replicas", "engine");
7240
- var EVENTS_FILE = join11(ENGINE_DIR, "events.jsonl");
7256
+ var ENGINE_DIR = join12(homedir9(), ".replicas", "engine");
7257
+ var EVENTS_FILE = join12(ENGINE_DIR, "events.jsonl");
7241
7258
  var EventService = class {
7242
7259
  subscribers = /* @__PURE__ */ new Map();
7243
7260
  writer = new StreamWriter();
@@ -7272,8 +7289,8 @@ import { mkdir as mkdir8, readFile as readFile7 } from "fs/promises";
7272
7289
  import { existsSync as existsSync4 } from "fs";
7273
7290
  import { randomUUID as randomUUID2 } from "crypto";
7274
7291
  import { homedir as homedir10 } from "os";
7275
- import { dirname as dirname2, join as join12 } from "path";
7276
- var PREVIEW_PORTS_FILE = join12(homedir10(), ".replicas", "preview-ports.json");
7292
+ import { dirname as dirname2, join as join13 } from "path";
7293
+ var PREVIEW_PORTS_FILE = join13(homedir10(), ".replicas", "preview-ports.json");
7277
7294
  async function readPreviewsFile() {
7278
7295
  try {
7279
7296
  if (!existsSync4(PREVIEW_PORTS_FILE)) {
@@ -7386,7 +7403,7 @@ async function registerDesktopPreview() {
7386
7403
  import { existsSync as existsSync7 } from "fs";
7387
7404
  import { appendFile as appendFile3, copyFile, mkdir as mkdir14, readFile as readFile14, rename as rename2, rm as rm2 } from "fs/promises";
7388
7405
  import { homedir as homedir15 } from "os";
7389
- import { join as join25 } from "path";
7406
+ import { join as join26 } from "path";
7390
7407
  import { randomUUID as randomUUID5 } from "crypto";
7391
7408
 
7392
7409
  // src/managers/claude-manager.ts
@@ -7394,7 +7411,7 @@ import {
7394
7411
  query
7395
7412
  } from "@anthropic-ai/claude-agent-sdk";
7396
7413
  import { randomUUID as randomUUID4 } from "crypto";
7397
- import { dirname as dirname4, join as join15 } from "path";
7414
+ import { dirname as dirname4, join as join16 } from "path";
7398
7415
  import { mkdir as mkdir10 } from "fs/promises";
7399
7416
  import { homedir as homedir12 } from "os";
7400
7417
 
@@ -7783,7 +7800,7 @@ function extractPlanFromCodexAspNotification(notification) {
7783
7800
  import { randomUUID as randomUUID3 } from "crypto";
7784
7801
  import { mkdir as mkdir9, unlink as unlink2, writeFile as writeFile5 } from "fs/promises";
7785
7802
  import { homedir as homedir11 } from "os";
7786
- import { join as join13 } from "path";
7803
+ import { join as join14 } from "path";
7787
7804
  function isImageMediaType(value) {
7788
7805
  return IMAGE_MEDIA_TYPES.includes(value);
7789
7806
  }
@@ -7883,14 +7900,14 @@ async function normalizeImages(images) {
7883
7900
  }
7884
7901
  return normalized;
7885
7902
  }
7886
- async function saveNormalizedImagesToTempFiles(images, tempImageDir = join13(homedir11(), ".replicas", "codex", "temp-images")) {
7903
+ async function saveNormalizedImagesToTempFiles(images, tempImageDir = join14(homedir11(), ".replicas", "codex", "temp-images")) {
7887
7904
  await mkdir9(tempImageDir, { recursive: true });
7888
7905
  const tempPaths = [];
7889
7906
  try {
7890
7907
  for (const image of images) {
7891
7908
  const ext = image.source.media_type.split("/")[1] || "png";
7892
7909
  const filename = `img_${randomUUID3()}.${ext}`;
7893
- const filepath = join13(tempImageDir, filename);
7910
+ const filepath = join14(tempImageDir, filename);
7894
7911
  await writeFile5(filepath, Buffer.from(image.source.data, "base64"));
7895
7912
  tempPaths.push(filepath);
7896
7913
  }
@@ -8475,7 +8492,7 @@ function reportCommandProtectionBlock(options) {
8475
8492
 
8476
8493
  // src/services/skill-registry-service.ts
8477
8494
  import { readFile as readFile8, readdir as readdir3, stat as stat2 } from "fs/promises";
8478
- import { dirname as dirname3, isAbsolute, join as join14, relative, resolve } from "path";
8495
+ import { dirname as dirname3, isAbsolute, join as join15, relative, resolve } from "path";
8479
8496
  var REGISTRY_ROOT_DIR = ".replicas/skill-registries";
8480
8497
  var REGISTRY_MANIFEST = "manifest.json";
8481
8498
  async function getSkillRegistryInventory(homeDir) {
@@ -8536,10 +8553,10 @@ async function scanRegistry(registryDir) {
8536
8553
  }
8537
8554
  async function findSkillCollections(registryDir) {
8538
8555
  const candidateRoots = [
8539
- { source: "skills", root: join14(registryDir, "skills") },
8540
- { source: "agents", root: join14(registryDir, ".agents", "skills") },
8541
- { source: "codex", root: join14(registryDir, ".codex", "skills") },
8542
- { source: "claude", root: join14(registryDir, ".claude", "skills") }
8556
+ { source: "skills", root: join15(registryDir, "skills") },
8557
+ { source: "agents", root: join15(registryDir, ".agents", "skills") },
8558
+ { source: "codex", root: join15(registryDir, ".codex", "skills") },
8559
+ { source: "claude", root: join15(registryDir, ".claude", "skills") }
8543
8560
  ];
8544
8561
  const collections = [];
8545
8562
  for (const { source, root } of candidateRoots) {
@@ -8553,9 +8570,9 @@ async function findSkillCollections(registryDir) {
8553
8570
  async function findSkillDirsInRoot(root) {
8554
8571
  const skillDirs = [];
8555
8572
  for (const dirent of await safeReadDir(root)) {
8556
- const skillDir = join14(root, dirent.name);
8573
+ const skillDir = join15(root, dirent.name);
8557
8574
  if (!await isDirectoryDirent(dirent, skillDir)) continue;
8558
- if (await fileExists(join14(skillDir, "SKILL.md"))) {
8575
+ if (await fileExists(join15(skillDir, "SKILL.md"))) {
8559
8576
  skillDirs.push(skillDir);
8560
8577
  }
8561
8578
  }
@@ -8565,9 +8582,9 @@ async function findTopLevelSkills(registryDir) {
8565
8582
  const skills = [];
8566
8583
  for (const dirent of await safeReadDir(registryDir)) {
8567
8584
  if (dirent.name.startsWith(".") || dirent.name === "skills" || dirent.name === "plugins") continue;
8568
- const skillDir = join14(registryDir, dirent.name);
8585
+ const skillDir = join15(registryDir, dirent.name);
8569
8586
  if (!await isDirectoryDirent(dirent, skillDir)) continue;
8570
- if (await fileExists(join14(skillDir, "SKILL.md"))) {
8587
+ if (await fileExists(join15(skillDir, "SKILL.md"))) {
8571
8588
  skills.push({ source: "root", skillDir });
8572
8589
  }
8573
8590
  }
@@ -8578,10 +8595,10 @@ async function findClaudePluginRoots(registryDir) {
8578
8595
  async function walk(dir) {
8579
8596
  for (const dirent of await safeReadDir(dir)) {
8580
8597
  if (dirent.name === ".git") continue;
8581
- const child = join14(dir, dirent.name);
8598
+ const child = join15(dir, dirent.name);
8582
8599
  if (!await isDirectoryDirent(dirent, child)) continue;
8583
8600
  if (dirent.name === ".claude-plugin") {
8584
- if (await fileExists(join14(child, "plugin.json"))) {
8601
+ if (await fileExists(join15(child, "plugin.json"))) {
8585
8602
  roots.push(dirname3(child));
8586
8603
  }
8587
8604
  continue;
@@ -8593,7 +8610,7 @@ async function findClaudePluginRoots(registryDir) {
8593
8610
  return uniqueStrings(roots);
8594
8611
  }
8595
8612
  async function hasCodexMarketplace(registryDir) {
8596
- return await fileExists(join14(registryDir, ".agents", "plugins", "marketplace.json")) || await fileExists(join14(registryDir, ".codex", "plugins", "marketplace.json"));
8613
+ return await fileExists(join15(registryDir, ".agents", "plugins", "marketplace.json")) || await fileExists(join15(registryDir, ".codex", "plugins", "marketplace.json"));
8597
8614
  }
8598
8615
  async function installCodexRegistryPlugins(client, inventory) {
8599
8616
  const cwds = inventory.codexMarketplaceCwds;
@@ -8643,10 +8660,10 @@ function isSkillRegistryEntry(value) {
8643
8660
  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";
8644
8661
  }
8645
8662
  function getRegistryRoot(homeDir) {
8646
- return join14(homeDir, REGISTRY_ROOT_DIR);
8663
+ return join15(homeDir, REGISTRY_ROOT_DIR);
8647
8664
  }
8648
8665
  function getManifestPath(homeDir) {
8649
- return join14(getRegistryRoot(homeDir), REGISTRY_MANIFEST);
8666
+ return join15(getRegistryRoot(homeDir), REGISTRY_MANIFEST);
8650
8667
  }
8651
8668
  function emptyInventory(registryRoot) {
8652
8669
  return {
@@ -8994,7 +9011,7 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
8994
9011
  authRetrying = false;
8995
9012
  constructor(options) {
8996
9013
  super(options);
8997
- this.historyFilePath = options.historyFilePath ?? join15(homedir12(), ".replicas", "claude", "history.jsonl");
9014
+ this.historyFilePath = options.historyFilePath ?? join16(homedir12(), ".replicas", "claude", "history.jsonl");
8998
9015
  this.historyFile = new CodexHistoryFile(this.historyFilePath);
8999
9016
  this.systemPromptOverride = options.systemPromptOverride;
9000
9017
  this.toolsOverride = options.tools;
@@ -9944,7 +9961,7 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
9944
9961
 
9945
9962
  // src/managers/codex-asp/codex-asp-manager.ts
9946
9963
  import { readdir as readdir4 } from "fs/promises";
9947
- import { join as join17 } from "path";
9964
+ import { join as join18 } from "path";
9948
9965
 
9949
9966
  // src/managers/codex-asp/app-server-process.ts
9950
9967
  import { spawn as spawn3 } from "child_process";
@@ -10145,7 +10162,7 @@ var DEFAULT_CODEX_ARGS = ["app-server", "--listen", "stdio://"];
10145
10162
  var MIN_CODEX_CLI_VERSION = "0.144.6";
10146
10163
  var CODEX_UPGRADE_TIMEOUT_MS = 12e4;
10147
10164
  var codexCliVersionEnsured = null;
10148
- var ENGINE_PACKAGE_VERSION = "0.1.532";
10165
+ var ENGINE_PACKAGE_VERSION = "0.1.533";
10149
10166
  var INITIALIZE_METHOD = "initialize";
10150
10167
  var INITIALIZED_NOTIFICATION = "initialized";
10151
10168
  var ACCOUNT_LOGIN_START_METHOD = "account/login/start";
@@ -11069,15 +11086,15 @@ var TranscriptUpdateCoalescer = class {
11069
11086
 
11070
11087
  // src/services/chat/history-paths.ts
11071
11088
  import { homedir as homedir13 } from "os";
11072
- import { join as join16 } from "path";
11073
- var ENGINE_DIR2 = join16(homedir13(), ".replicas", "engine");
11074
- var CHATS_FILE = join16(ENGINE_DIR2, "chats.json");
11075
- var CLAUDE_HISTORY_DIR = join16(ENGINE_DIR2, "claude-histories");
11076
- var RELAY_HISTORY_DIR = join16(ENGINE_DIR2, "relay-histories");
11077
- var CODEX_HISTORY_DIR = join16(ENGINE_DIR2, "codex-histories");
11078
- var CURSOR_HISTORY_DIR = join16(ENGINE_DIR2, "cursor-histories");
11079
- var OPENCODE_HISTORY_DIR = join16(ENGINE_DIR2, "opencode-histories");
11080
- var PI_HISTORY_DIR = join16(ENGINE_DIR2, "pi-histories");
11089
+ import { join as join17 } from "path";
11090
+ var ENGINE_DIR2 = join17(homedir13(), ".replicas", "engine");
11091
+ var CHATS_FILE = join17(ENGINE_DIR2, "chats.json");
11092
+ var CLAUDE_HISTORY_DIR = join17(ENGINE_DIR2, "claude-histories");
11093
+ var RELAY_HISTORY_DIR = join17(ENGINE_DIR2, "relay-histories");
11094
+ var CODEX_HISTORY_DIR = join17(ENGINE_DIR2, "codex-histories");
11095
+ var CURSOR_HISTORY_DIR = join17(ENGINE_DIR2, "cursor-histories");
11096
+ var OPENCODE_HISTORY_DIR = join17(ENGINE_DIR2, "opencode-histories");
11097
+ var PI_HISTORY_DIR = join17(ENGINE_DIR2, "pi-histories");
11081
11098
  var HISTORY_DIR_BY_PROVIDER = {
11082
11099
  claude: CLAUDE_HISTORY_DIR,
11083
11100
  relay: RELAY_HISTORY_DIR,
@@ -11123,7 +11140,7 @@ async function readCodexAspThreadHistory(threadId) {
11123
11140
  }
11124
11141
  for (const entry of entries) {
11125
11142
  if (!entry.isFile() || !entry.name.endsWith(".jsonl")) continue;
11126
- const history = await new CodexHistoryFile(join17(CODEX_HISTORY_DIR, entry.name)).load();
11143
+ const history = await new CodexHistoryFile(join18(CODEX_HISTORY_DIR, entry.name)).load();
11127
11144
  const transcript = history.transcriptsByThreadId.get(threadId);
11128
11145
  if (transcript) {
11129
11146
  return {
@@ -12350,7 +12367,7 @@ var CodexAspManager = class extends CodingAgentManager {
12350
12367
 
12351
12368
  // src/managers/cursor-manager.ts
12352
12369
  import { mkdir as mkdir11, readFile as readFile10, readdir as readdir5 } from "fs/promises";
12353
- import { basename, dirname as dirname5, extname, join as join18 } from "path";
12370
+ import { basename, dirname as dirname5, extname, join as join19 } from "path";
12354
12371
  import { parse as parseYaml2 } from "yaml";
12355
12372
  import { Agent as CursorAgent } from "@cursor/sdk";
12356
12373
  var CURSOR_SLASH_COMMANDS_CACHE_MS = 3e4;
@@ -12409,7 +12426,7 @@ async function listCursorCommandsInDirectory(directory) {
12409
12426
  const name = basename(entry.name, ".md");
12410
12427
  let description;
12411
12428
  try {
12412
- description = extractCursorCommandDescription(await readFile10(join18(directory, entry.name), "utf8"));
12429
+ description = extractCursorCommandDescription(await readFile10(join19(directory, entry.name), "utf8"));
12413
12430
  } catch (error) {
12414
12431
  console.warn("[CursorManager] Failed to read slash command file:", error);
12415
12432
  }
@@ -12431,7 +12448,7 @@ var CursorManager = class extends CodingAgentManager {
12431
12448
  slashCommandsRequest = null;
12432
12449
  constructor(options) {
12433
12450
  super(options);
12434
- this.historyFilePath = options.historyFilePath ?? join18(ENGINE_ENV.HOME_DIR, ".replicas", "cursor", "history.jsonl");
12451
+ this.historyFilePath = options.historyFilePath ?? join19(ENGINE_ENV.HOME_DIR, ".replicas", "cursor", "history.jsonl");
12435
12452
  this.historyFile = new CodexHistoryFile(this.historyFilePath);
12436
12453
  this.initializeManager(this.processMessageInternal.bind(this));
12437
12454
  }
@@ -12482,7 +12499,7 @@ var CursorManager = class extends CodingAgentManager {
12482
12499
  this.slashCommandsRequest ??= (async () => {
12483
12500
  try {
12484
12501
  const repoDirectories = await getAgentAdditionalDirectories();
12485
- const commandDirectories = [this.workingDirectory, ...repoDirectories, ENGINE_ENV.HOME_DIR].map((directory) => join18(directory, ".cursor", "commands"));
12502
+ const commandDirectories = [this.workingDirectory, ...repoDirectories, ENGINE_ENV.HOME_DIR].map((directory) => join19(directory, ".cursor", "commands"));
12486
12503
  const commands = mergeSlashCommands(
12487
12504
  ...await Promise.all(commandDirectories.map(listCursorCommandsInDirectory))
12488
12505
  );
@@ -12742,7 +12759,7 @@ ${request.message}` : request.message;
12742
12759
  // src/managers/opencode-manager.ts
12743
12760
  import { existsSync as existsSync6 } from "fs";
12744
12761
  import { mkdir as mkdir12, readFile as readFile11 } from "fs/promises";
12745
- import { delimiter, dirname as dirname6, join as join19 } from "path";
12762
+ import { delimiter, dirname as dirname6, join as join20 } from "path";
12746
12763
  import { randomBytes as randomBytes2 } from "crypto";
12747
12764
  import { fileURLToPath } from "url";
12748
12765
  import { Agent } from "undici";
@@ -12770,7 +12787,7 @@ import {
12770
12787
  createOpencodeServer
12771
12788
  } from "@opencode-ai/sdk/v2";
12772
12789
  var OPENCODE_SHIM_DIR = dirname6(fileURLToPath(new URL("../../scripts/opencode", import.meta.url)));
12773
- var OPENCODE_CONFIG_PATH = join19(ENGINE_ENV.HOME_DIR, ".config", "opencode", "opencode.json");
12790
+ var OPENCODE_CONFIG_PATH = join20(ENGINE_ENV.HOME_DIR, ".config", "opencode", "opencode.json");
12774
12791
  var OPENCODE_FETCH_DISPATCHER = new Agent({ headersTimeout: 0, bodyTimeout: 0 });
12775
12792
  var OPENCODE_SERVER_STARTUP_TIMEOUT_MS = 3e4;
12776
12793
  var OPENCODE_WORKSPACE_PERMISSION = {
@@ -13018,7 +13035,7 @@ var OpencodeManager = class extends CodingAgentManager {
13018
13035
  constructor(options) {
13019
13036
  super(options);
13020
13037
  this.sessionId = options.initialSessionId;
13021
- this.historyFilePath = options.historyFilePath ?? join19(ENGINE_ENV.HOME_DIR, ".replicas", "opencode", "history.jsonl");
13038
+ this.historyFilePath = options.historyFilePath ?? join20(ENGINE_ENV.HOME_DIR, ".replicas", "opencode", "history.jsonl");
13022
13039
  this.historyFile = new CodexHistoryFile(this.historyFilePath);
13023
13040
  this.initializeManager(this.processMessageInternal.bind(this));
13024
13041
  }
@@ -13517,7 +13534,7 @@ var OpencodeManager = class extends CodingAgentManager {
13517
13534
 
13518
13535
  // src/managers/pi-manager.ts
13519
13536
  import { mkdir as mkdir13 } from "fs/promises";
13520
- import { dirname as dirname7, join as join20 } from "path";
13537
+ import { dirname as dirname7, join as join21 } from "path";
13521
13538
  import {
13522
13539
  AuthStorage,
13523
13540
  createAgentSession,
@@ -13558,7 +13575,7 @@ var PiManager = class extends CodingAgentManager {
13558
13575
  providerId = "openrouter";
13559
13576
  constructor(options) {
13560
13577
  super(options);
13561
- this.historyFilePath = options.historyFilePath ?? join20(PI_HISTORY_DIR, `${Date.now()}.jsonl`);
13578
+ this.historyFilePath = options.historyFilePath ?? join21(PI_HISTORY_DIR, `${Date.now()}.jsonl`);
13562
13579
  this.historyFile = new CodexHistoryFile(this.historyFilePath);
13563
13580
  this.initializeManager(this.processMessageInternal.bind(this));
13564
13581
  }
@@ -13664,7 +13681,7 @@ var PiManager = class extends CodingAgentManager {
13664
13681
  const sessionManager = this.initialSessionId ? SessionManager.open(this.initialSessionId, PI_HISTORY_DIR, this.workingDirectory) : SessionManager.create(this.workingDirectory, PI_HISTORY_DIR);
13665
13682
  const resourceLoader = new DefaultResourceLoader({
13666
13683
  cwd: this.workingDirectory,
13667
- agentDir: join20(ENGINE_ENV.HOME_DIR, ".pi", "agent"),
13684
+ agentDir: join21(ENGINE_ENV.HOME_DIR, ".pi", "agent"),
13668
13685
  extensionFactories: [registerCommandProtection(this.workingDirectory)],
13669
13686
  appendSystemPrompt: [this.buildCombinedInstructions() ?? ""]
13670
13687
  });
@@ -14377,17 +14394,17 @@ var keepAliveService = new KeepAliveService();
14377
14394
  // src/services/canvas-service.ts
14378
14395
  import { readdir as readdir6, readFile as readFile12, stat as stat3 } from "fs/promises";
14379
14396
  import { homedir as homedir14 } from "os";
14380
- import { join as join21 } from "path";
14397
+ import { join as join22 } from "path";
14381
14398
  var GLOBAL_CANVAS_DIRECTORIES = [
14382
- join21(homedir14(), ".claude", "plans"),
14383
- join21(process.env.XDG_DATA_HOME ?? join21(homedir14(), ".local", "share"), "opencode", "plans"),
14384
- join21(homedir14(), ".replicas", "canvas")
14399
+ join22(homedir14(), ".claude", "plans"),
14400
+ join22(process.env.XDG_DATA_HOME ?? join22(homedir14(), ".local", "share"), "opencode", "plans"),
14401
+ join22(homedir14(), ".replicas", "canvas")
14385
14402
  ];
14386
14403
  async function canvasDirectories() {
14387
14404
  const repositories = await gitService.listRepositories().catch(() => []);
14388
14405
  return [
14389
14406
  ...GLOBAL_CANVAS_DIRECTORIES,
14390
- ...repositories.map((repository) => join21(repository.path, ".opencode", "plans"))
14407
+ ...repositories.map((repository) => join22(repository.path, ".opencode", "plans"))
14391
14408
  ];
14392
14409
  }
14393
14410
  var CanvasService = class {
@@ -14407,7 +14424,7 @@ var CanvasService = class {
14407
14424
  const { kind } = classifyCanvasFilename(entry.name);
14408
14425
  let sizeBytes = 0;
14409
14426
  try {
14410
- const s = await stat3(join21(directory, entry.name));
14427
+ const s = await stat3(join22(directory, entry.name));
14411
14428
  sizeBytes = s.size;
14412
14429
  } catch {
14413
14430
  continue;
@@ -14422,7 +14439,7 @@ var CanvasService = class {
14422
14439
  if (!safe) return null;
14423
14440
  const { kind, mimeType } = classifyCanvasFilename(safe);
14424
14441
  for (const directory of await canvasDirectories()) {
14425
- const filePath = join21(directory, safe);
14442
+ const filePath = join22(directory, safe);
14426
14443
  let sizeBytes = 0;
14427
14444
  let updatedAt = "";
14428
14445
  try {
@@ -14562,13 +14579,13 @@ import { createReadStream } from "fs";
14562
14579
  import { readdir as readdir7, readFile as readFile13, stat as stat4 } from "fs/promises";
14563
14580
  import { request as httpRequest } from "http";
14564
14581
  import { request as httpsRequest } from "https";
14565
- import { basename as basename2, join as join23 } from "path";
14582
+ import { basename as basename2, join as join24 } from "path";
14566
14583
 
14567
14584
  // src/services/chat/chat-senders.ts
14568
- import { join as join22 } from "path";
14569
- var CHAT_SENDERS_DIR = join22(ENGINE_DIR2, "chat-senders");
14585
+ import { join as join23 } from "path";
14586
+ var CHAT_SENDERS_DIR = join23(ENGINE_DIR2, "chat-senders");
14570
14587
  function chatMessageSendersFilePath(chatId) {
14571
- return join22(CHAT_SENDERS_DIR, `${chatId}.jsonl`);
14588
+ return join23(CHAT_SENDERS_DIR, `${chatId}.jsonl`);
14572
14589
  }
14573
14590
  function parseChatMessageSendersJsonl(content) {
14574
14591
  return content.split("\n").flatMap((line) => {
@@ -14584,9 +14601,9 @@ function parseChatMessageSendersJsonl(content) {
14584
14601
 
14585
14602
  // src/services/upload-chat-transcripts.ts
14586
14603
  var HISTORY_DIRS = [
14587
- join23(ENGINE_DIR2, "claude-histories"),
14588
- join23(ENGINE_DIR2, "relay-histories"),
14589
- join23(ENGINE_DIR2, "codex-histories")
14604
+ join24(ENGINE_DIR2, "claude-histories"),
14605
+ join24(ENGINE_DIR2, "relay-histories"),
14606
+ join24(ENGINE_DIR2, "codex-histories")
14590
14607
  ];
14591
14608
  async function putTranscript(uploadUrl, filePath, size) {
14592
14609
  await new Promise((resolve4, reject) => {
@@ -14631,7 +14648,7 @@ async function flushAllChatTranscripts(chatsById = /* @__PURE__ */ new Map()) {
14631
14648
  if (!entry.endsWith(".jsonl")) continue;
14632
14649
  const chatId = basename2(entry, ".jsonl");
14633
14650
  tasks.push(
14634
- uploadChatTranscript(chatId, join23(dir, entry), chatsById.get(chatId)).then(() => {
14651
+ uploadChatTranscript(chatId, join24(dir, entry), chatsById.get(chatId)).then(() => {
14635
14652
  flushed++;
14636
14653
  }).catch((err) => {
14637
14654
  failed++;
@@ -14718,7 +14735,7 @@ async function flushRepoState() {
14718
14735
  // src/services/upload-engine-logs.ts
14719
14736
  import { createReadStream as createReadStream2 } from "fs";
14720
14737
  import { readdir as readdir8, stat as stat5 } from "fs/promises";
14721
- import { join as join24 } from "path";
14738
+ import { join as join25 } from "path";
14722
14739
  var MAX_ENGINE_LOG_FLUSH_SESSIONS = 10;
14723
14740
  var MAX_ENGINE_LOG_FLUSH_BYTES = 5 * 1024 * 1024;
14724
14741
  var ENGINE_LOG_FLUSH_TIMEOUT_MS = 2e4;
@@ -14747,7 +14764,7 @@ async function flushAllEngineLogs() {
14747
14764
  const candidates = (await Promise.all(filenames.slice(0, MAX_ENGINE_LOG_FLUSH_SESSIONS).map(async (filename) => {
14748
14765
  try {
14749
14766
  const sessionId = filename.slice(0, -".log".length);
14750
- const filePath = join24(LOG_DIR, filename);
14767
+ const filePath = join25(LOG_DIR, filename);
14751
14768
  const fileStat = await runBeforeDeadline(() => stat5(filePath), deadline);
14752
14769
  if (!fileStat.isFile()) {
14753
14770
  skipped++;
@@ -14843,7 +14860,7 @@ async function uploadEngineLog(input, timeoutMs) {
14843
14860
  }
14844
14861
 
14845
14862
  // src/services/chat/chat-service.ts
14846
- var CODEX_AUTH_PATH2 = join25(homedir15(), ".codex", "auth.json");
14863
+ var CODEX_AUTH_PATH2 = join26(homedir15(), ".codex", "auth.json");
14847
14864
  var CHATS_BACKUP_FILE = `${CHATS_FILE}.bak`;
14848
14865
  function isCodexAvailable() {
14849
14866
  return existsSync7(CODEX_AUTH_PATH2) || Boolean(ENGINE_ENV.OPENAI_API_KEY);
@@ -15310,7 +15327,7 @@ var ChatService = class {
15310
15327
  return descendants;
15311
15328
  }
15312
15329
  async deleteHistoryFile(persisted) {
15313
- await rm2(join25(HISTORY_DIR_BY_PROVIDER[persisted.provider], `${persisted.id}.jsonl`), { force: true });
15330
+ await rm2(join26(HISTORY_DIR_BY_PROVIDER[persisted.provider], `${persisted.id}.jsonl`), { force: true });
15314
15331
  await rm2(chatMessageSendersFilePath(persisted.id), { force: true });
15315
15332
  }
15316
15333
  async getChatHistory(chatId, page = {}) {
@@ -15386,7 +15403,7 @@ var ChatService = class {
15386
15403
  if (persisted.provider === "claude") {
15387
15404
  provider = new ClaudeManager({
15388
15405
  workingDirectory: this.workingDirectory,
15389
- historyFilePath: join25(CLAUDE_HISTORY_DIR, `${persisted.id}.jsonl`),
15406
+ historyFilePath: join26(CLAUDE_HISTORY_DIR, `${persisted.id}.jsonl`),
15390
15407
  initialSessionId: persisted.providerSessionId,
15391
15408
  onSaveSessionId: saveSession,
15392
15409
  onTurnComplete: onProviderTurnComplete,
@@ -15395,7 +15412,7 @@ var ChatService = class {
15395
15412
  } else if (persisted.provider === "relay") {
15396
15413
  provider = new RelayManager({
15397
15414
  workingDirectory: this.workingDirectory,
15398
- historyFilePath: join25(RELAY_HISTORY_DIR, `${persisted.id}.jsonl`),
15415
+ historyFilePath: join26(RELAY_HISTORY_DIR, `${persisted.id}.jsonl`),
15399
15416
  initialSessionId: persisted.providerSessionId,
15400
15417
  onSaveSessionId: saveSession,
15401
15418
  onTurnComplete: onProviderTurnComplete,
@@ -15409,7 +15426,7 @@ var ChatService = class {
15409
15426
  } else if (persisted.provider === "cursor") {
15410
15427
  provider = new CursorManager({
15411
15428
  workingDirectory: this.workingDirectory,
15412
- historyFilePath: join25(CURSOR_HISTORY_DIR, `${persisted.id}.jsonl`),
15429
+ historyFilePath: join26(CURSOR_HISTORY_DIR, `${persisted.id}.jsonl`),
15413
15430
  initialSessionId: persisted.providerSessionId,
15414
15431
  onSaveSessionId: saveSession,
15415
15432
  onTurnComplete: onProviderTurnComplete,
@@ -15418,7 +15435,7 @@ var ChatService = class {
15418
15435
  } else if (persisted.provider === "opencode") {
15419
15436
  provider = new OpencodeManager({
15420
15437
  workingDirectory: this.workingDirectory,
15421
- historyFilePath: join25(OPENCODE_HISTORY_DIR, `${persisted.id}.jsonl`),
15438
+ historyFilePath: join26(OPENCODE_HISTORY_DIR, `${persisted.id}.jsonl`),
15422
15439
  initialSessionId: persisted.providerSessionId,
15423
15440
  onSaveSessionId: saveSession,
15424
15441
  onTurnComplete: onProviderTurnComplete,
@@ -15427,7 +15444,7 @@ var ChatService = class {
15427
15444
  } else if (persisted.provider === "pi") {
15428
15445
  provider = new PiManager({
15429
15446
  workingDirectory: this.workingDirectory,
15430
- historyFilePath: join25(PI_HISTORY_DIR, `${persisted.id}.jsonl`),
15447
+ historyFilePath: join26(PI_HISTORY_DIR, `${persisted.id}.jsonl`),
15431
15448
  initialSessionId: persisted.providerSessionId,
15432
15449
  onSaveSessionId: saveSession,
15433
15450
  onTurnComplete: onProviderTurnComplete,
@@ -15436,7 +15453,7 @@ var ChatService = class {
15436
15453
  } else {
15437
15454
  provider = new CodexAspManager({
15438
15455
  workingDirectory: this.workingDirectory,
15439
- historyFilePath: join25(CODEX_HISTORY_DIR, `${persisted.id}.jsonl`),
15456
+ historyFilePath: join26(CODEX_HISTORY_DIR, `${persisted.id}.jsonl`),
15440
15457
  initialSessionId: persisted.providerSessionId,
15441
15458
  onSaveSessionId: saveSession,
15442
15459
  onTurnComplete: onProviderTurnComplete,
@@ -15586,7 +15603,7 @@ var ChatService = class {
15586
15603
  });
15587
15604
  uploadChatTranscript(
15588
15605
  chatId,
15589
- join25(HISTORY_DIR_BY_PROVIDER[chat.persisted.provider], `${chatId}.jsonl`),
15606
+ join26(HISTORY_DIR_BY_PROVIDER[chat.persisted.provider], `${chatId}.jsonl`),
15590
15607
  this.toSummary(chat)
15591
15608
  ).catch((err) => {
15592
15609
  console.error("[ChatService] Failed to upload chat transcript:", { chatId, err });
@@ -15722,7 +15739,7 @@ var ChatService = class {
15722
15739
  // src/services/repo-file-service.ts
15723
15740
  import { execFile as execFile2 } from "child_process";
15724
15741
  import { readFile as readFile15, realpath, stat as stat6 } from "fs/promises";
15725
- import { join as join26, resolve as resolve2, extname as extname2 } from "path";
15742
+ import { join as join27, resolve as resolve2, extname as extname2 } from "path";
15726
15743
  var CACHE_TTL_MS = 3e4;
15727
15744
  var SEARCH_TIMEOUT_MS = 15e3;
15728
15745
  var MAX_CONTENT_BYTES = 256 * 1024;
@@ -15882,7 +15899,7 @@ var RepoFileService = class {
15882
15899
  const repo = repos.find((r) => r.name === repoName);
15883
15900
  if (!repo) return null;
15884
15901
  try {
15885
- const fullPath = await realpath(resolve2(join26(repo.path, filePath)));
15902
+ const fullPath = await realpath(resolve2(join27(repo.path, filePath)));
15886
15903
  const repoRoot = await realpath(repo.path);
15887
15904
  const repoPrefix = repoRoot.endsWith("/") ? repoRoot : repoRoot + "/";
15888
15905
  if (!fullPath.startsWith(repoPrefix) && fullPath !== repoRoot) return null;
@@ -15990,20 +16007,20 @@ var RepoFileService = class {
15990
16007
  import { Hono } from "hono";
15991
16008
  import { z as z7 } from "zod";
15992
16009
  import { readdir as readdir10, stat as stat7, readFile as readFile18 } from "fs/promises";
15993
- import { join as join29, resolve as resolve3 } from "path";
16010
+ import { join as join30, resolve as resolve3 } from "path";
15994
16011
 
15995
16012
  // src/services/warm-hooks-service.ts
15996
16013
  import { spawn as spawn4 } from "child_process";
15997
16014
  import { readFile as readFile17 } from "fs/promises";
15998
16015
  import { existsSync as existsSync8 } from "fs";
15999
- import { join as join28 } from "path";
16016
+ import { join as join29 } from "path";
16000
16017
 
16001
16018
  // src/services/warm-hook-logs-service.ts
16002
16019
  import { mkdir as mkdir15, readFile as readFile16, writeFile as writeFile6, readdir as readdir9, appendFile as appendFile4, unlink as unlink3 } from "fs/promises";
16003
16020
  import { homedir as homedir16 } from "os";
16004
- import { join as join27 } from "path";
16005
- var LOGS_DIR2 = join27(homedir16(), ".replicas", "warm-hook-logs");
16006
- var CURRENT_RUN_LOG = join27(LOGS_DIR2, "current-run.log");
16021
+ import { join as join28 } from "path";
16022
+ var LOGS_DIR2 = join28(homedir16(), ".replicas", "warm-hook-logs");
16023
+ var CURRENT_RUN_LOG = join28(LOGS_DIR2, "current-run.log");
16007
16024
  var GLOBAL_FILENAME = "global.json";
16008
16025
  function withPreview2(stored) {
16009
16026
  const preview = buildHookOutputPreview(stored.output);
@@ -16020,7 +16037,7 @@ var WarmHookLogsService = class {
16020
16037
  hookName: "organization",
16021
16038
  ...entry
16022
16039
  };
16023
- await writeFile6(join27(LOGS_DIR2, GLOBAL_FILENAME), `${JSON.stringify(log, null, 2)}
16040
+ await writeFile6(join28(LOGS_DIR2, GLOBAL_FILENAME), `${JSON.stringify(log, null, 2)}
16024
16041
  `, "utf-8");
16025
16042
  }
16026
16043
  async saveEnvironmentHookLog(entry) {
@@ -16030,7 +16047,7 @@ var WarmHookLogsService = class {
16030
16047
  hookName: "environment",
16031
16048
  ...entry
16032
16049
  };
16033
- await writeFile6(join27(LOGS_DIR2, ENVIRONMENT_HOOK_LOG_FILENAME), `${JSON.stringify(log, null, 2)}
16050
+ await writeFile6(join28(LOGS_DIR2, ENVIRONMENT_HOOK_LOG_FILENAME), `${JSON.stringify(log, null, 2)}
16034
16051
  `, "utf-8");
16035
16052
  }
16036
16053
  async saveRepoHookLog(repoName, entry) {
@@ -16040,7 +16057,7 @@ var WarmHookLogsService = class {
16040
16057
  hookName: repoName,
16041
16058
  ...entry
16042
16059
  };
16043
- await writeFile6(join27(LOGS_DIR2, repoHookLogFilename(repoName)), `${JSON.stringify(log, null, 2)}
16060
+ await writeFile6(join28(LOGS_DIR2, repoHookLogFilename(repoName)), `${JSON.stringify(log, null, 2)}
16044
16061
  `, "utf-8");
16045
16062
  }
16046
16063
  async getAllLogs() {
@@ -16059,7 +16076,7 @@ var WarmHookLogsService = class {
16059
16076
  continue;
16060
16077
  }
16061
16078
  try {
16062
- const raw = await readFile16(join27(LOGS_DIR2, file), "utf-8");
16079
+ const raw = await readFile16(join28(LOGS_DIR2, file), "utf-8");
16063
16080
  const stored = JSON.parse(raw);
16064
16081
  logs.push(withPreview2(stored));
16065
16082
  } catch {
@@ -16097,7 +16114,7 @@ var WarmHookLogsService = class {
16097
16114
  async getFullOutput(hookType, hookName) {
16098
16115
  const filename = hookType === "global" ? GLOBAL_FILENAME : hookType === "environment" ? ENVIRONMENT_HOOK_LOG_FILENAME : repoHookLogFilename(hookName);
16099
16116
  try {
16100
- const raw = await readFile16(join27(LOGS_DIR2, filename), "utf-8");
16117
+ const raw = await readFile16(join28(LOGS_DIR2, filename), "utf-8");
16101
16118
  const stored = JSON.parse(raw);
16102
16119
  if (stored.hookType !== hookType || stored.hookName !== hookName) {
16103
16120
  return null;
@@ -16116,7 +16133,7 @@ var warmHookLogsService = new WarmHookLogsService();
16116
16133
  // src/services/warm-hooks-service.ts
16117
16134
  async function readRepoWarmHook(repoPath) {
16118
16135
  for (const filename of REPLICAS_CONFIG_FILENAMES) {
16119
- const configPath = join28(repoPath, filename);
16136
+ const configPath = join29(repoPath, filename);
16120
16137
  if (!existsSync8(configPath)) {
16121
16138
  continue;
16122
16139
  }
@@ -17378,7 +17395,7 @@ data: ${JSON.stringify("Terminal session not found")}
17378
17395
  const logFiles = files.filter((f) => f.endsWith(".log"));
17379
17396
  const sessions = await Promise.all(
17380
17397
  logFiles.map(async (filename) => {
17381
- const filePath = join29(LOG_DIR, filename);
17398
+ const filePath = join30(LOG_DIR, filename);
17382
17399
  const fileStat = await stat7(filePath);
17383
17400
  const sessionId = filename.replace(/\.log$/, "");
17384
17401
  return {
@@ -17763,6 +17780,10 @@ serve(
17763
17780
  await timeStartupStep("chat_initialize", () => chatService.initialize());
17764
17781
  await timeStartupStep("preview_initialize", () => previewService.initialize());
17765
17782
  if (!IS_WARMING_MODE) {
17783
+ await timeStartupStep(
17784
+ "git_credential_helper_initialize",
17785
+ () => configureManagedGitCredentialHelper(ENGINE_ENV.HOME_DIR)
17786
+ );
17766
17787
  await timeStartupStep("github_token_initialize", () => githubTokenManager.start());
17767
17788
  }
17768
17789
  engineReady = true;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "replicas-engine",
3
- "version": "0.1.532",
3
+ "version": "0.1.533",
4
4
  "description": "Lightweight API server for Replicas workspaces",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",