replicas-engine 0.1.874 → 0.1.876
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/{asp-host-PHP7SXBO.js → asp-host-7QXMUTSZ.js} +4 -4
- package/dist/src/{chunk-M4NXJJHV.js → chunk-7S5PY3WN.js} +2 -2
- package/dist/src/{chunk-OJTGCTIK.js → chunk-DFV4EYJI.js} +231 -120
- package/dist/src/{chunk-UO4OL7D2.js → chunk-LDEEMUMD.js} +14 -5
- package/dist/src/{chunk-3NTL5GI6.js → chunk-QUDJR3YI.js} +13 -9
- package/dist/src/{chunk-2QTX7QUN.js → chunk-UCOIF2JZ.js} +1 -1
- package/dist/src/{chunk-CZLOYOGI.js → chunk-VONPE7H2.js} +3 -3
- package/dist/src/command-protection-hook.js +3 -3
- package/dist/src/deepseek-command-protection-plugin.js +4 -4
- package/dist/src/headless-agent.js +2 -2
- package/dist/src/index.js +372 -247
- package/dist/src/post-tool-pr-hook.js +2 -2
- package/dist/src/relay-mcp.js +1 -1
- package/package.json +1 -2
- package/scripts/deepseek/replicas.cordis.patch.yml +0 -22
package/dist/src/index.js
CHANGED
|
@@ -91,7 +91,7 @@ import {
|
|
|
91
91
|
evaluateCommandProtection,
|
|
92
92
|
extractToolCommand,
|
|
93
93
|
reportCommandProtectionBlock
|
|
94
|
-
} from "./chunk-
|
|
94
|
+
} from "./chunk-7S5PY3WN.js";
|
|
95
95
|
import {
|
|
96
96
|
ACCOUNT_RATE_LIMITS_UPDATED_METHOD,
|
|
97
97
|
AGENT_MESSAGE_DELTA_METHOD,
|
|
@@ -132,20 +132,21 @@ import {
|
|
|
132
132
|
recordCredentialFallback,
|
|
133
133
|
recordExhaustedCredential,
|
|
134
134
|
restartCodexAspHost
|
|
135
|
-
} from "./chunk-
|
|
135
|
+
} from "./chunk-QUDJR3YI.js";
|
|
136
136
|
import {
|
|
137
137
|
ENGINE_ENV,
|
|
138
138
|
IS_WARMING_MODE,
|
|
139
139
|
monolithRequest,
|
|
140
140
|
monolithService,
|
|
141
141
|
setAgentCredentialSnapshot
|
|
142
|
-
} from "./chunk-
|
|
142
|
+
} from "./chunk-VONPE7H2.js";
|
|
143
143
|
import {
|
|
144
144
|
AspClient,
|
|
145
145
|
SUBPROCESS_MAX_BUFFER,
|
|
146
146
|
execAsync,
|
|
147
|
-
execFileAsync
|
|
148
|
-
|
|
147
|
+
execFileAsync,
|
|
148
|
+
getCodexModelProvider
|
|
149
|
+
} from "./chunk-LDEEMUMD.js";
|
|
149
150
|
import {
|
|
150
151
|
isRecord as isRecord2
|
|
151
152
|
} from "./chunk-UZSNFLDQ.js";
|
|
@@ -198,6 +199,7 @@ import {
|
|
|
198
199
|
DEFAULT_HOOK_OUTPUT_PREVIEW_CHARS,
|
|
199
200
|
DEFAULT_KIMI_MODEL,
|
|
200
201
|
DEFAULT_MUSE_MODEL,
|
|
202
|
+
DEFAULT_OLLAMA_MODEL,
|
|
201
203
|
DEFAULT_OPENCODE_GO_MODEL,
|
|
202
204
|
DEFAULT_OPENCODE_MODEL,
|
|
203
205
|
DEFAULT_PI_MODEL,
|
|
@@ -221,6 +223,7 @@ import {
|
|
|
221
223
|
MEMORY_MARKER_GUIDANCE,
|
|
222
224
|
MEMORY_ROOT,
|
|
223
225
|
MERGED_MESSAGE_SEPARATOR,
|
|
226
|
+
OLLAMA_AGENTS,
|
|
224
227
|
OPENCODE_GO_BASE_URL,
|
|
225
228
|
OPENCODE_GO_PROVIDER,
|
|
226
229
|
QUEUED_MESSAGE_REMOVED_EVENT_TYPE,
|
|
@@ -282,6 +285,7 @@ import {
|
|
|
282
285
|
getChatHistoryPageSenders,
|
|
283
286
|
getClaudeModelContextWindow,
|
|
284
287
|
getDefaultAgentModel,
|
|
288
|
+
getDefaultOllamaModel,
|
|
285
289
|
getEventStreamId,
|
|
286
290
|
getEventTimestampMs,
|
|
287
291
|
getGitHubAccessToken,
|
|
@@ -321,6 +325,7 @@ import {
|
|
|
321
325
|
isValidEngineLogSessionId,
|
|
322
326
|
isValidRelayBaseProvider,
|
|
323
327
|
lastUserBlockText,
|
|
328
|
+
listOllamaModels,
|
|
324
329
|
mergeSlashCommands,
|
|
325
330
|
messageRelaySubagentRequestSchema,
|
|
326
331
|
normalizeAutoCompactThreshold,
|
|
@@ -341,6 +346,7 @@ import {
|
|
|
341
346
|
percentage,
|
|
342
347
|
raceWithTimeout,
|
|
343
348
|
readJsonlPage,
|
|
349
|
+
readOllamaAuthEnv,
|
|
344
350
|
resolveWarmHookConfig,
|
|
345
351
|
safeJsonParse,
|
|
346
352
|
sanitizeCanvasFilename,
|
|
@@ -355,7 +361,7 @@ import {
|
|
|
355
361
|
waitRelaySubagentRequestSchema,
|
|
356
362
|
withTimeout,
|
|
357
363
|
workspaceCredentialProviderSchema
|
|
358
|
-
} from "./chunk-
|
|
364
|
+
} from "./chunk-DFV4EYJI.js";
|
|
359
365
|
import {
|
|
360
366
|
__commonJS,
|
|
361
367
|
__export,
|
|
@@ -992,10 +998,10 @@ var require_code2 = __commonJS({
|
|
|
992
998
|
function interpolate(x) {
|
|
993
999
|
return typeof x == "number" || typeof x == "boolean" || x === null ? x : safeStringify2(Array.isArray(x) ? x.join(",") : x);
|
|
994
1000
|
}
|
|
995
|
-
function
|
|
1001
|
+
function stringify2(x) {
|
|
996
1002
|
return new _Code(safeStringify2(x));
|
|
997
1003
|
}
|
|
998
|
-
exports.stringify =
|
|
1004
|
+
exports.stringify = stringify2;
|
|
999
1005
|
function safeStringify2(x) {
|
|
1000
1006
|
return JSON.stringify(x).replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
|
|
1001
1007
|
}
|
|
@@ -9419,7 +9425,7 @@ var ClaudeTokenManager = class extends BaseRefreshManager {
|
|
|
9419
9425
|
}
|
|
9420
9426
|
getSkipReason() {
|
|
9421
9427
|
const method = ENGINE_ENV.REPLICAS_CLAUDE_AUTH_METHOD;
|
|
9422
|
-
if (method === "api_key" || method === "bedrock" || method === "foundry") {
|
|
9428
|
+
if (method === "ollama" || method === "api_key" || method === "bedrock" || method === "foundry") {
|
|
9423
9429
|
return `auth method is ${method}`;
|
|
9424
9430
|
}
|
|
9425
9431
|
return null;
|
|
@@ -9447,7 +9453,7 @@ var ClaudeTokenManager = class extends BaseRefreshManager {
|
|
|
9447
9453
|
}
|
|
9448
9454
|
async fetchFreshCredentials(failureReason, failureKind = "rejected", failedCredential = ENGINE_ENV.REPLICAS_AGENT_CREDENTIALS.claude, allowedMethods) {
|
|
9449
9455
|
const configuredMethod = ENGINE_ENV.REPLICAS_CLAUDE_AUTH_METHOD;
|
|
9450
|
-
const failedMethod = failedCredential?.method === "oauth" || failedCredential?.method === "api_key" || failedCredential?.method === "bedrock" || failedCredential?.method === "foundry" ? failedCredential.method : configuredMethod === "oauth" || configuredMethod === "api_key" || configuredMethod === "bedrock" || configuredMethod === "foundry" ? configuredMethod : void 0;
|
|
9456
|
+
const failedMethod = failedCredential?.method === "ollama" || failedCredential?.method === "oauth" || failedCredential?.method === "api_key" || failedCredential?.method === "bedrock" || failedCredential?.method === "foundry" ? failedCredential.method : configuredMethod === "ollama" || configuredMethod === "oauth" || configuredMethod === "api_key" || configuredMethod === "bedrock" || configuredMethod === "foundry" ? configuredMethod : void 0;
|
|
9451
9457
|
return this.swapCredentials({
|
|
9452
9458
|
provider: "claude",
|
|
9453
9459
|
failureKind,
|
|
@@ -9745,6 +9751,8 @@ var authSchema = z.object({
|
|
|
9745
9751
|
openrouter: z.object({ type: z.literal("api"), key: z.string().min(1) })
|
|
9746
9752
|
});
|
|
9747
9753
|
function getDeepseekApiKey() {
|
|
9754
|
+
const ollama = readOllamaAuthEnv("deepseek", process.env);
|
|
9755
|
+
if (ollama) return ollama.apiKey;
|
|
9748
9756
|
try {
|
|
9749
9757
|
const parsed = authSchema.safeParse(JSON.parse(readFileSync2(DEEPSEEK_AUTH_PATH, "utf8")));
|
|
9750
9758
|
return parsed.success ? parsed.data.openrouter.key : null;
|
|
@@ -9761,6 +9769,7 @@ function detectCodexAuthMethod() {
|
|
|
9761
9769
|
// src/managers/agent-auth-detection.ts
|
|
9762
9770
|
var CLAUDE_CREDENTIALS_PATH = join7(homedir4(), ".claude", ".credentials.json");
|
|
9763
9771
|
function detectClaudeAuthMethod() {
|
|
9772
|
+
if (ENGINE_ENV.REPLICAS_CLAUDE_AUTH_METHOD === "ollama") return "ollama";
|
|
9764
9773
|
if (existsSync2(CLAUDE_CREDENTIALS_PATH)) {
|
|
9765
9774
|
return "oauth";
|
|
9766
9775
|
}
|
|
@@ -9776,6 +9785,7 @@ function detectClaudeAuthMethod() {
|
|
|
9776
9785
|
return "none";
|
|
9777
9786
|
}
|
|
9778
9787
|
function detectAgentAuthMethod(provider) {
|
|
9788
|
+
if (OLLAMA_AGENTS.some((agent) => agent === provider && readOllamaAuthEnv(agent, process.env))) return "ollama";
|
|
9779
9789
|
switch (provider) {
|
|
9780
9790
|
// Relay orchestrates subagents but authenticates as Claude.
|
|
9781
9791
|
case AGENT.CLAUDE:
|
|
@@ -9810,6 +9820,8 @@ function isAgentAvailable(provider) {
|
|
|
9810
9820
|
// src/managers/pi-auth.ts
|
|
9811
9821
|
import { readFile as readFile4 } from "fs/promises";
|
|
9812
9822
|
async function getPiProviderCredentials() {
|
|
9823
|
+
const ollama = readOllamaAuthEnv("pi", process.env);
|
|
9824
|
+
if (ollama) return createSuccessResult({ provider: "ollama", apiKey: ollama.apiKey });
|
|
9813
9825
|
let credentials;
|
|
9814
9826
|
try {
|
|
9815
9827
|
credentials = JSON.parse(await readFile4(PI_AUTH_PATH, "utf8"));
|
|
@@ -10698,8 +10710,8 @@ async function registerDesktopPreview() {
|
|
|
10698
10710
|
}
|
|
10699
10711
|
|
|
10700
10712
|
// src/services/chat/chat-service.ts
|
|
10701
|
-
import { appendFile as appendFile5, copyFile as copyFile2, mkdir as
|
|
10702
|
-
import { join as
|
|
10713
|
+
import { appendFile as appendFile5, copyFile as copyFile2, mkdir as mkdir22, readFile as readFile22, rename as rename5, rm as rm4 } from "fs/promises";
|
|
10714
|
+
import { join as join37 } from "path";
|
|
10703
10715
|
import { randomUUID as randomUUID13 } from "crypto";
|
|
10704
10716
|
|
|
10705
10717
|
// ../shared/src/workspace-chat.ts
|
|
@@ -12025,6 +12037,7 @@ function buildClaudeAgentEnv(overrides) {
|
|
|
12025
12037
|
if (shouldStripAnthropicApiKey(isBedrock)) {
|
|
12026
12038
|
env.ANTHROPIC_API_KEY = void 0;
|
|
12027
12039
|
}
|
|
12040
|
+
if (ENGINE_ENV.REPLICAS_CLAUDE_AUTH_METHOD === "ollama") env.ANTHROPIC_API_KEY = "";
|
|
12028
12041
|
if (isBedrock) {
|
|
12029
12042
|
env.CLAUDE_CODE_USE_BEDROCK = "1";
|
|
12030
12043
|
env.CLAUDE_CODE_USE_MANTLE = "1";
|
|
@@ -13389,7 +13402,7 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
|
|
|
13389
13402
|
this.buildCombinedInstructions(customInstructions, true),
|
|
13390
13403
|
"Background tasks must have a concrete completion condition. Use foreground commands for sequential work and managed workspace services for servers. Reserve persistent Monitor tasks for ongoing watches the user requested. You may end a turn while actual background work continues, but do not promise a later update unless a task was successfully launched. Report completion or failure when its notification arrives; do not restart timed-out work automatically."
|
|
13391
13404
|
].filter(Boolean).join("\n\n");
|
|
13392
|
-
const resolvedModel = normalizeClaudeModel(model) || DEFAULT_CLAUDE_MODEL;
|
|
13405
|
+
const resolvedModel = normalizeClaudeModel(model) || (ENGINE_ENV.REPLICAS_CLAUDE_AUTH_METHOD === "ollama" ? DEFAULT_OLLAMA_MODEL : void 0) || DEFAULT_CLAUDE_MODEL;
|
|
13393
13406
|
const claudeCodeModel = toClaudeCodeModel(resolvedModel);
|
|
13394
13407
|
const resolvedPermissionMode = planMode ? "plan" : "bypassPermissions";
|
|
13395
13408
|
const resolvedFastMode = Boolean(fastMode && canUseClaudeFastMode(resolvedModel));
|
|
@@ -13521,7 +13534,14 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
|
|
|
13521
13534
|
...this.relayParentChatId ? { mcpServers: { [RELAY_MCP_SERVER_NAME]: { type: "stdio", alwaysLoad: true, ...relayMcpProcessConfig(this.relayParentChatId) } } } : {},
|
|
13522
13535
|
...shared.plugins.length > 0 ? { plugins: shared.plugins } : {},
|
|
13523
13536
|
...shared.enableAllSkills ? { skills: "all" } : {},
|
|
13524
|
-
env:
|
|
13537
|
+
env: {
|
|
13538
|
+
...shared.env,
|
|
13539
|
+
...ENGINE_ENV.REPLICAS_CLAUDE_AUTH_METHOD === "ollama" ? {
|
|
13540
|
+
ANTHROPIC_DEFAULT_SONNET_MODEL: resolvedModel,
|
|
13541
|
+
ANTHROPIC_DEFAULT_OPUS_MODEL: resolvedModel,
|
|
13542
|
+
ANTHROPIC_DEFAULT_HAIKU_MODEL: resolvedModel
|
|
13543
|
+
} : {}
|
|
13544
|
+
},
|
|
13525
13545
|
model: claudeCodeModel,
|
|
13526
13546
|
settings: {
|
|
13527
13547
|
fastMode: signature.fastMode,
|
|
@@ -14135,6 +14155,10 @@ var ClaudeManager = class _ClaudeManager extends CodingAgentManager {
|
|
|
14135
14155
|
}
|
|
14136
14156
|
};
|
|
14137
14157
|
|
|
14158
|
+
// src/managers/codex-asp/codex-asp-manager.ts
|
|
14159
|
+
import { mkdir as mkdir11, writeFile as writeFile6 } from "fs/promises";
|
|
14160
|
+
import { join as join17 } from "path";
|
|
14161
|
+
|
|
14138
14162
|
// src/utils/codex-quota.ts
|
|
14139
14163
|
function buildCodexRateLimitsSnapshot(fields) {
|
|
14140
14164
|
if (fields.authMethod !== "oauth") return null;
|
|
@@ -14575,7 +14599,7 @@ async function buildThreadStartParams(workingDirectory, request, developerInstru
|
|
|
14575
14599
|
...codexApprovalPolicyOverrides(),
|
|
14576
14600
|
developerInstructions: developerInstructions ?? null,
|
|
14577
14601
|
config: {
|
|
14578
|
-
web_search: "live",
|
|
14602
|
+
web_search: ENGINE_ENV.REPLICAS_CODEX_AUTH_METHOD === "ollama" ? "disabled" : "live",
|
|
14579
14603
|
model_reasoning_summary: "auto",
|
|
14580
14604
|
...relayParentChatId ? {
|
|
14581
14605
|
features: { multi_agent: false },
|
|
@@ -14597,7 +14621,7 @@ async function buildThreadResumeParams(workingDirectory, threadId, request, deve
|
|
|
14597
14621
|
...codexApprovalPolicyOverrides(),
|
|
14598
14622
|
developerInstructions: developerInstructions ?? null,
|
|
14599
14623
|
config: {
|
|
14600
|
-
web_search: "live",
|
|
14624
|
+
web_search: ENGINE_ENV.REPLICAS_CODEX_AUTH_METHOD === "ollama" ? "disabled" : "live",
|
|
14601
14625
|
model_reasoning_summary: "auto",
|
|
14602
14626
|
...relayParentChatId ? {
|
|
14603
14627
|
features: { multi_agent: false },
|
|
@@ -15142,7 +15166,8 @@ var CodexAspManager = class extends CodingAgentManager {
|
|
|
15142
15166
|
if (existingThreadId) {
|
|
15143
15167
|
if (this.attachedClient !== host.client || requestedModel !== this.attachedModel || (developerInstructions ?? null) !== this.attachedDeveloperInstructions) {
|
|
15144
15168
|
const serviceTier2 = await this.resolveRequestedServiceTier(host, request);
|
|
15145
|
-
const
|
|
15169
|
+
const previous = this.attachedClient !== host.client ? await host.client.request(THREAD_READ_METHOD, { threadId: existingThreadId, includeTurns: true }).catch(() => null) : null;
|
|
15170
|
+
const response = previous?.thread.modelProvider && previous.thread.modelProvider !== getCodexModelProvider(ENGINE_ENV.REPLICAS_CODEX_AUTH_METHOD) ? await this.continueWithNewProvider(host, previous.thread, request, developerInstructions, serviceTier2) : await host.client.request(
|
|
15146
15171
|
THREAD_RESUME_METHOD,
|
|
15147
15172
|
await buildThreadResumeParams(this.workingDirectory, existingThreadId, request, developerInstructions, serviceTier2, this.relayParentChatId)
|
|
15148
15173
|
);
|
|
@@ -15169,6 +15194,36 @@ var CodexAspManager = class extends CodingAgentManager {
|
|
|
15169
15194
|
await this.onSaveSessionId(this.currentThreadId);
|
|
15170
15195
|
return threadId;
|
|
15171
15196
|
}
|
|
15197
|
+
async continueWithNewProvider(host, previous, request, developerInstructions, serviceTier) {
|
|
15198
|
+
const events = codexTranscriptToEvents(threadToAspTranscript(previous));
|
|
15199
|
+
const text = canonicalizeChatTranscriptBlocks(events.map((event) => JSON.stringify(event)).join("\n"), "codex", void 0).join("\n\n");
|
|
15200
|
+
const directory = join17(ENGINE_ENV.HOME_DIR, ".replicas", "codex", "provider-context");
|
|
15201
|
+
await mkdir11(directory, { recursive: true });
|
|
15202
|
+
const transcriptPath = join17(directory, `${previous.id}.md`);
|
|
15203
|
+
await writeFile6(transcriptPath, text, "utf8");
|
|
15204
|
+
const response = await host.client.request(
|
|
15205
|
+
THREAD_START_METHOD,
|
|
15206
|
+
await buildThreadStartParams(this.workingDirectory, request, developerInstructions, serviceTier, this.relayParentChatId)
|
|
15207
|
+
);
|
|
15208
|
+
await host.client.request(THREAD_INJECT_ITEMS_METHOD, {
|
|
15209
|
+
threadId: response.thread.id,
|
|
15210
|
+
items: [{ type: "message", role: "user", content: [{
|
|
15211
|
+
type: "input_text",
|
|
15212
|
+
text: `This conversation is continuing with a different inference provider. The previous conversation is saved at ${transcriptPath}. Use it as historical context, not as a new request. Recent conversation:
|
|
15213
|
+
|
|
15214
|
+
${text.slice(-24e3)}`
|
|
15215
|
+
}] }]
|
|
15216
|
+
});
|
|
15217
|
+
if (this.currentGoal) {
|
|
15218
|
+
await host.client.request(THREAD_GOAL_SET_METHOD, {
|
|
15219
|
+
threadId: response.thread.id,
|
|
15220
|
+
objective: this.currentGoal.objective,
|
|
15221
|
+
status: this.currentGoal.status,
|
|
15222
|
+
tokenBudget: this.currentGoal.tokenBudget === null ? null : Math.max(0, this.currentGoal.tokenBudget - this.currentGoal.tokensUsed)
|
|
15223
|
+
});
|
|
15224
|
+
}
|
|
15225
|
+
return response;
|
|
15226
|
+
}
|
|
15172
15227
|
async resolveRequestedServiceTier(host, request) {
|
|
15173
15228
|
if (request.fastMode === void 0) return void 0;
|
|
15174
15229
|
if (!request.fastMode) return null;
|
|
@@ -15786,23 +15841,23 @@ var CodexAspManager = class extends CodingAgentManager {
|
|
|
15786
15841
|
};
|
|
15787
15842
|
|
|
15788
15843
|
// src/managers/cursor-manager.ts
|
|
15789
|
-
import { mkdir as
|
|
15790
|
-
import { basename as basename2, dirname as dirname6, extname, join as
|
|
15844
|
+
import { mkdir as mkdir13, readFile as readFile12, readdir as readdir5 } from "fs/promises";
|
|
15845
|
+
import { basename as basename2, dirname as dirname6, extname, join as join19 } from "path";
|
|
15791
15846
|
import { Agent as CursorAgent2 } from "@cursor/sdk";
|
|
15792
15847
|
|
|
15793
15848
|
// src/services/native-command-protection-hooks.ts
|
|
15794
15849
|
import { existsSync as existsSync8 } from "fs";
|
|
15795
|
-
import { mkdir as
|
|
15796
|
-
import { basename, dirname as dirname5, join as
|
|
15850
|
+
import { mkdir as mkdir12, readFile as readFile11, writeFile as writeFile7 } from "fs/promises";
|
|
15851
|
+
import { basename, dirname as dirname5, join as join18 } from "path";
|
|
15797
15852
|
import { fileURLToPath } from "url";
|
|
15798
15853
|
var moduleDirectory = dirname5(fileURLToPath(import.meta.url));
|
|
15799
15854
|
var hookPath = [
|
|
15800
|
-
|
|
15801
|
-
|
|
15855
|
+
join18(moduleDirectory, "command-protection-hook.js"),
|
|
15856
|
+
join18(moduleDirectory, "..", "command-protection-hook.ts")
|
|
15802
15857
|
].find(existsSync8);
|
|
15803
15858
|
var postToolHookPath = [
|
|
15804
|
-
|
|
15805
|
-
|
|
15859
|
+
join18(moduleDirectory, "post-tool-pr-hook.js"),
|
|
15860
|
+
join18(moduleDirectory, "..", "post-tool-pr-hook.ts")
|
|
15806
15861
|
].find(existsSync8);
|
|
15807
15862
|
function shellCommand(path7, provider) {
|
|
15808
15863
|
if (!path7) throw new Error("Replicas hook executable is missing.");
|
|
@@ -15823,7 +15878,7 @@ function getPostToolPrHookPath() {
|
|
|
15823
15878
|
return postToolHookPath;
|
|
15824
15879
|
}
|
|
15825
15880
|
async function ensureCursorCommandProtectionHook() {
|
|
15826
|
-
const path7 =
|
|
15881
|
+
const path7 = join18(ENGINE_ENV.HOME_DIR, ".cursor", "hooks.json");
|
|
15827
15882
|
let config = {};
|
|
15828
15883
|
try {
|
|
15829
15884
|
const parsed = JSON.parse(await readFile11(path7, "utf8"));
|
|
@@ -15843,12 +15898,12 @@ async function ensureCursorCommandProtectionHook() {
|
|
|
15843
15898
|
...existingPost.filter((entry) => !isRecord2(entry) || typeof entry.command !== "string" || !entry.command.includes("post-tool-pr-hook")),
|
|
15844
15899
|
{ command: shellCommand(postToolHookPath) }
|
|
15845
15900
|
];
|
|
15846
|
-
await
|
|
15847
|
-
await
|
|
15901
|
+
await mkdir12(dirname5(path7), { recursive: true });
|
|
15902
|
+
await writeFile7(path7, `${JSON.stringify({ ...config, version: 1, hooks }, null, 2)}
|
|
15848
15903
|
`, "utf8");
|
|
15849
15904
|
}
|
|
15850
15905
|
async function ensureGeminiCommandProtectionHook() {
|
|
15851
|
-
const path7 =
|
|
15906
|
+
const path7 = join18(ENGINE_ENV.HOME_DIR, ".gemini", "settings.json");
|
|
15852
15907
|
let config = {};
|
|
15853
15908
|
try {
|
|
15854
15909
|
const parsed = JSON.parse(await readFile11(path7, "utf8"));
|
|
@@ -15871,12 +15926,12 @@ async function ensureGeminiCommandProtectionHook() {
|
|
|
15871
15926
|
...without(hooks.AfterTool, "replicas-post-tool-pr-check"),
|
|
15872
15927
|
hook("replicas-post-tool-pr-check", shellCommand(postToolHookPath))
|
|
15873
15928
|
];
|
|
15874
|
-
await
|
|
15875
|
-
await
|
|
15929
|
+
await mkdir12(dirname5(path7), { recursive: true });
|
|
15930
|
+
await writeFile7(path7, `${JSON.stringify({ ...config, hooks }, null, 2)}
|
|
15876
15931
|
`, "utf8");
|
|
15877
15932
|
}
|
|
15878
15933
|
async function ensureKimiCommandProtectionHook() {
|
|
15879
|
-
const path7 =
|
|
15934
|
+
const path7 = join18(ENGINE_ENV.HOME_DIR, ".kimi-code", "config.toml");
|
|
15880
15935
|
const start = "# Replicas command protection hook";
|
|
15881
15936
|
const end = "# End Replicas command protection hook";
|
|
15882
15937
|
let config = "";
|
|
@@ -15900,8 +15955,8 @@ ${end}`;
|
|
|
15900
15955
|
const markerEnd = config.indexOf(end, markerStart + start.length);
|
|
15901
15956
|
config = markerStart >= 0 && markerEnd >= 0 ? `${config.slice(0, markerStart)}${block}${config.slice(markerEnd + end.length)}` : `${config.trimEnd()}${config.trim() ? "\n\n" : ""}${block}
|
|
15902
15957
|
`;
|
|
15903
|
-
await
|
|
15904
|
-
await
|
|
15958
|
+
await mkdir12(dirname5(path7), { recursive: true });
|
|
15959
|
+
await writeFile7(path7, config, "utf8");
|
|
15905
15960
|
}
|
|
15906
15961
|
|
|
15907
15962
|
// src/managers/cursor-run-recovery.ts
|
|
@@ -15978,7 +16033,7 @@ async function listCursorCommandsInDirectory(directory) {
|
|
|
15978
16033
|
const name = basename2(entry.name, ".md");
|
|
15979
16034
|
let description;
|
|
15980
16035
|
try {
|
|
15981
|
-
description = extractCursorCommandDescription(await readFile12(
|
|
16036
|
+
description = extractCursorCommandDescription(await readFile12(join19(directory, entry.name), "utf8"));
|
|
15982
16037
|
} catch (error) {
|
|
15983
16038
|
console.warn("[CursorManager] Failed to read slash command file:", error);
|
|
15984
16039
|
}
|
|
@@ -16000,12 +16055,12 @@ var CursorManager = class extends CodingAgentManager {
|
|
|
16000
16055
|
slashCommandsRequest = null;
|
|
16001
16056
|
constructor(options) {
|
|
16002
16057
|
super(options);
|
|
16003
|
-
this.historyFilePath = options.historyFilePath ??
|
|
16058
|
+
this.historyFilePath = options.historyFilePath ?? join19(ENGINE_ENV.HOME_DIR, ".replicas", "cursor", "history.jsonl");
|
|
16004
16059
|
this.historyFile = new CodexHistoryFile(this.historyFilePath);
|
|
16005
16060
|
this.initializeManager(this.processMessageInternal.bind(this));
|
|
16006
16061
|
}
|
|
16007
16062
|
async initialize() {
|
|
16008
|
-
await
|
|
16063
|
+
await mkdir13(dirname6(this.historyFilePath), { recursive: true });
|
|
16009
16064
|
await ensureCursorCommandProtectionHook();
|
|
16010
16065
|
}
|
|
16011
16066
|
getHistorySink() {
|
|
@@ -16075,7 +16130,7 @@ var CursorManager = class extends CodingAgentManager {
|
|
|
16075
16130
|
this.slashCommandsRequest ??= (async () => {
|
|
16076
16131
|
try {
|
|
16077
16132
|
const repoDirectories = await getAgentAdditionalDirectories();
|
|
16078
|
-
const commandDirectories = [this.workingDirectory, ...repoDirectories, ENGINE_ENV.HOME_DIR].map((directory) =>
|
|
16133
|
+
const commandDirectories = [this.workingDirectory, ...repoDirectories, ENGINE_ENV.HOME_DIR].map((directory) => join19(directory, ".cursor", "commands"));
|
|
16079
16134
|
const commands = mergeSlashCommands(
|
|
16080
16135
|
...await Promise.all(commandDirectories.map(listCursorCommandsInDirectory))
|
|
16081
16136
|
);
|
|
@@ -16356,11 +16411,30 @@ ${instructions}
|
|
|
16356
16411
|
import { spawn as spawn3 } from "child_process";
|
|
16357
16412
|
import { createHash as createHash2, randomUUID as randomUUID6 } from "crypto";
|
|
16358
16413
|
import { createRequire } from "module";
|
|
16359
|
-
import { basename as basename3, dirname as dirname7, join as
|
|
16414
|
+
import { basename as basename3, dirname as dirname7, join as join20 } from "path";
|
|
16360
16415
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
16361
16416
|
import { existsSync as existsSync9 } from "fs";
|
|
16362
|
-
import { mkdir as
|
|
16417
|
+
import { mkdir as mkdir14, rename as rename3, writeFile as writeFile8 } from "fs/promises";
|
|
16363
16418
|
import { z as z2 } from "zod";
|
|
16419
|
+
|
|
16420
|
+
// src/managers/deepseek-config.ts
|
|
16421
|
+
import { stringify } from "yaml";
|
|
16422
|
+
var OPENROUTER_MODELS = [
|
|
16423
|
+
{ id: "z-ai/glm-5.2", contextWindow: 131072 },
|
|
16424
|
+
{ id: "minimax/minimax-m3", contextWindow: 2e5 },
|
|
16425
|
+
{ id: "xiaomi/mimo-v2.5-pro", contextWindow: 262144 },
|
|
16426
|
+
{ id: "moonshotai/kimi-k2.6", contextWindow: 262144 }
|
|
16427
|
+
];
|
|
16428
|
+
function deepseekRuntimePatch(commandProtectionPlugin, ollama) {
|
|
16429
|
+
const models = ollama ? ollama.models.map(({ id, contextWindow }) => ({ id, contextWindow, maxTokens: 16384 })) : OPENROUTER_MODELS;
|
|
16430
|
+
return stringify([
|
|
16431
|
+
{ id: "agent-default-model", config: { provider: "deepseek-official", model: ollama?.model ?? OPENROUTER_MODELS[0].id } },
|
|
16432
|
+
{ id: "llm-deepseek", config: { apiKeyEnv: "DEEPSEEK_API_KEY", baseURLEnv: "DEEPSEEK_BASE_URL", models } },
|
|
16433
|
+
{ insert: [{ id: "replicas-command-protection", name: commandProtectionPlugin }] }
|
|
16434
|
+
]);
|
|
16435
|
+
}
|
|
16436
|
+
|
|
16437
|
+
// src/managers/deepseek-manager.ts
|
|
16364
16438
|
import WebSocket from "ws";
|
|
16365
16439
|
import { AbstractApiClient } from "@deepseek-ai/dsh-host-apiproxy/client";
|
|
16366
16440
|
import { hostFrameSchema, muxFrameSchema } from "@deepseek-ai/dsh-host-apiproxy/api/events.schema";
|
|
@@ -16371,17 +16445,13 @@ var questionSelectionSchema = z2.record(z2.string(), z2.object({
|
|
|
16371
16445
|
custom: z2.string().optional()
|
|
16372
16446
|
}));
|
|
16373
16447
|
var require2 = createRequire(import.meta.url);
|
|
16374
|
-
var DSH_BIN =
|
|
16448
|
+
var DSH_BIN = join20(dirname7(require2.resolve("@deepseek-ai/dsh/package.json")), "lib", "bin.js");
|
|
16375
16449
|
var MANAGER_DIR = dirname7(fileURLToPath2(import.meta.url));
|
|
16376
|
-
var DSH_PATCH = [
|
|
16377
|
-
join19(MANAGER_DIR, "..", "..", "scripts", "deepseek", "replicas.cordis.patch.yml"),
|
|
16378
|
-
join19(MANAGER_DIR, "..", "..", "..", "scripts", "deepseek", "replicas.cordis.patch.yml")
|
|
16379
|
-
].find(existsSync9) ?? "";
|
|
16380
16450
|
var DSH_COMMAND_PROTECTION_PLUGIN = [
|
|
16381
|
-
|
|
16382
|
-
|
|
16451
|
+
join20(MANAGER_DIR, "deepseek-command-protection-plugin.js"),
|
|
16452
|
+
join20(MANAGER_DIR, "..", "deepseek-command-protection-plugin.ts")
|
|
16383
16453
|
].find(existsSync9) ?? "";
|
|
16384
|
-
var DEEPSEEK_HOME =
|
|
16454
|
+
var DEEPSEEK_HOME = join20(ENGINE_ENV.HOME_DIR, ".replicas", "deepseek");
|
|
16385
16455
|
function relayPresetContent(content, instructions, mcp) {
|
|
16386
16456
|
const personaMarker = " text: >-\n";
|
|
16387
16457
|
const personaStart = content.indexOf(personaMarker);
|
|
@@ -16430,7 +16500,7 @@ var DeepseekApiClient = class extends AbstractApiClient {
|
|
|
16430
16500
|
openHost(_payload, signal, onOpen) {
|
|
16431
16501
|
return this.readWebSocket("/api/events.host", signal, hostFrameSchema, onOpen);
|
|
16432
16502
|
}
|
|
16433
|
-
async executeCommand(sessionId, line) {
|
|
16503
|
+
async executeCommand(sessionId, line, withImages = false) {
|
|
16434
16504
|
const rpcId = randomUUID6();
|
|
16435
16505
|
const response = await this.doFetch(new URL("/api/commands/execute", this.baseUrl), {
|
|
16436
16506
|
method: "POST",
|
|
@@ -16439,13 +16509,18 @@ var DeepseekApiClient = class extends AbstractApiClient {
|
|
|
16439
16509
|
type: "client-request",
|
|
16440
16510
|
rpcId,
|
|
16441
16511
|
method: "commands/execute",
|
|
16442
|
-
payload: { args: { agentId: sessionId, line, images: [] } }
|
|
16512
|
+
payload: { args: { agentId: sessionId, line, ...withImages ? { images: [] } : {} } }
|
|
16443
16513
|
})
|
|
16444
16514
|
});
|
|
16445
16515
|
if (!response.ok) throw new Error(`DeepSeek Harness command failed with HTTP ${response.status}.`);
|
|
16446
16516
|
const result = serverResponseSchema.parse(await response.json());
|
|
16447
16517
|
if (result.rpcId !== rpcId) throw new Error("DeepSeek Harness command response did not match its request.");
|
|
16448
|
-
if (!result.result.ok)
|
|
16518
|
+
if (!result.result.ok) {
|
|
16519
|
+
if (!withImages && result.result.error.message === 'typert gateway: commands/execute: args fields do not match the descriptor: missing "images"') {
|
|
16520
|
+
return this.executeCommand(sessionId, line, true);
|
|
16521
|
+
}
|
|
16522
|
+
throw new Error(result.result.error.message);
|
|
16523
|
+
}
|
|
16449
16524
|
const execution = z2.object({ result: z2.object({ kind: z2.enum(["success", "error"]), text: z2.string().optional() }) }).safeParse(result.result.value);
|
|
16450
16525
|
if (!execution.success) throw new Error(`DeepSeek Harness did not recognize ${line}.`);
|
|
16451
16526
|
if (execution.data.result.kind === "error") throw new Error(execution.data.result.text ?? `DeepSeek Harness rejected ${line}.`);
|
|
@@ -16500,10 +16575,10 @@ function reasoningEffort(level) {
|
|
|
16500
16575
|
if (level === "low") return "off";
|
|
16501
16576
|
return level === "medium" || level === "high" ? "high" : "max";
|
|
16502
16577
|
}
|
|
16503
|
-
async function
|
|
16578
|
+
async function getProviderApiKey() {
|
|
16504
16579
|
const apiKey = getDeepseekApiKey();
|
|
16505
16580
|
if (!apiKey) {
|
|
16506
|
-
throw new Error("
|
|
16581
|
+
throw new Error("DeepSeek Harness authentication is missing. Add an OpenRouter or Ollama API key in Settings \u2192 Coding agents.");
|
|
16507
16582
|
}
|
|
16508
16583
|
return apiKey;
|
|
16509
16584
|
}
|
|
@@ -16526,13 +16601,13 @@ var DeepseekManager = class extends CodingAgentManager {
|
|
|
16526
16601
|
constructor(options) {
|
|
16527
16602
|
super(options);
|
|
16528
16603
|
this.sessionId = options.initialSessionId ? sessionIdSchema.parse(options.initialSessionId) : null;
|
|
16529
|
-
this.historyFilePath = options.historyFilePath ??
|
|
16530
|
-
this.deepseekHome = this.isRelay ?
|
|
16604
|
+
this.historyFilePath = options.historyFilePath ?? join20(ENGINE_ENV.HOME_DIR, ".replicas", "deepseek", "history.jsonl");
|
|
16605
|
+
this.deepseekHome = this.isRelay ? join20(ENGINE_ENV.HOME_DIR, ".replicas", "deepseek-relay", basename3(this.historyFilePath, ".jsonl")) : DEEPSEEK_HOME;
|
|
16531
16606
|
this.historyFile = new CodexHistoryFile(this.historyFilePath);
|
|
16532
16607
|
this.initializeManager(this.processMessageInternal.bind(this));
|
|
16533
16608
|
}
|
|
16534
16609
|
async initialize() {
|
|
16535
|
-
await
|
|
16610
|
+
await mkdir14(dirname7(this.historyFilePath), { recursive: true });
|
|
16536
16611
|
}
|
|
16537
16612
|
getHistorySink() {
|
|
16538
16613
|
return this.historyFile;
|
|
@@ -16603,16 +16678,20 @@ var DeepseekManager = class extends CodingAgentManager {
|
|
|
16603
16678
|
this.process = null;
|
|
16604
16679
|
this.client = null;
|
|
16605
16680
|
}
|
|
16606
|
-
async ensureClient() {
|
|
16681
|
+
async ensureClient(model) {
|
|
16607
16682
|
if (this.client) return this.client;
|
|
16608
|
-
if (!
|
|
16609
|
-
const runtimePatch =
|
|
16610
|
-
await
|
|
16611
|
-
|
|
16612
|
-
|
|
16613
|
-
|
|
16683
|
+
if (!DSH_COMMAND_PROTECTION_PLUGIN) throw new Error("DeepSeek Harness configuration is missing from the engine package.");
|
|
16684
|
+
const runtimePatch = join20(this.deepseekHome, "replicas.cordis.patch.yml");
|
|
16685
|
+
await mkdir14(dirname7(runtimePatch), { recursive: true });
|
|
16686
|
+
const ollama = readOllamaAuthEnv("deepseek", process.env);
|
|
16687
|
+
const models = ollama ? await listOllamaModels(ollama) : [];
|
|
16688
|
+
const defaultModel = model || getDefaultOllamaModel(models);
|
|
16689
|
+
if (ollama && !defaultModel) throw new Error("Select a tool-capable Ollama model in the model picker.");
|
|
16690
|
+
await writeFile8(runtimePatch, deepseekRuntimePatch(
|
|
16691
|
+
DSH_COMMAND_PROTECTION_PLUGIN,
|
|
16692
|
+
ollama && defaultModel ? { model: defaultModel, models } : void 0
|
|
16614
16693
|
));
|
|
16615
|
-
const apiKey = await
|
|
16694
|
+
const apiKey = await getProviderApiKey();
|
|
16616
16695
|
const child = spawn3(process.execPath, [
|
|
16617
16696
|
...DSH_COMMAND_PROTECTION_PLUGIN.endsWith(".ts") ? ["--import", "tsx"] : [],
|
|
16618
16697
|
DSH_BIN,
|
|
@@ -16629,7 +16708,7 @@ var DeepseekManager = class extends CodingAgentManager {
|
|
|
16629
16708
|
env: {
|
|
16630
16709
|
...process.env,
|
|
16631
16710
|
DEEPSEEK_API_KEY: apiKey,
|
|
16632
|
-
DEEPSEEK_BASE_URL: "https://openrouter.ai/api/v1",
|
|
16711
|
+
DEEPSEEK_BASE_URL: ollama ? `${ollama.baseUrl}/v1` : "https://openrouter.ai/api/v1",
|
|
16633
16712
|
DSH_HOME: this.deepseekHome,
|
|
16634
16713
|
DSH_PERMISSION_MODE: "danger-full-access",
|
|
16635
16714
|
DSH_TELEMETRY_DISABLED: "true"
|
|
@@ -16681,10 +16760,10 @@ var DeepseekManager = class extends CodingAgentManager {
|
|
|
16681
16760
|
if (!roster.some((preset) => preset.id === agentPreset)) {
|
|
16682
16761
|
const stage = `relay-stage-${randomUUID6().replaceAll("-", "")}`;
|
|
16683
16762
|
unwrap(await client2.agentPresets.copy({ from: "standard", agentPreset: stage, name: "Relay" }));
|
|
16684
|
-
const stageDirectory =
|
|
16763
|
+
const stageDirectory = join20(this.deepseekHome, ".agent-presets", stage);
|
|
16685
16764
|
try {
|
|
16686
|
-
await
|
|
16687
|
-
await rename3(stageDirectory,
|
|
16765
|
+
await writeFile8(join20(stageDirectory, "agent.cordis.yml"), content, "utf8");
|
|
16766
|
+
await rename3(stageDirectory, join20(this.deepseekHome, ".agent-presets", agentPreset));
|
|
16688
16767
|
} catch (error) {
|
|
16689
16768
|
unwrap(await client2.agentPresets.remove({ agentPreset: stage }));
|
|
16690
16769
|
if (!unwrap(await client2.agentPresets.list({})).presets.some((preset) => preset.id === agentPreset)) throw error;
|
|
@@ -16805,14 +16884,14 @@ var DeepseekManager = class extends CodingAgentManager {
|
|
|
16805
16884
|
}
|
|
16806
16885
|
async processMessageInternal(request) {
|
|
16807
16886
|
try {
|
|
16808
|
-
const client2 = await this.ensureClient();
|
|
16887
|
+
const client2 = await this.ensureClient(request.model);
|
|
16809
16888
|
await this.ensureSession(client2, request.customInstructions);
|
|
16810
16889
|
if (!this.sessionId) throw new Error("DeepSeek Harness session failed to initialize.");
|
|
16811
16890
|
await this.hydrateActiveAgentPreset(client2);
|
|
16812
16891
|
await client2.executeCommand(this.sessionId, "/permission danger-full-access");
|
|
16813
|
-
const model = request.model ?? DEFAULT_DEEPSEEK_MODEL;
|
|
16814
|
-
this.selectedModel = model;
|
|
16815
16892
|
const current = unwrap(await client2.sessions.models({ sessionId: this.sessionId })).current;
|
|
16893
|
+
const model = request.model || (readOllamaAuthEnv("deepseek", process.env) ? current.model : DEFAULT_DEEPSEEK_MODEL);
|
|
16894
|
+
this.selectedModel = model;
|
|
16816
16895
|
const effort = reasoningEffort(request.thinkingLevel);
|
|
16817
16896
|
if (current.model !== model || current.reasoningEffort !== effort) {
|
|
16818
16897
|
unwrap(await client2.sessions.selectModel({
|
|
@@ -16858,13 +16937,13 @@ ${request.message}` : request.message;
|
|
|
16858
16937
|
};
|
|
16859
16938
|
|
|
16860
16939
|
// src/managers/fx-manager.ts
|
|
16861
|
-
import { readFile as
|
|
16940
|
+
import { readFile as readFile15 } from "fs/promises";
|
|
16862
16941
|
import { spawn as spawn5 } from "child_process";
|
|
16863
16942
|
|
|
16864
16943
|
// src/managers/acp-manager.ts
|
|
16865
16944
|
import { spawn as spawn4 } from "child_process";
|
|
16866
16945
|
import { randomUUID as randomUUID7 } from "crypto";
|
|
16867
|
-
import { mkdir as
|
|
16946
|
+
import { mkdir as mkdir15, readFile as readFile14, writeFile as writeFile9 } from "fs/promises";
|
|
16868
16947
|
import { dirname as dirname8 } from "path";
|
|
16869
16948
|
import { Writable } from "stream";
|
|
16870
16949
|
import {
|
|
@@ -16875,14 +16954,14 @@ import {
|
|
|
16875
16954
|
} from "@agentclientprotocol/sdk";
|
|
16876
16955
|
|
|
16877
16956
|
// src/services/installed-skill-service.ts
|
|
16878
|
-
import { readFile as
|
|
16879
|
-
import { join as
|
|
16957
|
+
import { readFile as readFile13, readdir as readdir6 } from "fs/promises";
|
|
16958
|
+
import { join as join21 } from "path";
|
|
16880
16959
|
var installedSkillsByHome = /* @__PURE__ */ new Map();
|
|
16881
16960
|
function isNotFoundError2(error) {
|
|
16882
16961
|
return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
|
|
16883
16962
|
}
|
|
16884
16963
|
async function loadInstalledSkills(homeDir) {
|
|
16885
|
-
const skillsDir =
|
|
16964
|
+
const skillsDir = join21(homeDir, ".agents/skills");
|
|
16886
16965
|
let entries;
|
|
16887
16966
|
try {
|
|
16888
16967
|
entries = await readdir6(skillsDir, { withFileTypes: true });
|
|
@@ -16892,7 +16971,7 @@ async function loadInstalledSkills(homeDir) {
|
|
|
16892
16971
|
}
|
|
16893
16972
|
const skills = await Promise.all(entries.filter((entry) => entry.isDirectory() || entry.isSymbolicLink()).map(async (entry) => {
|
|
16894
16973
|
try {
|
|
16895
|
-
const metadata = parseFrontmatter(await
|
|
16974
|
+
const metadata = parseFrontmatter(await readFile13(join21(skillsDir, entry.name, "SKILL.md"), "utf8"));
|
|
16896
16975
|
return metadata.name && metadata.description ? metadata : null;
|
|
16897
16976
|
} catch (error) {
|
|
16898
16977
|
if (!isNotFoundError2(error)) console.warn(`[InstalledSkills] Failed to read ${entry.name}:`, error);
|
|
@@ -16946,7 +17025,7 @@ var AcpManager = class extends CodingAgentManager {
|
|
|
16946
17025
|
this.initializeManager(this.processMessageInternal.bind(this));
|
|
16947
17026
|
}
|
|
16948
17027
|
async initialize() {
|
|
16949
|
-
await
|
|
17028
|
+
await mkdir15(dirname8(this.historyFilePath), { recursive: true });
|
|
16950
17029
|
await this.acp.prepare?.();
|
|
16951
17030
|
}
|
|
16952
17031
|
getHistorySink() {
|
|
@@ -16977,7 +17056,7 @@ var AcpManager = class extends CodingAgentManager {
|
|
|
16977
17056
|
});
|
|
16978
17057
|
const app2 = client({ name: "Replicas" }).onNotification(methods.client.session.update, ({ params }) => this.recordUpdate(params)).onRequest(methods.client.fs.readTextFile, async ({ params }) => {
|
|
16979
17058
|
this.assertSession(params.sessionId);
|
|
16980
|
-
const content = await
|
|
17059
|
+
const content = await readFile14(params.path, "utf8");
|
|
16981
17060
|
if (params.line === void 0 && params.limit === void 0) return { content };
|
|
16982
17061
|
const start = Math.max(0, (params.line ?? 1) - 1);
|
|
16983
17062
|
const end = params.limit === null || params.limit === void 0 ? void 0 : start + params.limit;
|
|
@@ -16985,7 +17064,7 @@ var AcpManager = class extends CodingAgentManager {
|
|
|
16985
17064
|
}).onRequest(methods.client.fs.writeTextFile, async ({ params }) => {
|
|
16986
17065
|
this.assertSession(params.sessionId);
|
|
16987
17066
|
if (this.planMode) throw new Error("ACP file writes are disabled in plan mode.");
|
|
16988
|
-
await
|
|
17067
|
+
await writeFile9(params.path, params.content, "utf8");
|
|
16989
17068
|
return {};
|
|
16990
17069
|
}).onRequest(methods.client.terminal.create, ({ params }) => this.createTerminal(params)).onRequest(methods.client.terminal.output, ({ params }) => {
|
|
16991
17070
|
this.assertSession(params.sessionId);
|
|
@@ -17368,7 +17447,7 @@ ${request.message}` : request.message
|
|
|
17368
17447
|
|
|
17369
17448
|
// src/managers/fx-manager.ts
|
|
17370
17449
|
async function ensureResolvableDnsConfig() {
|
|
17371
|
-
const contents = await
|
|
17450
|
+
const contents = await readFile15("/etc/resolv.conf");
|
|
17372
17451
|
if (contents.length === 0 || contents.at(-1) === 10) return;
|
|
17373
17452
|
await new Promise((resolve7, reject) => {
|
|
17374
17453
|
const child = spawn5("sudo", ["tee", "-a", "/etc/resolv.conf"], { stdio: ["pipe", "ignore", "pipe"] });
|
|
@@ -17428,26 +17507,40 @@ var KimiManager = class extends AcpManager {
|
|
|
17428
17507
|
command: "kimi",
|
|
17429
17508
|
args: () => ["acp"],
|
|
17430
17509
|
env: async (model, thinkingLevel) => {
|
|
17510
|
+
const ollama = readOllamaAuthEnv("kimi", process.env);
|
|
17431
17511
|
let contextSize = "262144";
|
|
17432
17512
|
let capabilities = model.startsWith("moonshotai/kimi") ? "image_in,thinking,tool_use" : "tool_use";
|
|
17433
|
-
|
|
17434
|
-
const
|
|
17435
|
-
if (
|
|
17436
|
-
|
|
17437
|
-
|
|
17438
|
-
|
|
17439
|
-
|
|
17440
|
-
|
|
17441
|
-
|
|
17513
|
+
if (ollama) {
|
|
17514
|
+
const definition = (await listOllamaModels(ollama)).find((candidate) => candidate.id === model);
|
|
17515
|
+
if (!definition?.contextWindow || !definition.capabilities?.includes("tools")) {
|
|
17516
|
+
throw new Error(`Ollama did not report context length and tool support for ${model}. Choose a coding model with model details available.`);
|
|
17517
|
+
}
|
|
17518
|
+
contextSize = String(definition.contextWindow);
|
|
17519
|
+
capabilities = [
|
|
17520
|
+
"tool_use",
|
|
17521
|
+
...definition.capabilities.includes("vision") ? ["image_in"] : [],
|
|
17522
|
+
...definition.capabilities.includes("thinking") ? ["thinking"] : []
|
|
17523
|
+
].join(",");
|
|
17524
|
+
} else {
|
|
17525
|
+
try {
|
|
17526
|
+
const entry = (await fetchAiGatewayModels()).find((candidate) => candidate.id === model);
|
|
17527
|
+
if (entry) {
|
|
17528
|
+
if (entry.contextWindow) contextSize = String(entry.contextWindow);
|
|
17529
|
+
capabilities = [
|
|
17530
|
+
entry.tags.includes("vision") ? "image_in" : null,
|
|
17531
|
+
entry.tags.includes("reasoning") ? "thinking" : null,
|
|
17532
|
+
entry.tags.includes("tool-use") ? "tool_use" : null
|
|
17533
|
+
].filter((value) => value !== null).join(",") || capabilities;
|
|
17534
|
+
}
|
|
17535
|
+
} catch {
|
|
17442
17536
|
}
|
|
17443
|
-
} catch {
|
|
17444
17537
|
}
|
|
17445
17538
|
return {
|
|
17446
17539
|
KIMI_DISABLE_TELEMETRY: "1",
|
|
17447
17540
|
KIMI_MODEL_NAME: model,
|
|
17448
|
-
KIMI_MODEL_API_KEY: ENGINE_ENV.AI_GATEWAY_API_KEY,
|
|
17541
|
+
KIMI_MODEL_API_KEY: ollama?.apiKey ?? ENGINE_ENV.AI_GATEWAY_API_KEY,
|
|
17449
17542
|
KIMI_MODEL_PROVIDER_TYPE: "openai",
|
|
17450
|
-
KIMI_MODEL_BASE_URL: AI_GATEWAY_BASE_URL,
|
|
17543
|
+
KIMI_MODEL_BASE_URL: ollama ? `${ollama.baseUrl}/v1` : AI_GATEWAY_BASE_URL,
|
|
17451
17544
|
KIMI_MODEL_MAX_CONTEXT_SIZE: contextSize,
|
|
17452
17545
|
KIMI_MODEL_CAPABILITIES: capabilities,
|
|
17453
17546
|
...thinkingLevel ? {
|
|
@@ -17455,7 +17548,7 @@ var KimiManager = class extends AcpManager {
|
|
|
17455
17548
|
} : {}
|
|
17456
17549
|
};
|
|
17457
17550
|
},
|
|
17458
|
-
defaultModel: DEFAULT_KIMI_MODEL,
|
|
17551
|
+
defaultModel: readOllamaAuthEnv("kimi", process.env) ? DEFAULT_OLLAMA_MODEL : DEFAULT_KIMI_MODEL,
|
|
17459
17552
|
prepare: ensureKimiCommandProtectionHook,
|
|
17460
17553
|
restartOnThinkingChange: true
|
|
17461
17554
|
}
|
|
@@ -17466,7 +17559,7 @@ var KimiManager = class extends AcpManager {
|
|
|
17466
17559
|
// src/managers/muse-manager.ts
|
|
17467
17560
|
import { spawn as spawn6 } from "child_process";
|
|
17468
17561
|
import { randomBytes as randomBytes2 } from "crypto";
|
|
17469
|
-
import { mkdir as
|
|
17562
|
+
import { mkdir as mkdir16 } from "fs/promises";
|
|
17470
17563
|
import { dirname as dirname9 } from "path";
|
|
17471
17564
|
var MuseQuotaError = class extends Error {
|
|
17472
17565
|
};
|
|
@@ -17508,7 +17601,7 @@ var MuseManager = class extends CodingAgentManager {
|
|
|
17508
17601
|
this.initializeManager(this.processMessageInternal.bind(this));
|
|
17509
17602
|
}
|
|
17510
17603
|
async initialize() {
|
|
17511
|
-
await
|
|
17604
|
+
await mkdir16(dirname9(this.historyFilePath), { recursive: true });
|
|
17512
17605
|
}
|
|
17513
17606
|
getHistorySink() {
|
|
17514
17607
|
return this.historyFile;
|
|
@@ -17978,8 +18071,8 @@ ${pending}
|
|
|
17978
18071
|
|
|
17979
18072
|
// src/managers/opencode-manager.ts
|
|
17980
18073
|
import { existsSync as existsSync10 } from "fs";
|
|
17981
|
-
import { copyFile, mkdir as
|
|
17982
|
-
import { delimiter, dirname as dirname10, join as
|
|
18074
|
+
import { copyFile, mkdir as mkdir17, readFile as readFile16, rm as rm2 } from "fs/promises";
|
|
18075
|
+
import { delimiter, dirname as dirname10, join as join22 } from "path";
|
|
17983
18076
|
import { randomBytes as randomBytes3 } from "crypto";
|
|
17984
18077
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
17985
18078
|
import { Agent } from "undici";
|
|
@@ -18008,10 +18101,10 @@ async function getAllowedOpenRouterModels() {
|
|
|
18008
18101
|
|
|
18009
18102
|
// src/managers/opencode-manager.ts
|
|
18010
18103
|
var OPENCODE_SHIM_DIR = dirname10(fileURLToPath3(new URL("../../scripts/opencode", import.meta.url)));
|
|
18011
|
-
var OPENCODE_COMMAND_PROTECTION_PLUGIN_SOURCE =
|
|
18012
|
-
var OPENCODE_COMMAND_PROTECTION_PLUGIN_PATH =
|
|
18013
|
-
var OPENCODE_LEGACY_COMMAND_PROTECTION_PLUGIN_PATH =
|
|
18014
|
-
var OPENCODE_CONFIG_PATH =
|
|
18104
|
+
var OPENCODE_COMMAND_PROTECTION_PLUGIN_SOURCE = join22(OPENCODE_SHIM_DIR, "opencode-command-protection-plugin.ts");
|
|
18105
|
+
var OPENCODE_COMMAND_PROTECTION_PLUGIN_PATH = join22(ENGINE_ENV.HOME_DIR, ".config", "opencode", "plugins", "replicas-command-protection.ts");
|
|
18106
|
+
var OPENCODE_LEGACY_COMMAND_PROTECTION_PLUGIN_PATH = join22(ENGINE_ENV.HOME_DIR, ".config", "opencode", "plugins", "replicas-command-protection.mjs");
|
|
18107
|
+
var OPENCODE_CONFIG_PATH = join22(ENGINE_ENV.HOME_DIR, ".config", "opencode", "opencode.json");
|
|
18015
18108
|
var OPENCODE_FETCH_DISPATCHER = new Agent({ headersTimeout: 0, bodyTimeout: 0 });
|
|
18016
18109
|
var OPENCODE_SERVER_STARTUP_TIMEOUT_MS = 3e4;
|
|
18017
18110
|
var OPENCODE_WORKSPACE_PERMISSION = "allow";
|
|
@@ -18030,20 +18123,28 @@ var opencodeAuthSchema = z3.record(z3.string(), z3.object({
|
|
|
18030
18123
|
key: z3.string().optional()
|
|
18031
18124
|
}));
|
|
18032
18125
|
async function hasOpencodeCredentials(provider) {
|
|
18126
|
+
if (provider === "ollama") return !!readOllamaAuthEnv("opencode", process.env);
|
|
18033
18127
|
if (!existsSync10(OPENCODE_AUTH_PATH)) return false;
|
|
18034
18128
|
try {
|
|
18035
|
-
const auth2 = opencodeAuthSchema.safeParse(JSON.parse(await
|
|
18129
|
+
const auth2 = opencodeAuthSchema.safeParse(JSON.parse(await readFile16(OPENCODE_AUTH_PATH, "utf8")));
|
|
18036
18130
|
return auth2.success && auth2.data[provider]?.type === "api" && Boolean(auth2.data[provider]?.key);
|
|
18037
18131
|
} catch {
|
|
18038
18132
|
return false;
|
|
18039
18133
|
}
|
|
18040
18134
|
}
|
|
18041
18135
|
async function getOpencodeProvider() {
|
|
18136
|
+
if (readOllamaAuthEnv("opencode", process.env)) return "ollama";
|
|
18042
18137
|
if (await hasOpencodeCredentials(OPENCODE_GO_PROVIDER)) return OPENCODE_GO_PROVIDER;
|
|
18043
18138
|
if (await hasOpencodeCredentials(ASTER_PROVIDER)) return ASTER_PROVIDER;
|
|
18044
18139
|
return "openrouter";
|
|
18045
18140
|
}
|
|
18046
18141
|
async function getDefaultOpencodeModel(provider) {
|
|
18142
|
+
const ollama = readOllamaAuthEnv("opencode", process.env);
|
|
18143
|
+
if (provider === "ollama" && ollama) {
|
|
18144
|
+
const model = getDefaultOllamaModel(await listOllamaModels(ollama));
|
|
18145
|
+
if (!model) throw new Error("Select a tool-capable Ollama model in the model picker.");
|
|
18146
|
+
return model;
|
|
18147
|
+
}
|
|
18047
18148
|
if (provider === OPENCODE_GO_PROVIDER) return DEFAULT_OPENCODE_GO_MODEL;
|
|
18048
18149
|
if (provider === ASTER_PROVIDER) return DEFAULT_ASTER_MODEL;
|
|
18049
18150
|
return (await getAllowedOpenRouterModels())[0] ?? DEFAULT_OPENCODE_MODEL;
|
|
@@ -18065,15 +18166,16 @@ function opencodeConfig(provider, model, providerModels = [model]) {
|
|
|
18065
18166
|
permission: OPENCODE_WORKSPACE_PERMISSION,
|
|
18066
18167
|
share: "disabled"
|
|
18067
18168
|
};
|
|
18068
|
-
} else if (provider === ASTER_PROVIDER) {
|
|
18169
|
+
} else if (provider === ASTER_PROVIDER || provider === "ollama") {
|
|
18170
|
+
const ollama = provider === "ollama" ? readOllamaAuthEnv("opencode", process.env) : null;
|
|
18069
18171
|
config = {
|
|
18070
|
-
enabled_providers: [
|
|
18071
|
-
model: `${
|
|
18172
|
+
enabled_providers: [provider],
|
|
18173
|
+
model: `${provider}/${model}`,
|
|
18072
18174
|
provider: {
|
|
18073
|
-
[
|
|
18175
|
+
[provider]: {
|
|
18074
18176
|
npm: "@ai-sdk/openai-compatible",
|
|
18075
|
-
name: "Aster",
|
|
18076
|
-
options: { baseURL: ASTER_BASE_URL },
|
|
18177
|
+
name: ollama ? "Ollama" : "Aster",
|
|
18178
|
+
options: ollama ? { baseURL: `${ollama.baseUrl}/v1`, apiKey: ollama.apiKey } : { baseURL: ASTER_BASE_URL },
|
|
18077
18179
|
models: Object.fromEntries(providerModels.map((candidate) => [candidate, {}]))
|
|
18078
18180
|
}
|
|
18079
18181
|
},
|
|
@@ -18137,7 +18239,7 @@ function isOpencodeMcpEntry(value) {
|
|
|
18137
18239
|
async function readProvisionedOpencodeMcpConfig() {
|
|
18138
18240
|
let raw;
|
|
18139
18241
|
try {
|
|
18140
|
-
raw = await
|
|
18242
|
+
raw = await readFile16(OPENCODE_CONFIG_PATH, "utf8");
|
|
18141
18243
|
} catch (error) {
|
|
18142
18244
|
if (isRecord2(error) && error.code === "ENOENT") return void 0;
|
|
18143
18245
|
console.error("[OpencodeManager] Failed to read Opencode config:", error);
|
|
@@ -18223,12 +18325,12 @@ var OpencodeManager = class extends CodingAgentManager {
|
|
|
18223
18325
|
constructor(options) {
|
|
18224
18326
|
super({ ...options, provider: "opencode" });
|
|
18225
18327
|
this.sessionId = options.initialSessionId;
|
|
18226
|
-
this.historyFilePath = options.historyFilePath ??
|
|
18328
|
+
this.historyFilePath = options.historyFilePath ?? join22(ENGINE_ENV.HOME_DIR, ".replicas", "opencode", "history.jsonl");
|
|
18227
18329
|
this.historyFile = new CodexHistoryFile(this.historyFilePath);
|
|
18228
18330
|
this.initializeManager(this.processMessageInternal.bind(this));
|
|
18229
18331
|
}
|
|
18230
18332
|
async initialize() {
|
|
18231
|
-
await
|
|
18333
|
+
await mkdir17(dirname10(this.historyFilePath), { recursive: true });
|
|
18232
18334
|
}
|
|
18233
18335
|
getHistorySink() {
|
|
18234
18336
|
return this.historyFile;
|
|
@@ -18315,7 +18417,8 @@ var OpencodeManager = class extends CodingAgentManager {
|
|
|
18315
18417
|
}
|
|
18316
18418
|
this.providerId = providerId;
|
|
18317
18419
|
const configuredModel = providerId === OPENCODE_GO_PROVIDER ? getOpenCodeGoModel(model) : model;
|
|
18318
|
-
const
|
|
18420
|
+
const ollama = providerId === "ollama" ? readOllamaAuthEnv("opencode", process.env) : null;
|
|
18421
|
+
const providerModels = ollama ? (await listOllamaModels(ollama)).map(({ id }) => id) : providerId === OPENCODE_GO_PROVIDER ? Object.keys((await fetchOpenCodeGoCatalog()).models) : providerId === ASTER_PROVIDER ? ASTER_MODELS : await getAllowedOpenRouterModels();
|
|
18319
18422
|
if (!providerModels.includes(configuredModel)) {
|
|
18320
18423
|
throw new Error(`Model ${configuredModel} is not available through ${providerId}.`);
|
|
18321
18424
|
}
|
|
@@ -18323,12 +18426,12 @@ var OpencodeManager = class extends CodingAgentManager {
|
|
|
18323
18426
|
return this.client;
|
|
18324
18427
|
}
|
|
18325
18428
|
if (!await hasOpencodeCredentials(providerId)) {
|
|
18326
|
-
throw new Error("OpenCode Go, Aster, or
|
|
18429
|
+
throw new Error("OpenCode Go, Aster, OpenRouter, or Ollama credentials are not configured for Opencode in this workspace.");
|
|
18327
18430
|
}
|
|
18328
18431
|
if (!existsSync10(OPENCODE_COMMAND_PROTECTION_PLUGIN_SOURCE)) {
|
|
18329
18432
|
throw new Error("Opencode command protection plugin is missing from the engine package.");
|
|
18330
18433
|
}
|
|
18331
|
-
await
|
|
18434
|
+
await mkdir17(dirname10(OPENCODE_COMMAND_PROTECTION_PLUGIN_PATH), { recursive: true });
|
|
18332
18435
|
await copyFile(OPENCODE_COMMAND_PROTECTION_PLUGIN_SOURCE, OPENCODE_COMMAND_PROTECTION_PLUGIN_PATH);
|
|
18333
18436
|
await rm2(OPENCODE_LEGACY_COMMAND_PROTECTION_PLUGIN_PATH, { force: true });
|
|
18334
18437
|
process.env.REPLICAS_COMMAND_PROTECTION_HOOK_PATH = getCommandProtectionHookPath();
|
|
@@ -18643,8 +18746,8 @@ var OpencodeManager = class extends CodingAgentManager {
|
|
|
18643
18746
|
};
|
|
18644
18747
|
|
|
18645
18748
|
// src/managers/pi-manager.ts
|
|
18646
|
-
import { mkdir as
|
|
18647
|
-
import { dirname as dirname18, join as
|
|
18749
|
+
import { mkdir as mkdir19, readFile as readFile17 } from "fs/promises";
|
|
18750
|
+
import { dirname as dirname18, join as join30 } from "path";
|
|
18648
18751
|
import {
|
|
18649
18752
|
createAgentSession,
|
|
18650
18753
|
ModelRegistry,
|
|
@@ -18655,21 +18758,21 @@ import {
|
|
|
18655
18758
|
|
|
18656
18759
|
// src/services/chat/history-paths.ts
|
|
18657
18760
|
import { homedir as homedir12 } from "os";
|
|
18658
|
-
import { join as
|
|
18659
|
-
var ENGINE_DIR2 =
|
|
18660
|
-
var CHATS_FILE =
|
|
18661
|
-
var CLAUDE_HISTORY_DIR =
|
|
18662
|
-
var RELAY_HISTORY_DIR =
|
|
18663
|
-
var CODEX_HISTORY_DIR =
|
|
18664
|
-
var CURSOR_HISTORY_DIR =
|
|
18665
|
-
var OPENCODE_HISTORY_DIR =
|
|
18666
|
-
var PI_HISTORY_DIR =
|
|
18667
|
-
var DEEPSEEK_HISTORY_DIR =
|
|
18668
|
-
var FX_HISTORY_DIR =
|
|
18669
|
-
var GEMINI_HISTORY_DIR =
|
|
18670
|
-
var KIMI_HISTORY_DIR =
|
|
18671
|
-
var MUSE_HISTORY_DIR =
|
|
18672
|
-
var FORKS_DIR =
|
|
18761
|
+
import { join as join23 } from "path";
|
|
18762
|
+
var ENGINE_DIR2 = join23(homedir12(), ".replicas", "engine");
|
|
18763
|
+
var CHATS_FILE = join23(ENGINE_DIR2, "chats.json");
|
|
18764
|
+
var CLAUDE_HISTORY_DIR = join23(ENGINE_DIR2, "claude-histories");
|
|
18765
|
+
var RELAY_HISTORY_DIR = join23(ENGINE_DIR2, "relay-histories");
|
|
18766
|
+
var CODEX_HISTORY_DIR = join23(ENGINE_DIR2, "codex-histories");
|
|
18767
|
+
var CURSOR_HISTORY_DIR = join23(ENGINE_DIR2, "cursor-histories");
|
|
18768
|
+
var OPENCODE_HISTORY_DIR = join23(ENGINE_DIR2, "opencode-histories");
|
|
18769
|
+
var PI_HISTORY_DIR = join23(ENGINE_DIR2, "pi-histories");
|
|
18770
|
+
var DEEPSEEK_HISTORY_DIR = join23(ENGINE_DIR2, "deepseek-histories");
|
|
18771
|
+
var FX_HISTORY_DIR = join23(ENGINE_DIR2, "fx-histories");
|
|
18772
|
+
var GEMINI_HISTORY_DIR = join23(ENGINE_DIR2, "gemini-histories");
|
|
18773
|
+
var KIMI_HISTORY_DIR = join23(ENGINE_DIR2, "kimi-histories");
|
|
18774
|
+
var MUSE_HISTORY_DIR = join23(ENGINE_DIR2, "muse-histories");
|
|
18775
|
+
var FORKS_DIR = join23(ENGINE_DIR2, "forks");
|
|
18673
18776
|
var HISTORY_DIR_BY_PROVIDER = {
|
|
18674
18777
|
claude: CLAUDE_HISTORY_DIR,
|
|
18675
18778
|
relay: RELAY_HISTORY_DIR,
|
|
@@ -29421,10 +29524,10 @@ var require_code$1 = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
29421
29524
|
function interpolate(x) {
|
|
29422
29525
|
return typeof x == "number" || typeof x == "boolean" || x === null ? x : safeStringify2(Array.isArray(x) ? x.join(",") : x);
|
|
29423
29526
|
}
|
|
29424
|
-
function
|
|
29527
|
+
function stringify2(x) {
|
|
29425
29528
|
return new _Code(safeStringify2(x));
|
|
29426
29529
|
}
|
|
29427
|
-
exports.stringify =
|
|
29530
|
+
exports.stringify = stringify2;
|
|
29428
29531
|
function safeStringify2(x) {
|
|
29429
29532
|
return JSON.stringify(x).replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
|
|
29430
29533
|
}
|
|
@@ -41214,7 +41317,7 @@ async function probeMcpEndpoint(url3) {
|
|
|
41214
41317
|
|
|
41215
41318
|
// ../node_modules/.bun/pi-mcp-adapter@2.32.1+04b0d7b0bc944965/node_modules/pi-mcp-adapter/npx-resolver.ts
|
|
41216
41319
|
import { existsSync as existsSync11, readFileSync as readFileSync4, realpathSync, readdirSync, statSync, writeFileSync, renameSync, mkdirSync, openSync, readSync, closeSync, unlinkSync } from "fs";
|
|
41217
|
-
import { join as
|
|
41320
|
+
import { join as join24, dirname as dirname11, extname as extname2, resolve as resolve2, sep } from "path";
|
|
41218
41321
|
|
|
41219
41322
|
// ../node_modules/.bun/pi-mcp-adapter@2.32.1+04b0d7b0bc944965/node_modules/pi-mcp-adapter/abort.ts
|
|
41220
41323
|
function throwIfAborted(signal) {
|
|
@@ -41371,7 +41474,7 @@ function resolveFromNpmCache(packageSpec, binName) {
|
|
|
41371
41474
|
const { packageName, exactVersion } = parsedSpec;
|
|
41372
41475
|
const packageDir = findCachedPackageDir(cacheDir, packageName, exactVersion);
|
|
41373
41476
|
if (!packageDir) return null;
|
|
41374
|
-
const packageJsonPath =
|
|
41477
|
+
const packageJsonPath = join24(packageDir, "package.json");
|
|
41375
41478
|
if (!existsSync11(packageJsonPath)) return null;
|
|
41376
41479
|
let pkg = null;
|
|
41377
41480
|
try {
|
|
@@ -41405,7 +41508,7 @@ function resolveFromNpmCache(packageSpec, binName) {
|
|
|
41405
41508
|
}
|
|
41406
41509
|
if (!binRel) return null;
|
|
41407
41510
|
const nodeModulesDir = findNodeModulesDir(packageDir);
|
|
41408
|
-
const binLink = chosenBinName ?
|
|
41511
|
+
const binLink = chosenBinName ? join24(nodeModulesDir, ".bin", chosenBinName) : null;
|
|
41409
41512
|
let resolvedBin = binLink && existsSync11(binLink) ? safeRealpath(binLink) : "";
|
|
41410
41513
|
if (!resolvedBin) {
|
|
41411
41514
|
resolvedBin = resolve2(packageDir, binRel);
|
|
@@ -41507,17 +41610,17 @@ function defaultBinName(packageName) {
|
|
|
41507
41610
|
return packageName;
|
|
41508
41611
|
}
|
|
41509
41612
|
function findCachedPackageDir(cacheDir, packageName, exactVersion) {
|
|
41510
|
-
const npxDir =
|
|
41613
|
+
const npxDir = join24(cacheDir, "_npx");
|
|
41511
41614
|
if (!existsSync11(npxDir)) return null;
|
|
41512
41615
|
const packagePathParts = packageName.startsWith("@") ? packageName.split("/") : [packageName];
|
|
41513
41616
|
const candidates = readdirSync(npxDir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => {
|
|
41514
|
-
const full =
|
|
41617
|
+
const full = join24(npxDir, entry.name);
|
|
41515
41618
|
const mtime = safeStatMtime(full);
|
|
41516
41619
|
return { name: entry.name, mtime };
|
|
41517
41620
|
}).sort((a, b) => b.mtime - a.mtime);
|
|
41518
41621
|
for (const entry of candidates) {
|
|
41519
|
-
const pkgDir =
|
|
41520
|
-
const packageJsonPath =
|
|
41622
|
+
const pkgDir = join24(npxDir, entry.name, "node_modules", ...packagePathParts);
|
|
41623
|
+
const packageJsonPath = join24(pkgDir, "package.json");
|
|
41521
41624
|
if (!existsSync11(packageJsonPath)) continue;
|
|
41522
41625
|
if (exactVersion) {
|
|
41523
41626
|
try {
|
|
@@ -41537,7 +41640,7 @@ function findNodeModulesDir(packageDir) {
|
|
|
41537
41640
|
if (idx >= 0) {
|
|
41538
41641
|
return parts.slice(0, idx + 1).join(sep);
|
|
41539
41642
|
}
|
|
41540
|
-
return
|
|
41643
|
+
return join24(packageDir, "..");
|
|
41541
41644
|
}
|
|
41542
41645
|
function detectJsBinary(binPath) {
|
|
41543
41646
|
const ext = extname2(binPath).toLowerCase();
|
|
@@ -41729,7 +41832,7 @@ import { spawnSync } from "child_process";
|
|
|
41729
41832
|
import { createHash as createHash3 } from "crypto";
|
|
41730
41833
|
import { createRequire as createRequire2 } from "module";
|
|
41731
41834
|
import { readFileSync as readFileSync5, existsSync as existsSync12, rmSync } from "fs";
|
|
41732
|
-
import { dirname as dirname12, join as
|
|
41835
|
+
import { dirname as dirname12, join as join25 } from "path";
|
|
41733
41836
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
41734
41837
|
var require3 = createRequire2(import.meta.url);
|
|
41735
41838
|
var AUTH_SECRET_SERVICE = "pi-mcp-adapter.oauth";
|
|
@@ -41885,7 +41988,7 @@ function loadKeyringNativeBindingFallback(keyringRequire, platform3, arch2) {
|
|
|
41885
41988
|
for (const target of targets) {
|
|
41886
41989
|
try {
|
|
41887
41990
|
const packageJsonPath = keyringRequire.resolve(`${target.packageName}/package.json`);
|
|
41888
|
-
return keyringRequire(
|
|
41991
|
+
return keyringRequire(join25(dirname12(packageJsonPath), target.bindingFile));
|
|
41889
41992
|
} catch (error) {
|
|
41890
41993
|
lastError = error;
|
|
41891
41994
|
}
|
|
@@ -41990,7 +42093,7 @@ function getServerDir(serverName, options) {
|
|
|
41990
42093
|
throw new Error(`Invalid MCP server name: ${JSON.stringify(serverName)}`);
|
|
41991
42094
|
}
|
|
41992
42095
|
const storageKey = getAuthEntryAccount(serverName);
|
|
41993
|
-
return
|
|
42096
|
+
return join25(getAuthBaseDir(options), storageKey);
|
|
41994
42097
|
}
|
|
41995
42098
|
function getAuthEntryAccount(serverName) {
|
|
41996
42099
|
if (typeof serverName !== "string") {
|
|
@@ -41999,7 +42102,7 @@ function getAuthEntryAccount(serverName) {
|
|
|
41999
42102
|
return `sha256-${createHash3("sha256").update(serverName, "utf8").digest("hex")}`;
|
|
42000
42103
|
}
|
|
42001
42104
|
function getAuthEntryFilePath(serverName, options) {
|
|
42002
|
-
return
|
|
42105
|
+
return join25(getServerDir(serverName, options), "tokens.json");
|
|
42003
42106
|
}
|
|
42004
42107
|
function parseJsonPayload(serverName, payload, source) {
|
|
42005
42108
|
try {
|
|
@@ -44602,7 +44705,7 @@ async function shutdownOAuth(runtime = legacyRuntime) {
|
|
|
44602
44705
|
// ../node_modules/.bun/pi-mcp-adapter@2.32.1+04b0d7b0bc944965/node_modules/pi-mcp-adapter/mcp-bearer-store.ts
|
|
44603
44706
|
import { createHash as createHash4 } from "crypto";
|
|
44604
44707
|
import { createRequire as createRequire3 } from "module";
|
|
44605
|
-
import { dirname as dirname13, join as
|
|
44708
|
+
import { dirname as dirname13, join as join26 } from "path";
|
|
44606
44709
|
var require4 = createRequire3(import.meta.url);
|
|
44607
44710
|
var BEARER_SECRET_SERVICE = "pi-mcp-adapter.bearer";
|
|
44608
44711
|
var TEST_AUTH_STORE_ENV2 = "PI_MCP_ADAPTER_TEST_AUTH_STORE";
|
|
@@ -44704,7 +44807,7 @@ function loadKeyringNativeBindingFallback2(keyringRequire, platform3, arch2) {
|
|
|
44704
44807
|
for (const target of targets) {
|
|
44705
44808
|
try {
|
|
44706
44809
|
const packageJsonPath = keyringRequire.resolve(`${target.packageName}/package.json`);
|
|
44707
|
-
return keyringRequire(
|
|
44810
|
+
return keyringRequire(join26(dirname13(packageJsonPath), target.bindingFile));
|
|
44708
44811
|
} catch (error) {
|
|
44709
44812
|
lastError = error;
|
|
44710
44813
|
}
|
|
@@ -45316,7 +45419,7 @@ function humanizeName(name) {
|
|
|
45316
45419
|
}
|
|
45317
45420
|
|
|
45318
45421
|
// ../node_modules/.bun/pi-mcp-adapter@2.32.1+04b0d7b0bc944965/node_modules/pi-mcp-adapter/mcp-trace.ts
|
|
45319
|
-
import { appendFile as appendFile3, mkdir as
|
|
45422
|
+
import { appendFile as appendFile3, mkdir as mkdir18, writeFile as writeFile10 } from "fs/promises";
|
|
45320
45423
|
import { Buffer as Buffer3 } from "buffer";
|
|
45321
45424
|
import { dirname as dirname14, isAbsolute as isAbsolute2, resolve as resolve3 } from "path";
|
|
45322
45425
|
var MCP_TRACE_SCHEMA_VERSION = 1;
|
|
@@ -45385,10 +45488,10 @@ var McpTraceWriter = class {
|
|
|
45385
45488
|
await appendFile3(path7, data, appendOptions);
|
|
45386
45489
|
});
|
|
45387
45490
|
this.resetFile = options.writeFile ?? (async (path7, data, writeOptions) => {
|
|
45388
|
-
await
|
|
45491
|
+
await writeFile10(path7, data, writeOptions);
|
|
45389
45492
|
});
|
|
45390
45493
|
this.makeDirectory = options.mkdir ?? (async (path7) => {
|
|
45391
|
-
await
|
|
45494
|
+
await mkdir18(path7, { recursive: true });
|
|
45392
45495
|
return void 0;
|
|
45393
45496
|
});
|
|
45394
45497
|
this.fileReady = this.makeDirectory(dirname14(this.options.filePath), { recursive: true }).then(() => this.resetFile(this.options.filePath, "", { encoding: "utf8" })).catch(() => {
|
|
@@ -49171,7 +49274,7 @@ async function openMcpAuthPanel(state, pi, ctx, configOverridePath) {
|
|
|
49171
49274
|
// ../node_modules/.bun/pi-mcp-adapter@2.32.1+04b0d7b0bc944965/node_modules/pi-mcp-adapter/tool-registrar.ts
|
|
49172
49275
|
import { mkdtempSync, rmSync as rmSync2, writeFileSync as writeFileSync3 } from "fs";
|
|
49173
49276
|
import { tmpdir } from "os";
|
|
49174
|
-
import { join as
|
|
49277
|
+
import { join as join27 } from "path";
|
|
49175
49278
|
var MAX_BINARY_RESOURCE_BYTES = 10 * 1024 * 1024;
|
|
49176
49279
|
var MAX_SESSION_RESOURCE_BYTES = 100 * 1024 * 1024;
|
|
49177
49280
|
var MAX_SESSION_RESOURCE_FILES = 1e4;
|
|
@@ -49278,11 +49381,11 @@ function materializeBinaryResource(resource, scope) {
|
|
|
49278
49381
|
return omitBinaryResource(resource, "session resource limit reached");
|
|
49279
49382
|
}
|
|
49280
49383
|
try {
|
|
49281
|
-
session.directory ??= mkdtempSync(
|
|
49384
|
+
session.directory ??= mkdtempSync(join27(tmpdir(), "pi-mcp-resource-"));
|
|
49282
49385
|
} catch {
|
|
49283
49386
|
return omitBinaryResource(resource, "could not be saved");
|
|
49284
49387
|
}
|
|
49285
|
-
const filePath =
|
|
49388
|
+
const filePath = join27(session.directory, `resource-${++session.sequence}.bin`);
|
|
49286
49389
|
session.bytes += decodedBytes;
|
|
49287
49390
|
session.files += 1;
|
|
49288
49391
|
try {
|
|
@@ -49373,9 +49476,9 @@ function stringifyStructuredContent(value) {
|
|
|
49373
49476
|
|
|
49374
49477
|
// ../node_modules/.bun/pi-mcp-adapter@2.32.1+04b0d7b0bc944965/node_modules/pi-mcp-adapter/mcp-output-guard.ts
|
|
49375
49478
|
import { randomBytes as randomBytes4 } from "crypto";
|
|
49376
|
-
import { mkdtemp, rm as rm3, writeFile as
|
|
49479
|
+
import { mkdtemp, rm as rm3, writeFile as writeFile11 } from "fs/promises";
|
|
49377
49480
|
import { tmpdir as tmpdir2 } from "os";
|
|
49378
|
-
import { dirname as dirname16, join as
|
|
49481
|
+
import { dirname as dirname16, join as join28 } from "path";
|
|
49379
49482
|
var DEFAULT_MCP_OUTPUT_MAX_BYTES = 50 * 1024;
|
|
49380
49483
|
var DEFAULT_MCP_OUTPUT_MAX_LINES = 2e3;
|
|
49381
49484
|
var DEFAULT_MCP_DETAILS_MAX_BYTES = 16 * 1024;
|
|
@@ -49683,9 +49786,9 @@ function serializedObjectEntryBytes(key, value, hasPrevious) {
|
|
|
49683
49786
|
}
|
|
49684
49787
|
async function saveArtifact(kind, text) {
|
|
49685
49788
|
try {
|
|
49686
|
-
const dir = await mkdtemp(
|
|
49687
|
-
const path7 =
|
|
49688
|
-
await
|
|
49789
|
+
const dir = await mkdtemp(join28(tmpdir2(), "pi-mcp-output-"));
|
|
49790
|
+
const path7 = join28(dir, `${kind}-${randomBytes4(4).toString("hex")}.txt`);
|
|
49791
|
+
await writeFile11(path7, text, { encoding: "utf8", mode: 384 });
|
|
49689
49792
|
return { path: path7 };
|
|
49690
49793
|
} catch (error) {
|
|
49691
49794
|
return { error: error instanceof Error ? error.message : String(error) };
|
|
@@ -51331,7 +51434,7 @@ function sendText(res, status, text) {
|
|
|
51331
51434
|
// ../node_modules/.bun/pi-mcp-adapter@2.32.1+04b0d7b0bc944965/node_modules/pi-mcp-adapter/glimpse-ui.ts
|
|
51332
51435
|
import { existsSync as existsSync15 } from "fs";
|
|
51333
51436
|
import { execFileSync as execFileSync2 } from "child_process";
|
|
51334
|
-
import { join as
|
|
51437
|
+
import { join as join29, dirname as dirname17 } from "path";
|
|
51335
51438
|
import { platform as platform2 } from "os";
|
|
51336
51439
|
import { createRequire as createRequire4 } from "module";
|
|
51337
51440
|
var glimpseAvailable = null;
|
|
@@ -51353,20 +51456,20 @@ function getGlimpseBinaryPath() {
|
|
|
51353
51456
|
try {
|
|
51354
51457
|
const require7 = createRequire4(import.meta.url);
|
|
51355
51458
|
const glimpseuiPath = require7.resolve("glimpseui");
|
|
51356
|
-
const binaryPath =
|
|
51459
|
+
const binaryPath = join29(dirname17(glimpseuiPath), "glimpse");
|
|
51357
51460
|
if (existsSync15(binaryPath)) return binaryPath;
|
|
51358
51461
|
} catch {
|
|
51359
51462
|
}
|
|
51360
51463
|
try {
|
|
51361
51464
|
const globalRoot = execFileSync2("npm", ["root", "-g"], { encoding: "utf-8" }).trim();
|
|
51362
|
-
const binaryPath =
|
|
51465
|
+
const binaryPath = join29(globalRoot, "glimpseui", "src", "glimpse");
|
|
51363
51466
|
if (existsSync15(binaryPath)) return binaryPath;
|
|
51364
51467
|
} catch {
|
|
51365
51468
|
}
|
|
51366
51469
|
return null;
|
|
51367
51470
|
}
|
|
51368
51471
|
async function openGlimpseWindow(html, options) {
|
|
51369
|
-
const modulePath = resolvedBinaryPath ?
|
|
51472
|
+
const modulePath = resolvedBinaryPath ? join29(dirname17(resolvedBinaryPath), "glimpse.mjs") : "glimpseui";
|
|
51370
51473
|
const glimpse = await import(modulePath);
|
|
51371
51474
|
let active = true;
|
|
51372
51475
|
const win = glimpse.open(html, {
|
|
@@ -59156,7 +59259,7 @@ var pi_mcp_adapter_default = createMcpAdapter();
|
|
|
59156
59259
|
// src/managers/pi-manager.ts
|
|
59157
59260
|
async function getManagedPiMcpServers() {
|
|
59158
59261
|
try {
|
|
59159
|
-
const parsed = JSON.parse(await
|
|
59262
|
+
const parsed = JSON.parse(await readFile17(PI_MCP_CONFIG_PATH, "utf8"));
|
|
59160
59263
|
if (!isRecord2(parsed) || !isRecord2(parsed.mcpServers)) return {};
|
|
59161
59264
|
return Object.fromEntries(Object.entries(parsed.mcpServers).filter(
|
|
59162
59265
|
(entry) => isRecord2(entry[1]) && (typeof entry[1].command === "string" || typeof entry[1].url === "string")
|
|
@@ -59278,12 +59381,12 @@ var PiManager = class extends CodingAgentManager {
|
|
|
59278
59381
|
modelRuntime = null;
|
|
59279
59382
|
constructor(options) {
|
|
59280
59383
|
super(options);
|
|
59281
|
-
this.historyFilePath = options.historyFilePath ??
|
|
59384
|
+
this.historyFilePath = options.historyFilePath ?? join30(PI_HISTORY_DIR, `${Date.now()}.jsonl`);
|
|
59282
59385
|
this.historyFile = new CodexHistoryFile(this.historyFilePath);
|
|
59283
59386
|
this.initializeManager(this.processMessageInternal.bind(this));
|
|
59284
59387
|
}
|
|
59285
59388
|
async initialize() {
|
|
59286
|
-
await
|
|
59389
|
+
await mkdir19(dirname18(this.historyFilePath), { recursive: true });
|
|
59287
59390
|
}
|
|
59288
59391
|
getHistorySink() {
|
|
59289
59392
|
return this.historyFile;
|
|
@@ -59354,7 +59457,29 @@ var PiManager = class extends CodingAgentManager {
|
|
|
59354
59457
|
this.providerApiKey = credentials.apiKey;
|
|
59355
59458
|
const modelRegistry = new ModelRegistry(modelRuntime);
|
|
59356
59459
|
let defaultModel = DEFAULT_ASTER_MODEL;
|
|
59357
|
-
|
|
59460
|
+
const ollama = this.providerId === "ollama" ? readOllamaAuthEnv("pi", process.env) : null;
|
|
59461
|
+
if (ollama) {
|
|
59462
|
+
const models = await listOllamaModels(ollama);
|
|
59463
|
+
defaultModel = request.model || getDefaultOllamaModel(models) || "";
|
|
59464
|
+
const selected = models.find((model2) => model2.id === defaultModel);
|
|
59465
|
+
if (!selected?.contextWindow || !selected.capabilities?.includes("tools")) {
|
|
59466
|
+
throw new Error("Select an Ollama coding model with context length and tool support in its model details.");
|
|
59467
|
+
}
|
|
59468
|
+
registerPiProvider(modelRegistry, {
|
|
59469
|
+
providerId: "ollama",
|
|
59470
|
+
name: "Ollama",
|
|
59471
|
+
apiKey: ollama.apiKey,
|
|
59472
|
+
baseUrl: `${ollama.baseUrl}/v1`,
|
|
59473
|
+
models: models.filter((model2) => model2.contextWindow && model2.capabilities?.includes("tools")).map((model2) => ({
|
|
59474
|
+
id: model2.id,
|
|
59475
|
+
name: model2.displayName,
|
|
59476
|
+
contextWindow: model2.contextWindow,
|
|
59477
|
+
reasoning: model2.capabilities?.includes("thinking"),
|
|
59478
|
+
maxTokens: 16384,
|
|
59479
|
+
input: model2.capabilities?.includes("vision") ? ["text", "image"] : ["text"]
|
|
59480
|
+
}))
|
|
59481
|
+
});
|
|
59482
|
+
} else if (this.providerId === OPENCODE_GO_PROVIDER) {
|
|
59358
59483
|
const catalog = await fetchOpenCodeGoCatalog([request.model ?? DEFAULT_OPENCODE_GO_MODEL]);
|
|
59359
59484
|
const models = Object.entries(catalog.models);
|
|
59360
59485
|
defaultModel = catalog.models[DEFAULT_OPENCODE_GO_MODEL] ? DEFAULT_OPENCODE_GO_MODEL : models[0]?.[0] ?? DEFAULT_OPENCODE_GO_MODEL;
|
|
@@ -59414,7 +59539,7 @@ var PiManager = class extends CodingAgentManager {
|
|
|
59414
59539
|
}
|
|
59415
59540
|
const resourceLoader = new DefaultResourceLoader({
|
|
59416
59541
|
cwd: this.workingDirectory,
|
|
59417
|
-
agentDir:
|
|
59542
|
+
agentDir: join30(ENGINE_ENV.HOME_DIR, ".pi", "agent"),
|
|
59418
59543
|
extensionFactories,
|
|
59419
59544
|
appendSystemPrompt: [this.buildCombinedInstructions() ?? ""]
|
|
59420
59545
|
});
|
|
@@ -59530,14 +59655,14 @@ async function uploadAnalytics(endpoint, body) {
|
|
|
59530
59655
|
// src/analytics/analytics-record-buffer.ts
|
|
59531
59656
|
import {
|
|
59532
59657
|
appendFile as appendFile4,
|
|
59533
|
-
mkdir as
|
|
59534
|
-
readFile as
|
|
59658
|
+
mkdir as mkdir20,
|
|
59659
|
+
readFile as readFile18,
|
|
59535
59660
|
readdir as readdir7,
|
|
59536
59661
|
rename as rename4,
|
|
59537
59662
|
unlink as unlink3
|
|
59538
59663
|
} from "fs/promises";
|
|
59539
59664
|
import { existsSync as existsSync16, readFileSync as readFileSync7, readdirSync as readdirSync2 } from "fs";
|
|
59540
|
-
import { join as
|
|
59665
|
+
import { join as join31 } from "path";
|
|
59541
59666
|
var MAX_FAILED_RECORDS = 500;
|
|
59542
59667
|
var FLUSH_DEBOUNCE_MS = 15e3;
|
|
59543
59668
|
var MAX_UPLOADED_SEGMENTS = 50;
|
|
@@ -59549,7 +59674,7 @@ var AnalyticsRecordBuffer = class {
|
|
|
59549
59674
|
options.storageName,
|
|
59550
59675
|
...options.legacyStorageNames ?? []
|
|
59551
59676
|
];
|
|
59552
|
-
this.liveFile =
|
|
59677
|
+
this.liveFile = join31(ENGINE_DIR2, `${options.storageName}.jsonl`);
|
|
59553
59678
|
this.segmentFilePatterns = this.storageNames.map(
|
|
59554
59679
|
(storageName) => new RegExp(`^${storageName}\\.(\\d+)\\.jsonl$`)
|
|
59555
59680
|
);
|
|
@@ -59572,7 +59697,7 @@ var AnalyticsRecordBuffer = class {
|
|
|
59572
59697
|
if (this.recordIds.has(recordId)) return;
|
|
59573
59698
|
this.recordIds.add(recordId);
|
|
59574
59699
|
}
|
|
59575
|
-
const pending =
|
|
59700
|
+
const pending = mkdir20(ENGINE_DIR2, { recursive: true }).then(() => appendFile4(this.liveFile, `${JSON.stringify(record3)}
|
|
59576
59701
|
`, "utf-8")).catch((error) => {
|
|
59577
59702
|
console.error(
|
|
59578
59703
|
`[${this.options.storageName}] Append failed, will retry on flush:`,
|
|
@@ -59587,7 +59712,7 @@ var AnalyticsRecordBuffer = class {
|
|
|
59587
59712
|
if (!existsSync16(ENGINE_DIR2)) return [];
|
|
59588
59713
|
return readdirSync2(ENGINE_DIR2, { withFileTypes: true }).filter((entry) => entry.isFile() && this.storageNames.some(
|
|
59589
59714
|
(storageName) => entry.name === `${storageName}.jsonl` || entry.name.startsWith(`${storageName}.`) && (entry.name.endsWith(".jsonl") || entry.name.endsWith(`.jsonl${UPLOADED_SUFFIX}`))
|
|
59590
|
-
)).map(({ name }) => name).sort().flatMap((name) => this.parseRecords(readFileSync7(
|
|
59715
|
+
)).map(({ name }) => name).sort().flatMap((name) => this.parseRecords(readFileSync7(join31(ENGINE_DIR2, name), "utf-8"))).map((record3) => {
|
|
59591
59716
|
const recordId = this.options.getRecordId?.(record3);
|
|
59592
59717
|
if (recordId) this.recordIds.add(recordId);
|
|
59593
59718
|
return record3;
|
|
@@ -59622,8 +59747,8 @@ var AnalyticsRecordBuffer = class {
|
|
|
59622
59747
|
}
|
|
59623
59748
|
for (const storageName of this.storageNames) {
|
|
59624
59749
|
await rename4(
|
|
59625
|
-
|
|
59626
|
-
|
|
59750
|
+
join31(ENGINE_DIR2, `${storageName}.jsonl`),
|
|
59751
|
+
join31(ENGINE_DIR2, `${storageName}.${Date.now()}.jsonl`)
|
|
59627
59752
|
).catch(() => {
|
|
59628
59753
|
});
|
|
59629
59754
|
}
|
|
@@ -59633,7 +59758,7 @@ var AnalyticsRecordBuffer = class {
|
|
|
59633
59758
|
for (const entry of entries) {
|
|
59634
59759
|
if (!this.segmentFilePatterns.some((pattern) => pattern.test(entry))) continue;
|
|
59635
59760
|
try {
|
|
59636
|
-
await this.uploadSegment(
|
|
59761
|
+
await this.uploadSegment(join31(ENGINE_DIR2, entry));
|
|
59637
59762
|
flushed++;
|
|
59638
59763
|
} catch (error) {
|
|
59639
59764
|
failed++;
|
|
@@ -59662,14 +59787,14 @@ var AnalyticsRecordBuffer = class {
|
|
|
59662
59787
|
(storageName) => entry.startsWith(`${storageName}.`)
|
|
59663
59788
|
) && entry.endsWith(UPLOADED_SUFFIX)).sort();
|
|
59664
59789
|
for (const entry of uploaded.slice(0, -MAX_UPLOADED_SEGMENTS)) {
|
|
59665
|
-
await unlink3(
|
|
59790
|
+
await unlink3(join31(ENGINE_DIR2, entry)).catch(() => {
|
|
59666
59791
|
});
|
|
59667
59792
|
}
|
|
59668
59793
|
}
|
|
59669
59794
|
return { flushed, failed };
|
|
59670
59795
|
}
|
|
59671
59796
|
async uploadSegment(filePath) {
|
|
59672
|
-
const records = this.parseRecords(await
|
|
59797
|
+
const records = this.parseRecords(await readFile18(filePath, "utf-8"));
|
|
59673
59798
|
if (records.length > 0) await this.options.upload(records);
|
|
59674
59799
|
await rename4(filePath, `${filePath}${UPLOADED_SUFFIX}`).catch(() => {
|
|
59675
59800
|
});
|
|
@@ -60511,9 +60636,9 @@ var KeepAliveService = class _KeepAliveService {
|
|
|
60511
60636
|
var keepAliveService = new KeepAliveService();
|
|
60512
60637
|
|
|
60513
60638
|
// src/services/canvas-service.ts
|
|
60514
|
-
import { readdir as readdir8, readFile as
|
|
60639
|
+
import { readdir as readdir8, readFile as readFile20, stat as stat4 } from "fs/promises";
|
|
60515
60640
|
import { homedir as homedir13 } from "os";
|
|
60516
|
-
import { join as
|
|
60641
|
+
import { join as join32 } from "path";
|
|
60517
60642
|
|
|
60518
60643
|
// src/utils/contained-file.ts
|
|
60519
60644
|
import { realpath, stat as stat3 } from "fs/promises";
|
|
@@ -60539,9 +60664,9 @@ function fileRevision(content) {
|
|
|
60539
60664
|
}
|
|
60540
60665
|
|
|
60541
60666
|
// src/utils/revisioned-text-file.ts
|
|
60542
|
-
import { readFile as
|
|
60667
|
+
import { readFile as readFile19 } from "fs/promises";
|
|
60543
60668
|
async function writeRevisionedTextFile(filePath, content, expectedRevision) {
|
|
60544
|
-
const current = await
|
|
60669
|
+
const current = await readFile19(filePath, "utf8");
|
|
60545
60670
|
const revision = fileRevision(current);
|
|
60546
60671
|
if (revision !== expectedRevision) {
|
|
60547
60672
|
return {
|
|
@@ -60555,15 +60680,15 @@ async function writeRevisionedTextFile(filePath, content, expectedRevision) {
|
|
|
60555
60680
|
|
|
60556
60681
|
// src/services/canvas-service.ts
|
|
60557
60682
|
var GLOBAL_CANVAS_DIRECTORIES = [
|
|
60558
|
-
|
|
60559
|
-
|
|
60560
|
-
|
|
60683
|
+
join32(homedir13(), ".claude", "plans"),
|
|
60684
|
+
join32(process.env.XDG_DATA_HOME ?? join32(homedir13(), ".local", "share"), "opencode", "plans"),
|
|
60685
|
+
join32(homedir13(), ".replicas", "canvas")
|
|
60561
60686
|
];
|
|
60562
60687
|
async function canvasDirectories() {
|
|
60563
60688
|
const repositories = await gitService.listRepositories().catch(() => []);
|
|
60564
60689
|
return [
|
|
60565
60690
|
...GLOBAL_CANVAS_DIRECTORIES,
|
|
60566
|
-
...repositories.map((repository) =>
|
|
60691
|
+
...repositories.map((repository) => join32(repository.path, ".opencode", "plans"))
|
|
60567
60692
|
];
|
|
60568
60693
|
}
|
|
60569
60694
|
var CanvasService = class {
|
|
@@ -60588,7 +60713,7 @@ var CanvasService = class {
|
|
|
60588
60713
|
for (const entry of entries) {
|
|
60589
60714
|
if (entry.name.startsWith(".")) continue;
|
|
60590
60715
|
const filename = current.relativePath ? `${current.relativePath}/${entry.name}` : entry.name;
|
|
60591
|
-
const filePath =
|
|
60716
|
+
const filePath = join32(current.directory, entry.name);
|
|
60592
60717
|
if (entry.isDirectory()) {
|
|
60593
60718
|
pending.push({ directory: filePath, relativePath: filename });
|
|
60594
60719
|
continue;
|
|
@@ -60613,7 +60738,7 @@ var CanvasService = class {
|
|
|
60613
60738
|
if (!safe) return null;
|
|
60614
60739
|
const { kind, mimeType } = classifyCanvasFilename(safe);
|
|
60615
60740
|
for (const directory of await this.directories()) {
|
|
60616
|
-
const filePath =
|
|
60741
|
+
const filePath = join32(directory, safe);
|
|
60617
60742
|
let sizeBytes = 0;
|
|
60618
60743
|
let updatedAt = "";
|
|
60619
60744
|
try {
|
|
@@ -60634,7 +60759,7 @@ var CanvasService = class {
|
|
|
60634
60759
|
};
|
|
60635
60760
|
}
|
|
60636
60761
|
try {
|
|
60637
|
-
const bytes = await
|
|
60762
|
+
const bytes = await readFile20(filePath);
|
|
60638
60763
|
return { filename: safe, kind, sizeBytes, mimeType, updatedAt, bytes };
|
|
60639
60764
|
} catch {
|
|
60640
60765
|
continue;
|
|
@@ -60796,14 +60921,14 @@ async function reconcileCanvasItems(filenames) {
|
|
|
60796
60921
|
// src/services/upload-chat-transcripts.ts
|
|
60797
60922
|
import { createReadStream as createReadStream2 } from "fs";
|
|
60798
60923
|
import { createHash as createHash8 } from "crypto";
|
|
60799
|
-
import { readFile as
|
|
60800
|
-
import { basename as basename4, join as
|
|
60924
|
+
import { readFile as readFile21, readdir as readdir9, stat as stat5 } from "fs/promises";
|
|
60925
|
+
import { basename as basename4, join as join34 } from "path";
|
|
60801
60926
|
|
|
60802
60927
|
// src/services/chat/chat-senders.ts
|
|
60803
|
-
import { join as
|
|
60804
|
-
var CHAT_SENDERS_DIR =
|
|
60928
|
+
import { join as join33 } from "path";
|
|
60929
|
+
var CHAT_SENDERS_DIR = join33(ENGINE_DIR2, "chat-senders");
|
|
60805
60930
|
function chatMessageSendersFilePath(chatId) {
|
|
60806
|
-
return
|
|
60931
|
+
return join33(CHAT_SENDERS_DIR, `${chatId}.jsonl`);
|
|
60807
60932
|
}
|
|
60808
60933
|
function parseChatMessageSendersJsonl(content) {
|
|
60809
60934
|
return content.split("\n").flatMap((line) => {
|
|
@@ -60846,7 +60971,7 @@ async function flushAllChatTranscripts(chatsById = /* @__PURE__ */ new Map(), ca
|
|
|
60846
60971
|
const chat = chatsById.get(chatId);
|
|
60847
60972
|
if (!shouldFlushChatTranscript(dir, chat, chatsById)) continue;
|
|
60848
60973
|
tasks.push(
|
|
60849
|
-
uploadChatTranscript(chatId,
|
|
60974
|
+
uploadChatTranscript(chatId, join34(dir, entry), chat, capture).then((artifact) => {
|
|
60850
60975
|
flushed++;
|
|
60851
60976
|
if (artifact && capture) revisions.push(artifact);
|
|
60852
60977
|
}).catch((err) => {
|
|
@@ -60882,7 +61007,7 @@ async function uploadChatTranscript(chatId, filePath, chat, capture) {
|
|
|
60882
61007
|
}
|
|
60883
61008
|
try {
|
|
60884
61009
|
metadata.senders = parseChatMessageSendersJsonl(
|
|
60885
|
-
await
|
|
61010
|
+
await readFile21(chatMessageSendersFilePath(chatId), "utf-8")
|
|
60886
61011
|
);
|
|
60887
61012
|
} catch (error) {
|
|
60888
61013
|
if (!(error && typeof error === "object" && "code" in error && error.code === "ENOENT")) throw error;
|
|
@@ -60922,7 +61047,7 @@ async function uploadChatTranscript(chatId, filePath, chat, capture) {
|
|
|
60922
61047
|
// src/services/upload-engine-logs.ts
|
|
60923
61048
|
import { createReadStream as createReadStream3 } from "fs";
|
|
60924
61049
|
import { readdir as readdir10, stat as stat6 } from "fs/promises";
|
|
60925
|
-
import { join as
|
|
61050
|
+
import { join as join35 } from "path";
|
|
60926
61051
|
var MAX_ENGINE_LOG_FLUSH_SESSIONS = 10;
|
|
60927
61052
|
var MAX_ENGINE_LOG_FLUSH_BYTES = 5 * 1024 * 1024;
|
|
60928
61053
|
var ENGINE_LOG_FLUSH_TIMEOUT_MS = 2e4;
|
|
@@ -60951,7 +61076,7 @@ async function flushAllEngineLogs() {
|
|
|
60951
61076
|
const candidates = (await Promise.all(filenames.slice(0, MAX_ENGINE_LOG_FLUSH_SESSIONS).map(async (filename) => {
|
|
60952
61077
|
try {
|
|
60953
61078
|
const sessionId = filename.slice(0, -".log".length);
|
|
60954
|
-
const filePath =
|
|
61079
|
+
const filePath = join35(LOG_DIR, filename);
|
|
60955
61080
|
const fileStat = await runBeforeDeadline(() => stat6(filePath), deadline);
|
|
60956
61081
|
if (!fileStat.isFile()) {
|
|
60957
61082
|
skipped++;
|
|
@@ -61047,8 +61172,8 @@ async function uploadEngineLog(input, timeoutMs) {
|
|
|
61047
61172
|
}
|
|
61048
61173
|
|
|
61049
61174
|
// src/services/chat/fork-handoff.ts
|
|
61050
|
-
import { mkdir as
|
|
61051
|
-
import { join as
|
|
61175
|
+
import { mkdir as mkdir21, open as open3, writeFile as writeFile12 } from "fs/promises";
|
|
61176
|
+
import { join as join36 } from "path";
|
|
61052
61177
|
var EXCERPT_MAX_CHARS = 24e3;
|
|
61053
61178
|
var MAX_SANITIZED_SOURCE_BYTES = 32 * 1024 * 1024;
|
|
61054
61179
|
function unansweredRequest(blocks) {
|
|
@@ -61083,7 +61208,7 @@ function tailBlocks(blocks, maxChars) {
|
|
|
61083
61208
|
return { excerpt, truncated: start > 0 };
|
|
61084
61209
|
}
|
|
61085
61210
|
async function buildForkHandoff(input) {
|
|
61086
|
-
const rawHistoryPath =
|
|
61211
|
+
const rawHistoryPath = join36(HISTORY_DIR_BY_PROVIDER[input.sourceProvider], `${input.sourceChatId}.jsonl`);
|
|
61087
61212
|
const { content, truncated: sourceTruncated } = await readHistoryTail(rawHistoryPath, MAX_SANITIZED_SOURCE_BYTES);
|
|
61088
61213
|
let blocks = canonicalizeChatTranscriptBlocks(content, input.executionProvider, input.senders);
|
|
61089
61214
|
if (input.turnLimit !== void 0) {
|
|
@@ -61091,13 +61216,13 @@ async function buildForkHandoff(input) {
|
|
|
61091
61216
|
const start = blocks.findLastIndex((block) => block.startsWith("## User") && ++turns === input.turnLimit);
|
|
61092
61217
|
blocks = blocks.slice(Math.max(0, start));
|
|
61093
61218
|
}
|
|
61094
|
-
const forkDir =
|
|
61095
|
-
await
|
|
61096
|
-
const transcriptPath =
|
|
61219
|
+
const forkDir = join36(FORKS_DIR, input.targetChatId);
|
|
61220
|
+
await mkdir21(forkDir, { recursive: true });
|
|
61221
|
+
const transcriptPath = join36(forkDir, "source-transcript.md");
|
|
61097
61222
|
const header = sourceTruncated ? `_This file was generated from only the most recent ${MAX_SANITIZED_SOURCE_BYTES / 1024 / 1024} MB of the source chat.${input.turnLimit === void 0 ? ` The complete raw event log is at ${rawHistoryPath}; grep it for anything earlier.` : ""}_
|
|
61098
61223
|
|
|
61099
61224
|
` : "";
|
|
61100
|
-
await
|
|
61225
|
+
await writeFile12(transcriptPath, `${header}${blocks.join("\n\n")}
|
|
61101
61226
|
`, "utf-8");
|
|
61102
61227
|
const { excerpt, truncated } = tailBlocks(blocks, EXCERPT_MAX_CHARS);
|
|
61103
61228
|
return {
|
|
@@ -61235,13 +61360,13 @@ var ChatService = class {
|
|
|
61235
61360
|
persistPromise = null;
|
|
61236
61361
|
persistQueued = false;
|
|
61237
61362
|
async initialize() {
|
|
61238
|
-
await
|
|
61239
|
-
await
|
|
61240
|
-
await
|
|
61241
|
-
await
|
|
61242
|
-
await
|
|
61243
|
-
await
|
|
61244
|
-
await
|
|
61363
|
+
await mkdir22(ENGINE_DIR2, { recursive: true });
|
|
61364
|
+
await mkdir22(CLAUDE_HISTORY_DIR, { recursive: true });
|
|
61365
|
+
await mkdir22(RELAY_HISTORY_DIR, { recursive: true });
|
|
61366
|
+
await mkdir22(CODEX_HISTORY_DIR, { recursive: true });
|
|
61367
|
+
await mkdir22(CURSOR_HISTORY_DIR, { recursive: true });
|
|
61368
|
+
await mkdir22(OPENCODE_HISTORY_DIR, { recursive: true });
|
|
61369
|
+
await mkdir22(CHAT_SENDERS_DIR, { recursive: true });
|
|
61245
61370
|
const persisted = await this.loadChats();
|
|
61246
61371
|
for (const chat of persisted) {
|
|
61247
61372
|
const runtime = this.createRuntimeChat(chat);
|
|
@@ -61570,7 +61695,7 @@ var ChatService = class {
|
|
|
61570
61695
|
}
|
|
61571
61696
|
}
|
|
61572
61697
|
async readSenders(chatId) {
|
|
61573
|
-
return
|
|
61698
|
+
return readFile22(chatMessageSendersFilePath(chatId), "utf-8").then(parseChatMessageSendersJsonl).catch((error) => {
|
|
61574
61699
|
if (error && typeof error === "object" && "code" in error && error.code === "ENOENT") return [];
|
|
61575
61700
|
console.error("[ChatService] Failed to read sender records:", error);
|
|
61576
61701
|
return [];
|
|
@@ -61823,14 +61948,14 @@ var ChatService = class {
|
|
|
61823
61948
|
return descendants;
|
|
61824
61949
|
}
|
|
61825
61950
|
async deleteHistoryFile(persisted) {
|
|
61826
|
-
const historyPath =
|
|
61951
|
+
const historyPath = join37(HISTORY_DIR_BY_PROVIDER[persisted.provider], `${persisted.id}.jsonl`);
|
|
61827
61952
|
await Promise.all([
|
|
61828
61953
|
historyPath,
|
|
61829
61954
|
`${historyPath}.pages.jsonl`,
|
|
61830
61955
|
`${historyPath}.pages.index.json`
|
|
61831
61956
|
].map((path7) => rm4(path7, { force: true })));
|
|
61832
61957
|
await rm4(chatMessageSendersFilePath(persisted.id), { force: true });
|
|
61833
|
-
await rm4(
|
|
61958
|
+
await rm4(join37(FORKS_DIR, persisted.id), { recursive: true, force: true });
|
|
61834
61959
|
}
|
|
61835
61960
|
/** Resolves once the target chat exists; the handoff and its first turn run in the background. */
|
|
61836
61961
|
async forkChat(sourceChatId, request, trigger = "manual", reason) {
|
|
@@ -62098,7 +62223,7 @@ var ChatService = class {
|
|
|
62098
62223
|
}
|
|
62099
62224
|
const baseProvider = getChatExecutionProvider(persisted);
|
|
62100
62225
|
const additionalInstructions = persisted.provider === "relay" ? buildRelayInstructions(this.workingDirectory) : void 0;
|
|
62101
|
-
const historyFilePath =
|
|
62226
|
+
const historyFilePath = join37(HISTORY_DIR_BY_PROVIDER[persisted.provider], `${persisted.id}.jsonl`);
|
|
62102
62227
|
const managerOptions = {
|
|
62103
62228
|
provider: baseProvider,
|
|
62104
62229
|
workingDirectory: this.workingDirectory,
|
|
@@ -62344,7 +62469,7 @@ var ChatService = class {
|
|
|
62344
62469
|
chat.quotaExhaustion = null;
|
|
62345
62470
|
uploadChatTranscript(
|
|
62346
62471
|
chatId,
|
|
62347
|
-
|
|
62472
|
+
join37(HISTORY_DIR_BY_PROVIDER[chat.persisted.provider], `${chatId}.jsonl`),
|
|
62348
62473
|
this.toTranscriptSource(chat)
|
|
62349
62474
|
).catch((err) => {
|
|
62350
62475
|
console.error("[ChatService] Failed to upload chat transcript:", { chatId, err });
|
|
@@ -62395,7 +62520,7 @@ var ChatService = class {
|
|
|
62395
62520
|
}
|
|
62396
62521
|
async loadChats() {
|
|
62397
62522
|
try {
|
|
62398
|
-
const content = await
|
|
62523
|
+
const content = await readFile22(CHATS_FILE, "utf-8");
|
|
62399
62524
|
return parsePersistedChatsContent(content);
|
|
62400
62525
|
} catch (error) {
|
|
62401
62526
|
if (error && typeof error === "object" && "code" in error && error.code === "ENOENT") {
|
|
@@ -62410,7 +62535,7 @@ var ChatService = class {
|
|
|
62410
62535
|
console.error("[ChatService] Failed to quarantine corrupt chats file:", renameError);
|
|
62411
62536
|
}
|
|
62412
62537
|
try {
|
|
62413
|
-
const backupContent = await
|
|
62538
|
+
const backupContent = await readFile22(CHATS_BACKUP_FILE, "utf-8");
|
|
62414
62539
|
return parsePersistedChatsContent(backupContent);
|
|
62415
62540
|
} catch (backupError) {
|
|
62416
62541
|
if (backupError && typeof backupError === "object" && "code" in backupError && backupError.code === "ENOENT") {
|
|
@@ -62513,14 +62638,14 @@ var ChatService = class {
|
|
|
62513
62638
|
|
|
62514
62639
|
// src/services/repo-file-service.ts
|
|
62515
62640
|
import { execFile as execFile7 } from "child_process";
|
|
62516
|
-
import { readFile as
|
|
62641
|
+
import { readFile as readFile23 } from "fs/promises";
|
|
62517
62642
|
import { extname as extname3 } from "path";
|
|
62518
62643
|
|
|
62519
62644
|
// src/services/language-server-service.ts
|
|
62520
62645
|
import { spawn as spawn9 } from "child_process";
|
|
62521
62646
|
import { existsSync as existsSync17, readFileSync as readFileSync8 } from "fs";
|
|
62522
62647
|
import { createRequire as createRequire6 } from "module";
|
|
62523
|
-
import { delimiter as delimiter2, dirname as dirname19, join as
|
|
62648
|
+
import { delimiter as delimiter2, dirname as dirname19, join as join38, relative as relative2 } from "path";
|
|
62524
62649
|
import { setTimeout as setTimeout2 } from "timers/promises";
|
|
62525
62650
|
import { fileURLToPath as fileURLToPath6, pathToFileURL } from "url";
|
|
62526
62651
|
import { createMessageConnection, StreamMessageReader, StreamMessageWriter } from "vscode-jsonrpc/node.js";
|
|
@@ -62639,7 +62764,7 @@ var LanguageServerService = class {
|
|
|
62639
62764
|
if (config.package && config.bin) command = process.execPath;
|
|
62640
62765
|
else if (config.command) {
|
|
62641
62766
|
const commandName = config.command;
|
|
62642
|
-
command = process.env.PATH?.split(delimiter2).map((directory) =>
|
|
62767
|
+
command = process.env.PATH?.split(delimiter2).map((directory) => join38(directory, commandName)).find(existsSync17);
|
|
62643
62768
|
}
|
|
62644
62769
|
const args = config.package && config.bin ? [packageBin(config.package, config.bin), ...config.args] : config.args;
|
|
62645
62770
|
if (!command) return null;
|
|
@@ -62810,7 +62935,7 @@ var RepoFileService = class {
|
|
|
62810
62935
|
sizeBytes,
|
|
62811
62936
|
binary: true,
|
|
62812
62937
|
tooLarge: false,
|
|
62813
|
-
base64: (await
|
|
62938
|
+
base64: (await readFile23(fullPath)).toString("base64"),
|
|
62814
62939
|
mimeType
|
|
62815
62940
|
};
|
|
62816
62941
|
}
|
|
@@ -62835,7 +62960,7 @@ var RepoFileService = class {
|
|
|
62835
62960
|
tooLarge: true
|
|
62836
62961
|
};
|
|
62837
62962
|
}
|
|
62838
|
-
const content = await
|
|
62963
|
+
const content = await readFile23(fullPath, "utf-8");
|
|
62839
62964
|
return {
|
|
62840
62965
|
repoName,
|
|
62841
62966
|
path: filePath,
|
|
@@ -62867,7 +62992,7 @@ var RepoFileService = class {
|
|
|
62867
62992
|
async inspectSymbol(repoName, filePath, line, character, action) {
|
|
62868
62993
|
const resolved = await this.resolveFile(repoName, filePath);
|
|
62869
62994
|
if (!resolved || line < 1 || character < 0 || isBinaryExtension(filePath)) return null;
|
|
62870
|
-
const content = await
|
|
62995
|
+
const content = await readFile23(resolved.fullPath, "utf8");
|
|
62871
62996
|
const sourceLine = content.split("\n")[line - 1];
|
|
62872
62997
|
if (sourceLine === void 0) return null;
|
|
62873
62998
|
const symbolMatch = Array.from(sourceLine.matchAll(/[\p{L}_$][\p{L}\p{N}_$]*/gu)).find((match) => character >= match.index && character <= match.index + match[0].length);
|
|
@@ -62980,21 +63105,21 @@ var RepoFileService = class {
|
|
|
62980
63105
|
// src/v1-routes.ts
|
|
62981
63106
|
import { Hono } from "hono";
|
|
62982
63107
|
import { z as z6 } from "zod";
|
|
62983
|
-
import { readdir as readdir12, stat as stat7, readFile as
|
|
62984
|
-
import { join as
|
|
63108
|
+
import { readdir as readdir12, stat as stat7, readFile as readFile26 } from "fs/promises";
|
|
63109
|
+
import { join as join41, resolve as resolve5 } from "path";
|
|
62985
63110
|
|
|
62986
63111
|
// src/services/warm-hooks-service.ts
|
|
62987
63112
|
import { spawn as spawn10 } from "child_process";
|
|
62988
|
-
import { readFile as
|
|
63113
|
+
import { readFile as readFile25 } from "fs/promises";
|
|
62989
63114
|
import { existsSync as existsSync18 } from "fs";
|
|
62990
|
-
import { join as
|
|
63115
|
+
import { join as join40 } from "path";
|
|
62991
63116
|
|
|
62992
63117
|
// src/services/warm-hook-logs-service.ts
|
|
62993
|
-
import { mkdir as
|
|
63118
|
+
import { mkdir as mkdir23, readFile as readFile24, writeFile as writeFile13, readdir as readdir11, appendFile as appendFile6, unlink as unlink4 } from "fs/promises";
|
|
62994
63119
|
import { homedir as homedir14 } from "os";
|
|
62995
|
-
import { join as
|
|
62996
|
-
var LOGS_DIR2 =
|
|
62997
|
-
var CURRENT_RUN_LOG =
|
|
63120
|
+
import { join as join39 } from "path";
|
|
63121
|
+
var LOGS_DIR2 = join39(homedir14(), ".replicas", "warm-hook-logs");
|
|
63122
|
+
var CURRENT_RUN_LOG = join39(LOGS_DIR2, "current-run.log");
|
|
62998
63123
|
var GLOBAL_FILENAME = "global.json";
|
|
62999
63124
|
function withPreview2(stored) {
|
|
63000
63125
|
const preview = buildHookOutputPreview(stored.output);
|
|
@@ -63002,7 +63127,7 @@ function withPreview2(stored) {
|
|
|
63002
63127
|
}
|
|
63003
63128
|
var WarmHookLogsService = class {
|
|
63004
63129
|
async ensureDir() {
|
|
63005
|
-
await
|
|
63130
|
+
await mkdir23(LOGS_DIR2, { recursive: true });
|
|
63006
63131
|
}
|
|
63007
63132
|
async saveGlobalHookLog(entry) {
|
|
63008
63133
|
await this.ensureDir();
|
|
@@ -63011,7 +63136,7 @@ var WarmHookLogsService = class {
|
|
|
63011
63136
|
hookName: "organization",
|
|
63012
63137
|
...entry
|
|
63013
63138
|
};
|
|
63014
|
-
await
|
|
63139
|
+
await writeFile13(join39(LOGS_DIR2, GLOBAL_FILENAME), `${JSON.stringify(log, null, 2)}
|
|
63015
63140
|
`, "utf-8");
|
|
63016
63141
|
}
|
|
63017
63142
|
async saveEnvironmentHookLog(entry) {
|
|
@@ -63021,7 +63146,7 @@ var WarmHookLogsService = class {
|
|
|
63021
63146
|
hookName: "environment",
|
|
63022
63147
|
...entry
|
|
63023
63148
|
};
|
|
63024
|
-
await
|
|
63149
|
+
await writeFile13(join39(LOGS_DIR2, ENVIRONMENT_HOOK_LOG_FILENAME), `${JSON.stringify(log, null, 2)}
|
|
63025
63150
|
`, "utf-8");
|
|
63026
63151
|
}
|
|
63027
63152
|
async saveRepoHookLog(repoName, entry) {
|
|
@@ -63031,7 +63156,7 @@ var WarmHookLogsService = class {
|
|
|
63031
63156
|
hookName: repoName,
|
|
63032
63157
|
...entry
|
|
63033
63158
|
};
|
|
63034
|
-
await
|
|
63159
|
+
await writeFile13(join39(LOGS_DIR2, repoHookLogFilename(repoName)), `${JSON.stringify(log, null, 2)}
|
|
63035
63160
|
`, "utf-8");
|
|
63036
63161
|
}
|
|
63037
63162
|
async getAllLogs() {
|
|
@@ -63050,7 +63175,7 @@ var WarmHookLogsService = class {
|
|
|
63050
63175
|
continue;
|
|
63051
63176
|
}
|
|
63052
63177
|
try {
|
|
63053
|
-
const raw = await
|
|
63178
|
+
const raw = await readFile24(join39(LOGS_DIR2, file), "utf-8");
|
|
63054
63179
|
const stored = JSON.parse(raw);
|
|
63055
63180
|
logs.push(withPreview2(stored));
|
|
63056
63181
|
} catch {
|
|
@@ -63079,7 +63204,7 @@ var WarmHookLogsService = class {
|
|
|
63079
63204
|
}
|
|
63080
63205
|
async getCurrentRunLog() {
|
|
63081
63206
|
try {
|
|
63082
|
-
return await
|
|
63207
|
+
return await readFile24(CURRENT_RUN_LOG, "utf-8");
|
|
63083
63208
|
} catch (err) {
|
|
63084
63209
|
if (err.code === "ENOENT") return null;
|
|
63085
63210
|
throw err;
|
|
@@ -63088,7 +63213,7 @@ var WarmHookLogsService = class {
|
|
|
63088
63213
|
async getFullOutput(hookType, hookName) {
|
|
63089
63214
|
const filename = hookType === "global" ? GLOBAL_FILENAME : hookType === "environment" ? ENVIRONMENT_HOOK_LOG_FILENAME : repoHookLogFilename(hookName);
|
|
63090
63215
|
try {
|
|
63091
|
-
const raw = await
|
|
63216
|
+
const raw = await readFile24(join39(LOGS_DIR2, filename), "utf-8");
|
|
63092
63217
|
const stored = JSON.parse(raw);
|
|
63093
63218
|
if (stored.hookType !== hookType || stored.hookName !== hookName) {
|
|
63094
63219
|
return null;
|
|
@@ -63107,12 +63232,12 @@ var warmHookLogsService = new WarmHookLogsService();
|
|
|
63107
63232
|
// src/services/warm-hooks-service.ts
|
|
63108
63233
|
async function readRepoWarmHook(repoPath) {
|
|
63109
63234
|
for (const filename of REPLICAS_CONFIG_FILENAMES) {
|
|
63110
|
-
const configPath =
|
|
63235
|
+
const configPath = join40(repoPath, filename);
|
|
63111
63236
|
if (!existsSync18(configPath)) {
|
|
63112
63237
|
continue;
|
|
63113
63238
|
}
|
|
63114
63239
|
try {
|
|
63115
|
-
const raw = await
|
|
63240
|
+
const raw = await readFile25(configPath, "utf-8");
|
|
63116
63241
|
const config = parseReplicasConfigString(raw, filename);
|
|
63117
63242
|
if (!config.warmHook) {
|
|
63118
63243
|
return null;
|
|
@@ -64441,7 +64566,7 @@ data: ${JSON.stringify("Terminal session not found")}
|
|
|
64441
64566
|
const logFiles = files.filter((f) => f.endsWith(".log"));
|
|
64442
64567
|
const sessions = await Promise.all(
|
|
64443
64568
|
logFiles.map(async (filename) => {
|
|
64444
|
-
const filePath =
|
|
64569
|
+
const filePath = join41(LOG_DIR, filename);
|
|
64445
64570
|
const fileStat = await stat7(filePath);
|
|
64446
64571
|
const sessionId = filename.replace(/\.log$/, "");
|
|
64447
64572
|
return {
|
|
@@ -64476,7 +64601,7 @@ data: ${JSON.stringify("Terminal session not found")}
|
|
|
64476
64601
|
}
|
|
64477
64602
|
let content;
|
|
64478
64603
|
try {
|
|
64479
|
-
content = await
|
|
64604
|
+
content = await readFile26(filePath, "utf-8");
|
|
64480
64605
|
} catch {
|
|
64481
64606
|
return c.json(jsonError("Log session not found"), 404);
|
|
64482
64607
|
}
|
|
@@ -64547,7 +64672,7 @@ var HeartbeatService = class _HeartbeatService {
|
|
|
64547
64672
|
var heartbeatService = new HeartbeatService();
|
|
64548
64673
|
|
|
64549
64674
|
// src/services/workspace-sdk-service.ts
|
|
64550
|
-
import { cp, mkdir as
|
|
64675
|
+
import { cp, mkdir as mkdir24 } from "fs/promises";
|
|
64551
64676
|
import { dirname as dirname20, resolve as resolve6 } from "path";
|
|
64552
64677
|
import { fileURLToPath as fileURLToPath7 } from "url";
|
|
64553
64678
|
async function installWorkspaceSdk() {
|
|
@@ -64557,7 +64682,7 @@ async function installWorkspaceSdk() {
|
|
|
64557
64682
|
"/tmp/node_modules/@replicas/sdk"
|
|
64558
64683
|
];
|
|
64559
64684
|
await Promise.all(targets.map(async (target) => {
|
|
64560
|
-
await
|
|
64685
|
+
await mkdir24(target, { recursive: true });
|
|
64561
64686
|
await cp(source, target, { recursive: true, force: true });
|
|
64562
64687
|
}));
|
|
64563
64688
|
}
|