@botiverse/raft-daemon 0.60.0-play.20260615140421 → 0.61.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.
@@ -1,7 +1,7 @@
1
1
  // src/core.ts
2
- import path16 from "path";
2
+ import path17 from "path";
3
3
  import os8 from "os";
4
- import { createRequire as createRequire2 } from "module";
4
+ import { createRequire as createRequire3 } from "module";
5
5
  import { accessSync } from "fs";
6
6
  import { fileURLToPath } from "url";
7
7
 
@@ -1298,7 +1298,11 @@ var RUNTIMES = [
1298
1298
  { id: "claude", displayName: "Claude Code", binary: "claude", supported: true },
1299
1299
  { id: "codex", displayName: "Codex CLI", binary: "codex", supported: true },
1300
1300
  { id: "antigravity", displayName: "Antigravity CLI", binary: "agy", supported: true },
1301
- { id: "kimi", displayName: "Kimi CLI", binary: "kimi", supported: true },
1301
+ // Kimi: prefer the in-process SDK (`kimi-sdk` "Kimi Code") for new agents.
1302
+ // The legacy `kimi` (kimi-cli child-process) entry stays for backward compat
1303
+ // with existing `runtime=kimi` agents but is labelled deprecated.
1304
+ { id: "kimi-sdk", displayName: "Kimi Code", binary: "", supported: true },
1305
+ { id: "kimi", displayName: "Kimi CLI (deprecated)", binary: "kimi", supported: true },
1302
1306
  { id: "copilot", displayName: "Copilot CLI", binary: "copilot", supported: true },
1303
1307
  { id: "cursor", displayName: "Cursor CLI", binary: "cursor-agent", supported: true },
1304
1308
  { id: "gemini", displayName: "Gemini CLI", binary: "gemini", supported: true },
@@ -1366,6 +1370,15 @@ var RUNTIME_MODELS = {
1366
1370
  // built-in option is to defer to whatever default model the CLI already uses.
1367
1371
  kimi: [
1368
1372
  { id: "default", label: "Configured Default" }
1373
+ ],
1374
+ // kimi-sdk runs the Kimi Code SDK in-process. Surface the canonical model
1375
+ // first so getDefaultModel("kimi-sdk") returns it (without a static entry,
1376
+ // useRuntimeModels falls back to Claude's list and getDefaultModel returns
1377
+ // "sonnet" — which the SDK driver would pass through to the Kimi session
1378
+ // and the LLM call would fail). Mirrors detectKimiSdkModels() in the daemon.
1379
+ "kimi-sdk": [
1380
+ { id: "kimi-code/kimi-for-coding", label: "Kimi-K2.6 (Kimi for Coding)", verified: "launchable" },
1381
+ { id: "kimi-k2-0905-preview", label: "Kimi K2 (preview)", verified: "suggestion_only" }
1369
1382
  ]
1370
1383
  };
1371
1384
  function getDefaultModel(runtimeId) {
@@ -1551,10 +1564,10 @@ var DISPLAY_PLAN_CONFIG = {
1551
1564
  };
1552
1565
 
1553
1566
  // src/agentProcessManager.ts
1554
- import { mkdirSync as mkdirSync4, readdirSync as readdirSync3, statSync, writeFileSync as writeFileSync4 } from "fs";
1567
+ import { mkdirSync as mkdirSync5, readdirSync as readdirSync3, statSync, writeFileSync as writeFileSync4 } from "fs";
1555
1568
  import { mkdir, writeFile, access, readdir as readdir2, stat as stat2, readFile, rm as rm2 } from "fs/promises";
1556
1569
  import { createHash as createHash3 } from "crypto";
1557
- import path12 from "path";
1570
+ import path13 from "path";
1558
1571
  import os6 from "os";
1559
1572
 
1560
1573
  // src/drivers/claude.ts
@@ -2143,19 +2156,6 @@ function listLegacySlockStatePaths(slockHome = resolveSlockHome(), homeDir = os.
2143
2156
  return candidates.filter((candidate) => existsSync(candidate.path));
2144
2157
  }
2145
2158
 
2146
- // src/authEnv.ts
2147
- var DAEMON_API_KEY_ENV = "SLOCK_MACHINE_API_KEY";
2148
- var SLOCK_AGENT_TOKEN_ENV = "SLOCK_AGENT_TOKEN";
2149
- function scrubDaemonAuthEnv(env) {
2150
- delete env[DAEMON_API_KEY_ENV];
2151
- return env;
2152
- }
2153
- function scrubDaemonChildEnv(env) {
2154
- delete env[DAEMON_API_KEY_ENV];
2155
- delete env[SLOCK_AGENT_TOKEN_ENV];
2156
- return env;
2157
- }
2158
-
2159
2159
  // src/agentCredentialProxy.ts
2160
2160
  import { randomBytes } from "crypto";
2161
2161
  import http from "http";
@@ -3367,6 +3367,7 @@ function routeFamilyForPath(pathname) {
3367
3367
  function daemonUpstreamTargetHostClass(url) {
3368
3368
  const hostname = url.hostname.toLowerCase();
3369
3369
  if (hostname === "api.slock.ai") return "api.slock.ai";
3370
+ if (hostname === "api.raft.build") return "api.raft.build";
3370
3371
  return "custom_server";
3371
3372
  }
3372
3373
  function upstreamLayerForProxyError(err) {
@@ -3643,9 +3644,7 @@ var LOOPBACK_NO_PROXY = "127.0.0.1,localhost";
3643
3644
  var CLI_TRANSPORT_TRACE_DIR_ENV = "SLOCK_CLI_TRANSPORT_TRACE_DIR";
3644
3645
  var safePathPart = (value) => value.replace(/[^a-zA-Z0-9_.-]/g, "_");
3645
3646
  var RAW_CREDENTIAL_ENV_DENYLIST = [
3646
- "SLOCK_AGENT_TOKEN",
3647
- "SLOCK_AGENT_CREDENTIAL_KEY",
3648
- "SLOCK_AGENT_CREDENTIAL_KEY_FILE"
3647
+ "SLOCK_AGENT_CREDENTIAL_KEY"
3649
3648
  ];
3650
3649
  function deriveCliFallbackCandidates(cliPath) {
3651
3650
  if (!cliPath || cliPath === "__cli") return [];
@@ -3960,7 +3959,7 @@ set "SLOCK_AGENT_ACTIVE_CAPABILITIES=${DEFAULT_ACTIVE_CAPABILITIES}"\r
3960
3959
  ...agentCredentialProxy ? {} : { SLOCK_AGENT_TOKEN_FILE: tokenFile },
3961
3960
  PATH: `${slockDir}${path2.delimiter}${process.env.PATH ?? ""}`
3962
3961
  };
3963
- scrubDaemonChildEnv(spawnEnv);
3962
+ delete spawnEnv.SLOCK_AGENT_TOKEN;
3964
3963
  for (const key of RAW_CREDENTIAL_ENV_DENYLIST) {
3965
3964
  delete spawnEnv[key];
3966
3965
  }
@@ -4395,7 +4394,7 @@ function requiresWindowsShell(command, platform = process.platform) {
4395
4394
  }
4396
4395
  function resolveCommandOnPath(command, deps = {}) {
4397
4396
  const platform = deps.platform ?? process.platform;
4398
- const env = scrubDaemonChildEnv({ ...withWindowsUserEnvironment(deps.env ?? process.env, deps) });
4397
+ const env = withWindowsUserEnvironment(deps.env ?? process.env, deps);
4399
4398
  const execFileSyncFn = deps.execFileSyncFn ?? execFileSync;
4400
4399
  const existsSyncFn = deps.existsSyncFn ?? existsSync3;
4401
4400
  if (platform === "win32") {
@@ -4421,7 +4420,7 @@ function firstExistingPath(candidates, deps = {}) {
4421
4420
  return null;
4422
4421
  }
4423
4422
  function readCommandVersion(command, args = [], deps = {}) {
4424
- const env = scrubDaemonChildEnv({ ...withWindowsUserEnvironment(deps.env ?? process.env, deps) });
4423
+ const env = withWindowsUserEnvironment(deps.env ?? process.env, deps);
4425
4424
  const execFileSyncFn = deps.execFileSyncFn ?? execFileSync;
4426
4425
  try {
4427
4426
  const output = normalizeExecOutput(execFileSyncFn(command, [...args, "--version"], {
@@ -5815,11 +5814,11 @@ function detectCursorModels(runCommand = runCursorModelsCommand) {
5815
5814
  return parseCursorModelsOutput(String(result.stdout || ""));
5816
5815
  }
5817
5816
  function buildCursorModelProbeEnv(deps = {}) {
5818
- return scrubDaemonChildEnv(withWindowsUserEnvironment({
5817
+ return withWindowsUserEnvironment({
5819
5818
  ...deps.env ?? process.env,
5820
5819
  FORCE_COLOR: "0",
5821
5820
  NO_COLOR: "1"
5822
- }, deps));
5821
+ }, deps);
5823
5822
  }
5824
5823
  function runCursorModelsCommand() {
5825
5824
  return spawnSync("cursor-agent", ["models"], {
@@ -5875,7 +5874,7 @@ function resolveGeminiSpawn(commandArgs, deps = {}) {
5875
5874
  }
5876
5875
  const execFileSyncFn = deps.execFileSyncFn ?? execFileSync3;
5877
5876
  const existsSyncFn = deps.existsSyncFn ?? existsSync6;
5878
- const env = scrubDaemonChildEnv({ ...deps.env ?? process.env });
5877
+ const env = deps.env ?? process.env;
5879
5878
  const winPath = path7.win32;
5880
5879
  let geminiEntry = null;
5881
5880
  try {
@@ -6012,15 +6011,12 @@ var GeminiDriver = class {
6012
6011
  // src/drivers/kimi.ts
6013
6012
  import { randomUUID as randomUUID2 } from "crypto";
6014
6013
  import { spawn as spawn7 } from "child_process";
6015
- import { chmodSync, existsSync as existsSync7, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "fs";
6014
+ import { existsSync as existsSync7, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "fs";
6016
6015
  import os4 from "os";
6017
6016
  import path8 from "path";
6018
6017
  var KIMI_WIRE_PROTOCOL_VERSION = "1.3";
6019
6018
  var KIMI_SYSTEM_PROMPT_FILE = ".slock-kimi-system.md";
6020
6019
  var KIMI_AGENT_FILE = ".slock-kimi-agent.yaml";
6021
- var KIMI_GENERATED_CONFIG_FILE = ".slock-kimi-config.toml";
6022
- var SLOCK_KIMI_CONFIG_CONTENT_ENV = "SLOCK_KIMI_CONFIG_CONTENT";
6023
- var SLOCK_KIMI_CONFIG_FILE_ENV = "SLOCK_KIMI_CONFIG_FILE";
6024
6020
  function parseToolArguments(raw) {
6025
6021
  if (typeof raw !== "string") return raw;
6026
6022
  try {
@@ -6029,73 +6025,6 @@ function parseToolArguments(raw) {
6029
6025
  return raw;
6030
6026
  }
6031
6027
  }
6032
- function readKimiConfigSource(home = os4.homedir(), env = process.env) {
6033
- const inlineConfig = env[SLOCK_KIMI_CONFIG_CONTENT_ENV];
6034
- if (inlineConfig && inlineConfig.trim()) {
6035
- return {
6036
- raw: inlineConfig,
6037
- explicitPath: null,
6038
- sourcePath: SLOCK_KIMI_CONFIG_CONTENT_ENV
6039
- };
6040
- }
6041
- const explicitPath = env[SLOCK_KIMI_CONFIG_FILE_ENV];
6042
- const configPath = explicitPath && explicitPath.trim() ? explicitPath : path8.join(home, ".kimi", "config.toml");
6043
- try {
6044
- return {
6045
- raw: readFileSync3(configPath, "utf8"),
6046
- explicitPath: explicitPath && explicitPath.trim() ? explicitPath : null,
6047
- sourcePath: configPath
6048
- };
6049
- } catch {
6050
- return {
6051
- raw: null,
6052
- explicitPath: explicitPath && explicitPath.trim() ? explicitPath : null,
6053
- sourcePath: configPath
6054
- };
6055
- }
6056
- }
6057
- function buildKimiSpawnEnv(env = process.env) {
6058
- const spawnEnv = { ...env, FORCE_COLOR: "0", NO_COLOR: "1" };
6059
- delete spawnEnv[SLOCK_KIMI_CONFIG_CONTENT_ENV];
6060
- delete spawnEnv[SLOCK_KIMI_CONFIG_FILE_ENV];
6061
- return scrubDaemonChildEnv(spawnEnv);
6062
- }
6063
- function buildKimiEffectiveEnv(ctx, overrideEnv) {
6064
- return {
6065
- ...process.env,
6066
- ...ctx.config.envVars || {},
6067
- ...overrideEnv || {}
6068
- };
6069
- }
6070
- function buildKimiLaunchOptions(ctx, opts = {}) {
6071
- const env = buildKimiEffectiveEnv(ctx, opts.env);
6072
- const source = readKimiConfigSource(opts.home ?? os4.homedir(), env);
6073
- const args = [];
6074
- let configFilePath = null;
6075
- let configContent = null;
6076
- if (source.explicitPath) {
6077
- configFilePath = source.explicitPath;
6078
- } else if (source.raw !== null && source.sourcePath === SLOCK_KIMI_CONFIG_CONTENT_ENV) {
6079
- configFilePath = path8.join(ctx.workingDirectory, KIMI_GENERATED_CONFIG_FILE);
6080
- configContent = source.raw;
6081
- if (opts.writeGeneratedConfig !== false) {
6082
- writeFileSync3(configFilePath, source.raw, { encoding: "utf8", mode: 384 });
6083
- chmodSync(configFilePath, 384);
6084
- }
6085
- }
6086
- if (configFilePath) {
6087
- args.push("--config-file", configFilePath);
6088
- }
6089
- if (ctx.config.model && ctx.config.model !== "default") {
6090
- args.push("--model", ctx.config.model);
6091
- }
6092
- return {
6093
- args,
6094
- env: buildKimiSpawnEnv(env),
6095
- configFilePath,
6096
- configContent
6097
- };
6098
- }
6099
6028
  function resolveKimiSpawn(commandArgs, deps = {}) {
6100
6029
  return {
6101
6030
  command: resolveCommandOnPath("kimi", deps) ?? "kimi",
@@ -6119,25 +6048,7 @@ var KimiDriver = class {
6119
6048
  };
6120
6049
  model = {
6121
6050
  detectedModelsVerifiedAs: "launchable",
6122
- toLaunchSpec: (modelId, ctx, opts) => {
6123
- if (!ctx) return { args: ["--model", modelId] };
6124
- const launchCtx = {
6125
- ...ctx,
6126
- config: {
6127
- ...ctx.config,
6128
- model: modelId
6129
- }
6130
- };
6131
- const launch = buildKimiLaunchOptions(launchCtx, {
6132
- home: opts?.home,
6133
- writeGeneratedConfig: false
6134
- });
6135
- return {
6136
- args: launch.args,
6137
- env: launch.env,
6138
- configFiles: launch.configFilePath ? [launch.configFilePath] : void 0
6139
- };
6140
- }
6051
+ toLaunchSpec: (modelId) => ({ args: ["--model", modelId] })
6141
6052
  };
6142
6053
  supportsStdinNotification = true;
6143
6054
  busyDeliveryMode = "direct";
@@ -6161,23 +6072,21 @@ var KimiDriver = class {
6161
6072
  ` system_prompt_path: ./${KIMI_SYSTEM_PROMPT_FILE}`,
6162
6073
  ""
6163
6074
  ].join("\n"), "utf8");
6164
- const launch = buildKimiLaunchOptions(ctx);
6165
6075
  const args = [
6166
6076
  "--wire",
6167
6077
  "--yolo",
6168
6078
  "--agent-file",
6169
6079
  agentFilePath,
6170
6080
  "--session",
6171
- this.sessionId,
6172
- ...launch.args
6081
+ this.sessionId
6173
6082
  ];
6174
6083
  const launchRuntimeFields = runtimeConfigToLaunchFields(ctx.config);
6175
6084
  if (launchRuntimeFields.model && launchRuntimeFields.model !== "default") {
6176
6085
  args.push("--model", launchRuntimeFields.model);
6177
6086
  }
6178
6087
  const spawnEnv = (await prepareCliTransport(ctx, { NO_COLOR: "1" })).spawnEnv;
6179
- const spawnTarget = resolveKimiSpawn(args);
6180
- const proc = spawn7(spawnTarget.command, spawnTarget.args, {
6088
+ const launch = resolveKimiSpawn(args);
6089
+ const proc = spawn7(launch.command, launch.args, {
6181
6090
  cwd: ctx.workingDirectory,
6182
6091
  stdio: ["pipe", "pipe", "pipe"],
6183
6092
  env: spawnEnv,
@@ -6185,7 +6094,7 @@ var KimiDriver = class {
6185
6094
  // and has an 8191-character command-line limit. Kimi's official
6186
6095
  // installer/uv entrypoint is an executable, so launch it directly and
6187
6096
  // keep prompts on stdin / files instead of routing through cmd.exe.
6188
- shell: spawnTarget.shell
6097
+ shell: launch.shell
6189
6098
  });
6190
6099
  proc.stdin?.write(JSON.stringify({
6191
6100
  jsonrpc: "2.0",
@@ -6298,9 +6207,14 @@ var KimiDriver = class {
6298
6207
  return detectKimiModels();
6299
6208
  }
6300
6209
  };
6301
- function detectKimiModels(home = os4.homedir(), opts = {}) {
6302
- const raw = readKimiConfigSource(home, opts.env).raw;
6303
- if (raw === null) return null;
6210
+ function detectKimiModels(home = os4.homedir()) {
6211
+ const configPath = path8.join(home, ".kimi", "config.toml");
6212
+ let raw;
6213
+ try {
6214
+ raw = readFileSync3(configPath, "utf8");
6215
+ } catch {
6216
+ return null;
6217
+ }
6304
6218
  const models = [];
6305
6219
  const sectionRe = /^\s*\[models(?:\.([^\]]+)|"\.[^"]+"|\."[^"]+")\s*\]\s*$/gm;
6306
6220
  const lineRe = /^\s*\[models\.(.+?)\s*\]\s*$/gm;
@@ -6319,11 +6233,455 @@ function detectKimiModels(home = os4.homedir(), opts = {}) {
6319
6233
  return { models, default: defaultModel };
6320
6234
  }
6321
6235
 
6236
+ // src/drivers/kimi-sdk.ts
6237
+ import { randomUUID as randomUUID3 } from "crypto";
6238
+ import { EventEmitter } from "events";
6239
+ import { mkdirSync as mkdirSync3 } from "fs";
6240
+ import path9 from "path";
6241
+ import { createRequire as createRequire2 } from "module";
6242
+ import {
6243
+ createKimiHarness
6244
+ } from "@botiverse/kimi-code-sdk";
6245
+ var requireFromHere = createRequire2(import.meta.url);
6246
+ var KIMI_CODE_USER_AGENT_PRODUCT = "kimi-code-cli";
6247
+ var KIMI_CODE_HOST_VERSION = "0.14.3";
6248
+ function getDaemonVersion() {
6249
+ try {
6250
+ const pkg = requireFromHere("../../package.json");
6251
+ return pkg.version || "0.0.0";
6252
+ } catch {
6253
+ return "0.0.0";
6254
+ }
6255
+ }
6256
+ var KIMI_SESSION_DIR = ".kimi-sessions";
6257
+ function createKimiSdkEventMappingState(sessionId = null) {
6258
+ return {
6259
+ sessionId,
6260
+ sessionAnnounced: false
6261
+ };
6262
+ }
6263
+ function buildKimiSessionDir(workingDirectory) {
6264
+ return path9.join(workingDirectory, KIMI_SESSION_DIR);
6265
+ }
6266
+ function kimiErrorMessage(error) {
6267
+ if (typeof error === "string" && error.trim()) return error.trim();
6268
+ if (error && typeof error === "object") {
6269
+ const record = error;
6270
+ if (typeof record.message === "string" && record.message.trim()) return record.message.trim();
6271
+ try {
6272
+ return JSON.stringify(error);
6273
+ } catch {
6274
+ }
6275
+ }
6276
+ return "Unknown Kimi error";
6277
+ }
6278
+ function pushSessionInitIfNeeded(state, events) {
6279
+ if (!state.sessionAnnounced && state.sessionId) {
6280
+ events.push({ kind: "session_init", sessionId: state.sessionId });
6281
+ state.sessionAnnounced = true;
6282
+ }
6283
+ }
6284
+ function mapKimiSdkEventToParsedEvents(event, state) {
6285
+ const events = [];
6286
+ pushSessionInitIfNeeded(state, events);
6287
+ switch (event.type) {
6288
+ // ── content streaming → ParsedEvent ──
6289
+ case "thinking.delta":
6290
+ if (typeof event.delta === "string" && event.delta.length > 0) {
6291
+ events.push({ kind: "thinking", text: event.delta });
6292
+ }
6293
+ return events;
6294
+ case "assistant.delta":
6295
+ if (typeof event.delta === "string" && event.delta.length > 0) {
6296
+ events.push({ kind: "text", text: event.delta });
6297
+ }
6298
+ return events;
6299
+ case "tool.call.started":
6300
+ events.push({
6301
+ kind: "tool_call",
6302
+ name: event.name || "unknown_tool",
6303
+ input: event.args ?? {}
6304
+ });
6305
+ return events;
6306
+ case "tool.result":
6307
+ events.push({ kind: "tool_output", name: "" });
6308
+ return events;
6309
+ case "compaction.started":
6310
+ events.push({ kind: "compaction_started" });
6311
+ return events;
6312
+ case "compaction.completed":
6313
+ events.push({ kind: "compaction_finished" });
6314
+ return events;
6315
+ case "error":
6316
+ events.push({ kind: "error", message: kimiErrorMessage(event) });
6317
+ return events;
6318
+ // ── THE single turn-triggering source class ──
6319
+ case "turn.ended":
6320
+ events.push({ kind: "turn_end", sessionId: state.sessionId || void 0 });
6321
+ return events;
6322
+ // ── explicit drops (RS-004) ──
6323
+ // `warning` is non-fatal in the SDK's vocabulary; mapping it to
6324
+ // ParsedEvent.kind="error" would latch the agent into APM's error state
6325
+ // (lastRuntimeError set by `runtime.error`, then NOT cleared by the
6326
+ // following turn_end) — so a warning would brick the agent until
6327
+ // restart. Drop it here; the SDK's own log already records it.
6328
+ case "warning":
6329
+ // turn / step lifecycle (state-only, no parsed payload)
6330
+ case "turn.started":
6331
+ case "turn.step.started":
6332
+ case "turn.step.completed":
6333
+ case "turn.step.retrying":
6334
+ case "turn.step.interrupted":
6335
+ // tool-call progress / hooks (could elevate to internal_progress in future)
6336
+ case "tool.call.delta":
6337
+ case "tool.progress":
6338
+ case "hook.result":
6339
+ // status / meta updates
6340
+ case "agent.status.updated":
6341
+ case "session.meta.updated":
6342
+ case "goal.updated":
6343
+ case "skill.activated":
6344
+ // MCP infra
6345
+ case "tool.list.updated":
6346
+ case "mcp.server.status":
6347
+ // subagent lifecycle (v0: drop; could surface later)
6348
+ case "subagent.spawned":
6349
+ case "subagent.started":
6350
+ case "subagent.suspended":
6351
+ case "subagent.completed":
6352
+ case "subagent.failed":
6353
+ // compaction sub-cases
6354
+ case "compaction.blocked":
6355
+ case "compaction.cancelled":
6356
+ // out-of-band
6357
+ case "background.task.started":
6358
+ case "background.task.terminated":
6359
+ case "cron.fired":
6360
+ return events;
6361
+ default: {
6362
+ const _exhaustive = event;
6363
+ return _exhaustive;
6364
+ }
6365
+ }
6366
+ }
6367
+ var KIMI_SDK_RUNTIME_SESSION_DESCRIPTOR = {
6368
+ transport: "sdk",
6369
+ lifecycle: "sdk_session",
6370
+ input: {
6371
+ initial: "start",
6372
+ idle: "sdk_prompt",
6373
+ busy: "sdk_steer"
6374
+ },
6375
+ readiness: "sdk_ready",
6376
+ turnBoundary: "sdk_event",
6377
+ startPolicy: "immediate",
6378
+ inFlightWake: "steer",
6379
+ busyDelivery: "direct",
6380
+ postTurn: "keep_alive"
6381
+ };
6382
+ async function createKimiAgentSessionForContext(ctx, sessionId) {
6383
+ const sessionDir = buildKimiSessionDir(ctx.workingDirectory);
6384
+ mkdirSync3(sessionDir, { recursive: true });
6385
+ const cliTransport = await prepareCliTransport(ctx, { NO_COLOR: "1" });
6386
+ const spawnEnv = cliTransport.spawnEnv;
6387
+ const wrapperPath = cliTransport.wrapperPath;
6388
+ const homeDir = spawnEnv.KIMI_HOME || (process.env.HOME ? path9.join(process.env.HOME, ".kimi") : path9.join(ctx.workingDirectory, ".kimi"));
6389
+ mkdirSync3(homeDir, { recursive: true });
6390
+ const harness = createKimiHarness({
6391
+ homeDir,
6392
+ identity: {
6393
+ userAgentProduct: KIMI_CODE_USER_AGENT_PRODUCT,
6394
+ version: KIMI_CODE_HOST_VERSION,
6395
+ userAgentSuffix: `slock-daemon/${getDaemonVersion()}`
6396
+ }
6397
+ });
6398
+ const launchRuntimeFields = runtimeConfigToLaunchFields(ctx.config);
6399
+ const sessionFields = {
6400
+ workDir: ctx.workingDirectory,
6401
+ ...launchRuntimeFields.model && launchRuntimeFields.model !== "default" ? { model: launchRuntimeFields.model } : {}
6402
+ };
6403
+ let session;
6404
+ if (ctx.config.sessionId) {
6405
+ try {
6406
+ session = await harness.resumeSession({ ...sessionFields, id: ctx.config.sessionId });
6407
+ } catch (resumeError) {
6408
+ void resumeError;
6409
+ session = await harness.createSession(sessionFields);
6410
+ }
6411
+ } else {
6412
+ session = await harness.createSession(sessionFields);
6413
+ }
6414
+ return { harness, session, wrapperPath };
6415
+ }
6416
+ var KimiSdkRuntimeSession = class {
6417
+ constructor(ctx, setCurrentSessionId, sessionFactory = createKimiAgentSessionForContext) {
6418
+ this.ctx = ctx;
6419
+ this.setCurrentSessionId = setCurrentSessionId;
6420
+ this.sessionFactory = sessionFactory;
6421
+ this.mappingState = createKimiSdkEventMappingState(ctx.config.sessionId || null);
6422
+ }
6423
+ descriptor = KIMI_SDK_RUNTIME_SESSION_DESCRIPTOR;
6424
+ events = new EventEmitter();
6425
+ mappingState;
6426
+ harness = null;
6427
+ session = null;
6428
+ wrapperPath = null;
6429
+ unsubscribe = null;
6430
+ started = false;
6431
+ didClose = false;
6432
+ requestedStopReason;
6433
+ exitInfo = null;
6434
+ get pid() {
6435
+ return void 0;
6436
+ }
6437
+ get currentSessionId() {
6438
+ return this.mappingState.sessionId;
6439
+ }
6440
+ get exitCode() {
6441
+ return this.exitInfo?.code ?? null;
6442
+ }
6443
+ get signalCode() {
6444
+ return this.exitInfo?.signal ?? null;
6445
+ }
6446
+ get closed() {
6447
+ return this.didClose;
6448
+ }
6449
+ on(event, cb) {
6450
+ this.events.on(event, cb);
6451
+ }
6452
+ async start(input) {
6453
+ if (this.started) {
6454
+ return { ok: false, reason: "runtime_error", error: "runtime session already started" };
6455
+ }
6456
+ if (this.didClose) return { ok: false, reason: "closed" };
6457
+ this.started = true;
6458
+ const sessionId = input.sessionId || this.ctx.config.sessionId || randomUUID3();
6459
+ this.mappingState.sessionId = sessionId;
6460
+ this.setCurrentSessionId(sessionId);
6461
+ const { harness, session, wrapperPath } = await this.sessionFactory(
6462
+ {
6463
+ ...this.ctx,
6464
+ config: {
6465
+ ...this.ctx.config,
6466
+ sessionId
6467
+ }
6468
+ },
6469
+ sessionId
6470
+ );
6471
+ this.harness = harness;
6472
+ this.session = session;
6473
+ this.wrapperPath = wrapperPath;
6474
+ this.mappingState.sessionId = session.id;
6475
+ this.setCurrentSessionId(session.id);
6476
+ session.setApprovalHandler(() => ({ decision: "approved", scope: "session" }));
6477
+ this.unsubscribe = session.onEvent((event) => {
6478
+ for (const parsed of mapKimiSdkEventToParsedEvents(event, this.mappingState)) {
6479
+ this.events.emit("runtime_event", parsed);
6480
+ }
6481
+ });
6482
+ this.emitSessionInit();
6483
+ const firstTurnText = this.composeFirstTurnPreamble(input.text);
6484
+ this.launchPrompt(firstTurnText);
6485
+ return { ok: true, acceptedAs: "prompt" };
6486
+ }
6487
+ composeFirstTurnPreamble(turnText) {
6488
+ const sections = [];
6489
+ if (this.ctx.standingPrompt) {
6490
+ sections.push(this.ctx.standingPrompt);
6491
+ }
6492
+ if (this.wrapperPath) {
6493
+ sections.push(
6494
+ `## CLI invocation note (Kimi SDK in-process runtime)
6495
+
6496
+ When you run \`raft\` CLI commands from your bash tool, **use this absolute path** because PATH is not pre-injected for the in-process Kimi SDK:
6497
+
6498
+ \`\`\`
6499
+ ${this.wrapperPath}
6500
+ \`\`\`
6501
+
6502
+ So instead of \`raft message send ...\`, run \`${this.wrapperPath} message send ...\` (every \`raft\` reference in the protocol above maps to this wrapper). The wrapper carries this agent's identity automatically; do not pass auth tokens explicitly.`
6503
+ );
6504
+ }
6505
+ sections.push(turnText);
6506
+ return sections.join("\n\n---\n\n");
6507
+ }
6508
+ send(input) {
6509
+ if (this.didClose) return { ok: false, reason: "closed" };
6510
+ const session = this.session;
6511
+ if (!session) return { ok: false, reason: "closed" };
6512
+ if (input.mode === "busy") {
6513
+ this.deferSdkCall(() => session.steer(input.text));
6514
+ return { ok: true, acceptedAs: "steer" };
6515
+ }
6516
+ this.launchPrompt(input.text);
6517
+ return { ok: true, acceptedAs: "prompt" };
6518
+ }
6519
+ async stop(opts) {
6520
+ if (this.didClose) return;
6521
+ this.requestedStopReason = opts?.reason;
6522
+ const signal = opts?.signal ?? "SIGTERM";
6523
+ const session = this.session;
6524
+ if (session) {
6525
+ try {
6526
+ await session.cancel();
6527
+ } catch (error) {
6528
+ this.events.emit("stderr", kimiErrorMessage(error));
6529
+ }
6530
+ }
6531
+ await this.disposeSession();
6532
+ this.emitExitAndClose(null, signal);
6533
+ }
6534
+ async dispose() {
6535
+ if (this.didClose) return;
6536
+ await this.disposeSession();
6537
+ this.emitExitAndClose(0, null);
6538
+ }
6539
+ emitSessionInit() {
6540
+ const sessionId = this.mappingState.sessionId;
6541
+ if (!sessionId || this.mappingState.sessionAnnounced) return;
6542
+ this.mappingState.sessionAnnounced = true;
6543
+ this.events.emit("runtime_event", { kind: "session_init", sessionId });
6544
+ }
6545
+ launchPrompt(text) {
6546
+ const session = this.session;
6547
+ if (!session) {
6548
+ this.events.emit("runtime_event", {
6549
+ kind: "error",
6550
+ message: "Kimi SDK session is not started"
6551
+ });
6552
+ return;
6553
+ }
6554
+ this.deferSdkCall(() => session.prompt(text));
6555
+ }
6556
+ deferSdkCall(invoke) {
6557
+ setImmediate(() => {
6558
+ if (this.didClose) return;
6559
+ try {
6560
+ void invoke().catch((error) => {
6561
+ if (this.didClose) return;
6562
+ this.events.emit("runtime_event", {
6563
+ kind: "error",
6564
+ message: kimiErrorMessage(error)
6565
+ });
6566
+ });
6567
+ } catch (error) {
6568
+ if (this.didClose) return;
6569
+ this.events.emit("runtime_event", {
6570
+ kind: "error",
6571
+ message: kimiErrorMessage(error)
6572
+ });
6573
+ }
6574
+ });
6575
+ }
6576
+ async disposeSession() {
6577
+ const unsubscribe = this.unsubscribe;
6578
+ this.unsubscribe = null;
6579
+ try {
6580
+ unsubscribe?.();
6581
+ } catch {
6582
+ }
6583
+ const session = this.session;
6584
+ this.session = null;
6585
+ try {
6586
+ await session?.close();
6587
+ } catch (error) {
6588
+ this.events.emit("stderr", kimiErrorMessage(error));
6589
+ }
6590
+ const harness = this.harness;
6591
+ this.harness = null;
6592
+ try {
6593
+ await harness?.close();
6594
+ } catch (error) {
6595
+ this.events.emit("stderr", kimiErrorMessage(error));
6596
+ }
6597
+ }
6598
+ emitExitAndClose(code, signal) {
6599
+ if (this.didClose) return;
6600
+ this.didClose = true;
6601
+ const info = {
6602
+ code,
6603
+ signal,
6604
+ reason: this.requestedStopReason ? "requested" : "runtime_exit"
6605
+ };
6606
+ this.exitInfo = info;
6607
+ this.events.emit("exit", info);
6608
+ this.events.emit("close", info);
6609
+ }
6610
+ };
6611
+ var KIMI_SDK_DEFAULT_MODELS = [
6612
+ // Canonical Kimi Code SDK model (matches the `default_model` upstream
6613
+ // ships in `~/.kimi/config.toml` after `kimi login`). Mirrored as the first
6614
+ // entry in `RUNTIME_MODELS["kimi-sdk"]` (packages/shared/src/index.ts) so
6615
+ // both the daemon's launch resolution and the web's getDefaultModel agree.
6616
+ { id: "kimi-code/kimi-for-coding", label: "Kimi-K2.6 (Kimi for Coding)", verified: "launchable" },
6617
+ { id: "kimi-k2-0905-preview", label: "Kimi K2 (preview)", verified: "suggestion_only" }
6618
+ ];
6619
+ function detectKimiSdkModels() {
6620
+ return { models: KIMI_SDK_DEFAULT_MODELS };
6621
+ }
6622
+ var KimiSdkDriver = class {
6623
+ id = "kimi-sdk";
6624
+ supportsNativeStandingPrompt = true;
6625
+ lifecycle = {
6626
+ kind: "persistent",
6627
+ stdin: "direct",
6628
+ inFlightWake: "steer"
6629
+ };
6630
+ communication = {
6631
+ chat: "slock_cli",
6632
+ runtimeControl: "none"
6633
+ };
6634
+ session = {
6635
+ recovery: "resume_or_fresh"
6636
+ };
6637
+ model = {
6638
+ detectedModelsVerifiedAs: "suggestion_only",
6639
+ toLaunchSpec: (modelId) => ({ params: { model: modelId } })
6640
+ };
6641
+ supportsStdinNotification = true;
6642
+ busyDeliveryMode = "direct";
6643
+ sessionId = null;
6644
+ get currentSessionId() {
6645
+ return this.sessionId;
6646
+ }
6647
+ probe() {
6648
+ return { available: true };
6649
+ }
6650
+ async detectModels() {
6651
+ return detectKimiSdkModels();
6652
+ }
6653
+ createSession(ctx) {
6654
+ this.sessionId = ctx.config.sessionId || null;
6655
+ return new KimiSdkRuntimeSession(ctx, (sessionId) => {
6656
+ this.sessionId = sessionId;
6657
+ });
6658
+ }
6659
+ async spawn(_ctx) {
6660
+ throw new Error("KimiSdkDriver uses a native RuntimeSession; child-process spawn is unsupported");
6661
+ }
6662
+ parseLine(_line) {
6663
+ return [];
6664
+ }
6665
+ encodeStdinMessage(_text, _sessionId, _opts) {
6666
+ return null;
6667
+ }
6668
+ buildSystemPrompt(config, _agentId) {
6669
+ return buildCliTransportSystemPrompt(config, {
6670
+ extraCriticalRules: [],
6671
+ postStartupNotes: [
6672
+ "**Kimi SDK runtime note:** Slock keeps Kimi running as a persistent SDK session. While you are working, Slock may send inbox-count notifications into the current turn; call `raft message check` at natural breakpoints."
6673
+ ],
6674
+ includeStdinNotificationSection: true,
6675
+ messageNotificationStyle: "direct"
6676
+ });
6677
+ }
6678
+ };
6679
+
6322
6680
  // src/drivers/opencode.ts
6323
6681
  import { spawn as spawn8, spawnSync as spawnSync2 } from "child_process";
6324
6682
  import { existsSync as existsSync8, readFileSync as readFileSync4 } from "fs";
6325
6683
  import os5 from "os";
6326
- import path9 from "path";
6684
+ import path10 from "path";
6327
6685
  var SLOCK_AGENT_NAME = "slock";
6328
6686
  var NO_MESSAGE_PROMPT = "No new messages are pending. Stop now.";
6329
6687
  var FIRST_MESSAGE_TASK_PREFIX = "First message task (system-triggered):";
@@ -6352,7 +6710,7 @@ function parseUserOpenCodeConfig(ctx) {
6352
6710
  return parseOpenCodeConfigContent(raw);
6353
6711
  }
6354
6712
  function readLocalOpenCodeConfig(home = os5.homedir()) {
6355
- const configPath = path9.join(home, ".config", "opencode", "opencode.json");
6713
+ const configPath = path10.join(home, ".config", "opencode", "opencode.json");
6356
6714
  try {
6357
6715
  return parseOpenCodeConfigContent(readFileSync4(configPath, "utf8"));
6358
6716
  } catch {
@@ -6538,7 +6896,7 @@ function runOpenCodeModelsCommand(home, deps = {}) {
6538
6896
  const platform = deps.platform ?? process.platform;
6539
6897
  const spawnSyncFn = deps.spawnSyncFn ?? spawnSync2;
6540
6898
  const result = spawnSyncFn("opencode", ["models"], {
6541
- env: scrubDaemonChildEnv({ ...process.env, HOME: home, FORCE_COLOR: "0", NO_COLOR: "1" }),
6899
+ env: { ...process.env, HOME: home, FORCE_COLOR: "0", NO_COLOR: "1" },
6542
6900
  encoding: "utf8",
6543
6901
  timeout: 5e3,
6544
6902
  shell: platform === "win32"
@@ -6550,11 +6908,11 @@ function runOpenCodeModelsCommand(home, deps = {}) {
6550
6908
  };
6551
6909
  }
6552
6910
  function isWindowsCommandShim(commandPath) {
6553
- const ext = path9.win32.extname(commandPath).toLowerCase();
6911
+ const ext = path10.win32.extname(commandPath).toLowerCase();
6554
6912
  return ext === ".cmd" || ext === ".bat";
6555
6913
  }
6556
6914
  function opencodePackageEntryCandidates(packageRoot) {
6557
- const winPath = path9.win32;
6915
+ const winPath = path10.win32;
6558
6916
  return [
6559
6917
  winPath.join(packageRoot, "bin", "opencode.exe"),
6560
6918
  winPath.join(packageRoot, "bin", "opencode.js"),
@@ -6563,7 +6921,7 @@ function opencodePackageEntryCandidates(packageRoot) {
6563
6921
  ];
6564
6922
  }
6565
6923
  function openCodeSpecForEntry(entry, commandArgs) {
6566
- if (path9.win32.extname(entry).toLowerCase() === ".exe") {
6924
+ if (path10.win32.extname(entry).toLowerCase() === ".exe") {
6567
6925
  return { command: entry, args: commandArgs, shell: false };
6568
6926
  }
6569
6927
  return { command: process.execPath, args: [entry, ...commandArgs], shell: false };
@@ -6572,7 +6930,7 @@ function resolveWindowsOpenCodePackageEntry(commandPath, deps = {}) {
6572
6930
  const existsSyncFn = deps.existsSyncFn ?? existsSync8;
6573
6931
  const execFileSyncFn = deps.execFileSyncFn;
6574
6932
  const env = deps.env ?? process.env;
6575
- const winPath = path9.win32;
6933
+ const winPath = path10.win32;
6576
6934
  const candidates = [];
6577
6935
  if (execFileSyncFn) {
6578
6936
  try {
@@ -6600,7 +6958,7 @@ function resolveWindowsOpenCodePackageEntry(commandPath, deps = {}) {
6600
6958
  function extractWindowsShimTargets(commandPath, deps = {}) {
6601
6959
  if (!isWindowsCommandShim(commandPath)) return [];
6602
6960
  const readFileSyncFn = deps.readFileSyncFn ?? readFileSync4;
6603
- const commandDir = path9.win32.dirname(commandPath);
6961
+ const commandDir = path10.win32.dirname(commandPath);
6604
6962
  let raw;
6605
6963
  try {
6606
6964
  raw = String(readFileSyncFn(commandPath, "utf8"));
@@ -6611,7 +6969,7 @@ function extractWindowsShimTargets(commandPath, deps = {}) {
6611
6969
  const dp0Pattern = /%~dp0\\?([^"\r\n]*?opencode\.(?:exe|js|mjs|cjs))/gi;
6612
6970
  for (const match of raw.matchAll(dp0Pattern)) {
6613
6971
  const relative = match[1]?.replace(/^\\+/, "");
6614
- if (relative) candidates.push(path9.win32.normalize(path9.win32.join(commandDir, relative)));
6972
+ if (relative) candidates.push(path10.win32.normalize(path10.win32.join(commandDir, relative)));
6615
6973
  }
6616
6974
  return candidates;
6617
6975
  }
@@ -6625,7 +6983,7 @@ function resolveOpenCodeSpawn(commandArgs, deps = {}) {
6625
6983
  };
6626
6984
  }
6627
6985
  const command = resolveCommandOnPath("opencode", deps);
6628
- if (command && path9.win32.extname(command).toLowerCase() === ".exe") {
6986
+ if (command && path10.win32.extname(command).toLowerCase() === ".exe") {
6629
6987
  return { command, args: commandArgs, shell: false };
6630
6988
  }
6631
6989
  const packageEntry = resolveWindowsOpenCodePackageEntry(command, deps);
@@ -6795,10 +7153,10 @@ var OpenCodeDriver = class {
6795
7153
  };
6796
7154
 
6797
7155
  // src/drivers/pi.ts
6798
- import { randomUUID as randomUUID3 } from "crypto";
6799
- import { EventEmitter } from "events";
6800
- import { mkdirSync as mkdirSync3, readdirSync as readdirSync2 } from "fs";
6801
- import path10 from "path";
7156
+ import { randomUUID as randomUUID4 } from "crypto";
7157
+ import { EventEmitter as EventEmitter2 } from "events";
7158
+ import { mkdirSync as mkdirSync4, readdirSync as readdirSync2 } from "fs";
7159
+ import path11 from "path";
6802
7160
  import {
6803
7161
  AuthStorage,
6804
7162
  createBashTool,
@@ -6824,7 +7182,7 @@ function createPiSdkEventMappingState(sessionId = null) {
6824
7182
  };
6825
7183
  }
6826
7184
  function buildPiSessionDir(workingDirectory) {
6827
- return path10.join(workingDirectory, PI_SESSION_DIR);
7185
+ return path11.join(workingDirectory, PI_SESSION_DIR);
6828
7186
  }
6829
7187
  async function buildPiSpawnEnv(ctx) {
6830
7188
  return (await prepareCliTransport(ctx, { NO_COLOR: "1" })).spawnEnv;
@@ -6846,7 +7204,7 @@ function findPiSessionFile(sessionDir, sessionId) {
6846
7204
  }
6847
7205
  const suffix = `_${sessionId}.jsonl`;
6848
7206
  const match = entries.find((entry) => entry.endsWith(suffix));
6849
- return match ? path10.join(sessionDir, match) : null;
7207
+ return match ? path11.join(sessionDir, match) : null;
6850
7208
  }
6851
7209
  function detectPiModelsFromRegistry(modelRegistry) {
6852
7210
  const models = [];
@@ -6959,7 +7317,7 @@ function piErrorMessage(error) {
6959
7317
  }
6960
7318
  return "Unknown Pi error";
6961
7319
  }
6962
- function pushSessionInitIfNeeded(state, events) {
7320
+ function pushSessionInitIfNeeded2(state, events) {
6963
7321
  if (!state.sessionAnnounced && state.sessionId) {
6964
7322
  events.push({ kind: "session_init", sessionId: state.sessionId });
6965
7323
  state.sessionAnnounced = true;
@@ -6996,7 +7354,7 @@ function mapPiAssistantMessageEvent(assistantEvent, state) {
6996
7354
  }
6997
7355
  function mapPiSdkEventToParsedEvents(event, state) {
6998
7356
  const events = [];
6999
- pushSessionInitIfNeeded(state, events);
7357
+ pushSessionInitIfNeeded2(state, events);
7000
7358
  switch (event.type) {
7001
7359
  case "agent_start":
7002
7360
  case "turn_start":
@@ -7061,7 +7419,7 @@ var PI_IDLE_PROMPT_RETRY_MS = 25;
7061
7419
  var PI_IDLE_PROMPT_MAX_WAIT_MS = 1e3;
7062
7420
  async function createPiAgentSessionForContext(ctx, sessionId) {
7063
7421
  const sessionDir = buildPiSessionDir(ctx.workingDirectory);
7064
- mkdirSync3(sessionDir, { recursive: true });
7422
+ mkdirSync4(sessionDir, { recursive: true });
7065
7423
  const launchRuntimeFields = runtimeConfigToLaunchFields(ctx.config);
7066
7424
  const requestedModel = launchRuntimeFields.model || "default";
7067
7425
  const traceSpan = ctx.tracer?.startSpan("daemon.pi.session.create", {
@@ -7079,7 +7437,7 @@ async function createPiAgentSessionForContext(ctx, sessionId) {
7079
7437
  try {
7080
7438
  const spawnEnv = await buildPiSpawnEnv(ctx);
7081
7439
  const agentDir = spawnEnv.PI_CODING_AGENT_DIR || getAgentDir();
7082
- const authStorage = AuthStorage.create(path10.join(agentDir, "auth.json"));
7440
+ const authStorage = AuthStorage.create(path11.join(agentDir, "auth.json"));
7083
7441
  const settingsManager = SettingsManager.create(ctx.workingDirectory, agentDir);
7084
7442
  const services = await createAgentSessionServices({
7085
7443
  cwd: ctx.workingDirectory,
@@ -7191,7 +7549,7 @@ var PiSdkRuntimeSession = class {
7191
7549
  this.mappingState = createPiSdkEventMappingState(ctx.config.sessionId || null);
7192
7550
  }
7193
7551
  descriptor = PI_RUNTIME_SESSION_DESCRIPTOR;
7194
- events = new EventEmitter();
7552
+ events = new EventEmitter2();
7195
7553
  mappingState;
7196
7554
  session = null;
7197
7555
  unsubscribe = null;
@@ -7223,7 +7581,7 @@ var PiSdkRuntimeSession = class {
7223
7581
  }
7224
7582
  if (this.didClose) return { ok: false, reason: "closed" };
7225
7583
  this.started = true;
7226
- const sessionId = input.sessionId || this.ctx.config.sessionId || randomUUID3();
7584
+ const sessionId = input.sessionId || this.ctx.config.sessionId || randomUUID4();
7227
7585
  this.mappingState.sessionId = sessionId;
7228
7586
  this.setCurrentSessionId(sessionId);
7229
7587
  const session = await this.sessionFactory({
@@ -7434,7 +7792,7 @@ function delay(ms) {
7434
7792
  }
7435
7793
 
7436
7794
  // src/drivers/runtimeSession.ts
7437
- import { EventEmitter as EventEmitter2 } from "events";
7795
+ import { EventEmitter as EventEmitter3 } from "events";
7438
7796
  function descriptorFromDriver(driver) {
7439
7797
  const lifecycle = driver.lifecycle.kind === "per_turn" ? "turn_based" : "persistent_stream";
7440
7798
  const idle = driver.supportsStdinNotification ? "stdin" : "unsupported";
@@ -7462,7 +7820,7 @@ var ChildProcessRuntimeSession = class {
7462
7820
  this.descriptor = descriptorFromDriver(driver);
7463
7821
  }
7464
7822
  descriptor;
7465
- events = new EventEmitter2();
7823
+ events = new EventEmitter3();
7466
7824
  process = null;
7467
7825
  started = false;
7468
7826
  stdoutBuffer = "";
@@ -7575,7 +7933,13 @@ var driverFactories = {
7575
7933
  copilot: () => new CopilotDriver(),
7576
7934
  cursor: () => new CursorDriver(),
7577
7935
  gemini: () => new GeminiDriver(),
7936
+ // Two separate Kimi runtimes (per #proj-runtime:cc818e65 6/16 consensus):
7937
+ // - `kimi` = legacy kimi-cli child-process driver. Backward-compat for
7938
+ // existing `runtime=kimi` agents. Frontend marks deprecated.
7939
+ // - `kimi-sdk` = canonical in-process SDK driver. Frontend label "Kimi Code".
7940
+ // No alias / no auto-migration; explicit pick at agent-create time.
7578
7941
  kimi: () => new KimiDriver(),
7942
+ "kimi-sdk": () => new KimiSdkDriver(),
7579
7943
  opencode: () => new OpenCodeDriver(),
7580
7944
  pi: () => new PiDriver()
7581
7945
  };
@@ -7590,7 +7954,7 @@ function getDriver(runtimeId) {
7590
7954
 
7591
7955
  // src/workspaces.ts
7592
7956
  import { readdir, rm, stat } from "fs/promises";
7593
- import path11 from "path";
7957
+ import path12 from "path";
7594
7958
  function isValidWorkspaceDirectoryName(directoryName) {
7595
7959
  return !directoryName.includes("/") && !directoryName.includes("\\") && !directoryName.includes("..");
7596
7960
  }
@@ -7598,7 +7962,7 @@ function resolveWorkspaceDirectoryPath(dataDir, directoryName) {
7598
7962
  if (!isValidWorkspaceDirectoryName(directoryName)) {
7599
7963
  return null;
7600
7964
  }
7601
- return path11.join(dataDir, directoryName);
7965
+ return path12.join(dataDir, directoryName);
7602
7966
  }
7603
7967
  function emptyWorkspaceDirectorySummary(latestMtime = /* @__PURE__ */ new Date(0)) {
7604
7968
  return {
@@ -7647,7 +8011,7 @@ async function summarizeWorkspaceDirectory(dirPath) {
7647
8011
  return summary;
7648
8012
  }
7649
8013
  const childSummaries = await Promise.all(
7650
- entries.map((entry) => summarizeWorkspaceEntry(path11.join(dirPath, entry.name), entry))
8014
+ entries.map((entry) => summarizeWorkspaceEntry(path12.join(dirPath, entry.name), entry))
7651
8015
  );
7652
8016
  for (const childSummary of childSummaries) {
7653
8017
  summary = mergeWorkspaceDirectorySummaries(summary, childSummary);
@@ -7666,7 +8030,7 @@ async function scanWorkspaceDirectories(dataDir) {
7666
8030
  if (!entry.isDirectory()) {
7667
8031
  return null;
7668
8032
  }
7669
- const dirPath = path11.join(dataDir, entry.name);
8033
+ const dirPath = path12.join(dataDir, entry.name);
7670
8034
  try {
7671
8035
  const summary = await summarizeWorkspaceDirectory(dirPath);
7672
8036
  return {
@@ -8217,12 +8581,12 @@ function findSessionJsonl(root, predicate) {
8217
8581
  for (const entry of entries) {
8218
8582
  if (++visited > maxEntries) return null;
8219
8583
  if (!entry.isFile() || !predicate(entry.name)) continue;
8220
- return path12.join(dir, entry.name);
8584
+ return path13.join(dir, entry.name);
8221
8585
  }
8222
8586
  for (const entry of entries) {
8223
8587
  if (++visited > maxEntries) return null;
8224
8588
  if (!entry.isDirectory()) continue;
8225
- const found = visit(path12.join(dir, entry.name), depth - 1);
8589
+ const found = visit(path13.join(dir, entry.name), depth - 1);
8226
8590
  if (found) return found;
8227
8591
  }
8228
8592
  return null;
@@ -8235,9 +8599,9 @@ function safeSessionFilename(value) {
8235
8599
  }
8236
8600
  function writeRuntimeSessionHandoff(runtime, sessionId, fallbackDir) {
8237
8601
  try {
8238
- const dir = path12.join(fallbackDir, ".slock", "runtime-sessions");
8239
- mkdirSync4(dir, { recursive: true });
8240
- const filePath = path12.join(dir, `${runtime}-${safeSessionFilename(sessionId)}.jsonl`);
8602
+ const dir = path13.join(fallbackDir, ".slock", "runtime-sessions");
8603
+ mkdirSync5(dir, { recursive: true });
8604
+ const filePath = path13.join(dir, `${runtime}-${safeSessionFilename(sessionId)}.jsonl`);
8241
8605
  writeFileSync4(filePath, JSON.stringify({
8242
8606
  type: "runtime_session_handoff",
8243
8607
  runtime,
@@ -8269,7 +8633,7 @@ function ensureRuntimeHomeDir(config, defaultHomeDir, workspacePath) {
8269
8633
  return defaultHomeDir;
8270
8634
  }
8271
8635
  function resolveRuntimeSessionRef(runtime, sessionId, homeDir = os6.homedir(), fallbackDir) {
8272
- const directPath = path12.isAbsolute(sessionId) ? sessionId : null;
8636
+ const directPath = path13.isAbsolute(sessionId) ? sessionId : null;
8273
8637
  if (directPath) {
8274
8638
  try {
8275
8639
  if (statSync(directPath).isFile()) {
@@ -8278,7 +8642,7 @@ function resolveRuntimeSessionRef(runtime, sessionId, homeDir = os6.homedir(), f
8278
8642
  } catch {
8279
8643
  }
8280
8644
  }
8281
- 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;
8645
+ const resolvedPath = runtime === "claude" ? findSessionJsonl(path13.join(homeDir, ".claude", "projects"), (filename) => filename === `${sessionId}.jsonl`) : runtime === "codex" ? findSessionJsonl(path13.join(homeDir, ".codex", "sessions"), (filename) => filename.endsWith(".jsonl") && filename.includes(sessionId)) : null;
8282
8646
  if (!resolvedPath && fallbackDir) {
8283
8647
  const fallback = writeRuntimeSessionHandoff(runtime, sessionId, fallbackDir);
8284
8648
  if (fallback) return fallback;
@@ -10229,7 +10593,7 @@ var AgentProcessManager = class _AgentProcessManager {
10229
10593
  );
10230
10594
  wakeMessage = void 0;
10231
10595
  }
10232
- const agentDataDir = path12.join(this.dataDir, agentId);
10596
+ const agentDataDir = path13.join(this.dataDir, agentId);
10233
10597
  await mkdir(agentDataDir, { recursive: true });
10234
10598
  let runtimeConfig = withLocalRuntimeContext(config, agentId, agentDataDir);
10235
10599
  const legacyRuntimeProfileControl = runtimeConfig.runtimeProfileControl?.kind === "migration" ? runtimeConfig.runtimeProfileControl : null;
@@ -10243,23 +10607,23 @@ var AgentProcessManager = class _AgentProcessManager {
10243
10607
  );
10244
10608
  runtimeConfig = { ...runtimeConfig, runtimeProfileControl: null };
10245
10609
  }
10246
- const memoryMdPath = path12.join(agentDataDir, "MEMORY.md");
10610
+ const memoryMdPath = path13.join(agentDataDir, "MEMORY.md");
10247
10611
  try {
10248
10612
  await access(memoryMdPath);
10249
10613
  } catch {
10250
10614
  const initialMemoryMd = buildInitialMemoryMd(runtimeConfig);
10251
10615
  await writeFile(memoryMdPath, initialMemoryMd);
10252
10616
  }
10253
- const notesDir = path12.join(agentDataDir, "notes");
10617
+ const notesDir = path13.join(agentDataDir, "notes");
10254
10618
  await mkdir(notesDir, { recursive: true });
10255
10619
  if (getOnboardingSeedMode(config) === FIRST_CINDY_SEED_MODE) {
10256
10620
  const seedFiles = buildOnboardingSeedFiles();
10257
10621
  for (const { relativePath, content } of seedFiles) {
10258
- const fullPath = path12.join(agentDataDir, relativePath);
10622
+ const fullPath = path13.join(agentDataDir, relativePath);
10259
10623
  try {
10260
10624
  await access(fullPath);
10261
10625
  } catch {
10262
- await mkdir(path12.dirname(fullPath), { recursive: true });
10626
+ await mkdir(path13.dirname(fullPath), { recursive: true });
10263
10627
  await writeFile(fullPath, content);
10264
10628
  }
10265
10629
  }
@@ -11486,7 +11850,7 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
11486
11850
  return true;
11487
11851
  }
11488
11852
  async resetWorkspace(agentId) {
11489
- const agentDataDir = path12.join(this.dataDir, agentId);
11853
+ const agentDataDir = path13.join(this.dataDir, agentId);
11490
11854
  try {
11491
11855
  await rm2(agentDataDir, { recursive: true, force: true });
11492
11856
  logger.info(`[Agent ${agentId}] Workspace reset complete (${agentDataDir})`);
@@ -11547,7 +11911,7 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
11547
11911
  return result;
11548
11912
  }
11549
11913
  buildRuntimeProfileReport(agentId, config, sessionId, launchId) {
11550
- const workspacePath = path12.join(this.dataDir, agentId);
11914
+ const workspacePath = path13.join(this.dataDir, agentId);
11551
11915
  const runtimeHomeDir = resolveRuntimeHomeDir(config, this.runtimeSessionHomeDir, workspacePath);
11552
11916
  return {
11553
11917
  agentId,
@@ -11841,7 +12205,7 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
11841
12205
  }
11842
12206
  // Workspace file browsing
11843
12207
  async getFileTree(agentId, dirPath) {
11844
- const agentDir = path12.join(this.dataDir, agentId);
12208
+ const agentDir = path13.join(this.dataDir, agentId);
11845
12209
  try {
11846
12210
  await stat2(agentDir);
11847
12211
  } catch {
@@ -11849,8 +12213,8 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
11849
12213
  }
11850
12214
  let targetDir = agentDir;
11851
12215
  if (dirPath) {
11852
- const resolved = path12.resolve(agentDir, dirPath);
11853
- if (!resolved.startsWith(agentDir + path12.sep) && resolved !== agentDir) {
12216
+ const resolved = path13.resolve(agentDir, dirPath);
12217
+ if (!resolved.startsWith(agentDir + path13.sep) && resolved !== agentDir) {
11854
12218
  return [];
11855
12219
  }
11856
12220
  targetDir = resolved;
@@ -11858,14 +12222,14 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
11858
12222
  return this.listDirectoryChildren(targetDir, agentDir);
11859
12223
  }
11860
12224
  async readFile(agentId, filePath) {
11861
- const agentDir = path12.join(this.dataDir, agentId);
11862
- const resolved = path12.resolve(agentDir, filePath);
11863
- if (!resolved.startsWith(agentDir + path12.sep) && resolved !== agentDir) {
12225
+ const agentDir = path13.join(this.dataDir, agentId);
12226
+ const resolved = path13.resolve(agentDir, filePath);
12227
+ if (!resolved.startsWith(agentDir + path13.sep) && resolved !== agentDir) {
11864
12228
  throw new Error("Access denied");
11865
12229
  }
11866
12230
  const info = await stat2(resolved);
11867
12231
  if (info.isDirectory()) throw new Error("Cannot read a directory");
11868
- const ext = path12.extname(resolved).toLowerCase();
12232
+ const ext = path13.extname(resolved).toLowerCase();
11869
12233
  if (WORKSPACE_TEXT_EXTENSIONS.has(ext) || ext === "") {
11870
12234
  if (info.size > WORKSPACE_TEXT_FILE_MAX_BYTES) throw new Error("File too large");
11871
12235
  const content = await readFile(resolved, "utf-8");
@@ -11901,14 +12265,14 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
11901
12265
  const idle = this.idleAgentConfigs.get(agentId);
11902
12266
  const config = agent?.config ?? idle?.config ?? null;
11903
12267
  const runtime = runtimeHint || config?.runtime || "claude";
11904
- const workspaceDir = path12.join(this.dataDir, agentId);
12268
+ const workspaceDir = path13.join(this.dataDir, agentId);
11905
12269
  const home = config ? ensureRuntimeHomeDir(config, os6.homedir(), workspaceDir) : os6.homedir();
11906
12270
  const paths = _AgentProcessManager.SKILL_PATHS[runtime] || _AgentProcessManager.SKILL_PATHS.claude;
11907
12271
  const globalResults = await Promise.all(
11908
- paths.global.map((p) => this.scanSkillsDir(path12.join(home, p)))
12272
+ paths.global.map((p) => this.scanSkillsDir(path13.join(home, p)))
11909
12273
  );
11910
12274
  const workspaceResults = await Promise.all(
11911
- paths.workspace.map((p) => this.scanSkillsDir(path12.join(workspaceDir, p)))
12275
+ paths.workspace.map((p) => this.scanSkillsDir(path13.join(workspaceDir, p)))
11912
12276
  );
11913
12277
  const dedup = (skills) => {
11914
12278
  const seen = /* @__PURE__ */ new Set();
@@ -11937,7 +12301,7 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
11937
12301
  const skills = [];
11938
12302
  for (const entry of entries) {
11939
12303
  if (entry.isDirectory() || entry.isSymbolicLink()) {
11940
- const skillMd = path12.join(dir, entry.name, "SKILL.md");
12304
+ const skillMd = path13.join(dir, entry.name, "SKILL.md");
11941
12305
  try {
11942
12306
  const content = await readFile(skillMd, "utf-8");
11943
12307
  const skill = this.parseSkillMd(entry.name, content);
@@ -11948,7 +12312,7 @@ Use ${communicationCommand("read_history")} to catch up on the channels listed a
11948
12312
  } else if (entry.name.endsWith(".md")) {
11949
12313
  const cmdName = entry.name.replace(/\.md$/, "");
11950
12314
  try {
11951
- const content = await readFile(path12.join(dir, entry.name), "utf-8");
12315
+ const content = await readFile(path13.join(dir, entry.name), "utf-8");
11952
12316
  const skill = this.parseSkillMd(cmdName, content);
11953
12317
  skill.sourcePath = dir;
11954
12318
  skills.push(skill);
@@ -13428,8 +13792,8 @@ ${RESPONSE_TARGET_HINT}`);
13428
13792
  const nodes = [];
13429
13793
  for (const entry of entries) {
13430
13794
  if (entry.name.startsWith(".") || entry.name === "node_modules") continue;
13431
- const fullPath = path12.join(dir, entry.name);
13432
- const relativePath = path12.relative(rootDir, fullPath);
13795
+ const fullPath = path13.join(dir, entry.name);
13796
+ const relativePath = path13.relative(rootDir, fullPath);
13433
13797
  let info;
13434
13798
  try {
13435
13799
  info = await stat2(fullPath);
@@ -13802,10 +14166,10 @@ var ReminderCache = class {
13802
14166
  };
13803
14167
 
13804
14168
  // src/machineLock.ts
13805
- import { createHash as createHash4, randomUUID as randomUUID4 } from "crypto";
13806
- import { mkdirSync as mkdirSync5, readFileSync as readFileSync5, rmSync as rmSync3, statSync as statSync2, writeFileSync as writeFileSync5 } from "fs";
14169
+ import { createHash as createHash4, randomUUID as randomUUID5 } from "crypto";
14170
+ import { mkdirSync as mkdirSync6, readFileSync as readFileSync5, rmSync as rmSync3, statSync as statSync2, writeFileSync as writeFileSync5 } from "fs";
13807
14171
  import os7 from "os";
13808
- import path13 from "path";
14172
+ import path14 from "path";
13809
14173
  var INCOMPLETE_LOCK_STALE_MS = 3e4;
13810
14174
  var DaemonMachineLockConflictError = class extends Error {
13811
14175
  code = "DAEMON_MACHINE_LOCK_HELD";
@@ -13827,7 +14191,7 @@ function resolveDefaultMachineStateRoot() {
13827
14191
  return resolveSlockHomePath("machines");
13828
14192
  }
13829
14193
  function ownerPath(lockDir) {
13830
- return path13.join(lockDir, "owner.json");
14194
+ return path14.join(lockDir, "owner.json");
13831
14195
  }
13832
14196
  function readOwner(lockDir) {
13833
14197
  try {
@@ -13857,13 +14221,13 @@ function acquireDaemonMachineLock(options) {
13857
14221
  const rootDir = options.rootDir ?? resolveDefaultMachineStateRoot();
13858
14222
  const fingerprint = apiKeyFingerprint(options.apiKey);
13859
14223
  const lockId = getDaemonMachineLockId(options.apiKey);
13860
- const machineDir = path13.join(rootDir, lockId);
13861
- const lockDir = path13.join(machineDir, "daemon.lock");
13862
- const token = randomUUID4();
13863
- mkdirSync5(machineDir, { recursive: true });
14224
+ const machineDir = path14.join(rootDir, lockId);
14225
+ const lockDir = path14.join(machineDir, "daemon.lock");
14226
+ const token = randomUUID5();
14227
+ mkdirSync6(machineDir, { recursive: true });
13864
14228
  for (let attempt = 0; attempt < 2; attempt += 1) {
13865
14229
  try {
13866
- mkdirSync5(lockDir);
14230
+ mkdirSync6(lockDir);
13867
14231
  const owner = {
13868
14232
  pid: process.pid,
13869
14233
  token,
@@ -13918,8 +14282,8 @@ function acquireDaemonMachineLock(options) {
13918
14282
  }
13919
14283
 
13920
14284
  // src/localTraceSink.ts
13921
- import { appendFileSync, mkdirSync as mkdirSync6, readdirSync as readdirSync4, rmSync as rmSync4, statSync as statSync3, writeFileSync as writeFileSync6 } from "fs";
13922
- import path14 from "path";
14285
+ import { appendFileSync, mkdirSync as mkdirSync7, readdirSync as readdirSync4, rmSync as rmSync4, statSync as statSync3, writeFileSync as writeFileSync6 } from "fs";
14286
+ import path15 from "path";
13923
14287
  var DEFAULT_MAX_FILE_BYTES = 5 * 1024 * 1024;
13924
14288
  var DEFAULT_MAX_FILE_AGE_MS = 5 * 60 * 1e3;
13925
14289
  var DEFAULT_MAX_FILES = 8;
@@ -13956,7 +14320,7 @@ var LocalRotatingTraceSink = class {
13956
14320
  currentSize = 0;
13957
14321
  sequence = 0;
13958
14322
  constructor(options) {
13959
- this.traceDir = path14.join(options.machineDir, "traces");
14323
+ this.traceDir = path15.join(options.machineDir, "traces");
13960
14324
  this.maxFileBytes = Math.max(1024, Math.floor(options.maxFileBytes ?? DEFAULT_MAX_FILE_BYTES));
13961
14325
  const baseAgeMs = Math.max(1e3, Math.floor(options.maxFileAgeMs ?? DEFAULT_MAX_FILE_AGE_MS));
13962
14326
  const ageJitterMs = Math.max(0, Math.floor(options.maxFileAgeJitterMs ?? 0));
@@ -13982,11 +14346,11 @@ var LocalRotatingTraceSink = class {
13982
14346
  return this.currentFile;
13983
14347
  }
13984
14348
  ensureFile(nextBytes) {
13985
- mkdirSync6(this.traceDir, { recursive: true, mode: 448 });
14349
+ mkdirSync7(this.traceDir, { recursive: true, mode: 448 });
13986
14350
  const nowMs = this.nowMsProvider();
13987
14351
  const shouldRotateForAge = this.currentFileOpenedAtMs !== null && nowMs - this.currentFileOpenedAtMs >= this.maxFileAgeMs;
13988
14352
  if (!this.currentFile || this.currentSize + nextBytes > this.maxFileBytes || shouldRotateForAge) {
13989
- this.currentFile = path14.join(
14353
+ this.currentFile = path15.join(
13990
14354
  this.traceDir,
13991
14355
  `daemon-trace-${safeTimestamp(nowMs)}-${process.pid}-${String(this.sequence++).padStart(4, "0")}.jsonl`
13992
14356
  );
@@ -14001,7 +14365,7 @@ var LocalRotatingTraceSink = class {
14001
14365
  const excess = files.length - this.maxFiles;
14002
14366
  if (excess <= 0) return;
14003
14367
  for (const file of files.slice(0, excess)) {
14004
- rmSync4(path14.join(this.traceDir, file), { force: true });
14368
+ rmSync4(path15.join(this.traceDir, file), { force: true });
14005
14369
  }
14006
14370
  }
14007
14371
  };
@@ -14089,10 +14453,10 @@ function isDiagnosticErrorAttr(key) {
14089
14453
  }
14090
14454
 
14091
14455
  // src/traceBundleUpload.ts
14092
- import { createHash as createHash6, randomUUID as randomUUID5 } from "crypto";
14456
+ import { createHash as createHash6, randomUUID as randomUUID6 } from "crypto";
14093
14457
  import { gzipSync } from "zlib";
14094
14458
  import { mkdir as mkdir2, readFile as readFile2, readdir as readdir3, stat as stat3, writeFile as writeFile2 } from "fs/promises";
14095
- import path15 from "path";
14459
+ import path16 from "path";
14096
14460
 
14097
14461
  // src/chatBridgeRequest.ts
14098
14462
  var DEFAULT_CHAT_BRIDGE_TOOL_TIMEOUT_MS = Number.parseInt(
@@ -14192,8 +14556,8 @@ async function executeResponseRequest(url, init, {
14192
14556
  }
14193
14557
 
14194
14558
  // src/directUploadCapability.ts
14195
- function joinUrl(base, path17) {
14196
- return `${base.replace(/\/+$/, "")}${path17}`;
14559
+ function joinUrl(base, path18) {
14560
+ return `${base.replace(/\/+$/, "")}${path18}`;
14197
14561
  }
14198
14562
  function jsonHeaders(apiKey) {
14199
14563
  return {
@@ -14412,7 +14776,7 @@ var DaemonTraceBundleUploader = class {
14412
14776
  }, nextMs);
14413
14777
  }
14414
14778
  async findUploadCandidates() {
14415
- const traceDir = path15.join(this.options.machineDir, "traces");
14779
+ const traceDir = path16.join(this.options.machineDir, "traces");
14416
14780
  let names;
14417
14781
  try {
14418
14782
  names = await readdir3(traceDir);
@@ -14424,8 +14788,8 @@ var DaemonTraceBundleUploader = class {
14424
14788
  const currentFile = this.options.currentFileProvider?.();
14425
14789
  const candidates = [];
14426
14790
  for (const name of names.filter((entry) => entry.startsWith("daemon-trace-") && entry.endsWith(".jsonl")).sort()) {
14427
- const file = path15.join(traceDir, name);
14428
- if (currentFile && path15.resolve(file) === path15.resolve(currentFile)) continue;
14791
+ const file = path16.join(traceDir, name);
14792
+ if (currentFile && path16.resolve(file) === path16.resolve(currentFile)) continue;
14429
14793
  if (await this.isUploaded(file)) continue;
14430
14794
  try {
14431
14795
  const info = await stat3(file);
@@ -14457,7 +14821,7 @@ var DaemonTraceBundleUploader = class {
14457
14821
  }
14458
14822
  const gzipped = gzipSync(raw);
14459
14823
  const bundleSha256 = sha256Hex(gzipped);
14460
- const bundleId = randomUUID5();
14824
+ const bundleId = randomUUID6();
14461
14825
  await uploadWithSignedCapability({
14462
14826
  serverUrl: this.options.serverUrl,
14463
14827
  apiKey: this.options.apiKey,
@@ -14499,8 +14863,8 @@ var DaemonTraceBundleUploader = class {
14499
14863
  }
14500
14864
  }
14501
14865
  uploadStatePath(file) {
14502
- const stateDir = path15.join(this.options.machineDir, "trace-uploads");
14503
- return path15.join(stateDir, `${path15.basename(file)}.uploaded.json`);
14866
+ const stateDir = path16.join(this.options.machineDir, "trace-uploads");
14867
+ return path16.join(stateDir, `${path16.basename(file)}.uploaded.json`);
14504
14868
  }
14505
14869
  async isUploaded(file) {
14506
14870
  try {
@@ -14512,9 +14876,9 @@ var DaemonTraceBundleUploader = class {
14512
14876
  }
14513
14877
  async markUploaded(file, metadata) {
14514
14878
  const stateFile = this.uploadStatePath(file);
14515
- await mkdir2(path15.dirname(stateFile), { recursive: true, mode: 448 });
14879
+ await mkdir2(path16.dirname(stateFile), { recursive: true, mode: 448 });
14516
14880
  await writeFile2(stateFile, `${JSON.stringify({
14517
- file: path15.basename(file),
14881
+ file: path16.basename(file),
14518
14882
  uploadedAt: (/* @__PURE__ */ new Date()).toISOString(),
14519
14883
  ...metadata
14520
14884
  }, null, 2)}
@@ -14599,7 +14963,7 @@ var DAEMON_CORE_TRACE_ATTR_CONTRACTS = {
14599
14963
  spanAttrs: ["running_agents_count", "idle_agents_count"]
14600
14964
  }
14601
14965
  };
14602
- var DAEMON_CLI_USAGE = `Usage: slock-daemon --server-url <url> (--api-key <key> or ${DAEMON_API_KEY_ENV}=<key>)`;
14966
+ var DAEMON_CLI_USAGE = "Usage: slock-daemon --server-url <url> --api-key <key>";
14603
14967
  var RunnerCredentialMintError2 = class extends Error {
14604
14968
  code;
14605
14969
  retryable;
@@ -14635,9 +14999,9 @@ function runnerCredentialErrorDetail2(error) {
14635
14999
  async function waitForRunnerCredentialRetry2() {
14636
15000
  await new Promise((resolve) => setTimeout(resolve, RUNNER_CREDENTIAL_MINT_RETRY_DELAY_MS2));
14637
15001
  }
14638
- function parseDaemonCliArgs(args, env = {}) {
15002
+ function parseDaemonCliArgs(args) {
14639
15003
  let serverUrl = "";
14640
- let apiKey = env[DAEMON_API_KEY_ENV] ?? "";
15004
+ let apiKey = "";
14641
15005
  for (let i = 0; i < args.length; i++) {
14642
15006
  if (args[i] === "--server-url" && args[i + 1]) serverUrl = args[++i];
14643
15007
  if (args[i] === "--api-key" && args[i + 1]) apiKey = args[++i];
@@ -14647,20 +15011,20 @@ function parseDaemonCliArgs(args, env = {}) {
14647
15011
  }
14648
15012
  function readDaemonVersion(moduleUrl = import.meta.url) {
14649
15013
  try {
14650
- const require2 = createRequire2(moduleUrl);
15014
+ const require2 = createRequire3(moduleUrl);
14651
15015
  return require2("../package.json").version;
14652
15016
  } catch {
14653
15017
  return "0.0.0-dev";
14654
15018
  }
14655
15019
  }
14656
15020
  function resolveSlockCliPath(moduleUrl = import.meta.url) {
14657
- const thisDir = path16.dirname(fileURLToPath(moduleUrl));
14658
- const bundledDistPath = path16.resolve(thisDir, "cli", "index.js");
15021
+ const thisDir = path17.dirname(fileURLToPath(moduleUrl));
15022
+ const bundledDistPath = path17.resolve(thisDir, "cli", "index.js");
14659
15023
  try {
14660
15024
  accessSync(bundledDistPath);
14661
15025
  return bundledDistPath;
14662
15026
  } catch {
14663
- const workspaceDistPath = path16.resolve(thisDir, "..", "..", "cli", "dist", "index.js");
15027
+ const workspaceDistPath = path17.resolve(thisDir, "..", "..", "cli", "dist", "index.js");
14664
15028
  accessSync(workspaceDistPath);
14665
15029
  return workspaceDistPath;
14666
15030
  }
@@ -14674,7 +15038,7 @@ function resolveSlockCliPathOrEmpty(moduleUrl = import.meta.url) {
14674
15038
  }
14675
15039
  async function runBundledSlockCli(argv) {
14676
15040
  process.argv = [process.execPath, "slock", ...argv];
14677
- await import("./dist-GKTG7LRO.js");
15041
+ await import("./dist-6YUWBDWX.js");
14678
15042
  }
14679
15043
  function detectRuntimes(tracer = noopTracer) {
14680
15044
  const ids = [];
@@ -14866,7 +15230,7 @@ var DaemonCore = class {
14866
15230
  }
14867
15231
  resolveMachineStateRoot() {
14868
15232
  if (this.options.machineStateDir) return this.options.machineStateDir;
14869
- if (this.options.dataDir) return path16.join(path16.dirname(this.options.dataDir), "machines");
15233
+ if (this.options.dataDir) return path17.join(path17.dirname(this.options.dataDir), "machines");
14870
15234
  return resolveDefaultMachineStateRoot();
14871
15235
  }
14872
15236
  shouldEnableLocalTrace() {
@@ -14893,7 +15257,7 @@ var DaemonCore = class {
14893
15257
  sink: this.localTraceSink
14894
15258
  }));
14895
15259
  this.agentManager.setTracer(this.tracer);
14896
- this.agentManager.setCliTransportTraceDir(path16.join(machineDir, "traces"));
15260
+ this.agentManager.setCliTransportTraceDir(path17.join(machineDir, "traces"));
14897
15261
  }
14898
15262
  installTraceBundleUploader(machineDir) {
14899
15263
  if (!this.shouldEnableLocalTrace()) return;
@@ -15501,8 +15865,6 @@ var DaemonCore = class {
15501
15865
  };
15502
15866
 
15503
15867
  export {
15504
- DAEMON_API_KEY_ENV,
15505
- scrubDaemonAuthEnv,
15506
15868
  subscribeDaemonLogs,
15507
15869
  resolveWorkspaceDirectoryPath,
15508
15870
  scanWorkspaceDirectories,