taskin 4.0.0 → 4.1.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/dashboard-dist/assets/index-D1nMsp_D.js +36 -0
- package/dashboard-dist/assets/index-mlyY0OL7.css +1 -0
- package/dashboard-dist/index.html +2 -2
- package/dist/index.js +397 -154
- package/package.json +7 -7
- package/dashboard-dist/assets/index-BFJ7BiAJ.css +0 -1
- package/dashboard-dist/assets/index-iRSwFmq6.js +0 -36
package/dist/index.js
CHANGED
|
@@ -15,12 +15,12 @@ var __export = (target, all) => {
|
|
|
15
15
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
16
16
|
};
|
|
17
17
|
|
|
18
|
-
// ../../node_modules/.pnpm/tsup@8.5.1_postcss@8.5.
|
|
18
|
+
// ../../node_modules/.pnpm/tsup@8.5.1_postcss@8.5.26_supports-color@7.2.0_tsx@4.23.13_typescript@6.0.3_yaml@2.9.0/node_modules/tsup/assets/esm_shims.js
|
|
19
19
|
import path from "path";
|
|
20
20
|
import { fileURLToPath } from "url";
|
|
21
21
|
var getFilename, getDirname, __dirname;
|
|
22
22
|
var init_esm_shims = __esm({
|
|
23
|
-
"../../node_modules/.pnpm/tsup@8.5.1_postcss@8.5.
|
|
23
|
+
"../../node_modules/.pnpm/tsup@8.5.1_postcss@8.5.26_supports-color@7.2.0_tsx@4.23.13_typescript@6.0.3_yaml@2.9.0/node_modules/tsup/assets/esm_shims.js"() {
|
|
24
24
|
"use strict";
|
|
25
25
|
getFilename = () => fileURLToPath(import.meta.url);
|
|
26
26
|
getDirname = () => path.dirname(getFilename());
|
|
@@ -449,6 +449,230 @@ var init_inline_metadata = __esm({
|
|
|
449
449
|
}
|
|
450
450
|
});
|
|
451
451
|
|
|
452
|
+
// ../file-system-task-provider/src/metadata-style/metadata-block.ts
|
|
453
|
+
function headerEndIndex(lines) {
|
|
454
|
+
const index = lines.findIndex((line) => SECTION_HEADING.test(line));
|
|
455
|
+
return index === -1 ? lines.length : index;
|
|
456
|
+
}
|
|
457
|
+
function readMetadataBlock(content) {
|
|
458
|
+
const lines = splitLines(content);
|
|
459
|
+
const headerEnd = headerEndIndex(lines);
|
|
460
|
+
let start = -1;
|
|
461
|
+
for (let index = 0; index < headerEnd; index++) {
|
|
462
|
+
const line = lines[index] ?? "";
|
|
463
|
+
if (isHeading(line) || line.trim() === "") continue;
|
|
464
|
+
if (METADATA_LINE.test(line)) {
|
|
465
|
+
start = index;
|
|
466
|
+
}
|
|
467
|
+
break;
|
|
468
|
+
}
|
|
469
|
+
if (start === -1) return void 0;
|
|
470
|
+
let end = start;
|
|
471
|
+
while (end < headerEnd) {
|
|
472
|
+
const line = lines[end] ?? "";
|
|
473
|
+
if (isHeading(line) || !METADATA_LINE.test(line)) break;
|
|
474
|
+
end++;
|
|
475
|
+
}
|
|
476
|
+
const blockLines = lines.slice(start, end);
|
|
477
|
+
const fields = [];
|
|
478
|
+
for (const line of blockLines) {
|
|
479
|
+
const match = line.match(METADATA_LINE);
|
|
480
|
+
if (!match?.[1]) continue;
|
|
481
|
+
fields.push({ label: match[1], value: match[2] ?? "" });
|
|
482
|
+
}
|
|
483
|
+
return { fields, lines: blockLines, start, end };
|
|
484
|
+
}
|
|
485
|
+
function replaceMetadataBlock(content, newLines) {
|
|
486
|
+
const lines = splitLines(content);
|
|
487
|
+
const block = readMetadataBlock(content);
|
|
488
|
+
if (block) {
|
|
489
|
+
lines.splice(block.start, block.end - block.start, ...newLines);
|
|
490
|
+
return lines.join("\n");
|
|
491
|
+
}
|
|
492
|
+
if (newLines.length === 0) return content;
|
|
493
|
+
const titleIndex = lines.findIndex((line) => line.startsWith("# "));
|
|
494
|
+
if (titleIndex === -1) {
|
|
495
|
+
return [...newLines, "", ...lines].join("\n");
|
|
496
|
+
}
|
|
497
|
+
lines.splice(titleIndex + 1, 0, "", ...newLines);
|
|
498
|
+
return lines.join("\n");
|
|
499
|
+
}
|
|
500
|
+
function removeMetadataBlock(content) {
|
|
501
|
+
const block = readMetadataBlock(content);
|
|
502
|
+
if (!block) return content;
|
|
503
|
+
const lines = splitLines(content);
|
|
504
|
+
lines.splice(block.start, block.end - block.start);
|
|
505
|
+
return lines.join("\n").replace(/\n{3,}/g, "\n\n");
|
|
506
|
+
}
|
|
507
|
+
var METADATA_LINE, SECTION_HEADING, isHeading, splitLines, sameLabel;
|
|
508
|
+
var init_metadata_block = __esm({
|
|
509
|
+
"../file-system-task-provider/src/metadata-style/metadata-block.ts"() {
|
|
510
|
+
"use strict";
|
|
511
|
+
init_esm_shims();
|
|
512
|
+
METADATA_LINE = /^(?:-[ \t]+)?([^:\n]{1,40}?)[ \t]*:[ \t]*(.*?)[ \t]*\\?[ \t]*$/;
|
|
513
|
+
SECTION_HEADING = /^#{2,}\s/;
|
|
514
|
+
isHeading = (line) => line.startsWith("#");
|
|
515
|
+
splitLines = (content) => content.split(/\r?\n/);
|
|
516
|
+
sameLabel = (a, b) => a.toLowerCase() === b.toLowerCase();
|
|
517
|
+
}
|
|
518
|
+
});
|
|
519
|
+
|
|
520
|
+
// ../file-system-task-provider/src/metadata-style/metadata-style.base.ts
|
|
521
|
+
function defineMetadataStyle(definition) {
|
|
522
|
+
const format = (fields) => definition.formatLines(fields).join("\n");
|
|
523
|
+
return {
|
|
524
|
+
id: definition.id,
|
|
525
|
+
matches: definition.matches,
|
|
526
|
+
format,
|
|
527
|
+
read(content, label) {
|
|
528
|
+
const block = readMetadataBlock(content);
|
|
529
|
+
return block?.fields.find((field) => sameLabel(field.label, label))?.value;
|
|
530
|
+
},
|
|
531
|
+
write(content, label, value) {
|
|
532
|
+
const block = readMetadataBlock(content);
|
|
533
|
+
const fields = [...block?.fields ?? []];
|
|
534
|
+
const index = fields.findIndex((field) => sameLabel(field.label, label));
|
|
535
|
+
if (value === void 0) {
|
|
536
|
+
if (index === -1) return content;
|
|
537
|
+
fields.splice(index, 1);
|
|
538
|
+
return fields.length === 0 ? removeMetadataBlock(content) : replaceMetadataBlock(content, format(fields).split("\n"));
|
|
539
|
+
}
|
|
540
|
+
if (index === -1) {
|
|
541
|
+
fields.push({ label, value });
|
|
542
|
+
} else {
|
|
543
|
+
fields[index] = { label: fields[index]?.label ?? label, value };
|
|
544
|
+
}
|
|
545
|
+
return replaceMetadataBlock(content, format(fields).split("\n"));
|
|
546
|
+
}
|
|
547
|
+
};
|
|
548
|
+
}
|
|
549
|
+
var init_metadata_style_base = __esm({
|
|
550
|
+
"../file-system-task-provider/src/metadata-style/metadata-style.base.ts"() {
|
|
551
|
+
"use strict";
|
|
552
|
+
init_esm_shims();
|
|
553
|
+
init_metadata_block();
|
|
554
|
+
}
|
|
555
|
+
});
|
|
556
|
+
|
|
557
|
+
// ../file-system-task-provider/src/metadata-style/metadata-style.hard-break.ts
|
|
558
|
+
var hardBreakMetadataStyle;
|
|
559
|
+
var init_metadata_style_hard_break = __esm({
|
|
560
|
+
"../file-system-task-provider/src/metadata-style/metadata-style.hard-break.ts"() {
|
|
561
|
+
"use strict";
|
|
562
|
+
init_esm_shims();
|
|
563
|
+
init_inline_metadata();
|
|
564
|
+
init_metadata_style_base();
|
|
565
|
+
hardBreakMetadataStyle = defineMetadataStyle({
|
|
566
|
+
id: "hard-break",
|
|
567
|
+
// Uma linha com a barra basta: nenhum dos outros dois estilos a produz.
|
|
568
|
+
matches: (blockLines) => blockLines.some((line) => line.trimEnd().endsWith(HARD_BREAK)),
|
|
569
|
+
formatLines: (fields) => fields.map((field, index) => {
|
|
570
|
+
const isLast = index === fields.length - 1;
|
|
571
|
+
return `${field.label}: ${field.value}${isLast ? "" : HARD_BREAK}`;
|
|
572
|
+
})
|
|
573
|
+
});
|
|
574
|
+
}
|
|
575
|
+
});
|
|
576
|
+
|
|
577
|
+
// ../file-system-task-provider/src/metadata-style/metadata-style.list.ts
|
|
578
|
+
var LIST_MARKER, listMetadataStyle;
|
|
579
|
+
var init_metadata_style_list = __esm({
|
|
580
|
+
"../file-system-task-provider/src/metadata-style/metadata-style.list.ts"() {
|
|
581
|
+
"use strict";
|
|
582
|
+
init_esm_shims();
|
|
583
|
+
init_metadata_style_base();
|
|
584
|
+
LIST_MARKER = "- ";
|
|
585
|
+
listMetadataStyle = defineMetadataStyle({
|
|
586
|
+
id: "list",
|
|
587
|
+
// Um bloco so esta neste estilo se **todas** as linhas forem itens: uma so
|
|
588
|
+
// com `- ` no meio de linhas soltas e um arquivo misto, nao um bloco `list`.
|
|
589
|
+
matches: (blockLines) => blockLines.length > 0 && blockLines.every((line) => line.trimStart().startsWith(LIST_MARKER)),
|
|
590
|
+
formatLines: (fields) => fields.map((field) => `${LIST_MARKER}${field.label}: ${field.value}`)
|
|
591
|
+
});
|
|
592
|
+
}
|
|
593
|
+
});
|
|
594
|
+
|
|
595
|
+
// ../file-system-task-provider/src/metadata-style/metadata-style.plain.ts
|
|
596
|
+
var plainMetadataStyle;
|
|
597
|
+
var init_metadata_style_plain = __esm({
|
|
598
|
+
"../file-system-task-provider/src/metadata-style/metadata-style.plain.ts"() {
|
|
599
|
+
"use strict";
|
|
600
|
+
init_esm_shims();
|
|
601
|
+
init_metadata_style_base();
|
|
602
|
+
plainMetadataStyle = defineMetadataStyle({
|
|
603
|
+
id: "plain",
|
|
604
|
+
matches: () => true,
|
|
605
|
+
formatLines: (fields) => fields.map((field) => `${field.label}: ${field.value}`)
|
|
606
|
+
});
|
|
607
|
+
}
|
|
608
|
+
});
|
|
609
|
+
|
|
610
|
+
// ../file-system-task-provider/src/metadata-style/metadata-style.ts
|
|
611
|
+
function isMetadataStyleId(value) {
|
|
612
|
+
return typeof value === "string" && METADATA_STYLE_IDS.includes(value);
|
|
613
|
+
}
|
|
614
|
+
function getMetadataStyle(id) {
|
|
615
|
+
return METADATA_STYLES[id];
|
|
616
|
+
}
|
|
617
|
+
function detectMetadataStyle(content) {
|
|
618
|
+
const block = readMetadataBlock(content);
|
|
619
|
+
if (!block || block.lines.length === 0) return void 0;
|
|
620
|
+
return DETECTION_ORDER.find((style) => style.matches(block.lines));
|
|
621
|
+
}
|
|
622
|
+
function resolveMetadataStyle(content, fallback = DEFAULT_METADATA_STYLE_ID) {
|
|
623
|
+
return detectMetadataStyle(content) ?? getMetadataStyle(fallback);
|
|
624
|
+
}
|
|
625
|
+
function readMetadataField(content, ...labels) {
|
|
626
|
+
const block = readMetadataBlock(content);
|
|
627
|
+
if (!block) return void 0;
|
|
628
|
+
for (const label of labels) {
|
|
629
|
+
const field = block.fields.find((candidate) => sameLabel(candidate.label, label));
|
|
630
|
+
if (field) return field.value;
|
|
631
|
+
}
|
|
632
|
+
return void 0;
|
|
633
|
+
}
|
|
634
|
+
function writeMetadataField(content, label, value, fallback = DEFAULT_METADATA_STYLE_ID) {
|
|
635
|
+
return resolveMetadataStyle(content, fallback).write(content, label, value);
|
|
636
|
+
}
|
|
637
|
+
function convertMetadataStyle(content, target) {
|
|
638
|
+
const block = readMetadataBlock(content);
|
|
639
|
+
if (!block || block.fields.length === 0) return content;
|
|
640
|
+
const lines = getMetadataStyle(target).format(block.fields).split("\n");
|
|
641
|
+
if (lines.join("\n") === block.lines.join("\n")) return content;
|
|
642
|
+
return replaceMetadataBlock(content, lines);
|
|
643
|
+
}
|
|
644
|
+
var DEFAULT_METADATA_STYLE_ID, DETECTION_ORDER, METADATA_STYLES, METADATA_STYLE_IDS;
|
|
645
|
+
var init_metadata_style = __esm({
|
|
646
|
+
"../file-system-task-provider/src/metadata-style/metadata-style.ts"() {
|
|
647
|
+
"use strict";
|
|
648
|
+
init_esm_shims();
|
|
649
|
+
init_metadata_block();
|
|
650
|
+
init_metadata_style_hard_break();
|
|
651
|
+
init_metadata_style_list();
|
|
652
|
+
init_metadata_style_plain();
|
|
653
|
+
DEFAULT_METADATA_STYLE_ID = "list";
|
|
654
|
+
DETECTION_ORDER = [hardBreakMetadataStyle, listMetadataStyle, plainMetadataStyle];
|
|
655
|
+
METADATA_STYLES = {
|
|
656
|
+
"hard-break": hardBreakMetadataStyle,
|
|
657
|
+
list: listMetadataStyle,
|
|
658
|
+
plain: plainMetadataStyle
|
|
659
|
+
};
|
|
660
|
+
METADATA_STYLE_IDS = ["list", "hard-break", "plain"];
|
|
661
|
+
}
|
|
662
|
+
});
|
|
663
|
+
|
|
664
|
+
// ../file-system-task-provider/src/metadata-style/index.ts
|
|
665
|
+
var init_metadata_style2 = __esm({
|
|
666
|
+
"../file-system-task-provider/src/metadata-style/index.ts"() {
|
|
667
|
+
"use strict";
|
|
668
|
+
init_esm_shims();
|
|
669
|
+
init_metadata_style_hard_break();
|
|
670
|
+
init_metadata_style();
|
|
671
|
+
init_metadata_style_list();
|
|
672
|
+
init_metadata_style_plain();
|
|
673
|
+
}
|
|
674
|
+
});
|
|
675
|
+
|
|
452
676
|
// ../file-system-task-provider/src/file-system-metrics-adapter.ts
|
|
453
677
|
import {
|
|
454
678
|
TASK_STATUSES,
|
|
@@ -641,7 +865,7 @@ var init_file_system_metrics_adapter = __esm({
|
|
|
641
865
|
"use strict";
|
|
642
866
|
init_esm_shims();
|
|
643
867
|
init_assignee_identity();
|
|
644
|
-
|
|
868
|
+
init_metadata_style2();
|
|
645
869
|
MILLISECONDS_PER_SECOND = 1e3;
|
|
646
870
|
SECONDS_PER_MINUTE = 60;
|
|
647
871
|
MINUTES_PER_HOUR = 60;
|
|
@@ -692,11 +916,7 @@ var init_file_system_metrics_adapter = __esm({
|
|
|
692
916
|
const titleMatch = content.match(TASK_TITLE_PATTERNS.withDash) ?? content.match(TASK_TITLE_PATTERNS.withNumber);
|
|
693
917
|
const title = titleMatch?.[1] ?? file.replace(/\.md$/, "");
|
|
694
918
|
const contentWithoutCodeBlocks = removeCodeBlocks(content);
|
|
695
|
-
const extract = (name) =>
|
|
696
|
-
const rx = new RegExp(`^${name}:\\s*(.+)$`, "im");
|
|
697
|
-
const captured = contentWithoutCodeBlocks.match(rx)?.[1];
|
|
698
|
-
return captured === void 0 ? void 0 : stripHardBreak(captured);
|
|
699
|
-
};
|
|
919
|
+
const extract = (name) => readMetadataField(contentWithoutCodeBlocks, name);
|
|
700
920
|
const statusValue = extract("Status");
|
|
701
921
|
const assigneeValue = extract("Assignee");
|
|
702
922
|
const typeValue = extract("Type");
|
|
@@ -955,7 +1175,7 @@ __export(task_validator_exports, {
|
|
|
955
1175
|
});
|
|
956
1176
|
import { readFile, writeFile } from "fs/promises";
|
|
957
1177
|
import { TASK_STATUSES as TASK_STATUSES2 } from "@opentask/taskin-types";
|
|
958
|
-
async function fixTaskFile(filePath) {
|
|
1178
|
+
async function fixTaskFile(filePath, options = {}) {
|
|
959
1179
|
try {
|
|
960
1180
|
const content = await readFile(filePath, "utf-8");
|
|
961
1181
|
const locale = detectLocale(content);
|
|
@@ -963,66 +1183,32 @@ async function fixTaskFile(filePath) {
|
|
|
963
1183
|
const statusPattern = new RegExp(`##\\s*(?:Status|${i18n.status})\\s*\\n\\s*([^\\n\\r]+)`, "i");
|
|
964
1184
|
const typePattern = new RegExp(`##\\s*(?:Type|${i18n.type})\\s*\\n\\s*([^\\n\\r]+)`, "i");
|
|
965
1185
|
const assigneePattern = new RegExp(`##\\s*(?:Assignee|${i18n.assignee})\\s*\\n\\s*([^\\n\\r]+)`, "i");
|
|
966
|
-
const
|
|
967
|
-
const
|
|
968
|
-
const
|
|
969
|
-
const
|
|
970
|
-
const inlineTypePattern = /^(Type|Tipo):\s*/i;
|
|
971
|
-
const inlineAssigneePattern = /^(Assignee|Responsável):\s*/i;
|
|
972
|
-
const lines = content.split(/\r?\n/);
|
|
973
|
-
const inlineStatusLine = lines.find((l) => inlineStatusPattern.test(l));
|
|
974
|
-
const inlineTypeLine = lines.find((l) => inlineTypePattern.test(l));
|
|
975
|
-
const inlineAssigneeLine = lines.find((l) => inlineAssigneePattern.test(l));
|
|
976
|
-
const hasInlineStatus = !!inlineStatusLine;
|
|
977
|
-
const hasInlineType = !!inlineTypeLine;
|
|
978
|
-
const hasInlineAssignee = !!inlineAssigneeLine;
|
|
979
|
-
const endsWithHardBreak = (line) => !!line && line.endsWith(HARD_BREAK);
|
|
980
|
-
const needsSpaceFix = hasInlineStatus && !endsWithHardBreak(inlineStatusLine) || hasInlineType && !endsWithHardBreak(inlineTypeLine) || hasInlineAssignee && !endsWithHardBreak(inlineAssigneeLine);
|
|
981
|
-
if (!hasSectionStatus && !hasSectionType && !hasSectionAssignee && !needsSpaceFix) {
|
|
982
|
-
return false;
|
|
983
|
-
}
|
|
1186
|
+
const statusMatch = content.match(statusPattern);
|
|
1187
|
+
const typeMatch = content.match(typePattern);
|
|
1188
|
+
const assigneeMatch = content.match(assigneePattern);
|
|
1189
|
+
const hasSectionMetadata = !!(statusMatch || typeMatch || assigneeMatch);
|
|
984
1190
|
let newContent = content;
|
|
985
|
-
if (
|
|
986
|
-
const
|
|
987
|
-
|
|
988
|
-
const assigneeMatch = content.match(assigneePattern);
|
|
989
|
-
if (statusMatch) {
|
|
990
|
-
newContent = newContent.replace(statusPattern, "");
|
|
991
|
-
}
|
|
992
|
-
if (typeMatch) {
|
|
993
|
-
newContent = newContent.replace(typePattern, "");
|
|
994
|
-
}
|
|
995
|
-
if (assigneeMatch) {
|
|
996
|
-
newContent = newContent.replace(assigneePattern, "");
|
|
1191
|
+
if (hasSectionMetadata) {
|
|
1192
|
+
for (const pattern of [statusPattern, typePattern, assigneePattern]) {
|
|
1193
|
+
newContent = newContent.replace(pattern, "");
|
|
997
1194
|
}
|
|
998
1195
|
newContent = newContent.replace(/\n{3,}/g, "\n\n");
|
|
999
|
-
|
|
1000
|
-
if (titleLineIdx === -1) {
|
|
1196
|
+
if (!newContent.split("\n").some((line) => line.trim().startsWith("# "))) {
|
|
1001
1197
|
return false;
|
|
1002
1198
|
}
|
|
1003
|
-
const contentLines = newContent.split("\n");
|
|
1004
|
-
const beforeTitle = contentLines.slice(0, titleLineIdx + 1);
|
|
1005
|
-
const afterTitle = contentLines.slice(titleLineIdx + 1);
|
|
1006
|
-
const inlineMetadata = [];
|
|
1007
|
-
if (statusMatch?.[1]) {
|
|
1008
|
-
inlineMetadata.push(`Status: ${statusMatch[1].trim()}${HARD_BREAK}`);
|
|
1009
|
-
}
|
|
1010
|
-
if (typeMatch?.[1]) {
|
|
1011
|
-
inlineMetadata.push(`Type: ${typeMatch[1].trim()}${HARD_BREAK}`);
|
|
1012
|
-
}
|
|
1013
|
-
if (assigneeMatch?.[1]) {
|
|
1014
|
-
inlineMetadata.push(`Assignee: ${assigneeMatch[1].trim()}${HARD_BREAK}`);
|
|
1015
|
-
}
|
|
1016
|
-
newContent = [...beforeTitle, "", ...inlineMetadata, "", ...afterTitle].join("\n");
|
|
1017
1199
|
}
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
)
|
|
1200
|
+
const style = options.convertTo ? getMetadataStyle(options.convertTo) : resolveMetadataStyle(newContent, options.metadataStyle ?? DEFAULT_METADATA_STYLE_ID);
|
|
1201
|
+
if (hasSectionMetadata) {
|
|
1202
|
+
const migrated = [
|
|
1203
|
+
["Status", statusMatch?.[1]?.trim()],
|
|
1204
|
+
["Type", typeMatch?.[1]?.trim()],
|
|
1205
|
+
["Assignee", assigneeMatch?.[1]?.trim()]
|
|
1206
|
+
];
|
|
1207
|
+
for (const [label, value] of migrated) {
|
|
1208
|
+
if (value) newContent = style.write(newContent, label, value);
|
|
1024
1209
|
}
|
|
1025
1210
|
}
|
|
1211
|
+
newContent = convertMetadataStyle(newContent, style.id);
|
|
1026
1212
|
const finalContentRaw = `${newContent.replace(/\n{3,}/g, "\n\n").trim()}
|
|
1027
1213
|
`;
|
|
1028
1214
|
const originalContentRaw = `${content.replace(/\n{3,}/g, "\n\n").trim()}
|
|
@@ -1049,9 +1235,10 @@ async function validateTaskFile(filePath) {
|
|
|
1049
1235
|
const locale = detectLocale(content);
|
|
1050
1236
|
const i18n = getI18n(locale);
|
|
1051
1237
|
const hasTitleSection = lines.some((line) => line.trim().startsWith("# "));
|
|
1052
|
-
const inlineStatusPattern = new RegExp(`^(?:Status|${i18n.status}):\\s*.+$`, "im");
|
|
1053
1238
|
const sectionStatusPattern = new RegExp(`##\\s*(?:Status|${i18n.status})`, "i");
|
|
1054
|
-
const
|
|
1239
|
+
const inlineStatus = readMetadataField(content, i18n.status, "Status");
|
|
1240
|
+
const isMetadataLine = (line) => new RegExp(`^(?:-\\s+)?(?:Status|${i18n.status})\\s*:`, "i").test(line.trim());
|
|
1241
|
+
const hasInlineStatus = inlineStatus !== void 0;
|
|
1055
1242
|
const hasSectionStatus = sectionStatusPattern.test(content);
|
|
1056
1243
|
const hasDescriptionSection = content.includes("## Description") || content.includes("## Descri\xE7\xE3o");
|
|
1057
1244
|
if (!hasTitleSection) {
|
|
@@ -1083,10 +1270,9 @@ ${i18n.status}: <todo|in-progress|done>`
|
|
|
1083
1270
|
${i18n.status}: <todo|in-progress|done>`
|
|
1084
1271
|
});
|
|
1085
1272
|
} else {
|
|
1086
|
-
const
|
|
1087
|
-
const statusValue = statusMatch ? stripHardBreak(statusMatch[0].split(":")[1] ?? "").toLowerCase() : "";
|
|
1273
|
+
const statusValue = (inlineStatus ?? "").toLowerCase();
|
|
1088
1274
|
if (!ACCEPTED_STATUSES.includes(statusValue)) {
|
|
1089
|
-
const statusLineIdx = lines.findIndex(
|
|
1275
|
+
const statusLineIdx = lines.findIndex(isMetadataLine);
|
|
1090
1276
|
issues.push({
|
|
1091
1277
|
file: filePath,
|
|
1092
1278
|
line: statusLineIdx >= 0 ? statusLineIdx + 1 : void 0,
|
|
@@ -1150,7 +1336,7 @@ var init_task_validator = __esm({
|
|
|
1150
1336
|
"use strict";
|
|
1151
1337
|
init_esm_shims();
|
|
1152
1338
|
init_i18n();
|
|
1153
|
-
|
|
1339
|
+
init_metadata_style2();
|
|
1154
1340
|
ACCEPTED_STATUSES = [...TASK_STATUSES2, "todo"];
|
|
1155
1341
|
ACCEPTED_STATUSES_LABEL = ACCEPTED_STATUSES.join(", ");
|
|
1156
1342
|
}
|
|
@@ -1442,16 +1628,8 @@ function parsePrioritizationFields(priorityMatch, groupMatch, groupNameMatch, di
|
|
|
1442
1628
|
...difficulty !== void 0 && !Number.isNaN(difficulty) && { difficulty }
|
|
1443
1629
|
};
|
|
1444
1630
|
}
|
|
1445
|
-
function setInlineField(content, fieldName, value) {
|
|
1446
|
-
|
|
1447
|
-
if (value === void 0) {
|
|
1448
|
-
return linePattern.test(content) ? content.replace(linePattern, "") : content;
|
|
1449
|
-
}
|
|
1450
|
-
if (new RegExp(`^${fieldName}:\\s*.+$`, "im").test(content)) {
|
|
1451
|
-
return content.replace(new RegExp(`^${fieldName}:\\s*.+$`, "im"), `${fieldName}: ${value}${HARD_BREAK}`);
|
|
1452
|
-
}
|
|
1453
|
-
return content.replace(/(^#.*\n)/, `$1${fieldName}: ${value}${HARD_BREAK}
|
|
1454
|
-
`);
|
|
1631
|
+
function setInlineField(content, fieldName, value, fallbackStyle) {
|
|
1632
|
+
return resolveMetadataStyle(content, fallbackStyle).write(content, fieldName, value);
|
|
1455
1633
|
}
|
|
1456
1634
|
var TITLE_PATTERN, FileSystemTaskProvider;
|
|
1457
1635
|
var init_file_system_task_provider = __esm({
|
|
@@ -1461,20 +1639,52 @@ var init_file_system_task_provider = __esm({
|
|
|
1461
1639
|
init_src();
|
|
1462
1640
|
init_assignee_identity();
|
|
1463
1641
|
init_i18n();
|
|
1464
|
-
|
|
1642
|
+
init_metadata_style2();
|
|
1465
1643
|
init_task_validator();
|
|
1466
1644
|
init_user_registry();
|
|
1467
1645
|
init_users_file_location();
|
|
1468
1646
|
TITLE_PATTERN = /^#\s+(?:🧩\s+)?Task\s+\d+\s*[—-]\s*(.+)$/im;
|
|
1469
1647
|
FileSystemTaskProvider = class {
|
|
1470
|
-
constructor(tasksDirectory, userRegistry, locale = "en-US", logger) {
|
|
1648
|
+
constructor(tasksDirectory, userRegistry, locale = "en-US", logger, options = {}) {
|
|
1471
1649
|
this.tasksDirectory = tasksDirectory;
|
|
1472
1650
|
this.userRegistry = userRegistry;
|
|
1473
1651
|
this.locale = locale;
|
|
1474
1652
|
this.logger = logger ?? NullLogger;
|
|
1653
|
+
this.metadataStyle = options.metadataStyle ?? DEFAULT_METADATA_STYLE_ID;
|
|
1654
|
+
this.convertMetadataStyleTo = options.convertMetadataStyleTo;
|
|
1475
1655
|
}
|
|
1476
1656
|
locale;
|
|
1477
1657
|
logger;
|
|
1658
|
+
metadataStyle;
|
|
1659
|
+
convertMetadataStyleTo;
|
|
1660
|
+
/**
|
|
1661
|
+
* Reads the metadata a task file carries, whatever style it is written in
|
|
1662
|
+
* and whichever of the two locales named the fields.
|
|
1663
|
+
*/
|
|
1664
|
+
readInlineMetadata(content) {
|
|
1665
|
+
const i18n = getI18n(detectLocale(content));
|
|
1666
|
+
const read = (english, localized) => readMetadataField(content, localized, english);
|
|
1667
|
+
return {
|
|
1668
|
+
status: read("Status", i18n.status),
|
|
1669
|
+
type: read("Type", i18n.type),
|
|
1670
|
+
assignee: read("Assignee", i18n.assignee),
|
|
1671
|
+
priority: read("Priority", i18n.priority),
|
|
1672
|
+
group: read("Group", i18n.group),
|
|
1673
|
+
groupName: read("GroupName", i18n.groupName),
|
|
1674
|
+
difficulty: read("Difficulty", i18n.difficulty)
|
|
1675
|
+
};
|
|
1676
|
+
}
|
|
1677
|
+
/**
|
|
1678
|
+
* The label to write a field under: the one the file already uses, or the
|
|
1679
|
+
* English name.
|
|
1680
|
+
*
|
|
1681
|
+
* Without this, writing `Prioridade` into a file that already says
|
|
1682
|
+
* `Priority` appends a second line instead of updating the first.
|
|
1683
|
+
*/
|
|
1684
|
+
labelFor(content, english, localized) {
|
|
1685
|
+
if (readMetadataField(content, localized) !== void 0) return localized;
|
|
1686
|
+
return english;
|
|
1687
|
+
}
|
|
1478
1688
|
/**
|
|
1479
1689
|
* A raiz do projeto: o diretório que contém `TASKS/` e `.taskin/`.
|
|
1480
1690
|
*
|
|
@@ -1519,8 +1729,7 @@ var init_file_system_task_provider = __esm({
|
|
|
1519
1729
|
*/
|
|
1520
1730
|
readAssigneeLine(content) {
|
|
1521
1731
|
const i18n = getI18n(detectLocale(content));
|
|
1522
|
-
|
|
1523
|
-
return match?.[1] === void 0 ? void 0 : stripHardBreak(match[1]);
|
|
1732
|
+
return readMetadataField(content, "Assignee", i18n.assignee);
|
|
1524
1733
|
}
|
|
1525
1734
|
async pathExists(target) {
|
|
1526
1735
|
try {
|
|
@@ -1539,25 +1748,15 @@ var init_file_system_task_provider = __esm({
|
|
|
1539
1748
|
const filePath = path6.join(this.tasksDirectory, taskFile);
|
|
1540
1749
|
const content = await fs4.readFile(filePath, "utf-8");
|
|
1541
1750
|
const title = content.match(TITLE_PATTERN)?.[1]?.trim() ?? "Untitled";
|
|
1542
|
-
const
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
}
|
|
1552
|
-
return null;
|
|
1553
|
-
};
|
|
1554
|
-
const statusMatch = extractInline("Status", i18n.status);
|
|
1555
|
-
const typeMatch = extractInline("Type", i18n.type);
|
|
1556
|
-
const assigneeMatch = extractInline("Assignee", i18n.assignee);
|
|
1557
|
-
const priorityMatch = extractInline("Priority", i18n.priority);
|
|
1558
|
-
const groupMatch = extractInline("Group", i18n.group);
|
|
1559
|
-
const groupNameMatch = extractInline("GroupName", i18n.groupName);
|
|
1560
|
-
const difficultyMatch = extractInline("Difficulty", i18n.difficulty);
|
|
1751
|
+
const {
|
|
1752
|
+
status: statusMatch,
|
|
1753
|
+
type: typeMatch,
|
|
1754
|
+
assignee: assigneeMatch,
|
|
1755
|
+
priority: priorityMatch,
|
|
1756
|
+
group: groupMatch,
|
|
1757
|
+
groupName: groupNameMatch,
|
|
1758
|
+
difficulty: difficultyMatch
|
|
1759
|
+
} = this.readInlineMetadata(content);
|
|
1561
1760
|
let assignee;
|
|
1562
1761
|
if (assigneeMatch) {
|
|
1563
1762
|
const assigneeValue = assigneeMatch.trim();
|
|
@@ -1588,27 +1787,35 @@ var init_file_system_task_provider = __esm({
|
|
|
1588
1787
|
const hasSectionMetadata = /##\s*(Status|Type|Assignee)/i.test(currentContent);
|
|
1589
1788
|
if (hasSectionMetadata) {
|
|
1590
1789
|
const { fixTaskFile: fixTaskFile2 } = await Promise.resolve().then(() => (init_task_validator(), task_validator_exports));
|
|
1591
|
-
await fixTaskFile2(task.filePath);
|
|
1790
|
+
await fixTaskFile2(task.filePath, { metadataStyle: this.metadataStyle });
|
|
1592
1791
|
}
|
|
1593
1792
|
const content = await fs4.readFile(task.filePath, "utf-8");
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
updatedContent
|
|
1599
|
-
|
|
1600
|
-
|
|
1793
|
+
const i18n = getI18n(detectLocale(content));
|
|
1794
|
+
const style = resolveMetadataStyle(content, this.metadataStyle);
|
|
1795
|
+
let updatedContent = style.write(content, this.labelFor(content, "Status", i18n.status), task.status);
|
|
1796
|
+
updatedContent = setInlineField(
|
|
1797
|
+
updatedContent,
|
|
1798
|
+
this.labelFor(updatedContent, "Priority", i18n.priority),
|
|
1799
|
+
task.order !== void 0 ? String(task.order) : void 0,
|
|
1800
|
+
this.metadataStyle
|
|
1801
|
+
);
|
|
1802
|
+
updatedContent = setInlineField(
|
|
1803
|
+
updatedContent,
|
|
1804
|
+
this.labelFor(updatedContent, "Group", i18n.group),
|
|
1805
|
+
task.groupId || void 0,
|
|
1806
|
+
this.metadataStyle
|
|
1807
|
+
);
|
|
1601
1808
|
updatedContent = setInlineField(
|
|
1602
1809
|
updatedContent,
|
|
1603
|
-
"
|
|
1604
|
-
task.
|
|
1810
|
+
this.labelFor(updatedContent, "GroupName", i18n.groupName),
|
|
1811
|
+
task.groupName || void 0,
|
|
1812
|
+
this.metadataStyle
|
|
1605
1813
|
);
|
|
1606
|
-
updatedContent = setInlineField(updatedContent, "Group", task.groupId || void 0);
|
|
1607
|
-
updatedContent = setInlineField(updatedContent, "GroupName", task.groupName || void 0);
|
|
1608
1814
|
updatedContent = setInlineField(
|
|
1609
1815
|
updatedContent,
|
|
1610
|
-
"Difficulty",
|
|
1611
|
-
task.difficulty !== void 0 ? String(task.difficulty) : void 0
|
|
1816
|
+
this.labelFor(updatedContent, "Difficulty", i18n.difficulty),
|
|
1817
|
+
task.difficulty !== void 0 ? String(task.difficulty) : void 0,
|
|
1818
|
+
this.metadataStyle
|
|
1612
1819
|
);
|
|
1613
1820
|
await fs4.writeFile(task.filePath, updatedContent, "utf-8");
|
|
1614
1821
|
}
|
|
@@ -1622,25 +1829,15 @@ var init_file_system_task_provider = __esm({
|
|
|
1622
1829
|
const filePath = path6.join(this.tasksDirectory, file);
|
|
1623
1830
|
const content = await fs4.readFile(filePath, "utf-8");
|
|
1624
1831
|
const title = content.match(TITLE_PATTERN)?.[1]?.trim() ?? "Untitled";
|
|
1625
|
-
const
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
}
|
|
1635
|
-
return null;
|
|
1636
|
-
};
|
|
1637
|
-
const statusMatch = extractInline("Status", i18n.status);
|
|
1638
|
-
const typeMatch = extractInline("Type", i18n.type);
|
|
1639
|
-
const assigneeMatch = extractInline("Assignee", i18n.assignee);
|
|
1640
|
-
const priorityMatch = extractInline("Priority", i18n.priority);
|
|
1641
|
-
const groupMatch = extractInline("Group", i18n.group);
|
|
1642
|
-
const groupNameMatch = extractInline("GroupName", i18n.groupName);
|
|
1643
|
-
const difficultyMatch = extractInline("Difficulty", i18n.difficulty);
|
|
1832
|
+
const {
|
|
1833
|
+
status: statusMatch,
|
|
1834
|
+
type: typeMatch,
|
|
1835
|
+
assignee: assigneeMatch,
|
|
1836
|
+
priority: priorityMatch,
|
|
1837
|
+
group: groupMatch,
|
|
1838
|
+
groupName: groupNameMatch,
|
|
1839
|
+
difficulty: difficultyMatch
|
|
1840
|
+
} = this.readInlineMetadata(content);
|
|
1644
1841
|
let assignee;
|
|
1645
1842
|
if (assigneeMatch) {
|
|
1646
1843
|
const assigneeValue = assigneeMatch.trim();
|
|
@@ -1714,11 +1911,14 @@ var init_file_system_task_provider = __esm({
|
|
|
1714
1911
|
}
|
|
1715
1912
|
generateTaskMarkdown(data) {
|
|
1716
1913
|
const { id, title, type, description, assignee, i18n } = data;
|
|
1914
|
+
const metadata = getMetadataStyle(this.metadataStyle).format([
|
|
1915
|
+
{ label: i18n.status, value: "pending" },
|
|
1916
|
+
{ label: i18n.type, value: type },
|
|
1917
|
+
{ label: i18n.assignee, value: assignee }
|
|
1918
|
+
]);
|
|
1717
1919
|
return `# \u{1F9E9} Task ${id} \u2014 ${title}
|
|
1718
1920
|
|
|
1719
|
-
${
|
|
1720
|
-
${i18n.type}: ${type}${HARD_BREAK}
|
|
1721
|
-
${i18n.assignee}: ${assignee}${HARD_BREAK}
|
|
1921
|
+
${metadata}
|
|
1722
1922
|
|
|
1723
1923
|
## ${i18n.description}
|
|
1724
1924
|
${description || i18n.descriptionPlaceholder}
|
|
@@ -1762,7 +1962,10 @@ ${i18n.notesPlaceholder}
|
|
|
1762
1962
|
}
|
|
1763
1963
|
let fixedCount = 0;
|
|
1764
1964
|
for (const filePath of taskFiles) {
|
|
1765
|
-
const wasFixed = await fixTaskFile(filePath
|
|
1965
|
+
const wasFixed = await fixTaskFile(filePath, {
|
|
1966
|
+
metadataStyle: this.metadataStyle,
|
|
1967
|
+
...this.convertMetadataStyleTo !== void 0 && { convertTo: this.convertMetadataStyleTo }
|
|
1968
|
+
});
|
|
1766
1969
|
if (wasFixed) {
|
|
1767
1970
|
fixedCount++;
|
|
1768
1971
|
}
|
|
@@ -1802,32 +2005,45 @@ var init_task_file_types = __esm({
|
|
|
1802
2005
|
// ../file-system-task-provider/src/index.ts
|
|
1803
2006
|
var src_exports = {};
|
|
1804
2007
|
__export(src_exports, {
|
|
2008
|
+
DEFAULT_METADATA_STYLE_ID: () => DEFAULT_METADATA_STYLE_ID,
|
|
1805
2009
|
FileSystemMetricsAdapter: () => FileSystemMetricsAdapter,
|
|
1806
2010
|
FileSystemTaskProvider: () => FileSystemTaskProvider,
|
|
1807
2011
|
HARD_BREAK: () => HARD_BREAK,
|
|
2012
|
+
METADATA_STYLES: () => METADATA_STYLES,
|
|
2013
|
+
METADATA_STYLE_IDS: () => METADATA_STYLE_IDS,
|
|
1808
2014
|
NullLogger: () => NullLogger,
|
|
1809
2015
|
PARKED_USERS_FILE_NAME: () => PARKED_USERS_FILE_NAME,
|
|
1810
2016
|
TASKIN_DIR_NAME: () => TASKIN_DIR_NAME,
|
|
1811
2017
|
USERS_FILE_NAME: () => USERS_FILE_NAME,
|
|
1812
2018
|
UserRegistry: () => UserRegistry,
|
|
1813
2019
|
classifyAssignee: () => classifyAssignee,
|
|
2020
|
+
convertMetadataStyle: () => convertMetadataStyle,
|
|
1814
2021
|
createTaskWithSync: () => createTaskWithSync,
|
|
1815
2022
|
detectLocale: () => detectLocale,
|
|
2023
|
+
detectMetadataStyle: () => detectMetadataStyle,
|
|
1816
2024
|
fixAssignees: () => fixAssignees,
|
|
1817
2025
|
fixUsersFileLocation: () => fixUsersFileLocation,
|
|
1818
2026
|
foldAssignee: () => foldAssignee,
|
|
1819
2027
|
getI18n: () => getI18n,
|
|
2028
|
+
getMetadataStyle: () => getMetadataStyle,
|
|
1820
2029
|
getNextTaskNumberAfterSync: () => getNextTaskNumberAfterSync,
|
|
2030
|
+
hardBreakMetadataStyle: () => hardBreakMetadataStyle,
|
|
1821
2031
|
i18nConfig: () => i18nConfig,
|
|
1822
2032
|
inspectUsersFileLocation: () => inspectUsersFileLocation,
|
|
2033
|
+
isMetadataStyleId: () => isMetadataStyleId,
|
|
2034
|
+
listMetadataStyle: () => listMetadataStyle,
|
|
2035
|
+
plainMetadataStyle: () => plainMetadataStyle,
|
|
1823
2036
|
pushAfterCreate: () => pushAfterCreate,
|
|
2037
|
+
readMetadataField: () => readMetadataField,
|
|
2038
|
+
resolveMetadataStyle: () => resolveMetadataStyle,
|
|
1824
2039
|
resolveUsersFilePaths: () => resolveUsersFilePaths,
|
|
1825
2040
|
squashTaskFileOnDone: () => squashTaskFileOnDone,
|
|
1826
2041
|
stripHardBreak: () => stripHardBreak,
|
|
1827
2042
|
syncBeforeCreate: () => syncBeforeCreate,
|
|
1828
2043
|
validateAssignees: () => validateAssignees,
|
|
1829
2044
|
validateSeededUsers: () => validateSeededUsers,
|
|
1830
|
-
validateUsersFileLocation: () => validateUsersFileLocation
|
|
2045
|
+
validateUsersFileLocation: () => validateUsersFileLocation,
|
|
2046
|
+
writeMetadataField: () => writeMetadataField
|
|
1831
2047
|
});
|
|
1832
2048
|
var init_src2 = __esm({
|
|
1833
2049
|
"../file-system-task-provider/src/index.ts"() {
|
|
@@ -1839,6 +2055,7 @@ var init_src2 = __esm({
|
|
|
1839
2055
|
init_file_system_task_provider();
|
|
1840
2056
|
init_i18n();
|
|
1841
2057
|
init_inline_metadata();
|
|
2058
|
+
init_metadata_style2();
|
|
1842
2059
|
init_task_file_types();
|
|
1843
2060
|
init_user_registry();
|
|
1844
2061
|
init_users_file_location();
|
|
@@ -3029,6 +3246,10 @@ var AVAILABLE_PROVIDERS = [
|
|
|
3029
3246
|
tasksDir: {
|
|
3030
3247
|
type: "string",
|
|
3031
3248
|
description: "Directory to store task files"
|
|
3249
|
+
},
|
|
3250
|
+
metadataStyle: {
|
|
3251
|
+
type: "string",
|
|
3252
|
+
description: "Marking of the metadata block for new files (list | hard-break | plain)"
|
|
3032
3253
|
}
|
|
3033
3254
|
}
|
|
3034
3255
|
},
|
|
@@ -3133,11 +3354,16 @@ function expandProviderConfig(config) {
|
|
|
3133
3354
|
return expanded;
|
|
3134
3355
|
}
|
|
3135
3356
|
var buildFileSystemProvider = async ({ projectRoot, providerConfig, tasksDirOverride }) => {
|
|
3136
|
-
const { FileSystemTaskProvider: FileSystemTaskProvider2, UserRegistry: UserRegistry2 } = await Promise.resolve().then(() => (init_src2(), src_exports));
|
|
3357
|
+
const { FileSystemTaskProvider: FileSystemTaskProvider2, isMetadataStyleId: isMetadataStyleId2, UserRegistry: UserRegistry2 } = await Promise.resolve().then(() => (init_src2(), src_exports));
|
|
3137
3358
|
const configuredTasksDir = typeof providerConfig.tasksDir === "string" ? providerConfig.tasksDir : "TASKS";
|
|
3138
3359
|
const tasksDir = path7.resolve(projectRoot, tasksDirOverride ?? configuredTasksDir);
|
|
3139
3360
|
const userRegistry = new UserRegistry2({ taskinDir: path7.join(projectRoot, ".taskin") });
|
|
3140
|
-
const
|
|
3361
|
+
const metadataStyle = isMetadataStyleId2(providerConfig.metadataStyle) ? providerConfig.metadataStyle : void 0;
|
|
3362
|
+
const convertMetadataStyleTo = isMetadataStyleId2(providerConfig.convertMetadataStyleTo) ? providerConfig.convertMetadataStyleTo : void 0;
|
|
3363
|
+
const provider = new FileSystemTaskProvider2(tasksDir, userRegistry, void 0, void 0, {
|
|
3364
|
+
...metadataStyle !== void 0 && { metadataStyle },
|
|
3365
|
+
...convertMetadataStyleTo !== void 0 && { convertMetadataStyleTo }
|
|
3366
|
+
});
|
|
3141
3367
|
return { provider, userRegistry };
|
|
3142
3368
|
};
|
|
3143
3369
|
var PROVIDER_BUILDERS = {
|
|
@@ -3169,7 +3395,7 @@ async function resolveTaskProvider(options = {}, builders = PROVIDER_BUILDERS) {
|
|
|
3169
3395
|
}
|
|
3170
3396
|
const context = {
|
|
3171
3397
|
projectRoot,
|
|
3172
|
-
providerConfig: expandProviderConfig(config.provider.config),
|
|
3398
|
+
providerConfig: { ...expandProviderConfig(config.provider.config), ...options.configOverrides },
|
|
3173
3399
|
...options.tasksDir !== void 0 && { tasksDirOverride: options.tasksDir }
|
|
3174
3400
|
};
|
|
3175
3401
|
const { provider, userRegistry } = await build(context);
|
|
@@ -4825,7 +5051,7 @@ async function setupProviderConfig(provider, cwd) {
|
|
|
4825
5051
|
}
|
|
4826
5052
|
async function setupFileSystemProvider(cwd) {
|
|
4827
5053
|
const tasksDir = join3(cwd, "TASKS");
|
|
4828
|
-
const { FileSystemTaskProvider: FileSystemTaskProvider2, UserRegistry: UserRegistry2 } = await Promise.resolve().then(() => (init_src2(), src_exports));
|
|
5054
|
+
const { DEFAULT_METADATA_STYLE_ID: DEFAULT_METADATA_STYLE_ID2, FileSystemTaskProvider: FileSystemTaskProvider2, getMetadataStyle: getMetadataStyle2, UserRegistry: UserRegistry2 } = await Promise.resolve().then(() => (init_src2(), src_exports));
|
|
4829
5055
|
const userRegistry = new UserRegistry2({ taskinDir: join3(cwd, ".taskin") });
|
|
4830
5056
|
const fileSystemProvider = new FileSystemTaskProvider2(tasksDir, userRegistry);
|
|
4831
5057
|
await fileSystemProvider.initialize();
|
|
@@ -4838,11 +5064,14 @@ async function setupFileSystemProvider(cwd) {
|
|
|
4838
5064
|
} else {
|
|
4839
5065
|
const sampleTaskFile = join3(tasksDir, "task-001-setup-project.md");
|
|
4840
5066
|
info("Creating sample task...");
|
|
5067
|
+
const sampleMetadata = getMetadataStyle2(DEFAULT_METADATA_STYLE_ID2).format([
|
|
5068
|
+
{ label: "Status", value: "pending" },
|
|
5069
|
+
{ label: "Type", value: "chore" },
|
|
5070
|
+
{ label: "Assignee", value: "developer" }
|
|
5071
|
+
]);
|
|
4841
5072
|
const sampleTask = `# Task 001 \u2014 Setup Project
|
|
4842
5073
|
|
|
4843
|
-
|
|
4844
|
-
Type: chore
|
|
4845
|
-
Assignee: developer
|
|
5074
|
+
${sampleMetadata}
|
|
4846
5075
|
|
|
4847
5076
|
## Description
|
|
4848
5077
|
|
|
@@ -4862,7 +5091,8 @@ You can edit or delete this file. Use \`taskin list\` to see all tasks.
|
|
|
4862
5091
|
success(`\u2713 Created sample task ${colors.highlight("task-001-setup-project.md")}`);
|
|
4863
5092
|
}
|
|
4864
5093
|
return {
|
|
4865
|
-
tasksDir: "TASKS"
|
|
5094
|
+
tasksDir: "TASKS",
|
|
5095
|
+
metadataStyle: DEFAULT_METADATA_STYLE_ID2
|
|
4866
5096
|
};
|
|
4867
5097
|
}
|
|
4868
5098
|
async function promptCreateFirstUser(cwd) {
|
|
@@ -4909,6 +5139,7 @@ async function promptCreateFirstUser(cwd) {
|
|
|
4909
5139
|
// src/commands/lint.ts
|
|
4910
5140
|
init_esm_shims();
|
|
4911
5141
|
import chalk5 from "chalk";
|
|
5142
|
+
var METADATA_STYLES2 = ["list", "hard-break", "plain"];
|
|
4912
5143
|
var lintCommand = defineCommand({
|
|
4913
5144
|
name: "lint",
|
|
4914
5145
|
description: "\u{1F50D} Validate task markdown files",
|
|
@@ -4921,6 +5152,10 @@ var lintCommand = defineCommand({
|
|
|
4921
5152
|
{
|
|
4922
5153
|
flags: "-f, --fix",
|
|
4923
5154
|
description: "Automatically fix task file format issues"
|
|
5155
|
+
},
|
|
5156
|
+
{
|
|
5157
|
+
flags: "-m, --metadata-style <style>",
|
|
5158
|
+
description: `Rewrite the metadata block in this style with --fix (${METADATA_STYLES2.join(" | ")})`
|
|
4924
5159
|
}
|
|
4925
5160
|
],
|
|
4926
5161
|
handler: async (options) => {
|
|
@@ -4928,7 +5163,19 @@ var lintCommand = defineCommand({
|
|
|
4928
5163
|
}
|
|
4929
5164
|
});
|
|
4930
5165
|
async function executeLint(options) {
|
|
4931
|
-
const
|
|
5166
|
+
const style = options.metadataStyle;
|
|
5167
|
+
if (style !== void 0 && !METADATA_STYLES2.includes(style)) {
|
|
5168
|
+
console.error(chalk5.red(`Unknown metadata style "${style}". Use one of: ${METADATA_STYLES2.join(", ")}.`));
|
|
5169
|
+
process.exit(1);
|
|
5170
|
+
}
|
|
5171
|
+
if (style !== void 0 && !options.fix) {
|
|
5172
|
+
console.error(chalk5.red("--metadata-style rewrites files, so it requires --fix."));
|
|
5173
|
+
process.exit(1);
|
|
5174
|
+
}
|
|
5175
|
+
const { provider, providerType } = await resolveTaskProvider({
|
|
5176
|
+
...options.path ? { tasksDir: options.path } : {},
|
|
5177
|
+
...style !== void 0 && { configOverrides: { metadataStyle: style, convertMetadataStyleTo: style } }
|
|
5178
|
+
});
|
|
4932
5179
|
if (options.fix) {
|
|
4933
5180
|
console.log(`\u{1F527} Fixing tasks (provider: ${providerType})
|
|
4934
5181
|
`);
|
|
@@ -6723,14 +6970,10 @@ var FileSystemTaskLinter = class {
|
|
|
6723
6970
|
return null;
|
|
6724
6971
|
}
|
|
6725
6972
|
extractMetadata(content) {
|
|
6726
|
-
const [headerSection = ""] = content.split(/^##/m);
|
|
6727
|
-
const statusMatch = headerSection.match(/^Status:\s*(.+)$/im);
|
|
6728
|
-
const typeMatch = headerSection.match(/^Type:\s*(.+)$/im);
|
|
6729
|
-
const assigneeMatch = headerSection.match(/^Assignee:\s*(.+)$/im);
|
|
6730
6973
|
return {
|
|
6731
|
-
status:
|
|
6732
|
-
type:
|
|
6733
|
-
assignee:
|
|
6974
|
+
status: readMetadataField(content, "Status")?.toLowerCase(),
|
|
6975
|
+
type: readMetadataField(content, "Type")?.toLowerCase(),
|
|
6976
|
+
assignee: readMetadataField(content, "Assignee")
|
|
6734
6977
|
};
|
|
6735
6978
|
}
|
|
6736
6979
|
/**
|