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,582 @@
1
+ # 🔌 OpenCode adapter
2
+
3
+ > [← Back to README](../../README.md) · [Setup guide](../../SETUP.md) · [How OpenCode loads](HOW-OPENCODE-LOADS.md) · [Global harness spec](GLOBAL-HARNESS-SPEC.md)
4
+
5
+ [OpenCode](https://opencode.ai) is `AGENTS.md`-native and has first-class
6
+ **subagents** and **commands**, so Geneseed fits it cleanly. Pick the depth you
7
+ want — the baseline is a 30-second drop-in; the native mapping turns Geneseed's
8
+ agents and skills into real OpenCode primitives.
9
+
10
+ > New to how OpenCode discovers config, instructions, and plugins — or wondering
11
+ > why a file shows up twice? See [**HOW-OPENCODE-LOADS.md**](HOW-OPENCODE-LOADS.md).
12
+
13
+ ## Baseline (instant intake)
14
+
15
+ After implanting the harness into your repo (so `AGENT.md`, `agents/`, `skills/`,
16
+ `laws/`, `memory/` are at the root):
17
+
18
+ - Copy [`opencode.json`](opencode.json) to the repo root (or merge its
19
+ `instructions` array into an existing `opencode.json`). It points OpenCode's
20
+ `instructions` field at `AGENT.md` (which inlines the laws) — so every session
21
+ starts bound by the harness. The project-context manifest `context.json` is **not**
22
+ listed here; the [context plugin](#doc-enforcement--the-context-plugin-v2-convention-glob) loads it,
23
+ and listing it in two configs would double-load it.
24
+
25
+ That's it. OpenCode loads `AGENT.md` as a rule file on every run; the plugins handle
26
+ context and memory.
27
+
28
+ > **Alternative, zero-config:** OpenCode auto-loads `AGENTS.md` (plural) with no
29
+ > config at all. If you prefer that, rename the harness entrypoint
30
+ > `AGENT.md` → `AGENTS.md` when you implant it and skip `opencode.json` entirely.
31
+
32
+ ## Native mapping (recommended) — generated, zero drift
33
+
34
+ Turn Geneseed's capability agents into OpenCode **subagents** and its skills into
35
+ native **skills**, so they're dispatchable rather than just described in prose. The
36
+ generator produces all of it from the same `src/`, so it never drifts:
37
+
38
+ ```
39
+ geneseed build --emit opencode --target /path/to/your-repo
40
+ ```
41
+
42
+ That writes, on top of the normal bundle (note the **plural** dir names — canonical
43
+ in OpenCode; singular `agent/`/`command/` is back-compat only):
44
+
45
+ ```
46
+ your-repo/
47
+ ├── opencode.json instructions → AGENT.md (context auto-discovered by plugin)
48
+ └── .opencode/
49
+ ├── agents/ one subagent per capability agent
50
+ │ ├── reviewer.md architect.md security.md (read-only: write/edit denied)
51
+ │ ├── tester.md docs.md (may edit files)
52
+ ├── skills/ one native skill per skill (dir-per-skill)
53
+ │ ├── commit/SKILL.md code-review/SKILL.md create-skill/SKILL.md …
54
+ └── plugins/ context + learn plugins
55
+ ```
56
+
57
+ - Read-only agents (their spec says *Read-only*) get an OpenCode `permission` block
58
+ — `edit: deny`, `webfetch: deny`, and `bash: deny`, so a read-only agent can't
59
+ mutate via the shell either. One that must run read-only commands (tests, linters,
60
+ scanners) declares `<!-- bash: allow -->` in its spec, which gates bash to `ask`
61
+ instead. The rest keep edit access.
62
+ - OpenCode invokes a subagent via the task tool, e.g. `subagent_type: "reviewer"`.
63
+ - **Skills are native, not slash commands** — model-invoked via the `skill` tool
64
+ with progressive disclosure (the agent sees each skill's `description` and loads
65
+ the body on demand). This is the *same `SKILL.md` shape Claude Code uses*, so the
66
+ one artifact serves both tools. Trade-off: no `/name` slash trigger and no
67
+ per-skill `agent:`/`model:` pin (a skill runs in the current agent context). See
68
+ [GLOBAL-HARNESS-SPEC.md](GLOBAL-HARNESS-SPEC.md) §9.1.
69
+ - Theming: the *scaffolding* is always plain English — folder names
70
+ (`agents/`/`skills/`/`memory/`), link paths, section layout, and law numbers stay
71
+ fixed so `AGENT.md`'s links match the dirs OpenCode fixes (every emit, not just
72
+ OpenCode). A theme changes the AI's **voice** *and* the prose **vocabulary**: the
73
+ core nouns are themed (imperial reads *Dictates*/*Adepts*/*Rites*, with a themed
74
+ banner and sigil), while **neutral keeps the plain words** (Rules/Agents/Skills). So
75
+ `--theme imperial` flavours both the tone and the page over the same neutral
76
+ scaffolding. The only OpenCode-specific touch is rewriting `AGENT.md`'s skill links
77
+ to the nested `skills/<name>/SKILL.md` form.
78
+ - **Bundle in a subfolder?** OpenCode resolves `instructions` paths from the
79
+ *project root*, not from `opencode.json`'s folder. So if the bundle lives in a
80
+ subfolder, add `--root <repo>` — `opencode.json` and `.opencode/` are written to
81
+ the repo root while the whole bundle (incl. `context.json`) stays in `--out`, and
82
+ the instruction path is prefixed (`["Harness/AGENT.md"]`):
83
+ `geneseed build --emit opencode --out repo/Harness --root repo`.
84
+
85
+ ### Keeping it in sync — `geneseed upgrade`
86
+
87
+ By default `geneseed upgrade` emits only the **plain bundle** (rendered to a sibling
88
+ `Harness/`). If you reference the bundle's `AGENT.md` directly — including by
89
+ absolute path from anywhere on the machine, or through OpenCode's global config —
90
+ that's all you need; **no `opencode.json` is written**.
91
+
92
+ ```
93
+ cd Geneseed
94
+ ./geneseed upgrade # plain bundle, keeps the last-built theme
95
+ ./geneseed upgrade imperial # force a theme while upgrading
96
+ ```
97
+
98
+ On Windows use `.\geneseed.cmd upgrade` — same subcommands, no bash, and PowerShell
99
+ runs it directly.
100
+
101
+ The native layer is **opt-in**. To (re)generate subagents, native skills, and an
102
+ `opencode.json` on upgrade, set `GENESEED_EMIT=opencode` (or
103
+ `GENESEED_EMIT=opencode-global` for the global install):
104
+
105
+ ```
106
+ GENESEED_EMIT=opencode ./geneseed upgrade imperial
107
+ ```
108
+
109
+ That writes `opencode.json` + `.opencode/` to the project root (the Geneseed
110
+ folder's parent), keeps the bundle in `Harness/`, and prefixes the instruction
111
+ paths — `["Harness/AGENT.md", "Harness/context.json"]`. Override the locations
112
+ with `GENESEED_OUT` (bundle) and `GENESEED_ROOT` (project root).
113
+
114
+ ### Manual mapping (fallback)
115
+
116
+ If you'd rather not run the generator, create each file by hand:
117
+ `.opencode/agents/<name>.md` with frontmatter `description`, `mode: subagent`, and
118
+ (for read-only agents) a `permission:` block (`edit: deny`, `webfetch: deny`, and
119
+ `bash: deny` — or `bash: ask` if it runs read-only commands), body = the agent spec. Skills become native skills at `.opencode/skills/<name>/SKILL.md` with
120
+ frontmatter `name` + `description`, body =
121
+ the skill spec. (Plural dir names are canonical; singular `agent/`/`command/` are
122
+ back-compat aliases.)
123
+
124
+ ## Memory loop — the `learn` plugin
125
+
126
+ OpenCode's session-end event is `session.idle`; Geneseed hooks it with a **plugin**
127
+ — [`plugins/geneseed-learn.js`](plugins/geneseed-learn.js). On every session end it
128
+ distils durable memories from the conversation and writes them into the bundle's
129
+ `memory/`, maintaining `MEMORY.md` and deduping against what is already stored.
130
+
131
+ It is **self-contained**: it distils with the *same model the session already
132
+ used* (read from the transcript), so it inherits your OpenCode provider config —
133
+ no API key, no separate model CLI, nothing to set for the model. Trivial sessions
134
+ are skipped and any error is swallowed, so it never blocks or disturbs a session.
135
+
136
+ ### Install
137
+
138
+ All seven plugins (activity, context, guard, learn, notify, ponytail, workflow) install together in
139
+ one step — the shared recipe lives in
140
+ **[Plugin setup](../../docs/opencode-plugin-setup.md)** (global `cp …/plugins/*.js`
141
+ + `GENESEED_HARNESS`, or `geneseed-build --emit opencode` / `opencode-global`).
142
+
143
+ **Verify it loaded:** start a session, do a little work, end it. On `session.idle`
144
+ the learn plugin logs to stderr — either `[geneseed-learn] wrote N memory file(s): …`
145
+ or a `[geneseed-learn] …` skip reason. Total silence means it did not load: re-check
146
+ the filename, the `.js` extension, and that the path is exactly the plugins dir.
147
+
148
+ ### Point it at the memory dir
149
+
150
+ The plugin writes into the first location that resolves:
151
+
152
+ 1. `$GENESEED_MEMORY` — an explicit memory dir;
153
+ 2. `$GENESEED_HARNESS/memory` (or `/anamnesis` for the imperial theme);
154
+ 3. `./memory` or `./Harness/memory` — when the bundle lives inside the project.
155
+
156
+ Because your Harness is global (used from any directory), set `GENESEED_HARNESS`
157
+ once to the bundle's absolute path so the plugin always writes to the same memory
158
+ store no matter where you launch OpenCode:
159
+
160
+ ```
161
+ export GENESEED_HARNESS=/abs/path/to/Harness # e.g. in your shell profile
162
+ ```
163
+
164
+ If the plugin can't read the session's model from the transcript, set a fallback
165
+ `GENESEED_MODEL=provider/model`. Otherwise there is nothing else to configure.
166
+
167
+ > **Field-test note.** This plugin uses `session.idle`, `client.session.messages`,
168
+ > message `info.providerID/modelID`, and `client.session.prompt` — all confirmed
169
+ > against the current OpenCode plugin + SDK docs. Field names can still shift between
170
+ > versions; if one differs it degrades quietly — logs to stderr and writes nothing —
171
+ > rather than erroring. The resolvers are isolated at the top of `geneseed-learn.js`
172
+ > for a one-line adjustment if needed.
173
+
174
+ ## Doc enforcement — the `context` plugin (v2, convention-glob)
175
+
176
+ OpenCode's `instructions` array can load a rule file, but not a tree of project
177
+ docs with an `eager`/`lazy` split. The
178
+ [`plugins/geneseed-context.js`](plugins/geneseed-context.js) plugin closes that gap
179
+ — and v2 needs **no committed `context.json`**.
180
+
181
+ On `session.created` it **auto-discovers the current repo's docs by convention**
182
+ and injects the `eager` ones into the session via a no-reply prompt
183
+ (`session.prompt({ noReply: true })`) — so they're in context before your first
184
+ turn, enforcing **Law XVIII** by injection, not agent discipline. This is what lets
185
+ the harness live entirely in the global config dir with zero per-repo files.
186
+
187
+ - **Eager** (injected in full, budget-capped): root `AGENTS.md`/`AGENT.md`/
188
+ `CLAUDE.md`/`.cursorrules`, `README.md`, `CONTRIBUTING.md`.
189
+ - **Lazy** (only listed — path + first heading, read on demand): `docs/`, `doc/`,
190
+ `documentation/`, `architecture/`, `adr/`, monorepo `packages/*/README.md`,
191
+ other root `*.md`. `node_modules`, `.git`, `dist`, `build`, … are never scanned.
192
+ - **Budget:** per-eager-file 16 KB and total 48 KB caps (env-overridable via
193
+ `GENESEED_EAGER_FILE_KB` / `GENESEED_EAGER_TOTAL_KB`); an oversized eager file is
194
+ demoted to a lazy listing, logged — never silently truncated.
195
+ - **Override / escape hatch:** drop a `.harness/context.json` (or `./context.json`,
196
+ or point `$GENESEED_CONTEXT`) to take control — same schema, plus glob `path`s,
197
+ `load: exclude`, and `"extend": true` to layer overrides on top of discovery.
198
+ - **Idempotent:** writes a `<!-- geneseed-context:v2 -->` marker and skips a session
199
+ that already carries it — so a stray second plugin copy can't double-inject. (The
200
+ hard guarantee is still a single install: OpenCode dedups plugins by npm
201
+ name+version only, so two local copies both load.)
202
+ - **Survives compaction:** on the experimental `session.compacting` hook it re-pushes
203
+ the eager docs into the compaction context, so the project context (Law XVIII)
204
+ persists when a long session is summarised. The `AGENT.md` rules already survive —
205
+ they load via `instructions`, not the conversation — so only the injected project
206
+ context needs re-pushing.
207
+ - **Machine wiki (AGENT.md §7):** the same block carries a `MACHINE WIKI` segment
208
+ for the user's own knowledge base(s) — typically an Obsidian vault — declared in
209
+ `wiki.jsonc` (`$GENESEED_WIKI` → `$GENESEED_HARNESS/wiki.jsonc` → beside the
210
+ install). Per wiki: eager entries inject in full, lazy entries list, and the
211
+ `conventions` / `inbox` / `protected` metadata is surfaced — on the **same**
212
+ budgets, compaction and transform paths as the project context. Schema and
213
+ behaviour: [SETUP.md → Wiki](../../SETUP.md#wiki--your-own-knowledge-base-optional).
214
+
215
+ It needs no model, writes nothing, skips the learn plugin's throwaway sessions, and
216
+ swallows every error. Output mirrors `geneseed-hook context`.
217
+
218
+ - **Quiet by default:** it logs nothing (OpenCode renders a plugin's stderr as red
219
+ text in the UI). `GENESEED_DEBUG=1` re-enables discovery/inject logs.
220
+ - **Invisible by default:** the context is prepended to each outgoing request via
221
+ the experimental `chat.messages.transform` hook — no `PROJECT CONTEXT` block in
222
+ the conversation, and compaction survival is inherent (re-sent per request). On a
223
+ build that lacks the hook the plugin detects it (a request completes without the
224
+ hook firing) and falls back to the classic visible delivery, a `noReply` session
225
+ message. `GENESEED_CONTEXT_VISIBLE=1` forces the visible block up front; set
226
+ `GENESEED_CONTEXT_INJECT=off` to disable injection entirely and fall back to the
227
+ AGENT.md project-context Law (soft, agent-discipline — no injection).
228
+
229
+ **Install:** installs with the others in one step — see
230
+ [Plugin setup](../../docs/opencode-plugin-setup.md). It uses
231
+ `session.created`, `session.idle` (transform-fallback detection), `session.prompt`
232
+ `noReply`, `session.messages`, `session.get`, and the experimental
233
+ `chat.messages.transform` and `session.compacting` hooks — all confirmed against the
234
+ current OpenCode docs; it degrades quietly if a field differs in your build.
235
+
236
+ ## Workflow tool — the `workflow` plugin
237
+
238
+ [`plugins/geneseed-workflow.js`](plugins/geneseed-workflow.js) registers ONE custom
239
+ tool, `workflow`, that runs saved, code-driven orchestration scripts — the
240
+ deterministic counterpart to the model-driven `council` / `parallel-agents` skills:
241
+ the script, not the model, drives the control flow.
242
+
243
+ - **Saved scripts only (v1):** the tool loads `<name>.js` from the sibling
244
+ `workflows/` dir (`.opencode/workflows/` per-repo, `<config>/workflows/` global;
245
+ override with `GENESEED_WORKFLOWS_DIR`). No model-authored scripts are eval'd.
246
+ - **Call shape:** `workflow({ name, args })` — call with no name to list what is
247
+ available. Shipped: `council`, `review`, `research-plan-implement`, `dispatch`.
248
+ - **Runtime API** ([`workflows/_runtime.js`](workflows/_runtime.js)): scripts get
249
+ `agent()`, `parallel()`, `pipeline()`, `phase()`, `log()`, `budget`, `args`.
250
+ Child work runs as real OpenCode sessions (created, prompted, then deleted);
251
+ concurrency is capped at `min(16, cores − 2)`; `budget` meters output tokens.
252
+ - **Synchronous and contained:** the tool blocks until the workflow finishes; a
253
+ phase-by-phase trace plus the full result land in
254
+ `.geneseed/workflow-runs/<runId>.log`. Failures are reported, never thrown into
255
+ the session. `GENESEED_DEBUG=1` enables stderr logging.
256
+
257
+ The matching `workflow` **skill** (in the rendered bundle) teaches the agent when
258
+ to reach for the tool; the plugin is what actually executes the scripts.
259
+
260
+ ## Desktop notifications — the `notify` plugin
261
+
262
+ [`plugins/geneseed-notify.js`](plugins/geneseed-notify.js) pings the OS when the
263
+ agent finishes a turn, so you can start a long run, walk away, and be called back
264
+ when it's your move again. It hooks `session.idle` like the learn plugin.
265
+
266
+ - **Anti-spam by design:** it only fires when the turn actually took a while — the
267
+ gap between the session's last user prompt and now must exceed
268
+ `GENESEED_NOTIFY_MIN_SECONDS` (default **30**; set `0` to notify on every turn). A
269
+ quick back-and-forth never notifies; a multi-minute build/test run does.
270
+ - **Stays out of the way:** native subagent child sessions and the learn plugin's
271
+ throwaway `geneseed-*` distil sessions are skipped, so background machinery is
272
+ silent.
273
+ - **Native, dependency-free delivery:** macOS `osascript`, Linux `notify-send`
274
+ (from libnotify — if it isn't installed the call is swallowed, no error), Windows
275
+ a PowerShell balloon tip. The notifier is spawned detached; any failure is
276
+ swallowed, so it never blocks, delays, or breaks a session.
277
+ - **Config:** `GENESEED_NOTIFY=off` disables it; `GENESEED_NOTIFY_MIN_SECONDS=N`
278
+ tunes the threshold; `GENESEED_NOTIFY_TITLE="…"` overrides the title (default
279
+ `Geneseed`); `GENESEED_DEBUG=1` logs each decision/delivery to stderr.
280
+
281
+ **Verify it loaded:** with `GENESEED_DEBUG=1`, end a session that ran longer than the
282
+ threshold — you'll see `[geneseed-notify] notified for …` and a desktop notification.
283
+ On Linux, install `libnotify` (`notify-send`) if nothing appears.
284
+
285
+ ## Global install — everything in the config dir
286
+
287
+ For "the harness is global, zero per-repo files," render straight into OpenCode's
288
+ global config dir:
289
+
290
+ ```
291
+ geneseed build --emit opencode-global # add --theme imperial if wanted
292
+ ```
293
+
294
+ It is **self-contained** — it writes only into the config dir (`$OPENCODE_CONFIG_DIR`,
295
+ else `$XDG_CONFIG_HOME/opencode`, else `~/.config/opencode` — on Windows that resolves
296
+ to `C:\Users\<user>\.config\opencode`, the same homedir-relative path OpenCode itself
297
+ uses) and builds **no sibling `Harness/` folder**:
298
+
299
+ - `AGENT.md` rendered straight in;
300
+ - `agents/`, `skills/<name>/SKILL.md`, and a single `plugins/` copy;
301
+ - the **memory store** at `<cfg>/memory` — always classic English, never themed
302
+ (like `agents/`/`skills/`); migrated once from a legacy `Harness/memory` (or a
303
+ themed `anamnesis/`) if you had one, else seeded;
304
+ - `opencode.json` merged to point `instructions` at the absolute `AGENT.md`;
305
+ - **no** `context.json` — the context plugin auto-discovers each repo's docs.
306
+
307
+ The learn plugin now **auto-locates** the in-config store: it resolves `memory/`
308
+ relative to its own file (`<cfg>/plugins/geneseed-learn.js` → `<cfg>/memory`), so the
309
+ `export GENESEED_HARNESS` step is **optional**. Set it only to point the plugin at a
310
+ *different* store:
311
+
312
+ ```
313
+ export GENESEED_HARNESS="$HOME/.config/opencode" # optional override
314
+ echo "export GENESEED_HARNESS=\"$HOME/.config/opencode\"" >> ~/.zshrc
315
+ ```
316
+
317
+ The dir is shared with your own config, so it is never wiped: a
318
+ `.geneseed-manifest.json` tracks only the files this layer owns (AGENT.md, agents,
319
+ skills, plugins — **not** memory) and removes stale ones on re-emit, leaving your own
320
+ agents/skills/plugins and the memory store untouched.
321
+
322
+ Use `$OPENCODE_CONFIG_DIR` to keep the global harness in a **git-tracked** folder.
323
+ On upgrade: `GENESEED_EMIT=opencode-global ./geneseed upgrade` — or, on Windows,
324
+ `$env:GENESEED_EMIT="opencode-global"; .\geneseed.cmd upgrade` — (the mode is then
325
+ remembered in `<cfg>/.geneseed-emit`, so a bare upgrade keeps it). Full design, setup
326
+ guide, and acceptance checklist: [GLOBAL-HARNESS-SPEC.md](GLOBAL-HARNESS-SPEC.md).
327
+
328
+ ## Pointing the agent at files beyond the Harness
329
+
330
+ With the v2 context plugin you usually need **nothing here** — it auto-discovers a
331
+ repo's docs. A **`context.json`** manifest is the *override* for when the convention
332
+ doesn't fit: drop it at the bundle root, in `.harness/context.json`, or point
333
+ `$GENESEED_CONTEXT` at it. Each entry carries a `load` mode: `eager` (read every
334
+ session — small, always-relevant rules), `lazy` (read only when the task needs it),
335
+ or `exclude`; `path` may be absolute, repo-relative, or a glob, and `"extend": true`
336
+ layers the manifest on top of auto-discovery. The build drops an empty
337
+ `context.json` at the bundle root (never overwriting an existing one); git-ignore
338
+ it. The schema is in AGENT.md §8, GLOBAL-HARNESS-SPEC.md §3.4, and the file's own
339
+ comment.
340
+
341
+ If you'd rather use OpenCode's own always-on loading for a small rule file, you can
342
+ also add its path to the `instructions` array of `opencode.json` directly — it
343
+ accepts absolute paths, repo-relative paths, globs, and URLs.
344
+
345
+ ## Newer OpenCode integrations
346
+
347
+ These exploit OpenCode features beyond the baseline. **All default to today's
348
+ behaviour** — nothing changes the machine's current agent/model unless you opt in.
349
+
350
+ - **Per-agent model routing** (`agent-overrides.json`). The build drops an empty,
351
+ git-ignored `agent-overrides.json` at the bundle/config root. Empty ⇒ every agent
352
+ inherits OpenCode's current model **as-is**. Add entries to pin a model/temperature
353
+ per agent (e.g. route the read-only `reviewer`/`explorer` to a cheaper model). Each
354
+ entry also accepts `variant` (reasoning effort, e.g. `"high"`) and `steps` (a max
355
+ tool-iteration cap — a runaway-loop safety net):
356
+ ```json
357
+ { "agents": { "reviewer": { "model": "anthropic/claude-haiku-4-5", "temperature": 0.1, "variant": "high", "steps": 20 } } }
358
+ ```
359
+ Re-emit to apply. (A future TUI screen will edit this map.) Unlisted keys are omitted,
360
+ so the agent inherits OpenCode's defaults.
361
+ - **Agent colours.** Each capability agent is emitted with a `color:` set to an OpenCode
362
+ *named theme slot*, sourced from the active harness theme's `AGENT_COLORS` map
363
+ (`themes/_TEMPLATE.json`; the shipped default — architect=`primary`, reviewer=`warning`,
364
+ tester=`success`, docs=`info`, security=`error`, explorer=`accent`, everything else
365
+ (council seats)=`secondary` — is the same in every shipped theme, but a theme is free
366
+ to restyle its own grouping). An unrecognised slot value falls back to `secondary` with
367
+ a build-time warning, so a bad restyle never reaches an invalid `color:` in emitted
368
+ frontmatter. The agent switcher and subagent output are colour-coded this way, and the
369
+ colour tracks whatever OpenCode theme you run (portable, never a raw hex). Cosmetic.
370
+ - **Branded theme** (`/theme geneseed-<theme>`). The emit writes a complete OpenCode
371
+ theme at `.opencode/themes/geneseed-<theme>.json` (global: `<cfg>/themes/`), tinted by
372
+ the harness theme's accent using terminal-native ANSI colours (always valid, no host
373
+ palette). Select it with e.g. `/theme geneseed-imperial`; ignore it otherwise.
374
+ - **Curated colour themes** (`/theme geneseed-<name>-solid` / `-transparent`). Beyond the
375
+ accent-tint above, the emit also ships eight full-palette themes — `catppuccin`,
376
+ `tokyonight`, `rosepine`, `gruvbox`, `nord`, `everforest`, `kanagawa`, `dracula` — each
377
+ in a **solid** (opaque) and a **transparent** (terminal-background-through) flavour.
378
+ These are decoupled from the voice theme: any voice theme can run any colour theme.
379
+ Authored under `themes/opencode/` (see its README and
380
+ [the spec](../../docs/specs/2026-06-17-opencode-color-themes.md)).
381
+ - **Runtime guard plugin** (`geneseed-guard.js`, installed with the others). Enforces
382
+ the safety Laws at the tool boundary: **blocks** writes to private-key/credential
383
+ files (Law I), catastrophic shell like `rm -rf /` (Law IV), and any mutation under
384
+ a declared wiki's `protected` folders (AGENT.md §7, from `wiki.jsonc`); **warns** on
385
+ `.env` writes and force-push. `GENESEED_GUARD=off` disables it, `=warn` downgrades
386
+ blocks to warnings.
387
+ - **Invisible context injection** (the default). The context plugin delivers via
388
+ `experimental.chat.messages.transform`, so the PROJECT CONTEXT block never appears in
389
+ the conversation and survives compaction inherently; on a build without the hook it
390
+ auto-falls back to the visible `session.created` message. `GENESEED_CONTEXT_VISIBLE=1`
391
+ forces the visible block (legacy `GENESEED_CONTEXT_TRANSFORM=0/off` does the same).
392
+ - **Default permissions.** A fresh `opencode.json` gets a minimal policy that **asks**
393
+ before `rm -rf *` and **every `git commit` and `git push`** (the host-level backstop
394
+ for the consent-before-commit/push Rule — the agent never records or shares code
395
+ unprompted, on any branch; force-push is also called out explicitly). Added only when
396
+ you have no `permission` key — an existing policy is never touched. Routine local work
397
+ (edits, builds, tests) is unaffected; to allow frictionless commits/pushes, set
398
+ `"git commit*"` / `"git push*"` to `"allow"` in your own `permission.bash` map. (Note:
399
+ OpenCode lets a user pick "always allow" for the session, which makes the gate
400
+ session-sticky — the Claude Code adapter's PreToolUse hook re-asks every time instead.)
401
+ - **Primary agent** (`GENESEED_PRIMARY=1`). Emits a `mode: primary` orchestrator that
402
+ works by the Rules and delegates to the capability subagents. Off by default (it can
403
+ change which agent is your default, so it stays opt-in).
404
+ - **Slash commands** (`GENESEED_COMMANDS=1`). Also emits `.opencode/command/<name>.md`
405
+ for the hot skill set (commit, plan, code-review, review-response, verify, ship, debug,
406
+ research) so they get `/name` triggers, alongside the native skills. Off by default.
407
+
408
+ ## Language servers (LSP)
409
+
410
+ The emitted `opencode.json` carries `"lsp": true`, which turns on **every
411
+ built-in** OpenCode language server (LSP is off by default). That covers the
412
+ languages the harness targets with a single line — no per-language map.
413
+
414
+ | Language | Server | You install? |
415
+ |---|---|---|
416
+ | JavaScript / TypeScript / React / React Native | `typescript-language-server` | No — OpenCode self-downloads |
417
+ | Python | `pyright` | No — OpenCode self-downloads |
418
+ | Java | `jdtls` | **JDK 21+** — OpenCode downloads jdtls itself, but it runs on a JVM |
419
+ | SQL / PostgreSQL / Oracle | *none — by design* | — |
420
+
421
+ One server (`typescript-language-server`) covers JS, TS, React, and React
422
+ Native — they are all TS/JS, JSX included — so there is no separate React server.
423
+
424
+ **The one prerequisite the harness can't self-install:** a **JDK 21+** for
425
+ jdtls. OpenCode downloads the JS-runtime servers itself on first file-open, but
426
+ it can't install a JVM. The setup wizard checks for `java` and prints an install
427
+ hint (`brew install openjdk@21`, SDKMAN `sdk install java 21-tem`, or your
428
+ distro's JDK) when it's missing — it does not auto-install one.
429
+
430
+ **No SQL server, on purpose.** A SQL language server is dialect-locked
431
+ (`libpg_query`-based Postgres servers flag Oracle SQL as errors and vice versa)
432
+ and a `.sql` file maps to only one server with no per-file dialect signal. Rather
433
+ than mis-flag half of all SQL codebases we ship none; a project that knows its
434
+ dialect adds the matching server under its own `opencode.json` `lsp` key.
435
+
436
+ Air-gapped? Set `OPENCODE_DISABLE_LSP_DOWNLOAD=true` and pre-install each server.
437
+
438
+ ## MCP servers — document conversion (MarkItDown)
439
+
440
+ OpenCode loads MCP servers from the `mcp` key of `opencode.json`. The baseline
441
+ [`opencode.json`](opencode.json) registers one **local** server — Microsoft's
442
+ **MarkItDown** — so the `ingest` skill can convert PDF / Office / HTML → Markdown
443
+ through a single low-cost tool, `convert_to_markdown(uri)`, instead of shelling out
444
+ to a converter:
445
+
446
+ ```json
447
+ "mcp": {
448
+ "markitdown": { "type": "local", "command": ["uvx", "markitdown-mcp"], "enabled": true }
449
+ }
450
+ ```
451
+
452
+ It's a *reference* entry, not a hard dependency. A `local` server is just a command
453
+ OpenCode runs, so the command has to resolve — the `uvx` form above needs only
454
+ [uv](https://docs.astral.sh/uv/) and installs nothing (it fetches + caches on first
455
+ call). No uv? `pipx install markitdown-mcp` and swap the command to `["markitdown-mcp"]`.
456
+ Or drop the block entirely — the skill falls back to a CLI converter (MarkItDown /
457
+ Pandoc / Docling) and never installs one silently. Listed but not connecting? The
458
+ command isn't on PATH — see [SETUP.md → MCP server won't connect](../../SETUP.md#mcp-server-wont-connect).
459
+ Full runbook, including the corporate-TLS (`UV_SYSTEM_CERTS`) step and the OCR extras:
460
+ [SETUP.md → MarkItDown via MCP](../../SETUP.md#markitdown-via-mcp-opencode).
461
+
462
+ ## Optional add-on — git-worktree isolation (third-party, not vendored)
463
+
464
+ [`opencode-worktree`](https://github.com/kdcokenny/opencode-worktree) gives the
465
+ agent two tools — `worktree_create(branch, baseBranch?)` and
466
+ `worktree_delete(reason)` — that create an isolated git worktree under
467
+ `~/.local/share/opencode/worktree/<project-id>/<branch>/`, spawn a terminal with
468
+ OpenCode already running inside it, and auto-commit + clean up on delete. It pairs
469
+ well with the harness's parallel-agent workflows when you want *filesystem*
470
+ isolation, not just separate sessions.
471
+
472
+ It is **not vendored** and **not installed by the harness** — treat it like the
473
+ MarkItDown MCP server: a reference pointer you opt into, not a dependency. It does
474
+ not follow Geneseed's plugin convention (the vendored plugins are single-file,
475
+ zero-dependency `.js` copied by `cp …/plugins/*.js`; this one is multi-file
476
+ TypeScript with npm deps — `jsonc-parser`, `zod` — and Bun-only APIs like
477
+ `bun:sqlite`/`Bun.spawn`), so it can't ride the `build --emit opencode` install or
478
+ the global-install manifest. Install it on its own track instead.
479
+
480
+ It coexists cleanly with the vendored plugins — it only registers two tools and
481
+ hooks no events they use, so nothing double-fires.
482
+
483
+ ### Setup (extra steps the `*.js` plugins don't need)
484
+
485
+ Unlike the vendored plugins — which need nothing but the `cp` copy — this one
486
+ requires its own package manager and a config file:
487
+
488
+ 1. **Install [OCX](https://github.com/kdcokenny/ocx)** (the KDCO package manager) if
489
+ you don't have it. The worktree plugin is distributed through OCX's registry, not
490
+ copied into `~/.config/opencode/plugins/` like ours.
491
+ 2. **Add the plugin:**
492
+ ```bash
493
+ ocx add kdco/worktree --from https://registry.kdco.dev
494
+ ```
495
+ OCX manages its npm dependencies and updates for you. (No separate Bun install —
496
+ OpenCode already runs on Bun, which is what the plugin's `bun:sqlite`/`Bun.*` calls
497
+ need.)
498
+ 3. **Configure sync + lifecycle hooks.** The plugin auto-creates
499
+ `.opencode/worktree.jsonc` on first use. Fill in what each new worktree should
500
+ inherit and run — e.g. for a Node repo:
501
+ ```jsonc
502
+ {
503
+ "sync": {
504
+ "copyFiles": [".env", ".env.local"], // copied from the main worktree
505
+ "symlinkDirs": ["node_modules"], // symlinked, not duplicated
506
+ "exclude": []
507
+ },
508
+ "hooks": {
509
+ "postCreate": ["pnpm install"], // after the worktree is created
510
+ "preDelete": [] // before it's removed
511
+ }
512
+ }
513
+ ```
514
+ 4. **(Optional) terminal multiplexer.** Terminal spawning is auto-detected across
515
+ macOS/Linux/Windows; it prefers `tmux` when you're already inside it and
516
+ [`cmux`](https://www.cmux.dev/) for agentic workflows. Neither is required —
517
+ it falls back to your OS default terminal.
518
+
519
+ **Manual install (no OCX):** copy the plugin's `src/` into `.opencode/plugin/` and
520
+ install `jsonc-parser` yourself — you lose OCX's dependency management and
521
+ auto-updates, and you own the upgrade-by-re-copy. Prefer the OCX path.
522
+
523
+ **Consent note.** `worktree_delete` auto-commits before removal. The harness's
524
+ consent-before-commit Rule is enforced for *shell* `git commit` via `opencode.json`
525
+ permissions, but this plugin commits through its own tool path — so review what it
526
+ will commit before invoking delete, or keep the worktree and commit yourself.
527
+
528
+ ## Optional add-on — interactive TUI canvases (third-party, not vendored)
529
+
530
+ [`@mailshieldai/opencode-canvas`](https://github.com/mailshieldai/opencode-canvas)
531
+ (MIT) lets the agent spawn rich, interactive terminal UIs in a tmux split — a
532
+ calendar/date picker, a document editor, a flight-search panel — and read the user's
533
+ selection back. It registers four tools (`canvas_spawn`, `canvas_update`,
534
+ `canvas_selection`, `canvas_close`) that talk to the TUI over a Unix socket. Reach for
535
+ it when a choice is genuinely easier *picked* than typed.
536
+
537
+ Like the worktree add-on, it is **not vendored** and **not installed by the harness**,
538
+ and does not follow Geneseed's plugin convention (the four vendored plugins are
539
+ single-file, zero-dependency `.js` copied by `cp …/plugins/*.js`): it ships as a
540
+ multi-file TypeScript npm package that runs on **Bun** and needs **tmux**, so it can't
541
+ ride the `build --emit opencode` install or the global-install manifest. Install it on
542
+ its own track.
543
+
544
+ ### Setup
545
+
546
+ 1. **Prerequisites.** Ensure `bun` and `tmux` are on `PATH` — OpenCode already runs on
547
+ Bun; the canvases render inside a tmux split, so you must be in (or able to start) a
548
+ tmux session.
549
+ 2. **Register the plugin and grant its tools** in your `opencode.jsonc` (project
550
+ `./opencode.json[c]` or the global config dir). OpenCode resolves the npm package by
551
+ name — no manual `bun add`:
552
+ ```jsonc
553
+ {
554
+ // ... your existing Geneseed config (instructions, the four geneseed plugins) ...
555
+ "plugin": ["@mailshieldai/opencode-canvas"],
556
+ "permission": {
557
+ "canvas_spawn": "allow",
558
+ "canvas_update": "allow",
559
+ "canvas_selection": "allow",
560
+ "canvas_close": "allow"
561
+ }
562
+ }
563
+ ```
564
+ `plugin` and `permission` **merge** with Geneseed's — list the canvas plugin
565
+ alongside (don't replace) anything the harness already put there. Check the
566
+ upstream README for the current package name and any version pin.
567
+ 3. **Verify.** Start OpenCode inside tmux and confirm the `canvas_*` tools appear in the
568
+ tool list; a first `canvas_spawn` should open a pane.
569
+
570
+ It coexists with the vendored plugins (it only adds the four `canvas_*` tools and a
571
+ socket; it hooks none of the events `context`/`learn`/`guard`/`workflow` use, so
572
+ nothing double-fires). It is host-specific and adds runtime dependencies, so adopt it
573
+ deliberately, not by default.
574
+
575
+ ## Notes
576
+
577
+ - Project config beats global; `./opencode.json` or `.opencode/opencode.json`
578
+ both work (OpenCode walks up to the worktree root).
579
+ - `instructions` in `opencode.json` accepts absolute paths, repo-relative paths,
580
+ globs (`"laws/*.md"`), and URLs — edit it directly for ambient rule files.
581
+ - OpenCode also auto-loads external skills from `~/.claude/skills/` — unrelated to
582
+ this harness, but handy to know.
@@ -0,0 +1,25 @@
1
+ You are the primary agent for a repository running the Geneseed harness.
2
+
3
+ Operate by the Rules in `AGENT.md` — load them, and the project context, before your
4
+ first action. Rather than doing everything in one context, delegate focused work to the
5
+ capability subagents and keep your own context lean:
6
+
7
+ - **reviewer** — a change is ready and needs a correctness + quality pass before merge.
8
+ - **tester** — tests must be written, run, or a failure diagnosed.
9
+ - **architect** — a task needs a design or plan before any code is written.
10
+ - **docs** — code has landed and user-facing docs must follow.
11
+ - **security** — a change touches auth, input handling, secrets, or dependencies.
12
+ - **explorer** — many files must be swept for an answer and you want only the conclusion.
13
+
14
+ Hold to the discipline the Rules describe: plan before non-trivial work, verify before
15
+ claiming done, keep each change to one intent, read the docs before touching a part, and
16
+ persist durable insight to memory. When a task matches a Skill, run the Skill before
17
+ improvising. You own the conversation; the subagents own their slices.
18
+
19
+ When a goal spans several capabilities, dispatch it rather than serially doing it all
20
+ yourself: decompose into independent subtasks, route each to the single owning subagent
21
+ above, and converge the results yourself. Prefer the saved `dispatch` workflow when the
22
+ `workflow` tool is available; otherwise follow the parallel-agents Skill. Every handoff
23
+ carries an envelope — the subtask goal, the inputs the agent needs, its output contract —
24
+ and the constraints travel with it: subagents never commit or push (Law XX stays with
25
+ you), and an unfulfilled contract comes back as a stated gap, never invented content.
@@ -0,0 +1,44 @@
1
+ {
2
+ "$schema": "https://opencode.ai/config.json",
3
+ "instructions": ["AGENT.md"],
4
+ "permission": {
5
+ "bash": {
6
+ "rm -rf *": "ask",
7
+ "git commit*": "ask",
8
+ "git push*": "ask",
9
+ "git push --force*": "ask",
10
+ "git push -f*": "ask"
11
+ }
12
+ },
13
+ "lsp": true,
14
+ "mcp": {
15
+ "markitdown": {
16
+ "type": "local",
17
+ "command": ["uvx", "markitdown-mcp"],
18
+ "enabled": true
19
+ },
20
+ "gitlab": {
21
+ "type": "local",
22
+ "command": ["npx", "-y", "@zereight/mcp-gitlab"],
23
+ "environment": {
24
+ "GITLAB_PERSONAL_ACCESS_TOKEN": "",
25
+ "GITLAB_API_URL": "https://gitlab.com/api/v4"
26
+ },
27
+ "enabled": false
28
+ },
29
+ "gitlab-2": {
30
+ "type": "local",
31
+ "command": ["npx", "-y", "@zereight/mcp-gitlab"],
32
+ "environment": {
33
+ "GITLAB_PERSONAL_ACCESS_TOKEN": "",
34
+ "GITLAB_API_URL": "https://gitlab.example.com/api/v4"
35
+ },
36
+ "enabled": false
37
+ },
38
+ "filesystem": {
39
+ "type": "local",
40
+ "command": ["npx", "-y", "@modelcontextprotocol/server-filesystem", "/path/to/allowed/dir"],
41
+ "enabled": false
42
+ }
43
+ }
44
+ }