hunter-harness 0.1.2 → 0.2.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/LICENSE +21 -21
- package/README.md +11 -0
- package/dist/bin.js +955 -318
- package/package.json +1 -1
- package/resources/harness/bundles/general/claude-code/.harness-build.json +6 -0
- package/resources/harness/{general → bundles/general/claude-code}/agents/harness-reviewer.md +2 -2
- package/resources/harness/{general → bundles/general/claude-code}/harness-archive/SKILL.md +1 -1
- package/resources/harness/{java → bundles/general/claude-code}/harness-codebase-map/SKILL.md +1 -1
- package/resources/harness/{java → bundles/general/claude-code}/harness-knowledge-ingest/SKILL.md +1 -1
- package/resources/harness/{general → bundles/general/claude-code}/harness-knowledge-ingest/reference.md +1 -1
- package/resources/harness/{general → bundles/general/claude-code}/harness-knowledge-query/SKILL.md +1 -1
- package/resources/harness/{general → bundles/general/claude-code}/harness-plan/SKILL.md +1 -1
- package/resources/harness/{java → bundles/general/claude-code}/harness-review/SKILL.md +8 -4
- package/resources/harness/{general → bundles/general/claude-code}/harness-review/checklist.md +3 -3
- package/resources/harness/{general → bundles/general/claude-code}/harness-run/SKILL.md +1 -1
- package/resources/harness/{general → bundles/general/claude-code}/harness-run/checklist.md +1 -1
- package/resources/harness/{general → bundles/general/claude-code}/harness-run/reference.md +2 -2
- package/resources/harness/{general → bundles/general/claude-code}/harness-submit/SKILL.md +1 -1
- package/resources/harness/{java → bundles/general/claude-code}/harness-sync/SKILL.md +2 -2
- package/resources/harness/{general → bundles/general/claude-code}/harness-sync/reference.md +7 -7
- package/resources/harness/{general → bundles/general/claude-code}/harness-test/SKILL.md +1 -1
- package/resources/harness/{general → bundles/general/claude-code}/harness-test/checklist.md +1 -1
- package/resources/harness/{java → bundles/general/claude-code}/scripts/harness_archive.py +2300 -2300
- package/resources/harness/{general → bundles/general/claude-code}/scripts/harness_deploy.py +74 -13
- package/resources/harness/{general → bundles/general/claude-code}/scripts/harness_events.py +680 -680
- package/resources/harness/{general → bundles/general/claude-code}/scripts/harness_ledger.py +660 -660
- package/resources/harness/{java → bundles/general/claude-code}/scripts/harness_preflight.py +765 -765
- package/resources/harness/{general → bundles/general/claude-code}/scripts/harness_service.py +1331 -1331
- package/resources/harness/bundles/general/codebuddy/.harness-build.json +6 -0
- package/resources/harness/bundles/general/codebuddy/agents/harness-evaluator.md +94 -0
- package/resources/harness/bundles/general/codebuddy/agents/harness-explorer.md +53 -0
- package/resources/harness/bundles/general/codebuddy/agents/harness-reviewer.md +52 -0
- package/resources/harness/bundles/general/codebuddy/harness-archive/SKILL.md +198 -0
- package/resources/harness/bundles/general/codebuddy/harness-codebase-map/SKILL.md +95 -0
- package/resources/harness/bundles/general/codebuddy/harness-knowledge-ingest/SKILL.md +229 -0
- package/resources/harness/{java → bundles/general/codebuddy}/harness-knowledge-ingest/reference.md +1 -1
- package/resources/harness/bundles/general/codebuddy/harness-knowledge-query/SKILL.md +147 -0
- package/resources/harness/bundles/general/codebuddy/harness-plan/SKILL.md +109 -0
- package/resources/harness/bundles/general/codebuddy/harness-review/SKILL.md +142 -0
- package/resources/harness/{java → bundles/general/codebuddy}/harness-review/checklist.md +3 -3
- package/resources/harness/bundles/general/codebuddy/harness-run/SKILL.md +113 -0
- package/resources/harness/bundles/general/codebuddy/harness-run/checklist.md +259 -0
- package/resources/harness/bundles/general/codebuddy/harness-run/reference.md +834 -0
- package/resources/harness/bundles/general/codebuddy/harness-submit/SKILL.md +142 -0
- package/resources/harness/bundles/general/codebuddy/harness-sync/SKILL.md +65 -0
- package/resources/harness/{java → bundles/general/codebuddy}/harness-sync/reference.md +7 -7
- package/resources/harness/bundles/general/codebuddy/harness-test/SKILL.md +160 -0
- package/resources/harness/bundles/general/codebuddy/harness-test/checklist.md +319 -0
- package/resources/harness/bundles/general/codebuddy/harness-test/reference.md +791 -0
- package/resources/harness/{general → bundles/general/codebuddy}/scripts/harness_archive.py +2300 -2300
- package/resources/harness/{java → bundles/general/codebuddy}/scripts/harness_deploy.py +74 -13
- package/resources/harness/{java → bundles/general/codebuddy}/scripts/harness_events.py +680 -680
- package/resources/harness/{java → bundles/general/codebuddy}/scripts/harness_ledger.py +660 -660
- package/resources/harness/{general → bundles/general/codebuddy}/scripts/harness_preflight.py +765 -765
- package/resources/harness/{java → bundles/general/codebuddy}/scripts/harness_service.py +1331 -1331
- package/resources/harness/bundles/general/codex/.harness-build.json +6 -0
- package/resources/harness/bundles/general/codex/CONTEXT.md +65 -0
- package/resources/harness/bundles/general/codex/README.md +478 -0
- package/resources/harness/bundles/general/codex/harness-archive/SKILL.md +198 -0
- package/resources/harness/bundles/general/codex/harness-archive/checklist.md +52 -0
- package/resources/harness/bundles/general/codex/harness-archive/reference.md +103 -0
- package/resources/harness/bundles/general/codex/harness-archive/scripts/gen-manifest.ps1 +31 -0
- package/resources/harness/bundles/general/codex/harness-archive/templates/render-summary.mjs +171 -0
- package/resources/harness/bundles/general/codex/harness-archive/templates/summary-data-template.json +128 -0
- package/resources/harness/bundles/general/codex/harness-codebase-map/SKILL.md +95 -0
- package/resources/harness/bundles/general/codex/harness-codebase-map/checklist.md +126 -0
- package/resources/harness/bundles/general/codex/harness-codebase-map/reference.md +364 -0
- package/resources/harness/bundles/general/codex/harness-codebase-map/templates/ARCHITECTURE.md +57 -0
- package/resources/harness/bundles/general/codex/harness-codebase-map/templates/CONCERNS.md +49 -0
- package/resources/harness/bundles/general/codex/harness-codebase-map/templates/CONVENTIONS.md +57 -0
- package/resources/harness/bundles/general/codex/harness-codebase-map/templates/INTEGRATIONS.md +52 -0
- package/resources/harness/bundles/general/codex/harness-codebase-map/templates/STACK.md +55 -0
- package/resources/harness/bundles/general/codex/harness-codebase-map/templates/STRUCTURE.md +69 -0
- package/resources/harness/bundles/general/codex/harness-codebase-map/templates/TESTING.md +64 -0
- package/resources/harness/bundles/general/codex/harness-codebase-map/templates/map-manifest.schema.json +73 -0
- package/resources/harness/bundles/general/codex/harness-codebase-map/templates/map-summary.md +64 -0
- package/resources/harness/bundles/general/codex/harness-knowledge-ingest/SKILL.md +229 -0
- package/resources/harness/bundles/general/codex/harness-knowledge-ingest/design.md +842 -0
- package/resources/harness/bundles/general/codex/harness-knowledge-ingest/evaluations/harness_knowledge_evaluation.xml +42 -0
- package/resources/harness/bundles/general/codex/harness-knowledge-ingest/mcp-config.example.json +10 -0
- package/resources/harness/bundles/general/codex/harness-knowledge-ingest/reference.md +309 -0
- package/resources/harness/bundles/general/codex/harness-knowledge-ingest/scripts/harness_knowledge.py +4082 -0
- package/resources/harness/bundles/general/codex/harness-knowledge-ingest/scripts/harness_knowledge_mcp.py +273 -0
- package/resources/harness/bundles/general/codex/harness-knowledge-query/SKILL.md +147 -0
- package/resources/harness/bundles/general/codex/harness-plan/SKILL.md +109 -0
- package/resources/harness/bundles/general/codex/harness-plan/checklist.md +243 -0
- package/resources/harness/bundles/general/codex/harness-plan/protocols.md +124 -0
- package/resources/harness/bundles/general/codex/harness-plan/reference.md +376 -0
- package/resources/harness/bundles/general/codex/harness-review/SKILL.md +137 -0
- package/resources/harness/bundles/general/codex/harness-review/checklist.md +124 -0
- package/resources/harness/bundles/general/codex/harness-review/protocols.md +68 -0
- package/resources/harness/bundles/general/codex/harness-review/reference.md +86 -0
- package/resources/harness/bundles/general/codex/harness-run/SKILL.md +113 -0
- package/resources/harness/bundles/general/codex/harness-run/checklist.md +259 -0
- package/resources/harness/bundles/general/codex/harness-run/protocols.md +78 -0
- package/resources/harness/bundles/general/codex/harness-run/reference.md +834 -0
- package/resources/harness/bundles/general/codex/harness-submit/SKILL.md +142 -0
- package/resources/harness/bundles/general/codex/harness-submit/checklist.md +407 -0
- package/resources/harness/bundles/general/codex/harness-submit/reference.md +152 -0
- package/resources/harness/bundles/general/codex/harness-sync/SKILL.md +65 -0
- package/resources/harness/bundles/general/codex/harness-sync/reference.md +153 -0
- package/resources/harness/bundles/general/codex/harness-test/SKILL.md +160 -0
- package/resources/harness/bundles/general/codex/harness-test/checklist.md +319 -0
- package/resources/harness/bundles/general/codex/harness-test/pitfalls.md +260 -0
- package/resources/harness/bundles/general/codex/harness-test/reference.md +791 -0
- package/resources/harness/bundles/general/codex/protocols/archive-report-protocol.md +175 -0
- package/resources/harness/bundles/general/codex/protocols/evidence-based-reporting-protocol.md +134 -0
- package/resources/harness/bundles/general/codex/protocols/ledger-protocol.md +270 -0
- package/resources/harness/bundles/general/codex/protocols/powershell-protocol.md +181 -0
- package/resources/harness/bundles/general/codex/protocols/report-pipeline-protocol.md +150 -0
- package/resources/harness/bundles/general/codex/protocols/sensitive-info-protocol.md +92 -0
- package/resources/harness/bundles/general/codex/protocols/state-layout-protocol.md +131 -0
- package/resources/harness/bundles/general/codex/protocols/submit-protocol.md +78 -0
- package/resources/harness/bundles/general/codex/scripts/harness_archive.py +2319 -0
- package/resources/harness/bundles/general/codex/scripts/harness_deploy.py +674 -0
- package/resources/harness/bundles/general/codex/scripts/harness_events.py +680 -0
- package/resources/harness/bundles/general/codex/scripts/harness_ledger.py +671 -0
- package/resources/harness/bundles/general/codex/scripts/harness_preflight.py +780 -0
- package/resources/harness/bundles/general/codex/scripts/harness_service.py +1331 -0
- package/resources/harness/bundles/general/cursor/.harness-build.json +6 -0
- package/resources/harness/bundles/general/cursor/CONTEXT.md +65 -0
- package/resources/harness/bundles/general/cursor/README.md +478 -0
- package/resources/harness/bundles/general/cursor/harness-archive/SKILL.md +198 -0
- package/resources/harness/bundles/general/cursor/harness-archive/checklist.md +52 -0
- package/resources/harness/bundles/general/cursor/harness-archive/reference.md +103 -0
- package/resources/harness/bundles/general/cursor/harness-archive/scripts/gen-manifest.ps1 +31 -0
- package/resources/harness/bundles/general/cursor/harness-archive/templates/render-summary.mjs +171 -0
- package/resources/harness/bundles/general/cursor/harness-archive/templates/summary-data-template.json +128 -0
- package/resources/harness/bundles/general/cursor/harness-codebase-map/SKILL.md +95 -0
- package/resources/harness/bundles/general/cursor/harness-codebase-map/checklist.md +126 -0
- package/resources/harness/bundles/general/cursor/harness-codebase-map/reference.md +364 -0
- package/resources/harness/bundles/general/cursor/harness-codebase-map/templates/ARCHITECTURE.md +57 -0
- package/resources/harness/bundles/general/cursor/harness-codebase-map/templates/CONCERNS.md +49 -0
- package/resources/harness/bundles/general/cursor/harness-codebase-map/templates/CONVENTIONS.md +57 -0
- package/resources/harness/bundles/general/cursor/harness-codebase-map/templates/INTEGRATIONS.md +52 -0
- package/resources/harness/bundles/general/cursor/harness-codebase-map/templates/STACK.md +55 -0
- package/resources/harness/bundles/general/cursor/harness-codebase-map/templates/STRUCTURE.md +69 -0
- package/resources/harness/bundles/general/cursor/harness-codebase-map/templates/TESTING.md +64 -0
- package/resources/harness/bundles/general/cursor/harness-codebase-map/templates/map-manifest.schema.json +73 -0
- package/resources/harness/bundles/general/cursor/harness-codebase-map/templates/map-summary.md +64 -0
- package/resources/harness/bundles/general/cursor/harness-knowledge-ingest/SKILL.md +229 -0
- package/resources/harness/bundles/general/cursor/harness-knowledge-ingest/design.md +842 -0
- package/resources/harness/bundles/general/cursor/harness-knowledge-ingest/evaluations/harness_knowledge_evaluation.xml +42 -0
- package/resources/harness/bundles/general/cursor/harness-knowledge-ingest/mcp-config.example.json +10 -0
- package/resources/harness/bundles/general/cursor/harness-knowledge-ingest/reference.md +309 -0
- package/resources/harness/bundles/general/cursor/harness-knowledge-ingest/scripts/harness_knowledge.py +4082 -0
- package/resources/harness/bundles/general/cursor/harness-knowledge-ingest/scripts/harness_knowledge_mcp.py +273 -0
- package/resources/harness/bundles/general/cursor/harness-knowledge-query/SKILL.md +147 -0
- package/resources/harness/bundles/general/cursor/harness-plan/SKILL.md +109 -0
- package/resources/harness/bundles/general/cursor/harness-plan/checklist.md +243 -0
- package/resources/harness/bundles/general/cursor/harness-plan/protocols.md +124 -0
- package/resources/harness/bundles/general/cursor/harness-plan/reference.md +376 -0
- package/resources/harness/bundles/general/cursor/harness-review/SKILL.md +137 -0
- package/resources/harness/bundles/general/cursor/harness-review/checklist.md +124 -0
- package/resources/harness/bundles/general/cursor/harness-review/protocols.md +68 -0
- package/resources/harness/bundles/general/cursor/harness-review/reference.md +86 -0
- package/resources/harness/bundles/general/cursor/harness-run/SKILL.md +113 -0
- package/resources/harness/bundles/general/cursor/harness-run/checklist.md +259 -0
- package/resources/harness/bundles/general/cursor/harness-run/protocols.md +78 -0
- package/resources/harness/bundles/general/cursor/harness-run/reference.md +834 -0
- package/resources/harness/bundles/general/cursor/harness-submit/SKILL.md +142 -0
- package/resources/harness/bundles/general/cursor/harness-submit/checklist.md +407 -0
- package/resources/harness/bundles/general/cursor/harness-submit/reference.md +152 -0
- package/resources/harness/bundles/general/cursor/harness-sync/SKILL.md +65 -0
- package/resources/harness/bundles/general/cursor/harness-sync/reference.md +153 -0
- package/resources/harness/bundles/general/cursor/harness-test/SKILL.md +160 -0
- package/resources/harness/bundles/general/cursor/harness-test/checklist.md +319 -0
- package/resources/harness/bundles/general/cursor/harness-test/pitfalls.md +260 -0
- package/resources/harness/bundles/general/cursor/harness-test/reference.md +791 -0
- package/resources/harness/bundles/general/cursor/protocols/archive-report-protocol.md +175 -0
- package/resources/harness/bundles/general/cursor/protocols/evidence-based-reporting-protocol.md +134 -0
- package/resources/harness/bundles/general/cursor/protocols/ledger-protocol.md +270 -0
- package/resources/harness/bundles/general/cursor/protocols/powershell-protocol.md +181 -0
- package/resources/harness/bundles/general/cursor/protocols/report-pipeline-protocol.md +150 -0
- package/resources/harness/bundles/general/cursor/protocols/sensitive-info-protocol.md +92 -0
- package/resources/harness/bundles/general/cursor/protocols/state-layout-protocol.md +131 -0
- package/resources/harness/bundles/general/cursor/protocols/submit-protocol.md +78 -0
- package/resources/harness/bundles/general/cursor/scripts/harness_archive.py +2319 -0
- package/resources/harness/bundles/general/cursor/scripts/harness_deploy.py +674 -0
- package/resources/harness/bundles/general/cursor/scripts/harness_events.py +680 -0
- package/resources/harness/bundles/general/cursor/scripts/harness_ledger.py +671 -0
- package/resources/harness/bundles/general/cursor/scripts/harness_preflight.py +780 -0
- package/resources/harness/bundles/general/cursor/scripts/harness_service.py +1331 -0
- package/resources/harness/bundles/java/claude-code/.harness-build.json +6 -0
- package/resources/harness/bundles/java/claude-code/CONTEXT.md +65 -0
- package/resources/harness/bundles/java/claude-code/README.md +478 -0
- package/resources/harness/{java → bundles/java/claude-code}/agents/harness-reviewer.md +2 -2
- package/resources/harness/{java → bundles/java/claude-code}/harness-apidoc/SKILL.md +1 -1
- package/resources/harness/{java → bundles/java/claude-code}/harness-archive/SKILL.md +1 -1
- package/resources/harness/bundles/java/claude-code/harness-archive/checklist.md +52 -0
- package/resources/harness/bundles/java/claude-code/harness-archive/reference.md +103 -0
- package/resources/harness/bundles/java/claude-code/harness-archive/scripts/gen-manifest.ps1 +31 -0
- package/resources/harness/bundles/java/claude-code/harness-archive/templates/render-summary.mjs +171 -0
- package/resources/harness/bundles/java/claude-code/harness-archive/templates/summary-data-template.json +128 -0
- package/resources/harness/{general → bundles/java/claude-code}/harness-codebase-map/SKILL.md +1 -1
- package/resources/harness/bundles/java/claude-code/harness-codebase-map/checklist.md +126 -0
- package/resources/harness/bundles/java/claude-code/harness-codebase-map/reference.md +364 -0
- package/resources/harness/bundles/java/claude-code/harness-codebase-map/templates/ARCHITECTURE.md +57 -0
- package/resources/harness/bundles/java/claude-code/harness-codebase-map/templates/CONCERNS.md +49 -0
- package/resources/harness/bundles/java/claude-code/harness-codebase-map/templates/CONVENTIONS.md +57 -0
- package/resources/harness/bundles/java/claude-code/harness-codebase-map/templates/INTEGRATIONS.md +52 -0
- package/resources/harness/bundles/java/claude-code/harness-codebase-map/templates/STACK.md +55 -0
- package/resources/harness/bundles/java/claude-code/harness-codebase-map/templates/STRUCTURE.md +69 -0
- package/resources/harness/bundles/java/claude-code/harness-codebase-map/templates/TESTING.md +64 -0
- package/resources/harness/bundles/java/claude-code/harness-codebase-map/templates/map-manifest.schema.json +73 -0
- package/resources/harness/bundles/java/claude-code/harness-codebase-map/templates/map-summary.md +64 -0
- package/resources/harness/{general → bundles/java/claude-code}/harness-knowledge-ingest/SKILL.md +1 -1
- package/resources/harness/bundles/java/claude-code/harness-knowledge-ingest/design.md +842 -0
- package/resources/harness/bundles/java/claude-code/harness-knowledge-ingest/evaluations/harness_knowledge_evaluation.xml +42 -0
- package/resources/harness/bundles/java/claude-code/harness-knowledge-ingest/mcp-config.example.json +10 -0
- package/resources/harness/bundles/java/claude-code/harness-knowledge-ingest/reference.md +309 -0
- package/resources/harness/bundles/java/claude-code/harness-knowledge-ingest/scripts/harness_knowledge.py +4082 -0
- package/resources/harness/bundles/java/claude-code/harness-knowledge-ingest/scripts/harness_knowledge_mcp.py +273 -0
- package/resources/harness/{java → bundles/java/claude-code}/harness-knowledge-query/SKILL.md +1 -1
- package/resources/harness/{java → bundles/java/claude-code}/harness-package/SKILL.md +1 -1
- package/resources/harness/{java → bundles/java/claude-code}/harness-package/reference.md +1 -1
- package/resources/harness/{java → bundles/java/claude-code}/harness-plan/SKILL.md +1 -1
- package/resources/harness/bundles/java/claude-code/harness-plan/checklist.md +243 -0
- package/resources/harness/bundles/java/claude-code/harness-plan/protocols.md +124 -0
- package/resources/harness/bundles/java/claude-code/harness-plan/reference.md +376 -0
- package/resources/harness/{general → bundles/java/claude-code}/harness-review/SKILL.md +8 -4
- package/resources/harness/bundles/java/claude-code/harness-review/checklist.md +124 -0
- package/resources/harness/bundles/java/claude-code/harness-review/protocols.md +68 -0
- package/resources/harness/bundles/java/claude-code/harness-review/reference.md +86 -0
- package/resources/harness/{java → bundles/java/claude-code}/harness-run/SKILL.md +1 -1
- package/resources/harness/{java → bundles/java/claude-code}/harness-run/checklist.md +1 -1
- package/resources/harness/bundles/java/claude-code/harness-run/protocols.md +78 -0
- package/resources/harness/{java → bundles/java/claude-code}/harness-run/reference.md +2 -2
- package/resources/harness/{java → bundles/java/claude-code}/harness-submit/SKILL.md +1 -1
- package/resources/harness/bundles/java/claude-code/harness-submit/checklist.md +407 -0
- package/resources/harness/bundles/java/claude-code/harness-submit/reference.md +152 -0
- package/resources/harness/{general → bundles/java/claude-code}/harness-sync/SKILL.md +2 -2
- package/resources/harness/bundles/java/claude-code/harness-sync/reference.md +153 -0
- package/resources/harness/{java → bundles/java/claude-code}/harness-test/SKILL.md +1 -1
- package/resources/harness/{java → bundles/java/claude-code}/harness-test/checklist.md +316 -316
- package/resources/harness/bundles/java/claude-code/harness-test/pitfalls.md +260 -0
- package/resources/harness/{java → bundles/java/claude-code}/harness-test/reference.md +788 -788
- package/resources/harness/bundles/java/claude-code/protocols/archive-report-protocol.md +175 -0
- package/resources/harness/bundles/java/claude-code/protocols/evidence-based-reporting-protocol.md +134 -0
- package/resources/harness/bundles/java/claude-code/protocols/ledger-protocol.md +270 -0
- package/resources/harness/bundles/java/claude-code/protocols/powershell-protocol.md +181 -0
- package/resources/harness/bundles/java/claude-code/protocols/report-pipeline-protocol.md +150 -0
- package/resources/harness/bundles/java/claude-code/protocols/sensitive-info-protocol.md +92 -0
- package/resources/harness/bundles/java/claude-code/protocols/state-layout-protocol.md +131 -0
- package/resources/harness/bundles/java/claude-code/protocols/submit-protocol.md +78 -0
- package/resources/harness/bundles/java/claude-code/scripts/harness_archive.py +2319 -0
- package/resources/harness/bundles/java/claude-code/scripts/harness_deploy.py +674 -0
- package/resources/harness/bundles/java/claude-code/scripts/harness_events.py +680 -0
- package/resources/harness/bundles/java/claude-code/scripts/harness_ledger.py +671 -0
- package/resources/harness/bundles/java/claude-code/scripts/harness_preflight.py +780 -0
- package/resources/harness/bundles/java/claude-code/scripts/harness_service.py +1331 -0
- package/resources/harness/bundles/java/codebuddy/.harness-build.json +6 -0
- package/resources/harness/bundles/java/codebuddy/CONTEXT.md +65 -0
- package/resources/harness/bundles/java/codebuddy/README.md +478 -0
- package/resources/harness/bundles/java/codebuddy/agents/harness-evaluator.md +94 -0
- package/resources/harness/bundles/java/codebuddy/agents/harness-explorer.md +53 -0
- package/resources/harness/bundles/java/codebuddy/agents/harness-reviewer.md +52 -0
- package/resources/harness/bundles/java/codebuddy/harness-apidoc/SKILL.md +68 -0
- package/resources/harness/bundles/java/codebuddy/harness-apidoc/checklist.md +142 -0
- package/resources/harness/bundles/java/codebuddy/harness-apidoc/reference.md +233 -0
- package/resources/harness/bundles/java/codebuddy/harness-archive/SKILL.md +198 -0
- package/resources/harness/bundles/java/codebuddy/harness-archive/checklist.md +52 -0
- package/resources/harness/bundles/java/codebuddy/harness-archive/reference.md +103 -0
- package/resources/harness/bundles/java/codebuddy/harness-archive/scripts/gen-manifest.ps1 +31 -0
- package/resources/harness/bundles/java/codebuddy/harness-archive/templates/render-summary.mjs +171 -0
- package/resources/harness/bundles/java/codebuddy/harness-archive/templates/summary-data-template.json +128 -0
- package/resources/harness/bundles/java/codebuddy/harness-codebase-map/SKILL.md +95 -0
- package/resources/harness/bundles/java/codebuddy/harness-codebase-map/checklist.md +126 -0
- package/resources/harness/bundles/java/codebuddy/harness-codebase-map/reference.md +364 -0
- package/resources/harness/bundles/java/codebuddy/harness-codebase-map/templates/ARCHITECTURE.md +57 -0
- package/resources/harness/bundles/java/codebuddy/harness-codebase-map/templates/CONCERNS.md +49 -0
- package/resources/harness/bundles/java/codebuddy/harness-codebase-map/templates/CONVENTIONS.md +57 -0
- package/resources/harness/bundles/java/codebuddy/harness-codebase-map/templates/INTEGRATIONS.md +52 -0
- package/resources/harness/bundles/java/codebuddy/harness-codebase-map/templates/STACK.md +55 -0
- package/resources/harness/bundles/java/codebuddy/harness-codebase-map/templates/STRUCTURE.md +69 -0
- package/resources/harness/bundles/java/codebuddy/harness-codebase-map/templates/TESTING.md +64 -0
- package/resources/harness/bundles/java/codebuddy/harness-codebase-map/templates/map-manifest.schema.json +73 -0
- package/resources/harness/bundles/java/codebuddy/harness-codebase-map/templates/map-summary.md +64 -0
- package/resources/harness/bundles/java/codebuddy/harness-knowledge-ingest/SKILL.md +229 -0
- package/resources/harness/bundles/java/codebuddy/harness-knowledge-ingest/design.md +842 -0
- package/resources/harness/bundles/java/codebuddy/harness-knowledge-ingest/evaluations/harness_knowledge_evaluation.xml +42 -0
- package/resources/harness/bundles/java/codebuddy/harness-knowledge-ingest/mcp-config.example.json +10 -0
- package/resources/harness/bundles/java/codebuddy/harness-knowledge-ingest/reference.md +309 -0
- package/resources/harness/bundles/java/codebuddy/harness-knowledge-ingest/scripts/harness_knowledge.py +4082 -0
- package/resources/harness/bundles/java/codebuddy/harness-knowledge-ingest/scripts/harness_knowledge_mcp.py +273 -0
- package/resources/harness/bundles/java/codebuddy/harness-knowledge-query/SKILL.md +147 -0
- package/resources/harness/bundles/java/codebuddy/harness-package/SKILL.md +69 -0
- package/resources/harness/bundles/java/codebuddy/harness-package/checklist.md +322 -0
- package/resources/harness/bundles/java/codebuddy/harness-package/reference.md +210 -0
- package/resources/harness/bundles/java/codebuddy/harness-plan/SKILL.md +109 -0
- package/resources/harness/bundles/java/codebuddy/harness-plan/checklist.md +243 -0
- package/resources/harness/bundles/java/codebuddy/harness-plan/protocols.md +124 -0
- package/resources/harness/bundles/java/codebuddy/harness-plan/reference.md +376 -0
- package/resources/harness/bundles/java/codebuddy/harness-review/SKILL.md +142 -0
- package/resources/harness/bundles/java/codebuddy/harness-review/checklist.md +124 -0
- package/resources/harness/bundles/java/codebuddy/harness-review/protocols.md +68 -0
- package/resources/harness/bundles/java/codebuddy/harness-review/reference.md +86 -0
- package/resources/harness/bundles/java/codebuddy/harness-run/SKILL.md +129 -0
- package/resources/harness/bundles/java/codebuddy/harness-run/checklist.md +250 -0
- package/resources/harness/bundles/java/codebuddy/harness-run/protocols.md +78 -0
- package/resources/harness/bundles/java/codebuddy/harness-run/reference.md +814 -0
- package/resources/harness/bundles/java/codebuddy/harness-submit/SKILL.md +149 -0
- package/resources/harness/bundles/java/codebuddy/harness-submit/checklist.md +407 -0
- package/resources/harness/bundles/java/codebuddy/harness-submit/reference.md +152 -0
- package/resources/harness/bundles/java/codebuddy/harness-sync/SKILL.md +65 -0
- package/resources/harness/bundles/java/codebuddy/harness-sync/reference.md +153 -0
- package/resources/harness/bundles/java/codebuddy/harness-test/SKILL.md +172 -0
- package/resources/harness/bundles/java/codebuddy/harness-test/checklist.md +317 -0
- package/resources/harness/bundles/java/codebuddy/harness-test/pitfalls-java.md +16 -0
- package/resources/harness/bundles/java/codebuddy/harness-test/pitfalls.md +260 -0
- package/resources/harness/bundles/java/codebuddy/harness-test/reference.md +788 -0
- package/resources/harness/bundles/java/codebuddy/protocols/archive-report-protocol.md +175 -0
- package/resources/harness/bundles/java/codebuddy/protocols/evidence-based-reporting-protocol.md +134 -0
- package/resources/harness/bundles/java/codebuddy/protocols/ledger-protocol.md +270 -0
- package/resources/harness/bundles/java/codebuddy/protocols/powershell-protocol.md +181 -0
- package/resources/harness/bundles/java/codebuddy/protocols/report-pipeline-protocol.md +150 -0
- package/resources/harness/bundles/java/codebuddy/protocols/sensitive-info-protocol.md +92 -0
- package/resources/harness/bundles/java/codebuddy/protocols/state-layout-protocol.md +131 -0
- package/resources/harness/bundles/java/codebuddy/protocols/submit-protocol.md +78 -0
- package/resources/harness/bundles/java/codebuddy/scripts/harness_archive.py +2319 -0
- package/resources/harness/bundles/java/codebuddy/scripts/harness_deploy.py +674 -0
- package/resources/harness/bundles/java/codebuddy/scripts/harness_events.py +680 -0
- package/resources/harness/bundles/java/codebuddy/scripts/harness_ledger.py +671 -0
- package/resources/harness/bundles/java/codebuddy/scripts/harness_preflight.py +780 -0
- package/resources/harness/bundles/java/codebuddy/scripts/harness_service.py +1331 -0
- package/resources/harness/bundles/java/codex/.harness-build.json +6 -0
- package/resources/harness/bundles/java/codex/CONTEXT.md +65 -0
- package/resources/harness/bundles/java/codex/README.md +478 -0
- package/resources/harness/bundles/java/codex/harness-apidoc/SKILL.md +68 -0
- package/resources/harness/bundles/java/codex/harness-apidoc/checklist.md +142 -0
- package/resources/harness/bundles/java/codex/harness-apidoc/reference.md +233 -0
- package/resources/harness/bundles/java/codex/harness-archive/SKILL.md +198 -0
- package/resources/harness/bundles/java/codex/harness-archive/checklist.md +52 -0
- package/resources/harness/bundles/java/codex/harness-archive/reference.md +103 -0
- package/resources/harness/bundles/java/codex/harness-archive/scripts/gen-manifest.ps1 +31 -0
- package/resources/harness/bundles/java/codex/harness-archive/templates/render-summary.mjs +171 -0
- package/resources/harness/bundles/java/codex/harness-archive/templates/summary-data-template.json +128 -0
- package/resources/harness/bundles/java/codex/harness-codebase-map/SKILL.md +95 -0
- package/resources/harness/bundles/java/codex/harness-codebase-map/checklist.md +126 -0
- package/resources/harness/bundles/java/codex/harness-codebase-map/reference.md +364 -0
- package/resources/harness/bundles/java/codex/harness-codebase-map/templates/ARCHITECTURE.md +57 -0
- package/resources/harness/bundles/java/codex/harness-codebase-map/templates/CONCERNS.md +49 -0
- package/resources/harness/bundles/java/codex/harness-codebase-map/templates/CONVENTIONS.md +57 -0
- package/resources/harness/bundles/java/codex/harness-codebase-map/templates/INTEGRATIONS.md +52 -0
- package/resources/harness/bundles/java/codex/harness-codebase-map/templates/STACK.md +55 -0
- package/resources/harness/bundles/java/codex/harness-codebase-map/templates/STRUCTURE.md +69 -0
- package/resources/harness/bundles/java/codex/harness-codebase-map/templates/TESTING.md +64 -0
- package/resources/harness/bundles/java/codex/harness-codebase-map/templates/map-manifest.schema.json +73 -0
- package/resources/harness/bundles/java/codex/harness-codebase-map/templates/map-summary.md +64 -0
- package/resources/harness/bundles/java/codex/harness-knowledge-ingest/SKILL.md +229 -0
- package/resources/harness/bundles/java/codex/harness-knowledge-ingest/design.md +842 -0
- package/resources/harness/bundles/java/codex/harness-knowledge-ingest/evaluations/harness_knowledge_evaluation.xml +42 -0
- package/resources/harness/bundles/java/codex/harness-knowledge-ingest/mcp-config.example.json +10 -0
- package/resources/harness/bundles/java/codex/harness-knowledge-ingest/reference.md +309 -0
- package/resources/harness/bundles/java/codex/harness-knowledge-ingest/scripts/harness_knowledge.py +4082 -0
- package/resources/harness/bundles/java/codex/harness-knowledge-ingest/scripts/harness_knowledge_mcp.py +273 -0
- package/resources/harness/bundles/java/codex/harness-knowledge-query/SKILL.md +147 -0
- package/resources/harness/bundles/java/codex/harness-package/SKILL.md +69 -0
- package/resources/harness/bundles/java/codex/harness-package/checklist.md +322 -0
- package/resources/harness/bundles/java/codex/harness-package/reference.md +210 -0
- package/resources/harness/bundles/java/codex/harness-plan/SKILL.md +109 -0
- package/resources/harness/bundles/java/codex/harness-plan/checklist.md +243 -0
- package/resources/harness/bundles/java/codex/harness-plan/protocols.md +124 -0
- package/resources/harness/bundles/java/codex/harness-plan/reference.md +376 -0
- package/resources/harness/bundles/java/codex/harness-review/SKILL.md +137 -0
- package/resources/harness/bundles/java/codex/harness-review/checklist.md +124 -0
- package/resources/harness/bundles/java/codex/harness-review/protocols.md +68 -0
- package/resources/harness/bundles/java/codex/harness-review/reference.md +86 -0
- package/resources/harness/bundles/java/codex/harness-run/SKILL.md +129 -0
- package/resources/harness/bundles/java/codex/harness-run/checklist.md +250 -0
- package/resources/harness/bundles/java/codex/harness-run/protocols.md +78 -0
- package/resources/harness/bundles/java/codex/harness-run/reference.md +814 -0
- package/resources/harness/bundles/java/codex/harness-submit/SKILL.md +149 -0
- package/resources/harness/bundles/java/codex/harness-submit/checklist.md +407 -0
- package/resources/harness/bundles/java/codex/harness-submit/reference.md +152 -0
- package/resources/harness/bundles/java/codex/harness-sync/SKILL.md +65 -0
- package/resources/harness/bundles/java/codex/harness-sync/reference.md +153 -0
- package/resources/harness/bundles/java/codex/harness-test/SKILL.md +172 -0
- package/resources/harness/bundles/java/codex/harness-test/checklist.md +317 -0
- package/resources/harness/bundles/java/codex/harness-test/pitfalls-java.md +16 -0
- package/resources/harness/bundles/java/codex/harness-test/pitfalls.md +260 -0
- package/resources/harness/bundles/java/codex/harness-test/reference.md +788 -0
- package/resources/harness/bundles/java/codex/protocols/archive-report-protocol.md +175 -0
- package/resources/harness/bundles/java/codex/protocols/evidence-based-reporting-protocol.md +134 -0
- package/resources/harness/bundles/java/codex/protocols/ledger-protocol.md +270 -0
- package/resources/harness/bundles/java/codex/protocols/powershell-protocol.md +181 -0
- package/resources/harness/bundles/java/codex/protocols/report-pipeline-protocol.md +150 -0
- package/resources/harness/bundles/java/codex/protocols/sensitive-info-protocol.md +92 -0
- package/resources/harness/bundles/java/codex/protocols/state-layout-protocol.md +131 -0
- package/resources/harness/bundles/java/codex/protocols/submit-protocol.md +78 -0
- package/resources/harness/bundles/java/codex/scripts/harness_archive.py +2319 -0
- package/resources/harness/bundles/java/codex/scripts/harness_deploy.py +674 -0
- package/resources/harness/bundles/java/codex/scripts/harness_events.py +680 -0
- package/resources/harness/bundles/java/codex/scripts/harness_ledger.py +671 -0
- package/resources/harness/bundles/java/codex/scripts/harness_preflight.py +780 -0
- package/resources/harness/bundles/java/codex/scripts/harness_service.py +1331 -0
- package/resources/harness/bundles/java/cursor/.harness-build.json +6 -0
- package/resources/harness/bundles/java/cursor/CONTEXT.md +65 -0
- package/resources/harness/bundles/java/cursor/README.md +478 -0
- package/resources/harness/bundles/java/cursor/harness-apidoc/SKILL.md +68 -0
- package/resources/harness/bundles/java/cursor/harness-apidoc/checklist.md +142 -0
- package/resources/harness/bundles/java/cursor/harness-apidoc/reference.md +233 -0
- package/resources/harness/bundles/java/cursor/harness-archive/SKILL.md +198 -0
- package/resources/harness/bundles/java/cursor/harness-archive/checklist.md +52 -0
- package/resources/harness/bundles/java/cursor/harness-archive/reference.md +103 -0
- package/resources/harness/bundles/java/cursor/harness-archive/scripts/gen-manifest.ps1 +31 -0
- package/resources/harness/bundles/java/cursor/harness-archive/templates/render-summary.mjs +171 -0
- package/resources/harness/bundles/java/cursor/harness-archive/templates/summary-data-template.json +128 -0
- package/resources/harness/bundles/java/cursor/harness-codebase-map/SKILL.md +95 -0
- package/resources/harness/bundles/java/cursor/harness-codebase-map/checklist.md +126 -0
- package/resources/harness/bundles/java/cursor/harness-codebase-map/reference.md +364 -0
- package/resources/harness/bundles/java/cursor/harness-codebase-map/templates/ARCHITECTURE.md +57 -0
- package/resources/harness/bundles/java/cursor/harness-codebase-map/templates/CONCERNS.md +49 -0
- package/resources/harness/bundles/java/cursor/harness-codebase-map/templates/CONVENTIONS.md +57 -0
- package/resources/harness/bundles/java/cursor/harness-codebase-map/templates/INTEGRATIONS.md +52 -0
- package/resources/harness/bundles/java/cursor/harness-codebase-map/templates/STACK.md +55 -0
- package/resources/harness/bundles/java/cursor/harness-codebase-map/templates/STRUCTURE.md +69 -0
- package/resources/harness/bundles/java/cursor/harness-codebase-map/templates/TESTING.md +64 -0
- package/resources/harness/bundles/java/cursor/harness-codebase-map/templates/map-manifest.schema.json +73 -0
- package/resources/harness/bundles/java/cursor/harness-codebase-map/templates/map-summary.md +64 -0
- package/resources/harness/bundles/java/cursor/harness-knowledge-ingest/SKILL.md +229 -0
- package/resources/harness/bundles/java/cursor/harness-knowledge-ingest/design.md +842 -0
- package/resources/harness/bundles/java/cursor/harness-knowledge-ingest/evaluations/harness_knowledge_evaluation.xml +42 -0
- package/resources/harness/bundles/java/cursor/harness-knowledge-ingest/mcp-config.example.json +10 -0
- package/resources/harness/bundles/java/cursor/harness-knowledge-ingest/reference.md +309 -0
- package/resources/harness/bundles/java/cursor/harness-knowledge-ingest/scripts/harness_knowledge.py +4082 -0
- package/resources/harness/bundles/java/cursor/harness-knowledge-ingest/scripts/harness_knowledge_mcp.py +273 -0
- package/resources/harness/bundles/java/cursor/harness-knowledge-query/SKILL.md +147 -0
- package/resources/harness/bundles/java/cursor/harness-package/SKILL.md +69 -0
- package/resources/harness/bundles/java/cursor/harness-package/checklist.md +322 -0
- package/resources/harness/bundles/java/cursor/harness-package/reference.md +210 -0
- package/resources/harness/bundles/java/cursor/harness-plan/SKILL.md +109 -0
- package/resources/harness/bundles/java/cursor/harness-plan/checklist.md +243 -0
- package/resources/harness/bundles/java/cursor/harness-plan/protocols.md +124 -0
- package/resources/harness/bundles/java/cursor/harness-plan/reference.md +376 -0
- package/resources/harness/bundles/java/cursor/harness-review/SKILL.md +137 -0
- package/resources/harness/bundles/java/cursor/harness-review/checklist.md +124 -0
- package/resources/harness/bundles/java/cursor/harness-review/protocols.md +68 -0
- package/resources/harness/bundles/java/cursor/harness-review/reference.md +86 -0
- package/resources/harness/bundles/java/cursor/harness-run/SKILL.md +129 -0
- package/resources/harness/bundles/java/cursor/harness-run/checklist.md +250 -0
- package/resources/harness/bundles/java/cursor/harness-run/protocols.md +78 -0
- package/resources/harness/bundles/java/cursor/harness-run/reference.md +814 -0
- package/resources/harness/bundles/java/cursor/harness-submit/SKILL.md +149 -0
- package/resources/harness/bundles/java/cursor/harness-submit/checklist.md +407 -0
- package/resources/harness/bundles/java/cursor/harness-submit/reference.md +152 -0
- package/resources/harness/bundles/java/cursor/harness-sync/SKILL.md +65 -0
- package/resources/harness/bundles/java/cursor/harness-sync/reference.md +153 -0
- package/resources/harness/bundles/java/cursor/harness-test/SKILL.md +172 -0
- package/resources/harness/bundles/java/cursor/harness-test/checklist.md +317 -0
- package/resources/harness/bundles/java/cursor/harness-test/pitfalls-java.md +16 -0
- package/resources/harness/bundles/java/cursor/harness-test/pitfalls.md +260 -0
- package/resources/harness/bundles/java/cursor/harness-test/reference.md +788 -0
- package/resources/harness/bundles/java/cursor/protocols/archive-report-protocol.md +175 -0
- package/resources/harness/bundles/java/cursor/protocols/evidence-based-reporting-protocol.md +134 -0
- package/resources/harness/bundles/java/cursor/protocols/ledger-protocol.md +270 -0
- package/resources/harness/bundles/java/cursor/protocols/powershell-protocol.md +181 -0
- package/resources/harness/bundles/java/cursor/protocols/report-pipeline-protocol.md +150 -0
- package/resources/harness/bundles/java/cursor/protocols/sensitive-info-protocol.md +92 -0
- package/resources/harness/bundles/java/cursor/protocols/state-layout-protocol.md +131 -0
- package/resources/harness/bundles/java/cursor/protocols/submit-protocol.md +78 -0
- package/resources/harness/bundles/java/cursor/scripts/harness_archive.py +2319 -0
- package/resources/harness/bundles/java/cursor/scripts/harness_deploy.py +674 -0
- package/resources/harness/bundles/java/cursor/scripts/harness_events.py +680 -0
- package/resources/harness/bundles/java/cursor/scripts/harness_ledger.py +671 -0
- package/resources/harness/bundles/java/cursor/scripts/harness_preflight.py +780 -0
- package/resources/harness/bundles/java/cursor/scripts/harness_service.py +1331 -0
- package/resources/harness/manifests/{general.json → general/claude-code.json} +27 -26
- package/resources/harness/manifests/general/codebuddy.json +277 -0
- package/resources/harness/manifests/general/codex.json +265 -0
- package/resources/harness/manifests/general/cursor.json +265 -0
- package/resources/harness/manifests/{java.json → java/claude-code.json} +31 -30
- package/resources/harness/manifests/java/codebuddy.json +305 -0
- package/resources/harness/manifests/java/codex.json +293 -0
- package/resources/harness/manifests/java/cursor.json +293 -0
- package/resources/harness/general/.harness-build.json +0 -5
- package/resources/harness/java/.harness-build.json +0 -5
- /package/resources/harness/{general → bundles/general/claude-code}/CONTEXT.md +0 -0
- /package/resources/harness/{general → bundles/general/claude-code}/README.md +0 -0
- /package/resources/harness/{general → bundles/general/claude-code}/agents/harness-evaluator.md +0 -0
- /package/resources/harness/{general → bundles/general/claude-code}/agents/harness-explorer.md +0 -0
- /package/resources/harness/{general → bundles/general/claude-code}/harness-archive/checklist.md +0 -0
- /package/resources/harness/{general → bundles/general/claude-code}/harness-archive/reference.md +0 -0
- /package/resources/harness/{general → bundles/general/claude-code}/harness-archive/scripts/gen-manifest.ps1 +0 -0
- /package/resources/harness/{general → bundles/general/claude-code}/harness-archive/templates/render-summary.mjs +0 -0
- /package/resources/harness/{general → bundles/general/claude-code}/harness-archive/templates/summary-data-template.json +0 -0
- /package/resources/harness/{general → bundles/general/claude-code}/harness-codebase-map/checklist.md +0 -0
- /package/resources/harness/{general → bundles/general/claude-code}/harness-codebase-map/reference.md +0 -0
- /package/resources/harness/{general → bundles/general/claude-code}/harness-codebase-map/templates/ARCHITECTURE.md +0 -0
- /package/resources/harness/{general → bundles/general/claude-code}/harness-codebase-map/templates/CONCERNS.md +0 -0
- /package/resources/harness/{general → bundles/general/claude-code}/harness-codebase-map/templates/CONVENTIONS.md +0 -0
- /package/resources/harness/{general → bundles/general/claude-code}/harness-codebase-map/templates/INTEGRATIONS.md +0 -0
- /package/resources/harness/{general → bundles/general/claude-code}/harness-codebase-map/templates/STACK.md +0 -0
- /package/resources/harness/{general → bundles/general/claude-code}/harness-codebase-map/templates/STRUCTURE.md +0 -0
- /package/resources/harness/{general → bundles/general/claude-code}/harness-codebase-map/templates/TESTING.md +0 -0
- /package/resources/harness/{general → bundles/general/claude-code}/harness-codebase-map/templates/map-manifest.schema.json +0 -0
- /package/resources/harness/{general → bundles/general/claude-code}/harness-codebase-map/templates/map-summary.md +0 -0
- /package/resources/harness/{general → bundles/general/claude-code}/harness-knowledge-ingest/design.md +0 -0
- /package/resources/harness/{general → bundles/general/claude-code}/harness-knowledge-ingest/evaluations/harness_knowledge_evaluation.xml +0 -0
- /package/resources/harness/{general → bundles/general/claude-code}/harness-knowledge-ingest/mcp-config.example.json +0 -0
- /package/resources/harness/{general → bundles/general/claude-code}/harness-knowledge-ingest/scripts/harness_knowledge.py +0 -0
- /package/resources/harness/{general → bundles/general/claude-code}/harness-knowledge-ingest/scripts/harness_knowledge_mcp.py +0 -0
- /package/resources/harness/{general → bundles/general/claude-code}/harness-plan/checklist.md +0 -0
- /package/resources/harness/{general → bundles/general/claude-code}/harness-plan/protocols.md +0 -0
- /package/resources/harness/{general → bundles/general/claude-code}/harness-plan/reference.md +0 -0
- /package/resources/harness/{general → bundles/general/claude-code}/harness-review/protocols.md +0 -0
- /package/resources/harness/{general → bundles/general/claude-code}/harness-review/reference.md +0 -0
- /package/resources/harness/{general → bundles/general/claude-code}/harness-run/protocols.md +0 -0
- /package/resources/harness/{general → bundles/general/claude-code}/harness-submit/checklist.md +0 -0
- /package/resources/harness/{general → bundles/general/claude-code}/harness-submit/reference.md +0 -0
- /package/resources/harness/{general → bundles/general/claude-code}/harness-test/pitfalls.md +0 -0
- /package/resources/harness/{general → bundles/general/claude-code}/harness-test/reference.md +0 -0
- /package/resources/harness/{general → bundles/general/claude-code}/protocols/archive-report-protocol.md +0 -0
- /package/resources/harness/{general → bundles/general/claude-code}/protocols/evidence-based-reporting-protocol.md +0 -0
- /package/resources/harness/{general → bundles/general/claude-code}/protocols/ledger-protocol.md +0 -0
- /package/resources/harness/{general → bundles/general/claude-code}/protocols/powershell-protocol.md +0 -0
- /package/resources/harness/{general → bundles/general/claude-code}/protocols/report-pipeline-protocol.md +0 -0
- /package/resources/harness/{general → bundles/general/claude-code}/protocols/sensitive-info-protocol.md +0 -0
- /package/resources/harness/{general → bundles/general/claude-code}/protocols/state-layout-protocol.md +0 -0
- /package/resources/harness/{general → bundles/general/claude-code}/protocols/submit-protocol.md +0 -0
- /package/resources/harness/{java → bundles/general/codebuddy}/CONTEXT.md +0 -0
- /package/resources/harness/{java → bundles/general/codebuddy}/README.md +0 -0
- /package/resources/harness/{java → bundles/general/codebuddy}/harness-archive/checklist.md +0 -0
- /package/resources/harness/{java → bundles/general/codebuddy}/harness-archive/reference.md +0 -0
- /package/resources/harness/{java → bundles/general/codebuddy}/harness-archive/scripts/gen-manifest.ps1 +0 -0
- /package/resources/harness/{java → bundles/general/codebuddy}/harness-archive/templates/render-summary.mjs +0 -0
- /package/resources/harness/{java → bundles/general/codebuddy}/harness-archive/templates/summary-data-template.json +0 -0
- /package/resources/harness/{java → bundles/general/codebuddy}/harness-codebase-map/checklist.md +0 -0
- /package/resources/harness/{java → bundles/general/codebuddy}/harness-codebase-map/reference.md +0 -0
- /package/resources/harness/{java → bundles/general/codebuddy}/harness-codebase-map/templates/ARCHITECTURE.md +0 -0
- /package/resources/harness/{java → bundles/general/codebuddy}/harness-codebase-map/templates/CONCERNS.md +0 -0
- /package/resources/harness/{java → bundles/general/codebuddy}/harness-codebase-map/templates/CONVENTIONS.md +0 -0
- /package/resources/harness/{java → bundles/general/codebuddy}/harness-codebase-map/templates/INTEGRATIONS.md +0 -0
- /package/resources/harness/{java → bundles/general/codebuddy}/harness-codebase-map/templates/STACK.md +0 -0
- /package/resources/harness/{java → bundles/general/codebuddy}/harness-codebase-map/templates/STRUCTURE.md +0 -0
- /package/resources/harness/{java → bundles/general/codebuddy}/harness-codebase-map/templates/TESTING.md +0 -0
- /package/resources/harness/{java → bundles/general/codebuddy}/harness-codebase-map/templates/map-manifest.schema.json +0 -0
- /package/resources/harness/{java → bundles/general/codebuddy}/harness-codebase-map/templates/map-summary.md +0 -0
- /package/resources/harness/{java → bundles/general/codebuddy}/harness-knowledge-ingest/design.md +0 -0
- /package/resources/harness/{java → bundles/general/codebuddy}/harness-knowledge-ingest/evaluations/harness_knowledge_evaluation.xml +0 -0
- /package/resources/harness/{java → bundles/general/codebuddy}/harness-knowledge-ingest/mcp-config.example.json +0 -0
- /package/resources/harness/{java → bundles/general/codebuddy}/harness-knowledge-ingest/scripts/harness_knowledge.py +0 -0
- /package/resources/harness/{java → bundles/general/codebuddy}/harness-knowledge-ingest/scripts/harness_knowledge_mcp.py +0 -0
- /package/resources/harness/{java → bundles/general/codebuddy}/harness-plan/checklist.md +0 -0
- /package/resources/harness/{java → bundles/general/codebuddy}/harness-plan/protocols.md +0 -0
- /package/resources/harness/{java → bundles/general/codebuddy}/harness-plan/reference.md +0 -0
- /package/resources/harness/{java → bundles/general/codebuddy}/harness-review/protocols.md +0 -0
- /package/resources/harness/{java → bundles/general/codebuddy}/harness-review/reference.md +0 -0
- /package/resources/harness/{java → bundles/general/codebuddy}/harness-run/protocols.md +0 -0
- /package/resources/harness/{java → bundles/general/codebuddy}/harness-submit/checklist.md +0 -0
- /package/resources/harness/{java → bundles/general/codebuddy}/harness-submit/reference.md +0 -0
- /package/resources/harness/{java → bundles/general/codebuddy}/harness-test/pitfalls.md +0 -0
- /package/resources/harness/{java → bundles/general/codebuddy}/protocols/archive-report-protocol.md +0 -0
- /package/resources/harness/{java → bundles/general/codebuddy}/protocols/evidence-based-reporting-protocol.md +0 -0
- /package/resources/harness/{java → bundles/general/codebuddy}/protocols/ledger-protocol.md +0 -0
- /package/resources/harness/{java → bundles/general/codebuddy}/protocols/powershell-protocol.md +0 -0
- /package/resources/harness/{java → bundles/general/codebuddy}/protocols/report-pipeline-protocol.md +0 -0
- /package/resources/harness/{java → bundles/general/codebuddy}/protocols/sensitive-info-protocol.md +0 -0
- /package/resources/harness/{java → bundles/general/codebuddy}/protocols/state-layout-protocol.md +0 -0
- /package/resources/harness/{java → bundles/general/codebuddy}/protocols/submit-protocol.md +0 -0
- /package/resources/harness/{java → bundles/java/claude-code}/agents/harness-evaluator.md +0 -0
- /package/resources/harness/{java → bundles/java/claude-code}/agents/harness-explorer.md +0 -0
- /package/resources/harness/{java → bundles/java/claude-code}/harness-apidoc/checklist.md +0 -0
- /package/resources/harness/{java → bundles/java/claude-code}/harness-apidoc/reference.md +0 -0
- /package/resources/harness/{java → bundles/java/claude-code}/harness-package/checklist.md +0 -0
- /package/resources/harness/{java → bundles/java/claude-code}/harness-test/pitfalls-java.md +0 -0
package/dist/bin.js
CHANGED
|
@@ -567,16 +567,29 @@ import { z as z9 } from "zod";
|
|
|
567
567
|
var projectIdSchema = z9.string().regex(/^prj_[A-Za-z0-9_-]+$/);
|
|
568
568
|
var tokenEnvSchema = z9.string().regex(/^[A-Z_][A-Z0-9_]*$/);
|
|
569
569
|
var httpsUrlSchema = z9.url().refine((value) => new URL(value).protocol === "https:", "server URL must use HTTPS");
|
|
570
|
+
var HARNESS_AGENT_ORDER = [
|
|
571
|
+
"claude-code",
|
|
572
|
+
"codex",
|
|
573
|
+
"cursor",
|
|
574
|
+
"codebuddy"
|
|
575
|
+
];
|
|
576
|
+
var harnessAgentSchema = z9.enum(HARNESS_AGENT_ORDER);
|
|
577
|
+
var codebuddySurfaceSchema = z9.enum(["both", "ide", "cli"]);
|
|
578
|
+
function sortHarnessAgents(agents) {
|
|
579
|
+
return HARNESS_AGENT_ORDER.filter((agent) => agents.includes(agent));
|
|
580
|
+
}
|
|
570
581
|
var adapterNameSchema = z9.enum([
|
|
571
582
|
"claude-code",
|
|
572
583
|
"codex",
|
|
573
584
|
"cursor",
|
|
585
|
+
"codebuddy",
|
|
574
586
|
"generic",
|
|
575
587
|
"mcp"
|
|
576
588
|
]);
|
|
577
589
|
var initConfigSchema = z9.object({
|
|
578
|
-
|
|
590
|
+
agents: z9.array(harnessAgentSchema).min(1),
|
|
579
591
|
profile: z9.enum(["general", "java"]),
|
|
592
|
+
codebuddy_surface: codebuddySurfaceSchema.default("both"),
|
|
580
593
|
server_url: httpsUrlSchema.nullable().optional(),
|
|
581
594
|
token_env: tokenEnvSchema.nullable().optional(),
|
|
582
595
|
project_id: projectIdSchema.nullable().optional(),
|
|
@@ -603,7 +616,12 @@ var projectConfigSchema = z9.object({
|
|
|
603
616
|
}).strict(),
|
|
604
617
|
adapters: z9.object({
|
|
605
618
|
enabled: z9.array(adapterNameSchema).min(1)
|
|
606
|
-
}).strict()
|
|
619
|
+
}).strict(),
|
|
620
|
+
adapter_options: z9.object({
|
|
621
|
+
codebuddy: z9.object({
|
|
622
|
+
surface: codebuddySurfaceSchema
|
|
623
|
+
}).strict()
|
|
624
|
+
}).strict().optional()
|
|
607
625
|
}).strict();
|
|
608
626
|
|
|
609
627
|
// ../contracts/dist/dashboard.js
|
|
@@ -817,8 +835,8 @@ async function assertNoSymlinks(root, relativePath) {
|
|
|
817
835
|
for (const segment of normalized.split("/")) {
|
|
818
836
|
current = join(current, segment);
|
|
819
837
|
try {
|
|
820
|
-
const
|
|
821
|
-
if (
|
|
838
|
+
const stat5 = await lstat(current);
|
|
839
|
+
if (stat5.isSymbolicLink()) {
|
|
822
840
|
throw new UnsafePathError("symbolic links are not managed");
|
|
823
841
|
}
|
|
824
842
|
} catch (error) {
|
|
@@ -1063,12 +1081,12 @@ function renderBlock(content, newline) {
|
|
|
1063
1081
|
return MANAGED_BLOCK_START + newline + normalized + newline + MANAGED_BLOCK_END;
|
|
1064
1082
|
}
|
|
1065
1083
|
function extractManagedBlock(content) {
|
|
1066
|
-
if (validateMarkers(content) === "
|
|
1067
|
-
|
|
1084
|
+
if (validateMarkers(content) === "present") {
|
|
1085
|
+
const start = content.indexOf(MANAGED_BLOCK_START) + MANAGED_BLOCK_START.length;
|
|
1086
|
+
const end = content.indexOf(MANAGED_BLOCK_END);
|
|
1087
|
+
return content.slice(start, end).replace(/^\r?\n/, "").replace(/\r?\n$/, "");
|
|
1068
1088
|
}
|
|
1069
|
-
|
|
1070
|
-
const end = content.indexOf(MANAGED_BLOCK_END);
|
|
1071
|
-
return content.slice(start, end).replace(/^\r?\n/, "").replace(/\r?\n$/, "");
|
|
1089
|
+
return extractSingleManagedBlockById(content)?.content ?? null;
|
|
1072
1090
|
}
|
|
1073
1091
|
function upsertManagedBlock(original, content) {
|
|
1074
1092
|
const newline = original.includes("\r\n") ? "\r\n" : "\n";
|
|
@@ -1094,25 +1112,34 @@ function removeManagedBlock(original) {
|
|
|
1094
1112
|
const after = original.slice(end).replace(/^(?:\r?\n){1,2}/, "");
|
|
1095
1113
|
return before + after;
|
|
1096
1114
|
}
|
|
1097
|
-
function refreshManagedBlock(original, blockContent) {
|
|
1098
|
-
const starts = markerCount(original, MANAGED_BLOCK_START);
|
|
1099
|
-
const ends = markerCount(original, MANAGED_BLOCK_END);
|
|
1100
|
-
const absent = starts === 0 && ends === 0;
|
|
1101
|
-
const malformed = !absent && (starts !== 1 || ends !== 1 || original.indexOf(MANAGED_BLOCK_START) > original.indexOf(MANAGED_BLOCK_END));
|
|
1102
|
-
if (malformed) {
|
|
1103
|
-
return { content: original, action: "preserved_conflict", conflict: true };
|
|
1104
|
-
}
|
|
1105
|
-
const action = absent ? "appended" : "refreshed";
|
|
1106
|
-
return { content: upsertManagedBlock(original, blockContent), action, conflict: false };
|
|
1107
|
-
}
|
|
1108
1115
|
function escapeRe(value) {
|
|
1109
1116
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
1110
1117
|
}
|
|
1111
1118
|
var startById = (id) => `<!-- hunter-harness:start id=${id} -->`;
|
|
1112
1119
|
var endById = (id) => `<!-- hunter-harness:end id=${id} -->`;
|
|
1120
|
+
function extractSingleManagedBlockById(content) {
|
|
1121
|
+
const matches = [...content.matchAll(/<!-- hunter-harness:start id=([A-Za-z0-9_-]+) -->/g)];
|
|
1122
|
+
if (matches.length !== 1)
|
|
1123
|
+
return null;
|
|
1124
|
+
const id = matches[0]?.[1];
|
|
1125
|
+
if (id === void 0)
|
|
1126
|
+
return null;
|
|
1127
|
+
const start = startById(id);
|
|
1128
|
+
const end = endById(id);
|
|
1129
|
+
if (markerCount(content, start) !== 1 || markerCount(content, end) !== 1 || content.indexOf(start) > content.indexOf(end)) {
|
|
1130
|
+
throw new Error("managed block markers are malformed or duplicated");
|
|
1131
|
+
}
|
|
1132
|
+
const bodyStart = content.indexOf(start) + start.length;
|
|
1133
|
+
const bodyEnd = content.indexOf(end);
|
|
1134
|
+
return {
|
|
1135
|
+
id,
|
|
1136
|
+
content: content.slice(bodyStart, bodyEnd).replace(/^\r?\n/, "").replace(/\r?\n$/, "")
|
|
1137
|
+
};
|
|
1138
|
+
}
|
|
1113
1139
|
function upsertManagedBlockById(original, id, content) {
|
|
1114
1140
|
const newline = original.includes("\r\n") ? "\r\n" : "\n";
|
|
1115
|
-
const
|
|
1141
|
+
const normalized = content.replace(/\r\n/g, "\n").replace(/\n/g, newline);
|
|
1142
|
+
const block = startById(id) + newline + normalized + newline + endById(id);
|
|
1116
1143
|
const re = new RegExp(escapeRe(startById(id)) + "[\\s\\S]*?" + escapeRe(endById(id)));
|
|
1117
1144
|
if (re.test(original)) {
|
|
1118
1145
|
return original.replace(re, block);
|
|
@@ -1120,6 +1147,68 @@ function upsertManagedBlockById(original, id, content) {
|
|
|
1120
1147
|
const separator = original.length === 0 ? "" : original.endsWith(newline) ? newline : newline + newline;
|
|
1121
1148
|
return original + separator + block + newline;
|
|
1122
1149
|
}
|
|
1150
|
+
function refreshManagedBlockById(original, id, blockContent, options = {}) {
|
|
1151
|
+
const idStart = startById(id);
|
|
1152
|
+
const idEnd = endById(id);
|
|
1153
|
+
const idStarts = markerCount(original, idStart);
|
|
1154
|
+
const idEnds = markerCount(original, idEnd);
|
|
1155
|
+
if (idStarts > 0 || idEnds > 0) {
|
|
1156
|
+
if (idStarts !== 1 || idEnds !== 1 || original.indexOf(idStart) > original.indexOf(idEnd)) {
|
|
1157
|
+
return { content: original, action: "preserved_conflict", conflict: true };
|
|
1158
|
+
}
|
|
1159
|
+
return {
|
|
1160
|
+
content: upsertManagedBlockById(original, id, blockContent),
|
|
1161
|
+
action: "refreshed",
|
|
1162
|
+
conflict: false
|
|
1163
|
+
};
|
|
1164
|
+
}
|
|
1165
|
+
const legacyStarts = markerCount(original, MANAGED_BLOCK_START);
|
|
1166
|
+
const legacyEnds = markerCount(original, MANAGED_BLOCK_END);
|
|
1167
|
+
const legacyAbsent = legacyStarts === 0 && legacyEnds === 0;
|
|
1168
|
+
const legacyMalformed = !legacyAbsent && (legacyStarts !== 1 || legacyEnds !== 1 || original.indexOf(MANAGED_BLOCK_START) > original.indexOf(MANAGED_BLOCK_END));
|
|
1169
|
+
if (legacyMalformed) {
|
|
1170
|
+
return { content: original, action: "preserved_conflict", conflict: true };
|
|
1171
|
+
}
|
|
1172
|
+
if (!legacyAbsent && options.upgradeLegacy === true) {
|
|
1173
|
+
const newline = original.includes("\r\n") ? "\r\n" : "\n";
|
|
1174
|
+
const normalized = blockContent.replace(/\r\n/g, "\n").replace(/\n/g, newline);
|
|
1175
|
+
const block = idStart + newline + normalized + newline + idEnd;
|
|
1176
|
+
const start = original.indexOf(MANAGED_BLOCK_START);
|
|
1177
|
+
const end = original.indexOf(MANAGED_BLOCK_END) + MANAGED_BLOCK_END.length;
|
|
1178
|
+
return {
|
|
1179
|
+
content: original.slice(0, start) + block + original.slice(end),
|
|
1180
|
+
action: "refreshed",
|
|
1181
|
+
conflict: false
|
|
1182
|
+
};
|
|
1183
|
+
}
|
|
1184
|
+
if (!legacyAbsent) {
|
|
1185
|
+
return {
|
|
1186
|
+
content: upsertManagedBlockById(original, id, blockContent),
|
|
1187
|
+
action: "appended",
|
|
1188
|
+
conflict: false
|
|
1189
|
+
};
|
|
1190
|
+
}
|
|
1191
|
+
return {
|
|
1192
|
+
content: upsertManagedBlockById(original, id, blockContent),
|
|
1193
|
+
action: "appended",
|
|
1194
|
+
conflict: false
|
|
1195
|
+
};
|
|
1196
|
+
}
|
|
1197
|
+
function removeManagedBlockById(original, id) {
|
|
1198
|
+
const idStart = startById(id);
|
|
1199
|
+
const idEnd = endById(id);
|
|
1200
|
+
if (markerCount(original, idStart) === 0 && markerCount(original, idEnd) === 0) {
|
|
1201
|
+
return original;
|
|
1202
|
+
}
|
|
1203
|
+
if (markerCount(original, idStart) !== 1 || markerCount(original, idEnd) !== 1 || original.indexOf(idStart) > original.indexOf(idEnd)) {
|
|
1204
|
+
throw new Error("managed block markers are malformed or duplicated");
|
|
1205
|
+
}
|
|
1206
|
+
const start = original.indexOf(idStart);
|
|
1207
|
+
const end = original.indexOf(idEnd) + idEnd.length;
|
|
1208
|
+
const before = original.slice(0, start).replace(/(?:\r?\n){2}$/, "\n");
|
|
1209
|
+
const after = original.slice(end).replace(/^(?:\r?\n){1,2}/, "");
|
|
1210
|
+
return before + after;
|
|
1211
|
+
}
|
|
1123
1212
|
|
|
1124
1213
|
// ../core/dist/policy/file-policy.js
|
|
1125
1214
|
var USER_MANAGED_BLOCK = {
|
|
@@ -1197,10 +1286,10 @@ function under(path, prefix) {
|
|
|
1197
1286
|
}
|
|
1198
1287
|
function classifyFile(input) {
|
|
1199
1288
|
const path = normalizeManagedPath(input);
|
|
1200
|
-
if (path === "CLAUDE.md" || path === "AGENTS.md") {
|
|
1289
|
+
if (path === "CLAUDE.md" || path === "AGENTS.md" || path === "CODEBUDDY.md") {
|
|
1201
1290
|
return USER_MANAGED_BLOCK;
|
|
1202
1291
|
}
|
|
1203
|
-
if (under(path, ".claude/rules/") || under(path, ".claude/skills/harness-")) {
|
|
1292
|
+
if (under(path, ".claude/rules/") || under(path, ".claude/skills/harness-") || under(path, ".agents/skills/harness-") || under(path, ".cursor/skills/harness-") || under(path, ".codebuddy/skills/harness-") || under(path, ".codebuddy/agents/harness-")) {
|
|
1204
1293
|
return USER_DIFF;
|
|
1205
1294
|
}
|
|
1206
1295
|
if (under(path, ".cursor/rules/") || under(path, ".agent-skills/")) {
|
|
@@ -1255,6 +1344,7 @@ function decideUpdate(policy, dirty) {
|
|
|
1255
1344
|
}
|
|
1256
1345
|
|
|
1257
1346
|
// ../core/dist/project/initialize.js
|
|
1347
|
+
import { createHash as createHash4 } from "node:crypto";
|
|
1258
1348
|
import { readFile as readFile4, stat as stat2 } from "node:fs/promises";
|
|
1259
1349
|
import { basename, join as join5, resolve as resolve3 } from "node:path";
|
|
1260
1350
|
import { parse as parseYaml2, stringify as stringifyYaml } from "yaml";
|
|
@@ -1508,13 +1598,20 @@ async function runTransaction(projectRoot, rawOperations, options = {}) {
|
|
|
1508
1598
|
return { transactionId, status: "committed" };
|
|
1509
1599
|
}
|
|
1510
1600
|
|
|
1601
|
+
// ../core/dist/project/agent-adapters.js
|
|
1602
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
1603
|
+
|
|
1511
1604
|
// ../core/dist/project/managed-content.js
|
|
1605
|
+
var AGENTS_CORE_BLOCK_ID = "hunter-harness-core";
|
|
1606
|
+
var CLAUDE_BLOCK_ID = "hunter-harness-claude-code";
|
|
1607
|
+
var CODEBUDDY_BLOCK_ID = "hunter-harness-codebuddy";
|
|
1512
1608
|
var AGENTS_MANAGED_BLOCK_CONTENT = [
|
|
1513
1609
|
"# Hunter Harness",
|
|
1514
1610
|
"",
|
|
1515
|
-
"Use
|
|
1516
|
-
"
|
|
1517
|
-
"
|
|
1611
|
+
"Use `.harness/context-index.json` to locate the instructions, skills, knowledge,",
|
|
1612
|
+
"and codebase map for the active agent.",
|
|
1613
|
+
"Treat installed `harness-*` skills as editable adapter working copies.",
|
|
1614
|
+
"Do not modify `.harness/state` or `.harness/cache` directly."
|
|
1518
1615
|
].join("\n");
|
|
1519
1616
|
var CLAUDE_MANAGED_BLOCK_CONTENT = [
|
|
1520
1617
|
"@AGENTS.md",
|
|
@@ -1526,54 +1623,61 @@ var CLAUDE_MANAGED_BLOCK_CONTENT = [
|
|
|
1526
1623
|
"- Knowledge: .harness/knowledge/",
|
|
1527
1624
|
"- Codebase map: .harness/codebase/map/"
|
|
1528
1625
|
].join("\n");
|
|
1626
|
+
var CODEBUDDY_MANAGED_BLOCK_CONTENT = [
|
|
1627
|
+
"# Hunter Harness",
|
|
1628
|
+
"",
|
|
1629
|
+
"Use `.harness/context-index.json` to locate the instructions, skills, knowledge,",
|
|
1630
|
+
"and codebase map for the active agent.",
|
|
1631
|
+
"Treat installed `harness-*` skills as editable adapter working copies.",
|
|
1632
|
+
"Do not modify `.harness/state` or `.harness/cache` directly.",
|
|
1633
|
+
"",
|
|
1634
|
+
"- Skills: .codebuddy/skills/harness-*/",
|
|
1635
|
+
"- Agents: .codebuddy/agents/harness-*.md",
|
|
1636
|
+
"- Knowledge: .harness/knowledge/",
|
|
1637
|
+
"- Codebase map: .harness/codebase/map/"
|
|
1638
|
+
].join("\n");
|
|
1529
1639
|
var HARNESS_GENERAL_RULES_CONTENT = "# Hunter Harness Rules\n\n- Report evidence honestly.\n- Do not execute destructive actions without confirmation.\n";
|
|
1530
1640
|
var HARNESS_JAVA_RULES_CONTENT = "# Java Profile\n\n- Verify builds and tests with the project build tool.\n";
|
|
1641
|
+
var CURSOR_GENERAL_RULES_CONTENT = "---\ndescription: Hunter Harness project-wide safety and evidence rules\nglobs:\nalwaysApply: true\n---\n\n# Hunter Harness Rules\n\n- Report evidence honestly.\n- Do not execute destructive actions without confirmation.\n";
|
|
1642
|
+
var CURSOR_JAVA_RULES_CONTENT = "---\ndescription: Hunter Harness Java profile rules\nglobs:\nalwaysApply: true\n---\n\n# Java Profile\n\n- Verify builds and tests with the project build tool.\n";
|
|
1531
1643
|
|
|
1532
|
-
// ../core/dist/project/
|
|
1533
|
-
|
|
1534
|
-
import { readFile as readFile3, readdir as readdir2 } from "node:fs/promises";
|
|
1535
|
-
import { join as join4 } from "node:path";
|
|
1536
|
-
function isProfile(value) {
|
|
1537
|
-
return value === "general" || value === "java";
|
|
1538
|
-
}
|
|
1644
|
+
// ../core/dist/project/agent-adapters.js
|
|
1645
|
+
var AGENT_SOURCE_PATH = /^agents\/([^/]+\.md)$/;
|
|
1539
1646
|
function validateRelativeBundlePath(path) {
|
|
1540
1647
|
if (typeof path !== "string" || path.length === 0 || path.includes("\0") || path.startsWith("/") || path.startsWith("\\") || /^[A-Za-z]:/.test(path) || path.split("/").some((part) => part === "" || part === "." || part === "..")) {
|
|
1541
1648
|
throw new Error("invalid Harness Bundle path");
|
|
1542
1649
|
}
|
|
1543
1650
|
}
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
validateRelativeBundlePath(item2.path);
|
|
1552
|
-
if (typeof item2.sha256 !== "string" || !/^[a-f0-9]{64}$/.test(item2.sha256) || files.has(item2.path)) {
|
|
1553
|
-
throw new Error(`invalid ${profile} Harness Bundle manifest entry`);
|
|
1554
|
-
}
|
|
1555
|
-
const bytes = await readFile3(join4(resourcesRoot, "harness", profile, item2.path));
|
|
1556
|
-
if (createHash2("sha256").update(bytes).digest("hex") !== item2.sha256) {
|
|
1557
|
-
throw new Error(`Harness Bundle hash mismatch: ${item2.path}`);
|
|
1558
|
-
}
|
|
1559
|
-
files.set(item2.path, bytes);
|
|
1560
|
-
}
|
|
1561
|
-
return { manifest: raw, files };
|
|
1562
|
-
}
|
|
1563
|
-
async function managedBundleTargets(resourcesRoot, profile) {
|
|
1564
|
-
const bundle = await loadProfileBundle(resourcesRoot, profile);
|
|
1565
|
-
const targets = new Set(bundleTargetContents(bundle).keys());
|
|
1566
|
-
if (profile === "java")
|
|
1567
|
-
targets.add(".claude/rules/harness-profile-java.md");
|
|
1568
|
-
return targets;
|
|
1651
|
+
function ruleTarget(sourcePath, targetPath, content) {
|
|
1652
|
+
return {
|
|
1653
|
+
source_path: sourcePath,
|
|
1654
|
+
target_path: normalizeManagedPath(targetPath),
|
|
1655
|
+
sha256: createHash2("sha256").update(content).digest("hex"),
|
|
1656
|
+
bytes: new TextEncoder().encode(content)
|
|
1657
|
+
};
|
|
1569
1658
|
}
|
|
1570
|
-
|
|
1571
|
-
function projectBundle(bundle) {
|
|
1659
|
+
function projectBundleFiles(bundle, skillsRoot, agentsRoot) {
|
|
1572
1660
|
const records = [];
|
|
1573
1661
|
for (const [sourcePath, bytes] of bundle.files) {
|
|
1574
1662
|
validateRelativeBundlePath(sourcePath);
|
|
1575
1663
|
const agent = AGENT_SOURCE_PATH.exec(sourcePath);
|
|
1576
|
-
|
|
1664
|
+
if (agent?.[1] !== void 0) {
|
|
1665
|
+
if (agentsRoot === null)
|
|
1666
|
+
continue;
|
|
1667
|
+
const projectedTarget2 = `${agentsRoot}/${agent[1]}`;
|
|
1668
|
+
const manifestEntry2 = bundle.manifest.files.find((entry) => entry.path === sourcePath);
|
|
1669
|
+
if (manifestEntry2 === void 0) {
|
|
1670
|
+
throw new Error(`Harness Bundle missing manifest entry: ${sourcePath}`);
|
|
1671
|
+
}
|
|
1672
|
+
records.push({
|
|
1673
|
+
source_path: sourcePath,
|
|
1674
|
+
target_path: normalizeManagedPath(projectedTarget2),
|
|
1675
|
+
sha256: manifestEntry2.sha256,
|
|
1676
|
+
bytes
|
|
1677
|
+
});
|
|
1678
|
+
continue;
|
|
1679
|
+
}
|
|
1680
|
+
const projectedTarget = `${skillsRoot}/${sourcePath}`;
|
|
1577
1681
|
const manifestEntry = bundle.manifest.files.find((entry) => entry.path === sourcePath);
|
|
1578
1682
|
if (manifestEntry === void 0) {
|
|
1579
1683
|
throw new Error(`Harness Bundle missing manifest entry: ${sourcePath}`);
|
|
@@ -1588,32 +1692,195 @@ function projectBundle(bundle) {
|
|
|
1588
1692
|
assertNoCaseCollisions(records.map((record) => record.target_path));
|
|
1589
1693
|
return records.sort((left, right) => left.target_path.localeCompare(right.target_path));
|
|
1590
1694
|
}
|
|
1591
|
-
function
|
|
1592
|
-
return new Map(projectBundle(bundle).map((record) => [record.target_path, record.bytes]));
|
|
1593
|
-
}
|
|
1594
|
-
function ruleTarget(sourcePath, targetPath, content) {
|
|
1695
|
+
function makeAdapter(spec) {
|
|
1595
1696
|
return {
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1697
|
+
name: spec.name,
|
|
1698
|
+
skillsRoot: spec.skillsRoot,
|
|
1699
|
+
rulesRoot: spec.rulesRoot,
|
|
1700
|
+
agentsRoot: spec.agentsRoot,
|
|
1701
|
+
commandsRoot: spec.commandsRoot,
|
|
1702
|
+
supportsExecutableHooks: false,
|
|
1703
|
+
projectInstructionTargets() {
|
|
1704
|
+
return ["AGENTS.md", ...spec.extraInstructionFiles];
|
|
1705
|
+
},
|
|
1706
|
+
projectBundle(bundle) {
|
|
1707
|
+
return projectBundleFiles(bundle, spec.skillsRoot, spec.agentsRoot);
|
|
1708
|
+
},
|
|
1709
|
+
contextIndex(context) {
|
|
1710
|
+
const rules = [];
|
|
1711
|
+
if (spec.rulesRoot !== null && spec.ruleExt !== null) {
|
|
1712
|
+
rules.push(`${spec.rulesRoot}/harness-general${spec.ruleExt}`);
|
|
1713
|
+
if (context.profile === "java") {
|
|
1714
|
+
rules.push(`${spec.rulesRoot}/harness-profile-java${spec.ruleExt}`);
|
|
1715
|
+
}
|
|
1716
|
+
}
|
|
1717
|
+
return {
|
|
1718
|
+
instructions: spec.instructions,
|
|
1719
|
+
skills_root: spec.skillsRoot,
|
|
1720
|
+
rules
|
|
1721
|
+
};
|
|
1722
|
+
},
|
|
1723
|
+
pruneBoundaries() {
|
|
1724
|
+
const boundaries = [spec.skillsRoot];
|
|
1725
|
+
if (spec.agentsRoot !== null)
|
|
1726
|
+
boundaries.push(spec.agentsRoot);
|
|
1727
|
+
if (spec.rulesRoot !== null)
|
|
1728
|
+
boundaries.push(spec.rulesRoot);
|
|
1729
|
+
const top = spec.skillsRoot.split("/")[0];
|
|
1730
|
+
if (top !== void 0)
|
|
1731
|
+
boundaries.push(top);
|
|
1732
|
+
return boundaries;
|
|
1733
|
+
}
|
|
1600
1734
|
};
|
|
1601
1735
|
}
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1736
|
+
var ADAPTERS = {
|
|
1737
|
+
"claude-code": makeAdapter({
|
|
1738
|
+
name: "claude-code",
|
|
1739
|
+
skillsRoot: ".claude/skills",
|
|
1740
|
+
rulesRoot: ".claude/rules",
|
|
1741
|
+
agentsRoot: ".claude/agents",
|
|
1742
|
+
commandsRoot: null,
|
|
1743
|
+
instructions: "CLAUDE.md",
|
|
1744
|
+
extraInstructionFiles: ["CLAUDE.md"],
|
|
1745
|
+
ruleExt: ".md"
|
|
1746
|
+
}),
|
|
1747
|
+
codex: makeAdapter({
|
|
1748
|
+
name: "codex",
|
|
1749
|
+
skillsRoot: ".agents/skills",
|
|
1750
|
+
rulesRoot: null,
|
|
1751
|
+
agentsRoot: null,
|
|
1752
|
+
commandsRoot: null,
|
|
1753
|
+
instructions: "AGENTS.md",
|
|
1754
|
+
extraInstructionFiles: [],
|
|
1755
|
+
ruleExt: null
|
|
1756
|
+
}),
|
|
1757
|
+
cursor: makeAdapter({
|
|
1758
|
+
name: "cursor",
|
|
1759
|
+
skillsRoot: ".cursor/skills",
|
|
1760
|
+
rulesRoot: ".cursor/rules",
|
|
1761
|
+
agentsRoot: null,
|
|
1762
|
+
commandsRoot: ".cursor/commands",
|
|
1763
|
+
instructions: "AGENTS.md",
|
|
1764
|
+
extraInstructionFiles: [],
|
|
1765
|
+
ruleExt: ".mdc"
|
|
1766
|
+
}),
|
|
1767
|
+
codebuddy: makeAdapter({
|
|
1768
|
+
name: "codebuddy",
|
|
1769
|
+
skillsRoot: ".codebuddy/skills",
|
|
1770
|
+
rulesRoot: null,
|
|
1771
|
+
agentsRoot: ".codebuddy/agents",
|
|
1772
|
+
commandsRoot: ".codebuddy/commands",
|
|
1773
|
+
instructions: "CODEBUDDY.md",
|
|
1774
|
+
extraInstructionFiles: ["CODEBUDDY.md"],
|
|
1775
|
+
ruleExt: null
|
|
1776
|
+
})
|
|
1777
|
+
};
|
|
1778
|
+
function getAdapter(name) {
|
|
1779
|
+
return ADAPTERS[name];
|
|
1780
|
+
}
|
|
1781
|
+
function getAdapters(names) {
|
|
1782
|
+
return HARNESS_AGENT_ORDER.filter((n) => names.includes(n)).map(getAdapter);
|
|
1783
|
+
}
|
|
1784
|
+
function managedTargetsFor(adapter, bundle, context) {
|
|
1785
|
+
const records = [...adapter.projectBundle(bundle, context)];
|
|
1786
|
+
if (adapter.name === "claude-code") {
|
|
1787
|
+
records.push(ruleTarget("rules/harness-general.md", ".claude/rules/harness-general.md", HARNESS_GENERAL_RULES_CONTENT));
|
|
1788
|
+
if (context.profile === "java") {
|
|
1789
|
+
records.push(ruleTarget("rules/harness-profile-java.md", ".claude/rules/harness-profile-java.md", HARNESS_JAVA_RULES_CONTENT));
|
|
1790
|
+
}
|
|
1791
|
+
} else if (adapter.name === "cursor") {
|
|
1792
|
+
records.push(ruleTarget("rules/harness-general.mdc", ".cursor/rules/harness-general.mdc", CURSOR_GENERAL_RULES_CONTENT));
|
|
1793
|
+
if (context.profile === "java") {
|
|
1794
|
+
records.push(ruleTarget("rules/harness-profile-java.mdc", ".cursor/rules/harness-profile-java.mdc", CURSOR_JAVA_RULES_CONTENT));
|
|
1795
|
+
}
|
|
1613
1796
|
}
|
|
1614
1797
|
assertNoCaseCollisions(records.map((record) => record.target_path));
|
|
1615
1798
|
return records.sort((left, right) => left.target_path.localeCompare(right.target_path));
|
|
1616
1799
|
}
|
|
1800
|
+
|
|
1801
|
+
// ../core/dist/project/profile-bundle.js
|
|
1802
|
+
import { createHash as createHash3 } from "node:crypto";
|
|
1803
|
+
import { readFile as readFile3, readdir as readdir2 } from "node:fs/promises";
|
|
1804
|
+
import { join as join4 } from "node:path";
|
|
1805
|
+
var AdapterBundleError = class extends Error {
|
|
1806
|
+
code;
|
|
1807
|
+
exitCode = 7;
|
|
1808
|
+
constructor(code, message) {
|
|
1809
|
+
super(message);
|
|
1810
|
+
this.code = code;
|
|
1811
|
+
this.name = "AdapterBundleError";
|
|
1812
|
+
}
|
|
1813
|
+
};
|
|
1814
|
+
function isEnoent(error) {
|
|
1815
|
+
return error !== null && typeof error === "object" && "code" in error && error.code === "ENOENT";
|
|
1816
|
+
}
|
|
1817
|
+
function isProfile(value) {
|
|
1818
|
+
return value === "general" || value === "java";
|
|
1819
|
+
}
|
|
1820
|
+
function isAgent(value) {
|
|
1821
|
+
return value === "claude-code" || value === "codex" || value === "cursor" || value === "codebuddy";
|
|
1822
|
+
}
|
|
1823
|
+
function validateRelativeBundlePath2(path) {
|
|
1824
|
+
if (typeof path !== "string" || path.length === 0 || path.includes("\0") || path.startsWith("/") || path.startsWith("\\") || /^[A-Za-z]:/.test(path) || path.split("/").some((part) => part === "" || part === "." || part === "..")) {
|
|
1825
|
+
throw new Error("invalid Harness Bundle path");
|
|
1826
|
+
}
|
|
1827
|
+
}
|
|
1828
|
+
async function loadAgentBundle(resourcesRoot, profile, agent) {
|
|
1829
|
+
const manifestPath = join4(resourcesRoot, "harness", "manifests", profile, `${agent}.json`);
|
|
1830
|
+
let manifestText;
|
|
1831
|
+
try {
|
|
1832
|
+
manifestText = await readFile3(manifestPath, "utf8");
|
|
1833
|
+
} catch (error) {
|
|
1834
|
+
if (isEnoent(error)) {
|
|
1835
|
+
throw new AdapterBundleError("ADAPTER_BUNDLE_MISSING", `offline Harness Bundle manifest missing: ${profile}/${agent}`);
|
|
1836
|
+
}
|
|
1837
|
+
throw error;
|
|
1838
|
+
}
|
|
1839
|
+
let raw;
|
|
1840
|
+
try {
|
|
1841
|
+
raw = JSON.parse(manifestText);
|
|
1842
|
+
} catch {
|
|
1843
|
+
throw new AdapterBundleError("ADAPTER_BUNDLE_INVALID", `unparseable ${profile}/${agent} Harness Bundle manifest`);
|
|
1844
|
+
}
|
|
1845
|
+
if (raw.schema_version !== 2 || raw.profile !== profile || raw.adapter !== agent || typeof raw.bundle_version !== "string" || raw.generator !== "harness_deploy.py" || !Array.isArray(raw.files)) {
|
|
1846
|
+
throw new AdapterBundleError("ADAPTER_BUNDLE_INVALID", `invalid ${profile}/${agent} Harness Bundle manifest`);
|
|
1847
|
+
}
|
|
1848
|
+
const files = /* @__PURE__ */ new Map();
|
|
1849
|
+
for (const item2 of raw.files) {
|
|
1850
|
+
try {
|
|
1851
|
+
validateRelativeBundlePath2(item2.path);
|
|
1852
|
+
} catch {
|
|
1853
|
+
throw new AdapterBundleError("ADAPTER_BUNDLE_INVALID", `invalid ${profile}/${agent} Harness Bundle path`);
|
|
1854
|
+
}
|
|
1855
|
+
if (typeof item2.sha256 !== "string" || !/^[a-f0-9]{64}$/.test(item2.sha256) || files.has(item2.path)) {
|
|
1856
|
+
throw new AdapterBundleError("ADAPTER_BUNDLE_INVALID", `invalid ${profile}/${agent} Harness Bundle manifest entry`);
|
|
1857
|
+
}
|
|
1858
|
+
let bytes;
|
|
1859
|
+
try {
|
|
1860
|
+
bytes = await readFile3(join4(resourcesRoot, "harness", "bundles", profile, agent, item2.path));
|
|
1861
|
+
} catch (error) {
|
|
1862
|
+
if (isEnoent(error)) {
|
|
1863
|
+
throw new AdapterBundleError("ADAPTER_BUNDLE_MISSING", `offline Harness Bundle file missing: ${profile}/${agent}/${item2.path}`);
|
|
1864
|
+
}
|
|
1865
|
+
throw error;
|
|
1866
|
+
}
|
|
1867
|
+
if (createHash3("sha256").update(bytes).digest("hex") !== item2.sha256) {
|
|
1868
|
+
throw new AdapterBundleError("ADAPTER_BUNDLE_INVALID", `Harness Bundle hash mismatch: ${profile}/${agent}/${item2.path}`);
|
|
1869
|
+
}
|
|
1870
|
+
files.set(item2.path, bytes);
|
|
1871
|
+
}
|
|
1872
|
+
return { manifest: raw, files };
|
|
1873
|
+
}
|
|
1874
|
+
async function managedBundleTargets(resourcesRoot, profile, agent = "claude-code") {
|
|
1875
|
+
const bundle = await loadAgentBundle(resourcesRoot, profile, agent);
|
|
1876
|
+
const adapter = getAdapter(agent);
|
|
1877
|
+
const context = { profile, codebuddySurface: "both" };
|
|
1878
|
+
const targets = new Set(adapter.projectBundle(bundle, context).map((t) => t.target_path));
|
|
1879
|
+
if (profile === "java" && agent === "claude-code") {
|
|
1880
|
+
targets.add(".claude/rules/harness-profile-java.md");
|
|
1881
|
+
}
|
|
1882
|
+
return targets;
|
|
1883
|
+
}
|
|
1617
1884
|
function parseHarnessProfile(value) {
|
|
1618
1885
|
return isProfile(value) ? value : null;
|
|
1619
1886
|
}
|
|
@@ -1622,21 +1889,25 @@ function parseMigrationManifest(raw) {
|
|
|
1622
1889
|
throw new Error("invalid Harness migration manifest");
|
|
1623
1890
|
}
|
|
1624
1891
|
const record = raw;
|
|
1625
|
-
|
|
1892
|
+
const schemaVersion = record.schema_version;
|
|
1893
|
+
if (schemaVersion !== 1 && schemaVersion !== 2 || !isProfile(record.profile) || typeof record.bundle_version !== "string" || !/^sha256:[a-f0-9]{64}$/.test(String(record.bundle_manifest_hash)) || !Array.isArray(record.projection)) {
|
|
1626
1894
|
throw new Error("invalid Harness migration manifest");
|
|
1627
1895
|
}
|
|
1896
|
+
const adapter = schemaVersion === 1 ? "claude-code" : isAgent(record.adapter) ? record.adapter : (() => {
|
|
1897
|
+
throw new Error("invalid Harness migration manifest adapter");
|
|
1898
|
+
})();
|
|
1628
1899
|
const projection = [];
|
|
1629
1900
|
for (const entry of record.projection) {
|
|
1630
1901
|
if (entry === null || typeof entry !== "object") {
|
|
1631
1902
|
throw new Error("invalid Harness migration manifest entry");
|
|
1632
1903
|
}
|
|
1633
1904
|
const item2 = entry;
|
|
1634
|
-
|
|
1905
|
+
validateRelativeBundlePath2(item2.source_path);
|
|
1635
1906
|
if (typeof item2.target_path !== "string" || typeof item2.sha256 !== "string" || !/^[a-f0-9]{64}$/.test(item2.sha256)) {
|
|
1636
1907
|
throw new Error("invalid Harness migration manifest entry");
|
|
1637
1908
|
}
|
|
1638
1909
|
const targetPath = normalizeManagedPath(item2.target_path);
|
|
1639
|
-
if (!targetPath.startsWith(".claude/")) {
|
|
1910
|
+
if (schemaVersion === 1 && !targetPath.startsWith(".claude/")) {
|
|
1640
1911
|
throw new Error("invalid Harness migration manifest target");
|
|
1641
1912
|
}
|
|
1642
1913
|
projection.push({
|
|
@@ -1647,8 +1918,9 @@ function parseMigrationManifest(raw) {
|
|
|
1647
1918
|
}
|
|
1648
1919
|
assertNoCaseCollisions(projection.map((item2) => item2.target_path));
|
|
1649
1920
|
return {
|
|
1650
|
-
schema_version:
|
|
1921
|
+
schema_version: schemaVersion,
|
|
1651
1922
|
profile: record.profile,
|
|
1923
|
+
adapter,
|
|
1652
1924
|
bundle_version: record.bundle_version,
|
|
1653
1925
|
bundle_manifest_hash: record.bundle_manifest_hash,
|
|
1654
1926
|
projection
|
|
@@ -1697,17 +1969,37 @@ function uuidV7(now = Date.now()) {
|
|
|
1697
1969
|
const byte8 = bytes[8] ?? 0;
|
|
1698
1970
|
bytes[6] = byte6 & 15 | 112;
|
|
1699
1971
|
bytes[8] = byte8 & 63 | 128;
|
|
1700
|
-
const
|
|
1972
|
+
const hex2 = bytes.toString("hex");
|
|
1701
1973
|
return [
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1974
|
+
hex2.slice(0, 8),
|
|
1975
|
+
hex2.slice(8, 12),
|
|
1976
|
+
hex2.slice(12, 16),
|
|
1977
|
+
hex2.slice(16, 20),
|
|
1978
|
+
hex2.slice(20)
|
|
1707
1979
|
].join("-");
|
|
1708
1980
|
}
|
|
1709
1981
|
|
|
1710
1982
|
// ../core/dist/project/initialize.js
|
|
1983
|
+
var TargetCollisionError = class extends Error {
|
|
1984
|
+
code = "TARGET_COLLISION";
|
|
1985
|
+
exitCode = 7;
|
|
1986
|
+
constructor(targetPath) {
|
|
1987
|
+
super(`TARGET_COLLISION: conflicting bytes for ${targetPath}`);
|
|
1988
|
+
this.name = "TargetCollisionError";
|
|
1989
|
+
}
|
|
1990
|
+
};
|
|
1991
|
+
function hex(bytes) {
|
|
1992
|
+
return createHash4("sha256").update(bytes).digest("hex");
|
|
1993
|
+
}
|
|
1994
|
+
function bytesEqual(left, right) {
|
|
1995
|
+
if (left.byteLength !== right.byteLength)
|
|
1996
|
+
return false;
|
|
1997
|
+
for (let i = 0; i < left.byteLength; i += 1) {
|
|
1998
|
+
if (left[i] !== right[i])
|
|
1999
|
+
return false;
|
|
2000
|
+
}
|
|
2001
|
+
return true;
|
|
2002
|
+
}
|
|
1711
2003
|
async function readOptional(path) {
|
|
1712
2004
|
try {
|
|
1713
2005
|
return await readFile4(path, "utf8");
|
|
@@ -1738,14 +2030,76 @@ async function operationFor(root, path, content) {
|
|
|
1738
2030
|
return await exists2(join5(root, path)) ? { operation: "modify", path, content } : { operation: "add", path, content };
|
|
1739
2031
|
}
|
|
1740
2032
|
var INSTALLED_BUNDLE_PATH = ".harness/state/local/installed-harness-bundle.json";
|
|
2033
|
+
function mergeOwnedTargets(owned) {
|
|
2034
|
+
const byTarget = /* @__PURE__ */ new Map();
|
|
2035
|
+
for (const item2 of owned) {
|
|
2036
|
+
const list = byTarget.get(item2.target_path) ?? [];
|
|
2037
|
+
list.push(item2);
|
|
2038
|
+
byTarget.set(item2.target_path, list);
|
|
2039
|
+
}
|
|
2040
|
+
const merged = [];
|
|
2041
|
+
for (const [targetPath, items] of [...byTarget.entries()].sort((a, b) => a[0].localeCompare(b[0]))) {
|
|
2042
|
+
const first = items[0];
|
|
2043
|
+
if (first === void 0) {
|
|
2044
|
+
throw new Error(`missing projected targets for ${targetPath}`);
|
|
2045
|
+
}
|
|
2046
|
+
for (const item2 of items.slice(1)) {
|
|
2047
|
+
if (!bytesEqual(first.bytes, item2.bytes) || first.sha256 !== item2.sha256) {
|
|
2048
|
+
throw new TargetCollisionError(targetPath);
|
|
2049
|
+
}
|
|
2050
|
+
}
|
|
2051
|
+
const owners = new Set(items.map((item2) => item2.owner));
|
|
2052
|
+
merged.push({
|
|
2053
|
+
owner: owners.size === 1 ? first.owner : "shared",
|
|
2054
|
+
source_path: first.source_path,
|
|
2055
|
+
target_path: targetPath,
|
|
2056
|
+
sha256: first.sha256,
|
|
2057
|
+
bytes: first.bytes
|
|
2058
|
+
});
|
|
2059
|
+
}
|
|
2060
|
+
return merged.sort((left, right) => {
|
|
2061
|
+
const byTarget2 = left.target_path.localeCompare(right.target_path);
|
|
2062
|
+
return byTarget2 !== 0 ? byTarget2 : left.source_path.localeCompare(right.source_path);
|
|
2063
|
+
});
|
|
2064
|
+
}
|
|
1741
2065
|
async function initializeProject(options) {
|
|
1742
2066
|
const root = resolve3(options.projectRoot);
|
|
1743
2067
|
const config = initConfigSchema.parse(options.config);
|
|
1744
2068
|
const existing = await existingProjectConfig(root);
|
|
1745
2069
|
const profile = config.profile;
|
|
1746
|
-
const
|
|
1747
|
-
const
|
|
1748
|
-
const
|
|
2070
|
+
const enabledAgents = sortHarnessAgents(config.agents);
|
|
2071
|
+
const surface = config.codebuddy_surface;
|
|
2072
|
+
const adapterContext = { profile, codebuddySurface: surface };
|
|
2073
|
+
const owned = [];
|
|
2074
|
+
const manifests = [];
|
|
2075
|
+
const adaptersIndex = {};
|
|
2076
|
+
const skillBundles = {};
|
|
2077
|
+
let primaryBundleHash = "";
|
|
2078
|
+
let primaryRegistryVersion = "";
|
|
2079
|
+
for (const agent of enabledAgents) {
|
|
2080
|
+
const bundle = await loadAgentBundle(options.resourcesRoot, profile, agent);
|
|
2081
|
+
const adapter = getAdapter(agent);
|
|
2082
|
+
const targets = managedTargetsFor(adapter, bundle, adapterContext);
|
|
2083
|
+
const bundleHash = sha256Bytes(canonicalJson(bundle.manifest.files));
|
|
2084
|
+
if (primaryBundleHash === "") {
|
|
2085
|
+
primaryBundleHash = bundleHash;
|
|
2086
|
+
primaryRegistryVersion = bundle.manifest.bundle_version;
|
|
2087
|
+
}
|
|
2088
|
+
manifests.push({
|
|
2089
|
+
adapter: agent,
|
|
2090
|
+
bundle_version: bundle.manifest.bundle_version,
|
|
2091
|
+
bundle_manifest_hash: bundleHash
|
|
2092
|
+
});
|
|
2093
|
+
skillBundles[agent] = {
|
|
2094
|
+
registry_version: bundle.manifest.bundle_version,
|
|
2095
|
+
bundle_hash: bundleHash
|
|
2096
|
+
};
|
|
2097
|
+
adaptersIndex[agent] = adapter.contextIndex(adapterContext);
|
|
2098
|
+
for (const target of targets) {
|
|
2099
|
+
owned.push({ ...target, owner: agent });
|
|
2100
|
+
}
|
|
2101
|
+
}
|
|
2102
|
+
const mergedTargets = mergeOwnedTargets(owned);
|
|
1749
2103
|
const projectConfig = projectConfigSchema.parse({
|
|
1750
2104
|
harness: { name: "hunter-harness", schema_version: 1 },
|
|
1751
2105
|
project: {
|
|
@@ -1759,7 +2113,8 @@ async function initializeProject(options) {
|
|
|
1759
2113
|
url: config.server_url ?? existing?.server.url ?? null,
|
|
1760
2114
|
token_env: config.token_env ?? existing?.server.token_env ?? "HUNTER_HARNESS_TOKEN"
|
|
1761
2115
|
},
|
|
1762
|
-
adapters: { enabled:
|
|
2116
|
+
adapters: { enabled: enabledAgents },
|
|
2117
|
+
...enabledAgents.includes("codebuddy") ? { adapter_options: { codebuddy: { surface: config.codebuddy_surface } } } : {}
|
|
1763
2118
|
});
|
|
1764
2119
|
const baseline = baselineManifestSchema.parse({
|
|
1765
2120
|
schema_version: 1,
|
|
@@ -1768,8 +2123,15 @@ async function initializeProject(options) {
|
|
|
1768
2123
|
artifact_manifest_hash: null,
|
|
1769
2124
|
files: {}
|
|
1770
2125
|
});
|
|
1771
|
-
const
|
|
1772
|
-
|
|
2126
|
+
const managedBlocks = [];
|
|
2127
|
+
let agentsContent = await readOptional(join5(root, "AGENTS.md"));
|
|
2128
|
+
agentsContent = upsertManagedBlockById(agentsContent, AGENTS_CORE_BLOCK_ID, AGENTS_MANAGED_BLOCK_CONTENT);
|
|
2129
|
+
managedBlocks.push({
|
|
2130
|
+
owner: "shared",
|
|
2131
|
+
target_path: "AGENTS.md",
|
|
2132
|
+
block_id: AGENTS_CORE_BLOCK_ID,
|
|
2133
|
+
content_sha256: hex(AGENTS_MANAGED_BLOCK_CONTENT)
|
|
2134
|
+
});
|
|
1773
2135
|
const files = /* @__PURE__ */ new Map([
|
|
1774
2136
|
[
|
|
1775
2137
|
".harness/project.yaml",
|
|
@@ -1782,38 +2144,64 @@ async function initializeProject(options) {
|
|
|
1782
2144
|
[
|
|
1783
2145
|
".harness/context-index.json",
|
|
1784
2146
|
JSON.stringify({
|
|
1785
|
-
schema_version:
|
|
1786
|
-
project: {
|
|
1787
|
-
|
|
2147
|
+
schema_version: 2,
|
|
2148
|
+
project: {
|
|
2149
|
+
shared_instructions: "AGENTS.md",
|
|
2150
|
+
adapters: adaptersIndex
|
|
2151
|
+
},
|
|
1788
2152
|
knowledge: { index: ".harness/knowledge/index.json" },
|
|
1789
2153
|
codebase: { map: ".harness/codebase/map", status: "missing" },
|
|
1790
|
-
|
|
1791
|
-
registry_version: bundle.manifest.bundle_version,
|
|
1792
|
-
bundle_hash: bundleHash
|
|
1793
|
-
}
|
|
2154
|
+
skill_bundles: skillBundles
|
|
1794
2155
|
}, null, 2) + "\n"
|
|
1795
2156
|
],
|
|
1796
2157
|
[
|
|
1797
2158
|
".harness/knowledge/index.json",
|
|
1798
2159
|
JSON.stringify({ schema_version: 1, generated_at: null, entries: [] }, null, 2) + "\n"
|
|
1799
2160
|
],
|
|
1800
|
-
["AGENTS.md", agentsContent]
|
|
1801
|
-
["CLAUDE.md", claudeContent]
|
|
2161
|
+
["AGENTS.md", agentsContent]
|
|
1802
2162
|
]);
|
|
1803
|
-
|
|
2163
|
+
if (enabledAgents.includes("claude-code")) {
|
|
2164
|
+
let claudeContent = await readOptional(join5(root, "CLAUDE.md"));
|
|
2165
|
+
claudeContent = upsertManagedBlockById(claudeContent, CLAUDE_BLOCK_ID, CLAUDE_MANAGED_BLOCK_CONTENT);
|
|
2166
|
+
files.set("CLAUDE.md", claudeContent);
|
|
2167
|
+
managedBlocks.push({
|
|
2168
|
+
owner: "claude-code",
|
|
2169
|
+
target_path: "CLAUDE.md",
|
|
2170
|
+
block_id: CLAUDE_BLOCK_ID,
|
|
2171
|
+
content_sha256: hex(CLAUDE_MANAGED_BLOCK_CONTENT)
|
|
2172
|
+
});
|
|
2173
|
+
}
|
|
2174
|
+
if (enabledAgents.includes("codebuddy")) {
|
|
2175
|
+
let codebuddyContent = await readOptional(join5(root, "CODEBUDDY.md"));
|
|
2176
|
+
codebuddyContent = upsertManagedBlockById(codebuddyContent, CODEBUDDY_BLOCK_ID, CODEBUDDY_MANAGED_BLOCK_CONTENT);
|
|
2177
|
+
files.set("CODEBUDDY.md", codebuddyContent);
|
|
2178
|
+
managedBlocks.push({
|
|
2179
|
+
owner: "codebuddy",
|
|
2180
|
+
target_path: "CODEBUDDY.md",
|
|
2181
|
+
block_id: CODEBUDDY_BLOCK_ID,
|
|
2182
|
+
content_sha256: hex(CODEBUDDY_MANAGED_BLOCK_CONTENT)
|
|
2183
|
+
});
|
|
2184
|
+
}
|
|
2185
|
+
for (const target of mergedTargets) {
|
|
1804
2186
|
files.set(target.target_path, target.bytes);
|
|
1805
2187
|
}
|
|
2188
|
+
managedBlocks.sort((left, right) => {
|
|
2189
|
+
const byTarget = left.target_path.localeCompare(right.target_path);
|
|
2190
|
+
return byTarget !== 0 ? byTarget : left.block_id.localeCompare(right.block_id);
|
|
2191
|
+
});
|
|
1806
2192
|
const installedState = {
|
|
1807
|
-
schema_version:
|
|
2193
|
+
schema_version: 3,
|
|
1808
2194
|
profile,
|
|
1809
|
-
|
|
1810
|
-
bundle_manifest_hash: bundleHash,
|
|
2195
|
+
adapters: enabledAgents,
|
|
1811
2196
|
installed_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1812
|
-
|
|
2197
|
+
manifests,
|
|
2198
|
+
files: mergedTargets.map((target) => ({
|
|
2199
|
+
owner: target.owner,
|
|
1813
2200
|
source_path: target.source_path,
|
|
1814
2201
|
target_path: target.target_path,
|
|
1815
2202
|
sha256: target.sha256
|
|
1816
|
-
}))
|
|
2203
|
+
})),
|
|
2204
|
+
managed_blocks: managedBlocks
|
|
1817
2205
|
};
|
|
1818
2206
|
files.set(INSTALLED_BUNDLE_PATH, JSON.stringify(installedState, null, 2) + "\n");
|
|
1819
2207
|
const paths = [...files.keys()].sort((left, right) => left.localeCompare(right));
|
|
@@ -1824,32 +2212,21 @@ async function initializeProject(options) {
|
|
|
1824
2212
|
return {
|
|
1825
2213
|
projectConfig,
|
|
1826
2214
|
paths,
|
|
1827
|
-
bundleHash,
|
|
1828
|
-
registryVersion:
|
|
2215
|
+
bundleHash: primaryBundleHash,
|
|
2216
|
+
registryVersion: primaryRegistryVersion
|
|
1829
2217
|
};
|
|
1830
2218
|
}
|
|
1831
2219
|
|
|
1832
2220
|
// ../core/dist/project/refresh.js
|
|
1833
|
-
import { createHash as
|
|
1834
|
-
import { readFile as readFile5, readdir as readdir3, rmdir
|
|
2221
|
+
import { createHash as createHash5 } from "node:crypto";
|
|
2222
|
+
import { readFile as readFile5, readdir as readdir3, rmdir } from "node:fs/promises";
|
|
1835
2223
|
import { dirname as dirname3, join as join6, resolve as resolve4 } from "node:path";
|
|
1836
2224
|
import { parse as parseYaml3, stringify as stringifyYaml2 } from "yaml";
|
|
1837
2225
|
var INSTALLED_STATE_PATH = ".harness/state/local/installed-harness-bundle.json";
|
|
1838
2226
|
var CONTEXT_INDEX_PATH = ".harness/context-index.json";
|
|
1839
|
-
async function exists3(path) {
|
|
1840
|
-
try {
|
|
1841
|
-
await stat3(path);
|
|
1842
|
-
return true;
|
|
1843
|
-
} catch (error) {
|
|
1844
|
-
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
1845
|
-
return false;
|
|
1846
|
-
}
|
|
1847
|
-
throw error;
|
|
1848
|
-
}
|
|
1849
|
-
}
|
|
1850
2227
|
async function fileHex(path) {
|
|
1851
2228
|
try {
|
|
1852
|
-
return
|
|
2229
|
+
return createHash5("sha256").update(await readFile5(path)).digest("hex");
|
|
1853
2230
|
} catch (error) {
|
|
1854
2231
|
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
1855
2232
|
return null;
|
|
@@ -1870,17 +2247,17 @@ async function readOptionalText(path) {
|
|
|
1870
2247
|
async function readInstalledState(root) {
|
|
1871
2248
|
const content = await readOptionalText(join6(root, INSTALLED_STATE_PATH));
|
|
1872
2249
|
if (content === "") {
|
|
1873
|
-
return { profile: null, schemaVersion: null, trusted: /* @__PURE__ */ new Map() };
|
|
2250
|
+
return { profile: null, schemaVersion: null, adapters: [], trusted: /* @__PURE__ */ new Map() };
|
|
1874
2251
|
}
|
|
1875
2252
|
let parsed;
|
|
1876
2253
|
try {
|
|
1877
2254
|
parsed = JSON.parse(content);
|
|
1878
2255
|
} catch {
|
|
1879
|
-
return { profile: null, schemaVersion: null, trusted: /* @__PURE__ */ new Map() };
|
|
2256
|
+
return { profile: null, schemaVersion: null, adapters: [], trusted: /* @__PURE__ */ new Map() };
|
|
1880
2257
|
}
|
|
1881
2258
|
const profile = parseHarnessProfile(parsed.profile);
|
|
1882
2259
|
const trusted = /* @__PURE__ */ new Map();
|
|
1883
|
-
if (parsed.schema_version === 2 && Array.isArray(parsed.files)) {
|
|
2260
|
+
if ((parsed.schema_version === 2 || parsed.schema_version === 3) && Array.isArray(parsed.files)) {
|
|
1884
2261
|
for (const entry of parsed.files) {
|
|
1885
2262
|
if (entry !== null && typeof entry === "object" && "target_path" in entry && "sha256" in entry) {
|
|
1886
2263
|
const target = entry.target_path;
|
|
@@ -1891,7 +2268,9 @@ async function readInstalledState(root) {
|
|
|
1891
2268
|
}
|
|
1892
2269
|
}
|
|
1893
2270
|
}
|
|
1894
|
-
|
|
2271
|
+
const schemaVersion = typeof parsed.schema_version === "number" ? parsed.schema_version : null;
|
|
2272
|
+
const adapters = schemaVersion === 3 && Array.isArray(parsed.adapters) ? sortHarnessAgents(parsed.adapters.filter((value) => value === "claude-code" || value === "codex" || value === "cursor" || value === "codebuddy")) : schemaVersion === 1 || schemaVersion === 2 ? ["claude-code"] : [];
|
|
2273
|
+
return { profile, schemaVersion, adapters, trusted };
|
|
1895
2274
|
}
|
|
1896
2275
|
async function readContextIndexBundleHash(root) {
|
|
1897
2276
|
const content = await readOptionalText(join6(root, CONTEXT_INDEX_PATH));
|
|
@@ -1905,16 +2284,11 @@ async function readContextIndexBundleHash(root) {
|
|
|
1905
2284
|
return null;
|
|
1906
2285
|
}
|
|
1907
2286
|
}
|
|
1908
|
-
async function pruneEmptyParentDirs(root, deletedPaths) {
|
|
1909
|
-
const
|
|
1910
|
-
const boundaries = /* @__PURE__ */ new Set([
|
|
1911
|
-
claudeRoot,
|
|
1912
|
-
join6(claudeRoot, "skills"),
|
|
1913
|
-
join6(claudeRoot, "agents")
|
|
1914
|
-
]);
|
|
2287
|
+
async function pruneEmptyParentDirs(root, deletedPaths, boundaryPaths) {
|
|
2288
|
+
const boundaries = new Set(boundaryPaths.map((path) => join6(root, path)));
|
|
1915
2289
|
for (const deleted of deletedPaths) {
|
|
1916
2290
|
let dir = dirname3(join6(root, deleted));
|
|
1917
|
-
while (dir.startsWith(
|
|
2291
|
+
while (dir.startsWith(root) && !boundaries.has(dir)) {
|
|
1918
2292
|
let entries;
|
|
1919
2293
|
try {
|
|
1920
2294
|
entries = await readdir3(dir);
|
|
@@ -1954,82 +2328,130 @@ function conflict(target, reason, oldSha, incomingSha) {
|
|
|
1954
2328
|
function sortByTarget(items) {
|
|
1955
2329
|
return [...items].sort((left, right) => left.target_path.localeCompare(right.target_path));
|
|
1956
2330
|
}
|
|
1957
|
-
async function
|
|
1958
|
-
const original = await readOptionalText(join6(root, fileName));
|
|
1959
|
-
const current = original === "" ? null : createHash3("sha256").update(original).digest("hex");
|
|
1960
|
-
const refresh = refreshManagedBlock(original, blockContent);
|
|
1961
|
-
const synthetic = {
|
|
1962
|
-
source_path: fileName,
|
|
1963
|
-
target_path: fileName,
|
|
1964
|
-
sha256: createHash3("sha256").update(blockContent).digest("hex"),
|
|
1965
|
-
bytes: new TextEncoder().encode(blockContent)
|
|
1966
|
-
};
|
|
1967
|
-
if (refresh.conflict) {
|
|
1968
|
-
preserved.push(item(synthetic, "preserve", "MALFORMED_MANAGED_BLOCK", current, synthetic.sha256));
|
|
1969
|
-
conflicts.push(conflict(synthetic, "MALFORMED_MANAGED_BLOCK", current, synthetic.sha256));
|
|
1970
|
-
return;
|
|
1971
|
-
}
|
|
1972
|
-
if (refresh.content === original) {
|
|
1973
|
-
return;
|
|
1974
|
-
}
|
|
1975
|
-
ops.push({
|
|
1976
|
-
operation: original === "" ? "add" : "modify",
|
|
1977
|
-
path: fileName,
|
|
1978
|
-
content: refresh.content
|
|
1979
|
-
});
|
|
1980
|
-
}
|
|
1981
|
-
async function reconcileContextIndex(root, bundleVersion, bundleManifestHash) {
|
|
2331
|
+
async function reconcileContextIndex(root, profile, agents, manifests, codebuddySurface2) {
|
|
1982
2332
|
const existing = await readOptionalText(join6(root, CONTEXT_INDEX_PATH));
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
}
|
|
2000
|
-
record.skill_bundle = {
|
|
2001
|
-
registry_version: bundleVersion,
|
|
2002
|
-
bundle_hash: bundleManifestHash
|
|
2333
|
+
const context = { profile, codebuddySurface: codebuddySurface2 };
|
|
2334
|
+
const record = {
|
|
2335
|
+
schema_version: 2,
|
|
2336
|
+
project: {
|
|
2337
|
+
shared_instructions: "AGENTS.md",
|
|
2338
|
+
adapters: Object.fromEntries(agents.map((agent) => [
|
|
2339
|
+
agent,
|
|
2340
|
+
getAdapter(agent).contextIndex(context)
|
|
2341
|
+
]))
|
|
2342
|
+
},
|
|
2343
|
+
knowledge: { index: ".harness/knowledge/index.json" },
|
|
2344
|
+
codebase: { map: ".harness/codebase/map", status: "missing" },
|
|
2345
|
+
skill_bundles: Object.fromEntries(manifests.map((manifest) => [
|
|
2346
|
+
manifest.adapter,
|
|
2347
|
+
{ registry_version: manifest.bundle_version, bundle_hash: manifest.bundle_manifest_hash }
|
|
2348
|
+
]))
|
|
2003
2349
|
};
|
|
2350
|
+
const next = JSON.stringify(record, null, 2) + "\n";
|
|
2351
|
+
if (existing === next)
|
|
2352
|
+
return null;
|
|
2004
2353
|
return {
|
|
2005
2354
|
operation: existing === "" ? "add" : "modify",
|
|
2006
2355
|
path: CONTEXT_INDEX_PATH,
|
|
2007
|
-
content:
|
|
2356
|
+
content: next
|
|
2008
2357
|
};
|
|
2009
2358
|
}
|
|
2010
|
-
async function
|
|
2011
|
-
if (previousProfile ===
|
|
2359
|
+
async function projectTransitionOperation(root, previousProfile, profile, oldAgents, agents, codebuddySurface2) {
|
|
2360
|
+
if (previousProfile === profile && oldAgents.length === agents.length && oldAgents.every((agent, index) => agent === agents[index]))
|
|
2012
2361
|
return null;
|
|
2013
2362
|
const path = ".harness/project.yaml";
|
|
2014
2363
|
const content = await readOptionalText(join6(root, path));
|
|
2015
|
-
|
|
2364
|
+
if (content === "")
|
|
2365
|
+
return null;
|
|
2366
|
+
const project = parseYaml3(content);
|
|
2016
2367
|
return {
|
|
2017
2368
|
operation: "modify",
|
|
2018
2369
|
path,
|
|
2019
2370
|
content: stringifyYaml2({
|
|
2020
2371
|
...project,
|
|
2021
|
-
project: { ...project.project, profiles: [profile] }
|
|
2372
|
+
project: { ...project.project, profiles: [profile] },
|
|
2373
|
+
adapters: { enabled: agents },
|
|
2374
|
+
...agents.includes("codebuddy") ? { adapter_options: { codebuddy: { surface: codebuddySurface2 } } } : { adapter_options: void 0 }
|
|
2022
2375
|
}, { sortMapEntries: true })
|
|
2023
2376
|
};
|
|
2024
2377
|
}
|
|
2378
|
+
function mergeTargets(targets) {
|
|
2379
|
+
const grouped = /* @__PURE__ */ new Map();
|
|
2380
|
+
for (const target of targets) {
|
|
2381
|
+
grouped.set(target.target_path, [...grouped.get(target.target_path) ?? [], target]);
|
|
2382
|
+
}
|
|
2383
|
+
return [...grouped.entries()].map(([path, values]) => {
|
|
2384
|
+
const first = values[0];
|
|
2385
|
+
if (first === void 0)
|
|
2386
|
+
throw new TargetCollisionError(path);
|
|
2387
|
+
if (values.some((value) => value.sha256 !== first.sha256))
|
|
2388
|
+
throw new TargetCollisionError(path);
|
|
2389
|
+
const owner = new Set(values.map((value) => value.owner)).size === 1 ? first.owner : "shared";
|
|
2390
|
+
return { ...first, owner };
|
|
2391
|
+
}).sort((left, right) => left.target_path.localeCompare(right.target_path));
|
|
2392
|
+
}
|
|
2393
|
+
async function reconcileMarkdownBlock(root, fileName, blockId, content, remove, ops, conflicts, preserved) {
|
|
2394
|
+
const original = await readOptionalText(join6(root, fileName));
|
|
2395
|
+
const synthetic = {
|
|
2396
|
+
source_path: fileName,
|
|
2397
|
+
target_path: fileName,
|
|
2398
|
+
sha256: createHash5("sha256").update(content).digest("hex"),
|
|
2399
|
+
bytes: new TextEncoder().encode(content)
|
|
2400
|
+
};
|
|
2401
|
+
let next;
|
|
2402
|
+
try {
|
|
2403
|
+
if (remove) {
|
|
2404
|
+
const hasId = original.includes(`<!-- hunter-harness:start id=${blockId} -->`);
|
|
2405
|
+
next = hasId ? removeManagedBlockById(original, blockId) : removeManagedBlock(original);
|
|
2406
|
+
} else {
|
|
2407
|
+
const refreshed = refreshManagedBlockById(original, blockId, content, { upgradeLegacy: true });
|
|
2408
|
+
if (refreshed.conflict)
|
|
2409
|
+
throw new Error("managed block conflict");
|
|
2410
|
+
next = refreshed.content;
|
|
2411
|
+
}
|
|
2412
|
+
} catch {
|
|
2413
|
+
const current = original === "" ? null : createHash5("sha256").update(original).digest("hex");
|
|
2414
|
+
preserved.push(item(synthetic, "preserve", "MALFORMED_MANAGED_BLOCK", current, synthetic.sha256));
|
|
2415
|
+
conflicts.push(conflict(synthetic, "MALFORMED_MANAGED_BLOCK", current, synthetic.sha256));
|
|
2416
|
+
return;
|
|
2417
|
+
}
|
|
2418
|
+
if (next !== original)
|
|
2419
|
+
ops.push({
|
|
2420
|
+
operation: original === "" ? "add" : "modify",
|
|
2421
|
+
path: fileName,
|
|
2422
|
+
content: next
|
|
2423
|
+
});
|
|
2424
|
+
}
|
|
2425
|
+
function stateWithoutInstalledAt(value) {
|
|
2426
|
+
if (value === null || typeof value !== "object" || Array.isArray(value))
|
|
2427
|
+
return value;
|
|
2428
|
+
const copy = { ...value };
|
|
2429
|
+
delete copy.installed_at;
|
|
2430
|
+
return copy;
|
|
2431
|
+
}
|
|
2025
2432
|
async function refreshProject(options) {
|
|
2026
2433
|
const root = resolve4(options.projectRoot);
|
|
2027
2434
|
const profile = options.profile;
|
|
2028
|
-
const newManaged = await managedTargets(options.resourcesRoot, profile);
|
|
2029
|
-
const newBundle = await loadProfileBundle(options.resourcesRoot, profile);
|
|
2030
|
-
const bundleManifestHash = sha256Bytes(canonicalJson(newBundle.manifest.files));
|
|
2031
2435
|
const installed = await readInstalledState(root);
|
|
2032
2436
|
const previousProfile = installed.profile;
|
|
2437
|
+
const agents = sortHarnessAgents(options.agents);
|
|
2438
|
+
const oldAgents = installed.adapters.length > 0 ? installed.adapters : ["claude-code"];
|
|
2439
|
+
const codebuddySurface2 = options.codebuddySurface ?? "both";
|
|
2440
|
+
const context = { profile, codebuddySurface: codebuddySurface2 };
|
|
2441
|
+
const owned = [];
|
|
2442
|
+
const manifests = [];
|
|
2443
|
+
for (const agent of agents) {
|
|
2444
|
+
const bundle = await loadAgentBundle(options.resourcesRoot, profile, agent);
|
|
2445
|
+
manifests.push({
|
|
2446
|
+
adapter: agent,
|
|
2447
|
+
bundle_version: bundle.manifest.bundle_version,
|
|
2448
|
+
bundle_manifest_hash: sha256Bytes(canonicalJson(bundle.manifest.files))
|
|
2449
|
+
});
|
|
2450
|
+
for (const target of managedTargetsFor(getAdapter(agent), bundle, context)) {
|
|
2451
|
+
owned.push({ ...target, owner: agent });
|
|
2452
|
+
}
|
|
2453
|
+
}
|
|
2454
|
+
const newManaged = mergeTargets(owned);
|
|
2033
2455
|
let trusted = installed.trusted;
|
|
2034
2456
|
let migrationOldPaths = null;
|
|
2035
2457
|
if (installed.schemaVersion === 1) {
|
|
@@ -2056,9 +2478,14 @@ async function refreshProject(options) {
|
|
|
2056
2478
|
});
|
|
2057
2479
|
}
|
|
2058
2480
|
}
|
|
2059
|
-
} else if (previousProfile !== null
|
|
2060
|
-
const
|
|
2061
|
-
|
|
2481
|
+
} else if (previousProfile !== null) {
|
|
2482
|
+
const oldContext = { profile: previousProfile, codebuddySurface: codebuddySurface2 };
|
|
2483
|
+
const oldTargets = [];
|
|
2484
|
+
for (const agent of oldAgents) {
|
|
2485
|
+
const bundle = await loadAgentBundle(options.resourcesRoot, previousProfile, agent);
|
|
2486
|
+
oldTargets.push(...managedTargetsFor(getAdapter(agent), bundle, oldContext));
|
|
2487
|
+
}
|
|
2488
|
+
oldOnly = oldTargets.filter((target) => !newTargetSet.has(target.target_path));
|
|
2062
2489
|
}
|
|
2063
2490
|
const applied = [];
|
|
2064
2491
|
const removed = [];
|
|
@@ -2073,12 +2500,12 @@ async function refreshProject(options) {
|
|
|
2073
2500
|
if (current === null) {
|
|
2074
2501
|
applied.push(item(target, "add", "MISSING_TARGET", null, incoming));
|
|
2075
2502
|
ops.push({ operation: "add", path: target.target_path, content: target.bytes });
|
|
2076
|
-
newStateFiles.push({ source_path: target.source_path, target_path: target.target_path, sha256: incoming });
|
|
2503
|
+
newStateFiles.push({ owner: target.owner, source_path: target.source_path, target_path: target.target_path, sha256: incoming });
|
|
2077
2504
|
continue;
|
|
2078
2505
|
}
|
|
2079
2506
|
if (current === incoming) {
|
|
2080
2507
|
unchanged.push(item(target, "unchanged", "ALREADY_CURRENT", current, incoming));
|
|
2081
|
-
newStateFiles.push({ source_path: target.source_path, target_path: target.target_path, sha256: incoming });
|
|
2508
|
+
newStateFiles.push({ owner: target.owner, source_path: target.source_path, target_path: target.target_path, sha256: incoming });
|
|
2082
2509
|
continue;
|
|
2083
2510
|
}
|
|
2084
2511
|
const trustedHash = trusted.get(target.target_path);
|
|
@@ -2086,13 +2513,13 @@ async function refreshProject(options) {
|
|
|
2086
2513
|
const reason = options.forceManaged ? "FORCE_MANAGED" : "BASELINE_CLEAN";
|
|
2087
2514
|
applied.push(item(target, "replace", reason, current, incoming));
|
|
2088
2515
|
ops.push({ operation: "modify", path: target.target_path, content: target.bytes });
|
|
2089
|
-
newStateFiles.push({ source_path: target.source_path, target_path: target.target_path, sha256: incoming });
|
|
2516
|
+
newStateFiles.push({ owner: target.owner, source_path: target.source_path, target_path: target.target_path, sha256: incoming });
|
|
2090
2517
|
} else {
|
|
2091
2518
|
const reason = trustedHash === void 0 ? "LEGACY_BASELINE_UNKNOWN" : "LOCAL_MODIFICATION";
|
|
2092
2519
|
preserved.push(item(target, "preserve", reason, current, incoming));
|
|
2093
2520
|
conflicts.push(conflict(target, reason, current, incoming));
|
|
2094
2521
|
if (trustedHash !== void 0) {
|
|
2095
|
-
newStateFiles.push({ source_path: target.source_path, target_path: target.target_path, sha256: trustedHash });
|
|
2522
|
+
newStateFiles.push({ owner: target.owner, source_path: target.source_path, target_path: target.target_path, sha256: trustedHash });
|
|
2096
2523
|
}
|
|
2097
2524
|
}
|
|
2098
2525
|
}
|
|
@@ -2101,7 +2528,7 @@ async function refreshProject(options) {
|
|
|
2101
2528
|
if (current === null) {
|
|
2102
2529
|
continue;
|
|
2103
2530
|
}
|
|
2104
|
-
const trustedHash =
|
|
2531
|
+
const trustedHash = target.sha256 !== "" ? target.sha256 : void 0;
|
|
2105
2532
|
const clean = trustedHash !== void 0 && current === trustedHash;
|
|
2106
2533
|
if (clean || options.forceManaged) {
|
|
2107
2534
|
const reason = clean ? "BASELINE_CLEAN" : "FORCE_MANAGED";
|
|
@@ -2113,28 +2540,60 @@ async function refreshProject(options) {
|
|
|
2113
2540
|
conflicts.push(conflict(target, reason, current, null));
|
|
2114
2541
|
}
|
|
2115
2542
|
}
|
|
2116
|
-
await
|
|
2117
|
-
await
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2543
|
+
await reconcileMarkdownBlock(root, "AGENTS.md", AGENTS_CORE_BLOCK_ID, AGENTS_MANAGED_BLOCK_CONTENT, false, ops, conflicts, preserved);
|
|
2544
|
+
await reconcileMarkdownBlock(root, "CLAUDE.md", CLAUDE_BLOCK_ID, CLAUDE_MANAGED_BLOCK_CONTENT, !agents.includes("claude-code"), ops, conflicts, preserved);
|
|
2545
|
+
await reconcileMarkdownBlock(root, "CODEBUDDY.md", CODEBUDDY_BLOCK_ID, CODEBUDDY_MANAGED_BLOCK_CONTENT, !agents.includes("codebuddy"), ops, conflicts, preserved);
|
|
2546
|
+
const projectOperation = await projectTransitionOperation(root, previousProfile, profile, oldAgents, agents, codebuddySurface2);
|
|
2547
|
+
if (projectOperation !== null)
|
|
2548
|
+
ops.push(projectOperation);
|
|
2549
|
+
const contextOperation = await reconcileContextIndex(root, profile, agents, manifests, codebuddySurface2);
|
|
2550
|
+
if (contextOperation !== null)
|
|
2551
|
+
ops.push(contextOperation);
|
|
2552
|
+
const managedBlocks = [
|
|
2553
|
+
{
|
|
2554
|
+
owner: "shared",
|
|
2555
|
+
target_path: "AGENTS.md",
|
|
2556
|
+
block_id: AGENTS_CORE_BLOCK_ID,
|
|
2557
|
+
content_sha256: createHash5("sha256").update(AGENTS_MANAGED_BLOCK_CONTENT).digest("hex")
|
|
2558
|
+
},
|
|
2559
|
+
...agents.includes("claude-code") ? [{
|
|
2560
|
+
owner: "claude-code",
|
|
2561
|
+
target_path: "CLAUDE.md",
|
|
2562
|
+
block_id: CLAUDE_BLOCK_ID,
|
|
2563
|
+
content_sha256: createHash5("sha256").update(CLAUDE_MANAGED_BLOCK_CONTENT).digest("hex")
|
|
2564
|
+
}] : [],
|
|
2565
|
+
...agents.includes("codebuddy") ? [{
|
|
2566
|
+
owner: "codebuddy",
|
|
2567
|
+
target_path: "CODEBUDDY.md",
|
|
2568
|
+
block_id: CODEBUDDY_BLOCK_ID,
|
|
2569
|
+
content_sha256: createHash5("sha256").update(CODEBUDDY_MANAGED_BLOCK_CONTENT).digest("hex")
|
|
2570
|
+
}] : []
|
|
2571
|
+
].sort((left, right) => left.target_path.localeCompare(right.target_path) || left.block_id.localeCompare(right.block_id));
|
|
2122
2572
|
const installedState = {
|
|
2123
|
-
schema_version:
|
|
2573
|
+
schema_version: 3,
|
|
2124
2574
|
profile,
|
|
2125
|
-
|
|
2126
|
-
bundle_manifest_hash: bundleManifestHash,
|
|
2575
|
+
adapters: agents,
|
|
2127
2576
|
installed_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2128
|
-
|
|
2577
|
+
manifests,
|
|
2578
|
+
files: newStateFiles.sort((left, right) => left.target_path.localeCompare(right.target_path) || left.source_path.localeCompare(right.source_path)),
|
|
2579
|
+
managed_blocks: managedBlocks
|
|
2129
2580
|
};
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
}
|
|
2581
|
+
const existingState = await readOptionalText(join6(root, INSTALLED_STATE_PATH));
|
|
2582
|
+
let existingParsed = null;
|
|
2583
|
+
try {
|
|
2584
|
+
existingParsed = existingState === "" ? null : JSON.parse(existingState);
|
|
2585
|
+
} catch {
|
|
2586
|
+
}
|
|
2587
|
+
if (JSON.stringify(stateWithoutInstalledAt(existingParsed)) !== JSON.stringify(stateWithoutInstalledAt(installedState))) {
|
|
2588
|
+
ops.push({
|
|
2589
|
+
operation: existingState === "" ? "add" : "modify",
|
|
2590
|
+
path: INSTALLED_STATE_PATH,
|
|
2591
|
+
content: JSON.stringify(installedState, null, 2) + "\n"
|
|
2592
|
+
});
|
|
2593
|
+
}
|
|
2135
2594
|
if (!options.dryRun) {
|
|
2136
2595
|
await runTransaction(root, ops, { kind: "refresh" });
|
|
2137
|
-
await pruneEmptyParentDirs(root, removed.map((item2) => item2.target_path));
|
|
2596
|
+
await pruneEmptyParentDirs(root, removed.map((item2) => item2.target_path), getAdapters([.../* @__PURE__ */ new Set([...agents, ...oldAgents])]).flatMap((adapter) => adapter.pruneBoundaries(context)));
|
|
2138
2597
|
}
|
|
2139
2598
|
return {
|
|
2140
2599
|
profile,
|
|
@@ -2519,18 +2978,16 @@ var PushWorkflowError = class extends Error {
|
|
|
2519
2978
|
this.code = code;
|
|
2520
2979
|
}
|
|
2521
2980
|
};
|
|
2522
|
-
var
|
|
2523
|
-
".claude/rules",
|
|
2981
|
+
var SHARED_MANAGED_ROOTS = [
|
|
2524
2982
|
".harness/knowledge",
|
|
2525
2983
|
".harness/codebase"
|
|
2526
2984
|
];
|
|
2527
|
-
var
|
|
2528
|
-
"CLAUDE.md",
|
|
2985
|
+
var SHARED_MANAGED_FILES = [
|
|
2529
2986
|
"AGENTS.md",
|
|
2530
2987
|
".harness/project.yaml",
|
|
2531
2988
|
".harness/context-index.json"
|
|
2532
2989
|
];
|
|
2533
|
-
async function
|
|
2990
|
+
async function exists3(path) {
|
|
2534
2991
|
try {
|
|
2535
2992
|
await lstat2(path);
|
|
2536
2993
|
return true;
|
|
@@ -2542,7 +2999,7 @@ async function exists4(path) {
|
|
|
2542
2999
|
}
|
|
2543
3000
|
}
|
|
2544
3001
|
async function walkFiles(root, current, output) {
|
|
2545
|
-
if (!await
|
|
3002
|
+
if (!await exists3(current)) {
|
|
2546
3003
|
return;
|
|
2547
3004
|
}
|
|
2548
3005
|
for (const item2 of await readdir4(current, { withFileTypes: true })) {
|
|
@@ -2557,23 +3014,50 @@ async function walkFiles(root, current, output) {
|
|
|
2557
3014
|
}
|
|
2558
3015
|
}
|
|
2559
3016
|
}
|
|
2560
|
-
|
|
3017
|
+
function enabledHarnessAgents(project) {
|
|
3018
|
+
return project.adapters.enabled.flatMap((agent) => {
|
|
3019
|
+
const parsed = harnessAgentSchema.safeParse(agent);
|
|
3020
|
+
return parsed.success ? [parsed.data] : [];
|
|
3021
|
+
});
|
|
3022
|
+
}
|
|
3023
|
+
async function walkHarnessEntries(root, directory, output) {
|
|
3024
|
+
if (!await exists3(directory))
|
|
3025
|
+
return;
|
|
3026
|
+
for (const item2 of await readdir4(directory, { withFileTypes: true })) {
|
|
3027
|
+
if (item2.name.startsWith("harness-")) {
|
|
3028
|
+
const path = join9(directory, item2.name);
|
|
3029
|
+
if (item2.isDirectory()) {
|
|
3030
|
+
await walkFiles(root, path, output);
|
|
3031
|
+
} else if (item2.isFile()) {
|
|
3032
|
+
output.push(normalizeManagedPath(relative(root, path).replaceAll("\\", "/")));
|
|
3033
|
+
}
|
|
3034
|
+
}
|
|
3035
|
+
}
|
|
3036
|
+
}
|
|
3037
|
+
async function managedFiles(projectRoot, project) {
|
|
2561
3038
|
const root = resolve5(projectRoot);
|
|
2562
3039
|
const paths = [];
|
|
2563
|
-
|
|
2564
|
-
|
|
3040
|
+
const adapters = getAdapters(enabledHarnessAgents(project));
|
|
3041
|
+
const managedFiles2 = [
|
|
3042
|
+
...SHARED_MANAGED_FILES,
|
|
3043
|
+
...adapters.some((adapter) => adapter.name === "claude-code") ? ["CLAUDE.md"] : [],
|
|
3044
|
+
...adapters.some((adapter) => adapter.name === "codebuddy") ? ["CODEBUDDY.md"] : []
|
|
3045
|
+
];
|
|
3046
|
+
for (const path of managedFiles2) {
|
|
3047
|
+
if (await exists3(join9(root, path))) {
|
|
2565
3048
|
paths.push(path);
|
|
2566
3049
|
}
|
|
2567
3050
|
}
|
|
2568
|
-
for (const path of
|
|
3051
|
+
for (const path of SHARED_MANAGED_ROOTS) {
|
|
2569
3052
|
await walkFiles(root, join9(root, path), paths);
|
|
2570
3053
|
}
|
|
2571
|
-
const
|
|
2572
|
-
|
|
2573
|
-
|
|
2574
|
-
|
|
2575
|
-
|
|
2576
|
-
|
|
3054
|
+
for (const adapter of adapters) {
|
|
3055
|
+
if (adapter.rulesRoot !== null) {
|
|
3056
|
+
await walkFiles(root, join9(root, adapter.rulesRoot), paths);
|
|
3057
|
+
}
|
|
3058
|
+
await walkHarnessEntries(root, join9(root, adapter.skillsRoot), paths);
|
|
3059
|
+
if (adapter.agentsRoot !== null) {
|
|
3060
|
+
await walkHarnessEntries(root, join9(root, adapter.agentsRoot), paths);
|
|
2577
3061
|
}
|
|
2578
3062
|
}
|
|
2579
3063
|
const result = {};
|
|
@@ -2693,8 +3177,8 @@ async function pushProject(options) {
|
|
|
2693
3177
|
let project = await readProject(root);
|
|
2694
3178
|
let baseline = await readBaseline(root);
|
|
2695
3179
|
const profile = parseHarnessProfile(project.project.profiles[0]);
|
|
2696
|
-
const installedPaths = profile === null ? /* @__PURE__ */ new Set() : await managedBundleTargets(options.resourcesRoot, profile);
|
|
2697
|
-
let preview = makePreview(baseline, await managedFiles(root), options.confirmedProjectLocal ?? [], installedPaths);
|
|
3180
|
+
const installedPaths = profile === null ? /* @__PURE__ */ new Set() : new Set(await Promise.all(enabledHarnessAgents(project).map((agent) => managedBundleTargets(options.resourcesRoot, profile, agent))).then((targets) => targets.flatMap((target) => [...target])));
|
|
3181
|
+
let preview = makePreview(baseline, await managedFiles(root, project), options.confirmedProjectLocal ?? [], installedPaths);
|
|
2698
3182
|
if (preview.blocked) {
|
|
2699
3183
|
throw new PushWorkflowError("sensitive information scan blocked the proposal", 6, "SENSITIVE_CONTENT_BLOCKED");
|
|
2700
3184
|
}
|
|
@@ -2734,7 +3218,7 @@ async function pushProject(options) {
|
|
|
2734
3218
|
let workflow = priorWorkflow?.local_project_key === project.project.local_project_key ? priorWorkflow : newWorkflowState(project, clientId);
|
|
2735
3219
|
workflow.client_id = clientId;
|
|
2736
3220
|
await atomicWriteJson(workflowPath, workflow);
|
|
2737
|
-
preview = makePreview(baseline, await managedFiles(root), options.confirmedProjectLocal ?? [], installedPaths, workflow.created_at);
|
|
3221
|
+
preview = makePreview(baseline, await managedFiles(root, project), options.confirmedProjectLocal ?? [], installedPaths, workflow.created_at);
|
|
2738
3222
|
const requestId = workflow.request_id;
|
|
2739
3223
|
const client = new HunterHarnessApiClient({
|
|
2740
3224
|
serverUrl: parsedServerUrl.toString(),
|
|
@@ -2752,7 +3236,7 @@ async function pushProject(options) {
|
|
|
2752
3236
|
({ project, baseline } = await bindProject(root, project, baseline, resolved.project_id));
|
|
2753
3237
|
workflow.project_id = resolved.project_id;
|
|
2754
3238
|
await atomicWriteJson(workflowPath, workflow);
|
|
2755
|
-
preview = makePreview(baseline, await managedFiles(root), options.confirmedProjectLocal ?? [], installedPaths, workflow.created_at);
|
|
3239
|
+
preview = makePreview(baseline, await managedFiles(root, project), options.confirmedProjectLocal ?? [], installedPaths, workflow.created_at);
|
|
2756
3240
|
if (preview.blocked) {
|
|
2757
3241
|
throw new PushWorkflowError("sensitive information scan blocked the proposal", 6, "SENSITIVE_CONTENT_BLOCKED");
|
|
2758
3242
|
}
|
|
@@ -2948,7 +3432,7 @@ var AGENT_DESCRIPTORS = {
|
|
|
2948
3432
|
var INSTALLABLE_AGENTS = Object.keys(AGENT_DESCRIPTORS).filter((agent) => AGENT_DESCRIPTORS[agent]?.installable === true);
|
|
2949
3433
|
|
|
2950
3434
|
// ../core/dist/transaction/recovery.js
|
|
2951
|
-
import { readFile as readFile10, readdir as readdir6, rm as rm6, stat as
|
|
3435
|
+
import { readFile as readFile10, readdir as readdir6, rm as rm6, stat as stat3 } from "node:fs/promises";
|
|
2952
3436
|
import { join as join11 } from "node:path";
|
|
2953
3437
|
async function recoverTransaction(projectRoot, transactionId) {
|
|
2954
3438
|
const journal = JSON.parse(await readFile10(join11(stateLayout(projectRoot).transactions, transactionId, "journal.json"), "utf8"));
|
|
@@ -2995,7 +3479,7 @@ async function pendingTransactions(projectRoot) {
|
|
|
2995
3479
|
}
|
|
2996
3480
|
async function pathExists(path) {
|
|
2997
3481
|
try {
|
|
2998
|
-
await
|
|
3482
|
+
await stat3(path);
|
|
2999
3483
|
return true;
|
|
3000
3484
|
} catch (error) {
|
|
3001
3485
|
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
@@ -3014,8 +3498,8 @@ async function rollbackLatestCommittedUpdate(projectRoot) {
|
|
|
3014
3498
|
const after = JSON.parse(await readFile10(join11(transactionRoot, "after", "manifest.json"), "utf8"));
|
|
3015
3499
|
for (const entry of after) {
|
|
3016
3500
|
const target = join11(projectRoot, entry.path);
|
|
3017
|
-
const
|
|
3018
|
-
if (
|
|
3501
|
+
const exists5 = await pathExists(target);
|
|
3502
|
+
if (exists5 !== entry.exists || exists5 && await sha256File(target) !== entry.hash) {
|
|
3019
3503
|
throw new Error("cannot rollback dirty path: " + entry.path);
|
|
3020
3504
|
}
|
|
3021
3505
|
}
|
|
@@ -3027,15 +3511,15 @@ async function rollbackLatestCommittedUpdate(projectRoot) {
|
|
|
3027
3511
|
}
|
|
3028
3512
|
seen.add(snapshot.path);
|
|
3029
3513
|
const target = join11(projectRoot, snapshot.path);
|
|
3030
|
-
const
|
|
3514
|
+
const exists5 = await pathExists(target);
|
|
3031
3515
|
if (snapshot.existed && snapshot.snapshot_name !== null) {
|
|
3032
3516
|
const content = await readFile10(join11(transactionRoot, "before", snapshot.snapshot_name));
|
|
3033
3517
|
operations.push({
|
|
3034
|
-
operation:
|
|
3518
|
+
operation: exists5 ? "modify" : "add",
|
|
3035
3519
|
path: snapshot.path,
|
|
3036
3520
|
content
|
|
3037
3521
|
});
|
|
3038
|
-
} else if (
|
|
3522
|
+
} else if (exists5) {
|
|
3039
3523
|
operations.push({ operation: "delete", path: snapshot.path });
|
|
3040
3524
|
}
|
|
3041
3525
|
}
|
|
@@ -3308,7 +3792,8 @@ async function updateProject(options) {
|
|
|
3308
3792
|
equivalent = finalContent === sourceContent;
|
|
3309
3793
|
} else if (incoming !== null) {
|
|
3310
3794
|
const incomingBlock = extractManagedBlock(incoming) ?? incoming.trim();
|
|
3311
|
-
const
|
|
3795
|
+
const incomingId = extractSingleManagedBlockById(incoming)?.id;
|
|
3796
|
+
const blockId = operation.operation === "add" || operation.operation === "modify" ? operation.block_id ?? incomingId : void 0;
|
|
3312
3797
|
finalContent = blockId !== void 0 ? upsertManagedBlockById(targetContent ?? "", blockId, incomingBlock) : upsertManagedBlock(targetContent ?? "", incomingBlock);
|
|
3313
3798
|
equivalent = finalContent === targetContent;
|
|
3314
3799
|
}
|
|
@@ -3416,19 +3901,82 @@ import { isAbsolute as isAbsolute2, join as join13 } from "node:path";
|
|
|
3416
3901
|
import { readFile as readFile12 } from "node:fs/promises";
|
|
3417
3902
|
var InitConfigurationError = class extends Error {
|
|
3418
3903
|
exitCode;
|
|
3419
|
-
|
|
3904
|
+
code;
|
|
3905
|
+
constructor(message, exitCode = 3, code = "INIT_CONFIG_INVALID", options) {
|
|
3420
3906
|
super(message, options);
|
|
3421
3907
|
this.name = "InitConfigurationError";
|
|
3422
3908
|
this.exitCode = exitCode;
|
|
3909
|
+
this.code = code;
|
|
3423
3910
|
}
|
|
3424
3911
|
};
|
|
3912
|
+
function harnessErrorInfo(error) {
|
|
3913
|
+
const info = {};
|
|
3914
|
+
if (error === null || typeof error !== "object") return info;
|
|
3915
|
+
const record = error;
|
|
3916
|
+
if (typeof record.code === "string") info.code = record.code;
|
|
3917
|
+
if (typeof record.exitCode === "number") {
|
|
3918
|
+
info.exitCode = record.exitCode;
|
|
3919
|
+
}
|
|
3920
|
+
return info;
|
|
3921
|
+
}
|
|
3922
|
+
var AGENT_BY_INDEX = {
|
|
3923
|
+
"1": "claude-code",
|
|
3924
|
+
"2": "codex",
|
|
3925
|
+
"3": "cursor",
|
|
3926
|
+
"4": "codebuddy"
|
|
3927
|
+
};
|
|
3425
3928
|
function normalizeProfile(value) {
|
|
3426
3929
|
if (value === void 0) return void 0;
|
|
3427
3930
|
if (value === "" || value === "1" || value === "general") return "general";
|
|
3428
3931
|
if (value === "2" || value === "java") return "java";
|
|
3429
|
-
throw new InitConfigurationError("
|
|
3932
|
+
throw new InitConfigurationError("\u914D\u7F6E\u7C7B\u578B\u5FC5\u987B\u4E3A general \u6216 java");
|
|
3933
|
+
}
|
|
3934
|
+
function parseAgentsInput(raw) {
|
|
3935
|
+
const trimmed = raw.trim();
|
|
3936
|
+
if (trimmed === "") return ["claude-code"];
|
|
3937
|
+
if (trimmed === "all") return [...HARNESS_AGENT_ORDER];
|
|
3938
|
+
const agents = [];
|
|
3939
|
+
for (const token of trimmed.split(",")) {
|
|
3940
|
+
const value = token.trim();
|
|
3941
|
+
const byIndex = AGENT_BY_INDEX[value];
|
|
3942
|
+
if (byIndex !== void 0) {
|
|
3943
|
+
agents.push(byIndex);
|
|
3944
|
+
continue;
|
|
3945
|
+
}
|
|
3946
|
+
const byName = harnessAgentSchema.safeParse(value);
|
|
3947
|
+
if (byName.success) {
|
|
3948
|
+
agents.push(byName.data);
|
|
3949
|
+
continue;
|
|
3950
|
+
}
|
|
3951
|
+
throw new InitConfigurationError(`\u672A\u77E5 Agent\uFF1A${value}`, 3, "AGENT_UNSUPPORTED");
|
|
3952
|
+
}
|
|
3953
|
+
if (agents.length === 0) {
|
|
3954
|
+
throw new InitConfigurationError("Agent \u5217\u8868\u4E3A\u7A7A", 3, "AGENTS_REQUIRED");
|
|
3955
|
+
}
|
|
3956
|
+
return sortHarnessAgents(agents);
|
|
3430
3957
|
}
|
|
3431
|
-
|
|
3958
|
+
function parseAgentsFromConfig(value) {
|
|
3959
|
+
if (!Array.isArray(value) || value.length === 0) {
|
|
3960
|
+
throw new InitConfigurationError("Agent \u5217\u8868\u4E3A\u7A7A", 3, "AGENTS_REQUIRED");
|
|
3961
|
+
}
|
|
3962
|
+
const agents = [];
|
|
3963
|
+
for (const item2 of value) {
|
|
3964
|
+
const parsed = harnessAgentSchema.safeParse(item2);
|
|
3965
|
+
if (!parsed.success) {
|
|
3966
|
+
throw new InitConfigurationError(
|
|
3967
|
+
`\u672A\u77E5 Agent\uFF1A${String(item2)}`,
|
|
3968
|
+
3,
|
|
3969
|
+
"AGENT_UNSUPPORTED"
|
|
3970
|
+
);
|
|
3971
|
+
}
|
|
3972
|
+
agents.push(parsed.data);
|
|
3973
|
+
}
|
|
3974
|
+
return sortHarnessAgents(agents);
|
|
3975
|
+
}
|
|
3976
|
+
function hasOwn(record, key) {
|
|
3977
|
+
return Object.prototype.hasOwnProperty.call(record, key);
|
|
3978
|
+
}
|
|
3979
|
+
async function resolveInitConfig(cwd, flags, prompts = {}, warnings = []) {
|
|
3432
3980
|
let fileConfig = {};
|
|
3433
3981
|
if (flags.config !== void 0) {
|
|
3434
3982
|
const path = isAbsolute2(flags.config) ? flags.config : join13(cwd, flags.config);
|
|
@@ -3438,20 +3986,58 @@ async function resolveInitConfig(cwd, flags, promptMissing) {
|
|
|
3438
3986
|
throw new InitConfigurationError(
|
|
3439
3987
|
"unable to read init config: " + (error instanceof Error ? error.message : String(error)),
|
|
3440
3988
|
3,
|
|
3989
|
+
"INIT_CONFIG_INVALID",
|
|
3441
3990
|
{ cause: error }
|
|
3442
3991
|
);
|
|
3443
3992
|
}
|
|
3444
3993
|
}
|
|
3445
|
-
const
|
|
3446
|
-
|
|
3447
|
-
|
|
3994
|
+
const hasConfigAgents = hasOwn(fileConfig, "agents");
|
|
3995
|
+
const hasConfigAdapter = hasOwn(fileConfig, "adapter");
|
|
3996
|
+
if (hasConfigAgents && hasConfigAdapter) {
|
|
3997
|
+
throw new InitConfigurationError(
|
|
3998
|
+
"\u914D\u7F6E\u4E0D\u80FD\u540C\u65F6\u5305\u542B agents \u4E0E adapter",
|
|
3999
|
+
3,
|
|
4000
|
+
"AGENT_OPTIONS_CONFLICT"
|
|
4001
|
+
);
|
|
4002
|
+
}
|
|
4003
|
+
let agents;
|
|
4004
|
+
if (hasConfigAgents) {
|
|
4005
|
+
agents = parseAgentsFromConfig(fileConfig.agents);
|
|
4006
|
+
} else if (hasConfigAdapter) {
|
|
4007
|
+
if (fileConfig.adapter !== "claude-code") {
|
|
4008
|
+
throw new InitConfigurationError(
|
|
4009
|
+
`\u672A\u77E5 Agent\uFF1A${String(fileConfig.adapter)}`,
|
|
4010
|
+
3,
|
|
4011
|
+
"AGENT_UNSUPPORTED"
|
|
4012
|
+
);
|
|
4013
|
+
}
|
|
4014
|
+
agents = ["claude-code"];
|
|
4015
|
+
warnings.push(
|
|
4016
|
+
'DEPRECATION: init config field "adapter" is deprecated; use "agents" instead'
|
|
4017
|
+
);
|
|
4018
|
+
} else if (flags.agents !== void 0) {
|
|
4019
|
+
agents = parseAgentsInput(flags.agents);
|
|
4020
|
+
} else if (prompts.agents !== void 0) {
|
|
4021
|
+
agents = parseAgentsInput(await prompts.agents());
|
|
4022
|
+
} else {
|
|
4023
|
+
agents = ["claude-code"];
|
|
4024
|
+
}
|
|
4025
|
+
const surfaceFromConfig = hasOwn(fileConfig, "codebuddy_surface");
|
|
4026
|
+
const surfaceFromFlags = flags.codebuddySurface !== void 0;
|
|
4027
|
+
if ((surfaceFromConfig || surfaceFromFlags) && !agents.includes("codebuddy")) {
|
|
4028
|
+
throw new InitConfigurationError(
|
|
4029
|
+
"\u672A\u9009\u62E9 CodeBuddy \u65F6\u4E0D\u80FD\u6307\u5B9A codebuddy_surface",
|
|
4030
|
+
3,
|
|
4031
|
+
"CODEBUDDY_SURFACE_UNUSED"
|
|
4032
|
+
);
|
|
3448
4033
|
}
|
|
3449
4034
|
const profile = normalizeProfile(
|
|
3450
|
-
fileConfig.profile ?? flags.profile ?? (
|
|
4035
|
+
fileConfig.profile ?? flags.profile ?? (prompts.profile === void 0 ? void 0 : await prompts.profile())
|
|
3451
4036
|
);
|
|
3452
4037
|
const candidate = {
|
|
3453
|
-
|
|
4038
|
+
agents,
|
|
3454
4039
|
profile,
|
|
4040
|
+
codebuddy_surface: fileConfig.codebuddy_surface ?? flags.codebuddySurface ?? "both",
|
|
3455
4041
|
server_url: fileConfig.server_url ?? flags.serverUrl ?? null,
|
|
3456
4042
|
token_env: fileConfig.token_env ?? flags.tokenEnv ?? "HUNTER_HARNESS_TOKEN",
|
|
3457
4043
|
project_id: fileConfig.project_id ?? null,
|
|
@@ -3464,7 +4050,8 @@ async function resolveInitConfig(cwd, flags, promptMissing) {
|
|
|
3464
4050
|
if (!parsed.success) {
|
|
3465
4051
|
throw new InitConfigurationError(
|
|
3466
4052
|
"init config schema validation failed: " + parsed.error.message,
|
|
3467
|
-
7
|
|
4053
|
+
7,
|
|
4054
|
+
"INIT_CONFIG_INVALID"
|
|
3468
4055
|
);
|
|
3469
4056
|
}
|
|
3470
4057
|
return parsed.data;
|
|
@@ -3501,7 +4088,17 @@ function parseProfile(value, current) {
|
|
|
3501
4088
|
}
|
|
3502
4089
|
if (value === "1" || value === "general") return "general";
|
|
3503
4090
|
if (value === "2" || value === "java") return "java";
|
|
3504
|
-
throw new Error("
|
|
4091
|
+
throw new Error("\u914D\u7F6E\u7C7B\u578B\u5FC5\u987B\u4E3A general \u6216 java");
|
|
4092
|
+
}
|
|
4093
|
+
function refreshAgents(config) {
|
|
4094
|
+
const agents = sortHarnessAgents(config.adapters.enabled.flatMap((agent) => {
|
|
4095
|
+
const parsed = harnessAgentSchema.safeParse(agent);
|
|
4096
|
+
return parsed.success ? [parsed.data] : [];
|
|
4097
|
+
}));
|
|
4098
|
+
return agents.length > 0 ? agents : ["claude-code"];
|
|
4099
|
+
}
|
|
4100
|
+
function codebuddySurface(config) {
|
|
4101
|
+
return config.adapter_options?.codebuddy?.surface ?? "both";
|
|
3505
4102
|
}
|
|
3506
4103
|
function summarize(result) {
|
|
3507
4104
|
const items = [
|
|
@@ -3538,35 +4135,57 @@ function renderProfileTransitionPreview(result) {
|
|
|
3538
4135
|
...result.preserved,
|
|
3539
4136
|
...result.unchanged
|
|
3540
4137
|
];
|
|
3541
|
-
|
|
4138
|
+
const actionLabel = {
|
|
4139
|
+
add: "\u65B0\u589E",
|
|
4140
|
+
replace: "\u66FF\u6362",
|
|
4141
|
+
delete: "\u5220\u9664",
|
|
4142
|
+
preserve: "\u4FDD\u7559",
|
|
4143
|
+
unchanged: "\u65E0\u9700\u53D8\u66F4"
|
|
4144
|
+
};
|
|
4145
|
+
const reasonLabel = {
|
|
4146
|
+
MISSING_TARGET: "\u76EE\u6807\u7F3A\u5931",
|
|
4147
|
+
BASELINE_CLEAN: "\u57FA\u7EBF\u672A\u4FEE\u6539",
|
|
4148
|
+
ALREADY_CURRENT: "\u5DF2\u662F\u6700\u65B0",
|
|
4149
|
+
LOCAL_MODIFICATION: "\u68C0\u6D4B\u5230\u672C\u5730\u4FEE\u6539",
|
|
4150
|
+
MALFORMED_MANAGED_BLOCK: "\u53D7\u7BA1\u533A\u5757\u683C\u5F0F\u5F02\u5E38",
|
|
4151
|
+
LEGACY_PROFILE_FILE_MODIFIED: "\u65E7\u914D\u7F6E\u6587\u4EF6\u5DF2\u4FEE\u6539",
|
|
4152
|
+
LEGACY_BASELINE_UNKNOWN: "\u65E7\u7248\u57FA\u7EBF\u672A\u77E5",
|
|
4153
|
+
FORCE_MANAGED: "\u5F3A\u5236\u66F4\u65B0"
|
|
4154
|
+
};
|
|
4155
|
+
return "\u914D\u7F6E\u5207\u6362\u9884\u89C8\uFF1A\n" + items.map((item2) => `- ${actionLabel[item2.action]}\uFF1A${item2.target_path}\uFF08${reasonLabel[item2.reason]}\uFF09`).join("\n") + "\n";
|
|
3542
4156
|
}
|
|
3543
4157
|
async function runRefresh(options, dependencies) {
|
|
3544
4158
|
const requestId = uuidV7();
|
|
3545
4159
|
const detection = await detectProject(dependencies.cwd);
|
|
3546
4160
|
if (detection.status === "absent") {
|
|
3547
|
-
dependencies.stderr("Hunter Harness
|
|
4161
|
+
dependencies.stderr("\u5C1A\u672A\u521D\u59CB\u5316 Hunter Harness\uFF1B\u8BF7\u5148\u8FD0\u884C `hunter-harness`\u3002\n");
|
|
3548
4162
|
return 3;
|
|
3549
4163
|
}
|
|
3550
4164
|
if (detection.status === "invalid") {
|
|
3551
|
-
dependencies.stderr("PROJECT_CONFIG_INVALID
|
|
4165
|
+
dependencies.stderr("PROJECT_CONFIG_INVALID\uFF1A.harness/project.yaml \u65E0\u6548\n");
|
|
3552
4166
|
return 3;
|
|
3553
4167
|
}
|
|
3554
4168
|
const currentProfile = detection.config.project.profiles[0] ?? "general";
|
|
3555
4169
|
let targetProfile;
|
|
4170
|
+
let targetAgents;
|
|
3556
4171
|
try {
|
|
3557
4172
|
targetProfile = parseProfile(options.profile, currentProfile);
|
|
4173
|
+
targetAgents = options.agents === void 0 ? refreshAgents(detection.config) : parseAgentsInput(options.agents);
|
|
3558
4174
|
} catch (error) {
|
|
3559
4175
|
const message = error instanceof Error ? error.message : String(error);
|
|
3560
|
-
|
|
3561
|
-
|
|
4176
|
+
const code = error instanceof InitConfigurationError ? error.code : void 0;
|
|
4177
|
+
dependencies.stderr((code === void 0 ? "" : code + ": ") + message + "\n");
|
|
4178
|
+
return error instanceof InitConfigurationError ? error.exitCode : 3;
|
|
3562
4179
|
}
|
|
3563
4180
|
const dryRun = options.dryRun === true;
|
|
3564
|
-
if (targetProfile !== currentProfile && !dryRun) {
|
|
4181
|
+
if ((targetProfile !== currentProfile || targetAgents.some((agent, index) => agent !== refreshAgents(detection.config)[index]) || targetAgents.length !== refreshAgents(detection.config).length) && !dryRun) {
|
|
3565
4182
|
try {
|
|
3566
4183
|
const preview = await refreshProject({
|
|
3567
4184
|
projectRoot: dependencies.cwd,
|
|
3568
4185
|
resourcesRoot: dependencies.resourcesRoot,
|
|
3569
4186
|
profile: targetProfile,
|
|
4187
|
+
agents: targetAgents,
|
|
4188
|
+
codebuddySurface: codebuddySurface(detection.config),
|
|
3570
4189
|
dryRun: true,
|
|
3571
4190
|
forceManaged: options.forceManaged === true
|
|
3572
4191
|
});
|
|
@@ -3585,12 +4204,12 @@ async function runRefresh(options, dependencies) {
|
|
|
3585
4204
|
if (options.confirmed !== true) {
|
|
3586
4205
|
if (options.nonInteractive === true) {
|
|
3587
4206
|
if (!options.yes && !dryRun) {
|
|
3588
|
-
dependencies.stderr("
|
|
4207
|
+
dependencies.stderr("\u975E\u4EA4\u4E92\u6A21\u5F0F\u5237\u65B0\u9700\u8981 --yes\n");
|
|
3589
4208
|
return 2;
|
|
3590
4209
|
}
|
|
3591
4210
|
} else if (!options.yes && !dryRun) {
|
|
3592
|
-
const label = targetProfile === currentProfile ?
|
|
3593
|
-
const answer = await dependencies.prompt(`${label}
|
|
4211
|
+
const label = targetProfile === currentProfile ? `\u5237\u65B0\u5F53\u524D\u914D\u7F6E\uFF08${currentProfile}\uFF09` : `\u5207\u6362\u914D\u7F6E\uFF1A${currentProfile} \u2192 ${targetProfile}`;
|
|
4212
|
+
const answer = await dependencies.prompt(`${label}\uFF1F[y/N]\uFF1A`);
|
|
3594
4213
|
if (!/^(?:y|yes)$/i.test(answer.trim())) {
|
|
3595
4214
|
return 2;
|
|
3596
4215
|
}
|
|
@@ -3601,6 +4220,8 @@ async function runRefresh(options, dependencies) {
|
|
|
3601
4220
|
projectRoot: dependencies.cwd,
|
|
3602
4221
|
resourcesRoot: dependencies.resourcesRoot,
|
|
3603
4222
|
profile: targetProfile,
|
|
4223
|
+
agents: targetAgents,
|
|
4224
|
+
codebuddySurface: codebuddySurface(detection.config),
|
|
3604
4225
|
dryRun,
|
|
3605
4226
|
forceManaged: options.forceManaged === true
|
|
3606
4227
|
});
|
|
@@ -3609,17 +4230,20 @@ async function runRefresh(options, dependencies) {
|
|
|
3609
4230
|
dependencies.stdout(serializeCliResult({ ...output, request_id: requestId }));
|
|
3610
4231
|
} else {
|
|
3611
4232
|
const parts = [];
|
|
3612
|
-
if (result.applied.length > 0) parts.push(
|
|
3613
|
-
if (result.removed.length > 0) parts.push(
|
|
3614
|
-
if (result.preserved.length > 0) parts.push(
|
|
3615
|
-
if (result.unchanged.length > 0) parts.push(
|
|
3616
|
-
dependencies.stdout(`Harness
|
|
4233
|
+
if (result.applied.length > 0) parts.push(`\u5DF2\u66F4\u65B0 ${result.applied.length} \u4E2A`);
|
|
4234
|
+
if (result.removed.length > 0) parts.push(`\u5DF2\u5220\u9664 ${result.removed.length} \u4E2A`);
|
|
4235
|
+
if (result.preserved.length > 0) parts.push(`\u5DF2\u4FDD\u7559 ${result.preserved.length} \u4E2A`);
|
|
4236
|
+
if (result.unchanged.length > 0) parts.push(`\u65E0\u9700\u53D8\u66F4 ${result.unchanged.length} \u4E2A`);
|
|
4237
|
+
dependencies.stdout(`Harness \u5237\u65B0\uFF08${targetProfile}\uFF09\uFF1A${parts.join("\uFF0C") || "\u6CA1\u6709\u53D8\u66F4"}\u3002
|
|
3617
4238
|
`);
|
|
3618
4239
|
}
|
|
3619
4240
|
return output.exit_code;
|
|
3620
4241
|
} catch (error) {
|
|
4242
|
+
const info = harnessErrorInfo(error);
|
|
4243
|
+
const exitCode = info.exitCode ?? 1;
|
|
4244
|
+
const code = info.code;
|
|
3621
4245
|
const message = error instanceof Error ? error.message : String(error);
|
|
3622
|
-
dependencies.stderr(message + "\n");
|
|
4246
|
+
dependencies.stderr((code !== void 0 ? code + ": " : "") + message + "\n");
|
|
3623
4247
|
if (options.json === true) {
|
|
3624
4248
|
dependencies.stdout(serializeCliResult({
|
|
3625
4249
|
schema_version: 1,
|
|
@@ -3627,15 +4251,15 @@ async function runRefresh(options, dependencies) {
|
|
|
3627
4251
|
request_id: requestId,
|
|
3628
4252
|
dry_run: dryRun,
|
|
3629
4253
|
ok: false,
|
|
3630
|
-
exit_code:
|
|
4254
|
+
exit_code: exitCode,
|
|
3631
4255
|
project_id: null,
|
|
3632
4256
|
summary: { applied: 0, removed: 0, preserved: 0, unchanged: 0, conflicts: 0 },
|
|
3633
4257
|
items: [],
|
|
3634
4258
|
warnings: [],
|
|
3635
|
-
errors: [{ message }]
|
|
4259
|
+
errors: [{ ...code === void 0 ? {} : { code }, message }]
|
|
3636
4260
|
}));
|
|
3637
4261
|
}
|
|
3638
|
-
return
|
|
4262
|
+
return exitCode;
|
|
3639
4263
|
}
|
|
3640
4264
|
}
|
|
3641
4265
|
|
|
@@ -3646,15 +4270,25 @@ function otherProfile(current) {
|
|
|
3646
4270
|
async function runFirstInstall(options, dependencies) {
|
|
3647
4271
|
const requestId = uuidV7();
|
|
3648
4272
|
try {
|
|
4273
|
+
const warnings = [];
|
|
3649
4274
|
const config = await resolveInitConfig(
|
|
3650
4275
|
dependencies.cwd,
|
|
3651
4276
|
options,
|
|
3652
|
-
options.nonInteractive === true ?
|
|
3653
|
-
|
|
3654
|
-
|
|
4277
|
+
options.nonInteractive === true ? {} : {
|
|
4278
|
+
agents: () => dependencies.prompt(
|
|
4279
|
+
"\u8BF7\u9009\u62E9\u76EE\u6807 Agent\uFF08\u53EF\u591A\u9009\uFF0C\u4F7F\u7528\u9017\u53F7\u5206\u9694\uFF09\n 1. Claude Code\n 2. Codex\n 3. Cursor\n 4. CodeBuddy\n\u8BF7\u8F93\u5165\u7F16\u53F7 [1]: "
|
|
4280
|
+
).then((answer) => answer.trim()),
|
|
4281
|
+
profile: () => dependencies.prompt(
|
|
4282
|
+
"\u8BF7\u9009\u62E9 Harness \u7C7B\u578B\uFF1A\n1. \u901A\u7528\uFF08\u9ED8\u8BA4\uFF09\n2. Java\n\u8BF7\u8F93\u5165 1 \u6216 2 [1]: "
|
|
4283
|
+
).then((answer) => answer.trim())
|
|
4284
|
+
},
|
|
4285
|
+
warnings
|
|
3655
4286
|
);
|
|
4287
|
+
for (const warning of warnings) {
|
|
4288
|
+
dependencies.stderr(warning + "\n");
|
|
4289
|
+
}
|
|
3656
4290
|
if (options.nonInteractive === true && options.yes !== true && options.dryRun !== true) {
|
|
3657
|
-
dependencies.stderr("
|
|
4291
|
+
dependencies.stderr("\u975E\u4EA4\u4E92\u6A21\u5F0F\u6267\u884C\u5199\u5165\u64CD\u4F5C\u9700\u8981 --yes\n");
|
|
3658
4292
|
return 2;
|
|
3659
4293
|
}
|
|
3660
4294
|
const result = await initializeProject({
|
|
@@ -3676,12 +4310,14 @@ async function runFirstInstall(options, dependencies) {
|
|
|
3676
4310
|
warnings: [],
|
|
3677
4311
|
errors: []
|
|
3678
4312
|
};
|
|
3679
|
-
dependencies.stdout(options.json === true ? serializeCliResult(output) : "Hunter Harness
|
|
4313
|
+
dependencies.stdout(options.json === true ? serializeCliResult(output) : "Hunter Harness \u521D\u59CB\u5316\u5B8C\u6210\uFF0C\u5171\u5904\u7406 " + result.paths.length + " \u4E2A\u6587\u4EF6\u3002\n");
|
|
3680
4314
|
return 0;
|
|
3681
4315
|
} catch (error) {
|
|
3682
|
-
const
|
|
4316
|
+
const info = harnessErrorInfo(error);
|
|
4317
|
+
const exitCode = info.exitCode ?? 1;
|
|
4318
|
+
const code = info.code;
|
|
3683
4319
|
const message = error instanceof Error ? error.message : String(error);
|
|
3684
|
-
dependencies.stderr(message + "\n");
|
|
4320
|
+
dependencies.stderr((code !== void 0 ? code + ": " : "") + message + "\n");
|
|
3685
4321
|
if (options.json === true) {
|
|
3686
4322
|
dependencies.stdout(serializeCliResult({
|
|
3687
4323
|
schema_version: 1,
|
|
@@ -3694,7 +4330,7 @@ async function runFirstInstall(options, dependencies) {
|
|
|
3694
4330
|
summary: { planned: 0, applied: 0 },
|
|
3695
4331
|
items: [],
|
|
3696
4332
|
warnings: [],
|
|
3697
|
-
errors: [{ message }]
|
|
4333
|
+
errors: [{ ...code === void 0 ? {} : { code }, message }]
|
|
3698
4334
|
}));
|
|
3699
4335
|
}
|
|
3700
4336
|
return exitCode;
|
|
@@ -3702,6 +4338,7 @@ async function runFirstInstall(options, dependencies) {
|
|
|
3702
4338
|
}
|
|
3703
4339
|
async function runExistingProject(options, dependencies, currentProfile) {
|
|
3704
4340
|
const refreshOptions = {};
|
|
4341
|
+
if (options.agents !== void 0) refreshOptions.agents = options.agents;
|
|
3705
4342
|
if (options.profile !== void 0) refreshOptions.profile = options.profile;
|
|
3706
4343
|
if (options.nonInteractive !== void 0) refreshOptions.nonInteractive = options.nonInteractive;
|
|
3707
4344
|
if (options.yes !== void 0) refreshOptions.yes = options.yes;
|
|
@@ -3713,9 +4350,9 @@ async function runExistingProject(options, dependencies, currentProfile) {
|
|
|
3713
4350
|
}
|
|
3714
4351
|
const menu = await dependencies.prompt(
|
|
3715
4352
|
`Hunter Harness \u5DF2\u521D\u59CB\u5316\uFF08profile: ${currentProfile}\uFF09\u3002
|
|
3716
|
-
1.
|
|
3717
|
-
2.
|
|
3718
|
-
3.
|
|
4353
|
+
1. \u5237\u65B0\u5F53\u524D\u914D\u7F6E\uFF08\u9ED8\u8BA4\u4E14\u63A8\u8350\uFF09
|
|
4354
|
+
2. \u5207\u6362\u5230\u53E6\u4E00\u79CD\u914D\u7F6E
|
|
4355
|
+
3. \u53D6\u6D88
|
|
3719
4356
|
\u8BF7\u9009\u62E9 [1]: `
|
|
3720
4357
|
);
|
|
3721
4358
|
const choice = menu.trim();
|
|
@@ -3763,7 +4400,7 @@ async function runCleanup(options, dependencies) {
|
|
|
3763
4400
|
const requestId = uuidV7();
|
|
3764
4401
|
const dryRun = options.dryRun === true;
|
|
3765
4402
|
if (options.nonInteractive === true && options.yes !== true && !dryRun) {
|
|
3766
|
-
dependencies.stderr("
|
|
4403
|
+
dependencies.stderr("\u975E\u4EA4\u4E92\u6A21\u5F0F\u6E05\u7406\u9700\u8981 --yes\n");
|
|
3767
4404
|
return 2;
|
|
3768
4405
|
}
|
|
3769
4406
|
try {
|
|
@@ -3791,7 +4428,7 @@ async function runCleanup(options, dependencies) {
|
|
|
3791
4428
|
dependencies.stdout(serializeCliResult(output));
|
|
3792
4429
|
} else {
|
|
3793
4430
|
dependencies.stdout(
|
|
3794
|
-
`Harness
|
|
4431
|
+
`Harness \u6E05\u7406\u5B8C\u6210\uFF1A\u5DF2\u88C1\u526A ${result.pruned_transactions.length} \u4E2A\u4E8B\u52A1\uFF0C\u5DF2\u5220\u9664 ${result.removed_cache.length} \u4E2A\u7F13\u5B58\u6761\u76EE\u3002
|
|
3795
4432
|
`
|
|
3796
4433
|
);
|
|
3797
4434
|
}
|
|
@@ -3822,7 +4459,7 @@ async function runCleanup(options, dependencies) {
|
|
|
3822
4459
|
async function runPush(options, dependencies) {
|
|
3823
4460
|
const requestId = uuidV7();
|
|
3824
4461
|
if (options.nonInteractive === true && options.yes !== true && options.dryRun !== true) {
|
|
3825
|
-
dependencies.stderr("
|
|
4462
|
+
dependencies.stderr("\u975E\u4EA4\u4E92\u6A21\u5F0F\u63A8\u9001\u9700\u8981 --yes\n");
|
|
3826
4463
|
return 2;
|
|
3827
4464
|
}
|
|
3828
4465
|
try {
|
|
@@ -3901,7 +4538,7 @@ async function runPush(options, dependencies) {
|
|
|
3901
4538
|
async function runUpdate(options, dependencies) {
|
|
3902
4539
|
const requestId = uuidV7();
|
|
3903
4540
|
if (options.nonInteractive === true && options.yes !== true && options.dryRun !== true) {
|
|
3904
|
-
dependencies.stderr("
|
|
4541
|
+
dependencies.stderr("\u975E\u4EA4\u4E92\u6A21\u5F0F\u66F4\u65B0\u9700\u8981 --yes\n");
|
|
3905
4542
|
return 2;
|
|
3906
4543
|
}
|
|
3907
4544
|
const execute = async (dryRun) => updateProject({
|
|
@@ -3917,7 +4554,7 @@ async function runUpdate(options, dependencies) {
|
|
|
3917
4554
|
if (options.dryRun !== true && options.yes !== true && options.nonInteractive !== true) {
|
|
3918
4555
|
const preview = await execute(true);
|
|
3919
4556
|
const answer = await dependencies.prompt(
|
|
3920
|
-
"
|
|
4557
|
+
"\u5E94\u7528 " + preview.applied.length + " \u4E2A\u53EF\u66F4\u65B0\u6761\u76EE\uFF1F[y/N]\uFF1A"
|
|
3921
4558
|
);
|
|
3922
4559
|
if (!/^(?:y|yes)$/i.test(answer.trim())) {
|
|
3923
4560
|
return 2;
|
|
@@ -3960,7 +4597,7 @@ async function runUpdate(options, dependencies) {
|
|
|
3960
4597
|
warnings: result.skipped,
|
|
3961
4598
|
errors: []
|
|
3962
4599
|
};
|
|
3963
|
-
dependencies.stdout(options.json === true ? serializeCliResult(output) : result.artifactId === null ? "
|
|
4600
|
+
dependencies.stdout(options.json === true ? serializeCliResult(output) : result.artifactId === null ? "\u6CA1\u6709\u53EF\u5E94\u7528\u7684\u5DF2\u6279\u51C6\u66F4\u65B0\u3002\n" : "\u66F4\u65B0\u5B8C\u6210\uFF1A\u5DF2\u5E94\u7528 " + result.applied.length + " \u4E2A\u6761\u76EE\uFF0C\u8DF3\u8FC7 " + result.skipped.length + " \u4E2A\u3002\n");
|
|
3964
4601
|
return exitCode;
|
|
3965
4602
|
} catch (error) {
|
|
3966
4603
|
const exitCode = error instanceof UpdateWorkflowError ? error.exitCode : 1;
|
|
@@ -3989,33 +4626,33 @@ async function runUpdate(options, dependencies) {
|
|
|
3989
4626
|
}
|
|
3990
4627
|
|
|
3991
4628
|
// src/commands/recovery.ts
|
|
3992
|
-
import { stat as
|
|
4629
|
+
import { stat as stat4 } from "node:fs/promises";
|
|
3993
4630
|
import { join as join15 } from "node:path";
|
|
3994
|
-
async function
|
|
4631
|
+
async function exists4(path) {
|
|
3995
4632
|
try {
|
|
3996
|
-
await
|
|
4633
|
+
await stat4(path);
|
|
3997
4634
|
return true;
|
|
3998
4635
|
} catch {
|
|
3999
4636
|
return false;
|
|
4000
4637
|
}
|
|
4001
4638
|
}
|
|
4002
4639
|
function explicitConfigure(options) {
|
|
4003
|
-
return options.adapter !== void 0 || options.profile !== void 0 || options.config !== void 0 || options.serverUrl !== void 0 || options.tokenEnv !== void 0;
|
|
4640
|
+
return options.agents !== void 0 || options.adapter !== void 0 || options.profile !== void 0 || options.config !== void 0 || options.serverUrl !== void 0 || options.tokenEnv !== void 0;
|
|
4004
4641
|
}
|
|
4005
4642
|
async function runRecoveryMenuIfApplicable(options, dependencies) {
|
|
4006
4643
|
const pending = await pendingTransactions(dependencies.cwd);
|
|
4007
4644
|
if (pending.length > 0) {
|
|
4008
4645
|
if (options.nonInteractive === true) {
|
|
4009
|
-
dependencies.stderr("
|
|
4646
|
+
dependencies.stderr("\u5B58\u5728\u672A\u5B8C\u6210\u4E8B\u52A1\uFF0C\u9700\u8981\u4EE5\u4EA4\u4E92\u6A21\u5F0F\u6062\u590D\u3002\n");
|
|
4010
4647
|
return 5;
|
|
4011
4648
|
}
|
|
4012
4649
|
const answer2 = await dependencies.prompt([
|
|
4013
|
-
"
|
|
4014
|
-
"1.
|
|
4015
|
-
"2.
|
|
4016
|
-
"3.
|
|
4017
|
-
"4.
|
|
4018
|
-
"
|
|
4650
|
+
"\u68C0\u6D4B\u5230\u672A\u5B8C\u6210\u7684 Hunter Harness \u4E8B\u52A1\u3002",
|
|
4651
|
+
"1. \u6062\u590D\u6700\u8FD1\u4E00\u6B21\u5931\u8D25\u7684\u66F4\u65B0",
|
|
4652
|
+
"2. \u56DE\u6EDA\u6700\u8FD1\u4E00\u6B21\u5DF2\u63D0\u4EA4\u7684\u66F4\u65B0",
|
|
4653
|
+
"3. \u67E5\u770B\u4E8B\u52A1\u72B6\u6001",
|
|
4654
|
+
"4. \u6E05\u7406\u65E7\u4E8B\u52A1",
|
|
4655
|
+
"\u8BF7\u9009\u62E9 [1-4]\uFF1A"
|
|
4019
4656
|
].join("\n"));
|
|
4020
4657
|
try {
|
|
4021
4658
|
if (answer2.trim() === "1") {
|
|
@@ -4023,12 +4660,12 @@ async function runRecoveryMenuIfApplicable(options, dependencies) {
|
|
|
4023
4660
|
dependencies.cwd,
|
|
4024
4661
|
pending[0]?.transactionId ?? ""
|
|
4025
4662
|
);
|
|
4026
|
-
dependencies.stdout("
|
|
4663
|
+
dependencies.stdout("\u6062\u590D\u5B8C\u6210\uFF1A" + result.status + "\u3002\n");
|
|
4027
4664
|
return 0;
|
|
4028
4665
|
}
|
|
4029
4666
|
if (answer2.trim() === "2") {
|
|
4030
4667
|
const result = await rollbackLatestCommittedUpdate(dependencies.cwd);
|
|
4031
|
-
dependencies.stdout("
|
|
4668
|
+
dependencies.stdout("\u56DE\u6EDA\u5B8C\u6210\uFF1A" + result.status + "\u3002\n");
|
|
4032
4669
|
return 0;
|
|
4033
4670
|
}
|
|
4034
4671
|
if (answer2.trim() === "3") {
|
|
@@ -4041,7 +4678,7 @@ async function runRecoveryMenuIfApplicable(options, dependencies) {
|
|
|
4041
4678
|
}
|
|
4042
4679
|
if (answer2.trim() === "4") {
|
|
4043
4680
|
const removed = await cleanupOldTransactions(dependencies.cwd);
|
|
4044
|
-
dependencies.stdout("
|
|
4681
|
+
dependencies.stdout("\u5DF2\u6E05\u7406 " + removed.length + " \u4E2A\u65E7\u4E8B\u52A1\u3002\n");
|
|
4045
4682
|
return 0;
|
|
4046
4683
|
}
|
|
4047
4684
|
return 2;
|
|
@@ -4050,18 +4687,18 @@ async function runRecoveryMenuIfApplicable(options, dependencies) {
|
|
|
4050
4687
|
return 5;
|
|
4051
4688
|
}
|
|
4052
4689
|
}
|
|
4053
|
-
const initialized = await
|
|
4690
|
+
const initialized = await exists4(join15(dependencies.cwd, ".harness", "project.yaml"));
|
|
4054
4691
|
if (!initialized || options.nonInteractive === true || explicitConfigure(options)) {
|
|
4055
4692
|
return null;
|
|
4056
4693
|
}
|
|
4057
4694
|
const answer = await dependencies.prompt([
|
|
4058
|
-
"Hunter Harness
|
|
4059
|
-
"1.
|
|
4060
|
-
"2.
|
|
4061
|
-
"3.
|
|
4062
|
-
"4.
|
|
4063
|
-
"5.
|
|
4064
|
-
"
|
|
4695
|
+
"Hunter Harness \u9879\u76EE\u83DC\u5355\u3002",
|
|
4696
|
+
"1. \u914D\u7F6E\u9879\u76EE",
|
|
4697
|
+
"2. \u56DE\u6EDA\u6700\u8FD1\u4E00\u6B21\u66F4\u65B0",
|
|
4698
|
+
"3. \u6E05\u7406\u65E7\u4E8B\u52A1",
|
|
4699
|
+
"4. \u67E5\u770B\u4E8B\u52A1\u72B6\u6001",
|
|
4700
|
+
"5. \u9000\u51FA",
|
|
4701
|
+
"\u8BF7\u9009\u62E9 [1-5]\uFF1A"
|
|
4065
4702
|
].join("\n"));
|
|
4066
4703
|
try {
|
|
4067
4704
|
if (answer.trim() === "1") {
|
|
@@ -4069,12 +4706,12 @@ async function runRecoveryMenuIfApplicable(options, dependencies) {
|
|
|
4069
4706
|
}
|
|
4070
4707
|
if (answer.trim() === "2") {
|
|
4071
4708
|
const result = await rollbackLatestCommittedUpdate(dependencies.cwd);
|
|
4072
|
-
dependencies.stdout("
|
|
4709
|
+
dependencies.stdout("\u56DE\u6EDA\u5B8C\u6210\uFF1A" + result.status + "\u3002\n");
|
|
4073
4710
|
return 0;
|
|
4074
4711
|
}
|
|
4075
4712
|
if (answer.trim() === "3") {
|
|
4076
4713
|
const removed = await cleanupOldTransactions(dependencies.cwd);
|
|
4077
|
-
dependencies.stdout("
|
|
4714
|
+
dependencies.stdout("\u5DF2\u6E05\u7406 " + removed.length + " \u4E2A\u65E7\u4E8B\u52A1\u3002\n");
|
|
4078
4715
|
return 0;
|
|
4079
4716
|
}
|
|
4080
4717
|
if (answer.trim() === "4") {
|
|
@@ -4114,7 +4751,7 @@ function defaultDependencies(overrides) {
|
|
|
4114
4751
|
};
|
|
4115
4752
|
}
|
|
4116
4753
|
function addCommonOptions(command) {
|
|
4117
|
-
return command.option("--dry-run").option("--yes").option("--json").option("--server-url <url>").option("--token-env <ENV_NAME>").option("--non-interactive");
|
|
4754
|
+
return command.option("--dry-run").option("--yes").option("--json").option("--server-url <url>").option("--token-env <ENV_NAME>").option("--non-interactive").option("--agents <csv>").option("--codebuddy-surface <surface>");
|
|
4118
4755
|
}
|
|
4119
4756
|
async function runCli(argv, overrides = {}) {
|
|
4120
4757
|
const dependencies = defaultDependencies(overrides);
|
|
@@ -4131,22 +4768,22 @@ async function runCli(argv, overrides = {}) {
|
|
|
4131
4768
|
}
|
|
4132
4769
|
exitCode = await runConfigure(options, dependencies);
|
|
4133
4770
|
});
|
|
4134
|
-
addCommonOptions(program.command("refresh")).description("
|
|
4771
|
+
addCommonOptions(program.command("refresh")).description("\u672C\u5730\u4FDD\u5B88\u5237\u65B0\u5DF2\u5B89\u88C5\u7684 Harness \u9879\u76EE").option("--profile <name>").option("--force-managed").action(async (options) => {
|
|
4135
4772
|
exitCode = await runRefresh(
|
|
4136
4773
|
{ ...program.opts(), ...options },
|
|
4137
4774
|
dependencies
|
|
4138
4775
|
);
|
|
4139
4776
|
});
|
|
4140
|
-
addCommonOptions(program.command("update")).description("
|
|
4777
|
+
addCommonOptions(program.command("update")).description("\u5E94\u7528\u5DF2\u6279\u51C6\u7684\u670D\u52A1\u7AEF\u4EA7\u7269").action(async (options) => {
|
|
4141
4778
|
exitCode = await runUpdate(
|
|
4142
4779
|
{ ...program.opts(), ...options },
|
|
4143
4780
|
dependencies
|
|
4144
4781
|
);
|
|
4145
4782
|
});
|
|
4146
|
-
addCommonOptions(program.command("push")).description("
|
|
4783
|
+
addCommonOptions(program.command("push")).description("\u521B\u5EFA\u53D7\u6CBB\u7406\u7684\u53D8\u66F4\u63D0\u6848").action(async (options) => {
|
|
4147
4784
|
exitCode = await runPush({ ...program.opts(), ...options }, dependencies);
|
|
4148
4785
|
});
|
|
4149
|
-
addCommonOptions(program.command("cleanup")).description("
|
|
4786
|
+
addCommonOptions(program.command("cleanup")).description("\u6E05\u7406\u5DF2\u5B8C\u6210\u4E8B\u52A1\u548C\u8FC7\u671F\u670D\u52A1\u7AEF\u7F13\u5B58").action(async (options) => {
|
|
4150
4787
|
exitCode = await runCleanup(
|
|
4151
4788
|
{ ...program.opts(), ...options },
|
|
4152
4789
|
dependencies
|