@slock-ai/daemon 0.48.0-play.20260513145259 → 0.48.1
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/chat-bridge.js +58 -3
- package/dist/{chunk-DOUUVDEA.js → chunk-RDRY2MW2.js} +103 -514
- package/dist/cli/index.js +0 -1
- package/dist/core.js +2 -6
- package/dist/index.js +3 -5
- package/package.json +1 -2
package/dist/chat-bridge.js
CHANGED
|
@@ -169,16 +169,64 @@ function formatHistoryMessageLine(message) {
|
|
|
169
169
|
}
|
|
170
170
|
|
|
171
171
|
// src/chatBridgeSendRequest.ts
|
|
172
|
-
import { randomUUID } from "crypto";
|
|
172
|
+
import { createHash, randomUUID } from "crypto";
|
|
173
|
+
var DEFAULT_SEND_RETRY_FINGERPRINT_TTL_MS = 10 * 60 * 1e3;
|
|
174
|
+
var ambiguousSendKeys = /* @__PURE__ */ new Map();
|
|
175
|
+
function pruneExpiredAmbiguousSendKeys(nowMs) {
|
|
176
|
+
for (const [fingerprint, entry] of ambiguousSendKeys) {
|
|
177
|
+
if (entry.expiresAt <= nowMs) {
|
|
178
|
+
ambiguousSendKeys.delete(fingerprint);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
function resolveIdempotencyKey(opts) {
|
|
183
|
+
if (opts.idempotencyKey) return opts.idempotencyKey;
|
|
184
|
+
if (!opts.retryFingerprint) return randomUUID();
|
|
185
|
+
pruneExpiredAmbiguousSendKeys(opts.nowMs);
|
|
186
|
+
const existing = ambiguousSendKeys.get(opts.retryFingerprint);
|
|
187
|
+
if (existing && existing.expiresAt > opts.nowMs) {
|
|
188
|
+
return existing.idempotencyKey;
|
|
189
|
+
}
|
|
190
|
+
return randomUUID();
|
|
191
|
+
}
|
|
192
|
+
function rememberAmbiguousSendKey(retryFingerprint, idempotencyKey, nowMs, ttlMs) {
|
|
193
|
+
if (!retryFingerprint) return;
|
|
194
|
+
pruneExpiredAmbiguousSendKeys(nowMs);
|
|
195
|
+
ambiguousSendKeys.set(retryFingerprint, {
|
|
196
|
+
idempotencyKey,
|
|
197
|
+
expiresAt: nowMs + ttlMs
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
function clearAmbiguousSendKey(retryFingerprint) {
|
|
201
|
+
if (!retryFingerprint) return;
|
|
202
|
+
ambiguousSendKeys.delete(retryFingerprint);
|
|
203
|
+
}
|
|
204
|
+
function buildSendRetryFingerprint(input) {
|
|
205
|
+
const attachmentIds = input.attachmentIds ?? [];
|
|
206
|
+
const hash = createHash("sha256").update(JSON.stringify({
|
|
207
|
+
target: input.target,
|
|
208
|
+
content: input.content,
|
|
209
|
+
attachmentIds
|
|
210
|
+
})).digest("hex");
|
|
211
|
+
return `send_message:${hash}`;
|
|
212
|
+
}
|
|
173
213
|
async function executeRetrySafeSendRequest(url, buildInit, {
|
|
174
214
|
fetchImpl,
|
|
175
215
|
target,
|
|
176
216
|
timeoutMs = DEFAULT_CHAT_BRIDGE_TOOL_TIMEOUT_MS,
|
|
177
217
|
now = () => Date.now(),
|
|
178
218
|
warn = (message) => logger.warn(message),
|
|
179
|
-
idempotencyKey
|
|
219
|
+
idempotencyKey: explicitIdempotencyKey,
|
|
220
|
+
retryFingerprint,
|
|
221
|
+
retryFingerprintTtlMs = DEFAULT_SEND_RETRY_FINGERPRINT_TTL_MS
|
|
180
222
|
}) {
|
|
181
223
|
let lastError;
|
|
224
|
+
const idempotencyKey = resolveIdempotencyKey({
|
|
225
|
+
idempotencyKey: explicitIdempotencyKey,
|
|
226
|
+
retryFingerprint,
|
|
227
|
+
retryFingerprintTtlMs,
|
|
228
|
+
nowMs: now()
|
|
229
|
+
});
|
|
182
230
|
for (let attempt = 1; attempt <= 2; attempt += 1) {
|
|
183
231
|
try {
|
|
184
232
|
const result = await executeJsonRequest(
|
|
@@ -193,6 +241,7 @@ async function executeRetrySafeSendRequest(url, buildInit, {
|
|
|
193
241
|
warn
|
|
194
242
|
}
|
|
195
243
|
);
|
|
244
|
+
clearAmbiguousSendKey(retryFingerprint);
|
|
196
245
|
return {
|
|
197
246
|
...result,
|
|
198
247
|
idempotencyKey,
|
|
@@ -206,6 +255,7 @@ async function executeRetrySafeSendRequest(url, buildInit, {
|
|
|
206
255
|
);
|
|
207
256
|
}
|
|
208
257
|
}
|
|
258
|
+
rememberAmbiguousSendKey(retryFingerprint, idempotencyKey, now(), retryFingerprintTtlMs);
|
|
209
259
|
throw lastError;
|
|
210
260
|
}
|
|
211
261
|
function describeRetryReason(error) {
|
|
@@ -578,7 +628,12 @@ if (!deprecatedShimMode && !runtimeActionsOnlyMode) {
|
|
|
578
628
|
}),
|
|
579
629
|
{
|
|
580
630
|
target,
|
|
581
|
-
fetchImpl: bridgeFetch
|
|
631
|
+
fetchImpl: bridgeFetch,
|
|
632
|
+
retryFingerprint: buildSendRetryFingerprint({
|
|
633
|
+
target,
|
|
634
|
+
content,
|
|
635
|
+
attachmentIds: attachment_ids
|
|
636
|
+
})
|
|
582
637
|
}
|
|
583
638
|
);
|
|
584
639
|
if (!res.ok) {
|
|
@@ -11,11 +11,11 @@ import {
|
|
|
11
11
|
} from "./chunk-B7XIMLOT.js";
|
|
12
12
|
|
|
13
13
|
// src/core.ts
|
|
14
|
-
import
|
|
14
|
+
import path15 from "path";
|
|
15
15
|
import os7 from "os";
|
|
16
16
|
import { createRequire } from "module";
|
|
17
17
|
import { accessSync } from "fs";
|
|
18
|
-
import { fileURLToPath
|
|
18
|
+
import { fileURLToPath } from "url";
|
|
19
19
|
|
|
20
20
|
// ../shared/src/tracing/index.ts
|
|
21
21
|
var DEFAULT_TRACE_FLAGS = "00";
|
|
@@ -725,7 +725,6 @@ var SERVER_CAPABILITY_MATRIX = {
|
|
|
725
725
|
var RUNTIMES = [
|
|
726
726
|
{ id: "claude", displayName: "Claude Code", binary: "claude", supported: true },
|
|
727
727
|
{ id: "codex", displayName: "Codex CLI", binary: "codex", supported: true },
|
|
728
|
-
{ id: "pi", displayName: "Pi", binary: "pi", supported: true },
|
|
729
728
|
{ id: "kimi", displayName: "Kimi CLI", binary: "kimi", supported: true },
|
|
730
729
|
{ id: "copilot", displayName: "Copilot CLI", binary: "copilot", supported: true },
|
|
731
730
|
{ id: "cursor", displayName: "Cursor CLI", binary: "cursor-agent", supported: true },
|
|
@@ -767,10 +766,10 @@ var DISPLAY_PLAN_CONFIG = {
|
|
|
767
766
|
};
|
|
768
767
|
|
|
769
768
|
// src/agentProcessManager.ts
|
|
770
|
-
import { mkdirSync as
|
|
769
|
+
import { mkdirSync as mkdirSync4, readdirSync as readdirSync3, statSync as statSync2, writeFileSync as writeFileSync7 } from "fs";
|
|
771
770
|
import { mkdir, writeFile, access, readdir as readdir2, stat as stat2, readFile, rm as rm2 } from "fs/promises";
|
|
772
771
|
import { createHash as createHash2 } from "crypto";
|
|
773
|
-
import
|
|
772
|
+
import path11 from "path";
|
|
774
773
|
import os5 from "os";
|
|
775
774
|
|
|
776
775
|
// src/drivers/claude.ts
|
|
@@ -1177,17 +1176,6 @@ Keep the user informed. They cannot see your internal reasoning, so:
|
|
|
1177
1176
|
- For multi-step work, send short progress updates (e.g. "Working on step 2/3\u2026").
|
|
1178
1177
|
- When done, summarize the result.
|
|
1179
1178
|
- Keep updates concise \u2014 one or two sentences. Don't flood the chat.
|
|
1180
|
-
- For long answers where users need the conclusion first but details still matter, put the conclusion and next action outside any collapse, then use sanitized HTML details blocks for optional depth:
|
|
1181
|
-
|
|
1182
|
-
\`\`\`html
|
|
1183
|
-
<details>
|
|
1184
|
-
<summary>Evidence, logs, or edge cases</summary>
|
|
1185
|
-
|
|
1186
|
-
Detailed notes go here.
|
|
1187
|
-
</details>
|
|
1188
|
-
\`\`\`
|
|
1189
|
-
|
|
1190
|
-
Do not hide the main recommendation, blocker, or required action inside \`<details>\`; only fold supporting evidence, logs, alternatives, or extended rationale.
|
|
1191
1179
|
|
|
1192
1180
|
### Conversation etiquette
|
|
1193
1181
|
|
|
@@ -1321,19 +1309,6 @@ function buildMcpSystemPrompt(config, opts) {
|
|
|
1321
1309
|
return buildPrompt(config, "mcp", opts);
|
|
1322
1310
|
}
|
|
1323
1311
|
|
|
1324
|
-
// src/authEnv.ts
|
|
1325
|
-
var DAEMON_API_KEY_ENV = "SLOCK_MACHINE_API_KEY";
|
|
1326
|
-
var SLOCK_AGENT_TOKEN_ENV = "SLOCK_AGENT_TOKEN";
|
|
1327
|
-
function scrubDaemonAuthEnv(env) {
|
|
1328
|
-
delete env[DAEMON_API_KEY_ENV];
|
|
1329
|
-
return env;
|
|
1330
|
-
}
|
|
1331
|
-
function scrubDaemonChildEnv(env) {
|
|
1332
|
-
delete env[DAEMON_API_KEY_ENV];
|
|
1333
|
-
delete env[SLOCK_AGENT_TOKEN_ENV];
|
|
1334
|
-
return env;
|
|
1335
|
-
}
|
|
1336
|
-
|
|
1337
1312
|
// src/drivers/cliTransport.ts
|
|
1338
1313
|
var shellSingleQuote = (value) => `'${value.replace(/'/g, `'\\''`)}'`;
|
|
1339
1314
|
function runtimeContextEnv(config) {
|
|
@@ -1387,7 +1362,7 @@ exec ${shellSingleQuote(process.execPath)} ${shellSingleQuote(ctx.slockCliPath)}
|
|
|
1387
1362
|
SLOCK_AGENT_TOKEN_FILE: tokenFile,
|
|
1388
1363
|
PATH: `${slockDir}${path.delimiter}${process.env.PATH ?? ""}`
|
|
1389
1364
|
};
|
|
1390
|
-
|
|
1365
|
+
delete spawnEnv.SLOCK_AGENT_TOKEN;
|
|
1391
1366
|
return {
|
|
1392
1367
|
slockDir,
|
|
1393
1368
|
tokenFile,
|
|
@@ -1424,7 +1399,7 @@ function resolveCommandOnWindows(command, env, execFileSyncFn) {
|
|
|
1424
1399
|
}
|
|
1425
1400
|
function resolveCommandOnPath(command, deps = {}) {
|
|
1426
1401
|
const platform = deps.platform ?? process.platform;
|
|
1427
|
-
const env =
|
|
1402
|
+
const env = deps.env ?? process.env;
|
|
1428
1403
|
const execFileSyncFn = deps.execFileSyncFn ?? execFileSync;
|
|
1429
1404
|
if (platform === "win32") {
|
|
1430
1405
|
return resolveCommandOnWindows(command, env, execFileSyncFn);
|
|
@@ -1449,7 +1424,7 @@ function firstExistingPath(candidates, deps = {}) {
|
|
|
1449
1424
|
return null;
|
|
1450
1425
|
}
|
|
1451
1426
|
function readCommandVersion(command, args = [], deps = {}) {
|
|
1452
|
-
const env =
|
|
1427
|
+
const env = deps.env ?? process.env;
|
|
1453
1428
|
const execFileSyncFn = deps.execFileSyncFn ?? execFileSync;
|
|
1454
1429
|
try {
|
|
1455
1430
|
const output = normalizeExecOutput(execFileSyncFn(command, [...args, "--version"], {
|
|
@@ -1890,21 +1865,18 @@ function resolveCodexSpawn(commandArgs, deps = {}) {
|
|
|
1890
1865
|
if ((deps.platform ?? process.platform) !== "win32") {
|
|
1891
1866
|
return { command: resolveCodexCommand(deps) ?? "codex", args: commandArgs };
|
|
1892
1867
|
}
|
|
1893
|
-
const execSyncFn = deps.execSyncFn ?? execSync;
|
|
1894
|
-
const existsSyncFn = deps.existsSyncFn ?? existsSync3;
|
|
1895
|
-
const env = scrubDaemonChildEnv({ ...deps.env ?? process.env });
|
|
1896
1868
|
let codexEntry = null;
|
|
1897
1869
|
try {
|
|
1898
|
-
const globalRoot =
|
|
1870
|
+
const globalRoot = execSync("npm root -g", { encoding: "utf8", stdio: ["pipe", "pipe", "pipe"] }).trim();
|
|
1899
1871
|
const candidate = path4.join(globalRoot, "@openai", "codex", "bin", "codex.js");
|
|
1900
|
-
if (
|
|
1872
|
+
if (existsSync3(candidate)) codexEntry = candidate;
|
|
1901
1873
|
} catch {
|
|
1902
1874
|
}
|
|
1903
1875
|
if (!codexEntry) {
|
|
1904
1876
|
try {
|
|
1905
|
-
const cmdPath =
|
|
1877
|
+
const cmdPath = execSync("where codex", { encoding: "utf8", stdio: ["pipe", "pipe", "pipe"] }).trim().split(/\r?\n/)[0];
|
|
1906
1878
|
const candidate = path4.join(path4.dirname(cmdPath), "node_modules", "@openai", "codex", "bin", "codex.js");
|
|
1907
|
-
if (
|
|
1879
|
+
if (existsSync3(candidate)) codexEntry = candidate;
|
|
1908
1880
|
} catch {
|
|
1909
1881
|
}
|
|
1910
1882
|
}
|
|
@@ -2366,13 +2338,13 @@ import { spawn as spawn3 } from "child_process";
|
|
|
2366
2338
|
import path5 from "path";
|
|
2367
2339
|
import { writeFileSync as writeFileSync3 } from "fs";
|
|
2368
2340
|
function buildCopilotSpawnEnv(ctx) {
|
|
2369
|
-
return
|
|
2341
|
+
return {
|
|
2370
2342
|
...process.env,
|
|
2371
2343
|
FORCE_COLOR: "0",
|
|
2372
2344
|
NO_COLOR: "1",
|
|
2373
2345
|
...ctx.config.envVars || {},
|
|
2374
2346
|
[SLOCK_HOME_ENV]: resolveSlockHome()
|
|
2375
|
-
}
|
|
2347
|
+
};
|
|
2376
2348
|
}
|
|
2377
2349
|
var CopilotDriver = class {
|
|
2378
2350
|
id = "copilot";
|
|
@@ -2530,13 +2502,13 @@ import { spawn as spawn4, spawnSync } from "child_process";
|
|
|
2530
2502
|
import { writeFileSync as writeFileSync4, mkdirSync as mkdirSync2, existsSync as existsSync4 } from "fs";
|
|
2531
2503
|
import path6 from "path";
|
|
2532
2504
|
function buildCursorSpawnEnv(ctx) {
|
|
2533
|
-
return
|
|
2505
|
+
return {
|
|
2534
2506
|
...process.env,
|
|
2535
2507
|
FORCE_COLOR: "0",
|
|
2536
2508
|
NO_COLOR: "1",
|
|
2537
2509
|
...ctx.config.envVars || {},
|
|
2538
2510
|
[SLOCK_HOME_ENV]: resolveSlockHome()
|
|
2539
|
-
}
|
|
2511
|
+
};
|
|
2540
2512
|
}
|
|
2541
2513
|
var CursorDriver = class {
|
|
2542
2514
|
id = "cursor";
|
|
@@ -2706,7 +2678,7 @@ function detectCursorModels(runCommand = runCursorModelsCommand) {
|
|
|
2706
2678
|
}
|
|
2707
2679
|
function runCursorModelsCommand() {
|
|
2708
2680
|
return spawnSync("cursor-agent", ["models"], {
|
|
2709
|
-
env:
|
|
2681
|
+
env: { ...process.env, FORCE_COLOR: "0", NO_COLOR: "1" },
|
|
2710
2682
|
encoding: "utf8",
|
|
2711
2683
|
timeout: 5e3
|
|
2712
2684
|
});
|
|
@@ -2753,7 +2725,7 @@ function resolveGeminiSpawn(commandArgs, deps = {}) {
|
|
|
2753
2725
|
}
|
|
2754
2726
|
const execFileSyncFn = deps.execFileSyncFn ?? execFileSync2;
|
|
2755
2727
|
const existsSyncFn = deps.existsSyncFn ?? existsSync5;
|
|
2756
|
-
const env =
|
|
2728
|
+
const env = deps.env ?? process.env;
|
|
2757
2729
|
const winPath = path7.win32;
|
|
2758
2730
|
let geminiEntry = null;
|
|
2759
2731
|
try {
|
|
@@ -2927,16 +2899,13 @@ var GeminiDriver = class {
|
|
|
2927
2899
|
// src/drivers/kimi.ts
|
|
2928
2900
|
import { randomUUID } from "crypto";
|
|
2929
2901
|
import { spawn as spawn6 } from "child_process";
|
|
2930
|
-
import {
|
|
2902
|
+
import { existsSync as existsSync6, readFileSync as readFileSync3, writeFileSync as writeFileSync6 } from "fs";
|
|
2931
2903
|
import os3 from "os";
|
|
2932
2904
|
import path8 from "path";
|
|
2933
2905
|
var KIMI_WIRE_PROTOCOL_VERSION = "1.3";
|
|
2934
2906
|
var KIMI_SYSTEM_PROMPT_FILE = ".slock-kimi-system.md";
|
|
2935
2907
|
var KIMI_AGENT_FILE = ".slock-kimi-agent.yaml";
|
|
2936
2908
|
var KIMI_MCP_FILE = ".slock-kimi-mcp.json";
|
|
2937
|
-
var KIMI_GENERATED_CONFIG_FILE = ".slock-kimi-config.toml";
|
|
2938
|
-
var SLOCK_KIMI_CONFIG_CONTENT_ENV = "SLOCK_KIMI_CONFIG_CONTENT";
|
|
2939
|
-
var SLOCK_KIMI_CONFIG_FILE_ENV = "SLOCK_KIMI_CONFIG_FILE";
|
|
2940
2909
|
function parseToolArguments(raw) {
|
|
2941
2910
|
if (typeof raw !== "string") return raw;
|
|
2942
2911
|
try {
|
|
@@ -2945,73 +2914,6 @@ function parseToolArguments(raw) {
|
|
|
2945
2914
|
return raw;
|
|
2946
2915
|
}
|
|
2947
2916
|
}
|
|
2948
|
-
function readKimiConfigSource(home = os3.homedir(), env = process.env) {
|
|
2949
|
-
const inlineConfig = env[SLOCK_KIMI_CONFIG_CONTENT_ENV];
|
|
2950
|
-
if (inlineConfig && inlineConfig.trim()) {
|
|
2951
|
-
return {
|
|
2952
|
-
raw: inlineConfig,
|
|
2953
|
-
explicitPath: null,
|
|
2954
|
-
sourcePath: SLOCK_KIMI_CONFIG_CONTENT_ENV
|
|
2955
|
-
};
|
|
2956
|
-
}
|
|
2957
|
-
const explicitPath = env[SLOCK_KIMI_CONFIG_FILE_ENV];
|
|
2958
|
-
const configPath = explicitPath && explicitPath.trim() ? explicitPath : path8.join(home, ".kimi", "config.toml");
|
|
2959
|
-
try {
|
|
2960
|
-
return {
|
|
2961
|
-
raw: readFileSync3(configPath, "utf8"),
|
|
2962
|
-
explicitPath: explicitPath && explicitPath.trim() ? explicitPath : null,
|
|
2963
|
-
sourcePath: configPath
|
|
2964
|
-
};
|
|
2965
|
-
} catch {
|
|
2966
|
-
return {
|
|
2967
|
-
raw: null,
|
|
2968
|
-
explicitPath: explicitPath && explicitPath.trim() ? explicitPath : null,
|
|
2969
|
-
sourcePath: configPath
|
|
2970
|
-
};
|
|
2971
|
-
}
|
|
2972
|
-
}
|
|
2973
|
-
function buildKimiSpawnEnv(env = process.env) {
|
|
2974
|
-
const spawnEnv = { ...env, FORCE_COLOR: "0", NO_COLOR: "1" };
|
|
2975
|
-
delete spawnEnv[SLOCK_KIMI_CONFIG_CONTENT_ENV];
|
|
2976
|
-
delete spawnEnv[SLOCK_KIMI_CONFIG_FILE_ENV];
|
|
2977
|
-
return scrubDaemonChildEnv(spawnEnv);
|
|
2978
|
-
}
|
|
2979
|
-
function buildKimiEffectiveEnv(ctx, overrideEnv) {
|
|
2980
|
-
return {
|
|
2981
|
-
...process.env,
|
|
2982
|
-
...ctx.config.envVars || {},
|
|
2983
|
-
...overrideEnv || {}
|
|
2984
|
-
};
|
|
2985
|
-
}
|
|
2986
|
-
function buildKimiLaunchOptions(ctx, opts = {}) {
|
|
2987
|
-
const env = buildKimiEffectiveEnv(ctx, opts.env);
|
|
2988
|
-
const source = readKimiConfigSource(opts.home ?? os3.homedir(), env);
|
|
2989
|
-
const args = [];
|
|
2990
|
-
let configFilePath = null;
|
|
2991
|
-
let configContent = null;
|
|
2992
|
-
if (source.explicitPath) {
|
|
2993
|
-
configFilePath = source.explicitPath;
|
|
2994
|
-
} else if (source.raw !== null && source.sourcePath === SLOCK_KIMI_CONFIG_CONTENT_ENV) {
|
|
2995
|
-
configFilePath = path8.join(ctx.workingDirectory, KIMI_GENERATED_CONFIG_FILE);
|
|
2996
|
-
configContent = source.raw;
|
|
2997
|
-
if (opts.writeGeneratedConfig !== false) {
|
|
2998
|
-
writeFileSync6(configFilePath, source.raw, { encoding: "utf8", mode: 384 });
|
|
2999
|
-
chmodSync(configFilePath, 384);
|
|
3000
|
-
}
|
|
3001
|
-
}
|
|
3002
|
-
if (configFilePath) {
|
|
3003
|
-
args.push("--config-file", configFilePath);
|
|
3004
|
-
}
|
|
3005
|
-
if (ctx.config.model && ctx.config.model !== "default") {
|
|
3006
|
-
args.push("--model", ctx.config.model);
|
|
3007
|
-
}
|
|
3008
|
-
return {
|
|
3009
|
-
args,
|
|
3010
|
-
env: buildKimiSpawnEnv(env),
|
|
3011
|
-
configFilePath,
|
|
3012
|
-
configContent
|
|
3013
|
-
};
|
|
3014
|
-
}
|
|
3015
2917
|
var KimiDriver = class {
|
|
3016
2918
|
id = "kimi";
|
|
3017
2919
|
lifecycle = {
|
|
@@ -3028,25 +2930,7 @@ var KimiDriver = class {
|
|
|
3028
2930
|
};
|
|
3029
2931
|
model = {
|
|
3030
2932
|
detectedModelsVerifiedAs: "launchable",
|
|
3031
|
-
toLaunchSpec: (modelId
|
|
3032
|
-
if (!ctx) return { args: ["--model", modelId] };
|
|
3033
|
-
const launchCtx = {
|
|
3034
|
-
...ctx,
|
|
3035
|
-
config: {
|
|
3036
|
-
...ctx.config,
|
|
3037
|
-
model: modelId
|
|
3038
|
-
}
|
|
3039
|
-
};
|
|
3040
|
-
const launch = buildKimiLaunchOptions(launchCtx, {
|
|
3041
|
-
home: opts?.home,
|
|
3042
|
-
writeGeneratedConfig: false
|
|
3043
|
-
});
|
|
3044
|
-
return {
|
|
3045
|
-
args: launch.args,
|
|
3046
|
-
env: launch.env,
|
|
3047
|
-
configFiles: launch.configFilePath ? [launch.configFilePath] : void 0
|
|
3048
|
-
};
|
|
3049
|
-
}
|
|
2933
|
+
toLaunchSpec: (modelId) => ({ args: ["--model", modelId] })
|
|
3050
2934
|
};
|
|
3051
2935
|
supportsStdinNotification = true;
|
|
3052
2936
|
mcpToolPrefix = "";
|
|
@@ -3098,7 +2982,6 @@ var KimiDriver = class {
|
|
|
3098
2982
|
}
|
|
3099
2983
|
}
|
|
3100
2984
|
}), "utf8");
|
|
3101
|
-
const launch = buildKimiLaunchOptions(ctx);
|
|
3102
2985
|
const args = [
|
|
3103
2986
|
"--wire",
|
|
3104
2987
|
"--yolo",
|
|
@@ -3107,13 +2990,16 @@ var KimiDriver = class {
|
|
|
3107
2990
|
"--mcp-config-file",
|
|
3108
2991
|
mcpConfigPath,
|
|
3109
2992
|
"--session",
|
|
3110
|
-
this.sessionId
|
|
3111
|
-
...launch.args
|
|
2993
|
+
this.sessionId
|
|
3112
2994
|
];
|
|
2995
|
+
if (ctx.config.model && ctx.config.model !== "default") {
|
|
2996
|
+
args.push("--model", ctx.config.model);
|
|
2997
|
+
}
|
|
2998
|
+
const spawnEnv = { ...process.env, FORCE_COLOR: "0", NO_COLOR: "1" };
|
|
3113
2999
|
const proc = spawn6("kimi", args, {
|
|
3114
3000
|
cwd: ctx.workingDirectory,
|
|
3115
3001
|
stdio: ["pipe", "pipe", "pipe"],
|
|
3116
|
-
env:
|
|
3002
|
+
env: spawnEnv,
|
|
3117
3003
|
shell: process.platform === "win32"
|
|
3118
3004
|
});
|
|
3119
3005
|
proc.stdin?.write(JSON.stringify({
|
|
@@ -3230,9 +3116,14 @@ var KimiDriver = class {
|
|
|
3230
3116
|
return detectKimiModels();
|
|
3231
3117
|
}
|
|
3232
3118
|
};
|
|
3233
|
-
function detectKimiModels(home = os3.homedir()
|
|
3234
|
-
const
|
|
3235
|
-
|
|
3119
|
+
function detectKimiModels(home = os3.homedir()) {
|
|
3120
|
+
const configPath = path8.join(home, ".kimi", "config.toml");
|
|
3121
|
+
let raw;
|
|
3122
|
+
try {
|
|
3123
|
+
raw = readFileSync3(configPath, "utf8");
|
|
3124
|
+
} catch {
|
|
3125
|
+
return null;
|
|
3126
|
+
}
|
|
3236
3127
|
const models = [];
|
|
3237
3128
|
const sectionRe = /^\s*\[models(?:\.([^\]]+)|"\.[^"]+"|\."[^"]+")\s*\]\s*$/gm;
|
|
3238
3129
|
const lineRe = /^\s*\[models\.(.+?)\s*\]\s*$/gm;
|
|
@@ -3479,7 +3370,7 @@ function detectOpenCodeModels(home = os4.homedir(), runCommand = runOpenCodeMode
|
|
|
3479
3370
|
}
|
|
3480
3371
|
function runOpenCodeModelsCommand(home) {
|
|
3481
3372
|
const result = spawnSync2("opencode", ["models"], {
|
|
3482
|
-
env:
|
|
3373
|
+
env: { ...process.env, HOME: home, FORCE_COLOR: "0", NO_COLOR: "1" },
|
|
3483
3374
|
encoding: "utf8",
|
|
3484
3375
|
timeout: 5e3
|
|
3485
3376
|
});
|
|
@@ -3635,305 +3526,6 @@ var OpenCodeDriver = class {
|
|
|
3635
3526
|
}
|
|
3636
3527
|
};
|
|
3637
3528
|
|
|
3638
|
-
// src/drivers/pi.ts
|
|
3639
|
-
import { spawn as spawn8, spawnSync as spawnSync3 } from "child_process";
|
|
3640
|
-
import { existsSync as existsSync7, mkdirSync as mkdirSync4, writeFileSync as writeFileSync7 } from "fs";
|
|
3641
|
-
import { fileURLToPath } from "url";
|
|
3642
|
-
import path10 from "path";
|
|
3643
|
-
var CHAT_MCP_TOOL_PREFIX2 = "chat_";
|
|
3644
|
-
var NO_MESSAGE_PROMPT2 = "No new messages are pending. Stop now.";
|
|
3645
|
-
var FIRST_MESSAGE_TASK_PREFIX2 = "First message task (system-triggered):";
|
|
3646
|
-
var MIN_BUNDLED_PI_VERSION = "0.74.0";
|
|
3647
|
-
function defaultPackageResolver(specifier) {
|
|
3648
|
-
return import.meta.resolve(specifier);
|
|
3649
|
-
}
|
|
3650
|
-
function parseSemver2(version) {
|
|
3651
|
-
const match = version.match(/(\d+)\.(\d+)\.(\d+)/);
|
|
3652
|
-
if (!match) return null;
|
|
3653
|
-
return [Number(match[1]), Number(match[2]), Number(match[3])];
|
|
3654
|
-
}
|
|
3655
|
-
function isSupportedPiVersion(version) {
|
|
3656
|
-
if (!version) return true;
|
|
3657
|
-
const actual = parseSemver2(version);
|
|
3658
|
-
const minimum = parseSemver2(MIN_BUNDLED_PI_VERSION);
|
|
3659
|
-
if (!actual || !minimum) return true;
|
|
3660
|
-
for (let i = 0; i < 3; i += 1) {
|
|
3661
|
-
if (actual[i] > minimum[i]) return true;
|
|
3662
|
-
if (actual[i] < minimum[i]) return false;
|
|
3663
|
-
}
|
|
3664
|
-
return true;
|
|
3665
|
-
}
|
|
3666
|
-
function resolveBundledPiCliPath(resolver = defaultPackageResolver) {
|
|
3667
|
-
try {
|
|
3668
|
-
const mainPath = fileURLToPath(resolver("@earendil-works/pi-coding-agent"));
|
|
3669
|
-
const cliPath = path10.join(path10.dirname(mainPath), "cli.js");
|
|
3670
|
-
return existsSync7(cliPath) ? cliPath : null;
|
|
3671
|
-
} catch {
|
|
3672
|
-
return null;
|
|
3673
|
-
}
|
|
3674
|
-
}
|
|
3675
|
-
function readBundledPiVersion(cliPath) {
|
|
3676
|
-
const result = spawnSync3(process.execPath, [cliPath, "--version"], {
|
|
3677
|
-
env: scrubDaemonChildEnv({ ...process.env }),
|
|
3678
|
-
encoding: "utf8",
|
|
3679
|
-
timeout: 5e3
|
|
3680
|
-
});
|
|
3681
|
-
if (result.error || result.status !== 0) return null;
|
|
3682
|
-
return String(result.stdout || result.stderr || "").trim() || null;
|
|
3683
|
-
}
|
|
3684
|
-
function unsupportedPiVersionMessage(version) {
|
|
3685
|
-
if (!version || isSupportedPiVersion(version)) return null;
|
|
3686
|
-
return `Bundled Pi CLI ${version} is unsupported; requires Pi >= ${MIN_BUNDLED_PI_VERSION}.`;
|
|
3687
|
-
}
|
|
3688
|
-
function buildPiLaunchOptions(ctx, opts = {}) {
|
|
3689
|
-
const cliPath = opts.cliPath ?? resolveBundledPiCliPath();
|
|
3690
|
-
if (!cliPath) {
|
|
3691
|
-
throw new Error("Bundled Pi CLI not found in @earendil-works/pi-coding-agent");
|
|
3692
|
-
}
|
|
3693
|
-
const piDir = path10.join(ctx.workingDirectory, ".slock", "pi");
|
|
3694
|
-
const sessionDir = path10.join(piDir, "sessions");
|
|
3695
|
-
mkdirSync4(sessionDir, { recursive: true });
|
|
3696
|
-
const slock = prepareCliTransport(ctx, {
|
|
3697
|
-
NO_COLOR: "1",
|
|
3698
|
-
PI_CODING_AGENT_DIR: piDir,
|
|
3699
|
-
PI_CODING_AGENT_SESSION_DIR: sessionDir
|
|
3700
|
-
});
|
|
3701
|
-
const systemPromptPath = path10.join(slock.slockDir, "pi-system-prompt.md");
|
|
3702
|
-
writeFileSync7(systemPromptPath, ctx.standingPrompt, { encoding: "utf8", mode: 384 });
|
|
3703
|
-
const args = [
|
|
3704
|
-
cliPath,
|
|
3705
|
-
"--mode",
|
|
3706
|
-
"json",
|
|
3707
|
-
"--session-dir",
|
|
3708
|
-
sessionDir,
|
|
3709
|
-
"--append-system-prompt",
|
|
3710
|
-
systemPromptPath,
|
|
3711
|
-
"--no-context-files",
|
|
3712
|
-
"--no-extensions",
|
|
3713
|
-
"--no-skills",
|
|
3714
|
-
"--no-prompt-templates",
|
|
3715
|
-
"--no-themes"
|
|
3716
|
-
];
|
|
3717
|
-
if (ctx.config.model && ctx.config.model !== "default") {
|
|
3718
|
-
args.push("--model", ctx.config.model);
|
|
3719
|
-
}
|
|
3720
|
-
if (ctx.config.sessionId) {
|
|
3721
|
-
args.push("--session", ctx.config.sessionId);
|
|
3722
|
-
}
|
|
3723
|
-
const turnPrompt = ctx.prompt === ctx.standingPrompt ? NO_MESSAGE_PROMPT2 : ctx.prompt;
|
|
3724
|
-
args.push(turnPrompt);
|
|
3725
|
-
return {
|
|
3726
|
-
command: process.execPath,
|
|
3727
|
-
args,
|
|
3728
|
-
env: slock.spawnEnv,
|
|
3729
|
-
sessionDir,
|
|
3730
|
-
systemPromptPath
|
|
3731
|
-
};
|
|
3732
|
-
}
|
|
3733
|
-
function isSystemFirstMessageTask2(message) {
|
|
3734
|
-
return message.sender_id === "system" && message.channel_type === "channel" && message.channel_name === "all" && message.content.trimStart().startsWith(FIRST_MESSAGE_TASK_PREFIX2);
|
|
3735
|
-
}
|
|
3736
|
-
function buildPiSystemPrompt(config) {
|
|
3737
|
-
return buildCliTransportSystemPrompt(config, {
|
|
3738
|
-
toolPrefix: CHAT_MCP_TOOL_PREFIX2,
|
|
3739
|
-
extraCriticalRules: [
|
|
3740
|
-
"- Runtime Profile migration controls are not available in the Pi runtime yet. If asked to acknowledge a runtime migration, explain the blocker instead of inventing a command."
|
|
3741
|
-
],
|
|
3742
|
-
postStartupNotes: [
|
|
3743
|
-
"**Pi runtime note:** Slock launches you as a per-turn process. Complete the current wake using `slock` CLI commands, then stop; the daemon will restart you when new messages arrive."
|
|
3744
|
-
],
|
|
3745
|
-
includeStdinNotificationSection: false,
|
|
3746
|
-
messageNotificationStyle: "poll"
|
|
3747
|
-
});
|
|
3748
|
-
}
|
|
3749
|
-
function contentText(content) {
|
|
3750
|
-
if (!content) return "";
|
|
3751
|
-
const chunks = [];
|
|
3752
|
-
for (const item of content) {
|
|
3753
|
-
if (item.type === "text" && typeof item.text === "string") {
|
|
3754
|
-
chunks.push(item.text);
|
|
3755
|
-
}
|
|
3756
|
-
}
|
|
3757
|
-
return chunks.join("");
|
|
3758
|
-
}
|
|
3759
|
-
function apiKeyErrorMessage(line) {
|
|
3760
|
-
const trimmed = line.trim();
|
|
3761
|
-
if (!trimmed) return null;
|
|
3762
|
-
if (/no api key found/i.test(trimmed)) return trimmed;
|
|
3763
|
-
if (/api key.+required/i.test(trimmed)) return trimmed;
|
|
3764
|
-
if (/no models available/i.test(trimmed)) return trimmed;
|
|
3765
|
-
return null;
|
|
3766
|
-
}
|
|
3767
|
-
var PiDriver = class {
|
|
3768
|
-
id = "pi";
|
|
3769
|
-
lifecycle = {
|
|
3770
|
-
kind: "per_turn",
|
|
3771
|
-
start: "defer_until_concrete_message",
|
|
3772
|
-
exit: "terminate_on_turn_end",
|
|
3773
|
-
inFlightWake: "coalesce_into_pending"
|
|
3774
|
-
};
|
|
3775
|
-
communication = {
|
|
3776
|
-
chat: "slock_cli",
|
|
3777
|
-
runtimeControl: "none"
|
|
3778
|
-
};
|
|
3779
|
-
session = {
|
|
3780
|
-
recovery: "resume_or_fresh"
|
|
3781
|
-
};
|
|
3782
|
-
model = {
|
|
3783
|
-
detectedModelsVerifiedAs: "launchable",
|
|
3784
|
-
toLaunchSpec: (modelId, ctx) => {
|
|
3785
|
-
if (!ctx) return { args: ["--model", modelId] };
|
|
3786
|
-
const launchCtx = {
|
|
3787
|
-
...ctx,
|
|
3788
|
-
config: {
|
|
3789
|
-
...ctx.config,
|
|
3790
|
-
model: modelId
|
|
3791
|
-
}
|
|
3792
|
-
};
|
|
3793
|
-
const launch = buildPiLaunchOptions(launchCtx);
|
|
3794
|
-
return {
|
|
3795
|
-
args: launch.args,
|
|
3796
|
-
env: launch.env,
|
|
3797
|
-
configFiles: [launch.systemPromptPath]
|
|
3798
|
-
};
|
|
3799
|
-
}
|
|
3800
|
-
};
|
|
3801
|
-
supportsStdinNotification = false;
|
|
3802
|
-
mcpToolPrefix = CHAT_MCP_TOOL_PREFIX2;
|
|
3803
|
-
busyDeliveryMode = "none";
|
|
3804
|
-
terminateProcessOnTurnEnd = true;
|
|
3805
|
-
deferSpawnUntilMessage = true;
|
|
3806
|
-
usesSlockCliForCommunication = true;
|
|
3807
|
-
sessionId = null;
|
|
3808
|
-
sessionAnnounced = false;
|
|
3809
|
-
apiKeyErrorAnnounced = false;
|
|
3810
|
-
turnEnded = false;
|
|
3811
|
-
assistantTextByMessageId = /* @__PURE__ */ new Map();
|
|
3812
|
-
shouldDeferWakeMessage(message) {
|
|
3813
|
-
return isSystemFirstMessageTask2(message);
|
|
3814
|
-
}
|
|
3815
|
-
probe() {
|
|
3816
|
-
const cliPath = resolveBundledPiCliPath();
|
|
3817
|
-
if (!cliPath) return { available: false };
|
|
3818
|
-
const version = readBundledPiVersion(cliPath) || void 0;
|
|
3819
|
-
const unsupportedMessage = unsupportedPiVersionMessage(version);
|
|
3820
|
-
if (unsupportedMessage) {
|
|
3821
|
-
return {
|
|
3822
|
-
available: false,
|
|
3823
|
-
version: `${version} (requires >= ${MIN_BUNDLED_PI_VERSION})`
|
|
3824
|
-
};
|
|
3825
|
-
}
|
|
3826
|
-
return { available: true, version };
|
|
3827
|
-
}
|
|
3828
|
-
async detectModels() {
|
|
3829
|
-
return null;
|
|
3830
|
-
}
|
|
3831
|
-
spawn(ctx) {
|
|
3832
|
-
this.sessionId = ctx.config.sessionId || null;
|
|
3833
|
-
this.sessionAnnounced = false;
|
|
3834
|
-
this.apiKeyErrorAnnounced = false;
|
|
3835
|
-
this.turnEnded = false;
|
|
3836
|
-
this.assistantTextByMessageId.clear();
|
|
3837
|
-
const cliPath = resolveBundledPiCliPath();
|
|
3838
|
-
if (!cliPath) throw new Error("Bundled Pi CLI not found in @earendil-works/pi-coding-agent");
|
|
3839
|
-
const unsupportedMessage = unsupportedPiVersionMessage(readBundledPiVersion(cliPath));
|
|
3840
|
-
if (unsupportedMessage) throw new Error(unsupportedMessage);
|
|
3841
|
-
const launch = buildPiLaunchOptions(ctx, { cliPath });
|
|
3842
|
-
const proc = spawn8(launch.command, launch.args, {
|
|
3843
|
-
cwd: ctx.workingDirectory,
|
|
3844
|
-
stdio: ["pipe", "pipe", "pipe"],
|
|
3845
|
-
env: launch.env,
|
|
3846
|
-
shell: process.platform === "win32"
|
|
3847
|
-
});
|
|
3848
|
-
proc.stdin?.end();
|
|
3849
|
-
return { process: proc };
|
|
3850
|
-
}
|
|
3851
|
-
parseLine(line) {
|
|
3852
|
-
let event;
|
|
3853
|
-
try {
|
|
3854
|
-
event = JSON.parse(line);
|
|
3855
|
-
} catch {
|
|
3856
|
-
if (this.apiKeyErrorAnnounced) return [];
|
|
3857
|
-
const message = apiKeyErrorMessage(line);
|
|
3858
|
-
if (!message) return [];
|
|
3859
|
-
this.apiKeyErrorAnnounced = true;
|
|
3860
|
-
this.turnEnded = true;
|
|
3861
|
-
return [
|
|
3862
|
-
{ kind: "error", message },
|
|
3863
|
-
{ kind: "turn_end", sessionId: this.sessionId || void 0 }
|
|
3864
|
-
];
|
|
3865
|
-
}
|
|
3866
|
-
const events = [];
|
|
3867
|
-
if (event.type === "session" && event.id) {
|
|
3868
|
-
this.sessionId = event.id;
|
|
3869
|
-
}
|
|
3870
|
-
if (!this.sessionAnnounced && this.sessionId) {
|
|
3871
|
-
events.push({ kind: "session_init", sessionId: this.sessionId });
|
|
3872
|
-
this.sessionAnnounced = true;
|
|
3873
|
-
}
|
|
3874
|
-
switch (event.type) {
|
|
3875
|
-
case "agent_start":
|
|
3876
|
-
case "turn_start":
|
|
3877
|
-
events.push({ kind: "thinking", text: "" });
|
|
3878
|
-
break;
|
|
3879
|
-
case "message_update":
|
|
3880
|
-
case "message_end":
|
|
3881
|
-
if (event.message?.role === "assistant") {
|
|
3882
|
-
const key = event.message.id || "current";
|
|
3883
|
-
const currentText = contentText(event.message.content);
|
|
3884
|
-
const previousText = this.assistantTextByMessageId.get(key) ?? "";
|
|
3885
|
-
if (currentText.length > previousText.length && currentText.startsWith(previousText)) {
|
|
3886
|
-
events.push({ kind: "text", text: currentText.slice(previousText.length) });
|
|
3887
|
-
} else if (currentText && currentText !== previousText) {
|
|
3888
|
-
events.push({ kind: "text", text: currentText });
|
|
3889
|
-
}
|
|
3890
|
-
this.assistantTextByMessageId.set(key, currentText);
|
|
3891
|
-
if (event.message.stopReason === "error" || event.message.stopReason === "aborted") {
|
|
3892
|
-
events.push({ kind: "error", message: event.message.errorMessage || `Request ${event.message.stopReason}` });
|
|
3893
|
-
}
|
|
3894
|
-
}
|
|
3895
|
-
break;
|
|
3896
|
-
case "tool_execution_start":
|
|
3897
|
-
events.push({
|
|
3898
|
-
kind: "tool_call",
|
|
3899
|
-
name: event.toolName || "unknown_tool",
|
|
3900
|
-
input: event.args
|
|
3901
|
-
});
|
|
3902
|
-
break;
|
|
3903
|
-
case "tool_execution_end":
|
|
3904
|
-
events.push({
|
|
3905
|
-
kind: "tool_output",
|
|
3906
|
-
name: event.toolName || "unknown_tool"
|
|
3907
|
-
});
|
|
3908
|
-
if (event.isError) {
|
|
3909
|
-
events.push({ kind: "error", message: `Pi tool ${event.toolName || "unknown_tool"} failed` });
|
|
3910
|
-
}
|
|
3911
|
-
break;
|
|
3912
|
-
case "compaction_start":
|
|
3913
|
-
events.push({ kind: "compaction_started" });
|
|
3914
|
-
break;
|
|
3915
|
-
case "compaction_end":
|
|
3916
|
-
events.push({ kind: "compaction_finished" });
|
|
3917
|
-
if (event.errorMessage) events.push({ kind: "error", message: event.errorMessage });
|
|
3918
|
-
break;
|
|
3919
|
-
case "turn_end":
|
|
3920
|
-
case "agent_end":
|
|
3921
|
-
if (!this.turnEnded) {
|
|
3922
|
-
events.push({ kind: "turn_end", sessionId: this.sessionId || void 0 });
|
|
3923
|
-
this.turnEnded = true;
|
|
3924
|
-
}
|
|
3925
|
-
break;
|
|
3926
|
-
}
|
|
3927
|
-
return events;
|
|
3928
|
-
}
|
|
3929
|
-
encodeStdinMessage(_text, _sessionId, _opts) {
|
|
3930
|
-
return null;
|
|
3931
|
-
}
|
|
3932
|
-
buildSystemPrompt(config, _agentId) {
|
|
3933
|
-
return buildPiSystemPrompt(config);
|
|
3934
|
-
}
|
|
3935
|
-
};
|
|
3936
|
-
|
|
3937
3529
|
// src/drivers/index.ts
|
|
3938
3530
|
var driverFactories = {
|
|
3939
3531
|
claude: () => new ClaudeDriver(),
|
|
@@ -3942,8 +3534,7 @@ var driverFactories = {
|
|
|
3942
3534
|
cursor: () => new CursorDriver(),
|
|
3943
3535
|
gemini: () => new GeminiDriver(),
|
|
3944
3536
|
kimi: () => new KimiDriver(),
|
|
3945
|
-
opencode: () => new OpenCodeDriver()
|
|
3946
|
-
pi: () => new PiDriver()
|
|
3537
|
+
opencode: () => new OpenCodeDriver()
|
|
3947
3538
|
};
|
|
3948
3539
|
function getDriver(runtimeId) {
|
|
3949
3540
|
const createDriver = driverFactories[runtimeId];
|
|
@@ -3956,7 +3547,7 @@ function getDriver(runtimeId) {
|
|
|
3956
3547
|
|
|
3957
3548
|
// src/workspaces.ts
|
|
3958
3549
|
import { readdir, rm, stat } from "fs/promises";
|
|
3959
|
-
import
|
|
3550
|
+
import path10 from "path";
|
|
3960
3551
|
function isValidWorkspaceDirectoryName(directoryName) {
|
|
3961
3552
|
return !directoryName.includes("/") && !directoryName.includes("\\") && !directoryName.includes("..");
|
|
3962
3553
|
}
|
|
@@ -3964,7 +3555,7 @@ function resolveWorkspaceDirectoryPath(dataDir, directoryName) {
|
|
|
3964
3555
|
if (!isValidWorkspaceDirectoryName(directoryName)) {
|
|
3965
3556
|
return null;
|
|
3966
3557
|
}
|
|
3967
|
-
return
|
|
3558
|
+
return path10.join(dataDir, directoryName);
|
|
3968
3559
|
}
|
|
3969
3560
|
function emptyWorkspaceDirectorySummary(latestMtime = /* @__PURE__ */ new Date(0)) {
|
|
3970
3561
|
return {
|
|
@@ -4013,7 +3604,7 @@ async function summarizeWorkspaceDirectory(dirPath) {
|
|
|
4013
3604
|
return summary;
|
|
4014
3605
|
}
|
|
4015
3606
|
const childSummaries = await Promise.all(
|
|
4016
|
-
entries.map((entry) => summarizeWorkspaceEntry(
|
|
3607
|
+
entries.map((entry) => summarizeWorkspaceEntry(path10.join(dirPath, entry.name), entry))
|
|
4017
3608
|
);
|
|
4018
3609
|
for (const childSummary of childSummaries) {
|
|
4019
3610
|
summary = mergeWorkspaceDirectorySummaries(summary, childSummary);
|
|
@@ -4032,7 +3623,7 @@ async function scanWorkspaceDirectories(dataDir) {
|
|
|
4032
3623
|
if (!entry.isDirectory()) {
|
|
4033
3624
|
return null;
|
|
4034
3625
|
}
|
|
4035
|
-
const dirPath =
|
|
3626
|
+
const dirPath = path10.join(dataDir, entry.name);
|
|
4036
3627
|
try {
|
|
4037
3628
|
const summary = await summarizeWorkspaceDirectory(dirPath);
|
|
4038
3629
|
return {
|
|
@@ -4230,12 +3821,12 @@ function findSessionJsonl(root, predicate) {
|
|
|
4230
3821
|
for (const entry of entries) {
|
|
4231
3822
|
if (++visited > maxEntries) return null;
|
|
4232
3823
|
if (!entry.isFile() || !predicate(entry.name)) continue;
|
|
4233
|
-
return
|
|
3824
|
+
return path11.join(dir, entry.name);
|
|
4234
3825
|
}
|
|
4235
3826
|
for (const entry of entries) {
|
|
4236
3827
|
if (++visited > maxEntries) return null;
|
|
4237
3828
|
if (!entry.isDirectory()) continue;
|
|
4238
|
-
const found = visit(
|
|
3829
|
+
const found = visit(path11.join(dir, entry.name), depth - 1);
|
|
4239
3830
|
if (found) return found;
|
|
4240
3831
|
}
|
|
4241
3832
|
return null;
|
|
@@ -4248,10 +3839,10 @@ function safeSessionFilename(value) {
|
|
|
4248
3839
|
}
|
|
4249
3840
|
function writeRuntimeSessionHandoff(runtime, sessionId, fallbackDir) {
|
|
4250
3841
|
try {
|
|
4251
|
-
const dir =
|
|
4252
|
-
|
|
4253
|
-
const filePath =
|
|
4254
|
-
|
|
3842
|
+
const dir = path11.join(fallbackDir, ".slock", "runtime-sessions");
|
|
3843
|
+
mkdirSync4(dir, { recursive: true });
|
|
3844
|
+
const filePath = path11.join(dir, `${runtime}-${safeSessionFilename(sessionId)}.jsonl`);
|
|
3845
|
+
writeFileSync7(filePath, JSON.stringify({
|
|
4255
3846
|
type: "runtime_session_handoff",
|
|
4256
3847
|
runtime,
|
|
4257
3848
|
sessionId,
|
|
@@ -4270,7 +3861,7 @@ function writeRuntimeSessionHandoff(runtime, sessionId, fallbackDir) {
|
|
|
4270
3861
|
}
|
|
4271
3862
|
}
|
|
4272
3863
|
function resolveRuntimeSessionRef(runtime, sessionId, homeDir = os5.homedir(), fallbackDir) {
|
|
4273
|
-
const directPath =
|
|
3864
|
+
const directPath = path11.isAbsolute(sessionId) ? sessionId : null;
|
|
4274
3865
|
if (directPath) {
|
|
4275
3866
|
try {
|
|
4276
3867
|
if (statSync2(directPath).isFile()) {
|
|
@@ -4279,7 +3870,7 @@ function resolveRuntimeSessionRef(runtime, sessionId, homeDir = os5.homedir(), f
|
|
|
4279
3870
|
} catch {
|
|
4280
3871
|
}
|
|
4281
3872
|
}
|
|
4282
|
-
const resolvedPath = runtime === "claude" ? findSessionJsonl(
|
|
3873
|
+
const resolvedPath = runtime === "claude" ? findSessionJsonl(path11.join(homeDir, ".claude", "projects"), (filename) => filename === `${sessionId}.jsonl`) : runtime === "codex" ? findSessionJsonl(path11.join(homeDir, ".codex", "sessions"), (filename) => filename.endsWith(".jsonl") && filename.includes(sessionId)) : null;
|
|
4283
3874
|
if (!resolvedPath && fallbackDir) {
|
|
4284
3875
|
const fallback = writeRuntimeSessionHandoff(runtime, sessionId, fallbackDir);
|
|
4285
3876
|
if (fallback) return fallback;
|
|
@@ -5412,26 +5003,26 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
5412
5003
|
this.recordDaemonTrace("daemon.agent.spawn.started", this.startQueueTraceAttrs(agentId, config, wakeMessage, unreadSummary, resumePrompt, launchId));
|
|
5413
5004
|
try {
|
|
5414
5005
|
const driver = this.driverResolver(config.runtime || "claude");
|
|
5415
|
-
const agentDataDir =
|
|
5006
|
+
const agentDataDir = path11.join(this.dataDir, agentId);
|
|
5416
5007
|
await mkdir(agentDataDir, { recursive: true });
|
|
5417
5008
|
const runtimeConfig = withLocalRuntimeContext(config, agentId, agentDataDir);
|
|
5418
|
-
const memoryMdPath =
|
|
5009
|
+
const memoryMdPath = path11.join(agentDataDir, "MEMORY.md");
|
|
5419
5010
|
try {
|
|
5420
5011
|
await access(memoryMdPath);
|
|
5421
5012
|
} catch {
|
|
5422
5013
|
const initialMemoryMd = buildInitialMemoryMd(runtimeConfig);
|
|
5423
5014
|
await writeFile(memoryMdPath, initialMemoryMd);
|
|
5424
5015
|
}
|
|
5425
|
-
const notesDir =
|
|
5016
|
+
const notesDir = path11.join(agentDataDir, "notes");
|
|
5426
5017
|
await mkdir(notesDir, { recursive: true });
|
|
5427
5018
|
if (getOnboardingSeedMode(config) === FIRST_CINDY_SEED_MODE) {
|
|
5428
5019
|
const seedFiles = buildOnboardingSeedFiles();
|
|
5429
5020
|
for (const { relativePath, content } of seedFiles) {
|
|
5430
|
-
const fullPath =
|
|
5021
|
+
const fullPath = path11.join(agentDataDir, relativePath);
|
|
5431
5022
|
try {
|
|
5432
5023
|
await access(fullPath);
|
|
5433
5024
|
} catch {
|
|
5434
|
-
await mkdir(
|
|
5025
|
+
await mkdir(path11.dirname(fullPath), { recursive: true });
|
|
5435
5026
|
await writeFile(fullPath, content);
|
|
5436
5027
|
}
|
|
5437
5028
|
}
|
|
@@ -6110,7 +5701,7 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
|
|
|
6110
5701
|
return true;
|
|
6111
5702
|
}
|
|
6112
5703
|
async resetWorkspace(agentId) {
|
|
6113
|
-
const agentDataDir =
|
|
5704
|
+
const agentDataDir = path11.join(this.dataDir, agentId);
|
|
6114
5705
|
try {
|
|
6115
5706
|
await rm2(agentDataDir, { recursive: true, force: true });
|
|
6116
5707
|
logger.info(`[Agent ${agentId}] Workspace reset complete (${agentDataDir})`);
|
|
@@ -6147,7 +5738,7 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
|
|
|
6147
5738
|
return result;
|
|
6148
5739
|
}
|
|
6149
5740
|
buildRuntimeProfileReport(agentId, config, sessionId, launchId) {
|
|
6150
|
-
const workspacePath =
|
|
5741
|
+
const workspacePath = path11.join(this.dataDir, agentId);
|
|
6151
5742
|
return {
|
|
6152
5743
|
agentId,
|
|
6153
5744
|
launchId,
|
|
@@ -6395,7 +5986,7 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
|
|
|
6395
5986
|
}
|
|
6396
5987
|
// Workspace file browsing
|
|
6397
5988
|
async getFileTree(agentId, dirPath) {
|
|
6398
|
-
const agentDir =
|
|
5989
|
+
const agentDir = path11.join(this.dataDir, agentId);
|
|
6399
5990
|
try {
|
|
6400
5991
|
await stat2(agentDir);
|
|
6401
5992
|
} catch {
|
|
@@ -6403,8 +5994,8 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
|
|
|
6403
5994
|
}
|
|
6404
5995
|
let targetDir = agentDir;
|
|
6405
5996
|
if (dirPath) {
|
|
6406
|
-
const resolved =
|
|
6407
|
-
if (!resolved.startsWith(agentDir +
|
|
5997
|
+
const resolved = path11.resolve(agentDir, dirPath);
|
|
5998
|
+
if (!resolved.startsWith(agentDir + path11.sep) && resolved !== agentDir) {
|
|
6408
5999
|
return [];
|
|
6409
6000
|
}
|
|
6410
6001
|
targetDir = resolved;
|
|
@@ -6412,14 +6003,14 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
|
|
|
6412
6003
|
return this.listDirectoryChildren(targetDir, agentDir);
|
|
6413
6004
|
}
|
|
6414
6005
|
async readFile(agentId, filePath) {
|
|
6415
|
-
const agentDir =
|
|
6416
|
-
const resolved =
|
|
6417
|
-
if (!resolved.startsWith(agentDir +
|
|
6006
|
+
const agentDir = path11.join(this.dataDir, agentId);
|
|
6007
|
+
const resolved = path11.resolve(agentDir, filePath);
|
|
6008
|
+
if (!resolved.startsWith(agentDir + path11.sep) && resolved !== agentDir) {
|
|
6418
6009
|
throw new Error("Access denied");
|
|
6419
6010
|
}
|
|
6420
6011
|
const info = await stat2(resolved);
|
|
6421
6012
|
if (info.isDirectory()) throw new Error("Cannot read a directory");
|
|
6422
|
-
const ext =
|
|
6013
|
+
const ext = path11.extname(resolved).toLowerCase();
|
|
6423
6014
|
if (WORKSPACE_TEXT_EXTENSIONS.has(ext) || ext === "") {
|
|
6424
6015
|
if (info.size > WORKSPACE_TEXT_FILE_MAX_BYTES) throw new Error("File too large");
|
|
6425
6016
|
const content = await readFile(resolved, "utf-8");
|
|
@@ -6454,13 +6045,13 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
|
|
|
6454
6045
|
const agent = this.agents.get(agentId);
|
|
6455
6046
|
const runtime = runtimeHint || agent?.config.runtime || "claude";
|
|
6456
6047
|
const home = os5.homedir();
|
|
6457
|
-
const workspaceDir =
|
|
6048
|
+
const workspaceDir = path11.join(this.dataDir, agentId);
|
|
6458
6049
|
const paths = _AgentProcessManager.SKILL_PATHS[runtime] || _AgentProcessManager.SKILL_PATHS.claude;
|
|
6459
6050
|
const globalResults = await Promise.all(
|
|
6460
|
-
paths.global.map((p) => this.scanSkillsDir(
|
|
6051
|
+
paths.global.map((p) => this.scanSkillsDir(path11.join(home, p)))
|
|
6461
6052
|
);
|
|
6462
6053
|
const workspaceResults = await Promise.all(
|
|
6463
|
-
paths.workspace.map((p) => this.scanSkillsDir(
|
|
6054
|
+
paths.workspace.map((p) => this.scanSkillsDir(path11.join(workspaceDir, p)))
|
|
6464
6055
|
);
|
|
6465
6056
|
const dedup = (skills) => {
|
|
6466
6057
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -6489,7 +6080,7 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
|
|
|
6489
6080
|
const skills = [];
|
|
6490
6081
|
for (const entry of entries) {
|
|
6491
6082
|
if (entry.isDirectory() || entry.isSymbolicLink()) {
|
|
6492
|
-
const skillMd =
|
|
6083
|
+
const skillMd = path11.join(dir, entry.name, "SKILL.md");
|
|
6493
6084
|
try {
|
|
6494
6085
|
const content = await readFile(skillMd, "utf-8");
|
|
6495
6086
|
const skill = this.parseSkillMd(entry.name, content);
|
|
@@ -6500,7 +6091,7 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
|
|
|
6500
6091
|
} else if (entry.name.endsWith(".md")) {
|
|
6501
6092
|
const cmdName = entry.name.replace(/\.md$/, "");
|
|
6502
6093
|
try {
|
|
6503
|
-
const content = await readFile(
|
|
6094
|
+
const content = await readFile(path11.join(dir, entry.name), "utf-8");
|
|
6504
6095
|
const skill = this.parseSkillMd(cmdName, content);
|
|
6505
6096
|
skill.sourcePath = dir;
|
|
6506
6097
|
skills.push(skill);
|
|
@@ -7343,8 +6934,8 @@ ${RESPONSE_TARGET_HINT}`);
|
|
|
7343
6934
|
const nodes = [];
|
|
7344
6935
|
for (const entry of entries) {
|
|
7345
6936
|
if (entry.name.startsWith(".") || entry.name === "node_modules") continue;
|
|
7346
|
-
const fullPath =
|
|
7347
|
-
const relativePath =
|
|
6937
|
+
const fullPath = path11.join(dir, entry.name);
|
|
6938
|
+
const relativePath = path11.relative(rootDir, fullPath);
|
|
7348
6939
|
let info;
|
|
7349
6940
|
try {
|
|
7350
6941
|
info = await stat2(fullPath);
|
|
@@ -7647,9 +7238,9 @@ var ReminderCache = class {
|
|
|
7647
7238
|
|
|
7648
7239
|
// src/machineLock.ts
|
|
7649
7240
|
import { createHash as createHash3, randomUUID as randomUUID2 } from "crypto";
|
|
7650
|
-
import { mkdirSync as
|
|
7241
|
+
import { mkdirSync as mkdirSync5, readFileSync as readFileSync5, rmSync as rmSync2, statSync as statSync3, writeFileSync as writeFileSync8 } from "fs";
|
|
7651
7242
|
import os6 from "os";
|
|
7652
|
-
import
|
|
7243
|
+
import path12 from "path";
|
|
7653
7244
|
var INCOMPLETE_LOCK_STALE_MS = 3e4;
|
|
7654
7245
|
var DaemonMachineLockConflictError = class extends Error {
|
|
7655
7246
|
code = "DAEMON_MACHINE_LOCK_HELD";
|
|
@@ -7671,7 +7262,7 @@ function resolveDefaultMachineStateRoot() {
|
|
|
7671
7262
|
return resolveSlockHomePath("machines");
|
|
7672
7263
|
}
|
|
7673
7264
|
function ownerPath(lockDir) {
|
|
7674
|
-
return
|
|
7265
|
+
return path12.join(lockDir, "owner.json");
|
|
7675
7266
|
}
|
|
7676
7267
|
function readOwner(lockDir) {
|
|
7677
7268
|
try {
|
|
@@ -7701,13 +7292,13 @@ function acquireDaemonMachineLock(options) {
|
|
|
7701
7292
|
const rootDir = options.rootDir ?? resolveDefaultMachineStateRoot();
|
|
7702
7293
|
const fingerprint = apiKeyFingerprint(options.apiKey);
|
|
7703
7294
|
const lockId = getDaemonMachineLockId(options.apiKey);
|
|
7704
|
-
const machineDir =
|
|
7705
|
-
const lockDir =
|
|
7295
|
+
const machineDir = path12.join(rootDir, lockId);
|
|
7296
|
+
const lockDir = path12.join(machineDir, "daemon.lock");
|
|
7706
7297
|
const token = randomUUID2();
|
|
7707
|
-
|
|
7298
|
+
mkdirSync5(machineDir, { recursive: true });
|
|
7708
7299
|
for (let attempt = 0; attempt < 2; attempt += 1) {
|
|
7709
7300
|
try {
|
|
7710
|
-
|
|
7301
|
+
mkdirSync5(lockDir);
|
|
7711
7302
|
const owner = {
|
|
7712
7303
|
pid: process.pid,
|
|
7713
7304
|
token,
|
|
@@ -7717,7 +7308,7 @@ function acquireDaemonMachineLock(options) {
|
|
|
7717
7308
|
apiKeyFingerprint: fingerprint.slice(0, 16)
|
|
7718
7309
|
};
|
|
7719
7310
|
try {
|
|
7720
|
-
|
|
7311
|
+
writeFileSync8(ownerPath(lockDir), `${JSON.stringify(owner, null, 2)}
|
|
7721
7312
|
`, { mode: 384 });
|
|
7722
7313
|
} catch (err) {
|
|
7723
7314
|
rmSync2(lockDir, { recursive: true, force: true });
|
|
@@ -7754,8 +7345,8 @@ function acquireDaemonMachineLock(options) {
|
|
|
7754
7345
|
}
|
|
7755
7346
|
|
|
7756
7347
|
// src/localTraceSink.ts
|
|
7757
|
-
import { appendFileSync, mkdirSync as
|
|
7758
|
-
import
|
|
7348
|
+
import { appendFileSync, mkdirSync as mkdirSync6, readdirSync as readdirSync4, rmSync as rmSync3, statSync as statSync4, writeFileSync as writeFileSync9 } from "fs";
|
|
7349
|
+
import path13 from "path";
|
|
7759
7350
|
var DEFAULT_MAX_FILE_BYTES = 5 * 1024 * 1024;
|
|
7760
7351
|
var DEFAULT_MAX_FILE_AGE_MS = 5 * 60 * 1e3;
|
|
7761
7352
|
var DEFAULT_MAX_FILES = 8;
|
|
@@ -7791,7 +7382,7 @@ var LocalRotatingTraceSink = class {
|
|
|
7791
7382
|
currentSize = 0;
|
|
7792
7383
|
sequence = 0;
|
|
7793
7384
|
constructor(options) {
|
|
7794
|
-
this.traceDir =
|
|
7385
|
+
this.traceDir = path13.join(options.machineDir, "traces");
|
|
7795
7386
|
this.maxFileBytes = Math.max(1024, Math.floor(options.maxFileBytes ?? DEFAULT_MAX_FILE_BYTES));
|
|
7796
7387
|
const baseAgeMs = Math.max(1e3, Math.floor(options.maxFileAgeMs ?? DEFAULT_MAX_FILE_AGE_MS));
|
|
7797
7388
|
const ageJitterMs = Math.max(0, Math.floor(options.maxFileAgeJitterMs ?? 0));
|
|
@@ -7817,15 +7408,15 @@ var LocalRotatingTraceSink = class {
|
|
|
7817
7408
|
return this.currentFile;
|
|
7818
7409
|
}
|
|
7819
7410
|
ensureFile(nextBytes) {
|
|
7820
|
-
|
|
7411
|
+
mkdirSync6(this.traceDir, { recursive: true, mode: 448 });
|
|
7821
7412
|
const nowMs = this.nowMsProvider();
|
|
7822
7413
|
const shouldRotateForAge = this.currentFileOpenedAtMs !== null && nowMs - this.currentFileOpenedAtMs >= this.maxFileAgeMs;
|
|
7823
7414
|
if (!this.currentFile || this.currentSize + nextBytes > this.maxFileBytes || shouldRotateForAge) {
|
|
7824
|
-
this.currentFile =
|
|
7415
|
+
this.currentFile = path13.join(
|
|
7825
7416
|
this.traceDir,
|
|
7826
7417
|
`daemon-trace-${safeTimestamp(nowMs)}-${process.pid}-${String(this.sequence++).padStart(4, "0")}.jsonl`
|
|
7827
7418
|
);
|
|
7828
|
-
|
|
7419
|
+
writeFileSync9(this.currentFile, "", { flag: "a", mode: 384 });
|
|
7829
7420
|
this.currentSize = statSync4(this.currentFile).size;
|
|
7830
7421
|
this.currentFileOpenedAtMs = nowMs;
|
|
7831
7422
|
this.pruneOldFiles();
|
|
@@ -7836,7 +7427,7 @@ var LocalRotatingTraceSink = class {
|
|
|
7836
7427
|
const excess = files.length - this.maxFiles;
|
|
7837
7428
|
if (excess <= 0) return;
|
|
7838
7429
|
for (const file of files.slice(0, excess)) {
|
|
7839
|
-
rmSync3(
|
|
7430
|
+
rmSync3(path13.join(this.traceDir, file), { force: true });
|
|
7840
7431
|
}
|
|
7841
7432
|
}
|
|
7842
7433
|
};
|
|
@@ -7923,11 +7514,11 @@ function isDiagnosticErrorAttr(key) {
|
|
|
7923
7514
|
import { createHash as createHash5, randomUUID as randomUUID3 } from "crypto";
|
|
7924
7515
|
import { gzipSync } from "zlib";
|
|
7925
7516
|
import { mkdir as mkdir2, readFile as readFile2, readdir as readdir3, stat as stat3, writeFile as writeFile2 } from "fs/promises";
|
|
7926
|
-
import
|
|
7517
|
+
import path14 from "path";
|
|
7927
7518
|
|
|
7928
7519
|
// src/directUploadCapability.ts
|
|
7929
|
-
function joinUrl(base,
|
|
7930
|
-
return `${base.replace(/\/+$/, "")}${
|
|
7520
|
+
function joinUrl(base, path16) {
|
|
7521
|
+
return `${base.replace(/\/+$/, "")}${path16}`;
|
|
7931
7522
|
}
|
|
7932
7523
|
function jsonHeaders(apiKey) {
|
|
7933
7524
|
return {
|
|
@@ -8146,7 +7737,7 @@ var DaemonTraceBundleUploader = class {
|
|
|
8146
7737
|
}, nextMs);
|
|
8147
7738
|
}
|
|
8148
7739
|
async findUploadCandidates() {
|
|
8149
|
-
const traceDir =
|
|
7740
|
+
const traceDir = path14.join(this.options.machineDir, "traces");
|
|
8150
7741
|
let names;
|
|
8151
7742
|
try {
|
|
8152
7743
|
names = await readdir3(traceDir);
|
|
@@ -8158,8 +7749,8 @@ var DaemonTraceBundleUploader = class {
|
|
|
8158
7749
|
const currentFile = this.options.currentFileProvider?.();
|
|
8159
7750
|
const candidates = [];
|
|
8160
7751
|
for (const name of names.filter((entry) => entry.startsWith("daemon-trace-") && entry.endsWith(".jsonl")).sort()) {
|
|
8161
|
-
const file =
|
|
8162
|
-
if (currentFile &&
|
|
7752
|
+
const file = path14.join(traceDir, name);
|
|
7753
|
+
if (currentFile && path14.resolve(file) === path14.resolve(currentFile)) continue;
|
|
8163
7754
|
if (await this.isUploaded(file)) continue;
|
|
8164
7755
|
try {
|
|
8165
7756
|
const info = await stat3(file);
|
|
@@ -8233,8 +7824,8 @@ var DaemonTraceBundleUploader = class {
|
|
|
8233
7824
|
}
|
|
8234
7825
|
}
|
|
8235
7826
|
uploadStatePath(file) {
|
|
8236
|
-
const stateDir =
|
|
8237
|
-
return
|
|
7827
|
+
const stateDir = path14.join(this.options.machineDir, "trace-uploads");
|
|
7828
|
+
return path14.join(stateDir, `${path14.basename(file)}.uploaded.json`);
|
|
8238
7829
|
}
|
|
8239
7830
|
async isUploaded(file) {
|
|
8240
7831
|
try {
|
|
@@ -8246,9 +7837,9 @@ var DaemonTraceBundleUploader = class {
|
|
|
8246
7837
|
}
|
|
8247
7838
|
async markUploaded(file, metadata) {
|
|
8248
7839
|
const stateFile = this.uploadStatePath(file);
|
|
8249
|
-
await mkdir2(
|
|
7840
|
+
await mkdir2(path14.dirname(stateFile), { recursive: true, mode: 448 });
|
|
8250
7841
|
await writeFile2(stateFile, `${JSON.stringify({
|
|
8251
|
-
file:
|
|
7842
|
+
file: path14.basename(file),
|
|
8252
7843
|
uploadedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
8253
7844
|
...metadata
|
|
8254
7845
|
}, null, 2)}
|
|
@@ -8267,10 +7858,10 @@ function readPositiveIntegerEnv2(name, fallback) {
|
|
|
8267
7858
|
|
|
8268
7859
|
// src/core.ts
|
|
8269
7860
|
var DEFAULT_TRACE_UPLOAD_URL = "https://slock-trace-upload.botiverse.dev";
|
|
8270
|
-
var DAEMON_CLI_USAGE =
|
|
8271
|
-
function parseDaemonCliArgs(args
|
|
7861
|
+
var DAEMON_CLI_USAGE = "Usage: slock-daemon --server-url <url> --api-key <key>";
|
|
7862
|
+
function parseDaemonCliArgs(args) {
|
|
8272
7863
|
let serverUrl = "";
|
|
8273
|
-
let apiKey =
|
|
7864
|
+
let apiKey = "";
|
|
8274
7865
|
for (let i = 0; i < args.length; i++) {
|
|
8275
7866
|
if (args[i] === "--server-url" && args[i + 1]) serverUrl = args[++i];
|
|
8276
7867
|
if (args[i] === "--api-key" && args[i + 1]) apiKey = args[++i];
|
|
@@ -8287,23 +7878,23 @@ function readDaemonVersion(moduleUrl = import.meta.url) {
|
|
|
8287
7878
|
}
|
|
8288
7879
|
}
|
|
8289
7880
|
function resolveChatBridgePath(moduleUrl = import.meta.url) {
|
|
8290
|
-
const dirname =
|
|
8291
|
-
const jsPath =
|
|
7881
|
+
const dirname = path15.dirname(fileURLToPath(moduleUrl));
|
|
7882
|
+
const jsPath = path15.resolve(dirname, "chat-bridge.js");
|
|
8292
7883
|
try {
|
|
8293
7884
|
accessSync(jsPath);
|
|
8294
7885
|
return jsPath;
|
|
8295
7886
|
} catch {
|
|
8296
|
-
return
|
|
7887
|
+
return path15.resolve(dirname, "chat-bridge.ts");
|
|
8297
7888
|
}
|
|
8298
7889
|
}
|
|
8299
7890
|
function resolveSlockCliPath(moduleUrl = import.meta.url) {
|
|
8300
|
-
const thisDir =
|
|
8301
|
-
const bundledDistPath =
|
|
7891
|
+
const thisDir = path15.dirname(fileURLToPath(moduleUrl));
|
|
7892
|
+
const bundledDistPath = path15.resolve(thisDir, "cli", "index.js");
|
|
8302
7893
|
try {
|
|
8303
7894
|
accessSync(bundledDistPath);
|
|
8304
7895
|
return bundledDistPath;
|
|
8305
7896
|
} catch {
|
|
8306
|
-
const workspaceDistPath =
|
|
7897
|
+
const workspaceDistPath = path15.resolve(thisDir, "..", "..", "cli", "dist", "index.js");
|
|
8307
7898
|
accessSync(workspaceDistPath);
|
|
8308
7899
|
return workspaceDistPath;
|
|
8309
7900
|
}
|
|
@@ -8482,7 +8073,7 @@ var DaemonCore = class {
|
|
|
8482
8073
|
}
|
|
8483
8074
|
resolveMachineStateRoot() {
|
|
8484
8075
|
if (this.options.machineStateDir) return this.options.machineStateDir;
|
|
8485
|
-
if (this.options.dataDir) return
|
|
8076
|
+
if (this.options.dataDir) return path15.join(path15.dirname(this.options.dataDir), "machines");
|
|
8486
8077
|
return resolveDefaultMachineStateRoot();
|
|
8487
8078
|
}
|
|
8488
8079
|
shouldEnableLocalTrace() {
|
|
@@ -8865,8 +8456,6 @@ var DaemonCore = class {
|
|
|
8865
8456
|
};
|
|
8866
8457
|
|
|
8867
8458
|
export {
|
|
8868
|
-
DAEMON_API_KEY_ENV,
|
|
8869
|
-
scrubDaemonAuthEnv,
|
|
8870
8459
|
resolveWorkspaceDirectoryPath,
|
|
8871
8460
|
scanWorkspaceDirectories,
|
|
8872
8461
|
deleteWorkspaceDirectory,
|
package/dist/cli/index.js
CHANGED
|
@@ -14101,7 +14101,6 @@ var SERVER_CAPABILITY_MATRIX = {
|
|
|
14101
14101
|
var RUNTIMES = [
|
|
14102
14102
|
{ id: "claude", displayName: "Claude Code", binary: "claude", supported: true },
|
|
14103
14103
|
{ id: "codex", displayName: "Codex CLI", binary: "codex", supported: true },
|
|
14104
|
-
{ id: "pi", displayName: "Pi", binary: "pi", supported: true },
|
|
14105
14104
|
{ id: "kimi", displayName: "Kimi CLI", binary: "kimi", supported: true },
|
|
14106
14105
|
{ id: "copilot", displayName: "Copilot CLI", binary: "copilot", supported: true },
|
|
14107
14106
|
{ id: "cursor", displayName: "Cursor CLI", binary: "cursor-agent", supported: true },
|
package/dist/core.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import {
|
|
2
|
-
DAEMON_API_KEY_ENV,
|
|
3
2
|
DAEMON_CLI_USAGE,
|
|
4
3
|
DaemonCore,
|
|
5
4
|
deleteWorkspaceDirectory,
|
|
@@ -9,14 +8,12 @@ import {
|
|
|
9
8
|
resolveChatBridgePath,
|
|
10
9
|
resolveSlockCliPath,
|
|
11
10
|
resolveWorkspaceDirectoryPath,
|
|
12
|
-
scanWorkspaceDirectories
|
|
13
|
-
|
|
14
|
-
} from "./chunk-DOUUVDEA.js";
|
|
11
|
+
scanWorkspaceDirectories
|
|
12
|
+
} from "./chunk-RDRY2MW2.js";
|
|
15
13
|
import {
|
|
16
14
|
subscribeDaemonLogs
|
|
17
15
|
} from "./chunk-B7XIMLOT.js";
|
|
18
16
|
export {
|
|
19
|
-
DAEMON_API_KEY_ENV,
|
|
20
17
|
DAEMON_CLI_USAGE,
|
|
21
18
|
DaemonCore,
|
|
22
19
|
deleteWorkspaceDirectory,
|
|
@@ -27,6 +24,5 @@ export {
|
|
|
27
24
|
resolveSlockCliPath,
|
|
28
25
|
resolveWorkspaceDirectoryPath,
|
|
29
26
|
scanWorkspaceDirectories,
|
|
30
|
-
scrubDaemonAuthEnv,
|
|
31
27
|
subscribeDaemonLogs
|
|
32
28
|
};
|
package/dist/index.js
CHANGED
|
@@ -2,14 +2,12 @@
|
|
|
2
2
|
import {
|
|
3
3
|
DAEMON_CLI_USAGE,
|
|
4
4
|
DaemonCore,
|
|
5
|
-
parseDaemonCliArgs
|
|
6
|
-
|
|
7
|
-
} from "./chunk-DOUUVDEA.js";
|
|
5
|
+
parseDaemonCliArgs
|
|
6
|
+
} from "./chunk-RDRY2MW2.js";
|
|
8
7
|
import "./chunk-B7XIMLOT.js";
|
|
9
8
|
|
|
10
9
|
// src/index.ts
|
|
11
|
-
var parsedArgs = parseDaemonCliArgs(process.argv.slice(2)
|
|
12
|
-
scrubDaemonAuthEnv(process.env);
|
|
10
|
+
var parsedArgs = parseDaemonCliArgs(process.argv.slice(2));
|
|
13
11
|
if (!parsedArgs) {
|
|
14
12
|
console.error(DAEMON_CLI_USAGE);
|
|
15
13
|
process.exit(1);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@slock-ai/daemon",
|
|
3
|
-
"version": "0.48.
|
|
3
|
+
"version": "0.48.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"slock-daemon": "dist/index.js"
|
|
@@ -36,7 +36,6 @@
|
|
|
36
36
|
"release:alpha": "npm version prerelease --preid=alpha --no-git-tag-version && cd ../.. && pnpm install --lockfile-only && git add packages/daemon/package.json pnpm-lock.yaml && git commit -m \"chore: bump @slock-ai/daemon to v$(node -p \"require('./packages/daemon/package.json').version\")\" && git tag daemon-v$(node -p \"require('./packages/daemon/package.json').version\") && git push && git push --tags"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@earendil-works/pi-coding-agent": "0.74.0",
|
|
40
39
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
41
40
|
"commander": "^12.1.0",
|
|
42
41
|
"https-proxy-agent": "^7.0.6",
|