spexcode 0.6.2 → 0.6.6

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 (495) hide show
  1. package/README.md +3 -1
  2. package/bin/spex.mjs +4 -0
  3. package/node_modules/@spexcode/session-core/dist/delivery-queue.d.ts +23 -0
  4. package/node_modules/@spexcode/session-core/dist/delivery-queue.js +195 -0
  5. package/node_modules/@spexcode/session-core/dist/index.d.ts +5 -0
  6. package/node_modules/@spexcode/session-core/dist/index.js +5 -0
  7. package/node_modules/@spexcode/session-core/dist/internal.d.ts +3 -0
  8. package/node_modules/@spexcode/session-core/dist/internal.js +3 -0
  9. package/node_modules/@spexcode/session-core/dist/message.d.ts +22 -0
  10. package/node_modules/@spexcode/session-core/dist/message.js +52 -0
  11. package/node_modules/@spexcode/session-core/dist/record-lock.d.ts +7 -0
  12. package/node_modules/@spexcode/session-core/dist/record-lock.js +152 -0
  13. package/node_modules/@spexcode/session-core/dist/runtime-session.d.ts +50 -0
  14. package/node_modules/@spexcode/session-core/dist/runtime-session.js +286 -0
  15. package/node_modules/@spexcode/session-core/dist/session-cursors.d.ts +14 -0
  16. package/node_modules/@spexcode/session-core/dist/session-cursors.js +82 -0
  17. package/node_modules/@spexcode/session-core/dist/session-timeline.d.ts +46 -0
  18. package/node_modules/@spexcode/session-core/dist/session-timeline.js +216 -0
  19. package/node_modules/@spexcode/session-core/package.json +33 -0
  20. package/node_modules/@spexcode/spec-cli/bin/spex.mjs +77 -0
  21. package/node_modules/@spexcode/spec-cli/dist/attach.d.ts +2 -0
  22. package/node_modules/@spexcode/spec-cli/dist/attach.js +48 -0
  23. package/node_modules/@spexcode/spec-cli/dist/claude-headless.d.ts +36 -0
  24. package/node_modules/@spexcode/spec-cli/dist/claude-headless.js +316 -0
  25. package/node_modules/@spexcode/spec-cli/dist/cli.d.ts +1 -0
  26. package/node_modules/@spexcode/spec-cli/dist/cli.js +1908 -0
  27. package/node_modules/@spexcode/spec-cli/dist/client.d.ts +112 -0
  28. package/node_modules/@spexcode/spec-cli/dist/client.js +481 -0
  29. package/node_modules/@spexcode/spec-cli/dist/cockpit.d.ts +7 -0
  30. package/node_modules/@spexcode/spec-cli/dist/cockpit.js +26 -0
  31. package/node_modules/@spexcode/spec-cli/dist/codex-headless.d.ts +1 -0
  32. package/{spec-cli/src/codex-headless.ts → node_modules/@spexcode/spec-cli/dist/codex-headless.js} +3 -9
  33. package/node_modules/@spexcode/spec-cli/dist/codex-runtime-generations.d.ts +58 -0
  34. package/node_modules/@spexcode/spec-cli/dist/codex-runtime-generations.js +798 -0
  35. package/node_modules/@spexcode/spec-cli/dist/commit-surgery.d.ts +1 -0
  36. package/node_modules/@spexcode/spec-cli/dist/commit-surgery.js +90 -0
  37. package/node_modules/@spexcode/spec-cli/dist/contract-filter.d.ts +14 -0
  38. package/node_modules/@spexcode/spec-cli/dist/contract-filter.js +219 -0
  39. package/node_modules/@spexcode/spec-cli/dist/dashboard-assets.d.ts +6 -0
  40. package/node_modules/@spexcode/spec-cli/dist/dashboard-assets.js +50 -0
  41. package/node_modules/@spexcode/spec-cli/dist/doctor.d.ts +9 -0
  42. package/node_modules/@spexcode/spec-cli/dist/doctor.js +553 -0
  43. package/node_modules/@spexcode/spec-cli/dist/eval-host.d.ts +1 -0
  44. package/node_modules/@spexcode/spec-cli/dist/eval-host.js +19 -0
  45. package/node_modules/@spexcode/spec-cli/dist/execution-trace.d.ts +26 -0
  46. package/node_modules/@spexcode/spec-cli/dist/execution-trace.js +475 -0
  47. package/node_modules/@spexcode/spec-cli/dist/file-write.d.ts +2 -0
  48. package/node_modules/@spexcode/spec-cli/dist/file-write.js +26 -0
  49. package/node_modules/@spexcode/spec-cli/dist/flat.d.ts +89 -0
  50. package/node_modules/@spexcode/spec-cli/dist/flat.js +1076 -0
  51. package/node_modules/@spexcode/spec-cli/dist/gateway-auth.d.ts +56 -0
  52. package/node_modules/@spexcode/spec-cli/dist/gateway-auth.js +168 -0
  53. package/node_modules/@spexcode/spec-cli/dist/gateway-hub.d.ts +28 -0
  54. package/node_modules/@spexcode/spec-cli/dist/gateway-hub.js +363 -0
  55. package/node_modules/@spexcode/spec-cli/dist/gateway.d.ts +38 -0
  56. package/node_modules/@spexcode/spec-cli/dist/gateway.js +527 -0
  57. package/node_modules/@spexcode/spec-cli/dist/graphCache.d.ts +27 -0
  58. package/node_modules/@spexcode/spec-cli/dist/graphCache.js +717 -0
  59. package/node_modules/@spexcode/spec-cli/dist/graphSnapshot.d.ts +14 -0
  60. package/node_modules/@spexcode/spec-cli/dist/graphSnapshot.js +36 -0
  61. package/node_modules/@spexcode/spec-cli/dist/graphStream.d.ts +85 -0
  62. package/node_modules/@spexcode/spec-cli/dist/graphStream.js +1195 -0
  63. package/node_modules/@spexcode/spec-cli/dist/guidance-catalog.d.ts +64 -0
  64. package/node_modules/@spexcode/spec-cli/dist/guidance-catalog.js +166 -0
  65. package/node_modules/@spexcode/spec-cli/dist/guide.d.ts +8 -0
  66. package/{spec-cli/src/guide.ts → node_modules/@spexcode/spec-cli/dist/guide.js} +36 -32
  67. package/node_modules/@spexcode/spec-cli/dist/harness-select.d.ts +18 -0
  68. package/node_modules/@spexcode/spec-cli/dist/harness-select.js +62 -0
  69. package/node_modules/@spexcode/spec-cli/dist/harness.d.ts +338 -0
  70. package/node_modules/@spexcode/spec-cli/dist/harness.js +3146 -0
  71. package/node_modules/@spexcode/spec-cli/dist/headless-controller.d.ts +9 -0
  72. package/node_modules/@spexcode/spec-cli/dist/headless-controller.js +47 -0
  73. package/node_modules/@spexcode/spec-cli/dist/help.d.ts +15 -0
  74. package/node_modules/@spexcode/spec-cli/dist/help.js +594 -0
  75. package/node_modules/@spexcode/spec-cli/dist/hook-prompts.d.ts +18 -0
  76. package/node_modules/@spexcode/spec-cli/dist/hook-prompts.js +122 -0
  77. package/node_modules/@spexcode/spec-cli/dist/hooks.d.ts +1 -0
  78. package/{spec-cli/src/hooks.ts → node_modules/@spexcode/spec-cli/dist/hooks.js} +15 -15
  79. package/node_modules/@spexcode/spec-cli/dist/host-resources.d.ts +97 -0
  80. package/node_modules/@spexcode/spec-cli/dist/host-resources.js +795 -0
  81. package/node_modules/@spexcode/spec-cli/dist/host.d.ts +88 -0
  82. package/node_modules/@spexcode/spec-cli/dist/host.js +663 -0
  83. package/node_modules/@spexcode/spec-cli/dist/index.d.ts +1 -0
  84. package/node_modules/@spexcode/spec-cli/dist/index.js +899 -0
  85. package/node_modules/@spexcode/spec-cli/dist/init.d.ts +1 -0
  86. package/node_modules/@spexcode/spec-cli/dist/init.js +284 -0
  87. package/node_modules/@spexcode/spec-cli/dist/issues-cli.d.ts +6 -0
  88. package/node_modules/@spexcode/spec-cli/dist/issues-cli.js +334 -0
  89. package/node_modules/@spexcode/spec-cli/dist/issues.d.ts +69 -0
  90. package/node_modules/@spexcode/spec-cli/dist/issues.js +189 -0
  91. package/node_modules/@spexcode/spec-cli/dist/lint.d.ts +34 -0
  92. package/node_modules/@spexcode/spec-cli/dist/lint.js +476 -0
  93. package/node_modules/@spexcode/spec-cli/dist/listen.d.ts +8 -0
  94. package/node_modules/@spexcode/spec-cli/dist/listen.js +24 -0
  95. package/node_modules/@spexcode/spec-cli/dist/localIssues.d.ts +65 -0
  96. package/node_modules/@spexcode/spec-cli/dist/localIssues.js +582 -0
  97. package/node_modules/@spexcode/spec-cli/dist/login-page.d.ts +5 -0
  98. package/{spec-cli/src/login-page.ts → node_modules/@spexcode/spec-cli/dist/login-page.js} +7 -7
  99. package/node_modules/@spexcode/spec-cli/dist/loop-in.d.ts +23 -0
  100. package/{spec-cli/src/loop-in.ts → node_modules/@spexcode/spec-cli/dist/loop-in.js} +35 -45
  101. package/node_modules/@spexcode/spec-cli/dist/machine-peer.d.ts +69 -0
  102. package/node_modules/@spexcode/spec-cli/dist/machine-peer.js +603 -0
  103. package/node_modules/@spexcode/spec-cli/dist/materialize.d.ts +18 -0
  104. package/node_modules/@spexcode/spec-cli/dist/materialize.js +468 -0
  105. package/node_modules/@spexcode/spec-cli/dist/mentions.d.ts +50 -0
  106. package/node_modules/@spexcode/spec-cli/dist/mentions.js +117 -0
  107. package/node_modules/@spexcode/spec-cli/dist/opencode-headless.d.ts +5 -0
  108. package/node_modules/@spexcode/spec-cli/dist/opencode-headless.js +215 -0
  109. package/node_modules/@spexcode/spec-cli/dist/opencode.d.ts +3 -0
  110. package/{spec-cli/src/opencode.ts → node_modules/@spexcode/spec-cli/dist/opencode.js} +9 -13
  111. package/node_modules/@spexcode/spec-cli/dist/pi-harness.d.ts +3 -0
  112. package/{spec-cli/src/pi-harness.ts → node_modules/@spexcode/spec-cli/dist/pi-harness.js} +45 -40
  113. package/node_modules/@spexcode/spec-cli/dist/pi-headless.d.ts +25 -0
  114. package/node_modules/@spexcode/spec-cli/dist/pi-headless.js +196 -0
  115. package/node_modules/@spexcode/spec-cli/dist/plugin-harness.d.ts +21 -0
  116. package/node_modules/@spexcode/spec-cli/dist/plugin-harness.js +146 -0
  117. package/node_modules/@spexcode/spec-cli/dist/pty-bridge.d.ts +10 -0
  118. package/node_modules/@spexcode/spec-cli/dist/pty-bridge.js +404 -0
  119. package/node_modules/@spexcode/spec-cli/dist/pty-helper.d.mts +1 -0
  120. package/node_modules/@spexcode/spec-cli/dist/pty-helper.mjs +101 -0
  121. package/node_modules/@spexcode/spec-cli/dist/pty-native-helper.d.mts +2 -0
  122. package/node_modules/@spexcode/spec-cli/dist/pty-native-helper.mjs +23 -0
  123. package/node_modules/@spexcode/spec-cli/dist/public-graph.d.ts +46 -0
  124. package/node_modules/@spexcode/spec-cli/dist/public-graph.js +56 -0
  125. package/node_modules/@spexcode/spec-cli/dist/ranker.d.ts +15 -0
  126. package/node_modules/@spexcode/spec-cli/dist/ranker.js +188 -0
  127. package/node_modules/@spexcode/spec-cli/dist/reaper.d.ts +6 -0
  128. package/node_modules/@spexcode/spec-cli/dist/reaper.js +81 -0
  129. package/node_modules/@spexcode/spec-cli/dist/reviews.d.ts +189 -0
  130. package/node_modules/@spexcode/spec-cli/dist/reviews.js +350 -0
  131. package/node_modules/@spexcode/spec-cli/dist/runtime-guard.d.ts +6 -0
  132. package/node_modules/@spexcode/spec-cli/dist/runtime-guard.js +37 -0
  133. package/node_modules/@spexcode/spec-cli/dist/runtime-ownership.d.ts +21 -0
  134. package/node_modules/@spexcode/spec-cli/dist/runtime-ownership.js +84 -0
  135. package/node_modules/@spexcode/spec-cli/dist/runtime-rotate.d.ts +1 -0
  136. package/node_modules/@spexcode/spec-cli/dist/runtime-rotate.js +58 -0
  137. package/node_modules/@spexcode/spec-cli/dist/search.bench.d.mts +1 -0
  138. package/node_modules/@spexcode/spec-cli/dist/search.bench.mjs +75 -0
  139. package/node_modules/@spexcode/spec-cli/dist/search.d.ts +20 -0
  140. package/node_modules/@spexcode/spec-cli/dist/search.js +61 -0
  141. package/node_modules/@spexcode/spec-cli/dist/session-declarations.d.ts +13 -0
  142. package/node_modules/@spexcode/spec-cli/dist/session-declarations.js +126 -0
  143. package/node_modules/@spexcode/spec-cli/dist/session-execution.d.ts +10 -0
  144. package/node_modules/@spexcode/spec-cli/dist/session-execution.js +70 -0
  145. package/node_modules/@spexcode/spec-cli/dist/session-files.d.ts +28 -0
  146. package/node_modules/@spexcode/spec-cli/dist/session-files.js +130 -0
  147. package/node_modules/@spexcode/spec-cli/dist/session-follow.d.ts +31 -0
  148. package/node_modules/@spexcode/spec-cli/dist/session-follow.js +179 -0
  149. package/node_modules/@spexcode/spec-cli/dist/session-reparent.d.ts +10 -0
  150. package/node_modules/@spexcode/spec-cli/dist/session-reparent.js +33 -0
  151. package/node_modules/@spexcode/spec-cli/dist/session-timeline.d.ts +11 -0
  152. package/node_modules/@spexcode/spec-cli/dist/session-timeline.js +20 -0
  153. package/node_modules/@spexcode/spec-cli/dist/session-web.d.ts +24 -0
  154. package/node_modules/@spexcode/spec-cli/dist/session-web.js +141 -0
  155. package/node_modules/@spexcode/spec-cli/dist/sessions.d.ts +433 -0
  156. package/node_modules/@spexcode/spec-cli/dist/sessions.js +4667 -0
  157. package/node_modules/@spexcode/spec-cli/dist/sh.d.ts +1 -0
  158. package/node_modules/@spexcode/spec-cli/dist/sh.js +3 -0
  159. package/node_modules/@spexcode/spec-cli/dist/shim-runtime.d.ts +1 -0
  160. package/{spec-cli/src/shim-runtime.ts → node_modules/@spexcode/spec-cli/dist/shim-runtime.js} +3 -4
  161. package/node_modules/@spexcode/spec-cli/dist/slash-commands.d.ts +9 -0
  162. package/node_modules/@spexcode/spec-cli/dist/slash-commands.js +307 -0
  163. package/node_modules/@spexcode/spec-cli/dist/source-files.d.ts +9 -0
  164. package/node_modules/@spexcode/spec-cli/dist/source-files.js +113 -0
  165. package/node_modules/@spexcode/spec-cli/dist/supervise.d.ts +1 -0
  166. package/node_modules/@spexcode/spec-cli/dist/supervise.js +308 -0
  167. package/node_modules/@spexcode/spec-cli/dist/tree.d.ts +25 -0
  168. package/node_modules/@spexcode/spec-cli/dist/tree.js +98 -0
  169. package/node_modules/@spexcode/spec-cli/dist/tsx-bin.d.ts +3 -0
  170. package/node_modules/@spexcode/spec-cli/dist/tsx-bin.js +41 -0
  171. package/node_modules/@spexcode/spec-cli/dist/uninstall.d.ts +3 -0
  172. package/node_modules/@spexcode/spec-cli/dist/uninstall.js +177 -0
  173. package/node_modules/@spexcode/spec-cli/dist/uploads.d.ts +36 -0
  174. package/node_modules/@spexcode/spec-cli/dist/uploads.js +243 -0
  175. package/node_modules/@spexcode/spec-cli/dist/worktree-sources.d.ts +1 -0
  176. package/node_modules/@spexcode/spec-cli/dist/worktree-sources.js +47 -0
  177. package/{spec-cli → node_modules/@spexcode/spec-cli}/hooks/dispatch.sh +5 -5
  178. package/{spec-cli → node_modules/@spexcode/spec-cli}/hooks/harness.sh +1 -1
  179. package/node_modules/@spexcode/spec-cli/package.json +49 -0
  180. package/node_modules/@spexcode/spec-cli/templates/spec/project/.plugins/commands/supervisor/spec.md +8 -0
  181. package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/spec-first/spec-first.sh +1 -1
  182. package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/spec-of-file/spec-of-file.sh +1 -0
  183. package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/stop-gate/spec.md +2 -2
  184. package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/stop-gate/stop-gate.sh +31 -29
  185. package/node_modules/@spexcode/spec-core/dist/anchors.d.ts +94 -0
  186. package/node_modules/@spexcode/spec-core/dist/anchors.js +730 -0
  187. package/node_modules/@spexcode/spec-core/dist/git.d.ts +170 -0
  188. package/node_modules/@spexcode/spec-core/dist/git.js +2768 -0
  189. package/node_modules/@spexcode/spec-core/dist/graph-delta.d.ts +44 -0
  190. package/node_modules/@spexcode/spec-core/dist/graph-delta.js +72 -0
  191. package/node_modules/@spexcode/spec-core/dist/graph.d.ts +34 -0
  192. package/node_modules/@spexcode/spec-core/dist/graph.js +237 -0
  193. package/node_modules/@spexcode/spec-core/dist/graphDelta.d.ts +3 -0
  194. package/node_modules/@spexcode/spec-core/dist/graphDelta.js +13 -0
  195. package/node_modules/@spexcode/spec-core/dist/harness-identity.d.ts +31 -0
  196. package/node_modules/@spexcode/spec-core/dist/harness-identity.js +20 -0
  197. package/node_modules/@spexcode/spec-core/dist/identity-presets.d.ts +152 -0
  198. package/node_modules/@spexcode/spec-core/dist/identity-presets.js +132 -0
  199. package/node_modules/@spexcode/spec-core/dist/index.d.ts +45 -0
  200. package/node_modules/@spexcode/spec-core/dist/index.js +19 -0
  201. package/node_modules/@spexcode/spec-core/dist/layout.d.ts +187 -0
  202. package/node_modules/@spexcode/spec-core/dist/layout.js +548 -0
  203. package/node_modules/@spexcode/spec-core/dist/process-identity.d.ts +37 -0
  204. package/node_modules/@spexcode/spec-core/dist/process-identity.js +214 -0
  205. package/node_modules/@spexcode/spec-core/dist/project-identity.d.ts +12 -0
  206. package/node_modules/@spexcode/spec-core/dist/project-identity.js +71 -0
  207. package/node_modules/@spexcode/spec-core/dist/project-store.d.ts +3 -0
  208. package/node_modules/@spexcode/spec-core/dist/project-store.js +14 -0
  209. package/node_modules/@spexcode/spec-core/dist/resilience.d.ts +2 -0
  210. package/node_modules/@spexcode/spec-core/dist/resilience.js +40 -0
  211. package/node_modules/@spexcode/spec-core/dist/review/index.d.ts +3 -0
  212. package/node_modules/@spexcode/spec-core/dist/review/index.js +5 -0
  213. package/node_modules/@spexcode/spec-core/dist/review/reviewFilters.d.ts +77 -0
  214. package/node_modules/@spexcode/spec-core/dist/review/reviewFilters.js +308 -0
  215. package/node_modules/@spexcode/spec-core/dist/review/reviewQuery.d.ts +66 -0
  216. package/node_modules/@spexcode/spec-core/dist/review/reviewQuery.js +180 -0
  217. package/node_modules/@spexcode/spec-core/dist/review/session.d.ts +4 -0
  218. package/node_modules/@spexcode/spec-core/dist/review/session.js +8 -0
  219. package/node_modules/@spexcode/spec-core/dist/reviewSnapshot.d.ts +15 -0
  220. package/node_modules/@spexcode/spec-core/dist/reviewSnapshot.js +12 -0
  221. package/node_modules/@spexcode/spec-core/dist/root-lru.d.ts +4 -0
  222. package/{spec-cli/src/root-lru.ts → node_modules/@spexcode/spec-core/dist/root-lru.js} +26 -30
  223. package/node_modules/@spexcode/spec-core/dist/specs.d.ts +117 -0
  224. package/node_modules/@spexcode/spec-core/dist/specs.js +489 -0
  225. package/node_modules/@spexcode/spec-core/package.json +28 -0
  226. package/node_modules/@spexcode/spec-eval/dist/cache.d.ts +10 -0
  227. package/node_modules/@spexcode/spec-eval/dist/cache.js +50 -0
  228. package/node_modules/@spexcode/spec-eval/dist/cli.d.ts +22 -0
  229. package/node_modules/@spexcode/spec-eval/dist/cli.js +981 -0
  230. package/node_modules/@spexcode/spec-eval/dist/evaltab.d.ts +98 -0
  231. package/node_modules/@spexcode/spec-eval/dist/evaltab.js +176 -0
  232. package/node_modules/@spexcode/spec-eval/dist/filing.d.ts +16 -0
  233. package/node_modules/@spexcode/spec-eval/dist/filing.js +36 -0
  234. package/node_modules/@spexcode/spec-eval/dist/freshness.d.ts +48 -0
  235. package/node_modules/@spexcode/spec-eval/dist/freshness.js +799 -0
  236. package/node_modules/@spexcode/spec-eval/dist/host.d.ts +46 -0
  237. package/node_modules/@spexcode/spec-eval/dist/host.js +53 -0
  238. package/node_modules/@spexcode/spec-eval/dist/humanok.d.ts +11 -0
  239. package/node_modules/@spexcode/spec-eval/dist/humanok.js +27 -0
  240. package/node_modules/@spexcode/spec-eval/dist/index.d.ts +4 -0
  241. package/node_modules/@spexcode/spec-eval/dist/index.js +4 -0
  242. package/node_modules/@spexcode/spec-eval/dist/remarks.d.ts +31 -0
  243. package/node_modules/@spexcode/spec-eval/dist/remarks.js +1 -0
  244. package/node_modules/@spexcode/spec-eval/dist/scenariofresh.d.ts +13 -0
  245. package/node_modules/@spexcode/spec-eval/dist/scenariofresh.js +303 -0
  246. package/node_modules/@spexcode/spec-eval/dist/scenarios.d.ts +99 -0
  247. package/node_modules/@spexcode/spec-eval/dist/scenarios.js +650 -0
  248. package/node_modules/@spexcode/spec-eval/dist/sessioneval.d.ts +307 -0
  249. package/node_modules/@spexcode/spec-eval/dist/sessioneval.js +1883 -0
  250. package/node_modules/@spexcode/spec-eval/dist/sidecar.d.ts +55 -0
  251. package/node_modules/@spexcode/spec-eval/dist/sidecar.js +82 -0
  252. package/node_modules/@spexcode/spec-eval/dist/timeline.d.ts +25 -0
  253. package/node_modules/@spexcode/spec-eval/dist/timeline.js +65 -0
  254. package/node_modules/@spexcode/spec-eval/dist/ui-path.d.ts +1 -0
  255. package/node_modules/@spexcode/spec-eval/dist/ui-path.js +2 -0
  256. package/node_modules/@spexcode/spec-eval/package.json +36 -0
  257. package/node_modules/@spexcode/spec-forge/dist/cache.d.ts +29 -0
  258. package/node_modules/@spexcode/spec-forge/dist/cache.js +59 -0
  259. package/node_modules/@spexcode/spec-forge/dist/cli.d.ts +1 -0
  260. package/node_modules/@spexcode/spec-forge/dist/cli.js +100 -0
  261. package/node_modules/@spexcode/spec-forge/dist/drivers/github.d.ts +2 -0
  262. package/node_modules/@spexcode/spec-forge/dist/drivers/github.js +116 -0
  263. package/node_modules/@spexcode/spec-forge/dist/drivers/gitlab.d.ts +7 -0
  264. package/node_modules/@spexcode/spec-forge/dist/drivers/gitlab.js +144 -0
  265. package/node_modules/@spexcode/spec-forge/dist/drivers.d.ts +10 -0
  266. package/node_modules/@spexcode/spec-forge/dist/drivers.js +83 -0
  267. package/node_modules/@spexcode/spec-forge/dist/index.d.ts +4 -0
  268. package/node_modules/@spexcode/spec-forge/dist/index.js +4 -0
  269. package/node_modules/@spexcode/spec-forge/dist/links.d.ts +15 -0
  270. package/node_modules/@spexcode/spec-forge/dist/links.js +65 -0
  271. package/node_modules/@spexcode/spec-forge/dist/needs-eval.d.ts +10 -0
  272. package/node_modules/@spexcode/spec-forge/dist/needs-eval.js +20 -0
  273. package/node_modules/@spexcode/spec-forge/dist/port.d.ts +53 -0
  274. package/node_modules/@spexcode/spec-forge/dist/port.js +1 -0
  275. package/node_modules/@spexcode/spec-forge/dist/resident.d.ts +7 -0
  276. package/node_modules/@spexcode/spec-forge/dist/resident.js +43 -0
  277. package/node_modules/@spexcode/spec-forge/package.json +32 -0
  278. package/package.json +33 -19
  279. package/spec-cli/bin/spex.mjs +0 -69
  280. package/spec-cli/src/anchors.ts +0 -728
  281. package/spec-cli/src/attach.ts +0 -43
  282. package/spec-cli/src/claude-headless.ts +0 -321
  283. package/spec-cli/src/cli.ts +0 -1258
  284. package/spec-cli/src/client.ts +0 -414
  285. package/spec-cli/src/cockpit.ts +0 -43
  286. package/spec-cli/src/codex-runtime-generations.ts +0 -646
  287. package/spec-cli/src/commit-surgery.ts +0 -68
  288. package/spec-cli/src/contract-filter.ts +0 -202
  289. package/spec-cli/src/delivery-queue.ts +0 -165
  290. package/spec-cli/src/doctor.ts +0 -516
  291. package/spec-cli/src/execution-trace.ts +0 -444
  292. package/spec-cli/src/file-write.ts +0 -22
  293. package/spec-cli/src/gateway-auth.ts +0 -181
  294. package/spec-cli/src/gateway-hub.ts +0 -358
  295. package/spec-cli/src/gateway.ts +0 -461
  296. package/spec-cli/src/git.ts +0 -2556
  297. package/spec-cli/src/graph.ts +0 -271
  298. package/spec-cli/src/graphCache.ts +0 -710
  299. package/spec-cli/src/graphDelta.ts +0 -77
  300. package/spec-cli/src/graphStream.ts +0 -1019
  301. package/spec-cli/src/harness-select.ts +0 -77
  302. package/spec-cli/src/harness.ts +0 -3025
  303. package/spec-cli/src/headless-controller.ts +0 -63
  304. package/spec-cli/src/help.ts +0 -492
  305. package/spec-cli/src/host-resources.ts +0 -762
  306. package/spec-cli/src/host.ts +0 -611
  307. package/spec-cli/src/identity-presets.d.ts +0 -13
  308. package/spec-cli/src/identity-presets.js +0 -138
  309. package/spec-cli/src/index.ts +0 -818
  310. package/spec-cli/src/init.ts +0 -258
  311. package/spec-cli/src/issues-cli.ts +0 -276
  312. package/spec-cli/src/issues.ts +0 -237
  313. package/spec-cli/src/layout.ts +0 -640
  314. package/spec-cli/src/lint.ts +0 -488
  315. package/spec-cli/src/listen.ts +0 -28
  316. package/spec-cli/src/localIssues.ts +0 -538
  317. package/spec-cli/src/materialize.ts +0 -417
  318. package/spec-cli/src/mentions.ts +0 -81
  319. package/spec-cli/src/opencode-headless.ts +0 -205
  320. package/spec-cli/src/pi-headless.ts +0 -153
  321. package/spec-cli/src/plugin-harness.ts +0 -157
  322. package/spec-cli/src/process-identity.ts +0 -207
  323. package/spec-cli/src/project-identity.ts +0 -73
  324. package/spec-cli/src/project-store.ts +0 -17
  325. package/spec-cli/src/pty-bridge.ts +0 -396
  326. package/spec-cli/src/pty-helper.mjs +0 -96
  327. package/spec-cli/src/pty-native-helper.mjs +0 -22
  328. package/spec-cli/src/ranker.ts +0 -191
  329. package/spec-cli/src/reaper.ts +0 -125
  330. package/spec-cli/src/resilience.ts +0 -41
  331. package/spec-cli/src/reviewSnapshot.ts +0 -28
  332. package/spec-cli/src/reviews.ts +0 -434
  333. package/spec-cli/src/runtime-guard.ts +0 -35
  334. package/spec-cli/src/runtime-ownership.ts +0 -88
  335. package/spec-cli/src/search.bench.mjs +0 -80
  336. package/spec-cli/src/search.ts +0 -63
  337. package/spec-cli/src/session-cursors.ts +0 -91
  338. package/spec-cli/src/session-execution.ts +0 -68
  339. package/spec-cli/src/session-files.ts +0 -121
  340. package/spec-cli/src/session-follow.ts +0 -182
  341. package/spec-cli/src/session-reparent.ts +0 -33
  342. package/spec-cli/src/session-timeline.ts +0 -247
  343. package/spec-cli/src/session-web.ts +0 -135
  344. package/spec-cli/src/sessions.ts +0 -3883
  345. package/spec-cli/src/sh.ts +0 -3
  346. package/spec-cli/src/slash-commands.ts +0 -318
  347. package/spec-cli/src/source-files.ts +0 -104
  348. package/spec-cli/src/specs.ts +0 -498
  349. package/spec-cli/src/supervise.ts +0 -245
  350. package/spec-cli/src/tree.ts +0 -118
  351. package/spec-cli/src/tsx-bin.ts +0 -18
  352. package/spec-cli/src/uninstall.ts +0 -171
  353. package/spec-cli/src/uploads.ts +0 -253
  354. package/spec-cli/src/worktree-sources.ts +0 -42
  355. package/spec-cli/templates/spec/project/.plugins/commands/supervisor/spec.md +0 -8
  356. package/spec-dashboard/dist/assets/App-B6IbFbGu.js +0 -2
  357. package/spec-dashboard/dist/assets/Dashboard-C5ap-Sga.css +0 -1
  358. package/spec-dashboard/dist/assets/Dashboard-_sDk7Rcg.js +0 -27
  359. package/spec-dashboard/dist/assets/EvalsPage-BT357Lyt.js +0 -2
  360. package/spec-dashboard/dist/assets/IssuesPage-BG9rNOgV.js +0 -1
  361. package/spec-dashboard/dist/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  362. package/spec-dashboard/dist/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
  363. package/spec-dashboard/dist/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
  364. package/spec-dashboard/dist/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
  365. package/spec-dashboard/dist/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
  366. package/spec-dashboard/dist/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  367. package/spec-dashboard/dist/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
  368. package/spec-dashboard/dist/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  369. package/spec-dashboard/dist/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
  370. package/spec-dashboard/dist/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
  371. package/spec-dashboard/dist/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
  372. package/spec-dashboard/dist/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  373. package/spec-dashboard/dist/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
  374. package/spec-dashboard/dist/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  375. package/spec-dashboard/dist/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
  376. package/spec-dashboard/dist/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  377. package/spec-dashboard/dist/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
  378. package/spec-dashboard/dist/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
  379. package/spec-dashboard/dist/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  380. package/spec-dashboard/dist/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
  381. package/spec-dashboard/dist/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
  382. package/spec-dashboard/dist/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
  383. package/spec-dashboard/dist/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
  384. package/spec-dashboard/dist/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  385. package/spec-dashboard/dist/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  386. package/spec-dashboard/dist/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
  387. package/spec-dashboard/dist/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
  388. package/spec-dashboard/dist/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
  389. package/spec-dashboard/dist/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  390. package/spec-dashboard/dist/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
  391. package/spec-dashboard/dist/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
  392. package/spec-dashboard/dist/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
  393. package/spec-dashboard/dist/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  394. package/spec-dashboard/dist/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
  395. package/spec-dashboard/dist/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  396. package/spec-dashboard/dist/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
  397. package/spec-dashboard/dist/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  398. package/spec-dashboard/dist/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
  399. package/spec-dashboard/dist/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
  400. package/spec-dashboard/dist/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
  401. package/spec-dashboard/dist/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
  402. package/spec-dashboard/dist/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  403. package/spec-dashboard/dist/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
  404. package/spec-dashboard/dist/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  405. package/spec-dashboard/dist/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
  406. package/spec-dashboard/dist/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
  407. package/spec-dashboard/dist/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
  408. package/spec-dashboard/dist/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  409. package/spec-dashboard/dist/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
  410. package/spec-dashboard/dist/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  411. package/spec-dashboard/dist/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
  412. package/spec-dashboard/dist/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
  413. package/spec-dashboard/dist/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
  414. package/spec-dashboard/dist/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
  415. package/spec-dashboard/dist/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
  416. package/spec-dashboard/dist/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  417. package/spec-dashboard/dist/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
  418. package/spec-dashboard/dist/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  419. package/spec-dashboard/dist/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
  420. package/spec-dashboard/dist/assets/MobileApp-D9yPMR3A.js +0 -2
  421. package/spec-dashboard/dist/assets/Modal-B3EcgeA3.js +0 -1
  422. package/spec-dashboard/dist/assets/PageScroll-CNZOugWV.js +0 -1
  423. package/spec-dashboard/dist/assets/ProjectsPage-C2CRHmvs.js +0 -1
  424. package/spec-dashboard/dist/assets/SessionInterface-6GBZ9nXN.css +0 -32
  425. package/spec-dashboard/dist/assets/SessionInterface-DOEjuT3l.js +0 -40
  426. package/spec-dashboard/dist/assets/SessionWindow-1nYgZ4CL.js +0 -1
  427. package/spec-dashboard/dist/assets/Settings-7WeTJn0V.js +0 -1
  428. package/spec-dashboard/dist/assets/Thread-CEbzAFQn.js +0 -13
  429. package/spec-dashboard/dist/assets/bindings-BC9vqpYU.js +0 -1
  430. package/spec-dashboard/dist/assets/data-SlvxNA2r.js +0 -1
  431. package/spec-dashboard/dist/assets/index-DLVeOHL-.js +0 -41
  432. package/spec-dashboard/dist/assets/index-DYLGfPjx.css +0 -1
  433. package/spec-dashboard/dist/assets/launch-Cp579UoJ.css +0 -1
  434. package/spec-dashboard/dist/assets/launch-yxCYr64x.js +0 -276
  435. package/spec-dashboard/dist/assets/sessionSurface--7l69h4F.js +0 -1
  436. package/spec-dashboard/dist/index.html +0 -29
  437. package/spec-dashboard/src/reviewFilters.js +0 -322
  438. package/spec-dashboard/src/reviewQuery.js +0 -174
  439. package/spec-dashboard/src/session.js +0 -199
  440. package/spec-eval/src/cache.ts +0 -57
  441. package/spec-eval/src/cli.ts +0 -894
  442. package/spec-eval/src/evaltab.ts +0 -264
  443. package/spec-eval/src/filing.ts +0 -39
  444. package/spec-eval/src/freshness.ts +0 -836
  445. package/spec-eval/src/humanok.ts +0 -28
  446. package/spec-eval/src/scenariofresh.ts +0 -244
  447. package/spec-eval/src/scenarios.ts +0 -672
  448. package/spec-eval/src/sessioneval.ts +0 -2220
  449. package/spec-eval/src/sidecar.ts +0 -93
  450. package/spec-eval/src/timeline.ts +0 -54
  451. package/spec-forge/src/__fixtures__/github-forge.json +0 -63
  452. package/spec-forge/src/cache.ts +0 -66
  453. package/spec-forge/src/cli.ts +0 -99
  454. package/spec-forge/src/drivers/github.ts +0 -132
  455. package/spec-forge/src/drivers/gitlab.ts +0 -153
  456. package/spec-forge/src/drivers.ts +0 -73
  457. package/spec-forge/src/links.ts +0 -72
  458. package/spec-forge/src/needs-eval.ts +0 -29
  459. package/spec-forge/src/port.ts +0 -36
  460. package/spec-forge/src/resident.ts +0 -46
  461. /package/{spec-cli → node_modules/@spexcode/spec-cli}/README.md +0 -0
  462. /package/{spec-cli → node_modules/@spexcode/spec-cli}/hooks/compat/mark-active-0.5.2-eef1.fixture +0 -0
  463. /package/{spec-cli → node_modules/@spexcode/spec-cli}/hooks/compat/mark-active-sed-v0.fixture +0 -0
  464. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/hooks/commit-msg +0 -0
  465. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/hooks/post-checkout +0 -0
  466. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/hooks/post-merge +0 -0
  467. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/hooks/pre-commit +0 -0
  468. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/hooks/prepare-commit-msg +0 -0
  469. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/hooks/reference-transaction +0 -0
  470. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/commands/extract/spec.md +0 -0
  471. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/commands/regroup/spec.md +0 -0
  472. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/commands/rename/spec.md +0 -0
  473. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/commands/spec.md +0 -0
  474. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/commands/tidy/spec.md +0 -0
  475. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/comment-altitude/spec.md +0 -0
  476. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/idle/idle.sh +0 -0
  477. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/idle/spec.md +0 -0
  478. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/mark-active/mark-active.sh +0 -0
  479. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/mark-active/spec.md +0 -0
  480. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/session-fail/fail.sh +0 -0
  481. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/session-fail/spec.md +0 -0
  482. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/spec-first/spec.md +0 -0
  483. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/spec-of-file/spec.md +0 -0
  484. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/core/spec.md +0 -0
  485. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/prompts/atomic-landing/spec.md +0 -0
  486. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/prompts/forge-link/spec.md +0 -0
  487. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/prompts/memory-hygiene/spec.md +0 -0
  488. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/prompts/reproduce-before-fix/spec.md +0 -0
  489. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/prompts/spec.md +0 -0
  490. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/skills/distill/digest.mjs +0 -0
  491. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/skills/distill/spec.md +0 -0
  492. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/skills/spec.md +0 -0
  493. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/.plugins/spec.md +0 -0
  494. /package/{spec-cli → node_modules/@spexcode/spec-cli}/templates/spec/project/spec.md +0 -0
  495. /package/{spec-cli → node_modules/@spexcode/spec-core}/templates/spexcode.json +0 -0
