@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.
- package/README.md +73 -25
- package/dist/asks.test.d.ts +17 -0
- package/dist/asks.test.d.ts.map +1 -0
- package/dist/asks.test.js +278 -0
- package/dist/asks.test.js.map +1 -0
- package/dist/check.d.ts +43 -0
- package/dist/check.d.ts.map +1 -0
- package/dist/check.js +403 -0
- package/dist/check.js.map +1 -0
- package/dist/check.test.d.ts +9 -0
- package/dist/check.test.d.ts.map +1 -0
- package/dist/check.test.js +248 -0
- package/dist/check.test.js.map +1 -0
- package/dist/claim-io.d.ts +73 -0
- package/dist/claim-io.d.ts.map +1 -0
- package/dist/claim-io.js +344 -0
- package/dist/claim-io.js.map +1 -0
- package/dist/claim.d.ts +61 -9
- package/dist/claim.d.ts.map +1 -1
- package/dist/claim.js +197 -67
- package/dist/claim.js.map +1 -1
- package/dist/claim.test.d.ts +2 -2
- package/dist/claim.test.js +235 -64
- package/dist/claim.test.js.map +1 -1
- package/dist/cli.js +724 -136
- package/dist/cli.js.map +1 -1
- package/dist/file-store.d.ts +110 -38
- package/dist/file-store.d.ts.map +1 -1
- package/dist/file-store.js +514 -238
- package/dist/file-store.js.map +1 -1
- package/dist/git-serve.d.ts +183 -0
- package/dist/git-serve.d.ts.map +1 -0
- package/dist/git-serve.js +503 -0
- package/dist/git-serve.js.map +1 -0
- package/dist/git-serve.test.d.ts +16 -0
- package/dist/git-serve.test.d.ts.map +1 -0
- package/dist/git-serve.test.js +183 -0
- package/dist/git-serve.test.js.map +1 -0
- package/dist/git.d.ts +65 -0
- package/dist/git.d.ts.map +1 -0
- package/dist/git.js +114 -0
- package/dist/git.js.map +1 -0
- package/dist/id.d.ts +39 -0
- package/dist/id.d.ts.map +1 -0
- package/dist/id.js +67 -0
- package/dist/id.js.map +1 -0
- package/dist/inbox.d.ts +41 -0
- package/dist/inbox.d.ts.map +1 -0
- package/dist/inbox.js +56 -0
- package/dist/inbox.js.map +1 -0
- package/dist/index.d.ts +5 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -3
- package/dist/index.js.map +1 -1
- package/dist/overview.d.ts +52 -0
- package/dist/overview.d.ts.map +1 -0
- package/dist/overview.js +61 -0
- package/dist/overview.js.map +1 -0
- package/dist/overview.test.d.ts +8 -0
- package/dist/overview.test.d.ts.map +1 -0
- package/dist/overview.test.js +48 -0
- package/dist/overview.test.js.map +1 -0
- package/dist/promote.test.d.ts +15 -0
- package/dist/promote.test.d.ts.map +1 -0
- package/dist/promote.test.js +104 -0
- package/dist/promote.test.js.map +1 -0
- package/dist/publish.d.ts +2 -17
- package/dist/publish.d.ts.map +1 -1
- package/dist/publish.js +4 -49
- package/dist/publish.js.map +1 -1
- package/dist/search.d.ts +34 -0
- package/dist/search.d.ts.map +1 -0
- package/dist/search.js +79 -0
- package/dist/search.js.map +1 -0
- package/dist/search.test.d.ts +2 -0
- package/dist/search.test.d.ts.map +1 -0
- package/dist/search.test.js +53 -0
- package/dist/search.test.js.map +1 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +228 -23
- package/dist/server.js.map +1 -1
- package/dist/store.d.ts +43 -63
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +0 -368
- package/dist/store.js.map +1 -1
- package/dist/store.test.d.ts +1 -2
- package/dist/store.test.d.ts.map +1 -1
- package/dist/store.test.js +148 -106
- package/dist/store.test.js.map +1 -1
- package/dist/ticket-doc.d.ts +74 -5
- package/dist/ticket-doc.d.ts.map +1 -1
- package/dist/ticket-doc.js +229 -15
- package/dist/ticket-doc.js.map +1 -1
- package/dist/types.d.ts +115 -28
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +1 -1
- package/skill/SKILL.md +153 -40
- package/src/asks.test.ts +355 -0
- package/src/check.test.ts +328 -0
- package/src/check.ts +497 -0
- package/src/claim-io.ts +401 -0
- package/src/claim.test.ts +301 -71
- package/src/claim.ts +238 -81
- package/src/cli.ts +740 -131
- package/src/file-store.ts +572 -254
- package/src/git-serve.test.ts +240 -0
- package/src/git-serve.ts +595 -0
- package/src/git.ts +141 -0
- package/src/id.ts +68 -0
- package/src/inbox.ts +77 -0
- package/src/index.ts +4 -2
- package/src/overview.test.ts +52 -0
- package/src/overview.ts +105 -0
- package/src/promote.test.ts +143 -0
- package/src/publish.ts +6 -53
- package/src/search.test.ts +64 -0
- package/src/search.ts +105 -0
- package/src/server.ts +232 -21
- package/src/store.test.ts +166 -116
- package/src/store.ts +46 -444
- package/src/ticket-doc.ts +284 -21
- package/src/types.ts +120 -28
- package/ui/dist/assets/index-BjsorZOU.js +229 -0
- package/ui/dist/assets/index-CoKCUYic.css +1 -0
- package/ui/dist/index.html +2 -2
- package/ui/dist/assets/index-COunM-QN.css +0 -1
- package/ui/dist/assets/index-D4homvrQ.js +0 -229
package/dist/ticket-doc.js
CHANGED
|
@@ -15,6 +15,21 @@
|
|
|
15
15
|
* diff of a new ticket *is* the ticket.
|
|
16
16
|
*/
|
|
17
17
|
import { STATUSES, isStatus } from "./types.js";
|
|
18
|
+
/** The frontmatter keys a ticket file may carry; anything else is an extra. */
|
|
19
|
+
export const TICKET_FIELDS = [
|
|
20
|
+
"status",
|
|
21
|
+
"tags",
|
|
22
|
+
"goal",
|
|
23
|
+
"blocked_by",
|
|
24
|
+
"prs",
|
|
25
|
+
"position",
|
|
26
|
+
"created",
|
|
27
|
+
"updated",
|
|
28
|
+
];
|
|
29
|
+
/** The frontmatter keys a comment file may carry. */
|
|
30
|
+
export const COMMENT_FIELDS = ["author", "created"];
|
|
31
|
+
/** The frontmatter keys an ask file may carry. */
|
|
32
|
+
export const ASK_FIELDS = ["author", "created", "resolved", "resolved_by"];
|
|
18
33
|
/** A parse that names the file it failed in — these files invite hand-editing. */
|
|
19
34
|
export class TicketParseError extends Error {
|
|
20
35
|
}
|
|
@@ -34,13 +49,23 @@ function parseScalar(raw) {
|
|
|
34
49
|
return trimmed;
|
|
35
50
|
}
|
|
36
51
|
}
|
|
52
|
+
/**
|
|
53
|
+
* Split a file into frontmatter fields and body. Two callers, two stances:
|
|
54
|
+
* with a `where` the CLI is parsing and every malformation throws, naming the
|
|
55
|
+
* file; with `where: null` the hosted board is rendering and a file with no
|
|
56
|
+
* frontmatter returns null while a merely-odd line is skipped.
|
|
57
|
+
*/
|
|
37
58
|
function splitRaw(text, where) {
|
|
38
59
|
const lines = text.replace(/\r\n/g, "\n").split("\n");
|
|
39
60
|
if (lines[0] !== "---") {
|
|
61
|
+
if (where === null)
|
|
62
|
+
return null;
|
|
40
63
|
throw new TicketParseError(`${where}: expected the file to start with a --- frontmatter block`);
|
|
41
64
|
}
|
|
42
65
|
const end = lines.indexOf("---", 1);
|
|
43
66
|
if (end < 0) {
|
|
67
|
+
if (where === null)
|
|
68
|
+
return null;
|
|
44
69
|
throw new TicketParseError(`${where}: unterminated frontmatter — no closing ---`);
|
|
45
70
|
}
|
|
46
71
|
const fields = new Map();
|
|
@@ -49,6 +74,8 @@ function splitRaw(text, where) {
|
|
|
49
74
|
continue;
|
|
50
75
|
const colon = line.indexOf(":");
|
|
51
76
|
if (colon < 0) {
|
|
77
|
+
if (where === null)
|
|
78
|
+
continue;
|
|
52
79
|
throw new TicketParseError(`${where}: not a "key: value" frontmatter line: ${line}`);
|
|
53
80
|
}
|
|
54
81
|
fields.set(line.slice(0, colon).trim(), line.slice(colon + 1));
|
|
@@ -76,14 +103,16 @@ function stringList(raw, key, where) {
|
|
|
76
103
|
return value;
|
|
77
104
|
throw new TicketParseError(`${where}: ${key} should be a list of strings, e.g. ["a", "b"]`);
|
|
78
105
|
}
|
|
79
|
-
function
|
|
106
|
+
function keyList(raw, key, where) {
|
|
80
107
|
const value = field(raw, key);
|
|
81
108
|
if (value === undefined)
|
|
82
109
|
return [];
|
|
83
|
-
if (Array.isArray(value) && value.every((v) => typeof v === "
|
|
110
|
+
if (Array.isArray(value) && value.every((v) => typeof v === "string")) {
|
|
84
111
|
return value;
|
|
85
112
|
}
|
|
86
|
-
|
|
113
|
+
// A list of bare numbers is a pre-migration file (ids were sequential
|
|
114
|
+
// integers before TAS-42) — name the one edit that fixes it.
|
|
115
|
+
throw new TicketParseError(`${where}: ${key} should be a list of ticket keys, e.g. ["x7k4m", "q3v8d"] — numeric entries are the pre-TAS-42 id format, which is no longer read`);
|
|
87
116
|
}
|
|
88
117
|
// ── Tickets ──────────────────────────────────────────────────────────────────
|
|
89
118
|
/**
|
|
@@ -107,11 +136,16 @@ export function parseTicket(text, where) {
|
|
|
107
136
|
if (!isStatus(status)) {
|
|
108
137
|
throw new TicketParseError(`${where}: invalid status "${status}" — one of: ${STATUSES.join(", ")}`);
|
|
109
138
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
139
|
+
// The pre-0.8 `milestone:` spelling is not honored (TAS-41: no compat), and
|
|
140
|
+
// reading past it would silently drop the ticket's goal — refuse by name
|
|
141
|
+
// instead, so the one edit that fixes the file is in the error.
|
|
142
|
+
if (raw.fields.has("milestone")) {
|
|
143
|
+
throw new TicketParseError(`${where}: \`milestone:\` is the pre-0.8 spelling and is no longer read — rename the key to \`goal:\``);
|
|
144
|
+
}
|
|
145
|
+
const goal = field(raw, "goal");
|
|
146
|
+
if (goal !== undefined && goal !== null && typeof goal !== "string") {
|
|
147
|
+
throw new TicketParseError(`${where}: goal should be a string`);
|
|
113
148
|
}
|
|
114
|
-
const needsHuman = field(raw, "needs_human");
|
|
115
149
|
const position = field(raw, "position");
|
|
116
150
|
if (position !== undefined && typeof position !== "number") {
|
|
117
151
|
throw new TicketParseError(`${where}: position should be a number`);
|
|
@@ -120,18 +154,24 @@ export function parseTicket(text, where) {
|
|
|
120
154
|
if (title === null) {
|
|
121
155
|
throw new TicketParseError(`${where}: expected the body to start with "# <title>"`);
|
|
122
156
|
}
|
|
157
|
+
const known = new Set(TICKET_FIELDS);
|
|
158
|
+
const extras = [];
|
|
159
|
+
for (const [key, value] of raw.fields) {
|
|
160
|
+
if (!known.has(key))
|
|
161
|
+
extras.push([key, value.trim()]);
|
|
162
|
+
}
|
|
123
163
|
return {
|
|
124
164
|
title,
|
|
125
165
|
description,
|
|
126
166
|
status,
|
|
127
167
|
tags: stringList(raw, "tags", where),
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
blockedBy: numberList(raw, "blocked_by", where),
|
|
168
|
+
goal: typeof goal === "string" && goal !== "" ? goal : null,
|
|
169
|
+
blockedBy: keyList(raw, "blocked_by", where),
|
|
131
170
|
prs: stringList(raw, "prs", where),
|
|
132
171
|
position: typeof position === "number" ? position : 0,
|
|
133
172
|
createdAt: stringField(raw, "created", where, ""),
|
|
134
173
|
updatedAt: stringField(raw, "updated", where, ""),
|
|
174
|
+
...(extras.length ? { extras } : {}),
|
|
135
175
|
};
|
|
136
176
|
}
|
|
137
177
|
/** JSON array on one line — `["a", "b"]` — which is also valid YAML flow style. */
|
|
@@ -141,16 +181,15 @@ function list(values) {
|
|
|
141
181
|
/**
|
|
142
182
|
* The canonical bytes for a ticket. Field order is fixed and empty fields are
|
|
143
183
|
* omitted, so an unchanged ticket always serializes identically — diffs show
|
|
144
|
-
* edits, never churn.
|
|
184
|
+
* edits, never churn. Unknown fields the parse carried through are re-emitted
|
|
185
|
+
* after the known ones, in their original order.
|
|
145
186
|
*/
|
|
146
187
|
export function serializeTicket(doc) {
|
|
147
188
|
const lines = ["---", `status: ${doc.status}`];
|
|
148
189
|
if (doc.tags.length)
|
|
149
190
|
lines.push(`tags: ${list(doc.tags)}`);
|
|
150
|
-
if (doc.
|
|
151
|
-
lines.push(`
|
|
152
|
-
if (doc.needsHuman)
|
|
153
|
-
lines.push(`needs_human: true`);
|
|
191
|
+
if (doc.goal)
|
|
192
|
+
lines.push(`goal: ${JSON.stringify(doc.goal)}`);
|
|
154
193
|
if (doc.blockedBy.length)
|
|
155
194
|
lines.push(`blocked_by: ${list(doc.blockedBy)}`);
|
|
156
195
|
if (doc.prs.length)
|
|
@@ -158,11 +197,76 @@ export function serializeTicket(doc) {
|
|
|
158
197
|
lines.push(`position: ${doc.position}`);
|
|
159
198
|
lines.push(`created: ${doc.createdAt}`);
|
|
160
199
|
lines.push(`updated: ${doc.updatedAt}`);
|
|
200
|
+
for (const [key, value] of doc.extras ?? [])
|
|
201
|
+
lines.push(`${key}: ${value}`);
|
|
202
|
+
lines.push("---", "", `# ${doc.title}`);
|
|
203
|
+
if (doc.description)
|
|
204
|
+
lines.push("", doc.description);
|
|
205
|
+
return `${lines.join("\n")}\n`;
|
|
206
|
+
}
|
|
207
|
+
/** The frontmatter keys a goal file may carry. */
|
|
208
|
+
export const GOAL_FIELDS = ["created", "updated"];
|
|
209
|
+
/**
|
|
210
|
+
* What a goal slug may look like — same alphabet as the claim-branch-safe
|
|
211
|
+
* ticket ids, because the slug ends up in frontmatter, URLs and prompts.
|
|
212
|
+
* "archive" is reserved: `goals/archive/` is where archived goals live.
|
|
213
|
+
*/
|
|
214
|
+
export const GOAL_SLUG_PATTERN = /^[a-z0-9][a-z0-9-]{0,63}$/;
|
|
215
|
+
export function isGoalSlug(value) {
|
|
216
|
+
return GOAL_SLUG_PATTERN.test(value) && value !== "archive";
|
|
217
|
+
}
|
|
218
|
+
/** Derive a slug from a title: "Trust & guardrail layer" → "trust-guardrail-layer". */
|
|
219
|
+
export function slugifyGoal(title) {
|
|
220
|
+
return title
|
|
221
|
+
.toLowerCase()
|
|
222
|
+
.replace(/[^a-z0-9]+/g, "-")
|
|
223
|
+
.replace(/^-+|-+$/g, "")
|
|
224
|
+
.slice(0, 64)
|
|
225
|
+
.replace(/-+$/g, "");
|
|
226
|
+
}
|
|
227
|
+
export function parseGoal(text, where) {
|
|
228
|
+
const raw = splitRaw(text, where);
|
|
229
|
+
const { title, description } = splitTitle(raw.body);
|
|
230
|
+
if (title === null) {
|
|
231
|
+
throw new TicketParseError(`${where}: expected the body to start with "# <title>"`);
|
|
232
|
+
}
|
|
233
|
+
const known = new Set(GOAL_FIELDS);
|
|
234
|
+
const extras = [];
|
|
235
|
+
for (const [key, value] of raw.fields) {
|
|
236
|
+
if (!known.has(key))
|
|
237
|
+
extras.push([key, value.trim()]);
|
|
238
|
+
}
|
|
239
|
+
return {
|
|
240
|
+
title,
|
|
241
|
+
description,
|
|
242
|
+
createdAt: stringField(raw, "created", where, ""),
|
|
243
|
+
updatedAt: stringField(raw, "updated", where, ""),
|
|
244
|
+
...(extras.length ? { extras } : {}),
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
/** Canonical bytes for a goal — fixed field order, like tickets. */
|
|
248
|
+
export function serializeGoal(doc) {
|
|
249
|
+
const lines = ["---", `created: ${doc.createdAt}`, `updated: ${doc.updatedAt}`];
|
|
250
|
+
for (const [key, value] of doc.extras ?? [])
|
|
251
|
+
lines.push(`${key}: ${value}`);
|
|
161
252
|
lines.push("---", "", `# ${doc.title}`);
|
|
162
253
|
if (doc.description)
|
|
163
254
|
lines.push("", doc.description);
|
|
164
255
|
return `${lines.join("\n")}\n`;
|
|
165
256
|
}
|
|
257
|
+
/** A goal, forgivingly — null when there's no frontmatter at all. */
|
|
258
|
+
export function parseGoalLenient(text) {
|
|
259
|
+
const raw = splitRaw(text, null);
|
|
260
|
+
if (!raw)
|
|
261
|
+
return null;
|
|
262
|
+
const { title, description } = splitTitle(raw.body);
|
|
263
|
+
return {
|
|
264
|
+
title: title ?? "",
|
|
265
|
+
description,
|
|
266
|
+
createdAt: lenientString(field(raw, "created")),
|
|
267
|
+
updatedAt: lenientString(field(raw, "updated")),
|
|
268
|
+
};
|
|
269
|
+
}
|
|
166
270
|
// ── Comments ─────────────────────────────────────────────────────────────────
|
|
167
271
|
export function parseComment(text, where) {
|
|
168
272
|
const raw = splitRaw(text, where);
|
|
@@ -179,6 +283,116 @@ export function serializeComment(doc) {
|
|
|
179
283
|
lines.push(`created: ${doc.createdAt}`, "---", "", doc.body);
|
|
180
284
|
return `${lines.join("\n")}\n`;
|
|
181
285
|
}
|
|
286
|
+
// ── Asks ─────────────────────────────────────────────────────────────────────
|
|
287
|
+
export function parseAsk(text, where) {
|
|
288
|
+
const raw = splitRaw(text, where);
|
|
289
|
+
const resolvedAt = field(raw, "resolved");
|
|
290
|
+
if (resolvedAt !== undefined && typeof resolvedAt !== "string") {
|
|
291
|
+
throw new TicketParseError(`${where}: resolved should be a timestamp string`);
|
|
292
|
+
}
|
|
293
|
+
return {
|
|
294
|
+
author: stringField(raw, "author", where, ""),
|
|
295
|
+
createdAt: stringField(raw, "created", where, ""),
|
|
296
|
+
resolvedAt: resolvedAt ?? null,
|
|
297
|
+
resolvedBy: resolvedAt === undefined ? null : stringField(raw, "resolved_by", where, ""),
|
|
298
|
+
body: raw.body,
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
export function serializeAsk(doc) {
|
|
302
|
+
const lines = ["---"];
|
|
303
|
+
if (doc.author)
|
|
304
|
+
lines.push(`author: ${JSON.stringify(doc.author)}`);
|
|
305
|
+
lines.push(`created: ${doc.createdAt}`);
|
|
306
|
+
if (doc.resolvedAt) {
|
|
307
|
+
lines.push(`resolved: ${doc.resolvedAt}`);
|
|
308
|
+
if (doc.resolvedBy)
|
|
309
|
+
lines.push(`resolved_by: ${JSON.stringify(doc.resolvedBy)}`);
|
|
310
|
+
}
|
|
311
|
+
lines.push("---", "", doc.body);
|
|
312
|
+
return `${lines.join("\n")}\n`;
|
|
313
|
+
}
|
|
314
|
+
/**
|
|
315
|
+
* An ask, forgivingly — null when there's no frontmatter at all. The lenient
|
|
316
|
+
* read matters more here than for comments: the inbox reads ask files straight
|
|
317
|
+
* off claim branches, which are exactly the bytes a strict parser can't refuse.
|
|
318
|
+
*/
|
|
319
|
+
export function parseAskLenient(text) {
|
|
320
|
+
const raw = splitRaw(text, null);
|
|
321
|
+
if (!raw)
|
|
322
|
+
return null;
|
|
323
|
+
const resolvedAt = field(raw, "resolved");
|
|
324
|
+
return {
|
|
325
|
+
author: lenientString(field(raw, "author")),
|
|
326
|
+
createdAt: lenientString(field(raw, "created")),
|
|
327
|
+
resolvedAt: typeof resolvedAt === "string" && resolvedAt !== "" ? resolvedAt : null,
|
|
328
|
+
resolvedBy: lenientString(field(raw, "resolved_by")) || null,
|
|
329
|
+
body: raw.body,
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
// ── Lenient parsing ──────────────────────────────────────────────────────────
|
|
333
|
+
//
|
|
334
|
+
// The hosted board's read of the same format. The CLI is strict — it wrote the
|
|
335
|
+
// file, so a malformation is a bug worth halting on — but a renderer is looking
|
|
336
|
+
// at whatever a hand-edit or a bad merge left behind, and it must degrade
|
|
337
|
+
// rather than throw: a broken ticket becomes a degraded ticket (unknown status
|
|
338
|
+
// → backlog, missing heading → empty title), never a broken board. Living here
|
|
339
|
+
// rather than restated in the worker keeps one definition of the format.
|
|
340
|
+
function lenientStrings(value) {
|
|
341
|
+
return Array.isArray(value) ? value.filter((v) => typeof v === "string") : [];
|
|
342
|
+
}
|
|
343
|
+
function lenientKeys(value) {
|
|
344
|
+
// Numeric entries (the pre-TAS-42 id format) are dropped, not coerced: a
|
|
345
|
+
// rendered old branch degrades to unlinked tickets, never to wrong links.
|
|
346
|
+
return Array.isArray(value) ? value.filter((v) => typeof v === "string") : [];
|
|
347
|
+
}
|
|
348
|
+
function lenientString(value) {
|
|
349
|
+
return typeof value === "string" ? value : "";
|
|
350
|
+
}
|
|
351
|
+
/** A ticket, forgivingly — or null when there's no frontmatter to read at all. */
|
|
352
|
+
export function parseTicketLenient(text) {
|
|
353
|
+
const raw = splitRaw(text, null);
|
|
354
|
+
if (!raw)
|
|
355
|
+
return null;
|
|
356
|
+
const status = field(raw, "status");
|
|
357
|
+
// No `milestone:` read here either — on the old branches the hosted board
|
|
358
|
+
// previews, a pre-0.8 ticket degrades to goalless, the same as any other
|
|
359
|
+
// retired field. History renders; it doesn't get reinterpreted.
|
|
360
|
+
const goal = field(raw, "goal");
|
|
361
|
+
const position = field(raw, "position");
|
|
362
|
+
const { title, description } = splitTitle(raw.body);
|
|
363
|
+
return {
|
|
364
|
+
title: title ?? "",
|
|
365
|
+
description,
|
|
366
|
+
status: typeof status === "string" && isStatus(status) ? status : "backlog",
|
|
367
|
+
tags: lenientStrings(field(raw, "tags")),
|
|
368
|
+
goal: typeof goal === "string" && goal !== "" ? goal : null,
|
|
369
|
+
blockedBy: [...new Set(lenientKeys(field(raw, "blocked_by")))].sort(),
|
|
370
|
+
prs: lenientStrings(field(raw, "prs")),
|
|
371
|
+
position: typeof position === "number" && Number.isFinite(position) ? position : 0,
|
|
372
|
+
createdAt: lenientString(field(raw, "created")),
|
|
373
|
+
updatedAt: lenientString(field(raw, "updated")),
|
|
374
|
+
};
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* The frontmatter keys a file carries, leniently — null when there's no
|
|
378
|
+
* frontmatter at all. `task check` uses this to spot unknown keys in files
|
|
379
|
+
* whose parsed shape (comments) doesn't carry them through.
|
|
380
|
+
*/
|
|
381
|
+
export function frontmatterKeys(text) {
|
|
382
|
+
const raw = splitRaw(text, null);
|
|
383
|
+
return raw ? [...raw.fields.keys()] : null;
|
|
384
|
+
}
|
|
385
|
+
/** A comment, forgivingly — or null when there's no frontmatter at all. */
|
|
386
|
+
export function parseCommentLenient(text) {
|
|
387
|
+
const raw = splitRaw(text, null);
|
|
388
|
+
if (!raw)
|
|
389
|
+
return null;
|
|
390
|
+
return {
|
|
391
|
+
author: lenientString(field(raw, "author")),
|
|
392
|
+
createdAt: lenientString(field(raw, "created")),
|
|
393
|
+
body: raw.body,
|
|
394
|
+
};
|
|
395
|
+
}
|
|
182
396
|
/**
|
|
183
397
|
* A comment's filename stem — readable, sortable, and unique enough that two
|
|
184
398
|
* branches almost never mint the same one: `2026-08-15T165943-claude`. The
|
package/dist/ticket-doc.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ticket-doc.js","sourceRoot":"","sources":["../src/ticket-doc.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ticket-doc.js","sourceRoot":"","sources":["../src/ticket-doc.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -2,24 +2,65 @@
|
|
|
2
2
|
* you can configure is a task manager you have to configure. */
|
|
3
3
|
export declare const STATUSES: readonly ["backlog", "todo", "in_progress", "done", "canceled"];
|
|
4
4
|
export type Status = (typeof STATUSES)[number];
|
|
5
|
+
/**
|
|
6
|
+
* An ask: one thing a person owes this ticket before it can be done. Stored
|
|
7
|
+
* like a comment — one file per ask under `tickets/<n>/asks/` — so a worker on
|
|
8
|
+
* a claim branch can add one without ever conflicting with main. The ask is
|
|
9
|
+
* the primitive everything human-owed funnels through: `needsHuman` is derived
|
|
10
|
+
* from open asks, `task inbox` is the list of them, and `done` is gated on
|
|
11
|
+
* zero remaining.
|
|
12
|
+
*/
|
|
13
|
+
export interface Ask {
|
|
14
|
+
/** Stable opaque id — the ask's filename stem (e.g. "2026-08-27T104501-claude"). */
|
|
15
|
+
id: string;
|
|
16
|
+
taskId: string;
|
|
17
|
+
/**
|
|
18
|
+
* 1-based position in creation order across the ticket's asks, resolved and
|
|
19
|
+
* open alike — the short handle `task resolve <id> <ordinal>` takes.
|
|
20
|
+
*/
|
|
21
|
+
ordinal: number;
|
|
22
|
+
text: string;
|
|
23
|
+
author: string;
|
|
24
|
+
createdAt: string;
|
|
25
|
+
/** Both null while the ask is open. */
|
|
26
|
+
resolvedAt: string | null;
|
|
27
|
+
resolvedBy: string | null;
|
|
28
|
+
}
|
|
5
29
|
export interface Task {
|
|
6
|
-
/** Display id — `<prefix>-<
|
|
30
|
+
/** Display id — `<prefix>-<key>`, e.g. "PHO-x7k4m". */
|
|
7
31
|
id: string;
|
|
8
|
-
|
|
32
|
+
/**
|
|
33
|
+
* The ticket's key: 5 random lowercase characters minted at creation (see
|
|
34
|
+
* id.ts), doubling as its directory name under `.task/tickets/`. Random on
|
|
35
|
+
* purpose — allocation must be safe across branches that have never seen
|
|
36
|
+
* each other — and opaque on purpose: creation order lives in `createdAt`,
|
|
37
|
+
* board order in `position`.
|
|
38
|
+
*/
|
|
39
|
+
key: string;
|
|
9
40
|
title: string;
|
|
10
41
|
description: string;
|
|
11
42
|
status: Status;
|
|
12
43
|
tags: string[];
|
|
13
|
-
|
|
14
|
-
|
|
44
|
+
/**
|
|
45
|
+
* Slug of the goal this task belongs to — at most one. Tags answer "what
|
|
46
|
+
* kind" (many); the goal answers "where is this going" (one). Something that
|
|
47
|
+
* wants to live in two goals is a tag.
|
|
48
|
+
*/
|
|
49
|
+
goal: string | null;
|
|
50
|
+
/**
|
|
51
|
+
* Derived, never stored: true while any ask is open. There is no flag to
|
|
52
|
+
* set — a flag with no stated reason is the failure mode asks exist to end.
|
|
53
|
+
*/
|
|
15
54
|
needsHuman: boolean;
|
|
55
|
+
/** Every ask on this ticket, open and resolved, in creation order. */
|
|
56
|
+
asks: Ask[];
|
|
16
57
|
/**
|
|
17
|
-
*
|
|
58
|
+
* Keys of tasks this one blocks / is blocked by. One relation, two views:
|
|
18
59
|
* a single `(blocker, blocked)` row shows up in the blocker's `blocks` and
|
|
19
60
|
* the blocked task's `blockedBy`, so the mirror can never drift.
|
|
20
61
|
*/
|
|
21
|
-
blocks:
|
|
22
|
-
blockedBy:
|
|
62
|
+
blocks: string[];
|
|
63
|
+
blockedBy: string[];
|
|
23
64
|
/** Pull request URLs attached to this task. */
|
|
24
65
|
prs: string[];
|
|
25
66
|
/** Sort key within a status column; smaller sorts first. */
|
|
@@ -34,37 +75,85 @@ export interface Task {
|
|
|
34
75
|
archived?: boolean;
|
|
35
76
|
}
|
|
36
77
|
export interface Comment {
|
|
37
|
-
/**
|
|
38
|
-
* Stable opaque id. On file-backed boards it's the comment's filename stem
|
|
39
|
-
* (e.g. "2026-08-15T165943-claude"); on legacy SQLite boards, the rowid as a
|
|
40
|
-
* string.
|
|
41
|
-
*/
|
|
78
|
+
/** Stable opaque id — the comment's filename stem (e.g. "2026-08-15T165943-claude"). */
|
|
42
79
|
id: string;
|
|
43
80
|
taskId: string;
|
|
44
81
|
author: string;
|
|
45
82
|
body: string;
|
|
46
83
|
createdAt: string;
|
|
47
84
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
/** Uppercase id prefix, e.g. "PHO" → PHO-1, PHO-2, … */
|
|
51
|
-
prefix: string;
|
|
52
|
-
version: number;
|
|
85
|
+
/** How this board's tickets get claimed — see `claim.ts` for the mechanics. */
|
|
86
|
+
export interface ClaimsConfig {
|
|
53
87
|
/**
|
|
54
88
|
* Branch namespace `task claim` creates claim branches under — committed
|
|
55
89
|
* with the board on purpose, so every worker and every clone agree on what
|
|
56
90
|
* "claimed" looks like. Defaults to "task/claim/"; repos whose workers are
|
|
57
91
|
* Claude Code cloud sessions set "claude/task/", the one prefix that
|
|
58
|
-
* runtime can push without extra ceremony.
|
|
92
|
+
* runtime can push without extra ceremony. Must agree across a repo's
|
|
93
|
+
* boards (`task check` lints it) — workflows match claim branches by
|
|
94
|
+
* pattern, and one repo with two patterns matches neither reliably.
|
|
95
|
+
*/
|
|
96
|
+
branchPrefix?: string;
|
|
97
|
+
/**
|
|
98
|
+
* Repo-wide cap on open claims: `task claim` refuses (exit 2) while this
|
|
99
|
+
* many claim branches exist on origin, `--force` overrides. Read from the
|
|
100
|
+
* repo's *root* board only — a WIP cap per board is no cap at all.
|
|
101
|
+
*/
|
|
102
|
+
maxOpenCount?: number;
|
|
103
|
+
}
|
|
104
|
+
export interface ProjectConfig {
|
|
105
|
+
name: string;
|
|
106
|
+
/** Uppercase id prefix, e.g. "PHO" → PHO-x7k4m, PHO-q3v8d, … */
|
|
107
|
+
prefix: string;
|
|
108
|
+
version: number;
|
|
109
|
+
/**
|
|
110
|
+
* Pre-0.8 spelling of `claims.branchPrefix`. Never honored — typed only so
|
|
111
|
+
* `claimNamespace` can refuse it by name instead of silently defaulting the
|
|
112
|
+
* board's committed lock convention out from under its workers.
|
|
59
113
|
*/
|
|
60
114
|
claimPrefix?: string;
|
|
115
|
+
claims?: ClaimsConfig;
|
|
116
|
+
/**
|
|
117
|
+
* Root board only: the repo's automation-visible boards, by id prefix, in
|
|
118
|
+
* priority order. This is *selection scope* — where `claim --next` and
|
|
119
|
+
* `list --claimable` look — not permission: explicit-id claims work on any
|
|
120
|
+
* board regardless. Absent → automation sees the nearest board only, so a
|
|
121
|
+
* vendored board can't opt itself in.
|
|
122
|
+
*/
|
|
123
|
+
boards?: string[];
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* A goal: a titled, described destination that tasks belong to. Progress is
|
|
127
|
+
* always derived from its tasks — a goal has no stored status on purpose,
|
|
128
|
+
* because a second state machine is a second thing that can lie.
|
|
129
|
+
*/
|
|
130
|
+
export interface Goal {
|
|
131
|
+
/** Filename stem under `.task/goals/` — the stable identity tickets reference. */
|
|
132
|
+
slug: string;
|
|
133
|
+
title: string;
|
|
134
|
+
/** The strategic why. Tickets keep the how; this is the context they share. */
|
|
135
|
+
description: string;
|
|
136
|
+
createdAt: string;
|
|
137
|
+
updatedAt: string;
|
|
138
|
+
/** Set (to true) only on goals living in `.task/goals/archive/`. */
|
|
139
|
+
archived?: boolean;
|
|
140
|
+
}
|
|
141
|
+
export interface GoalInput {
|
|
142
|
+
title: string;
|
|
143
|
+
/** Derived from the title when omitted. */
|
|
144
|
+
slug?: string;
|
|
145
|
+
description?: string;
|
|
146
|
+
}
|
|
147
|
+
export interface GoalPatch {
|
|
148
|
+
title?: string;
|
|
149
|
+
description?: string;
|
|
61
150
|
}
|
|
62
151
|
export interface TaskFilter {
|
|
63
152
|
statuses?: Status[];
|
|
64
153
|
/** Any-of: a task matches if it carries at least one of these tags. */
|
|
65
154
|
tags?: string[];
|
|
66
|
-
|
|
67
|
-
/** undefined = don't filter
|
|
155
|
+
goal?: string;
|
|
156
|
+
/** Matches the *derived* flag — open asks, nothing else. undefined = don't filter. */
|
|
68
157
|
needsHuman?: boolean;
|
|
69
158
|
/** true = list the archive instead of the board. */
|
|
70
159
|
archived?: boolean;
|
|
@@ -74,10 +163,9 @@ export interface TaskInput {
|
|
|
74
163
|
description?: string;
|
|
75
164
|
status?: Status;
|
|
76
165
|
tags?: string[];
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
blockedBy?: number[];
|
|
166
|
+
goal?: string | null;
|
|
167
|
+
blocks?: string[];
|
|
168
|
+
blockedBy?: string[];
|
|
81
169
|
prs?: string[];
|
|
82
170
|
}
|
|
83
171
|
export interface TaskPatch {
|
|
@@ -85,14 +173,13 @@ export interface TaskPatch {
|
|
|
85
173
|
description?: string;
|
|
86
174
|
status?: Status;
|
|
87
175
|
tags?: string[];
|
|
88
|
-
|
|
89
|
-
needsHuman?: boolean;
|
|
176
|
+
goal?: string | null;
|
|
90
177
|
/**
|
|
91
178
|
* Full replacement, like `tags` — the store reconciles the relation table
|
|
92
179
|
* to match. Writing either side updates the other task's mirror view.
|
|
93
180
|
*/
|
|
94
|
-
blocks?:
|
|
95
|
-
blockedBy?:
|
|
181
|
+
blocks?: string[];
|
|
182
|
+
blockedBy?: string[];
|
|
96
183
|
prs?: string[];
|
|
97
184
|
/** Explicit board position (used by drag-and-drop in the UI). */
|
|
98
185
|
position?: number;
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;gEACgE;AAChE,eAAO,MAAM,QAAQ,iEAMX,CAAA;AACV,MAAM,MAAM,MAAM,GAAG,CAAC,OAAO,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAA;AAE9C,MAAM,WAAW,IAAI;IACnB,uDAAuD;IACvD,EAAE,EAAE,MAAM,CAAA;IACV,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;gEACgE;AAChE,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,SAAS;IACT,MAAM;IACN,aAAa;IACb,MAAM;IACN,UAAU;CACF,CAAA;
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;gEACgE;AAChE,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,SAAS;IACT,MAAM;IACN,aAAa;IACb,MAAM;IACN,UAAU;CACF,CAAA;AAoMV,MAAM,UAAU,QAAQ,CAAC,KAAa;IACpC,OAAQ,QAA8B,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;AACxD,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nickmeriano/task",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A task manager that lives in your repo — plain-text tickets in .task/, a zero-dependency CLI for humans and agents, and a live kanban/table UI via `task serve`.",
|
|
6
6
|
"license": "MIT",
|