wicked-crew 0.7.39 → 0.7.45

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 (380) hide show
  1. package/dist/api/audit.d.ts +3 -0
  2. package/dist/api/audit.d.ts.map +1 -1
  3. package/dist/api/audit.js +2 -0
  4. package/dist/api/audit.js.map +1 -1
  5. package/dist/api/capture.d.ts +149 -0
  6. package/dist/api/capture.d.ts.map +1 -0
  7. package/dist/api/capture.js +330 -0
  8. package/dist/api/capture.js.map +1 -0
  9. package/dist/api/chat-citations.d.ts +174 -0
  10. package/dist/api/chat-citations.d.ts.map +1 -0
  11. package/dist/api/chat-citations.js +528 -0
  12. package/dist/api/chat-citations.js.map +1 -0
  13. package/dist/api/chat-scope.d.ts +37 -1
  14. package/dist/api/chat-scope.d.ts.map +1 -1
  15. package/dist/api/chat-scope.js +131 -7
  16. package/dist/api/chat-scope.js.map +1 -1
  17. package/dist/api/chat-transcripts.d.ts +20 -1
  18. package/dist/api/chat-transcripts.d.ts.map +1 -1
  19. package/dist/api/chat-transcripts.js +29 -0
  20. package/dist/api/chat-transcripts.js.map +1 -1
  21. package/dist/api/delivery-cache.d.ts +2 -2
  22. package/dist/api/delivery-freeze.d.ts +66 -0
  23. package/dist/api/delivery-freeze.d.ts.map +1 -0
  24. package/dist/api/delivery-freeze.js +104 -0
  25. package/dist/api/delivery-freeze.js.map +1 -0
  26. package/dist/api/delivery-index.d.ts +53 -9
  27. package/dist/api/delivery-index.d.ts.map +1 -1
  28. package/dist/api/delivery-index.js +115 -22
  29. package/dist/api/delivery-index.js.map +1 -1
  30. package/dist/api/demo.d.ts +90 -0
  31. package/dist/api/demo.d.ts.map +1 -0
  32. package/dist/api/demo.js +492 -0
  33. package/dist/api/demo.js.map +1 -0
  34. package/dist/api/diagnostics.d.ts +64 -1
  35. package/dist/api/diagnostics.d.ts.map +1 -1
  36. package/dist/api/diagnostics.js +129 -1
  37. package/dist/api/diagnostics.js.map +1 -1
  38. package/dist/api/eval-sample.d.ts +6 -6
  39. package/dist/api/governance-steering.d.ts +2 -2
  40. package/dist/api/mcp.d.ts +282 -0
  41. package/dist/api/mcp.d.ts.map +1 -0
  42. package/dist/api/mcp.js +521 -0
  43. package/dist/api/mcp.js.map +1 -0
  44. package/dist/api/plan-schema.d.ts +56 -0
  45. package/dist/api/plan-schema.d.ts.map +1 -0
  46. package/dist/api/plan-schema.js +26 -0
  47. package/dist/api/plan-schema.js.map +1 -0
  48. package/dist/api/roster-standing.d.ts +15 -2
  49. package/dist/api/roster-standing.d.ts.map +1 -1
  50. package/dist/api/roster-standing.js +55 -3
  51. package/dist/api/roster-standing.js.map +1 -1
  52. package/dist/api/routes.d.ts +647 -59
  53. package/dist/api/routes.d.ts.map +1 -1
  54. package/dist/api/routes.js +906 -146
  55. package/dist/api/routes.js.map +1 -1
  56. package/dist/api/run-files.d.ts.map +1 -1
  57. package/dist/api/run-files.js +31 -2
  58. package/dist/api/run-files.js.map +1 -1
  59. package/dist/api/run-liveness.d.ts +41 -0
  60. package/dist/api/run-liveness.d.ts.map +1 -0
  61. package/dist/api/run-liveness.js +166 -0
  62. package/dist/api/run-liveness.js.map +1 -0
  63. package/dist/api/run-timing-index.d.ts +10 -0
  64. package/dist/api/run-timing-index.d.ts.map +1 -1
  65. package/dist/api/run-timing-index.js +24 -0
  66. package/dist/api/run-timing-index.js.map +1 -1
  67. package/dist/api/seat-health.d.ts.map +1 -1
  68. package/dist/api/seat-health.js +20 -4
  69. package/dist/api/seat-health.js.map +1 -1
  70. package/dist/api/seat-probe.d.ts +141 -0
  71. package/dist/api/seat-probe.d.ts.map +1 -0
  72. package/dist/api/seat-probe.js +257 -0
  73. package/dist/api/seat-probe.js.map +1 -0
  74. package/dist/api/seat-record.d.ts +40 -0
  75. package/dist/api/seat-record.d.ts.map +1 -0
  76. package/dist/api/seat-record.js +218 -0
  77. package/dist/api/seat-record.js.map +1 -0
  78. package/dist/api/seat-signin.d.ts.map +1 -1
  79. package/dist/api/seat-signin.js +3 -1
  80. package/dist/api/seat-signin.js.map +1 -1
  81. package/dist/api/seat-standing.d.ts +24 -4
  82. package/dist/api/seat-standing.d.ts.map +1 -1
  83. package/dist/api/seat-standing.js +50 -3
  84. package/dist/api/seat-standing.js.map +1 -1
  85. package/dist/api/server.d.ts +34 -48
  86. package/dist/api/server.d.ts.map +1 -1
  87. package/dist/api/server.js +316 -116
  88. package/dist/api/server.js.map +1 -1
  89. package/dist/api/skills.d.ts +3 -1
  90. package/dist/api/skills.d.ts.map +1 -1
  91. package/dist/api/skills.js +7 -2
  92. package/dist/api/skills.js.map +1 -1
  93. package/dist/api/stall-watchdog.d.ts +34 -3
  94. package/dist/api/stall-watchdog.d.ts.map +1 -1
  95. package/dist/api/stall-watchdog.js +107 -8
  96. package/dist/api/stall-watchdog.js.map +1 -1
  97. package/dist/api/steering-landing.d.ts +6 -6
  98. package/dist/api/steering-landing.d.ts.map +1 -1
  99. package/dist/api/steering-landing.js +7 -9
  100. package/dist/api/steering-landing.js.map +1 -1
  101. package/dist/api/testing.d.ts +6 -4
  102. package/dist/api/testing.d.ts.map +1 -1
  103. package/dist/api/testing.js +82 -47
  104. package/dist/api/testing.js.map +1 -1
  105. package/dist/campaign/boot-resume.d.ts +34 -0
  106. package/dist/campaign/boot-resume.d.ts.map +1 -0
  107. package/dist/campaign/boot-resume.js +45 -0
  108. package/dist/campaign/boot-resume.js.map +1 -0
  109. package/dist/campaigns/rollup.d.ts +4 -1
  110. package/dist/campaigns/rollup.d.ts.map +1 -1
  111. package/dist/campaigns/rollup.js +6 -1
  112. package/dist/campaigns/rollup.js.map +1 -1
  113. package/dist/campaigns/routes.d.ts +2 -2
  114. package/dist/cli/bearer.d.ts +27 -1
  115. package/dist/cli/bearer.d.ts.map +1 -1
  116. package/dist/cli/bearer.js +62 -2
  117. package/dist/cli/bearer.js.map +1 -1
  118. package/dist/cli/governance.d.ts +11 -0
  119. package/dist/cli/governance.d.ts.map +1 -1
  120. package/dist/cli/governance.js +8 -2
  121. package/dist/cli/governance.js.map +1 -1
  122. package/dist/cli/index.d.ts.map +1 -1
  123. package/dist/cli/index.js +140 -75
  124. package/dist/cli/index.js.map +1 -1
  125. package/dist/cli/mcp.d.ts +11 -0
  126. package/dist/cli/mcp.d.ts.map +1 -1
  127. package/dist/cli/mcp.js +40 -9
  128. package/dist/cli/mcp.js.map +1 -1
  129. package/dist/cli/service.d.ts +78 -0
  130. package/dist/cli/service.d.ts.map +1 -0
  131. package/dist/cli/service.js +334 -0
  132. package/dist/cli/service.js.map +1 -0
  133. package/dist/core/adapter.d.ts +247 -14
  134. package/dist/core/adapter.d.ts.map +1 -1
  135. package/dist/core/adapter.js +638 -161
  136. package/dist/core/adapter.js.map +1 -1
  137. package/dist/core/bridge-reaper.d.ts +4 -1
  138. package/dist/core/bridge-reaper.d.ts.map +1 -1
  139. package/dist/core/bridge-reaper.js +15 -1
  140. package/dist/core/bridge-reaper.js.map +1 -1
  141. package/dist/core/bus-notice.d.ts +27 -0
  142. package/dist/core/bus-notice.d.ts.map +1 -0
  143. package/dist/core/bus-notice.js +24 -0
  144. package/dist/core/bus-notice.js.map +1 -0
  145. package/dist/core/bus.d.ts +99 -0
  146. package/dist/core/bus.d.ts.map +1 -0
  147. package/dist/core/bus.js +176 -0
  148. package/dist/core/bus.js.map +1 -0
  149. package/dist/core/deliver-exclusions.d.ts +71 -0
  150. package/dist/core/deliver-exclusions.d.ts.map +1 -0
  151. package/dist/core/deliver-exclusions.js +110 -0
  152. package/dist/core/deliver-exclusions.js.map +1 -0
  153. package/dist/core/deliver-text.d.ts +61 -14
  154. package/dist/core/deliver-text.d.ts.map +1 -1
  155. package/dist/core/deliver-text.js +178 -30
  156. package/dist/core/deliver-text.js.map +1 -1
  157. package/dist/core/deliver-triage.d.ts +11 -2
  158. package/dist/core/deliver-triage.d.ts.map +1 -1
  159. package/dist/core/deliver-triage.js +19 -1
  160. package/dist/core/deliver-triage.js.map +1 -1
  161. package/dist/core/deliver.d.ts +161 -3
  162. package/dist/core/deliver.d.ts.map +1 -1
  163. package/dist/core/deliver.js +463 -25
  164. package/dist/core/deliver.js.map +1 -1
  165. package/dist/core/deliverable-floor.d.ts.map +1 -1
  166. package/dist/core/deliverable-floor.js +5 -7
  167. package/dist/core/deliverable-floor.js.map +1 -1
  168. package/dist/core/engine-bus.d.ts +40 -0
  169. package/dist/core/engine-bus.d.ts.map +1 -0
  170. package/dist/core/engine-bus.js +27 -0
  171. package/dist/core/engine-bus.js.map +1 -0
  172. package/dist/core/estate-mcp-client.d.ts +87 -5
  173. package/dist/core/estate-mcp-client.d.ts.map +1 -1
  174. package/dist/core/estate-mcp-client.js +90 -11
  175. package/dist/core/estate-mcp-client.js.map +1 -1
  176. package/dist/core/linked-issues.d.ts +46 -0
  177. package/dist/core/linked-issues.d.ts.map +1 -0
  178. package/dist/core/linked-issues.js +123 -0
  179. package/dist/core/linked-issues.js.map +1 -0
  180. package/dist/core/run-identity.d.ts +100 -0
  181. package/dist/core/run-identity.d.ts.map +1 -0
  182. package/dist/core/run-identity.js +178 -0
  183. package/dist/core/run-identity.js.map +1 -0
  184. package/dist/core/shutdown.d.ts +16 -0
  185. package/dist/core/shutdown.d.ts.map +1 -0
  186. package/dist/core/shutdown.js +39 -0
  187. package/dist/core/shutdown.js.map +1 -0
  188. package/dist/core/types.d.ts +15 -1
  189. package/dist/core/types.d.ts.map +1 -1
  190. package/dist/core/types.js +4 -0
  191. package/dist/core/types.js.map +1 -1
  192. package/dist/interactive/bridge-pool.d.ts +67 -3
  193. package/dist/interactive/bridge-pool.d.ts.map +1 -1
  194. package/dist/interactive/bridge-pool.js +129 -13
  195. package/dist/interactive/bridge-pool.js.map +1 -1
  196. package/dist/interactive/bridge-root.d.ts +9 -0
  197. package/dist/interactive/bridge-root.d.ts.map +1 -1
  198. package/dist/interactive/bridge-root.js +11 -4
  199. package/dist/interactive/bridge-root.js.map +1 -1
  200. package/dist/interactive/chat-events.d.ts +14 -9
  201. package/dist/interactive/chat-events.d.ts.map +1 -1
  202. package/dist/interactive/chat-events.js +55 -57
  203. package/dist/interactive/chat-events.js.map +1 -1
  204. package/dist/interactive/council-outcome.d.ts +1 -0
  205. package/dist/interactive/council-outcome.d.ts.map +1 -1
  206. package/dist/interactive/council-outcome.js +33 -0
  207. package/dist/interactive/council-outcome.js.map +1 -1
  208. package/dist/interactive/draft-events.d.ts +36 -17
  209. package/dist/interactive/draft-events.d.ts.map +1 -1
  210. package/dist/interactive/draft-events.js +121 -92
  211. package/dist/interactive/draft-events.js.map +1 -1
  212. package/dist/interactive/draft-skill.d.ts +59 -0
  213. package/dist/interactive/draft-skill.d.ts.map +1 -1
  214. package/dist/interactive/draft-skill.js +233 -0
  215. package/dist/interactive/draft-skill.js.map +1 -1
  216. package/dist/interactive/edit-events.d.ts +1 -14
  217. package/dist/interactive/edit-events.d.ts.map +1 -1
  218. package/dist/interactive/edit-events.js +37 -70
  219. package/dist/interactive/edit-events.js.map +1 -1
  220. package/dist/interactive/proxy-routes.d.ts +2 -2
  221. package/dist/interactive/proxy-routes.d.ts.map +1 -1
  222. package/dist/interactive/proxy-routes.js +4 -13
  223. package/dist/interactive/proxy-routes.js.map +1 -1
  224. package/dist/interactive/ws-relay.d.ts +9 -10
  225. package/dist/interactive/ws-relay.d.ts.map +1 -1
  226. package/dist/interactive/ws-relay.js +23 -50
  227. package/dist/interactive/ws-relay.js.map +1 -1
  228. package/dist/mcp/broker.d.ts +88 -0
  229. package/dist/mcp/broker.d.ts.map +1 -0
  230. package/dist/mcp/broker.js +307 -0
  231. package/dist/mcp/broker.js.map +1 -0
  232. package/dist/mcp/call-records.d.ts +61 -0
  233. package/dist/mcp/call-records.d.ts.map +1 -0
  234. package/dist/mcp/call-records.js +135 -0
  235. package/dist/mcp/call-records.js.map +1 -0
  236. package/dist/mcp/classify.d.ts +45 -0
  237. package/dist/mcp/classify.d.ts.map +1 -0
  238. package/dist/mcp/classify.js +83 -0
  239. package/dist/mcp/classify.js.map +1 -0
  240. package/dist/mcp/discovery.d.ts +24 -0
  241. package/dist/mcp/discovery.d.ts.map +1 -0
  242. package/dist/mcp/discovery.js +78 -0
  243. package/dist/mcp/discovery.js.map +1 -0
  244. package/dist/mcp/invoke.d.ts +36 -0
  245. package/dist/mcp/invoke.d.ts.map +1 -0
  246. package/dist/mcp/invoke.js +80 -0
  247. package/dist/mcp/invoke.js.map +1 -0
  248. package/dist/mcp/policies.d.ts +110 -0
  249. package/dist/mcp/policies.d.ts.map +1 -0
  250. package/dist/mcp/policies.js +400 -0
  251. package/dist/mcp/policies.js.map +1 -0
  252. package/dist/mcp/probe.d.ts +66 -0
  253. package/dist/mcp/probe.d.ts.map +1 -0
  254. package/dist/mcp/probe.js +116 -0
  255. package/dist/mcp/probe.js.map +1 -0
  256. package/dist/mcp/redact.d.ts +34 -0
  257. package/dist/mcp/redact.d.ts.map +1 -0
  258. package/dist/mcp/redact.js +84 -0
  259. package/dist/mcp/redact.js.map +1 -0
  260. package/dist/mcp/registry-store.d.ts +69 -0
  261. package/dist/mcp/registry-store.d.ts.map +1 -0
  262. package/dist/mcp/registry-store.js +82 -0
  263. package/dist/mcp/registry-store.js.map +1 -0
  264. package/dist/mcp/registry.d.ts +147 -0
  265. package/dist/mcp/registry.d.ts.map +1 -0
  266. package/dist/mcp/registry.js +509 -0
  267. package/dist/mcp/registry.js.map +1 -0
  268. package/dist/mcp/rest.d.ts +111 -0
  269. package/dist/mcp/rest.d.ts.map +1 -0
  270. package/dist/mcp/rest.js +606 -0
  271. package/dist/mcp/rest.js.map +1 -0
  272. package/dist/mcp/secrets.d.ts +66 -0
  273. package/dist/mcp/secrets.d.ts.map +1 -0
  274. package/dist/mcp/secrets.js +180 -0
  275. package/dist/mcp/secrets.js.map +1 -0
  276. package/dist/mcp/tool-list.d.ts +25 -0
  277. package/dist/mcp/tool-list.d.ts.map +1 -0
  278. package/dist/mcp/tool-list.js +62 -0
  279. package/dist/mcp/tool-list.js.map +1 -0
  280. package/dist/mcp/upstream-error.d.ts +12 -0
  281. package/dist/mcp/upstream-error.d.ts.map +1 -0
  282. package/dist/mcp/upstream-error.js +14 -0
  283. package/dist/mcp/upstream-error.js.map +1 -0
  284. package/dist/mcp/usage.d.ts +31 -0
  285. package/dist/mcp/usage.d.ts.map +1 -0
  286. package/dist/mcp/usage.js +159 -0
  287. package/dist/mcp/usage.js.map +1 -0
  288. package/dist/presets/routes.d.ts +53 -0
  289. package/dist/presets/routes.d.ts.map +1 -0
  290. package/dist/presets/routes.js +115 -0
  291. package/dist/presets/routes.js.map +1 -0
  292. package/dist/projects/activity.d.ts +6 -18
  293. package/dist/projects/activity.d.ts.map +1 -1
  294. package/dist/projects/activity.js +17 -60
  295. package/dist/projects/activity.js.map +1 -1
  296. package/dist/projects/events.d.ts +6 -5
  297. package/dist/projects/events.d.ts.map +1 -1
  298. package/dist/projects/events.js +33 -58
  299. package/dist/projects/events.js.map +1 -1
  300. package/dist/projects/graph.d.ts +11 -0
  301. package/dist/projects/graph.d.ts.map +1 -1
  302. package/dist/projects/graph.js +12 -0
  303. package/dist/projects/graph.js.map +1 -1
  304. package/dist/projects/routes.d.ts.map +1 -1
  305. package/dist/projects/routes.js +19 -0
  306. package/dist/projects/routes.js.map +1 -1
  307. package/dist/projects/state-home-preflight.d.ts.map +1 -1
  308. package/dist/projects/state-home-preflight.js +7 -0
  309. package/dist/projects/state-home-preflight.js.map +1 -1
  310. package/dist/projects/state-home-registry.d.ts.map +1 -1
  311. package/dist/projects/state-home-registry.js +9 -1
  312. package/dist/projects/state-home-registry.js.map +1 -1
  313. package/dist/qe/acceptance.d.ts +28 -28
  314. package/dist/qe/acceptance.d.ts.map +1 -1
  315. package/dist/qe/acceptance.js +60 -61
  316. package/dist/qe/acceptance.js.map +1 -1
  317. package/dist/qe/test-sets.d.ts +3 -5
  318. package/dist/qe/test-sets.d.ts.map +1 -1
  319. package/dist/qe/test-sets.js +5 -7
  320. package/dist/qe/test-sets.js.map +1 -1
  321. package/dist/skills/installed.d.ts +51 -0
  322. package/dist/skills/installed.d.ts.map +1 -0
  323. package/dist/skills/installed.js +46 -0
  324. package/dist/skills/installed.js.map +1 -0
  325. package/dist/skills/phase-skill-gaps.d.ts +108 -0
  326. package/dist/skills/phase-skill-gaps.d.ts.map +1 -0
  327. package/dist/skills/phase-skill-gaps.js +199 -0
  328. package/dist/skills/phase-skill-gaps.js.map +1 -0
  329. package/dist/skills/runtime.d.ts +1 -1
  330. package/dist/skills/runtime.d.ts.map +1 -1
  331. package/dist/skills/runtime.js +2 -1
  332. package/dist/skills/runtime.js.map +1 -1
  333. package/dist/standing-orders/evaluator.d.ts +113 -0
  334. package/dist/standing-orders/evaluator.d.ts.map +1 -0
  335. package/dist/standing-orders/evaluator.js +225 -0
  336. package/dist/standing-orders/evaluator.js.map +1 -0
  337. package/dist/standing-orders/history.d.ts +58 -0
  338. package/dist/standing-orders/history.d.ts.map +1 -0
  339. package/dist/standing-orders/history.js +117 -0
  340. package/dist/standing-orders/history.js.map +1 -0
  341. package/dist/standing-orders/parse.d.ts +19 -0
  342. package/dist/standing-orders/parse.d.ts.map +1 -0
  343. package/dist/standing-orders/parse.js +75 -0
  344. package/dist/standing-orders/parse.js.map +1 -0
  345. package/dist/standing-orders/routes.d.ts +180 -0
  346. package/dist/standing-orders/routes.d.ts.map +1 -0
  347. package/dist/standing-orders/routes.js +95 -0
  348. package/dist/standing-orders/routes.js.map +1 -0
  349. package/dist/standing-orders/store.d.ts +154 -0
  350. package/dist/standing-orders/store.d.ts.map +1 -0
  351. package/dist/standing-orders/store.js +189 -0
  352. package/dist/standing-orders/store.js.map +1 -0
  353. package/dist/studio/assets/index-CvV5qITf.css +32 -0
  354. package/dist/studio/assets/index-jCOy6Ns7.js +568 -0
  355. package/dist/studio/index.html +3 -3
  356. package/dist/studio/testid-inventory.json +3307 -897
  357. package/dist/team/key.d.ts +5 -0
  358. package/dist/team/key.d.ts.map +1 -0
  359. package/dist/team/key.js +21 -0
  360. package/dist/team/key.js.map +1 -0
  361. package/dist/team/routes.d.ts +196 -0
  362. package/dist/team/routes.d.ts.map +1 -0
  363. package/dist/team/routes.js +274 -0
  364. package/dist/team/routes.js.map +1 -0
  365. package/dist/team/ws-relay.d.ts +39 -0
  366. package/dist/team/ws-relay.d.ts.map +1 -0
  367. package/dist/team/ws-relay.js +63 -0
  368. package/dist/team/ws-relay.js.map +1 -0
  369. package/endpoint-manifest.json +502 -6
  370. package/package.json +6 -6
  371. package/dist/interactive/demo-events.d.ts +0 -367
  372. package/dist/interactive/demo-events.d.ts.map +0 -1
  373. package/dist/interactive/demo-events.js +0 -1293
  374. package/dist/interactive/demo-events.js.map +0 -1
  375. package/dist/qe/gate-events.d.ts +0 -113
  376. package/dist/qe/gate-events.d.ts.map +0 -1
  377. package/dist/qe/gate-events.js +0 -172
  378. package/dist/qe/gate-events.js.map +0 -1
  379. package/dist/studio/assets/index-BRDAN35i.js +0 -548
  380. package/dist/studio/assets/index-Drfcsy8b.css +0 -32
