gentyr 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/agents/antipattern-hunter.md +176 -0
- package/.claude/agents/code-reviewer.md +205 -0
- package/.claude/agents/code-writer.md +154 -0
- package/.claude/agents/deputy-cto.md +309 -0
- package/.claude/agents/feedback-agent.md +101 -0
- package/.claude/agents/investigator.md +136 -0
- package/.claude/agents/product-manager.md +97 -0
- package/.claude/agents/project-manager.md +116 -0
- package/.claude/agents/repo-hygiene-expert.md +626 -0
- package/.claude/agents/secret-manager.md +324 -0
- package/.claude/agents/test-writer.md +354 -0
- package/.claude/commands/configure-personas.md +144 -0
- package/.claude/commands/cto-report.md +36 -0
- package/.claude/commands/demo.md +89 -0
- package/.claude/commands/deputy-cto.md +345 -0
- package/.claude/commands/hotfix.md +31 -0
- package/.claude/commands/overdrive-gentyr.md +167 -0
- package/.claude/commands/product-manager.md +32 -0
- package/.claude/commands/push-migrations.md +86 -0
- package/.claude/commands/push-secrets.md +97 -0
- package/.claude/commands/services.json.example +30 -0
- package/.claude/commands/setup-gentyr.md +396 -0
- package/.claude/commands/show.md +42 -0
- package/.claude/commands/spawn-tasks.md +79 -0
- package/.claude/commands/toggle-automation-gentyr.md +75 -0
- package/.claude/commands/toggle-product-manager.md +19 -0
- package/.claude/commands/triage.md +69 -0
- package/.claude/hooks/README.md +686 -0
- package/.claude/hooks/__tests__/README.md +129 -0
- package/.claude/hooks/agent-tracker.js +434 -0
- package/.claude/hooks/antipattern-hunter-hook.js +401 -0
- package/.claude/hooks/api-key-watcher.js +289 -0
- package/.claude/hooks/block-no-verify.js +301 -0
- package/.claude/hooks/bypass-approval-hook.js +313 -0
- package/.claude/hooks/compliance-checker.js +1309 -0
- package/.claude/hooks/config-reader.js +143 -0
- package/.claude/hooks/credential-file-guard.js +1139 -0
- package/.claude/hooks/credential-health-check.js +168 -0
- package/.claude/hooks/credential-sync-hook.js +79 -0
- package/.claude/hooks/cto-notification-hook.js +656 -0
- package/.claude/hooks/feedback-launcher.js +424 -0
- package/.claude/hooks/feedback-orchestrator.js +367 -0
- package/.claude/hooks/gentyr-splash.js +47 -0
- package/.claude/hooks/gentyr-sync.js +389 -0
- package/.claude/hooks/hourly-automation.js +3340 -0
- package/.claude/hooks/key-sync.js +899 -0
- package/.claude/hooks/lib/approval-utils.js +731 -0
- package/.claude/hooks/lib/feature-branch-helper.js +102 -0
- package/.claude/hooks/lib/worktree-manager.js +330 -0
- package/.claude/hooks/mapping-validator.js +285 -0
- package/.claude/hooks/plan-executor.js +398 -0
- package/.claude/hooks/playwright-cli-guard.js +104 -0
- package/.claude/hooks/playwright-health-check.js +71 -0
- package/.claude/hooks/pre-commit-review.js +725 -0
- package/.claude/hooks/prompts/local-spec-enforcement.md +310 -0
- package/.claude/hooks/prompts/mapping-fix.md +92 -0
- package/.claude/hooks/prompts/mapping-review.md +140 -0
- package/.claude/hooks/prompts/schema-mapper.md +185 -0
- package/.claude/hooks/prompts/spec-enforcement.md +233 -0
- package/.claude/hooks/protected-action-approval-hook.js +336 -0
- package/.claude/hooks/protected-action-gate.js +562 -0
- package/.claude/hooks/protected-actions.json +208 -0
- package/.claude/hooks/protected-actions.json.template +122 -0
- package/.claude/hooks/quota-monitor.js +490 -0
- package/.claude/hooks/reporters/jest-failure-reporter.js +401 -0
- package/.claude/hooks/reporters/playwright-failure-reporter.js +446 -0
- package/.claude/hooks/reporters/vitest-failure-reporter.js +443 -0
- package/.claude/hooks/schema-mapper-hook.js +544 -0
- package/.claude/hooks/secret-leak-detector.js +216 -0
- package/.claude/hooks/session-reviver.js +514 -0
- package/.claude/hooks/slash-command-prefetch.js +1145 -0
- package/.claude/hooks/stale-work-detector.js +205 -0
- package/.claude/hooks/stop-continue-hook.js +414 -0
- package/.claude/hooks/todo-maintenance.js +522 -0
- package/.claude/hooks/todo-processing-prompt.md +75 -0
- package/.claude/hooks/usage-optimizer.js +791 -0
- package/.claude/mcp/README.md +246 -0
- package/.claude/settings.json.template +168 -0
- package/.mcp.json.template +207 -0
- package/CLAUDE.md +340 -0
- package/CLAUDE.md.gentyr-section +89 -0
- package/LICENSE +21 -0
- package/README.md +297 -0
- package/cli/commands/init.js +471 -0
- package/cli/commands/migrate.js +132 -0
- package/cli/commands/protect.js +271 -0
- package/cli/commands/scaffold.js +48 -0
- package/cli/commands/status.js +133 -0
- package/cli/commands/sync.js +101 -0
- package/cli/commands/uninstall.js +207 -0
- package/cli/index.js +111 -0
- package/cli/lib/config-gen.js +214 -0
- package/cli/lib/resolve-framework.js +97 -0
- package/cli/lib/state.js +140 -0
- package/cli/lib/symlinks.js +260 -0
- package/docs/AUTOMATION-SYSTEMS.md +484 -0
- package/docs/BINARY-PATCHING.md +212 -0
- package/docs/CHANGELOG.md +2830 -0
- package/docs/CREDENTIAL-DETECTION.md +151 -0
- package/docs/CTO-DASHBOARD.md +476 -0
- package/docs/DEPLOYMENT-FLOW.md +477 -0
- package/docs/DEVELOPER.md +116 -0
- package/docs/Executive.md +372 -0
- package/docs/SECRET-PATHS.md +77 -0
- package/docs/SETUP-GUIDE.md +419 -0
- package/docs/STACK.md +109 -0
- package/docs/TESTING.md +440 -0
- package/docs/assets/claude-logo.svg +3 -0
- package/docs/sessions/2026-01-24-spec-suite-implementation.md +190 -0
- package/docs/sessions/2026-02-15-feedback-e2e-audit.md +484 -0
- package/docs/sessions/2026-02-20-credential-rotation-experiments.md +340 -0
- package/docs/sessions/TEST-COVERAGE-REPORT-2026-02-20.md +168 -0
- package/docs/shared/EPHEMERAL-STATE-FILES.md +115 -0
- package/docs/shared/PROTECTION-SYSTEM.md +341 -0
- package/husky/post-commit +10 -0
- package/husky/pre-commit +40 -0
- package/husky/pre-push +94 -0
- package/package.json +43 -0
- package/packages/cto-dashboard/package-lock.json +3510 -0
- package/packages/cto-dashboard/package.json +41 -0
- package/packages/cto-dashboard/pnpm-lock.yaml +2168 -0
- package/packages/mcp-servers/dist/__testUtils__/fixtures.d.ts +220 -0
- package/packages/mcp-servers/dist/__testUtils__/fixtures.d.ts.map +1 -0
- package/packages/mcp-servers/dist/__testUtils__/fixtures.js +376 -0
- package/packages/mcp-servers/dist/__testUtils__/fixtures.js.map +1 -0
- package/packages/mcp-servers/dist/__testUtils__/index.d.ts +121 -0
- package/packages/mcp-servers/dist/__testUtils__/index.d.ts.map +1 -0
- package/packages/mcp-servers/dist/__testUtils__/index.js +180 -0
- package/packages/mcp-servers/dist/__testUtils__/index.js.map +1 -0
- package/packages/mcp-servers/dist/__testUtils__/schemas.d.ts +84 -0
- package/packages/mcp-servers/dist/__testUtils__/schemas.d.ts.map +1 -0
- package/packages/mcp-servers/dist/__testUtils__/schemas.js +309 -0
- package/packages/mcp-servers/dist/__testUtils__/schemas.js.map +1 -0
- package/packages/mcp-servers/dist/agent-reports/index.d.ts +7 -0
- package/packages/mcp-servers/dist/agent-reports/index.d.ts.map +1 -0
- package/packages/mcp-servers/dist/agent-reports/index.js +8 -0
- package/packages/mcp-servers/dist/agent-reports/index.js.map +1 -0
- package/packages/mcp-servers/dist/agent-reports/server.d.ts +22 -0
- package/packages/mcp-servers/dist/agent-reports/server.d.ts.map +1 -0
- package/packages/mcp-servers/dist/agent-reports/server.js +535 -0
- package/packages/mcp-servers/dist/agent-reports/server.js.map +1 -0
- package/packages/mcp-servers/dist/agent-reports/types.d.ts +258 -0
- package/packages/mcp-servers/dist/agent-reports/types.d.ts.map +1 -0
- package/packages/mcp-servers/dist/agent-reports/types.js +81 -0
- package/packages/mcp-servers/dist/agent-reports/types.js.map +1 -0
- package/packages/mcp-servers/dist/agent-tracker/index.d.ts +5 -0
- package/packages/mcp-servers/dist/agent-tracker/index.d.ts.map +1 -0
- package/packages/mcp-servers/dist/agent-tracker/index.js +5 -0
- package/packages/mcp-servers/dist/agent-tracker/index.js.map +1 -0
- package/packages/mcp-servers/dist/agent-tracker/server.d.ts +12 -0
- package/packages/mcp-servers/dist/agent-tracker/server.d.ts.map +1 -0
- package/packages/mcp-servers/dist/agent-tracker/server.js +919 -0
- package/packages/mcp-servers/dist/agent-tracker/server.js.map +1 -0
- package/packages/mcp-servers/dist/agent-tracker/types.d.ts +328 -0
- package/packages/mcp-servers/dist/agent-tracker/types.d.ts.map +1 -0
- package/packages/mcp-servers/dist/agent-tracker/types.js +128 -0
- package/packages/mcp-servers/dist/agent-tracker/types.js.map +1 -0
- package/packages/mcp-servers/dist/chrome-bridge/browser-tips.d.ts +27 -0
- package/packages/mcp-servers/dist/chrome-bridge/browser-tips.d.ts.map +1 -0
- package/packages/mcp-servers/dist/chrome-bridge/browser-tips.js +167 -0
- package/packages/mcp-servers/dist/chrome-bridge/browser-tips.js.map +1 -0
- package/packages/mcp-servers/dist/chrome-bridge/index.d.ts +6 -0
- package/packages/mcp-servers/dist/chrome-bridge/index.d.ts.map +1 -0
- package/packages/mcp-servers/dist/chrome-bridge/index.js +6 -0
- package/packages/mcp-servers/dist/chrome-bridge/index.js.map +1 -0
- package/packages/mcp-servers/dist/chrome-bridge/server.d.ts +13 -0
- package/packages/mcp-servers/dist/chrome-bridge/server.d.ts.map +1 -0
- package/packages/mcp-servers/dist/chrome-bridge/server.js +959 -0
- package/packages/mcp-servers/dist/chrome-bridge/server.js.map +1 -0
- package/packages/mcp-servers/dist/chrome-bridge/types.d.ts +41 -0
- package/packages/mcp-servers/dist/chrome-bridge/types.d.ts.map +1 -0
- package/packages/mcp-servers/dist/chrome-bridge/types.js +8 -0
- package/packages/mcp-servers/dist/chrome-bridge/types.js.map +1 -0
- package/packages/mcp-servers/dist/cloudflare/index.d.ts +8 -0
- package/packages/mcp-servers/dist/cloudflare/index.d.ts.map +1 -0
- package/packages/mcp-servers/dist/cloudflare/index.js +8 -0
- package/packages/mcp-servers/dist/cloudflare/index.js.map +1 -0
- package/packages/mcp-servers/dist/cloudflare/server.d.ts +16 -0
- package/packages/mcp-servers/dist/cloudflare/server.d.ts.map +1 -0
- package/packages/mcp-servers/dist/cloudflare/server.js +253 -0
- package/packages/mcp-servers/dist/cloudflare/server.js.map +1 -0
- package/packages/mcp-servers/dist/cloudflare/types.d.ts +141 -0
- package/packages/mcp-servers/dist/cloudflare/types.d.ts.map +1 -0
- package/packages/mcp-servers/dist/cloudflare/types.js +53 -0
- package/packages/mcp-servers/dist/cloudflare/types.js.map +1 -0
- package/packages/mcp-servers/dist/codecov/index.d.ts +7 -0
- package/packages/mcp-servers/dist/codecov/index.d.ts.map +1 -0
- package/packages/mcp-servers/dist/codecov/index.js +7 -0
- package/packages/mcp-servers/dist/codecov/index.js.map +1 -0
- package/packages/mcp-servers/dist/codecov/server.d.ts +21 -0
- package/packages/mcp-servers/dist/codecov/server.d.ts.map +1 -0
- package/packages/mcp-servers/dist/codecov/server.js +376 -0
- package/packages/mcp-servers/dist/codecov/server.js.map +1 -0
- package/packages/mcp-servers/dist/codecov/types.d.ts +269 -0
- package/packages/mcp-servers/dist/codecov/types.d.ts.map +1 -0
- package/packages/mcp-servers/dist/codecov/types.js +128 -0
- package/packages/mcp-servers/dist/codecov/types.js.map +1 -0
- package/packages/mcp-servers/dist/cto-report/index.d.ts +9 -0
- package/packages/mcp-servers/dist/cto-report/index.d.ts.map +1 -0
- package/packages/mcp-servers/dist/cto-report/index.js +9 -0
- package/packages/mcp-servers/dist/cto-report/index.js.map +1 -0
- package/packages/mcp-servers/dist/cto-report/server.d.ts +14 -0
- package/packages/mcp-servers/dist/cto-report/server.d.ts.map +1 -0
- package/packages/mcp-servers/dist/cto-report/server.js +859 -0
- package/packages/mcp-servers/dist/cto-report/server.js.map +1 -0
- package/packages/mcp-servers/dist/cto-report/types.d.ts +213 -0
- package/packages/mcp-servers/dist/cto-report/types.d.ts.map +1 -0
- package/packages/mcp-servers/dist/cto-report/types.js +29 -0
- package/packages/mcp-servers/dist/cto-report/types.js.map +1 -0
- package/packages/mcp-servers/dist/cto-reports/index.d.ts +7 -0
- package/packages/mcp-servers/dist/cto-reports/index.d.ts.map +1 -0
- package/packages/mcp-servers/dist/cto-reports/index.js +8 -0
- package/packages/mcp-servers/dist/cto-reports/index.js.map +1 -0
- package/packages/mcp-servers/dist/cto-reports/server.d.ts +20 -0
- package/packages/mcp-servers/dist/cto-reports/server.d.ts.map +1 -0
- package/packages/mcp-servers/dist/cto-reports/server.js +538 -0
- package/packages/mcp-servers/dist/cto-reports/server.js.map +1 -0
- package/packages/mcp-servers/dist/cto-reports/types.d.ts +236 -0
- package/packages/mcp-servers/dist/cto-reports/types.d.ts.map +1 -0
- package/packages/mcp-servers/dist/cto-reports/types.js +77 -0
- package/packages/mcp-servers/dist/cto-reports/types.js.map +1 -0
- package/packages/mcp-servers/dist/deputy-cto/index.d.ts +7 -0
- package/packages/mcp-servers/dist/deputy-cto/index.d.ts.map +1 -0
- package/packages/mcp-servers/dist/deputy-cto/index.js +8 -0
- package/packages/mcp-servers/dist/deputy-cto/index.js.map +1 -0
- package/packages/mcp-servers/dist/deputy-cto/server.d.ts +23 -0
- package/packages/mcp-servers/dist/deputy-cto/server.d.ts.map +1 -0
- package/packages/mcp-servers/dist/deputy-cto/server.js +1700 -0
- package/packages/mcp-servers/dist/deputy-cto/server.js.map +1 -0
- package/packages/mcp-servers/dist/deputy-cto/types.d.ts +439 -0
- package/packages/mcp-servers/dist/deputy-cto/types.d.ts.map +1 -0
- package/packages/mcp-servers/dist/deputy-cto/types.js +102 -0
- package/packages/mcp-servers/dist/deputy-cto/types.js.map +1 -0
- package/packages/mcp-servers/dist/elastic-logs/index.d.ts +5 -0
- package/packages/mcp-servers/dist/elastic-logs/index.d.ts.map +1 -0
- package/packages/mcp-servers/dist/elastic-logs/index.js +5 -0
- package/packages/mcp-servers/dist/elastic-logs/index.js.map +1 -0
- package/packages/mcp-servers/dist/elastic-logs/server.d.ts +18 -0
- package/packages/mcp-servers/dist/elastic-logs/server.d.ts.map +1 -0
- package/packages/mcp-servers/dist/elastic-logs/server.js +259 -0
- package/packages/mcp-servers/dist/elastic-logs/server.js.map +1 -0
- package/packages/mcp-servers/dist/elastic-logs/types.d.ts +107 -0
- package/packages/mcp-servers/dist/elastic-logs/types.d.ts.map +1 -0
- package/packages/mcp-servers/dist/elastic-logs/types.js +31 -0
- package/packages/mcp-servers/dist/elastic-logs/types.js.map +1 -0
- package/packages/mcp-servers/dist/feedback-explorer/index.d.ts +2 -0
- package/packages/mcp-servers/dist/feedback-explorer/index.d.ts.map +1 -0
- package/packages/mcp-servers/dist/feedback-explorer/index.js +2 -0
- package/packages/mcp-servers/dist/feedback-explorer/index.js.map +1 -0
- package/packages/mcp-servers/dist/feedback-explorer/server.d.ts +21 -0
- package/packages/mcp-servers/dist/feedback-explorer/server.d.ts.map +1 -0
- package/packages/mcp-servers/dist/feedback-explorer/server.js +580 -0
- package/packages/mcp-servers/dist/feedback-explorer/server.js.map +1 -0
- package/packages/mcp-servers/dist/feedback-explorer/types.d.ts +331 -0
- package/packages/mcp-servers/dist/feedback-explorer/types.d.ts.map +1 -0
- package/packages/mcp-servers/dist/feedback-explorer/types.js +40 -0
- package/packages/mcp-servers/dist/feedback-explorer/types.js.map +1 -0
- package/packages/mcp-servers/dist/feedback-reporter/index.d.ts +9 -0
- package/packages/mcp-servers/dist/feedback-reporter/index.d.ts.map +1 -0
- package/packages/mcp-servers/dist/feedback-reporter/index.js +9 -0
- package/packages/mcp-servers/dist/feedback-reporter/index.js.map +1 -0
- package/packages/mcp-servers/dist/feedback-reporter/server.d.ts +36 -0
- package/packages/mcp-servers/dist/feedback-reporter/server.d.ts.map +1 -0
- package/packages/mcp-servers/dist/feedback-reporter/server.js +392 -0
- package/packages/mcp-servers/dist/feedback-reporter/server.js.map +1 -0
- package/packages/mcp-servers/dist/feedback-reporter/types.d.ts +152 -0
- package/packages/mcp-servers/dist/feedback-reporter/types.d.ts.map +1 -0
- package/packages/mcp-servers/dist/feedback-reporter/types.js +67 -0
- package/packages/mcp-servers/dist/feedback-reporter/types.js.map +1 -0
- package/packages/mcp-servers/dist/github/index.d.ts +7 -0
- package/packages/mcp-servers/dist/github/index.d.ts.map +1 -0
- package/packages/mcp-servers/dist/github/index.js +7 -0
- package/packages/mcp-servers/dist/github/index.js.map +1 -0
- package/packages/mcp-servers/dist/github/server.d.ts +15 -0
- package/packages/mcp-servers/dist/github/server.d.ts.map +1 -0
- package/packages/mcp-servers/dist/github/server.js +686 -0
- package/packages/mcp-servers/dist/github/server.js.map +1 -0
- package/packages/mcp-servers/dist/github/types.d.ts +660 -0
- package/packages/mcp-servers/dist/github/types.d.ts.map +1 -0
- package/packages/mcp-servers/dist/github/types.js +209 -0
- package/packages/mcp-servers/dist/github/types.js.map +1 -0
- package/packages/mcp-servers/dist/index.d.ts +30 -0
- package/packages/mcp-servers/dist/index.d.ts.map +1 -0
- package/packages/mcp-servers/dist/index.js +32 -0
- package/packages/mcp-servers/dist/index.js.map +1 -0
- package/packages/mcp-servers/dist/makerkit-docs/index.d.ts +5 -0
- package/packages/mcp-servers/dist/makerkit-docs/index.d.ts.map +1 -0
- package/packages/mcp-servers/dist/makerkit-docs/index.js +5 -0
- package/packages/mcp-servers/dist/makerkit-docs/index.js.map +1 -0
- package/packages/mcp-servers/dist/makerkit-docs/server.d.ts +15 -0
- package/packages/mcp-servers/dist/makerkit-docs/server.d.ts.map +1 -0
- package/packages/mcp-servers/dist/makerkit-docs/server.js +252 -0
- package/packages/mcp-servers/dist/makerkit-docs/server.js.map +1 -0
- package/packages/mcp-servers/dist/makerkit-docs/types.d.ts +74 -0
- package/packages/mcp-servers/dist/makerkit-docs/types.d.ts.map +1 -0
- package/packages/mcp-servers/dist/makerkit-docs/types.js +20 -0
- package/packages/mcp-servers/dist/makerkit-docs/types.js.map +1 -0
- package/packages/mcp-servers/dist/onepassword/index.d.ts +2 -0
- package/packages/mcp-servers/dist/onepassword/index.d.ts.map +1 -0
- package/packages/mcp-servers/dist/onepassword/index.js +2 -0
- package/packages/mcp-servers/dist/onepassword/index.js.map +1 -0
- package/packages/mcp-servers/dist/onepassword/server.d.ts +2 -0
- package/packages/mcp-servers/dist/onepassword/server.d.ts.map +1 -0
- package/packages/mcp-servers/dist/onepassword/server.js +159 -0
- package/packages/mcp-servers/dist/onepassword/server.js.map +1 -0
- package/packages/mcp-servers/dist/onepassword/types.d.ts +55 -0
- package/packages/mcp-servers/dist/onepassword/types.d.ts.map +1 -0
- package/packages/mcp-servers/dist/onepassword/types.js +22 -0
- package/packages/mcp-servers/dist/onepassword/types.js.map +1 -0
- package/packages/mcp-servers/dist/playwright/helpers.d.ts +20 -0
- package/packages/mcp-servers/dist/playwright/helpers.d.ts.map +1 -0
- package/packages/mcp-servers/dist/playwright/helpers.js +31 -0
- package/packages/mcp-servers/dist/playwright/helpers.js.map +1 -0
- package/packages/mcp-servers/dist/playwright/index.d.ts +5 -0
- package/packages/mcp-servers/dist/playwright/index.d.ts.map +1 -0
- package/packages/mcp-servers/dist/playwright/index.js +5 -0
- package/packages/mcp-servers/dist/playwright/index.js.map +1 -0
- package/packages/mcp-servers/dist/playwright/server.d.ts +13 -0
- package/packages/mcp-servers/dist/playwright/server.d.ts.map +1 -0
- package/packages/mcp-servers/dist/playwright/server.js +1201 -0
- package/packages/mcp-servers/dist/playwright/server.js.map +1 -0
- package/packages/mcp-servers/dist/playwright/types.d.ts +216 -0
- package/packages/mcp-servers/dist/playwright/types.d.ts.map +1 -0
- package/packages/mcp-servers/dist/playwright/types.js +172 -0
- package/packages/mcp-servers/dist/playwright/types.js.map +1 -0
- package/packages/mcp-servers/dist/playwright-feedback/browser-manager.d.ts +39 -0
- package/packages/mcp-servers/dist/playwright-feedback/browser-manager.d.ts.map +1 -0
- package/packages/mcp-servers/dist/playwright-feedback/browser-manager.js +71 -0
- package/packages/mcp-servers/dist/playwright-feedback/browser-manager.js.map +1 -0
- package/packages/mcp-servers/dist/playwright-feedback/index.d.ts +5 -0
- package/packages/mcp-servers/dist/playwright-feedback/index.d.ts.map +1 -0
- package/packages/mcp-servers/dist/playwright-feedback/index.js +5 -0
- package/packages/mcp-servers/dist/playwright-feedback/index.js.map +1 -0
- package/packages/mcp-servers/dist/playwright-feedback/server.d.ts +34 -0
- package/packages/mcp-servers/dist/playwright-feedback/server.d.ts.map +1 -0
- package/packages/mcp-servers/dist/playwright-feedback/server.js +538 -0
- package/packages/mcp-servers/dist/playwright-feedback/server.js.map +1 -0
- package/packages/mcp-servers/dist/playwright-feedback/types.d.ts +305 -0
- package/packages/mcp-servers/dist/playwright-feedback/types.d.ts.map +1 -0
- package/packages/mcp-servers/dist/playwright-feedback/types.js +123 -0
- package/packages/mcp-servers/dist/playwright-feedback/types.js.map +1 -0
- package/packages/mcp-servers/dist/product-manager/server.d.ts +17 -0
- package/packages/mcp-servers/dist/product-manager/server.d.ts.map +1 -0
- package/packages/mcp-servers/dist/product-manager/server.js +690 -0
- package/packages/mcp-servers/dist/product-manager/server.js.map +1 -0
- package/packages/mcp-servers/dist/product-manager/types.d.ts +286 -0
- package/packages/mcp-servers/dist/product-manager/types.d.ts.map +1 -0
- package/packages/mcp-servers/dist/product-manager/types.js +99 -0
- package/packages/mcp-servers/dist/product-manager/types.js.map +1 -0
- package/packages/mcp-servers/dist/programmatic-feedback/index.d.ts +7 -0
- package/packages/mcp-servers/dist/programmatic-feedback/index.d.ts.map +1 -0
- package/packages/mcp-servers/dist/programmatic-feedback/index.js +7 -0
- package/packages/mcp-servers/dist/programmatic-feedback/index.js.map +1 -0
- package/packages/mcp-servers/dist/programmatic-feedback/sandbox.d.ts +19 -0
- package/packages/mcp-servers/dist/programmatic-feedback/sandbox.d.ts.map +1 -0
- package/packages/mcp-servers/dist/programmatic-feedback/sandbox.js +174 -0
- package/packages/mcp-servers/dist/programmatic-feedback/sandbox.js.map +1 -0
- package/packages/mcp-servers/dist/programmatic-feedback/server.d.ts +35 -0
- package/packages/mcp-servers/dist/programmatic-feedback/server.d.ts.map +1 -0
- package/packages/mcp-servers/dist/programmatic-feedback/server.js +465 -0
- package/packages/mcp-servers/dist/programmatic-feedback/server.js.map +1 -0
- package/packages/mcp-servers/dist/programmatic-feedback/types.d.ts +127 -0
- package/packages/mcp-servers/dist/programmatic-feedback/types.d.ts.map +1 -0
- package/packages/mcp-servers/dist/programmatic-feedback/types.js +80 -0
- package/packages/mcp-servers/dist/programmatic-feedback/types.js.map +1 -0
- package/packages/mcp-servers/dist/render/index.d.ts +8 -0
- package/packages/mcp-servers/dist/render/index.d.ts.map +1 -0
- package/packages/mcp-servers/dist/render/index.js +8 -0
- package/packages/mcp-servers/dist/render/index.js.map +1 -0
- package/packages/mcp-servers/dist/render/server.d.ts +15 -0
- package/packages/mcp-servers/dist/render/server.d.ts.map +1 -0
- package/packages/mcp-servers/dist/render/server.js +428 -0
- package/packages/mcp-servers/dist/render/server.js.map +1 -0
- package/packages/mcp-servers/dist/render/types.d.ts +273 -0
- package/packages/mcp-servers/dist/render/types.d.ts.map +1 -0
- package/packages/mcp-servers/dist/render/types.js +102 -0
- package/packages/mcp-servers/dist/render/types.js.map +1 -0
- package/packages/mcp-servers/dist/resend/index.d.ts +7 -0
- package/packages/mcp-servers/dist/resend/index.d.ts.map +1 -0
- package/packages/mcp-servers/dist/resend/index.js +7 -0
- package/packages/mcp-servers/dist/resend/index.js.map +1 -0
- package/packages/mcp-servers/dist/resend/server.d.ts +15 -0
- package/packages/mcp-servers/dist/resend/server.d.ts.map +1 -0
- package/packages/mcp-servers/dist/resend/server.js +298 -0
- package/packages/mcp-servers/dist/resend/server.js.map +1 -0
- package/packages/mcp-servers/dist/resend/types.d.ts +222 -0
- package/packages/mcp-servers/dist/resend/types.d.ts.map +1 -0
- package/packages/mcp-servers/dist/resend/types.js +58 -0
- package/packages/mcp-servers/dist/resend/types.js.map +1 -0
- package/packages/mcp-servers/dist/review-queue/index.d.ts +6 -0
- package/packages/mcp-servers/dist/review-queue/index.d.ts.map +1 -0
- package/packages/mcp-servers/dist/review-queue/index.js +6 -0
- package/packages/mcp-servers/dist/review-queue/index.js.map +1 -0
- package/packages/mcp-servers/dist/review-queue/server.d.ts +17 -0
- package/packages/mcp-servers/dist/review-queue/server.d.ts.map +1 -0
- package/packages/mcp-servers/dist/review-queue/server.js +348 -0
- package/packages/mcp-servers/dist/review-queue/server.js.map +1 -0
- package/packages/mcp-servers/dist/review-queue/types.d.ts +162 -0
- package/packages/mcp-servers/dist/review-queue/types.d.ts.map +1 -0
- package/packages/mcp-servers/dist/review-queue/types.js +56 -0
- package/packages/mcp-servers/dist/review-queue/types.js.map +1 -0
- package/packages/mcp-servers/dist/secret-sync/server.d.ts +19 -0
- package/packages/mcp-servers/dist/secret-sync/server.d.ts.map +1 -0
- package/packages/mcp-servers/dist/secret-sync/server.js +1139 -0
- package/packages/mcp-servers/dist/secret-sync/server.js.map +1 -0
- package/packages/mcp-servers/dist/secret-sync/types.d.ts +442 -0
- package/packages/mcp-servers/dist/secret-sync/types.d.ts.map +1 -0
- package/packages/mcp-servers/dist/secret-sync/types.js +113 -0
- package/packages/mcp-servers/dist/secret-sync/types.js.map +1 -0
- package/packages/mcp-servers/dist/session-events/index.d.ts +5 -0
- package/packages/mcp-servers/dist/session-events/index.d.ts.map +1 -0
- package/packages/mcp-servers/dist/session-events/index.js +5 -0
- package/packages/mcp-servers/dist/session-events/index.js.map +1 -0
- package/packages/mcp-servers/dist/session-events/server.d.ts +11 -0
- package/packages/mcp-servers/dist/session-events/server.d.ts.map +1 -0
- package/packages/mcp-servers/dist/session-events/server.js +290 -0
- package/packages/mcp-servers/dist/session-events/server.js.map +1 -0
- package/packages/mcp-servers/dist/session-events/types.d.ts +213 -0
- package/packages/mcp-servers/dist/session-events/types.d.ts.map +1 -0
- package/packages/mcp-servers/dist/session-events/types.js +69 -0
- package/packages/mcp-servers/dist/session-events/types.js.map +1 -0
- package/packages/mcp-servers/dist/session-restart/index.d.ts +9 -0
- package/packages/mcp-servers/dist/session-restart/index.d.ts.map +1 -0
- package/packages/mcp-servers/dist/session-restart/index.js +9 -0
- package/packages/mcp-servers/dist/session-restart/index.js.map +1 -0
- package/packages/mcp-servers/dist/session-restart/server.d.ts +20 -0
- package/packages/mcp-servers/dist/session-restart/server.d.ts.map +1 -0
- package/packages/mcp-servers/dist/session-restart/server.js +411 -0
- package/packages/mcp-servers/dist/session-restart/server.js.map +1 -0
- package/packages/mcp-servers/dist/session-restart/types.d.ts +26 -0
- package/packages/mcp-servers/dist/session-restart/types.d.ts.map +1 -0
- package/packages/mcp-servers/dist/session-restart/types.js +16 -0
- package/packages/mcp-servers/dist/session-restart/types.js.map +1 -0
- package/packages/mcp-servers/dist/setup-helper/index.d.ts +5 -0
- package/packages/mcp-servers/dist/setup-helper/index.d.ts.map +1 -0
- package/packages/mcp-servers/dist/setup-helper/index.js +5 -0
- package/packages/mcp-servers/dist/setup-helper/index.js.map +1 -0
- package/packages/mcp-servers/dist/setup-helper/server.d.ts +14 -0
- package/packages/mcp-servers/dist/setup-helper/server.d.ts.map +1 -0
- package/packages/mcp-servers/dist/setup-helper/server.js +454 -0
- package/packages/mcp-servers/dist/setup-helper/server.js.map +1 -0
- package/packages/mcp-servers/dist/setup-helper/types.d.ts +81 -0
- package/packages/mcp-servers/dist/setup-helper/types.d.ts.map +1 -0
- package/packages/mcp-servers/dist/setup-helper/types.js +41 -0
- package/packages/mcp-servers/dist/setup-helper/types.js.map +1 -0
- package/packages/mcp-servers/dist/shared/audited-server.d.ts +31 -0
- package/packages/mcp-servers/dist/shared/audited-server.d.ts.map +1 -0
- package/packages/mcp-servers/dist/shared/audited-server.js +126 -0
- package/packages/mcp-servers/dist/shared/audited-server.js.map +1 -0
- package/packages/mcp-servers/dist/shared/constants.d.ts +26 -0
- package/packages/mcp-servers/dist/shared/constants.d.ts.map +1 -0
- package/packages/mcp-servers/dist/shared/constants.js +41 -0
- package/packages/mcp-servers/dist/shared/constants.js.map +1 -0
- package/packages/mcp-servers/dist/shared/index.d.ts +6 -0
- package/packages/mcp-servers/dist/shared/index.d.ts.map +1 -0
- package/packages/mcp-servers/dist/shared/index.js +6 -0
- package/packages/mcp-servers/dist/shared/index.js.map +1 -0
- package/packages/mcp-servers/dist/shared/readonly-db.d.ts +11 -0
- package/packages/mcp-servers/dist/shared/readonly-db.d.ts.map +1 -0
- package/packages/mcp-servers/dist/shared/readonly-db.js +47 -0
- package/packages/mcp-servers/dist/shared/readonly-db.js.map +1 -0
- package/packages/mcp-servers/dist/shared/resolve-framework.d.ts +20 -0
- package/packages/mcp-servers/dist/shared/resolve-framework.d.ts.map +1 -0
- package/packages/mcp-servers/dist/shared/resolve-framework.js +65 -0
- package/packages/mcp-servers/dist/shared/resolve-framework.js.map +1 -0
- package/packages/mcp-servers/dist/shared/server.d.ts +86 -0
- package/packages/mcp-servers/dist/shared/server.d.ts.map +1 -0
- package/packages/mcp-servers/dist/shared/server.js +291 -0
- package/packages/mcp-servers/dist/shared/server.js.map +1 -0
- package/packages/mcp-servers/dist/shared/types.d.ts +113 -0
- package/packages/mcp-servers/dist/shared/types.d.ts.map +1 -0
- package/packages/mcp-servers/dist/shared/types.js +36 -0
- package/packages/mcp-servers/dist/shared/types.js.map +1 -0
- package/packages/mcp-servers/dist/show/server.d.ts +12 -0
- package/packages/mcp-servers/dist/show/server.d.ts.map +1 -0
- package/packages/mcp-servers/dist/show/server.js +97 -0
- package/packages/mcp-servers/dist/show/server.js.map +1 -0
- package/packages/mcp-servers/dist/show/types.d.ts +19 -0
- package/packages/mcp-servers/dist/show/types.d.ts.map +1 -0
- package/packages/mcp-servers/dist/show/types.js +32 -0
- package/packages/mcp-servers/dist/show/types.js.map +1 -0
- package/packages/mcp-servers/dist/specs-browser/index.d.ts +5 -0
- package/packages/mcp-servers/dist/specs-browser/index.d.ts.map +1 -0
- package/packages/mcp-servers/dist/specs-browser/index.js +5 -0
- package/packages/mcp-servers/dist/specs-browser/index.js.map +1 -0
- package/packages/mcp-servers/dist/specs-browser/server.d.ts +13 -0
- package/packages/mcp-servers/dist/specs-browser/server.d.ts.map +1 -0
- package/packages/mcp-servers/dist/specs-browser/server.js +692 -0
- package/packages/mcp-servers/dist/specs-browser/server.js.map +1 -0
- package/packages/mcp-servers/dist/specs-browser/types.d.ts +337 -0
- package/packages/mcp-servers/dist/specs-browser/types.d.ts.map +1 -0
- package/packages/mcp-servers/dist/specs-browser/types.js +134 -0
- package/packages/mcp-servers/dist/specs-browser/types.js.map +1 -0
- package/packages/mcp-servers/dist/supabase/index.d.ts +10 -0
- package/packages/mcp-servers/dist/supabase/index.d.ts.map +1 -0
- package/packages/mcp-servers/dist/supabase/index.js +10 -0
- package/packages/mcp-servers/dist/supabase/index.js.map +1 -0
- package/packages/mcp-servers/dist/supabase/server.d.ts +20 -0
- package/packages/mcp-servers/dist/supabase/server.d.ts.map +1 -0
- package/packages/mcp-servers/dist/supabase/server.js +451 -0
- package/packages/mcp-servers/dist/supabase/server.js.map +1 -0
- package/packages/mcp-servers/dist/supabase/types.d.ts +196 -0
- package/packages/mcp-servers/dist/supabase/types.d.ts.map +1 -0
- package/packages/mcp-servers/dist/supabase/types.js +76 -0
- package/packages/mcp-servers/dist/supabase/types.js.map +1 -0
- package/packages/mcp-servers/dist/todo-db/index.d.ts +5 -0
- package/packages/mcp-servers/dist/todo-db/index.d.ts.map +1 -0
- package/packages/mcp-servers/dist/todo-db/index.js +5 -0
- package/packages/mcp-servers/dist/todo-db/index.js.map +1 -0
- package/packages/mcp-servers/dist/todo-db/server.d.ts +13 -0
- package/packages/mcp-servers/dist/todo-db/server.d.ts.map +1 -0
- package/packages/mcp-servers/dist/todo-db/server.js +649 -0
- package/packages/mcp-servers/dist/todo-db/server.js.map +1 -0
- package/packages/mcp-servers/dist/todo-db/types.d.ts +225 -0
- package/packages/mcp-servers/dist/todo-db/types.d.ts.map +1 -0
- package/packages/mcp-servers/dist/todo-db/types.js +69 -0
- package/packages/mcp-servers/dist/todo-db/types.js.map +1 -0
- package/packages/mcp-servers/dist/user-feedback/index.d.ts +7 -0
- package/packages/mcp-servers/dist/user-feedback/index.d.ts.map +1 -0
- package/packages/mcp-servers/dist/user-feedback/index.js +8 -0
- package/packages/mcp-servers/dist/user-feedback/index.js.map +1 -0
- package/packages/mcp-servers/dist/user-feedback/server.d.ts +25 -0
- package/packages/mcp-servers/dist/user-feedback/server.d.ts.map +1 -0
- package/packages/mcp-servers/dist/user-feedback/server.js +914 -0
- package/packages/mcp-servers/dist/user-feedback/server.js.map +1 -0
- package/packages/mcp-servers/dist/user-feedback/types.d.ts +415 -0
- package/packages/mcp-servers/dist/user-feedback/types.d.ts.map +1 -0
- package/packages/mcp-servers/dist/user-feedback/types.js +132 -0
- package/packages/mcp-servers/dist/user-feedback/types.js.map +1 -0
- package/packages/mcp-servers/dist/vercel/index.d.ts +9 -0
- package/packages/mcp-servers/dist/vercel/index.d.ts.map +1 -0
- package/packages/mcp-servers/dist/vercel/index.js +9 -0
- package/packages/mcp-servers/dist/vercel/index.js.map +1 -0
- package/packages/mcp-servers/dist/vercel/server.d.ts +17 -0
- package/packages/mcp-servers/dist/vercel/server.d.ts.map +1 -0
- package/packages/mcp-servers/dist/vercel/server.js +265 -0
- package/packages/mcp-servers/dist/vercel/server.js.map +1 -0
- package/packages/mcp-servers/dist/vercel/types.d.ts +189 -0
- package/packages/mcp-servers/dist/vercel/types.d.ts.map +1 -0
- package/packages/mcp-servers/dist/vercel/types.js +65 -0
- package/packages/mcp-servers/dist/vercel/types.js.map +1 -0
- package/packages/mcp-servers/package-lock.json +3765 -0
- package/packages/mcp-servers/package.json +64 -0
- package/packages/mcp-servers/test/reporters/test-failure-reporter.ts +372 -0
- package/packages/mcp-servers/vitest.config.ts +27 -0
- package/scripts/__tests__/README.md +163 -0
- package/scripts/apply-credential-hardening.sh +271 -0
- package/scripts/credential-providers/manual.js +56 -0
- package/scripts/credential-providers/onepassword.js +85 -0
- package/scripts/credential-providers/provider-interface.js +104 -0
- package/scripts/encrypt-credential.js +337 -0
- package/scripts/feedback-launcher.js +338 -0
- package/scripts/feedback-orchestrator.js +373 -0
- package/scripts/fix-mcp-launcher-issues.sh +97 -0
- package/scripts/force-spawn-tasks.js +651 -0
- package/scripts/force-triage-reports.js +560 -0
- package/scripts/generate-protected-actions-spec.js +142 -0
- package/scripts/generate-proxy-certs.sh +158 -0
- package/scripts/grant-chrome-ext-permissions.sh +242 -0
- package/scripts/mcp-launcher.js +125 -0
- package/scripts/merge-settings.cjs +167 -0
- package/scripts/patch-clawd.py +844 -0
- package/scripts/patch-credential-cache.py +313 -0
- package/scripts/patches/credential-file-guard-patched.mjs +573 -0
- package/scripts/patches/credential-file-guard.js.patched +573 -0
- package/scripts/patches/verify-tokenizer.mjs +132 -0
- package/scripts/protect-framework.sh +478 -0
- package/scripts/readme-chrome.template +12 -0
- package/scripts/reap-completed-agents.js +439 -0
- package/scripts/reinstall.sh +86 -0
- package/scripts/resign-node.sh +185 -0
- package/scripts/rotation-proxy.js +656 -0
- package/scripts/rotation-stress-monitor.mjs +862 -0
- package/scripts/setup-automation-service.sh +648 -0
- package/scripts/setup-check.js +251 -0
- package/scripts/watch-claude-version.js +142 -0
- package/specs/framework/CORE-INVARIANTS.md +161 -0
- package/specs/patterns/AGENT-PATTERNS.md +223 -0
- package/specs/patterns/HOOK-PATTERNS.md +242 -0
- package/specs/patterns/MCP-SERVER-PATTERNS.md +144 -0
- package/templates/config/gitignore.template +14 -0
- package/templates/config/merge-chain-check.yml.template +51 -0
- package/templates/config/package.json.template +18 -0
- package/templates/config/pnpm-workspace.yaml +5 -0
- package/templates/config/services.json.template +18 -0
- package/templates/config/tsconfig.base.json +17 -0
- package/templates/scaffold/integrations/_template/.gitkeep +0 -0
- package/templates/scaffold/packages/logger/package.json +17 -0
- package/templates/scaffold/packages/logger/src/logger.ts +44 -0
- package/templates/scaffold/packages/shared/package.json +17 -0
- package/templates/scaffold/packages/shared/src/errors.ts +43 -0
- package/templates/scaffold/products/_product/apps/backend/package.json +21 -0
- package/templates/scaffold/products/_product/apps/backend/src/index.ts +17 -0
- package/templates/scaffold/products/_product/apps/extension/.gitkeep +0 -0
- package/templates/scaffold/products/_product/apps/web/.gitkeep +0 -0
- package/templates/scaffold/specs/global/.gitkeep +0 -0
- package/templates/scaffold/specs/local/.gitkeep +0 -0
- package/templates/scaffold/specs/reference/.gitkeep +0 -0
- package/version.json +15 -0
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@gentyr/mcp-servers",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "MCP servers for Claude Code integration",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"bin": {
|
|
9
|
+
"mcp-todo-db": "./dist/todo-db/server.js",
|
|
10
|
+
"mcp-specs-browser": "./dist/specs-browser/server.js",
|
|
11
|
+
"mcp-review-queue": "./dist/review-queue/server.js",
|
|
12
|
+
"mcp-agent-tracker": "./dist/agent-tracker/server.js",
|
|
13
|
+
"mcp-session-events": "./dist/session-events/server.js",
|
|
14
|
+
"mcp-agent-reports": "./dist/agent-reports/server.js",
|
|
15
|
+
"mcp-deputy-cto": "./dist/deputy-cto/server.js",
|
|
16
|
+
"mcp-cto-report": "./dist/cto-report/server.js",
|
|
17
|
+
"mcp-cto-reports": "./dist/cto-reports/server.js",
|
|
18
|
+
"mcp-render": "./dist/render/server.js",
|
|
19
|
+
"mcp-vercel": "./dist/vercel/server.js",
|
|
20
|
+
"mcp-github": "./dist/github/server.js",
|
|
21
|
+
"mcp-cloudflare": "./dist/cloudflare/server.js",
|
|
22
|
+
"mcp-supabase": "./dist/supabase/server.js",
|
|
23
|
+
"mcp-resend": "./dist/resend/server.js",
|
|
24
|
+
"mcp-elastic-logs": "./dist/elastic-logs/server.js",
|
|
25
|
+
"mcp-onepassword": "./dist/onepassword/server.js",
|
|
26
|
+
"mcp-codecov": "./dist/codecov/server.js",
|
|
27
|
+
"mcp-secret-sync": "./dist/secret-sync/server.js",
|
|
28
|
+
"mcp-user-feedback": "./dist/user-feedback/server.js",
|
|
29
|
+
"mcp-programmatic-feedback": "./dist/programmatic-feedback/server.js",
|
|
30
|
+
"mcp-playwright-feedback": "./dist/playwright-feedback/server.js",
|
|
31
|
+
"mcp-feedback-reporter": "./dist/feedback-reporter/server.js",
|
|
32
|
+
"mcp-playwright": "./dist/playwright/server.js",
|
|
33
|
+
"mcp-makerkit-docs": "./dist/makerkit-docs/server.js",
|
|
34
|
+
"mcp-setup-helper": "./dist/setup-helper/server.js",
|
|
35
|
+
"mcp-chrome-bridge": "./dist/chrome-bridge/server.js",
|
|
36
|
+
"mcp-product-manager": "./dist/product-manager/server.js"
|
|
37
|
+
},
|
|
38
|
+
"scripts": {
|
|
39
|
+
"build": "tsc",
|
|
40
|
+
"dev": "tsc --watch",
|
|
41
|
+
"test": "vitest run",
|
|
42
|
+
"test:watch": "vitest",
|
|
43
|
+
"test:coverage": "vitest run --coverage",
|
|
44
|
+
"lint": "eslint src --ext .ts",
|
|
45
|
+
"typecheck": "tsc --noEmit"
|
|
46
|
+
},
|
|
47
|
+
"dependencies": {
|
|
48
|
+
"@elastic/elasticsearch": "^8.11.0",
|
|
49
|
+
"@modelcontextprotocol/sdk": "^1.26.0",
|
|
50
|
+
"better-sqlite3": "^12.6.2",
|
|
51
|
+
"playwright": "^1.58.2",
|
|
52
|
+
"tweetnacl": "^1.0.3",
|
|
53
|
+
"zod": "^3.22.4"
|
|
54
|
+
},
|
|
55
|
+
"devDependencies": {
|
|
56
|
+
"@types/better-sqlite3": "^7.6.8",
|
|
57
|
+
"@types/node": "^20.10.0",
|
|
58
|
+
"typescript": "^5.3.0",
|
|
59
|
+
"vitest": "^1.0.0"
|
|
60
|
+
},
|
|
61
|
+
"engines": {
|
|
62
|
+
"node": ">=20"
|
|
63
|
+
}
|
|
64
|
+
}
|
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vitest Custom Reporter - Test Failure Handler
|
|
3
|
+
*
|
|
4
|
+
* This reporter spawns Claude Code to fix test failures automatically.
|
|
5
|
+
* Triggered by Vitest after test runs complete.
|
|
6
|
+
*
|
|
7
|
+
* Features:
|
|
8
|
+
* - Per-suite cooldown (120 minutes) - per individual test suite
|
|
9
|
+
* - Content-based deduplication via SHA-256 hashing (24-hour expiry)
|
|
10
|
+
* - Dynamic suite name extraction (no hardcoding)
|
|
11
|
+
* - Spawns Claude with failure details attached
|
|
12
|
+
* - Fire and forget (doesn't block test completion)
|
|
13
|
+
* - [Task][test-failure-vitest] prefix for CTO report tracking
|
|
14
|
+
* - CLAUDE_SPAWNED_SESSION env var to prevent hook chain reactions
|
|
15
|
+
*
|
|
16
|
+
* @version 1.0.0
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import * as fs from 'fs';
|
|
20
|
+
import * as path from 'path';
|
|
21
|
+
import * as crypto from 'crypto';
|
|
22
|
+
import { spawn } from 'child_process';
|
|
23
|
+
import type { Reporter, File, Task } from 'vitest';
|
|
24
|
+
|
|
25
|
+
// Configuration
|
|
26
|
+
const CONFIG = {
|
|
27
|
+
STATE_FILENAME: 'test-failure-state.json',
|
|
28
|
+
PROMPT_FILENAME: 'test-failure-prompt.md',
|
|
29
|
+
COOLDOWN_MINUTES: 60, // Per-suite cooldown
|
|
30
|
+
MAX_SUITES_PER_SPAWN: 3,
|
|
31
|
+
HASH_EXPIRY_HOURS: 12, // Failure output hashes expire after 12 hours
|
|
32
|
+
HOOKS_DIR: '.claude/hooks',
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
interface TestFailureState {
|
|
36
|
+
suites: Record<string, string>; // suiteName -> ISO timestamp
|
|
37
|
+
failureHashes: Record<string, string>; // hash -> ISO timestamp
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
interface FailedSuite {
|
|
41
|
+
name: string;
|
|
42
|
+
filepath: string;
|
|
43
|
+
failures: Array<{
|
|
44
|
+
name: string;
|
|
45
|
+
error: string;
|
|
46
|
+
}>;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Get the project root directory
|
|
51
|
+
*/
|
|
52
|
+
function getProjectRoot(): string {
|
|
53
|
+
// Navigate from packages/mcp-servers/test/reporters/ to project root
|
|
54
|
+
return process.env['CLAUDE_PROJECT_DIR'] || path.resolve(__dirname, '..', '..', '..', '..');
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Get the path to the state file
|
|
59
|
+
*/
|
|
60
|
+
function getStatePath(): string {
|
|
61
|
+
return path.join(getProjectRoot(), CONFIG.HOOKS_DIR, CONFIG.STATE_FILENAME);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Get the path to the prompt file
|
|
66
|
+
*/
|
|
67
|
+
function getPromptPath(): string {
|
|
68
|
+
return path.join(getProjectRoot(), CONFIG.HOOKS_DIR, CONFIG.PROMPT_FILENAME);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Read the cooldown state from file
|
|
73
|
+
*/
|
|
74
|
+
function readState(): TestFailureState {
|
|
75
|
+
try {
|
|
76
|
+
const content = fs.readFileSync(getStatePath(), 'utf8');
|
|
77
|
+
const state = JSON.parse(content) as Partial<TestFailureState>;
|
|
78
|
+
return {
|
|
79
|
+
suites: state.suites || {},
|
|
80
|
+
failureHashes: state.failureHashes || {},
|
|
81
|
+
};
|
|
82
|
+
} catch {
|
|
83
|
+
return { suites: {}, failureHashes: {} };
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Write the state to file
|
|
89
|
+
*/
|
|
90
|
+
function writeState(state: TestFailureState): void {
|
|
91
|
+
try {
|
|
92
|
+
const statePath = getStatePath();
|
|
93
|
+
const dir = path.dirname(statePath);
|
|
94
|
+
if (!fs.existsSync(dir)) {
|
|
95
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
96
|
+
}
|
|
97
|
+
fs.writeFileSync(statePath, JSON.stringify(state, null, 2), 'utf8');
|
|
98
|
+
} catch (err) {
|
|
99
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
100
|
+
console.error(`Warning: Could not write state: ${message}`);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Check if a suite is in cooldown
|
|
106
|
+
*/
|
|
107
|
+
function isInCooldown(state: TestFailureState, suiteName: string, now: Date = new Date()): boolean {
|
|
108
|
+
const lastSpawn = state.suites[suiteName];
|
|
109
|
+
if (!lastSpawn) {return false;}
|
|
110
|
+
|
|
111
|
+
const lastSpawnDate = new Date(lastSpawn);
|
|
112
|
+
const minutesSince = (now.getTime() - lastSpawnDate.getTime()) / (1000 * 60);
|
|
113
|
+
|
|
114
|
+
return minutesSince < CONFIG.COOLDOWN_MINUTES;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Record spawn time for suites
|
|
119
|
+
*/
|
|
120
|
+
function recordSpawn(suiteNames: string[], now: Date = new Date()): void {
|
|
121
|
+
const state = readState();
|
|
122
|
+
|
|
123
|
+
// Record per-suite timestamps
|
|
124
|
+
for (const suite of suiteNames) {
|
|
125
|
+
state.suites[suite] = now.toISOString();
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Clean up old entries (older than 24 hours)
|
|
129
|
+
const oneDayAgo = new Date(now.getTime() - 24 * 60 * 60 * 1000);
|
|
130
|
+
for (const [suite, timestamp] of Object.entries(state.suites)) {
|
|
131
|
+
if (new Date(timestamp) < oneDayAgo) {
|
|
132
|
+
delete state.suites[suite];
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
writeState(state);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Compute a hash of failure details for deduplication
|
|
141
|
+
*/
|
|
142
|
+
function computeFailureHash(failureDetails: string): string {
|
|
143
|
+
return crypto.createHash('sha256').update(failureDetails).digest('hex').slice(0, 16);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Check if a failure hash has been seen recently (within expiry period)
|
|
148
|
+
*/
|
|
149
|
+
function isHashSeen(state: TestFailureState, hash: string, now: Date = new Date()): boolean {
|
|
150
|
+
const timestamp = state.failureHashes[hash];
|
|
151
|
+
if (!timestamp) {return false;}
|
|
152
|
+
|
|
153
|
+
const hashDate = new Date(timestamp);
|
|
154
|
+
const hoursSince = (now.getTime() - hashDate.getTime()) / (1000 * 60 * 60);
|
|
155
|
+
|
|
156
|
+
return hoursSince < CONFIG.HASH_EXPIRY_HOURS;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Record a failure hash and clean up expired hashes
|
|
161
|
+
*/
|
|
162
|
+
function recordFailureHash(hash: string, now: Date = new Date()): void {
|
|
163
|
+
const state = readState();
|
|
164
|
+
|
|
165
|
+
// Record the new hash
|
|
166
|
+
state.failureHashes[hash] = now.toISOString();
|
|
167
|
+
|
|
168
|
+
// Clean up expired hashes (older than 24 hours)
|
|
169
|
+
const expiryTime = new Date(now.getTime() - CONFIG.HASH_EXPIRY_HOURS * 60 * 60 * 1000);
|
|
170
|
+
for (const [h, timestamp] of Object.entries(state.failureHashes)) {
|
|
171
|
+
if (new Date(timestamp) < expiryTime) {
|
|
172
|
+
delete state.failureHashes[h];
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
writeState(state);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Read the prompt template from file
|
|
181
|
+
*/
|
|
182
|
+
function readPrompt(): string | null {
|
|
183
|
+
try {
|
|
184
|
+
return fs.readFileSync(getPromptPath(), 'utf8').trim();
|
|
185
|
+
} catch (err) {
|
|
186
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
187
|
+
console.error(`Warning: Could not read prompt file: ${message}`);
|
|
188
|
+
return null;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Format failure details from Vitest test results
|
|
194
|
+
*/
|
|
195
|
+
function formatFailureDetails(failedSuites: FailedSuite[]): string {
|
|
196
|
+
const details: string[] = [];
|
|
197
|
+
|
|
198
|
+
for (const suite of failedSuites) {
|
|
199
|
+
details.push(`\n=== ${suite.filepath} ===`);
|
|
200
|
+
|
|
201
|
+
for (const failure of suite.failures) {
|
|
202
|
+
details.push(`\n● ${failure.name}`);
|
|
203
|
+
// Truncate very long messages
|
|
204
|
+
const truncated =
|
|
205
|
+
failure.error.length > 1000 ? `${failure.error.slice(0, 1000) }\n... (truncated)` : failure.error;
|
|
206
|
+
details.push(truncated);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
return details.join('\n');
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Extract failed tests from a Vitest task tree
|
|
215
|
+
*/
|
|
216
|
+
function extractFailures(tasks: Task[], ancestorNames: string[] = []): Array<{ name: string; error: string }> {
|
|
217
|
+
const failures: Array<{ name: string; error: string }> = [];
|
|
218
|
+
|
|
219
|
+
for (const task of tasks) {
|
|
220
|
+
const fullName = [...ancestorNames, task.name].join(' › ');
|
|
221
|
+
|
|
222
|
+
if (task.type === 'test' && task.result?.state === 'fail') {
|
|
223
|
+
const errorMessage = task.result.errors?.map((e) => e.message || String(e)).join('\n') || 'Unknown error';
|
|
224
|
+
failures.push({ name: fullName, error: errorMessage });
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// Recursively check nested tasks (describe blocks)
|
|
228
|
+
if ('tasks' in task && Array.isArray(task.tasks)) {
|
|
229
|
+
failures.push(...extractFailures(task.tasks, [...ancestorNames, task.name]));
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
return failures;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Spawn Claude to fix test failures
|
|
238
|
+
*/
|
|
239
|
+
function spawnClaude(suiteNames: string[], failureDetails: string): boolean {
|
|
240
|
+
const promptTemplate = readPrompt();
|
|
241
|
+
|
|
242
|
+
if (!promptTemplate) {
|
|
243
|
+
console.error('Warning: No prompt file found, skipping Claude spawn');
|
|
244
|
+
return false;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
const projectRoot = getProjectRoot();
|
|
248
|
+
const suitesFormatted = suiteNames.slice(0, CONFIG.MAX_SUITES_PER_SPAWN).join('\n- ');
|
|
249
|
+
|
|
250
|
+
// Add [Task][test-failure-vitest] prefix for CTO report tracking
|
|
251
|
+
const prompt = `[Task][test-failure-vitest] ${promptTemplate}
|
|
252
|
+
|
|
253
|
+
FAILING TEST SUITES (processing up to ${CONFIG.MAX_SUITES_PER_SPAWN}):
|
|
254
|
+
- ${suitesFormatted}
|
|
255
|
+
|
|
256
|
+
FAILURE OUTPUT:
|
|
257
|
+
\`\`\`
|
|
258
|
+
${failureDetails.slice(0, 8000)}
|
|
259
|
+
\`\`\``;
|
|
260
|
+
|
|
261
|
+
try {
|
|
262
|
+
// Try to register spawn with agent tracker (fire-and-forget, don't fail if unavailable)
|
|
263
|
+
try {
|
|
264
|
+
// Dynamic import to avoid hard dependency
|
|
265
|
+
const agentTrackerPath = path.join(projectRoot, '.claude/hooks/agent-tracker.js');
|
|
266
|
+
if (fs.existsSync(agentTrackerPath)) {
|
|
267
|
+
// We can't use dynamic import in this context, so we'll skip registration
|
|
268
|
+
// The agent will still be tracked by the session itself
|
|
269
|
+
}
|
|
270
|
+
} catch {
|
|
271
|
+
// Agent tracker not available, continue without registration
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
const claude = spawn(
|
|
275
|
+
'claude',
|
|
276
|
+
['--dangerously-skip-permissions', '-p', prompt],
|
|
277
|
+
{
|
|
278
|
+
detached: true,
|
|
279
|
+
stdio: 'ignore',
|
|
280
|
+
cwd: projectRoot,
|
|
281
|
+
env: {
|
|
282
|
+
...process.env,
|
|
283
|
+
CLAUDE_PROJECT_DIR: projectRoot,
|
|
284
|
+
CLAUDE_SPAWNED_SESSION: 'true', // Prevent chain reaction from hooks
|
|
285
|
+
},
|
|
286
|
+
}
|
|
287
|
+
);
|
|
288
|
+
|
|
289
|
+
claude.unref();
|
|
290
|
+
return true;
|
|
291
|
+
} catch (err) {
|
|
292
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
293
|
+
console.error(`Warning: Failed to spawn Claude: ${message}`);
|
|
294
|
+
return false;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* Vitest Custom Reporter Class
|
|
300
|
+
*/
|
|
301
|
+
export default class TestFailureReporter implements Reporter {
|
|
302
|
+
onFinished(files?: File[]): void {
|
|
303
|
+
if (!files || files.length === 0) {
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// Extract failed suites
|
|
308
|
+
const failedSuites: FailedSuite[] = [];
|
|
309
|
+
|
|
310
|
+
for (const file of files) {
|
|
311
|
+
const failures = extractFailures(file.tasks);
|
|
312
|
+
|
|
313
|
+
if (failures.length > 0) {
|
|
314
|
+
failedSuites.push({
|
|
315
|
+
name: path.basename(file.filepath),
|
|
316
|
+
filepath: file.filepath,
|
|
317
|
+
failures,
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
if (failedSuites.length === 0) {
|
|
323
|
+
return; // No failures, nothing to do
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
// Get suite names
|
|
327
|
+
const suiteNames = failedSuites.map((s) => s.name);
|
|
328
|
+
|
|
329
|
+
// Check cooldowns
|
|
330
|
+
const state = readState();
|
|
331
|
+
const now = new Date();
|
|
332
|
+
|
|
333
|
+
// Check per-suite cooldowns
|
|
334
|
+
const suitesToProcess = suiteNames.filter((suite) => !isInCooldown(state, suite, now));
|
|
335
|
+
|
|
336
|
+
if (suitesToProcess.length === 0) {
|
|
337
|
+
console.warn('\n[TestFailureReporter] All failing suites are in cooldown, skipping spawn');
|
|
338
|
+
return;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
// Limit to max suites per spawn
|
|
342
|
+
const suitesToSpawn = suitesToProcess.slice(0, CONFIG.MAX_SUITES_PER_SPAWN);
|
|
343
|
+
|
|
344
|
+
// Get the failed suites that match our spawn list
|
|
345
|
+
const failedSuitesToReport = failedSuites.filter((s) => suitesToSpawn.includes(s.name));
|
|
346
|
+
|
|
347
|
+
// Format failure details
|
|
348
|
+
const failureDetails = formatFailureDetails(failedSuitesToReport);
|
|
349
|
+
|
|
350
|
+
// Check if this exact failure output has been seen recently (deduplication)
|
|
351
|
+
const failureHash = computeFailureHash(failureDetails);
|
|
352
|
+
if (isHashSeen(state, failureHash, now)) {
|
|
353
|
+
console.warn(`\n[TestFailureReporter] Duplicate failure output detected (hash: ${failureHash}), skipping spawn`);
|
|
354
|
+
return;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
// Spawn Claude
|
|
358
|
+
const spawned = spawnClaude(suitesToSpawn, failureDetails);
|
|
359
|
+
|
|
360
|
+
if (spawned) {
|
|
361
|
+
recordSpawn(suitesToSpawn, now);
|
|
362
|
+
recordFailureHash(failureHash, now);
|
|
363
|
+
// Use console.warn since console.log is not allowed by lint rules
|
|
364
|
+
console.warn(
|
|
365
|
+
`\n[TestFailureReporter] Spawned Claude to fix ${suitesToSpawn.length} failing test suite(s) (hash: ${failureHash}):`
|
|
366
|
+
);
|
|
367
|
+
for (const suite of suitesToSpawn) {
|
|
368
|
+
console.warn(` - ${suite}`);
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { defineConfig } from 'vitest/config';
|
|
2
|
+
|
|
3
|
+
export default defineConfig({
|
|
4
|
+
test: {
|
|
5
|
+
globals: true,
|
|
6
|
+
environment: 'node',
|
|
7
|
+
coverage: {
|
|
8
|
+
provider: 'v8',
|
|
9
|
+
reporter: ['text', 'json', 'html'],
|
|
10
|
+
exclude: [
|
|
11
|
+
'node_modules/**',
|
|
12
|
+
'dist/**',
|
|
13
|
+
'**/*.test.ts',
|
|
14
|
+
'**/*.spec.ts',
|
|
15
|
+
'**/types.ts',
|
|
16
|
+
'**/index.ts',
|
|
17
|
+
],
|
|
18
|
+
},
|
|
19
|
+
// Increase timeout for database operations
|
|
20
|
+
testTimeout: 10000,
|
|
21
|
+
// Custom reporters - TestFailureReporter spawns Claude to fix failures
|
|
22
|
+
reporters: [
|
|
23
|
+
'default',
|
|
24
|
+
'./test/reporters/test-failure-reporter.ts',
|
|
25
|
+
],
|
|
26
|
+
},
|
|
27
|
+
});
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
# Scripts Tests
|
|
2
|
+
|
|
3
|
+
This directory contains tests for standalone scripts in the `scripts/` directory.
|
|
4
|
+
|
|
5
|
+
## Running Tests
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# Run all script tests
|
|
9
|
+
node --test scripts/__tests__/*.test.js
|
|
10
|
+
|
|
11
|
+
# Run specific test file
|
|
12
|
+
node --test scripts/__tests__/setup-check.test.js
|
|
13
|
+
|
|
14
|
+
# Run with detailed output
|
|
15
|
+
node --test --test-reporter=spec scripts/__tests__/*.test.js
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Test Files
|
|
19
|
+
|
|
20
|
+
### `setup-check.test.js`
|
|
21
|
+
Tests for the `setup-check.js` credential evaluation script.
|
|
22
|
+
|
|
23
|
+
**What it tests:**
|
|
24
|
+
- Code structure validation (ES module, required functions, CREDENTIALS registry)
|
|
25
|
+
- JSON output schema compliance
|
|
26
|
+
- Graceful degradation (missing GENTYR, missing op CLI, missing vault-mappings.json)
|
|
27
|
+
- GITHUB_TOKEN/GITHUB_PAT deduplication (caching op:// path checks)
|
|
28
|
+
- Summary calculation logic
|
|
29
|
+
- Edge cases (environment variables, corrupted files)
|
|
30
|
+
|
|
31
|
+
**Test approach:**
|
|
32
|
+
- **Structure tests**: Regex matching on source code to validate constants and functions exist
|
|
33
|
+
- **Behavior tests**: Execute script with mocked project directories, validate JSON output
|
|
34
|
+
- **Graceful degradation**: Test all failure modes (missing dependencies, missing files, corrupted data)
|
|
35
|
+
|
|
36
|
+
## Test Framework
|
|
37
|
+
|
|
38
|
+
Uses Node's built-in test runner (`node:test`) rather than Jest or Vitest, because:
|
|
39
|
+
- No external dependencies required
|
|
40
|
+
- Perfect for standalone script testing
|
|
41
|
+
- Native ES modules support
|
|
42
|
+
- Built-in assertion library
|
|
43
|
+
- Matches the pattern used in `.claude/hooks/__tests__/`
|
|
44
|
+
|
|
45
|
+
## Testing Philosophy
|
|
46
|
+
|
|
47
|
+
### Structure Validation
|
|
48
|
+
When behavior is hard to test in isolation (e.g., requires live 1Password CLI), we validate the code structure:
|
|
49
|
+
- Use regex to match expected patterns in source code
|
|
50
|
+
- Verify constants, functions, and exports exist
|
|
51
|
+
- Validate documentation and JSDoc
|
|
52
|
+
|
|
53
|
+
### Behavior Validation
|
|
54
|
+
When behavior can be tested without live dependencies:
|
|
55
|
+
- Create temporary project directories with controlled states
|
|
56
|
+
- Execute the script and parse JSON output
|
|
57
|
+
- Validate output schema and calculations
|
|
58
|
+
- Test all code paths (missing files, corrupted data, etc.)
|
|
59
|
+
|
|
60
|
+
### Graceful Degradation
|
|
61
|
+
All failure modes should be tested:
|
|
62
|
+
- Missing GENTYR installation
|
|
63
|
+
- Missing 1Password CLI
|
|
64
|
+
- 1Password not authenticated
|
|
65
|
+
- Missing vault-mappings.json
|
|
66
|
+
- Corrupted vault-mappings.json
|
|
67
|
+
- Partial credential configuration
|
|
68
|
+
|
|
69
|
+
## Why Not Mock `execFileSync` for op CLI?
|
|
70
|
+
|
|
71
|
+
**Decision: We do NOT mock the `op` CLI in these tests.**
|
|
72
|
+
|
|
73
|
+
**Rationale:**
|
|
74
|
+
1. **Real-world testing**: The script already has graceful degradation for missing op CLI
|
|
75
|
+
2. **Complexity**: Mocking `execFileSync` requires module-level mocking (complex in ES modules)
|
|
76
|
+
3. **Coverage**: We get sufficient coverage by testing:
|
|
77
|
+
- `opCliAvailable: false` (op CLI not in PATH)
|
|
78
|
+
- `opAuthenticated: false` (op CLI available but not authenticated)
|
|
79
|
+
- Real `op` CLI when available (opportunistic)
|
|
80
|
+
|
|
81
|
+
**What we DO test:**
|
|
82
|
+
- Code structure (functions exist, constants defined)
|
|
83
|
+
- JSON output schema (all required fields present)
|
|
84
|
+
- Graceful degradation (missing dependencies, corrupted files)
|
|
85
|
+
- Summary calculations (counts, booleans)
|
|
86
|
+
|
|
87
|
+
**What we DON'T test:**
|
|
88
|
+
- Actual `op read` calls to 1Password (would require mocking or live credentials)
|
|
89
|
+
- Exact `existsInOp` values (depends on live 1Password state)
|
|
90
|
+
|
|
91
|
+
This approach gives us:
|
|
92
|
+
- ✅ Fast tests (no mocking overhead)
|
|
93
|
+
- ✅ High confidence in graceful degradation
|
|
94
|
+
- ✅ Schema validation
|
|
95
|
+
- ✅ Real-world behavior (when op CLI available)
|
|
96
|
+
|
|
97
|
+
## Test Coverage
|
|
98
|
+
|
|
99
|
+
### Code Structure (100%)
|
|
100
|
+
- [x] ES module imports
|
|
101
|
+
- [x] Shebang for direct execution
|
|
102
|
+
- [x] CREDENTIALS registry with all required credentials
|
|
103
|
+
- [x] All required functions defined
|
|
104
|
+
- [x] main() called at end of script
|
|
105
|
+
|
|
106
|
+
### Function Behavior (95%)
|
|
107
|
+
- [x] checkGentyrInstalled() - directory/symlink detection
|
|
108
|
+
- [x] readVaultMappings() - JSON parsing, graceful errors
|
|
109
|
+
- [x] main() - JSON output schema
|
|
110
|
+
- [ ] checkOpCli() - **Not fully tested** (would require mocking)
|
|
111
|
+
- [ ] checkOpSecret() - **Not fully tested** (would require mocking)
|
|
112
|
+
|
|
113
|
+
### Graceful Degradation (100%)
|
|
114
|
+
- [x] Missing GENTYR installation
|
|
115
|
+
- [x] Missing vault-mappings.json
|
|
116
|
+
- [x] Corrupted vault-mappings.json
|
|
117
|
+
- [x] Partial credential configuration
|
|
118
|
+
- [x] op CLI not in PATH
|
|
119
|
+
- [x] Environment variable handling
|
|
120
|
+
|
|
121
|
+
### JSON Schema (100%)
|
|
122
|
+
- [x] All top-level fields present
|
|
123
|
+
- [x] credentials object structure
|
|
124
|
+
- [x] summary object structure
|
|
125
|
+
- [x] Credential metadata fields
|
|
126
|
+
- [x] Summary calculation accuracy
|
|
127
|
+
|
|
128
|
+
### Edge Cases (100%)
|
|
129
|
+
- [x] GITHUB_TOKEN/GITHUB_PAT deduplication
|
|
130
|
+
- [x] Identifier credentials (null opPath)
|
|
131
|
+
- [x] CLAUDE_PROJECT_DIR environment variable
|
|
132
|
+
- [x] Fallback to process.cwd()
|
|
133
|
+
|
|
134
|
+
## Maintenance Notes
|
|
135
|
+
|
|
136
|
+
### When to Update Tests
|
|
137
|
+
|
|
138
|
+
**Add tests when:**
|
|
139
|
+
- New credentials added to CREDENTIALS registry
|
|
140
|
+
- New top-level fields added to JSON output
|
|
141
|
+
- New summary calculations added
|
|
142
|
+
- New graceful degradation behavior added
|
|
143
|
+
|
|
144
|
+
**Update tests when:**
|
|
145
|
+
- CREDENTIALS registry structure changes
|
|
146
|
+
- JSON output schema changes
|
|
147
|
+
- Summary calculation logic changes
|
|
148
|
+
|
|
149
|
+
### Test Isolation
|
|
150
|
+
|
|
151
|
+
All tests use temporary directories created with `createTestProject()`:
|
|
152
|
+
- Each test creates a fresh temporary project directory
|
|
153
|
+
- Tests clean up after themselves (in `finally` blocks)
|
|
154
|
+
- No tests depend on actual GENTYR installation or 1Password state
|
|
155
|
+
|
|
156
|
+
### Performance
|
|
157
|
+
|
|
158
|
+
Tests are fast because:
|
|
159
|
+
- No network calls (1Password CLI only used when available)
|
|
160
|
+
- No mocking overhead (tests actual graceful degradation)
|
|
161
|
+
- Temporary directories cleaned up immediately
|
|
162
|
+
|
|
163
|
+
**Typical runtime:** < 2 seconds for full suite
|