@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,172 @@
1
+ import fsExtra from 'fs-extra';
2
+ import * as path from 'path';
3
+ import glob from 'fast-glob';
4
+ import { getDocTypes, TEMPLATE_REGISTRY } from './types.generated.js';
5
+ import { expectedFolder } from './naming.js';
6
+ const fs = fsExtra;
7
+ /**
8
+ * Count markdown files in a directory
9
+ */
10
+ async function countMarkdownFiles(dirPath) {
11
+ try {
12
+ const files = await glob(['**/*.md'], {
13
+ cwd: dirPath,
14
+ absolute: false,
15
+ onlyFiles: true,
16
+ ignore: ['**/Examples/*.md', '**/templates/**']
17
+ });
18
+ return files.length;
19
+ }
20
+ catch (error) {
21
+ // Directory might not exist yet, which is fine
22
+ return 0;
23
+ }
24
+ }
25
+ /**
26
+ * Generate homepage content with navigation and getting started sections
27
+ */
28
+ export async function generateHomepage(options = {}) {
29
+ const { contentDir = path.resolve(process.cwd(), 'content'), outputPath = path.join(contentDir, 'index.md') } = options;
30
+ console.log('Generating homepage...');
31
+ // Define the sections based on doc types
32
+ const sections = [];
33
+ // Get type config from registry with proper pluralization
34
+ const typeConfig = Object.entries(TEMPLATE_REGISTRY).reduce((acc, [type, metadata]) => {
35
+ // Special pluralization rules
36
+ let pluralLabel = metadata.displayLabel;
37
+ if (pluralLabel.endsWith('y') && !pluralLabel.endsWith('ey')) {
38
+ pluralLabel = pluralLabel.slice(0, -1) + 'ies'; // Policy -> Policies
39
+ }
40
+ else if (pluralLabel.endsWith('s') || pluralLabel.endsWith('x') || pluralLabel.endsWith('ch')) {
41
+ pluralLabel += 'es'; // Process -> Processes
42
+ }
43
+ else {
44
+ pluralLabel += 's'; // Standard -> Standards
45
+ }
46
+ acc[type] = {
47
+ label: pluralLabel,
48
+ collection: metadata.cmsCollection
49
+ };
50
+ return acc;
51
+ }, {});
52
+ // Build sections for each doc type
53
+ for (const docType of getDocTypes()) {
54
+ const folder = expectedFolder(docType);
55
+ const config = typeConfig[docType];
56
+ if (config && folder) {
57
+ // Remove 'content/' prefix since contentDir already contains it
58
+ const relativeFolderPath = folder.replace(/^content\//, '');
59
+ const folderPath = path.join(contentDir, relativeFolderPath);
60
+ const count = await countMarkdownFiles(folderPath);
61
+ // Debug logging
62
+ if (count > 0) {
63
+ console.log(` ${config.label}: ${count} documents in ${folder}`);
64
+ }
65
+ sections.push({
66
+ type: docType,
67
+ label: config.label,
68
+ folder,
69
+ collection: config.collection,
70
+ count
71
+ });
72
+ }
73
+ }
74
+ // Build homepage content
75
+ let content = `# Synapse Documentation Framework
76
+
77
+ Welcome to your centralized documentation hub. This framework provides a structured approach to managing technical and operational documentation.
78
+
79
+ ## Quick Navigation
80
+
81
+ Navigate to documentation by type:
82
+
83
+ `;
84
+ // Group sections by category for better organization
85
+ const policyGroup = sections.filter(s => ['policy', 'standard'].includes(s.type));
86
+ const processGroup = sections.filter(s => ['process', 'sop', 'runbook'].includes(s.type));
87
+ const meetingGroup = sections.filter(s => ['meeting', 'scorecard'].includes(s.type));
88
+ const architectureGroup = sections.filter(s => ['adr', 'tdd'].includes(s.type));
89
+ const productGroup = sections.filter(s => ['prd'].includes(s.type));
90
+ const systemGroup = sections.filter(s => ['system', 'capability'].includes(s.type));
91
+ // Add Policy & Standards section
92
+ if (policyGroup.length > 0) {
93
+ content += `### Governance & Standards\n\n`;
94
+ for (const section of policyGroup) {
95
+ content += `- **${section.label}** (${section.count}): [[${section.folder}]] • [Edit in CMS](/admin/#/collections/${section.collection})\n`;
96
+ }
97
+ content += '\n';
98
+ }
99
+ // Add Process & Operations section
100
+ if (processGroup.length > 0) {
101
+ content += `### Processes & Operations\n\n`;
102
+ for (const section of processGroup) {
103
+ content += `- **${section.label}** (${section.count}): [[${section.folder}]] • [Edit in CMS](/admin/#/collections/${section.collection})\n`;
104
+ }
105
+ content += '\n';
106
+ }
107
+ // Add Meetings & Assessments section
108
+ if (meetingGroup.length > 0) {
109
+ content += `### Meetings & Assessments\n\n`;
110
+ for (const section of meetingGroup) {
111
+ content += `- **${section.label}** (${section.count}): [[${section.folder}]] • [Edit in CMS](/admin/#/collections/${section.collection})\n`;
112
+ }
113
+ content += '\n';
114
+ }
115
+ // Add Architecture section
116
+ if (architectureGroup.length > 0) {
117
+ content += `### Architecture\n\n`;
118
+ for (const section of architectureGroup) {
119
+ content += `- **${section.label}** (${section.count}): [[${section.folder}]] • [Edit in CMS](/admin/#/collections/${section.collection})\n`;
120
+ }
121
+ content += '\n';
122
+ }
123
+ // Add Products section
124
+ if (productGroup.length > 0) {
125
+ content += `### Products\n\n`;
126
+ for (const section of productGroup) {
127
+ content += `- **${section.label}** (${section.count}): [[${section.folder}]] • [Edit in CMS](/admin/#/collections/${section.collection})\n`;
128
+ }
129
+ content += '\n';
130
+ }
131
+ // Add Systems & Capabilities section
132
+ if (systemGroup.length > 0) {
133
+ content += `### Systems & Capabilities\n\n`;
134
+ for (const section of systemGroup) {
135
+ content += `- **${section.label}** (${section.count}): [[${section.folder}]] • [Edit in CMS](/admin/#/collections/${section.collection})\n`;
136
+ }
137
+ content += '\n';
138
+ }
139
+ // Add Getting Started section
140
+ content += `## Getting Started
141
+
142
+ New to the framework? Start here:
143
+
144
+ - **[[00_Guides/Authoring Guide]]**: Learn how to create and maintain documentation
145
+ - **[[00_Guides/Examples]]**: Browse example documents for each type
146
+
147
+ ## Recent Activity
148
+
149
+ _This section will be automatically updated with recent changes._
150
+
151
+ ## Statistics
152
+
153
+ Total documents: **${sections.reduce((sum, s) => sum + s.count, 0)}**
154
+
155
+ | Type | Count |
156
+ |------|-------|
157
+ ${sections.map(s => `| ${s.label} | ${s.count} |`).join('\n')}
158
+
159
+ ---
160
+
161
+ _Last updated: ${new Date().toISOString()}_
162
+ `;
163
+ // Ensure the output directory exists
164
+ await fs.ensureDir(path.dirname(outputPath));
165
+ // Write the homepage
166
+ await fs.writeFile(outputPath, content, 'utf-8');
167
+ console.log(`Homepage generated at: ${outputPath}`);
168
+ // Log summary
169
+ const totalDocs = sections.reduce((sum, s) => sum + s.count, 0);
170
+ console.log(`Total documents indexed: ${totalDocs}`);
171
+ }
172
+ //# sourceMappingURL=homepage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"homepage.js","sourceRoot":"","sources":["../../src/lib/homepage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Shared utilities for parsing and processing markdown documents
3
+ */
4
+ import type { Root, Content } from 'mdast';
5
+ /**
6
+ * Extracts raw frontmatter and body from markdown content
7
+ * @param content - The markdown content to parse
8
+ * @returns Object with raw frontmatter string, body, and line numbers
9
+ */
10
+ export declare function extractFrontmatter(content: string): {
11
+ frontmatter: string;
12
+ body: string;
13
+ startLine: number;
14
+ endLine: number;
15
+ };
16
+ /**
17
+ * Parses markdown content into frontmatter data and body
18
+ * @param content - The markdown content to parse
19
+ * @returns Object with parsed frontmatter data and body
20
+ */
21
+ export declare function parseDocument(content: string): {
22
+ frontmatter: any;
23
+ body: string;
24
+ raw: {
25
+ frontmatter: string;
26
+ startLine: number;
27
+ endLine: number;
28
+ };
29
+ error?: string;
30
+ };
31
+ /**
32
+ * Extracts wikilinks from markdown content
33
+ * @param content - The markdown content to parse
34
+ * @returns Array of wikilink targets (without the brackets)
35
+ */
36
+ export declare function extractWikilinks(content: string): string[];
37
+ /**
38
+ * Validates that a wikilink target exists in the vault
39
+ * @param linkTarget - The target of the wikilink (without brackets)
40
+ * @param existingFiles - Set of existing file paths in the vault
41
+ * @returns true if the target exists, false otherwise
42
+ */
43
+ export declare function validateWikilinkExists(linkTarget: string, existingFiles: Set<string>): boolean;
44
+ /**
45
+ * Extracts all {{placeholder}} references from template text
46
+ * Used primarily for template linting
47
+ */
48
+ export declare function extractPlaceholders(text: string): Set<string>;
49
+ /**
50
+ * Parses frontmatter keys from raw frontmatter string
51
+ * Used for template analysis without full YAML parsing
52
+ */
53
+ export declare function parseFrontmatterKeys(frontmatter: string): Set<string>;
54
+ /**
55
+ * Checks if a string value needs YAML quoting
56
+ * Returns true if the string contains characters that could cause YAML parsing issues
57
+ */
58
+ export declare function needsYamlQuoting(value: string): boolean;
59
+ /**
60
+ * Represents a section node extracted from the AST
61
+ */
62
+ export interface SectionNode {
63
+ /** Section ID (normalized from title) */
64
+ id: string;
65
+ /** Original heading text */
66
+ title: string;
67
+ /** Heading depth (2 for H2, 3 for H3, etc.) */
68
+ depth: number;
69
+ /** Line number where the heading appears */
70
+ line: number;
71
+ /** Column number where the heading starts */
72
+ column: number;
73
+ /** AST nodes that are children of this section */
74
+ content: Content[];
75
+ /** Start position in the document */
76
+ position?: {
77
+ start: {
78
+ line: number;
79
+ column: number;
80
+ offset?: number;
81
+ };
82
+ end: {
83
+ line: number;
84
+ column: number;
85
+ offset?: number;
86
+ };
87
+ };
88
+ }
89
+ /**
90
+ * Parses markdown body text into an AST
91
+ * @param body - The markdown body content (without frontmatter)
92
+ * @returns The parsed AST root node
93
+ */
94
+ export declare function parseMarkdown(body: string): Root;
95
+ /**
96
+ * Finds all H2 sections in the AST and extracts their content
97
+ * @param ast - The parsed markdown AST
98
+ * @returns Array of section nodes with their content
99
+ */
100
+ export declare function findSections(ast: Root): SectionNode[];
101
+ /**
102
+ * Stringifies an AST back to markdown
103
+ * @param ast - The AST to stringify
104
+ * @returns The markdown string
105
+ */
106
+ export declare function stringifyMarkdown(ast: Root): string;
107
+ //# sourceMappingURL=markdown.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/lib/markdown.ts"],"names":[],"mappings":"AAAA;;GAEG;AAOH,OAAO,KAAK,EAAE,IAAI,EAAW,OAAO,EAAmB,MAAM,OAAO,CAAC;AAErE;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG;IACnD,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB,CAkCA;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG;IAC9C,WAAW,EAAE,GAAG,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE;QACH,WAAW,EAAE,MAAM,CAAC;QACpB,SAAS,EAAE,MAAM,CAAC;QAClB,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CA0BA;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAe1D;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,UAAU,EAAE,MAAM,EAClB,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,GACzB,OAAO,CAwBT;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAgC7D;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAarE;AAGD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAiBvD;AAcD;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,yCAAyC;IACzC,EAAE,EAAE,MAAM,CAAC;IACX,4BAA4B;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,+CAA+C;IAC/C,KAAK,EAAE,MAAM,CAAC;IACd,4CAA4C;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,6CAA6C;IAC7C,MAAM,EAAE,MAAM,CAAC;IACf,kDAAkD;IAClD,OAAO,EAAE,OAAO,EAAE,CAAC;IACnB,qCAAqC;IACrC,QAAQ,CAAC,EAAE;QACT,KAAK,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAC;YAAC,MAAM,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;QACzD,GAAG,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAC;YAAC,MAAM,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;KACxD,CAAC;CACH;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAIhD;AAuDD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,IAAI,GAAG,WAAW,EAAE,CA0CrD;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,IAAI,GAAG,MAAM,CAQnD"}
@@ -0,0 +1,318 @@
1
+ /**
2
+ * Shared utilities for parsing and processing markdown documents
3
+ */
4
+ import * as yaml from 'js-yaml';
5
+ import { unified } from 'unified';
6
+ import remarkParse from 'remark-parse';
7
+ import remarkGfm from 'remark-gfm';
8
+ import remarkStringify from 'remark-stringify';
9
+ /**
10
+ * Extracts raw frontmatter and body from markdown content
11
+ * @param content - The markdown content to parse
12
+ * @returns Object with raw frontmatter string, body, and line numbers
13
+ */
14
+ export function extractFrontmatter(content) {
15
+ const lines = content.split('\n');
16
+ let startLine = -1;
17
+ let endLine = -1;
18
+ for (let i = 0; i < lines.length; i++) {
19
+ if (lines[i].trim() === '---') {
20
+ if (startLine === -1) {
21
+ startLine = i;
22
+ }
23
+ else {
24
+ endLine = i;
25
+ break;
26
+ }
27
+ }
28
+ }
29
+ if (startLine === -1 || endLine === -1) {
30
+ return {
31
+ frontmatter: '',
32
+ body: content,
33
+ startLine: 0,
34
+ endLine: 0
35
+ };
36
+ }
37
+ const frontmatter = lines.slice(startLine + 1, endLine).join('\n');
38
+ const body = lines.slice(endLine + 1).join('\n');
39
+ return {
40
+ frontmatter,
41
+ body,
42
+ startLine: startLine + 1,
43
+ endLine
44
+ };
45
+ }
46
+ /**
47
+ * Parses markdown content into frontmatter data and body
48
+ * @param content - The markdown content to parse
49
+ * @returns Object with parsed frontmatter data and body
50
+ */
51
+ export function parseDocument(content) {
52
+ const extracted = extractFrontmatter(content);
53
+ let frontmatterData = {};
54
+ let parseError;
55
+ if (extracted.frontmatter) {
56
+ try {
57
+ frontmatterData = yaml.load(extracted.frontmatter) || {};
58
+ }
59
+ catch (error) {
60
+ // Capture the error but still return empty frontmatter
61
+ parseError = error instanceof Error ? error.message : String(error);
62
+ console.warn('Failed to parse frontmatter YAML:', error);
63
+ }
64
+ }
65
+ return {
66
+ frontmatter: frontmatterData,
67
+ body: extracted.body,
68
+ raw: {
69
+ frontmatter: extracted.frontmatter,
70
+ startLine: extracted.startLine,
71
+ endLine: extracted.endLine
72
+ },
73
+ error: parseError
74
+ };
75
+ }
76
+ /**
77
+ * Extracts wikilinks from markdown content
78
+ * @param content - The markdown content to parse
79
+ * @returns Array of wikilink targets (without the brackets)
80
+ */
81
+ export function extractWikilinks(content) {
82
+ const wikilinks = [];
83
+ // Match [[Link]] and [[Link|Display Text]] patterns
84
+ const wikilinkRegex = /\[\[([^\]|]+)(?:\|[^\]]+)?\]\]/g;
85
+ let match;
86
+ while ((match = wikilinkRegex.exec(content)) !== null) {
87
+ const linkTarget = match[1].trim();
88
+ if (linkTarget && !wikilinks.includes(linkTarget)) {
89
+ wikilinks.push(linkTarget);
90
+ }
91
+ }
92
+ return wikilinks;
93
+ }
94
+ /**
95
+ * Validates that a wikilink target exists in the vault
96
+ * @param linkTarget - The target of the wikilink (without brackets)
97
+ * @param existingFiles - Set of existing file paths in the vault
98
+ * @returns true if the target exists, false otherwise
99
+ */
100
+ export function validateWikilinkExists(linkTarget, existingFiles) {
101
+ // Normalize the link target to handle various cases
102
+ const normalizedTarget = linkTarget.toLowerCase().replace(/\s+/g, '-');
103
+ // Check if any file matches the link target
104
+ for (const file of existingFiles) {
105
+ const normalizedFile = file.toLowerCase();
106
+ const fileBasename = normalizedFile.split('/').pop() || '';
107
+ const fileWithoutExt = fileBasename.replace(/\.md$/, '');
108
+ // Check various matching patterns
109
+ if (normalizedFile.endsWith(`/${normalizedTarget}.md`) ||
110
+ normalizedFile.endsWith(`-${normalizedTarget}.md`) ||
111
+ normalizedFile.endsWith(`/${normalizedTarget}`) ||
112
+ normalizedFile.endsWith(`-${normalizedTarget}`) ||
113
+ fileWithoutExt === normalizedTarget ||
114
+ fileWithoutExt.endsWith(`-${normalizedTarget}`) ||
115
+ normalizedFile === `${normalizedTarget}.md` ||
116
+ normalizedFile === normalizedTarget) {
117
+ return true;
118
+ }
119
+ }
120
+ return false;
121
+ }
122
+ /**
123
+ * Extracts all {{placeholder}} references from template text
124
+ * Used primarily for template linting
125
+ */
126
+ export function extractPlaceholders(text) {
127
+ const placeholders = new Set();
128
+ // Match {{variable}} or {{#helper variable}} or {{/helper}}
129
+ const regex = /\{\{(?:#|\/)?([^}#/\s]+)(?:\s+([^}]+))?\}\}/g;
130
+ let match;
131
+ while ((match = regex.exec(text)) !== null) {
132
+ const [fullMatch, helper, args] = match;
133
+ // Skip closing tags
134
+ if (fullMatch.startsWith('{{/')) {
135
+ continue;
136
+ }
137
+ // For block helpers like {{#each}}, extract the variable being iterated
138
+ if (fullMatch.startsWith('{{#')) {
139
+ if (args) {
140
+ // Extract the variable name from the arguments
141
+ const varName = args.trim().split(/\s+/)[0];
142
+ if (varName && !varName.includes('}')) {
143
+ placeholders.add(varName);
144
+ }
145
+ }
146
+ }
147
+ else {
148
+ // Regular placeholder - skip default helpers
149
+ if (!isDefaultHelper(helper)) {
150
+ placeholders.add(helper);
151
+ }
152
+ }
153
+ }
154
+ return placeholders;
155
+ }
156
+ /**
157
+ * Parses frontmatter keys from raw frontmatter string
158
+ * Used for template analysis without full YAML parsing
159
+ */
160
+ export function parseFrontmatterKeys(frontmatter) {
161
+ const keys = new Set();
162
+ const lines = frontmatter.split('\n');
163
+ for (const line of lines) {
164
+ // Match 'key: value' pattern at the start of a line
165
+ const match = line.match(/^(\w+):/);
166
+ if (match) {
167
+ keys.add(match[1]);
168
+ }
169
+ }
170
+ return keys;
171
+ }
172
+ // Helper function for placeholder extraction
173
+ /**
174
+ * Checks if a string value needs YAML quoting
175
+ * Returns true if the string contains characters that could cause YAML parsing issues
176
+ */
177
+ export function needsYamlQuoting(value) {
178
+ if (typeof value !== 'string')
179
+ return false;
180
+ // Check for problematic patterns
181
+ const problematicPatterns = [
182
+ /:/, // Colons can be interpreted as key-value separator
183
+ /\n/, // Newlines need proper handling
184
+ /^['"]/, // Starting quotes
185
+ /^[!&*]/, // YAML special characters
186
+ /^-\s/, // Looks like a list item
187
+ /^\s/, // Leading whitespace
188
+ /\s$/, // Trailing whitespace
189
+ /^(true|false|null|yes|no|on|off)$/i, // YAML keywords
190
+ /^\d+$/, // Pure numbers
191
+ ];
192
+ return problematicPatterns.some(pattern => pattern.test(value));
193
+ }
194
+ /**
195
+ * Checks if a helper name is a default Handlebars helper
196
+ */
197
+ function isDefaultHelper(name) {
198
+ const DEFAULT_HELPERS = ['now', 'each', 'unless', 'if', 'with'];
199
+ return DEFAULT_HELPERS.includes(name);
200
+ }
201
+ /**
202
+ * Parses markdown body text into an AST
203
+ * @param body - The markdown body content (without frontmatter)
204
+ * @returns The parsed AST root node
205
+ */
206
+ export function parseMarkdown(body) {
207
+ const processor = unified().use(remarkParse).use(remarkGfm);
208
+ const ast = processor.parse(body);
209
+ return ast;
210
+ }
211
+ /**
212
+ * Extracts heading text from a heading node, stripping HTML anchors
213
+ * @param heading - The heading node from the AST
214
+ * @returns The clean heading text
215
+ */
216
+ function extractHeadingText(heading) {
217
+ let text = '';
218
+ for (const child of heading.children) {
219
+ if (child.type === 'text') {
220
+ text += child.value;
221
+ }
222
+ else if (child.type === 'html') {
223
+ // Skip HTML anchor tags like <a id="summary"/>
224
+ continue;
225
+ }
226
+ else if ('children' in child) {
227
+ // Handle nested inline elements (emphasis, strong, etc.)
228
+ text += extractInlineText(child.children);
229
+ }
230
+ }
231
+ return text.trim();
232
+ }
233
+ /**
234
+ * Extracts text from phrasing content (inline elements)
235
+ */
236
+ function extractInlineText(children) {
237
+ let text = '';
238
+ for (const child of children) {
239
+ if (child.type === 'text') {
240
+ text += child.value;
241
+ }
242
+ else if ('children' in child) {
243
+ text += extractInlineText(child.children);
244
+ }
245
+ }
246
+ return text;
247
+ }
248
+ /**
249
+ * Normalizes a section title to an ID
250
+ * @param title - The section title
251
+ * @returns The normalized section ID
252
+ */
253
+ function normalizeSectionId(title) {
254
+ return title
255
+ .toLowerCase()
256
+ .trim()
257
+ .replace(/[^\w\s-]/g, '') // Remove special characters
258
+ .replace(/\s+/g, '-') // Replace spaces with dashes
259
+ .replace(/-+/g, '-') // Replace multiple dashes with single dash
260
+ .replace(/^-+|-+$/g, ''); // Remove leading/trailing dashes
261
+ }
262
+ /**
263
+ * Finds all H2 sections in the AST and extracts their content
264
+ * @param ast - The parsed markdown AST
265
+ * @returns Array of section nodes with their content
266
+ */
267
+ export function findSections(ast) {
268
+ const sections = [];
269
+ const children = ast.children;
270
+ let currentSection = null;
271
+ for (let i = 0; i < children.length; i++) {
272
+ const node = children[i];
273
+ // Check if this is an H2 heading
274
+ if (node.type === 'heading' && node.depth === 2) {
275
+ // Save the previous section if it exists
276
+ if (currentSection) {
277
+ sections.push(currentSection);
278
+ }
279
+ // Start a new section
280
+ const title = extractHeadingText(node);
281
+ const id = normalizeSectionId(title);
282
+ currentSection = {
283
+ id,
284
+ title,
285
+ depth: node.depth,
286
+ line: node.position?.start.line || 0,
287
+ column: node.position?.start.column || 0,
288
+ content: [],
289
+ position: node.position
290
+ };
291
+ }
292
+ else if (currentSection) {
293
+ // Add content to the current section
294
+ currentSection.content.push(node);
295
+ }
296
+ // Ignore content before the first H2 section
297
+ }
298
+ // Add the last section
299
+ if (currentSection) {
300
+ sections.push(currentSection);
301
+ }
302
+ return sections;
303
+ }
304
+ /**
305
+ * Stringifies an AST back to markdown
306
+ * @param ast - The AST to stringify
307
+ * @returns The markdown string
308
+ */
309
+ export function stringifyMarkdown(ast) {
310
+ const processor = unified().use(remarkStringify, {
311
+ bullet: '-',
312
+ emphasis: '_',
313
+ fences: true,
314
+ incrementListMarker: true,
315
+ });
316
+ return processor.stringify(ast);
317
+ }
318
+ //# sourceMappingURL=markdown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown.js","sourceRoot":"","sources":["../../src/lib/markdown.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ export type InstallMode = 'fork' | 'npm' | 'unknown';
2
+ /**
3
+ * Detect whether the current project is using fork-based or npm-based distribution.
4
+ *
5
+ * - Fork mode: `.synapse-upstream` file exists in project root
6
+ * - NPM mode: `@synapse/schemas` is resolvable via require.resolve
7
+ * - Unknown: neither detected
8
+ */
9
+ export declare function detectInstallMode(cwd?: string): InstallMode;
10
+ //# sourceMappingURL=mode-detection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mode-detection.d.ts","sourceRoot":"","sources":["../../src/lib/mode-detection.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,KAAK,GAAG,SAAS,CAAC;AAErD;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,WAAW,CAmB3D"}
@@ -0,0 +1,29 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ import { createRequire } from 'module';
4
+ /**
5
+ * Detect whether the current project is using fork-based or npm-based distribution.
6
+ *
7
+ * - Fork mode: `.synapse-upstream` file exists in project root
8
+ * - NPM mode: `@synapse/schemas` is resolvable via require.resolve
9
+ * - Unknown: neither detected
10
+ */
11
+ export function detectInstallMode(cwd) {
12
+ const rootDir = cwd ?? process.cwd();
13
+ // Fork mode: .synapse-upstream tracking file exists
14
+ const upstreamPath = path.join(rootDir, '.synapse-upstream');
15
+ if (fs.existsSync(upstreamPath)) {
16
+ return 'fork';
17
+ }
18
+ // NPM mode: @synapse/schemas is resolvable
19
+ try {
20
+ const require = createRequire(path.join(rootDir, 'package.json'));
21
+ require.resolve('@synapse/schemas/package.json');
22
+ return 'npm';
23
+ }
24
+ catch {
25
+ // Package not installed
26
+ }
27
+ return 'unknown';
28
+ }
29
+ //# sourceMappingURL=mode-detection.js.map