replicas-engine 0.1.531 → 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-v2";
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 {
@@ -3412,7 +3421,12 @@ var workspaceChangedEventSchema = z2.discriminatedUnion("type", [
3412
3421
  chatId: z2.string(),
3413
3422
  ts: z2.string()
3414
3423
  }),
3415
- z2.object({ type: z2.literal("presence.changed"), ts: z2.string() })
3424
+ z2.object({ type: z2.literal("presence.changed"), ts: z2.string() }),
3425
+ z2.object({
3426
+ type: z2.literal("mobile-testing.changed"),
3427
+ workspaceId: z2.string(),
3428
+ ts: z2.string()
3429
+ })
3416
3430
  ]);
3417
3431
 
3418
3432
  // ../shared/src/routes/presence.ts
@@ -5211,7 +5225,7 @@ var monolithService = new MonolithService();
5211
5225
 
5212
5226
  // src/utils/file.ts
5213
5227
  import { mkdir, readFile, rename, unlink, writeFile } from "fs/promises";
5214
- import { dirname } from "path";
5228
+ import { dirname, join as join3 } from "path";
5215
5229
 
5216
5230
  // src/utils/async-lock.ts
5217
5231
  var AsyncLock = class {
@@ -5243,6 +5257,14 @@ async function writeSecureCredentialFile(filePath, content, options) {
5243
5257
  }
5244
5258
  await atomicWriteFile(filePath, content, { mode: 384 });
5245
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
+ }
5246
5268
  var credentialFileLock = new AsyncLock();
