tack-cli 0.1.1 → 0.1.2
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 +329 -267
- package/dist/engine/contextPack.js +1 -1
- package/dist/index.js +48 -43
- package/dist/lib/cli.d.ts +4 -2
- package/dist/lib/cli.js +6 -5
- package/dist/lib/files.d.ts +3 -0
- package/dist/lib/files.js +78 -9
- package/dist/lib/logger.d.ts +12 -0
- package/dist/lib/logger.js +53 -1
- package/dist/lib/ndjson.d.ts +1 -0
- package/dist/lib/ndjson.js +70 -10
- package/dist/lib/signals.d.ts +8 -0
- package/dist/mcp.js +8 -1
- package/dist/plain/colors.d.ts +4 -0
- package/dist/plain/colors.js +12 -0
- package/dist/plain/watch.js +20 -3
- package/dist/ui/Logo.js +1 -1
- package/dist/ui/Watch.js +32 -3
- package/package.json +53 -52
package/README.md
CHANGED
|
@@ -1,267 +1,329 @@
|
|
|
1
|
-
# tack
|
|
2
|
-
|
|
3
|
-
[](https://www.npmjs.com/package/tack-cli) [](LICENSE)
|
|
4
|
-
|
|
5
|
-
Architecture drift guard.
|
|
6
|
-
|
|
7
|
-
## Why Tack
|
|
8
|
-
|
|
9
|
-
`tack`
|
|
10
|
-
|
|
11
|
-
It gives agents and humans a shared project memory across sessions:
|
|
12
|
-
|
|
13
|
-
- Captures architecture
|
|
14
|
-
- Detects architecture signals in code and tracks drift over time.
|
|
15
|
-
- Generates handoff artifacts (`.md` + canonical `.json`) for the next agent
|
|
16
|
-
- Preserves machine history in append-only logs.
|
|
17
|
-
-
|
|
18
|
-
|
|
19
|
-
## Persistent Context in `.tack/`
|
|
20
|
-
|
|
21
|
-
All state lives in `./.tack
|
|
22
|
-
|
|
23
|
-
- `context.md`, `goals.md`, `assumptions.md`, `open_questions.md`
|
|
24
|
-
- `decisions.md` -
|
|
25
|
-
- `_notes.ndjson`
|
|
26
|
-
- `spec.yaml`
|
|
27
|
-
- `_audit.yaml`
|
|
28
|
-
- `_drift.yaml`
|
|
29
|
-
- `_logs.ndjson`
|
|
30
|
-
- `handoffs/*.md` and `handoffs/*.json`
|
|
31
|
-
- `verification.md`
|
|
32
|
-
|
|
33
|
-
Agents and tools
|
|
34
|
-
|
|
35
|
-
-
|
|
36
|
-
-
|
|
37
|
-
|
|
38
|
-
## Change Tracking Workflow
|
|
39
|
-
|
|
40
|
-
- `tack status` updates `_audit.yaml
|
|
41
|
-
- `tack watch` continuously rescans and appends events to `_logs.ndjson`.
|
|
42
|
-
- `tack handoff` packages context + machine state + git deltas for the next session.
|
|
43
|
-
- `tack log` and `tack note` store decisions and notes that future agents can reuse.
|
|
44
|
-
|
|
45
|
-
## Install from npm
|
|
46
|
-
|
|
47
|
-
Use Tack in any project without cloning:
|
|
48
|
-
|
|
49
|
-
**Run without installing (npx):**
|
|
50
|
-
|
|
51
|
-
```bash
|
|
52
|
-
npx tack-cli init
|
|
53
|
-
npx tack-cli status
|
|
54
|
-
npx tack-cli handoff
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
**Or install in your project (local):**
|
|
58
|
-
|
|
59
|
-
```bash
|
|
60
|
-
npm install tack-cli
|
|
61
|
-
npx tack-cli init
|
|
62
|
-
# or: ./node_modules/.bin/tack init
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
**Or install globally:**
|
|
66
|
-
|
|
67
|
-
```bash
|
|
68
|
-
npm install -g tack-cli
|
|
69
|
-
tack init
|
|
70
|
-
tack status
|
|
71
|
-
tack handoff
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
> **Note:** If global install on Windows fails with `EEXIST` or cleanup errors, remove any existing `tack` or `tack-cli` in `npm root -g`, or use `npx tack-cli` instead.
|
|
75
|
-
|
|
76
|
-
## Build from source
|
|
77
|
-
|
|
78
|
-
To develop or contribute:
|
|
79
|
-
|
|
80
|
-
```bash
|
|
81
|
-
npm install
|
|
82
|
-
npm run build
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
Optional global link for local development:
|
|
86
|
-
|
|
87
|
-
```bash
|
|
88
|
-
npm link
|
|
89
|
-
# now `tack` is available globally on this machine
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
Or package for use in another project:
|
|
93
|
-
|
|
94
|
-
```bash
|
|
95
|
-
npm pack
|
|
96
|
-
# then install the tarball in another project if desired
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
## Usage
|
|
100
|
-
|
|
101
|
-
From any project directory:
|
|
102
|
-
|
|
103
|
-
```bash
|
|
104
|
-
node /absolute/path/to/tack/dist/index.js init
|
|
105
|
-
node /absolute/path/to/tack/dist/index.js status
|
|
106
|
-
node /absolute/path/to/tack/dist/index.js watch
|
|
107
|
-
node /absolute/path/to/tack/dist/index.js handoff
|
|
108
|
-
node /absolute/path/to/tack/dist/index.js mcp
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
Within the `tack` repo itself:
|
|
112
|
-
|
|
113
|
-
```bash
|
|
114
|
-
node dist/index.js help
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
## `tack watch` Preview
|
|
118
|
-
|
|
119
|
-
](https://www.npmjs.com/package/tack-cli) [](LICENSE)
|
|
4
|
+
|
|
5
|
+
Architecture drift guard. You declare the spec; Tack checks your code against it.
|
|
6
|
+
|
|
7
|
+
## Why Tack
|
|
8
|
+
|
|
9
|
+
`tack` keeps a single, shared picture of your architecture and how it changes over time.
|
|
10
|
+
|
|
11
|
+
It gives agents and humans a shared project memory that survives across sessions:
|
|
12
|
+
|
|
13
|
+
- Captures your intended architecture in `spec.yaml` and a small set of context docs.
|
|
14
|
+
- Detects architecture signals in code and tracks drift from the spec over time.
|
|
15
|
+
- Generates handoff artifacts (`.md` + canonical `.json`) for the next agent or session.
|
|
16
|
+
- Preserves machine history in append-only logs instead of ad-hoc console output.
|
|
17
|
+
- Records explicit decisions and notes so future sessions can see why changes happened.
|
|
18
|
+
|
|
19
|
+
## Persistent Context in `.tack/`
|
|
20
|
+
|
|
21
|
+
All Tack state lives in `./.tack/`, so you can stop and resume work (or swap agents) without losing context:
|
|
22
|
+
|
|
23
|
+
- `context.md`, `goals.md`, `assumptions.md`, `open_questions.md` – human-written intent and constraints.
|
|
24
|
+
- `decisions.md` – append-only decision history with a short reason for each choice.
|
|
25
|
+
- `_notes.ndjson` – timestamped agent notes between sessions (newline-delimited JSON).
|
|
26
|
+
- `spec.yaml` – your architecture contract: allowed/forbidden systems, constraints, optional `domains` map.
|
|
27
|
+
- `_audit.yaml` – latest detector snapshot of what the codebase actually does.
|
|
28
|
+
- `_drift.yaml` – unresolved/accepted/rejected drift items between spec and reality.
|
|
29
|
+
- `_logs.ndjson` – append-only machine event stream (what Tack saw and when).
|
|
30
|
+
- `handoffs/*.md` and `handoffs/*.json` – handoff packages for the next session.
|
|
31
|
+
- `verification.md` – validation steps that get pulled into handoffs.
|
|
32
|
+
|
|
33
|
+
Agents and tools read and write this state in two main ways:
|
|
34
|
+
|
|
35
|
+
- Through the `tack-mcp` server (Model Context Protocol), which exposes typed context resources and safe write-back tools.
|
|
36
|
+
- By reading and appending to files under `.tack/`, where human-authored docs and machine-managed state live side by side.
|
|
37
|
+
|
|
38
|
+
## Change Tracking Workflow
|
|
39
|
+
|
|
40
|
+
- `tack status` runs a scan, updates `_audit.yaml`, and computes drift against your spec.
|
|
41
|
+
- `tack watch` continuously rescans on file changes and appends events to `_logs.ndjson`.
|
|
42
|
+
- `tack handoff` packages context + machine state + git deltas for the next session.
|
|
43
|
+
- `tack log` and `tack note` store decisions and notes that future agents and humans can reuse.
|
|
44
|
+
|
|
45
|
+
## Install from npm
|
|
46
|
+
|
|
47
|
+
Use Tack in any project without cloning:
|
|
48
|
+
|
|
49
|
+
**Run without installing (npx):**
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
npx tack-cli init
|
|
53
|
+
npx tack-cli status
|
|
54
|
+
npx tack-cli handoff
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
**Or install in your project (local):**
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
npm install tack-cli
|
|
61
|
+
npx tack-cli init
|
|
62
|
+
# or: ./node_modules/.bin/tack init
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
**Or install globally:**
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
npm install -g tack-cli
|
|
69
|
+
tack init
|
|
70
|
+
tack status
|
|
71
|
+
tack handoff
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
> **Note:** If global install on Windows fails with `EEXIST` or cleanup errors, remove any existing `tack` or `tack-cli` in `npm root -g`, or use `npx tack-cli` instead.
|
|
75
|
+
|
|
76
|
+
## Build from source
|
|
77
|
+
|
|
78
|
+
To develop or contribute:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
npm install
|
|
82
|
+
npm run build
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Optional global link for local development:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
npm link
|
|
89
|
+
# now `tack` is available globally on this machine
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Or package for use in another project:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
npm pack
|
|
96
|
+
# then install the tarball in another project if desired
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Usage
|
|
100
|
+
|
|
101
|
+
From any project directory:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
node /absolute/path/to/tack/dist/index.js init
|
|
105
|
+
node /absolute/path/to/tack/dist/index.js status
|
|
106
|
+
node /absolute/path/to/tack/dist/index.js watch
|
|
107
|
+
node /absolute/path/to/tack/dist/index.js handoff
|
|
108
|
+
node /absolute/path/to/tack/dist/index.js mcp
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Within the `tack` repo itself:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
node dist/index.js help
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## `tack watch` Preview
|
|
118
|
+
|
|
119
|
+

|
|
120
|
+
|
|
121
|
+
## Typical Multi-Session Loop
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
# Session start
|
|
125
|
+
tack status
|
|
126
|
+
|
|
127
|
+
# During work
|
|
128
|
+
tack watch
|
|
129
|
+
|
|
130
|
+
# Record key intent changes
|
|
131
|
+
tack log
|
|
132
|
+
tack note
|
|
133
|
+
|
|
134
|
+
# Session end
|
|
135
|
+
tack handoff
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Project Root Rules
|
|
139
|
+
|
|
140
|
+
Tack looks for the nearest ancestor directory that contains `.tack/` and treats that as the project root. This means you can run `tack status`, `tack watch`, `tack handoff`, `tack log`, `tack note`, and `tack diff` from subdirectories inside an initialized project.
|
|
141
|
+
|
|
142
|
+
If no `.tack/` directory exists in the current directory or any parent, Tack will not try to guess a sibling project. Run Tack from the project root you actually want, or initialize a new project there:
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
cd /path/to/your/project
|
|
146
|
+
tack init
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Legacy migration from `./tack/` to `./.tack/` only happens when that directory looks like old Tack state, not when it is just a separate folder named `tack`.
|
|
150
|
+
|
|
151
|
+
## Using Tack with Agents
|
|
152
|
+
|
|
153
|
+
Tack exposes a small, deterministic engine that agents call into (same inputs → same outputs, no hidden network calls). Agents should read context from `.tack/` and write back only through the documented channels instead of editing machine-managed files directly.
|
|
154
|
+
|
|
155
|
+
### MCP (Model Context Protocol)
|
|
156
|
+
|
|
157
|
+
**Run the MCP server:** From a project that has `.tack/`, run:
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
tack mcp
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
If `tack` is on your PATH (for example after `npm install -g tack-cli` or `npm link` from the Tack repo), that’s all you need. Or run `node /path/to/tack/dist/index.js mcp`. The server reads `.tack/` from the current working directory, so always run it from your **project root**.
|
|
164
|
+
|
|
165
|
+
**Cursor:** In Cursor (Settings → Tools & MCP), add an MCP server with command `tack`, args `["mcp"]`, and **cwd** set to your project root (the directory that contains `.tack/`). If `tack` isn’t on PATH, use command `node` with args `["/path/to/tack/dist/index.js", "mcp"]`, cwd = project root. Restart Cursor after changing MCP config.
|
|
166
|
+
|
|
167
|
+
**Codex CLI:** Add the Tack MCP server to Codex:
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
# With tack-cli on PATH (for example after npm install -g tack-cli)
|
|
171
|
+
codex mcp add tack -- tack mcp
|
|
172
|
+
|
|
173
|
+
# With a local build of this repo
|
|
174
|
+
codex mcp add tack -- node /path/to/tack/dist/index.js mcp
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Then verify it:
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
codex mcp get tack
|
|
181
|
+
codex mcp list
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
Tack reads `.tack/` from the current working directory, and Codex launches MCP servers relative to the Codex session cwd. Start Codex from your **project root** (the directory that contains `.tack/`), for example:
|
|
185
|
+
|
|
186
|
+
```bash
|
|
187
|
+
cd /path/to/your/project
|
|
188
|
+
codex
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
Or:
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
codex -C /path/to/your/project
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
If you update Tack from source, rebuild it with `npm run build` so `dist/index.js` stays current.
|
|
198
|
+
|
|
199
|
+
**Claude Code:** From your project root (the directory that contains `.tack/`), add the Tack MCP server:
|
|
200
|
+
|
|
201
|
+
```bash
|
|
202
|
+
# With tack-cli on PATH (e.g. npm install -g tack-cli)
|
|
203
|
+
claude mcp add --transport stdio tack-mcp -- tack mcp
|
|
204
|
+
|
|
205
|
+
# With npx (no global install)
|
|
206
|
+
claude mcp add --transport stdio tack-mcp -- npx tack-cli mcp
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
On **Windows (native, not WSL)** use the `cmd /c` wrapper for npx:
|
|
210
|
+
|
|
211
|
+
```bash
|
|
212
|
+
claude mcp add --transport stdio tack-mcp -- cmd /c npx tack-cli mcp
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
Then run `/mcp` in Claude Code to confirm the server is connected. Tack reads `.tack/` from the current working directory, so open your project folder in Claude Code so the server runs with the correct cwd.
|
|
216
|
+
|
|
217
|
+
The server (`tack-mcp`) exposes these key resources:
|
|
218
|
+
|
|
219
|
+
- `tack://context/intent` – `context.md`, `goals.md`, `open_questions.md`, `decisions.md`
|
|
220
|
+
- `tack://context/facts` – `implementation_status.md` and `spec.yaml`
|
|
221
|
+
- `tack://context/machine_state` – `_audit.yaml` and `_drift.yaml`
|
|
222
|
+
- `tack://context/decisions_recent` – recent decisions as markdown
|
|
223
|
+
- `tack://handoff/latest` – latest handoff JSON (`.tack/handoffs/*.json`)
|
|
224
|
+
|
|
225
|
+
And these tools for safe write-back:
|
|
226
|
+
|
|
227
|
+
- `log_decision` – appends a decision to `.tack/decisions.md` and logs a `decision` event
|
|
228
|
+
- `log_agent_note` – appends an agent note to `.tack/_notes.ndjson`
|
|
229
|
+
|
|
230
|
+
### Direct File Access
|
|
231
|
+
|
|
232
|
+
Agents without MCP should:
|
|
233
|
+
|
|
234
|
+
- **Read**:
|
|
235
|
+
- `.tack/spec.yaml` — architecture guardrails
|
|
236
|
+
- `.tack/context.md`, `.tack/goals.md`, `.tack/assumptions.md`, `.tack/open_questions.md`
|
|
237
|
+
- `.tack/implementation_status.md`
|
|
238
|
+
- `.tack/_audit.yaml`, `.tack/_drift.yaml`
|
|
239
|
+
- `.tack/verification.md` — validation/verification steps to run after changes
|
|
240
|
+
- `.tack/handoffs/*.json`, `.tack/handoffs/*.md`
|
|
241
|
+
- `.tack/_notes.ndjson` — agent working notes (NDJSON)
|
|
242
|
+
- **Write back**:
|
|
243
|
+
- Append decisions to `.tack/decisions.md` in this format: `- [YYYY-MM-DD] Decision — reason`
|
|
244
|
+
- Prefer the CLI for notes: `tack note --message "..." --type discovered --actor agent:cursor`
|
|
245
|
+
- If the CLI is not available, append NDJSON lines manually to `.tack/_notes.ndjson`
|
|
246
|
+
|
|
247
|
+
Do **not** modify `.tack/_drift.yaml`, `.tack/_audit.yaml`, or `.tack/_logs.ndjson` directly; they are machine-managed and may be overwritten at any time.
|
|
248
|
+
|
|
249
|
+
## Detectors and YAML rules
|
|
250
|
+
|
|
251
|
+
Detection is **YAML-driven**. Bundled rules live in `src/detectors/rules/*.yaml` and ship with the CLI. At runtime Tack also loads any `*.yaml` from `.tack/detectors/` so projects can add or override detectors.
|
|
252
|
+
|
|
253
|
+
Each rule file uses this schema:
|
|
254
|
+
|
|
255
|
+
- **Top-level:** `name`, `displayName`, `signalId`, `category` (`system` | `scope` | `risk`).
|
|
256
|
+
- **`systems`:** list of entries, each with:
|
|
257
|
+
- `id` — system identifier (for example `nextjs`, `prisma`, `stripe`)
|
|
258
|
+
- `packages` — npm package names that imply this system
|
|
259
|
+
- `configFiles` — config files to look for (for example `next.config.js`)
|
|
260
|
+
- `directories` — optional directories (for example `src/jobs`)
|
|
261
|
+
- `routePatterns` — optional regex strings to grep in project files
|
|
262
|
+
|
|
263
|
+
If any of `packages` / `configFiles` / `directories` / `routePatterns` match for a system, one signal is emitted (confidence 1). Invalid YAML or bad regex is skipped without failing the scan. The only detectors still implemented in TypeScript are `multiuser`, `admin`, and `duplicates`; all other primary systems (framework, auth, db, payments, background_jobs, exports) are defined in YAML.
|
|
264
|
+
|
|
265
|
+
## Commands
|
|
266
|
+
|
|
267
|
+
### `init`
|
|
268
|
+
|
|
269
|
+
- Runs a detector sweep
|
|
270
|
+
- Prompts you to classify detected systems as allowed/forbidden/skip
|
|
271
|
+
- Writes initial files under `./.tack/`
|
|
272
|
+
|
|
273
|
+
### `status`
|
|
274
|
+
|
|
275
|
+
- Runs a one-shot scan
|
|
276
|
+
- Updates `./.tack/_audit.yaml`
|
|
277
|
+
- Computes drift and prints summary
|
|
278
|
+
|
|
279
|
+
### `watch`
|
|
280
|
+
|
|
281
|
+
- Starts persistent file watching
|
|
282
|
+
- Re-scans on file changes
|
|
283
|
+
- Creates drift items for new violations/risks/undeclared systems
|
|
284
|
+
- Sends OS notifications for violations and risks
|
|
285
|
+
- Press `q` to quit
|
|
286
|
+
|
|
287
|
+
### `handoff`
|
|
288
|
+
|
|
289
|
+
- Reads context docs + current machine state
|
|
290
|
+
- Reads file-level git changes
|
|
291
|
+
- Writes `./.tack/handoffs/<timestamp>.md`
|
|
292
|
+
- Writes `./.tack/handoffs/<timestamp>.json` (canonical)
|
|
293
|
+
- Includes a **Validation / Verification** section driven by `.tack/verification.md`:
|
|
294
|
+
- Each bullet/numbered item becomes a `verification.steps` entry in JSON and a markdown bullet
|
|
295
|
+
- Intended for humans or external tools to know which commands/checks to run after applying the handoff
|
|
296
|
+
- Tack does **not** execute these commands automatically
|
|
297
|
+
|
|
298
|
+
## Keyboard Controls
|
|
299
|
+
|
|
300
|
+
In selection prompts (`init`, drift options):
|
|
301
|
+
|
|
302
|
+
- `↑` / `↓` to move
|
|
303
|
+
- `Enter` to confirm
|
|
304
|
+
|
|
305
|
+
## Development
|
|
306
|
+
|
|
307
|
+
```bash
|
|
308
|
+
npm run typecheck
|
|
309
|
+
bun test
|
|
310
|
+
npm run dev
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
Optional Bun fast path for build contributors:
|
|
314
|
+
|
|
315
|
+
```bash
|
|
316
|
+
npm run build:bun
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
Optional Bun source-run for contributors who have Bun:
|
|
320
|
+
|
|
321
|
+
```bash
|
|
322
|
+
npm run dev:bun
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
## Notes
|
|
326
|
+
|
|
327
|
+
- Offline-only (no network calls)
|
|
328
|
+
- Writes are guarded to `./.tack/` only
|
|
329
|
+
- Python virtual environments are ignored during scans (`venv`, `.venv`, `site-packages`) to avoid false positives
|
|
@@ -65,7 +65,7 @@ export function parseDecisionsMarkdown(content, file = ".tack/decisions.md") {
|
|
|
65
65
|
const line = (lines[i] ?? "").trim();
|
|
66
66
|
if (!line.startsWith("- "))
|
|
67
67
|
continue;
|
|
68
|
-
const m = line.match(/^-\s*\[(\d{4}-\d{2}-\d{2})\]\s*(.+?)\s
|
|
68
|
+
const m = line.match(/^-\s*\[(\d{4}-\d{2}-\d{2})\]\s*(.+?)\s*(?:—|–|--|-)\s*(.+)$/);
|
|
69
69
|
if (!m)
|
|
70
70
|
continue;
|
|
71
71
|
out.push({
|