geneseed 3.10.0 → 3.12.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 +96 -0
- package/DESIGN.md +1 -1
- package/README.md +27 -45
- package/SHIPPED.md +2 -2
- package/adapters/bob/README.md +1 -1
- package/adapters/claude-code/README.md +17 -12
- package/adapters/openclaude/README.md +1 -1
- package/adapters/opencode/README.md +4 -4
- package/adapters/opencode/plugins/geneseed-guard.js +157 -2
- package/bin/build-driver.mjs +2 -0
- package/bin/geneseed-cli.mjs +21 -0
- package/bin/geneseed-hook.mjs +2 -0
- package/docs/README.md +42 -0
- package/docs/_groups.json +18 -0
- package/docs/concepts/agents.md +44 -0
- package/docs/concepts/collaboration.md +62 -0
- package/docs/concepts/exclusions.md +55 -0
- package/docs/concepts/footprint.md +52 -0
- package/docs/concepts/foreman-mode.md +69 -0
- package/docs/concepts/hooks.md +101 -0
- package/docs/concepts/hosts.md +55 -0
- package/docs/concepts/loops.md +165 -0
- package/docs/concepts/lsp.md +50 -0
- package/docs/{web → concepts}/memory.md +2 -2
- package/docs/{web → concepts}/notebook.md +2 -2
- package/docs/concepts/rules.md +52 -0
- package/docs/concepts/skills.md +49 -0
- package/docs/concepts/themes.md +50 -0
- package/docs/extending.md +32 -21
- package/docs/guides/autostart.md +70 -0
- package/docs/guides/choose-your-setup.md +134 -0
- package/docs/guides/headless.md +22 -0
- package/docs/guides/install.md +161 -0
- package/docs/guides/mcp.md +195 -0
- package/docs/guides/migrate.md +41 -0
- package/docs/guides/project-context.md +87 -0
- package/docs/guides/run-anywhere.md +45 -0
- package/docs/guides/uninstall.md +51 -0
- package/docs/guides/upgrade.md +65 -0
- package/docs/guides/verify.md +65 -0
- package/docs/guides/wiki.md +69 -0
- package/docs/guides/worktree.md +47 -0
- package/docs/reference/about.md +7 -0
- package/docs/reference/cli.md +7 -0
- package/docs/reference/environment.md +99 -0
- package/docs/reference/glossary.md +37 -0
- package/docs/reference/opencode-plugins.md +133 -0
- package/docs/reference/troubleshooting.md +350 -0
- package/docs/understand/a-day.md +77 -0
- package/docs/understand/enforced-vs-asked.md +64 -0
- package/docs/understand/harness.md +36 -0
- package/docs/understand/on-your-machine.md +76 -0
- package/docs/web-ui.md +13 -2
- package/harness.config.json +1 -1
- package/js/README.md +27 -4
- package/js/build/driver.mjs +14 -8
- package/js/build/generate.mjs +22 -7
- package/js/build/render.mjs +5 -0
- package/js/build/source.mjs +11 -1
- package/js/cli-table.json +236 -1
- package/js/hosts/gitref.mjs +99 -0
- package/js/hosts/hooks.mjs +88 -1
- package/js/hosts/installs.mjs +21 -0
- package/js/hosts/mcp.mjs +1 -1
- package/js/hosts/settings.mjs +13 -1
- package/js/inspect/checks-authoring.mjs +15 -3
- package/js/inspect/diff.mjs +3 -0
- package/js/inspect/doctor.mjs +3 -2
- package/js/inspect/inventory.mjs +2 -1
- package/js/inspect/registry.mjs +20 -3
- package/js/inspect/status.mjs +8 -3
- package/js/lib/node-floor.mjs +30 -0
- package/js/loop/catalog.mjs +116 -0
- package/js/loop/cli.mjs +151 -0
- package/js/loop/graph.mjs +145 -0
- package/js/loop/score.mjs +143 -0
- package/js/loop/state.mjs +322 -0
- package/js/maintain/migrate.mjs +4 -2
- package/js/maintain/setup.mjs +109 -21
- package/js/maintain/update.mjs +4 -15
- package/js/ui/cli.mjs +2 -2
- package/js/web/actions.mjs +9 -3
- package/js/web/api.mjs +41 -2
- package/js/web/daemon.mjs +94 -4
- package/js/web/docs.mjs +149 -65
- package/js/web/handler.mjs +1 -0
- package/js/web/jobs.mjs +3 -1
- package/js/web/server.mjs +10 -5
- package/package.json +6 -4
- package/registry.json +21 -0
- package/src/AGENT.md.tmpl +6 -0
- package/src/bricks/README.md +32 -0
- package/src/bricks/_template.md +32 -0
- package/src/bricks/apply.md +17 -0
- package/src/bricks/baseline-green.md +17 -0
- package/src/bricks/bruno-test.md +16 -0
- package/src/bricks/ci-fix.md +17 -0
- package/src/bricks/deps-audit.md +14 -0
- package/src/bricks/docs-update.md +15 -0
- package/src/bricks/identify.md +20 -0
- package/src/bricks/lint.md +14 -0
- package/src/bricks/plan.md +17 -0
- package/src/bricks/reproduce.md +16 -0
- package/src/bricks/review.md +17 -0
- package/src/bricks/security-scan.md +17 -0
- package/src/bricks/test.md +14 -0
- package/src/doctrines/process.md +11 -8
- package/src/loops/bugfix.json +22 -0
- package/src/loops/feature.json +21 -0
- package/src/loops/refactor.json +20 -0
- package/src/postures/mentor.md +1 -0
- package/src/skills/brick-forge.md +46 -0
- package/src/skills/geneseed.md +1 -1
- package/src/skills/learn-mode.md +89 -0
- package/src/skills/loop.md +99 -0
- package/src/skills/pipeline.md +2 -2
- package/src/skills/quiz.md +2 -1
- package/src/skills/teach.md +2 -1
- package/themes/_TEMPLATE.json +3 -0
- package/themes/biker.json +3 -0
- package/themes/commentator.json +3 -0
- package/themes/cyberpunk.json +3 -0
- package/themes/gamer.json +3 -0
- package/themes/imperial.json +3 -0
- package/themes/joker.json +3 -0
- package/themes/marvin.json +3 -0
- package/themes/mean.json +3 -0
- package/themes/military.json +3 -0
- package/themes/neutral.json +3 -0
- package/themes/pirate.json +3 -0
- package/themes/sports.json +3 -0
- package/themes/verstappen.json +3 -0
- package/themes/wizard.json +3 -0
- package/web/dist/assets/Activity-GaaZWXTY.js +1 -0
- package/web/dist/assets/ActivityDetail-4t7d45Du.js +1 -0
- package/web/dist/assets/Dashboard-CYn7Tp16.js +2 -0
- package/web/dist/assets/Docs-BeFKLg2T.js +5 -0
- package/web/dist/assets/{GreenhouseView-D0cbCJ5m.js → GreenhouseView-C6ibc8IE.js} +1 -1
- package/web/dist/assets/Installs-DRYjYnxs.js +2 -0
- package/web/dist/assets/JournalView-1HbU1mfg.js +1 -0
- package/web/dist/assets/Laws-DFoG8JWB.js +3 -0
- package/web/dist/assets/Library-DDjgNwz_.js +1 -0
- package/web/dist/assets/Loops-D9VEoO0F.js +1 -0
- package/web/dist/assets/{Markdown-CkFyfgNf.js → Markdown-qjM2_ofS.js} +5 -5
- package/web/dist/assets/{OperatorHudView-CiAkAkQL.js → OperatorHudView-Bs7paWmh.js} +1 -1
- package/web/dist/assets/Personal-BY5n4gTw.js +1 -0
- package/web/dist/assets/Tabs-ho-EYD8i.js +1 -0
- package/web/dist/assets/api-CyMRbU2x.js +1 -0
- package/web/dist/assets/drawable-CLS9drMb.js +1 -0
- package/web/dist/assets/index-CX_hXMi5.css +1 -0
- package/web/dist/assets/index-Cjr7XCA3.js +2 -0
- package/web/dist/index.html +3 -2
- package/QUICKSTART.md +0 -50
- package/SETUP.md +0 -1148
- package/docs/web/_groups.json +0 -45
- package/docs/web/about.md +0 -6
- package/docs/web/adapters-claude-code.md +0 -8
- package/docs/web/adapters-opencode-loads.md +0 -8
- package/docs/web/adapters-opencode-spec.md +0 -8
- package/docs/web/adapters-opencode.md +0 -8
- package/docs/web/agents.md +0 -8
- package/docs/web/authoring.md +0 -11
- package/docs/web/autostart.md +0 -9
- package/docs/web/claude-hooks.md +0 -37
- package/docs/web/cli.md +0 -6
- package/docs/web/collaboration.md +0 -27
- package/docs/web/configure-wiki.md +0 -9
- package/docs/web/design.md +0 -7
- package/docs/web/env-knobs.md +0 -9
- package/docs/web/exclusions.md +0 -26
- package/docs/web/first-session.md +0 -28
- package/docs/web/footprint.md +0 -38
- package/docs/web/foreman-mode.md +0 -33
- package/docs/web/glossary.md +0 -6
- package/docs/web/harnesses.md +0 -30
- package/docs/web/headless.md +0 -9
- package/docs/web/ingest-docs.md +0 -9
- package/docs/web/install-paths.md +0 -9
- package/docs/web/install-quick.md +0 -35
- package/docs/web/lsp-overview.md +0 -37
- package/docs/web/mcp-claude-code.md +0 -10
- package/docs/web/mcp-filesystem.md +0 -9
- package/docs/web/mcp-gitlab.md +0 -9
- package/docs/web/mcp-markitdown.md +0 -9
- package/docs/web/mcp-overview.md +0 -34
- package/docs/web/mcp-trouble.md +0 -9
- package/docs/web/mcp-verify.md +0 -9
- package/docs/web/migrate.md +0 -39
- package/docs/web/model.md +0 -20
- package/docs/web/pipelines.md +0 -24
- package/docs/web/plugin-activity.md +0 -23
- package/docs/web/plugin-context.md +0 -26
- package/docs/web/plugin-guard.md +0 -24
- package/docs/web/plugin-learn.md +0 -27
- package/docs/web/plugin-notify.md +0 -24
- package/docs/web/plugin-ponytail.md +0 -23
- package/docs/web/plugin-setup.md +0 -7
- package/docs/web/plugin-workflow.md +0 -25
- package/docs/web/plugins.md +0 -17
- package/docs/web/project-context.md +0 -9
- package/docs/web/rules.md +0 -30
- package/docs/web/run-anywhere.md +0 -9
- package/docs/web/self-improve.md +0 -8
- package/docs/web/setup-choices.md +0 -64
- package/docs/web/skills.md +0 -8
- package/docs/web/themes-author.md +0 -20
- package/docs/web/themes.md +0 -9
- package/docs/web/token-footprint.md +0 -7
- package/docs/web/trouble.md +0 -38
- package/docs/web/upgrade.md +0 -9
- package/docs/web/verify.md +0 -30
- package/docs/web/wiki.md +0 -7
- package/docs/web/worktree.md +0 -10
- package/docs/wiki.md +0 -43
- package/web/dist/assets/Activity-BjVp522q.js +0 -1
- package/web/dist/assets/ActivityDetail-8ep1bspW.js +0 -1
- package/web/dist/assets/Dashboard-OkC_PCH6.js +0 -2
- package/web/dist/assets/Docs-CKPWz00o.js +0 -2
- package/web/dist/assets/Installs-BtGGdoTt.js +0 -2
- package/web/dist/assets/JournalView-Ckl4dmzR.js +0 -1
- package/web/dist/assets/Laws-CLpdRRk8.js +0 -3
- package/web/dist/assets/Library-wPPuKQrI.js +0 -1
- package/web/dist/assets/Personal-D8CnDo9v.js +0 -1
- package/web/dist/assets/Tabs-B4HNrrCs.js +0 -1
- package/web/dist/assets/drawable-BiwaOo6x.js +0 -1
- package/web/dist/assets/index-C1yil5j1.js +0 -2
- package/web/dist/assets/index-CDPDk2vj.css +0 -1
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
---
|
|
2
|
+
group: concepts
|
|
3
|
+
order: 11
|
|
4
|
+
title: "Loops"
|
|
5
|
+
kind: "concept"
|
|
6
|
+
link: {"hash": "#/docs/reference/cli", "label": "geneseed loop --help →"}
|
|
7
|
+
---
|
|
8
|
+
A **loop** is a requirement worked as small, validated, committed iterations instead of one long
|
|
9
|
+
turn. `geneseed loop` is the state machine: it decides every transition, ceiling, score and stop,
|
|
10
|
+
and hands the agent one node at a time to run. The `loop` [skill](skills.md) is the only thing
|
|
11
|
+
that talks to it — the agent runs the node it is given and reports the outcome, never its own
|
|
12
|
+
reading of the graph.
|
|
13
|
+
|
|
14
|
+
> **You already know this:** a checklist a tech lead walks through on a ticket, where some steps
|
|
15
|
+
> need a sign-off before continuing and others don't. The lead doesn't improvise the order; the
|
|
16
|
+
> checklist decides it, and only the risky steps stop for you.
|
|
17
|
+
|
|
18
|
+
## The ring
|
|
19
|
+
|
|
20
|
+
A loop is a graph of **bricks** — one node each — wired by **edges**, one per outcome a brick can
|
|
21
|
+
report. One cycle through the graph back to its head is an **iteration**; the graph's `loops`
|
|
22
|
+
array names every cycle that is allowed to exist, each with a `max` number of times a node inside
|
|
23
|
+
it may be re-entered. Picture it as rings: the outer ring is the iteration itself (plan, apply,
|
|
24
|
+
test, review, back to plan), and inner rings sit inside it for retries (apply failed its test, try
|
|
25
|
+
`apply` again without going all the way back around). The three shipped templates —
|
|
26
|
+
`bugfix`, `feature`, `refactor` — all nest a short `apply`↔`test` retry ring inside the iteration
|
|
27
|
+
ring, and `bugfix` and `feature` nest a second, wider `apply`↔`test`↔`review` ring
|
|
28
|
+
(`review-fix`) around that.
|
|
29
|
+
|
|
30
|
+
Work closes into a commit whenever the graph re-enters the iteration loop's head — so any setup
|
|
31
|
+
work before the loop starts (reproducing a bug, say) is its own unit, numbered iteration 0, kept
|
|
32
|
+
out of iteration 1's diff. For the same reason the iteration has exactly one way in: its
|
|
33
|
+
**head** is the first node listed in the iteration loop (normally `identify`), and every edge that
|
|
34
|
+
enters the iteration from outside it — and `start`, when `start` is inside it — must target that
|
|
35
|
+
head. `geneseed loop check` refuses a graph that enters anywhere else.
|
|
36
|
+
|
|
37
|
+
**A node's re-entry budget is not each loop's `max` added up.** Every node inside one or more
|
|
38
|
+
inner loops gets a single shared counter: `1 + the largest max among the inner loops that contain
|
|
39
|
+
it`. A node in both a `max: 5` and a `max: 3` loop gets 6 re-entries total, not 8 — the loops don't
|
|
40
|
+
stack, the larger one wins and the `+1` is the node's own first run. A node inside no inner loop at
|
|
41
|
+
all gets exactly 1 — no re-entry — which is also why **every cycle inside an iteration must be a
|
|
42
|
+
named inner loop** in the graph JSON: `geneseed loop check` (and `loop init`, which runs the same
|
|
43
|
+
check) refuses a graph with an undeclared cycle inside an iteration, before a single node runs.
|
|
44
|
+
|
|
45
|
+
## Bricks, templates, and the three origins
|
|
46
|
+
|
|
47
|
+
A **brick** is a markdown file: YAML-ish frontmatter (`name`, `description`, `effect` — `read` or
|
|
48
|
+
`mutate` — exactly one of `agent` or `skill`, and `outcomes`) plus a 4-10 line prose body. The
|
|
49
|
+
model never sees the file; `geneseed loop next` hands it the body as the prompt. A **loop
|
|
50
|
+
template** (`bugfix`, `feature`, `refactor`, or one composed by hand) is the graph JSON that wires
|
|
51
|
+
bricks together.
|
|
52
|
+
|
|
53
|
+
Both are looked up across three origins, each able to override the one before it **by name**:
|
|
54
|
+
|
|
55
|
+
| origin | path | who writes it |
|
|
56
|
+
|---|---|---|
|
|
57
|
+
| shipped | `src/bricks/`, `src/loops/` | Geneseed itself — read by the CLI from its own source, never emitted into an install |
|
|
58
|
+
| global | `$XDG_CONFIG_HOME/geneseed/{bricks,loops}` (default `~/.config/geneseed/…`) | the user, for every project on this machine |
|
|
59
|
+
| project | `<repo>/.geneseed/{bricks,loops}` | a team, committed and shared |
|
|
60
|
+
|
|
61
|
+
Precedence is project > global > shipped. A project or global brick named `apply` replaces the
|
|
62
|
+
shipped `apply` everywhere a template references it, without the template changing.
|
|
63
|
+
`geneseed loop check` lists every override it finds, never silently.
|
|
64
|
+
|
|
65
|
+
A per-install skill exclusion is invisible to the CLI — it has no way to know which skills your
|
|
66
|
+
install carries. The `loop` skill covers the gap itself: when composing a graph it skips a brick
|
|
67
|
+
whose `skill` it doesn't have.
|
|
68
|
+
|
|
69
|
+
To add or adapt a brick, use the `brick-forge` skill — ask it, or see
|
|
70
|
+
[the bricks README](https://github.com/geneseed-dev/geneseed/blob/main/src/bricks/README.md) in
|
|
71
|
+
the repository.
|
|
72
|
+
|
|
73
|
+
## Risk, trust, and the three validation levels
|
|
74
|
+
|
|
75
|
+
Before a `mutate` brick runs, the loop scores the card the brick's setup declared: one risk weight
|
|
76
|
+
per action kind it named, and the score is the **max**, not a sum — one contract change outweighs
|
|
77
|
+
ten trivial renames, and ten trivial renames never add up to one. After the brick runs, the loop
|
|
78
|
+
re-scores against the real diff, and the diff can only raise the score, never lower it:
|
|
79
|
+
|
|
80
|
+
- a file touched outside the declared write set raises the score to at least **api** (`0.8`);
|
|
81
|
+
- more than 20 deleted lines raises it to at least the **delete** weight;
|
|
82
|
+
- touching a file listed in the loop's `contracts` raises it to at least the **api** weight.
|
|
83
|
+
|
|
84
|
+
`LOOP.md` itself is excluded from every score and every diff check — it's the engine's own
|
|
85
|
+
bookkeeping, rewritten on every action, never part of the work being judged.
|
|
86
|
+
|
|
87
|
+
The score is checked against a **trust preset** — `--preset` on `geneseed loop init`, editable
|
|
88
|
+
afterward in `LOOP.md`'s `preset` field, applying from the next score on:
|
|
89
|
+
|
|
90
|
+
| preset | silent ≤ | soft ≤ | above soft |
|
|
91
|
+
|---|---|---|---|
|
|
92
|
+
| prudent | 0.1 | 0.3 | blocking |
|
|
93
|
+
| balanced (default) | 0.2 | 0.6 | blocking |
|
|
94
|
+
| aggressive | 0.4 | 0.8 | blocking |
|
|
95
|
+
|
|
96
|
+
Three levels follow from where the score lands:
|
|
97
|
+
|
|
98
|
+
- **silent** — nothing more than the commit trailers below.
|
|
99
|
+
- **soft** — listed under "to review" in the run's final summary; no notification during the run.
|
|
100
|
+
- **blocking** — the run ends. `LOOP.md` is written with `status: awaiting`, and a person has to
|
|
101
|
+
answer with `geneseed loop decide --verdict ok|no|amend`. Amending a verdict marks the decision
|
|
102
|
+
`blocking (amended)` in the trailers rather than silently rewriting it to something else.
|
|
103
|
+
|
|
104
|
+
## `LOOP.md` and its trailers
|
|
105
|
+
|
|
106
|
+
`LOOP.md`, at the worktree root, is both the human-readable record (title, requirement, and the
|
|
107
|
+
rule that you may edit `preset` or `contracts` there) and the engine's own JSON state block. Every
|
|
108
|
+
closing commit carries seven trailers, read straight off that state:
|
|
109
|
+
|
|
110
|
+
```
|
|
111
|
+
Loop-Iteration: <n>
|
|
112
|
+
Loop-Bricks: <every brick name visited this unit, deduplicated>
|
|
113
|
+
Loop-Risk-Declared: <score>
|
|
114
|
+
Loop-Risk-Actual: <score>
|
|
115
|
+
Loop-Threshold: <preset> <silent>/<soft>
|
|
116
|
+
Loop-Decision: silent | soft | blocking[ (amended)]
|
|
117
|
+
Loop-Tests: <what the loop was told about test state>
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## The `loop/*` branch, and why merge always asks
|
|
121
|
+
|
|
122
|
+
A loop runs in its own worktree, on a branch named `loop/<slug>` — the `loop` skill creates both
|
|
123
|
+
with `git worktree add -b loop/<slug>` before `geneseed loop init` writes `LOOP.md` there.
|
|
124
|
+
While that branch is checked out and `LOOP.md` carries the engine's state marker, the git gate lets
|
|
125
|
+
exactly one commit/push form through without asking:
|
|
126
|
+
|
|
127
|
+
```
|
|
128
|
+
git add -A && git commit -F <message_file> && git push [-u] <remote> HEAD:<loop branch>
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Nothing else is exempt — not `git commit -m`, not a quoted refspec, not a plain `git push` with no
|
|
132
|
+
explicit `HEAD:<ref>` — any other shape still asks. The exemption only ever covers a `loop/*`
|
|
133
|
+
branch, and never a shared one (`main`, `master`, `develop`, `development`, `release/*`,
|
|
134
|
+
`hotfix/*`). The **final** commit of a run — the one that removes `LOOP.md` on `$close` — is
|
|
135
|
+
outside the exemption too, because the loop is no longer running when it lands; that ask is your
|
|
136
|
+
consent to close it. **Merging a loop branch into anything else always asks, with no exception.**
|
|
137
|
+
The loop reports the branch to merge and the iterations that landed in "to review" — it never
|
|
138
|
+
merges for you.
|
|
139
|
+
|
|
140
|
+
## `geneseed loop` actions
|
|
141
|
+
|
|
142
|
+
| action | what it does |
|
|
143
|
+
|---|---|
|
|
144
|
+
| `check` | lists templates and every brick (available, unavailable, overridden); validates one graph file (`--graph`) or one brick file (`--brick`) |
|
|
145
|
+
| `init` | writes a fresh `LOOP.md` from a template or graph file, under a title, requirement and trust preset |
|
|
146
|
+
| `next` | the only driver of the cycle — returns the next thing to do: run a node, score a card, answer an `awaiting`, or a terminal |
|
|
147
|
+
| `score` | scores a declared card (`--declared`) before a mutate node runs, or the real diff (`--diff`, numstat piped on stdin) before a commit |
|
|
148
|
+
| `record` | records a brick's reported outcome and advances the graph |
|
|
149
|
+
| `decide` | answers an `awaiting` validation with a verdict and a note |
|
|
150
|
+
|
|
151
|
+
Run `geneseed loop --help` for the full flag list.
|
|
152
|
+
|
|
153
|
+
## Limits
|
|
154
|
+
|
|
155
|
+
- **No parallel nodes.** The graph runs one node at a time; there is no fan-out.
|
|
156
|
+
- **A per-install skill exclusion is invisible to the CLI** (see above) — the `loop` skill is
|
|
157
|
+
responsible for skipping bricks it can't run, not the engine.
|
|
158
|
+
|
|
159
|
+
## Not foreman mode
|
|
160
|
+
|
|
161
|
+
A loop and a [foreman-mode](foreman-mode.md) pipeline are both "hand work off and keep going," but
|
|
162
|
+
they solve different problems. A pipeline is a one-shot crew for a single task, uncommitted until
|
|
163
|
+
you accept it. A loop is a long-running, self-scoring state machine that commits each validated
|
|
164
|
+
iteration on its own branch as it goes, and only stops for a person when the risk crosses a
|
|
165
|
+
threshold.
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
---
|
|
2
|
+
group: concepts
|
|
3
|
+
order: 13
|
|
4
|
+
title: "Code intelligence (LSP, OpenCode)"
|
|
5
|
+
kind: "concept"
|
|
6
|
+
---
|
|
7
|
+
OpenCode can run **language servers** — the same Language Server Protocol servers your editor uses — so the agent sees real diagnostics, type errors and definitions, not just text. Geneseed turns this on for every language OpenCode ships a server for.
|
|
8
|
+
|
|
9
|
+
> **You already know this:** the red squiggles in your editor. With LSP on, the agent gets the same squiggles before it tells you a change is done.
|
|
10
|
+
|
|
11
|
+
### What is covered
|
|
12
|
+
|
|
13
|
+
| Language | Server | You install |
|
|
14
|
+
| --- | --- | --- |
|
|
15
|
+
| JavaScript, TypeScript, React, React Native | typescript-language-server | nothing — OpenCode downloads it |
|
|
16
|
+
| Python | pyright | nothing — OpenCode downloads it |
|
|
17
|
+
| Java | jdtls | a **JDK 21+** (OpenCode downloads jdtls itself) |
|
|
18
|
+
| SQL | none, on purpose | — |
|
|
19
|
+
|
|
20
|
+
One server covers JavaScript, TypeScript, React and React Native: they are all TS/JS.
|
|
21
|
+
|
|
22
|
+
### The one prerequisite: Java 21+
|
|
23
|
+
|
|
24
|
+
OpenCode downloads the servers that run on Node by itself on first use. It cannot install a JVM, and jdtls needs one, so `geneseed setup` checks for Java 21+ and prints an install hint if it is missing. Any JDK 21 works, for example:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
brew install openjdk@21
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
sdk install java 21-tem
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Why no SQL server
|
|
35
|
+
|
|
36
|
+
A SQL language server is tied to one dialect — a PostgreSQL server flags Oracle SQL as errors and the other way round — and a `.sql` file can map to only one server, with nothing telling OpenCode which dialect a repo uses. Rather than be wrong for half of all SQL codebases, Geneseed ships none. If your project knows its dialect, add the matching server under the `lsp` key of the project's own `opencode.json`.
|
|
37
|
+
|
|
38
|
+
### How it is wired
|
|
39
|
+
|
|
40
|
+
The install adds `"lsp": true` to your `opencode.json` (LSP is off in OpenCode by default). If you already have an `lsp` key, Geneseed leaves yours alone.
|
|
41
|
+
|
|
42
|
+
On an air-gapped machine, stop the downloads and pre-install each server yourself:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
export OPENCODE_DISABLE_LSP_DOWNLOAD=true
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Verify
|
|
49
|
+
|
|
50
|
+
Open a `.ts` and a `.py` file in a session and ask the agent for diagnostics. The first open triggers the download.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
---
|
|
2
|
+
group: concepts
|
|
3
|
+
order: 2
|
|
4
|
+
title: "Rules (the constitution)"
|
|
5
|
+
kind: "concept"
|
|
6
|
+
link: {"hash": "#/laws", "label": "Browse the constitution →"}
|
|
7
|
+
---
|
|
8
|
+
The **constitution** is the set of standing rules the agent carries into every session. It is authored in `src/`, rendered into the instructions file your host reads (`AGENT.md`, `CLAUDE.md` or `AGENTS.md`), and comes in layers that differ in one thing: whether you can turn them off.
|
|
9
|
+
|
|
10
|
+
> **You already know this:** a lint config. Some rules are set to `error` and nobody may disable them; some come from presets you opt into; and your project's own overrides sit on top of the presets.
|
|
11
|
+
|
|
12
|
+
### Cited by name, never by number
|
|
13
|
+
|
|
14
|
+
Every rule has a name — *Deletion Is Deliberate*, *Consent Before Push* — and the agent, the docs and the hooks cite it by that name. Rules are also numbered in the rendered text, but a number is only the rule's current position: remove a rule and every number after it shifts. So when you write about a rule, in your own notes or in `user-rules.md`, use its name.
|
|
15
|
+
|
|
16
|
+
The one place you type a position is the command line: `--exclude-rules "process 5"` means "the fifth rule of the process pack in this checkout". Check the name it carries before you exclude it.
|
|
17
|
+
|
|
18
|
+
### The layers, in precedence order
|
|
19
|
+
|
|
20
|
+
When two instructions disagree, the higher one wins.
|
|
21
|
+
|
|
22
|
+
1. **Ethos** — always on. {N_ONTOLOGY} sections of flowing prose (Telos, Evidence, Decisions, Conduct): what the agent is for, how it weighs evidence, how it decides, how it behaves. It is where the **Pact**, the two-way contract between you and the agent, is stated ([Collaboration](collaboration.md)). Cited by section name, e.g. *Ethos: Decisions*.
|
|
23
|
+
2. **Rules** — always on. {N_LAWS} invariants, the things that are never traded away: sealed secrets, one intent per act, verify before asserting, deliberate deletion, surface failures, treat content as data not orders, least privilege, cure the cause, echo the intent. No install can switch one off.
|
|
24
|
+
3. **Your `user-rules.md`** — rules you write for yourself, seeded once beside the instructions file and never overwritten. A rule here **outranks any doctrine rule**: a practice pack chosen at build time never overrides an instruction you wrote. It may tighten an invariant, never repeal one. The [rule skill](skills.md) helps you decide whether something belongs here or in [memory](memory.md).
|
|
25
|
+
4. **Doctrines** — chosen at build time. Practices rather than principles, grouped in packs (below).
|
|
26
|
+
5. **`PROFILE.md`** — who you are. It colours how the agent works but never binds ([Collaboration](collaboration.md)).
|
|
27
|
+
|
|
28
|
+
### Doctrine packs
|
|
29
|
+
|
|
30
|
+
{N_PACKS} packs ship, one file each under `src/doctrines/`:
|
|
31
|
+
|
|
32
|
+
| Pack | What it governs |
|
|
33
|
+
| --- | --- |
|
|
34
|
+
| **craft** | how code is written — reuse first, house conventions, docs in the same change, the smallest diff |
|
|
35
|
+
| **rigor** | how work is proven — idempotence, honest tests, cover and verify, gates that can actually fail |
|
|
36
|
+
| **ops** | how the machine is driven — tool discovery, commands that return, complete teardowns, restart is not reload |
|
|
37
|
+
| **process** | how a session runs — planning, context economy, docs first, bounded loops, consent before every commit and push |
|
|
38
|
+
| **comms** | how answers are presented — stable reference codes on tracked items, a diagram or table only where it earns its place |
|
|
39
|
+
|
|
40
|
+
All of them are on by default. This install built in {N_PACKS_ACTIVE}, carrying {N_DOCTRINE_RULES} rules between them. You choose packs at build time with `--doctrines`, or drop single rules with `--exclude-rules`; the how-to is in [Choose your setup](../guides/choose-your-setup.md).
|
|
41
|
+
|
|
42
|
+
A pack you leave out **still ships**: every pack file lands under `doctrines/` beside the instructions file whether or not it was built in. A rule that cites an inactive pack still resolves on disk, and you can read the alternatives before turning one on. An inactive pack loses its binding force, not its availability.
|
|
43
|
+
|
|
44
|
+
**process** is the one pack whose removal changes what the machine does, not only what the agent reads: it holds *Consent Before Push*, which a hook enforces. Without it, commits and pushes are no longer stopped for a question — destructive git still is, because that is a Rule ([Hooks](hooks.md)).
|
|
45
|
+
|
|
46
|
+
### Themes do not move rules
|
|
47
|
+
|
|
48
|
+
A [theme](themes.md) renames the nouns — an `imperial` install calls the invariants *Dictates* — but the layers, their order and every rule stay exactly where they are.
|
|
49
|
+
|
|
50
|
+
### Related
|
|
51
|
+
|
|
52
|
+
[Footprint](footprint.md) — how much of this text loads every turn · [Exclusions](exclusions.md) — switching rules off per rule versus per repo · [Glossary](../reference/glossary.md)
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
---
|
|
2
|
+
group: concepts
|
|
3
|
+
order: 4
|
|
4
|
+
title: "Skills"
|
|
5
|
+
kind: "concept"
|
|
6
|
+
link: {"hash": "#/section/skills", "label": "Browse the catalog →"}
|
|
7
|
+
---
|
|
8
|
+
A **skill** is a repeatable workflow written as a markdown playbook: when it applies, the steps, and what "done" looks like. The agent reads the playbook before acting, so a task it has a skill for is done the same careful way every time instead of improvised.
|
|
9
|
+
|
|
10
|
+
> **You already know this:** a runbook. Nobody deploys from memory — you open the deploy runbook and follow it. A skill is that runbook, addressed to the agent.
|
|
11
|
+
|
|
12
|
+
{N_SKILLS} skills ship. Each is authored once under `src/skills/` and installed under `skills/` in the install, where the host looks for skills.
|
|
13
|
+
|
|
14
|
+
### How a skill gets used
|
|
15
|
+
|
|
16
|
+
- **By name.** Ask for it — "brainstorm this", "run a council on it" — or, on hosts with slash commands, type `/<name>`.
|
|
17
|
+
- **By trigger.** Every skill has a one-line description of its purpose and when it applies. The host shows those descriptions to the agent every turn, and the agent opens the matching skill when your request fits.
|
|
18
|
+
- **User-only skills.** A few skills are marked to open only when *you* call them (a teaching drill, a tool tied to a setup the agent cannot see). They answer `/<name>` but the agent never starts them on its own, and their description stays out of the always-loaded list.
|
|
19
|
+
|
|
20
|
+
### A tour
|
|
21
|
+
|
|
22
|
+
| You want to… | Skill |
|
|
23
|
+
| --- | --- |
|
|
24
|
+
| turn a raw idea into an approved design before any code | `brainstorm` |
|
|
25
|
+
| write a plan to a file before a non-trivial task | `plan` |
|
|
26
|
+
| drive a change through smallest change → tests → green suite | `develop` |
|
|
27
|
+
| find a bug by evidence: reproduce, isolate, root-cause, verify | `debug` |
|
|
28
|
+
| answer a question from the open web, every claim cross-checked | `research` |
|
|
29
|
+
| have several viewpoints debate a decision | `council` |
|
|
30
|
+
| get an adversarial critique of anything | `roast-me` |
|
|
31
|
+
| see what a change does before you agree to commit it | `explain-changes` |
|
|
32
|
+
| stage the right paths and write a focused commit | `commit` |
|
|
33
|
+
| open a pull request, or finish and merge a branch | `ship` |
|
|
34
|
+
| decide whether something is a standing rule or a fact to remember | `rule` |
|
|
35
|
+
| be taught a topic, or quizzed on it | `teach`, `quiz` |
|
|
36
|
+
|
|
37
|
+
The full list, with each description, is in the catalog.
|
|
38
|
+
|
|
39
|
+
### Skills improve themselves
|
|
40
|
+
|
|
41
|
+
Every skill ends with one beat of reflection: if a step misled or a step was missing, the agent proposes the exact edit to that skill and applies it only with your assent. Most runs end with nothing to change.
|
|
42
|
+
|
|
43
|
+
### What they cost
|
|
44
|
+
|
|
45
|
+
The skill *bodies* are read only when used. The *descriptions* are listed to the agent every turn so it can pick the right one — that list is part of the always-on cost described in [Footprint](footprint.md).
|
|
46
|
+
|
|
47
|
+
### Related
|
|
48
|
+
|
|
49
|
+
[Agents](agents.md) — who does the work · [Rules](rules.md) — what every skill obeys · writing your own: [docs/extending.md](../extending.md)
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
---
|
|
2
|
+
group: concepts
|
|
3
|
+
order: 12
|
|
4
|
+
title: "Themes"
|
|
5
|
+
kind: "concept"
|
|
6
|
+
---
|
|
7
|
+
A **theme** changes the agent's *voice* and the words the harness uses for its own parts. It never changes structure: the same rules, in the same order, with the same files, folders and links, whatever theme you pick.
|
|
8
|
+
|
|
9
|
+
> **You already know this:** an editor colour scheme. It changes how everything looks, never what the code does.
|
|
10
|
+
|
|
11
|
+
### What changes and what does not
|
|
12
|
+
|
|
13
|
+
| Changes with the theme | Never changes |
|
|
14
|
+
| --- | --- |
|
|
15
|
+
| how the agent phrases its replies | which rules apply, and their order |
|
|
16
|
+
| the nouns for the harness's parts — an `imperial` install calls the Rules *Dictates*, agents *Adepts*, skills *Rites* | folder names: `agents/`, `skills/`, `memory/`, `laws/`, `doctrines/`… |
|
|
17
|
+
| the banner, the readiness line the agent prints when it starts, the closing lines | section layout and the links between files |
|
|
18
|
+
| the names and descriptions shown for rules, agents and skills | rule addresses such as `process 5` |
|
|
19
|
+
|
|
20
|
+
`neutral` keeps the plain words — Rule, Doctrine, Agent, Skill, Memory — so it is the theme to pick if you want no flavour at all. The [glossary](../reference/glossary.md) shows each themed word beside its neutral one.
|
|
21
|
+
|
|
22
|
+
### The themes that ship
|
|
23
|
+
|
|
24
|
+
14 themes ship: `neutral`, `imperial` (Warhammer 40k), `military`, `pirate`, `wizard`, `cyberpunk`, `gamer`, `sports` (play-by-play), `biker`, `commentator`, `joker`, `marvin`, `mean` and `verstappen`.
|
|
25
|
+
|
|
26
|
+
### Switching
|
|
27
|
+
|
|
28
|
+
The theme is stored in a `.geneseed-theme` marker in the install, so upgrades and rebuilds keep it.
|
|
29
|
+
|
|
30
|
+
- **Setup wizard** — lists every theme with a live preview:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
geneseed setup
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
- **Web console** — the per-install voice dropdown on the Harness page.
|
|
37
|
+
- **Command line** — with the emit target of the install you are changing:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
geneseed build --emit claude-global --theme pirate
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
<!--harness:opencode-->
|
|
44
|
+
*(OpenCode only)*
|
|
45
|
+
OpenCode also has *colour* themes for its interface. Those are separate from voice themes; `geneseed theme <name>` creates your own colour theme in OpenCode's themes folder, and it survives rebuilds.
|
|
46
|
+
<!--/harness-->
|
|
47
|
+
|
|
48
|
+
### Writing your own
|
|
49
|
+
|
|
50
|
+
A theme is one JSON file of voice tokens in `themes/`. How the tokens split between voice and structure, and how to add one, is in the maintainer design notes: [DESIGN.md](../../DESIGN.md).
|
package/docs/extending.md
CHANGED
|
@@ -26,7 +26,7 @@ Three seams, and almost every question about "where do I edit?" resolves to one
|
|
|
26
26
|
| Seam | Source of truth | How it reaches a user | Rebuild needed |
|
|
27
27
|
|---|---|---|---|
|
|
28
28
|
| **Harness content** | `src/` (laws, agents, skills, memory/notebook conventions, `AGENT.md.tmpl`) + `themes/*.json` for voice | rendered into a bundle by `geneseed build` / `update` / `rebuild-all` | yes — every active install must be re-emitted |
|
|
29
|
-
| **
|
|
29
|
+
| **Docs** | `docs/{understand,guides,concepts,reference}/*.md` + `docs/_groups.json` | read on GitHub as plain markdown, and off disk at request time by `js/web/docs.mjs` | no — not even a daemon restart for content |
|
|
30
30
|
| **Console app** | `web/src/**` | built by vite into the **tracked** `web/dist/` | yes — rebuild *and commit* dist, then `geneseed web restart` |
|
|
31
31
|
|
|
32
32
|
Two rules follow from the table and they cause most of the surprises:
|
|
@@ -34,7 +34,7 @@ Two rules follow from the table and they cause most of the surprises:
|
|
|
34
34
|
- **Nothing propagates by itself.** A bundle is a *render*. Editing `src/` changes nothing on any
|
|
35
35
|
machine until something re-emits (`sourceFingerprint` in `js/build/version.mjs` re-fingerprints, `js/inspect/status.mjs`
|
|
36
36
|
reports the drift).
|
|
37
|
-
- **`docs
|
|
37
|
+
- **`docs/` is data, `web/src/` is code.** A new documentation page is one file and no
|
|
38
38
|
rebuild. A new screen is a new hashed chunk and a mandatory `web/dist` commit.
|
|
39
39
|
|
|
40
40
|
### Counts are computed — never type one
|
|
@@ -408,10 +408,11 @@ The `geneseed-` prefix and the `.js` suffix are mechanically load-bearing: the b
|
|
|
408
408
|
1. `adapters/opencode/plugins/geneseed-<name>.js` — ESM, zero dependencies. The factory-export
|
|
409
409
|
convention is real (OpenCode requires it) but **ungated**; the only generic gate on plugin
|
|
410
410
|
source is `node --check` (the one spawn in `authoringProblems`).
|
|
411
|
-
2. `docs/
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
411
|
+
2. `docs/reference/opencode-plugins.md` — a `## geneseed-<name>` section (gated: every plugin
|
|
412
|
+
file needs one). The count in its intro renders from `{N_PLUGINS}`.
|
|
413
|
+
3. `docs/understand/on-your-machine.md` — a row in the OpenCode map table (Piece · What it does
|
|
414
|
+
for you · Kind · Cost · Turn it off). **Hand-written and ungated** beyond the table parsing.
|
|
415
|
+
4. `docs/concepts/hosts.md` — check the capability matrix still tells the truth.
|
|
415
416
|
5. `README.md` — **three** sites: the badge, the `N plugins` prose, and the 🔌 Plugins row.
|
|
416
417
|
6. `SHIPPED.md` — the bare name inside `plugins (…)`; that list must equal the directory exactly,
|
|
417
418
|
in both directions (`tests/unit/web_api.test.mjs:1655`).
|
|
@@ -432,14 +433,20 @@ a row to `js/cli-table.json` with a help string over 20 characters.
|
|
|
432
433
|
|
|
433
434
|
### 4c — A documentation page
|
|
434
435
|
|
|
435
|
-
**One file, no rebuild, no server change.** `docs
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
436
|
+
**One file, no rebuild, no server change.** `docs/<folder>/<id>.md` — folder ∈ understand,
|
|
437
|
+
guides, concepts, reference; the stem is the id and must be unique across folders (a duplicate
|
|
438
|
+
throws). The same file is what GitHub shows, so write for both
|
|
439
|
+
(`tests/unit/docs_tree.test.mjs` gates it). Frontmatter is JSON-per-value, not YAML
|
|
440
|
+
(`docFrontmatter` in `js/web/docs.mjs`):
|
|
441
|
+
|
|
442
|
+
- `group` must match an id in `docs/_groups.json` — gated by `docs_tree.test.mjs`.
|
|
443
|
+
- `kind` ∈ `markdown | concept | map | glossary | about | cli`; anything else 404s. `map` is a
|
|
444
|
+
concept page whose Piece/Kind/Cost table the console turns into the clickable map.
|
|
445
|
+
- `harness: "claude"|"opencode"` hides the page from the other host — keep it for how-tos that
|
|
446
|
+
cannot run elsewhere; a reference page says its host in its title instead.
|
|
447
|
+
- Link pages with relative `.md` links; the console rewrites them to `#/docs/<id>`. A host-only
|
|
448
|
+
passage is `<!--harness:x-->` + a visible `*(OpenCode only)*` / `*(Claude Code only)*` line.
|
|
449
|
+
- No `{N_*}` token in `understand/` or `guides/` — GitHub would show it raw.
|
|
443
450
|
- `kind: "markdown"` pulls from a repo file via `source:`, traversal-guarded, optionally sliced to
|
|
444
451
|
one section with `anchor:` + `slice: true`.
|
|
445
452
|
|
|
@@ -593,7 +600,7 @@ text or flags is now an ordinary edit: `js/cli-table.json` is the owned document
|
|
|
593
600
|
holds. Three hand-written equalities still converge on it and are cheap to keep in step — the
|
|
594
601
|
29-command count and the hidden-argument rule (`tests/unit/cli_table.test.mjs`), and
|
|
595
602
|
`tests/unit/docs.test.mjs`, which validates every fenced `geneseed <verb> <flags>` line in
|
|
596
|
-
`README.md`, `
|
|
603
|
+
`README.md`, `SHIPPED.md` and every page under `docs/{understand,guides,concepts,reference}/` against the table.
|
|
597
604
|
|
|
598
605
|
---
|
|
599
606
|
|
|
@@ -607,8 +614,8 @@ only, at best, on its presence.
|
|
|
607
614
|
| `§N` cross-references into `AGENT.md`'s anatomy | `src/skills/*`, `src/agents/*`, `adapters/**` | **range only.** `constitutionProblems` refuses a `§N` the template declares no section for — which catches a pointer past the end, the shape *removing* a section leaves. It cannot catch one that still resolves and now means something else, which is the shape *inserting* a section leaves, and is what actually happened when `## 2. Doctrines` pushed every later section down one. **Renumbering the anatomy means `grep -rn '§' src/ adapters/` and reading every hit.** Four satellites and a live OpenCode deny message shipped stale because the sweep stopped at `AGENT.md.tmpl` |
|
|
608
615
|
| Per-law Principle lines | `web/src/pages/Laws.jsx` | presence and class only, never accuracy |
|
|
609
616
|
| 588 themed constitution titles (42 keys × 14 voices) — `LEX_<ID>` (one per law), `DOC_<ID>` (one per doctrine rule), `PACK_<NAME>` | `themes/*.json` | key presence only — a shipped placeholder is green. `LEX_*` and `DOC_*` are held across the template too, and in both directions; `PACK_*` only across the voices |
|
|
610
|
-
| The README keyword enumerations | `README.md`, `docs/
|
|
611
|
-
| The
|
|
617
|
+
| The README keyword enumerations | `README.md`, `docs/concepts/rules.md` | nothing |
|
|
618
|
+
| The per-host map of what lands on a machine | `docs/understand/on-your-machine.md` | table shape only, never accuracy |
|
|
612
619
|
| Section labels and page subtitles | `web/src/lib/sections.js`, `web/src/pages/Docs/index.jsx` | nothing |
|
|
613
620
|
| `THEME_BLURBS` (8 of 14), `ART` (8 of 14) | `js/maintain/setup.mjs`, `js/ui/anim.mjs` | nothing — missing entries fall back silently |
|
|
614
621
|
| `LOADED_SIGIL` uniqueness | `themes/*.json` | nothing, and it is load-bearing for theme detection |
|
|
@@ -678,10 +685,9 @@ answer.
|
|
|
678
685
|
- **`AGENT_LESSON_PROMPT` has no drift gate.** Its sibling `LEARN_PROMPT_HEAD` is checked for
|
|
679
686
|
extractability; this one's parity test was retired. Reformat the declaration in
|
|
680
687
|
`geneseed-learn.js` and the per-agent lesson prompt silently degrades to a two-line fallback.
|
|
681
|
-
- **The fenced-command gate
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
tree to that array is one line, and it would have caught item 2 on the day it was written.
|
|
688
|
+
- **The fenced-command gate skips the maintainer docs.** `tests/unit/docs.test.mjs` validates
|
|
689
|
+
every `geneseed <verb> <flags>` line against `js/cli-table.json` in `README.md`, `SHIPPED.md`
|
|
690
|
+
and the user docs tree — not in `DESIGN.md` or the `docs/*.md` maintainer pages.
|
|
685
691
|
|
|
686
692
|
---
|
|
687
693
|
|
|
@@ -742,6 +748,11 @@ handler falls back to `index.html` at 200 with `text/html`, and the browser repo
|
|
|
742
748
|
"no running server recorded" and exits 0, and `web restart` starts a *second* daemon. Recovery is
|
|
743
749
|
to kill every pid on the port, then `geneseed web start`.
|
|
744
750
|
|
|
751
|
+
`--port N` on `web stop|restart|status` names *which* daemon: the verb acts only if the record is
|
|
752
|
+
on N, and refuses (exit 1, nothing sent) when it names another port. A test instance on another
|
|
753
|
+
port is therefore stopped with `--port`, never with a bare `web stop` — that one stops whatever
|
|
754
|
+
the record names, usually the live console on 4747.
|
|
755
|
+
|
|
745
756
|
---
|
|
746
757
|
|
|
747
758
|
## 10 — What to settle before the next wave
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
---
|
|
2
|
+
group: guides
|
|
3
|
+
order: 10
|
|
4
|
+
title: "Start the web console at login"
|
|
5
|
+
kind: "concept"
|
|
6
|
+
---
|
|
7
|
+
The web console is the only long-running Geneseed process. `geneseed web start` launches it as a background process on `127.0.0.1:4747` and returns immediately. A login item that runs this command once, with `--no-browser`, leaves the console ready whenever you open [http://127.0.0.1:4747](http://127.0.0.1:4747).
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
geneseed web start --no-browser # start in the background
|
|
11
|
+
geneseed web status # is it running?
|
|
12
|
+
geneseed web stop # stop it (the login item stays)
|
|
13
|
+
geneseed web restart # restart it, e.g. after an update
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Only one console runs at a time. A second `start` does nothing, so logging in twice is harmless. Each machine and each user runs its own console on its own loopback address.
|
|
17
|
+
|
|
18
|
+
> **Always use `web start` in a login item, never bare `web`.** Bare `geneseed web` runs in the foreground and leaves no record of itself. `web stop`, `web restart` and `web status` then cannot see it: they report no live server while it keeps serving. A `restart` would then start a second console that cannot take the busy port.
|
|
19
|
+
|
|
20
|
+
> **This is a file you create. Geneseed never writes or edits a login item**, and that includes `geneseed migrate`. To remove the login item, delete the file.
|
|
21
|
+
|
|
22
|
+
The examples below assume `geneseed` is on your `PATH` (see [Run geneseed from anywhere](run-anywhere.md)). Login items do not see your shell's `PATH`, so always use the absolute path to the launcher. For an npm install, `npm prefix -g` shows where npm keeps it.
|
|
23
|
+
|
|
24
|
+
## Windows
|
|
25
|
+
|
|
26
|
+
Press **Win+R**, type `shell:startup`, and create a file called `geneseed-web.vbs` in the folder that opens:
|
|
27
|
+
|
|
28
|
+
```vbs
|
|
29
|
+
' geneseed-web.vbs: start the Geneseed web console at login (hidden, no browser).
|
|
30
|
+
CreateObject("WScript.Shell").Run "cmd /c ""C:\Users\you\AppData\Local\Geneseed\bin\geneseed.cmd"" web start --no-browser", 0, False
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Write out the full path, as shown. VBS does not expand `%LOCALAPPDATA%` inside a string. The script runs hidden, so no console window flashes at login. To disable it, delete the file.
|
|
34
|
+
|
|
35
|
+
If you would rather use a scheduled task:
|
|
36
|
+
|
|
37
|
+
```powershell
|
|
38
|
+
schtasks /Create /TN "Geneseed Web" /SC ONLOGON /TR "\"%LOCALAPPDATA%\Geneseed\bin\geneseed.cmd\" web start --no-browser" /RL LIMITED /F
|
|
39
|
+
schtasks /Delete /TN "Geneseed Web" /F # to remove it
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## macOS
|
|
43
|
+
|
|
44
|
+
Create a LaunchAgent at `~/Library/LaunchAgents/dev.geneseed.web.plist`. Set `RunAtLoad` and **no** `KeepAlive`. The launcher exits as soon as it has started the background process, which keeps running on its own.
|
|
45
|
+
|
|
46
|
+
```xml
|
|
47
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
48
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
|
|
49
|
+
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
50
|
+
<plist version="1.0">
|
|
51
|
+
<dict>
|
|
52
|
+
<key>Label</key> <string>dev.geneseed.web</string>
|
|
53
|
+
<key>ProgramArguments</key>
|
|
54
|
+
<array>
|
|
55
|
+
<string>/Users/you/.local/bin/geneseed</string>
|
|
56
|
+
<string>web</string>
|
|
57
|
+
<string>start</string>
|
|
58
|
+
<string>--no-browser</string>
|
|
59
|
+
</array>
|
|
60
|
+
<key>RunAtLoad</key> <true/>
|
|
61
|
+
</dict>
|
|
62
|
+
</plist>
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
`/Users/you/.local/bin/geneseed` is where `./geneseed link` puts the launcher by default. Replace it with your own absolute path. Then load the agent, which also starts the console now:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
launchctl load ~/Library/LaunchAgents/dev.geneseed.web.plist # enable and start now
|
|
69
|
+
launchctl unload ~/Library/LaunchAgents/dev.geneseed.web.plist # disable
|
|
70
|
+
```
|