@lucasviola/specwiki 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +227 -0
  3. package/dist/cli.d.ts +3 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +226 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/commands/generate.d.ts +5 -0
  8. package/dist/commands/generate.d.ts.map +1 -0
  9. package/dist/commands/generate.js +197 -0
  10. package/dist/commands/generate.js.map +1 -0
  11. package/dist/commands/init.d.ts +5 -0
  12. package/dist/commands/init.d.ts.map +1 -0
  13. package/dist/commands/init.js +91 -0
  14. package/dist/commands/init.js.map +1 -0
  15. package/dist/commands/open.d.ts +8 -0
  16. package/dist/commands/open.d.ts.map +1 -0
  17. package/dist/commands/open.js +150 -0
  18. package/dist/commands/open.js.map +1 -0
  19. package/dist/config/loader.d.ts +20 -0
  20. package/dist/config/loader.d.ts.map +1 -0
  21. package/dist/config/loader.js +143 -0
  22. package/dist/config/loader.js.map +1 -0
  23. package/dist/config/patterns.d.ts +9 -0
  24. package/dist/config/patterns.d.ts.map +1 -0
  25. package/dist/config/patterns.js +159 -0
  26. package/dist/config/patterns.js.map +1 -0
  27. package/dist/core/Logger.d.ts +8 -0
  28. package/dist/core/Logger.d.ts.map +1 -0
  29. package/dist/core/Logger.js +33 -0
  30. package/dist/core/Logger.js.map +1 -0
  31. package/dist/core/paths.d.ts +8 -0
  32. package/dist/core/paths.d.ts.map +1 -0
  33. package/dist/core/paths.js +45 -0
  34. package/dist/core/paths.js.map +1 -0
  35. package/dist/discover/specs.d.ts +11 -0
  36. package/dist/discover/specs.d.ts.map +1 -0
  37. package/dist/discover/specs.js +157 -0
  38. package/dist/discover/specs.js.map +1 -0
  39. package/dist/output/html/assets/highlight.css +101 -0
  40. package/dist/output/html/assets/search.js +368 -0
  41. package/dist/output/html/assets/specwiki.css +905 -0
  42. package/dist/output/html/renderer.d.ts +21 -0
  43. package/dist/output/html/renderer.d.ts.map +1 -0
  44. package/dist/output/html/renderer.js +203 -0
  45. package/dist/output/html/renderer.js.map +1 -0
  46. package/dist/output/html/search-index.d.ts +20 -0
  47. package/dist/output/html/search-index.d.ts.map +1 -0
  48. package/dist/output/html/search-index.js +46 -0
  49. package/dist/output/html/search-index.js.map +1 -0
  50. package/dist/output/html/templates/article.mustache +85 -0
  51. package/dist/output/html/templates/index.mustache +80 -0
  52. package/dist/output/html/templates/layout.mustache +205 -0
  53. package/dist/output/llms.d.ts +4 -0
  54. package/dist/output/llms.d.ts.map +1 -0
  55. package/dist/output/llms.js +44 -0
  56. package/dist/output/llms.js.map +1 -0
  57. package/dist/output/readme-index.d.ts +17 -0
  58. package/dist/output/readme-index.d.ts.map +1 -0
  59. package/dist/output/readme-index.js +71 -0
  60. package/dist/output/readme-index.js.map +1 -0
  61. package/dist/output/wiki.d.ts +11 -0
  62. package/dist/output/wiki.d.ts.map +1 -0
  63. package/dist/output/wiki.js +400 -0
  64. package/dist/output/wiki.js.map +1 -0
  65. package/dist/parse/markdown.d.ts +6 -0
  66. package/dist/parse/markdown.d.ts.map +1 -0
  67. package/dist/parse/markdown.js +225 -0
  68. package/dist/parse/markdown.js.map +1 -0
  69. package/dist/types.d.ts +96 -0
  70. package/dist/types.d.ts.map +1 -0
  71. package/dist/types.js +2 -0
  72. package/dist/types.js.map +1 -0
  73. package/package.json +67 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/config/loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Default glob patterns for discovering AI spec files across common
