@ngxtm/devkit 2.1.0 → 3.0.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/cli/detect.js +292 -0
- package/cli/index.js +204 -92
- package/cli/init.js +245 -0
- package/cli/update.js +243 -0
- package/cli/utils.js +195 -0
- package/package.json +16 -20
- package/rules-index.json +76 -0
- package/scripts/generate-index.js +223 -0
- package/scripts/merge-commands.js +290 -0
- package/scripts/organize-rules.js +226 -0
- package/templates/base/hooks/lib/ck-config-utils.cjs +769 -0
- package/templates/base/hooks/lib/ck-paths.cjs +110 -0
- package/templates/base/hooks/lib/colors.cjs +95 -0
- package/templates/base/hooks/lib/config-counter.cjs +103 -0
- package/templates/base/hooks/lib/context-builder.cjs +600 -0
- package/templates/base/hooks/lib/context-tracker.cjs +335 -0
- package/templates/base/hooks/lib/privacy-checker.cjs +297 -0
- package/templates/base/hooks/lib/project-detector.cjs +430 -0
- package/templates/base/hooks/lib/scout-checker.cjs +172 -0
- package/templates/base/hooks/lib/transcript-parser.cjs +164 -0
- package/templates/base/hooks/privacy-block.cjs +145 -0
- package/agents/backend-engineer.md +0 -154
- package/agents/brainstormer.md +0 -169
- package/agents/business-analyst.md +0 -166
- package/agents/database-architect.md +0 -159
- package/agents/debugger.md +0 -155
- package/agents/designer.md +0 -150
- package/agents/devops-engineer.md +0 -155
- package/agents/docs-manager.md +0 -171
- package/agents/frontend-engineer.md +0 -159
- package/agents/game-engineer.md +0 -148
- package/agents/mobile-engineer.md +0 -149
- package/agents/performance-engineer.md +0 -152
- package/agents/planner.md +0 -161
- package/agents/project-manager.md +0 -160
- package/agents/researcher.md +0 -146
- package/agents/reviewer.md +0 -155
- package/agents/scouter.md +0 -157
- package/agents/security-engineer.md +0 -154
- package/agents/tech-lead.md +0 -159
- package/agents/tester.md +0 -157
- package/agents-claudekit/brainstormer.md +0 -113
- package/agents-claudekit/code-reviewer.md +0 -157
- package/agents-claudekit/code-simplifier.md +0 -42
- package/agents-claudekit/copywriter.md +0 -110
- package/agents-claudekit/database-admin.md +0 -92
- package/agents-claudekit/debugger.md +0 -137
- package/agents-claudekit/docs-manager.md +0 -208
- package/agents-claudekit/fullstack-developer.md +0 -95
- package/agents-claudekit/git-manager.md +0 -394
- package/agents-claudekit/journal-writer.md +0 -113
- package/agents-claudekit/mcp-manager.md +0 -93
- package/agents-claudekit/planner.md +0 -108
- package/agents-claudekit/project-manager.md +0 -125
- package/agents-claudekit/researcher.md +0 -38
- package/agents-claudekit/scout-external.md +0 -141
- package/agents-claudekit/scout.md +0 -107
- package/agents-claudekit/tester.md +0 -105
- package/agents-claudekit/ui-ux-designer.md +0 -236
- package/commands/ask.md +0 -64
- package/commands/brainstorm.md +0 -64
- package/commands/code.md +0 -64
- package/commands/cook.md +0 -64
- package/commands/debug.md +0 -64
- package/commands/design/fast.md +0 -134
- package/commands/fix/fast.md +0 -84
- package/commands/fix/hard.md +0 -116
- package/commands/fix.md +0 -64
- package/commands/plan/fast.md +0 -78
- package/commands/plan/hard.md +0 -131
- package/commands/plan.md +0 -64
- package/commands/test.md +0 -64
- package/matrix-skills/_index.yaml +0 -275
- package/matrix-skills/ai-ml.yaml +0 -353
- package/matrix-skills/architecture.yaml +0 -93
- package/matrix-skills/backend.yaml +0 -280
- package/matrix-skills/cloud.yaml +0 -112
- package/matrix-skills/data.yaml +0 -74
- package/matrix-skills/design.yaml +0 -98
- package/matrix-skills/devops.yaml +0 -200
- package/matrix-skills/frontend.yaml +0 -200
- package/matrix-skills/gaming.yaml +0 -39
- package/matrix-skills/languages.yaml +0 -160
- package/matrix-skills/management.yaml +0 -50
- package/matrix-skills/mcp.yaml +0 -82
- package/matrix-skills/mobile.yaml +0 -85
- package/matrix-skills/performance.yaml +0 -23
- package/matrix-skills/planning.yaml +0 -117
- package/matrix-skills/quality.yaml +0 -195
- package/matrix-skills/research.yaml +0 -106
- package/matrix-skills/security.yaml +0 -293
- package/matrix-skills/tools.yaml +0 -352
- package/output-styles/coding-level-0-eli5.md +0 -103
- package/output-styles/coding-level-1-junior.md +0 -124
- package/output-styles/coding-level-2-mid.md +0 -146
- package/output-styles/coding-level-3-senior.md +0 -148
- package/output-styles/coding-level-4-lead.md +0 -159
- package/output-styles/coding-level-5-god.md +0 -91
- package/rules/README.md +0 -141
- package/rules/metadata.json +0 -54
- package/settings.json +0 -3
- package/statusline.cjs +0 -500
- package/statusline.ps1 +0 -307
- package/statusline.sh +0 -237
- package/workflows/development-rules.md +0 -42
- package/workflows/documentation-management.md +0 -121
- package/workflows/orchestration-protocol.md +0 -16
- package/workflows/primary-workflow.md +0 -45
- /package/{commands → merged-commands}/ask/fast.md +0 -0
- /package/{commands → merged-commands}/ask/hard.md +0 -0
- /package/{commands-claudekit → merged-commands}/ask.md +0 -0
- /package/{commands → merged-commands}/auto.md +0 -0
- /package/{commands-claudekit → merged-commands}/bootstrap/auto/fast.md +0 -0
- /package/{commands-claudekit → merged-commands}/bootstrap/auto/parallel.md +0 -0
- /package/{commands-claudekit → merged-commands}/bootstrap/auto.md +0 -0
- /package/{commands-claudekit → merged-commands}/bootstrap.md +0 -0
- /package/{commands → merged-commands}/brainstorm/fast.md +0 -0
- /package/{commands → merged-commands}/brainstorm/hard.md +0 -0
- /package/{commands-claudekit → merged-commands}/brainstorm.md +0 -0
- /package/{commands-claudekit → merged-commands}/ck-help.md +0 -0
- /package/{commands-claudekit → merged-commands}/code/auto.md +0 -0
- /package/{commands → merged-commands}/code/fast.md +0 -0
- /package/{commands → merged-commands}/code/hard.md +0 -0
- /package/{commands-claudekit → merged-commands}/code/no-test.md +0 -0
- /package/{commands-claudekit → merged-commands}/code/parallel.md +0 -0
- /package/{commands-claudekit → merged-commands}/code.md +0 -0
- /package/{commands-claudekit → merged-commands}/coding-level.md +0 -0
- /package/{commands-claudekit → merged-commands}/content/cro.md +0 -0
- /package/{commands-claudekit → merged-commands}/content/enhance.md +0 -0
- /package/{commands-claudekit → merged-commands}/content/fast.md +0 -0
- /package/{commands-claudekit → merged-commands}/content/good.md +0 -0
- /package/{commands-claudekit → merged-commands}/cook/auto/fast.md +0 -0
- /package/{commands-claudekit → merged-commands}/cook/auto/parallel.md +0 -0
- /package/{commands-claudekit → merged-commands}/cook/auto.md +0 -0
- /package/{commands → merged-commands}/cook/fast.md +0 -0
- /package/{commands → merged-commands}/cook/hard.md +0 -0
- /package/{commands-claudekit → merged-commands}/cook.md +0 -0
- /package/{commands → merged-commands}/debug/fast.md +0 -0
- /package/{commands → merged-commands}/debug/hard.md +0 -0
- /package/{commands-claudekit → merged-commands}/debug.md +0 -0
- /package/{commands → merged-commands}/deploy/check.md +0 -0
- /package/{commands → merged-commands}/deploy/preview.md +0 -0
- /package/{commands → merged-commands}/deploy/production.md +0 -0
- /package/{commands → merged-commands}/deploy/rollback.md +0 -0
- /package/{commands → merged-commands}/deploy.md +0 -0
- /package/{commands-claudekit → merged-commands}/design/3d.md +0 -0
- /package/{commands-claudekit → merged-commands}/design/describe.md +0 -0
- /package/{commands-claudekit → merged-commands}/design/fast.md +0 -0
- /package/{commands-claudekit → merged-commands}/design/good.md +0 -0
- /package/{commands → merged-commands}/design/hard.md +0 -0
- /package/{commands-claudekit → merged-commands}/design/screenshot.md +0 -0
- /package/{commands-claudekit → merged-commands}/design/video.md +0 -0
- /package/{commands → merged-commands}/design.md +0 -0
- /package/{commands → merged-commands}/docs/audit.md +0 -0
- /package/{commands → merged-commands}/docs/business.md +0 -0
- /package/{commands → merged-commands}/docs/core.md +0 -0
- /package/{commands-claudekit → merged-commands}/docs/init.md +0 -0
- /package/{commands-claudekit → merged-commands}/docs/summarize.md +0 -0
- /package/{commands-claudekit → merged-commands}/docs/update.md +0 -0
- /package/{commands → merged-commands}/docs.md +0 -0
- /package/{commands-claudekit → merged-commands}/fix/ci.md +0 -0
- /package/{commands-claudekit → merged-commands}/fix/fast.md +0 -0
- /package/{commands-claudekit → merged-commands}/fix/hard.md +0 -0
- /package/{commands-claudekit → merged-commands}/fix/logs.md +0 -0
- /package/{commands-claudekit → merged-commands}/fix/parallel.md +0 -0
- /package/{commands-claudekit → merged-commands}/fix/test.md +0 -0
- /package/{commands-claudekit → merged-commands}/fix/types.md +0 -0
- /package/{commands-claudekit → merged-commands}/fix/ui.md +0 -0
- /package/{commands-claudekit → merged-commands}/fix.md +0 -0
- /package/{commands-claudekit → merged-commands}/git/cm.md +0 -0
- /package/{commands-claudekit → merged-commands}/git/cp.md +0 -0
- /package/{commands-claudekit → merged-commands}/git/merge.md +0 -0
- /package/{commands-claudekit → merged-commands}/git/pr.md +0 -0
- /package/{commands-claudekit → merged-commands}/integrate/polar.md +0 -0
- /package/{commands-claudekit → merged-commands}/integrate/sepay.md +0 -0
- /package/{commands-claudekit → merged-commands}/journal.md +0 -0
- /package/{commands-claudekit → merged-commands}/kanban.md +0 -0
- /package/{commands-claudekit → merged-commands}/plan/archive.md +0 -0
- /package/{commands-claudekit → merged-commands}/plan/ci.md +0 -0
- /package/{commands-claudekit → merged-commands}/plan/cro.md +0 -0
- /package/{commands-claudekit → merged-commands}/plan/fast.md +0 -0
- /package/{commands-claudekit → merged-commands}/plan/hard.md +0 -0
- /package/{commands-claudekit → merged-commands}/plan/parallel.md +0 -0
- /package/{commands-claudekit → merged-commands}/plan/two.md +0 -0
- /package/{commands-claudekit → merged-commands}/plan/validate.md +0 -0
- /package/{commands-claudekit → merged-commands}/plan.md +0 -0
- /package/{commands-claudekit → merged-commands}/preview.md +0 -0
- /package/{commands-claudekit → merged-commands}/review/codebase/parallel.md +0 -0
- /package/{commands-claudekit → merged-commands}/review/codebase.md +0 -0
- /package/{commands → merged-commands}/review/fast.md +0 -0
- /package/{commands → merged-commands}/review/hard.md +0 -0
- /package/{commands → merged-commands}/review.md +0 -0
- /package/{commands-claudekit → merged-commands}/scout/ext.md +0 -0
- /package/{commands-claudekit → merged-commands}/scout.md +0 -0
- /package/{commands-claudekit → merged-commands}/skill/add.md +0 -0
- /package/{commands-claudekit → merged-commands}/skill/create.md +0 -0
- /package/{commands-claudekit → merged-commands}/skill/fix-logs.md +0 -0
- /package/{commands-claudekit → merged-commands}/skill/optimize/auto.md +0 -0
- /package/{commands-claudekit → merged-commands}/skill/optimize.md +0 -0
- /package/{commands-claudekit → merged-commands}/skill/plan.md +0 -0
- /package/{commands-claudekit → merged-commands}/skill/update.md +0 -0
- /package/{commands → merged-commands}/test/fast.md +0 -0
- /package/{commands → merged-commands}/test/hard.md +0 -0
- /package/{commands-claudekit → merged-commands}/test/ui.md +0 -0
- /package/{commands-claudekit → merged-commands}/test.md +0 -0
- /package/{commands-claudekit → merged-commands}/use-mcp.md +0 -0
- /package/{commands-claudekit → merged-commands}/watzup.md +0 -0
- /package/{commands-claudekit → merged-commands}/worktree.md +0 -0
- /package/{rules → templates/dart/rules}/dart/best-practices/SKILL.md +0 -0
- /package/{rules → templates/dart/rules}/dart/language/SKILL.md +0 -0
- /package/{rules → templates/dart/rules}/dart/tooling/SKILL.md +0 -0
- /package/{rules → templates/flutter/rules}/flutter/auto-route-navigation/SKILL.md +0 -0
- /package/{rules → templates/flutter/rules}/flutter/auto-route-navigation/references/REFERENCE.md +0 -0
- /package/{rules → templates/flutter/rules}/flutter/auto-route-navigation/references/router-config.md +0 -0
- /package/{rules → templates/flutter/rules}/flutter/bloc-state-management/SKILL.md +0 -0
- /package/{rules → templates/flutter/rules}/flutter/bloc-state-management/references/REFERENCE.md +0 -0
- /package/{rules → templates/flutter/rules}/flutter/bloc-state-management/references/auth-bloc-example.md +0 -0
- /package/{rules → templates/flutter/rules}/flutter/bloc-state-management/references/equatable-usage.md +0 -0
- /package/{rules → templates/flutter/rules}/flutter/bloc-state-management/references/property-based-state.md +0 -0
- /package/{rules → templates/flutter/rules}/flutter/bloc.rule.md +0 -0
- /package/{rules → templates/flutter/rules}/flutter/cicd/SKILL.md +0 -0
- /package/{rules → templates/flutter/rules}/flutter/cicd/references/advanced-workflow.md +0 -0
- /package/{rules → templates/flutter/rules}/flutter/cicd/references/fastlane.md +0 -0
- /package/{rules → templates/flutter/rules}/flutter/cicd/references/github-actions.md +0 -0
- /package/{rules → templates/flutter/rules}/flutter/dependency-injection/SKILL.md +0 -0
- /package/{rules → templates/flutter/rules}/flutter/dependency-injection/references/REFERENCE.md +0 -0
- /package/{rules → templates/flutter/rules}/flutter/dependency-injection/references/modules.md +0 -0
- /package/{rules → templates/flutter/rules}/flutter/error-handling/SKILL.md +0 -0
- /package/{rules → templates/flutter/rules}/flutter/error-handling/references/REFERENCE.md +0 -0
- /package/{rules → templates/flutter/rules}/flutter/error-handling/references/error-mapping.md +0 -0
- /package/{rules → templates/flutter/rules}/flutter/feature-based-clean-architecture/SKILL.md +0 -0
- /package/{rules → templates/flutter/rules}/flutter/feature-based-clean-architecture/references/REFERENCE.md +0 -0
- /package/{rules → templates/flutter/rules}/flutter/feature-based-clean-architecture/references/folder-structure.md +0 -0
- /package/{rules → templates/flutter/rules}/flutter/getx-navigation/SKILL.md +0 -0
- /package/{rules → templates/flutter/rules}/flutter/getx-navigation/references/app-pages.md +0 -0
- /package/{rules → templates/flutter/rules}/flutter/getx-navigation/references/middleware-example.md +0 -0
- /package/{rules → templates/flutter/rules}/flutter/getx-state-management/SKILL.md +0 -0
- /package/{rules → templates/flutter/rules}/flutter/getx-state-management/references/binding-example.md +0 -0
- /package/{rules → templates/flutter/rules}/flutter/getx-state-management/references/reactive-vs-simple.md +0 -0
- /package/{rules → templates/flutter/rules}/flutter/go-router-navigation/SKILL.md +0 -0
- /package/{rules → templates/flutter/rules}/flutter/idiomatic-flutter/SKILL.md +0 -0
- /package/{rules → templates/flutter/rules}/flutter/layer-based-clean-architecture/SKILL.md +0 -0
- /package/{rules → templates/flutter/rules}/flutter/layer-based-clean-architecture/references/REFERENCE.md +0 -0
- /package/{rules → templates/flutter/rules}/flutter/layer-based-clean-architecture/references/repository-mapping.md +0 -0
- /package/{rules → templates/flutter/rules}/flutter/localization/SKILL.md +0 -0
- /package/{rules → templates/flutter/rules}/flutter/localization/references/REFERENCE.md +0 -0
- /package/{rules → templates/flutter/rules}/flutter/localization/references/sheet-loader.md +0 -0
- /package/{rules → templates/flutter/rules}/flutter/navigator-v1-navigation/SKILL.md +0 -0
- /package/{rules → templates/flutter/rules}/flutter/navigator-v1-navigation/references/on-generate-route.md +0 -0
- /package/{rules → templates/flutter/rules}/flutter/performance/SKILL.md +0 -0
- /package/{rules → templates/flutter/rules}/flutter/retrofit-networking/SKILL.md +0 -0
- /package/{rules → templates/flutter/rules}/flutter/retrofit-networking/references/REFERENCE.md +0 -0
- /package/{rules → templates/flutter/rules}/flutter/retrofit-networking/references/token-refresh.md +0 -0
- /package/{rules → templates/flutter/rules}/flutter/riverpod-state-management/SKILL.md +0 -0
- /package/{rules → templates/flutter/rules}/flutter/riverpod-state-management/references/architecture.md +0 -0
- /package/{rules → templates/flutter/rules}/flutter/riverpod-state-management/references/best-practices.md +0 -0
- /package/{rules → templates/flutter/rules}/flutter/riverpod-state-management/references/testing.md +0 -0
- /package/{rules → templates/flutter/rules}/flutter/riverpod.rule.md +0 -0
- /package/{rules → templates/flutter/rules}/flutter/security/SKILL.md +0 -0
- /package/{rules → templates/flutter/rules}/flutter/security/references/REFERENCE.md +0 -0
- /package/{rules → templates/flutter/rules}/flutter/security/references/network-security.md +0 -0
- /package/{rules → templates/flutter/rules}/flutter/testing/SKILL.md +0 -0
- /package/{rules → templates/flutter/rules}/flutter/testing/references/REFERENCE.md +0 -0
- /package/{rules → templates/flutter/rules}/flutter/testing/references/bloc-testing.md +0 -0
- /package/{rules → templates/flutter/rules}/flutter/testing/references/integration-testing.md +0 -0
- /package/{rules → templates/flutter/rules}/flutter/testing/references/robot-pattern.md +0 -0
- /package/{rules → templates/flutter/rules}/flutter/testing/references/unit-testing.md +0 -0
- /package/{rules → templates/flutter/rules}/flutter/testing/references/widget-testing.md +0 -0
- /package/{rules → templates/flutter/rules}/flutter/widgets/SKILL.md +0 -0
- /package/{rules → templates/golang/rules}/golang/chi-router/SKILL.md +0 -0
- /package/{rules → templates/golang/rules}/golang/chi-router/references/REFERENCE.md +0 -0
- /package/{rules → templates/golang/rules}/golang/chi-router/references/routing-patterns.md +0 -0
- /package/{rules → templates/golang/rules}/golang/cobra-cli/SKILL.md +0 -0
- /package/{rules → templates/golang/rules}/golang/cobra-cli/references/REFERENCE.md +0 -0
- /package/{rules → templates/golang/rules}/golang/cobra-cli/references/command-patterns.md +0 -0
- /package/{rules → templates/golang/rules}/golang/core/SKILL.md +0 -0
- /package/{rules → templates/golang/rules}/golang/core/references/REFERENCE.md +0 -0
- /package/{rules → templates/golang/rules}/golang/core/references/concurrency-patterns.md +0 -0
- /package/{rules → templates/golang/rules}/golang/core/references/error-handling.md +0 -0
- /package/{rules → templates/golang/rules}/golang/echo-framework/SKILL.md +0 -0
- /package/{rules → templates/golang/rules}/golang/echo-framework/references/REFERENCE.md +0 -0
- /package/{rules → templates/golang/rules}/golang/echo-framework/references/middleware-patterns.md +0 -0
- /package/{rules → templates/golang/rules}/golang/echo-framework/references/routing-patterns.md +0 -0
- /package/{rules → templates/golang/rules}/golang/ent-orm/SKILL.md +0 -0
- /package/{rules → templates/golang/rules}/golang/ent-orm/references/REFERENCE.md +0 -0
- /package/{rules → templates/golang/rules}/golang/ent-orm/references/schema-patterns.md +0 -0
- /package/{rules → templates/golang/rules}/golang/fiber-framework/SKILL.md +0 -0
- /package/{rules → templates/golang/rules}/golang/fiber-framework/references/REFERENCE.md +0 -0
- /package/{rules → templates/golang/rules}/golang/fiber-framework/references/routing-patterns.md +0 -0
- /package/{rules → templates/golang/rules}/golang/gin-framework/SKILL.md +0 -0
- /package/{rules → templates/golang/rules}/golang/gin-framework/references/REFERENCE.md +0 -0
- /package/{rules → templates/golang/rules}/golang/gin-framework/references/middleware-patterns.md +0 -0
- /package/{rules → templates/golang/rules}/golang/gorm-orm/SKILL.md +0 -0
- /package/{rules → templates/golang/rules}/golang/gorm-orm/references/REFERENCE.md +0 -0
- /package/{rules → templates/golang/rules}/golang/gorm-orm/references/model-definitions.md +0 -0
- /package/{rules → templates/golang/rules}/golang/gorm-orm/references/query-patterns.md +0 -0
- /package/{rules → templates/golang/rules}/golang/grpc/SKILL.md +0 -0
- /package/{rules → templates/golang/rules}/golang/grpc/references/REFERENCE.md +0 -0
- /package/{rules → templates/golang/rules}/golang/grpc/references/service-patterns.md +0 -0
- /package/{rules → templates/golang/rules}/golang/testify/SKILL.md +0 -0
- /package/{rules → templates/golang/rules}/golang/testify/references/REFERENCE.md +0 -0
- /package/{rules → templates/golang/rules}/golang/testify/references/assert-patterns.md +0 -0
- /package/{rules → templates/golang/rules}/golang/validator/SKILL.md +0 -0
- /package/{rules → templates/golang/rules}/golang/validator/references/REFERENCE.md +0 -0
- /package/{rules → templates/golang/rules}/golang/validator/references/validation-tags.md +0 -0
- /package/{rules → templates/golang/rules}/golang/viper-config/SKILL.md +0 -0
- /package/{rules → templates/golang/rules}/golang/viper-config/references/REFERENCE.md +0 -0
- /package/{rules → templates/golang/rules}/golang/viper-config/references/config-loading.md +0 -0
- /package/{rules → templates/golang/rules}/golang/wire-di/SKILL.md +0 -0
- /package/{rules → templates/golang/rules}/golang/wire-di/references/REFERENCE.md +0 -0
- /package/{rules → templates/golang/rules}/golang/wire-di/references/provider-patterns.md +0 -0
- /package/{rules → templates/golang/rules}/golang/zap-logging/SKILL.md +0 -0
- /package/{rules → templates/golang/rules}/golang/zap-logging/references/REFERENCE.md +0 -0
- /package/{rules → templates/golang/rules}/golang/zap-logging/references/logger-config.md +0 -0
- /package/{rules → templates/java/rules}/java/build-gradle/SKILL.md +0 -0
- /package/{rules → templates/java/rules}/java/build-gradle/references/REFERENCE.md +0 -0
- /package/{rules → templates/java/rules}/java/build-gradle/references/kotlin-dsl.md +0 -0
- /package/{rules → templates/java/rules}/java/build-gradle/references/task-configuration.md +0 -0
- /package/{rules → templates/java/rules}/java/build-maven/SKILL.md +0 -0
- /package/{rules → templates/java/rules}/java/build-maven/references/REFERENCE.md +0 -0
- /package/{rules → templates/java/rules}/java/build-maven/references/dependency-management.md +0 -0
- /package/{rules → templates/java/rules}/java/build-maven/references/lifecycle-phases.md +0 -0
- /package/{rules → templates/java/rules}/java/graalvm-native/SKILL.md +0 -0
- /package/{rules → templates/java/rules}/java/graalvm-native/references/REFERENCE.md +0 -0
- /package/{rules → templates/java/rules}/java/java-collections-streams/SKILL.md +0 -0
- /package/{rules → templates/java/rules}/java/java-collections-streams/references/REFERENCE.md +0 -0
- /package/{rules → templates/java/rules}/java/java-collections-streams/references/collectors-patterns.md +0 -0
- /package/{rules → templates/java/rules}/java/java-collections-streams/references/stream-pipelines.md +0 -0
- /package/{rules → templates/java/rules}/java/java-concurrency/SKILL.md +0 -0
- /package/{rules → templates/java/rules}/java/java-concurrency/references/REFERENCE.md +0 -0
- /package/{rules → templates/java/rules}/java/java-concurrency/references/completable-future.md +0 -0
- /package/{rules → templates/java/rules}/java/java-concurrency/references/executor-patterns.md +0 -0
- /package/{rules → templates/java/rules}/java/java-concurrency/references/virtual-threads.md +0 -0
- /package/{rules → templates/java/rules}/java/java-core-language/SKILL.md +0 -0
- /package/{rules → templates/java/rules}/java/java-core-language/references/REFERENCE.md +0 -0
- /package/{rules → templates/java/rules}/java/java-core-language/references/jvm-memory-model.md +0 -0
- /package/{rules → templates/java/rules}/java/java-core-language/references/modern-java-features.md +0 -0
- /package/{rules → templates/java/rules}/java/java-project-structure/SKILL.md +0 -0
- /package/{rules → templates/java/rules}/java/java-project-structure/references/REFERENCE.md +0 -0
- /package/{rules → templates/java/rules}/java/java-project-structure/references/maven-project-layout.md +0 -0
- /package/{rules → templates/java/rules}/java/java-project-structure/references/module-system.md +0 -0
- /package/{rules → templates/java/rules}/java/micronaut-core/SKILL.md +0 -0
- /package/{rules → templates/java/rules}/java/micronaut-core/references/REFERENCE.md +0 -0
- /package/{rules → templates/java/rules}/java/micronaut-reactive/SKILL.md +0 -0
- /package/{rules → templates/java/rules}/java/micronaut-reactive/references/REFERENCE.md +0 -0
- /package/{rules → templates/java/rules}/java/quarkus-core/SKILL.md +0 -0
- /package/{rules → templates/java/rules}/java/quarkus-core/references/REFERENCE.md +0 -0
- /package/{rules → templates/java/rules}/java/quarkus-reactive/SKILL.md +0 -0
- /package/{rules → templates/java/rules}/java/quarkus-reactive/references/REFERENCE.md +0 -0
- /package/{rules → templates/java/rules}/java/spring-batch/SKILL.md +0 -0
- /package/{rules → templates/java/rules}/java/spring-batch/references/REFERENCE.md +0 -0
- /package/{rules → templates/java/rules}/java/spring-boot-architecture/SKILL.md +0 -0
- /package/{rules → templates/java/rules}/java/spring-boot-architecture/references/REFERENCE.md +0 -0
- /package/{rules → templates/java/rules}/java/spring-boot-architecture/references/auto-configuration.md +0 -0
- /package/{rules → templates/java/rules}/java/spring-boot-architecture/references/configuration-properties.md +0 -0
- /package/{rules → templates/java/rules}/java/spring-boot-web/SKILL.md +0 -0
- /package/{rules → templates/java/rules}/java/spring-boot-web/references/REFERENCE.md +0 -0
- /package/{rules → templates/java/rules}/java/spring-cloud/SKILL.md +0 -0
- /package/{rules → templates/java/rules}/java/spring-cloud/references/REFERENCE.md +0 -0
- /package/{rules → templates/java/rules}/java/spring-data-jpa/SKILL.md +0 -0
- /package/{rules → templates/java/rules}/java/spring-data-jpa/references/REFERENCE.md +0 -0
- /package/{rules → templates/java/rules}/java/spring-security/SKILL.md +0 -0
- /package/{rules → templates/java/rules}/java/spring-security/references/REFERENCE.md +0 -0
- /package/{rules → templates/java/rules}/java/spring-security/references/jwt-auth-flow.md +0 -0
- /package/{rules → templates/java/rules}/java/testing-junit-mockito/SKILL.md +0 -0
- /package/{rules → templates/java/rules}/java/testing-junit-mockito/references/REFERENCE.md +0 -0
- /package/{rules → templates/java/rules}/java/testing-junit-mockito/references/junit5-patterns.md +0 -0
- /package/{rules → templates/java/rules}/java/testing-junit-mockito/references/mockito-patterns.md +0 -0
- /package/{rules → templates/java/rules}/java/testing-junit-mockito/references/spring-boot-testing.md +0 -0
- /package/{rules → templates/javascript/rules}/javascript/best-practices/SKILL.md +0 -0
- /package/{rules → templates/javascript/rules}/javascript/best-practices/references/REFERENCE.md +0 -0
- /package/{rules → templates/javascript/rules}/javascript/language/SKILL.md +0 -0
- /package/{rules → templates/javascript/rules}/javascript/language/references/REFERENCE.md +0 -0
- /package/{rules → templates/javascript/rules}/javascript/tooling/SKILL.md +0 -0
- /package/{rules → templates/javascript/rules}/javascript/tooling/references/REFERENCE.md +0 -0
- /package/{rules → templates/nestjs/rules}/nestjs/api-standards/SKILL.md +0 -0
- /package/{rules → templates/nestjs/rules}/nestjs/api-standards/references/pagination-wrapper.md +0 -0
- /package/{rules → templates/nestjs/rules}/nestjs/architecture/SKILL.md +0 -0
- /package/{rules → templates/nestjs/rules}/nestjs/architecture/references/dynamic-module.md +0 -0
- /package/{rules → templates/nestjs/rules}/nestjs/caching/SKILL.md +0 -0
- /package/{rules → templates/nestjs/rules}/nestjs/caching/references/REFERENCE.md +0 -0
- /package/{rules → templates/nestjs/rules}/nestjs/caching/references/cache-patterns.md +0 -0
- /package/{rules → templates/nestjs/rules}/nestjs/configuration/SKILL.md +0 -0
- /package/{rules → templates/nestjs/rules}/nestjs/configuration/references/REFERENCE.md +0 -0
- /package/{rules → templates/nestjs/rules}/nestjs/configuration/references/config-patterns.md +0 -0
- /package/{rules → templates/nestjs/rules}/nestjs/controllers-services/SKILL.md +0 -0
- /package/{rules → templates/nestjs/rules}/nestjs/controllers-services/references/REFERENCE.md +0 -0
- /package/{rules → templates/nestjs/rules}/nestjs/controllers-services/references/controller-patterns.md +0 -0
- /package/{rules → templates/nestjs/rules}/nestjs/controllers-services/references/service-patterns.md +0 -0
- /package/{rules → templates/nestjs/rules}/nestjs/database/SKILL.md +0 -0
- /package/{rules → templates/nestjs/rules}/nestjs/database/references/REFERENCE.md +0 -0
- /package/{rules → templates/nestjs/rules}/nestjs/database/references/typeorm-patterns.md +0 -0
- /package/{rules → templates/nestjs/rules}/nestjs/deployment/SKILL.md +0 -0
- /package/{rules → templates/nestjs/rules}/nestjs/deployment/references/REFERENCE.md +0 -0
- /package/{rules → templates/nestjs/rules}/nestjs/deployment/references/deployment-patterns.md +0 -0
- /package/{rules → templates/nestjs/rules}/nestjs/documentation/SKILL.md +0 -0
- /package/{rules → templates/nestjs/rules}/nestjs/documentation/references/REFERENCE.md +0 -0
- /package/{rules → templates/nestjs/rules}/nestjs/documentation/references/swagger-patterns.md +0 -0
- /package/{rules → templates/nestjs/rules}/nestjs/error-handling/SKILL.md +0 -0
- /package/{rules → templates/nestjs/rules}/nestjs/error-handling/references/REFERENCE.md +0 -0
- /package/{rules → templates/nestjs/rules}/nestjs/error-handling/references/exception-filters.md +0 -0
- /package/{rules → templates/nestjs/rules}/nestjs/file-uploads/SKILL.md +0 -0
- /package/{rules → templates/nestjs/rules}/nestjs/file-uploads/references/REFERENCE.md +0 -0
- /package/{rules → templates/nestjs/rules}/nestjs/file-uploads/references/upload-patterns.md +0 -0
- /package/{rules → templates/nestjs/rules}/nestjs/observability/SKILL.md +0 -0
- /package/{rules → templates/nestjs/rules}/nestjs/observability/references/REFERENCE.md +0 -0
- /package/{rules → templates/nestjs/rules}/nestjs/observability/references/logging-metrics.md +0 -0
- /package/{rules → templates/nestjs/rules}/nestjs/performance/SKILL.md +0 -0
- /package/{rules → templates/nestjs/rules}/nestjs/performance/references/REFERENCE.md +0 -0
- /package/{rules → templates/nestjs/rules}/nestjs/performance/references/performance-patterns.md +0 -0
- /package/{rules → templates/nestjs/rules}/nestjs/real-time/SKILL.md +0 -0
- /package/{rules → templates/nestjs/rules}/nestjs/real-time/references/REFERENCE.md +0 -0
- /package/{rules → templates/nestjs/rules}/nestjs/real-time/references/websocket-patterns.md +0 -0
- /package/{rules → templates/nestjs/rules}/nestjs/scheduling/SKILL.md +0 -0
- /package/{rules → templates/nestjs/rules}/nestjs/scheduling/references/REFERENCE.md +0 -0
- /package/{rules → templates/nestjs/rules}/nestjs/scheduling/references/scheduling-patterns.md +0 -0
- /package/{rules → templates/nestjs/rules}/nestjs/search/SKILL.md +0 -0
- /package/{rules → templates/nestjs/rules}/nestjs/search/references/REFERENCE.md +0 -0
- /package/{rules → templates/nestjs/rules}/nestjs/search/references/search-patterns.md +0 -0
- /package/{rules → templates/nestjs/rules}/nestjs/security/SKILL.md +0 -0
- /package/{rules → templates/nestjs/rules}/nestjs/security/references/REFERENCE.md +0 -0
- /package/{rules → templates/nestjs/rules}/nestjs/security/references/authentication.md +0 -0
- /package/{rules → templates/nestjs/rules}/nestjs/testing/SKILL.md +0 -0
- /package/{rules → templates/nestjs/rules}/nestjs/testing/references/REFERENCE.md +0 -0
- /package/{rules → templates/nestjs/rules}/nestjs/testing/references/unit-testing.md +0 -0
- /package/{rules → templates/nestjs/rules}/nestjs/transport/SKILL.md +0 -0
- /package/{rules → templates/nestjs/rules}/nestjs/transport/references/REFERENCE.md +0 -0
- /package/{rules → templates/nestjs/rules}/nestjs/transport/references/microservices-patterns.md +0 -0
- /package/{rules → templates/nextjs/rules}/nextjs/app-router/SKILL.md +0 -0
- /package/{rules → templates/nextjs/rules}/nextjs/app-router/references/REFERENCE.md +0 -0
- /package/{rules → templates/nextjs/rules}/nextjs/app-router/references/routing-patterns.md +0 -0
- /package/{rules → templates/nextjs/rules}/nextjs/architecture/SKILL.md +0 -0
- /package/{rules → templates/nextjs/rules}/nextjs/architecture/references/fsd-structure.md +0 -0
- /package/{rules → templates/nextjs/rules}/nextjs/authentication/SKILL.md +0 -0
- /package/{rules → templates/nextjs/rules}/nextjs/authentication/references/auth-implementation.md +0 -0
- /package/{rules → templates/nextjs/rules}/nextjs/caching/SKILL.md +0 -0
- /package/{rules → templates/nextjs/rules}/nextjs/caching/references/REFERENCE.md +0 -0
- /package/{rules → templates/nextjs/rules}/nextjs/caching/references/cache-strategies.md +0 -0
- /package/{rules → templates/nextjs/rules}/nextjs/data-access-layer/SKILL.md +0 -0
- /package/{rules → templates/nextjs/rules}/nextjs/data-access-layer/references/patterns.md +0 -0
- /package/{rules → templates/nextjs/rules}/nextjs/data-fetching/SKILL.md +0 -0
- /package/{rules → templates/nextjs/rules}/nextjs/data-fetching/references/REFERENCE.md +0 -0
- /package/{rules → templates/nextjs/rules}/nextjs/data-fetching/references/fetch-patterns.md +0 -0
- /package/{rules → templates/nextjs/rules}/nextjs/internationalization/SKILL.md +0 -0
- /package/{rules → templates/nextjs/rules}/nextjs/internationalization/references/REFERENCE.md +0 -0
- /package/{rules → templates/nextjs/rules}/nextjs/internationalization/references/i18n-patterns.md +0 -0
- /package/{rules → templates/nextjs/rules}/nextjs/optimization/SKILL.md +0 -0
- /package/{rules → templates/nextjs/rules}/nextjs/optimization/references/REFERENCE.md +0 -0
- /package/{rules → templates/nextjs/rules}/nextjs/optimization/references/optimization-patterns.md +0 -0
- /package/{rules → templates/nextjs/rules}/nextjs/rendering/SKILL.md +0 -0
- /package/{rules → templates/nextjs/rules}/nextjs/rendering/references/REFERENCE.md +0 -0
- /package/{rules → templates/nextjs/rules}/nextjs/rendering/references/rendering-modes.md +0 -0
- /package/{rules → templates/nextjs/rules}/nextjs/server-actions/SKILL.md +0 -0
- /package/{rules → templates/nextjs/rules}/nextjs/server-actions/references/REFERENCE.md +0 -0
- /package/{rules → templates/nextjs/rules}/nextjs/server-actions/references/action-patterns.md +0 -0
- /package/{rules → templates/nextjs/rules}/nextjs/server-components/SKILL.md +0 -0
- /package/{rules → templates/nextjs/rules}/nextjs/server-components/references/REFERENCE.md +0 -0
- /package/{rules → templates/nextjs/rules}/nextjs/server-components/references/component-patterns.md +0 -0
- /package/{rules → templates/nextjs/rules}/nextjs/state-management/SKILL.md +0 -0
- /package/{rules → templates/nextjs/rules}/nextjs/state-management/references/REFERENCE.md +0 -0
- /package/{rules → templates/nextjs/rules}/nextjs/state-management/references/state-patterns.md +0 -0
- /package/{rules → templates/nextjs/rules}/nextjs/styling/SKILL.md +0 -0
- /package/{rules → templates/nextjs/rules}/nextjs/styling/references/implementation.md +0 -0
- /package/{rules → templates/react/rules}/react/component-patterns/SKILL.md +0 -0
- /package/{rules → templates/react/rules}/react/component-patterns/references/REFERENCE.md +0 -0
- /package/{rules → templates/react/rules}/react/hooks/SKILL.md +0 -0
- /package/{rules → templates/react/rules}/react/hooks/references/REFERENCE.md +0 -0
- /package/{rules → templates/react/rules}/react/hooks.rule.md +0 -0
- /package/{rules → templates/react/rules}/react/performance/SKILL.md +0 -0
- /package/{rules → templates/react/rules}/react/performance/references/REFERENCE.md +0 -0
- /package/{rules → templates/react/rules}/react/security/SKILL.md +0 -0
- /package/{rules → templates/react/rules}/react/security/references/REFERENCE.md +0 -0
- /package/{rules → templates/react/rules}/react/state-management/SKILL.md +0 -0
- /package/{rules → templates/react/rules}/react/state-management/references/REFERENCE.md +0 -0
- /package/{rules → templates/react/rules}/react/testing/SKILL.md +0 -0
- /package/{rules → templates/react/rules}/react/testing/references/REFERENCE.md +0 -0
- /package/{rules → templates/react/rules}/react/tooling/SKILL.md +0 -0
- /package/{rules → templates/react/rules}/react/typescript/SKILL.md +0 -0
- /package/{rules → templates/rust/rules}/rust/actix-web/SKILL.md +0 -0
- /package/{rules → templates/rust/rules}/rust/actix-web/references/REFERENCE.md +0 -0
- /package/{rules → templates/rust/rules}/rust/actix-web/references/handler-patterns.md +0 -0
- /package/{rules → templates/rust/rules}/rust/async-graphql/SKILL.md +0 -0
- /package/{rules → templates/rust/rules}/rust/async-graphql/references/REFERENCE.md +0 -0
- /package/{rules → templates/rust/rules}/rust/async-graphql/references/schema-patterns.md +0 -0
- /package/{rules → templates/rust/rules}/rust/axum/SKILL.md +0 -0
- /package/{rules → templates/rust/rules}/rust/axum/references/REFERENCE.md +0 -0
- /package/{rules → templates/rust/rules}/rust/axum/references/handler-patterns.md +0 -0
- /package/{rules → templates/rust/rules}/rust/bevy/SKILL.md +0 -0
- /package/{rules → templates/rust/rules}/rust/bevy/references/REFERENCE.md +0 -0
- /package/{rules → templates/rust/rules}/rust/bevy/references/ecs-patterns.md +0 -0
- /package/{rules → templates/rust/rules}/rust/clap/SKILL.md +0 -0
- /package/{rules → templates/rust/rules}/rust/clap/references/REFERENCE.md +0 -0
- /package/{rules → templates/rust/rules}/rust/clap/references/derive-patterns.md +0 -0
- /package/{rules → templates/rust/rules}/rust/core/SKILL.md +0 -0
- /package/{rules → templates/rust/rules}/rust/core/references/REFERENCE.md +0 -0
- /package/{rules → templates/rust/rules}/rust/core/references/error-handling.md +0 -0
- /package/{rules → templates/rust/rules}/rust/diesel-orm/SKILL.md +0 -0
- /package/{rules → templates/rust/rules}/rust/diesel-orm/references/REFERENCE.md +0 -0
- /package/{rules → templates/rust/rules}/rust/diesel-orm/references/schema-patterns.md +0 -0
- /package/{rules → templates/rust/rules}/rust/rocket/SKILL.md +0 -0
- /package/{rules → templates/rust/rules}/rust/rocket/references/REFERENCE.md +0 -0
- /package/{rules → templates/rust/rules}/rust/rocket/references/handler-patterns.md +0 -0
- /package/{rules → templates/rust/rules}/rust/sea-orm/SKILL.md +0 -0
- /package/{rules → templates/rust/rules}/rust/sea-orm/references/REFERENCE.md +0 -0
- /package/{rules → templates/rust/rules}/rust/sea-orm/references/entity-patterns.md +0 -0
- /package/{rules → templates/rust/rules}/rust/serde-serialization/SKILL.md +0 -0
- /package/{rules → templates/rust/rules}/rust/serde-serialization/references/REFERENCE.md +0 -0
- /package/{rules → templates/rust/rules}/rust/serde-serialization/references/serialization-patterns.md +0 -0
- /package/{rules → templates/rust/rules}/rust/sqlx-database/SKILL.md +0 -0
- /package/{rules → templates/rust/rules}/rust/sqlx-database/references/REFERENCE.md +0 -0
- /package/{rules → templates/rust/rules}/rust/sqlx-database/references/query-patterns.md +0 -0
- /package/{rules → templates/rust/rules}/rust/tauri/SKILL.md +0 -0
- /package/{rules → templates/rust/rules}/rust/tauri/references/REFERENCE.md +0 -0
- /package/{rules → templates/rust/rules}/rust/tauri/references/command-patterns.md +0 -0
- /package/{rules → templates/rust/rules}/rust/tokio-runtime/SKILL.md +0 -0
- /package/{rules → templates/rust/rules}/rust/tokio-runtime/references/REFERENCE.md +0 -0
- /package/{rules → templates/rust/rules}/rust/tokio-runtime/references/async-patterns.md +0 -0
- /package/{rules → templates/rust/rules}/rust/tokio-runtime/references/synchronization.md +0 -0
- /package/{rules → templates/rust/rules}/rust/tonic/SKILL.md +0 -0
- /package/{rules → templates/rust/rules}/rust/tonic/references/REFERENCE.md +0 -0
- /package/{rules → templates/rust/rules}/rust/tonic/references/service-patterns.md +0 -0
- /package/{rules → templates/rust/rules}/rust/tracing/SKILL.md +0 -0
- /package/{rules → templates/rust/rules}/rust/tracing/references/REFERENCE.md +0 -0
- /package/{rules → templates/rust/rules}/rust/tracing/references/instrumentation.md +0 -0
- /package/{rules → templates/typescript/rules}/typescript/best-practices/SKILL.md +0 -0
- /package/{rules → templates/typescript/rules}/typescript/best-practices/references/REFERENCE.md +0 -0
- /package/{rules → templates/typescript/rules}/typescript/language/SKILL.md +0 -0
- /package/{rules → templates/typescript/rules}/typescript/language/references/REFERENCE.md +0 -0
- /package/{rules → templates/typescript/rules}/typescript/patterns.rule.md +0 -0
- /package/{rules → templates/typescript/rules}/typescript/security/SKILL.md +0 -0
- /package/{rules → templates/typescript/rules}/typescript/security/references/REFERENCE.md +0 -0
- /package/{rules → templates/typescript/rules}/typescript/tooling/SKILL.md +0 -0
- /package/{rules → templates/typescript/rules}/typescript/tooling/references/REFERENCE.md +0 -0
|
@@ -0,0 +1,430 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* project-detector.cjs - Project and environment detection logic
|
|
4
|
+
*
|
|
5
|
+
* Extracted from session-init.cjs for reuse in both Claude hooks and OpenCode plugins.
|
|
6
|
+
* Detects project type, package manager, framework, and runtime versions.
|
|
7
|
+
*
|
|
8
|
+
* @module project-detector
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
const fs = require('fs');
|
|
12
|
+
const path = require('path');
|
|
13
|
+
const os = require('os');
|
|
14
|
+
const { execSync, execFileSync } = require('child_process');
|
|
15
|
+
|
|
16
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
17
|
+
// SAFE EXECUTION HELPERS
|
|
18
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Safely execute shell command with optional timeout
|
|
22
|
+
* @param {string} cmd - Command to execute
|
|
23
|
+
* @param {number} [timeoutMs=5000] - Timeout in milliseconds
|
|
24
|
+
* @returns {string|null} Output or null on error
|
|
25
|
+
*/
|
|
26
|
+
function execSafe(cmd, timeoutMs = 5000) {
|
|
27
|
+
try {
|
|
28
|
+
return execSync(cmd, {
|
|
29
|
+
encoding: 'utf8',
|
|
30
|
+
timeout: timeoutMs,
|
|
31
|
+
stdio: ['pipe', 'pipe', 'pipe']
|
|
32
|
+
}).trim();
|
|
33
|
+
} catch (e) {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Safely execute a binary with arguments (no shell interpolation)
|
|
40
|
+
* @param {string} binary - Path to the executable
|
|
41
|
+
* @param {string[]} args - Arguments array
|
|
42
|
+
* @param {number} [timeoutMs=2000] - Timeout in milliseconds
|
|
43
|
+
* @returns {string|null} Output or null on error
|
|
44
|
+
*/
|
|
45
|
+
function execFileSafe(binary, args, timeoutMs = 2000) {
|
|
46
|
+
try {
|
|
47
|
+
return execFileSync(binary, args, {
|
|
48
|
+
encoding: 'utf8',
|
|
49
|
+
timeout: timeoutMs,
|
|
50
|
+
stdio: ['pipe', 'pipe', 'pipe']
|
|
51
|
+
}).trim();
|
|
52
|
+
} catch (e) {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
58
|
+
// PYTHON DETECTION
|
|
59
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Validate that a path is a file and doesn't contain shell metacharacters
|
|
63
|
+
* @param {string} p - Path to validate
|
|
64
|
+
* @returns {boolean}
|
|
65
|
+
*/
|
|
66
|
+
function isValidPythonPath(p) {
|
|
67
|
+
if (!p || typeof p !== 'string') return false;
|
|
68
|
+
if (/[;&|`$(){}[\]<>!#*?]/.test(p)) return false;
|
|
69
|
+
try {
|
|
70
|
+
const stat = fs.statSync(p);
|
|
71
|
+
return stat.isFile();
|
|
72
|
+
} catch (e) {
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Build platform-specific Python paths for fast filesystem check
|
|
79
|
+
* @returns {string[]} Array of potential Python paths
|
|
80
|
+
*/
|
|
81
|
+
function getPythonPaths() {
|
|
82
|
+
const paths = [];
|
|
83
|
+
|
|
84
|
+
if (process.env.PYTHON_PATH) {
|
|
85
|
+
paths.push(process.env.PYTHON_PATH);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (process.platform === 'win32') {
|
|
89
|
+
const localAppData = process.env.LOCALAPPDATA;
|
|
90
|
+
const programFiles = process.env.ProgramFiles || 'C:\\Program Files';
|
|
91
|
+
const programFilesX86 = process.env['ProgramFiles(x86)'] || 'C:\\Program Files (x86)';
|
|
92
|
+
|
|
93
|
+
if (localAppData) {
|
|
94
|
+
paths.push(path.join(localAppData, 'Microsoft', 'WindowsApps', 'python.exe'));
|
|
95
|
+
paths.push(path.join(localAppData, 'Microsoft', 'WindowsApps', 'python3.exe'));
|
|
96
|
+
for (const ver of ['313', '312', '311', '310', '39']) {
|
|
97
|
+
paths.push(path.join(localAppData, 'Programs', 'Python', `Python${ver}`, 'python.exe'));
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
for (const ver of ['313', '312', '311', '310', '39']) {
|
|
102
|
+
paths.push(path.join(programFiles, `Python${ver}`, 'python.exe'));
|
|
103
|
+
paths.push(path.join(programFilesX86, `Python${ver}`, 'python.exe'));
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
paths.push('C:\\Python313\\python.exe');
|
|
107
|
+
paths.push('C:\\Python312\\python.exe');
|
|
108
|
+
paths.push('C:\\Python311\\python.exe');
|
|
109
|
+
paths.push('C:\\Python310\\python.exe');
|
|
110
|
+
paths.push('C:\\Python39\\python.exe');
|
|
111
|
+
} else {
|
|
112
|
+
paths.push('/usr/bin/python3');
|
|
113
|
+
paths.push('/usr/local/bin/python3');
|
|
114
|
+
paths.push('/opt/homebrew/bin/python3');
|
|
115
|
+
paths.push('/opt/homebrew/bin/python');
|
|
116
|
+
paths.push('/usr/bin/python');
|
|
117
|
+
paths.push('/usr/local/bin/python');
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return paths;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Find Python binary using fast filesystem check
|
|
125
|
+
* @returns {string|null} Python binary path or null
|
|
126
|
+
*/
|
|
127
|
+
function findPythonBinary() {
|
|
128
|
+
const paths = getPythonPaths();
|
|
129
|
+
for (const p of paths) {
|
|
130
|
+
if (isValidPythonPath(p)) return p;
|
|
131
|
+
}
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Get Python version with optimized detection
|
|
137
|
+
* @returns {string|null} Python version string or null
|
|
138
|
+
*/
|
|
139
|
+
function getPythonVersion() {
|
|
140
|
+
const pythonPath = findPythonBinary();
|
|
141
|
+
if (pythonPath) {
|
|
142
|
+
const result = execFileSafe(pythonPath, ['--version']);
|
|
143
|
+
if (result) return result;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const commands = ['python3', 'python'];
|
|
147
|
+
for (const cmd of commands) {
|
|
148
|
+
const result = execFileSafe(cmd, ['--version']);
|
|
149
|
+
if (result) return result;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
return null;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
156
|
+
// GIT DETECTION
|
|
157
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Get git remote URL
|
|
161
|
+
* @returns {string|null}
|
|
162
|
+
*/
|
|
163
|
+
function getGitRemoteUrl() {
|
|
164
|
+
return execSafe('git config --get remote.origin.url');
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Get current git branch
|
|
169
|
+
* @returns {string|null}
|
|
170
|
+
*/
|
|
171
|
+
function getGitBranch() {
|
|
172
|
+
return execSafe('git branch --show-current');
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Get git repository root
|
|
177
|
+
* @returns {string|null}
|
|
178
|
+
*/
|
|
179
|
+
function getGitRoot() {
|
|
180
|
+
return execSafe('git rev-parse --show-toplevel');
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
184
|
+
// PROJECT DETECTION
|
|
185
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Detect project type based on workspace indicators
|
|
189
|
+
* @param {string} [configOverride] - Manual override from config
|
|
190
|
+
* @returns {'monorepo' | 'library' | 'single-repo'}
|
|
191
|
+
*/
|
|
192
|
+
function detectProjectType(configOverride) {
|
|
193
|
+
if (configOverride && configOverride !== 'auto') return configOverride;
|
|
194
|
+
|
|
195
|
+
if (fs.existsSync('pnpm-workspace.yaml')) return 'monorepo';
|
|
196
|
+
if (fs.existsSync('lerna.json')) return 'monorepo';
|
|
197
|
+
|
|
198
|
+
if (fs.existsSync('package.json')) {
|
|
199
|
+
try {
|
|
200
|
+
const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));
|
|
201
|
+
if (pkg.workspaces) return 'monorepo';
|
|
202
|
+
if (pkg.main || pkg.exports) return 'library';
|
|
203
|
+
} catch (e) { /* ignore */ }
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
return 'single-repo';
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Detect package manager from lock files
|
|
211
|
+
* @param {string} [configOverride] - Manual override from config
|
|
212
|
+
* @returns {'npm' | 'pnpm' | 'yarn' | 'bun' | null}
|
|
213
|
+
*/
|
|
214
|
+
function detectPackageManager(configOverride) {
|
|
215
|
+
if (configOverride && configOverride !== 'auto') return configOverride;
|
|
216
|
+
|
|
217
|
+
if (fs.existsSync('bun.lockb')) return 'bun';
|
|
218
|
+
if (fs.existsSync('pnpm-lock.yaml')) return 'pnpm';
|
|
219
|
+
if (fs.existsSync('yarn.lock')) return 'yarn';
|
|
220
|
+
if (fs.existsSync('package-lock.json')) return 'npm';
|
|
221
|
+
|
|
222
|
+
return null;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Detect framework from package.json dependencies
|
|
227
|
+
* @param {string} [configOverride] - Manual override from config
|
|
228
|
+
* @returns {string|null}
|
|
229
|
+
*/
|
|
230
|
+
function detectFramework(configOverride) {
|
|
231
|
+
if (configOverride && configOverride !== 'auto') return configOverride;
|
|
232
|
+
if (!fs.existsSync('package.json')) return null;
|
|
233
|
+
|
|
234
|
+
try {
|
|
235
|
+
const pkg = JSON.parse(fs.readFileSync('package.json', 'utf8'));
|
|
236
|
+
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
237
|
+
|
|
238
|
+
if (deps['next']) return 'next';
|
|
239
|
+
if (deps['nuxt']) return 'nuxt';
|
|
240
|
+
if (deps['astro']) return 'astro';
|
|
241
|
+
if (deps['@remix-run/node'] || deps['@remix-run/react']) return 'remix';
|
|
242
|
+
if (deps['svelte'] || deps['@sveltejs/kit']) return 'svelte';
|
|
243
|
+
if (deps['vue']) return 'vue';
|
|
244
|
+
if (deps['react']) return 'react';
|
|
245
|
+
if (deps['express']) return 'express';
|
|
246
|
+
if (deps['fastify']) return 'fastify';
|
|
247
|
+
if (deps['hono']) return 'hono';
|
|
248
|
+
if (deps['elysia']) return 'elysia';
|
|
249
|
+
|
|
250
|
+
return null;
|
|
251
|
+
} catch (e) {
|
|
252
|
+
return null;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
257
|
+
// CODING LEVEL
|
|
258
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Get coding level style name mapping
|
|
262
|
+
* @param {number} level - Coding level (0-5)
|
|
263
|
+
* @returns {string} Style name
|
|
264
|
+
*/
|
|
265
|
+
function getCodingLevelStyleName(level) {
|
|
266
|
+
const styleMap = {
|
|
267
|
+
0: 'coding-level-0-eli5',
|
|
268
|
+
1: 'coding-level-1-junior',
|
|
269
|
+
2: 'coding-level-2-mid',
|
|
270
|
+
3: 'coding-level-3-senior',
|
|
271
|
+
4: 'coding-level-4-lead',
|
|
272
|
+
5: 'coding-level-5-god'
|
|
273
|
+
};
|
|
274
|
+
return styleMap[level] || 'coding-level-5-god';
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Get coding level guidelines by reading from output-styles .md files
|
|
279
|
+
* @param {number} level - Coding level (-1 to 5)
|
|
280
|
+
* @param {string} [configDir] - Config directory path
|
|
281
|
+
* @returns {string|null} Guidelines text or null if disabled
|
|
282
|
+
*/
|
|
283
|
+
function getCodingLevelGuidelines(level, configDir) {
|
|
284
|
+
if (level === -1 || level === null || level === undefined) return null;
|
|
285
|
+
|
|
286
|
+
const styleName = getCodingLevelStyleName(level);
|
|
287
|
+
const basePath = configDir || path.join(process.cwd(), '.claude');
|
|
288
|
+
const stylePath = path.join(basePath, 'output-styles', `${styleName}.md`);
|
|
289
|
+
|
|
290
|
+
try {
|
|
291
|
+
if (!fs.existsSync(stylePath)) return null;
|
|
292
|
+
const content = fs.readFileSync(stylePath, 'utf8');
|
|
293
|
+
const withoutFrontmatter = content.replace(/^---[\s\S]*?---\n*/, '').trim();
|
|
294
|
+
return withoutFrontmatter;
|
|
295
|
+
} catch (e) {
|
|
296
|
+
return null;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
301
|
+
// CONTEXT OUTPUT
|
|
302
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* Build context summary for output (compact, single line)
|
|
306
|
+
* @param {Object} config - Loaded config
|
|
307
|
+
* @param {Object} detections - Project detections
|
|
308
|
+
* @param {{ path: string|null, resolvedBy: string|null }} resolved - Plan resolution
|
|
309
|
+
* @param {string|null} gitRoot - Git repository root
|
|
310
|
+
* @returns {string}
|
|
311
|
+
*/
|
|
312
|
+
function buildContextOutput(config, detections, resolved, gitRoot) {
|
|
313
|
+
const lines = [`Project: ${detections.type || 'unknown'}`];
|
|
314
|
+
if (detections.pm) lines.push(`PM: ${detections.pm}`);
|
|
315
|
+
lines.push(`Plan naming: ${config.plan.namingFormat}`);
|
|
316
|
+
|
|
317
|
+
if (gitRoot && gitRoot !== process.cwd()) {
|
|
318
|
+
lines.push(`Root: ${gitRoot}`);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
if (resolved.path) {
|
|
322
|
+
if (resolved.resolvedBy === 'session') {
|
|
323
|
+
lines.push(`Plan: ${resolved.path}`);
|
|
324
|
+
} else {
|
|
325
|
+
lines.push(`Suggested: ${resolved.path}`);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
return lines.join(' | ');
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
333
|
+
// MAIN ENTRY POINT
|
|
334
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* Detect all project information
|
|
338
|
+
*
|
|
339
|
+
* @param {Object} [options]
|
|
340
|
+
* @param {Object} [options.configOverrides] - Override auto-detection
|
|
341
|
+
* @returns {{
|
|
342
|
+
* type: 'monorepo' | 'library' | 'single-repo',
|
|
343
|
+
* packageManager: 'npm' | 'pnpm' | 'yarn' | 'bun' | null,
|
|
344
|
+
* framework: string | null,
|
|
345
|
+
* pythonVersion: string | null,
|
|
346
|
+
* nodeVersion: string,
|
|
347
|
+
* gitBranch: string | null,
|
|
348
|
+
* gitRoot: string | null,
|
|
349
|
+
* gitUrl: string | null,
|
|
350
|
+
* osPlatform: string,
|
|
351
|
+
* user: string,
|
|
352
|
+
* locale: string,
|
|
353
|
+
* timezone: string
|
|
354
|
+
* }}
|
|
355
|
+
*/
|
|
356
|
+
function detectProject(options = {}) {
|
|
357
|
+
const { configOverrides = {} } = options;
|
|
358
|
+
|
|
359
|
+
return {
|
|
360
|
+
type: detectProjectType(configOverrides.type),
|
|
361
|
+
packageManager: detectPackageManager(configOverrides.packageManager),
|
|
362
|
+
framework: detectFramework(configOverrides.framework),
|
|
363
|
+
pythonVersion: getPythonVersion(),
|
|
364
|
+
nodeVersion: process.version,
|
|
365
|
+
gitBranch: getGitBranch(),
|
|
366
|
+
gitRoot: getGitRoot(),
|
|
367
|
+
gitUrl: getGitRemoteUrl(),
|
|
368
|
+
osPlatform: process.platform,
|
|
369
|
+
user: process.env.USERNAME || process.env.USER || process.env.LOGNAME || os.userInfo().username,
|
|
370
|
+
locale: process.env.LANG || '',
|
|
371
|
+
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
/**
|
|
376
|
+
* Build static environment info object
|
|
377
|
+
* @param {string} [configDir] - Config directory path
|
|
378
|
+
* @returns {Object} Static environment info
|
|
379
|
+
*/
|
|
380
|
+
function buildStaticEnv(configDir) {
|
|
381
|
+
return {
|
|
382
|
+
nodeVersion: process.version,
|
|
383
|
+
pythonVersion: getPythonVersion(),
|
|
384
|
+
osPlatform: process.platform,
|
|
385
|
+
gitUrl: getGitRemoteUrl(),
|
|
386
|
+
gitBranch: getGitBranch(),
|
|
387
|
+
gitRoot: getGitRoot(),
|
|
388
|
+
user: process.env.USERNAME || process.env.USER || process.env.LOGNAME || os.userInfo().username,
|
|
389
|
+
locale: process.env.LANG || '',
|
|
390
|
+
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
|
|
391
|
+
configDir: configDir || path.join(process.cwd(), '.claude')
|
|
392
|
+
};
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
396
|
+
// EXPORTS
|
|
397
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
398
|
+
|
|
399
|
+
module.exports = {
|
|
400
|
+
// Main entry points
|
|
401
|
+
detectProject,
|
|
402
|
+
buildStaticEnv,
|
|
403
|
+
|
|
404
|
+
// Detection functions
|
|
405
|
+
detectProjectType,
|
|
406
|
+
detectPackageManager,
|
|
407
|
+
detectFramework,
|
|
408
|
+
|
|
409
|
+
// Python detection
|
|
410
|
+
getPythonVersion,
|
|
411
|
+
findPythonBinary,
|
|
412
|
+
getPythonPaths,
|
|
413
|
+
isValidPythonPath,
|
|
414
|
+
|
|
415
|
+
// Git detection
|
|
416
|
+
getGitRemoteUrl,
|
|
417
|
+
getGitBranch,
|
|
418
|
+
getGitRoot,
|
|
419
|
+
|
|
420
|
+
// Coding level
|
|
421
|
+
getCodingLevelStyleName,
|
|
422
|
+
getCodingLevelGuidelines,
|
|
423
|
+
|
|
424
|
+
// Output
|
|
425
|
+
buildContextOutput,
|
|
426
|
+
|
|
427
|
+
// Helpers
|
|
428
|
+
execSafe,
|
|
429
|
+
execFileSafe
|
|
430
|
+
};
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* scout-checker.cjs - Facade for scout-block modules
|
|
4
|
+
*
|
|
5
|
+
* Provides unified interface to scout-block/* modules for reuse in both
|
|
6
|
+
* Claude hooks and OpenCode plugins.
|
|
7
|
+
*
|
|
8
|
+
* @module scout-checker
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
const path = require('path');
|
|
12
|
+
|
|
13
|
+
// Import scout-block modules
|
|
14
|
+
const { loadPatterns, createMatcher, matchPath } = require('../scout-block/pattern-matcher.cjs');
|
|
15
|
+
const { extractFromToolInput } = require('../scout-block/path-extractor.cjs');
|
|
16
|
+
const { detectBroadPatternIssue } = require('../scout-block/broad-pattern-detector.cjs');
|
|
17
|
+
|
|
18
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
19
|
+
// COMMAND PATTERNS
|
|
20
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
21
|
+
|
|
22
|
+
// Build command allowlist - these are allowed even if they contain blocked paths
|
|
23
|
+
// Handles flags and filters: npm build, pnpm --filter web run build, yarn workspace app build
|
|
24
|
+
const BUILD_COMMAND_PATTERN = /^(npm|pnpm|yarn|bun)\s+([^\s]+\s+)*(run\s+)?(build|test|lint|dev|start|install|ci|add|remove|update|publish|pack|init|create|exec)/;
|
|
25
|
+
|
|
26
|
+
// Tool commands - go, cargo, make, mvn/mvnw, gradle/gradlew, dotnet, docker, bazel, cmake, sbt, flutter, swift, ant, ninja, meson
|
|
27
|
+
const TOOL_COMMAND_PATTERN = /^(\.\/)?(npx|pnpx|bunx|tsc|esbuild|vite|webpack|rollup|turbo|nx|jest|vitest|mocha|eslint|prettier|go|cargo|make|mvn|mvnw|gradle|gradlew|dotnet|docker|podman|kubectl|helm|terraform|ansible|bazel|cmake|sbt|flutter|swift|ant|ninja|meson)/;
|
|
28
|
+
|
|
29
|
+
// Allow execution from .venv/bin/ or venv/bin/ (Unix) and .venv/Scripts/ or venv/Scripts/ (Windows)
|
|
30
|
+
const VENV_EXECUTABLE_PATTERN = /(^|[\/\\])\.?venv[\/\\](bin|Scripts)[\/\\]/;
|
|
31
|
+
|
|
32
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
33
|
+
// HELPER FUNCTIONS
|
|
34
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Check if a command is a build/tooling command (should be allowed)
|
|
38
|
+
* @param {string} command - The command to check
|
|
39
|
+
* @returns {boolean}
|
|
40
|
+
*/
|
|
41
|
+
function isBuildCommand(command) {
|
|
42
|
+
if (!command || typeof command !== 'string') return false;
|
|
43
|
+
const trimmed = command.trim();
|
|
44
|
+
return BUILD_COMMAND_PATTERN.test(trimmed) || TOOL_COMMAND_PATTERN.test(trimmed);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Check if command executes from a .venv bin directory
|
|
49
|
+
* @param {string} command - The command to check
|
|
50
|
+
* @returns {boolean}
|
|
51
|
+
*/
|
|
52
|
+
function isVenvExecutable(command) {
|
|
53
|
+
if (!command || typeof command !== 'string') return false;
|
|
54
|
+
return VENV_EXECUTABLE_PATTERN.test(command);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Check if command should be allowed (build or venv executable)
|
|
59
|
+
* @param {string} command - The command to check
|
|
60
|
+
* @returns {boolean}
|
|
61
|
+
*/
|
|
62
|
+
function isAllowedCommand(command) {
|
|
63
|
+
return isBuildCommand(command) || isVenvExecutable(command);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
67
|
+
// MAIN ENTRY POINT
|
|
68
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Check if a tool call accesses blocked directories or uses overly broad patterns
|
|
72
|
+
*
|
|
73
|
+
* @param {Object} params
|
|
74
|
+
* @param {string} params.toolName - Name of tool (Bash, Glob, Read, etc.)
|
|
75
|
+
* @param {Object} params.toolInput - Tool input with file_path, path, pattern, command
|
|
76
|
+
* @param {Object} [params.options]
|
|
77
|
+
* @param {string} [params.options.ckignorePath] - Path to .ckignore file
|
|
78
|
+
* @param {string} [params.options.claudeDir] - Path to .claude or .opencode directory
|
|
79
|
+
* @param {boolean} [params.options.checkBroadPatterns] - Check for overly broad glob patterns (default: true)
|
|
80
|
+
* @returns {{
|
|
81
|
+
* blocked: boolean,
|
|
82
|
+
* path?: string,
|
|
83
|
+
* pattern?: string,
|
|
84
|
+
* reason?: string,
|
|
85
|
+
* isBroadPattern?: boolean,
|
|
86
|
+
* suggestions?: string[],
|
|
87
|
+
* isAllowedCommand?: boolean
|
|
88
|
+
* }}
|
|
89
|
+
*/
|
|
90
|
+
function checkScoutBlock({ toolName, toolInput, options = {} }) {
|
|
91
|
+
const {
|
|
92
|
+
ckignorePath,
|
|
93
|
+
claudeDir = path.join(process.cwd(), '.claude'),
|
|
94
|
+
checkBroadPatterns = true
|
|
95
|
+
} = options;
|
|
96
|
+
|
|
97
|
+
// Check if it's a build command or venv executable (allowed regardless of paths)
|
|
98
|
+
if (toolInput.command && isAllowedCommand(toolInput.command)) {
|
|
99
|
+
return { blocked: false, isAllowedCommand: true };
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Check for overly broad glob patterns (Glob tool)
|
|
103
|
+
if (checkBroadPatterns && (toolName === 'Glob' || toolInput.pattern)) {
|
|
104
|
+
const broadResult = detectBroadPatternIssue(toolInput);
|
|
105
|
+
if (broadResult.blocked) {
|
|
106
|
+
return {
|
|
107
|
+
blocked: true,
|
|
108
|
+
isBroadPattern: true,
|
|
109
|
+
pattern: toolInput.pattern,
|
|
110
|
+
reason: broadResult.reason || 'Pattern too broad - may fill context with too many files',
|
|
111
|
+
suggestions: broadResult.suggestions || []
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Resolve .ckignore path
|
|
117
|
+
const resolvedCkignorePath = ckignorePath || path.join(claudeDir, '.ckignore');
|
|
118
|
+
|
|
119
|
+
// Load patterns and create matcher
|
|
120
|
+
const patterns = loadPatterns(resolvedCkignorePath);
|
|
121
|
+
const matcher = createMatcher(patterns);
|
|
122
|
+
|
|
123
|
+
// Extract paths from tool input
|
|
124
|
+
const extractedPaths = extractFromToolInput(toolInput);
|
|
125
|
+
|
|
126
|
+
// If no paths extracted, allow operation
|
|
127
|
+
if (extractedPaths.length === 0) {
|
|
128
|
+
return { blocked: false };
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Check each path against patterns
|
|
132
|
+
for (const extractedPath of extractedPaths) {
|
|
133
|
+
const result = matchPath(matcher, extractedPath);
|
|
134
|
+
if (result.blocked) {
|
|
135
|
+
return {
|
|
136
|
+
blocked: true,
|
|
137
|
+
path: extractedPath,
|
|
138
|
+
pattern: result.pattern,
|
|
139
|
+
reason: `Path matches blocked pattern: ${result.pattern}`
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// All paths allowed
|
|
145
|
+
return { blocked: false };
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
149
|
+
// EXPORTS
|
|
150
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
151
|
+
|
|
152
|
+
module.exports = {
|
|
153
|
+
// Main entry point
|
|
154
|
+
checkScoutBlock,
|
|
155
|
+
|
|
156
|
+
// Command checkers
|
|
157
|
+
isBuildCommand,
|
|
158
|
+
isVenvExecutable,
|
|
159
|
+
isAllowedCommand,
|
|
160
|
+
|
|
161
|
+
// Re-export scout-block modules for direct access
|
|
162
|
+
loadPatterns,
|
|
163
|
+
createMatcher,
|
|
164
|
+
matchPath,
|
|
165
|
+
extractFromToolInput,
|
|
166
|
+
detectBroadPatternIssue,
|
|
167
|
+
|
|
168
|
+
// Patterns (for testing)
|
|
169
|
+
BUILD_COMMAND_PATTERN,
|
|
170
|
+
TOOL_COMMAND_PATTERN,
|
|
171
|
+
VENV_EXECUTABLE_PATTERN
|
|
172
|
+
};
|