@synap-core/cli 1.12.2 → 1.13.1-next.20261102.246dc73

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 (358) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +38 -11
  3. package/dist/build-info.json +2 -3
  4. package/dist/commands/agents.d.ts +0 -1
  5. package/dist/commands/agents.js +13 -3
  6. package/dist/commands/agents.js.map +1 -1
  7. package/dist/commands/app.js +2 -1
  8. package/dist/commands/app.js.map +1 -1
  9. package/dist/commands/automation.js +46 -41
  10. package/dist/commands/automation.js.map +1 -1
  11. package/dist/commands/box.d.ts +42 -0
  12. package/dist/commands/box.js +89 -0
  13. package/dist/commands/box.js.map +1 -0
  14. package/dist/commands/bridge-setup.js +3 -1
  15. package/dist/commands/bridge-setup.js.map +1 -1
  16. package/dist/commands/capability.d.ts +87 -1
  17. package/dist/commands/capability.js +174 -64
  18. package/dist/commands/capability.js.map +1 -1
  19. package/dist/commands/close-questions.d.ts +27 -0
  20. package/dist/commands/close-questions.js +49 -0
  21. package/dist/commands/close-questions.js.map +1 -0
  22. package/dist/commands/close-questions.test.d.ts +1 -0
  23. package/dist/commands/close-questions.test.js +52 -0
  24. package/dist/commands/close-questions.test.js.map +1 -0
  25. package/dist/commands/connect.d.ts +1 -3
  26. package/dist/commands/connect.js +2 -2
  27. package/dist/commands/connect.js.map +1 -1
  28. package/dist/commands/context.js +74 -44
  29. package/dist/commands/context.js.map +1 -1
  30. package/dist/commands/data-extra.d.ts +13 -0
  31. package/dist/commands/data-extra.js +35 -6
  32. package/dist/commands/data-extra.js.map +1 -1
  33. package/dist/commands/data.js +2 -1
  34. package/dist/commands/data.js.map +1 -1
  35. package/dist/commands/doctor.d.ts +39 -0
  36. package/dist/commands/doctor.js +136 -14
  37. package/dist/commands/doctor.js.map +1 -1
  38. package/dist/commands/hooks.d.ts +19 -0
  39. package/dist/commands/hooks.js +70 -0
  40. package/dist/commands/hooks.js.map +1 -0
  41. package/dist/commands/import.d.ts +25 -0
  42. package/dist/commands/import.js +98 -12
  43. package/dist/commands/import.js.map +1 -1
  44. package/dist/commands/init.d.ts +14 -0
  45. package/dist/commands/init.js +63 -21
  46. package/dist/commands/init.js.map +1 -1
  47. package/dist/commands/keys-request.d.ts +48 -0
  48. package/dist/commands/keys-request.js +236 -0
  49. package/dist/commands/keys-request.js.map +1 -0
  50. package/dist/commands/keys-request.test.d.ts +1 -0
  51. package/dist/commands/keys-request.test.js +176 -0
  52. package/dist/commands/keys-request.test.js.map +1 -0
  53. package/dist/commands/knowledge.d.ts +42 -5
  54. package/dist/commands/knowledge.js +94 -29
  55. package/dist/commands/knowledge.js.map +1 -1
  56. package/dist/commands/lens.js +2 -1
  57. package/dist/commands/lens.js.map +1 -1
  58. package/dist/commands/market-authoring.js +1 -1
  59. package/dist/commands/market-authoring.js.map +1 -1
  60. package/dist/commands/market.d.ts +89 -31
  61. package/dist/commands/market.js +215 -222
  62. package/dist/commands/market.js.map +1 -1
  63. package/dist/commands/mcp.d.ts +1 -1
  64. package/dist/commands/mcp.js +14 -9
  65. package/dist/commands/mcp.js.map +1 -1
  66. package/dist/commands/observe.category.test.d.ts +1 -0
  67. package/dist/commands/observe.category.test.js +59 -0
  68. package/dist/commands/observe.category.test.js.map +1 -0
  69. package/dist/commands/observe.d.ts +3 -0
  70. package/dist/commands/observe.js +7 -5
  71. package/dist/commands/observe.js.map +1 -1
  72. package/dist/commands/observe.title.test.d.ts +1 -0
  73. package/dist/commands/observe.title.test.js +37 -0
  74. package/dist/commands/observe.title.test.js.map +1 -0
  75. package/dist/commands/playbook.js +9 -0
  76. package/dist/commands/playbook.js.map +1 -1
  77. package/dist/commands/pods.d.ts +6 -1
  78. package/dist/commands/pods.js +38 -17
  79. package/dist/commands/pods.js.map +1 -1
  80. package/dist/commands/proposals-actions.js +7 -1
  81. package/dist/commands/proposals-actions.js.map +1 -1
  82. package/dist/commands/proton-setup.js +3 -1
  83. package/dist/commands/proton-setup.js.map +1 -1
  84. package/dist/commands/providers.d.ts +22 -6
  85. package/dist/commands/providers.js +39 -32
  86. package/dist/commands/providers.js.map +1 -1
  87. package/dist/commands/raycast.d.ts +15 -0
  88. package/dist/commands/raycast.js +36 -10
  89. package/dist/commands/raycast.js.map +1 -1
  90. package/dist/commands/session-feed-wait.d.ts +48 -0
  91. package/dist/commands/session-feed-wait.js +261 -0
  92. package/dist/commands/session-feed-wait.js.map +1 -0
  93. package/dist/commands/session-post.d.ts +40 -0
  94. package/dist/commands/session-post.js +96 -0
  95. package/dist/commands/session-post.js.map +1 -0
  96. package/dist/commands/session-wait.d.ts +9 -4
  97. package/dist/commands/session-wait.js +20 -5
  98. package/dist/commands/session-wait.js.map +1 -1
  99. package/dist/commands/sessions.d.ts +2 -0
  100. package/dist/commands/sessions.js +23 -0
  101. package/dist/commands/sessions.js.map +1 -1
  102. package/dist/commands/skills-commands.d.ts +2 -0
  103. package/dist/commands/skills-commands.js +9 -1
  104. package/dist/commands/skills-commands.js.map +1 -1
  105. package/dist/commands/skills-commands.test.d.ts +1 -0
  106. package/dist/commands/skills-commands.test.js +57 -0
  107. package/dist/commands/skills-commands.test.js.map +1 -0
  108. package/dist/commands/status.js +13 -7
  109. package/dist/commands/status.js.map +1 -1
  110. package/dist/commands/statusline.backoff.test.js +13 -3
  111. package/dist/commands/statusline.backoff.test.js.map +1 -1
  112. package/dist/commands/statusline.d.ts +104 -9
  113. package/dist/commands/statusline.js +392 -148
  114. package/dist/commands/statusline.js.map +1 -1
  115. package/dist/commands/statusline.line2.test.d.ts +15 -0
  116. package/dist/commands/statusline.line2.test.js +226 -0
  117. package/dist/commands/statusline.line2.test.js.map +1 -0
  118. package/dist/commands/statusline.needs-you.test.d.ts +1 -0
  119. package/dist/commands/statusline.needs-you.test.js +17 -0
  120. package/dist/commands/statusline.needs-you.test.js.map +1 -0
  121. package/dist/commands/statusline.now.test.d.ts +10 -0
  122. package/dist/commands/statusline.now.test.js +250 -0
  123. package/dist/commands/statusline.now.test.js.map +1 -0
  124. package/dist/commands/tracks.d.ts +68 -6
  125. package/dist/commands/tracks.js +272 -16
  126. package/dist/commands/tracks.js.map +1 -1
  127. package/dist/commands/upload.js +12 -0
  128. package/dist/commands/upload.js.map +1 -1
  129. package/dist/commands/wait.d.ts +124 -0
  130. package/dist/commands/wait.js +384 -0
  131. package/dist/commands/wait.js.map +1 -0
  132. package/dist/commands/wait.test.d.ts +8 -0
  133. package/dist/commands/wait.test.js +308 -0
  134. package/dist/commands/wait.test.js.map +1 -0
  135. package/dist/commands/whoami.d.ts +7 -0
  136. package/dist/commands/whoami.js +17 -0
  137. package/dist/commands/whoami.js.map +1 -1
  138. package/dist/commands/worker-accounts.d.ts +149 -0
  139. package/dist/commands/worker-accounts.js +339 -0
  140. package/dist/commands/worker-accounts.js.map +1 -0
  141. package/dist/commands/worker-accounts.test.d.ts +1 -0
  142. package/dist/commands/worker-accounts.test.js +224 -0
  143. package/dist/commands/worker-accounts.test.js.map +1 -0
  144. package/dist/commands/worker-github-app.d.ts +63 -0
  145. package/dist/commands/worker-github-app.js +161 -0
  146. package/dist/commands/worker-github-app.js.map +1 -0
  147. package/dist/commands/worker-github-app.test.d.ts +1 -0
  148. package/dist/commands/worker-github-app.test.js +102 -0
  149. package/dist/commands/worker-github-app.test.js.map +1 -0
  150. package/dist/commands/worker-github-broker.d.ts +39 -0
  151. package/dist/commands/worker-github-broker.js +106 -0
  152. package/dist/commands/worker-github-broker.js.map +1 -0
  153. package/dist/commands/worker-github-broker.test.d.ts +1 -0
  154. package/dist/commands/worker-github-broker.test.js +90 -0
  155. package/dist/commands/worker-github-broker.test.js.map +1 -0
  156. package/dist/commands/worker-runs.test.d.ts +1 -0
  157. package/dist/commands/worker-runs.test.js +150 -0
  158. package/dist/commands/worker-runs.test.js.map +1 -0
  159. package/dist/commands/worker-worktrees.d.ts +34 -0
  160. package/dist/commands/worker-worktrees.js +87 -0
  161. package/dist/commands/worker-worktrees.js.map +1 -0
  162. package/dist/commands/worker.d.ts +406 -10
  163. package/dist/commands/worker.js +1180 -126
  164. package/dist/commands/worker.js.map +1 -1
  165. package/dist/commands/worker.test.js +588 -11
  166. package/dist/commands/worker.test.js.map +1 -1
  167. package/dist/index.js +220 -28
  168. package/dist/index.js.map +1 -1
  169. package/dist/lib/agent-door.d.ts +1 -3
  170. package/dist/lib/agent-door.js +10 -7
  171. package/dist/lib/agent-door.js.map +1 -1
  172. package/dist/lib/agents-config.d.ts +9 -0
  173. package/dist/lib/agents-config.js +20 -0
  174. package/dist/lib/agents-config.js.map +1 -1
  175. package/dist/lib/atomic-file.d.ts +20 -1
  176. package/dist/lib/atomic-file.js +100 -2
  177. package/dist/lib/atomic-file.js.map +1 -1
  178. package/dist/lib/auth.d.ts +28 -2
  179. package/dist/lib/auth.js +52 -12
  180. package/dist/lib/auth.js.map +1 -1
  181. package/dist/lib/box/egress.d.ts +82 -0
  182. package/dist/lib/box/egress.js +264 -0
  183. package/dist/lib/box/egress.js.map +1 -0
  184. package/dist/lib/box/evidence.d.ts +86 -0
  185. package/dist/lib/box/evidence.js +121 -0
  186. package/dist/lib/box/evidence.js.map +1 -0
  187. package/dist/lib/box/job-server.d.ts +72 -0
  188. package/dist/lib/box/job-server.js +250 -0
  189. package/dist/lib/box/job-server.js.map +1 -0
  190. package/dist/lib/box/provisioner.d.ts +83 -0
  191. package/dist/lib/box/provisioner.js +312 -0
  192. package/dist/lib/box/provisioner.js.map +1 -0
  193. package/dist/lib/box/proxmox.d.ts +112 -0
  194. package/dist/lib/box/proxmox.js +211 -0
  195. package/dist/lib/box/proxmox.js.map +1 -0
  196. package/dist/lib/box/wire.d.ts +98 -0
  197. package/dist/lib/box/wire.js +70 -0
  198. package/dist/lib/box/wire.js.map +1 -0
  199. package/dist/lib/bridge-invocation.test.d.ts +1 -0
  200. package/dist/lib/bridge-invocation.test.js +75 -0
  201. package/dist/lib/bridge-invocation.test.js.map +1 -0
  202. package/dist/lib/bridge-status.d.ts +144 -0
  203. package/dist/lib/bridge-status.js +227 -0
  204. package/dist/lib/bridge-status.js.map +1 -0
  205. package/dist/lib/bridge-status.test.d.ts +6 -0
  206. package/dist/lib/bridge-status.test.js +197 -0
  207. package/dist/lib/bridge-status.test.js.map +1 -0
  208. package/dist/lib/client-header.test.d.ts +1 -0
  209. package/dist/lib/client-header.test.js +103 -0
  210. package/dist/lib/client-header.test.js.map +1 -0
  211. package/dist/lib/conversation-headers.d.ts +89 -9
  212. package/dist/lib/conversation-headers.js +156 -3
  213. package/dist/lib/conversation-headers.js.map +1 -1
  214. package/dist/lib/conversation-headers.test.d.ts +1 -0
  215. package/dist/lib/conversation-headers.test.js +78 -0
  216. package/dist/lib/conversation-headers.test.js.map +1 -0
  217. package/dist/lib/credential-class.d.ts +40 -2
  218. package/dist/lib/credential-class.js +48 -6
  219. package/dist/lib/credential-class.js.map +1 -1
  220. package/dist/lib/device-connect.d.ts +45 -0
  221. package/dist/lib/device-connect.js +60 -0
  222. package/dist/lib/device-connect.js.map +1 -1
  223. package/dist/lib/exporter-coverage.d.ts +1 -1
  224. package/dist/lib/exporter-coverage.js +1 -1
  225. package/dist/lib/goal-words.d.ts +38 -0
  226. package/dist/lib/goal-words.js +115 -0
  227. package/dist/lib/goal-words.js.map +1 -0
  228. package/dist/lib/hub-client.d.ts +87 -8
  229. package/dist/lib/hub-client.js +205 -70
  230. package/dist/lib/hub-client.js.map +1 -1
  231. package/dist/lib/init-handoff.d.ts +8 -0
  232. package/dist/lib/init-handoff.js +9 -2
  233. package/dist/lib/init-handoff.js.map +1 -1
  234. package/dist/lib/key-locations.d.ts +3 -3
  235. package/dist/lib/key-locations.js +3 -39
  236. package/dist/lib/key-locations.js.map +1 -1
  237. package/dist/lib/key-source.d.ts +3 -1
  238. package/dist/lib/key-source.js +7 -4
  239. package/dist/lib/key-source.js.map +1 -1
  240. package/dist/lib/knowledge-title.d.ts +3 -2
  241. package/dist/lib/knowledge-title.js +3 -2
  242. package/dist/lib/knowledge-title.js.map +1 -1
  243. package/dist/lib/machine-instance.d.ts +7 -5
  244. package/dist/lib/machine-instance.js +7 -5
  245. package/dist/lib/machine-instance.js.map +1 -1
  246. package/dist/lib/mcp-bridge.d.ts +50 -0
  247. package/dist/lib/mcp-bridge.js +232 -11
  248. package/dist/lib/mcp-bridge.js.map +1 -1
  249. package/dist/lib/mcp-bridge.test.js +224 -4
  250. package/dist/lib/mcp-bridge.test.js.map +1 -1
  251. package/dist/lib/mcp-call.d.ts +5 -1
  252. package/dist/lib/mcp-call.js +7 -6
  253. package/dist/lib/mcp-call.js.map +1 -1
  254. package/dist/lib/mcp-connector-url.test.d.ts +1 -0
  255. package/dist/lib/mcp-connector-url.test.js +13 -0
  256. package/dist/lib/mcp-connector-url.test.js.map +1 -0
  257. package/dist/lib/mcp-snippets.d.ts +16 -0
  258. package/dist/lib/mcp-snippets.js +20 -2
  259. package/dist/lib/mcp-snippets.js.map +1 -1
  260. package/dist/lib/now-line.d.ts +66 -0
  261. package/dist/lib/now-line.js +193 -0
  262. package/dist/lib/now-line.js.map +1 -0
  263. package/dist/lib/now-line.test.d.ts +5 -0
  264. package/dist/lib/now-line.test.js +177 -0
  265. package/dist/lib/now-line.test.js.map +1 -0
  266. package/dist/lib/package-updates.d.ts +66 -0
  267. package/dist/lib/package-updates.js +76 -0
  268. package/dist/lib/package-updates.js.map +1 -0
  269. package/dist/lib/pod-moved.d.ts +70 -0
  270. package/dist/lib/pod-moved.js +146 -0
  271. package/dist/lib/pod-moved.js.map +1 -0
  272. package/dist/lib/pod-reach.d.ts +39 -0
  273. package/dist/lib/pod-reach.js +117 -0
  274. package/dist/lib/pod-reach.js.map +1 -0
  275. package/dist/lib/pod-reach.test.d.ts +1 -0
  276. package/dist/lib/pod-reach.test.js +67 -0
  277. package/dist/lib/pod-reach.test.js.map +1 -0
  278. package/dist/lib/pod.d.ts +8 -4
  279. package/dist/lib/pod.js +12 -10
  280. package/dist/lib/pod.js.map +1 -1
  281. package/dist/lib/register-claude-code-mcp.test.d.ts +1 -0
  282. package/dist/lib/register-claude-code-mcp.test.js +97 -0
  283. package/dist/lib/register-claude-code-mcp.test.js.map +1 -0
  284. package/dist/lib/review-credential.js +3 -1
  285. package/dist/lib/review-credential.js.map +1 -1
  286. package/dist/lib/safe-open.d.ts +5 -3
  287. package/dist/lib/safe-open.js +9 -8
  288. package/dist/lib/safe-open.js.map +1 -1
  289. package/dist/lib/self-host.d.ts +17 -0
  290. package/dist/lib/self-host.js +24 -0
  291. package/dist/lib/self-host.js.map +1 -0
  292. package/dist/lib/session-feed.d.ts +185 -0
  293. package/dist/lib/session-feed.js +257 -0
  294. package/dist/lib/session-feed.js.map +1 -0
  295. package/dist/lib/targets.d.ts +52 -3
  296. package/dist/lib/targets.js +150 -209
  297. package/dist/lib/targets.js.map +1 -1
  298. package/dist/lib/template-lifecycle.d.ts +0 -31
  299. package/dist/lib/template-lifecycle.js +0 -74
  300. package/dist/lib/template-lifecycle.js.map +1 -1
  301. package/dist/lib/term.d.ts +24 -0
  302. package/dist/lib/term.js +52 -0
  303. package/dist/lib/term.js.map +1 -0
  304. package/dist/lib/term.test.d.ts +1 -0
  305. package/dist/lib/term.test.js +29 -0
  306. package/dist/lib/term.test.js.map +1 -0
  307. package/dist/lib/transcript-index.d.ts +94 -0
  308. package/dist/lib/transcript-index.js +321 -0
  309. package/dist/lib/transcript-index.js.map +1 -0
  310. package/dist/lib/transcript-index.test.d.ts +10 -0
  311. package/dist/lib/transcript-index.test.js +200 -0
  312. package/dist/lib/transcript-index.test.js.map +1 -0
  313. package/dist/lib/wait-help.d.ts +11 -0
  314. package/dist/lib/wait-help.js +25 -0
  315. package/dist/lib/wait-help.js.map +1 -0
  316. package/dist/lib/wait-state.d.ts +57 -0
  317. package/dist/lib/wait-state.js +114 -0
  318. package/dist/lib/wait-state.js.map +1 -0
  319. package/dist/lib/wake-hook-settings.d.ts +57 -0
  320. package/dist/lib/wake-hook-settings.js +153 -0
  321. package/dist/lib/wake-hook-settings.js.map +1 -0
  322. package/dist/lib/wake-state.d.ts +65 -0
  323. package/dist/lib/wake-state.js +122 -0
  324. package/dist/lib/wake-state.js.map +1 -0
  325. package/package.json +5 -2
  326. package/skills/README.md +1 -1
  327. package/skills/agent-os/SKILL.md +8 -8
  328. package/skills/synap/SKILL.md +188 -94
  329. package/skills/synap/code-skills.md +84 -0
  330. package/skills/synap/concepts.md +38 -20
  331. package/skills/synap/creative-loop.md +1 -1
  332. package/skills/synap/document-embeds.md +17 -1
  333. package/skills/synap/focus-sessions.md +17 -8
  334. package/skills/synap/from-intent.md +33 -17
  335. package/skills/synap/governance-rules.md +3 -1
  336. package/skills/synap/hand-off.md +10 -6
  337. package/skills/synap/lenses.md +4 -4
  338. package/skills/synap/linking.md +2 -2
  339. package/skills/synap/mental-model.md +1 -1
  340. package/skills/synap/operating-mode-rules.md +1 -1
  341. package/skills/synap/quick-reference.md +2 -1
  342. package/skills/synap/reflexes.md +8 -8
  343. package/skills/synap/viewframe-cells.md +1 -1
  344. package/skills/synap/work-model.md +24 -10
  345. package/skills/synap/workspace-design.md +5 -5
  346. package/skills/synap/writes.md +16 -9
  347. package/skills/synap/writing-titles.md +7 -0
  348. package/skills/synap-app/SKILL.md +148 -66
  349. package/skills/synap-app/creating-the-base-app.md +12 -7
  350. package/skills/synap-app/governance.md +27 -16
  351. package/skills/synap-app/install-commands.md +18 -9
  352. package/skills/synap-app/overview.md +16 -9
  353. package/skills/synap-app/using-the-sdk.md +75 -25
  354. package/skills/synap-market/SKILL.md +1 -1
  355. package/skills/synap-market/governance-and-catalog.md +1 -1
  356. package/skills/synap-schema/SKILL.md +24 -21
  357. package/skills/synap-schema/intent-vocabulary-ssot.md +24 -21
  358. package/templates/box/runner.py +206 -0
