wendkeep 0.18.0 → 0.20.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +52 -0
- package/package.json +1 -1
- package/src/init.mjs +3 -3
- package/src/skills-seed.mjs +207 -14
- package/src/taxonomy.mjs +13 -0
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,58 @@ All notable changes to **wendkeep** are documented here. Format based on
|
|
|
4
4
|
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/); this project follows
|
|
5
5
|
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
+
## [0.20.1] — 2026-07-06
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
- The interactive (and text-fallback) companion picker in `wendkeep init` **no longer lists
|
|
11
|
+
dotcontext**. The native a2 loop replaces it, so leaving it in the prompt was just clutter. It
|
|
12
|
+
stays reachable for anyone already invested via an explicit `--companions dotcontext` — the
|
|
13
|
+
hiding is UI-only (`resolveCompanions` still honors the id). New `selectableCompanions()` helper
|
|
14
|
+
drives the picker.
|
|
15
|
+
|
|
16
|
+
## [0.20.0] — 2026-07-06
|
|
17
|
+
|
|
18
|
+
Richer skills: bundled templates (multi-file).
|
|
19
|
+
|
|
20
|
+
### Added
|
|
21
|
+
- The process skills now ship **bundled templates** next to their `SKILL.md`, delivered together
|
|
22
|
+
by `sync-defs` (the whole skill folder is copied) and auto-delivered by `init`. The model reads
|
|
23
|
+
them on demand — depth without bloating `SKILL.md`:
|
|
24
|
+
- **wk-verify** → `spec-reviewer-prompt.md` (the prompt to hand a fresh read-only verifier
|
|
25
|
+
sub-agent) + `verdict-template.json` (the exact `verdict.json` shape).
|
|
26
|
+
- **wk-planning** → `plan-template.md` (file map + bite-sized TDD task structure).
|
|
27
|
+
- **wk-brainstorming** → `design-template.md` (context, approaches, signed-off assumptions,
|
|
28
|
+
out-of-scope table, acceptance).
|
|
29
|
+
- pt-BR and en variants; the prose templates follow the vault locale, the JSON is shared.
|
|
30
|
+
|
|
31
|
+
### Notes
|
|
32
|
+
- Subagents stay the **native harness's** job. wendkeep ships the verifier **prompt** (the agent
|
|
33
|
+
spawns a read-only sub-agent via its own Task/Agent tool) and captures subagent telemetry — it
|
|
34
|
+
does not orchestrate spawning. So the reviewer is a template, not a Claude-only
|
|
35
|
+
`.claude/agents/*.md`, which keeps it agent-agnostic.
|
|
36
|
+
|
|
37
|
+
### Upgrade
|
|
38
|
+
- `npm update wendkeep`, then `wendkeep init` (or `wendkeep sync-defs`) to get the templates
|
|
39
|
+
alongside your existing skills. Non-destructive — existing `SKILL.md` files are never overwritten.
|
|
40
|
+
|
|
41
|
+
## [0.19.0] — 2026-07-06
|
|
42
|
+
|
|
43
|
+
Fix: memory + active-change injection wired by default.
|
|
44
|
+
|
|
45
|
+
### Fixed
|
|
46
|
+
- `wendkeep init` now wires the **`brain-inject`** hook into SessionStart (ordered *before*
|
|
47
|
+
`session-start`), so every session gets `<brain_memory>` injected: CORE + DIGEST + the
|
|
48
|
+
**active change** (proposal + open tasks) + project lessons. Previously the default hook set was
|
|
49
|
+
only `session-start` / `session-stop` / `session-ensure` — the memory/change injector existed
|
|
50
|
+
(`wendkeep hook brain-inject`) but wasn't wired, so the "the change is injected at the next
|
|
51
|
+
SessionStart" promise (the `wk-workflow` skill and the README) didn't actually hold on a fresh
|
|
52
|
+
install. matcher `startup|clear|compact` re-injects after a compaction or clear, not only on a
|
|
53
|
+
cold startup.
|
|
54
|
+
|
|
55
|
+
### Upgrade
|
|
56
|
+
- Existing installs pick it up by re-running `wendkeep init --force` (idempotent — it only adds the
|
|
57
|
+
missing hook), or by adding `npx wendkeep hook brain-inject` to the SessionStart hooks manually.
|
|
58
|
+
|
|
7
59
|
## [0.18.0] — 2026-07-06
|
|
8
60
|
|
|
9
61
|
Session identity in the note.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wendkeep",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.20.1",
|
|
4
4
|
"description": "A persistent-memory harness for AI coding agents on your Obsidian vault: turn-by-turn session capture plus a native, zero-dependency spec→change→verify→archive loop (sensor-gated, independent verdict, mutation discrimination). Local-first, agent-agnostic (Claude Code, Codex, Cursor…).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
package/src/init.mjs
CHANGED
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
mcpServerEntry,
|
|
14
14
|
hookCommand,
|
|
15
15
|
deriveVaultDirName,
|
|
16
|
-
|
|
16
|
+
selectableCompanions,
|
|
17
17
|
resolveCompanions,
|
|
18
18
|
companionSettingsPatch,
|
|
19
19
|
companionMcpPatch,
|
|
@@ -260,11 +260,11 @@ export async function runInit(argv) {
|
|
|
260
260
|
} else if (process.stdin.isTTY && !args.yes) {
|
|
261
261
|
if (canInteractiveSelect()) {
|
|
262
262
|
log(''); // the checkbox menu renders its own header
|
|
263
|
-
companions = await selectCompanionsInteractive(
|
|
263
|
+
companions = await selectCompanionsInteractive(selectableCompanions(), { labels: P.menu });
|
|
264
264
|
} else {
|
|
265
265
|
// Text fallback (no raw-mode TTY): list + comma input with clear instructions.
|
|
266
266
|
log(P.companionsHeader);
|
|
267
|
-
for (const c of
|
|
267
|
+
for (const c of selectableCompanions()) log(` ${c.default ? '[x]' : '[ ]'} ${c.label}`);
|
|
268
268
|
const def = resolveCompanions({}).join(',');
|
|
269
269
|
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
270
270
|
const ans = (await rl.question(P.companionsAsk(def))).trim();
|
package/src/skills-seed.mjs
CHANGED
|
@@ -4,8 +4,11 @@
|
|
|
4
4
|
import { existsSync, mkdirSync, writeFileSync } from 'node:fs';
|
|
5
5
|
import { join } from 'node:path';
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
// A skill is a SKILL.md plus optional bundled files (templates/prompts) that ship in the same
|
|
8
|
+
// folder and are delivered together by `wendkeep sync-defs` (cpSync of the whole dir). The
|
|
9
|
+
// SKILL.md references them; the model reads them on demand — depth without bloating SKILL.md.
|
|
10
|
+
function skill(name, description, body, files = []) {
|
|
11
|
+
return { name, description, body: `---\nname: ${name}\ndescription: ${description}\n---\n${body}`, files };
|
|
9
12
|
}
|
|
10
13
|
|
|
11
14
|
const WORKFLOW = `# Loop a2 — o ciclo de trabalho do wendkeep
|
|
@@ -144,6 +147,10 @@ precisar de design" é onde suposições não-checadas mais custam. O design pod
|
|
|
144
147
|
mas tem que existir e ser aprovado.
|
|
145
148
|
|
|
146
149
|
Ao aprovar, o próximo passo é **wk-planning** (design → plano). Não pule pra implementação.
|
|
150
|
+
|
|
151
|
+
## Template
|
|
152
|
+
Use o \`design-template.md\` (nesta pasta da skill) pra estruturar o design (contexto, abordagens,
|
|
153
|
+
decisões assinadas, tabela out-of-scope, aceite).
|
|
147
154
|
`;
|
|
148
155
|
|
|
149
156
|
const PLANNING = `# Planejamento — design vira plano de tarefas
|
|
@@ -174,6 +181,9 @@ de 2–5 min:
|
|
|
174
181
|
"tratar erros apropriadamente", "similar à Task N".
|
|
175
182
|
- DRY, YAGNI. Corte features que o design não pediu.
|
|
176
183
|
- Nomes/assinaturas consistentes entre tarefas (uma função é \`x()\` em toda parte).
|
|
184
|
+
|
|
185
|
+
## Template
|
|
186
|
+
Comece do \`plan-template.md\` (nesta pasta da skill) — a estrutura de arquivos + tarefas TDD.
|
|
177
187
|
`;
|
|
178
188
|
|
|
179
189
|
const VERIFY = `# Verificação independente — o passe fresco
|
|
@@ -201,6 +211,10 @@ nunca tivesse visto a implementação. Contexto fresco, read-only.
|
|
|
201
211
|
- \`ok: false\` se algum requisito não tem cobertura que discrimina. Gap não é "quase lá" — é vermelho.
|
|
202
212
|
- Não conserte aqui. Gap vira tarefa de correção na change; re-verifica depois.
|
|
203
213
|
- O gate do \`archive\` **exige** \`verdict.json\` com \`ok\` cobrindo todo \`[req:]\`. Sem isso, não arquiva.
|
|
214
|
+
|
|
215
|
+
## Templates (nesta pasta)
|
|
216
|
+
- \`spec-reviewer-prompt.md\` — cole ao spawnar o subagente verificador (read-only, autor≠verificador).
|
|
217
|
+
- \`verdict-template.json\` — o formato exato do \`verdict.json\` a gravar.
|
|
204
218
|
`;
|
|
205
219
|
|
|
206
220
|
const WORKFLOW_EN = `# The a2 loop — wendkeep's work cycle
|
|
@@ -291,6 +305,10 @@ List explicitly what the change does **not** do. Undeclared scope becomes creep.
|
|
|
291
305
|
## Hard gate
|
|
292
306
|
No code / scaffold / implementation action until a design is presented and approved. Then go to
|
|
293
307
|
**wk-planning**.
|
|
308
|
+
|
|
309
|
+
## Template
|
|
310
|
+
Use \`design-template.md\` (in this skill folder) to structure the design (context, approaches,
|
|
311
|
+
signed-off decisions, out-of-scope table, acceptance).
|
|
294
312
|
`;
|
|
295
313
|
|
|
296
314
|
const PLANNING_EN = `# Planning — design into a task plan
|
|
@@ -309,6 +327,9 @@ implementation (show code) → run and see it pass → checkpoint: suite green.
|
|
|
309
327
|
## Rules
|
|
310
328
|
- Exact file paths, always. Real code in each step — no "TODO", "handle errors appropriately",
|
|
311
329
|
"similar to Task N". DRY, YAGNI. Consistent names/signatures across tasks.
|
|
330
|
+
|
|
331
|
+
## Template
|
|
332
|
+
Start from \`plan-template.md\` (in this skill folder) — the file map + TDD task structure.
|
|
312
333
|
`;
|
|
313
334
|
|
|
314
335
|
const VERIFY_EN = `# Independent verification — the fresh pass
|
|
@@ -329,24 +350,190 @@ the author — even if you wrote the code, enter as if you'd never seen it. Fres
|
|
|
329
350
|
- \`ok: false\` if any requirement lacks discriminating coverage. A gap is red, not "almost".
|
|
330
351
|
- Don't fix here — a gap becomes a fix task; re-verify after.
|
|
331
352
|
- The archive gate **requires** a fresh \`verdict.json\` (matching \`tasksHash\`) covering every \`[req:]\`.
|
|
353
|
+
|
|
354
|
+
## Templates (in this folder)
|
|
355
|
+
- \`spec-reviewer-prompt.md\` — hand it to the verifier sub-agent you spawn (read-only, author≠verifier).
|
|
356
|
+
- \`verdict-template.json\` — the exact shape of the \`verdict.json\` to write.
|
|
357
|
+
`;
|
|
358
|
+
|
|
359
|
+
// --- bundled templates (shipped alongside the relevant SKILL.md) -------------
|
|
360
|
+
|
|
361
|
+
// Shared, language-neutral verdict skeleton for the independent verify pass.
|
|
362
|
+
const VERDICT_TEMPLATE = `{
|
|
363
|
+
"slug": "<change-slug>",
|
|
364
|
+
"ok": true,
|
|
365
|
+
"coverage": [
|
|
366
|
+
{ "req": "GATE-1", "covered": true, "evidence": "tests/foo.test.mjs:42" }
|
|
367
|
+
],
|
|
368
|
+
"tasksHash": "<copie de verificacao.json — selo de frescor / copy from verificacao.json — freshness seal>",
|
|
369
|
+
"notes": []
|
|
370
|
+
}
|
|
371
|
+
`;
|
|
372
|
+
|
|
373
|
+
const REVIEWER_PROMPT_PT = `# Prompt — passe de verificação independente (read-only)
|
|
374
|
+
|
|
375
|
+
Entregue este prompt ao spawnar o subagente verificador (via o harness nativo — Task/Agent no
|
|
376
|
+
Claude). Ele NÃO é o autor: entra fresco, read-only, não edita nada.
|
|
377
|
+
|
|
378
|
+
---
|
|
379
|
+
Você é o verificador independente de uma mudança do wendkeep. Não escreveu este código —
|
|
380
|
+
entre como se nunca o tivesse visto. Read-only.
|
|
381
|
+
|
|
382
|
+
Leia o pacote \`08-Mudanças/<slug>/verificacao.json\` (requisitos, tarefas, evidência) e os
|
|
383
|
+
specs vivos em \`07-Specs/<capability>.md\`.
|
|
384
|
+
|
|
385
|
+
Para cada \`[req:ID]\` da mudança:
|
|
386
|
+
1. Leia o **critério de aceite do requisito** no spec — NÃO leia a implementação primeiro.
|
|
387
|
+
2. Ache o teste que cobre esse comportamento. Ele **discrimina**? (falharia sob uma
|
|
388
|
+
implementação errada; afirma valor/estado persistido, não "o mock foi chamado").
|
|
389
|
+
3. Evidência \`arquivo:linha\`. Sem teste que discrimina = \`covered: false\` (é vermelho, não "quase").
|
|
390
|
+
4. Cheque o resultado observável contra o critério — não contra o código.
|
|
391
|
+
|
|
392
|
+
Grave \`08-Mudanças/<slug>/verdict.json\` no formato de \`verdict-template.json\`. \`ok: false\` se
|
|
393
|
+
qualquer \`[req:]\` não tem cobertura que discrimina. Não conserte aqui — gap vira tarefa de
|
|
394
|
+
correção. O \`tasksHash\` vem do pacote (selo de frescor; alterou tarefa depois, o gate rejeita).
|
|
395
|
+
---
|
|
396
|
+
`;
|
|
397
|
+
|
|
398
|
+
const REVIEWER_PROMPT_EN = `# Prompt — independent verification pass (read-only)
|
|
399
|
+
|
|
400
|
+
Hand this to the verifier sub-agent you spawn (via the native harness — Task/Agent on Claude).
|
|
401
|
+
It is NOT the author: fresh context, read-only, edits nothing.
|
|
402
|
+
|
|
403
|
+
---
|
|
404
|
+
You are the independent verifier of a wendkeep change. You did not write this code — enter as if
|
|
405
|
+
you'd never seen it. Read-only.
|
|
406
|
+
|
|
407
|
+
Read the package \`08-Changes/<slug>/verificacao.json\` (requirements, tasks, evidence) and the
|
|
408
|
+
living specs in \`07-Specs/<capability>.md\`.
|
|
409
|
+
|
|
410
|
+
For each \`[req:ID]\`:
|
|
411
|
+
1. Read the requirement's **acceptance criterion** in the spec — do NOT read the implementation first.
|
|
412
|
+
2. Find the test covering that behaviour. Does it **discriminate**? (would fail under a wrong
|
|
413
|
+
implementation; asserts a persisted value/state, not "the mock was called").
|
|
414
|
+
3. \`file:line\` evidence. No discriminating test = \`covered: false\` (red, not "almost").
|
|
415
|
+
4. Check the observable result against the criterion — not the code.
|
|
416
|
+
|
|
417
|
+
Write \`08-Changes/<slug>/verdict.json\` in the shape of \`verdict-template.json\`. \`ok: false\` if any
|
|
418
|
+
\`[req:]\` lacks discriminating coverage. Don't fix here — a gap becomes a fix task. \`tasksHash\`
|
|
419
|
+
comes from the package (freshness seal; edit a task later and the gate rejects it as stale).
|
|
420
|
+
---
|
|
421
|
+
`;
|
|
422
|
+
|
|
423
|
+
const PLAN_TEMPLATE_PT = `# Template — plano de tarefas (TDD, bite-sized)
|
|
424
|
+
|
|
425
|
+
## Arquivos
|
|
426
|
+
- Criar: \`caminho/exato.mjs\`
|
|
427
|
+
- Modificar: \`caminho/existente.mjs:120-140\`
|
|
428
|
+
- Teste: \`tests/exato.test.mjs\`
|
|
429
|
+
|
|
430
|
+
## Tarefa N — <nome>
|
|
431
|
+
- **Consome:** <o que usa de tarefas anteriores — assinaturas exatas>
|
|
432
|
+
- **Produz:** <o que tarefas seguintes usam — nomes/tipos exatos>
|
|
433
|
+
|
|
434
|
+
- [ ] N.1 escreva o teste que falha (mostre o código do teste) \`[req:<ID>]\`
|
|
435
|
+
- [ ] N.2 rode e veja falhar — pelo motivo certo (comando exato + saída esperada)
|
|
436
|
+
- [ ] N.3 implementação mínima (mostre o código) \`[sensor:<id>]\` se precisa de prova
|
|
437
|
+
- [ ] N.4 rode e veja passar
|
|
438
|
+
- [ ] N.5 checkpoint: suíte verde · commit
|
|
439
|
+
|
|
440
|
+
## Regras
|
|
441
|
+
Caminhos exatos sempre. Código real em cada passo — nada de "TODO" / "tratar erros
|
|
442
|
+
apropriadamente" / "similar à Tarefa N". DRY, YAGNI. Nomes e assinaturas consistentes entre
|
|
443
|
+
tarefas (uma função é \`x()\` em toda parte). Cada tarefa termina num entregável testável sozinho.
|
|
444
|
+
`;
|
|
445
|
+
|
|
446
|
+
const PLAN_TEMPLATE_EN = `# Template — task plan (TDD, bite-sized)
|
|
447
|
+
|
|
448
|
+
## Files
|
|
449
|
+
- Create: \`exact/path.mjs\`
|
|
450
|
+
- Modify: \`exact/existing.mjs:120-140\`
|
|
451
|
+
- Test: \`tests/exact.test.mjs\`
|
|
452
|
+
|
|
453
|
+
## Task N — <name>
|
|
454
|
+
- **Consumes:** <what it uses from earlier tasks — exact signatures>
|
|
455
|
+
- **Produces:** <what later tasks rely on — exact names/types>
|
|
456
|
+
|
|
457
|
+
- [ ] N.1 write the failing test (show the test code) \`[req:<ID>]\`
|
|
458
|
+
- [ ] N.2 run and see it fail — for the right reason (exact command + expected output)
|
|
459
|
+
- [ ] N.3 minimal implementation (show the code) \`[sensor:<id>]\` if it needs proof
|
|
460
|
+
- [ ] N.4 run and see it pass
|
|
461
|
+
- [ ] N.5 checkpoint: suite green · commit
|
|
462
|
+
|
|
463
|
+
## Rules
|
|
464
|
+
Exact paths always. Real code in every step — no "TODO" / "handle errors appropriately" /
|
|
465
|
+
"similar to Task N". DRY, YAGNI. Consistent names/signatures across tasks. Each task ends in an
|
|
466
|
+
independently testable deliverable.
|
|
467
|
+
`;
|
|
468
|
+
|
|
469
|
+
const DESIGN_TEMPLATE_PT = `# Template — documento de design
|
|
470
|
+
|
|
471
|
+
## Contexto
|
|
472
|
+
<o problema, o estado atual, por que agora>
|
|
473
|
+
|
|
474
|
+
## Abordagens consideradas
|
|
475
|
+
1. **<A>** — <trade-off>.
|
|
476
|
+
2. **<B>** — <trade-off>.
|
|
477
|
+
Recomendada: **<qual>** — <por quê>.
|
|
478
|
+
|
|
479
|
+
## Design
|
|
480
|
+
<arquitetura, componentes, fluxo de dados, tratamento de erro, estratégia de teste — em seções
|
|
481
|
+
escaladas ao tamanho do problema>
|
|
482
|
+
|
|
483
|
+
## Decisões e assumptions assinadas
|
|
484
|
+
- Assumo **X** porque **Y** — corrija se errado.
|
|
485
|
+
|
|
486
|
+
## Out-of-scope (o contrato do que NÃO muda)
|
|
487
|
+
| Item | Por que fora |
|
|
488
|
+
|---|---|
|
|
489
|
+
| <x> | <razão> |
|
|
490
|
+
|
|
491
|
+
## Aceite
|
|
492
|
+
<critérios verificáveis: para cada requisito, o teste que falha → passa>
|
|
493
|
+
`;
|
|
494
|
+
|
|
495
|
+
const DESIGN_TEMPLATE_EN = `# Template — design document
|
|
496
|
+
|
|
497
|
+
## Context
|
|
498
|
+
<the problem, the current state, why now>
|
|
499
|
+
|
|
500
|
+
## Approaches considered
|
|
501
|
+
1. **<A>** — <trade-off>.
|
|
502
|
+
2. **<B>** — <trade-off>.
|
|
503
|
+
Recommended: **<which>** — <why>.
|
|
504
|
+
|
|
505
|
+
## Design
|
|
506
|
+
<architecture, components, data flow, error handling, test strategy — sections scaled to the
|
|
507
|
+
size of the problem>
|
|
508
|
+
|
|
509
|
+
## Decisions and signed-off assumptions
|
|
510
|
+
- Assuming **X** because **Y** — correct me if wrong.
|
|
511
|
+
|
|
512
|
+
## Out-of-scope (the contract of what does NOT change)
|
|
513
|
+
| Item | Why out |
|
|
514
|
+
|---|---|
|
|
515
|
+
| <x> | <reason> |
|
|
516
|
+
|
|
517
|
+
## Acceptance
|
|
518
|
+
<verifiable criteria: for each requirement, the test that fails → passes>
|
|
332
519
|
`;
|
|
333
520
|
|
|
334
521
|
const WK_SKILLS_PT = [
|
|
335
522
|
skill('wk-workflow', 'Use ao começar qualquer mudança não-trivial — orquestra o loop a2 (explore, propose, apply, verify, archive) nos comandos wendkeep.', WORKFLOW),
|
|
336
523
|
skill('wk-tdd', 'Use ao implementar qualquer comportamento — Red/Green/Refactor com testes que discriminam (derivados do spec, litmus não-raso, adequação).', TDD),
|
|
337
524
|
skill('wk-debugging', 'Use quando algo falha ou quebra — depuração sistemática por hipótese antes de corrigir.', DEBUGGING),
|
|
338
|
-
skill('wk-brainstorming', 'Use quando a ideia ainda é vaga — vira design aprovado, com closure gate e tabela out-of-scope, antes de código.', BRAINSTORMING),
|
|
339
|
-
skill('wk-planning', 'Use após um design aprovado — decompõe em plano de tarefas TDD bite-sized.', PLANNING),
|
|
340
|
-
skill('wk-verify', 'Use no verify deep — passe independente read-only (autor≠verificador) que re-deriva a cobertura do spec e grava verdict.json.', VERIFY),
|
|
525
|
+
skill('wk-brainstorming', 'Use quando a ideia ainda é vaga — vira design aprovado, com closure gate e tabela out-of-scope, antes de código.', BRAINSTORMING, [{ name: 'design-template.md', content: DESIGN_TEMPLATE_PT }]),
|
|
526
|
+
skill('wk-planning', 'Use após um design aprovado — decompõe em plano de tarefas TDD bite-sized.', PLANNING, [{ name: 'plan-template.md', content: PLAN_TEMPLATE_PT }]),
|
|
527
|
+
skill('wk-verify', 'Use no verify deep — passe independente read-only (autor≠verificador) que re-deriva a cobertura do spec e grava verdict.json.', VERIFY, [{ name: 'spec-reviewer-prompt.md', content: REVIEWER_PROMPT_PT }, { name: 'verdict-template.json', content: VERDICT_TEMPLATE }]),
|
|
341
528
|
];
|
|
342
529
|
|
|
343
530
|
const WK_SKILLS_EN = [
|
|
344
531
|
skill('wk-workflow', 'Use when starting any non-trivial change — orchestrates the a2 loop (explore, propose, apply, verify, archive) over the wendkeep commands.', WORKFLOW_EN),
|
|
345
532
|
skill('wk-tdd', 'Use when implementing any behaviour — Red/Green/Refactor with tests that discriminate (spec-derived, non-shallow litmus, adequacy).', TDD_EN),
|
|
346
533
|
skill('wk-debugging', 'Use when something fails or breaks — systematic hypothesis-driven debugging before fixing.', DEBUGGING_EN),
|
|
347
|
-
skill('wk-brainstorming', 'Use when the idea is still vague — turns it into an approved design, with a closure gate and out-of-scope table, before code.', BRAINSTORMING_EN),
|
|
348
|
-
skill('wk-planning', 'Use after an approved design — decomposes it into a bite-sized TDD task plan.', PLANNING_EN),
|
|
349
|
-
skill('wk-verify', 'Use in verify deep — an independent read-only pass (author≠verifier) that re-derives spec coverage and writes verdict.json.', VERIFY_EN),
|
|
534
|
+
skill('wk-brainstorming', 'Use when the idea is still vague — turns it into an approved design, with a closure gate and out-of-scope table, before code.', BRAINSTORMING_EN, [{ name: 'design-template.md', content: DESIGN_TEMPLATE_EN }]),
|
|
535
|
+
skill('wk-planning', 'Use after an approved design — decomposes it into a bite-sized TDD task plan.', PLANNING_EN, [{ name: 'plan-template.md', content: PLAN_TEMPLATE_EN }]),
|
|
536
|
+
skill('wk-verify', 'Use in verify deep — an independent read-only pass (author≠verifier) that re-derives spec coverage and writes verdict.json.', VERIFY_EN, [{ name: 'spec-reviewer-prompt.md', content: REVIEWER_PROMPT_EN }, { name: 'verdict-template.json', content: VERDICT_TEMPLATE }]),
|
|
350
537
|
];
|
|
351
538
|
|
|
352
539
|
// Skill set for a locale. WK_SKILLS stays the pt-BR set for back-compat.
|
|
@@ -355,17 +542,23 @@ export function wkSkills(localeId = 'pt-BR') {
|
|
|
355
542
|
}
|
|
356
543
|
export const WK_SKILLS = WK_SKILLS_PT;
|
|
357
544
|
|
|
358
|
-
// Seed each skill into <brainDir>/skills/<name>/
|
|
545
|
+
// Seed each skill into <brainDir>/skills/<name>/ if absent (non-destructive): SKILL.md plus any
|
|
546
|
+
// bundled template/prompt files. Existing files are never overwritten, so re-seeding an older
|
|
547
|
+
// install just fills in the new template files alongside its SKILL.md.
|
|
359
548
|
export function seedWkSkills(brainDir, localeId = 'pt-BR') {
|
|
360
549
|
const created = [];
|
|
361
550
|
for (const s of wkSkills(localeId)) {
|
|
362
551
|
const dir = join(brainDir, 'skills', s.name);
|
|
363
552
|
mkdirSync(dir, { recursive: true });
|
|
364
|
-
const
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
553
|
+
const writeIfAbsent = (name, content) => {
|
|
554
|
+
const f = join(dir, name);
|
|
555
|
+
if (!existsSync(f)) {
|
|
556
|
+
writeFileSync(f, content, 'utf8');
|
|
557
|
+
created.push(f);
|
|
558
|
+
}
|
|
559
|
+
};
|
|
560
|
+
writeIfAbsent('SKILL.md', s.body);
|
|
561
|
+
for (const file of s.files || []) writeIfAbsent(file.name, file.content);
|
|
369
562
|
}
|
|
370
563
|
return created;
|
|
371
564
|
}
|
package/src/taxonomy.mjs
CHANGED
|
@@ -78,6 +78,10 @@ export const MCP_SERVER_KEY = 'wendkeep-vault';
|
|
|
78
78
|
// installed package is the single source of truth (update with `npm update wendkeep`,
|
|
79
79
|
// no re-copying). Returned as a spec the merge logic folds into settings.json.
|
|
80
80
|
export const SESSION_HOOKS = [
|
|
81
|
+
// Memory + active-change injection. Runs FIRST on SessionStart (order -10, folds before
|
|
82
|
+
// session-start) so the agent gets CORE + DIGEST + the active change + lessons as context.
|
|
83
|
+
// matcher 'startup|clear|compact' re-injects after a compaction/clear, not only cold startup.
|
|
84
|
+
{ event: 'SessionStart', matcher: 'startup|clear|compact', name: 'brain-inject', timeout: 15, order: -10, statusMessage: 'wendkeep: injecting memory + active change' },
|
|
81
85
|
{ event: 'SessionStart', matcher: 'startup', name: 'session-start', timeout: 30, statusMessage: 'wendkeep: opening Obsidian session' },
|
|
82
86
|
{ event: 'Stop', matcher: null, name: 'session-stop', timeout: 60, statusMessage: 'wendkeep: writing session checkpoint' },
|
|
83
87
|
{ event: 'UserPromptSubmit', matcher: null, name: 'session-ensure', timeout: 30, statusMessage: 'wendkeep: ensuring active session' },
|
|
@@ -130,6 +134,9 @@ export const COMPANIONS = [
|
|
|
130
134
|
// Kept selectable for anyone already invested in it; not a default.
|
|
131
135
|
label: 'dotcontext — legado (o loop a2 nativo do wendkeep substitui; não recomendado)',
|
|
132
136
|
default: false,
|
|
137
|
+
// Hidden from the interactive/text companion picker — the native a2 loop replaces it.
|
|
138
|
+
// Still reachable for anyone already invested via explicit `--companions dotcontext`.
|
|
139
|
+
hidden: true,
|
|
133
140
|
// MCP-only (no Claude Code plugin). Agent-agnostic server, @latest surface.
|
|
134
141
|
mcp: { key: 'dotcontext', entry: { type: 'stdio', command: 'npx', args: ['-y', '@dotcontext/mcp@latest'], env: {} } },
|
|
135
142
|
// Lifecycle hooks via the pinned CLI; wired by wendkeep (single writer).
|
|
@@ -141,6 +148,12 @@ export const COMPANIONS = [
|
|
|
141
148
|
|
|
142
149
|
const COMPANION_BY_ID = Object.fromEntries(COMPANIONS.map((c) => [c.id, c]));
|
|
143
150
|
|
|
151
|
+
// Companions offered in the interactive / text picker. Excludes `hidden` ones (e.g. the legacy
|
|
152
|
+
// dotcontext) — those stay reachable only via an explicit `--companions <id>`.
|
|
153
|
+
export function selectableCompanions() {
|
|
154
|
+
return COMPANIONS.filter((c) => !c.hidden);
|
|
155
|
+
}
|
|
156
|
+
|
|
144
157
|
// Resolve the companion ids for the NON-interactive path (the interactive prompt
|
|
145
158
|
// supplies its own selection). --no-companions wins; an explicit flag selects the
|
|
146
159
|
// named ids (unknown dropped) in registry order; otherwise the defaults.
|