saga-mcp 1.8.3 → 1.10.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.
Files changed (42) hide show
  1. package/README.md +51 -2
  2. package/dist/db.js +52 -0
  3. package/dist/db.js.map +1 -1
  4. package/dist/helpers/coerce.d.ts +46 -0
  5. package/dist/helpers/coerce.js +156 -0
  6. package/dist/helpers/coerce.js.map +1 -0
  7. package/dist/helpers/slim.js +1 -1
  8. package/dist/helpers/slim.js.map +1 -1
  9. package/dist/helpers/sql-builder.js +7 -1
  10. package/dist/helpers/sql-builder.js.map +1 -1
  11. package/dist/helpers/visibility.d.ts +39 -0
  12. package/dist/helpers/visibility.js +46 -0
  13. package/dist/helpers/visibility.js.map +1 -0
  14. package/dist/tools/activity.js +2 -1
  15. package/dist/tools/activity.js.map +1 -1
  16. package/dist/tools/dashboard.js +30 -6
  17. package/dist/tools/dashboard.js.map +1 -1
  18. package/dist/tools/epics.js +45 -2
  19. package/dist/tools/epics.js.map +1 -1
  20. package/dist/tools/export-import.js +3 -1
  21. package/dist/tools/export-import.js.map +1 -1
  22. package/dist/tools/notes.js +2 -1
  23. package/dist/tools/notes.js.map +1 -1
  24. package/dist/tools/projects.js +2 -1
  25. package/dist/tools/projects.js.map +1 -1
  26. package/dist/tools/search.js +10 -1
  27. package/dist/tools/search.js.map +1 -1
  28. package/dist/tools/subtasks.js +17 -20
  29. package/dist/tools/subtasks.js.map +1 -1
  30. package/dist/tools/tasks.js +91 -4
  31. package/dist/tools/tasks.js.map +1 -1
  32. package/dist/tools/templates.js +2 -1
  33. package/dist/tools/templates.js.map +1 -1
  34. package/dist/web/index.js +5 -2
  35. package/dist/web/index.js.map +1 -1
  36. package/dist/web/queries.d.ts +3 -2
  37. package/dist/web/queries.js +21 -12
  38. package/dist/web/queries.js.map +1 -1
  39. package/dist/web/ui.js +72 -8
  40. package/dist/web/ui.js.map +1 -1
  41. package/manifest.json +1 -1
  42. package/package.json +1 -1
package/README.md CHANGED
@@ -12,7 +12,7 @@ lived in the context window, or in a `TODO.md` nobody updates.
12
12
 
13
13
  saga-mcp gives the agent a real tracker instead: a SQLite file in your project
14
14
  holding projects, epics, tasks, subtasks, dependencies, comments, notes and
15
- decisions, exposed as 35 MCP tools. The agent writes to it as it works and
15
+ decisions, exposed as 38 MCP tools. The agent writes to it as it works and
16
16
  reads the dashboard when it comes back. No accounts, no external service, no
17
17
  network calls — the database is a file you own.
18
18
 
@@ -76,7 +76,7 @@ recent activity, notes.
76
76
  - **Activity log**: Every mutation is automatically tracked with old/new values
77
77
  - **Notes system**: Decisions, context, meeting notes, blockers — all searchable
78
78
  - **Batch operations**: Create multiple subtasks or update multiple tasks in one call
79
- - **35 focused tools**: With MCP safety annotations on every tool
79
+ - **38 focused tools**: With MCP safety annotations on every tool
80
80
  - **Import/export**: Full project backup and migration as JSON (with dependencies and comments)
81
81
  - **Source references**: Link tasks to specific code locations
82
82
  - **Auto time tracking**: Hours computed automatically from activity log
@@ -180,6 +180,7 @@ import/export, session diffs and the rest discoverable.
180
180
  |------|-------------|-------------|
181
181
  | `epic_create` | Create an epic within a project | `readOnly: false` |
182
182
  | `epic_list` | List epics with task counts | `readOnly: true` |
183
+ | `epic_archive` | Archive/unarchive an epic, hiding it and its tasks from listings | `readOnly: false`, `idempotent: true` |
183
184
  | `epic_update` | Update an epic | `readOnly: false`, `idempotent: true` |
184
185
 
185
186
  ### Tasks
@@ -191,6 +192,8 @@ import/export, session diffs and the rest discoverable.
191
192
  | `task_get` | Get task with subtasks, notes, comments, and dependencies | `readOnly: true` |
192
193
  | `task_update` | Update task (auto-logs, auto-blocks/unblocks) | `readOnly: false`, `idempotent: true` |
193
194
  | `task_lock_description` | Lock/unlock a description so agents can't rewrite it | `readOnly: false`, `idempotent: true` |
195
+ | `task_delete` | Remove a `todo` task (soft delete, restorable) | `readOnly: false`, `idempotent: true` |
196
+ | `task_restore` | Restore a removed task | `readOnly: false`, `idempotent: true` |
194
197
  | `task_batch_update` | Update multiple tasks at once | `readOnly: false`, `idempotent: true` |
