@hiveforge/hivemind-mcp 2.6.1 → 2.7.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.
Files changed (113) hide show
  1. package/dist/cli/fix/fixer.d.ts +100 -0
  2. package/dist/cli/fix/fixer.d.ts.map +1 -0
  3. package/dist/cli/fix/fixer.js +256 -0
  4. package/dist/cli/fix/fixer.js.map +1 -0
  5. package/dist/cli/fix/formatter.d.ts +48 -0
  6. package/dist/cli/fix/formatter.d.ts.map +1 -0
  7. package/dist/cli/fix/formatter.js +159 -0
  8. package/dist/cli/fix/formatter.js.map +1 -0
  9. package/dist/cli/fix/id-generator.d.ts +48 -0
  10. package/dist/cli/fix/id-generator.d.ts.map +1 -0
  11. package/dist/cli/fix/id-generator.js +133 -0
  12. package/dist/cli/fix/id-generator.js.map +1 -0
  13. package/dist/cli/fix/index.d.ts +45 -0
  14. package/dist/cli/fix/index.d.ts.map +1 -0
  15. package/dist/cli/fix/index.js +239 -0
  16. package/dist/cli/fix/index.js.map +1 -0
  17. package/dist/cli/fix/types.d.ts +83 -0
  18. package/dist/cli/fix/types.d.ts.map +1 -0
  19. package/dist/cli/fix/types.js +8 -0
  20. package/dist/cli/fix/types.js.map +1 -0
  21. package/dist/cli/fix/writer.d.ts +44 -0
  22. package/dist/cli/fix/writer.d.ts.map +1 -0
  23. package/dist/cli/fix/writer.js +73 -0
  24. package/dist/cli/fix/writer.js.map +1 -0
  25. package/dist/cli/init/detection.d.ts +18 -0
  26. package/dist/cli/init/detection.d.ts.map +1 -0
  27. package/dist/cli/init/detection.js +40 -0
  28. package/dist/cli/init/detection.js.map +1 -0
  29. package/dist/cli/init/index.d.ts +27 -0
  30. package/dist/cli/init/index.d.ts.map +1 -0
  31. package/dist/cli/init/index.js +115 -0
  32. package/dist/cli/init/index.js.map +1 -0
  33. package/dist/cli/init/output.d.ts +58 -0
  34. package/dist/cli/init/output.d.ts.map +1 -0
  35. package/dist/cli/init/output.js +168 -0
  36. package/dist/cli/init/output.js.map +1 -0
  37. package/dist/cli/init/prompts.d.ts +28 -0
  38. package/dist/cli/init/prompts.d.ts.map +1 -0
  39. package/dist/cli/init/prompts.js +85 -0
  40. package/dist/cli/init/prompts.js.map +1 -0
  41. package/dist/cli/init/validators.d.ts +15 -0
  42. package/dist/cli/init/validators.d.ts.map +1 -0
  43. package/dist/cli/init/validators.js +48 -0
  44. package/dist/cli/init/validators.js.map +1 -0
  45. package/dist/cli/init/wizard.d.ts +22 -0
  46. package/dist/cli/init/wizard.d.ts.map +1 -0
  47. package/dist/cli/init/wizard.js +84 -0
  48. package/dist/cli/init/wizard.js.map +1 -0
  49. package/dist/cli/shared/clipboard.d.ts +2 -0
  50. package/dist/cli/shared/clipboard.d.ts.map +1 -0
  51. package/dist/cli/shared/clipboard.js +12 -0
  52. package/dist/cli/shared/clipboard.js.map +1 -0
  53. package/dist/cli/shared/colors.d.ts +6 -0
  54. package/dist/cli/shared/colors.d.ts.map +1 -0
  55. package/dist/cli/shared/colors.js +7 -0
  56. package/dist/cli/shared/colors.js.map +1 -0
  57. package/dist/cli/validate/formatter.d.ts +25 -0
  58. package/dist/cli/validate/formatter.d.ts.map +1 -0
  59. package/dist/cli/validate/formatter.js +156 -0
  60. package/dist/cli/validate/formatter.js.map +1 -0
  61. package/dist/cli/validate/index.d.ts +12 -0
  62. package/dist/cli/validate/index.d.ts.map +1 -0
  63. package/dist/cli/validate/index.js +105 -0
  64. package/dist/cli/validate/index.js.map +1 -0
  65. package/dist/cli/validate/scanner.d.ts +32 -0
  66. package/dist/cli/validate/scanner.d.ts.map +1 -0
  67. package/dist/cli/validate/scanner.js +114 -0
  68. package/dist/cli/validate/scanner.js.map +1 -0
  69. package/dist/cli/validate/types.d.ts +71 -0
  70. package/dist/cli/validate/types.d.ts.map +1 -0
  71. package/dist/cli/validate/types.js +7 -0
  72. package/dist/cli/validate/types.js.map +1 -0
  73. package/dist/cli/validate/validator.d.ts +24 -0
  74. package/dist/cli/validate/validator.d.ts.map +1 -0
  75. package/dist/cli/validate/validator.js +133 -0
  76. package/dist/cli/validate/validator.js.map +1 -0
  77. package/dist/cli.js +24 -353
  78. package/dist/cli.js.map +1 -1
  79. package/dist/comfyui/client.js +1 -1
  80. package/dist/comfyui/client.js.map +1 -1
  81. package/dist/graph/database.js +1 -1
  82. package/dist/graph/database.js.map +1 -1
  83. package/dist/index.js +1 -1
  84. package/dist/index.js.map +1 -1
  85. package/dist/search/engine.js +1 -1
  86. package/dist/search/engine.js.map +1 -1
  87. package/dist/templates/builtin/people-management.d.ts.map +1 -1
  88. package/dist/templates/builtin/people-management.js +19 -0
  89. package/dist/templates/builtin/people-management.js.map +1 -1
  90. package/dist/templates/builtin/research.d.ts.map +1 -1
  91. package/dist/templates/builtin/research.js +18 -0
  92. package/dist/templates/builtin/research.js.map +1 -1
  93. package/dist/templates/builtin/worldbuilding.d.ts.map +1 -1
  94. package/dist/templates/builtin/worldbuilding.js +44 -0
  95. package/dist/templates/builtin/worldbuilding.js.map +1 -1
  96. package/dist/templates/folder-mapper.d.ts +61 -36
  97. package/dist/templates/folder-mapper.d.ts.map +1 -1
  98. package/dist/templates/folder-mapper.js +176 -53
  99. package/dist/templates/folder-mapper.js.map +1 -1
  100. package/dist/templates/registry.d.ts +11 -1
  101. package/dist/templates/registry.d.ts.map +1 -1
  102. package/dist/templates/registry.js +16 -0
  103. package/dist/templates/registry.js.map +1 -1
  104. package/dist/templates/types.d.ts +47 -0
  105. package/dist/templates/types.d.ts.map +1 -1
  106. package/dist/templates/validator.d.ts +15 -0
  107. package/dist/templates/validator.d.ts.map +1 -1
  108. package/dist/templates/validator.js +8 -0
  109. package/dist/templates/validator.js.map +1 -1
  110. package/dist/types/index.d.ts +5 -5
  111. package/dist/vault/reader.js +1 -1
  112. package/dist/vault/reader.js.map +1 -1
  113. package/package.json +8 -2
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Result of interactive wizard.
3
+ */
4
+ export interface WizardResult {
5
+ vaultPath: string;
6
+ templateId: string;
7
+ cancelled: boolean;
8
+ }
9
+ /**
10
+ * Run the interactive setup wizard.
11
+ *
12
+ * Flow:
13
+ * 1. Check for TTY (bail if non-interactive)
14
+ * 2. Check for existing config.json (prompt to overwrite)
15
+ * 3. Prompt for vault path
16
+ * 4. Auto-detect template or manual selection
17
+ * 5. Return result for config generation
18
+ *
19
+ * @returns Wizard result with vault path and template ID
20
+ */
21
+ export declare function runInteractiveWizard(): Promise<WizardResult>;
22
+ //# sourceMappingURL=wizard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wizard.d.ts","sourceRoot":"","sources":["../../../src/cli/init/wizard.ts"],"names":[],"mappings":"AAsBA;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,YAAY,CAAC,CAyDlE"}
@@ -0,0 +1,84 @@
1
+ import { ExitPromptError } from '@inquirer/core';
2
+ import { promptVaultPath, promptOverwriteConfig } from './prompts.js';
3
+ import { detectAndConfirmTemplate } from './detection.js';
4
+ import { configExists } from './validators.js';
5
+ import { success, error, dim, bold } from '../shared/colors.js';
6
+ /**
7
+ * Breadcrumb steps for progress display.
8
+ */
9
+ const STEPS = ['Vault', 'Template', 'Config', 'Done'];
10
+ /**
11
+ * Render breadcrumb progress indicator.
12
+ */
13
+ function renderBreadcrumb(current) {
14
+ return STEPS.map((step, i) => {
15
+ if (i < current)
16
+ return dim(step);
17
+ if (i === current)
18
+ return bold(step);
19
+ return dim(step);
20
+ }).join(dim(' > '));
21
+ }
22
+ /**
23
+ * Run the interactive setup wizard.
24
+ *
25
+ * Flow:
26
+ * 1. Check for TTY (bail if non-interactive)
27
+ * 2. Check for existing config.json (prompt to overwrite)
28
+ * 3. Prompt for vault path
29
+ * 4. Auto-detect template or manual selection
30
+ * 5. Return result for config generation
31
+ *
32
+ * @returns Wizard result with vault path and template ID
33
+ */
34
+ export async function runInteractiveWizard() {
35
+ // Check for TTY before prompts
36
+ if (!process.stdin.isTTY) {
37
+ console.error(error('Interactive mode requires a terminal.'));
38
+ console.error('Use --config <preset.json> or flags for non-interactive mode.');
39
+ process.exit(1);
40
+ }
41
+ try {
42
+ console.log('\n' + bold('Hivemind Setup Wizard'));
43
+ console.log('='.repeat(40) + '\n');
44
+ // Step 1: Check for existing config
45
+ const cwd = process.cwd();
46
+ if (configExists(cwd)) {
47
+ const overwrite = await promptOverwriteConfig();
48
+ if (!overwrite) {
49
+ console.log('\nSetup cancelled.');
50
+ return { vaultPath: '', templateId: '', cancelled: true };
51
+ }
52
+ }
53
+ // Step 2: Vault path
54
+ console.log('\n' + renderBreadcrumb(0));
55
+ const vaultPath = await promptVaultPath();
56
+ console.log(success(`Using vault: ${vaultPath}`));
57
+ // Step 3: Template selection (with auto-detection)
58
+ console.log('\n' + renderBreadcrumb(1));
59
+ let templateId = await detectAndConfirmTemplate(vaultPath);
60
+ // Handle custom template selection
61
+ if (templateId === 'custom') {
62
+ console.log('\n' + dim('Custom template creation will be available after initial setup.'));
63
+ console.log(dim('For now, starting with worldbuilding template. Run create-template later.'));
64
+ templateId = 'worldbuilding';
65
+ }
66
+ console.log(success(`Using template: ${templateId}`));
67
+ // Step 4: Complete
68
+ console.log('\n' + renderBreadcrumb(3));
69
+ return {
70
+ vaultPath,
71
+ templateId,
72
+ cancelled: false,
73
+ };
74
+ }
75
+ catch (err) {
76
+ // Handle Ctrl+C gracefully
77
+ if (err instanceof ExitPromptError) {
78
+ console.log('\n\nSetup cancelled.');
79
+ return { vaultPath: '', templateId: '', cancelled: true };
80
+ }
81
+ throw err;
82
+ }
83
+ }
84
+ //# sourceMappingURL=wizard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wizard.js","sourceRoot":"","sources":["../../../src/cli/init/wizard.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function copyToClipboard(text: string): Promise<boolean>;
2
+ //# sourceMappingURL=clipboard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clipboard.d.ts","sourceRoot":"","sources":["../../../src/cli/shared/clipboard.ts"],"names":[],"mappings":"AAEA,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAQpE"}
@@ -0,0 +1,12 @@
1
+ import clipboard from 'clipboardy';
2
+ export async function copyToClipboard(text) {
3
+ try {
4
+ await clipboard.write(text);
5
+ return true;
6
+ }
7
+ catch {
8
+ // Clipboard may not be available in all environments (CI, SSH, etc.)
9
+ return false;
10
+ }
11
+ }
12
+ //# sourceMappingURL=clipboard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clipboard.js","sourceRoot":"","sources":["../../../src/cli/shared/clipboard.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,YAAY,CAAC;AAEnC,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,IAAY;IAChD,IAAI,CAAC;QACH,MAAM,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC5B,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,qEAAqE;QACrE,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
@@ -0,0 +1,6 @@
1
+ export declare const success: (text: string) => string;
2
+ export declare const error: (text: string) => string;
3
+ export declare const dim: (text: string) => string;
4
+ export declare const bold: (text: string) => string;
5
+ export declare const warn: (text: string) => string;
6
+ //# sourceMappingURL=colors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"colors.d.ts","sourceRoot":"","sources":["../../../src/cli/shared/colors.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,OAAO,GAAI,MAAM,MAAM,WAAmB,CAAC;AACxD,eAAO,MAAM,KAAK,GAAI,MAAM,MAAM,WAAiB,CAAC;AACpD,eAAO,MAAM,GAAG,GAAI,MAAM,MAAM,WAAiB,CAAC;AAClD,eAAO,MAAM,IAAI,GAAI,MAAM,MAAM,WAAkB,CAAC;AACpD,eAAO,MAAM,IAAI,GAAI,MAAM,MAAM,WAAoB,CAAC"}
@@ -0,0 +1,7 @@
1
+ import pc from 'picocolors';
2
+ export const success = (text) => pc.green(text);
3
+ export const error = (text) => pc.red(text);
4
+ export const dim = (text) => pc.dim(text);
5
+ export const bold = (text) => pc.bold(text);
6
+ export const warn = (text) => pc.yellow(text);
7
+ //# sourceMappingURL=colors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"colors.js","sourceRoot":"","sources":["../../../src/cli/shared/colors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AACxD,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AACpD,MAAM,CAAC,MAAM,GAAG,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAClD,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACpD,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Output formatters for vault validation results.
3
+ *
4
+ * Provides text (grouped by issue type) and JSON (grouped by file) output.
5
+ */
6
+ import type { ValidationResult, ValidationSummary, ValidationIssue } from './types.js';
7
+ /**
8
+ * Format a single validation issue as a human-readable message.
9
+ */
10
+ export declare function formatIssueMessage(issue: ValidationIssue): string;
11
+ /**
12
+ * Calculate summary statistics from validation results.
13
+ */
14
+ export declare function calculateSummary(results: ValidationResult[]): ValidationSummary;
15
+ /**
16
+ * Format validation results as grouped text output.
17
+ * Groups results by issue type (all "missing frontmatter" together, etc.).
18
+ */
19
+ export declare function formatTextOutput(results: ValidationResult[], summary: ValidationSummary): string;
20
+ /**
21
+ * Format validation results as JSON output.
22
+ * Groups results by file for machine-readable processing.
23
+ */
24
+ export declare function formatJsonOutput(results: ValidationResult[], summary: ValidationSummary, vaultPath: string): string;
25
+ //# sourceMappingURL=formatter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatter.d.ts","sourceRoot":"","sources":["../../../src/cli/validate/formatter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAGvF;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM,CAajE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,gBAAgB,EAAE,GAAG,iBAAiB,CA4B/E;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,gBAAgB,EAAE,EAAE,OAAO,EAAE,iBAAiB,GAAG,MAAM,CAwFhG;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,gBAAgB,EAAE,EAC3B,OAAO,EAAE,iBAAiB,EAC1B,SAAS,EAAE,MAAM,GAChB,MAAM,CA6BR"}
@@ -0,0 +1,156 @@
1
+ /**
2
+ * Output formatters for vault validation results.
3
+ *
4
+ * Provides text (grouped by issue type) and JSON (grouped by file) output.
5
+ */
6
+ import { error, bold } from '../shared/colors.js';
7
+ /**
8
+ * Format a single validation issue as a human-readable message.
9
+ */
10
+ export function formatIssueMessage(issue) {
11
+ switch (issue.type) {
12
+ case 'missing_frontmatter':
13
+ return 'Missing frontmatter';
14
+ case 'missing_field':
15
+ return `Missing required field: ${issue.field}`;
16
+ case 'invalid_type':
17
+ return `Invalid type "${issue.actual}" (valid: ${issue.validTypes.join(', ')})`;
18
+ case 'schema_error':
19
+ return `${issue.field}: ${issue.message}`;
20
+ case 'folder_mismatch':
21
+ return `Folder suggests type "${issue.expected}" but file has type "${issue.actual}"`;
22
+ }
23
+ }
24
+ /**
25
+ * Calculate summary statistics from validation results.
26
+ */
27
+ export function calculateSummary(results) {
28
+ const summary = {
29
+ totalFiles: results.length,
30
+ validFiles: 0,
31
+ invalidFiles: 0,
32
+ issuesByType: {
33
+ missing_frontmatter: 0,
34
+ missing_field: 0,
35
+ invalid_type: 0,
36
+ schema_error: 0,
37
+ folder_mismatch: 0,
38
+ },
39
+ };
40
+ for (const result of results) {
41
+ if (result.valid) {
42
+ summary.validFiles++;
43
+ }
44
+ else {
45
+ summary.invalidFiles++;
46
+ // Count issues by type
47
+ for (const issue of result.issues) {
48
+ summary.issuesByType[issue.type]++;
49
+ }
50
+ }
51
+ }
52
+ return summary;
53
+ }
54
+ /**
55
+ * Format validation results as grouped text output.
56
+ * Groups results by issue type (all "missing frontmatter" together, etc.).
57
+ */
58
+ export function formatTextOutput(results, summary) {
59
+ // Filter to only invalid files
60
+ const invalidResults = results.filter((r) => !r.valid);
61
+ // Group results by issue type
62
+ const groups = {
63
+ missing_frontmatter: invalidResults.filter((r) => r.issues.some((i) => i.type === 'missing_frontmatter')),
64
+ invalid_type: invalidResults.filter((r) => r.issues.some((i) => i.type === 'invalid_type')),
65
+ missing_field: invalidResults.filter((r) => r.issues.some((i) => i.type === 'missing_field')),
66
+ schema_error: invalidResults.filter((r) => r.issues.some((i) => i.type === 'schema_error')),
67
+ folder_mismatch: invalidResults.filter((r) => r.issues.some((i) => i.type === 'folder_mismatch')),
68
+ };
69
+ const output = [];
70
+ // Output each group with header
71
+ if (groups.missing_frontmatter.length > 0) {
72
+ output.push(error('Missing frontmatter:'));
73
+ for (const result of groups.missing_frontmatter) {
74
+ output.push(` ${result.path}`);
75
+ }
76
+ output.push('');
77
+ }
78
+ if (groups.invalid_type.length > 0) {
79
+ output.push(error('Invalid type:'));
80
+ for (const result of groups.invalid_type) {
81
+ const issue = result.issues.find((i) => i.type === 'invalid_type');
82
+ if (issue && issue.type === 'invalid_type') {
83
+ output.push(` ${result.path}: "${issue.actual}" (valid: ${issue.validTypes.join(', ')})`);
84
+ }
85
+ }
86
+ output.push('');
87
+ }
88
+ if (groups.missing_field.length > 0) {
89
+ output.push(error('Missing required fields:'));
90
+ for (const result of groups.missing_field) {
91
+ const missingFields = result.issues
92
+ .filter((i) => i.type === 'missing_field')
93
+ .map((i) => i.field);
94
+ output.push(` ${result.path}: ${missingFields.join(', ')}`);
95
+ }
96
+ output.push('');
97
+ }
98
+ if (groups.schema_error.length > 0) {
99
+ output.push(error('Schema validation errors:'));
100
+ for (const result of groups.schema_error) {
101
+ const schemaIssues = result.issues.filter((i) => i.type === 'schema_error');
102
+ output.push(` ${result.path}:`);
103
+ for (const issue of schemaIssues) {
104
+ if (issue.type === 'schema_error') {
105
+ output.push(` - ${issue.field}: ${issue.message}`);
106
+ }
107
+ }
108
+ }
109
+ output.push('');
110
+ }
111
+ if (groups.folder_mismatch.length > 0) {
112
+ output.push(error('Folder mismatches:'));
113
+ for (const result of groups.folder_mismatch) {
114
+ const issue = result.issues.find((i) => i.type === 'folder_mismatch');
115
+ if (issue && issue.type === 'folder_mismatch') {
116
+ output.push(` ${result.path}: folder suggests "${issue.expected}", file has "${issue.actual}"`);
117
+ }
118
+ }
119
+ output.push('');
120
+ }
121
+ // Summary line at end (always shown if there are issues)
122
+ const totalIssues = Object.values(summary.issuesByType).reduce((a, b) => a + b, 0);
123
+ output.push(bold(`Found ${totalIssues} issue${totalIssues === 1 ? '' : 's'} in ${summary.invalidFiles} file${summary.invalidFiles === 1 ? '' : 's'}`));
124
+ return output.join('\n');
125
+ }
126
+ /**
127
+ * Format validation results as JSON output.
128
+ * Groups results by file for machine-readable processing.
129
+ */
130
+ export function formatJsonOutput(results, summary, vaultPath) {
131
+ const files = {};
132
+ // Only include invalid files
133
+ for (const result of results) {
134
+ if (!result.valid) {
135
+ files[result.path] = result.issues.map(formatIssueMessage);
136
+ }
137
+ }
138
+ const totalIssues = Object.values(summary.issuesByType).reduce((a, b) => a + b, 0);
139
+ const output = {
140
+ valid: summary.invalidFiles === 0,
141
+ timestamp: new Date().toISOString(),
142
+ vaultPath,
143
+ totalFiles: summary.totalFiles,
144
+ totalIssues,
145
+ files,
146
+ summary: {
147
+ missingFrontmatter: summary.issuesByType.missing_frontmatter || 0,
148
+ invalidType: summary.issuesByType.invalid_type || 0,
149
+ missingField: summary.issuesByType.missing_field || 0,
150
+ schemaErrors: summary.issuesByType.schema_error || 0,
151
+ folderMismatches: summary.issuesByType.folder_mismatch || 0,
152
+ },
153
+ };
154
+ return JSON.stringify(output, null, 2);
155
+ }
156
+ //# sourceMappingURL=formatter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatter.js","sourceRoot":"","sources":["../../../src/cli/validate/formatter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * CLI validate command entry point.
3
+ *
4
+ * Handles argument parsing, config loading, and orchestrates validation.
5
+ */
6
+ /**
7
+ * Main entry point for validate command.
8
+ *
9
+ * Loads config, parses arguments, runs validation, and outputs results.
10
+ */
11
+ export declare function validateCommand(): Promise<void>;
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cli/validate/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAwCH;;;;GAIG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAqErD"}
@@ -0,0 +1,105 @@
1
+ /**
2
+ * CLI validate command entry point.
3
+ *
4
+ * Handles argument parsing, config loading, and orchestrates validation.
5
+ */
6
+ import { readFileSync, existsSync } from 'fs';
7
+ import { resolve } from 'path';
8
+ import { ValidationScanner } from './scanner.js';
9
+ import { formatTextOutput, formatJsonOutput, calculateSummary } from './formatter.js';
10
+ import { initializeTemplateRegistry } from './validator.js';
11
+ import { outputMissingConfigError } from '../init/output.js';
12
+ /**
13
+ * Parse command-line arguments for validate command.
14
+ */
15
+ function parseValidateArgs() {
16
+ const args = process.argv.slice(3); // Skip node, script, 'validate'
17
+ const options = {
18
+ skipMissing: args.includes('--skip-missing'),
19
+ ignorePatterns: [],
20
+ json: args.includes('--json'),
21
+ quiet: args.includes('--quiet'),
22
+ };
23
+ // Parse --ignore patterns (can appear multiple times)
24
+ for (let i = 0; i < args.length; i++) {
25
+ if (args[i] === '--ignore' && args[i + 1]) {
26
+ options.ignorePatterns.push(args[i + 1]);
27
+ }
28
+ }
29
+ // Parse target path (non-flag argument)
30
+ const nonFlagArgs = args.filter((a) => !a.startsWith('-') && args[args.indexOf(a) - 1] !== '--ignore');
31
+ if (nonFlagArgs.length > 0) {
32
+ options.targetPath = nonFlagArgs[0];
33
+ }
34
+ return options;
35
+ }
36
+ /**
37
+ * Main entry point for validate command.
38
+ *
39
+ * Loads config, parses arguments, runs validation, and outputs results.
40
+ */
41
+ export async function validateCommand() {
42
+ // 1. Load config
43
+ const configPath = resolve(process.cwd(), 'config.json');
44
+ if (!existsSync(configPath)) {
45
+ outputMissingConfigError();
46
+ process.exit(2); // Config error
47
+ }
48
+ let config;
49
+ try {
50
+ config = JSON.parse(readFileSync(configPath, 'utf-8'));
51
+ }
52
+ catch (err) {
53
+ console.error('Configuration error:', err instanceof Error ? err.message : String(err));
54
+ process.exit(2);
55
+ }
56
+ // 2. Get vault path
57
+ const vaultPath = resolve(config.vault?.path);
58
+ if (!vaultPath || !existsSync(vaultPath)) {
59
+ console.error('Vault path does not exist:', vaultPath);
60
+ process.exit(2);
61
+ }
62
+ // 3. Parse arguments
63
+ const parsedOptions = parseValidateArgs();
64
+ const options = {
65
+ ...parsedOptions,
66
+ vaultPath,
67
+ };
68
+ // 4. Initialize template registry
69
+ const activeTemplate = config.template?.activeTemplate || 'worldbuilding';
70
+ try {
71
+ await initializeTemplateRegistry(activeTemplate);
72
+ }
73
+ catch (err) {
74
+ console.error('Template error:', err instanceof Error ? err.message : String(err));
75
+ process.exit(2);
76
+ }
77
+ // 5. Run scanner
78
+ const scanner = new ValidationScanner(options);
79
+ const results = await scanner.scan();
80
+ const summary = calculateSummary(results);
81
+ // 6. Output results based on flags
82
+ if (summary.invalidFiles === 0) {
83
+ // Silent success per CONTEXT.md
84
+ process.exit(0);
85
+ }
86
+ if (!options.quiet) {
87
+ if (options.json) {
88
+ console.log(formatJsonOutput(results, summary, vaultPath));
89
+ }
90
+ else {
91
+ console.log(formatTextOutput(results, summary));
92
+ // ERR-03: Suggestions when vault has no valid entities
93
+ if (summary.validFiles === 0 && summary.totalFiles > 0) {
94
+ console.log('');
95
+ console.log('Your vault has no files with valid frontmatter.');
96
+ console.log('Try:');
97
+ console.log(' 1. Run "npx hivemind fix" to add frontmatter to existing files');
98
+ console.log(' 2. Check that your templates match your content types');
99
+ console.log(' 3. Run "npx hivemind init" to reconfigure if needed');
100
+ }
101
+ }
102
+ }
103
+ process.exit(1); // Validation errors found
104
+ }
105
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/cli/validate/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Validation scanner for discovering and validating markdown files in vault.
3
+ *
4
+ * Reuses VaultReader's file discovery logic with exclusion support.
5
+ */
6
+ import type { ValidateOptions, ValidationResult } from './types.js';
7
+ /**
8
+ * Scanner for discovering and validating vault files.
9
+ */
10
+ export declare class ValidationScanner {
11
+ private options;
12
+ constructor(options: ValidateOptions);
13
+ /**
14
+ * Scan vault and validate all markdown files.
15
+ *
16
+ * @returns Array of validation results for all files
17
+ */
18
+ scan(): Promise<ValidationResult[]>;
19
+ /**
20
+ * Recursively find all markdown files in a directory.
21
+ *
22
+ * Adapted from VaultReader.findMarkdownFiles with exclusion support.
23
+ */
24
+ private findMarkdownFiles;
25
+ /**
26
+ * Check if a file/directory should be excluded.
27
+ *
28
+ * Adapted from VaultReader.shouldExclude with user patterns support.
29
+ */
30
+ private shouldExclude;
31
+ }
32
+ //# sourceMappingURL=scanner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../../../src/cli/validate/scanner.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAGpE;;GAEG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,OAAO,CAAkB;gBAErB,OAAO,EAAE,eAAe;IAIpC;;;;OAIG;IACG,IAAI,IAAI,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAgCzC;;;;OAIG;YACW,iBAAiB;IA8B/B;;;;OAIG;IACH,OAAO,CAAC,aAAa;CA6BtB"}
@@ -0,0 +1,114 @@
1
+ /**
2
+ * Validation scanner for discovering and validating markdown files in vault.
3
+ *
4
+ * Reuses VaultReader's file discovery logic with exclusion support.
5
+ */
6
+ import { promises as fs } from 'fs';
7
+ import { join, relative } from 'path';
8
+ import picomatch from 'picomatch';
9
+ import { validateFile } from './validator.js';
10
+ /**
11
+ * Scanner for discovering and validating vault files.
12
+ */
13
+ export class ValidationScanner {
14
+ options;
15
+ constructor(options) {
16
+ this.options = options;
17
+ }
18
+ /**
19
+ * Scan vault and validate all markdown files.
20
+ *
21
+ * @returns Array of validation results for all files
22
+ */
23
+ async scan() {
24
+ const results = [];
25
+ // Determine starting path (targetPath or vaultPath)
26
+ const startPath = this.options.targetPath
27
+ ? join(this.options.vaultPath, this.options.targetPath)
28
+ : this.options.vaultPath;
29
+ // Find all markdown files
30
+ const files = await this.findMarkdownFiles(startPath);
31
+ // Validate each file
32
+ for (const filePath of files) {
33
+ try {
34
+ const result = await validateFile(filePath, this.options.vaultPath, {
35
+ skipMissing: this.options.skipMissing,
36
+ });
37
+ results.push(result);
38
+ }
39
+ catch (_error) {
40
+ // If file can't be read, include error in results
41
+ const relPath = relative(this.options.vaultPath, filePath);
42
+ results.push({
43
+ path: relPath,
44
+ valid: false,
45
+ issues: [{ type: 'missing_frontmatter' }],
46
+ });
47
+ }
48
+ }
49
+ return results;
50
+ }
51
+ /**
52
+ * Recursively find all markdown files in a directory.
53
+ *
54
+ * Adapted from VaultReader.findMarkdownFiles with exclusion support.
55
+ */
56
+ async findMarkdownFiles(dir) {
57
+ const results = [];
58
+ try {
59
+ const entries = await fs.readdir(dir, { withFileTypes: true });
60
+ for (const entry of entries) {
61
+ const fullPath = join(dir, entry.name);
62
+ // Skip excluded patterns
63
+ if (this.shouldExclude(entry.name)) {
64
+ continue;
65
+ }
66
+ if (entry.isDirectory()) {
67
+ // Recursively search subdirectories
68
+ const subFiles = await this.findMarkdownFiles(fullPath);
69
+ results.push(...subFiles);
70
+ }
71
+ else if (entry.isFile() && entry.name.endsWith('.md')) {
72
+ results.push(fullPath);
73
+ }
74
+ }
75
+ }
76
+ catch (error) {
77
+ // Skip directories we can't read
78
+ console.error(`Error reading directory ${dir}:`, error);
79
+ }
80
+ return results;
81
+ }
82
+ /**
83
+ * Check if a file/directory should be excluded.
84
+ *
85
+ * Adapted from VaultReader.shouldExclude with user patterns support.
86
+ */
87
+ shouldExclude(name) {
88
+ const defaultExcludes = [
89
+ '.obsidian',
90
+ '.trash',
91
+ '.git',
92
+ 'node_modules',
93
+ '_template.md',
94
+ ];
95
+ const excludePatterns = [
96
+ ...defaultExcludes,
97
+ ...(this.options.ignorePatterns || []),
98
+ ];
99
+ // Check for hidden files/folders (starting with .)
100
+ if (name.startsWith('.')) {
101
+ return true;
102
+ }
103
+ return excludePatterns.some((pattern) => {
104
+ if (pattern.includes('*')) {
105
+ // Glob pattern matching with picomatch
106
+ const matcher = picomatch(pattern);
107
+ return matcher(name);
108
+ }
109
+ // Exact match or prefix match
110
+ return name === pattern || name.startsWith(pattern);
111
+ });
112
+ }
113
+ }
114
+ //# sourceMappingURL=scanner.js.map