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.
- package/CHANGELOG.md +938 -0
- package/DESIGN.md +1423 -0
- package/LICENSE +21 -0
- package/QUICKSTART.md +48 -0
- package/README.md +336 -0
- package/SETUP.md +1027 -0
- package/SHIPPED.md +70 -0
- package/adapters/bob/README.md +100 -0
- package/adapters/claude-code/README.md +101 -0
- package/adapters/claude-code/settings.json +47 -0
- package/adapters/claude-code/skills/geneseed/SKILL.md +72 -0
- package/adapters/copilot/README.md +76 -0
- package/adapters/opencode/GLOBAL-HARNESS-SPEC.md +434 -0
- package/adapters/opencode/HOW-OPENCODE-LOADS.md +158 -0
- package/adapters/opencode/README.md +582 -0
- package/adapters/opencode/agents/orchestrator.md +25 -0
- package/adapters/opencode/opencode.json +44 -0
- package/adapters/opencode/plugins/geneseed-activity.js +430 -0
- package/adapters/opencode/plugins/geneseed-context.js +876 -0
- package/adapters/opencode/plugins/geneseed-guard.js +290 -0
- package/adapters/opencode/plugins/geneseed-learn.js +396 -0
- package/adapters/opencode/plugins/geneseed-notify.js +142 -0
- package/adapters/opencode/plugins/geneseed-ponytail.js +148 -0
- package/adapters/opencode/plugins/geneseed-workflow.js +183 -0
- package/adapters/opencode/workflows/_runtime.js +277 -0
- package/adapters/opencode/workflows/council.js +64 -0
- package/adapters/opencode/workflows/dispatch.js +89 -0
- package/adapters/opencode/workflows/research-plan-implement.js +43 -0
- package/adapters/opencode/workflows/review.js +57 -0
- package/bin/geneseed-cli.mjs +412 -0
- package/bin/geneseed-hook.mjs +129 -0
- package/bin/geneseed.mjs +1086 -0
- package/docs/declined.md +149 -0
- package/docs/limits.md +270 -0
- package/docs/opencode-plugin-setup.md +64 -0
- package/docs/token-footprint.md +68 -0
- package/docs/web/_groups.json +45 -0
- package/docs/web/about.md +6 -0
- package/docs/web/adapters-claude-code.md +8 -0
- package/docs/web/adapters-opencode-loads.md +8 -0
- package/docs/web/adapters-opencode-spec.md +8 -0
- package/docs/web/adapters-opencode.md +8 -0
- package/docs/web/agents.md +8 -0
- package/docs/web/authoring.md +11 -0
- package/docs/web/autostart.md +9 -0
- package/docs/web/claude-hooks.md +36 -0
- package/docs/web/cli.md +6 -0
- package/docs/web/collaboration.md +27 -0
- package/docs/web/configure-wiki.md +9 -0
- package/docs/web/design.md +7 -0
- package/docs/web/env-knobs.md +9 -0
- package/docs/web/exclusions.md +26 -0
- package/docs/web/first-session.md +28 -0
- package/docs/web/footprint.md +31 -0
- package/docs/web/foreman-mode.md +33 -0
- package/docs/web/glossary.md +6 -0
- package/docs/web/harnesses.md +28 -0
- package/docs/web/headless.md +9 -0
- package/docs/web/ingest-docs.md +9 -0
- package/docs/web/install-paths.md +9 -0
- package/docs/web/install-quick.md +35 -0
- package/docs/web/lsp-overview.md +37 -0
- package/docs/web/mcp-claude-code.md +10 -0
- package/docs/web/mcp-filesystem.md +9 -0
- package/docs/web/mcp-gitlab.md +9 -0
- package/docs/web/mcp-markitdown.md +9 -0
- package/docs/web/mcp-overview.md +34 -0
- package/docs/web/mcp-trouble.md +9 -0
- package/docs/web/mcp-verify.md +9 -0
- package/docs/web/memory.md +7 -0
- package/docs/web/migrate.md +39 -0
- package/docs/web/model.md +20 -0
- package/docs/web/notebook.md +7 -0
- package/docs/web/pipelines.md +24 -0
- package/docs/web/plugin-activity.md +23 -0
- package/docs/web/plugin-context.md +26 -0
- package/docs/web/plugin-guard.md +24 -0
- package/docs/web/plugin-learn.md +27 -0
- package/docs/web/plugin-notify.md +24 -0
- package/docs/web/plugin-ponytail.md +23 -0
- package/docs/web/plugin-setup.md +7 -0
- package/docs/web/plugin-workflow.md +24 -0
- package/docs/web/plugins.md +17 -0
- package/docs/web/project-context.md +9 -0
- package/docs/web/rules.md +8 -0
- package/docs/web/run-anywhere.md +9 -0
- package/docs/web/self-improve.md +8 -0
- package/docs/web/setup-choices.md +39 -0
- package/docs/web/skills.md +8 -0
- package/docs/web/themes-author.md +8 -0
- package/docs/web/themes.md +9 -0
- package/docs/web/token-footprint.md +7 -0
- package/docs/web/trouble.md +38 -0
- package/docs/web/upgrade.md +9 -0
- package/docs/web/verify.md +30 -0
- package/docs/web/wiki.md +7 -0
- package/docs/web/worktree.md +10 -0
- package/docs/web-ui.md +144 -0
- package/docs/wiki.md +43 -0
- package/geneseed +39 -0
- package/geneseed.cmd +34 -0
- package/harness.config.json +6 -0
- package/js/anim.mjs +326 -0
- package/js/catalog.mjs +112 -0
- package/js/checkout.mjs +88 -0
- package/js/cli-table.json +1034 -0
- package/js/cli.mjs +498 -0
- package/js/diff.mjs +384 -0
- package/js/doctor.mjs +1364 -0
- package/js/emit.mjs +1373 -0
- package/js/excludes.mjs +271 -0
- package/js/generate.mjs +379 -0
- package/js/hooks.mjs +1026 -0
- package/js/hosts.mjs +253 -0
- package/js/installs.mjs +378 -0
- package/js/inventory.mjs +175 -0
- package/js/lib/fs.mjs +913 -0
- package/js/lib/proc.mjs +28 -0
- package/js/lib/udiff.mjs +275 -0
- package/js/link.mjs +286 -0
- package/js/mcp.mjs +335 -0
- package/js/memory.mjs +108 -0
- package/js/menu.mjs +118 -0
- package/js/migrate.mjs +251 -0
- package/js/native.mjs +426 -0
- package/js/opencode.mjs +325 -0
- package/js/registry.mjs +110 -0
- package/js/render.mjs +282 -0
- package/js/settings.mjs +924 -0
- package/js/setup.mjs +492 -0
- package/js/status.mjs +281 -0
- package/js/themes.mjs +195 -0
- package/js/tui.mjs +444 -0
- package/js/uninstall.mjs +1137 -0
- package/js/update.mjs +910 -0
- package/js/web/actions.mjs +868 -0
- package/js/web/activity.mjs +284 -0
- package/js/web/api.mjs +873 -0
- package/js/web/docs.mjs +531 -0
- package/js/web/graph.mjs +0 -0
- package/js/web/jobs.mjs +480 -0
- package/js/web/server.mjs +1135 -0
- package/package.json +54 -0
- package/registry.json +474 -0
- package/src/AGENT.md.tmpl +390 -0
- package/src/agents/_template.md +76 -0
- package/src/agents/advocate.md +36 -0
- package/src/agents/architect.md +55 -0
- package/src/agents/developer.md +66 -0
- package/src/agents/docs.md +54 -0
- package/src/agents/empiricist.md +39 -0
- package/src/agents/explorer.md +54 -0
- package/src/agents/framer.md +36 -0
- package/src/agents/historian.md +51 -0
- package/src/agents/operator.md +37 -0
- package/src/agents/pragmatist.md +37 -0
- package/src/agents/reviewer.md +52 -0
- package/src/agents/security.md +57 -0
- package/src/agents/skeptic.md +48 -0
- package/src/agents/steward.md +36 -0
- package/src/agents/tester.md +54 -0
- package/src/agents/user-advocate.md +36 -0
- package/src/agents/visionary.md +36 -0
- package/src/laws/universal.md +387 -0
- package/src/memory/README.md +109 -0
- package/src/memory/gitignore +6 -0
- package/src/modes/README.md +26 -0
- package/src/modes/direct.md +2 -0
- package/src/modes/foreman.md +19 -0
- package/src/notebook/README.md +39 -0
- package/src/notebook/gitignore +7 -0
- package/src/postures/README.md +31 -0
- package/src/postures/artisan.md +14 -0
- package/src/postures/assistant.md +12 -0
- package/src/postures/expert.md +11 -0
- package/src/postures/mentor.md +11 -0
- package/src/postures/peer.md +12 -0
- package/src/skills/_template.md +47 -0
- package/src/skills/brainstorm.md +28 -0
- package/src/skills/clarify.md +28 -0
- package/src/skills/codebase-design.md +44 -0
- package/src/skills/commit.md +48 -0
- package/src/skills/council.md +34 -0
- package/src/skills/crash-course.md +28 -0
- package/src/skills/daydream/.claude-plugin/plugin.json +9 -0
- package/src/skills/daydream/SKILL.md +74 -0
- package/src/skills/daydream/VENDOR.md +25 -0
- package/src/skills/daydream/critic-prompt.md +38 -0
- package/src/skills/daydream/instructions.md +422 -0
- package/src/skills/daydream/synthesizer-prompt.md +41 -0
- package/src/skills/debug.md +37 -0
- package/src/skills/decode.md +28 -0
- package/src/skills/develop.md +29 -0
- package/src/skills/document-project.md +79 -0
- package/src/skills/domain-modeling.md +38 -0
- package/src/skills/drill.md +28 -0
- package/src/skills/feynman.md +26 -0
- package/src/skills/forge-mcp.md +48 -0
- package/src/skills/fresh-eyes.md +29 -0
- package/src/skills/frontend-design.md +58 -0
- package/src/skills/gap-detector.md +27 -0
- package/src/skills/geneseed-code-review.md +33 -0
- package/src/skills/geneseed.md +29 -0
- package/src/skills/git-archaeology.md +47 -0
- package/src/skills/git-rescue.md +68 -0
- package/src/skills/handoff.md +29 -0
- package/src/skills/herdr.md +164 -0
- package/src/skills/ingest.md +49 -0
- package/src/skills/learning-path.md +26 -0
- package/src/skills/migrate.md +45 -0
- package/src/skills/opencode-theme.md +52 -0
- package/src/skills/parallel-agents.md +28 -0
- package/src/skills/pipeline.md +52 -0
- package/src/skills/plan.md +45 -0
- package/src/skills/ponytail.md +29 -0
- package/src/skills/profile.md +58 -0
- package/src/skills/prose.md +42 -0
- package/src/skills/prototype.md +44 -0
- package/src/skills/react-view-transitions/AGENTS.md +955 -0
- package/src/skills/react-view-transitions/README.md +42 -0
- package/src/skills/react-view-transitions/SKILL.md +320 -0
- package/src/skills/react-view-transitions/VENDOR.md +16 -0
- package/src/skills/react-view-transitions/metadata.json +12 -0
- package/src/skills/react-view-transitions/references/css-recipes.md +242 -0
- package/src/skills/react-view-transitions/references/implementation.md +182 -0
- package/src/skills/react-view-transitions/references/nextjs.md +176 -0
- package/src/skills/react-view-transitions/references/patterns.md +262 -0
- package/src/skills/refactor.md +32 -0
- package/src/skills/release.md +43 -0
- package/src/skills/repo-map.md +36 -0
- package/src/skills/research.md +42 -0
- package/src/skills/review-response.md +36 -0
- package/src/skills/roast-me.md +28 -0
- package/src/skills/rule.md +100 -0
- package/src/skills/ship.md +49 -0
- package/src/skills/tdd.md +31 -0
- package/src/skills/tickets.md +44 -0
- package/src/skills/token-report/SKILL.md +76 -0
- package/src/skills/token-report/VENDOR.md +23 -0
- package/src/skills/token-report/scripts/token_report.mjs +1301 -0
- package/src/skills/wayfinder.md +49 -0
- package/src/skills/wiki.md +68 -0
- package/src/skills/workflow.md +38 -0
- package/themes/README.md +69 -0
- package/themes/_TEMPLATE.json +147 -0
- package/themes/biker.json +147 -0
- package/themes/commentator.json +147 -0
- package/themes/cyberpunk.json +147 -0
- package/themes/gamer.json +147 -0
- package/themes/imperial.json +147 -0
- package/themes/joker.json +147 -0
- package/themes/marvin.json +147 -0
- package/themes/mean.json +147 -0
- package/themes/military.json +147 -0
- package/themes/neutral.json +147 -0
- package/themes/opencode/README.md +58 -0
- package/themes/opencode/catppuccin.json +27 -0
- package/themes/opencode/dracula.json +27 -0
- package/themes/opencode/everforest.json +27 -0
- package/themes/opencode/gruvbox.json +27 -0
- package/themes/opencode/kanagawa.json +27 -0
- package/themes/opencode/neon.json +27 -0
- package/themes/opencode/nord.json +27 -0
- package/themes/opencode/rosepine.json +27 -0
- package/themes/opencode/tokyonight.json +27 -0
- package/themes/pirate.json +147 -0
- package/themes/sports.json +147 -0
- package/themes/verstappen.json +147 -0
- package/themes/wizard.json +147 -0
- package/web/dist/assets/About-DX1-VTBP.js +1 -0
- package/web/dist/assets/Activity-Dp9NaXOn.js +1 -0
- package/web/dist/assets/ActivityDetail-HpOBtrXS.js +1 -0
- package/web/dist/assets/Diff-Ct4G3Se8.js +5 -0
- package/web/dist/assets/Doctor-DGjkZFuA.js +1 -0
- package/web/dist/assets/Graph-b8o-S6kv.js +1 -0
- package/web/dist/assets/Harnesses-gr3-aHBF.js +1 -0
- package/web/dist/assets/Laws-DTwF5tTC.js +1 -0
- package/web/dist/assets/Library-BEZscyaQ.js +1 -0
- package/web/dist/assets/Markdown-k_LSLBGq.js +1 -0
- package/web/dist/assets/Profile-DydukTxP.js +1 -0
- package/web/dist/assets/Rules-CIRG4Ldt.js +1 -0
- package/web/dist/assets/Skills-Buoi1IBr.js +1 -0
- package/web/dist/assets/StatusBadge-CE_AJttl.js +1 -0
- package/web/dist/assets/Themes-CI4o3gJC.js +2 -0
- package/web/dist/assets/activity-BCW7e6Cy.js +1 -0
- package/web/dist/assets/audiowide-latin-400-normal-6GFCX7ni.woff2 +0 -0
- package/web/dist/assets/geist-mono-latin-400-normal-DKaoCDn5.woff2 +0 -0
- package/web/dist/assets/geist-mono-latin-500-normal-C3sF8Y1B.woff2 +0 -0
- package/web/dist/assets/geist-mono-latin-600-normal-BHzjB6_C.woff2 +0 -0
- package/web/dist/assets/hanken-grotesk-latin-400-italic-Bserb8X5.woff2 +0 -0
- package/web/dist/assets/hanken-grotesk-latin-400-normal-BG6hkEXj.woff2 +0 -0
- package/web/dist/assets/hanken-grotesk-latin-500-italic-BGfwwhek.woff2 +0 -0
- package/web/dist/assets/hanken-grotesk-latin-500-normal-DrDcrrxK.woff2 +0 -0
- package/web/dist/assets/hanken-grotesk-latin-600-normal-CIXX6EOa.woff2 +0 -0
- package/web/dist/assets/hanken-grotesk-latin-700-normal-CeQ8H3UY.woff2 +0 -0
- package/web/dist/assets/ibm-plex-mono-latin-400-normal-DMJ8VG8y.woff2 +0 -0
- package/web/dist/assets/ibm-plex-mono-latin-500-normal-DSY6xOcd.woff2 +0 -0
- package/web/dist/assets/ibm-plex-mono-latin-600-normal-BgSNZQsw.woff2 +0 -0
- package/web/dist/assets/ibm-plex-serif-latin-400-normal-BIGslYFI.woff2 +0 -0
- package/web/dist/assets/ibm-plex-serif-latin-500-normal-REKAfBVG.woff2 +0 -0
- package/web/dist/assets/ibm-plex-serif-latin-600-normal-DAxitmSu.woff2 +0 -0
- package/web/dist/assets/index-B1PIx7RM.js +1 -0
- package/web/dist/assets/index-BnTQUSUz.js +12 -0
- package/web/dist/assets/index-Ck2iCdaC.js +2 -0
- package/web/dist/assets/index-DUCsDv7z.css +1 -0
- package/web/dist/assets/inter-latin-400-normal-C38fXH4l.woff2 +0 -0
- package/web/dist/assets/inter-latin-500-normal-Cerq10X2.woff2 +0 -0
- package/web/dist/assets/inter-latin-600-normal-LgqL8muc.woff2 +0 -0
- package/web/dist/assets/inter-latin-700-normal-Yt3aPRUw.woff2 +0 -0
- package/web/dist/assets/jetbrains-mono-latin-400-normal-V6pRDFza.woff2 +0 -0
- package/web/dist/assets/jetbrains-mono-latin-500-normal-BWZEU5yA.woff2 +0 -0
- package/web/dist/assets/jetbrains-mono-latin-600-normal-C8RAYTDA.woff2 +0 -0
- package/web/dist/assets/marked.esm-JKvyS0Pp.js +46 -0
- package/web/dist/assets/oswald-latin-400-normal-BAFo8sP8.woff2 +0 -0
- package/web/dist/assets/oswald-latin-500-normal-B-eyT0Dw.woff2 +0 -0
- package/web/dist/assets/oswald-latin-600-normal-plFmSr5g.woff2 +0 -0
- package/web/dist/assets/oswald-latin-700-normal-vy6hmKSr.woff2 +0 -0
- package/web/dist/assets/poppins-latin-400-normal-cpxAROuN.woff2 +0 -0
- package/web/dist/assets/poppins-latin-500-normal-C8OXljZJ.woff2 +0 -0
- package/web/dist/assets/poppins-latin-600-normal-zEkxB9Mr.woff2 +0 -0
- package/web/dist/assets/poppins-latin-700-normal-Qrb0O0WB.woff2 +0 -0
- package/web/dist/assets/react-DOpiTn5v.js +32 -0
- package/web/dist/assets/roman-DkYN0LX9.js +1 -0
- package/web/dist/assets/space-grotesk-latin-400-normal-CJ-V5oYT.woff2 +0 -0
- package/web/dist/assets/space-grotesk-latin-500-normal-lFbtlQH6.woff2 +0 -0
- package/web/dist/assets/space-grotesk-latin-600-normal-DjKNqYRj.woff2 +0 -0
- package/web/dist/assets/space-grotesk-latin-700-normal-RjhwGPKo.woff2 +0 -0
- package/web/dist/assets/space-mono-latin-400-italic-YylcN9Ay.woff2 +0 -0
- package/web/dist/assets/space-mono-latin-400-normal-Rg4St2Dn.woff2 +0 -0
- package/web/dist/assets/space-mono-latin-700-italic-vNvENeTh.woff2 +0 -0
- package/web/dist/assets/space-mono-latin-700-normal-mWgeinG7.woff2 +0 -0
- package/web/dist/icon-maskable.svg +10 -0
- package/web/dist/icon.svg +8 -0
- package/web/dist/index.html +21 -0
- package/web/dist/manifest.webmanifest +14 -0
- package/web/dist/sw.js +40 -0
- 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
|
+
}
|