@nickmeriano/task 0.8.0 → 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 +65 -22
- 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 +3 -2
- package/dist/check.d.ts.map +1 -1
- package/dist/check.js +99 -60
- package/dist/check.js.map +1 -1
- package/dist/check.test.js +99 -60
- package/dist/check.test.js.map +1 -1
- 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 +21 -22
- package/dist/claim.d.ts.map +1 -1
- package/dist/claim.js +58 -83
- package/dist/claim.js.map +1 -1
- package/dist/claim.test.d.ts +2 -2
- package/dist/claim.test.js +111 -94
- package/dist/claim.test.js.map +1 -1
- package/dist/cli.js +241 -64
- package/dist/cli.js.map +1 -1
- package/dist/file-store.d.ts +70 -24
- package/dist/file-store.d.ts.map +1 -1
- package/dist/file-store.js +319 -141
- 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/overview.d.ts +9 -0
- package/dist/overview.d.ts.map +1 -1
- package/dist/overview.js +19 -11
- package/dist/overview.js.map +1 -1
- package/dist/overview.test.js +6 -5
- package/dist/overview.test.js.map +1 -1
- package/dist/promote.test.d.ts +3 -2
- package/dist/promote.test.d.ts.map +1 -1
- package/dist/promote.test.js +29 -31
- package/dist/promote.test.js.map +1 -1
- 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 +3 -1
- package/dist/search.d.ts.map +1 -1
- package/dist/search.js +15 -2
- package/dist/search.js.map +1 -1
- package/dist/search.test.js +9 -9
- package/dist/search.test.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +218 -21
- package/dist/server.js.map +1 -1
- package/dist/store.d.ts +28 -14
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js.map +1 -1
- package/dist/store.test.js +88 -75
- package/dist/store.test.js.map +1 -1
- package/dist/ticket-doc.d.ts +26 -10
- package/dist/ticket-doc.d.ts.map +1 -1
- package/dist/ticket-doc.js +71 -27
- package/dist/ticket-doc.js.map +1 -1
- package/dist/types.d.ts +51 -17
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +1 -1
- package/skill/SKILL.md +70 -23
- package/src/asks.test.ts +355 -0
- package/src/check.test.ts +129 -72
- package/src/check.ts +101 -58
- package/src/claim-io.ts +401 -0
- package/src/claim.test.ts +141 -99
- package/src/claim.ts +69 -96
- package/src/cli.ts +251 -63
- package/src/file-store.ts +357 -145
- 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/overview.test.ts +6 -5
- package/src/overview.ts +25 -10
- package/src/promote.test.ts +40 -28
- package/src/publish.ts +6 -53
- package/src/search.test.ts +11 -11
- package/src/search.ts +17 -3
- package/src/server.ts +221 -19
- package/src/store.test.ts +95 -77
- package/src/store.ts +28 -13
- package/src/ticket-doc.ts +93 -30
- package/src/types.ts +52 -17
- 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-BJmOsOdR.js +0 -229
- package/ui/dist/assets/index-BoqQlqSU.css +0 -1
package/dist/check.js
CHANGED
|
@@ -10,8 +10,9 @@
|
|
|
10
10
|
* references (one branch deleted a ticket another branch linked to), `goal:`
|
|
11
11
|
* refs naming a goal that doesn't exist, tickets duplicated between the board
|
|
12
12
|
* and the archive, unknown frontmatter keys, and formatting drift from the
|
|
13
|
-
* canonical serialization
|
|
14
|
-
*
|
|
13
|
+
* canonical serialization. Retired pre-0.8 spellings (`milestone:`,
|
|
14
|
+
* `claimPrefix`) are refused by the parsers with the rename in the error —
|
|
15
|
+
* this lint just surfaces those messages; there is no migration machinery.
|
|
15
16
|
*
|
|
16
17
|
* The mechanical repairs — pruning dangling or self references, deduping and
|
|
17
18
|
* sorting `blocked_by`, rewriting a file into canonical form — are applied by
|
|
@@ -21,10 +22,11 @@
|
|
|
21
22
|
*/
|
|
22
23
|
import { existsSync, readdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
23
24
|
import { join } from "node:path";
|
|
24
|
-
import { ARCHIVE_DIR, COMMENTS_DIR, GOALS_ARCHIVE_DIR, GOALS_DIR, TICKETS_DIR, TICKET_FILE, } from "./file-store.js";
|
|
25
|
-
import { COMMENT_FIELDS, TicketParseError, frontmatterKeys, isGoalSlug, parseComment, parseGoal, parseTicket, serializeComment, serializeGoal, serializeTicket, } from "./ticket-doc.js";
|
|
25
|
+
import { ARCHIVE_DIR, ASKS_DIR, COMMENTS_DIR, GOALS_ARCHIVE_DIR, GOALS_DIR, TICKETS_DIR, TICKET_FILE, } from "./file-store.js";
|
|
26
|
+
import { ASK_FIELDS, COMMENT_FIELDS, TicketParseError, frontmatterKeys, isGoalSlug, parseAsk, parseComment, parseGoal, parseTicket, serializeAsk, serializeComment, serializeGoal, serializeTicket, } from "./ticket-doc.js";
|
|
26
27
|
import { CONFIG_FILE, TASK_DIR, boardConfig, findBoards, findRoot, findScopeRoot, } from "./store.js";
|
|
27
28
|
import { claimNamespace } from "./claim.js";
|
|
29
|
+
import { isTicketKey } from "./id.js";
|
|
28
30
|
/** The boards `task check` covers from `cwd` — the same set `task serve` has. */
|
|
29
31
|
export function checkRoot(cwd) {
|
|
30
32
|
return findRoot(cwd) ?? cwd;
|
|
@@ -66,14 +68,16 @@ export function checkBoards(root, fix) {
|
|
|
66
68
|
return { boards: boards.length, files, issues, fixed };
|
|
67
69
|
}
|
|
68
70
|
/**
|
|
69
|
-
* Config lints (TAS-27):
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
71
|
+
* Config lints (TAS-27): a `boards` list on a non-root board (root-only by
|
|
72
|
+
* design, so vendored boards can't opt into a repo's automation), a malformed
|
|
73
|
+
* one, an unusable branch prefix, a branch prefix that disagrees with the
|
|
74
|
+
* root board's (workflows match claim branches by pattern — one repo, one
|
|
75
|
+
* namespace), and a leftover pre-0.8 `claimPrefix` key. The retired spelling
|
|
76
|
+
* is not migrated anymore (TAS-41: no compat) — with no `claims.branchPrefix`
|
|
77
|
+
* beside it, `claimNamespace` refuses by name and that error surfaces here;
|
|
78
|
+
* with one, the stray key is inert and gets its own line.
|
|
75
79
|
*/
|
|
76
|
-
function checkConfig(board, scopeRoot, rootBranchPrefix,
|
|
80
|
+
function checkConfig(board, scopeRoot, rootBranchPrefix, push) {
|
|
77
81
|
const absolute = join(board.root, TASK_DIR, CONFIG_FILE);
|
|
78
82
|
const file = posixJoin(board.id, TASK_DIR, CONFIG_FILE);
|
|
79
83
|
let raw;
|
|
@@ -85,29 +89,8 @@ function checkConfig(board, scopeRoot, rootBranchPrefix, fix, push, fixed) {
|
|
|
85
89
|
return null;
|
|
86
90
|
}
|
|
87
91
|
const config = raw;
|
|
88
|
-
if (raw.claimPrefix !== undefined) {
|
|
89
|
-
push(file, "`claimPrefix` is
|
|
90
|
-
if (fix) {
|
|
91
|
-
// In-place key replacement so the migration diff is one line where
|
|
92
|
-
// possible; an existing claims.branchPrefix wins over the legacy key.
|
|
93
|
-
const claims = {
|
|
94
|
-
...(typeof raw.claims === "object" && raw.claims !== null
|
|
95
|
-
? raw.claims
|
|
96
|
-
: {}),
|
|
97
|
-
};
|
|
98
|
-
claims.branchPrefix ??= raw.claimPrefix;
|
|
99
|
-
const migrated = {};
|
|
100
|
-
for (const [key, value] of Object.entries(raw)) {
|
|
101
|
-
if (key === "claimPrefix") {
|
|
102
|
-
if (raw.claims === undefined)
|
|
103
|
-
migrated.claims = claims;
|
|
104
|
-
continue;
|
|
105
|
-
}
|
|
106
|
-
migrated[key] = key === "claims" ? claims : value;
|
|
107
|
-
}
|
|
108
|
-
writeFileSync(absolute, `${JSON.stringify(migrated, null, 2)}\n`);
|
|
109
|
-
fixed.push(file);
|
|
110
|
-
}
|
|
92
|
+
if (raw.claimPrefix !== undefined && config.claims?.branchPrefix !== undefined) {
|
|
93
|
+
push(file, "`claimPrefix` is the pre-0.8 spelling and is no longer read — `claims.branchPrefix` wins; delete the leftover key");
|
|
111
94
|
}
|
|
112
95
|
if (raw.boards !== undefined) {
|
|
113
96
|
if (board.root !== scopeRoot) {
|
|
@@ -138,9 +121,9 @@ function checkBoard(board, scopeRoot, rootBranchPrefix, fix, issues, fixed) {
|
|
|
138
121
|
const taskDir = join(board.root, TASK_DIR);
|
|
139
122
|
const relTaskDir = posixJoin(board.id, TASK_DIR);
|
|
140
123
|
const push = (file, message, fixable = false) => issues.push({ board: board.id, file, message, fixable });
|
|
141
|
-
const config = checkConfig(board, scopeRoot, rootBranchPrefix,
|
|
124
|
+
const config = checkConfig(board, scopeRoot, rootBranchPrefix, push);
|
|
142
125
|
const prefix = config?.prefix ?? "TASK";
|
|
143
|
-
const displayId = (
|
|
126
|
+
const displayId = (k) => `${prefix}-${k}`;
|
|
144
127
|
// ── Collect every ticket, live and archived ────────────────────────────────
|
|
145
128
|
const tickets = [];
|
|
146
129
|
let files = 0;
|
|
@@ -155,8 +138,18 @@ function checkBoard(board, scopeRoot, rootBranchPrefix, fix, issues, fixed) {
|
|
|
155
138
|
if (entry.name.startsWith("."))
|
|
156
139
|
continue;
|
|
157
140
|
const relEntry = posixJoin(relTaskDir, dir, entry.name);
|
|
158
|
-
|
|
159
|
-
|
|
141
|
+
// A purely numeric directory is a pre-TAS-42 ticket — the old
|
|
142
|
+
// sequential-id format, which nothing reads anymore. The likely way one
|
|
143
|
+
// appears post-migration is merging a branch cut before the cutover;
|
|
144
|
+
// the fix is mechanical and named here.
|
|
145
|
+
if (entry.isDirectory() && /^\d+$/.test(entry.name)) {
|
|
146
|
+
push(relEntry, "numeric ticket directory — the pre-TAS-42 sequential-id format, which is no longer read; migrate it with `node tools/migrate-ids/migrate.mjs --ticket <board-dir> " +
|
|
147
|
+
entry.name +
|
|
148
|
+
"`");
|
|
149
|
+
continue;
|
|
150
|
+
}
|
|
151
|
+
if (!entry.isDirectory() || !isTicketKey(entry.name)) {
|
|
152
|
+
push(relEntry, "unexpected entry — ticket directories are named by their key (e.g. x7k4m)");
|
|
160
153
|
continue;
|
|
161
154
|
}
|
|
162
155
|
const absolute = join(home, entry.name, TICKET_FILE);
|
|
@@ -176,17 +169,19 @@ function checkBoard(board, scopeRoot, rootBranchPrefix, fix, issues, fixed) {
|
|
|
176
169
|
throw error;
|
|
177
170
|
push(file, reason(error, file));
|
|
178
171
|
}
|
|
179
|
-
tickets.push({
|
|
172
|
+
tickets.push({ key: entry.name, file, absolute, archived, text, doc });
|
|
180
173
|
}
|
|
181
174
|
}
|
|
182
175
|
// A ticket present in both tickets/ and archive/ is a merge artifact: one
|
|
183
176
|
// branch archived it while another kept editing it. Which copy wins is a
|
|
184
|
-
// human call, so it's reported, never auto-fixed.
|
|
185
|
-
|
|
186
|
-
|
|
177
|
+
// human call, so it's reported, never auto-fixed. (This doubles as the
|
|
178
|
+
// duplicate-key lint: within either directory git itself makes duplicates
|
|
179
|
+
// impossible, so board-and-archive is the only place one can exist.)
|
|
180
|
+
const live = new Set(tickets.filter((t) => !t.archived).map((t) => t.key));
|
|
181
|
+
const valid = new Set(tickets.map((t) => t.key));
|
|
187
182
|
for (const ticket of tickets) {
|
|
188
|
-
if (ticket.archived && live.has(ticket.
|
|
189
|
-
push(ticket.file, `${displayId(ticket.
|
|
183
|
+
if (ticket.archived && live.has(ticket.key)) {
|
|
184
|
+
push(ticket.file, `${displayId(ticket.key)} also exists in ${TICKETS_DIR}/ — a merge kept both copies; delete one`);
|
|
190
185
|
}
|
|
191
186
|
}
|
|
192
187
|
// ── Goals ──────────────────────────────────────────────────────────────────
|
|
@@ -256,7 +251,7 @@ function checkBoard(board, scopeRoot, rootBranchPrefix, fix, issues, fixed) {
|
|
|
256
251
|
}
|
|
257
252
|
// ── Per-ticket content checks ──────────────────────────────────────────────
|
|
258
253
|
for (const ticket of tickets) {
|
|
259
|
-
const { doc, file,
|
|
254
|
+
const { doc, file, key } = ticket;
|
|
260
255
|
if (!doc)
|
|
261
256
|
continue;
|
|
262
257
|
for (const [key, at] of [
|
|
@@ -282,32 +277,27 @@ function checkBoard(board, scopeRoot, rootBranchPrefix, fix, issues, fixed) {
|
|
|
282
277
|
// The repaired relation list: no self references, no dangling targets, no
|
|
283
278
|
// duplicates, sorted. Each divergence is its own issue; all are mechanical.
|
|
284
279
|
const pruned = [...new Set(doc.blockedBy)]
|
|
285
|
-
.filter((
|
|
286
|
-
.sort((a, b) => a
|
|
287
|
-
if (doc.blockedBy.includes(
|
|
288
|
-
push(file, `${displayId(
|
|
280
|
+
.filter((k) => k !== key && valid.has(k))
|
|
281
|
+
.sort((a, b) => a.localeCompare(b));
|
|
282
|
+
if (doc.blockedBy.includes(key)) {
|
|
283
|
+
push(file, `${displayId(key)} is blocked by itself`, true);
|
|
289
284
|
}
|
|
290
285
|
for (const target of new Set(doc.blockedBy)) {
|
|
291
|
-
if (target !==
|
|
286
|
+
if (target !== key && !valid.has(target)) {
|
|
292
287
|
push(file, `blocked_by references ${displayId(target)}, which doesn't exist`, true);
|
|
293
288
|
}
|
|
294
289
|
}
|
|
295
290
|
// Everything else — duplicate or unsorted blocked_by, hand-edited field
|
|
296
291
|
// order or quoting, stray whitespace — is formatting drift: the parse is
|
|
297
292
|
// fine, the bytes just aren't what the CLI would write. `normalized` keeps
|
|
298
|
-
// the dangling refs so drift isn't double-reported on top of them.
|
|
299
|
-
//
|
|
300
|
-
//
|
|
301
|
-
// parses as the goal, and the canonical rewrite is the whole migration —
|
|
302
|
-
// but "not in canonical form" would undersell what the fix is about to do.
|
|
293
|
+
// the dangling refs so drift isn't double-reported on top of them. (The
|
|
294
|
+
// pre-0.8 `milestone:` key never reaches here — the strict parse refuses
|
|
295
|
+
// it by name, and that error is the whole report.)
|
|
303
296
|
const normalized = serializeTicket({
|
|
304
297
|
...doc,
|
|
305
|
-
blockedBy: [...new Set(doc.blockedBy)].sort((a, b) => a
|
|
298
|
+
blockedBy: [...new Set(doc.blockedBy)].sort((a, b) => a.localeCompare(b)),
|
|
306
299
|
});
|
|
307
|
-
if (
|
|
308
|
-
push(file, "`milestone:` is now `goal:` — `task check --fix` rewrites it", true);
|
|
309
|
-
}
|
|
310
|
-
else if (normalized !== ticket.text) {
|
|
300
|
+
if (normalized !== ticket.text) {
|
|
311
301
|
push(file, "not in canonical form — `task check --fix` rewrites it", true);
|
|
312
302
|
}
|
|
313
303
|
const canonical = serializeTicket({ ...doc, blockedBy: pruned });
|
|
@@ -316,6 +306,55 @@ function checkBoard(board, scopeRoot, rootBranchPrefix, fix, issues, fixed) {
|
|
|
316
306
|
fixed.push(file);
|
|
317
307
|
}
|
|
318
308
|
}
|
|
309
|
+
// ── Asks ───────────────────────────────────────────────────────────────────
|
|
310
|
+
// Same pass as comments: strict parse, timestamps, unknown keys, canonical
|
|
311
|
+
// drift. An empty ask body gets its own line — an ask that doesn't say what's
|
|
312
|
+
// owed is the old boolean wearing a new file.
|
|
313
|
+
const knownAskKeys = new Set(ASK_FIELDS);
|
|
314
|
+
for (const ticket of tickets) {
|
|
315
|
+
const dir = join(ticket.absolute, "..", ASKS_DIR);
|
|
316
|
+
if (!existsSync(dir))
|
|
317
|
+
continue;
|
|
318
|
+
for (const entry of readdirSync(dir)) {
|
|
319
|
+
if (!entry.endsWith(".md") || entry.startsWith("."))
|
|
320
|
+
continue;
|
|
321
|
+
files++;
|
|
322
|
+
const file = posixJoin(ticket.file.slice(0, -TICKET_FILE.length - 1), ASKS_DIR, entry);
|
|
323
|
+
const text = readFileSync(join(dir, entry), "utf8");
|
|
324
|
+
let parsed;
|
|
325
|
+
try {
|
|
326
|
+
parsed = parseAsk(text, file);
|
|
327
|
+
}
|
|
328
|
+
catch (error) {
|
|
329
|
+
if (!(error instanceof TicketParseError))
|
|
330
|
+
throw error;
|
|
331
|
+
push(file, reason(error, file));
|
|
332
|
+
continue;
|
|
333
|
+
}
|
|
334
|
+
if (!isValidTimestamp(parsed.createdAt))
|
|
335
|
+
push(file, "created is not a valid timestamp");
|
|
336
|
+
if (parsed.resolvedAt !== null && !isValidTimestamp(parsed.resolvedAt)) {
|
|
337
|
+
push(file, "resolved is not a valid timestamp");
|
|
338
|
+
}
|
|
339
|
+
if (!parsed.body.trim())
|
|
340
|
+
push(file, "empty ask — say what a person owes, or delete it");
|
|
341
|
+
let unknownKeys = false;
|
|
342
|
+
for (const key of frontmatterKeys(text) ?? []) {
|
|
343
|
+
if (knownAskKeys.has(key))
|
|
344
|
+
continue;
|
|
345
|
+
unknownKeys = true;
|
|
346
|
+
push(file, `unknown frontmatter key "${key}"`);
|
|
347
|
+
}
|
|
348
|
+
const canonical = serializeAsk(parsed);
|
|
349
|
+
if (canonical !== text && !unknownKeys) {
|
|
350
|
+
push(file, "not in canonical form — `task check --fix` rewrites it", true);
|
|
351
|
+
if (fix) {
|
|
352
|
+
writeFileSync(join(dir, entry), canonical);
|
|
353
|
+
fixed.push(file);
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
}
|
|
319
358
|
// ── Comments ───────────────────────────────────────────────────────────────
|
|
320
359
|
const knownCommentKeys = new Set(COMMENT_FIELDS);
|
|
321
360
|
for (const ticket of tickets) {
|
package/dist/check.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"check.js","sourceRoot":"","sources":["../src/check.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAC9E,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EACL,WAAW,EACX,YAAY,EACZ,iBAAiB,EACjB,SAAS,EACT,WAAW,EACX,WAAW,GACZ,MAAM,iBAAiB,CAAA;AACxB,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,eAAe,EACf,UAAU,EACV,YAAY,EACZ,SAAS,EACT,WAAW,EACX,gBAAgB,EAChB,aAAa,EACb,eAAe,GAEhB,MAAM,iBAAiB,CAAA;AACxB,OAAO,EACL,WAAW,EACX,QAAQ,EACR,WAAW,EACX,UAAU,EACV,QAAQ,EACR,aAAa,GAEd,MAAM,YAAY,CAAA;AACnB,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAsB3C,iFAAiF;AACjF,MAAM,UAAU,SAAS,CAAC,GAAW;IACnC,OAAO,QAAQ,CAAC,GAAG,CAAC,IAAI,GAAG,CAAA;AAC7B,CAAC;AAaD,SAAS,SAAS,CAAC,GAAG,KAAe;IACnC,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AAC7D,CAAC;AAED,sFAAsF;AACtF,SAAS,MAAM,CAAC,KAAc,EAAE,KAAa;IAC3C,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;IACtE,OAAO,OAAO,CAAC,UAAU,CAAC,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAA;AACrF,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAa;IACrC,OAAO,KAAK,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAA;AACzD,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,IAAY,EAAE,GAAY;IACpD,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,CAAA;IAC/B,yEAAyE;IACzE,2EAA2E;IAC3E,0EAA0E;IAC1E,wEAAwE;IACxE,MAAM,SAAS,GAAG,aAAa,CAAC,IAAI,CAAC,CAAA;IACrC,wEAAwE;IACxE,kEAAkE;IAClE,+DAA+D;IAC/D,IAAI,gBAAgB,GAAkB,IAAI,CAAA;IAC1C,IAAI,CAAC;QACH,gBAAgB,GAAG,cAAc,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,CAAA;IAC3D,CAAC;IAAC,MAAM,CAAC;QACP,gBAAgB,GAAG,IAAI,CAAA;IACzB,CAAC;IACD,MAAM,MAAM,GAAiB,EAAE,CAAA;IAC/B,MAAM,KAAK,GAAa,EAAE,CAAA;IAC1B,IAAI,KAAK,GAAG,CAAC,CAAA;IAEb,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,KAAK,IAAI,UAAU,CAAC,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,CAAA;IAC7E,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,CAAA;AACxD,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,WAAW,CAClB,KAAe,EACf,SAAiB,EACjB,gBAA+B,EAC/B,GAAY,EACZ,IAAgE,EAChE,KAAe;IAEf,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAA;IACxD,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,CAAC,EAAE,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAA;IACvD,IAAI,GAA4B,CAAA;IAChC,IAAI,CAAC;QACH,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAA4B,CAAA;IAC7E,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAA;QAC7B,OAAO,IAAI,CAAA;IACb,CAAC;IACD,MAAM,MAAM,GAAG,GAA+B,CAAA;IAE9C,IAAI,GAAG,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;QAClC,IAAI,CAAC,IAAI,EAAE,6EAA6E,EAAE,IAAI,CAAC,CAAA;QAC/F,IAAI,GAAG,EAAE,CAAC;YACR,mEAAmE;YACnE,sEAAsE;YACtE,MAAM,MAAM,GAAG;gBACb,GAAG,CAAC,OAAO,GAAG,CAAC,MAAM,KAAK,QAAQ,IAAI,GAAG,CAAC,MAAM,KAAK,IAAI;oBACvD,CAAC,CAAE,GAAG,CAAC,MAAkC;oBACzC,CAAC,CAAC,EAAE,CAAC;aACR,CAAA;YACD,MAAM,CAAC,YAAY,KAAK,GAAG,CAAC,WAAW,CAAA;YACvC,MAAM,QAAQ,GAA4B,EAAE,CAAA;YAC5C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC/C,IAAI,GAAG,KAAK,aAAa,EAAE,CAAC;oBAC1B,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS;wBAAE,QAAQ,CAAC,MAAM,GAAG,MAAM,CAAA;oBACtD,SAAQ;gBACV,CAAC;gBACD,QAAQ,CAAC,GAAG,CAAC,GAAG,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAA;YACnD,CAAC;YACD,aAAa,CAAC,QAAQ,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAA;YACjE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAClB,CAAC;IACH,CAAC;IAED,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAC7B,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC7B,IAAI,CACF,IAAI,EACJ,yFAAyF,CAC1F,CAAA;QACH,CAAC;aAAM,IACL,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC;YAC1B,GAAG,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC;YACvB,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,EAC7C,CAAC;YACD,IAAI,CAAC,IAAI,EAAE,2EAA2E,CAAC,CAAA;QACzF,CAAC;IACH,CAAC;IAED,IAAI,YAAY,GAAkB,IAAI,CAAA;IACtC,IAAI,CAAC;QACH,YAAY,GAAG,cAAc,CAAC,MAAM,CAAC,CAAA;IACvC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAA;IAC/B,CAAC;IACD,IACE,YAAY,KAAK,IAAI;QACrB,gBAAgB,KAAK,IAAI;QACzB,KAAK,CAAC,IAAI,KAAK,SAAS;QACxB,YAAY,KAAK,gBAAgB,EACjC,CAAC;QACD,IAAI,CACF,IAAI,EACJ,uBAAuB,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,oCAAoC,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC,2EAA2E,CACnM,CAAA;IACH,CAAC;IAED,OAAO,MAAM,CAAA;AACf,CAAC;AAED,SAAS,UAAU,CACjB,KAAe,EACf,SAAiB,EACjB,gBAA+B,EAC/B,GAAY,EACZ,MAAoB,EACpB,KAAe;IAEf,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAA;IAC1C,MAAM,UAAU,GAAG,SAAS,CAAC,KAAK,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAA;IAChD,MAAM,IAAI,GAAG,CAAC,IAAY,EAAE,OAAe,EAAE,OAAO,GAAG,KAAK,EAAE,EAAE,CAC9D,MAAM,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAA;IAE1D,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,CAAC,CAAA;IAChF,MAAM,MAAM,GAAG,MAAM,EAAE,MAAM,IAAI,MAAM,CAAA;IACvC,MAAM,SAAS,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,GAAG,MAAM,IAAI,CAAC,EAAE,CAAA;IAEjD,8EAA8E;IAC9E,MAAM,OAAO,GAAkB,EAAE,CAAA;IACjC,IAAI,KAAK,GAAG,CAAC,CAAA;IACb,KAAK,MAAM,CAAC,GAAG,EAAE,QAAQ,CAAC,IAAI;QAC5B,CAAC,WAAW,EAAE,KAAK,CAAC;QACpB,CAAC,WAAW,EAAE,IAAI,CAAC;KACX,EAAE,CAAC;QACX,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,CAAA;QAC/B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;YAAE,SAAQ;QAC/B,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,IAAI,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;YAC/D,IAAI,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;gBAAE,SAAQ;YACxC,MAAM,QAAQ,GAAG,SAAS,CAAC,UAAU,EAAE,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAA;YACvD,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;gBACtD,IAAI,CAAC,QAAQ,EAAE,oEAAoE,CAAC,CAAA;gBACpF,SAAQ;YACV,CAAC;YACD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,WAAW,CAAC,CAAA;YACpD,MAAM,IAAI,GAAG,SAAS,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAA;YAC7C,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC1B,IAAI,CAAC,IAAI,EAAE,sCAAsC,CAAC,CAAA;gBAClD,SAAQ;YACV,CAAC;YACD,KAAK,EAAE,CAAA;YACP,MAAM,IAAI,GAAG,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;YAC3C,IAAI,GAAG,GAAqB,IAAI,CAAA;YAChC,IAAI,CAAC;gBACH,GAAG,GAAG,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;YAC/B,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,CAAC,CAAC,KAAK,YAAY,gBAAgB,CAAC;oBAAE,MAAM,KAAK,CAAA;gBACrD,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAA;YACjC,CAAC;YACD,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAA;QACnF,CAAC;IACH,CAAC;IAED,0EAA0E;IAC1E,yEAAyE;IACzE,kDAAkD;IAClD,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAA;IAC7E,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAA;IACnD,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,IAAI,MAAM,CAAC,QAAQ,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;YAC/C,IAAI,CACF,MAAM,CAAC,IAAI,EACX,GAAG,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,mBAAmB,WAAW,0CAA0C,CACpG,CAAA;QACH,CAAC;IACH,CAAC;IAED,8EAA8E;IAC9E,0EAA0E;IAC1E,yEAAyE;IACzE,2DAA2D;IAC3D,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAA;IACnC,MAAM,aAAa,GAAG,IAAI,GAAG,EAAU,CAAA;IACvC,KAAK,MAAM,CAAC,GAAG,EAAE,YAAY,CAAC,IAAI;QAChC,CAAC,SAAS,EAAE,KAAK,CAAC;QAClB,CAAC,GAAG,SAAS,IAAI,iBAAiB,EAAE,EAAE,IAAI,CAAC;KACnC,EAAE,CAAC;QACX,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,CAAA;QAC/B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;YAAE,SAAQ;QAC/B,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,IAAI,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;YAC/D,IAAI,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;gBAAE,SAAQ;YACxC,IAAI,KAAK,CAAC,WAAW,EAAE,IAAI,CAAC,YAAY,IAAI,KAAK,CAAC,IAAI,KAAK,iBAAiB;gBAAE,SAAQ;YACtF,MAAM,IAAI,GAAG,SAAS,CAAC,UAAU,EAAE,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAA;YACnD,IAAI,KAAK,CAAC,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;gBACvD,IAAI,CAAC,IAAI,EAAE,wDAAwD,CAAC,CAAA;gBACpE,SAAQ;YACV,CAAC;YACD,KAAK,EAAE,CAAA;YACP,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;YACpC,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,CAAA;YACzD,IAAI,GAAG,CAAA;YACP,IAAI,CAAC;gBACH,GAAG,GAAG,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;YAC7B,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,CAAC,CAAC,KAAK,YAAY,gBAAgB,CAAC;oBAAE,MAAM,KAAK,CAAA;gBACrD,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAA;gBAC/B,SAAQ;YACV,CAAC;YACD,IAAI,YAAY,IAAI,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC5C,IAAI,CAAC,IAAI,EAAE,SAAS,IAAI,oBAAoB,SAAS,0CAA0C,CAAC,CAAA;YAClG,CAAC;YACD,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;YACnB,IAAI,CAAC,YAAY;gBAAE,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;YAC1C,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;gBACtB,IAAI,CAAC,IAAI,EAAE,IAAI,IAAI,mEAAmE,CAAC,CAAA;YACzF,CAAC;YACD,KAAK,MAAM,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI;gBACtB,CAAC,GAAG,CAAC,SAAS,EAAE,SAAS,CAAC;gBAC1B,CAAC,GAAG,CAAC,SAAS,EAAE,SAAS,CAAC;aAClB,EAAE,CAAC;gBACX,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC;oBAAE,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,2BAA2B,CAAC,CAAA;YAC1E,CAAC;YACD,KAAK,MAAM,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC;gBACrC,IAAI,CAAC,IAAI,EAAE,4BAA4B,GAAG,gDAAgD,CAAC,CAAA;YAC7F,CAAC;YACD,MAAM,SAAS,GAAG,aAAa,CAAC,GAAG,CAAC,CAAA;YACpC,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;gBACvB,IAAI,CAAC,IAAI,EAAE,wDAAwD,EAAE,IAAI,CAAC,CAAA;gBAC1E,IAAI,GAAG,EAAE,CAAC;oBACR,aAAa,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC,CAAA;oBAChD,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;gBAClB,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,8EAA8E;IAC9E,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAAA;QACpC,IAAI,CAAC,GAAG;YAAE,SAAQ;QAElB,KAAK,MAAM,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI;YACtB,CAAC,GAAG,CAAC,SAAS,EAAE,SAAS,CAAC;YAC1B,CAAC,GAAG,CAAC,SAAS,EAAE,SAAS,CAAC;SAClB,EAAE,CAAC;YACX,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC;gBAAE,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE,2BAA2B,CAAC,CAAA;QAC1E,CAAC;QACD,KAAK,MAAM,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC;YACrC,IAAI,CAAC,IAAI,EAAE,4BAA4B,GAAG,gDAAgD,CAAC,CAAA;QAC7F,CAAC;QACD,IAAI,MAAM,CAAC,QAAQ,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM,IAAI,GAAG,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;YAC1E,IAAI,CACF,IAAI,EACJ,sBAAsB,GAAG,CAAC,MAAM,wDAAwD,CACzF,CAAA;QACH,CAAC;QAED,uEAAuE;QACvE,+DAA+D;QAC/D,0EAA0E;QAC1E,mEAAmE;QACnE,IAAI,GAAG,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACzC,IAAI,CACF,IAAI,EACJ,SAAS,GAAG,CAAC,IAAI,yFAAyF,CAC3G,CAAA;QACH,CAAC;QAED,0EAA0E;QAC1E,4EAA4E;QAC5E,MAAM,MAAM,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;aACvC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,MAAM,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;aAC3C,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;QACxB,IAAI,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YACnC,IAAI,CAAC,IAAI,EAAE,GAAG,SAAS,CAAC,MAAM,CAAC,uBAAuB,EAAE,IAAI,CAAC,CAAA;QAC/D,CAAC;QACD,KAAK,MAAM,MAAM,IAAI,IAAI,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;YAC5C,IAAI,MAAM,KAAK,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC5C,IAAI,CAAC,IAAI,EAAE,yBAAyB,SAAS,CAAC,MAAM,CAAC,uBAAuB,EAAE,IAAI,CAAC,CAAA;YACrF,CAAC;QACH,CAAC;QAED,wEAAwE;QACxE,yEAAyE;QACzE,2EAA2E;QAC3E,mEAAmE;QACnE,EAAE;QACF,uEAAuE;QACvE,yEAAyE;QACzE,2EAA2E;QAC3E,MAAM,UAAU,GAAG,eAAe,CAAC;YACjC,GAAG,GAAG;YACN,SAAS,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC;SAC7D,CAAC,CAAA;QACF,IAAI,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;YACxD,IAAI,CAAC,IAAI,EAAE,8DAA8D,EAAE,IAAI,CAAC,CAAA;QAClF,CAAC;aAAM,IAAI,UAAU,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC;YACtC,IAAI,CAAC,IAAI,EAAE,wDAAwD,EAAE,IAAI,CAAC,CAAA;QAC5E,CAAC;QACD,MAAM,SAAS,GAAG,eAAe,CAAC,EAAE,GAAG,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC,CAAA;QAChE,IAAI,GAAG,IAAI,SAAS,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC;YACrC,aAAa,CAAC,MAAM,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAA;YACzC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAClB,CAAC;IACH,CAAC;IAED,8EAA8E;IAC9E,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAS,cAAc,CAAC,CAAA;IACxD,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,IAAI,EAAE,YAAY,CAAC,CAAA;QACrD,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAQ;QAC9B,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC;YACrC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC;gBAAE,SAAQ;YAC7D,KAAK,EAAE,CAAA;YACP,MAAM,IAAI,GAAG,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,YAAY,EAAE,KAAK,CAAC,CAAA;YAC1F,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,CAAA;YACnD,IAAI,MAAM,CAAA;YACV,IAAI,CAAC;gBACH,MAAM,GAAG,YAAY,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;YACnC,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,CAAC,CAAC,KAAK,YAAY,gBAAgB,CAAC;oBAAE,MAAM,KAAK,CAAA;gBACrD,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAA;gBAC/B,SAAQ;YACV,CAAC;YACD,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC;gBAAE,IAAI,CAAC,IAAI,EAAE,kCAAkC,CAAC,CAAA;YACvF,IAAI,WAAW,GAAG,KAAK,CAAA;YACvB,KAAK,MAAM,GAAG,IAAI,eAAe,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;gBAC9C,IAAI,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC;oBAAE,SAAQ;gBACvC,WAAW,GAAG,IAAI,CAAA;gBAClB,IAAI,CAAC,IAAI,EAAE,4BAA4B,GAAG,GAAG,CAAC,CAAA;YAChD,CAAC;YACD,wEAAwE;YACxE,sEAAsE;YACtE,MAAM,SAAS,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAA;YAC1C,IAAI,SAAS,KAAK,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;gBACvC,IAAI,CAAC,IAAI,EAAE,wDAAwD,EAAE,IAAI,CAAC,CAAA;gBAC1E,IAAI,GAAG,EAAE,CAAC;oBACR,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,SAAS,CAAC,CAAA;oBAC1C,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;gBAClB,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAA;AACd,CAAC"}
|
|
1
|
+
{"version":3,"file":"check.js","sourceRoot":"","sources":["../src/check.ts"],"names":[],"mappings":"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"}
|
package/dist/check.test.js
CHANGED
|
@@ -24,45 +24,71 @@ test("a board the CLI wrote is clean", () => {
|
|
|
24
24
|
store.createGoal({ title: "Ship it", description: "the why" });
|
|
25
25
|
const a = store.create({ title: "First", description: "with a body", goal: "ship-it" });
|
|
26
26
|
const b = store.create({ title: "Second", status: "backlog", tags: ["x"] });
|
|
27
|
-
store.link(b.
|
|
28
|
-
store.addComment(a.
|
|
29
|
-
store.update(a.
|
|
30
|
-
store.archive(a.
|
|
27
|
+
store.link(b.key, "blocked_by", a.key);
|
|
28
|
+
store.addComment(a.key, "hello", "claude");
|
|
29
|
+
store.update(a.key, { status: "done" });
|
|
30
|
+
store.archive(a.key);
|
|
31
31
|
const result = checkBoards(root, false);
|
|
32
32
|
assert.deepEqual(result.issues, []);
|
|
33
33
|
assert.equal(result.boards, 1);
|
|
34
34
|
assert.equal(result.files, 4); // two tickets + one comment + one goal
|
|
35
35
|
});
|
|
36
|
+
test("ask files are linted like comments; the retired flag reads as an unknown key", () => {
|
|
37
|
+
const root = tempRoot();
|
|
38
|
+
const store = initProject(root, { name: "owed", prefix: "OWE" });
|
|
39
|
+
const t = store.create({ title: "Owes things", status: "in_progress" });
|
|
40
|
+
store.addAsk(t.key, "Mint the token", "claude");
|
|
41
|
+
assert.deepEqual(checkBoards(root, false).issues, [], "a CLI-written ask is clean");
|
|
42
|
+
const asksDir = join(root, ".task", "tickets", t.key, "asks");
|
|
43
|
+
// Hand-edit shapes: an ask that says nothing, a resolution that isn't a
|
|
44
|
+
// timestamp, a key nothing reads, and mere drift (unquoted author).
|
|
45
|
+
writeFileSync(join(asksDir, "z-empty.md"), '---\nauthor: "x"\ncreated: 2026-08-27T00:00:00.000Z\n---\n\n\n');
|
|
46
|
+
writeFileSync(join(asksDir, "z-bad.md"), '---\nauthor: "x"\ncreated: 2026-08-27T00:00:00.000Z\nresolved: yesterday-ish\nurgency: high\n---\n\nDo the thing\n');
|
|
47
|
+
const found = checkBoards(root, false);
|
|
48
|
+
const messages = found.issues.map((issue) => issue.message);
|
|
49
|
+
assert.ok(messages.some((m) => /empty ask/.test(m)), "empty ask reported");
|
|
50
|
+
assert.ok(messages.some((m) => /resolved is not a valid timestamp/.test(m)), "bad resolution reported");
|
|
51
|
+
assert.ok(messages.some((m) => /unknown frontmatter key "urgency"/.test(m)), "unknown key reported");
|
|
52
|
+
// The retired pre-0.8 boolean isn't a field anymore — a file still carrying
|
|
53
|
+
// it (deep history, an ancient branch) reads as an unknown key: flagged,
|
|
54
|
+
// preserved through rewrites, never interpreted.
|
|
55
|
+
const ticketPath = join(root, ".task", "tickets", t.key, "ticket.md");
|
|
56
|
+
writeFileSync(ticketPath, readFileSync(ticketPath, "utf8").replace("status: in_progress", "status: in_progress\nneeds_human: true"));
|
|
57
|
+
const flagged = checkBoards(root, true);
|
|
58
|
+
const unknown = flagged.issues.find((issue) => /unknown frontmatter key "needs_human"/.test(issue.message));
|
|
59
|
+
assert.ok(unknown, "retired key flagged as unknown");
|
|
60
|
+
assert.match(readFileSync(ticketPath, "utf8"), /needs_human: true/);
|
|
61
|
+
});
|
|
36
62
|
test("finds what merges and hand-edits leave behind, and --fix repairs the mechanical part", () => {
|
|
37
63
|
const root = tempRoot();
|
|
38
64
|
const store = initProject(root, { name: "rough", prefix: "RGH" });
|
|
39
65
|
const a = store.create({ title: "Kept", status: "todo" });
|
|
40
66
|
const b = store.create({ title: "Points at a ghost", status: "todo" });
|
|
41
|
-
store.create({ title: "Broken later", status: "todo" });
|
|
67
|
+
const c = store.create({ title: "Broken later", status: "todo" });
|
|
42
68
|
// A dangling reference: link b to a ticket, then lose the ticket the way a
|
|
43
69
|
// merge would — the directory vanishes without the store's delete cascade.
|
|
44
|
-
store.link(b.
|
|
45
|
-
const ticketPath = (
|
|
46
|
-
const bText = readFileSync(ticketPath(b.
|
|
47
|
-
writeFileSync(ticketPath(b.
|
|
70
|
+
store.link(b.key, "blocked_by", a.key);
|
|
71
|
+
const ticketPath = (key) => join(root, ".task", "tickets", key, "ticket.md");
|
|
72
|
+
const bText = readFileSync(ticketPath(b.key), "utf8");
|
|
73
|
+
writeFileSync(ticketPath(b.key), bText.replace(`blocked_by: ["${a.key}"]`, `blocked_by: ["${a.key}", "zz9zz", "zz9zz"]`));
|
|
48
74
|
// A hand-edit that still parses but isn't canonical (bare goal string).
|
|
49
75
|
store.createGoal({ title: "Launch" });
|
|
50
|
-
const cText = readFileSync(ticketPath(
|
|
51
|
-
writeFileSync(ticketPath(
|
|
52
|
-
// A file that doesn't parse at all.
|
|
53
|
-
mkdirSync(join(root, ".task", "tickets", "
|
|
54
|
-
writeFileSync(ticketPath(
|
|
76
|
+
const cText = readFileSync(ticketPath(c.key), "utf8");
|
|
77
|
+
writeFileSync(ticketPath(c.key), cText.replace("status: todo", "status: todo\ngoal: launch"));
|
|
78
|
+
// A file that doesn't parse at all, in a well-formed key directory.
|
|
79
|
+
mkdirSync(join(root, ".task", "tickets", "zzz9x"));
|
|
80
|
+
writeFileSync(ticketPath("zzz9x"), "---\nstatus: todoo\nposition: 0\ncreated: x\nupdated: x\n---\n\n# Bad status\n");
|
|
55
81
|
const found = checkBoards(root, false);
|
|
56
82
|
const messages = found.issues.map((issue) => issue.message);
|
|
57
|
-
assert.ok(messages.some((m) => /RGH-
|
|
83
|
+
assert.ok(messages.some((m) => /RGH-zz9zz, which doesn't exist/.test(m)), "dangling ref reported");
|
|
58
84
|
assert.ok(messages.some((m) => /not in canonical form/.test(m)), "drift reported");
|
|
59
85
|
assert.ok(messages.some((m) => /invalid status "todoo"/.test(m)), "parse error reported");
|
|
60
86
|
assert.ok(messages.some((m) => /not a valid timestamp/.test(m)) === false, "unparseable file isn't double-reported");
|
|
61
87
|
const fixed = checkBoards(root, true);
|
|
62
88
|
assert.ok(fixed.fixed.length >= 2, "fix rewrote the repairable files");
|
|
63
89
|
// The dangling ref is pruned, the real one kept; the drift is normalized.
|
|
64
|
-
assert.
|
|
65
|
-
assert.match(readFileSync(ticketPath(
|
|
90
|
+
assert.ok(readFileSync(ticketPath(b.key), "utf8").includes(`blocked_by: ["${a.key}"]\n`));
|
|
91
|
+
assert.match(readFileSync(ticketPath(c.key), "utf8"), /goal: "launch"/);
|
|
66
92
|
// What remains is exactly what needs a human: the unparseable file.
|
|
67
93
|
const after = checkBoards(root, false);
|
|
68
94
|
assert.deepEqual(after.issues.filter((issue) => issue.fixable), []);
|
|
@@ -73,11 +99,11 @@ test("merge artifacts across the archive are reported, never auto-fixed", () =>
|
|
|
73
99
|
const root = tempRoot();
|
|
74
100
|
const store = initProject(root, { name: "dup", prefix: "DUP" });
|
|
75
101
|
const t = store.create({ title: "Archived on one branch" });
|
|
76
|
-
store.update(t.
|
|
77
|
-
store.archive(t.
|
|
102
|
+
store.update(t.key, { status: "done" });
|
|
103
|
+
store.archive(t.key);
|
|
78
104
|
// The other branch kept editing it — the merge keeps both directories.
|
|
79
|
-
mkdirSync(join(root, ".task", "tickets",
|
|
80
|
-
writeFileSync(join(root, ".task", "tickets",
|
|
105
|
+
mkdirSync(join(root, ".task", "tickets", t.key), { recursive: true });
|
|
106
|
+
writeFileSync(join(root, ".task", "tickets", t.key, "ticket.md"), readFileSync(join(root, ".task", "archive", t.key, "ticket.md")));
|
|
81
107
|
const result = checkBoards(root, true);
|
|
82
108
|
assert.ok(result.issues.some((issue) => /also exists in tickets\//.test(issue.message)));
|
|
83
109
|
assert.deepEqual(result.fixed, []);
|
|
@@ -86,8 +112,8 @@ test("a ticket parked in the archive while still open is flagged", () => {
|
|
|
86
112
|
const root = tempRoot();
|
|
87
113
|
const store = initProject(root, { name: "arc", prefix: "ARC" });
|
|
88
114
|
const t = store.create({ title: "Half archived", status: "todo" });
|
|
89
|
-
renameSync(join(root, ".task", "tickets",
|
|
90
|
-
join(root, ".task", "archive",
|
|
115
|
+
renameSync(join(root, ".task", "tickets", t.key), (mkdirSync(join(root, ".task", "archive"), { recursive: true }),
|
|
116
|
+
join(root, ".task", "archive", t.key)));
|
|
91
117
|
const result = checkBoards(root, false);
|
|
92
118
|
assert.ok(result.issues.some((issue) => /archived but still todo/.test(issue.message)));
|
|
93
119
|
});
|
|
@@ -95,12 +121,12 @@ test("unknown frontmatter keys are reported — and survive a rewrite round-trip
|
|
|
95
121
|
const root = tempRoot();
|
|
96
122
|
const store = initProject(root, { name: "extra", prefix: "EXT" });
|
|
97
123
|
const t = store.create({ title: "Carries a custom field", status: "todo" });
|
|
98
|
-
const path = join(root, ".task", "tickets",
|
|
124
|
+
const path = join(root, ".task", "tickets", t.key, "ticket.md");
|
|
99
125
|
writeFileSync(path, readFileSync(path, "utf8").replace("status: todo", 'status: todo\nowner: "nick"'));
|
|
100
126
|
const result = checkBoards(root, false);
|
|
101
127
|
assert.ok(result.issues.some((issue) => /unknown frontmatter key "owner"/.test(issue.message)));
|
|
102
128
|
// The sharp edge this fixed: an ordinary update used to drop the key.
|
|
103
|
-
store.update(t.
|
|
129
|
+
store.update(t.key, { title: "Renamed" });
|
|
104
130
|
const text = readFileSync(path, "utf8");
|
|
105
131
|
assert.match(text, /owner: "nick"/);
|
|
106
132
|
assert.match(text, /# Renamed/);
|
|
@@ -112,23 +138,23 @@ test("unknown frontmatter keys are reported — and survive a rewrite round-trip
|
|
|
112
138
|
'unknown frontmatter key "owner" — preserved on rewrite, but nothing reads it',
|
|
113
139
|
]);
|
|
114
140
|
});
|
|
115
|
-
test("the pre-0.8 milestone key is
|
|
141
|
+
test("the pre-0.8 milestone key is refused by name — no migration machinery", () => {
|
|
116
142
|
const root = tempRoot();
|
|
117
143
|
const store = initProject(root, { name: "old", prefix: "OLD" });
|
|
118
144
|
const t = store.create({ title: "From an old board", status: "todo" });
|
|
119
|
-
const path = join(root, ".task", "tickets",
|
|
145
|
+
const path = join(root, ".task", "tickets", t.key, "ticket.md");
|
|
120
146
|
writeFileSync(path, readFileSync(path, "utf8").replace("status: todo", 'status: todo\nmilestone: "launch"'));
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
assert.ok(
|
|
147
|
+
// The strict parse refuses the retired spelling with the rename in the
|
|
148
|
+
// error; check surfaces exactly that, unfixable, and --fix leaves the file
|
|
149
|
+
// alone — renaming the key is the human's one edit.
|
|
150
|
+
const found = checkBoards(root, true);
|
|
151
|
+
const refusal = found.issues.find((issue) => /`milestone:` is the pre-0\.8 spelling.*rename the key to `goal:`/.test(issue.message));
|
|
152
|
+
assert.ok(refusal, "retired spelling refused by name");
|
|
153
|
+
assert.equal(refusal.fixable, false);
|
|
154
|
+
assert.match(readFileSync(path, "utf8"), /milestone: "launch"/);
|
|
155
|
+
writeFileSync(path, readFileSync(path, "utf8").replace('milestone: "launch"', 'goal: "launch"'));
|
|
127
156
|
store.createGoal({ title: "Launch" });
|
|
128
157
|
checkBoards(root, true);
|
|
129
|
-
const text = readFileSync(path, "utf8");
|
|
130
|
-
assert.match(text, /goal: "launch"/);
|
|
131
|
-
assert.doesNotMatch(text, /milestone/);
|
|
132
158
|
assert.deepEqual(checkBoards(root, false).issues, []);
|
|
133
159
|
});
|
|
134
160
|
test("goal files are linted, and drift in them is fixable", () => {
|
|
@@ -150,14 +176,14 @@ test("comment files are linted too", () => {
|
|
|
150
176
|
const root = tempRoot();
|
|
151
177
|
const store = initProject(root, { name: "com", prefix: "COM" });
|
|
152
178
|
const t = store.create({ title: "Talked about" });
|
|
153
|
-
store.addComment(t.
|
|
154
|
-
const dir = join(root, ".task", "tickets",
|
|
179
|
+
store.addComment(t.key, "fine", "claude");
|
|
180
|
+
const dir = join(root, ".task", "tickets", t.key, "comments");
|
|
155
181
|
// A hand-dropped comment: parseable, wrong created, non-canonical spacing.
|
|
156
182
|
writeFileSync(join(dir, "2026-08-15T170000-other.md"), '---\nauthor: "other"\ncreated: not-a-date\n---\nbody\n');
|
|
157
183
|
const result = checkBoards(root, false);
|
|
158
184
|
assert.ok(result.issues.some((issue) => /created is not a valid timestamp/.test(issue.message)));
|
|
159
185
|
});
|
|
160
|
-
test("config lints:
|
|
186
|
+
test("config lints: retired claimPrefix refuses, boards is root-only, prefixes must agree", () => {
|
|
161
187
|
const root = tempRoot();
|
|
162
188
|
initProject(root, { name: "cfg", prefix: "CFG" });
|
|
163
189
|
const rootConfig = join(root, ".task", "config.json");
|
|
@@ -174,25 +200,20 @@ test("config lints: legacy claimPrefix migrates, boards is root-only, prefixes m
|
|
|
174
200
|
subRaw.boards = ["SUB"];
|
|
175
201
|
subRaw.claims = { branchPrefix: "task/claim/" };
|
|
176
202
|
writeFileSync(subConfig, `${JSON.stringify(subRaw, null, 2)}\n`);
|
|
177
|
-
|
|
203
|
+
// The retired key with no claims.branchPrefix beside it: claimNamespace
|
|
204
|
+
// refuses by name, check surfaces that refusal, and --fix touches nothing —
|
|
205
|
+
// renaming the key is the human's one edit. The root's namespace being
|
|
206
|
+
// unreadable also means the sub-board mismatch lint has no reference to
|
|
207
|
+
// compare against; the root-only boards lint still fires.
|
|
208
|
+
const found = checkBoards(root, true);
|
|
178
209
|
const messages = found.issues.map((issue) => issue.message);
|
|
179
|
-
assert.ok(messages.some((m) => /`claimPrefix` is
|
|
210
|
+
assert.ok(messages.some((m) => /`claimPrefix` in \.task\/config\.json is the pre-0\.8 spelling/.test(m)));
|
|
180
211
|
assert.ok(messages.some((m) => /"boards" is root-only/.test(m)));
|
|
181
|
-
assert.ok(
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
assert.ok(fixed.fixed.includes(".task/config.json"));
|
|
185
|
-
const migrated = JSON.parse(readFileSync(rootConfig, "utf8"));
|
|
186
|
-
assert.equal(migrated.claimPrefix, undefined);
|
|
187
|
-
assert.equal(migrated.claims?.branchPrefix, "claude/task/");
|
|
188
|
-
assert.deepEqual(migrated.boards, ["CFG", "SUB"]);
|
|
189
|
-
assert.equal(migrated.prefix, "CFG");
|
|
190
|
-
const remaining = checkBoards(root, false).issues.map((issue) => issue.message);
|
|
191
|
-
assert.ok(!remaining.some((m) => /`claimPrefix` is now/.test(m)), "nag gone after migration");
|
|
192
|
-
assert.ok(remaining.some((m) => /"boards" is root-only/.test(m)), "root-only lint stays");
|
|
193
|
-
assert.ok(remaining.some((m) => /disagrees with the root board's/.test(m)), "mismatch stays");
|
|
212
|
+
assert.ok(found.issues.every((issue) => !issue.fixable || !/claimPrefix/.test(issue.message)));
|
|
213
|
+
const untouched = JSON.parse(readFileSync(rootConfig, "utf8"));
|
|
214
|
+
assert.equal(untouched.claimPrefix, "claude/task/");
|
|
194
215
|
});
|
|
195
|
-
test("
|
|
216
|
+
test("a stray claimPrefix beside claims.branchPrefix is inert and flagged", () => {
|
|
196
217
|
const root = tempRoot();
|
|
197
218
|
initProject(root, { name: "dup", prefix: "DUP" });
|
|
198
219
|
const configPath = join(root, ".task", "config.json");
|
|
@@ -200,10 +221,28 @@ test("an existing claims.branchPrefix wins over the legacy key on migration", ()
|
|
|
200
221
|
raw.claimPrefix = "old/ns/";
|
|
201
222
|
raw.claims = { branchPrefix: "new/ns/", maxOpenCount: 2 };
|
|
202
223
|
writeFileSync(configPath, `${JSON.stringify(raw, null, 2)}\n`);
|
|
203
|
-
checkBoards(root,
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
224
|
+
const messages = checkBoards(root, false).issues.map((issue) => issue.message);
|
|
225
|
+
assert.ok(messages.some((m) => /`claims\.branchPrefix` wins; delete the leftover key/.test(m)));
|
|
226
|
+
});
|
|
227
|
+
test("numeric ticket dirs are called out as pre-TAS-42 — junk entries separately", () => {
|
|
228
|
+
const root = tempRoot();
|
|
229
|
+
const store = initProject(root, { name: "mig", prefix: "MIG" });
|
|
230
|
+
store.create({ title: "A modern ticket", status: "todo" });
|
|
231
|
+
// A pre-migration ticket, imported by merging a branch cut before the id
|
|
232
|
+
// cutover: numeric directory, numeric blocked_by.
|
|
233
|
+
mkdirSync(join(root, ".task", "tickets", "42"), { recursive: true });
|
|
234
|
+
writeFileSync(join(root, ".task", "tickets", "42", "ticket.md"), "---\nstatus: todo\nposition: 0\ncreated: 2026-08-15T16:00:33.758Z\nupdated: 2026-08-15T16:00:33.758Z\n---\n\n# Old-format ticket\n");
|
|
235
|
+
// And something that was never a ticket directory at all.
|
|
236
|
+
mkdirSync(join(root, ".task", "tickets", "Not A Key"), { recursive: true });
|
|
237
|
+
const messages = checkBoards(root, false).issues.map((issue) => issue.message);
|
|
238
|
+
assert.ok(messages.some((m) => /numeric ticket directory — the pre-TAS-42 sequential-id format/.test(m)), "pre-migration dir named with the migration fix");
|
|
239
|
+
assert.ok(messages.some((m) => /ticket directories are named by their key/.test(m)), "junk entry reported as unexpected");
|
|
240
|
+
// A modern file whose blocked_by still carries numbers is refused by the
|
|
241
|
+
// strict parser with the migration named — surfaced through check.
|
|
242
|
+
const modern = store.create({ title: "Bad link format", status: "todo" });
|
|
243
|
+
const path = join(root, ".task", "tickets", modern.key, "ticket.md");
|
|
244
|
+
writeFileSync(path, readFileSync(path, "utf8").replace("status: todo", "status: todo\nblocked_by: [7]"));
|
|
245
|
+
const after = checkBoards(root, false).issues.map((issue) => issue.message);
|
|
246
|
+
assert.ok(after.some((m) => /pre-TAS-42 id format, which is no longer read/.test(m)));
|
|
208
247
|
});
|
|
209
248
|
//# sourceMappingURL=check.test.js.map
|