svamp-cli 0.2.185 → 0.2.187

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 (29) hide show
  1. package/bin/skills/loop/SKILL.md +2 -1
  2. package/bin/skills/loop/bin/inject-loop.mjs +36 -1
  3. package/bin/skills/loop/bin/loop-init.mjs +2 -0
  4. package/bin/skills/loop/bin/stop-gate.mjs +1 -1
  5. package/dist/{agentCommands-Tcfv1U8D.mjs → agentCommands-D82YAIjn.mjs} +5 -5
  6. package/dist/{auth-B1W6o3z6.mjs → auth-CRgqElsS.mjs} +1 -1
  7. package/dist/cli.mjs +60 -60
  8. package/dist/{commands-BtvYB2td.mjs → commands-2vgPBzxG.mjs} +5 -5
  9. package/dist/{commands-W7DllEQt.mjs → commands-B7oQTg-f.mjs} +1 -1
  10. package/dist/{commands-BCcf9P0h.mjs → commands-BpIsPzLL.mjs} +1 -1
  11. package/dist/{commands-DhWWYPCu.mjs → commands-CkxVt5V0.mjs} +1 -1
  12. package/dist/{commands-wuGT62QI.mjs → commands-DB3LqPei.mjs} +1 -1
  13. package/dist/{commands-xE8KNuKU.mjs → commands-DIPPrpHk.mjs} +2 -2
  14. package/dist/{commands-DLUtnIUf.mjs → commands-DubAkp0i.mjs} +2 -2
  15. package/dist/{fleet-BtIF0tcq.mjs → fleet-PKdEHCXZ.mjs} +1 -1
  16. package/dist/{frpc-DGErIpoO.mjs → frpc-CDj2C0fs.mjs} +1 -1
  17. package/dist/{headlessCli-DyPAqqxN.mjs → headlessCli-BGGF_UPQ.mjs} +2 -2
  18. package/dist/index.mjs +1 -1
  19. package/dist/package-B6C96K9S.mjs +63 -0
  20. package/dist/{rpc-eRCuvMdD.mjs → rpc-B0_q0Ore.mjs} +1 -1
  21. package/dist/{rpc-efgqAqwL.mjs → rpc-DuAe8TKC.mjs} +1 -1
  22. package/dist/{run-L9mNCmzT.mjs → run-DZLwKdGH.mjs} +213 -207
  23. package/dist/{run-BuNdAM7A.mjs → run-FgS-4E-C.mjs} +5 -2
  24. package/dist/{scheduler-TtMT4mcq.mjs → scheduler-CVODqtZb.mjs} +1 -1
  25. package/dist/{serveCommands-DgbxJMHe.mjs → serveCommands-C8QvTpse.mjs} +5 -5
  26. package/dist/{serveManager-BH8Suv9x.mjs → serveManager-CU5NrVV-.mjs} +2 -2
  27. package/dist/{sideband-DRMOoCdW.mjs → sideband-B7uDd_pR.mjs} +1 -1
  28. package/package.json +2 -2
  29. package/dist/package-dix09Aop.mjs +0 -63
