@vibe-agent-toolkit/cli 0.1.2 → 0.1.4

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 (50) hide show
  1. package/dist/bin.js +1 -1
  2. package/dist/bin.js.map +1 -1
  3. package/dist/commands/agent/build.js +1 -1
  4. package/dist/commands/agent/build.js.map +1 -1
  5. package/dist/commands/agent/import.js +1 -1
  6. package/dist/commands/agent/import.js.map +1 -1
  7. package/dist/commands/audit/hierarchical-output.d.ts +1 -1
  8. package/dist/commands/audit/hierarchical-output.d.ts.map +1 -1
  9. package/dist/commands/audit.js +1 -1
  10. package/dist/commands/audit.js.map +1 -1
  11. package/dist/commands/doctor.d.ts.map +1 -1
  12. package/dist/commands/doctor.js +59 -7
  13. package/dist/commands/doctor.js.map +1 -1
  14. package/dist/commands/resources/index.d.ts.map +1 -1
  15. package/dist/commands/resources/index.js +122 -15
  16. package/dist/commands/resources/index.js.map +1 -1
  17. package/dist/commands/resources/scan.d.ts +2 -0
  18. package/dist/commands/resources/scan.d.ts.map +1 -1
  19. package/dist/commands/resources/scan.js +39 -17
  20. package/dist/commands/resources/scan.js.map +1 -1
  21. package/dist/commands/resources/validate.d.ts +49 -0
  22. package/dist/commands/resources/validate.d.ts.map +1 -1
  23. package/dist/commands/resources/validate.js +355 -29
  24. package/dist/commands/resources/validate.js.map +1 -1
  25. package/dist/schemas/config.d.ts +88 -0
  26. package/dist/schemas/config.d.ts.map +1 -1
  27. package/dist/schemas/config.js +6 -0
  28. package/dist/schemas/config.js.map +1 -1
  29. package/dist/utils/agent-runner.js +2 -2
  30. package/dist/utils/agent-runner.js.map +1 -1
  31. package/dist/utils/config-loader.d.ts +18 -0
  32. package/dist/utils/config-loader.d.ts.map +1 -1
  33. package/dist/utils/config-loader.js +21 -2
  34. package/dist/utils/config-loader.js.map +1 -1
  35. package/dist/utils/duration.d.ts +24 -0
  36. package/dist/utils/duration.d.ts.map +1 -0
  37. package/dist/utils/duration.js +32 -0
  38. package/dist/utils/duration.js.map +1 -0
  39. package/dist/utils/project-root.d.ts +19 -0
  40. package/dist/utils/project-root.d.ts.map +1 -1
  41. package/dist/utils/project-root.js +23 -0
  42. package/dist/utils/project-root.js.map +1 -1
  43. package/dist/utils/resource-loader.d.ts +2 -0
  44. package/dist/utils/resource-loader.d.ts.map +1 -1
  45. package/dist/utils/resource-loader.js +33 -2
  46. package/dist/utils/resource-loader.js.map +1 -1
  47. package/dist/utils/validate-help-files.js +1 -1
  48. package/dist/utils/validate-help-files.js.map +1 -1
  49. package/docs/index.md +53 -4
  50. package/package.json +11 -11
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * Resources scan command - discover markdown resources
3
3
  */
4
+ import { formatDurationSecs } from '../../utils/duration.js';
4
5
  import { createLogger } from '../../utils/logger.js';
5
6
  import { writeYamlOutput } from '../../utils/output.js';
6
7
  import { loadResourcesWithConfig } from '../../utils/resource-loader.js';
