adr-kit 0.2.5 → 0.2.7
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/README.md +47 -39
- package/README.zh.md +43 -36
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +10 -11
- package/dist/cli.js.map +1 -1
- package/dist/commands/accept.d.ts.map +1 -1
- package/dist/commands/accept.js +12 -14
- package/dist/commands/accept.js.map +1 -1
- package/dist/commands/decide.d.ts.map +1 -1
- package/dist/commands/decide.js +3 -2
- package/dist/commands/decide.js.map +1 -1
- package/dist/commands/init.js +2 -2
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/instructions.d.ts.map +1 -1
- package/dist/commands/instructions.js +24 -25
- package/dist/commands/instructions.js.map +1 -1
- package/dist/commands/list.d.ts.map +1 -1
- package/dist/commands/list.js +14 -14
- package/dist/commands/list.js.map +1 -1
- package/dist/commands/propose.d.ts.map +1 -1
- package/dist/commands/propose.js +12 -5
- package/dist/commands/propose.js.map +1 -1
- package/dist/commands/reject.d.ts +1 -1
- package/dist/commands/reject.d.ts.map +1 -1
- package/dist/commands/reject.js +8 -20
- package/dist/commands/reject.js.map +1 -1
- package/dist/commands/show.d.ts.map +1 -1
- package/dist/commands/show.js +16 -2
- package/dist/commands/show.js.map +1 -1
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +15 -14
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/supersede.d.ts.map +1 -1
- package/dist/commands/supersede.js +7 -2
- package/dist/commands/supersede.js.map +1 -1
- package/dist/core/adr.d.ts +10 -4
- package/dist/core/adr.d.ts.map +1 -1
- package/dist/core/adr.js +14 -23
- package/dist/core/adr.js.map +1 -1
- package/dist/core/git.d.ts +9 -0
- package/dist/core/git.d.ts.map +1 -0
- package/dist/core/git.js +22 -0
- package/dist/core/git.js.map +1 -0
- package/dist/core/repository.d.ts +11 -0
- package/dist/core/repository.d.ts.map +1 -1
- package/dist/core/repository.js +92 -16
- package/dist/core/repository.js.map +1 -1
- package/dist/core/templates.d.ts +7 -7
- package/dist/core/templates.d.ts.map +1 -1
- package/dist/core/templates.js +15 -25
- package/dist/core/templates.js.map +1 -1
- package/dist/core/tool-integrations.d.ts.map +1 -1
- package/dist/core/tool-integrations.js +33 -26
- package/dist/core/tool-integrations.js.map +1 -1
- package/dist/core/validate.d.ts +6 -0
- package/dist/core/validate.d.ts.map +1 -1
- package/dist/core/validate.js +103 -94
- package/dist/core/validate.js.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -8,9 +8,9 @@
|
|
|
8
8
|
<p>
|
|
9
9
|
<a href="https://www.npmjs.com/package/adr-kit"><img src="https://img.shields.io/npm/v/adr-kit?style=flat-square&color=0e7490" alt="npm version" /></a>
|
|
10
10
|
<a href="https://www.npmjs.com/package/adr-kit"><img src="https://img.shields.io/npm/dm/adr-kit?style=flat-square&color=0e7490" alt="npm downloads" /></a>
|
|
11
|
-
<a href="https://nodejs.org/"><img src="https://img.shields.io/node/v/adr-kit?style=flat-square&color=0e7490" alt="node" /></a>
|
|
12
|
-
<a href="https://github.com/luochang212/adr-kit/actions/workflows/ci.yml"><img src="https://github.com/luochang212/adr-kit/actions/workflows/ci.yml/badge.svg" alt="ci" /></a>
|
|
13
11
|
<a href="https://github.com/luochang212/adr-kit/blob/main/LICENSE"><img src="https://img.shields.io/npm/l/adr-kit?style=flat-square&color=0e7490" alt="license" /></a>
|
|
12
|
+
<a href="https://zread.ai/luochang212/adr-kit"><img src="https://img.shields.io/badge/%E2%80%8B-zread-0e7490?style=flat-square&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTQuOTYxNTYgMS42MDAxSDIuMjQxNTZDMS44ODgxIDEuNjAwMSAxLjYwMTU2IDEuODg2NjQgMS42MDE1NiAyLjI0MDFWNC45NjAxQzEuNjAxNTYgNS4zMTM1NiAxLjg4ODEgNS42MDAxIDIuMjQxNTYgNS42MDAxSDQuOTYxNTZDNS4zMTUwMiA1LjYwMDEgNS42MDE1NiA1LjMxMzU2IDUuNjAxNTYgNC45NjAxVjIuMjQwMUM1LjYwMTU2IDEuODg2NjQgNS4zMTUwMiAxLjYwMDEgNC45NjE1NiAxLjYwMDFaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik00Ljk2MTU2IDEwLjM5OTlIMi4yNDE1NkMxLjg4ODEgMTAuMzk5OSAxLjYwMTU2IDEwLjY4NjQgMS42MDE1NiAxMS4wMzk5VjEzLjc1OTlDMS42MDE1NiAxNC4xMTM0IDEuODg4MSAxNC4zOTk5IDIuMjQxNTYgMTQuMzk5OUg0Ljk2MTU2QzUuMzE1MDIgMTQuMzk5OSA1LjYwMTU2IDE0LjExMzQgNS42MDE1NiAxMy43NTk5VjExLjAzOTlDNS42MDE1NiAxMC42ODY0IDUuMzE1MDIgMTAuMzk5OSA0Ljk2MTU2IDEwLjM5OTlaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik0xMy43NTg0IDEuNjAwMUgxMS4wMzg0QzEwLjY4NSAxLjYwMDEgMTAuMzk4NCAxLjg4NjY0IDEwLjM5ODQgMi4yNDAxVjQuOTYwMUMxMC4zOTg0IDUuMzEzNTYgMTAuNjg1IDUuNjAwMSAxMS4wMzg0IDUuNjAwMUgxMy43NTg0QzE0LjExMTkgNS42MDAxIDE0LjM5ODQgNS4zMTM1NiAxNC4zOTg0IDQuOTYwMVYyLjI0MDFDMTQuMzk4NCAxLjg4NjY0IDE0LjExMTkgMS42MDAxIDEzLjc1ODQgMS42MDAxWiIgZmlsbD0iI2ZmZiIvPgo8cGF0aCBkPSJNNCAxMkwxMiA0TDQgMTJaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik00IDEyTDEyIDQiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPgo8L3N2Zz4K&logoColor=ffffff" alt="zread" /></a>
|
|
13
|
+
<a href="https://github.com/luochang212/adr-kit/actions/workflows/ci.yml"><img src="https://github.com/luochang212/adr-kit/actions/workflows/ci.yml/badge.svg" alt="ci" /></a>
|
|
14
14
|
</p>
|
|
15
15
|
|
|
16
16
|
<p>
|
|
@@ -18,8 +18,10 @@
|
|
|
18
18
|
</p>
|
|
19
19
|
|
|
20
20
|
ADR Kit turns architecture decisions into plain Markdown files with a
|
|
21
|
-
machine-checkable lifecycle
|
|
22
|
-
|
|
21
|
+
machine-checkable lifecycle. Decisions are durable records
|
|
22
|
+
(**accepted / superseded**); proposals are ephemeral drafts that either become
|
|
23
|
+
a decision or vanish. It borrows the spec-driven spirit of
|
|
24
|
+
[OpenSpec](https://github.com/Fission-AI/OpenSpec)
|
|
23
25
|
and the decision-record discipline of agent-native codebases: every record
|
|
24
26
|
must say what problem it solves, what it chose, and what it gave up.
|
|
25
27
|
|
|
@@ -36,7 +38,7 @@ Requires Node.js 20.19 or later.
|
|
|
36
38
|
npm install -g adr-kit
|
|
37
39
|
cd your-project
|
|
38
40
|
adrkit init
|
|
39
|
-
adrkit
|
|
41
|
+
adrkit decide "Use SQLite for session storage"
|
|
40
42
|
```
|
|
41
43
|
|
|
42
44
|
`adrkit init` creates an `adr/` directory:
|
|
@@ -45,37 +47,40 @@ adrkit propose "Use SQLite for session storage"
|
|
|
45
47
|
adr/
|
|
46
48
|
├── config.yaml # project context and per-status rules
|
|
47
49
|
├── README.md # repository conventions
|
|
48
|
-
├──
|
|
49
|
-
|
|
50
|
-
└── rejected/ # rejected proposals, frozen
|
|
50
|
+
├── .gitignore # keeps adr/.drafts/ out of git
|
|
51
|
+
└── decisions/ # decisions, numbered N, immutable history
|
|
51
52
|
```
|
|
52
53
|
|
|
53
|
-
|
|
54
|
+
Proposals are ephemeral drafts in `adr/.drafts/`: `adrkit propose` creates
|
|
55
|
+
one, `adrkit accept` promotes it to a numbered decision, and `adrkit reject`
|
|
56
|
+
discards it without leaving a record. Rejection is recorded in a decision's
|
|
57
|
+
`Alternatives considered`, never as a standalone record.
|
|
58
|
+
|
|
59
|
+
Fill in the decision, then:
|
|
54
60
|
|
|
55
61
|
```bash
|
|
56
62
|
adrkit validate
|
|
57
|
-
adrkit accept "Use SQLite for session storage"
|
|
58
63
|
adrkit list
|
|
59
64
|
```
|
|
60
65
|
|
|
61
66
|
## Commands
|
|
62
67
|
|
|
63
68
|
```text
|
|
64
|
-
adrkit init [path] [--tools <list>]
|
|
65
|
-
adrkit
|
|
66
|
-
adrkit
|
|
67
|
-
adrkit accept <name>
|
|
68
|
-
adrkit reject <name> --reason <text>
|
|
69
|
-
adrkit supersede <name> --by <name>
|
|
70
|
-
adrkit list [--json]
|
|
71
|
-
adrkit show <name>
|
|
72
|
-
adrkit status [--json]
|
|
73
|
-
adrkit instructions [--json]
|
|
69
|
+
adrkit init [path] [--tools <list>] Initialize an ADR Kit repository
|
|
70
|
+
adrkit decide <title> Record an already-made decision (default path)
|
|
71
|
+
adrkit propose <title> Create an ephemeral proposal draft
|
|
72
|
+
adrkit accept <name> Promote a draft to a decision (assigns N)
|
|
73
|
+
adrkit reject <name> [--reason <text>] Discard a draft (leaves no record)
|
|
74
|
+
adrkit supersede <name> --by <name> Mark an accepted decision as superseded
|
|
75
|
+
adrkit list [--json] List decisions and pending drafts
|
|
76
|
+
adrkit show <name> Show a decision or draft
|
|
77
|
+
adrkit status [--json] Show lifecycle counts and validity
|
|
78
|
+
adrkit instructions [--json] Print the next step; flag pending drafts as ready or needing work
|
|
74
79
|
adrkit validate [name] [--all] [--json] Validate one record or the repository
|
|
75
80
|
adrkit update [--tools <list>] Rewrite AI tool integrations
|
|
76
|
-
adrkit config [--json]
|
|
77
|
-
adrkit completion <bash|zsh|fish>
|
|
78
|
-
adrkit version
|
|
81
|
+
adrkit config [--json] Print the current configuration
|
|
82
|
+
adrkit completion <bash|zsh|fish> Print a shell completion script
|
|
83
|
+
adrkit version Print the version
|
|
79
84
|
```
|
|
80
85
|
|
|
81
86
|
`<name>` resolves by title, file name, or decision number (`1`).
|
|
@@ -95,27 +100,31 @@ Every record is YAML front matter followed by a Markdown body:
|
|
|
95
100
|
|
|
96
101
|
```markdown
|
|
97
102
|
---
|
|
98
|
-
status:
|
|
103
|
+
status: accepted
|
|
99
104
|
date: 2026-08-19
|
|
105
|
+
commit: abc1234
|
|
100
106
|
---
|
|
101
107
|
|
|
102
|
-
# ADR: Use SQLite for session storage
|
|
108
|
+
# ADR: 1 Use SQLite for session storage
|
|
103
109
|
|
|
104
110
|
## Problem
|
|
105
111
|
...
|
|
106
112
|
```
|
|
107
113
|
|
|
108
114
|
The `date` field records when the current status was reached; the CLI
|
|
109
|
-
stamps it at every lifecycle move
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
115
|
+
stamps it at every lifecycle move, alongside the git `commit` the decision
|
|
116
|
+
was recorded against. Decisions are immutable history; the current facts
|
|
117
|
+
live in code, not in the record.
|
|
118
|
+
|
|
119
|
+
- **Decisions** (`adr/decisions/N-slug.md`) are `accepted` or `superseded`
|
|
120
|
+
and require `Problem`, `Decision`, `Alternatives considered`, and
|
|
121
|
+
`Consequences`; proposal-era headings are rejected by `validate`.
|
|
122
|
+
- **Drafts** (`adr/.drafts/YYYY-MM-DD-slug.md`) are ephemeral proposals with
|
|
123
|
+
`status: proposed`, require `Problem`, `Proposal`, `Alternatives
|
|
124
|
+
considered`, `Acceptance criteria`, and `Risks`, and are never checked by
|
|
125
|
+
`validate` - `adrkit accept` validates a draft right before promoting it.
|
|
126
|
+
- **Rejected** ideas are not standalone records: a decision's
|
|
127
|
+
`Alternatives considered` documents what was considered and why it lost.
|
|
119
128
|
- **Superseded** decisions stay in `adr/decisions/` as history, with the
|
|
120
129
|
replacing decision in the front matter: `status: superseded` plus
|
|
121
130
|
`superseded-by: N`.
|
|
@@ -170,10 +179,9 @@ history, and current facts live in code, not in the record.
|
|
|
170
179
|
ADR that says what was decided and what was given up stays useful.
|
|
171
180
|
- **Alternatives are mandatory.** A decision recorded without what it beat
|
|
172
181
|
invites re-litigation.
|
|
173
|
-
- **Lifecycle is mechanical, not editorial.**
|
|
174
|
-
accepted
|
|
175
|
-
|
|
176
|
-
shape.
|
|
182
|
+
- **Lifecycle is mechanical, not editorial.** Promoting a draft and retiring
|
|
183
|
+
an accepted decision are commands (`accept`, `supersede`), and `validate`
|
|
184
|
+
enforces the resulting shape.
|
|
177
185
|
- **Agents are first-class users.** The format is plain Markdown, paths are
|
|
178
186
|
predictable, and agent-facing commands print machine-readable `--json`
|
|
179
187
|
output; the rest reject the flag instead of silently ignoring it.
|
package/README.zh.md
CHANGED
|
@@ -8,17 +8,17 @@
|
|
|
8
8
|
<p>
|
|
9
9
|
<a href="https://www.npmjs.com/package/adr-kit"><img src="https://img.shields.io/npm/v/adr-kit?style=flat-square&color=0e7490" alt="npm version" /></a>
|
|
10
10
|
<a href="https://www.npmjs.com/package/adr-kit"><img src="https://img.shields.io/npm/dm/adr-kit?style=flat-square&color=0e7490" alt="npm downloads" /></a>
|
|
11
|
-
<a href="https://nodejs.org/"><img src="https://img.shields.io/node/v/adr-kit?style=flat-square&color=0e7490" alt="node" /></a>
|
|
12
|
-
<a href="https://github.com/luochang212/adr-kit/actions/workflows/ci.yml"><img src="https://github.com/luochang212/adr-kit/actions/workflows/ci.yml/badge.svg" alt="ci" /></a>
|
|
13
11
|
<a href="https://github.com/luochang212/adr-kit/blob/main/LICENSE"><img src="https://img.shields.io/npm/l/adr-kit?style=flat-square&color=0e7490" alt="license" /></a>
|
|
12
|
+
<a href="https://zread.ai/luochang212/adr-kit"><img src="https://img.shields.io/badge/%E2%80%8B-zread-0e7490?style=flat-square&logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTQuOTYxNTYgMS42MDAxSDIuMjQxNTZDMS44ODgxIDEuNjAwMSAxLjYwMTU2IDEuODg2NjQgMS42MDE1NiAyLjI0MDFWNC45NjAxQzEuNjAxNTYgNS4zMTM1NiAxLjg4ODEgNS42MDAxIDIuMjQxNTYgNS42MDAxSDQuOTYxNTZDNS4zMTUwMiA1LjYwMDEgNS42MDE1NiA1LjMxMzU2IDUuNjAxNTYgNC45NjAxVjIuMjQwMUM1LjYwMTU2IDEuODg2NjQgNS4zMTUwMiAxLjYwMDEgNC45NjE1NiAxLjYwMDFaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik00Ljk2MTU2IDEwLjM5OTlIMi4yNDE1NkMxLjg4ODEgMTAuMzk5OSAxLjYwMTU2IDEwLjY4NjQgMS42MDE1NiAxMS4wMzk5VjEzLjc1OTlDMS42MDE1NiAxNC4xMTM0IDEuODg4MSAxNC4zOTk5IDIuMjQxNTYgMTQuMzk5OUg0Ljk2MTU2QzUuMzE1MDIgMTQuMzk5OSA1LjYwMTU2IDE0LjExMzQgNS42MDE1NiAxMy43NTk5VjExLjAzOTlDNS42MDE1NiAxMC42ODY0IDUuMzE1MDIgMTAuMzk5OSA0Ljk2MTU2IDEwLjM5OTlaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik0xMy43NTg0IDEuNjAwMUgxMS4wMzg0QzEwLjY4NSAxLjYwMDEgMTAuMzk4NCAxLjg4NjY0IDEwLjM5ODQgMi4yNDAxVjQuOTYwMUMxMC4zOTg0IDUuMzEzNTYgMTAuNjg1IDUuNjAwMSAxMS4wMzg0IDUuNjAwMUgxMy43NTg0QzE0LjExMTkgNS42MDAxIDE0LjM5ODQgNS4zMTM1NiAxNC4zOTg0IDQuOTYwMVYyLjI0MDFDMTQuMzk4NCAxLjg4NjY0IDE0LjExMTkgMS42MDAxIDEzLjc1ODQgMS42MDAxWiIgZmlsbD0iI2ZmZiIvPgo8cGF0aCBkPSJNNCAxMkwxMiA0TDQgMTJaIiBmaWxsPSIjZmZmIi8%2BCjxwYXRoIGQ9Ik00IDEyTDEyIDQiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPgo8L3N2Zz4K&logoColor=ffffff" alt="zread" /></a>
|
|
13
|
+
<a href="https://github.com/luochang212/adr-kit/actions/workflows/ci.yml"><img src="https://github.com/luochang212/adr-kit/actions/workflows/ci.yml/badge.svg" alt="ci" /></a>
|
|
14
14
|
</p>
|
|
15
15
|
|
|
16
16
|
<p>
|
|
17
17
|
<img src="./assets/readme-banner.png" alt="ADR Kit" width="100%" />
|
|
18
18
|
</p>
|
|
19
19
|
|
|
20
|
-
ADR Kit 把架构决策变成纯 Markdown
|
|
21
|
-
|
|
20
|
+
ADR Kit 把架构决策变成纯 Markdown 文件,并带有机检的生命周期。决策是持久记录
|
|
21
|
+
(**accepted / superseded**);提案是临时草稿,要么变成决策、要么消失。它借鉴了
|
|
22
22
|
[OpenSpec](https://github.com/Fission-AI/OpenSpec) 的 spec-driven 思路,以及
|
|
23
23
|
agent 原生代码库的决策记录纪律:每条记录都必须说明它解决什么问题、选择了什么、
|
|
24
24
|
放弃了什么。
|
|
@@ -36,7 +36,7 @@ agent 原生代码库的决策记录纪律:每条记录都必须说明它解
|
|
|
36
36
|
npm install -g adr-kit
|
|
37
37
|
cd your-project
|
|
38
38
|
adrkit init
|
|
39
|
-
adrkit
|
|
39
|
+
adrkit decide "使用 SQLite 存储会话"
|
|
40
40
|
```
|
|
41
41
|
|
|
42
42
|
`adrkit init` 会创建 `adr/` 目录:
|
|
@@ -45,37 +45,39 @@ adrkit propose "使用 SQLite 存储会话"
|
|
|
45
45
|
adr/
|
|
46
46
|
├── config.yaml # 项目上下文与分状态规则
|
|
47
47
|
├── README.md # 仓库约定
|
|
48
|
-
├──
|
|
49
|
-
|
|
50
|
-
└── rejected/ # 已拒绝提案,冻结保存
|
|
48
|
+
├── .gitignore # 让 adr/.drafts/ 不进 git
|
|
49
|
+
└── decisions/ # 决策,按 N 编号,不可变历史
|
|
51
50
|
```
|
|
52
51
|
|
|
53
|
-
|
|
52
|
+
提案是 `adr/.drafts/` 里的临时草稿:`adrkit propose` 创建一条,
|
|
53
|
+
`adrkit accept` 把它提升为编号决策,`adrkit reject` 直接丢弃、不留下任何记录。
|
|
54
|
+
拒绝记录在决策的 `Alternatives considered` 里,从不是独立记录。
|
|
55
|
+
|
|
56
|
+
填写决策内容后:
|
|
54
57
|
|
|
55
58
|
```bash
|
|
56
59
|
adrkit validate
|
|
57
|
-
adrkit accept "使用 SQLite 存储会话"
|
|
58
60
|
adrkit list
|
|
59
61
|
```
|
|
60
62
|
|
|
61
63
|
## 命令
|
|
62
64
|
|
|
63
65
|
```text
|
|
64
|
-
adrkit init [path] [--tools <list>]
|
|
65
|
-
adrkit
|
|
66
|
-
adrkit
|
|
67
|
-
adrkit accept <name>
|
|
68
|
-
adrkit reject <name> --reason <text>
|
|
69
|
-
adrkit supersede <name> --by <name>
|
|
70
|
-
adrkit list [--json]
|
|
71
|
-
adrkit show <name>
|
|
72
|
-
adrkit status [--json]
|
|
73
|
-
adrkit instructions [--json]
|
|
66
|
+
adrkit init [path] [--tools <list>] 初始化 ADR Kit 仓库
|
|
67
|
+
adrkit decide <title> 直接记录已做的决策(默认路径)
|
|
68
|
+
adrkit propose <title> 创建临时提案草稿
|
|
69
|
+
adrkit accept <name> 把草稿提升为决策(分配 N 编号)
|
|
70
|
+
adrkit reject <name> [--reason <text>] 丢弃草稿(不留记录)
|
|
71
|
+
adrkit supersede <name> --by <name> 标记已接受决策被新决策取代
|
|
72
|
+
adrkit list [--json] 列出决策与待决草稿
|
|
73
|
+
adrkit show <name> 查看决策或草稿
|
|
74
|
+
adrkit status [--json] 查看生命周期计数与校验状态
|
|
75
|
+
adrkit instructions [--json] 查看下一步;标注待决草稿已就绪或需修改
|
|
74
76
|
adrkit validate [name] [--all] [--json] 校验单条记录或整个仓库
|
|
75
77
|
adrkit update [--tools <list>] 重写 AI 工具集成文件
|
|
76
|
-
adrkit config [--json]
|
|
77
|
-
adrkit completion <bash|zsh|fish>
|
|
78
|
-
adrkit version
|
|
78
|
+
adrkit config [--json] 查看当前配置
|
|
79
|
+
adrkit completion <bash|zsh|fish> 打印 shell 补全脚本
|
|
80
|
+
adrkit version 查看版本
|
|
79
81
|
```
|
|
80
82
|
|
|
81
83
|
`<name>` 支持按标题、文件名或决策编号(`1`)查找。
|
|
@@ -95,25 +97,30 @@ adrkit version 查看版本
|
|
|
95
97
|
|
|
96
98
|
```markdown
|
|
97
99
|
---
|
|
98
|
-
status:
|
|
100
|
+
status: accepted
|
|
99
101
|
date: 2026-08-19
|
|
102
|
+
commit: abc1234
|
|
100
103
|
---
|
|
101
104
|
|
|
102
|
-
# ADR: 使用 SQLite 存储会话
|
|
105
|
+
# ADR: 1 使用 SQLite 存储会话
|
|
103
106
|
|
|
104
107
|
## Problem
|
|
105
108
|
...
|
|
106
109
|
```
|
|
107
110
|
|
|
108
|
-
`date` 字段记录当前状态达成的日期;CLI
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
`
|
|
115
|
-
-
|
|
116
|
-
|
|
111
|
+
`date` 字段记录当前状态达成的日期;CLI 在每次生命周期迁移时自动盖章,
|
|
112
|
+
同时盖上该决策对应的 git `commit`。决策是不可变历史;当前事实以代码为准,
|
|
113
|
+
不在记录里。
|
|
114
|
+
|
|
115
|
+
- **决策**(`adr/decisions/N-slug.md`)是 `accepted` 或 `superseded`,
|
|
116
|
+
需要 `Problem`、`Decision`、`Alternatives considered`、`Consequences`;
|
|
117
|
+
`validate` 会拒绝提案时代的标题出现在已接受决策中。
|
|
118
|
+
- **草稿**(`adr/.drafts/YYYY-MM-DD-slug.md`)是 `status: proposed` 的临时
|
|
119
|
+
提案,需要 `Problem`、`Proposal`、`Alternatives considered`、
|
|
120
|
+
`Acceptance criteria`、`Risks`,`validate` 不检查它们——`adrkit accept`
|
|
121
|
+
在提升前才校验草稿。
|
|
122
|
+
- **被否决**的想法不是独立记录:决策的 `Alternatives considered` 记录了
|
|
123
|
+
考虑过什么、为什么落选。
|
|
117
124
|
- **Superseded** 决策保留在 `adr/decisions/` 作为历史,front matter 指向
|
|
118
125
|
取代它的决策:`status: superseded` 加 `superseded-by: N`。
|
|
119
126
|
`adrkit supersede <旧> --by <新>` 完成改写;
|
|
@@ -160,8 +167,8 @@ ADR Kit 站在两个项目之上,两者角色不同:
|
|
|
160
167
|
- **记录是事实来源。** 代码注释会腐化,文档会漂移;一条写明了决定与代价的
|
|
161
168
|
ADR 会持续有用。
|
|
162
169
|
- **备选方案是强制项。** 没有记录被否决方案的决策,是在邀请未来的重复争论。
|
|
163
|
-
- **生命周期是机械操作,不是编辑操作。**
|
|
164
|
-
|
|
170
|
+
- **生命周期是机械操作,不是编辑操作。** 提升草稿、退役已接受决策都是命令
|
|
171
|
+
(`accept`、`supersede`),`validate` 强制检查结果形态。
|
|
165
172
|
- **Agent 是一等用户。** 纯 Markdown、可预测的路径、需要时可输出 JSON。
|
|
166
173
|
|
|
167
174
|
## 开发
|
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AA+CA,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CA8HzC"}
|
package/dist/cli.js
CHANGED
|
@@ -17,15 +17,18 @@ import { updateCommand } from './commands/update.js';
|
|
|
17
17
|
import { validateCommand } from './commands/validate.js';
|
|
18
18
|
const HELP = `adrkit ${VERSION} - A lightweight ADR workflow for humans and agents
|
|
19
19
|
|
|
20
|
+
Decisions are durable records in adr/decisions/. Proposals are ephemeral drafts
|
|
21
|
+
in adr/.drafts/ that are promoted by accept or discarded by reject.
|
|
22
|
+
|
|
20
23
|
Usage:
|
|
21
24
|
adrkit init [path] [--tools <list>] Initialize an ADR Kit repository
|
|
22
|
-
adrkit
|
|
23
|
-
adrkit
|
|
24
|
-
adrkit accept <name>
|
|
25
|
-
adrkit reject <name> --reason <reason>
|
|
25
|
+
adrkit decide <title> Record a decision (default path)
|
|
26
|
+
adrkit propose <title> Create an ephemeral proposal draft
|
|
27
|
+
adrkit accept <name> Promote a draft to a decision (assigns the next number)
|
|
28
|
+
adrkit reject <name> [--reason <reason>] Discard a draft (leaves no record)
|
|
26
29
|
adrkit supersede <name> --by <name> Mark an accepted decision as superseded
|
|
27
|
-
adrkit list [--json] List
|
|
28
|
-
adrkit show <name> Show a decision
|
|
30
|
+
adrkit list [--json] List decisions and pending drafts
|
|
31
|
+
adrkit show <name> Show a decision or draft
|
|
29
32
|
adrkit status [--json] Show lifecycle counts and validity
|
|
30
33
|
adrkit instructions [--json] Print the next workflow step
|
|
31
34
|
adrkit validate [name] [--all] [--json] Validate one record or the whole repo
|
|
@@ -104,11 +107,7 @@ export function main(argv) {
|
|
|
104
107
|
}
|
|
105
108
|
case 'reject': {
|
|
106
109
|
requireTitle(rest, 'reject');
|
|
107
|
-
|
|
108
|
-
if (reason === undefined) {
|
|
109
|
-
throw new Error('reject requires --reason <reason>');
|
|
110
|
-
}
|
|
111
|
-
console.log(rejectCommand(rest[0], reason, process.cwd()));
|
|
110
|
+
console.log(rejectCommand(rest[0], values.reason, process.cwd()));
|
|
112
111
|
return;
|
|
113
112
|
}
|
|
114
113
|
case 'supersede': {
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,MAAM,IAAI,GAAG,UAAU,OAAO
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"accept.d.ts","sourceRoot":"","sources":["../../src/commands/accept.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"accept.d.ts","sourceRoot":"","sources":["../../src/commands/accept.ts"],"names":[],"mappings":"AAQA,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CA+BhE"}
|
package/dist/commands/accept.js
CHANGED
|
@@ -1,34 +1,32 @@
|
|
|
1
1
|
import { existsSync } from 'node:fs';
|
|
2
2
|
import { join } from 'node:path';
|
|
3
3
|
import { requireRoot } from '../core/config.js';
|
|
4
|
-
import {
|
|
4
|
+
import { gitHead } from '../core/git.js';
|
|
5
|
+
import { folderPath, nextDecisionNumber, removeRecord, resolveDraft, writeRecord } from '../core/repository.js';
|
|
5
6
|
import { droppedSections, proposalToDecision } from '../core/templates.js';
|
|
6
|
-
import { formatIssues,
|
|
7
|
+
import { formatIssues, validateDraft } from '../core/validate.js';
|
|
7
8
|
export function acceptCommand(query, cwd) {
|
|
8
9
|
const root = requireRoot(cwd);
|
|
9
|
-
const
|
|
10
|
-
if (
|
|
11
|
-
throw new Error(`"${query}" is not a proposal (it is in ${record.folder})`);
|
|
12
|
-
}
|
|
13
|
-
if (/^\d+\s+/.test(record.title)) {
|
|
10
|
+
const draft = resolveDraft(root, query);
|
|
11
|
+
if (/^\d+\s+/.test(draft.title)) {
|
|
14
12
|
throw new Error('proposal title must not start with a number; ADR Kit assigns decision numbers');
|
|
15
13
|
}
|
|
16
|
-
const issues =
|
|
14
|
+
const issues = validateDraft(root, draft);
|
|
17
15
|
if (issues.length > 0) {
|
|
18
|
-
throw new Error(`
|
|
16
|
+
throw new Error(`draft is not ready; fix it before accepting:\n${formatIssues(issues)}`);
|
|
19
17
|
}
|
|
20
18
|
const number = nextDecisionNumber(root);
|
|
21
|
-
const slug =
|
|
19
|
+
const slug = draft.fileName.replace(/^\d{4}-\d{2}-\d{2}-/, '').replace(/\.md$/, '');
|
|
22
20
|
const fileName = `${number}-${slug}.md`;
|
|
23
21
|
const path = join(folderPath(root, 'decisions'), fileName);
|
|
24
22
|
if (existsSync(path)) {
|
|
25
23
|
throw new Error(`decision already exists: adr/decisions/${fileName}`);
|
|
26
24
|
}
|
|
27
|
-
const content = proposalToDecision(
|
|
25
|
+
const content = proposalToDecision(draft, number, gitHead(root));
|
|
28
26
|
writeRecord(root, 'decisions', fileName, content);
|
|
29
|
-
removeRecord(
|
|
30
|
-
let output = `accepted adr
|
|
31
|
-
const dropped = droppedSections(
|
|
27
|
+
removeRecord(draft);
|
|
28
|
+
let output = `accepted adr/.drafts/${draft.fileName} as adr/decisions/${fileName}`;
|
|
29
|
+
const dropped = droppedSections(draft);
|
|
32
30
|
if (dropped.length > 0) {
|
|
33
31
|
output += `\nwarning: dropped section(s) with no place in an accepted decision: ${dropped
|
|
34
32
|
.map((heading) => `## ${heading}`)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"accept.js","sourceRoot":"","sources":["../../src/commands/accept.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,
|
|
1
|
+
{"version":3,"file":"accept.js","sourceRoot":"","sources":["../../src/commands/accept.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAChH,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC3E,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAElE,MAAM,UAAU,aAAa,CAAC,KAAa,EAAE,GAAW;IACtD,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IAC9B,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACxC,IAAI,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CAAC,+EAA+E,CAAC,CAAC;IACnG,CAAC;IAED,MAAM,MAAM,GAAG,aAAa,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAC1C,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,iDAAiD,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAC3F,CAAC;IAED,MAAM,MAAM,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC;IACxC,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,qBAAqB,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IACpF,MAAM,QAAQ,GAAG,GAAG,MAAM,IAAI,IAAI,KAAK,CAAC;IACxC,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,WAAW,CAAC,EAAE,QAAQ,CAAC,CAAC;IAC3D,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CAAC,0CAA0C,QAAQ,EAAE,CAAC,CAAC;IACxE,CAAC;IAED,MAAM,OAAO,GAAG,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IACjE,WAAW,CAAC,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;IAClD,YAAY,CAAC,KAAK,CAAC,CAAC;IACpB,IAAI,MAAM,GAAG,wBAAwB,KAAK,CAAC,QAAQ,qBAAqB,QAAQ,EAAE,CAAC;IACnF,MAAM,OAAO,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;IACvC,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,wEAAwE,OAAO;aACtF,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,MAAM,OAAO,EAAE,CAAC;aACjC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;IAClB,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decide.d.ts","sourceRoot":"","sources":["../../src/commands/decide.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"decide.d.ts","sourceRoot":"","sources":["../../src/commands/decide.ts"],"names":[],"mappings":"AAQA,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAkBhE"}
|
package/dist/commands/decide.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { existsSync } from 'node:fs';
|
|
2
2
|
import { join } from 'node:path';
|
|
3
3
|
import { readConfig, requireRoot } from '../core/config.js';
|
|
4
|
+
import { gitHead } from '../core/git.js';
|
|
4
5
|
import { folderPath, nextDecisionNumber, writeRecord } from '../core/repository.js';
|
|
5
6
|
import { decisionTemplate } from '../core/templates.js';
|
|
6
7
|
import { slugify } from '../core/slug.js';
|
|
@@ -19,8 +20,8 @@ export function decideCommand(title, cwd) {
|
|
|
19
20
|
if (existsSync(path)) {
|
|
20
21
|
throw new Error(`decision already exists: adr/decisions/${fileName}`);
|
|
21
22
|
}
|
|
22
|
-
const content = decisionTemplate(number, trimmed, readConfig(root).context);
|
|
23
|
+
const content = decisionTemplate(number, trimmed, readConfig(root).context, gitHead(root));
|
|
23
24
|
writeRecord(root, 'decisions', fileName, content);
|
|
24
|
-
return `created adr/decisions/${fileName}\n\nfill in the
|
|
25
|
+
return `created adr/decisions/${fileName}\n\nfill in the decision and validate it with:\n adrkit validate ${number}`;
|
|
25
26
|
}
|
|
26
27
|
//# sourceMappingURL=decide.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decide.js","sourceRoot":"","sources":["../../src/commands/decide.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpF,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE1C,MAAM,UAAU,aAAa,CAAC,KAAa,EAAE,GAAW;IACtD,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IAC7C,CAAC;IACD,IAAI,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CAAC,sEAAsE,CAAC,CAAC;IAC1F,CAAC;IACD,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IAC9B,MAAM,MAAM,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC;IACxC,MAAM,QAAQ,GAAG,GAAG,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC;IACpD,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,WAAW,CAAC,EAAE,QAAQ,CAAC,CAAC;IAC3D,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CAAC,0CAA0C,QAAQ,EAAE,CAAC,CAAC;IACxE,CAAC;IACD,MAAM,OAAO,GAAG,gBAAgB,CAAC,MAAM,EAAE,OAAO,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"decide.js","sourceRoot":"","sources":["../../src/commands/decide.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpF,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE1C,MAAM,UAAU,aAAa,CAAC,KAAa,EAAE,GAAW;IACtD,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IAC7C,CAAC;IACD,IAAI,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CAAC,sEAAsE,CAAC,CAAC;IAC1F,CAAC;IACD,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IAC9B,MAAM,MAAM,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC;IACxC,MAAM,QAAQ,GAAG,GAAG,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC;IACpD,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,WAAW,CAAC,EAAE,QAAQ,CAAC,CAAC;IAC3D,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CAAC,0CAA0C,QAAQ,EAAE,CAAC,CAAC;IACxE,CAAC;IACD,MAAM,OAAO,GAAG,gBAAgB,CAAC,MAAM,EAAE,OAAO,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IAC3F,WAAW,CAAC,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;IAClD,OAAO,yBAAyB,QAAQ,qEAAqE,MAAM,EAAE,CAAC;AACxH,CAAC"}
|
package/dist/commands/init.js
CHANGED
|
@@ -11,8 +11,8 @@ export function initCommand(targetDir, toolsValue) {
|
|
|
11
11
|
...integrationSummary(root, integrations),
|
|
12
12
|
'',
|
|
13
13
|
'Next:',
|
|
14
|
-
' adrkit
|
|
15
|
-
' adrkit
|
|
14
|
+
' adrkit decide "use sqlite for sessions" # record a decision (default path)',
|
|
15
|
+
' adrkit propose "your first decision" # draft a proposal for review',
|
|
16
16
|
].join('\n');
|
|
17
17
|
}
|
|
18
18
|
//# sourceMappingURL=init.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,UAAU,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAErG,MAAM,UAAU,WAAW,CAAC,SAAiB,EAAE,UAAmB;IAChE,MAAM,KAAK,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC;IACrC,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,cAAc,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IAC3D,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC;IACzD,MAAM,YAAY,GAAG,qBAAqB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACxD,OAAO;QACL,0BAA0B,IAAI,EAAE;QAChC,GAAG,KAAK;QACR,GAAG,kBAAkB,CAAC,IAAI,EAAE,YAAY,CAAC;QACzC,EAAE;QACF,OAAO;QACP,
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,UAAU,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAErG,MAAM,UAAU,WAAW,CAAC,SAAiB,EAAE,UAAmB;IAChE,MAAM,KAAK,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC;IACrC,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,cAAc,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IAC3D,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC;IACzD,MAAM,YAAY,GAAG,qBAAqB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACxD,OAAO;QACL,0BAA0B,IAAI,EAAE;QAChC,GAAG,KAAK;QACR,GAAG,kBAAkB,CAAC,IAAI,EAAE,YAAY,CAAC;QACzC,EAAE;QACF,OAAO;QACP,8EAA8E;QAC9E,yEAAyE;KAC1E,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instructions.d.ts","sourceRoot":"","sources":["../../src/commands/instructions.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"instructions.d.ts","sourceRoot":"","sources":["../../src/commands/instructions.ts"],"names":[],"mappings":"AAIA,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,UAAQ,GAAG,MAAM,CA2GvE"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { findRoot } from '../core/config.js';
|
|
2
|
-
import { listRecords } from '../core/repository.js';
|
|
3
|
-
import { formatIssues,
|
|
2
|
+
import { listDrafts, listRecords } from '../core/repository.js';
|
|
3
|
+
import { formatIssues, validateDraft, validateRepository } from '../core/validate.js';
|
|
4
4
|
export function instructionsCommand(cwd, asJson = false) {
|
|
5
5
|
const root = findRoot(cwd);
|
|
6
6
|
if (root === undefined) {
|
|
@@ -9,19 +9,18 @@ export function instructionsCommand(cwd, asJson = false) {
|
|
|
9
9
|
'',
|
|
10
10
|
'Next:',
|
|
11
11
|
' adrkit init',
|
|
12
|
-
' adrkit
|
|
12
|
+
' adrkit decide "your first decision"',
|
|
13
13
|
].join('\n');
|
|
14
14
|
return asJson
|
|
15
15
|
? JSON.stringify({ step: 'init', message: output }, null, 2)
|
|
16
16
|
: output;
|
|
17
17
|
}
|
|
18
|
-
// Pending
|
|
19
|
-
// elsewhere in the repo must not hide the proposals that are ready.
|
|
20
|
-
//
|
|
21
|
-
// which reports the parse error as an issue.
|
|
22
|
-
let records;
|
|
18
|
+
// Pending drafts come first: promoting or discarding them is the steer, and a
|
|
19
|
+
// draft elsewhere in the repo must not hide the proposals that are ready.
|
|
20
|
+
// A corrupt durable record falls back to the repository-level validation
|
|
21
|
+
// output, which reports the parse error as an issue.
|
|
23
22
|
try {
|
|
24
|
-
|
|
23
|
+
listRecords(root);
|
|
25
24
|
}
|
|
26
25
|
catch {
|
|
27
26
|
const issues = validateRepository(root);
|
|
@@ -37,42 +36,42 @@ export function instructionsCommand(cwd, asJson = false) {
|
|
|
37
36
|
? JSON.stringify({ step: 'fix-validation', issues, message: output }, null, 2)
|
|
38
37
|
: output;
|
|
39
38
|
}
|
|
40
|
-
const
|
|
41
|
-
if (
|
|
39
|
+
const drafts = listDrafts(root);
|
|
40
|
+
if (drafts.length > 0) {
|
|
42
41
|
const ready = [];
|
|
43
42
|
const needsWork = {};
|
|
44
|
-
for (const
|
|
45
|
-
const issues =
|
|
43
|
+
for (const draft of drafts) {
|
|
44
|
+
const issues = validateDraft(root, draft);
|
|
46
45
|
if (issues.length === 0) {
|
|
47
|
-
ready.push(
|
|
46
|
+
ready.push(draft.fileName);
|
|
48
47
|
}
|
|
49
48
|
else {
|
|
50
|
-
needsWork[
|
|
49
|
+
needsWork[draft.fileName] = issues.map((issue) => issue.message);
|
|
51
50
|
}
|
|
52
51
|
}
|
|
53
52
|
const readySet = new Set(ready);
|
|
54
|
-
const lines = [`${
|
|
55
|
-
for (const
|
|
56
|
-
if (readySet.has(
|
|
57
|
-
lines.push(` ✓ ${
|
|
53
|
+
const lines = [`${drafts.length} draft${drafts.length === 1 ? '' : 's'} pending:`];
|
|
54
|
+
for (const draft of drafts) {
|
|
55
|
+
if (readySet.has(draft.fileName)) {
|
|
56
|
+
lines.push(` ✓ ${draft.fileName} validated - ready to accept`);
|
|
58
57
|
}
|
|
59
58
|
else {
|
|
60
|
-
const first = needsWork[
|
|
61
|
-
lines.push(` ✗ ${
|
|
59
|
+
const first = needsWork[draft.fileName]?.[0] ?? 'validation failed';
|
|
60
|
+
lines.push(` ✗ ${draft.fileName} ${first}`);
|
|
62
61
|
}
|
|
63
62
|
}
|
|
64
63
|
lines.push('', 'Next:');
|
|
65
64
|
for (const name of ready) {
|
|
66
|
-
lines.push(` adrkit accept ${name} #
|
|
65
|
+
lines.push(` adrkit accept ${name} # promote to a decision`);
|
|
67
66
|
}
|
|
68
67
|
for (const name of Object.keys(needsWork)) {
|
|
69
|
-
lines.push(` adrkit
|
|
68
|
+
lines.push(` adrkit reject ${name} # or fix adr/.drafts/${name} and accept it`);
|
|
70
69
|
}
|
|
71
70
|
const output = lines.join('\n');
|
|
72
71
|
return asJson
|
|
73
72
|
? JSON.stringify({
|
|
74
73
|
step: 'decide',
|
|
75
|
-
pending:
|
|
74
|
+
pending: drafts.map((draft) => draft.fileName),
|
|
76
75
|
readyToAccept: ready,
|
|
77
76
|
needsWork,
|
|
78
77
|
message: output,
|
|
@@ -97,7 +96,7 @@ export function instructionsCommand(cwd, asJson = false) {
|
|
|
97
96
|
'No proposals waiting.',
|
|
98
97
|
'',
|
|
99
98
|
'Next:',
|
|
100
|
-
' adrkit propose "
|
|
99
|
+
' adrkit propose "a decision you are unsure about" # ephemeral draft',
|
|
101
100
|
' adrkit decide "an already-made decision"',
|
|
102
101
|
].join('\n');
|
|
103
102
|
return asJson
|