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
package/SETUP.md ADDED
@@ -0,0 +1,1027 @@
1
+ <div align="center">
2
+
3
+ # 🧬 Geneseed — Setup Guide
4
+
5
+ **From bare repository to a disciplined agent in a few minutes.**
6
+
7
+ [← Back to README](README.md) · [Design](DESIGN.md) · [OpenCode adapter](adapters/opencode/README.md) · [Claude Code adapter](adapters/claude-code/README.md)
8
+
9
+ </div>
10
+
11
+ > **In a hurry?** The 5-minute recommended path is **[QUICKSTART.md](QUICKSTART.md)**.
12
+ > This page is the full reference: every install path, knob, and troubleshooting step.
13
+
14
+ ---
15
+
16
+ You pick a **theme** — the voice and vocabulary the harness wears — and an **install mode**;
17
+ the build implants the gene-seed and the agent wakes speaking in that voice. Pick the path
18
+ that matches your tool, then configure and verify. For the conceptual overview see the
19
+ [README](README.md); for OpenCode internals see [adapters/opencode/](adapters/opencode/README.md).
20
+
21
+ ## 📋 Prerequisites
22
+
23
+ - **Node ≥ 22.3** — the only hard requirement. Geneseed ships as an npm package with
24
+ **zero dependencies**; `npx geneseed` needs nothing else.
25
+ - **Your agent tool** — OpenCode (recommended), Claude Code, Bob, Copilot, or anything
26
+ that reads a root instructions file.
27
+ - *Only for a git checkout:* **git**. Nothing else — a checkout runs the same Node
28
+ entry points the npm package installs.
29
+ - *Optional, for the `ingest` skill:* a document converter — **MarkItDown**, Pandoc,
30
+ or Docling — if you want the agent to read PDFs/Office files (see
31
+ [Reading non-markdown docs](#reading-non-markdown-docs)).
32
+
33
+ ### 🟩 One runtime — Node, and nothing else
34
+
35
+ Nothing in this guide needs a second interpreter. Three things are worth stating plainly,
36
+ because each is a live constraint rather than a footnote:
37
+
38
+ - **0 commands have no Node twin**: every command in this guide answers from the Node
39
+ entry points. There is no full-screen browse panel: `geneseed tui` and `geneseed menu`
40
+ are verbs that say the panel is not here and print the command list instead, and off a
41
+ terminal (which is how scripts and CI run them) the bytes and the exit code are the
42
+ recorded ones. `home` opens the web console, which is the visual front end.
43
+ - **Nothing you install needs an interpreter.** The `token-report` skill is a script
44
+ rather than prose, and it ships as `scripts/token_report.mjs`, run with `node`;
45
+ `daydream` and `herdr` hand their inline code to `node -e`.
46
+ So **every bundle carries** nothing that needs one: no Python file, and no skill that
47
+ shells out to an interpreter — on any host, any theme, either footprint. Three tests
48
+ freeze that, down to a byte-for-byte replay of the report script over seeded
49
+ transcripts for all four hosts.
50
+ - **The self-update commands are for a git checkout.** `upgrade`, `update`, `sync-self`
51
+ and `bootstrap` `git pull` the install's own origin. From an npm install they stop
52
+ before touching anything and name `npm install -g geneseed@latest` instead.
53
+
54
+ One more, in the web console rather than the CLI: the **"browse…" folder picker** would
55
+ open an OS-native dialog on the machine running the daemon, and the server declines to.
56
+ The button reports itself unavailable and the path field beside it stays editable.
57
+
58
+ ## 🛣️ Choose your path
59
+
60
+ **Easiest:** `npx geneseed setup` — no clone, nothing installed permanently.
61
+ It runs the same guided wizard as a checkout does: it asks for a theme and an install
62
+ mode, runs the right build, and offers a health check. To keep the command around, put
63
+ it on PATH with `npm install -g geneseed`.
64
+
65
+ **From a clone:** `./geneseed setup` on macOS/Linux, `.\geneseed.cmd setup` on Windows.
66
+ It is the same dependency-free wizard the npx route runs — plain text prompts, every
67
+ console, every OS.
68
+
69
+ **Already installed from a clone, and moving to npm?** `geneseed migrate` re-emits every
70
+ install you already have onto the npm shape in a single all-or-nothing pass, keeping each
71
+ one's own theme, emit, footprint, posture and mode. `--dry-run` prints the plan and
72
+ writes nothing. It **reports rather than rewrites** anything it did not create — your own
73
+ hooks, third-party hooks, and the login autostart entry you hand-wrote. Your old clone
74
+ keeps working for a full release; there is no cliff.
75
+ See [Migrate an existing install](docs/web/migrate.md).
76
+
77
+ As you move through the theme picker the wizard **previews each theme live** — its
78
+ tagline, loaded-sigil, and voice — so you hear the flavour before you choose; once
79
+ you pick, it speaks in that theme's accent through confirm and build, and the
80
+ install ends on the theme's own **banner and benediction**.
81
+
82
+ **Already installed?** Bare **`./geneseed`** (Windows: `.\geneseed.cmd`) opens the
83
+ **web console**, which is where browsing, local edits, rebuilds, memory, status, MCP
84
+ servers and uninstall all live — see [The web console](docs/web-ui.md). `GENESEED_NO_WEB=1`
85
+ suppresses that and prints the command list instead. Uninstall from the CLI is
86
+ `geneseed uninstall --target <repo>` (bare `--target` runs against whichever project
87
+ install the cwd sits in). **`./geneseed bootstrap`** jumps straight to
88
+ update-then-setup; **`./geneseed setup`** straight to the wizard. Prefer to do it by
89
+ hand? Pick a path below.
90
+
91
+ | Path | Use when |
92
+ | --- | --- |
93
+ | [A — OpenCode, global](#path-a--opencode-global-recommended) | **Recommended.** One install, every repo inherits it, nothing committed into projects. |
94
+ | [B — OpenCode, per-repo](#path-b--opencode-per-repo) | You want a committed `.opencode/` layer in one repository. |
95
+ | [C — Claude Code](#path-c--claude-code) | You drive Claude Code and want the lifecycle hooks. |
96
+ | [C′ — GitHub Copilot](#path-c--github-copilot) | You drive the Copilot CLI, coding agent, or VS Code agent mode. |
97
+ | [D — Any `AGENT.md` tool](#path-d--any-agentmd-tool) | Cursor, Aider, or any tool that reads a root instructions file. |
98
+ | [E — No runtime on the target at all](#path-e--no-runtime-on-the-target-at-all) | The machine that *uses* the harness cannot run Node. |
99
+
100
+ > **Every `geneseed-build …` below is the generator.** `npm install -g geneseed` puts it
101
+ > on your `PATH`; without installing anything, `npx -p geneseed geneseed-build --emit
102
+ > opencode-global` is the same command. From a checkout it is
103
+ > `node bin/geneseed.mjs` with the same flags. Its output is replayed byte for byte
104
+ > against frozen recordings on every commit, across every theme × host × footprint
105
+ > combination.
106
+
107
+ ---
108
+
109
+ ### Path A — OpenCode, global (recommended)
110
+
111
+ Installs the whole harness into OpenCode's config dir; every repo you open inherits it.
112
+
113
+ ```
114
+ # from inside the Geneseed folder
115
+ geneseed-build --emit opencode-global # add --theme imperial for the 40k voice
116
+ # GENESEED_HARNESS is optional — the learn plugin auto-locates the in-config memory
117
+ # store. Set it only to pin the location explicitly (and persist it to your rc):
118
+ export GENESEED_HARNESS="$HOME/.config/opencode"
119
+ echo 'export GENESEED_HARNESS="$HOME/.config/opencode"' >> ~/.zshrc
120
+ ```
121
+
122
+ **Windows (PowerShell)** — identical, no bash/WSL needed:
123
+ ```powershell
124
+ # from inside the Geneseed folder
125
+ geneseed-build --emit opencode-global # add --theme imperial for the 40k voice
126
+ setx GENESEED_HARNESS "$env:USERPROFILE\.config\opencode" # optional; pins the memory store
127
+ ```
128
+ On Windows the config dir is the same homedir-relative path,
129
+ `C:\Users\<user>\.config\opencode` — OpenCode uses `~/.config/opencode` on every OS.
130
+
131
+ This writes into `$OPENCODE_CONFIG_DIR` (else `$XDG_CONFIG_HOME/opencode`, else
132
+ `~/.config/opencode`): `AGENT.md`, `agents/`, `skills/<name>/SKILL.md`, a single
133
+ `plugins/` copy, the `memory/` store, and a merged `opencode.json` pointing
134
+ `instructions` at the absolute `AGENT.md`. No `context.json` — the context plugin
135
+ auto-discovers each repo's docs.
136
+
137
+ It is **non-destructive**: a `.geneseed-manifest.json` tracks only the files it owns
138
+ and prunes stale ones on re-emit; your own agents/skills/plugins and the memory store
139
+ are never touched. Full design + checklist:
140
+ [GLOBAL-HARNESS-SPEC.md](adapters/opencode/GLOBAL-HARNESS-SPEC.md).
141
+
142
+ ### Path B — OpenCode, per-repo
143
+
144
+ ```
145
+ geneseed-build --emit opencode --target /path/to/your-repo
146
+ ```
147
+
148
+ Writes the full bundle (`AGENT.md`, `agents/`, `skills/`, `memory/`, `notebook/`)
149
+ plus the OpenCode-native layer (`opencode.json` and `.opencode/{agents,skills,plugins,workflows}`)
150
+ into the target dir. Commit them or not. **Want the bundle in a subfolder?** add `--root`
151
+ so instruction paths resolve from the project root:
152
+
153
+ ```
154
+ geneseed-build --emit opencode --out /path/to/repo/Harness --root /path/to/repo
155
+ ```
156
+
157
+ Depth, native mapping, and the manual fallback: [adapters/opencode/](adapters/opencode/README.md).
158
+
159
+ ### Path C — Claude Code
160
+
161
+ Merge [`adapters/claude-code/settings.json`](adapters/claude-code/settings.json) into
162
+ your repo's `.claude/settings.json` (paths assume the bundle is at the repo root).
163
+ It wires:
164
+
165
+ - **PreToolUse** (matcher `Bash`) — runs `harness git-gate`, a tool-boundary backstop
166
+ for Law XX. The hook inspects the command and forces an `ask` on every `git commit`
167
+ or `git push` (even chained or `-C`-flagged), un-suppressible by a one-time "don't
168
+ ask again". Every other Bash command is deferred to the normal permission flow.
169
+ - **SessionStart** (`startup`/`clear`) — prints `AGENT.md` and injects the project
170
+ context (`harness context`, which auto-discovers the repo's docs);
171
+ - **SessionStart** (`resume`) — refreshes the project context only, without re-printing
172
+ the static `AGENT.md`;
173
+ - **Stop** — runs `harness learn` to capture durable memory. Opt in by setting
174
+ `GENESEED_LLM` (e.g. `claude -p`); unset, it's a harmless no-op. Geneseed never
175
+ embeds an API key.
176
+
177
+ All four hooks are emitted as one stable path — the **hook shim** at
178
+ `~/.geneseed/bin/geneseed-hook` (`geneseed-hook.cmd` on Windows) — instead of writing
179
+ this machine's runtime and this checkout into your `settings.json`. The shim
180
+ carries those two volatile paths itself, so moving or replacing the clone no longer
181
+ breaks the hooks in every install at once: one `geneseed build` rewrites the shim and
182
+ every install is live again. It is refreshed on every emit, and `geneseed doctor`
183
+ reports it if it was ever stale. `GENESEED_HOME` relocates it.
184
+
185
+ Detail: [adapters/claude-code/](adapters/claude-code/README.md).
186
+
187
+ ### Sovereign repos — excluding folders from the global harness
188
+
189
+ Some repos are complete agent harnesses of their own (an Obsidian vault with its
190
+ own laws, hooks and memory conventions). Inside such a repo the global Geneseed
191
+ layer would stack on top of the local one — conflicting doctrine and wasted
192
+ tokens. Exclude the folder instead:
193
+
194
+ harness exclude add ~/Documents/git/Terra
195
+ harness exclude list
196
+ harness exclude remove ~/Documents/git/Terra
197
+
198
+ Inside an excluded folder the global install is fully dormant: the context,
199
+ learn and git-gate hooks exit silently (they check `<config dir>/excludes.json`
200
+ on every call — edits take effect immediately, no re-emit), and the global
201
+ preamble is suppressed natively (Claude: `claudeMdExcludes` written to the
202
+ repo's own `.claude/settings.local.json`; Bob: the workspace rules shadow stub;
203
+ OpenCode: the plugins stand down). Everything is reversed by `exclude remove`.
204
+
205
+ Limitations: GitHub Copilot has no per-repo suppression mechanism, so the global
206
+ `copilot-instructions.md` still loads there; and globally installed skills/
207
+ subagents remain listed by the host (no native per-repo disable exists). A
208
+ global install emitted later starts with an empty list — re-run
209
+ `harness exclude add` (`exclude list` flags installs that diverge).
210
+
211
+ ### Path C′ — GitHub Copilot
212
+
213
+ ```
214
+ geneseed-build --emit copilot-global # personal: render into ~/.copilot
215
+ geneseed-build --emit copilot --out . --root . # per-repo: AGENTS.md + .github/, committed
216
+ ```
217
+
218
+ Copilot is Claude-shaped where it counts: skills are the same `SKILL.md` folders
219
+ (Copilot's Agent Skills — `.github/skills/` in a repo, `~/.copilot/skills/`
220
+ personally), agents render in Copilot's own custom-agent dialect
221
+ (`agents/<name>.agent.md`, a `tools:` allowlist instead of Claude's denylist), and
222
+ the preamble rides a file Copilot auto-loads: the repo-root `AGENTS.md` (CLI, coding
223
+ agent, and VS Code agent mode) or the personal `~/.copilot/copilot-instructions.md`
224
+ (CLI). Two differences from the Claude paths:
225
+
226
+ - **No hooks.** Copilot has no settings.json or hook mechanism, so there is no
227
+ eager context injection and no `harness learn` Stop-hook — the memory convention
228
+ still applies, driven by the preamble's instructions alone.
229
+ - **The per-repo layer lives in the shared `.github/`** (Copilot's repo config
230
+ surface). Safe by construction: the ownership manifest + claim-on-create never
231
+ touch files Geneseed didn't write — your workflows and same-named agents/skills
232
+ survive every emit and uninstall.
233
+
234
+ MCP servers go in `~/.copilot/mcp-config.json` (the Settings/MCP screens know the
235
+ shape). `$COPILOT_CONFIG_DIR` relocates the personal dir, mirroring
236
+ `$BOB_CONFIG_DIR`. Note both carriers stack if you install globally *and* per-repo —
237
+ the global emit warns when that's about to happen.
238
+
239
+ ### Path D — Any `AGENT.md` tool
240
+
241
+ ```
242
+ geneseed-build # renders the plain bundle to ./Harness
243
+ ```
244
+
245
+ Point your tool's instructions/rules setting at `Harness/AGENT.md`. If the tool only
246
+ auto-loads a specific name, rename or symlink (`AGENT.md` → `AGENTS.md` / `CLAUDE.md`).
247
+ The rules work on agent self-discipline alone; the plugins (context, memory) are an
248
+ OpenCode convenience.
249
+
250
+ ### Path E — No runtime on the target at all
251
+
252
+ A maintainer runs it once, on a machine that can run Node:
253
+
254
+ ```
255
+ npx geneseed prompt --theme neutral > install-geneseed.md
256
+ ```
257
+
258
+ That emits a self-contained prompt that recreates the entire file tree verbatim.
259
+ Paste it into any capable agent on the target machine — nothing to install, no build step.
260
+ Any theme works the same way — substitute its name after `--theme`. The prompt is
261
+ always rendered fresh from `src/`, so it can never drift from the current harness.
262
+
263
+ ---
264
+
265
+ ## 🎛 Configure
266
+
267
+ ### Theme
268
+
269
+ Choose any of the 14 themes in `themes/` — `neutral` (plain), `imperial` (Warhammer 40k),
270
+ `military`, `pirate`, `wizard`, `cyberpunk`, `gamer`, `sports` (play-by-play),
271
+ `biker`, `commentator`, `joker`, `marvin`, `mean`, or `verstappen` — with
272
+ `--theme NAME` (the wizard lists them all with live previews). It is remembered in a
273
+ `.geneseed-theme` marker, so later upgrades keep it. Adding your own is one JSON file
274
+ of voice tokens; `doctor` checks every theme defines the same keys.
275
+
276
+ Adding a new voice token to `themes/_TEMPLATE.json` means all 14 theme files need it
277
+ too, or the parity check fails. `geneseed-build --sync-themes` does the mechanical
278
+ part: it copies any key the template has but a theme is missing into that theme
279
+ (filled with the template's placeholder text), in template order, and prints exactly
280
+ which keys were added so you can restyle them in that theme's voice. It never deletes
281
+ a key a theme has that the template doesn't — those are only reported. The edit is
282
+ surgical (only the inserted lines change; nothing is reformatted), and the exit code
283
+ doubles as a CI drift check: `1` when it had to change files, `0` when every theme was
284
+ already in sync, and `2` when `_TEMPLATE.json` itself is missing or unreadable — the one
285
+ case where a `0` would have meant "in sync" without having checked anything.
286
+
287
+ ### Footprint (lean vs full)
288
+
289
+ **Footprint** sets how much of the Rules `AGENT.md` carries *inline* on every turn — a
290
+ token-cost dial, not a change to which Rules apply. Both states keep all Rules in force:
291
+
292
+ - **full** (default) — Section 1 inlines every Rule's complete text *and* rationale.
293
+ Maximum guidance density; the largest always-loaded block in the harness.
294
+ - **lean** — Section 1 carries each Rule's heading + the rule line, then a pointer to the
295
+ full law file. ~40% smaller; the complete `laws/universal.md` still ships beside
296
+ `AGENT.md` and the agent reads it on demand (and is told to before acting on secrets,
297
+ deletion, git history, scope, or untrusted content).
298
+
299
+ **Why:** context is scarce and metered. Lean reclaims that budget — and the tokens you
300
+ pay for it — for the task, moving the *rationale* one read away while keeping the rules
301
+ themselves present. **Pros & cons:** full = always-present reasoning (better for smaller
302
+ models, zero indirection) at the highest token cost; lean = cheaper, leaner context every
303
+ turn at the cost of one extra fetch when a rule's nuance matters. Prefer **lean** for long
304
+ sessions, large repos, or cost-sensitive runs; keep **full** when cost is a non-issue or
305
+ you run a smaller model.
306
+
307
+ **Same harness, either way.** Footprint changes neither what the harness *is* nor what it
308
+ can *do*: lean and full emit identical files (same agents, skills, plugins, commands, memory,
309
+ notebook, hooks) and every Rule is present and binding. The only structural difference is
310
+ that a lean install on a global / Claude / Bob / Copilot target also ships the standalone
311
+ `laws/universal.md` (project bundles already carry it); the only behavioural difference is
312
+ that each Rule's reasoning loads on demand instead of every turn. Lean is the default;
313
+ full, with the rationale always in front of the model, applies a rule's nuance more
314
+ reliably on subtle edge cases or with a weaker model, and is one flag away.
315
+
316
+ Set it with `--footprint lean|full` (alongside any `--emit`), the **Footprint** toggle in
317
+ the web Settings, the per-harness dropdown in the Harnesses tab, or the setup wizard. It is
318
+ remembered in a `.geneseed-footprint` marker and preserved across every rebuild, on every
319
+ host (OpenCode, Claude Code, Bob, Copilot).
320
+
321
+ ### Dry-run a build (`validate`)
322
+
323
+ ```
324
+ geneseed validate --theme imperial --emit opencode --out /path/to/repo/Harness
325
+ ```
326
+
327
+ (It is a verb on the CLI rather than a flag on the generator because it runs `doctor`, and
328
+ the generator is deliberately unable to start a process. `geneseed-build --validate-only
329
+ …` is the same tool with the same flags.)
330
+
331
+ Renders and emits the requested `--theme`/`--emit`/`--out`/`--root`/`--footprint`
332
+ combination into a throwaway sandbox — nothing under the real `--out`/`--root` is
333
+ written, no marker files, no settings merge, no install-registry record — then runs
334
+ every doctor-grade check against it (unresolved tokens, dead/non-hermetic links, theme
335
+ parity, authoring gates, AGENT.md table parity). Prints a per-layer file count of what
336
+ would have been written (`-v`/`--verbose` for the full path list) and exits non-zero on
337
+ any problem, `0` when clean. Useful in CI, or before pointing a real deploy at a repo you
338
+ don't want to touch yet.
339
+
340
+ ### Project context (usually nothing)
341
+
342
+ On OpenCode the context plugin auto-discovers a repo's docs every session:
343
+
344
+ - **Eager** (injected in full, budget-capped): root `AGENTS.md`/`AGENT.md`/`CLAUDE.md`/
345
+ `.cursorrules`, `README.md`, `CONTRIBUTING.md`.
346
+ - **Lazy** (listed, read on demand): `docs/`, `doc/`, `documentation/`, `architecture/`,
347
+ `adr/`, `ADR/`, monorepo `packages/*/README.md` and `apps/*/README.md`, other root
348
+ `*.md`. `node_modules`, `.git`, `dist`, `build`, `vendor`, `.next`, `target`,
349
+ `.venv`, `__pycache__`, `.opencode`, and `.harness` are never scanned.
350
+
351
+ Override only when the convention doesn't fit — drop a `.harness/context.json` (or
352
+ `./context.json`, or point `$GENESEED_CONTEXT`):
353
+
354
+ ```json
355
+ {
356
+ "extend": true,
357
+ "context": [
358
+ { "path": "docs/house-rules.md", "load": "eager", "description": "Branch policy, DoD." },
359
+ { "path": "docs/**/*.md", "load": "lazy" },
360
+ { "path": "internal/secrets.md", "load": "exclude" }
361
+ ]
362
+ }
363
+ ```
364
+
365
+ `path` is absolute, repo-relative, or a glob; `load` is `eager` | `lazy` | `exclude`;
366
+ `"extend": true` layers the manifest on top of discovery. Schema:
367
+ [GLOBAL-HARNESS-SPEC.md §3](adapters/opencode/GLOBAL-HARNESS-SPEC.md).
368
+
369
+ #### 📌 Worked example — a monorepo's `context.json`
370
+
371
+ The harness stays lean because project knowledge does not go into it — it goes
372
+ into this per-repo manifest, which the context plugin auto-loads at session
373
+ start. A monorepo with docs scattered across packages might write:
374
+
375
+ ```json
376
+ {
377
+ "extend": true,
378
+ "context": [
379
+ { "path": "docs/architecture.md", "load": "eager", "description": "system map" },
380
+ { "path": "api/README.md", "load": "eager" },
381
+ { "path": "web/README.md", "load": "eager" }
382
+ ]
383
+ }
384
+ ```
385
+
386
+ `"extend": true` keeps auto-discovery running (so `README.md`, `AGENT.md`, and
387
+ the rest of the convention still apply) and layers these three eager entries on
388
+ top. Keep the eager list to the few files a new teammate would read first —
389
+ each `eager` entry is injected in full into every session in this repo, so it
390
+ has a permanent token cost; prefer three sharp docs over ten broad ones, and
391
+ reach for `"load": "lazy"` for anything a session should only read on demand.
392
+
393
+ **Self-orientation extras.** The same injected block also carries two best-effort
394
+ lines so the agent starts oriented: the repo's **runnable commands** (targets from
395
+ `Makefile`, `package.json` scripts — with the right runner per lockfile — `justfile`,
396
+ and `Taskfile`), and the session's **current model** (read from the transcript, or
397
+ `GENESEED_MODEL=provider/model` as a fallback). Both degrade silently when absent —
398
+ no commands file, no known model → the line is simply omitted.
399
+
400
+ **Delivery — invisible by default.** The plugin delivers the context by prepending
401
+ it to each outgoing request via OpenCode's `experimental.chat.messages.transform`
402
+ hook: nothing shows in the conversation, and the context survives compaction
403
+ inherently because it is re-sent per request. The hook is experimental — on an
404
+ OpenCode build that lacks it, the plugin notices the first time a request completes
405
+ without it and **falls back automatically** to the classic visible delivery (the
406
+ `PROJECT CONTEXT` block posted as a session message), so no build is ever left
407
+ without context; `GENESEED_DEBUG=1` logs the fallback when it engages. Prefer to
408
+ *see* what the agent received? Set `GENESEED_CONTEXT_VISIBLE=1` (persist with
409
+ `export` in your rc, or `setx` on Windows) to force the visible block up front —
410
+ legacy `GENESEED_CONTEXT_TRANSFORM=0`/`off` does the same, while `=1`, the old
411
+ opt-in, now simply matches the default. To drop injection entirely, set
412
+ `GENESEED_CONTEXT_INJECT=off` and rely on the AGENT.md law.
413
+
414
+ ### Wiki — your own knowledge base (optional)
415
+
416
+ If you keep a personal knowledge base on this machine — an Obsidian vault, or any
417
+ folder of interlinked markdown — declare it once in **`wiki.jsonc`** and the agent
418
+ becomes a citizen of it: entry notes load each session (eager) or on demand (lazy),
419
+ and it reads *and writes* notes under your vault's own conventions (AGENT.md §7,
420
+ the `wiki` skill). Unlike `context.json` this is **per machine, not per repo**.
421
+
422
+ The build seeds `wiki.jsonc` beside `AGENT.md` (for a global install:
423
+ `~/.config/opencode/wiki.jsonc`) and never overwrites it. The file is **JSONC** —
424
+ comments and trailing commas are fine — and the seeded stub carries this very
425
+ example commented out, ready to copy and edit in place. Resolution:
426
+ `$GENESEED_WIKI` → `$GENESEED_HARNESS/wiki.jsonc` → beside the installed `AGENT.md`
427
+ (a `wiki.json` from an earlier install is still honoured at each location).
428
+ Fill it in:
429
+
430
+ ```json
431
+ {
432
+ "wikis": [{
433
+ "name": "Brain",
434
+ "path": "/home/me/Documents/Brain",
435
+ "description": "my machine-wide knowledge base",
436
+ "entries": [
437
+ { "path": "ARCHITECTURE.md", "load": "eager", "description": "the root map" },
438
+ { "path": ".", "load": "lazy" }
439
+ ],
440
+ "conventions": "STYLE.md",
441
+ "inbox": "Inbox/",
442
+ "protected": ["Journal/"]
443
+ }]
444
+ }
445
+ ```
446
+
447
+ `path` is the vault root (absolute; on Windows use forward slashes —
448
+ `C:/Users/me/Brain`); entry paths are relative to it, with the same `eager`/`lazy`
449
+ semantics as `context.json`. An entry may name a single note **or a folder**: a
450
+ folder applies its mode to every note beneath it (`"."` = the whole vault,
451
+ dot-folders like `.obsidian` skipped), a file entry overrides its folder's mode
452
+ whatever the order, and `"load": "exclude"` prunes a note or folder from the
453
+ listing. The example above is the canonical shape — root index eager, everything
454
+ else on demand. A big vault's lazy listing truncates at 200 lines with a visible
455
+ count (`GENESEED_WIKI_LAZY_LIMIT` adjusts it). `conventions` names the note the agent must read before
456
+ its first write; `inbox` is where it drops notes it cannot confidently file;
457
+ `protected` folders are write-blocked by the guard plugin at the tool boundary
458
+ (`GENESEED_GUARD` modes apply). Several wikis may be declared; an empty `wikis`
459
+ list keeps the feature off. The file may hold private paths — it is host-specific,
460
+ covered by the bundle `.gitignore`, and never committed.
461
+
462
+ On tools without the plugins (plain `AGENT.md`, Claude Code), the same contract
463
+ holds through prose: AGENT.md §7 instructs the agent to read `wiki.jsonc` at session
464
+ start and honour it.
465
+
466
+ ### Memory
467
+
468
+ Durable facts live as one-file-per-fact under the memory store, indexed by `MEMORY.md`
469
+ (git-ignored — personal to the machine). The learn plugin writes to the first that
470
+ resolves: `$GENESEED_MEMORY` → `$GENESEED_HARNESS/memory` → `./memory` or
471
+ `./Harness/memory`. For a global install, set `GENESEED_HARNESS` once (Path A).
472
+ Convention: [src/memory/README.md](src/memory/README.md).
473
+
474
+ ### Reading non-markdown docs
475
+
476
+ The `ingest` skill teaches the agent to convert a PDF/Word/PPTX/Excel/HTML file or a
477
+ URL to markdown before reading it — discovery and the read-the-docs law only see
478
+ markdown. Install one converter and the skill uses it:
479
+
480
+ - **MarkItDown** (Microsoft) — broadest (`pip install markitdown`), or its MCP server
481
+ (see [MarkItDown via MCP](#markitdown-via-mcp) below — preferred on an
482
+ MCP-capable host: zero per-call install, one low-cost tool);
483
+ - **Pandoc** — excellent for Office/HTML (single binary);
484
+ - **Docling** (IBM) — best for complex tables / scanned PDFs.
485
+
486
+ The skill never installs a converter silently — if none is present it reports which to add.
487
+
488
+ ### MCP servers
489
+
490
+ Beyond document conversion, Geneseed ships ready-to-wire MCP server presets —
491
+ **MarkItDown** (below), **GitLab** (two slots, `gitlab` and `gitlab-2`, so you can
492
+ point at two instances), and **Filesystem** — four preset entries in total. Each
493
+ is a *local* server the agent launches on demand: registering one only points the agent
494
+ at a command — *you* install the tool (or let `npx`/`pipx` fetch it) and supply any
495
+ credentials. On OpenCode they live under the `mcp` key of an `opencode.json`, each entry
496
+ shaped:
497
+
498
+ ```json
499
+ "<name>": { "type": "local", "command": ["…"], "environment": {}, "enabled": true }
500
+ ```
501
+
502
+ > **Never commit a real token.** The presets and the reference
503
+ > [`adapters/opencode/opencode.json`](adapters/opencode/opencode.json) carry **empty**
504
+ > `GITLAB_PERSONAL_ACCESS_TOKEN` placeholders (and a sample filesystem path) — fill them
505
+ > in your own config, never in a tracked file (universal Law I — secrets).
506
+
507
+ **Don't want to hand-edit JSON?** `./geneseed` → **Settings** → **MCP servers** toggles
508
+ any preset into your project or global `opencode.json` — and enables, disables, or
509
+ removes them — for you. The reference config ships MarkItDown enabled and the GitLab /
510
+ Filesystem entries disabled, so a merge never activates a credential-less server: fill
511
+ the blanks, then flip the one(s) you want on.
512
+
513
+ #### MarkItDown via MCP
514
+
515
+ Wire Microsoft's MarkItDown in as a **local MCP server** so the agent can convert
516
+ PDF / Word / Excel / PowerPoint / HTML → Markdown on demand, exposing a single tool
517
+ `convert_to_markdown(uri)` (`uri` accepts `file:`, `http:`, `https:`, or `data:`).
518
+ The server runs locally and, once cached, does not hit PyPI again.
519
+
520
+ > **A config entry alone does nothing.** A `local` MCP server is just a command your
521
+ > agent launches — if that command isn't on PATH in the shell the agent starts from, the
522
+ > server still *appears* in the list but never connects ("shown but not working"). The
523
+ > `uvx` form below is the zero-install way to guarantee it resolves.
524
+
525
+ **1. Make the command resolve.** Pick one:
526
+
527
+ - **`uvx` (recommended, zero-install).** If you have [uv](https://docs.astral.sh/uv/)
528
+ (`uvx` on PATH), nothing to install — `uvx markitdown-mcp` fetches and caches the
529
+ server on first call. This is the command the reference config and the harness toggle
530
+ now use.
531
+ - **`pipx` (pinned install).** No uv? `pipx install markitdown-mcp` puts a
532
+ `markitdown-mcp` binary on PATH; then use `"command": ["markitdown-mcp"]` instead.
533
+ Verify with `markitdown-mcp --help`.
534
+
535
+ ```
536
+ # uv route (recommended) — confirm it resolves:
537
+ uvx markitdown-mcp --help
538
+ # pipx route — only if you don't have uv:
539
+ brew install pipx && pipx ensurepath # macOS; Debian/Ubuntu: sudo apt install pipx && pipx ensurepath
540
+ pipx install markitdown-mcp && markitdown-mcp --help
541
+ ```
542
+
543
+ Optional OCR / image / audio extras (needed for scanned/image-only PDFs, which
544
+ otherwise return empty): `uvx --with "markitdown[all]" markitdown-mcp` for the uv route,
545
+ or `pipx inject markitdown-mcp "markitdown[all]"` for the pipx route (same venv).
546
+
547
+ **2. Corporate TLS (only on a network with SSL inspection).** uv ships its own root CAs
548
+ and ignores the OS trust store, so a proxy's internal CA fails with `invalid peer
549
+ certificate: UnknownIssuer`. Point uv at the OS trust store — don't disable verification:
550
+
551
+ ```
552
+ echo 'export UV_SYSTEM_CERTS=true' >> ~/.zshrc && source ~/.zshrc # older uv: UV_NATIVE_TLS=true
553
+ # fallback: export SSL_CERT_FILE=/path/to/corporate-root-ca.pem
554
+ ```
555
+
556
+ **3. Register it in your host's MCP config** — add the server entry to the file your
557
+ agent reads, alongside any servers you already have:
558
+
559
+ <!--harness:opencode-->
560
+ On OpenCode that's `opencode.json` (global `~/.config/opencode/opencode.json`, the
561
+ `.jsonc` variant if you keep one — the file OpenCode reads — or per-repo), under the
562
+ `mcp` key. Geneseed's
563
+ [`adapters/opencode/opencode.json`](adapters/opencode/opencode.json) already carries
564
+ this block:
565
+
566
+ ```json
567
+ {
568
+ "$schema": "https://opencode.ai/config.json",
569
+ "mcp": {
570
+ "markitdown": { "type": "local", "command": ["uvx", "markitdown-mcp"], "enabled": true }
571
+ }
572
+ }
573
+ ```
574
+
575
+ On the pipx route, swap the command to `["markitdown-mcp"]`. Prefer not to hand-edit
576
+ JSON? `./geneseed` → **Settings** → **MCP servers** toggles this exact block in for you.
577
+ <!--/harness-->
578
+ <!--harness:claude-->
579
+ On Claude Code that's `.mcp.json` under `mcpServers`:
580
+
581
+ ```json
582
+ { "mcpServers": { "markitdown": { "command": "uvx", "args": ["markitdown-mcp"] } } }
583
+ ```
584
+
585
+ See the **Claude Code** section for the GitLab / Filesystem shapes.
586
+ <!--/harness-->
587
+
588
+ **4. Verify.** Restart your agent; its MCP list should show `markitdown` **connected**
589
+ (not just listed). The `ingest` skill auto-prefers an MCP
590
+ converter when one is exposed,
591
+ so a prompt like *"convert file:///path/to/spec.pdf to markdown"* now just works. Still
592
+ not connecting? See [MCP server won't connect](#mcp-server-wont-connect) below.
593
+
594
+ #### GitLab (one entry per instance)
595
+
596
+ Wire GitLab in via [`@zereight/mcp-gitlab`](https://github.com/zereight/gitlab-mcp) —
597
+ repo, merge-request, issue, and CI tools over the GitLab API, run through `npx` (nothing
598
+ installed globally; the first run fetches it). It is self-hosted ready, so the same
599
+ command serves gitlab.com and any private instance.
600
+
601
+ **1. Mint a Personal Access Token** on *each* instance — User Settings → Access Tokens,
602
+ scopes `api` and `read_repository`. Treat it like a password.
603
+
604
+ **2. Register one entry per instance** — same command, different `GITLAB_API_URL`
605
+ and token. Two instances (e.g. gitlab.com plus a self-hosted server) → two entries:
606
+
607
+ <!--harness:opencode-->
608
+ On OpenCode, under the `mcp` key of `opencode.json`:
609
+
610
+ ```json
611
+ {
612
+ "mcp": {
613
+ "gitlab": {
614
+ "type": "local",
615
+ "command": ["npx", "-y", "@zereight/mcp-gitlab"],
616
+ "environment": {
617
+ "GITLAB_PERSONAL_ACCESS_TOKEN": "glpat-…",
618
+ "GITLAB_API_URL": "https://gitlab.com/api/v4"
619
+ },
620
+ "enabled": true
621
+ },
622
+ "gitlab-2": {
623
+ "type": "local",
624
+ "command": ["npx", "-y", "@zereight/mcp-gitlab"],
625
+ "environment": {
626
+ "GITLAB_PERSONAL_ACCESS_TOKEN": "glpat-…",
627
+ "GITLAB_API_URL": "https://gitlab.example.com/api/v4"
628
+ },
629
+ "enabled": true
630
+ }
631
+ }
632
+ }
633
+ ```
634
+ <!--/harness-->
635
+ <!--harness:claude-->
636
+ On Claude Code, under `mcpServers` in `.mcp.json` — same command, but `env` (not
637
+ `environment`) and `command` + `args` split. See the **Claude Code** section for the
638
+ exact block; add one `mcpServers` entry per instance.
639
+ <!--/harness-->
640
+
641
+ The entry key is just a label — name them `gitlab` / `gitlab-2`, or after each instance
642
+ (`gitlab`, `gitlab-acme`). What separates the two is the `GITLAB_API_URL` + token pair;
643
+ keep the `/api/v4` suffix on the URL.
644
+
645
+ #### Filesystem
646
+
647
+ Give the agent scoped file access via
648
+ [`@modelcontextprotocol/server-filesystem`](https://github.com/modelcontextprotocol/servers/tree/main/src/filesystem),
649
+ also through `npx`. The **allowed directories are command-line arguments** — the server
650
+ can touch *only* the paths you list, so grant the narrowest set that works:
651
+
652
+ <!--harness:opencode-->
653
+ On OpenCode, under the `mcp` key of `opencode.json`:
654
+
655
+ ```json
656
+ {
657
+ "mcp": {
658
+ "filesystem": {
659
+ "type": "local",
660
+ "command": [
661
+ "npx", "-y", "@modelcontextprotocol/server-filesystem",
662
+ "/path/to/project", "/path/to/another/allowed/dir"
663
+ ],
664
+ "enabled": true
665
+ }
666
+ }
667
+ }
668
+ ```
669
+ <!--/harness-->
670
+ <!--harness:claude-->
671
+ On Claude Code, under `mcpServers` in `.mcp.json` (`command` + `args` split):
672
+
673
+ ```json
674
+ { "mcpServers": { "filesystem": { "command": "npx", "args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/project"] } } }
675
+ ```
676
+ <!--/harness-->
677
+
678
+ > **Replace the placeholder.** The reference config and the harness toggle ship the
679
+ > literal arg `/path/to/allowed/dir`. Enabling the server without swapping that for a
680
+ > real path leaves it running but able to touch nothing — the classic "filesystem MCP
681
+ > sees nothing." Edit the path(s) before (or right after) you flip it on.
682
+
683
+ > **Least privilege.** Prefer the narrowest set of dirs the task needs over `$HOME` or
684
+ > `/` — the server refuses any path outside them, and a broad grant lets the agent reach
685
+ > everything under it.
686
+
687
+ #### Claude Code
688
+
689
+ Claude Code reads the same servers from a `.mcp.json` `mcpServers` map — note the key is
690
+ `env` (not `environment`) and the command and its args are split into `command` +
691
+ `args`:
692
+
693
+ ```json
694
+ {
695
+ "mcpServers": {
696
+ "gitlab": {
697
+ "command": "npx",
698
+ "args": ["-y", "@zereight/mcp-gitlab"],
699
+ "env": {
700
+ "GITLAB_PERSONAL_ACCESS_TOKEN": "glpat-…",
701
+ "GITLAB_API_URL": "https://gitlab.com/api/v4"
702
+ }
703
+ },
704
+ "filesystem": {
705
+ "command": "npx",
706
+ "args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/allowed/dir"]
707
+ },
708
+ "markitdown": { "command": "uvx", "args": ["markitdown-mcp"] }
709
+ }
710
+ }
711
+ ```
712
+
713
+ Register it with `claude mcp add` or by editing `.mcp.json` directly; the same
714
+ token-safety rule applies.
715
+
716
+ #### Verify
717
+
718
+ Restart your agent.
719
+ <!--harness:opencode-->
720
+ On OpenCode, `opencode mcp` lists each server and whether it **connected**.
721
+ <!--/harness-->
722
+ <!--harness:claude-->
723
+ On Claude Code, `/mcp` lists each server and whether it connected.
724
+ <!--/harness-->
725
+ Listed ≠ working — a `local` server
726
+ appears in the list whether or not its command actually launches.
727
+
728
+ #### MCP server won't connect
729
+
730
+ A `local` MCP entry is just a command OpenCode/Claude Code runs. If it's listed but
731
+ not connected, walk these in order:
732
+
733
+ 1. **Does the command resolve?** Run the exact command from a fresh terminal —
734
+ `uvx markitdown-mcp --help`, `npx -y @modelcontextprotocol/server-filesystem --help`.
735
+ "command not found" means the binary isn't on PATH in the shell your agent launches
736
+ from. Fix: use the `uvx`/`npx` zero-install form (these only need uv / Node), or
737
+ install the tool and point at the absolute path. This is the #1 cause of
738
+ "shown but not working" for **markitdown** (no `markitdown-mcp` on PATH, no pipx).
739
+ 2. **Filesystem sees nothing?** The allowed-dir arg is still the placeholder
740
+ `/path/to/allowed/dir`, or points somewhere that doesn't exist. Swap in a real path.
741
+ 3. **GitLab won't connect?** Almost always a missing / over-scoped token or the wrong
742
+ `GITLAB_API_URL` — keep the `/api/v4` suffix.
743
+ <!--harness:opencode-->
744
+ 4. **Right file?** OpenCode reads `opencode.jsonc` if present, else `opencode.json`, at
745
+ the project root and `~/.config/opencode/`. Editing the wrong one is silent. Use
746
+ `./geneseed` → **Settings** → **MCP servers** to write to the file OpenCode actually reads.
747
+ <!--/harness-->
748
+ <!--harness:claude-->
749
+ 4. **Right file?** Claude Code reads `.mcp.json` (project) and the `mcpServers` block in
750
+ `~/.claude.json` / settings. Editing the wrong one is silent — `claude mcp list`
751
+ shows which servers actually loaded.
752
+ <!--/harness-->
753
+
754
+ ### Environment knobs
755
+
756
+ | Variable | Used by | Effect |
757
+ | --- | --- | --- |
758
+ | `GENESEED_HOME` | emit / hooks | dir holding the hook shim `bin/geneseed-hook` (default: `~/.geneseed`). Change it and re-run the build, so emitted hooks point at the new location |
759
+ | `GENESEED_HARNESS` | learn plugin | base whose `memory/` the plugin writes to (optional — the plugin auto-locates the in-config store; set to pin it) |
760
+ | `GENESEED_MEMORY` | learn plugin / CLI | explicit memory dir (overrides the above) |
761
+ | `GENESEED_CONTEXT` | context plugin / CLI | explicit `context.json` path |
762
+ | `GENESEED_WIKI` | context + guard plugins | explicit `wiki.jsonc` path (default: `$GENESEED_HARNESS/wiki.jsonc`, else beside the installed `AGENT.md`) |
763
+ | `GENESEED_ROOT` | `harness context` | repo root to discover docs from (default: cwd) |
764
+ | `GENESEED_MODEL` | learn + context plugins | `provider/model` fallback if the session model can't be read (learn distils with it; context shows it in the self-awareness line) |
765
+ | `GENESEED_LLM` | `harness learn` (Claude) | model CLI for distillation, e.g. `claude -p` |
766
+ | `GENESEED_EMIT` | `geneseed upgrade` | `opencode-global` \| `opencode` \| unset (plain bundle) |
767
+ | `GENESEED_OUT` / `GENESEED_ROOT` | `geneseed upgrade` | bundle / project-root locations |
768
+ | `GENESEED_DEBUG` | context + notify + ponytail plugins | `1` re-enables discovery/inject logs (context), decision/delivery logs (notify), and level-switch logs (ponytail) |
769
+ | `GENESEED_CONTEXT_INJECT` | context plugin | `off` disables the injected block (rely on the AGENT.md law) |
770
+ | `GENESEED_EAGER_FILE_KB` / `GENESEED_EAGER_TOTAL_KB` | context plugin | per-file / total eager injection budget (default 16 / 48) |
771
+ | `GENESEED_LAZY_HEADINGS` | context plugin | cap on lazy-file heading reads per session (default 64) |
772
+ | `GENESEED_WIKI_LAZY_LIMIT` | context plugin | cap on lazy notes LISTED per wiki per session (default 200; beyond it the listing truncates with a count) |
773
+ | `GENESEED_CONTEXT_VISIBLE` | context plugin | `1` shows the classic visible `PROJECT CONTEXT` block instead of the invisible per-request delivery (see [Project context](#project-context-usually-nothing)) |
774
+ | `GENESEED_CONTEXT_TRANSFORM` | context plugin | legacy — `0`/`off` forces the visible delivery (same as `GENESEED_CONTEXT_VISIBLE=1`); `1` matches the default |
775
+ | `GENESEED_LEARN_DEBOUNCE_MS` | learn plugin | quiet period before distilling (default 60000) |
776
+ | `GENESEED_GUARD` | guard plugin | `warn` downgrades blocks to warnings; `off` disables the safety guard |
777
+ | `GENESEED_WORKFLOWS_DIR` | workflow plugin | override the directory the `workflow` tool reads saved scripts from |
778
+ | `GENESEED_NOTIFY` | notify plugin | `off` disables end-of-run desktop notifications |
779
+ | `GENESEED_NOTIFY_MIN_SECONDS` | notify plugin | minimum turn length, in seconds, before notifying (default 30; `0` = every turn) |
780
+ | `GENESEED_NOTIFY_TITLE` | notify plugin | override the notification title (default `Geneseed`) |
781
+ | `GENESEED_PONYTAIL` | ponytail plugin | default minimal-code level for new installs: `lite` \| `full` \| `ultra` \| `off` (default `off`; switch live with `/ponytail <level>`) |
782
+ | `GENESEED_PRIMARY` | `geneseed-build` | `1` also emits the primary orchestrator agent |
783
+ | `GENESEED_COMMANDS` | `geneseed-build` | `1` also emits the `/slash` command layer |
784
+ | `GENESEED_TUI_ASCII` / `GENESEED_TUI_PLAIN` | terminal output | force pure-ASCII / drop emoji + animation in what the CLI prints |
785
+ | `GENESEED_NO_ANIM` | install animation | disable the themed install animation |
786
+ | `GENESEED_LOG` | `geneseed upgrade` | override the install/upgrade log path |
787
+ | `GENESEED_NET_TIMEOUT` | `upgrade` | seconds before download attempts give up (default 20, floor 5) |
788
+ | `GENESEED_NO_WEB` | launcher / menu | `1` disables the web-first default of bare `./geneseed` — falls back to the terminal menu |
789
+ | `OPENCODE_CONFIG_DIR` / `XDG_CONFIG_HOME` | global emit | where the global install is written |
790
+ | `OPENCODE_DISABLE_LSP_DOWNLOAD` | OpenCode (LSP) | `true` stops OpenCode auto-downloading built-in language servers (typescript, pyright, jdtls) — set it on air-gapped machines and pre-install each server yourself |
791
+
792
+ ---
793
+
794
+ ## ✅ Verify it works
795
+
796
+ 1. **Sigil** — the agent's first reply opens with the readiness line (the `✅`/`🧬`
797
+ sigil for neutral/imperial). If it's missing, the instructions aren't pointed at
798
+ `AGENT.md`.
799
+ 2. **Context (OpenCode)** — start a session; with `GENESEED_DEBUG=1` the context
800
+ plugin logs what it discovered and injected.
801
+ 3. **Memory (OpenCode)** — do a little work and end the session; after the debounce
802
+ the learn plugin logs `wrote N memory file(s)` or a skip reason to stderr. Total
803
+ silence means it didn't load — re-check the filename, `.js` extension, and that it
804
+ sits in the plugins dir.
805
+ 4. **Harness health** — `geneseed doctor` should print `ok` (`npx geneseed doctor` without
806
+ installing). From a checkout, `node bin/geneseed-cli.mjs doctor` runs the same checks.
807
+ To run the full suite the way CI does: `node --test "tests/**/*.test.mjs"`.
808
+
809
+ Browsing agents, skills and laws, and running build/doctor/diff without retyping a
810
+ command, is what the web console is for — bare `./geneseed` opens it.
811
+
812
+ ## 🚀 Run `geneseed` from anywhere
813
+
814
+ **From npm this is already done.** `npm install -g geneseed` puts `geneseed`,
815
+ `geneseed-hook` and `geneseed-build` on your `PATH` through npm's own bin linking; there
816
+ is nothing to link and `geneseed link` is not needed. The rest of this section is for a
817
+ git checkout.
818
+
819
+ By default you invoke the launcher as `./geneseed` from inside the repo. To call it
820
+ like any other command — plain `geneseed` from any directory — put it on your `PATH`:
821
+
822
+ ```
823
+ ./geneseed link # a launcher shim in ~/.local/bin (no sudo); pass a dir to override
824
+ ./geneseed link /usr/local/bin # e.g. a system-wide bin dir (may prompt for sudo)
825
+ ```
826
+
827
+ (Or, in the web console: **Settings** → the Maintenance card's PATH link / unlink.)
828
+
829
+ `link` writes a small `#!/bin/sh` shim that runs this checkout by absolute path, and
830
+ tells you whether the target dir is on your `PATH` (and, if not, the one line to add
831
+ it). The shim names this checkout's CLI entry point by absolute path, so it finds the
832
+ harness no matter where the shim itself lives — the same shape the Windows arm has
833
+ always used. Once it's on `PATH`, drop the `./`:
834
+
835
+ ```
836
+ geneseed # the interactive main menu, from any directory
837
+ geneseed build # …and every subcommand
838
+ ```
839
+
840
+ Remove it with `./geneseed unlink` (it clears the `geneseed` shims it wrote — and any
841
+ symlink an older version left — from `PATH` and the common bin dirs; a `geneseed` it
842
+ did not write is left alone). Prefer a shell function? Add one to your rc instead —
843
+ it does the same job:
844
+
845
+ ```
846
+ echo 'geneseed() { "'"$PWD"'/geneseed" "$@"; }' >> ~/.zshrc # or ~/.bashrc
847
+ ```
848
+
849
+ **Windows** — use the native launcher `geneseed.cmd`, which routes to the same Node CLI with
850
+ no bash. PowerShell runs a `.cmd` directly, so it is the PowerShell spelling too:
851
+
852
+ ```powershell
853
+ .\geneseed.cmd setup
854
+ .\geneseed.cmd link # writes a geneseed.cmd shim into %LOCALAPPDATA%\Geneseed\bin
855
+ # and adds that dir to your user PATH (no admin / symlink needed)
856
+ ```
857
+
858
+ Open a new terminal after `link`, then call `geneseed` from any directory. Remove it
859
+ again with `.\geneseed.cmd unlink`.
860
+
861
+ ## 🔌 Start the web UI at login
862
+
863
+ The web UI is the only long-running Geneseed process. `geneseed web **start**`
864
+ spawns a **detached daemon** on `127.0.0.1:4747` and returns immediately, so a login
865
+ hook that runs `geneseed web start --no-browser` once — no browser tab — leaves the
866
+ UI ready whenever you open [http://127.0.0.1:4747](http://127.0.0.1:4747). It is
867
+ **per-user and per-machine**: each laptop runs its own daemon on its own loopback, so
868
+ Windows and macOS are set up independently and never collide. The daemon is a
869
+ singleton — a second `start` just no-ops — so re-running it (or logging in twice) is
870
+ harmless.
871
+
872
+ > **Use `web start`, not bare `web`, in every launcher below.** Without the
873
+ > `start` action the server runs in the **foreground** and writes no
874
+ > `.geneseed-web.json` record, so it becomes invisible to `web stop`, `web restart`
875
+ > and `web status` — they report "no live server" while it keeps serving, and a
876
+ > `restart` will orphan a second daemon that cannot bind the taken port. Recovering
877
+ > then means finding it by port and killing it by hand.
878
+
879
+ > **These are files YOU create, and Geneseed never writes one.** Nothing in this project
880
+ > has ever created a Startup entry or a LaunchAgent, and nothing ever edits one — including
881
+ > `geneseed migrate`, which detects a login item still naming an old checkout, prints the
882
+ > path and the line to put there, and leaves the file alone. It is your login
883
+ > configuration; deleting the file is the only uninstall it has.
884
+
885
+ **Windows** — drop a hidden VBS launcher in the Startup folder (runs at login, no
886
+ console flash, removed by deleting the file). Open the folder with **Win+R** →
887
+ `shell:startup`, then create `geneseed-web.vbs`:
888
+
889
+ ```vbs
890
+ ' geneseed-web.vbs — start the Geneseed web daemon at login (hidden, no browser).
891
+ CreateObject("WScript.Shell").Run "cmd /c ""%LOCALAPPDATA%\Geneseed\bin\geneseed.cmd"" web start --no-browser", 0, False
892
+ ```
893
+
894
+ Expand `%LOCALAPPDATA%` to its real path (e.g. `C:\Users\you\AppData\Local`) — VBS
895
+ does not expand environment variables inside a string. **Disable** by deleting the
896
+ file. Prefer a scheduled task (runs hidden, can restart on failure)? Use:
897
+
898
+ ```powershell
899
+ schtasks /Create /TN "Geneseed Web" /SC ONLOGON /TR "\"%LOCALAPPDATA%\Geneseed\bin\geneseed.cmd\" web start --no-browser" /RL LIMITED /F
900
+ schtasks /Delete /TN "Geneseed Web" /F # to remove
901
+ ```
902
+
903
+ **macOS** — the launcher is the `geneseed` shim that `./geneseed link` writes (default
904
+ `~/.local/bin/geneseed`). Use a **LaunchAgent** with `RunAtLoad` — and **no**
905
+ `KeepAlive`, because the launcher exits after spawning the detached daemon (the
906
+ daemon runs in its own session and survives). Write
907
+ `~/Library/LaunchAgents/dev.geneseed.web.plist`:
908
+
909
+ ```xml
910
+ <?xml version="1.0" encoding="UTF-8"?>
911
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
912
+ "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
913
+ <plist version="1.0">
914
+ <dict>
915
+ <key>Label</key> <string>dev.geneseed.web</string>
916
+ <key>ProgramArguments</key>
917
+ <array>
918
+ <string>/Users/you/.local/bin/geneseed</string>
919
+ <string>web</string>
920
+ <string>start</string>
921
+ <string>--no-browser</string>
922
+ </array>
923
+ <key>RunAtLoad</key> <true/>
924
+ </dict>
925
+ </plist>
926
+ ```
927
+
928
+ Use the **absolute** path to your `geneseed` launcher (LaunchAgents don't see your
929
+ shell `PATH`). Then load it — it also runs it once now:
930
+
931
+ ```bash
932
+ launchctl load ~/Library/LaunchAgents/dev.geneseed.web.plist # enable + start now
933
+ launchctl unload ~/Library/LaunchAgents/dev.geneseed.web.plist # disable
934
+ ```
935
+
936
+ On either OS, `geneseed web stop` stops the running daemon without touching the
937
+ login hook, and `geneseed web status` reports whether it's up.
938
+
939
+ ## 🤖 Headless / CI (OpenCode)
940
+
941
+ Once the harness is installed (Path A or B), OpenCode can run **non-interactively** —
942
+ no TUI — so the harness's agents, rules, and skills apply in scripts and pipelines:
943
+
944
+ ```
945
+ opencode run "review the staged diff and list any correctness bugs" # one-shot, prints to stdout
946
+ opencode run -m anthropic/claude-sonnet-4-5 "…" # pin a model for the run
947
+ cat issue.md | opencode run "triage this and propose a fix plan" # pipe input in
948
+ ```
949
+
950
+ `opencode run` loads the same `opencode.json` (so `instructions` → `AGENT.md`, the
951
+ permission gates, and any per-agent overrides all take effect) and the same
952
+ `.opencode/` agents/skills/plugins. Useful for CI checks, cron jobs, or scripting a
953
+ capability agent. Notes:
954
+
955
+ - **Permissions still gate.** The consent-before-commit/push / `rm -rf` `ask` rules
956
+ will *block* in a non-interactive run (nothing to answer the prompt). Both
957
+ `git commit` and `git push` are gated now (Law XX, every branch), so a CI job that
958
+ commits must opt those commands back to `"allow"` in its own `permission.bash` map,
959
+ or scope the run to read-only work — don't blanket-disable the guards.
960
+ - **`--pure`** runs OpenCode ignoring local/global config — handy to reproduce a bug
961
+ without the harness in the way, or to confirm a behaviour is the harness's doing.
962
+ - The **learn** plugin (`session.idle` → memory) and **context** plugin still load in
963
+ headless runs; set `GENESEED_GUARD=warn`/`off` or `GENESEED_DEBUG=1` per the
964
+ [adapter README](adapters/opencode/README.md) if a run needs different behaviour.
965
+
966
+ This is a usage note, not an emitted feature — the harness writes nothing for it.
967
+
968
+ ## Upgrade
969
+
970
+ **Installed from npm:**
971
+
972
+ ```
973
+ npm install -g geneseed@latest # get the new version
974
+ geneseed rebuild-all # re-render every active install in its own theme + mode
975
+ ```
976
+
977
+ `upgrade` / `update` / `sync-self` / `bootstrap` are the *git checkout* route — they pull
978
+ the install's own origin. Run one from an npm install and it stops before touching
979
+ anything, naming the `npm install -g` line above instead.
980
+
981
+ **Installed from a clone:**
982
+
983
+ ```
984
+ ./geneseed upgrade # track main; keep the remembered theme + emit mode
985
+ ./geneseed upgrade v1.0.0 # pin to a tag
986
+ ./geneseed upgrade main imperial # force a theme
987
+ ```
988
+
989
+ It git-pulls the install's own origin (fast-forward only), validates it (a blocking
990
+ `doctor` pass, rolling back on failure), then re-renders in place — leaving host state
991
+ (memory, `context.json`, markers) untouched. Theme and emit mode are remembered between
992
+ runs. `./geneseed update` and `./geneseed sync-self` are aliases of `upgrade` (one pull
993
+ refreshes launchers and factory together), and `./geneseed bootstrap` continues into the
994
+ setup wizard. A dirty tree or a non-git checkout is reported, not force-updated.
995
+
996
+ **Reviewing local edits** — if the deployed harness was tweaked in place (you, or the
997
+ agent's own self-improvement loops) and you want to see what diverged from source:
998
+
999
+ ```
1000
+ ./geneseed diff # summary — --full for line-level diffs
1001
+ ./geneseed diff --out improvements.md # export a markdown improvements file
1002
+ ```
1003
+
1004
+ The `--out` file is a self-contained back-port artifact: hand it to an agent in the
1005
+ Geneseed source repo and ask it to fold the changes into `src/`. You rarely need to
1006
+ run it by hand — **setup, re-theme, and upgrade auto-export one** whenever the
1007
+ harness they are about to overwrite carries local edits, so a rebuild never silently
1008
+ destroys what the agent learned. The auto-export lands in `improvements/` **inside
1009
+ the deployed harness dir** (e.g. `~/.config/opencode/improvements/`) — beside the
1010
+ install it describes; it is not in the manifest, so re-emits never clobber it, diff
1011
+ never reports it, and uninstall leaves it in place (the same contract as memory).
1012
+ The web console's **Changes** page exports the same file.
1013
+
1014
+ ## 🩺 Troubleshooting
1015
+
1016
+ | Symptom | Fix |
1017
+ | --- | --- |
1018
+ | No readiness sigil | Instructions not pointed at `AGENT.md` — check `opencode.json` `instructions` (or your tool's rules setting). |
1019
+ | `PROJECT CONTEXT` block appears twice | Two copies of the context plugin (global + a leftover `.opencode/plugins/`). Remove the project copy. |
1020
+ | Full `PROJECT CONTEXT` block visible in the terminal | Either `GENESEED_CONTEXT_VISIBLE=1` (or legacy `GENESEED_CONTEXT_TRANSFORM=0/off`) is set, or your OpenCode build lacks the experimental transform hook and the plugin fell back to visible delivery — run with `GENESEED_DEBUG=1` to see which (see [Project context](#project-context-usually-nothing)). |
1021
+ | Learn plugin silent / no memory written | Set `GENESEED_HARNESS` (or `GENESEED_MEMORY`); confirm the `.js` files are in the plugins dir. |
1022
+ | `could not determine a model` | Set `GENESEED_MODEL=provider/model`. |
1023
+ | PDFs / Office docs ignored | Use the `ingest` skill and install a converter (MarkItDown / Pandoc / Docling). |
1024
+ | A "read-only" agent won't run a command | By design — read-only agents are denied `bash`. Agents that must run read-only commands (reviewer, security) allow it via a spec marker. |
1025
+ | Skills not tracked in git | A parent `.gitignore` blanket-ignores the bundle dir — remove the bare `Harness/` line; the bundle's own `.gitignore` scopes correctly. |
1026
+
1027
+ More OpenCode-specific notes (why a file loads twice, plugin loading): [HOW-OPENCODE-LOADS.md](adapters/opencode/HOW-OPENCODE-LOADS.md).