@polderlabs/bizar-omp 0.7.0 → 0.7.2

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 (420) hide show
  1. package/README.md +8 -4
  2. package/dist/cli/agents-ink.d.ts.map +1 -1
  3. package/dist/cli/agents-ink.js +5 -3
  4. package/dist/cli/agents-ink.js.map +1 -1
  5. package/dist/cli/agents.d.ts.map +1 -1
  6. package/dist/cli/agents.js +27 -9
  7. package/dist/cli/agents.js.map +1 -1
  8. package/dist/cli/doctor.d.ts +4 -4
  9. package/dist/cli/main.js +0 -0
  10. package/dist/cli/omb.js +0 -0
  11. package/dist/core/recovery.d.ts.map +1 -1
  12. package/dist/core/recovery.js +10 -5
  13. package/dist/core/recovery.js.map +1 -1
  14. package/dist/core/transitions.d.ts +4 -0
  15. package/dist/core/transitions.d.ts.map +1 -1
  16. package/dist/core/transitions.js +12 -2
  17. package/dist/core/transitions.js.map +1 -1
  18. package/dist/core/types.d.ts +46 -0
  19. package/dist/core/types.d.ts.map +1 -1
  20. package/dist/extension.d.ts +4 -0
  21. package/dist/extension.d.ts.map +1 -1
  22. package/dist/extension.js +308 -23
  23. package/dist/extension.js.map +1 -1
  24. package/dist/omp/compatibility.d.ts +5 -5
  25. package/dist/omp/compatibility.d.ts.map +1 -1
  26. package/dist/omp/compatibility.js +2 -2
  27. package/dist/omp/compatibility.js.map +1 -1
  28. package/dist/omp/daemon-service.d.ts.map +1 -1
  29. package/dist/omp/daemon-service.js +54 -21
  30. package/dist/omp/daemon-service.js.map +1 -1
  31. package/dist/omp/daemon.d.ts.map +1 -1
  32. package/dist/omp/daemon.js +109 -21
  33. package/dist/omp/daemon.js.map +1 -1
  34. package/dist/omp/dashboard-html.js +5 -5
  35. package/dist/omp/dispatch-admission.js +1 -1
  36. package/dist/omp/dispatch-admission.js.map +1 -1
  37. package/dist/omp/model-role-assignment.d.ts +4 -0
  38. package/dist/omp/model-role-assignment.d.ts.map +1 -1
  39. package/dist/omp/model-role-assignment.js +52 -7
  40. package/dist/omp/model-role-assignment.js.map +1 -1
  41. package/dist/omp/omb-sessions.d.ts +65 -7
  42. package/dist/omp/omb-sessions.d.ts.map +1 -1
  43. package/dist/omp/omb-sessions.js +329 -34
  44. package/dist/omp/omb-sessions.js.map +1 -1
  45. package/dist/omp/omb-settings.d.ts +15 -1
  46. package/dist/omp/omb-settings.d.ts.map +1 -1
  47. package/dist/omp/omb-settings.js +107 -31
  48. package/dist/omp/omb-settings.js.map +1 -1
  49. package/dist/omp/rpc.d.ts +8 -0
  50. package/dist/omp/rpc.d.ts.map +1 -1
  51. package/dist/omp/session-activity.d.ts +5 -0
  52. package/dist/omp/session-activity.d.ts.map +1 -1
  53. package/dist/omp/session-activity.js +17 -0
  54. package/dist/omp/session-activity.js.map +1 -1
  55. package/dist/omp/tmux.d.ts +3 -1
  56. package/dist/omp/tmux.d.ts.map +1 -1
  57. package/dist/omp/tmux.js +195 -31
  58. package/dist/omp/tmux.js.map +1 -1
  59. package/dist/services/candidate-verify.d.ts.map +1 -1
  60. package/dist/services/candidate-verify.js +44 -1
  61. package/dist/services/candidate-verify.js.map +1 -1
  62. package/dist/services/inspector.d.ts +5 -1
  63. package/dist/services/inspector.d.ts.map +1 -1
  64. package/dist/services/inspector.js +11 -2
  65. package/dist/services/inspector.js.map +1 -1
  66. package/dist/services/native-review-ingest.d.ts +35 -0
  67. package/dist/services/native-review-ingest.d.ts.map +1 -0
  68. package/dist/services/native-review-ingest.js +14 -0
  69. package/dist/services/native-review-ingest.js.map +1 -0
  70. package/dist/storage/journal-recovery.js +1 -1
  71. package/dist/storage/journal-recovery.js.map +1 -1
  72. package/dist/storage/resources.js +1 -1
  73. package/dist/storage/resources.js.map +1 -1
  74. package/dist/tools/integrate.d.ts.map +1 -1
  75. package/dist/tools/integrate.js +13 -0
  76. package/dist/tools/integrate.js.map +1 -1
  77. package/dist/tools/workflow.d.ts +9 -0
  78. package/dist/tools/workflow.d.ts.map +1 -1
  79. package/dist/tools/workflow.js +25 -2
  80. package/dist/tools/workflow.js.map +1 -1
  81. package/docs/compatibility/baseline.json +8 -7
  82. package/docs/compatibility/supported-surfaces.json +2 -1
  83. package/docs/development/ci-release-implementation-guide.md +1261 -0
  84. package/docs/development/contributing-and-releasing.md +117 -0
  85. package/docs/development/omp-compatibility-update-guide.md +117 -0
  86. package/docs/releases/0.7.1.md +15 -0
  87. package/docs/releases/0.7.2.md +32 -0
  88. package/docs/releases/native-stable.md +11 -1
  89. package/docs/releases/npm-publishing.md +31 -4
  90. package/docs/releases/support-matrix.md +1 -1
  91. package/package.json +2 -1
  92. package/rules/oflow-gitlab.md +6 -0
  93. package/skills/oflow-gitlab-context/SKILL.md +49 -0
  94. package/skills/omp-native-development/SKILL.md +1 -1
  95. package/skills/omp-native-development/references/accuracy-and-versioning.md +1 -1
  96. package/skills/omp-native-development/references/source-manifest.json +3 -3
  97. package/dist/src/cli/agents-ink.d.ts +0 -25
  98. package/dist/src/cli/agents-ink.js +0 -517
  99. package/dist/src/cli/agents-ink.js.map +0 -1
  100. package/dist/src/cli/agents.d.ts +0 -14
  101. package/dist/src/cli/agents.js +0 -197
  102. package/dist/src/cli/agents.js.map +0 -1
  103. package/dist/src/cli/directory-selector.d.ts +0 -60
  104. package/dist/src/cli/directory-selector.js +0 -208
  105. package/dist/src/cli/directory-selector.js.map +0 -1
  106. package/dist/src/cli/doctor.d.ts +0 -41
  107. package/dist/src/cli/doctor.js +0 -31
  108. package/dist/src/cli/doctor.js.map +0 -1
  109. package/dist/src/cli/install.d.ts +0 -129
  110. package/dist/src/cli/install.js +0 -164
  111. package/dist/src/cli/install.js.map +0 -1
  112. package/dist/src/cli/main.d.ts +0 -2
  113. package/dist/src/cli/main.js +0 -117
  114. package/dist/src/cli/main.js.map +0 -1
  115. package/dist/src/cli/migrate.d.ts +0 -18
  116. package/dist/src/cli/migrate.js +0 -14
  117. package/dist/src/cli/migrate.js.map +0 -1
  118. package/dist/src/cli/omb-commands.d.ts +0 -29
  119. package/dist/src/cli/omb-commands.js +0 -107
  120. package/dist/src/cli/omb-commands.js.map +0 -1
  121. package/dist/src/cli/omb-daemon.d.ts +0 -2
  122. package/dist/src/cli/omb-daemon.js +0 -135
  123. package/dist/src/cli/omb-daemon.js.map +0 -1
  124. package/dist/src/cli/omb-dashboard.d.ts +0 -12
  125. package/dist/src/cli/omb-dashboard.js +0 -113
  126. package/dist/src/cli/omb-dashboard.js.map +0 -1
  127. package/dist/src/cli/omb-invocation.d.ts +0 -8
  128. package/dist/src/cli/omb-invocation.js +0 -41
  129. package/dist/src/cli/omb-invocation.js.map +0 -1
  130. package/dist/src/cli/omb-runtime.d.ts +0 -41
  131. package/dist/src/cli/omb-runtime.js +0 -371
  132. package/dist/src/cli/omb-runtime.js.map +0 -1
  133. package/dist/src/cli/omb-tray.d.ts +0 -2
  134. package/dist/src/cli/omb-tray.js +0 -38
  135. package/dist/src/cli/omb-tray.js.map +0 -1
  136. package/dist/src/cli/omb.d.ts +0 -2
  137. package/dist/src/cli/omb.js +0 -31
  138. package/dist/src/cli/omb.js.map +0 -1
  139. package/dist/src/cli/omp-theme.d.ts +0 -17
  140. package/dist/src/cli/omp-theme.js +0 -22
  141. package/dist/src/cli/omp-theme.js.map +0 -1
  142. package/dist/src/cli/process.d.ts +0 -6
  143. package/dist/src/cli/process.js +0 -54
  144. package/dist/src/cli/process.js.map +0 -1
  145. package/dist/src/cli/run.d.ts +0 -2
  146. package/dist/src/cli/run.js +0 -5
  147. package/dist/src/cli/run.js.map +0 -1
  148. package/dist/src/cli/setup-ui.d.ts +0 -37
  149. package/dist/src/cli/setup-ui.js +0 -90
  150. package/dist/src/cli/setup-ui.js.map +0 -1
  151. package/dist/src/core/acceptance.d.ts +0 -32
  152. package/dist/src/core/acceptance.js +0 -87
  153. package/dist/src/core/acceptance.js.map +0 -1
  154. package/dist/src/core/errors.d.ts +0 -20
  155. package/dist/src/core/errors.js +0 -30
  156. package/dist/src/core/errors.js.map +0 -1
  157. package/dist/src/core/evidence.d.ts +0 -10
  158. package/dist/src/core/evidence.js +0 -35
  159. package/dist/src/core/evidence.js.map +0 -1
  160. package/dist/src/core/policies.d.ts +0 -10
  161. package/dist/src/core/policies.js +0 -60
  162. package/dist/src/core/policies.js.map +0 -1
  163. package/dist/src/core/recovery.d.ts +0 -6
  164. package/dist/src/core/recovery.js +0 -56
  165. package/dist/src/core/recovery.js.map +0 -1
  166. package/dist/src/core/transitions.d.ts +0 -13
  167. package/dist/src/core/transitions.js +0 -59
  168. package/dist/src/core/transitions.js.map +0 -1
  169. package/dist/src/core/types.d.ts +0 -256
  170. package/dist/src/core/types.js +0 -2
  171. package/dist/src/core/types.js.map +0 -1
  172. package/dist/src/extension.d.ts +0 -60
  173. package/dist/src/extension.js +0 -538
  174. package/dist/src/extension.js.map +0 -1
  175. package/dist/src/index.d.ts +0 -29
  176. package/dist/src/index.js +0 -30
  177. package/dist/src/index.js.map +0 -1
  178. package/dist/src/omp/autonomous-settings.d.ts +0 -14
  179. package/dist/src/omp/autonomous-settings.js +0 -65
  180. package/dist/src/omp/autonomous-settings.js.map +0 -1
  181. package/dist/src/omp/capabilities.d.ts +0 -23
  182. package/dist/src/omp/capabilities.js +0 -6
  183. package/dist/src/omp/capabilities.js.map +0 -1
  184. package/dist/src/omp/compatibility.d.ts +0 -30
  185. package/dist/src/omp/compatibility.js +0 -34
  186. package/dist/src/omp/compatibility.js.map +0 -1
  187. package/dist/src/omp/completion.d.ts +0 -7
  188. package/dist/src/omp/completion.js +0 -10
  189. package/dist/src/omp/completion.js.map +0 -1
  190. package/dist/src/omp/config.d.ts +0 -10
  191. package/dist/src/omp/config.js +0 -14
  192. package/dist/src/omp/config.js.map +0 -1
  193. package/dist/src/omp/context.d.ts +0 -15
  194. package/dist/src/omp/context.js +0 -3
  195. package/dist/src/omp/context.js.map +0 -1
  196. package/dist/src/omp/daemon-service.d.ts +0 -25
  197. package/dist/src/omp/daemon-service.js +0 -483
  198. package/dist/src/omp/daemon-service.js.map +0 -1
  199. package/dist/src/omp/daemon.d.ts +0 -48
  200. package/dist/src/omp/daemon.js +0 -194
  201. package/dist/src/omp/daemon.js.map +0 -1
  202. package/dist/src/omp/dashboard-html.d.ts +0 -3
  203. package/dist/src/omp/dashboard-html.js +0 -419
  204. package/dist/src/omp/dashboard-html.js.map +0 -1
  205. package/dist/src/omp/dispatch-admission.d.ts +0 -2
  206. package/dist/src/omp/dispatch-admission.js +0 -12
  207. package/dist/src/omp/dispatch-admission.js.map +0 -1
  208. package/dist/src/omp/integration-recovery.d.ts +0 -10
  209. package/dist/src/omp/integration-recovery.js +0 -18
  210. package/dist/src/omp/integration-recovery.js.map +0 -1
  211. package/dist/src/omp/isolation-policy.d.ts +0 -14
  212. package/dist/src/omp/isolation-policy.js +0 -9
  213. package/dist/src/omp/isolation-policy.js.map +0 -1
  214. package/dist/src/omp/lifecycle.d.ts +0 -14
  215. package/dist/src/omp/lifecycle.js +0 -14
  216. package/dist/src/omp/lifecycle.js.map +0 -1
  217. package/dist/src/omp/memory.d.ts +0 -16
  218. package/dist/src/omp/memory.js +0 -4
  219. package/dist/src/omp/memory.js.map +0 -1
  220. package/dist/src/omp/model-role-assignment.d.ts +0 -296
  221. package/dist/src/omp/model-role-assignment.js +0 -559
  222. package/dist/src/omp/model-role-assignment.js.map +0 -1
  223. package/dist/src/omp/model-roles.d.ts +0 -19
  224. package/dist/src/omp/model-roles.js +0 -6
  225. package/dist/src/omp/model-roles.js.map +0 -1
  226. package/dist/src/omp/omb-sessions.d.ts +0 -122
  227. package/dist/src/omp/omb-sessions.js +0 -512
  228. package/dist/src/omp/omb-sessions.js.map +0 -1
  229. package/dist/src/omp/omb-settings.d.ts +0 -35
  230. package/dist/src/omp/omb-settings.js +0 -104
  231. package/dist/src/omp/omb-settings.js.map +0 -1
  232. package/dist/src/omp/result-reconciliation.d.ts +0 -2
  233. package/dist/src/omp/result-reconciliation.js +0 -9
  234. package/dist/src/omp/result-reconciliation.js.map +0 -1
  235. package/dist/src/omp/rpc.d.ts +0 -67
  236. package/dist/src/omp/rpc.js +0 -4
  237. package/dist/src/omp/rpc.js.map +0 -1
  238. package/dist/src/omp/run-log.d.ts +0 -25
  239. package/dist/src/omp/run-log.js +0 -24
  240. package/dist/src/omp/run-log.js.map +0 -1
  241. package/dist/src/omp/session-activity.d.ts +0 -70
  242. package/dist/src/omp/session-activity.js +0 -361
  243. package/dist/src/omp/session-activity.js.map +0 -1
  244. package/dist/src/omp/session-controls.d.ts +0 -17
  245. package/dist/src/omp/session-controls.js +0 -14
  246. package/dist/src/omp/session-controls.js.map +0 -1
  247. package/dist/src/omp/tmux.d.ts +0 -89
  248. package/dist/src/omp/tmux.js +0 -445
  249. package/dist/src/omp/tmux.js.map +0 -1
  250. package/dist/src/omp/tray-icons.d.ts +0 -5
  251. package/dist/src/omp/tray-icons.js +0 -78
  252. package/dist/src/omp/tray-icons.js.map +0 -1
  253. package/dist/src/omp/tray.d.ts +0 -23
  254. package/dist/src/omp/tray.js +0 -167
  255. package/dist/src/omp/tray.js.map +0 -1
  256. package/dist/src/services/budget.d.ts +0 -19
  257. package/dist/src/services/budget.js +0 -10
  258. package/dist/src/services/budget.js.map +0 -1
  259. package/dist/src/services/candidate-local.d.ts +0 -13
  260. package/dist/src/services/candidate-local.js +0 -15
  261. package/dist/src/services/candidate-local.js.map +0 -1
  262. package/dist/src/services/candidates.d.ts +0 -20
  263. package/dist/src/services/candidates.js +0 -100
  264. package/dist/src/services/candidates.js.map +0 -1
  265. package/dist/src/services/evidence-bundle.d.ts +0 -17
  266. package/dist/src/services/evidence-bundle.js +0 -21
  267. package/dist/src/services/evidence-bundle.js.map +0 -1
  268. package/dist/src/services/inspector.d.ts +0 -11
  269. package/dist/src/services/inspector.js +0 -6
  270. package/dist/src/services/inspector.js.map +0 -1
  271. package/dist/src/services/lessons.d.ts +0 -13
  272. package/dist/src/services/lessons.js +0 -11
  273. package/dist/src/services/lessons.js.map +0 -1
  274. package/dist/src/services/projection.d.ts +0 -21
  275. package/dist/src/services/projection.js +0 -10
  276. package/dist/src/services/projection.js.map +0 -1
  277. package/dist/src/services/readiness.d.ts +0 -4
  278. package/dist/src/services/readiness.js +0 -35
  279. package/dist/src/services/readiness.js.map +0 -1
  280. package/dist/src/services/recipes.d.ts +0 -15
  281. package/dist/src/services/recipes.js +0 -42
  282. package/dist/src/services/recipes.js.map +0 -1
  283. package/dist/src/services/recovery.d.ts +0 -19
  284. package/dist/src/services/recovery.js +0 -9
  285. package/dist/src/services/recovery.js.map +0 -1
  286. package/dist/src/services/review.d.ts +0 -15
  287. package/dist/src/services/review.js +0 -9
  288. package/dist/src/services/review.js.map +0 -1
  289. package/dist/src/storage/journal-recovery.d.ts +0 -10
  290. package/dist/src/storage/journal-recovery.js +0 -33
  291. package/dist/src/storage/journal-recovery.js.map +0 -1
  292. package/dist/src/storage/journal.d.ts +0 -12
  293. package/dist/src/storage/journal.js +0 -82
  294. package/dist/src/storage/journal.js.map +0 -1
  295. package/dist/src/storage/migrations.d.ts +0 -22
  296. package/dist/src/storage/migrations.js +0 -107
  297. package/dist/src/storage/migrations.js.map +0 -1
  298. package/dist/src/storage/repository-identity.d.ts +0 -11
  299. package/dist/src/storage/repository-identity.js +0 -67
  300. package/dist/src/storage/repository-identity.js.map +0 -1
  301. package/dist/src/storage/resources.d.ts +0 -66
  302. package/dist/src/storage/resources.js +0 -148
  303. package/dist/src/storage/resources.js.map +0 -1
  304. package/dist/src/tools/evidence.d.ts +0 -8
  305. package/dist/src/tools/evidence.js +0 -9
  306. package/dist/src/tools/evidence.js.map +0 -1
  307. package/dist/src/tools/integrate.d.ts +0 -13
  308. package/dist/src/tools/integrate.js +0 -90
  309. package/dist/src/tools/integrate.js.map +0 -1
  310. package/dist/src/tools/result.d.ts +0 -9
  311. package/dist/src/tools/result.js +0 -2
  312. package/dist/src/tools/result.js.map +0 -1
  313. package/dist/src/tools/verify.d.ts +0 -13
  314. package/dist/src/tools/verify.js +0 -61
  315. package/dist/src/tools/verify.js.map +0 -1
  316. package/dist/src/tools/workflow.d.ts +0 -8
  317. package/dist/src/tools/workflow.js +0 -65
  318. package/dist/src/tools/workflow.js.map +0 -1
  319. package/dist/src/workflows/direct.d.ts +0 -9
  320. package/dist/src/workflows/direct.js +0 -2
  321. package/dist/src/workflows/direct.js.map +0 -1
  322. package/dist/src/workflows/implement.d.ts +0 -2
  323. package/dist/src/workflows/implement.js +0 -4
  324. package/dist/src/workflows/implement.js.map +0 -1
  325. package/dist/src/workflows/plan.d.ts +0 -17
  326. package/dist/src/workflows/plan.js +0 -6
  327. package/dist/src/workflows/plan.js.map +0 -1
  328. package/dist/src/workflows/research.d.ts +0 -15
  329. package/dist/src/workflows/research.js +0 -2
  330. package/dist/src/workflows/research.js.map +0 -1
  331. package/dist/src/workflows/review.d.ts +0 -15
  332. package/dist/src/workflows/review.js +0 -2
  333. package/dist/src/workflows/review.js.map +0 -1
  334. package/dist/src/workflows/verify.d.ts +0 -9
  335. package/dist/src/workflows/verify.js +0 -2
  336. package/dist/src/workflows/verify.js.map +0 -1
  337. package/dist/tests/acceptance.test.d.ts +0 -1
  338. package/dist/tests/acceptance.test.js +0 -27
  339. package/dist/tests/acceptance.test.js.map +0 -1
  340. package/dist/tests/agents.test.d.ts +0 -1
  341. package/dist/tests/agents.test.js +0 -369
  342. package/dist/tests/agents.test.js.map +0 -1
  343. package/dist/tests/candidates.test.d.ts +0 -1
  344. package/dist/tests/candidates.test.js +0 -60
  345. package/dist/tests/candidates.test.js.map +0 -1
  346. package/dist/tests/core.test.d.ts +0 -1
  347. package/dist/tests/core.test.js +0 -39
  348. package/dist/tests/core.test.js.map +0 -1
  349. package/dist/tests/daemon.test.d.ts +0 -1
  350. package/dist/tests/daemon.test.js +0 -157
  351. package/dist/tests/daemon.test.js.map +0 -1
  352. package/dist/tests/dashboard.test.d.ts +0 -1
  353. package/dist/tests/dashboard.test.js +0 -414
  354. package/dist/tests/dashboard.test.js.map +0 -1
  355. package/dist/tests/directory-selector.test.d.ts +0 -1
  356. package/dist/tests/directory-selector.test.js +0 -93
  357. package/dist/tests/directory-selector.test.js.map +0 -1
  358. package/dist/tests/doctor.test.d.ts +0 -1
  359. package/dist/tests/doctor.test.js +0 -32
  360. package/dist/tests/doctor.test.js.map +0 -1
  361. package/dist/tests/install.test.d.ts +0 -1
  362. package/dist/tests/install.test.js +0 -101
  363. package/dist/tests/install.test.js.map +0 -1
  364. package/dist/tests/integration.test.d.ts +0 -1
  365. package/dist/tests/integration.test.js +0 -49
  366. package/dist/tests/integration.test.js.map +0 -1
  367. package/dist/tests/journal.test.d.ts +0 -1
  368. package/dist/tests/journal.test.js +0 -50
  369. package/dist/tests/journal.test.js.map +0 -1
  370. package/dist/tests/model-role-assignment.test.d.ts +0 -1
  371. package/dist/tests/model-role-assignment.test.js +0 -294
  372. package/dist/tests/model-role-assignment.test.js.map +0 -1
  373. package/dist/tests/omb-runtime.test.d.ts +0 -1
  374. package/dist/tests/omb-runtime.test.js +0 -554
  375. package/dist/tests/omb-runtime.test.js.map +0 -1
  376. package/dist/tests/omb-session-actions.test.d.ts +0 -1
  377. package/dist/tests/omb-session-actions.test.js +0 -191
  378. package/dist/tests/omb-session-actions.test.js.map +0 -1
  379. package/dist/tests/omb-settings.test.d.ts +0 -1
  380. package/dist/tests/omb-settings.test.js +0 -82
  381. package/dist/tests/omb-settings.test.js.map +0 -1
  382. package/dist/tests/omp-contract.test.d.ts +0 -1
  383. package/dist/tests/omp-contract.test.js +0 -362
  384. package/dist/tests/omp-contract.test.js.map +0 -1
  385. package/dist/tests/process.test.d.ts +0 -1
  386. package/dist/tests/process.test.js +0 -12
  387. package/dist/tests/process.test.js.map +0 -1
  388. package/dist/tests/psmux-windows.test.d.ts +0 -1
  389. package/dist/tests/psmux-windows.test.js +0 -105
  390. package/dist/tests/psmux-windows.test.js.map +0 -1
  391. package/dist/tests/recovery.test.d.ts +0 -1
  392. package/dist/tests/recovery.test.js +0 -9
  393. package/dist/tests/recovery.test.js.map +0 -1
  394. package/dist/tests/resources.test.d.ts +0 -1
  395. package/dist/tests/resources.test.js +0 -55
  396. package/dist/tests/resources.test.js.map +0 -1
  397. package/dist/tests/session-activity.test.d.ts +0 -1
  398. package/dist/tests/session-activity.test.js +0 -159
  399. package/dist/tests/session-activity.test.js.map +0 -1
  400. package/dist/tests/setup-ui.test.d.ts +0 -1
  401. package/dist/tests/setup-ui.test.js +0 -37
  402. package/dist/tests/setup-ui.test.js.map +0 -1
  403. package/dist/tests/storage-integrity.test.d.ts +0 -1
  404. package/dist/tests/storage-integrity.test.js +0 -88
  405. package/dist/tests/storage-integrity.test.js.map +0 -1
  406. package/dist/tests/tmux.test.d.ts +0 -1
  407. package/dist/tests/tmux.test.js +0 -239
  408. package/dist/tests/tmux.test.js.map +0 -1
  409. package/dist/tests/tray.test.d.ts +0 -1
  410. package/dist/tests/tray.test.js +0 -37
  411. package/dist/tests/tray.test.js.map +0 -1
  412. package/dist/tests/verification.test.d.ts +0 -1
  413. package/dist/tests/verification.test.js +0 -61
  414. package/dist/tests/verification.test.js.map +0 -1
  415. package/dist/tests/workflow-features.test.d.ts +0 -1
  416. package/dist/tests/workflow-features.test.js +0 -82
  417. package/dist/tests/workflow-features.test.js.map +0 -1
  418. package/dist/tests/workflow-safety.test.d.ts +0 -1
  419. package/dist/tests/workflow-safety.test.js +0 -57
  420. package/dist/tests/workflow-safety.test.js.map +0 -1
