@vibelet/cli 0.1.38 → 1.0.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.
Files changed (323) hide show
  1. package/README.md +80 -0
  2. package/bin/cloudflared-quick-tunnel.mjs +11 -0
  3. package/bin/cloudflared-resolver.mjs +171 -0
  4. package/bin/vibelet-runtime-policy.mjs +36 -0
  5. package/bin/vibelet.cjs +12 -0
  6. package/bin/vibelet.mjs +1235 -0
  7. package/dist/index.cjs +126 -0
  8. package/package.json +24 -22
  9. package/app.json +0 -5
  10. package/dist/advertised-hosts.d.ts +0 -34
  11. package/dist/advertised-hosts.d.ts.map +0 -1
  12. package/dist/advertised-hosts.js +0 -176
  13. package/dist/advertised-hosts.js.map +0 -1
  14. package/dist/advertised-hosts.test.d.ts +0 -2
  15. package/dist/advertised-hosts.test.d.ts.map +0 -1
  16. package/dist/advertised-hosts.test.js +0 -96
  17. package/dist/advertised-hosts.test.js.map +0 -1
  18. package/dist/audit.d.ts +0 -30
  19. package/dist/audit.d.ts.map +0 -1
  20. package/dist/audit.js +0 -73
  21. package/dist/audit.js.map +0 -1
  22. package/dist/audit.test.d.ts +0 -2
  23. package/dist/audit.test.d.ts.map +0 -1
  24. package/dist/audit.test.js +0 -33
  25. package/dist/audit.test.js.map +0 -1
  26. package/dist/auth.d.ts +0 -6
  27. package/dist/auth.d.ts.map +0 -1
  28. package/dist/auth.js +0 -27
  29. package/dist/auth.js.map +0 -1
  30. package/dist/claude-hooks.d.ts +0 -58
  31. package/dist/claude-hooks.d.ts.map +0 -1
  32. package/dist/claude-hooks.js +0 -129
  33. package/dist/claude-hooks.js.map +0 -1
  34. package/dist/cli-version.d.ts +0 -3
  35. package/dist/cli-version.d.ts.map +0 -1
  36. package/dist/cli-version.js +0 -35
  37. package/dist/cli-version.js.map +0 -1
  38. package/dist/cli-version.test.d.ts +0 -2
  39. package/dist/cli-version.test.d.ts.map +0 -1
  40. package/dist/cli-version.test.js +0 -38
  41. package/dist/cli-version.test.js.map +0 -1
  42. package/dist/config.d.ts +0 -30
  43. package/dist/config.d.ts.map +0 -1
  44. package/dist/config.js +0 -327
  45. package/dist/config.js.map +0 -1
  46. package/dist/config.test.d.ts +0 -2
  47. package/dist/config.test.d.ts.map +0 -1
  48. package/dist/config.test.js +0 -184
  49. package/dist/config.test.js.map +0 -1
  50. package/dist/dev-auth.test.d.ts +0 -2
  51. package/dist/dev-auth.test.d.ts.map +0 -1
  52. package/dist/dev-auth.test.js +0 -154
  53. package/dist/dev-auth.test.js.map +0 -1
  54. package/dist/dev-script.test.d.ts +0 -2
  55. package/dist/dev-script.test.d.ts.map +0 -1
  56. package/dist/dev-script.test.js +0 -412
  57. package/dist/dev-script.test.js.map +0 -1
  58. package/dist/drivers/claude.d.ts +0 -34
  59. package/dist/drivers/claude.d.ts.map +0 -1
  60. package/dist/drivers/claude.js +0 -413
  61. package/dist/drivers/claude.js.map +0 -1
  62. package/dist/drivers/claude.test.d.ts +0 -2
  63. package/dist/drivers/claude.test.d.ts.map +0 -1
  64. package/dist/drivers/claude.test.js +0 -951
  65. package/dist/drivers/claude.test.js.map +0 -1
  66. package/dist/drivers/codex.d.ts +0 -38
  67. package/dist/drivers/codex.d.ts.map +0 -1
  68. package/dist/drivers/codex.js +0 -771
  69. package/dist/drivers/codex.js.map +0 -1
  70. package/dist/drivers/codex.test.d.ts +0 -2
  71. package/dist/drivers/codex.test.d.ts.map +0 -1
  72. package/dist/drivers/codex.test.js +0 -939
  73. package/dist/drivers/codex.test.js.map +0 -1
  74. package/dist/drivers/types.d.ts +0 -14
  75. package/dist/drivers/types.d.ts.map +0 -1
  76. package/dist/drivers/types.js +0 -2
  77. package/dist/drivers/types.js.map +0 -1
  78. package/dist/e2e.test.d.ts +0 -2
  79. package/dist/e2e.test.d.ts.map +0 -1
  80. package/dist/e2e.test.js +0 -111
  81. package/dist/e2e.test.js.map +0 -1
  82. package/dist/identity.d.ts +0 -10
  83. package/dist/identity.d.ts.map +0 -1
  84. package/dist/identity.js +0 -66
  85. package/dist/identity.js.map +0 -1
  86. package/dist/identity.test.d.ts +0 -2
  87. package/dist/identity.test.d.ts.map +0 -1
  88. package/dist/identity.test.js +0 -25
  89. package/dist/identity.test.js.map +0 -1
  90. package/dist/index-entry.test.d.ts +0 -2
  91. package/dist/index-entry.test.d.ts.map +0 -1
  92. package/dist/index-entry.test.js +0 -272
  93. package/dist/index-entry.test.js.map +0 -1
  94. package/dist/index.d.ts +0 -2
  95. package/dist/index.d.ts.map +0 -1
  96. package/dist/index.js +0 -707
  97. package/dist/index.js.map +0 -1
  98. package/dist/logger.d.ts +0 -31
  99. package/dist/logger.d.ts.map +0 -1
  100. package/dist/logger.js +0 -75
  101. package/dist/logger.js.map +0 -1
  102. package/dist/metrics.d.ts +0 -52
  103. package/dist/metrics.d.ts.map +0 -1
  104. package/dist/metrics.js +0 -89
  105. package/dist/metrics.js.map +0 -1
  106. package/dist/pairing-store.d.ts +0 -29
  107. package/dist/pairing-store.d.ts.map +0 -1
  108. package/dist/pairing-store.js +0 -131
  109. package/dist/pairing-store.js.map +0 -1
  110. package/dist/pairing-store.test.d.ts +0 -2
  111. package/dist/pairing-store.test.d.ts.map +0 -1
  112. package/dist/pairing-store.test.js +0 -47
  113. package/dist/pairing-store.test.js.map +0 -1
  114. package/dist/paths.d.ts +0 -16
  115. package/dist/paths.d.ts.map +0 -1
  116. package/dist/paths.js +0 -18
  117. package/dist/paths.js.map +0 -1
  118. package/dist/perf-compare.d.ts +0 -13
  119. package/dist/perf-compare.d.ts.map +0 -1
  120. package/dist/perf-compare.js +0 -125
  121. package/dist/perf-compare.js.map +0 -1
  122. package/dist/port-conflict.d.ts +0 -9
  123. package/dist/port-conflict.d.ts.map +0 -1
  124. package/dist/port-conflict.js +0 -33
  125. package/dist/port-conflict.js.map +0 -1
  126. package/dist/port-conflict.test.d.ts +0 -2
  127. package/dist/port-conflict.test.d.ts.map +0 -1
  128. package/dist/port-conflict.test.js +0 -38
  129. package/dist/port-conflict.test.js.map +0 -1
  130. package/dist/process-scanner.d.ts +0 -43
  131. package/dist/process-scanner.d.ts.map +0 -1
  132. package/dist/process-scanner.js +0 -453
  133. package/dist/process-scanner.js.map +0 -1
  134. package/dist/process-scanner.perf.test.d.ts +0 -2
  135. package/dist/process-scanner.perf.test.d.ts.map +0 -1
  136. package/dist/process-scanner.perf.test.js +0 -186
  137. package/dist/process-scanner.perf.test.js.map +0 -1
  138. package/dist/process-scanner.test.d.ts +0 -2
  139. package/dist/process-scanner.test.d.ts.map +0 -1
  140. package/dist/process-scanner.test.js +0 -399
  141. package/dist/process-scanner.test.js.map +0 -1
  142. package/dist/push-protocol.d.ts +0 -15
  143. package/dist/push-protocol.d.ts.map +0 -1
  144. package/dist/push-protocol.js +0 -23
  145. package/dist/push-protocol.js.map +0 -1
  146. package/dist/push-protocol.test.d.ts +0 -2
  147. package/dist/push-protocol.test.d.ts.map +0 -1
  148. package/dist/push-protocol.test.js +0 -57
  149. package/dist/push-protocol.test.js.map +0 -1
  150. package/dist/push-store.d.ts +0 -22
  151. package/dist/push-store.d.ts.map +0 -1
  152. package/dist/push-store.js +0 -103
  153. package/dist/push-store.js.map +0 -1
  154. package/dist/push-store.test.d.ts +0 -2
  155. package/dist/push-store.test.d.ts.map +0 -1
  156. package/dist/push-store.test.js +0 -79
  157. package/dist/push-store.test.js.map +0 -1
  158. package/dist/push.d.ts +0 -65
  159. package/dist/push.d.ts.map +0 -1
  160. package/dist/push.js +0 -202
  161. package/dist/push.js.map +0 -1
  162. package/dist/push.test.d.ts +0 -2
  163. package/dist/push.test.d.ts.map +0 -1
  164. package/dist/push.test.js +0 -199
  165. package/dist/push.test.js.map +0 -1
  166. package/dist/safe-stdio.d.ts +0 -3
  167. package/dist/safe-stdio.d.ts.map +0 -1
  168. package/dist/safe-stdio.js +0 -46
  169. package/dist/safe-stdio.js.map +0 -1
  170. package/dist/scanner.d.ts +0 -30
  171. package/dist/scanner.d.ts.map +0 -1
  172. package/dist/scanner.js +0 -859
  173. package/dist/scanner.js.map +0 -1
  174. package/dist/scanner.perf.test.d.ts +0 -2
  175. package/dist/scanner.perf.test.d.ts.map +0 -1
  176. package/dist/scanner.perf.test.js +0 -320
  177. package/dist/scanner.perf.test.js.map +0 -1
  178. package/dist/scanner.test.d.ts +0 -2
  179. package/dist/scanner.test.d.ts.map +0 -1
  180. package/dist/scanner.test.js +0 -948
  181. package/dist/scanner.test.js.map +0 -1
  182. package/dist/session-inventory.d.ts +0 -63
  183. package/dist/session-inventory.d.ts.map +0 -1
  184. package/dist/session-inventory.js +0 -525
  185. package/dist/session-inventory.js.map +0 -1
  186. package/dist/session-inventory.perf.test.d.ts +0 -2
  187. package/dist/session-inventory.perf.test.d.ts.map +0 -1
  188. package/dist/session-inventory.perf.test.js +0 -220
  189. package/dist/session-inventory.perf.test.js.map +0 -1
  190. package/dist/session-inventory.test.d.ts +0 -2
  191. package/dist/session-inventory.test.d.ts.map +0 -1
  192. package/dist/session-inventory.test.js +0 -712
  193. package/dist/session-inventory.test.js.map +0 -1
  194. package/dist/session-manager.d.ts +0 -75
  195. package/dist/session-manager.d.ts.map +0 -1
  196. package/dist/session-manager.js +0 -1515
  197. package/dist/session-manager.js.map +0 -1
  198. package/dist/session-manager.test.d.ts +0 -2
  199. package/dist/session-manager.test.d.ts.map +0 -1
  200. package/dist/session-manager.test.js +0 -2861
  201. package/dist/session-manager.test.js.map +0 -1
  202. package/dist/session-store.d.ts +0 -42
  203. package/dist/session-store.d.ts.map +0 -1
  204. package/dist/session-store.js +0 -163
  205. package/dist/session-store.js.map +0 -1
  206. package/dist/session-store.test.d.ts +0 -2
  207. package/dist/session-store.test.d.ts.map +0 -1
  208. package/dist/session-store.test.js +0 -236
  209. package/dist/session-store.test.js.map +0 -1
  210. package/dist/session-title.d.ts +0 -6
  211. package/dist/session-title.d.ts.map +0 -1
  212. package/dist/session-title.js +0 -105
  213. package/dist/session-title.js.map +0 -1
  214. package/dist/session-title.perf.test.d.ts +0 -2
  215. package/dist/session-title.perf.test.d.ts.map +0 -1
  216. package/dist/session-title.perf.test.js +0 -99
  217. package/dist/session-title.perf.test.js.map +0 -1
  218. package/dist/session-title.test.d.ts +0 -2
  219. package/dist/session-title.test.d.ts.map +0 -1
  220. package/dist/session-title.test.js +0 -199
  221. package/dist/session-title.test.js.map +0 -1
  222. package/dist/shutdown-endpoint.test.d.ts +0 -2
  223. package/dist/shutdown-endpoint.test.d.ts.map +0 -1
  224. package/dist/shutdown-endpoint.test.js +0 -93
  225. package/dist/shutdown-endpoint.test.js.map +0 -1
  226. package/dist/storage-housekeeping.d.ts +0 -28
  227. package/dist/storage-housekeeping.d.ts.map +0 -1
  228. package/dist/storage-housekeeping.js +0 -76
  229. package/dist/storage-housekeeping.js.map +0 -1
  230. package/dist/storage-housekeeping.test.d.ts +0 -2
  231. package/dist/storage-housekeeping.test.d.ts.map +0 -1
  232. package/dist/storage-housekeeping.test.js +0 -65
  233. package/dist/storage-housekeeping.test.js.map +0 -1
  234. package/dist/test-daemon-harness.d.ts +0 -31
  235. package/dist/test-daemon-harness.d.ts.map +0 -1
  236. package/dist/test-daemon-harness.js +0 -337
  237. package/dist/test-daemon-harness.js.map +0 -1
  238. package/dist/token-auth.test.d.ts +0 -2
  239. package/dist/token-auth.test.d.ts.map +0 -1
  240. package/dist/token-auth.test.js +0 -52
  241. package/dist/token-auth.test.js.map +0 -1
  242. package/dist/utils.d.ts +0 -4
  243. package/dist/utils.d.ts.map +0 -1
  244. package/dist/utils.js +0 -40
  245. package/dist/utils.js.map +0 -1
  246. package/dist/utils.test.d.ts +0 -2
  247. package/dist/utils.test.d.ts.map +0 -1
  248. package/dist/utils.test.js +0 -54
  249. package/dist/utils.test.js.map +0 -1
  250. package/dist/ws-data.d.ts +0 -4
  251. package/dist/ws-data.d.ts.map +0 -1
  252. package/dist/ws-data.js +0 -20
  253. package/dist/ws-data.js.map +0 -1
  254. package/dist/ws-data.test.d.ts +0 -2
  255. package/dist/ws-data.test.d.ts.map +0 -1
  256. package/dist/ws-data.test.js +0 -17
  257. package/dist/ws-data.test.js.map +0 -1
  258. package/perf-reporter.mjs +0 -138
  259. package/scripts/build-release.mjs +0 -41
  260. package/scripts/dev.mjs +0 -537
  261. package/src/advertised-hosts.test.ts +0 -125
  262. package/src/advertised-hosts.ts +0 -225
  263. package/src/audit.test.ts +0 -38
  264. package/src/audit.ts +0 -117
  265. package/src/auth.ts +0 -31
  266. package/src/claude-hooks.ts +0 -195
  267. package/src/cli-version.test.ts +0 -36
  268. package/src/cli-version.ts +0 -46
  269. package/src/config.test.ts +0 -254
  270. package/src/config.ts +0 -324
  271. package/src/dev-auth.test.ts +0 -183
  272. package/src/dev-script.test.ts +0 -511
  273. package/src/drivers/claude.test.ts +0 -1186
  274. package/src/drivers/claude.ts +0 -443
  275. package/src/drivers/codex.test.ts +0 -1096
  276. package/src/drivers/codex.ts +0 -879
  277. package/src/drivers/types.ts +0 -15
  278. package/src/e2e.test.ts +0 -139
  279. package/src/identity.test.ts +0 -26
  280. package/src/identity.ts +0 -82
  281. package/src/index-entry.test.ts +0 -336
  282. package/src/index.ts +0 -781
  283. package/src/logger.ts +0 -112
  284. package/src/metrics.ts +0 -117
  285. package/src/pairing-store.test.ts +0 -53
  286. package/src/pairing-store.ts +0 -154
  287. package/src/paths.ts +0 -19
  288. package/src/perf-compare.ts +0 -164
  289. package/src/port-conflict.test.ts +0 -45
  290. package/src/port-conflict.ts +0 -44
  291. package/src/process-scanner.perf.test.ts +0 -222
  292. package/src/process-scanner.test.ts +0 -575
  293. package/src/process-scanner.ts +0 -514
  294. package/src/push-protocol.test.ts +0 -74
  295. package/src/push-protocol.ts +0 -36
  296. package/src/push-store.test.ts +0 -89
  297. package/src/push-store.ts +0 -126
  298. package/src/push.test.ts +0 -234
  299. package/src/push.ts +0 -318
  300. package/src/safe-stdio.ts +0 -51
  301. package/src/scanner.perf.test.ts +0 -359
  302. package/src/scanner.test.ts +0 -1045
  303. package/src/scanner.ts +0 -924
  304. package/src/session-inventory.perf.test.ts +0 -250
  305. package/src/session-inventory.test.ts +0 -1002
  306. package/src/session-inventory.ts +0 -721
  307. package/src/session-manager.test.ts +0 -3430
  308. package/src/session-manager.ts +0 -1775
  309. package/src/session-store.test.ts +0 -276
  310. package/src/session-store.ts +0 -202
  311. package/src/session-title.perf.test.ts +0 -118
  312. package/src/session-title.test.ts +0 -286
  313. package/src/session-title.ts +0 -108
  314. package/src/shutdown-endpoint.test.ts +0 -95
  315. package/src/storage-housekeeping.test.ts +0 -78
  316. package/src/storage-housekeeping.ts +0 -111
  317. package/src/test-daemon-harness.ts +0 -410
  318. package/src/token-auth.test.ts +0 -67
  319. package/src/utils.test.ts +0 -65
  320. package/src/utils.ts +0 -47
  321. package/src/ws-data.test.ts +0 -20
  322. package/src/ws-data.ts +0 -26
  323. package/tsconfig.json +0 -12