195
198
 
196
199
  ### Subtasks
@@ -360,6 +363,51 @@ project was a guess, rather than silently reporting on the wrong repo.
360
363
  The web UI is unaffected either way: its project switcher lists every project in the database, and
361
364
  each tab is scoped to the selected one.
362
365
 
366
+ ## Forgiving input
367
+
368
+ Smaller models routinely send an array parameter as a *string* containing JSON.
369
+ Every array-taking tool accepts that, so a batch does not silently collapse into one record:
370
+
371
+ ```
372
+ subtask_create({ task_id: 3, titles: '["Write it","Test it"]' }) # 2 subtasks
373
+ subtask_create({ task_id: 3, titles: "- Write it
374
+ - Test it" }) # 2 subtasks
375
+ task_batch_update({ ids: "[4,5]", status: "done" }) # both tasks
376
+ task_create({ epic_id: 1, title: "x", tags: "billing, urgent" }) # 2 tags
377
+ ```
378
+
379
+ Coercion stops where intent becomes ambiguous. A comma inside a *title* is left alone —
380
+ `"Design the API, then implement it"` is one subtask, not two — while a comma in a tag or an id
381
+ list is a separator, because neither can contain one. Anything genuinely unusable is refused with
382
+ a message naming what arrived and what was wanted, rather than a leaked `ids.map is not a function`.
383
+
384
+ ## Getting old work out of the way
385
+
386
+ An epic list that is mostly finished work, and tasks an agent created that should have been
387
+ subtasks, are context you pay for on every call.
388
+
389
+ ```
390
+ epic_archive({ id: 4 }) # the epic and its tasks drop out of listings
391
+ task_delete({ id: 12, reason: "should have been a subtask" })
392
+ ```
393
+
394
+ Archiving is deliberately **not** the `cancelled` status: `cancelled` means "we decided not to do
395
+ this", while most of what you want to archive is *completed*. Archived epics and their tasks
396
+ disappear from `epic_list`, `tracker_dashboard`, `task_list` and `tracker_search` — including the
397
+ statistics, not just the lists — and come back with `include_archived`.
398
+
399
+ Nothing vanishes silently. The dashboard says what it left out:
400
+
401
+ ```
402
+ Hidden: 2 archived epic(s) and 1 removed task(s) — pass include_archived to include them.
403
+ ```
404
+
405
+ `task_delete` is the same soft delete comments have, restricted to tasks still in `todo`:
406
+ anything further along has comments, time tracking and an activity log that removing it would
407
+ strand, and a task other tasks depend on is refused outright so nothing is left blocked forever.
408
+ The row is kept, `task_restore` brings it back, and `tracker_export` includes archived and removed
409
+ rows because a backup that omits things is not a backup.
410
+
363
411
  ## Keeping agents on the rails
364
412
 
365
413
  Two guards for the ways an agent goes wrong on a long task.
@@ -439,6 +487,7 @@ What you get:
439
487
  - **Board** — kanban across the five task statuses; drag a card to change its status
440
488
  - **Epics** — the full Epic → Task → Subtask tree, which is the fastest way to review a spec an agent just wrote
441
489
  - **Notes** and **Activity** — decisions and the complete change history
490
+ - **Archived section** — archived epics collapse below a divider, with a "show archived (N)" toggle
442
491
  - **Task drawer** — edit any field, comment, remove or restore a comment, lock the description, drag subtasks into order, and set which subtasks wait on which. Each subtask has one control carrying its whole state (todo / in progress / done, or blocked), and the drawer resizes by dragging its edge
443
492
  - **Project switcher** — every project in the database, so one central `.tracker.db` covers all your repos; every tab, including Activity, is scoped to the selected project
444
493
  - **Shareable, refreshable URLs** — the open project, tab and task live in the address bar, so a browser refresh puts you back where you were and back/forward move between tasks. A ⟳ button in the task drawer re-reads that task without a page reload, for picking up what an agent just wrote
package/dist/db.js CHANGED
@@ -51,6 +51,58 @@ export function getDb() {
51
51
  db.exec('ALTER TABLE tasks ADD COLUMN description_locked INTEGER NOT NULL DEFAULT 0');
52
52
  }
53
53
  catch { /* column already exists */ }