3
+ * frameworks, agent configs, and spec-driven development layouts.
4
+ */
5
+ export declare const DEFAULT_SPEC_PATTERNS: string[];
6
+ export declare function validatePatternList(patterns: string[]): string[];
7
+ export declare function parsePatternList(value: string): string[];
8
+ export declare const CATEGORY_LABELS: Record<string, string>;
9
+ //# sourceMappingURL=patterns.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"patterns.d.ts","sourceRoot":"","sources":["../../src/config/patterns.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,qBAAqB,UAkCjC,CAAC;AAwEF,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAYhE;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAsDxD;AAED,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAelD,CAAC"}
@@ -0,0 +1,159 @@
1
+ /**
2
+ * Default glob patterns for discovering AI spec files across common
3
+ * frameworks, agent configs, and spec-driven development layouts.
4
+ */
5
+ export const DEFAULT_SPEC_PATTERNS = [
6
+ // Root-level agent / spec files
7
+ "AGENTS.md",
8
+ "SPEC.md",
9
+ "CLAUDE.md",
10
+ "GEMINI.md",
11
+ "llms.txt",
12
+ // Cursor rules
13
+ ".cursor/rules/**/*.{md,mdc}",
14
+ ".cursor/skills/**/SKILL.md",
15
+ // Spec-driven frameworks
16
+ "specs/**/*.{md,mdc}",
17
+ "spec/**/*.{md,mdc}",
18
+ "openspec/**/*.{md,mdc}",
19
+ ".kiro/specs/**/*.{md,mdc}",
20
+ "docs/specs/**/*.{md,mdc}",
21
+ "requirements/**/*.{md,mdc}",
22
+ // Agent transcripts and plans (optional but useful)
23
+ "docs/plans/**/*.{md,mdc}",
24
+ // GitHub Copilot
25
+ ".github/copilot-instructions.md",
26
+ // Extended POST-MVP discovery (S8.3)
27
+ "**/AGENTS.md",
28
+ "_bmad-output/**/*.md",
29
+ ".agents/skills/**/SKILL.md",
30
+ "**/README.md",
31
+ // Broad markdown discovery (S17.1)
32
+ "**/*.{md,mdc}",
33
+ ];
34
+ const EMPTY_PATTERNS_MESSAGE = "Patterns must be a comma-separated list of non-empty globs";
35
+ const UNBALANCED_PATTERNS_MESSAGE = "Patterns must use balanced glob delimiters";
36
+ const OUTSIDE_PROJECT_PATTERNS_MESSAGE = "Patterns must stay within the project root";
37
+ const CLOSING_DELIMITERS = {
38
+ "}": "{",
39
+ "]": "[",
40
+ ")": "(",
41
+ };
42
+ function escapesProjectRoot(pattern) {
43
+ const candidate = pattern.startsWith("!") && !pattern.startsWith("!(")
44
+ ? pattern.slice(1)
45
+ : pattern;
46
+ const normalized = candidate.replace(/\\/g, "/");
47
+ return (/(?:^|[,{(|])(?:\/|[A-Za-z]:\/)/.test(normalized) ||
48
+ /(?:^|[/{,(|])\.\.(?:\/|[},)|]|$)/.test(normalized));
49
+ }
50
+ function validateSinglePattern(pattern) {
51
+ if (pattern.length === 0) {
52
+ throw new Error(EMPTY_PATTERNS_MESSAGE);
53
+ }
54
+ const delimiters = [];
55
+ let escaped = false;
56
+ for (const character of pattern) {
57
+ if (escaped) {
58
+ if (delimiters.at(-1) === CLOSING_DELIMITERS[character]) {
59
+ delimiters.pop();
60
+ }
61
+ escaped = false;
62
+ continue;
63
+ }
64
+ if (character === "\\") {
65
+ escaped = true;
66
+ continue;
67
+ }
68
+ if (character === "{" || character === "[" || character === "(") {
69
+ delimiters.push(character);
70
+ continue;
71
+ }
72
+ if (character === "}" || character === "]" || character === ")") {
73
+ const expectedOpening = CLOSING_DELIMITERS[character];
74
+ const activeOpening = delimiters.at(-1);
75
+ if (activeOpening === expectedOpening) {
76
+ delimiters.pop();
77
+ }
78
+ }
79
+ }
80
+ if (delimiters.length > 0) {
81
+ throw new Error(UNBALANCED_PATTERNS_MESSAGE);
82
+ }
83
+ if (escapesProjectRoot(pattern)) {
84
+ throw new Error(OUTSIDE_PROJECT_PATTERNS_MESSAGE);
85
+ }
86
+ }
87
+ export function validatePatternList(patterns) {
88
+ const normalized = patterns.map((pattern) => pattern.trim());
89
+ if (normalized.length === 0) {
90
+ throw new Error(EMPTY_PATTERNS_MESSAGE);
91
+ }
92
+ for (const pattern of normalized) {
93
+ validateSinglePattern(pattern);
94
+ }
95
+ return normalized;
96
+ }
97
+ export function parsePatternList(value) {
98
+ const patterns = [];
99
+ const delimiters = [];
100
+ let current = "";
101
+ let escaped = false;
102
+ for (const character of value) {
103
+ if (escaped) {
104
+ if (delimiters.at(-1) === CLOSING_DELIMITERS[character]) {
105
+ delimiters.pop();
106
+ }
107
+ current += character;
108
+ escaped = false;
109
+ continue;
110
+ }
111
+ if (character === "\\") {
112
+ current += character;
113
+ escaped = true;
114
+ continue;
115
+ }
116
+ if (character === "{" || character === "[" || character === "(") {
117
+ delimiters.push(character);
118
+ current += character;
119
+ continue;
120
+ }
121
+ if (character === "}" || character === "]" || character === ")") {
122
+ const expectedOpening = CLOSING_DELIMITERS[character];
123
+ const activeOpening = delimiters.at(-1);
124
+ if (activeOpening === expectedOpening) {
125
+ delimiters.pop();
126
+ }
127
+ current += character;
128
+ continue;
129
+ }
130
+ if (character === "," && delimiters.length === 0) {
131
+ patterns.push(current.trim());
132
+ current = "";
133
+ continue;
134
+ }
135
+ current += character;
136
+ }
137
+ if (delimiters.length > 0) {
138
+ throw new Error(UNBALANCED_PATTERNS_MESSAGE);
139
+ }
140
+ patterns.push(current.trim());
141
+ return validatePatternList(patterns);
142
+ }
143
+ export const CATEGORY_LABELS = {
144
+ root: "Project Root",
145
+ "cursor-rules": "Cursor Rules",
146
+ "cursor-skills": "Cursor Skills",
147
+ specs: "Specifications",
148
+ spec: "Specifications",
149
+ openspec: "OpenSpec",
150
+ kiro: "Kiro Specs",
151
+ "docs-specs": "Documentation Specs",
152
+ requirements: "Requirements",
153
+ plans: "Plans",
154
+ github: "GitHub",
155
+ "bmad-output": "BMAD Output",
156
+ "agent-skills": "Agent Skills",
157
+ other: "Other",
158
+ };
159
+ //# sourceMappingURL=patterns.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"patterns.js","sourceRoot":"","sources":["../../src/config/patterns.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ type LogPayload = Record<string, unknown>;
2
+ export declare const log: {
3
+ setVerbose(enabled: boolean): void;
4
+ info(event: string, payload?: LogPayload): void;
5
+ error(event: string, payload?: LogPayload): void;
6
+ };
7
+ export {};
8
+ //# sourceMappingURL=Logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Logger.d.ts","sourceRoot":"","sources":["../../src/core/Logger.ts"],"names":[],"mappings":"AAAA,KAAK,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAgC1C,eAAO,MAAM,GAAG;wBACM,OAAO,GAAG,IAAI;gBAItB,MAAM,YAAW,UAAU,GAAQ,IAAI;iBAOtC,MAAM,YAAW,UAAU,GAAQ,IAAI;CAGrD,CAAC"}
@@ -0,0 +1,33 @@
1
+ let verbose = false;
2
+ function serializeLogLine(level, event, payload) {
3
+ const record = { ...payload, event, level };
4
+ try {
5
+ return JSON.stringify(record) + "\n";
6
+ }
7
+ catch {
8
+ return (JSON.stringify({
9
+ event,
10
+ level,
11
+ serializationError: true,
12
+ message: "log payload could not be serialized",
13
+ }) + "\n");
14
+ }
15
+ }
16
+ function writeLog(level, event, payload) {
17
+ process.stderr.write(serializeLogLine(level, event, payload));
18
+ }
19
+ export const log = {
20
+ setVerbose(enabled) {
21
+ verbose = enabled;
22
+ },
23
+ info(event, payload = {}) {
24
+ if (!verbose) {
25
+ return;
26
+ }
27
+ writeLog("info", event, payload);
28
+ },
29
+ error(event, payload = {}) {
30
+ writeLog("error", event, payload);
31
+ },
32
+ };
33
+ //# sourceMappingURL=Logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Logger.js","sourceRoot":"","sources":["../../src/core/Logger.ts"],"names":[],"mappings":"AAEA,IAAI,OAAO,GAAG,KAAK,CAAC;AAEpB,SAAS,gBAAgB,CACvB,KAAuB,EACvB,KAAa,EACb,OAAmB;IAEnB,MAAM,MAAM,GAAG,EAAE,GAAG,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;IAC5C,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;IACvC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CACL,IAAI,CAAC,SAAS,CAAC;YACb,KAAK;YACL,KAAK;YACL,kBAAkB,EAAE,IAAI;YACxB,OAAO,EAAE,qCAAqC;SAC/C,CAAC,GAAG,IAAI,CACV,CAAC;IACJ,CAAC;AACH,CAAC;AAED,SAAS,QAAQ,CACf,KAAuB,EACvB,KAAa,EACb,OAAmB;IAEnB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC;AAChE,CAAC;AAED,MAAM,CAAC,MAAM,GAAG,GAAG;IACjB,UAAU,CAAC,OAAgB;QACzB,OAAO,GAAG,OAAO,CAAC;IACpB,CAAC;IAED,IAAI,CAAC,KAAa,EAAE,UAAsB,EAAE;QAC1C,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO;QACT,CAAC;QACD,QAAQ,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;IACnC,CAAC;IAED,KAAK,CAAC,KAAa,EAAE,UAAsB,EAAE;QAC3C,QAAQ,CAAC,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;IACpC,CAAC;CACF,CAAC"}
@@ -0,0 +1,8 @@
1
+ export declare class PathEscapeError extends Error {
2
+ readonly label: string;
3
+ constructor(label: string);
4
+ }
5
+ export declare function assertConfinedUnder(root: string, target: string, label: string): void;
6
+ export declare function assertRealpathConfinedUnder(root: string, target: string, label: string): Promise<void>;
7
+ export declare function resolveOutputWithinProject(projectRoot: string, outputDir: string): Promise<string>;
8
+ //# sourceMappingURL=paths.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/core/paths.ts"],"names":[],"mappings":"AAGA,qBAAa,eAAgB,SAAQ,KAAK;IACxC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;gBAEX,KAAK,EAAE,MAAM;CAK1B;AAED,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GACZ,IAAI,CAQN;AAED,wBAAsB,2BAA2B,CAC/C,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,IAAI,CAAC,CAkBf;AAED,wBAAsB,0BAA0B,CAC9C,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,MAAM,CAAC,CAYjB"}
@@ -0,0 +1,45 @@
1
+ import fs from "node:fs/promises";
2
+ import path from "node:path";
3
+ export class PathEscapeError extends Error {
4
+ label;
5
+ constructor(label) {
6
+ super("Output directory must stay within project root");
7
+ this.name = "PathEscapeError";
8
+ this.label = label;
9
+ }
10
+ }
11
+ export function assertConfinedUnder(root, target, label) {
12
+ const resolvedRoot = path.resolve(root);
13
+ const resolvedTarget = path.resolve(target);
14
+ const relative = path.relative(resolvedRoot, resolvedTarget);
15
+ if (relative.startsWith("..") || path.isAbsolute(relative)) {
16
+ throw new PathEscapeError(label);
17
+ }
18
+ }
19
+ export async function assertRealpathConfinedUnder(root, target, label) {
20
+ try {
21
+ const realRoot = await fs.realpath(root);
22
+ const realTarget = await fs.realpath(target);
23
+ const relative = path.relative(realRoot, realTarget);
24
+ if (relative.startsWith("..") || path.isAbsolute(relative)) {
25
+ throw new PathEscapeError(label);
26
+ }
27
+ }
28
+ catch (err) {
29
+ if (err.code === "ENOENT") {
30
+ return;
31
+ }
32
+ if (err instanceof PathEscapeError) {
33
+ throw err;
34
+ }
35
+ throw err;
36
+ }
37
+ }
38
+ export async function resolveOutputWithinProject(projectRoot, outputDir) {
39
+ const resolvedProjectRoot = path.resolve(projectRoot);
40
+ const resolvedOutput = path.resolve(resolvedProjectRoot, outputDir);
41
+ assertConfinedUnder(resolvedProjectRoot, resolvedOutput, "output directory");
42
+ await assertRealpathConfinedUnder(resolvedProjectRoot, resolvedOutput, "output directory");
43
+ return resolvedOutput;
44
+ }
45
+ //# sourceMappingURL=paths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/core/paths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,MAAM,OAAO,eAAgB,SAAQ,KAAK;IAC/B,KAAK,CAAS;IAEvB,YAAY,KAAa;QACvB,KAAK,CAAC,gDAAgD,CAAC,CAAC;QACxD,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;QAC9B,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;CACF;AAED,MAAM,UAAU,mBAAmB,CACjC,IAAY,EACZ,MAAc,EACd,KAAa;IAEb,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5C,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,YAAY,EAAE,cAAc,CAAC,CAAC;IAE7D,IAAI,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC3D,MAAM,IAAI,eAAe,CAAC,KAAK,CAAC,CAAC;IACnC,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAC/C,IAAY,EACZ,MAAc,EACd,KAAa;IAEb,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACzC,MAAM,UAAU,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC7C,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;QAErD,IAAI,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC3D,MAAM,IAAI,eAAe,CAAC,KAAK,CAAC,CAAC;QACnC,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACrD,OAAO;QACT,CAAC;QACD,IAAI,GAAG,YAAY,eAAe,EAAE,CAAC;YACnC,MAAM,GAAG,CAAC;QACZ,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAC9C,WAAmB,EACnB,SAAiB;IAEjB,MAAM,mBAAmB,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IACtD,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,mBAAmB,EAAE,SAAS,CAAC,CAAC;IAEpE,mBAAmB,CAAC,mBAAmB,EAAE,cAAc,EAAE,kBAAkB,CAAC,CAAC;IAC7E,MAAM,2BAA2B,CAC/B,mBAAmB,EACnB,cAAc,EACd,kBAAkB,CACnB,CAAC;IAEF,OAAO,cAAc,CAAC;AACxB,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { DiscoverOptions, SpecFile } from "../types.js";
2
+ /** Match count above which verbose mode emits a performance heads-up. */
3
+ export declare const LARGE_SET_THRESHOLD = 500;
4
+ /** Path-prefix category for discovery and list grouping. Exported for tests. */
5
+ export declare function deriveCategory(relativePath: string): string;
6
+ /** Human-readable title from basename; special cases for agent/skill files. Exported for tests. */
7
+ export declare function deriveTitle(relativePath: string): string;
8
+ /** Build fast-glob ignore list, optionally excluding project-relative output dirs. */
9
+ export declare function buildDiscoveryIgnores(ignorePaths?: string[]): string[];
10
+ export declare function discoverSpecs(options: DiscoverOptions): Promise<SpecFile[]>;
11
+ //# sourceMappingURL=specs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"specs.d.ts","sourceRoot":"","sources":["../../src/discover/specs.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE7D,yEAAyE;AACzE,eAAO,MAAM,mBAAmB,MAAM,CAAC;AAEvC,gFAAgF;AAChF,wBAAgB,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAkB3D;AAED,mGAAmG;AACnG,wBAAgB,WAAW,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAoBxD;AAaD,sFAAsF;AACtF,wBAAgB,qBAAqB,CAAC,WAAW,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAiBtE;AAED,wBAAsB,aAAa,CACjC,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,QAAQ,EAAE,CAAC,CA8ErB"}
@@ -0,0 +1,157 @@
1
+ import fg from "fast-glob";
2
+ import path from "node:path";
3
+ import { DEFAULT_SPEC_PATTERNS } from "../config/patterns.js";
4
+ import { log } from "../core/Logger.js";
5
+ /** Match count above which verbose mode emits a performance heads-up. */
6
+ export const LARGE_SET_THRESHOLD = 500;
7
+ /** Path-prefix category for discovery and list grouping. Exported for tests. */
8
+ export function deriveCategory(relativePath) {
9
+ const normalized = relativePath.replace(/\\/g, "/");
10
+ if (!normalized.includes("/"))
11
+ return "root";
12
+ if (normalized.startsWith(".cursor/rules/"))
13
+ return "cursor-rules";
14
+ if (normalized.startsWith(".cursor/skills/"))
15
+ return "cursor-skills";
16
+ if (normalized.startsWith("specs/"))
17
+ return "specs";
18
+ if (normalized.startsWith("spec/"))
19
+ return "spec";
20
+ if (normalized.startsWith("openspec/"))
21
+ return "openspec";
22
+ if (normalized.startsWith(".kiro/specs/"))
23
+ return "kiro";
24
+ if (normalized.startsWith("docs/specs/"))
25
+ return "docs-specs";
26
+ if (normalized.startsWith("docs/plans/"))
27
+ return "plans";
28
+ if (normalized.startsWith("requirements/"))
29
+ return "requirements";
30
+ if (normalized.startsWith(".github/"))
31
+ return "github";
32
+ if (normalized.startsWith("_bmad-output/"))
33
+ return "bmad-output";
34
+ if (normalized.startsWith(".agents/skills/"))
35
+ return "agent-skills";
36
+ return "other";
37
+ }
38
+ /** Human-readable title from basename; special cases for agent/skill files. Exported for tests. */
39
+ export function deriveTitle(relativePath) {
40
+ const basename = path.basename(relativePath, path.extname(relativePath));
41
+ if (basename === "SKILL") {
42
+ const parent = path.basename(path.dirname(relativePath));
43
+ return parent
44
+ .split("-")
45
+ .map((w) => w.charAt(0).toUpperCase() + w.slice(1))
46
+ .join(" ");
47
+ }
48
+ if (basename === "AGENTS")
49
+ return "Agent Instructions";
50
+ if (basename === "SPEC")
51
+ return "Project Specification";
52
+ if (basename === "CLAUDE")
53
+ return "Claude Instructions";
54
+ if (basename === "GEMINI")
55
+ return "Gemini Instructions";
56
+ if (basename === "README")
57
+ return "Readme";
58
+ return basename
59
+ .replace(/[-_]/g, " ")
60
+ .replace(/\b\w/g, (c) => c.toUpperCase());
61
+ }
62
+ const STATIC_DISCOVERY_IGNORES = [
63
+ "**/.git/**",
64
+ "**/node_modules/**",
65
+ "**/dist/**",
66
+ "**/wiki/**",
67
+ "**/.specwiki/**",
68
+ "**/coverage/**",
69
+ "**/.venv/**",
70
+ "**/vendor/**",
71
+ ];
72
+ /** Build fast-glob ignore list, optionally excluding project-relative output dirs. */
73
+ export function buildDiscoveryIgnores(ignorePaths) {
74
+ const ignores = [...STATIC_DISCOVERY_IGNORES];
75
+ for (const ignorePath of ignorePaths ?? []) {
76
+ const normalized = ignorePath.replace(/\\/g, "/").replace(/\/$/, "");
77
+ if (normalized.length === 0 ||
78
+ normalized === "." ||
79
+ normalized === ".." ||
80
+ normalized.startsWith("../")) {
81
+ continue;
82
+ }
83
+ ignores.push(`${normalized}/**`);
84
+ }
85
+ return ignores;
86
+ }
87
+ export async function discoverSpecs(options) {
88
+ const patterns = options.patterns ?? DEFAULT_SPEC_PATTERNS;
89
+ log.info("discover.start", {
90
+ projectRoot: options.projectRoot,
91
+ patternCount: patterns.length,
92
+ });
93
+ let entries;
94
+ try {
95
+ entries = await fg(patterns, {
96
+ cwd: options.projectRoot,
97
+ absolute: true,
98
+ onlyFiles: true,
99
+ dot: true,
100
+ ignore: buildDiscoveryIgnores(options.ignorePaths),
101
+ });
102
+ }
103
+ catch (err) {
104
+ log.error("discover.error", {
105
+ projectRoot: options.projectRoot,
106
+ message: err instanceof Error ? err.message : String(err),
107
+ });
108
+ throw err;
109
+ }
110
+ for (const filePath of entries) {
111
+ const relativePath = path.relative(options.projectRoot, filePath);
112
+ if (relativePath === ".." ||
113
+ relativePath.startsWith(`..${path.sep}`) ||
114
+ path.isAbsolute(relativePath)) {
115
+ const message = "Discovered path is outside the project root";
116
+ log.error("discover.error", {
117
+ projectRoot: options.projectRoot,
118
+ message,
119
+ });
120
+ throw new Error(message);
121
+ }
122
+ }
123
+ const specs = entries
124
+ .map((filePath) => {
125
+ const relativePath = path.relative(options.projectRoot, filePath);
126
+ return {
127
+ path: filePath,
128
+ relativePath,
129
+ category: deriveCategory(relativePath),
130
+ title: deriveTitle(relativePath),
131
+ };
132
+ })
133
+ .sort((a, b) => {
134
+ const catCompare = a.category.localeCompare(b.category);
135
+ if (catCompare !== 0)
136
+ return catCompare;
137
+ return a.relativePath.localeCompare(b.relativePath);
138
+ });
139
+ for (const spec of specs) {
140
+ log.info("discover.match", { relativePath: spec.relativePath });
141
+ }
142
+ if (specs.length === 0) {
143
+ log.info("discover.empty", {
144
+ projectRoot: options.projectRoot,
145
+ patternCount: patterns.length,
146
+ });
147
+ }
148
+ log.info("discover.complete", {
149
+ projectRoot: options.projectRoot,
150
+ matchCount: specs.length,
151
+ });
152
+ if (specs.length > LARGE_SET_THRESHOLD) {
153
+ log.info("discover.large-set", { matchCount: specs.length });
154
+ }
155
+ return specs;
156
+ }
157
+ //# sourceMappingURL=specs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"specs.js","sourceRoot":"","sources":["../../src/discover/specs.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,101 @@
1
+ pre code.hljs {
2
+ display: block;
3
+ overflow-x: auto;
4
+ padding: 1em;
5
+ }
6
+
7
+ code.hljs {
8
+ padding: 3px 5px;
9
+ }
10
+
11
+ .hljs {
12
+ color: var(--specwiki-syntax-text);
13
+ background: var(--specwiki-syntax-background);
14
+ }
15
+
16
+ .hljs-doctag,
17
+ .hljs-keyword,
18
+ .hljs-meta .hljs-keyword,
19
+ .hljs-template-tag,
20
+ .hljs-template-variable,
21
+ .hljs-type,
22
+ .hljs-variable.language_ {
23
+ color: var(--specwiki-syntax-keyword);
24
+ }
25
+
26
+ .hljs-title,
27
+ .hljs-title.class_,
28
+ .hljs-title.class_.inherited__,
29
+ .hljs-title.function_ {
30
+ color: var(--specwiki-syntax-title);
31
+ }
32
+
33
+ .hljs-attr,
34
+ .hljs-attribute,
35
+ .hljs-literal,
36
+ .hljs-meta,
37
+ .hljs-number,
38
+ .hljs-operator,
39
+ .hljs-selector-attr,
40
+ .hljs-selector-class,
41
+ .hljs-selector-id,
42
+ .hljs-variable {
43
+ color: var(--specwiki-syntax-literal);
44
+ }
45
+
46
+ .hljs-meta .hljs-string,
47
+ .hljs-regexp,
48
+ .hljs-string {
49
+ color: var(--specwiki-syntax-string);
50
+ }
51
+
52
+ .hljs-built_in,
53
+ .hljs-symbol {
54
+ color: var(--specwiki-syntax-built-in);
55
+ }
56
+
57
+ .hljs-code,
58
+ .hljs-comment,
59
+ .hljs-formula {
60
+ color: var(--specwiki-syntax-comment);
61
+ }
62
+
63
+ .hljs-name,
64
+ .hljs-quote,
65
+ .hljs-selector-pseudo,
66
+ .hljs-selector-tag {
67
+ color: var(--specwiki-syntax-tag);
68
+ }
69
+
70
+ .hljs-subst,
71
+ .hljs-emphasis,
72
+ .hljs-strong {
73
+ color: var(--specwiki-syntax-text);
74
+ }
75
+
76
+ .hljs-section {
77
+ color: var(--specwiki-syntax-section);
78
+ font-weight: 700;
79
+ }
80
+
81
+ .hljs-bullet {
82
+ color: var(--specwiki-syntax-bullet);
83
+ }
84
+
85
+ .hljs-emphasis {
86
+ font-style: italic;
87
+ }
88
+
89
+ .hljs-strong {
90
+ font-weight: 700;
91
+ }
92
+
93
+ .hljs-addition {
94
+ color: var(--specwiki-syntax-addition);
95
+ background-color: var(--specwiki-syntax-addition-background);
96
+ }
97
+
98
+ .hljs-deletion {
99
+ color: var(--specwiki-syntax-deletion);
100
+ background-color: var(--specwiki-syntax-deletion-background);
101
+ }