svamp-cli 0.2.312 → 0.2.314

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.
Files changed (27) hide show
  1. package/dist/{adminCommands-CRQQhXsw.mjs → adminCommands-DCttALYO.mjs} +1 -1
  2. package/dist/{agentCommands-hLTce38n.mjs → agentCommands-BUsSOz5M.mjs} +5 -5
  3. package/dist/{auth-B2ZuhK_S.mjs → auth-D5yTcsy2.mjs} +1 -1
  4. package/dist/{cli-HI-J8Y7U.mjs → cli-ahWO_ULm.mjs} +207 -73
  5. package/dist/cli.mjs +2 -2
  6. package/dist/{commands-ND3vwGkQ.mjs → commands-BSHZGcCC.mjs} +8 -8
  7. package/dist/{commands-DGUgZoou.mjs → commands-CJmKY6Qo.mjs} +2 -2
  8. package/dist/{commands-D6BqvSLe.mjs → commands-Ce7MP6Ut.mjs} +2 -2
  9. package/dist/{commands-IPkpFWbi.mjs → commands-Cl-TIip1.mjs} +2 -2
  10. package/dist/{commands-12pIcOWK.mjs → commands-CuinsdU0.mjs} +1 -1
  11. package/dist/{commands-CmMh6R6S.mjs → commands-ZML4FIzg.mjs} +1 -1
  12. package/dist/{commands-DpfYt_SX.mjs → commands-bS4ErsEr.mjs} +2 -2
  13. package/dist/{commands-C2zQmf3Y.mjs → commands-r4QVEq12.mjs} +1 -1
  14. package/dist/{fleet-Cuv2uu1t.mjs → fleet-CSwFR8B0.mjs} +41 -2
  15. package/dist/{frpc-DbZDLphz.mjs → frpc-CpuE7d3Y.mjs} +1 -1
  16. package/dist/{headlessCli-DakQSPzS.mjs → headlessCli-Dg-awx4h.mjs} +2 -2
  17. package/dist/index.mjs +1 -1
  18. package/dist/{notifyCommands-DhRbelQA.mjs → notifyCommands-Dlm4RafU.mjs} +1 -1
  19. package/dist/{package-BKX7lisO.mjs → package-DO2e6EnU.mjs} +2 -2
  20. package/dist/{rpc-C7uDtxFw.mjs → rpc-BN7kFhGk.mjs} +1 -1
  21. package/dist/{rpc-Q4PWHeNn.mjs → rpc-CLTPF1K6.mjs} +1 -1
  22. package/dist/{run-DG0yDh6U.mjs → run-B6-6GYde.mjs} +1 -1
  23. package/dist/{run-Ccf8_4AF.mjs → run-Y3YLx8x7.mjs} +299 -18
  24. package/dist/{scheduler-B1xThM3A.mjs → scheduler-CWlkmpMz.mjs} +1 -1
  25. package/dist/{serveCommands-DDq9qzoN.mjs → serveCommands-mnocpHcO.mjs} +5 -5
  26. package/dist/{sideband-CDdpZAXO.mjs → sideband-c4lkIKWJ.mjs} +1 -1
  27. package/package.json +2 -2
@@ -3153,7 +3153,7 @@ Connection: close\r
3153
3153
  const mount = this.mounts.get(mountName);
3154
3154
  const subdomainOverride = mount?.access === "link" && mount.linkToken ? /* @__PURE__ */ new Map([[this.port, buildLinkSubdomain(subdomainSafe, mount.linkToken)]]) : void 0;
