svamp-cli 0.2.331 → 0.2.333

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 (28) hide show
  1. package/dist/{adminCommands-DQ6TQAXa.mjs → adminCommands-BMzwjOct.mjs} +1 -1
  2. package/dist/{agentCommands-CovUtOYv.mjs → agentCommands-BVz1k2R2.mjs} +35 -6
  3. package/dist/{auth-CMWkQmps.mjs → auth-D0v5RwMJ.mjs} +1 -1
  4. package/dist/{cli-Cd_6Xp2x.mjs → cli-DmjtuskT.mjs} +93 -77
  5. package/dist/cli.mjs +2 -2
  6. package/dist/{commands-B-PLeiIB.mjs → commands-BOGd7CmP.mjs} +14 -4
  7. package/dist/{commands-CpXKePYP.mjs → commands-C3r_GhOb.mjs} +3 -3
  8. package/dist/{commands-D2he7eNq.mjs → commands-CPTWYXJD.mjs} +3 -3
  9. package/dist/{commands-DCTCLAPA.mjs → commands-CYgkxHsf.mjs} +3 -3
  10. package/dist/{commands-OwmAlnGb.mjs → commands-CwoMu1mu.mjs} +1 -1
  11. package/dist/{commands-CWkWkrZF.mjs → commands-DKouDroK.mjs} +1 -1
  12. package/dist/{commands-BCWHfbuw.mjs → commands-DcQMh7oz.mjs} +29 -18
  13. package/dist/{commands-Bv52WaQ0.mjs → commands-DmPwUOqX.mjs} +11 -11
  14. package/dist/{fleet-DrLOwe6r.mjs → fleet-5foIrEnM.mjs} +3 -3
  15. package/dist/{headlessCli-CDjGYUpj.mjs → headlessCli-BLZSVVlt.mjs} +2 -2
  16. package/dist/index.mjs +1 -1
  17. package/dist/{notifyCommands-DSRd8YaE.mjs → notifyCommands-DADOx-j_.mjs} +1 -1
  18. package/dist/package-By6uMuic.mjs +64 -0
  19. package/dist/{pinnedClaudeCode-BO0Qs_kE.mjs → pinnedClaudeCode-C43KnZ-Q.mjs} +27 -6
  20. package/dist/{rpc-OmhzsDGP.mjs → rpc-CoPRGZkJ.mjs} +2 -1
  21. package/dist/{rpc-CVBhR9Cj.mjs → rpc-UomHF39a.mjs} +13 -1
  22. package/dist/{run-DcwSfoyP.mjs → run-CkEjIO1m.mjs} +1 -1
  23. package/dist/{run-CSNL62FQ.mjs → run-PXdghhjy.mjs} +592 -147
  24. package/dist/{scheduler-DDw3YLzH.mjs → scheduler-gMWmsAgp.mjs} +1 -1
  25. package/dist/{serveCommands-BQ0jhFUR.mjs → serveCommands-Cklx2iuZ.mjs} +10 -10
  26. package/dist/{sideband-S3ycJa01.mjs → sideband-DXyAkIaB.mjs} +1 -1
  27. package/package.json +4 -4
  28. package/dist/package-C23qFmVz.mjs +0 -64
@@ -1,9 +1,9 @@
1
1
  import { existsSync } from 'node:fs';
2
2
  import { join, resolve } from 'node:path';
3
- import { connectAndGetMachine, resolveSessionId, createWorktree, connectAndResolveSession } from './commands-CWkWkrZF.mjs';
3
+ import { connectAndGetMachine, resolveSessionId, createWorktree, connectAndResolveSession } from './commands-DKouDroK.mjs';
4
4
  import { execFileSync } from 'node:child_process';
5
- import { ah as withFileLock, u as updateIssue, j as addComment, k as addIssue, e as shortId } from './run-CSNL62FQ.mjs';
6
- import { w as wantsHelp } from './cli-Cd_6Xp2x.mjs';
5
+ import { aj as withFileLock, u as updateIssue, k as addComment, l as addIssue, e as shortId } from './run-PXdghhjy.mjs';
6
+ import { w as wantsHelp } from './cli-DmjtuskT.mjs';
7
7
  import 'node:os';
8
8
  import 'os';
9
9
  import 'fs/promises';
@@ -1,10 +1,10 @@
1
- import { connectAndResolveSession } from './commands-CWkWkrZF.mjs';
2
- import { w as wantsHelp } from './cli-Cd_6Xp2x.mjs';
1
+ import { connectAndResolveSession } from './commands-DKouDroK.mjs';
2
+ import { w as wantsHelp } from './cli-DmjtuskT.mjs';
3
3
  import 'node:fs';
4
4
  import 'node:child_process';
5
5
  import 'node:path';
6
6
  import 'node:os';
7
- import './run-CSNL62FQ.mjs';
7
+ import './run-PXdghhjy.mjs';
8
8
  import 'os';
9
9
  import 'fs/promises';
10
10
  import 'fs';
@@ -1,12 +1,12 @@
1
1
  import { writeFileSync, readFileSync } from 'fs';
2
2
  import { resolve } from 'path';
3
- import { connectAndGetMachine } from './commands-CWkWkrZF.mjs';
4
- import { w as wantsHelp } from './cli-Cd_6Xp2x.mjs';
3
+ import { connectAndGetMachine } from './commands-DKouDroK.mjs';
4
+ import { w as wantsHelp } from './cli-DmjtuskT.mjs';
5
5
  import 'node:fs';
6
6
  import 'node:child_process';
7
7
  import 'node:path';
8
8
  import 'node:os';
9
- import './run-CSNL62FQ.mjs';
9
+ import './run-PXdghhjy.mjs';
10
10
  import 'os';
11
11
  import 'fs/promises';
12
12
  import 'url';
@@ -1,7 +1,7 @@
1
1
  import os from 'os';
2
2
  import fs__default from 'fs';
3
3
  import { resolve, join, relative } from 'path';
