@vibe-agent-toolkit/cli 0.1.0 → 0.1.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 (37) hide show
  1. package/README.md +67 -4
  2. package/dist/bin.js +15 -12
  3. package/dist/bin.js.map +1 -1
  4. package/dist/commands/agent/index.d.ts.map +1 -1
  5. package/dist/commands/agent/index.js +0 -37
  6. package/dist/commands/agent/index.js.map +1 -1
  7. package/dist/commands/audit/cache-detector.d.ts +32 -0
  8. package/dist/commands/audit/cache-detector.d.ts.map +1 -0
  9. package/dist/commands/audit/cache-detector.js +68 -0
  10. package/dist/commands/audit/cache-detector.js.map +1 -0
  11. package/dist/commands/audit/hierarchical-output.d.ts +41 -0
  12. package/dist/commands/audit/hierarchical-output.d.ts.map +1 -0
  13. package/dist/commands/audit/hierarchical-output.js +267 -0
  14. package/dist/commands/audit/hierarchical-output.js.map +1 -0
  15. package/dist/commands/audit.d.ts +18 -0
  16. package/dist/commands/audit.d.ts.map +1 -0
  17. package/dist/commands/audit.js +386 -0
  18. package/dist/commands/audit.js.map +1 -0
  19. package/dist/commands/doctor.d.ts +106 -0
  20. package/dist/commands/doctor.d.ts.map +1 -0
  21. package/dist/commands/doctor.js +499 -0
  22. package/dist/commands/doctor.js.map +1 -0
  23. package/dist/commands/resources/scan.d.ts.map +1 -1
  24. package/dist/commands/resources/scan.js +8 -0
  25. package/dist/commands/resources/scan.js.map +1 -1
  26. package/dist/utils/config-loader.d.ts +6 -0
  27. package/dist/utils/config-loader.d.ts.map +1 -1
  28. package/dist/utils/config-loader.js +18 -0
  29. package/dist/utils/config-loader.js.map +1 -1
  30. package/docs/audit.md +446 -0
  31. package/docs/doctor.md +268 -0
  32. package/docs/index.md +32 -0
  33. package/package.json +11 -8
  34. package/dist/commands/agent/audit.d.ts +0 -9
  35. package/dist/commands/agent/audit.d.ts.map +0 -1
  36. package/dist/commands/agent/audit.js +0 -139
  37. package/dist/commands/agent/audit.js.map +0 -1
package/README.md CHANGED
@@ -71,6 +71,69 @@ vat rag clear
71
71
  - 384-dimensional embeddings
72
72
  - No API key required
73
73
 
74
+ ### Doctor Command
75
+
76
+ Diagnose vat setup and environment health.
77
+
78
+ **Usage:**
79
+ ```bash
80
+ # Check environment and configuration
81
+ vat doctor
82
+
83
+ # Show all checks (including passing ones)
84
+ vat doctor --verbose
85
+ ```
86
+
87
+ **What it checks:**
88
+ - Node.js version (>=20 required)
89
+ - Git installation and repository
90
+ - Configuration file exists and is valid
91
+ - VAT version (checks for updates)
92
+ - CLI build status (in VAT source tree only)
93
+
94
+ **Exit codes:**
95
+ - `0` - All checks passed
96
+ - `1` - One or more checks failed
97
+
98
+ **Example output:**
99
+ ```
100
+ 🩺 vat doctor
101
+
102
+ Running diagnostic checks...
103
+
104
+ ✅ Node.js version
105
+ v22.0.0 (meets requirement: >=20.0.0)
106
+
107
+ ✅ Git installed
108
+ git version 2.43.0
109
+
110
+ ✅ Git repository
111
+ Current directory is a git repository
112
+
113
+ ✅ Configuration file
114
+ Found: vibe-agent-toolkit.config.yaml
115
+
116
+ ✅ Configuration valid
117
+ Configuration is valid
118
+
119
+ ✅ vat version
120
+ Current: 0.1.0 — up to date
121
+
122
+ 📊 Results: 6/6 checks passed
123
+
124
+ ✨ All checks passed! Your vat setup looks healthy.
125
+ ```
126
+
127
+ **Troubleshooting:**
128
+
129
+ If checks fail, doctor provides specific suggestions:
130
+
131
+ ```
132
+ ❌ Node.js version
133
+ v18.0.0 is too old. Node.js 20+ required.
134
+ 💡 Upgrade Node.js: https://nodejs.org/ or use nvm
135
+ ```
136
+
74
137
  ### Configuration
