@lucasviola/specwiki 1.0.2 → 1.1.1
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 +3 -1
- package/dist/output/html/assets/specwiki.css +125 -25
- package/dist/output/html/nav-grouping-catalog.d.ts +32 -0
- package/dist/output/html/nav-grouping-catalog.d.ts.map +1 -0
- package/dist/output/html/nav-grouping-catalog.js +294 -0
- package/dist/output/html/nav-grouping-catalog.js.map +1 -0
- package/dist/output/html/nav-grouping.d.ts +12 -5
- package/dist/output/html/nav-grouping.d.ts.map +1 -1
- package/dist/output/html/nav-grouping.js +172 -5
- package/dist/output/html/nav-grouping.js.map +1 -1
- package/dist/output/html/renderer.d.ts +1 -0
- package/dist/output/html/renderer.d.ts.map +1 -1
- package/dist/output/html/renderer.js +28 -13
- package/dist/output/html/renderer.js.map +1 -1
- package/dist/output/html/templates/article.mustache +3 -37
- package/dist/output/html/templates/index.mustache +2 -36
- package/dist/output/html/templates/partials/nav-subgroup-nested.mustache +23 -0
- package/dist/output/html/templates/partials/nav-subgroup.mustache +23 -35
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<br><br>
|
|
6
6
|
|
|
7
7
|
[](https://github.com/lucasviola/specwiki/actions/workflows/ci.yml)
|
|
8
|
-
[](package.json)
|
|
9
9
|
[](package.json)
|
|
10
10
|
[](LICENSE)
|
|
11
11
|
|
|
@@ -222,6 +222,8 @@ npm run typecheck
|
|
|
222
222
|
npm test
|
|
223
223
|
```
|
|
224
224
|
|
|
225
|
+
See [CHANGELOG.md](CHANGELOG.md) for release history. When shipping user-facing changes, add a bullet under `[Unreleased]` there.
|
|
226
|
+
|
|
225
227
|
## License
|
|
226
228
|
|
|
227
229
|
MIT
|
|
@@ -34,6 +34,19 @@
|
|
|
34
34
|
--specwiki-syntax-deletion: #cf222e;
|
|
35
35
|
--specwiki-syntax-deletion-background: #ffebe9;
|
|
36
36
|
--specwiki-header-block-size: calc(var(--size-tool) + 1px);
|
|
37
|
+
--font-size-h1: 2rem;
|
|
38
|
+
--font-size-h2: 1.625rem;
|
|
39
|
+
--font-size-h3: 1.375rem;
|
|
40
|
+
--font-size-h4: 1.125rem;
|
|
41
|
+
--font-size-h5: 1rem;
|
|
42
|
+
--font-size-h6: 0.875rem;
|
|
43
|
+
--font-size-caption: 0.6875rem;
|
|
44
|
+
--font-size-ui-sm: 0.75rem;
|
|
45
|
+
--font-size-ui: 0.8125rem;
|
|
46
|
+
--font-size-body: 0.875rem;
|
|
47
|
+
--font-family-monospace-brand:
|
|
48
|
+
ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono",
|
|
49
|
+
monospace;
|
|
37
50
|
}
|
|
38
51
|
|
|
39
52
|
:root[data-theme="light"] {
|
|
@@ -118,8 +131,8 @@
|
|
|
118
131
|
|
|
119
132
|
body.specwiki {
|
|
120
133
|
margin: 0;
|
|
121
|
-
font-family: var(--font-family-
|
|
122
|
-
font-size:
|
|
134
|
+
font-family: var(--font-family-system-sans);
|
|
135
|
+
font-size: var(--font-size-body);
|
|
123
136
|
line-height: var(--line-height-base);
|
|
124
137
|
color: var(--color-base);
|
|
125
138
|
background-color: var(--background-color-base);
|
|
@@ -200,8 +213,8 @@ body.specwiki {
|
|
|
200
213
|
padding: 0.4rem 0.625rem;
|
|
201
214
|
color: var(--color-base--subtle);
|
|
202
215
|
background-color: var(--background-color-interactive-subtle);
|
|
203
|
-
font-size:
|
|
204
|
-
font-weight: var(--font-weight-bold);
|
|
216
|
+
font-size: var(--font-size-ui-sm);
|
|
217
|
+
font-weight: var(--font-weight-semi-bold);
|
|
205
218
|
text-transform: uppercase;
|
|
206
219
|
letter-spacing: 0.04em;
|
|
207
220
|
}
|
|
@@ -252,7 +265,7 @@ body.specwiki {
|
|
|
252
265
|
border-radius: var(--border-radius-base, 2px);
|
|
253
266
|
color: var(--color-base);
|
|
254
267
|
background-color: var(--specwiki-search-badge-background);
|
|
255
|
-
font-size:
|
|
268
|
+
font-size: var(--font-size-caption);
|
|
256
269
|
font-weight: var(--font-weight-normal);
|
|
257
270
|
text-overflow: ellipsis;
|
|
258
271
|
white-space: nowrap;
|
|
@@ -264,7 +277,7 @@ body.specwiki {
|
|
|
264
277
|
min-width: 0;
|
|
265
278
|
overflow: hidden;
|
|
266
279
|
color: var(--color-base--subtle);
|
|
267
|
-
font-size:
|
|
280
|
+
font-size: var(--font-size-ui);
|
|
268
281
|
font-weight: normal;
|
|
269
282
|
text-overflow: ellipsis;
|
|
270
283
|
white-space: nowrap;
|
|
@@ -296,7 +309,7 @@ body.specwiki {
|
|
|
296
309
|
text-decoration: none;
|
|
297
310
|
font-weight: var(--font-weight-bold);
|
|
298
311
|
font-size: 1rem;
|
|
299
|
-
font-family: var(--font-family-monospace);
|
|
312
|
+
font-family: var(--font-family-monospace-brand);
|
|
300
313
|
letter-spacing: -0.02em;
|
|
301
314
|
}
|
|
302
315
|
|
|
@@ -446,7 +459,8 @@ body.specwiki {
|
|
|
446
459
|
display: block;
|
|
447
460
|
color: var(--color-primary);
|
|
448
461
|
text-decoration: none;
|
|
449
|
-
font-size:
|
|
462
|
+
font-size: var(--font-size-ui);
|
|
463
|
+
font-weight: var(--font-weight-semi-bold);
|
|
450
464
|
margin-bottom: 0.25rem;
|
|
451
465
|
}
|
|
452
466
|
|
|
@@ -466,7 +480,7 @@ body.specwiki {
|
|
|
466
480
|
border-radius: var(--border-radius-base, 2px);
|
|
467
481
|
color: var(--color-base--subtle);
|
|
468
482
|
background-color: var(--background-color-interactive-subtle);
|
|
469
|
-
font-size:
|
|
483
|
+
font-size: var(--font-size-caption);
|
|
470
484
|
font-weight: var(--font-weight-normal);
|
|
471
485
|
}
|
|
472
486
|
|
|
@@ -483,7 +497,7 @@ body.specwiki {
|
|
|
483
497
|
.category-nav-pages a {
|
|
484
498
|
color: var(--color-base);
|
|
485
499
|
text-decoration: none;
|
|
486
|
-
font-size:
|
|
500
|
+
font-size: var(--font-size-ui-sm);
|
|
487
501
|
}
|
|
488
502
|
|
|
489
503
|
.category-nav-pages a:hover {
|
|
@@ -501,16 +515,51 @@ body.specwiki {
|
|
|
501
515
|
margin-top: 0.25rem;
|
|
502
516
|
}
|
|
503
517
|
|
|
518
|
+
.category-nav-subgroup-summary {
|
|
519
|
+
display: flex;
|
|
520
|
+
align-items: center;
|
|
521
|
+
gap: 0.25rem;
|
|
522
|
+
cursor: pointer;
|
|
523
|
+
list-style: none;
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
.category-nav-subgroup-group > summary::-webkit-details-marker {
|
|
527
|
+
display: none;
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
.category-nav-subgroup-group > summary::marker {
|
|
531
|
+
content: "";
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
.category-nav-subgroup-group > summary::before {
|
|
535
|
+
content: "›";
|
|
536
|
+
color: var(--color-base--subtle);
|
|
537
|
+
font-size: 0.875rem;
|
|
538
|
+
line-height: 1;
|
|
539
|
+
transform: rotate(0deg);
|
|
540
|
+
transition: transform 160ms ease-out;
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
.category-nav-subgroup-group[open] > summary::before {
|
|
544
|
+
transform: rotate(90deg);
|
|
545
|
+
}
|
|
546
|
+
|
|
504
547
|
.category-nav-subgroup-label {
|
|
505
548
|
display: block;
|
|
506
|
-
font-size:
|
|
507
|
-
font-weight: var(--font-weight-bold);
|
|
549
|
+
font-size: var(--font-size-caption);
|
|
550
|
+
font-weight: var(--font-weight-semi-bold);
|
|
508
551
|
color: var(--color-base--subtle);
|
|
509
552
|
margin: 0 0 0.1875rem;
|
|
510
553
|
text-transform: uppercase;
|
|
511
554
|
letter-spacing: 0.04em;
|
|
512
555
|
}
|
|
513
556
|
|
|
557
|
+
.category-nav-subgroup-summary .category-nav-subgroup-label {
|
|
558
|
+
flex: 1;
|
|
559
|
+
min-width: 0;
|
|
560
|
+
margin-bottom: 0;
|
|
561
|
+
}
|
|
562
|
+
|
|
514
563
|
.category-nav-subgroup-pages {
|
|
515
564
|
list-style: none;
|
|
516
565
|
margin: 0;
|
|
@@ -520,6 +569,7 @@ body.specwiki {
|
|
|
520
569
|
|
|
521
570
|
.category-nav-subgroup-pages > li > a {
|
|
522
571
|
color: var(--color-base);
|
|
572
|
+
font-size: var(--font-size-ui-sm);
|
|
523
573
|
}
|
|
524
574
|
|
|
525
575
|
.category-nav-subgroup-nested {
|
|
@@ -527,8 +577,8 @@ body.specwiki {
|
|
|
527
577
|
}
|
|
528
578
|
|
|
529
579
|
.category-nav-subgroup-nested .category-nav-subgroup-label {
|
|
530
|
-
font-weight: var(--font-weight-bold);
|
|
531
|
-
font-size:
|
|
580
|
+
font-weight: var(--font-weight-semi-bold);
|
|
581
|
+
font-size: var(--font-size-caption);
|
|
532
582
|
text-transform: none;
|
|
533
583
|
letter-spacing: normal;
|
|
534
584
|
color: var(--color-base--subtle);
|
|
@@ -545,7 +595,7 @@ body.specwiki {
|
|
|
545
595
|
}
|
|
546
596
|
|
|
547
597
|
.breadcrumb {
|
|
548
|
-
font-size:
|
|
598
|
+
font-size: var(--font-size-ui);
|
|
549
599
|
color: var(--color-base--subtle);
|
|
550
600
|
margin-bottom: var(--padding-horizontal-base);
|
|
551
601
|
}
|
|
@@ -566,7 +616,7 @@ body.specwiki {
|
|
|
566
616
|
border: 1px solid var(--border-color-base);
|
|
567
617
|
background-color: var(--background-color-interactive-subtle);
|
|
568
618
|
padding: var(--padding-vertical-base) var(--padding-horizontal-base);
|
|
569
|
-
font-size:
|
|
619
|
+
font-size: var(--font-size-ui);
|
|
570
620
|
}
|
|
571
621
|
|
|
572
622
|
.infobox-title {
|
|
@@ -596,7 +646,7 @@ body.specwiki {
|
|
|
596
646
|
}
|
|
597
647
|
|
|
598
648
|
.infobox-table code {
|
|
599
|
-
font-size:
|
|
649
|
+
font-size: var(--font-size-ui-sm);
|
|
600
650
|
word-break: break-all;
|
|
601
651
|
}
|
|
602
652
|
|
|
@@ -613,7 +663,7 @@ body.specwiki {
|
|
|
613
663
|
|
|
614
664
|
.toc-heading {
|
|
615
665
|
margin: 0 0 var(--padding-vertical-base);
|
|
616
|
-
font-size:
|
|
666
|
+
font-size: var(--font-size-ui);
|
|
617
667
|
font-weight: var(--font-weight-bold);
|
|
618
668
|
}
|
|
619
669
|
|
|
@@ -630,7 +680,7 @@ body.specwiki {
|
|
|
630
680
|
.toc-list a {
|
|
631
681
|
color: var(--color-primary);
|
|
632
682
|
text-decoration: none;
|
|
633
|
-
font-size:
|
|
683
|
+
font-size: var(--font-size-ui-sm);
|
|
634
684
|
}
|
|
635
685
|
|
|
636
686
|
.toc-list a:hover {
|
|
@@ -653,10 +703,58 @@ body.specwiki {
|
|
|
653
703
|
padding-left: 3rem;
|
|
654
704
|
}
|
|
655
705
|
|
|
656
|
-
.specwiki-
|
|
657
|
-
.mw-parser-output
|
|
658
|
-
|
|
659
|
-
|
|
706
|
+
.specwiki-article-body .mw-parser-output h1,
|
|
707
|
+
.specwiki-article-body .mw-parser-output h2 {
|
|
708
|
+
font-family: var(--font-family-heading-main);
|
|
709
|
+
font-weight: 400;
|
|
710
|
+
line-height: var(--line-height-heading);
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
.specwiki-article-body .mw-parser-output h3,
|
|
714
|
+
.specwiki-article-body .mw-parser-output h4,
|
|
715
|
+
.specwiki-article-body .mw-parser-output h5,
|
|
716
|
+
.specwiki-article-body .mw-parser-output h6 {
|
|
717
|
+
font-family: var(--font-family-system-sans);
|
|
718
|
+
font-weight: 600;
|
|
719
|
+
line-height: var(--line-height-heading);
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
.specwiki-article-body .mw-parser-output h1 {
|
|
723
|
+
font-size: var(--font-size-h1);
|
|
724
|
+
margin: 0 0 0.75rem;
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
.specwiki-article-body .mw-parser-output h2 {
|
|
728
|
+
font-size: var(--font-size-h2);
|
|
729
|
+
margin: 1.5rem 0 0.5rem;
|
|
730
|
+
padding-bottom: 0.15rem;
|
|
731
|
+
border-bottom: 1px solid var(--border-color-divider);
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
.specwiki-article-body .mw-parser-output h3 {
|
|
735
|
+
font-size: var(--font-size-h3);
|
|
736
|
+
margin: 1.25rem 0 0.35rem;
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
.specwiki-article-body .mw-parser-output h4 {
|
|
740
|
+
font-size: var(--font-size-h4);
|
|
741
|
+
margin: 1rem 0 0.35rem;
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
.specwiki-article-body .mw-parser-output h5 {
|
|
745
|
+
font-size: var(--font-size-h5);
|
|
746
|
+
margin: 0.85rem 0 0.25rem;
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
.specwiki-article-body .mw-parser-output h6 {
|
|
750
|
+
font-size: var(--font-size-h6);
|
|
751
|
+
margin: 0.75rem 0 0.25rem;
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
.specwiki-portal h1 {
|
|
755
|
+
font-family: var(--font-family-heading-main);
|
|
756
|
+
font-size: var(--font-size-h1);
|
|
757
|
+
font-weight: 400;
|
|
660
758
|
line-height: var(--line-height-heading);
|
|
661
759
|
}
|
|
662
760
|
|
|
@@ -763,7 +861,7 @@ body.specwiki {
|
|
|
763
861
|
padding: 0.15em 0.4em;
|
|
764
862
|
border-radius: var(--border-radius-base);
|
|
765
863
|
font-size: 0.9em;
|
|
766
|
-
font-family: var(--font-family-monospace);
|
|
864
|
+
font-family: var(--font-family-monospace-brand);
|
|
767
865
|
}
|
|
768
866
|
|
|
769
867
|
.mw-parser-output pre {
|
|
@@ -771,6 +869,7 @@ body.specwiki {
|
|
|
771
869
|
padding: var(--padding-horizontal-base);
|
|
772
870
|
border-radius: var(--border-radius-base);
|
|
773
871
|
overflow-x: auto;
|
|
872
|
+
font-family: var(--font-family-monospace-brand);
|
|
774
873
|
}
|
|
775
874
|
|
|
776
875
|
.mw-parser-output pre code {
|
|
@@ -946,7 +1045,8 @@ body.specwiki {
|
|
|
946
1045
|
|
|
947
1046
|
@media (prefers-reduced-motion: reduce) {
|
|
948
1047
|
.specwiki-nav-drawer,
|
|
949
|
-
.category-nav-group > summary::before
|
|
1048
|
+
.category-nav-group > summary::before,
|
|
1049
|
+
.category-nav-subgroup-group > summary::before {
|
|
950
1050
|
transition: none;
|
|
951
1051
|
}
|
|
952
1052
|
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export interface AgentSkillCatalogEntry {
|
|
2
|
+
skillId: string;
|
|
3
|
+
displayName?: string;
|
|
4
|
+
phase?: string;
|
|
5
|
+
module?: string;
|
|
6
|
+
description?: string;
|
|
7
|
+
isAgent: boolean;
|
|
8
|
+
agentName?: string;
|
|
9
|
+
agentTitle?: string;
|
|
10
|
+
agentIcon?: string;
|
|
11
|
+
/** True when at least one non-_meta CSV row contributed to this entry. */
|
|
12
|
+
inCsv: boolean;
|
|
13
|
+
}
|
|
14
|
+
export interface NavGroupingContext {
|
|
15
|
+
readonly loaded: boolean;
|
|
16
|
+
readonly skillsById: ReadonlyMap<string, AgentSkillCatalogEntry>;
|
|
17
|
+
}
|
|
18
|
+
export declare function loadNavGroupingContext(projectRoot: string): Promise<NavGroupingContext>;
|
|
19
|
+
/** Exported for unit tests — keeps catalog reads under projectRoot. */
|
|
20
|
+
export declare function catalogPath(root: string, ...parts: string[]): string;
|
|
21
|
+
/** Minimal RFC4180 line parser (quoted fields, escaped quotes). */
|
|
22
|
+
export declare function parseCsvLine(line: string): string[];
|
|
23
|
+
interface ParsedSkillToml {
|
|
24
|
+
isAgent: boolean;
|
|
25
|
+
agentName?: string;
|
|
26
|
+
agentTitle?: string;
|
|
27
|
+
agentIcon?: string;
|
|
28
|
+
}
|
|
29
|
+
/** Section detect + scalar extract — not a full TOML AST. */
|
|
30
|
+
export declare function parseSkillCustomizeToml(text: string): ParsedSkillToml;
|
|
31
|
+
export {};
|
|
32
|
+
//# sourceMappingURL=nav-grouping-catalog.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nav-grouping-catalog.d.ts","sourceRoot":"","sources":["../../../src/output/html/nav-grouping-catalog.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0EAA0E;IAC1E,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,WAAW,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC;CAClE;AAqBD,wBAAsB,sBAAsB,CAC1C,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,kBAAkB,CAAC,CA2C7B;AAED,uEAAuE;AACvE,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAOpE;AA0ED,mEAAmE;AACnE,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAqCnD;AAuJD,UAAU,eAAe;IACvB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,6DAA6D;AAC7D,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,CAYrE"}
|
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { log } from "../../core/Logger.js";
|
|
4
|
+
import { assertRealpathConfinedUnder, PathEscapeError, } from "../../core/paths.js";
|
|
5
|
+
const SDLC_PHASES = new Set([
|
|
6
|
+
"1-analysis",
|
|
7
|
+
"2-planning",
|
|
8
|
+
"3-solutioning",
|
|
9
|
+
"4-implementation",
|
|
10
|
+
]);
|
|
11
|
+
function emptyContext() {
|
|
12
|
+
return { loaded: false, skillsById: new Map() };
|
|
13
|
+
}
|
|
14
|
+
export async function loadNavGroupingContext(projectRoot) {
|
|
15
|
+
try {
|
|
16
|
+
const resolvedRoot = path.resolve(projectRoot);
|
|
17
|
+
const csvPath = catalogPath(resolvedRoot, "_bmad", "_config", "bmad-help.csv");
|
|
18
|
+
const csvText = await readConfinedFile(resolvedRoot, csvPath, "bmad-help.csv");
|
|
19
|
+
if (csvText === null) {
|
|
20
|
+
return emptyContext();
|
|
21
|
+
}
|
|
22
|
+
const skillsById = new Map();
|
|
23
|
+
for (const row of parseBmadHelpCsv(csvText)) {
|
|
24
|
+
mergeCsvRow(skillsById, row);
|
|
25
|
+
}
|
|
26
|
+
await enrichFromSkillTomls(resolvedRoot, skillsById);
|
|
27
|
+
let agentCount = 0;
|
|
28
|
+
for (const entry of skillsById.values()) {
|
|
29
|
+
if (entry.isAgent) {
|
|
30
|
+
agentCount += 1;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
log.info("output.write", {
|
|
34
|
+
relativePath: "_bmad/_config/bmad-help.csv",
|
|
35
|
+
skillsLoaded: skillsById.size,
|
|
36
|
+
agentsFound: agentCount,
|
|
37
|
+
});
|
|
38
|
+
return { loaded: true, skillsById };
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
return emptyContext();
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/** Exported for unit tests — keeps catalog reads under projectRoot. */
|
|
45
|
+
export function catalogPath(root, ...parts) {
|
|
46
|
+
const resolved = path.resolve(root, ...parts);
|
|
47
|
+
const relative = path.relative(root, resolved);
|
|
48
|
+
if (relative.startsWith("..") || path.isAbsolute(relative)) {
|
|
49
|
+
throw new Error("catalog path escapes project root");
|
|
50
|
+
}
|
|
51
|
+
return resolved;
|
|
52
|
+
}
|
|
53
|
+
async function readConfinedFile(projectRoot, targetPath, label) {
|
|
54
|
+
try {
|
|
55
|
+
await assertRealpathConfinedUnder(projectRoot, targetPath, label);
|
|
56
|
+
}
|
|
57
|
+
catch (err) {
|
|
58
|
+
if (err instanceof PathEscapeError) {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
throw err;
|
|
62
|
+
}
|
|
63
|
+
try {
|
|
64
|
+
return await fs.readFile(targetPath, "utf-8");
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
function descriptionLooksDeprecated(description) {
|
|
71
|
+
return (description ?? "").toLowerCase().includes("deprecated");
|
|
72
|
+
}
|
|
73
|
+
function parseBmadHelpCsv(text) {
|
|
74
|
+
const lines = text.split(/\r?\n/);
|
|
75
|
+
const headerFields = parseCsvLine(lines[0] || "");
|
|
76
|
+
const index = {
|
|
77
|
+
module: headerFields.indexOf("module"),
|
|
78
|
+
skill: headerFields.indexOf("skill"),
|
|
79
|
+
displayName: headerFields.indexOf("display-name"),
|
|
80
|
+
description: headerFields.indexOf("description"),
|
|
81
|
+
phase: headerFields.indexOf("phase"),
|
|
82
|
+
};
|
|
83
|
+
if (index.skill < 0) {
|
|
84
|
+
return [];
|
|
85
|
+
}
|
|
86
|
+
const rows = [];
|
|
87
|
+
for (let i = 1; i < lines.length; i++) {
|
|
88
|
+
const line = lines[i];
|
|
89
|
+
if (!line.trim()) {
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
const fields = parseCsvLine(line);
|
|
93
|
+
const skill = (fields[index.skill] || "").trim();
|
|
94
|
+
if (!skill || skill === "_meta") {
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
rows.push({
|
|
98
|
+
module: fieldAt(fields, index.module),
|
|
99
|
+
skill,
|
|
100
|
+
displayName: fieldAt(fields, index.displayName),
|
|
101
|
+
description: fieldAt(fields, index.description),
|
|
102
|
+
phase: fieldAt(fields, index.phase),
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
return rows;
|
|
106
|
+
}
|
|
107
|
+
function fieldAt(fields, index) {
|
|
108
|
+
if (index < 0 || index >= fields.length) {
|
|
109
|
+
return "";
|
|
110
|
+
}
|
|
111
|
+
return fields[index].trim();
|
|
112
|
+
}
|
|
113
|
+
/** Minimal RFC4180 line parser (quoted fields, escaped quotes). */
|
|
114
|
+
export function parseCsvLine(line) {
|
|
115
|
+
const fields = [];
|
|
116
|
+
let current = "";
|
|
117
|
+
let inQuotes = false;
|
|
118
|
+
for (let i = 0; i < line.length; i++) {
|
|
119
|
+
const ch = line[i];
|
|
120
|
+
if (inQuotes) {
|
|
121
|
+
if (ch === '"') {
|
|
122
|
+
if (line[i + 1] === '"') {
|
|
123
|
+
current += '"';
|
|
124
|
+
i += 1;
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
inQuotes = false;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
current += ch;
|
|
132
|
+
}
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
if (ch === '"') {
|
|
136
|
+
inQuotes = true;
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
if (ch === ",") {
|
|
140
|
+
fields.push(current);
|
|
141
|
+
current = "";
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
current += ch;
|
|
145
|
+
}
|
|
146
|
+
fields.push(current);
|
|
147
|
+
return fields;
|
|
148
|
+
}
|
|
149
|
+
function csvRowScore(row) {
|
|
150
|
+
let score = 0;
|
|
151
|
+
if (SDLC_PHASES.has(row.phase)) {
|
|
152
|
+
score += 100;
|
|
153
|
+
}
|
|
154
|
+
else if (row.phase === "anytime") {
|
|
155
|
+
score += 10;
|
|
156
|
+
}
|
|
157
|
+
if (row.module.includes("BMad Method") ||
|
|
158
|
+
(row.module && row.module !== "Core")) {
|
|
159
|
+
score += 5;
|
|
160
|
+
}
|
|
161
|
+
else if (row.module === "Core") {
|
|
162
|
+
score += 1;
|
|
163
|
+
}
|
|
164
|
+
return score;
|
|
165
|
+
}
|
|
166
|
+
function mergeCsvRow(skillsById, row) {
|
|
167
|
+
const existing = skillsById.get(row.skill);
|
|
168
|
+
if (!existing) {
|
|
169
|
+
skillsById.set(row.skill, {
|
|
170
|
+
skillId: row.skill,
|
|
171
|
+
displayName: row.displayName || undefined,
|
|
172
|
+
phase: row.phase || undefined,
|
|
173
|
+
module: row.module || undefined,
|
|
174
|
+
description: row.description || undefined,
|
|
175
|
+
isAgent: false,
|
|
176
|
+
inCsv: true,
|
|
177
|
+
});
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
const existingAsRow = {
|
|
181
|
+
module: existing.module || "",
|
|
182
|
+
skill: existing.skillId,
|
|
183
|
+
displayName: existing.displayName || "",
|
|
184
|
+
description: existing.description || "",
|
|
185
|
+
phase: existing.phase || "",
|
|
186
|
+
};
|
|
187
|
+
const priorDeprecatedDescription = descriptionLooksDeprecated(existing.description)
|
|
188
|
+
? existing.description
|
|
189
|
+
: undefined;
|
|
190
|
+
if (csvRowScore(row) > csvRowScore(existingAsRow)) {
|
|
191
|
+
if (row.displayName) {
|
|
192
|
+
existing.displayName = row.displayName;
|
|
193
|
+
}
|
|
194
|
+
if (row.phase) {
|
|
195
|
+
existing.phase = row.phase;
|
|
196
|
+
}
|
|
197
|
+
if (row.module) {
|
|
198
|
+
existing.module = row.module;
|
|
199
|
+
}
|
|
200
|
+
if (row.description) {
|
|
201
|
+
existing.description = row.description;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
// Any CSV row marking DEPRECATED wins membership, even on score ties / losses.
|
|
205
|
+
if (descriptionLooksDeprecated(row.description)) {
|
|
206
|
+
existing.description = row.description;
|
|
207
|
+
}
|
|
208
|
+
else if (priorDeprecatedDescription) {
|
|
209
|
+
existing.description = priorDeprecatedDescription;
|
|
210
|
+
}
|
|
211
|
+
existing.inCsv = true;
|
|
212
|
+
}
|
|
213
|
+
async function enrichFromSkillTomls(projectRoot, skillsById) {
|
|
214
|
+
const skillsDir = catalogPath(projectRoot, ".agents", "skills");
|
|
215
|
+
try {
|
|
216
|
+
await assertRealpathConfinedUnder(projectRoot, skillsDir, "agent skills directory");
|
|
217
|
+
}
|
|
218
|
+
catch (err) {
|
|
219
|
+
if (err instanceof PathEscapeError) {
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
throw err;
|
|
223
|
+
}
|
|
224
|
+
let entries;
|
|
225
|
+
try {
|
|
226
|
+
entries = await fs.readdir(skillsDir);
|
|
227
|
+
}
|
|
228
|
+
catch {
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
for (const skillId of entries) {
|
|
232
|
+
let tomlPath;
|
|
233
|
+
try {
|
|
234
|
+
tomlPath = catalogPath(projectRoot, ".agents", "skills", skillId, "customize.toml");
|
|
235
|
+
}
|
|
236
|
+
catch {
|
|
237
|
+
continue;
|
|
238
|
+
}
|
|
239
|
+
const tomlText = await readConfinedFile(projectRoot, tomlPath, `customize.toml (${skillId})`);
|
|
240
|
+
if (tomlText === null) {
|
|
241
|
+
continue;
|
|
242
|
+
}
|
|
243
|
+
const parsed = parseSkillCustomizeToml(tomlText);
|
|
244
|
+
const existing = skillsById.get(skillId);
|
|
245
|
+
if (existing) {
|
|
246
|
+
if (parsed.isAgent) {
|
|
247
|
+
existing.isAgent = true;
|
|
248
|
+
existing.agentName = parsed.agentName;
|
|
249
|
+
existing.agentTitle = parsed.agentTitle;
|
|
250
|
+
existing.agentIcon = parsed.agentIcon;
|
|
251
|
+
}
|
|
252
|
+
continue;
|
|
253
|
+
}
|
|
254
|
+
if (parsed.isAgent) {
|
|
255
|
+
skillsById.set(skillId, {
|
|
256
|
+
skillId,
|
|
257
|
+
isAgent: true,
|
|
258
|
+
agentName: parsed.agentName,
|
|
259
|
+
agentTitle: parsed.agentTitle,
|
|
260
|
+
agentIcon: parsed.agentIcon,
|
|
261
|
+
inCsv: false,
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
/** Section detect + scalar extract — not a full TOML AST. */
|
|
267
|
+
export function parseSkillCustomizeToml(text) {
|
|
268
|
+
if (!/^\s*\[agent\]\s*$/m.test(text)) {
|
|
269
|
+
return { isAgent: false };
|
|
270
|
+
}
|
|
271
|
+
const agentBody = extractTomlSection(text, "agent");
|
|
272
|
+
return {
|
|
273
|
+
isAgent: true,
|
|
274
|
+
agentName: extractTomlString(agentBody, "name"),
|
|
275
|
+
agentTitle: extractTomlString(agentBody, "title"),
|
|
276
|
+
agentIcon: extractTomlString(agentBody, "icon"),
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
function extractTomlSection(text, section) {
|
|
280
|
+
const header = new RegExp(String.raw `^\s*\[${section}\]\s*(?:\r?\n|$)`, "m").exec(text);
|
|
281
|
+
if (!header) {
|
|
282
|
+
return "";
|
|
283
|
+
}
|
|
284
|
+
const rest = text.slice(header.index + header[0].length);
|
|
285
|
+
const nextHeader = rest.search(/^\s*\[[^\]]+\]\s*$/m);
|
|
286
|
+
return nextHeader === -1 ? rest : rest.slice(0, nextHeader);
|
|
287
|
+
}
|
|
288
|
+
function extractTomlString(sectionBody, key) {
|
|
289
|
+
const pattern = new RegExp(String.raw `^\s*${key}\s*=\s*(?:"([^"]*)"|'([^']*)')\s*$`, "m");
|
|
290
|
+
const match = sectionBody.match(pattern);
|
|
291
|
+
const value = match?.[1] ?? match?.[2];
|
|
292
|
+
return value ? value : undefined;
|
|
293
|
+
}
|
|
294
|
+
//# sourceMappingURL=nav-grouping-catalog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nav-grouping-catalog.js","sourceRoot":"","sources":["../../../src/output/html/nav-grouping-catalog.ts"],"names":[],"mappings":"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"}
|