replicas-engine 0.1.500 → 0.1.501
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 +147 -135
- package/package.json +1 -1
package/dist/src/index.js
CHANGED
|
@@ -611,7 +611,7 @@ var WORKSPACE_SIZES = ["small", "large"];
|
|
|
611
611
|
var INVALID_WORKSPACE_SIZE_ERROR = `Invalid size: must be one of ${WORKSPACE_SIZES.join(", ")}`;
|
|
612
612
|
|
|
613
613
|
// ../shared/src/e2b.ts
|
|
614
|
-
var E2B_TEMPLATE_NAME = "replicas-sandbox-2026-07-25-
|
|
614
|
+
var E2B_TEMPLATE_NAME = "replicas-sandbox-2026-07-25-v3";
|
|
615
615
|
|
|
616
616
|
// ../shared/src/runtime-env.ts
|
|
617
617
|
function shellQuotePosix(value) {
|
|
@@ -4855,7 +4855,6 @@ function loadEngineEnv() {
|
|
|
4855
4855
|
ANTHROPIC_API_KEY: readEnv("ANTHROPIC_API_KEY"),
|
|
4856
4856
|
OPENAI_API_KEY: readEnv("OPENAI_API_KEY"),
|
|
4857
4857
|
CURSOR_API_KEY: readEnv("CURSOR_API_KEY"),
|
|
4858
|
-
OPENROUTER_API_KEY: readEnv("OPENROUTER_API_KEY"),
|
|
4859
4858
|
CLAUDE_CODE_USE_BEDROCK: readEnv("CLAUDE_CODE_USE_BEDROCK"),
|
|
4860
4859
|
AWS_ACCESS_KEY_ID: readEnv("AWS_ACCESS_KEY_ID"),
|
|
4861
4860
|
AWS_SECRET_ACCESS_KEY: readEnv("AWS_SECRET_ACCESS_KEY"),
|
|
@@ -6299,22 +6298,29 @@ var engineLogger = new EngineLogger();
|
|
|
6299
6298
|
// src/services/replicas-config-service.ts
|
|
6300
6299
|
import { readFile as readFile6, appendFile, writeFile as writeFile4, mkdir as mkdir6 } from "fs/promises";
|
|
6301
6300
|
import { existsSync as existsSync3 } from "fs";
|
|
6302
|
-
import { join as
|
|
6303
|
-
import { homedir as
|
|
6301
|
+
import { join as join10 } from "path";
|
|
6302
|
+
import { homedir as homedir8 } from "os";
|
|
6304
6303
|
import { spawn as spawn2 } from "child_process";
|
|
6305
6304
|
|
|
6306
6305
|
// src/services/environment-details-service.ts
|
|
6307
6306
|
import { mkdir as mkdir4, readFile as readFile4 } from "fs/promises";
|
|
6308
6307
|
import { existsSync as existsSync2 } from "fs";
|
|
6308
|
+
import { homedir as homedir6 } from "os";
|
|
6309
|
+
import { join as join8 } from "path";
|
|
6310
|
+
|
|
6311
|
+
// src/managers/agent-auth-paths.ts
|
|
6309
6312
|
import { homedir as homedir5 } from "os";
|
|
6310
6313
|
import { join as join7 } from "path";
|
|
6311
|
-
var REPLICAS_DIR = join7(homedir5(), ".replicas");
|
|
6312
|
-
var DETAILS_FILE = join7(REPLICAS_DIR, "environment-details.json");
|
|
6313
|
-
var CLAUDE_CREDENTIALS_PATH = join7(homedir5(), ".claude", ".credentials.json");
|
|
6314
|
-
var CODEX_AUTH_PATH = join7(homedir5(), ".codex", "auth.json");
|
|
6315
6314
|
var OPENCODE_AUTH_PATH = join7(homedir5(), ".local", "share", "opencode", "auth.json");
|
|
6316
|
-
var
|
|
6317
|
-
|
|
6315
|
+
var PI_AUTH_PATH = join7(homedir5(), ".pi", "agent", "auth.json");
|
|
6316
|
+
|
|
6317
|
+
// src/services/environment-details-service.ts
|
|
6318
|
+
var REPLICAS_DIR = join8(homedir6(), ".replicas");
|
|
6319
|
+
var DETAILS_FILE = join8(REPLICAS_DIR, "environment-details.json");
|
|
6320
|
+
var CLAUDE_CREDENTIALS_PATH = join8(homedir6(), ".claude", ".credentials.json");
|
|
6321
|
+
var CODEX_AUTH_PATH = join8(homedir6(), ".codex", "auth.json");
|
|
6322
|
+
var GH_HOSTS_PATH = join8(homedir6(), ".config", "gh", "hosts.yml");
|
|
6323
|
+
var GIT_CREDENTIALS_PATH = join8(homedir6(), ".git-credentials");
|
|
6318
6324
|
function detectClaudeAuthMethod() {
|
|
6319
6325
|
if (existsSync2(CLAUDE_CREDENTIALS_PATH)) {
|
|
6320
6326
|
return "oauth";
|
|
@@ -6344,10 +6350,10 @@ function detectCursorAuthMethod() {
|
|
|
6344
6350
|
return ENGINE_ENV.CURSOR_API_KEY ? "api_key" : "none";
|
|
6345
6351
|
}
|
|
6346
6352
|
function detectOpencodeAuthMethod() {
|
|
6347
|
-
return existsSync2(OPENCODE_AUTH_PATH)
|
|
6353
|
+
return existsSync2(OPENCODE_AUTH_PATH) ? "api_key" : "none";
|
|
6348
6354
|
}
|
|
6349
6355
|
function detectPiAuthMethod() {
|
|
6350
|
-
return
|
|
6356
|
+
return existsSync2(PI_AUTH_PATH) ? "api_key" : "none";
|
|
6351
6357
|
}
|
|
6352
6358
|
async function detectGitIdentityConfigured() {
|
|
6353
6359
|
try {
|
|
@@ -6520,8 +6526,8 @@ var environmentDetailsService = new EnvironmentDetailsService();
|
|
|
6520
6526
|
|
|
6521
6527
|
// src/services/start-hook-logs-service.ts
|
|
6522
6528
|
import { mkdir as mkdir5, readFile as readFile5, writeFile as writeFile3, readdir as readdir2 } from "fs/promises";
|
|
6523
|
-
import { homedir as
|
|
6524
|
-
import { join as
|
|
6529
|
+
import { homedir as homedir7 } from "os";
|
|
6530
|
+
import { join as join9 } from "path";
|
|
6525
6531
|
|
|
6526
6532
|
// src/services/hook-log-files.ts
|
|
6527
6533
|
import { createHash } from "crypto";
|
|
@@ -6533,7 +6539,7 @@ function repoHookLogFilename(repoName) {
|
|
|
6533
6539
|
}
|
|
6534
6540
|
|
|
6535
6541
|
// src/services/start-hook-logs-service.ts
|
|
6536
|
-
var LOGS_DIR =
|
|
6542
|
+
var LOGS_DIR = join9(homedir7(), ".replicas", "start-hook-logs");
|
|
6537
6543
|
function withPreview(stored) {
|
|
6538
6544
|
const preview = buildHookOutputPreview(stored.output);
|
|
6539
6545
|
return { ...stored, ...preview };
|
|
@@ -6571,7 +6577,7 @@ var StartHookLogsService = class {
|
|
|
6571
6577
|
await this.ensureDir();
|
|
6572
6578
|
const log = { hookType, hookName, repoName: hookName, ...entry };
|
|
6573
6579
|
const filename = hookType === "environment" ? ENVIRONMENT_HOOK_LOG_FILENAME : repoHookLogFilename(hookName);
|
|
6574
|
-
await writeFile3(
|
|
6580
|
+
await writeFile3(join9(LOGS_DIR, filename), `${JSON.stringify(log, null, 2)}
|
|
6575
6581
|
`, "utf-8");
|
|
6576
6582
|
}
|
|
6577
6583
|
async saveEnvironmentLog(entry) {
|
|
@@ -6596,7 +6602,7 @@ var StartHookLogsService = class {
|
|
|
6596
6602
|
continue;
|
|
6597
6603
|
}
|
|
6598
6604
|
try {
|
|
6599
|
-
const raw = await readFile5(
|
|
6605
|
+
const raw = await readFile5(join9(LOGS_DIR, file), "utf-8");
|
|
6600
6606
|
const stored = normalizeStored(JSON.parse(raw));
|
|
6601
6607
|
if (stored) {
|
|
6602
6608
|
logs.push(withPreview(stored));
|
|
@@ -6615,7 +6621,7 @@ var StartHookLogsService = class {
|
|
|
6615
6621
|
async getFullOutput(hookType, hookName) {
|
|
6616
6622
|
const filename = hookType === "environment" ? ENVIRONMENT_HOOK_LOG_FILENAME : repoHookLogFilename(hookName);
|
|
6617
6623
|
try {
|
|
6618
|
-
const raw = await readFile5(
|
|
6624
|
+
const raw = await readFile5(join9(LOGS_DIR, filename), "utf-8");
|
|
6619
6625
|
const stored = normalizeStored(JSON.parse(raw));
|
|
6620
6626
|
if (!stored || stored.hookType !== hookType || stored.hookName !== hookName) {
|
|
6621
6627
|
return null;
|
|
@@ -6632,7 +6638,7 @@ var StartHookLogsService = class {
|
|
|
6632
6638
|
var startHookLogsService = new StartHookLogsService();
|
|
6633
6639
|
|
|
6634
6640
|
// src/services/replicas-config-service.ts
|
|
6635
|
-
var START_HOOKS_LOG =
|
|
6641
|
+
var START_HOOKS_LOG = join10(homedir8(), ".replicas", "startHooks.log");
|
|
6636
6642
|
var START_HOOKS_RUNNING_PROMPT = `IMPORTANT - Start Hooks Running:
|
|
6637
6643
|
Start hooks are shell commands/scripts set by repository owners that run on workspace startup.
|
|
6638
6644
|
These hooks are currently executing in the background. You can:
|
|
@@ -6643,7 +6649,7 @@ The start hooks may install dependencies, build projects, or perform other setup
|
|
|
6643
6649
|
If your task depends on setup being complete, check the log file before proceeding.`;
|
|
6644
6650
|
async function readReplicasConfigFromDir(dirPath) {
|
|
6645
6651
|
for (const filename of REPLICAS_CONFIG_FILENAMES) {
|
|
6646
|
-
const configPath =
|
|
6652
|
+
const configPath = join10(dirPath, filename);
|
|
6647
6653
|
if (!existsSync3(configPath)) {
|
|
6648
6654
|
continue;
|
|
6649
6655
|
}
|
|
@@ -6713,7 +6719,7 @@ var ReplicasConfigService = class {
|
|
|
6713
6719
|
const logLine = `[${timestamp}] ${message}
|
|
6714
6720
|
`;
|
|
6715
6721
|
try {
|
|
6716
|
-
await mkdir6(
|
|
6722
|
+
await mkdir6(join10(homedir8(), ".replicas"), { recursive: true });
|
|
6717
6723
|
await appendFile(START_HOOKS_LOG, logLine, "utf-8");
|
|
6718
6724
|
} catch (error) {
|
|
6719
6725
|
console.error("Failed to write to start hooks log:", error);
|
|
@@ -6725,7 +6731,7 @@ var ReplicasConfigService = class {
|
|
|
6725
6731
|
command: params.content,
|
|
6726
6732
|
label: "env start hook",
|
|
6727
6733
|
repoName: "environment",
|
|
6728
|
-
cwd:
|
|
6734
|
+
cwd: homedir8(),
|
|
6729
6735
|
timeout: params.timeoutMs ?? DEFAULT_START_HOOK_TIMEOUT_MS,
|
|
6730
6736
|
onOutputChunk: params.onOutputChunk
|
|
6731
6737
|
});
|
|
@@ -6848,7 +6854,7 @@ var ReplicasConfigService = class {
|
|
|
6848
6854
|
this.hooksCompleted = false;
|
|
6849
6855
|
this.hooksFailed = false;
|
|
6850
6856
|
try {
|
|
6851
|
-
await mkdir6(
|
|
6857
|
+
await mkdir6(join10(homedir8(), ".replicas"), { recursive: true });
|
|
6852
6858
|
await writeFile4(
|
|
6853
6859
|
START_HOOKS_LOG,
|
|
6854
6860
|
`=== Start Hooks Execution Log ===
|
|
@@ -7043,11 +7049,11 @@ var replicasConfigService = new ReplicasConfigService();
|
|
|
7043
7049
|
|
|
7044
7050
|
// src/services/event-service.ts
|
|
7045
7051
|
import { mkdir as mkdir7 } from "fs/promises";
|
|
7046
|
-
import { homedir as
|
|
7047
|
-
import { join as
|
|
7052
|
+
import { homedir as homedir9 } from "os";
|
|
7053
|
+
import { join as join11 } from "path";
|
|
7048
7054
|
import { randomUUID } from "crypto";
|
|
7049
|
-
var ENGINE_DIR =
|
|
7050
|
-
var EVENTS_FILE =
|
|
7055
|
+
var ENGINE_DIR = join11(homedir9(), ".replicas", "engine");
|
|
7056
|
+
var EVENTS_FILE = join11(ENGINE_DIR, "events.jsonl");
|
|
7051
7057
|
var EventService = class {
|
|
7052
7058
|
subscribers = /* @__PURE__ */ new Map();
|
|
7053
7059
|
writer = new StreamWriter();
|
|
@@ -7081,9 +7087,9 @@ var eventService = new EventService();
|
|
|
7081
7087
|
import { mkdir as mkdir8, readFile as readFile7 } from "fs/promises";
|
|
7082
7088
|
import { existsSync as existsSync4 } from "fs";
|
|
7083
7089
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
7084
|
-
import { homedir as
|
|
7085
|
-
import { dirname as dirname2, join as
|
|
7086
|
-
var PREVIEW_PORTS_FILE =
|
|
7090
|
+
import { homedir as homedir10 } from "os";
|
|
7091
|
+
import { dirname as dirname2, join as join12 } from "path";
|
|
7092
|
+
var PREVIEW_PORTS_FILE = join12(homedir10(), ".replicas", "preview-ports.json");
|
|
7087
7093
|
async function readPreviewsFile() {
|
|
7088
7094
|
try {
|
|
7089
7095
|
if (!existsSync4(PREVIEW_PORTS_FILE)) {
|
|
@@ -7195,8 +7201,8 @@ async function registerDesktopPreview() {
|
|
|
7195
7201
|
// src/services/chat/chat-service.ts
|
|
7196
7202
|
import { existsSync as existsSync7 } from "fs";
|
|
7197
7203
|
import { appendFile as appendFile3, copyFile, mkdir as mkdir14, readFile as readFile14, rename as rename2, rm as rm2 } from "fs/promises";
|
|
7198
|
-
import { homedir as
|
|
7199
|
-
import { join as
|
|
7204
|
+
import { homedir as homedir15 } from "os";
|
|
7205
|
+
import { join as join25 } from "path";
|
|
7200
7206
|
import { randomUUID as randomUUID5 } from "crypto";
|
|
7201
7207
|
|
|
7202
7208
|
// src/managers/claude-manager.ts
|
|
@@ -7204,9 +7210,9 @@ import {
|
|
|
7204
7210
|
query
|
|
7205
7211
|
} from "@anthropic-ai/claude-agent-sdk";
|
|
7206
7212
|
import { randomUUID as randomUUID4 } from "crypto";
|
|
7207
|
-
import { dirname as dirname4, join as
|
|
7213
|
+
import { dirname as dirname4, join as join15 } from "path";
|
|
7208
7214
|
import { mkdir as mkdir10 } from "fs/promises";
|
|
7209
|
-
import { homedir as
|
|
7215
|
+
import { homedir as homedir12 } from "os";
|
|
7210
7216
|
|
|
7211
7217
|
// src/utils/linear-converter.ts
|
|
7212
7218
|
function linearThoughtToResponse(thought) {
|
|
@@ -7592,8 +7598,8 @@ function extractPlanFromCodexAspNotification(notification) {
|
|
|
7592
7598
|
// src/utils/image-utils.ts
|
|
7593
7599
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
7594
7600
|
import { mkdir as mkdir9, unlink as unlink2, writeFile as writeFile5 } from "fs/promises";
|
|
7595
|
-
import { homedir as
|
|
7596
|
-
import { join as
|
|
7601
|
+
import { homedir as homedir11 } from "os";
|
|
7602
|
+
import { join as join13 } from "path";
|
|
7597
7603
|
function isImageMediaType(value) {
|
|
7598
7604
|
return IMAGE_MEDIA_TYPES.includes(value);
|
|
7599
7605
|
}
|
|
@@ -7693,14 +7699,14 @@ async function normalizeImages(images) {
|
|
|
7693
7699
|
}
|
|
7694
7700
|
return normalized;
|
|
7695
7701
|
}
|
|
7696
|
-
async function saveNormalizedImagesToTempFiles(images, tempImageDir =
|
|
7702
|
+
async function saveNormalizedImagesToTempFiles(images, tempImageDir = join13(homedir11(), ".replicas", "codex", "temp-images")) {
|
|
7697
7703
|
await mkdir9(tempImageDir, { recursive: true });
|
|
7698
7704
|
const tempPaths = [];
|
|
7699
7705
|
try {
|
|
7700
7706
|
for (const image of images) {
|
|
7701
7707
|
const ext = image.source.media_type.split("/")[1] || "png";
|
|
7702
7708
|
const filename = `img_${randomUUID3()}.${ext}`;
|
|
7703
|
-
const filepath =
|
|
7709
|
+
const filepath = join13(tempImageDir, filename);
|
|
7704
7710
|
await writeFile5(filepath, Buffer.from(image.source.data, "base64"));
|
|
7705
7711
|
tempPaths.push(filepath);
|
|
7706
7712
|
}
|
|
@@ -8285,7 +8291,7 @@ function reportCommandProtectionBlock(options) {
|
|
|
8285
8291
|
|
|
8286
8292
|
// src/services/skill-registry-service.ts
|
|
8287
8293
|
import { readFile as readFile8, readdir as readdir3, stat as stat2 } from "fs/promises";
|
|
8288
|
-
import { dirname as dirname3, isAbsolute, join as
|
|
8294
|
+
import { dirname as dirname3, isAbsolute, join as join14, relative, resolve } from "path";
|
|
8289
8295
|
var REGISTRY_ROOT_DIR = ".replicas/skill-registries";
|
|
8290
8296
|
var REGISTRY_MANIFEST = "manifest.json";
|
|
8291
8297
|
async function getSkillRegistryInventory(homeDir) {
|
|
@@ -8346,10 +8352,10 @@ async function scanRegistry(registryDir) {
|
|
|
8346
8352
|
}
|
|
8347
8353
|
async function findSkillCollections(registryDir) {
|
|
8348
8354
|
const candidateRoots = [
|
|
8349
|
-
{ source: "skills", root:
|
|
8350
|
-
{ source: "agents", root:
|
|
8351
|
-
{ source: "codex", root:
|
|
8352
|
-
{ source: "claude", root:
|
|
8355
|
+
{ source: "skills", root: join14(registryDir, "skills") },
|
|
8356
|
+
{ source: "agents", root: join14(registryDir, ".agents", "skills") },
|
|
8357
|
+
{ source: "codex", root: join14(registryDir, ".codex", "skills") },
|
|
8358
|
+
{ source: "claude", root: join14(registryDir, ".claude", "skills") }
|
|
8353
8359
|
];
|
|
8354
8360
|
const collections = [];
|
|
8355
8361
|
for (const { source, root } of candidateRoots) {
|
|
@@ -8363,9 +8369,9 @@ async function findSkillCollections(registryDir) {
|
|
|
8363
8369
|
async function findSkillDirsInRoot(root) {
|
|
8364
8370
|
const skillDirs = [];
|
|
8365
8371
|
for (const dirent of await safeReadDir(root)) {
|
|
8366
|
-
const skillDir =
|
|
8372
|
+
const skillDir = join14(root, dirent.name);
|
|
8367
8373
|
if (!await isDirectoryDirent(dirent, skillDir)) continue;
|
|
8368
|
-
if (await fileExists(
|
|
8374
|
+
if (await fileExists(join14(skillDir, "SKILL.md"))) {
|
|
8369
8375
|
skillDirs.push(skillDir);
|
|
8370
8376
|
}
|
|
8371
8377
|
}
|
|
@@ -8375,9 +8381,9 @@ async function findTopLevelSkills(registryDir) {
|
|
|
8375
8381
|
const skills = [];
|
|
8376
8382
|
for (const dirent of await safeReadDir(registryDir)) {
|
|
8377
8383
|
if (dirent.name.startsWith(".") || dirent.name === "skills" || dirent.name === "plugins") continue;
|
|
8378
|
-
const skillDir =
|
|
8384
|
+
const skillDir = join14(registryDir, dirent.name);
|
|
8379
8385
|
if (!await isDirectoryDirent(dirent, skillDir)) continue;
|
|
8380
|
-
if (await fileExists(
|
|
8386
|
+
if (await fileExists(join14(skillDir, "SKILL.md"))) {
|
|
8381
8387
|
skills.push({ source: "root", skillDir });
|
|
8382
8388
|
}
|
|
8383
8389
|
}
|
|
@@ -8388,10 +8394,10 @@ async function findClaudePluginRoots(registryDir) {
|
|
|
8388
8394
|
async function walk(dir) {
|
|
8389
8395
|
for (const dirent of await safeReadDir(dir)) {
|
|
8390
8396
|
if (dirent.name === ".git") continue;
|
|
8391
|
-
const child =
|
|
8397
|
+
const child = join14(dir, dirent.name);
|
|
8392
8398
|
if (!await isDirectoryDirent(dirent, child)) continue;
|
|
8393
8399
|
if (dirent.name === ".claude-plugin") {
|
|
8394
|
-
if (await fileExists(
|
|
8400
|
+
if (await fileExists(join14(child, "plugin.json"))) {
|
|
8395
8401
|
roots.push(dirname3(child));
|
|
8396
8402
|
}
|
|
8397
8403
|
continue;
|
|
@@ -8403,7 +8409,7 @@ async function findClaudePluginRoots(registryDir) {
|
|
|
8403
8409
|
return uniqueStrings(roots);
|
|
8404
8410
|
}
|
|
8405
8411
|
async function hasCodexMarketplace(registryDir) {
|
|
8406
|
-
return await fileExists(
|
|
8412
|
+
return await fileExists(join14(registryDir, ".agents", "plugins", "marketplace.json")) || await fileExists(join14(registryDir, ".codex", "plugins", "marketplace.json"));
|
|
8407
8413
|
}
|
|
8408
8414
|
async function installCodexRegistryPlugins(client, inventory) {
|
|
8409
8415
|
const cwds = inventory.codexMarketplaceCwds;
|
|
@@ -8453,10 +8459,10 @@ function isSkillRegistryEntry(value) {
|
|
|
8453
8459
|
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";
|
|
8454
8460
|
}
|
|
8455
8461
|
function getRegistryRoot(homeDir) {
|
|
8456
|
-
return
|
|
8462
|
+
return join14(homeDir, REGISTRY_ROOT_DIR);
|
|
8457
8463
|
}
|
|
8458
8464
|
function getManifestPath(homeDir) {
|
|
8459
|
-
return
|
|
8465
|
+
return join14(getRegistryRoot(homeDir), REGISTRY_MANIFEST);
|
|
8460
8466
|
}
|
|
8461
8467
|
function emptyInventory(registryRoot) {
|
|
8462
8468
|
return {
|
|
@@ -8803,7 +8809,7 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
|
|
|
8803
8809
|
authRetrying = false;
|
|
8804
8810
|
constructor(options) {
|
|
8805
8811
|
super(options);
|
|
8806
|
-
this.historyFilePath = options.historyFilePath ??
|
|
8812
|
+
this.historyFilePath = options.historyFilePath ?? join15(homedir12(), ".replicas", "claude", "history.jsonl");
|
|
8807
8813
|
this.historyFile = new CodexHistoryFile(this.historyFilePath);
|
|
8808
8814
|
this.systemPromptOverride = options.systemPromptOverride;
|
|
8809
8815
|
this.toolsOverride = options.tools;
|
|
@@ -9735,7 +9741,7 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
|
|
|
9735
9741
|
|
|
9736
9742
|
// src/managers/codex-asp/codex-asp-manager.ts
|
|
9737
9743
|
import { readdir as readdir4 } from "fs/promises";
|
|
9738
|
-
import { join as
|
|
9744
|
+
import { join as join17 } from "path";
|
|
9739
9745
|
|
|
9740
9746
|
// src/managers/codex-asp/app-server-process.ts
|
|
9741
9747
|
import { spawn as spawn3 } from "child_process";
|
|
@@ -9936,7 +9942,7 @@ var DEFAULT_CODEX_ARGS = ["app-server", "--listen", "stdio://"];
|
|
|
9936
9942
|
var MIN_CODEX_CLI_VERSION = "0.144.6";
|
|
9937
9943
|
var CODEX_UPGRADE_TIMEOUT_MS = 12e4;
|
|
9938
9944
|
var codexCliVersionEnsured = null;
|
|
9939
|
-
var ENGINE_PACKAGE_VERSION = "0.1.
|
|
9945
|
+
var ENGINE_PACKAGE_VERSION = "0.1.501";
|
|
9940
9946
|
var INITIALIZE_METHOD = "initialize";
|
|
9941
9947
|
var INITIALIZED_NOTIFICATION = "initialized";
|
|
9942
9948
|
var ACCOUNT_LOGIN_START_METHOD = "account/login/start";
|
|
@@ -10861,16 +10867,16 @@ var TranscriptUpdateCoalescer = class {
|
|
|
10861
10867
|
};
|
|
10862
10868
|
|
|
10863
10869
|
// src/services/chat/history-paths.ts
|
|
10864
|
-
import { homedir as
|
|
10865
|
-
import { join as
|
|
10866
|
-
var ENGINE_DIR2 =
|
|
10867
|
-
var CHATS_FILE =
|
|
10868
|
-
var CLAUDE_HISTORY_DIR =
|
|
10869
|
-
var RELAY_HISTORY_DIR =
|
|
10870
|
-
var CODEX_HISTORY_DIR =
|
|
10871
|
-
var CURSOR_HISTORY_DIR =
|
|
10872
|
-
var OPENCODE_HISTORY_DIR =
|
|
10873
|
-
var PI_HISTORY_DIR =
|
|
10870
|
+
import { homedir as homedir13 } from "os";
|
|
10871
|
+
import { join as join16 } from "path";
|
|
10872
|
+
var ENGINE_DIR2 = join16(homedir13(), ".replicas", "engine");
|
|
10873
|
+
var CHATS_FILE = join16(ENGINE_DIR2, "chats.json");
|
|
10874
|
+
var CLAUDE_HISTORY_DIR = join16(ENGINE_DIR2, "claude-histories");
|
|
10875
|
+
var RELAY_HISTORY_DIR = join16(ENGINE_DIR2, "relay-histories");
|
|
10876
|
+
var CODEX_HISTORY_DIR = join16(ENGINE_DIR2, "codex-histories");
|
|
10877
|
+
var CURSOR_HISTORY_DIR = join16(ENGINE_DIR2, "cursor-histories");
|
|
10878
|
+
var OPENCODE_HISTORY_DIR = join16(ENGINE_DIR2, "opencode-histories");
|
|
10879
|
+
var PI_HISTORY_DIR = join16(ENGINE_DIR2, "pi-histories");
|
|
10874
10880
|
var HISTORY_DIR_BY_PROVIDER = {
|
|
10875
10881
|
claude: CLAUDE_HISTORY_DIR,
|
|
10876
10882
|
relay: RELAY_HISTORY_DIR,
|
|
@@ -10916,7 +10922,7 @@ async function readCodexAspThreadHistory(threadId) {
|
|
|
10916
10922
|
}
|
|
10917
10923
|
for (const entry of entries) {
|
|
10918
10924
|
if (!entry.isFile() || !entry.name.endsWith(".jsonl")) continue;
|
|
10919
|
-
const history = await new CodexHistoryFile(
|
|
10925
|
+
const history = await new CodexHistoryFile(join17(CODEX_HISTORY_DIR, entry.name)).load();
|
|
10920
10926
|
const transcript = history.transcriptsByThreadId.get(threadId);
|
|
10921
10927
|
if (transcript) {
|
|
10922
10928
|
return {
|
|
@@ -12133,7 +12139,7 @@ var CodexAspManager = class extends CodingAgentManager {
|
|
|
12133
12139
|
|
|
12134
12140
|
// src/managers/cursor-manager.ts
|
|
12135
12141
|
import { mkdir as mkdir11, readFile as readFile10, readdir as readdir5 } from "fs/promises";
|
|
12136
|
-
import { basename, dirname as dirname5, extname, join as
|
|
12142
|
+
import { basename, dirname as dirname5, extname, join as join18 } from "path";
|
|
12137
12143
|
import { parse as parseYaml2 } from "yaml";
|
|
12138
12144
|
import { Agent as CursorAgent } from "@cursor/sdk";
|
|
12139
12145
|
var CURSOR_SLASH_COMMANDS_CACHE_MS = 3e4;
|
|
@@ -12192,7 +12198,7 @@ async function listCursorCommandsInDirectory(directory) {
|
|
|
12192
12198
|
const name = basename(entry.name, ".md");
|
|
12193
12199
|
let description;
|
|
12194
12200
|
try {
|
|
12195
|
-
description = extractCursorCommandDescription(await readFile10(
|
|
12201
|
+
description = extractCursorCommandDescription(await readFile10(join18(directory, entry.name), "utf8"));
|
|
12196
12202
|
} catch (error) {
|
|
12197
12203
|
console.warn("[CursorManager] Failed to read slash command file:", error);
|
|
12198
12204
|
}
|
|
@@ -12214,7 +12220,7 @@ var CursorManager = class extends CodingAgentManager {
|
|
|
12214
12220
|
slashCommandsRequest = null;
|
|
12215
12221
|
constructor(options) {
|
|
12216
12222
|
super(options);
|
|
12217
|
-
this.historyFilePath = options.historyFilePath ??
|
|
12223
|
+
this.historyFilePath = options.historyFilePath ?? join18(ENGINE_ENV.HOME_DIR, ".replicas", "cursor", "history.jsonl");
|
|
12218
12224
|
this.historyFile = new CodexHistoryFile(this.historyFilePath);
|
|
12219
12225
|
this.initializeManager(this.processMessageInternal.bind(this));
|
|
12220
12226
|
}
|
|
@@ -12265,7 +12271,7 @@ var CursorManager = class extends CodingAgentManager {
|
|
|
12265
12271
|
this.slashCommandsRequest ??= (async () => {
|
|
12266
12272
|
try {
|
|
12267
12273
|
const repoDirectories = await getAgentAdditionalDirectories();
|
|
12268
|
-
const commandDirectories = [this.workingDirectory, ...repoDirectories, ENGINE_ENV.HOME_DIR].map((directory) =>
|
|
12274
|
+
const commandDirectories = [this.workingDirectory, ...repoDirectories, ENGINE_ENV.HOME_DIR].map((directory) => join18(directory, ".cursor", "commands"));
|
|
12269
12275
|
const commands = mergeSlashCommands(
|
|
12270
12276
|
...await Promise.all(commandDirectories.map(listCursorCommandsInDirectory))
|
|
12271
12277
|
);
|
|
@@ -12514,7 +12520,7 @@ ${request.message}` : request.message;
|
|
|
12514
12520
|
// src/managers/opencode-manager.ts
|
|
12515
12521
|
import { existsSync as existsSync6 } from "fs";
|
|
12516
12522
|
import { mkdir as mkdir12, readFile as readFile11 } from "fs/promises";
|
|
12517
|
-
import { delimiter, dirname as dirname6, join as
|
|
12523
|
+
import { delimiter, dirname as dirname6, join as join19 } from "path";
|
|
12518
12524
|
import { randomBytes as randomBytes2 } from "crypto";
|
|
12519
12525
|
import { fileURLToPath } from "url";
|
|
12520
12526
|
import { Agent } from "undici";
|
|
@@ -12524,8 +12530,7 @@ import {
|
|
|
12524
12530
|
createOpencodeServer
|
|
12525
12531
|
} from "@opencode-ai/sdk/v2";
|
|
12526
12532
|
var OPENCODE_SHIM_DIR = dirname6(fileURLToPath(new URL("../../scripts/opencode", import.meta.url)));
|
|
12527
|
-
var OPENCODE_CONFIG_PATH =
|
|
12528
|
-
var OPENCODE_AUTH_PATH2 = join18(ENGINE_ENV.HOME_DIR, ".local", "share", "opencode", "auth.json");
|
|
12533
|
+
var OPENCODE_CONFIG_PATH = join19(ENGINE_ENV.HOME_DIR, ".config", "opencode", "opencode.json");
|
|
12529
12534
|
var OPENCODE_FETCH_DISPATCHER = new Agent({ headersTimeout: 0, bodyTimeout: 0 });
|
|
12530
12535
|
var OPENCODE_SERVER_STARTUP_TIMEOUT_MS = 3e4;
|
|
12531
12536
|
var OPENCODE_WORKSPACE_PERMISSION = {
|
|
@@ -12559,11 +12564,11 @@ var opencodeAuthSchema = z5.record(z5.string(), z5.object({
|
|
|
12559
12564
|
type: z5.string().optional(),
|
|
12560
12565
|
key: z5.string().optional()
|
|
12561
12566
|
}));
|
|
12562
|
-
async function
|
|
12563
|
-
if (!existsSync6(
|
|
12567
|
+
async function hasOpencodeCredentials(provider) {
|
|
12568
|
+
if (!existsSync6(OPENCODE_AUTH_PATH)) return false;
|
|
12564
12569
|
try {
|
|
12565
|
-
const auth = opencodeAuthSchema.safeParse(JSON.parse(await readFile11(
|
|
12566
|
-
return auth.success && auth.data[
|
|
12570
|
+
const auth = opencodeAuthSchema.safeParse(JSON.parse(await readFile11(OPENCODE_AUTH_PATH, "utf8")));
|
|
12571
|
+
return auth.success && auth.data[provider]?.type === "api" && Boolean(auth.data[provider]?.key);
|
|
12567
12572
|
} catch {
|
|
12568
12573
|
return false;
|
|
12569
12574
|
}
|
|
@@ -12573,7 +12578,7 @@ function getOpenCodeGoModel(model) {
|
|
|
12573
12578
|
}
|
|
12574
12579
|
async function opencodeConfig(model) {
|
|
12575
12580
|
let config;
|
|
12576
|
-
if (await
|
|
12581
|
+
if (await hasOpencodeCredentials(OPENCODE_GO_PROVIDER)) {
|
|
12577
12582
|
config = {
|
|
12578
12583
|
enabled_providers: [OPENCODE_GO_PROVIDER],
|
|
12579
12584
|
model: `${OPENCODE_GO_PROVIDER}/${model}`,
|
|
@@ -12587,10 +12592,7 @@ async function opencodeConfig(model) {
|
|
|
12587
12592
|
model: `openrouter/${model}`,
|
|
12588
12593
|
provider: {
|
|
12589
12594
|
openrouter: {
|
|
12590
|
-
models: Object.fromEntries(models.map((candidate) => [candidate, {}]))
|
|
12591
|
-
options: {
|
|
12592
|
-
apiKey: "{env:OPENROUTER_API_KEY}"
|
|
12593
|
-
}
|
|
12595
|
+
models: Object.fromEntries(models.map((candidate) => [candidate, {}]))
|
|
12594
12596
|
}
|
|
12595
12597
|
},
|
|
12596
12598
|
permission: OPENCODE_WORKSPACE_PERMISSION,
|
|
@@ -12754,7 +12756,7 @@ var OpencodeManager = class extends CodingAgentManager {
|
|
|
12754
12756
|
constructor(options) {
|
|
12755
12757
|
super(options);
|
|
12756
12758
|
this.sessionId = options.initialSessionId;
|
|
12757
|
-
this.historyFilePath = options.historyFilePath ??
|
|
12759
|
+
this.historyFilePath = options.historyFilePath ?? join19(ENGINE_ENV.HOME_DIR, ".replicas", "opencode", "history.jsonl");
|
|
12758
12760
|
this.historyFile = new CodexHistoryFile(this.historyFilePath);
|
|
12759
12761
|
this.initializeManager(this.processMessageInternal.bind(this));
|
|
12760
12762
|
}
|
|
@@ -12825,7 +12827,7 @@ var OpencodeManager = class extends CodingAgentManager {
|
|
|
12825
12827
|
return this.slashCommandsRequest;
|
|
12826
12828
|
}
|
|
12827
12829
|
async ensureClient(model) {
|
|
12828
|
-
const providerId = await
|
|
12830
|
+
const providerId = await hasOpencodeCredentials(OPENCODE_GO_PROVIDER) ? OPENCODE_GO_PROVIDER : "openrouter";
|
|
12829
12831
|
if (this.client && this.providerId !== providerId) {
|
|
12830
12832
|
this.eventAbortController?.abort();
|
|
12831
12833
|
this.server?.close();
|
|
@@ -12838,7 +12840,7 @@ var OpencodeManager = class extends CodingAgentManager {
|
|
|
12838
12840
|
if (this.client && (providerId === OPENCODE_GO_PROVIDER || this.configuredModels.has(configuredModel))) {
|
|
12839
12841
|
return this.client;
|
|
12840
12842
|
}
|
|
12841
|
-
if (
|
|
12843
|
+
if (this.providerId !== OPENCODE_GO_PROVIDER && !await hasOpencodeCredentials("openrouter")) {
|
|
12842
12844
|
throw new Error("OpenCode Go or OpenRouter credentials are not configured for Opencode in this workspace.");
|
|
12843
12845
|
}
|
|
12844
12846
|
this.eventAbortController?.abort();
|
|
@@ -13245,7 +13247,7 @@ var OpencodeManager = class extends CodingAgentManager {
|
|
|
13245
13247
|
|
|
13246
13248
|
// src/managers/pi-manager.ts
|
|
13247
13249
|
import { mkdir as mkdir13 } from "fs/promises";
|
|
13248
|
-
import { dirname as dirname7, join as
|
|
13250
|
+
import { dirname as dirname7, join as join20 } from "path";
|
|
13249
13251
|
import {
|
|
13250
13252
|
AuthStorage,
|
|
13251
13253
|
createAgentSession,
|
|
@@ -13285,7 +13287,7 @@ var PiManager = class extends CodingAgentManager {
|
|
|
13285
13287
|
historyFile;
|
|
13286
13288
|
constructor(options) {
|
|
13287
13289
|
super(options);
|
|
13288
|
-
this.historyFilePath = options.historyFilePath ??
|
|
13290
|
+
this.historyFilePath = options.historyFilePath ?? join20(PI_HISTORY_DIR, `${Date.now()}.jsonl`);
|
|
13289
13291
|
this.historyFile = new CodexHistoryFile(this.historyFilePath);
|
|
13290
13292
|
this.initializeManager(this.processMessageInternal.bind(this));
|
|
13291
13293
|
}
|
|
@@ -13312,6 +13314,13 @@ var PiManager = class extends CodingAgentManager {
|
|
|
13312
13314
|
await this.initialized;
|
|
13313
13315
|
return mergeSlashCommands(...(this.session?.promptTemplates ?? []).map((template) => createProviderSlashCommand("pi", template.name, template.description)).filter((command) => Boolean(command)));
|
|
13314
13316
|
}
|
|
13317
|
+
async enqueueMessage(request) {
|
|
13318
|
+
await this.initialized;
|
|
13319
|
+
if (!this.session && !await this.getOpenRouterApiKey()) {
|
|
13320
|
+
throw new Error("OpenRouter authentication is missing for Pi. Add an OpenRouter API key in Settings \u2192 Coding agents.");
|
|
13321
|
+
}
|
|
13322
|
+
return this.messageQueue.enqueue(request);
|
|
13323
|
+
}
|
|
13315
13324
|
dispose() {
|
|
13316
13325
|
this.unsubscribe?.();
|
|
13317
13326
|
this.unsubscribe = null;
|
|
@@ -13329,9 +13338,9 @@ var PiManager = class extends CodingAgentManager {
|
|
|
13329
13338
|
}
|
|
13330
13339
|
return this.session;
|
|
13331
13340
|
}
|
|
13332
|
-
const
|
|
13341
|
+
const authStorage = AuthStorage.create(PI_AUTH_PATH);
|
|
13342
|
+
const apiKey = await this.getOpenRouterApiKey(authStorage);
|
|
13333
13343
|
if (!apiKey) throw new Error("OpenRouter API key is not configured for Pi.");
|
|
13334
|
-
const authStorage = AuthStorage.inMemory({ openrouter: { type: "api_key", key: apiKey } });
|
|
13335
13344
|
const modelRegistry = ModelRegistry.create(authStorage);
|
|
13336
13345
|
const openRouterModels = modelRegistry.getAll().filter((candidate) => candidate.provider === "openrouter");
|
|
13337
13346
|
const modelTemplate = openRouterModels[0];
|
|
@@ -13361,7 +13370,7 @@ var PiManager = class extends CodingAgentManager {
|
|
|
13361
13370
|
const sessionManager = this.initialSessionId ? SessionManager.open(this.initialSessionId, PI_HISTORY_DIR, this.workingDirectory) : SessionManager.create(this.workingDirectory, PI_HISTORY_DIR);
|
|
13362
13371
|
const resourceLoader = new DefaultResourceLoader({
|
|
13363
13372
|
cwd: this.workingDirectory,
|
|
13364
|
-
agentDir:
|
|
13373
|
+
agentDir: join20(ENGINE_ENV.HOME_DIR, ".pi", "agent"),
|
|
13365
13374
|
extensionFactories: [registerCommandProtection(this.workingDirectory)],
|
|
13366
13375
|
appendSystemPrompt: [this.buildCombinedInstructions() ?? ""]
|
|
13367
13376
|
});
|
|
@@ -13383,6 +13392,10 @@ var PiManager = class extends CodingAgentManager {
|
|
|
13383
13392
|
this.unsubscribe = this.session.subscribe((event) => this.handleEvent(event));
|
|
13384
13393
|
return this.session;
|
|
13385
13394
|
}
|
|
13395
|
+
async getOpenRouterApiKey(authStorage = AuthStorage.create(PI_AUTH_PATH)) {
|
|
13396
|
+
const credential = authStorage.get("openrouter");
|
|
13397
|
+
return credential?.type === "api_key" ? credential.key : void 0;
|
|
13398
|
+
}
|
|
13386
13399
|
handleEvent(event) {
|
|
13387
13400
|
const payload = eventPayload(event);
|
|
13388
13401
|
this.recordHistoryEvent(`pi-${event.type}`, payload, this.historyFile);
|
|
@@ -14066,18 +14079,18 @@ var keepAliveService = new KeepAliveService();
|
|
|
14066
14079
|
|
|
14067
14080
|
// src/services/canvas-service.ts
|
|
14068
14081
|
import { readdir as readdir6, readFile as readFile12, stat as stat3 } from "fs/promises";
|
|
14069
|
-
import { homedir as
|
|
14070
|
-
import { join as
|
|
14082
|
+
import { homedir as homedir14 } from "os";
|
|
14083
|
+
import { join as join21 } from "path";
|
|
14071
14084
|
var GLOBAL_CANVAS_DIRECTORIES = [
|
|
14072
|
-
|
|
14073
|
-
|
|
14074
|
-
|
|
14085
|
+
join21(homedir14(), ".claude", "plans"),
|
|
14086
|
+
join21(process.env.XDG_DATA_HOME ?? join21(homedir14(), ".local", "share"), "opencode", "plans"),
|
|
14087
|
+
join21(homedir14(), ".replicas", "canvas")
|
|
14075
14088
|
];
|
|
14076
14089
|
async function canvasDirectories() {
|
|
14077
14090
|
const repositories = await gitService.listRepositories().catch(() => []);
|
|
14078
14091
|
return [
|
|
14079
14092
|
...GLOBAL_CANVAS_DIRECTORIES,
|
|
14080
|
-
...repositories.map((repository) =>
|
|
14093
|
+
...repositories.map((repository) => join21(repository.path, ".opencode", "plans"))
|
|
14081
14094
|
];
|
|
14082
14095
|
}
|
|
14083
14096
|
var CanvasService = class {
|
|
@@ -14097,7 +14110,7 @@ var CanvasService = class {
|
|
|
14097
14110
|
const { kind } = classifyCanvasFilename(entry.name);
|
|
14098
14111
|
let sizeBytes = 0;
|
|
14099
14112
|
try {
|
|
14100
|
-
const s = await stat3(
|
|
14113
|
+
const s = await stat3(join21(directory, entry.name));
|
|
14101
14114
|
sizeBytes = s.size;
|
|
14102
14115
|
} catch {
|
|
14103
14116
|
continue;
|
|
@@ -14112,7 +14125,7 @@ var CanvasService = class {
|
|
|
14112
14125
|
if (!safe) return null;
|
|
14113
14126
|
const { kind, mimeType } = classifyCanvasFilename(safe);
|
|
14114
14127
|
for (const directory of await canvasDirectories()) {
|
|
14115
|
-
const filePath =
|
|
14128
|
+
const filePath = join21(directory, safe);
|
|
14116
14129
|
let sizeBytes = 0;
|
|
14117
14130
|
let updatedAt = "";
|
|
14118
14131
|
try {
|
|
@@ -14249,13 +14262,13 @@ async function reconcileCanvasItems(filenames) {
|
|
|
14249
14262
|
|
|
14250
14263
|
// src/services/upload-chat-transcripts.ts
|
|
14251
14264
|
import { readdir as readdir7, readFile as readFile13 } from "fs/promises";
|
|
14252
|
-
import { basename as basename2, join as
|
|
14265
|
+
import { basename as basename2, join as join23 } from "path";
|
|
14253
14266
|
|
|
14254
14267
|
// src/services/chat/chat-senders.ts
|
|
14255
|
-
import { join as
|
|
14256
|
-
var CHAT_SENDERS_DIR =
|
|
14268
|
+
import { join as join22 } from "path";
|
|
14269
|
+
var CHAT_SENDERS_DIR = join22(ENGINE_DIR2, "chat-senders");
|
|
14257
14270
|
function chatMessageSendersFilePath(chatId) {
|
|
14258
|
-
return
|
|
14271
|
+
return join22(CHAT_SENDERS_DIR, `${chatId}.jsonl`);
|
|
14259
14272
|
}
|
|
14260
14273
|
function parseChatMessageSendersJsonl(content) {
|
|
14261
14274
|
return content.split("\n").flatMap((line) => {
|
|
@@ -14271,9 +14284,9 @@ function parseChatMessageSendersJsonl(content) {
|
|
|
14271
14284
|
|
|
14272
14285
|
// src/services/upload-chat-transcripts.ts
|
|
14273
14286
|
var HISTORY_DIRS = [
|
|
14274
|
-
|
|
14275
|
-
|
|
14276
|
-
|
|
14287
|
+
join23(ENGINE_DIR2, "claude-histories"),
|
|
14288
|
+
join23(ENGINE_DIR2, "relay-histories"),
|
|
14289
|
+
join23(ENGINE_DIR2, "codex-histories")
|
|
14277
14290
|
];
|
|
14278
14291
|
async function flushAllChatTranscripts(chatsById = /* @__PURE__ */ new Map()) {
|
|
14279
14292
|
let flushed = 0;
|
|
@@ -14290,7 +14303,7 @@ async function flushAllChatTranscripts(chatsById = /* @__PURE__ */ new Map()) {
|
|
|
14290
14303
|
if (!entry.endsWith(".jsonl")) continue;
|
|
14291
14304
|
const chatId = basename2(entry, ".jsonl");
|
|
14292
14305
|
tasks.push(
|
|
14293
|
-
uploadChatTranscript(chatId,
|
|
14306
|
+
uploadChatTranscript(chatId, join23(dir, entry), chatsById.get(chatId)).then(() => {
|
|
14294
14307
|
flushed++;
|
|
14295
14308
|
}).catch((err) => {
|
|
14296
14309
|
failed++;
|
|
@@ -14380,7 +14393,7 @@ async function flushRepoState() {
|
|
|
14380
14393
|
// src/services/upload-engine-logs.ts
|
|
14381
14394
|
import { createReadStream } from "fs";
|
|
14382
14395
|
import { readdir as readdir8, stat as stat4 } from "fs/promises";
|
|
14383
|
-
import { join as
|
|
14396
|
+
import { join as join24 } from "path";
|
|
14384
14397
|
var MAX_ENGINE_LOG_FLUSH_SESSIONS = 10;
|
|
14385
14398
|
var MAX_ENGINE_LOG_FLUSH_BYTES = 5 * 1024 * 1024;
|
|
14386
14399
|
var ENGINE_LOG_FLUSH_TIMEOUT_MS = 2e4;
|
|
@@ -14409,7 +14422,7 @@ async function flushAllEngineLogs() {
|
|
|
14409
14422
|
const candidates = (await Promise.all(filenames.slice(0, MAX_ENGINE_LOG_FLUSH_SESSIONS).map(async (filename) => {
|
|
14410
14423
|
try {
|
|
14411
14424
|
const sessionId = filename.slice(0, -".log".length);
|
|
14412
|
-
const filePath =
|
|
14425
|
+
const filePath = join24(LOG_DIR, filename);
|
|
14413
14426
|
const fileStat = await runBeforeDeadline(() => stat4(filePath), deadline);
|
|
14414
14427
|
if (!fileStat.isFile()) {
|
|
14415
14428
|
skipped++;
|
|
@@ -14505,17 +14518,16 @@ async function uploadEngineLog(input, timeoutMs) {
|
|
|
14505
14518
|
}
|
|
14506
14519
|
|
|
14507
14520
|
// src/services/chat/chat-service.ts
|
|
14508
|
-
var CODEX_AUTH_PATH2 =
|
|
14509
|
-
var OPENCODE_AUTH_PATH3 = join24(homedir14(), ".local", "share", "opencode", "auth.json");
|
|
14521
|
+
var CODEX_AUTH_PATH2 = join25(homedir15(), ".codex", "auth.json");
|
|
14510
14522
|
var CHATS_BACKUP_FILE = `${CHATS_FILE}.bak`;
|
|
14511
14523
|
function isCodexAvailable() {
|
|
14512
14524
|
return existsSync7(CODEX_AUTH_PATH2) || Boolean(ENGINE_ENV.OPENAI_API_KEY);
|
|
14513
14525
|
}
|
|
14514
14526
|
function isOpencodeAvailable() {
|
|
14515
|
-
return existsSync7(
|
|
14527
|
+
return existsSync7(OPENCODE_AUTH_PATH);
|
|
14516
14528
|
}
|
|
14517
14529
|
function isPiAvailable() {
|
|
14518
|
-
return
|
|
14530
|
+
return existsSync7(PI_AUTH_PATH);
|
|
14519
14531
|
}
|
|
14520
14532
|
function isCursorAvailable() {
|
|
14521
14533
|
return Boolean(ENGINE_ENV.CURSOR_API_KEY);
|
|
@@ -14972,7 +14984,7 @@ var ChatService = class {
|
|
|
14972
14984
|
return descendants;
|
|
14973
14985
|
}
|
|
14974
14986
|
async deleteHistoryFile(persisted) {
|
|
14975
|
-
await rm2(
|
|
14987
|
+
await rm2(join25(HISTORY_DIR_BY_PROVIDER[persisted.provider], `${persisted.id}.jsonl`), { force: true });
|
|
14976
14988
|
await rm2(chatMessageSendersFilePath(persisted.id), { force: true });
|
|
14977
14989
|
}
|
|
14978
14990
|
async getChatHistory(chatId, page = {}) {
|
|
@@ -15048,7 +15060,7 @@ var ChatService = class {
|
|
|
15048
15060
|
if (persisted.provider === "claude") {
|
|
15049
15061
|
provider = new ClaudeManager({
|
|
15050
15062
|
workingDirectory: this.workingDirectory,
|
|
15051
|
-
historyFilePath:
|
|
15063
|
+
historyFilePath: join25(CLAUDE_HISTORY_DIR, `${persisted.id}.jsonl`),
|
|
15052
15064
|
initialSessionId: persisted.providerSessionId,
|
|
15053
15065
|
onSaveSessionId: saveSession,
|
|
15054
15066
|
onTurnComplete: onProviderTurnComplete,
|
|
@@ -15057,7 +15069,7 @@ var ChatService = class {
|
|
|
15057
15069
|
} else if (persisted.provider === "relay") {
|
|
15058
15070
|
provider = new RelayManager({
|
|
15059
15071
|
workingDirectory: this.workingDirectory,
|
|
15060
|
-
historyFilePath:
|
|
15072
|
+
historyFilePath: join25(RELAY_HISTORY_DIR, `${persisted.id}.jsonl`),
|
|
15061
15073
|
initialSessionId: persisted.providerSessionId,
|
|
15062
15074
|
onSaveSessionId: saveSession,
|
|
15063
15075
|
onTurnComplete: onProviderTurnComplete,
|
|
@@ -15071,7 +15083,7 @@ var ChatService = class {
|
|
|
15071
15083
|
} else if (persisted.provider === "cursor") {
|
|
15072
15084
|
provider = new CursorManager({
|
|
15073
15085
|
workingDirectory: this.workingDirectory,
|
|
15074
|
-
historyFilePath:
|
|
15086
|
+
historyFilePath: join25(CURSOR_HISTORY_DIR, `${persisted.id}.jsonl`),
|
|
15075
15087
|
initialSessionId: persisted.providerSessionId,
|
|
15076
15088
|
onSaveSessionId: saveSession,
|
|
15077
15089
|
onTurnComplete: onProviderTurnComplete,
|
|
@@ -15080,7 +15092,7 @@ var ChatService = class {
|
|
|
15080
15092
|
} else if (persisted.provider === "opencode") {
|
|
15081
15093
|
provider = new OpencodeManager({
|
|
15082
15094
|
workingDirectory: this.workingDirectory,
|
|
15083
|
-
historyFilePath:
|
|
15095
|
+
historyFilePath: join25(OPENCODE_HISTORY_DIR, `${persisted.id}.jsonl`),
|
|
15084
15096
|
initialSessionId: persisted.providerSessionId,
|
|
15085
15097
|
onSaveSessionId: saveSession,
|
|
15086
15098
|
onTurnComplete: onProviderTurnComplete,
|
|
@@ -15089,7 +15101,7 @@ var ChatService = class {
|
|
|
15089
15101
|
} else if (persisted.provider === "pi") {
|
|
15090
15102
|
provider = new PiManager({
|
|
15091
15103
|
workingDirectory: this.workingDirectory,
|
|
15092
|
-
historyFilePath:
|
|
15104
|
+
historyFilePath: join25(PI_HISTORY_DIR, `${persisted.id}.jsonl`),
|
|
15093
15105
|
initialSessionId: persisted.providerSessionId,
|
|
15094
15106
|
onSaveSessionId: saveSession,
|
|
15095
15107
|
onTurnComplete: onProviderTurnComplete,
|
|
@@ -15098,7 +15110,7 @@ var ChatService = class {
|
|
|
15098
15110
|
} else {
|
|
15099
15111
|
provider = new CodexAspManager({
|
|
15100
15112
|
workingDirectory: this.workingDirectory,
|
|
15101
|
-
historyFilePath:
|
|
15113
|
+
historyFilePath: join25(CODEX_HISTORY_DIR, `${persisted.id}.jsonl`),
|
|
15102
15114
|
initialSessionId: persisted.providerSessionId,
|
|
15103
15115
|
onSaveSessionId: saveSession,
|
|
15104
15116
|
onTurnComplete: onProviderTurnComplete,
|
|
@@ -15247,7 +15259,7 @@ var ChatService = class {
|
|
|
15247
15259
|
});
|
|
15248
15260
|
uploadChatTranscript(
|
|
15249
15261
|
chatId,
|
|
15250
|
-
|
|
15262
|
+
join25(HISTORY_DIR_BY_PROVIDER[chat.persisted.provider], `${chatId}.jsonl`),
|
|
15251
15263
|
this.toSummary(chat)
|
|
15252
15264
|
).catch((err) => {
|
|
15253
15265
|
console.error("[ChatService] Failed to upload chat transcript:", { chatId, err });
|
|
@@ -15383,7 +15395,7 @@ var ChatService = class {
|
|
|
15383
15395
|
// src/services/repo-file-service.ts
|
|
15384
15396
|
import { execFile as execFile2 } from "child_process";
|
|
15385
15397
|
import { readFile as readFile15, realpath, stat as stat5 } from "fs/promises";
|
|
15386
|
-
import { join as
|
|
15398
|
+
import { join as join26, resolve as resolve2, extname as extname2 } from "path";
|
|
15387
15399
|
var CACHE_TTL_MS = 3e4;
|
|
15388
15400
|
var SEARCH_TIMEOUT_MS = 15e3;
|
|
15389
15401
|
var MAX_CONTENT_BYTES = 256 * 1024;
|
|
@@ -15543,7 +15555,7 @@ var RepoFileService = class {
|
|
|
15543
15555
|
const repo = repos.find((r) => r.name === repoName);
|
|
15544
15556
|
if (!repo) return null;
|
|
15545
15557
|
try {
|
|
15546
|
-
const fullPath = await realpath(resolve2(
|
|
15558
|
+
const fullPath = await realpath(resolve2(join26(repo.path, filePath)));
|
|
15547
15559
|
const repoRoot = await realpath(repo.path);
|
|
15548
15560
|
const repoPrefix = repoRoot.endsWith("/") ? repoRoot : repoRoot + "/";
|
|
15549
15561
|
if (!fullPath.startsWith(repoPrefix) && fullPath !== repoRoot) return null;
|
|
@@ -15651,20 +15663,20 @@ var RepoFileService = class {
|
|
|
15651
15663
|
import { Hono } from "hono";
|
|
15652
15664
|
import { z as z7 } from "zod";
|
|
15653
15665
|
import { readdir as readdir10, stat as stat6, readFile as readFile18 } from "fs/promises";
|
|
15654
|
-
import { join as
|
|
15666
|
+
import { join as join29, resolve as resolve3 } from "path";
|
|
15655
15667
|
|
|
15656
15668
|
// src/services/warm-hooks-service.ts
|
|
15657
15669
|
import { spawn as spawn4 } from "child_process";
|
|
15658
15670
|
import { readFile as readFile17 } from "fs/promises";
|
|
15659
15671
|
import { existsSync as existsSync8 } from "fs";
|
|
15660
|
-
import { join as
|
|
15672
|
+
import { join as join28 } from "path";
|
|
15661
15673
|
|
|
15662
15674
|
// src/services/warm-hook-logs-service.ts
|
|
15663
15675
|
import { mkdir as mkdir15, readFile as readFile16, writeFile as writeFile6, readdir as readdir9, appendFile as appendFile4, unlink as unlink3 } from "fs/promises";
|
|
15664
|
-
import { homedir as
|
|
15665
|
-
import { join as
|
|
15666
|
-
var LOGS_DIR2 =
|
|
15667
|
-
var CURRENT_RUN_LOG =
|
|
15676
|
+
import { homedir as homedir16 } from "os";
|
|
15677
|
+
import { join as join27 } from "path";
|
|
15678
|
+
var LOGS_DIR2 = join27(homedir16(), ".replicas", "warm-hook-logs");
|
|
15679
|
+
var CURRENT_RUN_LOG = join27(LOGS_DIR2, "current-run.log");
|
|
15668
15680
|
var GLOBAL_FILENAME = "global.json";
|
|
15669
15681
|
function withPreview2(stored) {
|
|
15670
15682
|
const preview = buildHookOutputPreview(stored.output);
|
|
@@ -15681,7 +15693,7 @@ var WarmHookLogsService = class {
|
|
|
15681
15693
|
hookName: "organization",
|
|
15682
15694
|
...entry
|
|
15683
15695
|
};
|
|
15684
|
-
await writeFile6(
|
|
15696
|
+
await writeFile6(join27(LOGS_DIR2, GLOBAL_FILENAME), `${JSON.stringify(log, null, 2)}
|
|
15685
15697
|
`, "utf-8");
|
|
15686
15698
|
}
|
|
15687
15699
|
async saveEnvironmentHookLog(entry) {
|
|
@@ -15691,7 +15703,7 @@ var WarmHookLogsService = class {
|
|
|
15691
15703
|
hookName: "environment",
|
|
15692
15704
|
...entry
|
|
15693
15705
|
};
|
|
15694
|
-
await writeFile6(
|
|
15706
|
+
await writeFile6(join27(LOGS_DIR2, ENVIRONMENT_HOOK_LOG_FILENAME), `${JSON.stringify(log, null, 2)}
|
|
15695
15707
|
`, "utf-8");
|
|
15696
15708
|
}
|
|
15697
15709
|
async saveRepoHookLog(repoName, entry) {
|
|
@@ -15701,7 +15713,7 @@ var WarmHookLogsService = class {
|
|
|
15701
15713
|
hookName: repoName,
|
|
15702
15714
|
...entry
|
|
15703
15715
|
};
|
|
15704
|
-
await writeFile6(
|
|
15716
|
+
await writeFile6(join27(LOGS_DIR2, repoHookLogFilename(repoName)), `${JSON.stringify(log, null, 2)}
|
|
15705
15717
|
`, "utf-8");
|
|
15706
15718
|
}
|
|
15707
15719
|
async getAllLogs() {
|
|
@@ -15720,7 +15732,7 @@ var WarmHookLogsService = class {
|
|
|
15720
15732
|
continue;
|
|
15721
15733
|
}
|
|
15722
15734
|
try {
|
|
15723
|
-
const raw = await readFile16(
|
|
15735
|
+
const raw = await readFile16(join27(LOGS_DIR2, file), "utf-8");
|
|
15724
15736
|
const stored = JSON.parse(raw);
|
|
15725
15737
|
logs.push(withPreview2(stored));
|
|
15726
15738
|
} catch {
|
|
@@ -15758,7 +15770,7 @@ var WarmHookLogsService = class {
|
|
|
15758
15770
|
async getFullOutput(hookType, hookName) {
|
|
15759
15771
|
const filename = hookType === "global" ? GLOBAL_FILENAME : hookType === "environment" ? ENVIRONMENT_HOOK_LOG_FILENAME : repoHookLogFilename(hookName);
|
|
15760
15772
|
try {
|
|
15761
|
-
const raw = await readFile16(
|
|
15773
|
+
const raw = await readFile16(join27(LOGS_DIR2, filename), "utf-8");
|
|
15762
15774
|
const stored = JSON.parse(raw);
|
|
15763
15775
|
if (stored.hookType !== hookType || stored.hookName !== hookName) {
|
|
15764
15776
|
return null;
|
|
@@ -15777,7 +15789,7 @@ var warmHookLogsService = new WarmHookLogsService();
|
|
|
15777
15789
|
// src/services/warm-hooks-service.ts
|
|
15778
15790
|
async function readRepoWarmHook(repoPath) {
|
|
15779
15791
|
for (const filename of REPLICAS_CONFIG_FILENAMES) {
|
|
15780
|
-
const configPath =
|
|
15792
|
+
const configPath = join28(repoPath, filename);
|
|
15781
15793
|
if (!existsSync8(configPath)) {
|
|
15782
15794
|
continue;
|
|
15783
15795
|
}
|
|
@@ -17010,7 +17022,7 @@ data: ${JSON.stringify("Terminal session not found")}
|
|
|
17010
17022
|
const logFiles = files.filter((f) => f.endsWith(".log"));
|
|
17011
17023
|
const sessions = await Promise.all(
|
|
17012
17024
|
logFiles.map(async (filename) => {
|
|
17013
|
-
const filePath =
|
|
17025
|
+
const filePath = join29(LOG_DIR, filename);
|
|
17014
17026
|
const fileStat = await stat6(filePath);
|
|
17015
17027
|
const sessionId = filename.replace(/\.log$/, "");
|
|
17016
17028
|
return {
|