@@ -0,0 +1,308 @@
1
+ import { sessionHeadline, sessionPresent } from './session.js';
2
+ import { effectiveTokens, tokenize } from './reviewQuery.js';
3
+ // [[review-filters]]: one pure filter engine — the single home of Issues/Evals FIELD SEMANTICS. Domain
4
+ // adapters below provide field values; surfaces provide only the state home and presentation: the
5
+ // canonical pages parse their ONE visible token text ([[review-query]]) and bridge it here, the Spec
6
+ // Information panes keep plain local state. Neither duplicates matching.
7
+ const text = (value) => String(value ?? '').trim().toLocaleLowerCase();
8
+ const values = (value) => (Array.isArray(value) ? value : value == null || value === '' ? [] : [value]);
9
+ const unique = (items) => [...new Set(items.flatMap(values).filter((value) => value != null && value !== '').map(String))];
10
+ export const EVAL_FILTER_KIND = Object.freeze({
11
+ RESULT: 'result',
12
+ BLIND: 'blind',
13
+ UNMEASURED: 'unmeasured',
14
+ DANGLING: 'dangling',
15
+ });
16
+ export const evidenceList = (reading) => reading?.evidence?.length ? reading.evidence
17
+ : reading?.blob != null ? [{ hash: reading.blob, kind: reading.blobKind || 'image', state: reading.blobState || 'present' }]
18
+ : [];
19
+ export const kindsOf = (reading) => {
20
+ const evidence = evidenceList(reading);
21
+ if (!evidence.length)
22
+ return ['note'];
23
+ return ['video', 'image', 'transcript', 'data'].filter((kind) => evidence.some((item) => item.kind === kind));
24
+ };
25
+ const optionLabel = (t, key, fallback) => t ? t(key) : fallback;
26
+ const allOption = (t) => ({ value: '', label: optionLabel(t, 'reviewList.all', 'All') });
27
+ const optionsFor = (items, facet, state, context, t) => {
28
+ const active = state[facet.key] != null && String(state[facet.key]) !== '';
29
+ // a fixed-value ENUM facet keeps its ACTIVE value as a real (checked) row even when no data carries
30
+ // it — an active facet must never hide its own off-switch; data-valued facets stay data-derived.
31
+ const found = facet.fixedValues
32
+ ? facet.fixedValues.filter((value) => facet.enumerateFixed
33
+ || (active && String(state[facet.key]) === String(value))
34
+ || items.some((item) => values(facet.values(item, context)).map(String).includes(String(value))))
35
+ : unique(items.map((item) => facet.values(item, context)));
36
+ const available = facet.available
37
+ ? facet.available(found, items, state, context)
38
+ : found.length >= (facet.minValues ?? 2);
39
+ if (!available && !active)
40
+ return [];
41
+ return [allOption(t), ...found.map((value) => ({
42
+ value,
43
+ label: facet.labelValue ? facet.labelValue(value, context) : value,
44
+ }))];
45
+ };
46
+ // A SPLIT section reports its count as two named buckets instead of one number. The predicate is BINARY
47
+ // and applied to the section's own matched rows, so the buckets always re-add to that section's whole
48
+ // population — a surface can lead with one half without the count quietly shrinking. The adapter alone
49
+ // decides which sections split and on what axis; the engine invents no bucket.
50
+ const splitCount = (matched, split, context) => {
51
+ const first = matched.filter((item) => split.is(item, context)).length;
52
+ return { [split.keys[0]]: first, [split.keys[1]]: matched.length - first };
53
+ };
54
+ // the one reading rule for a section count, whichever shape the adapter declared.
55
+ export const sectionTotal = (count) => (typeof count === 'number'
56
+ ? count
57
+ : Object.values(count ?? {}).reduce((sum, value) => sum + value, 0));
58
+ export function filterReviewItems(items, state, config, context = {}) {
59
+ // `q` is one substring or an ARRAY of substrings (the token text's bare words/phrases), conjunctive;
60
+ // an `impossible` state (an unknown qualifier in the canonical text) honestly matches NOTHING.
61
+ const qs = values(state.q).map(text).filter(Boolean);
62
+ const faceted = state.impossible ? [] : items.filter((item) => (qs.every((q) => config.search(item, context).some((value) => text(value).includes(q)))
63
+ && config.facets.every((facet) => {
64
+ const selected = state[facet.key];
65
+ return selected == null || selected === ''
66
+ || (facet.matches
67
+ ? facet.matches(item, selected, context)
68
+ : values(facet.values(item, context)).map(String).includes(String(selected)));
69
+ })));
70
+ const sectionValue = config.section && state[config.section.key];
71
+ const sectionMatch = (item, selected) => (config.section.matches
72
+ ? config.section.matches(item, selected, context)
73
+ : String(config.section.value(item, context)) === String(selected));
74
+ const shown = sectionValue == null || sectionValue === ''
75
+ ? faceted
76
+ : faceted.filter((item) => sectionMatch(item, sectionValue));
77
+ const sections = config.section
78
+ ? Object.fromEntries(config.section.options.map((option) => {
79
+ const matched = faceted.filter((item) => sectionMatch(item, option.value));
80
+ return [option.value, option.split && config.section.split
81
+ ? splitCount(matched, config.section.split, context)
82
+ : matched.length];
83
+ }))
84
+ : {};
85
+ const facets = Object.fromEntries(config.facets.map((facet) => [facet.key, {
86
+ key: facet.key,
87
+ label: optionLabel(context.t, facet.label, facet.key),
88
+ value: state[facet.key] || '',
89
+ options: optionsFor(items, facet, state, context, context.t),
90
+ }]));
91
+ return { state, faceted, shown, sections, facets };
92
+ }
93
+ export const reviewActorName = (actor) => String(actor || '').length > 22 ? `${String(actor).slice(0, 8)}…` : actor;
94
+ // the source-session PRESENCE join ([[live-session-filter]]): originator or any reply author still
95
+ // resolves on the board — membership, never liveness.
96
+ const issuePresent = (issue, sessions) => !!sessionPresent(sessions, issue.by)
97
+ || (Array.isArray(issue.replies) && issue.replies.some((reply) => sessionPresent(sessions, reply.by)));
98
+ const presenceFacet = (valuesOf) => ({
99
+ key: 'session', label: 'reviewList.facetSession', fixedValues: ['present', 'missing'],
100
+ values: valuesOf,
101
+ labelValue: (value, { t }) => optionLabel(t, value === 'present' ? 'reviewList.sessionPresent' : 'reviewList.sessionMissing', value),
102
+ });
103
+ export function issueFilterState(raw = {}, { defaultSection = '' } = {}) {
104
+ const state = raw.state === 'closed' || raw.concluded === '1'
105
+ ? 'closed'
106
+ : raw.state || defaultSection;
107
+ return {
108
+ q: raw.q || '', state, impossible: raw.impossible === true,
109
+ author: raw.author || '', store: raw.store || '', node: raw.node || '', label: raw.label || '',
110
+ session: raw.session || '',
111
+ };
112
+ }
113
+ const ISSUE_CONFIG = {
114
+ search: (issue) => [issue.id, issue.concern, issue.by, ...(issue.nodes || [])],
115
+ section: {
116
+ key: 'state',
117
+ value: (issue) => issue.status === 'open' ? 'open' : 'closed',
118
+ // open|closed are the lifecycle halves; a concrete concluded spelling (landed) matches that status
119
+ // honestly instead of pretending the enum is binary.
120
+ matches: (issue, selected) => (selected === 'open' ? issue.status === 'open'
121
+ : selected === 'closed' ? issue.status !== 'open' : issue.status === selected),
122
+ options: [{ value: 'open', label: 'reviewList.open' }, { value: 'closed', label: 'reviewList.closed' }],
123
+ },
124
+ facets: [
125
+ { key: 'author', label: 'reviewList.facetAuthor', values: (issue) => issue.by, labelValue: reviewActorName },
126
+ { key: 'store', label: 'reviewList.facetStore', values: (issue) => issue.store },
127
+ { key: 'node', label: 'reviewList.facetNode', values: (issue) => issue.nodes || [] },
128
+ { key: 'label', label: 'reviewList.facetLabel', values: (issue) => (issue.labels || []).map((label) => typeof label === 'string' ? label : label?.name), minValues: 1 },
129
+ presenceFacet((issue, { sessions }) => issuePresent(issue, sessions) ? 'present' : 'missing'),
130
+ ],
131
+ };
132
+ export function issueFilterModel(items, raw = {}, context = {}) {
133
+ const state = issueFilterState(raw, { defaultSection: context.defaultSection ?? '' });
134
+ const model = filterReviewItems(items, state, ISSUE_CONFIG, context);
135
+ model.section = {
136
+ key: 'state', label: optionLabel(context.t, 'reviewList.facetState', 'State'), value: state.state,
137
+ meaningful: Object.values(model.sections).filter((count) => sectionTotal(count) > 0).length > 1 || !!state.state,
138
+ options: [allOption(context.t), ...ISSUE_CONFIG.section.options.map((option) => ({
139
+ value: option.value,
140
+ label: optionLabel(context.t, option.label, option.value),
141
+ count: sectionTotal(model.sections[option.value]),
142
+ }))].filter((option, index, all) => index === 0 || option.count > 0 || option.value === state.state),
143
+ };
144
+ return model;
145
+ }
146
+ const evalIsResult = (entry) => entry.filterKind === EVAL_FILTER_KIND.RESULT;
147
+ const verdictOf = (entry) => evalIsResult(entry)
148
+ ? (entry.verdict?.status || 'unscored')
149
+ : entry.filterKind === EVAL_FILTER_KIND.BLIND || entry.filterKind === EVAL_FILTER_KIND.UNMEASURED
150
+ ? 'unmeasured'
151
+ : 'unscored';
152
+ const reviewStateOf = (entry) => (evalIsResult(entry) && entry.fresh && entry.humanOk ? 'reviewed' : 'current');
153
+ // the ONE freshness axis of the Eval adapter — the facet's option values and the verdict sections' split
154
+ // read it, so a chip and its Freshness menu can never disagree about what "stale" counts.
155
+ const evalFresh = (entry) => entry.fresh === true;
156
+ const freshnessOf = (entry) => (evalIsResult(entry) ? (evalFresh(entry) ? 'fresh' : 'stale') : null);
157
+ export const evalReviewState = (reading) => {
158
+ // an order-only row never had its freshness computed, so it has no verdict to report. Refuse it here
159
+ // rather than let its conservative placeholder be published as a measured `stalePass`/`staleFail`: the
160
+ // whole point of the deferred pass is that these rows exist only to establish sequence.
161
+ if (reading?.freshnessDeferred)
162
+ throw new Error(`eval row ${reading.scenario ?? '?'} has deferred freshness — it can order a list, never state a verdict`);
163
+ const status = reading?.verdict?.status;
164
+ if (status !== 'pass' && status !== 'fail')
165
+ return 'empty';
166
+ if (reading.fresh)
167
+ return status;
168
+ return status === 'pass' ? 'stalePass' : 'staleFail';
169
+ };
170
+ const shortSession = (value, sessions) => {
171
+ const session = sessions.find((item) => item.id === value);
172
+ if (session)
173
+ return sessionHeadline(session);
174
+ return String(value || '').length > 22 ? `${String(value).slice(0, 8)}…` : value;
175
+ };
176
+ export function evalFilterState(raw = {}, { defaultKind = 'all', defaultSection = '' } = {}) {
177
+ const legacyReview = raw.ok === '1' ? 'reviewed' : raw.ok;
178
+ return {
179
+ q: raw.q || '', kind: raw.kind || defaultKind, impossible: raw.impossible === true,
180
+ verdict: raw.verdict || '', freshness: raw.freshness || '', node: raw.node || '', filer: raw.filer || '',
181
+ session: raw.session || '', review: raw.review || legacyReview || defaultSection,
182
+ };
183
+ }
184
+ const EVAL_CONFIG = {
185
+ search: (entry) => [entry.scenario, entry.node, entry.by, entry.evaluator],
186
+ section: {
187
+ key: 'verdict', value: verdictOf,
188
+ // A MEASURED verdict carries a reading, so it also carries freshness: its count splits into the fresh
189
+ // half and the stale half that still owes a re-measurement. The two halves re-add to the verdict's
190
+ // whole population — splitting reports the remeasurement debt, it never hides a row. `unmeasured` owns
191
+ // no reading and therefore no freshness axis, so it stays one honest number.
192
+ split: { keys: ['fresh', 'stale'], is: evalFresh },
193
+ options: [
194
+ { value: 'fail', label: 'reviewList.verdict.fail', split: true },
195
+ { value: 'pass', label: 'reviewList.verdict.pass', split: true },
196
+ { value: 'unmeasured', label: 'reviewList.verdict.unmeasured' },
197
+ ],
198
+ },
199
+ facets: [
200
+ {
201
+ key: 'review', label: 'reviewList.facetReview', fixedValues: ['current', 'reviewed'], enumerateFixed: true,
202
+ values: reviewStateOf,
203
+ labelValue: (value, { t }) => optionLabel(t, value === 'reviewed' ? 'reviewList.reviewed' : 'reviewList.needsReview', value),
204
+ },
205
+ {
206
+ key: 'freshness', label: 'reviewList.facetFreshness', minValues: 2,
207
+ values: (entry) => freshnessOf(entry) ?? [],
208
+ labelValue: (value, { t }) => optionLabel(t, `reviewList.freshness.${value}`, value),
209
+ },
210
+ {
211
+ key: 'kind', label: 'reviewList.facetKind', fixedValues: ['video', 'image'], minValues: 1,
212
+ values: (entry) => evalIsResult(entry) ? kindsOf(entry).filter((kind) => kind === 'video' || kind === 'image') : [],
213
+ matches: (entry, selected) => selected === 'all' || (evalIsResult(entry) && kindsOf(entry).includes(selected)),
214
+ labelValue: (value, { t }) => optionLabel(t, `evalsFeed.kind.${value}`, value),
215
+ available: (found, _items, state) => found.length > 0 || state.kind !== 'all',
216
+ },
217
+ { key: 'node', label: 'reviewList.facetNode', values: (entry) => entry.node },
218
+ {
219
+ key: 'filer', label: 'reviewList.facetFiler', values: (entry) => evalIsResult(entry) ? entry.by : [],
220
+ labelValue: (value, { sessions = [] }) => shortSession(value, sessions),
221
+ },
222
+ presenceFacet((entry, { sessions }) => (evalIsResult(entry)
223
+ ? (sessionPresent(sessions, entry.by) ? 'present' : 'missing')
224
+ : [])),
225
+ ],
226
+ };
227
+ export function evalFilterModel(items, raw = {}, context = {}) {
228
+ const state = evalFilterState(raw, {
229
+ defaultKind: context.defaultKind ?? 'all',
230
+ defaultSection: context.defaultSection ?? '',
231
+ });
232
+ const model = filterReviewItems(items, state, EVAL_CONFIG, context);
233
+ model.section = {
234
+ key: 'verdict', label: optionLabel(context.t, 'reviewList.facetVerdict', 'Verdict'), value: state.verdict,
235
+ meaningful: Object.values(model.sections).some((count) => sectionTotal(count) > 0) || !!state.verdict,
236
+ // the menu/popup face of the same sections keeps the verdict's WHOLE count: a compact radio row has no
237
+ // room for the split, and it must still agree with the list it filters.
238
+ options: [allOption(context.t), ...EVAL_CONFIG.section.options.map((option) => ({
239
+ value: option.value,
240
+ label: optionLabel(context.t, option.label, option.value),
241
+ count: sectionTotal(model.sections[option.value]),
242
+ }))].filter((option, index) => index === 0 || option.count > 0 || option.value === state.verdict),
243
+ };
244
+ const kindFacet = model.facets.kind;
245
+ if (kindFacet.options.length) {
246
+ kindFacet.options = [
247
+ { value: 'all', label: optionLabel(context.t, 'evalsFeed.kind.all', 'All') },
248
+ ...kindFacet.options.filter((option) => option.value !== '').map((option) => ({ ...option })),
249
+ ];
250
+ kindFacet.value = state.kind;
251
+ }
252
+ return model;
253
+ }
254
+ export function filterMenuGroups(model, onChange, keys) {
255
+ return keys.map((key) => key === 'section' ? model.section : model.facets[key]).filter((facet) => (facet?.meaningful !== false
256
+ && (facet?.options?.length > 1 || (facet?.value != null && facet.value !== '' && facet.value !== 'all')))).map((facet) => ({
257
+ key: facet.key,
258
+ label: facet.label,
259
+ value: facet.value,
260
+ active: facet.value != null && facet.value !== '' && facet.value !== 'all',
261
+ options: facet.options,
262
+ clearLabel: facet.value === 'all' ? null : undefined,
263
+ onChange: (value) => onChange({ [facet.key]: value || null }),
264
+ }));
265
+ }
266
+ // the CANONICAL pages' bridge ([[review-query]] → this engine): parse the ONE visible token text into
267
+ // engine state. Bare words/phrases become conjunctive q substrings; duplicate qualifiers are last-wins;
268
+ // a qualifier outside the page's map (or a wrong is: identity) marks the state IMPOSSIBLE — the token
269
+ // stays verbatim in the text and the list honestly shows nothing. `scope:` maps to no filter: it picks
270
+ // the DATA SOURCE upstream ([[evals-view]]), never a per-row predicate.
271
+ const TOKEN_MAPS = {
272
+ issue: {
273
+ is: (v) => (v === 'issue' ? {} : null),
274
+ state: (v) => ({ state: v }),
275
+ store: (v) => ({ store: v }),
276
+ author: (v) => ({ author: v }),
277
+ node: (v) => ({ node: v }),
278
+ label: (v) => ({ label: v }),
279
+ session: (v) => ({ session: v }),
280
+ },
281
+ eval: {
282
+ is: (v) => (v === 'eval' ? {} : null),
283
+ state: (v) => ({ review: v }),
284
+ verdict: (v) => ({ verdict: v }),
285
+ freshness: (v) => ({ freshness: v }),
286
+ evidence: (v) => ({ kind: v }),
287
+ node: (v) => ({ node: v }),
288
+ filer: (v) => ({ filer: v }),
289
+ session: (v) => ({ session: v }),
290
+ scope: () => ({}),
291
+ },
292
+ };
293
+ export function tokenFilterState(text, domain) {
294
+ const map = TOKEN_MAPS[domain];
295
+ const state = { q: [] };
296
+ for (const token of effectiveTokens(tokenize(text))) {
297
+ if (token.key == null) {
298
+ state.q.push(token.value);
299
+ continue;
300
+ }
301
+ const toState = map[token.key];
302
+ const mapped = toState ? toState(token.value) : null;
303
+ if (mapped == null)
304
+ return { impossible: true, q: [] };
305
+ Object.assign(state, mapped);
306
+ }
307
+ return state;
308
+ }
@@ -0,0 +1,66 @@
1
+ export function scanQuery(text: any): ({
2
+ ws: boolean;
3
+ raw: string;
4
+ start: number;
5
+ end: number;
6
+ key?: undefined;
7
+ value?: undefined;
8
+ } | {
9
+ ws: boolean;
10
+ raw: string;
11
+ start: number;
12
+ end: number;
13
+ key: string;
14
+ value: any;
15
+ } | {
16
+ ws: boolean;
17
+ raw: string;
18
+ start: number;
19
+ end: number;
20
+ key: null;
21
+ value: any;
22
+ })[];
23
+ export function setToken(text: any, key: any, value: any): any;
24
+ export function legacyQueryText(defaultText: any, query: any): any;
25
+ export function suggestAt(text: any, caret: any, keys?: any[], values?: {}): {
26
+ start: number;
27
+ end: number;
28
+ items: any;
29
+ };
30
+ export const ISSUE_QUERY_DEFAULT: "is:issue state:open";
31
+ export const EVAL_QUERY_DEFAULT: "is:eval";
32
+ export function scopedEvalQuery(sessionId: any): any;
33
+ export function nodeEvalQuery(nodeId: any): any;
34
+ export function quoteValue(v: any): string;
35
+ export function tokenize(text: any): ({
36
+ ws: boolean;
37
+ raw: string;
38
+ start: number;
39
+ end: number;
40
+ key?: undefined;
41
+ value?: undefined;
42
+ } | {
43
+ ws: boolean;
44
+ raw: string;
45
+ start: number;
46
+ end: number;
47
+ key: string;
48
+ value: any;
49
+ } | {
50
+ ws: boolean;
51
+ raw: string;
52
+ start: number;
53
+ end: number;
54
+ key: null;
55
+ value: any;
56
+ })[];
57
+ export function serialize(tokens: any): any;
58
+ export function normalizeQuery(text: any): any;
59
+ export function sameQuery(a: any, b: any): boolean;
60
+ export function effectiveTokens(tokens: any): any;
61
+ export function readToken(text: any, key: any): any;
62
+ export function queryParam(text: any, defaultText: any): {
63
+ q: string;
64
+ } | null;
65
+ export function reviewRouteQuery(text: any, defaultText: any, page?: null): {} | null;
66
+ export function hasLegacyParams(query: any): boolean;
@@ -0,0 +1,180 @@
1
+ // The ONE token-query engine ([[review-query]]) — pure JS, no React/DOM. Both review ListViews, the
2
+ // route layer's legacy replay, and any consumer minting canonical eval/issue addresses import from HERE:
3
+ // the visible query TEXT is the single source of truth, and every tab/menu/autocomplete is only a
4
+ // BUILDER that rewrites tokens in it (GitHub-measured semantics).
5
+ export const ISSUE_QUERY_DEFAULT = 'is:issue state:open';
6
+ export const EVAL_QUERY_DEFAULT = 'is:eval';
7
+ // the session doors' scoped-list address: the default view, scoped — the text shows exactly that.
8
+ export const scopedEvalQuery = (sessionId) => setToken(EVAL_QUERY_DEFAULT, 'scope', sessionId);
9
+ // the aggregate score/count doors' address ([[eval-score-badge]]): the default view, node-filtered.
10
+ export const nodeEvalQuery = (nodeId) => setToken(EVAL_QUERY_DEFAULT, 'node', nodeId);
11
+ const KEY_RE = /^([A-Za-z][A-Za-z0-9-]*):(.*)$/s;
12
+ const unquote = (v) => (v.length >= 2 && v.startsWith('"') && v.endsWith('"') ? v.slice(1, -1) : v);
13
+ export const quoteValue = (v) => (/\s/.test(String(v)) ? `"${v}"` : String(v));
14
+ // segment scan preserving EVERY character — whitespace runs and tokens (a `"` swallows spaces until it
15
+ // closes), each with [start,end) offsets — so the aria-hidden highlight overlay mirrors the input
16
+ // glyph-for-glyph and the autocomplete can find the token under the caret.
17
+ export function scanQuery(text) {
18
+ const s = String(text ?? '');
19
+ const out = [];
20
+ let i = 0;
21
+ while (i < s.length) {
22
+ let j = i;
23
+ if (/\s/.test(s[i])) {
24
+ while (j < s.length && /\s/.test(s[j]))
25
+ j++;
26
+ out.push({ ws: true, raw: s.slice(i, j), start: i, end: j });
27
+ }
28
+ else {
29
+ while (j < s.length && !/\s/.test(s[j])) {
30
+ if (s[j] === '"') {
31
+ j++;
32
+ while (j < s.length && s[j] !== '"')
33
+ j++;
34
+ if (j < s.length)
35
+ j++;
36
+ }
37
+ else
38
+ j++;
39
+ }
40
+ const raw = s.slice(i, j);
41
+ const m = KEY_RE.exec(raw);
42
+ out.push(m
43
+ ? { ws: false, raw, start: i, end: j, key: m[1].toLowerCase(), value: unquote(m[2]) }
44
+ : { ws: false, raw, start: i, end: j, key: null, value: unquote(raw) });
45
+ }
46
+ i = j;
47
+ }
48
+ return out;
49
+ }
50
+ export const tokenize = (text) => scanQuery(text).filter((seg) => !seg.ws);
51
+ export const serialize = (tokens) => tokens.map((t) => t.raw).join(' ');
52
+ export const normalizeQuery = (text) => serialize(tokenize(text));
53
+ export const sameQuery = (a, b) => normalizeQuery(a) === normalizeQuery(b);
54
+ // duplicate qualifiers: the LAST occurrence wins; bare words all apply.
55
+ export const effectiveTokens = (tokens) => {
56
+ const last = new Map();
57
+ for (const t of tokens)
58
+ if (t.key != null)
59
+ last.set(t.key, t);
60
+ return tokens.filter((t) => t.key == null || last.get(t.key) === t);
61
+ };
62
+ export const readToken = (text, key) => {
63
+ const tokens = tokenize(text);
64
+ for (let i = tokens.length - 1; i >= 0; i--)
65
+ if (tokens[i].key === key)
66
+ return tokens[i].value;
67
+ return '';
68
+ };
69
+ // token SURGERY: rewrite the key at its first position, drop later duplicates, append when absent,
70
+ // remove the key entirely on an empty value. Every other token — known or not — survives verbatim.
71
+ export function setToken(text, key, value) {
72
+ const next = value == null || String(value) === ''
73
+ ? null
74
+ : { ws: false, raw: `${key}:${quoteValue(value)}`, key, value: String(value) };
75
+ const out = [];
76
+ let placed = false;
77
+ for (const t of tokenize(text)) {
78
+ if (t.key === key) {
79
+ if (next && !placed) {
80
+ out.push(next);
81
+ placed = true;
82
+ }
83
+ continue;
84
+ }
85
+ out.push(t);
86
+ }
87
+ if (next && !placed)
88
+ out.push(next);
89
+ return serialize(out);
90
+ }
91
+ // MATCHING is deliberately NOT here: this module owns text — scan/serialize/surgery/suggestions and the
92
+ // canonical-address discipline — while the conjunctive field matching (including the unknown-qualifier
93
+ // IMPOSSIBLE state) lives in the ONE [[review-filters]] engine, reached through its tokenFilterState
94
+ // bridge. A second predicate here would be the exact fork the fusion removed.
95
+ // canonical address discipline: the default view is the BARE page address; any other state is exactly
96
+ // ?q=<raw text>. An emptied submit falls back to the default (→ bare).
97
+ export const queryParam = (text, defaultText) => {
98
+ const trimmed = String(text ?? '').trim();
99
+ if (!trimmed || sameQuery(trimmed, defaultText))
100
+ return null;
101
+ return { q: trimmed };
102
+ };
103
+ // A query/filter action resets by omitting page; a PAGINATION action passes a page (including 1) and
104
+ // therefore records GitHub's explicit page=1 history form. The distinction is the action, not equivalence.
105
+ export const reviewRouteQuery = (text, defaultText, page = null) => {
106
+ const query = queryParam(text, defaultText) || {};
107
+ if (page != null)
108
+ query.page = String(page);
109
+ return Object.keys(query).length ? query : null;
110
+ };
111
+ // LEGACY structured params → token pairs. `kind=all` maps to nothing: the evidence default IS all.
112
+ const LEGACY_PARAMS = {
113
+ state: (v) => ['state', v],
114
+ concluded: (v) => (v === '1' ? ['state', 'closed'] : null),
115
+ ok: (v) => (v === '1' ? ['state', 'reviewed'] : null),
116
+ verdict: (v) => ['verdict', v],
117
+ freshness: (v) => ['freshness', v],
118
+ kind: (v) => (v === 'all' ? null : ['evidence', v]),
119
+ store: (v) => ['store', v],
120
+ author: (v) => ['author', v],
121
+ node: (v) => ['node', v],
122
+ filer: (v) => ['filer', v],
123
+ live: (v) => (v === '1' ? ['session', 'present'] : null),
124
+ session: (v) => ['scope', v],
125
+ };
126
+ export const hasLegacyParams = (query) => Object.keys(LEGACY_PARAMS).some((k) => query?.[k] != null && query[k] !== '');
127
+ // the legacy free q was ONE substring search — it must replay as ONE text token. Quote it whenever the
128
+ // tokenizer would read it as anything else: spaces (several words), a colon (q=drift:check would become
129
+ // an unknown qualifier and match zero), or a stray quote (which would swallow neighbours).
130
+ const freeTextToken = (v) => (/[\s:"]/.test(v) ? `"${v.replace(/"/g, '')}"` : v);
131
+ // a legacy LIST address replays as the FULL visible state: the page's default tokens with each legacy
132
+ // param surgically applied (live=1→session:present, session=<id>→scope:<id>, ok=1→state:reviewed,
133
+ // kind→evidence:), the free-text q appended as ONE bare/phrase token preserving the old
134
+ // single-substring search. Returns null when nothing legacy is present.
135
+ export function legacyQueryText(defaultText, query) {
136
+ if (!hasLegacyParams(query))
137
+ return null;
138
+ let text = defaultText;
139
+ for (const [param, toPair] of Object.entries(LEGACY_PARAMS)) {
140
+ const v = query[param];
141
+ if (v == null || v === '')
142
+ continue;
143
+ const pair = toPair(String(v));
144
+ if (pair)
145
+ text = setToken(text, pair[0], pair[1]);
146
+ }
147
+ const free = String(query.q ?? '').trim();
148
+ if (free)
149
+ text = `${text} ${freeTextToken(free)}`.trim();
150
+ return text;
151
+ }
152
+ // inline autocomplete at the caret — client-side and BOUNDED. A bare prefix completes qualifier KEYS
153
+ // (insert `key:`, keep typing); a `key:prefix` completes VALUES from the page-supplied candidate list
154
+ // only (data-derived; scope = sessions on the current board), capped at 8. Everything else stays
155
+ // hand-typable and submits verbatim.
156
+ export function suggestAt(text, caret, keys = [], values = {}) {
157
+ const s = String(text ?? '');
158
+ const at = Math.max(0, Math.min(caret ?? s.length, s.length));
159
+ const seg = scanQuery(s).find((g) => !g.ws && g.start < at && at <= g.end);
160
+ if (!seg)
161
+ return { start: at, end: at, items: [] };
162
+ const typed = s.slice(seg.start, at);
163
+ const m = KEY_RE.exec(typed);
164
+ if (!m) {
165
+ const w = typed.toLowerCase();
166
+ if (!w || w.includes('"'))
167
+ return { start: seg.start, end: seg.end, items: [] };
168
+ const items = keys.filter((k) => k.startsWith(w)).slice(0, 8)
169
+ .map((k) => ({ type: 'key', key: k, insert: `${k}:` }));
170
+ return { start: seg.start, end: seg.end, items };
171
+ }
172
+ const key = m[1].toLowerCase();
173
+ const prefix = m[2].replace(/^"/, '').replace(/"$/, '').toLowerCase();
174
+ const pool = values[key] || [];
175
+ const items = pool
176
+ .filter((c) => String(c.value).toLowerCase().startsWith(prefix) && String(c.value).toLowerCase() !== prefix)
177
+ .slice(0, 8)
178
+ .map((c) => ({ type: 'value', key, value: String(c.value), label: c.label || null, insert: `${key}:${quoteValue(c.value)} ` }));
179
+ return { start: seg.start, end: seg.end, items };
180
+ }
@@ -0,0 +1,4 @@
1
+ export function sessionPresent(sessions: any, id: any): any;
2
+ export function sessionHeadline(session: any): any;
3
+ export function sessionHandle(session: any): any;
4
+ export function sessionTitle(session: any): any;
@@ -0,0 +1,8 @@
1
+ export const sessionPresent = (sessions, id) => {
2
+ const session = id ? (sessions || []).find((item) => item.id === id) : null;
3
+ return session || null;
4
+ };
5
+ export const sessionHeadline = (session) => session?.title || session?.headline || session?.name || session?.activity || session?.note
6
+ || session?.promptPreview || session?.node || session?.raw?.title || session?.branch || session?.id;
7
+ export const sessionHandle = (session) => session?.label || session?.name || session?.node || session?.title || session?.branch || session?.id;
8
+ export const sessionTitle = sessionHeadline;
@@ -0,0 +1,15 @@
1
+ export type ReviewEvalNode = {
2
+ id: string;
3
+ hue?: number;
4
+ scenarios: any[];
5
+ evals: any[];
6
+ readings: any[];
7
+ };
8
+ export type ReviewSnapshot = {
9
+ issues: any[];
10
+ evalNodes: ReviewEvalNode[];
11
+ forgeRevision: number;
12
+ };
13
+ export declare function publishReviewSnapshot(snapshot: ReviewSnapshot): void;
14
+ export declare function readReviewSnapshot(): ReviewSnapshot;
15
+ export declare function hasReviewSnapshot(): boolean;
@@ -0,0 +1,12 @@
1
+ let current = null;
2
+ export function publishReviewSnapshot(snapshot) {
3
+ current = snapshot;
4
+ }
5
+ export function readReviewSnapshot() {
6
+ if (!current)
7
+ throw new Error('review snapshot is unavailable before the first successful graph build');
8
+ return current;
9
+ }
10
+ export function hasReviewSnapshot() {
11
+ return current !== null;
12
+ }
@@ -0,0 +1,4 @@
1
+ export declare const rootSlots: (env: string | undefined, fallback: number) => number;
2
+ export declare function touchRoot(roots: Map<string, string>, cache: Map<string, unknown> & {
3
+ delete(key: string): boolean;
4
+ }, root: string, key: string, slots: number): void;