@@ -0,0 +1,99 @@
1
+ /**
2
+ * THE CREW BUS (wicked-core#631) — every bus row in-daemon crew code writes or reads goes through
3
+ * the ENGINE that holds the bus.
4
+ *
5
+ * The daemon's bus file is the engine's (DES-TEAMING-002 T0): the engine opens it once, through its
6
+ * bundled SQLite, and never closes it. A second SQLite library in the same process cannot share that
7
+ * file safely: POSIX locks belong to the process, so two libraries do not exclude each other's
8
+ * writes, and a close in either drops the other's locks (sqlite.org/howtocorrupt.html §2.2.1,
9
+ * F-E2E-021). So crew holds no SQLite library at all. It emits with `Core.busEmit` and reads with
10
+ * `Core.busRead`; the engine is the one writer and the one reader on its bus.
11
+ *
12
+ * The adapter attaches its engine to the bus file it handed it (`attachEngineBus`), and each seam
13
+ * names the bus it uses by path. A seam whose bus no engine holds cannot arm: it throws, and the
14
+ * seam logs and disables itself. tests/bus-no-write.test.ts fails the build if in-daemon code
15
+ * names a SQLite library or wicked-bus.
16
+ */
17
+ /** The engine's two bus calls (wicked-core-ts `Core.busEmit` / `Core.busRead`). */
18
+ export interface EngineBus {
19
+ busEmit(eventJson: string): Promise<number>;
20
+ busRead(afterId: number, limit: number, typePrefix?: string | null, includeExpired?: boolean | null): Promise<string>;
21
+ }
22
+ /** One row, as wicked-bus `emit` takes it. */
23
+ export interface BusRow {
24
+ event_type: string;
25
+ domain: string;
26
+ subdomain?: string;
27
+ payload: unknown;
28
+ idempotency_key?: string;
29
+ producer_id?: string;
30
+ /** Per-event TTL in whole hours (wicked-bus `emit`'s override); default the bus config's. */
31
+ ttl_hours?: number;
32
+ }
33
+ /** One `events` row as the engine reads it back: every column the file has, `payload` parsed
34
+ * (the stored string when it is not JSON). */
35
+ export interface BusEvent {
36
+ event_id: number;
37
+ event_type: string;
38
+ domain: string;
39
+ subdomain: string;
40
+ payload: unknown;
41
+ idempotency_key: string;
42
+ emitted_at: number;
43
+ [k: string]: unknown;
44
+ }
45
+ /** Test seam only: the bus for a path no engine is attached to (tests/setup/bus-double.ts). */
46
+ export declare const busTesting: {
47
+ unattached: ((dbPath: string) => EngineBus) | undefined;
48
+ };
49
+ /** The engine at `dbPath` serves every seam that names that bus (the adapter, once its engine is up). */
50
+ export declare function attachEngineBus(dbPath: string, engine: EngineBus): void;
51
+ /** Undo {@link attachEngineBus} (the adapter, on close) — only if `engine` is still the one attached. */
52
+ export declare function detachEngineBus(dbPath: string, engine: EngineBus): void;
53
+ /** The resolved path of the bus at `dbPath` when an engine holds it; throws when none does (a seam
54
+ * checks this at arm time, so a seam with no bus disables itself before arming anything). */
55
+ export declare function requireEngineBus(dbPath: string | undefined): string;
56
+ /**
57
+ * Emit one row on the bus at `dbPath`. Resolves to the row's `event_id`; a key already on the bus
58
+ * resolves to the existing row's id (the engine's dedup: success, as wicked-bus's WB-002 was).
59
+ * Rejects when no engine holds the bus or the engine refuses the row (`WB-001 …`).
60
+ */
61
+ export declare function emitOnBus(dbPath: string, row: BusRow): Promise<number>;
62
+ /**
63
+ * Every row on the bus at `dbPath` whose type starts with `typePrefix`, oldest first. `history:
64
+ * true` includes rows past their TTL: the daemon's bus is never swept, so an expired row is still
65
+ * the record (the activity feed, the team route); a live consumer leaves it off.
66
+ */
67
+ export declare function readBus(dbPath: string, typePrefix: string, opts?: {
68
+ history?: boolean;
69
+ }): Promise<BusEvent[]>;
70
+ export interface BusTapOptions {
71
+ /** The bus db (the one the daemon handed its engine). */
72
+ dbPath: string | undefined;
73
+ /** `<prefix>.**` or an exact type, optionally `@<domain>` (`wicked.interactive.**`, `wicked.qe.**`, …). */
74
+ filter: string;
75
+ /** Poll cadence, ms. */
76
+ pollIntervalMs?: number | undefined;
77
+ /** Called once per matching row, in order; awaited before the next row. */
78
+ handler: (event: BusEvent) => void | Promise<void>;
79
+ /** A failed read (`event` null) or a failed handler (the row). Never retried; the cursor moves on. */
80
+ onError?: ((err: Error, event?: BusEvent | null) => void) | undefined;
81
+ }
82
+ export interface BusTap {
83
+ /** The bus file this tap reads. */
84
+ readonly dbPath: string;
85
+ /** Stop polling; resolves once an in-flight handler has returned. */
86
+ stop(): Promise<void>;
87
+ }
88
+ /**
89
+ * Arm a tap: poll the engine's bus from its newest row (rows already on the bus are history, as
90
+ * wicked-bus's `latest` cursor treated them), cursor in memory, handing each matching row to the
91
+ * handler in order. Rejects when no engine holds the bus or the filter is not one crew supports
92
+ * (the caller logs and disables its seam); a failed read goes to `onError` and the next poll
93
+ * retries it. A
94
+ * restart starts at the newest row again, so rows emitted while the daemon was down are not
95
+ * delivered; a failed handler is not retried. A bus file replaced under the same path is followed:
96
+ * the engine answers cursor 0 and the tap reads the new file from its first row.
97
+ */
98
+ export declare function tapBus(opts: BusTapOptions): Promise<BusTap>;
99
+ //# sourceMappingURL=bus.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bus.d.ts","sourceRoot":"","sources":["../../src/core/bus.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,176 @@
1
+ /**
2
+ * THE CREW BUS (wicked-core#631) — every bus row in-daemon crew code writes or reads goes through
3
+ * the ENGINE that holds the bus.
4
+ *
5
+ * The daemon's bus file is the engine's (DES-TEAMING-002 T0): the engine opens it once, through its
6
+ * bundled SQLite, and never closes it. A second SQLite library in the same process cannot share that
7
+ * file safely: POSIX locks belong to the process, so two libraries do not exclude each other's
8
+ * writes, and a close in either drops the other's locks (sqlite.org/howtocorrupt.html §2.2.1,
9
+ * F-E2E-021). So crew holds no SQLite library at all. It emits with `Core.busEmit` and reads with
10
+ * `Core.busRead`; the engine is the one writer and the one reader on its bus.
11
+ *
12
+ * The adapter attaches its engine to the bus file it handed it (`attachEngineBus`), and each seam
13
+ * names the bus it uses by path. A seam whose bus no engine holds cannot arm: it throws, and the
14
+ * seam logs and disables itself. tests/bus-no-write.test.ts fails the build if in-daemon code
15
+ * names a SQLite library or wicked-bus.
16
+ */
17
+ import { resolve } from 'node:path';
18
+ /** Rows per read: a burst drains over a few polls instead of one unbounded read. */
19
+ const BATCH = 500;
20
+ const engines = new Map();
21
+ /** Test seam only: the bus for a path no engine is attached to (tests/setup/bus-double.ts). */
22
+ export const busTesting = {
23
+ unattached: undefined,
24
+ };
25
+ /** The engine at `dbPath` serves every seam that names that bus (the adapter, once its engine is up). */
26
+ export function attachEngineBus(dbPath, engine) {
27
+ engines.set(resolve(dbPath), engine);
28
+ }
29
+ /** Undo {@link attachEngineBus} (the adapter, on close) — only if `engine` is still the one attached. */
30
+ export function detachEngineBus(dbPath, engine) {
31
+ const key = resolve(dbPath);
32
+ if (engines.get(key) === engine)
33
+ engines.delete(key);
34
+ }
35
+ /** The resolved path of the bus at `dbPath` when an engine holds it; throws when none does (a seam
36
+ * checks this at arm time, so a seam with no bus disables itself before arming anything). */
37
+ export function requireEngineBus(dbPath) {
38
+ engineFor(dbPath);
39
+ return resolve(dbPath);
40
+ }
41
+ /** The engine holding the bus at `dbPath`; throws when there is none. */
42
+ function engineFor(dbPath) {
43
+ if (dbPath === undefined)
44
+ throw new Error('no bus named (the daemon hands each seam its engine bus)');
45
+ const key = resolve(dbPath);
46
+ const engine = engines.get(key) ?? busTesting.unattached?.(key);
47
+ if (engine === undefined) {
48
+ throw new Error(`no engine holds the bus at ${key} (the engine was handed no bus, or another one)`);
49
+ }
50
+ return engine;
51
+ }
52
+ /**
53
+ * Emit one row on the bus at `dbPath`. Resolves to the row's `event_id`; a key already on the bus
54
+ * resolves to the existing row's id (the engine's dedup: success, as wicked-bus's WB-002 was).
55
+ * Rejects when no engine holds the bus or the engine refuses the row (`WB-001 …`).
56
+ */
57
+ export async function emitOnBus(dbPath, row) {
58
+ return engineFor(dbPath).busEmit(JSON.stringify(row));
59
+ }
60
+ /** One page of rows after `afterId` whose type starts with `typePrefix` (live ones unless
61
+ * `includeExpired`). */
62
+ async function readPage(engine, afterId, typePrefix, includeExpired = false) {
63
+ return JSON.parse(await engine.busRead(afterId, BATCH, typePrefix, includeExpired));
64
+ }
65
+ /**
66
+ * Every row on the bus at `dbPath` whose type starts with `typePrefix`, oldest first. `history:
67
+ * true` includes rows past their TTL: the daemon's bus is never swept, so an expired row is still
68
+ * the record (the activity feed, the team route); a live consumer leaves it off.
69
+ */
70
+ export async function readBus(dbPath, typePrefix, opts = {}) {
71
+ const engine = engineFor(dbPath);
72
+ const out = [];
73
+ for (let after = 0;;) {
74
+ const page = await readPage(engine, after, typePrefix, opts.history === true);
75
+ out.push(...page.rows);
76
+ if (page.rows.length < BATCH || page.next <= after)
77
+ return out;
78
+ after = page.next;
79
+ }
80
+ }
81
+ /**
82
+ * A tap filter: `<prefix>.**` (every type under the prefix) or `<type>` (exactly that type), either
83
+ * with an optional `@<domain>` (only that publisher) — the two wicked-bus filter forms crew's seams
84
+ * use, meaning what they mean to wicked-bus `matchesFilter`. Any other form throws at arm.
85
+ */
86
+ function compileFilter(filter) {
87
+ const at = filter.indexOf('@');
88
+ const type = at === -1 ? filter : filter.slice(0, at);
89
+ const domain = at === -1 ? '' : filter.slice(at + 1);
90
+ const ofDomain = (e) => domain === '' || e.domain === domain;
91
+ if (type.endsWith('.**') && !type.slice(0, -3).includes('*')) {
92
+ const typePrefix = type.slice(0, -2);
93
+ return { typePrefix, matches: (e) => ofDomain(e) && e.event_type.length > typePrefix.length };
94
+ }
95
+ if (type !== '' && !type.includes('*')) {
96
+ return { typePrefix: type, matches: (e) => ofDomain(e) && e.event_type === type };
97
+ }
98
+ throw new Error(`unsupported bus filter ${JSON.stringify(filter)} (use <prefix>.** or an exact type, optionally @<domain>)`);
99
+ }
100
+ /**
101
+ * Arm a tap: poll the engine's bus from its newest row (rows already on the bus are history, as
102
+ * wicked-bus's `latest` cursor treated them), cursor in memory, handing each matching row to the
103
+ * handler in order. Rejects when no engine holds the bus or the filter is not one crew supports
104
+ * (the caller logs and disables its seam); a failed read goes to `onError` and the next poll
105
+ * retries it. A
106
+ * restart starts at the newest row again, so rows emitted while the daemon was down are not
107
+ * delivered; a failed handler is not retried. A bus file replaced under the same path is followed:
108
+ * the engine answers cursor 0 and the tap reads the new file from its first row.
109
+ */
110
+ export async function tapBus(opts) {
111
+ const engine = engineFor(opts.dbPath);
112
+ const dbPath = resolve(opts.dbPath);
113
+ const { typePrefix, matches } = compileFilter(opts.filter);
114
+ let stopped = false;
115
+ let inFlight = null;
116
+ const report = (err, event) => {
117
+ opts.onError?.(err instanceof Error ? err : new Error(String(err)), event);
118
+ };
119
+ // Where the tap starts: the bus tail as of arming. `null` until that read succeeds — a failed
120
+ // first read is reported and retried by the next poll, never a guessed start.
121
+ let cursor = null;
122
+ const start = async () => {
123
+ try {
124
+ cursor = JSON.parse(await engine.busRead(0, 0, null)).next;
125
+ }
126
+ catch (err) {
127
+ report(err, null);
128
+ }
129
+ };
130
+ await start();
131
+ const poll = async () => {
132
+ if (cursor === null)
133
+ return start();
134
+ let page;
135
+ try {
136
+ page = await readPage(engine, cursor, typePrefix);
137
+ }
138
+ catch (err) {
139
+ report(err, null);
140
+ return;
141
+ }
142
+ for (const row of page.rows) {
143
+ if (stopped)
144
+ return;
145
+ cursor = row.event_id;
146
+ if (!matches(row))
147
+ continue;
148
+ try {
149
+ await opts.handler(row);
150
+ }
151
+ catch (err) {
152
+ report(err, row);
153
+ }
154
+ }
155
+ if (!stopped)
156
+ cursor = page.next;
157
+ };
158
+ const timer = setInterval(() => {
159
+ if (stopped || inFlight !== null)
160
+ return;
161
+ inFlight = poll().finally(() => {
162
+ inFlight = null;
163
+ });
164
+ }, opts.pollIntervalMs ?? 2000);
165
+ timer.unref();
166
+ return {
167
+ dbPath,
168
+ stop: async () => {
169
+ stopped = true;
170
+ clearInterval(timer);
171
+ if (inFlight !== null)
172
+ await inFlight;
173
+ },
174
+ };
175
+ }
176
+ //# sourceMappingURL=bus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bus.js","sourceRoot":"","sources":["../../src/core/bus.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * WHAT THE DELIVER PUSH LEAVES BEHIND — the crew#434 classifier, as one reusable predicate.
3
+ *
4
+ * The rules themselves are not new: they have run inside `deliverPrScript`'s generated bash since
5
+ * crew#434 (an untracked candidate is staged UNLESS it looks like scratch or key material, and
6
+ * every exclusion is printed with its reason). What is new is that they are now readable from
7
+ * TypeScript, because a second consumer needs the SAME answer.
8
+ *
9
+ * ## Why (F3, ship-proof C7)
10
+ *
11
+ * The deliver gate's consent diffstat is computed from `GET /runs/:id/diff`, whose untracked pass
12
+ * appended every non-ignored untracked path as an all-addition hunk. The push does not carry every
13
+ * non-ignored untracked path. On a run whose creator left a `tmp/` behind, the gate read
14
+ * **"109 files changed, +258, -2"** and the commit pushed **4 files, +47, -2** — 27x over, on the
15
+ * one gate with an irreversible external side effect. The script printed
16
+ * `deliver: EXCLUDED (scratch-dir): tmp/ (105 files)`, so the exclusion applied to the push and
17
+ * not to the number the operator approved.
18
+ *
19
+ * The number on a consent surface has to be the number that ships, so the diff the gate reads now
20
+ * runs this classifier over its untracked candidates.
21
+ *
22
+ * ## Drift
23
+ *
24
+ * There are necessarily TWO implementations — this one runs in the daemon, the other is generated
25
+ * bash running in the run worktree — and only one of them decides what is actually pushed. The
26
+ * shell is therefore the source of truth and this module tracks it; they are pinned together by
27
+ * `tests/deliver-gate-diffstat.test.ts`, which runs the REAL script over a fixture tree and
28
+ * requires the committed set to equal the set this function keeps.
29
+ *
30
+ * It is a GUARD, NOT A SILENT DROP: the script still prints every excluded path with its reason
31
+ * into the phase output (retained and served on the run wire), and this module only changes which
32
+ * files a *preview* of the push counts.
33
+ */
34
+ /**
35
+ * The deliver script's untracked RECOVERY SENTINEL (crew#432): a failed push leaves this empty file
36
+ * at the worktree root so the engine's terminal reap never removes a worktree whose work was
37
+ * committed but not delivered, and the next attempt removes it before staging. It is never part of
38
+ * the push, so it is never part of the consent diffstat either (N2, ship re-proof): the retry gate
39
+ * read "5 files changed" for a commit of 4 because this predicate did not know the name. The
40
+ * script's `S=` line is generated FROM this constant, so the name cannot drift between the two.
41
+ */
42
+ export declare const DELIVER_STRANDED_SENTINEL = ".wicked-crew-delivery-stranded";
43
+ /** Past this, an otherwise-unrecognised file is scratch by size alone (the generic net). */
44
+ export declare const OVERSIZE_BYTES = 1048576;
45
+ /**
46
+ * Why the deliver push would exclude this path on its NAME alone — the arms that need no `stat`:
47
+ * the denylist, the `socket` basename, `.DS_Store`, and a scratch directory at any depth. `null`
48
+ * means "no name rule fires"; the caller still owes the size rule ({@link deliverExclusionReason}).
49
+ *
50
+ * Split out so a caller can classify 100 000 untracked paths without 100 000 synchronous `stat`
51
+ * calls on the daemon's event loop (codex review of the F3 PR, MEDIUM): only a path that survives
52
+ * every name rule is ever stat'd, and under a scratch directory none of them are.
53
+ *
54
+ * `relPath` is repo-relative with `/` separators — git's own spelling, which
55
+ * `git status --porcelain -z` and `git ls-files -z` emit on every platform.
56
+ *
57
+ * The order of the arms is the script's order, and it matters: a `tmp/x.db` reports
58
+ * `denylisted-name`, exactly as the shell's `[ -n "$RN" ] ||` guards do.
59
+ */
60
+ export declare function deliverExclusionByName(relPath: string): string | null;
61
+ /**
62
+ * Why the deliver push would EXCLUDE this untracked path, or `null` when it rides — the whole
63
+ * ladder, name rules first and then the size rule.
64
+ *
65
+ * `sizeBytes` is the file's size, or `null` when it could not be stat'd; an unknown size is never
66
+ * treated as oversize (the shell's `wc -c < "$F" 2>/dev/null || echo 0` degrades the same way).
67
+ * A caller that wants to avoid the `stat` for a path a name rule already rejects calls
68
+ * {@link deliverExclusionByName} first.
69
+ */
70
+ export declare function deliverExclusionReason(relPath: string, sizeBytes: number | null): string | null;
71
+ //# sourceMappingURL=deliver-exclusions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deliver-exclusions.d.ts","sourceRoot":"","sources":["../../src/core/deliver-exclusions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH;;;;;;;GAOG;AACH,eAAO,MAAM,yBAAyB,mCAAmC,CAAC;AAgB1E,4FAA4F;AAC5F,eAAO,MAAM,cAAc,UAAU,CAAC;AAEtC;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAerE;AAED;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAK/F"}
@@ -0,0 +1,110 @@
1
+ /**
2
+ * WHAT THE DELIVER PUSH LEAVES BEHIND — the crew#434 classifier, as one reusable predicate.
3
+ *
4
+ * The rules themselves are not new: they have run inside `deliverPrScript`'s generated bash since
5
+ * crew#434 (an untracked candidate is staged UNLESS it looks like scratch or key material, and
6
+ * every exclusion is printed with its reason). What is new is that they are now readable from
7
+ * TypeScript, because a second consumer needs the SAME answer.
8
+ *
9
+ * ## Why (F3, ship-proof C7)
10
+ *
11
+ * The deliver gate's consent diffstat is computed from `GET /runs/:id/diff`, whose untracked pass
12
+ * appended every non-ignored untracked path as an all-addition hunk. The push does not carry every
13
+ * non-ignored untracked path. On a run whose creator left a `tmp/` behind, the gate read
14
+ * **"109 files changed, +258, -2"** and the commit pushed **4 files, +47, -2** — 27x over, on the
15
+ * one gate with an irreversible external side effect. The script printed
16
+ * `deliver: EXCLUDED (scratch-dir): tmp/ (105 files)`, so the exclusion applied to the push and
17
+ * not to the number the operator approved.
18
+ *
19
+ * The number on a consent surface has to be the number that ships, so the diff the gate reads now
20
+ * runs this classifier over its untracked candidates.
21
+ *
22
+ * ## Drift
23
+ *
24
+ * There are necessarily TWO implementations — this one runs in the daemon, the other is generated
25
+ * bash running in the run worktree — and only one of them decides what is actually pushed. The
26
+ * shell is therefore the source of truth and this module tracks it; they are pinned together by
27
+ * `tests/deliver-gate-diffstat.test.ts`, which runs the REAL script over a fixture tree and
28
+ * requires the committed set to equal the set this function keeps.
29
+ *
30
+ * It is a GUARD, NOT A SILENT DROP: the script still prints every excluded path with its reason
31
+ * into the phase output (retained and served on the run wire), and this module only changes which
32
+ * files a *preview* of the push counts.
33
+ */
34
+ /**
35
+ * The deliver script's untracked RECOVERY SENTINEL (crew#432): a failed push leaves this empty file
36
+ * at the worktree root so the engine's terminal reap never removes a worktree whose work was
37
+ * committed but not delivered, and the next attempt removes it before staging. It is never part of
38
+ * the push, so it is never part of the consent diffstat either (N2, ship re-proof): the retry gate
39
+ * read "5 files changed" for a commit of 4 because this predicate did not know the name. The
40
+ * script's `S=` line is generated FROM this constant, so the name cannot drift between the two.
41
+ */
42
+ export const DELIVER_STRANDED_SENTINEL = '.wicked-crew-delivery-stranded';
43
+ /** Basename globs that mean "scratch or key material, never a run's product" (crew#434). */
44
+ const DENYLISTED = [
45
+ /\.db$/, /\.db-wal$/, /\.db-shm$/,
46
+ /\.sqlite$/, /\.sqlite2$/, /\.sqlite3$/, /\.sqlite-wal$/, /\.sqlite-shm$/,
47
+ /\.sock$/, /\.pid$/,
48
+ /\.env$/, /\.env\./, /^\.envrc$/,
49
+ /\.gif$/, /\.webm$/, /\.mp4$/, /\.mov$/,
50
+ /\.pem$/, /\.key$/, /\.p12$/, /\.pfx$/,
51
+ /^id_rsa/, /credentials/,
52
+ ];
53
+ /** The scratch/cache directory names the push never carries, at any depth. */
54
+ const SCRATCH_DIRS = ['tmp', '.tmp', 'scratch', '.cache', 'coverage'];
55
+ /** Past this, an otherwise-unrecognised file is scratch by size alone (the generic net). */
56
+ export const OVERSIZE_BYTES = 1048576;
57
+ /**
58
+ * Why the deliver push would exclude this path on its NAME alone — the arms that need no `stat`:
59
+ * the denylist, the `socket` basename, `.DS_Store`, and a scratch directory at any depth. `null`
60
+ * means "no name rule fires"; the caller still owes the size rule ({@link deliverExclusionReason}).
61
+ *
62
+ * Split out so a caller can classify 100 000 untracked paths without 100 000 synchronous `stat`
63
+ * calls on the daemon's event loop (codex review of the F3 PR, MEDIUM): only a path that survives
64
+ * every name rule is ever stat'd, and under a scratch directory none of them are.
65
+ *
66
+ * `relPath` is repo-relative with `/` separators — git's own spelling, which
67
+ * `git status --porcelain -z` and `git ls-files -z` emit on every platform.
68
+ *
69
+ * The order of the arms is the script's order, and it matters: a `tmp/x.db` reports
70
+ * `denylisted-name`, exactly as the shell's `[ -n "$RN" ] ||` guards do.
71
+ */
72
+ export function deliverExclusionByName(relPath) {
73
+ // The script's own recovery sentinel, at the worktree root only — the shell's first arm.
74
+ if (relPath === DELIVER_STRANDED_SENTINEL)
75
+ return 'delivery-sentinel';
76
+ const base = relPath.slice(relPath.lastIndexOf('/') + 1);
77
+ // The script classifies on a LOWERCASED basename so DEPLOY.KEY / .ENV / SOCKET.PATH cannot
78
+ // bypass the denylist by case (crew#439).
79
+ const lower = base.toLowerCase();
80
+ if (DENYLISTED.some((re) => re.test(lower)))
81
+ return 'denylisted-name';
82
+ if (lower.includes('socket'))
83
+ return 'socket-name';
84
+ // `.DS_Store` is matched on the ORIGINAL basename, as the shell does.
85
+ if (base === '.DS_Store')
86
+ return 'ds-store';
87
+ const segments = relPath.split('/');
88
+ // Every segment BUT the last is a directory of the path (`/$F` against `*/tmp/*` in the shell).
89
+ if (segments.slice(0, -1).some((s) => SCRATCH_DIRS.includes(s)))
90
+ return 'scratch-dir';
91
+ return null;
92
+ }
93
+ /**
94
+ * Why the deliver push would EXCLUDE this untracked path, or `null` when it rides — the whole
95
+ * ladder, name rules first and then the size rule.
96
+ *
97
+ * `sizeBytes` is the file's size, or `null` when it could not be stat'd; an unknown size is never
98
+ * treated as oversize (the shell's `wc -c < "$F" 2>/dev/null || echo 0` degrades the same way).
99
+ * A caller that wants to avoid the `stat` for a path a name rule already rejects calls
100
+ * {@link deliverExclusionByName} first.
101
+ */
102
+ export function deliverExclusionReason(relPath, sizeBytes) {
103
+ const byName = deliverExclusionByName(relPath);
104
+ if (byName !== null)
105
+ return byName;
106
+ if (sizeBytes !== null && sizeBytes > OVERSIZE_BYTES)
107
+ return 'oversize-1mib';
108
+ return null;
109
+ }
110
+ //# sourceMappingURL=deliver-exclusions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deliver-exclusions.js","sourceRoot":"","sources":["../../src/core/deliver-exclusions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,gCAAgC,CAAC;AAE1E,4FAA4F;AAC5F,MAAM,UAAU,GAAG;IACjB,OAAO,EAAE,WAAW,EAAE,WAAW;IACjC,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,eAAe,EAAE,eAAe;IACzE,SAAS,EAAE,QAAQ;IACnB,QAAQ,EAAE,SAAS,EAAE,WAAW;IAChC,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ;IACvC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ;IACtC,SAAS,EAAE,aAAa;CACzB,CAAC;AAEF,8EAA8E;AAC9E,MAAM,YAAY,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;AAEtE,4FAA4F;AAC5F,MAAM,CAAC,MAAM,cAAc,GAAG,OAAO,CAAC;AAEtC;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,sBAAsB,CAAC,OAAe;IACpD,yFAAyF;IACzF,IAAI,OAAO,KAAK,yBAAyB;QAAE,OAAO,mBAAmB,CAAC;IACtE,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IACzD,2FAA2F;IAC3F,0CAA0C;IAC1C,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IACjC,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAAE,OAAO,iBAAiB,CAAC;IACtE,IAAI,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAAE,OAAO,aAAa,CAAC;IACnD,sEAAsE;IACtE,IAAI,IAAI,KAAK,WAAW;QAAE,OAAO,UAAU,CAAC;IAC5C,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACpC,gGAAgG;IAChG,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;QAAE,OAAO,aAAa,CAAC;IACtF,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,sBAAsB,CAAC,OAAe,EAAE,SAAwB;IAC9E,MAAM,MAAM,GAAG,sBAAsB,CAAC,OAAO,CAAC,CAAC;IAC/C,IAAI,MAAM,KAAK,IAAI;QAAE,OAAO,MAAM,CAAC;IACnC,IAAI,SAAS,KAAK,IAAI,IAAI,SAAS,GAAG,cAAc;QAAE,OAAO,eAAe,CAAC;IAC7E,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -28,8 +28,14 @@
28
28
  * run either way; only the deliver phase's own commit is guaranteed to match it.
