@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 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 text / Delete
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 <text> quick add (priority: med)
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` | `text`, `project?`, `tags?`, `priority?`, `source?` | create a TODO |
142
- | `update` | `id`, `text?`, `priority?`, `status?`, `project?`, `tags?` | edit a TODO (set `status: parked` to defer) |
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, text, project, tags, priority (low|med|high|critical), status (open|in_progress|parked|done|cancelled), source, createdAt, updatedAt, closedAt`.
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: 2` schema. Not pi session entries, so it outlives any conversation.
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: [`docs/superpowers/specs/2026-07-20-lifecycle-boxes-prune-design.md`](docs/superpowers/specs/2026-07-20-lifecycle-boxes-prune-design.md). Original v0.1.0 spec: [`docs/todo-SPEC.md`](docs/todo-SPEC.md).
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` (147/147 across 7 suites).
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