@botiverse/raft-daemon 0.59.0 → 0.59.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1471,11 +1471,17 @@ function runtimeConfigToLaunchFields(config) {
1471
1471
  }
1472
1472
  var PLAN_CONFIG = {
1473
1473
  free: {
1474
- displayName: "Hobby",
1474
+ displayName: "Free",
1475
1475
  limits: { maxMachines: 2, maxAgents: 5, maxChannels: 5, messageHistoryDays: 30, includedAgents: 5 },
1476
1476
  comingSoon: false,
1477
1477
  price: 0,
1478
- extraAgentPrice: 0
1478
+ extraAgentPrice: 0,
1479
+ displayFeatures: [
1480
+ "Unlimited human seats",
1481
+ "Up to 5 agent seats",
1482
+ "30 days of message history",
1483
+ "100 MB file uploads/month"
1484
+ ]
1479
1485
  },
1480
1486
  founder: {
1481
1487
  displayName: "Founder",
@@ -1488,23 +1494,40 @@ var PLAN_CONFIG = {
1488
1494
  var DISPLAY_PLAN_CONFIG = {
1489
1495
  free: PLAN_CONFIG.free,
1490
1496
  pro: {
1491
- displayName: "Team",
1492
- limits: { maxMachines: 8, maxAgents: 40, maxChannels: 20, messageHistoryDays: -1, includedAgents: 40 },
1493
- comingSoon: true,
1497
+ displayName: "Pro",
1498
+ limits: { maxMachines: -1, maxAgents: 10, maxChannels: -1, messageHistoryDays: -1, includedAgents: 10 },
1499
+ comingSoon: false,
1494
1500
  price: 20,
1495
- extraAgentPrice: 0
1501
+ priceCadence: "/ seat pack / month",
1502
+ extraAgentPrice: 0,
1503
+ displayFeatures: [
1504
+ "1 human seat + 10 agent seats per Pro Seat Pack",
1505
+ "Unlimited message history",
1506
+ "Higher file upload limits",
1507
+ "Joint Channels",
1508
+ "More professional features coming soon"
1509
+ ],
1510
+ displayNote: "$17.60 / seat pack / month when billed yearly"
1496
1511
  },
1497
- max: {
1498
- displayName: "Business",
1499
- limits: { maxMachines: 40, maxAgents: 200, maxChannels: -1, messageHistoryDays: -1, includedAgents: 200 },
1500
- comingSoon: true,
1501
- price: 200,
1502
- extraAgentPrice: 0
1512
+ enterprise: {
1513
+ displayName: "Enterprise",
1514
+ limits: { maxMachines: -1, maxAgents: -1, maxChannels: -1, messageHistoryDays: -1, includedAgents: -1 },
1515
+ comingSoon: false,
1516
+ price: 0,
1517
+ priceLabel: "Coming soon",
1518
+ priceCadence: null,
1519
+ extraAgentPrice: 0,
1520
+ displayFeatures: [
1521
+ "Custom commercial terms",
1522
+ "Security and compliance review",
1523
+ "Dedicated support and onboarding",
1524
+ "Custom deployment planning"
1525
+ ]
1503
1526
  }
1504
1527
  };
1505
1528
 
1506
1529
  // src/agentProcessManager.ts
1507
- import { mkdirSync as mkdirSync4, readdirSync as readdirSync2, statSync, writeFileSync as writeFileSync4 } from "fs";
1530
+ import { mkdirSync as mkdirSync4, readdirSync as readdirSync3, statSync, writeFileSync as writeFileSync4 } from "fs";
1508
1531
  import { mkdir, writeFile, access, readdir as readdir2, stat as stat2, readFile, rm as rm2 } from "fs/promises";
1509
1532
  import { createHash as createHash3 } from "crypto";
1510
1533
  import path12 from "path";
@@ -1514,7 +1537,7 @@ import os6 from "os";
1514
1537
  import { spawn } from "child_process";
1515
1538
 
1516
1539
  // src/drivers/cliTransport.ts
1517
- import { mkdirSync, readFileSync, rmSync, writeFileSync } from "fs";
1540
+ import { existsSync as existsSync2, mkdirSync, readdirSync, readFileSync, rmSync, writeFileSync } from "fs";
1518
1541
  import { createRequire } from "module";
1519
1542
  import path2 from "path";
1520
1543
 
@@ -3585,6 +3608,32 @@ var safePathPart = (value) => value.replace(/[^a-zA-Z0-9_.-]/g, "_");
3585
3608
  var RAW_CREDENTIAL_ENV_DENYLIST = [
3586
3609
  "SLOCK_AGENT_CREDENTIAL_KEY"
3587
3610
  ];
3611
+ function deriveCliFallbackCandidates(cliPath) {
3612
+ if (!cliPath || cliPath === "__cli") return [];
3613
+ const normalized = cliPath.split(path2.sep).join("/");
3614
+ const marker = "/node_modules/";
3615
+ const idx = normalized.indexOf(marker);
3616
+ if (idx === -1) return [];
3617
+ const globalRoot = cliPath.slice(0, idx + marker.length - 1);
3618
+ const tail = path2.join("dist", "cli", "index.js");
3619
+ return [
3620
+ path2.join(globalRoot, "@botiverse", "raft-daemon", tail),
3621
+ path2.join(globalRoot, "@slock-ai", "daemon", tail)
3622
+ ].filter((candidate) => candidate !== cliPath);
3623
+ }
3624
+ function deriveOpencliFallbackCandidates(binPath) {
3625
+ if (!binPath) return [];
3626
+ const normalized = binPath.split(path2.sep).join("/");
3627
+ const marker = "/node_modules/";
3628
+ const first = normalized.indexOf(marker);
3629
+ if (first === -1) return [];
3630
+ const pkgMarker = "/node_modules/@jackwener/opencli/";
3631
+ const last = normalized.lastIndexOf(pkgMarker);
3632
+ if (last === -1) return [];
3633
+ const suffix = normalized.slice(last + pkgMarker.length);
3634
+ const candidate = path2.join(binPath.slice(0, first + marker.length - 1), "@jackwener", "opencli", ...suffix.split("/"));
3635
+ return candidate === binPath ? [] : [candidate];
3636
+ }
3588
3637
  var cachedOpencliBinPath;
3589
3638
  function resolveOpencliBinPath() {
3590
3639
  if (cachedOpencliBinPath !== void 0) return cachedOpencliBinPath;
@@ -3619,6 +3668,64 @@ function resolveOpencliBinPath() {
3619
3668
  return null;
3620
3669
  }
3621
3670
  }
3671
+ function writeOpencliWrapper(slockDir, opencliBinPath, platform = process.platform) {
3672
+ const fallbacks = deriveOpencliFallbackCandidates(opencliBinPath);
3673
+ let binPath = opencliBinPath;
3674
+ if (!existsSync2(binPath)) {
3675
+ const fallback = fallbacks.find((candidate) => existsSync2(candidate));
3676
+ if (fallback) binPath = fallback;
3677
+ }
3678
+ const posixFallbackBlock = fallbacks.length === 0 ? "" : `if [ ! -e "$OPENCLI_BIN" ]; then
3679
+ ${fallbacks.map((candidate, i) => ` ${i === 0 ? "if" : "elif"} [ -e ${shellSingleQuote(candidate)} ]; then OPENCLI_BIN=${shellSingleQuote(candidate)};`).join("\n")}
3680
+ fi
3681
+ fi
3682
+ `;
3683
+ writeFileSync(
3684
+ path2.join(slockDir, "opencli"),
3685
+ `#!/usr/bin/env bash
3686
+ OPENCLI_BIN=${shellSingleQuote(binPath)}
3687
+ ${posixFallbackBlock}exec ${shellSingleQuote(process.execPath)} "$OPENCLI_BIN" "$@"
3688
+ `,
3689
+ { mode: 493 }
3690
+ );
3691
+ if (platform === "win32") {
3692
+ const opencliCmdBody = [
3693
+ "@echo off",
3694
+ "set PYTHONIOENCODING=utf-8",
3695
+ "set PYTHONUTF8=1",
3696
+ "set LANG=C.UTF-8",
3697
+ "set LC_ALL=C.UTF-8",
3698
+ "chcp 65001 >NUL 2>NUL",
3699
+ `set "OPENCLI_BIN=${binPath}"`,
3700
+ ...fallbacks.map((candidate) => `if not exist "%OPENCLI_BIN%" set "OPENCLI_BIN=${candidate}"`),
3701
+ `"${process.execPath}" "%OPENCLI_BIN%" %*`,
3702
+ ""
3703
+ ].join("\r\n") + "\r\n";
3704
+ writeFileSync(path2.join(slockDir, "opencli.cmd"), opencliCmdBody);
3705
+ }
3706
+ }
3707
+ function regenerateExistingOpencliWrappers(agentsRoot, platform = process.platform, opencliBinPath = resolveOpencliBinPath()) {
3708
+ if (!opencliBinPath) return { scanned: 0, rewritten: 0 };
3709
+ let entries;
3710
+ try {
3711
+ entries = readdirSync(agentsRoot);
3712
+ } catch {
3713
+ return { scanned: 0, rewritten: 0 };
3714
+ }
3715
+ let scanned = 0;
3716
+ let rewritten = 0;
3717
+ for (const entry of entries) {
3718
+ const slockDir = path2.join(agentsRoot, entry, ".slock");
3719
+ if (!existsSync2(path2.join(slockDir, "opencli"))) continue;
3720
+ scanned++;
3721
+ try {
3722
+ writeOpencliWrapper(slockDir, opencliBinPath, platform);
3723
+ rewritten++;
3724
+ } catch {
3725
+ }
3726
+ }
3727
+ return { scanned, rewritten };
3728
+ }
3622
3729
  function windowsUtf8Env() {
3623
3730
  return {
3624
3731
  PYTHONIOENCODING: "utf-8",
@@ -3676,6 +3783,21 @@ async function prepareCliTransport(ctx, extraEnv = {}, platform = process.platfo
3676
3783
  if (!ctx.slockCliPath) {
3677
3784
  throw new Error(`${ctx.config.runtime} driver: slockCliPath is required (daemon must inject it)`);
3678
3785
  }
3786
+ let cliPath = ctx.slockCliPath;
3787
+ const cliFallbackCandidates = deriveCliFallbackCandidates(cliPath);
3788
+ if (cliPath !== "__cli" && !existsSync2(cliPath)) {
3789
+ const fallback = cliFallbackCandidates.find((candidate) => existsSync2(candidate));
3790
+ if (fallback) {
3791
+ console.error(
3792
+ `[cliTransport] bundled CLI missing at ${cliPath} (package tree mutated under a running daemon?); using ${fallback}. Restart the daemon from its current install to clear this.`
3793
+ );
3794
+ cliPath = fallback;
3795
+ } else {
3796
+ console.error(
3797
+ `[cliTransport] bundled CLI missing at ${cliPath} and no global fallback found; wrappers will be broken until the daemon is restarted from a valid install.`
3798
+ );
3799
+ }
3800
+ }
3679
3801
  const slockDir = path2.join(ctx.workingDirectory, ".slock");
3680
3802
  mkdirSync(slockDir, { recursive: true });
3681
3803
  const slockHome = resolveSlockHome();
@@ -3704,9 +3826,15 @@ async function prepareCliTransport(ctx, extraEnv = {}, platform = process.platfo
3704
3826
  const posixWrapper = path2.join(slockDir, "slock");
3705
3827
  const posixRaftWrapper = path2.join(slockDir, "raft");
3706
3828
  const posixCredentialPrefix = agentCredentialProxy ? `SLOCK_AGENT_PROXY_URL=${shellSingleQuote(agentCredentialProxy.proxyUrl)} SLOCK_AGENT_PROXY_TOKEN_FILE=${shellSingleQuote(agentCredentialProxyTokenFile)} SLOCK_AGENT_ACTIVE_CAPABILITIES=${shellSingleQuote(DEFAULT_ACTIVE_CAPABILITIES)} ` : "";
3829
+ const posixCliFallbackBlock = cliPath === "__cli" || cliFallbackCandidates.length === 0 ? "" : `if [ ! -e "$SLOCK_CLI" ]; then
3830
+ ${cliFallbackCandidates.map((candidate, i) => ` ${i === 0 ? "if" : "elif"} [ -e ${shellSingleQuote(candidate)} ]; then SLOCK_CLI=${shellSingleQuote(candidate)};`).join("\n")}
3831
+ fi
3832
+ fi
3833
+ `;
3707
3834
  const posixBody = `#!/usr/bin/env bash
3708
3835
  ${posixLoopbackNoProxyPrelude()}
3709
- ${posixCredentialPrefix}exec ${shellSingleQuote(process.execPath)} ${shellSingleQuote(ctx.slockCliPath)} "$@"
3836
+ SLOCK_CLI=${shellSingleQuote(cliPath)}
3837
+ ${posixCliFallbackBlock}${posixCredentialPrefix}exec ${shellSingleQuote(process.execPath)} "$SLOCK_CLI" "$@"
3710
3838
  `;
3711
3839
  writeFileSync(posixWrapper, posixBody, { mode: 493 });
3712
3840
  writeFileSync(posixRaftWrapper, posixBody, { mode: 493 });
@@ -3717,6 +3845,7 @@ ${posixCredentialPrefix}exec ${shellSingleQuote(process.execPath)} ${shellSingle
3717
3845
  set "SLOCK_AGENT_PROXY_TOKEN_FILE=${agentCredentialProxyTokenFile}"\r
3718
3846
  set "SLOCK_AGENT_ACTIVE_CAPABILITIES=${DEFAULT_ACTIVE_CAPABILITIES}"\r
3719
3847
  ` : "";
3848
+ const cmdCliFallbackLines = cliPath === "__cli" ? [] : cliFallbackCandidates.map((candidate) => `if not exist "%SLOCK_CLI%" set "SLOCK_CLI=${candidate}"`);
3720
3849
  const cmdBody = [
3721
3850
  "@echo off",
3722
3851
  "set PYTHONIOENCODING=utf-8",
@@ -3726,7 +3855,9 @@ set "SLOCK_AGENT_ACTIVE_CAPABILITIES=${DEFAULT_ACTIVE_CAPABILITIES}"\r
3726
3855
  "chcp 65001 >NUL 2>NUL",
3727
3856
  ...cmdLoopbackNoProxyLines(),
3728
3857
  cmdCredentialLine.trimEnd(),
3729
- `"${process.execPath}" "${ctx.slockCliPath}" %*`,
3858
+ `set "SLOCK_CLI=${cliPath}"`,
3859
+ ...cmdCliFallbackLines,
3860
+ `"${process.execPath}" "%SLOCK_CLI%" %*`,
3730
3861
  ""
3731
3862
  ].filter((line) => line.length > 0).join("\r\n") + "\r\n";
3732
3863
  writeFileSync(cmdWrapper, cmdBody);
@@ -3750,7 +3881,14 @@ set "SLOCK_AGENT_ACTIVE_CAPABILITIES=${DEFAULT_ACTIVE_CAPABILITIES}"\r
3750
3881
  ...powershellLoopbackNoProxyLines(),
3751
3882
  ...psCredentialLines,
3752
3883
  `$node = ${powershellSingleQuote(process.execPath)}`,
3753
- `$cli = ${powershellSingleQuote(ctx.slockCliPath)}`,
3884
+ `$cli = ${powershellSingleQuote(cliPath)}`,
3885
+ ...cliPath === "__cli" || cliFallbackCandidates.length === 0 ? [] : [
3886
+ "if (-not (Test-Path $cli)) {",
3887
+ ` foreach ($candidate in @(${cliFallbackCandidates.map(powershellSingleQuote).join(", ")})) {`,
3888
+ " if (Test-Path $candidate) { $cli = $candidate; break }",
3889
+ " }",
3890
+ "}"
3891
+ ],
3754
3892
  "if ($MyInvocation.ExpectingInput) {",
3755
3893
  " $input | & $node $cli @args",
3756
3894
  "} else {",
@@ -3764,28 +3902,7 @@ set "SLOCK_AGENT_ACTIVE_CAPABILITIES=${DEFAULT_ACTIVE_CAPABILITIES}"\r
3764
3902
  }
3765
3903
  const opencliBinPath = resolveOpencliBinPath();
3766
3904
  if (opencliBinPath) {
3767
- const opencliPosixWrapper = path2.join(slockDir, "opencli");
3768
- writeFileSync(
3769
- opencliPosixWrapper,
3770
- `#!/usr/bin/env bash
3771
- exec ${shellSingleQuote(process.execPath)} ${shellSingleQuote(opencliBinPath)} "$@"
3772
- `,
3773
- { mode: 493 }
3774
- );
3775
- if (platform === "win32") {
3776
- const opencliCmdWrapper = path2.join(slockDir, "opencli.cmd");
3777
- const opencliCmdBody = [
3778
- "@echo off",
3779
- "set PYTHONIOENCODING=utf-8",
3780
- "set PYTHONUTF8=1",
3781
- "set LANG=C.UTF-8",
3782
- "set LC_ALL=C.UTF-8",
3783
- "chcp 65001 >NUL 2>NUL",
3784
- `"${process.execPath}" "${opencliBinPath}" %*`,
3785
- ""
3786
- ].join("\r\n") + "\r\n";
3787
- writeFileSync(opencliCmdWrapper, opencliCmdBody);
3788
- }
3905
+ writeOpencliWrapper(slockDir, opencliBinPath, platform);
3789
3906
  }
3790
3907
  const wrapperPath = platform === "win32" ? path2.join(slockDir, "slock.cmd") : posixWrapper;
3791
3908
  const launchRuntimeFields = runtimeConfigToLaunchFields(ctx.config);
@@ -4079,7 +4196,7 @@ import path4 from "path";
4079
4196
 
4080
4197
  // src/drivers/probe.ts
4081
4198
  import { execFileSync } from "child_process";
4082
- import { existsSync as existsSync2 } from "fs";
4199
+ import { existsSync as existsSync3 } from "fs";
4083
4200
  import path3 from "path";
4084
4201
  function normalizeExecOutput(raw) {
4085
4202
  return Buffer.isBuffer(raw) ? raw.toString("utf8") : String(raw ?? "");
@@ -4231,11 +4348,17 @@ function resolveCommandOnWindows(command, env, execFileSyncFn, existsSyncFn) {
4231
4348
  return null;
4232
4349
  }
4233
4350
  }
4351
+ function requiresWindowsShell(command, platform = process.platform) {
4352
+ if (platform !== "win32") return false;
4353
+ if (!command) return false;
4354
+ const lower = command.toLowerCase();
4355
+ return lower.endsWith(".cmd") || lower.endsWith(".bat");
4356
+ }
4234
4357
  function resolveCommandOnPath(command, deps = {}) {
4235
4358
  const platform = deps.platform ?? process.platform;
4236
4359
  const env = withWindowsUserEnvironment(deps.env ?? process.env, deps);
4237
4360
  const execFileSyncFn = deps.execFileSyncFn ?? execFileSync;
4238
- const existsSyncFn = deps.existsSyncFn ?? existsSync2;
4361
+ const existsSyncFn = deps.existsSyncFn ?? existsSync3;
4239
4362
  if (platform === "win32") {
4240
4363
  return resolveCommandOnWindows(command, env, execFileSyncFn, existsSyncFn);
4241
4364
  }
@@ -4252,7 +4375,7 @@ function resolveCommandOnPath(command, deps = {}) {
4252
4375
  }
4253
4376
  }
4254
4377
  function firstExistingPath(candidates, deps = {}) {
4255
- const exists = deps.existsSyncFn ?? existsSync2;
4378
+ const exists = deps.existsSyncFn ?? existsSync3;
4256
4379
  for (const candidate of candidates) {
4257
4380
  if (exists(candidate)) return candidate;
4258
4381
  }
@@ -4354,7 +4477,7 @@ function buildClaudeSpawnSpec(claudeCommand, platform = process.platform) {
4354
4477
  }
4355
4478
 
4356
4479
  // src/drivers/claudeProviderIsolation.ts
4357
- import { existsSync as existsSync3, mkdirSync as mkdirSync2, symlinkSync } from "fs";
4480
+ import { existsSync as existsSync4, mkdirSync as mkdirSync2, symlinkSync } from "fs";
4358
4481
  import os2 from "os";
4359
4482
  import path5 from "path";
4360
4483
  function isClaudeCustomProviderConfig(config) {
@@ -4372,7 +4495,7 @@ function getClaudeProviderStatePaths(workingDirectory) {
4372
4495
  }
4373
4496
  function linkIfPresent(source, target) {
4374
4497
  try {
4375
- if (!existsSync3(source) || existsSync3(target)) return;
4498
+ if (!existsSync4(source) || existsSync4(target)) return;
4376
4499
  mkdirSync2(path5.dirname(target), { recursive: true, mode: 448 });
4377
4500
  symlinkSync(source, target, "dir");
4378
4501
  } catch {
@@ -4493,7 +4616,7 @@ var ClaudeDriver = class {
4493
4616
 
4494
4617
  // src/drivers/codex.ts
4495
4618
  import { spawn as spawn2, execFileSync as execFileSync2, execSync } from "child_process";
4496
- import { existsSync as existsSync4, readFileSync as readFileSync2 } from "fs";
4619
+ import { existsSync as existsSync5, readFileSync as readFileSync2 } from "fs";
4497
4620
  import os3 from "os";
4498
4621
  import path6 from "path";
4499
4622
 
@@ -4882,7 +5005,7 @@ var CodexEventNormalizer = class {
4882
5005
 
4883
5006
  // src/drivers/codex.ts
4884
5007
  function ensureGitRepoForCodex(workingDirectory, deps = {}) {
4885
- const existsSyncFn = deps.existsSyncFn ?? existsSync4;
5008
+ const existsSyncFn = deps.existsSyncFn ?? existsSync5;
4886
5009
  const execSyncFn = deps.execSyncFn ?? execSync;
4887
5010
  const gitDir = path6.join(workingDirectory, ".git");
4888
5011
  if (existsSyncFn(gitDir)) return;
@@ -4900,7 +5023,7 @@ function isWindowsSandboxRunner(commandPath) {
4900
5023
  return path6.basename(commandPath).toLowerCase().startsWith("codex-command-runner");
4901
5024
  }
4902
5025
  function resolveWindowsNpmCodexEntry(deps = {}) {
4903
- const existsSyncFn = deps.existsSyncFn ?? existsSync4;
5026
+ const existsSyncFn = deps.existsSyncFn ?? existsSync5;
4904
5027
  const execFileSyncFn = deps.execFileSyncFn ?? execFileSync2;
4905
5028
  const env = deps.env ?? process.env;
4906
5029
  const winPath = path6.win32;
@@ -4922,7 +5045,7 @@ function resolveWindowsNpmCodexEntry(deps = {}) {
4922
5045
  return null;
4923
5046
  }
4924
5047
  function resolveWindowsCodexDesktopEntry(deps = {}) {
4925
- const existsSyncFn = deps.existsSyncFn ?? existsSync4;
5048
+ const existsSyncFn = deps.existsSyncFn ?? existsSync5;
4926
5049
  const env = deps.env ?? process.env;
4927
5050
  const homeDir = deps.homeDir;
4928
5051
  const winPath = path6.win32;
@@ -5037,7 +5160,7 @@ var CodexDriver = class {
5037
5160
  threadParams.config = { model_reasoning_effort: launchRuntimeFields.reasoningEffort };
5038
5161
  }
5039
5162
  if (launchRuntimeFields.mode.kind === "fast") {
5040
- threadParams.serviceTier = "priority";
5163
+ threadParams.serviceTier = "fast";
5041
5164
  }
5042
5165
  if (ctx.config.sessionId) {
5043
5166
  return {
@@ -5237,10 +5360,11 @@ var ANTIGRAVITY_ENV_OVERRIDES = {
5237
5360
  SSH_TTY: void 0
5238
5361
  };
5239
5362
  function resolveAntigravitySpawn(commandArgs, deps = {}) {
5363
+ const command = resolveCommandOnPath("agy", deps) ?? "agy";
5240
5364
  return {
5241
- command: resolveCommandOnPath("agy", deps) ?? "agy",
5365
+ command,
5242
5366
  args: commandArgs,
5243
- shell: false
5367
+ shell: requiresWindowsShell(command, deps.platform)
5244
5368
  };
5245
5369
  }
5246
5370
  function buildAntigravityArgs(ctx) {
@@ -5664,7 +5788,7 @@ function runCursorModelsCommand() {
5664
5788
 
5665
5789
  // src/drivers/gemini.ts
5666
5790
  import { execFileSync as execFileSync3, spawn as spawn6 } from "child_process";
5667
- import { existsSync as existsSync5 } from "fs";
5791
+ import { existsSync as existsSync6 } from "fs";
5668
5792
  import path7 from "path";
5669
5793
  async function buildGeminiSpawnEnv(ctx, platform = process.platform) {
5670
5794
  const { spawnEnv } = await prepareCliTransport(ctx, { NO_COLOR: "1" }, platform);
@@ -5707,7 +5831,7 @@ function resolveGeminiSpawn(commandArgs, deps = {}) {
5707
5831
  return { command: resolveCommandOnPath("gemini", deps) ?? "gemini", args: commandArgs };
5708
5832
  }
5709
5833
  const execFileSyncFn = deps.execFileSyncFn ?? execFileSync3;
5710
- const existsSyncFn = deps.existsSyncFn ?? existsSync5;
5834
+ const existsSyncFn = deps.existsSyncFn ?? existsSync6;
5711
5835
  const env = deps.env ?? process.env;
5712
5836
  const winPath = path7.win32;
5713
5837
  let geminiEntry = null;
@@ -5845,7 +5969,7 @@ var GeminiDriver = class {
5845
5969
  // src/drivers/kimi.ts
5846
5970
  import { randomUUID as randomUUID2 } from "crypto";
5847
5971
  import { spawn as spawn7 } from "child_process";
5848
- import { existsSync as existsSync6, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "fs";
5972
+ import { existsSync as existsSync7, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "fs";
5849
5973
  import os4 from "os";
5850
5974
  import path8 from "path";
5851
5975
  var KIMI_WIRE_PROTOCOL_VERSION = "1.3";
@@ -5896,7 +6020,7 @@ var KimiDriver = class {
5896
6020
  this.promptRequestId = randomUUID2();
5897
6021
  const systemPromptPath = path8.join(ctx.workingDirectory, KIMI_SYSTEM_PROMPT_FILE);
5898
6022
  const agentFilePath = path8.join(ctx.workingDirectory, KIMI_AGENT_FILE);
5899
- if (!isResume || !existsSync6(systemPromptPath)) {
6023
+ if (!isResume || !existsSync7(systemPromptPath)) {
5900
6024
  writeFileSync3(systemPromptPath, ctx.prompt, "utf8");
5901
6025
  }
5902
6026
  writeFileSync3(agentFilePath, [
@@ -6069,7 +6193,7 @@ function detectKimiModels(home = os4.homedir()) {
6069
6193
 
6070
6194
  // src/drivers/opencode.ts
6071
6195
  import { spawn as spawn8, spawnSync as spawnSync2 } from "child_process";
6072
- import { existsSync as existsSync7, readFileSync as readFileSync4 } from "fs";
6196
+ import { existsSync as existsSync8, readFileSync as readFileSync4 } from "fs";
6073
6197
  import os5 from "os";
6074
6198
  import path9 from "path";
6075
6199
  var SLOCK_AGENT_NAME = "slock";
@@ -6317,7 +6441,7 @@ function openCodeSpecForEntry(entry, commandArgs) {
6317
6441
  return { command: process.execPath, args: [entry, ...commandArgs], shell: false };
6318
6442
  }
6319
6443
  function resolveWindowsOpenCodePackageEntry(commandPath, deps = {}) {
6320
- const existsSyncFn = deps.existsSyncFn ?? existsSync7;
6444
+ const existsSyncFn = deps.existsSyncFn ?? existsSync8;
6321
6445
  const execFileSyncFn = deps.execFileSyncFn;
6322
6446
  const env = deps.env ?? process.env;
6323
6447
  const winPath = path9.win32;
@@ -6545,7 +6669,7 @@ var OpenCodeDriver = class {
6545
6669
  // src/drivers/pi.ts
6546
6670
  import { randomUUID as randomUUID3 } from "crypto";
6547
6671
  import { EventEmitter } from "events";
6548
- import { mkdirSync as mkdirSync3, readdirSync } from "fs";
6672
+ import { mkdirSync as mkdirSync3, readdirSync as readdirSync2 } from "fs";
6549
6673
  import path10 from "path";
6550
6674
  import {
6551
6675
  AuthStorage,
@@ -6589,7 +6713,7 @@ function resolvePiModelFromRegistry(modelId, modelRegistry) {
6589
6713
  function findPiSessionFile(sessionDir, sessionId) {
6590
6714
  let entries;
6591
6715
  try {
6592
- entries = readdirSync(sessionDir);
6716
+ entries = readdirSync2(sessionDir);
6593
6717
  } catch {
6594
6718
  return null;
6595
6719
  }
@@ -7819,7 +7943,7 @@ function findSessionJsonl(root, predicate) {
7819
7943
  if (depth < 0 || visited >= maxEntries) return null;
7820
7944
  let entries;
7821
7945
  try {
7822
- entries = readdirSync2(dir, { withFileTypes: true }).sort((a, b) => b.name.localeCompare(a.name));
7946
+ entries = readdirSync3(dir, { withFileTypes: true }).sort((a, b) => b.name.localeCompare(a.name));
7823
7947
  } catch {
7824
7948
  return null;
7825
7949
  }
@@ -13428,7 +13552,7 @@ function acquireDaemonMachineLock(options) {
13428
13552
  }
13429
13553
 
13430
13554
  // src/localTraceSink.ts
13431
- import { appendFileSync, mkdirSync as mkdirSync6, readdirSync as readdirSync3, rmSync as rmSync4, statSync as statSync3, writeFileSync as writeFileSync6 } from "fs";
13555
+ import { appendFileSync, mkdirSync as mkdirSync6, readdirSync as readdirSync4, rmSync as rmSync4, statSync as statSync3, writeFileSync as writeFileSync6 } from "fs";
13432
13556
  import path14 from "path";
13433
13557
  var DEFAULT_MAX_FILE_BYTES = 5 * 1024 * 1024;
13434
13558
  var DEFAULT_MAX_FILE_AGE_MS = 5 * 60 * 1e3;
@@ -13507,7 +13631,7 @@ var LocalRotatingTraceSink = class {
13507
13631
  }
13508
13632
  }
13509
13633
  pruneOldFiles() {
13510
- const files = readdirSync3(this.traceDir).filter((name) => name.startsWith("daemon-trace-") && name.endsWith(".jsonl")).sort();
13634
+ const files = readdirSync4(this.traceDir).filter((name) => name.startsWith("daemon-trace-") && name.endsWith(".jsonl")).sort();
13511
13635
  const excess = files.length - this.maxFiles;
13512
13636
  if (excess <= 0) return;
13513
13637
  for (const file of files.slice(0, excess)) {
@@ -14166,7 +14290,7 @@ function resolveSlockCliPathOrEmpty(moduleUrl = import.meta.url) {
14166
14290
  }
14167
14291
  async function runBundledSlockCli(argv) {
14168
14292
  process.argv = [process.execPath, "slock", ...argv];
14169
- await import("./dist-CLQ4P4XZ.js");
14293
+ await import("./dist-QQ3DYJPK.js");
14170
14294
  }
14171
14295
  function detectRuntimes(tracer = noopTracer) {
14172
14296
  const ids = [];
@@ -14302,6 +14426,11 @@ var DaemonCore = class {
14302
14426
  computerVersion;
14303
14427
  slockCliPath;
14304
14428
  slockHome;
14429
+ agentsDataDir;
14430
+ // One-shot guard: rewrite stale per-agent opencli wrappers to the current
14431
+ // self-healing form on the first connect of this daemon process (a SEA
14432
+ // computer switch / daemon upgrade restarts the daemon → triggers this).
14433
+ opencliWrappersRegenerated = false;
14305
14434
  runtimeDetector;
14306
14435
  agentManager;
14307
14436
  connection;
@@ -14328,8 +14457,9 @@ var DaemonCore = class {
14328
14457
  onFire: (job) => this.onReminderFire(job)
14329
14458
  });
14330
14459
  let connection;
14460
+ this.agentsDataDir = options.dataDir ?? resolveSlockHomePath("agents", this.slockHome);
14331
14461
  const agentManagerOptions = {
14332
- dataDir: options.dataDir ?? resolveSlockHomePath("agents", this.slockHome),
14462
+ dataDir: this.agentsDataDir,
14333
14463
  serverUrl: options.serverUrl,
14334
14464
  defaultAgentEnvVarsProvider: options.defaultAgentEnvVarsProvider,
14335
14465
  slockCliPath: this.slockCliPath,
@@ -14859,6 +14989,17 @@ var DaemonCore = class {
14859
14989
  const { ids: runtimes, versions: runtimeVersions } = this.runtimeDetector();
14860
14990
  const runtimeInfo = runtimes.map((id) => runtimeVersions[id] ? `${id} (${runtimeVersions[id]})` : id);
14861
14991
  logger.info(`[Daemon] Detected runtimes: ${runtimeInfo.join(", ") || "none"}`);
14992
+ if (!this.opencliWrappersRegenerated) {
14993
+ this.opencliWrappersRegenerated = true;
14994
+ try {
14995
+ const { scanned, rewritten } = regenerateExistingOpencliWrappers(this.agentsDataDir);
14996
+ if (scanned > 0) {
14997
+ logger.info(`[Daemon] Refreshed ${rewritten}/${scanned} opencli wrapper(s) to current self-healing form`);
14998
+ }
14999
+ } catch (err) {
15000
+ logger.warn(`[Daemon] opencli wrapper refresh skipped: ${err instanceof Error ? err.message : String(err)}`);
15001
+ }
15002
+ }
14862
15003
  const runningAgentIds = this.agentManager.getRunningAgentIds();
14863
15004
  const idleAgentSessions = this.agentManager.getIdleAgentSessionIds();
14864
15005
  const runtimeProfileReports = this.agentManager.getAgentRuntimeProfileReports();
package/dist/cli/index.js CHANGED
@@ -1302,7 +1302,6 @@ function formatVerificationHandoff(action) {
1302
1302
  const mins = Math.max(0, Math.floor(action.expiresInSeconds / 60));
1303
1303
  if (action.verificationUriComplete) {
1304
1304
  return `Open this link to approve (code pre-filled): ${action.verificationUriComplete}
1305
- (fallback) Open ${action.verificationUri} and enter code ${action.userCode}.
1306
1305
  Expires in ~${mins}m.
1307
1306
  `;
1308
1307
  }
@@ -1317,8 +1316,6 @@ function formatStartHandoff(authorization, options, paths) {
1317
1316
  `;
1318
1317
  if (authorization.verificationUriComplete) {
1319
1318
  out += ` Open this link (code pre-filled): ${authorization.verificationUriComplete}
1320
- `;
1321
- out += ` (fallback) Open ${authorization.verificationUri} and enter code ${authorization.userCode}.
1322
1319
  `;
1323
1320
  } else {
1324
1321
  out += ` Open ${authorization.verificationUri} and enter code ${authorization.userCode}.
@@ -15815,11 +15812,17 @@ var RUNTIME_MODELS = {
15815
15812
  };
15816
15813
  var PLAN_CONFIG = {
15817
15814
  free: {
15818
- displayName: "Hobby",
15815
+ displayName: "Free",
15819
15816
  limits: { maxMachines: 2, maxAgents: 5, maxChannels: 5, messageHistoryDays: 30, includedAgents: 5 },
15820
15817
  comingSoon: false,
15821
15818
  price: 0,
15822
- extraAgentPrice: 0
15819
+ extraAgentPrice: 0,
15820
+ displayFeatures: [
15821
+ "Unlimited human seats",
15822
+ "Up to 5 agent seats",
15823
+ "30 days of message history",
15824
+ "100 MB file uploads/month"
15825
+ ]
15823
15826
  },
15824
15827
  founder: {
15825
15828
  displayName: "Founder",
@@ -15832,18 +15835,35 @@ var PLAN_CONFIG = {
15832
15835
  var DISPLAY_PLAN_CONFIG = {
15833
15836
  free: PLAN_CONFIG.free,
15834
15837
  pro: {
15835
- displayName: "Team",
15836
- limits: { maxMachines: 8, maxAgents: 40, maxChannels: 20, messageHistoryDays: -1, includedAgents: 40 },
15837
- comingSoon: true,
15838
+ displayName: "Pro",
15839
+ limits: { maxMachines: -1, maxAgents: 10, maxChannels: -1, messageHistoryDays: -1, includedAgents: 10 },
15840
+ comingSoon: false,
15838
15841
  price: 20,
15839
- extraAgentPrice: 0
15842
+ priceCadence: "/ seat pack / month",
15843
+ extraAgentPrice: 0,
15844
+ displayFeatures: [
15845
+ "1 human seat + 10 agent seats per Pro Seat Pack",
15846
+ "Unlimited message history",
15847
+ "Higher file upload limits",
15848
+ "Joint Channels",
15849
+ "More professional features coming soon"
15850
+ ],
15851
+ displayNote: "$17.60 / seat pack / month when billed yearly"
15840
15852
  },
15841
- max: {
15842
- displayName: "Business",
15843
- limits: { maxMachines: 40, maxAgents: 200, maxChannels: -1, messageHistoryDays: -1, includedAgents: 200 },
15844
- comingSoon: true,
15845
- price: 200,
15846
- extraAgentPrice: 0
15853
+ enterprise: {
15854
+ displayName: "Enterprise",
15855
+ limits: { maxMachines: -1, maxAgents: -1, maxChannels: -1, messageHistoryDays: -1, includedAgents: -1 },
15856
+ comingSoon: false,
15857
+ price: 0,
15858
+ priceLabel: "Coming soon",
15859
+ priceCadence: null,
15860
+ extraAgentPrice: 0,
15861
+ displayFeatures: [
15862
+ "Custom commercial terms",
15863
+ "Security and compliance review",
15864
+ "Dedicated support and onboarding",
15865
+ "Custom deployment planning"
15866
+ ]
15847
15867
  }
15848
15868
  };
15849
15869
 
package/dist/core.js CHANGED
@@ -11,7 +11,7 @@ import {
11
11
  runBundledSlockCli,
12
12
  scanWorkspaceDirectories,
13
13
  subscribeDaemonLogs
14
- } from "./chunk-FTEZQN4P.js";
14
+ } from "./chunk-C7OYRUYW.js";
15
15
  export {
16
16
  DAEMON_CLI_USAGE,
17
17
  DaemonCore,
@@ -1289,7 +1289,6 @@ function formatVerificationHandoff(action) {
1289
1289
  const mins = Math.max(0, Math.floor(action.expiresInSeconds / 60));
1290
1290
  if (action.verificationUriComplete) {
1291
1291
  return `Open this link to approve (code pre-filled): ${action.verificationUriComplete}
1292
- (fallback) Open ${action.verificationUri} and enter code ${action.userCode}.
1293
1292
  Expires in ~${mins}m.
1294
1293
  `;
1295
1294
  }
@@ -1304,8 +1303,6 @@ function formatStartHandoff(authorization, options, paths) {
1304
1303
  `;
1305
1304
  if (authorization.verificationUriComplete) {
1306
1305
  out += ` Open this link (code pre-filled): ${authorization.verificationUriComplete}
1307
- `;
1308
- out += ` (fallback) Open ${authorization.verificationUri} and enter code ${authorization.userCode}.
1309
1306
  `;
1310
1307
  } else {
1311
1308
  out += ` Open ${authorization.verificationUri} and enter code ${authorization.userCode}.
@@ -15621,11 +15618,17 @@ var RUNTIME_MODELS = {
15621
15618
  };
15622
15619
  var PLAN_CONFIG = {
15623
15620
  free: {
15624
- displayName: "Hobby",
15621
+ displayName: "Free",
15625
15622
  limits: { maxMachines: 2, maxAgents: 5, maxChannels: 5, messageHistoryDays: 30, includedAgents: 5 },
15626
15623
  comingSoon: false,
15627
15624
  price: 0,
15628
- extraAgentPrice: 0
15625
+ extraAgentPrice: 0,
15626
+ displayFeatures: [
15627
+ "Unlimited human seats",
15628
+ "Up to 5 agent seats",
15629
+ "30 days of message history",
15630
+ "100 MB file uploads/month"
15631
+ ]
15629
15632
  },
15630
15633
  founder: {
15631
15634
  displayName: "Founder",
@@ -15638,18 +15641,35 @@ var PLAN_CONFIG = {
15638
15641
  var DISPLAY_PLAN_CONFIG = {
15639
15642
  free: PLAN_CONFIG.free,
15640
15643
  pro: {
15641
- displayName: "Team",
15642
- limits: { maxMachines: 8, maxAgents: 40, maxChannels: 20, messageHistoryDays: -1, includedAgents: 40 },
15643
- comingSoon: true,
15644
+ displayName: "Pro",
15645
+ limits: { maxMachines: -1, maxAgents: 10, maxChannels: -1, messageHistoryDays: -1, includedAgents: 10 },
15646
+ comingSoon: false,
15644
15647
  price: 20,
15645
- extraAgentPrice: 0
15648
+ priceCadence: "/ seat pack / month",
15649
+ extraAgentPrice: 0,
15650
+ displayFeatures: [
15651
+ "1 human seat + 10 agent seats per Pro Seat Pack",
15652
+ "Unlimited message history",
15653
+ "Higher file upload limits",
15654
+ "Joint Channels",
15655
+ "More professional features coming soon"
15656
+ ],
15657
+ displayNote: "$17.60 / seat pack / month when billed yearly"
15646
15658
  },
15647
- max: {
15648
- displayName: "Business",
15649
- limits: { maxMachines: 40, maxAgents: 200, maxChannels: -1, messageHistoryDays: -1, includedAgents: 200 },
15650
- comingSoon: true,
15651
- price: 200,
15652
- extraAgentPrice: 0
15659
+ enterprise: {
15660
+ displayName: "Enterprise",
15661
+ limits: { maxMachines: -1, maxAgents: -1, maxChannels: -1, messageHistoryDays: -1, includedAgents: -1 },
15662
+ comingSoon: false,
15663
+ price: 0,
15664
+ priceLabel: "Coming soon",
15665
+ priceCadence: null,
15666
+ extraAgentPrice: 0,
15667
+ displayFeatures: [
15668
+ "Custom commercial terms",
15669
+ "Security and compliance review",
15670
+ "Dedicated support and onboarding",
15671
+ "Custom deployment planning"
15672
+ ]
15653
15673
  }
15654
15674
  };
15655
15675
  var AGENT_COMMS_PROTOCOL_VERSION = "agent-comms-core.v1";
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  DAEMON_CLI_USAGE,
4
4
  DaemonCore,
5
5
  parseDaemonCliArgs
6
- } from "./chunk-FTEZQN4P.js";
6
+ } from "./chunk-C7OYRUYW.js";
7
7
 
8
8
  // src/index.ts
9
9
  var parsedArgs = parseDaemonCliArgs(process.argv.slice(2));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@botiverse/raft-daemon",
3
- "version": "0.59.0",
3
+ "version": "0.59.1",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "raft-daemon": "dist/raft-daemon.js",
@@ -43,8 +43,8 @@
43
43
  "release:alpha": "npm version prerelease --preid=alpha --no-git-tag-version && cd ../.. && pnpm install --lockfile-only && git add packages/daemon/package.json pnpm-lock.yaml && git commit -m \"chore: bump @botiverse/raft-daemon to v$(node -p \"require('./packages/daemon/package.json').version\")\" && git tag daemon-v$(node -p \"require('./packages/daemon/package.json').version\") && git push && git push --tags"
44
44
  },
45
45
  "dependencies": {
46
- "@earendil-works/pi-ai": "0.79.1",
47
- "@earendil-works/pi-coding-agent": "0.79.1",
46
+ "@earendil-works/pi-ai": "0.79.3",
47
+ "@earendil-works/pi-coding-agent": "0.79.3",
48
48
  "@jackwener/opencli": "^1.8.3",
49
49
  "@modelcontextprotocol/sdk": "^1.29.0",
50
50
  "commander": "^12.1.0",