@getpipher/armory-todo 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -8
- package/docs/superpowers/plans/2026-07-21-title-notes-split.md +1586 -0
- package/docs/superpowers/specs/2026-07-21-title-notes-split-design.md +411 -0
- package/docs/todo-SPEC.md +5 -0
- package/extensions/todo.ts +58 -28
- package/package.json +2 -2
- package/src/archive.ts +13 -3
- package/src/health.ts +17 -1
- package/src/migrate.ts +110 -1
- package/src/panel-data.ts +7 -14
- package/src/panel.ts +48 -4
- package/src/todo-store.ts +43 -21
package/README.md
CHANGED
|
@@ -92,6 +92,10 @@ todos. It's gated three ways:
|
|
|
92
92
|
Everything else in armory-todo is reversible. `prune --hard` is the one
|
|
93
93
|
irreversible escape hatch, always user-confirmed.
|
|
94
94
|
|
|
95
|
+
## Title + notes (v0.3.0)
|
|
96
|
+
|
|
97
|
+
The single `text` field is split into **`title`** (≤120 chars, one-line summary — the only thing injected into the prompt or shown in compact lists) and **`notes`** (any length, the running detail/log — never auto-injected). A hard cap rejects `title` >120 chars at `add`/`update` so the junk-drawer pattern can't re-form. `list` shows titles + a `•` marker when notes exist; `get <id>` reads a todo's full notes before acting on it. v2 `text`-only stores migrate on first load (curated for the 2 known todos + a first-line fallback).
|
|
98
|
+
|
|
95
99
|
## Interactive panel (SPEC-3)
|
|
96
100
|
|
|
97
101
|
Run `/todo` (no arg) in a TUI session to open the interactive triage panel:
|
|
@@ -99,7 +103,8 @@ Run `/todo` (no arg) in a TUI session to open the interactive triage panel:
|
|
|
99
103
|
- **Box tabs** (Tab / Shift+Tab): Active · Parked · Archive · Config
|
|
100
104
|
- **Filter input**: type to search by text (live filter)
|
|
101
105
|
- **SelectList**: arrow keys navigate, Enter selects
|
|
102
|
-
- **Action submenu** (on Enter): Complete / Park / Re-activate / Restore / Edit
|
|
106
|
+
- **Action submenu** (on Enter): View detail / Complete / Park / Re-activate / Restore / Edit title / Delete
|
|
107
|
+
- **Detail view** (View detail, or Enter on a row): renders the title + full `notes` read-only, with a footer hint on editing notes via the `todo` tool
|
|
103
108
|
- **Archive box**: summary-first (counts by project + month) → Enter on a bucket to drill down
|
|
104
109
|
- **Config box**: SettingsList with prune ages + health thresholds — edit live, persists to `todo.config.json`
|
|
105
110
|
- **Escape**: exit the panel
|
|
@@ -120,7 +125,7 @@ Typed subcommands (`/todo park <id>`, `/todo prune`, etc.) all still work alongs
|
|
|
120
125
|
```
|
|
121
126
|
/todo list open + in-progress TODOs
|
|
122
127
|
/todo all include parked/done/cancelled
|
|
123
|
-
/todo add <
|
|
128
|
+
/todo add <title> quick add (priority: med; notes via the todo tool)
|
|
124
129
|
/todo done <id> mark done
|
|
125
130
|
/todo rm <id> cancel (tombstone)
|
|
126
131
|
/todo park <id> defer (parked — not injected, recoverable)
|
|
@@ -138,8 +143,9 @@ Typed subcommands (`/todo park <id>`, `/todo prune`, etc.) all still work alongs
|
|
|
138
143
|
| action | params | effect |
|
|
139
144
|
|---|---|---|
|
|
140
145
|
| `list` | `statusFilter?`, `projectFilter?`, `tagFilter?`, `text?`, `since?`, `before?`, `limit?`, `page?`, `archived?` | matching TODOs (default: open + in_progress). `archived:true` queries the archive — bare call returns a summary, filters return paginated slices |
|
|
141
|
-
| `add` | `
|
|
142
|
-
| `
|
|
146
|
+
| `add` | `title`, `notes?`, `project?`, `tags?`, `priority?`, `source?` | create a TODO (`title` ≤120 chars; long detail goes in `notes`) |
|
|
147
|
+
| `get` | `id` | read a TODO's full record incl. `notes` |
|
|
148
|
+
| `update` | `id`, `title?`, `notes?`, `priority?`, `status?`, `project?`, `tags?` | edit a TODO (set `status: parked` to defer; `notes=""` clears) |
|
|
143
149
|
| `complete` | `id` | mark done |
|
|
144
150
|
| `delete` | `id` | cancel (tombstone) |
|
|
145
151
|
| `park` | `id` | defer (parked — not injected) |
|
|
@@ -149,17 +155,20 @@ Typed subcommands (`/todo park <id>`, `/todo prune`, etc.) all still work alongs
|
|
|
149
155
|
| `prune` (hard) | `hard:true`, `confirm:true`, `box?`, `olderThan?`, `project?`, `tag?` | PERMANENT deletion — the only irreversible action |
|
|
150
156
|
| `clear` | `status?` (default `done`) | bulk-clear a status (deprecated — use prune) |
|
|
151
157
|
|
|
152
|
-
Each TODO carries `id,
|
|
158
|
+
Each TODO carries `id, title (≤120 chars), notes (any length), project, tags, priority (low|med|high|critical), status (open|in_progress|parked|done|cancelled), source, createdAt, updatedAt, closedAt`. The auto-injected block + list/panel show `title` only; `notes` is read via `get` and never injected.
|
|
153
159
|
|
|
154
160
|
## How it works
|
|
155
161
|
|
|
156
|
-
- **Disk store** — `~/.pi/agent/todo/` folder: `todo.json` (live: active + parked), `todo-archive.json` (sealed: done + cancelled), `todo.config.json` (prune ages + health thresholds). Atomic `0600` writes, corrupt-file auto-recovery, `version:
|
|
162
|
+
- **Disk store** — `~/.pi/agent/todo/` folder: `todo.json` (live: active + parked), `todo-archive.json` (sealed: done + cancelled), `todo.config.json` (prune ages + health thresholds). Atomic `0600` writes, corrupt-file auto-recovery, `version: 3` schema (`title` ≤120 chars + `notes` any length; v2 `text`-only stores migrate to v3 on first load). Not pi session entries, so it outlives any conversation.
|
|
157
163
|
- **`todo` tool** — model CRUD + lifecycle (above).
|
|
158
164
|
- **`/todo` command** — human triage (above).
|
|
159
165
|
- **Auto-inject** — on every `before_agent_start`, a compact `## Open TODOs (N)` block (titles + ids, capped at 15, sorted by priority) is appended to the system prompt, so the agent starts every turn already aware of pending work. Only `open` + `in_progress` are injected — `parked` and archived todos are excluded (the lifecycle-box boundary). Mutations refresh it on the next turn.
|
|
160
166
|
- **Archive query** — `list` with `archived:true` is summary-first (counts by project + month) then filtered/paginated on demand, so a large archive never bloats a single query.
|
|
161
167
|
|
|
162
|
-
Full design + decisions:
|
|
168
|
+
Full design + decisions:
|
|
169
|
+
- v0.3.0 (title + notes split): [`docs/superpowers/specs/2026-07-21-title-notes-split-design.md`](docs/superpowers/specs/2026-07-21-title-notes-split-design.md)
|
|
170
|
+
- v0.2.0 (lifecycle boxes + prune + health): [`docs/superpowers/specs/2026-07-20-lifecycle-boxes-prune-design.md`](docs/superpowers/specs/2026-07-20-lifecycle-boxes-prune-design.md)
|
|
171
|
+
- Original v0.1.0 spec: [`docs/todo-SPEC.md`](docs/todo-SPEC.md)
|
|
163
172
|
|
|
164
173
|
## Configuration
|
|
165
174
|
|
|
@@ -167,7 +176,12 @@ Full design + decisions: [`docs/superpowers/specs/2026-07-20-lifecycle-boxes-pru
|
|
|
167
176
|
|---|---|---|
|
|
168
177
|
| `TODO_DIR` | `~/.pi/agent/todo/` | override the store folder (tests / multiple profiles) |
|
|
169
178
|
|
|
170
|
-
Run the store tests: `npm test` (
|
|
179
|
+
Run the store tests: `npm test` (220/220 across 8 suites).
|
|
180
|
+
|
|
181
|
+
## Known issues
|
|
182
|
+
|
|
183
|
+
- **No in-panel multi-line `notes` editing.** The panel's inline Edit is single-line (`Input`) for `title` only; `ctx.ui.editor()` from inside `ctx.ui.custom()` triggers a nested-UI bug (`/todo` won't reopen). `notes` is model-managed via the `todo` tool (`action: update, id, notes`). When a safe `ctx.ui.editor()`-from-`custom()` pattern lands in pi-tui, in-panel notes editing is a clean follow-up.
|
|
184
|
+
- **Preventive caps-on-add** (notes length cap + project registry) are deferred to Workstream C (v0.4.0). Until then, `health` reports notes-bytes as a read-only diagnostic.
|
|
171
185
|
|
|
172
186
|
## Security
|
|
173
187
|
|