3155
3155
  try {
3156
- const { FrpcTunnel } = await import('./frpc-DbZDLphz.mjs');
3156
+ const { FrpcTunnel } = await import('./frpc-CpuE7d3Y.mjs');
3157
3157
  let tunnel;
3158
3158
  tunnel = new FrpcTunnel({
3159
3159
  name: tunnelName,
@@ -6286,7 +6286,7 @@ async function registerMachineService(server, machineId, metadata, daemonState,
6286
6286
  const tunnels = handlers.tunnels;
6287
6287
  if (!tunnels) throw new Error("Tunnel management not available");
6288
6288
  if (tunnels.has(params.name)) throw new Error(`Tunnel '${params.name}' already running`);
6289
- const { FrpcTunnel } = await import('./frpc-DbZDLphz.mjs');
6289
+ const { FrpcTunnel } = await import('./frpc-CpuE7d3Y.mjs');
6290
6290
  const tunnel = new FrpcTunnel({
6291
6291
  name: params.name,
6292
6292
  ports: params.ports,
@@ -6779,7 +6779,7 @@ QUESTION: ${params.question || "Summarize this concisely."}` }
6779
6779
  }
6780
6780
  const deps = buildSessionDeps(rpc, { cwd, ownerEmail: owner });
6781
6781
  const sender = { name: context?.user?.email || context?.user?.id || "user", kind: "user", verified: true };
6782
- const { toolsForRole } = await import('./sideband-CDdpZAXO.mjs');
6782
+ const { toolsForRole } = await import('./sideband-c4lkIKWJ.mjs');
6783
6783
  const r2 = await runWiseAgent({ message: params.message, sender, config: { tools: toolsForRole(role2) }, deps, transport, model: resolved.model });
6784
6784
  return fmt(r2);
6785
6785
  }
@@ -6884,7 +6884,7 @@ QUESTION: ${params.question || "Summarize this concisely."}` }
6884
6884
  return { ok: false, call_id: callId, status: "busy", error: "channel is busy (too many concurrent requests) \u2014 retry shortly" };
6885
6885
  }
6886
6886
  const rendered = renderMessage(c, { sender: r.sender, body: { message: kwargs.message }, callId });
6887
- const { queryCore } = await import('./commands-C2zQmf3Y.mjs');
6887
+ const { queryCore } = await import('./commands-r4QVEq12.mjs');
6888
6888
  const timeout = c.reply?.timeout_sec || 120;
6889
6889
  let result;
6890
6890
  try {
@@ -10094,7 +10094,7 @@ function handleClaudeMessage(ctx, msg) {
10094
10094
  }
10095
10095
  }
10096
10096
 
10097
- const KNOWN_AGENT_LAUNCHERS = ["claude", "codex", "gemini"];
10097
+ const KNOWN_AGENT_LAUNCHERS = ["claude", "codex", "gemini", "kimi"];
10098
10098
  function agentLauncherExists(cmd, env = process.env) {
10099
10099
  if (!cmd) return false;
10100
10100
  if (cmd.includes("/") || cmd.includes("\\")) return existsSync$1(cmd);
@@ -12157,7 +12157,8 @@ var acpBackend = /*#__PURE__*/Object.freeze({
12157
12157
  });
12158
12158
 
12159
12159
  const KNOWN_ACP_AGENTS = {
12160
- gemini: { command: "gemini", args: ["--experimental-acp"] }
12160
+ gemini: { command: "gemini", args: ["--experimental-acp"] },
12161
+ kimi: { command: "kimi", args: ["acp"] }
12161
12162
  };
12162
12163
  const KNOWN_CODEX_AGENTS = {
12163
12164
  codex: { command: "codex", args: ["app-server", "--listen", "stdio://"] }
@@ -13229,7 +13230,7 @@ const GEMINI_TOOL_PATTERNS = [
13229
13230
  inputFields: ["thought", "thinking"]
13230
13231
  }
13231
13232
  ];
13232
- const AVAILABLE_MODELS = [
13233
+ const AVAILABLE_MODELS$1 = [
13233
13234
  "gemini-2.5-pro",
13234
13235
  "gemini-2.5-flash",
13235
13236
  "gemini-2.5-flash-lite"
@@ -13261,7 +13262,7 @@ class GeminiTransport {
13261
13262
  const msg = {
13262
13263
  type: "status",
13263
13264
  status: "error",
13264
- detail: `Model not found. Available models: ${AVAILABLE_MODELS.join(", ")}`
13265
+ detail: `Model not found. Available models: ${AVAILABLE_MODELS$1.join(", ")}`
13265
13266
  };
13266
13267
  return { message: msg };
13267
13268
  }
@@ -13334,6 +13335,244 @@ var GeminiTransport$1 = /*#__PURE__*/Object.freeze({
13334
13335
  GeminiTransport: GeminiTransport
13335
13336
  });
13336
13337
 
13338
+ const KIMI_TIMEOUTS = {
13339
+ init: 12e4,
13340
+ toolCall: 12e4,
13341
+ investigation: 6e5,
13342
+ think: 3e4,
13343
+ idle: 500
13344
+ };
13345
+ const KIMI_TOOL_PATTERNS = [
13346
+ {
13347
+ name: "change_title",
13348
+ patterns: ["change_title", "change-title", "svamp__change_title", "mcp__svamp__change_title"],
13349
+ inputFields: ["title"],
13350
+ emptyInputDefault: true
13351
+ },
13352
+ {
13353
+ name: "set_session_link",
13354
+ patterns: ["set_session_link", "set-session-link", "svamp__set_session_link", "mcp__svamp__set_session_link"],
13355
+ inputFields: ["url"]
13356
+ },
13357
+ {
13358
+ name: "save_memory",
13359
+ patterns: ["save_memory", "save-memory"],
13360
+ inputFields: ["memory", "content"]
13361
+ },
13362
+ {
13363
+ name: "think",
13364
+ patterns: ["think"],
13365
+ inputFields: ["thought", "thinking"]
13366
+ }
13367
+ ];
13368
+ const AVAILABLE_MODELS = [
13369
+ "moonshotai/kimi-k2.5",
13370
+ "moonshotai/kimi-k3",
13371
+ "moonshotai/kimi-k2.7-code",
13372
+ "moonshotai/kimi-k2-thinking",
13373
+ "moonshotai/kimi-k2-turbo-preview",
13374
+ "kimi-for-coding/kimi-for-coding"
13375
+ ];
13376
+ class KimiTransport {
13377
+ agentName = "kimi";
13378
+ getInitTimeout() {
13379
+ return KIMI_TIMEOUTS.init;
13380
+ }
13381
+ filterStdoutLine(line) {
13382
+ const trimmed = line.trim();
13383
+ if (!trimmed) return null;
13384
+ if (!trimmed.startsWith("{") && !trimmed.startsWith("[")) return null;
13385
+ try {
13386
+ const parsed = JSON.parse(trimmed);
13387
+ if (typeof parsed !== "object" || parsed === null) return null;
13388
+ return line;
13389
+ } catch {
13390
+ return null;
13391
+ }
13392
+ }
13393
+ handleStderr(text, context) {
13394
+ const trimmed = text.trim();
13395
+ if (!trimmed) return { message: null, suppress: true };
13396
+ if (trimmed.includes("no provider configured") || trimmed.includes("Authentication required") || trimmed.includes("Invalid Authentication") || trimmed.includes("authentication_error") || trimmed.includes("401")) {
13397
+ const msg = {
13398
+ type: "status",
13399
+ status: "error",
13400
+ detail: "Kimi has no valid provider configured. Run `svamp daemon kimi-auth use-moonshot <api-key>` (or `use-coding` / `set`) on this machine, then restart the daemon."
13401
+ };
13402
+ return { message: msg };
13403
+ }
13404
+ if (trimmed.includes("status 429") || trimmed.includes('code":429') || trimmed.includes("429") || trimmed.includes("rate limit") || trimmed.includes("RESOURCE_EXHAUSTED")) {
13405
+ return { message: null, suppress: false };
13406
+ }
13407
+ if (trimmed.includes("status 404") || trimmed.includes('code":404') || trimmed.includes("model_not_found")) {
13408
+ const msg = {
13409
+ type: "status",
13410
+ status: "error",
13411
+ detail: `Model not found. Example Kimi models: ${AVAILABLE_MODELS.join(", ")}`
13412
+ };
13413
+ return { message: msg };
13414
+ }
13415
+ if (context.hasActiveInvestigation) {
13416
+ const hasError = trimmed.includes("timeout") || trimmed.includes("Timeout") || trimmed.includes("failed") || trimmed.includes("Failed") || trimmed.includes("error") || trimmed.includes("Error");
13417
+ if (hasError) {
13418
+ return { message: null, suppress: false };
13419
+ }
13420
+ }
13421
+ return { message: null };
13422
+ }
13423
+ getToolPatterns() {
13424
+ return KIMI_TOOL_PATTERNS;
13425
+ }
13426
+ isInvestigationTool(toolCallId, toolKind) {
13427
+ const lowerId = toolCallId.toLowerCase();
13428
+ return lowerId.includes("codebase_investigator") || lowerId.includes("investigator") || typeof toolKind === "string" && toolKind.includes("investigator");
13429
+ }
13430
+ getToolCallTimeout(toolCallId, toolKind) {
13431
+ if (this.isInvestigationTool(toolCallId, toolKind)) return KIMI_TIMEOUTS.investigation;
13432
+ if (toolKind === "think") return KIMI_TIMEOUTS.think;
13433
+ return KIMI_TIMEOUTS.toolCall;
13434
+ }
13435
+ getIdleTimeout() {
13436
+ return KIMI_TIMEOUTS.idle;
13437
+ }
13438
+ extractToolNameFromId(toolCallId) {
13439
+ const lowerId = toolCallId.toLowerCase();
13440
+ for (const toolPattern of KIMI_TOOL_PATTERNS) {
13441
+ for (const pattern of toolPattern.patterns) {
13442
+ if (lowerId.includes(pattern.toLowerCase())) {
13443
+ return toolPattern.name;
13444
+ }
13445
+ }
13446
+ }
13447
+ return null;
13448
+ }
13449
+ isEmptyInput(input) {
13450
+ if (!input) return true;
13451
+ if (Array.isArray(input)) return input.length === 0;
13452
+ if (typeof input === "object") return Object.keys(input).length === 0;
13453
+ return false;
13454
+ }
13455
+ determineToolName(toolName, toolCallId, input, _context) {
13456
+ if (toolName !== "other" && toolName !== "Unknown tool") return toolName;
13457
+ const idToolName = this.extractToolNameFromId(toolCallId);
13458
+ if (idToolName) return idToolName;
13459
+ if (input && typeof input === "object" && !Array.isArray(input)) {
13460
+ const inputKeys = Object.keys(input);
13461
+ for (const toolPattern of KIMI_TOOL_PATTERNS) {
13462
+ if (toolPattern.inputFields) {
13463
+ const hasMatchingField = toolPattern.inputFields.some(
13464
+ (field) => inputKeys.some((key) => key.toLowerCase() === field.toLowerCase())
13465
+ );
13466
+ if (hasMatchingField) return toolPattern.name;
13467
+ }
13468
+ }
13469
+ }
13470
+ if (this.isEmptyInput(input) && toolName === "other") {
13471
+ const defaultTool = KIMI_TOOL_PATTERNS.find((p) => p.emptyInputDefault);
13472
+ if (defaultTool) return defaultTool.name;
13473
+ }
13474
+ return toolName;
13475
+ }
13476
+ }
13477
+
13478
+ var KimiTransport$1 = /*#__PURE__*/Object.freeze({
13479
+ __proto__: null,
13480
+ KIMI_TIMEOUTS: KIMI_TIMEOUTS,
13481
+ KimiTransport: KimiTransport
13482
+ });
13483
+
13484
+ const DEFAULT_KIMI_PROVIDER = "moonshotai";
13485
+ const DEFAULT_KIMI_MODEL_BY_PROVIDER = {
13486
+ moonshotai: "kimi-k2.5",
13487
+ "moonshotai-cn": "kimi-k2-turbo-preview",
13488
+ "kimi-for-coding": "kimi-for-coding"
13489
+ };
13490
+ function kimiDefaultModelId(cfg) {
13491
+ if (cfg.model) {
13492
+ const m = cfg.model.trim();
13493
+ return m.includes("/") ? m.split("/").pop() || void 0 : m;
13494
+ }
13495
+ return DEFAULT_KIMI_MODEL_BY_PROVIDER[cfg.provider];
13496
+ }
13497
+ function kimiSpawnEnv(_env = process.env) {
13498
+ return { KIMI_CLI_NO_AUTO_UPDATE: "1" };
13499
+ }
13500
+ function resolveKimiProvider(env = process.env) {
13501
+ return {
13502
+ provider: env.SVAMP_KIMI_PROVIDER || DEFAULT_KIMI_PROVIDER,
13503
+ apiKey: env.SVAMP_KIMI_API_KEY || env.LLM_API_KEY || void 0,
13504
+ apiBase: env.SVAMP_KIMI_API_BASE || env.LLM_API_BASE || void 0,
13505
+ model: env.SVAMP_KIMI_MODEL || env.LLM_MODEL || void 0
13506
+ };
13507
+ }
13508
+ function hasKimiProvider(cfg) {
13509
+ return !!cfg.apiKey;
13510
+ }
13511
+ function buildKimiCatalogAddArgs(cfg) {
13512
+ if (!hasKimiProvider(cfg)) return null;
13513
+ const args = ["provider", "catalog", "add", cfg.provider, "--api-key", cfg.apiKey];
13514
+ if (cfg.apiBase) args.push("--base-url", cfg.apiBase);
13515
+ const defaultModel = kimiDefaultModelId(cfg);
13516
+ if (defaultModel) args.push("--default-model", defaultModel);
13517
+ return args;
13518
+ }
13519
+ function kimiProviderConfigured(configTomlText, provider) {
13520
+ if (!configTomlText) return false;
13521
+ const header = `[providers.${provider}]`;
13522
+ const idx = configTomlText.indexOf(header);
13523
+ if (idx < 0) return false;
13524
+ const rest = configTomlText.slice(idx + header.length);
13525
+ const nextTable = rest.search(/\n\s*\[/);
13526
+ const block = nextTable < 0 ? rest : rest.slice(0, nextTable);
13527
+ return /(^|\n)\s*api_key\s*=/.test(block);
13528
+ }
13529
+
13530
+ var kimiProvider = /*#__PURE__*/Object.freeze({
13531
+ __proto__: null,
13532
+ DEFAULT_KIMI_MODEL_BY_PROVIDER: DEFAULT_KIMI_MODEL_BY_PROVIDER,
13533
+ DEFAULT_KIMI_PROVIDER: DEFAULT_KIMI_PROVIDER,
13534
+ buildKimiCatalogAddArgs: buildKimiCatalogAddArgs,
13535
+ hasKimiProvider: hasKimiProvider,
13536
+ kimiDefaultModelId: kimiDefaultModelId,
13537
+ kimiProviderConfigured: kimiProviderConfigured,
13538
+ kimiSpawnEnv: kimiSpawnEnv,
13539
+ resolveKimiProvider: resolveKimiProvider
13540
+ });
13541
+
13542
+ const KIMI_CONFIG_PATH = join$1(homedir$1(), ".kimi-code", "config.toml");
13543
+ function readKimiConfig() {
13544
+ try {
13545
+ return readFileSync(KIMI_CONFIG_PATH, "utf8");
13546
+ } catch {
13547
+ return null;
13548
+ }
13549
+ }
13550
+ function ensureKimiProviderConfigured(env = process.env, command = "kimi", log = () => {
13551
+ }) {
13552
+ const cfg = resolveKimiProvider(env);
13553
+ if (!hasKimiProvider(cfg)) return false;
13554
+ if (kimiProviderConfigured(readKimiConfig(), cfg.provider)) return true;
13555
+ const args = buildKimiCatalogAddArgs(cfg);
13556
+ if (!args) return false;
13557
+ try {
13558
+ execFileSync(command, args, {
13559
+ stdio: "ignore",
13560
+ timeout: 3e4,
13561
+ env: { ...process.env, KIMI_CLI_NO_AUTO_UPDATE: "1" }
13562
+ });
13563
+ log(`[kimi] configured provider '${cfg.provider}' in ${KIMI_CONFIG_PATH}`);
13564
+ return kimiProviderConfigured(readKimiConfig(), cfg.provider);
13565
+ } catch (err) {
13566
+ log(`[kimi] provider auto-config failed (${err?.message || err}); session may need kimi-auth`);
13567
+ return false;
13568
+ }
13569
+ }
13570
+
13571
+ var kimiSetup = /*#__PURE__*/Object.freeze({
13572
+ __proto__: null,
13573
+ ensureKimiProviderConfigured: ensureKimiProviderConfigured
13574
+ });
13575
+
13337
13576
  function resolveTranscriptPath(cwd, claudeSessionId) {
13338
13577
  let real;
13339
13578
  try {
@@ -15643,6 +15882,12 @@ function resolveLoopDurable(cfg) {
15643
15882
  if (typeof cfg.durable === "boolean") return cfg.durable;
15644
15883
  return isBacklogDrainerOracle(cfg.oracle);
15645
15884
  }
15885
+ function shouldRearmDormantLoop(s, pendingCount, sessionId) {
15886
+ if (!s || s.phase !== "dormant") return false;
15887
+ if (typeof s.session_id === "string" && sessionId && s.session_id !== sessionId) return false;
15888
+ if (!isBacklogDrainerOracle(typeof s.oracle === "string" ? s.oracle : void 0)) return false;
15889
+ return pendingCount > 0;
15890
+ }
15646
15891
  function issuesClosedSince(projectRoot, sinceMs) {
15647
15892
  const all = listIssues(projectRoot, { includeArchived: true, status: "archived" });
15648
15893
  if (!sinceMs || !Number.isFinite(sinceMs)) return all;
@@ -17964,7 +18209,7 @@ async function startDaemon(options) {
17964
18209
  try {
17965
18210
  const dir = loadSessionIndex()[sessionId]?.directory;
17966
18211
  if (!dir) return;
17967
- const { reconcileServiceLinks } = await import('./agentCommands-hLTce38n.mjs');
18212
+ const { reconcileServiceLinks } = await import('./agentCommands-BUsSOz5M.mjs');
17968
18213
  const configPath = getSvampConfigPath(dir, sessionId);
17969
18214
  const config = readSvampConfig(configPath);
17970
18215
  const entries = Array.from(urls.entries());
@@ -17982,7 +18227,7 @@ async function startDaemon(options) {
17982
18227
  }
17983
18228
  }
17984
18229
  async function createExposedTunnel(spec) {
17985
- const { FrpcTunnel } = await import('./frpc-DbZDLphz.mjs');
18230
+ const { FrpcTunnel } = await import('./frpc-CpuE7d3Y.mjs');
17986
18231
  const tunnel = new FrpcTunnel({
17987
18232
  name: spec.name,
17988
18233
  ports: spec.ports,
@@ -20327,11 +20572,11 @@ ${capturedError}${buildClaudeErrorHint(capturedError)}`;
20327
20572
  });
20328
20573
  },
20329
20574
  onIssue: async (params) => {
20330
- const { issueRpc } = await import('./rpc-Q4PWHeNn.mjs');
20575
+ const { issueRpc } = await import('./rpc-CLTPF1K6.mjs');
20331
20576
  return issueRpc(params?.cwd || directory, params || {}, { notifySession: notifyIssueOwner, rekickLoopOwner });
20332
20577
  },
20333
20578
  onWorkflow: async (params) => {
20334
- const { workflowRpc } = await import('./rpc-C7uDtxFw.mjs');
20579
+ const { workflowRpc } = await import('./rpc-BN7kFhGk.mjs');
20335
20580
  return workflowRpc(params?.cwd || directory, params || {});
20336
20581
  },
20337
20582
  onRipgrep: async (args, cwd) => {
@@ -20608,6 +20853,34 @@ ${capturedError}${buildClaudeErrorHint(capturedError)}`;
20608
20853
  if (INBOX_RECONCILE_INTERVAL_MS > 0) {
20609
20854
  inboxReconcileTimer = setInterval(reconcileIdleInbox, INBOX_RECONCILE_INTERVAL_MS);
20610
20855
  }
20856
+ const dormantSweepMs = Number(process.env.SVAMP_LOOP_DORMANT_SWEEP_MS);
20857
+ const DORMANT_SWEEP_INTERVAL_MS = Number.isFinite(dormantSweepMs) && dormantSweepMs >= 0 ? dormantSweepMs : 2e4;
20858
+ let dormantRearmTimer = null;
20859
+ const sweepDormantRearm = () => {
20860
+ if (trackedSession.stopped) {
20861
+ if (dormantRearmTimer) clearInterval(dormantRearmTimer);
20862
+ return;
20863
+ }
20864
+ let s = null;
20865
+ try {
20866
+ s = readLoopState(directory, sessionId);
20867
+ } catch {
20868
+ return;
20869
+ }
20870
+ if (!s || s.phase !== "dormant") return;
20871
+ let pending = [];
20872
+ try {
20873
+ pending = backlogOraclePending(directory, sessionId);
20874
+ } catch {
20875
+ return;
20876
+ }
20877
+ if (!shouldRearmDormantLoop(s, pending.length, sessionId)) return;
20878
+ logger.log(`[Session ${sessionId}] Dormant re-arm sweep: ${pending.length} pending issue(s) on disk (added outside the daemon RPC) \u2014 re-arming loop`);
20879
+ trackedSession.rekickLoop?.();
20880
+ };
20881
+ if (DORMANT_SWEEP_INTERVAL_MS > 0) {
20882
+ dormantRearmTimer = setInterval(sweepDormantRearm, DORMANT_SWEEP_INTERVAL_MS);
20883
+ }
20611
20884
  return {
20612
20885
  type: "success",
20613
20886
  sessionId,
@@ -21007,11 +21280,11 @@ ${capturedError}${buildClaudeErrorHint(capturedError)}`;
21007
21280
  });
21008
21281
  },
21009
21282
  onIssue: async (params) => {
21010
- const { issueRpc } = await import('./rpc-Q4PWHeNn.mjs');
21283
+ const { issueRpc } = await import('./rpc-CLTPF1K6.mjs');
21011
21284
  return issueRpc(params?.cwd || directory, params || {}, { notifySession: notifyIssueOwner, rekickLoopOwner });
21012
21285
  },
21013
21286
  onWorkflow: async (params) => {
21014
- const { workflowRpc } = await import('./rpc-C7uDtxFw.mjs');
21287
+ const { workflowRpc } = await import('./rpc-BN7kFhGk.mjs');
21015
21288
  return workflowRpc(params?.cwd || directory, params || {});
21016
21289
  },
21017
21290
  onRipgrep: async (args, cwd) => {
@@ -21243,8 +21516,16 @@ ${capturedError}${buildClaudeErrorHint(capturedError)}`;
21243
21516
  resumeThreadId: acpResumeThreadId
21244
21517
  });
21245
21518
  } else {
21246
- const transportHandler = agentName === "gemini" ? new GeminiTransport() : new DefaultTransport(agentName);
21519
+ const transportHandler = agentName === "gemini" ? new GeminiTransport() : agentName === "kimi" ? new KimiTransport() : new DefaultTransport(agentName);
21247
21520
  const acpConfig = KNOWN_ACP_AGENTS[agentName];
21521
+ let kimiEnv = {};
21522
+ if (agentName === "kimi") {
21523
+ try {
21524
+ ensureKimiProviderConfigured(process.env, acpConfig.command, logger.log);
21525
+ } catch {
21526
+ }
21527
+ kimiEnv = kimiSpawnEnv(process.env);
21528
+ }
21248
21529
  agentBackend = new AcpBackend({
21249
21530
  agentName,
21250
21531
  cwd: directory,
@@ -21252,7 +21533,7 @@ ${capturedError}${buildClaudeErrorHint(capturedError)}`;
21252
21533
  args: acpConfig.args,
21253
21534
  // #0599: session identity (SVAMP_SESSION_ID/HANDLE/MACHINE_ID) so ACP terminal
21254
21535
  // tools self-identify like Claude's do; applied last (identity wins).
21255
- env: { ...options2.environmentVariables || {}, ...sessionIdentityEnv },
21536
+ env: { ...options2.environmentVariables || {}, ...kimiEnv, ...sessionIdentityEnv },
21256
21537
  permissionHandler,
21257
21538
  transportHandler,
21258
21539
  log: logger.log,
@@ -22249,7 +22530,7 @@ ${oracle.output.trim().slice(0, 500)}`, "\u{1F501} Continuing loop");
22249
22530
  const PING_TIMEOUT_MS = 15e3;
22250
22531
  const POST_RECONNECT_GRACE_MS = 2e4;
22251
22532
  const RECONNECT_JITTER_MS = 2500;
22252
- const { WorkflowScheduler } = await import('./scheduler-B1xThM3A.mjs');
22533
+ const { WorkflowScheduler } = await import('./scheduler-CWlkmpMz.mjs');
22253
22534
  const workflowProjectRoots = () => {
22254
22535
  const dirs = /* @__PURE__ */ new Set();
22255
22536
  for (const s of pidToTrackedSession.values()) {
@@ -22883,4 +23164,4 @@ var run = /*#__PURE__*/Object.freeze({
22883
23164
  writeStopMarker: writeStopMarker
22884
23165
  });
22885
23166
 
22886
- export { SKILLS_DIR as $, removeWorkflow as A, validateWorkflowName as B, saveWorkflow as C, rawWorkflow as D, listWorkflows as E, isWorkflowEnabled as F, workflowSchedules as G, inZone as H, cronMatches as I, summarize as J, workflowSteps as K, parseJwtEmail as L, computeCollectionConfigUpdate as M, SYSTEM_COLLECTION_CONFIG as N, loadMachineContext as O, buildMachineInstructions as P, machineToolsForRole as Q, READ_ONLY_TOOLS as R, SharingNotificationSync as S, buildMachineTools as T, PINNED_CODEX_VERSION as U, parseFrontmatter as V, getSkillsServer as W, getSkillsWorkspaceName as X, getSkillsCollectionName as Y, fetchWithTimeout as Z, searchSkills as _, createSessionStore as a, getSkillInfo as a0, downloadSkillFile as a1, listSkillFiles as a2, resolveModel as a3, clearStopMarker as a4, stopMarkerExists as a5, formatHandle as a6, normalizeAllowedUser as a7, loadSecurityContextConfig as a8, resolveSecurityContext as a9, run as aA, buildSecurityContextFromFlags as aa, mergeSecurityContexts as ab, buildSessionShareUrl as ac, computeOutboundHop as ad, registerAwaitingReply as ae, buildMachineShareUrl as af, parseHandle as ag, handleMatchesMetadata as ah, withFileLock as ai, describeMisconfiguration as aj, buildMachineDeps as ak, applyClaudeProxyEnv as al, composeSessionId as am, generateFriendlyName as an, generateHookSettings as ao, staticFileServer as ap, instanceConfig as aq, claudeAuth as ar, codexProvider as as, projectInfo as at, DefaultTransport$1 as au, acpBackend as av, acpAgentConfig as aw, codexAppServerBackend as ax, GeminiTransport$1 as ay, api as az, stopDaemon as b, connectToHypha as c, daemonStatus as d, getFrpsSubdomainHost as e, getFrpsServerPort as f, getHyphaServerUrl$1 as g, getFrpsServerAddr as h, shortId as i, resolveProjectRoot as j, getIssue as k, resumeIssue as l, addComment as m, addIssue as n, listIssues as o, pauseIssue as p, searchIssues as q, registerMachineService as r, startDaemon as s, isVisibleTo as t, updateIssue as u, getRun as v, listRuns as w, getWorkflow as x, runWorkflow as y, setWorkflowEnabled as z };
23167
+ export { getSkillInfo as $, removeWorkflow as A, validateWorkflowName as B, saveWorkflow as C, rawWorkflow as D, listWorkflows as E, isWorkflowEnabled as F, workflowSchedules as G, inZone as H, cronMatches as I, summarize as J, workflowSteps as K, parseJwtEmail as L, computeCollectionConfigUpdate as M, SYSTEM_COLLECTION_CONFIG as N, loadMachineContext as O, buildMachineInstructions as P, machineToolsForRole as Q, READ_ONLY_TOOLS as R, SharingNotificationSync as S, buildMachineTools as T, parseFrontmatter as U, getSkillsServer as V, getSkillsWorkspaceName as W, getSkillsCollectionName as X, fetchWithTimeout as Y, searchSkills as Z, SKILLS_DIR as _, createSessionStore as a, downloadSkillFile as a0, listSkillFiles as a1, resolveModel as a2, clearStopMarker as a3, stopMarkerExists as a4, formatHandle as a5, normalizeAllowedUser as a6, loadSecurityContextConfig as a7, resolveSecurityContext as a8, buildSecurityContextFromFlags as a9, kimiProvider as aA, kimiSetup as aB, api as aC, run as aD, mergeSecurityContexts as aa, buildSessionShareUrl as ab, computeOutboundHop as ac, registerAwaitingReply as ad, buildMachineShareUrl as ae, parseHandle as af, handleMatchesMetadata as ag, PINNED_CODEX_VERSION as ah, withFileLock as ai, describeMisconfiguration as aj, buildMachineDeps as ak, applyClaudeProxyEnv as al, composeSessionId as am, generateFriendlyName as an, generateHookSettings as ao, staticFileServer as ap, instanceConfig as aq, claudeAuth as ar, codexProvider as as, projectInfo as at, DefaultTransport$1 as au, acpBackend as av, acpAgentConfig as aw, codexAppServerBackend as ax, GeminiTransport$1 as ay, KimiTransport$1 as az, stopDaemon as b, connectToHypha as c, daemonStatus as d, getFrpsSubdomainHost as e, getFrpsServerPort as f, getHyphaServerUrl$1 as g, getFrpsServerAddr as h, shortId as i, resolveProjectRoot as j, getIssue as k, resumeIssue as l, addComment as m, addIssue as n, listIssues as o, pauseIssue as p, searchIssues as q, registerMachineService as r, startDaemon as s, isVisibleTo as t, updateIssue as u, getRun as v, listRuns as w, getWorkflow as x, runWorkflow as y, setWorkflowEnabled as z };
@@ -1,4 +1,4 @@
1
- import { j as resolveProjectRoot, E as listWorkflows, F as isWorkflowEnabled, G as workflowSchedules, H as inZone, y as runWorkflow, I as cronMatches } from './run-Ccf8_4AF.mjs';
1
+ import { j as resolveProjectRoot, E as listWorkflows, F as isWorkflowEnabled, G as workflowSchedules, H as inZone, y as runWorkflow, I as cronMatches } from './run-Y3YLx8x7.mjs';
2
2
  import 'os';
3
3
  import 'fs/promises';
4
4
  import 'fs';
@@ -54,7 +54,7 @@ async function handleServeCommand() {
54
54
  }
55
55
  }
56
56
  async function serveAdd(args, machineId) {
57
- const { connectAndGetMachine } = await import('./commands-C2zQmf3Y.mjs');
57
+ const { connectAndGetMachine } = await import('./commands-r4QVEq12.mjs');
58
58
  const pos = positionalArgs(args);
59
59
  const name = pos[0];
60
60
  if (!name) {
@@ -93,7 +93,7 @@ async function serveAdd(args, machineId) {
93
93
  }
94
94
  }
95
95
  async function serveApply(args, machineId) {
96
- const { connectAndGetMachine } = await import('./commands-C2zQmf3Y.mjs');
96
+ const { connectAndGetMachine } = await import('./commands-r4QVEq12.mjs');
97
97
  const fs = await import('fs');
98
98
  const yaml = await import('yaml');
99
99
  const file = positionalArgs(args)[0];
@@ -182,7 +182,7 @@ async function serveApply(args, machineId) {
182
182
  }
183
183
  }
184
184
  async function serveRemove(args, machineId) {
185
- const { connectAndGetMachine } = await import('./commands-C2zQmf3Y.mjs');
185
+ const { connectAndGetMachine } = await import('./commands-r4QVEq12.mjs');
186
186
  const pos = positionalArgs(args);
187
187
  const name = pos[0];
188
188
  if (!name) {
@@ -202,7 +202,7 @@ async function serveRemove(args, machineId) {
202
202
  }
203
203
  }
204
204
  async function serveList(args, machineId) {
205
- const { connectAndGetMachine } = await import('./commands-C2zQmf3Y.mjs');
205
+ const { connectAndGetMachine } = await import('./commands-r4QVEq12.mjs');
206
206
  const all = hasFlag(args, "--all", "-a");
207
207
  const json = hasFlag(args, "--json");
208
208
  const sessionId = getFlag(args, "--session");
@@ -236,7 +236,7 @@ async function serveList(args, machineId) {
236
236
  }
237
237
  }
238
238
  async function serveInfo(machineId) {
239
- const { connectAndGetMachine } = await import('./commands-C2zQmf3Y.mjs');
239
+ const { connectAndGetMachine } = await import('./commands-r4QVEq12.mjs');
240
240
  const { machine, server } = await connectAndGetMachine(machineId);
241
241
  try {
242
242
  const info = await machine.serveInfo();
@@ -1,4 +1,4 @@
1
- import { R as READ_ONLY_TOOLS, O as loadMachineContext, P as buildMachineInstructions, Q as machineToolsForRole, T as buildMachineTools } from './run-Ccf8_4AF.mjs';
1
+ import { R as READ_ONLY_TOOLS, O as loadMachineContext, P as buildMachineInstructions, Q as machineToolsForRole, T as buildMachineTools } from './run-Y3YLx8x7.mjs';
2
2
  import 'node:child_process';
3
3
  import 'os';
4
4
  import 'fs/promises';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svamp-cli",
3
- "version": "0.2.312",
3
+ "version": "0.2.314",
4
4
  "description": "Svamp CLI — AI workspace daemon on Hypha Cloud",
5
5
  "author": "Amun AI AB",
6
6
  "license": "SEE LICENSE IN LICENSE",
@@ -20,7 +20,7 @@
20
20
  "scripts": {
21
21
  "build": "rm -rf dist bin/skills bin/commands && mkdir -p bin/skills && cp -r ../../skills/artifact bin/skills/artifact && cp -r ../../skills/crew bin/skills/crew && cp -r ../../commands bin/commands && tsc --noEmit && pkgroll",
22
22
  "typecheck": "tsc --noEmit",
23
- "test": "npx tsx test/test-context-window.mjs && npx tsx test/test-ratelimit-retry.mjs && npx tsx test/test-instance-config.mjs && npx tsx test/test-authorize.mjs && npx tsx test/test-normalize-allowed-user.mjs && npx tsx test/test-share-url.mjs && npx tsx test/test-update-sharing-normalization.mjs && npx tsx test/test-sharing-notify-sync.mjs && npx tsx test/test-sharing-notify-resolve.mjs && npx tsx test/test-staged-homes-sweep.mjs && npx tsx test/test-session-helpers.mjs && npx tsx test/test-cli-routing.mjs && npx tsx test/test-security-context.mjs && npx tsx test/test-isolation-decision.mjs && npx tsx test/test-message-helpers.mjs && npx tsx test/test-stdin-delivery.mjs && npx tsx test/test-agent-config.mjs && npx tsx test/test-wrap-command.mjs && npx tsx test/test-credential-staging.mjs && npx tsx test/test-claude-auth.mjs && npx tsx test/test-backend-accounts.mjs && npx tsx test/test-codex-force-model.mjs && npx tsx test/test-backend-oauth.mjs && npx tsx test/test-btw-proxy-env.mjs && npx tsx test/test-output-formatters.mjs && npx tsx test/test-inbox-guard.mjs && npx tsx test/test-user-events.mjs && npx tsx test/test-migrate-children.mjs && npx tsx test/test-outpost-install.mjs && npx tsx test/test-outpost-setup.mjs && npx tsx test/test-outpost-pairing.mjs && npx tsx test/test-outpost-coordinator.mjs && npx tsx test/e2e-outpost-transport.mjs && npx tsx test/test-inbox-reconcile.mjs && npx tsx test/test-auto-topic.mjs && npx tsx test/test-project-info.mjs && npx tsx test/test-agent-types.mjs && npx tsx test/test-transport.mjs && npx tsx test/test-session-update-handlers.mjs && npx tsx test/test-session-scanner.mjs && npx tsx test/test-hypha-client.mjs && npx tsx test/test-hook-settings.mjs && npx tsx test/test-session-service-logic.mjs && npx tsx test/test-daemon-persistence.mjs && npx tsx test/test-detect-isolation.mjs && npx tsx test/test-isolation-disable.mjs && npx tsx test/test-machine-service-logic.mjs && npx tsx test/test-machine-session-visibility.mjs && npx tsx test/test-session-access-fallback.mjs && npx tsx test/test-session-rpc-role-map.mjs && npx tsx test/test-interactive-helpers.mjs && npx tsx test/test-pinned-codex.mjs && npx tsx test/test-codex-request-timeout.mjs && npx tsx test/test-codex-app-server.mjs && npx tsx test/e2e-codex-midturn-steer.mjs && npx tsx test/test-acp-backend.mjs && npx tsx test/test-acp-bridge.mjs && npx tsx test/test-listener-backoff.mjs && npx tsx test/test-session-identity-env.mjs && npx tsx test/test-hook-server.mjs && npx tsx test/test-session-commands.mjs && npx tsx test/test-interactive-console.mjs && npx tsx test/test-session-messages.mjs && npx tsx test/test-session-send-query.mjs && npx tsx test/test-skills.mjs && npx tsx test/test-agent-grouping.mjs && npx tsx test/test-machine-list-directory.mjs && npx tsx test/test-service-commands.mjs && npx tsx test/test-supervisor.mjs && npx tsx test/test-supervisor-lock.mjs && node test/test-supervisor-restart.mjs && npx tsx test/test-clear-detection.mjs && npx tsx test/test-compact-detect.mjs && npx tsx test/test-session-consolidation.mjs && npx tsx test/test-inbox-store.mjs && npx tsx test/test-inbox.mjs && npx tsx test/test-inbox-cross-machine.mjs && npx tsx test/test-issue-store.mjs && npx tsx test/test-issue-store-lock.mjs && npx tsx test/test-issue-close-gate.mjs && npx tsx test/test-loop-verify.mjs && npx tsx test/test-restore-decision.mjs && npx tsx test/test-issue-rpc.mjs && npx tsx test/test-issue-pause.mjs && npx tsx test/test-workflow-store.mjs && npx tsx test/test-workflow-rpc.mjs && npx tsx test/test-workflow-scheduler.mjs && npx tsx test/test-cron.mjs && npx tsx test/test-workflow-runs.mjs && npx tsx test/test-workflow-runs-lock.mjs && npx tsx test/test-workflow-idle.mjs && npx tsx test/test-workflow-reconcile.mjs && npx tsx test/test-serve-link-subdomain.mjs && npx tsx test/test-short-id.mjs && npx tsx test/test-transcript-edit.mjs && npx tsx test/test-edit-history.mjs && npx tsx test/test-friendly-name.mjs && npx tsx test/test-session-rpc-dispatch.mjs && npx tsx test/test-sandbox-cli.mjs && npx tsx test/test-serve-manager.mjs && npx tsx test/test-serve-ws-upgrade.mjs && npx tsx test/test-serve-auth.mjs && npx tsx test/test-static-file-server.mjs && npx tsx test/test-serve-stability.mjs && npx tsx test/test-frpc-e2e.mjs --unit-only && npx tsx test/test-frpc-status.mjs && node test/pinnedClaudeCode.test.mjs && node test/fleet.test.mjs && npx tsx test/test-session-file.mjs && npx tsx test/test-channel-rpc.mjs && npx tsx test/test-wise-agent.mjs && npx tsx test/test-channel-agent.mjs && npx tsx test/test-channels-service.mjs && npx tsx test/test-hotreload-seam.mjs && npx tsx test/test-hot-reload.mjs && npx tsx test/test-hot-reload-live.mjs && npx tsx test/test-session-core.mjs && npx tsx test/test-channel-async-reply.mjs && npx tsx test/test-outbox-reload.mjs && npx tsx test/test-channel-binding.mjs && npx tsx test/test-channel-store-lock.mjs && npx tsx test/test-channel-identity.mjs && npx tsx test/test-stateless-dispatch-limiter.mjs && npx tsx test/test-shared-session-identity.mjs && npx tsx test/test-wise-agent-auth.mjs && npx tsx test/test-channel-http.mjs && npx tsx test/test-channel-upload.mjs && npx tsx test/test-wise-voice.mjs && npx tsx test/test-wise-headless.mjs && npx tsx test/test-wise-machine.mjs && npx tsx test/test-crew-merge.mjs && npx tsx test/test-crew-verdict-routing.mjs && npx tsx test/test-crew-standalone.mjs && npx tsx test/test-session-links.mjs && npx tsx test/test-issue-loop-pause-guard.mjs && npx tsx test/test-artifact-guard.mjs && npx tsx test/test-artifact-sync-pagination.mjs && npx tsx test/test-graceful-restart.mjs && npx tsx test/test-flush-exit.mjs && npx tsx test/test-codex-skills.mjs",
23
+ "test": "npx tsx test/test-context-window.mjs && npx tsx test/test-ratelimit-retry.mjs && npx tsx test/test-instance-config.mjs && npx tsx test/test-authorize.mjs && npx tsx test/test-normalize-allowed-user.mjs && npx tsx test/test-share-url.mjs && npx tsx test/test-update-sharing-normalization.mjs && npx tsx test/test-sharing-notify-sync.mjs && npx tsx test/test-sharing-notify-resolve.mjs && npx tsx test/test-staged-homes-sweep.mjs && npx tsx test/test-session-helpers.mjs && npx tsx test/test-cli-routing.mjs && npx tsx test/test-security-context.mjs && npx tsx test/test-isolation-decision.mjs && npx tsx test/test-message-helpers.mjs && npx tsx test/test-stdin-delivery.mjs && npx tsx test/test-agent-config.mjs && npx tsx test/test-wrap-command.mjs && npx tsx test/test-credential-staging.mjs && npx tsx test/test-claude-auth.mjs && npx tsx test/test-backend-accounts.mjs && npx tsx test/test-codex-force-model.mjs && npx tsx test/test-backend-oauth.mjs && npx tsx test/test-btw-proxy-env.mjs && npx tsx test/test-output-formatters.mjs && npx tsx test/test-inbox-guard.mjs && npx tsx test/test-user-events.mjs && npx tsx test/test-migrate-children.mjs && npx tsx test/test-outpost-install.mjs && npx tsx test/test-outpost-setup.mjs && npx tsx test/test-outpost-pairing.mjs && npx tsx test/test-outpost-coordinator.mjs && npx tsx test/e2e-outpost-transport.mjs && npx tsx test/test-inbox-reconcile.mjs && npx tsx test/test-auto-topic.mjs && npx tsx test/test-project-info.mjs && npx tsx test/test-agent-types.mjs && npx tsx test/test-transport.mjs && npx tsx test/test-session-update-handlers.mjs && npx tsx test/test-session-scanner.mjs && npx tsx test/test-hypha-client.mjs && npx tsx test/test-hook-settings.mjs && npx tsx test/test-session-service-logic.mjs && npx tsx test/test-daemon-persistence.mjs && npx tsx test/test-detect-isolation.mjs && npx tsx test/test-isolation-disable.mjs && npx tsx test/test-machine-service-logic.mjs && npx tsx test/test-machine-session-visibility.mjs && npx tsx test/test-session-access-fallback.mjs && npx tsx test/test-session-rpc-role-map.mjs && npx tsx test/test-interactive-helpers.mjs && npx tsx test/test-pinned-codex.mjs && npx tsx test/test-codex-request-timeout.mjs && npx tsx test/test-codex-app-server.mjs && npx tsx test/e2e-codex-midturn-steer.mjs && npx tsx test/test-kimi-provider.mjs && npx tsx test/test-acp-backend.mjs && npx tsx test/test-acp-bridge.mjs && npx tsx test/test-listener-backoff.mjs && npx tsx test/test-session-identity-env.mjs && npx tsx test/test-hook-server.mjs && npx tsx test/test-session-commands.mjs && npx tsx test/test-interactive-console.mjs && npx tsx test/test-session-messages.mjs && npx tsx test/test-session-send-query.mjs && npx tsx test/test-skills.mjs && npx tsx test/test-agent-grouping.mjs && npx tsx test/test-machine-list-directory.mjs && npx tsx test/test-service-commands.mjs && npx tsx test/test-supervisor.mjs && npx tsx test/test-supervisor-lock.mjs && node test/test-supervisor-restart.mjs && npx tsx test/test-clear-detection.mjs && npx tsx test/test-compact-detect.mjs && npx tsx test/test-session-consolidation.mjs && npx tsx test/test-inbox-store.mjs && npx tsx test/test-inbox.mjs && npx tsx test/test-inbox-cross-machine.mjs && npx tsx test/test-issue-store.mjs && npx tsx test/test-issue-store-lock.mjs && npx tsx test/test-issue-close-gate.mjs && npx tsx test/test-loop-verify.mjs && npx tsx test/test-restore-decision.mjs && npx tsx test/test-issue-rpc.mjs && npx tsx test/test-issue-pause.mjs && npx tsx test/test-workflow-store.mjs && npx tsx test/test-workflow-rpc.mjs && npx tsx test/test-workflow-scheduler.mjs && npx tsx test/test-cron.mjs && npx tsx test/test-workflow-runs.mjs && npx tsx test/test-workflow-runs-lock.mjs && npx tsx test/test-workflow-idle.mjs && npx tsx test/test-workflow-reconcile.mjs && npx tsx test/test-serve-link-subdomain.mjs && npx tsx test/test-short-id.mjs && npx tsx test/test-transcript-edit.mjs && npx tsx test/test-edit-history.mjs && npx tsx test/test-friendly-name.mjs && npx tsx test/test-session-rpc-dispatch.mjs && npx tsx test/test-sandbox-cli.mjs && npx tsx test/test-serve-manager.mjs && npx tsx test/test-serve-ws-upgrade.mjs && npx tsx test/test-serve-auth.mjs && npx tsx test/test-static-file-server.mjs && npx tsx test/test-serve-stability.mjs && npx tsx test/test-frpc-e2e.mjs --unit-only && npx tsx test/test-frpc-status.mjs && node test/pinnedClaudeCode.test.mjs && node test/fleet.test.mjs && npx tsx test/test-session-file.mjs && npx tsx test/test-channel-rpc.mjs && npx tsx test/test-wise-agent.mjs && npx tsx test/test-channel-agent.mjs && npx tsx test/test-channels-service.mjs && npx tsx test/test-hotreload-seam.mjs && npx tsx test/test-hot-reload.mjs && npx tsx test/test-hot-reload-live.mjs && npx tsx test/test-session-core.mjs && npx tsx test/test-channel-async-reply.mjs && npx tsx test/test-outbox-reload.mjs && npx tsx test/test-channel-binding.mjs && npx tsx test/test-channel-store-lock.mjs && npx tsx test/test-channel-identity.mjs && npx tsx test/test-stateless-dispatch-limiter.mjs && npx tsx test/test-shared-session-identity.mjs && npx tsx test/test-wise-agent-auth.mjs && npx tsx test/test-channel-http.mjs && npx tsx test/test-channel-upload.mjs && npx tsx test/test-wise-voice.mjs && npx tsx test/test-wise-headless.mjs && npx tsx test/test-wise-machine.mjs && npx tsx test/test-crew-merge.mjs && npx tsx test/test-crew-verdict-routing.mjs && npx tsx test/test-crew-standalone.mjs && npx tsx test/test-session-links.mjs && npx tsx test/test-issue-loop-pause-guard.mjs && npx tsx test/test-artifact-guard.mjs && npx tsx test/test-artifact-sync-pagination.mjs && npx tsx test/test-graceful-restart.mjs && npx tsx test/test-flush-exit.mjs && npx tsx test/test-codex-skills.mjs",
24
24
  "test:hypha": "node --no-warnings test/test-hypha-service.mjs",
25
25
  "dev": "tsx src/cli.ts",
26
26
  "dev:daemon": "tsx src/cli.ts daemon start-sync",