29
29
  */
30
30
  import type { GateSpec, PhaseDef, SessionView } from './types.js';
31
- /** The PR title / commit subject cap — git's conventional subject width. */
32
- export declare const DELIVER_TITLE_MAX = 72;
31
+ /**
32
+ * The PR title cap — GitHub's own limit (crew#550 P-1: a 72-character cap on the PR title still
33
+ * severed the intent inside a quoted phrase). The COMMIT subject keeps git's conventional width,
34
+ * {@link COMMIT_SUBJECT_MAX}; a longer title then opens the commit body in full.
35
+ */
36
+ export declare const DELIVER_TITLE_MAX = 256;
37
+ /** The commit subject cap — git's conventional subject width (crew#550). */
38
+ export declare const COMMIT_SUBJECT_MAX = 72;
33
39
  /** One phase of the run, with as much as is known about it at composition time. */
34
40
  export interface DeliverPhaseFact {
35
41
  id: string;
@@ -89,9 +95,16 @@ export interface DeliverTextFacts {
89
95
  number: number;
90
96
  url: string;
91
97
  } | null;
98
+ /** crew#550: extra git trailers for the commit (`Co-Authored-By: …`), from
99
+ * {@link DELIVER_TRAILERS_ENV}; absent/empty = only the `Delivered-By:` trailer. */
100
+ trailers?: string[];
101
+ /** crew#550 P-7: the follow-ups the evaluator flagged (its `FOLLOW-UPS:` block, read from the
102
+ * evaluator units' output by {@link extractFollowUps}). `[]` = read, none flagged; absent = not
103
+ * read (a definition-time composition), and the section is left out. */
104
+ followUps?: string[];
92
105
  }
