@nickmeriano/task 0.7.1 → 0.9.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 (128) hide show
  1. package/README.md +73 -25
  2. package/dist/asks.test.d.ts +17 -0
  3. package/dist/asks.test.d.ts.map +1 -0
  4. package/dist/asks.test.js +278 -0
  5. package/dist/asks.test.js.map +1 -0
  6. package/dist/check.d.ts +43 -0
  7. package/dist/check.d.ts.map +1 -0
  8. package/dist/check.js +403 -0
  9. package/dist/check.js.map +1 -0
  10. package/dist/check.test.d.ts +9 -0
  11. package/dist/check.test.d.ts.map +1 -0
  12. package/dist/check.test.js +248 -0
  13. package/dist/check.test.js.map +1 -0
  14. package/dist/claim-io.d.ts +73 -0
  15. package/dist/claim-io.d.ts.map +1 -0
  16. package/dist/claim-io.js +344 -0
  17. package/dist/claim-io.js.map +1 -0
  18. package/dist/claim.d.ts +61 -9
  19. package/dist/claim.d.ts.map +1 -1
  20. package/dist/claim.js +197 -67
  21. package/dist/claim.js.map +1 -1
  22. package/dist/claim.test.d.ts +2 -2
  23. package/dist/claim.test.js +235 -64
  24. package/dist/claim.test.js.map +1 -1
  25. package/dist/cli.js +724 -136
  26. package/dist/cli.js.map +1 -1
  27. package/dist/file-store.d.ts +110 -38
  28. package/dist/file-store.d.ts.map +1 -1
  29. package/dist/file-store.js +514 -238
  30. package/dist/file-store.js.map +1 -1
  31. package/dist/git-serve.d.ts +183 -0
  32. package/dist/git-serve.d.ts.map +1 -0
  33. package/dist/git-serve.js +503 -0
  34. package/dist/git-serve.js.map +1 -0
  35. package/dist/git-serve.test.d.ts +16 -0
  36. package/dist/git-serve.test.d.ts.map +1 -0
  37. package/dist/git-serve.test.js +183 -0
  38. package/dist/git-serve.test.js.map +1 -0
  39. package/dist/git.d.ts +65 -0
  40. package/dist/git.d.ts.map +1 -0
  41. package/dist/git.js +114 -0
  42. package/dist/git.js.map +1 -0
  43. package/dist/id.d.ts +39 -0
  44. package/dist/id.d.ts.map +1 -0
  45. package/dist/id.js +67 -0
  46. package/dist/id.js.map +1 -0
  47. package/dist/inbox.d.ts +41 -0
  48. package/dist/inbox.d.ts.map +1 -0
  49. package/dist/inbox.js +56 -0
  50. package/dist/inbox.js.map +1 -0
  51. package/dist/index.d.ts +5 -3
  52. package/dist/index.d.ts.map +1 -1
  53. package/dist/index.js +5 -3
  54. package/dist/index.js.map +1 -1
  55. package/dist/overview.d.ts +52 -0
  56. package/dist/overview.d.ts.map +1 -0
  57. package/dist/overview.js +61 -0
  58. package/dist/overview.js.map +1 -0
  59. package/dist/overview.test.d.ts +8 -0
  60. package/dist/overview.test.d.ts.map +1 -0
  61. package/dist/overview.test.js +48 -0
  62. package/dist/overview.test.js.map +1 -0
  63. package/dist/promote.test.d.ts +15 -0
  64. package/dist/promote.test.d.ts.map +1 -0
  65. package/dist/promote.test.js +104 -0
  66. package/dist/promote.test.js.map +1 -0
  67. package/dist/publish.d.ts +2 -17
  68. package/dist/publish.d.ts.map +1 -1
  69. package/dist/publish.js +4 -49
  70. package/dist/publish.js.map +1 -1
  71. package/dist/search.d.ts +34 -0
  72. package/dist/search.d.ts.map +1 -0
  73. package/dist/search.js +79 -0
  74. package/dist/search.js.map +1 -0
  75. package/dist/search.test.d.ts +2 -0
  76. package/dist/search.test.d.ts.map +1 -0
  77. package/dist/search.test.js +53 -0
  78. package/dist/search.test.js.map +1 -0
  79. package/dist/server.d.ts.map +1 -1
  80. package/dist/server.js +228 -23
  81. package/dist/server.js.map +1 -1
  82. package/dist/store.d.ts +43 -63
  83. package/dist/store.d.ts.map +1 -1
  84. package/dist/store.js +0 -368
  85. package/dist/store.js.map +1 -1
  86. package/dist/store.test.d.ts +1 -2
  87. package/dist/store.test.d.ts.map +1 -1
  88. package/dist/store.test.js +148 -106
  89. package/dist/store.test.js.map +1 -1
  90. package/dist/ticket-doc.d.ts +74 -5
  91. package/dist/ticket-doc.d.ts.map +1 -1
  92. package/dist/ticket-doc.js +229 -15
  93. package/dist/ticket-doc.js.map +1 -1
  94. package/dist/types.d.ts +115 -28
  95. package/dist/types.d.ts.map +1 -1
  96. package/dist/types.js.map +1 -1
  97. package/package.json +1 -1
  98. package/skill/SKILL.md +153 -40
  99. package/src/asks.test.ts +355 -0
  100. package/src/check.test.ts +328 -0
  101. package/src/check.ts +497 -0
  102. package/src/claim-io.ts +401 -0
  103. package/src/claim.test.ts +301 -71
  104. package/src/claim.ts +238 -81
  105. package/src/cli.ts +740 -131
  106. package/src/file-store.ts +572 -254
  107. package/src/git-serve.test.ts +240 -0
  108. package/src/git-serve.ts +595 -0
  109. package/src/git.ts +141 -0
  110. package/src/id.ts +68 -0
  111. package/src/inbox.ts +77 -0
  112. package/src/index.ts +4 -2
  113. package/src/overview.test.ts +52 -0
  114. package/src/overview.ts +105 -0
  115. package/src/promote.test.ts +143 -0
  116. package/src/publish.ts +6 -53
  117. package/src/search.test.ts +64 -0
  118. package/src/search.ts +105 -0
  119. package/src/server.ts +232 -21
  120. package/src/store.test.ts +166 -116
  121. package/src/store.ts +46 -444
  122. package/src/ticket-doc.ts +284 -21
  123. package/src/types.ts +120 -28
  124. package/ui/dist/assets/index-BjsorZOU.js +229 -0
  125. package/ui/dist/assets/index-CoKCUYic.css +1 -0
  126. package/ui/dist/index.html +2 -2
  127. package/ui/dist/assets/index-COunM-QN.css +0 -1
  128. package/ui/dist/assets/index-D4homvrQ.js +0 -229
