@macpaw/cctk 1.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/License +21 -0
- package/README.md +142 -0
- package/bin/index.js +5 -0
- package/dist/index.js +1 -0
- package/package.json +65 -0
- package/templates/claude/agents/brainstormer.md +113 -0
- package/templates/claude/agents/code-reviewer.md +157 -0
- package/templates/claude/agents/copywriter.md +110 -0
- package/templates/claude/agents/database-admin.md +92 -0
- package/templates/claude/agents/debugger.md +137 -0
- package/templates/claude/agents/docs-manager.md +208 -0
- package/templates/claude/agents/fullstack-developer.md +95 -0
- package/templates/claude/agents/git-manager.md +394 -0
- package/templates/claude/agents/journal-writer.md +113 -0
- package/templates/claude/agents/mcp-manager.md +89 -0
- package/templates/claude/agents/planner.md +108 -0
- package/templates/claude/agents/project-manager.md +125 -0
- package/templates/claude/agents/registry.json +304 -0
- package/templates/claude/agents/researcher.md +37 -0
- package/templates/claude/agents/scout-external.md +140 -0
- package/templates/claude/agents/scout.md +106 -0
- package/templates/claude/agents/tester.md +105 -0
- package/templates/claude/agents/ui-ux-designer.md +208 -0
- package/templates/claude/commands/ask.md +56 -0
- package/templates/claude/commands/bootstrap/auto/fast.md +106 -0
- package/templates/claude/commands/bootstrap/auto/parallel.md +64 -0
- package/templates/claude/commands/bootstrap/auto.md +110 -0
- package/templates/claude/commands/bootstrap.md +130 -0
- package/templates/claude/commands/brainstorm.md +75 -0
- package/templates/claude/commands/code/auto.md +198 -0
- package/templates/claude/commands/code/no-test.md +172 -0
- package/templates/claude/commands/code/parallel.md +100 -0
- package/templates/claude/commands/code.md +197 -0
- package/templates/claude/commands/coding-level.md +37 -0
- package/templates/claude/commands/content/cro.md +41 -0
- package/templates/claude/commands/content/enhance.md +12 -0
- package/templates/claude/commands/content/fast.md +11 -0
- package/templates/claude/commands/content/good.md +14 -0
- package/templates/claude/commands/cook/auto/fast.md +26 -0
- package/templates/claude/commands/cook/auto/parallel.md +49 -0
- package/templates/claude/commands/cook/auto.md +15 -0
- package/templates/claude/commands/cook.md +101 -0
- package/templates/claude/commands/debug.md +13 -0
- package/templates/claude/commands/docs/init.md +37 -0
- package/templates/claude/commands/docs/summarize.md +22 -0
- package/templates/claude/commands/docs/update.md +78 -0
- package/templates/claude/commands/fix/ci.md +17 -0
- package/templates/claude/commands/fix/fast.md +18 -0
- package/templates/claude/commands/fix/hard.md +35 -0
- package/templates/claude/commands/fix/logs.md +26 -0
- package/templates/claude/commands/fix/parallel.md +54 -0
- package/templates/claude/commands/fix/test.md +20 -0
- package/templates/claude/commands/fix/types.md +9 -0
- package/templates/claude/commands/fix/ui.md +33 -0
- package/templates/claude/commands/fix.md +43 -0
- package/templates/claude/commands/git/cm.md +5 -0
- package/templates/claude/commands/git/cp.md +4 -0
- package/templates/claude/commands/git/merge.md +40 -0
- package/templates/claude/commands/git/pr.md +50 -0
- package/templates/claude/commands/journal.md +7 -0
- package/templates/claude/commands/kanban.md +99 -0
- package/templates/claude/commands/plan/archive.md +57 -0
- package/templates/claude/commands/plan/ci.md +33 -0
- package/templates/claude/commands/plan/cro.md +67 -0
- package/templates/claude/commands/plan/fast.md +66 -0
- package/templates/claude/commands/plan/hard.md +92 -0
- package/templates/claude/commands/plan/parallel.md +129 -0
- package/templates/claude/commands/plan/two.md +45 -0
- package/templates/claude/commands/plan/validate.md +117 -0
- package/templates/claude/commands/plan.md +30 -0
- package/templates/claude/commands/preview.md +87 -0
- package/templates/claude/commands/registry.json +313 -0
- package/templates/claude/commands/review/codebase/parallel.md +122 -0
- package/templates/claude/commands/review/codebase.md +47 -0
- package/templates/claude/commands/scout/ext.md +35 -0
- package/templates/claude/commands/scout.md +28 -0
- package/templates/claude/commands/skill/add.md +36 -0
- package/templates/claude/commands/skill/create.md +29 -0
- package/templates/claude/commands/skill/fix-logs.md +22 -0
- package/templates/claude/commands/skill/optimize/auto.md +25 -0
- package/templates/claude/commands/skill/optimize.md +34 -0
- package/templates/claude/commands/skill/plan.md +45 -0
- package/templates/claude/commands/test/ui.md +91 -0
- package/templates/claude/commands/test.md +8 -0
- package/templates/claude/commands/use-mcp.md +34 -0
- package/templates/claude/commands/watzup.md +8 -0
- package/templates/claude/commands/worktree.md +126 -0
- package/templates/claude/hooks/dev-rules-reminder.cjs +258 -0
- package/templates/claude/hooks/docs/README.md +42 -0
- package/templates/claude/hooks/lib/cctk-config-utils.cjs +751 -0
- package/templates/claude/hooks/lib/cctk-paths.cjs +106 -0
- package/templates/claude/hooks/lib/context-tracker.cjs +346 -0
- package/templates/claude/hooks/privacy-block.cjs +289 -0
- package/templates/claude/hooks/registry.json +77 -0
- package/templates/claude/hooks/scout-block/broad-pattern-detector.cjs +293 -0
- package/templates/claude/hooks/scout-block/error-formatter.cjs +156 -0
- package/templates/claude/hooks/scout-block/path-extractor.cjs +359 -0
- package/templates/claude/hooks/scout-block/pattern-matcher.cjs +184 -0
- package/templates/claude/hooks/scout-block/vendor/ignore.js +626 -0
- package/templates/claude/hooks/scout-block.cjs +167 -0
- package/templates/claude/hooks/session-end.cjs +35 -0
- package/templates/claude/hooks/session-init.cjs +214 -0
- package/templates/claude/hooks/subagent-init.cjs +161 -0
- package/templates/claude/hooks/write-compact-marker.cjs +153 -0
- package/templates/claude/output-styles/coding-level-1.md +148 -0
- package/templates/claude/output-styles/coding-level-2.md +159 -0
- package/templates/claude/output-styles/coding-level-3.md +91 -0
- package/templates/claude/scripts/README.md +33 -0
- package/templates/claude/scripts/generate-catalogs.cjs +318 -0
- package/templates/claude/scripts/registry.json +48 -0
- package/templates/claude/scripts/set-active-plan.cjs +45 -0
- package/templates/claude/scripts/validate-docs.cjs +447 -0
- package/templates/claude/scripts/worktree.cjs +658 -0
- package/templates/claude/skills/README.md +112 -0
- package/templates/claude/skills/ai-artist/SKILL.md +75 -0
- package/templates/claude/skills/ai-artist/references/advanced-techniques.md +184 -0
- package/templates/claude/skills/ai-artist/references/domain-code.md +66 -0
- package/templates/claude/skills/ai-artist/references/domain-data.md +72 -0
- package/templates/claude/skills/ai-artist/references/domain-marketing.md +66 -0
- package/templates/claude/skills/ai-artist/references/domain-patterns.md +33 -0
- package/templates/claude/skills/ai-artist/references/domain-writing.md +68 -0
- package/templates/claude/skills/ai-artist/references/image-prompting.md +141 -0
- package/templates/claude/skills/ai-artist/references/llm-prompting.md +165 -0
- package/templates/claude/skills/ai-artist/references/nano-banana.md +59 -0
- package/templates/claude/skills/ai-artist/references/reasoning-techniques.md +201 -0
- package/templates/claude/skills/backend-development/SKILL.md +95 -0
- package/templates/claude/skills/backend-development/references/backend-api-design.md +495 -0
- package/templates/claude/skills/backend-development/references/backend-architecture.md +454 -0
- package/templates/claude/skills/backend-development/references/backend-authentication.md +338 -0
- package/templates/claude/skills/backend-development/references/backend-code-quality.md +659 -0
- package/templates/claude/skills/backend-development/references/backend-debugging.md +904 -0
- package/templates/claude/skills/backend-development/references/backend-devops.md +494 -0
- package/templates/claude/skills/backend-development/references/backend-mindset.md +387 -0
- package/templates/claude/skills/backend-development/references/backend-performance.md +397 -0
- package/templates/claude/skills/backend-development/references/backend-security.md +290 -0
- package/templates/claude/skills/backend-development/references/backend-technologies.md +256 -0
- package/templates/claude/skills/backend-development/references/backend-testing.md +429 -0
- package/templates/claude/skills/better-auth/SKILL.md +204 -0
- package/templates/claude/skills/better-auth/references/advanced-features.md +553 -0
- package/templates/claude/skills/better-auth/references/database-integration.md +577 -0
- package/templates/claude/skills/better-auth/references/email-password-auth.md +416 -0
- package/templates/claude/skills/better-auth/references/oauth-providers.md +430 -0
- package/templates/claude/skills/better-auth/scripts/better_auth_init.py +521 -0
- package/templates/claude/skills/chrome-devtools/SKILL.md +473 -0
- package/templates/claude/skills/chrome-devtools/references/cdp-domains.md +694 -0
- package/templates/claude/skills/chrome-devtools/references/performance-guide.md +940 -0
- package/templates/claude/skills/chrome-devtools/references/puppeteer-reference.md +953 -0
- package/templates/claude/skills/chrome-devtools/scripts/README.md +288 -0
- package/templates/claude/skills/chrome-devtools/scripts/aria-snapshot.js +368 -0
- package/templates/claude/skills/chrome-devtools/scripts/click.js +92 -0
- package/templates/claude/skills/chrome-devtools/scripts/console.js +85 -0
- package/templates/claude/skills/chrome-devtools/scripts/evaluate.js +59 -0
- package/templates/claude/skills/chrome-devtools/scripts/fill.js +84 -0
- package/templates/claude/skills/chrome-devtools/scripts/inject-auth.js +247 -0
- package/templates/claude/skills/chrome-devtools/scripts/install-deps.sh +11 -0
- package/templates/claude/skills/chrome-devtools/scripts/install.sh +36 -0
- package/templates/claude/skills/chrome-devtools/scripts/lib/browser.js +335 -0
- package/templates/claude/skills/chrome-devtools/scripts/lib/selector.js +183 -0
- package/templates/claude/skills/chrome-devtools/scripts/navigate.js +60 -0
- package/templates/claude/skills/chrome-devtools/scripts/network.js +113 -0
- package/templates/claude/skills/chrome-devtools/scripts/package.json +16 -0
- package/templates/claude/skills/chrome-devtools/scripts/performance.js +159 -0
- package/templates/claude/skills/chrome-devtools/scripts/screenshot.js +212 -0
- package/templates/claude/skills/chrome-devtools/scripts/select-ref.js +151 -0
- package/templates/claude/skills/chrome-devtools/scripts/snapshot.js +143 -0
- package/templates/claude/skills/chrome-devtools/scripts/ws-debug.js +47 -0
- package/templates/claude/skills/chrome-devtools/scripts/ws-full-debug.js +115 -0
- package/templates/claude/skills/claude-code/references/advanced-features.md +399 -0
- package/templates/claude/skills/claude-code/references/agent-skills.md +399 -0
- package/templates/claude/skills/claude-code/references/api-reference.md +498 -0
- package/templates/claude/skills/claude-code/references/best-practices.md +447 -0
- package/templates/claude/skills/claude-code/references/cicd-integration.md +428 -0
- package/templates/claude/skills/claude-code/references/common-workflows.md +107 -0
- package/templates/claude/skills/claude-code/references/configuration.md +480 -0
- package/templates/claude/skills/claude-code/references/enterprise-features.md +472 -0
- package/templates/claude/skills/claude-code/references/getting-started.md +244 -0
- package/templates/claude/skills/claude-code/references/hooks-and-plugins.md +444 -0
- package/templates/claude/skills/claude-code/references/hooks-comprehensive.md +622 -0
- package/templates/claude/skills/claude-code/references/ide-integration.md +316 -0
- package/templates/claude/skills/claude-code/references/mcp-integration.md +386 -0
- package/templates/claude/skills/claude-code/references/slash-commands.md +460 -0
- package/templates/claude/skills/claude-code/references/troubleshooting.md +455 -0
- package/templates/claude/skills/claude-code/skill.md +60 -0
- package/templates/claude/skills/code-review/SKILL.md +143 -0
- package/templates/claude/skills/code-review/references/code-review-reception.md +209 -0
- package/templates/claude/skills/code-review/references/requesting-code-review.md +105 -0
- package/templates/claude/skills/code-review/references/verification-before-completion.md +139 -0
- package/templates/claude/skills/context-engineering/SKILL.md +86 -0
- package/templates/claude/skills/context-engineering/references/context-compression.md +84 -0
- package/templates/claude/skills/context-engineering/references/context-degradation.md +93 -0
- package/templates/claude/skills/context-engineering/references/context-fundamentals.md +75 -0
- package/templates/claude/skills/context-engineering/references/context-optimization.md +82 -0
- package/templates/claude/skills/context-engineering/references/evaluation.md +89 -0
- package/templates/claude/skills/context-engineering/references/memory-systems.md +88 -0
- package/templates/claude/skills/context-engineering/references/multi-agent-patterns.md +90 -0
- package/templates/claude/skills/context-engineering/references/project-development.md +97 -0
- package/templates/claude/skills/context-engineering/references/tool-design.md +86 -0
- package/templates/claude/skills/context-engineering/scripts/compression_evaluator.py +329 -0
- package/templates/claude/skills/context-engineering/scripts/context_analyzer.py +294 -0
- package/templates/claude/skills/databases/SKILL.md +232 -0
- package/templates/claude/skills/databases/references/mongodb-aggregation.md +447 -0
- package/templates/claude/skills/databases/references/mongodb-atlas.md +465 -0
- package/templates/claude/skills/databases/references/mongodb-crud.md +408 -0
- package/templates/claude/skills/databases/references/mongodb-indexing.md +442 -0
- package/templates/claude/skills/databases/references/postgresql-administration.md +594 -0
- package/templates/claude/skills/databases/references/postgresql-performance.md +527 -0
- package/templates/claude/skills/databases/references/postgresql-psql-cli.md +467 -0
- package/templates/claude/skills/databases/references/postgresql-queries.md +475 -0
- package/templates/claude/skills/databases/scripts/db_backup.py +502 -0
- package/templates/claude/skills/databases/scripts/db_migrate.py +414 -0
- package/templates/claude/skills/databases/scripts/db_performance_check.py +445 -0
- package/templates/claude/skills/debugging/SKILL.md +84 -0
- package/templates/claude/skills/debugging/references/defense-in-depth.md +124 -0
- package/templates/claude/skills/debugging/references/root-cause-tracing.md +122 -0
- package/templates/claude/skills/debugging/references/systematic-debugging.md +102 -0
- package/templates/claude/skills/debugging/references/verification.md +123 -0
- package/templates/claude/skills/debugging/scripts/find-polluter.sh +63 -0
- package/templates/claude/skills/debugging/scripts/find-polluter.test.md +102 -0
- package/templates/claude/skills/devops/SKILL.md +293 -0
- package/templates/claude/skills/devops/references/browser-rendering.md +305 -0
- package/templates/claude/skills/devops/references/cloudflare-d1-kv.md +123 -0
- package/templates/claude/skills/devops/references/cloudflare-platform.md +271 -0
- package/templates/claude/skills/devops/references/cloudflare-r2-storage.md +280 -0
- package/templates/claude/skills/devops/references/cloudflare-workers-advanced.md +312 -0
- package/templates/claude/skills/devops/references/cloudflare-workers-apis.md +309 -0
- package/templates/claude/skills/devops/references/cloudflare-workers-basics.md +418 -0
- package/templates/claude/skills/devops/references/docker-basics.md +297 -0
- package/templates/claude/skills/devops/references/docker-compose.md +292 -0
- package/templates/claude/skills/devops/references/gcloud-platform.md +307 -0
- package/templates/claude/skills/devops/references/gcloud-services.md +304 -0
- package/templates/claude/skills/devops/scripts/cloudflare_deploy.py +269 -0
- package/templates/claude/skills/devops/scripts/docker_optimize.py +320 -0
- package/templates/claude/skills/docs-seeker/SKILL.md +95 -0
- package/templates/claude/skills/docs-seeker/package.json +24 -0
- package/templates/claude/skills/docs-seeker/references/advanced.md +78 -0
- package/templates/claude/skills/docs-seeker/references/context7-patterns.md +68 -0
- package/templates/claude/skills/docs-seeker/references/errors.md +68 -0
- package/templates/claude/skills/docs-seeker/scripts/analyze-llms-txt.js +245 -0
- package/templates/claude/skills/docs-seeker/scripts/detect-topic.js +172 -0
- package/templates/claude/skills/docs-seeker/scripts/fetch-docs.js +212 -0
- package/templates/claude/skills/docs-seeker/workflows/library-search.md +87 -0
- package/templates/claude/skills/docs-seeker/workflows/repo-analysis.md +91 -0
- package/templates/claude/skills/docs-seeker/workflows/topic-search.md +77 -0
- package/templates/claude/skills/frontend-design/SKILL.md +85 -0
- package/templates/claude/skills/frontend-design/references/analysis-best-practices.md +80 -0
- package/templates/claude/skills/frontend-design/references/analysis-prompts.md +141 -0
- package/templates/claude/skills/frontend-design/references/analysis-techniques.md +118 -0
- package/templates/claude/skills/frontend-design/references/animejs.md +396 -0
- package/templates/claude/skills/frontend-design/references/design-extraction-overview.md +71 -0
- package/templates/claude/skills/frontend-design/references/extraction-best-practices.md +141 -0
- package/templates/claude/skills/frontend-design/references/extraction-output-templates.md +162 -0
- package/templates/claude/skills/frontend-design/references/extraction-prompts.md +127 -0
- package/templates/claude/skills/frontend-design/references/technical-accessibility.md +119 -0
- package/templates/claude/skills/frontend-design/references/technical-best-practices.md +97 -0
- package/templates/claude/skills/frontend-design/references/technical-optimization.md +44 -0
- package/templates/claude/skills/frontend-design/references/technical-overview.md +90 -0
- package/templates/claude/skills/frontend-design/references/technical-workflows.md +150 -0
- package/templates/claude/skills/frontend-design/references/visual-analysis-overview.md +95 -0
- package/templates/claude/skills/frontend-development/SKILL.md +399 -0
- package/templates/claude/skills/frontend-development/resources/common-patterns.md +331 -0
- package/templates/claude/skills/frontend-development/resources/complete-examples.md +872 -0
- package/templates/claude/skills/frontend-development/resources/component-patterns.md +502 -0
- package/templates/claude/skills/frontend-development/resources/data-fetching.md +767 -0
- package/templates/claude/skills/frontend-development/resources/file-organization.md +502 -0
- package/templates/claude/skills/frontend-development/resources/loading-and-error-states.md +501 -0
- package/templates/claude/skills/frontend-development/resources/performance.md +406 -0
- package/templates/claude/skills/frontend-development/resources/routing-guide.md +364 -0
- package/templates/claude/skills/frontend-development/resources/styling-guide.md +428 -0
- package/templates/claude/skills/frontend-development/resources/typescript-standards.md +418 -0
- package/templates/claude/skills/markdown-novel-viewer/SKILL.md +272 -0
- package/templates/claude/skills/markdown-novel-viewer/assets/directory-browser.css +215 -0
- package/templates/claude/skills/markdown-novel-viewer/assets/favicon.png +0 -0
- package/templates/claude/skills/markdown-novel-viewer/assets/novel-theme.css +872 -0
- package/templates/claude/skills/markdown-novel-viewer/assets/reader.js +378 -0
- package/templates/claude/skills/markdown-novel-viewer/assets/template.html +85 -0
- package/templates/claude/skills/markdown-novel-viewer/package.json +15 -0
- package/templates/claude/skills/markdown-novel-viewer/scripts/lib/http-server.cjs +434 -0
- package/templates/claude/skills/markdown-novel-viewer/scripts/lib/markdown-renderer.cjs +335 -0
- package/templates/claude/skills/markdown-novel-viewer/scripts/lib/plan-navigator.cjs +509 -0
- package/templates/claude/skills/markdown-novel-viewer/scripts/lib/port-finder.cjs +49 -0
- package/templates/claude/skills/markdown-novel-viewer/scripts/lib/process-mgr.cjs +150 -0
- package/templates/claude/skills/markdown-novel-viewer/scripts/server.cjs +398 -0
- package/templates/claude/skills/mcp-builder/SKILL.md +328 -0
- package/templates/claude/skills/mcp-builder/reference/evaluation.md +602 -0
- package/templates/claude/skills/mcp-builder/reference/mcp_best_practices.md +915 -0
- package/templates/claude/skills/mcp-builder/reference/node_mcp_server.md +916 -0
- package/templates/claude/skills/mcp-builder/reference/python_mcp_server.md +752 -0
- package/templates/claude/skills/mcp-builder/scripts/connections.py +151 -0
- package/templates/claude/skills/mcp-builder/scripts/evaluation.py +381 -0
- package/templates/claude/skills/mcp-builder/scripts/example_evaluation.xml +22 -0
- package/templates/claude/skills/mcp-builder/scripts/requirements.txt +2 -0
- package/templates/claude/skills/mcp-management/README.md +219 -0
- package/templates/claude/skills/mcp-management/SKILL.md +209 -0
- package/templates/claude/skills/mcp-management/assets/tools.json +3146 -0
- package/templates/claude/skills/mcp-management/references/configuration.md +114 -0
- package/templates/claude/skills/mcp-management/references/gemini-cli-integration.md +209 -0
- package/templates/claude/skills/mcp-management/references/mcp-protocol.md +116 -0
- package/templates/claude/skills/mcp-management/scripts/.env.example +10 -0
- package/templates/claude/skills/mcp-management/scripts/cli.ts +202 -0
- package/templates/claude/skills/mcp-management/scripts/mcp-client.ts +247 -0
- package/templates/claude/skills/mcp-management/scripts/package.json +20 -0
- package/templates/claude/skills/mcp-management/scripts/tsconfig.json +15 -0
- package/templates/claude/skills/media-processing/SKILL.md +91 -0
- package/templates/claude/skills/media-processing/references/common-workflows.md +132 -0
- package/templates/claude/skills/media-processing/references/ffmpeg-encoding.md +358 -0
- package/templates/claude/skills/media-processing/references/ffmpeg-filters.md +503 -0
- package/templates/claude/skills/media-processing/references/ffmpeg-streaming.md +395 -0
- package/templates/claude/skills/media-processing/references/format-compatibility.md +375 -0
- package/templates/claude/skills/media-processing/references/imagemagick-batch.md +612 -0
- package/templates/claude/skills/media-processing/references/imagemagick-editing.md +623 -0
- package/templates/claude/skills/media-processing/references/rmbg-background-removal.md +66 -0
- package/templates/claude/skills/media-processing/references/troubleshooting.md +109 -0
- package/templates/claude/skills/media-processing/scripts/README.md +102 -0
- package/templates/claude/skills/media-processing/scripts/batch-remove-background.sh +124 -0
- package/templates/claude/skills/media-processing/scripts/batch_resize.py +342 -0
- package/templates/claude/skills/media-processing/scripts/media_convert.py +311 -0
- package/templates/claude/skills/media-processing/scripts/remove-background.sh +96 -0
- package/templates/claude/skills/media-processing/scripts/remove-bg-node.js +181 -0
- package/templates/claude/skills/mermaidjs-v11/SKILL.md +115 -0
- package/templates/claude/skills/mermaidjs-v11/references/cli-usage.md +228 -0
- package/templates/claude/skills/mermaidjs-v11/references/configuration.md +232 -0
- package/templates/claude/skills/mermaidjs-v11/references/diagram-types.md +315 -0
- package/templates/claude/skills/mermaidjs-v11/references/examples.md +344 -0
- package/templates/claude/skills/mermaidjs-v11/references/integration.md +310 -0
- package/templates/claude/skills/planning/SKILL.md +115 -0
- package/templates/claude/skills/planning/references/codebase-understanding.md +62 -0
- package/templates/claude/skills/planning/references/output-standards.md +127 -0
- package/templates/claude/skills/planning/references/plan-organization.md +150 -0
- package/templates/claude/skills/planning/references/research-phase.md +49 -0
- package/templates/claude/skills/planning/references/solution-design.md +63 -0
- package/templates/claude/skills/plans-kanban/SKILL.md +157 -0
- package/templates/claude/skills/plans-kanban/assets/dashboard-template.html +119 -0
- package/templates/claude/skills/plans-kanban/assets/dashboard.css +1594 -0
- package/templates/claude/skills/plans-kanban/assets/dashboard.js +659 -0
- package/templates/claude/skills/plans-kanban/assets/favicon.png +0 -0
- package/templates/claude/skills/plans-kanban/package.json +13 -0
- package/templates/claude/skills/plans-kanban/scripts/lib/dashboard-renderer.cjs +941 -0
- package/templates/claude/skills/plans-kanban/scripts/lib/http-server.cjs +310 -0
- package/templates/claude/skills/plans-kanban/scripts/lib/plan-metadata-extractor.cjs +489 -0
- package/templates/claude/skills/plans-kanban/scripts/lib/plan-parser.cjs +194 -0
- package/templates/claude/skills/plans-kanban/scripts/lib/plan-scanner.cjs +277 -0
- package/templates/claude/skills/plans-kanban/scripts/lib/port-finder.cjs +49 -0
- package/templates/claude/skills/plans-kanban/scripts/lib/process-mgr.cjs +128 -0
- package/templates/claude/skills/plans-kanban/scripts/server.cjs +249 -0
- package/templates/claude/skills/problem-solving/SKILL.md +96 -0
- package/templates/claude/skills/problem-solving/references/attribution.md +69 -0
- package/templates/claude/skills/problem-solving/references/collision-zone-thinking.md +79 -0
- package/templates/claude/skills/problem-solving/references/inversion-exercise.md +91 -0
- package/templates/claude/skills/problem-solving/references/meta-pattern-recognition.md +87 -0
- package/templates/claude/skills/problem-solving/references/scale-game.md +95 -0
- package/templates/claude/skills/problem-solving/references/simplification-cascades.md +80 -0
- package/templates/claude/skills/problem-solving/references/when-stuck.md +72 -0
- package/templates/claude/skills/registry.json +258 -0
- package/templates/claude/skills/repomix/SKILL.md +247 -0
- package/templates/claude/skills/repomix/references/configuration.md +211 -0
- package/templates/claude/skills/repomix/references/usage-patterns.md +232 -0
- package/templates/claude/skills/repomix/scripts/README.md +179 -0
- package/templates/claude/skills/repomix/scripts/repomix_batch.py +455 -0
- package/templates/claude/skills/repomix/scripts/repos.example.json +15 -0
- package/templates/claude/skills/research/SKILL.md +168 -0
- package/templates/claude/skills/sequential-thinking/.env.example +8 -0
- package/templates/claude/skills/sequential-thinking/README.md +183 -0
- package/templates/claude/skills/sequential-thinking/SKILL.md +94 -0
- package/templates/claude/skills/sequential-thinking/package.json +31 -0
- package/templates/claude/skills/sequential-thinking/references/advanced-strategies.md +79 -0
- package/templates/claude/skills/sequential-thinking/references/advanced-techniques.md +76 -0
- package/templates/claude/skills/sequential-thinking/references/core-patterns.md +95 -0
- package/templates/claude/skills/sequential-thinking/references/examples-api.md +88 -0
- package/templates/claude/skills/sequential-thinking/references/examples-architecture.md +94 -0
- package/templates/claude/skills/sequential-thinking/references/examples-debug.md +90 -0
- package/templates/claude/skills/sequential-thinking/scripts/format-thought.js +182 -0
- package/templates/claude/skills/sequential-thinking/scripts/process-thought.js +252 -0
- package/templates/claude/skills/skill-creator/LICENSE.txt +202 -0
- package/templates/claude/skills/skill-creator/SKILL.md +266 -0
- package/templates/claude/skills/skill-creator/references/agent-skills-spec.md +51 -0
- package/templates/claude/skills/skill-creator/scripts/encoding_utils.py +21 -0
- package/templates/claude/skills/skill-creator/scripts/init_skill.py +304 -0
- package/templates/claude/skills/skill-creator/scripts/package_skill.py +110 -0
- package/templates/claude/skills/skill-creator/scripts/quick_validate.py +66 -0
- package/templates/claude/skills/template-skill/SKILL.md +6 -0
- package/templates/claude/skills/vitest/SKILL.md +595 -0
- package/templates/claude/skills/vitest/references/async-patterns.md +82 -0
- package/templates/claude/skills/vitest/references/mock-patterns.md +78 -0
- package/templates/claude/skills/vitest/references/monorepo-setup.md +185 -0
- package/templates/claude/skills/vitest/references/turborepo-setup.md +332 -0
- package/templates/claude/skills/web-frameworks/SKILL.md +324 -0
- package/templates/claude/skills/web-frameworks/references/nextjs-app-router.md +465 -0
- package/templates/claude/skills/web-frameworks/references/nextjs-data-fetching.md +459 -0
- package/templates/claude/skills/web-frameworks/references/nextjs-optimization.md +511 -0
- package/templates/claude/skills/web-frameworks/references/nextjs-server-components.md +495 -0
- package/templates/claude/skills/web-frameworks/references/remix-icon-integration.md +603 -0
- package/templates/claude/skills/web-frameworks/references/turborepo-caching.md +551 -0
- package/templates/claude/skills/web-frameworks/references/turborepo-pipelines.md +517 -0
- package/templates/claude/skills/web-frameworks/references/turborepo-setup.md +542 -0
- package/templates/claude/skills/web-frameworks/scripts/nextjs_init.py +547 -0
- package/templates/claude/skills/web-frameworks/scripts/turborepo_migrate.py +394 -0
- package/templates/claude/workflows/development-rules.md +40 -0
- package/templates/claude/workflows/documentation-management.md +121 -0
- package/templates/claude/workflows/orchestration-protocol.md +16 -0
- package/templates/claude/workflows/primary-workflow.md +45 -0
- package/templates/claude/workflows/registry.json +37 -0
- package/templates/common/.cct.json +41 -0
- package/templates/common/.cctkignore +22 -0
- package/templates/common/.env.example +39 -0
- package/templates/common/.mcp.json.example +16 -0
- package/templates/common/metadata.json +15 -0
- package/templates/common/settings.json +79 -0
- package/templates/common/statusline.cjs +271 -0
- package/templates/config/.repomixignore +22 -0
- package/templates/config/AGENTS.md +55 -0
- package/templates/config/CLAUDE.md +87 -0
- package/templates/plans/bug-fix-template.md +69 -0
- package/templates/plans/feature-implementation-template.md +84 -0
- package/templates/plans/refactor-template.md +82 -0
- package/templates/plans/template-usage-guide.md +58 -0
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* privacy-block.cjs - Block access to sensitive files unless user-approved
|
|
4
|
+
*
|
|
5
|
+
* PRIVACY-based blocking (separate from SIZE-based scout-block)
|
|
6
|
+
* Blocks sensitive files. LLM must get user approval and use APPROVED: prefix.
|
|
7
|
+
*
|
|
8
|
+
* Flow:
|
|
9
|
+
* 1. LLM tries: Read ".env" → BLOCKED
|
|
10
|
+
* 2. LLM asks user for permission
|
|
11
|
+
* 3. User approves
|
|
12
|
+
* 4. LLM retries: Read "APPROVED:.env" → ALLOWED
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
const path = require('path');
|
|
16
|
+
const fs = require('fs');
|
|
17
|
+
|
|
18
|
+
const APPROVED_PREFIX = 'APPROVED:';
|
|
19
|
+
|
|
20
|
+
// Safe file patterns - exempt from privacy checks (documentation/template files)
|
|
21
|
+
const SAFE_PATTERNS = [
|
|
22
|
+
/\.example$/i, // .env.example, config.example
|
|
23
|
+
/\.sample$/i, // .env.sample
|
|
24
|
+
/\.template$/i, // .env.template
|
|
25
|
+
];
|
|
26
|
+
|
|
27
|
+
// Privacy-sensitive patterns
|
|
28
|
+
const PRIVACY_PATTERNS = [
|
|
29
|
+
/^\.env$/, // .env
|
|
30
|
+
/^\.env\./, // .env.local, .env.production, etc.
|
|
31
|
+
/\.env$/, // path/to/.env
|
|
32
|
+
/\/\.env\./, // path/to/.env.local
|
|
33
|
+
/credentials/i, // credentials.json, etc.
|
|
34
|
+
/secrets?\.ya?ml$/i, // secrets.yaml, secret.yml
|
|
35
|
+
/\.pem$/, // Private keys
|
|
36
|
+
/\.key$/, // Private keys
|
|
37
|
+
/id_rsa/, // SSH keys
|
|
38
|
+
/id_ed25519/, // SSH keys
|
|
39
|
+
];
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Load .cctk.json config to check if privacy block is disabled
|
|
43
|
+
* @returns {boolean} true if privacy block should be skipped
|
|
44
|
+
*/
|
|
45
|
+
function isPrivacyBlockDisabled() {
|
|
46
|
+
try {
|
|
47
|
+
const configPath = path.join(process.cwd(), '.claude', '.cctk.json');
|
|
48
|
+
const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
|
|
49
|
+
return config.privacyBlock === false;
|
|
50
|
+
} catch {
|
|
51
|
+
return false; // Default to enabled on error (file not found or invalid JSON)
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Check if path is a safe file (example/sample/template)
|
|
57
|
+
* @param {string} testPath - Path to check
|
|
58
|
+
* @returns {boolean} true if file matches safe patterns
|
|
59
|
+
*/
|
|
60
|
+
function isSafeFile(testPath) {
|
|
61
|
+
if (!testPath) return false;
|
|
62
|
+
const basename = path.basename(testPath);
|
|
63
|
+
return SAFE_PATTERNS.some(p => p.test(basename));
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Check if path has APPROVED: prefix
|
|
68
|
+
* @param {string} testPath - Path to check
|
|
69
|
+
* @returns {boolean} true if path starts with APPROVED:
|
|
70
|
+
*/
|
|
71
|
+
function hasApprovalPrefix(testPath) {
|
|
72
|
+
return testPath && testPath.startsWith(APPROVED_PREFIX);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Strip APPROVED: prefix from path, warn on suspicious paths
|
|
77
|
+
* @param {string} testPath - Path to process
|
|
78
|
+
* @returns {string} Path without APPROVED: prefix
|
|
79
|
+
*/
|
|
80
|
+
function stripApprovalPrefix(testPath) {
|
|
81
|
+
if (hasApprovalPrefix(testPath)) {
|
|
82
|
+
const stripped = testPath.slice(APPROVED_PREFIX.length);
|
|
83
|
+
|
|
84
|
+
// Warn on suspicious paths (path traversal or absolute)
|
|
85
|
+
if (stripped.includes('..') || path.isAbsolute(stripped)) {
|
|
86
|
+
console.error('\x1b[33mWARN:\x1b[0m Approved path is outside project:', stripped);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return stripped;
|
|
90
|
+
}
|
|
91
|
+
return testPath;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Check if path matches privacy patterns
|
|
96
|
+
* @param {string} testPath - Path to check
|
|
97
|
+
* @returns {boolean} true if path matches privacy-sensitive patterns
|
|
98
|
+
*/
|
|
99
|
+
function isPrivacySensitive(testPath) {
|
|
100
|
+
if (!testPath) return false;
|
|
101
|
+
|
|
102
|
+
// Strip prefix for pattern matching
|
|
103
|
+
const cleanPath = stripApprovalPrefix(testPath);
|
|
104
|
+
let normalized = cleanPath.replace(/\\/g, '/');
|
|
105
|
+
|
|
106
|
+
// Decode URI components to catch obfuscated paths (%2e = '.')
|
|
107
|
+
try {
|
|
108
|
+
normalized = decodeURIComponent(normalized);
|
|
109
|
+
} catch (e) {
|
|
110
|
+
// Invalid encoding, use as-is
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Check safe patterns first - exempt example/sample/template files
|
|
114
|
+
if (isSafeFile(normalized)) {
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const basename = path.basename(normalized);
|
|
119
|
+
|
|
120
|
+
for (const pattern of PRIVACY_PATTERNS) {
|
|
121
|
+
if (pattern.test(basename) || pattern.test(normalized)) {
|
|
122
|
+
return true;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Extract paths from tool input
|
|
130
|
+
* @param {Object} toolInput - Tool input object with file_path, path, pattern, or command
|
|
131
|
+
* @returns {Array<{value: string, field: string}>} Array of extracted paths with field names
|
|
132
|
+
*/
|
|
133
|
+
function extractPaths(toolInput) {
|
|
134
|
+
const paths = [];
|
|
135
|
+
if (!toolInput) return paths;
|
|
136
|
+
|
|
137
|
+
if (toolInput.file_path) paths.push({ value: toolInput.file_path, field: 'file_path' });
|
|
138
|
+
if (toolInput.path) paths.push({ value: toolInput.path, field: 'path' });
|
|
139
|
+
if (toolInput.pattern) paths.push({ value: toolInput.pattern, field: 'pattern' });
|
|
140
|
+
|
|
141
|
+
// Check bash commands for file paths
|
|
142
|
+
if (toolInput.command) {
|
|
143
|
+
// Look for APPROVED:.env or .env patterns
|
|
144
|
+
const approvedMatch = toolInput.command.match(/APPROVED:[^\s]+/g) || [];
|
|
145
|
+
approvedMatch.forEach(p => paths.push({ value: p, field: 'command' }));
|
|
146
|
+
|
|
147
|
+
// Only look for .env if no APPROVED: version found
|
|
148
|
+
if (approvedMatch.length === 0) {
|
|
149
|
+
const envMatch = toolInput.command.match(/\.env[^\s]*/g) || [];
|
|
150
|
+
envMatch.forEach(p => paths.push({ value: p, field: 'command' }));
|
|
151
|
+
|
|
152
|
+
// Also check bash variable assignments (FILE=.env, ENV_FILE=.env.local)
|
|
153
|
+
const varAssignments = toolInput.command.match(/\w+=[^\s]*\.env[^\s]*/g) || [];
|
|
154
|
+
varAssignments.forEach(a => {
|
|
155
|
+
const value = a.split('=')[1];
|
|
156
|
+
if (value) paths.push({ value, field: 'command' });
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
// Check command substitution containing sensitive patterns - extract .env from inside
|
|
160
|
+
const cmdSubst = toolInput.command.match(/\$\([^)]*?(\.env[^\s)]*)[^)]*\)/g) || [];
|
|
161
|
+
for (const subst of cmdSubst) {
|
|
162
|
+
const inner = subst.match(/\.env[^\s)]*/);
|
|
163
|
+
if (inner) paths.push({ value: inner[0], field: 'command' });
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
return paths.filter(p => p.value);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Format block message with approval instructions and JSON marker for AskUserQuestion
|
|
173
|
+
* @param {string} filePath - Blocked file path
|
|
174
|
+
* @returns {string} Formatted block message with JSON marker
|
|
175
|
+
*/
|
|
176
|
+
function formatBlockMessage(filePath) {
|
|
177
|
+
const basename = path.basename(filePath);
|
|
178
|
+
|
|
179
|
+
// JSON marker for LLM to parse and use AskUserQuestion tool
|
|
180
|
+
const promptData = {
|
|
181
|
+
type: 'PRIVACY_PROMPT',
|
|
182
|
+
file: filePath,
|
|
183
|
+
basename: basename,
|
|
184
|
+
question: {
|
|
185
|
+
header: 'File Access',
|
|
186
|
+
text: `I need to read "${basename}" which may contain sensitive data (API keys, passwords, tokens). Do you approve?`,
|
|
187
|
+
options: [
|
|
188
|
+
{ label: 'Yes, approve access', description: `Allow reading ${basename} this time` },
|
|
189
|
+
{ label: 'No, skip this file', description: 'Continue without accessing this file' }
|
|
190
|
+
]
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
return `
|
|
195
|
+
\x1b[36mNOTE:\x1b[0m This is not an error - this block protects sensitive data.
|
|
196
|
+
|
|
197
|
+
\x1b[33mPRIVACY BLOCK\x1b[0m: Sensitive file access requires user approval
|
|
198
|
+
|
|
199
|
+
\x1b[33mFile:\x1b[0m ${filePath}
|
|
200
|
+
|
|
201
|
+
This file may contain secrets (API keys, passwords, tokens).
|
|
202
|
+
|
|
203
|
+
\x1b[90m@@PRIVACY_PROMPT_START@@\x1b[0m
|
|
204
|
+
${JSON.stringify(promptData, null, 2)}
|
|
205
|
+
\x1b[90m@@PRIVACY_PROMPT_END@@\x1b[0m
|
|
206
|
+
|
|
207
|
+
\x1b[34mClaude:\x1b[0m Use AskUserQuestion tool with the JSON above, then:
|
|
208
|
+
\x1b[32mIf "Yes":\x1b[0m Use bash to read: cat "${filePath}"
|
|
209
|
+
\x1b[31mIf "No":\x1b[0m Continue without this file.
|
|
210
|
+
`;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Format approval notice
|
|
215
|
+
* @param {string} filePath - Approved file path
|
|
216
|
+
* @returns {string} Formatted approval notice
|
|
217
|
+
*/
|
|
218
|
+
function formatApprovalNotice(filePath) {
|
|
219
|
+
return `\x1b[32m✓\x1b[0m Privacy: User-approved access to ${path.basename(filePath)}`;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// Main
|
|
223
|
+
async function main() {
|
|
224
|
+
// Check if privacy block is disabled via .cctk.json
|
|
225
|
+
if (isPrivacyBlockDisabled()) {
|
|
226
|
+
process.exit(0); // Disabled, allow all
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
let input = '';
|
|
230
|
+
for await (const chunk of process.stdin) {
|
|
231
|
+
input += chunk;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
let hookData;
|
|
235
|
+
try {
|
|
236
|
+
hookData = JSON.parse(input);
|
|
237
|
+
} catch (e) {
|
|
238
|
+
process.exit(0); // Invalid JSON, allow
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
const { tool_input: toolInput, tool_name: toolName } = hookData;
|
|
242
|
+
|
|
243
|
+
// For Bash commands, only warn but don't block - let Claude Code's permission system handle it
|
|
244
|
+
// This allows the "Yes → bash cat" flow after AskUserQuestion approval
|
|
245
|
+
const isBashTool = toolName === 'Bash';
|
|
246
|
+
|
|
247
|
+
const paths = extractPaths(toolInput);
|
|
248
|
+
|
|
249
|
+
// Check each path
|
|
250
|
+
for (const { value: testPath } of paths) {
|
|
251
|
+
if (!isPrivacySensitive(testPath)) continue;
|
|
252
|
+
|
|
253
|
+
// Check for approval prefix
|
|
254
|
+
if (hasApprovalPrefix(testPath)) {
|
|
255
|
+
// User approved - allow with notice
|
|
256
|
+
console.error(formatApprovalNotice(testPath));
|
|
257
|
+
continue; // Check other paths
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// For Bash: warn but don't block - allows "Yes → bash cat" flow
|
|
261
|
+
if (isBashTool) {
|
|
262
|
+
console.error(`\x1b[33mWARN:\x1b[0m Bash command accesses sensitive file: ${testPath}`);
|
|
263
|
+
continue; // Warn but allow
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// No approval - block
|
|
267
|
+
console.error(formatBlockMessage(testPath));
|
|
268
|
+
process.exit(2); // Block
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
process.exit(0); // Allow
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
// Run main only when executed directly (not when required for testing)
|
|
275
|
+
if (require.main === module) {
|
|
276
|
+
main().catch(() => process.exit(0));
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// Export functions for unit testing
|
|
280
|
+
if (typeof module !== 'undefined') {
|
|
281
|
+
module.exports = {
|
|
282
|
+
isSafeFile,
|
|
283
|
+
isPrivacyBlockDisabled,
|
|
284
|
+
isPrivacySensitive,
|
|
285
|
+
hasApprovalPrefix,
|
|
286
|
+
stripApprovalPrefix,
|
|
287
|
+
extractPaths,
|
|
288
|
+
};
|
|
289
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "hooks",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"items": [
|
|
5
|
+
{
|
|
6
|
+
"name": "core-libs",
|
|
7
|
+
"title": "Hook Core Libraries",
|
|
8
|
+
"description": "Shared utilities required by all hooks",
|
|
9
|
+
"files": ["hooks/lib/"],
|
|
10
|
+
"dependencies": {}
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"name": "dev-rules-reminder",
|
|
14
|
+
"title": "Dev Rules Reminder",
|
|
15
|
+
"description": "Reminds about development rules during session",
|
|
16
|
+
"files": ["hooks/dev-rules-reminder.cjs"],
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"hooks": ["core-libs"],
|
|
19
|
+
"workflows": ["development-rules"]
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"name": "privacy-block",
|
|
24
|
+
"title": "Privacy Block",
|
|
25
|
+
"description": "Blocks privacy-sensitive operations",
|
|
26
|
+
"files": ["hooks/privacy-block.cjs"],
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"hooks": ["core-libs"]
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"name": "scout-block",
|
|
33
|
+
"title": "Scout Block",
|
|
34
|
+
"description": "Blocks scout subagent operations",
|
|
35
|
+
"files": ["hooks/scout-block.cjs", "hooks/scout-block/"],
|
|
36
|
+
"dependencies": {
|
|
37
|
+
"hooks": ["core-libs"]
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"name": "session-end",
|
|
42
|
+
"title": "Session End",
|
|
43
|
+
"description": "Cleanup and finalization at session end",
|
|
44
|
+
"files": ["hooks/session-end.cjs"],
|
|
45
|
+
"dependencies": {
|
|
46
|
+
"hooks": ["core-libs"]
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"name": "session-init",
|
|
51
|
+
"title": "Session Init",
|
|
52
|
+
"description": "Bootstrap session with config and context",
|
|
53
|
+
"files": ["hooks/session-init.cjs"],
|
|
54
|
+
"dependencies": {
|
|
55
|
+
"hooks": ["core-libs"]
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"name": "subagent-init",
|
|
60
|
+
"title": "Subagent Init",
|
|
61
|
+
"description": "Initialize subagent context and configuration",
|
|
62
|
+
"files": ["hooks/subagent-init.cjs"],
|
|
63
|
+
"dependencies": {
|
|
64
|
+
"hooks": ["core-libs"]
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
"name": "write-compact-marker",
|
|
69
|
+
"title": "Write Compact Marker",
|
|
70
|
+
"description": "Adds compact markers when writing files",
|
|
71
|
+
"files": ["hooks/write-compact-marker.cjs"],
|
|
72
|
+
"dependencies": {
|
|
73
|
+
"hooks": ["core-libs"]
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
]
|
|
77
|
+
}
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* broad-pattern-detector.cjs - Detect overly broad glob patterns
|
|
4
|
+
*
|
|
5
|
+
* Prevents LLMs from filling context by using patterns like "all files"
|
|
6
|
+
* at project root, which returns ALL files of a type.
|
|
7
|
+
*
|
|
8
|
+
* Detection Strategy:
|
|
9
|
+
* 1. Pattern breadth: recursive glob at start = recursive everywhere
|
|
10
|
+
* 2. Path depth: Root or shallow paths are high-risk
|
|
11
|
+
* 3. Combined: Broad pattern + high-level path = BLOCK
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
const path = require('node:path');
|
|
15
|
+
|
|
16
|
+
// Patterns that recursively match everywhere when at root
|
|
17
|
+
// These are dangerous because they return ALL matching files
|
|
18
|
+
const BROAD_PATTERN_REGEXES = [
|
|
19
|
+
// ** - all files everywhere (no filter at all)
|
|
20
|
+
/^\*\*$/,
|
|
21
|
+
// * - all files in root
|
|
22
|
+
/^\*$/,
|
|
23
|
+
// **/* - all files everywhere
|
|
24
|
+
/^\*\*\/\*$/,
|
|
25
|
+
// **/. - all dotfiles everywhere
|
|
26
|
+
/^\*\*\/\.\*$/,
|
|
27
|
+
// **/*.ext - all files with extension (catches .ts, .py, .java, etc.)
|
|
28
|
+
/^\*\*\/\*\.\w+$/,
|
|
29
|
+
// **/*.{ext,ext2} - all files with multiple extensions
|
|
30
|
+
/^\*\*\/\*\.\{[^}]+\}$/,
|
|
31
|
+
// **/name.ext - all files with specific name anywhere
|
|
32
|
+
/^\*\*\/[\w-]+\.\w+$/,
|
|
33
|
+
// *.ext at root (matches all in root, but combined with deep search)
|
|
34
|
+
/^\*\.\w+$/,
|
|
35
|
+
// *.{ext,ext2} at root
|
|
36
|
+
/^\*\.\{[^}]+\}$/,
|
|
37
|
+
];
|
|
38
|
+
|
|
39
|
+
// Common source directories that indicate a more specific search
|
|
40
|
+
const SPECIFIC_DIRS = [
|
|
41
|
+
'src',
|
|
42
|
+
'lib',
|
|
43
|
+
'app',
|
|
44
|
+
'apps',
|
|
45
|
+
'packages',
|
|
46
|
+
'components',
|
|
47
|
+
'pages',
|
|
48
|
+
'api',
|
|
49
|
+
'server',
|
|
50
|
+
'client',
|
|
51
|
+
'web',
|
|
52
|
+
'mobile',
|
|
53
|
+
'shared',
|
|
54
|
+
'common',
|
|
55
|
+
'utils',
|
|
56
|
+
'helpers',
|
|
57
|
+
'services',
|
|
58
|
+
'hooks',
|
|
59
|
+
'store',
|
|
60
|
+
'routes',
|
|
61
|
+
'models',
|
|
62
|
+
'controllers',
|
|
63
|
+
'views',
|
|
64
|
+
'tests',
|
|
65
|
+
'__tests__',
|
|
66
|
+
'spec',
|
|
67
|
+
];
|
|
68
|
+
|
|
69
|
+
// High-risk paths (project/worktree roots)
|
|
70
|
+
const HIGH_RISK_INDICATORS = [
|
|
71
|
+
// Worktree paths
|
|
72
|
+
/\/worktrees\/[^/]+\/?$/,
|
|
73
|
+
// Project roots (contain package.json, etc.)
|
|
74
|
+
/^\.?\/?$/,
|
|
75
|
+
// Shallow paths (just one directory deep)
|
|
76
|
+
/^[^/]+\/?$/,
|
|
77
|
+
];
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Check if a glob pattern is overly broad
|
|
81
|
+
*
|
|
82
|
+
* @param {string} pattern - The glob pattern to check
|
|
83
|
+
* @returns {boolean}
|
|
84
|
+
*/
|
|
85
|
+
function isBroadPattern(pattern) {
|
|
86
|
+
if (!pattern || typeof pattern !== 'string') return false;
|
|
87
|
+
|
|
88
|
+
const normalized = pattern.trim();
|
|
89
|
+
|
|
90
|
+
// Check against known broad patterns
|
|
91
|
+
for (const regex of BROAD_PATTERN_REGEXES) {
|
|
92
|
+
if (regex.test(normalized)) {
|
|
93
|
+
return true;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Check if pattern contains a specific subdirectory.
|
|
102
|
+
* Scoped patterns like "src/..." are OK because they target specific dirs.
|
|
103
|
+
*
|
|
104
|
+
* @param {string} pattern - The glob pattern
|
|
105
|
+
* @returns {boolean}
|
|
106
|
+
*/
|
|
107
|
+
function hasSpecificDirectory(pattern) {
|
|
108
|
+
if (!pattern) return false;
|
|
109
|
+
|
|
110
|
+
// Check if pattern starts with a specific directory
|
|
111
|
+
for (const dir of SPECIFIC_DIRS) {
|
|
112
|
+
if (pattern.startsWith(`${dir}/`) || pattern.startsWith(`./${dir}/`)) {
|
|
113
|
+
return true;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Check for any non-glob directory prefix
|
|
118
|
+
// e.g., "mydir/..." has a specific directory
|
|
119
|
+
const firstSegment = pattern.split('/')[0];
|
|
120
|
+
|
|
121
|
+
if (firstSegment && !firstSegment.includes('*') && firstSegment !== '.') {
|
|
122
|
+
return true;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Check if the base path is at a high-level (risky) location
|
|
130
|
+
*
|
|
131
|
+
* @param {string} basePath - The path where glob will run
|
|
132
|
+
* @param {string} cwd - Current working directory
|
|
133
|
+
* @returns {boolean}
|
|
134
|
+
*/
|
|
135
|
+
function isHighLevelPath(basePath, cwd) {
|
|
136
|
+
// No path specified = uses CWD (often project root)
|
|
137
|
+
if (!basePath) return true;
|
|
138
|
+
|
|
139
|
+
const normalized = basePath.replaceAll('\\', '/');
|
|
140
|
+
|
|
141
|
+
// Check high-risk indicators
|
|
142
|
+
for (const regex of HIGH_RISK_INDICATORS) {
|
|
143
|
+
if (regex.test(normalized)) {
|
|
144
|
+
return true;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// Check path depth - shallow paths are higher risk
|
|
149
|
+
const segments = normalized.split('/').filter((s) => s && s !== '.');
|
|
150
|
+
|
|
151
|
+
if (segments.length <= 1) {
|
|
152
|
+
return true;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// If path doesn't contain a specific directory, it's high-level
|
|
156
|
+
const hasSpecific = SPECIFIC_DIRS.some(
|
|
157
|
+
(dir) =>
|
|
158
|
+
normalized.includes(`/${dir}/`) ||
|
|
159
|
+
normalized.includes(`/${dir}`) ||
|
|
160
|
+
normalized.startsWith(`${dir}/`) ||
|
|
161
|
+
normalized === dir,
|
|
162
|
+
);
|
|
163
|
+
|
|
164
|
+
return !hasSpecific;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Generate suggestions for more specific patterns
|
|
169
|
+
*
|
|
170
|
+
* @param {string} pattern - The broad pattern
|
|
171
|
+
* @returns {string[]}
|
|
172
|
+
*/
|
|
173
|
+
function suggestSpecificPatterns(pattern) {
|
|
174
|
+
const suggestions = [];
|
|
175
|
+
|
|
176
|
+
// Extract the extension/file part from the pattern
|
|
177
|
+
let ext = '';
|
|
178
|
+
const extMatch = pattern.match(/\*\.(\{[^}]+\}|\w+)$/);
|
|
179
|
+
|
|
180
|
+
if (extMatch) {
|
|
181
|
+
ext = extMatch[1];
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// Suggest common directories
|
|
185
|
+
const commonDirs = ['src', 'lib', 'app', 'components'];
|
|
186
|
+
|
|
187
|
+
for (const dir of commonDirs) {
|
|
188
|
+
if (ext) {
|
|
189
|
+
suggestions.push(`${dir}/**/*.${ext}`);
|
|
190
|
+
} else {
|
|
191
|
+
suggestions.push(`${dir}/**/*`);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// If it's a TypeScript pattern, add specific suggestions
|
|
196
|
+
if (pattern.includes('.ts') || pattern.includes('{ts')) {
|
|
197
|
+
suggestions.unshift('src/**/*.ts', 'src/**/*.tsx');
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// If it's a JavaScript pattern
|
|
201
|
+
if (pattern.includes('.js') || pattern.includes('{js')) {
|
|
202
|
+
suggestions.unshift('src/**/*.js', 'lib/**/*.js');
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
return suggestions.slice(0, 4); // Return top 4 suggestions
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Main detection function - check if a Glob tool call is problematic
|
|
210
|
+
*
|
|
211
|
+
* @param {Object} toolInput - The tool_input from hook JSON
|
|
212
|
+
* @param {string} toolInput.pattern - The glob pattern
|
|
213
|
+
* @param {string} [toolInput.path] - Optional base path
|
|
214
|
+
* @returns {Object} { blocked: boolean, reason?: string, suggestions?: string[] }
|
|
215
|
+
*/
|
|
216
|
+
function detectBroadPatternIssue(toolInput) {
|
|
217
|
+
if (!toolInput || typeof toolInput !== 'object') {
|
|
218
|
+
return { blocked: false };
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
const { pattern, path: basePath } = toolInput;
|
|
222
|
+
|
|
223
|
+
// No pattern = nothing to check
|
|
224
|
+
if (!pattern) {
|
|
225
|
+
return { blocked: false };
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// Pattern has a specific directory = OK
|
|
229
|
+
if (hasSpecificDirectory(pattern)) {
|
|
230
|
+
return { blocked: false };
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// Check if pattern is broad
|
|
234
|
+
if (!isBroadPattern(pattern)) {
|
|
235
|
+
return { blocked: false };
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// Check if path is high-level
|
|
239
|
+
if (!isHighLevelPath(basePath)) {
|
|
240
|
+
return { blocked: false };
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// Broad pattern at high-level path = BLOCK
|
|
244
|
+
return {
|
|
245
|
+
blocked: true,
|
|
246
|
+
reason: `Pattern '${pattern}' is too broad for ${basePath || 'project root'}`,
|
|
247
|
+
pattern,
|
|
248
|
+
suggestions: suggestSpecificPatterns(pattern),
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* Format error message for broad pattern detection
|
|
254
|
+
*
|
|
255
|
+
* @param {Object} result - Result from detectBroadPatternIssue
|
|
256
|
+
* @param {string} claudeDir - Path to .claude directory
|
|
257
|
+
* @returns {string}
|
|
258
|
+
*/
|
|
259
|
+
function formatBroadPatternError(result, claudeDir) {
|
|
260
|
+
const { reason, pattern, suggestions } = result;
|
|
261
|
+
|
|
262
|
+
const lines = [
|
|
263
|
+
'',
|
|
264
|
+
'\u001B[36mNOTE:\u001B[0m This is not an error - this block is intentional to optimize context.',
|
|
265
|
+
'',
|
|
266
|
+
'\u001B[31mBLOCKED\u001B[0m: Overly broad glob pattern detected',
|
|
267
|
+
'',
|
|
268
|
+
` \u001B[33mPattern:\u001B[0m ${pattern}`,
|
|
269
|
+
` \u001B[33mReason:\u001B[0m Would return ALL matching files, filling context`,
|
|
270
|
+
'',
|
|
271
|
+
' \u001B[34mUse more specific patterns:\u001B[0m',
|
|
272
|
+
];
|
|
273
|
+
|
|
274
|
+
for (const suggestion of suggestions || []) {
|
|
275
|
+
lines.push(` • ${suggestion}`);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
lines.push('', ' \u001B[2mTip: Target specific directories to avoid context overflow\u001B[0m', '');
|
|
279
|
+
|
|
280
|
+
return lines.join('\n');
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
module.exports = {
|
|
284
|
+
isBroadPattern,
|
|
285
|
+
hasSpecificDirectory,
|
|
286
|
+
isHighLevelPath,
|
|
287
|
+
suggestSpecificPatterns,
|
|
288
|
+
detectBroadPatternIssue,
|
|
289
|
+
formatBroadPatternError,
|
|
290
|
+
BROAD_PATTERN_REGEXES,
|
|
291
|
+
SPECIFIC_DIRS,
|
|
292
|
+
HIGH_RISK_INDICATORS,
|
|
293
|
+
};
|