diff --git a/plugins/config-audit/docs/v5.1.0-test-audit.md b/plugins/config-audit/docs/v5.1.0-test-audit.md new file mode 100644 index 0000000..7b12a1b --- /dev/null +++ b/plugins/config-audit/docs/v5.1.0-test-audit.md @@ -0,0 +1,121 @@ +# v5.1.0 Title-String Assertion Audit + +Generated by Wave 0 / Step 0 pre-flight on 2026-05-01. + +This document is the authoritative change list for **Step 4** (replace title-string assertions with ID-based or shape-based assertions). Step 5 cannot wire the humanizer until every "WILL BREAK" entry below is converted. + +## Classification key + +- **(a) shape-only** — checks existence, type, or test-fixture input; not affected by humanization. +- **(b) literal-string WILL BREAK** — exact equality or substring match against scanner-produced title prose. Humanization rewrites these strings; the assertion must be re-anchored to `finding.id`, `finding.scanner`, or `finding.evidence`. +- **(c) ID-based** — already anchored on `finding.id` or scanner prefix. No change needed. + +## Audit summary + +| Test file | Matches | Will break (b) | Safe (a/c) | +|-----------|---------|----------------|------------| +| `tests/lib/output.test.mjs` | 1 | 0 | 1 | +| `tests/scanners/feature-gap-scanner.test.mjs` | 6 | 6 | 0 | +| `tests/scanners/hook-validator.test.mjs` | 12 | 9 | 3 | +| `tests/lib/diff-engine.test.mjs` | 2 | 0 | 2 | +| `tests/scanners/fix-engine.test.mjs` | 1 | 0 | 1 | +| `tests/scanners/plugin-health-scanner.test.mjs` | 9 | 8 | 1 | +| `tests/scanners/settings-validator.test.mjs` | 11 | 11 | 0 | +| **Total** | **42** | **34** | **8** | + +## Per-file findings + +### `tests/lib/output.test.mjs` + +| Line | Code | Class | Action | +|------|------|-------|--------| +| 46 | `assert.strictEqual(f.title, 'Test')` | (a) shape-only | None — `'Test'` is the test's own input to `finding()` constructor, not a scanner-produced title. | + +### `tests/scanners/feature-gap-scanner.test.mjs` + +| Line | Code | Class | Action | +|------|------|-------|--------| +| 45 | `f.title === 'No CLAUDE.md file'` | (b) WILL BREAK | Replace with `f.id === ''`. Anchor on ID. | +| 49 | `f.title === 'No MCP servers configured'` | (b) WILL BREAK | Replace with ID anchor. | +| 53 | `f.title === 'No hooks configured'` | (b) WILL BREAK | Replace with ID anchor. | +| 96 | `f.title === 'No hooks configured'` | (b) WILL BREAK | Replace with ID anchor. | +| 100 | `f.title === 'No MCP servers configured'` | (b) WILL BREAK | Replace with ID anchor. | +| 150 | `f.title === 'No CLAUDE.md file'` | (b) WILL BREAK | Replace with ID anchor. | + +> **Implementation note for Step 4:** look up the actual GAP finding IDs via `grep -n "title:" scanners/feature-gap-scanner.mjs` and substitute. For shape only: `assert.ok(f.id.startsWith('CA-GAP-'))` is acceptable when the test only cares that a GAP finding fired. + +### `tests/scanners/hook-validator.test.mjs` + +| Line | Code | Class | Action | +|------|------|-------|--------| +| 30 | `serious.map(f => f.title).join(', ')` | (a) shape-only | None — title used only for error-message formatting in failed assert; not the assertion itself. | +| 49 | `f.title === 'Unknown hook event'` | (b) WILL BREAK | Replace with ID anchor. | +| 54 | `f.title.includes('Matcher must be a string')` | (b) WILL BREAK | Replace with ID anchor or `.evidence.includes(...)`. | +| 59 | `f.title === 'Invalid hook handler type'` | (b) WILL BREAK | Replace with ID anchor. | +| 64 | `f.title.includes('timeout')` | (b) WILL BREAK | Replace with ID anchor. | +| 69 | `f.title === 'Unknown hook event'` | (b) WILL BREAK | Replace with ID anchor. | +| 80 | `/verbose hook output/i.test(x.title \|\| '')` | (b) WILL BREAK | Replace with ID anchor. | +| 81 | `result.findings.map(x => x.title).join(' \| ')` | (a) shape-only | Used only in error-message formatting. None. | +| 91 | `/verbose hook output/i.test(x.title \|\| '')` | (b) WILL BREAK | Replace with ID anchor. | +| 92 | `f?.title` | (a) shape-only | Used only in error-message formatting. None. | + +### `tests/lib/diff-engine.test.mjs` + +| Line | Code | Class | Action | +|------|------|-------|--------| +| 66 | `diff.newFindings[0].title === 'New issue'` | (a) shape-only | None — `'New issue'` is the test's synthetic finding input, not scanner-produced. | +| 78 | `diff.resolvedFindings[0].title === 'Old issue'` | (a) shape-only | None — synthetic test input. | + +### `tests/scanners/fix-engine.test.mjs` + +| Line | Code | Class | Action | +|------|------|-------|--------| +| 62 | `assert.ok(m.title, 'Manual finding should have title')` | (a) shape-only | None — pure existence check. | + +### `tests/scanners/plugin-health-scanner.test.mjs` + +| Line | Code | Class | Action | +|------|------|-------|--------| +| 52 | `f.title.includes('Missing required field')` | (b) WILL BREAK | Replace with ID anchor or `f.evidence.includes(...)`. | +| 59 | `f.title.includes('missing') && f.title.includes('section')` | (b) WILL BREAK | Replace with ID anchor on the missing-section finding. | +| 68 | `f.title.includes('Missing required field')` | (b) WILL BREAK | Replace with ID anchor. | +| 75 | `f.title === 'Missing CLAUDE.md'` | (b) WILL BREAK | Replace with ID anchor. | +| 82 | `f.title === 'Command missing frontmatter'` | (b) WILL BREAK | Replace with ID anchor. | +| 90 | `f.title.startsWith('Agent missing frontmatter field:')` | (b) WILL BREAK | Replace with ID anchor + `f.evidence.includes(...)` for the field name (humanizer preserves evidence). | +| 93 | `missingAgent.map(f => f.title).join(', ')` | (a) shape-only | Used only in error-message formatting. None. | +| 102 | `result.findings[0].title === 'No plugins found'` | (b) WILL BREAK | Replace with ID anchor. | +| 125 | `assert.ok(f.title)` | (a) shape-only | None — pure existence check. | + +### `tests/scanners/settings-validator.test.mjs` + +| Line | Code | Class | Action | +|------|------|-------|--------| +| 49 | `f.title === 'Unknown settings key'` | (b) WILL BREAK | Replace with ID anchor (likely `CA-SET-001` or similar — verify). | +| 54 | `f.title === 'Deprecated settings key'` | (b) WILL BREAK | Replace with ID anchor. | +| 59 | `f.title === 'Type mismatch in settings'` | (b) WILL BREAK | Replace with ID anchor. | +| 64 | `f.title === 'Invalid effortLevel value'` | (b) WILL BREAK | Replace with ID anchor. | +| 69 | `f.title.includes('array instead of object')` | (b) WILL BREAK | Replace with ID anchor. | +| 74 | `f.title.includes('array instead of object')` | (b) WILL BREAK | Replace with ID anchor. | +| 86 | `f.title === 'Unknown settings key' && /additionalDirectories/.test(f.evidence)` | (b) WILL BREAK | Keep evidence regex; replace title check with ID anchor. | +| 96 | `/additionalDirectories/i.test(x.title \|\| '')` | (b) WILL BREAK | Replace with ID anchor + evidence regex (additionalDirectories likely appears in evidence already). | +| 98 | `f?.title` | (a) shape-only — but inside breaking assertion | Will become moot after line 96 is fixed. | +| 106 | `/additionalDirectories/i.test(x.title \|\| '')` | (b) WILL BREAK | Replace with ID anchor + evidence regex. | +| 107 | `result.findings.map(x => x.title).join(' \| ')` | (a) shape-only | Error-message formatting only. None. | + +## Step 4 implementation guidance + +1. For each (b) WILL BREAK row, look up the actual finding ID from the corresponding scanner source: + - `grep -n "id: 'CA-GAP-" scanners/feature-gap-scanner.mjs` + - `grep -n "id: 'CA-HKV-" scanners/hook-validator.mjs` + - `grep -n "id: 'CA-PLH-" scanners/plugin-health-scanner.mjs` + - `grep -n "id: 'CA-SET-" scanners/settings-validator.mjs` +2. Replace the title check with `f.id === ''`. If the test cares about a sub-variant (e.g., a specific deprecated key), pair the ID anchor with an `f.evidence.includes(...)` substring check — humanizer preserves `evidence` exactly. +3. For broad categorical checks ("any GAP finding fired"), use `f.id.startsWith('CA-GAP-')`. +4. For tests that capture `f.title` only inside `assert` failure-message templates (class (a)): leave them. Humanization changes the displayed string but the assertion still anchors on `f.id`. +5. Re-run `node --test 'tests/**/*.test.mjs'` after changes; expect zero regressions before proceeding to Step 5. + +## Total scope for Step 4 + +- **6 test files** require code changes (`output.test.mjs` and `diff-engine.test.mjs` are clean). +- **34 distinct assertions** to convert. +- Estimated effort: 1–2 hours including ID lookup and verification. diff --git a/plugins/config-audit/tests/snapshots/v5.0.0-stderr/posture.txt b/plugins/config-audit/tests/snapshots/v5.0.0-stderr/posture.txt new file mode 100644 index 0000000..a4b8829 --- /dev/null +++ b/plugins/config-audit/tests/snapshots/v5.0.0-stderr/posture.txt @@ -0,0 +1,30 @@ + [CML] CLAUDE.md Linter: 0 finding(s) (9ms) + [SET] Settings Validator: 0 finding(s) (0ms) + [HKV] Hook Validator: 0 finding(s) (2ms) + [RUL] Rules Validator: 0 finding(s) (0ms) + [MCP] MCP Config Validator: 0 finding(s) (1ms) + [IMP] Import Resolver: 0 finding(s) (1ms) + [CNF] Conflict Detector: 0 finding(s) (1ms) + [GAP] Feature Gap Scanner: 17 finding(s) (3ms) + [TOK] Token Hotspots: 1 finding(s) (116ms) + [CPS] Cache-Prefix Stability: 0 finding(s) (1ms) + [DIS] Disabled-In-Schema: 1 finding(s) (1ms) + [COL] Plugin Skill Collision: 1 finding(s) (77ms) + +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + Config-Audit Health Score +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + Health: A (97/100) 9 areas scanned + + Area Scores + ─────────── + CLAUDE.md ........... A (100) Settings ............ A (90) + Hooks ............... A (100) Rules ............... A (100) + MCP ................. A (100) Imports ............. A (100) + Conflicts ........... A (100) Token Efficiency .... A (90) + Plugin Hygiene ...... A (90) + + 17 opportunities available — run /config-audit feature-gap for recommendations + +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ diff --git a/plugins/config-audit/tests/snapshots/v5.0.0/drift.json b/plugins/config-audit/tests/snapshots/v5.0.0/drift.json new file mode 100644 index 0000000..78785b8 --- /dev/null +++ b/plugins/config-audit/tests/snapshots/v5.0.0/drift.json @@ -0,0 +1,421 @@ +{ + "newFindings": [], + "resolvedFindings": [], + "unchangedFindings": [ + { + "id": "CA-GAP-001", + "scanner": "GAP", + "severity": "medium", + "title": "No custom skills or commands", + "description": "Feature gap: No custom skills or commands. Create project-specific skills in .claude/skills/ or commands in .claude/commands/ to automate repetitive workflows.", + "file": null, + "line": null, + "evidence": null, + "category": "t1", + "recommendation": "Create project-specific skills in .claude/skills/ or commands in .claude/commands/ to automate repetitive workflows.", + "autoFixable": false + }, + { + "id": "CA-GAP-002", + "scanner": "GAP", + "severity": "low", + "title": "Settings only at one scope", + "description": "Feature gap: Settings only at one scope. Use all 3 settings scopes: ~/.claude/settings.json (user), .claude/settings.json (project), .claude/settings.local.json (local/personal).", + "file": null, + "line": null, + "evidence": null, + "category": "t2", + "recommendation": "Use all 3 settings scopes: ~/.claude/settings.json (user), .claude/settings.json (project), .claude/settings.local.json (local/personal).", + "autoFixable": false + }, + { + "id": "CA-GAP-003", + "scanner": "GAP", + "severity": "low", + "title": "No path-scoped rules", + "description": "Feature gap: No path-scoped rules. Create .claude/rules/*.md with paths: frontmatter to apply rules only to matching files.", + "file": null, + "line": null, + "evidence": null, + "category": "t2", + "recommendation": "Create .claude/rules/*.md with paths: frontmatter to apply rules only to matching files.", + "autoFixable": false + }, + { + "id": "CA-GAP-004", + "scanner": "GAP", + "severity": "low", + "title": "Low hook diversity", + "description": "Feature gap: Low hook diversity. Use hooks across 3+ events (e.g., SessionStart, PreToolUse, Stop) for comprehensive automation.", + "file": null, + "line": null, + "evidence": null, + "category": "t2", + "recommendation": "Use hooks across 3+ events (e.g., SessionStart, PreToolUse, Stop) for comprehensive automation.", + "autoFixable": false + }, + { + "id": "CA-GAP-005", + "scanner": "GAP", + "severity": "low", + "title": "No custom subagents", + "description": "Feature gap: No custom subagents. Create custom agents in .claude/agents/ or ~/.claude/agents/ with specialized tools and model selection.", + "file": null, + "line": null, + "evidence": null, + "category": "t2", + "recommendation": "Create custom agents in .claude/agents/ or ~/.claude/agents/ with specialized tools and model selection.", + "autoFixable": false + }, + { + "id": "CA-GAP-006", + "scanner": "GAP", + "severity": "low", + "title": "No model configuration", + "description": "Feature gap: No model configuration. Set model preferences in settings.json (model, modelOverrides) for cost/quality optimization.", + "file": null, + "line": null, + "evidence": null, + "category": "t2", + "recommendation": "Set model preferences in settings.json (model, modelOverrides) for cost/quality optimization.", + "autoFixable": false + }, + { + "id": "CA-GAP-007", + "scanner": "GAP", + "severity": "info", + "title": "No status line configured", + "description": "Feature gap: No status line configured. Configure statusLine in settings.json to show context window usage, cost, and model info.", + "file": null, + "line": null, + "evidence": null, + "category": "t3", + "recommendation": "Configure statusLine in settings.json to show context window usage, cost, and model info.", + "autoFixable": false + }, + { + "id": "CA-GAP-008", + "scanner": "GAP", + "severity": "info", + "title": "No custom keybindings", + "description": "Feature gap: No custom keybindings. Create ~/.claude/keybindings.json to customize keyboard shortcuts (e.g., bind chat:newline to Shift+Enter).", + "file": null, + "line": null, + "evidence": null, + "category": "t3", + "recommendation": "Create ~/.claude/keybindings.json to customize keyboard shortcuts (e.g., bind chat:newline to Shift+Enter).", + "autoFixable": false + }, + { + "id": "CA-GAP-009", + "scanner": "GAP", + "severity": "info", + "title": "Using default output style", + "description": "Feature gap: Using default output style. Try \"Explanatory\" or \"Learning\" output styles, or create custom styles in .claude/output-styles/.", + "file": null, + "line": null, + "evidence": null, + "category": "t3", + "recommendation": "Try \"Explanatory\" or \"Learning\" output styles, or create custom styles in .claude/output-styles/.", + "autoFixable": false + }, + { + "id": "CA-GAP-010", + "scanner": "GAP", + "severity": "info", + "title": "No worktree workflow", + "description": "Feature gap: No worktree workflow. Use --worktree for parallel feature development. Configure worktree.symlinkDirectories for node_modules.", + "file": null, + "line": null, + "evidence": null, + "category": "t3", + "recommendation": "Use --worktree for parallel feature development. Configure worktree.symlinkDirectories for node_modules.", + "autoFixable": false + }, + { + "id": "CA-GAP-011", + "scanner": "GAP", + "severity": "info", + "title": "No advanced skill frontmatter", + "description": "Feature gap: No advanced skill frontmatter. Use disable-model-invocation, context:fork, or argument-hint in skill frontmatter for better control.", + "file": null, + "line": null, + "evidence": null, + "category": "t3", + "recommendation": "Use disable-model-invocation, context:fork, or argument-hint in skill frontmatter for better control.", + "autoFixable": false + }, + { + "id": "CA-GAP-012", + "scanner": "GAP", + "severity": "info", + "title": "No subagent isolation", + "description": "Feature gap: No subagent isolation. Use isolation: worktree in agent frontmatter for safe parallel development.", + "file": null, + "line": null, + "evidence": null, + "category": "t3", + "recommendation": "Use isolation: worktree in agent frontmatter for safe parallel development.", + "autoFixable": false + }, + { + "id": "CA-GAP-013", + "scanner": "GAP", + "severity": "info", + "title": "No dynamic skill context", + "description": "Feature gap: No dynamic skill context. Use !`command` syntax in skills to inject dynamic context (e.g., !`git branch --show-current`).", + "file": null, + "line": null, + "evidence": null, + "category": "t3", + "recommendation": "Use !`command` syntax in skills to inject dynamic context (e.g., !`git branch --show-current`).", + "autoFixable": false + }, + { + "id": "CA-GAP-014", + "scanner": "GAP", + "severity": "info", + "title": "No autoMode classifier", + "description": "Feature gap: No autoMode classifier. Configure autoMode in user/local settings with environment context and allow/deny rules.", + "file": null, + "line": null, + "evidence": null, + "category": "t3", + "recommendation": "Configure autoMode in user/local settings with environment context and allow/deny rules.", + "autoFixable": false + }, + { + "id": "CA-GAP-015", + "scanner": "GAP", + "severity": "info", + "title": "No custom plugin", + "description": "Feature gap: No custom plugin. Package reusable skills, agents, and hooks as a Claude Code plugin with .claude-plugin/plugin.json.", + "file": null, + "line": null, + "evidence": null, + "category": "t4", + "recommendation": "Package reusable skills, agents, and hooks as a Claude Code plugin with .claude-plugin/plugin.json.", + "autoFixable": false + }, + { + "id": "CA-GAP-016", + "scanner": "GAP", + "severity": "info", + "title": "No managed settings", + "description": "Feature gap: No managed settings. Use managed-settings.json for organization-wide policy enforcement.", + "file": null, + "line": null, + "evidence": null, + "category": "t4", + "recommendation": "Use managed-settings.json for organization-wide policy enforcement.", + "autoFixable": false + }, + { + "id": "CA-GAP-017", + "scanner": "GAP", + "severity": "info", + "title": "No LSP plugins", + "description": "Feature gap: No LSP plugins. Add .lsp.json for real-time code intelligence from language servers.", + "file": null, + "line": null, + "evidence": null, + "category": "t4", + "recommendation": "Add .lsp.json for real-time code intelligence from language servers.", + "autoFixable": false + }, + { + "id": "CA-TOK-001", + "scanner": "TOK", + "severity": "low", + "title": "High MCP tool-schema budget on server \"memory\"", + "description": "MCP server \"memory (.mcp.json)\" has tool count unknown — could not parse manifest or cached tools/list. Tool schemas load on every turn; an unverified server may be inflating the per-turn payload silently.", + "file": ".mcp.json", + "line": null, + "evidence": "tool_count=unknown; server=\"memory\"; source=\".mcp.json\" — severity reflects estimated tokens/turn based on structural heuristic; not measured against runtime telemetry", + "category": "token-efficiency", + "recommendation": "Install the package locally (so detect-mcp-tool-count can read its manifest), or run the server once and cache its tools/list response under ~/.claude/config-audit/mcp-cache/.json. See knowledge/cache-telemetry-recipe.md.", + "autoFixable": false + }, + { + "id": "CA-DIS-001", + "scanner": "DIS", + "severity": "low", + "title": "Tool listed in both permissions.deny and permissions.allow", + "description": ".claude/settings.json contains 1 tool present in both deny and allow lists. The deny list wins — the allow entries are dead config but still load on every turn and may confuse future readers about intent.", + "file": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/config-audit/tests/fixtures/marketplace-medium/.claude/settings.json", + "line": null, + "evidence": "Read: allow=\"Read(src/**)\" + deny=\"Read(./.env)\"", + "category": "permissions-hygiene", + "recommendation": "Remove the redundant allow entries. If you actually want this tool enabled, remove it from the deny list instead. Settings should express intent clearly.", + "autoFixable": false + }, + { + "id": "CA-COL-001", + "scanner": "COL", + "severity": "low", + "title": "Skill name \"okr-offentlig-sektor\" used by multiple plugins", + "description": "2 plugins (okr, okr) expose a skill named \"okr-offentlig-sektor\". Even when invocation is namespaced via /plugin:skill, shared names create ambiguity in error messages, search results, and the plugin-skills enumeration.", + "file": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/okr/skills/okr-offentlig-sektor/SKILL.md", + "line": null, + "evidence": "name=\"okr-offentlig-sektor\"; plugins=okr,okr", + "category": "plugin-hygiene", + "recommendation": "Coordinate naming across plugins, or rename one to clarify intent. The shared name forces every reader to disambiguate by source.", + "autoFixable": false, + "details": { + "namespaces": [ + { + "source": "plugin:okr", + "name": "okr-offentlig-sektor", + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/okr/skills/okr-offentlig-sektor/SKILL.md" + }, + { + "source": "plugin:okr", + "name": "okr-offentlig-sektor", + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/okr/skills/okr-offentlig-sektor/SKILL.md" + } + ] + } + } + ], + "movedFindings": [], + "scoreChange": { + "before": { + "score": 91, + "grade": "A" + }, + "after": { + "score": 91, + "grade": "A" + }, + "delta": 0 + }, + "areaChanges": [ + { + "name": "CLAUDE.md", + "before": { + "score": 100, + "grade": "A" + }, + "after": { + "score": 100, + "grade": "A" + }, + "delta": 0 + }, + { + "name": "Settings", + "before": { + "score": 90, + "grade": "A" + }, + "after": { + "score": 90, + "grade": "A" + }, + "delta": 0 + }, + { + "name": "Hooks", + "before": { + "score": 100, + "grade": "A" + }, + "after": { + "score": 100, + "grade": "A" + }, + "delta": 0 + }, + { + "name": "Rules", + "before": { + "score": 100, + "grade": "A" + }, + "after": { + "score": 100, + "grade": "A" + }, + "delta": 0 + }, + { + "name": "MCP", + "before": { + "score": 100, + "grade": "A" + }, + "after": { + "score": 100, + "grade": "A" + }, + "delta": 0 + }, + { + "name": "Imports", + "before": { + "score": 100, + "grade": "A" + }, + "after": { + "score": 100, + "grade": "A" + }, + "delta": 0 + }, + { + "name": "Conflicts", + "before": { + "score": 100, + "grade": "A" + }, + "after": { + "score": 100, + "grade": "A" + }, + "delta": 0 + }, + { + "name": "Feature Coverage", + "before": { + "score": 43, + "grade": "D" + }, + "after": { + "score": 43, + "grade": "D" + }, + "delta": 0 + }, + { + "name": "Token Efficiency", + "before": { + "score": 90, + "grade": "A" + }, + "after": { + "score": 90, + "grade": "A" + }, + "delta": 0 + }, + { + "name": "Plugin Hygiene", + "before": { + "score": 90, + "grade": "A" + }, + "after": { + "score": 90, + "grade": "A" + }, + "delta": 0 + } + ], + "summary": { + "totalBefore": 20, + "totalAfter": 20, + "newCount": 0, + "resolvedCount": 0, + "trend": "stable" + } +} diff --git a/plugins/config-audit/tests/snapshots/v5.0.0/fix-cli.json b/plugins/config-audit/tests/snapshots/v5.0.0/fix-cli.json new file mode 100644 index 0000000..acdf49d --- /dev/null +++ b/plugins/config-audit/tests/snapshots/v5.0.0/fix-cli.json @@ -0,0 +1,130 @@ +{ + "planned": [], + "applied": [], + "failed": [], + "verified": [], + "regressions": [], + "manual": [ + { + "findingId": "CA-GAP-001", + "title": "No custom skills or commands", + "file": null, + "recommendation": "Create project-specific skills in .claude/skills/ or commands in .claude/commands/ to automate repetitive workflows." + }, + { + "findingId": "CA-GAP-002", + "title": "Settings only at one scope", + "file": null, + "recommendation": "Use all 3 settings scopes: ~/.claude/settings.json (user), .claude/settings.json (project), .claude/settings.local.json (local/personal)." + }, + { + "findingId": "CA-GAP-003", + "title": "No path-scoped rules", + "file": null, + "recommendation": "Create .claude/rules/*.md with paths: frontmatter to apply rules only to matching files." + }, + { + "findingId": "CA-GAP-004", + "title": "Low hook diversity", + "file": null, + "recommendation": "Use hooks across 3+ events (e.g., SessionStart, PreToolUse, Stop) for comprehensive automation." + }, + { + "findingId": "CA-GAP-005", + "title": "No custom subagents", + "file": null, + "recommendation": "Create custom agents in .claude/agents/ or ~/.claude/agents/ with specialized tools and model selection." + }, + { + "findingId": "CA-GAP-006", + "title": "No model configuration", + "file": null, + "recommendation": "Set model preferences in settings.json (model, modelOverrides) for cost/quality optimization." + }, + { + "findingId": "CA-GAP-007", + "title": "No status line configured", + "file": null, + "recommendation": "Configure statusLine in settings.json to show context window usage, cost, and model info." + }, + { + "findingId": "CA-GAP-008", + "title": "No custom keybindings", + "file": null, + "recommendation": "Create ~/.claude/keybindings.json to customize keyboard shortcuts (e.g., bind chat:newline to Shift+Enter)." + }, + { + "findingId": "CA-GAP-009", + "title": "Using default output style", + "file": null, + "recommendation": "Try \"Explanatory\" or \"Learning\" output styles, or create custom styles in .claude/output-styles/." + }, + { + "findingId": "CA-GAP-010", + "title": "No worktree workflow", + "file": null, + "recommendation": "Use --worktree for parallel feature development. Configure worktree.symlinkDirectories for node_modules." + }, + { + "findingId": "CA-GAP-011", + "title": "No advanced skill frontmatter", + "file": null, + "recommendation": "Use disable-model-invocation, context:fork, or argument-hint in skill frontmatter for better control." + }, + { + "findingId": "CA-GAP-012", + "title": "No subagent isolation", + "file": null, + "recommendation": "Use isolation: worktree in agent frontmatter for safe parallel development." + }, + { + "findingId": "CA-GAP-013", + "title": "No dynamic skill context", + "file": null, + "recommendation": "Use !`command` syntax in skills to inject dynamic context (e.g., !`git branch --show-current`)." + }, + { + "findingId": "CA-GAP-014", + "title": "No autoMode classifier", + "file": null, + "recommendation": "Configure autoMode in user/local settings with environment context and allow/deny rules." + }, + { + "findingId": "CA-GAP-015", + "title": "No custom plugin", + "file": null, + "recommendation": "Package reusable skills, agents, and hooks as a Claude Code plugin with .claude-plugin/plugin.json." + }, + { + "findingId": "CA-GAP-016", + "title": "No managed settings", + "file": null, + "recommendation": "Use managed-settings.json for organization-wide policy enforcement." + }, + { + "findingId": "CA-GAP-017", + "title": "No LSP plugins", + "file": null, + "recommendation": "Add .lsp.json for real-time code intelligence from language servers." + }, + { + "findingId": "CA-TOK-001", + "title": "High MCP tool-schema budget on server \"memory\"", + "file": ".mcp.json", + "recommendation": "Install the package locally (so detect-mcp-tool-count can read its manifest), or run the server once and cache its tools/list response under ~/.claude/config-audit/mcp-cache/.json. See knowledge/cache-telemetry-recipe.md." + }, + { + "findingId": "CA-DIS-001", + "title": "Tool listed in both permissions.deny and permissions.allow", + "file": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/config-audit/tests/fixtures/marketplace-medium/.claude/settings.json", + "recommendation": "Remove the redundant allow entries. If you actually want this tool enabled, remove it from the deny list instead. Settings should express intent clearly." + }, + { + "findingId": "CA-COL-001", + "title": "Skill name \"okr-offentlig-sektor\" used by multiple plugins", + "file": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/okr/skills/okr-offentlig-sektor/SKILL.md", + "recommendation": "Coordinate naming across plugins, or rename one to clarify intent. The shared name forces every reader to disambiguate by source." + } + ], + "backupId": null +} diff --git a/plugins/config-audit/tests/snapshots/v5.0.0/manifest.json b/plugins/config-audit/tests/snapshots/v5.0.0/manifest.json new file mode 100644 index 0000000..5ab8aff --- /dev/null +++ b/plugins/config-audit/tests/snapshots/v5.0.0/manifest.json @@ -0,0 +1,1253 @@ +{ + "meta": { + "tool": "config-audit:manifest", + "repoPath": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/config-audit/tests/fixtures/marketplace-medium", + "generatedAt": "2026-05-01T14:44:33.062Z", + "durationMs": 116 + }, + "sources": [ + { + "kind": "plugin", + "name": "plugin-dev", + "source": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/plugin-dev", + "estimated_tokens": 27574 + }, + { + "kind": "plugin", + "name": "ms-ai-architect", + "source": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/ms-ai-architect", + "estimated_tokens": 21982 + }, + { + "kind": "plugin", + "name": "linkedin-thought-leadership", + "source": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/linkedin-thought-leadership", + "estimated_tokens": 19852 + }, + { + "kind": "plugin", + "name": "content-machine", + "source": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/content-machine", + "estimated_tokens": 11367 + }, + { + "kind": "plugin", + "name": "mcp-server-dev", + "source": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/mcp-server-dev", + "estimated_tokens": 9836 + }, + { + "kind": "plugin", + "name": "skill-creator", + "source": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/skill-creator", + "estimated_tokens": 8292 + }, + { + "kind": "skill", + "name": "skill-creator", + "source": "plugin:skill-creator", + "estimated_tokens": 8292 + }, + { + "kind": "plugin", + "name": "harness", + "source": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/harness", + "estimated_tokens": 7032 + }, + { + "kind": "plugin", + "name": "ralph-wiggum", + "source": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/ralph-wiggum", + "estimated_tokens": 5783 + }, + { + "kind": "skill", + "name": "skill-development", + "source": "plugin:plugin-dev", + "estimated_tokens": 5707 + }, + { + "kind": "plugin", + "name": "config-audit", + "source": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/config-audit", + "estimated_tokens": 5589 + }, + { + "kind": "plugin", + "name": "newsletter", + "source": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/newsletter", + "estimated_tokens": 5443 + }, + { + "kind": "plugin", + "name": "kiur", + "source": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/kiur", + "estimated_tokens": 5050 + }, + { + "kind": "skill", + "name": "capability-auditor", + "source": "user", + "estimated_tokens": 5036 + }, + { + "kind": "plugin", + "name": "math-olympiad", + "source": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/math-olympiad", + "estimated_tokens": 4991 + }, + { + "kind": "skill", + "name": "math-olympiad", + "source": "plugin:math-olympiad", + "estimated_tokens": 4991 + }, + { + "kind": "skill", + "name": "build-mcp-app", + "source": "plugin:mcp-server-dev", + "estimated_tokens": 4848 + }, + { + "kind": "skill", + "name": "command-development", + "source": "plugin:plugin-dev", + "estimated_tokens": 4809 + }, + { + "kind": "plugin", + "name": "okr", + "source": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/okr", + "estimated_tokens": 4775 + }, + { + "kind": "plugin", + "name": "okr", + "source": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/okr", + "estimated_tokens": 4775 + }, + { + "kind": "plugin", + "name": "llm-security", + "source": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/llm-security", + "estimated_tokens": 4492 + }, + { + "kind": "skill", + "name": "story", + "source": "user", + "estimated_tokens": 4214 + }, + { + "kind": "skill", + "name": "ms-ai-infrastructure", + "source": "plugin:ms-ai-architect", + "estimated_tokens": 4185 + }, + { + "kind": "skill", + "name": "ms-ai-governance", + "source": "plugin:ms-ai-architect", + "estimated_tokens": 4073 + }, + { + "kind": "skill", + "name": "hook-development", + "source": "plugin:plugin-dev", + "estimated_tokens": 4062 + }, + { + "kind": "plugin", + "name": "ultraplan-local", + "source": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/ultraplan-local", + "estimated_tokens": 3780 + }, + { + "kind": "plugin", + "name": "ultra-cc-architect", + "source": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/ultra-cc-architect", + "estimated_tokens": 3676 + }, + { + "kind": "skill", + "name": "plugin-structure", + "source": "plugin:plugin-dev", + "estimated_tokens": 3449 + }, + { + "kind": "plugin", + "name": "hookify", + "source": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/hookify", + "estimated_tokens": 3148 + }, + { + "kind": "skill", + "name": "mcp-integration", + "source": "plugin:plugin-dev", + "estimated_tokens": 3130 + }, + { + "kind": "skill", + "name": "plugin-settings", + "source": "plugin:plugin-dev", + "estimated_tokens": 3025 + }, + { + "kind": "skill", + "name": "ms-ai-security", + "source": "plugin:ms-ai-architect", + "estimated_tokens": 3024 + }, + { + "kind": "skill", + "name": "build-mcp-server", + "source": "plugin:mcp-server-dev", + "estimated_tokens": 3021 + }, + { + "kind": "skill", + "name": "gpt-prompting-expert", + "source": "user", + "estimated_tokens": 2951 + }, + { + "kind": "skill", + "name": "pptx", + "source": "user", + "estimated_tokens": 2898 + }, + { + "kind": "skill", + "name": "agent-development", + "source": "plugin:plugin-dev", + "estimated_tokens": 2792 + }, + { + "kind": "plugin", + "name": "claude-code-setup", + "source": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/claude-code-setup", + "estimated_tokens": 2714 + }, + { + "kind": "skill", + "name": "claude-automation-recommender", + "source": "plugin:claude-code-setup", + "estimated_tokens": 2714 + }, + { + "kind": "skill", + "name": "claude-code-changelog", + "source": "user", + "estimated_tokens": 2697 + }, + { + "kind": "skill", + "name": "ms-ai-advisor", + "source": "plugin:ms-ai-architect", + "estimated_tokens": 2658 + }, + { + "kind": "claude-md", + "name": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/config-audit/CLAUDE.md", + "source": "project", + "estimated_tokens": 2537 + }, + { + "kind": "skill", + "name": "linkedin-strategy", + "source": "plugin:linkedin-thought-leadership", + "estimated_tokens": 2509 + }, + { + "kind": "skill", + "name": "linkedin-content-creation", + "source": "plugin:linkedin-thought-leadership", + "estimated_tokens": 2503 + }, + { + "kind": "skill", + "name": "ms-ai-engineering", + "source": "plugin:ms-ai-architect", + "estimated_tokens": 2496 + }, + { + "kind": "plugin", + "name": "claude-code-to-copilot", + "source": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/claude-code-to-copilot", + "estimated_tokens": 2466 + }, + { + "kind": "skill", + "name": "convert-to-copilot", + "source": "plugin:claude-code-to-copilot", + "estimated_tokens": 2466 + }, + { + "kind": "skill", + "name": "kiur", + "source": "plugin:kiur", + "estimated_tokens": 2402 + }, + { + "kind": "claude-md", + "name": "/Users/ktg/.claude/CLAUDE.md", + "source": "user", + "estimated_tokens": 2381 + }, + { + "kind": "skill", + "name": "harness", + "source": "plugin:harness", + "estimated_tokens": 2347 + }, + { + "kind": "plugin", + "name": "vegnormalene", + "source": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/vegnormalene", + "estimated_tokens": 2301 + }, + { + "kind": "skill", + "name": "mcp-builder", + "source": "user", + "estimated_tokens": 2273 + }, + { + "kind": "skill", + "name": "linkedin-thought-leadership", + "source": "plugin:linkedin-thought-leadership", + "estimated_tokens": 2227 + }, + { + "kind": "skill", + "name": "agent-browser", + "source": "user", + "estimated_tokens": 2199 + }, + { + "kind": "skill", + "name": "cc-architect-catalog", + "source": "plugin:ultra-cc-architect", + "estimated_tokens": 2176 + }, + { + "kind": "skill", + "name": "writing-rules", + "source": "plugin:hookify", + "estimated_tokens": 2106 + }, + { + "kind": "skill", + "name": "learning-design", + "source": "plugin:content-machine", + "estimated_tokens": 2032 + }, + { + "kind": "skill", + "name": "build-mcpb", + "source": "plugin:mcp-server-dev", + "estimated_tokens": 1967 + }, + { + "kind": "plugin", + "name": "sadhguru-wisdom", + "source": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/sadhguru-wisdom", + "estimated_tokens": 1919 + }, + { + "kind": "skill", + "name": "linkedin-analytics", + "source": "plugin:linkedin-thought-leadership", + "estimated_tokens": 1915 + }, + { + "kind": "skill", + "name": "okr-offentlig-sektor", + "source": "plugin:okr", + "estimated_tokens": 1854 + }, + { + "kind": "skill", + "name": "okr-offentlig-sektor", + "source": "plugin:okr", + "estimated_tokens": 1854 + }, + { + "kind": "plugin", + "name": "code-modernization", + "source": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/code-modernization", + "estimated_tokens": 1800 + }, + { + "kind": "skill", + "name": "linkedin-voice", + "source": "plugin:linkedin-thought-leadership", + "estimated_tokens": 1786 + }, + { + "kind": "skill", + "name": "linkedin-networking", + "source": "plugin:linkedin-thought-leadership", + "estimated_tokens": 1668 + }, + { + "kind": "plugin", + "name": "claude-md-management", + "source": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/claude-md-management", + "estimated_tokens": 1657 + }, + { + "kind": "skill", + "name": "image-style-guide", + "source": "plugin:content-machine", + "estimated_tokens": 1628 + }, + { + "kind": "skill", + "name": "brand-voice", + "source": "plugin:content-machine", + "estimated_tokens": 1622 + }, + { + "kind": "skill", + "name": "claude-md-improver", + "source": "plugin:claude-md-management", + "estimated_tokens": 1507 + }, + { + "kind": "plugin", + "name": "graceful-handoff", + "source": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/graceful-handoff", + "estimated_tokens": 1479 + }, + { + "kind": "skill", + "name": "repo-init", + "source": "user", + "estimated_tokens": 1393 + }, + { + "kind": "skill", + "name": "seo-intelligence", + "source": "plugin:content-machine", + "estimated_tokens": 1348 + }, + { + "kind": "skill", + "name": "graceful-handoff", + "source": "plugin:graceful-handoff", + "estimated_tokens": 1291 + }, + { + "kind": "plugin", + "name": "example-plugin", + "source": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/example-plugin", + "estimated_tokens": 1139 + }, + { + "kind": "skill", + "name": "tier-requirements", + "source": "plugin:content-machine", + "estimated_tokens": 1111 + }, + { + "kind": "plugin", + "name": "frontend-design", + "source": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/frontend-design", + "estimated_tokens": 1069 + }, + { + "kind": "skill", + "name": "frontend-design", + "source": "plugin:frontend-design", + "estimated_tokens": 1069 + }, + { + "kind": "skill", + "name": "security-controls", + "source": "plugin:ralph-wiggum", + "estimated_tokens": 1064 + }, + { + "kind": "plugin", + "name": "pr-review-toolkit", + "source": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/pr-review-toolkit", + "estimated_tokens": 1050 + }, + { + "kind": "plugin", + "name": "ai-psychosis", + "source": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/ai-psychosis", + "estimated_tokens": 1017 + }, + { + "kind": "plugin", + "name": "playground", + "source": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/playground", + "estimated_tokens": 956 + }, + { + "kind": "skill", + "name": "playground", + "source": "plugin:playground", + "estimated_tokens": 956 + }, + { + "kind": "skill", + "name": "persona-creator", + "source": "user", + "estimated_tokens": 931 + }, + { + "kind": "skill", + "name": "sadhana-privacy", + "source": "plugin:content-machine", + "estimated_tokens": 926 + }, + { + "kind": "skill", + "name": "youtube-analyse", + "source": "user", + "estimated_tokens": 922 + }, + { + "kind": "plugin", + "name": "az-900-skill", + "source": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/az-900-skill", + "estimated_tokens": 865 + }, + { + "kind": "skill", + "name": "az-900", + "source": "plugin:az-900-skill", + "estimated_tokens": 865 + }, + { + "kind": "skill", + "name": "config-hierarchy", + "source": "plugin:config-audit", + "estimated_tokens": 850 + }, + { + "kind": "skill", + "name": "sadhguru-persona", + "source": "plugin:sadhguru-wisdom", + "estimated_tokens": 800 + }, + { + "kind": "skill", + "name": "newsletter-workflow", + "source": "plugin:newsletter", + "estimated_tokens": 793 + }, + { + "kind": "skill", + "name": "prepare-release", + "source": "user", + "estimated_tokens": 692 + }, + { + "kind": "skill", + "name": "example-skill", + "source": "plugin:example-plugin", + "estimated_tokens": 682 + }, + { + "kind": "skill", + "name": "prd-writing", + "source": "plugin:ralph-wiggum", + "estimated_tokens": 618 + }, + { + "kind": "claude-md", + "name": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/CLAUDE.md", + "source": "project", + "estimated_tokens": 614 + }, + { + "kind": "plugin", + "name": "feature-dev", + "source": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/feature-dev", + "estimated_tokens": 600 + }, + { + "kind": "skill", + "name": "ai-psychosis", + "source": "plugin:ai-psychosis", + "estimated_tokens": 591 + }, + { + "kind": "skill", + "name": "vegnorm-expert", + "source": "plugin:vegnormalene", + "estimated_tokens": 582 + }, + { + "kind": "skill", + "name": "autonomous-loop", + "source": "plugin:ralph-wiggum", + "estimated_tokens": 562 + }, + { + "kind": "skill", + "name": "e2e-verification", + "source": "plugin:ralph-wiggum", + "estimated_tokens": 549 + }, + { + "kind": "plugin", + "name": "ralph-loop", + "source": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/ralph-loop", + "estimated_tokens": 534 + }, + { + "kind": "plugin", + "name": "claude-code-essentials", + "source": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/claude-code-essentials", + "estimated_tokens": 500 + }, + { + "kind": "mcp-server", + "name": "memory", + "source": ".mcp.json", + "estimated_tokens": 500 + }, + { + "kind": "mcp-server", + "name": "sadhguru-wisdom", + "source": "plugin:sadhguru-wisdom", + "estimated_tokens": 500 + }, + { + "kind": "mcp-server", + "name": "vegnorm-rag", + "source": "plugin:vegnormalene", + "estimated_tokens": 500 + }, + { + "kind": "plugin", + "name": "agent-sdk-dev", + "source": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/agent-sdk-dev", + "estimated_tokens": 450 + }, + { + "kind": "plugin", + "name": "commit-commands", + "source": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/commit-commands", + "estimated_tokens": 450 + }, + { + "kind": "skill", + "name": "essentials", + "source": "plugin:claude-code-essentials", + "estimated_tokens": 362 + }, + { + "kind": "skill", + "name": "example-command", + "source": "plugin:example-plugin", + "estimated_tokens": 307 + }, + { + "kind": "plugin", + "name": "code-review", + "source": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/code-review", + "estimated_tokens": 150 + }, + { + "kind": "plugin", + "name": "code-simplifier", + "source": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/code-simplifier", + "estimated_tokens": 150 + }, + { + "kind": "claude-md", + "name": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/config-audit/tests/fixtures/marketplace-medium/CLAUDE.md", + "source": "project", + "estimated_tokens": 116 + }, + { + "kind": "plugin", + "name": "security-guidance", + "source": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/security-guidance", + "estimated_tokens": 110 + }, + { + "kind": "plugin", + "name": "explanatory-output-style", + "source": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/explanatory-output-style", + "estimated_tokens": 93 + }, + { + "kind": "plugin", + "name": "learning-output-style", + "source": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/learning-output-style", + "estimated_tokens": 92 + }, + { + "kind": "claude-md", + "name": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/config-audit/tests/fixtures/marketplace-medium/.claude/shared.md", + "source": "import", + "estimated_tokens": 68 + }, + { + "kind": "hook", + "name": "SessionStart", + "source": "user", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "PreToolUse:Bash", + "source": "user", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "PreToolUse:Bash", + "source": "user", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "PreToolUse:Bash", + "source": "user", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "PreToolUse:Edit|Write", + "source": "user", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "PreToolUse:Edit|Write", + "source": "user", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "PreToolUse:mcp__*", + "source": "user", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "PostToolUse:*", + "source": "user", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "PostToolUse:Bash", + "source": "user", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "Stop", + "source": "user", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "UserPromptSubmit", + "source": "user", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "SessionStart", + "source": "plugin:explanatory-output-style", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "PreToolUse", + "source": "plugin:hookify", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "PostToolUse", + "source": "plugin:hookify", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "Stop", + "source": "plugin:hookify", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "UserPromptSubmit", + "source": "plugin:hookify", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "SessionStart", + "source": "plugin:learning-output-style", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "Stop", + "source": "plugin:ralph-loop", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "PreToolUse:Edit|Write|MultiEdit", + "source": "plugin:security-guidance", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "SessionStart", + "source": "plugin:ai-psychosis", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "UserPromptSubmit", + "source": "plugin:ai-psychosis", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "PostToolUse", + "source": "plugin:ai-psychosis", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "SessionEnd", + "source": "plugin:ai-psychosis", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "PreToolUse:Edit|Write", + "source": "plugin:config-audit", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "PostToolUse:Edit|Write", + "source": "plugin:config-audit", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "SessionStart", + "source": "plugin:config-audit", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "Stop", + "source": "plugin:config-audit", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "SessionStart", + "source": "plugin:graceful-handoff", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "Stop", + "source": "plugin:graceful-handoff", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "SessionStart", + "source": "plugin:linkedin-thought-leadership", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "PreToolUse:Write|Edit", + "source": "plugin:linkedin-thought-leadership", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "PreToolUse:Write|Edit", + "source": "plugin:linkedin-thought-leadership", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "PreToolUse:Write|Edit", + "source": "plugin:linkedin-thought-leadership", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "Stop", + "source": "plugin:linkedin-thought-leadership", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "UserPromptSubmit", + "source": "plugin:linkedin-thought-leadership", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "PostToolUse:Write", + "source": "plugin:linkedin-thought-leadership", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "PreCompact", + "source": "plugin:linkedin-thought-leadership", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "Notification:idle_prompt", + "source": "plugin:linkedin-thought-leadership", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "UserPromptSubmit", + "source": "plugin:llm-security", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "UserPromptSubmit", + "source": "plugin:llm-security", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "PreToolUse:Edit|Write", + "source": "plugin:llm-security", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "PreToolUse:Bash", + "source": "plugin:llm-security", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "PreToolUse:Bash", + "source": "plugin:llm-security", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "PreToolUse:Write", + "source": "plugin:llm-security", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "PostToolUse", + "source": "plugin:llm-security", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "PostToolUse", + "source": "plugin:llm-security", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "PreCompact", + "source": "plugin:llm-security", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "SessionStart", + "source": "plugin:ms-ai-architect", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "Stop", + "source": "plugin:ms-ai-architect", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "SessionStart", + "source": "plugin:okr", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "UserPromptSubmit", + "source": "plugin:okr", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "PreCompact", + "source": "plugin:okr", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "Stop", + "source": "plugin:okr", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "PreToolUse:Bash", + "source": "plugin:ultraplan-local", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "PreToolUse:Write", + "source": "plugin:ultraplan-local", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "UserPromptSubmit", + "source": "plugin:ultraplan-local", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "PostToolUse:Bash", + "source": "plugin:ultraplan-local", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "PreCompact", + "source": "plugin:ultraplan-local", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "PreToolUse:Bash", + "source": "plugin:claude-code-essentials", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "PreToolUse:Edit|Write", + "source": "plugin:claude-code-essentials", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "SessionStart", + "source": "plugin:harness", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "SessionStart", + "source": "plugin:harness", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "Stop", + "source": "plugin:harness", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "Stop", + "source": "plugin:harness", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "Stop", + "source": "plugin:harness", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "SessionEnd", + "source": "plugin:harness", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "SubagentStop", + "source": "plugin:harness", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "PreCompact", + "source": "plugin:harness", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "PreToolUse:Write|Edit", + "source": "plugin:harness", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "PreToolUse:Write|Edit", + "source": "plugin:harness", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "PreToolUse:EnterPlanMode", + "source": "plugin:harness", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "PostToolUse:Write|Edit", + "source": "plugin:harness", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "PostToolUse:Write|Edit", + "source": "plugin:harness", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "SessionStart", + "source": "plugin:kiur", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "PreToolUse:Bash", + "source": "plugin:kiur", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "PostToolUse:Bash", + "source": "plugin:kiur", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "SubagentStop", + "source": "plugin:kiur", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "PreCompact", + "source": "plugin:kiur", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "SessionEnd", + "source": "plugin:kiur", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "SessionStart", + "source": "plugin:okr", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "UserPromptSubmit", + "source": "plugin:okr", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "PreCompact", + "source": "plugin:okr", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "Stop", + "source": "plugin:okr", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "UserPromptSubmit", + "source": "plugin:ralph-wiggum", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "PreToolUse:Bash", + "source": "plugin:ralph-wiggum", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "PreToolUse:Bash", + "source": "plugin:ralph-wiggum", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "PreToolUse:Write|Edit", + "source": "plugin:ralph-wiggum", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "PreToolUse:Write|Edit", + "source": "plugin:ralph-wiggum", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "PreToolUse:Write|Edit", + "source": "plugin:ralph-wiggum", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "SessionStart", + "source": "plugin:ralph-wiggum", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "Stop", + "source": "plugin:ralph-wiggum", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "SessionStart", + "source": "plugin:sadhguru-wisdom", + "estimated_tokens": 15 + }, + { + "kind": "hook", + "name": "SessionStart", + "source": "plugin:vegnormalene", + "estimated_tokens": 15 + } + ], + "total": 334986 +} \ No newline at end of file diff --git a/plugins/config-audit/tests/snapshots/v5.0.0/plugin-health.json b/plugins/config-audit/tests/snapshots/v5.0.0/plugin-health.json new file mode 100644 index 0000000..9158d70 --- /dev/null +++ b/plugins/config-audit/tests/snapshots/v5.0.0/plugin-health.json @@ -0,0 +1,14 @@ +{ + "scanner": "PLH", + "status": "ok", + "files_scanned": 1, + "duration_ms": 17, + "findings": [], + "counts": { + "critical": 0, + "high": 0, + "medium": 0, + "low": 0, + "info": 0 + } +} diff --git a/plugins/config-audit/tests/snapshots/v5.0.0/posture.json b/plugins/config-audit/tests/snapshots/v5.0.0/posture.json new file mode 100644 index 0000000..8198e55 --- /dev/null +++ b/plugins/config-audit/tests/snapshots/v5.0.0/posture.json @@ -0,0 +1,639 @@ +{ + "utilization": { + "score": 43, + "overhang": 57 + }, + "maturity": { + "level": 2, + "name": "Structured", + "description": "Rules, skills, hooks" + }, + "segment": { + "segment": "Developing", + "description": "Basic setup — significant features untapped" + }, + "areas": [ + { + "id": "claude_md", + "name": "CLAUDE.md", + "grade": "A", + "score": 100, + "findingCount": 0 + }, + { + "id": "settings", + "name": "Settings", + "grade": "A", + "score": 90, + "findingCount": 1 + }, + { + "id": "hooks", + "name": "Hooks", + "grade": "A", + "score": 100, + "findingCount": 0 + }, + { + "id": "rules", + "name": "Rules", + "grade": "A", + "score": 100, + "findingCount": 0 + }, + { + "id": "mcp", + "name": "MCP", + "grade": "A", + "score": 100, + "findingCount": 0 + }, + { + "id": "imports", + "name": "Imports", + "grade": "A", + "score": 100, + "findingCount": 0 + }, + { + "id": "conflicts", + "name": "Conflicts", + "grade": "A", + "score": 100, + "findingCount": 0 + }, + { + "id": "feature_coverage", + "name": "Feature Coverage", + "grade": "D", + "score": 43, + "findingCount": 17 + }, + { + "id": "token_efficiency", + "name": "Token Efficiency", + "grade": "A", + "score": 90, + "findingCount": 1 + }, + { + "id": "plugin_hygiene", + "name": "Plugin Hygiene", + "grade": "A", + "score": 90, + "findingCount": 1 + } + ], + "overallGrade": "A", + "topActions": [ + "Create project-specific skills in .claude/skills/ or commands in .claude/commands/ to automate repetitive workflows.", + "Use all 3 settings scopes: ~/.claude/settings.json (user), .claude/settings.json (project), .claude/settings.local.json (local/personal).", + "Create .claude/rules/*.md with paths: frontmatter to apply rules only to matching files." + ], + "opportunityCount": 17, + "scannerEnvelope": { + "meta": { + "target": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/config-audit/tests/fixtures/marketplace-medium", + "timestamp": "2026-05-01T14:44:22.725Z", + "version": "2.2.0", + "tool": "config-audit" + }, + "scanners": [ + { + "scanner": "CML", + "status": "ok", + "files_scanned": 1, + "duration_ms": 1, + "findings": [], + "counts": { + "critical": 0, + "high": 0, + "medium": 0, + "low": 0, + "info": 0 + } + }, + { + "scanner": "SET", + "status": "ok", + "files_scanned": 1, + "duration_ms": 0, + "findings": [], + "counts": { + "critical": 0, + "high": 0, + "medium": 0, + "low": 0, + "info": 0 + } + }, + { + "scanner": "HKV", + "status": "ok", + "files_scanned": 1, + "duration_ms": 1, + "findings": [], + "counts": { + "critical": 0, + "high": 0, + "medium": 0, + "low": 0, + "info": 0 + } + }, + { + "scanner": "RUL", + "status": "skipped", + "files_scanned": 0, + "duration_ms": 1, + "findings": [], + "counts": { + "critical": 0, + "high": 0, + "medium": 0, + "low": 0, + "info": 0 + } + }, + { + "scanner": "MCP", + "status": "ok", + "files_scanned": 1, + "duration_ms": 0, + "findings": [], + "counts": { + "critical": 0, + "high": 0, + "medium": 0, + "low": 0, + "info": 0 + } + }, + { + "scanner": "IMP", + "status": "ok", + "files_scanned": 1, + "duration_ms": 1, + "findings": [], + "counts": { + "critical": 0, + "high": 0, + "medium": 0, + "low": 0, + "info": 0 + } + }, + { + "scanner": "CNF", + "status": "ok", + "files_scanned": 2, + "duration_ms": 1, + "findings": [], + "counts": { + "critical": 0, + "high": 0, + "medium": 0, + "low": 0, + "info": 0 + } + }, + { + "scanner": "GAP", + "status": "ok", + "files_scanned": 4, + "duration_ms": 3, + "findings": [ + { + "id": "CA-GAP-001", + "scanner": "GAP", + "severity": "medium", + "title": "No custom skills or commands", + "description": "Feature gap: No custom skills or commands. Create project-specific skills in .claude/skills/ or commands in .claude/commands/ to automate repetitive workflows.", + "file": null, + "line": null, + "evidence": null, + "category": "t1", + "recommendation": "Create project-specific skills in .claude/skills/ or commands in .claude/commands/ to automate repetitive workflows.", + "autoFixable": false + }, + { + "id": "CA-GAP-002", + "scanner": "GAP", + "severity": "low", + "title": "Settings only at one scope", + "description": "Feature gap: Settings only at one scope. Use all 3 settings scopes: ~/.claude/settings.json (user), .claude/settings.json (project), .claude/settings.local.json (local/personal).", + "file": null, + "line": null, + "evidence": null, + "category": "t2", + "recommendation": "Use all 3 settings scopes: ~/.claude/settings.json (user), .claude/settings.json (project), .claude/settings.local.json (local/personal).", + "autoFixable": false + }, + { + "id": "CA-GAP-003", + "scanner": "GAP", + "severity": "low", + "title": "No path-scoped rules", + "description": "Feature gap: No path-scoped rules. Create .claude/rules/*.md with paths: frontmatter to apply rules only to matching files.", + "file": null, + "line": null, + "evidence": null, + "category": "t2", + "recommendation": "Create .claude/rules/*.md with paths: frontmatter to apply rules only to matching files.", + "autoFixable": false + }, + { + "id": "CA-GAP-004", + "scanner": "GAP", + "severity": "low", + "title": "Low hook diversity", + "description": "Feature gap: Low hook diversity. Use hooks across 3+ events (e.g., SessionStart, PreToolUse, Stop) for comprehensive automation.", + "file": null, + "line": null, + "evidence": null, + "category": "t2", + "recommendation": "Use hooks across 3+ events (e.g., SessionStart, PreToolUse, Stop) for comprehensive automation.", + "autoFixable": false + }, + { + "id": "CA-GAP-005", + "scanner": "GAP", + "severity": "low", + "title": "No custom subagents", + "description": "Feature gap: No custom subagents. Create custom agents in .claude/agents/ or ~/.claude/agents/ with specialized tools and model selection.", + "file": null, + "line": null, + "evidence": null, + "category": "t2", + "recommendation": "Create custom agents in .claude/agents/ or ~/.claude/agents/ with specialized tools and model selection.", + "autoFixable": false + }, + { + "id": "CA-GAP-006", + "scanner": "GAP", + "severity": "low", + "title": "No model configuration", + "description": "Feature gap: No model configuration. Set model preferences in settings.json (model, modelOverrides) for cost/quality optimization.", + "file": null, + "line": null, + "evidence": null, + "category": "t2", + "recommendation": "Set model preferences in settings.json (model, modelOverrides) for cost/quality optimization.", + "autoFixable": false + }, + { + "id": "CA-GAP-007", + "scanner": "GAP", + "severity": "info", + "title": "No status line configured", + "description": "Feature gap: No status line configured. Configure statusLine in settings.json to show context window usage, cost, and model info.", + "file": null, + "line": null, + "evidence": null, + "category": "t3", + "recommendation": "Configure statusLine in settings.json to show context window usage, cost, and model info.", + "autoFixable": false + }, + { + "id": "CA-GAP-008", + "scanner": "GAP", + "severity": "info", + "title": "No custom keybindings", + "description": "Feature gap: No custom keybindings. Create ~/.claude/keybindings.json to customize keyboard shortcuts (e.g., bind chat:newline to Shift+Enter).", + "file": null, + "line": null, + "evidence": null, + "category": "t3", + "recommendation": "Create ~/.claude/keybindings.json to customize keyboard shortcuts (e.g., bind chat:newline to Shift+Enter).", + "autoFixable": false + }, + { + "id": "CA-GAP-009", + "scanner": "GAP", + "severity": "info", + "title": "Using default output style", + "description": "Feature gap: Using default output style. Try \"Explanatory\" or \"Learning\" output styles, or create custom styles in .claude/output-styles/.", + "file": null, + "line": null, + "evidence": null, + "category": "t3", + "recommendation": "Try \"Explanatory\" or \"Learning\" output styles, or create custom styles in .claude/output-styles/.", + "autoFixable": false + }, + { + "id": "CA-GAP-010", + "scanner": "GAP", + "severity": "info", + "title": "No worktree workflow", + "description": "Feature gap: No worktree workflow. Use --worktree for parallel feature development. Configure worktree.symlinkDirectories for node_modules.", + "file": null, + "line": null, + "evidence": null, + "category": "t3", + "recommendation": "Use --worktree for parallel feature development. Configure worktree.symlinkDirectories for node_modules.", + "autoFixable": false + }, + { + "id": "CA-GAP-011", + "scanner": "GAP", + "severity": "info", + "title": "No advanced skill frontmatter", + "description": "Feature gap: No advanced skill frontmatter. Use disable-model-invocation, context:fork, or argument-hint in skill frontmatter for better control.", + "file": null, + "line": null, + "evidence": null, + "category": "t3", + "recommendation": "Use disable-model-invocation, context:fork, or argument-hint in skill frontmatter for better control.", + "autoFixable": false + }, + { + "id": "CA-GAP-012", + "scanner": "GAP", + "severity": "info", + "title": "No subagent isolation", + "description": "Feature gap: No subagent isolation. Use isolation: worktree in agent frontmatter for safe parallel development.", + "file": null, + "line": null, + "evidence": null, + "category": "t3", + "recommendation": "Use isolation: worktree in agent frontmatter for safe parallel development.", + "autoFixable": false + }, + { + "id": "CA-GAP-013", + "scanner": "GAP", + "severity": "info", + "title": "No dynamic skill context", + "description": "Feature gap: No dynamic skill context. Use !`command` syntax in skills to inject dynamic context (e.g., !`git branch --show-current`).", + "file": null, + "line": null, + "evidence": null, + "category": "t3", + "recommendation": "Use !`command` syntax in skills to inject dynamic context (e.g., !`git branch --show-current`).", + "autoFixable": false + }, + { + "id": "CA-GAP-014", + "scanner": "GAP", + "severity": "info", + "title": "No autoMode classifier", + "description": "Feature gap: No autoMode classifier. Configure autoMode in user/local settings with environment context and allow/deny rules.", + "file": null, + "line": null, + "evidence": null, + "category": "t3", + "recommendation": "Configure autoMode in user/local settings with environment context and allow/deny rules.", + "autoFixable": false + }, + { + "id": "CA-GAP-015", + "scanner": "GAP", + "severity": "info", + "title": "No custom plugin", + "description": "Feature gap: No custom plugin. Package reusable skills, agents, and hooks as a Claude Code plugin with .claude-plugin/plugin.json.", + "file": null, + "line": null, + "evidence": null, + "category": "t4", + "recommendation": "Package reusable skills, agents, and hooks as a Claude Code plugin with .claude-plugin/plugin.json.", + "autoFixable": false + }, + { + "id": "CA-GAP-016", + "scanner": "GAP", + "severity": "info", + "title": "No managed settings", + "description": "Feature gap: No managed settings. Use managed-settings.json for organization-wide policy enforcement.", + "file": null, + "line": null, + "evidence": null, + "category": "t4", + "recommendation": "Use managed-settings.json for organization-wide policy enforcement.", + "autoFixable": false + }, + { + "id": "CA-GAP-017", + "scanner": "GAP", + "severity": "info", + "title": "No LSP plugins", + "description": "Feature gap: No LSP plugins. Add .lsp.json for real-time code intelligence from language servers.", + "file": null, + "line": null, + "evidence": null, + "category": "t4", + "recommendation": "Add .lsp.json for real-time code intelligence from language servers.", + "autoFixable": false + } + ], + "counts": { + "critical": 0, + "high": 0, + "medium": 1, + "low": 5, + "info": 11 + } + }, + { + "scanner": "TOK", + "status": "ok", + "files_scanned": 2, + "duration_ms": 167, + "findings": [ + { + "id": "CA-TOK-001", + "scanner": "TOK", + "severity": "low", + "title": "High MCP tool-schema budget on server \"memory\"", + "description": "MCP server \"memory (.mcp.json)\" has tool count unknown — could not parse manifest or cached tools/list. Tool schemas load on every turn; an unverified server may be inflating the per-turn payload silently.", + "file": ".mcp.json", + "line": null, + "evidence": "tool_count=unknown; server=\"memory\"; source=\".mcp.json\" — severity reflects estimated tokens/turn based on structural heuristic; not measured against runtime telemetry", + "category": "token-efficiency", + "recommendation": "Install the package locally (so detect-mcp-tool-count can read its manifest), or run the server once and cache its tools/list response under ~/.claude/config-audit/mcp-cache/.json. See knowledge/cache-telemetry-recipe.md.", + "autoFixable": false + } + ], + "counts": { + "critical": 0, + "high": 0, + "medium": 0, + "low": 1, + "info": 0 + }, + "hotspots": [ + { + "source": "mcp:memory (.mcp.json)", + "estimated_tokens": 500, + "rank": 1, + "recommendations": [ + "Review whether this source needs to load on every turn." + ] + }, + { + "source": "mcp:sadhguru-wisdom (plugin:sadhguru-wisdom)", + "estimated_tokens": 500, + "rank": 2, + "recommendations": [ + "Review whether this source needs to load on every turn." + ] + }, + { + "source": "mcp:vegnorm-rag (plugin:vegnormalene)", + "estimated_tokens": 500, + "rank": 3, + "recommendations": [ + "Review whether this source needs to load on every turn." + ] + }, + { + "source": "CLAUDE.md", + "estimated_tokens": 116, + "rank": 4, + "recommendations": [ + "Move volatile top-of-file content to the bottom or extract to an @import-ed file.", + "Split overlong CLAUDE.md into focused @imports (≤200 lines each)." + ], + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/config-audit/tests/fixtures/marketplace-medium/CLAUDE.md" + }, + { + "source": "hooks/hooks.json", + "estimated_tokens": 81, + "rank": 5, + "recommendations": [ + "Deduplicate overlapping entries — each duplicate inflates the per-turn schema payload.", + "Move rarely-used permissions to a project-local override." + ], + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/config-audit/tests/fixtures/marketplace-medium/hooks/hooks.json" + }, + { + "source": ".claude/settings.json", + "estimated_tokens": 59, + "rank": 6, + "recommendations": [ + "Deduplicate overlapping entries — each duplicate inflates the per-turn schema payload.", + "Move rarely-used permissions to a project-local override." + ], + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/config-audit/tests/fixtures/marketplace-medium/.claude/settings.json" + }, + { + "source": ".mcp.json", + "estimated_tokens": 53, + "rank": 7, + "recommendations": [ + "Deduplicate overlapping entries — each duplicate inflates the per-turn schema payload.", + "Move rarely-used permissions to a project-local override." + ], + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/config-audit/tests/fixtures/marketplace-medium/.mcp.json" + } + ], + "total_estimated_tokens": 1809, + "activeConfig": { + "claudeMdEstimatedTokens": 5716, + "mcpServerCount": 3, + "pluginCount": 41, + "skillCount": 65 + } + }, + { + "scanner": "CPS", + "status": "ok", + "files_scanned": 1, + "duration_ms": 1, + "findings": [], + "counts": { + "critical": 0, + "high": 0, + "medium": 0, + "low": 0, + "info": 0 + } + }, + { + "scanner": "DIS", + "status": "ok", + "files_scanned": 1, + "duration_ms": 0, + "findings": [ + { + "id": "CA-DIS-001", + "scanner": "DIS", + "severity": "low", + "title": "Tool listed in both permissions.deny and permissions.allow", + "description": ".claude/settings.json contains 1 tool present in both deny and allow lists. The deny list wins — the allow entries are dead config but still load on every turn and may confuse future readers about intent.", + "file": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/config-audit/tests/fixtures/marketplace-medium/.claude/settings.json", + "line": null, + "evidence": "Read: allow=\"Read(src/**)\" + deny=\"Read(./.env)\"", + "category": "permissions-hygiene", + "recommendation": "Remove the redundant allow entries. If you actually want this tool enabled, remove it from the deny list instead. Settings should express intent clearly.", + "autoFixable": false + } + ], + "counts": { + "critical": 0, + "high": 0, + "medium": 0, + "low": 1, + "info": 0 + } + }, + { + "scanner": "COL", + "status": "ok", + "files_scanned": 65, + "duration_ms": 107, + "findings": [ + { + "id": "CA-COL-001", + "scanner": "COL", + "severity": "low", + "title": "Skill name \"okr-offentlig-sektor\" used by multiple plugins", + "description": "2 plugins (okr, okr) expose a skill named \"okr-offentlig-sektor\". Even when invocation is namespaced via /plugin:skill, shared names create ambiguity in error messages, search results, and the plugin-skills enumeration.", + "file": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/okr/skills/okr-offentlig-sektor/SKILL.md", + "line": null, + "evidence": "name=\"okr-offentlig-sektor\"; plugins=okr,okr", + "category": "plugin-hygiene", + "recommendation": "Coordinate naming across plugins, or rename one to clarify intent. The shared name forces every reader to disambiguate by source.", + "autoFixable": false, + "details": { + "namespaces": [ + { + "source": "plugin:okr", + "name": "okr-offentlig-sektor", + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/okr/skills/okr-offentlig-sektor/SKILL.md" + }, + { + "source": "plugin:okr", + "name": "okr-offentlig-sektor", + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/okr/skills/okr-offentlig-sektor/SKILL.md" + } + ] + } + } + ], + "counts": { + "critical": 0, + "high": 0, + "medium": 0, + "low": 1, + "info": 0 + } + } + ], + "aggregate": { + "total_findings": 20, + "counts": { + "critical": 0, + "high": 0, + "medium": 1, + "low": 8, + "info": 11 + }, + "risk_score": 12, + "risk_band": "Medium", + "verdict": "PASS", + "scanners_ok": 11, + "scanners_error": 0, + "scanners_skipped": 1 + } + } +} \ No newline at end of file diff --git a/plugins/config-audit/tests/snapshots/v5.0.0/scan-orchestrator.json b/plugins/config-audit/tests/snapshots/v5.0.0/scan-orchestrator.json new file mode 100644 index 0000000..ba109a9 --- /dev/null +++ b/plugins/config-audit/tests/snapshots/v5.0.0/scan-orchestrator.json @@ -0,0 +1,545 @@ +{ + "meta": { + "target": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/config-audit/tests/fixtures/marketplace-medium", + "timestamp": "2026-05-01T14:44:16.877Z", + "version": "2.2.0", + "tool": "config-audit" + }, + "scanners": [ + { + "scanner": "CML", + "status": "ok", + "files_scanned": 1, + "duration_ms": 2, + "findings": [], + "counts": { + "critical": 0, + "high": 0, + "medium": 0, + "low": 0, + "info": 0 + } + }, + { + "scanner": "SET", + "status": "ok", + "files_scanned": 1, + "duration_ms": 1, + "findings": [], + "counts": { + "critical": 0, + "high": 0, + "medium": 0, + "low": 0, + "info": 0 + } + }, + { + "scanner": "HKV", + "status": "ok", + "files_scanned": 1, + "duration_ms": 1, + "findings": [], + "counts": { + "critical": 0, + "high": 0, + "medium": 0, + "low": 0, + "info": 0 + } + }, + { + "scanner": "RUL", + "status": "skipped", + "files_scanned": 0, + "duration_ms": 0, + "findings": [], + "counts": { + "critical": 0, + "high": 0, + "medium": 0, + "low": 0, + "info": 0 + } + }, + { + "scanner": "MCP", + "status": "ok", + "files_scanned": 1, + "duration_ms": 0, + "findings": [], + "counts": { + "critical": 0, + "high": 0, + "medium": 0, + "low": 0, + "info": 0 + } + }, + { + "scanner": "IMP", + "status": "ok", + "files_scanned": 1, + "duration_ms": 0, + "findings": [], + "counts": { + "critical": 0, + "high": 0, + "medium": 0, + "low": 0, + "info": 0 + } + }, + { + "scanner": "CNF", + "status": "ok", + "files_scanned": 2, + "duration_ms": 1, + "findings": [], + "counts": { + "critical": 0, + "high": 0, + "medium": 0, + "low": 0, + "info": 0 + } + }, + { + "scanner": "GAP", + "status": "ok", + "files_scanned": 4, + "duration_ms": 2, + "findings": [ + { + "id": "CA-GAP-001", + "scanner": "GAP", + "severity": "medium", + "title": "No custom skills or commands", + "description": "Feature gap: No custom skills or commands. Create project-specific skills in .claude/skills/ or commands in .claude/commands/ to automate repetitive workflows.", + "file": null, + "line": null, + "evidence": null, + "category": "t1", + "recommendation": "Create project-specific skills in .claude/skills/ or commands in .claude/commands/ to automate repetitive workflows.", + "autoFixable": false + }, + { + "id": "CA-GAP-002", + "scanner": "GAP", + "severity": "low", + "title": "Settings only at one scope", + "description": "Feature gap: Settings only at one scope. Use all 3 settings scopes: ~/.claude/settings.json (user), .claude/settings.json (project), .claude/settings.local.json (local/personal).", + "file": null, + "line": null, + "evidence": null, + "category": "t2", + "recommendation": "Use all 3 settings scopes: ~/.claude/settings.json (user), .claude/settings.json (project), .claude/settings.local.json (local/personal).", + "autoFixable": false + }, + { + "id": "CA-GAP-003", + "scanner": "GAP", + "severity": "low", + "title": "No path-scoped rules", + "description": "Feature gap: No path-scoped rules. Create .claude/rules/*.md with paths: frontmatter to apply rules only to matching files.", + "file": null, + "line": null, + "evidence": null, + "category": "t2", + "recommendation": "Create .claude/rules/*.md with paths: frontmatter to apply rules only to matching files.", + "autoFixable": false + }, + { + "id": "CA-GAP-004", + "scanner": "GAP", + "severity": "low", + "title": "Low hook diversity", + "description": "Feature gap: Low hook diversity. Use hooks across 3+ events (e.g., SessionStart, PreToolUse, Stop) for comprehensive automation.", + "file": null, + "line": null, + "evidence": null, + "category": "t2", + "recommendation": "Use hooks across 3+ events (e.g., SessionStart, PreToolUse, Stop) for comprehensive automation.", + "autoFixable": false + }, + { + "id": "CA-GAP-005", + "scanner": "GAP", + "severity": "low", + "title": "No custom subagents", + "description": "Feature gap: No custom subagents. Create custom agents in .claude/agents/ or ~/.claude/agents/ with specialized tools and model selection.", + "file": null, + "line": null, + "evidence": null, + "category": "t2", + "recommendation": "Create custom agents in .claude/agents/ or ~/.claude/agents/ with specialized tools and model selection.", + "autoFixable": false + }, + { + "id": "CA-GAP-006", + "scanner": "GAP", + "severity": "low", + "title": "No model configuration", + "description": "Feature gap: No model configuration. Set model preferences in settings.json (model, modelOverrides) for cost/quality optimization.", + "file": null, + "line": null, + "evidence": null, + "category": "t2", + "recommendation": "Set model preferences in settings.json (model, modelOverrides) for cost/quality optimization.", + "autoFixable": false + }, + { + "id": "CA-GAP-007", + "scanner": "GAP", + "severity": "info", + "title": "No status line configured", + "description": "Feature gap: No status line configured. Configure statusLine in settings.json to show context window usage, cost, and model info.", + "file": null, + "line": null, + "evidence": null, + "category": "t3", + "recommendation": "Configure statusLine in settings.json to show context window usage, cost, and model info.", + "autoFixable": false + }, + { + "id": "CA-GAP-008", + "scanner": "GAP", + "severity": "info", + "title": "No custom keybindings", + "description": "Feature gap: No custom keybindings. Create ~/.claude/keybindings.json to customize keyboard shortcuts (e.g., bind chat:newline to Shift+Enter).", + "file": null, + "line": null, + "evidence": null, + "category": "t3", + "recommendation": "Create ~/.claude/keybindings.json to customize keyboard shortcuts (e.g., bind chat:newline to Shift+Enter).", + "autoFixable": false + }, + { + "id": "CA-GAP-009", + "scanner": "GAP", + "severity": "info", + "title": "Using default output style", + "description": "Feature gap: Using default output style. Try \"Explanatory\" or \"Learning\" output styles, or create custom styles in .claude/output-styles/.", + "file": null, + "line": null, + "evidence": null, + "category": "t3", + "recommendation": "Try \"Explanatory\" or \"Learning\" output styles, or create custom styles in .claude/output-styles/.", + "autoFixable": false + }, + { + "id": "CA-GAP-010", + "scanner": "GAP", + "severity": "info", + "title": "No worktree workflow", + "description": "Feature gap: No worktree workflow. Use --worktree for parallel feature development. Configure worktree.symlinkDirectories for node_modules.", + "file": null, + "line": null, + "evidence": null, + "category": "t3", + "recommendation": "Use --worktree for parallel feature development. Configure worktree.symlinkDirectories for node_modules.", + "autoFixable": false + }, + { + "id": "CA-GAP-011", + "scanner": "GAP", + "severity": "info", + "title": "No advanced skill frontmatter", + "description": "Feature gap: No advanced skill frontmatter. Use disable-model-invocation, context:fork, or argument-hint in skill frontmatter for better control.", + "file": null, + "line": null, + "evidence": null, + "category": "t3", + "recommendation": "Use disable-model-invocation, context:fork, or argument-hint in skill frontmatter for better control.", + "autoFixable": false + }, + { + "id": "CA-GAP-012", + "scanner": "GAP", + "severity": "info", + "title": "No subagent isolation", + "description": "Feature gap: No subagent isolation. Use isolation: worktree in agent frontmatter for safe parallel development.", + "file": null, + "line": null, + "evidence": null, + "category": "t3", + "recommendation": "Use isolation: worktree in agent frontmatter for safe parallel development.", + "autoFixable": false + }, + { + "id": "CA-GAP-013", + "scanner": "GAP", + "severity": "info", + "title": "No dynamic skill context", + "description": "Feature gap: No dynamic skill context. Use !`command` syntax in skills to inject dynamic context (e.g., !`git branch --show-current`).", + "file": null, + "line": null, + "evidence": null, + "category": "t3", + "recommendation": "Use !`command` syntax in skills to inject dynamic context (e.g., !`git branch --show-current`).", + "autoFixable": false + }, + { + "id": "CA-GAP-014", + "scanner": "GAP", + "severity": "info", + "title": "No autoMode classifier", + "description": "Feature gap: No autoMode classifier. Configure autoMode in user/local settings with environment context and allow/deny rules.", + "file": null, + "line": null, + "evidence": null, + "category": "t3", + "recommendation": "Configure autoMode in user/local settings with environment context and allow/deny rules.", + "autoFixable": false + }, + { + "id": "CA-GAP-015", + "scanner": "GAP", + "severity": "info", + "title": "No custom plugin", + "description": "Feature gap: No custom plugin. Package reusable skills, agents, and hooks as a Claude Code plugin with .claude-plugin/plugin.json.", + "file": null, + "line": null, + "evidence": null, + "category": "t4", + "recommendation": "Package reusable skills, agents, and hooks as a Claude Code plugin with .claude-plugin/plugin.json.", + "autoFixable": false + }, + { + "id": "CA-GAP-016", + "scanner": "GAP", + "severity": "info", + "title": "No managed settings", + "description": "Feature gap: No managed settings. Use managed-settings.json for organization-wide policy enforcement.", + "file": null, + "line": null, + "evidence": null, + "category": "t4", + "recommendation": "Use managed-settings.json for organization-wide policy enforcement.", + "autoFixable": false + }, + { + "id": "CA-GAP-017", + "scanner": "GAP", + "severity": "info", + "title": "No LSP plugins", + "description": "Feature gap: No LSP plugins. Add .lsp.json for real-time code intelligence from language servers.", + "file": null, + "line": null, + "evidence": null, + "category": "t4", + "recommendation": "Add .lsp.json for real-time code intelligence from language servers.", + "autoFixable": false + } + ], + "counts": { + "critical": 0, + "high": 0, + "medium": 1, + "low": 5, + "info": 11 + } + }, + { + "scanner": "TOK", + "status": "ok", + "files_scanned": 2, + "duration_ms": 120, + "findings": [ + { + "id": "CA-TOK-001", + "scanner": "TOK", + "severity": "low", + "title": "High MCP tool-schema budget on server \"memory\"", + "description": "MCP server \"memory (.mcp.json)\" has tool count unknown — could not parse manifest or cached tools/list. Tool schemas load on every turn; an unverified server may be inflating the per-turn payload silently.", + "file": ".mcp.json", + "line": null, + "evidence": "tool_count=unknown; server=\"memory\"; source=\".mcp.json\" — severity reflects estimated tokens/turn based on structural heuristic; not measured against runtime telemetry", + "category": "token-efficiency", + "recommendation": "Install the package locally (so detect-mcp-tool-count can read its manifest), or run the server once and cache its tools/list response under ~/.claude/config-audit/mcp-cache/.json. See knowledge/cache-telemetry-recipe.md.", + "autoFixable": false + } + ], + "counts": { + "critical": 0, + "high": 0, + "medium": 0, + "low": 1, + "info": 0 + }, + "hotspots": [ + { + "source": "mcp:memory (.mcp.json)", + "estimated_tokens": 500, + "rank": 1, + "recommendations": [ + "Review whether this source needs to load on every turn." + ] + }, + { + "source": "mcp:sadhguru-wisdom (plugin:sadhguru-wisdom)", + "estimated_tokens": 500, + "rank": 2, + "recommendations": [ + "Review whether this source needs to load on every turn." + ] + }, + { + "source": "mcp:vegnorm-rag (plugin:vegnormalene)", + "estimated_tokens": 500, + "rank": 3, + "recommendations": [ + "Review whether this source needs to load on every turn." + ] + }, + { + "source": "CLAUDE.md", + "estimated_tokens": 116, + "rank": 4, + "recommendations": [ + "Move volatile top-of-file content to the bottom or extract to an @import-ed file.", + "Split overlong CLAUDE.md into focused @imports (≤200 lines each)." + ], + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/config-audit/tests/fixtures/marketplace-medium/CLAUDE.md" + }, + { + "source": "hooks/hooks.json", + "estimated_tokens": 81, + "rank": 5, + "recommendations": [ + "Deduplicate overlapping entries — each duplicate inflates the per-turn schema payload.", + "Move rarely-used permissions to a project-local override." + ], + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/config-audit/tests/fixtures/marketplace-medium/hooks/hooks.json" + }, + { + "source": ".claude/settings.json", + "estimated_tokens": 59, + "rank": 6, + "recommendations": [ + "Deduplicate overlapping entries — each duplicate inflates the per-turn schema payload.", + "Move rarely-used permissions to a project-local override." + ], + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/config-audit/tests/fixtures/marketplace-medium/.claude/settings.json" + }, + { + "source": ".mcp.json", + "estimated_tokens": 53, + "rank": 7, + "recommendations": [ + "Deduplicate overlapping entries — each duplicate inflates the per-turn schema payload.", + "Move rarely-used permissions to a project-local override." + ], + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/config-audit/tests/fixtures/marketplace-medium/.mcp.json" + } + ], + "total_estimated_tokens": 1809, + "activeConfig": { + "claudeMdEstimatedTokens": 5716, + "mcpServerCount": 3, + "pluginCount": 41, + "skillCount": 65 + } + }, + { + "scanner": "CPS", + "status": "ok", + "files_scanned": 1, + "duration_ms": 0, + "findings": [], + "counts": { + "critical": 0, + "high": 0, + "medium": 0, + "low": 0, + "info": 0 + } + }, + { + "scanner": "DIS", + "status": "ok", + "files_scanned": 1, + "duration_ms": 0, + "findings": [ + { + "id": "CA-DIS-001", + "scanner": "DIS", + "severity": "low", + "title": "Tool listed in both permissions.deny and permissions.allow", + "description": ".claude/settings.json contains 1 tool present in both deny and allow lists. The deny list wins — the allow entries are dead config but still load on every turn and may confuse future readers about intent.", + "file": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/config-audit/tests/fixtures/marketplace-medium/.claude/settings.json", + "line": null, + "evidence": "Read: allow=\"Read(src/**)\" + deny=\"Read(./.env)\"", + "category": "permissions-hygiene", + "recommendation": "Remove the redundant allow entries. If you actually want this tool enabled, remove it from the deny list instead. Settings should express intent clearly.", + "autoFixable": false + } + ], + "counts": { + "critical": 0, + "high": 0, + "medium": 0, + "low": 1, + "info": 0 + } + }, + { + "scanner": "COL", + "status": "ok", + "files_scanned": 65, + "duration_ms": 91, + "findings": [ + { + "id": "CA-COL-001", + "scanner": "COL", + "severity": "low", + "title": "Skill name \"okr-offentlig-sektor\" used by multiple plugins", + "description": "2 plugins (okr, okr) expose a skill named \"okr-offentlig-sektor\". Even when invocation is namespaced via /plugin:skill, shared names create ambiguity in error messages, search results, and the plugin-skills enumeration.", + "file": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/okr/skills/okr-offentlig-sektor/SKILL.md", + "line": null, + "evidence": "name=\"okr-offentlig-sektor\"; plugins=okr,okr", + "category": "plugin-hygiene", + "recommendation": "Coordinate naming across plugins, or rename one to clarify intent. The shared name forces every reader to disambiguate by source.", + "autoFixable": false, + "details": { + "namespaces": [ + { + "source": "plugin:okr", + "name": "okr-offentlig-sektor", + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/okr/skills/okr-offentlig-sektor/SKILL.md" + }, + { + "source": "plugin:okr", + "name": "okr-offentlig-sektor", + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/okr/skills/okr-offentlig-sektor/SKILL.md" + } + ] + } + } + ], + "counts": { + "critical": 0, + "high": 0, + "medium": 0, + "low": 1, + "info": 0 + } + } + ], + "aggregate": { + "total_findings": 20, + "counts": { + "critical": 0, + "high": 0, + "medium": 1, + "low": 8, + "info": 11 + }, + "risk_score": 12, + "risk_band": "Medium", + "verdict": "PASS", + "scanners_ok": 11, + "scanners_error": 0, + "scanners_skipped": 1 + } +} \ No newline at end of file diff --git a/plugins/config-audit/tests/snapshots/v5.0.0/token-hotspots.json b/plugins/config-audit/tests/snapshots/v5.0.0/token-hotspots.json new file mode 100644 index 0000000..fef6640 --- /dev/null +++ b/plugins/config-audit/tests/snapshots/v5.0.0/token-hotspots.json @@ -0,0 +1,95 @@ +{ + "scanner": "TOK", + "status": "ok", + "files_scanned": 2, + "duration_ms": 119, + "total_estimated_tokens": 1809, + "hotspots": [ + { + "source": "mcp:memory (.mcp.json)", + "estimated_tokens": 500, + "rank": 1, + "recommendations": [ + "Review whether this source needs to load on every turn." + ] + }, + { + "source": "mcp:sadhguru-wisdom (plugin:sadhguru-wisdom)", + "estimated_tokens": 500, + "rank": 2, + "recommendations": [ + "Review whether this source needs to load on every turn." + ] + }, + { + "source": "mcp:vegnorm-rag (plugin:vegnormalene)", + "estimated_tokens": 500, + "rank": 3, + "recommendations": [ + "Review whether this source needs to load on every turn." + ] + }, + { + "source": "CLAUDE.md", + "estimated_tokens": 116, + "rank": 4, + "recommendations": [ + "Move volatile top-of-file content to the bottom or extract to an @import-ed file.", + "Split overlong CLAUDE.md into focused @imports (≤200 lines each)." + ], + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/config-audit/tests/fixtures/marketplace-medium/CLAUDE.md" + }, + { + "source": "hooks/hooks.json", + "estimated_tokens": 81, + "rank": 5, + "recommendations": [ + "Deduplicate overlapping entries — each duplicate inflates the per-turn schema payload.", + "Move rarely-used permissions to a project-local override." + ], + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/config-audit/tests/fixtures/marketplace-medium/hooks/hooks.json" + }, + { + "source": ".claude/settings.json", + "estimated_tokens": 59, + "rank": 6, + "recommendations": [ + "Deduplicate overlapping entries — each duplicate inflates the per-turn schema payload.", + "Move rarely-used permissions to a project-local override." + ], + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/config-audit/tests/fixtures/marketplace-medium/.claude/settings.json" + }, + { + "source": ".mcp.json", + "estimated_tokens": 53, + "rank": 7, + "recommendations": [ + "Deduplicate overlapping entries — each duplicate inflates the per-turn schema payload.", + "Move rarely-used permissions to a project-local override." + ], + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/config-audit/tests/fixtures/marketplace-medium/.mcp.json" + } + ], + "findings": [ + { + "id": "CA-TOK-001", + "scanner": "TOK", + "severity": "low", + "title": "High MCP tool-schema budget on server \"memory\"", + "description": "MCP server \"memory (.mcp.json)\" has tool count unknown — could not parse manifest or cached tools/list. Tool schemas load on every turn; an unverified server may be inflating the per-turn payload silently.", + "file": ".mcp.json", + "line": null, + "evidence": "tool_count=unknown; server=\"memory\"; source=\".mcp.json\" — severity reflects estimated tokens/turn based on structural heuristic; not measured against runtime telemetry", + "category": "token-efficiency", + "recommendation": "Install the package locally (so detect-mcp-tool-count can read its manifest), or run the server once and cache its tools/list response under ~/.claude/config-audit/mcp-cache/.json. See knowledge/cache-telemetry-recipe.md.", + "autoFixable": false + } + ], + "counts": { + "critical": 0, + "high": 0, + "medium": 0, + "low": 1, + "info": 0 + } +} \ No newline at end of file diff --git a/plugins/config-audit/tests/snapshots/v5.0.0/whats-active.json b/plugins/config-audit/tests/snapshots/v5.0.0/whats-active.json new file mode 100644 index 0000000..0b48ba7 --- /dev/null +++ b/plugins/config-audit/tests/snapshots/v5.0.0/whats-active.json @@ -0,0 +1,1886 @@ +{ + "meta": { + "tool": "config-audit:whats-active", + "version": "1.0.0", + "generatedAt": "2026-05-01T14:44:38.432Z", + "repoPath": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/config-audit/tests/fixtures/marketplace-medium", + "gitRoot": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace", + "projectKey": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace", + "durationMs": 119 + }, + "claudeMd": { + "files": [ + { + "path": "/Users/ktg/.claude/CLAUDE.md", + "scope": "user", + "bytes": 9523, + "lines": 201, + "parent": null + }, + { + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/CLAUDE.md", + "scope": "project", + "bytes": 2456, + "lines": 52, + "parent": null + }, + { + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/config-audit/CLAUDE.md", + "scope": "project", + "bytes": 10146, + "lines": 175, + "parent": null + }, + { + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/config-audit/tests/fixtures/marketplace-medium/CLAUDE.md", + "scope": "project", + "bytes": 464, + "lines": 25, + "parent": null + }, + { + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/config-audit/tests/fixtures/marketplace-medium/.claude/shared.md", + "scope": "import", + "bytes": 273, + "lines": 14, + "parent": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/config-audit/tests/fixtures/marketplace-medium/CLAUDE.md" + } + ], + "totalBytes": 22862, + "totalLines": 467, + "estimatedTokens": 5716 + }, + "plugins": [ + { + "name": "agent-sdk-dev", + "path": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/agent-sdk-dev", + "version": null, + "commands": 1, + "agents": 2, + "skills": 0, + "hooks": 0, + "rules": 0, + "totalBytes": 18471, + "estimatedTokens": 450 + }, + { + "name": "claude-code-setup", + "path": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/claude-code-setup", + "version": "1.0.0", + "commands": 0, + "agents": 0, + "skills": 1, + "hooks": 0, + "rules": 0, + "totalBytes": 10856, + "estimatedTokens": 2714 + }, + { + "name": "claude-md-management", + "path": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/claude-md-management", + "version": "1.0.0", + "commands": 1, + "agents": 0, + "skills": 1, + "hooks": 0, + "rules": 0, + "totalBytes": 7385, + "estimatedTokens": 1657 + }, + { + "name": "code-modernization", + "path": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/code-modernization", + "version": null, + "commands": 7, + "agents": 5, + "skills": 0, + "hooks": 0, + "rules": 0, + "totalBytes": 31227, + "estimatedTokens": 1800 + }, + { + "name": "code-review", + "path": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/code-review", + "version": null, + "commands": 1, + "agents": 0, + "skills": 0, + "hooks": 0, + "rules": 0, + "totalBytes": 7422, + "estimatedTokens": 150 + }, + { + "name": "code-simplifier", + "path": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/code-simplifier", + "version": "1.0.0", + "commands": 0, + "agents": 1, + "skills": 0, + "hooks": 0, + "rules": 0, + "totalBytes": 3129, + "estimatedTokens": 150 + }, + { + "name": "commit-commands", + "path": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/commit-commands", + "version": null, + "commands": 3, + "agents": 0, + "skills": 0, + "hooks": 0, + "rules": 0, + "totalBytes": 3285, + "estimatedTokens": 450 + }, + { + "name": "example-plugin", + "path": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/example-plugin", + "version": null, + "commands": 1, + "agents": 0, + "skills": 2, + "hooks": 0, + "rules": 0, + "totalBytes": 5198, + "estimatedTokens": 1139 + }, + { + "name": "explanatory-output-style", + "path": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/explanatory-output-style", + "version": "1.0.0", + "commands": 0, + "agents": 0, + "skills": 0, + "hooks": 1, + "rules": 0, + "totalBytes": 323, + "estimatedTokens": 93 + }, + { + "name": "feature-dev", + "path": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/feature-dev", + "version": null, + "commands": 1, + "agents": 3, + "skills": 0, + "hooks": 0, + "rules": 0, + "totalBytes": 12465, + "estimatedTokens": 600 + }, + { + "name": "frontend-design", + "path": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/frontend-design", + "version": null, + "commands": 0, + "agents": 0, + "skills": 1, + "hooks": 0, + "rules": 0, + "totalBytes": 4274, + "estimatedTokens": 1069 + }, + { + "name": "hookify", + "path": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/hookify", + "version": null, + "commands": 4, + "agents": 1, + "skills": 1, + "hooks": 4, + "rules": 0, + "totalBytes": 32242, + "estimatedTokens": 3148 + }, + { + "name": "learning-output-style", + "path": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/learning-output-style", + "version": "1.0.0", + "commands": 0, + "agents": 0, + "skills": 0, + "hooks": 1, + "rules": 0, + "totalBytes": 320, + "estimatedTokens": 92 + }, + { + "name": "math-olympiad", + "path": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/math-olympiad", + "version": null, + "commands": 0, + "agents": 0, + "skills": 1, + "hooks": 0, + "rules": 0, + "totalBytes": 19961, + "estimatedTokens": 4991 + }, + { + "name": "mcp-server-dev", + "path": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/mcp-server-dev", + "version": null, + "commands": 0, + "agents": 0, + "skills": 3, + "hooks": 0, + "rules": 0, + "totalBytes": 39342, + "estimatedTokens": 9836 + }, + { + "name": "playground", + "path": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/playground", + "version": null, + "commands": 0, + "agents": 0, + "skills": 1, + "hooks": 0, + "rules": 0, + "totalBytes": 3824, + "estimatedTokens": 956 + }, + { + "name": "plugin-dev", + "path": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/plugin-dev", + "version": null, + "commands": 1, + "agents": 3, + "skills": 7, + "hooks": 0, + "rules": 0, + "totalBytes": 144037, + "estimatedTokens": 27574 + }, + { + "name": "pr-review-toolkit", + "path": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/pr-review-toolkit", + "version": null, + "commands": 1, + "agents": 6, + "skills": 0, + "hooks": 0, + "rules": 0, + "totalBytes": 36215, + "estimatedTokens": 1050 + }, + { + "name": "ralph-loop", + "path": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/ralph-loop", + "version": "1.0.0", + "commands": 3, + "agents": 0, + "skills": 0, + "hooks": 1, + "rules": 0, + "totalBytes": 5172, + "estimatedTokens": 534 + }, + { + "name": "security-guidance", + "path": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/security-guidance", + "version": null, + "commands": 0, + "agents": 0, + "skills": 0, + "hooks": 1, + "rules": 0, + "totalBytes": 382, + "estimatedTokens": 110 + }, + { + "name": "skill-creator", + "path": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/skill-creator", + "version": null, + "commands": 0, + "agents": 0, + "skills": 1, + "hooks": 0, + "rules": 0, + "totalBytes": 33168, + "estimatedTokens": 8292 + }, + { + "name": "ai-psychosis", + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/ai-psychosis", + "version": "1.0.0", + "commands": 1, + "agents": 0, + "skills": 1, + "hooks": 4, + "rules": 0, + "totalBytes": 11308, + "estimatedTokens": 1017 + }, + { + "name": "config-audit", + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/config-audit", + "version": "5.0.0", + "commands": 18, + "agents": 6, + "skills": 1, + "hooks": 4, + "rules": 4, + "totalBytes": 112496, + "estimatedTokens": 5589 + }, + { + "name": "graceful-handoff", + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/graceful-handoff", + "version": "2.1.0", + "commands": 0, + "agents": 0, + "skills": 1, + "hooks": 2, + "rules": 0, + "totalBytes": 5819, + "estimatedTokens": 1479 + }, + { + "name": "linkedin-thought-leadership", + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/linkedin-thought-leadership", + "version": "1.2.0", + "commands": 27, + "agents": 17, + "skills": 6, + "hooks": 9, + "rules": 0, + "totalBytes": 535796, + "estimatedTokens": 19852 + }, + { + "name": "llm-security", + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/llm-security", + "version": "7.3.1", + "commands": 20, + "agents": 6, + "skills": 0, + "hooks": 9, + "rules": 0, + "totalBytes": 161770, + "estimatedTokens": 4492 + }, + { + "name": "ms-ai-architect", + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/ms-ai-architect", + "version": "1.8.0", + "commands": 24, + "agents": 12, + "skills": 5, + "hooks": 2, + "rules": 0, + "totalBytes": 250571, + "estimatedTokens": 21982 + }, + { + "name": "okr", + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/okr", + "version": "1.3.0", + "commands": 10, + "agents": 7, + "skills": 1, + "hooks": 4, + "rules": 0, + "totalBytes": 89284, + "estimatedTokens": 4775 + }, + { + "name": "ultra-cc-architect", + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/ultra-cc-architect", + "version": "0.1.0", + "commands": 2, + "agents": 8, + "skills": 1, + "hooks": 0, + "rules": 0, + "totalBytes": 87115, + "estimatedTokens": 3676 + }, + { + "name": "ultraplan-local", + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/ultraplan-local", + "version": "3.1.0", + "commands": 4, + "agents": 19, + "skills": 0, + "hooks": 5, + "rules": 0, + "totalBytes": 256642, + "estimatedTokens": 3780 + }, + { + "name": "az-900-skill", + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/az-900-skill", + "version": "1.0.0", + "commands": 0, + "agents": 0, + "skills": 1, + "hooks": 0, + "rules": 0, + "totalBytes": 3457, + "estimatedTokens": 865 + }, + { + "name": "claude-code-essentials", + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/claude-code-essentials", + "version": "1.0.0", + "commands": 0, + "agents": 0, + "skills": 1, + "hooks": 2, + "rules": 0, + "totalBytes": 1929, + "estimatedTokens": 500 + }, + { + "name": "claude-code-to-copilot", + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/claude-code-to-copilot", + "version": "0.2.0", + "commands": 0, + "agents": 0, + "skills": 1, + "hooks": 0, + "rules": 0, + "totalBytes": 9864, + "estimatedTokens": 2466 + }, + { + "name": "content-machine", + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/content-machine", + "version": "0.1.0", + "commands": 5, + "agents": 13, + "skills": 6, + "hooks": 0, + "rules": 0, + "totalBytes": 167944, + "estimatedTokens": 11367 + }, + { + "name": "harness", + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/harness", + "version": "13.0.0", + "commands": 16, + "agents": 10, + "skills": 1, + "hooks": 13, + "rules": 0, + "totalBytes": 222414, + "estimatedTokens": 7032 + }, + { + "name": "kiur", + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/kiur", + "version": "5.5.1", + "commands": 8, + "agents": 7, + "skills": 1, + "hooks": 6, + "rules": 0, + "totalBytes": 124394, + "estimatedTokens": 5050 + }, + { + "name": "newsletter", + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/newsletter", + "version": "0.7.0", + "commands": 12, + "agents": 19, + "skills": 1, + "hooks": 0, + "rules": 0, + "totalBytes": 225106, + "estimatedTokens": 5443 + }, + { + "name": "okr", + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/okr", + "version": "1.3.0", + "commands": 10, + "agents": 7, + "skills": 1, + "hooks": 4, + "rules": 0, + "totalBytes": 89284, + "estimatedTokens": 4775 + }, + { + "name": "ralph-wiggum", + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/ralph-wiggum", + "version": "0.7.0", + "commands": 12, + "agents": 5, + "skills": 4, + "hooks": 8, + "rules": 0, + "totalBytes": 67176, + "estimatedTokens": 5783 + }, + { + "name": "sadhguru-wisdom", + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/sadhguru-wisdom", + "version": "0.1.0", + "commands": 6, + "agents": 1, + "skills": 1, + "hooks": 1, + "rules": 0, + "totalBytes": 12566, + "estimatedTokens": 1919 + }, + { + "name": "vegnormalene", + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/vegnormalene", + "version": "0.1.0", + "commands": 9, + "agents": 2, + "skills": 1, + "hooks": 1, + "rules": 0, + "totalBytes": 16731, + "estimatedTokens": 2301 + } + ], + "skills": [ + { + "name": "agent-browser", + "source": "user", + "pluginName": null, + "path": "/Users/ktg/.claude/skills/agent-browser/SKILL.md", + "bytes": 8796, + "estimatedTokens": 2199 + }, + { + "name": "capability-auditor", + "source": "user", + "pluginName": null, + "path": "/Users/ktg/.claude/skills/capability-auditor/SKILL.md", + "bytes": 20144, + "estimatedTokens": 5036 + }, + { + "name": "claude-code-changelog", + "source": "user", + "pluginName": null, + "path": "/Users/ktg/.claude/skills/claude-code-changelog/SKILL.md", + "bytes": 10787, + "estimatedTokens": 2697 + }, + { + "name": "gpt-prompting-expert", + "source": "user", + "pluginName": null, + "path": "/Users/ktg/.claude/skills/gpt-prompting-expert/SKILL.md", + "bytes": 11801, + "estimatedTokens": 2951 + }, + { + "name": "mcp-builder", + "source": "user", + "pluginName": null, + "path": "/Users/ktg/.claude/skills/mcp-builder/SKILL.md", + "bytes": 9092, + "estimatedTokens": 2273 + }, + { + "name": "persona-creator", + "source": "user", + "pluginName": null, + "path": "/Users/ktg/.claude/skills/persona-creator/SKILL.md", + "bytes": 3722, + "estimatedTokens": 931 + }, + { + "name": "pptx", + "source": "user", + "pluginName": null, + "path": "/Users/ktg/.claude/skills/pptx/SKILL.md", + "bytes": 11592, + "estimatedTokens": 2898 + }, + { + "name": "prepare-release", + "source": "user", + "pluginName": null, + "path": "/Users/ktg/.claude/skills/prepare-release/SKILL.md", + "bytes": 2768, + "estimatedTokens": 692 + }, + { + "name": "repo-init", + "source": "user", + "pluginName": null, + "path": "/Users/ktg/.claude/skills/repo-init/SKILL.md", + "bytes": 5570, + "estimatedTokens": 1393 + }, + { + "name": "story", + "source": "user", + "pluginName": null, + "path": "/Users/ktg/.claude/skills/story/SKILL.md", + "bytes": 16853, + "estimatedTokens": 4214 + }, + { + "name": "youtube-analyse", + "source": "user", + "pluginName": null, + "path": "/Users/ktg/.claude/skills/youtube-analyse/SKILL.md", + "bytes": 3688, + "estimatedTokens": 922 + }, + { + "name": "claude-automation-recommender", + "source": "plugin", + "pluginName": "claude-code-setup", + "path": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/claude-code-setup/skills/claude-automation-recommender/SKILL.md", + "bytes": 10856, + "estimatedTokens": 2714 + }, + { + "name": "claude-md-improver", + "source": "plugin", + "pluginName": "claude-md-management", + "path": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/claude-md-management/skills/claude-md-improver/SKILL.md", + "bytes": 6028, + "estimatedTokens": 1507 + }, + { + "name": "example-command", + "source": "plugin", + "pluginName": "example-plugin", + "path": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/example-plugin/skills/example-command/SKILL.md", + "bytes": 1226, + "estimatedTokens": 307 + }, + { + "name": "example-skill", + "source": "plugin", + "pluginName": "example-plugin", + "path": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/example-plugin/skills/example-skill/SKILL.md", + "bytes": 2725, + "estimatedTokens": 682 + }, + { + "name": "frontend-design", + "source": "plugin", + "pluginName": "frontend-design", + "path": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/frontend-design/skills/frontend-design/SKILL.md", + "bytes": 4274, + "estimatedTokens": 1069 + }, + { + "name": "writing-rules", + "source": "plugin", + "pluginName": "hookify", + "path": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/hookify/skills/writing-rules/SKILL.md", + "bytes": 8423, + "estimatedTokens": 2106 + }, + { + "name": "math-olympiad", + "source": "plugin", + "pluginName": "math-olympiad", + "path": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/math-olympiad/skills/math-olympiad/SKILL.md", + "bytes": 19961, + "estimatedTokens": 4991 + }, + { + "name": "build-mcp-app", + "source": "plugin", + "pluginName": "mcp-server-dev", + "path": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/mcp-server-dev/skills/build-mcp-app/SKILL.md", + "bytes": 19391, + "estimatedTokens": 4848 + }, + { + "name": "build-mcp-server", + "source": "plugin", + "pluginName": "mcp-server-dev", + "path": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/mcp-server-dev/skills/build-mcp-server/SKILL.md", + "bytes": 12084, + "estimatedTokens": 3021 + }, + { + "name": "build-mcpb", + "source": "plugin", + "pluginName": "mcp-server-dev", + "path": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/mcp-server-dev/skills/build-mcpb/SKILL.md", + "bytes": 7867, + "estimatedTokens": 1967 + }, + { + "name": "playground", + "source": "plugin", + "pluginName": "playground", + "path": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/playground/skills/playground/SKILL.md", + "bytes": 3824, + "estimatedTokens": 956 + }, + { + "name": "agent-development", + "source": "plugin", + "pluginName": "plugin-dev", + "path": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/plugin-dev/skills/agent-development/SKILL.md", + "bytes": 11168, + "estimatedTokens": 2792 + }, + { + "name": "command-development", + "source": "plugin", + "pluginName": "plugin-dev", + "path": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/plugin-dev/skills/command-development/SKILL.md", + "bytes": 19233, + "estimatedTokens": 4809 + }, + { + "name": "hook-development", + "source": "plugin", + "pluginName": "plugin-dev", + "path": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/plugin-dev/skills/hook-development/SKILL.md", + "bytes": 16246, + "estimatedTokens": 4062 + }, + { + "name": "mcp-integration", + "source": "plugin", + "pluginName": "plugin-dev", + "path": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/plugin-dev/skills/mcp-integration/SKILL.md", + "bytes": 12519, + "estimatedTokens": 3130 + }, + { + "name": "plugin-settings", + "source": "plugin", + "pluginName": "plugin-dev", + "path": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/plugin-dev/skills/plugin-settings/SKILL.md", + "bytes": 12097, + "estimatedTokens": 3025 + }, + { + "name": "plugin-structure", + "source": "plugin", + "pluginName": "plugin-dev", + "path": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/plugin-dev/skills/plugin-structure/SKILL.md", + "bytes": 13796, + "estimatedTokens": 3449 + }, + { + "name": "skill-development", + "source": "plugin", + "pluginName": "plugin-dev", + "path": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/plugin-dev/skills/skill-development/SKILL.md", + "bytes": 22825, + "estimatedTokens": 5707 + }, + { + "name": "skill-creator", + "source": "plugin", + "pluginName": "skill-creator", + "path": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/skill-creator/skills/skill-creator/SKILL.md", + "bytes": 33168, + "estimatedTokens": 8292 + }, + { + "name": "ai-psychosis", + "source": "plugin", + "pluginName": "ai-psychosis", + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/ai-psychosis/skills/ai-psychosis/SKILL.md", + "bytes": 2361, + "estimatedTokens": 591 + }, + { + "name": "config-hierarchy", + "source": "plugin", + "pluginName": "config-audit", + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/config-audit/skills/config-hierarchy/SKILL.md", + "bytes": 3397, + "estimatedTokens": 850 + }, + { + "name": "graceful-handoff", + "source": "plugin", + "pluginName": "graceful-handoff", + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/graceful-handoff/skills/graceful-handoff/SKILL.md", + "bytes": 5163, + "estimatedTokens": 1291 + }, + { + "name": "linkedin-analytics", + "source": "plugin", + "pluginName": "linkedin-thought-leadership", + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/linkedin-thought-leadership/skills/linkedin-analytics/SKILL.md", + "bytes": 7659, + "estimatedTokens": 1915 + }, + { + "name": "linkedin-content-creation", + "source": "plugin", + "pluginName": "linkedin-thought-leadership", + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/linkedin-thought-leadership/skills/linkedin-content-creation/SKILL.md", + "bytes": 10012, + "estimatedTokens": 2503 + }, + { + "name": "linkedin-networking", + "source": "plugin", + "pluginName": "linkedin-thought-leadership", + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/linkedin-thought-leadership/skills/linkedin-networking/SKILL.md", + "bytes": 6672, + "estimatedTokens": 1668 + }, + { + "name": "linkedin-strategy", + "source": "plugin", + "pluginName": "linkedin-thought-leadership", + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/linkedin-thought-leadership/skills/linkedin-strategy/SKILL.md", + "bytes": 10036, + "estimatedTokens": 2509 + }, + { + "name": "linkedin-thought-leadership", + "source": "plugin", + "pluginName": "linkedin-thought-leadership", + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/linkedin-thought-leadership/skills/linkedin-thought-leadership/SKILL.md", + "bytes": 8906, + "estimatedTokens": 2227 + }, + { + "name": "linkedin-voice", + "source": "plugin", + "pluginName": "linkedin-thought-leadership", + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/linkedin-thought-leadership/skills/linkedin-voice/SKILL.md", + "bytes": 7141, + "estimatedTokens": 1786 + }, + { + "name": "ms-ai-advisor", + "source": "plugin", + "pluginName": "ms-ai-architect", + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/ms-ai-architect/skills/ms-ai-advisor/SKILL.md", + "bytes": 10631, + "estimatedTokens": 2658 + }, + { + "name": "ms-ai-engineering", + "source": "plugin", + "pluginName": "ms-ai-architect", + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/ms-ai-architect/skills/ms-ai-engineering/SKILL.md", + "bytes": 9982, + "estimatedTokens": 2496 + }, + { + "name": "ms-ai-governance", + "source": "plugin", + "pluginName": "ms-ai-architect", + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/ms-ai-architect/skills/ms-ai-governance/SKILL.md", + "bytes": 16291, + "estimatedTokens": 4073 + }, + { + "name": "ms-ai-infrastructure", + "source": "plugin", + "pluginName": "ms-ai-architect", + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/ms-ai-architect/skills/ms-ai-infrastructure/SKILL.md", + "bytes": 16738, + "estimatedTokens": 4185 + }, + { + "name": "ms-ai-security", + "source": "plugin", + "pluginName": "ms-ai-architect", + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/ms-ai-architect/skills/ms-ai-security/SKILL.md", + "bytes": 12093, + "estimatedTokens": 3024 + }, + { + "name": "okr-offentlig-sektor", + "source": "plugin", + "pluginName": "okr", + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/okr/skills/okr-offentlig-sektor/SKILL.md", + "bytes": 7414, + "estimatedTokens": 1854 + }, + { + "name": "cc-architect-catalog", + "source": "plugin", + "pluginName": "ultra-cc-architect", + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/ultra-cc-architect/skills/cc-architect-catalog/SKILL.md", + "bytes": 8702, + "estimatedTokens": 2176 + }, + { + "name": "az-900", + "source": "plugin", + "pluginName": "az-900-skill", + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/az-900-skill/skills/az-900/SKILL.md", + "bytes": 3457, + "estimatedTokens": 865 + }, + { + "name": "essentials", + "source": "plugin", + "pluginName": "claude-code-essentials", + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/claude-code-essentials/skills/essentials/SKILL.md", + "bytes": 1446, + "estimatedTokens": 362 + }, + { + "name": "convert-to-copilot", + "source": "plugin", + "pluginName": "claude-code-to-copilot", + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/claude-code-to-copilot/skills/convert-to-copilot/SKILL.md", + "bytes": 9864, + "estimatedTokens": 2466 + }, + { + "name": "brand-voice", + "source": "plugin", + "pluginName": "content-machine", + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/content-machine/skills/brand-voice/SKILL.md", + "bytes": 6485, + "estimatedTokens": 1622 + }, + { + "name": "image-style-guide", + "source": "plugin", + "pluginName": "content-machine", + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/content-machine/skills/image-style-guide/SKILL.md", + "bytes": 6509, + "estimatedTokens": 1628 + }, + { + "name": "learning-design", + "source": "plugin", + "pluginName": "content-machine", + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/content-machine/skills/learning-design/SKILL.md", + "bytes": 8127, + "estimatedTokens": 2032 + }, + { + "name": "sadhana-privacy", + "source": "plugin", + "pluginName": "content-machine", + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/content-machine/skills/sadhana-privacy/SKILL.md", + "bytes": 3704, + "estimatedTokens": 926 + }, + { + "name": "seo-intelligence", + "source": "plugin", + "pluginName": "content-machine", + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/content-machine/skills/seo-intelligence/SKILL.md", + "bytes": 5389, + "estimatedTokens": 1348 + }, + { + "name": "tier-requirements", + "source": "plugin", + "pluginName": "content-machine", + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/content-machine/skills/tier-requirements/SKILL.md", + "bytes": 4443, + "estimatedTokens": 1111 + }, + { + "name": "harness", + "source": "plugin", + "pluginName": "harness", + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/harness/skills/harness/SKILL.md", + "bytes": 9387, + "estimatedTokens": 2347 + }, + { + "name": "kiur", + "source": "plugin", + "pluginName": "kiur", + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/kiur/skills/kiur/SKILL.md", + "bytes": 9607, + "estimatedTokens": 2402 + }, + { + "name": "newsletter-workflow", + "source": "plugin", + "pluginName": "newsletter", + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/newsletter/skills/newsletter-workflow/SKILL.md", + "bytes": 3172, + "estimatedTokens": 793 + }, + { + "name": "okr-offentlig-sektor", + "source": "plugin", + "pluginName": "okr", + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/okr/skills/okr-offentlig-sektor/SKILL.md", + "bytes": 7414, + "estimatedTokens": 1854 + }, + { + "name": "autonomous-loop", + "source": "plugin", + "pluginName": "ralph-wiggum", + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/ralph-wiggum/skills/autonomous-loop/SKILL.md", + "bytes": 2248, + "estimatedTokens": 562 + }, + { + "name": "e2e-verification", + "source": "plugin", + "pluginName": "ralph-wiggum", + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/ralph-wiggum/skills/e2e-verification/SKILL.md", + "bytes": 2195, + "estimatedTokens": 549 + }, + { + "name": "prd-writing", + "source": "plugin", + "pluginName": "ralph-wiggum", + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/ralph-wiggum/skills/prd-writing/SKILL.md", + "bytes": 2471, + "estimatedTokens": 618 + }, + { + "name": "security-controls", + "source": "plugin", + "pluginName": "ralph-wiggum", + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/ralph-wiggum/skills/security-controls/SKILL.md", + "bytes": 4254, + "estimatedTokens": 1064 + }, + { + "name": "sadhguru-persona", + "source": "plugin", + "pluginName": "sadhguru-wisdom", + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/sadhguru-wisdom/skills/sadhguru-persona/SKILL.md", + "bytes": 3197, + "estimatedTokens": 800 + }, + { + "name": "vegnorm-expert", + "source": "plugin", + "pluginName": "vegnormalene", + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/vegnormalene/skills/vegnorm-expert/SKILL.md", + "bytes": 2328, + "estimatedTokens": 582 + } + ], + "mcpServers": [ + { + "name": "memory", + "source": ".mcp.json", + "command": "npx -y @modelcontextprotocol/server-memory", + "enabled": true, + "disabledBy": null, + "toolCount": null, + "toolCountUnknown": true, + "estimatedTokens": 500 + }, + { + "name": "sadhguru-wisdom", + "source": "plugin:sadhguru-wisdom", + "command": "uv run --directory ${HOME}/.claude/mcp-servers/sadhguru-wisdom python server.py", + "enabled": true, + "disabledBy": null, + "toolCount": null, + "toolCountUnknown": true, + "estimatedTokens": 500 + }, + { + "name": "vegnorm-rag", + "source": "plugin:vegnormalene", + "command": "uv run --directory ${HOME}/.claude/mcp-servers/vegnorm-rag python server.py", + "enabled": true, + "disabledBy": null, + "toolCount": null, + "toolCountUnknown": true, + "estimatedTokens": 500 + } + ], + "hooks": [ + { + "event": "SessionStart", + "matcher": null, + "command": "~/.claude/hooks/session-start.sh", + "source": "user", + "sourcePath": "/Users/ktg/.claude/settings.json", + "estimatedTokens": 15 + }, + { + "event": "PreToolUse", + "matcher": "Bash", + "command": "~/.claude/hooks/pre-bash-gitguard.sh", + "source": "user", + "sourcePath": "/Users/ktg/.claude/settings.json", + "estimatedTokens": 15 + }, + { + "event": "PreToolUse", + "matcher": "Bash", + "command": "~/.claude/hooks/pre-commit-version-check.sh", + "source": "user", + "sourcePath": "/Users/ktg/.claude/settings.json", + "estimatedTokens": 15 + }, + { + "event": "PreToolUse", + "matcher": "Bash", + "command": "~/.claude/hooks/pre-commit-docs-gate.sh", + "source": "user", + "sourcePath": "/Users/ktg/.claude/settings.json", + "estimatedTokens": 15 + }, + { + "event": "PreToolUse", + "matcher": "Edit|Write", + "command": "~/.claude/hooks/pre-edit-secrets.sh", + "source": "user", + "sourcePath": "/Users/ktg/.claude/settings.json", + "estimatedTokens": 15 + }, + { + "event": "PreToolUse", + "matcher": "Edit|Write", + "command": "~/.claude/hooks/pre-write-pathguard.sh", + "source": "user", + "sourcePath": "/Users/ktg/.claude/settings.json", + "estimatedTokens": 15 + }, + { + "event": "PreToolUse", + "matcher": "mcp__*", + "command": "~/.claude/hooks/pre-mcp-guardrail.sh", + "source": "user", + "sourcePath": "/Users/ktg/.claude/settings.json", + "estimatedTokens": 15 + }, + { + "event": "PostToolUse", + "matcher": "*", + "command": "~/.claude/hooks/audit-logger.sh", + "source": "user", + "sourcePath": "/Users/ktg/.claude/settings.json", + "estimatedTokens": 15 + }, + { + "event": "PostToolUse", + "matcher": "Bash", + "command": "~/.claude/hooks/post-commit-push-reminder.sh", + "source": "user", + "sourcePath": "/Users/ktg/.claude/settings.json", + "estimatedTokens": 15 + }, + { + "event": "Stop", + "matcher": null, + "command": "S=$(tmux display-message -p '#{session_name}' 2>/dev/null); T=$$-$RANDOM; echo $T > /tmp/tmux-bell-$S; tmux set-option -q status-style 'bg=#b57614,fg=#282828,bold' 2>/dev/null; printf '\\a' 2>/dev/null; (sleep 15; [ \"$(cat /tmp/tmux-bell-$S 2>/dev/null)\" = \"$T\" ] && tmux set-option -q status-style 'bg=#3c3836,fg=#665c54' 2>/dev/null) & true", + "source": "user", + "sourcePath": "/Users/ktg/.claude/settings.json", + "estimatedTokens": 15 + }, + { + "event": "UserPromptSubmit", + "matcher": null, + "command": "echo submit > /tmp/tmux-bell-$(tmux display-message -p '#{session_name}' 2>/dev/null) 2>/dev/null; tmux set-option -q status-style 'bg=#3c3836,fg=#665c54' 2>/dev/null; true", + "source": "user", + "sourcePath": "/Users/ktg/.claude/settings.json", + "estimatedTokens": 15 + }, + { + "event": "SessionStart", + "matcher": null, + "command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks-handlers/session-start.sh\"", + "source": "plugin:explanatory-output-style", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/explanatory-output-style/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "PreToolUse", + "matcher": null, + "command": "python3 ${CLAUDE_PLUGIN_ROOT}/hooks/pretooluse.py", + "source": "plugin:hookify", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/hookify/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "PostToolUse", + "matcher": null, + "command": "python3 ${CLAUDE_PLUGIN_ROOT}/hooks/posttooluse.py", + "source": "plugin:hookify", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/hookify/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "Stop", + "matcher": null, + "command": "python3 ${CLAUDE_PLUGIN_ROOT}/hooks/stop.py", + "source": "plugin:hookify", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/hookify/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "UserPromptSubmit", + "matcher": null, + "command": "python3 ${CLAUDE_PLUGIN_ROOT}/hooks/userpromptsubmit.py", + "source": "plugin:hookify", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/hookify/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "SessionStart", + "matcher": null, + "command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks-handlers/session-start.sh\"", + "source": "plugin:learning-output-style", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/learning-output-style/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "Stop", + "matcher": null, + "command": "bash \"${CLAUDE_PLUGIN_ROOT}/hooks/stop-hook.sh\"", + "source": "plugin:ralph-loop", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/ralph-loop/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "PreToolUse", + "matcher": "Edit|Write|MultiEdit", + "command": "python3 ${CLAUDE_PLUGIN_ROOT}/hooks/security_reminder_hook.py", + "source": "plugin:security-guidance", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/claude-plugins-official/plugins/security-guidance/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "SessionStart", + "matcher": null, + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/session-start.mjs", + "source": "plugin:ai-psychosis", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/ai-psychosis/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "UserPromptSubmit", + "matcher": null, + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/prompt-analyzer.mjs", + "source": "plugin:ai-psychosis", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/ai-psychosis/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "PostToolUse", + "matcher": null, + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/tool-tracker.mjs", + "source": "plugin:ai-psychosis", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/ai-psychosis/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "SessionEnd", + "matcher": null, + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/session-end.mjs", + "source": "plugin:ai-psychosis", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/ai-psychosis/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "PreToolUse", + "matcher": "Edit|Write", + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/auto-backup-config.mjs", + "source": "plugin:config-audit", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/config-audit/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "PostToolUse", + "matcher": "Edit|Write", + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/post-edit-verify.mjs", + "source": "plugin:config-audit", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/config-audit/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "SessionStart", + "matcher": null, + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/session-start.mjs", + "source": "plugin:config-audit", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/config-audit/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "Stop", + "matcher": null, + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/stop-session-reminder.mjs", + "source": "plugin:config-audit", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/config-audit/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "SessionStart", + "matcher": null, + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/session-start-load-handoff.mjs", + "source": "plugin:graceful-handoff", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/graceful-handoff/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "Stop", + "matcher": null, + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/stop-context-monitor.mjs", + "source": "plugin:graceful-handoff", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/graceful-handoff/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "SessionStart", + "matcher": null, + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/session-start.mjs", + "source": "plugin:linkedin-thought-leadership", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/linkedin-thought-leadership/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "PreToolUse", + "matcher": "Write|Edit", + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/content-gatekeeper.mjs content-quality-gate.md", + "source": "plugin:linkedin-thought-leadership", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/linkedin-thought-leadership/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "PreToolUse", + "matcher": "Write|Edit", + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/content-gatekeeper.mjs voice-guardian.md", + "source": "plugin:linkedin-thought-leadership", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/linkedin-thought-leadership/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "PreToolUse", + "matcher": "Write|Edit", + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/content-gatekeeper.mjs topic-rotation-gate.md", + "source": "plugin:linkedin-thought-leadership", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/linkedin-thought-leadership/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "Stop", + "matcher": null, + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/stop-reminder.mjs", + "source": "plugin:linkedin-thought-leadership", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/linkedin-thought-leadership/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "UserPromptSubmit", + "matcher": null, + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/user-prompt-context.mjs", + "source": "plugin:linkedin-thought-leadership", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/linkedin-thought-leadership/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "PostToolUse", + "matcher": "Write", + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/content-gatekeeper.mjs post-creation-automation.md --no-session-marker", + "source": "plugin:linkedin-thought-leadership", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/linkedin-thought-leadership/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "PreCompact", + "matcher": null, + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/pre-compact.mjs", + "source": "plugin:linkedin-thought-leadership", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/linkedin-thought-leadership/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "Notification", + "matcher": "idle_prompt", + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/posting-reminder.mjs", + "source": "plugin:linkedin-thought-leadership", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/linkedin-thought-leadership/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "UserPromptSubmit", + "matcher": null, + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/pre-prompt-inject-scan.mjs", + "source": "plugin:llm-security", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/llm-security/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "UserPromptSubmit", + "matcher": null, + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/update-check.mjs", + "source": "plugin:llm-security", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/llm-security/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "PreToolUse", + "matcher": "Edit|Write", + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/pre-edit-secrets.mjs", + "source": "plugin:llm-security", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/llm-security/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "PreToolUse", + "matcher": "Bash", + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/pre-bash-destructive.mjs", + "source": "plugin:llm-security", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/llm-security/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "PreToolUse", + "matcher": "Bash", + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/pre-install-supply-chain.mjs", + "source": "plugin:llm-security", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/llm-security/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "PreToolUse", + "matcher": "Write", + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/pre-write-pathguard.mjs", + "source": "plugin:llm-security", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/llm-security/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "PostToolUse", + "matcher": null, + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/post-mcp-verify.mjs", + "source": "plugin:llm-security", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/llm-security/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "PostToolUse", + "matcher": null, + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/post-session-guard.mjs", + "source": "plugin:llm-security", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/llm-security/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "PreCompact", + "matcher": null, + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/pre-compact-scan.mjs", + "source": "plugin:llm-security", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/llm-security/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "SessionStart", + "matcher": null, + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/session-start-context.mjs", + "source": "plugin:ms-ai-architect", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/ms-ai-architect/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "Stop", + "matcher": null, + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/stop-assessment-reminder.mjs", + "source": "plugin:ms-ai-architect", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/ms-ai-architect/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "SessionStart", + "matcher": null, + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/coaching-hook.mjs", + "source": "plugin:okr", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/okr/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "UserPromptSubmit", + "matcher": null, + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/inject-okr-context.mjs", + "source": "plugin:okr", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/okr/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "PreCompact", + "matcher": null, + "command": "", + "source": "plugin:okr", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/okr/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "Stop", + "matcher": null, + "command": "", + "source": "plugin:okr", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/okr/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "PreToolUse", + "matcher": "Bash", + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/pre-bash-executor.mjs", + "source": "plugin:ultraplan-local", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/ultraplan-local/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "PreToolUse", + "matcher": "Write", + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/pre-write-executor.mjs", + "source": "plugin:ultraplan-local", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/ultraplan-local/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "UserPromptSubmit", + "matcher": null, + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/session-title.mjs", + "source": "plugin:ultraplan-local", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/ultraplan-local/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "PostToolUse", + "matcher": "Bash", + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/post-bash-stats.mjs", + "source": "plugin:ultraplan-local", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/ultraplan-local/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "PreCompact", + "matcher": null, + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/pre-compact-flush.mjs", + "source": "plugin:ultraplan-local", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/ultraplan-local/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "PreToolUse", + "matcher": "Bash", + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/pre-bash-firewall.mjs", + "source": "plugin:claude-code-essentials", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/claude-code-essentials/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "PreToolUse", + "matcher": "Edit|Write", + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/pre-edit-secrets.mjs", + "source": "plugin:claude-code-essentials", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/claude-code-essentials/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "SessionStart", + "matcher": null, + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/session-start-orientation.mjs", + "source": "plugin:harness", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/harness/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "SessionStart", + "matcher": null, + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/session-lock-detect.mjs", + "source": "plugin:harness", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/harness/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "Stop", + "matcher": null, + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/session-lock-cleanup.mjs", + "source": "plugin:harness", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/harness/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "Stop", + "matcher": null, + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/harness-event-log.mjs '{\"event\":\"session_end\"}'", + "source": "plugin:harness", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/harness/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "Stop", + "matcher": null, + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/notify.mjs '{\"event\":\"session_digest\"}'", + "source": "plugin:harness", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/harness/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "SessionEnd", + "matcher": null, + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/session-end-archive.mjs", + "source": "plugin:harness", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/harness/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "SubagentStop", + "matcher": null, + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/subagent-stop-validate.mjs", + "source": "plugin:harness", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/harness/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "PreCompact", + "matcher": null, + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/pre-compact-snapshot.mjs", + "source": "plugin:harness", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/harness/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "PreToolUse", + "matcher": "Write|Edit", + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/file-lock-guard.mjs", + "source": "plugin:harness", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/harness/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "PreToolUse", + "matcher": "Write|Edit", + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/feature-list-guard.mjs", + "source": "plugin:harness", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/harness/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "PreToolUse", + "matcher": "EnterPlanMode", + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/enter-plan-mode-intercept.mjs", + "source": "plugin:harness", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/harness/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "PostToolUse", + "matcher": "Write|Edit", + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/dag-validator.mjs", + "source": "plugin:harness", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/harness/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "PostToolUse", + "matcher": "Write|Edit", + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/presence-update.mjs", + "source": "plugin:harness", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/harness/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "SessionStart", + "matcher": null, + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/session-start-reminder.mjs", + "source": "plugin:kiur", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/kiur/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "PreToolUse", + "matcher": "Bash", + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/pre-bash-firewall.mjs", + "source": "plugin:kiur", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/kiur/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "PostToolUse", + "matcher": "Bash", + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/post-bash-failure-detector.mjs", + "source": "plugin:kiur", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/kiur/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "SubagentStop", + "matcher": null, + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/subagent-stop-validate.mjs", + "source": "plugin:kiur", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/kiur/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "PreCompact", + "matcher": null, + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/pre-compact-snapshot.mjs", + "source": "plugin:kiur", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/kiur/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "SessionEnd", + "matcher": null, + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/session-end-archive.mjs", + "source": "plugin:kiur", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/kiur/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "SessionStart", + "matcher": null, + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/coaching-hook.mjs", + "source": "plugin:okr", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/okr/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "UserPromptSubmit", + "matcher": null, + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/inject-okr-context.mjs", + "source": "plugin:okr", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/okr/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "PreCompact", + "matcher": null, + "command": "", + "source": "plugin:okr", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/okr/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "Stop", + "matcher": null, + "command": "", + "source": "plugin:okr", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/okr/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "UserPromptSubmit", + "matcher": null, + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/validate-input.mjs", + "source": "plugin:ralph-wiggum", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/ralph-wiggum/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "PreToolUse", + "matcher": "Bash", + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/validate-output.mjs", + "source": "plugin:ralph-wiggum", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/ralph-wiggum/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "PreToolUse", + "matcher": "Bash", + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/audit-log.mjs", + "source": "plugin:ralph-wiggum", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/ralph-wiggum/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "PreToolUse", + "matcher": "Write|Edit", + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/filter-secrets.mjs", + "source": "plugin:ralph-wiggum", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/ralph-wiggum/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "PreToolUse", + "matcher": "Write|Edit", + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/validate-code.mjs", + "source": "plugin:ralph-wiggum", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/ralph-wiggum/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "PreToolUse", + "matcher": "Write|Edit", + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/audit-log.mjs", + "source": "plugin:ralph-wiggum", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/ralph-wiggum/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "SessionStart", + "matcher": null, + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/check-integrity.mjs", + "source": "plugin:ralph-wiggum", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/ralph-wiggum/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "Stop", + "matcher": null, + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/stop-workflow-reminder.mjs", + "source": "plugin:ralph-wiggum", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/ralph-wiggum/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "SessionStart", + "matcher": null, + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/session-start-stats.mjs", + "source": "plugin:sadhguru-wisdom", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/sadhguru-wisdom/hooks/hooks.json", + "estimatedTokens": 15 + }, + { + "event": "SessionStart", + "matcher": null, + "command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/session-start-stats.mjs", + "source": "plugin:vegnormalene", + "sourcePath": "/Users/ktg/.claude/plugins/marketplaces/ktg-privat/plugins/vegnormalene/hooks/hooks.json", + "estimatedTokens": 15 + } + ], + "settings": { + "cascade": [ + { + "scope": "user", + "path": "/Users/ktg/.claude/settings.json", + "exists": true, + "keyCount": 14 + }, + { + "scope": "project", + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/config-audit/tests/fixtures/marketplace-medium/.claude/settings.json", + "exists": true, + "keyCount": 3 + }, + { + "scope": "local", + "path": "/Users/ktg/.claude/plugins/marketplaces/ktg-plugin-marketplace/plugins/config-audit/tests/fixtures/marketplace-medium/.claude/settings.local.json", + "exists": false, + "keyCount": 0 + } + ] + }, + "totals": { + "plugins": 41, + "skills": 65, + "mcpServers": 3, + "hooks": 93, + "claudeMdFiles": 5, + "estimatedTokens": { + "claudeMd": 5716, + "plugins": 180998, + "skills": 145377, + "mcpServers": 1500, + "hooks": 1395, + "grandTotal": 334986 + } + }, + "suggestDisables": null, + "warnings": [] +} \ No newline at end of file