@@ -4,8 +4,7 @@
4
4
  * 1. The text format round-trips — parse(serialize(x)) loses nothing.
5
5
  * 2. `FileStore` behaves like the store always has (positions, links,
6
6
  * comments, cascade on delete).
7
- * 3. `task migrate` reproduces a legacy SQLite board in files, exactly.
8
- * 4. Concurrent-writer shapes merge by construction: a comment is a new file,
7
+ * 3. Concurrent-writer shapes merge by construction: a comment is a new file,
9
8
  * a claim is a one-line status diff.
10
9
  */
11
10
  import assert from "node:assert/strict";
@@ -13,9 +12,10 @@ import { test } from "node:test";
13
12
  import { mkdtempSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
14
13
  import { tmpdir } from "node:os";
15
14
  import { join } from "node:path";
16
- import { FileStore, initProject, migrateBoard, openBoard } from "./file-store.js";
17
- import { parseTicket, serializeTicket } from "./ticket-doc.js";
18
- import { TaskStore, findBoardsByPrefix, findScopeRoot } from "./store.js";
15
+ import { FileStore, initProject, openBoard } from "./file-store.js";
16
+ import { KEY_PATTERN } from "./id.js";
17
+ import { parseTicket, parseTicketLenient, serializeTicket } from "./ticket-doc.js";
18
+ import { findBoardsByPrefix, findScopeRoot } from "./store.js";
19
19
  function tempRoot() {
20
20
  const dir = mkdtempSync(join(tmpdir(), "task-test-"));
21
21
  process.on("exit", () => rmSync(dir, { recursive: true, force: true }));
@@ -28,8 +28,7 @@ test("ticket documents round-trip, including the awkward bodies", () => {
28
28
  description: "One line.",
29
29
  status: "todo",
30
30
  tags: [],
31
- milestone: null,
32
- needsHuman: false,
31
+ goal: null,
33
32
  blockedBy: [],
34
33
  prs: [],
35
34
  position: 1024,
@@ -43,9 +42,8 @@ test("ticket documents round-trip, including the awkward bodies", () => {
43
42
  description: "# Not the title\n\n---\n\nstatus: not-a-field\n\n```md\n---\n```",
44
43
  status: "in_progress",
45
44
  tags: ["storage", "architecture"],
46
- milestone: "v2 storage",
47
- needsHuman: true,
48
- blockedBy: [3, 7],
45
+ goal: "v2-storage",
46
+ blockedBy: ["k3mfp", "x7c2d"],
49
47
  prs: ["https://github.com/x/y/pull/1"],
50
48
  position: -512.5,
51
49
  createdAt: "2026-08-15T16:00:33.758Z",
@@ -56,8 +54,7 @@ test("ticket documents round-trip, including the awkward bodies", () => {
56
54
  description: "",
57
55
  status: "backlog",
58
56
  tags: [],
59
- milestone: null,
60
- needsHuman: false,
57
+ goal: null,
61
58
  blockedBy: [],
62
59
  prs: [],
63
60
  position: 0,
@@ -73,7 +70,7 @@ test("hand-edits are forgiven where they're unambiguous", () => {
73
70
  const text = [
74
71
  "---",
75
72
  "status: todo",
76
- "milestone: launch", // unquoted string — the YAML instinct
73
+ "goal: launch", // unquoted string — the YAML instinct
77
74
  "position: 8",
78
75
  "created: 2026-08-15T16:00:33.758Z",
79
76
  "updated: 2026-08-15T16:00:33.758Z",
@@ -84,8 +81,14 @@ test("hand-edits are forgiven where they're unambiguous", () => {
84
81
  "Body.",
85
82
  ].join("\n");
86
83
  const doc = parseTicket(text, "test");
87
- assert.equal(doc.milestone, "launch");
84
+ assert.equal(doc.goal, "launch");
88
85
  assert.equal(doc.position, 8);
86
+ // The pre-0.8 `milestone:` spelling is refused by name (TAS-41: no compat)
87
+ // — reading past it would silently drop the goal, so the error carries the
88
+ // one edit that fixes the file. The lenient parser just ignores it.
89
+ assert.throws(() => parseTicket(text.replace("goal: launch", "milestone: launch"), "test"), /`milestone:` is the pre-0\.8 spelling.*rename the key to `goal:`/);
90
+ const degraded = parseTicketLenient(text.replace("goal: launch", "milestone: launch"));
91
+ assert.equal(degraded?.goal, null);
89
92
  assert.throws(() => parseTicket(text.replace("status: todo", "status: todoo"), "here"), /here.*invalid status/);
90
93
  assert.throws(() => parseTicket("no frontmatter", "here"), /here.*frontmatter/);
91
94
  });
@@ -94,126 +97,165 @@ test("FileStore keeps the store's contract", () => {
94
97
  const store = initProject(root, { name: "sample project" });
95
98
  assert.equal(store.config.prefix, "SAM");
96
99
  assert.ok(store instanceof FileStore);
97
- const a = store.create({ title: "First", description: "alpha", tags: ["api"] });
100
+ const a = store.create({ title: "First", description: "alpha", tags: ["api"], status: "todo" });
98
101
  const b = store.create({ title: "Second", status: "todo" });
99
102
  const c = store.create({ title: "Third", status: "backlog" });
100
- assert.deepEqual([a.number, b.number, c.number], [1, 2, 3]);
103
+ // Keys are random, well-formed, and distinct — never sequential (TAS-42).
104
+ for (const t of [a, b, c])
105
+ assert.match(t.key, KEY_PATTERN);
106
+ assert.equal(new Set([a.key, b.key, c.key]).size, 3);
107
+ assert.equal(a.id, `SAM-${a.key}`);
101
108
  // New tasks land at the bottom of their column.
102
109
  assert.ok(b.position > a.position);
103
110
  // Status move without an explicit slot lands on top of the new column.
104
- const moved = store.update(c.number, { status: "todo" });
111
+ const moved = store.update(c.key, { status: "todo" });
105
112
  assert.ok(moved.position < a.position);
106
- assert.equal(store.list({ statuses: ["todo"] })[0].number, c.number);
113
+ assert.equal(store.list({ statuses: ["todo"] })[0].key, c.key);
107
114
  // One relation, two views, stored on one side only.
108
- store.link(a.number, "blocked_by", b.number);
109
- assert.deepEqual(store.get(b.number).blocks, [a.number]);
110
- const onDisk = readFileSync(join(root, ".task", "tickets", "1", "ticket.md"), "utf8");
111
- assert.match(onDisk, /blocked_by: \[2\]/);
112
- assert.doesNotMatch(readFileSync(join(root, ".task", "tickets", "2", "ticket.md"), "utf8"), /blocked_by/);
113
- store.unlink(b.number, "blocks", a.number);
114
- assert.deepEqual(store.get(a.number).blockedBy, []);
115
- assert.throws(() => store.link(a.number, "blocks", a.number), /can't block itself/);
116
- assert.throws(() => store.update(a.number, { blockedBy: [99] }), /no such task: SAM-99/);
115
+ store.link(a.key, "blocked_by", b.key);
116
+ assert.deepEqual(store.get(b.key).blocks, [a.key]);
117
+ const onDisk = readFileSync(join(root, ".task", "tickets", a.key, "ticket.md"), "utf8");
118
+ assert.ok(onDisk.includes(`blocked_by: ["${b.key}"]`));
119
+ assert.doesNotMatch(readFileSync(join(root, ".task", "tickets", b.key, "ticket.md"), "utf8"), /blocked_by/);
120
+ store.unlink(b.key, "blocks", a.key);
121
+ assert.deepEqual(store.get(a.key).blockedBy, []);
122
+ assert.throws(() => store.link(a.key, "blocks", a.key), /can't block itself/);
123
+ assert.throws(() => store.update(a.key, { blockedBy: ["zz9zz"] }), /no such task: SAM-zz9zz/);
124
+ // parseId: exact keys, PREFIX-key, and unique git-style prefixes all land.
125
+ assert.equal(store.parseId(a.key), a.key);
126
+ assert.equal(store.parseId(`SAM-${a.key}`), a.key);
127
+ assert.equal(store.parseId(a.key.toUpperCase()), a.key);
128
+ const uniquePrefix = [a, b, c].every((t) => t.key[0] !== a.key[0] || t.key === a.key)
129
+ ? a.key[0]
130
+ : a.key.slice(0, 4);
131
+ if ([a, b, c].filter((t) => t.key.startsWith(uniquePrefix)).length === 1) {
132
+ assert.equal(store.parseId(uniquePrefix), a.key);
133
+ }
134
+ assert.throws(() => store.parseId("not an id!"), /invalid task id/);
117
135
  // Comments: one file each, stable ids, author preserved.
118
- const comment = store.addComment(a.number, "first!\n\nwith **markdown**", "claude");
136
+ const comment = store.addComment(a.key, "first!\n\nwith **markdown**", "claude");
119
137
  assert.match(comment.id, /^\d{4}-\d{2}-\d{2}T\d{6}-claude$/);
120
- assert.equal(store.comments(a.number)[0].body, "first!\n\nwith **markdown**");
121
- assert.equal(store.commentCounts().get(a.number), 1);
122
- const second = store.addComment(a.number, "again", "claude");
138
+ assert.equal(store.comments(a.key)[0].body, "first!\n\nwith **markdown**");
139
+ assert.equal(store.commentCounts().get(a.key), 1);
140
+ const second = store.addComment(a.key, "again", "claude");
123
141
  assert.notEqual(second.id, comment.id);
124
- store.deleteComment(a.number, second.id);
125
- assert.equal(store.comments(a.number).length, 1);
126
- assert.throws(() => store.deleteComment(a.number, "../../escape"), /no such comment/);
142
+ store.deleteComment(a.key, second.id);
143
+ assert.equal(store.comments(a.key).length, 1);
144
+ assert.throws(() => store.deleteComment(a.key, "../../escape"), /no such comment/);
127
145
  // Delete cascades the relation away, like the FK did.
128
- store.link(b.number, "blocked_by", a.number);
129
- store.delete(a.number);
130
- assert.equal(store.get(a.number), null);
131
- assert.deepEqual(store.get(b.number).blockedBy, []);
132
- // Numbers never move backwards past an existing ticket.
133
- const d = store.create({ title: "Fourth" });
134
- assert.equal(d.number, 4);
146
+ store.link(b.key, "blocked_by", a.key);
147
+ store.delete(a.key);
148
+ assert.equal(store.get(a.key), null);
149
+ assert.deepEqual(store.get(b.key).blockedBy, []);
135
150
  });
136
- test("openBoard picks the backend by what's on disk", () => {
151
+ test("openBoard reads text boards, and refuses a pre-0.6 SQLite board loudly", () => {
137
152
  const fileRoot = tempRoot();
138
153
  initProject(fileRoot, { name: "files" });
139
154
  assert.ok(openBoard(fileRoot) instanceof FileStore);
155
+ // A pre-0.6 board: version-1 config, committed database, no tickets/ tree.
156
+ // Reading it as an empty text board would silently strand every ticket in
157
+ // the database, so it must refuse instead — pointing at the last release
158
+ // that still carries `task migrate`.
140
159
  const legacyRoot = tempRoot();
141
160
  mkdirSync(join(legacyRoot, ".task"));
142
161
  writeFileSync(join(legacyRoot, ".task", "config.json"), `${JSON.stringify({ name: "legacy", prefix: "LEG", version: 1 }, null, 2)}\n`);
143
- const legacy = openBoard(legacyRoot);
144
- assert.ok(legacy instanceof TaskStore);
145
- legacy.close();
146
- });
147
- test("migrate reproduces a legacy board, byte-visible and loss-free", () => {
148
- const root = tempRoot();
149
- mkdirSync(join(root, ".task"));
150
- writeFileSync(join(root, ".task", "config.json"), `${JSON.stringify({ name: "legacy board", prefix: "LEG", version: 1 }, null, 2)}\n`);
151
- const legacy = new TaskStore(root);
152
- const one = legacy.create({ title: "Keep me", description: "with *body*", tags: ["a", "b"] });
153
- const two = legacy.create({
154
- title: "Blocked one",
155
- status: "in_progress",
156
- milestone: "launch",
157
- needsHuman: true,
158
- blockedBy: [one.number],
159
- prs: ["https://github.com/x/y/pull/9"],
160
- });
161
- legacy.addComment(one.number, "hello", "nick");
162
- legacy.addComment(one.number, "and back", "claude");
163
- const expectedTasks = legacy.list({});
164
- const expectedComments = legacy.comments(one.number);
165
- legacy.close();
166
- const result = migrateBoard(root);
167
- assert.deepEqual(result, { tasks: 2, comments: 2 });
168
- assert.throws(() => migrateBoard(root), /already migrated/);
169
- const store = openBoard(root);
170
- assert.ok(store instanceof FileStore);
171
- assert.deepEqual(store.list({}), expectedTasks);
172
- assert.deepEqual(store.comments(one.number).map(({ author, body, createdAt }) => ({ author, body, createdAt })), expectedComments.map(({ author, body, createdAt }) => ({ author, body, createdAt })));
173
- assert.deepEqual(store.get(two.number).blockedBy, [one.number]);
174
- assert.match(readFileSync(join(root, ".task", ".gitignore"), "utf8"), /tasks\.db/);
175
- assert.equal(JSON.parse(readFileSync(join(root, ".task", "config.json"), "utf8"))
176
- .version, 2);
162
+ writeFileSync(join(legacyRoot, ".task", "tasks.db"), "not really a database");
163
+ assert.throws(() => openBoard(legacyRoot), /pre-0\.6 SQLite database.*migrate/);
164
+ // A version-2 board with no tickets yet is just an empty board, not legacy.
165
+ const emptyRoot = tempRoot();
166
+ mkdirSync(join(emptyRoot, ".task"));
167
+ writeFileSync(join(emptyRoot, ".task", "config.json"), `${JSON.stringify({ name: "empty", prefix: "EMP", version: 2 }, null, 2)}\n`);
168
+ assert.deepEqual(openBoard(emptyRoot).list({}), []);
177
169
  });
178
170
  test("archive moves finished tickets off the hot path, losing nothing", () => {
179
171
  const root = tempRoot();
180
172
  const store = initProject(root, { name: "archive test", prefix: "ARC" });
181
- const keep = store.create({ title: "Still open" });
182
- const old = store.create({ title: "Finished work" });
183
- store.link(keep.number, "blocked_by", old.number);
184
- store.addComment(old.number, "how it went", "nick");
173
+ const keep = store.create({ title: "Still open", status: "todo" });
174
+ const old = store.create({ title: "Finished work", status: "todo" });
175
+ store.link(keep.key, "blocked_by", old.key);
176
+ store.addComment(old.key, "how it went", "nick");
185
177
  // Only finished work qualifies — archive is history, not a hiding place.
186
- assert.throws(() => store.archive(old.number), /is todo/);
187
- store.update(old.number, { status: "done" });
188
- const archived = store.archive(old.number);
178
+ assert.throws(() => store.archive(old.key), /is todo/);
179
+ store.update(old.key, { status: "done" });
180
+ const archived = store.archive(old.key);
189
181
  assert.equal(archived.archived, true);
190
182
  // Off the board and out of every default read…
191
- assert.deepEqual(store.list({}).map((t) => t.number), [keep.number]);
192
- assert.equal(store.commentCounts().get(old.number), undefined);
183
+ assert.deepEqual(store.list({}).map((t) => t.key), [keep.key]);
184
+ assert.equal(store.commentCounts().get(old.key), undefined);
193
185
  // …but reads still reach it, comments included, and its links still show.
194
- const shown = store.get(old.number);
186
+ const shown = store.get(old.key);
195
187
  assert.equal(shown.archived, true);
196
- assert.deepEqual(shown.blocks, [keep.number]);
197
- assert.equal(store.comments(old.number)[0].body, "how it went");
188
+ assert.deepEqual(shown.blocks, [keep.key]);
189
+ assert.equal(store.comments(old.key)[0].body, "how it went");
198
190
  const listed = store.list({ archived: true });
199
- assert.deepEqual(listed.map((t) => [t.number, t.archived]), [[old.number, true]]);
191
+ assert.deepEqual(listed.map((t) => [t.key, t.archived]), [[old.key, true]]);
200
192
  // Writes refuse until unarchived, with a message that says what to do.
201
- assert.throws(() => store.update(old.number, { title: "x" }), /archived — run/);
202
- assert.throws(() => store.addComment(old.number, "x", "y"), /archived — run/);
203
- assert.throws(() => store.delete(old.number), /archived — run/);
204
- assert.throws(() => store.archive(old.number), /already archived/);
193
+ assert.throws(() => store.update(old.key, { title: "x" }), /archived — run/);
194
+ assert.throws(() => store.addComment(old.key, "x", "y"), /archived — run/);
195
+ assert.throws(() => store.delete(old.key), /archived — run/);
196
+ assert.throws(() => store.archive(old.key), /already archived/);
205
197
  // Linking *to* an archived target refuses; pruning a stale link succeeds.
206
- assert.throws(() => store.link(keep.number, "blocked_by", old.number), /archived — run/);
207
- assert.deepEqual(store.update(keep.number, { blockedBy: [] }).blockedBy, []);
208
- // Numbers stay reserved — the next ticket never reuses an archived one.
209
- assert.equal(store.create({ title: "Next" }).number, 3);
198
+ assert.throws(() => store.link(keep.key, "blocked_by", old.key), /archived — run/);
199
+ assert.deepEqual(store.update(keep.key, { blockedBy: [] }).blockedBy, []);
200
+ // Keys stay reserved — a new mint can never take an archived ticket's name.
201
+ const next = store.create({ title: "Next" });
202
+ assert.notEqual(next.key, old.key);
203
+ // An archived key still resolves through parseId (exact match).
204
+ assert.equal(store.parseId(`ARC-${old.key}`), old.key);
210
205
  // Round trip: unarchive puts it back exactly as it was.
211
- const back = store.unarchive(old.number);
206
+ const back = store.unarchive(old.key);
212
207
  assert.equal(back.archived, undefined);
213
208
  assert.equal(back.status, "done");
214
209
  assert.deepEqual(store.list({ archived: true }), []);
215
- assert.equal(store.comments(old.number).length, 1);
216
- assert.throws(() => store.unarchive(old.number), /isn't archived/);
210
+ assert.equal(store.comments(old.key).length, 1);
211
+ assert.throws(() => store.unarchive(old.key), /isn't archived/);
212
+ });
213
+ test("goals: titled and described, one per task, progress always derived", () => {
214
+ const root = tempRoot();
215
+ const store = initProject(root, { name: "goals test", prefix: "GOA" });
216
+ // Created deliberately, slug derived from the title.
217
+ const goal = store.createGoal({
218
+ title: "Trust & guardrail layer",
219
+ description: "Why: DialMCP context lives here once, not in every ticket.",
220
+ });
221
+ assert.equal(goal.slug, "trust-guardrail-layer");
222
+ assert.throws(() => store.createGoal({ title: "Trust & guardrail layer" }), /already exists/);
223
+ assert.throws(() => store.createGoal({ title: "x", slug: "archive" }), /invalid goal slug/);
224
+ assert.throws(() => store.createGoal({ title: "x", slug: "Not A Slug" }), /invalid goal slug/);
225
+ // Assignment is validated: a goal must exist before a task can belong to it.
226
+ assert.throws(() => store.create({ title: "T", goal: "nope" }), /no such goal/);
227
+ const a = store.create({ title: "First", goal: goal.slug });
228
+ const b = store.create({ title: "Second" });
229
+ store.update(b.key, { goal: goal.slug });
230
+ assert.equal(store.get(b.key).goal, goal.slug);
231
+ assert.deepEqual(store.list({ goal: goal.slug }).map((t) => t.key), [a.key, b.key]);
232
+ // The file is the state: goal ref serialized on the ticket, goal file on disk.
233
+ assert.match(readFileSync(join(root, ".task", "tickets", a.key, "ticket.md"), "utf8"), /goal: "trust-guardrail-layer"/);
234
+ const goalFile = readFileSync(join(root, ".task", "goals", "trust-guardrail-layer.md"), "utf8");
235
+ assert.match(goalFile, /# Trust & guardrail layer/);
236
+ // Update touches the file; clearing a task's goal is `goal: null`.
237
+ store.updateGoal(goal.slug, { description: "Sharper why." });
238
+ assert.equal(store.getGoal(goal.slug).description, "Sharper why.");
239
+ store.update(b.key, { goal: null });
240
+ assert.equal(store.get(b.key).goal, null);
241
+ // Archive refuses while open work references the goal, allows after.
242
+ assert.throws(() => store.archiveGoal(goal.slug), new RegExp(`still has open tasks \\(GOA-${a.key}\\)`));
243
+ store.update(a.key, { status: "done" });
244
+ const shelved = store.archiveGoal(goal.slug);
245
+ assert.equal(shelved.archived, true);
246
+ assert.deepEqual(store.goals().map((g) => g.slug), []);
247
+ assert.deepEqual(store.goals(true).map((g) => g.slug), [goal.slug]);
248
+ // Still resolvable (done tickets keep their ref readable), not assignable.
249
+ assert.equal(store.getGoal(goal.slug).title, "Trust & guardrail layer");
250
+ assert.throws(() => store.update(b.key, { goal: goal.slug }), /is archived — run/);
251
+ assert.throws(() => store.updateGoal(goal.slug, { title: "x" }), /is archived — run/);
252
+ // Delete needs every live ref cleared first — pruning organization is a
253
+ // human call, so the human makes it.
254
+ store.unarchiveGoal(goal.slug);
255
+ assert.throws(() => store.deleteGoal(goal.slug), new RegExp(`referenced by GOA-${a.key}`));
256
+ store.update(a.key, { goal: null });
257
+ store.deleteGoal(goal.slug);
258
+ assert.equal(store.getGoal(goal.slug), null);
217
259
  });
218
260
  test("prefix routing helpers find the right board from anywhere", () => {
219
261
  const repo = tempRoot();
@@ -230,21 +272,21 @@ test("prefix routing helpers find the right board from anywhere", () => {
230
272
  test("concurrent-writer shapes merge by construction", () => {
231
273
  const root = tempRoot();
232
274
  const store = initProject(root, { name: "merge" });
233
- const task = store.create({ title: "Contended" });
275
+ const task = store.create({ title: "Contended", status: "todo" });
234
276
  // Two agents commenting at once = two files; simulate the second writer by
235
277
  // dropping its file in directly, the way a git merge would.
236
- store.addComment(task.number, "from session one", "claude");
237
- const commentsDir = join(root, ".task", "tickets", String(task.number), "comments");
278
+ store.addComment(task.key, "from session one", "claude");
279
+ const commentsDir = join(root, ".task", "tickets", task.key, "comments");
238
280
  writeFileSync(join(commentsDir, "2026-08-15T170000-other.md"), "---\nauthor: \"other\"\ncreated: 2026-08-15T17:00:00.000Z\n---\n\nfrom session two\n");
239
- assert.equal(store.comments(task.number).length, 2);
281
+ assert.equal(store.comments(task.key).length, 2);
240
282
  // A claim is a one-line diff: exactly one meaningful frontmatter line
241
283
  // changes. `updated:` is excluded because it only changes when the update
242
284
  // lands in a different millisecond than the create — true except when this
243
285
  // test runs fast enough, which is exactly the kind of coin-flip a test must
244
286
  // not depend on.
245
- const path = join(root, ".task", "tickets", String(task.number), "ticket.md");
287
+ const path = join(root, ".task", "tickets", task.key, "ticket.md");
246
288
  const before = readFileSync(path, "utf8").split("\n");
247
- store.update(task.number, { status: "in_progress", position: task.position });
289
+ store.update(task.key, { status: "in_progress", position: task.position });
248
290
  const after = readFileSync(path, "utf8").split("\n");
249
291
  const changed = before.filter((line, i) => after[i] !== line);
250
292
  assert.deepEqual(changed.filter((line) => !line.startsWith("updated: ")), ["status: todo"]);
@@ -1 +1 @@
1
- {"version":3,"file":"store.test.js","sourceRoot":"","sources":["../src/store.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"store.test.js","sourceRoot":"","sources":["../src/store.test.ts"],"names":[],"mappings":"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"}
@@ -21,20 +21,45 @@ export interface TicketDoc {
21
21
  description: string;
22
22
  status: Status;
23
23
  tags: string[];
24
- milestone: string | null;
25
- needsHuman: boolean;
26
- /** Task numbers blocking this one — the single stored side of the relation. */
27
- blockedBy: number[];
24
+ /** Slug of the goal this ticket belongs to — at most one, by design. */
25
+ goal: string | null;
26
+ /** Keys of tasks blocking this one — the single stored side of the relation. */
27
+ blockedBy: string[];
28
28
  prs: string[];
29
29
  position: number;
30
30
  createdAt: string;
31
31
  updatedAt: string;
32
+ /**
33
+ * Frontmatter keys this version doesn't know, as raw `[key, value]` pairs in
34
+ * file order. Carried so a rewrite can't silently drop them — a hand-added
35
+ * field (or one written by a newer CLI) survives every update, re-emitted
36
+ * after the known fields. Present only when the file actually has any.
37
+ */
38
+ extras?: [string, string][];
32
39
  }
40
+ /** The frontmatter keys a ticket file may carry; anything else is an extra. */
41
+ export declare const TICKET_FIELDS: readonly ["status", "tags", "goal", "blocked_by", "prs", "position", "created", "updated"];
42
+ /** The frontmatter keys a comment file may carry. */
43
+ export declare const COMMENT_FIELDS: readonly ["author", "created"];
33
44
  export interface CommentDoc {
34
45
  author: string;
35
46
  createdAt: string;
36
47
  body: string;
37
48
  }
49
+ /** The frontmatter keys an ask file may carry. */
50
+ export declare const ASK_FIELDS: readonly ["author", "created", "resolved", "resolved_by"];
51
+ /**
52
+ * One ask on disk — `tickets/<n>/asks/<stem>.md`, the comment layout plus a
53
+ * resolution: `resolved`/`resolved_by` appear when the ask is closed and are
54
+ * simply absent while it's open, so an open ask's bytes never churn.
55
+ */
56
+ export interface AskDoc {
57
+ author: string;
58
+ createdAt: string;
59
+ resolvedAt: string | null;
60
+ resolvedBy: string | null;
61
+ body: string;
62
+ }
38
63
  /** A parse that names the file it failed in — these files invite hand-editing. */
39
64
  export declare class TicketParseError extends Error {
40
65
  }
@@ -42,11 +67,55 @@ export declare function parseTicket(text: string, where: string): TicketDoc;
42
67
  /**
43
68
  * The canonical bytes for a ticket. Field order is fixed and empty fields are
44
69
  * omitted, so an unchanged ticket always serializes identically — diffs show
45
- * edits, never churn.
70
+ * edits, never churn. Unknown fields the parse carried through are re-emitted
71
+ * after the known ones, in their original order.
46
72
  */
47
73
  export declare function serializeTicket(doc: TicketDoc): string;
74
+ /** Everything `goals/<slug>.md` stores. The slug is the filename, not a field. */
75
+ export interface GoalDoc {
76
+ title: string;
77
+ description: string;
78
+ createdAt: string;
79
+ updatedAt: string;
80
+ /** Unknown frontmatter, carried through rewrites — same deal as tickets. */
81
+ extras?: [string, string][];
82
+ }
83
+ /** The frontmatter keys a goal file may carry. */
84
+ export declare const GOAL_FIELDS: readonly ["created", "updated"];
85
+ /**
86
+ * What a goal slug may look like — same alphabet as the claim-branch-safe
87
+ * ticket ids, because the slug ends up in frontmatter, URLs and prompts.
88
+ * "archive" is reserved: `goals/archive/` is where archived goals live.
89
+ */
90
+ export declare const GOAL_SLUG_PATTERN: RegExp;
91
+ export declare function isGoalSlug(value: string): boolean;
92
+ /** Derive a slug from a title: "Trust & guardrail layer" → "trust-guardrail-layer". */
93
+ export declare function slugifyGoal(title: string): string;
94
+ export declare function parseGoal(text: string, where: string): GoalDoc;
95
+ /** Canonical bytes for a goal — fixed field order, like tickets. */
96
+ export declare function serializeGoal(doc: GoalDoc): string;
97
+ /** A goal, forgivingly — null when there's no frontmatter at all. */
98
+ export declare function parseGoalLenient(text: string): GoalDoc | null;
48
99
  export declare function parseComment(text: string, where: string): CommentDoc;
49
100
  export declare function serializeComment(doc: CommentDoc): string;
101
+ export declare function parseAsk(text: string, where: string): AskDoc;
102
+ export declare function serializeAsk(doc: AskDoc): string;
103
+ /**
104
+ * An ask, forgivingly — null when there's no frontmatter at all. The lenient
105
+ * read matters more here than for comments: the inbox reads ask files straight
106
+ * off claim branches, which are exactly the bytes a strict parser can't refuse.
107
+ */
108
+ export declare function parseAskLenient(text: string): AskDoc | null;
109
+ /** A ticket, forgivingly — or null when there's no frontmatter to read at all. */
110
+ export declare function parseTicketLenient(text: string): TicketDoc | null;
111
+ /**
112
+ * The frontmatter keys a file carries, leniently — null when there's no
113
+ * frontmatter at all. `task check` uses this to spot unknown keys in files
114
+ * whose parsed shape (comments) doesn't carry them through.
115
+ */
116
+ export declare function frontmatterKeys(text: string): string[] | null;
117
+ /** A comment, forgivingly — or null when there's no frontmatter at all. */
118
+ export declare function parseCommentLenient(text: string): CommentDoc | null;
50
119
  /**
51
120
  * A comment's filename stem — readable, sortable, and unique enough that two
52
121
  * branches almost never mint the same one: `2026-08-15T165943-claude`. The
@@ -1 +1 @@
1
- {"version":3,"file":"ticket-doc.d.ts","sourceRoot":"","sources":["../src/ticket-doc.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAsB,KAAK,MAAM,EAAE,MAAM,YAAY,CAAA;AAE5D,8EAA8E;AAC9E,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,EAAE,CAAA;IACd,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,UAAU,EAAE,OAAO,CAAA;IACnB,+EAA+E;IAC/E,SAAS,EAAE,MAAM,EAAE,CAAA;IACnB,GAAG,EAAE,MAAM,EAAE,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,MAAM,CAAA;CACb;AAED,kFAAkF;AAClF,qBAAa,gBAAiB,SAAQ,KAAK;CAAG;AA0F9C,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,CAkClE;AAOD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,SAAS,GAAG,MAAM,CAatD;AAID,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,UAAU,CAOpE;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,UAAU,GAAG,MAAM,CAKxD;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAQrE"}
1
+ {"version":3,"file":"ticket-doc.d.ts","sourceRoot":"","sources":["../src/ticket-doc.ts"],"names":[],"mappings":"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"}