runlist 0.0.0 → 0.94.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +1114 -6
- package/assets/app/app.css +283 -0
- package/assets/app/app.mjs +381 -0
- package/assets/app/block-editor.mjs +182 -0
- package/assets/app/block-model.mjs +52 -0
- package/assets/app/document-create.mjs +86 -0
- package/assets/app/document-lifecycle.mjs +36 -0
- package/assets/app/document-stages.mjs +22 -0
- package/assets/app/document-views.mjs +33 -0
- package/assets/app/document-yardstick.mjs +258 -0
- package/assets/app/editor-navigation.mjs +51 -0
- package/assets/app/filing-navigation.mjs +138 -0
- package/assets/app/git-changes.mjs +80 -0
- package/assets/app/git-commit.mjs +46 -0
- package/assets/app/index.html +70 -0
- package/assets/app/library-navigation.mjs +93 -0
- package/assets/app/outline.mjs +18 -0
- package/assets/app/quick-navigation.mjs +52 -0
- package/assets/app/record-navigation.mjs +78 -0
- package/assets/app/recovery-center.mjs +53 -0
- package/assets/app/semantic-search.mjs +14 -0
- package/assets/app/settings.mjs +15 -0
- package/assets/app/shared.mjs +104 -0
- package/assets/app/stage-source.mjs +75 -0
- package/assets/app/template-editor.mjs +47 -0
- package/assets/app/theme.mjs +25 -0
- package/assets/app/transport.mjs +43 -0
- package/assets/contracts/source-editing-v1.md +232 -0
- package/assets/opencode/plugin.js +162 -0
- package/assets/schemas/runlist-record-v1.schema.json +912 -0
- package/bin/dotmd.mjs +5 -0
- package/bin/runlist.mjs +2714 -0
- package/package.json +53 -6
- package/plugins/runlist-codex/.codex-plugin/plugin.json +18 -0
- package/plugins/runlist-codex/bin/runlist-hook +86 -0
- package/plugins/runlist-codex/hooks/hooks.json +16 -0
- package/plugins/runlist-codex/skills/runlist/SKILL.md +25 -0
- package/runlist.config.example.mjs +370 -0
- package/scripts/postinstall.mjs +56 -0
- package/src/agent-context.mjs +201 -0
- package/src/ai.mjs +30 -0
- package/src/app-create.mjs +169 -0
- package/src/app-filing.mjs +139 -0
- package/src/app-git-commits.mjs +48 -0
- package/src/app-git.mjs +180 -0
- package/src/app-library.mjs +152 -0
- package/src/app-lifecycle-worker.mjs +12 -0
- package/src/app-lifecycle.mjs +79 -0
- package/src/app-records.mjs +134 -0
- package/src/app-search.mjs +80 -0
- package/src/app-semantic-search.mjs +105 -0
- package/src/app-service.mjs +208 -0
- package/src/app-yardstick.mjs +269 -0
- package/src/app.mjs +102 -0
- package/src/atomic-mutation.mjs +1736 -0
- package/src/baton.mjs +435 -0
- package/src/body-link.mjs +48 -0
- package/src/bulk-tag.mjs +174 -0
- package/src/check-collapse.mjs +75 -0
- package/src/claude-commands.mjs +75 -0
- package/src/cli-editor.mjs +8 -0
- package/src/code-refs.mjs +545 -0
- package/src/codex-integration.mjs +81 -0
- package/src/color.mjs +14 -0
- package/src/commands.mjs +374 -0
- package/src/completions.mjs +93 -0
- package/src/config-edit.mjs +606 -0
- package/src/config.mjs +705 -0
- package/src/decision-action.mjs +58 -0
- package/src/decision.mjs +220 -0
- package/src/decisions.mjs +787 -0
- package/src/deps.mjs +317 -0
- package/src/desktop-install.mjs +158 -0
- package/src/desktop-runtime.mjs +4 -0
- package/src/desktop.mjs +25 -0
- package/src/diff.mjs +101 -0
- package/src/doctor.mjs +591 -0
- package/src/durable-rename.mjs +55 -0
- package/src/errors-read.mjs +44 -0
- package/src/export.mjs +496 -0
- package/src/extractors.mjs +101 -0
- package/src/filing.mjs +255 -0
- package/src/fix-membership.mjs +134 -0
- package/src/fix-refs.mjs +174 -0
- package/src/flags.mjs +318 -0
- package/src/frontmatter-fix.mjs +195 -0
- package/src/frontmatter.mjs +252 -0
- package/src/git-commit-filters.mjs +32 -0
- package/src/git-commit-protocol.mjs +198 -0
- package/src/git-commit-signing.mjs +75 -0
- package/src/git-commit-store.mjs +26 -0
- package/src/git-commit-support.mjs +16 -0
- package/src/git-commit-worker.mjs +32 -0
- package/src/git.mjs +909 -0
- package/src/glossary-check.mjs +35 -0
- package/src/glossary.mjs +243 -0
- package/src/graph.mjs +298 -0
- package/src/guard.mjs +488 -0
- package/src/health.mjs +212 -0
- package/src/hints.mjs +129 -0
- package/src/host-integration.mjs +339 -0
- package/src/hub-membership.mjs +284 -0
- package/src/hub.mjs +292 -0
- package/src/hud.mjs +436 -0
- package/src/index-file.mjs +163 -0
- package/src/index.mjs +478 -0
- package/src/init.mjs +512 -0
- package/src/install.mjs +222 -0
- package/src/journal-read.mjs +116 -0
- package/src/journal.mjs +472 -0
- package/src/lifecycle.mjs +1444 -0
- package/src/lint.mjs +386 -0
- package/src/managed-path.mjs +192 -0
- package/src/markdown-code-spans.mjs +58 -0
- package/src/migrate-prompts.mjs +171 -0
- package/src/migrate-template.mjs +170 -0
- package/src/migrate.mjs +90 -0
- package/src/misuse-read.mjs +61 -0
- package/src/model-request.mjs +33 -0
- package/src/model.mjs +523 -0
- package/src/modules.mjs +355 -0
- package/src/naming.mjs +55 -0
- package/src/native-action.mjs +59 -0
- package/src/native-record.mjs +244 -0
- package/src/new.mjs +1321 -0
- package/src/output-identity.mjs +111 -0
- package/src/parent-plan.mjs +58 -0
- package/src/parse-cache.mjs +99 -0
- package/src/path-containment.mjs +15 -0
- package/src/pickup-card.mjs +293 -0
- package/src/pickup.mjs +671 -0
- package/src/prompt.mjs +25 -0
- package/src/prompts.mjs +585 -0
- package/src/query.mjs +977 -0
- package/src/record-action.mjs +11 -0
- package/src/record-create.mjs +82 -0
- package/src/reference-planner.mjs +388 -0
- package/src/reference-values.mjs +11 -0
- package/src/rename.mjs +107 -0
- package/src/render.mjs +678 -0
- package/src/roadmap.mjs +184 -0
- package/src/runlist.mjs +944 -0
- package/src/section.mjs +225 -0
- package/src/semantic-search-client.mjs +58 -0
- package/src/ship.mjs +166 -0
- package/src/show.mjs +101 -0
- package/src/skill-drift.mjs +98 -0
- package/src/source-editor.mjs +491 -0
- package/src/stages.mjs +73 -0
- package/src/state-migration.mjs +123 -0
- package/src/stats.mjs +200 -0
- package/src/status-metadata.mjs +87 -0
- package/src/statuses.mjs +721 -0
- package/src/summary.mjs +74 -0
- package/src/surfaces.mjs +28 -0
- package/src/sync-status.mjs +316 -0
- package/src/template-store.mjs +62 -0
- package/src/update.mjs +338 -0
- package/src/use.mjs +58 -0
- package/src/util.mjs +337 -0
- package/src/validate.mjs +794 -0
- package/src/watch.mjs +56 -0
- package/src/xref.mjs +406 -0
- package/src/yardstick-command.mjs +178 -0
- package/src/yardstick.mjs +112 -0
package/README.md
CHANGED
|
@@ -1,14 +1,1122 @@
|
|
|
1
1
|
# runlist
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
CLI for managing Markdown documents with YAML frontmatter.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
runlist (formerly dotmd) indexes, queries, validates, graphs, exports, and lifecycle-manages plans,
|
|
6
|
+
ADRs, RFCs, design docs, and other structured Markdown. It is built for
|
|
7
|
+
AI-assisted development workflows where documents need to remain current and
|
|
8
|
+
safe to mutate.
|
|
7
9
|
|
|
8
|
-
|
|
10
|
+
- Zero runtime dependencies
|
|
11
|
+
- Node.js 20 or newer
|
|
12
|
+
- Runtime support for Linux, macOS, and Windows
|
|
13
|
+
- Type-aware lifecycle rules for plans, docs, and saved prompts
|
|
9
14
|
|
|
15
|
+
## Install
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install -g runlist # global CLI and agent-host hooks
|
|
19
|
+
npm install -D runlist # project scripts via node_modules/.bin
|
|
20
|
+
npx runlist init # try it without installing
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
`runlist` is the canonical executable, `rl` is its short convenience alias, and
|
|
24
|
+
`dotmd` remains supported during the compatibility window. All three invoke the
|
|
25
|
+
same CLI. The npm package is `runlist`; existing `dotmd-cli` installs should be
|
|
26
|
+
replaced with `runlist`. The Claude Code plugin is `runlist@runlist`. Legacy
|
|
27
|
+
`dotmd.config.*` files, `DOTMD_*` variables and `.dotmd/` state keep working.
|
|
28
|
+
|
|
29
|
+
If you installed the old package globally, remove it before installing the new
|
|
30
|
+
one because both packages provide the same executable names:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npm uninstall -g dotmd-cli
|
|
34
|
+
npm install -g runlist
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
The optional desktop app is a separate download with the same Markdown engine; see
|
|
38
|
+
[desktop setup and validation](desktop/README.md). The delivered app includes
|
|
39
|
+
reviewed plan/doc/hub creation, ⌘/Ctrl+K navigation, on-demand local content
|
|
40
|
+
search, saved library views, checkout-wide recovery and reviewed local Git commits
|
|
41
|
+
for qualified macOS checkouts. Saving writes local Markdown; committing remains
|
|
42
|
+
a separate reviewed action. **Product goal** shows your written yardstick beside
|
|
43
|
+
a plan's delivery statement, with explicit Review/Apply for your assessment.
|
|
44
|
+
**Filing** shows where plans are homed and opens the supporting hub rows.
|
|
45
|
+
Stage filters, grouping and editing are included. Optional grepmax semantic
|
|
46
|
+
controls are experimental; live retrieval depends on a compatible external
|
|
47
|
+
provider. Local chat and push are deferred.
|
|
48
|
+
|
|
49
|
+
The previous Apple Silicon GUI was **0.94.0-rc.1**, signed and accepted by Apple.
|
|
50
|
+
Its public installers have been withdrawn during a privacy cleanup. A clean
|
|
51
|
+
replacement has not yet been built. Existing installations can still be opened.
|
|
52
|
+
The desktop app is separate from CLI 0.94.1,
|
|
53
|
+
which includes optional plan-filing checks and the owner-written product yardstick,
|
|
54
|
+
corrected hub-category inheritance, updates for every saved Claude plugin scope,
|
|
55
|
+
and `runlist desktop install`.
|
|
56
|
+
Updating the CLI does not replace the GUI's bundled engine; this GUI reports 0.94.0-rc.1.
|
|
57
|
+
Earlier development packages and their qualification results are historical;
|
|
58
|
+
see the [desktop validation record](desktop/VALIDATION.md).
|
|
59
|
+
|
|
60
|
+
Deferred work awaiting selection:
|
|
61
|
+
|
|
62
|
+
1. Expand local-commit qualification to process filters, broader clean-filter
|
|
63
|
+
command profiles, Windows, Linux x64/other Git versions and additional signing profiles.
|
|
64
|
+
Configured commit hooks and noninteractive SSH/OpenPGP signing are supported
|
|
65
|
+
in current source on the qualified macOS/Linux combinations. Push is deferred.
|
|
66
|
+
2. Optional grepmax live retrieval/coverage qualification is parked: the owner
|
|
67
|
+
reports a watcher issue requiring a reboot. The last check saw gmax 0.26.65
|
|
68
|
+
ready, but its installed bridge/daemon lacked Runlist's required document-search
|
|
69
|
+
contract. Watcher recovery and compatibility must be verified before live
|
|
70
|
+
qualification resumes; preserve the existing safety hold. See the
|
|
71
|
+
current status and resume gates.
|
|
72
|
+
The compatibility plan
|
|
73
|
+
now has steps 1–4 passing against gmax 0.26.66 source and an extracted local
|
|
74
|
+
npm candidate, including the actual private helper. Deployment and live
|
|
75
|
+
checks remain separate gates.
|
|
76
|
+
Large-checkout inventory,
|
|
77
|
+
unavailable-state memory/latency and bridge cleanup have terminal evidence.
|
|
78
|
+
The Runlist GUI/backend adapter and guarded protocol fixtures are included
|
|
79
|
+
in GUI 0.94.0-rc.1. External provider deployment and successful live retrieval
|
|
80
|
+
remain unverified. Optional local model chat is deferred.
|
|
81
|
+
3. Complete native plan lifecycle, legacy migration,
|
|
82
|
+
settings/diagnostics. GUI yardstick and Filing reports are delivered in
|
|
83
|
+
0.94.0-rc.1. Stage filters/groups and guarded Stage editing are also delivered.
|
|
84
|
+
4. Finish platform qualification: a terminal-ready Windows host, Linux x64 and
|
|
85
|
+
older distributions, real-version upgrades, fresh/minimum-version and Intel
|
|
86
|
+
Macs, plus native rendering, focus, accessibility and whole-window memory.
|
|
87
|
+
|
|
88
|
+
Mac GUI downloads are temporarily unavailable pending a clean replacement.
|
|
89
|
+
CLI 0.94.1 includes the optional product yardstick.
|
|
90
|
+
The supported desktop
|
|
91
|
+
release is Apple Silicon macOS 13.5 or newer. Broader platform work and
|
|
92
|
+
experimental semantic search remain separate follow-up work.
|
|
93
|
+
|
|
94
|
+
Maintainer release automation is POSIX-only because it uses Bash and POSIX
|
|
95
|
+
command-line tools. The published Node.js CLI remains cross-platform.
|
|
96
|
+
|
|
97
|
+
### Optional desktop GUI
|
|
98
|
+
|
|
99
|
+
The CLI works on its own. Public GUI downloads are temporarily unavailable
|
|
100
|
+
during a privacy cleanup; a clean replacement has not yet been built. On an
|
|
101
|
+
Apple Silicon Mac (macOS 13.5 or newer), open an existing installation with:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
runlist desktop
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
The installer downloads the GUI from Runlist's public GitHub Releases, checks
|
|
108
|
+
its SHA-256 digest, developer signature and Apple approval, then installs it
|
|
109
|
+
without opening it. The app bundles its runtime and reads local files through
|
|
110
|
+
private pipes, with no listening server. Choose your checkout folder in the app.
|
|
111
|
+
No checkout configuration is loaded by these CLI commands.
|
|
112
|
+
|
|
113
|
+
The GUI is versioned separately from the CLI. There is currently no public Mac
|
|
114
|
+
installer available to `runlist desktop install`.
|
|
115
|
+
Windows, Linux and Intel Mac GUI downloads are not yet available through this
|
|
116
|
+
command. An existing app is kept as-is. To replace it using a downloaded signed
|
|
117
|
+
DMG, quit Runlist and run:
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
runlist desktop install --from /path/to/Runlist.dmg
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Replacement keeps the previous app as a rollback copy. Add `--dry-run` to preview
|
|
124
|
+
an install or launch without network access, file changes or opening the app.
|
|
125
|
+
Use `runlist desktop --app /path/to/application` for a custom installation path.
|
|
126
|
+
|
|
127
|
+
### Agent host setup
|
|
128
|
+
|
|
129
|
+
The CLI alone gives an agent no orientation and no session identity. Install the
|
|
130
|
+
integration for whichever host you run:
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
runlist install # what's installed for each host
|
|
134
|
+
runlist install claude # Claude Code plugin (marketplace + plugin)
|
|
135
|
+
runlist install codex # Codex skill and hooks (personal marketplace)
|
|
136
|
+
runlist install opencode # OpenCode plugin (one auto-discovered file)
|
|
137
|
+
runlist doctor --session # what identity runlist sees here, and from where
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
The integrations are one-time and global. Codex exports `CODEX_THREAD_ID` to
|
|
141
|
+
every tool shell, so its identity works without the plugin; the plugin adds a
|
|
142
|
+
workflow skill, session orientation, and the tool guard.
|
|
143
|
+
|
|
144
|
+
### Codex Plugin
|
|
145
|
+
|
|
146
|
+
`runlist install codex` copies the plugin included in the npm package into the
|
|
147
|
+
personal Codex marketplace and runs `codex plugin add runlist-codex@personal`.
|
|
148
|
+
Codex asks you to review and trust plugin hooks separately. Start a new thread
|
|
149
|
+
after installation so the skill and SessionStart primer load. The hooks use
|
|
150
|
+
the globally installed `runlist` CLI; a missing CLI produces one install hint
|
|
151
|
+
and otherwise leaves tool calls alone. `CODEX_THREAD_ID` stays the ownership
|
|
152
|
+
source. The CLI refuses to overwrite a plugin directory it did not generate.
|
|
153
|
+
|
|
154
|
+
Direct prompt reads warn by default in Codex and Claude. A repository can set
|
|
155
|
+
`export const guard = { promptReads: 'deny' };` to block reads of existing
|
|
156
|
+
pending prompts; `runlist prompts show` remains the read-only inspection verb.
|
|
157
|
+
|
|
158
|
+
### Claude Code Plugin
|
|
159
|
+
|
|
160
|
+
`runlist install claude` runs the two steps below for you. From inside a session:
|
|
161
|
+
|
|
162
|
+
```text
|
|
163
|
+
/plugin marketplace add reowens/runlist
|
|
164
|
+
/plugin install runlist@runlist
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Existing `dotmd@dotmd` installs can be migrated with `runlist install claude`
|
|
168
|
+
or `runlist update --plugin-only`. The command installs `runlist@runlist` and
|
|
169
|
+
then uninstalls the old plugin, so its hooks do not run twice.
|
|
170
|
+
|
|
171
|
+
The plugin provides SessionStart and SubagentStart orientation, a
|
|
172
|
+
UserPromptSubmit hint that gives the exact `runlist baton` form when you ask for
|
|
173
|
+
a handoff, a PreToolUse guard, the canonical workflow skill, and `/plans`,
|
|
174
|
+
`/docs`, `/prompts`, and `/baton` commands.
|
|
175
|
+
|
|
176
|
+
### OpenCode Plugin
|
|
177
|
+
|
|
178
|
+
`runlist install opencode` writes one plugin file into OpenCode's global config
|
|
179
|
+
directory, where OpenCode auto-discovers it — no `opencode.json` edit. It
|
|
180
|
+
supplies the two things the CLI cannot get on its own:
|
|
181
|
+
|
|
182
|
+
- **Per-session plan ownership.** OpenCode exports no session id to a tool
|
|
183
|
+
shell. Without the plugin, runlist falls back to `OPENCODE_PID`, which names the
|
|
184
|
+
OpenCode *process* — so every session in one OpenCode instance shares an
|
|
185
|
+
identity and can release the others' in-session plans.
|
|
186
|
+
- **A session-start briefing**, the equivalent of Claude Code's SessionStart
|
|
187
|
+
hook. OpenCode's Claude Code compatibility covers skills and the system
|
|
188
|
+
prompt, not hooks, so nothing else runs `runlist hud`.
|
|
189
|
+
- **Prompt-read guardrails.** Recognized reads are checked before execution so
|
|
190
|
+
the opt-in strict policy can stop them. Default warnings are attached to the
|
|
191
|
+
result because OpenCode's before hook cannot return model context.
|
|
192
|
+
|
|
193
|
+
Restart OpenCode after installing. The generated file is `runlist.js` and is
|
|
194
|
+
version-stamped (`runlist-generated:`). `runlist install opencode` migrates a
|
|
195
|
+
generated `dotmd.js` from older releases; an unmarked file is treated as
|
|
196
|
+
hand-authored and is never overwritten.
|
|
197
|
+
|
|
198
|
+
The plugin requires a global CLI install because its hooks resolve `runlist` (or `dotmd`) from
|
|
199
|
+
`PATH`. A project devDependency is useful for npm scripts but does not put the
|
|
200
|
+
CLI on the hook's `PATH`.
|
|
201
|
+
|
|
202
|
+
Keep the CLI and plugin aligned with:
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
runlist update
|
|
206
|
+
runlist update --check
|
|
207
|
+
runlist update --cli-only
|
|
208
|
+
runlist update --plugin-only
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
From CLI 0.93.2, Claude plugin updates cover each saved user, project and local
|
|
212
|
+
installation.
|
|
213
|
+
Project/local updates run from the recorded project folder. `update --check`
|
|
214
|
+
shows each scope separately, and an update verifies the fresh installation
|
|
215
|
+
records before reporting success. Missing project paths, unavailable folders
|
|
216
|
+
and managed scopes are reported rather than silently updating another scope.
|
|
217
|
+
The release workflow uses the same scope selection and verifies every entry
|
|
218
|
+
against the released version.
|
|
219
|
+
|
|
220
|
+
Restart Claude Code, or run `/reload-plugins`, after a plugin update.
|
|
221
|
+
|
|
222
|
+
## Quick Start
|
|
223
|
+
|
|
224
|
+
```bash
|
|
225
|
+
runlist init # create config, docs/, and the generated index
|
|
226
|
+
runlist new plan auth-refresh # scaffold a typed document
|
|
227
|
+
runlist plans # compact live plan dashboard
|
|
228
|
+
runlist briefing # comprehensive active-work view
|
|
229
|
+
runlist check # validate schema, references, and lifecycle shape
|
|
230
|
+
runlist doctor # preview repairs; add --apply to write
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
`runlist plans` is the compact orientation view. `runlist briefing` lists live
|
|
234
|
+
plans with next steps and grows with the corpus. `runlist context` is the fuller
|
|
235
|
+
human/LLM briefing, while `runlist agent-context` emits bounded structured JSON for
|
|
236
|
+
agent integrations. Its default response is capped at 16,384 UTF-8 bytes,
|
|
237
|
+
including JSON formatting and the final newline. Each collection reports
|
|
238
|
+
`total`, `shown`, and `truncated`; `budget` reports emitted bytes. Claims, the
|
|
239
|
+
next pending prompt, and the first plan action are retained. If protected
|
|
240
|
+
information cannot fit, the command reports the required budget rather than
|
|
241
|
+
silently dropping it.
|
|
242
|
+
|
|
243
|
+
```bash
|
|
244
|
+
runlist agent-context --sections plans,prompts,counts --max-bytes 8192
|
|
245
|
+
runlist context --json --compact --sections plans,issues
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
Available sections are `statusVocabulary`, `counts`, `prompts`, `plans`, and
|
|
249
|
+
`issues`. Section selection is explicit in the response's scope. Passive
|
|
250
|
+
context reads continue to skip custom side effects and expensive Git history.
|
|
251
|
+
|
|
252
|
+
The developing native record format is specified by
|
|
253
|
+
[runlist-record-v1.schema.json](assets/schemas/runlist-record-v1.schema.json).
|
|
254
|
+
It uses flat frontmatter for identity and lifecycle fields, a literal
|
|
255
|
+
`record_data` block containing nested JSON, and native Markdown for narrative
|
|
256
|
+
and anchored plan tasks. The read-only parser in `src/native-record.mjs`
|
|
257
|
+
preserves original source, validates metadata and relationships, and rejects
|
|
258
|
+
ambiguous keys, unsupported versions, incomplete resolution evidence, and
|
|
259
|
+
invalid ruling provenance. Existing CLI writers and migration do not yet use
|
|
260
|
+
this format; ordinary legacy documents and flag logs remain unchanged.
|
|
261
|
+
|
|
262
|
+
The local source-editing core in `src/source-editor.mjs` provides authenticated
|
|
263
|
+
actor attribution, exact revision saves, durable retry/repair receipts, private
|
|
264
|
+
draft recovery, and compensating undo. It preserves frontmatter and lifecycle
|
|
265
|
+
history, respects CLI claims, and reports conflicts with the current source.
|
|
266
|
+
The [source editing contract](assets/contracts/source-editing-v1.md) describes
|
|
267
|
+
the API and trusted host responsibilities. The local browser adapter below
|
|
268
|
+
uses that core; managed record domain writers remain upcoming work.
|
|
269
|
+
|
|
270
|
+
Runlist also has a [macOS desktop application](desktop/README.md) built from this
|
|
271
|
+
source checkout. Install `Runlist.app`, open it normally, and choose a trusted
|
|
272
|
+
checkout. It bundles its runtime and uses private pipes; normal desktop work
|
|
273
|
+
needs no installed Node, browser access link or listening server. CLI 0.92.0 provides the desktop commands below.
|
|
274
|
+
The GUI remains optional:
|
|
275
|
+
|
|
276
|
+
```bash
|
|
277
|
+
runlist desktop install # requires an available public installer
|
|
278
|
+
runlist desktop # open the installed GUI
|
|
279
|
+
runlist desktop install --from /path/to/Runlist.dmg # install a local signed DMG
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
The installer currently supports Apple Silicon Macs. It verifies the published
|
|
283
|
+
download checksum, Runlist developer signature and Apple approval, and installs
|
|
284
|
+
without opening the app. An existing app is kept unless `--from` supplies a
|
|
285
|
+
replacement; replacement keeps a rollback copy. `--dry-run` uses no network and
|
|
286
|
+
changes no files. Public Mac downloads have been withdrawn during a privacy
|
|
287
|
+
cleanup; a clean replacement is pending. `--from` still works with a local
|
|
288
|
+
approved installer. These commands ship
|
|
289
|
+
in [CLI 0.92.0](https://github.com/reowens/runlist/releases/tag/v0.92.0) and can also
|
|
290
|
+
be used from this checkout as `node bin/runlist.mjs desktop …`. The GUI remains
|
|
291
|
+
separately versioned at **0.94.0-rc.1**; npm installation does not download it.
|
|
292
|
+
|
|
293
|
+
The optional browser document app is available from this source checkout (unreleased):
|
|
294
|
+
|
|
295
|
+
```bash
|
|
296
|
+
node bin/runlist.mjs app docs/plans/my-plan.md --port 5173
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
Open the local access link printed in the terminal. The app homes existing
|
|
300
|
+
hubs, plans and documents in the selected checkout, edits the document inline, exposes source, reviews a
|
|
301
|
+
diff before saving, keeps private recovery drafts, reports intervening edits,
|
|
302
|
+
and undoes a save through a new revision-checked operation. Related legacy
|
|
303
|
+
flags retain their original observation beside their current location; missing
|
|
304
|
+
observed revisions are explicit. Browser sessions identify as the local human
|
|
305
|
+
and respect agent claims. Save writes the Markdown file; Git commit and sharing
|
|
306
|
+
remain separate. Stop the server with Ctrl+C. CLI 0.92.0 also includes this explicitly launched browser-app command;
|
|
307
|
+
use `runlist app` from an installed CLI.
|
|
308
|
+
|
|
309
|
+
Click headings, paragraphs, list items, quotes, or code to edit them in place.
|
|
310
|
+
Enter creates the next block; an empty list item exits the list. Type `/` in an
|
|
311
|
+
empty paragraph or use the `+` beside a block to choose a heading, list, task,
|
|
312
|
+
quote, code block, or divider. Task checkboxes are interactive. Select text for
|
|
313
|
+
bold, italic, code, strikethrough, and links; Command/Ctrl+B and +I also work.
|
|
314
|
+
Command/Ctrl+Z undoes draft edits, while **Undo save** reverses a published save.
|
|
315
|
+
Private drafts save automatically; **Review changes → Save changes** publishes
|
|
316
|
+
them to Markdown. Managed lifecycle history stays read only. Tables and complex
|
|
317
|
+
blocks offer a local Markdown editor; **Edit Markdown** opens the full body as a
|
|
318
|
+
fallback. Untouched blocks, comments, and line endings retain their source.
|
|
319
|
+
|
|
320
|
+
The sidebar provides **All documents**, **Hubs**, **Plans**, **Docs**, **Flags**, **Decisions**, **Changes**, pins, recents,
|
|
321
|
+
and templates. Selecting a category opens its searchable results in the main
|
|
322
|
+
area, with type, status, location, sort and archive controls. Opened documents
|
|
323
|
+
have a **← Library** action; returning to the library retains unsaved drafts.
|
|
324
|
+
On narrow screens, **Navigation** opens the sidebar. Search spans the
|
|
325
|
+
whole configured library; only 50 result rows are returned/rendered per page.
|
|
326
|
+
Header metadata is cached and unchanged files are reused on refresh; Refresh
|
|
327
|
+
explicitly picks up external additions, removals, moves and metadata edits.
|
|
328
|
+
Discovery reads headers in 4 KiB chunks, up to 128 KiB when needed, and detaches
|
|
329
|
+
cached metadata from source buffers. Record refreshes process one document at a
|
|
330
|
+
time, retain decision fragments and flag connection paths, and load linked record
|
|
331
|
+
bodies when opened. To measure a read-only workload on your checkout, run
|
|
332
|
+
`node scripts/measure-app-memory.mjs /path/to/checkout`; adding `--expose-gc`
|
|
333
|
+
before the script also measures retained heap after collection.
|
|
334
|
+
Pinned/recent documents remain browser-local and reachable outside the current
|
|
335
|
+
results. Hub members, parent hubs and related documents remain navigable through
|
|
336
|
+
Connections and preview links, including documents on another page. Membership
|
|
337
|
+
uses the CLI's hub/order definition and parent back-pointers, rather than treating
|
|
338
|
+
every citation as a child. Configured non-plan narratives use the same reviewed
|
|
339
|
+
source save; untyped or unsupported formats open read only. Private prompts,
|
|
340
|
+
excluded corpora and generated indexes stay outside the library.
|
|
341
|
+
|
|
342
|
+
|
|
343
|
+
**Changes** reviews saved Markdown against the local Git HEAD, with 100-row
|
|
344
|
+
pages, search, archive inclusion and whole-file selection. Open it from the
|
|
345
|
+
sidebar, quick navigation or **Saved Git changes** in a document review.
|
|
346
|
+
Plans, hubs and other documents use the same configured-root and private-path
|
|
347
|
+
policy. Additions, modifications, deletions and renames include both safe rename
|
|
348
|
+
paths; partially staged files and ignored local-only files explain why selection
|
|
349
|
+
is blocked. Unrelated staging is counted without exposing unrelated source.
|
|
350
|
+
Refresh retains selection and the diff; navigation preserves unsaved drafts, and
|
|
351
|
+
**Return to draft** resumes the current editor without saving it. Git inspection
|
|
352
|
+
runs on demand with bounded asynchronous output and no optional index locks.
|
|
353
|
+
**Review local commit** opens a separate message and exact Git-content review.
|
|
354
|
+
Open each selected file before **Commit locally** becomes available. The review
|
|
355
|
+
uses the actual Git tree, including ordinary EOL normalization, and authorizes
|
|
356
|
+
both paths of a rename. The commit guard checks the actual commit’s tree, parent,
|
|
357
|
+
message, destination branch, saved files, effective Git configuration/attributes
|
|
358
|
+
and owned final-index generation before ref publication. Unrelated staging stays
|
|
359
|
+
staged. Selected partial staging and ignored/private files are never replaced or
|
|
360
|
+
force-added. Runlist initiates no fetch, push or credential operation.
|
|
361
|
+
|
|
362
|
+
The writable gate supports Apple Silicon macOS with Git 2.54.0 or 2.55.0 and Linux ARM64 with
|
|
363
|
+
Git 2.47.3. Linux was qualified through terminal fixtures on the dev Pi:
|
|
364
|
+
Debian 13.5, glibc 2.41 and the pinned Node 24.21.0 helper runtime; the initial
|
|
365
|
+
baseline passed 19 commit/recovery and 20 native-helper checks with external networking
|
|
366
|
+
disabled. Linux x64, other Linux Git versions and Windows remain unqualified.
|
|
367
|
+
See Linux commit evidence.
|
|
368
|
+
Both gates require an existing named branch, SHA-1 objects and a plain v2/v3
|
|
369
|
+
index (at most 2 MiB; only the ordinary TREE extension).
|
|
370
|
+
One-shot clean filters with a regular executable and literal arguments are supported,
|
|
371
|
+
including a standalone `%f` filename argument and quoted paths. Process filters,
|
|
372
|
+
shell expressions/builtins/globbing, working-tree encoding, sparse/split/fsmonitor/extended
|
|
373
|
+
indexes, unsupported signing profiles and other platforms/versions still require Git.
|
|
374
|
+
These settings are refused before execution, never bypassed. Opening Changes or
|
|
375
|
+
its saved-file diff disables executable filters: filtered candidates may be
|
|
376
|
+
unchanged in Git. **Review exact Git content** explicitly applies the configured
|
|
377
|
+
clean filter in two private indexes and displays the resulting canonical blobs.
|
|
378
|
+
Different outputs, partial staging, changed config/attributes/executable/literal
|
|
379
|
+
file arguments or a final tree/index mismatch block the commit. Saved Markdown
|
|
380
|
+
remains unchanged; unrelated staging is preserved. Git retains required/optional
|
|
381
|
+
filter-failure behavior. Executables and referenced file arguments have a 16 MiB
|
|
382
|
+
inspection bound; the existing 1 MiB combined review bound still applies.
|
|
383
|
+
Filters are trusted checkout code with their own side effects and indirect
|
|
384
|
+
dependencies; Runlist does not sandbox or undo those effects. A filtered private
|
|
385
|
+
Git step that exceeds its time/output limits stops its owned process group and
|
|
386
|
+
retains failure evidence. The read-only view remains independent of the write gate.
|
|
387
|
+
|
|
388
|
+
Configured commit hooks run at their original paths with Git's arguments, stdin,
|
|
389
|
+
working directory and index/editor context, including relative or absolute
|
|
390
|
+
`core.hooksPath`. Preview and private index preparation never execute them.
|
|
391
|
+
The review lists the enabled hooks, signing format and clean-filter names. Changed hook generations,
|
|
392
|
+
hook rejection or unreviewed tree/message/index changes block publication.
|
|
393
|
+
Post-commit failures retain the known commit; they never trigger another commit.
|
|
394
|
+
Hooks are trusted checkout code and can perform their own side effects; Runlist
|
|
395
|
+
preserves those effects and retained evidence rather than claiming to sandbox or
|
|
396
|
+
undo them. Each hook has a 10-second bound within the existing job limits.
|
|
397
|
+
|
|
398
|
+
Required signing supports local Ed25519 OpenSSH private-key files through
|
|
399
|
+
`ssh-keygen`, and OpenPGP through GnuPG with an explicit full signing fingerprint
|
|
400
|
+
and a ready agent. SSH agents/hardware, X.509, custom signer commands and
|
|
401
|
+
conflicting OpenPGP program aliases remain unqualified. SSH askpass is disabled;
|
|
402
|
+
GnuPG uses batch/no-tty, error-only pinentry and no agent autostart or automatic
|
|
403
|
+
key retrieval. Encrypted SSH keys and unavailable GPG agents fail without an
|
|
404
|
+
unsigned fallback. The guard verifies the actual signature against the selected
|
|
405
|
+
key before ref publication, alongside the reviewed content and staging checks.
|
|
406
|
+
Private keys/passphrases are never stored in receipts. See
|
|
407
|
+
hook and signing evidence.
|
|
408
|
+
|
|
409
|
+
Commit jobs return promptly and survive renderer/helper disconnect. **Recovery**
|
|
410
|
+
finds private human/checkout-bound disk receipts even without browser storage.
|
|
411
|
+
**Inspect outcome** checks retained evidence; **Recover owned staging** restores
|
|
412
|
+
only a proven owned generation after its process group has stopped. Foreign or
|
|
413
|
+
unverified locks/indexes are preserved. An uncertain publication is never retried;
|
|
414
|
+
an explicit note can acknowledge fresh inspected ref/index evidence without
|
|
415
|
+
replaying or undoing a commit. Closing a review preserves its receipt and message
|
|
416
|
+
draft. Bounds include a 1 MiB combined review, 8 KiB message, 30-minute review
|
|
417
|
+
expiry, bounded Git command/job deadlines and 500 retained operations. Private
|
|
418
|
+
receipt storage must be ignored, untracked and free of symlinks.
|
|
419
|
+
|
|
420
|
+
This source work has not replaced the installed desktop app. Native visual/focus
|
|
421
|
+
checks, broader Git compatibility and platform qualification remain separate;
|
|
422
|
+
Apple status checks remain stopped.
|
|
423
|
+
|
|
424
|
+
**Flags** is the triage queue, with search, severity/status filters, source and
|
|
425
|
+
hub filters, and 50-row pages. Open a flag for its original observation, current
|
|
426
|
+
evidence and append-only history. Accept, reject or resolve with a reason, review,
|
|
427
|
+
then confirm. Accept keeps the flag open; reject closes it; resolve records that
|
|
428
|
+
it was addressed.
|
|
429
|
+
|
|
430
|
+
**Decisions** brings existing plan sections and registers into one queue. Linked
|
|
431
|
+
register/plan records collapse using the CLI parser's scope rules. Each record
|
|
432
|
+
shows its source, connected work, blocking items, question and recorded outcomes.
|
|
433
|
+
Review a hold, ruling, closure or reopening before saving. A ruling requires a
|
|
434
|
+
selected answer and a reason; the app records the authenticated human and date.
|
|
435
|
+
Earlier outcomes and original text remain in the source. Reviewed requests are
|
|
436
|
+
retained in browser storage so a reload or lost acknowledgement can retry the
|
|
437
|
+
same operation without duplicating it. External edits and claims are checked
|
|
438
|
+
again on save. Native v1 records also support reviewed actions. Flag accept,
|
|
439
|
+
reject, manual resolution and reopening retain original evidence and history.
|
|
440
|
+
Native decision rulings select an existing option ID; changed rulings explicitly
|
|
441
|
+
supersede their predecessor, and reopening or holding a ruled decision records
|
|
442
|
+
a withdrawal. Human authority is required to record or withdraw rulings.
|
|
443
|
+
Duplicate native IDs and invalid records remain read only in the queue.
|
|
444
|
+
|
|
445
|
+
**New flag** and **New decision** are available in their queues, the New dialog
|
|
446
|
+
and quick actions in current source. A flag asks for a finding, severity and
|
|
447
|
+
context; it starts open and unreviewed. A decision asks for a question and two to
|
|
448
|
+
twelve described alternatives, with optional benefits, costs, risks and follow-up.
|
|
449
|
+
It starts open, without a ruling. Review the canonical fields and exact Markdown,
|
|
450
|
+
then explicitly confirm creation. The authenticated local human owns the creation
|
|
451
|
+
event. Retained operation IDs, exclusive writes and Recovery protect against
|
|
452
|
+
duplicate retries, conflicting files and interrupted publication.
|
|
453
|
+
|
|
454
|
+
The first record also reviews `runlist.records.json`, containing schema 1, a
|
|
455
|
+
stable `repositoryId`, a root under the configured document roots and
|
|
456
|
+
`shared: false`. The default root is `<catch-all document root>/records`; each
|
|
457
|
+
record lives in its `flags/` or `decisions/` folder. A single existing native
|
|
458
|
+
repository identity is reused; multiple identities require explicit selection.
|
|
459
|
+
Alternatively, set `export const records = { schema: 1, repositoryId:
|
|
460
|
+
'repo:<UUID-v4>', root: 'docs/records', shared: false }` in `runlist.config.mjs`.
|
|
461
|
+
If both settings sources exist, they must agree. `shared: true` requires a working
|
|
462
|
+
Git checkout and a trackable destination; ignored files produce an error without
|
|
463
|
+
changing ignore rules or force-adding anything. To share the identity across
|
|
464
|
+
clones, include its configuration in your own Git commit; the GUI's managed-doc
|
|
465
|
+
selection does not include the root-level JSON file. Existing records and custom
|
|
466
|
+
configuration source are preserved. This feature is source-only and has not
|
|
467
|
+
replaced the installed desktop app. See the
|
|
468
|
+
creation work item.
|
|
469
|
+
|
|
470
|
+
The companion CLI uses the same native action preparation and editing core:
|
|
471
|
+
|
|
472
|
+
```bash
|
|
473
|
+
node bin/runlist.mjs record docs/flags/finding.md resolve --note "Manually verified the fix"
|
|
474
|
+
node bin/runlist.mjs record docs/decisions/choice.md ruled --option option:<uuid> --note "Fits the work"
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
Add `--dry-run` to inspect the prepared source, `--expected-revision sha256:<hash>`
|
|
478
|
+
to check an earlier read, or `--json` for a durable receipt. Legacy migration,
|
|
479
|
+
automated resolution proofs and agent recommendation editing
|
|
480
|
+
remain separate work.
|
|
481
|
+
|
|
482
|
+
**Change status** opens a lifecycle review for configured documents and plans.
|
|
483
|
+
The application uses the CLI engine for status validation, filing/archive moves,
|
|
484
|
+
reference repairs, history and index updates. The review checks source, claims,
|
|
485
|
+
configuration and destination again before publishing. Save or discard drafts
|
|
486
|
+
first. Claimed sources and native plan lifecycle operations are unavailable;
|
|
487
|
+
native flags and decisions use their domain actions instead. Moves retain
|
|
488
|
+
browser pins and heading bookmarks. Lost acknowledgements can be inspected and
|
|
489
|
+
retried through the retained operation ID. An interrupted runner stays uncertain
|
|
490
|
+
until inspected; acknowledging its outcome records that uncertainty without
|
|
491
|
+
replaying the operation. Retained CLI transactions must be repaired first.
|
|
492
|
+
|
|
493
|
+
**Semantic · gmax** is an optional search mode in ⌘/Ctrl+K and the library.
|
|
494
|
+
Type a natural-language query, then press **Search**; semantic queries do not run
|
|
495
|
+
on each keystroke. Results use relevance order over plans, hubs and other configured
|
|
496
|
+
Markdown roots. Section links are offered only when the indexed byte hash matches
|
|
497
|
+
the current file; changed sources open at the document. Library results are bounded
|
|
498
|
+
**top matches**, with no claim of full-corpus totals or pagination.
|
|
499
|
+
|
|
500
|
+
Runlist does not depend on, bundle or install grepmax, copy its index, start its
|
|
501
|
+
services, refresh its index, download/load models, or fall back to cloud search.
|
|
502
|
+
It requires an external gmax provider supporting `mcp --existing-index-only` and
|
|
503
|
+
a compatible already-running daemon with a warm embedding worker. The last
|
|
504
|
+
authorized check on October 7 at 21:36 UTC saw installed gmax 0.26.65 and a ready daemon,
|
|
505
|
+
but the installed document bridge and required daemon capability were absent.
|
|
506
|
+
Runlist's guarded probe returned `tool_unavailable`; the source bridge had
|
|
507
|
+
previously returned `unsupported_daemon` against 0.26.59. A ready ping alone
|
|
508
|
+
does not establish working semantic retrieval or watcher health.
|
|
509
|
+
Authorized steps 1–4 of the
|
|
510
|
+
compatibility plan
|
|
511
|
+
restore and qualify the bridge in gmax 0.26.66 source and an extracted npm
|
|
512
|
+
candidate. The first slice uses warm-only dense retrieval, with no hybrid/FTS,
|
|
513
|
+
ColBERT inference or reranking. Package/private-helper fixtures pass on Node
|
|
514
|
+
22.23.1 and 26.8.1; checkout dependencies were reused, not freshly installed.
|
|
515
|
+
This candidate is not deployed. Installation, matching-daemon negotiation and
|
|
516
|
+
live relevance/runtime-memory checks remain separate.
|
|
517
|
+
The release audit's source items 1–6 are now fixed: oversized-worker retirement
|
|
518
|
+
without replacement, native-read lifetime, required generations, idle MLX
|
|
519
|
+
readiness, bounded coverage/freshness metadata and the ARM64 Git write gate.
|
|
520
|
+
Rebuilt provider/private-helper fixtures pass on Node 22 and bundled Node 24.
|
|
521
|
+
Fresh isolated consumers now pass on Node 22.12.0 and 24.21.0 against the distinct
|
|
522
|
+
local gmax `0.26.68-runlist.1` candidate, with lifecycle scripts disabled and no
|
|
523
|
+
checkout dependency links. An unsigned Runlist `0.91.0-rc.1` Mac ARM64 candidate
|
|
524
|
+
contains that historical source snapshot. Separate optional provider qualification
|
|
525
|
+
is documented in [provider qualification](desktop/PROVIDER-QUALIFICATION.md); it
|
|
526
|
+
requires an exact accessible artifact URL/hash when explicitly invoked. Normal
|
|
527
|
+
CLI publication and desktop builds do not require that provider job. These results
|
|
528
|
+
do not establish deployment, live retrieval, watcher recovery or native-window
|
|
529
|
+
acceptance.
|
|
530
|
+
Ordinary text/content search works without gmax. Primary local stores are supported
|
|
531
|
+
by this first contract; external/secondary stores remain unavailable in Semantic mode.
|
|
532
|
+
|
|
533
|
+
**Settings → Semantic search** detects an external installation or lets you save
|
|
534
|
+
absolute paths to its Node executable and `grepmax/dist/bin.js`. These tool settings
|
|
535
|
+
stay in the user's Runlist configuration directory, outside the checkout; a changed
|
|
536
|
+
saved installation must be selected again. No queries/snippets are saved by Runlist,
|
|
537
|
+
and this gmax mode suppresses query logging without changing global gmax settings.
|
|
538
|
+
See the integration plan for
|
|
539
|
+
qualification limits. Older frozen packages omitted these additions; the delivered
|
|
540
|
+
0.92.0-rc.1 GUI includes the experimental semantic controls. An external provider
|
|
541
|
+
and live-search qualification remain separate.
|
|
542
|
+
|
|
543
|
+
Terminal checks on the real platform checkout covered 2,757 library documents.
|
|
544
|
+
The source engine harness and transient bridge sampled at 97.5 MiB and 81.7 MiB
|
|
545
|
+
peak RSS respectively; requests safely reported the absent daemon in 0.7–0.9 seconds.
|
|
546
|
+
These measure the unavailable path, not successful semantic queries or whole-app
|
|
547
|
+
memory. See [qualification evidence](desktop/VALIDATION.md#optional-gmax-real-checkout-probes--2026-10-07).
|
|
548
|
+
The absent-daemon and memory-pressure findings above are historical. The owner
|
|
549
|
+
now reports a gmax watcher problem requiring a reboot; its cause and post-reboot
|
|
550
|
+
recovery are unverified. Live qualification remains parked for watcher recovery
|
|
551
|
+
and the external contract gap. Preserve the host-safety hold; neither service
|
|
552
|
+
startup nor model headroom has been qualified. See the
|
|
553
|
+
watcher/search status.
|
|
554
|
+
Ordinary text/content search remains available; gmax is optional. Installing
|
|
555
|
+
current Runlist alone does not provide the missing external gmax contract.
|
|
556
|
+
|
|
557
|
+
**Settings** in the sidebar saves browser defaults for appearance, document order,
|
|
558
|
+
archive visibility and the records view. It links to the editable templates and
|
|
559
|
+
shows loaded document roots, exclusions, status rules and where changes live.
|
|
560
|
+
Repository configuration remains editable in its source or through the CLI;
|
|
561
|
+
this panel displays its effective rules.
|
|
562
|
+
|
|
563
|
+
**Appearance** in the header offers Light, Dark, and System. The browser remembers
|
|
564
|
+
your choice across reloads and shares it with other tabs at the same local app
|
|
565
|
+
address. System follows your OS appearance, including live changes. The theme
|
|
566
|
+
covers the library, inline editor, source, diffs, section tools, and templates.
|
|
567
|
+
|
|
568
|
+
**Sections** provides a searchable heading outline, heading bookmarks, and section
|
|
569
|
+
insertion. Command/Ctrl+Shift+J focuses section search; Alt+Page Up/Down moves
|
|
570
|
+
between headings. Stars save bookmarks for this checkout and file in the current
|
|
571
|
+
browser. Inline heading renames update their bookmarks; removed or unmatched
|
|
572
|
+
headings stay visible as unavailable bookmarks.
|
|
573
|
+
|
|
574
|
+
**Templates** in the sidebar opens the doc, plan, and prompt scaffolds with
|
|
575
|
+
Markdown editing, an example preview, and a diff before saving. Template drafts
|
|
576
|
+
stay in browser storage. Saves use revision checks and write the repository's
|
|
577
|
+
`runlist.templates.json`; ordinary `runlist new` commands consume these overrides.
|
|
578
|
+
Existing documents are unaffected. Keep `{{title}}`, `{{body}}`, and the managed
|
|
579
|
+
`{{status}}`/`{{date}}` metadata placeholders; `{{version}}` is also available.
|
|
580
|
+
Authored complete bodies and explicit plan variants retain their existing CLI
|
|
581
|
+
behavior. JavaScript templates from `runlist.config.mjs` can be inspected without
|
|
582
|
+
executing them. Built-in types can receive a Markdown override; custom JavaScript
|
|
583
|
+
types remain editable in that config file. The template file can be committed
|
|
584
|
+
with Git; bookmarks and draft recovery remain local.
|
|
585
|
+
|
|
586
|
+
The renderer covers headings, paragraphs, lists/tasks, tables, quotes, fenced
|
|
587
|
+
code, and safe links. Authored HTML is displayed as text; unsupported syntax
|
|
588
|
+
remains available in Source. The optional `test/browser-app-smoke.mjs` exercises
|
|
589
|
+
real browser save/CLI readback, undo, reload recovery, conflict review, lost
|
|
590
|
+
acknowledgements, and narrow-screen layouts with Playwright supplied externally.
|
|
591
|
+
|
|
592
|
+
### Plan stages
|
|
593
|
+
|
|
594
|
+
Stages describe when a plan should ship. Status describes its progress. Each
|
|
595
|
+
repository owns its ordered vocabulary in `taxonomy.milestones`; existing string
|
|
596
|
+
lists remain valid, and entries can include a plain-English meaning:
|
|
597
|
+
|
|
598
|
+
```js
|
|
599
|
+
export const taxonomy = {
|
|
600
|
+
milestones: [
|
|
601
|
+
{ word: 'beta', meaning: 'First customers are using it while it settles.' },
|
|
602
|
+
{ word: 'ga', meaning: 'Available to every customer who buys it.' },
|
|
603
|
+
{ word: 'later', meaning: 'Parked with no stage committed.' },
|
|
604
|
+
],
|
|
605
|
+
};
|
|
606
|
+
```
|
|
607
|
+
|
|
608
|
+
A plan selects a stage with `ships: beta`. Missing or blank `ships:` is **Unset**,
|
|
609
|
+
separate from an explicit `later`. Runlist never assigns a stage from status.
|
|
610
|
+
`check` reports stage coverage and rejects malformed or unknown configured values.
|
|
611
|
+
|
|
612
|
+
```bash
|
|
613
|
+
runlist plans --stage beta
|
|
614
|
+
runlist plans --stage @unset
|
|
615
|
+
runlist plans --group-by stage
|
|
616
|
+
```
|
|
617
|
+
|
|
618
|
+
Use `word:<name>` for a literal stage named `@unset` or beginning with `word:`.
|
|
619
|
+
In the GUI, Library → Plans can filter/group by Stage and save that view.
|
|
620
|
+
A plan's Stage dropdown changes the draft; review and save publishes it through
|
|
621
|
+
the existing revision, ownership and recovery guards. Other document metadata
|
|
622
|
+
stays protected. Semantic results retain relevance order when filtered by stage.
|
|
623
|
+
Plan stages are available in CLI 0.92.0 and GUI 0.92.0-rc.1.
|
|
624
|
+
|
|
625
|
+
## Core Workflow
|
|
626
|
+
|
|
627
|
+
```bash
|
|
628
|
+
runlist plans
|
|
629
|
+
runlist use docs/plans/auth-refresh.md
|
|
630
|
+
runlist set awaiting docs/plans/auth-refresh.md --note "Need API owner decision"
|
|
631
|
+
runlist set active docs/plans/auth-refresh.md --note "Decision received"
|
|
632
|
+
runlist archive docs/plans/auth-refresh.md --note "Shipped and verified"
|
|
633
|
+
```
|
|
634
|
+
|
|
635
|
+
Use `runlist set <status> [<file>]` for lifecycle changes rather than editing a
|
|
636
|
+
`status:` line. It validates the status for the document type, updates history,
|
|
637
|
+
runs lifecycle hooks, repairs references after moves, and synchronizes the
|
|
638
|
+
index.
|
|
639
|
+
|
|
640
|
+
For unfinished session work, save the handoff and release the owned plan in one
|
|
641
|
+
operation:
|
|
642
|
+
|
|
643
|
+
```bash
|
|
644
|
+
runlist baton @/tmp/resume.md
|
|
645
|
+
```
|
|
646
|
+
|
|
647
|
+
Baton refuses when a handoff for the same work is already pending, so one piece
|
|
648
|
+
of work never has two resume prompts. Inspect the pending handoff with
|
|
649
|
+
`runlist prompts show <slug>`. Keep it if current; if stale, pass `--replace`
|
|
650
|
+
with a new draft. Baton archives the previous text and refreshes the pending
|
|
651
|
+
prompt in the same operation as any plan release.
|
|
652
|
+
|
|
653
|
+
Repositories with a commit wrapper can export `batonCommitCommand(message, paths)`
|
|
654
|
+
from `runlist.config.mjs` and return an argv array such as
|
|
655
|
+
`['just', 'commit', message, ...paths]`. Baton quotes the printed command and
|
|
656
|
+
excludes session prompts from `paths`.
|
|
657
|
+
|
|
658
|
+
Saved prompts are local session state. Consume them with `runlist use`; inspect
|
|
659
|
+
without consuming via `runlist prompts show`. Consuming a baton prompt also claims
|
|
660
|
+
its plan; `runlist use --no-claim` reads and archives it without starting the plan.
|
|
661
|
+
|
|
662
|
+
New plans are created `planned`; `runlist use` starts one, and
|
|
663
|
+
`runlist new plan <name> --status <status>` sets a different starting status.
|
|
664
|
+
|
|
665
|
+
## Document Format
|
|
666
|
+
|
|
667
|
+
```markdown
|
|
668
|
+
---
|
|
669
|
+
type: plan
|
|
670
|
+
status: active
|
|
671
|
+
updated: 2026-07-13
|
|
672
|
+
modules:
|
|
673
|
+
- auth
|
|
674
|
+
surfaces:
|
|
675
|
+
- backend
|
|
676
|
+
current_state: Token validation is complete.
|
|
677
|
+
next_step: Wire refresh rotation into middleware.
|
|
678
|
+
related_docs:
|
|
679
|
+
- ./auth-design.md
|
|
680
|
+
---
|
|
681
|
+
|
|
682
|
+
# Auth Refresh
|
|
683
|
+
|
|
684
|
+
- [x] Validate tokens
|
|
685
|
+
- [ ] Rotate refresh tokens
|
|
686
|
+
```
|
|
687
|
+
|
|
688
|
+
`status` is the only universally required field. A `type` enables type-specific
|
|
689
|
+
statuses, validation, templates, and briefing behavior. Explicit frontmatter
|
|
690
|
+
wins, but runlist can also derive titles, summaries, state, next steps, checklist
|
|
691
|
+
progress, and Markdown links from the body.
|
|
692
|
+
|
|
693
|
+
Use plural `modules:` and `surfaces:` arrays. The old singular keys remain
|
|
694
|
+
readable for compatibility and can be migrated with `runlist lint --fix`.
|
|
695
|
+
|
|
696
|
+
### Built-In Types
|
|
697
|
+
|
|
698
|
+
| Type | Purpose | Default statuses |
|
|
699
|
+
|---|---|---|
|
|
700
|
+
| `plan` | Executable work | `in-session`, `active`, `planned`, `blocked`, `partial`, `paused`, `awaiting`, `queued-after`, `archived` |
|
|
701
|
+
| `doc` | Specs, ADRs, audits, and reference material | `draft`, `active`, `review`, `reference`, `deprecated`, `archived` |
|
|
702
|
+
| `prompt` | Saved future-session instructions | `pending`, `archived` |
|
|
703
|
+
|
|
704
|
+
Status definitions can be customized per type. Rich status objects co-locate
|
|
705
|
+
display, staleness, validation, terminal, and archive behavior in one place.
|
|
706
|
+
|
|
707
|
+
## Hubs, Ordered Plans, And Roadmaps
|
|
708
|
+
|
|
709
|
+
A **hub** is a Markdown document that organizes related plans and supporting
|
|
710
|
+
docs. Older documentation and existing filenames also call these documents
|
|
711
|
+
**runlists**. Hub and runlist describe the same organizing document; they are
|
|
712
|
+
not two successive levels. **Runlist** is also the product name.
|
|
713
|
+
|
|
714
|
+
A hub can organize an area through prose and links (**coordination hub**) or
|
|
715
|
+
use a `runlist:` array for an explicit plan sequence (**ordered hub**, also
|
|
716
|
+
called a sprint runlist). Coordination hubs can also rank plans through linked
|
|
717
|
+
body rows or lists. A **roadmap** is an optional hub that collects other hubs and
|
|
718
|
+
rolls up their progress. These are hub shapes, not three containers every
|
|
719
|
+
project must create. A simple arrangement is:
|
|
720
|
+
|
|
721
|
+
```text
|
|
722
|
+
Repository
|
|
723
|
+
└── Roadmap hub (optional, collects hubs)
|
|
724
|
+
└── Area or ordered hub
|
|
725
|
+
├── Supporting docs
|
|
726
|
+
└── Plans (optionally ordered)
|
|
727
|
+
└── Tasks
|
|
728
|
+
```
|
|
729
|
+
|
|
730
|
+
These are document relationships, not a required folder layout. Plans and
|
|
731
|
+
supporting docs can also stand alone. A plan's **stage** describes when
|
|
732
|
+
it should ship, and its **status** describes progress; neither adds a document
|
|
733
|
+
level. Hubs currently use `type: plan` with hub metadata, while supporting specs,
|
|
734
|
+
ADRs and reference material use `type: doc` or a configured document type.
|
|
735
|
+
|
|
736
|
+
Existing commands, fields, filenames and CLI labels retain `runlist` terminology.
|
|
737
|
+
The `runlist:` array declares the ordered plans **on the hub itself**. It does
|
|
738
|
+
not create a separate runlist document inside the hub. Scaffold an ordered hub
|
|
739
|
+
and its child plans together:
|
|
740
|
+
|
|
741
|
+
```bash
|
|
742
|
+
runlist new hub auth-revamp --runlist extract,rewrite,cleanup
|
|
743
|
+
runlist runlist auth-revamp
|
|
744
|
+
runlist runlist next auth-revamp
|
|
745
|
+
```
|
|
746
|
+
|
|
747
|
+
Mutate the structure through the CLI so the array, child `parent_plan` refs, and
|
|
748
|
+
body order list remain synchronized:
|
|
749
|
+
|
|
750
|
+
```bash
|
|
751
|
+
runlist runlist add auth-revamp docs/plans/existing-plan.md
|
|
752
|
+
runlist runlist add auth-revamp follow-up
|
|
753
|
+
runlist runlist reorder auth-revamp follow-up --before cleanup
|
|
754
|
+
runlist runlist remove auth-revamp extract --clear-parent
|
|
755
|
+
```
|
|
756
|
+
|
|
757
|
+
Archived children count as complete. Parked children (`blocked`, `partial`,
|
|
758
|
+
`paused`, `awaiting`, and `queued-after`) are skipped when choosing the next
|
|
759
|
+
pickup but do not count as done.
|
|
760
|
+
|
|
761
|
+
For a prose-first area map, create a coordination hub:
|
|
762
|
+
|
|
763
|
+
```bash
|
|
764
|
+
runlist new hub platform-work
|
|
765
|
+
runlist runlists
|
|
766
|
+
```
|
|
767
|
+
|
|
768
|
+
`runlist new hub` defaults to a coordination hub; add `--runlist a,b,c` for an
|
|
769
|
+
ordered hub or `--roadmap` for a roadmap hub. The existing `new plan` forms with
|
|
770
|
+
`--coordination`, `--runlist` or `--roadmap` create the same respective shapes.
|
|
771
|
+
|
|
772
|
+
For progress across several hubs, create an optional roadmap hub:
|
|
773
|
+
|
|
774
|
+
```bash
|
|
775
|
+
runlist new hub platform-roadmap --roadmap
|
|
776
|
+
runlist roadmap platform-roadmap
|
|
777
|
+
runlist roadmap platform-roadmap next
|
|
778
|
+
```
|
|
779
|
+
|
|
780
|
+
Roadmaps roll up progress recursively and choose the first startable plan across
|
|
781
|
+
their child hubs. They can also link plans directly. Hubs, including roadmaps,
|
|
782
|
+
are held out of actionable plan counts so dashboards do not double-count their
|
|
783
|
+
children.
|
|
784
|
+
|
|
785
|
+
### Product Yardstick
|
|
786
|
+
|
|
787
|
+
Optional yardstick support is included from CLI 0.94.0. The separately installed
|
|
788
|
+
GUI 0.92.0-rc.1 retains its earlier engine; yardstick controls in the GUI are
|
|
789
|
+
follow-up work. From a source checkout, use `node bin/runlist.mjs` in place of
|
|
790
|
+
`runlist` below.
|
|
791
|
+
|
|
792
|
+
Write your description of the finished product in an ordinary Markdown document
|
|
793
|
+
and opt in from repository config:
|
|
794
|
+
|
|
795
|
+
```js
|
|
796
|
+
export const yardstick = 'docs/product-yardstick.md';
|
|
797
|
+
```
|
|
798
|
+
|
|
799
|
+
Runlist reads that document's body and shows it beside a plan's literal
|
|
800
|
+
`delivers:` text on pickup cards. It records your judgment; it does not generate
|
|
801
|
+
the goal, score plans or decide which ones belong. Unset assessments are
|
|
802
|
+
**not yet reviewed**. The goal file must stay inside the repository; an unset
|
|
803
|
+
or false config disables the feature.
|
|
804
|
+
|
|
805
|
+
```bash
|
|
806
|
+
runlist yardstick show
|
|
807
|
+
runlist yardstick show docs/plans/navigation.md --json
|
|
808
|
+
runlist yardstick mark docs/plans/navigation.md serves
|
|
809
|
+
runlist yardstick fold docs/plans/old-navigation.md --into docs/plans/navigation.md --reason "Combined into navigation work." --dry-run
|
|
810
|
+
runlist yardstick close docs/plans/unused-navigation.md --reason "No longer needed." --dry-run
|
|
811
|
+
runlist yardstick clear docs/plans/navigation.md
|
|
812
|
+
```
|
|
813
|
+
|
|
814
|
+
**Close and fold actually archive the plan**, retaining the owner reason and
|
|
815
|
+
replacement link when folded. Removing `--dry-run` applies the displayed action.
|
|
816
|
+
Writes respect plan ownership, and archive/reference updates remain one
|
|
817
|
+
transaction. Replacement links are repaired when their targets move, including
|
|
818
|
+
with custom reference-field lists. Clearing an assessment does not reopen or
|
|
819
|
+
unarchive a plan. Every write supports `--dry-run` and `--json`; `--no-index`
|
|
820
|
+
leaves generated-index refresh to the caller.
|
|
821
|
+
|
|
822
|
+
Assessments use flat `yardstick_disposition`, `yardstick_into`,
|
|
823
|
+
`yardstick_reason` and `yardstick_revision` fields in plan frontmatter. After
|
|
824
|
+
the goal body changes, older assessments remain recorded and are labeled
|
|
825
|
+
**Reviewed against an earlier goal**. Goal frontmatter date edits and line-ending
|
|
826
|
+
changes alone do not require reassessment. `runlist check` warns about malformed
|
|
827
|
+
assessment fields or closed/folded metadata on live plans, and never closes
|
|
828
|
+
them automatically. Goal reads and assessments require no semantic provider,
|
|
829
|
+
local model or server. GUI controls are implemented in the source checkout:
|
|
830
|
+
Product goal shows the saved statement, delivery and assessment, with reviewed
|
|
831
|
+
Serves/Clear/Close/Fold actions and retained recovery. Structured plans display
|
|
832
|
+
the comparison with an explanation when assessment changes are unavailable.
|
|
833
|
+
These controls are included in the public desktop package 0.94.0-rc.1;
|
|
834
|
+
updating the CLI alone does not replace an existing app.
|
|
835
|
+
|
|
836
|
+
### Plan Homes And Filing Checks
|
|
837
|
+
|
|
838
|
+
This policy is available in CLI 0.93.0. From a source checkout, invoke the
|
|
839
|
+
commands below as `node bin/runlist.mjs …`. The separately versioned GUI
|
|
840
|
+
0.94.0-rc.1 also includes a read-only Filing view. The correction
|
|
841
|
+
for category inheritance from status-less hub indexes is included in CLI
|
|
842
|
+
0.93.1.
|
|
843
|
+
|
|
844
|
+
Repositories can enable the plan-home policy in `runlist.config.mjs`:
|
|
845
|
+
|
|
846
|
+
```js
|
|
847
|
+
export const filing = true;
|
|
848
|
+
// Or choose the category heading level (default: ###):
|
|
849
|
+
// export const filing = { categoryDepth: 3 };
|
|
850
|
+
```
|
|
851
|
+
|
|
852
|
+
A home is a table row in a live hub whose **first cell links to the plan** and
|
|
853
|
+
whose status cell contains a recognized plan status. Explicit managed status
|
|
854
|
+
markers also count. Links in prose, another row's commentary, frontmatter,
|
|
855
|
+
order lists, or tables without statuses are references. A numbered row with
|
|
856
|
+
the plan in its second cell is an execution order, not a filing home.
|
|
857
|
+
|
|
858
|
+
Categories come from `###` headings by default (`categoryDepth` accepts 2–6),
|
|
859
|
+
or from explicit first-cell hub index rows beneath those headings. These index
|
|
860
|
+
rows can categorize a hub without a status column; they do not establish a
|
|
861
|
+
plan home or a home for its children. Categories propagate through nested hub
|
|
862
|
+
indexes. A plan row's own category takes precedence over inherited categories.
|
|
863
|
+
Hub titles do not supply an inferred category, and competing inherited mappings
|
|
864
|
+
stay visible. A child with no own row can inherit a home through its explicit
|
|
865
|
+
`parent_plan:` chain; the report names the filed ancestor and its home rows.
|
|
866
|
+
A child's own row takes precedence. Missing, ambiguous or cyclic parent links
|
|
867
|
+
do not invent a home. Hubs and archived/terminal plans are excluded from the
|
|
868
|
+
executable-plan totals; closed hubs do not provide current homes.
|
|
869
|
+
|
|
870
|
+
```bash
|
|
871
|
+
runlist check # filing defect counts
|
|
872
|
+
runlist check --verbose # affected plans and hub:line locations
|
|
873
|
+
runlist check --json # filingCoverage, including inherited homes
|
|
874
|
+
runlist coverage # plan homes, categories and locations
|
|
875
|
+
runlist coverage --json # same report under filing
|
|
876
|
+
```
|
|
877
|
+
|
|
878
|
+
The three findings are **unfiled**, **multiply filed** (multiple rows or
|
|
879
|
+
categories), and **filed under no category**. Findings can overlap. These are
|
|
880
|
+
warnings; Runlist does not choose homes or add/remove rows. An incomplete scan
|
|
881
|
+
is labeled and suppresses absence/uniqueness findings. Path/type-scoped output
|
|
882
|
+
keeps the full hub/ancestor evidence while reporting only selected plans.
|
|
883
|
+
The source checkout also includes a read-only Filing view: open it to scan,
|
|
884
|
+
filter 50-plan pages, and inspect exact hub rows in 20-row evidence pages. Saved
|
|
885
|
+
edits invalidate the report. This view is included in public desktop package 0.94.0-rc.1.
|
|
886
|
+
The policy is off when `filing` is unset, false, or `{ enabled: false }`.
|
|
887
|
+
It can replace a repository's older “any link counts” coverage script once
|
|
888
|
+
that repository enables it and retires its custom check.
|
|
889
|
+
|
|
890
|
+
## Decisions
|
|
891
|
+
|
|
892
|
+
A decision is an entry in its plan, not a document of its own. Write the record
|
|
893
|
+
(the situation, what exists today, what each answer leaves in place) to a file
|
|
894
|
+
and add it:
|
|
895
|
+
|
|
896
|
+
```bash
|
|
897
|
+
runlist new decision auth-revamp --question "Which token store?" @record.md
|
|
10
898
|
```
|
|
11
|
-
|
|
899
|
+
|
|
900
|
+
It takes the next id (`D1`, `D2`, …) that no decision item in that plan uses,
|
|
901
|
+
lands at the end of the plan's top-level decisions section (created before
|
|
902
|
+
`## Version History` when there is none) with a `Disposition: OPEN.` line, and
|
|
903
|
+
refuses an empty record. `--disposition held` parks it instead.
|
|
904
|
+
|
|
905
|
+
A corpus that indexes its decisions in one register numbers them in one
|
|
906
|
+
sequence. Name the register, and the id follows the highest the register or the
|
|
907
|
+
plan uses, and the register gets the entry's row in the same locked write:
|
|
908
|
+
|
|
909
|
+
```js
|
|
910
|
+
export const decisions = {
|
|
911
|
+
section: 'Decisions',
|
|
912
|
+
prefix: 'D',
|
|
913
|
+
register: { file: 'docs/plans/register.md', statusLine: 'waiting on you:' },
|
|
914
|
+
};
|
|
915
|
+
```
|
|
916
|
+
|
|
917
|
+
The register block is the fenced block whose first line carries `statusLine`.
|
|
918
|
+
The row is the question plus `--answers` (what each answer leaves in place),
|
|
919
|
+
which is required when a register is configured.
|
|
920
|
+
|
|
921
|
+
`runlist decisions --json` gives each open or held decision its `question`,
|
|
922
|
+
its document's `docTitle`, and `blocks`: what its record says it blocks or
|
|
923
|
+
gates, then every unticked checklist item and frontmatter blocker that names
|
|
924
|
+
its id, alone or inside a written range (`A2 to A12`). In another document the
|
|
925
|
+
id has to sit beside a link to the decision's document.
|
|
926
|
+
|
|
927
|
+
Record an outcome in an existing legacy decision with the same source operation
|
|
928
|
+
used by the app:
|
|
929
|
+
|
|
930
|
+
```sh
|
|
931
|
+
runlist decision docs/plans/work.md D1 --disposition held --note "Need evidence"
|
|
932
|
+
runlist decision docs/plans/work.md D1 --disposition ruled --choice "Blue bin" --note "Fits the shelf"
|
|
933
|
+
```
|
|
934
|
+
|
|
935
|
+
`--dry-run` prints prepared source. `--expected-revision sha256:<hash>` checks a
|
|
936
|
+
previous read; `--json` returns the operation receipt. Human rulings require a
|
|
937
|
+
human CLI context. Agent sessions may record open, held or closed outcomes.
|
|
938
|
+
The source editor retains receipts and checks claims and exact source revisions.
|
|
939
|
+
|
|
940
|
+
## Flags
|
|
941
|
+
|
|
942
|
+
A flag is something someone found that the person should know about when they
|
|
943
|
+
come back: a plan that contradicts another, a decision open in one place and
|
|
944
|
+
ruled in another, a citation that no longer says what it claims. Any session,
|
|
945
|
+
person or check can add one, and no model is needed:
|
|
946
|
+
|
|
947
|
+
```bash
|
|
948
|
+
runlist flag add docs/plans/auth.md:42 "says tokens expire in 1h; the spec says 24h" --severity problem
|
|
949
|
+
runlist flags # open flags, problems first, newest first
|
|
950
|
+
runlist flag accept F3 --note "real, owner agrees"
|
|
951
|
+
runlist flag reject F4 # not a problem; closed
|
|
952
|
+
runlist flag resolve F3 # fixed
|
|
953
|
+
runlist check --flag # the check's errors become flags, attributed to it
|
|
954
|
+
```
|
|
955
|
+
|
|
956
|
+
Each flag keeps the text of the line it points at, so the list says when that
|
|
957
|
+
line has moved or changed since. A repeat of an open flag on the same place is
|
|
958
|
+
merged. The log is append-only, `.runlist/flags.jsonl` by default
|
|
959
|
+
(`export const flags = { file }` moves it), and triage is recorded as events
|
|
960
|
+
beside the flag, never over it. Every session start shows a count and the top
|
|
961
|
+
open flags.
|
|
962
|
+
|
|
963
|
+
## Local model
|
|
964
|
+
|
|
965
|
+
Summaries (`--summarize`, `runlist summary`, `runlist diff --summarize`) and
|
|
966
|
+
lint's status inference use one local model server, Ollama by default or any
|
|
967
|
+
OpenAI-compatible server. runlist never starts it or pulls a model on its own:
|
|
968
|
+
|
|
969
|
+
```bash
|
|
970
|
+
runlist model # server, model, cap, free memory, what is loaded
|
|
971
|
+
runlist model start # ollama serve, one model and one request at a time
|
|
972
|
+
runlist model measure # record each pulled candidate's peak memory and speed here
|
|
973
|
+
runlist model use qwen3.5:9b # name a model; `auto` picks the first measured one under the cap
|
|
974
|
+
runlist model cap 8 # most memory a model may take; `auto` is a quarter of the machine
|
|
975
|
+
runlist model stop # unload it now
|
|
976
|
+
```
|
|
977
|
+
|
|
978
|
+
The model unloads after 5 idle minutes. Before it loads, the memory free right
|
|
979
|
+
now must hold it plus 1.5 GB with memory pressure normal, or the command goes
|
|
980
|
+
on without it. On an 8 GB machine the cap is 2 GB and model features stay off;
|
|
981
|
+
point `RUNLIST_MODEL_ENDPOINT` at a server on a bigger machine instead. Settings
|
|
982
|
+
are per machine in `~/.runlist/model.json`.
|
|
983
|
+
|
|
984
|
+
`runlist model status --json` leads with a one-line reading for dashboards,
|
|
985
|
+
`running`, `name` (the model loaded now, else the one runlist would load) and
|
|
986
|
+
`memoryMb` (what it holds, null when nothing is loaded), followed by the full
|
|
987
|
+
detail.
|
|
988
|
+
|
|
989
|
+
## One document's card
|
|
990
|
+
|
|
991
|
+
```bash
|
|
992
|
+
runlist show docs/plans/shelf.md # title, status, next step, blockers, checklist, related, links
|
|
993
|
+
runlist show shelf bins --json # [{ path, title, status, nextStep, blockers, checklist,
|
|
994
|
+
# related: [{ field, path, title, status }], links: [...] }]
|
|
995
|
+
```
|
|
996
|
+
|
|
997
|
+
Read-only: nothing is claimed. `related` is what the frontmatter names
|
|
998
|
+
(`related_plans`, `related_docs`, `supports_plans`, `parent_plan`, `runlist` and
|
|
999
|
+
the configured reference fields), each with its title and status; `links` is
|
|
1000
|
+
every other document the body links to.
|
|
1001
|
+
|
|
1002
|
+
## Failed commands
|
|
1003
|
+
|
|
1004
|
+
Every runlist command that fails, by an error or a non-zero exit, appends one
|
|
1005
|
+
line to `~/.claude/logs/runlist-errors.log` (`RUNLIST_ERROR_LOG_DIR` moves it)
|
|
1006
|
+
with the time, the command with secrets redacted, and the error's one-line
|
|
1007
|
+
message. It rotates at 5 MB, a new runlist version, or 30 days of active
|
|
1008
|
+
history, retaining up to eight numbered backups for 30 days. Readers include
|
|
1009
|
+
the retained backups. Dry runs and the session-start `hud` are never logged.
|
|
1010
|
+
|
|
1011
|
+
```bash
|
|
1012
|
+
runlist errors # the newest 20 failures, newest first
|
|
1013
|
+
runlist errors --limit 50 # the newest N
|
|
1014
|
+
runlist errors --json # [{ at, command, message, repo, exit }]
|
|
1015
|
+
runlist errors --by-family --json # validation, unknown-command, conflicts, exceptions
|
|
1016
|
+
```
|
|
1017
|
+
|
|
1018
|
+
Validation findings remain non-zero results and remain in the raw chronological
|
|
1019
|
+
view. Grouping distinguishes those findings from command errors and unexpected
|
|
1020
|
+
exceptions. Failed `xref --check` entries include the first finding's file,
|
|
1021
|
+
line, and message.
|
|
1022
|
+
|
|
1023
|
+
The repository invocation journal remains opt-in through
|
|
1024
|
+
`export const journal = true;` in config or `RUNLIST_JOURNAL=1`. It uses the same retention policy.
|
|
1025
|
+
Top-level and per-command help calls record their topic and outcome without
|
|
1026
|
+
authored arguments. Use `runlist journal --help-topics --json` to see topic,
|
|
1027
|
+
session, version, and retained invocation counts. These denominators cover the
|
|
1028
|
+
retained opt-in window; passive context, HUD, dry runs, disabled journaling,
|
|
1029
|
+
and pruned history are excluded. They are not machine-wide usage rates.
|
|
1030
|
+
|
|
1031
|
+
## Safety Model
|
|
1032
|
+
|
|
1033
|
+
- Mutation commands support `--dry-run` / `-n`.
|
|
1034
|
+
- Managed writes are confined to configured document roots.
|
|
1035
|
+
- Lifecycle and multi-file moves use atomic, conflict-aware mutation paths.
|
|
1036
|
+
- Session ownership is durable local state, not inferred from telemetry.
|
|
1037
|
+
- Passive orientation commands do not mutate repository state.
|
|
1038
|
+
- Repository paths in machine and human output use stable slash-normalized
|
|
1039
|
+
identities across supported operating systems.
|
|
1040
|
+
|
|
1041
|
+
## Command Reference
|
|
1042
|
+
|
|
1043
|
+
The CLI is the source of truth for command syntax and options:
|
|
1044
|
+
|
|
1045
|
+
```bash
|
|
1046
|
+
runlist --help
|
|
1047
|
+
runlist help all
|
|
1048
|
+
runlist help statuses
|
|
1049
|
+
runlist <command> --help
|
|
12
1050
|
```
|
|
13
1051
|
|
|
14
|
-
|
|
1052
|
+
Shell completion is generated from the same command registry:
|
|
1053
|
+
|
|
1054
|
+
```bash
|
|
1055
|
+
eval "$(runlist completions bash)"
|
|
1056
|
+
eval "$(runlist completions zsh)"
|
|
1057
|
+
```
|
|
1058
|
+
|
|
1059
|
+
This README intentionally documents onboarding and concepts instead of
|
|
1060
|
+
duplicating the complete command catalog.
|
|
1061
|
+
|
|
1062
|
+
## Configuration
|
|
1063
|
+
|
|
1064
|
+
Run `runlist init` to create `runlist.config.mjs` (a legacy `dotmd.config.mjs` is still read). A minimal typed configuration:
|
|
1065
|
+
|
|
1066
|
+
```js
|
|
1067
|
+
export const root = 'docs';
|
|
1068
|
+
export const archiveDir = 'archived';
|
|
1069
|
+
|
|
1070
|
+
export const types = {
|
|
1071
|
+
plan: {
|
|
1072
|
+
statuses: {
|
|
1073
|
+
'in-session': { context: 'expanded', staleDays: 1 },
|
|
1074
|
+
active: { context: 'expanded', staleDays: 14 },
|
|
1075
|
+
planned: { context: 'listed', staleDays: 30 },
|
|
1076
|
+
archived: {
|
|
1077
|
+
context: 'counted',
|
|
1078
|
+
archive: true,
|
|
1079
|
+
terminal: true,
|
|
1080
|
+
skipStale: true,
|
|
1081
|
+
skipWarnings: true,
|
|
1082
|
+
},
|
|
1083
|
+
},
|
|
1084
|
+
},
|
|
1085
|
+
};
|
|
1086
|
+
```
|
|
1087
|
+
|
|
1088
|
+
### Code references
|
|
1089
|
+
|
|
1090
|
+
Archive and rename repair every reference inside the doc roots. `codeRoots`
|
|
1091
|
+
extends that to source files that cite a document by its repo-relative path in
|
|
1092
|
+
a comment, a docstring or a string literal:
|
|
1093
|
+
|
|
1094
|
+
```js
|
|
1095
|
+
export const codeRoots = ['packages', 'scripts', 'services'];
|
|
1096
|
+
export const codeRefsUntouched = ['scripts/guards/plan-baseline.json'];
|
|
1097
|
+
```
|
|
1098
|
+
|
|
1099
|
+
`runlist refs <old> <new>` reports every citation by file and line and writes
|
|
1100
|
+
only on `--fix`; `runlist refs repair` does the same for every archived
|
|
1101
|
+
document still cited at its previous path. Archive and rename print the count
|
|
1102
|
+
afterwards and take `--fix-refs`. Only the full repo-relative path matches,
|
|
1103
|
+
never a bare basename, and only that segment is replaced, so a trailing `§` or
|
|
1104
|
+
`#` anchor survives. A citation inside a string literal waits for `--strings`,
|
|
1105
|
+
a file in `codeRefsUntouched` is never written, and with no `codeRoots` set
|
|
1106
|
+
nothing is scanned.
|
|
1107
|
+
|
|
1108
|
+
Configuration supports multiple roots, custom types and templates, taxonomy,
|
|
1109
|
+
reference fields, presets, rendering, lifecycle hooks, validation hooks, and
|
|
1110
|
+
AI summarization hooks. See [`runlist.config.example.mjs`](runlist.config.example.mjs)
|
|
1111
|
+
for the complete annotated reference.
|
|
1112
|
+
|
|
1113
|
+
## Hooks
|
|
1114
|
+
|
|
1115
|
+
Functions exported from `runlist.config.mjs` are detected as hooks. They can add
|
|
1116
|
+
validation, customize rendering and summaries, or react to lifecycle events.
|
|
1117
|
+
Hooks receive the resolved config and command context; mutation hooks participate
|
|
1118
|
+
in the command's dry-run and failure contracts.
|
|
1119
|
+
|
|
1120
|
+
## License
|
|
1121
|
+
|
|
1122
|
+
MIT
|