replicas-engine 0.1.422 → 0.1.424

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
@@ -87,6 +87,7 @@ Token refresh managers may later overwrite credential files in place:
87
87
  - `~/.git-credentials`
88
88
  - `~/.claude/.credentials.json`
89
89
  - `~/.codex/auth.json`
90
+ - `~/.replicas/infisical-env.sh` and `~/workspaces/.infisical.json`
90
91
 
91
92
  Engine persistence locations:
92
93
 
@@ -131,3 +132,4 @@ Outgoing endpoints:
131
132
  - `POST /v1/engine/github/refresh-token`
132
133
  - `POST /v1/engine/claude/refresh-credentials`
133
134
  - `POST /v1/engine/codex/refresh-credentials`
135
+ - `POST /v1/engine/infisical/refresh-token`
package/dist/src/index.js CHANGED
@@ -508,9 +508,12 @@ var WORKSPACE_SIZES = ["small", "large"];
508
508
  var INVALID_WORKSPACE_SIZE_ERROR = `Invalid size: must be one of ${WORKSPACE_SIZES.join(", ")}`;
509
509
 
510
510
  // ../shared/src/e2b.ts
511
- var E2B_TEMPLATE_NAME = "replicas-sandbox-2026-07-10-v3";
511
+ var E2B_TEMPLATE_NAME = "replicas-sandbox-2026-07-10-v5";
512
512
 
513
513
  // ../shared/src/runtime-env.ts
514
+ function shellQuotePosix(value) {
515
+ return `'${value.split("'").join("'\\''")}'`;
516
+ }
514
517
  function parsePosixEnvFile(content) {
515
518
  const result = {};
516
519
  let pos = 0;
@@ -3368,18 +3371,13 @@ var BaseRefreshManager = class {
3368
3371
  }
3369
3372
  }
3370
3373
  }
3371
- this.intervalHandle = setInterval(() => {
3372
- this.refreshOnce().catch((error) => {
3373
- console.error(`[${this.managerName}] Scheduled refresh failed:`, error);
3374
- });
3375
- }, this.intervalMs);
3376
- console.log(`[${this.managerName}] Token refresh scheduled every ${Math.round(this.intervalMs / 6e4)} minutes`);
3374
+ this.scheduleNextRefresh();
3377
3375
  }
