wendkeep 0.32.0 → 0.33.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 +19 -0
- package/README.md +5 -3
- package/README.pt-BR.md +3 -3
- package/hooks/brain-inject.mjs +3 -3
- package/hooks/change-context.mjs +6 -15
- package/hooks/change-core.mjs +70 -21
- package/package.json +1 -1
- package/src/change.mjs +15 -5
- package/src/skills-seed.mjs +12 -6
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,25 @@ 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.33.0] — 2026-07-11
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- **Visão global de changes abertas**: `SessionStart`, `UserPromptSubmit`, `wendkeep change list`
|
|
12
|
+
e `wendkeep change status` sem slug mostram todas as pendências, inclusive as iniciadas por
|
|
13
|
+
outro agente.
|
|
14
|
+
- Ações de takeover explícitas no contexto: Claude, Codex ou outro agente podem retomar uma
|
|
15
|
+
change existente sem perder o restante do backlog.
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
|
|
19
|
+
- `.brain/CURRENT_CHANGE.md` continua como ponteiro global único, agora marcado como change
|
|
20
|
+
**atual**. Comandos implícitos (`done`, `verify`, `archive`, `abandon`) continuam restritos a ela.
|
|
21
|
+
- Mudanças em qualquer `tarefas.md` invalidam o hash do hook de contexto e reinjetam a lista global
|
|
22
|
+
na sessão afetada.
|
|
23
|
+
- `change-nag` permanece local à change atual; pendências de outra frente não bloqueiam o agente
|
|
24
|
+
em foco.
|
|
25
|
+
|
|
7
26
|
## [0.32.0] — 2026-07-09
|
|
8
27
|
|
|
9
28
|
### Added
|
package/README.md
CHANGED
|
@@ -112,7 +112,7 @@ No re‑copying, no snapshot to re‑sync — the package is the single source o
|
|
|
112
112
|
|---|---|
|
|
113
113
|
| `wendkeep init` | Set up wendkeep in a project (vault taxonomy + settings + MCP + skills). |
|
|
114
114
|
| `wendkeep hook <name>` | Run a session hook; invoked by `settings.json` (reads agent JSON on stdin). |
|
|
115
|
-
| `wendkeep change <sub>` | Change lifecycle: `new [--simple]` / `list` / `show` / `status` / `done <id
|
|
115
|
+
| `wendkeep change <sub>` | Change lifecycle: `new [--simple]` / `list` (global backlog) / `show` / `status [slug]` / `done <id> [--change slug]` / `undone <id> [--change slug]` / `diff` / `archive [--force]`. |
|
|
116
116
|
| `wendkeep verify [--deep]` | Run the change's task sensors; `--deep` assembles the independent-verification package. |
|
|
117
117
|
| `wendkeep spec <sub>` | Living specs: `list` / `show <capability>`. |
|
|
118
118
|
| `wendkeep sensors <sub>` | `list` / `add <id> "<command>"` — view/edit `wendkeep.sensors.json` (JSON Schema shipped). |
|
|
@@ -148,7 +148,7 @@ Beyond capturing sessions, wendkeep is a **harness**: a native, zero‑dependenc
|
|
|
148
148
|
explore → propose → apply (TDD) → verify → archive
|
|
149
149
|
```
|
|
150
150
|
|
|
151
|
-
- **Propose** — `wendkeep change new <slug>` scaffolds `08-Mudanças/<slug>/` (`proposta.md`, `design.md`, `tarefas.md`, and a `specs/` delta).
|
|
151
|
+
- **Propose** — `wendkeep change new <slug>` scaffolds `08-Mudanças/<slug>/` (`proposta.md`, `design.md`, `tarefas.md`, and a `specs/` delta). It becomes the global *current* change. Multiple changes may remain open: hooks and `change list/status` expose every pending task, while commands without `--change` use only the current one.
|
|
152
152
|
- **Apply** — implement each `tarefas.md` task. Tag a task that needs machine proof with `[sensor:<id>]`.
|
|
153
153
|
- **Verify** — `wendkeep verify` runs the sensors your tasks declared (from `wendkeep.sensors.json` at the project root) and records `evidencia.json`. A critical red fails the gate; a `warning` red is advisory.
|
|
154
154
|
- **Archive** — `wendkeep change archive <slug>` **gates** on the evidence (blocks unless every declared critical sensor is green), promotes each capability's spec delta (`ADDED`/`MODIFIED`/`REMOVED`) into the living `07-Specs/<capability>.md`, moves the change to `_arquivo/`, and mints an ADR in `04-Decisões/`.
|
|
@@ -175,6 +175,8 @@ Declare the capability in `proposta.md` (`specs: [ui]`) and author its delta in
|
|
|
175
175
|
|
|
176
176
|
```bash
|
|
177
177
|
npx wendkeep change status # one screen: tasks / sensors / verdict
|
|
178
|
+
npx wendkeep change list # all open changes + pending tasks
|
|
179
|
+
npx wendkeep change status dark-mode # one change in detail
|
|
178
180
|
npx wendkeep change done 1.1 # tick a task from the CLI
|
|
179
181
|
npx wendkeep verify # run the declared sensors -> evidencia.json
|
|
180
182
|
npx wendkeep verify --deep # assemble the verification package
|
|
@@ -194,7 +196,7 @@ agent session ──hooks──▶ wendkeep ──▶ Markdown in vault ──
|
|
|
194
196
|
(Claude/Codex) (Node) (02-Sessões/…) (CORE+DIGEST, backlinks)
|
|
195
197
|
```
|
|
196
198
|
|
|
197
|
-
The agent's settings.json points each hook at `npx wendkeep hook …`. On `Stop`, wendkeep parses the session transcript, appends the turn, updates the token/cost table, and (idempotently) emits any decision/bug/learning notes. On every `SessionStart`, `brain-inject` injects back
|
|
199
|
+
The agent's settings.json points each hook at `npx wendkeep hook …`. On `Stop`, wendkeep parses the session transcript, appends the turn, updates the token/cost table, and (idempotently) emits any decision/bug/learning notes. On every `SessionStart`, `brain-inject` injects back curated memory (CORE + DIGEST), every open change with its pending tasks, the global current-change marker, project lessons, and a `<wk_process>` router. Claude, Codex, or another agent can therefore resume work started elsewhere without hiding the rest of the backlog.
|
|
198
200
|
|
|
199
201
|
The archive **gate** blocks unless: the change scaffold is filled (G0), no task is open (G1), every declared critical sensor is green (with fresh evidence), and — when the change declares `[req:]` — an independent `verdict.json` covers them. `--force` is the human escape hatch; the agent is instructed never to use it on its own.
|
|
200
202
|
|
package/README.pt-BR.md
CHANGED
|
@@ -110,7 +110,7 @@ Sem recopiar, sem snapshot pra re‑sincronizar — o pacote é a única fonte d
|
|
|
110
110
|
|---|---|
|
|
111
111
|
| `wendkeep init` | Configura o wendkeep num projeto (taxonomia do cofre + settings + MCP + skills). |
|
|
112
112
|
| `wendkeep hook <name>` | Roda um hook de sessão; invocado pelo `settings.json` (lê o JSON do agente no stdin). |
|
|
113
|
-
| `wendkeep change <sub>` | Ciclo de mudança: `new [--simple]` / `list` / `show` / `status` / `done <id
|
|
113
|
+
| `wendkeep change <sub>` | Ciclo de mudança: `new [--simple]` / `list` (backlog global) / `show` / `status [slug]` / `done <id> [--change slug]` / `undone <id> [--change slug]` / `diff` / `archive [--force]`. |
|
|
114
114
|
| `wendkeep verify [--deep]` | Roda os sensores das tarefas da change; `--deep` monta o pacote de verificação independente. |
|
|
115
115
|
| `wendkeep spec <sub>` | Specs vivos: `list` / `show <capability>`. |
|
|
116
116
|
| `wendkeep sensors <sub>` | `list` / `add <id> "<comando>"` — vê/edita `wendkeep.sensors.json` (JSON Schema incluso). |
|
|
@@ -147,7 +147,7 @@ Além de capturar sessões, o wendkeep é um **harness**: um loop nativo e sem d
|
|
|
147
147
|
explore → propose → apply (TDD) → verify → archive
|
|
148
148
|
```
|
|
149
149
|
|
|
150
|
-
- **Propose** — `wendkeep change new <slug>` faz o scaffold de `08-Mudanças/<slug>/` (`proposta.md`, `design.md`, `tarefas.md` e um delta `specs/`). A change vira *
|
|
150
|
+
- **Propose** — `wendkeep change new <slug>` faz o scaffold de `08-Mudanças/<slug>/` (`proposta.md`, `design.md`, `tarefas.md` e um delta `specs/`). A change vira a *atual* global. Várias changes podem ficar abertas: hooks e `change list/status` mostram todas as pendências, enquanto comandos sem `--change` usam somente a atual.
|
|
151
151
|
- **Apply** — implemente cada tarefa de `tarefas.md`. Taggeie a tarefa que precisa de prova de máquina com `[sensor:<id>]`.
|
|
152
152
|
- **Verify** — `wendkeep verify` roda os sensores que suas tarefas declararam (do `wendkeep.sensors.json` na raiz do projeto) e grava `evidencia.json`. Um vermelho crítico falha o gate; um vermelho `warning` é aviso.
|
|
153
153
|
- **Archive** — `wendkeep change archive <slug>` faz **gate** na evidência (bloqueia a não ser que todo sensor crítico declarado esteja verde), promove o delta de cada capability (`ADDED`/`MODIFIED`/`REMOVED`) pro `07-Specs/<capability>.md` vivo, move a change pro `_arquivo/` e cunha um ADR em `04-Decisões/`.
|
|
@@ -163,7 +163,7 @@ sessão do agente ──hooks──▶ wendkeep ──▶ Markdown no cofre ─
|
|
|
163
163
|
(Claude/Codex) (Node) (02-Sessões/…) (CORE+DIGEST, backlinks)
|
|
164
164
|
```
|
|
165
165
|
|
|
166
|
-
O settings.json do agente aponta cada hook pra `npx wendkeep hook …`. No `Stop`, o wendkeep parseia o transcript, anexa o turno, atualiza a tabela de tokens/custo e (idempotentemente) emite qualquer nota de decisão/bug/aprendizado. Em todo `SessionStart`, o `brain-inject` injeta
|
|
166
|
+
O settings.json do agente aponta cada hook pra `npx wendkeep hook …`. No `Stop`, o wendkeep parseia o transcript, anexa o turno, atualiza a tabela de tokens/custo e (idempotentemente) emite qualquer nota de decisão/bug/aprendizado. Em todo `SessionStart`, o `brain-inject` injeta a memória curada (CORE + DIGEST), todas as changes abertas com suas pendências, o marcador global da change atual, as lições do projeto e o roteador `<wk_process>`. Claude, Codex ou outro agente podem assim retomar trabalho iniciado em outro lugar sem ocultar o restante do backlog.
|
|
167
167
|
|
|
168
168
|
O **gate** do archive bloqueia a não ser que: o scaffold da change esteja preenchido (G0), nenhuma tarefa esteja aberta (G1), todo sensor crítico declarado esteja verde (com evidência fresca) e — quando a change declara `[req:]` — um `verdict.json` independente cubra eles. O `--force` é a saída de emergência humana; o agente é instruído a nunca usar por conta própria.
|
|
169
169
|
|
package/hooks/brain-inject.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// .agent/hooks/brain-inject.mjs
|
|
2
2
|
// Injeção da camada quente no SessionStart (Claude/Codex/Copilot): CORE curado +
|
|
3
|
-
// DIGEST auto + 1-linha pointer do recall
|
|
3
|
+
// DIGEST auto + 1-linha pointer do recall + backlog completo de changes. Nunca derruba o hook.
|
|
4
4
|
// Uso (hook): node .agent/hooks/brain-inject.mjs (input JSON via stdin)
|
|
5
5
|
import { readFileSync } from 'node:fs';
|
|
6
6
|
import { join } from 'node:path';
|
|
@@ -72,8 +72,8 @@ if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href)
|
|
|
72
72
|
additionalContext: buildInjection(vaultBase),
|
|
73
73
|
},
|
|
74
74
|
});
|
|
75
|
-
// Sentinela do change-context:
|
|
76
|
-
// UserPromptSubmit não precisa re-pingar no 1º prompt. Bônus — nunca derruba a injeção.
|
|
75
|
+
// Sentinela do change-context: o backlog completo acabou de ser injetado aqui, então o hook
|
|
76
|
+
// UserPromptSubmit não precisa re-pingar no 1º prompt. Bônus — nunca derruba a injeção.
|
|
77
77
|
try {
|
|
78
78
|
const st = changeCtxState(vaultBase);
|
|
79
79
|
if (st) writeSentinel(vaultBase, 'ctx', input.session_id || input.sessionId || '', st.hash);
|
package/hooks/change-context.mjs
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
// UserPromptSubmit hook. Dois papéis, ambos quiet-by-default (a maioria dos prompts não injeta nada):
|
|
3
|
-
// 1. Com
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
// 2. Sem change ativa: prompt com cara de tarefa ganha <wk_skill_gate> mandando invocar a
|
|
3
|
+
// 1. Com changes abertas: re-injeta <open_changes_ping> (backlog completo) SÓ quando o estado
|
|
4
|
+
// mudou desde a última injeção (hash em sentinela por sessão).
|
|
5
|
+
// 2. Sem changes abertas: prompt com cara de tarefa ganha <wk_skill_gate> mandando invocar a
|
|
7
6
|
// Skill wk-workflow ANTES de editar — 1x por sessão. É o empurrão de ativação da skill.
|
|
8
7
|
// Fail-open; brain-inject grava a sentinela ctx no SessionStart para não duplicar no 1º prompt.
|
|
9
8
|
import { pathToFileURL } from 'node:url';
|
|
10
9
|
import { getVaultBase, readHookInput, writeHookOutput } from './obsidian-common.mjs';
|
|
11
|
-
import { changeCtxState, readSentinel, writeSentinel } from './change-core.mjs';
|
|
10
|
+
import { changeCtxState, readSentinel, renderOpenChanges, writeSentinel } from './change-core.mjs';
|
|
12
11
|
|
|
13
12
|
// Conservador de propósito: verbos de tarefa comuns (pt+en) + tamanho mínimo. Falso-negativo
|
|
14
13
|
// custa só o nudge; falso-positivo em pergunta curta viraria ruído.
|
|
@@ -25,17 +24,9 @@ export function buildChangePing(vaultBase, sessionId, prompt = '') {
|
|
|
25
24
|
if (st) {
|
|
26
25
|
if (readSentinel(vaultBase, 'ctx', sessionId) === st.hash) return null;
|
|
27
26
|
writeSentinel(vaultBase, 'ctx', sessionId, st.hash);
|
|
28
|
-
|
|
29
|
-
const context = [
|
|
30
|
-
'<active_change_ping>',
|
|
31
|
-
`Mudança ativa: ${st.slug}${st.openTasks.length ? ` — tarefa(s) aberta(s):` : ' — sem tarefas abertas.'}`,
|
|
32
|
-
...lines,
|
|
33
|
-
'Ao concluir uma tarefa: `wendkeep change done <id>`. Antes de arquivar: `wendkeep verify`.',
|
|
34
|
-
'</active_change_ping>',
|
|
35
|
-
].join('\n');
|
|
36
|
-
return { context, hash: st.hash };
|
|
27
|
+
return { context: renderOpenChanges(st, { tag: 'open_changes_ping' }), hash: st.hash };
|
|
37
28
|
}
|
|
38
|
-
// Sem
|
|
29
|
+
// Sem changes abertas: gate de skill para prompt-tarefa, 1x por sessão.
|
|
39
30
|
if (!looksLikeTask(prompt)) return null;
|
|
40
31
|
if (readSentinel(vaultBase, 'gate', sessionId)) return null;
|
|
41
32
|
writeSentinel(vaultBase, 'gate', sessionId);
|
package/hooks/change-core.mjs
CHANGED
|
@@ -167,22 +167,67 @@ export function listChanges(vaultBase) {
|
|
|
167
167
|
try {
|
|
168
168
|
archived = readdirSync(join(base, ARCHIVE_DIR)).filter((n) => !n.startsWith('.'));
|
|
169
169
|
} catch { /* none */ }
|
|
170
|
-
return { active, archived };
|
|
170
|
+
return { active: active.sort(), archived: archived.sort() };
|
|
171
171
|
}
|
|
172
172
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
173
|
+
// Visão derivada de TODAS as changes abertas. CURRENT_CHANGE continua sendo o único foco para
|
|
174
|
+
// comandos implícitos; provider/session nunca filtram a fila, para que outro agente possa assumir
|
|
175
|
+
// o trabalho. O hash leva o conteúdo inteiro de cada tarefas.md — não apenas as contagens — pois
|
|
176
|
+
// ele controla a reinjeção por sessão dos hooks.
|
|
177
|
+
export function allChangesState(vaultBase) {
|
|
178
|
+
const current = activeChange(vaultBase);
|
|
179
|
+
const { active } = listChanges(vaultBase);
|
|
176
180
|
const chDir = getLocale(vaultBase).folders.changes;
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
181
|
+
const fingerprint = [`current:${current}`];
|
|
182
|
+
const changes = active.map((slug) => {
|
|
183
|
+
let md = '';
|
|
184
|
+
let warning = '';
|
|
185
|
+
try { md = readFileSync(join(vaultBase, chDir, slug, 'tarefas.md'), 'utf8'); }
|
|
186
|
+
catch { warning = 'tarefas.md ausente ou ilegível'; }
|
|
187
|
+
const tasks = parseTasks(md);
|
|
188
|
+
const openTasks = tasks.filter((t) => !t.done);
|
|
189
|
+
fingerprint.push(`slug:${slug}`, `tasks:${md}`, `warning:${warning}`);
|
|
190
|
+
return {
|
|
191
|
+
slug,
|
|
192
|
+
current: slug === current,
|
|
193
|
+
openTasks,
|
|
194
|
+
openCount: openTasks.length,
|
|
195
|
+
doneCount: tasks.length - openTasks.length,
|
|
196
|
+
warning,
|
|
197
|
+
};
|
|
198
|
+
});
|
|
199
|
+
changes.sort((a, b) => Number(b.current) - Number(a.current) || a.slug.localeCompare(b.slug));
|
|
200
|
+
const pointerWarning = current && !changes.some((change) => change.current)
|
|
201
|
+
? `CURRENT_CHANGE aponta para change inexistente: ${current}`
|
|
202
|
+
: '';
|
|
203
|
+
if (pointerWarning) fingerprint.push(`pointer-warning:${pointerWarning}`);
|
|
204
|
+
return { current, changes, pointerWarning, hash: tasksHashOf(fingerprint.join('\n')) };
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
export function renderOpenChanges(state, { tag = 'open_changes' } = {}) {
|
|
208
|
+
if (!state?.changes?.length && !state?.pointerWarning) return '';
|
|
209
|
+
const lines = [];
|
|
210
|
+
if (tag) lines.push(`<${tag}>`);
|
|
211
|
+
if (state.current) lines.push(`Change atual (comandos sem --change): ${state.current}.`);
|
|
212
|
+
else lines.push('Nenhuma change atual selecionada; comandos sem --change continuam recusados.');
|
|
213
|
+
if (state.pointerWarning) lines.push(`Aviso: ${state.pointerWarning}.`);
|
|
214
|
+
for (const change of state.changes || []) {
|
|
215
|
+
const label = change.current ? 'ATUAL' : 'ABERTA';
|
|
216
|
+
lines.push(`### ${label} — ${change.slug} (${change.openCount} aberta(s), ${change.doneCount} concluída(s))`);
|
|
217
|
+
if (change.warning) lines.push(`- Aviso: ${change.warning}.`);
|
|
218
|
+
else if (!change.openTasks.length) lines.push('- Nenhuma tarefa aberta.');
|
|
219
|
+
else for (const task of change.openTasks) lines.push(`- [ ] ${task.id} ${task.text}`);
|
|
220
|
+
}
|
|
221
|
+
if (state.current) lines.push('Para change atual: `wendkeep change done <id>`; antes de archive: `wendkeep verify`.');
|
|
222
|
+
lines.push('Qualquer agente pode assumir uma change: selecione-a com `wendkeep change new <slug-existente>` ou use `--change <slug>` quando disponível.');
|
|
223
|
+
if (tag) lines.push(`</${tag}>`);
|
|
224
|
+
return lines.join('\n');
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// Mantém o nome exportado para consumidores internos existentes, mas agora injeta o backlog
|
|
228
|
+
// completo em vez de ocultar changes não selecionadas.
|
|
229
|
+
export function buildActiveChangeInjection(vaultBase) {
|
|
230
|
+
return renderOpenChanges(allChangesState(vaultBase));
|
|
186
231
|
}
|
|
187
232
|
|
|
188
233
|
export function activeChangeLink(vaultBase) {
|
|
@@ -232,14 +277,18 @@ export function writeSentinel(vaultBase, kind, sid, value = '1') {
|
|
|
232
277
|
} catch { /* fail-open: pior caso = aviso repetido */ }
|
|
233
278
|
}
|
|
234
279
|
|
|
235
|
-
// Estado
|
|
236
|
-
// change
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
return {
|
|
280
|
+
// Estado global usado pelo change-context: hash cobre qualquer tarefa aberta, inclusive de uma
|
|
281
|
+
// change que não esteja no ponteiro. As propriedades slug/openTasks preservam compatibilidade com
|
|
282
|
+
// consumidores antigos e descrevem somente a atual.
|
|
283
|
+
export function changeCtxState(vaultBase) {
|
|
284
|
+
const state = allChangesState(vaultBase);
|
|
285
|
+
if (!state.changes.length && !state.pointerWarning) return null;
|
|
286
|
+
const selected = state.changes.find((change) => change.current);
|
|
287
|
+
return {
|
|
288
|
+
...state,
|
|
289
|
+
slug: state.current,
|
|
290
|
+
openTasks: selected?.openTasks || [],
|
|
291
|
+
};
|
|
243
292
|
}
|
|
244
293
|
|
|
245
294
|
// GC das sentinelas (>7 dias) — seleção pura separada da execução (testável sem depender de
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wendkeep",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.33.0",
|
|
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/change.mjs
CHANGED
|
@@ -4,7 +4,9 @@ import { isAbsolute, join, resolve } from 'node:path';
|
|
|
4
4
|
import {
|
|
5
5
|
newChange,
|
|
6
6
|
activeChange,
|
|
7
|
+
allChangesState,
|
|
7
8
|
listChanges,
|
|
9
|
+
renderOpenChanges,
|
|
8
10
|
parseTasks,
|
|
9
11
|
setTaskDone,
|
|
10
12
|
archiveChange,
|
|
@@ -61,9 +63,9 @@ export function runChange(argv) {
|
|
|
61
63
|
}
|
|
62
64
|
|
|
63
65
|
if (sub === 'list') {
|
|
64
|
-
const
|
|
65
|
-
const
|
|
66
|
-
process.stdout.write(
|
|
66
|
+
const state = allChangesState(vaultBase);
|
|
67
|
+
const { archived } = listChanges(vaultBase);
|
|
68
|
+
process.stdout.write(`${renderOpenChanges(state, { tag: '' }) || 'open changes: (none)'}\n`);
|
|
67
69
|
process.stdout.write(`archived: ${archived.join(', ') || '(none)'}\n`);
|
|
68
70
|
process.exit(0);
|
|
69
71
|
}
|
|
@@ -82,8 +84,16 @@ export function runChange(argv) {
|
|
|
82
84
|
}
|
|
83
85
|
|
|
84
86
|
if (sub === 'status') {
|
|
85
|
-
const slug = slugArg()
|
|
86
|
-
if (!slug) {
|
|
87
|
+
const slug = slugArg();
|
|
88
|
+
if (!slug) {
|
|
89
|
+
const state = allChangesState(vaultBase);
|
|
90
|
+
if (!state.changes.length && !state.pointerWarning) {
|
|
91
|
+
process.stderr.write('wendkeep change status: no open changes\n');
|
|
92
|
+
process.exit(2);
|
|
93
|
+
}
|
|
94
|
+
process.stdout.write(`${renderOpenChanges(state, { tag: '' })}\n`);
|
|
95
|
+
process.exit(0);
|
|
96
|
+
}
|
|
87
97
|
const dir = join(vaultBase, getLocale(vaultBase).folders.changes, slug);
|
|
88
98
|
let tarefasMd;
|
|
89
99
|
try { tarefasMd = readFileSync(join(dir, 'tarefas.md'), 'utf8'); }
|
package/src/skills-seed.mjs
CHANGED
|
@@ -29,8 +29,9 @@ vault cego. Exceção única: mudança trivial (typo, 1 linha).
|
|
|
29
29
|
- \`proposta.md\` — *por quê* e *o que muda* (o WHAT).
|
|
30
30
|
- \`design.md\` — a abordagem técnica.
|
|
31
31
|
- \`tarefas.md\` — a lista de tarefas \`- [ ] N.N descrição\`.
|
|
32
|
-
A mudança vira a *
|
|
33
|
-
|
|
32
|
+
A mudança vira a *atual* (ponteiro global \`.brain/CURRENT_CHANGE.md\`). Podem existir
|
|
33
|
+
várias changes abertas: hooks e \`change list/status\` mostram todas as pendências; comandos
|
|
34
|
+
sem \`--change\` usam somente a atual.
|
|
34
35
|
Antes de implementar, resolva \`spec_impact\` na proposta:
|
|
35
36
|
- \`required\`: liste a capability em \`specs:\` e preencha
|
|
36
37
|
\`specs/<capability>/spec.md\` com ADDED/MODIFIED/REMOVED; ligue tarefas com \`[req:ID]\`.
|
|
@@ -53,7 +54,9 @@ vault cego. Exceção única: mudança trivial (typo, 1 linha).
|
|
|
53
54
|
|
|
54
55
|
## Regras
|
|
55
56
|
|
|
56
|
-
-
|
|
57
|
+
- Várias changes podem ficar abertas. \`CURRENT_CHANGE.md\` marca uma atual, sem esconder as
|
|
58
|
+
outras pendências. Claude, Codex ou outro agente podem assumir uma change existente com
|
|
59
|
+
\`wendkeep change new <slug-existente>\` ou \`--change <slug>\` quando disponível.
|
|
57
60
|
- Se uma tarefa não precisa de prova automatizada, não declare sensor — o gate só exige
|
|
58
61
|
o que você declarou. Sem \`[sensor:]\`, o archive não trava.
|
|
59
62
|
- A proposta linka a sessão de origem; a sessão linka a mudança ativa. É de propósito:
|
|
@@ -248,8 +251,9 @@ leaves the vault blind. Single exception: a trivial change (typo, one line).
|
|
|
248
251
|
|
|
249
252
|
1. **Explore** — understand the problem before proposing.
|
|
250
253
|
2. **Propose** — \`wendkeep change new <slug>\` scaffolds \`08-Changes/<slug>/\`
|
|
251
|
-
(proposta/design/tarefas + a \`specs/\` delta). The change becomes *
|
|
252
|
-
|
|
254
|
+
(proposta/design/tarefas + a \`specs/\` delta). The change becomes *current* through global
|
|
255
|
+
\`.brain/CURRENT_CHANGE.md\`. Multiple changes may stay open; hooks and \`change list/status\`
|
|
256
|
+
show every pending task, while commands without \`--change\` use only the current change.
|
|
253
257
|
Before implementation, resolve \`spec_impact\`: \`required\` needs the capability listed in
|
|
254
258
|
\`specs:\` plus a real \`specs/<capability>/spec.md\` delta and \`[req:ID]\` links; \`none\`
|
|
255
259
|
needs a real \`spec_impact_reason\`. \`pending\` is never ready for implementation/archive.
|
|
@@ -263,7 +267,9 @@ leaves the vault blind. Single exception: a trivial change (typo, one line).
|
|
|
263
267
|
verdict AND no open tasks. It promotes the delta into \`07-Specs\` and mints an ADR.
|
|
264
268
|
|
|
265
269
|
## Rules
|
|
266
|
-
-
|
|
270
|
+
- Multiple changes may stay open. \`CURRENT_CHANGE.md\` marks one current change without hiding
|
|
271
|
+
other pending tasks. Any agent may take over an existing change with
|
|
272
|
+
\`wendkeep change new <existing-slug>\` or \`--change <slug>\` where available.
|
|
267
273
|
- No \`[sensor:]\` on a task = no automated gate for it. No \`[req:]\` = no independent verdict.
|
|
268
274
|
- The graph links session ↔ change ↔ requirement ↔ decision. That is the point.
|
|
269
275
|
`;
|