replicas-engine 0.1.196 → 0.1.199
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/dist/src/index.js +91 -95
- package/package.json +1 -1
package/dist/src/index.js
CHANGED
|
@@ -12,11 +12,13 @@ import { promises as fs } from "fs";
|
|
|
12
12
|
import path from "path";
|
|
13
13
|
|
|
14
14
|
// src/engine-env.ts
|
|
15
|
-
import { homedir } from "os";
|
|
16
|
-
import { join } from "path";
|
|
15
|
+
import { homedir as homedir2 } from "os";
|
|
16
|
+
import { join as join2 } from "path";
|
|
17
17
|
|
|
18
18
|
// src/runtime-env-loader.ts
|
|
19
19
|
import { readFileSync } from "fs";
|
|
20
|
+
import { homedir } from "os";
|
|
21
|
+
import { join } from "path";
|
|
20
22
|
|
|
21
23
|
// ../shared/src/event.ts
|
|
22
24
|
var CODEX_QUOTA_STATUS_EVENT_TYPE = "codex-quota-status";
|
|
@@ -205,15 +207,6 @@ var SANDBOX_LIFECYCLE = {
|
|
|
205
207
|
AUTO_DELETE_MINUTES: -1,
|
|
206
208
|
SSH_TOKEN_EXPIRATION_MINUTES: 3 * 60
|
|
207
209
|
};
|
|
208
|
-
var SANDBOX_PATHS = {
|
|
209
|
-
HOME_DIR: "/home/ubuntu",
|
|
210
|
-
WORKSPACES_DIR: "/home/ubuntu/workspaces",
|
|
211
|
-
REPLICAS_DIR: "/home/ubuntu/.replicas",
|
|
212
|
-
REPLICAS_FILES_DIR: "/home/ubuntu/.replicas/files",
|
|
213
|
-
REPLICAS_FILES_DISPLAY_DIR: "~/.replicas/files",
|
|
214
|
-
REPLICAS_RUNTIME_ENV_FILE: "/home/ubuntu/.replicas/runtime-env.sh",
|
|
215
|
-
REPLICAS_PREVIEW_PORTS_FILE: "/home/ubuntu/.replicas/preview-ports.json"
|
|
216
|
-
};
|
|
217
210
|
|
|
218
211
|
// ../shared/src/runtime-env.ts
|
|
219
212
|
function parsePosixEnvFile(content) {
|
|
@@ -392,7 +385,7 @@ function parseReplicasConfigString(content, filename) {
|
|
|
392
385
|
}
|
|
393
386
|
|
|
394
387
|
// ../shared/src/engine/environment.ts
|
|
395
|
-
var DAYTONA_SNAPSHOT_ID = "21-05-2026-royal-york-
|
|
388
|
+
var DAYTONA_SNAPSHOT_ID = "21-05-2026-royal-york-v6";
|
|
396
389
|
|
|
397
390
|
// ../shared/src/engine/types.ts
|
|
398
391
|
var DEFAULT_CHAT_TITLES = {
|
|
@@ -458,7 +451,7 @@ var MEDIA_KINDS = [MEDIA_KIND.IMAGE, MEDIA_KIND.VIDEO, MEDIA_KIND.AUDIO];
|
|
|
458
451
|
function loadRuntimeEnvFile() {
|
|
459
452
|
let content;
|
|
460
453
|
try {
|
|
461
|
-
content = readFileSync(
|
|
454
|
+
content = readFileSync(join(homedir(), ".replicas", "runtime-env.sh"), "utf-8");
|
|
462
455
|
} catch {
|
|
463
456
|
return;
|
|
464
457
|
}
|
|
@@ -511,7 +504,7 @@ function parseCodexAuthMethod(value) {
|
|
|
511
504
|
var IS_WARMING_MODE = process.argv.includes("--warming");
|
|
512
505
|
function loadEngineEnv() {
|
|
513
506
|
loadRuntimeEnvFile();
|
|
514
|
-
const HOME_DIR =
|
|
507
|
+
const HOME_DIR = homedir2();
|
|
515
508
|
const env = {
|
|
516
509
|
// Defined: always available
|
|
517
510
|
REPLICAS_ENGINE_SECRET: requireDefined(readEnv("REPLICAS_ENGINE_SECRET"), "REPLICAS_ENGINE_SECRET"),
|
|
@@ -519,7 +512,7 @@ function loadEngineEnv() {
|
|
|
519
512
|
MONOLITH_URL: requireValidURL(requireDefined(readEnv("MONOLITH_URL"), "MONOLITH_URL"), "MONOLITH_URL"),
|
|
520
513
|
GH_TOKEN: readEnv("GH_TOKEN"),
|
|
521
514
|
HOME_DIR,
|
|
522
|
-
WORKSPACE_ROOT:
|
|
515
|
+
WORKSPACE_ROOT: join2(HOME_DIR, "workspaces"),
|
|
523
516
|
// Runtime: may not be set during warming
|
|
524
517
|
WORKSPACE_ID: readEnv("WORKSPACE_ID"),
|
|
525
518
|
WORKSPACE_BRANCH_NAME: readEnv("WORKSPACE_BRANCH_NAME"),
|
|
@@ -832,13 +825,13 @@ var codexTokenManager = new CodexTokenManager();
|
|
|
832
825
|
import { readdir, stat } from "fs/promises";
|
|
833
826
|
import { existsSync as existsSync2 } from "fs";
|
|
834
827
|
import { execFileSync as execFileSync2, spawnSync } from "child_process";
|
|
835
|
-
import { join as
|
|
828
|
+
import { join as join5 } from "path";
|
|
836
829
|
|
|
837
830
|
// src/utils/state.ts
|
|
838
831
|
import { readFile, writeFile, mkdir, rename, unlink } from "fs/promises";
|
|
839
832
|
import { existsSync } from "fs";
|
|
840
|
-
import { join as
|
|
841
|
-
import { homedir as
|
|
833
|
+
import { join as join3 } from "path";
|
|
834
|
+
import { homedir as homedir3 } from "os";
|
|
842
835
|
|
|
843
836
|
// src/utils/type-guards.ts
|
|
844
837
|
function isRecord3(value) {
|
|
@@ -846,8 +839,8 @@ function isRecord3(value) {
|
|
|
846
839
|
}
|
|
847
840
|
|
|
848
841
|
// src/utils/state.ts
|
|
849
|
-
var STATE_DIR =
|
|
850
|
-
var STATE_FILE =
|
|
842
|
+
var STATE_DIR = join3(homedir3(), ".replicas");
|
|
843
|
+
var STATE_FILE = join3(STATE_DIR, "engine-state.json");
|
|
851
844
|
var DEFAULT_STATE = {
|
|
852
845
|
repos: {}
|
|
853
846
|
};
|
|
@@ -958,7 +951,7 @@ async function saveRepoState(repoName, state, fallbackState) {
|
|
|
958
951
|
// src/git/commands.ts
|
|
959
952
|
import { execFileSync } from "child_process";
|
|
960
953
|
import { readFileSync as readFileSync2 } from "fs";
|
|
961
|
-
import { join as
|
|
954
|
+
import { join as join4 } from "path";
|
|
962
955
|
function runGitCommand(args, cwd) {
|
|
963
956
|
return execFileSync("git", args, {
|
|
964
957
|
cwd,
|
|
@@ -968,7 +961,7 @@ function runGitCommand(args, cwd) {
|
|
|
968
961
|
}
|
|
969
962
|
function readRepoHeadBranch(repoPath) {
|
|
970
963
|
try {
|
|
971
|
-
const contents = readFileSync2(
|
|
964
|
+
const contents = readFileSync2(join4(repoPath, ".git", "HEAD"), "utf-8").trim();
|
|
972
965
|
const match = contents.match(/^ref:\s+refs\/heads\/(.+)$/);
|
|
973
966
|
return match ? match[1] : null;
|
|
974
967
|
} catch {
|
|
@@ -1011,13 +1004,13 @@ var GitService = class {
|
|
|
1011
1004
|
const entries = await readdir(root);
|
|
1012
1005
|
const repos = [];
|
|
1013
1006
|
for (const entry of entries) {
|
|
1014
|
-
const fullPath =
|
|
1007
|
+
const fullPath = join5(root, entry);
|
|
1015
1008
|
try {
|
|
1016
1009
|
const entryStat = await stat(fullPath);
|
|
1017
1010
|
if (!entryStat.isDirectory()) {
|
|
1018
1011
|
continue;
|
|
1019
1012
|
}
|
|
1020
|
-
const hasGit = Boolean(await this.safeStat(
|
|
1013
|
+
const hasGit = Boolean(await this.safeStat(join5(fullPath, ".git")));
|
|
1021
1014
|
if (!hasGit) {
|
|
1022
1015
|
continue;
|
|
1023
1016
|
}
|
|
@@ -1392,11 +1385,11 @@ var gitService = new GitService();
|
|
|
1392
1385
|
|
|
1393
1386
|
// src/utils/logger.ts
|
|
1394
1387
|
import { appendFile, mkdir as mkdir2, writeFile as writeFile2 } from "fs/promises";
|
|
1395
|
-
import { homedir as
|
|
1396
|
-
import { join as
|
|
1388
|
+
import { homedir as homedir4 } from "os";
|
|
1389
|
+
import { join as join6 } from "path";
|
|
1397
1390
|
import { format } from "util";
|
|
1398
1391
|
import { randomBytes } from "crypto";
|
|
1399
|
-
var LOG_DIR =
|
|
1392
|
+
var LOG_DIR = join6(homedir4(), ".replicas", "logs");
|
|
1400
1393
|
var EngineLogger = class {
|
|
1401
1394
|
_sessionId = null;
|
|
1402
1395
|
filePath = null;
|
|
@@ -1408,7 +1401,7 @@ var EngineLogger = class {
|
|
|
1408
1401
|
async initialize() {
|
|
1409
1402
|
await mkdir2(LOG_DIR, { recursive: true });
|
|
1410
1403
|
this._sessionId = this.createSessionId();
|
|
1411
|
-
this.filePath =
|
|
1404
|
+
this.filePath = join6(LOG_DIR, `${this._sessionId}.log`);
|
|
1412
1405
|
await writeFile2(this.filePath, `=== Replicas Engine Session ${this._sessionId} ===
|
|
1413
1406
|
`, "utf-8");
|
|
1414
1407
|
this.patchConsole();
|
|
@@ -1461,23 +1454,23 @@ var engineLogger = new EngineLogger();
|
|
|
1461
1454
|
// src/services/replicas-config-service.ts
|
|
1462
1455
|
import { readFile as readFile4, appendFile as appendFile2, writeFile as writeFile5, mkdir as mkdir5 } from "fs/promises";
|
|
1463
1456
|
import { existsSync as existsSync4 } from "fs";
|
|
1464
|
-
import { join as
|
|
1465
|
-
import { homedir as
|
|
1457
|
+
import { join as join9 } from "path";
|
|
1458
|
+
import { homedir as homedir7 } from "os";
|
|
1466
1459
|
import { exec } from "child_process";
|
|
1467
1460
|
import { promisify as promisify2 } from "util";
|
|
1468
1461
|
|
|
1469
1462
|
// src/services/environment-details-service.ts
|
|
1470
1463
|
import { mkdir as mkdir3, readFile as readFile2, writeFile as writeFile3 } from "fs/promises";
|
|
1471
1464
|
import { existsSync as existsSync3 } from "fs";
|
|
1472
|
-
import { homedir as
|
|
1473
|
-
import { join as
|
|
1465
|
+
import { homedir as homedir5 } from "os";
|
|
1466
|
+
import { join as join7 } from "path";
|
|
1474
1467
|
import { execFile } from "child_process";
|
|
1475
1468
|
import { promisify } from "util";
|
|
1476
1469
|
var execFileAsync = promisify(execFile);
|
|
1477
|
-
var REPLICAS_DIR =
|
|
1478
|
-
var DETAILS_FILE =
|
|
1479
|
-
var CLAUDE_CREDENTIALS_PATH =
|
|
1480
|
-
var CODEX_AUTH_PATH =
|
|
1470
|
+
var REPLICAS_DIR = join7(homedir5(), ".replicas");
|
|
1471
|
+
var DETAILS_FILE = join7(REPLICAS_DIR, "environment-details.json");
|
|
1472
|
+
var CLAUDE_CREDENTIALS_PATH = join7(homedir5(), ".claude", ".credentials.json");
|
|
1473
|
+
var CODEX_AUTH_PATH = join7(homedir5(), ".codex", "auth.json");
|
|
1481
1474
|
function detectClaudeAuthMethod() {
|
|
1482
1475
|
if (existsSync3(CLAUDE_CREDENTIALS_PATH)) {
|
|
1483
1476
|
return "oauth";
|
|
@@ -1635,8 +1628,9 @@ var environmentDetailsService = new EnvironmentDetailsService();
|
|
|
1635
1628
|
// src/services/start-hook-logs-service.ts
|
|
1636
1629
|
import { createHash } from "crypto";
|
|
1637
1630
|
import { mkdir as mkdir4, readFile as readFile3, writeFile as writeFile4, readdir as readdir2 } from "fs/promises";
|
|
1638
|
-
import {
|
|
1639
|
-
|
|
1631
|
+
import { homedir as homedir6 } from "os";
|
|
1632
|
+
import { join as join8 } from "path";
|
|
1633
|
+
var LOGS_DIR = join8(homedir6(), ".replicas", "start-hook-logs");
|
|
1640
1634
|
function sanitizeFilename(name) {
|
|
1641
1635
|
const safe = name.replace(/[^a-zA-Z0-9._-]/g, "_");
|
|
1642
1636
|
const hash = createHash("sha256").update(name).digest("hex").slice(0, 8);
|
|
@@ -1656,7 +1650,7 @@ var StartHookLogsService = class {
|
|
|
1656
1650
|
async saveRepoLog(repoName, entry) {
|
|
1657
1651
|
await this.ensureDir();
|
|
1658
1652
|
const log = { repoName, ...entry };
|
|
1659
|
-
await writeFile4(
|
|
1653
|
+
await writeFile4(join8(LOGS_DIR, repoFilename(repoName)), `${JSON.stringify(log, null, 2)}
|
|
1660
1654
|
`, "utf-8");
|
|
1661
1655
|
}
|
|
1662
1656
|
async getAllLogs() {
|
|
@@ -1675,7 +1669,7 @@ var StartHookLogsService = class {
|
|
|
1675
1669
|
continue;
|
|
1676
1670
|
}
|
|
1677
1671
|
try {
|
|
1678
|
-
const raw = await readFile3(
|
|
1672
|
+
const raw = await readFile3(join8(LOGS_DIR, file), "utf-8");
|
|
1679
1673
|
const stored = JSON.parse(raw);
|
|
1680
1674
|
logs.push(withPreview(stored));
|
|
1681
1675
|
} catch {
|
|
@@ -1686,7 +1680,7 @@ var StartHookLogsService = class {
|
|
|
1686
1680
|
}
|
|
1687
1681
|
async getFullOutput(repoName) {
|
|
1688
1682
|
try {
|
|
1689
|
-
const raw = await readFile3(
|
|
1683
|
+
const raw = await readFile3(join8(LOGS_DIR, repoFilename(repoName)), "utf-8");
|
|
1690
1684
|
const stored = JSON.parse(raw);
|
|
1691
1685
|
if (stored.repoName !== repoName) {
|
|
1692
1686
|
return null;
|
|
@@ -1704,7 +1698,7 @@ var startHookLogsService = new StartHookLogsService();
|
|
|
1704
1698
|
|
|
1705
1699
|
// src/services/replicas-config-service.ts
|
|
1706
1700
|
var execAsync = promisify2(exec);
|
|
1707
|
-
var START_HOOKS_LOG =
|
|
1701
|
+
var START_HOOKS_LOG = join9(homedir7(), ".replicas", "startHooks.log");
|
|
1708
1702
|
var START_HOOKS_RUNNING_PROMPT = `IMPORTANT - Start Hooks Running:
|
|
1709
1703
|
Start hooks are shell commands/scripts set by repository owners that run on workspace startup.
|
|
1710
1704
|
These hooks are currently executing in the background. You can:
|
|
@@ -1715,7 +1709,7 @@ The start hooks may install dependencies, build projects, or perform other setup
|
|
|
1715
1709
|
If your task depends on setup being complete, check the log file before proceeding.`;
|
|
1716
1710
|
async function readReplicasConfigFromDir(dirPath) {
|
|
1717
1711
|
for (const filename of REPLICAS_CONFIG_FILENAMES) {
|
|
1718
|
-
const configPath =
|
|
1712
|
+
const configPath = join9(dirPath, filename);
|
|
1719
1713
|
if (!existsSync4(configPath)) {
|
|
1720
1714
|
continue;
|
|
1721
1715
|
}
|
|
@@ -1779,7 +1773,7 @@ var ReplicasConfigService = class {
|
|
|
1779
1773
|
const logLine = `[${timestamp}] ${message}
|
|
1780
1774
|
`;
|
|
1781
1775
|
try {
|
|
1782
|
-
await mkdir5(
|
|
1776
|
+
await mkdir5(join9(homedir7(), ".replicas"), { recursive: true });
|
|
1783
1777
|
await appendFile2(START_HOOKS_LOG, logLine, "utf-8");
|
|
1784
1778
|
} catch (error) {
|
|
1785
1779
|
console.error("Failed to write to start hooks log:", error);
|
|
@@ -1840,7 +1834,7 @@ var ReplicasConfigService = class {
|
|
|
1840
1834
|
this.hooksRunning = true;
|
|
1841
1835
|
this.hooksCompleted = false;
|
|
1842
1836
|
try {
|
|
1843
|
-
await mkdir5(
|
|
1837
|
+
await mkdir5(join9(homedir7(), ".replicas"), { recursive: true });
|
|
1844
1838
|
await writeFile5(
|
|
1845
1839
|
START_HOOKS_LOG,
|
|
1846
1840
|
`=== Start Hooks Execution Log ===
|
|
@@ -1988,11 +1982,11 @@ var replicasConfigService = new ReplicasConfigService();
|
|
|
1988
1982
|
|
|
1989
1983
|
// src/services/event-service.ts
|
|
1990
1984
|
import { appendFile as appendFile3, mkdir as mkdir6 } from "fs/promises";
|
|
1991
|
-
import { homedir as
|
|
1992
|
-
import { join as
|
|
1985
|
+
import { homedir as homedir8 } from "os";
|
|
1986
|
+
import { join as join10 } from "path";
|
|
1993
1987
|
import { randomUUID } from "crypto";
|
|
1994
|
-
var ENGINE_DIR =
|
|
1995
|
-
var EVENTS_FILE =
|
|
1988
|
+
var ENGINE_DIR = join10(homedir8(), ".replicas", "engine");
|
|
1989
|
+
var EVENTS_FILE = join10(ENGINE_DIR, "events.jsonl");
|
|
1996
1990
|
var EventService = class {
|
|
1997
1991
|
subscribers = /* @__PURE__ */ new Map();
|
|
1998
1992
|
writeChain = Promise.resolve();
|
|
@@ -2030,8 +2024,9 @@ var eventService = new EventService();
|
|
|
2030
2024
|
import { mkdir as mkdir7, readFile as readFile5, writeFile as writeFile6 } from "fs/promises";
|
|
2031
2025
|
import { existsSync as existsSync5 } from "fs";
|
|
2032
2026
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
2033
|
-
import {
|
|
2034
|
-
|
|
2027
|
+
import { homedir as homedir9 } from "os";
|
|
2028
|
+
import { dirname, join as join11 } from "path";
|
|
2029
|
+
var PREVIEW_PORTS_FILE = join11(homedir9(), ".replicas", "preview-ports.json");
|
|
2035
2030
|
async function readPreviewsFile() {
|
|
2036
2031
|
try {
|
|
2037
2032
|
if (!existsSync5(PREVIEW_PORTS_FILE)) {
|
|
@@ -2100,8 +2095,8 @@ var previewService = new PreviewService();
|
|
|
2100
2095
|
// src/services/chat/chat-service.ts
|
|
2101
2096
|
import { existsSync as existsSync7 } from "fs";
|
|
2102
2097
|
import { appendFile as appendFile5, mkdir as mkdir10, readFile as readFile8, rm, writeFile as writeFile8 } from "fs/promises";
|
|
2103
|
-
import { homedir as
|
|
2104
|
-
import { join as
|
|
2098
|
+
import { homedir as homedir12 } from "os";
|
|
2099
|
+
import { join as join14 } from "path";
|
|
2105
2100
|
import { randomUUID as randomUUID5 } from "crypto";
|
|
2106
2101
|
|
|
2107
2102
|
// src/managers/claude-manager.ts
|
|
@@ -2109,9 +2104,9 @@ import {
|
|
|
2109
2104
|
query
|
|
2110
2105
|
} from "@anthropic-ai/claude-agent-sdk";
|
|
2111
2106
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
2112
|
-
import { join as
|
|
2107
|
+
import { join as join12 } from "path";
|
|
2113
2108
|
import { mkdir as mkdir8, appendFile as appendFile4 } from "fs/promises";
|
|
2114
|
-
import { homedir as
|
|
2109
|
+
import { homedir as homedir10 } from "os";
|
|
2115
2110
|
|
|
2116
2111
|
// src/utils/jsonl-reader.ts
|
|
2117
2112
|
import { readFile as readFile6 } from "fs/promises";
|
|
@@ -3109,7 +3104,7 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
|
|
|
3109
3104
|
pendingToolInputs = /* @__PURE__ */ new Map();
|
|
3110
3105
|
constructor(options) {
|
|
3111
3106
|
super(options);
|
|
3112
|
-
this.historyFile = options.historyFilePath ??
|
|
3107
|
+
this.historyFile = options.historyFilePath ?? join12(homedir10(), ".replicas", "claude", "history.jsonl");
|
|
3113
3108
|
this.systemPromptOverride = options.systemPromptOverride;
|
|
3114
3109
|
this.toolsOverride = options.tools;
|
|
3115
3110
|
this.mcpServersConfig = options.mcpServers;
|
|
@@ -3442,7 +3437,7 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
|
|
|
3442
3437
|
};
|
|
3443
3438
|
}
|
|
3444
3439
|
async initialize() {
|
|
3445
|
-
const historyDir =
|
|
3440
|
+
const historyDir = join12(homedir10(), ".replicas", "claude");
|
|
3446
3441
|
await mkdir8(historyDir, { recursive: true });
|
|
3447
3442
|
if (this.initialSessionId) {
|
|
3448
3443
|
this.sessionId = this.initialSessionId;
|
|
@@ -3496,11 +3491,11 @@ import { Codex } from "@openai/codex-sdk";
|
|
|
3496
3491
|
import { randomUUID as randomUUID4 } from "crypto";
|
|
3497
3492
|
import { readdir as readdir3, stat as stat2, writeFile as writeFile7, mkdir as mkdir9, readFile as readFile7 } from "fs/promises";
|
|
3498
3493
|
import { existsSync as existsSync6 } from "fs";
|
|
3499
|
-
import { join as
|
|
3500
|
-
import { homedir as
|
|
3494
|
+
import { join as join13 } from "path";
|
|
3495
|
+
import { homedir as homedir11 } from "os";
|
|
3501
3496
|
import { parse as parseToml, stringify as stringifyToml } from "smol-toml";
|
|
3502
3497
|
var DEFAULT_MODEL = "gpt-5.5";
|
|
3503
|
-
var CODEX_CONFIG_PATH =
|
|
3498
|
+
var CODEX_CONFIG_PATH = join13(homedir11(), ".codex", "config.toml");
|
|
3504
3499
|
function isLinearThoughtEvent2(event) {
|
|
3505
3500
|
return event.content.type === "thought";
|
|
3506
3501
|
}
|
|
@@ -3554,7 +3549,7 @@ var CodexManager = class extends CodingAgentManager {
|
|
|
3554
3549
|
env: buildCodexAgentEnv(),
|
|
3555
3550
|
...codexApiKey ? { apiKey: codexApiKey } : {}
|
|
3556
3551
|
});
|
|
3557
|
-
this.tempImageDir =
|
|
3552
|
+
this.tempImageDir = join13(homedir11(), ".replicas", "codex", "temp-images");
|
|
3558
3553
|
this.initializeManager(this.processMessageInternal.bind(this));
|
|
3559
3554
|
}
|
|
3560
3555
|
async initialize() {
|
|
@@ -3641,7 +3636,7 @@ var CodexManager = class extends CodingAgentManager {
|
|
|
3641
3636
|
*/
|
|
3642
3637
|
async updateCodexConfig(developerInstructions) {
|
|
3643
3638
|
try {
|
|
3644
|
-
const codexDir =
|
|
3639
|
+
const codexDir = join13(homedir11(), ".codex");
|
|
3645
3640
|
await mkdir9(codexDir, { recursive: true });
|
|
3646
3641
|
let config = {};
|
|
3647
3642
|
if (existsSync6(CODEX_CONFIG_PATH)) {
|
|
@@ -3677,7 +3672,7 @@ var CodexManager = class extends CodingAgentManager {
|
|
|
3677
3672
|
for (const image of images) {
|
|
3678
3673
|
const ext = image.source.media_type.split("/")[1] || "png";
|
|
3679
3674
|
const filename = `img_${randomUUID4()}.${ext}`;
|
|
3680
|
-
const filepath =
|
|
3675
|
+
const filepath = join13(this.tempImageDir, filename);
|
|
3681
3676
|
const buffer = Buffer.from(image.source.data, "base64");
|
|
3682
3677
|
await writeFile7(filepath, buffer);
|
|
3683
3678
|
tempPaths.push(filepath);
|
|
@@ -3837,13 +3832,13 @@ var CodexManager = class extends CodingAgentManager {
|
|
|
3837
3832
|
}
|
|
3838
3833
|
// Helper methods for finding session files
|
|
3839
3834
|
async findSessionFile(threadId) {
|
|
3840
|
-
const sessionsDir =
|
|
3835
|
+
const sessionsDir = join13(homedir11(), ".codex", "sessions");
|
|
3841
3836
|
try {
|
|
3842
3837
|
const now = /* @__PURE__ */ new Date();
|
|
3843
3838
|
const year = now.getFullYear();
|
|
3844
3839
|
const month = String(now.getMonth() + 1).padStart(2, "0");
|
|
3845
3840
|
const day = String(now.getDate()).padStart(2, "0");
|
|
3846
|
-
const todayDir =
|
|
3841
|
+
const todayDir = join13(sessionsDir, String(year), month, day);
|
|
3847
3842
|
const file = await this.findFileInDirectory(todayDir, threadId);
|
|
3848
3843
|
if (file) return file;
|
|
3849
3844
|
for (let daysAgo = 1; daysAgo <= 7; daysAgo++) {
|
|
@@ -3852,7 +3847,7 @@ var CodexManager = class extends CodingAgentManager {
|
|
|
3852
3847
|
const searchYear = date.getFullYear();
|
|
3853
3848
|
const searchMonth = String(date.getMonth() + 1).padStart(2, "0");
|
|
3854
3849
|
const searchDay = String(date.getDate()).padStart(2, "0");
|
|
3855
|
-
const searchDir =
|
|
3850
|
+
const searchDir = join13(sessionsDir, String(searchYear), searchMonth, searchDay);
|
|
3856
3851
|
const file2 = await this.findFileInDirectory(searchDir, threadId);
|
|
3857
3852
|
if (file2) return file2;
|
|
3858
3853
|
}
|
|
@@ -3866,7 +3861,7 @@ var CodexManager = class extends CodingAgentManager {
|
|
|
3866
3861
|
const files = await readdir3(directory);
|
|
3867
3862
|
for (const file of files) {
|
|
3868
3863
|
if (file.endsWith(".jsonl") && file.includes(threadId)) {
|
|
3869
|
-
const fullPath =
|
|
3864
|
+
const fullPath = join13(directory, file);
|
|
3870
3865
|
const stats = await stat2(fullPath);
|
|
3871
3866
|
if (stats.isFile()) {
|
|
3872
3867
|
return fullPath;
|
|
@@ -4574,12 +4569,12 @@ var DuplicateDefaultChatError = class extends Error {
|
|
|
4574
4569
|
};
|
|
4575
4570
|
|
|
4576
4571
|
// src/services/chat/chat-service.ts
|
|
4577
|
-
var ENGINE_DIR2 =
|
|
4578
|
-
var CHATS_FILE =
|
|
4579
|
-
var CLAUDE_HISTORY_DIR =
|
|
4580
|
-
var RELAY_HISTORY_DIR =
|
|
4581
|
-
var CHAT_SENDERS_DIR =
|
|
4582
|
-
var CODEX_AUTH_PATH2 =
|
|
4572
|
+
var ENGINE_DIR2 = join14(homedir12(), ".replicas", "engine");
|
|
4573
|
+
var CHATS_FILE = join14(ENGINE_DIR2, "chats.json");
|
|
4574
|
+
var CLAUDE_HISTORY_DIR = join14(ENGINE_DIR2, "claude-histories");
|
|
4575
|
+
var RELAY_HISTORY_DIR = join14(ENGINE_DIR2, "relay-histories");
|
|
4576
|
+
var CHAT_SENDERS_DIR = join14(ENGINE_DIR2, "chat-senders");
|
|
4577
|
+
var CODEX_AUTH_PATH2 = join14(homedir12(), ".codex", "auth.json");
|
|
4583
4578
|
function isChatMessageSender(value) {
|
|
4584
4579
|
if (!isRecord3(value)) return false;
|
|
4585
4580
|
return typeof value.senderUserId === "string" && typeof value.senderEmail === "string" && typeof value.recordedAt === "string";
|
|
@@ -4700,7 +4695,7 @@ var ChatService = class {
|
|
|
4700
4695
|
};
|
|
4701
4696
|
}
|
|
4702
4697
|
senderFilePath(chatId) {
|
|
4703
|
-
return
|
|
4698
|
+
return join14(CHAT_SENDERS_DIR, `${chatId}.jsonl`);
|
|
4704
4699
|
}
|
|
4705
4700
|
async appendSender(chatId, sender) {
|
|
4706
4701
|
try {
|
|
@@ -4817,7 +4812,7 @@ var ChatService = class {
|
|
|
4817
4812
|
async deleteHistoryFile(persisted) {
|
|
4818
4813
|
if (persisted.provider === "claude" || persisted.provider === "relay") {
|
|
4819
4814
|
const dir = persisted.provider === "claude" ? CLAUDE_HISTORY_DIR : RELAY_HISTORY_DIR;
|
|
4820
|
-
await rm(
|
|
4815
|
+
await rm(join14(dir, `${persisted.id}.jsonl`), { force: true });
|
|
4821
4816
|
}
|
|
4822
4817
|
await rm(this.senderFilePath(persisted.id), { force: true });
|
|
4823
4818
|
}
|
|
@@ -4865,7 +4860,7 @@ var ChatService = class {
|
|
|
4865
4860
|
if (persisted.provider === "claude") {
|
|
4866
4861
|
provider = new ClaudeManager({
|
|
4867
4862
|
workingDirectory: this.workingDirectory,
|
|
4868
|
-
historyFilePath:
|
|
4863
|
+
historyFilePath: join14(CLAUDE_HISTORY_DIR, `${persisted.id}.jsonl`),
|
|
4869
4864
|
initialSessionId: persisted.providerSessionId,
|
|
4870
4865
|
onSaveSessionId: saveSession,
|
|
4871
4866
|
onTurnComplete: onProviderTurnComplete,
|
|
@@ -4874,7 +4869,7 @@ var ChatService = class {
|
|
|
4874
4869
|
} else if (persisted.provider === "relay") {
|
|
4875
4870
|
provider = new RelayManager({
|
|
4876
4871
|
workingDirectory: this.workingDirectory,
|
|
4877
|
-
historyFilePath:
|
|
4872
|
+
historyFilePath: join14(RELAY_HISTORY_DIR, `${persisted.id}.jsonl`),
|
|
4878
4873
|
initialSessionId: persisted.providerSessionId,
|
|
4879
4874
|
onSaveSessionId: saveSession,
|
|
4880
4875
|
onTurnComplete: onProviderTurnComplete,
|
|
@@ -5051,7 +5046,7 @@ var ChatService = class {
|
|
|
5051
5046
|
// src/services/repo-file-service.ts
|
|
5052
5047
|
import { execFile as execFile2 } from "child_process";
|
|
5053
5048
|
import { readFile as readFile9, realpath, stat as stat3 } from "fs/promises";
|
|
5054
|
-
import { join as
|
|
5049
|
+
import { join as join15, resolve, extname } from "path";
|
|
5055
5050
|
var CACHE_TTL_MS = 3e4;
|
|
5056
5051
|
var SEARCH_TIMEOUT_MS = 15e3;
|
|
5057
5052
|
var MAX_CONTENT_BYTES = 256 * 1024;
|
|
@@ -5211,7 +5206,7 @@ var RepoFileService = class {
|
|
|
5211
5206
|
const repo = repos.find((r) => r.name === repoName);
|
|
5212
5207
|
if (!repo) return null;
|
|
5213
5208
|
try {
|
|
5214
|
-
const fullPath = await realpath(resolve(
|
|
5209
|
+
const fullPath = await realpath(resolve(join15(repo.path, filePath)));
|
|
5215
5210
|
const repoRoot = await realpath(repo.path);
|
|
5216
5211
|
const repoPrefix = repoRoot.endsWith("/") ? repoRoot : repoRoot + "/";
|
|
5217
5212
|
if (!fullPath.startsWith(repoPrefix) && fullPath !== repoRoot) return null;
|
|
@@ -5323,15 +5318,15 @@ var RepoFileService = class {
|
|
|
5323
5318
|
import { Hono } from "hono";
|
|
5324
5319
|
import { z as z2 } from "zod";
|
|
5325
5320
|
import { readdir as readdir6, stat as stat4, readFile as readFile13 } from "fs/promises";
|
|
5326
|
-
import { join as
|
|
5321
|
+
import { join as join19, resolve as resolve2 } from "path";
|
|
5327
5322
|
|
|
5328
5323
|
// src/services/plan-service.ts
|
|
5329
5324
|
import { readdir as readdir4, readFile as readFile10 } from "fs/promises";
|
|
5330
|
-
import { homedir as
|
|
5331
|
-
import { basename, join as
|
|
5325
|
+
import { homedir as homedir13 } from "os";
|
|
5326
|
+
import { basename, join as join16 } from "path";
|
|
5332
5327
|
var PLAN_DIRECTORIES = [
|
|
5333
|
-
|
|
5334
|
-
|
|
5328
|
+
join16(homedir13(), ".claude", "plans"),
|
|
5329
|
+
join16(homedir13(), ".replicas", "plans")
|
|
5335
5330
|
];
|
|
5336
5331
|
function isMarkdownFile(filename) {
|
|
5337
5332
|
return filename.toLowerCase().endsWith(".md");
|
|
@@ -5365,7 +5360,7 @@ var PlanService = class {
|
|
|
5365
5360
|
return null;
|
|
5366
5361
|
}
|
|
5367
5362
|
for (const directory of PLAN_DIRECTORIES) {
|
|
5368
|
-
const filePath =
|
|
5363
|
+
const filePath = join16(directory, safeFilename);
|
|
5369
5364
|
try {
|
|
5370
5365
|
const content = await readFile10(filePath, "utf-8");
|
|
5371
5366
|
return { filename: safeFilename, content };
|
|
@@ -5381,13 +5376,14 @@ var planService = new PlanService();
|
|
|
5381
5376
|
import { spawn } from "child_process";
|
|
5382
5377
|
import { readFile as readFile12 } from "fs/promises";
|
|
5383
5378
|
import { existsSync as existsSync8 } from "fs";
|
|
5384
|
-
import { join as
|
|
5379
|
+
import { join as join18 } from "path";
|
|
5385
5380
|
|
|
5386
5381
|
// src/services/warm-hook-logs-service.ts
|
|
5387
5382
|
import { createHash as createHash2 } from "crypto";
|
|
5388
5383
|
import { mkdir as mkdir11, readFile as readFile11, writeFile as writeFile9, readdir as readdir5 } from "fs/promises";
|
|
5389
|
-
import {
|
|
5390
|
-
|
|
5384
|
+
import { homedir as homedir14 } from "os";
|
|
5385
|
+
import { join as join17 } from "path";
|
|
5386
|
+
var LOGS_DIR2 = join17(homedir14(), ".replicas", "warm-hook-logs");
|
|
5391
5387
|
function sanitizeFilename2(name) {
|
|
5392
5388
|
const safe = name.replace(/[^a-zA-Z0-9._-]/g, "_");
|
|
5393
5389
|
const hash = createHash2("sha256").update(name).digest("hex").slice(0, 8);
|
|
@@ -5417,7 +5413,7 @@ var WarmHookLogsService = class {
|
|
|
5417
5413
|
hookName: "organization",
|
|
5418
5414
|
...entry
|
|
5419
5415
|
};
|
|
5420
|
-
await writeFile9(
|
|
5416
|
+
await writeFile9(join17(LOGS_DIR2, globalFilename()), `${JSON.stringify(log, null, 2)}
|
|
5421
5417
|
`, "utf-8");
|
|
5422
5418
|
}
|
|
5423
5419
|
async saveEnvironmentHookLog(entry) {
|
|
@@ -5427,7 +5423,7 @@ var WarmHookLogsService = class {
|
|
|
5427
5423
|
hookName: "environment",
|
|
5428
5424
|
...entry
|
|
5429
5425
|
};
|
|
5430
|
-
await writeFile9(
|
|
5426
|
+
await writeFile9(join17(LOGS_DIR2, environmentFilename()), `${JSON.stringify(log, null, 2)}
|
|
5431
5427
|
`, "utf-8");
|
|
5432
5428
|
}
|
|
5433
5429
|
async saveRepoHookLog(repoName, entry) {
|
|
@@ -5437,7 +5433,7 @@ var WarmHookLogsService = class {
|
|
|
5437
5433
|
hookName: repoName,
|
|
5438
5434
|
...entry
|
|
5439
5435
|
};
|
|
5440
|
-
await writeFile9(
|
|
5436
|
+
await writeFile9(join17(LOGS_DIR2, repoFilename2(repoName)), `${JSON.stringify(log, null, 2)}
|
|
5441
5437
|
`, "utf-8");
|
|
5442
5438
|
}
|
|
5443
5439
|
async getAllLogs() {
|
|
@@ -5456,7 +5452,7 @@ var WarmHookLogsService = class {
|
|
|
5456
5452
|
continue;
|
|
5457
5453
|
}
|
|
5458
5454
|
try {
|
|
5459
|
-
const raw = await readFile11(
|
|
5455
|
+
const raw = await readFile11(join17(LOGS_DIR2, file), "utf-8");
|
|
5460
5456
|
const stored = JSON.parse(raw);
|
|
5461
5457
|
logs.push(withPreview2(stored));
|
|
5462
5458
|
} catch {
|
|
@@ -5474,7 +5470,7 @@ var WarmHookLogsService = class {
|
|
|
5474
5470
|
async getFullOutput(hookType, hookName) {
|
|
5475
5471
|
const filename = hookType === "global" ? globalFilename() : hookType === "environment" ? environmentFilename() : repoFilename2(hookName);
|
|
5476
5472
|
try {
|
|
5477
|
-
const raw = await readFile11(
|
|
5473
|
+
const raw = await readFile11(join17(LOGS_DIR2, filename), "utf-8");
|
|
5478
5474
|
const stored = JSON.parse(raw);
|
|
5479
5475
|
if (stored.hookType !== hookType || stored.hookName !== hookName) {
|
|
5480
5476
|
return null;
|
|
@@ -5493,7 +5489,7 @@ var warmHookLogsService = new WarmHookLogsService();
|
|
|
5493
5489
|
// src/services/warm-hooks-service.ts
|
|
5494
5490
|
async function readRepoWarmHook(repoPath) {
|
|
5495
5491
|
for (const filename of REPLICAS_CONFIG_FILENAMES) {
|
|
5496
|
-
const configPath =
|
|
5492
|
+
const configPath = join18(repoPath, filename);
|
|
5497
5493
|
if (!existsSync8(configPath)) {
|
|
5498
5494
|
continue;
|
|
5499
5495
|
}
|
|
@@ -6297,7 +6293,7 @@ function createV1Routes(deps) {
|
|
|
6297
6293
|
const logFiles = files.filter((f) => f.endsWith(".log"));
|
|
6298
6294
|
const sessions = await Promise.all(
|
|
6299
6295
|
logFiles.map(async (filename) => {
|
|
6300
|
-
const filePath =
|
|
6296
|
+
const filePath = join19(LOG_DIR, filename);
|
|
6301
6297
|
const fileStat = await stat4(filePath);
|
|
6302
6298
|
const sessionId = filename.replace(/\.log$/, "");
|
|
6303
6299
|
return {
|