wendkeep 0.86.0 → 0.87.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/.githooks/commit-msg +16 -0
- package/.githooks/prepare-commit-msg +16 -0
- package/CHANGELOG.md +14 -0
- package/README.en.md +2 -0
- package/README.md +2 -0
- package/docs/en/commands/commit.md +159 -0
- package/docs/pt-BR/commands/commit.md +159 -0
- package/package.json +5 -2
- package/packages/cli/src/index.mjs +11 -1
- package/packages/commit/package.json +6 -0
- package/packages/commit/src/cli.mjs +89 -0
- package/packages/commit/src/commit-input.mjs +181 -0
- package/packages/commit/src/commit-message.mjs +51 -0
- package/packages/commit/src/commit-policy.mjs +144 -0
- package/packages/commit/src/git-runtime.mjs +428 -0
- package/packages/commit/src/index.mjs +28 -0
- package/packages/commit/src/proof-validation.mjs +443 -0
- package/schema/commit-message-v1.schema.json +75 -0
- package/scripts/validate-commit-range.mjs +244 -0
- package/src/doctor.mjs +7 -0
- package/src/git-commit-hooks.mjs +112 -0
- package/src/init.mjs +13 -0
- package/src/skills-seed.mjs +79 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
set -eu
|
|
3
|
+
|
|
4
|
+
CLI=${WENDKEEP_COMMIT_CLI:-}
|
|
5
|
+
if [ -z "$CLI" ]; then
|
|
6
|
+
if [ -f "./node_modules/wendkeep/bin/wendkeep.mjs" ]; then
|
|
7
|
+
CLI=./node_modules/wendkeep/bin/wendkeep.mjs
|
|
8
|
+
elif [ -f "./bin/wendkeep.mjs" ]; then
|
|
9
|
+
CLI=./bin/wendkeep.mjs
|
|
10
|
+
else
|
|
11
|
+
echo "WENDKEEP_COMMIT_CLI_MISSING: install wendkeep or run wendkeep doctor" >&2
|
|
12
|
+
exit 2
|
|
13
|
+
fi
|
|
14
|
+
fi
|
|
15
|
+
|
|
16
|
+
exec node "$CLI" commit validate --message-file "$1" --consume-context
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
set -eu
|
|
3
|
+
|
|
4
|
+
CLI=${WENDKEEP_COMMIT_CLI:-}
|
|
5
|
+
if [ -z "$CLI" ]; then
|
|
6
|
+
if [ -f "./node_modules/wendkeep/bin/wendkeep.mjs" ]; then
|
|
7
|
+
CLI=./node_modules/wendkeep/bin/wendkeep.mjs
|
|
8
|
+
elif [ -f "./bin/wendkeep.mjs" ]; then
|
|
9
|
+
CLI=./bin/wendkeep.mjs
|
|
10
|
+
else
|
|
11
|
+
echo "WENDKEEP_COMMIT_CLI_MISSING: install wendkeep or run wendkeep doctor" >&2
|
|
12
|
+
exit 2
|
|
13
|
+
fi
|
|
14
|
+
fi
|
|
15
|
+
|
|
16
|
+
exec node "$CLI" commit prepare --message-file "$1" --source "${2:-}" --commit "${3:-}"
|
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,20 @@ 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.87.0] — 2026-08-29
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- **Política universal de commits baseada em evidências.** O novo pacote `wendkeep/commit`, a CLI,
|
|
12
|
+
os hooks Git e o gate de intervalo produzem e validam mensagens determinísticas a partir de
|
|
13
|
+
autoridade, tarefas, spec, escopo e sensores rederiváveis no checkout exato do commit.
|
|
14
|
+
|
|
15
|
+
### Security
|
|
16
|
+
|
|
17
|
+
- **Prova remota limitada ao que o CI consegue rederivar.** Evidências causais locais permanecem
|
|
18
|
+
não publicadas; alegações remotas indisponíveis, provas circulares, sensores divergentes,
|
|
19
|
+
adulterações de escopo e caminhos privados falham de modo fechado antes da persistência.
|
|
20
|
+
|
|
7
21
|
## [0.86.0] — 2026-08-28
|
|
8
22
|
|
|
9
23
|
### Added
|
package/README.en.md
CHANGED
|
@@ -151,6 +151,7 @@ npx wendkeep init --no-companions --no-mcp --yes # zero companions,
|
|
|
151
151
|
| `--no-mcp` | Skip **wendkeep's own** vault MCP (`wendkeep-vault`). Companion MCPs still follow `--companions`. |
|
|
152
152
|
| `--no-colors` | Skip the Obsidian color system (`.obsidian` snippet + graph groups). |
|
|
153
153
|
| `--vscode-worktree-tasks` | Create a local, Git-excluded `.vscode/tasks.json` for creating/listing/opening/finishing worktrees; never overwrites an existing file. Also accepted by `sync`. |
|
|
154
|
+
| `--git-commit-hooks` | Opt in to copying commit hooks into `.githooks/` and setting local `core.hooksPath`; custom hooks are preserved without `--force`. |
|
|
154
155
|
| `--yes`, `-y` | Non-interactive; accept defaults (skips the language / vault / companion prompts). |
|
|
155
156
|
| `--force` | Overwrite existing wendkeep config blocks. |
|
|
156
157
|
|
|
@@ -259,6 +260,7 @@ The README is the map; the guides provide syntax, options, exit codes, examples,
|
|
|
259
260
|
| **Notes and knowledge** | BUG/APR/ADR, repairs, renumbering, lessons, and dashboard | [Notes and knowledge](https://github.com/rogersialves/wendkeep/blob/main/docs/en/commands/notes-and-knowledge.md) |
|
|
260
261
|
| **Costs and observability** | safe dry-run, tri-state, aggregation, trends, and historical rebuild | [Costs and observability](https://github.com/rogersialves/wendkeep/blob/main/docs/en/commands/costs-and-observability.md) |
|
|
261
262
|
| **Maintenance and diagnostics** | doctor, frontier/manifest freshness, drift, version, and help | [Maintenance and diagnostics](https://github.com/rogersialves/wendkeep/blob/main/docs/en/commands/maintenance-and-diagnostics.md) |
|
|
263
|
+
| **Evidence-based commits** | `wendkeep commit`, tasks derived from contracts, tests only from canonical execution bound to the exact SHA, opt-in Git hooks, privacy, and remote range gate | [Commits](https://github.com/rogersialves/wendkeep/blob/main/docs/en/commands/commit.md) |
|
|
262
264
|
| **Local Observer** | `observer serve`, registration, incremental publication, `reconcile`, outbox, and multi-project index | [Local Observer](https://github.com/rogersialves/wendkeep/blob/main/docs/en/commands/observer.md) |
|
|
263
265
|
|
|
264
266
|
Operations that deserve step-by-step guidance: [verify and exits 0/1/2](https://github.com/rogersialves/wendkeep/blob/main/docs/en/commands/verify.md),
|
package/README.md
CHANGED
|
@@ -151,6 +151,7 @@ npx wendkeep init --no-companions --no-mcp --yes # zero companions,
|
|
|
151
151
|
| `--no-mcp` | Skip **wendkeep's own** vault MCP (`wendkeep-vault`). Companion MCPs still follow `--companions`. |
|
|
152
152
|
| `--no-colors` | Skip the Obsidian color system (`.obsidian` snippet + graph groups). |
|
|
153
153
|
| `--vscode-worktree-tasks` | Create a local, Git-excluded `.vscode/tasks.json` for creating/listing/opening/finishing worktrees; never overwrites an existing file. Also accepted by `sync`. |
|
|
154
|
+
| `--git-commit-hooks` | Opt in to copying commit hooks into `.githooks/` and setting local `core.hooksPath`; custom hooks are preserved without `--force`. |
|
|
154
155
|
| `--yes`, `-y` | Non-interactive; accept defaults (skips the language / vault / companion prompts). |
|
|
155
156
|
| `--force` | Overwrite existing wendkeep config blocks. |
|
|
156
157
|
|
|
@@ -259,6 +260,7 @@ The README is the map; the guides provide syntax, options, exit codes, examples,
|
|
|
259
260
|
| **Notes and knowledge** | BUG/APR/ADR, repairs, renumbering, lessons, and dashboard | [Notes and knowledge](https://github.com/rogersialves/wendkeep/blob/main/docs/en/commands/notes-and-knowledge.md) |
|
|
260
261
|
| **Costs and observability** | safe dry-run, tri-state, aggregation, trends, and historical rebuild | [Costs and observability](https://github.com/rogersialves/wendkeep/blob/main/docs/en/commands/costs-and-observability.md) |
|
|
261
262
|
| **Maintenance and diagnostics** | doctor, frontier/manifest freshness, drift, version, and help | [Maintenance and diagnostics](https://github.com/rogersialves/wendkeep/blob/main/docs/en/commands/maintenance-and-diagnostics.md) |
|
|
263
|
+
| **Evidence-based commits** | `wendkeep commit`, tasks derived from contracts, tests only from canonical execution bound to the exact SHA, opt-in Git hooks, privacy, and remote range gate | [Commits](https://github.com/rogersialves/wendkeep/blob/main/docs/en/commands/commit.md) |
|
|
262
264
|
| **Local Observer** | `observer serve`, registration, incremental publication, `reconcile`, outbox, and multi-project index | [Local Observer](https://github.com/rogersialves/wendkeep/blob/main/docs/en/commands/observer.md) |
|
|
263
265
|
|
|
264
266
|
Operations that deserve step-by-step guidance: [verify and exits 0/1/2](https://github.com/rogersialves/wendkeep/blob/main/docs/en/commands/verify.md),
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
# Evidence-based commits
|
|
2
|
+
|
|
3
|
+
**English** · [Português](../../pt-BR/commands/commit.md)
|
|
4
|
+
|
|
5
|
+
## Purpose
|
|
6
|
+
|
|
7
|
+
Produce the same auditable message from Codex, Claude Code, or another Git client using typed input,
|
|
8
|
+
public references, and a staged-index summary only. The deterministic kernel does not read the
|
|
9
|
+
Vault, `.brain`, session registries, or the network.
|
|
10
|
+
|
|
11
|
+
## When to use
|
|
12
|
+
|
|
13
|
+
Use before `feat`, `fix`, `refactor`, or `perf` implementation commits that must record causal
|
|
14
|
+
authority, tasks, tests, scope, and verifiable evidence consistently across harnesses.
|
|
15
|
+
|
|
16
|
+
## When not to use
|
|
17
|
+
|
|
18
|
+
Do not use it to invent proof, publish private content, rewrite history, or automate pushes.
|
|
19
|
+
`docs`, `test`, and `chore` commits need no context only when every changed file is objectively
|
|
20
|
+
documentation/test material. Product changes require the governed body regardless of type.
|
|
21
|
+
|
|
22
|
+
## Prerequisites
|
|
23
|
+
|
|
24
|
+
Run inside a Git repository with WendKeep installed locally and the selected product files already
|
|
25
|
+
present in the staged index.
|
|
26
|
+
|
|
27
|
+
## Syntax
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
npx --no-install wendkeep commit context --input <json|-> [--json]
|
|
31
|
+
npx --no-install wendkeep commit context --clear [--json]
|
|
32
|
+
npx --no-install wendkeep commit render --input <json|->
|
|
33
|
+
npx --no-install wendkeep commit prepare --message-file <path> [--source <source>]
|
|
34
|
+
npx --no-install wendkeep commit validate --message-file <path> [--json]
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Options and exit codes
|
|
38
|
+
|
|
39
|
+
- Exit `0`: context written/cleared or message valid.
|
|
40
|
+
- Exit `1`: invalid governed message.
|
|
41
|
+
- Exit `2`: invalid argument, JSON, Git state, privacy boundary, or stale context.
|
|
42
|
+
- `--consume-context` is reserved for the `commit-msg` wrapper and removes context after validation.
|
|
43
|
+
|
|
44
|
+
## Opt-in installation
|
|
45
|
+
|
|
46
|
+
The default `init` does not enable Git hooks. To copy the portable wrappers and set
|
|
47
|
+
`core.hooksPath=.githooks` for this repository only:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
npx --no-install wendkeep init --git-commit-hooks --yes
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Custom hooks are never overwritten silently. When `init` finds a conflict it preserves the file.
|
|
54
|
+
Review it and rerun with `--force` only when replacement is intended; the previous file is retained
|
|
55
|
+
as `.bak`.
|
|
56
|
+
A custom `core.hooksPath` is also a conflict and remains untouched without `--force`.
|
|
57
|
+
|
|
58
|
+
## Examples
|
|
59
|
+
|
|
60
|
+
### Prepare a commit
|
|
61
|
+
|
|
62
|
+
Create JSON matching `schema/commit-message-v1.schema.json`. Declare authority and evidence
|
|
63
|
+
references, but do not provide `tasks`, `tests`, `fresh`, or `verified`. Runtime derives tasks from
|
|
64
|
+
completed canonical Task Contracts. Tests come only from `[sensor:<id>]` sensors executed by the
|
|
65
|
+
collector; `[phase:verify]` alone is never a result. Sensors
|
|
66
|
+
declared in an Envelope must exactly match the canonical reexecution in IDs, configuration,
|
|
67
|
+
command, severity, and result; only that reexecution emits a `Tests` line. The remote gate
|
|
68
|
+
re-executes each sensor in the checkout for that exact commit SHA. Every
|
|
69
|
+
published reference gets a re-derived SHA-256 digest. ADR/design validate artifact ID and path;
|
|
70
|
+
tasks containing `[req:]` require a versioned, sanitized `spec` reference that defines every
|
|
71
|
+
requirement. Evidence Envelope, Verdict, receipt, and TDD attestation may participate in local
|
|
72
|
+
validation, but are omitted from remote Evidence: worktree/session/branch IDs are not published,
|
|
73
|
+
and self-contained consistency is not promoted to proof. A message claiming them as
|
|
74
|
+
`fresh`/`verified` is rejected with `WENDKEEP_COMMIT_REMOTE_PROOF_UNAVAILABLE`. The fixed trailers
|
|
75
|
+
`Remote-Proof-Scope: git,authority,tasks,spec,sensors` and `Local-Causal-Proof: unpublished` make
|
|
76
|
+
that boundary explicit. Range re-derives authority/artifacts, task/spec, Git `Scope`, and
|
|
77
|
+
config/sensors from the SHA, and only canonical reexecution emits `Tests`. `Co-Authored-By` is
|
|
78
|
+
omitted until a trusted identity registry can resolve it.
|
|
79
|
+
|
|
80
|
+
The normal authority is the causal ADR:
|
|
81
|
+
|
|
82
|
+
```json
|
|
83
|
+
{ "authority": { "kind": "adr", "adr": "ADR-1234", "ref": "docs/ADR-1234.md", "issue": "#123" } }
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Only when no causal change/ADR exists may the native harness declare the fallback below. `issue`
|
|
87
|
+
must be `#NNN` and `design` must be versioned in the same commit under
|
|
88
|
+
`docs/superpowers/specs/` or `plans/`:
|
|
89
|
+
|
|
90
|
+
```json
|
|
91
|
+
{
|
|
92
|
+
"authority": {
|
|
93
|
+
"kind": "native",
|
|
94
|
+
"issue": "#40",
|
|
95
|
+
"design": "docs/superpowers/specs/approved-design.md"
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Runtime observes effective profile `OFF`, no causal context/change/lease or ADR, and the issue in the
|
|
101
|
+
design. This mode emits unique `Authority: native-no-causal-change`, `Issue`, and `Design` trailers. Free text, unversioned
|
|
102
|
+
design, stale/unverified proof, or a missing body/tests fail closed.
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
git add <product-files>
|
|
106
|
+
npx --no-install wendkeep commit context --input commit-input.json
|
|
107
|
+
git commit -m "feat(scope): draft"
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
`commit context` calculates the staged diff SHA-256 and stores the sanitized context at
|
|
111
|
+
`.git/wendkeep-commit-input.json`, outside the working tree. `prepare-commit-msg` replaces the draft
|
|
112
|
+
with the canonical message; `commit-msg` validates it and consumes the context. If the index changes,
|
|
113
|
+
the context becomes stale and must be recreated.
|
|
114
|
+
`commit-msg` rereads context, compares the complete message and staged hash/files, and consumes
|
|
115
|
+
context only after success. Merge, squash, and amend clear incompatible context so it cannot leak
|
|
116
|
+
to the next commit. `--message-file` stays inside the repository or Git directory.
|
|
117
|
+
|
|
118
|
+
Other commands:
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
npx --no-install wendkeep commit render --input commit-input.json
|
|
122
|
+
npx --no-install wendkeep commit validate --message-file .git/COMMIT_EDITMSG
|
|
123
|
+
npx --no-install wendkeep commit context --clear
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Objectively trivial commits remain unchanged. Implementation
|
|
127
|
+
commits (`feat`, `fix`, `refactor`, and `perf`) require a Conventional Commit subject with an ADR or
|
|
128
|
+
the restricted native fallback above, Capability, Evidence, Tasks, Tests, and Scope sections, the
|
|
129
|
+
staged hash, and a `WendKeep-Commit: v1` trailer. Amend, merge, and squash never receive duplicate or
|
|
130
|
+
invented proof.
|
|
131
|
+
|
|
132
|
+
## Privacy and fail-closed behavior
|
|
133
|
+
|
|
134
|
+
- Embedded absolute paths, any configured/default Vault, `.brain`, session registries, PII, and secrets are rejected
|
|
135
|
+
before persistence.
|
|
136
|
+
- `reported`, `legacy-unbound`, `stale`, and `unproven` evidence cannot be presented as proof.
|
|
137
|
+
- Context holds sanitized references and diff metadata, never private Vault content.
|
|
138
|
+
- `--no-verify` is not accepted: CI validates every new commit, including merges and novel resolutions.
|
|
139
|
+
|
|
140
|
+
## Expected result
|
|
141
|
+
|
|
142
|
+
A deterministic, self-contained message with no private material, the hash of the committed index,
|
|
143
|
+
and coherent causal trailers.
|
|
144
|
+
|
|
145
|
+
## Common errors and diagnosis
|
|
146
|
+
|
|
147
|
+
`wendkeep doctor` reports `[commit-hooks] healthy`, `disabled`, `missing`, or `drift` and remains
|
|
148
|
+
read-only. After review, recover missing or divergent files with:
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
npx --no-install wendkeep init --git-commit-hooks --force --yes
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
When abandoning a commit, remove only its transient context with
|
|
155
|
+
`wendkeep commit context --clear`. No command rewrites history or pushes automatically.
|
|
156
|
+
|
|
157
|
+
## Next steps
|
|
158
|
+
|
|
159
|
+
Review the generated message, commit it, and let the PR range gate detect any local bypass.
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
# Commits baseados em evidências
|
|
2
|
+
|
|
3
|
+
**PT-BR** · [English](../../en/commands/commit.md)
|
|
4
|
+
|
|
5
|
+
## Objetivo
|
|
6
|
+
|
|
7
|
+
Produzir a mesma mensagem auditável em Codex, Claude Code ou outro cliente Git, usando somente
|
|
8
|
+
entrada tipada, referências públicas e o resumo do index staged. O kernel é determinístico e não
|
|
9
|
+
lê o Vault, `.brain`, registros de sessão ou rede.
|
|
10
|
+
|
|
11
|
+
## Quando usar
|
|
12
|
+
|
|
13
|
+
Use antes de commits de implementação `feat`, `fix`, `refactor` ou `perf` que precisam registrar
|
|
14
|
+
autoridade causal, tarefas, testes, escopo e evidência verificável de forma equivalente entre
|
|
15
|
+
harnesses.
|
|
16
|
+
|
|
17
|
+
## Quando não usar
|
|
18
|
+
|
|
19
|
+
Não use para inventar prova, publicar conteúdo privado, reescrever histórico ou automatizar push.
|
|
20
|
+
Commits `docs`, `test` e `chore` dispensam contexto somente quando todos os arquivos alterados são
|
|
21
|
+
objetivamente documentação/testes. Alteração de produto exige o corpo governado mesmo com outro tipo.
|
|
22
|
+
|
|
23
|
+
## Pré-requisitos
|
|
24
|
+
|
|
25
|
+
Execute dentro de um repositório Git, com o WendKeep instalado localmente e os arquivos do produto
|
|
26
|
+
já selecionados no index staged.
|
|
27
|
+
|
|
28
|
+
## Sintaxe
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npx --no-install wendkeep commit context --input <json|-> [--json]
|
|
32
|
+
npx --no-install wendkeep commit context --clear [--json]
|
|
33
|
+
npx --no-install wendkeep commit render --input <json|->
|
|
34
|
+
npx --no-install wendkeep commit prepare --message-file <path> [--source <source>]
|
|
35
|
+
npx --no-install wendkeep commit validate --message-file <path> [--json]
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Opções e códigos de saída
|
|
39
|
+
|
|
40
|
+
- Exit `0`: contexto escrito/limpo ou mensagem válida.
|
|
41
|
+
- Exit `1`: mensagem governada inválida.
|
|
42
|
+
- Exit `2`: argumento, JSON, Git, privacidade ou contexto inválido/stale.
|
|
43
|
+
- `--consume-context` é reservado ao wrapper `commit-msg`; remove o contexto após validação verde.
|
|
44
|
+
|
|
45
|
+
## Instalação opt-in
|
|
46
|
+
|
|
47
|
+
Os hooks Git não são ativados pelo `init` padrão. Para copiar os wrappers portáteis e configurar
|
|
48
|
+
`core.hooksPath=.githooks` somente neste repositório:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
npx --no-install wendkeep init --git-commit-hooks --yes
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Hooks personalizados nunca são sobrescritos silenciosamente. Se o `init` encontrar conflito, ele
|
|
55
|
+
preserva o arquivo. Revise-o e, somente se quiser substituí-lo, execute novamente com `--force`; o
|
|
56
|
+
arquivo anterior fica em `.bak`.
|
|
57
|
+
Um `core.hooksPath` customizado também é conflito: sem `--force` ele permanece intocado.
|
|
58
|
+
|
|
59
|
+
## Exemplos
|
|
60
|
+
|
|
61
|
+
### Preparar um commit
|
|
62
|
+
|
|
63
|
+
Crie um JSON conforme `schema/commit-message-v1.schema.json`. Declare autoridade e referências de
|
|
64
|
+
evidência, mas não envie `tasks`, `tests`, `fresh` ou `verified`. O runtime deriva tarefas do
|
|
65
|
+
checklist canônico com Task Contracts concluídos. Testes vêm somente de sensores declarados por
|
|
66
|
+
`[sensor:<id>]` e executados pelo coletor; `[phase:verify]`
|
|
67
|
+
sozinho nunca é resultado. Sensors declarados no Envelope devem corresponder exatamente em IDs,
|
|
68
|
+
configuração, comando, severidade e resultado à reexecução canônica; apenas essa reexecução gera a
|
|
69
|
+
linha `Tests`. O gate remoto reexecuta o sensor no checkout do SHA correspondente.
|
|
70
|
+
Cada referência publicada recebe digest SHA-256 rederivado. ADR/design validam
|
|
71
|
+
ID/path/artefato. Tasks com `[req:]` exigem uma referência `spec` versionada e sanitizada que defina
|
|
72
|
+
cada requisito. Evidence Envelope, Verdict, receipt e TDD attestation podem participar da validação
|
|
73
|
+
local, mas são omitidos da Evidence remota: não há publicação de IDs de worktree/sessão/branch nem
|
|
74
|
+
promoção de consistência autocontida para prova. Se uma mensagem os alegar como `fresh`/`verified`,
|
|
75
|
+
o range rejeita `WENDKEEP_COMMIT_REMOTE_PROOF_UNAVAILABLE`. Os trailers fixos
|
|
76
|
+
`Remote-Proof-Scope: git,authority,tasks,spec,sensors` e `Local-Causal-Proof: unpublished` tornam
|
|
77
|
+
essa fronteira explícita. No range, authority/artefatos, task/spec, `Scope` Git e config/sensors são
|
|
78
|
+
rederivados do SHA, e apenas a reexecução canônica gera `Tests`. `Co-Authored-By` é
|
|
79
|
+
omitido enquanto não houver identidade registrada confiável.
|
|
80
|
+
|
|
81
|
+
A autoridade normal é a ADR causal:
|
|
82
|
+
|
|
83
|
+
```json
|
|
84
|
+
{ "authority": { "kind": "adr", "adr": "ADR-1234", "ref": "docs/ADR-1234.md", "issue": "#123" } }
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Somente quando não existe change/ADR causal, o harness nativo pode declarar o fallback abaixo.
|
|
88
|
+
`issue` deve ser `#NNN` e `design` precisa estar versionado no mesmo commit sob
|
|
89
|
+
`docs/superpowers/specs/` ou `plans/`:
|
|
90
|
+
|
|
91
|
+
```json
|
|
92
|
+
{
|
|
93
|
+
"authority": {
|
|
94
|
+
"kind": "native",
|
|
95
|
+
"issue": "#40",
|
|
96
|
+
"design": "docs/superpowers/specs/design-aprovado.md"
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
O runtime confirma perfil efetivo `OFF`, ausência de context/change/lease e ADR causal reais, além
|
|
102
|
+
da issue no design. Esse modo gera trailers únicos `Authority: native-no-causal-change`, `Issue` e `Design`. Texto solto,
|
|
103
|
+
design não versionado, prova stale/unverified, corpo ou testes ausentes falham fechados.
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
git add <arquivos-do-produto>
|
|
107
|
+
npx --no-install wendkeep commit context --input commit-input.json
|
|
108
|
+
git commit -m "feat(escopo): rascunho"
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
`commit context` calcula o hash SHA-256 do diff staged e guarda o contexto sanitizado em
|
|
112
|
+
`.git/wendkeep-commit-input.json`, fora do working tree. `prepare-commit-msg` substitui o rascunho
|
|
113
|
+
pela mensagem canônica; `commit-msg` valida e consome o contexto. Se o index mudar, o contexto fica
|
|
114
|
+
stale e deve ser recriado.
|
|
115
|
+
O `commit-msg` relê o contexto, compara a mensagem inteira e o hash/files staged, e só consome o
|
|
116
|
+
contexto após sucesso. `merge`, `squash` e amend limpam contexto incompatível para não contaminar o
|
|
117
|
+
commit seguinte. `--message-file` fica contido no repositório ou git-dir.
|
|
118
|
+
|
|
119
|
+
Outros comandos:
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
npx --no-install wendkeep commit render --input commit-input.json
|
|
123
|
+
npx --no-install wendkeep commit validate --message-file .git/COMMIT_EDITMSG
|
|
124
|
+
npx --no-install wendkeep commit context --clear
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Commits realmente triviais permanecem intactos. Commits de implementação
|
|
128
|
+
`feat`, `fix`, `refactor` e `perf` exigem assunto Conventional Commit com ADR ou o fallback nativo
|
|
129
|
+
restrito acima, seções Capability, Evidence, Tasks, Tests e Scope, hash staged e trailer
|
|
130
|
+
`WendKeep-Commit: v1`. Amend, merge e squash não recebem corpo duplicado ou prova inventada.
|
|
131
|
+
|
|
132
|
+
## Privacidade e falha segura
|
|
133
|
+
|
|
134
|
+
- Caminhos absolutos mesmo embutidos, qualquer Vault configurado/default, `.brain`, registros de sessão, PII e segredos são
|
|
135
|
+
rejeitados antes da persistência.
|
|
136
|
+
- Evidência `reported`, `legacy-unbound`, `stale` ou `unproven` não pode ser apresentada como prova.
|
|
137
|
+
- O contexto contém referências sanitizadas e metadados do diff, nunca o conteúdo privado do Vault.
|
|
138
|
+
- `--no-verify` não é um fluxo aceito: o CI valida cada commit novo, inclusive merges e resoluções inéditas.
|
|
139
|
+
|
|
140
|
+
## Resultado esperado
|
|
141
|
+
|
|
142
|
+
Uma mensagem determinística, autocontida, sem material privado, com hash do mesmo index que foi
|
|
143
|
+
commitado e trailers causais coerentes.
|
|
144
|
+
|
|
145
|
+
## Erros comuns e diagnóstico
|
|
146
|
+
|
|
147
|
+
`wendkeep doctor` mostra `[commit-hooks] healthy`, `disabled`, `missing` ou `drift` e permanece
|
|
148
|
+
read-only. Para recuperar arquivos ausentes ou divergentes após revisão:
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
npx --no-install wendkeep init --git-commit-hooks --force --yes
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Se um commit for abandonado, limpe apenas o contexto transitório com
|
|
155
|
+
`wendkeep commit context --clear`. Nenhum comando reescreve histórico ou faz push automaticamente.
|
|
156
|
+
|
|
157
|
+
## Próximos passos
|
|
158
|
+
|
|
159
|
+
Revise a mensagem gerada, faça o commit e deixe o gate de range do PR validar qualquer bypass local.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wendkeep",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.87.0",
|
|
4
4
|
"description": "Vault-first persistent memory for AI coding agents, with an optional profile-aware governance runtime: OFF, FLOW, GUIDE, GOVERN, or ASSURE. Local-first and agent-agnostic (Claude Code, Codex, Cursor…).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"workspaces": [
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
"exports": {
|
|
10
10
|
"./harness": "./packages/harness/src/index.mjs",
|
|
11
11
|
"./vault": "./packages/vault/src/index.mjs",
|
|
12
|
+
"./commit": "./packages/commit/src/index.mjs",
|
|
12
13
|
"./hooks/*": "./hooks/*",
|
|
13
14
|
"./src/*": "./src/*",
|
|
14
15
|
"./bin/*": "./bin/*",
|
|
@@ -28,8 +29,10 @@
|
|
|
28
29
|
"bin",
|
|
29
30
|
"src",
|
|
30
31
|
"hooks",
|
|
32
|
+
".githooks",
|
|
31
33
|
"packages",
|
|
32
34
|
"schema",
|
|
35
|
+
"scripts/validate-commit-range.mjs",
|
|
33
36
|
"web/observer",
|
|
34
37
|
"docs/pt-BR/commands/*.md",
|
|
35
38
|
"docs/en/commands/*.md",
|
|
@@ -42,7 +45,7 @@
|
|
|
42
45
|
},
|
|
43
46
|
"scripts": {
|
|
44
47
|
"precheck": "node --check src/capabilities.mjs && node --check src/host-capabilities.mjs && node --check src/task-contracts.mjs && node --check src/task-leases.mjs && node --check src/task.mjs && node --check src/change.mjs && node --check src/archive-operation-lock.mjs && node --check src/worktree.mjs && node --check src/worktree-cleanup.mjs && node --check src/provenance-gate.mjs && node --check src/provenance-sources.mjs && node --check src/receipt-ledger.mjs && node --check src/evidence-envelope.mjs && node --check src/context.mjs && node --check src/active-context-health.mjs && node --check src/active-context-runtime.mjs && node --check hooks/active-context-store.mjs && node --check hooks/change-core.mjs && node --check hooks/brain-inject.mjs && node --check hooks/change-context.mjs && node --check hooks/session-stop.mjs && node --check packages/vault/src/worktree-metadata.mjs && node --check packages/vault/src/evidence-envelope.mjs && node --check packages/vault/src/memory-handoff.mjs && node --check packages/integrations/src/capabilities.mjs && node --check packages/pi/src/index.mjs && node --check src/sync-protocol.mjs && node --check src/sync-outbox.mjs && node --check src/sync-adapters.mjs && node --check src/sync-protocol-cli.mjs && node --check packages/mcp/src/sync.mjs && node --check src/portable.mjs && node --check src/tdd.mjs && node --check src/tdd-attestation.mjs && node --check src/tdd-attestation-store.mjs",
|
|
45
|
-
"check": "node --check scripts/release.mjs && node --check scripts/release-plan.mjs && node --check scripts/release-provenance.mjs && node --check scripts/run-scope.mjs && node --check src/release-provenance.mjs && node --check bin/wendkeep.mjs && node --check packages/cli/src/index.mjs && node --check src/mcp.mjs && node --check src/init.mjs && node --check src/doctor.mjs && node --check src/active-context-health.mjs && node --check src/project-vault.mjs && node --check src/observer-auth.mjs && node --check src/observer-privacy.mjs && node --check src/observer-snapshot.mjs && node --check src/observer-store.mjs && node --check src/observer-memory.mjs && node --check src/observer-memory-publish.mjs && node --check src/observer-sql-store.mjs && node --check src/observer-sql-migrate.mjs && node --check src/observer-sql-publish.mjs && node --check src/observer-transcript-store.mjs && node --check src/observer-server.mjs && node --check src/observer.mjs && node --check src/observer-publish.mjs && node --check src/operating-profile.mjs && node --check src/profile.mjs && node --check src/flow.mjs && node --check src/work-kind.mjs && node --check src/delivery.mjs && node --check web/observer/app.mjs && node --check hooks/observer-publish.mjs && node --check hooks/evidence-context.mjs && node --check hooks/active-context-handoff-evidence.mjs && node --check hooks/evidence-recall.mjs && node --check hooks/memory-scope.mjs && node --check hooks/operating-profile-runtime.mjs && node --check hooks/operating-profile-task-store.mjs && node --check hooks/flow-core.mjs && node --check hooks/flow-protected-policy.mjs && node --check hooks/git-snapshot.mjs && node --check hooks/vault-path-safety.mjs && node --check hooks/vault-runtime-store.mjs && node --check packages/harness/src/index.mjs && node --check packages/harness/src/flow-store.mjs && node --check packages/harness/src/operating-profile.mjs && node --check packages/harness/src/sensors-core.mjs && node --check packages/integrations/src/host-hooks.mjs && node --check packages/integrations/src/hook-envelope.mjs && node --check packages/integrations/src/prompt-content.mjs && node --check packages/integrations/src/transcript-usage.mjs && node --check packages/integrations/src/transcripts.mjs && node --check packages/integrations/src/session-identity.mjs && node --check packages/integrations/src/index.mjs && node --check packages/mcp/src/audit.mjs && node --check packages/mcp/src/cli.mjs && node --check packages/mcp/src/config.mjs && node --check packages/mcp/src/effects.mjs && node --check packages/mcp/src/executor.mjs && node --check packages/mcp/src/server.mjs && node --check packages/mcp/src/stdio.mjs && node --check packages/mcp/src/index.mjs && node --check packages/vault/src/index.mjs && node --check packages/vault/src/project-vault.mjs && node --check packages/vault/src/vault-path-safety.mjs && node --check packages/vault/src/locale.mjs && node --check packages/vault/src/memory-schema.mjs && node --check packages/vault/src/memory-mode.mjs && node --check packages/vault/src/memory-scope.mjs && node --check packages/vault/src/memory-candidate-policy.mjs && node --check packages/vault/src/evidence-recall.mjs && node --check packages/vault/src/memory-handoff.mjs && node --check packages/vault/src/memory-store.mjs && node --check packages/vault/src/validate-core.mjs && node --check packages/vault/src/validate-memory.mjs",
|
|
48
|
+
"check": "node --check scripts/validate-commit-range.mjs && node --check packages/commit/src/index.mjs && node --check packages/commit/src/cli.mjs && node --check packages/commit/src/git-runtime.mjs && node --check src/git-commit-hooks.mjs && node --check scripts/release.mjs && node --check scripts/release-plan.mjs && node --check scripts/release-provenance.mjs && node --check scripts/run-scope.mjs && node --check src/release-provenance.mjs && node --check bin/wendkeep.mjs && node --check packages/cli/src/index.mjs && node --check src/mcp.mjs && node --check src/init.mjs && node --check src/doctor.mjs && node --check src/active-context-health.mjs && node --check src/project-vault.mjs && node --check src/observer-auth.mjs && node --check src/observer-privacy.mjs && node --check src/observer-snapshot.mjs && node --check src/observer-store.mjs && node --check src/observer-memory.mjs && node --check src/observer-memory-publish.mjs && node --check src/observer-sql-store.mjs && node --check src/observer-sql-migrate.mjs && node --check src/observer-sql-publish.mjs && node --check src/observer-transcript-store.mjs && node --check src/observer-server.mjs && node --check src/observer.mjs && node --check src/observer-publish.mjs && node --check src/operating-profile.mjs && node --check src/profile.mjs && node --check src/flow.mjs && node --check src/work-kind.mjs && node --check src/delivery.mjs && node --check web/observer/app.mjs && node --check hooks/observer-publish.mjs && node --check hooks/evidence-context.mjs && node --check hooks/active-context-handoff-evidence.mjs && node --check hooks/evidence-recall.mjs && node --check hooks/memory-scope.mjs && node --check hooks/operating-profile-runtime.mjs && node --check hooks/operating-profile-task-store.mjs && node --check hooks/flow-core.mjs && node --check hooks/flow-protected-policy.mjs && node --check hooks/git-snapshot.mjs && node --check hooks/vault-path-safety.mjs && node --check hooks/vault-runtime-store.mjs && node --check packages/harness/src/index.mjs && node --check packages/harness/src/flow-store.mjs && node --check packages/harness/src/operating-profile.mjs && node --check packages/harness/src/sensors-core.mjs && node --check packages/integrations/src/host-hooks.mjs && node --check packages/integrations/src/hook-envelope.mjs && node --check packages/integrations/src/prompt-content.mjs && node --check packages/integrations/src/transcript-usage.mjs && node --check packages/integrations/src/transcripts.mjs && node --check packages/integrations/src/session-identity.mjs && node --check packages/integrations/src/index.mjs && node --check packages/mcp/src/audit.mjs && node --check packages/mcp/src/cli.mjs && node --check packages/mcp/src/config.mjs && node --check packages/mcp/src/effects.mjs && node --check packages/mcp/src/executor.mjs && node --check packages/mcp/src/server.mjs && node --check packages/mcp/src/stdio.mjs && node --check packages/mcp/src/index.mjs && node --check packages/vault/src/index.mjs && node --check packages/vault/src/project-vault.mjs && node --check packages/vault/src/vault-path-safety.mjs && node --check packages/vault/src/locale.mjs && node --check packages/vault/src/memory-schema.mjs && node --check packages/vault/src/memory-mode.mjs && node --check packages/vault/src/memory-scope.mjs && node --check packages/vault/src/memory-candidate-policy.mjs && node --check packages/vault/src/evidence-recall.mjs && node --check packages/vault/src/memory-handoff.mjs && node --check packages/vault/src/memory-store.mjs && node --check packages/vault/src/validate-core.mjs && node --check packages/vault/src/validate-memory.mjs",
|
|
46
49
|
"test": "node --test --test-concurrency=2",
|
|
47
50
|
"test:core": "node scripts/run-scope.mjs core",
|
|
48
51
|
"release": "node scripts/release.mjs",
|
|
@@ -34,6 +34,7 @@ Usage:
|
|
|
34
34
|
--no-companions Skip companion plugins/MCP entirely.
|
|
35
35
|
--no-colors Skip the Obsidian color system (.obsidian snippet + graph groups).
|
|
36
36
|
--vscode-worktree-tasks Create local, Git-excluded VS Code tasks for managed worktrees.
|
|
37
|
+
--git-commit-hooks Opt in to .githooks + local core.hooksPath for evidence commits.
|
|
37
38
|
--dotcontext-mcp <v> dotcontext MCP placement: auto (default; skip project entry
|
|
38
39
|
if already global), project, or none.
|
|
39
40
|
--dotcontext-hooks <v> dotcontext hooks: full (default), light (no PostToolUse), none.
|
|
@@ -53,6 +54,7 @@ Usage:
|
|
|
53
54
|
Uses explicit CAS/conflicts and an offline outbox; --remote path or --url HTTPS.
|
|
54
55
|
|
|
55
56
|
wendkeep doctor [--vault P] Health check. --scope core|runtime · --strict for CI/release.
|
|
57
|
+
wendkeep commit <sub> Evidence-based Git commits: context | render | prepare | validate.
|
|
56
58
|
wendkeep portable <sub> Shared authored state: status | export | import | diff.
|
|
57
59
|
Default file: .wendkeep/portable/state.json; private runtime stays local.
|
|
58
60
|
wendkeep mcp <serve|config> Native semantic MCP over stdio, or client config generation.
|
|
@@ -232,6 +234,9 @@ async function main(argv) {
|
|
|
232
234
|
} else if (cmd === 'capabilities') {
|
|
233
235
|
const { CAPABILITIES_HELP } = await import('../../../src/capabilities.mjs');
|
|
234
236
|
process.stdout.write(CAPABILITIES_HELP);
|
|
237
|
+
} else if (cmd === 'commit') {
|
|
238
|
+
const { COMMIT_HELP } = await import('../../commit/src/cli.mjs');
|
|
239
|
+
process.stdout.write(COMMIT_HELP);
|
|
235
240
|
} else {
|
|
236
241
|
process.stdout.write(HELP);
|
|
237
242
|
}
|
|
@@ -245,7 +250,7 @@ async function main(argv) {
|
|
|
245
250
|
// `sync` starts with `init` and resolves the freshly bound Vault itself. Pre-resolving
|
|
246
251
|
// here would prevent that repair step from reporting a corrupt binding as its own
|
|
247
252
|
// first-stage failure (and could never make it as far as the guarded init).
|
|
248
|
-
&& !['init', 'sync', 'worktree', 'hook', 'observer', 'mcp', 'capabilities', '--version', '-v', '--help', '-h', 'help'].includes(cmd)) {
|
|
253
|
+
&& !['init', 'sync', 'worktree', 'hook', 'observer', 'mcp', 'capabilities', 'commit', '--version', '-v', '--help', '-h', 'help'].includes(cmd)) {
|
|
249
254
|
await preferProjectVault(rest);
|
|
250
255
|
}
|
|
251
256
|
switch (cmd) {
|
|
@@ -262,6 +267,11 @@ async function main(argv) {
|
|
|
262
267
|
process.exit(runDoctor(rest));
|
|
263
268
|
break;
|
|
264
269
|
}
|
|
270
|
+
case 'commit': {
|
|
271
|
+
const { runCommit } = await import('../../commit/src/cli.mjs');
|
|
272
|
+
process.exit(runCommit(rest));
|
|
273
|
+
break;
|
|
274
|
+
}
|
|
265
275
|
case 'portable': {
|
|
266
276
|
const { runPortable } = await import('../../../src/portable.mjs');
|
|
267
277
|
process.exit(runPortable(rest));
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
|
|
3
|
+
import { renderCommitMessage } from './commit-message.mjs';
|
|
4
|
+
import {
|
|
5
|
+
buildCommitInput,
|
|
6
|
+
clearCommitContext,
|
|
7
|
+
prepareCommitMessageFile,
|
|
8
|
+
validateCommitMessageFile,
|
|
9
|
+
writeCommitContext,
|
|
10
|
+
} from './git-runtime.mjs';
|
|
11
|
+
|
|
12
|
+
export const COMMIT_HELP = `wendkeep commit — evidence-based Git commit policy
|
|
13
|
+
|
|
14
|
+
Usage:
|
|
15
|
+
wendkeep commit context --input <json|-> [--json]
|
|
16
|
+
wendkeep commit context --clear [--json]
|
|
17
|
+
wendkeep commit render --input <json|->
|
|
18
|
+
wendkeep commit prepare --message-file <path> [--source <source>]
|
|
19
|
+
wendkeep commit validate --message-file <path> [--consume-context] [--json]
|
|
20
|
+
|
|
21
|
+
The context is stored under the repository Git directory, never in the Vault or working tree.
|
|
22
|
+
`;
|
|
23
|
+
|
|
24
|
+
function option(argv, name) {
|
|
25
|
+
const index = argv.indexOf(name);
|
|
26
|
+
if (index >= 0) return argv[index + 1] || '';
|
|
27
|
+
return argv.find((item) => item.startsWith(`${name}=`))?.slice(name.length + 1) || '';
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function readInput(path) {
|
|
31
|
+
if (!path) throw Object.assign(new Error('--input is required'), { code: 'WENDKEEP_COMMIT_ARGUMENT' });
|
|
32
|
+
const source = path === '-' ? readFileSync(0, 'utf8') : readFileSync(path, 'utf8');
|
|
33
|
+
return JSON.parse(source);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function outputJson(value) {
|
|
37
|
+
process.stdout.write(`${JSON.stringify(value)}\n`);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function runCommit(argv, { cwd = process.cwd() } = {}) {
|
|
41
|
+
const [subcommand, ...rest] = argv;
|
|
42
|
+
const json = rest.includes('--json');
|
|
43
|
+
try {
|
|
44
|
+
if (!subcommand || subcommand === 'help' || rest.includes('--help') || rest.includes('-h')) {
|
|
45
|
+
process.stdout.write(COMMIT_HELP);
|
|
46
|
+
return 0;
|
|
47
|
+
}
|
|
48
|
+
if (subcommand === 'context') {
|
|
49
|
+
const result = rest.includes('--clear')
|
|
50
|
+
? clearCommitContext({ cwd })
|
|
51
|
+
: writeCommitContext(readInput(option(rest, '--input')), { cwd });
|
|
52
|
+
if (json) outputJson(rest.includes('--clear') ? result : { path: result.path, schema_version: 1 });
|
|
53
|
+
else process.stdout.write(`${rest.includes('--clear') ? 'cleared' : 'written'}: ${result.path}\n`);
|
|
54
|
+
return 0;
|
|
55
|
+
}
|
|
56
|
+
if (subcommand === 'render') {
|
|
57
|
+
const input = buildCommitInput(readInput(option(rest, '--input')), { cwd });
|
|
58
|
+
process.stdout.write(renderCommitMessage(input));
|
|
59
|
+
return 0;
|
|
60
|
+
}
|
|
61
|
+
if (subcommand === 'prepare') {
|
|
62
|
+
const result = prepareCommitMessageFile({
|
|
63
|
+
messageFile: option(rest, '--message-file'),
|
|
64
|
+
source: option(rest, '--source'),
|
|
65
|
+
cwd,
|
|
66
|
+
});
|
|
67
|
+
if (json) outputJson(result);
|
|
68
|
+
return 0;
|
|
69
|
+
}
|
|
70
|
+
if (subcommand === 'validate') {
|
|
71
|
+
const result = validateCommitMessageFile({
|
|
72
|
+
messageFile: option(rest, '--message-file'),
|
|
73
|
+
consumeContext: rest.includes('--consume-context'),
|
|
74
|
+
cwd,
|
|
75
|
+
});
|
|
76
|
+
if (json) outputJson(result);
|
|
77
|
+
if (!result.ok) {
|
|
78
|
+
process.stderr.write(`WENDKEEP_COMMIT_MESSAGE_INVALID\n${result.errors.map((error) => `- ${error}`).join('\n')}\n`);
|
|
79
|
+
return 1;
|
|
80
|
+
}
|
|
81
|
+
return 0;
|
|
82
|
+
}
|
|
83
|
+
process.stderr.write(`wendkeep commit: unknown subcommand "${subcommand}"\n`);
|
|
84
|
+
return 2;
|
|
85
|
+
} catch (error) {
|
|
86
|
+
process.stderr.write(`${error.code || 'WENDKEEP_COMMIT_ERROR'}: ${error.message}\n`);
|
|
87
|
+
return 2;
|
|
88
|
+
}
|
|
89
|
+
}
|