@@ -1,186 +0,0 @@
1
- import { describe, it } from 'node:test';
2
- import assert from 'node:assert/strict';
3
- import { classifyProcessSnapshot, extractExplicitSessionId, mergeRunningSessionCandidates, scanRunningSessions, invalidateProcessScanCache, } from './process-scanner.js';
4
- function measure(fn, iterations) {
5
- fn(); // warmup
6
- const start = performance.now();
7
- for (let i = 0; i < iterations; i++)
8
- fn();
9
- const totalMs = performance.now() - start;
10
- return { totalMs, avgMs: totalMs / iterations };
11
- }
12
- const ITERATIONS = 10_000;
13
- describe('process-scanner performance', () => {
14
- describe('extractExplicitSessionId', () => {
15
- it(`claude --resume parsing × ${ITERATIONS} < 50ms`, () => {
16
- const { totalMs } = measure(() => {
17
- extractExplicitSessionId('claude', 'node /usr/bin/claude --resume 019d03e3-2672-7011-9c6d-5ba083b71111');
18
- }, ITERATIONS);
19
- console.log(` claude --resume: ${totalMs.toFixed(2)}ms for ${ITERATIONS} calls`);
20
- assert.ok(totalMs < 50, `took ${totalMs.toFixed(2)}ms, expected < 50ms`);
21
- });
22
- it(`claude --resume= parsing × ${ITERATIONS} < 50ms`, () => {
23
- const { totalMs } = measure(() => {
24
- extractExplicitSessionId('claude', 'claude --resume=abc123def456');
25
- }, ITERATIONS);
26
- console.log(` claude --resume=: ${totalMs.toFixed(2)}ms for ${ITERATIONS} calls`);
27
- assert.ok(totalMs < 50, `took ${totalMs.toFixed(2)}ms, expected < 50ms`);
28
- });
29
- it(`codex resume parsing × ${ITERATIONS} < 50ms`, () => {
30
- const { totalMs } = measure(() => {
31
- extractExplicitSessionId('codex', 'codex resume 019d03e3-2672-7011-9c6d-5ba083b71111');
32
- }, ITERATIONS);
33
- console.log(` codex resume: ${totalMs.toFixed(2)}ms for ${ITERATIONS} calls`);
34
- assert.ok(totalMs < 50, `took ${totalMs.toFixed(2)}ms, expected < 50ms`);
35
- });
36
- it(`no match parsing × ${ITERATIONS} < 50ms`, () => {
37
- const { totalMs } = measure(() => {
38
- extractExplicitSessionId('claude', 'claude --yolo --mode auto');
39
- }, ITERATIONS);
40
- console.log(` no match: ${totalMs.toFixed(2)}ms for ${ITERATIONS} calls`);
41
- assert.ok(totalMs < 50, `took ${totalMs.toFixed(2)}ms, expected < 50ms`);
42
- });
43
- it(`complex quoted command × ${ITERATIONS} < 100ms`, () => {
44
- const cmd = '/usr/local/bin/node "/opt/homebrew/bin/claude" --resume "019d03e3-2672-7011-9c6d-5ba083b71111" --cwd "/Users/test/my project"';
45
- const { totalMs } = measure(() => {
46
- extractExplicitSessionId('claude', cmd);
47
- }, ITERATIONS);
48
- console.log(` complex quoted: ${totalMs.toFixed(2)}ms for ${ITERATIONS} calls`);
49
- assert.ok(totalMs < 100, `took ${totalMs.toFixed(2)}ms, expected < 100ms`);
50
- });
51
- });
52
- describe('classifyProcessSnapshot', () => {
53
- it(`high confidence (explicit resume) × ${ITERATIONS} < 100ms`, () => {
54
- const snapshot = {
55
- pid: 6581,
56
- agent: 'codex',
57
- command: 'codex resume 019d03e3-2672-7011-9c6d-5ba083b71111',
58
- cwd: '/repo',
59
- sessionFiles: [],
60
- };
61
- const { totalMs } = measure(() => {
62
- classifyProcessSnapshot(snapshot);
63
- }, ITERATIONS);
64
- console.log(` high confidence: ${totalMs.toFixed(2)}ms for ${ITERATIONS} calls`);
65
- assert.ok(totalMs < 100, `took ${totalMs.toFixed(2)}ms, expected < 100ms`);
66
- });
67
- it(`medium confidence (single file) × ${ITERATIONS} < 100ms`, () => {
68
- const snapshot = {
69
- pid: 52424,
70
- agent: 'codex',
71
- command: 'codex --yolo',
72
- cwd: '/repo',
73
- sessionFiles: ['/Users/test/.codex/sessions/2026/03/20/rollout-019d08ac-c265-7270-9497-d14125228a50.jsonl'],
74
- };
75
- const { totalMs } = measure(() => {
76
- classifyProcessSnapshot(snapshot);
77
- }, ITERATIONS);
78
- console.log(` medium confidence: ${totalMs.toFixed(2)}ms for ${ITERATIONS} calls`);
79
- assert.ok(totalMs < 100, `took ${totalMs.toFixed(2)}ms, expected < 100ms`);
80
- });
81
- it(`null result (multiple files) × ${ITERATIONS} < 100ms`, () => {
82
- const snapshot = {
83
- pid: 52424,
84
- agent: 'codex',
85
- command: 'codex --yolo',
86
- cwd: '/repo',
87
- sessionFiles: [
88
- '/Users/test/.codex/sessions/2026/03/20/rollout-a.jsonl',
89
- '/Users/test/.codex/sessions/2026/03/20/rollout-b.jsonl',
90
- ],
91
- };
92
- const { totalMs } = measure(() => {
93
- classifyProcessSnapshot(snapshot);
94
- }, ITERATIONS);
95
- console.log(` null (multi-file): ${totalMs.toFixed(2)}ms for ${ITERATIONS} calls`);
96
- assert.ok(totalMs < 100, `took ${totalMs.toFixed(2)}ms, expected < 100ms`);
97
- });
98
- it(`subagent filtering × ${ITERATIONS} < 100ms`, () => {
99
- const snapshot = {
100
- pid: 1000,
101
- agent: 'claude',
102
- command: 'claude --resume abc',
103
- cwd: '/repo',
104
- sessionFiles: ['/Users/test/.claude/projects/-repo/subagents/abc.jsonl'],
105
- };
106
- const { totalMs } = measure(() => {
107
- classifyProcessSnapshot(snapshot);
108
- }, ITERATIONS);
109
- console.log(` subagent filter: ${totalMs.toFixed(2)}ms for ${ITERATIONS} calls`);
110
- assert.ok(totalMs < 100, `took ${totalMs.toFixed(2)}ms, expected < 100ms`);
111
- });
112
- });
113
- describe('mergeRunningSessionCandidates', () => {
114
- function makeCandidates(count) {
115
- return Array.from({ length: count }, (_, i) => ({
116
- agent: (i % 2 === 0 ? 'claude' : 'codex'),
117
- pid: 1000 + i,
118
- cwd: `/repo/project-${i % 5}`,
119
- command: `${i % 2 === 0 ? 'claude' : 'codex'} --resume session-${i % (count / 2)}`,
120
- sessionId: `session-${i % (count / 2)}`,
121
- confidence: (i % 3 === 0 ? 'high' : 'medium'),
122
- }));
123
- }
124
- it('merge 50 candidates (25 unique) × 1000 < 100ms', () => {
125
- const candidates = makeCandidates(50);
126
- const { totalMs, avgMs } = measure(() => {
127
- mergeRunningSessionCandidates(candidates);
128
- }, 1000);
129
- console.log(` merge 50: ${totalMs.toFixed(2)}ms total, ${avgMs.toFixed(3)}ms avg`);
130
- assert.ok(totalMs < 100, `took ${totalMs.toFixed(2)}ms, expected < 100ms`);
131
- });
132
- it('merge 200 candidates (100 unique) × 500 < 200ms', () => {
133
- const candidates = makeCandidates(200);
134
- const { totalMs, avgMs } = measure(() => {
135
- mergeRunningSessionCandidates(candidates);
136
- }, 500);
137
- console.log(` merge 200: ${totalMs.toFixed(2)}ms total, ${avgMs.toFixed(3)}ms avg`);
138
- assert.ok(totalMs < 200, `took ${totalMs.toFixed(2)}ms, expected < 200ms`);
139
- });
140
- it('merge 1000 candidates (500 unique) × 100 < 500ms', () => {
141
- const candidates = makeCandidates(1000);
142
- const { totalMs, avgMs } = measure(() => {
143
- mergeRunningSessionCandidates(candidates);
144
- }, 100);
145
- console.log(` merge 1000: ${totalMs.toFixed(2)}ms total, ${avgMs.toFixed(3)}ms avg`);
146
- assert.ok(totalMs < 500, `took ${totalMs.toFixed(2)}ms, expected < 500ms`);
147
- });
148
- it('merge 0 candidates × 10000 < 20ms', () => {
149
- const { totalMs } = measure(() => {
150
- mergeRunningSessionCandidates([]);
151
- }, 10000);
152
- console.log(` merge 0: ${totalMs.toFixed(2)}ms for 10000 calls`);
153
- assert.ok(totalMs < 20, `took ${totalMs.toFixed(2)}ms, expected < 20ms`);
154
- });
155
- });
156
- describe('scanRunningSessions throttle', () => {
157
- it('second call within TTL is near-instant (< 1ms)', async () => {
158
- invalidateProcessScanCache();
159
- // First call (cold — shells out to pgrep + lsof)
160
- const coldStart = performance.now();
161
- await scanRunningSessions();
162
- const coldMs = performance.now() - coldStart;
163
- // Second call (throttled)
164
- const warmStart = performance.now();
165
- await scanRunningSessions();
166
- const warmMs = performance.now() - warmStart;
167
- console.log(` scanRunningSessions cold: ${coldMs.toFixed(2)}ms, throttled: ${warmMs.toFixed(3)}ms`);
168
- assert.ok(warmMs < 1, `throttled call took ${warmMs.toFixed(3)}ms, expected < 1ms`);
169
- invalidateProcessScanCache();
170
- });
171
- it('invalidateProcessScanCache forces re-scan', async () => {
172
- invalidateProcessScanCache();
173
- await scanRunningSessions();
174
- // After invalidation, should re-scan (not instant)
175
- invalidateProcessScanCache();
176
- const start = performance.now();
177
- await scanRunningSessions();
178
- const ms = performance.now() - start;
179
- console.log(` after invalidation: ${ms.toFixed(2)}ms`);
180
- // Just verify it completes without error
181
- assert.ok(ms >= 0);
182
- invalidateProcessScanCache();
183
- });
184
- });
185
- });
186
- //# sourceMappingURL=process-scanner.perf.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"process-scanner.perf.test.js","sourceRoot":"","sources":["../src/process-scanner.perf.test.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=process-scanner.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"process-scanner.test.d.ts","sourceRoot":"","sources":["../src/process-scanner.test.ts"],"names":[],"mappings":""}
@@ -1,399 +0,0 @@
1
- import test from 'node:test';
2
- import assert from 'node:assert/strict';
3
- import { mkdir, mkdtemp, rm, utimes, writeFile } from 'fs/promises';
4
- import { join } from 'path';
5
- import { tmpdir } from 'os';
6
- import { classifyProcessSnapshot, extractExplicitSessionId, findRecentSessionFileForCwd, hasContinueFlag, isRelevantProcessCommand, isProcessAlive, mergeRunningSessionCandidates, } from './process-scanner.js';
7
- function snapshot(overrides) {
8
- return {
9
- pid: 1,
10
- agent: 'codex',
11
- command: 'codex --yolo',
12
- cwd: '/repo',
13
- sessionFiles: [],
14
- ...overrides,
15
- };
16
- }
17
- test('classifies explicit codex resume as high confidence', () => {
18
- const candidate = classifyProcessSnapshot(snapshot({
19
- pid: 6581,
20
- command: 'codex resume 019d03e3-2672-7011-9c6d-5ba083b71111',
21
- }));
22
- assert.deepEqual(candidate, {
23
- agent: 'codex',
24
- pid: 6581,
25
- cwd: '/repo',
26
- command: 'codex resume 019d03e3-2672-7011-9c6d-5ba083b71111',
27
- sessionId: '019d03e3-2672-7011-9c6d-5ba083b71111',
28
- confidence: 'high',
29
- });
30
- });
31
- test('classifies explicit Claude resume with permission flags and keeps approval mode', () => {
32
- const candidate = classifyProcessSnapshot(snapshot({
33
- agent: 'claude',
34
- pid: 6582,
35
- command: 'claude --resume session-1 --permission-mode acceptEdits',
36
- }));
37
- assert.deepEqual(candidate, {
38
- agent: 'claude',
39
- pid: 6582,
40
- cwd: '/repo',
41
- command: 'claude --resume session-1 --permission-mode acceptEdits',
42
- sessionId: 'session-1',
43
- confidence: 'high',
44
- approvalMode: 'acceptEdits',
45
- });
46
- });
47
- test('classifies explicit Claude bypass mode from process command', () => {
48
- const candidate = classifyProcessSnapshot(snapshot({
49
- agent: 'claude',
50
- pid: 6583,
51
- command: 'claude --resume session-2 --dangerously-skip-permissions',
52
- }));
53
- assert.equal(candidate?.approvalMode, 'autoApprove');
54
- });
55
- test('classifies a single codex rollout file as medium confidence', () => {
56
- const filePath = '/Users/test/.codex/sessions/2026/03/20/rollout-2026-03-20T08-37-12-019d08ac-c265-7270-9497-d14125228a50.jsonl';
57
- const candidate = classifyProcessSnapshot(snapshot({
58
- pid: 52424,
59
- sessionFiles: [filePath],
60
- }));
61
- assert.equal(candidate?.confidence, 'medium');
62
- assert.equal(candidate?.sessionId, '019d08ac-c265-7270-9497-d14125228a50');
63
- assert.equal(candidate?.sessionFilePath, filePath);
64
- });
65
- test('drops ambiguous app-server processes with multiple session files', () => {
66
- const candidate = classifyProcessSnapshot(snapshot({
67
- command: 'codex app-server',
68
- sessionFiles: [
69
- '/Users/test/.codex/sessions/2026/03/20/rollout-2026-03-20T08-37-12-019d08ac-c265-7270-9497-d14125228a50.jsonl',
70
- '/Users/test/.codex/sessions/2026/03/20/rollout-2026-03-20T08-42-17-019d08b1-67e6-75a1-bdb6-3c1b25b1103b.jsonl',
71
- ],
72
- }));
73
- assert.equal(candidate, null);
74
- });
75
- test('drops claude --continue without a unique session file', () => {
76
- const candidate = classifyProcessSnapshot(snapshot({
77
- agent: 'claude',
78
- command: 'claude --dangerously-skip-permissions --continue',
79
- sessionFiles: [],
80
- }));
81
- assert.equal(candidate, null);
82
- });
83
- test('drops claude subagent transcript files', () => {
84
- const candidate = classifyProcessSnapshot(snapshot({
85
- agent: 'claude',
86
- command: 'claude --dangerously-skip-permissions --continue',
87
- sessionFiles: [
88
- '/Users/test/.claude/projects/-Users-test/repo/subagents/agent-aa9cc4dbb140502a8.jsonl',
89
- ],
90
- }));
91
- assert.equal(candidate, null);
92
- });
93
- // ===== extractExplicitSessionId =====
94
- test('extracts claude session id from --resume flag', () => {
95
- assert.equal(extractExplicitSessionId('claude', 'claude --resume abc-123-def'), 'abc-123-def');
96
- });
97
- test('extracts claude session id from --resume= syntax', () => {
98
- assert.equal(extractExplicitSessionId('claude', 'claude --resume=abc-123-def'), 'abc-123-def');
99
- });
100
- test('returns null for claude without --resume', () => {
101
- assert.equal(extractExplicitSessionId('claude', 'claude --dangerously-skip-permissions --continue'), null);
102
- });
103
- test('returns null when --resume has no value', () => {
104
- assert.equal(extractExplicitSessionId('claude', 'claude --resume --other-flag'), null);
105
- });
106
- test('extracts codex session id from resume subcommand', () => {
107
- assert.equal(extractExplicitSessionId('codex', 'codex resume 019d03e3-2672-7011-9c6d-5ba083b71111'), '019d03e3-2672-7011-9c6d-5ba083b71111');
108
- });
109
- test('returns null for codex without resume subcommand', () => {
110
- assert.equal(extractExplicitSessionId('codex', 'codex --yolo'), null);
111
- });
112
- test('returns null when agent does not match binary in command', () => {
113
- assert.equal(extractExplicitSessionId('claude', 'codex resume abc-123'), null);
114
- });
115
- test('handles quoted tokens in command', () => {
116
- assert.equal(extractExplicitSessionId('claude', 'claude --resume "my-session-id"'), 'my-session-id');
117
- });
118
- test('handles full path to binary', () => {
119
- assert.equal(extractExplicitSessionId('claude', '/usr/local/bin/claude --resume sess-1'), 'sess-1');
120
- });
121
- test('extracts claude session id from shell-wrapped resume command', () => {
122
- assert.equal(extractExplicitSessionId('claude', "zsh -lc 'cd /repo && claude --resume sess-1'"), 'sess-1');
123
- });
124
- test('returns null for empty command', () => {
125
- assert.equal(extractExplicitSessionId('codex', ''), null);
126
- });
127
- // ===== relevant process command matching =====
128
- test('isRelevantProcessCommand matches shell-wrapped claude resume commands', () => {
129
- assert.equal(isRelevantProcessCommand("zsh -lc 'cd /repo && claude --resume sess-1'"), true);
130
- });
131
- test('isRelevantProcessCommand ignores binaries that only contain claude as a substring', () => {
132
- assert.equal(isRelevantProcessCommand("zsh -lc '/usr/local/bin/claude-wrapper --resume sess-1'"), false);
133
- });
134
- // ===== mergeRunningSessionCandidates (continued) =====
135
- test('dedupes duplicate running candidates by keeping the higher confidence entry', () => {
136
- const high = {
137
- agent: 'codex',
138
- pid: 6581,
139
- cwd: '/repo',
140
- command: 'codex resume 019d03e3-2672-7011-9c6d-5ba083b71111',
141
- sessionId: '019d03e3-2672-7011-9c6d-5ba083b71111',
142
- confidence: 'high',
143
- };
144
- const medium = {
145
- agent: 'codex',
146
- pid: 72545,
147
- cwd: '/repo',
148
- command: 'codex --yolo',
149
- sessionId: '019d03e3-2672-7011-9c6d-5ba083b71111',
150
- confidence: 'medium',
151
- title: 'Recovered title',
152
- sessionFilePath: '/Users/test/.codex/sessions/2026/03/20/rollout-2026-03-20T08-37-12-019d03e3-2672-7011-9c6d-5ba083b71111.jsonl',
153
- isResponding: true,
154
- };
155
- assert.deepEqual(mergeRunningSessionCandidates([medium, high]), [{
156
- ...high,
157
- title: 'Recovered title',
158
- sessionFilePath: medium.sessionFilePath,
159
- isResponding: true,
160
- }]);
161
- });
162
- test('mergeRunningSessionCandidates: keeps both when different sessionIds', () => {
163
- const a = {
164
- agent: 'codex', pid: 1, cwd: '/repo', command: 'codex',
165
- sessionId: 'aaa', confidence: 'high',
166
- };
167
- const b = {
168
- agent: 'codex', pid: 2, cwd: '/repo', command: 'codex',
169
- sessionId: 'bbb', confidence: 'high',
170
- };
171
- assert.equal(mergeRunningSessionCandidates([a, b]).length, 2);
172
- });
173
- test('mergeRunningSessionCandidates: returns empty for empty input', () => {
174
- assert.deepEqual(mergeRunningSessionCandidates([]), []);
175
- });
176
- // ===== classifyProcessSnapshot edge cases =====
177
- test('classifies claude --resume as high confidence', () => {
178
- const candidate = classifyProcessSnapshot(snapshot({
179
- agent: 'claude',
180
- command: 'claude --resume my-session-id-123',
181
- sessionFiles: [],
182
- }));
183
- assert.equal(candidate?.confidence, 'high');
184
- assert.equal(candidate?.sessionId, 'my-session-id-123');
185
- });
186
- test('classifies single claude project file as medium confidence', () => {
187
- const filePath = '/Users/test/.claude/projects/-Users-test-repo/session-abc.jsonl';
188
- const candidate = classifyProcessSnapshot(snapshot({
189
- agent: 'claude',
190
- command: 'claude --dangerously-skip-permissions',
191
- sessionFiles: [filePath],
192
- }));
193
- assert.equal(candidate?.confidence, 'medium');
194
- assert.equal(candidate?.sessionId, 'session-abc');
195
- });
196
- test('returns null for process with no session files and no explicit id', () => {
197
- const candidate = classifyProcessSnapshot(snapshot({
198
- command: 'codex app-server',
199
- sessionFiles: [],
200
- }));
201
- assert.equal(candidate, null);
202
- });
203
- test('filters out non-supported session file paths', () => {
204
- const candidate = classifyProcessSnapshot(snapshot({
205
- command: 'codex app-server',
206
- sessionFiles: ['/tmp/random.jsonl'],
207
- }));
208
- assert.equal(candidate, null);
209
- });
210
- // ===== extractExplicitSessionId edge cases =====
211
- test('extracts codex resume id skipping flags before session id', () => {
212
- assert.equal(extractExplicitSessionId('codex', 'codex resume --some-flag session-id-abc'), 'session-id-abc');
213
- });
214
- test('returns null for codex resume with only flags', () => {
215
- assert.equal(extractExplicitSessionId('codex', 'codex resume --flag-only'), null);
216
- });
217
- test('handles single-quoted session id', () => {
218
- assert.equal(extractExplicitSessionId('claude', "claude --resume 'my-session'"), 'my-session');
219
- });
220
- // ===== classifyProcessSnapshot edge cases =====
221
- test('classifies process with single codex session file in supported path', () => {
222
- const filePath = '/Users/test/.codex/sessions/2026/03/20/some-file-019d08ac-c265-7270-9497-d14125228a50.jsonl';
223
- const candidate = classifyProcessSnapshot(snapshot({
224
- command: 'codex app-server',
225
- sessionFiles: [filePath],
226
- }));
227
- assert.equal(candidate?.confidence, 'medium');
228
- assert.equal(candidate?.sessionFilePath, filePath);
229
- });
230
- test('classifies process with single claude project file', () => {
231
- const filePath = '/Users/test/.claude/projects/-Users-test-repo/my-session.jsonl';
232
- const candidate = classifyProcessSnapshot(snapshot({
233
- agent: 'claude',
234
- command: 'claude --continue',
235
- sessionFiles: [filePath],
236
- }));
237
- assert.equal(candidate?.confidence, 'medium');
238
- assert.equal(candidate?.sessionId, 'my-session');
239
- });
240
- test('ignores duplicate session files (dedupes before counting)', () => {
241
- const filePath = '/Users/test/.codex/sessions/2026/03/20/rollout-019d08ac-c265-7270-9497-d14125228a50.jsonl';
242
- const candidate = classifyProcessSnapshot(snapshot({
243
- command: 'codex app-server',
244
- sessionFiles: [filePath, filePath], // duplicate
245
- }));
246
- assert.equal(candidate?.confidence, 'medium');
247
- assert.equal(candidate?.sessionId, '019d08ac-c265-7270-9497-d14125228a50');
248
- });
249
- // ===== mergeRunningSessionCandidates edge cases =====
250
- test('mergeRunningSessionCandidates: same confidence uses lower PID as winner', () => {
251
- const a = {
252
- agent: 'codex', pid: 100, cwd: '/repo', command: 'codex',
253
- sessionId: 'same-id', confidence: 'medium',
254
- };
255
- const b = {
256
- agent: 'codex', pid: 200, cwd: '/other', command: 'codex',
257
- sessionId: 'same-id', confidence: 'medium',
258
- title: 'Title from B',
259
- };
260
- const result = mergeRunningSessionCandidates([a, b]);
261
- assert.equal(result.length, 1);
262
- assert.equal(result[0].pid, 100); // lower PID wins
263
- assert.equal(result[0].title, 'Title from B'); // title merged from loser
264
- });
265
- test('mergeRunningSessionCandidates: winner gets cwd from loser when winner has empty cwd', () => {
266
- const a = {
267
- agent: 'codex', pid: 1, cwd: '', command: 'codex',
268
- sessionId: 'id-1', confidence: 'high',
269
- };
270
- const b = {
271
- agent: 'codex', pid: 2, cwd: '/repo', command: 'codex',
272
- sessionId: 'id-1', confidence: 'low',
273
- };
274
- const result = mergeRunningSessionCandidates([a, b]);
275
- assert.equal(result[0].cwd, '/repo');
276
- });
277
- test('mergeRunningSessionCandidates: different agents are separate entries', () => {
278
- const a = {
279
- agent: 'codex', pid: 1, cwd: '/repo', command: 'codex',
280
- sessionId: 'same-id', confidence: 'high',
281
- };
282
- const b = {
283
- agent: 'claude', pid: 2, cwd: '/repo', command: 'claude',
284
- sessionId: 'same-id', confidence: 'high',
285
- };
286
- const result = mergeRunningSessionCandidates([a, b]);
287
- assert.equal(result.length, 2); // different agents = different keys
288
- });
289
- test('mergeRunningSessionCandidates: single candidate passes through', () => {
290
- const a = {
291
- agent: 'codex', pid: 42, cwd: '/repo', command: 'codex resume abc',
292
- sessionId: 'abc', confidence: 'high', title: 'My Title',
293
- };
294
- const result = mergeRunningSessionCandidates([a]);
295
- assert.equal(result.length, 1);
296
- assert.deepEqual(result[0], a);
297
- });
298
- // ===== extractExplicitSessionId: --session-id support =====
299
- test('extracts claude session id from --session-id flag', () => {
300
- assert.equal(extractExplicitSessionId('claude', 'claude --session-id 7f03bcf8-d5aa-4eb2-b123-abcdef012345'), '7f03bcf8-d5aa-4eb2-b123-abcdef012345');
301
- });
302
- test('extracts claude session id from --session-id= syntax', () => {
303
- assert.equal(extractExplicitSessionId('claude', 'claude --session-id=7f03bcf8-d5aa-4eb2-b123-abcdef012345'), '7f03bcf8-d5aa-4eb2-b123-abcdef012345');
304
- });
305
- test('extracts claude session id from full path binary with --session-id', () => {
306
- assert.equal(extractExplicitSessionId('claude', '/Users/test/.local/bin/claude --session-id abc-123'), 'abc-123');
307
- });
308
- test('classifies claude --session-id as high confidence', () => {
309
- const candidate = classifyProcessSnapshot(snapshot({
310
- agent: 'claude',
311
- command: '/Users/test/.local/bin/claude --session-id 7f03bcf8-d5aa-4eb2-b123-abcdef012345',
312
- sessionFiles: [],
313
- }));
314
- assert.equal(candidate?.confidence, 'high');
315
- assert.equal(candidate?.sessionId, '7f03bcf8-d5aa-4eb2-b123-abcdef012345');
316
- });
317
- // ===== hasContinueFlag =====
318
- test('hasContinueFlag detects --continue', () => {
319
- assert.equal(hasContinueFlag('claude', 'claude --dangerously-skip-permissions --continue'), true);
320
- });
321
- test('hasContinueFlag detects -c shorthand', () => {
322
- assert.equal(hasContinueFlag('claude', '/usr/local/bin/claude -c'), true);
323
- });
324
- test('hasContinueFlag returns false without --continue', () => {
325
- assert.equal(hasContinueFlag('claude', 'claude --resume abc'), false);
326
- });
327
- test('hasContinueFlag returns false for wrong agent', () => {
328
- assert.equal(hasContinueFlag('codex', 'claude --continue'), false);
329
- });
330
- // ===== cwd fallback: classifyProcessSnapshot returns null, scanRunningSessions uses filesystem =====
331
- test('classifyProcessSnapshot returns null for --continue without session files (fallback skipped)', () => {
332
- const candidate = classifyProcessSnapshot(snapshot({
333
- agent: 'claude',
334
- command: '/Users/test/.local/bin/claude --dangerously-skip-permissions --continue',
335
- cwd: '/some/project',
336
- sessionFiles: [],
337
- }));
338
- // classifyProcessSnapshot returns null; scanRunningSessions skips the mtime fallback for --continue
339
- assert.equal(candidate, null);
340
- });
341
- test('findRecentSessionFileForCwd matches Codex fallback by cwd instead of global newest file', async () => {
342
- const tempHome = await mkdtemp(join(tmpdir(), 'vibe-codex-cwd-'));
343
- const sessionsDir = join(tempHome, '.codex', 'sessions', '2026', '03', '21');
344
- const matchingOld = join(sessionsDir, 'matching-old.jsonl');
345
- const nonMatchingNewest = join(sessionsDir, 'other-cwd.jsonl');
346
- const matchingNewest = join(sessionsDir, 'matching-new.jsonl');
347
- const originalHome = process.env.HOME;
348
- await mkdir(sessionsDir, { recursive: true });
349
- await writeFile(matchingOld, `${JSON.stringify({ cwd: '/repo-a', id: 'codex-a-old', title: 'Old match' })}\n`);
350
- await writeFile(nonMatchingNewest, `${JSON.stringify({ cwd: '/repo-b', id: 'codex-b-new', title: 'Wrong cwd' })}\n`);
351
- await writeFile(matchingNewest, `${JSON.stringify({ cwd: '/repo-a', id: 'codex-a-new', title: 'New match' })}\n`);
352
- await utimes(matchingOld, new Date(1_000), new Date(1_000));
353
- await utimes(nonMatchingNewest, new Date(4_000), new Date(4_000));
354
- await utimes(matchingNewest, new Date(3_000), new Date(3_000));
355
- process.env.HOME = tempHome;
356
- try {
357
- const result = await findRecentSessionFileForCwd('codex', '/repo-a');
358
- assert.deepEqual(result, {
359
- sessionId: 'codex-a-new',
360
- filePath: matchingNewest,
361
- });
362
- }
363
- finally {
364
- process.env.HOME = originalHome;
365
- await rm(tempHome, { recursive: true, force: true });
366
- }
367
- });
368
- // ===== scanProcessSnapshots / scanRunningSessions (live system tests) =====
369
- import { scanProcessSnapshots, scanRunningSessions } from './process-scanner.js';
370
- test('scanProcessSnapshots returns an array', async () => {
371
- const snapshots = await scanProcessSnapshots();
372
- assert.ok(Array.isArray(snapshots));
373
- // Each snapshot should have the right shape
374
- for (const s of snapshots) {
375
- assert.equal(typeof s.pid, 'number');
376
- assert.ok(s.agent === 'claude' || s.agent === 'codex');
377
- assert.equal(typeof s.command, 'string');
378
- assert.equal(typeof s.cwd, 'string');
379
- assert.ok(Array.isArray(s.sessionFiles));
380
- }
381
- });
382
- test('scanRunningSessions returns an array of valid candidates', async () => {
383
- const candidates = await scanRunningSessions();
384
- assert.ok(Array.isArray(candidates));
385
- for (const c of candidates) {
386
- assert.equal(typeof c.sessionId, 'string');
387
- assert.ok(c.agent === 'claude' || c.agent === 'codex');
388
- assert.ok(['high', 'medium', 'low'].includes(c.confidence));
389
- }
390
- });
391
- // ─── isProcessAlive ──────────────────────────────────────────────────────────
392
- test('isProcessAlive returns true for the current process', () => {
393
- assert.equal(isProcessAlive(process.pid), true);
394
- });
395
- test('isProcessAlive returns false for a non-existent PID', () => {
396
- // PID 2147483647 (INT32_MAX) is almost certainly not in use.
397
- assert.equal(isProcessAlive(2147483647), false);
398
- });
399
- //# sourceMappingURL=process-scanner.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"process-scanner.test.js","sourceRoot":"","sources":["../src/process-scanner.test.ts"],"names":[],"mappings":"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"}