geneseed 2.0.0

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 (337) hide show
  1. package/CHANGELOG.md +938 -0
  2. package/DESIGN.md +1423 -0
  3. package/LICENSE +21 -0
  4. package/QUICKSTART.md +48 -0
  5. package/README.md +336 -0
  6. package/SETUP.md +1027 -0
  7. package/SHIPPED.md +70 -0
  8. package/adapters/bob/README.md +100 -0
  9. package/adapters/claude-code/README.md +101 -0
  10. package/adapters/claude-code/settings.json +47 -0
  11. package/adapters/claude-code/skills/geneseed/SKILL.md +72 -0
  12. package/adapters/copilot/README.md +76 -0
  13. package/adapters/opencode/GLOBAL-HARNESS-SPEC.md +434 -0
  14. package/adapters/opencode/HOW-OPENCODE-LOADS.md +158 -0
  15. package/adapters/opencode/README.md +582 -0
  16. package/adapters/opencode/agents/orchestrator.md +25 -0
  17. package/adapters/opencode/opencode.json +44 -0
  18. package/adapters/opencode/plugins/geneseed-activity.js +430 -0
  19. package/adapters/opencode/plugins/geneseed-context.js +876 -0
  20. package/adapters/opencode/plugins/geneseed-guard.js +290 -0
  21. package/adapters/opencode/plugins/geneseed-learn.js +396 -0
  22. package/adapters/opencode/plugins/geneseed-notify.js +142 -0
  23. package/adapters/opencode/plugins/geneseed-ponytail.js +148 -0
  24. package/adapters/opencode/plugins/geneseed-workflow.js +183 -0
  25. package/adapters/opencode/workflows/_runtime.js +277 -0
  26. package/adapters/opencode/workflows/council.js +64 -0
  27. package/adapters/opencode/workflows/dispatch.js +89 -0
  28. package/adapters/opencode/workflows/research-plan-implement.js +43 -0
  29. package/adapters/opencode/workflows/review.js +57 -0
  30. package/bin/geneseed-cli.mjs +412 -0
  31. package/bin/geneseed-hook.mjs +129 -0
  32. package/bin/geneseed.mjs +1086 -0
  33. package/docs/declined.md +149 -0
  34. package/docs/limits.md +270 -0
  35. package/docs/opencode-plugin-setup.md +64 -0
  36. package/docs/token-footprint.md +68 -0
  37. package/docs/web/_groups.json +45 -0
  38. package/docs/web/about.md +6 -0
  39. package/docs/web/adapters-claude-code.md +8 -0
  40. package/docs/web/adapters-opencode-loads.md +8 -0
  41. package/docs/web/adapters-opencode-spec.md +8 -0
  42. package/docs/web/adapters-opencode.md +8 -0
  43. package/docs/web/agents.md +8 -0
  44. package/docs/web/authoring.md +11 -0
  45. package/docs/web/autostart.md +9 -0
  46. package/docs/web/claude-hooks.md +36 -0
  47. package/docs/web/cli.md +6 -0
  48. package/docs/web/collaboration.md +27 -0
  49. package/docs/web/configure-wiki.md +9 -0
  50. package/docs/web/design.md +7 -0
  51. package/docs/web/env-knobs.md +9 -0
  52. package/docs/web/exclusions.md +26 -0
  53. package/docs/web/first-session.md +28 -0
  54. package/docs/web/footprint.md +31 -0
  55. package/docs/web/foreman-mode.md +33 -0
  56. package/docs/web/glossary.md +6 -0
  57. package/docs/web/harnesses.md +28 -0
  58. package/docs/web/headless.md +9 -0
  59. package/docs/web/ingest-docs.md +9 -0
  60. package/docs/web/install-paths.md +9 -0
  61. package/docs/web/install-quick.md +35 -0
  62. package/docs/web/lsp-overview.md +37 -0
  63. package/docs/web/mcp-claude-code.md +10 -0
  64. package/docs/web/mcp-filesystem.md +9 -0
  65. package/docs/web/mcp-gitlab.md +9 -0
  66. package/docs/web/mcp-markitdown.md +9 -0
  67. package/docs/web/mcp-overview.md +34 -0
  68. package/docs/web/mcp-trouble.md +9 -0
  69. package/docs/web/mcp-verify.md +9 -0
  70. package/docs/web/memory.md +7 -0
  71. package/docs/web/migrate.md +39 -0
  72. package/docs/web/model.md +20 -0
  73. package/docs/web/notebook.md +7 -0
  74. package/docs/web/pipelines.md +24 -0
  75. package/docs/web/plugin-activity.md +23 -0
  76. package/docs/web/plugin-context.md +26 -0
  77. package/docs/web/plugin-guard.md +24 -0
  78. package/docs/web/plugin-learn.md +27 -0
  79. package/docs/web/plugin-notify.md +24 -0
  80. package/docs/web/plugin-ponytail.md +23 -0
  81. package/docs/web/plugin-setup.md +7 -0
  82. package/docs/web/plugin-workflow.md +24 -0
  83. package/docs/web/plugins.md +17 -0
  84. package/docs/web/project-context.md +9 -0
  85. package/docs/web/rules.md +8 -0
  86. package/docs/web/run-anywhere.md +9 -0
  87. package/docs/web/self-improve.md +8 -0
  88. package/docs/web/setup-choices.md +39 -0
  89. package/docs/web/skills.md +8 -0
  90. package/docs/web/themes-author.md +8 -0
  91. package/docs/web/themes.md +9 -0
  92. package/docs/web/token-footprint.md +7 -0
  93. package/docs/web/trouble.md +38 -0
  94. package/docs/web/upgrade.md +9 -0
  95. package/docs/web/verify.md +30 -0
  96. package/docs/web/wiki.md +7 -0
  97. package/docs/web/worktree.md +10 -0
  98. package/docs/web-ui.md +144 -0
  99. package/docs/wiki.md +43 -0
  100. package/geneseed +39 -0
  101. package/geneseed.cmd +34 -0
  102. package/harness.config.json +6 -0
  103. package/js/anim.mjs +326 -0
  104. package/js/catalog.mjs +112 -0
  105. package/js/checkout.mjs +88 -0
  106. package/js/cli-table.json +1034 -0
  107. package/js/cli.mjs +498 -0
  108. package/js/diff.mjs +384 -0
  109. package/js/doctor.mjs +1364 -0
  110. package/js/emit.mjs +1373 -0
  111. package/js/excludes.mjs +271 -0
  112. package/js/generate.mjs +379 -0
  113. package/js/hooks.mjs +1026 -0
  114. package/js/hosts.mjs +253 -0
  115. package/js/installs.mjs +378 -0
  116. package/js/inventory.mjs +175 -0
  117. package/js/lib/fs.mjs +913 -0
  118. package/js/lib/proc.mjs +28 -0
  119. package/js/lib/udiff.mjs +275 -0
  120. package/js/link.mjs +286 -0
  121. package/js/mcp.mjs +335 -0
  122. package/js/memory.mjs +108 -0
  123. package/js/menu.mjs +118 -0
  124. package/js/migrate.mjs +251 -0
  125. package/js/native.mjs +426 -0
  126. package/js/opencode.mjs +325 -0
  127. package/js/registry.mjs +110 -0
  128. package/js/render.mjs +282 -0
  129. package/js/settings.mjs +924 -0
  130. package/js/setup.mjs +492 -0
  131. package/js/status.mjs +281 -0
  132. package/js/themes.mjs +195 -0
  133. package/js/tui.mjs +444 -0
  134. package/js/uninstall.mjs +1137 -0
  135. package/js/update.mjs +910 -0
  136. package/js/web/actions.mjs +868 -0
  137. package/js/web/activity.mjs +284 -0
  138. package/js/web/api.mjs +873 -0
  139. package/js/web/docs.mjs +531 -0
  140. package/js/web/graph.mjs +0 -0
  141. package/js/web/jobs.mjs +480 -0
  142. package/js/web/server.mjs +1135 -0
  143. package/package.json +54 -0
  144. package/registry.json +474 -0
  145. package/src/AGENT.md.tmpl +390 -0
  146. package/src/agents/_template.md +76 -0
  147. package/src/agents/advocate.md +36 -0
  148. package/src/agents/architect.md +55 -0
  149. package/src/agents/developer.md +66 -0
  150. package/src/agents/docs.md +54 -0
  151. package/src/agents/empiricist.md +39 -0
  152. package/src/agents/explorer.md +54 -0
  153. package/src/agents/framer.md +36 -0
  154. package/src/agents/historian.md +51 -0
  155. package/src/agents/operator.md +37 -0
  156. package/src/agents/pragmatist.md +37 -0
  157. package/src/agents/reviewer.md +52 -0
  158. package/src/agents/security.md +57 -0
  159. package/src/agents/skeptic.md +48 -0
  160. package/src/agents/steward.md +36 -0
  161. package/src/agents/tester.md +54 -0
  162. package/src/agents/user-advocate.md +36 -0
  163. package/src/agents/visionary.md +36 -0
  164. package/src/laws/universal.md +387 -0
  165. package/src/memory/README.md +109 -0
  166. package/src/memory/gitignore +6 -0
  167. package/src/modes/README.md +26 -0
  168. package/src/modes/direct.md +2 -0
  169. package/src/modes/foreman.md +19 -0
  170. package/src/notebook/README.md +39 -0
  171. package/src/notebook/gitignore +7 -0
  172. package/src/postures/README.md +31 -0
  173. package/src/postures/artisan.md +14 -0
  174. package/src/postures/assistant.md +12 -0
  175. package/src/postures/expert.md +11 -0
  176. package/src/postures/mentor.md +11 -0
  177. package/src/postures/peer.md +12 -0
  178. package/src/skills/_template.md +47 -0
  179. package/src/skills/brainstorm.md +28 -0
  180. package/src/skills/clarify.md +28 -0
  181. package/src/skills/codebase-design.md +44 -0
  182. package/src/skills/commit.md +48 -0
  183. package/src/skills/council.md +34 -0
  184. package/src/skills/crash-course.md +28 -0
  185. package/src/skills/daydream/.claude-plugin/plugin.json +9 -0
  186. package/src/skills/daydream/SKILL.md +74 -0
  187. package/src/skills/daydream/VENDOR.md +25 -0
  188. package/src/skills/daydream/critic-prompt.md +38 -0
  189. package/src/skills/daydream/instructions.md +422 -0
  190. package/src/skills/daydream/synthesizer-prompt.md +41 -0
  191. package/src/skills/debug.md +37 -0
  192. package/src/skills/decode.md +28 -0
  193. package/src/skills/develop.md +29 -0
  194. package/src/skills/document-project.md +79 -0
  195. package/src/skills/domain-modeling.md +38 -0
  196. package/src/skills/drill.md +28 -0
  197. package/src/skills/feynman.md +26 -0
  198. package/src/skills/forge-mcp.md +48 -0
  199. package/src/skills/fresh-eyes.md +29 -0
  200. package/src/skills/frontend-design.md +58 -0
  201. package/src/skills/gap-detector.md +27 -0
  202. package/src/skills/geneseed-code-review.md +33 -0
  203. package/src/skills/geneseed.md +29 -0
  204. package/src/skills/git-archaeology.md +47 -0
  205. package/src/skills/git-rescue.md +68 -0
  206. package/src/skills/handoff.md +29 -0
  207. package/src/skills/herdr.md +164 -0
  208. package/src/skills/ingest.md +49 -0
  209. package/src/skills/learning-path.md +26 -0
  210. package/src/skills/migrate.md +45 -0
  211. package/src/skills/opencode-theme.md +52 -0
  212. package/src/skills/parallel-agents.md +28 -0
  213. package/src/skills/pipeline.md +52 -0
  214. package/src/skills/plan.md +45 -0
  215. package/src/skills/ponytail.md +29 -0
  216. package/src/skills/profile.md +58 -0
  217. package/src/skills/prose.md +42 -0
  218. package/src/skills/prototype.md +44 -0
  219. package/src/skills/react-view-transitions/AGENTS.md +955 -0
  220. package/src/skills/react-view-transitions/README.md +42 -0
  221. package/src/skills/react-view-transitions/SKILL.md +320 -0
  222. package/src/skills/react-view-transitions/VENDOR.md +16 -0
  223. package/src/skills/react-view-transitions/metadata.json +12 -0
  224. package/src/skills/react-view-transitions/references/css-recipes.md +242 -0
  225. package/src/skills/react-view-transitions/references/implementation.md +182 -0
  226. package/src/skills/react-view-transitions/references/nextjs.md +176 -0
  227. package/src/skills/react-view-transitions/references/patterns.md +262 -0
  228. package/src/skills/refactor.md +32 -0
  229. package/src/skills/release.md +43 -0
  230. package/src/skills/repo-map.md +36 -0
  231. package/src/skills/research.md +42 -0
  232. package/src/skills/review-response.md +36 -0
  233. package/src/skills/roast-me.md +28 -0
  234. package/src/skills/rule.md +100 -0
  235. package/src/skills/ship.md +49 -0
  236. package/src/skills/tdd.md +31 -0
  237. package/src/skills/tickets.md +44 -0
  238. package/src/skills/token-report/SKILL.md +76 -0
  239. package/src/skills/token-report/VENDOR.md +23 -0
  240. package/src/skills/token-report/scripts/token_report.mjs +1301 -0
  241. package/src/skills/wayfinder.md +49 -0
  242. package/src/skills/wiki.md +68 -0
  243. package/src/skills/workflow.md +38 -0
  244. package/themes/README.md +69 -0
  245. package/themes/_TEMPLATE.json +147 -0
  246. package/themes/biker.json +147 -0
  247. package/themes/commentator.json +147 -0
  248. package/themes/cyberpunk.json +147 -0
  249. package/themes/gamer.json +147 -0
  250. package/themes/imperial.json +147 -0
  251. package/themes/joker.json +147 -0
  252. package/themes/marvin.json +147 -0
  253. package/themes/mean.json +147 -0
  254. package/themes/military.json +147 -0
  255. package/themes/neutral.json +147 -0
  256. package/themes/opencode/README.md +58 -0
  257. package/themes/opencode/catppuccin.json +27 -0
  258. package/themes/opencode/dracula.json +27 -0
  259. package/themes/opencode/everforest.json +27 -0
  260. package/themes/opencode/gruvbox.json +27 -0
  261. package/themes/opencode/kanagawa.json +27 -0
  262. package/themes/opencode/neon.json +27 -0
  263. package/themes/opencode/nord.json +27 -0
  264. package/themes/opencode/rosepine.json +27 -0
  265. package/themes/opencode/tokyonight.json +27 -0
  266. package/themes/pirate.json +147 -0
  267. package/themes/sports.json +147 -0
  268. package/themes/verstappen.json +147 -0
  269. package/themes/wizard.json +147 -0
  270. package/web/dist/assets/About-DX1-VTBP.js +1 -0
  271. package/web/dist/assets/Activity-Dp9NaXOn.js +1 -0
  272. package/web/dist/assets/ActivityDetail-HpOBtrXS.js +1 -0
  273. package/web/dist/assets/Diff-Ct4G3Se8.js +5 -0
  274. package/web/dist/assets/Doctor-DGjkZFuA.js +1 -0
  275. package/web/dist/assets/Graph-b8o-S6kv.js +1 -0
  276. package/web/dist/assets/Harnesses-gr3-aHBF.js +1 -0
  277. package/web/dist/assets/Laws-DTwF5tTC.js +1 -0
  278. package/web/dist/assets/Library-BEZscyaQ.js +1 -0
  279. package/web/dist/assets/Markdown-k_LSLBGq.js +1 -0
  280. package/web/dist/assets/Profile-DydukTxP.js +1 -0
  281. package/web/dist/assets/Rules-CIRG4Ldt.js +1 -0
  282. package/web/dist/assets/Skills-Buoi1IBr.js +1 -0
  283. package/web/dist/assets/StatusBadge-CE_AJttl.js +1 -0
  284. package/web/dist/assets/Themes-CI4o3gJC.js +2 -0
  285. package/web/dist/assets/activity-BCW7e6Cy.js +1 -0
  286. package/web/dist/assets/audiowide-latin-400-normal-6GFCX7ni.woff2 +0 -0
  287. package/web/dist/assets/geist-mono-latin-400-normal-DKaoCDn5.woff2 +0 -0
  288. package/web/dist/assets/geist-mono-latin-500-normal-C3sF8Y1B.woff2 +0 -0
  289. package/web/dist/assets/geist-mono-latin-600-normal-BHzjB6_C.woff2 +0 -0
  290. package/web/dist/assets/hanken-grotesk-latin-400-italic-Bserb8X5.woff2 +0 -0
  291. package/web/dist/assets/hanken-grotesk-latin-400-normal-BG6hkEXj.woff2 +0 -0
  292. package/web/dist/assets/hanken-grotesk-latin-500-italic-BGfwwhek.woff2 +0 -0
  293. package/web/dist/assets/hanken-grotesk-latin-500-normal-DrDcrrxK.woff2 +0 -0
  294. package/web/dist/assets/hanken-grotesk-latin-600-normal-CIXX6EOa.woff2 +0 -0
  295. package/web/dist/assets/hanken-grotesk-latin-700-normal-CeQ8H3UY.woff2 +0 -0
  296. package/web/dist/assets/ibm-plex-mono-latin-400-normal-DMJ8VG8y.woff2 +0 -0
  297. package/web/dist/assets/ibm-plex-mono-latin-500-normal-DSY6xOcd.woff2 +0 -0
  298. package/web/dist/assets/ibm-plex-mono-latin-600-normal-BgSNZQsw.woff2 +0 -0
  299. package/web/dist/assets/ibm-plex-serif-latin-400-normal-BIGslYFI.woff2 +0 -0
  300. package/web/dist/assets/ibm-plex-serif-latin-500-normal-REKAfBVG.woff2 +0 -0
  301. package/web/dist/assets/ibm-plex-serif-latin-600-normal-DAxitmSu.woff2 +0 -0
  302. package/web/dist/assets/index-B1PIx7RM.js +1 -0
  303. package/web/dist/assets/index-BnTQUSUz.js +12 -0
  304. package/web/dist/assets/index-Ck2iCdaC.js +2 -0
  305. package/web/dist/assets/index-DUCsDv7z.css +1 -0
  306. package/web/dist/assets/inter-latin-400-normal-C38fXH4l.woff2 +0 -0
  307. package/web/dist/assets/inter-latin-500-normal-Cerq10X2.woff2 +0 -0
  308. package/web/dist/assets/inter-latin-600-normal-LgqL8muc.woff2 +0 -0
  309. package/web/dist/assets/inter-latin-700-normal-Yt3aPRUw.woff2 +0 -0
  310. package/web/dist/assets/jetbrains-mono-latin-400-normal-V6pRDFza.woff2 +0 -0
  311. package/web/dist/assets/jetbrains-mono-latin-500-normal-BWZEU5yA.woff2 +0 -0
  312. package/web/dist/assets/jetbrains-mono-latin-600-normal-C8RAYTDA.woff2 +0 -0
  313. package/web/dist/assets/marked.esm-JKvyS0Pp.js +46 -0
  314. package/web/dist/assets/oswald-latin-400-normal-BAFo8sP8.woff2 +0 -0
  315. package/web/dist/assets/oswald-latin-500-normal-B-eyT0Dw.woff2 +0 -0
  316. package/web/dist/assets/oswald-latin-600-normal-plFmSr5g.woff2 +0 -0
  317. package/web/dist/assets/oswald-latin-700-normal-vy6hmKSr.woff2 +0 -0
  318. package/web/dist/assets/poppins-latin-400-normal-cpxAROuN.woff2 +0 -0
  319. package/web/dist/assets/poppins-latin-500-normal-C8OXljZJ.woff2 +0 -0
  320. package/web/dist/assets/poppins-latin-600-normal-zEkxB9Mr.woff2 +0 -0
  321. package/web/dist/assets/poppins-latin-700-normal-Qrb0O0WB.woff2 +0 -0
  322. package/web/dist/assets/react-DOpiTn5v.js +32 -0
  323. package/web/dist/assets/roman-DkYN0LX9.js +1 -0
  324. package/web/dist/assets/space-grotesk-latin-400-normal-CJ-V5oYT.woff2 +0 -0
  325. package/web/dist/assets/space-grotesk-latin-500-normal-lFbtlQH6.woff2 +0 -0
  326. package/web/dist/assets/space-grotesk-latin-600-normal-DjKNqYRj.woff2 +0 -0
  327. package/web/dist/assets/space-grotesk-latin-700-normal-RjhwGPKo.woff2 +0 -0
  328. package/web/dist/assets/space-mono-latin-400-italic-YylcN9Ay.woff2 +0 -0
  329. package/web/dist/assets/space-mono-latin-400-normal-Rg4St2Dn.woff2 +0 -0
  330. package/web/dist/assets/space-mono-latin-700-italic-vNvENeTh.woff2 +0 -0
  331. package/web/dist/assets/space-mono-latin-700-normal-mWgeinG7.woff2 +0 -0
  332. package/web/dist/icon-maskable.svg +10 -0
  333. package/web/dist/icon.svg +8 -0
  334. package/web/dist/index.html +21 -0
  335. package/web/dist/manifest.webmanifest +14 -0
  336. package/web/dist/sw.js +40 -0
  337. package/web/src/pages/Laws.jsx +230 -0
