@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.
- package/dist/cli/fix/fixer.d.ts +100 -0
- package/dist/cli/fix/fixer.d.ts.map +1 -0
- package/dist/cli/fix/fixer.js +256 -0
- package/dist/cli/fix/fixer.js.map +1 -0
- package/dist/cli/fix/formatter.d.ts +48 -0
- package/dist/cli/fix/formatter.d.ts.map +1 -0
- package/dist/cli/fix/formatter.js +159 -0
- package/dist/cli/fix/formatter.js.map +1 -0
- package/dist/cli/fix/id-generator.d.ts +48 -0
- package/dist/cli/fix/id-generator.d.ts.map +1 -0
- package/dist/cli/fix/id-generator.js +133 -0
- package/dist/cli/fix/id-generator.js.map +1 -0
- package/dist/cli/fix/index.d.ts +45 -0
- package/dist/cli/fix/index.d.ts.map +1 -0
- package/dist/cli/fix/index.js +239 -0
- package/dist/cli/fix/index.js.map +1 -0
- package/dist/cli/fix/types.d.ts +83 -0
- package/dist/cli/fix/types.d.ts.map +1 -0
- package/dist/cli/fix/types.js +8 -0
- package/dist/cli/fix/types.js.map +1 -0
- package/dist/cli/fix/writer.d.ts +44 -0
- package/dist/cli/fix/writer.d.ts.map +1 -0
- package/dist/cli/fix/writer.js +73 -0
- package/dist/cli/fix/writer.js.map +1 -0
- package/dist/cli/init/detection.d.ts +18 -0
- package/dist/cli/init/detection.d.ts.map +1 -0
- package/dist/cli/init/detection.js +40 -0
- package/dist/cli/init/detection.js.map +1 -0
- package/dist/cli/init/index.d.ts +27 -0
- package/dist/cli/init/index.d.ts.map +1 -0
- package/dist/cli/init/index.js +115 -0
- package/dist/cli/init/index.js.map +1 -0
- package/dist/cli/init/output.d.ts +58 -0
- package/dist/cli/init/output.d.ts.map +1 -0
- package/dist/cli/init/output.js +168 -0
- package/dist/cli/init/output.js.map +1 -0
- package/dist/cli/init/prompts.d.ts +28 -0
- package/dist/cli/init/prompts.d.ts.map +1 -0
- package/dist/cli/init/prompts.js +85 -0
- package/dist/cli/init/prompts.js.map +1 -0
- package/dist/cli/init/validators.d.ts +15 -0
- package/dist/cli/init/validators.d.ts.map +1 -0
- package/dist/cli/init/validators.js +48 -0
- package/dist/cli/init/validators.js.map +1 -0
- package/dist/cli/init/wizard.d.ts +22 -0
- package/dist/cli/init/wizard.d.ts.map +1 -0
- package/dist/cli/init/wizard.js +84 -0
- package/dist/cli/init/wizard.js.map +1 -0
- package/dist/cli/shared/clipboard.d.ts +2 -0
- package/dist/cli/shared/clipboard.d.ts.map +1 -0
- package/dist/cli/shared/clipboard.js +12 -0
- package/dist/cli/shared/clipboard.js.map +1 -0
- package/dist/cli/shared/colors.d.ts +6 -0
- package/dist/cli/shared/colors.d.ts.map +1 -0
- package/dist/cli/shared/colors.js +7 -0
- package/dist/cli/shared/colors.js.map +1 -0
- package/dist/cli/validate/formatter.d.ts +25 -0
- package/dist/cli/validate/formatter.d.ts.map +1 -0
- package/dist/cli/validate/formatter.js +156 -0
- package/dist/cli/validate/formatter.js.map +1 -0
- package/dist/cli/validate/index.d.ts +12 -0
- package/dist/cli/validate/index.d.ts.map +1 -0
- package/dist/cli/validate/index.js +105 -0
- package/dist/cli/validate/index.js.map +1 -0
- package/dist/cli/validate/scanner.d.ts +32 -0
- package/dist/cli/validate/scanner.d.ts.map +1 -0
- package/dist/cli/validate/scanner.js +114 -0
- package/dist/cli/validate/scanner.js.map +1 -0
- package/dist/cli/validate/types.d.ts +71 -0
- package/dist/cli/validate/types.d.ts.map +1 -0
- package/dist/cli/validate/types.js +7 -0
- package/dist/cli/validate/types.js.map +1 -0
- package/dist/cli/validate/validator.d.ts +24 -0
- package/dist/cli/validate/validator.d.ts.map +1 -0
- package/dist/cli/validate/validator.js +133 -0
- package/dist/cli/validate/validator.js.map +1 -0
- package/dist/cli.js +24 -353
- package/dist/cli.js.map +1 -1
- package/dist/comfyui/client.js +1 -1
- package/dist/comfyui/client.js.map +1 -1
- package/dist/graph/database.js +1 -1
- package/dist/graph/database.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/search/engine.js +1 -1
- package/dist/search/engine.js.map +1 -1
- package/dist/templates/builtin/people-management.d.ts.map +1 -1
- package/dist/templates/builtin/people-management.js +19 -0
- package/dist/templates/builtin/people-management.js.map +1 -1
- package/dist/templates/builtin/research.d.ts.map +1 -1
- package/dist/templates/builtin/research.js +18 -0
- package/dist/templates/builtin/research.js.map +1 -1
- package/dist/templates/builtin/worldbuilding.d.ts.map +1 -1
- package/dist/templates/builtin/worldbuilding.js +44 -0
- package/dist/templates/builtin/worldbuilding.js.map +1 -1
- package/dist/templates/folder-mapper.d.ts +61 -36
- package/dist/templates/folder-mapper.d.ts.map +1 -1
- package/dist/templates/folder-mapper.js +176 -53
- package/dist/templates/folder-mapper.js.map +1 -1
- package/dist/templates/registry.d.ts +11 -1
- package/dist/templates/registry.d.ts.map +1 -1
- package/dist/templates/registry.js +16 -0
- package/dist/templates/registry.js.map +1 -1
- package/dist/templates/types.d.ts +47 -0
- package/dist/templates/types.d.ts.map +1 -1
- package/dist/templates/validator.d.ts +15 -0
- package/dist/templates/validator.d.ts.map +1 -1
- package/dist/templates/validator.js +8 -0
- package/dist/templates/validator.js.map +1 -1
- package/dist/types/index.d.ts +5 -5
- package/dist/vault/reader.js +1 -1
- package/dist/vault/reader.js.map +1 -1
- 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 @@
|
|
|
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":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAElD;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAsB;IACvD,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,KAAK,qBAAqB;YACxB,OAAO,qBAAqB,CAAC;QAC/B,KAAK,eAAe;YAClB,OAAO,2BAA2B,KAAK,CAAC,KAAK,EAAE,CAAC;QAClD,KAAK,cAAc;YACjB,OAAO,iBAAiB,KAAK,CAAC,MAAM,aAAa,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;QAClF,KAAK,cAAc;YACjB,OAAO,GAAG,KAAK,CAAC,KAAK,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC;QAC5C,KAAK,iBAAiB;YACpB,OAAO,yBAAyB,KAAK,CAAC,QAAQ,wBAAwB,KAAK,CAAC,MAAM,GAAG,CAAC;IAC1F,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAA2B;IAC1D,MAAM,OAAO,GAAsB;QACjC,UAAU,EAAE,OAAO,CAAC,MAAM;QAC1B,UAAU,EAAE,CAAC;QACb,YAAY,EAAE,CAAC;QACf,YAAY,EAAE;YACZ,mBAAmB,EAAE,CAAC;YACtB,aAAa,EAAE,CAAC;YAChB,YAAY,EAAE,CAAC;YACf,YAAY,EAAE,CAAC;YACf,eAAe,EAAE,CAAC;SACnB;KACF,CAAC;IAEF,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YACjB,OAAO,CAAC,UAAU,EAAE,CAAC;QACvB,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,YAAY,EAAE,CAAC;YAEvB,uBAAuB;YACvB,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;gBAClC,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACrC,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAA2B,EAAE,OAA0B;IACtF,+BAA+B;IAC/B,MAAM,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IAEvD,8BAA8B;IAC9B,MAAM,MAAM,GAAG;QACb,mBAAmB,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAC/C,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,qBAAqB,CAAC,CACvD;QACD,YAAY,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CACxC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,cAAc,CAAC,CAChD;QACD,aAAa,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CACzC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,eAAe,CAAC,CACjD;QACD,YAAY,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CACxC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,cAAc,CAAC,CAChD;QACD,eAAe,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAC3C,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,iBAAiB,CAAC,CACnD;KACF,CAAC;IAEF,MAAM,MAAM,GAAa,EAAE,CAAC;IAE5B,gCAAgC;IAChC,IAAI,MAAM,CAAC,mBAAmB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1C,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC,CAAC;QAC3C,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,mBAAmB,EAAE,CAAC;YAChD,MAAM,CAAC,IAAI,CAAC,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QAClC,CAAC;QACD,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,MAAM,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACnC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,CAAC;QACpC,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;YACzC,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,cAAc,CAAC,CAAC;YACnE,IAAI,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;gBAC3C,MAAM,CAAC,IAAI,CAAC,KAAK,MAAM,CAAC,IAAI,MAAM,KAAK,CAAC,MAAM,aAAa,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC7F,CAAC;QACH,CAAC;QACD,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,MAAM,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC,CAAC;QAC/C,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;YAC1C,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM;iBAChC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,eAAe,CAAC;iBACzC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAE,CAA8C,CAAC,KAAK,CAAC,CAAC;YACrE,MAAM,CAAC,IAAI,CAAC,KAAK,MAAM,CAAC,IAAI,KAAK,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC/D,CAAC;QACD,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,MAAM,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACnC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC,CAAC;QAChD,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;YACzC,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,cAAc,CAAC,CAAC;YAC5E,MAAM,CAAC,IAAI,CAAC,KAAK,MAAM,CAAC,IAAI,GAAG,CAAC,CAAC;YACjC,KAAK,MAAM,KAAK,IAAI,YAAY,EAAE,CAAC;gBACjC,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;oBAClC,MAAM,CAAC,IAAI,CAAC,SAAS,KAAK,CAAC,KAAK,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;gBACxD,CAAC;YACH,CAAC;QACH,CAAC;QACD,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,MAAM,CAAC,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC,CAAC;QACzC,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,eAAe,EAAE,CAAC;YAC5C,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,iBAAiB,CAAC,CAAC;YACtE,IAAI,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,iBAAiB,EAAE,CAAC;gBAC9C,MAAM,CAAC,IAAI,CACT,KAAK,MAAM,CAAC,IAAI,sBAAsB,KAAK,CAAC,QAAQ,gBAAgB,KAAK,CAAC,MAAM,GAAG,CACpF,CAAC;YACJ,CAAC;QACH,CAAC;QACD,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAClB,CAAC;IAED,yDAAyD;IACzD,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IACnF,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,WAAW,SAAS,WAAW,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,OAAO,OAAO,CAAC,YAAY,QAAQ,OAAO,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IAEvJ,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC3B,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAC9B,OAA2B,EAC3B,OAA0B,EAC1B,SAAiB;IAEjB,MAAM,KAAK,GAA6B,EAAE,CAAC;IAE3C,6BAA6B;IAC7B,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;YAClB,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC;IAED,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IAEnF,MAAM,MAAM,GAAG;QACb,KAAK,EAAE,OAAO,CAAC,YAAY,KAAK,CAAC;QACjC,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,SAAS;QACT,UAAU,EAAE,OAAO,CAAC,UAAU;QAC9B,WAAW;QACX,KAAK;QACL,OAAO,EAAE;YACP,kBAAkB,EAAE,OAAO,CAAC,YAAY,CAAC,mBAAmB,IAAI,CAAC;YACjE,WAAW,EAAE,OAAO,CAAC,YAAY,CAAC,YAAY,IAAI,CAAC;YACnD,YAAY,EAAE,OAAO,CAAC,YAAY,CAAC,aAAa,IAAI,CAAC;YACrD,YAAY,EAAE,OAAO,CAAC,YAAY,CAAC,YAAY,IAAI,CAAC;YACpD,gBAAgB,EAAE,OAAO,CAAC,YAAY,CAAC,eAAe,IAAI,CAAC;SAC5D;KACF,CAAC;IAEF,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;AACzC,CAAC"}
|
|
@@ -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
|