93
106
  export interface DeliverText {
94
- /** ≤ {@link DELIVER_TITLE_MAX} characters, one line, never cut mid-word. */
107
+ /** The PR title: ≤ {@link DELIVER_TITLE_MAX} characters, one line, never cut mid-word. */
95
108
  title: string;
96
109
  /** Markdown; never empty. */
97
110
  body: string;
@@ -110,7 +123,7 @@ export interface IssueRefs {
110
123
  export declare function conventionalPrefix(workflowId: string | null | undefined): string;
111
124
  /**
112
125
  * The PR title / commit subject: the intent's first line, whole when it fits, otherwise cut at the
113
- * last word boundary that leaves room for a single `…` — so the result is ≤ 72 characters and never
126
+ * last word boundary that leaves room for a single `…` — so the result is ≤ 256 characters and never
114
127
  * ends mid-word (the F-3R2-014 headline `…scenario CLN-2) aga`). Dangling punctuation before the
115
128
  * ellipsis is dropped. A blank intent names the run instead — through the SAME bounded cut, so a
116
129
  * long caller-supplied session id (the CLI passes `--session` through) is never cut mid-id either
@@ -118,13 +131,19 @@ export declare function conventionalPrefix(workflowId: string | null | undefined
118
131
  */
119
132
  export declare function deliverTitle(intent: string, runId: string, workflowId?: string | null): string;
120
133
  /**
121
- * `line` whole when it fits, else cut at a word boundary with a single `…` — ≤ 72 characters —
134
+ * `line` whole when it fits, else cut at a word boundary with a single `…` — ≤ `max` characters —
122
135
  * choosing the LAST boundary at nesting depth 0: never inside a quoted or bracketed phrase (crew#550
123
136
  * P-1: `… truncated at '(Failed):' and 'sign a seat…`). A straight apostrophe opens a quote only
124
137
  * after a space or at the start (so `daemon's` is a word, not a quote). When no depth-0 boundary
125
138
  * exists inside the room, any word boundary is taken; a single 72+ character token is cut hard.
126
139
  */
127
- export declare function boundedTitle(line: string): string;
140
+ export declare function boundedTitle(line: string, max?: number): string;
141
+ /**
142
+ * The commit subject for a PR title (crew#550): the title itself when it fits git's 72-character
143
+ * subject width, else the same depth-aware word-boundary cut at 72. The deliver script puts the
144
+ * full title at the top of the commit body whenever the two differ.
145
+ */
146
+ export declare function commitSubject(title: string): string;
128
147
  /**
129
148
  * The issues the intent names, split into the ones it says it fixes and the rest.
130
149
  *
@@ -134,7 +153,7 @@ export declare function boundedTitle(line: string): string;
134
153
  * on a wicked-studio delivery must close #214). Any other owner-less `repo#N` rides verbatim as
135
154
  * information; `owner/repo#N` is left exactly as written.
136
155
  */
137
- export declare function issueRefs(intent: string, repoRef?: string | null): IssueRefs;
156
+ export declare function issueRefs(rawIntent: string, repoRef?: string | null): IssueRefs;
138
157
  /**
139
158
  * How much of the intent the deliver SCRIPT carries in its embedded fallback text. The script is
140
159
  * one `bash -lc` argument, and `LaunchSchema.problem` has no length cap, so an unbounded intent
@@ -184,10 +203,9 @@ export declare function baseWorkflowId(workflowId: string, runId: string): strin
184
203
  * The facts from a persisted run view — what the daemon answers on `GET /runs/:id/deliver-text`.
185
204
  * The deliver phase itself (running while it asks) is listed as `this PR`.
186
205
  *
187
- * `resolved.workflowId` is the DEFINITION the route resolved for the run (`resolveRunWorkflow`
188
- * over the full registry): the engine stores an instance id (`wf-<uuid>`) that `sessionsDetail()`
189
- * patches back to a name for BUILT-INS only, so a user-registered workflow would otherwise read as
190
- * `workflow wf-…` here. Absent, the view's id is used (with the per-run composition suffix cut).
206
+ * `resolved.workflowId` is the run's preset or workflow NAME the route resolved from the engine's
207
+ * record (`runIdentityOf`, seam X2) — `null` for a user plan or a free-text run, which names no
208
+ * workflow. Absent (`undefined`), the view's id is used (with the per-run composition suffix cut).
191
209
  */
192
210
  export declare function factsFromRun(view: SessionView, runUrl: string | null, resolved?: {
193
211
  workflowId?: string | null;
@@ -195,6 +213,8 @@ export declare function factsFromRun(view: SessionView, runUrl: string | null, r
195
213
  number: number;
196
214
  url: string;
197
215
  } | null;
216
+ /** crew#550: the evaluator follow-ups, when the caller read the evaluator units' output. */
217
+ followUps?: string[];
198
218
  }): DeliverTextFacts;
199
219
  /** What is known at LAUNCH, from the workflow definition — the script's embedded fallback. */
200
220
  export declare function factsFromWorkflow(input: {
@@ -209,6 +229,22 @@ export declare function factsFromWorkflow(input: {
209
229
  url: string;
210
230
  } | null;
211
231
  }): DeliverTextFacts;
232
+ /**
233
+ * The environment variable naming extra commit trailers for delivered work (crew#550), one per
234
+ * line — e.g. `Co-Authored-By: Name <address>`. Only well-formed single-line `Token: value`
235
+ * trailers are kept; anything else is dropped rather than breaking the commit's trailer block.
236
+ */
237
+ export declare const DELIVER_TRAILERS_ENV = "WICKED_CREW_DELIVER_TRAILERS";
238
+ /** The configured trailers, validated; `[]` when none. */
239
+ export declare function configuredTrailers(env?: NodeJS.ProcessEnv): string[];
240
+ /**
241
+ * The environment variable naming the PUBLIC origin a PR's run link may use (crew#550 P-2) — the
242
+ * studio address a reviewer can open (`https://studio.example.com`). Unset, a PR body names the run
243
+ * id and carries no link: the daemon's own loopback address opens only on the daemon's host.
244
+ */
245
+ export declare const PUBLIC_ORIGIN_ENV = "WICKED_CREW_PUBLIC_ORIGIN";
246
+ /** The configured public origin, or `null`. */
247
+ export declare function configuredPublicOrigin(env?: NodeJS.ProcessEnv): string | null;
212
248
  /**
213
249
  * `s` as ONE URL path segment, RFC 3986 strict: everything but unreserved characters is
214
250
  * percent-encoded — `encodeURIComponent` alone leaves `!'()*` alone, and `'` in particular must not
@@ -216,9 +252,20 @@ export declare function factsFromWorkflow(input: {
216
252
  */
217
253
  export declare function urlPathSegment(s: string): string;
218
254
  /**
219
- * The studio bookmark for a run under a daemon origin (`http://127.0.0.1:7701/runs/<id>`), or
220
- * null. LOOPBACK ORIGINS ONLY (review W3-K4): a daemon bound to a LAN host or IP would otherwise
221
- * put that host into a public PR body; the run id itself is always named in the text.
255
+ * The run link for a PR body under the configured PUBLIC origin ({@link configuredPublicOrigin}),
256
+ * or null (crew#550 P-2). Never a loopback URL: `http://127.0.0.1:<port>/runs/<id>` opens only on
257
+ * the daemon's own host, so a PR carrying it gave every other reader a dead link. A loopback,
258
+ * unparseable or non-http(s) origin yields no link; the run id itself is always named in the text.
222
259
  */
223
260
  export declare function runUrlFor(origin: string | null | undefined, runId: string): string | null;
261
+ /** At most this many follow-ups ride a PR body; each is cut to {@link FOLLOW_UP_MAX_CHARS}. */
262
+ export declare const FOLLOW_UPS_MAX = 10;
263
+ export declare const FOLLOW_UP_MAX_CHARS = 300;
264
+ /**
265
+ * The follow-ups an evaluator's output flags (crew#550 P-7): the list under its `FOLLOW-UPS:`
266
+ * heading (or the heading line's own text), ending at the first line that is neither an item nor
267
+ * the continuation of one. `none` / `n/a` yields nothing. Every block in the text is read, in order,
268
+ * de-duplicated, capped at {@link FOLLOW_UPS_MAX}.
269
+ */
270
+ export declare function extractFollowUps(text: string): string[];
224
271
  //# sourceMappingURL=deliver-text.d.ts.map