54
+ // #30: archiving an epic hides it without pretending it was cancelled, and a
55
+ // todo task can be removed the way a comment can — kept, hidden, restorable.
56
+ try {
57
+ db.exec('ALTER TABLE epics ADD COLUMN archived INTEGER NOT NULL DEFAULT 0');
58
+ }
59
+ catch { /* column already exists */ }
60
+ try {
61
+ db.exec('ALTER TABLE epics ADD COLUMN archived_at TEXT');
62
+ }
63
+ catch { /* column already exists */ }
64
+ try {
65
+ db.exec('ALTER TABLE tasks ADD COLUMN is_deleted INTEGER NOT NULL DEFAULT 0');
66
+ }
67
+ catch { /* column already exists */ }
68
+ try {
69
+ db.exec('ALTER TABLE tasks ADD COLUMN deleted_at TEXT');
70
+ }
71
+ catch { /* column already exists */ }
72
+ try {
73
+ db.exec('ALTER TABLE tasks ADD COLUMN deleted_by TEXT');
74
+ }
75
+ catch { /* column already exists */ }
76
+ try {
77
+ db.exec('ALTER TABLE tasks ADD COLUMN delete_reason TEXT');
78
+ }
79
+ catch { /* column already exists */ }
80
+ try {
81
+ db.exec('CREATE INDEX IF NOT EXISTS idx_epics_archived ON epics(project_id, archived)');
82
+ }
83
+ catch { /* index already exists */ }
84
+ try {
85
+ db.exec('CREATE INDEX IF NOT EXISTS idx_tasks_live ON tasks(epic_id, is_deleted)');
86
+ }
87
+ catch { /* index already exists */ }
88
+ // #29 left corrupted tags behind: a tags array sent as a JSON *string* was
89
+ // stored verbatim, so the column held a string rather than an array. The UI
90
+ // then rendered one pill per character and json_each tag filters matched
91
+ // nothing. Repair what is recoverable, losslessly.
92
+ for (const table of ['projects', 'epics', 'tasks', 'notes']) {
93
+ try {
94
+ // A JSON string that is itself a JSON array — unwrap it.
95
+ db.exec(`UPDATE ${table} SET tags = json_extract(tags, '$')
96
+ WHERE json_valid(tags) AND json_type(tags) = 'text'
97
+ AND json_valid(json_extract(tags, '$'))
98
+ AND json_type(json_extract(tags, '$')) = 'array'`);
99
+ // Anything still stored as a bare string becomes a single-element array.
100
+ // Nothing is split or invented; the text is preserved exactly.
101
+ db.exec(`UPDATE ${table} SET tags = json_array(json_extract(tags, '$'))
102
+ WHERE json_valid(tags) AND json_type(tags) = 'text'`);
103
+ }
104
+ catch { /* table may not exist yet on a fresh database */ }
105
+ }
54
106
  return db;
55
107
  }
