freeharness 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/NOTICE +108 -0
- package/README.md +134 -0
- package/canonical/HARVEST.yaml +858 -0
- package/canonical/PROVENANCE.yaml +740 -0
- package/canonical/agents/README.md +95 -0
- package/canonical/agents/agentic-architect.md +18 -0
- package/canonical/agents/database-reviewer.md +41 -0
- package/canonical/agents/explorer-ai-engineer-analyst.md +65 -0
- package/canonical/agents/pr-reviewer.md +96 -0
- package/canonical/agents/python-reviewer.md +55 -0
- package/canonical/agents/report-formatter.md +19 -0
- package/canonical/agents/security-reviewer.md +53 -0
- package/canonical/agents/test-writer.md +34 -0
- package/canonical/commands/fh-context.md +37 -0
- package/canonical/evals/promptfoo.redteam.yaml +108 -0
- package/canonical/hooks/cost-prices.json +14 -0
- package/canonical/hooks/freeharness-auto-memory.mjs +158 -0
- package/canonical/hooks/freeharness-config-guard.mjs +162 -0
- package/canonical/hooks/freeharness-context-monitor.mjs +198 -0
- package/canonical/hooks/freeharness-converge.mjs +227 -0
- package/canonical/hooks/freeharness-cost-tracker.mjs +1027 -0
- package/canonical/hooks/freeharness-memory-guard.mjs +57 -0
- package/canonical/hooks/freeharness-output-pruner.mjs +333 -0
- package/canonical/hooks/freeharness-precompact.mjs +323 -0
- package/canonical/hooks/freeharness-repeat-tool.mjs +208 -0
- package/canonical/hooks/freeharness-security-guidance.mjs +164 -0
- package/canonical/hooks/freeharness-session-start +583 -0
- package/canonical/hooks/hooks.auto-memory.claude-code.json +16 -0
- package/canonical/hooks/hooks.claude-code.json +17 -0
- package/canonical/hooks/hooks.config-guard.claude-code.json +16 -0
- package/canonical/hooks/hooks.context-monitor.claude-code.json +15 -0
- package/canonical/hooks/hooks.converge.claude-code.json +15 -0
- package/canonical/hooks/hooks.cost-tracker.claude-code.json +37 -0
- package/canonical/hooks/hooks.memory-guard.claude-code.json +16 -0
- package/canonical/hooks/hooks.output-pruner.claude-code.json +16 -0
- package/canonical/hooks/hooks.precompact.claude-code.json +15 -0
- package/canonical/hooks/hooks.repeat-tool.claude-code.json +25 -0
- package/canonical/hooks/hooks.security-guidance.claude-code.json +16 -0
- package/canonical/mcp/servers.json +20 -0
- package/canonical/openspec/config.base.yaml +89 -0
- package/canonical/openspec/schema.spec-driven.yaml +277 -0
- package/canonical/openspec/templates/data-contract.md +36 -0
- package/canonical/openspec/templates/design.md +84 -0
- package/canonical/openspec/templates/eval-plan.md +33 -0
- package/canonical/openspec/templates/follow-ups.md +2 -0
- package/canonical/openspec/templates/proposal.md +45 -0
- package/canonical/openspec/templates/spec.md +42 -0
- package/canonical/openspec/templates/tasks.md +38 -0
- package/canonical/profiles/local-llamacpp.LOCAL-MODELS.md +47 -0
- package/canonical/profiles/local-llamacpp.json +27 -0
- package/canonical/profiles/local-ollama.json +20 -0
- package/canonical/profiles/mcp.json +91 -0
- package/canonical/rules/CLAUDE.md +78 -0
- package/canonical/rules/project-CLAUDE.template.md +62 -0
- package/canonical/rules/routing.md +20 -0
- package/canonical/rules/safety.md +41 -0
- package/canonical/settings/settings.cache-hygiene.claude-code.json +5 -0
- package/canonical/skills/agent-evaluation/SKILL.md +102 -0
- package/canonical/skills/agent-evaluation/assets/evaluation_report_template.md +206 -0
- package/canonical/skills/agent-evaluation/evals/cases.yaml +106 -0
- package/canonical/skills/agent-evaluation/references/dataset-preparation.md +351 -0
- package/canonical/skills/agent-evaluation/references/scorers-constraints.md +165 -0
- package/canonical/skills/agent-evaluation/references/scorers.md +431 -0
- package/canonical/skills/agent-evaluation/references/setup-guide.md +252 -0
- package/canonical/skills/agent-evaluation/references/tracing-integration.md +164 -0
- package/canonical/skills/agent-evaluation/references/troubleshooting.md +514 -0
- package/canonical/skills/agent-evaluation/scripts/analyze_results.py +462 -0
- package/canonical/skills/agent-evaluation/scripts/create_dataset_template.py +382 -0
- package/canonical/skills/agent-evaluation/scripts/list_datasets.py +273 -0
- package/canonical/skills/agent-evaluation/scripts/run_evaluation_template.py +309 -0
- package/canonical/skills/agent-evaluation/scripts/setup_mlflow.py +353 -0
- package/canonical/skills/agent-evaluation/scripts/utils/__init__.py +27 -0
- package/canonical/skills/agent-evaluation/scripts/utils/env_validation.py +123 -0
- package/canonical/skills/agent-evaluation/scripts/utils/tracing_utils.py +108 -0
- package/canonical/skills/agent-evaluation/scripts/validate_agent_tracing.py +148 -0
- package/canonical/skills/agent-evaluation/scripts/validate_auth.py +240 -0
- package/canonical/skills/agent-evaluation/scripts/validate_environment.py +185 -0
- package/canonical/skills/agent-evaluation/scripts/validate_tracing_runtime.py +318 -0
- package/canonical/skills/agentic-architecture/SKILL.md +41 -0
- package/canonical/skills/agentic-architecture/evals/cases.yaml +94 -0
- package/canonical/skills/agentic-architecture/reference/context-engineering.md +75 -0
- package/canonical/skills/agentic-architecture/reference/patterns.md +76 -0
- package/canonical/skills/agentic-architecture/reference/reliability-observability.md +94 -0
- package/canonical/skills/agentic-architecture/reference/review-framework.md +59 -0
- package/canonical/skills/code-review/SKILL.md +52 -0
- package/canonical/skills/code-review/evals/cases.yaml +197 -0
- package/canonical/skills/git-workflow/SKILL.md +41 -0
- package/canonical/skills/git-workflow/evals/cases.yaml +92 -0
- package/canonical/skills/local-code/SKILL.md +24 -0
- package/canonical/skills/local-code/evals/cases.yaml +85 -0
- package/canonical/skills/local-code/scripts/query_llama.py +68 -0
- package/canonical/skills/report-formatting/SKILL.md +62 -0
- package/canonical/skills/report-formatting/evals/cases.yaml +83 -0
- package/canonical/skills/report-formatting/reference/ARCHITECTURE.md +135 -0
- package/canonical/skills/report-formatting/reference/HELPERS.md +120 -0
- package/canonical/skills/report-formatting/reference/PPTX.md +136 -0
- package/canonical/skills/report-formatting/reference/RELEASE.md +99 -0
- package/canonical/skills/report-formatting/reference/TEMPLATES.md +48 -0
- package/canonical/skills/report-formatting/reference/authoring.md +66 -0
- package/canonical/skills/report-formatting/scripts/architecture-template.md +271 -0
- package/canonical/skills/report-formatting/scripts/assets/claro-logo.png +0 -0
- package/canonical/skills/report-formatting/scripts/assets/claro-wordmark.svg +1 -0
- package/canonical/skills/report-formatting/scripts/build-architecture.js +57 -0
- package/canonical/skills/report-formatting/scripts/build-md-claro.js +224 -0
- package/canonical/skills/report-formatting/scripts/build-release.js +51 -0
- package/canonical/skills/report-formatting/scripts/check-env.js +58 -0
- package/canonical/skills/report-formatting/scripts/docmodel.js +283 -0
- package/canonical/skills/report-formatting/scripts/example-build.js +119 -0
- package/canonical/skills/report-formatting/scripts/example_build_ArchitectureReview_docx.js +195 -0
- package/canonical/skills/report-formatting/scripts/example_build_ExecutiveReport_docx.js +114 -0
- package/canonical/skills/report-formatting/scripts/package.json +17 -0
- package/canonical/skills/report-formatting/scripts/pptx/example_build_StatusReport_pptx.py +223 -0
- package/canonical/skills/report-formatting/scripts/pptx/example_build_WeeklyStatus_pptx.py +245 -0
- package/canonical/skills/report-formatting/scripts/pptx/pptx_office.py +144 -0
- package/canonical/skills/report-formatting/scripts/pptx/requirements.txt +7 -0
- package/canonical/skills/report-formatting/scripts/pptx/status_report_blocks.py +193 -0
- package/canonical/skills/report-formatting/scripts/pptx/theme_claro_pptx.py +473 -0
- package/canonical/skills/report-formatting/scripts/release-template.md +80 -0
- package/canonical/skills/report-formatting/scripts/render-mermaid.js +105 -0
- package/canonical/skills/report-formatting/scripts/theme-claro.js +403 -0
- package/canonical/skills/subagent-driven-development/SKILL.md +60 -0
- package/canonical/skills/subagent-driven-development/evals/cases.yaml +208 -0
- package/canonical/skills/subagent-driven-development/reference/brief.md +91 -0
- package/canonical/skills/subagent-driven-development/reference/handoff.md +118 -0
- package/canonical/skills/subagent-driven-development/scripts/validate-handoff.mjs +850 -0
- package/canonical/skills/systematic-debugging/SKILL.md +44 -0
- package/canonical/skills/systematic-debugging/evals/cases.yaml +90 -0
- package/canonical/skills/test-driven-development/SKILL.md +42 -0
- package/canonical/skills/test-driven-development/evals/cases.yaml +86 -0
- package/canonical/skills/test-driven-development/reference/writing-good-tests.md +52 -0
- package/canonical/skills/verification-before-completion/SKILL.md +53 -0
- package/canonical/skills/verification-before-completion/evals/cases.yaml +107 -0
- package/dist/adapters/content/language-lint.d.ts +46 -0
- package/dist/adapters/content/language-lint.js +191 -0
- package/dist/adapters/harness/claude-code.d.ts +57 -0
- package/dist/adapters/harness/claude-code.js +385 -0
- package/dist/adapters/harness/index.d.ts +3 -0
- package/dist/adapters/harness/index.js +17 -0
- package/dist/adapters/harness/opencode.d.ts +7 -0
- package/dist/adapters/harness/opencode.js +166 -0
- package/dist/adapters/harness/plugin.d.ts +22 -0
- package/dist/adapters/harness/plugin.js +257 -0
- package/dist/adapters/memory/doctor.d.ts +480 -0
- package/dist/adapters/memory/doctor.js +1217 -0
- package/dist/adapters/memory/vendored.d.ts +150 -0
- package/dist/adapters/memory/vendored.js +487 -0
- package/dist/adapters/package/node.d.ts +9 -0
- package/dist/adapters/package/node.js +20 -0
- package/dist/adapters/prompt/readline.d.ts +19 -0
- package/dist/adapters/prompt/readline.js +53 -0
- package/dist/adapters/sync/diff.d.ts +43 -0
- package/dist/adapters/sync/diff.js +380 -0
- package/dist/cli/cleanup.d.ts +86 -0
- package/dist/cli/cleanup.js +382 -0
- package/dist/cli/cost.d.ts +304 -0
- package/dist/cli/cost.js +501 -0
- package/dist/cli/doctor.d.ts +205 -0
- package/dist/cli/doctor.js +654 -0
- package/dist/cli/executor.d.ts +5 -0
- package/dist/cli/executor.js +48 -0
- package/dist/cli/plugin-validate.d.ts +37 -0
- package/dist/cli/plugin-validate.js +256 -0
- package/dist/cli/prefix.d.ts +68 -0
- package/dist/cli/prefix.js +218 -0
- package/dist/cli/profile.d.ts +170 -0
- package/dist/cli/profile.js +285 -0
- package/dist/cli/runner.d.ts +10 -0
- package/dist/cli/runner.js +27 -0
- package/dist/cli/uninstall.d.ts +65 -0
- package/dist/cli/uninstall.js +147 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +989 -0
- package/dist/infra/dogfood.d.ts +31 -0
- package/dist/infra/dogfood.js +51 -0
- package/dist/infra/fsutil.d.ts +40 -0
- package/dist/infra/fsutil.js +143 -0
- package/dist/infra/manifest.d.ts +76 -0
- package/dist/infra/manifest.js +92 -0
- package/dist/infra/paths.d.ts +19 -0
- package/dist/infra/paths.js +74 -0
- package/dist/infra/routing.d.ts +4 -0
- package/dist/infra/routing.js +7 -0
- package/node_modules/@freeharness/core/dist/context.d.ts +30 -0
- package/node_modules/@freeharness/core/dist/context.js +1 -0
- package/node_modules/@freeharness/core/dist/index.d.ts +5 -0
- package/node_modules/@freeharness/core/dist/index.js +6 -0
- package/node_modules/@freeharness/core/dist/planner.d.ts +13 -0
- package/node_modules/@freeharness/core/dist/planner.js +18 -0
- package/node_modules/@freeharness/core/dist/ports.d.ts +90 -0
- package/node_modules/@freeharness/core/dist/ports.js +1 -0
- package/node_modules/@freeharness/core/dist/registry.d.ts +41 -0
- package/node_modules/@freeharness/core/dist/registry.js +124 -0
- package/node_modules/@freeharness/core/dist/tiers.d.ts +30 -0
- package/node_modules/@freeharness/core/dist/tiers.js +99 -0
- package/node_modules/@freeharness/core/package.json +34 -0
- package/node_modules/@freeharness/sdd/PROVENANCE.yaml +175 -0
- package/node_modules/@freeharness/sdd/dist/src/bin/openspec.d.ts +2 -0
- package/node_modules/@freeharness/sdd/dist/src/bin/openspec.js +166 -0
- package/node_modules/@freeharness/sdd/dist/src/index.d.ts +14 -0
- package/node_modules/@freeharness/sdd/dist/src/index.js +11 -0
- package/node_modules/@freeharness/sdd/dist/src/init.d.ts +39 -0
- package/node_modules/@freeharness/sdd/dist/src/init.js +190 -0
- package/node_modules/@freeharness/sdd/dist/src/root-resolver.d.ts +8 -0
- package/node_modules/@freeharness/sdd/dist/src/root-resolver.js +32 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/archive.d.ts +81 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/archive.js +483 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/context.d.ts +4 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/context.js +48 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/follow-up.d.ts +57 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/follow-up.js +279 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/instructions.d.ts +67 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/instructions.js +460 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/list.d.ts +5 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/list.js +95 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/new-change.d.ts +6 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/new-change.js +150 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/schemas.d.ts +4 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/schemas.js +23 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/shared.d.ts +56 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/shared.js +140 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/status.d.ts +8 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/status.js +85 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/validate.d.ts +6 -0
- package/node_modules/@freeharness/sdd/dist/src/shim/validate.js +229 -0
- package/node_modules/@freeharness/sdd/dist/src/validate-change.d.ts +40 -0
- package/node_modules/@freeharness/sdd/dist/src/validate-change.js +114 -0
- package/node_modules/@freeharness/sdd/dist/src/validate.d.ts +24 -0
- package/node_modules/@freeharness/sdd/dist/src/validate.js +72 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/apply/specs-apply.d.ts +130 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/apply/specs-apply.js +981 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/change-metadata.d.ts +46 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/change-metadata.js +128 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/change-status-policy.d.ts +26 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/change-status-policy.js +32 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/file-system.d.ts +50 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/file-system.js +394 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/global-config.d.ts +15 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/global-config.js +49 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/graph.d.ts +71 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/graph.js +164 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/index.d.ts +11 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/index.js +21 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/instruction-loader.d.ts +102 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/instruction-loader.js +230 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/outputs.d.ts +18 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/outputs.js +138 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/resolver.d.ts +82 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/resolver.js +333 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/schema.d.ts +12 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/schema.js +110 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/state.d.ts +11 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/state.js +32 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/task-progress.d.ts +33 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/task-progress.js +149 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/types.d.ts +39 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/engine/types.js +49 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/adapters/claude.d.ts +12 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/adapters/claude.js +31 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/adapters/index.d.ts +10 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/adapters/index.js +10 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/adapters/opencode.d.ts +12 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/adapters/opencode.js +26 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/generator.d.ts +28 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/generator.js +41 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/index.d.ts +23 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/index.js +25 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/invocation.d.ts +72 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/invocation.js +76 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/registry.d.ts +39 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/registry.js +53 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/types.d.ts +62 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/types.js +7 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/yaml.d.ts +35 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-generation/yaml.js +47 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-references.d.ts +33 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/command-references.js +55 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/shared/allowed-tools.d.ts +11 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/shared/allowed-tools.js +11 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/shared/skill-generation.d.ts +48 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/shared/skill-generation.js +99 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/skill-templates.d.ts +19 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/skill-templates.js +18 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/types.d.ts +18 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/types.js +4 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/apply-change.d.ts +19 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/apply-change.js +207 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/archive-change.d.ts +12 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/archive-change.js +409 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/bulk-archive-change.d.ts +9 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/bulk-archive-change.js +673 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/continue-change.d.ts +9 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/continue-change.js +230 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/explore.d.ts +12 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/explore.js +550 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/feedback.d.ts +8 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/feedback.js +107 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/ff-change.d.ts +12 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/ff-change.js +228 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/new-change.d.ts +9 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/new-change.js +147 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/onboard.d.ts +9 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/onboard.js +571 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/propose.d.ts +12 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/propose.js +322 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/store-selection.d.ts +7 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/store-selection.js +7 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/sync-specs.d.ts +9 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/sync-specs.js +518 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/update-change.d.ts +9 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/update-change.js +176 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/verify-change.d.ts +9 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/generation/templates/workflows/verify-change.js +344 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/constants.d.ts +39 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/constants.js +54 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/delta-resolution.d.ts +35 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/delta-resolution.js +171 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/change-parser.d.ts +27 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/change-parser.js +210 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/code-fence.d.ts +14 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/code-fence.js +48 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/markdown-parser.d.ts +22 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/markdown-parser.js +186 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/requirement-blocks.d.ts +65 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/requirement-blocks.js +409 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/requirement-text.d.ts +55 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/requirement-text.js +98 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/spec-structure.d.ts +8 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/parsers/spec-structure.js +77 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/purpose-placeholder.d.ts +44 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/purpose-placeholder.js +116 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/schemas/base.schema.d.ts +12 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/schemas/base.schema.js +17 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/schemas/change.schema.d.ts +72 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/schemas/change.schema.js +30 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/schemas/index.d.ts +3 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/schemas/index.js +3 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/schemas/spec.schema.d.ts +17 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/schemas/spec.schema.js +14 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/spec-discovery.d.ts +39 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/spec-discovery.js +114 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/task-lines.d.ts +45 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/task-lines.js +105 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/task-numbering.d.ts +15 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/task-numbering.js +56 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/types.d.ts +17 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/types.js +1 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/validator.d.ts +94 -0
- package/node_modules/@freeharness/sdd/dist/vendor/openspec/validation/validator.js +756 -0
- package/node_modules/@freeharness/sdd/package.json +57 -0
- package/node_modules/@freeharness/sdd/vendor/openspec/LICENSE.upstream +22 -0
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/schema.upstream.yaml +232 -0
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/README.md +19 -0
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-apply-change/SKILL.md +187 -0
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-archive-change/SKILL.md +181 -0
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-bulk-archive-change/SKILL.md +338 -0
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-continue-change/SKILL.md +117 -0
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-explore/SKILL.md +342 -0
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-ff-change/SKILL.md +116 -0
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-new-change/SKILL.md +76 -0
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-onboard/SKILL.md +560 -0
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-propose/SKILL.md +162 -0
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-sync-specs/SKILL.md +261 -0
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-update-change/SKILL.md +90 -0
- package/node_modules/@freeharness/sdd/vendor/openspec/assets/skills/openspec-verify-change/SKILL.md +174 -0
- package/package.json +70 -0
- package/provenance/canonical.PROVENANCE.yaml +740 -0
- package/provenance/claude-mem.LICENSE.upstream +202 -0
- package/provenance/memory.PROVENANCE.yaml +399 -0
- package/provenance/sdd.PROVENANCE.yaml +175 -0
- package/vendor-licenses/caveman.LICENSE +27 -0
- package/vendor-licenses/deepseek-harness.LICENSE +21 -0
- package/vendor-licenses/ecc.LICENSE +21 -0
- package/vendor-licenses/pi.LICENSE +21 -0
- package/vendor-licenses/superpowers.LICENSE +21 -0
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import type { Capability, HarnessTarget } from "./registry.js";
|
|
2
|
+
import type { AdapterResult, ExecStep, InstallContext, Scope } from "./context.js";
|
|
3
|
+
export interface HarnessPort {
|
|
4
|
+
target: HarnessTarget;
|
|
5
|
+
apply(capability: Capability, ctx: InstallContext): Promise<AdapterResult>;
|
|
6
|
+
}
|
|
7
|
+
export interface FsPort {
|
|
8
|
+
exists(file: string): boolean;
|
|
9
|
+
readText(file: string): string;
|
|
10
|
+
writeText(file: string, content: string, dryRun: boolean): string;
|
|
11
|
+
writeTextIfAbsent(file: string, content: string, dryRun: boolean): {
|
|
12
|
+
path: string;
|
|
13
|
+
skipped: boolean;
|
|
14
|
+
};
|
|
15
|
+
ensureDir(dir: string, dryRun: boolean): void;
|
|
16
|
+
}
|
|
17
|
+
export type PackageManager = "npm" | "pip" | "bun" | "uv";
|
|
18
|
+
export interface PackagePort {
|
|
19
|
+
isPresent(tool: string): Promise<boolean>;
|
|
20
|
+
exec(step: ExecStep): Promise<{
|
|
21
|
+
ok: boolean;
|
|
22
|
+
code: number;
|
|
23
|
+
}>;
|
|
24
|
+
}
|
|
25
|
+
/** One selectable item for `PromptPort.select`. */
|
|
26
|
+
export interface SelectItem {
|
|
27
|
+
id: string;
|
|
28
|
+
label: string;
|
|
29
|
+
}
|
|
30
|
+
export interface PromptPort {
|
|
31
|
+
confirm(message: string): Promise<boolean>;
|
|
32
|
+
select(message: string, items: SelectItem[]): Promise<string[]>;
|
|
33
|
+
}
|
|
34
|
+
export interface SddPort {
|
|
35
|
+
schemaValidate(name: string): Promise<{
|
|
36
|
+
valid: boolean;
|
|
37
|
+
message?: string;
|
|
38
|
+
}>;
|
|
39
|
+
initProject(target: HarnessTarget, projectRoot: string, ctx: InstallContext): Promise<AdapterResult>;
|
|
40
|
+
}
|
|
41
|
+
export interface MemoryPort {
|
|
42
|
+
ensurePrerequisites(ctx: InstallContext): Promise<AdapterResult>;
|
|
43
|
+
install(scope: Scope, ctx: InstallContext): Promise<AdapterResult>;
|
|
44
|
+
registerHooks(scope: Scope, ctx: InstallContext): Promise<AdapterResult>;
|
|
45
|
+
migrateExisting(ctx: InstallContext): Promise<AdapterResult>;
|
|
46
|
+
}
|
|
47
|
+
export interface McpPort {
|
|
48
|
+
register(target: HarnessTarget, ctx: InstallContext): Promise<AdapterResult>;
|
|
49
|
+
}
|
|
50
|
+
export interface SyncReport {
|
|
51
|
+
target: string;
|
|
52
|
+
baseline: string;
|
|
53
|
+
changedPaths: string[];
|
|
54
|
+
contractAffected: string[];
|
|
55
|
+
/** Paths rewritten on purpose (always differ); value = why. Review upstream by hand. */
|
|
56
|
+
divergent: Record<string, string>;
|
|
57
|
+
}
|
|
58
|
+
/** Options for `sync adopt`: which tracked labels to take, and the write/force gates. */
|
|
59
|
+
export interface AdoptOptions {
|
|
60
|
+
/** Tracked entry labels to adopt (as reported by `check`); all tracked entries when omitted. */
|
|
61
|
+
paths?: string[];
|
|
62
|
+
/** Preview only: compute previews and the would-be report, write nothing. */
|
|
63
|
+
dryRun: boolean;
|
|
64
|
+
/** Adopt DIVERGENT entries too (normally always skipped; the caller must warn loudly). */
|
|
65
|
+
forceDivergent: boolean;
|
|
66
|
+
}
|
|
67
|
+
/** One unified-diff preview for a tracked path (a file, or one file inside a tracked dir). */
|
|
68
|
+
export interface AdoptPreview {
|
|
69
|
+
label: string;
|
|
70
|
+
diff: string;
|
|
71
|
+
}
|
|
72
|
+
/** Outcome of `sync adopt` (or its dry run). Paths are labels as in `SyncReport.changedPaths`. */
|
|
73
|
+
export interface AdoptReport {
|
|
74
|
+
target: string;
|
|
75
|
+
/** Tracked entry labels copied from upstream (or that would be, in a dry run). */
|
|
76
|
+
adopted: string[];
|
|
77
|
+
/** DIVERGENT labels left untouched (compare by hand). */
|
|
78
|
+
skippedDivergent: string[];
|
|
79
|
+
/** PROVENANCE `baseline_commit` before / after (equal when nothing was written or the fork is not a git checkout). */
|
|
80
|
+
baselineBefore: string;
|
|
81
|
+
baselineAfter: string;
|
|
82
|
+
previews: AdoptPreview[];
|
|
83
|
+
/** Non-fatal notices (fork not a git checkout, upstream file removed, ...). */
|
|
84
|
+
warnings: string[];
|
|
85
|
+
}
|
|
86
|
+
/** Driven: read-only upstream check plus the explicit, path-scoped adoption. */
|
|
87
|
+
export interface SyncPort {
|
|
88
|
+
check(target: string): Promise<SyncReport>;
|
|
89
|
+
adopt(target: string, options: AdoptOptions): Promise<AdoptReport>;
|
|
90
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Emission targets. `claude-code` and `opencode` install into a harness; `plugin` writes a
|
|
3
|
+
* Claude Code plugin directory (official layout) that is installed through a marketplace.
|
|
4
|
+
*/
|
|
5
|
+
export type HarnessTarget = "claude-code" | "opencode" | "plugin";
|
|
6
|
+
/** Every target `--target` accepts. */
|
|
7
|
+
export declare const ALL_TARGETS: readonly HarnessTarget[];
|
|
8
|
+
/** Targets used when `--target` is omitted: the installable harnesses, never the plugin dir. */
|
|
9
|
+
export declare const DEFAULT_TARGETS: readonly HarnessTarget[];
|
|
10
|
+
export interface Capability {
|
|
11
|
+
id: string;
|
|
12
|
+
description: string;
|
|
13
|
+
targets: HarnessTarget[];
|
|
14
|
+
dependsOn: string[];
|
|
15
|
+
optional: boolean;
|
|
16
|
+
delegatesTo?: string;
|
|
17
|
+
}
|
|
18
|
+
export declare const CAPABILITIES: Capability[];
|
|
19
|
+
export declare function getCapability(id: string): Capability | undefined;
|
|
20
|
+
export declare function resolveInstallOrder(requested: string[], targets: HarnessTarget[]): string[];
|
|
21
|
+
export declare function defaultCapabilityIds(): string[];
|
|
22
|
+
/**
|
|
23
|
+
* Opt-in profiles (v4 P6): data files under `canonical/profiles/` applied by
|
|
24
|
+
* `init --profile <id>`. A profile is never part of the default install set and never a
|
|
25
|
+
* capability: it merges an env block, a provider block or an MCP selection into an
|
|
26
|
+
* existing target and is recorded in the install manifest so `--profile none` can remove
|
|
27
|
+
* exactly what it wrote.
|
|
28
|
+
*/
|
|
29
|
+
export type ProfileKind = "claude-code-env" | "opencode-provider" | "mcp-catalog";
|
|
30
|
+
export interface Profile {
|
|
31
|
+
id: string;
|
|
32
|
+
description: string;
|
|
33
|
+
kind: ProfileKind;
|
|
34
|
+
targets: HarnessTarget[];
|
|
35
|
+
/** File under canonical/profiles/. */
|
|
36
|
+
file: string;
|
|
37
|
+
}
|
|
38
|
+
export declare const PROFILES: Profile[];
|
|
39
|
+
/** The reserved profile name that removes every profile recorded in the manifest. */
|
|
40
|
+
export declare const PROFILE_NONE = "none";
|
|
41
|
+
export declare function getProfile(id: string): Profile | undefined;
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
// Capability registry. `init` resolves the dependency graph and applies only
|
|
2
|
+
// what was requested, per target.
|
|
3
|
+
/** Every target `--target` accepts. */
|
|
4
|
+
export const ALL_TARGETS = ["claude-code", "opencode", "plugin"];
|
|
5
|
+
/** Targets used when `--target` is omitted: the installable harnesses, never the plugin dir. */
|
|
6
|
+
export const DEFAULT_TARGETS = ["claude-code", "opencode"];
|
|
7
|
+
export const CAPABILITIES = [
|
|
8
|
+
{
|
|
9
|
+
id: "rules",
|
|
10
|
+
description: "Canonical rules emitted as CLAUDE.md (Claude Code) / AGENTS.md (OpenCode); Claude Code also gets the SessionStart pointer (post-compaction re-orientation), memory-guard, config-guard and repeat-tool hooks.",
|
|
11
|
+
targets: ["claude-code", "opencode", "plugin"],
|
|
12
|
+
dependsOn: [],
|
|
13
|
+
optional: false,
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
id: "sdd",
|
|
17
|
+
description: "OpenSpec spec-driven schema (FreeHarness override, user-global) + the converge Stop hook (opt-in per project via .freeharness/converge.json).",
|
|
18
|
+
targets: ["claude-code", "opencode", "plugin"],
|
|
19
|
+
dependsOn: [],
|
|
20
|
+
optional: false,
|
|
21
|
+
delegatesTo: "vendored @freeharness/sdd initProject (in-process)",
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
id: "skills",
|
|
25
|
+
description: "Execution/verification skills: TDD, subagent-driven-dev, debugging, verification, code-review, git-workflow.",
|
|
26
|
+
targets: ["claude-code", "opencode", "plugin"],
|
|
27
|
+
dependsOn: [],
|
|
28
|
+
optional: false,
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
id: "memory",
|
|
32
|
+
description: "claude-mem integration (persistent memory). Owns lifecycle hooks; never overridden.",
|
|
33
|
+
targets: ["claude-code", "opencode", "plugin"],
|
|
34
|
+
dependsOn: [],
|
|
35
|
+
optional: true,
|
|
36
|
+
delegatesTo: "vendored claude-mem plugin (Claude Code); OpenCode = seam",
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
id: "agents",
|
|
40
|
+
description: "Review, design, and exploration agents: python/database/mle/security/pr reviewers, agentic-architect, explorer-ai-engineer-analyst, test-writer.",
|
|
41
|
+
targets: ["claude-code", "opencode", "plugin"],
|
|
42
|
+
dependsOn: ["rules"],
|
|
43
|
+
optional: false,
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
id: "safety",
|
|
47
|
+
description: "Prompt-injection sanitization and agent-decision logging rules + advisory security-guidance hook.",
|
|
48
|
+
targets: ["claude-code", "opencode", "plugin"],
|
|
49
|
+
dependsOn: ["rules"],
|
|
50
|
+
optional: false,
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
id: "mcp",
|
|
54
|
+
description: "Register the MCP servers listed in canonical/mcp/servers.json via `claude mcp add`.",
|
|
55
|
+
targets: ["claude-code", "opencode", "plugin"],
|
|
56
|
+
dependsOn: [],
|
|
57
|
+
optional: false,
|
|
58
|
+
delegatesTo: "claude mcp add",
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
id: "cost",
|
|
62
|
+
description: "Token economy, part of the default set: the v4 token-economy hooks (output-pruner on PostToolUse Bash, context-monitor on Stop, cost-tracker on Stop + SessionEnd writing usage snapshots into ~/.claude/freeharness/cost/usage.jsonl priced from an editable table) and the cache-hygiene settings (1h prompt cache TTLs) are core to the harness, not an add-on; `freeharness cost report [--sinks]` and `cost prefix` read them. `--only` without cost still skips it.",
|
|
63
|
+
targets: ["claude-code", "plugin"],
|
|
64
|
+
dependsOn: [],
|
|
65
|
+
optional: false,
|
|
66
|
+
},
|
|
67
|
+
];
|
|
68
|
+
export function getCapability(id) {
|
|
69
|
+
return CAPABILITIES.find((c) => c.id === id);
|
|
70
|
+
}
|
|
71
|
+
// Requested ids + transitive deps, filtered to those supporting a target, in
|
|
72
|
+
// dependency order.
|
|
73
|
+
export function resolveInstallOrder(requested, targets) {
|
|
74
|
+
const ordered = [];
|
|
75
|
+
const seen = new Set();
|
|
76
|
+
const visit = (id) => {
|
|
77
|
+
if (seen.has(id))
|
|
78
|
+
return;
|
|
79
|
+
seen.add(id);
|
|
80
|
+
const cap = getCapability(id);
|
|
81
|
+
if (!cap)
|
|
82
|
+
throw new Error(`Unknown capability: ${id}`);
|
|
83
|
+
for (const dep of cap.dependsOn)
|
|
84
|
+
visit(dep);
|
|
85
|
+
const supportsTarget = cap.targets.some((t) => targets.includes(t));
|
|
86
|
+
if (supportsTarget)
|
|
87
|
+
ordered.push(id);
|
|
88
|
+
};
|
|
89
|
+
for (const id of requested)
|
|
90
|
+
visit(id);
|
|
91
|
+
return ordered;
|
|
92
|
+
}
|
|
93
|
+
// Default set when --only is omitted: all required capabilities.
|
|
94
|
+
export function defaultCapabilityIds() {
|
|
95
|
+
return CAPABILITIES.filter((c) => !c.optional).map((c) => c.id);
|
|
96
|
+
}
|
|
97
|
+
export const PROFILES = [
|
|
98
|
+
{
|
|
99
|
+
id: "local-ollama",
|
|
100
|
+
description: "Claude Code on a local Ollama server: ANTHROPIC_BASE_URL + ANTHROPIC_DEFAULT_{OPUS,SONNET,HAIKU}_MODEL + CLAUDE_CODE_SUBAGENT_MODEL mapped from the strong/standard/fast tiers, merged additively into the settings.json env block.",
|
|
101
|
+
kind: "claude-code-env",
|
|
102
|
+
targets: ["claude-code"],
|
|
103
|
+
file: "local-ollama.json",
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
id: "local-llamacpp",
|
|
107
|
+
description: "OpenCode on a local llama.cpp server: provider block (@ai-sdk/openai-compatible, baseURL, tier models) merged into <project>/opencode.json + .opencode/LOCAL-MODELS.md with the Jinja template guidance.",
|
|
108
|
+
kind: "opencode-provider",
|
|
109
|
+
targets: ["opencode"],
|
|
110
|
+
file: "local-llamacpp.json",
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
id: "mcp",
|
|
114
|
+
description: "Opt-in MCP catalog for AI and Data engineers (context7, github, postgres-mcp restricted, jupyter, mlflow, serena, mcpdoc) with tool counts and context-cost notes; nothing is registered without an explicit selection.",
|
|
115
|
+
kind: "mcp-catalog",
|
|
116
|
+
targets: ["claude-code"],
|
|
117
|
+
file: "mcp.json",
|
|
118
|
+
},
|
|
119
|
+
];
|
|
120
|
+
/** The reserved profile name that removes every profile recorded in the manifest. */
|
|
121
|
+
export const PROFILE_NONE = "none";
|
|
122
|
+
export function getProfile(id) {
|
|
123
|
+
return PROFILES.find((p) => p.id === id);
|
|
124
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { HarnessTarget } from "./registry.js";
|
|
2
|
+
export type Tier = "strong" | "standard" | "fast";
|
|
3
|
+
/** OpenCode ids are provider-specific: emitted as env placeholders, not concrete models. */
|
|
4
|
+
export declare const TIER_MODEL: Record<HarnessTarget, Record<Tier, string>>;
|
|
5
|
+
export declare function mapTier(target: HarnessTarget, tier: Tier): string;
|
|
6
|
+
/** Body text of the leading frontmatter block, or undefined without one. */
|
|
7
|
+
export declare function frontmatterBody(content: string): string | undefined;
|
|
8
|
+
/** Rebuilds a file's frontmatter fence around `fn`'s rewrite of the body; content unchanged without a fence or when `fn` returns the same body. */
|
|
9
|
+
export declare function replaceFrontmatterBody(content: string, fn: (body: string) => string): string;
|
|
10
|
+
/** Rewrites the frontmatter `model:` tier to its target concrete id (`[ \t]*`, never `\s*`: `\r` is a JS line terminator). */
|
|
11
|
+
export declare function rewriteAgentModel(content: string, target: HarnessTarget): string;
|
|
12
|
+
/** True when the frontmatter block declares the key at column 0. */
|
|
13
|
+
export declare function frontmatterHasKey(content: string, key: string): boolean;
|
|
14
|
+
/** Strips column-0 frontmatter keys; body and nested keys stay. */
|
|
15
|
+
export declare function stripAgentKeys(content: string, keys: readonly string[]): string;
|
|
16
|
+
/** Env keys pinning one model per tier (the DeepClaude idea). */
|
|
17
|
+
export declare const CLAUDE_CODE_TIER_ENV: Record<Tier, string>;
|
|
18
|
+
export declare const CLAUDE_CODE_SUBAGENT_MODEL_ENV = "CLAUDE_CODE_SUBAGENT_MODEL";
|
|
19
|
+
export declare const ANTHROPIC_BASE_URL_ENV = "ANTHROPIC_BASE_URL";
|
|
20
|
+
/** Bearer token env key; a local server (Ollama) accepts any value. */
|
|
21
|
+
export declare const ANTHROPIC_AUTH_TOKEN_ENV = "ANTHROPIC_AUTH_TOKEN";
|
|
22
|
+
export interface LocalModelProfile {
|
|
23
|
+
baseUrl: string;
|
|
24
|
+
models: Record<Tier, string>;
|
|
25
|
+
authToken?: string;
|
|
26
|
+
}
|
|
27
|
+
/** Subagents pin to the standard tier (most agents declare it). */
|
|
28
|
+
export declare function tierEnv(p: LocalModelProfile): Record<string, string>;
|
|
29
|
+
/** Inverse of tierEnv, for doctor's profile line. */
|
|
30
|
+
export declare function tiersFromEnv(env: Record<string, unknown>): Partial<Record<Tier, string>>;
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/** OpenCode ids are provider-specific: emitted as env placeholders, not concrete models. */
|
|
2
|
+
export const TIER_MODEL = {
|
|
3
|
+
"claude-code": { strong: "opus", standard: "sonnet", fast: "haiku" },
|
|
4
|
+
// A plugin is loaded by Claude Code: same concrete model names.
|
|
5
|
+
plugin: { strong: "opus", standard: "sonnet", fast: "haiku" },
|
|
6
|
+
opencode: {
|
|
7
|
+
strong: "${OPENCODE_STRONG_MODEL}",
|
|
8
|
+
standard: "${OPENCODE_STANDARD_MODEL}",
|
|
9
|
+
fast: "${OPENCODE_FAST_MODEL}",
|
|
10
|
+
},
|
|
11
|
+
};
|
|
12
|
+
const TIERS = new Set(["strong", "standard", "fast"]);
|
|
13
|
+
export function mapTier(target, tier) {
|
|
14
|
+
return TIER_MODEL[target][tier];
|
|
15
|
+
}
|
|
16
|
+
// Frontmatter block, CRLF-tolerant, closing fence may lack a trailing newline: preserves a
|
|
17
|
+
// file's own line endings for every caller below.
|
|
18
|
+
const FRONTMATTER_RE = /^---(\r?\n)([\s\S]*?)(\r?\n)---(\r?\n|$)/;
|
|
19
|
+
// Parses the leading frontmatter block, or undefined without one.
|
|
20
|
+
function matchFrontmatter(content) {
|
|
21
|
+
const match = FRONTMATTER_RE.exec(content);
|
|
22
|
+
if (!match)
|
|
23
|
+
return undefined;
|
|
24
|
+
const [whole, openNl, body, closeNl, afterNl] = match;
|
|
25
|
+
return { body, index: match.index, whole, openNl, closeNl, afterNl };
|
|
26
|
+
}
|
|
27
|
+
/** Body text of the leading frontmatter block, or undefined without one. */
|
|
28
|
+
export function frontmatterBody(content) {
|
|
29
|
+
return matchFrontmatter(content)?.body;
|
|
30
|
+
}
|
|
31
|
+
/** Rebuilds a file's frontmatter fence around `fn`'s rewrite of the body; content unchanged without a fence or when `fn` returns the same body. */
|
|
32
|
+
export function replaceFrontmatterBody(content, fn) {
|
|
33
|
+
const m = matchFrontmatter(content);
|
|
34
|
+
if (!m)
|
|
35
|
+
return content;
|
|
36
|
+
const body = fn(m.body);
|
|
37
|
+
if (body === m.body)
|
|
38
|
+
return content;
|
|
39
|
+
const fenceEndIndex = m.index + m.whole.length;
|
|
40
|
+
return content.slice(0, m.index) + `---${m.openNl}${body}${m.closeNl}---${m.afterNl}` + content.slice(fenceEndIndex);
|
|
41
|
+
}
|
|
42
|
+
/** Rewrites the frontmatter `model:` tier to its target concrete id (`[ \t]*`, never `\s*`: `\r` is a JS line terminator). */
|
|
43
|
+
export function rewriteAgentModel(content, target) {
|
|
44
|
+
return replaceFrontmatterBody(content, (body) => body.replace(/^(model:[ \t]*)(\w+)[ \t]*$/m, (line, prefix, value) => TIERS.has(value) ? `${prefix}${mapTier(target, value)}` : line));
|
|
45
|
+
}
|
|
46
|
+
// Column-0 key of one frontmatter line, or undefined.
|
|
47
|
+
function frontmatterKey(line) {
|
|
48
|
+
const colonIndex = line.indexOf(":");
|
|
49
|
+
if (colonIndex === -1)
|
|
50
|
+
return undefined;
|
|
51
|
+
const key = line.slice(0, colonIndex);
|
|
52
|
+
return key !== "" && !/\s/.test(key) ? key : undefined;
|
|
53
|
+
}
|
|
54
|
+
/** True when the frontmatter block declares the key at column 0. */
|
|
55
|
+
export function frontmatterHasKey(content, key) {
|
|
56
|
+
const m = matchFrontmatter(content);
|
|
57
|
+
return m !== undefined && m.body.split("\n").some((line) => frontmatterKey(line) === key);
|
|
58
|
+
}
|
|
59
|
+
/** Strips column-0 frontmatter keys; body and nested keys stay. */
|
|
60
|
+
export function stripAgentKeys(content, keys) {
|
|
61
|
+
const keySet = new Set(keys);
|
|
62
|
+
return replaceFrontmatterBody(content, (body) => body
|
|
63
|
+
.split("\n")
|
|
64
|
+
.filter((line) => {
|
|
65
|
+
const key = frontmatterKey(line);
|
|
66
|
+
return key === undefined || !keySet.has(key);
|
|
67
|
+
})
|
|
68
|
+
.join("\n"));
|
|
69
|
+
}
|
|
70
|
+
/** Env keys pinning one model per tier (the DeepClaude idea). */
|
|
71
|
+
export const CLAUDE_CODE_TIER_ENV = {
|
|
72
|
+
strong: "ANTHROPIC_DEFAULT_OPUS_MODEL",
|
|
73
|
+
standard: "ANTHROPIC_DEFAULT_SONNET_MODEL",
|
|
74
|
+
fast: "ANTHROPIC_DEFAULT_HAIKU_MODEL",
|
|
75
|
+
};
|
|
76
|
+
export const CLAUDE_CODE_SUBAGENT_MODEL_ENV = "CLAUDE_CODE_SUBAGENT_MODEL";
|
|
77
|
+
export const ANTHROPIC_BASE_URL_ENV = "ANTHROPIC_BASE_URL";
|
|
78
|
+
/** Bearer token env key; a local server (Ollama) accepts any value. */
|
|
79
|
+
export const ANTHROPIC_AUTH_TOKEN_ENV = "ANTHROPIC_AUTH_TOKEN";
|
|
80
|
+
/** Subagents pin to the standard tier (most agents declare it). */
|
|
81
|
+
export function tierEnv(p) {
|
|
82
|
+
const env = { [ANTHROPIC_BASE_URL_ENV]: p.baseUrl };
|
|
83
|
+
for (const tier of ["strong", "standard", "fast"])
|
|
84
|
+
env[CLAUDE_CODE_TIER_ENV[tier]] = p.models[tier];
|
|
85
|
+
env[CLAUDE_CODE_SUBAGENT_MODEL_ENV] = p.models.standard;
|
|
86
|
+
if (p.authToken !== undefined)
|
|
87
|
+
env[ANTHROPIC_AUTH_TOKEN_ENV] = p.authToken;
|
|
88
|
+
return env;
|
|
89
|
+
}
|
|
90
|
+
/** Inverse of tierEnv, for doctor's profile line. */
|
|
91
|
+
export function tiersFromEnv(env) {
|
|
92
|
+
const out = {};
|
|
93
|
+
for (const tier of ["strong", "standard", "fast"]) {
|
|
94
|
+
const v = env[CLAUDE_CODE_TIER_ENV[tier]];
|
|
95
|
+
if (typeof v === "string" && v)
|
|
96
|
+
out[tier] = v;
|
|
97
|
+
}
|
|
98
|
+
return out;
|
|
99
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@freeharness/core",
|
|
3
|
+
"version": "0.4.1",
|
|
4
|
+
"private": true,
|
|
5
|
+
"description": "FreeHarness pure domain: capability registry, install planner, model tiers, install context, and ports. No I/O, zero runtime dependencies.",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "dist/index.js",
|
|
8
|
+
"types": "dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"default": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist"
|
|
17
|
+
],
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "tsc -p tsconfig.json",
|
|
20
|
+
"lint": "tsc -p tsconfig.json --noEmit",
|
|
21
|
+
"clean": "rm -rf dist",
|
|
22
|
+
"test": "node --import tsx --test test/*.test.ts"
|
|
23
|
+
},
|
|
24
|
+
"engines": {
|
|
25
|
+
"node": ">=18"
|
|
26
|
+
},
|
|
27
|
+
"license": "MIT",
|
|
28
|
+
"author": "André Negrelli",
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@types/node": "^20.14.0",
|
|
31
|
+
"typescript": "^5.5.0",
|
|
32
|
+
"tsx": "^4.16.0"
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
# Provenance for the vendored OpenSpec subset. `freeharness sync check sdd` diffs
|
|
2
|
+
# upstream against this baseline (P5), limited to the vendored paths.
|
|
3
|
+
upstream:
|
|
4
|
+
name: "@fission-ai/openspec"
|
|
5
|
+
repo: https://github.com/Fission-AI/OpenSpec
|
|
6
|
+
fork: https://github.com/anegrelli/OpenSpec
|
|
7
|
+
baseline_version: "1.13.0"
|
|
8
|
+
baseline_commit: "9d4e5974"
|
|
9
|
+
|
|
10
|
+
vendored:
|
|
11
|
+
assets:
|
|
12
|
+
- path: vendor/openspec/assets/skills
|
|
13
|
+
note: "/opsx skill source (stable contract — track against upstream)"
|
|
14
|
+
- path: vendor/openspec/assets/schema.upstream.yaml
|
|
15
|
+
note: "upstream spec-driven schema (diff baseline; our override lives in canonical/openspec)"
|
|
16
|
+
engine:
|
|
17
|
+
- path: vendor/openspec/engine
|
|
18
|
+
note: "schema-validation slice (artifact-graph: schema/resolver/types + file-system); P3 increment 1"
|
|
19
|
+
- path: vendor/openspec/engine/graph.ts
|
|
20
|
+
note: "ArtifactGraph VERBATIM (src/core/artifact-graph/graph.ts); imports already local; P3 increment 4"
|
|
21
|
+
- path: vendor/openspec/engine/state.ts
|
|
22
|
+
note: "detectCompleted VERBATIM (src/core/artifact-graph/state.ts); imports already local; P3 increment 4"
|
|
23
|
+
- path: vendor/openspec/engine/outputs.ts
|
|
24
|
+
note: "RECONSTRUCTED store-free/dependency-free (src/core/artifact-graph/outputs.ts): same public surface (isGlobPattern/resolveArtifactOutputPath/resolveArtifactOutputs/artifactOutputExists) via a minimal internal glob matcher instead of fast-glob; assertPathWithin confinement preserved; P3 increment 4"
|
|
25
|
+
- path: vendor/openspec/engine/change-metadata.ts
|
|
26
|
+
note: "RECONSTRUCTED store-free (src/utils/change-metadata.ts + core/change-metadata/schema.ts): read/write/resolveSchemaForChange with an inlined ChangeMetadata zod schema (schema+skip_specs, passthrough); DROPPED the project-config/config.yaml schema fallback + kebab/initiative machinery; P3 increment 4"
|
|
27
|
+
- path: vendor/openspec/engine/change-status-policy.ts
|
|
28
|
+
note: "buildActionContext/buildNextSteps FAITHFUL (src/core/change-status-policy.ts); DROPPED PlanningHome/summarizePlanningHome + the --store flag in next-step hints; P3 increment 4"
|
|
29
|
+
- path: vendor/openspec/engine/instruction-loader.ts
|
|
30
|
+
note: "RECONSTRUCTED store-free (src/core/artifact-graph/instruction-loader.ts): loadChangeContext/generateInstructions/formatChangeStatus/loadTemplate with the skill-facing output fields (artifacts[].status/requires, applyRequires, isPlanningComplete/isComplete, dependencies, unlocks, template) + skip_specs handling; DROPPED planningHome, references, config-driven context/rules; P3 increment 4"
|
|
31
|
+
- path: vendor/openspec/engine/task-progress.ts
|
|
32
|
+
note: "FAITHFUL store-free (src/utils/task-progress.ts): parseTaskLines + tracked-tasks glob resolution (apply.tracks -> generates -> resolveArtifactOutputs, tasks.md fallback); DROPPED SchemaGlobCache/--archived plumbing; P3 increment 4"
|
|
33
|
+
shim:
|
|
34
|
+
- path: src/shim
|
|
35
|
+
note: "RECONSTRUCTED thin library dispatchers over the vendored engine + validator, one per subcommand (status/instructions/list/schemas/context/validate/new-change/archive); reimplement src/commands + src/commands/workflow output (incl. --json shapes) WITHOUT commander/TUI/ora/chalk, store/root-selection, references, or project-config; P3 increment 4. archive.ts (inc.4c) RECONSTRUCTS a minimal non-interactive orchestration of src/core/archive.ts: validate (Validator.validateChangeDeltaSpecs) -> build every fold via vendored specs-apply -> write -> move openspec/changes/<name>/ to changes/archive/<name>/; DROPPED the interactive/TUI/prompt/task-progress-gate/retire-marker machinery and the dated archive-folder prefix"
|
|
36
|
+
- path: src/bin/openspec.ts
|
|
37
|
+
note: "RECONSTRUCTED commander-free argv CLI; `bin.openspec` -> dist/src/bin/openspec.js; store-free root resolution (findOpenspecDir walk-up, parent = project root); matches upstream flags + single-document --json; P3 increment 4"
|
|
38
|
+
apply:
|
|
39
|
+
- path: vendor/openspec/apply/specs-apply.ts
|
|
40
|
+
note: "specs-apply FAITHFUL (src/core/specs-apply.ts): findSpecUpdates/buildUpdatedSpec/writeUpdatedSpec/retireSpec/finalizeRetiredSpec/buildSpecSkeleton verbatim incl. the ADDED/MODIFIED/REMOVED/RENAMED fold, retirement guards, and unaccounted-content accounting; DROPPED only chalk (colored console -> plain string); import paths rebased to the vendored engine/validation layout; needs no id.ts or date helper (folderStyleNameProblem/formatLocalDate are not referenced by this module); P3 increment 4c"
|
|
41
|
+
validation:
|
|
42
|
+
- path: vendor/openspec/validation/parsers
|
|
43
|
+
note: "change-validation parsers VERBATIM (code-fence, requirement-text, requirement-blocks, spec-structure, markdown-parser); change-parser verbatim except spec-discovery import path; P3 increment 3"
|
|
44
|
+
- path: vendor/openspec/validation/schemas
|
|
45
|
+
note: "zod change/spec/base schemas + index VERBATIM except constants import path (../validation/constants -> ../constants); P3 increment 3"
|
|
46
|
+
- path: vendor/openspec/validation/constants.ts
|
|
47
|
+
note: "validation thresholds + messages VERBATIM (src/core/validation/constants.ts); P3 increment 3"
|
|
48
|
+
- path: vendor/openspec/validation/types.ts
|
|
49
|
+
note: "ValidationIssue/ValidationReport VERBATIM (src/core/validation/types.ts); P3 increment 3"
|
|
50
|
+
- path: vendor/openspec/validation/task-numbering.ts
|
|
51
|
+
note: "task-numbering VERBATIM except parseTaskLines import (task-progress -> ./task-lines); P3 increment 3"
|
|
52
|
+
- path: vendor/openspec/validation/spec-discovery.ts
|
|
53
|
+
note: "discoverSpecFiles + hasAnyFileUnder VERBATIM except file-system import (-> ../engine/file-system); reuses already-vendored engine FileSystemUtils; P3 increment 3"
|
|
54
|
+
- path: vendor/openspec/validation/task-lines.ts
|
|
55
|
+
note: "RECONSTRUCTED minimal parseTaskLines only (src/utils/task-progress.ts); the schema/artifact-graph task-file resolution is out of the slice; P3 increment 3"
|
|
56
|
+
- path: vendor/openspec/validation/validator.ts
|
|
57
|
+
note: "Validator TRIMMED (src/core/validation/validator.ts): skip_specs marker (change-metadata) removed; task-numbering schema gate + tracked-file resolution (artifact-graph/task-progress) reconstructed to read the change's tasks.md directly; scenario-loss (mainSpecsDir) kept; all delta/spec/scenario/SHALL-MUST rules faithful; P3 increment 3. FreeHarness addition: findUnresolvedHeaderIssues (delta-resolution.ts) after the archive-blockers pass"
|
|
58
|
+
- path: vendor/openspec/validation/delta-resolution.ts
|
|
59
|
+
note: "FREEHARNESS ADDITION (no upstream counterpart): MODIFIED/REMOVED/RENAMED headers resolved against openspec/specs/<cap>/spec.md, with the ADDED-by-<in-flight change> attribution; feeds the validator (ERROR under --strict, WARNING otherwise) and the archive refusal / --force skip"
|
|
60
|
+
generation:
|
|
61
|
+
- path: vendor/openspec/generation/command-generation
|
|
62
|
+
note: "command-generation faithful (types/yaml/invocation/generator verbatim); registry + adapters/index + index TRIMMED to claude+opencode; P3 increment 2"
|
|
63
|
+
- path: vendor/openspec/generation/command-references.ts
|
|
64
|
+
note: "TRIMMED to transformCommandInvocations only (dropped command-surface dep + Codex/Kimi/Rovo/getTransformerForTool); P3 increment 2"
|
|
65
|
+
- path: vendor/openspec/generation/shared
|
|
66
|
+
note: "allowed-tools + skill-generation verbatim (import paths only); P3 increment 2"
|
|
67
|
+
- path: vendor/openspec/generation/templates
|
|
68
|
+
note: "types + skill-templates facade + all 13 workflow modules verbatim (source of both command bodies and skill instructions); P3 increment 2"
|
|
69
|
+
|
|
70
|
+
patches:
|
|
71
|
+
- "global-config: replaced with a store-free data-dir resolver (no ~/.openspec multi-repo store)"
|
|
72
|
+
- "init: reconstructed minimal, non-interactive initProject() in src/init.ts (no store guard, legacy cleanup, prompts, profiles/delivery config, telemetry, or Copilot cloud); CORE_WORKFLOWS + tool skillsDir + serializeConfig inlined instead of vendoring profiles/config-prompts"
|
|
73
|
+
- "skills generated from vendored templates (not copied from assets/skills): init writes the /opsx:<id> command-reference form, whereas assets/skills is the skills.sh distribution variant with the /openspec-* form"
|
|
74
|
+
- "validation: validator.ts drops skip_specs-marker handling (needs change-metadata + schema-name resolution, out of slice); task-numbering reconstructed to read the change's top-level tasks.md (the spec-driven schema's apply.tracks) instead of resolving tracked files via the artifact graph"
|
|
75
|
+
- "validate-change.ts (library): change verdict follows the authoritative delta-spec pass + schema resolution (as `openspec validate <change>` does); the proposal-level pass (ChangeSchema Why/What-Changes + max-deltas advisory) is run and surfaced as [advisory] issues that never flip the verdict, mirroring upstream where it is archive's non-blocking warning source"
|
|
76
|
+
- "shim (P3 inc.4): the `openspec` bin is store-free — no root-selection/store/worksets/--store, no referenced-store index, no project-config context/rules/operation-inputs; root = the parent of the nearest openspec/ found by walking up from cwd; `context` reports this-root-alone (or the no_openspec_root diagnostic /opsx propose checks for); status/instructions/list/schemas/validate/new-change reproduce upstream --json shapes minus store-only fields (root/planningHome/references)"
|
|
77
|
+
- "unresolved delta headers: specs-apply.ts buildUpdatedSpec gains an opt-in skipUnresolved option (archive --force): a MODIFIED/RENAMED whose header is not in the current spec is skipped with a warning instead of aborting the fold; default behavior unchanged (throw). archive.ts refuses on any unresolved header (delta-resolution.ts) unless --force, --yes does not waive it"
|
|
78
|
+
- "shim archive (inc.4c): DONE — vendored src/core/specs-apply.ts (vendor/openspec/apply/specs-apply.ts) now backs a real `openspec archive <name>`: it validates the change, folds its ADDED/MODIFIED/REMOVED/RENAMED deltas into openspec/specs/, then moves the change to changes/archive/<name>/. The fold builds all specs before writing any, so an unapplicable delta aborts with openspec/specs/ untouched (never a move-without-fold). DROPPED capability retirement (retire_capabilities marker) and the dated archive-folder prefix; validation gates on the authoritative delta-spec pass (same as `openspec validate <change>`), not schema resolution"
|
|
79
|
+
- "change-metadata.ts (FreeHarness addition, no upstream counterpart): ChangeMetadataSchema gains optional `depends_on` / `supersedes` (change-id string arrays). shared.ts adds `resolveChangeId(projectRoot, id)` (in-flight / archived / null, path-separator and `..` safe). validate.ts extends a change item's issues with an ERROR for every unresolved id in either list, and a notice for a `depends_on` change that is in flight with open tasks — WARNING under the default verdict, downgraded to INFO under --strict since the vendored Validator's strict mode fails a change on any WARNING and a sister change still in flight is not itself a defect. archive.ts lists every unarchived `depends_on` id among the blockers (same refusal effect as an unchecked task) and reads `readSupersedes` as the union of design.md's `Supersedes:` lines and metadata `supersedes`, feeding the existing checkSupersession / writeSupersededBy pair unchanged"
|
|
80
|
+
- "task-lines.ts (FreeHarness addition, no upstream counterpart): `Disposition` joins `TASK_ANNOTATION_KEYS`; `parseAnnotatedTaskLines` parses a `Disposition: (superseded|moved) <change-id>` or `Disposition: external <reference>` line into `disposition: { kind, target } | null` on the task record, kept raw so a reader can flag a kind outside the three documented ones"
|
|
81
|
+
- "task-progress.ts (FreeHarness addition, no upstream counterpart): keeps its own disposition-aware scan (this engine directory does not import ../validation) so `countTasksFromContent`/`getTaskProgressForChange` return `done`/`open`/`dispositioned` alongside `total`/`completed` (`completed` is the upstream field name and the same count as `done`)"
|
|
82
|
+
- "annotation patterns (task-lines.ts, task-progress.ts): the per-task annotation pattern ends in `\\s*$` rather than `$`, so a tasks.md written with CRLF line endings still parses its Verify/Interfaces/Boundary/Depends/Disposition lines (`.` never matches the `\\r`) — the same reason TASK_LINE_PATTERN carries no end anchor"
|
|
83
|
+
- "task-progress.ts disposition kinds: `countTasksFromContent` resolves a task only for the documented kinds (superseded, moved, external); any other kind leaves the task open, matching the converge hook and the ERROR `validate --strict` reports for it"
|
|
84
|
+
- "formatTaskStatus (task-progress.ts): accepts the optional disposition-aware counts, reporting a change complete when `open` is zero and naming the dispositioned count while tasks are still open; a caller passing only `total`/`completed` keeps the upstream reading"
|
|
85
|
+
- "shim disposition rules (validate/status/archive, FreeHarness addition): validate.ts adds an ERROR for a disposition under a checked task, an unknown kind, an unresolved `superseded`/`moved` target, or an empty `external` reference; status.ts exposes `done`/`open`/`dispositioned` in `--json`, with the tasks resolved (never open) exactly when `open` is zero; archive.ts excludes a dispositioned task from the unchecked-task blocker and prints the dispositioned tasks grouped by kind after the other archive output"
|
|
86
|
+
|
|
87
|
+
skipped:
|
|
88
|
+
- "telemetry (PostHog); store/worksets; shell completions; version-check/self-update"
|
|
89
|
+
- "27 non-target tool adapters (keep only claude + opencode); GitHub-Copilot cloud; docs/marketing"
|
|
90
|
+
- "command-surface.ts + getTransformerForTool machinery (only claude/opencode invocation rewrite needed)"
|
|
91
|
+
- "validation: skip_specs marker (change-metadata), task-progress schema/artifact-graph task-file resolution, the CLI/TUI validate command wrapper (ValidateCommand + ora/inquirer), and archive were NOT vendored — only the change-validation library slice"
|
|
92
|
+
- "shim (P3 inc.4): commander/TUI wrappers, ora spinners, chalk; `openspec feedback` + `openspec store ...` (telemetry/multi-repo store)"
|
|
93
|
+
- "archive (P3 inc.4c): capability retirement (retire_capabilities marker + retireSpec deletion path), the interactive prompt/task-progress-completion gate, and the dated archive-folder prefix from src/core/archive.ts — NOT reconstructed; retireSpec/finalizeRetiredSpec are vendored in specs-apply.ts but unused by the shim orchestration"
|
|
94
|
+
|
|
95
|
+
# V4-P4 ports from upstream e062b957 (1.12.0, MIT). Each entry names the upstream file, the
|
|
96
|
+
# PR, and the vendored target; `sync adopt sdd` never touches these (tracked assets only).
|
|
97
|
+
ports_1_12:
|
|
98
|
+
- upstream: src/core/validation/purpose-placeholder.ts
|
|
99
|
+
pr: "#1671"
|
|
100
|
+
target: vendor/openspec/validation/purpose-placeholder.ts
|
|
101
|
+
note: "verbatim except the code-fence import path; WARNING on a placeholder Purpose (fails under --strict)"
|
|
102
|
+
- upstream: src/core/validation/constants.ts
|
|
103
|
+
pr: "#1671"
|
|
104
|
+
target: vendor/openspec/validation/constants.ts
|
|
105
|
+
note: "verbatim (PURPOSE_PLACEHOLDER_PREFIX/SUFFIX + PURPOSE_IS_PLACEHOLDER)"
|
|
106
|
+
- upstream: src/core/validation/validator.ts
|
|
107
|
+
pr: "#1671, #1710"
|
|
108
|
+
target: vendor/openspec/validation/validator.ts
|
|
109
|
+
note: "placeholder check before the brevity check; findArchiveBlockers (public here, private upstream) dry-runs buildUpdatedSpec and reports INFO 'Archive would refuse this delta'"
|
|
110
|
+
- upstream: src/core/specs-apply.ts
|
|
111
|
+
pr: "#1671, #1712, #1710"
|
|
112
|
+
target: vendor/openspec/apply/specs-apply.ts
|
|
113
|
+
note: "skeleton Purpose composed from the placeholder constants; RENAMED keeps the source block position (orderedKeys); ENOENT/ENOTDIR guard rethrows other read errors"
|
|
114
|
+
- upstream: src/core/templates/workflows/{propose,ff-change}.ts
|
|
115
|
+
pr: "#1737"
|
|
116
|
+
target: vendor/openspec/generation/templates/workflows/{propose,ff-change}.ts
|
|
117
|
+
note: "inspect-before-drafting bullet applied as the upstream diff; propose.ts also carries the FreeHarness supersession-check bullet (not upstream)"
|
|
118
|
+
- upstream: src/core/templates/workflows/explore.ts
|
|
119
|
+
pr: "#1716, #1017, #1010"
|
|
120
|
+
target: vendor/openspec/generation/templates/workflows/explore.ts
|
|
121
|
+
note: "confirmation before the first write, PLANNING_GUIDANCE (dependency-ordered single questions), ASCII-only diagrams; applied as the upstream diff"
|
|
122
|
+
- upstream: schemas/spec-driven/schema.yaml
|
|
123
|
+
pr: "#1660, #1703"
|
|
124
|
+
target: "canonical/openspec/schema.spec-driven.yaml (override) + assets/schema.upstream.yaml (adopted verbatim)"
|
|
125
|
+
note: "per-task verification wording in the tasks instruction; planningHome.root wording is store-free here (the shim stubs planningHome)"
|
|
126
|
+
- upstream: src/core/planning-home.ts + commands/workflow/{status,instructions,new-change}.ts
|
|
127
|
+
pr: "#1703"
|
|
128
|
+
target: src/shim/{shared,status,instructions,context,new-change}.ts
|
|
129
|
+
note: "store-free planningHome stub { kind: 'local', root, changesDir, defaultSchema } in every --json payload; no PlanningHome resolver vendored"
|
|
130
|
+
- upstream: "(FreeHarness, not upstream)"
|
|
131
|
+
pr: "V4-P4 4.4/4.5"
|
|
132
|
+
target: src/shim/archive.ts, vendor/openspec/validation/task-lines.ts, vendor/openspec/validation/parsers/markdown-parser.ts, vendor/openspec/generation/templates/workflows/archive-change.ts
|
|
133
|
+
note: "archive blockers gate (unchecked tasks + INFO blockers refuse without --yes), Supersedes: convention (link, reverse link, in-place edit refusal), per-task annotation parser, EARS header-only scenarios accepted by the main-spec parser, supersession step in the archive workflow"
|
|
134
|
+
|
|
135
|
+
# vendor-sync-2026-09 ports from upstream 9d4e5974 (1.13.0, MIT). Each entry names the
|
|
136
|
+
# upstream file, the PR, and the vendored target; `sync adopt sdd` never touches these
|
|
137
|
+
# (tracked assets only).
|
|
138
|
+
ports_1_13:
|
|
139
|
+
- upstream: src/core/specs-apply.ts
|
|
140
|
+
pr: "#1798"
|
|
141
|
+
target: vendor/openspec/apply/specs-apply.ts
|
|
142
|
+
note: "verbatim fence-aware collapseBlankRunsOutsideFences replaces the blanket \\n{3,} collapse in buildUpdatedSpec's rebuild step, so a fenced code sample's blank-line runs survive an archive fold byte-identical; comment restated in present tense per house style"
|
|
143
|
+
- upstream: src/core/parsers/requirement-blocks.ts
|
|
144
|
+
pr: "#1800, #1802"
|
|
145
|
+
target: vendor/openspec/validation/parsers/requirement-blocks.ts
|
|
146
|
+
note: "verbatim [-*+] bullet markers for REMOVED/RENAMED (#1800); splitTopLevelSections returns an ordered list and getSectionsCaseInsensitive returns every matching section so a repeated `## ADDED Requirements` header applies in full (#1802)"
|
|
147
|
+
- upstream: "(FreeHarness, not upstream)"
|
|
148
|
+
pr: "final-fix item 24"
|
|
149
|
+
target: vendor/openspec/validation/parsers/requirement-blocks.ts
|
|
150
|
+
note: "parseRenamedPairs: a FROM about to be overwritten by a new FROM (or left pending at end of section) without ever pairing with a TO now pushes a SkippedHeader-shaped diagnostic into the same skippedHeaders sink validator.ts renders as INFO, instead of being discarded silently"
|
|
151
|
+
- upstream: src/commands/workflow/instructions.ts + shared.ts
|
|
152
|
+
pr: "#1783"
|
|
153
|
+
target: src/shim/instructions.ts
|
|
154
|
+
note: "adapted: collectMissingPrerequisites/collectApplyWarnings/isSpecsArtifactPath reimplemented against the vendored ArtifactGraph/SchemaYaml/ChangeContext types (not the store-coupled upstream artifact-graph module); missingPrerequisites computed unconditionally and included in JSON whenever non-empty; warnings fires when a spec-producing artifact has no resolved delta files and skip_specs is not set; message text and JSON field names match upstream"
|
|
155
|
+
- upstream: src/core/templates/workflows/explore.ts (#1700), propose.ts (#1657), schemas/spec-driven/schema.yaml (#1700/#1657 cut)
|
|
156
|
+
pr: "#1700, #1657"
|
|
157
|
+
target: vendor/openspec/generation/templates/workflows/{explore,propose}.ts, canonical/openspec/schema.spec-driven.yaml (proposal + specs artifact instructions)
|
|
158
|
+
note: "adapted: verbatim research-guidance prose (spec-inventory step in explore.ts, project-context step in propose.ts, matching schema override text) with every --store clause dropped (store-free shim); FreeHarness supersession bullet in propose.ts preserved untouched"
|
|
159
|
+
|
|
160
|
+
# vendor-sync-2026-09: skipped paths reviewed and intentionally not ported (out of the
|
|
161
|
+
# store-free shim's scope; see design.md).
|
|
162
|
+
ports_1_13_ignored:
|
|
163
|
+
- pr: "#1779"
|
|
164
|
+
note: "init profiles — the shim's initProject() is a store-free reconstruction with no profiles/delivery-config machinery; out of slice"
|
|
165
|
+
- pr: "#1808"
|
|
166
|
+
note: "update drift — no `openspec update` surface is vendored (store/self-update commands are not part of the shim)"
|
|
167
|
+
- pr: "#1782"
|
|
168
|
+
note: "retire_capabilities — capability retirement (retire_capabilities marker + retireSpec deletion path) was not reconstructed in P3 inc.4c's archive shim; retireSpec/finalizeRetiredSpec are vendored in specs-apply.ts but unused by the shim orchestration"
|
|
169
|
+
|
|
170
|
+
roadmap:
|
|
171
|
+
- "vendor-sync-2026-09 (sdd): DONE — 1.13 engine/template ports (ports_1_13 above), tracked assets adopted at 9d4e5974, sources.yaml bumped to 9d4e5974 / 1.13.0"
|
|
172
|
+
- "P3 inc.3: DONE — vendored change-validation slice (parsers + schemas + Validator) + src/validate-change.ts"
|
|
173
|
+
- "P3 inc.4: DONE — store-free `openspec` CLI shim (src/bin/openspec.ts + src/shim/*) over the vendored engine: status/instructions/list/schemas/context/validate/new-change fully working"
|
|
174
|
+
- "V4-P4: DONE — 1.12 engine/template ports (ports_1_12 above), tracked assets adopted at e062b957, converge Stop hook emitted by the sdd capability"
|
|
175
|
+
- "P3 inc.4c: DONE — vendored specs-apply (vendor/openspec/apply/specs-apply.ts) + real `openspec archive` that folds ADDED/MODIFIED/REMOVED/RENAMED deltas into openspec/specs/ and moves the change to changes/archive/; verified end-to-end (ADDED fold, MODIFIED in-place update with no duplication, invalid-delta abort leaves specs untouched)"
|