3378
3376
  stop() {
3379
3377
  if (!this.intervalHandle) {
3380
3378
  return;
3381
3379
  }
3382
- clearInterval(this.intervalHandle);
3380
+ clearTimeout(this.intervalHandle);
3383
3381
  this.intervalHandle = null;
3384
3382
  this.health.isRunning = false;
3385
3383
  console.log(`[${this.managerName}] Stopped`);
@@ -3390,6 +3388,9 @@ var BaseRefreshManager = class {
3390
3388
  getSkipReason() {
3391
3389
  return null;
3392
3390
  }
3391
+ getNextRefreshDelayMs() {
3392
+ return this.intervalMs;
3393
+ }
3393
3394
  getRuntimeConfig() {
3394
3395
  if (!ENGINE_ENV.WORKSPACE_ID) {
3395
3396
  return null;
@@ -3400,6 +3401,15 @@ var BaseRefreshManager = class {
3400
3401
  engineSecret: ENGINE_ENV.REPLICAS_ENGINE_SECRET
3401
3402
  };
3402
3403
  }
3404
+ scheduleNextRefresh() {
3405
+ const delayMs = this.getNextRefreshDelayMs();
3406
+ this.health.intervalMs = delayMs;
3407
+ this.intervalHandle = setTimeout(async () => {
3408
+ await this.refreshOnce();
3409
+ if (this.intervalHandle) this.scheduleNextRefresh();
3410
+ }, delayMs);
3411
+ console.log(`[${this.managerName}] Token refresh scheduled in ${Math.round(delayMs / 1e3)} seconds`);
3412
+ }
3403
3413
  async refreshOnce() {
3404
3414
  if (this.getSkipReason()) {
3405
3415
  return;
@@ -3422,7 +3432,7 @@ var BaseRefreshManager = class {
3422
3432
  };
3423
3433
 
3424
3434
  // src/services/monolith-service.ts
3425
- async function monolithRequest(path5, init = {}) {
3435
+ async function monolithRequest(path6, init = {}) {
3426
3436
  if (!ENGINE_ENV.WORKSPACE_ID) {
3427
3437
  throw new Error("WORKSPACE_ID is not set; cannot call monolith");
3428
3438
  }
@@ -3432,7 +3442,7 @@ async function monolithRequest(path5, init = {}) {
3432
3442
  "X-Workspace-Id": ENGINE_ENV.WORKSPACE_ID
3433
3443
  };
3434
3444
  if (!isFormData) headers["Content-Type"] = "application/json";
3435
- return fetch(`${ENGINE_ENV.MONOLITH_URL}${path5}`, {
3445
+ return fetch(`${ENGINE_ENV.MONOLITH_URL}${path6}`, {
3436
3446
  method: init.method ?? "POST",
3437
3447
  headers,
3438
3448
  body: init.body === void 0 ? void 0 : isFormData ? init.body : JSON.stringify(init.body),
@@ -3475,11 +3485,11 @@ var AsyncLock = class {
3475
3485
  };
3476
3486
 
3477
3487
  // src/utils/file.ts
3478
- async function atomicWriteFile(path5, data, options) {
3479
- const tmpFile = `${path5}.${process.pid}.${Date.now()}.tmp`;
3488
+ async function atomicWriteFile(path6, data, options) {
3489
+ const tmpFile = `${path6}.${process.pid}.${Date.now()}.tmp`;
3480
3490
  try {
3481
3491
  await writeFile(tmpFile, data, { encoding: "utf-8", mode: options?.mode });
3482
- await rename(tmpFile, path5);
3492
+ await rename(tmpFile, path6);
3483
3493
  } catch (error) {
3484
3494
  await unlink(tmpFile).catch(() => void 0);
3485
3495
  throw error;
@@ -3862,6 +3872,64 @@ var CodexTokenManager = class extends BaseRefreshManager {
3862
3872
  };
3863
3873
  var codexTokenManager = new CodexTokenManager();
3864
3874
 
3875
+ // src/managers/infisical-token-manager.ts
3876
+ import { rm } from "fs/promises";
3877
+ import path5 from "path";
3878
+ var InfisicalTokenManager = class extends BaseRefreshManager {
3879
+ constructor(request = monolithRequest, paths = {
3880
+ homeDir: ENGINE_ENV.HOME_DIR,
3881
+ workspaceRoot: ENGINE_ENV.WORKSPACE_ROOT
3882
+ }, applyCredentials = applyInfisicalCredentials) {
3883
+ super("InfisicalTokenManager", 5 * 60 * 1e3);
3884
+ this.request = request;
3885
+ this.paths = paths;
3886
+ this.applyCredentials = applyCredentials;
3887
+ }
3888
+ request;
3889
+ paths;
3890
+ applyCredentials;
3891
+ nextRefreshDelayMs = 5 * 60 * 1e3;
3892
+ async doRefresh(_config) {
3893
+ const response = await this.request("/v1/engine/infisical/refresh-token");
3894
+ if (!response.ok) throw new Error(`Token refresh failed: ${response.status} ${await response.text()}`);
3895
+ const data = await response.json();
3896
+ await this.applyCredentials(data, this.paths);
3897
+ const ttlMs = data.configured ? Date.parse(data.expiresAt) - Date.now() : Number.NaN;
3898
+ this.nextRefreshDelayMs = Number.isFinite(ttlMs) ? Math.max(1e3, Math.min(5 * 60 * 1e3, Math.floor(ttlMs * 0.8))) : 5 * 60 * 1e3;
3899
+ }
3900
+ getNextRefreshDelayMs() {
3901
+ return this.nextRefreshDelayMs;
3902
+ }
3903
+ };
3904
+ async function applyInfisicalCredentials(data, paths) {
3905
+ const credentialPath = path5.join(paths.homeDir, ".replicas", "infisical-env.sh");
3906
+ const configPath = path5.join(paths.workspaceRoot, ".infisical.json");
3907
+ if (!data.configured) {
3908
+ delete process.env.INFISICAL_TOKEN;
3909
+ delete process.env.INFISICAL_DOMAIN;
3910
+ await Promise.all([rm(credentialPath, { force: true }), rm(configPath, { force: true })]);
3911
+ return;
3912
+ }
3913
+ process.env.INFISICAL_TOKEN = data.token;
3914
+ process.env.INFISICAL_DOMAIN = data.siteUrl;
3915
+ await Promise.all([
3916
+ writeSecureCredentialFile(credentialPath, [
3917
+ `export INFISICAL_TOKEN=${shellQuotePosix(data.token)}`,
3918
+ `export INFISICAL_DOMAIN=${shellQuotePosix(data.siteUrl)}`,
3919
+ "export INFISICAL_DISABLE_UPDATE_CHECK=true",
3920
+ ""
3921
+ ].join("\n"), { ensureParentDir: true }),
3922
+ writeSecureCredentialFile(configPath, `${JSON.stringify({
3923
+ workspaceId: data.projectId,
3924
+ defaultEnvironment: data.environment,
3925
+ gitBranchToEnvironmentMapping: null,
3926
+ domain: data.siteUrl
3927
+ }, null, 2)}
3928
+ `, { ensureParentDir: true })
3929
+ ]);
3930
+ }
3931
+ var infisicalTokenManager = new InfisicalTokenManager();
3932
+
3865
3933
  // src/git/service.ts
3866
3934
  import { readdir, readFile as readFile3, stat } from "fs/promises";
3867
3935
  import { existsSync as existsSync2, unlinkSync } from "fs";
@@ -4323,9 +4391,9 @@ var GitService = class {
4323
4391
  try {
4324
4392
  const paths = await this.listUntrackedPaths(repoPath);
4325
4393
  let total = 0;
4326
- for (const path5 of paths) {
4394
+ for (const path6 of paths) {
4327
4395
  try {
4328
- const contents = await readFile3(join5(repoPath, path5));
4396
+ const contents = await readFile3(join5(repoPath, path6));
4329
4397
  if (contents.length === 0 || contents.includes(0)) {
4330
4398
  continue;
4331
4399
  }
@@ -4613,12 +4681,12 @@ var GitService = class {
4613
4681
  await saveRepoState(repo.name, state, state);
4614
4682
  return state;
4615
4683
  }
4616
- pathExists(path5) {
4617
- return existsSync2(path5);
4684
+ pathExists(path6) {
4685
+ return existsSync2(path6);
4618
4686
  }
4619
- async safeStat(path5) {
4687
+ async safeStat(path6) {
4620
4688
  try {
4621
- return await stat(path5);
4689
+ return await stat(path6);
4622
4690
  } catch {
4623
4691
  return null;
4624
4692
  }
@@ -4641,8 +4709,8 @@ var StreamWriter = class {
4641
4709
  backpressured = false;
4642
4710
  droppedCount = 0;
4643
4711
  flushTimer = null;
4644
- open(path5, highWaterMark = DEFAULT_HIGH_WATER) {
4645
- this.stream = createWriteStream(path5, { flags: "a", highWaterMark });
4712
+ open(path6, highWaterMark = DEFAULT_HIGH_WATER) {
4713
+ this.stream = createWriteStream(path6, { flags: "a", highWaterMark });
4646
4714
  this.stream.on("error", () => {
4647
4715
  this.stream = null;
4648
4716
  });
@@ -5635,7 +5703,7 @@ async function registerDesktopPreview() {
5635
5703
 
5636
5704
  // src/services/chat/chat-service.ts
5637
5705
  import { existsSync as existsSync7 } from "fs";
5638
- import { appendFile as appendFile3, copyFile, mkdir as mkdir13, readFile as readFile14, rename as rename2, rm } from "fs/promises";
5706
+ import { appendFile as appendFile3, copyFile, mkdir as mkdir13, readFile as readFile14, rename as rename2, rm as rm2 } from "fs/promises";
5639
5707
  import { homedir as homedir15 } from "os";
5640
5708
  import { join as join21 } from "path";
5641
5709
  import { randomUUID as randomUUID5 } from "crypto";
@@ -6152,7 +6220,7 @@ async function saveNormalizedImagesToTempFiles(images, tempImageDir = join12(hom
6152
6220
  return tempPaths;
6153
6221
  }
6154
6222
  async function removeTempImageFiles(paths) {
6155
- await Promise.allSettled(paths.map((path5) => unlink2(path5)));
6223
+ await Promise.allSettled(paths.map((path6) => unlink2(path6)));
6156
6224
  }
6157
6225
 
6158
6226
  // src/services/message-queue-service.ts
@@ -6734,7 +6802,7 @@ async function getSkillRegistryInventory(homeDir) {
6734
6802
  async function buildClaudeRegistryConfig(homeDir) {
6735
6803
  const inventory = await getSkillRegistryInventory(homeDir);
6736
6804
  return {
6737
- plugins: inventory.claudePluginRoots.map((path5) => ({ type: "local", path: path5 })),
6805
+ plugins: inventory.claudePluginRoots.map((path6) => ({ type: "local", path: path6 })),
6738
6806
  enableAllSkills: inventory.claudePluginRoots.length > 0 || inventory.standaloneSkills.length > 0
6739
6807
  };
6740
6808
  }
@@ -6900,31 +6968,31 @@ function uniqueStandaloneSkills(skills) {
6900
6968
  }
6901
6969
  return unique;
6902
6970
  }
6903
- async function safeReadDir(path5) {
6971
+ async function safeReadDir(path6) {
6904
6972
  try {
6905
- return await readdir3(path5, { withFileTypes: true });
6973
+ return await readdir3(path6, { withFileTypes: true });
6906
6974
  } catch (error) {
6907
6975
  if (isNotFoundError(error)) return [];
6908
6976
  throw error;
6909
6977
  }
6910
6978
  }
6911
- async function isDirectoryDirent(dirent, path5) {
6979
+ async function isDirectoryDirent(dirent, path6) {
6912
6980
  if (dirent.isDirectory()) return true;
6913
6981
  if (!dirent.isSymbolicLink()) return false;
6914
- return directoryExists(path5);
6982
+ return directoryExists(path6);
6915
6983
  }
6916
- async function directoryExists(path5) {
6984
+ async function directoryExists(path6) {
6917
6985
  try {
6918
- const pathStat = await stat2(path5);
6986
+ const pathStat = await stat2(path6);
6919
6987
  return pathStat.isDirectory();
6920
6988
  } catch (error) {
6921
6989
  if (isNotFoundError(error)) return false;
6922
6990
  throw error;
6923
6991
  }
6924
6992
  }
6925
- async function fileExists(path5) {
6993
+ async function fileExists(path6) {
6926
6994
  try {
6927
- const pathStat = await stat2(path5);
6995
+ const pathStat = await stat2(path6);
6928
6996
  return pathStat.isFile();
6929
6997
  } catch (error) {
6930
6998
  if (isNotFoundError(error)) return false;
@@ -8348,7 +8416,7 @@ var DEFAULT_CODEX_ARGS = ["app-server", "--listen", "stdio://"];
8348
8416
  var MIN_CODEX_CLI_VERSION = "0.144.0";
8349
8417
  var CODEX_UPGRADE_TIMEOUT_MS = 12e4;
8350
8418
  var codexCliVersionEnsured = null;
8351
- var ENGINE_PACKAGE_VERSION = "0.1.422";
8419
+ var ENGINE_PACKAGE_VERSION = "0.1.424";
8352
8420
  var INITIALIZE_METHOD = "initialize";
8353
8421
  var INITIALIZED_NOTIFICATION = "initialized";
8354
8422
  var ACCOUNT_LOGIN_START_METHOD = "account/login/start";
@@ -8705,16 +8773,16 @@ function transcriptItemsForTurn(turn) {
8705
8773
  const otherItems = turn.items.filter((item) => item.type !== "userMessage");
8706
8774
  return [...userItems, ...otherItems];
8707
8775
  }
8708
- function userImageForLocalPath(path5) {
8709
- const cached = localImageCache.get(path5);
8776
+ function userImageForLocalPath(path6) {
8777
+ const cached = localImageCache.get(path6);
8710
8778
  if (cached) return cached;
8711
- if (!existsSync6(path5)) return null;
8779
+ if (!existsSync6(path6)) return null;
8712
8780
  const image = {
8713
8781
  type: "image",
8714
- mediaType: inferMediaType(path5),
8715
- data: readFileSync3(path5).toString("base64")
8782
+ mediaType: inferMediaType(path6),
8783
+ data: readFileSync3(path6).toString("base64")
8716
8784
  };
8717
- if (image.data.length > 0) localImageCache.set(path5, image);
8785
+ if (image.data.length > 0) localImageCache.set(path6, image);
8718
8786
  return image;
8719
8787
  }
8720
8788
  function userImagesForInput(input) {
@@ -9088,9 +9156,9 @@ async function buildTurnInput(request) {
9088
9156
  }
9089
9157
  const normalizedImages = await normalizeImages(request.images);
9090
9158
  const tempImagePaths = await saveNormalizedImagesToTempFiles(normalizedImages);
9091
- input.push(...tempImagePaths.map((path5) => ({
9159
+ input.push(...tempImagePaths.map((path6) => ({
9092
9160
  type: "localImage",
9093
- path: path5
9161
+ path: path6
9094
9162
  })));
9095
9163
  return { input, tempImagePaths };
9096
9164
  }
@@ -11534,9 +11602,9 @@ function extractTextBlocks(content, textBlockType, separator = "\n") {
11534
11602
  const texts = content.map((block) => block && typeof block === "object" && "type" in block && block.type === textBlockType && "text" in block && typeof block.text === "string" ? block.text : "").filter(Boolean);
11535
11603
  return texts.length > 0 ? texts.join(separator) : null;
11536
11604
  }
11537
- async function engineFetch(path5, options) {
11605
+ async function engineFetch(path6, options) {
11538
11606
  const baseUrl = `http://localhost:${ENGINE_ENV.REPLICAS_ENGINE_PORT}`;
11539
- return fetch(`${baseUrl}${path5}`, {
11607
+ return fetch(`${baseUrl}${path6}`, {
11540
11608
  ...options,
11541
11609
  headers: {
11542
11610
  "Content-Type": "application/json",
@@ -12812,8 +12880,8 @@ var ChatService = class {
12812
12880
  return descendants;
12813
12881
  }
12814
12882
  async deleteHistoryFile(persisted) {
12815
- await rm(join21(HISTORY_DIR_BY_PROVIDER[persisted.provider], `${persisted.id}.jsonl`), { force: true });
12816
- await rm(this.senderFilePath(persisted.id), { force: true });
12883
+ await rm2(join21(HISTORY_DIR_BY_PROVIDER[persisted.provider], `${persisted.id}.jsonl`), { force: true });
12884
+ await rm2(this.senderFilePath(persisted.id), { force: true });
12817
12885
  }
12818
12886
  async getChatHistory(chatId, page = {}) {
12819
12887
  const chat = this.requireChat(chatId);
@@ -14212,11 +14280,11 @@ function createV1Routes(deps) {
14212
14280
  });
14213
14281
  app2.get("/repo-files/content", async (c) => {
14214
14282
  const repoName = c.req.query("repoName");
14215
- const path5 = c.req.query("path");
14216
- if (!repoName || !path5) {
14283
+ const path6 = c.req.query("path");
14284
+ if (!repoName || !path6) {
14217
14285
  return c.json(jsonError("repoName and path are required"), 400);
14218
14286
  }
14219
- const result = await deps.repoFileService.readFile(repoName, path5);
14287
+ const result = await deps.repoFileService.readFile(repoName, path6);
14220
14288
  if (!result) {
14221
14289
  return c.json(jsonError("File not found"), 404);
14222
14290
  }
@@ -14805,7 +14873,8 @@ app.get("/token-refresh/health", async (c) => {
14805
14873
  github: githubTokenManager.getHealthStatus(),
14806
14874
  gitlab: gitlabTokenManager.getHealthStatus(),
14807
14875
  claude: claudeTokenManager.getHealthStatus(),
14808
- codex: codexTokenManager.getHealthStatus()
14876
+ codex: codexTokenManager.getHealthStatus(),
14877
+ infisical: infisicalTokenManager.getHealthStatus()
14809
14878
  });
14810
14879
  });
14811
14880
  var repoFileService = new RepoFileService(gitService);
@@ -14954,6 +15023,7 @@ serve(
14954
15023
  await gitlabTokenManager.start();
14955
15024
  await claudeTokenManager.start();
14956
15025
  await codexTokenManager.start();
15026
+ await infisicalTokenManager.start();
14957
15027
  }
14958
15028
  const repos = await gitService.listRepos();
14959
15029
  await eventService.publish({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "replicas-engine",
3
- "version": "0.1.422",
3
+ "version": "0.1.424",
4
4
  "description": "Lightweight API server for Replicas workspaces",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",