5247
5269
  function upsertCredentialFileLines(filePath, hosts, lines) {
5248
5270
  return credentialFileLock.run(async () => {
@@ -5272,12 +5294,12 @@ function removeCredentialFileLines(filePath, shouldRemove) {
5272
5294
  // src/git/service.ts
5273
5295
  import { readdir, readFile as readFile3, stat } from "fs/promises";
5274
5296
  import { spawn } from "child_process";
5275
- import { join as join5 } from "path";
5297
+ import { join as join6 } from "path";
5276
5298
 
5277
5299
  // src/utils/state.ts
5278
5300
  import { readFile as readFile2, mkdir as mkdir2 } from "fs/promises";
5279
5301
  import { existsSync } from "fs";
5280
- import { join as join3 } from "path";
5302
+ import { join as join4 } from "path";
5281
5303
  import { homedir as homedir3 } from "os";
5282
5304
 
5283
5305
  // src/utils/type-guards.ts
@@ -5286,8 +5308,8 @@ function isRecord4(value) {
5286
5308
  }
5287
5309
 
5288
5310
  // src/utils/state.ts
5289
- var STATE_DIR = join3(homedir3(), ".replicas");
5290
- 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");
5291
5313
  var DEFAULT_STATE = {
5292
5314
  repos: {}
5293
5315
  };
@@ -5385,7 +5407,7 @@ async function saveRepoState(repoName, state, fallbackState) {
5385
5407
 
5386
5408
  // src/git/commands.ts
5387
5409
  import { readFileSync as readFileSync2 } from "fs";
5388
- import { join as join4 } from "path";
5410
+ import { join as join5 } from "path";
5389
5411
  async function runGitCommand(args, cwd, options = {}) {
5390
5412
  const { stdout } = await execFileAsync("git", args, {
5391
5413
  cwd,
@@ -5396,7 +5418,7 @@ async function runGitCommand(args, cwd, options = {}) {
5396
5418
  }
5397
5419
  function readRepoHeadBranch(repoPath) {
5398
5420
  try {
5399
- const contents = readFileSync2(join4(repoPath, ".git", "HEAD"), "utf-8").trim();
5421
+ const contents = readFileSync2(join5(repoPath, ".git", "HEAD"), "utf-8").trim();
5400
5422
  const match = contents.match(/^ref:\s+refs\/heads\/(.+)$/);
5401
5423
  return match ? match[1] : null;
5402
5424
  } catch {
@@ -5458,13 +5480,13 @@ var GitService = class {
5458
5480
  const repos = [];
5459
5481
  let complete = true;
5460
5482
  for (const entry of entries) {
5461
- const fullPath = join5(root, entry);
5483
+ const fullPath = join6(root, entry);
5462
5484
  try {
5463
5485
  const entryStat = await stat(fullPath);
5464
5486
  if (!entryStat.isDirectory()) {
5465
5487
  continue;
5466
5488
  }
5467
- const hasGit = Boolean(await this.safeStat(join5(fullPath, ".git")));
5489
+ const hasGit = Boolean(await this.safeStat(join6(fullPath, ".git")));
5468
5490
  if (!hasGit) {
5469
5491
  continue;
5470
5492
  }
@@ -5655,7 +5677,7 @@ var GitService = class {
5655
5677
  let total = 0;
5656
5678
  for (const path6 of paths) {
5657
5679
  try {
5658
- const contents = await readFile3(join5(repoPath, path6));
5680
+ const contents = await readFile3(join6(repoPath, path6));
5659
5681
  if (contents.length === 0 || contents.includes(0)) {
5660
5682
  continue;
5661
5683
  }
@@ -5838,7 +5860,7 @@ var GitService = class {
5838
5860
  }
5839
5861
  async getGitLabAccessToken(host) {
5840
5862
  try {
5841
- 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");
5842
5864
  for (const line of credentials.split("\n")) {
5843
5865
  const trimmed = line.trim();
5844
5866
  if (!trimmed) continue;
@@ -6344,7 +6366,7 @@ var infisicalTokenManager = new InfisicalTokenManager();
6344
6366
  // src/utils/logger.ts
6345
6367
  import { mkdir as mkdir3, writeFile as writeFile2 } from "fs/promises";
6346
6368
  import { homedir as homedir4 } from "os";
6347
- import { join as join6 } from "path";
6369
+ import { join as join7 } from "path";
6348
6370
  import { format } from "util";
6349
6371
  import { randomBytes } from "crypto";
6350
6372
 
@@ -6419,7 +6441,7 @@ var StreamWriter = class {
6419
6441
  };
6420
6442
 
6421
6443
  // src/utils/logger.ts
6422
- var LOG_DIR = join6(homedir4(), ".replicas", "logs");
6444
+ var LOG_DIR = join7(homedir4(), ".replicas", "logs");
6423
6445
  var EngineLogger = class {
6424
6446
  _sessionId = null;
6425
6447
  patched = false;
@@ -6430,7 +6452,7 @@ var EngineLogger = class {
6430
6452
  async initialize() {
6431
6453
  await mkdir3(LOG_DIR, { recursive: true });
6432
6454
  this._sessionId = this.createSessionId();
6433
- const logPath = join6(LOG_DIR, `${this._sessionId}.log`);
6455
+ const logPath = join7(LOG_DIR, `${this._sessionId}.log`);
6434
6456
  await writeFile2(logPath, `=== Replicas Engine Session ${this._sessionId} ===
6435
6457
  `, "utf-8");
6436
6458
  this.writer.open(logPath);
@@ -6477,7 +6499,7 @@ var engineLogger = new EngineLogger();
6477
6499
  // src/services/replicas-config-service.ts
6478
6500
  import { readFile as readFile6, appendFile, writeFile as writeFile4, mkdir as mkdir6 } from "fs/promises";
6479
6501
  import { existsSync as existsSync3 } from "fs";
6480
- import { join as join10 } from "path";
6502
+ import { join as join11 } from "path";
6481
6503
  import { homedir as homedir8 } from "os";
6482
6504
  import { spawn as spawn2 } from "child_process";
6483
6505
 
@@ -6485,21 +6507,21 @@ import { spawn as spawn2 } from "child_process";
6485
6507
  import { mkdir as mkdir4, readFile as readFile4 } from "fs/promises";
6486
6508
  import { existsSync as existsSync2 } from "fs";
6487
6509
  import { homedir as homedir6 } from "os";
6488
- import { join as join8 } from "path";
6510
+ import { join as join9 } from "path";
6489
6511
 
6490
6512
  // src/managers/agent-auth-paths.ts
6491
6513
  import { homedir as homedir5 } from "os";
6492
- import { join as join7 } from "path";
6493
- var OPENCODE_AUTH_PATH = join7(homedir5(), ".local", "share", "opencode", "auth.json");
6494
- 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");
6495
6517
 
6496
6518
  // src/services/environment-details-service.ts
6497
- var REPLICAS_DIR = join8(homedir6(), ".replicas");
6498
- var DETAILS_FILE = join8(REPLICAS_DIR, "environment-details.json");
6499
- var CLAUDE_CREDENTIALS_PATH = join8(homedir6(), ".claude", ".credentials.json");
6500
- var CODEX_AUTH_PATH = join8(homedir6(), ".codex", "auth.json");
6501
- var GH_HOSTS_PATH = join8(homedir6(), ".config", "gh", "hosts.yml");
6502
- 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");
6503
6525
  function detectClaudeAuthMethod() {
6504
6526
  if (existsSync2(CLAUDE_CREDENTIALS_PATH)) {
6505
6527
  return "oauth";
@@ -6706,7 +6728,7 @@ var environmentDetailsService = new EnvironmentDetailsService();
6706
6728
  // src/services/start-hook-logs-service.ts
6707
6729
  import { mkdir as mkdir5, readFile as readFile5, writeFile as writeFile3, readdir as readdir2 } from "fs/promises";
6708
6730
  import { homedir as homedir7 } from "os";
6709
- import { join as join9 } from "path";
6731
+ import { join as join10 } from "path";
6710
6732
 
6711
6733
  // src/services/hook-log-files.ts
6712
6734
  import { createHash } from "crypto";
@@ -6718,7 +6740,7 @@ function repoHookLogFilename(repoName) {
6718
6740
  }
6719
6741
 
6720
6742
  // src/services/start-hook-logs-service.ts
6721
- var LOGS_DIR = join9(homedir7(), ".replicas", "start-hook-logs");
6743
+ var LOGS_DIR = join10(homedir7(), ".replicas", "start-hook-logs");
6722
6744
  function withPreview(stored) {
6723
6745
  const preview = buildHookOutputPreview(stored.output);
6724
6746
  return { ...stored, ...preview };
@@ -6756,7 +6778,7 @@ var StartHookLogsService = class {
6756
6778
  await this.ensureDir();
6757
6779
  const log = { hookType, hookName, repoName: hookName, ...entry };
6758
6780
  const filename = hookType === "environment" ? ENVIRONMENT_HOOK_LOG_FILENAME : repoHookLogFilename(hookName);
6759
- await writeFile3(join9(LOGS_DIR, filename), `${JSON.stringify(log, null, 2)}
6781
+ await writeFile3(join10(LOGS_DIR, filename), `${JSON.stringify(log, null, 2)}
6760
6782
  `, "utf-8");
6761
6783
  }
6762
6784
  async saveEnvironmentLog(entry) {
@@ -6781,7 +6803,7 @@ var StartHookLogsService = class {
6781
6803
  continue;
6782
6804
  }
6783
6805
  try {
6784
- const raw = await readFile5(join9(LOGS_DIR, file), "utf-8");
6806
+ const raw = await readFile5(join10(LOGS_DIR, file), "utf-8");
6785
6807
  const stored = normalizeStored(JSON.parse(raw));
6786
6808
  if (stored) {
6787
6809
  logs.push(withPreview(stored));
@@ -6800,7 +6822,7 @@ var StartHookLogsService = class {
6800
6822
  async getFullOutput(hookType, hookName) {
6801
6823
  const filename = hookType === "environment" ? ENVIRONMENT_HOOK_LOG_FILENAME : repoHookLogFilename(hookName);
6802
6824
  try {
6803
- const raw = await readFile5(join9(LOGS_DIR, filename), "utf-8");
6825
+ const raw = await readFile5(join10(LOGS_DIR, filename), "utf-8");
6804
6826
  const stored = normalizeStored(JSON.parse(raw));
6805
6827
  if (!stored || stored.hookType !== hookType || stored.hookName !== hookName) {
6806
6828
  return null;
@@ -6817,7 +6839,7 @@ var StartHookLogsService = class {
6817
6839
  var startHookLogsService = new StartHookLogsService();
6818
6840
 
6819
6841
  // src/services/replicas-config-service.ts
6820
- var START_HOOKS_LOG = join10(homedir8(), ".replicas", "startHooks.log");
6842
+ var START_HOOKS_LOG = join11(homedir8(), ".replicas", "startHooks.log");
6821
6843
  var START_HOOKS_RUNNING_PROMPT = `IMPORTANT - Start Hooks Running:
6822
6844
  Start hooks are shell commands/scripts set by repository owners that run on workspace startup.
6823
6845
  These hooks are currently executing in the background. You can:
@@ -6828,7 +6850,7 @@ The start hooks may install dependencies, build projects, or perform other setup
6828
6850
  If your task depends on setup being complete, check the log file before proceeding.`;
6829
6851
  async function readReplicasConfigFromDir(dirPath) {
6830
6852
  for (const filename of REPLICAS_CONFIG_FILENAMES) {
6831
- const configPath = join10(dirPath, filename);
6853
+ const configPath = join11(dirPath, filename);
6832
6854
  if (!existsSync3(configPath)) {
6833
6855
  continue;
6834
6856
  }
@@ -6898,7 +6920,7 @@ var ReplicasConfigService = class {
6898
6920
  const logLine = `[${timestamp}] ${message}
6899
6921
  `;
6900
6922
  try {
6901
- await mkdir6(join10(homedir8(), ".replicas"), { recursive: true });
6923
+ await mkdir6(join11(homedir8(), ".replicas"), { recursive: true });
6902
6924
  await appendFile(START_HOOKS_LOG, logLine, "utf-8");
6903
6925
  } catch (error) {
6904
6926
  console.error("Failed to write to start hooks log:", error);
@@ -7033,7 +7055,7 @@ var ReplicasConfigService = class {
7033
7055
  this.hooksCompleted = false;
7034
7056
  this.hooksFailed = false;
7035
7057
  try {
7036
- await mkdir6(join10(homedir8(), ".replicas"), { recursive: true });
7058
+ await mkdir6(join11(homedir8(), ".replicas"), { recursive: true });
7037
7059
  await writeFile4(
7038
7060
  START_HOOKS_LOG,
7039
7061
  `=== Start Hooks Execution Log ===
@@ -7229,10 +7251,10 @@ var replicasConfigService = new ReplicasConfigService();
7229
7251
  // src/services/event-service.ts
7230
7252
  import { mkdir as mkdir7 } from "fs/promises";
7231
7253
  import { homedir as homedir9 } from "os";
7232
- import { join as join11 } from "path";
7254
+ import { join as join12 } from "path";
7233
7255
  import { randomUUID } from "crypto";
7234
- var ENGINE_DIR = join11(homedir9(), ".replicas", "engine");
7235
- 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");
7236
7258
  var EventService = class {
7237
7259
  subscribers = /* @__PURE__ */ new Map();
7238
7260
  writer = new StreamWriter();
@@ -7267,8 +7289,8 @@ import { mkdir as mkdir8, readFile as readFile7 } from "fs/promises";
7267
7289
  import { existsSync as existsSync4 } from "fs";
7268
7290
  import { randomUUID as randomUUID2 } from "crypto";
7269
7291
  import { homedir as homedir10 } from "os";
7270
- import { dirname as dirname2, join as join12 } from "path";
7271
- 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");
7272
7294
  async function readPreviewsFile() {
7273
7295
  try {
7274
7296
  if (!existsSync4(PREVIEW_PORTS_FILE)) {
@@ -7381,7 +7403,7 @@ async function registerDesktopPreview() {
7381
7403
  import { existsSync as existsSync7 } from "fs";
7382
7404
  import { appendFile as appendFile3, copyFile, mkdir as mkdir14, readFile as readFile14, rename as rename2, rm as rm2 } from "fs/promises";
7383
7405
  import { homedir as homedir15 } from "os";
7384
- import { join as join25 } from "path";
7406
+ import { join as join26 } from "path";
7385
7407
  import { randomUUID as randomUUID5 } from "crypto";
7386
7408
 
7387
7409
  // src/managers/claude-manager.ts
@@ -7389,7 +7411,7 @@ import {
7389
7411
  query
7390
7412
  } from "@anthropic-ai/claude-agent-sdk";
7391
7413
  import { randomUUID as randomUUID4 } from "crypto";
7392
- import { dirname as dirname4, join as join15 } from "path";
7414
+ import { dirname as dirname4, join as join16 } from "path";
7393
7415
  import { mkdir as mkdir10 } from "fs/promises";
7394
7416
  import { homedir as homedir12 } from "os";
7395
7417
 
@@ -7778,7 +7800,7 @@ function extractPlanFromCodexAspNotification(notification) {
7778
7800
  import { randomUUID as randomUUID3 } from "crypto";
7779
7801
  import { mkdir as mkdir9, unlink as unlink2, writeFile as writeFile5 } from "fs/promises";
7780
7802
  import { homedir as homedir11 } from "os";
7781
- import { join as join13 } from "path";
7803
+ import { join as join14 } from "path";
7782
7804
  function isImageMediaType(value) {
7783
7805
  return IMAGE_MEDIA_TYPES.includes(value);
7784
7806
  }
@@ -7878,14 +7900,14 @@ async function normalizeImages(images) {
7878
7900
  }
7879
7901
  return normalized;
7880
7902
  }
7881
- async function saveNormalizedImagesToTempFiles(images, tempImageDir = join13(homedir11(), ".replicas", "codex", "temp-images")) {
7903
+ async function saveNormalizedImagesToTempFiles(images, tempImageDir = join14(homedir11(), ".replicas", "codex", "temp-images")) {
7882
7904
  await mkdir9(tempImageDir, { recursive: true });
7883
7905
  const tempPaths = [];
7884
7906
  try {
7885
7907
  for (const image of images) {
7886
7908
  const ext = image.source.media_type.split("/")[1] || "png";
7887
7909
  const filename = `img_${randomUUID3()}.${ext}`;
7888
- const filepath = join13(tempImageDir, filename);
7910
+ const filepath = join14(tempImageDir, filename);
7889
7911
  await writeFile5(filepath, Buffer.from(image.source.data, "base64"));
7890
7912
  tempPaths.push(filepath);
7891
7913
  }
@@ -8470,7 +8492,7 @@ function reportCommandProtectionBlock(options) {
8470
8492
 
8471
8493
  // src/services/skill-registry-service.ts
8472
8494
  import { readFile as readFile8, readdir as readdir3, stat as stat2 } from "fs/promises";
8473
- 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";
8474
8496
  var REGISTRY_ROOT_DIR = ".replicas/skill-registries";
8475
8497
  var REGISTRY_MANIFEST = "manifest.json";
8476
8498
  async function getSkillRegistryInventory(homeDir) {
@@ -8531,10 +8553,10 @@ async function scanRegistry(registryDir) {
8531
8553
  }
8532
8554
  async function findSkillCollections(registryDir) {
8533
8555
  const candidateRoots = [
8534
- { source: "skills", root: join14(registryDir, "skills") },
8535
- { source: "agents", root: join14(registryDir, ".agents", "skills") },
8536
- { source: "codex", root: join14(registryDir, ".codex", "skills") },
8537
- { 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") }
8538
8560
  ];
8539
8561
  const collections = [];
8540
8562
  for (const { source, root } of candidateRoots) {
@@ -8548,9 +8570,9 @@ async function findSkillCollections(registryDir) {
8548
8570
  async function findSkillDirsInRoot(root) {
8549
8571
  const skillDirs = [];
8550
8572
  for (const dirent of await safeReadDir(root)) {
8551
- const skillDir = join14(root, dirent.name);
8573
+ const skillDir = join15(root, dirent.name);
8552
8574
  if (!await isDirectoryDirent(dirent, skillDir)) continue;
8553
- if (await fileExists(join14(skillDir, "SKILL.md"))) {
8575
+ if (await fileExists(join15(skillDir, "SKILL.md"))) {
8554
8576
  skillDirs.push(skillDir);
8555
8577
  }
8556
8578
  }
@@ -8560,9 +8582,9 @@ async function findTopLevelSkills(registryDir) {
8560
8582
  const skills = [];
8561
8583
  for (const dirent of await safeReadDir(registryDir)) {
8562
8584
  if (dirent.name.startsWith(".") || dirent.name === "skills" || dirent.name === "plugins") continue;
8563
- const skillDir = join14(registryDir, dirent.name);
8585
+ const skillDir = join15(registryDir, dirent.name);
8564
8586
  if (!await isDirectoryDirent(dirent, skillDir)) continue;
8565
- if (await fileExists(join14(skillDir, "SKILL.md"))) {
8587
+ if (await fileExists(join15(skillDir, "SKILL.md"))) {
8566
8588
  skills.push({ source: "root", skillDir });
8567
8589
  }
8568
8590
  }
@@ -8573,10 +8595,10 @@ async function findClaudePluginRoots(registryDir) {
8573
8595
  async function walk(dir) {
8574
8596
  for (const dirent of await safeReadDir(dir)) {
8575
8597
  if (dirent.name === ".git") continue;
8576
- const child = join14(dir, dirent.name);
8598
+ const child = join15(dir, dirent.name);
8577
8599
  if (!await isDirectoryDirent(dirent, child)) continue;
8578
8600
  if (dirent.name === ".claude-plugin") {
8579
- if (await fileExists(join14(child, "plugin.json"))) {
8601
+ if (await fileExists(join15(child, "plugin.json"))) {
8580
8602
  roots.push(dirname3(child));
8581
8603
  }
8582
8604
  continue;
@@ -8588,7 +8610,7 @@ async function findClaudePluginRoots(registryDir) {
8588
8610
  return uniqueStrings(roots);
8589
8611
  }
8590
8612
  async function hasCodexMarketplace(registryDir) {
8591
- 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"));
8592
8614
  }
8593
8615
  async function installCodexRegistryPlugins(client, inventory) {
8594
8616
  const cwds = inventory.codexMarketplaceCwds;
@@ -8638,10 +8660,10 @@ function isSkillRegistryEntry(value) {
8638
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";
8639
8661
  }
8640
8662
  function getRegistryRoot(homeDir) {
8641
- return join14(homeDir, REGISTRY_ROOT_DIR);
8663
+ return join15(homeDir, REGISTRY_ROOT_DIR);
8642
8664
  }
8643
8665
  function getManifestPath(homeDir) {
8644
- return join14(getRegistryRoot(homeDir), REGISTRY_MANIFEST);
8666
+ return join15(getRegistryRoot(homeDir), REGISTRY_MANIFEST);
8645
8667
  }
8646
8668
  function emptyInventory(registryRoot) {
8647
8669
  return {
@@ -8989,7 +9011,7 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
8989
9011
  authRetrying = false;
8990
9012
  constructor(options) {
8991
9013
  super(options);
8992
- this.historyFilePath = options.historyFilePath ?? join15(homedir12(), ".replicas", "claude", "history.jsonl");
9014
+ this.historyFilePath = options.historyFilePath ?? join16(homedir12(), ".replicas", "claude", "history.jsonl");
8993
9015
  this.historyFile = new CodexHistoryFile(this.historyFilePath);
8994
9016
  this.systemPromptOverride = options.systemPromptOverride;
8995
9017
  this.toolsOverride = options.tools;
@@ -9939,7 +9961,7 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
9939
9961
 
9940
9962
  // src/managers/codex-asp/codex-asp-manager.ts
9941
9963
  import { readdir as readdir4 } from "fs/promises";
9942
- import { join as join17 } from "path";
9964
+ import { join as join18 } from "path";
9943
9965
 
9944
9966
  // src/managers/codex-asp/app-server-process.ts
9945
9967
  import { spawn as spawn3 } from "child_process";
@@ -10140,7 +10162,7 @@ var DEFAULT_CODEX_ARGS = ["app-server", "--listen", "stdio://"];
10140
10162
  var MIN_CODEX_CLI_VERSION = "0.144.6";
10141
10163
  var CODEX_UPGRADE_TIMEOUT_MS = 12e4;
10142
10164
  var codexCliVersionEnsured = null;
10143
- var ENGINE_PACKAGE_VERSION = "0.1.531";
10165
+ var ENGINE_PACKAGE_VERSION = "0.1.533";
10144
10166
  var INITIALIZE_METHOD = "initialize";
10145
10167
  var INITIALIZED_NOTIFICATION = "initialized";
10146
10168
  var ACCOUNT_LOGIN_START_METHOD = "account/login/start";
@@ -11064,15 +11086,15 @@ var TranscriptUpdateCoalescer = class {
11064
11086
 
11065
11087
  // src/services/chat/history-paths.ts
11066
11088
  import { homedir as homedir13 } from "os";
11067
- import { join as join16 } from "path";
11068
- var ENGINE_DIR2 = join16(homedir13(), ".replicas", "engine");
11069
- var CHATS_FILE = join16(ENGINE_DIR2, "chats.json");
11070
- var CLAUDE_HISTORY_DIR = join16(ENGINE_DIR2, "claude-histories");
11071
- var RELAY_HISTORY_DIR = join16(ENGINE_DIR2, "relay-histories");
11072
- var CODEX_HISTORY_DIR = join16(ENGINE_DIR2, "codex-histories");
11073
- var CURSOR_HISTORY_DIR = join16(ENGINE_DIR2, "cursor-histories");
11074
- var OPENCODE_HISTORY_DIR = join16(ENGINE_DIR2, "opencode-histories");
11075
- 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");
11076
11098
  var HISTORY_DIR_BY_PROVIDER = {
11077
11099
  claude: CLAUDE_HISTORY_DIR,
11078
11100
  relay: RELAY_HISTORY_DIR,
@@ -11118,7 +11140,7 @@ async function readCodexAspThreadHistory(threadId) {
11118
11140
  }
11119
11141
  for (const entry of entries) {
11120
11142
  if (!entry.isFile() || !entry.name.endsWith(".jsonl")) continue;
11121
- 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();
11122
11144
  const transcript = history.transcriptsByThreadId.get(threadId);
11123
11145
  if (transcript) {
11124
11146
  return {
@@ -12345,7 +12367,7 @@ var CodexAspManager = class extends CodingAgentManager {
12345
12367
 
12346
12368
  // src/managers/cursor-manager.ts
12347
12369
  import { mkdir as mkdir11, readFile as readFile10, readdir as readdir5 } from "fs/promises";
12348
- import { basename, dirname as dirname5, extname, join as join18 } from "path";
12370
+ import { basename, dirname as dirname5, extname, join as join19 } from "path";
12349
12371
  import { parse as parseYaml2 } from "yaml";
12350
12372
  import { Agent as CursorAgent } from "@cursor/sdk";
12351
12373
  var CURSOR_SLASH_COMMANDS_CACHE_MS = 3e4;
@@ -12404,7 +12426,7 @@ async function listCursorCommandsInDirectory(directory) {
12404
12426
  const name = basename(entry.name, ".md");
12405
12427
  let description;
12406
12428
  try {
12407
- description = extractCursorCommandDescription(await readFile10(join18(directory, entry.name), "utf8"));
12429
+ description = extractCursorCommandDescription(await readFile10(join19(directory, entry.name), "utf8"));
12408
12430
  } catch (error) {
12409
12431
  console.warn("[CursorManager] Failed to read slash command file:", error);
12410
12432
  }
@@ -12426,7 +12448,7 @@ var CursorManager = class extends CodingAgentManager {
12426
12448
  slashCommandsRequest = null;
12427
12449
  constructor(options) {
12428
12450
  super(options);
12429
- 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");
12430
12452
  this.historyFile = new CodexHistoryFile(this.historyFilePath);
12431
12453
  this.initializeManager(this.processMessageInternal.bind(this));
12432
12454
  }
@@ -12477,7 +12499,7 @@ var CursorManager = class extends CodingAgentManager {
12477
12499
  this.slashCommandsRequest ??= (async () => {
12478
12500
  try {
12479
12501
  const repoDirectories = await getAgentAdditionalDirectories();
12480
- 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"));
12481
12503
  const commands = mergeSlashCommands(
12482
12504
  ...await Promise.all(commandDirectories.map(listCursorCommandsInDirectory))
12483
12505
  );
@@ -12737,7 +12759,7 @@ ${request.message}` : request.message;
12737
12759
  // src/managers/opencode-manager.ts
12738
12760
  import { existsSync as existsSync6 } from "fs";
12739
12761
  import { mkdir as mkdir12, readFile as readFile11 } from "fs/promises";
12740
- import { delimiter, dirname as dirname6, join as join19 } from "path";
12762
+ import { delimiter, dirname as dirname6, join as join20 } from "path";
12741
12763
  import { randomBytes as randomBytes2 } from "crypto";
12742
12764
  import { fileURLToPath } from "url";
12743
12765
  import { Agent } from "undici";
@@ -12765,7 +12787,7 @@ import {
12765
12787
  createOpencodeServer
12766
12788
  } from "@opencode-ai/sdk/v2";
12767
12789
  var OPENCODE_SHIM_DIR = dirname6(fileURLToPath(new URL("../../scripts/opencode", import.meta.url)));
12768
- 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");
12769
12791
  var OPENCODE_FETCH_DISPATCHER = new Agent({ headersTimeout: 0, bodyTimeout: 0 });
12770
12792
  var OPENCODE_SERVER_STARTUP_TIMEOUT_MS = 3e4;
12771
12793
  var OPENCODE_WORKSPACE_PERMISSION = {
@@ -13013,7 +13035,7 @@ var OpencodeManager = class extends CodingAgentManager {
13013
13035
  constructor(options) {
13014
13036
  super(options);
13015
13037
  this.sessionId = options.initialSessionId;
13016
- 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");
13017
13039
  this.historyFile = new CodexHistoryFile(this.historyFilePath);
13018
13040
  this.initializeManager(this.processMessageInternal.bind(this));
13019
13041
  }
@@ -13512,7 +13534,7 @@ var OpencodeManager = class extends CodingAgentManager {
13512
13534
 
13513
13535
  // src/managers/pi-manager.ts
13514
13536
  import { mkdir as mkdir13 } from "fs/promises";
13515
- import { dirname as dirname7, join as join20 } from "path";
13537
+ import { dirname as dirname7, join as join21 } from "path";
13516
13538
  import {
13517
13539
  AuthStorage,
13518
13540
  createAgentSession,
@@ -13553,7 +13575,7 @@ var PiManager = class extends CodingAgentManager {
13553
13575
  providerId = "openrouter";
13554
13576
  constructor(options) {
13555
13577
  super(options);
13556
- this.historyFilePath = options.historyFilePath ?? join20(PI_HISTORY_DIR, `${Date.now()}.jsonl`);
13578
+ this.historyFilePath = options.historyFilePath ?? join21(PI_HISTORY_DIR, `${Date.now()}.jsonl`);
13557
13579
  this.historyFile = new CodexHistoryFile(this.historyFilePath);
13558
13580
  this.initializeManager(this.processMessageInternal.bind(this));
13559
13581
  }
@@ -13659,7 +13681,7 @@ var PiManager = class extends CodingAgentManager {
13659
13681
  const sessionManager = this.initialSessionId ? SessionManager.open(this.initialSessionId, PI_HISTORY_DIR, this.workingDirectory) : SessionManager.create(this.workingDirectory, PI_HISTORY_DIR);
13660
13682
  const resourceLoader = new DefaultResourceLoader({
13661
13683
  cwd: this.workingDirectory,
13662
- agentDir: join20(ENGINE_ENV.HOME_DIR, ".pi", "agent"),
13684
+ agentDir: join21(ENGINE_ENV.HOME_DIR, ".pi", "agent"),
13663
13685
  extensionFactories: [registerCommandProtection(this.workingDirectory)],
13664
13686
  appendSystemPrompt: [this.buildCombinedInstructions() ?? ""]
13665
13687
  });
@@ -14372,17 +14394,17 @@ var keepAliveService = new KeepAliveService();
14372
14394
  // src/services/canvas-service.ts
14373
14395
  import { readdir as readdir6, readFile as readFile12, stat as stat3 } from "fs/promises";
14374
14396
  import { homedir as homedir14 } from "os";
14375
- import { join as join21 } from "path";
14397
+ import { join as join22 } from "path";
14376
14398
  var GLOBAL_CANVAS_DIRECTORIES = [
14377
- join21(homedir14(), ".claude", "plans"),
14378
- join21(process.env.XDG_DATA_HOME ?? join21(homedir14(), ".local", "share"), "opencode", "plans"),
14379
- 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")
14380
14402
  ];
14381
14403
  async function canvasDirectories() {
14382
14404
  const repositories = await gitService.listRepositories().catch(() => []);
14383
14405
  return [
14384
14406
  ...GLOBAL_CANVAS_DIRECTORIES,
14385
- ...repositories.map((repository) => join21(repository.path, ".opencode", "plans"))
14407
+ ...repositories.map((repository) => join22(repository.path, ".opencode", "plans"))
14386
14408
  ];
14387
14409
  }
14388
14410
  var CanvasService = class {
@@ -14402,7 +14424,7 @@ var CanvasService = class {
14402
14424
  const { kind } = classifyCanvasFilename(entry.name);
14403
14425
  let sizeBytes = 0;
14404
14426
  try {
14405
- const s = await stat3(join21(directory, entry.name));
14427
+ const s = await stat3(join22(directory, entry.name));
14406
14428
  sizeBytes = s.size;
14407
14429
  } catch {
14408
14430
  continue;
@@ -14417,7 +14439,7 @@ var CanvasService = class {
14417
14439
  if (!safe) return null;
14418
14440
  const { kind, mimeType } = classifyCanvasFilename(safe);
14419
14441
  for (const directory of await canvasDirectories()) {
14420
- const filePath = join21(directory, safe);
14442
+ const filePath = join22(directory, safe);
14421
14443
  let sizeBytes = 0;
14422
14444
  let updatedAt = "";
14423
14445
  try {
@@ -14557,13 +14579,13 @@ import { createReadStream } from "fs";
14557
14579
  import { readdir as readdir7, readFile as readFile13, stat as stat4 } from "fs/promises";
14558
14580
  import { request as httpRequest } from "http";
14559
14581
  import { request as httpsRequest } from "https";
14560
- import { basename as basename2, join as join23 } from "path";
14582
+ import { basename as basename2, join as join24 } from "path";
14561
14583
 
14562
14584
  // src/services/chat/chat-senders.ts
14563
- import { join as join22 } from "path";
14564
- 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");
14565
14587
  function chatMessageSendersFilePath(chatId) {
14566
- return join22(CHAT_SENDERS_DIR, `${chatId}.jsonl`);
14588
+ return join23(CHAT_SENDERS_DIR, `${chatId}.jsonl`);
14567
14589
  }
14568
14590
  function parseChatMessageSendersJsonl(content) {
14569
14591
  return content.split("\n").flatMap((line) => {
@@ -14579,9 +14601,9 @@ function parseChatMessageSendersJsonl(content) {
14579
14601
 
14580
14602
  // src/services/upload-chat-transcripts.ts
14581
14603
  var HISTORY_DIRS = [
14582
- join23(ENGINE_DIR2, "claude-histories"),
14583
- join23(ENGINE_DIR2, "relay-histories"),
14584
- join23(ENGINE_DIR2, "codex-histories")
14604
+ join24(ENGINE_DIR2, "claude-histories"),
14605
+ join24(ENGINE_DIR2, "relay-histories"),
14606
+ join24(ENGINE_DIR2, "codex-histories")
14585
14607
  ];
14586
14608
  async function putTranscript(uploadUrl, filePath, size) {
14587
14609
  await new Promise((resolve4, reject) => {
@@ -14626,7 +14648,7 @@ async function flushAllChatTranscripts(chatsById = /* @__PURE__ */ new Map()) {
14626
14648
  if (!entry.endsWith(".jsonl")) continue;
14627
14649
  const chatId = basename2(entry, ".jsonl");
14628
14650
  tasks.push(
14629
- uploadChatTranscript(chatId, join23(dir, entry), chatsById.get(chatId)).then(() => {
14651
+ uploadChatTranscript(chatId, join24(dir, entry), chatsById.get(chatId)).then(() => {
14630
14652
  flushed++;
14631
14653
  }).catch((err) => {
14632
14654
  failed++;
@@ -14713,7 +14735,7 @@ async function flushRepoState() {
14713
14735
  // src/services/upload-engine-logs.ts
14714
14736
  import { createReadStream as createReadStream2 } from "fs";
14715
14737
  import { readdir as readdir8, stat as stat5 } from "fs/promises";
14716
- import { join as join24 } from "path";
14738
+ import { join as join25 } from "path";
14717
14739
  var MAX_ENGINE_LOG_FLUSH_SESSIONS = 10;
14718
14740
  var MAX_ENGINE_LOG_FLUSH_BYTES = 5 * 1024 * 1024;
14719
14741
  var ENGINE_LOG_FLUSH_TIMEOUT_MS = 2e4;
@@ -14742,7 +14764,7 @@ async function flushAllEngineLogs() {
14742
14764
  const candidates = (await Promise.all(filenames.slice(0, MAX_ENGINE_LOG_FLUSH_SESSIONS).map(async (filename) => {
14743
14765
  try {
14744
14766
  const sessionId = filename.slice(0, -".log".length);
14745
- const filePath = join24(LOG_DIR, filename);
14767
+ const filePath = join25(LOG_DIR, filename);
14746
14768
  const fileStat = await runBeforeDeadline(() => stat5(filePath), deadline);
14747
14769
  if (!fileStat.isFile()) {
14748
14770
  skipped++;
@@ -14838,7 +14860,7 @@ async function uploadEngineLog(input, timeoutMs) {
14838
14860
  }
14839
14861
 
14840
14862
  // src/services/chat/chat-service.ts
14841
- var CODEX_AUTH_PATH2 = join25(homedir15(), ".codex", "auth.json");
14863
+ var CODEX_AUTH_PATH2 = join26(homedir15(), ".codex", "auth.json");
14842
14864
  var CHATS_BACKUP_FILE = `${CHATS_FILE}.bak`;
14843
14865
  function isCodexAvailable() {
14844
14866
  return existsSync7(CODEX_AUTH_PATH2) || Boolean(ENGINE_ENV.OPENAI_API_KEY);
@@ -15305,7 +15327,7 @@ var ChatService = class {
15305
15327
  return descendants;
15306
15328
  }
15307
15329
  async deleteHistoryFile(persisted) {
15308
- 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 });
15309
15331
  await rm2(chatMessageSendersFilePath(persisted.id), { force: true });
15310
15332
  }
15311
15333
  async getChatHistory(chatId, page = {}) {
@@ -15381,7 +15403,7 @@ var ChatService = class {
15381
15403
  if (persisted.provider === "claude") {
15382
15404
  provider = new ClaudeManager({
15383
15405
  workingDirectory: this.workingDirectory,
15384
- historyFilePath: join25(CLAUDE_HISTORY_DIR, `${persisted.id}.jsonl`),
15406
+ historyFilePath: join26(CLAUDE_HISTORY_DIR, `${persisted.id}.jsonl`),
15385
15407
  initialSessionId: persisted.providerSessionId,
15386
15408
  onSaveSessionId: saveSession,
15387
15409
  onTurnComplete: onProviderTurnComplete,
@@ -15390,7 +15412,7 @@ var ChatService = class {
15390
15412
  } else if (persisted.provider === "relay") {
15391
15413
  provider = new RelayManager({
15392
15414
  workingDirectory: this.workingDirectory,
15393
- historyFilePath: join25(RELAY_HISTORY_DIR, `${persisted.id}.jsonl`),
15415
+ historyFilePath: join26(RELAY_HISTORY_DIR, `${persisted.id}.jsonl`),
15394
15416
  initialSessionId: persisted.providerSessionId,
15395
15417
  onSaveSessionId: saveSession,
15396
15418
  onTurnComplete: onProviderTurnComplete,
@@ -15404,7 +15426,7 @@ var ChatService = class {
15404
15426
  } else if (persisted.provider === "cursor") {
15405
15427
  provider = new CursorManager({
15406
15428
  workingDirectory: this.workingDirectory,
15407
- historyFilePath: join25(CURSOR_HISTORY_DIR, `${persisted.id}.jsonl`),
15429
+ historyFilePath: join26(CURSOR_HISTORY_DIR, `${persisted.id}.jsonl`),
15408
15430
  initialSessionId: persisted.providerSessionId,
15409
15431
  onSaveSessionId: saveSession,
15410
15432
  onTurnComplete: onProviderTurnComplete,
@@ -15413,7 +15435,7 @@ var ChatService = class {
15413
15435
  } else if (persisted.provider === "opencode") {
15414
15436
  provider = new OpencodeManager({
15415
15437
  workingDirectory: this.workingDirectory,
15416
- historyFilePath: join25(OPENCODE_HISTORY_DIR, `${persisted.id}.jsonl`),
15438
+ historyFilePath: join26(OPENCODE_HISTORY_DIR, `${persisted.id}.jsonl`),
15417
15439
  initialSessionId: persisted.providerSessionId,
15418
15440
  onSaveSessionId: saveSession,
15419
15441
  onTurnComplete: onProviderTurnComplete,
@@ -15422,7 +15444,7 @@ var ChatService = class {
15422
15444
  } else if (persisted.provider === "pi") {
15423
15445
  provider = new PiManager({
15424
15446
  workingDirectory: this.workingDirectory,
15425
- historyFilePath: join25(PI_HISTORY_DIR, `${persisted.id}.jsonl`),
15447
+ historyFilePath: join26(PI_HISTORY_DIR, `${persisted.id}.jsonl`),
15426
15448
  initialSessionId: persisted.providerSessionId,
15427
15449
  onSaveSessionId: saveSession,
15428
15450
  onTurnComplete: onProviderTurnComplete,
@@ -15431,7 +15453,7 @@ var ChatService = class {
15431
15453
  } else {
15432
15454
  provider = new CodexAspManager({
15433
15455
  workingDirectory: this.workingDirectory,
15434
- historyFilePath: join25(CODEX_HISTORY_DIR, `${persisted.id}.jsonl`),
15456
+ historyFilePath: join26(CODEX_HISTORY_DIR, `${persisted.id}.jsonl`),
15435
15457
  initialSessionId: persisted.providerSessionId,
15436
15458
  onSaveSessionId: saveSession,
15437
15459
  onTurnComplete: onProviderTurnComplete,
@@ -15581,7 +15603,7 @@ var ChatService = class {
15581
15603
  });
15582
15604
  uploadChatTranscript(
15583
15605
  chatId,
15584
- join25(HISTORY_DIR_BY_PROVIDER[chat.persisted.provider], `${chatId}.jsonl`),
15606
+ join26(HISTORY_DIR_BY_PROVIDER[chat.persisted.provider], `${chatId}.jsonl`),
15585
15607
  this.toSummary(chat)
15586
15608
  ).catch((err) => {
15587
15609
  console.error("[ChatService] Failed to upload chat transcript:", { chatId, err });
@@ -15717,7 +15739,7 @@ var ChatService = class {
15717
15739
  // src/services/repo-file-service.ts
15718
15740
  import { execFile as execFile2 } from "child_process";
15719
15741
  import { readFile as readFile15, realpath, stat as stat6 } from "fs/promises";
15720
- 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";
15721
15743
  var CACHE_TTL_MS = 3e4;
15722
15744
  var SEARCH_TIMEOUT_MS = 15e3;
15723
15745
  var MAX_CONTENT_BYTES = 256 * 1024;
@@ -15877,7 +15899,7 @@ var RepoFileService = class {
15877
15899
  const repo = repos.find((r) => r.name === repoName);
15878
15900
  if (!repo) return null;
15879
15901
  try {
15880
- const fullPath = await realpath(resolve2(join26(repo.path, filePath)));
15902
+ const fullPath = await realpath(resolve2(join27(repo.path, filePath)));
15881
15903
  const repoRoot = await realpath(repo.path);
15882
15904
  const repoPrefix = repoRoot.endsWith("/") ? repoRoot : repoRoot + "/";
15883
15905
  if (!fullPath.startsWith(repoPrefix) && fullPath !== repoRoot) return null;
@@ -15985,20 +16007,20 @@ var RepoFileService = class {
15985
16007
  import { Hono } from "hono";
15986
16008
  import { z as z7 } from "zod";
15987
16009
  import { readdir as readdir10, stat as stat7, readFile as readFile18 } from "fs/promises";
15988
- import { join as join29, resolve as resolve3 } from "path";
16010
+ import { join as join30, resolve as resolve3 } from "path";
15989
16011
 
15990
16012
  // src/services/warm-hooks-service.ts
15991
16013
  import { spawn as spawn4 } from "child_process";
15992
16014
  import { readFile as readFile17 } from "fs/promises";
15993
16015
  import { existsSync as existsSync8 } from "fs";
15994
- import { join as join28 } from "path";
16016
+ import { join as join29 } from "path";
15995
16017
 
15996
16018
  // src/services/warm-hook-logs-service.ts
15997
16019
  import { mkdir as mkdir15, readFile as readFile16, writeFile as writeFile6, readdir as readdir9, appendFile as appendFile4, unlink as unlink3 } from "fs/promises";
15998
16020
  import { homedir as homedir16 } from "os";
15999
- import { join as join27 } from "path";
16000
- var LOGS_DIR2 = join27(homedir16(), ".replicas", "warm-hook-logs");
16001
- 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");
16002
16024
  var GLOBAL_FILENAME = "global.json";
16003
16025
  function withPreview2(stored) {
16004
16026
  const preview = buildHookOutputPreview(stored.output);
@@ -16015,7 +16037,7 @@ var WarmHookLogsService = class {
16015
16037
  hookName: "organization",
16016
16038
  ...entry
16017
16039
  };
16018
- 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)}
16019
16041
  `, "utf-8");
16020
16042
  }
16021
16043
  async saveEnvironmentHookLog(entry) {
@@ -16025,7 +16047,7 @@ var WarmHookLogsService = class {
16025
16047
  hookName: "environment",
16026
16048
  ...entry
16027
16049
  };
16028
- 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)}
16029
16051
  `, "utf-8");
16030
16052
  }
16031
16053
  async saveRepoHookLog(repoName, entry) {
@@ -16035,7 +16057,7 @@ var WarmHookLogsService = class {
16035
16057
  hookName: repoName,
16036
16058
  ...entry
16037
16059
  };
16038
- 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)}
16039
16061
  `, "utf-8");
16040
16062
  }
16041
16063
  async getAllLogs() {
@@ -16054,7 +16076,7 @@ var WarmHookLogsService = class {
16054
16076
  continue;
16055
16077
  }
16056
16078
  try {
16057
- const raw = await readFile16(join27(LOGS_DIR2, file), "utf-8");
16079
+ const raw = await readFile16(join28(LOGS_DIR2, file), "utf-8");
16058
16080
  const stored = JSON.parse(raw);
16059
16081
  logs.push(withPreview2(stored));
16060
16082
  } catch {
@@ -16092,7 +16114,7 @@ var WarmHookLogsService = class {
16092
16114
  async getFullOutput(hookType, hookName) {
16093
16115
  const filename = hookType === "global" ? GLOBAL_FILENAME : hookType === "environment" ? ENVIRONMENT_HOOK_LOG_FILENAME : repoHookLogFilename(hookName);
16094
16116
  try {
16095
- const raw = await readFile16(join27(LOGS_DIR2, filename), "utf-8");
16117
+ const raw = await readFile16(join28(LOGS_DIR2, filename), "utf-8");
16096
16118
  const stored = JSON.parse(raw);
16097
16119
  if (stored.hookType !== hookType || stored.hookName !== hookName) {
16098
16120
  return null;
@@ -16111,7 +16133,7 @@ var warmHookLogsService = new WarmHookLogsService();
16111
16133
  // src/services/warm-hooks-service.ts
16112
16134
  async function readRepoWarmHook(repoPath) {
16113
16135
  for (const filename of REPLICAS_CONFIG_FILENAMES) {
16114
- const configPath = join28(repoPath, filename);
16136
+ const configPath = join29(repoPath, filename);
16115
16137
  if (!existsSync8(configPath)) {
16116
16138
  continue;
16117
16139
  }
@@ -17373,7 +17395,7 @@ data: ${JSON.stringify("Terminal session not found")}
17373
17395
  const logFiles = files.filter((f) => f.endsWith(".log"));
17374
17396
  const sessions = await Promise.all(
17375
17397
  logFiles.map(async (filename) => {
17376
- const filePath = join29(LOG_DIR, filename);
17398
+ const filePath = join30(LOG_DIR, filename);
17377
17399
  const fileStat = await stat7(filePath);
17378
17400
  const sessionId = filename.replace(/\.log$/, "");
17379
17401
  return {
@@ -17758,6 +17780,10 @@ serve(
17758
17780
  await timeStartupStep("chat_initialize", () => chatService.initialize());
17759
17781
  await timeStartupStep("preview_initialize", () => previewService.initialize());
17760
17782
  if (!IS_WARMING_MODE) {
17783
+ await timeStartupStep(
17784
+ "git_credential_helper_initialize",
17785
+ () => configureManagedGitCredentialHelper(ENGINE_ENV.HOME_DIR)
17786
+ );
17761
17787
  await timeStartupStep("github_token_initialize", () => githubTokenManager.start());
17762
17788
  }
17763
17789
  engineReady = true;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "replicas-engine",
3
- "version": "0.1.531",
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",