4
- import { T as parseFrontmatter, U as getSkillsServer, V as getSkillsWorkspaceName, W as getSkillsCollectionName, X as fetchWithTimeout, Y as searchSkills, Z as SKILLS_DIR, _ as getSkillInfo, $ as downloadSkillFile, a0 as listSkillFiles } from './run-CSNL62FQ.mjs';
4
+ import { V as parseFrontmatter, W as getSkillsServer, X as getSkillsWorkspaceName, Y as getSkillsCollectionName, Z as fetchWithTimeout, _ as searchSkills, $ as SKILLS_DIR, a0 as getSkillInfo, a1 as downloadSkillFile, a2 as listSkillFiles } from './run-PXdghhjy.mjs';
5
5
  import 'fs/promises';
6
6
  import 'url';
7
7
  import 'child_process';
@@ -2,7 +2,7 @@ import { existsSync, readFileSync, writeFileSync } from 'node:fs';
2
2
  import { execSync, execFileSync } from 'node:child_process';
3
3
  import { basename, resolve, join, isAbsolute } from 'node:path';
4
4
  import os from 'node:os';
5
- import { a2 as formatHandle, a3 as normalizeAllowedUser, a4 as loadSecurityContextConfig, a5 as resolveSecurityContext, a6 as buildSecurityContextFromFlags, a7 as mergeSecurityContexts, c as connectToHypha, a8 as buildSessionShareUrl, a9 as computeOutboundHop, e as shortId, aa as registerAwaitingReply, ab as buildMachineShareUrl, ac as parseHandle, ad as handleMatchesMetadata } from './run-CSNL62FQ.mjs';
5
+ import { a4 as formatHandle, a5 as normalizeAllowedUser, a6 as loadSecurityContextConfig, a7 as resolveSecurityContext, a8 as buildSecurityContextFromFlags, a9 as mergeSecurityContexts, c as connectToHypha, aa as buildSessionShareUrl, ab as computeOutboundHop, e as shortId, ac as registerAwaitingReply, ad as buildMachineShareUrl, ae as parseHandle, af as handleMatchesMetadata } from './run-PXdghhjy.mjs';
6
6
  import 'os';
7
7
  import 'fs/promises';
8
8
  import 'fs';
@@ -1,8 +1,7 @@
1
- import { execSync } from 'node:child_process';
2
1
  import { existsSync, readFileSync } from 'node:fs';
3
2
  import { join } from 'node:path';
4
- import { f as flushAndExit } from './cli-Cd_6Xp2x.mjs';
5
- import { f as resolveProjectRoot, n as searchIssues, l as listIssues, m as isPendingIssue, i as resumeIssue, p as pauseIssue, j as addComment, u as updateIssue, h as getIssue, o as isVisibleTo, I as summarize, k as addIssue } from './run-CSNL62FQ.mjs';
3
+ import { f as flushAndExit } from './cli-DmjtuskT.mjs';
4
+ import { f as resolveProjectRoot, o as searchIssues, m as listIssues, n as isPendingIssue, j as resumeIssue, p as pauseIssue, k as addComment, u as updateIssue, h as getIssue, i as checkVerifyCommand, q as isVisibleTo, J as summarize, l as addIssue } from './run-PXdghhjy.mjs';
6
5
  import './serviceManager-hlOVxkhW.mjs';
7
6
  import 'os';
8
7
  import 'fs/promises';
@@ -12,6 +11,7 @@ import 'url';
12
11
  import 'child_process';
13
12
  import 'crypto';
14
13
  import 'node:crypto';
14
+ import 'node:child_process';
15
15
  import 'util';
16
16
  import 'http';
17
17
  import 'net';
@@ -42,9 +42,17 @@ function has(args, name) {
42
42
  return args.includes(name);
43
43
  }
