@millstone/synapse-cli 0.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.
Files changed (103) hide show
  1. package/README.md +135 -0
  2. package/bin/synapse.js +3 -0
  3. package/dist/commands/eject.d.ts +19 -0
  4. package/dist/commands/eject.d.ts.map +1 -0
  5. package/dist/commands/eject.js +146 -0
  6. package/dist/commands/eject.js.map +1 -0
  7. package/dist/commands/fetch-reference.d.ts +19 -0
  8. package/dist/commands/fetch-reference.d.ts.map +1 -0
  9. package/dist/commands/fetch-reference.js +93 -0
  10. package/dist/commands/fetch-reference.js.map +1 -0
  11. package/dist/commands/format.d.ts +26 -0
  12. package/dist/commands/format.d.ts.map +1 -0
  13. package/dist/commands/format.js +126 -0
  14. package/dist/commands/format.js.map +1 -0
  15. package/dist/commands/generate-pdf.d.ts +19 -0
  16. package/dist/commands/generate-pdf.d.ts.map +1 -0
  17. package/dist/commands/generate-pdf.js +140 -0
  18. package/dist/commands/generate-pdf.js.map +1 -0
  19. package/dist/commands/index.d.ts +17 -0
  20. package/dist/commands/index.d.ts.map +1 -0
  21. package/dist/commands/index.js +26 -0
  22. package/dist/commands/index.js.map +1 -0
  23. package/dist/commands/init.d.ts +58 -0
  24. package/dist/commands/init.d.ts.map +1 -0
  25. package/dist/commands/init.js +234 -0
  26. package/dist/commands/init.js.map +1 -0
  27. package/dist/commands/migrate.d.ts +29 -0
  28. package/dist/commands/migrate.d.ts.map +1 -0
  29. package/dist/commands/migrate.js +297 -0
  30. package/dist/commands/migrate.js.map +1 -0
  31. package/dist/commands/scaffold.d.ts +24 -0
  32. package/dist/commands/scaffold.d.ts.map +1 -0
  33. package/dist/commands/scaffold.js +244 -0
  34. package/dist/commands/scaffold.js.map +1 -0
  35. package/dist/commands/update.d.ts +25 -0
  36. package/dist/commands/update.d.ts.map +1 -0
  37. package/dist/commands/update.js +253 -0
  38. package/dist/commands/update.js.map +1 -0
  39. package/dist/commands/validate.d.ts +37 -0
  40. package/dist/commands/validate.d.ts.map +1 -0
  41. package/dist/commands/validate.js +526 -0
  42. package/dist/commands/validate.js.map +1 -0
  43. package/dist/index.d.ts +3 -0
  44. package/dist/index.d.ts.map +1 -0
  45. package/dist/index.js +277 -0
  46. package/dist/index.js.map +1 -0
  47. package/dist/lib/bodyRules.d.ts +70 -0
  48. package/dist/lib/bodyRules.d.ts.map +1 -0
  49. package/dist/lib/bodyRules.js +711 -0
  50. package/dist/lib/bodyRules.js.map +1 -0
  51. package/dist/lib/config.d.ts +49 -0
  52. package/dist/lib/config.d.ts.map +1 -0
  53. package/dist/lib/config.js +91 -0
  54. package/dist/lib/config.js.map +1 -0
  55. package/dist/lib/git.d.ts +99 -0
  56. package/dist/lib/git.d.ts.map +1 -0
  57. package/dist/lib/git.js +266 -0
  58. package/dist/lib/git.js.map +1 -0
  59. package/dist/lib/graph.d.ts +6 -0
  60. package/dist/lib/graph.d.ts.map +1 -0
  61. package/dist/lib/graph.js +6 -0
  62. package/dist/lib/graph.js.map +1 -0
  63. package/dist/lib/homepage.d.ts +10 -0
  64. package/dist/lib/homepage.d.ts.map +1 -0
  65. package/dist/lib/homepage.js +172 -0
  66. package/dist/lib/homepage.js.map +1 -0
  67. package/dist/lib/markdown.d.ts +107 -0
  68. package/dist/lib/markdown.d.ts.map +1 -0
  69. package/dist/lib/markdown.js +318 -0
  70. package/dist/lib/markdown.js.map +1 -0
  71. package/dist/lib/mode-detection.d.ts +10 -0
  72. package/dist/lib/mode-detection.d.ts.map +1 -0
  73. package/dist/lib/mode-detection.js +29 -0
  74. package/dist/lib/mode-detection.js.map +1 -0
  75. package/dist/lib/naming.d.ts +47 -0
  76. package/dist/lib/naming.d.ts.map +1 -0
  77. package/dist/lib/naming.js +403 -0
  78. package/dist/lib/naming.js.map +1 -0
  79. package/dist/lib/schemas.d.ts +38 -0
  80. package/dist/lib/schemas.d.ts.map +1 -0
  81. package/dist/lib/schemas.js +248 -0
  82. package/dist/lib/schemas.js.map +1 -0
  83. package/dist/lib/templateLint.d.ts +21 -0
  84. package/dist/lib/templateLint.d.ts.map +1 -0
  85. package/dist/lib/templateLint.js +243 -0
  86. package/dist/lib/templateLint.js.map +1 -0
  87. package/dist/lib/templates.d.ts +53 -0
  88. package/dist/lib/templates.d.ts.map +1 -0
  89. package/dist/lib/templates.js +128 -0
  90. package/dist/lib/templates.js.map +1 -0
  91. package/dist/lib/tracking.d.ts +52 -0
  92. package/dist/lib/tracking.d.ts.map +1 -0
  93. package/dist/lib/tracking.js +135 -0
  94. package/dist/lib/tracking.js.map +1 -0
  95. package/dist/lib/types.generated.d.ts +54 -0
  96. package/dist/lib/types.generated.d.ts.map +1 -0
  97. package/dist/lib/types.generated.js +144 -0
  98. package/dist/lib/types.generated.js.map +1 -0
  99. package/dist/lib/validate-plugins.d.ts +22 -0
  100. package/dist/lib/validate-plugins.d.ts.map +1 -0
  101. package/dist/lib/validate-plugins.js +851 -0
  102. package/dist/lib/validate-plugins.js.map +1 -0
  103. package/package.json +85 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mode-detection.js","sourceRoot":"","sources":["../../src/lib/mode-detection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAIvC;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAAC,GAAY;IAC5C,MAAM,OAAO,GAAG,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IAErC,oDAAoD;IACpD,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAAC;IAC7D,IAAI,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAChC,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,2CAA2C;IAC3C,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC;QAClE,OAAO,CAAC,OAAO,CAAC,+BAA+B,CAAC,CAAC;QACjD,OAAO,KAAK,CAAC;IACf,CAAC;IAAC,MAAM,CAAC;QACP,wBAAwB;IAC1B,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC"}
