@harness-engineering/cli 1.14.0 → 1.16.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/dist/agents/commands/codex/AGENTS.md +39 -0
- package/dist/agents/commands/codex/harness/add-harness-component/SKILL.md +195 -0
- package/dist/agents/commands/codex/harness/add-harness-component/agents/openai.yaml +3 -0
- package/dist/agents/commands/codex/harness/cleanup-dead-code/SKILL.md +248 -0
- package/dist/agents/commands/codex/harness/cleanup-dead-code/agents/openai.yaml +3 -0
- package/dist/agents/commands/codex/harness/detect-doc-drift/SKILL.md +182 -0
- package/dist/agents/commands/codex/harness/detect-doc-drift/agents/openai.yaml +3 -0
- package/dist/agents/commands/codex/harness/enforce-architecture/SKILL.md +299 -0
- package/dist/agents/commands/codex/harness/enforce-architecture/agents/openai.yaml +3 -0
- package/dist/agents/commands/codex/harness/harness-architecture-advisor/SKILL.md +452 -0
- package/dist/agents/commands/codex/harness/harness-architecture-advisor/agents/openai.yaml +3 -0
- package/dist/agents/commands/codex/harness/harness-autopilot/SKILL.md +919 -0
- package/dist/agents/commands/codex/harness/harness-autopilot/agents/openai.yaml +3 -0
- package/dist/agents/commands/codex/harness/harness-brainstorming/SKILL.md +409 -0
- package/dist/agents/commands/codex/harness/harness-brainstorming/agents/openai.yaml +3 -0
- package/dist/agents/commands/codex/harness/harness-code-review/SKILL.md +860 -0
- package/dist/agents/commands/codex/harness/harness-code-review/agents/openai.yaml +3 -0
- package/dist/agents/commands/codex/harness/harness-codebase-cleanup/SKILL.md +227 -0
- package/dist/agents/commands/codex/harness/harness-codebase-cleanup/agents/openai.yaml +3 -0
- package/dist/agents/commands/codex/harness/harness-debugging/SKILL.md +369 -0
- package/dist/agents/commands/codex/harness/harness-debugging/agents/openai.yaml +3 -0
- package/dist/agents/commands/codex/harness/harness-dependency-health/SKILL.md +182 -0
- package/dist/agents/commands/codex/harness/harness-dependency-health/agents/openai.yaml +3 -0
- package/dist/agents/commands/codex/harness/harness-docs-pipeline/SKILL.md +463 -0
- package/dist/agents/commands/codex/harness/harness-docs-pipeline/agents/openai.yaml +3 -0
- package/dist/agents/commands/codex/harness/harness-execution/SKILL.md +513 -0
- package/dist/agents/commands/codex/harness/harness-execution/agents/openai.yaml +3 -0
- package/dist/agents/commands/codex/harness/harness-hotspot-detector/SKILL.md +164 -0
- package/dist/agents/commands/codex/harness/harness-hotspot-detector/agents/openai.yaml +3 -0
- package/dist/agents/commands/codex/harness/harness-impact-analysis/SKILL.md +187 -0
- package/dist/agents/commands/codex/harness/harness-impact-analysis/agents/openai.yaml +3 -0
- package/dist/agents/commands/codex/harness/harness-integrity/SKILL.md +170 -0
- package/dist/agents/commands/codex/harness/harness-integrity/agents/openai.yaml +3 -0
- package/dist/agents/commands/codex/harness/harness-onboarding/SKILL.md +291 -0
- package/dist/agents/commands/codex/harness/harness-onboarding/agents/openai.yaml +3 -0
- package/dist/agents/commands/codex/harness/harness-perf/SKILL.md +263 -0
- package/dist/agents/commands/codex/harness/harness-perf/agents/openai.yaml +3 -0
- package/dist/agents/commands/codex/harness/harness-planning/SKILL.md +582 -0
- package/dist/agents/commands/codex/harness/harness-planning/agents/openai.yaml +3 -0
- package/dist/agents/commands/codex/harness/harness-refactoring/SKILL.md +172 -0
- package/dist/agents/commands/codex/harness/harness-refactoring/agents/openai.yaml +3 -0
- package/dist/agents/commands/codex/harness/harness-release-readiness/SKILL.md +692 -0
- package/dist/agents/commands/codex/harness/harness-release-readiness/agents/openai.yaml +3 -0
- package/dist/agents/commands/codex/harness/harness-roadmap/SKILL.md +598 -0
- package/dist/agents/commands/codex/harness/harness-roadmap/agents/openai.yaml +3 -0
- package/dist/agents/commands/codex/harness/harness-security-scan/SKILL.md +157 -0
- package/dist/agents/commands/codex/harness/harness-security-scan/agents/openai.yaml +3 -0
- package/dist/agents/commands/codex/harness/harness-skill-authoring/SKILL.md +295 -0
- package/dist/agents/commands/codex/harness/harness-skill-authoring/agents/openai.yaml +3 -0
- package/dist/agents/commands/codex/harness/harness-soundness-review/SKILL.md +1270 -0
- package/dist/agents/commands/codex/harness/harness-soundness-review/agents/openai.yaml +3 -0
- package/dist/agents/commands/codex/harness/harness-supply-chain-audit/SKILL.md +247 -0
- package/dist/agents/commands/codex/harness/harness-supply-chain-audit/agents/openai.yaml +3 -0
- package/dist/agents/commands/codex/harness/harness-tdd/SKILL.md +180 -0
- package/dist/agents/commands/codex/harness/harness-tdd/agents/openai.yaml +3 -0
- package/dist/agents/commands/codex/harness/harness-test-advisor/SKILL.md +163 -0
- package/dist/agents/commands/codex/harness/harness-test-advisor/agents/openai.yaml +3 -0
- package/dist/agents/commands/codex/harness/harness-verification/SKILL.md +424 -0
- package/dist/agents/commands/codex/harness/harness-verification/agents/openai.yaml +3 -0
- package/dist/agents/commands/codex/harness/harness-verify/SKILL.md +162 -0
- package/dist/agents/commands/codex/harness/harness-verify/agents/openai.yaml +3 -0
- package/dist/agents/commands/codex/harness/initialize-harness-project/SKILL.md +235 -0
- package/dist/agents/commands/codex/harness/initialize-harness-project/agents/openai.yaml +3 -0
- package/dist/agents/commands/cursor/harness/add-harness-component.mdc +200 -0
- package/dist/agents/commands/cursor/harness/cleanup-dead-code.mdc +253 -0
- package/dist/agents/commands/cursor/harness/detect-doc-drift.mdc +187 -0
- package/dist/agents/commands/cursor/harness/enforce-architecture.mdc +304 -0
- package/dist/agents/commands/cursor/harness/harness-architecture-advisor.mdc +457 -0
- package/dist/agents/commands/cursor/harness/harness-autopilot.mdc +924 -0
- package/dist/agents/commands/cursor/harness/harness-brainstorming.mdc +414 -0
- package/dist/agents/commands/cursor/harness/harness-code-review.mdc +865 -0
- package/dist/agents/commands/cursor/harness/harness-codebase-cleanup.mdc +232 -0
- package/dist/agents/commands/cursor/harness/harness-debugging.mdc +374 -0
- package/dist/agents/commands/cursor/harness/harness-dependency-health.mdc +187 -0
- package/dist/agents/commands/cursor/harness/harness-docs-pipeline.mdc +468 -0
- package/dist/agents/commands/cursor/harness/harness-execution.mdc +518 -0
- package/dist/agents/commands/cursor/harness/harness-hotspot-detector.mdc +169 -0
- package/dist/agents/commands/cursor/harness/harness-impact-analysis.mdc +192 -0
- package/dist/agents/commands/cursor/harness/harness-integrity.mdc +175 -0
- package/dist/agents/commands/cursor/harness/harness-onboarding.mdc +296 -0
- package/dist/agents/commands/cursor/harness/harness-perf.mdc +268 -0
- package/dist/agents/commands/cursor/harness/harness-planning.mdc +587 -0
- package/dist/agents/commands/cursor/harness/harness-refactoring.mdc +177 -0
- package/dist/agents/commands/cursor/harness/harness-release-readiness.mdc +697 -0
- package/dist/agents/commands/cursor/harness/harness-roadmap.mdc +603 -0
- package/dist/agents/commands/cursor/harness/harness-security-scan.mdc +162 -0
- package/dist/agents/commands/cursor/harness/harness-skill-authoring.mdc +300 -0
- package/dist/agents/commands/cursor/harness/harness-soundness-review.mdc +1275 -0
- package/dist/agents/commands/cursor/harness/harness-supply-chain-audit.mdc +252 -0
- package/dist/agents/commands/cursor/harness/harness-tdd.mdc +185 -0
- package/dist/agents/commands/cursor/harness/harness-test-advisor.mdc +168 -0
- package/dist/agents/commands/cursor/harness/harness-verification.mdc +429 -0
- package/dist/agents/commands/cursor/harness/harness-verify.mdc +167 -0
- package/dist/agents/commands/cursor/harness/initialize-harness-project.mdc +240 -0
- package/dist/agents/skills/claude-code/enforce-architecture/SKILL.md +52 -0
- package/dist/agents/skills/claude-code/harness-api-design/SKILL.md +52 -0
- package/dist/agents/skills/claude-code/harness-architecture-advisor/SKILL.md +52 -0
- package/dist/agents/skills/claude-code/harness-auth/SKILL.md +52 -0
- package/dist/agents/skills/claude-code/harness-autopilot/SKILL.md +355 -45
- package/dist/agents/skills/claude-code/harness-autopilot/skill.yaml +12 -0
- package/dist/agents/skills/claude-code/harness-code-review/SKILL.md +97 -3
- package/dist/agents/skills/claude-code/harness-code-review/skill.yaml +6 -0
- package/dist/agents/skills/claude-code/harness-codebase-cleanup/SKILL.md +2 -4
- package/dist/agents/skills/claude-code/harness-database/SKILL.md +52 -0
- package/dist/agents/skills/claude-code/harness-deployment/SKILL.md +52 -0
- package/dist/agents/skills/claude-code/harness-planning/SKILL.md +99 -3
- package/dist/agents/skills/claude-code/harness-planning/skill.yaml +6 -0
- package/dist/agents/skills/claude-code/harness-pre-commit-review/SKILL.md +1 -1
- package/dist/agents/skills/claude-code/harness-product-spec/SKILL.md +5 -5
- package/dist/agents/skills/claude-code/harness-security-review/SKILL.md +27 -7
- package/dist/agents/skills/claude-code/harness-security-scan/SKILL.md +52 -0
- package/dist/agents/skills/claude-code/harness-supply-chain-audit/SKILL.md +281 -0
- package/dist/agents/skills/claude-code/harness-supply-chain-audit/skill.yaml +51 -0
- package/dist/agents/skills/codex/add-harness-component/SKILL.md +192 -0
- package/dist/agents/skills/codex/add-harness-component/skill.yaml +33 -0
- package/dist/agents/skills/codex/align-documentation/SKILL.md +213 -0
- package/dist/agents/skills/codex/align-documentation/skill.yaml +32 -0
- package/dist/agents/skills/codex/check-mechanical-constraints/SKILL.md +191 -0
- package/dist/agents/skills/codex/check-mechanical-constraints/skill.yaml +33 -0
- package/dist/agents/skills/codex/cleanup-dead-code/SKILL.md +245 -0
- package/dist/agents/skills/codex/cleanup-dead-code/skill.yaml +34 -0
- package/dist/agents/skills/codex/detect-doc-drift/SKILL.md +179 -0
- package/dist/agents/skills/codex/detect-doc-drift/skill.yaml +31 -0
- package/dist/agents/skills/codex/enforce-architecture/SKILL.md +296 -0
- package/dist/agents/skills/codex/enforce-architecture/skill.yaml +35 -0
- package/dist/agents/skills/codex/harness-accessibility/SKILL.md +281 -0
- package/dist/agents/skills/codex/harness-accessibility/skill.yaml +52 -0
- package/dist/agents/skills/codex/harness-api-design/SKILL.md +356 -0
- package/dist/agents/skills/codex/harness-api-design/skill.yaml +74 -0
- package/dist/agents/skills/codex/harness-architecture-advisor/SKILL.md +449 -0
- package/dist/agents/skills/codex/harness-architecture-advisor/skill.yaml +49 -0
- package/dist/agents/skills/codex/harness-auth/SKILL.md +331 -0
- package/dist/agents/skills/codex/harness-auth/skill.yaml +81 -0
- package/dist/agents/skills/codex/harness-autopilot/SKILL.md +916 -0
- package/dist/agents/skills/codex/harness-autopilot/skill.yaml +67 -0
- package/dist/agents/skills/codex/harness-brainstorming/SKILL.md +406 -0
- package/dist/agents/skills/codex/harness-brainstorming/skill.yaml +50 -0
- package/dist/agents/skills/codex/harness-caching/SKILL.md +309 -0
- package/dist/agents/skills/codex/harness-caching/skill.yaml +73 -0
- package/dist/agents/skills/codex/harness-chaos/SKILL.md +295 -0
- package/dist/agents/skills/codex/harness-chaos/skill.yaml +72 -0
- package/dist/agents/skills/codex/harness-code-review/SKILL.md +857 -0
- package/dist/agents/skills/codex/harness-code-review/skill.yaml +52 -0
- package/dist/agents/skills/codex/harness-codebase-cleanup/SKILL.md +224 -0
- package/dist/agents/skills/codex/harness-codebase-cleanup/skill.yaml +65 -0
- package/dist/agents/skills/codex/harness-compliance/SKILL.md +303 -0
- package/dist/agents/skills/codex/harness-compliance/skill.yaml +78 -0
- package/dist/agents/skills/codex/harness-containerization/SKILL.md +284 -0
- package/dist/agents/skills/codex/harness-containerization/skill.yaml +80 -0
- package/dist/agents/skills/codex/harness-data-pipeline/SKILL.md +274 -0
- package/dist/agents/skills/codex/harness-data-pipeline/skill.yaml +81 -0
- package/dist/agents/skills/codex/harness-data-validation/SKILL.md +343 -0
- package/dist/agents/skills/codex/harness-data-validation/skill.yaml +75 -0
- package/dist/agents/skills/codex/harness-database/SKILL.md +310 -0
- package/dist/agents/skills/codex/harness-database/skill.yaml +80 -0
- package/dist/agents/skills/codex/harness-debugging/SKILL.md +366 -0
- package/dist/agents/skills/codex/harness-debugging/skill.yaml +48 -0
- package/dist/agents/skills/codex/harness-dependency-health/SKILL.md +179 -0
- package/dist/agents/skills/codex/harness-dependency-health/skill.yaml +42 -0
- package/dist/agents/skills/codex/harness-deployment/SKILL.md +307 -0
- package/dist/agents/skills/codex/harness-deployment/skill.yaml +77 -0
- package/dist/agents/skills/codex/harness-design/SKILL.md +265 -0
- package/dist/agents/skills/codex/harness-design/skill.yaml +54 -0
- package/dist/agents/skills/codex/harness-design-mobile/SKILL.md +336 -0
- package/dist/agents/skills/codex/harness-design-mobile/skill.yaml +50 -0
- package/dist/agents/skills/codex/harness-design-system/SKILL.md +282 -0
- package/dist/agents/skills/codex/harness-design-system/skill.yaml +51 -0
- package/dist/agents/skills/codex/harness-design-web/SKILL.md +360 -0
- package/dist/agents/skills/codex/harness-design-web/skill.yaml +53 -0
- package/dist/agents/skills/codex/harness-diagnostics/SKILL.md +318 -0
- package/dist/agents/skills/codex/harness-diagnostics/skill.yaml +51 -0
- package/dist/agents/skills/codex/harness-docs-pipeline/SKILL.md +460 -0
- package/dist/agents/skills/codex/harness-docs-pipeline/skill.yaml +70 -0
- package/dist/agents/skills/codex/harness-dx/SKILL.md +276 -0
- package/dist/agents/skills/codex/harness-dx/skill.yaml +76 -0
- package/dist/agents/skills/codex/harness-e2e/SKILL.md +245 -0
- package/dist/agents/skills/codex/harness-e2e/skill.yaml +78 -0
- package/dist/agents/skills/codex/harness-event-driven/SKILL.md +280 -0
- package/dist/agents/skills/codex/harness-event-driven/skill.yaml +77 -0
- package/dist/agents/skills/codex/harness-execution/SKILL.md +510 -0
- package/dist/agents/skills/codex/harness-execution/skill.yaml +52 -0
- package/dist/agents/skills/codex/harness-feature-flags/SKILL.md +287 -0
- package/dist/agents/skills/codex/harness-feature-flags/skill.yaml +74 -0
- package/dist/agents/skills/codex/harness-git-workflow/SKILL.md +268 -0
- package/dist/agents/skills/codex/harness-git-workflow/skill.yaml +32 -0
- package/dist/agents/skills/codex/harness-hotspot-detector/SKILL.md +161 -0
- package/dist/agents/skills/codex/harness-hotspot-detector/skill.yaml +45 -0
- package/dist/agents/skills/codex/harness-i18n/SKILL.md +484 -0
- package/dist/agents/skills/codex/harness-i18n/skill.yaml +55 -0
- package/dist/agents/skills/codex/harness-i18n-process/SKILL.md +388 -0
- package/dist/agents/skills/codex/harness-i18n-process/skill.yaml +44 -0
- package/dist/agents/skills/codex/harness-i18n-workflow/SKILL.md +512 -0
- package/dist/agents/skills/codex/harness-i18n-workflow/skill.yaml +54 -0
- package/dist/agents/skills/codex/harness-impact-analysis/SKILL.md +184 -0
- package/dist/agents/skills/codex/harness-impact-analysis/skill.yaml +45 -0
- package/dist/agents/skills/codex/harness-incident-response/SKILL.md +223 -0
- package/dist/agents/skills/codex/harness-incident-response/skill.yaml +78 -0
- package/dist/agents/skills/codex/harness-infrastructure-as-code/SKILL.md +279 -0
- package/dist/agents/skills/codex/harness-infrastructure-as-code/skill.yaml +80 -0
- package/dist/agents/skills/codex/harness-integration-test/SKILL.md +271 -0
- package/dist/agents/skills/codex/harness-integration-test/skill.yaml +73 -0
- package/dist/agents/skills/codex/harness-integrity/SKILL.md +167 -0
- package/dist/agents/skills/codex/harness-integrity/skill.yaml +48 -0
- package/dist/agents/skills/codex/harness-knowledge-mapper/SKILL.md +195 -0
- package/dist/agents/skills/codex/harness-knowledge-mapper/skill.yaml +50 -0
- package/dist/agents/skills/codex/harness-load-testing/SKILL.md +274 -0
- package/dist/agents/skills/codex/harness-load-testing/skill.yaml +79 -0
- package/dist/agents/skills/codex/harness-ml-ops/SKILL.md +341 -0
- package/dist/agents/skills/codex/harness-ml-ops/skill.yaml +79 -0
- package/dist/agents/skills/codex/harness-mobile-patterns/SKILL.md +326 -0
- package/dist/agents/skills/codex/harness-mobile-patterns/skill.yaml +82 -0
- package/dist/agents/skills/codex/harness-mutation-test/SKILL.md +251 -0
- package/dist/agents/skills/codex/harness-mutation-test/skill.yaml +70 -0
- package/dist/agents/skills/codex/harness-observability/SKILL.md +283 -0
- package/dist/agents/skills/codex/harness-observability/skill.yaml +78 -0
- package/dist/agents/skills/codex/harness-onboarding/SKILL.md +288 -0
- package/dist/agents/skills/codex/harness-onboarding/skill.yaml +31 -0
- package/dist/agents/skills/codex/harness-parallel-agents/SKILL.md +256 -0
- package/dist/agents/skills/codex/harness-parallel-agents/skill.yaml +34 -0
- package/dist/agents/skills/codex/harness-perf/SKILL.md +260 -0
- package/dist/agents/skills/codex/harness-perf/skill.yaml +51 -0
- package/dist/agents/skills/codex/harness-perf-tdd/SKILL.md +249 -0
- package/dist/agents/skills/codex/harness-perf-tdd/skill.yaml +48 -0
- package/dist/agents/skills/codex/harness-planning/SKILL.md +579 -0
- package/dist/agents/skills/codex/harness-planning/skill.yaml +56 -0
- package/dist/agents/skills/codex/harness-pre-commit-review/SKILL.md +324 -0
- package/dist/agents/skills/codex/harness-pre-commit-review/skill.yaml +34 -0
- package/dist/agents/skills/codex/harness-product-spec/SKILL.md +285 -0
- package/dist/agents/skills/codex/harness-product-spec/skill.yaml +72 -0
- package/dist/agents/skills/codex/harness-property-test/SKILL.md +281 -0
- package/dist/agents/skills/codex/harness-property-test/skill.yaml +71 -0
- package/dist/agents/skills/codex/harness-refactoring/SKILL.md +169 -0
- package/dist/agents/skills/codex/harness-refactoring/skill.yaml +34 -0
- package/dist/agents/skills/codex/harness-release-readiness/SKILL.md +689 -0
- package/dist/agents/skills/codex/harness-release-readiness/skill.yaml +58 -0
- package/dist/agents/skills/codex/harness-resilience/SKILL.md +255 -0
- package/dist/agents/skills/codex/harness-resilience/skill.yaml +76 -0
- package/dist/agents/skills/codex/harness-roadmap/SKILL.md +595 -0
- package/dist/agents/skills/codex/harness-roadmap/skill.yaml +44 -0
- package/dist/agents/skills/codex/harness-secrets/SKILL.md +293 -0
- package/dist/agents/skills/codex/harness-secrets/skill.yaml +76 -0
- package/dist/agents/skills/codex/harness-security-review/SKILL.md +260 -0
- package/dist/agents/skills/codex/harness-security-review/skill.yaml +53 -0
- package/dist/agents/skills/codex/harness-security-scan/SKILL.md +154 -0
- package/dist/agents/skills/codex/harness-security-scan/skill.yaml +42 -0
- package/dist/agents/skills/codex/harness-skill-authoring/SKILL.md +292 -0
- package/dist/agents/skills/codex/harness-skill-authoring/skill.yaml +33 -0
- package/dist/agents/skills/codex/harness-soundness-review/SKILL.md +1267 -0
- package/dist/agents/skills/codex/harness-soundness-review/skill.yaml +49 -0
- package/dist/agents/skills/codex/harness-sql-review/SKILL.md +315 -0
- package/dist/agents/skills/codex/harness-sql-review/skill.yaml +74 -0
- package/dist/agents/skills/codex/harness-state-management/SKILL.md +309 -0
- package/dist/agents/skills/codex/harness-state-management/skill.yaml +33 -0
- package/dist/agents/skills/codex/harness-supply-chain-audit/SKILL.md +281 -0
- package/dist/agents/skills/codex/harness-supply-chain-audit/skill.yaml +51 -0
- package/dist/agents/skills/codex/harness-tdd/SKILL.md +177 -0
- package/dist/agents/skills/codex/harness-tdd/skill.yaml +49 -0
- package/dist/agents/skills/codex/harness-test-advisor/SKILL.md +160 -0
- package/dist/agents/skills/codex/harness-test-advisor/skill.yaml +45 -0
- package/dist/agents/skills/codex/harness-test-data/SKILL.md +268 -0
- package/dist/agents/skills/codex/harness-test-data/skill.yaml +74 -0
- package/dist/agents/skills/codex/harness-ux-copy/SKILL.md +271 -0
- package/dist/agents/skills/codex/harness-ux-copy/skill.yaml +77 -0
- package/dist/agents/skills/codex/harness-verification/SKILL.md +421 -0
- package/dist/agents/skills/codex/harness-verification/skill.yaml +43 -0
- package/dist/agents/skills/codex/harness-verify/SKILL.md +159 -0
- package/dist/agents/skills/codex/harness-verify/skill.yaml +41 -0
- package/dist/agents/skills/codex/harness-visual-regression/SKILL.md +257 -0
- package/dist/agents/skills/codex/harness-visual-regression/skill.yaml +74 -0
- package/dist/agents/skills/codex/initialize-harness-project/SKILL.md +232 -0
- package/dist/agents/skills/codex/initialize-harness-project/skill.yaml +32 -0
- package/dist/agents/skills/codex/validate-context-engineering/SKILL.md +150 -0
- package/dist/agents/skills/codex/validate-context-engineering/skill.yaml +32 -0
- package/dist/agents/skills/cursor/add-harness-component/SKILL.md +192 -0
- package/dist/agents/skills/cursor/add-harness-component/skill.yaml +33 -0
- package/dist/agents/skills/cursor/align-documentation/SKILL.md +213 -0
- package/dist/agents/skills/cursor/align-documentation/skill.yaml +32 -0
- package/dist/agents/skills/cursor/check-mechanical-constraints/SKILL.md +191 -0
- package/dist/agents/skills/cursor/check-mechanical-constraints/skill.yaml +33 -0
- package/dist/agents/skills/cursor/cleanup-dead-code/SKILL.md +245 -0
- package/dist/agents/skills/cursor/cleanup-dead-code/skill.yaml +34 -0
- package/dist/agents/skills/cursor/detect-doc-drift/SKILL.md +179 -0
- package/dist/agents/skills/cursor/detect-doc-drift/skill.yaml +31 -0
- package/dist/agents/skills/cursor/enforce-architecture/SKILL.md +296 -0
- package/dist/agents/skills/cursor/enforce-architecture/skill.yaml +35 -0
- package/dist/agents/skills/cursor/harness-accessibility/SKILL.md +281 -0
- package/dist/agents/skills/cursor/harness-accessibility/skill.yaml +52 -0
- package/dist/agents/skills/cursor/harness-api-design/SKILL.md +356 -0
- package/dist/agents/skills/cursor/harness-api-design/skill.yaml +74 -0
- package/dist/agents/skills/cursor/harness-architecture-advisor/SKILL.md +449 -0
- package/dist/agents/skills/cursor/harness-architecture-advisor/skill.yaml +49 -0
- package/dist/agents/skills/cursor/harness-auth/SKILL.md +331 -0
- package/dist/agents/skills/cursor/harness-auth/skill.yaml +81 -0
- package/dist/agents/skills/cursor/harness-autopilot/SKILL.md +916 -0
- package/dist/agents/skills/cursor/harness-autopilot/skill.yaml +67 -0
- package/dist/agents/skills/cursor/harness-brainstorming/SKILL.md +406 -0
- package/dist/agents/skills/cursor/harness-brainstorming/skill.yaml +50 -0
- package/dist/agents/skills/cursor/harness-caching/SKILL.md +309 -0
- package/dist/agents/skills/cursor/harness-caching/skill.yaml +73 -0
- package/dist/agents/skills/cursor/harness-chaos/SKILL.md +295 -0
- package/dist/agents/skills/cursor/harness-chaos/skill.yaml +72 -0
- package/dist/agents/skills/cursor/harness-code-review/SKILL.md +857 -0
- package/dist/agents/skills/cursor/harness-code-review/skill.yaml +52 -0
- package/dist/agents/skills/cursor/harness-codebase-cleanup/SKILL.md +224 -0
- package/dist/agents/skills/cursor/harness-codebase-cleanup/skill.yaml +65 -0
- package/dist/agents/skills/cursor/harness-compliance/SKILL.md +303 -0
- package/dist/agents/skills/cursor/harness-compliance/skill.yaml +78 -0
- package/dist/agents/skills/cursor/harness-containerization/SKILL.md +284 -0
- package/dist/agents/skills/cursor/harness-containerization/skill.yaml +80 -0
- package/dist/agents/skills/cursor/harness-data-pipeline/SKILL.md +274 -0
- package/dist/agents/skills/cursor/harness-data-pipeline/skill.yaml +81 -0
- package/dist/agents/skills/cursor/harness-data-validation/SKILL.md +343 -0
- package/dist/agents/skills/cursor/harness-data-validation/skill.yaml +75 -0
- package/dist/agents/skills/cursor/harness-database/SKILL.md +310 -0
- package/dist/agents/skills/cursor/harness-database/skill.yaml +80 -0
- package/dist/agents/skills/cursor/harness-debugging/SKILL.md +366 -0
- package/dist/agents/skills/cursor/harness-debugging/skill.yaml +48 -0
- package/dist/agents/skills/cursor/harness-dependency-health/SKILL.md +179 -0
- package/dist/agents/skills/cursor/harness-dependency-health/skill.yaml +42 -0
- package/dist/agents/skills/cursor/harness-deployment/SKILL.md +307 -0
- package/dist/agents/skills/cursor/harness-deployment/skill.yaml +77 -0
- package/dist/agents/skills/cursor/harness-design/SKILL.md +265 -0
- package/dist/agents/skills/cursor/harness-design/skill.yaml +54 -0
- package/dist/agents/skills/cursor/harness-design-mobile/SKILL.md +336 -0
- package/dist/agents/skills/cursor/harness-design-mobile/skill.yaml +50 -0
- package/dist/agents/skills/cursor/harness-design-system/SKILL.md +282 -0
- package/dist/agents/skills/cursor/harness-design-system/skill.yaml +51 -0
- package/dist/agents/skills/cursor/harness-design-web/SKILL.md +360 -0
- package/dist/agents/skills/cursor/harness-design-web/skill.yaml +53 -0
- package/dist/agents/skills/cursor/harness-diagnostics/SKILL.md +318 -0
- package/dist/agents/skills/cursor/harness-diagnostics/skill.yaml +51 -0
- package/dist/agents/skills/cursor/harness-docs-pipeline/SKILL.md +460 -0
- package/dist/agents/skills/cursor/harness-docs-pipeline/skill.yaml +70 -0
- package/dist/agents/skills/cursor/harness-dx/SKILL.md +276 -0
- package/dist/agents/skills/cursor/harness-dx/skill.yaml +76 -0
- package/dist/agents/skills/cursor/harness-e2e/SKILL.md +245 -0
- package/dist/agents/skills/cursor/harness-e2e/skill.yaml +78 -0
- package/dist/agents/skills/cursor/harness-event-driven/SKILL.md +280 -0
- package/dist/agents/skills/cursor/harness-event-driven/skill.yaml +77 -0
- package/dist/agents/skills/cursor/harness-execution/SKILL.md +510 -0
- package/dist/agents/skills/cursor/harness-execution/skill.yaml +52 -0
- package/dist/agents/skills/cursor/harness-feature-flags/SKILL.md +287 -0
- package/dist/agents/skills/cursor/harness-feature-flags/skill.yaml +74 -0
- package/dist/agents/skills/cursor/harness-git-workflow/SKILL.md +268 -0
- package/dist/agents/skills/cursor/harness-git-workflow/skill.yaml +32 -0
- package/dist/agents/skills/cursor/harness-hotspot-detector/SKILL.md +161 -0
- package/dist/agents/skills/cursor/harness-hotspot-detector/skill.yaml +45 -0
- package/dist/agents/skills/cursor/harness-i18n/SKILL.md +484 -0
- package/dist/agents/skills/cursor/harness-i18n/skill.yaml +55 -0
- package/dist/agents/skills/cursor/harness-i18n-process/SKILL.md +388 -0
- package/dist/agents/skills/cursor/harness-i18n-process/skill.yaml +44 -0
- package/dist/agents/skills/cursor/harness-i18n-workflow/SKILL.md +512 -0
- package/dist/agents/skills/cursor/harness-i18n-workflow/skill.yaml +54 -0
- package/dist/agents/skills/cursor/harness-impact-analysis/SKILL.md +184 -0
- package/dist/agents/skills/cursor/harness-impact-analysis/skill.yaml +45 -0
- package/dist/agents/skills/cursor/harness-incident-response/SKILL.md +223 -0
- package/dist/agents/skills/cursor/harness-incident-response/skill.yaml +78 -0
- package/dist/agents/skills/cursor/harness-infrastructure-as-code/SKILL.md +279 -0
- package/dist/agents/skills/cursor/harness-infrastructure-as-code/skill.yaml +80 -0
- package/dist/agents/skills/cursor/harness-integration-test/SKILL.md +271 -0
- package/dist/agents/skills/cursor/harness-integration-test/skill.yaml +73 -0
- package/dist/agents/skills/cursor/harness-integrity/SKILL.md +167 -0
- package/dist/agents/skills/cursor/harness-integrity/skill.yaml +48 -0
- package/dist/agents/skills/cursor/harness-knowledge-mapper/SKILL.md +195 -0
- package/dist/agents/skills/cursor/harness-knowledge-mapper/skill.yaml +50 -0
- package/dist/agents/skills/cursor/harness-load-testing/SKILL.md +274 -0
- package/dist/agents/skills/cursor/harness-load-testing/skill.yaml +79 -0
- package/dist/agents/skills/cursor/harness-ml-ops/SKILL.md +341 -0
- package/dist/agents/skills/cursor/harness-ml-ops/skill.yaml +79 -0
- package/dist/agents/skills/cursor/harness-mobile-patterns/SKILL.md +326 -0
- package/dist/agents/skills/cursor/harness-mobile-patterns/skill.yaml +82 -0
- package/dist/agents/skills/cursor/harness-mutation-test/SKILL.md +251 -0
- package/dist/agents/skills/cursor/harness-mutation-test/skill.yaml +70 -0
- package/dist/agents/skills/cursor/harness-observability/SKILL.md +283 -0
- package/dist/agents/skills/cursor/harness-observability/skill.yaml +78 -0
- package/dist/agents/skills/cursor/harness-onboarding/SKILL.md +288 -0
- package/dist/agents/skills/cursor/harness-onboarding/skill.yaml +31 -0
- package/dist/agents/skills/cursor/harness-parallel-agents/SKILL.md +256 -0
- package/dist/agents/skills/cursor/harness-parallel-agents/skill.yaml +34 -0
- package/dist/agents/skills/cursor/harness-perf/SKILL.md +260 -0
- package/dist/agents/skills/cursor/harness-perf/skill.yaml +51 -0
- package/dist/agents/skills/cursor/harness-perf-tdd/SKILL.md +249 -0
- package/dist/agents/skills/cursor/harness-perf-tdd/skill.yaml +48 -0
- package/dist/agents/skills/cursor/harness-planning/SKILL.md +579 -0
- package/dist/agents/skills/cursor/harness-planning/skill.yaml +56 -0
- package/dist/agents/skills/cursor/harness-pre-commit-review/SKILL.md +324 -0
- package/dist/agents/skills/cursor/harness-pre-commit-review/skill.yaml +34 -0
- package/dist/agents/skills/cursor/harness-product-spec/SKILL.md +285 -0
- package/dist/agents/skills/cursor/harness-product-spec/skill.yaml +72 -0
- package/dist/agents/skills/cursor/harness-property-test/SKILL.md +281 -0
- package/dist/agents/skills/cursor/harness-property-test/skill.yaml +71 -0
- package/dist/agents/skills/cursor/harness-refactoring/SKILL.md +169 -0
- package/dist/agents/skills/cursor/harness-refactoring/skill.yaml +34 -0
- package/dist/agents/skills/cursor/harness-release-readiness/SKILL.md +689 -0
- package/dist/agents/skills/cursor/harness-release-readiness/skill.yaml +58 -0
- package/dist/agents/skills/cursor/harness-resilience/SKILL.md +255 -0
- package/dist/agents/skills/cursor/harness-resilience/skill.yaml +76 -0
- package/dist/agents/skills/cursor/harness-roadmap/SKILL.md +595 -0
- package/dist/agents/skills/cursor/harness-roadmap/skill.yaml +44 -0
- package/dist/agents/skills/cursor/harness-secrets/SKILL.md +293 -0
- package/dist/agents/skills/cursor/harness-secrets/skill.yaml +76 -0
- package/dist/agents/skills/cursor/harness-security-review/SKILL.md +260 -0
- package/dist/agents/skills/cursor/harness-security-review/skill.yaml +53 -0
- package/dist/agents/skills/cursor/harness-security-scan/SKILL.md +154 -0
- package/dist/agents/skills/cursor/harness-security-scan/skill.yaml +42 -0
- package/dist/agents/skills/cursor/harness-skill-authoring/SKILL.md +292 -0
- package/dist/agents/skills/cursor/harness-skill-authoring/skill.yaml +33 -0
- package/dist/agents/skills/cursor/harness-soundness-review/SKILL.md +1267 -0
- package/dist/agents/skills/cursor/harness-soundness-review/skill.yaml +49 -0
- package/dist/agents/skills/cursor/harness-sql-review/SKILL.md +315 -0
- package/dist/agents/skills/cursor/harness-sql-review/skill.yaml +74 -0
- package/dist/agents/skills/cursor/harness-state-management/SKILL.md +309 -0
- package/dist/agents/skills/cursor/harness-state-management/skill.yaml +33 -0
- package/dist/agents/skills/cursor/harness-supply-chain-audit/SKILL.md +281 -0
- package/dist/agents/skills/cursor/harness-supply-chain-audit/skill.yaml +51 -0
- package/dist/agents/skills/cursor/harness-tdd/SKILL.md +177 -0
- package/dist/agents/skills/cursor/harness-tdd/skill.yaml +49 -0
- package/dist/agents/skills/cursor/harness-test-advisor/SKILL.md +160 -0
- package/dist/agents/skills/cursor/harness-test-advisor/skill.yaml +45 -0
- package/dist/agents/skills/cursor/harness-test-data/SKILL.md +268 -0
- package/dist/agents/skills/cursor/harness-test-data/skill.yaml +74 -0
- package/dist/agents/skills/cursor/harness-ux-copy/SKILL.md +271 -0
- package/dist/agents/skills/cursor/harness-ux-copy/skill.yaml +77 -0
- package/dist/agents/skills/cursor/harness-verification/SKILL.md +421 -0
- package/dist/agents/skills/cursor/harness-verification/skill.yaml +43 -0
- package/dist/agents/skills/cursor/harness-verify/SKILL.md +159 -0
- package/dist/agents/skills/cursor/harness-verify/skill.yaml +41 -0
- package/dist/agents/skills/cursor/harness-visual-regression/SKILL.md +257 -0
- package/dist/agents/skills/cursor/harness-visual-regression/skill.yaml +74 -0
- package/dist/agents/skills/cursor/initialize-harness-project/SKILL.md +232 -0
- package/dist/agents/skills/cursor/initialize-harness-project/skill.yaml +32 -0
- package/dist/agents/skills/cursor/validate-context-engineering/SKILL.md +150 -0
- package/dist/agents/skills/cursor/validate-context-engineering/skill.yaml +32 -0
- package/dist/agents/skills/gemini-cli/enforce-architecture/SKILL.md +52 -0
- package/dist/agents/skills/gemini-cli/harness-api-design/SKILL.md +52 -0
- package/dist/agents/skills/gemini-cli/harness-architecture-advisor/SKILL.md +52 -0
- package/dist/agents/skills/gemini-cli/harness-auth/SKILL.md +52 -0
- package/dist/agents/skills/gemini-cli/harness-autopilot/SKILL.md +355 -45
- package/dist/agents/skills/gemini-cli/harness-autopilot/skill.yaml +12 -0
- package/dist/agents/skills/gemini-cli/harness-code-review/SKILL.md +97 -3
- package/dist/agents/skills/gemini-cli/harness-code-review/skill.yaml +6 -0
- package/dist/agents/skills/gemini-cli/harness-codebase-cleanup/SKILL.md +2 -4
- package/dist/agents/skills/gemini-cli/harness-database/SKILL.md +52 -0
- package/dist/agents/skills/gemini-cli/harness-deployment/SKILL.md +52 -0
- package/dist/agents/skills/gemini-cli/harness-planning/SKILL.md +99 -3
- package/dist/agents/skills/gemini-cli/harness-planning/skill.yaml +6 -0
- package/dist/agents/skills/gemini-cli/harness-pre-commit-review/SKILL.md +1 -1
- package/dist/agents/skills/gemini-cli/harness-product-spec/SKILL.md +5 -5
- package/dist/agents/skills/gemini-cli/harness-security-review/SKILL.md +27 -7
- package/dist/agents/skills/gemini-cli/harness-security-scan/SKILL.md +52 -0
- package/dist/agents/skills/gemini-cli/harness-supply-chain-audit/SKILL.md +281 -0
- package/dist/agents/skills/gemini-cli/harness-supply-chain-audit/skill.yaml +51 -0
- package/dist/agents/skills/package.json +1 -0
- package/dist/agents/skills/templates/discipline-template.md +49 -0
- package/dist/agents/skills/tests/schema.ts +1 -1
- package/dist/agents/skills/vitest.config.mts +5 -0
- package/dist/{agents-md-YTYQDA3P.js → agents-md-VYDFPIRW.js} +1 -1
- package/dist/{architecture-JQZYM4US.js → architecture-K5HSRBGB.js} +2 -2
- package/dist/bin/harness-mcp.js +13 -13
- package/dist/bin/harness.js +21 -19
- package/dist/{check-phase-gate-L3RADYWO.js → check-phase-gate-5AS6SXL6.js} +3 -3
- package/dist/{chunk-6KTUUFRN.js → chunk-5ZXHMCPL.js} +1 -1
- package/dist/{chunk-RCWZBSK5.js → chunk-6KWBH4EO.js} +1 -1
- package/dist/{chunk-ABQHQ6I5.js → chunk-ALFKNAZW.js} +2436 -233
- package/dist/{chunk-OXLLOSSR.js → chunk-AV6KMDO5.js} +2 -2
- package/dist/{chunk-7IP4JIFL.js → chunk-C7DTKLPW.js} +4 -4
- package/dist/{chunk-ZOAWBDWU.js → chunk-CJDVBBPB.js} +5 -1
- package/dist/{chunk-YPYGXRDR.js → chunk-DNDBFIZN.js} +18 -4
- package/dist/{chunk-XYLGHKG6.js → chunk-HKUX2X7O.js} +11 -2
- package/dist/{chunk-YZD2MRNQ.js → chunk-JOP2NDNB.js} +684 -142
- package/dist/{chunk-YBJ262QL.js → chunk-LRG3B43J.js} +1 -1
- package/dist/{chunk-AOZRDOIP.js → chunk-M6TIO6NF.js} +1 -1
- package/dist/{chunk-O5OJVPL6.js → chunk-OCDDCGDE.js} +9 -1
- package/dist/{chunk-OSXBPAMK.js → chunk-QDF7COPQ.js} +1 -1
- package/dist/{chunk-TPOTOBR7.js → chunk-RWZPHW4H.js} +3 -3
- package/dist/{chunk-3C2MLBPJ.js → chunk-SFRGPAK6.js} +1 -1
- package/dist/{chunk-XKECDXJS.js → chunk-SHYWICGA.js} +2184 -456
- package/dist/{chunk-S2FXOWOR.js → chunk-TF6ZLHJV.js} +2 -2
- package/dist/{chunk-NLVUVUGD.js → chunk-ZJMU7MEV.js} +1 -1
- package/dist/{ci-workflow-EQZFVX3P.js → ci-workflow-CRWU723U.js} +1 -1
- package/dist/{create-skill-XSWHMSM5.js → create-skill-NDXQSTIK.js} +2 -2
- package/dist/{dist-HWXF2C3R.js → dist-4LPXJYVZ.js} +105 -1
- package/dist/{docs-7ECGYMAV.js → docs-4JRHTLUZ.js} +3 -3
- package/dist/{engine-EG4EH4IX.js → engine-3G3VIM6L.js} +1 -1
- package/dist/{entropy-5USWKLVS.js → entropy-G6CZ2A6P.js} +2 -2
- package/dist/{feedback-UTBXZZHF.js → feedback-QYKQ65HB.js} +1 -1
- package/dist/{generate-agent-definitions-3PM5EU7V.js → generate-agent-definitions-SAAOAPT4.js} +3 -3
- package/dist/index.d.ts +25 -4
- package/dist/index.js +18 -18
- package/dist/{loader-ZPALXIVR.js → loader-VCOK3PF7.js} +1 -1
- package/dist/{mcp-362EZHF4.js → mcp-YENEPHBW.js} +13 -13
- package/dist/{performance-OQAFMJUD.js → performance-UBCFI2UP.js} +4 -2
- package/dist/{review-pipeline-C4GCFVGP.js → review-pipeline-IQAVCWAX.js} +1 -1
- package/dist/{runtime-7YLVK453.js → runtime-PYFFIESU.js} +1 -1
- package/dist/{security-PZOX7AQS.js → security-ZDADTPYW.js} +1 -1
- package/dist/{skill-executor-XZLYZYAK.js → skill-executor-XEVDGXUM.js} +2 -2
- package/dist/{validate-FD3Z6VJD.js → validate-VRTUHALQ.js} +2 -2
- package/dist/{validate-cross-check-WNJM6H2D.js → validate-cross-check-4Y6NHNK3.js} +1 -1
- package/package.json +8 -5
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
detectEntropyDefinition,
|
|
3
3
|
handleDetectEntropy
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-AV6KMDO5.js";
|
|
5
5
|
import {
|
|
6
6
|
checkPerformanceDefinition,
|
|
7
7
|
getCriticalPathsDefinition,
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
handleGetPerfBaselines,
|
|
12
12
|
handleUpdatePerfBaselines,
|
|
13
13
|
updatePerfBaselinesDefinition
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-DNDBFIZN.js";
|
|
15
15
|
import {
|
|
16
16
|
analyzeDiffDefinition,
|
|
17
17
|
createSelfReviewDefinition,
|
|
@@ -19,43 +19,45 @@ import {
|
|
|
19
19
|
handleCreateSelfReview,
|
|
20
20
|
handleRequestPeerReview,
|
|
21
21
|
requestPeerReviewDefinition
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-RWZPHW4H.js";
|
|
23
23
|
import {
|
|
24
24
|
handleRunSecurityScan,
|
|
25
25
|
runSecurityScanDefinition
|
|
26
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-QDF7COPQ.js";
|
|
27
27
|
import {
|
|
28
28
|
handleRunCodeReview,
|
|
29
29
|
runCodeReviewDefinition
|
|
30
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-ZJMU7MEV.js";
|
|
31
31
|
import {
|
|
32
32
|
GENERATED_HEADER_CLAUDE,
|
|
33
|
+
GENERATED_HEADER_CODEX,
|
|
34
|
+
GENERATED_HEADER_CURSOR,
|
|
33
35
|
GENERATED_HEADER_GEMINI,
|
|
34
36
|
VALID_PLATFORMS,
|
|
35
37
|
applySyncPlan,
|
|
36
38
|
computeSyncPlan
|
|
37
|
-
} from "./chunk-
|
|
39
|
+
} from "./chunk-CJDVBBPB.js";
|
|
38
40
|
import {
|
|
39
41
|
handleValidateProject,
|
|
40
42
|
validateToolDefinition
|
|
41
|
-
} from "./chunk-
|
|
43
|
+
} from "./chunk-TF6ZLHJV.js";
|
|
42
44
|
import {
|
|
43
45
|
loadGraphStore
|
|
44
46
|
} from "./chunk-FTMXDOR6.js";
|
|
45
47
|
import {
|
|
46
48
|
checkDependenciesDefinition,
|
|
47
49
|
handleCheckDependencies
|
|
48
|
-
} from "./chunk-
|
|
50
|
+
} from "./chunk-SFRGPAK6.js";
|
|
49
51
|
import {
|
|
50
52
|
resolveProjectConfig
|
|
51
53
|
} from "./chunk-H7Y5CKTM.js";
|
|
52
54
|
import {
|
|
53
55
|
checkDocsDefinition,
|
|
54
56
|
handleCheckDocs
|
|
55
|
-
} from "./chunk-
|
|
57
|
+
} from "./chunk-C7DTKLPW.js";
|
|
56
58
|
import {
|
|
57
59
|
resolveConfig
|
|
58
|
-
} from "./chunk-
|
|
60
|
+
} from "./chunk-OCDDCGDE.js";
|
|
59
61
|
import {
|
|
60
62
|
resultToMcpResponse
|
|
61
63
|
} from "./chunk-IDZNPTYD.js";
|
|
@@ -78,7 +80,13 @@ import {
|
|
|
78
80
|
} from "./chunk-3WGJMBKH.js";
|
|
79
81
|
import {
|
|
80
82
|
SkillMetadataSchema
|
|
81
|
-
} from "./chunk-
|
|
83
|
+
} from "./chunk-HKUX2X7O.js";
|
|
84
|
+
import {
|
|
85
|
+
DESTRUCTIVE_BASH,
|
|
86
|
+
checkTaint,
|
|
87
|
+
scanForInjection,
|
|
88
|
+
writeTaint
|
|
89
|
+
} from "./chunk-ALFKNAZW.js";
|
|
82
90
|
import {
|
|
83
91
|
Err,
|
|
84
92
|
Ok
|
|
@@ -94,6 +102,123 @@ import {
|
|
|
94
102
|
ReadResourceRequestSchema
|
|
95
103
|
} from "@modelcontextprotocol/sdk/types.js";
|
|
96
104
|
|
|
105
|
+
// src/mcp/middleware/injection-guard.ts
|
|
106
|
+
import { realpathSync } from "fs";
|
|
107
|
+
import { resolve } from "path";
|
|
108
|
+
function isDestructiveBash(command) {
|
|
109
|
+
return DESTRUCTIVE_BASH.some((p) => p.test(command));
|
|
110
|
+
}
|
|
111
|
+
function isOutsideWorkspace(filePath, workspaceRoot) {
|
|
112
|
+
if (!filePath || !workspaceRoot) return false;
|
|
113
|
+
const resolved = resolve(workspaceRoot, filePath);
|
|
114
|
+
let realResolved = resolved;
|
|
115
|
+
try {
|
|
116
|
+
realResolved = realpathSync(resolved);
|
|
117
|
+
} catch {
|
|
118
|
+
}
|
|
119
|
+
return !realResolved.startsWith(workspaceRoot);
|
|
120
|
+
}
|
|
121
|
+
var INPUT_EXTRACTORS = {
|
|
122
|
+
Bash: (input) => input?.command ?? "",
|
|
123
|
+
Write: (input) => input?.content ?? "",
|
|
124
|
+
Edit: (input) => `${input?.old_string ?? ""}
|
|
125
|
+
${input?.new_string ?? ""}`,
|
|
126
|
+
Read: (input) => input?.file_path ?? ""
|
|
127
|
+
};
|
|
128
|
+
function extractInputText(toolName, toolInput) {
|
|
129
|
+
const extractor = INPUT_EXTRACTORS[toolName];
|
|
130
|
+
if (extractor) return extractor(toolInput);
|
|
131
|
+
const parts = Object.values(toolInput || {}).filter((v) => typeof v === "string");
|
|
132
|
+
return parts.length > 0 ? parts.join("\n") : null;
|
|
133
|
+
}
|
|
134
|
+
function extractResultText(result) {
|
|
135
|
+
return result.content.filter((c) => c.type === "text").map((c) => c.text).join("\n");
|
|
136
|
+
}
|
|
137
|
+
function isDestructiveOperation(toolName, toolInput, workspaceRoot) {
|
|
138
|
+
const normalized = toolName.toLowerCase().replace(/_/g, "");
|
|
139
|
+
if (normalized === "bash") {
|
|
140
|
+
const command = toolInput?.command ?? "";
|
|
141
|
+
return isDestructiveBash(command);
|
|
142
|
+
}
|
|
143
|
+
if (normalized === "write" || normalized === "edit") {
|
|
144
|
+
const filePath = toolInput?.file_path ?? "";
|
|
145
|
+
return isOutsideWorkspace(filePath, workspaceRoot);
|
|
146
|
+
}
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
function wrapWithInjectionGuard(toolName, handler, options = {}) {
|
|
150
|
+
const projectRoot = options.projectRoot ?? process.cwd();
|
|
151
|
+
const sessionId = options.sessionId ?? "default";
|
|
152
|
+
return async (input) => {
|
|
153
|
+
try {
|
|
154
|
+
const taintCheck = checkTaint(projectRoot, sessionId);
|
|
155
|
+
if (taintCheck.tainted && isDestructiveOperation(toolName, input, projectRoot)) {
|
|
156
|
+
return {
|
|
157
|
+
content: [
|
|
158
|
+
{
|
|
159
|
+
type: "text",
|
|
160
|
+
text: `BLOCKED by Sentinel: "${toolName}" blocked during tainted session. Destructive operations are restricted. Run "harness taint clear" to lift.`
|
|
161
|
+
}
|
|
162
|
+
],
|
|
163
|
+
isError: true
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
const textToScan = extractInputText(toolName, input);
|
|
167
|
+
if (textToScan) {
|
|
168
|
+
const findings = scanForInjection(textToScan);
|
|
169
|
+
const actionable = findings.filter(
|
|
170
|
+
(f) => f.severity === "high" || f.severity === "medium"
|
|
171
|
+
);
|
|
172
|
+
if (actionable.length > 0) {
|
|
173
|
+
writeTaint(
|
|
174
|
+
projectRoot,
|
|
175
|
+
sessionId,
|
|
176
|
+
`Injection pattern detected in MCP:${toolName} input`,
|
|
177
|
+
actionable,
|
|
178
|
+
`MCP:${toolName}`
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
const result = await handler(input);
|
|
183
|
+
const outputText = extractResultText(result);
|
|
184
|
+
if (outputText) {
|
|
185
|
+
const outputFindings = scanForInjection(outputText);
|
|
186
|
+
const actionableOutput = outputFindings.filter(
|
|
187
|
+
(f) => f.severity === "high" || f.severity === "medium"
|
|
188
|
+
);
|
|
189
|
+
if (actionableOutput.length > 0) {
|
|
190
|
+
writeTaint(
|
|
191
|
+
projectRoot,
|
|
192
|
+
sessionId,
|
|
193
|
+
`Injection pattern detected in MCP:${toolName} result`,
|
|
194
|
+
actionableOutput,
|
|
195
|
+
`MCP:${toolName}:output`
|
|
196
|
+
);
|
|
197
|
+
const warningLines = actionableOutput.map(
|
|
198
|
+
(f) => `Sentinel [${f.severity}] ${f.ruleId}: detected in ${toolName} output`
|
|
199
|
+
);
|
|
200
|
+
result.content.push({
|
|
201
|
+
type: "text",
|
|
202
|
+
text: `
|
|
203
|
+
---
|
|
204
|
+
Sentinel Warning: ${warningLines.join("; ")}`
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
return result;
|
|
209
|
+
} catch {
|
|
210
|
+
return handler(input);
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
function applyInjectionGuard(handlers, options = {}) {
|
|
215
|
+
const wrapped = {};
|
|
216
|
+
for (const [name, handler] of Object.entries(handlers)) {
|
|
217
|
+
wrapped[name] = wrapWithInjectionGuard(name, handler, options);
|
|
218
|
+
}
|
|
219
|
+
return wrapped;
|
|
220
|
+
}
|
|
221
|
+
|
|
97
222
|
// src/mcp/tools/linter.ts
|
|
98
223
|
var generateLinterDefinition = {
|
|
99
224
|
name: "generate_linter",
|
|
@@ -428,7 +553,7 @@ ${skippedMsg}`
|
|
|
428
553
|
async function handleInitProject(input) {
|
|
429
554
|
const i = input;
|
|
430
555
|
try {
|
|
431
|
-
const { TemplateEngine } = await import("./engine-
|
|
556
|
+
const { TemplateEngine } = await import("./engine-3G3VIM6L.js");
|
|
432
557
|
const engine = new TemplateEngine(resolveTemplatesDir());
|
|
433
558
|
const safePath = sanitizePath(i.path);
|
|
434
559
|
const detected = tryDetectFramework(engine, safePath, i);
|
|
@@ -449,7 +574,7 @@ var listPersonasDefinition = {
|
|
|
449
574
|
inputSchema: { type: "object", properties: {} }
|
|
450
575
|
};
|
|
451
576
|
async function handleListPersonas() {
|
|
452
|
-
const { listPersonas } = await import("./loader-
|
|
577
|
+
const { listPersonas } = await import("./loader-VCOK3PF7.js");
|
|
453
578
|
const result = listPersonas(resolvePersonasDir());
|
|
454
579
|
return resultToMcpResponse(result);
|
|
455
580
|
}
|
|
@@ -473,10 +598,10 @@ async function handleGeneratePersonaArtifacts(input) {
|
|
|
473
598
|
if (!/^[a-z0-9][a-z0-9._-]*$/i.test(input.name)) {
|
|
474
599
|
return resultToMcpResponse(Err(new Error(`Invalid persona name: ${input.name}`)));
|
|
475
600
|
}
|
|
476
|
-
const { loadPersona } = await import("./loader-
|
|
477
|
-
const { generateRuntime } = await import("./runtime-
|
|
478
|
-
const { generateAgentsMd } = await import("./agents-md-
|
|
479
|
-
const { generateCIWorkflow } = await import("./ci-workflow-
|
|
601
|
+
const { loadPersona } = await import("./loader-VCOK3PF7.js");
|
|
602
|
+
const { generateRuntime } = await import("./runtime-PYFFIESU.js");
|
|
603
|
+
const { generateAgentsMd } = await import("./agents-md-VYDFPIRW.js");
|
|
604
|
+
const { generateCIWorkflow } = await import("./ci-workflow-CRWU723U.js");
|
|
480
605
|
const personasDir = resolvePersonasDir();
|
|
481
606
|
const filePath = path3.join(personasDir, `${input.name}.yaml`);
|
|
482
607
|
if (!filePath.startsWith(personasDir)) {
|
|
@@ -531,9 +656,9 @@ async function handleRunPersona(input) {
|
|
|
531
656
|
if (!/^[a-z0-9][a-z0-9._-]*$/i.test(input.persona)) {
|
|
532
657
|
return resultToMcpResponse(Err(new Error(`Invalid persona name: ${input.persona}`)));
|
|
533
658
|
}
|
|
534
|
-
const { loadPersona } = await import("./loader-
|
|
659
|
+
const { loadPersona } = await import("./loader-VCOK3PF7.js");
|
|
535
660
|
const { runPersona } = await import("./runner-VMYLHWOC.js");
|
|
536
|
-
const { executeSkill } = await import("./skill-executor-
|
|
661
|
+
const { executeSkill } = await import("./skill-executor-XEVDGXUM.js");
|
|
537
662
|
const personasDir = resolvePersonasDir();
|
|
538
663
|
const filePath = path3.join(personasDir, `${input.persona}.yaml`);
|
|
539
664
|
if (!filePath.startsWith(personasDir)) {
|
|
@@ -944,8 +1069,8 @@ var runSkillDefinition = {
|
|
|
944
1069
|
path: { type: "string", description: "Path to project root for state context injection" },
|
|
945
1070
|
complexity: {
|
|
946
1071
|
type: "string",
|
|
947
|
-
enum: ["
|
|
948
|
-
description: "
|
|
1072
|
+
enum: ["fast", "standard", "thorough"],
|
|
1073
|
+
description: "Rigor level: fast (minimal), standard (default), thorough (full)"
|
|
949
1074
|
},
|
|
950
1075
|
phase: { type: "string", description: "Start at a specific phase (re-entry)" },
|
|
951
1076
|
party: { type: "boolean", description: "Enable multi-perspective evaluation" }
|
|
@@ -1031,7 +1156,7 @@ var createSkillDefinition = {
|
|
|
1031
1156
|
};
|
|
1032
1157
|
async function handleCreateSkill(input) {
|
|
1033
1158
|
try {
|
|
1034
|
-
const { generateSkillFiles } = await import("./create-skill-
|
|
1159
|
+
const { generateSkillFiles } = await import("./create-skill-NDXQSTIK.js");
|
|
1035
1160
|
const result = generateSkillFiles({
|
|
1036
1161
|
name: input.name,
|
|
1037
1162
|
description: input.description,
|
|
@@ -1142,6 +1267,26 @@ async function getLearningsResource(projectRoot) {
|
|
|
1142
1267
|
return sections.length > 0 ? sections.join("\n\n---\n\n") : "No learnings files found.";
|
|
1143
1268
|
}
|
|
1144
1269
|
|
|
1270
|
+
// src/mcp/tools/roadmap-auto-sync.ts
|
|
1271
|
+
import * as fs10 from "fs";
|
|
1272
|
+
import * as path11 from "path";
|
|
1273
|
+
async function autoSyncRoadmap(projectPath) {
|
|
1274
|
+
try {
|
|
1275
|
+
const roadmapFile = path11.join(projectPath, "docs", "roadmap.md");
|
|
1276
|
+
if (!fs10.existsSync(roadmapFile)) return;
|
|
1277
|
+
const { parseRoadmap, serializeRoadmap, syncRoadmap, applySyncChanges } = await import("./dist-4LPXJYVZ.js");
|
|
1278
|
+
const raw = fs10.readFileSync(roadmapFile, "utf-8");
|
|
1279
|
+
const parseResult = parseRoadmap(raw);
|
|
1280
|
+
if (!parseResult.ok) return;
|
|
1281
|
+
const roadmap = parseResult.value;
|
|
1282
|
+
const syncResult = syncRoadmap({ projectPath, roadmap });
|
|
1283
|
+
if (!syncResult.ok || syncResult.value.length === 0) return;
|
|
1284
|
+
applySyncChanges(roadmap, syncResult.value);
|
|
1285
|
+
fs10.writeFileSync(roadmapFile, serializeRoadmap(roadmap), "utf-8");
|
|
1286
|
+
} catch {
|
|
1287
|
+
}
|
|
1288
|
+
}
|
|
1289
|
+
|
|
1145
1290
|
// src/mcp/utils.ts
|
|
1146
1291
|
function mcpError(text) {
|
|
1147
1292
|
return { content: [{ type: "text", text }], isError: true };
|
|
@@ -1215,12 +1360,12 @@ var manageStateDefinition = {
|
|
|
1215
1360
|
}
|
|
1216
1361
|
};
|
|
1217
1362
|
async function handleShow(projectPath, input) {
|
|
1218
|
-
const { loadState } = await import("./dist-
|
|
1363
|
+
const { loadState } = await import("./dist-4LPXJYVZ.js");
|
|
1219
1364
|
return resultToMcpResponse(await loadState(projectPath, input.stream, input.session));
|
|
1220
1365
|
}
|
|
1221
1366
|
async function handleLearn(projectPath, input) {
|
|
1222
1367
|
if (!input.learning) return mcpError("Error: learning is required for learn action");
|
|
1223
|
-
const { appendLearning } = await import("./dist-
|
|
1368
|
+
const { appendLearning } = await import("./dist-4LPXJYVZ.js");
|
|
1224
1369
|
const result = await appendLearning(
|
|
1225
1370
|
projectPath,
|
|
1226
1371
|
input.learning,
|
|
@@ -1235,7 +1380,7 @@ async function handleLearn(projectPath, input) {
|
|
|
1235
1380
|
async function handleFailure(projectPath, input) {
|
|
1236
1381
|
if (!input.description) return mcpError("Error: description is required for failure action");
|
|
1237
1382
|
if (!input.failureType) return mcpError("Error: failureType is required for failure action");
|
|
1238
|
-
const { appendFailure } = await import("./dist-
|
|
1383
|
+
const { appendFailure } = await import("./dist-4LPXJYVZ.js");
|
|
1239
1384
|
const result = await appendFailure(
|
|
1240
1385
|
projectPath,
|
|
1241
1386
|
input.description,
|
|
@@ -1248,34 +1393,36 @@ async function handleFailure(projectPath, input) {
|
|
|
1248
1393
|
return resultToMcpResponse(Ok({ recorded: true }));
|
|
1249
1394
|
}
|
|
1250
1395
|
async function handleArchive(projectPath, input) {
|
|
1251
|
-
const { archiveFailures } = await import("./dist-
|
|
1396
|
+
const { archiveFailures } = await import("./dist-4LPXJYVZ.js");
|
|
1252
1397
|
const result = await archiveFailures(projectPath, input.stream, input.session);
|
|
1253
1398
|
if (!result.ok) return resultToMcpResponse(result);
|
|
1254
1399
|
return resultToMcpResponse(Ok({ archived: true }));
|
|
1255
1400
|
}
|
|
1256
1401
|
async function handleReset(projectPath, input) {
|
|
1257
|
-
const { saveState, DEFAULT_STATE } = await import("./dist-
|
|
1402
|
+
const { saveState, DEFAULT_STATE } = await import("./dist-4LPXJYVZ.js");
|
|
1258
1403
|
const result = await saveState(projectPath, { ...DEFAULT_STATE }, input.stream, input.session);
|
|
1259
1404
|
if (!result.ok) return resultToMcpResponse(result);
|
|
1260
1405
|
return resultToMcpResponse(Ok({ reset: true }));
|
|
1261
1406
|
}
|
|
1262
1407
|
async function handleGate(projectPath, _input) {
|
|
1263
|
-
const { runMechanicalGate } = await import("./dist-
|
|
1408
|
+
const { runMechanicalGate } = await import("./dist-4LPXJYVZ.js");
|
|
1264
1409
|
return resultToMcpResponse(await runMechanicalGate(projectPath));
|
|
1265
1410
|
}
|
|
1266
1411
|
async function handleSaveHandoff(projectPath, input) {
|
|
1267
1412
|
if (!input.handoff) return mcpError("Error: handoff is required for save-handoff action");
|
|
1268
|
-
const { saveHandoff } = await import("./dist-
|
|
1413
|
+
const { saveHandoff } = await import("./dist-4LPXJYVZ.js");
|
|
1269
1414
|
const result = await saveHandoff(
|
|
1270
1415
|
projectPath,
|
|
1271
1416
|
input.handoff,
|
|
1272
1417
|
input.stream,
|
|
1273
1418
|
input.session
|
|
1274
1419
|
);
|
|
1275
|
-
|
|
1420
|
+
if (!result.ok) return resultToMcpResponse(result);
|
|
1421
|
+
await autoSyncRoadmap(projectPath);
|
|
1422
|
+
return resultToMcpResponse(Ok({ saved: true }));
|
|
1276
1423
|
}
|
|
1277
1424
|
async function handleLoadHandoff(projectPath, input) {
|
|
1278
|
-
const { loadHandoff } = await import("./dist-
|
|
1425
|
+
const { loadHandoff } = await import("./dist-4LPXJYVZ.js");
|
|
1279
1426
|
return resultToMcpResponse(await loadHandoff(projectPath, input.stream, input.session));
|
|
1280
1427
|
}
|
|
1281
1428
|
async function handleAppendEntry(projectPath, input) {
|
|
@@ -1283,7 +1430,7 @@ async function handleAppendEntry(projectPath, input) {
|
|
|
1283
1430
|
if (!input.section) return mcpError("Error: section is required for append_entry action");
|
|
1284
1431
|
if (!input.authorSkill) return mcpError("Error: authorSkill is required for append_entry action");
|
|
1285
1432
|
if (!input.content) return mcpError("Error: content is required for append_entry action");
|
|
1286
|
-
const { appendSessionEntry } = await import("./dist-
|
|
1433
|
+
const { appendSessionEntry } = await import("./dist-4LPXJYVZ.js");
|
|
1287
1434
|
const result = await appendSessionEntry(
|
|
1288
1435
|
projectPath,
|
|
1289
1436
|
input.session,
|
|
@@ -1299,7 +1446,7 @@ async function handleUpdateEntryStatus(projectPath, input) {
|
|
|
1299
1446
|
if (!input.entryId) return mcpError("Error: entryId is required for update_entry_status action");
|
|
1300
1447
|
if (!input.newStatus)
|
|
1301
1448
|
return mcpError("Error: newStatus is required for update_entry_status action");
|
|
1302
|
-
const { updateSessionEntryStatus } = await import("./dist-
|
|
1449
|
+
const { updateSessionEntryStatus } = await import("./dist-4LPXJYVZ.js");
|
|
1303
1450
|
const result = await updateSessionEntryStatus(
|
|
1304
1451
|
projectPath,
|
|
1305
1452
|
input.session,
|
|
@@ -1312,7 +1459,7 @@ async function handleUpdateEntryStatus(projectPath, input) {
|
|
|
1312
1459
|
async function handleReadSection(projectPath, input) {
|
|
1313
1460
|
if (!input.session) return mcpError("Error: session is required for read_section action");
|
|
1314
1461
|
if (!input.section) return mcpError("Error: section is required for read_section action");
|
|
1315
|
-
const { readSessionSection } = await import("./dist-
|
|
1462
|
+
const { readSessionSection } = await import("./dist-4LPXJYVZ.js");
|
|
1316
1463
|
const result = await readSessionSection(
|
|
1317
1464
|
projectPath,
|
|
1318
1465
|
input.session,
|
|
@@ -1322,15 +1469,16 @@ async function handleReadSection(projectPath, input) {
|
|
|
1322
1469
|
}
|
|
1323
1470
|
async function handleReadSections(projectPath, input) {
|
|
1324
1471
|
if (!input.session) return mcpError("Error: session is required for read_sections action");
|
|
1325
|
-
const { readSessionSections } = await import("./dist-
|
|
1472
|
+
const { readSessionSections } = await import("./dist-4LPXJYVZ.js");
|
|
1326
1473
|
const result = await readSessionSections(projectPath, input.session);
|
|
1327
1474
|
return resultToMcpResponse(result);
|
|
1328
1475
|
}
|
|
1329
1476
|
async function handleArchiveSession(projectPath, input) {
|
|
1330
1477
|
if (!input.session) return mcpError("Error: session is required for archive_session action");
|
|
1331
|
-
const { archiveSession } = await import("./dist-
|
|
1478
|
+
const { archiveSession } = await import("./dist-4LPXJYVZ.js");
|
|
1332
1479
|
const result = await archiveSession(projectPath, input.session);
|
|
1333
1480
|
if (!result.ok) return resultToMcpResponse(result);
|
|
1481
|
+
await autoSyncRoadmap(projectPath);
|
|
1334
1482
|
return resultToMcpResponse(Ok({ archived: true }));
|
|
1335
1483
|
}
|
|
1336
1484
|
var ACTION_HANDLERS = {
|
|
@@ -1371,7 +1519,7 @@ var listStreamsDefinition = {
|
|
|
1371
1519
|
};
|
|
1372
1520
|
async function handleListStreams(input) {
|
|
1373
1521
|
try {
|
|
1374
|
-
const { listStreams, loadStreamIndex } = await import("./dist-
|
|
1522
|
+
const { listStreams, loadStreamIndex } = await import("./dist-4LPXJYVZ.js");
|
|
1375
1523
|
const projectPath = sanitizePath(input.path);
|
|
1376
1524
|
const indexResult = await loadStreamIndex(projectPath);
|
|
1377
1525
|
const streamsResult = await listStreams(projectPath);
|
|
@@ -1409,7 +1557,7 @@ var checkPhaseGateDefinition = {
|
|
|
1409
1557
|
};
|
|
1410
1558
|
async function handleCheckPhaseGate(input) {
|
|
1411
1559
|
try {
|
|
1412
|
-
const { runCheckPhaseGate } = await import("./check-phase-gate-
|
|
1560
|
+
const { runCheckPhaseGate } = await import("./check-phase-gate-5AS6SXL6.js");
|
|
1413
1561
|
const result = await runCheckPhaseGate({ cwd: sanitizePath(input.path) });
|
|
1414
1562
|
if (result.ok) {
|
|
1415
1563
|
return { content: [{ type: "text", text: JSON.stringify(result.value) }] };
|
|
@@ -1429,7 +1577,7 @@ async function handleCheckPhaseGate(input) {
|
|
|
1429
1577
|
}
|
|
1430
1578
|
|
|
1431
1579
|
// src/mcp/tools/cross-check.ts
|
|
1432
|
-
import * as
|
|
1580
|
+
import * as path12 from "path";
|
|
1433
1581
|
var validateCrossCheckDefinition = {
|
|
1434
1582
|
name: "validate_cross_check",
|
|
1435
1583
|
description: "Validate plan-to-implementation coverage: checks that specs have plans and plans have implementations, detects staleness",
|
|
@@ -1465,15 +1613,15 @@ async function handleValidateCrossCheck(input) {
|
|
|
1465
1613
|
};
|
|
1466
1614
|
}
|
|
1467
1615
|
try {
|
|
1468
|
-
const { runCrossCheck } = await import("./validate-cross-check-
|
|
1469
|
-
const specsDir =
|
|
1616
|
+
const { runCrossCheck } = await import("./validate-cross-check-4Y6NHNK3.js");
|
|
1617
|
+
const specsDir = path12.resolve(projectPath, input.specsDir ?? "docs/specs");
|
|
1470
1618
|
if (!specsDir.startsWith(projectPath)) {
|
|
1471
1619
|
return {
|
|
1472
1620
|
content: [{ type: "text", text: "Error: specsDir escapes project root" }],
|
|
1473
1621
|
isError: true
|
|
1474
1622
|
};
|
|
1475
1623
|
}
|
|
1476
|
-
const plansDir =
|
|
1624
|
+
const plansDir = path12.resolve(projectPath, input.plansDir ?? "docs/plans");
|
|
1477
1625
|
if (!plansDir.startsWith(projectPath)) {
|
|
1478
1626
|
return {
|
|
1479
1627
|
content: [{ type: "text", text: "Error: plansDir escapes project root" }],
|
|
@@ -1504,14 +1652,14 @@ async function handleValidateCrossCheck(input) {
|
|
|
1504
1652
|
|
|
1505
1653
|
// src/commands/generate-slash-commands.ts
|
|
1506
1654
|
import { Command } from "commander";
|
|
1507
|
-
import
|
|
1508
|
-
import
|
|
1655
|
+
import fs13 from "fs";
|
|
1656
|
+
import path15 from "path";
|
|
1509
1657
|
import os from "os";
|
|
1510
1658
|
import readline from "readline";
|
|
1511
1659
|
|
|
1512
1660
|
// src/slash-commands/normalize.ts
|
|
1513
|
-
import
|
|
1514
|
-
import
|
|
1661
|
+
import fs11 from "fs";
|
|
1662
|
+
import path13 from "path";
|
|
1515
1663
|
import { parse as parse3 } from "yaml";
|
|
1516
1664
|
|
|
1517
1665
|
// src/slash-commands/normalize-name.ts
|
|
@@ -1531,14 +1679,18 @@ function normalizeName(skillName) {
|
|
|
1531
1679
|
function readSkillYaml(yamlPath) {
|
|
1532
1680
|
let raw;
|
|
1533
1681
|
try {
|
|
1534
|
-
raw =
|
|
1682
|
+
raw = fs11.readFileSync(yamlPath, "utf-8");
|
|
1535
1683
|
} catch {
|
|
1536
1684
|
return null;
|
|
1537
1685
|
}
|
|
1538
1686
|
return SkillMetadataSchema.safeParse(parse3(raw));
|
|
1539
1687
|
}
|
|
1688
|
+
var DERIVED_FROM_CLAUDE_CODE = ["cursor", "codex"];
|
|
1540
1689
|
function shouldSkipSkill(meta, platforms) {
|
|
1541
|
-
const
|
|
1690
|
+
const effectivePlatforms = platforms.map(
|
|
1691
|
+
(p) => DERIVED_FROM_CLAUDE_CODE.includes(p) ? "claude-code" : p
|
|
1692
|
+
);
|
|
1693
|
+
const matchesPlatform = effectivePlatforms.some((p) => meta.platforms.includes(p));
|
|
1542
1694
|
if (!matchesPlatform) return true;
|
|
1543
1695
|
if (meta.tier === 3 || meta.internal) return true;
|
|
1544
1696
|
return false;
|
|
@@ -1591,10 +1743,10 @@ function buildProcessLines(meta) {
|
|
|
1591
1743
|
];
|
|
1592
1744
|
}
|
|
1593
1745
|
function buildSpec(meta, normalized, entry, skillsDir, source) {
|
|
1594
|
-
const skillMdPath =
|
|
1595
|
-
const skillMdContent =
|
|
1596
|
-
const skillMdRelative =
|
|
1597
|
-
const skillYamlRelative =
|
|
1746
|
+
const skillMdPath = path13.join(skillsDir, entry.name, "SKILL.md");
|
|
1747
|
+
const skillMdContent = fs11.existsSync(skillMdPath) ? fs11.readFileSync(skillMdPath, "utf-8") : "";
|
|
1748
|
+
const skillMdRelative = path13.relative(process.cwd(), skillMdPath).replaceAll("\\", "/");
|
|
1749
|
+
const skillYamlRelative = path13.relative(process.cwd(), path13.join(skillsDir, entry.name, "skill.yaml")).replaceAll("\\", "/");
|
|
1598
1750
|
const args = (meta.cli?.args ?? []).map((a) => ({
|
|
1599
1751
|
name: a.name,
|
|
1600
1752
|
description: a.description ?? "",
|
|
@@ -1619,6 +1771,7 @@ function buildSpec(meta, normalized, entry, skillsDir, source) {
|
|
|
1619
1771
|
sourceDir: entry.name,
|
|
1620
1772
|
skillsBaseDir: skillsDir,
|
|
1621
1773
|
source,
|
|
1774
|
+
...meta.cursor ? { cursor: meta.cursor } : {},
|
|
1622
1775
|
prompt: {
|
|
1623
1776
|
context: buildContextLines(meta).join("\n"),
|
|
1624
1777
|
objective: buildObjectiveLines(meta).join("\n"),
|
|
@@ -1631,11 +1784,11 @@ function normalizeSkills(skillSources, platforms) {
|
|
|
1631
1784
|
const specs = [];
|
|
1632
1785
|
const nameMap = /* @__PURE__ */ new Map();
|
|
1633
1786
|
for (const { dir: skillsDir, source } of skillSources) {
|
|
1634
|
-
if (!
|
|
1635
|
-
const entries =
|
|
1787
|
+
if (!fs11.existsSync(skillsDir)) continue;
|
|
1788
|
+
const entries = fs11.readdirSync(skillsDir, { withFileTypes: true }).filter((d) => d.isDirectory());
|
|
1636
1789
|
for (const entry of entries) {
|
|
1637
|
-
const yamlPath =
|
|
1638
|
-
if (!
|
|
1790
|
+
const yamlPath = path13.join(skillsDir, entry.name, "skill.yaml");
|
|
1791
|
+
if (!fs11.existsSync(yamlPath)) continue;
|
|
1639
1792
|
const result = readSkillYaml(yamlPath);
|
|
1640
1793
|
if (!result) continue;
|
|
1641
1794
|
if (!result.success) {
|
|
@@ -1743,27 +1896,140 @@ function renderGemini(spec, skillMdContent, skillYamlContent) {
|
|
|
1743
1896
|
return lines.join("\n");
|
|
1744
1897
|
}
|
|
1745
1898
|
|
|
1899
|
+
// src/slash-commands/render-cursor.ts
|
|
1900
|
+
function renderCursor(spec, skillMdContent, cursorConfig) {
|
|
1901
|
+
const lines = ["---"];
|
|
1902
|
+
lines.push(`description: ${spec.description}`);
|
|
1903
|
+
if (cursorConfig?.globs && cursorConfig.globs.length > 0) {
|
|
1904
|
+
lines.push("globs:");
|
|
1905
|
+
for (const glob of cursorConfig.globs) {
|
|
1906
|
+
lines.push(` - ${glob}`);
|
|
1907
|
+
}
|
|
1908
|
+
}
|
|
1909
|
+
const alwaysApply = cursorConfig?.alwaysApply ?? false;
|
|
1910
|
+
lines.push(`alwaysApply: ${alwaysApply}`);
|
|
1911
|
+
lines.push("---");
|
|
1912
|
+
lines.push("");
|
|
1913
|
+
lines.push(GENERATED_HEADER_CURSOR);
|
|
1914
|
+
lines.push("");
|
|
1915
|
+
lines.push(skillMdContent);
|
|
1916
|
+
lines.push("");
|
|
1917
|
+
return lines.join("\n");
|
|
1918
|
+
}
|
|
1919
|
+
|
|
1920
|
+
// src/slash-commands/render-codex.ts
|
|
1921
|
+
function renderCodexSkill(skillMdContent) {
|
|
1922
|
+
return `<!-- ${GENERATED_HEADER_CODEX.replace(/<!--\s*|\s*-->/g, "").trim()} -->
|
|
1923
|
+
|
|
1924
|
+
${skillMdContent}
|
|
1925
|
+
`;
|
|
1926
|
+
}
|
|
1927
|
+
function renderCodexOpenaiYaml(spec) {
|
|
1928
|
+
return [
|
|
1929
|
+
"# Reserved for Phase B native integration",
|
|
1930
|
+
`name: ${spec.skillYamlName}`,
|
|
1931
|
+
`version: "1.0.0"`,
|
|
1932
|
+
""
|
|
1933
|
+
].join("\n");
|
|
1934
|
+
}
|
|
1935
|
+
function renderCodexAgentsMd(specs) {
|
|
1936
|
+
const lines = [];
|
|
1937
|
+
lines.push(`<!-- ${GENERATED_HEADER_CODEX.replace(/<!--\s*|\s*-->/g, "").trim()} -->`);
|
|
1938
|
+
lines.push("");
|
|
1939
|
+
lines.push("# Harness Skills");
|
|
1940
|
+
lines.push("");
|
|
1941
|
+
lines.push(
|
|
1942
|
+
"This file bootstraps harness context for Codex CLI. Each skill is available as a structured workflow in the `harness/` directory."
|
|
1943
|
+
);
|
|
1944
|
+
lines.push("");
|
|
1945
|
+
lines.push("## Available Skills");
|
|
1946
|
+
lines.push("");
|
|
1947
|
+
for (const spec of specs) {
|
|
1948
|
+
lines.push(`- **${spec.skillYamlName}** \u2014 ${spec.description}`);
|
|
1949
|
+
}
|
|
1950
|
+
lines.push("");
|
|
1951
|
+
return lines.join("\n");
|
|
1952
|
+
}
|
|
1953
|
+
|
|
1954
|
+
// src/slash-commands/sync-codex.ts
|
|
1955
|
+
import fs12 from "fs";
|
|
1956
|
+
import path14 from "path";
|
|
1957
|
+
function computeCodexSync(outputDir, specs, dryRun) {
|
|
1958
|
+
const added = [];
|
|
1959
|
+
const updated = [];
|
|
1960
|
+
const unchanged = [];
|
|
1961
|
+
const specSkillNames = /* @__PURE__ */ new Set();
|
|
1962
|
+
for (const spec of specs) {
|
|
1963
|
+
const mdPath = path14.join(spec.skillsBaseDir, spec.sourceDir, "SKILL.md");
|
|
1964
|
+
const skillMd = fs12.existsSync(mdPath) ? fs12.readFileSync(mdPath, "utf-8") : "";
|
|
1965
|
+
const skillDir = path14.join(outputDir, spec.skillYamlName);
|
|
1966
|
+
specSkillNames.add(spec.skillYamlName);
|
|
1967
|
+
const renderedSkillMd = renderCodexSkill(skillMd);
|
|
1968
|
+
const renderedOpenaiYaml = renderCodexOpenaiYaml(spec);
|
|
1969
|
+
const existingSkillMdPath = path14.join(skillDir, "SKILL.md");
|
|
1970
|
+
const existingOpenaiYamlPath = path14.join(skillDir, "agents", "openai.yaml");
|
|
1971
|
+
if (!fs12.existsSync(skillDir)) {
|
|
1972
|
+
added.push(spec.skillYamlName);
|
|
1973
|
+
} else {
|
|
1974
|
+
const existingSkillMd = fs12.existsSync(existingSkillMdPath) ? fs12.readFileSync(existingSkillMdPath, "utf-8") : "";
|
|
1975
|
+
const existingOpenaiYaml = fs12.existsSync(existingOpenaiYamlPath) ? fs12.readFileSync(existingOpenaiYamlPath, "utf-8") : "";
|
|
1976
|
+
if (existingSkillMd === renderedSkillMd && existingOpenaiYaml === renderedOpenaiYaml) {
|
|
1977
|
+
unchanged.push(spec.skillYamlName);
|
|
1978
|
+
} else {
|
|
1979
|
+
updated.push(spec.skillYamlName);
|
|
1980
|
+
}
|
|
1981
|
+
}
|
|
1982
|
+
if (!dryRun && !unchanged.includes(spec.skillYamlName)) {
|
|
1983
|
+
const agentsSubDir = path14.join(skillDir, "agents");
|
|
1984
|
+
fs12.mkdirSync(agentsSubDir, { recursive: true });
|
|
1985
|
+
fs12.writeFileSync(existingSkillMdPath, renderedSkillMd, "utf-8");
|
|
1986
|
+
fs12.writeFileSync(existingOpenaiYamlPath, renderedOpenaiYaml, "utf-8");
|
|
1987
|
+
}
|
|
1988
|
+
}
|
|
1989
|
+
const removed = detectCodexOrphans(outputDir, specSkillNames);
|
|
1990
|
+
return { added, updated, removed, unchanged };
|
|
1991
|
+
}
|
|
1992
|
+
function detectCodexOrphans(outputDir, specSkillNames) {
|
|
1993
|
+
const removed = [];
|
|
1994
|
+
if (!fs12.existsSync(outputDir)) return removed;
|
|
1995
|
+
const existingDirs = fs12.readdirSync(outputDir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name);
|
|
1996
|
+
for (const dirName of existingDirs) {
|
|
1997
|
+
if (specSkillNames.has(dirName)) continue;
|
|
1998
|
+
const skillMdPath = path14.join(outputDir, dirName, "SKILL.md");
|
|
1999
|
+
if (fs12.existsSync(skillMdPath)) {
|
|
2000
|
+
const content = fs12.readFileSync(skillMdPath, "utf-8");
|
|
2001
|
+
if (content.includes(GENERATED_HEADER_CODEX)) {
|
|
2002
|
+
removed.push(dirName);
|
|
2003
|
+
}
|
|
2004
|
+
}
|
|
2005
|
+
}
|
|
2006
|
+
return removed;
|
|
2007
|
+
}
|
|
2008
|
+
|
|
1746
2009
|
// src/commands/generate-slash-commands.ts
|
|
1747
2010
|
function resolveOutputDir(platform, opts) {
|
|
1748
2011
|
if (opts.output) {
|
|
1749
|
-
return
|
|
2012
|
+
return path15.join(opts.output, "harness");
|
|
1750
2013
|
}
|
|
1751
2014
|
if (opts.global) {
|
|
1752
2015
|
const home = os.homedir();
|
|
1753
|
-
|
|
2016
|
+
if (platform === "claude-code") return path15.join(home, ".claude", "commands", "harness");
|
|
2017
|
+
if (platform === "gemini-cli") return path15.join(home, ".gemini", "commands", "harness");
|
|
2018
|
+
if (platform === "cursor") return path15.join(home, ".cursor", "rules", "harness");
|
|
2019
|
+
return path15.join(home, ".codex", "harness");
|
|
1754
2020
|
}
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
return
|
|
2021
|
+
if (platform === "claude-code") return path15.join("agents", "commands", "claude-code", "harness");
|
|
2022
|
+
if (platform === "gemini-cli") return path15.join("agents", "commands", "gemini-cli", "harness");
|
|
2023
|
+
if (platform === "cursor") return path15.join("agents", "commands", "cursor", "harness");
|
|
2024
|
+
return path15.join("agents", "commands", "codex", "harness");
|
|
1759
2025
|
}
|
|
1760
2026
|
async function confirmDeletion(files) {
|
|
1761
2027
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
1762
|
-
return new Promise((
|
|
2028
|
+
return new Promise((resolve3) => {
|
|
1763
2029
|
rl.question(`
|
|
1764
2030
|
Remove ${files.length} orphaned command(s)? (y/N) `, (answer) => {
|
|
1765
2031
|
rl.close();
|
|
1766
|
-
|
|
2032
|
+
resolve3(answer.toLowerCase() === "y");
|
|
1767
2033
|
});
|
|
1768
2034
|
});
|
|
1769
2035
|
}
|
|
@@ -1777,12 +2043,12 @@ function resolveSkillSources(opts) {
|
|
|
1777
2043
|
sources.push({ dir: projectDir, source: "project" });
|
|
1778
2044
|
}
|
|
1779
2045
|
const communityDir = resolveCommunitySkillsDir();
|
|
1780
|
-
if (
|
|
2046
|
+
if (fs13.existsSync(communityDir)) {
|
|
1781
2047
|
sources.push({ dir: communityDir, source: "community" });
|
|
1782
2048
|
}
|
|
1783
2049
|
if (opts.includeGlobal || sources.length === 0) {
|
|
1784
2050
|
const globalDir = resolveGlobalSkillsDir();
|
|
1785
|
-
if (!projectDir ||
|
|
2051
|
+
if (!projectDir || path15.resolve(globalDir) !== path15.resolve(projectDir)) {
|
|
1786
2052
|
sources.push({ dir: globalDir, source: "global" });
|
|
1787
2053
|
}
|
|
1788
2054
|
}
|
|
@@ -1794,12 +2060,26 @@ function generateSlashCommands(opts) {
|
|
|
1794
2060
|
const results = [];
|
|
1795
2061
|
for (const platform of opts.platforms) {
|
|
1796
2062
|
const outputDir = resolveOutputDir(platform, opts);
|
|
1797
|
-
const ext = fileExtension(platform);
|
|
1798
2063
|
const useAbsolutePaths = opts.global;
|
|
1799
2064
|
const rendered = /* @__PURE__ */ new Map();
|
|
2065
|
+
if (platform === "codex") {
|
|
2066
|
+
const codexSync = computeCodexSync(outputDir, specs, opts.dryRun);
|
|
2067
|
+
const codexRoot = path15.dirname(outputDir);
|
|
2068
|
+
if (!opts.dryRun) {
|
|
2069
|
+
fs13.mkdirSync(codexRoot, { recursive: true });
|
|
2070
|
+
fs13.writeFileSync(path15.join(codexRoot, "AGENTS.md"), renderCodexAgentsMd(specs), "utf-8");
|
|
2071
|
+
}
|
|
2072
|
+
results.push({ platform, ...codexSync, outputDir });
|
|
2073
|
+
continue;
|
|
2074
|
+
}
|
|
1800
2075
|
for (const spec of specs) {
|
|
1801
|
-
|
|
1802
|
-
|
|
2076
|
+
if (platform === "cursor") {
|
|
2077
|
+
const filename = `${spec.skillYamlName}.mdc`;
|
|
2078
|
+
const mdPath = path15.join(spec.skillsBaseDir, spec.sourceDir, "SKILL.md");
|
|
2079
|
+
const skillMd = fs13.existsSync(mdPath) ? fs13.readFileSync(mdPath, "utf-8") : "";
|
|
2080
|
+
rendered.set(filename, renderCursor(spec, skillMd, spec.cursor));
|
|
2081
|
+
} else if (platform === "claude-code") {
|
|
2082
|
+
const filename = `${spec.name}.md`;
|
|
1803
2083
|
const renderSpec = useAbsolutePaths ? {
|
|
1804
2084
|
...spec,
|
|
1805
2085
|
prompt: {
|
|
@@ -1807,7 +2087,7 @@ function generateSlashCommands(opts) {
|
|
|
1807
2087
|
executionContext: spec.prompt.executionContext.split("\n").map((line) => {
|
|
1808
2088
|
if (line.startsWith("@")) {
|
|
1809
2089
|
const relPath = line.slice(1);
|
|
1810
|
-
return `@${
|
|
2090
|
+
return `@${path15.resolve(relPath)}`;
|
|
1811
2091
|
}
|
|
1812
2092
|
return line;
|
|
1813
2093
|
}).join("\n")
|
|
@@ -1815,10 +2095,11 @@ function generateSlashCommands(opts) {
|
|
|
1815
2095
|
} : spec;
|
|
1816
2096
|
rendered.set(filename, renderClaudeCode(renderSpec));
|
|
1817
2097
|
} else {
|
|
1818
|
-
const
|
|
1819
|
-
const
|
|
1820
|
-
const
|
|
1821
|
-
const
|
|
2098
|
+
const filename = `${spec.name}.toml`;
|
|
2099
|
+
const mdPath = path15.join(spec.skillsBaseDir, spec.sourceDir, "SKILL.md");
|
|
2100
|
+
const yamlPath = path15.join(spec.skillsBaseDir, spec.sourceDir, "skill.yaml");
|
|
2101
|
+
const mdContent = fs13.existsSync(mdPath) ? fs13.readFileSync(mdPath, "utf-8") : "";
|
|
2102
|
+
const yamlContent = fs13.existsSync(yamlPath) ? fs13.readFileSync(yamlPath, "utf-8") : "";
|
|
1822
2103
|
rendered.set(filename, renderGemini(spec, mdContent, yamlContent));
|
|
1823
2104
|
}
|
|
1824
2105
|
}
|
|
@@ -1844,9 +2125,14 @@ async function handleOrphanDeletion(results, opts) {
|
|
|
1844
2125
|
const shouldDelete = opts.yes || await confirmDeletion(result.removed);
|
|
1845
2126
|
if (shouldDelete) {
|
|
1846
2127
|
for (const filename of result.removed) {
|
|
1847
|
-
const filePath =
|
|
1848
|
-
if (
|
|
1849
|
-
|
|
2128
|
+
const filePath = path15.join(result.outputDir, filename);
|
|
2129
|
+
if (fs13.existsSync(filePath)) {
|
|
2130
|
+
const stat = fs13.statSync(filePath);
|
|
2131
|
+
if (stat.isDirectory()) {
|
|
2132
|
+
fs13.rmSync(filePath, { recursive: true, force: true });
|
|
2133
|
+
} else {
|
|
2134
|
+
fs13.unlinkSync(filePath);
|
|
2135
|
+
}
|
|
1850
2136
|
}
|
|
1851
2137
|
}
|
|
1852
2138
|
}
|
|
@@ -1854,7 +2140,7 @@ async function handleOrphanDeletion(results, opts) {
|
|
|
1854
2140
|
}
|
|
1855
2141
|
function createGenerateSlashCommandsCommand() {
|
|
1856
2142
|
return new Command("generate-slash-commands").description(
|
|
1857
|
-
"Generate native
|
|
2143
|
+
"Generate native commands for Claude Code, Gemini CLI, Codex CLI, and Cursor from skill metadata"
|
|
1858
2144
|
).option("--platforms <list>", "Target platforms (comma-separated)", "claude-code,gemini-cli").option("--global", "Write to global config directories", false).option("--include-global", "Include built-in global skills alongside project skills", false).option("--output <dir>", "Custom output directory").option("--skills-dir <path>", "Skills directory to scan").option("--dry-run", "Show what would change without writing", false).option("--yes", "Skip deletion confirmation prompts", false).action(async (opts, cmd) => {
|
|
1859
2145
|
const globalOpts = cmd.optsWithGlobals();
|
|
1860
2146
|
const platforms = opts.platforms.split(",").map((p) => p.trim());
|
|
@@ -1972,7 +2258,7 @@ async function handleGenerateSlashCommands(input) {
|
|
|
1972
2258
|
// src/mcp/resources/state.ts
|
|
1973
2259
|
async function getStateResource(projectRoot) {
|
|
1974
2260
|
try {
|
|
1975
|
-
const { loadState, migrateToStreams } = await import("./dist-
|
|
2261
|
+
const { loadState, migrateToStreams } = await import("./dist-4LPXJYVZ.js");
|
|
1976
2262
|
await migrateToStreams(projectRoot);
|
|
1977
2263
|
const result = await loadState(projectRoot);
|
|
1978
2264
|
if (result.ok) {
|
|
@@ -2519,7 +2805,7 @@ async function handleGetImpact(input) {
|
|
|
2519
2805
|
}
|
|
2520
2806
|
|
|
2521
2807
|
// src/mcp/tools/graph/ingest-source.ts
|
|
2522
|
-
import * as
|
|
2808
|
+
import * as path16 from "path";
|
|
2523
2809
|
var ingestSourceDefinition = {
|
|
2524
2810
|
name: "ingest_source",
|
|
2525
2811
|
description: "Ingest sources into the project knowledge graph. Supports code analysis, knowledge documents, git history, or all at once.",
|
|
@@ -2539,10 +2825,10 @@ var ingestSourceDefinition = {
|
|
|
2539
2825
|
async function handleIngestSource(input) {
|
|
2540
2826
|
try {
|
|
2541
2827
|
const projectPath = sanitizePath(input.path);
|
|
2542
|
-
const graphDir =
|
|
2828
|
+
const graphDir = path16.join(projectPath, ".harness", "graph");
|
|
2543
2829
|
const { GraphStore, CodeIngestor, TopologicalLinker, KnowledgeIngestor, GitIngestor } = await import("./dist-B26DFXMP.js");
|
|
2544
|
-
const
|
|
2545
|
-
await
|
|
2830
|
+
const fs16 = await import("fs/promises");
|
|
2831
|
+
await fs16.mkdir(graphDir, { recursive: true });
|
|
2546
2832
|
const store = new GraphStore();
|
|
2547
2833
|
await store.load(graphDir);
|
|
2548
2834
|
const results = [];
|
|
@@ -2674,8 +2960,8 @@ async function handleAskGraph(input) {
|
|
|
2674
2960
|
}
|
|
2675
2961
|
|
|
2676
2962
|
// src/mcp/resources/graph.ts
|
|
2677
|
-
import * as
|
|
2678
|
-
import * as
|
|
2963
|
+
import * as fs14 from "fs/promises";
|
|
2964
|
+
import * as path17 from "path";
|
|
2679
2965
|
var MAX_ITEMS = 5e3;
|
|
2680
2966
|
function formatStaleness(isoTimestamp) {
|
|
2681
2967
|
const then = new Date(isoTimestamp).getTime();
|
|
@@ -2698,11 +2984,11 @@ async function getGraphResource(projectRoot) {
|
|
|
2698
2984
|
message: "No knowledge graph found. Run harness scan to build one."
|
|
2699
2985
|
});
|
|
2700
2986
|
}
|
|
2701
|
-
const graphDir =
|
|
2702
|
-
const metadataPath =
|
|
2987
|
+
const graphDir = path17.join(projectRoot, ".harness", "graph");
|
|
2988
|
+
const metadataPath = path17.join(graphDir, "metadata.json");
|
|
2703
2989
|
let lastScanTimestamp = null;
|
|
2704
2990
|
try {
|
|
2705
|
-
const raw = JSON.parse(await
|
|
2991
|
+
const raw = JSON.parse(await fs14.readFile(metadataPath, "utf-8"));
|
|
2706
2992
|
lastScanTimestamp = raw.lastScanTimestamp ?? null;
|
|
2707
2993
|
} catch {
|
|
2708
2994
|
}
|
|
@@ -2791,7 +3077,7 @@ var generateAgentDefinitionsDefinition = {
|
|
|
2791
3077
|
}
|
|
2792
3078
|
};
|
|
2793
3079
|
async function handleGenerateAgentDefinitions(input) {
|
|
2794
|
-
const { generateAgentDefinitions } = await import("./generate-agent-definitions-
|
|
3080
|
+
const { generateAgentDefinitions } = await import("./generate-agent-definitions-SAAOAPT4.js");
|
|
2795
3081
|
const platforms = input.platform === "all" || !input.platform ? ["claude-code", "gemini-cli"] : [input.platform];
|
|
2796
3082
|
const results = generateAgentDefinitions({
|
|
2797
3083
|
platforms: [...platforms],
|
|
@@ -2802,8 +3088,8 @@ async function handleGenerateAgentDefinitions(input) {
|
|
|
2802
3088
|
}
|
|
2803
3089
|
|
|
2804
3090
|
// src/mcp/tools/roadmap.ts
|
|
2805
|
-
import * as
|
|
2806
|
-
import * as
|
|
3091
|
+
import * as fs15 from "fs";
|
|
3092
|
+
import * as path18 from "path";
|
|
2807
3093
|
var manageRoadmapDefinition = {
|
|
2808
3094
|
name: "manage_roadmap",
|
|
2809
3095
|
description: "Manage the project roadmap: show, add, update, remove, sync features, or query by filter. Reads and writes docs/roadmap.md.",
|
|
@@ -2858,21 +3144,21 @@ var manageRoadmapDefinition = {
|
|
|
2858
3144
|
}
|
|
2859
3145
|
};
|
|
2860
3146
|
function roadmapPath(projectRoot) {
|
|
2861
|
-
return
|
|
3147
|
+
return path18.join(projectRoot, "docs", "roadmap.md");
|
|
2862
3148
|
}
|
|
2863
3149
|
function readRoadmapFile(projectRoot) {
|
|
2864
3150
|
const filePath = roadmapPath(projectRoot);
|
|
2865
3151
|
try {
|
|
2866
|
-
return
|
|
3152
|
+
return fs15.readFileSync(filePath, "utf-8");
|
|
2867
3153
|
} catch {
|
|
2868
3154
|
return null;
|
|
2869
3155
|
}
|
|
2870
3156
|
}
|
|
2871
3157
|
function writeRoadmapFile(projectRoot, content) {
|
|
2872
3158
|
const filePath = roadmapPath(projectRoot);
|
|
2873
|
-
const dir =
|
|
2874
|
-
|
|
2875
|
-
|
|
3159
|
+
const dir = path18.dirname(filePath);
|
|
3160
|
+
fs15.mkdirSync(dir, { recursive: true });
|
|
3161
|
+
fs15.writeFileSync(filePath, content, "utf-8");
|
|
2876
3162
|
}
|
|
2877
3163
|
function roadmapNotFoundError() {
|
|
2878
3164
|
return {
|
|
@@ -3077,18 +3363,7 @@ function handleSync(projectPath, input, deps) {
|
|
|
3077
3363
|
return resultToMcpResponse(Ok2({ changes: [], message: "Roadmap is up to date." }));
|
|
3078
3364
|
}
|
|
3079
3365
|
if (input.apply) {
|
|
3080
|
-
|
|
3081
|
-
for (const m of roadmap.milestones) {
|
|
3082
|
-
const feature = m.features.find(
|
|
3083
|
-
(f) => f.name.toLowerCase() === change.feature.toLowerCase()
|
|
3084
|
-
);
|
|
3085
|
-
if (feature) {
|
|
3086
|
-
feature.status = change.to;
|
|
3087
|
-
break;
|
|
3088
|
-
}
|
|
3089
|
-
}
|
|
3090
|
-
}
|
|
3091
|
-
roadmap.frontmatter.lastSynced = (/* @__PURE__ */ new Date()).toISOString();
|
|
3366
|
+
deps.applySyncChanges(roadmap, changes);
|
|
3092
3367
|
writeRoadmapFile(projectPath, serializeRoadmap(roadmap));
|
|
3093
3368
|
return resultToMcpResponse(Ok2({ changes, applied: true, roadmap }));
|
|
3094
3369
|
}
|
|
@@ -3096,10 +3371,10 @@ function handleSync(projectPath, input, deps) {
|
|
|
3096
3371
|
}
|
|
3097
3372
|
async function handleManageRoadmap(input) {
|
|
3098
3373
|
try {
|
|
3099
|
-
const { parseRoadmap, serializeRoadmap, syncRoadmap } = await import("./dist-
|
|
3374
|
+
const { parseRoadmap, serializeRoadmap, syncRoadmap, applySyncChanges } = await import("./dist-4LPXJYVZ.js");
|
|
3100
3375
|
const { Ok: Ok2 } = await import("./dist-USY2C5JL.js");
|
|
3101
3376
|
const projectPath = sanitizePath(input.path);
|
|
3102
|
-
const deps = { parseRoadmap, serializeRoadmap, syncRoadmap, Ok: Ok2 };
|
|
3377
|
+
const deps = { parseRoadmap, serializeRoadmap, syncRoadmap, applySyncChanges, Ok: Ok2 };
|
|
3103
3378
|
switch (input.action) {
|
|
3104
3379
|
case "show":
|
|
3105
3380
|
return handleShow2(projectPath, input, deps);
|
|
@@ -3524,7 +3799,7 @@ async function handleTransition(validInput, projectPath, id) {
|
|
|
3524
3799
|
const transition = transitionResult.data;
|
|
3525
3800
|
const prompt = renderTransition(transition);
|
|
3526
3801
|
try {
|
|
3527
|
-
const { saveHandoff } = await import("./dist-
|
|
3802
|
+
const { saveHandoff } = await import("./dist-4LPXJYVZ.js");
|
|
3528
3803
|
await saveHandoff(
|
|
3529
3804
|
projectPath,
|
|
3530
3805
|
{
|
|
@@ -3594,7 +3869,7 @@ async function handleEmitInteraction(input) {
|
|
|
3594
3869
|
}
|
|
3595
3870
|
async function recordInteraction(projectPath, id, type, decision, stream) {
|
|
3596
3871
|
try {
|
|
3597
|
-
const { loadState, saveState } = await import("./dist-
|
|
3872
|
+
const { loadState, saveState } = await import("./dist-4LPXJYVZ.js");
|
|
3598
3873
|
const stateResult = await loadState(projectPath, stream);
|
|
3599
3874
|
if (stateResult.ok) {
|
|
3600
3875
|
const state = stateResult.value;
|
|
@@ -3633,10 +3908,14 @@ var gatherContextDefinition = {
|
|
|
3633
3908
|
type: "array",
|
|
3634
3909
|
items: {
|
|
3635
3910
|
type: "string",
|
|
3636
|
-
enum: ["state", "learnings", "handoff", "graph", "validation", "sessions"]
|
|
3911
|
+
enum: ["state", "learnings", "handoff", "graph", "validation", "sessions", "events"]
|
|
3637
3912
|
},
|
|
3638
3913
|
description: "Which constituents to include (default: all)"
|
|
3639
3914
|
},
|
|
3915
|
+
includeEvents: {
|
|
3916
|
+
type: "boolean",
|
|
3917
|
+
description: "Include recent events timeline. Default: true when session is provided, false otherwise. Can also be controlled via include array."
|
|
3918
|
+
},
|
|
3640
3919
|
mode: {
|
|
3641
3920
|
type: "string",
|
|
3642
3921
|
enum: ["summary", "detailed"],
|
|
@@ -3649,6 +3928,11 @@ var gatherContextDefinition = {
|
|
|
3649
3928
|
session: {
|
|
3650
3929
|
type: "string",
|
|
3651
3930
|
description: "Session slug for session-scoped state. When provided, state/learnings/handoff/failures are read from .harness/sessions/<session>/ instead of .harness/. Omit for global fallback."
|
|
3931
|
+
},
|
|
3932
|
+
depth: {
|
|
3933
|
+
type: "string",
|
|
3934
|
+
enum: ["index", "summary", "full"],
|
|
3935
|
+
description: 'Retrieval depth for learnings. "index" returns one-line summaries, "summary" (default) returns full entries, "full" returns entries with linked context.'
|
|
3652
3936
|
}
|
|
3653
3937
|
},
|
|
3654
3938
|
required: ["path", "intent"]
|
|
@@ -3674,18 +3958,19 @@ async function handleGatherContext(input) {
|
|
|
3674
3958
|
input.include ?? ["state", "learnings", "handoff", "graph", "validation"]
|
|
3675
3959
|
);
|
|
3676
3960
|
const errors = [];
|
|
3677
|
-
const statePromise = includeSet.has("state") ? import("./dist-
|
|
3961
|
+
const statePromise = includeSet.has("state") ? import("./dist-4LPXJYVZ.js").then(
|
|
3678
3962
|
(core) => core.loadState(projectPath, void 0, input.session)
|
|
3679
3963
|
) : Promise.resolve(null);
|
|
3680
|
-
const learningsPromise = includeSet.has("learnings") ? import("./dist-
|
|
3964
|
+
const learningsPromise = includeSet.has("learnings") ? import("./dist-4LPXJYVZ.js").then(
|
|
3681
3965
|
(core) => core.loadBudgetedLearnings(projectPath, {
|
|
3682
3966
|
intent: input.intent,
|
|
3683
3967
|
tokenBudget: input.learningsBudget ?? 1e3,
|
|
3684
3968
|
...input.skill !== void 0 && { skill: input.skill },
|
|
3685
|
-
...input.session !== void 0 && { session: input.session }
|
|
3969
|
+
...input.session !== void 0 && { session: input.session },
|
|
3970
|
+
...input.depth !== void 0 && { depth: input.depth }
|
|
3686
3971
|
})
|
|
3687
3972
|
) : Promise.resolve(null);
|
|
3688
|
-
const handoffPromise = includeSet.has("handoff") ? import("./dist-
|
|
3973
|
+
const handoffPromise = includeSet.has("handoff") ? import("./dist-4LPXJYVZ.js").then(
|
|
3689
3974
|
(core) => core.loadHandoff(projectPath, void 0, input.session)
|
|
3690
3975
|
) : Promise.resolve(null);
|
|
3691
3976
|
const graphPromise = includeSet.has("graph") ? (async () => {
|
|
@@ -3729,11 +4014,19 @@ async function handleGatherContext(input) {
|
|
|
3729
4014
|
context: contextBlocks
|
|
3730
4015
|
};
|
|
3731
4016
|
})() : Promise.resolve(null);
|
|
3732
|
-
const sessionsPromise = includeSet.has("sessions") && input.session ? import("./dist-
|
|
4017
|
+
const sessionsPromise = includeSet.has("sessions") && input.session ? import("./dist-4LPXJYVZ.js").then(
|
|
3733
4018
|
(core) => core.readSessionSections(projectPath, input.session)
|
|
3734
4019
|
) : Promise.resolve(null);
|
|
4020
|
+
const shouldIncludeEvents = input.includeEvents !== void 0 ? input.includeEvents : includeSet.has("events") || !!input.session && !input.include;
|
|
4021
|
+
const eventsPromise = shouldIncludeEvents ? import("./dist-4LPXJYVZ.js").then(async (core) => {
|
|
4022
|
+
const result = await core.loadEvents(projectPath, {
|
|
4023
|
+
session: input.session
|
|
4024
|
+
});
|
|
4025
|
+
if (!result.ok) return null;
|
|
4026
|
+
return core.formatEventTimeline(result.value);
|
|
4027
|
+
}) : Promise.resolve(null);
|
|
3735
4028
|
const validationPromise = includeSet.has("validation") ? (async () => {
|
|
3736
|
-
const { handleValidateProject: handleValidateProject2 } = await import("./validate-
|
|
4029
|
+
const { handleValidateProject: handleValidateProject2 } = await import("./validate-VRTUHALQ.js");
|
|
3737
4030
|
const result = await handleValidateProject2({ path: projectPath });
|
|
3738
4031
|
const first = result.content[0];
|
|
3739
4032
|
return first ? JSON.parse(first.text) : null;
|
|
@@ -3744,14 +4037,16 @@ async function handleGatherContext(input) {
|
|
|
3744
4037
|
handoffResult,
|
|
3745
4038
|
graphResult,
|
|
3746
4039
|
validationResult,
|
|
3747
|
-
sessionsResult
|
|
4040
|
+
sessionsResult,
|
|
4041
|
+
eventsResult
|
|
3748
4042
|
] = await Promise.allSettled([
|
|
3749
4043
|
statePromise,
|
|
3750
4044
|
learningsPromise,
|
|
3751
4045
|
handoffPromise,
|
|
3752
4046
|
graphPromise,
|
|
3753
4047
|
validationPromise,
|
|
3754
|
-
sessionsPromise
|
|
4048
|
+
sessionsPromise,
|
|
4049
|
+
eventsPromise
|
|
3755
4050
|
]);
|
|
3756
4051
|
function extract(settled, name) {
|
|
3757
4052
|
if (settled.status === "rejected") {
|
|
@@ -3766,6 +4061,7 @@ async function handleGatherContext(input) {
|
|
|
3766
4061
|
const graphContextRaw = extract(graphResult, "graph");
|
|
3767
4062
|
const validationRaw = extract(validationResult, "validation");
|
|
3768
4063
|
const sessionsRaw = extract(sessionsResult, "sessions");
|
|
4064
|
+
const eventsTimeline = extract(eventsResult, "events");
|
|
3769
4065
|
const state = stateRaw && typeof stateRaw === "object" && "ok" in stateRaw ? stateRaw.ok ? stateRaw.value : (() => {
|
|
3770
4066
|
errors.push(`state: ${stateRaw.error.message}`);
|
|
3771
4067
|
return null;
|
|
@@ -3813,6 +4109,7 @@ async function handleGatherContext(input) {
|
|
|
3813
4109
|
graphContext: outputGraphContext,
|
|
3814
4110
|
validation: outputValidation,
|
|
3815
4111
|
sessionSections: sessionSections ?? null,
|
|
4112
|
+
events: eventsTimeline || null,
|
|
3816
4113
|
meta: {
|
|
3817
4114
|
assembledIn,
|
|
3818
4115
|
graphAvailable: graphContext !== null,
|
|
@@ -3823,7 +4120,7 @@ async function handleGatherContext(input) {
|
|
|
3823
4120
|
};
|
|
3824
4121
|
if (input.session) {
|
|
3825
4122
|
try {
|
|
3826
|
-
const core = await import("./dist-
|
|
4123
|
+
const core = await import("./dist-4LPXJYVZ.js");
|
|
3827
4124
|
core.updateSessionIndex(
|
|
3828
4125
|
projectPath,
|
|
3829
4126
|
input.session,
|
|
@@ -3893,7 +4190,7 @@ async function handleAssessProject(input) {
|
|
|
3893
4190
|
let validateResult = null;
|
|
3894
4191
|
if (checksToRun.has("validate")) {
|
|
3895
4192
|
try {
|
|
3896
|
-
const { handleValidateProject: handleValidateProject2 } = await import("./validate-
|
|
4193
|
+
const { handleValidateProject: handleValidateProject2 } = await import("./validate-VRTUHALQ.js");
|
|
3897
4194
|
const result = await handleValidateProject2({ path: projectPath });
|
|
3898
4195
|
const first = result.content[0];
|
|
3899
4196
|
const parsed = first ? JSON.parse(first.text) : {};
|
|
@@ -3918,7 +4215,7 @@ async function handleAssessProject(input) {
|
|
|
3918
4215
|
parallelChecks.push(
|
|
3919
4216
|
(async () => {
|
|
3920
4217
|
try {
|
|
3921
|
-
const { handleCheckDependencies: handleCheckDependencies2 } = await import("./architecture-
|
|
4218
|
+
const { handleCheckDependencies: handleCheckDependencies2 } = await import("./architecture-K5HSRBGB.js");
|
|
3922
4219
|
const result = await handleCheckDependencies2({ path: projectPath });
|
|
3923
4220
|
const first = result.content[0];
|
|
3924
4221
|
const parsed = first ? JSON.parse(first.text) : {};
|
|
@@ -3945,7 +4242,7 @@ async function handleAssessProject(input) {
|
|
|
3945
4242
|
parallelChecks.push(
|
|
3946
4243
|
(async () => {
|
|
3947
4244
|
try {
|
|
3948
|
-
const { handleCheckDocs: handleCheckDocs2 } = await import("./docs-
|
|
4245
|
+
const { handleCheckDocs: handleCheckDocs2 } = await import("./docs-4JRHTLUZ.js");
|
|
3949
4246
|
const result = await handleCheckDocs2({ path: projectPath, scope: "coverage" });
|
|
3950
4247
|
const first = result.content[0];
|
|
3951
4248
|
const parsed = first ? JSON.parse(first.text) : {};
|
|
@@ -3972,7 +4269,7 @@ async function handleAssessProject(input) {
|
|
|
3972
4269
|
parallelChecks.push(
|
|
3973
4270
|
(async () => {
|
|
3974
4271
|
try {
|
|
3975
|
-
const { handleDetectEntropy: handleDetectEntropy2 } = await import("./entropy-
|
|
4272
|
+
const { handleDetectEntropy: handleDetectEntropy2 } = await import("./entropy-G6CZ2A6P.js");
|
|
3976
4273
|
const result = await handleDetectEntropy2({ path: projectPath, type: "all" });
|
|
3977
4274
|
const first = result.content[0];
|
|
3978
4275
|
const parsed = first ? JSON.parse(first.text) : {};
|
|
@@ -3999,7 +4296,7 @@ async function handleAssessProject(input) {
|
|
|
3999
4296
|
parallelChecks.push(
|
|
4000
4297
|
(async () => {
|
|
4001
4298
|
try {
|
|
4002
|
-
const { handleRunSecurityScan: handleRunSecurityScan2 } = await import("./security-
|
|
4299
|
+
const { handleRunSecurityScan: handleRunSecurityScan2 } = await import("./security-ZDADTPYW.js");
|
|
4003
4300
|
const result = await handleRunSecurityScan2({ path: projectPath });
|
|
4004
4301
|
const first = result.content[0];
|
|
4005
4302
|
const parsed = first ? JSON.parse(first.text) : {};
|
|
@@ -4031,14 +4328,28 @@ async function handleAssessProject(input) {
|
|
|
4031
4328
|
parallelChecks.push(
|
|
4032
4329
|
(async () => {
|
|
4033
4330
|
try {
|
|
4034
|
-
const { handleCheckPerformance: handleCheckPerformance2 } = await import("./performance-
|
|
4331
|
+
const { handleCheckPerformance: handleCheckPerformance2 } = await import("./performance-UBCFI2UP.js");
|
|
4035
4332
|
const result = await handleCheckPerformance2({ path: projectPath });
|
|
4333
|
+
if ("isError" in result && result.isError) {
|
|
4334
|
+
const msg = result.content[0]?.text ?? "Performance check failed";
|
|
4335
|
+
return { name: "perf", passed: false, issueCount: 1, topIssue: msg };
|
|
4336
|
+
}
|
|
4036
4337
|
const first = result.content[0];
|
|
4037
|
-
|
|
4338
|
+
let parsed = {};
|
|
4339
|
+
try {
|
|
4340
|
+
parsed = first ? JSON.parse(first.text) : {};
|
|
4341
|
+
} catch {
|
|
4342
|
+
return {
|
|
4343
|
+
name: "perf",
|
|
4344
|
+
passed: false,
|
|
4345
|
+
issueCount: 1,
|
|
4346
|
+
topIssue: first?.text ?? "Invalid perf output"
|
|
4347
|
+
};
|
|
4348
|
+
}
|
|
4038
4349
|
const issues = parsed.violations?.length ?? parsed.issues?.length ?? 0;
|
|
4039
4350
|
return {
|
|
4040
4351
|
name: "perf",
|
|
4041
|
-
passed:
|
|
4352
|
+
passed: issues === 0,
|
|
4042
4353
|
issueCount: issues,
|
|
4043
4354
|
...issues > 0 ? { topIssue: "Performance issues detected" } : {},
|
|
4044
4355
|
...mode === "detailed" ? { detailed: parsed } : {}
|
|
@@ -4220,7 +4531,7 @@ async function handleReviewChanges(input) {
|
|
|
4220
4531
|
}
|
|
4221
4532
|
}
|
|
4222
4533
|
async function runQuickReview(projectPath, diff, diffLines, downgraded) {
|
|
4223
|
-
const { handleAnalyzeDiff: handleAnalyzeDiff2 } = await import("./feedback-
|
|
4534
|
+
const { handleAnalyzeDiff: handleAnalyzeDiff2 } = await import("./feedback-QYKQ65HB.js");
|
|
4224
4535
|
const result = await handleAnalyzeDiff2({ diff, path: projectPath });
|
|
4225
4536
|
const firstContent = result.content[0];
|
|
4226
4537
|
if (!firstContent) throw new Error("Empty analyze_diff response");
|
|
@@ -4251,7 +4562,7 @@ function extractFileCount(diffParsed) {
|
|
|
4251
4562
|
return files?.length ?? 0;
|
|
4252
4563
|
}
|
|
4253
4564
|
async function runStandardReview(projectPath, diff, diffLines, downgraded) {
|
|
4254
|
-
const { handleAnalyzeDiff: handleAnalyzeDiff2, handleCreateSelfReview: handleCreateSelfReview2 } = await import("./feedback-
|
|
4565
|
+
const { handleAnalyzeDiff: handleAnalyzeDiff2, handleCreateSelfReview: handleCreateSelfReview2 } = await import("./feedback-QYKQ65HB.js");
|
|
4255
4566
|
const [diffResult, reviewResult] = await Promise.all([
|
|
4256
4567
|
handleAnalyzeDiff2({ diff, path: projectPath }),
|
|
4257
4568
|
handleCreateSelfReview2({ path: projectPath, diff })
|
|
@@ -4283,7 +4594,7 @@ async function runStandardReview(projectPath, diff, diffLines, downgraded) {
|
|
|
4283
4594
|
};
|
|
4284
4595
|
}
|
|
4285
4596
|
async function runDeepReview(projectPath, diff, diffLines, _downgraded) {
|
|
4286
|
-
const { handleRunCodeReview: handleRunCodeReview2 } = await import("./review-pipeline-
|
|
4597
|
+
const { handleRunCodeReview: handleRunCodeReview2 } = await import("./review-pipeline-IQAVCWAX.js");
|
|
4287
4598
|
const result = await handleRunCodeReview2({ path: projectPath, diff });
|
|
4288
4599
|
const deepContent = result.content[0];
|
|
4289
4600
|
if (!deepContent) throw new Error("Empty code review response");
|
|
@@ -4569,7 +4880,7 @@ async function handleDetectStaleConstraints(input) {
|
|
|
4569
4880
|
]
|
|
4570
4881
|
};
|
|
4571
4882
|
}
|
|
4572
|
-
const { detectStaleConstraints } = await import("./dist-
|
|
4883
|
+
const { detectStaleConstraints } = await import("./dist-4LPXJYVZ.js");
|
|
4573
4884
|
const result = detectStaleConstraints(
|
|
4574
4885
|
store,
|
|
4575
4886
|
windowDays,
|
|
@@ -4666,6 +4977,226 @@ async function handleSearchSkills(input) {
|
|
|
4666
4977
|
};
|
|
4667
4978
|
}
|
|
4668
4979
|
|
|
4980
|
+
// src/mcp/tools/code-nav.ts
|
|
4981
|
+
var codeOutlineDefinition = {
|
|
4982
|
+
name: "code_outline",
|
|
4983
|
+
description: "Get a structural skeleton of a file or files matching a glob: exports, classes, functions, types with signatures and line numbers. No implementation bodies. 4-8x token savings vs full file read.",
|
|
4984
|
+
inputSchema: {
|
|
4985
|
+
type: "object",
|
|
4986
|
+
properties: {
|
|
4987
|
+
path: {
|
|
4988
|
+
type: "string",
|
|
4989
|
+
description: "Absolute file path or directory path. When a directory, outlines all supported files within it."
|
|
4990
|
+
},
|
|
4991
|
+
glob: {
|
|
4992
|
+
type: "string",
|
|
4993
|
+
description: 'Optional glob pattern to filter files (e.g. "*.ts", "src/**/*.py"). Only used when path is a directory.'
|
|
4994
|
+
}
|
|
4995
|
+
},
|
|
4996
|
+
required: ["path"]
|
|
4997
|
+
}
|
|
4998
|
+
};
|
|
4999
|
+
async function handleCodeOutline(input) {
|
|
5000
|
+
let targetPath;
|
|
5001
|
+
try {
|
|
5002
|
+
targetPath = sanitizePath(input.path);
|
|
5003
|
+
} catch (error) {
|
|
5004
|
+
return {
|
|
5005
|
+
content: [
|
|
5006
|
+
{
|
|
5007
|
+
type: "text",
|
|
5008
|
+
text: `Error: ${error instanceof Error ? error.message : String(error)}`
|
|
5009
|
+
}
|
|
5010
|
+
],
|
|
5011
|
+
isError: true
|
|
5012
|
+
};
|
|
5013
|
+
}
|
|
5014
|
+
try {
|
|
5015
|
+
const { getOutline, formatOutline, EXTENSION_MAP } = await import("./dist-4LPXJYVZ.js");
|
|
5016
|
+
const { stat } = await import("fs/promises");
|
|
5017
|
+
const stats = await stat(targetPath).catch(() => null);
|
|
5018
|
+
if (stats?.isFile()) {
|
|
5019
|
+
const outline = await getOutline(targetPath);
|
|
5020
|
+
return { content: [{ type: "text", text: formatOutline(outline) }] };
|
|
5021
|
+
}
|
|
5022
|
+
if (stats?.isDirectory()) {
|
|
5023
|
+
const { glob } = await import("glob");
|
|
5024
|
+
const exts = Object.keys(EXTENSION_MAP).map((e) => e.slice(1));
|
|
5025
|
+
const pattern = input.glob ?? `**/*.{${exts.join(",")}}`;
|
|
5026
|
+
const files = await glob(pattern, { cwd: targetPath, absolute: true });
|
|
5027
|
+
const results = [];
|
|
5028
|
+
const MAX_FILES = 50;
|
|
5029
|
+
for (const file of files.slice(0, MAX_FILES)) {
|
|
5030
|
+
const outline = await getOutline(file);
|
|
5031
|
+
results.push(formatOutline(outline));
|
|
5032
|
+
}
|
|
5033
|
+
if (files.length > MAX_FILES) {
|
|
5034
|
+
results.push(
|
|
5035
|
+
`
|
|
5036
|
+
... and ${files.length - MAX_FILES} more files (use a narrower glob to see them)`
|
|
5037
|
+
);
|
|
5038
|
+
}
|
|
5039
|
+
return { content: [{ type: "text", text: results.join("\n\n") }] };
|
|
5040
|
+
}
|
|
5041
|
+
return {
|
|
5042
|
+
content: [{ type: "text", text: `Error: Path not found: ${targetPath}` }],
|
|
5043
|
+
isError: true
|
|
5044
|
+
};
|
|
5045
|
+
} catch (error) {
|
|
5046
|
+
return {
|
|
5047
|
+
content: [
|
|
5048
|
+
{
|
|
5049
|
+
type: "text",
|
|
5050
|
+
text: `Error: ${error instanceof Error ? error.message : String(error)}`
|
|
5051
|
+
}
|
|
5052
|
+
],
|
|
5053
|
+
isError: true
|
|
5054
|
+
};
|
|
5055
|
+
}
|
|
5056
|
+
}
|
|
5057
|
+
var codeSearchDefinition = {
|
|
5058
|
+
name: "code_search",
|
|
5059
|
+
description: "Search for symbols (functions, classes, types, variables) by name or pattern across a directory. Returns matching locations with file, line, kind, and one-line context. 6-12x token savings vs grep + read.",
|
|
5060
|
+
inputSchema: {
|
|
5061
|
+
type: "object",
|
|
5062
|
+
properties: {
|
|
5063
|
+
query: {
|
|
5064
|
+
type: "string",
|
|
5065
|
+
description: "Symbol name or substring to search for (case-insensitive)."
|
|
5066
|
+
},
|
|
5067
|
+
directory: {
|
|
5068
|
+
type: "string",
|
|
5069
|
+
description: "Absolute path to directory to search in."
|
|
5070
|
+
},
|
|
5071
|
+
glob: {
|
|
5072
|
+
type: "string",
|
|
5073
|
+
description: 'Optional glob pattern to filter files (e.g. "*.ts").'
|
|
5074
|
+
}
|
|
5075
|
+
},
|
|
5076
|
+
required: ["query", "directory"]
|
|
5077
|
+
}
|
|
5078
|
+
};
|
|
5079
|
+
async function handleCodeSearch(input) {
|
|
5080
|
+
let directory;
|
|
5081
|
+
try {
|
|
5082
|
+
directory = sanitizePath(input.directory);
|
|
5083
|
+
} catch (error) {
|
|
5084
|
+
return {
|
|
5085
|
+
content: [
|
|
5086
|
+
{
|
|
5087
|
+
type: "text",
|
|
5088
|
+
text: `Error: ${error instanceof Error ? error.message : String(error)}`
|
|
5089
|
+
}
|
|
5090
|
+
],
|
|
5091
|
+
isError: true
|
|
5092
|
+
};
|
|
5093
|
+
}
|
|
5094
|
+
try {
|
|
5095
|
+
const { searchSymbols } = await import("./dist-4LPXJYVZ.js");
|
|
5096
|
+
const result = await searchSymbols(input.query, directory, input.glob);
|
|
5097
|
+
const lines = [`Search: "${result.query}" \u2014 ${result.matches.length} matches`];
|
|
5098
|
+
for (const match of result.matches) {
|
|
5099
|
+
const { symbol } = match;
|
|
5100
|
+
lines.push(
|
|
5101
|
+
` ${symbol.file}:${symbol.line} [${symbol.kind}] ${symbol.name} \u2014 ${match.context}`
|
|
5102
|
+
);
|
|
5103
|
+
}
|
|
5104
|
+
if (result.skipped.length > 0) {
|
|
5105
|
+
lines.push(`
|
|
5106
|
+
Skipped ${result.skipped.length} files (unsupported or parse failed)`);
|
|
5107
|
+
}
|
|
5108
|
+
return { content: [{ type: "text", text: lines.join("\n") }] };
|
|
5109
|
+
} catch (error) {
|
|
5110
|
+
return {
|
|
5111
|
+
content: [
|
|
5112
|
+
{
|
|
5113
|
+
type: "text",
|
|
5114
|
+
text: `Error: ${error instanceof Error ? error.message : String(error)}`
|
|
5115
|
+
}
|
|
5116
|
+
],
|
|
5117
|
+
isError: true
|
|
5118
|
+
};
|
|
5119
|
+
}
|
|
5120
|
+
}
|
|
5121
|
+
var codeUnfoldDefinition = {
|
|
5122
|
+
name: "code_unfold",
|
|
5123
|
+
description: "Extract the complete implementation of a specific symbol (function, class, type) or a line range from a file. Uses AST boundaries for precise extraction. 2-4x token savings vs full file read.",
|
|
5124
|
+
inputSchema: {
|
|
5125
|
+
type: "object",
|
|
5126
|
+
properties: {
|
|
5127
|
+
path: {
|
|
5128
|
+
type: "string",
|
|
5129
|
+
description: "Absolute path to the file."
|
|
5130
|
+
},
|
|
5131
|
+
symbol: {
|
|
5132
|
+
type: "string",
|
|
5133
|
+
description: "Name of the symbol to extract (function, class, type, etc.). Mutually exclusive with startLine/endLine."
|
|
5134
|
+
},
|
|
5135
|
+
startLine: {
|
|
5136
|
+
type: "number",
|
|
5137
|
+
description: "Start line number (1-indexed). Used with endLine for range extraction. Mutually exclusive with symbol."
|
|
5138
|
+
},
|
|
5139
|
+
endLine: {
|
|
5140
|
+
type: "number",
|
|
5141
|
+
description: "End line number (1-indexed, inclusive). Used with startLine for range extraction."
|
|
5142
|
+
}
|
|
5143
|
+
},
|
|
5144
|
+
required: ["path"]
|
|
5145
|
+
}
|
|
5146
|
+
};
|
|
5147
|
+
async function handleCodeUnfold(input) {
|
|
5148
|
+
let filePath;
|
|
5149
|
+
try {
|
|
5150
|
+
filePath = sanitizePath(input.path);
|
|
5151
|
+
} catch (error) {
|
|
5152
|
+
return {
|
|
5153
|
+
content: [
|
|
5154
|
+
{
|
|
5155
|
+
type: "text",
|
|
5156
|
+
text: `Error: ${error instanceof Error ? error.message : String(error)}`
|
|
5157
|
+
}
|
|
5158
|
+
],
|
|
5159
|
+
isError: true
|
|
5160
|
+
};
|
|
5161
|
+
}
|
|
5162
|
+
try {
|
|
5163
|
+
if (input.symbol) {
|
|
5164
|
+
const { unfoldSymbol } = await import("./dist-4LPXJYVZ.js");
|
|
5165
|
+
const result = await unfoldSymbol(filePath, input.symbol);
|
|
5166
|
+
const header = result.warning ? `${result.file}:${result.startLine}-${result.endLine} ${result.warning}
|
|
5167
|
+
` : `${result.file}:${result.startLine}-${result.endLine}
|
|
5168
|
+
`;
|
|
5169
|
+
return { content: [{ type: "text", text: header + result.content }] };
|
|
5170
|
+
}
|
|
5171
|
+
if (input.startLine != null && input.endLine != null) {
|
|
5172
|
+
const { unfoldRange } = await import("./dist-4LPXJYVZ.js");
|
|
5173
|
+
const result = await unfoldRange(filePath, input.startLine, input.endLine);
|
|
5174
|
+
const header = `${result.file}:${result.startLine}-${result.endLine}
|
|
5175
|
+
`;
|
|
5176
|
+
return { content: [{ type: "text", text: header + result.content }] };
|
|
5177
|
+
}
|
|
5178
|
+
return {
|
|
5179
|
+
content: [
|
|
5180
|
+
{
|
|
5181
|
+
type: "text",
|
|
5182
|
+
text: 'Error: Provide either "symbol" or "startLine" + "endLine".'
|
|
5183
|
+
}
|
|
5184
|
+
],
|
|
5185
|
+
isError: true
|
|
5186
|
+
};
|
|
5187
|
+
} catch (error) {
|
|
5188
|
+
return {
|
|
5189
|
+
content: [
|
|
5190
|
+
{
|
|
5191
|
+
type: "text",
|
|
5192
|
+
text: `Error: ${error instanceof Error ? error.message : String(error)}`
|
|
5193
|
+
}
|
|
5194
|
+
],
|
|
5195
|
+
isError: true
|
|
5196
|
+
};
|
|
5197
|
+
}
|
|
5198
|
+
}
|
|
5199
|
+
|
|
4669
5200
|
// src/mcp/server.ts
|
|
4670
5201
|
var TOOL_DEFINITIONS = [
|
|
4671
5202
|
validateToolDefinition,
|
|
@@ -4713,7 +5244,10 @@ var TOOL_DEFINITIONS = [
|
|
|
4713
5244
|
checkTaskIndependenceDefinition,
|
|
4714
5245
|
predictConflictsDefinition,
|
|
4715
5246
|
detectStaleConstraintsDefinition,
|
|
4716
|
-
searchSkillsDefinition
|
|
5247
|
+
searchSkillsDefinition,
|
|
5248
|
+
codeOutlineDefinition,
|
|
5249
|
+
codeSearchDefinition,
|
|
5250
|
+
codeUnfoldDefinition
|
|
4717
5251
|
];
|
|
4718
5252
|
var TOOL_HANDLERS = {
|
|
4719
5253
|
validate_project: handleValidateProject,
|
|
@@ -4761,7 +5295,10 @@ var TOOL_HANDLERS = {
|
|
|
4761
5295
|
check_task_independence: handleCheckTaskIndependence,
|
|
4762
5296
|
predict_conflicts: handlePredictConflicts,
|
|
4763
5297
|
detect_stale_constraints: handleDetectStaleConstraints,
|
|
4764
|
-
search_skills: handleSearchSkills
|
|
5298
|
+
search_skills: handleSearchSkills,
|
|
5299
|
+
code_outline: handleCodeOutline,
|
|
5300
|
+
code_search: handleCodeSearch,
|
|
5301
|
+
code_unfold: handleCodeUnfold
|
|
4765
5302
|
};
|
|
4766
5303
|
var RESOURCE_DEFINITIONS = [
|
|
4767
5304
|
{
|
|
@@ -4847,7 +5384,7 @@ async function appendUpdateNotification(result, resolvedRoot) {
|
|
|
4847
5384
|
shouldRunCheck,
|
|
4848
5385
|
readCheckState,
|
|
4849
5386
|
spawnBackgroundCheck
|
|
4850
|
-
} = await import("./dist-
|
|
5387
|
+
} = await import("./dist-4LPXJYVZ.js");
|
|
4851
5388
|
const { CLI_VERSION } = await import("./version-KFFPOQAX.js");
|
|
4852
5389
|
const configInterval = readConfigInterval(resolvedRoot);
|
|
4853
5390
|
const DEFAULT_INTERVAL = 864e5;
|
|
@@ -4865,19 +5402,24 @@ ${notification}` });
|
|
|
4865
5402
|
} catch {
|
|
4866
5403
|
}
|
|
4867
5404
|
}
|
|
4868
|
-
function createHarnessServer(projectRoot) {
|
|
5405
|
+
function createHarnessServer(projectRoot, toolFilter) {
|
|
4869
5406
|
const resolvedRoot = projectRoot ?? process.cwd();
|
|
4870
5407
|
let sessionChecked = false;
|
|
5408
|
+
const filteredDefinitions = toolFilter ? TOOL_DEFINITIONS.filter((t) => toolFilter.includes(t.name)) : TOOL_DEFINITIONS;
|
|
5409
|
+
const filteredHandlers = toolFilter ? Object.fromEntries(
|
|
5410
|
+
Object.entries(TOOL_HANDLERS).filter(([name]) => toolFilter.includes(name))
|
|
5411
|
+
) : TOOL_HANDLERS;
|
|
4871
5412
|
const server = new Server(
|
|
4872
5413
|
{ name: "harness-engineering", version: "0.1.0" },
|
|
4873
5414
|
{ capabilities: { tools: {}, resources: {} } }
|
|
4874
5415
|
);
|
|
4875
5416
|
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
4876
|
-
tools:
|
|
5417
|
+
tools: filteredDefinitions
|
|
4877
5418
|
}));
|
|
5419
|
+
const guardedHandlers = applyInjectionGuard(filteredHandlers, { projectRoot: resolvedRoot });
|
|
4878
5420
|
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
4879
5421
|
const { name, arguments: args } = request.params;
|
|
4880
|
-
const handler =
|
|
5422
|
+
const handler = guardedHandlers[name];
|
|
4881
5423
|
if (!handler) {
|
|
4882
5424
|
return { content: [{ type: "text", text: `Unknown tool: ${name}` }], isError: true };
|
|
4883
5425
|
}
|
|
@@ -4906,8 +5448,8 @@ function createHarnessServer(projectRoot) {
|
|
|
4906
5448
|
});
|
|
4907
5449
|
return server;
|
|
4908
5450
|
}
|
|
4909
|
-
async function startServer() {
|
|
4910
|
-
const server = createHarnessServer();
|
|
5451
|
+
async function startServer(toolFilter) {
|
|
5452
|
+
const server = createHarnessServer(void 0, toolFilter);
|
|
4911
5453
|
const transport = new StdioServerTransport();
|
|
4912
5454
|
await server.connect(transport);
|
|
4913
5455
|
}
|