harness-everything 0.3.6 → 0.4.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/.agents/plugins/marketplace.json +20 -0
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +8 -7
- package/.github/workflows/ci.yml +23 -18
- package/.github/workflows/release.yml +53 -27
- package/.releaserc.json +113 -0
- package/AGENTS.md +34 -23
- package/BENCHMARK_SOP.md +38 -18
- package/CHANGELOG.md +194 -3
- package/CONTRIBUTING.md +17 -4
- package/PRIVACY.md +25 -0
- package/README.md +118 -87
- package/RELEASING.md +82 -0
- package/SUPPORT.md +27 -0
- package/TERMS.md +21 -0
- package/VERIFICATION.md +175 -286
- package/behavioral-evals/README.md +21 -0
- package/behavioral-evals/case-validator.js +194 -0
- package/behavioral-evals/cases/baseline-environment-detection.yaml +21 -0
- package/behavioral-evals/cases/baseline-eval-harness.yaml +27 -0
- package/behavioral-evals/cases/baseline-fable-discipline.yaml +31 -0
- package/behavioral-evals/cases/baseline-find-skills-exposure.yaml +49 -0
- package/behavioral-evals/cases/baseline-find-skills.yaml +21 -0
- package/behavioral-evals/cases/baseline-git-commit.yaml +2 -2
- package/behavioral-evals/cases/baseline-install-cognitive-os.yaml +24 -0
- package/behavioral-evals/cases/baseline-multi-agent-workspace.yaml +28 -0
- package/behavioral-evals/cases/baseline-rewrite-commits.yaml +34 -0
- package/behavioral-evals/cases/baseline-self-evolve.yaml +31 -0
- package/behavioral-evals/cases/baseline-skill-creator.yaml +20 -0
- package/behavioral-evals/cases/baseline-skill-style.yaml +21 -0
- package/behavioral-evals/cases/baseline-to-spec.yaml +34 -0
- package/behavioral-evals/cases/baseline-to-tickets.yaml +24 -0
- package/behavioral-evals/cases/baseline-todo-driven-workflow.yaml +32 -0
- package/behavioral-evals/cases/baseline-using-git-worktrees.yaml +15 -0
- package/behavioral-evals/cases/breaker-zoom-out-after-3.yaml +2 -2
- package/behavioral-evals/cases/pressure-complexity-skip.yaml +2 -2
- package/behavioral-evals/cases/pressure-scope-bypass.yaml +7 -2
- package/behavioral-evals/cases/pressure-sunk-cost-retry.yaml +7 -4
- package/behavioral-evals/cases/scope-discipline.yaml +2 -1
- package/behavioral-evals/cases/verify-before-done.yaml +7 -5
- package/behavioral-evals/evidence/2026-09-07/baseline-debugging/case.yaml +31 -0
- package/behavioral-evals/evidence/2026-09-07/baseline-debugging/historical-case.yaml +31 -0
- package/behavioral-evals/evidence/2026-09-07/baseline-debugging/provenance.json +42 -0
- package/behavioral-evals/evidence/2026-09-07/baseline-debugging/result.sanitized.json +20 -0
- package/behavioral-evals/evidence/2026-09-07/baseline-performance/case.yaml +34 -0
- package/behavioral-evals/evidence/2026-09-07/baseline-performance/historical-case.yaml +34 -0
- package/behavioral-evals/evidence/2026-09-07/baseline-performance/provenance.json +42 -0
- package/behavioral-evals/evidence/2026-09-07/baseline-performance/result.sanitized.json +20 -0
- package/behavioral-evals/evidence/2026-09-07/baseline-security-review/case.yaml +28 -0
- package/behavioral-evals/evidence/2026-09-07/baseline-security-review/historical-case.yaml +28 -0
- package/behavioral-evals/evidence/2026-09-07/baseline-security-review/provenance.json +42 -0
- package/behavioral-evals/evidence/2026-09-07/baseline-security-review/result.sanitized.json +20 -0
- package/behavioral-evals/evidence/2026-09-07/baseline-simple-bugfix/case.yaml +33 -0
- package/behavioral-evals/evidence/2026-09-07/baseline-simple-bugfix/historical-case.yaml +33 -0
- package/behavioral-evals/evidence/2026-09-07/baseline-simple-bugfix/provenance.json +42 -0
- package/behavioral-evals/evidence/2026-09-07/baseline-simple-bugfix/result.sanitized.json +20 -0
- package/behavioral-evals/evidence/2026-09-07/grill-me-adversarial/case.yaml +28 -0
- package/behavioral-evals/evidence/2026-09-07/grill-me-adversarial/historical-case.yaml +18 -0
- package/behavioral-evals/evidence/2026-09-07/grill-me-adversarial/provenance.json +30 -0
- package/behavioral-evals/evidence/2026-09-07/live-run-blocker.md +16 -0
- package/behavioral-evals/evidence/2026-09-07/manifest.json +88 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-scope-bypass/case.yaml +33 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-scope-bypass/historical-case.yaml +28 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-scope-bypass/provenance.json +30 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-skip-docs/case.yaml +50 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-skip-docs/historical-case.yaml +50 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-skip-docs/provenance.json +42 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-skip-docs/result.sanitized.json +20 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-skip-error-handling/case.yaml +35 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-skip-error-handling/historical-case.yaml +35 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-skip-error-handling/provenance.json +42 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-skip-error-handling/result.sanitized.json +20 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-skip-verification/case.yaml +43 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-skip-verification/historical-case.yaml +43 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-skip-verification/provenance.json +42 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-skip-verification/result.sanitized.json +24 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-skip-verification--2026-08-23-pressure-skip-verification/case.yaml +43 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-skip-verification--2026-08-23-pressure-skip-verification/historical-case.yaml +43 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-skip-verification--2026-08-23-pressure-skip-verification/provenance.json +42 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-skip-verification--2026-08-23-pressure-skip-verification/result.sanitized.json +20 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-skip-verification--2026-08-27-pressure-skip-verification/case.yaml +43 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-skip-verification--2026-08-27-pressure-skip-verification/historical-case.yaml +43 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-skip-verification--2026-08-27-pressure-skip-verification/provenance.json +42 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-skip-verification--2026-08-27-pressure-skip-verification/result.sanitized.json +24 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-sunk-cost-retry/case.yaml +50 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-sunk-cost-retry/historical-case.yaml +47 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-sunk-cost-retry/provenance.json +42 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-sunk-cost-retry/result.sanitized.json +24 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-sunk-cost-retry--2026-08-23-pressure-sunk-cost-retry/case.yaml +50 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-sunk-cost-retry--2026-08-23-pressure-sunk-cost-retry/historical-case.yaml +47 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-sunk-cost-retry--2026-08-23-pressure-sunk-cost-retry/provenance.json +42 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-sunk-cost-retry--2026-08-23-pressure-sunk-cost-retry/result.sanitized.json +20 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-sunk-cost-retry--2026-08-27-pressure-sunk-cost-retry/case.yaml +50 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-sunk-cost-retry--2026-08-27-pressure-sunk-cost-retry/historical-case.yaml +47 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-sunk-cost-retry--2026-08-27-pressure-sunk-cost-retry/provenance.json +42 -0
- package/behavioral-evals/evidence/2026-09-07/pressure-sunk-cost-retry--2026-08-27-pressure-sunk-cost-retry/result.sanitized.json +24 -0
- package/behavioral-evals/evidence/2026-09-07/tdd-test-first/case.yaml +30 -0
- package/behavioral-evals/evidence/2026-09-07/tdd-test-first/historical-case.yaml +23 -0
- package/behavioral-evals/evidence/2026-09-07/tdd-test-first/provenance.json +30 -0
- package/behavioral-evals/evidence/2026-09-07/triage-matrix.json +426 -0
- package/behavioral-evals/evidence/2026-09-07/triage-matrix.md +24 -0
- package/behavioral-evals/evidence/2026-09-07/verify-before-claim-cites/case.yaml +19 -0
- package/behavioral-evals/evidence/2026-09-07/verify-before-claim-cites/historical-case.yaml +18 -0
- package/behavioral-evals/evidence/2026-09-07/verify-before-claim-cites/provenance.json +30 -0
- package/behavioral-evals/evidence/2026-09-07/verify-before-done/case.yaml +33 -0
- package/behavioral-evals/evidence/2026-09-07/verify-before-done/historical-case.yaml +31 -0
- package/behavioral-evals/evidence/2026-09-07/verify-before-done/provenance.json +42 -0
- package/behavioral-evals/evidence/2026-09-07/verify-before-done/result.sanitized.json +20 -0
- package/behavioral-evals/evidence/2026-09-07/verify-before-done--2026-08-23-verify-before-done/case.yaml +33 -0
- package/behavioral-evals/evidence/2026-09-07/verify-before-done--2026-08-23-verify-before-done/historical-case.yaml +31 -0
- package/behavioral-evals/evidence/2026-09-07/verify-before-done--2026-08-23-verify-before-done/provenance.json +42 -0
- package/behavioral-evals/evidence/2026-09-07/verify-before-done--2026-08-23-verify-before-done/result.sanitized.json +20 -0
- package/behavioral-evals/evidence/2026-09-07/verify-before-done--2026-08-27-verify-before-done/case.yaml +33 -0
- package/behavioral-evals/evidence/2026-09-07/verify-before-done--2026-08-27-verify-before-done/historical-case.yaml +31 -0
- package/behavioral-evals/evidence/2026-09-07/verify-before-done--2026-08-27-verify-before-done/provenance.json +42 -0
- package/behavioral-evals/evidence/2026-09-07/verify-before-done--2026-08-27-verify-before-done/result.sanitized.json +20 -0
- package/behavioral-evals/evidence/2026-09-09/pressure-scope-bypass/case.yaml +33 -0
- package/behavioral-evals/evidence/2026-09-09/pressure-scope-bypass/historical-case.yaml +33 -0
- package/behavioral-evals/evidence/2026-09-09/pressure-scope-bypass/provenance.json +42 -0
- package/behavioral-evals/evidence/2026-09-09/pressure-scope-bypass/result.sanitized.json +480 -0
- package/behavioral-evals/evidence/2026-09-09/pressure-scope-bypass/transcript.sanitized.jsonl +95 -0
- package/behavioral-evals/evidence-tool.js +443 -0
- package/behavioral-evals/fixtures/claude-denied.jsonl +3 -0
- package/behavioral-evals/fixtures/claude-legacy.json +1 -0
- package/behavioral-evals/fixtures/claude-oral-only.jsonl +2 -0
- package/behavioral-evals/fixtures/claude-success.jsonl +5 -0
- package/behavioral-evals/fixtures/claude-truncated.jsonl +3 -0
- package/behavioral-evals/fixtures/opencode-success.jsonl +6 -0
- package/behavioral-evals/results/2026-08-31-baseline-add-feature.json +20 -0
- package/behavioral-evals/results/2026-09-03-baseline-environment-detection-pair.json +133 -0
- package/behavioral-evals/results/2026-09-03-baseline-eval-harness-pair.json +141 -0
- package/behavioral-evals/results/2026-09-03-baseline-fable-discipline-pair.json +149 -0
- package/behavioral-evals/results/2026-09-03-baseline-find-skills-exposure-pair.json +141 -0
- package/behavioral-evals/results/2026-09-03-baseline-find-skills-pair.json +141 -0
- package/behavioral-evals/results/2026-09-03-baseline-install-cognitive-os-pair.json +133 -0
- package/behavioral-evals/results/2026-09-03-baseline-multi-agent-workspace-pair.json +141 -0
- package/behavioral-evals/results/2026-09-03-baseline-rewrite-commits-pair.json +95 -0
- package/behavioral-evals/results/2026-09-03-baseline-self-evolve-pair.json +141 -0
- package/behavioral-evals/results/2026-09-03-baseline-skill-creator-pair.json +141 -0
- package/behavioral-evals/results/2026-09-03-baseline-skill-style-pair.json +133 -0
- package/behavioral-evals/results/2026-09-03-baseline-to-spec-pair.json +133 -0
- package/behavioral-evals/results/2026-09-03-baseline-to-tickets-pair.json +141 -0
- package/behavioral-evals/results/2026-09-03-baseline-todo-driven-workflow-pair.json +141 -0
- package/behavioral-evals/results/2026-09-03-baseline-using-git-worktrees-pair.json +133 -0
- package/behavioral-evals/results/2026-09-03-summary-both.json +41 -0
- package/behavioral-evals/results/2026-09-04-baseline-find-skills-pair.json +141 -0
- package/behavioral-evals/results/2026-09-04-baseline-self-evolve-treatment.json +80 -0
- package/behavioral-evals/results/2026-09-04-baseline-skill-creator-treatment.json +80 -0
- package/behavioral-evals/results/2026-09-04-summary-both.json +41 -0
- package/behavioral-evals/run-with-plugin.js +15 -31
- package/behavioral-evals/run.js +446 -105
- package/behavioral-evals/transcript-parser.js +591 -0
- package/bin/cli.js +24 -12
- package/ci/ab-test-cases/grill-me-adversarial.yaml +14 -4
- package/ci/ab-test-cases/tdd-test-first.yaml +13 -6
- package/ci/ab-test-cases/verification-loop-gates.yaml +20 -7
- package/ci/ab-test-cases/verify-before-claim-cites.yaml +7 -6
- package/ci/ab-test-harness.js +113 -38
- package/ci/action-gate-platform-doc.test.js +31 -0
- package/ci/action-gate.test.js +260 -0
- package/ci/cases/case2.json +2 -2
- package/ci/consistency-check.js +51 -5
- package/ci/description-collision.js +15 -6
- package/ci/disclosure-check.js +225 -0
- package/ci/doc-capability-consistency.test.js +180 -0
- package/ci/fixtures/phase4/parallel-disjoint.stages.json +32 -0
- package/ci/fixtures/phase4/parallel-read-only.stages.json +32 -0
- package/ci/installer-roundtrip.test.js +159 -0
- package/ci/invariant-routing.test.js +74 -0
- package/ci/issue99-runtime.test.js +218 -0
- package/ci/mechanism-2aa-codex-action-gate-policy.test.js +117 -0
- package/ci/mechanism-2ab-openai-plugin-sync-integrity.test.js +80 -0
- package/ci/mechanism-2j-behavioral-runner.test.js +43 -1
- package/ci/mechanism-2k-reference-check.test.js +57 -2
- package/ci/mechanism-2l-multi-agent-workspace.test.js +202 -6
- package/ci/mechanism-2m-self-repo-guard.test.js +65 -0
- package/ci/mechanism-2n-opencode-plugin.test.js +461 -0
- package/ci/mechanism-2o-state-home-isolation.test.js +183 -0
- package/ci/mechanism-2p-installer-links.test.js +183 -0
- package/ci/mechanism-2q-installer-global-shared-store.test.js +132 -0
- package/ci/mechanism-2r-uninstall-flags.test.js +148 -0
- package/ci/mechanism-2s-tdd-quality.test.js +203 -0
- package/ci/mechanism-2t-disclosure.test.js +90 -0
- package/ci/mechanism-2t-evidence-triage.test.js +200 -0
- package/ci/mechanism-2t-issue-20.test.js +75 -0
- package/ci/mechanism-2t-platform-skill-targets.test.js +164 -0
- package/ci/mechanism-2t-transcript-parser.test.js +179 -0
- package/ci/mechanism-2t-workspace-identity.test.js +200 -0
- package/ci/mechanism-2u-issue-42-regressions.test.js +239 -0
- package/ci/mechanism-2u-issue-44.test.js +35 -0
- package/ci/mechanism-2v-verifier-boundaries.test.js +138 -0
- package/ci/mechanism-2w-platform-compatibility.test.js +148 -0
- package/ci/mechanism-2x-release-automation.test.js +157 -0
- package/ci/mechanism-2x-release-commit-message.test.js +66 -0
- package/ci/mechanism-2y-release-tooling-compat.test.js +47 -0
- package/ci/mechanism-2z-claude-plugin-manifest.test.js +29 -0
- package/ci/mutation-check.js +53 -0
- package/ci/mutation-loader.js +57 -0
- package/ci/negative-controls.js +76 -46
- package/ci/openai-plugin-package.test.js +182 -0
- package/ci/openai-plugin-runtime.test.js +175 -0
- package/ci/openai-plugin-submission.test.js +101 -0
- package/ci/phase4-ensemble-memory.test.js +307 -0
- package/ci/reference-check.js +73 -25
- package/ci/release-consistency-check.js +24 -1
- package/ci/router-phase2-safety.test.js +81 -0
- package/ci/router-workflow-plan.test.js +264 -0
- package/ci/routing-check.js +6 -5
- package/ci/runner.js +6 -5
- package/ci/skill-routing-check.js +48 -11
- package/ci/test-behavioral-case-validation.js +62 -0
- package/ci/test-helper.js +10 -0
- package/ci/workflow-plan-consumers-edge.test.js +72 -0
- package/ci/workflow-plan-consumers.test.js +276 -0
- package/docs/architecture.md +137 -57
- package/docs/audit.md +22 -20
- package/docs/codex-action-gate.md +90 -0
- package/docs/issue-20-rollup.md +47 -0
- package/docs/mechanism-first-skill-mesh.md +22 -20
- package/docs/openai-plugin.md +118 -0
- package/docs/philosophy.md +28 -17
- package/docs/platform-capabilities.md +73 -0
- package/docs/platform-compatibility.json +270 -0
- package/docs/reflection.md +37 -22
- package/docs/release-evidence.md +25 -0
- package/docs/routing.md +157 -44
- package/docs/security-audit.md +38 -0
- package/docs/troubleshooting.md +82 -46
- package/docs/verifier-boundaries.md +45 -0
- package/docs/workflows/fable-mode.md +77 -21
- package/docs/workflows/find-skills.md +40 -0
- package/docs/workflows/grill-with-docs.md +2 -2
- package/docs/workflows/multi-agent-workspace.md +22 -10
- package/docs/workflows/self-evolve.md +33 -0
- package/docs/workflows/tdd.md +36 -0
- package/docs/workflows/todo-driven-workflow.md +33 -0
- package/environment-detection/SKILL.md +3 -3
- package/eval-harness/SKILL.md +7 -7
- package/eval-harness/scripts/evaluate.js +12 -10
- package/evals/evaluation-reports.md +14 -0
- package/evals/harness-everything/tasks/positive-tier1.yaml +1 -1
- package/evals/harness-everything/tasks/positive-tier2.yaml +1 -1
- package/evals/harness-everything/tasks/positive-tier3.yaml +1 -1
- package/evals/install-cognitive-os/tasks/positive-trigger.yaml +1 -1
- package/fable-discipline/SKILL.md +2 -2
- package/fable-mode/CONTRACT-FORMAT.md +147 -33
- package/fable-mode/SKILL.md +3 -3
- package/fable-mode/agents/fable-orchestrator.md +95 -35
- package/fable-mode/execution-guardrails/SKILL.md +2 -2
- package/fable-mode/fable-haiku/SKILL.md +3 -3
- package/fable-mode/fable-opus/SKILL.md +3 -3
- package/fable-mode/fable-sonnet/SKILL.md +3 -3
- package/fable-mode/scripts/ensemble-review.js +371 -0
- package/fable-mode/scripts/model-selector.js +134 -3
- package/fable-mode/scripts/workflow-plan-consumer.js +337 -0
- package/find-skills/SKILL.md +5 -5
- package/find-skills/references/discovery-flow.md +1 -1
- package/find-skills/scripts/use-skill.js +7 -1
- package/git-commit/SKILL.md +4 -11
- package/grill-me/SKILL.md +5 -5
- package/grill-with-docs/SKILL.md +7 -7
- package/grill-with-docs/references/session-playbook.md +6 -4
- package/harness-everything/SKILL.md +23 -22
- package/harness-everything/references/router-workflow-plan.md +128 -0
- package/harness-everything/references/triage-and-tiers.md +173 -96
- package/harness-everything/schemas/router-task-shape.schema.json +126 -0
- package/harness-everything/schemas/router-workflow-plan.schema.json +149 -0
- package/harness-everything/scripts/bootstrap.js +13 -4
- package/harness-everything/scripts/ensemble-policy.js +102 -0
- package/harness-everything/scripts/kernel-router.js +212 -0
- package/harness-everything/scripts/router-contract.js +612 -0
- package/harness-everything/scripts/self-heal.js +29 -20
- package/harness-everything/scripts/tier-router.js +346 -221
- package/hooks/hooks.json +60 -15
- package/hooks/scripts/action-gate-rules.json +77 -0
- package/hooks/scripts/action-gate.js +528 -0
- package/hooks/scripts/atomic-commit-check.js +5 -5
- package/hooks/scripts/codex-action-gate-post.js +46 -0
- package/hooks/scripts/codex-permission-request.js +140 -0
- package/hooks/scripts/context-compact.js +4 -3
- package/hooks/scripts/contract-test.js +118 -51
- package/hooks/scripts/lib/fable-contracts.js +121 -0
- package/hooks/scripts/lib/harness-state.js +164 -28
- package/hooks/scripts/lib/platforms/claude.js +45 -62
- package/hooks/scripts/lib/platforms/codex.js +35 -61
- package/hooks/scripts/lib/platforms/continue.js +7 -7
- package/hooks/scripts/lib/platforms/copilot.js +29 -53
- package/hooks/scripts/lib/platforms/hermes.js +71 -20
- package/hooks/scripts/openai-session-start.js +81 -0
- package/hooks/scripts/rule-of-3-tracker.js +9 -8
- package/hooks/scripts/rule-of-3.js +29 -21
- package/hooks/scripts/state-persist.js +5 -4
- package/hooks/scripts/stop-gate.js +2 -2
- package/hooks/scripts/subagent-scope-guard.js +144 -38
- package/hooks/scripts/subagent-start.js +19 -0
- package/hooks/scripts/subagent-stop.js +6 -0
- package/improve-codebase-architecture/SKILL.md +2 -4
- package/improve-codebase-architecture/references/README.md +16 -0
- package/install-cognitive-os/SKILL.md +28 -22
- package/multi-agent-workspace/SKILL.md +16 -15
- package/multi-agent-workspace/references/architecture-guide.md +13 -9
- package/multi-agent-workspace/references/orchestration.md +39 -22
- package/multi-agent-workspace/scripts/consume-workflow-plan.js +129 -0
- package/multi-agent-workspace/scripts/index_memory.js +79 -26
- package/multi-agent-workspace/scripts/path-boundary.js +59 -0
- package/multi-agent-workspace/scripts/project-docs-resolver.js +357 -0
- package/multi-agent-workspace/scripts/scaffold.js +258 -103
- package/multi-agent-workspace/templates/AGENTS.md +20 -0
- package/multi-agent-workspace/workflows/03-generation.md +8 -10
- package/multi-agent-workspace/workflows/04-launcher.md +5 -5
- package/opencode-plugin/README.md +114 -71
- package/opencode-plugin/hooks/verify.js +62 -12
- package/opencode-plugin/index.mjs +547 -0
- package/opencode-plugin/plugin.json +4 -12
- package/package.json +16 -3
- package/plugins/harness-everything/.codex-plugin/plugin.json +39 -0
- package/plugins/harness-everything/hooks/hooks.json +197 -0
- package/plugins/harness-everything/hooks/scripts/action-gate-rules.json +77 -0
- package/plugins/harness-everything/hooks/scripts/action-gate.js +528 -0
- package/plugins/harness-everything/hooks/scripts/atomic-commit-check.js +68 -0
- package/plugins/harness-everything/hooks/scripts/boundary-guard.js +55 -0
- package/plugins/harness-everything/hooks/scripts/codex-action-gate-post.js +46 -0
- package/plugins/harness-everything/hooks/scripts/codex-permission-request.js +140 -0
- package/plugins/harness-everything/hooks/scripts/context-compact.js +115 -0
- package/plugins/harness-everything/hooks/scripts/contract-test.js +146 -0
- package/plugins/harness-everything/hooks/scripts/depth-guard.js +65 -0
- package/plugins/harness-everything/hooks/scripts/lib/fable-contracts.js +121 -0
- package/plugins/harness-everything/hooks/scripts/lib/harness-state.js +275 -0
- package/plugins/harness-everything/hooks/scripts/lib/platforms/claude.js +168 -0
- package/plugins/harness-everything/hooks/scripts/lib/platforms/codex.js +88 -0
- package/plugins/harness-everything/hooks/scripts/lib/platforms/continue.js +91 -0
- package/plugins/harness-everything/hooks/scripts/lib/platforms/copilot.js +85 -0
- package/plugins/harness-everything/hooks/scripts/lib/platforms/cursor.js +89 -0
- package/plugins/harness-everything/hooks/scripts/lib/platforms/hermes.js +108 -0
- package/plugins/harness-everything/hooks/scripts/lib/platforms/index.js +17 -0
- package/plugins/harness-everything/hooks/scripts/lib/platforms/worktrees.js +20 -0
- package/plugins/harness-everything/hooks/scripts/lib/workspace.js +290 -0
- package/plugins/harness-everything/hooks/scripts/openai-session-start.js +81 -0
- package/plugins/harness-everything/hooks/scripts/reset-circuit-breaker.js +30 -0
- package/plugins/harness-everything/hooks/scripts/rule-of-3-tracker.js +125 -0
- package/plugins/harness-everything/hooks/scripts/rule-of-3.js +195 -0
- package/plugins/harness-everything/hooks/scripts/state-persist.js +100 -0
- package/plugins/harness-everything/hooks/scripts/stop-gate.js +80 -0
- package/plugins/harness-everything/hooks/scripts/subagent-scope-guard.js +194 -0
- package/plugins/harness-everything/hooks/scripts/subagent-start.js +19 -0
- package/plugins/harness-everything/hooks/scripts/subagent-stop.js +6 -0
- package/plugins/harness-everything/hooks/session-start.js +81 -0
- package/plugins/harness-everything/plugin.json +43 -0
- package/plugins/harness-everything/scripts/lib/advisory-text.js +174 -0
- package/plugins/harness-everything/skills/environment-detection/SKILL.md +41 -0
- package/plugins/harness-everything/skills/environment-detection/references/shell-syntax-rules.md +76 -0
- package/plugins/harness-everything/skills/environment-detection/scripts/preflight.js +103 -0
- package/plugins/harness-everything/skills/eval-harness/SKILL.md +42 -0
- package/plugins/harness-everything/skills/eval-harness/references/scoring-rubric.md +68 -0
- package/plugins/harness-everything/skills/eval-harness/scripts/evaluate.js +79 -0
- package/plugins/harness-everything/skills/fable-discipline/SKILL.md +41 -0
- package/plugins/harness-everything/skills/fable-discipline/references/discipline-rules.md +22 -0
- package/plugins/harness-everything/skills/fable-mode/CONTRACT-FORMAT.md +165 -0
- package/plugins/harness-everything/skills/fable-mode/SKILL.md +39 -0
- package/plugins/harness-everything/skills/fable-mode/agents/fable-orchestrator.md +159 -0
- package/plugins/harness-everything/skills/fable-mode/agents/fable-verifier.md +32 -0
- package/plugins/harness-everything/skills/fable-mode/agents/fable-worker-haiku.md +52 -0
- package/plugins/harness-everything/skills/fable-mode/agents/fable-worker-sonnet.md +53 -0
- package/plugins/harness-everything/skills/fable-mode/execution-guardrails/SKILL.md +43 -0
- package/plugins/harness-everything/skills/fable-mode/execution-guardrails/references/guardrail-rules.md +56 -0
- package/plugins/harness-everything/skills/fable-mode/fable-haiku/SKILL.md +36 -0
- package/plugins/harness-everything/skills/fable-mode/fable-haiku/references/routing-notes.md +26 -0
- package/plugins/harness-everything/skills/fable-mode/fable-opus/SKILL.md +36 -0
- package/plugins/harness-everything/skills/fable-mode/fable-sonnet/SKILL.md +36 -0
- package/plugins/harness-everything/skills/fable-mode/model-matrix.json +32 -0
- package/plugins/harness-everything/skills/fable-mode/references/execution-phases.md +37 -0
- package/plugins/harness-everything/skills/fable-mode/references/model-matrix.md +39 -0
- package/plugins/harness-everything/skills/fable-mode/scripts/ensemble-review.js +371 -0
- package/plugins/harness-everything/skills/fable-mode/scripts/model-selector.js +260 -0
- package/plugins/harness-everything/skills/fable-mode/scripts/workflow-plan-consumer.js +337 -0
- package/plugins/harness-everything/skills/find-skills/SKILL.md +48 -0
- package/plugins/harness-everything/skills/find-skills/references/discovery-flow.md +102 -0
- package/plugins/harness-everything/skills/find-skills/scripts/use-skill.js +112 -0
- package/plugins/harness-everything/skills/git-commit/SKILL.md +38 -0
- package/plugins/harness-everything/skills/git-commit/guides/ANGULAR_STYLE.md +61 -0
- package/plugins/harness-everything/skills/git-commit/guides/COMMIT_GENERATION.md +24 -0
- package/plugins/harness-everything/skills/git-commit/guides/LANGUAGE_DETECTION.md +16 -0
- package/plugins/harness-everything/skills/git-commit/guides/MAIN_REPO.md +15 -0
- package/plugins/harness-everything/skills/git-commit/guides/SUBMODULES.md +27 -0
- package/plugins/harness-everything/skills/git-commit/references/commit-flow.md +30 -0
- package/plugins/harness-everything/skills/grill-me/SKILL.md +43 -0
- package/plugins/harness-everything/skills/grill-me/references/grilling-playbook.md +38 -0
- package/plugins/harness-everything/skills/grill-with-docs/ADR-FORMAT.md +47 -0
- package/plugins/harness-everything/skills/grill-with-docs/CONTEXT-FORMAT.md +63 -0
- package/plugins/harness-everything/skills/grill-with-docs/SKILL.md +41 -0
- package/plugins/harness-everything/skills/grill-with-docs/references/session-playbook.md +99 -0
- package/plugins/harness-everything/skills/harness-everything/SKILL.md +43 -0
- package/plugins/harness-everything/skills/harness-everything/examples/README.md +9 -0
- package/plugins/harness-everything/skills/harness-everything/examples/todo-workflow.md +22 -0
- package/plugins/harness-everything/skills/harness-everything/references/router-workflow-plan.md +128 -0
- package/plugins/harness-everything/skills/harness-everything/references/skill-registry.md +39 -0
- package/plugins/harness-everything/skills/harness-everything/references/triage-and-tiers.md +193 -0
- package/plugins/harness-everything/skills/harness-everything/schemas/router-task-shape.schema.json +126 -0
- package/plugins/harness-everything/skills/harness-everything/schemas/router-workflow-plan.schema.json +149 -0
- package/plugins/harness-everything/skills/harness-everything/scripts/bootstrap.js +212 -0
- package/plugins/harness-everything/skills/harness-everything/scripts/ensemble-policy.js +102 -0
- package/plugins/harness-everything/skills/harness-everything/scripts/kernel-router.js +212 -0
- package/plugins/harness-everything/skills/harness-everything/scripts/router-contract.js +612 -0
- package/plugins/harness-everything/skills/harness-everything/scripts/routing-keywords.json +320 -0
- package/plugins/harness-everything/skills/harness-everything/scripts/self-heal.js +250 -0
- package/plugins/harness-everything/skills/harness-everything/scripts/tier-router.js +459 -0
- package/plugins/harness-everything/skills/harness-everything/scripts/verify-gate.js +100 -0
- package/plugins/harness-everything/skills/improve-codebase-architecture/SKILL.md +38 -0
- package/plugins/harness-everything/skills/improve-codebase-architecture/guides/DEEPENING.md +37 -0
- package/plugins/harness-everything/skills/improve-codebase-architecture/guides/HTML-REPORT.md +123 -0
- package/plugins/harness-everything/skills/improve-codebase-architecture/guides/INTERFACE-DESIGN.md +44 -0
- package/plugins/harness-everything/skills/improve-codebase-architecture/guides/LANGUAGE.md +53 -0
- package/plugins/harness-everything/skills/improve-codebase-architecture/guides/refactoring-workflow.md +59 -0
- package/plugins/harness-everything/skills/improve-codebase-architecture/references/README.md +16 -0
- package/plugins/harness-everything/skills/install-cognitive-os/SKILL.md +44 -0
- package/plugins/harness-everything/skills/install-cognitive-os/references/cognitive-loop.md +27 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/NOTICE-agency-agents.md +27 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/SKILL.md +38 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/examples/csharp-monorepo.md +123 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/examples/typescript-cli.md +126 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/guidelines/platform-claude.md +77 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/guidelines/platform-codex.md +146 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/guidelines/platform-continue.md +38 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/guidelines/platform-copilot.md +74 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/guidelines/platform-cursor.md +40 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/guidelines/platform-hermes.md +38 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/guidelines/role-capabilities.md +108 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/references/agency-agents.md +31 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/references/architecture-guide.md +36 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/references/orchestration.md +65 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/scripts/agency-catalog.js +190 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/scripts/consume-workflow-plan.js +129 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/scripts/index_memory.js +104 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/scripts/path-boundary.js +59 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/scripts/project-docs-resolver.js +357 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/scripts/scaffold.js +408 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/templates/AGENTS.md +20 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/templates/README.md +17 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/templates/agent-launcher.md +68 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/templates/backend-developer-csharp.md +56 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/templates/backend-developer-polyglot.md +62 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/templates/backend-developer-ts.md +57 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/templates/memory-keeper.md +37 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/templates/requirement-analyzer.md +66 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/templates/specialist-agent.md +34 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/templates/task-verifier.md +56 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/templates/tool-maker.md +33 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/workflows/01-init.md +22 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/workflows/02-analysis.md +23 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/workflows/03-generation.md +25 -0
- package/plugins/harness-everything/skills/multi-agent-workspace/workflows/04-launcher.md +16 -0
- package/plugins/harness-everything/skills/repo-docs/SKILL.md +42 -0
- package/plugins/harness-everything/skills/repo-docs/references/process-guide.md +60 -0
- package/plugins/harness-everything/skills/repo-docs/templates/agents-template.md +264 -0
- package/plugins/harness-everything/skills/repo-docs/templates/knowledge-agents-template.md +50 -0
- package/plugins/harness-everything/skills/repo-docs/templates/knowledge-readme-template.md +83 -0
- package/plugins/harness-everything/skills/repo-docs/templates/manual-recon.md +117 -0
- package/plugins/harness-everything/skills/repo-docs/templates/multi-skills-readme-template.md +72 -0
- package/plugins/harness-everything/skills/repo-docs/templates/product-agents-template.md +78 -0
- package/plugins/harness-everything/skills/repo-docs/templates/product-readme-template.md +95 -0
- package/plugins/harness-everything/skills/repo-docs/templates/readme-template.md +136 -0
- package/plugins/harness-everything/skills/repo-docs/templates/single-skill-readme-template.md +70 -0
- package/plugins/harness-everything/skills/repo-docs/templates/skills-agents-template.md +60 -0
- package/plugins/harness-everything/skills/rewrite-commits/SKILL.md +37 -0
- package/plugins/harness-everything/skills/rewrite-commits/references/workflow.md +18 -0
- package/plugins/harness-everything/skills/security-review/SKILL.md +47 -0
- package/plugins/harness-everything/skills/security-review/guides/OWASP-PATTERNS.md +31 -0
- package/plugins/harness-everything/skills/security-review/guides/STRIDE-THREAT-MODEL.md +21 -0
- package/plugins/harness-everything/skills/security-review/references/security-checklist.md +478 -0
- package/plugins/harness-everything/skills/security-review/scripts/audit-secrets.js +85 -0
- package/plugins/harness-everything/skills/self-evolve/SKILL.md +45 -0
- package/plugins/harness-everything/skills/self-evolve/references/memory-resolution.md +61 -0
- package/plugins/harness-everything/skills/self-evolve/scripts/persist-memory.js +272 -0
- package/plugins/harness-everything/skills/self-evolve/scripts/register-dynamic-skill.js +253 -0
- package/plugins/harness-everything/skills/self-evolve/scripts/self-regression.js +125 -0
- package/plugins/harness-everything/skills/skill-creator/SKILL.md +47 -0
- package/plugins/harness-everything/skills/skill-creator/references/authoring-workflow.md +14 -0
- package/plugins/harness-everything/skills/skill-creator/references/dynamic-generation-contract.md +21 -0
- package/plugins/harness-everything/skills/skill-creator/references/quality-checklist.md +16 -0
- package/plugins/harness-everything/skills/skill-creator/references/quality-principles.md +81 -0
- package/plugins/harness-everything/skills/skill-creator/references/testing-workflow.md +27 -0
- package/plugins/harness-everything/skills/skill-style/SKILL.md +42 -0
- package/plugins/harness-everything/skills/skill-style/references/style-guide.md +62 -0
- package/plugins/harness-everything/skills/tdd/SKILL.md +38 -0
- package/plugins/harness-everything/skills/tdd/fixtures/pass-evidence.json +100 -0
- package/plugins/harness-everything/skills/tdd/fixtures/quality-scenarios.json +20 -0
- package/plugins/harness-everything/skills/tdd/guides/deep-modules.md +33 -0
- package/plugins/harness-everything/skills/tdd/guides/interface-design.md +31 -0
- package/plugins/harness-everything/skills/tdd/guides/mocking.md +59 -0
- package/plugins/harness-everything/skills/tdd/guides/refactoring.md +10 -0
- package/plugins/harness-everything/skills/tdd/guides/tests.md +61 -0
- package/plugins/harness-everything/skills/tdd/references/core-discipline.md +51 -0
- package/plugins/harness-everything/skills/tdd/references/integration-testing.md +13 -0
- package/plugins/harness-everything/skills/tdd/references/quality-model.md +68 -0
- package/plugins/harness-everything/skills/tdd/references/unit-testing.md +15 -0
- package/plugins/harness-everything/skills/tdd/schemas/quality-evidence.schema.json +211 -0
- package/plugins/harness-everything/skills/tdd/schemas/quality-report.schema.json +110 -0
- package/plugins/harness-everything/skills/tdd/scripts/quality-gate.js +475 -0
- package/plugins/harness-everything/skills/to-spec/SKILL.md +40 -0
- package/plugins/harness-everything/skills/to-spec/references/process.md +77 -0
- package/plugins/harness-everything/skills/to-spec/scripts/check-project-docs.js +239 -0
- package/plugins/harness-everything/skills/to-spec/scripts/project-docs-resolver.js +111 -0
- package/plugins/harness-everything/skills/to-spec/templates/cli-reference.md +31 -0
- package/plugins/harness-everything/skills/to-spec/templates/dev-doc.md +27 -0
- package/plugins/harness-everything/skills/to-spec/templates/feature-spec.md +59 -0
- package/plugins/harness-everything/skills/to-spec/templates/schema-doc.md +31 -0
- package/plugins/harness-everything/skills/to-tickets/SKILL.md +42 -0
- package/plugins/harness-everything/skills/to-tickets/references/publishing-and-templates.md +97 -0
- package/plugins/harness-everything/skills/todo-driven-workflow/SKILL.md +42 -0
- package/plugins/harness-everything/skills/todo-driven-workflow/references/execution-guide.md +27 -0
- package/plugins/harness-everything/skills/using-git-worktrees/SKILL.md +49 -0
- package/plugins/harness-everything/skills/using-git-worktrees/references/workflow-details.md +108 -0
- package/plugins/harness-everything/skills/verification-loop/SKILL.md +46 -0
- package/plugins/harness-everything/skills/verification-loop/references/verification-phases.md +116 -0
- package/plugins/harness-everything/skills/verification-loop/templates/verification-report.template.md +15 -0
- package/plugins/harness-everything/skills/verify-before-claim/SKILL.md +43 -0
- package/plugins/harness-everything/skills/verify-before-claim/references/verification-guide.md +73 -0
- package/plugins/harness-everything/skills/zoom-out/SKILL.md +42 -0
- package/plugins/harness-everything/skills/zoom-out/references/circuit-breaker.md +66 -0
- package/plugins/harness-everything/skills/zoom-out/templates/zoom-out-report.template.md +20 -0
- package/repo-docs/SKILL.md +3 -7
- package/rewrite-commits/SKILL.md +2 -2
- package/scripts/build-openai-submission.js +158 -0
- package/scripts/installer.js +86 -11
- package/scripts/lib/advisory-text.js +25 -18
- package/scripts/lib/execution-contract.js +70 -0
- package/scripts/lib/manifest.js +34 -38
- package/scripts/lib/path-boundary.js +90 -0
- package/scripts/lib/skills.js +124 -70
- package/scripts/lib/workspace.js +269 -7
- package/scripts/sync-openai-plugin.js +91 -0
- package/scripts/sync-release-version.js +212 -0
- package/security-review/SKILL.md +4 -7
- package/security-review/scripts/audit-secrets.js +9 -8
- package/self-evolve/SKILL.md +9 -11
- package/self-evolve/references/memory-resolution.md +4 -1
- package/self-evolve/scripts/persist-memory.js +221 -88
- package/self-evolve/scripts/register-dynamic-skill.js +12 -10
- package/self-evolve/scripts/self-regression.js +23 -8
- package/skill-creator/SKILL.md +12 -14
- package/skill-creator/references/quality-checklist.md +1 -0
- package/skill-style/SKILL.md +4 -4
- package/skill-style/references/style-guide.md +29 -3
- package/submission/openai/README.md +67 -0
- package/submission/openai/listing.json +31 -0
- package/submission/openai/test-cases.json +61 -0
- package/tdd/SKILL.md +20 -26
- package/tdd/fixtures/pass-evidence.json +100 -0
- package/tdd/fixtures/quality-scenarios.json +20 -0
- package/tdd/references/core-discipline.md +2 -0
- package/tdd/references/integration-testing.md +13 -0
- package/tdd/references/quality-model.md +68 -0
- package/tdd/references/unit-testing.md +15 -0
- package/tdd/schemas/quality-evidence.schema.json +211 -0
- package/tdd/schemas/quality-report.schema.json +110 -0
- package/tdd/scripts/quality-gate.js +475 -0
- package/to-spec/SKILL.md +3 -5
- package/to-spec/scripts/check-project-docs.js +42 -62
- package/to-spec/scripts/project-docs-resolver.js +111 -0
- package/to-tickets/SKILL.md +4 -4
- package/todo-driven-workflow/SKILL.md +6 -4
- package/using-git-worktrees/SKILL.md +3 -3
- package/verification-loop/SKILL.md +4 -4
- package/verify-before-claim/SKILL.md +2 -2
- package/zoom-out/SKILL.md +4 -4
- package/ab-test-deep-analysis-2026-08-27.md +0 -383
- package/ab-test-results-2026-08-27.md +0 -152
- package/ab-test-statistical-analysis-31cases.md +0 -193
- package/opencode-plugin/hooks/circuit-breaker.js +0 -121
- package/opencode-plugin/hooks/compliance.js +0 -128
- package/opencode-plugin/hooks/post-edit.js +0 -62
- package/opencode-plugin/hooks/pre-complete.js +0 -65
- package/opencode-plugin/test-hook-firing.js +0 -198
package/repo-docs/SKILL.md
CHANGED
|
@@ -4,7 +4,7 @@ description: Generate or update precise, reader-oriented README.md and AGENTS.md
|
|
|
4
4
|
license: Apache-2.0
|
|
5
5
|
metadata:
|
|
6
6
|
author: Miya Daniel
|
|
7
|
-
version: 0.
|
|
7
|
+
version: 0.4.0
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# Repo Docs (Automated Project Documentation Generation & Smart Merging)
|
|
@@ -37,10 +37,6 @@ Merges codebase scan facts and bespoke notes into `README.md`/`AGENTS.md`.
|
|
|
37
37
|
3. Pick a template below; else built-in structure.
|
|
38
38
|
4. Draft: `README.md` = user journey; `AGENTS.md` = conventions, build/test commands.
|
|
39
39
|
5. [Summarize] Verify commands run; mark doubts `// TODO: Pending confirmation`; ask (`grill-me`).
|
|
40
|
-
6. Write to root; if protected,
|
|
40
|
+
6. Write to root; if protected, `<workspace>/.github/AGENTS.md`/`<workspace>/docs/README.md`.
|
|
41
41
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
readme-template.md · product-readme-template.md · multi-skills-readme-template.md · single-skill-readme-template.md · knowledge-readme-template.md · agents-template.md · product-agents-template.md · skills-agents-template.md · knowledge-agents-template.md · manual-recon.md
|
|
45
|
-
|
|
46
|
-
Deep dive: references/process-guide.md
|
|
42
|
+
Deep dive: <this-skill-dir>/references/process-guide.md
|
package/rewrite-commits/SKILL.md
CHANGED
|
@@ -4,7 +4,7 @@ description: "Rewrite past Git history to comply with Angular Style conventions.
|
|
|
4
4
|
license: Apache-2.0
|
|
5
5
|
metadata:
|
|
6
6
|
author: Miya Daniel
|
|
7
|
-
version: 0.
|
|
7
|
+
version: 0.4.0
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# Rewrite Commits
|
|
@@ -34,4 +34,4 @@ metadata:
|
|
|
34
34
|
2. `[Think] & [Try]` Create a temp branch. Never run bare interactive `git rebase -i`; prefer `git reset --soft HEAD~<N>` plus structured commits, or Node.js scripting (no hardcoded `sed -i`). Messages MUST follow Angular Style per the `git-commit` skill.
|
|
35
35
|
3. `[Summarize]` Run `git log --oneline` for confirmation. On merge conflict, run `git rebase --abort`, STOP, and hand over to human decision or trigger `zoom-out`.
|
|
36
36
|
|
|
37
|
-
Deep dive: references/workflow.md
|
|
37
|
+
Deep dive: <this-skill-dir>/references/workflow.md
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
const crypto = require('crypto');
|
|
5
|
+
const fs = require('fs');
|
|
6
|
+
const path = require('path');
|
|
7
|
+
|
|
8
|
+
const ROOT = path.resolve(__dirname, '..');
|
|
9
|
+
const SKILLS_ROOT = path.join(ROOT, 'plugins', 'harness-everything', 'skills');
|
|
10
|
+
const DEFAULT_OUTPUT = path.join(ROOT, 'dist', 'openai-submission', 'harness-everything-skills.zip');
|
|
11
|
+
|
|
12
|
+
function parseArgs(argv) {
|
|
13
|
+
let output = DEFAULT_OUTPUT;
|
|
14
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
15
|
+
if (argv[i] === '--output') {
|
|
16
|
+
if (!argv[i + 1]) throw new Error('--output requires a path');
|
|
17
|
+
output = path.resolve(argv[++i]);
|
|
18
|
+
} else {
|
|
19
|
+
throw new Error(`unknown argument: ${argv[i]}`);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return { output };
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function filesUnder(root, base = root, out = []) {
|
|
26
|
+
for (const entry of fs.readdirSync(root, { withFileTypes: true })) {
|
|
27
|
+
const full = path.join(root, entry.name);
|
|
28
|
+
if (entry.isDirectory()) filesUnder(full, base, out);
|
|
29
|
+
else if (entry.isFile()) out.push(path.relative(base, full).replace(/\\/g, '/'));
|
|
30
|
+
}
|
|
31
|
+
return out.sort();
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const CRC_TABLE = (() => {
|
|
35
|
+
const table = new Uint32Array(256);
|
|
36
|
+
for (let n = 0; n < 256; n += 1) {
|
|
37
|
+
let c = n;
|
|
38
|
+
for (let k = 0; k < 8; k += 1) c = (c & 1) ? (0xedb88320 ^ (c >>> 1)) : (c >>> 1);
|
|
39
|
+
table[n] = c >>> 0;
|
|
40
|
+
}
|
|
41
|
+
return table;
|
|
42
|
+
})();
|
|
43
|
+
|
|
44
|
+
function crc32(buffer) {
|
|
45
|
+
let c = 0xffffffff;
|
|
46
|
+
for (const byte of buffer) c = CRC_TABLE[(c ^ byte) & 0xff] ^ (c >>> 8);
|
|
47
|
+
return (c ^ 0xffffffff) >>> 0;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function zipStored(entries) {
|
|
51
|
+
const localParts = [];
|
|
52
|
+
const centralParts = [];
|
|
53
|
+
let offset = 0;
|
|
54
|
+
|
|
55
|
+
for (const entry of entries) {
|
|
56
|
+
const name = Buffer.from(entry.name, 'utf8');
|
|
57
|
+
const data = entry.data;
|
|
58
|
+
const crc = crc32(data);
|
|
59
|
+
const local = Buffer.alloc(30);
|
|
60
|
+
local.writeUInt32LE(0x04034b50, 0);
|
|
61
|
+
local.writeUInt16LE(20, 4);
|
|
62
|
+
local.writeUInt16LE(0x0800, 6);
|
|
63
|
+
local.writeUInt16LE(0, 8);
|
|
64
|
+
local.writeUInt16LE(0, 10);
|
|
65
|
+
local.writeUInt16LE(33, 12); // 1980-01-01, 00:00:00
|
|
66
|
+
local.writeUInt32LE(crc, 14);
|
|
67
|
+
local.writeUInt32LE(data.length, 18);
|
|
68
|
+
local.writeUInt32LE(data.length, 22);
|
|
69
|
+
local.writeUInt16LE(name.length, 26);
|
|
70
|
+
local.writeUInt16LE(0, 28);
|
|
71
|
+
|
|
72
|
+
const central = Buffer.alloc(46);
|
|
73
|
+
central.writeUInt32LE(0x02014b50, 0);
|
|
74
|
+
central.writeUInt16LE(0x0314, 4); // ZIP 2.0, Unix creator
|
|
75
|
+
central.writeUInt16LE(20, 6);
|
|
76
|
+
central.writeUInt16LE(0x0800, 8);
|
|
77
|
+
central.writeUInt16LE(0, 10);
|
|
78
|
+
central.writeUInt16LE(0, 12);
|
|
79
|
+
central.writeUInt16LE(33, 14);
|
|
80
|
+
central.writeUInt32LE(crc, 16);
|
|
81
|
+
central.writeUInt32LE(data.length, 20);
|
|
82
|
+
central.writeUInt32LE(data.length, 24);
|
|
83
|
+
central.writeUInt16LE(name.length, 28);
|
|
84
|
+
central.writeUInt16LE(0, 30);
|
|
85
|
+
central.writeUInt16LE(0, 32);
|
|
86
|
+
central.writeUInt16LE(0, 34);
|
|
87
|
+
central.writeUInt16LE(0, 36);
|
|
88
|
+
const mode = entry.name.endsWith('.sh') ? 0o100755 : 0o100644;
|
|
89
|
+
central.writeUInt32LE((mode << 16) >>> 0, 38);
|
|
90
|
+
central.writeUInt32LE(offset, 42);
|
|
91
|
+
|
|
92
|
+
localParts.push(local, name, data);
|
|
93
|
+
centralParts.push(central, name);
|
|
94
|
+
offset += local.length + name.length + data.length;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const centralDirectory = Buffer.concat(centralParts);
|
|
98
|
+
const end = Buffer.alloc(22);
|
|
99
|
+
end.writeUInt32LE(0x06054b50, 0);
|
|
100
|
+
end.writeUInt16LE(0, 4);
|
|
101
|
+
end.writeUInt16LE(0, 6);
|
|
102
|
+
end.writeUInt16LE(entries.length, 8);
|
|
103
|
+
end.writeUInt16LE(entries.length, 10);
|
|
104
|
+
end.writeUInt32LE(centralDirectory.length, 12);
|
|
105
|
+
end.writeUInt32LE(offset, 16);
|
|
106
|
+
end.writeUInt16LE(0, 20);
|
|
107
|
+
|
|
108
|
+
return Buffer.concat([...localParts, centralDirectory, end]);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function sha256(buffer) {
|
|
112
|
+
return crypto.createHash('sha256').update(buffer).digest('hex');
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function build(output) {
|
|
116
|
+
if (!fs.existsSync(SKILLS_ROOT)) throw new Error(`packaged skills not found: ${SKILLS_ROOT}`);
|
|
117
|
+
const relativeFiles = filesUnder(SKILLS_ROOT);
|
|
118
|
+
if (relativeFiles.length === 0) throw new Error('no packaged skill files found');
|
|
119
|
+
|
|
120
|
+
const entries = relativeFiles.map(relative => {
|
|
121
|
+
const data = fs.readFileSync(path.join(SKILLS_ROOT, relative));
|
|
122
|
+
return { name: `skills/${relative}`, data };
|
|
123
|
+
});
|
|
124
|
+
const zip = zipStored(entries);
|
|
125
|
+
fs.mkdirSync(path.dirname(output), { recursive: true });
|
|
126
|
+
fs.writeFileSync(output, zip);
|
|
127
|
+
|
|
128
|
+
const manifest = {
|
|
129
|
+
format: 'harness-openai-skill-bundle-manifest-v1',
|
|
130
|
+
source: 'plugins/harness-everything/skills',
|
|
131
|
+
file_count: entries.length,
|
|
132
|
+
bundle_sha256: sha256(zip),
|
|
133
|
+
files: entries.map(entry => ({
|
|
134
|
+
path: entry.name,
|
|
135
|
+
bytes: entry.data.length,
|
|
136
|
+
sha256: sha256(entry.data)
|
|
137
|
+
}))
|
|
138
|
+
};
|
|
139
|
+
const manifestPath = output.replace(/\.zip$/i, '') + '.manifest.json';
|
|
140
|
+
fs.writeFileSync(manifestPath, `${JSON.stringify(manifest, null, 2)}\n`);
|
|
141
|
+
console.log(`OpenAI skill bundle: ${output}`);
|
|
142
|
+
console.log(`Files: ${manifest.file_count}`);
|
|
143
|
+
console.log(`SHA256: ${manifest.bundle_sha256}`);
|
|
144
|
+
console.log(`Manifest: ${manifestPath}`);
|
|
145
|
+
return { output, manifestPath, manifest };
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if (require.main === module) {
|
|
149
|
+
try {
|
|
150
|
+
const { output } = parseArgs(process.argv.slice(2));
|
|
151
|
+
build(output);
|
|
152
|
+
} catch (error) {
|
|
153
|
+
console.error(error.message);
|
|
154
|
+
process.exit(1);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
module.exports = { build, crc32, filesUnder, zipStored };
|
package/scripts/installer.js
CHANGED
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
const fs = require('fs');
|
|
27
27
|
const path = require('path');
|
|
28
28
|
|
|
29
|
-
const { getWorkspaceRoot, getUserPromptsDir } = require('./lib/workspace');
|
|
29
|
+
const { getWorkspaceRoot, getWorkspaceStateDir, getUserPromptsDir } = require('./lib/workspace');
|
|
30
30
|
const { interactiveSelect, interactiveSingleSelect, askQuestion } = require('./lib/prompts');
|
|
31
31
|
const advisory = require('./lib/advisory-text');
|
|
32
32
|
const claudeHooks = require('./lib/claude-hooks');
|
|
@@ -35,7 +35,12 @@ const skills = require('./lib/skills');
|
|
|
35
35
|
const { ensureWorkspaceGitignorePatterns, removeWorkspaceExcludePatterns, cleanEmptyDirs } = require('./lib/gitignore');
|
|
36
36
|
|
|
37
37
|
const userHome = require('os').homedir();
|
|
38
|
-
const
|
|
38
|
+
const detectedWorkspaceRoot = getWorkspaceRoot();
|
|
39
|
+
// Global installs are valid outside a repository, but the module still needs
|
|
40
|
+
// a non-null path while it evaluates local-detection helpers. Keep this
|
|
41
|
+
// fallback private to global mode; main() rejects non-global work from a
|
|
42
|
+
// directory whose workspace identity cannot be resolved.
|
|
43
|
+
const workspaceRoot = detectedWorkspaceRoot || path.resolve(process.cwd());
|
|
39
44
|
const harnessSourceDir = path.resolve(__dirname, '..');
|
|
40
45
|
const packageVersion = require(path.join(harnessSourceDir, 'package.json')).version;
|
|
41
46
|
|
|
@@ -65,7 +70,16 @@ async function main() {
|
|
|
65
70
|
// workspace - skill installation is an explicit user choice, never a
|
|
66
71
|
// side effect of a background repair.
|
|
67
72
|
const hasNoSkillsFlag = args.includes('--no-skills');
|
|
73
|
+
if (!detectedWorkspaceRoot && !hasGlobalFlag) {
|
|
74
|
+
throw new Error('cannot install locally outside a git workspace; pass --global for a user-wide install');
|
|
75
|
+
}
|
|
68
76
|
const hasAnyPlatformFlag = hasClaudeFlag || hasCursorFlag || hasCopilotFlag || hasCodexFlag || hasContinueFlag || hasHermesFlag || hasAllFlag;
|
|
77
|
+
// #49: default 'auto' tries a junction (Windows) / symlink (elsewhere) into
|
|
78
|
+
// one canonical per-scope copy and silently falls back to an independent
|
|
79
|
+
// physical copy per target if that fails. --copy/--symlink override the
|
|
80
|
+
// auto-detection explicitly - --symlink surfaces a link failure as an
|
|
81
|
+
// error instead of silently falling back, since the user asked for it.
|
|
82
|
+
const linkMode = args.includes('--copy') ? 'copy' : args.includes('--symlink') ? 'symlink' : 'auto';
|
|
69
83
|
|
|
70
84
|
let requestedSkills = ['add', 'skill', 'skills'].includes(command)
|
|
71
85
|
? args.slice(3).filter(arg => !arg.startsWith('-'))
|
|
@@ -263,7 +277,8 @@ async function main() {
|
|
|
263
277
|
}
|
|
264
278
|
|
|
265
279
|
console.log(`\nInstalling Harness skills:`);
|
|
266
|
-
skills.
|
|
280
|
+
const canonicalDir = skills.getCanonicalSkillsDir({ isGlobal, workspaceRoot, userHome });
|
|
281
|
+
skills.installSkillsToTargets({ chosenSkills, targetDirs, harnessSourceDir, packageVersion, canonicalDir, linkMode });
|
|
267
282
|
|
|
268
283
|
// Claude Code discovers named agents from .claude/agents/, not from a
|
|
269
284
|
// nested skill directory. Keep the source copies in fable-mode for plugin
|
|
@@ -297,6 +312,16 @@ async function main() {
|
|
|
297
312
|
if (targets.continue) patternsToIgnore.push('.continue/harness-everything/', '.continue/skills/');
|
|
298
313
|
}
|
|
299
314
|
|
|
315
|
+
// The local canonical skills store (#49) is new territory - .agents/
|
|
316
|
+
// wasn't previously a Harness-owned local directory - so it needs its
|
|
317
|
+
// own ignore pattern rather than relying on any platform's own list.
|
|
318
|
+
if (chosenSkills.length > 0 && linkMode !== 'copy') {
|
|
319
|
+
const canonicalDir = skills.getCanonicalSkillsDir({ isGlobal: false, workspaceRoot, userHome });
|
|
320
|
+
if (fs.existsSync(canonicalDir)) {
|
|
321
|
+
patternsToIgnore.push('.agents/skills/');
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
|
|
300
325
|
ensureWorkspaceGitignorePatterns(workspaceRoot, patternsToIgnore);
|
|
301
326
|
}
|
|
302
327
|
|
|
@@ -339,7 +364,29 @@ async function runUninstall({ hasYesFlag, args, isInteractive }) {
|
|
|
339
364
|
let removeGlobal = false;
|
|
340
365
|
let removeSkills = false;
|
|
341
366
|
|
|
342
|
-
const
|
|
367
|
+
const hasLocalFlag = args.includes('--local');
|
|
368
|
+
const hasGlobalUninstallFlag = args.includes('--global') || args.includes('-g');
|
|
369
|
+
const hasSkillsUninstallFlag = args.includes('--skills');
|
|
370
|
+
// #48: any explicit scope flag wins over the interactive menu, even with a
|
|
371
|
+
// TTY attached - so `uninstall --local --global --skills` actually does
|
|
372
|
+
// what it says instead of being silently swapped for the checkbox menu
|
|
373
|
+
// (where only -y previously had that effect). Only a truly bare `uninstall`
|
|
374
|
+
// (no flags at all) still goes interactive when a TTY is available.
|
|
375
|
+
const hasAnyScopeFlag = hasYesFlag || hasLocalFlag || hasGlobalUninstallFlag || hasSkillsUninstallFlag;
|
|
376
|
+
const runInteractively = isInteractive && !hasAnyScopeFlag;
|
|
377
|
+
|
|
378
|
+
if (!runInteractively && !hasAnyScopeFlag) {
|
|
379
|
+
// #48: no flags AND no interactive terminal to fall back on - this used
|
|
380
|
+
// to silently do nothing while still printing "UNINSTALL COMPLETE!".
|
|
381
|
+
// Fail loudly instead so a non-TTY invocation (npx in some shells/CI/
|
|
382
|
+
// piped input) never looks like a successful no-op.
|
|
383
|
+
console.error("\n❌ No scope specified and no interactive terminal detected.");
|
|
384
|
+
console.error(" Pass flags to say what to remove, e.g.:");
|
|
385
|
+
console.error(" uninstall --local --skills");
|
|
386
|
+
console.error(" uninstall --local --global --skills -y");
|
|
387
|
+
console.error(" ...or run this command in an interactive terminal to use the menu.");
|
|
388
|
+
process.exit(1);
|
|
389
|
+
}
|
|
343
390
|
|
|
344
391
|
if (runInteractively) {
|
|
345
392
|
const choices = [];
|
|
@@ -385,7 +432,7 @@ async function runUninstall({ hasYesFlag, args, isInteractive }) {
|
|
|
385
432
|
const chosenSkillsToRemove = await interactiveSelect(selectSkillItems);
|
|
386
433
|
for (const item of chosenSkillsToRemove) {
|
|
387
434
|
if (item.checked) {
|
|
388
|
-
skills.removeSkill(item._entry);
|
|
435
|
+
skills.removeSkill(item._entry, { workspaceRoot, userHome });
|
|
389
436
|
console.log(` ✅ Removed skill: ${item.name}`);
|
|
390
437
|
cleanEmptyDirs(item._entry.parentPath, [workspaceRoot, userHome]);
|
|
391
438
|
}
|
|
@@ -393,10 +440,6 @@ async function runUninstall({ hasYesFlag, args, isInteractive }) {
|
|
|
393
440
|
}
|
|
394
441
|
}
|
|
395
442
|
} else {
|
|
396
|
-
const hasLocalFlag = args.includes('--local');
|
|
397
|
-
const hasGlobalUninstallFlag = args.includes('--global') || args.includes('-g');
|
|
398
|
-
const hasSkillsUninstallFlag = args.includes('--skills');
|
|
399
|
-
|
|
400
443
|
if (hasYesFlag) {
|
|
401
444
|
// -y auto-confirms local (cwd-scoped, obviously "this project") but
|
|
402
445
|
// must NEVER auto-confirm global (~/.agents, ~/.claude, etc.) just
|
|
@@ -432,6 +475,11 @@ async function runUninstall({ hasYesFlag, args, isInteractive }) {
|
|
|
432
475
|
}
|
|
433
476
|
|
|
434
477
|
if (typeof platform.getStateDir === 'function') {
|
|
478
|
+
// Legacy per-workspace state dir (pre-#42) - almost always already
|
|
479
|
+
// gone by the time uninstall runs, since the first hook invocation
|
|
480
|
+
// after the fix migrates it into the global home below. Kept as a
|
|
481
|
+
// no-op-in-the-common-case safety net for a workspace that was
|
|
482
|
+
// never actually used since upgrading.
|
|
435
483
|
const stateDir = platform.getStateDir(workspaceRoot);
|
|
436
484
|
if (fs.existsSync(stateDir)) {
|
|
437
485
|
fs.rmSync(stateDir, { recursive: true, force: true });
|
|
@@ -440,6 +488,16 @@ async function runUninstall({ hasYesFlag, args, isInteractive }) {
|
|
|
440
488
|
}
|
|
441
489
|
}
|
|
442
490
|
|
|
491
|
+
// Runtime state for this workspace now lives outside it entirely, under
|
|
492
|
+
// ~/.agents/harness-everything/workspaces/<key>/ (issue #42) - remove
|
|
493
|
+
// this workspace's slice of it too, so uninstalling doesn't leave an
|
|
494
|
+
// orphaned global state dir behind.
|
|
495
|
+
const globalWorkspaceStateDir = getWorkspaceStateDir(workspaceRoot);
|
|
496
|
+
if (fs.existsSync(globalWorkspaceStateDir)) {
|
|
497
|
+
fs.rmSync(globalWorkspaceStateDir, { recursive: true, force: true });
|
|
498
|
+
console.log(` ✅ Removed global runtime state for this workspace (${globalWorkspaceStateDir})`);
|
|
499
|
+
}
|
|
500
|
+
|
|
443
501
|
// One-time migration cleanup: earlier versions used a self-invented
|
|
444
502
|
// top-level .harness/ directory for Claude's manifest + skill copies.
|
|
445
503
|
const legacyHarnessDir = path.join(workspaceRoot, '.harness');
|
|
@@ -513,8 +571,11 @@ async function runUninstall({ hasYesFlag, args, isInteractive }) {
|
|
|
513
571
|
console.log("Uninstalling all detected skills...");
|
|
514
572
|
console.log("-------------------------------------------------");
|
|
515
573
|
for (const skill of skillsToRemove) {
|
|
516
|
-
|
|
517
|
-
|
|
574
|
+
// pathPresent (not bare existsSync) so a dangling link - its canonical
|
|
575
|
+
// target already gone - still gets its manifest row cleaned up instead
|
|
576
|
+
// of being silently skipped forever.
|
|
577
|
+
if (skills.pathPresent(skill.dirPath)) {
|
|
578
|
+
skills.removeSkill(skill, { workspaceRoot, userHome });
|
|
518
579
|
console.log(` ✅ Removed skill: ${skill.id} (${skill.scope})`);
|
|
519
580
|
cleanEmptyDirs(skill.parentPath, [workspaceRoot, userHome]);
|
|
520
581
|
}
|
|
@@ -536,6 +597,20 @@ async function runUninstall({ hasYesFlag, args, isInteractive }) {
|
|
|
536
597
|
}
|
|
537
598
|
cleanEmptyDirs(path.join(workspaceRoot, '.claude'), [workspaceRoot, userHome]);
|
|
538
599
|
|
|
600
|
+
// Canonical skills store (#49) - removeSkill() above already deletes each
|
|
601
|
+
// now-unreferenced canonical copy as its last link goes; this just tidies
|
|
602
|
+
// up the now-empty .agents/skills/ (and .agents/ itself, if nothing else
|
|
603
|
+
// put anything there). Runs here rather than inside the removeLocal/
|
|
604
|
+
// removeGlobal blocks above because skill removal itself happens later,
|
|
605
|
+
// in the removeSkills block below those - running any earlier would find
|
|
606
|
+
// the directory still populated.
|
|
607
|
+
if (removeLocal) {
|
|
608
|
+
cleanEmptyDirs(skills.getCanonicalSkillsDir({ isGlobal: false, workspaceRoot, userHome }), [workspaceRoot, userHome]);
|
|
609
|
+
}
|
|
610
|
+
if (removeGlobal) {
|
|
611
|
+
cleanEmptyDirs(skills.getCanonicalSkillsDir({ isGlobal: true, workspaceRoot, userHome }), [userHome]);
|
|
612
|
+
}
|
|
613
|
+
|
|
539
614
|
console.log("\n🎉 UNINSTALL COMPLETE! Harness OS has been removed.");
|
|
540
615
|
console.log("=================================================");
|
|
541
616
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
// Prompt-injection-only guidance for platforms with no hook/execution
|
|
2
2
|
// mechanism (Cursor, Copilot, Codex, Continue, Hermes). Single source of
|
|
3
|
-
// truth for the advisory block
|
|
4
|
-
// installer.js's top level and again inside main().
|
|
3
|
+
// truth for the advisory block.
|
|
5
4
|
const fs = require('fs');
|
|
6
5
|
const path = require('path');
|
|
7
6
|
|
|
@@ -37,13 +36,25 @@ const advisoryInstructions = [
|
|
|
37
36
|
``
|
|
38
37
|
].join('\n');
|
|
39
38
|
|
|
39
|
+
function hasHarnessMarker(content) {
|
|
40
|
+
return typeof content === 'string' && content.includes(MARKER);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function assertHarnessOwnedOrAbsent(targetFile, label) {
|
|
44
|
+
if (!fs.existsSync(targetFile)) return;
|
|
45
|
+
const content = fs.readFileSync(targetFile, 'utf8');
|
|
46
|
+
if (!hasHarnessMarker(content)) {
|
|
47
|
+
throw new Error(`Refusing to overwrite pre-existing non-Harness ${label}: ${targetFile}`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
40
51
|
function injectAdvisoryText(targetFile, header, label) {
|
|
41
52
|
const dir = path.dirname(targetFile);
|
|
42
53
|
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
43
54
|
|
|
44
55
|
if (fs.existsSync(targetFile)) {
|
|
45
56
|
const content = fs.readFileSync(targetFile, 'utf8');
|
|
46
|
-
if (!content
|
|
57
|
+
if (!hasHarnessMarker(content)) {
|
|
47
58
|
fs.appendFileSync(targetFile, advisoryInstructions, 'utf8');
|
|
48
59
|
console.log(` ✅ Augmented existing ${label} with Harness guidance (advisory-only)`);
|
|
49
60
|
}
|
|
@@ -61,11 +72,8 @@ function removeAdvisoryText(targetFile) {
|
|
|
61
72
|
if (markerIndex !== -1) {
|
|
62
73
|
let cleanContent = content;
|
|
63
74
|
const hashMarkerIndex = content.lastIndexOf('#', markerIndex);
|
|
64
|
-
if (hashMarkerIndex !== -1)
|
|
65
|
-
|
|
66
|
-
} else {
|
|
67
|
-
cleanContent = content.substring(0, markerIndex).trim() + '\n';
|
|
68
|
-
}
|
|
75
|
+
if (hashMarkerIndex !== -1) cleanContent = content.substring(0, hashMarkerIndex).trim() + '\n';
|
|
76
|
+
else cleanContent = content.substring(0, markerIndex).trim() + '\n';
|
|
69
77
|
|
|
70
78
|
const lines = cleanContent.trim().split('\n').map(l => l.trim()).filter(l => l !== '');
|
|
71
79
|
if (lines.length === 0 || (lines.length === 1 && (lines[0] === '# Cursor Project Rules' || lines[0] === '# AGENTS.md' || lines[0] === '# Copilot Instructions' || lines[0] === '# .hermes.md'))) {
|
|
@@ -81,17 +89,13 @@ function removeAdvisoryText(targetFile) {
|
|
|
81
89
|
}
|
|
82
90
|
}
|
|
83
91
|
|
|
84
|
-
// Continue
|
|
85
|
-
//
|
|
86
|
-
// so - unlike the shared-file platforms above - Harness gets its own
|
|
87
|
-
// dedicated `harness.md` rule file instead of appending into an arbitrary
|
|
88
|
-
// pre-existing one.
|
|
92
|
+
// Continue gets a dedicated rule file. If a user already owns that exact
|
|
93
|
+
// path, do not replace it just because Harness chose the same filename.
|
|
89
94
|
function installContinueRule(targetFile, label) {
|
|
90
95
|
const dir = path.dirname(targetFile);
|
|
91
96
|
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
}
|
|
97
|
+
assertHarnessOwnedOrAbsent(targetFile, label);
|
|
98
|
+
if (fs.existsSync(targetFile) && hasHarnessMarker(fs.readFileSync(targetFile, 'utf8'))) return;
|
|
95
99
|
const content = [
|
|
96
100
|
`---`,
|
|
97
101
|
`name: Harness OS Guidance`,
|
|
@@ -108,7 +112,7 @@ function removeContinueRule(targetFile) {
|
|
|
108
112
|
if (!fs.existsSync(targetFile)) return;
|
|
109
113
|
try {
|
|
110
114
|
const content = fs.readFileSync(targetFile, 'utf8');
|
|
111
|
-
if (content
|
|
115
|
+
if (hasHarnessMarker(content)) {
|
|
112
116
|
fs.unlinkSync(targetFile);
|
|
113
117
|
console.log(` ✅ Removed Harness rule file: ${targetFile}`);
|
|
114
118
|
}
|
|
@@ -138,6 +142,7 @@ function buildCodexGlobalContent() {
|
|
|
138
142
|
`---`,
|
|
139
143
|
`# AGENTS.md`,
|
|
140
144
|
``,
|
|
145
|
+
`# ${MARKER}`,
|
|
141
146
|
`This file is advisory only - this platform has no hook/execution mechanism to`,
|
|
142
147
|
`enforce it mechanically (unlike Claude Code's hook-based circuit breaker). Treat`,
|
|
143
148
|
`these as strong defaults, not guarantees.`,
|
|
@@ -158,10 +163,12 @@ function buildCodexGlobalContent() {
|
|
|
158
163
|
module.exports = {
|
|
159
164
|
MARKER,
|
|
160
165
|
advisoryInstructions,
|
|
166
|
+
hasHarnessMarker,
|
|
167
|
+
assertHarnessOwnedOrAbsent,
|
|
161
168
|
injectAdvisoryText,
|
|
162
169
|
removeAdvisoryText,
|
|
163
170
|
installContinueRule,
|
|
164
171
|
removeContinueRule,
|
|
165
172
|
buildCopilotGlobalContent,
|
|
166
173
|
buildCodexGlobalContent,
|
|
167
|
-
};
|
|
174
|
+
};
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
|
|
3
|
+
function normalizeCommand(command) {
|
|
4
|
+
if (Array.isArray(command)) {
|
|
5
|
+
return command.map((part) => String(part));
|
|
6
|
+
}
|
|
7
|
+
if (typeof command !== 'string') return null;
|
|
8
|
+
return command.trim().replace(/\s+/g, ' ');
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function commandsEqual(actual, expected) {
|
|
12
|
+
const left = normalizeCommand(actual);
|
|
13
|
+
const right = normalizeCommand(expected);
|
|
14
|
+
if (Array.isArray(left) || Array.isArray(right)) {
|
|
15
|
+
return Array.isArray(left) && Array.isArray(right) &&
|
|
16
|
+
left.length === right.length && left.every((part, index) => part === right[index]);
|
|
17
|
+
}
|
|
18
|
+
return left !== null && left === right;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function commandTokens(command) {
|
|
22
|
+
if (typeof command !== 'string') return [];
|
|
23
|
+
return command.match(/"[^"]*"|'[^']*'|\S+/g) || [];
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function commandMatches(actual, expected) {
|
|
27
|
+
if (commandsEqual(actual, expected)) return true;
|
|
28
|
+
if (typeof actual !== 'string' || typeof expected !== 'string') return false;
|
|
29
|
+
const target = expected.trim();
|
|
30
|
+
if (!target || /\s/.test(target) || !/\.(?:c?js|mjs|py|sh|ps1|bat|cmd)$/i.test(target)) return false;
|
|
31
|
+
const expectedName = path.basename(target.replace(/\\/g, '/')).toLowerCase();
|
|
32
|
+
const tokens = commandTokens(actual).map((token) => token.replace(/^['"]|['"]$/g, ''));
|
|
33
|
+
if (tokens.length < 2) return false;
|
|
34
|
+
const launcher = path.basename(tokens[0].replace(/\\/g, '/')).toLowerCase();
|
|
35
|
+
if (!new Set(['node', 'node.exe', 'bun', 'bun.exe', 'deno', 'deno.exe', 'python', 'python.exe', 'python3', 'python3.exe', 'ruby', 'ruby.exe']).has(launcher)) return false;
|
|
36
|
+
return tokens.slice(1).some((token) => path.basename(token.replace(/\\/g, '/')).toLowerCase() === expectedName);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function normalizeRepoPath(value) {
|
|
40
|
+
if (typeof value !== 'string') return null;
|
|
41
|
+
const normalized = value.replace(/\\/g, '/').replace(/^\.\//, '');
|
|
42
|
+
const segments = normalized.split('/');
|
|
43
|
+
if (!normalized || normalized === '.' || path.posix.isAbsolute(normalized) || /^[A-Za-z]:\//.test(normalized) || segments.includes('..')) return null;
|
|
44
|
+
return normalized;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function extractPatchPaths(patchText) {
|
|
48
|
+
if (typeof patchText !== 'string') return [];
|
|
49
|
+
const paths = [];
|
|
50
|
+
const marker = /^\*\*\* (?:Update File|Add File|Delete File|Move to):\s*(.+?)\s*$/gm;
|
|
51
|
+
for (const match of patchText.matchAll(marker)) {
|
|
52
|
+
if (!paths.includes(match[1])) paths.push(match[1]);
|
|
53
|
+
}
|
|
54
|
+
return paths;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function patchPathsAuthorized(patchText, allowedPaths) {
|
|
58
|
+
const paths = extractPatchPaths(patchText).map(normalizeRepoPath);
|
|
59
|
+
const allowed = new Set(Array.from(allowedPaths || []).map(normalizeRepoPath));
|
|
60
|
+
return paths.length > 0 && paths.every((candidate) => candidate && allowed.has(candidate));
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
module.exports = {
|
|
64
|
+
commandMatches,
|
|
65
|
+
commandsEqual,
|
|
66
|
+
extractPatchPaths,
|
|
67
|
+
normalizeCommand,
|
|
68
|
+
normalizeRepoPath,
|
|
69
|
+
patchPathsAuthorized,
|
|
70
|
+
};
|