@@ -2720,7 +2720,7 @@ async function registerMachineService(server, machineId, metadata, daemonState,
2720
2720
  const tunnels = handlers.tunnels;
2721
2721
  if (!tunnels) throw new Error("Tunnel management not available");
2722
2722
  if (tunnels.has(params.name)) throw new Error(`Tunnel '${params.name}' already running`);
2723
- const { FrpcTunnel } = await import('./frpc-DGErIpoO.mjs');
2723
+ const { FrpcTunnel } = await import('./frpc-CDj2C0fs.mjs');
2724
2724
  const tunnel = new FrpcTunnel({
2725
2725
  name: params.name,
2726
2726
  ports: params.ports,
@@ -3167,7 +3167,7 @@ QUESTION: ${params.question || "Summarize this concisely."}` }
3167
3167
  }
3168
3168
  const deps = buildSessionDeps(rpc, { cwd, ownerEmail: owner });
3169
3169
  const sender = { name: context?.user?.email || context?.user?.id || "user", kind: "user", verified: true };
3170
- const { toolsForRole } = await import('./sideband-DRMOoCdW.mjs');
3170
+ const { toolsForRole } = await import('./sideband-B7uDd_pR.mjs');
3171
3171
  const r2 = await runWiseAgent({ message: params.message, sender, config: { tools: toolsForRole(role2) }, deps, transport, model: resolved.model });
3172
3172
  return fmt(r2);
3173
3173
  }
@@ -3266,7 +3266,7 @@ QUESTION: ${params.question || "Summarize this concisely."}` }
3266
3266
  if (r.error || !r.sender) return { error: r.error || "unauthorized" };
3267
3267
  const callId = "call_" + Math.random().toString(16).slice(2, 12);
3268
3268
  const rendered = renderMessage(c, { sender: r.sender, body: { message: kwargs.message }, callId });
3269
- const { queryCore } = await import('./commands-DhWWYPCu.mjs');
3269
+ const { queryCore } = await import('./commands-CkxVt5V0.mjs');
3270
3270
  const timeout = c.reply?.timeout_sec || 120;
3271
3271
  let result;
3272
3272
  try {
@@ -3565,6 +3565,199 @@ function isRetryableRateLimit(text, apiErrorStatus) {
3565
3565
  return apiErrorStatus === 429 || apiErrorStatus === 529 || apiErrorStatus === 503 || /\b(429|529|503)\b/.test(t) || t.includes("temporarily limiting") || t.includes("not your usage limit") || t.includes("overloaded") || t.includes("overload") || t.includes("too many requests") || t.includes("server is busy") || t.includes("rate limit") || t.includes("rate-limit") || t.includes("rate limited");
3566
3566
  }
3567
3567
 
3568
+ const EXAMPLE_HYPHA_PROXY_URL = "https://proxy.hypha.aicell.io";
3569
+ const MODE_KEY = "SVAMP_CLAUDE_PROXY";
3570
+ const HYPHA_PROXY_URL_KEY = "SVAMP_HYPHA_PROXY_URL";
3571
+ const MANAGED_KEYS = /* @__PURE__ */ new Set([
3572
+ MODE_KEY,
3573
+ HYPHA_PROXY_URL_KEY,
3574
+ "ANTHROPIC_BASE_URL",
3575
+ "ANTHROPIC_API_KEY"
3576
+ ]);
3577
+ function normalizeProxyUrl(raw) {
3578
+ const trimmed = raw.trim().replace(/\/+$/, "");
3579
+ if (trimmed.endsWith("/v1")) {
3580
+ throw new Error(
3581
+ "Hypha proxy URL must not end in /v1 \u2014 the SDK appends it, producing double /v1/v1/messages"
3582
+ );
3583
+ }
3584
+ return trimmed;
3585
+ }
3586
+ function resolveHyphaProxyUrl() {
3587
+ const configured = (process.env[HYPHA_PROXY_URL_KEY] || "").trim();
3588
+ if (!configured) return void 0;
3589
+ try {
3590
+ return normalizeProxyUrl(configured);
3591
+ } catch {
3592
+ return void 0;
3593
+ }
3594
+ }
3595
+ function envFilePath() {
3596
+ const svampHome = process.env.SVAMP_HOME || join(homedir(), ".svamp");
3597
+ return join(svampHome, ".env");
3598
+ }
3599
+ function readEnvLines() {
3600
+ const file = envFilePath();
3601
+ if (!existsSync(file)) return [];
3602
+ return readFileSync(file, "utf-8").split("\n");
3603
+ }
3604
+ function writeEnvLines(lines) {
3605
+ const file = envFilePath();
3606
+ const dir = join(file, "..");
3607
+ if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
3608
+ while (lines.length > 0 && lines[lines.length - 1].trim() === "") {
3609
+ lines.pop();
3610
+ }
3611
+ writeFileSync(file, lines.join("\n") + "\n", "utf-8");
3612
+ }
3613
+ function updateEnvFile(updates) {
3614
+ const lines = readEnvLines();
3615
+ const kept = [];
3616
+ const remainingUpdates = new Map(Object.entries(updates));
3617
+ for (const line of lines) {
3618
+ const trimmed = line.trim();
3619
+ if (!trimmed || trimmed.startsWith("#")) {
3620
+ kept.push(line);
3621
+ continue;
3622
+ }
3623
+ const eq = trimmed.indexOf("=");
3624
+ const key = eq === -1 ? trimmed : trimmed.slice(0, eq);
3625
+ if (remainingUpdates.has(key)) {
3626
+ const v = remainingUpdates.get(key);
3627
+ remainingUpdates.delete(key);
3628
+ if (v === void 0) continue;
3629
+ kept.push(`${key}=${v}`);
3630
+ continue;
3631
+ }
3632
+ kept.push(line);
3633
+ }
3634
+ for (const [key, v] of remainingUpdates) {
3635
+ if (v === void 0) continue;
3636
+ kept.push(`${key}=${v}`);
3637
+ }
3638
+ writeEnvLines(kept);
3639
+ }
3640
+ function currentMode() {
3641
+ const raw = (process.env[MODE_KEY] || "").trim().toLowerCase();
3642
+ if (raw === "hypha" || raw === "hypha-proxy") return "hypha";
3643
+ if (raw === "custom") return "custom";
3644
+ return "login";
3645
+ }
3646
+ function redactKey(key) {
3647
+ if (!key) return void 0;
3648
+ if (key.length <= 12) return "***";
3649
+ return `${key.slice(0, 8)}\u2026${key.slice(-4)}`;
3650
+ }
3651
+ function getClaudeAuthStatus() {
3652
+ const mode = currentMode();
3653
+ if (mode === "hypha") {
3654
+ const token = process.env.HYPHA_TOKEN;
3655
+ const proxyUrl = resolveHyphaProxyUrl();
3656
+ return {
3657
+ mode,
3658
+ baseUrl: proxyUrl,
3659
+ apiKeyPreview: redactKey(token),
3660
+ hyphaTokenMissing: !token,
3661
+ hyphaProxyUrlMissing: !proxyUrl
3662
+ };
3663
+ }
3664
+ if (mode === "custom") {
3665
+ return {
3666
+ mode,
3667
+ baseUrl: process.env.ANTHROPIC_BASE_URL,
3668
+ apiKeyPreview: redactKey(process.env.ANTHROPIC_API_KEY)
3669
+ };
3670
+ }
3671
+ return { mode: "login" };
3672
+ }
3673
+ function setClaudeAuthHyphaProxy(url) {
3674
+ if (!url || !url.trim()) {
3675
+ throw new Error(
3676
+ `A Hypha proxy URL is required (no default). Example: svamp daemon auth use-hypha-proxy ${EXAMPLE_HYPHA_PROXY_URL}`
3677
+ );
3678
+ }
3679
+ updateEnvFile({
3680
+ [MODE_KEY]: "hypha",
3681
+ [HYPHA_PROXY_URL_KEY]: normalizeProxyUrl(url),
3682
+ // Hypha mode resolves token live at spawn — no stored copy.
3683
+ ANTHROPIC_BASE_URL: void 0,
3684
+ ANTHROPIC_API_KEY: void 0
3685
+ });
3686
+ }
3687
+ function setClaudeAuthLogin() {
3688
+ updateEnvFile({
3689
+ [MODE_KEY]: void 0,
3690
+ [HYPHA_PROXY_URL_KEY]: void 0,
3691
+ ANTHROPIC_BASE_URL: void 0,
3692
+ ANTHROPIC_API_KEY: void 0
3693
+ });
3694
+ }
3695
+ function setClaudeAuthCustom(baseUrl, apiKey) {
3696
+ if (!baseUrl) throw new Error("ANTHROPIC_BASE_URL is required for custom mode");
3697
+ if (!apiKey) throw new Error("ANTHROPIC_API_KEY is required for custom mode");
3698
+ const trimmed = baseUrl.replace(/\/+$/, "");
3699
+ if (trimmed.endsWith("/v1")) {
3700
+ throw new Error(
3701
+ "ANTHROPIC_BASE_URL must not end in /v1 \u2014 the SDK appends it, producing double /v1/v1/messages"
3702
+ );
3703
+ }
3704
+ updateEnvFile({
3705
+ [MODE_KEY]: "custom",
3706
+ [HYPHA_PROXY_URL_KEY]: void 0,
3707
+ ANTHROPIC_BASE_URL: trimmed,
3708
+ ANTHROPIC_API_KEY: apiKey
3709
+ });
3710
+ }
3711
+ function applyClaudeProxyEnv(spawnEnv) {
3712
+ const mode = currentMode();
3713
+ if (mode === "hypha") {
3714
+ const proxyUrl = resolveHyphaProxyUrl();
3715
+ if (!proxyUrl) {
3716
+ delete spawnEnv.ANTHROPIC_BASE_URL;
3717
+ delete spawnEnv.ANTHROPIC_API_KEY;
3718
+ return `hypha mode but ${HYPHA_PROXY_URL_KEY} not configured \u2014 run \`svamp daemon auth use-hypha-proxy <URL>\`; falling back to login`;
3719
+ }
3720
+ const token = process.env.HYPHA_TOKEN;
3721
+ if (!token) {
3722
+ delete spawnEnv.ANTHROPIC_BASE_URL;
3723
+ delete spawnEnv.ANTHROPIC_API_KEY;
3724
+ return "hypha mode but HYPHA_TOKEN missing \u2014 falling back to login";
3725
+ }
3726
+ spawnEnv.ANTHROPIC_BASE_URL = proxyUrl;
3727
+ spawnEnv.ANTHROPIC_API_KEY = token;
3728
+ return `hypha proxy (${proxyUrl})`;
3729
+ }
3730
+ if (mode === "custom") {
3731
+ const url = process.env.ANTHROPIC_BASE_URL;
3732
+ const key = process.env.ANTHROPIC_API_KEY;
3733
+ if (!url || !key) {
3734
+ delete spawnEnv.ANTHROPIC_BASE_URL;
3735
+ delete spawnEnv.ANTHROPIC_API_KEY;
3736
+ return "custom mode but ANTHROPIC_BASE_URL/API_KEY missing \u2014 falling back to login";
3737
+ }
3738
+ spawnEnv.ANTHROPIC_BASE_URL = url;
3739
+ spawnEnv.ANTHROPIC_API_KEY = key;
3740
+ return `custom proxy (${url})`;
3741
+ }
3742
+ delete spawnEnv.ANTHROPIC_BASE_URL;
3743
+ delete spawnEnv.ANTHROPIC_API_KEY;
3744
+ return null;
3745
+ }
3746
+ const MANAGED_ENV_KEYS = Array.from(MANAGED_KEYS);
3747
+
3748
+ var claudeAuth = /*#__PURE__*/Object.freeze({
3749
+ __proto__: null,
3750
+ EXAMPLE_HYPHA_PROXY_URL: EXAMPLE_HYPHA_PROXY_URL,
3751
+ MANAGED_ENV_KEYS: MANAGED_ENV_KEYS,
3752
+ applyClaudeProxyEnv: applyClaudeProxyEnv,
3753
+ getClaudeAuthStatus: getClaudeAuthStatus,
3754
+ resolveHyphaProxyUrl: resolveHyphaProxyUrl,
3755
+ setClaudeAuthCustom: setClaudeAuthCustom,
3756
+ setClaudeAuthHyphaProxy: setClaudeAuthHyphaProxy,
3757
+ setClaudeAuthLogin: setClaudeAuthLogin,
3758
+ updateEnvFile: updateEnvFile
3759
+ });
3760
+
3568
3761
  const PARTICIPANTS_CHANNEL_ID = "sys-participants";
3569
3762
  function channelPublicView(c) {
3570
3763
  return { id: c.id, name: c.name, description: c.description, identity: { mode: c.identity?.mode }, action: c.action?.kind, bind: c.bind };
@@ -3897,6 +4090,8 @@ function createSessionStore(server, sessionId, initialMetadata, initialAgentStat
3897
4090
  ensureParticipantsChannel(initialMetadata.sharing);
3898
4091
  const forkClaudeOnce = async (prompt, claudeSessionId, cwd, maxTurns, timeoutMs) => {
3899
4092
  const { spawn } = await import('child_process');
4093
+ const forkEnv = { ...process.env, CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: "1" };
4094
+ applyClaudeProxyEnv(forkEnv);
3900
4095
  return new Promise((resolve) => {
3901
4096
  const child = spawn("claude", [
3902
4097
  "--print",
@@ -3915,7 +4110,7 @@ function createSessionStore(server, sessionId, initialMetadata, initialAgentStat
3915
4110
  cwd,
3916
4111
  timeout: timeoutMs,
3917
4112
  stdio: ["ignore", "pipe", "pipe"],
3918
- env: { ...process.env, CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: "1" }
4113
+ env: forkEnv
3919
4114
  });
3920
4115
  let stdout = "";
3921
4116
  let stderr = "";
@@ -8423,199 +8618,6 @@ function shouldIsolate(input) {
8423
8618
  return input.optionsSecurityContext !== null && input.optionsSecurityContext !== void 0;
8424
8619
  }
8425
8620
 
8426
- const EXAMPLE_HYPHA_PROXY_URL = "https://proxy.hypha.aicell.io";
8427
- const MODE_KEY = "SVAMP_CLAUDE_PROXY";
8428
- const HYPHA_PROXY_URL_KEY = "SVAMP_HYPHA_PROXY_URL";
8429
- const MANAGED_KEYS = /* @__PURE__ */ new Set([
8430
- MODE_KEY,
8431
- HYPHA_PROXY_URL_KEY,
8432
- "ANTHROPIC_BASE_URL",
8433
- "ANTHROPIC_API_KEY"
8434
- ]);
8435
- function normalizeProxyUrl(raw) {
8436
- const trimmed = raw.trim().replace(/\/+$/, "");
8437
- if (trimmed.endsWith("/v1")) {
8438
- throw new Error(
8439
- "Hypha proxy URL must not end in /v1 \u2014 the SDK appends it, producing double /v1/v1/messages"
8440
- );
8441
- }
8442
- return trimmed;
8443
- }
8444
- function resolveHyphaProxyUrl() {
8445
- const configured = (process.env[HYPHA_PROXY_URL_KEY] || "").trim();
8446
- if (!configured) return void 0;
8447
- try {
8448
- return normalizeProxyUrl(configured);
8449
- } catch {
8450
- return void 0;
8451
- }
8452
- }
8453
- function envFilePath() {
8454
- const svampHome = process.env.SVAMP_HOME || join(homedir(), ".svamp");
8455
- return join(svampHome, ".env");
8456
- }
8457
- function readEnvLines() {
8458
- const file = envFilePath();
8459
- if (!existsSync(file)) return [];
8460
- return readFileSync(file, "utf-8").split("\n");
8461
- }
8462
- function writeEnvLines(lines) {
8463
- const file = envFilePath();
8464
- const dir = join(file, "..");
8465
- if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
8466
- while (lines.length > 0 && lines[lines.length - 1].trim() === "") {
8467
- lines.pop();
8468
- }
8469
- writeFileSync(file, lines.join("\n") + "\n", "utf-8");
8470
- }
8471
- function updateEnvFile(updates) {
8472
- const lines = readEnvLines();
8473
- const kept = [];
8474
- const remainingUpdates = new Map(Object.entries(updates));
8475
- for (const line of lines) {
8476
- const trimmed = line.trim();
8477
- if (!trimmed || trimmed.startsWith("#")) {
8478
- kept.push(line);
8479
- continue;
8480
- }
8481
- const eq = trimmed.indexOf("=");
8482
- const key = eq === -1 ? trimmed : trimmed.slice(0, eq);
8483
- if (remainingUpdates.has(key)) {
8484
- const v = remainingUpdates.get(key);
8485
- remainingUpdates.delete(key);
8486
- if (v === void 0) continue;
8487
- kept.push(`${key}=${v}`);
8488
- continue;
8489
- }
8490
- kept.push(line);
8491
- }
8492
- for (const [key, v] of remainingUpdates) {
8493
- if (v === void 0) continue;
8494
- kept.push(`${key}=${v}`);
8495
- }
8496
- writeEnvLines(kept);
8497
- }
8498
- function currentMode() {
8499
- const raw = (process.env[MODE_KEY] || "").trim().toLowerCase();
8500
- if (raw === "hypha" || raw === "hypha-proxy") return "hypha";
8501
- if (raw === "custom") return "custom";
8502
- return "login";
8503
- }
8504
- function redactKey(key) {
8505
- if (!key) return void 0;
8506
- if (key.length <= 12) return "***";
8507
- return `${key.slice(0, 8)}\u2026${key.slice(-4)}`;
8508
- }
8509
- function getClaudeAuthStatus() {
8510
- const mode = currentMode();
8511
- if (mode === "hypha") {
8512
- const token = process.env.HYPHA_TOKEN;
8513
- const proxyUrl = resolveHyphaProxyUrl();
8514
- return {
8515
- mode,
8516
- baseUrl: proxyUrl,
8517
- apiKeyPreview: redactKey(token),
8518
- hyphaTokenMissing: !token,
8519
- hyphaProxyUrlMissing: !proxyUrl
8520
- };
8521
- }
8522
- if (mode === "custom") {
8523
- return {
8524
- mode,
8525
- baseUrl: process.env.ANTHROPIC_BASE_URL,
8526
- apiKeyPreview: redactKey(process.env.ANTHROPIC_API_KEY)
8527
- };
8528
- }
8529
- return { mode: "login" };
8530
- }
8531
- function setClaudeAuthHyphaProxy(url) {
8532
- if (!url || !url.trim()) {
8533
- throw new Error(
8534
- `A Hypha proxy URL is required (no default). Example: svamp daemon auth use-hypha-proxy ${EXAMPLE_HYPHA_PROXY_URL}`
8535
- );
8536
- }
8537
- updateEnvFile({
8538
- [MODE_KEY]: "hypha",
8539
- [HYPHA_PROXY_URL_KEY]: normalizeProxyUrl(url),
8540
- // Hypha mode resolves token live at spawn — no stored copy.
8541
- ANTHROPIC_BASE_URL: void 0,
8542
- ANTHROPIC_API_KEY: void 0
8543
- });
8544
- }
8545
- function setClaudeAuthLogin() {
8546
- updateEnvFile({
8547
- [MODE_KEY]: void 0,
8548
- [HYPHA_PROXY_URL_KEY]: void 0,
8549
- ANTHROPIC_BASE_URL: void 0,
8550
- ANTHROPIC_API_KEY: void 0
8551
- });
8552
- }
8553
- function setClaudeAuthCustom(baseUrl, apiKey) {
8554
- if (!baseUrl) throw new Error("ANTHROPIC_BASE_URL is required for custom mode");
8555
- if (!apiKey) throw new Error("ANTHROPIC_API_KEY is required for custom mode");
8556
- const trimmed = baseUrl.replace(/\/+$/, "");
8557
- if (trimmed.endsWith("/v1")) {
8558
- throw new Error(
8559
- "ANTHROPIC_BASE_URL must not end in /v1 \u2014 the SDK appends it, producing double /v1/v1/messages"
8560
- );
8561
- }
8562
- updateEnvFile({
8563
- [MODE_KEY]: "custom",
8564
- [HYPHA_PROXY_URL_KEY]: void 0,
8565
- ANTHROPIC_BASE_URL: trimmed,
8566
- ANTHROPIC_API_KEY: apiKey
8567
- });
8568
- }
8569
- function applyClaudeProxyEnv(spawnEnv) {
8570
- const mode = currentMode();
8571
- if (mode === "hypha") {
8572
- const proxyUrl = resolveHyphaProxyUrl();
8573
- if (!proxyUrl) {
8574
- delete spawnEnv.ANTHROPIC_BASE_URL;
8575
- delete spawnEnv.ANTHROPIC_API_KEY;
8576
- return `hypha mode but ${HYPHA_PROXY_URL_KEY} not configured \u2014 run \`svamp daemon auth use-hypha-proxy <URL>\`; falling back to login`;
8577
- }
8578
- const token = process.env.HYPHA_TOKEN;
8579
- if (!token) {
8580
- delete spawnEnv.ANTHROPIC_BASE_URL;
8581
- delete spawnEnv.ANTHROPIC_API_KEY;
8582
- return "hypha mode but HYPHA_TOKEN missing \u2014 falling back to login";
8583
- }
8584
- spawnEnv.ANTHROPIC_BASE_URL = proxyUrl;
8585
- spawnEnv.ANTHROPIC_API_KEY = token;
8586
- return `hypha proxy (${proxyUrl})`;
8587
- }
8588
- if (mode === "custom") {
8589
- const url = process.env.ANTHROPIC_BASE_URL;
8590
- const key = process.env.ANTHROPIC_API_KEY;
8591
- if (!url || !key) {
8592
- delete spawnEnv.ANTHROPIC_BASE_URL;
8593
- delete spawnEnv.ANTHROPIC_API_KEY;
8594
- return "custom mode but ANTHROPIC_BASE_URL/API_KEY missing \u2014 falling back to login";
8595
- }
8596
- spawnEnv.ANTHROPIC_BASE_URL = url;
8597
- spawnEnv.ANTHROPIC_API_KEY = key;
8598
- return `custom proxy (${url})`;
8599
- }
8600
- delete spawnEnv.ANTHROPIC_BASE_URL;
8601
- delete spawnEnv.ANTHROPIC_API_KEY;
8602
- return null;
8603
- }
8604
- const MANAGED_ENV_KEYS = Array.from(MANAGED_KEYS);
8605
-
8606
- var claudeAuth = /*#__PURE__*/Object.freeze({
8607
- __proto__: null,
8608
- EXAMPLE_HYPHA_PROXY_URL: EXAMPLE_HYPHA_PROXY_URL,
8609
- MANAGED_ENV_KEYS: MANAGED_ENV_KEYS,
8610
- applyClaudeProxyEnv: applyClaudeProxyEnv,
8611
- getClaudeAuthStatus: getClaudeAuthStatus,
8612
- resolveHyphaProxyUrl: resolveHyphaProxyUrl,
8613
- setClaudeAuthCustom: setClaudeAuthCustom,
8614
- setClaudeAuthHyphaProxy: setClaudeAuthHyphaProxy,
8615
- setClaudeAuthLogin: setClaudeAuthLogin,
8616
- updateEnvFile: updateEnvFile
8617
- });
8618
-
8619
8621
  function svampHome() {
8620
8622
  return process.env.SVAMP_HOME || join$1(homedir$1(), ".svamp");
8621
8623
  }
@@ -11612,7 +11614,7 @@ async function startDaemon(options) {
11612
11614
  saveExposedTunnels(list);
11613
11615
  }
11614
11616
  async function createExposedTunnel(spec) {
11615
- const { FrpcTunnel } = await import('./frpc-DGErIpoO.mjs');
11617
+ const { FrpcTunnel } = await import('./frpc-CDj2C0fs.mjs');
11616
11618
  const tunnel = new FrpcTunnel({
11617
11619
  name: spec.name,
11618
11620
  ports: spec.ports,
@@ -11632,7 +11634,7 @@ async function startDaemon(options) {
11632
11634
  return tunnel;
11633
11635
  }
11634
11636
  const tunnelRecreateState = /* @__PURE__ */ new Map();
11635
- const { ServeManager } = await import('./serveManager-BH8Suv9x.mjs');
11637
+ const { ServeManager } = await import('./serveManager-CU5NrVV-.mjs');
11636
11638
  const serveManager = new ServeManager(SVAMP_HOME, (msg) => logger.log(`[SERVE] ${msg}`), hyphaServerUrl);
11637
11639
  ensureAutoInstalledSkills(logger).catch(() => {
11638
11640
  });
@@ -12026,6 +12028,8 @@ ${v.guidance ? v.guidance + "\n" : ""}Criteria: ${v.criteria || "(none)"}
12026
12028
  const cwd = sessionMetadata.path || directory;
12027
12029
  const model = process.env.SVAMP_TOPIC_MODEL;
12028
12030
  try {
12031
+ const forkEnv = { ...process.env, CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: "1" };
12032
+ applyClaudeProxyEnv(forkEnv);
12029
12033
  const child = spawn$1("claude", [
12030
12034
  "--print",
12031
12035
  question,
@@ -12040,7 +12044,7 @@ ${v.guidance ? v.guidance + "\n" : ""}Criteria: ${v.criteria || "(none)"}
12040
12044
  "json",
12041
12045
  "--max-turns",
12042
12046
  "6"
12043
- ], { cwd, timeout: 6e4, stdio: ["ignore", "pipe", "pipe"], env: { ...process.env, CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: "1" } });
12047
+ ], { cwd, timeout: 6e4, stdio: ["ignore", "pipe", "pipe"], env: forkEnv });
12044
12048
  let stdout = "";
12045
12049
  child.stdout?.on("data", (d) => {
12046
12050
  stdout += d.toString();
@@ -13009,9 +13013,11 @@ ${capturedError}${buildClaudeErrorHint(capturedError)}`;
13009
13013
  "stream-json",
13010
13014
  "--verbose"
13011
13015
  ];
13016
+ const btwEnv = { ...process.env };
13017
+ applyClaudeProxyEnv(btwEnv);
13012
13018
  const btwProcess = spawn$1("claude", btwArgs, {
13013
13019
  cwd: directory,
13014
- env: { ...process.env },
13020
+ env: btwEnv,
13015
13021
  stdio: ["pipe", "pipe", "pipe"]
13016
13022
  });
13017
13023
  let btwResult = "";
@@ -13469,11 +13475,11 @@ ${capturedError}${buildClaudeErrorHint(capturedError)}`;
13469
13475
  });
13470
13476
  },
13471
13477
  onIssue: async (params) => {
13472
- const { issueRpc } = await import('./rpc-efgqAqwL.mjs');
13478
+ const { issueRpc } = await import('./rpc-DuAe8TKC.mjs');
13473
13479
  return issueRpc(params?.cwd || directory, params || {});
13474
13480
  },
13475
13481
  onWorkflow: async (params) => {
13476
- const { workflowRpc } = await import('./rpc-eRCuvMdD.mjs');
13482
+ const { workflowRpc } = await import('./rpc-B0_q0Ore.mjs');
13477
13483
  return workflowRpc(params?.cwd || directory, params || {});
13478
13484
  },
13479
13485
  onRipgrep: async (args, cwd) => {
@@ -13979,11 +13985,11 @@ ${capturedError}${buildClaudeErrorHint(capturedError)}`;
13979
13985
  });
13980
13986
  },
13981
13987
  onIssue: async (params) => {
13982
- const { issueRpc } = await import('./rpc-efgqAqwL.mjs');
13988
+ const { issueRpc } = await import('./rpc-DuAe8TKC.mjs');
13983
13989
  return issueRpc(params?.cwd || directory, params || {});
13984
13990
  },
13985
13991
  onWorkflow: async (params) => {
13986
- const { workflowRpc } = await import('./rpc-eRCuvMdD.mjs');
13992
+ const { workflowRpc } = await import('./rpc-B0_q0Ore.mjs');
13987
13993
  return workflowRpc(params?.cwd || directory, params || {});
13988
13994
  },
13989
13995
  onRipgrep: async (args, cwd) => {
@@ -14736,7 +14742,7 @@ ${capturedError}${buildClaudeErrorHint(capturedError)}`;
14736
14742
  const PING_TIMEOUT_MS = 15e3;
14737
14743
  const POST_RECONNECT_GRACE_MS = 2e4;
14738
14744
  const RECONNECT_JITTER_MS = 2500;
14739
- const { WorkflowScheduler } = await import('./scheduler-TtMT4mcq.mjs');
14745
+ const { WorkflowScheduler } = await import('./scheduler-CVODqtZb.mjs');
14740
14746
  const workflowScheduler = new WorkflowScheduler({
14741
14747
  projectRoots: () => {
14742
14748
  const dirs = /* @__PURE__ */ new Set();
@@ -15315,4 +15321,4 @@ var run = /*#__PURE__*/Object.freeze({
15315
15321
  writeStopMarker: writeStopMarker
15316
15322
  });
15317
15323
 
15318
- export { buildMachineDeps as $, machineToolsForRole as A, buildMachineTools as B, parseFrontmatter as C, getSkillsServer as D, getSkillsWorkspaceName as E, getSkillsCollectionName as F, fetchWithTimeout as G, searchSkills as H, SKILLS_DIR as I, getSkillInfo as J, downloadSkillFile as K, listSkillFiles as L, resolveModel as M, formatHandle as N, normalizeAllowedUser as O, loadSecurityContextConfig as P, resolveSecurityContext as Q, READ_ONLY_TOOLS as R, ServeAuth as S, buildSecurityContextFromFlags as T, mergeSecurityContexts as U, buildSessionShareUrl as V, computeOutboundHop as W, buildMachineShareUrl as X, parseHandle as Y, handleMatchesMetadata as Z, describeMisconfiguration as _, createSessionStore as a, composeSessionId as a0, generateFriendlyName as a1, generateHookSettings as a2, projectInfo as a3, DefaultTransport$1 as a4, acpBackend as a5, acpAgentConfig as a6, codexMcpBackend as a7, GeminiTransport$1 as a8, claudeAuth as a9, instanceConfig as aa, api as ab, run as ac, stopDaemon as b, connectToHypha as c, daemonStatus as d, clearStopMarker as e, stopMarkerExists as f, getHyphaServerUrl$1 as g, getFrpsSubdomainHost as h, getFrpsServerPort as i, getFrpsServerAddr as j, getHyphaServerUrl as k, hasCookieToken as l, resolveProjectRoot as m, getIssue as n, addComment as o, addIssue as p, listIssues as q, registerMachineService as r, startDaemon as s, searchIssues as t, updateIssue as u, cronMatches as v, summarize as w, shortId as x, loadMachineContext as y, buildMachineInstructions as z };
15324
+ export { buildMachineDeps as $, machineToolsForRole as A, buildMachineTools as B, parseFrontmatter as C, getSkillsServer as D, getSkillsWorkspaceName as E, getSkillsCollectionName as F, fetchWithTimeout as G, searchSkills as H, SKILLS_DIR as I, getSkillInfo as J, downloadSkillFile as K, listSkillFiles as L, resolveModel as M, formatHandle as N, normalizeAllowedUser as O, loadSecurityContextConfig as P, resolveSecurityContext as Q, READ_ONLY_TOOLS as R, ServeAuth as S, buildSecurityContextFromFlags as T, mergeSecurityContexts as U, buildSessionShareUrl as V, computeOutboundHop as W, buildMachineShareUrl as X, parseHandle as Y, handleMatchesMetadata as Z, describeMisconfiguration as _, createSessionStore as a, applyClaudeProxyEnv as a0, composeSessionId as a1, generateFriendlyName as a2, generateHookSettings as a3, claudeAuth as a4, projectInfo as a5, DefaultTransport$1 as a6, acpBackend as a7, acpAgentConfig as a8, codexMcpBackend as a9, GeminiTransport$1 as aa, instanceConfig as ab, api as ac, run as ad, stopDaemon as b, connectToHypha as c, daemonStatus as d, clearStopMarker as e, stopMarkerExists as f, getHyphaServerUrl$1 as g, getFrpsSubdomainHost as h, getFrpsServerPort as i, getFrpsServerAddr as j, getHyphaServerUrl as k, hasCookieToken as l, resolveProjectRoot as m, getIssue as n, addComment as o, addIssue as p, listIssues as q, registerMachineService as r, startDaemon as s, searchIssues as t, updateIssue as u, cronMatches as v, summarize as w, shortId as x, loadMachineContext as y, buildMachineInstructions as z };
@@ -1,4 +1,4 @@
1
- import{createRequire as _pkgrollCR}from"node:module";const require=_pkgrollCR(import.meta.url);import { a0 as composeSessionId, a1 as generateFriendlyName, c as connectToHypha, a as createSessionStore, r as registerMachineService, a2 as generateHookSettings } from './run-L9mNCmzT.mjs';
1
+ import{createRequire as _pkgrollCR}from"node:module";const require=_pkgrollCR(import.meta.url);import { a0 as applyClaudeProxyEnv, a1 as composeSessionId, a2 as generateFriendlyName, c as connectToHypha, a as createSessionStore, r as registerMachineService, a3 as generateHookSettings } from './run-DZLwKdGH.mjs';
2
2
  import os from 'node:os';
3
3
  import { resolve, join } from 'node:path';
4
4
  import { existsSync, readFileSync, watch } from 'node:fs';
@@ -190,11 +190,14 @@ async function runLocalMode(opts) {
190
190
  }
191
191
  process.stdin.pause();
192
192
  return new Promise((resolve) => {
193
+ const spawnEnv = { ...process.env };
194
+ const proxyDesc = applyClaudeProxyEnv(spawnEnv);
195
+ if (proxyDesc) log(`[local] Claude auth: ${proxyDesc}`);
193
196
  const child = spawn(claudeBin, args, {
194
197
  stdio: ["inherit", "inherit", "inherit"],
195
198
  cwd,
196
199
  signal: opts.abort,
197
- env: process.env
200
+ env: spawnEnv
198
201
  });
199
202
  child.on("error", (err) => {
200
203
  log(`[local] Spawn error: ${err.message}`);
@@ -1,5 +1,5 @@
1
1
  import { spawn } from 'node:child_process';
2
- import { m as resolveProjectRoot, v as cronMatches } from './run-L9mNCmzT.mjs';
2
+ import { m as resolveProjectRoot, v as cronMatches } from './run-DZLwKdGH.mjs';
3
3
  import { l as listWorkflows, i as isWorkflowEnabled, c as workflowCrons, w as workflowSteps } from './store-DEZ8e-uE.mjs';
4
4
  import 'os';
5
5
  import 'fs/promises';
@@ -54,7 +54,7 @@ async function handleServeCommand() {
54
54
  }
55
55
  }
56
56
  async function serveAdd(args, machineId) {
57
- const { connectAndGetMachine } = await import('./commands-DhWWYPCu.mjs');
57
+ const { connectAndGetMachine } = await import('./commands-CkxVt5V0.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-DhWWYPCu.mjs');
96
+ const { connectAndGetMachine } = await import('./commands-CkxVt5V0.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-DhWWYPCu.mjs');
185
+ const { connectAndGetMachine } = await import('./commands-CkxVt5V0.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-DhWWYPCu.mjs');
205
+ const { connectAndGetMachine } = await import('./commands-CkxVt5V0.mjs');
206
206
  const all = hasFlag(args, "--all", "-a");
207
207
  const json = hasFlag(args, "--json");
208
208
  const sessionId = getFlag(args, "--session");
@@ -235,7 +235,7 @@ async function serveList(args, machineId) {
235
235
  }
236
236
  }
237
237
  async function serveInfo(machineId) {
238
- const { connectAndGetMachine } = await import('./commands-DhWWYPCu.mjs');
238
+ const { connectAndGetMachine } = await import('./commands-CkxVt5V0.mjs');
239
239
  const { machine, server } = await connectAndGetMachine(machineId);
240
240
  try {
241
241
  const info = await machine.serveInfo();
@@ -4,7 +4,7 @@ import * as fs from 'fs';
4
4
  import * as http from 'http';
5
5
  import * as net from 'net';
6
6
  import * as path from 'path';
7
- import { k as getHyphaServerUrl, S as ServeAuth, l as hasCookieToken } from './run-L9mNCmzT.mjs';
7
+ import { k as getHyphaServerUrl, S as ServeAuth, l as hasCookieToken } from './run-DZLwKdGH.mjs';
8
8
  import 'os';
9
9
  import 'fs/promises';
10
10
  import 'url';
@@ -733,7 +733,7 @@ class ServeManager {
733
733
  const mount = this.mounts.get(mountName);
734
734
  const subdomainOverride = mount?.access === "link" && mount.linkToken ? /* @__PURE__ */ new Map([[this.port, buildLinkSubdomain(subdomainSafe, mount.linkToken)]]) : void 0;
735
735
  try {
736
- const { FrpcTunnel } = await import('./frpc-DGErIpoO.mjs');
736
+ const { FrpcTunnel } = await import('./frpc-CDj2C0fs.mjs');
737
737
  let tunnel;
738
738
  tunnel = new FrpcTunnel({
739
739
  name: tunnelName,
@@ -1,4 +1,4 @@
1
- import { R as READ_ONLY_TOOLS, y as loadMachineContext, z as buildMachineInstructions, A as machineToolsForRole, B as buildMachineTools } from './run-L9mNCmzT.mjs';
1
+ import { R as READ_ONLY_TOOLS, y as loadMachineContext, z as buildMachineInstructions, A as machineToolsForRole, B as buildMachineTools } from './run-DZLwKdGH.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.185",
3
+ "version": "0.2.187",
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 && mkdir -p bin/skills && cp -r ../../skills/artifact bin/skills/artifact && cp -r ../../skills/loop bin/skills/loop && cp -r ../../skills/crew bin/skills/crew && 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-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-loop-activation.mjs && npx tsx test/test-message-helpers.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-output-formatters.mjs && npx tsx test/test-inbox-guard.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-machine-service-logic.mjs && npx tsx test/test-interactive-helpers.mjs && npx tsx test/test-codex-backend.mjs && npx tsx test/test-acp-backend.mjs && npx tsx test/test-acp-bridge.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-session-consolidation.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-close-gate.mjs && npx tsx test/test-issue-rpc.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-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-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-channel-async-reply.mjs && npx tsx test/test-channel-binding.mjs && npx tsx test/test-channel-identity.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-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",
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-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-loop-activation.mjs && npx tsx test/test-message-helpers.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-btw-proxy-env.mjs && npx tsx test/test-output-formatters.mjs && npx tsx test/test-inbox-guard.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-machine-service-logic.mjs && npx tsx test/test-interactive-helpers.mjs && npx tsx test/test-codex-backend.mjs && npx tsx test/test-acp-backend.mjs && npx tsx test/test-acp-bridge.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-session-consolidation.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-close-gate.mjs && npx tsx test/test-issue-rpc.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-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-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-channel-async-reply.mjs && npx tsx test/test-channel-binding.mjs && npx tsx test/test-channel-identity.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-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",
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",