56
108
  export function closeDb() {
package/dist/db.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"db.js","sourceRoot":"","sources":["../src/db.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,IAAI,EAAE,GAA6B,IAAI,CAAC;AAExC,MAAM,UAAU,KAAK;IACnB,IAAI,EAAE;QAAE,OAAO,EAAE,CAAC;IAElB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC;IACnC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CACb,mIAAmI,CACpI,CAAC;IACJ,CAAC;IAED,EAAE,GAAG,IAAI,QAAQ,CAAC,MAAM,CAAC,CAAC;IAE1B,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;IAChC,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC;IAC/B,EAAE,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC;IACjC,EAAE,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC;IAElC,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAEpB,oCAAoC;IACpC,IAAI,CAAC;QAAC,EAAE,CAAC,IAAI,CAAC,8CAA8C,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAC,2BAA2B,CAAC,CAAC;IACtG,IAAI,CAAC;QAAC,EAAE,CAAC,IAAI,CAAC,0CAA0C,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAC,2BAA2B,CAAC,CAAC;IAClG,IAAI,CAAC;QAAC,EAAE,CAAC,IAAI,CAAC,8DAA8D,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAC,0BAA0B,CAAC,CAAC;IACrH,IAAI,CAAC;QAAC,EAAE,CAAC,IAAI,CAAC,uEAAuE,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAC,2BAA2B,CAAC,CAAC;IAC/H,IAAI,CAAC;QAAC,EAAE,CAAC,IAAI,CAAC,iDAAiD,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAC,2BAA2B,CAAC,CAAC;IACzG,IAAI,CAAC;QAAC,EAAE,CAAC,IAAI,CAAC,iDAAiD,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAC,2BAA2B,CAAC,CAAC;IACzG,IAAI,CAAC;QAAC,EAAE,CAAC,IAAI,CAAC,oDAAoD,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAC,2BAA2B,CAAC,CAAC;IAC5G,IAAI,CAAC;QAAC,EAAE,CAAC,IAAI,CAAC,oFAAoF,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAC,0BAA0B,CAAC,CAAC;IAC3I,IAAI,CAAC;QAAC,EAAE,CAAC,IAAI,CAAC,4EAA4E,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAC,2BAA2B,CAAC,CAAC;IAEpI,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,MAAM,UAAU,OAAO;IACrB,IAAI,EAAE,EAAE,CAAC;QACP,EAAE,CAAC,KAAK,EAAE,CAAC;QACX,EAAE,GAAG,IAAI,CAAC;IACZ,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"db.js","sourceRoot":"","sources":["../src/db.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Normalising what models actually send.
3
+ *
4
+ * Reported as #29: a batch of subtasks arrived as one record. The cause is
5
+ * general — smaller models routinely send an array parameter as a *string*
6
+ * containing JSON, and every array-taking tool here assumed a real array. The
7
+ * results ranged from bad to silent:
8
+ *
9
+ * subtask_create titles: '["a","b"]' -> one subtask literally titled ["a","b"]
10
+ * task_batch_update ids: '[1,2]' -> "ids.map is not a function"
11
+ * subtask_reorder ordered_ids: '[1]' -> "orderedIds.filter is not a function"
12
+ * subtask_update depends_on: '[4]' -> "Subtask(s) not found: [, 4, ]"
13
+ * tags: '["a","b"]' -> stored as a string, then rendered as
14
+ * one tag pill per character
15
+ *
16
+ * So these helpers accept what a model is likely to send, and refuse the rest
17
+ * with a message that says what arrived and what was wanted — a leaked
18
+ * TypeError teaches an agent nothing.
19
+ *
20
+ * The rules are deliberately conservative. Coercion only happens where the
21
+ * intent is unambiguous; anything that could plausibly be a legitimate single
22
+ * value is left alone.
23
+ */
24
+ /**
25
+ * A list of titles. Accepts an array, a JSON array written as a string, or a
26
+ * single string. A single string holding several lines is split, because a
27
+ * model asked for a checklist commonly returns one — bullets and numbering are
28
+ * stripped.
29
+ *
30
+ * Commas are deliberately NOT split on: "Design the API, then implement it" is
31
+ * a perfectly ordinary single title, and guessing there would quietly turn one
32
+ * subtask into two.
33
+ */
34
+ export declare function asTitleList(value: unknown, field?: string): string[];
35
+ /**
36
+ * A list of ids. Accepts an array, a single number, numeric strings, and a JSON
37
+ * array written as a string. Anything else is refused by name.
38
+ */
39
+ export declare function asIdList(value: unknown, field?: string): number[];
40
+ /**
41
+ * A list of tags. Unlike titles, tags are keyword-like, so a single string
42
+ * holding commas is split — that is what "tags: a,b" plainly means.
43
+ */
44
+ export declare function asTagList(value: unknown, field?: string): string[];
45
+ /** Tags ready for the column, so every writer stores the same shape. */
46
+ export declare function tagsColumn(value: unknown): string;
@@ -0,0 +1,156 @@
1
+ /**
2
+ * Normalising what models actually send.
3
+ *
4
+ * Reported as #29: a batch of subtasks arrived as one record. The cause is
5
+ * general — smaller models routinely send an array parameter as a *string*
6
+ * containing JSON, and every array-taking tool here assumed a real array. The
7
+ * results ranged from bad to silent:
8
+ *
9
+ * subtask_create titles: '["a","b"]' -> one subtask literally titled ["a","b"]
10
+ * task_batch_update ids: '[1,2]' -> "ids.map is not a function"
11
+ * subtask_reorder ordered_ids: '[1]' -> "orderedIds.filter is not a function"
12
+ * subtask_update depends_on: '[4]' -> "Subtask(s) not found: [, 4, ]"
13
+ * tags: '["a","b"]' -> stored as a string, then rendered as
14
+ * one tag pill per character
15
+ *
16
+ * So these helpers accept what a model is likely to send, and refuse the rest
17
+ * with a message that says what arrived and what was wanted — a leaked
18
+ * TypeError teaches an agent nothing.
19
+ *
20
+ * The rules are deliberately conservative. Coercion only happens where the
21
+ * intent is unambiguous; anything that could plausibly be a legitimate single
22
+ * value is left alone.
23
+ */
24
+ /** `["a","b"]` or `['a','b']` written as a string, or null if it is not that. */
25
+ function parseArrayLiteral(text) {
26
+ const trimmed = text.trim();
27
+ if (!trimmed.startsWith('[') || !trimmed.endsWith(']'))
28
+ return null;
29
+ try {
30
+ const parsed = JSON.parse(trimmed);
31
+ return Array.isArray(parsed) ? parsed : null;
32
+ }
33
+ catch {
34
+ // Models often emit Python-ish single quotes. Only retry when the string
35
+ // holds no double quotes of its own, so nothing is mangled.
36
+ if (trimmed.includes('"'))
37
+ return null;
38
+ try {
39
+ const parsed = JSON.parse(trimmed.replace(/'/g, '"'));
40
+ return Array.isArray(parsed) ? parsed : null;
41
+ }
42
+ catch {
43
+ return null;
44
+ }
45
+ }
46
+ }
47
+ /** Unwrap the common `['["a","b"]']` shape — an array holding one JSON string. */
48
+ function unwrapSingleEncoded(items) {
49
+ if (items.length !== 1 || typeof items[0] !== 'string')
50
+ return items;
51
+ return parseArrayLiteral(items[0]) ?? items;
52
+ }
53
+ /**
54
+ * A list of titles. Accepts an array, a JSON array written as a string, or a
55
+ * single string. A single string holding several lines is split, because a
56
+ * model asked for a checklist commonly returns one — bullets and numbering are
57
+ * stripped.
58
+ *
59
+ * Commas are deliberately NOT split on: "Design the API, then implement it" is
60
+ * a perfectly ordinary single title, and guessing there would quietly turn one
61
+ * subtask into two.
62
+ */
63
+ export function asTitleList(value, field = 'titles') {
64
+ const fromValue = (input) => {
65
+ if (Array.isArray(input)) {
66
+ return unwrapSingleEncoded(input).flatMap((item) => {
67
+ if (typeof item === 'string')
68
+ return fromValue(item);
69
+ // Models sometimes send [{title: "..."}] instead of ["..."].
70
+ if (item && typeof item === 'object' && typeof item.title === 'string') {
71
+ return [item.title.trim()];
72
+ }
73
+ throw new Error(`${field} must be strings. Received ${describe(item)}. Send ["First item", "Second item"].`);
74
+ });
75
+ }
76
+ if (typeof input === 'string') {
77
+ const asArray = parseArrayLiteral(input);
78
+ if (asArray)
79
+ return fromValue(asArray);
80
+ const lines = input
81
+ .split('\n')
82
+ .map((line) => line.replace(/^\s*(?:[-*•]|\d+[.)])\s+/, '').trim())
83
+ .filter(Boolean);
84
+ return lines.length > 1 ? lines : [input.trim()];
85
+ }
86
+ throw new Error(`${field} must be a string or an array of strings. Received ${describe(input)}.`);
87
+ };
88
+ const titles = fromValue(value).filter((t) => t.length > 0);
89
+ if (titles.length === 0)
90
+ throw new Error(`${field} is empty — nothing to create.`);
91
+ return titles;
92
+ }
93
+ /**
94
+ * A list of ids. Accepts an array, a single number, numeric strings, and a JSON
95
+ * array written as a string. Anything else is refused by name.
96
+ */
97
+ export function asIdList(value, field = 'ids') {
98
+ const toId = (item) => {
99
+ if (typeof item === 'number' && Number.isInteger(item))
100
+ return item;
101
+ if (typeof item === 'string' && /^\s*\d+\s*$/.test(item))
102
+ return Number(item.trim());
103
+ throw new Error(`${field} must contain whole numbers. Received ${describe(item)}. Send [1, 2, 3].`);
104
+ };
105
+ if (Array.isArray(value))
106
+ return unwrapSingleEncoded(value).map(toId);
107
+ if (typeof value === 'string') {
108
+ const parsed = parseArrayLiteral(value);
109
+ if (parsed)
110
+ return parsed.map(toId);
111
+ // "1,2,3" is unambiguous for ids — a title may contain a comma, an id cannot.
112
+ if (value.includes(','))
113
+ return value.split(',').map((part) => toId(part.trim()));
114
+ return [toId(value)];
115
+ }
116
+ if (typeof value === 'number')
117
+ return [toId(value)];
118
+ throw new Error(`${field} must be a number or an array of numbers. Received ${describe(value)}. Send [1, 2, 3].`);
119
+ }
120
+ /**
121
+ * A list of tags. Unlike titles, tags are keyword-like, so a single string
122
+ * holding commas is split — that is what "tags: a,b" plainly means.
123
+ */
124
+ export function asTagList(value, field = 'tags') {
125
+ if (value === undefined || value === null)
126
+ return [];
127
+ if (Array.isArray(value)) {
128
+ return unwrapSingleEncoded(value).flatMap((item) => asTagList(item, field));
129
+ }
130
+ if (typeof value === 'string') {
131
+ const parsed = parseArrayLiteral(value);
132
+ if (parsed)
133
+ return parsed.flatMap((item) => asTagList(item, field));
134
+ return value.split(',').map((t) => t.trim()).filter(Boolean);
135
+ }
136
+ if (typeof value === 'number' || typeof value === 'boolean')
137
+ return [String(value)];
138
+ throw new Error(`${field} must be strings. Received ${describe(value)}. Send ["billing", "urgent"].`);
139
+ }
140
+ /** Tags ready for the column, so every writer stores the same shape. */
141
+ export function tagsColumn(value) {
142
+ return JSON.stringify(asTagList(value));
143
+ }
144
+ /** A short, honest description of a value, for error messages. */
145
+ function describe(value) {
146
+ if (value === null)
147
+ return 'null';
148
+ if (Array.isArray(value))
149
+ return `an array (${JSON.stringify(value).slice(0, 60)})`;
150
+ if (typeof value === 'object')
151
+ return `an object (${JSON.stringify(value).slice(0, 60)})`;
152
+ if (typeof value === 'string')
153
+ return `the string ${JSON.stringify(value.slice(0, 60))}`;
154
+ return `${typeof value} (${String(value)})`;
155
+ }
156
+ //# sourceMappingURL=coerce.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coerce.js","sourceRoot":"","sources":["../../src/helpers/coerce.ts"],"names":[],"mappings":"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"}
@@ -17,7 +17,7 @@ export function truncate(text, max = LIST_DESCRIPTION_CHARS) {
17
17
  /** Fields never worth their bytes in a list response. */
18
18
  const ALWAYS_DROP = new Set(['metadata']);
19
19
  /** Flags that only matter when set — carrying the common `0` is pure noise. */
20
- const DROP_WHEN_ZERO = new Set(['description_locked', 'is_deleted']);
20
+ const DROP_WHEN_ZERO = new Set(['description_locked', 'is_deleted', 'archived']);
21
21
  /**
22
22
  * Strip a list row down: no nulls, no metadata blob, no empty tags array, and
23
23
  * long text fields truncated. Everything removed here is still available from
@@ -1 +1 @@
1
- {"version":3,"file":"slim.js","sourceRoot":"","sources":["../../src/helpers/slim.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,mFAAmF;AACnF,MAAM,CAAC,MAAM,sBAAsB,GAAG,GAAG,CAAC;AAE1C,MAAM,UAAU,QAAQ,CAAC,IAAY,EAAE,GAAG,GAAG,sBAAsB;IACjE,IAAI,IAAI,CAAC,MAAM,IAAI,GAAG;QAAE,OAAO,IAAI,CAAC;IACpC,0EAA0E;IAC1E,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC/B,MAAM,SAAS,GAAG,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IACvC,OAAO,CAAC,SAAS,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,GAAG,GAAG,CAAC;AACjF,CAAC;AAED,yDAAyD;AACzD,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;AAE1C,+EAA+E;AAC/E,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,CAAC,oBAAoB,EAAE,YAAY,CAAC,CAAC,CAAC;AAErE;;;;GAIG;AACH,MAAM,UAAU,WAAW,CACzB,GAA4B,EAC5B,iBAA2B,CAAC,aAAa,CAAC,EAC1C,OAAiB,EAAE;IAEnB,MAAM,GAAG,GAA4B,EAAE,CAAC;IACxC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/C,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS;YAAE,SAAS;QACpD,IAAI,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;YAAE,SAAS;QACzD,IAAI,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC,IAAI,KAAK,KAAK,KAAK,CAAC;YAAE,SAAS;QAC1E,IAAI,GAAG,KAAK,MAAM,IAAI,CAAC,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC;YAAE,SAAS;QACjE,IAAI,cAAc,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC9D,GAAG,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;YAC3B,SAAS;QACX,CAAC;QACD,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IACnB,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,6CAA6C;AAC7C,MAAM,UAAU,QAAQ,CACtB,IAAoC,EACpC,cAAyB,EACzB,IAAe;IAEf,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,CAAC,CAAC,CAAC;AACnE,CAAC"}
1
+ {"version":3,"file":"slim.js","sourceRoot":"","sources":["../../src/helpers/slim.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,mFAAmF;AACnF,MAAM,CAAC,MAAM,sBAAsB,GAAG,GAAG,CAAC;AAE1C,MAAM,UAAU,QAAQ,CAAC,IAAY,EAAE,GAAG,GAAG,sBAAsB;IACjE,IAAI,IAAI,CAAC,MAAM,IAAI,GAAG;QAAE,OAAO,IAAI,CAAC;IACpC,0EAA0E;IAC1E,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC/B,MAAM,SAAS,GAAG,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IACvC,OAAO,CAAC,SAAS,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,GAAG,GAAG,CAAC;AACjF,CAAC;AAED,yDAAyD;AACzD,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;AAE1C,+EAA+E;AAC/E,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,CAAC,oBAAoB,EAAE,YAAY,EAAE,UAAU,CAAC,CAAC,CAAC;AAEjF;;;;GAIG;AACH,MAAM,UAAU,WAAW,CACzB,GAA4B,EAC5B,iBAA2B,CAAC,aAAa,CAAC,EAC1C,OAAiB,EAAE;IAEnB,MAAM,GAAG,GAA4B,EAAE,CAAC;IACxC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/C,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS;YAAE,SAAS;QACpD,IAAI,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;YAAE,SAAS;QACzD,IAAI,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC,IAAI,KAAK,KAAK,KAAK,CAAC;YAAE,SAAS;QAC1E,IAAI,GAAG,KAAK,MAAM,IAAI,CAAC,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC;YAAE,SAAS;QACjE,IAAI,cAAc,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC9D,GAAG,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;YAC3B,SAAS;QACX,CAAC;QACD,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IACnB,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,6CAA6C;AAC7C,MAAM,UAAU,QAAQ,CACtB,IAAoC,EACpC,cAAyB,EACzB,IAAe;IAEf,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,CAAC,CAAC,CAAC;AACnE,CAAC"}
@@ -1,3 +1,4 @@
1
+ import { tagsColumn } from './coerce.js';
1
2
  const JSON_COLUMNS = new Set(['tags', 'metadata', 'source_ref']);
2
3
  export function buildUpdate(table, id, fields, allowedColumns) {
3
4
  const updates = [];
@@ -5,7 +6,12 @@ export function buildUpdate(table, id, fields, allowedColumns) {
5
6
  for (const col of allowedColumns) {
6
7
  if (fields[col] !== undefined) {
7
8
  updates.push(`${col} = ?`);
8
- params.push(JSON_COLUMNS.has(col) ? JSON.stringify(fields[col]) : fields[col]);
9
+ // Tags go through the normaliser so an update cannot store the shape a
10
+ // create would have rejected — addTagFilter runs json_each over this.
11
+ if (col === 'tags')
12
+ params.push(tagsColumn(fields[col]));
13
+ else
14
+ params.push(JSON_COLUMNS.has(col) ? JSON.stringify(fields[col]) : fields[col]);
9
15
  }
10
16
  }
11
17
  if (updates.length === 0)
@@ -1 +1 @@
1
- {"version":3,"file":"sql-builder.js","sourceRoot":"","sources":["../../src/helpers/sql-builder.ts"],"names":[],"mappings":"AAAA,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC,CAAC;AAEjE,MAAM,UAAU,WAAW,CACzB,KAAa,EACb,EAAU,EACV,MAA+B,EAC/B,cAAwB;IAExB,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,MAAM,GAAc,EAAE,CAAC;IAE7B,KAAK,MAAM,GAAG,IAAI,cAAc,EAAE,CAAC;QACjC,IAAI,MAAM,CAAC,GAAG,CAAC,KAAK,SAAS,EAAE,CAAC;YAC9B,OAAO,CAAC,IAAI,CAAC,GAAG,GAAG,MAAM,CAAC,CAAC;YAC3B,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QACjF,CAAC;IACH,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAEtC,OAAO,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;IAC7C,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEhB,OAAO;QACL,GAAG,EAAE,UAAU,KAAK,QAAQ,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,2BAA2B;QACzE,MAAM;KACP,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,YAAY,CAC1B,YAAsB,EACtB,MAAiB,EACjB,GAAW,EACX,KAAa;IAEb,YAAY,CAAC,IAAI,CACf,mCAAmC,KAAK,mCAAmC,CAC5E,CAAC;IACF,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACnB,CAAC"}
1
+ {"version":3,"file":"sql-builder.js","sourceRoot":"","sources":["../../src/helpers/sql-builder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC,CAAC;AAEjE,MAAM,UAAU,WAAW,CACzB,KAAa,EACb,EAAU,EACV,MAA+B,EAC/B,cAAwB;IAExB,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,MAAM,GAAc,EAAE,CAAC;IAE7B,KAAK,MAAM,GAAG,IAAI,cAAc,EAAE,CAAC;QACjC,IAAI,MAAM,CAAC,GAAG,CAAC,KAAK,SAAS,EAAE,CAAC;YAC9B,OAAO,CAAC,IAAI,CAAC,GAAG,GAAG,MAAM,CAAC,CAAC;YAC3B,uEAAuE;YACvE,sEAAsE;YACtE,IAAI,GAAG,KAAK,MAAM;gBAAE,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;;gBACpD,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QACtF,CAAC;IACH,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAEtC,OAAO,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;IAC7C,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEhB,OAAO;QACL,GAAG,EAAE,UAAU,KAAK,QAAQ,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,2BAA2B;QACzE,MAAM;KACP,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,YAAY,CAC1B,YAAsB,EACtB,MAAiB,EACjB,GAAW,EACX,KAAa;IAEb,YAAY,CAAC,IAAI,CACf,mCAAmC,KAAK,mCAAmC,CAC5E,CAAC;IACF,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACnB,CAAC"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * What a listing shows by default.
3
+ *
4
+ * #30: after a while the epic list is mostly finished work, and agents leave
5
+ * behind tasks that should have been subtasks. Both are noise an agent pays
6
+ * for on every call, so both can be put out of sight without being destroyed.
7
+ *
8
+ * Two separate ideas, deliberately not merged into one:
9
+ *
10
+ * epics.archived — "stop showing me this". Distinct from the `cancelled`
11
+ * status, which means "we decided not to do it": most of
12
+ * what you want to archive is *completed*, and overloading
13
+ * the status would make that impossible to say.
14
+ * tasks.is_deleted — the same soft delete comments already have. Restricted
15
+ * to `todo` tasks, because a task with real history has an
16
+ * activity log that deleting it would orphan.
17
+ *
18
+ * Nothing is hidden silently: the dashboard reports how much it left out.
19
+ */
20
+ /** SQL fragment hiding archived epics, given the alias the caller used. */
21
+ export declare function liveEpicClause(alias?: string): string;
22
+ /**
23
+ * SQL fragment hiding removed tasks, and tasks belonging to an archived epic —
24
+ * an epic you have put away should not keep sending its tasks to the model.
25
+ */
26
+ export declare function liveTaskClause(taskAlias?: string, epicAlias?: string): string;
27
+ /** Whether a caller asked to see hidden rows. Accepts the usual truthy shapes. */
28
+ export declare function wantsHidden(value: unknown): boolean;
29
+ /** Shared schema fragments, so every tool documents these identically. */
30
+ export declare const INCLUDE_ARCHIVED_SCHEMA: {
31
+ type: "boolean";
32
+ default: boolean;
33
+ description: string;
34
+ };
35
+ export declare const INCLUDE_DELETED_TASKS_SCHEMA: {
36
+ type: "boolean";
37
+ default: boolean;
38
+ description: string;
39
+ };
@@ -0,0 +1,46 @@
1
+ /**
2
+ * What a listing shows by default.
3
+ *
4
+ * #30: after a while the epic list is mostly finished work, and agents leave
5
+ * behind tasks that should have been subtasks. Both are noise an agent pays
6
+ * for on every call, so both can be put out of sight without being destroyed.
7
+ *
8
+ * Two separate ideas, deliberately not merged into one:
9
+ *
10
+ * epics.archived — "stop showing me this". Distinct from the `cancelled`
11
+ * status, which means "we decided not to do it": most of
12
+ * what you want to archive is *completed*, and overloading
13
+ * the status would make that impossible to say.
14
+ * tasks.is_deleted — the same soft delete comments already have. Restricted
15
+ * to `todo` tasks, because a task with real history has an
16
+ * activity log that deleting it would orphan.
17
+ *
18
+ * Nothing is hidden silently: the dashboard reports how much it left out.
19
+ */
20
+ /** SQL fragment hiding archived epics, given the alias the caller used. */
21
+ export function liveEpicClause(alias = 'e') {
22
+ return `${alias}.archived = 0`;
23
+ }
24
+ /**
25
+ * SQL fragment hiding removed tasks, and tasks belonging to an archived epic —
26
+ * an epic you have put away should not keep sending its tasks to the model.
27
+ */
28
+ export function liveTaskClause(taskAlias = 't', epicAlias = 'e') {
29
+ return `${taskAlias}.is_deleted = 0 AND ${epicAlias}.archived = 0`;
30
+ }
31
+ /** Whether a caller asked to see hidden rows. Accepts the usual truthy shapes. */
32
+ export function wantsHidden(value) {
33
+ return value === true || value === 'true' || value === 1 || value === '1';
34
+ }
35
+ /** Shared schema fragments, so every tool documents these identically. */
36
+ export const INCLUDE_ARCHIVED_SCHEMA = {
37
+ type: 'boolean',
38
+ default: false,
39
+ description: 'Include archived epics and their tasks.',
40
+ };
41
+ export const INCLUDE_DELETED_TASKS_SCHEMA = {
42
+ type: 'boolean',
43
+ default: false,
44
+ description: 'Include removed tasks.',
45
+ };
46
+ //# sourceMappingURL=visibility.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"visibility.js","sourceRoot":"","sources":["../../src/helpers/visibility.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,2EAA2E;AAC3E,MAAM,UAAU,cAAc,CAAC,KAAK,GAAG,GAAG;IACxC,OAAO,GAAG,KAAK,eAAe,CAAC;AACjC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,SAAS,GAAG,GAAG,EAAE,SAAS,GAAG,GAAG;IAC7D,OAAO,GAAG,SAAS,uBAAuB,SAAS,eAAe,CAAC;AACrE,CAAC;AAED,kFAAkF;AAClF,MAAM,UAAU,WAAW,CAAC,KAAc;IACxC,OAAO,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,CAAC,IAAI,KAAK,KAAK,GAAG,CAAC;AAC5E,CAAC;AAED,0EAA0E;AAC1E,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,IAAI,EAAE,SAAkB;IACxB,OAAO,EAAE,KAAK;IACd,WAAW,EAAE,yCAAyC;CACvD,CAAC;AAEF,MAAM,CAAC,MAAM,4BAA4B,GAAG;IAC1C,IAAI,EAAE,SAAkB;IACxB,OAAO,EAAE,KAAK;IACd,WAAW,EAAE,wBAAwB;CACtC,CAAC"}
@@ -1,6 +1,7 @@
1
1
  import { getDb } from '../db.js';
2
2
  import { resolveProjectId, activityScopeClause, repeatId, PROJECT_ID_SCHEMA } from '../helpers/project-scope.js';
3
3
  import { slimList } from '../helpers/slim.js';
4
+ import { asIdList } from '../helpers/coerce.js';
4
5
  import { guardTaskDone, FORCE_SCHEMA } from '../helpers/completion-guard.js';
5
6
  import { logActivity } from '../helpers/activity-logger.js';
6
7
  import { reevaluateDownstream } from './tasks.js';
@@ -142,7 +143,7 @@ function handleSessionDiff(args) {
142
143
  }
143
144
  function handleTaskBatchUpdate(args) {
144
145
  const db = getDb();
145
- const ids = args.ids;
146
+ const ids = asIdList(args.ids);
146
147
  const status = args.status;
147
148
  const priority = args.priority;
148
149
  const assignedTo = args.assigned_to;
@@ -1 +1 @@
1
- {"version":3,"file":"activity.js","sourceRoot":"","sources":["../../src/tools/activity.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"activity.js","sourceRoot":"","sources":["../../src/tools/activity.ts"],"names":[],"mappings":"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"}