@@ -0,0 +1,175 @@
1
+ /**
2
+ * `rituals/_harness_tui.py`'s CATALOG half — the taxonomy tables, the rendered-laws
3
+ * parser, the entity registry, and the render-accurate inventory the TUI, the `status`
4
+ * panel and the web console all read.
5
+ *
6
+ * WHY THIS FILE EXISTS RATHER THAN A THIRD COPY OF THE TABLES. `LAW_CLASS`, `SKILL_CLASS`,
7
+ * `LAW_CLASSES` and `ENTITY_STATUSES` crossed in P5g, inside `js/doctor.mjs`, because
8
+ * doctor's authoring gates are what validate them — and `js/status.mjs`'s docblock said
9
+ * flatly that "the taxonomy P7 owns" was not ported, which was true of `_parse_laws` and
10
+ * `entity_status` and had stopped being true of the tables. P6c needs all of it, so the
11
+ * tables move HERE, to the module that mirrors where Python keeps them, and `js/doctor.mjs`
12
+ * imports them. A copy of a value under test silently stops being the value under test.
13
+ *
14
+ * AND `inventoryCounts` FOLDS BACK INTO `tuiInventory`. P5d shipped a counting-only twin
15
+ * with a docblock warning that the two must not become two classifiers; this is the phase
16
+ * that would have made them two, because `api_catalog` consumes the very fields the count
17
+ * threw away. So there is one classifier — "a two-part relative path ending in `.md` and
18
+ * not starting with `_`, under `agents/` or `skills/`" — and `inventoryCounts` is three
19
+ * `length`s off it. The eleven `status` cells gate the counts; P6c's catalog cells gate
20
+ * the fields; both run over the same walk.
21
+ */
22
+ import path from 'node:path';
23
+
24
+ import { ROOT, SRC, makeCfg } from './checkout.mjs';
25
+ import { firstBlockquote } from './native.mjs';
26
+ import { renderAll } from './render.mjs';
27
+ import { pyResolve } from './hosts.mjs';
28
+ import { parseJson, readText } from './lib/fs.mjs';
29
+
30
+ /**
31
+ * `_harness_tui.LAW_HEADING_RE` — a heading in the RENDERED laws file, e.g.
32
+ * `### Rule XVIII — Load the Project Context`.
33
+ *
34
+ * Not `js/doctor.mjs`'s `LAW_HEADING_RE`, which matches the `{{LAW}}` token in the
35
+ * unrendered source. Two patterns, two inputs, two names in Python as well.
36
+ */
37
+ export const LAW_HEADING_RE = /^###\s+\S+\s+([IVXLCDM]+)\s+[—-]\s+(.+?)\s*$/;
38
+
39
+ /** `_harness_tui.LAW_CLASS` — each rule's class, keyed by Roman numeral. */
40
+ export const LAW_CLASS = {
41
+ I: 'security', II: 'process', III: 'verify', IV: 'security', V: 'craft',
42
+ VI: 'context', VII: 'verify', VIII: 'comms', IX: 'comms', X: 'comms',
43
+ XI: 'craft', XII: 'craft', XIII: 'craft', XIV: 'process', XV: 'process',
44
+ XVI: 'context', XVII: 'context', XVIII: 'context', XIX: 'context', XX: 'security',
45
+ XXI: 'process', XXII: 'security', XXIII: 'security', XXIV: 'craft', XXV: 'craft',
46
+ XXVI: 'craft', XXVII: 'verify', XXVIII: 'process', XXIX: 'comms', XXX: 'comms',
47
+ XXXI: 'comms', XXXII: 'craft', XXXIII: 'craft', XXXIV: 'verify', XXXV: 'verify',
48
+ XXXVI: 'security', XXXVII: 'process',
49
+ };
50
+
51
+ /** `_harness_tui.ENTITY_STATUSES` — the lifecycle statuses `registry.json` may carry. */
52
+ export const ENTITY_STATUSES = ['experimental', 'approved', 'deprecated'];
53
+
54
+ /** `_harness_tui.LAW_CLASSES` — the six governance classes a law may carry. */
55
+ export const LAW_CLASSES = ['security', 'process', 'verify', 'craft', 'context', 'comms'];
56
+
57
+ /** `_harness_tui.SKILL_CLASS` — each skill's category, keyed by file stem. */
58
+ export const SKILL_CLASS = {
59
+ brainstorm: 'design', clarify: 'design', plan: 'design', council: 'design',
60
+ workflow: 'design', 'parallel-agents': 'design', pipeline: 'design',
61
+ 'codebase-design': 'design', 'domain-modeling': 'design', wayfinder: 'design',
62
+ tickets: 'design',
63
+ tdd: 'build', develop: 'build', refactor: 'build', debug: 'build', migrate: 'build',
64
+ 'frontend-design': 'build', 'opencode-theme': 'build', prototype: 'build',
65
+ 'forge-mcp': 'build',
66
+ 'geneseed-code-review': 'review', 'fresh-eyes': 'review', 'gap-detector': 'review',
67
+ 'roast-me': 'review', 'review-response': 'review', ponytail: 'review',
68
+ commit: 'ship', ship: 'ship', release: 'ship', handoff: 'ship', 'git-rescue': 'ship',
69
+ 'repo-map': 'understand', 'git-archaeology': 'understand', decode: 'understand',
70
+ research: 'understand', ingest: 'understand', 'document-project': 'understand',
71
+ wiki: 'understand', prose: 'understand', geneseed: 'understand', rule: 'understand',
72
+ profile: 'understand', herdr: 'understand',
73
+ 'crash-course': 'learn', drill: 'learn', feynman: 'learn', 'learning-path': 'learn',
74
+ };
75
+
76
+ /** `k in dict` — own keys only, where `k in obj` also finds `Object.prototype` members. */
77
+ const has = (obj, k) => Object.hasOwn(obj, k);
78
+
79
+ /**
80
+ * `_harness_tui._parse_laws` — the rendered laws file split into
81
+ * `{num, title, klass, body}`.
82
+ *
83
+ * The accumulator appends `line + "\n"` to every non-heading line INCLUDING the ones
84
+ * before the first heading, which are discarded because `cur` is still None — and then
85
+ * strips each body at the end. Reproduced literally: a body's internal blank lines are
86
+ * kept and only its ends are trimmed.
87
+ */
88
+ export function parseLaws(text) {
89
+ const laws = [];
90
+ let cur = null;
91
+ for (const line of text.split('\n')) {
92
+ const m = LAW_HEADING_RE.exec(line);
93
+ if (m) {
94
+ if (cur) laws.push(cur);
95
+ cur = { num: m[1], title: m[2], klass: has(LAW_CLASS, m[1]) ? LAW_CLASS[m[1]] : 'craft', body: '' };
96
+ } else if (cur !== null) {
97
+ cur.body += `${line}\n`;
98
+ }
99
+ }
100
+ if (cur) laws.push(cur);
101
+ // `str.strip()`. `trim()`'s whitespace set differs from Python's only at U+FEFF, which
102
+ // is the standing item this port has carried since P4 — a rendered law body cannot end
103
+ // in a BOM, and a fourth primitive to say so would cost more than it gates.
104
+ for (const law of laws) law.body = law.body.trim();
105
+ return laws;
106
+ }
107
+
108
+ /**
109
+ * `_harness_tui.load_registry` — the `entities` map from `registry.json`, or `{}`.
110
+ *
111
+ * Deliberately forgiving on BOTH failure modes, as the reference is: a missing file and a
112
+ * corrupt one both yield `{}`, which reads every badge as "unknown" rather than breaking
113
+ * the browser. `registryProblems` in `js/doctor.mjs` is the loud reader of the same file
114
+ * and stays separate — the two answer different questions.
115
+ */
116
+ export function loadRegistry() {
117
+ let doc;
118
+ try {
119
+ doc = parseJson(readText(path.join(ROOT, 'registry.json')));
120
+ } catch {
121
+ return {};
122
+ }
123
+ const entities = doc && typeof doc === 'object' && !Array.isArray(doc) ? doc.entities : null;
124
+ return entities && typeof entities === 'object' && !Array.isArray(entities) ? entities : {};
125
+ }
126
+
127
+ /**
128
+ * `_harness_tui.entity_status` — one entity's lifecycle status, plus the two derived
129
+ * states that are never stored.
130
+ *
131
+ * An entity the registry has never heard of is "personal": your own skill dropped into the
132
+ * install, which Geneseed never shipped. An EMPTY registry means the file was missing or
133
+ * corrupt, so everything reads "unknown" there instead of relabelling the whole shipped
134
+ * catalogue as yours — which is why the empty check is on the registry and not on the row.
135
+ */
136
+ export function entityStatus(registry, key) {
137
+ if (!has(registry, key)) {
138
+ return Object.keys(registry).length ? 'personal' : 'unknown';
139
+ }
140
+ const row = registry[key];
141
+ const status = (row && typeof row === 'object' && !Array.isArray(row)) ? row.status : null;
142
+ return ENTITY_STATUSES.includes(status) ? status : 'unknown';
143
+ }
144
+
145
+ /**
146
+ * `_harness_tui._tui_inventory` — render-accurate inventory: every agent and skill with
147
+ * its one-line purpose, full rendered spec, source path and lifecycle badge, and every law
148
+ * with its title, body and governance class.
149
+ */
150
+ export function tuiInventory(themeName) {
151
+ const { items } = renderAll(makeCfg(), themeName);
152
+ const registry = loadRegistry();
153
+ const agents = [];
154
+ const skills = [];
155
+ let laws = [];
156
+ for (const { text, src } of items) {
157
+ if (text === null) continue;
158
+ const parts = path.relative(SRC, src).split(path.sep);
159
+ if (parts.length === 2 && parts[1].endsWith('.md') && !parts[1].startsWith('_')) {
160
+ const name = parts[1].slice(0, -3);
161
+ const entry = { name, desc: firstBlockquote(text), body: text,
162
+ source: pyResolve(src), status: entityStatus(registry, `${parts[0]}/${name}`) };
163
+ if (parts[0] === 'agents') agents.push(entry);
164
+ else if (parts[0] === 'skills') {
165
+ entry.klass = has(SKILL_CLASS, name) ? SKILL_CLASS[name] : 'build';
166
+ skills.push(entry);
167
+ }
168
+ }
169
+ if (parts[parts.length - 1] === 'universal.md') laws = parseLaws(text);
170
+ }
171
+ const byName = (a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0);
172
+ agents.sort(byName);
173
+ skills.sort(byName);
174
+ return { agents, skills, laws, theme: themeName };
175
+ }