44
44
  function loopActiveForCwd(cwd = process.cwd(), sid = process.env.SVAMP_SESSION_ID) {
45
+ const roots = [cwd];
46
+ try {
47
+ const root = resolveProjectRoot(cwd);
48
+ if (root && root !== cwd) roots.push(root);
49
+ } catch {
50
+ }
45
51
  const candidates = [];
46
- if (sid) candidates.push(join(cwd, ".svamp", sid, "loop", "loop-state.json"));
47
- candidates.push(join(cwd, ".claude", "loop", "loop-state.json"));
52
+ for (const base of roots) {
53
+ if (sid) candidates.push(join(base, ".svamp", sid, "loop", "loop-state.json"));
54
+ candidates.push(join(base, ".claude", "loop", "loop-state.json"));
55
+ }
48
56
  for (const p of candidates) {
49
57
  try {
50
58
  if (existsSync(p)) {
@@ -233,13 +241,11 @@ ${issue.body}`);
233
241
  if (has(rest, "--force")) {
234
242
  console.error(`\u26A0 #${id}: closing WITHOUT running verify-cmd (--force): \`${vc}\``);
235
243
  } else {
236
- try {
237
- execSync(vc, { cwd: root, stdio: "pipe", timeout: 6e5, maxBuffer: 64 * 1024 * 1024 });
238
- } catch (e) {
239
- const tail = (String(e?.stdout || "") + String(e?.stderr || "")).split("\n").slice(-15).join("\n").trim();
244
+ const res = checkVerifyCommand(root, current);
245
+ if (!res.ok) {
240
246
  console.error(`Refusing to close #${id}: its verify-cmd failed \u2014 the fix is not verified.
241
- $ ${vc}
242
- ${tail}
247
+ $ ${res.cmd}
248
+ ${res.output || ""}
243
249
  (Fix the issue, or pass --force to override.)`);
244
250
  process.exit(1);
245
251
  }
@@ -474,19 +480,24 @@ the user explicitly reserved): re-run with \`--blocked "<the specific blocker>"\
474
480
  "",
475
481
  ' add ["<title>"] [--ready] [--label x] [--verify-cmd "cmd"] [--scope project|session] [--body "\u2026"]',
476
482
  " # title optional \u2014 if omitted, the first line of --body becomes the title",
477
- " list [--status ready|in_progress|paused|archived|all] [--label x] [--scope \u2026] [--session <id>] [--json]",
483
+ " list [--status ready|in_progress|paused|archived|all] [--label x] [--scope \u2026] [--session <id>] [--mine] [--all] [--json]",
478
484
  " show <id> [--json]",
479
- " ready <id> | close <id> (\u2192 archived) | reopen <id> | archive <id> # lifecycle: ready \u2192 in_progress \u2192 archived",
480
- " work <id> [--branch <name>] # mark in-progress (optionally on a branch; merge to main before close)",
481
- " triage <id> [--title \u2026] [--label x] [--inline|--crew] [--verify-cmd \u2026|--verify \u2026] [--body \u2026]",
482
- " edit <id> [--title \u2026] [--label x] [--verify-cmd \u2026] [--no-verify] [--status \u2026] [--body \u2026]",
485
+ " ready <id> | close <id> [--force] | reopen <id> | archive <id> # lifecycle: ready \u2192 in_progress \u2192 archived",
486
+ " # close RUNS the verify-cmd and refuses if it fails; --force closes anyway \u2014",
487
+ " # use it ONLY for a duplicate or obsolete item, never to skip a real verification.",
488
+ " work <id> [--branch <name>] [--session <id>] # mark in-progress (optionally on a branch; merge to main before close)",
489
+ " # OWNERSHIP: starting work CLAIMS an unowned project-scope issue for the running session,",
490
+ " # so two sessions do not race the same item. `edit <id> --unclaim` hands it back;",
491
+ " # `--session <id>` reassigns it. `list`/`pending --mine` show only what you own.",
492
+ " triage <id> [--title \u2026] [--label x] [--inline|--crew] [--verify-cmd \u2026|--verify \u2026] [--body \u2026] [--manual]",
493
+ " edit <id> [--title \u2026] [--label x] [--verify-cmd \u2026] [--no-verify] [--status \u2026] [--body \u2026] [--unclaim|--session <id>]",
483
494
  ' comment <id> "<text>" # append a follow-up to the issue',
484
495
  ' pause <id> --blocked "<reason>" [--question "\u2026"] [--option "A" --option "B"]',
485
496
  " # ONLY when genuinely blocked (needs a secret/access/sign-off you cannot get).",
486
497
  " # A paused issue drops out of `pending`, so a loop converges cleanly instead",
487
498
  ' # of spinning on it. NOT for "please check my work" \u2014 close finished work.',
488
- " resume <id> # un-pause (the user answering a --question resumes it automatically)",
489
- " pending [--session <id>] # exit 0 if no actionable (ready/in_progress) issues \u2014 the loop oracle",
499
+ ' resume <id> [--answer "\u2026"] # un-pause (the user answering a --question resumes it automatically)',
500
+ " pending [--session <id>] [--mine] # exit 0 if no actionable (ready/in_progress) issues \u2014 the loop oracle",
490
501
  ' search "<query>" [--json]',
491
502
  " guide <triage|work> # the triage / work-loop procedure (so triggers can stay short)"
492
503
  ].join("\n"));
@@ -1,6 +1,6 @@
1
1
  import * as path from 'path';
2
- import { w as wantsHelp } from './cli-Cd_6Xp2x.mjs';
3
- import './run-CSNL62FQ.mjs';
2
+ import { w as wantsHelp } from './cli-DmjtuskT.mjs';
3
+ import './run-PXdghhjy.mjs';
4
4
  import 'os';
5
5
  import 'fs/promises';
6
6
  import 'fs';
@@ -83,7 +83,7 @@ async function serviceExpose(args) {
83
83
  process.exit(1);
84
84
  }
85
85
  if (foreground) {
86
- const { runFrpcTunnel } = await import('./run-CSNL62FQ.mjs').then(function (n) { return n.ap; });
86
+ const { runFrpcTunnel } = await import('./run-PXdghhjy.mjs').then(function (n) { return n.ar; });
87
87
  await runFrpcTunnel(name, ports, void 0, {
88
88
  group,
89
89
  groupKey,
@@ -93,7 +93,7 @@ async function serviceExpose(args) {
93
93
  });
94
94
  return;
95
95
  }
96
- const { connectAndGetMachine } = await import('./commands-CWkWkrZF.mjs');
96
+ const { connectAndGetMachine } = await import('./commands-DKouDroK.mjs');
97
97
  const { server, machine } = await connectAndGetMachine();
98
98
  try {
99
99
  const status = await machine.tunnelStart({
@@ -115,7 +115,7 @@ async function serviceExpose(args) {
115
115
  console.log(` port ${port}: ${url}`);
116
116
  }
117
117
  if (process.env.SVAMP_SESSION_ID) {
118
- const { autoAddSessionLink } = await import('./agentCommands-CovUtOYv.mjs');
118
+ const { autoAddSessionLink } = await import('./agentCommands-BVz1k2R2.mjs');
119
119
  let added = 0;
120
120
  for (const [port, url] of urlEntries) {
121
121
  const label = urlEntries.length > 1 ? `${name}:${port}` : name;
@@ -151,8 +151,8 @@ async function serviceServe(args) {
151
151
  const resolvedDir = path.resolve(directory);
152
152
  console.log(`Serving ${resolvedDir}`);
153
153
  const http = await import('http');
154
- const { serveStaticMount } = await import('./run-CSNL62FQ.mjs').then(function (n) { return n.aq; });
155
- const { getFreePort } = await import('./run-CSNL62FQ.mjs').then(function (n) { return n.ap; });
154
+ const { serveStaticMount } = await import('./run-PXdghhjy.mjs').then(function (n) { return n.as; });
155
+ const { getFreePort } = await import('./run-PXdghhjy.mjs').then(function (n) { return n.ar; });
156
156
  const server = http.createServer((req, res) => {
157
157
  const u = new URL(req.url || "/", "http://127.0.0.1");
158
158
  let rel = u.pathname;
@@ -175,7 +175,7 @@ async function serviceServe(args) {
175
175
  resolve(18080);
176
176
  });
177
177
  });
178
- const { runFrpcTunnel } = await import('./run-CSNL62FQ.mjs').then(function (n) { return n.ap; });
178
+ const { runFrpcTunnel } = await import('./run-PXdghhjy.mjs').then(function (n) { return n.ar; });
179
179
  void server;
180
180
  await runFrpcTunnel(name, [servePort]);
181
181
  } catch (err) {
@@ -185,7 +185,7 @@ async function serviceServe(args) {
185
185
  }
186
186
  async function serviceList(_args) {
187
187
  try {
188
- const { connectAndGetMachine } = await import('./commands-CWkWkrZF.mjs');
188
+ const { connectAndGetMachine } = await import('./commands-DKouDroK.mjs');
189
189
  const { server, machine } = await connectAndGetMachine();
190
190
  try {
191
191
  const tunnels = await machine.tunnelList({});
@@ -225,11 +225,11 @@ async function serviceDelete(args) {
225
225
  process.exit(1);
226
226
  }
227
227
  try {
228
- const { connectAndGetMachine } = await import('./commands-CWkWkrZF.mjs');
228
+ const { connectAndGetMachine } = await import('./commands-DKouDroK.mjs');
229
229
  const { server, machine } = await connectAndGetMachine();
230
230
  try {
231
231
  await machine.tunnelStop({ name });
232
- const { removeSessionLinkByService } = await import('./agentCommands-CovUtOYv.mjs');
232
+ const { removeSessionLinkByService } = await import('./agentCommands-BVz1k2R2.mjs');
233
233
  removeSessionLinkByService("tunnel", name);
234
234
  console.log(`Stopped tunnel '${name}'.`);
235
235
  } catch (err) {
@@ -1,8 +1,8 @@
1
1
  import { existsSync, readFileSync } from 'node:fs';
2
2
  import { join } from 'node:path';
3
3
  import os from 'node:os';
4
- import { ae as PINNED_CODEX_VERSION, c as connectToHypha } from './run-CSNL62FQ.mjs';
5
- import { PINNED_CLAUDE_CODE_VERSION } from './pinnedClaudeCode-BO0Qs_kE.mjs';
4
+ import { ag as PINNED_CODEX_VERSION, c as connectToHypha } from './run-PXdghhjy.mjs';
5
+ import { PINNED_CLAUDE_CODE_VERSION } from './pinnedClaudeCode-C43KnZ-Q.mjs';
6
6
  import 'os';
7
7
  import 'fs/promises';
8
8
  import 'fs';
@@ -23,7 +23,7 @@ import 'node:fs/promises';
23
23
  import 'yaml';
24
24
 
25
25
  const KIMI_NPM_PACKAGE = "@moonshot-ai/kimi-code";
26
- const PINNED_KIMI_VERSION = "0.36.1";
26
+ const PINNED_KIMI_VERSION = "0.38.0";
27
27
 
28
28
  const SVAMP_HOME = process.env.SVAMP_HOME || join(os.homedir(), ".svamp");
29
29
  const DAEMON_STATE_FILE = join(SVAMP_HOME, "daemon.state.json");
@@ -1,5 +1,5 @@
1
- import { a1 as resolveModel, ai as describeMisconfiguration, aj as buildMachineDeps } from './run-CSNL62FQ.mjs';
2
- import { handleRealtimeEvent, initMachineVoiceSession } from './sideband-S3ycJa01.mjs';
1
+ import { a3 as resolveModel, ak as describeMisconfiguration, al as buildMachineDeps } from './run-PXdghhjy.mjs';
2
+ import { handleRealtimeEvent, initMachineVoiceSession } from './sideband-DXyAkIaB.mjs';
3
3
  import { WebSocket } from 'ws';
4
4
  import { execSync, spawn } from 'child_process';
5
5
  import 'os';
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- export { c as connectToHypha, a as createSessionStore, d as daemonStatus, g as getHyphaServerUrl, r as registerMachineService, s as startDaemon, b as stopDaemon } from './run-CSNL62FQ.mjs';
1
+ export { c as connectToHypha, a as createSessionStore, d as daemonStatus, g as getHyphaServerUrl, r as registerMachineService, s as startDaemon, b as stopDaemon } from './run-PXdghhjy.mjs';
2
2
  import 'os';
3
3
  import 'fs/promises';
4
4
  import 'fs';
@@ -1,4 +1,4 @@
1
- import { c as connectToHypha, S as SharingNotificationSync, K as parseJwtEmail } from './run-CSNL62FQ.mjs';
1
+ import { c as connectToHypha, S as SharingNotificationSync, M as parseJwtEmail } from './run-PXdghhjy.mjs';
2
2
  import { randomUUID } from 'node:crypto';
3
3
  import { existsSync, readFileSync } from 'node:fs';
4
4
  import { join } from 'node:path';
@@ -0,0 +1,64 @@
1
+ var name = "svamp-cli";
2
+ var version = "0.2.333";
3
+ var description = "Svamp CLI — AI workspace daemon on Hypha Cloud";
4
+ var author = "Amun AI AB";
5
+ var license = "SEE LICENSE IN LICENSE";
6
+ var type = "module";
7
+ var bin = {
8
+ svamp: "./bin/svamp.mjs"
9
+ };
10
+ var files = [
11
+ "dist",
12
+ "bin"
13
+ ];
14
+ var main = "./dist/index.mjs";
15
+ var exports$1 = {
16
+ ".": "./dist/index.mjs",
17
+ "./cli": "./dist/cli.mjs"
18
+ };
19
+ var scripts = {
20
+ 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",
21
+ typecheck: "tsc --noEmit",
22
+ test: "node test/with-timeout.mjs 420 npx tsx test/test-context-window.mjs && node test/with-timeout.mjs 420 npx tsx test/test-ratelimit-retry.mjs && node test/with-timeout.mjs 420 npx tsx test/test-completed-requests.mjs && node test/with-timeout.mjs 420 npx tsx test/test-reconnect-health.mjs &&node test/with-timeout.mjs 420 npx tsx test/test-fleet-version-parse.mjs &&node test/with-timeout.mjs 420 npx tsx test/test-instance-config.mjs && node test/with-timeout.mjs 420 npx tsx test/test-authorize.mjs && node test/with-timeout.mjs 420 npx tsx test/test-normalize-allowed-user.mjs && node test/with-timeout.mjs 420 npx tsx test/test-share-url.mjs && node test/with-timeout.mjs 420 npx tsx test/test-update-sharing-normalization.mjs && node test/with-timeout.mjs 420 npx tsx test/test-sharing-notify-sync.mjs && node test/with-timeout.mjs 420 npx tsx test/test-sharing-notify-resolve.mjs && node test/with-timeout.mjs 420 npx tsx test/test-staged-homes-sweep.mjs && node test/with-timeout.mjs 420 npx tsx test/test-session-helpers.mjs && node test/with-timeout.mjs 420 npx tsx test/test-cli-routing.mjs && node test/with-timeout.mjs 420 npx tsx test/test-security-context.mjs && node test/with-timeout.mjs 420 npx tsx test/test-isolation-decision.mjs && node test/with-timeout.mjs 420 npx tsx test/test-message-helpers.mjs && node test/with-timeout.mjs 420 npx tsx test/test-stdin-delivery.mjs && node test/with-timeout.mjs 420 npx tsx test/test-agent-config.mjs && node test/with-timeout.mjs 420 npx tsx test/test-wrap-command.mjs && node test/with-timeout.mjs 420 npx tsx test/test-credential-staging.mjs && node test/with-timeout.mjs 420 npx tsx test/test-claude-auth.mjs && node test/with-timeout.mjs 420 npx tsx test/test-backend-accounts.mjs && node test/with-timeout.mjs 420 npx tsx test/test-codex-force-model.mjs && node test/with-timeout.mjs 420 npx tsx test/test-backend-oauth.mjs && node test/with-timeout.mjs 420 npx tsx test/test-btw-proxy-env.mjs && node test/with-timeout.mjs 420 npx tsx test/test-output-formatters.mjs && node test/with-timeout.mjs 420 npx tsx test/test-inbox-guard.mjs && node test/with-timeout.mjs 420 npx tsx test/test-user-events.mjs && node test/with-timeout.mjs 420 npx tsx test/test-migrate-children.mjs && node test/with-timeout.mjs 420 npx tsx test/test-outpost-install.mjs && node test/with-timeout.mjs 420 npx tsx test/test-outpost-setup.mjs && node test/with-timeout.mjs 420 npx tsx test/test-outpost-pairing.mjs && node test/with-timeout.mjs 420 npx tsx test/test-outpost-coordinator.mjs && node test/with-timeout.mjs 420 npx tsx test/e2e-outpost-transport.mjs && node test/with-timeout.mjs 420 npx tsx test/test-inbox-reconcile.mjs && node test/with-timeout.mjs 420 npx tsx test/test-auto-topic.mjs && node test/with-timeout.mjs 420 npx tsx test/test-project-info.mjs && node test/with-timeout.mjs 420 npx tsx test/test-agent-types.mjs && node test/with-timeout.mjs 420 npx tsx test/test-transport.mjs && node test/with-timeout.mjs 420 npx tsx test/test-session-update-handlers.mjs && node test/with-timeout.mjs 420 npx tsx test/test-session-scanner.mjs && node test/with-timeout.mjs 420 npx tsx test/test-hypha-client.mjs && node test/with-timeout.mjs 420 npx tsx test/test-hook-settings.mjs && node test/with-timeout.mjs 420 npx tsx test/test-session-service-logic.mjs && node test/with-timeout.mjs 420 npx tsx test/test-daemon-persistence.mjs && node test/with-timeout.mjs 420 npx tsx test/test-detect-isolation.mjs && node test/with-timeout.mjs 420 npx tsx test/test-isolation-disable.mjs && node test/with-timeout.mjs 420 npx tsx test/test-machine-service-logic.mjs && node test/with-timeout.mjs 420 npx tsx test/test-machine-session-visibility.mjs && node test/with-timeout.mjs 420 npx tsx test/test-session-access-fallback.mjs && node test/with-timeout.mjs 420 npx tsx test/test-session-rpc-role-map.mjs && node test/with-timeout.mjs 420 npx tsx test/test-interactive-helpers.mjs && node test/with-timeout.mjs 420 npx tsx test/test-pinned-codex.mjs && node test/with-timeout.mjs 420 npx tsx test/test-pinned-hypha-rpc.mjs && node test/with-timeout.mjs 420 npx tsx test/test-pinned-kimi.mjs && node test/with-timeout.mjs 420 npx tsx test/test-channel-receive-cap.mjs && node test/with-timeout.mjs 420 npx tsx test/test-dns-shadowing.mjs && node test/with-timeout.mjs 420 npx tsx test/test-codex-request-timeout.mjs && node test/with-timeout.mjs 420 npx tsx test/test-codex-app-server.mjs && node test/with-timeout.mjs 420 npx tsx test/test-kimi-provider.mjs && node test/with-timeout.mjs 420 npx tsx test/test-acp-backend.mjs && node test/with-timeout.mjs 420 npx tsx test/test-acp-bridge.mjs && node test/with-timeout.mjs 420 npx tsx test/test-listener-backoff.mjs && node test/with-timeout.mjs 420 npx tsx test/test-session-identity-env.mjs && node test/with-timeout.mjs 420 npx tsx test/test-hook-server.mjs && node test/with-timeout.mjs 420 npx tsx test/test-session-commands.mjs && node test/with-timeout.mjs 420 npx tsx test/test-interactive-console.mjs && node test/with-timeout.mjs 420 npx tsx test/test-session-messages.mjs && node test/with-timeout.mjs 420 npx tsx test/test-session-send-query.mjs && node test/with-timeout.mjs 420 npx tsx test/test-skills.mjs && node test/with-timeout.mjs 420 npx tsx test/test-agent-grouping.mjs && node test/with-timeout.mjs 420 npx tsx test/test-machine-list-directory.mjs && node test/with-timeout.mjs 420 npx tsx test/test-service-commands.mjs && node test/with-timeout.mjs 420 npx tsx test/test-supervisor.mjs && node test/with-timeout.mjs 420 npx tsx test/test-supervisor-lock.mjs && node test/with-timeout.mjs 420 node test/test-supervisor-restart.mjs && node test/with-timeout.mjs 420 npx tsx test/test-clear-detection.mjs && node test/with-timeout.mjs 420 npx tsx test/test-compact-detect.mjs && node test/with-timeout.mjs 420 npx tsx test/test-session-consolidation.mjs && node test/with-timeout.mjs 420 npx tsx test/test-inbox-store.mjs && node test/with-timeout.mjs 420 npx tsx test/test-inbox.mjs && node test/with-timeout.mjs 420 npx tsx test/test-inbox-cross-machine.mjs && node test/with-timeout.mjs 420 npx tsx test/test-issue-store.mjs && node test/with-timeout.mjs 420 npx tsx test/test-issue-store-lock.mjs && node test/with-timeout.mjs 420 npx tsx test/test-issue-close-gate.mjs && node test/with-timeout.mjs 420 npx tsx test/test-loop-verify.mjs && node test/with-timeout.mjs 420 npx tsx test/test-restore-decision.mjs && node test/with-timeout.mjs 420 npx tsx test/test-issue-rpc.mjs && node test/with-timeout.mjs 420 npx tsx test/test-issue-pause.mjs && node test/with-timeout.mjs 420 npx tsx test/test-workflow-store.mjs && node test/with-timeout.mjs 420 npx tsx test/test-workflow-rpc.mjs && node test/with-timeout.mjs 420 npx tsx test/test-workflow-scheduler.mjs && node test/with-timeout.mjs 420 npx tsx test/test-cron.mjs && node test/with-timeout.mjs 420 npx tsx test/test-workflow-runs.mjs && node test/with-timeout.mjs 420 npx tsx test/test-workflow-runs-lock.mjs && node test/with-timeout.mjs 420 npx tsx test/test-workflow-idle.mjs && node test/with-timeout.mjs 420 npx tsx test/test-workflow-reconcile.mjs && node test/with-timeout.mjs 420 npx tsx test/test-serve-link-subdomain.mjs && node test/with-timeout.mjs 420 npx tsx test/test-short-id.mjs && node test/with-timeout.mjs 420 npx tsx test/test-transcript-edit.mjs && node test/with-timeout.mjs 420 npx tsx test/test-edit-history.mjs && node test/with-timeout.mjs 420 npx tsx test/test-friendly-name.mjs && node test/with-timeout.mjs 420 npx tsx test/test-session-rpc-dispatch.mjs && node test/with-timeout.mjs 420 npx tsx test/test-sandbox-cli.mjs && node test/with-timeout.mjs 420 npx tsx test/test-serve-manager.mjs && node test/with-timeout.mjs 420 npx tsx test/test-session-files-gateway.mjs && node test/with-timeout.mjs 420 npx tsx test/test-serve-ws-upgrade.mjs && node test/with-timeout.mjs 420 npx tsx test/test-serve-auth.mjs && node test/with-timeout.mjs 420 npx tsx test/test-static-file-server.mjs && node test/with-timeout.mjs 420 npx tsx test/test-serve-stability.mjs && node test/with-timeout.mjs 420 npx tsx test/test-frpc-e2e.mjs --unit-only && node test/with-timeout.mjs 420 npx tsx test/test-frpc-status.mjs && node test/with-timeout.mjs 420 npx tsx test/test-frpc-orphan-reap.mjs && node test/with-timeout.mjs 420 node test/pinnedClaudeCode.test.mjs && node test/with-timeout.mjs 420 npx tsx test/test-claude-version-recheck.mjs && node test/with-timeout.mjs 420 node test/fleet.test.mjs && node test/with-timeout.mjs 420 npx tsx test/test-session-file.mjs && node test/with-timeout.mjs 420 npx tsx test/test-channel-rpc.mjs && node test/with-timeout.mjs 420 npx tsx test/test-wise-agent.mjs && node test/with-timeout.mjs 420 npx tsx test/test-channel-agent.mjs && node test/with-timeout.mjs 420 npx tsx test/test-channels-service.mjs && node test/with-timeout.mjs 420 npx tsx test/test-hotreload-seam.mjs && node test/with-timeout.mjs 420 npx tsx test/test-hot-reload.mjs && node test/with-timeout.mjs 420 npx tsx test/test-hot-reload-live.mjs && node test/with-timeout.mjs 420 npx tsx test/test-session-core.mjs && node test/with-timeout.mjs 420 npx tsx test/test-channel-async-reply.mjs && node test/with-timeout.mjs 420 npx tsx test/test-outbox-reload.mjs && node test/with-timeout.mjs 420 npx tsx test/test-channel-binding.mjs && node test/with-timeout.mjs 420 npx tsx test/test-channel-store-lock.mjs && node test/with-timeout.mjs 420 npx tsx test/test-channel-identity.mjs && node test/with-timeout.mjs 420 npx tsx test/test-stateless-dispatch-limiter.mjs && node test/with-timeout.mjs 420 npx tsx test/test-shared-session-identity.mjs && node test/with-timeout.mjs 420 npx tsx test/test-wise-agent-auth.mjs && node test/with-timeout.mjs 420 npx tsx test/test-channel-http.mjs && node test/with-timeout.mjs 420 npx tsx test/test-channel-upload.mjs && node test/with-timeout.mjs 420 npx tsx test/test-channel-file-access.mjs && node test/with-timeout.mjs 420 npx tsx test/test-wise-voice.mjs && node test/with-timeout.mjs 420 npx tsx test/test-wise-headless.mjs && node test/with-timeout.mjs 420 npx tsx test/test-wise-machine.mjs && node test/with-timeout.mjs 420 npx tsx test/test-crew-merge.mjs && node test/with-timeout.mjs 420 npx tsx test/test-crew-verdict-routing.mjs && node test/with-timeout.mjs 420 npx tsx test/test-crew-standalone.mjs && node test/with-timeout.mjs 420 npx tsx test/test-session-links.mjs && node test/with-timeout.mjs 420 npx tsx test/test-issue-loop-pause-guard.mjs && node test/with-timeout.mjs 420 npx tsx test/test-artifact-guard.mjs && node test/with-timeout.mjs 420 npx tsx test/test-artifact-sync-pagination.mjs && node test/with-timeout.mjs 420 npx tsx test/test-graceful-restart.mjs && node test/with-timeout.mjs 420 npx tsx test/test-flush-exit.mjs && node test/with-timeout.mjs 420 npx tsx test/test-codex-skills.mjs && node test/with-timeout.mjs 420 npx tsx test/test-nightly-0807-fixes.mjs && node test/with-timeout.mjs 420 npx tsx test/test-nightly-0814-fixes.mjs && node test/with-timeout.mjs 420 npx tsx test/test-log-prune.mjs && node test/with-timeout.mjs 420 node test/test-message-count-cache.mjs && node test/with-timeout.mjs 420 node test/test-serve-link-gate.mjs && node test/with-timeout.mjs 420 node test/test-security-context-unenforceable.mjs && node test/with-timeout.mjs 420 npx tsx test/test-issue-id-resolution.mjs && node test/with-timeout.mjs 420 npx tsx test/test-help-flag-never-acts.mjs && node test/with-timeout.mjs 420 npx tsx test/test-with-timeout.mjs && node test/with-timeout.mjs 420 npx tsx test/test-message-queue-cap.mjs && node test/with-timeout.mjs 420 npx tsx test/test-compaction-backstop.mjs && node test/with-timeout.mjs 420 npx tsx test/test-log-format.mjs && npx tsx test/test-deploy-manifests.mjs && npx tsx test/test-kimi-default-model-1169.mjs && npx tsx test/test-loop-dormant-runtime-1170.mjs && npx tsx test/test-skill-install-atomic.mjs",
23
+ "test:hypha": "node --no-warnings test/test-hypha-service.mjs",
24
+ dev: "tsx src/cli.ts",
25
+ "dev:daemon": "tsx src/cli.ts daemon start-sync",
26
+ "test:e2e": "node --no-warnings test/e2e-session-tests.mjs && npx tsx test/e2e-codex-midturn-steer.mjs && npx tsx test/e2e-serve-iframe-login.mjs && npx tsx test/test-archive-preserves-claude-file.mjs && npx tsx test/test-daemon-e2e.mjs && npx tsx test/test-hypha-service.mjs && npx tsx test/test-permission-e2e.mjs && npx tsx test/test-serve-e2e.mjs && npx tsx test/test-session-archive-resume.mjs && npx tsx test/test-session-rpc-e2e.mjs && npx tsx test/test-skills-integration.mjs && npx tsx test/test-wm-refresh.mjs && npx tsx test/e2e-session-files-gateway.mjs && npx tsx test/e2e-dns-production-hosts.mjs",
27
+ "test:frpc": "npx tsx test/test-frpc-e2e.mjs",
28
+ prepublishOnly: "node ../../scripts/bump-cli-version.mjs --check && yarn build && yarn test"
29
+ };
30
+ var dependencies = {
31
+ "@agentclientprotocol/sdk": "^0.14.1",
32
+ "@modelcontextprotocol/sdk": "^1.25.3",
33
+ "hypha-rpc": "0.21.46",
34
+ "node-pty": "1.2.0-beta.11",
35
+ ws: "^8.18.0",
36
+ yaml: "^2.8.2",
37
+ zod: "^3.24.4"
38
+ };
39
+ var devDependencies = {
40
+ "@types/node": ">=20",
41
+ "@types/ws": "^8.5.14",
42
+ pkgroll: "^2.14.2",
43
+ tsx: "^4.20.6",
44
+ typescript: "5.9.3"
45
+ };
46
+ var packageManager = "yarn@1.22.22";
47
+ var _package = {
48
+ name: name,
49
+ version: version,
50
+ description: description,
51
+ author: author,
52
+ license: license,
53
+ type: type,
54
+ bin: bin,
55
+ files: files,
56
+ main: main,
57
+ exports: exports$1,
58
+ scripts: scripts,
59
+ dependencies: dependencies,
60
+ devDependencies: devDependencies,
61
+ packageManager: packageManager
62
+ };
63
+
64
+ export { author, bin, _package as default, dependencies, description, devDependencies, exports$1 as exports, files, license, main, name, packageManager, scripts, type, version };
@@ -4,12 +4,33 @@ import { promisify } from 'node:util';
4
4
  const PINNED_CLAUDE_CODE_VERSION = "2.1.233";
5
5
  const exec = promisify(exec$1);
6
6
  let _reconcile = null;
7
- function beginClaudeVersionReconcile(log) {
8
- if (_reconcile) return;
9
- _reconcile = ensureClaudeCodeVersion(log).catch((e) => {
7
+ let _reconcileStartedAt = 0;
8
+ let _inFlight = false;
9
+ const CLAUDE_VERSION_RECHECK_MS = 60 * 60 * 1e3;
10
+ function beginClaudeVersionReconcile(log, opts) {
11
+ const now = opts?.now ?? Date.now();
12
+ const recheckMs = opts?.recheckMs ?? CLAUDE_VERSION_RECHECK_MS;
13
+ if (_inFlight) return;
14
+ if (_reconcile && !opts?.force && now - _reconcileStartedAt < recheckMs) return;
15
+ _inFlight = true;
16
+ _reconcileStartedAt = now;
17
+ _reconcile = ensureClaudeCodeVersion(log, PINNED_CLAUDE_CODE_VERSION, { readVersion: opts?.readVersion }).then((result) => {
18
+ try {
19
+ opts?.onResult?.(result);
20
+ } catch {
21
+ }
22
+ return result;
23
+ }).catch((e) => {
10
24
  log(`[claude-version] check failed: ${e?.message || e}`);
25
+ }).finally(() => {
26
+ _inFlight = false;
11
27
  });
12
28
  }
29
+ function __resetClaudeVersionReconcileForTests() {
30
+ _reconcile = null;
31
+ _reconcileStartedAt = 0;
32
+ _inFlight = false;
33
+ }
13
34
  function awaitClaudeVersionReady(timeoutMs = 6e4) {
14
35
  if (!_reconcile) return Promise.resolve();
15
36
  return Promise.race([
@@ -45,7 +66,7 @@ function runInstaller(version, log) {
45
66
  }
46
67
  async function ensureClaudeCodeVersion(log, pinned = PINNED_CLAUDE_CODE_VERSION, opts) {
47
68
  const autoInstall = opts?.allowAutoInstall !== false;
48
- const current = await readClaudeVersion();
69
+ const current = await (opts?.readVersion ?? readClaudeVersion)();
49
70
  if (!current) {
50
71
  log(`[claude-version] 'claude' not on PATH \u2014 please run the Anthropic installer once: curl -fsSL https://claude.ai/install.sh | sh`);
51
72
  return { kind: "not-installed", want: pinned };
@@ -64,9 +85,9 @@ async function ensureClaudeCodeVersion(log, pinned = PINNED_CLAUDE_CODE_VERSION,
64
85
  log(`[claude-version] install failed for ${pinned}: ${stderr.trim().slice(0, 400)}`);
65
86
  return { kind: "install-failed", from: current, want: pinned, error: stderr.slice(0, 400) };
66
87
  }
67
- const after = await readClaudeVersion();
88
+ const after = await (opts?.readVersion ?? readClaudeVersion)();
68
89
  log(`[claude-version] installer finished; now reports ${after ?? "unknown"}`);
69
90
  return { kind: "installed", from: current, to: after ?? pinned };
70
91
  }
71
92
 
72
- export { PINNED_CLAUDE_CODE_VERSION, awaitClaudeVersionReady, beginClaudeVersionReconcile, ensureClaudeCodeVersion };
93
+ export { CLAUDE_VERSION_RECHECK_MS, PINNED_CLAUDE_CODE_VERSION, __resetClaudeVersionReconcileForTests, awaitClaudeVersionReady, beginClaudeVersionReconcile, ensureClaudeCodeVersion };
@@ -1,4 +1,4 @@
1
- import { f as resolveProjectRoot, q as getRun, t as listRuns, v as getWorkflow, w as runWorkflow, x as setWorkflowEnabled, y as removeWorkflow, z as validateCronExpr, A as validateWorkflowName, B as saveWorkflow, C as rawWorkflow, D as listWorkflows } from './run-CSNL62FQ.mjs';
1
+ import { f as resolveProjectRoot, t as getRun, v as listRuns, w as getWorkflow, x as runWorkflow, y as setWorkflowEnabled, z as removeWorkflow, A as validateCronExpr, B as validateWorkflowName, C as saveWorkflow, D as rawWorkflow, E as listWorkflows } from './run-PXdghhjy.mjs';
2
2
  import 'os';
3
3
  import 'fs/promises';
4
4
  import 'fs';
@@ -37,6 +37,7 @@ async function workflowRpc(cwd, params) {
37
37
  for (const c of crons) validateCronExpr(c);
38
38
  if (crons.length) on.schedule = crons.map((c) => ({ cron: c }));
39
39
  if (params.dispatch || params.workflow_dispatch) on.workflow_dispatch = true;
40
+ if (params.idle || Array.isArray(params.on) && params.on.map(String).includes("idle")) on.idle = true;
40
41
  const runs = Array.isArray(params.runs) ? params.runs.map(String).filter(Boolean) : [];
41
42
  if (!params.name || !runs.length) throw new Error("workflow add: name and at least one run step required");
42
43
  validateWorkflowName(String(params.name));
@@ -1,4 +1,4 @@
1
- import { f as resolveProjectRoot, u as updateIssue, h as getIssue, i as resumeIssue, p as pauseIssue, j as addComment, k as addIssue, l as listIssues, m as isPendingIssue, n as searchIssues, o as isVisibleTo } from './run-CSNL62FQ.mjs';
1
+ import { f as resolveProjectRoot, u as updateIssue, h as getIssue, i as checkVerifyCommand, j as resumeIssue, p as pauseIssue, k as addComment, l as addIssue, m as listIssues, n as isPendingIssue, o as searchIssues, q as isVisibleTo } from './run-PXdghhjy.mjs';
2
2
  import 'os';
3
3
  import 'fs/promises';
4
4
  import 'fs';
@@ -137,6 +137,18 @@ function issueRpc(cwd, params, deps = {}) {
137
137
  case "status": {
138
138
  const status = STATUS_MAP[params.status];
139
139
  if (!status) throw new Error(`issue status: unknown status "${params.status}"`);
140
+ if ((params.status === "close" || params.status === "done") && !params.force) {
141
+ const cur = getIssue(root, String(params.id));
142
+ const res = checkVerifyCommand(root, cur);
143
+ if (!res.ok) {
144
+ throw new Error(
145
+ `Refusing to close #${params.id}: its verify-cmd failed \u2014 the fix is not verified.
146
+ $ ${res.cmd}
147
+ ${res.output || ""}
148
+ (Fix the issue, or close with force to override.)`
149
+ );
150
+ }
151
+ }
140
152
  const patch = { status };
141
153
  if (status === "in_progress" && params.session) {
142
154
  const cur = getIssue(root, String(params.id));
@@ -1,4 +1,4 @@
1
- import{createRequire as _pkgrollCR}from"node:module";const require=_pkgrollCR(import.meta.url);import { ak as applyClaudeProxyEnv, al as composeSessionId, am as generateFriendlyName, c as connectToHypha, a as createSessionStore, r as registerMachineService, an as generateHookSettings } from './run-CSNL62FQ.mjs';
1
+ import{createRequire as _pkgrollCR}from"node:module";const require=_pkgrollCR(import.meta.url);import { am as applyClaudeProxyEnv, an as composeSessionId, ao as generateFriendlyName, c as connectToHypha, a as createSessionStore, r as registerMachineService, ap as generateHookSettings } from './run-PXdghhjy.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';