geneseed 3.17.0 → 3.18.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 +22 -0
- package/README.md +17 -3
- package/SHIPPED.md +3 -3
- package/adapters/claude-code/skills/geneseed/SKILL.md +1 -1
- package/adapters/opencode/README.md +2 -2
- package/adapters/opencode/plugins/geneseed-context.js +19 -17
- package/adapters/opencode/plugins/geneseed-guard.js +7 -7
- package/bin/geneseed-cli.mjs +5 -0
- package/docs/concepts/exclusions.md +1 -1
- package/docs/concepts/skills.md +4 -0
- package/docs/extending.md +33 -0
- package/docs/guides/read-non-markdown.md +1 -1
- package/docs/guides/uninstall.md +1 -1
- package/docs/guides/upgrade.md +1 -1
- package/docs/guides/wiki.md +4 -4
- package/docs/opencode-plugin-setup.md +1 -1
- package/docs/reference/env-context.md +2 -2
- package/docs/reference/plugin-context.md +2 -2
- package/docs/reference/plugin-guard.md +1 -1
- package/docs/token-footprint.md +18 -15
- package/docs/understand/take-it-out.md +1 -1
- package/harness.config.json +1 -1
- package/js/README.md +4 -1
- package/js/build/args.mjs +22 -20
- package/js/build/bundle.mjs +1 -3
- package/js/build/emit-claude.mjs +5 -4
- package/js/build/emit-opencode.mjs +9 -2
- package/js/build/generate.mjs +6 -6
- package/js/build/render.mjs +19 -12
- package/js/build/source.mjs +82 -7
- package/js/build/stubs.mjs +35 -6
- package/js/build/themes.mjs +1 -3
- package/js/cli-table.json +53 -0
- package/js/hosts/hooks-context.mjs +13 -6
- package/js/hosts/hosts.mjs +1 -3
- package/js/hosts/installs.mjs +13 -7
- package/js/hosts/mcp.mjs +1 -1
- package/js/hosts/native.mjs +60 -5
- package/js/hosts/opencode.mjs +37 -6
- package/js/hosts/settings.mjs +1 -0
- package/js/hosts/shim.mjs +1 -0
- package/js/inspect/checks-authoring.mjs +4 -1
- package/js/inspect/checks-repo.mjs +164 -2
- package/js/inspect/diff.mjs +5 -1
- package/js/inspect/doctor.mjs +2 -1
- package/js/inspect/inventory.mjs +7 -9
- package/js/inspect/scorecard-checks.mjs +571 -0
- package/js/inspect/scorecard-svg.mjs +85 -0
- package/js/inspect/scorecard.mjs +839 -0
- package/js/lib/json.mjs +1 -1
- package/js/maintain/migrate.mjs +2 -1
- package/js/maintain/uninstall.mjs +2 -3
- package/js/maintain/update.mjs +10 -3
- package/js/ui/menu.mjs +2 -2
- package/js/ui/tui.mjs +1 -0
- package/js/web/api.mjs +2 -0
- package/js/web/catalog.mjs +24 -7
- package/js/web/daemon.mjs +2 -1
- package/js/web/routes.mjs +2 -0
- package/js/web/server.mjs +1 -1
- package/js/web/user-files.mjs +1 -0
- package/package.json +11 -3
- package/registry.json +12 -75
- package/src/AGENT.md.tmpl +13 -22
- package/src/agents/docs.md +1 -1
- package/src/agents/researcher.md +1 -1
- package/src/bricks/bruno-test.md +2 -2
- package/src/bricks/ci-fix.md +3 -3
- package/src/bricks/deps-audit.md +3 -3
- package/src/bricks/migration-plan.md +2 -2
- package/src/doctrines/process.md +2 -2
- package/src/laws/universal.md +2 -2
- package/src/skills/brainstorm.md +14 -10
- package/src/skills/bruno.md +84 -0
- package/src/skills/codebase-design.md +41 -23
- package/src/skills/daydream/SKILL.md +3 -3
- package/src/skills/daydream/VENDOR.md +2 -2
- package/src/skills/daydream/instructions.md +1 -1
- package/src/skills/debug/ci.md +11 -0
- package/src/skills/debug.md +11 -8
- package/src/skills/dependencies.md +65 -0
- package/src/skills/develop.md +9 -4
- package/src/skills/document-project.md +27 -22
- package/src/skills/geneseed-code-review.md +13 -8
- package/src/skills/geneseed.md +4 -1
- package/src/skills/git-history.md +78 -0
- package/src/skills/handoff.md +4 -3
- package/src/skills/parallel-agents.md +1 -0
- package/src/skills/plan.md +5 -1
- package/src/skills/prototype.md +10 -7
- package/src/skills/research.md +6 -1
- package/src/skills/rule/consolidate.md +32 -0
- package/src/skills/rule.md +14 -4
- package/src/skills/security-audit.md +1 -1
- package/src/skills/ship.md +8 -5
- package/src/skills/teach.md +5 -3
- package/src/skills/wayfinder.md +19 -16
- package/src/skills/wiki.md +2 -2
- package/themes/_TEMPLATE.json +7 -16
- package/themes/biker.json +7 -16
- package/themes/commentator.json +7 -16
- package/themes/cyberpunk.json +7 -16
- package/themes/gamer.json +7 -16
- package/themes/imperial.json +7 -16
- package/themes/joker.json +7 -16
- package/themes/marvin.json +7 -16
- package/themes/mean.json +7 -16
- package/themes/military.json +7 -16
- package/themes/neutral.json +7 -16
- package/themes/pirate.json +7 -16
- package/themes/sports.json +7 -16
- package/themes/verstappen.json +7 -16
- package/themes/wizard.json +7 -16
- package/web/dist/assets/{Activity-DonKN1pi.js → Activity-4M4VQJOh.js} +1 -1
- package/web/dist/assets/{ActivityDetail-e47a3cdE.js → ActivityDetail-CnmDs43F.js} +1 -1
- package/web/dist/assets/{Dashboard-Cr7i0PsO.js → Dashboard-lTaH58R9.js} +2 -2
- package/web/dist/assets/{Docs-Lne3nuzD.js → Docs-DU5znu5f.js} +1 -1
- package/web/dist/assets/FilterInput-BSfpStOZ.js +1 -0
- package/web/dist/assets/{GreenhouseView-4CbIuTpl.js → GreenhouseView-BxO84bKX.js} +1 -1
- package/web/dist/assets/{Installs-CIzbV1Ks.js → Installs-B1WcObxK.js} +1 -1
- package/web/dist/assets/{JournalView-BlBfuvzj.js → JournalView-0YNKcaaD.js} +1 -1
- package/web/dist/assets/{Laws-B-pjcjHr.js → Laws-DnDpRwpE.js} +1 -1
- package/web/dist/assets/Library-DBkKsBMe.js +1 -0
- package/web/dist/assets/{Loops-DIOxW1xH.js → Loops-P-6RCdzS.js} +1 -1
- package/web/dist/assets/Markdown-C6fRd4A4.js +67 -0
- package/web/dist/assets/{OperatorHudView-D7S7z7CJ.js → OperatorHudView-BZZ3uJPH.js} +1 -1
- package/web/dist/assets/{Personal-Ws3v35AB.js → Personal-BoVw6OCW.js} +1 -1
- package/web/dist/assets/{Tabs-6Z1eziAq.js → Tabs-VYLhUTiX.js} +1 -1
- package/web/dist/assets/{activity-Dr7ZMBI3.js → activity-dcg5vF9j.js} +1 -1
- package/web/dist/assets/{drawable-ATNeYKbT.js → drawable-CdNARIKC.js} +1 -1
- package/web/dist/assets/{index-CDg5XUhG.js → index-hsabpYzv.js} +2 -2
- package/web/dist/assets/react-DRhoX0kS.js +9 -0
- package/web/dist/assets/{usePoll-DD8VjtSg.js → usePoll-BmR631BB.js} +1 -1
- package/web/dist/index.html +2 -2
- package/src/skills/bruno-collection-generator.md +0 -52
- package/src/skills/bruno-test-writer.md +0 -51
- package/src/skills/ci-fix.md +0 -49
- package/src/skills/consolidate-memory.md +0 -50
- package/src/skills/deps-audit.md +0 -46
- package/src/skills/domain-modeling.md +0 -27
- package/src/skills/git-archaeology.md +0 -36
- package/src/skills/git-rescue.md +0 -58
- package/src/skills/migrate.md +0 -34
- package/src/skills/opencode-theme.md +0 -42
- package/src/skills/repo-map.md +0 -25
- package/src/skills/tickets.md +0 -33
- package/web/dist/assets/FilterInput-CVyqmYWM.js +0 -1
- package/web/dist/assets/Library-x8Nzg6yq.js +0 -1
- package/web/dist/assets/Markdown-X2a3qvOh.js +0 -38
- package/web/dist/assets/react-B9Z_tXRV.js +0 -8
package/js/lib/json.mjs
CHANGED
|
@@ -38,7 +38,7 @@ class JsonNumber {
|
|
|
38
38
|
* Python would have \u2014 NOT the original literal, because `json.dumps(json.loads('1.50'))`
|
|
39
39
|
* is `1.5`: Python re-formats through repr rather than echoing the source.
|
|
40
40
|
*/
|
|
41
|
-
toJSON() { return JSON.rawJSON(formatValue(this)); }
|
|
41
|
+
toJSON() { return /** @type {any} */ (JSON).rawJSON(formatValue(this)); }
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
/**
|
package/js/maintain/migrate.mjs
CHANGED
|
@@ -213,8 +213,9 @@ export function cmdMigrate(args = {}) {
|
|
|
213
213
|
// `process 5` among them) and dropped `--config-dir`, so a global found through
|
|
214
214
|
// `CLAUDE_CONFIG_DIR`/`OPENCODE_CONFIG_DIR` re-emitted into the DEFAULT dir instead.
|
|
215
215
|
for (const r of rows) {
|
|
216
|
-
const { emit, theme, argv } = installProfile(r.host, r.scope, r.root);
|
|
217
216
|
const label = `${r.host}:${r.scope} (${r.root})`;
|
|
217
|
+
const { emit, theme, argv } = installProfile(r.host, r.scope, r.root,
|
|
218
|
+
(n) => printErr(`[migrate] ${label}: ${n}\n`));
|
|
218
219
|
printOut(`[migrate] re-emitting ${label}: theme=${theme} emit=${emit}\n`);
|
|
219
220
|
let rc = 1;
|
|
220
221
|
try { rc = driverMain(argv); } catch { rc = 1; }
|
|
@@ -155,6 +155,7 @@ function pruneAncestors(start, stop) {
|
|
|
155
155
|
* `ownedWithin` first, the same containment boundary deactivate draws: the manifest is a file
|
|
156
156
|
* on disk, and without it an `owned` entry of `../../.bashrc` was unlinked — and the prune
|
|
157
157
|
* then climbed from ITS parent, which never meets `base`, removing empty directories as it went.
|
|
158
|
+
* @returns {[number, string[]]}
|
|
158
159
|
*/
|
|
159
160
|
function unlinkOwned(base, owned, label = '') {
|
|
160
161
|
let removed = 0;
|
|
@@ -758,9 +759,7 @@ export function cmdUninstall(args) {
|
|
|
758
759
|
*/
|
|
759
760
|
function moveTree(src, dst) {
|
|
760
761
|
if (existsSync(dst)) {
|
|
761
|
-
|
|
762
|
-
e.code = 'EEXIST';
|
|
763
|
-
throw e;
|
|
762
|
+
throw Object.assign(new Error(String(dst)), { code: 'EEXIST' });
|
|
764
763
|
}
|
|
765
764
|
mkdirSync(path.dirname(dst), { recursive: true });
|
|
766
765
|
renameSync(src, dst);
|
package/js/maintain/update.mjs
CHANGED
|
@@ -270,6 +270,7 @@ export function killTree(child) {
|
|
|
270
270
|
* `tests/unit/update_git.test.mjs` runs it over a recorded fetch transcript instead.
|
|
271
271
|
*
|
|
272
272
|
* Returns `[linesToLog, lastPhase]`, splitting the reference's loop from its side effects.
|
|
273
|
+
* @returns {[string[], string]}
|
|
273
274
|
*/
|
|
274
275
|
export function fetchPhases(rawLines, last = '') {
|
|
275
276
|
const out = [];
|
|
@@ -609,13 +610,17 @@ async function drainStdout() {
|
|
|
609
610
|
* rewritten markers back through `installProfile`, so the loss stuck. `installProfile` is the
|
|
610
611
|
* one reader of an install's axes; this takes its answer rather than growing a second one.
|
|
611
612
|
*
|
|
613
|
+
* `notify` hears the one-line notice for an excluded skill since merged or retired, as
|
|
614
|
+
* `rebuild-all` prints it. `upgrade` reads it BEFORE the pull, so it reflects the pre-pull
|
|
615
|
+
* alias table: a skill merged by the very commits being pulled is not named until the next run.
|
|
616
|
+
*
|
|
612
617
|
* Only the TAIL of the argv is kept: theme and emit are `upgrade`'s to decide (a theme argument
|
|
613
618
|
* may override the marker), and `setupBuildArgs` opens with exactly those four tokens when it
|
|
614
619
|
* is given no out and no root.
|
|
615
620
|
*/
|
|
616
|
-
export async function installAxes(dir, { installProfile, setupBuildArgs }) {
|
|
621
|
+
export async function installAxes(dir, { installProfile, setupBuildArgs }, notify = null) {
|
|
617
622
|
if (!existsSync(path.join(String(dir), '.geneseed-emit'))) return [];
|
|
618
|
-
const p = installProfile('opencode', 'global', String(dir));
|
|
623
|
+
const p = installProfile('opencode', 'global', String(dir), notify);
|
|
619
624
|
return setupBuildArgs('', 'files', null, null, p.footprint, p.posture, p.mode, p.doctrines,
|
|
620
625
|
undefined, p.excludeRules, p.trust, p.excludeSkills).slice(4);
|
|
621
626
|
}
|
|
@@ -704,7 +709,8 @@ export async function upgrade(ref = null, themeArg = null) {
|
|
|
704
709
|
// `installAxes` for why the target's own axes must be carried into the rebuild.
|
|
705
710
|
const [generate, { bounceDaemonIfRunning }] = await Promise.all([
|
|
706
711
|
import('../build/generate.mjs'), import('../web/daemon.mjs')]);
|
|
707
|
-
const axes = await installAxes(emit === 'opencode-global' ? cfg : out, generate
|
|
712
|
+
const axes = await installAxes(emit === 'opencode-global' ? cfg : out, generate,
|
|
713
|
+
(n) => log(`[upgrade] ${n}`));
|
|
708
714
|
|
|
709
715
|
log(`[geneseed] fetching from origin (git: ${which('git') || 'git'}, `
|
|
710
716
|
+ `timeout: ${fetchTimeout()}s) ...`);
|
|
@@ -921,6 +927,7 @@ async function bootstrapPlain() {
|
|
|
921
927
|
// deployed harness's local edits are overwritten by the rebuild with nothing recorded.
|
|
922
928
|
// Caught by `bootstrap/an-improvements-file-the-step-exported-is-re-announced-afterwards`,
|
|
923
929
|
// which was written for `_flush_export_notes` and found this instead.
|
|
930
|
+
/** @type {Array<[string, string[], () => Promise<number>]>} */
|
|
924
931
|
const steps = [['Update & rebuild', updateStepCmd('upgrade'),
|
|
925
932
|
() => cmdUpgrade({ ref: null, theme: null })]];
|
|
926
933
|
let failed = false;
|
package/js/ui/menu.mjs
CHANGED
|
@@ -103,11 +103,11 @@ export function cmdMenu() {
|
|
|
103
103
|
}
|
|
104
104
|
|
|
105
105
|
/** `cmd_home` — the default for a bare `geneseed`. */
|
|
106
|
-
export async function cmdHome(
|
|
106
|
+
export async function cmdHome(_args) {
|
|
107
107
|
if (webFirstOk()) {
|
|
108
108
|
printOut('[geneseed] opening the web console — `geneseed menu` for the terminal UI, '
|
|
109
109
|
+ 'GENESEED_NO_WEB=1 to disable.\n');
|
|
110
110
|
return startDaemon(null, 4747, true);
|
|
111
111
|
}
|
|
112
|
-
return cmdMenu(
|
|
112
|
+
return cmdMenu();
|
|
113
113
|
}
|
package/js/ui/tui.mjs
CHANGED
|
@@ -279,6 +279,7 @@ export function mark(kind) {
|
|
|
279
279
|
* — the order they are read in, the order AGENT.md renders them, and the order the console's
|
|
280
280
|
* three bands appear in. `Rule` and `Doctrine` are hardcoded English here, as `Rule` already
|
|
281
281
|
* was: this function receives an inventory, not a theme's nouns.
|
|
282
|
+
* @returns {any[][]}
|
|
282
283
|
*/
|
|
283
284
|
export function tuiEntries(inv) {
|
|
284
285
|
const rows = [['head', `AGENTS (${inv.agents.length})`, null]];
|
package/js/web/api.mjs
CHANGED
|
@@ -275,6 +275,7 @@ const RECENT_LIMIT = 8;
|
|
|
275
275
|
* law files, so a per-rule mtime would be the file's, repeated — one wrong date on nine rows.
|
|
276
276
|
*/
|
|
277
277
|
export function apiRecent(state) {
|
|
278
|
+
/** @type {Array<[string, string, () => any[]]>} */
|
|
278
279
|
const sections = [
|
|
279
280
|
['memory', 'memory', () => memoryItems(state)],
|
|
280
281
|
['notebook', 'notebook', () => notebookItems(state)],
|
|
@@ -316,6 +317,7 @@ export function apiLoops(state) {
|
|
|
316
317
|
const opts = { projectRoot: state.root };
|
|
317
318
|
const catalog = loadCatalog(opts);
|
|
318
319
|
const { bricks, templates, overridden } = catalog;
|
|
320
|
+
/** @type {(x: [string, any], y: [string, any]) => number} */
|
|
319
321
|
const byName = ([a], [b]) => (a < b ? -1 : 1);
|
|
320
322
|
return {
|
|
321
323
|
templates: [...templates].sort(byName).map(([name, { origin, ...graph }]) => ({
|
package/js/web/catalog.mjs
CHANGED
|
@@ -77,6 +77,10 @@ function specEntries(root, nested) {
|
|
|
77
77
|
for (const p of files) {
|
|
78
78
|
if (!isFile(p)) continue;
|
|
79
79
|
const [fm, body] = frontmatter(readMaybe(p) ?? '');
|
|
80
|
+
// An alias folder (native.mjs: an old name kept answering `/name`) is its target skill
|
|
81
|
+
// under a second name, not a skill of the user's own — listing it would read "personal".
|
|
82
|
+
if (nested && fm.get('disable-model-invocation') === 'true'
|
|
83
|
+
&& (fm.get('description') ?? '').startsWith('Alias of ')) continue;
|
|
80
84
|
const name = nested ? path.basename(path.dirname(p)) : path.basename(p, '.md');
|
|
81
85
|
out.push({ name, desc: specDesc(fm, body), body, source: resolvePath(p) });
|
|
82
86
|
}
|
|
@@ -179,15 +183,27 @@ export function notebookItems(state) {
|
|
|
179
183
|
}));
|
|
180
184
|
}
|
|
181
185
|
|
|
182
|
-
/**
|
|
186
|
+
/**
|
|
187
|
+
* The wiki manifest's names, current first. `wiki.jsonc` is the name before the `geneseed-`
|
|
188
|
+
* prefix: the build renames it on the next emit, and until then it is still read — one release.
|
|
189
|
+
*/
|
|
190
|
+
const WIKI_NAMES = ['geneseed-wiki.jsonc', 'wiki.jsonc'];
|
|
191
|
+
const WIKI_META = ['Wiki manifest', 'your machine-wide knowledge base(s)'];
|
|
192
|
+
|
|
193
|
+
/** The two setup manifests, in listing order (the wiki under either of its names). */
|
|
183
194
|
const CONFIG_META = {
|
|
184
195
|
'context.json': ['Project context', 'what the agent loads for this project'],
|
|
185
|
-
'wiki.jsonc':
|
|
196
|
+
'geneseed-wiki.jsonc': WIKI_META,
|
|
197
|
+
'wiki.jsonc': WIKI_META,
|
|
186
198
|
};
|
|
187
199
|
|
|
200
|
+
/** The wiki manifest beside the bundle under whichever name it has, or `null`. */
|
|
201
|
+
const wikiName = (state) => WIKI_NAMES.find((n) => isFile(path.join(state.target, n))) ?? null;
|
|
202
|
+
|
|
188
203
|
export function configItems(state) {
|
|
189
204
|
const out = [];
|
|
190
|
-
for (const fname of ['context.json',
|
|
205
|
+
for (const fname of ['context.json', wikiName(state)]) {
|
|
206
|
+
if (!fname) continue;
|
|
191
207
|
const p = path.join(state.target, fname);
|
|
192
208
|
if (!isFile(p)) continue;
|
|
193
209
|
const [title, desc] = CONFIG_META[fname] ?? [fname, ''];
|
|
@@ -227,7 +243,7 @@ function wikiPath(p) {
|
|
|
227
243
|
}
|
|
228
244
|
|
|
229
245
|
/**
|
|
230
|
-
* `$GENESEED_WIKI` first, else
|
|
246
|
+
* `$GENESEED_WIKI` first, else the wiki manifest beside the deployed bundle, read with the
|
|
231
247
|
* harness's generic JSONC loader.
|
|
232
248
|
*
|
|
233
249
|
* `resolvePath`, not merely `expanduser`: harmless here because `p` is consumed by `isFile`
|
|
@@ -236,7 +252,8 @@ function wikiPath(p) {
|
|
|
236
252
|
*/
|
|
237
253
|
function wikiManifest(state) {
|
|
238
254
|
const cand = process.env.GENESEED_WIKI;
|
|
239
|
-
const
|
|
255
|
+
const name = cand ? null : wikiName(state);
|
|
256
|
+
const p = cand ? wikiPath(cand) : name && path.join(state.target, name);
|
|
240
257
|
if (!p || !isFile(p)) return [];
|
|
241
258
|
const cfg = mcpLoad(p);
|
|
242
259
|
const wikis = cfg.wikis;
|
|
@@ -248,7 +265,7 @@ function wikiManifest(state) {
|
|
|
248
265
|
* unparseable, or not an object.
|
|
249
266
|
*
|
|
250
267
|
* Comment-tolerant is the whole point, and getting this wrong is silent: the two files it
|
|
251
|
-
* reads are `wiki.jsonc` and `context.json`, hand-maintained, so a `//` line is expected.
|
|
268
|
+
* reads are `geneseed-wiki.jsonc` and `context.json`, hand-maintained, so a `//` line is expected.
|
|
252
269
|
* Plain `JSON.parse` would throw on it and this loader would then answer `{}` — the wiki
|
|
253
270
|
* section listing nothing and the config item's `manifest` coming back empty, with no
|
|
254
271
|
* error surfaced anywhere.
|
|
@@ -389,7 +406,7 @@ export function resolveLinks(state, body) {
|
|
|
389
406
|
*/
|
|
390
407
|
function configManifest(name, p) {
|
|
391
408
|
const cfg = mcpLoad(p);
|
|
392
|
-
if (name
|
|
409
|
+
if (WIKI_NAMES.includes(name)) {
|
|
393
410
|
const wikis = cfg.wikis;
|
|
394
411
|
return { kind: 'wiki', wikis: Array.isArray(wikis) ? wikis : [] };
|
|
395
412
|
}
|
package/js/web/daemon.mjs
CHANGED
|
@@ -31,7 +31,7 @@ const ROOT = pathResolve(import.meta.dirname, '..', '..');
|
|
|
31
31
|
export function codeStamp(root = ROOT) {
|
|
32
32
|
const read = (rel) => { try { return readFileSync(join(root, rel)); } catch { return ''; } };
|
|
33
33
|
let version = 'unknown';
|
|
34
|
-
try { version = JSON.parse(read('package.json')).version ?? version; } catch { /* unknown */ }
|
|
34
|
+
try { version = JSON.parse(String(read('package.json'))).version ?? version; } catch { /* unknown */ }
|
|
35
35
|
const html = createHash('sha256').update(read(join('web', 'dist', 'index.html'))).digest('hex');
|
|
36
36
|
return `${version}:${html.slice(0, 12)}`;
|
|
37
37
|
}
|
|
@@ -161,6 +161,7 @@ export const none = (v) => (v === undefined || v === null ? 'None' : String(v));
|
|
|
161
161
|
*/
|
|
162
162
|
function spawnDetached(webArgs, log) {
|
|
163
163
|
const cmd = [process.execPath, join(ROOT, 'bin', 'geneseed-cli.mjs'), 'web', ...webArgs];
|
|
164
|
+
/** @type {'ignore' | number} */
|
|
164
165
|
let out = 'ignore';
|
|
165
166
|
try {
|
|
166
167
|
out = openSync(log, 'a');
|
package/js/web/routes.mjs
CHANGED
|
@@ -41,6 +41,7 @@ import { apiProfile, apiProfileSave, apiRules, apiRulesMutate, apiRulesPromote }
|
|
|
41
41
|
* `NotFound` is caught once, in `handler`, not per route — repeating the catch here would
|
|
42
42
|
* only duplicate it.
|
|
43
43
|
*/
|
|
44
|
+
/** @type {Map<string, [(state: any, body: any) => any, boolean]>} */
|
|
44
45
|
export const POST_ROUTES = new Map([
|
|
45
46
|
['/api/mcp', [apiMcpToggle, true]],
|
|
46
47
|
['/api/install', [apiInstallToggle, true]],
|
|
@@ -117,6 +118,7 @@ export function readJsonBody(buf) {
|
|
|
117
118
|
* `percentDecode` and not `decodeURIComponent`: the JS builtin throws a `URIError` on a `%`
|
|
118
119
|
* that is not an escape, where this shell instead answers a 404 naming the literal text.
|
|
119
120
|
*/
|
|
121
|
+
/** @type {Array<[string, (state: any, path: string) => any]>} */
|
|
120
122
|
export const PREFIX_ROUTES = [
|
|
121
123
|
['/api/catalog/', (state, p) => apiCatalog(state, p.split('/').pop())],
|
|
122
124
|
// /api/item/<type>/<name> — TYPE has no slash, the NAME keeps its slashes so a wiki
|
package/js/web/server.mjs
CHANGED
|
@@ -154,7 +154,7 @@ export async function serve({ theme = null, port = 4747, openBrowser = true,
|
|
|
154
154
|
srv.listen(port, '127.0.0.1', () => ready());
|
|
155
155
|
|
|
156
156
|
function ready() {
|
|
157
|
-
const hostPort = srv.address().port;
|
|
157
|
+
const hostPort = /** @type {import('node:net').AddressInfo} */ (srv.address()).port;
|
|
158
158
|
const url = `http://127.0.0.1:${hostPort}`;
|
|
159
159
|
if (daemon) {
|
|
160
160
|
writeDaemon(state.target, {
|
package/js/web/user-files.mjs
CHANGED
|
@@ -107,6 +107,7 @@ function parseRuleMeta(line) {
|
|
|
107
107
|
* Every rule carries its `start`/`end` LINE INDICES, which is what lets `apiRulesMutate`
|
|
108
108
|
* splice exactly one block and leave every other byte of the user's file — prose,
|
|
109
109
|
* formatting, hand-written sections — untouched.
|
|
110
|
+
* @returns {[Array<{id: number, start: number, end: number} & Record<string, any>>, string[]]}
|
|
110
111
|
*/
|
|
111
112
|
export function parseRules(text) {
|
|
112
113
|
const lines = splitLines(text);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"//": "Every field here is argued and gated in tests/unit/package_manifest.test.mjs. `files`, `bin` and `engines` each have a test that fails when reality drifts from this file; `version` mirrors harness.config.json and is gated too. Read that docblock before editing this one.",
|
|
3
3
|
"name": "geneseed",
|
|
4
|
-
"version": "3.
|
|
4
|
+
"version": "3.18.0",
|
|
5
5
|
"description": "A portable, theme-able harness you implant once and use everywhere to grow a disciplined AI coding agent.",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"ai",
|
|
@@ -54,11 +54,19 @@
|
|
|
54
54
|
"SHIPPED.md"
|
|
55
55
|
],
|
|
56
56
|
"devDependencies": {
|
|
57
|
+
"@commitlint/cli": "^21.2.3",
|
|
58
|
+
"@commitlint/config-conventional": "^21.2.3",
|
|
57
59
|
"@eslint/js": "^10.0.1",
|
|
60
|
+
"@stryker-mutator/core": "^10.0.0",
|
|
61
|
+
"@types/node": "^22.20.5",
|
|
62
|
+
"c8": "^12.0.0",
|
|
58
63
|
"eslint": "^10.9.0",
|
|
59
|
-
"
|
|
64
|
+
"fast-check": "^4.10.2",
|
|
65
|
+
"globals": "^17.11.0",
|
|
66
|
+
"typescript": "^5.9.3"
|
|
60
67
|
},
|
|
61
68
|
"scripts": {
|
|
62
|
-
"lint": "eslint js bin tests adapters"
|
|
69
|
+
"lint": "eslint js bin tests adapters fuzz",
|
|
70
|
+
"typecheck": "tsc -p ."
|
|
63
71
|
}
|
|
64
72
|
}
|
package/registry.json
CHANGED
|
@@ -141,25 +141,11 @@
|
|
|
141
141
|
"added": "2026-10-03",
|
|
142
142
|
"last_verified": ""
|
|
143
143
|
},
|
|
144
|
-
"skills/bruno
|
|
144
|
+
"skills/bruno": {
|
|
145
145
|
"status": "experimental",
|
|
146
146
|
"version": "1.0.0",
|
|
147
147
|
"owner": "Guillaume Lemer",
|
|
148
|
-
"added": "2026-
|
|
149
|
-
"last_verified": ""
|
|
150
|
-
},
|
|
151
|
-
"skills/bruno-test-writer": {
|
|
152
|
-
"status": "experimental",
|
|
153
|
-
"version": "1.0.0",
|
|
154
|
-
"owner": "Guillaume Lemer",
|
|
155
|
-
"added": "2026-09-03",
|
|
156
|
-
"last_verified": ""
|
|
157
|
-
},
|
|
158
|
-
"skills/ci-fix": {
|
|
159
|
-
"status": "experimental",
|
|
160
|
-
"version": "1.0.0",
|
|
161
|
-
"owner": "Guillaume Lemer",
|
|
162
|
-
"added": "2026-09-06",
|
|
148
|
+
"added": "2026-10-08",
|
|
163
149
|
"last_verified": ""
|
|
164
150
|
},
|
|
165
151
|
"skills/codebase-design": {
|
|
@@ -176,13 +162,6 @@
|
|
|
176
162
|
"added": "2026-06-01",
|
|
177
163
|
"last_verified": "2026-09-06"
|
|
178
164
|
},
|
|
179
|
-
"skills/consolidate-memory": {
|
|
180
|
-
"status": "experimental",
|
|
181
|
-
"version": "1.0.0",
|
|
182
|
-
"owner": "Guillaume Lemer",
|
|
183
|
-
"added": "2026-09-06",
|
|
184
|
-
"last_verified": ""
|
|
185
|
-
},
|
|
186
165
|
"skills/council": {
|
|
187
166
|
"status": "approved",
|
|
188
167
|
"version": "1.0.0",
|
|
@@ -204,11 +183,11 @@
|
|
|
204
183
|
"added": "2026-06-03",
|
|
205
184
|
"last_verified": "2026-09-06"
|
|
206
185
|
},
|
|
207
|
-
"skills/
|
|
186
|
+
"skills/dependencies": {
|
|
208
187
|
"status": "experimental",
|
|
209
188
|
"version": "1.0.0",
|
|
210
189
|
"owner": "Guillaume Lemer",
|
|
211
|
-
"added": "2026-
|
|
190
|
+
"added": "2026-10-08",
|
|
212
191
|
"last_verified": ""
|
|
213
192
|
},
|
|
214
193
|
"skills/develop": {
|
|
@@ -225,12 +204,12 @@
|
|
|
225
204
|
"added": "2026-06-10",
|
|
226
205
|
"last_verified": "2026-09-06"
|
|
227
206
|
},
|
|
228
|
-
"skills/
|
|
229
|
-
"status": "
|
|
207
|
+
"skills/explain-changes": {
|
|
208
|
+
"status": "experimental",
|
|
230
209
|
"version": "1.0.0",
|
|
231
210
|
"owner": "Guillaume Lemer",
|
|
232
|
-
"added": "2026-
|
|
233
|
-
"last_verified": "
|
|
211
|
+
"added": "2026-09-30",
|
|
212
|
+
"last_verified": ""
|
|
234
213
|
},
|
|
235
214
|
"skills/forge-mcp": {
|
|
236
215
|
"status": "approved",
|
|
@@ -267,19 +246,12 @@
|
|
|
267
246
|
"added": "2026-06-19",
|
|
268
247
|
"last_verified": "2026-09-06"
|
|
269
248
|
},
|
|
270
|
-
"skills/git-
|
|
271
|
-
"status": "
|
|
272
|
-
"version": "1.0.0",
|
|
273
|
-
"owner": "Guillaume Lemer",
|
|
274
|
-
"added": "2026-06-10",
|
|
275
|
-
"last_verified": "2026-09-06"
|
|
276
|
-
},
|
|
277
|
-
"skills/git-rescue": {
|
|
278
|
-
"status": "approved",
|
|
249
|
+
"skills/git-history": {
|
|
250
|
+
"status": "experimental",
|
|
279
251
|
"version": "1.0.0",
|
|
280
252
|
"owner": "Guillaume Lemer",
|
|
281
|
-
"added": "2026-
|
|
282
|
-
"last_verified": "
|
|
253
|
+
"added": "2026-10-08",
|
|
254
|
+
"last_verified": ""
|
|
283
255
|
},
|
|
284
256
|
"skills/handoff": {
|
|
285
257
|
"status": "approved",
|
|
@@ -316,20 +288,6 @@
|
|
|
316
288
|
"added": "2026-10-03",
|
|
317
289
|
"last_verified": ""
|
|
318
290
|
},
|
|
319
|
-
"skills/migrate": {
|
|
320
|
-
"status": "approved",
|
|
321
|
-
"version": "1.0.0",
|
|
322
|
-
"owner": "Guillaume Lemer",
|
|
323
|
-
"added": "2026-06-08",
|
|
324
|
-
"last_verified": "2026-09-06"
|
|
325
|
-
},
|
|
326
|
-
"skills/opencode-theme": {
|
|
327
|
-
"status": "approved",
|
|
328
|
-
"version": "1.0.0",
|
|
329
|
-
"owner": "Guillaume Lemer",
|
|
330
|
-
"added": "2026-06-19",
|
|
331
|
-
"last_verified": "2026-09-06"
|
|
332
|
-
},
|
|
333
291
|
"skills/parallel-agents": {
|
|
334
292
|
"status": "approved",
|
|
335
293
|
"version": "1.0.0",
|
|
@@ -407,13 +365,6 @@
|
|
|
407
365
|
"added": "2026-06-07",
|
|
408
366
|
"last_verified": "2026-09-06"
|
|
409
367
|
},
|
|
410
|
-
"skills/repo-map": {
|
|
411
|
-
"status": "approved",
|
|
412
|
-
"version": "1.0.0",
|
|
413
|
-
"owner": "Guillaume Lemer",
|
|
414
|
-
"added": "2026-06-01",
|
|
415
|
-
"last_verified": "2026-09-06"
|
|
416
|
-
},
|
|
417
368
|
"skills/research": {
|
|
418
369
|
"status": "approved",
|
|
419
370
|
"version": "1.0.0",
|
|
@@ -470,13 +421,6 @@
|
|
|
470
421
|
"added": "2026-09-06",
|
|
471
422
|
"last_verified": ""
|
|
472
423
|
},
|
|
473
|
-
"skills/tickets": {
|
|
474
|
-
"status": "approved",
|
|
475
|
-
"version": "1.0.0",
|
|
476
|
-
"owner": "Guillaume Lemer",
|
|
477
|
-
"added": "2026-07-13",
|
|
478
|
-
"last_verified": "2026-09-06"
|
|
479
|
-
},
|
|
480
424
|
"skills/token-report": {
|
|
481
425
|
"status": "experimental",
|
|
482
426
|
"version": "1.0.0",
|
|
@@ -484,13 +428,6 @@
|
|
|
484
428
|
"added": "2026-07-29",
|
|
485
429
|
"last_verified": ""
|
|
486
430
|
},
|
|
487
|
-
"skills/explain-changes": {
|
|
488
|
-
"status": "experimental",
|
|
489
|
-
"version": "1.0.0",
|
|
490
|
-
"owner": "Guillaume Lemer",
|
|
491
|
-
"added": "2026-09-30",
|
|
492
|
-
"last_verified": ""
|
|
493
|
-
},
|
|
494
431
|
"skills/wayfinder": {
|
|
495
432
|
"status": "approved",
|
|
496
433
|
"version": "1.0.0",
|
package/src/AGENT.md.tmpl
CHANGED
|
@@ -45,7 +45,7 @@ it as your very first tool call — before loading context, reading files, or se
|
|
|
45
45
|
skipped) and the `eager` entries of `context.json`. If no `=== SESSION FILES ===` or
|
|
46
46
|
`=== PROJECT CONTEXT ===` block is in your context, read them yourself first:
|
|
47
47
|
`{{AT_HARNESS}}user-rules.md`, `{{AT_HARNESS}}PROFILE.md`, `{{DIR_MEMORY}}/MEMORY.md`,
|
|
48
|
-
`{{DIR_NOTEBOOK}}/NOTEBOOK.md`, `{{AT_HARNESS}}wiki.jsonc`, `{{AT_HARNESS}}context.json`.
|
|
48
|
+
`{{DIR_NOTEBOOK}}/NOTEBOOK.md`, `{{AT_HARNESS}}geneseed-wiki.jsonc`, `{{AT_HARNESS}}context.json`.
|
|
49
49
|
|
|
50
50
|
**Response voice.** {{VOICE}} This sets *tone and vocabulary* — the section *layout*,
|
|
51
51
|
the law *numbers*, file paths, and folder names stay plain English so tooling and links
|
|
@@ -226,17 +226,14 @@ the ten council seats are convened by the [council {{SKILL}}]({{DIR_SKILLS}}/cou
|
|
|
226
226
|
| --- | --- |
|
|
227
227
|
| [brainstorm]({{DIR_SKILLS}}/brainstorm.md) | a new feature or project with no design yet, or whose goal, scope, or success criteria need pinning down first |
|
|
228
228
|
| [plan]({{DIR_SKILLS}}/plan.md) | a task has more than a couple of steps |
|
|
229
|
-
| [codebase-design]({{DIR_SKILLS}}/codebase-design.md) | designing a module's interface, placing a seam, or needing the deep-module vocabulary |
|
|
230
|
-
| [domain-modeling]({{DIR_SKILLS}}/domain-modeling.md) | pinning domain terminology in CONTEXT.md or recording an architectural decision as an ADR |
|
|
229
|
+
| [codebase-design]({{DIR_SKILLS}}/codebase-design.md) | designing a module's interface, placing a seam, or needing the deep-module vocabulary; pinning domain terms in GLOSSARY.md or recording a hard-to-reverse decision as an ADR |
|
|
231
230
|
| [wayfinder]({{DIR_SKILLS}}/wayfinder.md) | a chunk of work too big for one session, still in the fog — chart decision tickets before building |
|
|
232
|
-
| [tickets]({{DIR_SKILLS}}/tickets.md) | splitting a spec into tracker-ready tracer-bullet tickets with blocking edges |
|
|
233
231
|
| [parallel-agents]({{DIR_SKILLS}}/parallel-agents.md) | several independent subtasks and a tool that runs subagents |
|
|
234
232
|
| [develop]({{DIR_SKILLS}}/develop.md) | implementing a feature, fixing a bug, or changing behaviour — failing test first, affected suite green, one committed slice at a time |
|
|
235
233
|
| [worktree]({{DIR_SKILLS}}/worktree.md) | work must not share a tree with what is in flight — a crew, a second task, another session in this checkout |
|
|
236
|
-
| [debug]({{DIR_SKILLS}}/debug.md) | a bug or failure to diagnose before fixing |
|
|
234
|
+
| [debug]({{DIR_SKILLS}}/debug.md) | a bug or failure to diagnose before fixing — a red CI run or pre-merge check included, reproduced under CI's conditions |
|
|
237
235
|
| [prototype]({{DIR_SKILLS}}/prototype.md) | a design question needs a runnable answer before real implementation |
|
|
238
|
-
| [
|
|
239
|
-
| [document-project]({{DIR_SKILLS}}/document-project.md) | missing/drifted docs, or a PRD, design system, architecture doc or AGENTS.md |
|
|
236
|
+
| [document-project]({{DIR_SKILLS}}/document-project.md) | missing/drifted docs, or a PRD, design system, architecture doc or AGENTS.md; orienting to the repo, or refreshing its map after the structure changed |
|
|
240
237
|
| [ingest]({{DIR_SKILLS}}/ingest.md) | a task needs content from a PDF, Office doc, or URL |
|
|
241
238
|
| [research]({{DIR_SKILLS}}/research.md) | a question needs answers gathered and verified from the open web |
|
|
242
239
|
| [teach]({{DIR_SKILLS}}/teach.md) | the user wants to be taught — a crash course, confusing material decoded, or a day-by-day path to a deadline |
|
|
@@ -247,18 +244,14 @@ the ten council seats are convened by the [council {{SKILL}}]({{DIR_SKILLS}}/cou
|
|
|
247
244
|
| [review-response]({{DIR_SKILLS}}/review-response.md) | acting on review feedback you have received |
|
|
248
245
|
| [fresh-eyes]({{DIR_SKILLS}}/fresh-eyes.md) | a finished artifact needs an independent verdict on whether it meets the original spec, from an agent with none of the solving session's context |
|
|
249
246
|
| [security-audit]({{DIR_SKILLS}}/security-audit.md) | a change touches the security surface — auth, untrusted input, secrets, shell or file access, a new dependency — or "is this safe" |
|
|
250
|
-
| [
|
|
251
|
-
| [deps-audit]({{DIR_SKILLS}}/deps-audit.md) | deciding which dependencies to upgrade, remove, or refuse — outdated, vulnerable, abandoned, unused |
|
|
247
|
+
| [dependencies]({{DIR_SKILLS}}/dependencies.md) | auditing dependencies — outdated, vulnerable, abandoned, unused — or upgrading a dependency, framework, or language version one change at a time |
|
|
252
248
|
| [ship]({{DIR_SKILLS}}/ship.md) | a verified change is ready to open as a PR or merge |
|
|
253
249
|
| [release]({{DIR_SKILLS}}/release.md) | cutting a version: bump, changelog, tag |
|
|
254
|
-
| [
|
|
255
|
-
| [git-archaeology]({{DIR_SKILLS}}/git-archaeology.md) | finding when a regression landed or why code exists — bisect, blame, pickaxe |
|
|
256
|
-
| [git-rescue]({{DIR_SKILLS}}/git-rescue.md) | recovering a broken or messy repo, or safely rewriting history — reflog, undo, rebase behind a backup |
|
|
250
|
+
| [git-history]({{DIR_SKILLS}}/git-history.md) | finding when a regression landed or why code exists — bisect, blame, pickaxe — or recovering a broken repo and safely rewriting history behind a backup branch |
|
|
257
251
|
| [refactor]({{DIR_SKILLS}}/refactor.md) | improving code structure without changing behaviour |
|
|
258
252
|
| [ponytail]({{DIR_SKILLS}}/ponytail.md) | the user wants the minimal, laziest-that-works solution — "ponytail", "be lazy", "simplest path", or a complaint about over-engineering, bloat, or needless dependencies |
|
|
259
253
|
| [forge-mcp]({{DIR_SKILLS}}/forge-mcp.md) | building, extending, or hardening a Model Context Protocol (MCP) server |
|
|
260
|
-
| [bruno
|
|
261
|
-
| [bruno-test-writer]({{DIR_SKILLS}}/bruno-test-writer.md) | writing or strengthening Bruno tests, assertions, scripts, and request chaining for a request or collection |
|
|
254
|
+
| [bruno]({{DIR_SKILLS}}/bruno.md) | creating, converting, or testing a Bruno API collection — requests, environments, assertions, chaining — from routes, OpenAPI, curl, or an endpoint list |
|
|
262
255
|
| [prose]({{DIR_SKILLS}}/prose.md) | writing prose for a human — a commit body, PR, doc, comment, memory note, or reply — that should not read like a model wrote it |
|
|
263
256
|
| [frontend-design]({{DIR_SKILLS}}/frontend-design.md) | building or reshaping a UI that should carry a deliberate point of view, not a templated default |
|
|
264
257
|
| [handoff]({{DIR_SKILLS}}/handoff.md) | context filling, or passing work to another agent or session |
|
|
@@ -268,14 +261,12 @@ the ten council seats are convened by the [council {{SKILL}}]({{DIR_SKILLS}}/cou
|
|
|
268
261
|
| [pipeline]({{DIR_SKILLS}}/pipeline.md) | foreman mode triages a substantial task, or the user asks to run a crew (analyst → developer → tester) on one, isolated in its own worktree and merged on mechanical proof |
|
|
269
262
|
| [loop]({{DIR_SKILLS}}/loop.md) | the user asks to run a loop |
|
|
270
263
|
| [brick-forge]({{DIR_SKILLS}}/brick-forge.md) | a new or adapted loop brick |
|
|
271
|
-
| [wiki]({{DIR_SKILLS}}/wiki.md) | consulting or growing the user's machine-wide knowledge base declared in `wiki.jsonc` (§8) |
|
|
264
|
+
| [wiki]({{DIR_SKILLS}}/wiki.md) | consulting or growing the user's machine-wide knowledge base declared in `geneseed-wiki.jsonc` (§8) |
|
|
272
265
|
| [herdr]({{DIR_SKILLS}}/herdr.md) | running inside a [herdr](https://herdr.dev) pane (`HERDR_ENV=1`) and a task needs another pane — a sibling server, a watched build, a spawned agent |
|
|
273
|
-
| [rule]({{DIR_SKILLS}}/rule.md) | anything the user wants to outlive this session — a standing rule of their own (§1) or a durable fact to remember (§5); also
|
|
266
|
+
| [rule]({{DIR_SKILLS}}/rule.md) | anything the user wants to outlive this session — a standing rule of their own (§1) or a durable fact to remember (§5); also tending the {{MEMORY}} set — duplicates, stale facts, a recurring lesson due for promotion |
|
|
274
267
|
| [profile]({{DIR_SKILLS}}/profile.md) | the user wants the agent to know who they are — creating or refreshing the `PROFILE.md` identity file (§1) through a short interview |
|
|
275
|
-
| [consolidate-memory]({{DIR_SKILLS}}/consolidate-memory.md) | the {{MEMORY}} set needs tending — an overgrown index, duplicates, stale facts, a lesson due for promotion |
|
|
276
268
|
| [skill-forge]({{DIR_SKILLS}}/skill-forge.md) | a repeated task has no {{SKILL}}, a self-improvement loop produced an edit, or two {{SKILLS}} should merge |
|
|
277
|
-
| [geneseed]({{DIR_SKILLS}}/geneseed.md) | the user mentions Geneseed, the harness, or `AGENT.md`, or you need to inspect or read from the deployed bundle ({{LAWS}}, {{AGENTS}}, {{SKILLS}}, {{MEMORY}}) |
|
|
278
|
-
| [opencode-theme]({{DIR_SKILLS}}/opencode-theme.md) | the user wants their own OpenCode colour theme — pick or tweak a palette, get solid + transparent variants that survive rebuilds |
|
|
269
|
+
| [geneseed]({{DIR_SKILLS}}/geneseed.md) | the user mentions Geneseed, the harness, or `AGENT.md`, wants their own OpenCode colour theme, or you need to inspect or read from the deployed bundle ({{LAWS}}, {{AGENTS}}, {{SKILLS}}, {{MEMORY}}) |
|
|
279
270
|
|
|
280
271
|
**Folder {{SKILLS}}.** Some {{SKILLS}} ship as self-contained folders under
|
|
281
272
|
`{{DIR_SKILLS}}/`, each with its own format and provenance (`VENDOR.md`) —
|
|
@@ -283,7 +274,7 @@ third-party vendors plus first-party ones bundling scripts. Reach for one only w
|
|
|
283
274
|
its domain comes up:
|
|
284
275
|
- [react-view-transitions]({{DIR_SKILLS}}/react-view-transitions/SKILL.md) — animating
|
|
285
276
|
React UIs with the View Transition API (`<ViewTransition>`, shared elements, Next.js).
|
|
286
|
-
- [daydream]({{DIR_SKILLS}}/daydream/SKILL.md) — mining the `wiki.jsonc` vault (§8) for
|
|
277
|
+
- [daydream]({{DIR_SKILLS}}/daydream/SKILL.md) — mining the `geneseed-wiki.jsonc` vault (§8) for
|
|
287
278
|
non-obvious connections between notes via parallel synthesis + critique.
|
|
288
279
|
- [token-report]({{DIR_SKILLS}}/token-report/SKILL.md) — session token usage breakdown
|
|
289
280
|
tables: context baseline, growth, per-tool attribution.
|
|
@@ -416,7 +407,7 @@ It receives only the task's deliverables; your working files go in the {{NOTEBOO
|
|
|
416
407
|
*{{EPI_WIKI}}*
|
|
417
408
|
|
|
418
409
|
<!-- LEAN:begin -->
|
|
419
|
-
{{INTRO_WIKI}} It is declared in `{{AT_HARNESS}}wiki.jsonc`, a session file — or
|
|
410
|
+
{{INTRO_WIKI}} It is declared in `{{AT_HARNESS}}geneseed-wiki.jsonc`, a session file — or
|
|
420
411
|
wherever `$GENESEED_WIKI` points. An empty `wikis` list means none is declared and this
|
|
421
412
|
section stays dormant. (On OpenCode its `eager` entries are loaded for you.)
|
|
422
413
|
|
|
@@ -443,7 +434,7 @@ durable fact worth sharing across projects goes here via the
|
|
|
443
434
|
[wiki]({{DIR_SKILLS}}/wiki.md) {{SKILL}}; one that matters only to you stays in
|
|
444
435
|
{{MEMORY}} (§5).
|
|
445
436
|
<!-- LEAN:else -->
|
|
446
|
-
{{INTRO_WIKI}} Declared in `{{AT_HARNESS}}wiki.jsonc`, a session file (or at
|
|
437
|
+
{{INTRO_WIKI}} Declared in `{{AT_HARNESS}}geneseed-wiki.jsonc`, a session file (or at
|
|
447
438
|
`$GENESEED_WIKI`; an empty `wikis` list means dormant) — honour each wiki: load `entries` by `load` mode as in `context.json` (§9), read
|
|
448
439
|
`conventions` before your first write there, drop an unplaceable note in `inbox`,
|
|
449
440
|
never write inside `protected`. It is the user's: wikilinks over bare paths, every
|
package/src/agents/docs.md
CHANGED
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
3. Keep examples runnable; update any example that the change broke.
|
|
27
27
|
4. Write each page in the format it is already in — Markdown or AsciiDoc; never convert one.
|
|
28
28
|
A new page follows the `Docs format:` line in the root `AGENTS.md`, else the format the
|
|
29
|
-
project's docs already use (
|
|
29
|
+
project's docs already use (Markdown when it has none yet; AsciiDoc only on request). Agent-runtime files —
|
|
30
30
|
`AGENTS.md`, `CLAUDE.md`, specs, ADRs loops read — stay Markdown. In AsciiDoc, never add
|
|
31
31
|
an `include::` to a page agents read.
|
|
32
32
|
|
package/src/agents/researcher.md
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
findings, not the pages ({{DOCTRINE:context-economy}}).
|
|
9
9
|
- The research {{SKILL}} is running and the host can run subagents: this seat
|
|
10
10
|
does the fetching and cross-checking so the main context stays small.
|
|
11
|
-
- A
|
|
11
|
+
- A dependencies, forge-mcp, or ingest run needs a spec or changelog read before
|
|
12
12
|
deciding.
|
|
13
13
|
|
|
14
14
|
## When NOT to dispatch
|
package/src/bricks/bruno-test.md
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
name: bruno-test
|
|
3
3
|
description: Write or update Bruno requests for the endpoints this iteration touched.
|
|
4
4
|
effect: mutate
|
|
5
|
-
skill: bruno
|
|
5
|
+
skill: bruno
|
|
6
6
|
outcomes: pass, fail
|
|
7
7
|
---
|
|
8
|
-
Follow the bruno
|
|
8
|
+
Follow the bruno skill for every endpoint this iteration's diff added or changed.
|
|
9
9
|
Touch only the Bruno collection — new or updated `.bru` requests and their expectations — never
|
|
10
10
|
the application code.
|
|
11
11
|
|
package/src/bricks/ci-fix.md
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
name: ci-fix
|
|
3
3
|
description: Fix the failing CI check named in the card.
|
|
4
4
|
effect: mutate
|
|
5
|
-
skill:
|
|
5
|
+
skill: debug
|
|
6
6
|
outcomes: pass, fail
|
|
7
7
|
---
|
|
8
|
-
Follow the
|
|
9
|
-
guess from the check's title, before changing anything.
|
|
8
|
+
Follow the debug skill's CI branch against the failing check the card names — read its actual
|
|
9
|
+
log, not a guess from the check's title, before changing anything.
|
|
10
10
|
|
|
11
11
|
Touch only what that failure requires; this is a repair, not a chance to improve the pipeline
|
|
12
12
|
along the way.
|
package/src/bricks/deps-audit.md
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
name: deps-audit
|
|
3
3
|
description: Audit this iteration's dependency changes for known vulnerabilities.
|
|
4
4
|
effect: read
|
|
5
|
-
skill:
|
|
5
|
+
skill: dependencies
|
|
6
6
|
outcomes: pass, fail
|
|
7
7
|
---
|
|
8
|
-
Follow the
|
|
9
|
-
whole manifest, if nothing else scopes it). Never edit any file; this brick only observes.
|
|
8
|
+
Follow the dependencies skill's audit against the dependency manifest this iteration's diff
|
|
9
|
+
touched (or the whole manifest, if nothing else scopes it). Never edit any file; this brick only observes.
|
|
10
10
|
|
|
11
11
|
Report `pass` if the audit finds nothing at high severity or above.
|
|
12
12
|
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
name: migration-plan
|
|
3
3
|
description: Plan a breaking interface change as expand, migrate each consumer, contract — for the user to review.
|
|
4
4
|
effect: read
|
|
5
|
-
skill:
|
|
5
|
+
skill: dependencies
|
|
6
6
|
gate: human
|
|
7
7
|
outcomes: pass, fail
|
|
8
8
|
---
|
|
9
|
-
Following the
|
|
9
|
+
Following the dependencies skill, plan the change as ordered steps: expand (add the new shape beside
|
|
10
10
|
the old), migrate (one consumer or call-site group per step), contract (remove the old shape).
|
|
11
11
|
Every step must leave the system deployable and fit one `identify` card. Name the contract files
|
|
12
12
|
the expand and contract steps touch — API specs, schema migrations, event schemas. Never edit any
|