@slock-ai/daemon 0.49.0-play.20260516144406 → 0.50.0
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/{chunk-RBTNFLGC.js → chunk-EXJF5JKE.js} +100 -522
- package/dist/cli/index.js +2 -197
- package/dist/core.js +2 -6
- package/dist/index.js +3 -5
- package/package.json +1 -2
- package/dist/drivers/piSdkRunner.js +0 -96
|
@@ -7,11 +7,11 @@ import {
|
|
|
7
7
|
} from "./chunk-KNMCE6WB.js";
|
|
8
8
|
|
|
9
9
|
// src/core.ts
|
|
10
|
-
import
|
|
10
|
+
import path16 from "path";
|
|
11
11
|
import os8 from "os";
|
|
12
12
|
import { createRequire } from "module";
|
|
13
13
|
import { accessSync } from "fs";
|
|
14
|
-
import { fileURLToPath
|
|
14
|
+
import { fileURLToPath } from "url";
|
|
15
15
|
|
|
16
16
|
// ../shared/src/tracing/index.ts
|
|
17
17
|
var DEFAULT_TRACE_FLAGS = "00";
|
|
@@ -723,7 +723,6 @@ var SERVER_CAPABILITY_MATRIX = {
|
|
|
723
723
|
var RUNTIMES = [
|
|
724
724
|
{ id: "claude", displayName: "Claude Code", binary: "claude", supported: true },
|
|
725
725
|
{ id: "codex", displayName: "Codex CLI", binary: "codex", supported: true },
|
|
726
|
-
{ id: "pi", displayName: "Pi", binary: "pi", supported: true },
|
|
727
726
|
{ id: "kimi", displayName: "Kimi CLI", binary: "kimi", supported: true },
|
|
728
727
|
{ id: "copilot", displayName: "Copilot CLI", binary: "copilot", supported: true },
|
|
729
728
|
{ id: "cursor", displayName: "Cursor CLI", binary: "cursor-agent", supported: true },
|
|
@@ -765,10 +764,10 @@ var DISPLAY_PLAN_CONFIG = {
|
|
|
765
764
|
};
|
|
766
765
|
|
|
767
766
|
// src/agentProcessManager.ts
|
|
768
|
-
import { mkdirSync as
|
|
767
|
+
import { mkdirSync as mkdirSync4, readdirSync as readdirSync2, statSync as statSync2, writeFileSync as writeFileSync7 } from "fs";
|
|
769
768
|
import { mkdir, writeFile, access, readdir as readdir2, stat as stat2, readFile, rm as rm2 } from "fs/promises";
|
|
770
769
|
import { createHash as createHash2 } from "crypto";
|
|
771
|
-
import
|
|
770
|
+
import path12 from "path";
|
|
772
771
|
import os6 from "os";
|
|
773
772
|
|
|
774
773
|
// src/drivers/claude.ts
|
|
@@ -872,15 +871,13 @@ Use the \`slock\` CLI for chat / task / attachment operations. The daemon inject
|
|
|
872
871
|
17. **\`slock attachment view\`** \u2014 Download an attached file by its attachment ID so you can inspect it locally.
|
|
873
872
|
18. **\`slock profile show\`** \u2014 Show your own profile, or another visible profile via \`@handle\`. Mirrors the canonical Slock profile view.
|
|
874
873
|
19. **\`slock profile update\`** \u2014 Update your own profile. Supports \`--avatar-file <path>\`, \`--display-name <name>\`, and \`--description <text>\`. Values must be non-empty. Provide at least one flag per call; multiple flags can be combined.
|
|
875
|
-
20. **\`slock
|
|
876
|
-
21. **\`slock
|
|
877
|
-
22. **\`slock reminder
|
|
878
|
-
23. **\`slock reminder
|
|
879
|
-
24. **\`slock reminder
|
|
880
|
-
25. **\`slock reminder
|
|
881
|
-
26. **\`slock
|
|
882
|
-
27. **\`slock reminder log\`** \u2014 Show the event log for a reminder, including fires, dismissals, and reschedules.
|
|
883
|
-
28. **\`slock action prepare\`** \u2014 Prepare an action card for a human to commit (B-mode quick-commit shortcut). Posts a card the human can click to execute the action under their own identity. Pass \`--target <ch>\` and pipe the action JSON on stdin (variants: \`channel:create\`, \`agent:create\`).
|
|
874
|
+
20. **\`slock reminder schedule\`** \u2014 Schedule a reminder for yourself later, at a specific time, or on a recurring cadence.
|
|
875
|
+
21. **\`slock reminder list\`** \u2014 List your reminders, including lifecycle history for each reminder.
|
|
876
|
+
22. **\`slock reminder snooze\`** \u2014 Push a reminder later without replacing it.
|
|
877
|
+
23. **\`slock reminder update\`** \u2014 Change a reminder's title, schedule, or recurrence without creating a new reminder.
|
|
878
|
+
24. **\`slock reminder cancel\`** \u2014 Cancel one of your reminders by ID.
|
|
879
|
+
25. **\`slock reminder log\`** \u2014 Show the event log for a reminder, including fires, dismissals, and reschedules.
|
|
880
|
+
26. **\`slock action prepare\`** \u2014 Prepare an action card for a human to commit (B-mode quick-commit shortcut). Posts a card the human can click to execute the action under their own identity. Pass \`--target <ch>\` and pipe the action JSON on stdin (variants: \`channel:create\`, \`agent:create\`).
|
|
884
881
|
|
|
885
882
|
The CLI prints human-readable canonical text on success (matching the format you see in received messages and history). On failure it prints JSON to stderr:
|
|
886
883
|
- failure \u2192 stderr \`{"ok":false,"code":"...","message":"..."}\` with non-zero exit
|
|
@@ -981,11 +978,6 @@ Each channel has a **name** and optionally a **description** that define its pur
|
|
|
981
978
|
- **Reply in context** \u2014 always respond in the channel/thread the message came from.
|
|
982
979
|
- **Stay on topic** \u2014 when proactively sharing results or updates, post in the channel most relevant to the work. Don't scatter messages across unrelated channels.
|
|
983
980
|
- If unsure where something belongs, call ${serverInfoCmd} to review channel descriptions.`;
|
|
984
|
-
const thirdPartyIntegrationsSection = isCli ? `### Third-party integrations
|
|
985
|
-
|
|
986
|
-
If a registered third-party service requires login, use Slock Agent Login through the CLI instead of asking the human to copy tokens or complete human OAuth for you. If a human asks you to sign into, open, use, or fetch identity from a third-party app, first run \`slock integration list\` and match the app to a registered service before browsing the app. Use \`slock integration login --service <service>\` to provision or reuse your agent login for that service. When the command returns \`Agent login ready\` or \`Already logged in\`, the agent-side login is ready. If the output includes an app URL, open that URL as the service-provided third-party app surface; it should look like the service's normal Login with Slock callback and not require you to understand Slock's internal grant/request protocol. Do not crawl third-party routes looking for a session before trying the registered-service login path. Do not open the human \`Login with Slock\` browser flow, use internal request IDs as OAuth callback codes, or call third-party exchange endpoints unless a human explicitly asks you to debug that server-to-server protocol. If the service or human asks for your Slock Agent identity card, use \`slock profile show\`. Third-party pages may show \`Login with Slock\`; for agent-facing access, prefer the registered service / Slock Agent Login path.` : `### Third-party integrations
|
|
987
|
-
|
|
988
|
-
If a registered third-party service requires login, use Slock Agent Login through the available registered-service interface instead of asking the human to copy tokens or complete human OAuth for you. If a human asks you to sign into, open, use, or fetch identity from a third-party app, first inspect the registered-service interface and match the app to a registered service before browsing the app. Once the registered-service interface reports the agent login is ready, the agent-side login is ready. If that interface provides an app URL, use it as the service-provided third-party app surface; it should look like the service's normal Login with Slock callback and not require you to understand Slock's internal grant/request protocol. Do not crawl third-party routes looking for a session before trying the registered-service login path. Do not open the human \`Login with Slock\` browser flow or treat internal request IDs as OAuth callback codes unless a human explicitly asks you to debug that server-to-server protocol. If the service or human asks for your Slock Agent identity card, use your Slock profile view. Third-party pages may show \`Login with Slock\`; for agent-facing access, prefer the registered service / Slock Agent Login path.`;
|
|
989
981
|
const readingHistorySection = isCli ? `### Reading history
|
|
990
982
|
|
|
991
983
|
\`slock message read --channel "#channel-name"\` or \`slock message read --channel dm:@peer-name\` or \`slock message read --channel "#channel:shortid"\`
|
|
@@ -1157,8 +1149,6 @@ ${discoverySection}
|
|
|
1157
1149
|
|
|
1158
1150
|
${channelAwarenessSection}
|
|
1159
1151
|
|
|
1160
|
-
${thirdPartyIntegrationsSection}
|
|
1161
|
-
|
|
1162
1152
|
${readingHistorySection}
|
|
1163
1153
|
|
|
1164
1154
|
${historicalReferenceSection}
|
|
@@ -1190,17 +1180,6 @@ Keep the user informed. They cannot see your internal reasoning, so:
|
|
|
1190
1180
|
- For multi-step work, send short progress updates (e.g. "Working on step 2/3\u2026").
|
|
1191
1181
|
- When done, summarize the result.
|
|
1192
1182
|
- Keep updates concise \u2014 one or two sentences. Don't flood the chat.
|
|
1193
|
-
- 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:
|
|
1194
|
-
|
|
1195
|
-
\`\`\`html
|
|
1196
|
-
<details>
|
|
1197
|
-
<summary>Evidence, logs, or edge cases</summary>
|
|
1198
|
-
|
|
1199
|
-
Detailed notes go here.
|
|
1200
|
-
</details>
|
|
1201
|
-
\`\`\`
|
|
1202
|
-
|
|
1203
|
-
Do not hide the main recommendation, blocker, or required action inside \`<details>\`; only fold supporting evidence, logs, alternatives, or extended rationale.
|
|
1204
1183
|
|
|
1205
1184
|
### Conversation etiquette
|
|
1206
1185
|
|
|
@@ -1370,19 +1349,6 @@ function listLegacySlockStatePaths(slockHome = resolveSlockHome(), homeDir = os.
|
|
|
1370
1349
|
return candidates.filter((candidate) => existsSync(candidate.path));
|
|
1371
1350
|
}
|
|
1372
1351
|
|
|
1373
|
-
// src/authEnv.ts
|
|
1374
|
-
var DAEMON_API_KEY_ENV = "SLOCK_MACHINE_API_KEY";
|
|
1375
|
-
var SLOCK_AGENT_TOKEN_ENV = "SLOCK_AGENT_TOKEN";
|
|
1376
|
-
function scrubDaemonAuthEnv(env) {
|
|
1377
|
-
delete env[DAEMON_API_KEY_ENV];
|
|
1378
|
-
return env;
|
|
1379
|
-
}
|
|
1380
|
-
function scrubDaemonChildEnv(env) {
|
|
1381
|
-
delete env[DAEMON_API_KEY_ENV];
|
|
1382
|
-
delete env[SLOCK_AGENT_TOKEN_ENV];
|
|
1383
|
-
return env;
|
|
1384
|
-
}
|
|
1385
|
-
|
|
1386
1352
|
// src/drivers/cliTransport.ts
|
|
1387
1353
|
var shellSingleQuote = (value) => `'${value.replace(/'/g, `'\\''`)}'`;
|
|
1388
1354
|
function runtimeContextEnv(config) {
|
|
@@ -1410,12 +1376,6 @@ function prepareCliTransport(ctx, extraEnv = {}, platform = process.platform) {
|
|
|
1410
1376
|
mkdirSync(slockDir, { recursive: true });
|
|
1411
1377
|
const tokenFile = path2.join(slockDir, "agent-token");
|
|
1412
1378
|
writeFileSync(tokenFile, ctx.config.authToken || ctx.daemonApiKey, { mode: 384 });
|
|
1413
|
-
const agentCredentialKey = ctx.config.agentCredentialKey;
|
|
1414
|
-
let agentCredentialKeyFile = null;
|
|
1415
|
-
if (typeof agentCredentialKey === "string" && agentCredentialKey.length > 0) {
|
|
1416
|
-
agentCredentialKeyFile = path2.join(slockDir, "agent-credential-key");
|
|
1417
|
-
writeFileSync(agentCredentialKeyFile, agentCredentialKey, { mode: 384 });
|
|
1418
|
-
}
|
|
1419
1379
|
const posixWrapper = path2.join(slockDir, "slock");
|
|
1420
1380
|
const posixBody = `#!/usr/bin/env bash
|
|
1421
1381
|
exec ${shellSingleQuote(process.execPath)} ${shellSingleQuote(ctx.slockCliPath)} "$@"
|
|
@@ -1440,15 +1400,12 @@ exec ${shellSingleQuote(process.execPath)} ${shellSingleQuote(ctx.slockCliPath)}
|
|
|
1440
1400
|
...ctx.launchId ? { SLOCK_AGENT_LAUNCH_ID: ctx.launchId } : {},
|
|
1441
1401
|
SLOCK_SERVER_URL: ctx.config.serverUrl,
|
|
1442
1402
|
SLOCK_AGENT_TOKEN_FILE: tokenFile,
|
|
1443
|
-
...agentCredentialKeyFile ? { SLOCK_AGENT_CREDENTIAL_KEY_FILE: agentCredentialKeyFile } : {},
|
|
1444
1403
|
PATH: `${slockDir}${path2.delimiter}${process.env.PATH ?? ""}`
|
|
1445
1404
|
};
|
|
1446
|
-
|
|
1447
|
-
delete spawnEnv.SLOCK_AGENT_CREDENTIAL_KEY;
|
|
1405
|
+
delete spawnEnv.SLOCK_AGENT_TOKEN;
|
|
1448
1406
|
return {
|
|
1449
1407
|
slockDir,
|
|
1450
1408
|
tokenFile,
|
|
1451
|
-
agentCredentialKeyFile,
|
|
1452
1409
|
wrapperPath,
|
|
1453
1410
|
spawnEnv
|
|
1454
1411
|
};
|
|
@@ -1482,7 +1439,7 @@ function resolveCommandOnWindows(command, env, execFileSyncFn) {
|
|
|
1482
1439
|
}
|
|
1483
1440
|
function resolveCommandOnPath(command, deps = {}) {
|
|
1484
1441
|
const platform = deps.platform ?? process.platform;
|
|
1485
|
-
const env =
|
|
1442
|
+
const env = deps.env ?? process.env;
|
|
1486
1443
|
const execFileSyncFn = deps.execFileSyncFn ?? execFileSync;
|
|
1487
1444
|
if (platform === "win32") {
|
|
1488
1445
|
return resolveCommandOnWindows(command, env, execFileSyncFn);
|
|
@@ -1507,7 +1464,7 @@ function firstExistingPath(candidates, deps = {}) {
|
|
|
1507
1464
|
return null;
|
|
1508
1465
|
}
|
|
1509
1466
|
function readCommandVersion(command, args = [], deps = {}) {
|
|
1510
|
-
const env =
|
|
1467
|
+
const env = deps.env ?? process.env;
|
|
1511
1468
|
const execFileSyncFn = deps.execFileSyncFn ?? execFileSync;
|
|
1512
1469
|
try {
|
|
1513
1470
|
const output = normalizeExecOutput(execFileSyncFn(command, [...args, "--version"], {
|
|
@@ -2784,7 +2741,7 @@ function detectCursorModels(runCommand = runCursorModelsCommand) {
|
|
|
2784
2741
|
}
|
|
2785
2742
|
function runCursorModelsCommand() {
|
|
2786
2743
|
return spawnSync("cursor-agent", ["models"], {
|
|
2787
|
-
env:
|
|
2744
|
+
env: { ...process.env, FORCE_COLOR: "0", NO_COLOR: "1" },
|
|
2788
2745
|
encoding: "utf8",
|
|
2789
2746
|
timeout: 5e3
|
|
2790
2747
|
});
|
|
@@ -2831,7 +2788,7 @@ function resolveGeminiSpawn(commandArgs, deps = {}) {
|
|
|
2831
2788
|
}
|
|
2832
2789
|
const execFileSyncFn = deps.execFileSyncFn ?? execFileSync3;
|
|
2833
2790
|
const existsSyncFn = deps.existsSyncFn ?? existsSync6;
|
|
2834
|
-
const env =
|
|
2791
|
+
const env = deps.env ?? process.env;
|
|
2835
2792
|
const winPath = path8.win32;
|
|
2836
2793
|
let geminiEntry = null;
|
|
2837
2794
|
try {
|
|
@@ -3005,16 +2962,13 @@ var GeminiDriver = class {
|
|
|
3005
2962
|
// src/drivers/kimi.ts
|
|
3006
2963
|
import { randomUUID } from "crypto";
|
|
3007
2964
|
import { spawn as spawn6 } from "child_process";
|
|
3008
|
-
import {
|
|
2965
|
+
import { existsSync as existsSync7, readFileSync as readFileSync3, writeFileSync as writeFileSync6 } from "fs";
|
|
3009
2966
|
import os4 from "os";
|
|
3010
2967
|
import path9 from "path";
|
|
3011
2968
|
var KIMI_WIRE_PROTOCOL_VERSION = "1.3";
|
|
3012
2969
|
var KIMI_SYSTEM_PROMPT_FILE = ".slock-kimi-system.md";
|
|
3013
2970
|
var KIMI_AGENT_FILE = ".slock-kimi-agent.yaml";
|
|
3014
2971
|
var KIMI_MCP_FILE = ".slock-kimi-mcp.json";
|
|
3015
|
-
var KIMI_GENERATED_CONFIG_FILE = ".slock-kimi-config.toml";
|
|
3016
|
-
var SLOCK_KIMI_CONFIG_CONTENT_ENV = "SLOCK_KIMI_CONFIG_CONTENT";
|
|
3017
|
-
var SLOCK_KIMI_CONFIG_FILE_ENV = "SLOCK_KIMI_CONFIG_FILE";
|
|
3018
2972
|
function parseToolArguments(raw) {
|
|
3019
2973
|
if (typeof raw !== "string") return raw;
|
|
3020
2974
|
try {
|
|
@@ -3023,73 +2977,6 @@ function parseToolArguments(raw) {
|
|
|
3023
2977
|
return raw;
|
|
3024
2978
|
}
|
|
3025
2979
|
}
|
|
3026
|
-
function readKimiConfigSource(home = os4.homedir(), env = process.env) {
|
|
3027
|
-
const inlineConfig = env[SLOCK_KIMI_CONFIG_CONTENT_ENV];
|
|
3028
|
-
if (inlineConfig && inlineConfig.trim()) {
|
|
3029
|
-
return {
|
|
3030
|
-
raw: inlineConfig,
|
|
3031
|
-
explicitPath: null,
|
|
3032
|
-
sourcePath: SLOCK_KIMI_CONFIG_CONTENT_ENV
|
|
3033
|
-
};
|
|
3034
|
-
}
|
|
3035
|
-
const explicitPath = env[SLOCK_KIMI_CONFIG_FILE_ENV];
|
|
3036
|
-
const configPath = explicitPath && explicitPath.trim() ? explicitPath : path9.join(home, ".kimi", "config.toml");
|
|
3037
|
-
try {
|
|
3038
|
-
return {
|
|
3039
|
-
raw: readFileSync3(configPath, "utf8"),
|
|
3040
|
-
explicitPath: explicitPath && explicitPath.trim() ? explicitPath : null,
|
|
3041
|
-
sourcePath: configPath
|
|
3042
|
-
};
|
|
3043
|
-
} catch {
|
|
3044
|
-
return {
|
|
3045
|
-
raw: null,
|
|
3046
|
-
explicitPath: explicitPath && explicitPath.trim() ? explicitPath : null,
|
|
3047
|
-
sourcePath: configPath
|
|
3048
|
-
};
|
|
3049
|
-
}
|
|
3050
|
-
}
|
|
3051
|
-
function buildKimiSpawnEnv(env = process.env) {
|
|
3052
|
-
const spawnEnv = { ...env, FORCE_COLOR: "0", NO_COLOR: "1" };
|
|
3053
|
-
delete spawnEnv[SLOCK_KIMI_CONFIG_CONTENT_ENV];
|
|
3054
|
-
delete spawnEnv[SLOCK_KIMI_CONFIG_FILE_ENV];
|
|
3055
|
-
return scrubDaemonChildEnv(spawnEnv);
|
|
3056
|
-
}
|
|
3057
|
-
function buildKimiEffectiveEnv(ctx, overrideEnv) {
|
|
3058
|
-
return {
|
|
3059
|
-
...process.env,
|
|
3060
|
-
...ctx.config.envVars || {},
|
|
3061
|
-
...overrideEnv || {}
|
|
3062
|
-
};
|
|
3063
|
-
}
|
|
3064
|
-
function buildKimiLaunchOptions(ctx, opts = {}) {
|
|
3065
|
-
const env = buildKimiEffectiveEnv(ctx, opts.env);
|
|
3066
|
-
const source = readKimiConfigSource(opts.home ?? os4.homedir(), env);
|
|
3067
|
-
const args = [];
|
|
3068
|
-
let configFilePath = null;
|
|
3069
|
-
let configContent = null;
|
|
3070
|
-
if (source.explicitPath) {
|
|
3071
|
-
configFilePath = source.explicitPath;
|
|
3072
|
-
} else if (source.raw !== null && source.sourcePath === SLOCK_KIMI_CONFIG_CONTENT_ENV) {
|
|
3073
|
-
configFilePath = path9.join(ctx.workingDirectory, KIMI_GENERATED_CONFIG_FILE);
|
|
3074
|
-
configContent = source.raw;
|
|
3075
|
-
if (opts.writeGeneratedConfig !== false) {
|
|
3076
|
-
writeFileSync6(configFilePath, source.raw, { encoding: "utf8", mode: 384 });
|
|
3077
|
-
chmodSync(configFilePath, 384);
|
|
3078
|
-
}
|
|
3079
|
-
}
|
|
3080
|
-
if (configFilePath) {
|
|
3081
|
-
args.push("--config-file", configFilePath);
|
|
3082
|
-
}
|
|
3083
|
-
if (ctx.config.model && ctx.config.model !== "default") {
|
|
3084
|
-
args.push("--model", ctx.config.model);
|
|
3085
|
-
}
|
|
3086
|
-
return {
|
|
3087
|
-
args,
|
|
3088
|
-
env: buildKimiSpawnEnv(env),
|
|
3089
|
-
configFilePath,
|
|
3090
|
-
configContent
|
|
3091
|
-
};
|
|
3092
|
-
}
|
|
3093
2980
|
function resolveKimiSpawn(commandArgs, deps = {}) {
|
|
3094
2981
|
return {
|
|
3095
2982
|
command: resolveCommandOnPath("kimi", deps) ?? "kimi",
|
|
@@ -3113,25 +3000,7 @@ var KimiDriver = class {
|
|
|
3113
3000
|
};
|
|
3114
3001
|
model = {
|
|
3115
3002
|
detectedModelsVerifiedAs: "launchable",
|
|
3116
|
-
toLaunchSpec: (modelId
|
|
3117
|
-
if (!ctx) return { args: ["--model", modelId] };
|
|
3118
|
-
const launchCtx = {
|
|
3119
|
-
...ctx,
|
|
3120
|
-
config: {
|
|
3121
|
-
...ctx.config,
|
|
3122
|
-
model: modelId
|
|
3123
|
-
}
|
|
3124
|
-
};
|
|
3125
|
-
const launch = buildKimiLaunchOptions(launchCtx, {
|
|
3126
|
-
home: opts?.home,
|
|
3127
|
-
writeGeneratedConfig: false
|
|
3128
|
-
});
|
|
3129
|
-
return {
|
|
3130
|
-
args: launch.args,
|
|
3131
|
-
env: launch.env,
|
|
3132
|
-
configFiles: launch.configFilePath ? [launch.configFilePath] : void 0
|
|
3133
|
-
};
|
|
3134
|
-
}
|
|
3003
|
+
toLaunchSpec: (modelId) => ({ args: ["--model", modelId] })
|
|
3135
3004
|
};
|
|
3136
3005
|
supportsStdinNotification = true;
|
|
3137
3006
|
mcpToolPrefix = "";
|
|
@@ -3185,7 +3054,6 @@ var KimiDriver = class {
|
|
|
3185
3054
|
}
|
|
3186
3055
|
}
|
|
3187
3056
|
}), "utf8");
|
|
3188
|
-
const launch = buildKimiLaunchOptions(ctx);
|
|
3189
3057
|
const args = [
|
|
3190
3058
|
"--wire",
|
|
3191
3059
|
"--yolo",
|
|
@@ -3194,15 +3062,14 @@ var KimiDriver = class {
|
|
|
3194
3062
|
"--mcp-config-file",
|
|
3195
3063
|
mcpConfigPath,
|
|
3196
3064
|
"--session",
|
|
3197
|
-
this.sessionId
|
|
3198
|
-
...launch.args
|
|
3065
|
+
this.sessionId
|
|
3199
3066
|
];
|
|
3200
3067
|
if (ctx.config.model && ctx.config.model !== "default") {
|
|
3201
3068
|
args.push("--model", ctx.config.model);
|
|
3202
3069
|
}
|
|
3203
3070
|
const spawnEnv = prepareCliTransport(ctx, { NO_COLOR: "1" }).spawnEnv;
|
|
3204
|
-
const
|
|
3205
|
-
const proc = spawn6(
|
|
3071
|
+
const launch = resolveKimiSpawn(args);
|
|
3072
|
+
const proc = spawn6(launch.command, launch.args, {
|
|
3206
3073
|
cwd: ctx.workingDirectory,
|
|
3207
3074
|
stdio: ["pipe", "pipe", "pipe"],
|
|
3208
3075
|
env: spawnEnv,
|
|
@@ -3210,7 +3077,7 @@ var KimiDriver = class {
|
|
|
3210
3077
|
// and has an 8191-character command-line limit. Kimi's official
|
|
3211
3078
|
// installer/uv entrypoint is an executable, so launch it directly and
|
|
3212
3079
|
// keep prompts on stdin / files instead of routing through cmd.exe.
|
|
3213
|
-
shell:
|
|
3080
|
+
shell: launch.shell
|
|
3214
3081
|
});
|
|
3215
3082
|
proc.stdin?.write(JSON.stringify({
|
|
3216
3083
|
jsonrpc: "2.0",
|
|
@@ -3326,9 +3193,14 @@ var KimiDriver = class {
|
|
|
3326
3193
|
return detectKimiModels();
|
|
3327
3194
|
}
|
|
3328
3195
|
};
|
|
3329
|
-
function detectKimiModels(home = os4.homedir()
|
|
3330
|
-
const
|
|
3331
|
-
|
|
3196
|
+
function detectKimiModels(home = os4.homedir()) {
|
|
3197
|
+
const configPath = path9.join(home, ".kimi", "config.toml");
|
|
3198
|
+
let raw;
|
|
3199
|
+
try {
|
|
3200
|
+
raw = readFileSync3(configPath, "utf8");
|
|
3201
|
+
} catch {
|
|
3202
|
+
return null;
|
|
3203
|
+
}
|
|
3332
3204
|
const models = [];
|
|
3333
3205
|
const sectionRe = /^\s*\[models(?:\.([^\]]+)|"\.[^"]+"|\."[^"]+")\s*\]\s*$/gm;
|
|
3334
3206
|
const lineRe = /^\s*\[models\.(.+?)\s*\]\s*$/gm;
|
|
@@ -3575,7 +3447,7 @@ function detectOpenCodeModels(home = os5.homedir(), runCommand = runOpenCodeMode
|
|
|
3575
3447
|
}
|
|
3576
3448
|
function runOpenCodeModelsCommand(home) {
|
|
3577
3449
|
const result = spawnSync2("opencode", ["models"], {
|
|
3578
|
-
env:
|
|
3450
|
+
env: { ...process.env, HOME: home, FORCE_COLOR: "0", NO_COLOR: "1" },
|
|
3579
3451
|
encoding: "utf8",
|
|
3580
3452
|
timeout: 5e3
|
|
3581
3453
|
});
|
|
@@ -3731,297 +3603,6 @@ var OpenCodeDriver = class {
|
|
|
3731
3603
|
}
|
|
3732
3604
|
};
|
|
3733
3605
|
|
|
3734
|
-
// src/drivers/pi.ts
|
|
3735
|
-
import { spawn as spawn8 } from "child_process";
|
|
3736
|
-
import { existsSync as existsSync8, mkdirSync as mkdirSync4, writeFileSync as writeFileSync7 } from "fs";
|
|
3737
|
-
import path11 from "path";
|
|
3738
|
-
import { fileURLToPath } from "url";
|
|
3739
|
-
import { getAgentDir, VERSION as PI_SDK_VERSION } from "@earendil-works/pi-coding-agent";
|
|
3740
|
-
var CHAT_MCP_TOOL_PREFIX2 = "chat_";
|
|
3741
|
-
var NO_MESSAGE_PROMPT2 = "No new messages are pending. Stop now.";
|
|
3742
|
-
var FIRST_MESSAGE_TASK_PREFIX2 = "First message task (system-triggered):";
|
|
3743
|
-
var MIN_SUPPORTED_PI_VERSION = "0.74.0";
|
|
3744
|
-
function parseSemver2(version) {
|
|
3745
|
-
const match = version.match(/(\d+)\.(\d+)\.(\d+)/);
|
|
3746
|
-
if (!match) return null;
|
|
3747
|
-
return [Number(match[1]), Number(match[2]), Number(match[3])];
|
|
3748
|
-
}
|
|
3749
|
-
function isSupportedPiVersion(version) {
|
|
3750
|
-
if (!version) return true;
|
|
3751
|
-
const actual = parseSemver2(version);
|
|
3752
|
-
const minimum = parseSemver2(MIN_SUPPORTED_PI_VERSION);
|
|
3753
|
-
if (!actual || !minimum) return true;
|
|
3754
|
-
for (let i = 0; i < 3; i += 1) {
|
|
3755
|
-
if (actual[i] > minimum[i]) return true;
|
|
3756
|
-
if (actual[i] < minimum[i]) return false;
|
|
3757
|
-
}
|
|
3758
|
-
return true;
|
|
3759
|
-
}
|
|
3760
|
-
function unsupportedPiVersionMessage(version) {
|
|
3761
|
-
if (!version || isSupportedPiVersion(version)) return null;
|
|
3762
|
-
return `Pi SDK ${version} is unsupported; requires @earendil-works/pi-coding-agent >= ${MIN_SUPPORTED_PI_VERSION}. Upgrade the daemon Pi dependency before starting this runtime.`;
|
|
3763
|
-
}
|
|
3764
|
-
function probePi(version = PI_SDK_VERSION) {
|
|
3765
|
-
const unsupportedMessage = unsupportedPiVersionMessage(version);
|
|
3766
|
-
if (unsupportedMessage) {
|
|
3767
|
-
return {
|
|
3768
|
-
available: false,
|
|
3769
|
-
version: `${version} (requires @earendil-works/pi-coding-agent >= ${MIN_SUPPORTED_PI_VERSION})`
|
|
3770
|
-
};
|
|
3771
|
-
}
|
|
3772
|
-
return { available: true, version };
|
|
3773
|
-
}
|
|
3774
|
-
function resolvePiSdkRunnerPath(moduleUrl = import.meta.url) {
|
|
3775
|
-
const moduleDir = path11.dirname(fileURLToPath(moduleUrl));
|
|
3776
|
-
const sourceSibling = path11.join(moduleDir, "piSdkRunner.ts");
|
|
3777
|
-
if (existsSync8(sourceSibling)) return sourceSibling;
|
|
3778
|
-
const bundledEntry = path11.join(moduleDir, "drivers", "piSdkRunner.js");
|
|
3779
|
-
if (existsSync8(bundledEntry)) return bundledEntry;
|
|
3780
|
-
return path11.join(moduleDir, "piSdkRunner.js");
|
|
3781
|
-
}
|
|
3782
|
-
function buildPiSdkNodeArgs(runnerPath = resolvePiSdkRunnerPath()) {
|
|
3783
|
-
if (runnerPath.endsWith(".ts")) {
|
|
3784
|
-
return [...process.execArgv, runnerPath];
|
|
3785
|
-
}
|
|
3786
|
-
return [runnerPath];
|
|
3787
|
-
}
|
|
3788
|
-
function buildPiLaunchOptions(ctx, opts = {}) {
|
|
3789
|
-
const command = opts.command ?? process.execPath;
|
|
3790
|
-
const piDir = path11.join(ctx.workingDirectory, ".slock", "pi");
|
|
3791
|
-
const sessionDir = path11.join(piDir, "sessions");
|
|
3792
|
-
mkdirSync4(sessionDir, { recursive: true });
|
|
3793
|
-
const slock = prepareCliTransport(ctx, { NO_COLOR: "1" });
|
|
3794
|
-
const runnerPath = opts.runnerPath ?? resolvePiSdkRunnerPath();
|
|
3795
|
-
const agentDir = opts.agentDir ?? getAgentDir();
|
|
3796
|
-
const runnerConfigPath = path11.join(
|
|
3797
|
-
piDir,
|
|
3798
|
-
`sdk-run-${(ctx.launchId || "launch").replace(/[^a-zA-Z0-9_.-]/g, "_")}.json`
|
|
3799
|
-
);
|
|
3800
|
-
const turnPrompt = ctx.prompt === ctx.standingPrompt ? NO_MESSAGE_PROMPT2 : ctx.prompt;
|
|
3801
|
-
const runnerConfig = {
|
|
3802
|
-
cwd: ctx.workingDirectory,
|
|
3803
|
-
agentDir,
|
|
3804
|
-
sessionDir,
|
|
3805
|
-
sessionId: ctx.config.sessionId || null,
|
|
3806
|
-
standingPrompt: ctx.standingPrompt,
|
|
3807
|
-
prompt: turnPrompt,
|
|
3808
|
-
model: ctx.config.model && ctx.config.model !== "default" ? ctx.config.model : null
|
|
3809
|
-
};
|
|
3810
|
-
writeFileSync7(runnerConfigPath, `${JSON.stringify(runnerConfig)}
|
|
3811
|
-
`, { encoding: "utf8", mode: 384 });
|
|
3812
|
-
const args = [
|
|
3813
|
-
...buildPiSdkNodeArgs(runnerPath),
|
|
3814
|
-
"--config",
|
|
3815
|
-
runnerConfigPath
|
|
3816
|
-
];
|
|
3817
|
-
return {
|
|
3818
|
-
command,
|
|
3819
|
-
args,
|
|
3820
|
-
env: slock.spawnEnv,
|
|
3821
|
-
sessionDir,
|
|
3822
|
-
agentDir,
|
|
3823
|
-
runnerConfigPath,
|
|
3824
|
-
sdkVersion: PI_SDK_VERSION
|
|
3825
|
-
};
|
|
3826
|
-
}
|
|
3827
|
-
function isSystemFirstMessageTask2(message) {
|
|
3828
|
-
return message.sender_id === "system" && message.channel_type === "channel" && message.channel_name === "all" && message.content.trimStart().startsWith(FIRST_MESSAGE_TASK_PREFIX2);
|
|
3829
|
-
}
|
|
3830
|
-
function buildPiSystemPrompt(config) {
|
|
3831
|
-
return buildCliTransportSystemPrompt(config, {
|
|
3832
|
-
toolPrefix: CHAT_MCP_TOOL_PREFIX2,
|
|
3833
|
-
extraCriticalRules: [
|
|
3834
|
-
"- 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."
|
|
3835
|
-
],
|
|
3836
|
-
postStartupNotes: [
|
|
3837
|
-
"**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."
|
|
3838
|
-
],
|
|
3839
|
-
includeStdinNotificationSection: false,
|
|
3840
|
-
messageNotificationStyle: "poll"
|
|
3841
|
-
});
|
|
3842
|
-
}
|
|
3843
|
-
function contentText(content) {
|
|
3844
|
-
if (!content) return "";
|
|
3845
|
-
const chunks = [];
|
|
3846
|
-
for (const item of content) {
|
|
3847
|
-
if (item.type === "text" && typeof item.text === "string") {
|
|
3848
|
-
chunks.push(item.text);
|
|
3849
|
-
}
|
|
3850
|
-
}
|
|
3851
|
-
return chunks.join("");
|
|
3852
|
-
}
|
|
3853
|
-
function apiKeyErrorMessage(line) {
|
|
3854
|
-
const trimmed = line.trim();
|
|
3855
|
-
if (!trimmed) return null;
|
|
3856
|
-
if (/no api key found/i.test(trimmed)) return trimmed;
|
|
3857
|
-
if (/api key.+required/i.test(trimmed)) return trimmed;
|
|
3858
|
-
if (/no models available/i.test(trimmed)) return trimmed;
|
|
3859
|
-
return null;
|
|
3860
|
-
}
|
|
3861
|
-
var PiDriver = class {
|
|
3862
|
-
id = "pi";
|
|
3863
|
-
lifecycle = {
|
|
3864
|
-
kind: "per_turn",
|
|
3865
|
-
start: "defer_until_concrete_message",
|
|
3866
|
-
exit: "terminate_on_turn_end",
|
|
3867
|
-
inFlightWake: "coalesce_into_pending"
|
|
3868
|
-
};
|
|
3869
|
-
communication = {
|
|
3870
|
-
chat: "slock_cli",
|
|
3871
|
-
runtimeControl: "none"
|
|
3872
|
-
};
|
|
3873
|
-
session = {
|
|
3874
|
-
recovery: "resume_or_fresh"
|
|
3875
|
-
};
|
|
3876
|
-
model = {
|
|
3877
|
-
detectedModelsVerifiedAs: "launchable",
|
|
3878
|
-
toLaunchSpec: (modelId, ctx) => {
|
|
3879
|
-
if (!ctx) return modelId && modelId !== "default" ? { args: ["--model", modelId] } : { args: [] };
|
|
3880
|
-
const launchCtx = {
|
|
3881
|
-
...ctx,
|
|
3882
|
-
config: {
|
|
3883
|
-
...ctx.config,
|
|
3884
|
-
model: modelId
|
|
3885
|
-
}
|
|
3886
|
-
};
|
|
3887
|
-
const launch = buildPiLaunchOptions(launchCtx);
|
|
3888
|
-
return {
|
|
3889
|
-
args: launch.args,
|
|
3890
|
-
env: launch.env,
|
|
3891
|
-
configFiles: [launch.runnerConfigPath],
|
|
3892
|
-
params: {
|
|
3893
|
-
agentDir: launch.agentDir,
|
|
3894
|
-
sessionDir: launch.sessionDir,
|
|
3895
|
-
sdkVersion: launch.sdkVersion,
|
|
3896
|
-
resources: "extensions/skills/prompt-templates/themes/context-files disabled by Slock policy"
|
|
3897
|
-
}
|
|
3898
|
-
};
|
|
3899
|
-
}
|
|
3900
|
-
};
|
|
3901
|
-
supportsStdinNotification = false;
|
|
3902
|
-
mcpToolPrefix = CHAT_MCP_TOOL_PREFIX2;
|
|
3903
|
-
busyDeliveryMode = "none";
|
|
3904
|
-
terminateProcessOnTurnEnd = true;
|
|
3905
|
-
deferSpawnUntilMessage = true;
|
|
3906
|
-
usesSlockCliForCommunication = true;
|
|
3907
|
-
sessionId = null;
|
|
3908
|
-
sessionAnnounced = false;
|
|
3909
|
-
apiKeyErrorAnnounced = false;
|
|
3910
|
-
turnEnded = false;
|
|
3911
|
-
assistantTextByMessageId = /* @__PURE__ */ new Map();
|
|
3912
|
-
shouldDeferWakeMessage(message) {
|
|
3913
|
-
return isSystemFirstMessageTask2(message);
|
|
3914
|
-
}
|
|
3915
|
-
probe() {
|
|
3916
|
-
return probePi();
|
|
3917
|
-
}
|
|
3918
|
-
async detectModels() {
|
|
3919
|
-
return null;
|
|
3920
|
-
}
|
|
3921
|
-
spawn(ctx) {
|
|
3922
|
-
this.sessionId = ctx.config.sessionId || null;
|
|
3923
|
-
this.sessionAnnounced = false;
|
|
3924
|
-
this.apiKeyErrorAnnounced = false;
|
|
3925
|
-
this.turnEnded = false;
|
|
3926
|
-
this.assistantTextByMessageId.clear();
|
|
3927
|
-
const unsupportedMessage = unsupportedPiVersionMessage(PI_SDK_VERSION);
|
|
3928
|
-
if (unsupportedMessage) throw new Error(unsupportedMessage);
|
|
3929
|
-
const launch = buildPiLaunchOptions(ctx);
|
|
3930
|
-
const proc = spawn8(launch.command, launch.args, {
|
|
3931
|
-
cwd: ctx.workingDirectory,
|
|
3932
|
-
stdio: ["pipe", "pipe", "pipe"],
|
|
3933
|
-
env: launch.env,
|
|
3934
|
-
shell: false
|
|
3935
|
-
});
|
|
3936
|
-
proc.stdin?.end();
|
|
3937
|
-
return { process: proc };
|
|
3938
|
-
}
|
|
3939
|
-
parseLine(line) {
|
|
3940
|
-
let event;
|
|
3941
|
-
try {
|
|
3942
|
-
event = JSON.parse(line);
|
|
3943
|
-
} catch {
|
|
3944
|
-
if (this.apiKeyErrorAnnounced) return [];
|
|
3945
|
-
const message = apiKeyErrorMessage(line);
|
|
3946
|
-
if (!message) return [];
|
|
3947
|
-
this.apiKeyErrorAnnounced = true;
|
|
3948
|
-
this.turnEnded = true;
|
|
3949
|
-
return [
|
|
3950
|
-
{ kind: "error", message },
|
|
3951
|
-
{ kind: "turn_end", sessionId: this.sessionId || void 0 }
|
|
3952
|
-
];
|
|
3953
|
-
}
|
|
3954
|
-
const events = [];
|
|
3955
|
-
if (event.type === "session" && event.id) {
|
|
3956
|
-
this.sessionId = event.id;
|
|
3957
|
-
}
|
|
3958
|
-
if (!this.sessionAnnounced && this.sessionId) {
|
|
3959
|
-
events.push({ kind: "session_init", sessionId: this.sessionId });
|
|
3960
|
-
this.sessionAnnounced = true;
|
|
3961
|
-
}
|
|
3962
|
-
switch (event.type) {
|
|
3963
|
-
case "agent_start":
|
|
3964
|
-
case "turn_start":
|
|
3965
|
-
events.push({ kind: "thinking", text: "" });
|
|
3966
|
-
break;
|
|
3967
|
-
case "message_update":
|
|
3968
|
-
case "message_end":
|
|
3969
|
-
if (event.message?.role === "assistant") {
|
|
3970
|
-
const key = event.message.id || "current";
|
|
3971
|
-
const currentText = contentText(event.message.content);
|
|
3972
|
-
const previousText = this.assistantTextByMessageId.get(key) ?? "";
|
|
3973
|
-
if (currentText.length > previousText.length && currentText.startsWith(previousText)) {
|
|
3974
|
-
events.push({ kind: "text", text: currentText.slice(previousText.length) });
|
|
3975
|
-
} else if (currentText && currentText !== previousText) {
|
|
3976
|
-
events.push({ kind: "text", text: currentText });
|
|
3977
|
-
}
|
|
3978
|
-
this.assistantTextByMessageId.set(key, currentText);
|
|
3979
|
-
if (event.message.stopReason === "error" || event.message.stopReason === "aborted") {
|
|
3980
|
-
events.push({ kind: "error", message: event.message.errorMessage || `Request ${event.message.stopReason}` });
|
|
3981
|
-
}
|
|
3982
|
-
}
|
|
3983
|
-
break;
|
|
3984
|
-
case "tool_execution_start":
|
|
3985
|
-
events.push({
|
|
3986
|
-
kind: "tool_call",
|
|
3987
|
-
name: event.toolName || "unknown_tool",
|
|
3988
|
-
input: event.args
|
|
3989
|
-
});
|
|
3990
|
-
break;
|
|
3991
|
-
case "tool_execution_end":
|
|
3992
|
-
events.push({
|
|
3993
|
-
kind: "tool_output",
|
|
3994
|
-
name: event.toolName || "unknown_tool"
|
|
3995
|
-
});
|
|
3996
|
-
if (event.isError) {
|
|
3997
|
-
events.push({ kind: "error", message: `Pi tool ${event.toolName || "unknown_tool"} failed` });
|
|
3998
|
-
}
|
|
3999
|
-
break;
|
|
4000
|
-
case "compaction_start":
|
|
4001
|
-
events.push({ kind: "compaction_started" });
|
|
4002
|
-
break;
|
|
4003
|
-
case "compaction_end":
|
|
4004
|
-
events.push({ kind: "compaction_finished" });
|
|
4005
|
-
if (event.errorMessage) events.push({ kind: "error", message: event.errorMessage });
|
|
4006
|
-
break;
|
|
4007
|
-
case "turn_end":
|
|
4008
|
-
case "agent_end":
|
|
4009
|
-
if (!this.turnEnded) {
|
|
4010
|
-
events.push({ kind: "turn_end", sessionId: this.sessionId || void 0 });
|
|
4011
|
-
this.turnEnded = true;
|
|
4012
|
-
}
|
|
4013
|
-
break;
|
|
4014
|
-
}
|
|
4015
|
-
return events;
|
|
4016
|
-
}
|
|
4017
|
-
encodeStdinMessage(_text, _sessionId, _opts) {
|
|
4018
|
-
return null;
|
|
4019
|
-
}
|
|
4020
|
-
buildSystemPrompt(config, _agentId) {
|
|
4021
|
-
return buildPiSystemPrompt(config);
|
|
4022
|
-
}
|
|
4023
|
-
};
|
|
4024
|
-
|
|
4025
3606
|
// src/drivers/index.ts
|
|
4026
3607
|
var driverFactories = {
|
|
4027
3608
|
claude: () => new ClaudeDriver(),
|
|
@@ -4030,8 +3611,7 @@ var driverFactories = {
|
|
|
4030
3611
|
cursor: () => new CursorDriver(),
|
|
4031
3612
|
gemini: () => new GeminiDriver(),
|
|
4032
3613
|
kimi: () => new KimiDriver(),
|
|
4033
|
-
opencode: () => new OpenCodeDriver()
|
|
4034
|
-
pi: () => new PiDriver()
|
|
3614
|
+
opencode: () => new OpenCodeDriver()
|
|
4035
3615
|
};
|
|
4036
3616
|
function getDriver(runtimeId) {
|
|
4037
3617
|
const createDriver = driverFactories[runtimeId];
|
|
@@ -4044,7 +3624,7 @@ function getDriver(runtimeId) {
|
|
|
4044
3624
|
|
|
4045
3625
|
// src/workspaces.ts
|
|
4046
3626
|
import { readdir, rm, stat } from "fs/promises";
|
|
4047
|
-
import
|
|
3627
|
+
import path11 from "path";
|
|
4048
3628
|
function isValidWorkspaceDirectoryName(directoryName) {
|
|
4049
3629
|
return !directoryName.includes("/") && !directoryName.includes("\\") && !directoryName.includes("..");
|
|
4050
3630
|
}
|
|
@@ -4052,7 +3632,7 @@ function resolveWorkspaceDirectoryPath(dataDir, directoryName) {
|
|
|
4052
3632
|
if (!isValidWorkspaceDirectoryName(directoryName)) {
|
|
4053
3633
|
return null;
|
|
4054
3634
|
}
|
|
4055
|
-
return
|
|
3635
|
+
return path11.join(dataDir, directoryName);
|
|
4056
3636
|
}
|
|
4057
3637
|
function emptyWorkspaceDirectorySummary(latestMtime = /* @__PURE__ */ new Date(0)) {
|
|
4058
3638
|
return {
|
|
@@ -4101,7 +3681,7 @@ async function summarizeWorkspaceDirectory(dirPath) {
|
|
|
4101
3681
|
return summary;
|
|
4102
3682
|
}
|
|
4103
3683
|
const childSummaries = await Promise.all(
|
|
4104
|
-
entries.map((entry) => summarizeWorkspaceEntry(
|
|
3684
|
+
entries.map((entry) => summarizeWorkspaceEntry(path11.join(dirPath, entry.name), entry))
|
|
4105
3685
|
);
|
|
4106
3686
|
for (const childSummary of childSummaries) {
|
|
4107
3687
|
summary = mergeWorkspaceDirectorySummaries(summary, childSummary);
|
|
@@ -4120,7 +3700,7 @@ async function scanWorkspaceDirectories(dataDir) {
|
|
|
4120
3700
|
if (!entry.isDirectory()) {
|
|
4121
3701
|
return null;
|
|
4122
3702
|
}
|
|
4123
|
-
const dirPath =
|
|
3703
|
+
const dirPath = path11.join(dataDir, entry.name);
|
|
4124
3704
|
try {
|
|
4125
3705
|
const summary = await summarizeWorkspaceDirectory(dirPath);
|
|
4126
3706
|
return {
|
|
@@ -4324,12 +3904,12 @@ function findSessionJsonl(root, predicate) {
|
|
|
4324
3904
|
for (const entry of entries) {
|
|
4325
3905
|
if (++visited > maxEntries) return null;
|
|
4326
3906
|
if (!entry.isFile() || !predicate(entry.name)) continue;
|
|
4327
|
-
return
|
|
3907
|
+
return path12.join(dir, entry.name);
|
|
4328
3908
|
}
|
|
4329
3909
|
for (const entry of entries) {
|
|
4330
3910
|
if (++visited > maxEntries) return null;
|
|
4331
3911
|
if (!entry.isDirectory()) continue;
|
|
4332
|
-
const found = visit(
|
|
3912
|
+
const found = visit(path12.join(dir, entry.name), depth - 1);
|
|
4333
3913
|
if (found) return found;
|
|
4334
3914
|
}
|
|
4335
3915
|
return null;
|
|
@@ -4342,10 +3922,10 @@ function safeSessionFilename(value) {
|
|
|
4342
3922
|
}
|
|
4343
3923
|
function writeRuntimeSessionHandoff(runtime, sessionId, fallbackDir) {
|
|
4344
3924
|
try {
|
|
4345
|
-
const dir =
|
|
4346
|
-
|
|
4347
|
-
const filePath =
|
|
4348
|
-
|
|
3925
|
+
const dir = path12.join(fallbackDir, ".slock", "runtime-sessions");
|
|
3926
|
+
mkdirSync4(dir, { recursive: true });
|
|
3927
|
+
const filePath = path12.join(dir, `${runtime}-${safeSessionFilename(sessionId)}.jsonl`);
|
|
3928
|
+
writeFileSync7(filePath, JSON.stringify({
|
|
4349
3929
|
type: "runtime_session_handoff",
|
|
4350
3930
|
runtime,
|
|
4351
3931
|
sessionId,
|
|
@@ -4364,7 +3944,7 @@ function writeRuntimeSessionHandoff(runtime, sessionId, fallbackDir) {
|
|
|
4364
3944
|
}
|
|
4365
3945
|
}
|
|
4366
3946
|
function resolveRuntimeSessionRef(runtime, sessionId, homeDir = os6.homedir(), fallbackDir) {
|
|
4367
|
-
const directPath =
|
|
3947
|
+
const directPath = path12.isAbsolute(sessionId) ? sessionId : null;
|
|
4368
3948
|
if (directPath) {
|
|
4369
3949
|
try {
|
|
4370
3950
|
if (statSync2(directPath).isFile()) {
|
|
@@ -4373,7 +3953,7 @@ function resolveRuntimeSessionRef(runtime, sessionId, homeDir = os6.homedir(), f
|
|
|
4373
3953
|
} catch {
|
|
4374
3954
|
}
|
|
4375
3955
|
}
|
|
4376
|
-
const resolvedPath = runtime === "claude" ? findSessionJsonl(
|
|
3956
|
+
const resolvedPath = runtime === "claude" ? findSessionJsonl(path12.join(homeDir, ".claude", "projects"), (filename) => filename === `${sessionId}.jsonl`) : runtime === "codex" ? findSessionJsonl(path12.join(homeDir, ".codex", "sessions"), (filename) => filename.endsWith(".jsonl") && filename.includes(sessionId)) : null;
|
|
4377
3957
|
if (!resolvedPath && fallbackDir) {
|
|
4378
3958
|
const fallback = writeRuntimeSessionHandoff(runtime, sessionId, fallbackDir);
|
|
4379
3959
|
if (fallback) return fallback;
|
|
@@ -5507,26 +5087,26 @@ var AgentProcessManager = class _AgentProcessManager {
|
|
|
5507
5087
|
this.recordDaemonTrace("daemon.agent.spawn.started", this.startQueueTraceAttrs(agentId, config, wakeMessage, unreadSummary, resumePrompt, launchId));
|
|
5508
5088
|
try {
|
|
5509
5089
|
const driver = this.driverResolver(config.runtime || "claude");
|
|
5510
|
-
const agentDataDir =
|
|
5090
|
+
const agentDataDir = path12.join(this.dataDir, agentId);
|
|
5511
5091
|
await mkdir(agentDataDir, { recursive: true });
|
|
5512
5092
|
const runtimeConfig = withLocalRuntimeContext(config, agentId, agentDataDir);
|
|
5513
|
-
const memoryMdPath =
|
|
5093
|
+
const memoryMdPath = path12.join(agentDataDir, "MEMORY.md");
|
|
5514
5094
|
try {
|
|
5515
5095
|
await access(memoryMdPath);
|
|
5516
5096
|
} catch {
|
|
5517
5097
|
const initialMemoryMd = buildInitialMemoryMd(runtimeConfig);
|
|
5518
5098
|
await writeFile(memoryMdPath, initialMemoryMd);
|
|
5519
5099
|
}
|
|
5520
|
-
const notesDir =
|
|
5100
|
+
const notesDir = path12.join(agentDataDir, "notes");
|
|
5521
5101
|
await mkdir(notesDir, { recursive: true });
|
|
5522
5102
|
if (getOnboardingSeedMode(config) === FIRST_CINDY_SEED_MODE) {
|
|
5523
5103
|
const seedFiles = buildOnboardingSeedFiles();
|
|
5524
5104
|
for (const { relativePath, content } of seedFiles) {
|
|
5525
|
-
const fullPath =
|
|
5105
|
+
const fullPath = path12.join(agentDataDir, relativePath);
|
|
5526
5106
|
try {
|
|
5527
5107
|
await access(fullPath);
|
|
5528
5108
|
} catch {
|
|
5529
|
-
await mkdir(
|
|
5109
|
+
await mkdir(path12.dirname(fullPath), { recursive: true });
|
|
5530
5110
|
await writeFile(fullPath, content);
|
|
5531
5111
|
}
|
|
5532
5112
|
}
|
|
@@ -6208,7 +5788,7 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
|
|
|
6208
5788
|
return true;
|
|
6209
5789
|
}
|
|
6210
5790
|
async resetWorkspace(agentId) {
|
|
6211
|
-
const agentDataDir =
|
|
5791
|
+
const agentDataDir = path12.join(this.dataDir, agentId);
|
|
6212
5792
|
try {
|
|
6213
5793
|
await rm2(agentDataDir, { recursive: true, force: true });
|
|
6214
5794
|
logger.info(`[Agent ${agentId}] Workspace reset complete (${agentDataDir})`);
|
|
@@ -6245,7 +5825,7 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
|
|
|
6245
5825
|
return result;
|
|
6246
5826
|
}
|
|
6247
5827
|
buildRuntimeProfileReport(agentId, config, sessionId, launchId) {
|
|
6248
|
-
const workspacePath =
|
|
5828
|
+
const workspacePath = path12.join(this.dataDir, agentId);
|
|
6249
5829
|
return {
|
|
6250
5830
|
agentId,
|
|
6251
5831
|
launchId,
|
|
@@ -6493,7 +6073,7 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
|
|
|
6493
6073
|
}
|
|
6494
6074
|
// Workspace file browsing
|
|
6495
6075
|
async getFileTree(agentId, dirPath) {
|
|
6496
|
-
const agentDir =
|
|
6076
|
+
const agentDir = path12.join(this.dataDir, agentId);
|
|
6497
6077
|
try {
|
|
6498
6078
|
await stat2(agentDir);
|
|
6499
6079
|
} catch {
|
|
@@ -6501,8 +6081,8 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
|
|
|
6501
6081
|
}
|
|
6502
6082
|
let targetDir = agentDir;
|
|
6503
6083
|
if (dirPath) {
|
|
6504
|
-
const resolved =
|
|
6505
|
-
if (!resolved.startsWith(agentDir +
|
|
6084
|
+
const resolved = path12.resolve(agentDir, dirPath);
|
|
6085
|
+
if (!resolved.startsWith(agentDir + path12.sep) && resolved !== agentDir) {
|
|
6506
6086
|
return [];
|
|
6507
6087
|
}
|
|
6508
6088
|
targetDir = resolved;
|
|
@@ -6510,14 +6090,14 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
|
|
|
6510
6090
|
return this.listDirectoryChildren(targetDir, agentDir);
|
|
6511
6091
|
}
|
|
6512
6092
|
async readFile(agentId, filePath) {
|
|
6513
|
-
const agentDir =
|
|
6514
|
-
const resolved =
|
|
6515
|
-
if (!resolved.startsWith(agentDir +
|
|
6093
|
+
const agentDir = path12.join(this.dataDir, agentId);
|
|
6094
|
+
const resolved = path12.resolve(agentDir, filePath);
|
|
6095
|
+
if (!resolved.startsWith(agentDir + path12.sep) && resolved !== agentDir) {
|
|
6516
6096
|
throw new Error("Access denied");
|
|
6517
6097
|
}
|
|
6518
6098
|
const info = await stat2(resolved);
|
|
6519
6099
|
if (info.isDirectory()) throw new Error("Cannot read a directory");
|
|
6520
|
-
const ext =
|
|
6100
|
+
const ext = path12.extname(resolved).toLowerCase();
|
|
6521
6101
|
if (WORKSPACE_TEXT_EXTENSIONS.has(ext) || ext === "") {
|
|
6522
6102
|
if (info.size > WORKSPACE_TEXT_FILE_MAX_BYTES) throw new Error("File too large");
|
|
6523
6103
|
const content = await readFile(resolved, "utf-8");
|
|
@@ -6552,13 +6132,13 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
|
|
|
6552
6132
|
const agent = this.agents.get(agentId);
|
|
6553
6133
|
const runtime = runtimeHint || agent?.config.runtime || "claude";
|
|
6554
6134
|
const home = os6.homedir();
|
|
6555
|
-
const workspaceDir =
|
|
6135
|
+
const workspaceDir = path12.join(this.dataDir, agentId);
|
|
6556
6136
|
const paths = _AgentProcessManager.SKILL_PATHS[runtime] || _AgentProcessManager.SKILL_PATHS.claude;
|
|
6557
6137
|
const globalResults = await Promise.all(
|
|
6558
|
-
paths.global.map((p) => this.scanSkillsDir(
|
|
6138
|
+
paths.global.map((p) => this.scanSkillsDir(path12.join(home, p)))
|
|
6559
6139
|
);
|
|
6560
6140
|
const workspaceResults = await Promise.all(
|
|
6561
|
-
paths.workspace.map((p) => this.scanSkillsDir(
|
|
6141
|
+
paths.workspace.map((p) => this.scanSkillsDir(path12.join(workspaceDir, p)))
|
|
6562
6142
|
);
|
|
6563
6143
|
const dedup = (skills) => {
|
|
6564
6144
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -6587,7 +6167,7 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
|
|
|
6587
6167
|
const skills = [];
|
|
6588
6168
|
for (const entry of entries) {
|
|
6589
6169
|
if (entry.isDirectory() || entry.isSymbolicLink()) {
|
|
6590
|
-
const skillMd =
|
|
6170
|
+
const skillMd = path12.join(dir, entry.name, "SKILL.md");
|
|
6591
6171
|
try {
|
|
6592
6172
|
const content = await readFile(skillMd, "utf-8");
|
|
6593
6173
|
const skill = this.parseSkillMd(entry.name, content);
|
|
@@ -6598,7 +6178,7 @@ Use ${communicationCommand(driver, "read_history")} to catch up on the channels
|
|
|
6598
6178
|
} else if (entry.name.endsWith(".md")) {
|
|
6599
6179
|
const cmdName = entry.name.replace(/\.md$/, "");
|
|
6600
6180
|
try {
|
|
6601
|
-
const content = await readFile(
|
|
6181
|
+
const content = await readFile(path12.join(dir, entry.name), "utf-8");
|
|
6602
6182
|
const skill = this.parseSkillMd(cmdName, content);
|
|
6603
6183
|
skill.sourcePath = dir;
|
|
6604
6184
|
skills.push(skill);
|
|
@@ -7548,8 +7128,8 @@ ${RESPONSE_TARGET_HINT}`);
|
|
|
7548
7128
|
const nodes = [];
|
|
7549
7129
|
for (const entry of entries) {
|
|
7550
7130
|
if (entry.name.startsWith(".") || entry.name === "node_modules") continue;
|
|
7551
|
-
const fullPath =
|
|
7552
|
-
const relativePath =
|
|
7131
|
+
const fullPath = path12.join(dir, entry.name);
|
|
7132
|
+
const relativePath = path12.relative(rootDir, fullPath);
|
|
7553
7133
|
let info;
|
|
7554
7134
|
try {
|
|
7555
7135
|
info = await stat2(fullPath);
|
|
@@ -7852,9 +7432,9 @@ var ReminderCache = class {
|
|
|
7852
7432
|
|
|
7853
7433
|
// src/machineLock.ts
|
|
7854
7434
|
import { createHash as createHash3, randomUUID as randomUUID2 } from "crypto";
|
|
7855
|
-
import { mkdirSync as
|
|
7435
|
+
import { mkdirSync as mkdirSync5, readFileSync as readFileSync5, rmSync as rmSync2, statSync as statSync3, writeFileSync as writeFileSync8 } from "fs";
|
|
7856
7436
|
import os7 from "os";
|
|
7857
|
-
import
|
|
7437
|
+
import path13 from "path";
|
|
7858
7438
|
var INCOMPLETE_LOCK_STALE_MS = 3e4;
|
|
7859
7439
|
var DaemonMachineLockConflictError = class extends Error {
|
|
7860
7440
|
code = "DAEMON_MACHINE_LOCK_HELD";
|
|
@@ -7876,7 +7456,7 @@ function resolveDefaultMachineStateRoot() {
|
|
|
7876
7456
|
return resolveSlockHomePath("machines");
|
|
7877
7457
|
}
|
|
7878
7458
|
function ownerPath(lockDir) {
|
|
7879
|
-
return
|
|
7459
|
+
return path13.join(lockDir, "owner.json");
|
|
7880
7460
|
}
|
|
7881
7461
|
function readOwner(lockDir) {
|
|
7882
7462
|
try {
|
|
@@ -7906,13 +7486,13 @@ function acquireDaemonMachineLock(options) {
|
|
|
7906
7486
|
const rootDir = options.rootDir ?? resolveDefaultMachineStateRoot();
|
|
7907
7487
|
const fingerprint = apiKeyFingerprint(options.apiKey);
|
|
7908
7488
|
const lockId = getDaemonMachineLockId(options.apiKey);
|
|
7909
|
-
const machineDir =
|
|
7910
|
-
const lockDir =
|
|
7489
|
+
const machineDir = path13.join(rootDir, lockId);
|
|
7490
|
+
const lockDir = path13.join(machineDir, "daemon.lock");
|
|
7911
7491
|
const token = randomUUID2();
|
|
7912
|
-
|
|
7492
|
+
mkdirSync5(machineDir, { recursive: true });
|
|
7913
7493
|
for (let attempt = 0; attempt < 2; attempt += 1) {
|
|
7914
7494
|
try {
|
|
7915
|
-
|
|
7495
|
+
mkdirSync5(lockDir);
|
|
7916
7496
|
const owner = {
|
|
7917
7497
|
pid: process.pid,
|
|
7918
7498
|
token,
|
|
@@ -7922,7 +7502,7 @@ function acquireDaemonMachineLock(options) {
|
|
|
7922
7502
|
apiKeyFingerprint: fingerprint.slice(0, 16)
|
|
7923
7503
|
};
|
|
7924
7504
|
try {
|
|
7925
|
-
|
|
7505
|
+
writeFileSync8(ownerPath(lockDir), `${JSON.stringify(owner, null, 2)}
|
|
7926
7506
|
`, { mode: 384 });
|
|
7927
7507
|
} catch (err) {
|
|
7928
7508
|
rmSync2(lockDir, { recursive: true, force: true });
|
|
@@ -7959,8 +7539,8 @@ function acquireDaemonMachineLock(options) {
|
|
|
7959
7539
|
}
|
|
7960
7540
|
|
|
7961
7541
|
// src/localTraceSink.ts
|
|
7962
|
-
import { appendFileSync, mkdirSync as
|
|
7963
|
-
import
|
|
7542
|
+
import { appendFileSync, mkdirSync as mkdirSync6, readdirSync as readdirSync3, rmSync as rmSync3, statSync as statSync4, writeFileSync as writeFileSync9 } from "fs";
|
|
7543
|
+
import path14 from "path";
|
|
7964
7544
|
var DEFAULT_MAX_FILE_BYTES = 5 * 1024 * 1024;
|
|
7965
7545
|
var DEFAULT_MAX_FILE_AGE_MS = 5 * 60 * 1e3;
|
|
7966
7546
|
var DEFAULT_MAX_FILES = 8;
|
|
@@ -7996,7 +7576,7 @@ var LocalRotatingTraceSink = class {
|
|
|
7996
7576
|
currentSize = 0;
|
|
7997
7577
|
sequence = 0;
|
|
7998
7578
|
constructor(options) {
|
|
7999
|
-
this.traceDir =
|
|
7579
|
+
this.traceDir = path14.join(options.machineDir, "traces");
|
|
8000
7580
|
this.maxFileBytes = Math.max(1024, Math.floor(options.maxFileBytes ?? DEFAULT_MAX_FILE_BYTES));
|
|
8001
7581
|
const baseAgeMs = Math.max(1e3, Math.floor(options.maxFileAgeMs ?? DEFAULT_MAX_FILE_AGE_MS));
|
|
8002
7582
|
const ageJitterMs = Math.max(0, Math.floor(options.maxFileAgeJitterMs ?? 0));
|
|
@@ -8022,15 +7602,15 @@ var LocalRotatingTraceSink = class {
|
|
|
8022
7602
|
return this.currentFile;
|
|
8023
7603
|
}
|
|
8024
7604
|
ensureFile(nextBytes) {
|
|
8025
|
-
|
|
7605
|
+
mkdirSync6(this.traceDir, { recursive: true, mode: 448 });
|
|
8026
7606
|
const nowMs = this.nowMsProvider();
|
|
8027
7607
|
const shouldRotateForAge = this.currentFileOpenedAtMs !== null && nowMs - this.currentFileOpenedAtMs >= this.maxFileAgeMs;
|
|
8028
7608
|
if (!this.currentFile || this.currentSize + nextBytes > this.maxFileBytes || shouldRotateForAge) {
|
|
8029
|
-
this.currentFile =
|
|
7609
|
+
this.currentFile = path14.join(
|
|
8030
7610
|
this.traceDir,
|
|
8031
7611
|
`daemon-trace-${safeTimestamp(nowMs)}-${process.pid}-${String(this.sequence++).padStart(4, "0")}.jsonl`
|
|
8032
7612
|
);
|
|
8033
|
-
|
|
7613
|
+
writeFileSync9(this.currentFile, "", { flag: "a", mode: 384 });
|
|
8034
7614
|
this.currentSize = statSync4(this.currentFile).size;
|
|
8035
7615
|
this.currentFileOpenedAtMs = nowMs;
|
|
8036
7616
|
this.pruneOldFiles();
|
|
@@ -8041,7 +7621,7 @@ var LocalRotatingTraceSink = class {
|
|
|
8041
7621
|
const excess = files.length - this.maxFiles;
|
|
8042
7622
|
if (excess <= 0) return;
|
|
8043
7623
|
for (const file of files.slice(0, excess)) {
|
|
8044
|
-
rmSync3(
|
|
7624
|
+
rmSync3(path14.join(this.traceDir, file), { force: true });
|
|
8045
7625
|
}
|
|
8046
7626
|
}
|
|
8047
7627
|
};
|
|
@@ -8128,11 +7708,11 @@ function isDiagnosticErrorAttr(key) {
|
|
|
8128
7708
|
import { createHash as createHash5, randomUUID as randomUUID3 } from "crypto";
|
|
8129
7709
|
import { gzipSync } from "zlib";
|
|
8130
7710
|
import { mkdir as mkdir2, readFile as readFile2, readdir as readdir3, stat as stat3, writeFile as writeFile2 } from "fs/promises";
|
|
8131
|
-
import
|
|
7711
|
+
import path15 from "path";
|
|
8132
7712
|
|
|
8133
7713
|
// src/directUploadCapability.ts
|
|
8134
|
-
function joinUrl(base,
|
|
8135
|
-
return `${base.replace(/\/+$/, "")}${
|
|
7714
|
+
function joinUrl(base, path17) {
|
|
7715
|
+
return `${base.replace(/\/+$/, "")}${path17}`;
|
|
8136
7716
|
}
|
|
8137
7717
|
function jsonHeaders(apiKey) {
|
|
8138
7718
|
return {
|
|
@@ -8351,7 +7931,7 @@ var DaemonTraceBundleUploader = class {
|
|
|
8351
7931
|
}, nextMs);
|
|
8352
7932
|
}
|
|
8353
7933
|
async findUploadCandidates() {
|
|
8354
|
-
const traceDir =
|
|
7934
|
+
const traceDir = path15.join(this.options.machineDir, "traces");
|
|
8355
7935
|
let names;
|
|
8356
7936
|
try {
|
|
8357
7937
|
names = await readdir3(traceDir);
|
|
@@ -8363,8 +7943,8 @@ var DaemonTraceBundleUploader = class {
|
|
|
8363
7943
|
const currentFile = this.options.currentFileProvider?.();
|
|
8364
7944
|
const candidates = [];
|
|
8365
7945
|
for (const name of names.filter((entry) => entry.startsWith("daemon-trace-") && entry.endsWith(".jsonl")).sort()) {
|
|
8366
|
-
const file =
|
|
8367
|
-
if (currentFile &&
|
|
7946
|
+
const file = path15.join(traceDir, name);
|
|
7947
|
+
if (currentFile && path15.resolve(file) === path15.resolve(currentFile)) continue;
|
|
8368
7948
|
if (await this.isUploaded(file)) continue;
|
|
8369
7949
|
try {
|
|
8370
7950
|
const info = await stat3(file);
|
|
@@ -8438,8 +8018,8 @@ var DaemonTraceBundleUploader = class {
|
|
|
8438
8018
|
}
|
|
8439
8019
|
}
|
|
8440
8020
|
uploadStatePath(file) {
|
|
8441
|
-
const stateDir =
|
|
8442
|
-
return
|
|
8021
|
+
const stateDir = path15.join(this.options.machineDir, "trace-uploads");
|
|
8022
|
+
return path15.join(stateDir, `${path15.basename(file)}.uploaded.json`);
|
|
8443
8023
|
}
|
|
8444
8024
|
async isUploaded(file) {
|
|
8445
8025
|
try {
|
|
@@ -8451,9 +8031,9 @@ var DaemonTraceBundleUploader = class {
|
|
|
8451
8031
|
}
|
|
8452
8032
|
async markUploaded(file, metadata) {
|
|
8453
8033
|
const stateFile = this.uploadStatePath(file);
|
|
8454
|
-
await mkdir2(
|
|
8034
|
+
await mkdir2(path15.dirname(stateFile), { recursive: true, mode: 448 });
|
|
8455
8035
|
await writeFile2(stateFile, `${JSON.stringify({
|
|
8456
|
-
file:
|
|
8036
|
+
file: path15.basename(file),
|
|
8457
8037
|
uploadedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
8458
8038
|
...metadata
|
|
8459
8039
|
}, null, 2)}
|
|
@@ -8472,10 +8052,10 @@ function readPositiveIntegerEnv2(name, fallback) {
|
|
|
8472
8052
|
|
|
8473
8053
|
// src/core.ts
|
|
8474
8054
|
var DEFAULT_TRACE_UPLOAD_URL = "https://slock-trace-upload.botiverse.dev";
|
|
8475
|
-
var DAEMON_CLI_USAGE =
|
|
8476
|
-
function parseDaemonCliArgs(args
|
|
8055
|
+
var DAEMON_CLI_USAGE = "Usage: slock-daemon --server-url <url> --api-key <key>";
|
|
8056
|
+
function parseDaemonCliArgs(args) {
|
|
8477
8057
|
let serverUrl = "";
|
|
8478
|
-
let apiKey =
|
|
8058
|
+
let apiKey = "";
|
|
8479
8059
|
for (let i = 0; i < args.length; i++) {
|
|
8480
8060
|
if (args[i] === "--server-url" && args[i + 1]) serverUrl = args[++i];
|
|
8481
8061
|
if (args[i] === "--api-key" && args[i + 1]) apiKey = args[++i];
|
|
@@ -8492,23 +8072,23 @@ function readDaemonVersion(moduleUrl = import.meta.url) {
|
|
|
8492
8072
|
}
|
|
8493
8073
|
}
|
|
8494
8074
|
function resolveChatBridgePath(moduleUrl = import.meta.url) {
|
|
8495
|
-
const dirname =
|
|
8496
|
-
const jsPath =
|
|
8075
|
+
const dirname = path16.dirname(fileURLToPath(moduleUrl));
|
|
8076
|
+
const jsPath = path16.resolve(dirname, "chat-bridge.js");
|
|
8497
8077
|
try {
|
|
8498
8078
|
accessSync(jsPath);
|
|
8499
8079
|
return jsPath;
|
|
8500
8080
|
} catch {
|
|
8501
|
-
return
|
|
8081
|
+
return path16.resolve(dirname, "chat-bridge.ts");
|
|
8502
8082
|
}
|
|
8503
8083
|
}
|
|
8504
8084
|
function resolveSlockCliPath(moduleUrl = import.meta.url) {
|
|
8505
|
-
const thisDir =
|
|
8506
|
-
const bundledDistPath =
|
|
8085
|
+
const thisDir = path16.dirname(fileURLToPath(moduleUrl));
|
|
8086
|
+
const bundledDistPath = path16.resolve(thisDir, "cli", "index.js");
|
|
8507
8087
|
try {
|
|
8508
8088
|
accessSync(bundledDistPath);
|
|
8509
8089
|
return bundledDistPath;
|
|
8510
8090
|
} catch {
|
|
8511
|
-
const workspaceDistPath =
|
|
8091
|
+
const workspaceDistPath = path16.resolve(thisDir, "..", "..", "cli", "dist", "index.js");
|
|
8512
8092
|
accessSync(workspaceDistPath);
|
|
8513
8093
|
return workspaceDistPath;
|
|
8514
8094
|
}
|
|
@@ -8687,7 +8267,7 @@ var DaemonCore = class {
|
|
|
8687
8267
|
}
|
|
8688
8268
|
resolveMachineStateRoot() {
|
|
8689
8269
|
if (this.options.machineStateDir) return this.options.machineStateDir;
|
|
8690
|
-
if (this.options.dataDir) return
|
|
8270
|
+
if (this.options.dataDir) return path16.join(path16.dirname(this.options.dataDir), "machines");
|
|
8691
8271
|
return resolveDefaultMachineStateRoot();
|
|
8692
8272
|
}
|
|
8693
8273
|
shouldEnableLocalTrace() {
|
|
@@ -9070,8 +8650,6 @@ var DaemonCore = class {
|
|
|
9070
8650
|
};
|
|
9071
8651
|
|
|
9072
8652
|
export {
|
|
9073
|
-
DAEMON_API_KEY_ENV,
|
|
9074
|
-
scrubDaemonAuthEnv,
|
|
9075
8653
|
resolveWorkspaceDirectoryPath,
|
|
9076
8654
|
scanWorkspaceDirectories,
|
|
9077
8655
|
deleteWorkspaceDirectory,
|