@@ -0,0 +1,47 @@
1
+ import { DocType } from "./types.generated.js";
2
+ /**
3
+ * Validation issue structure for consistent error reporting
4
+ */
5
+ export interface ValidationIssue {
6
+ notePath: string;
7
+ type: "error" | "warning";
8
+ code: string;
9
+ message: string;
10
+ field?: string;
11
+ }
12
+ /**
13
+ * Get the expected folder path for a document type
14
+ * Now delegates to config.ts which handles config-based overrides
15
+ * @param type - The document type
16
+ * @param cwd - Optional working directory for config lookup
17
+ * @returns The expected folder path relative to content directory
18
+ */
19
+ export declare function expectedFolder(type: DocType, cwd?: string): string;
20
+ /**
21
+ * Validate that a file is in the correct folder for its type
22
+ * @param notePath - The path to the note file
23
+ * @param type - The document type
24
+ * @returns Array of validation issues (errors for incorrect placement)
25
+ */
26
+ export declare function validateFolderForType(notePath: string, type: DocType, cwd?: string): ValidationIssue[];
27
+ /**
28
+ * Validate the filename pattern for a document
29
+ * @param notePath - The path to the note file
30
+ * @param type - The document type
31
+ * @param id - The document ID from frontmatter
32
+ * @param title - The document title from frontmatter
33
+ * @param strict - Whether to use strict mode (default: true - elevates warnings to errors)
34
+ * @returns Array of validation issues
35
+ */
36
+ export declare function validateFilenamePattern(notePath: string, type: DocType, id: string, title: string, strict?: boolean, // Default to strict mode
37
+ frontmatter?: Record<string, any>): ValidationIssue[];
38
+ /**
39
+ * Comprehensive validation of naming and placement rules
40
+ * @param notePath - The path to the note file
41
+ * @param frontmatter - The parsed frontmatter data
42
+ * @param strict - Whether to use strict mode (default: true)
43
+ * @param cwd - Optional working directory for config lookup
44
+ * @returns Array of validation issues
45
+ */
46
+ export declare function validateNaming(notePath: string, frontmatter: Record<string, any>, strict?: boolean, cwd?: string): ValidationIssue[];
47
+ //# sourceMappingURL=naming.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"naming.d.ts","sourceRoot":"","sources":["../../src/lib/naming.ts"],"names":[],"mappings":"AACA,OAAO,EACL,OAAO,EAGR,MAAM,sBAAsB,CAAC;AAsE9B;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,OAAO,GAAG,SAAS,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAMlE;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,OAAO,EACb,GAAG,CAAC,EAAE,MAAM,GACX,eAAe,EAAE,CAwBnB;AAiBD;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,OAAO,EACb,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,MAAM,EACb,MAAM,GAAE,OAAc,EAAE,yBAAyB;AACjD,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAChC,eAAe,EAAE,CA6NnB;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAChC,MAAM,GAAE,OAAc,EACtB,GAAG,CAAC,EAAE,MAAM,GACX,eAAe,EAAE,CAsEnB"}
@@ -0,0 +1,403 @@
1
+ import * as path from "path";
2
+ import { isDocType, } from "./types.generated.js";
3
+ import { getExpectedFolder, getFolderName } from "./config.js";
4
+ /**
5
+ * Extract a source prefix from an upstream URL for reference documents
6
+ * @param upstreamUrl - The upstream URL from frontmatter
7
+ * @returns A source prefix string (e.g., "claude-code", "dora", "mercury")
8
+ */
9
+ function extractSourcePrefix(upstreamUrl) {
10
+ try {
11
+ const url = new URL(upstreamUrl);
12
+ const hostname = url.hostname.toLowerCase();
13
+ // Domain-based mapping with heuristics
14
+ // Prioritize specific known sources first
15
+ const domainMappings = {
16
+ 'docs.claude.com': 'claude-code',
17
+ 'claude.ai': 'claude',
18
+ 'dora.dev': 'dora',
19
+ 'docs.mercury.com': 'mercury',
20
+ 'api.mercury.com': 'mercury',
21
+ 'huggingface.co': 'huggingface',
22
+ 'readme.io': 'readme',
23
+ };
24
+ // Check exact domain matches first
25
+ if (domainMappings[hostname]) {
26
+ return domainMappings[hostname];
27
+ }
28
+ // Handle docs.X.com pattern
29
+ const docsMatch = hostname.match(/^docs\.([a-z0-9-]+)\.[a-z]+$/);
30
+ if (docsMatch) {
31
+ return docsMatch[1];
32
+ }
33
+ // Handle api.X.com pattern
34
+ const apiMatch = hostname.match(/^api\.([a-z0-9-]+)\.[a-z]+$/);
35
+ if (apiMatch) {
36
+ return apiMatch[1];
37
+ }
38
+ // For other domains, use the primary domain name (without TLD)
39
+ // e.g., "example.com" → "example", "my-site.org" → "my-site"
40
+ const parts = hostname.split('.');
41
+ if (parts.length >= 2) {
42
+ // Get the second-to-last part (domain before TLD)
43
+ const domainName = parts[parts.length - 2];
44
+ // Skip generic domains that aren't meaningful as prefixes
45
+ const genericDomains = ['github', 'stackoverflow', 'medium', 'dev', 'substack'];
46
+ if (!genericDomains.includes(domainName)) {
47
+ return domainName;
48
+ }
49
+ // For generic domains, try to extract from path
50
+ const pathSegments = url.pathname.split('/').filter(s => s.length > 0);
51
+ if (pathSegments.length > 0) {
52
+ // Use first path segment as prefix for generic domains
53
+ return toSlugCase(pathSegments[0]);
54
+ }
55
+ }
56
+ // Fallback: use domain name without TLD
57
+ return hostname.split('.')[0];
58
+ }
59
+ catch (error) {
60
+ // If URL parsing fails, return empty string (will trigger validation error)
61
+ return '';
62
+ }
63
+ }
64
+ /**
65
+ * Get the expected folder path for a document type
66
+ * Now delegates to config.ts which handles config-based overrides
67
+ * @param type - The document type
68
+ * @param cwd - Optional working directory for config lookup
69
+ * @returns The expected folder path relative to content directory
70
+ */
71
+ export function expectedFolder(type, cwd) {
72
+ // Check if type is valid
73
+ if (!isDocType(type)) {
74
+ throw new Error(`Unknown document type: ${type}`);
75
+ }
76
+ return getExpectedFolder(type, cwd);
77
+ }
78
+ /**
79
+ * Validate that a file is in the correct folder for its type
80
+ * @param notePath - The path to the note file
81
+ * @param type - The document type
82
+ * @returns Array of validation issues (errors for incorrect placement)
83
+ */
84
+ export function validateFolderForType(notePath, type, cwd) {
85
+ const issues = [];
86
+ const normalizedPath = notePath.replace(/\\/g, "/");
87
+ // Get folder configuration (respects config overrides)
88
+ const expectedFolderPath = expectedFolder(type, cwd);
89
+ const expectedFolderName = getFolderName(type, cwd);
90
+ // Check if the file is in the expected folder
91
+ // Accept either the full path (content/10_Policies) or just the folder name (10_Policies)
92
+ if (!normalizedPath.includes(expectedFolderPath) &&
93
+ !normalizedPath.includes(expectedFolderName)) {
94
+ issues.push({
95
+ notePath,
96
+ type: "error",
97
+ code: "WRONG_FOLDER",
98
+ message: `Document of type '${type}' must be placed in ${expectedFolderPath}`,
99
+ field: "path",
100
+ });
101
+ }
102
+ return issues;
103
+ }
104
+ /**
105
+ * Convert a string to slug case
106
+ * @param str - The string to convert
107
+ * @returns The slug-case version
108
+ */
109
+ function toSlugCase(str) {
110
+ return str
111
+ .toLowerCase()
112
+ .trim()
113
+ .replace(/[^\w\s-]/g, "") // Remove special characters
114
+ .replace(/\s+/g, "-") // Replace spaces with dashes
115
+ .replace(/-+/g, "-") // Replace multiple dashes with single dash
116
+ .replace(/^-+|-+$/g, ""); // Remove leading/trailing dashes
117
+ }
118
+ /**
119
+ * Validate the filename pattern for a document
120
+ * @param notePath - The path to the note file
121
+ * @param type - The document type
122
+ * @param id - The document ID from frontmatter
123
+ * @param title - The document title from frontmatter
124
+ * @param strict - Whether to use strict mode (default: true - elevates warnings to errors)
125
+ * @returns Array of validation issues
126
+ */
127
+ export function validateFilenamePattern(notePath, type, id, title, strict = true, // Default to strict mode
128
+ frontmatter) {
129
+ const issues = [];
130
+ const filename = path.basename(notePath, ".md");
131
+ if (type === "meeting") {
132
+ // Meeting filenames must start with YYYY-MM-DD- date prefix
133
+ const meetingDate = frontmatter?.meeting_date;
134
+ if (!meetingDate) {
135
+ issues.push({
136
+ notePath,
137
+ type: "error",
138
+ code: "MISSING_MEETING_DATE",
139
+ message: "Meeting documents require 'meeting_date' in frontmatter for filename validation",
140
+ field: "meeting_date",
141
+ });
142
+ return issues;
143
+ }
144
+ // Extract date from meeting_date (handle ISO 8601 format)
145
+ let datePrefix;
146
+ try {
147
+ const date = new Date(meetingDate);
148
+ if (isNaN(date.getTime())) {
149
+ throw new Error("Invalid date");
150
+ }
151
+ const year = date.getFullYear();
152
+ const month = String(date.getMonth() + 1).padStart(2, '0');
153
+ const day = String(date.getDate()).padStart(2, '0');
154
+ datePrefix = `${year}-${month}-${day}`;
155
+ }
156
+ catch (error) {
157
+ issues.push({
158
+ notePath,
159
+ type: "error",
160
+ code: "INVALID_MEETING_DATE",
161
+ message: `Invalid meeting_date format '${meetingDate}'. Must be a valid ISO 8601 date string.`,
162
+ field: "meeting_date",
163
+ });
164
+ return issues;
165
+ }
166
+ // Check if filename starts with date prefix
167
+ const expectedPattern = `${datePrefix}-`;
168
+ if (!filename.startsWith(expectedPattern)) {
169
+ issues.push({
170
+ notePath,
171
+ type: "error",
172
+ code: "MISSING_DATE_PREFIX",
173
+ message: `Meeting filename must start with date prefix '${datePrefix}-' (from meeting_date '${meetingDate}'). Expected pattern: 'YYYY-MM-DD-company-topic.md'`,
174
+ field: "filename",
175
+ });
176
+ return issues;
177
+ }
178
+ // Validate the rest of the filename is slug-case
179
+ const slugPart = filename.substring(datePrefix.length + 1); // +1 for the hyphen
180
+ const isSlugCase = /^[a-z0-9-]+$/.test(slugPart);
181
+ if (!isSlugCase) {
182
+ issues.push({
183
+ notePath,
184
+ type: "error",
185
+ code: "INVALID_FILENAME_FORMAT",
186
+ message: `Meeting filename after date prefix must be in slug-case (lowercase, hyphens only), got '${slugPart}'`,
187
+ field: "filename",
188
+ });
189
+ }
190
+ }
191
+ else if (type === "adr") {
192
+ // ADR has strict requirements
193
+ // 1. ID must match pattern ADR-####
194
+ const adrIdPattern = /^ADR-\d{4,}$/;
195
+ if (!adrIdPattern.test(id)) {
196
+ issues.push({
197
+ notePath,
198
+ type: "error",
199
+ code: "INVALID_ADR_ID",
200
+ message: `ADR id must match pattern ADR-#### (e.g., ADR-0001), got '${id}'`,
201
+ field: "id",
202
+ });
203
+ }
204
+ // 2. Filename must be ADR-####-slug.md
205
+ const adrFilenamePattern = /^ADR-\d{4,}-[a-z0-9-]+$/;
206
+ if (!adrFilenamePattern.test(filename)) {
207
+ issues.push({
208
+ notePath,
209
+ type: "error",
210
+ code: "INVALID_ADR_FILENAME",
211
+ message: `ADR filename must match pattern ADR-####-slug.md (e.g., ADR-0001-api-design.md), got '${filename}.md'`,
212
+ field: "filename",
213
+ });
214
+ }
215
+ else {
216
+ // Check that the ADR number in filename matches the ID
217
+ const filenameAdrNumber = filename.match(/^ADR-(\d{4,})/)?.[1];
218
+ const idAdrNumber = id.match(/^ADR-(\d{4,})/)?.[1];
219
+ if (filenameAdrNumber &&
220
+ idAdrNumber &&
221
+ filenameAdrNumber !== idAdrNumber) {
222
+ issues.push({
223
+ notePath,
224
+ type: "error",
225
+ code: "ADR_ID_MISMATCH",
226
+ message: `ADR number in filename (${filenameAdrNumber}) does not match id (${idAdrNumber})`,
227
+ field: "filename",
228
+ });
229
+ }
230
+ }
231
+ }
232
+ else if (type === "reference") {
233
+ // Reference type: enforce source prefix from upstream_url
234
+ const isSlugCase = /^[a-z0-9-]+$/.test(filename);
235
+ if (!isSlugCase) {
236
+ issues.push({
237
+ notePath,
238
+ type: "error",
239
+ code: "INVALID_FILENAME_FORMAT",
240
+ message: `Filename must be in slug-case (lowercase, hyphens only), got '${filename}'`,
241
+ field: "filename",
242
+ });
243
+ return issues; // Can't continue with invalid format
244
+ }
245
+ // Check for upstream_url in frontmatter
246
+ const upstreamUrl = frontmatter?.upstream_url;
247
+ const manualPrefix = frontmatter?.source_prefix;
248
+ if (!upstreamUrl) {
249
+ issues.push({
250
+ notePath,
251
+ type: "error",
252
+ code: "MISSING_UPSTREAM_URL",
253
+ message: "Reference documents require 'upstream_url' in frontmatter for source prefix validation",
254
+ field: "upstream_url",
255
+ });
256
+ return issues; // Can't validate prefix without upstream_url
257
+ }
258
+ // Extract or use manual source prefix
259
+ const sourcePrefix = manualPrefix || extractSourcePrefix(upstreamUrl);
260
+ if (!sourcePrefix) {
261
+ issues.push({
262
+ notePath,
263
+ type: "error",
264
+ code: "CANNOT_EXTRACT_SOURCE_PREFIX",
265
+ message: `Cannot extract source prefix from upstream_url '${upstreamUrl}'. Add 'source_prefix' field to frontmatter to manually specify the prefix.`,
266
+ field: "upstream_url",
267
+ });
268
+ return issues;
269
+ }
270
+ // Validate filename starts with source prefix
271
+ const expectedPattern = `${sourcePrefix}-`;
272
+ if (!filename.startsWith(expectedPattern)) {
273
+ issues.push({
274
+ notePath,
275
+ type: "error",
276
+ code: "MISSING_SOURCE_PREFIX",
277
+ message: `Reference filename must start with source prefix '${sourcePrefix}-' (derived from upstream_url '${upstreamUrl}'). Expected pattern: '${sourcePrefix}-{slug}.md'`,
278
+ field: "filename",
279
+ });
280
+ return issues;
281
+ }
282
+ // Extract the slug part (after prefix)
283
+ const slugPart = filename.substring(sourcePrefix.length + 1); // +1 for the hyphen
284
+ // Generate expected slug from title, removing the source prefix if it appears in the title
285
+ // e.g., "Claude Code Plugins" -> "plugins" (not "claude-code-plugins")
286
+ // e.g., "DORA 2025 Analysis" -> "2025-analysis" (not "dora-2025-analysis")
287
+ let titleForSlug = title;
288
+ const titleSlug = toSlugCase(title);
289
+ // If the title slug starts with the source prefix, remove it
290
+ if (titleSlug.startsWith(sourcePrefix + '-')) {
291
+ titleForSlug = titleSlug.substring(sourcePrefix.length + 1);
292
+ }
293
+ else {
294
+ titleForSlug = titleSlug;
295
+ }
296
+ // Validate the slug part matches the cleaned title slug
297
+ if (slugPart !== titleForSlug) {
298
+ const severity = strict ? "error" : "warning";
299
+ issues.push({
300
+ notePath,
301
+ type: severity,
302
+ code: "FILENAME_TITLE_MISMATCH",
303
+ message: `Filename slug '${slugPart}' does not match expected slug from title '${title}' (expected: '${sourcePrefix}-${titleForSlug}.md')`,
304
+ field: "filename",
305
+ });
306
+ }
307
+ }
308
+ else {
309
+ // Other document types: slug-case filename validation
310
+ const expectedSlug = toSlugCase(title);
311
+ const isSlugCase = /^[a-z0-9-]+$/.test(filename);
312
+ if (!isSlugCase) {
313
+ issues.push({
314
+ notePath,
315
+ type: "error",
316
+ code: "INVALID_FILENAME_FORMAT",
317
+ message: `Filename must be in slug-case (lowercase, hyphens only), got '${filename}'`,
318
+ field: "filename",
319
+ });
320
+ }
321
+ else if (filename !== expectedSlug) {
322
+ // Check if filename matches the title slug
323
+ const severity = strict ? "error" : "warning";
324
+ issues.push({
325
+ notePath,
326
+ type: severity,
327
+ code: "FILENAME_TITLE_MISMATCH",
328
+ message: `Filename '${filename}' does not match expected slug from title '${title}' (expected: '${expectedSlug}')`,
329
+ field: "filename",
330
+ });
331
+ }
332
+ }
333
+ return issues;
334
+ }
335
+ /**
336
+ * Comprehensive validation of naming and placement rules
337
+ * @param notePath - The path to the note file
338
+ * @param frontmatter - The parsed frontmatter data
339
+ * @param strict - Whether to use strict mode (default: true)
340
+ * @param cwd - Optional working directory for config lookup
341
+ * @returns Array of validation issues
342
+ */
343
+ export function validateNaming(notePath, frontmatter, strict = true, cwd) {
344
+ const issues = [];
345
+ // Skip naming validation for example files
346
+ if (notePath.includes("00_Guides/Examples/") ||
347
+ frontmatter.example === true) {
348
+ return issues;
349
+ }
350
+ // Extract required fields
351
+ const type = frontmatter.type;
352
+ const id = frontmatter.id;
353
+ const title = frontmatter.title;
354
+ // Validate type is present and valid
355
+ if (!type) {
356
+ issues.push({
357
+ notePath,
358
+ type: "error",
359
+ code: "MISSING_TYPE",
360
+ message: "Document type is missing from frontmatter",
361
+ field: "type",
362
+ });
363
+ return issues; // Can't continue without type
364
+ }
365
+ if (!isDocType(type)) {
366
+ issues.push({
367
+ notePath,
368
+ type: "error",
369
+ code: "INVALID_TYPE",
370
+ message: `Invalid document type: '${type}'`,
371
+ field: "type",
372
+ });
373
+ return issues; // Can't continue with invalid type
374
+ }
375
+ // Validate required fields for naming checks
376
+ if (!id) {
377
+ issues.push({
378
+ notePath,
379
+ type: "error",
380
+ code: "MISSING_ID",
381
+ message: "Document id is missing from frontmatter",
382
+ field: "id",
383
+ });
384
+ }
385
+ if (!title) {
386
+ issues.push({
387
+ notePath,
388
+ type: "error",
389
+ code: "MISSING_TITLE",
390
+ message: "Document title is missing from frontmatter",
391
+ field: "title",
392
+ });
393
+ }
394
+ // If we have all required fields, perform naming validation
395
+ if (type && id && title) {
396
+ // Validate folder placement
397
+ issues.push(...validateFolderForType(notePath, type, cwd));
398
+ // Validate filename pattern (pass frontmatter for reference type)
399
+ issues.push(...validateFilenamePattern(notePath, type, id, title, strict, frontmatter));
400
+ }
401
+ return issues;
402
+ }
403
+ //# sourceMappingURL=naming.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"naming.js","sourceRoot":"","sources":["../../src/lib/naming.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ import { DocType } from './types.generated.js';
2
+ export type { DocType } from './types.generated.js';
3
+ export { isDocType, DOC_TYPES } from './types.generated.js';
4
+ export type JSONSchema = any;
5
+ /**
6
+ * Load a schema for a specific document type
7
+ * Resolves $ref references to base.schema.json automatically
8
+ */
9
+ export declare function loadSchema(type: DocType, dir?: string): Promise<JSONSchema>;
10
+ /**
11
+ * List all available schema types in the schema directory
12
+ */
13
+ export declare function listSchemas(dir?: string): Promise<string[]>;
14
+ /**
15
+ * Validate frontmatter data against a JSON schema
16
+ */
17
+ export declare function validateFrontmatter(data: any, schema: JSONSchema): {
18
+ valid: boolean;
19
+ errors?: Array<{
20
+ path: string;
21
+ message: string;
22
+ }>;
23
+ };
24
+ /**
25
+ * Validate that all expected document types have schemas
26
+ * Returns an object with validation results
27
+ */
28
+ export declare function validateSchemasCoverage(dir?: string): Promise<{
29
+ success: boolean;
30
+ coverage: {
31
+ expected: DocType[];
32
+ found: string[];
33
+ missing: string[];
34
+ extra: string[];
35
+ };
36
+ errors: string[];
37
+ }>;
38
+ //# sourceMappingURL=schemas.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../../src/lib/schemas.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,OAAO,EAAwB,MAAM,sBAAsB,CAAC;AAGrE,YAAY,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAG5D,MAAM,MAAM,UAAU,GAAG,GAAG,CAAC;AAqD7B;;;GAGG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CA0DjF;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAoBjE;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,GAAG,EACT,MAAM,EAAE,UAAU,GACjB;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,CA0DvE;AAED;;;GAGG;AACH,wBAAsB,uBAAuB,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACnE,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE;QACR,QAAQ,EAAE,OAAO,EAAE,CAAC;QACpB,KAAK,EAAE,MAAM,EAAE,CAAC;QAChB,OAAO,EAAE,MAAM,EAAE,CAAC;QAClB,KAAK,EAAE,MAAM,EAAE,CAAC;KACjB,CAAC;IACF,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB,CAAC,CA6DD"}