geneseed 4.10.0 β 4.15.1
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 +106 -0
- package/README.md +5 -4
- package/SHIPPED.md +1 -1
- package/adapters/opencode/plugins/geneseed-guard.js +16 -1
- package/adapters/opencode/plugins/geneseed-learn.js +28 -12
- package/adapters/opencode/plugins/geneseed-workflow.js +19 -2
- package/docs/concepts/kits.md +14 -2
- package/docs/concepts/skills.md +1 -1
- package/docs/extending.md +3 -4
- package/docs/guides/install-bob.md +3 -1
- package/docs/guides/run-anywhere.md +2 -2
- package/docs/guides/upgrade.md +2 -2
- package/docs/reference/troubleshoot-install.md +1 -1
- package/docs/web-ui.md +6 -1
- package/harness.config.json +1 -1
- package/js/build/emit-claude.mjs +4 -2
- package/js/build/stubs.mjs +13 -0
- package/js/hosts/link.mjs +88 -1
- package/js/inspect/checks-build.mjs +8 -2
- package/js/inspect/cost.mjs +1 -1
- package/js/inspect/diff.mjs +53 -7
- package/js/inspect/inventory.mjs +1 -0
- package/js/lib/prompt.mjs +19 -2
- package/js/maintain/setup.mjs +92 -28
- package/js/maintain/update.mjs +2 -2
- package/js/web/actions.mjs +8 -0
- package/js/web/api.mjs +39 -17
- package/js/web/catalog.mjs +17 -2
- package/js/web/handler.mjs +1 -0
- package/js/web/server.mjs +11 -5
- package/js/web/state.mjs +38 -3
- package/package.json +1 -1
- package/registry.json +28 -0
- package/src/AGENT.md.tmpl +5 -5
- package/src/agents/_self-improvement.md +11 -0
- package/src/agents/_template.md +1 -8
- package/src/agents/advocate.md +1 -8
- package/src/agents/architect.md +1 -8
- package/src/agents/developer.md +1 -8
- package/src/agents/devops-engineer.md +1 -9
- package/src/agents/docker-expert.md +1 -9
- package/src/agents/docs.md +1 -8
- package/src/agents/empiricist.md +1 -8
- package/src/agents/explorer.md +1 -8
- package/src/agents/framer.md +1 -8
- package/src/agents/historian.md +1 -8
- package/src/agents/kubernetes-specialist.md +1 -9
- package/src/agents/memory-curator.md +1 -8
- package/src/agents/operator.md +1 -8
- package/src/agents/performance.md +1 -8
- package/src/agents/pragmatist.md +1 -8
- package/src/agents/react-engineer.md +38 -0
- package/src/agents/react-reviewer.md +42 -0
- package/src/agents/researcher.md +5 -10
- package/src/agents/reviewer.md +1 -8
- package/src/agents/security.md +1 -8
- package/src/agents/skeptic.md +1 -8
- package/src/agents/spring-boot-engineer.md +1 -9
- package/src/agents/spring-reviewer.md +1 -9
- package/src/agents/spring-security.md +1 -9
- package/src/agents/steward.md +1 -8
- package/src/agents/tester.md +1 -8
- package/src/agents/user-advocate.md +1 -8
- package/src/agents/visionary.md +1 -8
- package/src/doctrines/comms.md +21 -0
- package/src/kits/react/rules.md +13 -0
- package/src/kits/react.json +18 -0
- package/src/licenses/everything-claude-code.txt +21 -0
- package/src/skills/_self-improvement.md +22 -5
- package/src/skills/brainstorm.md +7 -2
- package/src/skills/codebase-design.md +6 -2
- package/src/skills/debug.md +1 -1
- package/src/skills/develop.md +4 -2
- package/src/skills/handoff.md +1 -1
- package/src/skills/parallel-agents.md +3 -1
- package/src/skills/plan.md +5 -2
- package/src/skills/prototype.md +4 -2
- package/src/skills/react/a11y.md +33 -0
- package/src/skills/react/vite.md +35 -0
- package/src/skills/react/webpack.md +40 -0
- package/src/skills/react-testing.md +68 -0
- package/src/skills/react.md +63 -0
- package/src/skills/research.md +4 -2
- package/src/skills/rule.md +4 -2
- package/src/skills/ship.md +6 -4
- package/src/skills/skill-forge.md +10 -5
- package/src/skills/wayfinder.md +6 -2
- package/src/skills/wiki.md +18 -5
- package/src/upstreams.json +7 -0
- package/themes/_TEMPLATE.json +5 -0
- package/themes/biker.json +5 -0
- package/themes/commentator.json +5 -0
- package/themes/cyberpunk.json +5 -0
- package/themes/gamer.json +5 -0
- package/themes/imperial.json +5 -0
- package/themes/joker.json +5 -0
- package/themes/marvin.json +5 -0
- package/themes/mean.json +5 -0
- package/themes/military.json +5 -0
- package/themes/neutral.json +5 -0
- package/themes/pirate.json +5 -0
- package/themes/sports.json +5 -0
- package/themes/verstappen.json +5 -0
- package/themes/wizard.json +5 -0
- package/web/dist/assets/Activity-M5qj6CxJ.js +1 -0
- package/web/dist/assets/ActivityDetail-DVCdNy73.js +1 -0
- package/web/dist/assets/Dashboard-B1rpgTz-.js +2 -0
- package/web/dist/assets/{Docs-DLVckkew.js β Docs-D-EixVuX.js} +3 -3
- package/web/dist/assets/FilterInput-CZREvrjX.js +1 -0
- package/web/dist/assets/GreenhouseView-BvA4t12P.js +2 -0
- package/web/dist/assets/Installs-DP4WjTpD.js +3 -0
- package/web/dist/assets/JournalView-hf2eO133.js +1 -0
- package/web/dist/assets/KitApply-aORiqjFC.js +1 -0
- package/web/dist/assets/Kits-DpIEozdv.js +1 -0
- package/web/dist/assets/{Laws-BkKnZOBI.js β Laws-cM_4CG9i.js} +2 -2
- package/web/dist/assets/Library-I1zEH3UW.js +1 -0
- package/web/dist/assets/Loops-CDa_mxP9.js +2 -0
- package/web/dist/assets/{Markdown-iHvBrpRN.js β Markdown-zaXXXHz9.js} +13 -13
- package/web/dist/assets/OperatorHudView-CMf1DQMB.js +2 -0
- package/web/dist/assets/Personal-BqU9Pzt1.js +1 -0
- package/web/dist/assets/Tabs-JZ2FQBcz.js +1 -0
- package/web/dist/assets/activity-Jw8XcPiP.js +1 -0
- package/web/dist/assets/{drawable-CgYi0Dtg.js β drawable-svc6-2Gp.js} +1 -1
- package/web/dist/assets/index-CZFrNe4N.js +2 -0
- package/web/dist/assets/{index-BCJz4_8C.css β index-jYlWihN-.css} +1 -1
- package/web/dist/assets/{react-BOF6yL40.js β react-DlYQp10C.js} +1 -1
- package/web/dist/assets/rolldown-runtime-hePW80VL.js +1 -0
- package/web/dist/assets/sections-ChwaobfW.js +1 -0
- package/web/dist/assets/usePoll-bDFN-Hr6.js +1 -0
- package/web/dist/index.html +5 -4
- package/web/src/pages/Laws.jsx +5 -0
- package/web/dist/assets/Activity-BjyJaf8e.js +0 -1
- package/web/dist/assets/ActivityDetail-Bo9nRDNV.js +0 -1
- package/web/dist/assets/Dashboard-BQJGU7vE.js +0 -2
- package/web/dist/assets/FilterInput-zLFXoSt6.js +0 -1
- package/web/dist/assets/GreenhouseView--DML7CW3.js +0 -2
- package/web/dist/assets/Installs-CxCiln1F.js +0 -3
- package/web/dist/assets/JournalView-ymgZleHi.js +0 -1
- package/web/dist/assets/Library-C8ercIZv.js +0 -1
- package/web/dist/assets/Loops-C95zhbFl.js +0 -2
- package/web/dist/assets/OperatorHudView-B9qwc3w3.js +0 -2
- package/web/dist/assets/Personal-DyR72AF-.js +0 -1
- package/web/dist/assets/Tabs-ChCr_HqV.js +0 -1
- package/web/dist/assets/activity-DvPxoS4Y.js +0 -1
- package/web/dist/assets/index-B32EvfDT.js +0 -2
- package/web/dist/assets/sections-BET3c1WT.js +0 -1
- package/web/dist/assets/usePoll-NSTzLOF4.js +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,112 @@ label. For the capability β spec map, see [SHIPPED.md](SHIPPED.md).
|
|
|
8
8
|
|
|
9
9
|
## [Unreleased]
|
|
10
10
|
|
|
11
|
+
## [4.15.1] β 2026-10-23
|
|
12
|
+
|
|
13
|
+
Patch: two host fixes. The first npm release since 4.14.0, so it also carries 4.15.0's comms 4 doctrine.
|
|
14
|
+
|
|
15
|
+
### Upgrade notes
|
|
16
|
+
- Run `geneseed rebuild-all`; nothing changes on a machine until something re-emits.
|
|
17
|
+
|
|
18
|
+
### Fixed
|
|
19
|
+
- OpenCode 1.x: the guard and learn plugins no longer write `[geneseed-guard] β¦` / `[geneseed-learn] β¦` lines in red over the TUI input box. Their messages now go to OpenCode's own log (`client.app.log`, service `geneseed-guard` / `geneseed-learn`). OpenCode 2 and a refused log call still use stderr. The workflow plugin's one-line load banner stays on stderr.
|
|
20
|
+
- IBM Bob: the first reply now starts with the theme's readiness line. Both Bob carriers (global `rules/geneseed.md`, the project's `AGENTS.md` block) open with a short first-reply override; without it, Bob's own greeting won. A bare "hi" still gets Bob's fixed welcome. Run `geneseed rebuild-all` to pick it up.
|
|
21
|
+
|
|
22
|
+
## [4.15.0] β 2026-10-22
|
|
23
|
+
|
|
24
|
+
Minor: a new comms doctrine rule makes every generated agent write its prose in ASD-STE100 Simplified Technical English.
|
|
25
|
+
|
|
26
|
+
### Upgrade notes
|
|
27
|
+
- Run `geneseed rebuild-all` to get the new rule; nothing changes on a machine until something re-emits. To keep the old behaviour on one install, rebuild it with `--exclude-rules "comms 4"`.
|
|
28
|
+
|
|
29
|
+
### Added
|
|
30
|
+
- **Doctrine comms 4, Simplified Technical English.** Every generated agent writes the prose of its replies and reports in ASD-STE100: one topic per sentence (at most 20 words in an instruction, 25 in a description), imperative steps with one action each and the condition first, the active voice, no -ing forms, no dropped articles, and one word per meaning. Code, commands, paths, identifiers and quoted output stay as they are. STE is an English standard and the ontology imposes no language, so an answer in another language keeps that language and the same sentence rules; the theme keeps its voice. It is in the toggleable comms pack, not a law, per DESIGN.md Decision 7: `--exclude-rules "comms 4"` turns it off. The carrier ceilings rise by 1 003 characters (full) and 472 (lean). Run `geneseed rebuild-all` to get it.
|
|
31
|
+
|
|
32
|
+
## [4.14.0] β 2026-10-22
|
|
33
|
+
|
|
34
|
+
Minor: the React kit supports webpack projects as well as Vite.
|
|
35
|
+
|
|
36
|
+
### Upgrade notes
|
|
37
|
+
- Run `geneseed rebuild-all` to get the new kit text; nothing changes on a machine until something re-emits.
|
|
38
|
+
|
|
39
|
+
### Changed
|
|
40
|
+
- **The `react` kit supports webpack as well as Vite** (#368). The `react` skill reads the bundler from `package.json` and loads its side file: the new `react/webpack.md` (config, client-side routing with `historyApiFallback` and `publicPath`, `DefinePlugin` env values, a webpack build-failure table) or `react/vite.md`. The kit rules, both agents, the Jest configuration table in `react-testing` and every theme's descriptions now name both bundlers.
|
|
41
|
+
|
|
42
|
+
## [4.13.0] β 2026-10-21
|
|
43
|
+
|
|
44
|
+
Minor: sharper ported skills, a wiki that keeps its history, and self-improvement notes that carry their evidence.
|
|
45
|
+
|
|
46
|
+
### Upgrade notes
|
|
47
|
+
- Run `geneseed rebuild-all` to get the new skill and agent text; nothing changes on a machine until something re-emits. Notes already in `notebook/skill-notes/` and `notebook/agent-notes/` keep working as written; only new lines take the new format.
|
|
48
|
+
|
|
49
|
+
### Changed
|
|
50
|
+
- **Self-improvement notes carry their evidence and their scope** (#366). A note is now one line, `- [skill|general] <correction> β seen: <what happened, against what was expected> (<date>)`, and an agent's `spec-feedback:` line takes the same shape. `seen:` is what a correction is judged by when `geneseed diff` hands it back for folding into `src/`, and pruning drops the lines without one first. `general` marks a correction that would fix other skills or agents too, so it belongs in a law, doctrine or memory rather than one file. The `geneseed diff` report explains both markers. Agents now share one self-improvement footer (`src/agents/_self-improvement.md`) instead of 29 copies; rendered agents differ only by the new wording.
|
|
51
|
+
- **The wiki writes history, not the present** (#365). Wiki claims are dated, code claims cite `owner/repo@commit`, and a correction supersedes a claim rather than rewriting it. A new report-only lint pass lists contradictions, orphans and overtaken claims without restructuring the wiki. Adapted from mattpocock/skills' chief-of-staff.
|
|
52
|
+
- **The mattpocock ports are sharpened against upstream `5beb35b`** (#365):
|
|
53
|
+
- `parallel-agents`: each slice branches off the integration tip when it is dispatched and merges the tip back before returning, so a later slice no longer misses its blocker's merged work. A whole-branch review follows.
|
|
54
|
+
- `codebase-design`: an interface is designed twice, and an ADR is not silently reopened.
|
|
55
|
+
- `research` and the `researcher` agent: one read in the source that owns a claim stands on its own; any other claim still needs two sources.
|
|
56
|
+
- `ship`: the docs check moves before the push it gates.
|
|
57
|
+
- `plan`, `wayfinder`, `prototype`, `develop`, `debug`, `rule`, `brainstorm`, `handoff` and `skill-forge` get smaller fixes: slice sizing, ticket graduation, mocking only at boundaries, checking for an existing guardrail before proposing one, and trigger pruning.
|
|
58
|
+
- New credits on `parallel-agents`, `skill-forge`, `brainstorm` and `wiki`.
|
|
59
|
+
|
|
60
|
+
## [4.12.0] β 2026-10-21
|
|
61
|
+
|
|
62
|
+
Minor: a second opt-in kit, `react`, and the setup wizard asks about each kit on its own.
|
|
63
|
+
|
|
64
|
+
### Upgrade notes
|
|
65
|
+
- Nothing to rebuild unless you want the new kit. Default installs are unchanged: no kit is on. To turn it on, run `geneseed build --emit <target> --kits react` (or `--kits react,spring-boot` for both), or use **Installs β Kits** in the web console.
|
|
66
|
+
|
|
67
|
+
### Added
|
|
68
|
+
- **The `react` kit** (#362), for React 18 or 19 apps built with Vite, in TypeScript or JavaScript, tested with Jest and React Testing Library. Skills `react` (with side files for Vite and accessibility) and `react-testing`; agents `react-engineer` and `react-reviewer` (read-only); kit rules, and a banned-API gate that keeps `ReactDOM.render(`, `findDOMNode`, Enzyme, `react-test-renderer` and `@testing-library/react-hooks` out of kit files. Adapted from affaan-m/everything-claude-code (MIT), rewritten and condensed for Vite and Jest, with no Server Components material.
|
|
69
|
+
|
|
70
|
+
### Changed
|
|
71
|
+
- **The setup wizard asks one yes/no per kit** (#362). A single pick could not turn on two kits at once.
|
|
72
|
+
|
|
73
|
+
### Repository
|
|
74
|
+
Not in the package; how Geneseed itself is built and checked.
|
|
75
|
+
- CI's golden cells run as two parallel jobs per platform, emit and CLI (#361). On Windows that leg drops from about 7 minutes in sequence to about 4. The unit suite runs at `--test-concurrency=8` on Linux and in the publish job; Windows keeps the default, where the flag bought nothing. If branch protection names the old `node-cells (<os>)` checks, they now report as `node-cells (<os>, emit)` and `node-cells (<os>, cli)`.
|
|
76
|
+
- The unit suite drops three repeated full-cost runs (#363): two update-flow arms use a doctor stand-in (the real rejection and exact rollback stay in `update_git`), the packaging test counts themes in process instead of a second `doctor --all`, and `--no-deletion-gate` replays only the 67 real-loss rows. 151 s to 139 s locally, same 2012 tests.
|
|
77
|
+
|
|
78
|
+
## [4.11.2] β 2026-10-21
|
|
79
|
+
|
|
80
|
+
Patch: a clone install on macOS or Linux puts the `geneseed` command on your PATH.
|
|
81
|
+
|
|
82
|
+
### Upgrade notes
|
|
83
|
+
- Nothing to rebuild. If `geneseed` is not found in a new terminal, run `./geneseed link` from your clone and accept the offer to add `~/.local/bin` to your shell's startup file.
|
|
84
|
+
|
|
85
|
+
### Fixed
|
|
86
|
+
- **A clone install puts `geneseed` on your PATH on macOS and Linux** (#359). `./install` never linked the command, and `geneseed link` wrote it to `~/.local/bin`, which macOS zsh does not search, so `geneseed` was not found (reported 2026-10). `./install` now runs `link` when `geneseed` is not found yet, and `link` offers, in a terminal, to add the folder to your shell's startup file (`~/.zshrc`, or `~/.bashrc` / `~/.bash_profile` for bash). It appends one marked block, never twice; `geneseed unlink` removes it. Outside a terminal it prints the line to add, as before.
|
|
87
|
+
|
|
88
|
+
## [4.11.1] β 2026-10-21
|
|
89
|
+
|
|
90
|
+
Patch: the web console on a machine with only IBM Bob (or any host but OpenCode): it opens on the install you have, the first-deploy form asks a per-repo mode for its folder, and the doctor stops reading a misplaced project install as a broken bundle.
|
|
91
|
+
|
|
92
|
+
### Upgrade notes
|
|
93
|
+
- Restart the console after updating (`geneseed web restart`) so it serves the rebuilt UI. If a per-repo install landed in `Harness/` inside your Geneseed clone, remove it with `./geneseed uninstall --target Harness --yes`, then delete `Harness/`.
|
|
94
|
+
|
|
95
|
+
### Fixed
|
|
96
|
+
- **The web console works on a machine without OpenCode** (#357). It always opened on the OpenCode global dir, so with only IBM Bob installed the Overview showed the first-deploy form over a working `~/.bob`, and nothing could re-point it (the harness selector hides itself below two installs). When nothing is deployed where it looks, the console now shows the first active install it finds, a global before a project, and follows a first deploy to where it landed.
|
|
97
|
+
- **The first-deploy form asks a project mode for its folder** (#357). Picking a per-repo mode (`bob`, `claude`, `opencode`, `openclaude`) sent a Build with no folder, so the files landed in `Harness/` inside the Geneseed clone, where the host never looks. The form now asks for the folder (typed or Browseβ¦) and deploys there; Build refuses a per-repo mode it has no folder for; the portable `files` bundle is left to the CLI. To remove an install misplaced this way, run `./geneseed uninstall --target Harness --yes` in the clone, then delete `Harness/`.
|
|
98
|
+
- **The doctor's committed-bundle check no longer reads a Claude, Bob or OpenClaude project install as a broken bundle** (#357). Such a tree has a `.bob/`-style data dir, not the bundle layout, so every file read "missing" (178 lines on the reported machine) and no rebuild could clear them.
|
|
99
|
+
|
|
100
|
+
## [4.11.0] β 2026-10-21
|
|
101
|
+
|
|
102
|
+
Minor: the self-improvement loops write to notebook notes instead of the installed skill or agent file, the web console gains a Kits section, and `./install` waits for your answers and finds tools installed for one user.
|
|
103
|
+
|
|
104
|
+
### Upgrade notes
|
|
105
|
+
- Run `geneseed rebuild-all` once after updating so installed skills, agents and AGENT.md carry the new self-improvement footer. Lessons the loops wrote into installed files before this release are still exported by `upgrade` into `improvements/`, as before.
|
|
106
|
+
|
|
107
|
+
### Added
|
|
108
|
+
- **Web console: Kits section** (#353). A top-level Kits page between Library and Loops: a list and a detail page per kit (rules, banned APIs, members linked to the Library, upstream pin and compare link, a switch per install that rebuilds through the install job). Installs β Kits shares its staging and Apply control. `GET /api/kits` now carries rules, word budget, banned APIs and credits, and the Library shows a `kit:` badge on kit members.
|
|
109
|
+
|
|
110
|
+
### Changed
|
|
111
|
+
- **Self-improvement writes to a sidecar, not the skill** (#354). The skill and agent loops used to edit the rendered file in place, which the doctor reported as stale and the next rebuild erased. They now write corrections to `notebook/skill-notes/<name>.md` and `notebook/agent-notes/<name>.md` (seed-once, agent-owned, never overwritten), and read them back before the skill runs or the agent is dispatched. `geneseed diff` lists the notes and `--out` exports them for back-porting into `src/`. AGENT.md names the notes paths, so the carrier ceilings rise by exactly that text (full 62_263, lean 39_156).
|
|
112
|
+
|
|
113
|
+
### Fixed
|
|
114
|
+
- **Setup's prompts no longer answer themselves in a real terminal** (#356). Reading `process.stdin` puts a terminal's input in non-blocking mode, and the line reader took the resulting `EAGAIN` for end of input: "Continue without one? (y/N)" printed and answered N at once, so `./install` stopped before anyone could type, and every other wizard question silently took its default. The reader now waits for the keypress.
|
|
115
|
+
- **A tool installed for one user is found** (#356). Setup looked only on PATH, so an IBM Bob installed under the user's profile read as missing. It now also checks `~/.local/bin`, `~/bin`, each tool's own installer dir (`~/.opencode/bin`, `~/.claude/local`), the per-user npm prefix on Windows, and Bob's desktop app folder (`%LOCALAPPDATA%\Programs` on Windows, `/Applications` and `~/Applications` on macOS); a tool found there is listed with its path. When nothing is found, setup asks for the tool's path before offering to stop. The double-clickable `install.command` now waits for Enter before its window can close, as `install.cmd` already did.
|
|
116
|
+
|
|
11
117
|
## [4.10.0] β 2026-10-20
|
|
12
118
|
|
|
13
119
|
Minor: opt-in kits (and a first one, `spring-boot`), credits for adapted content, a weekly upstream-drift check, and a web Kits tab.
|
package/README.md
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
[](themes/)
|
|
14
14
|
[](src/skills/)
|
|
15
15
|
[](src/agents/)
|
|
16
|
-
[](src/doctrines/)
|
|
17
17
|
[](adapters/opencode/plugins/)
|
|
18
18
|
[](#-supported-harnesses)
|
|
19
19
|
|
|
@@ -157,7 +157,7 @@ geneseed web stop # stop the daemon
|
|
|
157
157
|
geneseed web status # is it running, and where
|
|
158
158
|
```
|
|
159
159
|
|
|
160
|
-
The sidebar has
|
|
160
|
+
The sidebar has eight pages: **Overview** (what's deployed, health, recent jobs), **Constitution** (the rules and doctrine switches), **Library** (skills, agents, the wiki), **Kits** (opt-in stack bundles), **Loops** (the loop catalogue), **Personal** (your rules, profile, memory, notebook), **Installs** (hosts, local edits, doctor, server) and **Docs** β this documentation, opening on the Understand track, with a map of what Geneseed put on your machine.
|
|
161
161
|
|
|
162
162
|
It binds to `127.0.0.1` only and runs entirely offline β no npm needed at runtime; the UI build ships in `web/dist/`. Mutating actions run in the background and report back as toasts (fire-and-notify), guarded by a per-session token so other sites can't trigger them. A global **Spotlight** search in the topbar jumps to any agent, skill, rule, doc, or MCP server. Rebuild the UI after changing anything under `web/src/` with `cd web && npm install && npm run build`. If `web/dist/` is missing (fresh clone, never built), `geneseed web` offers to run that build for you β answer `Y` and it installs, builds, and starts the server; in non-interactive shells it prints the manual recipe instead.
|
|
163
163
|
|
|
@@ -334,7 +334,7 @@ geneseed rebuild-all # re-render every registered install in its own theme + m
|
|
|
334
334
|
./geneseed upgrade # just the content refresh (remembers theme + emit mode)
|
|
335
335
|
```
|
|
336
336
|
|
|
337
|
-
**Local edits survive.** If the agent
|
|
337
|
+
**Local edits survive.** The self-improvement loops write to notes under `notebook/`, which no rebuild touches. If you or the agent edited deployed agent/skill files in place anyway, an upgrade exports that drift to an `improvements/` file inside the install before overwriting. Details: [Upgrade](docs/guides/upgrade.md).
|
|
338
338
|
|
|
339
339
|
## π Documentation
|
|
340
340
|
|
|
@@ -373,12 +373,13 @@ Some skills and agents are adapted from other open-source skill collections, und
|
|
|
373
373
|
|
|
374
374
|
- `daydream` β [glebis/claude-skills](https://github.com/glebis/claude-skills) by Gleb Kalinin (MIT): the vendored `daydream` skill.
|
|
375
375
|
- `react-view-transitions` β [vercel-labs/agent-skills](https://github.com/vercel-labs/agent-skills) by Vercel Engineering (MIT): the vendored `react-view-transitions` skill.
|
|
376
|
-
- `mattpocock-skills` β [mattpocock/skills](https://github.com/mattpocock/skills) by Matt Pocock (MIT): the vocabulary and procedures behind codebase-design, wayfinder, prototype, develop, handoff and research, the spec pass of geneseed-code-review, the question rounds of brainstorm, the slicing of plan,
|
|
376
|
+
- `mattpocock-skills` β [mattpocock/skills](https://github.com/mattpocock/skills) by Matt Pocock (MIT): the vocabulary and procedures behind codebase-design, wayfinder, prototype, develop, handoff and research, the spec pass of geneseed-code-review, the question rounds and questionnaire of brainstorm, the slicing of plan, the reproduction step of debug, the integration-branch rules of parallel-agents, the trigger-pruning of skill-forge, and the dated-history rule of wiki.
|
|
377
377
|
- `mattpocock-skills-frozen` β [mattpocock/skills](https://github.com/mattpocock/skills) by Matt Pocock (MIT), pinned at 391a2701, the last commit carrying `resolving-merge-conflicts` (deleted upstream since): the merge-conflict step of git-history, from a skill upstream has since deleted, so the weekly drift check skips it.
|
|
378
378
|
- `mattpocock-skills-2509` β [mattpocock/skills](https://github.com/mattpocock/skills) by Matt Pocock (MIT), a second key for the same repo, at the same pin as `mattpocock-skills` today (5beb35b0): the PR body of ship and the guardrail clause of rule.
|
|
379
379
|
- `superpowers` β [obra/superpowers](https://github.com/obra/superpowers) by Jesse Vincent (MIT): the core of debug, the size step and builder check of brainstorm, the plan rules of plan, the reviewer brief behind geneseed-code-review and the reviewer agent, the review-handling steps of review-response, and the ruling format of pipeline and parallel-agents.
|
|
380
380
|
- `vibe-wise` β [nykooi1/vibe-wise](https://github.com/nykooi1/vibe-wise) by Noah Kim (MIT): the state file, levels and checkpoints of learn-mode.
|
|
381
381
|
- `piomin-spring-boot` β [piomin/claude-ai-spring-boot](https://github.com/piomin/claude-ai-spring-boot) by Piotr MiΕkowski (Apache-2.0): the Spring Boot kit's skills and agents, rewritten and condensed for Boot 4.
|
|
382
|
+
- `everything-claude-code` β [affaan-m/everything-claude-code](https://github.com/affaan-m/everything-claude-code) by Affaan Mustafa (MIT): the React kit's skills and agents, rewritten and condensed for Vite and Jest.
|
|
382
383
|
|
|
383
384
|
## π License
|
|
384
385
|
|
package/SHIPPED.md
CHANGED
|
@@ -20,7 +20,7 @@ historical references, not files distributed with the repo.
|
|
|
20
20
|
> **On version numbers.** [`harness.config.json`](harness.config.json)'s `version` is a
|
|
21
21
|
> human-readable label only. The canonical identity of an installed harness is the
|
|
22
22
|
> **source fingerprint** stamped in `.geneseed-version` (see `geneseed version`), not the
|
|
23
|
-
> string. Current label: **4.
|
|
23
|
+
> string. Current label: **4.15.1**.
|
|
24
24
|
|
|
25
25
|
## Capabilities
|
|
26
26
|
|
|
@@ -153,7 +153,21 @@ const gateOff = (marker) => new RegExp(`^${marker}:[ \\t]*off[ \\t]*\\r?$`, "m")
|
|
|
153
153
|
const DELETION_GATE_OFF = gateOff("Deletion gate")
|
|
154
154
|
const SECRETS_GATE_OFF = gateOff("Secrets gate")
|
|
155
155
|
|
|
156
|
-
|
|
156
|
+
// OpenCode 1.x paints a plugin's stderr over its TUI input box (in red); its own log API
|
|
157
|
+
// writes to the log file instead. The V1 entry sets LOG_CLIENT; V2 and tests have no
|
|
158
|
+
// client and keep stderr, as does a refused log call, so no line is lost. Never throws:
|
|
159
|
+
// a log line must not break a tool call.
|
|
160
|
+
let LOG_CLIENT = null
|
|
161
|
+
function say(msg, level = "warn") {
|
|
162
|
+
try {
|
|
163
|
+
if (LOG_CLIENT?.app?.log) {
|
|
164
|
+
Promise.resolve(LOG_CLIENT.app.log({ body: { service: "geneseed-guard", level, message: msg } })).catch(() => console.error(`[geneseed-guard] ${msg}`))
|
|
165
|
+
return
|
|
166
|
+
}
|
|
167
|
+
} catch { /* fall through to stderr */ }
|
|
168
|
+
console.error(`[geneseed-guard] ${msg}`)
|
|
169
|
+
}
|
|
170
|
+
const log = (msg) => say(msg)
|
|
157
171
|
|
|
158
172
|
// ---- the gate ledger ------------------------------------------------------------
|
|
159
173
|
// The twin of `ledger()` in js/hosts/hooks.mjs: one JSON line per BLOCK into
|
|
@@ -1369,6 +1383,7 @@ async function recordUse(tool, args) {
|
|
|
1369
1383
|
}
|
|
1370
1384
|
|
|
1371
1385
|
export const GeneseedGuard = async (ctx) => {
|
|
1386
|
+
if (ctx?.client) LOG_CLIENT = ctx.client
|
|
1372
1387
|
// The session's working directory, the same resolution the context plugin uses.
|
|
1373
1388
|
const root = () => ctx?.worktree || ctx?.directory || process.cwd()
|
|
1374
1389
|
return {
|
|
@@ -38,6 +38,21 @@ import * as path from "node:path"
|
|
|
38
38
|
import { fileURLToPath } from "node:url"
|
|
39
39
|
import { homedir } from "node:os"
|
|
40
40
|
|
|
41
|
+
// OpenCode 1.x paints a plugin's stderr over its TUI input box (in red); its own log API
|
|
42
|
+
// writes to the log file instead. The V1 entry sets LOG_CLIENT; V2 and tests have no
|
|
43
|
+
// client and keep stderr, as does a refused log call, so no line is lost. Never throws:
|
|
44
|
+
// a log line must not break a tool call.
|
|
45
|
+
let LOG_CLIENT = null
|
|
46
|
+
function say(msg, level = "warn") {
|
|
47
|
+
try {
|
|
48
|
+
if (LOG_CLIENT?.app?.log) {
|
|
49
|
+
Promise.resolve(LOG_CLIENT.app.log({ body: { service: "geneseed-learn", level, message: msg } })).catch(() => console.error(`[geneseed-learn] ${msg}`))
|
|
50
|
+
return
|
|
51
|
+
}
|
|
52
|
+
} catch { /* fall through to stderr */ }
|
|
53
|
+
console.error(`[geneseed-learn] ${msg}`)
|
|
54
|
+
}
|
|
55
|
+
|
|
41
56
|
// The plugin's own directory. In the global install the layout is
|
|
42
57
|
// <cfg>/plugins/geneseed-learn.js beside <cfg>/memory, so the store can be found
|
|
43
58
|
// relative to this file β no manual `export GENESEED_HARNESS` needed.
|
|
@@ -471,17 +486,18 @@ async function storeDistil(output, { isChild, memDir, agentName, existing }) {
|
|
|
471
486
|
const lesson = output.trim().split("\n")[0].replace(/^[-*]\s*/, "").trim()
|
|
472
487
|
if (lesson.length < 10 || lesson.length > 300) return // junk / truncation guard
|
|
473
488
|
const f = await appendAgentLesson(memDir, agentName, lesson)
|
|
474
|
-
|
|
489
|
+
say(`agent lesson -> ${f}`, "info")
|
|
475
490
|
return
|
|
476
491
|
}
|
|
477
492
|
const res = await writeMemories(output, memDir, existing)
|
|
478
493
|
for (const [verb, slugs] of [["wrote", res.created], ["updated", res.updated], ["archived", res.archived]]) {
|
|
479
|
-
if (slugs.length)
|
|
494
|
+
if (slugs.length) say(`${verb} ${slugs.length} memory file(s): ${slugs.join(", ")}`, "info")
|
|
480
495
|
}
|
|
481
496
|
}
|
|
482
497
|
|
|
483
498
|
export const GeneseedLearn = async (ctx) => {
|
|
484
499
|
const { client } = ctx ?? {}
|
|
500
|
+
if (client) LOG_CLIENT = client
|
|
485
501
|
const ours = new Set() // throwaway distil sessions β never mine our own output
|
|
486
502
|
const timers = new Map() // sid -> debounce timer, re-armed on each idle
|
|
487
503
|
const inFlight = new Set() // sid currently being distilled (guards against overlap)
|
|
@@ -510,8 +526,8 @@ export const GeneseedLearn = async (ctx) => {
|
|
|
510
526
|
if (!memDir) {
|
|
511
527
|
if (!warnedNoDir) {
|
|
512
528
|
warnedNoDir = true
|
|
513
|
-
|
|
514
|
-
"
|
|
529
|
+
say(
|
|
530
|
+
"no memory dir β set $GENESEED_HARNESS or $GENESEED_MEMORY."
|
|
515
531
|
)
|
|
516
532
|
}
|
|
517
533
|
return
|
|
@@ -524,8 +540,8 @@ export const GeneseedLearn = async (ctx) => {
|
|
|
524
540
|
notes = notes.slice(-MAX_NOTES_CHARS)
|
|
525
541
|
model = model ?? envModel()
|
|
526
542
|
if (!model) {
|
|
527
|
-
|
|
528
|
-
"
|
|
543
|
+
say(
|
|
544
|
+
"could not determine a model β set $GENESEED_MODEL=provider/model."
|
|
529
545
|
)
|
|
530
546
|
return
|
|
531
547
|
}
|
|
@@ -540,7 +556,7 @@ export const GeneseedLearn = async (ctx) => {
|
|
|
540
556
|
const newId = session?.id ?? session?.data?.id
|
|
541
557
|
if (!newId) {
|
|
542
558
|
// Prompting with {id: undefined} would 404 silently on every idle.
|
|
543
|
-
|
|
559
|
+
say("session.create returned no id β skipping this distil.")
|
|
544
560
|
return
|
|
545
561
|
}
|
|
546
562
|
ours.add(newId)
|
|
@@ -558,7 +574,7 @@ export const GeneseedLearn = async (ctx) => {
|
|
|
558
574
|
await storeDistil(output, { isChild, memDir, agentName, existing })
|
|
559
575
|
} catch (err) {
|
|
560
576
|
// Never break the session over a memory write.
|
|
561
|
-
|
|
577
|
+
say(`skipped: ${err?.message ?? err}`)
|
|
562
578
|
} finally {
|
|
563
579
|
inFlight.delete(sid)
|
|
564
580
|
}
|
|
@@ -647,7 +663,7 @@ async function setupV2(ctx) {
|
|
|
647
663
|
if (!memDir) {
|
|
648
664
|
if (!warnedNoDir) {
|
|
649
665
|
warnedNoDir = true
|
|
650
|
-
|
|
666
|
+
say("no memory dir β set $GENESEED_HARNESS or $GENESEED_MEMORY.")
|
|
651
667
|
}
|
|
652
668
|
return
|
|
653
669
|
}
|
|
@@ -660,7 +676,7 @@ async function setupV2(ctx) {
|
|
|
660
676
|
model = env ? { providerID: env.providerID, id: env.modelID } : null
|
|
661
677
|
}
|
|
662
678
|
if (!model) {
|
|
663
|
-
|
|
679
|
+
say("could not determine a model β set $GENESEED_MODEL=provider/model.")
|
|
664
680
|
return
|
|
665
681
|
}
|
|
666
682
|
|
|
@@ -673,7 +689,7 @@ async function setupV2(ctx) {
|
|
|
673
689
|
})
|
|
674
690
|
await storeDistil(String(reply?.text ?? ""), { isChild, memDir, agentName, existing })
|
|
675
691
|
} catch (err) {
|
|
676
|
-
|
|
692
|
+
say(`skipped: ${err?.message ?? err}`)
|
|
677
693
|
} finally {
|
|
678
694
|
inFlight.delete(sid)
|
|
679
695
|
}
|
|
@@ -695,7 +711,7 @@ async function setupV2(ctx) {
|
|
|
695
711
|
if (prev) clearTimeout(prev)
|
|
696
712
|
timers.set(sid, setTimeout(() => { timers.delete(sid); runDistill(sid) }, DEBOUNCE_MS))
|
|
697
713
|
}
|
|
698
|
-
})().catch((err) =>
|
|
714
|
+
})().catch((err) => say(`event stream ended: ${err?.message ?? err}`))
|
|
699
715
|
return () => {
|
|
700
716
|
controller.abort()
|
|
701
717
|
for (const t of timers.values()) clearTimeout(t)
|
|
@@ -25,7 +25,21 @@ import * as path from "node:path"
|
|
|
25
25
|
import { fileURLToPath, pathToFileURL } from "node:url"
|
|
26
26
|
|
|
27
27
|
const DEBUG = !!process.env.GENESEED_DEBUG
|
|
28
|
-
function dlog(m) { if (DEBUG)
|
|
28
|
+
function dlog(m) { if (DEBUG) say(m, "debug") }
|
|
29
|
+
// OpenCode 1.x paints a plugin's stderr over its TUI input box (in red); its own log API
|
|
30
|
+
// writes to the log file instead. The V1 entry sets LOG_CLIENT; V2 and tests have no
|
|
31
|
+
// client and keep stderr, as does a refused log call, so no line is lost. Never throws:
|
|
32
|
+
// a log line must not break a tool call.
|
|
33
|
+
let LOG_CLIENT = null
|
|
34
|
+
function say(msg, level = "warn") {
|
|
35
|
+
try {
|
|
36
|
+
if (LOG_CLIENT?.app?.log) {
|
|
37
|
+
Promise.resolve(LOG_CLIENT.app.log({ body: { service: "geneseed-workflow", level, message: msg } })).catch(() => console.error(`[geneseed-workflow] ${msg}`))
|
|
38
|
+
return
|
|
39
|
+
}
|
|
40
|
+
} catch { /* fall through to stderr */ }
|
|
41
|
+
console.error(`[geneseed-workflow] ${msg}`)
|
|
42
|
+
}
|
|
29
43
|
|
|
30
44
|
const __dir = path.dirname(fileURLToPath(import.meta.url))
|
|
31
45
|
const WORKFLOWS_DIR = process.env.GENESEED_WORKFLOWS_DIR
|
|
@@ -184,7 +198,9 @@ const NAME_DESCRIPTION = "saved workflow name; omit to list available"
|
|
|
184
198
|
const ARGS_DESCRIPTION = "inputs passed to the workflow script as `args` (object, or a JSON object string)"
|
|
185
199
|
|
|
186
200
|
// One-line load banner (always on) so a restart visibly confirms the plugin loaded and the
|
|
187
|
-
// `workflow` tool is registered. tests/host_canary.mjs reads it as V1's proof of load
|
|
201
|
+
// `workflow` tool is registered. tests/host_canary.mjs reads it as V1's proof of load, so it
|
|
202
|
+
// stays on stderr, not `say`: `opencode debug config` never prints a `client.app.log` line. It
|
|
203
|
+
// runs once, before the TUI draws, so it does not land in the input box as `say`'s lines did.
|
|
188
204
|
async function loadBanner(warn = "") {
|
|
189
205
|
try {
|
|
190
206
|
const names = await listWorkflows()
|
|
@@ -194,6 +210,7 @@ async function loadBanner(warn = "") {
|
|
|
194
210
|
|
|
195
211
|
export const GeneseedWorkflow = async (ctx) => {
|
|
196
212
|
const { client, directory, worktree } = ctx
|
|
213
|
+
if (client) LOG_CLIENT = client
|
|
197
214
|
let toolHelper
|
|
198
215
|
try { ({ tool: toolHelper } = await import("@opencode-ai/plugin")) }
|
|
199
216
|
catch { dlog("@opencode-ai/plugin tool helper unavailable β registering a raw tool def") }
|
package/docs/concepts/kits.md
CHANGED
|
@@ -26,10 +26,22 @@ The first kit is `spring-boot`, for Spring Boot 4 (Spring Framework 7, Java 21+)
|
|
|
26
26
|
|
|
27
27
|
The kit is adapted from [piomin/claude-ai-spring-boot](https://github.com/piomin/claude-ai-spring-boot) by Piotr MiΕkowski (Apache-2.0), rewritten and condensed for Boot 4. Each of its skill folders ships `LICENSE-piomin-spring-boot.txt`, and each agent carries a credit line.
|
|
28
28
|
|
|
29
|
+
The second kit is `react`, for React 18 or 19 apps built with Vite or webpack, in TypeScript or JavaScript, tested with Jest and React Testing Library. It adds four members:
|
|
30
|
+
|
|
31
|
+
| Member | Kind | What it is for |
|
|
32
|
+
|---|---|---|
|
|
33
|
+
| `react` | skill | Components, hooks, state placement, data fetching, TypeScript or JavaScript, React security; side files for Vite and for webpack (config, client-side routing, env variables, build failures), read by whichever the project uses, and accessibility |
|
|
34
|
+
| `react-testing` | skill | Jest and Testing Library: role queries, `userEvent`, MSW network mocks, `jest-axe`, and the Jest configuration a Vite or webpack project needs |
|
|
35
|
+
| `react-engineer` | agent | Implements a React feature, or makes a broken Vite or webpack build or Jest run green |
|
|
36
|
+
| `react-reviewer` | agent | Framework-aware review: hooks, state, data fetching, accessibility, React security, tests |
|
|
37
|
+
|
|
38
|
+
It is adapted from [affaan-m/everything-claude-code](https://github.com/affaan-m/everything-claude-code) by Affaan Mustafa (MIT), rewritten and condensed for Vite and Jest; the webpack side file is first-party. It has no Server Components material: a client-rendered app has no server render.
|
|
39
|
+
|
|
29
40
|
### Switching kits on and off
|
|
30
41
|
|
|
31
42
|
```bash
|
|
32
43
|
geneseed build --emit claude-global --kits spring-boot
|
|
44
|
+
geneseed build --emit claude-global --kits react,spring-boot
|
|
33
45
|
geneseed build --emit claude-global --kits none
|
|
34
46
|
```
|
|
35
47
|
|
|
@@ -37,7 +49,7 @@ geneseed build --emit claude-global --kits none
|
|
|
37
49
|
|
|
38
50
|
A build does exactly what its flags say. A plain `build` without `--kits` therefore turns off a kit the install has on. Before it does, it warns: `this install has kit <k>; this build turns it off β pass --kits <k> to keep it`.
|
|
39
51
|
|
|
40
|
-
The setup wizard asks one question
|
|
52
|
+
The setup wizard asks one yes/no question per kit, each defaulting to whether the install has that kit on. It asks them only when at least one kit exists.
|
|
41
53
|
|
|
42
54
|
### What an install records
|
|
43
55
|
|
|
@@ -47,7 +59,7 @@ An install with a kit on records it in its instructions file, under the skill se
|
|
|
47
59
|
|
|
48
60
|
`geneseed status` shows `kits: spring-boot` on the install's row, and `status --json` carries the same list.
|
|
49
61
|
|
|
50
|
-
In the web console, **Installs β Kits** (`#/installs/kits`) lists every install (disabled ones read-only) with one switch per kit. Toggling stages the set; **Apply** asks for confirmation, then rebuilds that one install with exactly that set as a console job (replace, not replay). Files you edited in a kit that is now off are kept, and the row names them so you can delete them by hand.
|
|
62
|
+
In the web console, **Installs β Kits** (`#/installs/kits`) lists every install (disabled ones read-only) with one switch per kit. Toggling stages the set; **Apply** asks for confirmation, then rebuilds that one install with exactly that set as a console job (replace, not replay). Files you edited in a kit that is now off are kept, and the row names them so you can delete them by hand. The top-level **Kits** page (`#/kits`) lists the kits; a kit's page (`#/kits/<kit>`) shows its rules, banned APIs and upstream credits with the same per-install switch, and the Library tags each member skill or agent with a `kit:` badge.
|
|
51
63
|
|
|
52
64
|
### What a kit adds to an install
|
|
53
65
|
|
package/docs/concepts/skills.md
CHANGED
|
@@ -41,7 +41,7 @@ The full list, with each description, is in the catalog.
|
|
|
41
41
|
|
|
42
42
|
### Skills improve themselves
|
|
43
43
|
|
|
44
|
-
Every skill ends with one beat of reflection: if a step misled or a step was missing, the agent
|
|
44
|
+
Every skill ends with one beat of reflection: if a step misled or a step was missing, the agent writes the exact correction, with your assent, into that skill's notes file, `notebook/skill-notes/<name>.md`, and reads those notes the next time the skill runs. It never edits the installed skill itself: that file is rendered from `src/`, a rebuild would overwrite the edit, and `doctor` would report it as drift. Agents work the same way through `notebook/agent-notes/`. Each note is one line that carries its evidence, `- [skill|general] <correction> β seen: <what happened, against what was expected> (<date>)`: `seen:` is what you judge the correction by before folding it in, and `general` marks one that belongs in a law, doctrine or memory rather than in that one skill. `geneseed diff` lists the notes so you can fold them back into `src/`. Most runs end with nothing to change.
|
|
45
45
|
|
|
46
46
|
### Old names keep working
|
|
47
47
|
|
package/docs/extending.md
CHANGED
|
@@ -513,10 +513,9 @@ enumerates skills would miss it. `src/kits/<kit>/` holds only `rules.md`.
|
|
|
513
513
|
to a kit member (it would dangle in an install without the kit), and a kit file that links to
|
|
514
514
|
another kit's member. Links run kit β core only. A kit's links to its own members do not
|
|
515
515
|
protect them from `--exclude-skills`; its link to a core skill still protects that skill.
|
|
516
|
-
5. **The setup wizard.** It asks
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
tree with no kit.
|
|
516
|
+
5. **The setup wizard.** It asks one yes/no per kit, and only when at least one kit exists. Each
|
|
517
|
+
shipped kit therefore adds one answer line to the stdin strings in `tests/unit/wizard.test.mjs`,
|
|
518
|
+
and the `wizard-no-kit` job holds that the questions are skipped on a tree with no kit.
|
|
520
519
|
6. **Golden cells**: the matrix (`tests/helpers/matrix/emit.*.json`) carries kit on for `claude` and
|
|
521
520
|
`opencode`, the kit-off baseline (`kits: []`, spelled `--kits none`), and three deletion cells
|
|
522
521
|
(kit on to off). One deletion cell sets `edit` (a map of sandbox path to appended text) so a member
|
|
@@ -13,7 +13,9 @@ geneseed build --emit bob-global # ~/.bob
|
|
|
13
13
|
geneseed build --emit bob --out /path/to/repo --root /path/to/repo # one repo
|
|
14
14
|
```
|
|
15
15
|
|
|
16
|
-
Bob is shaped like Claude Code, so it gets the same agents and skills. Per repo, the preamble goes into a root `AGENTS.md` and the rest into `.bob/`. Globally, everything goes under `~/.bob` (`$BOB_CONFIG_DIR` moves it), and the preamble rides `rules/geneseed.md`, because Bob does not auto-load a global `AGENTS.md`. Bob's hooks refuse an action with exit code 2, and Bob has no `SubagentStop` or `PreCompact` events.
|
|
16
|
+
Bob is shaped like Claude Code, so it gets the same agents and skills. Per repo, the preamble goes into a root `AGENTS.md` and the rest into `.bob/`. Globally, everything goes under `~/.bob` (`$BOB_CONFIG_DIR` moves it), and the preamble rides `rules/geneseed.md`, because Bob does not auto-load a global `AGENTS.md`. Bob's hooks refuse an action with exit code 2, and Bob has no `SubagentStop` or `PreCompact` events.
|
|
17
|
+
|
|
18
|
+
Both scopes open Bob's carrier with a short first-reply override, so the theme's readiness line (for example "𧬠Gene-seed implantedβ¦") starts the first reply. Without it, Bob's own greeting outranked the instruction lower in the file. A bare greeting such as "hi" still gets Bob's fixed welcome; the line appears on the first real request. That much was checked by hand in the Bob IDE (2026-10); the rest of the Bob support has not been verified against a live install.
|
|
17
19
|
|
|
18
20
|
---
|
|
19
21
|
|
|
@@ -8,7 +8,7 @@ description: "Put the geneseed command on your PATH from a clone."
|
|
|
8
8
|
---
|
|
9
9
|
**Installed from npm? You have nothing to do.** `npm install -g geneseed` already puts `geneseed`, `geneseed-build` and `geneseed-hook` on your `PATH`.
|
|
10
10
|
|
|
11
|
-
From a clone, you call the launcher inside the clone: `./geneseed` (Windows: `.\geneseed.cmd`). To type plain `geneseed` from any folder, link it.
|
|
11
|
+
From a clone, you call the launcher inside the clone: `./geneseed` (Windows: `.\geneseed.cmd`). To type plain `geneseed` from any folder, link it. On macOS and Linux, `./install` does this for you when `geneseed` is not found yet.
|
|
12
12
|
|
|
13
13
|
## macOS and Linux
|
|
14
14
|
|
|
@@ -17,7 +17,7 @@ From a clone, you call the launcher inside the clone: `./geneseed` (Windows: `.\
|
|
|
17
17
|
./geneseed link /usr/local/bin # or another bin folder (may ask for sudo)
|
|
18
18
|
```
|
|
19
19
|
|
|
20
|
-
`link` writes a small shell launcher that runs this clone by its absolute path.
|
|
20
|
+
`link` writes a small shell launcher that runs this clone by its absolute path. If the target folder is not on your `PATH` (macOS zsh does not search `~/.local/bin`), it offers to add it to your shell's startup file: `~/.zshrc` for zsh, `~/.bashrc` for bash on Linux, `~/.bash_profile` for bash on macOS. It appends one marked block, never twice, and `geneseed unlink` removes it. Outside a terminal, or for another shell, it prints the line to add instead. Open a new terminal, then:
|
|
21
21
|
|
|
22
22
|
```
|
|
23
23
|
geneseed # the web console (or the command list), from any folder
|
package/docs/guides/upgrade.md
CHANGED
|
@@ -46,7 +46,7 @@ A rebuild only replaces files the install's manifest says Geneseed owns. It leav
|
|
|
46
46
|
|
|
47
47
|
## Local edits, and the improvements file
|
|
48
48
|
|
|
49
|
-
The agent
|
|
49
|
+
The agent records what it learns about a skill or agent in notes under `notebook/skill-notes/` and `notebook/agent-notes/`, which rebuilds never touch. Edits made to the deployed agent and skill files themselves, by you or by an older harness, are another matter: a rebuild would overwrite those, so **setup, re-theme and upgrade export them first**. When the files they are about to overwrite differ from a fresh render, the differences are written to a markdown **improvements file** in `improvements/`, inside the install's own folder (for the OpenCode global install, `~/.config/opencode/improvements/`). The manifest does not list that folder, so rebuilds never overwrite it and uninstall never removes it.
|
|
50
50
|
|
|
51
51
|
A rebuild also refuses to overwrite a file you edited. The manifest records a fingerprint of every file Geneseed wrote; when a file no longer matches it, the rebuild leaves it alone and prints `kept your edited <file> β delete it to get Geneseed's copy back`. From then on the file is yours and later rebuilds skip it. A file the new version no longer ships is kept the same way, with `(no longer shipped)`. Line-ending changes from a git checkout do not count as edits. Installs made before fingerprints existed are overwritten as before.
|
|
52
52
|
|
|
@@ -58,7 +58,7 @@ geneseed diff --full # with line-level diffs
|
|
|
58
58
|
geneseed diff --out improvements.md # write the improvements file
|
|
59
59
|
```
|
|
60
60
|
|
|
61
|
-
`diff` compares the global OpenCode install by default. Pass `--target <config dir>` to compare another install. A file you replaced with a link to your own copy (a skill folder junctioned or symlinked elsewhere, say) is listed as `linked`: Geneseed never writes through a link, so it is yours and not drift, and it stays out of the improvements file. The improvements file is self-contained. To make the changes permanent, hand it to an agent in a Geneseed clone and ask it to fold them back into `src/`. Then they survive every future build. The web console's **Changes** page exports the same file.
|
|
61
|
+
`diff` compares the global OpenCode install by default. Pass `--target <config dir>` to compare another install. A file you replaced with a link to your own copy (a skill folder junctioned or symlinked elsewhere, say) is listed as `linked`: Geneseed never writes through a link, so it is yours and not drift, and it stays out of the improvements file. `diff` also lists every non-empty self-improvement note, and `--out` copies them into the improvements file; the upgrade export does not fire on notes alone, since a rebuild cannot lose them. The improvements file is self-contained. To make the changes permanent, hand it to an agent in a Geneseed clone and ask it to fold them back into `src/`. Then they survive every future build. The web console's **Changes** page exports the same file.
|
|
62
62
|
|
|
63
63
|
## Moving from a clone to npm
|
|
64
64
|
|
|
@@ -97,7 +97,7 @@ reports `version "21` or higher.
|
|
|
97
97
|
.\geneseed.cmd link
|
|
98
98
|
```
|
|
99
99
|
|
|
100
|
-
On Windows, `link` writes to `%LOCALAPPDATA%\Geneseed\bin` and adds it to your user PATH β only **new** terminals see it, so close and reopen yours.
|
|
100
|
+
On macOS and Linux, `link` offers to add `~/.local/bin` to your shell's startup file when it is not on your PATH; accept, then open a **new** terminal. On Windows, `link` writes to `%LOCALAPPDATA%\Geneseed\bin` and adds it to your user PATH β only **new** terminals see it, so close and reopen yours.
|
|
101
101
|
|
|
102
102
|
**Confirm.**
|
|
103
103
|
|
package/docs/web-ui.md
CHANGED
|
@@ -114,6 +114,11 @@ streams the output of background jobs and keeps their history across reloads.
|
|
|
114
114
|
**Promote to rule** control turns a recurring lesson into a trial rule in
|
|
115
115
|
`user-rules.md` β provenance recorded, the source fact deleted so it isn't loaded
|
|
116
116
|
twice β landing you on the Rules page.
|
|
117
|
+
- **Kits** (`#/kits`, `#/kits/<kit>`) β the list of shipped kits and, per kit, a detail page
|
|
118
|
+
with its rules, word budget, banned APIs, upstream credits and one switch per install.
|
|
119
|
+
`GET /api/kits` carries `rules`, `rulesWordBudget`, `banned` and `credits` per kit; the
|
|
120
|
+
catalog and item endpoints for skills and agents carry `kit` (the owning kit or `null`),
|
|
121
|
+
which the Library shows as a `kit:` badge.
|
|
117
122
|
- **Loops** (`#/loops`) β the loop catalogue `geneseed loop` runs from, read-only, laid out
|
|
118
123
|
like the Library: a rail of sections (**Templates**, **Bricks**, **Active**, each with its
|
|
119
124
|
count; `#/loops/<section>/<item>` opens an entry), with the selected section's groups
|
|
@@ -194,7 +199,7 @@ streams the output of background jobs and keeps their history across reloads.
|
|
|
194
199
|
card (shown once a global install exists) manages sovereign repos β folders where every
|
|
195
200
|
global harness goes dormant (hooks stay silent, the global preamble never loads);
|
|
196
201
|
add or remove one here, the web mirror of `harness exclude add|remove|list`.
|
|
197
|
-
- **Kits** (`#/installs/kits`) β every install (disabled ones read-only) as a
|
|
202
|
+
- **Kits** (`#/installs/kits`) β every install (disabled ones read-only) as a panel with one switch per kit.
|
|
198
203
|
Toggling only stages the set; **Apply** asks first, then rebuilds that install with
|
|
199
204
|
exactly that set as a console job. Files you edited in a kit that is now off are kept,
|
|
200
205
|
and the row lists them.
|
package/harness.config.json
CHANGED
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
"_comment": "version is a human-readable release label only; the canonical identity of an installed harness is the source fingerprint stamped in .geneseed-version (see `harness version`), not this string.",
|
|
3
3
|
"theme": "neutral",
|
|
4
4
|
"product": "Geneseed",
|
|
5
|
-
"version": "4.
|
|
5
|
+
"version": "4.15.1"
|
|
6
6
|
}
|
package/js/build/emit-claude.mjs
CHANGED
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
} from './emit-common.mjs';
|
|
22
22
|
import { kitsBody, renderAll, renderFile } from './render.mjs';
|
|
23
23
|
import {
|
|
24
|
-
BOB_RULES_STUB, ensureContextStub, ensureExcludesStub, ensureNotebookIndex,
|
|
24
|
+
BOB_RULES_STUB, bobFirstReply, ensureContextStub, ensureExcludesStub, ensureNotebookIndex,
|
|
25
25
|
ensureProfileStub,
|
|
26
26
|
ensureRulesStub, ensureWikiStub, WIKI_FILE,
|
|
27
27
|
} from './stubs.mjs';
|
|
@@ -100,7 +100,7 @@ export function emitClaudeRender(cfg, job) {
|
|
|
100
100
|
if (isBob && agentText !== null) {
|
|
101
101
|
const rulesMd = path.join(cfgDir, 'rules', 'geneseed.md');
|
|
102
102
|
claimAndWrite(cfgDir, rulesMd, 'rules/geneseed.md', scope === 'project' ? BOB_RULES_STUB
|
|
103
|
-
: stripCapabilityLinks(prefixedAgentText('../') || agentText), owned);
|
|
103
|
+
: bobFirstReply(theme.LOADED_SIGIL) + stripCapabilityLinks(prefixedAgentText('../') || agentText), owned);
|
|
104
104
|
}
|
|
105
105
|
|
|
106
106
|
ensureAgentOverridesStub(cfg, cfgDir);
|
|
@@ -179,6 +179,8 @@ export function emitClaudeRender(cfg, job) {
|
|
|
179
179
|
let claudeMdText = null;
|
|
180
180
|
if (agentText !== null && !(isBob && scope === 'global')) {
|
|
181
181
|
claudeMdText = stripCapabilityLinks(prefixedAgentText(lawsPrefix) || agentText);
|
|
182
|
+
// Bob only: its greeting persona outranks the template's sigil paragraph β see `bobFirstReply`.
|
|
183
|
+
if (isBob) claudeMdText = bobFirstReply(theme.LOADED_SIGIL) + claudeMdText;
|
|
182
184
|
}
|
|
183
185
|
|
|
184
186
|
// WIRE β see `claudeWire` below. One child per emit, so the two halves are two
|
package/js/build/stubs.mjs
CHANGED
|
@@ -139,6 +139,19 @@ file (\`~/.bob/rules/geneseed.md\`) so the global preamble does not stack on top
|
|
|
139
139
|
the project's own. Follow the root \`AGENTS.md\`.
|
|
140
140
|
`;
|
|
141
141
|
|
|
142
|
+
/**
|
|
143
|
+
* The paragraph a Bob emit puts FIRST in what Bob auto-loads (global `rules/geneseed.md`,
|
|
144
|
+
* the project's `AGENTS.md` block). Tried live in the Bob IDE (2026-10-23): with only the
|
|
145
|
+
* template's sigil paragraph β below the banner β the first reply to a real request carried
|
|
146
|
+
* no sigil; with this paragraph on top it did. Bob's own greeting persona outranks a rule
|
|
147
|
+
* that does not say it overrides it. A bare "hi" still gets Bob's fixed welcome either way.
|
|
148
|
+
*/
|
|
149
|
+
export function bobFirstReply(sigil) {
|
|
150
|
+
return '**First-reply override β highest priority.** Your very first reply in every '
|
|
151
|
+
+ 'conversation MUST begin with this exact line, before anything else and instead of any '
|
|
152
|
+
+ `default greeting or self-introduction:\n\n> ${sigil}\n\n`;
|
|
153
|
+
}
|
|
154
|
+
|
|
142
155
|
/** `_build_render.PROFILE_FILE`. */
|
|
143
156
|
const PROFILE_FILE = 'PROFILE.md';
|
|
144
157
|
|