@@ -11,10 +12,17 @@ export async function scanCommand(pathArg, options) {
11
12
  try {
12
13
  // Load resources with config support
13
14
  const { registry } = await loadResourcesWithConfig(pathArg, logger);
14
- const stats = registry.getStats();
15
+ // Get all resources (filtered by collection if specified)
16
+ let allResources = registry.getAllResources();
17
+ if (options.collection) {
18
+ const { collection } = options;
19
+ allResources = allResources.filter(r => {
20
+ return collection ? r.collections?.includes(collection) ?? false : false;
21
+ });
22
+ }
23
+ // Calculate stats from filtered resources
24
+ const totalLinks = allResources.reduce((sum, r) => sum + r.links.length, 0);
15
25
  const duration = Date.now() - startTime;
16
- // Get all resources
17
- const allResources = registry.getAllResources();
18
26
  const countHeadings = (headings) => {
19
27
  let count = headings.length;
20
28
  for (const heading of headings) {
@@ -25,27 +33,41 @@ export async function scanCommand(pathArg, options) {
25
33
  return count;
26
34
  };
27
35
  const totalHeadings = allResources.reduce((sum, resource) => sum + countHeadings(resource.headings), 0);
28
- // Get duplicate statistics
29
- const duplicates = registry.getDuplicates();
30
- const duplicateFileCount = duplicates.reduce((sum, group) => sum + group.length, 0);
31
- const uniqueResources = registry.getUniqueByChecksum();
36
+ // Build collection stats (filtered or all)
37
+ let collectionsOutput;
38
+ if (options.collection) {
39
+ // When filtering by collection, only show that collection
40
+ collectionsOutput = { [options.collection]: { resourceCount: allResources.length } };
41
+ }
42
+ else {
43
+ // Show all collections
44
+ const collectionStats = registry.getCollectionStats();
45
+ collectionsOutput = collectionStats
46
+ ? Object.fromEntries(Object.entries(collectionStats.collections).map(([id, stat]) => [
47
+ id,
48
+ { resourceCount: stat.resourceCount },
49
+ ]))
50
+ : undefined;
51
+ }
32
52
  // Output results as YAML
33
- writeYamlOutput({
53
+ const outputData = {
34
54
  status: 'success',
35
- filesScanned: stats.totalResources,
36
- uniqueFiles: uniqueResources.length,
37
- duplicateGroups: duplicates.length,
38
- duplicateFiles: duplicateFileCount,
39
- linksFound: stats.totalLinks,
55
+ filesScanned: allResources.length,
56
+ linksFound: totalLinks,
40
57
  anchorsFound: totalHeadings,
41
- files: allResources.map(resource => ({
58
+ durationSecs: formatDurationSecs(duration),
59
+ ...(collectionsOutput ? { collections: collectionsOutput } : {}),
60
+ };
61
+ // Add verbose file details if requested
62
+ if (options.verbose) {
63
+ outputData['files'] = allResources.map(resource => ({
42
64
  path: resource.filePath,
43
65
  links: resource.links.length,
44
66
  anchors: countHeadings(resource.headings),
45
67
  checksum: resource.checksum,
46
- })),
47
- duration: `${duration}ms`,
48
- });
68
+ }));
69
+ }
70
+ writeYamlOutput(outputData);
49
71
  process.exit(0);
50
72
  }
51
73
  catch (error) {
@@ -1 +1 @@
1
- {"version":3,"file":"scan.js","sourceRoot":"","sources":["../../../src/commands/resources/scan.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AAEzE,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAM1D,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,OAA2B,EAC3B,OAAoB;IAEpB,MAAM,MAAM,GAAG,YAAY,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,KAAK,EAAE,CAAC,CAAC;IAC/D,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAE7B,IAAI,CAAC;QACH,qCAAqC;QACrC,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,uBAAuB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAEpE,MAAM,KAAK,GAAG,QAAQ,CAAC,QAAQ,EAAE,CAAC;QAClC,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;QAExC,oBAAoB;QACpB,MAAM,YAAY,GAAG,QAAQ,CAAC,eAAe,EAAE,CAAC;QAIhD,MAAM,aAAa,GAAG,CAAC,QAA+B,EAAU,EAAE;YAChE,IAAI,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC;YAC5B,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;gBAC/B,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;oBACrB,KAAK,IAAI,aAAa,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;gBAC3C,CAAC;YACH,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC,CAAC;QAEF,MAAM,aAAa,GAAG,YAAY,CAAC,MAAM,CACvC,CAAC,GAAG,EAAE,QAAQ,EAAE,EAAE,CAAC,GAAG,GAAG,aAAa,CAAC,QAAQ,CAAC,QAAQ,CAAC,EACzD,CAAC,CACF,CAAC;QAEF,2BAA2B;QAC3B,MAAM,UAAU,GAAG,QAAQ,CAAC,aAAa,EAAE,CAAC;QAC5C,MAAM,kBAAkB,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,GAAG,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QACpF,MAAM,eAAe,GAAG,QAAQ,CAAC,mBAAmB,EAAE,CAAC;QAEvD,yBAAyB;QACzB,eAAe,CAAC;YACd,MAAM,EAAE,SAAS;YACjB,YAAY,EAAE,KAAK,CAAC,cAAc;YAClC,WAAW,EAAE,eAAe,CAAC,MAAM;YACnC,eAAe,EAAE,UAAU,CAAC,MAAM;YAClC,cAAc,EAAE,kBAAkB;YAClC,UAAU,EAAE,KAAK,CAAC,UAAU;YAC5B,YAAY,EAAE,aAAa;YAC3B,KAAK,EAAE,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;gBACnC,IAAI,EAAE,QAAQ,CAAC,QAAQ;gBACvB,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,MAAM;gBAC5B,OAAO,EAAE,aAAa,CAAC,QAAQ,CAAC,QAAQ,CAAC;gBACzC,QAAQ,EAAE,QAAQ,CAAC,QAAQ;aAC5B,CAAC,CAAC;YACH,QAAQ,EAAE,GAAG,QAAQ,IAAI;SAC1B,CAAC,CAAC;QAEH,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;IACvD,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"scan.js","sourceRoot":"","sources":["../../../src/commands/resources/scan.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,57 @@
1
1
  /**
2
2
  * Resources validate command - strict validation with error reporting
3
3
  */
4
+ /**
5
+ * Resolve schema path (supports both package paths and file paths).
6
+ *
7
+ * This function implements Node.js-style module resolution for schema paths,
8
+ * allowing users to reference schemas from installed packages OR local files.
9
+ *
10
+ * **Path Resolution Rules:**
11
+ *
12
+ * 1. **Absolute paths** (start with `/`) → Used as-is
13
+ * - Example: `/Users/jeff/project/schema.json`
14
+ *
15
+ * 2. **Explicit relative paths** (start with `./` or `../`) → Used as-is
16
+ * - Example: `./schemas/skill-schema.json`
17
+ * - Example: `../shared/schema.json`
18
+ *
19
+ * 3. **Scoped package paths** (start with `@`) → Resolved via Node.js module system
20
+ * - Example: `@vibe-agent-toolkit/agent-skills/schemas/skill-frontmatter.json`
21
+ * - Requires package to be installed and subpath to be exported
22
+ * - Throws error if package not found or subpath not exported
23
+ *
24
+ * 4. **Bare specifiers** (everything else) → Try package first, fallback to file
25
+ * - Example: `lodash/fp/array.json` → Tries package "lodash", falls back to file
26
+ * - Example: `schemas/file.json` → Tries package "schemas" (unlikely), falls back to file
27
+ * - Only collides if a package with matching name is installed
28
+ *
29
+ * **Why This Works Everywhere:**
30
+ * - Uses Node.js's `import.meta.resolve()` which works in any environment
31
+ * - Respects package.json "exports" field
32
+ * - Works in development (monorepo) and production (npm install)
33
+ *
34
+ * **Best Practices for Users:**
35
+ * - Package references: Use full package path with `@scope` prefix when possible
36
+ * - File references: Use explicit `./` prefix to avoid ambiguity
37
+ * - Avoid bare specifiers unless you know they won't collide
38
+ *
39
+ * @param schemaPath - Path to schema (package path or file path)
40
+ * @returns Resolved absolute file path
41
+ * @throws Error if scoped package path cannot be resolved
42
+ * @internal Exported for testing
43
+ */
44
+ export declare function resolveSchemaPath(schemaPath: string): Promise<string>;
45
+ /**
46
+ * Output format options.
47
+ */
48
+ type OutputFormat = 'yaml' | 'json' | 'text';
4
49
  interface ValidateOptions {
5
50
  debug?: boolean;
51
+ frontmatterSchema?: string;
52
+ validationMode?: 'strict' | 'permissive';
53
+ format?: OutputFormat;
54
+ collection?: string;
6
55
  }
7
56
  export declare function validateCommand(pathArg: string | undefined, options: ValidateOptions): Promise<void>;
8
57
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../../src/commands/resources/validate.ts"],"names":[],"mappings":"AAAA;;GAEG;AAQH,UAAU,eAAe;IACvB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,wBAAsB,eAAe,CACnC,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,IAAI,CAAC,CA6Df"}
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../../src/commands/resources/validate.ts"],"names":[],"mappings":"AAAA;;GAEG;AA4BH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,wBAAsB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA2C3E;AA6ED;;GAEG;AACH,KAAK,YAAY,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AA6M7C,UAAU,eAAe;IACvB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,cAAc,CAAC,EAAE,QAAQ,GAAG,YAAY,CAAC;IACzC,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAsB,eAAe,CACnC,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,IAAI,CAAC,CAkHf"}
@@ -1,56 +1,382 @@
1
1
  /**
2
2
  * Resources validate command - strict validation with error reporting
3
3
  */
4
+ import { readFile } from 'node:fs/promises';
5
+ import * as path from 'node:path';
6
+ import { toForwardSlash } from '@vibe-agent-toolkit/utils';
7
+ import * as yaml from 'js-yaml';
8
+ import { formatDurationSecs } from '../../utils/duration.js';
4
9
  import { createLogger } from '../../utils/logger.js';
5
- import { flushStdout, writeTestFormatError, writeYamlOutput } from '../../utils/output.js';
10
+ import { writeTestFormatError } from '../../utils/output.js';
6
11
  import { loadResourcesWithConfig } from '../../utils/resource-loader.js';
7
12
  import { handleCommandError } from './command-helpers.js';
13
+ /**
14
+ * Resolve schema path (supports both package paths and file paths).
15
+ *
16
+ * This function implements Node.js-style module resolution for schema paths,
17
+ * allowing users to reference schemas from installed packages OR local files.
18
+ *
19
+ * **Path Resolution Rules:**
20
+ *
21
+ * 1. **Absolute paths** (start with `/`) → Used as-is
22
+ * - Example: `/Users/jeff/project/schema.json`
23
+ *
24
+ * 2. **Explicit relative paths** (start with `./` or `../`) → Used as-is
25
+ * - Example: `./schemas/skill-schema.json`
26
+ * - Example: `../shared/schema.json`
27
+ *
28
+ * 3. **Scoped package paths** (start with `@`) → Resolved via Node.js module system
29
+ * - Example: `@vibe-agent-toolkit/agent-skills/schemas/skill-frontmatter.json`
30
+ * - Requires package to be installed and subpath to be exported
31
+ * - Throws error if package not found or subpath not exported
32
+ *
33
+ * 4. **Bare specifiers** (everything else) → Try package first, fallback to file
34
+ * - Example: `lodash/fp/array.json` → Tries package "lodash", falls back to file
35
+ * - Example: `schemas/file.json` → Tries package "schemas" (unlikely), falls back to file
36
+ * - Only collides if a package with matching name is installed
37
+ *
38
+ * **Why This Works Everywhere:**
39
+ * - Uses Node.js's `import.meta.resolve()` which works in any environment
40
+ * - Respects package.json "exports" field
41
+ * - Works in development (monorepo) and production (npm install)
42
+ *
43
+ * **Best Practices for Users:**
44
+ * - Package references: Use full package path with `@scope` prefix when possible
45
+ * - File references: Use explicit `./` prefix to avoid ambiguity
46
+ * - Avoid bare specifiers unless you know they won't collide
47
+ *
48
+ * @param schemaPath - Path to schema (package path or file path)
49
+ * @returns Resolved absolute file path
50
+ * @throws Error if scoped package path cannot be resolved
51
+ * @internal Exported for testing
52
+ */
53
+ export async function resolveSchemaPath(schemaPath) {
54
+ // Rule 1 & 2: Absolute or explicit relative paths → File
55
+ const normalizedPath = toForwardSlash(schemaPath);
56
+ if (path.isAbsolute(schemaPath) ||
57
+ normalizedPath.startsWith('./') ||
58
+ normalizedPath.startsWith('../')) {
59
+ return schemaPath;
60
+ }
61
+ // Rule 3 & 4: Package paths or bare specifiers → Try module resolution
62
+ try {
63
+ // Use Node.js native module resolution
64
+ // This respects package.json "exports" and works everywhere
65
+ const resolved = import.meta.resolve(schemaPath, import.meta.url);
66
+ // Convert file:// URL to filesystem path
67
+ return new URL(resolved).pathname;
68
+ }
69
+ catch (error) {
70
+ // Package resolution failed - could be:
71
+ // 1. Package not installed
72
+ // 2. Subpath not exported in package.json
73
+ // 3. Not actually a package reference (just a file path)
74
+ // For scoped packages, this is definitely an error
75
+ if (normalizedPath.startsWith('@')) {
76
+ const message = error instanceof Error ? error.message : 'Unknown error';
77
+ // Extract package name from scoped package path like "@scope/package/sub/path.json"
78
+ const pathParts = normalizedPath.split('/');
79
+ const packageName = pathParts.length >= 2 ? `${pathParts[0] ?? ''}/${pathParts[1] ?? ''}` : schemaPath;
80
+ throw new Error(`Cannot resolve package path: ${schemaPath}\n` +
81
+ `Possible causes:\n` +
82
+ ` - Package not installed (run: npm install ${String(packageName)})\n` +
83
+ ` - Subpath not exported in package.json "exports" field\n` +
84
+ ` - Typo in package name or path\n` +
85
+ `Original error: ${message}`);
86
+ }
87
+ // For bare specifiers, assume it's a file path
88
+ // This allows "schemas/file.json" to work when no package "schemas" exists
89
+ return schemaPath;
90
+ }
91
+ }
92
+ /**
93
+ * Load JSON Schema from file (supports .json and .yaml).
94
+ *
95
+ * Supports both package-based paths (via import.meta.resolve) and file paths.
96
+ * See `resolveSchemaPath()` for path resolution rules.
97
+ *
98
+ * @param schemaPath - Path to schema file (package path or file path)
99
+ * @returns Parsed schema object
100
+ */
101
+ async function loadSchema(schemaPath) {
102
+ const resolvedPath = await resolveSchemaPath(schemaPath);
103
+ // eslint-disable-next-line security/detect-non-literal-fs-filename -- schemaPath is user-provided CLI argument, validated by resolveSchemaPath
104
+ const content = await readFile(resolvedPath, 'utf-8');
105
+ const ext = path.extname(resolvedPath).toLowerCase();
106
+ if (ext === '.json') {
107
+ return JSON.parse(content);
108
+ }
109
+ else if (ext === '.yaml' || ext === '.yml') {
110
+ const parsed = yaml.load(content);
111
+ if (typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed)) {
112
+ return parsed;
113
+ }
114
+ throw new Error('YAML schema must be an object');
115
+ }
116
+ else {
117
+ throw new Error(`Unsupported schema format: ${ext} (use .json or .yaml)`);
118
+ }
119
+ }
120
+ /**
121
+ * Write structured output in specified format.
122
+ */
123
+ function writeStructuredOutput(data, format) {
124
+ if (format === 'json') {
125
+ console.log(JSON.stringify(data, null, 2));
126
+ }
127
+ else {
128
+ console.log(yaml.dump(data, { indent: 2, lineWidth: -1 }));
129
+ }
130
+ }
131
+ /**
132
+ * Group errors by file path.
133
+ */
134
+ function groupErrorsByFile(errors) {
135
+ const fileMap = new Map();
136
+ for (const error of errors) {
137
+ const existing = fileMap.get(error.file);
138
+ if (existing) {
139
+ existing.errors.push({
140
+ line: error.line,
141
+ column: error.column,
142
+ type: error.type,
143
+ message: error.message,
144
+ });
145
+ }
146
+ else {
147
+ fileMap.set(error.file, {
148
+ file: error.file,
149
+ errors: [{
150
+ line: error.line,
151
+ column: error.column,
152
+ type: error.type,
153
+ message: error.message,
154
+ }],
155
+ });
156
+ }
157
+ }
158
+ return [...fileMap.values()];
159
+ }
160
+ /**
161
+ * Log git tracker stats if available.
162
+ */
163
+ function logGitTrackerStats(gitTracker, logger) {
164
+ if (gitTracker) {
165
+ const gitStats = gitTracker.getStats();
166
+ logger.debug(`Git tracker cache size: ${gitStats.cacheSize} files`);
167
+ }
168
+ }
169
+ /**
170
+ * Output validation failure results.
171
+ */
172
+ function outputFailure(errorData, outputFormat, context, registry) {
173
+ if (outputFormat === 'text') {
174
+ // Text format: test-format errors to stderr
175
+ for (const error of errorData) {
176
+ writeTestFormatError(error.file, error.line, error.column, error.message);
177
+ }
178
+ }
179
+ else {
180
+ // Calculate error summary
181
+ const summary = buildErrorSummary(errorData, registry);
182
+ // Build collection stats with error info
183
+ const collectionsWithErrors = {};
184
+ if (context.collectionStats) {
185
+ for (const [id, baseStat] of Object.entries(context.collectionStats.collections)) {
186
+ const errorStat = summary.collectionErrorStats.get(id);
187
+ collectionsWithErrors[id] = {
188
+ ...baseStat,
189
+ ...(errorStat ? {
190
+ filesWithErrors: errorStat.filesWithErrors,
191
+ errorCount: errorStat.errorCount,
192
+ } : {}),
193
+ };
194
+ }
195
+ }
196
+ // Group errors by file
197
+ const groupedErrors = groupErrorsByFile(errorData);
198
+ const outputData = {
199
+ status: 'failed',
200
+ filesScanned: context.stats.totalResources,
201
+ filesWithErrors: summary.filesWithErrors,
202
+ errorsFound: context.errorCount,
203
+ errorSummary: summary.errorSummary,
204
+ durationSecs: formatDurationSecs(context.duration),
205
+ ...context.validationMetadata,
206
+ ...(Object.keys(collectionsWithErrors).length > 0 ? { collections: collectionsWithErrors } : {}),
207
+ errors: groupedErrors,
208
+ };
209
+ writeStructuredOutput(outputData, outputFormat);
210
+ }
211
+ }
212
+ /**
213
+ * Output validation success results.
214
+ */
215
+ function outputSuccess(outputFormat, context) {
216
+ if (outputFormat === 'text') {
217
+ // Text format: simple success message
218
+ console.log('✓ All validations passed');
219
+ console.log(`Files scanned: ${context.stats.totalResources}`);
220
+ console.log(`Links checked: ${context.stats.totalLinks}`);
221
+ if (context.collectionStats) {
222
+ console.log(`Collections: ${context.collectionStats.totalCollections}`);
223
+ console.log(`Resources in collections: ${context.collectionStats.resourcesInCollections}`);
224
+ }
225
+ console.log(`Duration: ${context.duration}ms`);
226
+ }
227
+ else {
228
+ // Structured format (yaml/json)
229
+ const outputData = {
230
+ status: 'success',
231
+ filesScanned: context.stats.totalResources,
232
+ linksChecked: context.stats.totalLinks,
233
+ durationSecs: formatDurationSecs(context.duration),
234
+ ...context.validationMetadata,
235
+ ...(context.collectionStats ? { collections: context.collectionStats.collections } : {}),
236
+ };
237
+ writeStructuredOutput(outputData, outputFormat);
238
+ }
239
+ }
240
+ /**
241
+ * Build error summary from validation issues.
242
+ *
243
+ * Calculates:
244
+ * - Error counts by type
245
+ * - Unique files with errors
246
+ * - Per-collection error statistics
247
+ *
248
+ * @param issues - Validation issues from registry (using ErrorData format with file instead of resourcePath)
249
+ * @param registry - Resource registry for collection lookups
250
+ * @returns Error summary statistics
251
+ */
252
+ function buildErrorSummary(issues, registry) {
253
+ // 1. Count by error type
254
+ const errorSummary = {};
255
+ for (const issue of issues) {
256
+ errorSummary[issue.type] = (errorSummary[issue.type] ?? 0) + 1;
257
+ }
258
+ // 2. Count unique files with errors
259
+ const filesWithErrorsSet = new Set(issues.map(i => i.file));
260
+ // 3. Map files to collections and count errors per collection
261
+ const collectionErrors = new Map();
262
+ for (const issue of issues) {
263
+ const resource = registry.getResource(issue.file);
264
+ const collections = resource?.collections;
265
+ if (collections) {
266
+ for (const collectionId of collections) {
267
+ const stat = collectionErrors.get(collectionId) ?? {
268
+ filesWithErrors: new Set(),
269
+ errorCount: 0,
270
+ };
271
+ stat.filesWithErrors.add(issue.file);
272
+ stat.errorCount++;
273
+ collectionErrors.set(collectionId, stat);
274
+ }
275
+ }
276
+ }
277
+ // Convert Sets to counts
278
+ const collectionStats = new Map();
279
+ for (const [id, stat] of collectionErrors.entries()) {
280
+ collectionStats.set(id, {
281
+ filesWithErrors: stat.filesWithErrors.size,
282
+ errorCount: stat.errorCount,
283
+ });
284
+ }
285
+ return {
286
+ errorSummary,
287
+ filesWithErrors: filesWithErrorsSet.size,
288
+ collectionErrorStats: collectionStats,
289
+ };
290
+ }
8
291
  export async function validateCommand(pathArg, options) {
9
292
  const logger = createLogger(options.debug ? { debug: true } : {});
10
293
  const startTime = Date.now();
11
294
  try {
12
- // Load resources with config support
13
- const { registry } = await loadResourcesWithConfig(pathArg, logger);
295
+ // Load resources with config support (includes GitTracker initialization)
296
+ const { registry, gitTracker } = await loadResourcesWithConfig(pathArg, logger);
297
+ // Load frontmatter schema if provided
298
+ let frontmatterSchemaObj;
299
+ if (options.frontmatterSchema) {
300
+ logger.debug(`Loading frontmatter schema from: ${options.frontmatterSchema}`);
301
+ frontmatterSchemaObj = await loadSchema(options.frontmatterSchema);
302
+ }
14
303
  // Validate all resources
15
- const validationResult = await registry.validate();
16
- const stats = registry.getStats();
304
+ const validationMode = options.validationMode ?? 'strict';
305
+ const validationResult = await registry.validate(...(frontmatterSchemaObj
306
+ ? [{ frontmatterSchema: frontmatterSchemaObj, validationMode }]
307
+ : [{ validationMode }]));
308
+ // Filter by collection if specified
309
+ let filteredIssues = validationResult.issues;
310
+ let filteredStats;
311
+ if (options.collection) {
312
+ // Get resources in the specified collection
313
+ const { collection } = options;
314
+ const collectionResources = registry
315
+ .getAllResources()
316
+ .filter(r => (collection ? r.collections?.includes(collection) ?? false : false));
317
+ const collectionPaths = new Set(collectionResources.map(r => r.filePath));
318
+ // Only show issues from files in this collection
319
+ filteredIssues = validationResult.issues.filter(issue => collectionPaths.has(issue.resourcePath));
320
+ // Calculate filtered stats
321
+ const totalLinks = collectionResources.reduce((sum, r) => sum + r.links.length, 0);
322
+ filteredStats = {
323
+ totalResources: collectionResources.length,
324
+ totalLinks,
325
+ linksByType: validationResult.linksByType, // Keep all link types
326
+ };
327
+ }
328
+ else {
329
+ filteredStats = registry.getStats();
330
+ }
17
331
  const duration = Date.now() - startTime;
332
+ // Build validation metadata
333
+ const validationMetadata = {
334
+ validationMode,
335
+ ...(options.frontmatterSchema ? { frontmatterSchema: options.frontmatterSchema } : {}),
336
+ };
337
+ // Get collection stats (filtered if collection specified)
338
+ let collectionStats = registry.getCollectionStats();
339
+ if (options.collection && collectionStats) {
340
+ // Only show the specified collection
341
+ const collectionStat = collectionStats.collections[options.collection];
342
+ if (collectionStat) {
343
+ collectionStats = {
344
+ totalCollections: 1,
345
+ resourcesInCollections: collectionStat.resourceCount,
346
+ collections: { [options.collection]: collectionStat },
347
+ };
348
+ }
349
+ }
18
350
  // Filter out external_url issues (informational only, not actual errors)
19
- const actualErrors = validationResult.issues.filter(issue => issue.type !== 'external_url');
351
+ const actualErrors = filteredIssues.filter(issue => issue.type !== 'external_url');
20
352
  const hasErrors = actualErrors.length > 0;
353
+ // Determine output format (default: yaml)
354
+ const outputFormat = options.format ?? 'yaml';
21
355
  if (hasErrors) {
22
- // Failure - write YAML first, then test-format errors
23
- const errors = actualErrors.map(issue => ({
356
+ // Failure path
357
+ const errorData = actualErrors.map(issue => ({
24
358
  file: issue.resourcePath,
25
359
  line: issue.line ?? 1,
26
360
  column: 1,
27
361
  type: issue.type,
28
362
  message: issue.message,
29
363
  }));
30
- writeYamlOutput({
31
- status: 'failed',
32
- filesScanned: stats.totalResources,
33
- errorsFound: validationResult.errorCount,
34
- warningsFound: validationResult.warningCount,
35
- errors,
36
- duration: `${duration}ms`,
37
- });
38
- // Flush stdout before writing to stderr
39
- await flushStdout();
40
- // Write test-format errors to stderr
41
- for (const error of errors) {
42
- writeTestFormatError(error.file, error.line, error.column, error.message);
43
- }
364
+ const context = {
365
+ stats: filteredStats,
366
+ errorCount: validationResult.errorCount,
367
+ validationMetadata,
368
+ collectionStats,
369
+ duration,
370
+ };
371
+ outputFailure(errorData, outputFormat, context, registry);
372
+ logGitTrackerStats(gitTracker, logger);
44
373
  process.exit(1);
45
374
  }
46
375
  else {
47
- // Success output
48
- writeYamlOutput({
49
- status: 'success',
50
- filesScanned: stats.totalResources,
51
- linksChecked: stats.totalLinks,
52
- duration: `${duration}ms`,
53
- });
376
+ // Success path
377
+ const context = { stats: filteredStats, validationMetadata, collectionStats, duration };
378
+ outputSuccess(outputFormat, context);
379
+ logGitTrackerStats(gitTracker, logger);
54
380
  process.exit(0);
55
381
  }
56
382
  }
@@ -1 +1 @@
1
- {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../../src/commands/resources/validate.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC3F,OAAO,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AAEzE,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAM1D,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,OAA2B,EAC3B,OAAwB;IAExB,MAAM,MAAM,GAAG,YAAY,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAClE,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAE7B,IAAI,CAAC;QACH,qCAAqC;QACrC,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,uBAAuB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAEpE,yBAAyB;QACzB,MAAM,gBAAgB,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,CAAC;QACnD,MAAM,KAAK,GAAG,QAAQ,CAAC,QAAQ,EAAE,CAAC;QAClC,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;QAExC,yEAAyE;QACzE,MAAM,YAAY,GAAG,gBAAgB,CAAC,MAAM,CAAC,MAAM,CACjD,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,cAAc,CACvC,CAAC;QACF,MAAM,SAAS,GAAG,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC;QAE1C,IAAI,SAAS,EAAE,CAAC;YACd,sDAAsD;YACtD,MAAM,MAAM,GAAG,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;gBACxC,IAAI,EAAE,KAAK,CAAC,YAAY;gBACxB,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC;gBACrB,MAAM,EAAE,CAAC;gBACT,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,OAAO,EAAE,KAAK,CAAC,OAAO;aACvB,CAAC,CAAC,CAAC;YAEJ,eAAe,CAAC;gBACd,MAAM,EAAE,QAAQ;gBAChB,YAAY,EAAE,KAAK,CAAC,cAAc;gBAClC,WAAW,EAAE,gBAAgB,CAAC,UAAU;gBACxC,aAAa,EAAE,gBAAgB,CAAC,YAAY;gBAC5C,MAAM;gBACN,QAAQ,EAAE,GAAG,QAAQ,IAAI;aAC1B,CAAC,CAAC;YAEH,wCAAwC;YACxC,MAAM,WAAW,EAAE,CAAC;YAEpB,qCAAqC;YACrC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;gBAC3B,oBAAoB,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;YAC5E,CAAC;YAED,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;aAAM,CAAC;YACN,iBAAiB;YACjB,eAAe,CAAC;gBACd,MAAM,EAAE,SAAS;gBACjB,YAAY,EAAE,KAAK,CAAC,cAAc;gBAClC,YAAY,EAAE,KAAK,CAAC,UAAU;gBAC9B,QAAQ,EAAE,GAAG,QAAQ,IAAI;aAC1B,CAAC,CAAC;YAEH,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,YAAY,CAAC,CAAC;IAC7D,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../../src/commands/resources/validate.ts"],"names":[],"mappings":"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"}