75
138
 
76
139
  Create `vibe-agent-toolkit.config.yaml` at project root:
@@ -111,10 +174,10 @@ vat --version # Shows: 0.1.0-dev (/path/to/vibe-agent-toolkit)
111
174
  # Build
112
175
  bun run build
113
176
 
114
- # Test
115
- bun test
116
- bun test:integration
117
- bun test:system
177
+ # Test (do NOT use 'bun test' directly)
178
+ bun run test:unit
179
+ bun run test:integration
180
+ bun run test:system
118
181
 
119
182
  # Prepare binaries after build
120
183
  bun run prepare-cli-bin
package/dist/bin.js CHANGED
@@ -5,6 +5,8 @@
5
5
  */
6
6
  import { Command } from 'commander';
7
7
  import { createAgentCommand, showAgentVerboseHelp } from './commands/agent/index.js';
8
+ import { createAuditCommand } from './commands/audit.js';
9
+ import { doctorCommand } from './commands/doctor.js';
8
10
  import { createRagCommand, showRagVerboseHelp } from './commands/rag/index.js';
9
11
  import { createResourcesCommand, showResourcesVerboseHelp } from './commands/resources/index.js';
10
12
  import { loadVerboseHelp } from './utils/help-loader.js';
@@ -23,7 +25,6 @@ program
23
25
  .description('Agent-friendly toolkit for building, testing, and deploying portable AI agents')
24
26
  .version(getVersionString(version, context), '-v, --version', 'Output version number')
25
27
  .option('--debug', 'Enable debug logging')
26
- .option('--verbose', 'Show verbose help (markdown format)')
27
28
  .helpCommand(false) // Disable redundant 'help' command, use --help instead
28
29
  .showHelpAfterError()