@@ -1,122 +0,0 @@
1
- import { type OmbSessionActivity } from "./session-activity.js";
2
- export declare const BIZAR_SESSION_PREFIX = "bizar-";
3
- /**
4
- * Connection and activity state of one Bizar-owned session.
5
- *
6
- * `working` and `waiting` describe what the agent is doing, `connected` and
7
- * `disconnected` describe whether an interactive client is attached to an idle
8
- * session, and `stopped` means no host is observed and the journal is silent.
9
- */
10
- export type OmbSessionState = "working" | "waiting" | "connected" | "disconnected" | "stopped";
11
- export interface OmbSessionInfo {
12
- name: string;
13
- cwd: string;
14
- project: string;
15
- id: string;
16
- /**
17
- * Human label for this row: the native OMP title when the session has one,
18
- * otherwise a readable derivation (first prompt, generated session label, or
19
- * project-scoped fallback). Every row carries it, so no renderer has to
20
- * invent a name from `id`.
21
- */
22
- displayName?: string;
23
- state: OmbSessionState;
24
- /** Privacy-safe live activity, when the session journal exposes it. */
25
- activity?: OmbSessionActivity;
26
- /**
27
- * True when tmux currently hosts this session.
28
- *
29
- * A live OMP process whose host `omb` never created, or whose host died
30
- * while the agent kept working, has no attachable tmux session. Absent for
31
- * synthetic records, which are treated as hosted.
32
- */
33
- hosted?: boolean;
34
- command: string;
35
- pid: string;
36
- /** Native OMP session id, when its journal is available. */
37
- nativeId?: string;
38
- /** Native OMP session title, when configured or auto-generated. */
39
- nativeName?: string;
40
- /** First user prompt, used as a stable local fallback before auto-titling. */
41
- firstMessage?: string;
42
- /** True when this host has a Bizar-owned isolated native session directory. */
43
- nativeSessionAvailable?: boolean;
44
- /**
45
- * True when tmux has a client attached to this session right now.
46
- *
47
- * Distinct from `state`: an attached session that is still working reports
48
- * `working`, so only this field answers "would stopping it disconnect
49
- * somebody?".
50
- */
51
- attached?: boolean;
52
- createdAt?: number;
53
- lastAttachedAt?: number;
54
- }
55
- export interface ListOmbSessionsOptions {
56
- /** Include Bizar sessions whose tmux host exited and whose journal is silent. Defaults to false. */
57
- includeStopped?: boolean;
58
- }
59
- /** Keep native OMP journals separate so each durable `omb` host has one exact session. */
60
- export declare function ombSessionDir(session: string, env?: NodeJS.ProcessEnv): string;
61
- /**
62
- * Whether a name is one of the sessions Bizar owns, and may therefore kill,
63
- * rename, tombstone, or adopt as its own native journal.
64
- */
65
- export declare function isOmbSessionName(session: string): boolean;
66
- /** Keep an intentionally removed session out of journal-based discovery. */
67
- export declare function markOmbSessionDeleted(session: string, env?: NodeJS.ProcessEnv): boolean;
68
- /** Reusing a session name makes its native journal discoverable again. */
69
- export declare function clearOmbSessionDeleted(session: string, env?: NodeJS.ProcessEnv): void;
70
- /** Native OMP title first, then a deterministic prompt/project fallback. */
71
- export declare function ombSessionDisplayName(session: Pick<OmbSessionInfo, "project" | "id" | "nativeName" | "firstMessage" | "nativeSessionAvailable">): string;
72
- /**
73
- * Resolve the tmux-compatible multiplexer binary. `BIZAR_TMUX_BIN` always
74
- * wins. On Windows, psmux is the supported native multiplexer (it ships a
75
- * `tmux` command alias, but resolving `tmux` on PATH could pick unrelated
76
- * binaries), so prefer `psmux` and fall back to the generic `tmux` name;
77
- * elsewhere the standard `tmux` binary is used.
78
- */
79
- export declare function resolveMultiplexerBin(env?: NodeJS.ProcessEnv): string;
80
- /**
81
- * Resolve the hub state from tmux liveness, client attachment, and journal
82
- * activity.
83
- *
84
- * Work wins over attachment: a detached client must never hide an agent that
85
- * is still processing, which is the failure this hub exists to prevent.
86
- * `waiting` refines an attached session that finished its turn, `connected`
87
- * covers an attached session with no structured activity yet, and
88
- * `disconnected` covers a live session with no client and no work in flight.
89
- */
90
- export declare function ombSessionState(input: {
91
- dead: boolean;
92
- attached: boolean;
93
- activity?: OmbSessionActivity;
94
- }): OmbSessionState;
95
- /**
96
- * Session names whose journal the pane of one live tmux session writes.
97
- *
98
- * Deletion uses this before killing the session, because a renamed session's
99
- * journal lives in the directory it was started with rather than the one named
100
- * after the current tmux session.
101
- */
102
- export declare function ombSessionBoundNames(session: string, cwd: string, env?: NodeJS.ProcessEnv): Promise<string[]>;
103
- /**
104
- * Where this process runs from, as far as the multiplexer can tell.
105
- *
106
- * `omb stop` needs `unknown` to exist: when `TMUX` is set but the multiplexer
107
- * cannot answer, the hosting session is unidentified, and a kill verb must
108
- * assume that one of the sessions it is about to stop could be its own.
109
- */
110
- export type OmbHostSession = {
111
- kind: "not-bizar";
112
- } | {
113
- kind: "bizar";
114
- name: string;
115
- } | {
116
- kind: "unknown";
117
- };
118
- export declare function currentOmbHostSession(cwd?: string, env?: NodeJS.ProcessEnv): Promise<OmbHostSession>;
119
- /** Discover Bizar-owned tmux sessions without touching unrelated tmux sessions. */
120
- export declare function listOmbSessions(cwd?: string, env?: NodeJS.ProcessEnv, options?: ListOmbSessionsOptions): Promise<OmbSessionInfo[]>;
121
- /** Return the most recently attached live session for one exact project path. */
122
- export declare function findLastOmbSession(cwd: string, env?: NodeJS.ProcessEnv): Promise<OmbSessionInfo | undefined>;
@@ -1,512 +0,0 @@
1
- import { spawn } from "node:child_process";
2
- import { access, readdir, stat } from "node:fs/promises";
3
- import { mkdirSync, rmSync, writeFileSync } from "node:fs";
4
- import { basename, join, relative, resolve } from "node:path";
5
- import { homedir, tmpdir } from "node:os";
6
- import { deriveSessionActivity, listSessionJournals, readJournalHead, readJournalTail, } from "./session-activity.js";
7
- export const BIZAR_SESSION_PREFIX = "bizar-";
8
- /** Most recent stopped sessions to surface when stopped sessions are enabled. */
9
- const STOPPED_SESSION_LIMIT = 6;
10
- const DELETED_SESSION_MARKER = ".bizar-deleted";
11
- function nativeSessionRoot(env) {
12
- const stateHome = env.XDG_STATE_HOME || join(env.HOME || homedir(), ".local", "state");
13
- return join(stateHome, "bizar-omp", "native-sessions");
14
- }
15
- /** Keep native OMP journals separate so each durable `omb` host has one exact session. */
16
- export function ombSessionDir(session, env = process.env) {
17
- return join(nativeSessionRoot(env), session);
18
- }
19
- /**
20
- * Whether a name is one of the sessions Bizar owns, and may therefore kill,
21
- * rename, tombstone, or adopt as its own native journal.
22
- */
23
- export function isOmbSessionName(session) {
24
- return /^bizar-[A-Za-z0-9_.-]+$/.test(session);
25
- }
26
- function markDirectoryDeleted(directory) {
27
- try {
28
- mkdirSync(directory, { recursive: true, mode: 0o700 });
29
- writeFileSync(join(directory, DELETED_SESSION_MARKER), `${Date.now()}\n`, { mode: 0o600 });
30
- return true;
31
- }
32
- catch {
33
- return false;
34
- }
35
- }
36
- /** Keep an intentionally removed session out of journal-based discovery. */
37
- export function markOmbSessionDeleted(session, env = process.env) {
38
- return isOmbSessionName(session) && markDirectoryDeleted(ombSessionDir(session, env));
39
- }
40
- /** Reusing a session name makes its native journal discoverable again. */
41
- export function clearOmbSessionDeleted(session, env = process.env) {
42
- if (!isOmbSessionName(session))
43
- return;
44
- try {
45
- rmSync(join(ombSessionDir(session, env), DELETED_SESSION_MARKER), { force: true });
46
- }
47
- catch { /* discovery remains conservative */ }
48
- }
49
- async function isOmbSessionDeleted(session, env) {
50
- try {
51
- await access(join(ombSessionDir(session, env), DELETED_SESSION_MARKER));
52
- return true;
53
- }
54
- catch {
55
- return false;
56
- }
57
- }
58
- function ompAgentDir(env) {
59
- if (env.PI_CODING_AGENT_DIR)
60
- return resolve(env.PI_CODING_AGENT_DIR);
61
- return join(env.HOME || homedir(), env.PI_CONFIG_DIR || ".omp", "agent");
62
- }
63
- function defaultOmpSessionDir(cwd, env) {
64
- const resolvedCwd = resolve(cwd);
65
- const home = resolve(env.HOME || homedir());
66
- const temp = resolve(tmpdir());
67
- const encode = (value) => value.replace(/[\\/:]/g, "-");
68
- const homeRelative = relative(home, resolvedCwd);
69
- if (homeRelative === "" || (!homeRelative.startsWith("..") && !homeRelative.startsWith("/"))) {
70
- return join(ompAgentDir(env), "sessions", homeRelative ? `-${encode(homeRelative)}` : "-");
71
- }
72
- const tempRelative = relative(temp, resolvedCwd);
73
- if (tempRelative === "" || (!tempRelative.startsWith("..") && !tempRelative.startsWith("/"))) {
74
- return join(ompAgentDir(env), "sessions", tempRelative ? `-tmp-${encode(tempRelative)}` : "-tmp");
75
- }
76
- return join(ompAgentDir(env), "sessions", `--${encode(resolvedCwd).replace(/^-/, "")}--`);
77
- }
78
- function cleanText(value) {
79
- if (typeof value !== "string")
80
- return undefined;
81
- const cleaned = value
82
- .split(/\r?\n/, 1)[0]
83
- .replace(/[\x00-\x1F\x7F]/g, "")
84
- .replace(/\s+/g, " ")
85
- .trim();
86
- return cleaned || undefined;
87
- }
88
- function asRecord(value) {
89
- return typeof value === "object" && value !== null ? value : undefined;
90
- }
91
- /**
92
- * Parse one journal's session header, title, and first user prompt.
93
- *
94
- * Current journals open with a `title` entry that is rewritten in place, so
95
- * the session header is the first `session` entry rather than the first line.
96
- */
97
- async function readNativeSessionFile(journal) {
98
- const content = await readJournalHead(journal);
99
- if (!content)
100
- return undefined;
101
- let header;
102
- const entries = [];
103
- for (const line of content.split("\n")) {
104
- const trimmed = line.trim();
105
- if (!trimmed || trimmed[0] !== "{")
106
- continue;
107
- let entry;
108
- try {
109
- entry = JSON.parse(trimmed);
110
- }
111
- catch {
112
- // A partially written final line must not hide the entries before it.
113
- continue;
114
- }
115
- if (!header && entry.type === "session") {
116
- header = entry;
117
- continue;
118
- }
119
- entries.push(entry);
120
- }
121
- if (!header)
122
- return undefined;
123
- let latestTitle = cleanText(header.title);
124
- let latestTitleAt = Number.NEGATIVE_INFINITY;
125
- let firstMessage;
126
- for (const entry of entries) {
127
- if (entry.type === "title" || entry.type === "title_change") {
128
- const title = cleanText(entry.title);
129
- const raw = entry.updatedAt ?? entry.timestamp;
130
- const at = typeof raw === "string" ? Date.parse(raw) : NaN;
131
- // OMP rewrites the opening `title` entry in place and appends
132
- // `title_change` history, so the newest timestamp — not file order —
133
- // names the title the session currently has.
134
- if (title && (!Number.isFinite(at) || at >= latestTitleAt)) {
135
- latestTitle = title;
136
- if (Number.isFinite(at))
137
- latestTitleAt = at;
138
- }
139
- }
140
- if (firstMessage || entry.type !== "message")
141
- continue;
142
- const message = asRecord(entry.message);
143
- if (message?.role !== "user")
144
- continue;
145
- if (typeof message.content === "string")
146
- firstMessage = cleanText(message.content);
147
- else if (Array.isArray(message.content)) {
148
- firstMessage = cleanText(message.content
149
- .filter(item => asRecord(item)?.type === "text")
150
- .map(item => asRecord(item)?.text)
151
- .filter((item) => typeof item === "string")
152
- .join(" "));
153
- }
154
- }
155
- const timestamp = typeof header.timestamp === "string" ? Date.parse(header.timestamp) : NaN;
156
- return {
157
- id: cleanText(header.id),
158
- title: latestTitle,
159
- cwd: cleanText(header.cwd),
160
- firstMessage,
161
- createdAt: Number.isFinite(timestamp) ? Math.floor(timestamp / 1000) : undefined,
162
- };
163
- }
164
- /** Metadata plus live activity for a Bizar-owned native session directory. */
165
- async function readNativeSessionSnapshot(sessionDir, now) {
166
- const journals = await listSessionJournals(sessionDir);
167
- const newest = journals.at(-1);
168
- if (!newest)
169
- return {};
170
- const [entries, modifiedAt, ...candidates] = await Promise.all([
171
- readJournalTail(newest),
172
- stat(newest).then(file => file.mtimeMs).catch(() => undefined),
173
- ...journals.slice(-3).reverse().map(journal => readNativeSessionFile(journal)),
174
- ]);
175
- let metadata;
176
- for (const candidate of candidates) {
177
- if (candidate) {
178
- metadata = candidate;
179
- break;
180
- }
181
- }
182
- return {
183
- metadata,
184
- activity: entries.length > 0 ? deriveSessionActivity(entries, { now, fallbackUpdatedAt: modifiedAt }) : undefined,
185
- };
186
- }
187
- async function readLegacyNativeSessionMetadata(cwd, sessionCreatedAt, env) {
188
- const sessionDir = defaultOmpSessionDir(cwd, env);
189
- const journals = await listSessionJournals(sessionDir);
190
- if (journals.length === 0)
191
- return undefined;
192
- const candidates = (await Promise.all(journals.map(async (journal) => {
193
- const metadata = await readNativeSessionFile(journal);
194
- return metadata ? { journal, metadata } : undefined;
195
- }))).filter((candidate) => Boolean(candidate));
196
- if (candidates.length === 0)
197
- return undefined;
198
- if (candidates.length === 1 || sessionCreatedAt === undefined)
199
- return candidates[0]?.metadata;
200
- candidates.sort((a, b) => Math.abs((a.metadata.createdAt ?? 0) - sessionCreatedAt) - Math.abs((b.metadata.createdAt ?? 0) - sessionCreatedAt));
201
- return candidates[0]?.metadata;
202
- }
203
- function compactPrompt(prompt) {
204
- const words = prompt.replace(/^[-*#>]+\s*/, "").split(/\s+/).filter(Boolean);
205
- const compact = words.slice(0, 7).join(" ").replace(/[.!?]+$/, "");
206
- return compact.length > 48 ? `${compact.slice(0, 47).trimEnd()}…` : compact;
207
- }
208
- function generatedSessionLabel(project, id) {
209
- const match = id.match(/^s-(.+)-([a-z0-9]{4,})$/);
210
- if (!match)
211
- return undefined;
212
- const stem = match[1];
213
- const normalizedProject = project.toLocaleLowerCase().replace(/[^a-z0-9]+/g, "-");
214
- if (stem === "session" || stem === normalizedProject || /^[a-z0-9]{7,}$/.test(stem))
215
- return `New ${project} session`;
216
- return `${project} · ${stem.replace(/-/g, " ")}`;
217
- }
218
- /** Session ids that carry no readable meaning on their own. */
219
- const OPAQUE_SESSION_ID = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}|[0-9a-f]{16,})$/i;
220
- /** Native OMP title first, then a deterministic prompt/project fallback. */
221
- export function ombSessionDisplayName(session) {
222
- if (session.nativeName)
223
- return session.nativeName;
224
- if (session.firstMessage)
225
- return compactPrompt(session.firstMessage);
226
- const generatedLabel = generatedSessionLabel(session.project, session.id);
227
- if (generatedLabel)
228
- return generatedLabel;
229
- if (session.nativeSessionAvailable)
230
- return `New ${session.project} session`;
231
- // A raw UUID (or another opaque token) is never a readable session name.
232
- if (OPAQUE_SESSION_ID.test(session.id))
233
- return `New ${session.project} session`;
234
- return `${session.project}/${session.id || "main"}`;
235
- }
236
- /**
237
- * Resolve the tmux-compatible multiplexer binary. `BIZAR_TMUX_BIN` always
238
- * wins. On Windows, psmux is the supported native multiplexer (it ships a
239
- * `tmux` command alias, but resolving `tmux` on PATH could pick unrelated
240
- * binaries), so prefer `psmux` and fall back to the generic `tmux` name;
241
- * elsewhere the standard `tmux` binary is used.
242
- */
243
- export function resolveMultiplexerBin(env = process.env) {
244
- if (env.BIZAR_TMUX_BIN)
245
- return env.BIZAR_TMUX_BIN;
246
- return process.platform === "win32" ? "psmux" : "tmux";
247
- }
248
- /**
249
- * Resolve the hub state from tmux liveness, client attachment, and journal
250
- * activity.
251
- *
252
- * Work wins over attachment: a detached client must never hide an agent that
253
- * is still processing, which is the failure this hub exists to prevent.
254
- * `waiting` refines an attached session that finished its turn, `connected`
255
- * covers an attached session with no structured activity yet, and
256
- * `disconnected` covers a live session with no client and no work in flight.
257
- */
258
- export function ombSessionState(input) {
259
- if (input.dead)
260
- return "stopped";
261
- const activity = input.activity;
262
- if (activity && activity.phase !== "unknown" && !activity.awaitingInput)
263
- return "working";
264
- if (!input.attached)
265
- return "disconnected";
266
- return activity?.awaitingInput ? "waiting" : "connected";
267
- }
268
- const STATE_RANK = {
269
- working: 0,
270
- waiting: 1,
271
- connected: 2,
272
- disconnected: 3,
273
- stopped: 4,
274
- };
275
- function exitCode(code, signal) {
276
- if (code !== null)
277
- return code;
278
- return signal ? 1 : 1;
279
- }
280
- function readTmux(command, args, cwd, env) {
281
- const child = spawn(command, args, { cwd, env, stdio: ["ignore", "pipe", "ignore"] });
282
- let output = "";
283
- child.stdout?.setEncoding("utf8");
284
- child.stdout?.on("data", chunk => { output += chunk; });
285
- return new Promise((resolve, reject) => {
286
- // A missing multiplexer binary means "no sessions", not a crash:
287
- // discovery callers treat any nonzero code as an empty listing. Any
288
- // other spawn failure (EACCES, EPERM, ...) is still a hard error.
289
- child.once("error", (error) => {
290
- if (error.code === "ENOENT" || error.code === "EINVAL")
291
- resolve({ code: 127, output: "" });
292
- else
293
- reject(error);
294
- });
295
- child.once("close", (code, signal) => resolve({ code: exitCode(code, signal), output }));
296
- });
297
- }
298
- function sessionId(name) {
299
- const match = name.match(/-[a-f0-9]{10}(?:-(.*))?$/);
300
- return match?.[1] || "main";
301
- }
302
- /** Project slug encoded in the Bizar session name, without the digest. */
303
- function sessionProject(name) {
304
- const trimmed = name.slice(BIZAR_SESSION_PREFIX.length);
305
- return trimmed.replace(/-[a-f0-9]{10}(?:-.*)?$/, "") || trimmed || "session";
306
- }
307
- /**
308
- * One pane's fields, including the command tmux started it with. Bizar launches
309
- * every host as `omp --session-dir <native root>/<session>`, so that command is
310
- * the only exact record of which journal a live row owns.
311
- */
312
- const PANE_FORMAT = "#{pane_dead}\t#{pane_current_path}\t#{pane_current_command}\t#{pane_pid}\t#{pane_start_command}";
313
- /**
314
- * Session whose native directory a pane command declares.
315
- *
316
- * A renamed tmux session keeps the directory its host was started with, so
317
- * discovery reads the binding from the pane instead of assuming the directory
318
- * matches the session name. Paths outside the Bizar native root, or names
319
- * Bizar does not own, are ignored so unrelated OMP hosts are never adopted.
320
- */
321
- function paneBoundSession(startCommand, env) {
322
- const declared = startCommand?.match(/--session-dir(?:=|\s+)(?:"([^"]*)"|'([^']*)'|(\S+))/);
323
- const value = declared?.[1] ?? declared?.[2] ?? declared?.[3];
324
- if (!value)
325
- return undefined;
326
- const directory = relative(resolve(nativeSessionRoot(env)), resolve(value));
327
- if (!directory || directory.startsWith("..") || directory.includes("/") || !isOmbSessionName(directory))
328
- return undefined;
329
- return directory;
330
- }
331
- function parsePane(output, env) {
332
- const [line = ""] = output.trim().split("\n");
333
- const [dead, cwd, command, pid, startCommand] = line.split("\t");
334
- return {
335
- dead: dead === "1",
336
- cwd: cwd || "?",
337
- command: command || "?",
338
- pid: pid || "?",
339
- bound: paneBoundSession(startCommand, env),
340
- };
341
- }
342
- function parseSessionList(output) {
343
- return output
344
- .split("\n")
345
- .map(line => line.trim())
346
- .filter(Boolean)
347
- .map(line => line.split("\t"))
348
- .filter(parts => parts[0]?.startsWith(BIZAR_SESSION_PREFIX))
349
- .map(parts => ({
350
- name: parts[0],
351
- createdAt: Number.isFinite(Number(parts[1])) ? Number(parts[1]) : undefined,
352
- lastAttachedAt: Number.isFinite(Number(parts[2])) ? Number(parts[2]) : undefined,
353
- attached: parts[3] !== "0",
354
- }));
355
- }
356
- function sessionRecord(name, fields) {
357
- const record = {
358
- name,
359
- project: fields.cwd === "?" ? sessionProject(name) : basename(fields.cwd),
360
- id: sessionId(name),
361
- ...fields,
362
- };
363
- return { ...record, displayName: ombSessionDisplayName(record) };
364
- }
365
- async function describeLiveSession(tmux, session, cwd, childEnv, env, now) {
366
- const pane = await readTmux(tmux, ["list-panes", "-t", session.name, "-F", PANE_FORMAT], cwd, childEnv);
367
- const details = parsePane(pane.output, env);
368
- // Prefer the journal the pane command names: after a rename the tmux session
369
- // and its native directory differ, and the host keeps writing the directory
370
- // it was started with.
371
- const declared = details.bound && details.bound !== session.name
372
- ? await readNativeSessionSnapshot(ombSessionDir(details.bound, env), now)
373
- : undefined;
374
- const snapshot = declared?.metadata ? declared : await readNativeSessionSnapshot(ombSessionDir(session.name, env), now);
375
- const native = snapshot.metadata ?? await readLegacyNativeSessionMetadata(details.cwd, session.createdAt, env);
376
- return {
377
- // A live session owns the directory its pane declared, so it must not also
378
- // be listed from that directory as a second, unopenable session.
379
- binding: declared?.metadata ? details.bound : undefined,
380
- session: sessionRecord(session.name, {
381
- cwd: details.cwd,
382
- state: ombSessionState({ dead: details.dead, attached: session.attached, activity: snapshot.activity }),
383
- attached: session.attached,
384
- activity: snapshot.activity,
385
- hosted: true,
386
- command: details.command,
387
- pid: details.pid,
388
- nativeId: native?.id,
389
- nativeName: native?.title,
390
- firstMessage: native?.firstMessage,
391
- nativeSessionAvailable: Boolean(snapshot.metadata || native),
392
- createdAt: session.createdAt ?? native?.createdAt,
393
- lastAttachedAt: session.lastAttachedAt,
394
- }),
395
- };
396
- }
397
- /**
398
- * Session names whose journal the pane of one live tmux session writes.
399
- *
400
- * Deletion uses this before killing the session, because a renamed session's
401
- * journal lives in the directory it was started with rather than the one named
402
- * after the current tmux session.
403
- */
404
- export async function ombSessionBoundNames(session, cwd, env = process.env) {
405
- if (!isOmbSessionName(session))
406
- return [];
407
- const childEnv = { ...env, BIZAR_OMP_NO_TMUX: "1" };
408
- const panes = await readTmux(resolveMultiplexerBin(env), ["list-panes", "-t", session, "-F", PANE_FORMAT], cwd, childEnv);
409
- if (panes.code !== 0)
410
- return [];
411
- const bound = parsePane(panes.output, env).bound;
412
- return bound && bound !== session ? [bound] : [];
413
- }
414
- /**
415
- * Bizar sessions that tmux no longer hosts.
416
- *
417
- * tmux removes a session as soon as its pane exits, so a terminated session
418
- * only remains discoverable through the native state directory that `omb`
419
- * gives every durable host. A journal written inside the stale window proves
420
- * the agent is still running — a host started outside `omb`, or one whose pane
421
- * died while the agent kept working — so those sessions stay live instead of
422
- * being reported as stopped.
423
- */
424
- async function listUnhostedSessions(env, claimed, now) {
425
- let entries;
426
- try {
427
- entries = await readdir(nativeSessionRoot(env), { withFileTypes: true });
428
- }
429
- catch {
430
- return [];
431
- }
432
- const unhosted = (await Promise.all(entries.map(async (entry) => {
433
- if (!entry.isDirectory() || !entry.name.startsWith(BIZAR_SESSION_PREFIX) || claimed.has(entry.name) || await isOmbSessionDeleted(entry.name, env))
434
- return undefined;
435
- const snapshot = await readNativeSessionSnapshot(join(nativeSessionRoot(env), entry.name), now);
436
- const metadata = snapshot.metadata;
437
- // A directory with no readable session header holds no session: it is an
438
- // emptied tombstone or a directory created before OMP journaled anything.
439
- // Listing it would resurrect a session that is gone.
440
- if (!metadata)
441
- return undefined;
442
- const activity = snapshot.activity;
443
- const alive = Boolean(activity && !activity.stale);
444
- return sessionRecord(entry.name, {
445
- cwd: metadata.cwd ?? "?",
446
- state: alive ? ombSessionState({ dead: false, attached: false, activity }) : "stopped",
447
- attached: false,
448
- activity,
449
- hosted: false,
450
- command: alive ? "unattached" : "exited",
451
- pid: "?",
452
- nativeId: metadata.id,
453
- nativeName: metadata.title,
454
- firstMessage: metadata.firstMessage,
455
- nativeSessionAvailable: true,
456
- createdAt: metadata.createdAt,
457
- });
458
- }))).filter((session) => Boolean(session));
459
- unhosted.sort((a, b) => (b.activity?.updatedAt ?? 0) - (a.activity?.updatedAt ?? 0));
460
- const live = unhosted.filter(session => session.state !== "stopped");
461
- return [...live, ...unhosted.filter(session => session.state === "stopped").slice(0, STOPPED_SESSION_LIMIT)];
462
- }
463
- export async function currentOmbHostSession(cwd = process.cwd(), env = process.env) {
464
- if (!env.TMUX)
465
- return { kind: "not-bizar" };
466
- const args = ["display-message", "-p"];
467
- if (env.TMUX_PANE)
468
- args.push("-t", env.TMUX_PANE);
469
- args.push("#{session_name}");
470
- let result;
471
- try {
472
- result = await readTmux(resolveMultiplexerBin(env), args, cwd, { ...env, BIZAR_OMP_NO_TMUX: "1" });
473
- }
474
- catch {
475
- return { kind: "unknown" };
476
- }
477
- if (result.code !== 0)
478
- return { kind: "unknown" };
479
- const [name = ""] = result.output.trim().split("\n");
480
- // A session Bizar does not own cannot be one of the sessions a stop targets.
481
- return isOmbSessionName(name) ? { kind: "bizar", name } : { kind: "not-bizar" };
482
- }
483
- /** Discover Bizar-owned tmux sessions without touching unrelated tmux sessions. */
484
- export async function listOmbSessions(cwd = process.cwd(), env = process.env, options = {}) {
485
- const tmux = resolveMultiplexerBin(env);
486
- const childEnv = { ...env, BIZAR_OMP_NO_TMUX: "1" };
487
- const now = Date.now();
488
- const sessions = await readTmux(tmux, ["list-sessions", "-F", "#{session_name}\t#{session_created}\t#{session_last_attached}\t#{session_attached}"], cwd, childEnv);
489
- const live = sessions.code === 0 ? parseSessionList(sessions.output) : [];
490
- const described = await Promise.all(live.map(session => describeLiveSession(tmux, session, cwd, childEnv, env, now)));
491
- // Every live session claims the directory its pane writes (its own, or the one
492
- // a rename left behind), so one session is never listed twice under two names.
493
- const claimed = new Set([
494
- ...live.map(session => session.name),
495
- ...described.map(item => item.binding).filter((name) => Boolean(name)),
496
- ]);
497
- const unhosted = await listUnhostedSessions(env, claimed, now);
498
- const stopped = options.includeStopped ? unhosted.filter(session => session.state === "stopped") : [];
499
- return [...described.map(item => item.session), ...unhosted.filter(session => session.state !== "stopped"), ...stopped].sort((a, b) => STATE_RANK[a.state] - STATE_RANK[b.state] ||
500
- a.project.localeCompare(b.project) ||
501
- a.name.localeCompare(b.name));
502
- }
503
- /** Return the most recently attached live session for one exact project path. */
504
- export async function findLastOmbSession(cwd, env = process.env) {
505
- const sessions = await listOmbSessions(cwd, env);
506
- return sessions
507
- // Only a session tmux still hosts can be reattached. Resuming a live but
508
- // unhosted session would put a second writer on its journal.
509
- .filter(session => session.cwd === cwd && session.state !== "stopped" && session.hosted !== false)
510
- .sort((a, b) => (b.lastAttachedAt ?? b.createdAt ?? 0) - (a.lastAttachedAt ?? a.createdAt ?? 0))[0];
511
- }
512
- //# sourceMappingURL=omb-sessions.js.map