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 +2 -2
- package/dist/src/index.js +143 -122
- package/package.json +1 -1
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
|
|
70
|
-
- `git config --global credential.helper
|
|
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-
|
|
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
|
|
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
|
|
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 =
|
|
5295
|
-
var STATE_FILE =
|
|
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
|
|
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(
|
|
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 =
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
|
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 =
|
|
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 =
|
|
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
|
|
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
|
|
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
|
|
6498
|
-
var OPENCODE_AUTH_PATH =
|
|
6499
|
-
var PI_AUTH_PATH =
|
|
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 =
|
|
6503
|
-
var DETAILS_FILE =
|
|
6504
|
-
var CLAUDE_CREDENTIALS_PATH =
|
|
6505
|
-
var CODEX_AUTH_PATH =
|
|
6506
|
-
var GH_HOSTS_PATH =
|
|
6507
|
-
var GIT_CREDENTIALS_PATH =
|
|
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
|
|
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 =
|
|
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(
|
|
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(
|
|
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(
|
|
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 =
|
|
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 =
|
|
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(
|
|
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(
|
|
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
|
|
7254
|
+
import { join as join12 } from "path";
|
|
7238
7255
|
import { randomUUID } from "crypto";
|
|
7239
|
-
var ENGINE_DIR =
|
|
7240
|
-
var EVENTS_FILE =
|
|
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
|
|
7276
|
-
var PREVIEW_PORTS_FILE =
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
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 =
|
|
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
|
|
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:
|
|
8540
|
-
{ source: "agents", root:
|
|
8541
|
-
{ source: "codex", root:
|
|
8542
|
-
{ source: "claude", root:
|
|
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 =
|
|
8573
|
+
const skillDir = join15(root, dirent.name);
|
|
8557
8574
|
if (!await isDirectoryDirent(dirent, skillDir)) continue;
|
|
8558
|
-
if (await fileExists(
|
|
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 =
|
|
8585
|
+
const skillDir = join15(registryDir, dirent.name);
|
|
8569
8586
|
if (!await isDirectoryDirent(dirent, skillDir)) continue;
|
|
8570
|
-
if (await fileExists(
|
|
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 =
|
|
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(
|
|
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(
|
|
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
|
|
8663
|
+
return join15(homeDir, REGISTRY_ROOT_DIR);
|
|
8647
8664
|
}
|
|
8648
8665
|
function getManifestPath(homeDir) {
|
|
8649
|
-
return
|
|
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 ??
|
|
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
|
|
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.
|
|
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
|
|
11073
|
-
var ENGINE_DIR2 =
|
|
11074
|
-
var CHATS_FILE =
|
|
11075
|
-
var CLAUDE_HISTORY_DIR =
|
|
11076
|
-
var RELAY_HISTORY_DIR =
|
|
11077
|
-
var CODEX_HISTORY_DIR =
|
|
11078
|
-
var CURSOR_HISTORY_DIR =
|
|
11079
|
-
var OPENCODE_HISTORY_DIR =
|
|
11080
|
-
var PI_HISTORY_DIR =
|
|
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(
|
|
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
|
|
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(
|
|
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 ??
|
|
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) =>
|
|
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
|
|
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 =
|
|
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 ??
|
|
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
|
|
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 ??
|
|
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:
|
|
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
|
|
14397
|
+
import { join as join22 } from "path";
|
|
14381
14398
|
var GLOBAL_CANVAS_DIRECTORIES = [
|
|
14382
|
-
|
|
14383
|
-
|
|
14384
|
-
|
|
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) =>
|
|
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(
|
|
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 =
|
|
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
|
|
14582
|
+
import { basename as basename2, join as join24 } from "path";
|
|
14566
14583
|
|
|
14567
14584
|
// src/services/chat/chat-senders.ts
|
|
14568
|
-
import { join as
|
|
14569
|
-
var CHAT_SENDERS_DIR =
|
|
14585
|
+
import { join as join23 } from "path";
|
|
14586
|
+
var CHAT_SENDERS_DIR = join23(ENGINE_DIR2, "chat-senders");
|
|
14570
14587
|
function chatMessageSendersFilePath(chatId) {
|
|
14571
|
-
return
|
|
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
|
-
|
|
14588
|
-
|
|
14589
|
-
|
|
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,
|
|
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
|
|
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 =
|
|
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 =
|
|
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(
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
-
|
|
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
|
|
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(
|
|
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
|
|
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
|
|
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
|
|
16005
|
-
var LOGS_DIR2 =
|
|
16006
|
-
var 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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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 =
|
|
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 =
|
|
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;
|