29
30
  .configureOutput({
@@ -41,17 +42,16 @@ For command details: vat resources --help
41
42
  For comprehensive help: vat --help --verbose
42
43
  For agent guidance: docs/cli/CLAUDE.md
43
44
  `);
44
- // Handle --help --verbose at root level only
45
- // Don't handle --verbose if a subcommand was specified
45
+ // Handle --help --verbose at root level before parsing
46
+ // Manually check process.argv since --verbose is not a root-level option
47
+ const hasHelp = process.argv.includes('--help') || process.argv.includes('-h');
48
+ const hasVerbose = process.argv.includes('--verbose');
46
49
  const hasSubcommand = process.argv.slice(2).some(arg => !arg.startsWith('-'));
47
- program.on('option:verbose', () => {
48
- const opts = program.opts();
49
- // Only show root verbose help if no subcommand is present
50
- if (opts['verbose'] && !hasSubcommand && program.args.length === 0) {
51
- showVerboseHelp();
52
- process.exit(0);
53
- }
54
- });
50
+ if (hasHelp && hasVerbose && !hasSubcommand) {
51
+ // Root level: vat --help --verbose
52
+ showVerboseHelp();
53
+ process.exit(0);
54
+ }
55
55
  // Special handling for "resources --verbose" before parsing
56
56
  if (process.argv.includes('resources') && process.argv.includes('--verbose')) {
57
57
  const argv = process.argv.slice(2);
@@ -88,10 +88,13 @@ if (process.argv.includes('agent') && process.argv.includes('--verbose')) {
88
88
  process.exit(0);
89
89
  }
90
90
  }
91
- // Add command groups
91
+ // Add command groups (audit is common, should be first)
92
+ program.addCommand(createAuditCommand());
92
93
  program.addCommand(createResourcesCommand());
93
94
  program.addCommand(createRagCommand());
94
95
  program.addCommand(createAgentCommand());
96
+ // Add standalone commands
97
+ doctorCommand(program);
95
98
  // Handle unknown commands
96
99
  program.on('command:*', (operands) => {
97
100
  const logger = createLogger();
package/dist/bin.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/agent/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAqBpC,wBAAgB,kBAAkB,IAAI,OAAO,CAsT5C;AAED,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/agent/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAoBpC,wBAAgB,kBAAkB,IAAI,OAAO,CA8Q5C;AAED,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC"}
@@ -2,7 +2,6 @@
2
2
  * Agent command group
3
3
  */
4
4
  import { Command } from 'commander';
5
- import { auditCommand } from './audit.js';
6
5
  import { buildCommand } from './build.js';
7
6
  import { importCommand } from './import.js';
8
7
  import { installAgent } from './install.js';
@@ -138,42 +137,6 @@ Examples:
138
137
  $ vat agent validate agent-generator # Validate by name
139
138
  $ vat agent validate ./my-agent # Validate by path
140
139
  $ vat agent validate ./agent.yaml # Validate specific file
141
- `);
142
- agent
143
- .command('audit [path]')
144
- .description('Audit Claude Skills for quality and compatibility')
145
- .option('-r, --recursive', 'Scan directories recursively for SKILL.md files')
146
- .option('--debug', DEBUG_OPTION_DESC)
147
- .action(auditCommand)
148
- .addHelpText('after', `
149
- Description:
150
- Audits Claude Skills (SKILL.md files) for quality, correctness, and
151
- console compatibility. Validates frontmatter, links, naming conventions,
152
- and warns about console-incompatible features. Outputs YAML report to
153
- stdout, errors/warnings to stderr.
154
-
155
- Path can be: directory, single SKILL.md file, or VAT agent directory
156
- Default: current directory
157
-
158
- Validation Checks:
159
- Errors (must fix):
160
- - Missing or invalid frontmatter (name, description)
161
- - Broken links to other files
162
- - Reserved words in names (anthropic, claude)
163
- - XML tags in frontmatter fields
164
- - Windows-style backslashes in paths
165
-
166
- Warnings (should fix):
167
- - Skill exceeds recommended length (>5000 lines)
168
- - References console-incompatible tools (Write, Edit, Bash)
169
-
170
- Exit Codes:
171
- 0 - Success | 1 - Errors found | 2 - System error
172
-
173
- Examples:
174
- $ vat agent audit # Audit current directory
175
- $ vat agent audit ./my-skill/SKILL.md # Audit single skill
176
- $ vat agent audit ./skills --recursive # Audit all skills recursively
177
140
  `);
178
141
  agent
179
142
  .command('import <skillPath>')
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/agent/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/agent/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ import type { ResourceMetadata } from '@vibe-agent-toolkit/resources';
2
+ export interface CacheStalenessResult {
3
+ fresh: FreshEntry[];
4
+ stale: StaleEntry[];
5
+ cacheOnly: ResourceMetadata[];
6
+ installedOnly: ResourceMetadata[];
7
+ }
8
+ export interface FreshEntry {
9
+ installed: ResourceMetadata;
10
+ cached: ResourceMetadata;
11
+ }
12
+ export interface StaleEntry {
13
+ installed: ResourceMetadata;
14
+ cached: ResourceMetadata;
15
+ }
16
+ /**
17
+ * Detect cache staleness by comparing checksums between installed and cached resources.
18
+ *
19
+ * Compares resources by filename and checksum to determine:
20
+ * - Fresh: Cache and installed have matching checksums
21
+ * - Stale: Cache and installed have different checksums
22
+ * - Cache-only: File exists in cache but not in installed
23
+ * - Installed-only: File exists in installed but not in cache
24
+ *
25
+ * Uses O(1) Map lookups for efficient matching.
26
+ *
27
+ * @param installed - Resources from installed plugin locations
28
+ * @param cached - Resources from ~/.claude/plugins/cache/
29
+ * @returns Categorized comparison results
30
+ */
31
+ export declare function detectCacheStaleness(installed: ResourceMetadata[], cached: ResourceMetadata[]): CacheStalenessResult;
32
+ //# sourceMappingURL=cache-detector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache-detector.d.ts","sourceRoot":"","sources":["../../../src/commands/audit/cache-detector.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAEtE,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,SAAS,EAAE,gBAAgB,EAAE,CAAC;IAC9B,aAAa,EAAE,gBAAgB,EAAE,CAAC;CACnC;AAED,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,gBAAgB,CAAC;IAC5B,MAAM,EAAE,gBAAgB,CAAC;CAC1B;AAED,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,gBAAgB,CAAC;IAC5B,MAAM,EAAE,gBAAgB,CAAC;CAC1B;AASD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,gBAAgB,EAAE,EAC7B,MAAM,EAAE,gBAAgB,EAAE,GACzB,oBAAoB,CAmDtB"}
@@ -0,0 +1,68 @@
1
+ import path from 'node:path';
2
+ /**
3
+ * Extract filename from file path
4
+ */
5
+ function getFileName(filePath) {
6
+ return path.basename(filePath);
7
+ }
8
+ /**
9
+ * Detect cache staleness by comparing checksums between installed and cached resources.
10
+ *
11
+ * Compares resources by filename and checksum to determine:
12
+ * - Fresh: Cache and installed have matching checksums
13
+ * - Stale: Cache and installed have different checksums
14
+ * - Cache-only: File exists in cache but not in installed
15
+ * - Installed-only: File exists in installed but not in cache
16
+ *
17
+ * Uses O(1) Map lookups for efficient matching.
18
+ *
19
+ * @param installed - Resources from installed plugin locations
20
+ * @param cached - Resources from ~/.claude/plugins/cache/
21
+ * @returns Categorized comparison results
22
+ */
23
+ export function detectCacheStaleness(installed, cached) {
24
+ const fresh = [];
25
+ const stale = [];
26
+ const cacheOnly = [];
27
+ const installedOnly = [];
28
+ // Build index of installed resources by filename for O(1) lookup
29
+ const installedByName = new Map();
30
+ for (const resource of installed) {
31
+ const filename = getFileName(resource.filePath);
32
+ installedByName.set(filename, resource);
33
+ }
34
+ // Check each cached resource
35
+ const matchedInstalledNames = new Set();
36
+ for (const cachedResource of cached) {
37
+ const cachedFilename = getFileName(cachedResource.filePath);
38
+ const installedResource = installedByName.get(cachedFilename);
39
+ if (!installedResource) {
40
+ // Cache file has no corresponding installed file
41
+ cacheOnly.push(cachedResource);
42
+ continue;
43
+ }
44
+ matchedInstalledNames.add(cachedFilename);
45
+ if (cachedResource.checksum === installedResource.checksum) {
46
+ // Checksums match - cache is fresh
47
+ fresh.push({
48
+ installed: installedResource,
49
+ cached: cachedResource,
50
+ });
51
+ }
52
+ else {
53
+ // Checksums differ - cache is stale
54
+ stale.push({
55
+ installed: installedResource,
56
+ cached: cachedResource,
57
+ });
58
+ }
59
+ }
60
+ // Find installed resources with no cache entry
61
+ for (const [name, resource] of installedByName) {
62
+ if (!matchedInstalledNames.has(name)) {
63
+ installedOnly.push(resource);
64
+ }
65
+ }
66
+ return { fresh, stale, cacheOnly, installedOnly };
67
+ }
68
+ //# sourceMappingURL=cache-detector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache-detector.js","sourceRoot":"","sources":["../../../src/commands/audit/cache-detector.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAqB7B;;GAEG;AACH,SAAS,WAAW,CAAC,QAAgB;IACnC,OAAO,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AACjC,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,oBAAoB,CAClC,SAA6B,EAC7B,MAA0B;IAE1B,MAAM,KAAK,GAAiB,EAAE,CAAC;IAC/B,MAAM,KAAK,GAAiB,EAAE,CAAC;IAC/B,MAAM,SAAS,GAAuB,EAAE,CAAC;IACzC,MAAM,aAAa,GAAuB,EAAE,CAAC;IAE7C,iEAAiE;IACjE,MAAM,eAAe,GAAG,IAAI,GAAG,EAA4B,CAAC;IAC5D,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QACjC,MAAM,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAChD,eAAe,CAAC,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC1C,CAAC;IAED,6BAA6B;IAC7B,MAAM,qBAAqB,GAAG,IAAI,GAAG,EAAU,CAAC;IAEhD,KAAK,MAAM,cAAc,IAAI,MAAM,EAAE,CAAC;QACpC,MAAM,cAAc,GAAG,WAAW,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;QAC5D,MAAM,iBAAiB,GAAG,eAAe,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;QAE9D,IAAI,CAAC,iBAAiB,EAAE,CAAC;YACvB,iDAAiD;YACjD,SAAS,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YAC/B,SAAS;QACX,CAAC;QAED,qBAAqB,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;QAE1C,IAAI,cAAc,CAAC,QAAQ,KAAK,iBAAiB,CAAC,QAAQ,EAAE,CAAC;YAC3D,mCAAmC;YACnC,KAAK,CAAC,IAAI,CAAC;gBACT,SAAS,EAAE,iBAAiB;gBAC5B,MAAM,EAAE,cAAc;aACvB,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,oCAAoC;YACpC,KAAK,CAAC,IAAI,CAAC;gBACT,SAAS,EAAE,iBAAiB;gBAC5B,MAAM,EAAE,cAAc;aACvB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,+CAA+C;IAC/C,KAAK,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,eAAe,EAAE,CAAC;QAC/C,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACrC,aAAa,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC/B,CAAC;IACH,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,CAAC;AACpD,CAAC"}
@@ -0,0 +1,41 @@
1
+ import type { ValidationIssue, ValidationResult } from '@vibe-agent-toolkit/runtime-claude-skills';
2
+ export interface HierarchicalOutput {
3
+ marketplaces: MarketplaceGroup[];
4
+ cachedPlugins: PluginGroup[];
5
+ standalonePlugins: PluginGroup[];
6
+ standaloneSkills: SkillEntry[];
7
+ }
8
+ export interface MarketplaceGroup {
9
+ name: string;
10
+ plugins: PluginGroup[];
11
+ }
12
+ export interface PluginGroup {
13
+ name: string;
14
+ skills: SkillEntry[];
15
+ }
16
+ export type CacheStatus = 'stale' | 'orphaned' | 'fresh';
17
+ export interface SkillEntry {
18
+ name: string;
19
+ path: string;
20
+ status: 'success' | 'warning' | 'error';
21
+ issues: ValidationIssue[];
22
+ cacheStatus?: CacheStatus;
23
+ }
24
+ /**
25
+ * Build hierarchical output structure from validation results.
26
+ *
27
+ * Groups skills by:
28
+ * 1. Marketplace -> Plugin -> Skills (for marketplace-installed plugins)
29
+ * 2. Standalone Plugins -> Skills (for non-marketplace plugins)
30
+ * 3. Standalone Skills (for skills without plugins)
31
+ *
32
+ * By default, only includes skills with issues (terse principle).
33
+ * With verbose=true, includes all scanned skills regardless of status.
34
+ * Replaces home directory with ~ for cleaner display.
35
+ *
36
+ * @param results - Validation results from audit command
37
+ * @param verbose - If true, include all results; if false, only show results with issues
38
+ * @returns Hierarchical structure for display
39
+ */
40
+ export declare function buildHierarchicalOutput(results: ValidationResult[], verbose?: boolean): HierarchicalOutput;
41
+ //# sourceMappingURL=hierarchical-output.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hierarchical-output.d.ts","sourceRoot":"","sources":["../../../src/commands/audit/hierarchical-output.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,2CAA2C,CAAC;AAGnG,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,gBAAgB,EAAE,CAAC;IACjC,aAAa,EAAE,WAAW,EAAE,CAAC;IAC7B,iBAAiB,EAAE,WAAW,EAAE,CAAC;IACjC,gBAAgB,EAAE,UAAU,EAAE,CAAC;CAChC;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,WAAW,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,UAAU,EAAE,CAAC;CACtB;AAED,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,UAAU,GAAG,OAAO,CAAC;AAEzD,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;IACxC,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;AA+RD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,gBAAgB,EAAE,EAAE,OAAO,GAAE,OAAe,GAAG,kBAAkB,CAiCjH"}
@@ -0,0 +1,267 @@
1
+ import * as os from 'node:os';
2
+ import { toForwardSlash } from '@vibe-agent-toolkit/utils';
3
+ /**
4
+ * Replace home directory with ~ for cleaner paths
5
+ * Normalizes paths for cross-platform comparison (handles Windows backslashes)
6
+ */
7
+ function replaceHomeDir(filePath) {
8
+ const homeDir = os.homedir();
9
+ // Normalize both paths to forward slashes for comparison
10
+ const normalizedFilePath = toForwardSlash(filePath);
11
+ const normalizedHomeDir = toForwardSlash(homeDir);
12
+ if (normalizedFilePath.startsWith(normalizedHomeDir)) {
13
+ // Replace using original paths to preserve platform separators in output
14
+ return filePath.replace(homeDir, '~');
15
+ }
16
+ return filePath;
17
+ }
18
+ /**
19
+ * Parse path structure to extract marketplace, plugin, and skill names
20
+ *
21
+ * Expected patterns:
22
+ * - Marketplace plugin skill: .../marketplaces/{marketplace}/{plugin}/skills/{skill}/SKILL.md
23
+ * - Standalone plugin skill: .../plugins/{plugin}/skills/{skill}/SKILL.md (no marketplaces/)
24
+ * - Standalone skill: .../plugins/{skill}/SKILL.md (no skills/)
25
+ */
26
+ function parsePathStructure(filePath) {
27
+ // Normalize to forward slashes for cross-platform parsing
28
+ const normalizedPath = toForwardSlash(filePath);
29
+ const parts = normalizedPath.split('/');
30
+ // Detect if this is a cached resource
31
+ const isCached = parts.includes('cache');
32
+ // Find key indices
33
+ const marketplacesIdx = parts.indexOf('marketplaces');
34
+ const pluginsIdx = parts.indexOf('plugins');
35
+ const skillsIdx = parts.indexOf('skills');
36
+ // Marketplace plugin skill: .../marketplaces/{marketplace}/{plugin}/skills/{skill}/SKILL.md
37
+ if (marketplacesIdx >= 0 && skillsIdx >= 0) {
38
+ const marketplace = parts[marketplacesIdx + 1];
39
+ const plugin = parts[marketplacesIdx + 2];
40
+ const skill = parts[skillsIdx + 1];
41
+ if (marketplace !== undefined && plugin !== undefined && skill !== undefined) {
42
+ return { marketplace, plugin, skill, isCached };
43
+ }
44
+ }
45
+ // Standalone plugin skill: .../plugins/{plugin}/skills/{skill}/SKILL.md
46
+ if (pluginsIdx >= 0 && skillsIdx >= 0) {
47
+ const plugin = parts[skillsIdx - 1]; // Plugin name is before /skills/
48
+ const skill = parts[skillsIdx + 1];
49
+ if (plugin !== undefined && skill !== undefined) {
50
+ return { plugin, skill, isCached };
51
+ }
52
+ }
53
+ // Standalone skill: .../plugins/{skill}/SKILL.md
54
+ if (pluginsIdx >= 0) {
55
+ const skill = parts[pluginsIdx + 1];
56
+ if (skill !== undefined) {
57
+ return { skill, isCached };
58
+ }
59
+ }
60
+ // Fallback: use directory name before SKILL.md
61
+ const skill = parts.at(-2) ?? 'unknown';
62
+ return { skill, isCached };
63
+ }
64
+ /**
65
+ * Add skill entry to marketplace map
66
+ */
67
+ function addToMarketplaceMap(marketplacesMap, marketplace, plugin, entry) {
68
+ if (!marketplacesMap.has(marketplace)) {
69
+ marketplacesMap.set(marketplace, new Map());
70
+ }
71
+ const pluginsMap = marketplacesMap.get(marketplace);
72
+ if (pluginsMap === undefined) {
73
+ return;
74
+ }
75
+ if (!pluginsMap.has(plugin)) {
76
+ pluginsMap.set(plugin, []);
77
+ }
78
+ pluginsMap.get(plugin)?.push(entry);
79
+ }
80
+ /**
81
+ * Add skill entry to cached plugin map
82
+ */
83
+ function addToCachedPluginMap(cachedPluginsMap, plugin, entry) {
84
+ if (!cachedPluginsMap.has(plugin)) {
85
+ cachedPluginsMap.set(plugin, []);
86
+ }
87
+ cachedPluginsMap.get(plugin)?.push(entry);
88
+ }
89
+ /**
90
+ * Add skill entry to standalone plugin map
91
+ */
92
+ function addToStandalonePluginMap(standalonePluginsMap, plugin, entry) {
93
+ if (!standalonePluginsMap.has(plugin)) {
94
+ standalonePluginsMap.set(plugin, []);
95
+ }
96
+ standalonePluginsMap.get(plugin)?.push(entry);
97
+ }
98
+ /**
99
+ * Filter out duplicate cache results that match their source
100
+ *
101
+ * Suppresses cache entries when:
102
+ * - A matching source (marketplace/plugin) exists
103
+ * - Same validation status (success/warning/error)
104
+ * - Same issues (count and content)
105
+ *
106
+ * Keeps cache entries when:
107
+ * - No matching source found (orphaned cache)
108
+ * - Different validation status or issues (stale/different)
109
+ *
110
+ * @returns Filtered results and cache status map
111
+ */
112
+ function filterCacheDuplicates(results) {
113
+ const sourceBySkillName = new Map();
114
+ const cacheResults = [];
115
+ const nonCacheResults = [];
116
+ const cacheStatusMap = new Map();
117
+ // First pass: categorize results and build source index
118
+ for (const result of results) {
119
+ const { skill, isCached } = parsePathStructure(result.path);
120
+ if (isCached) {
121
+ cacheResults.push(result);
122
+ }
123
+ else {
124
+ nonCacheResults.push(result);
125
+ // Index source results by skill name for matching
126
+ sourceBySkillName.set(skill, result);
127
+ }
128
+ }
129
+ // Second pass: filter cache results and track status
130
+ const filteredCache = [];
131
+ for (const cacheResult of cacheResults) {
132
+ const { skill } = parsePathStructure(cacheResult.path);
133
+ const sourceResult = sourceBySkillName.get(skill);
134
+ if (!sourceResult) {
135
+ // Orphaned cache - no matching source, keep it
136
+ filteredCache.push(cacheResult);
137
+ cacheStatusMap.set(cacheResult.path, 'orphaned');
138
+ continue;
139
+ }
140
+ // Check if cache and source have identical validation results
141
+ const statusMatches = cacheResult.status === sourceResult.status;
142
+ const issuesMatch = cacheResult.issues.length === sourceResult.issues.length &&
143
+ cacheResult.issues.every((issue, idx) => issue.code === sourceResult.issues[idx]?.code &&
144
+ issue.severity === sourceResult.issues[idx]?.severity);
145
+ if (!statusMatches || !issuesMatch) {
146
+ // Different validation results - keep both (stale or different)
147
+ filteredCache.push(cacheResult);
148
+ cacheStatusMap.set(cacheResult.path, 'stale');
149
+ }
150
+ else {
151
+ // Fresh cache - matches source, will be suppressed
152
+ cacheStatusMap.set(cacheResult.path, 'fresh');
153
+ }
154
+ // If they match exactly, suppress the cache copy (don't add to filteredCache)
155
+ }
156
+ return {
157
+ filtered: [...nonCacheResults, ...filteredCache],
158
+ cacheStatusMap,
159
+ };
160
+ }
161
+ /**
162
+ * Create skill entry from validation result
163
+ */
164
+ function createSkillEntry(result, cacheStatusMap) {
165
+ const { skill, isCached } = parsePathStructure(result.path);
166
+ const entry = {
167
+ name: skill,
168
+ path: replaceHomeDir(result.path),
169
+ status: result.status,
170
+ issues: result.issues,
171
+ };
172
+ // Add cache status if this is a cached resource
173
+ if (isCached) {
174
+ const cacheStatus = cacheStatusMap.get(result.path);
175
+ if (cacheStatus !== undefined) {
176
+ entry.cacheStatus = cacheStatus;
177
+ }
178
+ }
179
+ return entry;
180
+ }
181
+ /**
182
+ * Categorize entry into appropriate map
183
+ */
184
+ function categorizeEntry(entry, marketplace, plugin, isCached, maps) {
185
+ if (marketplace !== undefined && plugin !== undefined) {
186
+ addToMarketplaceMap(maps.marketplacesMap, marketplace, plugin, entry);
187
+ }
188
+ else if (plugin === undefined) {
189
+ maps.standaloneSkills.push(entry);
190
+ }
191
+ else if (isCached) {
192
+ addToCachedPluginMap(maps.cachedPluginsMap, plugin, entry);
193
+ }
194
+ else {
195
+ addToStandalonePluginMap(maps.standalonePluginsMap, plugin, entry);
196
+ }
197
+ }
198
+ /**
199
+ * Convert marketplace map to array structure
200
+ */
201
+ function convertMarketplacesMapToArray(marketplacesMap) {
202
+ const marketplaces = [];
203
+ for (const [marketplaceName, pluginsMap] of marketplacesMap) {
204
+ const plugins = [];
205
+ for (const [pluginName, skills] of pluginsMap) {
206
+ plugins.push({ name: pluginName, skills });
207
+ }
208
+ marketplaces.push({ name: marketplaceName, plugins });
209
+ }
210
+ return marketplaces;
211
+ }
212
+ /**
213
+ * Convert plugin map to array structure
214
+ */
215
+ function convertPluginMapToArray(pluginMap) {
216
+ const plugins = [];
217
+ for (const [pluginName, skills] of pluginMap) {
218
+ plugins.push({ name: pluginName, skills });
219
+ }
220
+ return plugins;
221
+ }
222
+ /**
223
+ * Build hierarchical output structure from validation results.
224
+ *
225
+ * Groups skills by:
226
+ * 1. Marketplace -> Plugin -> Skills (for marketplace-installed plugins)
227
+ * 2. Standalone Plugins -> Skills (for non-marketplace plugins)
228
+ * 3. Standalone Skills (for skills without plugins)
229
+ *
230
+ * By default, only includes skills with issues (terse principle).
231
+ * With verbose=true, includes all scanned skills regardless of status.
232
+ * Replaces home directory with ~ for cleaner display.
233
+ *
234
+ * @param results - Validation results from audit command
235
+ * @param verbose - If true, include all results; if false, only show results with issues
236
+ * @returns Hierarchical structure for display
237
+ */
238
+ export function buildHierarchicalOutput(results, verbose = false) {
239
+ // Filter out cache duplicates that match their source
240
+ const { filtered: filteredResults, cacheStatusMap } = filterCacheDuplicates(results);
241
+ const marketplacesMap = new Map();
242
+ const cachedPluginsMap = new Map();
243
+ const standalonePluginsMap = new Map();
244
+ const standaloneSkills = [];
245
+ const maps = {
246
+ marketplacesMap,
247
+ cachedPluginsMap,
248
+ standalonePluginsMap,
249
+ standaloneSkills,
250
+ };
251
+ for (const result of filteredResults) {
252
+ // Only include results with issues (terse principle), unless verbose mode
253
+ if (!verbose && result.status === 'success') {
254
+ continue;
255
+ }
256
+ const { marketplace, plugin, isCached } = parsePathStructure(result.path);
257
+ const entry = createSkillEntry(result, cacheStatusMap);
258
+ categorizeEntry(entry, marketplace, plugin, isCached, maps);
259
+ }
260
+ return {
261
+ marketplaces: convertMarketplacesMapToArray(marketplacesMap),
262
+ cachedPlugins: convertPluginMapToArray(cachedPluginsMap),
263
+ standalonePlugins: convertPluginMapToArray(standalonePluginsMap),
264
+ standaloneSkills,
265
+ };
266
+ }
267
+ //# sourceMappingURL=hierarchical-output.js.map