@@ -0,0 +1,144 @@
1
+ /**
2
+ * The status line's 4th line from the pod, through the synap-bridge plugin's
3
+ * per-conversation status file (bridge 0.10, plan P3.3).
4
+ *
5
+ * After each read of the bound session the bridge writes
6
+ * `~/.synap/bridge/status/<Claude Code session id>.json`, whole (tmp + `mv -f`,
7
+ * so a reader never sees half a file): `{ v: 1, writtenAt, sessionId, title,
8
+ * live, nextMove, waitingOn, workUnits }`, each from the session's
9
+ * continuation packet. A section the pod could not read is `null`, never
10
+ * empty; `sessionId: null` = nothing is bound. The writer is the bridge's
11
+ * `statusFile` (synap-bridge `hooks/lib.ts`).
12
+ *
13
+ * The file is the FIRST source of what the conversation waits on; the
14
+ * transcript index (lib/now-line.ts) stays the fallback whenever the file is
15
+ * absent, unbound, stale or unreadable. The turn state itself (working /
16
+ * needs you / stopped) stays Claude Code's registry when it is readable: the
17
+ * pod's `live` is the bridge's relay of that same registry, smoothed by the
18
+ * pod's 5-minute rule, so it is used only when the registry is not there.
19
+ *
20
+ * ▶ working · 4m · ⏳ 2 · other work (2) · synap-cli#52 open ✗
21
+ * ⏳ waiting on 3 · other work (2) · approval · synap-cli#52 open ✓
22
+ * ■ stopped · next: Produce "Wave 2 report" · pod 40m ago
23
+ *
24
+ * Local files only, no network. `readBridgeStatus` never throws;
25
+ * `buildBridgeLine` is pure.
26
+ */
27
+ import { type RegistryEntry } from "./now-line.js";
28
+ /** The pod's working window (`SESSION_WORKING_WINDOW_MS`), for a file whose `live` carries none. */
29
+ export declare const POD_WORKING_WINDOW_MS: number;
30
+ /**
31
+ * A file older than this is stale even when no registry says when this
32
+ * Claude Code process started: beyond half a day nothing shows its writer
33
+ * still runs. A quiet file younger than this is still true (the bridge
34
+ * rewrites it on every change the pod's feed sends), and its age is shown.
35
+ */
36
+ export declare const BRIDGE_STATUS_MAX_AGE_MS: number;
37
+ export interface WaitingOnMark {
38
+ reason: string;
39
+ count: number;
40
+ refs?: Array<{
41
+ kind?: string;
42
+ id?: string;
43
+ label?: string;
44
+ }>;
45
+ }
46
+ export interface BridgeWorkUnit {
47
+ key: string | null;
48
+ label: string;
49
+ kind: string;
50
+ url: string | null;
51
+ state: string;
52
+ /** `{ status: "ok", label, state, checks? }` or `{ status: "unavailable", reason }`; null = none recorded. */
53
+ prState: {
54
+ status?: string;
55
+ label?: string;
56
+ state?: string;
57
+ checks?: string;
58
+ } | null;
59
+ }
60
+ /**
61
+ * Version 1 of the file, as the status line reads it. `live` is normalised on
62
+ * read: a field the bridge wrote malformed (bridge ≤ 0.11 wrote
63
+ * `measuredAt: "undefined"` and `windowMs: NaN`, which JSON stores as null
64
+ * when the pod sent none) is null here, never a reason to drop the file.
65
+ */
66
+ export interface BridgeStatusFile {
67
+ v: 1;
68
+ writtenAt: string;
69
+ sessionId: string | null;
70
+ title: string | null;
71
+ live: {
72
+ state: "working" | "idle";
73
+ turnInFlight: boolean;
74
+ since: string | null;
75
+ lastActivityAt: string | null;
76
+ measuredAt: string | null;
77
+ windowMs: number | null;
78
+ } | null;
79
+ nextMove: {
80
+ kind: string;
81
+ actor: string;
82
+ label: string;
83
+ reason: string;
84
+ } | null;
85
+ waitingOn: WaitingOnMark[] | null;
86
+ workUnits: BridgeWorkUnit[] | null;
87
+ }
88
+ /**
89
+ * What reading the file found. Only `fresh` is drawn; every other answer falls
90
+ * back to the transcript index. `absent` and `unbound` are normal (no bridge,
91
+ * nothing bound) and say nothing; `failed` (unreadable or malformed) is a
92
+ * failed read the line marks, never folded into "absent".
93
+ */
94
+ export type BridgeStatusRead = {
95
+ status: "fresh";
96
+ file: BridgeStatusFile;
97
+ writtenAt: number;
98
+ } | {
99
+ status: "absent";
100
+ } | {
101
+ status: "unbound";
102
+ } | {
103
+ status: "stale";
104
+ why: string;
105
+ } | {
106
+ status: "failed";
107
+ why: string;
108
+ };
109
+ export declare function bridgeStatusPath(claudeSessionId: string, home?: string): string;
110
+ /**
111
+ * The parsed JSON as a version-1 file, or why it is not one. Every string in
112
+ * it is scrubbed of control characters first (term.ts): the file carries pod
113
+ * words (titles, labels, PR names) that are printed as they are.
114
+ */
115
+ export declare function parseBridgeStatus(raw: unknown): BridgeStatusFile | string;
116
+ /**
117
+ * This conversation's status file, judged. Stale when it was written before
118
+ * this Claude Code process started (`startedAt`, from the registry: the
119
+ * bridge of an earlier process wrote it, and this one has not confirmed the
120
+ * binding yet), or is older than BRIDGE_STATUS_MAX_AGE_MS. Never throws.
121
+ */
122
+ export declare function readBridgeStatus(claudeSessionId: string, opts: {
123
+ now: number;
124
+ startedAt?: number;
125
+ home?: string;
126
+ }): BridgeStatusRead;
127
+ /**
128
+ * The pod's rule (`isSessionWorkingNow`) on the file's `live`, judged now.
129
+ *
130
+ * `turnInFlight` is the pod's word AT `measuredAt` (else when the file was
131
+ * written, `writtenAt`), not now: it holds for one working window after that
132
+ * and no longer. Read as "now", a file the bridge last wrote mid-turn said
133
+ * "working" for as long as the file stayed fresh (12 h).
134
+ */
135
+ export declare function podWorking(live: NonNullable<BridgeStatusFile["live"]>, now: number, writtenAt?: number): boolean;
136
+ export interface BridgeLineInput {
137
+ now: number;
138
+ file: BridgeStatusFile;
139
+ writtenAt: number;
140
+ registry: RegistryEntry | null;
141
+ width?: number;
142
+ }
143
+ /** The 4th line from a fresh status file. */
144
+ export declare function buildBridgeLine(input: BridgeLineInput): string;
@@ -0,0 +1,227 @@
1
+ /**
2
+ * The status line's 4th line from the pod, through the synap-bridge plugin's
3
+ * per-conversation status file (bridge 0.10, plan P3.3).
4
+ *
5
+ * After each read of the bound session the bridge writes
6
+ * `~/.synap/bridge/status/<Claude Code session id>.json`, whole (tmp + `mv -f`,
7
+ * so a reader never sees half a file): `{ v: 1, writtenAt, sessionId, title,
8
+ * live, nextMove, waitingOn, workUnits }`, each from the session's
9
+ * continuation packet. A section the pod could not read is `null`, never
10
+ * empty; `sessionId: null` = nothing is bound. The writer is the bridge's
11
+ * `statusFile` (synap-bridge `hooks/lib.ts`).
12
+ *
13
+ * The file is the FIRST source of what the conversation waits on; the
14
+ * transcript index (lib/now-line.ts) stays the fallback whenever the file is
15
+ * absent, unbound, stale or unreadable. The turn state itself (working /
16
+ * needs you / stopped) stays Claude Code's registry when it is readable: the
17
+ * pod's `live` is the bridge's relay of that same registry, smoothed by the
18
+ * pod's 5-minute rule, so it is used only when the registry is not there.
19
+ *
20
+ * ▶ working · 4m · ⏳ 2 · other work (2) · synap-cli#52 open ✗
21
+ * ⏳ waiting on 3 · other work (2) · approval · synap-cli#52 open ✓
22
+ * ■ stopped · next: Produce "Wave 2 report" · pod 40m ago
23
+ *
24
+ * Local files only, no network. `readBridgeStatus` never throws;
25
+ * `buildBridgeLine` is pure.
26
+ */
27
+ import fs from "node:fs";
28
+ import os from "node:os";
29
+ import path from "node:path";
30
+ import { WAITING_ON_REASON_LABELS, goalWord } from "./goal-words.js";
31
+ import { age, capped, clip, DEFAULT_WIDTH } from "./now-line.js";
32
+ import { AMBER as A, BOLD_YELLOW as Y, CYAN as C, DIM as D, GREEN as G, RED as R, RESET as X, osc8, scrubStrings } from "./term.js";
33
+ /** The pod's working window (`SESSION_WORKING_WINDOW_MS`), for a file whose `live` carries none. */
34
+ export const POD_WORKING_WINDOW_MS = 5 * 60_000;
35
+ /**
36
+ * A file older than this is stale even when no registry says when this
37
+ * Claude Code process started: beyond half a day nothing shows its writer
38
+ * still runs. A quiet file younger than this is still true (the bridge
39
+ * rewrites it on every change the pod's feed sends), and its age is shown.
40
+ */
41
+ export const BRIDGE_STATUS_MAX_AGE_MS = 12 * 60 * 60_000;
42
+ export function bridgeStatusPath(claudeSessionId, home = os.homedir()) {
43
+ return path.join(home, ".synap", "bridge", "status", `${claudeSessionId}.json`);
44
+ }
45
+ const isObj = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
46
+ const isTime = (v) => typeof v === "string" && Number.isFinite(Date.parse(v));
47
+ const isStrOrNull = (v) => v === null || typeof v === "string";
48
+ /**
49
+ * The file's `live`, normalised. One malformed field costs that field (null),
50
+ * and a `live` that is no object at all reads as "not measured" (null): the
51
+ * rest of the file is still true, so it is never a failed read.
52
+ */
53
+ function readLive(v) {
54
+ if (!isObj(v))
55
+ return null;
56
+ const windowMs = typeof v.windowMs === "number" && Number.isFinite(v.windowMs) && v.windowMs > 0 ? v.windowMs : null;
57
+ return {
58
+ state: v.state === "working" ? "working" : "idle",
59
+ turnInFlight: v.turnInFlight === true,
60
+ since: isTime(v.since) ? v.since : null,
61
+ lastActivityAt: isTime(v.lastActivityAt) ? v.lastActivityAt : null,
62
+ measuredAt: isTime(v.measuredAt) ? v.measuredAt : null,
63
+ windowMs,
64
+ };
65
+ }
66
+ /**
67
+ * The parsed JSON as a version-1 file, or why it is not one. Every string in
68
+ * it is scrubbed of control characters first (term.ts): the file carries pod
69
+ * words (titles, labels, PR names) that are printed as they are.
70
+ */
71
+ export function parseBridgeStatus(raw) {
72
+ const json = scrubStrings(raw);
73
+ if (!isObj(json))
74
+ return "not an object";
75
+ if (json.v !== 1)
76
+ return `version ${JSON.stringify(json.v)} is not 1`;
77
+ if (!isTime(json.writtenAt))
78
+ return "no writtenAt time";
79
+ if (!isStrOrNull(json.sessionId))
80
+ return "sessionId is not a string";
81
+ if (!isStrOrNull(json.title ?? null))
82
+ return "title is not a string";
83
+ const live = readLive(json.live);
84
+ const next = json.nextMove ?? null;
85
+ if (next !== null && (!isObj(next) || typeof next.label !== "string"))
86
+ return "nextMove is malformed";
87
+ const waits = json.waitingOn ?? null;
88
+ if (waits !== null && (!Array.isArray(waits) || !waits.every((m) => isObj(m) && typeof m.reason === "string" && typeof m.count === "number")))
89
+ return "waitingOn is malformed";
90
+ const units = json.workUnits ?? null;
91
+ if (units !== null && (!Array.isArray(units) || !units.every((u) => isObj(u) && typeof u.label === "string" && typeof u.state === "string")))
92
+ return "workUnits is malformed";
93
+ return {
94
+ v: 1,
95
+ writtenAt: json.writtenAt,
96
+ sessionId: json.sessionId,
97
+ title: json.title ?? null,
98
+ live,
99
+ nextMove: next,
100
+ waitingOn: waits,
101
+ workUnits: units,
102
+ };
103
+ }
104
+ /**
105
+ * This conversation's status file, judged. Stale when it was written before
106
+ * this Claude Code process started (`startedAt`, from the registry: the
107
+ * bridge of an earlier process wrote it, and this one has not confirmed the
108
+ * binding yet), or is older than BRIDGE_STATUS_MAX_AGE_MS. Never throws.
109
+ */
110
+ export function readBridgeStatus(claudeSessionId, opts) {
111
+ // A session id becomes a file name: anything that could leave the directory is no file.
112
+ if (!/^[A-Za-z0-9_-]+$/.test(claudeSessionId))
113
+ return { status: "absent" };
114
+ let raw;
115
+ try {
116
+ raw = fs.readFileSync(bridgeStatusPath(claudeSessionId, opts.home), "utf-8");
117
+ }
118
+ catch (e) {
119
+ if (e.code === "ENOENT")
120
+ return { status: "absent" };
121
+ return { status: "failed", why: `unreadable (${e.code ?? "error"})` };
122
+ }
123
+ let json;
124
+ try {
125
+ json = JSON.parse(raw);
126
+ }
127
+ catch {
128
+ return { status: "failed", why: "not JSON" };
129
+ }
130
+ const file = parseBridgeStatus(json);
131
+ if (typeof file === "string")
132
+ return { status: "failed", why: file };
133
+ const writtenAt = Date.parse(file.writtenAt);
134
+ if (opts.startedAt && writtenAt < opts.startedAt)
135
+ return { status: "stale", why: "written before this Claude Code process started" };
136
+ if (opts.now - writtenAt > BRIDGE_STATUS_MAX_AGE_MS)
137
+ return { status: "stale", why: `written ${age(opts.now - writtenAt)} ago` };
138
+ if (file.sessionId === null)
139
+ return { status: "unbound" };
140
+ return { status: "fresh", file, writtenAt };
141
+ }
142
+ // ── The line ───────────────────────────────────────────────────────────
143
+ /** One mark: `other work (2)`, words through the vocabulary's table (goal-words.ts). */
144
+ function markText(m) {
145
+ const reason = goalWord(WAITING_ON_REASON_LABELS, m.reason).toLowerCase();
146
+ return m.count > 1 ? `${reason} (${m.count})` : reason;
147
+ }
148
+ /** A pull request still under way: `synap-cli#52 open ✗`, its name a link to it. */
149
+ function unitText(u) {
150
+ const isPr = u.kind === "pull_request" || /\/pull\/\d+/.test(u.url ?? "");
151
+ if (!isPr || (u.state !== "open" && u.state !== "claimed"))
152
+ return null;
153
+ const name = osc8(u.url, /^\S+#\d+/.exec(u.label)?.[0] ?? clip(u.label, 30));
154
+ const p = u.prState;
155
+ if (!p)
156
+ return name; // the pod recorded nothing about it: draw nothing, never a guess
157
+ if (p.status !== "ok")
158
+ return `${name} ${D}⚑ not read${X}`;
159
+ const word = (p.label ?? p.state ?? "").toLowerCase();
160
+ const checks = p.checks === "passed" ? ` ${G}✓${X}` : p.checks === "failed" ? ` ${R}✗${X}` : "";
161
+ return `${name}${word ? ` ${D}${word}${X}` : ""}${checks}`;
162
+ }
163
+ /**
164
+ * The pod's rule (`isSessionWorkingNow`) on the file's `live`, judged now.
165
+ *
166
+ * `turnInFlight` is the pod's word AT `measuredAt` (else when the file was
167
+ * written, `writtenAt`), not now: it holds for one working window after that
168
+ * and no longer. Read as "now", a file the bridge last wrote mid-turn said
169
+ * "working" for as long as the file stayed fresh (12 h).
170
+ */
171
+ export function podWorking(live, now, writtenAt) {
172
+ const window = live.windowMs ?? POD_WORKING_WINDOW_MS;
173
+ const last = live.lastActivityAt ? Date.parse(live.lastActivityAt) : NaN;
174
+ if (Number.isFinite(last) && now - last <= window)
175
+ return true;
176
+ if (!live.turnInFlight)
177
+ return false;
178
+ const measured = live.measuredAt ? Date.parse(live.measuredAt) : writtenAt ?? NaN;
179
+ return Number.isFinite(measured) && now - measured <= window;
180
+ }
181
+ /** The 4th line from a fresh status file. */
182
+ export function buildBridgeLine(input) {
183
+ const { now, file, registry } = input;
184
+ const width = input.width && input.width > 20 ? input.width : DEFAULT_WIDTH;
185
+ if (registry?.status === "waiting") {
186
+ return `${Y}✋ needs you${X} ${D}·${X} ${clip(registry.waitingFor || "your answer", width - 16)}`;
187
+ }
188
+ const marks = (file.waitingOn ?? []).filter((m) => m.count > 0);
189
+ const waited = marks.reduce((n, m) => n + m.count, 0);
190
+ const units = (file.workUnits ?? []).map(unitText).filter((t) => t !== null);
191
+ const unread = [file.waitingOn === null && "waits", file.workUnits === null && "PRs"].filter(Boolean);
192
+ // The registry's turn state when there is one; the pod's relay of it otherwise.
193
+ let working = false;
194
+ let since;
195
+ if (registry) {
196
+ working = registry.status === "busy";
197
+ since = registry.statusUpdatedAt;
198
+ }
199
+ else if (file.live) {
200
+ working = podWorking(file.live, now, input.writtenAt);
201
+ const at = Date.parse((working ? file.live.since : file.live.lastActivityAt) ?? "");
202
+ since = Number.isFinite(at) ? at : undefined;
203
+ }
204
+ const items = [...marks.map(markText), ...units];
205
+ if (!working && file.nextMove?.label)
206
+ items.push(`${D}next:${X} ${clip(file.nextMove.label, 60)}`);
207
+ if (unread.length)
208
+ items.push(`${D}⚑ not read: ${unread.join(", ")}${X}`);
209
+ // A quiet file is still true, but say how old the pod's word is.
210
+ if (now - input.writtenAt > POD_WORKING_WINDOW_MS)
211
+ items.push(`${D}pod ${age(now - input.writtenAt)} ago${X}`);
212
+ let head;
213
+ if (working) {
214
+ head = `${C}▶ working${X}${since ? ` ${D}· ${age(now - since)}${X}` : ""}${waited ? ` ${D}·${X} ⏳ ${waited}` : ""}`;
215
+ }
216
+ else if (waited) {
217
+ head = `${Y}⏳ waiting on ${waited}${X}`;
218
+ }
219
+ else if (!registry && !file.live) {
220
+ head = `${D}○ no session status${X}`;
221
+ }
222
+ else {
223
+ head = `${A}■ stopped${X}${since ? ` ${D}· ${age(now - since)}${X}` : ""}`;
224
+ }
225
+ return capped(head, items, width);
226
+ }
227
+ //# sourceMappingURL=bridge-status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bridge-status.js","sourceRoot":"","sources":["../../src/lib/bridge-status.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * The bridge's status file as the status line reads it: judged (fresh /
3
+ * absent / unbound / stale / failed) and drawn. Files go under a temp HOME
4
+ * passed as `home`; time, registry and width are arguments.
5
+ */
6
+ export {};
@@ -0,0 +1,197 @@
1
+ /**
2
+ * The bridge's status file as the status line reads it: judged (fresh /
3
+ * absent / unbound / stale / failed) and drawn. Files go under a temp HOME
4
+ * passed as `home`; time, registry and width are arguments.
5
+ */
6
+ import fs from "node:fs";
7
+ import os from "node:os";
8
+ import path from "node:path";
9
+ import { describe, it, expect, beforeEach } from "vitest";
10
+ import { BRIDGE_STATUS_MAX_AGE_MS, bridgeStatusPath, buildBridgeLine, readBridgeStatus, } from "./bridge-status.js";
11
+ const NOW = Date.parse("2026-10-30T22:00:00Z");
12
+ const min = (m) => NOW - m * 60_000;
13
+ const iso = (ms) => new Date(ms).toISOString();
14
+ // eslint-disable-next-line no-control-regex
15
+ const plain = (s) => s.replace(/\x1b\[[0-9;]*m|\x1b\]8;;[^\x1b]*\x1b\\/g, "");
16
+ const CONV = "11111111-2222-3333-4444-555555555555";
17
+ /** A file as the bridge's `statusFile` writes it (synap-bridge hooks/lib.ts). */
18
+ const file = (over = {}) => ({
19
+ v: 1,
20
+ writtenAt: iso(min(1)),
21
+ sessionId: "54436c32-783f-4a9d-9322-16ff18f448f7",
22
+ title: "Lane cli-statusfile",
23
+ live: { state: "idle", turnInFlight: false, since: iso(min(20)), lastActivityAt: iso(min(20)), measuredAt: iso(min(1)), windowMs: 300_000 },
24
+ nextMove: { kind: "agent_slot", actor: "ai", label: 'Produce "Wave 2 report"', reason: "Declared deliverable with no output yet" },
25
+ waitingOn: [],
26
+ workUnits: [],
27
+ ...over,
28
+ });
29
+ const reg = (status, extra = {}) => ({
30
+ sessionId: CONV,
31
+ pid: 1,
32
+ status,
33
+ statusUpdatedAt: min(4),
34
+ startedAt: min(600),
35
+ ...extra,
36
+ });
37
+ let home;
38
+ beforeEach(() => {
39
+ home = fs.mkdtempSync(path.join(os.tmpdir(), "bridge-status-"));
40
+ });
41
+ const write = (content) => {
42
+ const p = bridgeStatusPath(CONV, home);
43
+ fs.mkdirSync(path.dirname(p), { recursive: true });
44
+ fs.writeFileSync(p, content);
45
+ };
46
+ const read = (opts = {}) => readBridgeStatus(CONV, { now: NOW, home, ...opts });
47
+ describe("reading the file", () => {
48
+ it("is where the bridge writes it", () => {
49
+ expect(bridgeStatusPath(CONV, "/home/x")).toBe(`/home/x/.synap/bridge/status/${CONV}.json`);
50
+ });
51
+ it("a fresh file of a bound session is drawn", () => {
52
+ write(JSON.stringify(file()));
53
+ const r = read({ startedAt: min(600) });
54
+ expect(r.status).toBe("fresh");
55
+ if (r.status === "fresh")
56
+ expect(r.writtenAt).toBe(min(1));
57
+ });
58
+ it("no file is absent (no bridge, or it has not written yet)", () => {
59
+ expect(read()).toEqual({ status: "absent" });
60
+ });
61
+ it("nothing bound (`sessionId: null`, /bridge unbind) is unbound, not drawn", () => {
62
+ write(JSON.stringify(file({ sessionId: null, title: null })));
63
+ expect(read()).toEqual({ status: "unbound" });
64
+ });
65
+ it("a file written before this Claude Code process started is stale", () => {
66
+ write(JSON.stringify(file({ writtenAt: iso(min(90)) })));
67
+ expect(read({ startedAt: min(60) })).toEqual({ status: "stale", why: "written before this Claude Code process started" });
68
+ });
69
+ it("a file older than the max age is stale, even with no registry", () => {
70
+ write(JSON.stringify(file({ writtenAt: iso(NOW - BRIDGE_STATUS_MAX_AGE_MS - 60_000) })));
71
+ expect(read()).toMatchObject({ status: "stale" });
72
+ });
73
+ it("a quiet file younger than the max age is still fresh", () => {
74
+ write(JSON.stringify(file({ writtenAt: iso(min(45)) })));
75
+ expect(read({ startedAt: min(600) }).status).toBe("fresh");
76
+ });
77
+ it("malformed JSON is a failed read, never absent, and never throws", () => {
78
+ write('{"v":1,"writtenAt":');
79
+ expect(read()).toEqual({ status: "failed", why: "not JSON" });
80
+ });
81
+ it("another version, a missing time or a malformed section is a failed read", () => {
82
+ write(JSON.stringify({ ...file(), v: 2 }));
83
+ expect(read()).toMatchObject({ status: "failed", why: "version 2 is not 1" });
84
+ write(JSON.stringify({ ...file(), writtenAt: "soon" }));
85
+ expect(read()).toMatchObject({ status: "failed", why: "no writtenAt time" });
86
+ write(JSON.stringify({ ...file(), waitingOn: { status: "ok", marks: [] } }));
87
+ expect(read()).toMatchObject({ status: "failed", why: "waitingOn is malformed" });
88
+ write("[]");
89
+ expect(read()).toMatchObject({ status: "failed", why: "not an object" });
90
+ });
91
+ it("a malformed `live` costs only its own fields, never the file (bridge ≤ 0.11 wrote NaN and \"undefined\")", () => {
92
+ // What `String(undefined)` and `Number(undefined)` (NaN → null in JSON) leave in the file.
93
+ write(JSON.stringify({ ...file(), live: { state: "idle", turnInFlight: false, since: null, lastActivityAt: null, measuredAt: "undefined", windowMs: null } }));
94
+ const r = read({ startedAt: min(600) });
95
+ expect(r.status).toBe("fresh");
96
+ if (r.status === "fresh")
97
+ expect(r.file.live).toEqual({ state: "idle", turnInFlight: false, since: null, lastActivityAt: null, measuredAt: null, windowMs: null });
98
+ write(JSON.stringify({ ...file(), live: { state: "working" } }));
99
+ expect(read().status).toBe("fresh");
100
+ write(JSON.stringify({ ...file(), live: "undefined" }));
101
+ const s = read();
102
+ expect(s.status).toBe("fresh");
103
+ if (s.status === "fresh")
104
+ expect(s.file.live).toBeNull();
105
+ });
106
+ it("every string in the file is scrubbed of control characters", () => {
107
+ write(JSON.stringify(file({
108
+ nextMove: { kind: "agent_slot", actor: "ai", label: "Open\x1b]8;;https://evil.test\x1b\\ the PR\x07", reason: "" },
109
+ workUnits: [{ key: "a", label: "backend#7\x1b[2J x", kind: "pull_request", url: "https://github.com/Synap-core/backend/pull/7\x1b\\", state: "open", prState: null }],
110
+ })));
111
+ const r = read({ startedAt: min(600) });
112
+ expect(r.status).toBe("fresh");
113
+ if (r.status !== "fresh")
114
+ return;
115
+ const raw = buildBridgeLine({ now: NOW, file: r.file, writtenAt: r.writtenAt, registry: reg("idle") });
116
+ expect(raw).not.toContain("https://evil.test\x1b");
117
+ expect(raw).not.toContain("\x1b[2J");
118
+ expect(raw).not.toContain("\x07");
119
+ // The URL's own ESC is gone (its backslash is left, inert); our link around the PR name is intact.
120
+ expect(raw).toContain("\x1b]8;;https://github.com/Synap-core/backend/pull/7\\\x1b\\backend#7\x1b]8;;\x1b\\");
121
+ expect(plain(raw)).toContain("next: Open]8;;https://evil.test\\ the PR");
122
+ });
123
+ it("an unreadable file (here a directory) is a failed read", () => {
124
+ fs.mkdirSync(bridgeStatusPath(CONV, home), { recursive: true });
125
+ expect(read()).toMatchObject({ status: "failed", why: expect.stringContaining("unreadable") });
126
+ });
127
+ it("a session id that could leave the directory reads no file", () => {
128
+ expect(readBridgeStatus("../../etc/passwd", { now: NOW, home })).toEqual({ status: "absent" });
129
+ });
130
+ });
131
+ const line = (f, registry = reg("idle"), width) => plain(buildBridgeLine({ now: NOW, file: f, writtenAt: Date.parse(f.writtenAt), registry, width }));
132
+ describe("drawing the line", () => {
133
+ it("idle with nothing waited on: stopped, with the pod's next move", () => {
134
+ expect(line(file())).toBe('■ stopped · 4m · next: Produce "Wave 2 report"');
135
+ });
136
+ it("idle and waiting: the pod's marks, in the vocabulary's words, and the open PRs", () => {
137
+ const f = file({
138
+ waitingOn: [
139
+ { reason: "another_work", count: 2, refs: [{ kind: "session", id: "s2" }] },
140
+ { reason: "approval", count: 1 },
141
+ ],
142
+ workUnits: [
143
+ { key: "pr-synap-cli-52", label: "synap-cli#52 feat(statusline): read the bridge file", kind: "pull_request", url: "https://github.com/Synap-core/synap-cli/pull/52", state: "open", prState: { status: "ok", label: "Open", state: "open", checks: "failed" } },
144
+ { key: "pr-backend-9", label: "backend#9 done already", kind: "pull_request", url: "https://github.com/Synap-core/backend/pull/9", state: "met", prState: { status: "ok", label: "Merged", state: "merged" } },
145
+ ],
146
+ });
147
+ expect(line(f)).toBe('⏳ waiting on 3 · other work (2) · approval · synap-cli#52 open ✗ · next: Produce "Wave 2 report"');
148
+ });
149
+ it("working (the registry says busy): the marks follow, the next move does not", () => {
150
+ const f = file({ waitingOn: [{ reason: "input", count: 1 }] });
151
+ expect(line(f, reg("busy", { statusUpdatedAt: min(3) }))).toBe("▶ working · 3m · ⏳ 1 · input");
152
+ });
153
+ it("the registry's permission prompt beats everything", () => {
154
+ expect(line(file(), reg("waiting", { waitingFor: "permission prompt" }))).toBe("✋ needs you · permission prompt");
155
+ });
156
+ it("no registry: the pod's live, re-judged now by its own window", () => {
157
+ const working = file({ live: { state: "working", turnInFlight: false, since: iso(min(2)), lastActivityAt: iso(min(2)), measuredAt: iso(min(1)), windowMs: 300_000 } });
158
+ expect(line(working, null)).toBe("▶ working · 2m");
159
+ // Measured as working, but its last activity is now past the window: idle.
160
+ const lapsed = file({ live: { state: "working", turnInFlight: false, since: iso(min(8)), lastActivityAt: iso(min(8)), measuredAt: iso(min(1)), windowMs: 300_000 } });
161
+ expect(line(lapsed, null)).toBe('■ stopped · 8m · next: Produce "Wave 2 report"');
162
+ expect(line(file({ live: null }), null)).toBe('○ no session status · next: Produce "Wave 2 report"');
163
+ });
164
+ it("a turn in flight is the pod's word at `measuredAt`: it lapses one window later, never 12 h later", () => {
165
+ const inFlight = (measured, windowMs = 300_000) => file({ live: { state: "working", turnInFlight: true, since: iso(min(700)), lastActivityAt: iso(min(700)), measuredAt: iso(measured), windowMs } });
166
+ expect(line(inFlight(min(1)), null)).toBe("▶ working · 11h40");
167
+ // Written mid-turn 6 h ago and never rewritten: not "working".
168
+ expect(line(inFlight(min(360)), null)).toBe('■ stopped · 11h40 · next: Produce "Wave 2 report"');
169
+ // No usable measurement time: the time the file was written bounds it, and the pod's default window applies.
170
+ const unmeasured = file({ writtenAt: iso(min(30)), live: { ...inFlight(min(1)).live, measuredAt: null, windowMs: null } });
171
+ expect(line(unmeasured, null)).toBe('■ stopped · 11h40 · next: Produce "Wave 2 report" · pod 30m ago');
172
+ expect(line({ ...unmeasured, writtenAt: iso(min(2)) }, null)).toBe("▶ working · 11h40");
173
+ });
174
+ it("a section the pod could not read is said, never drawn as nothing", () => {
175
+ expect(line(file({ waitingOn: null, workUnits: null, nextMove: null }))).toBe("■ stopped · 4m · ⚑ not read: waits, PRs");
176
+ });
177
+ it("a PR whose state the pod could not read is marked; one with nothing recorded is just named", () => {
178
+ const f = file({
179
+ nextMove: null,
180
+ workUnits: [
181
+ { key: "a", label: "backend#7 x", kind: "pull_request", url: "https://github.com/Synap-core/backend/pull/7", state: "open", prState: { status: "unavailable" } },
182
+ { key: "b", label: "relay-app#3 y", kind: "pull_request", url: null, state: "claimed", prState: null },
183
+ ],
184
+ });
185
+ expect(line(f)).toBe("■ stopped · 4m · backend#7 ⚑ not read · relay-app#3");
186
+ });
187
+ it("a quiet file says how old the pod's word is", () => {
188
+ expect(line(file({ writtenAt: iso(min(40)), nextMove: null }))).toBe("■ stopped · 4m · pod 40m ago");
189
+ });
190
+ it("caps itself to the width", () => {
191
+ const f = file({ waitingOn: Array.from({ length: 6 }, (_, i) => ({ reason: `reason_${i}`, count: 1 })) });
192
+ const out = line(f, reg("idle"), 50);
193
+ expect(out.length).toBeLessThanOrEqual(50);
194
+ expect(out).toMatch(/\+\d+ more$/);
195
+ });
196
+ });
197
+ //# sourceMappingURL=bridge-status.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bridge-status.test.js","sourceRoot":"","sources":["../../src/lib/bridge-status.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};