@deftai/directive-core 0.55.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/architecture/sor-preflight.d.ts +66 -0
- package/dist/architecture/sor-preflight.js +903 -0
- package/dist/branch/evaluate.d.ts +23 -0
- package/dist/branch/evaluate.js +136 -0
- package/dist/branch/git.d.ts +15 -0
- package/dist/branch/git.js +42 -0
- package/dist/branch/index.d.ts +3 -0
- package/dist/branch/index.js +3 -0
- package/dist/cache/cli.d.ts +3 -0
- package/dist/cache/cli.js +8 -0
- package/dist/cache/constants.d.ts +12 -0
- package/dist/cache/constants.js +14 -0
- package/dist/cache/errors.d.ts +34 -0
- package/dist/cache/errors.js +52 -0
- package/dist/cache/fetch.d.ts +101 -0
- package/dist/cache/fetch.js +413 -0
- package/dist/cache/index.d.ts +14 -0
- package/dist/cache/index.js +14 -0
- package/dist/cache/io.d.ts +15 -0
- package/dist/cache/io.js +53 -0
- package/dist/cache/json.d.ts +11 -0
- package/dist/cache/json.js +32 -0
- package/dist/cache/main.d.ts +3 -0
- package/dist/cache/main.js +319 -0
- package/dist/cache/operations.d.ts +34 -0
- package/dist/cache/operations.js +348 -0
- package/dist/cache/paths.d.ts +7 -0
- package/dist/cache/paths.js +27 -0
- package/dist/cache/quota.d.ts +56 -0
- package/dist/cache/quota.js +191 -0
- package/dist/cache/scanner.d.ts +28 -0
- package/dist/cache/scanner.js +362 -0
- package/dist/cache/test-helpers.d.ts +10 -0
- package/dist/cache/test-helpers.js +17 -0
- package/dist/cache/time.d.ts +9 -0
- package/dist/cache/time.js +20 -0
- package/dist/cache/types.d.ts +50 -0
- package/dist/cache/types.js +2 -0
- package/dist/cache/validate.d.ts +3 -0
- package/dist/cache/validate.js +118 -0
- package/dist/capacity/backfill.d.ts +52 -0
- package/dist/capacity/backfill.js +429 -0
- package/dist/capacity/index.d.ts +3 -0
- package/dist/capacity/index.js +3 -0
- package/dist/capacity/show.d.ts +73 -0
- package/dist/capacity/show.js +387 -0
- package/dist/check/index.d.ts +3 -0
- package/dist/check/index.js +2 -0
- package/dist/check/orchestrator.d.ts +51 -0
- package/dist/check/orchestrator.js +71 -0
- package/dist/codebase/constants.d.ts +2 -0
- package/dist/codebase/constants.js +2 -0
- package/dist/codebase/default-extractor.d.ts +28 -0
- package/dist/codebase/default-extractor.js +713 -0
- package/dist/codebase/index.d.ts +8 -0
- package/dist/codebase/index.js +8 -0
- package/dist/codebase/json.d.ts +14 -0
- package/dist/codebase/json.js +45 -0
- package/dist/codebase/map-fresh.d.ts +11 -0
- package/dist/codebase/map-fresh.js +125 -0
- package/dist/codebase/map.d.ts +19 -0
- package/dist/codebase/map.js +345 -0
- package/dist/codebase/projection-registry.d.ts +25 -0
- package/dist/codebase/projection-registry.js +93 -0
- package/dist/codebase/provider.d.ts +30 -0
- package/dist/codebase/provider.js +696 -0
- package/dist/content-contracts/skills/greptile-detector.d.ts +56 -0
- package/dist/content-contracts/skills/greptile-detector.js +368 -0
- package/dist/content-contracts/skills/helpers.d.ts +24 -0
- package/dist/content-contracts/skills/helpers.js +73 -0
- package/dist/content-contracts/skills/skill-frontmatter.d.ts +7 -0
- package/dist/content-contracts/skills/skill-frontmatter.js +65 -0
- package/dist/content-contracts/standards/_helpers.d.ts +49 -0
- package/dist/content-contracts/standards/_helpers.js +227 -0
- package/dist/content-contracts/standards/_shapes.d.ts +12 -0
- package/dist/content-contracts/standards/_shapes.js +45 -0
- package/dist/content-contracts/standards/_taskfile-helpers.d.ts +12 -0
- package/dist/content-contracts/standards/_taskfile-helpers.js +61 -0
- package/dist/content-root.d.ts +47 -0
- package/dist/content-root.js +89 -0
- package/dist/doctor/agents-md.d.ts +14 -0
- package/dist/doctor/agents-md.js +263 -0
- package/dist/doctor/checks.d.ts +16 -0
- package/dist/doctor/checks.js +351 -0
- package/dist/doctor/cli.d.ts +2 -0
- package/dist/doctor/cli.js +7 -0
- package/dist/doctor/constants.d.ts +15 -0
- package/dist/doctor/constants.js +40 -0
- package/dist/doctor/doctor-state.d.ts +16 -0
- package/dist/doctor/doctor-state.js +117 -0
- package/dist/doctor/flags.d.ts +5 -0
- package/dist/doctor/flags.js +63 -0
- package/dist/doctor/index.d.ts +14 -0
- package/dist/doctor/index.js +14 -0
- package/dist/doctor/json.d.ts +3 -0
- package/dist/doctor/json.js +21 -0
- package/dist/doctor/main.d.ts +3 -0
- package/dist/doctor/main.js +387 -0
- package/dist/doctor/manifest.d.ts +11 -0
- package/dist/doctor/manifest.js +114 -0
- package/dist/doctor/output.d.ts +19 -0
- package/dist/doctor/output.js +49 -0
- package/dist/doctor/paths.d.ts +16 -0
- package/dist/doctor/paths.js +106 -0
- package/dist/doctor/payload-staleness.d.ts +13 -0
- package/dist/doctor/payload-staleness.js +165 -0
- package/dist/doctor/taskfile.d.ts +6 -0
- package/dist/doctor/taskfile.js +65 -0
- package/dist/doctor/types.d.ts +76 -0
- package/dist/doctor/types.js +4 -0
- package/dist/doctor/which.d.ts +3 -0
- package/dist/doctor/which.js +17 -0
- package/dist/encoding/evaluate.d.ts +19 -0
- package/dist/encoding/evaluate.js +155 -0
- package/dist/encoding/git.d.ts +11 -0
- package/dist/encoding/git.js +36 -0
- package/dist/encoding/index.d.ts +6 -0
- package/dist/encoding/index.js +6 -0
- package/dist/encoding/patterns.d.ts +29 -0
- package/dist/encoding/patterns.js +109 -0
- package/dist/encoding/scan.d.ts +24 -0
- package/dist/encoding/scan.js +182 -0
- package/dist/encoding/text.d.ts +21 -0
- package/dist/encoding/text.js +111 -0
- package/dist/index.d.ts +54 -0
- package/dist/index.js +55 -0
- package/dist/intake/candidates-log.d.ts +20 -0
- package/dist/intake/candidates-log.js +224 -0
- package/dist/intake/github-auth-modes-cli.d.ts +3 -0
- package/dist/intake/github-auth-modes-cli.js +23 -0
- package/dist/intake/github-auth-modes.d.ts +54 -0
- package/dist/intake/github-auth-modes.js +275 -0
- package/dist/intake/github-body-cli.d.ts +3 -0
- package/dist/intake/github-body-cli.js +30 -0
- package/dist/intake/github-body.d.ts +48 -0
- package/dist/intake/github-body.js +151 -0
- package/dist/intake/index.d.ts +15 -0
- package/dist/intake/index.js +15 -0
- package/dist/intake/issue-emit-cli.d.ts +3 -0
- package/dist/intake/issue-emit-cli.js +34 -0
- package/dist/intake/issue-emit.d.ts +63 -0
- package/dist/intake/issue-emit.js +351 -0
- package/dist/intake/issue-ingest-cli.d.ts +3 -0
- package/dist/intake/issue-ingest-cli.js +33 -0
- package/dist/intake/issue-ingest.d.ts +53 -0
- package/dist/intake/issue-ingest.js +477 -0
- package/dist/intake/markdown-scanners.d.ts +23 -0
- package/dist/intake/markdown-scanners.js +247 -0
- package/dist/intake/parity-scenarios.d.ts +22 -0
- package/dist/intake/parity-scenarios.js +32 -0
- package/dist/intake/platform-capabilities.d.ts +11 -0
- package/dist/intake/platform-capabilities.js +34 -0
- package/dist/intake/reconcile-issues-cli.d.ts +3 -0
- package/dist/intake/reconcile-issues-cli.js +31 -0
- package/dist/intake/reconcile-issues.d.ts +60 -0
- package/dist/intake/reconcile-issues.js +756 -0
- package/dist/integration-e2e/bootstrap-cache-module.d.ts +5 -0
- package/dist/integration-e2e/bootstrap-cache-module.js +21 -0
- package/dist/integration-e2e/helpers.d.ts +28 -0
- package/dist/integration-e2e/helpers.js +157 -0
- package/dist/lifecycle/event-detect.d.ts +32 -0
- package/dist/lifecycle/event-detect.js +172 -0
- package/dist/lifecycle/events.d.ts +45 -0
- package/dist/lifecycle/events.js +340 -0
- package/dist/lifecycle/index.d.ts +4 -0
- package/dist/lifecycle/index.js +4 -0
- package/dist/lifecycle/lifecycle-hygiene.d.ts +59 -0
- package/dist/lifecycle/lifecycle-hygiene.js +388 -0
- package/dist/orchestration/index.d.ts +7 -0
- package/dist/orchestration/index.js +7 -0
- package/dist/orchestration/judgment-policy.d.ts +23 -0
- package/dist/orchestration/judgment-policy.js +228 -0
- package/dist/orchestration/pathspec.d.ts +11 -0
- package/dist/orchestration/pathspec.js +95 -0
- package/dist/orchestration/probe-session.d.ts +74 -0
- package/dist/orchestration/probe-session.js +478 -0
- package/dist/orchestration/subagent-monitor.d.ts +64 -0
- package/dist/orchestration/subagent-monitor.js +405 -0
- package/dist/orchestration/verify-investigation.d.ts +27 -0
- package/dist/orchestration/verify-investigation.js +314 -0
- package/dist/orchestration/verify-judgment-gates.d.ts +66 -0
- package/dist/orchestration/verify-judgment-gates.js +710 -0
- package/dist/packs/index.d.ts +4 -0
- package/dist/packs/index.js +4 -0
- package/dist/packs/pack-render.d.ts +31 -0
- package/dist/packs/pack-render.js +357 -0
- package/dist/packs/packs-slice.d.ts +58 -0
- package/dist/packs/packs-slice.js +649 -0
- package/dist/packs/quarantine-ext.d.ts +7 -0
- package/dist/packs/quarantine-ext.js +164 -0
- package/dist/platform/agents-md.d.ts +31 -0
- package/dist/platform/agents-md.js +320 -0
- package/dist/platform/changelog-cli.d.ts +3 -0
- package/dist/platform/changelog-cli.js +64 -0
- package/dist/platform/constants.d.ts +20 -0
- package/dist/platform/constants.js +27 -0
- package/dist/platform/index.d.ts +9 -0
- package/dist/platform/index.js +9 -0
- package/dist/platform/ip-risk.d.ts +10 -0
- package/dist/platform/ip-risk.js +235 -0
- package/dist/platform/linear-scan.d.ts +36 -0
- package/dist/platform/linear-scan.js +174 -0
- package/dist/platform/platform-capabilities.d.ts +45 -0
- package/dist/platform/platform-capabilities.js +190 -0
- package/dist/platform/resolve-changelog-unreleased.d.ts +24 -0
- package/dist/platform/resolve-changelog-unreleased.js +364 -0
- package/dist/platform/resolve-version.d.ts +22 -0
- package/dist/platform/resolve-version.js +303 -0
- package/dist/platform/slug-normalize.d.ts +9 -0
- package/dist/platform/slug-normalize.js +110 -0
- package/dist/policy/autonomy.d.ts +43 -0
- package/dist/policy/autonomy.js +220 -0
- package/dist/policy/capacity.d.ts +45 -0
- package/dist/policy/capacity.js +251 -0
- package/dist/policy/decisions.d.ts +26 -0
- package/dist/policy/decisions.js +114 -0
- package/dist/policy/disclosure.d.ts +4 -0
- package/dist/policy/disclosure.js +19 -0
- package/dist/policy/index.d.ts +43 -0
- package/dist/policy/index.js +298 -0
- package/dist/policy/resolve.d.ts +38 -0
- package/dist/policy/resolve.js +228 -0
- package/dist/policy/wip.d.ts +15 -0
- package/dist/policy/wip.js +81 -0
- package/dist/pr-closing-keywords/constants.d.ts +6 -0
- package/dist/pr-closing-keywords/constants.js +6 -0
- package/dist/pr-closing-keywords/detect.d.ts +5 -0
- package/dist/pr-closing-keywords/detect.js +113 -0
- package/dist/pr-closing-keywords/gh.d.ts +6 -0
- package/dist/pr-closing-keywords/gh.js +129 -0
- package/dist/pr-closing-keywords/index.d.ts +7 -0
- package/dist/pr-closing-keywords/index.js +6 -0
- package/dist/pr-closing-keywords/io.d.ts +3 -0
- package/dist/pr-closing-keywords/io.js +22 -0
- package/dist/pr-closing-keywords/main.d.ts +9 -0
- package/dist/pr-closing-keywords/main.js +246 -0
- package/dist/pr-closing-keywords/types.d.ts +23 -0
- package/dist/pr-closing-keywords/types.js +2 -0
- package/dist/pr-merge-readiness/compute.d.ts +7 -0
- package/dist/pr-merge-readiness/compute.js +210 -0
- package/dist/pr-merge-readiness/constants.d.ts +20 -0
- package/dist/pr-merge-readiness/constants.js +32 -0
- package/dist/pr-merge-readiness/evaluate.d.ts +5 -0
- package/dist/pr-merge-readiness/evaluate.js +48 -0
- package/dist/pr-merge-readiness/gh.d.ts +22 -0
- package/dist/pr-merge-readiness/gh.js +281 -0
- package/dist/pr-merge-readiness/index.d.ts +9 -0
- package/dist/pr-merge-readiness/index.js +8 -0
- package/dist/pr-merge-readiness/main.d.ts +14 -0
- package/dist/pr-merge-readiness/main.js +67 -0
- package/dist/pr-merge-readiness/output.d.ts +7 -0
- package/dist/pr-merge-readiness/output.js +98 -0
- package/dist/pr-merge-readiness/parse.d.ts +6 -0
- package/dist/pr-merge-readiness/parse.js +83 -0
- package/dist/pr-merge-readiness/types.d.ts +29 -0
- package/dist/pr-merge-readiness/types.js +2 -0
- package/dist/pr-monitor/cadence.d.ts +3 -0
- package/dist/pr-monitor/cadence.js +12 -0
- package/dist/pr-monitor/constants.d.ts +8 -0
- package/dist/pr-monitor/constants.js +12 -0
- package/dist/pr-monitor/index.d.ts +7 -0
- package/dist/pr-monitor/index.js +6 -0
- package/dist/pr-monitor/main.d.ts +17 -0
- package/dist/pr-monitor/main.js +169 -0
- package/dist/pr-monitor/monitor.d.ts +9 -0
- package/dist/pr-monitor/monitor.js +106 -0
- package/dist/pr-monitor/readiness.d.ts +6 -0
- package/dist/pr-monitor/readiness.js +64 -0
- package/dist/pr-monitor/types.d.ts +30 -0
- package/dist/pr-monitor/types.js +2 -0
- package/dist/pr-protected-issues/constants.d.ts +7 -0
- package/dist/pr-protected-issues/constants.js +7 -0
- package/dist/pr-protected-issues/gh.d.ts +9 -0
- package/dist/pr-protected-issues/gh.js +96 -0
- package/dist/pr-protected-issues/index.d.ts +6 -0
- package/dist/pr-protected-issues/index.js +5 -0
- package/dist/pr-protected-issues/main.d.ts +14 -0
- package/dist/pr-protected-issues/main.js +128 -0
- package/dist/pr-protected-issues/parse.d.ts +6 -0
- package/dist/pr-protected-issues/parse.js +21 -0
- package/dist/pr-protected-issues/types.d.ts +8 -0
- package/dist/pr-protected-issues/types.js +2 -0
- package/dist/pr-wait-mergeable/cascade.d.ts +12 -0
- package/dist/pr-wait-mergeable/cascade.js +107 -0
- package/dist/pr-wait-mergeable/classify.d.ts +5 -0
- package/dist/pr-wait-mergeable/classify.js +47 -0
- package/dist/pr-wait-mergeable/constants.d.ts +5 -0
- package/dist/pr-wait-mergeable/constants.js +5 -0
- package/dist/pr-wait-mergeable/index.d.ts +8 -0
- package/dist/pr-wait-mergeable/index.js +7 -0
- package/dist/pr-wait-mergeable/main.d.ts +18 -0
- package/dist/pr-wait-mergeable/main.js +213 -0
- package/dist/pr-wait-mergeable/result.d.ts +9 -0
- package/dist/pr-wait-mergeable/result.js +38 -0
- package/dist/pr-wait-mergeable/types.d.ts +16 -0
- package/dist/pr-wait-mergeable/types.js +2 -0
- package/dist/pr-wait-mergeable/wrappers.d.ts +26 -0
- package/dist/pr-wait-mergeable/wrappers.js +103 -0
- package/dist/preflight/evaluate.d.ts +22 -0
- package/dist/preflight/evaluate.js +137 -0
- package/dist/preflight/index.d.ts +3 -0
- package/dist/preflight/index.js +2 -0
- package/dist/preflight-cache/evaluate.d.ts +40 -0
- package/dist/preflight-cache/evaluate.js +481 -0
- package/dist/preflight-cache/index.d.ts +3 -0
- package/dist/preflight-cache/index.js +2 -0
- package/dist/preflight-gh/classifier.d.ts +56 -0
- package/dist/preflight-gh/classifier.js +415 -0
- package/dist/preflight-gh/index.d.ts +3 -0
- package/dist/preflight-gh/index.js +2 -0
- package/dist/release/changelog.d.ts +9 -0
- package/dist/release/changelog.js +105 -0
- package/dist/release/cli.d.ts +2 -0
- package/dist/release/cli.js +7 -0
- package/dist/release/constants.d.ts +22 -0
- package/dist/release/constants.js +85 -0
- package/dist/release/flags.d.ts +4 -0
- package/dist/release/flags.js +131 -0
- package/dist/release/gh.d.ts +16 -0
- package/dist/release/gh.js +210 -0
- package/dist/release/git.d.ts +11 -0
- package/dist/release/git.js +84 -0
- package/dist/release/index.d.ts +14 -0
- package/dist/release/index.js +15 -0
- package/dist/release/main.d.ts +3 -0
- package/dist/release/main.js +47 -0
- package/dist/release/paths.d.ts +6 -0
- package/dist/release/paths.js +39 -0
- package/dist/release/pipeline.d.ts +6 -0
- package/dist/release/pipeline.js +314 -0
- package/dist/release/pyproject-sync.d.ts +6 -0
- package/dist/release/pyproject-sync.js +52 -0
- package/dist/release/pyproject.d.ts +3 -0
- package/dist/release/pyproject.js +33 -0
- package/dist/release/python-bridge.d.ts +7 -0
- package/dist/release/python-bridge.js +144 -0
- package/dist/release/spawn.d.ts +8 -0
- package/dist/release/spawn.js +44 -0
- package/dist/release/types.d.ts +58 -0
- package/dist/release/types.js +2 -0
- package/dist/release/version.d.ts +11 -0
- package/dist/release/version.js +74 -0
- package/dist/release-e2e/constants.d.ts +22 -0
- package/dist/release-e2e/constants.js +43 -0
- package/dist/release-e2e/entrypoint-worker-thread.d.ts +2 -0
- package/dist/release-e2e/entrypoint-worker-thread.js +22 -0
- package/dist/release-e2e/entrypoint-worker.d.ts +13 -0
- package/dist/release-e2e/entrypoint-worker.js +50 -0
- package/dist/release-e2e/entrypoint.d.ts +40 -0
- package/dist/release-e2e/entrypoint.js +257 -0
- package/dist/release-e2e/flags.d.ts +5 -0
- package/dist/release-e2e/flags.js +80 -0
- package/dist/release-e2e/gh-ops.d.ts +5 -0
- package/dist/release-e2e/gh-ops.js +72 -0
- package/dist/release-e2e/git-ops.d.ts +6 -0
- package/dist/release-e2e/git-ops.js +47 -0
- package/dist/release-e2e/index.d.ts +10 -0
- package/dist/release-e2e/index.js +10 -0
- package/dist/release-e2e/main.d.ts +4 -0
- package/dist/release-e2e/main.js +78 -0
- package/dist/release-e2e/npm-ops.d.ts +29 -0
- package/dist/release-e2e/npm-ops.js +149 -0
- package/dist/release-e2e/rehearsal.d.ts +3 -0
- package/dist/release-e2e/rehearsal.js +51 -0
- package/dist/release-e2e/rollback-bridge.d.ts +3 -0
- package/dist/release-e2e/rollback-bridge.js +20 -0
- package/dist/release-e2e/types.d.ts +40 -0
- package/dist/release-e2e/types.js +2 -0
- package/dist/release-publish/cli.d.ts +2 -0
- package/dist/release-publish/cli.js +7 -0
- package/dist/release-publish/constants.d.ts +4 -0
- package/dist/release-publish/constants.js +24 -0
- package/dist/release-publish/flags.d.ts +5 -0
- package/dist/release-publish/flags.js +67 -0
- package/dist/release-publish/gh-api.d.ts +6 -0
- package/dist/release-publish/gh-api.js +102 -0
- package/dist/release-publish/index.d.ts +7 -0
- package/dist/release-publish/index.js +8 -0
- package/dist/release-publish/main.d.ts +3 -0
- package/dist/release-publish/main.js +38 -0
- package/dist/release-publish/pipeline.d.ts +4 -0
- package/dist/release-publish/pipeline.js +46 -0
- package/dist/release-publish/types.d.ts +25 -0
- package/dist/release-publish/types.js +2 -0
- package/dist/release-rollback/constants.d.ts +18 -0
- package/dist/release-rollback/constants.js +55 -0
- package/dist/release-rollback/flags.d.ts +4 -0
- package/dist/release-rollback/flags.js +136 -0
- package/dist/release-rollback/gh.d.ts +5 -0
- package/dist/release-rollback/gh.js +71 -0
- package/dist/release-rollback/git.d.ts +9 -0
- package/dist/release-rollback/git.js +87 -0
- package/dist/release-rollback/guard.d.ts +12 -0
- package/dist/release-rollback/guard.js +97 -0
- package/dist/release-rollback/index.d.ts +9 -0
- package/dist/release-rollback/index.js +10 -0
- package/dist/release-rollback/main.d.ts +3 -0
- package/dist/release-rollback/main.js +51 -0
- package/dist/release-rollback/pipeline.d.ts +7 -0
- package/dist/release-rollback/pipeline.js +221 -0
- package/dist/release-rollback/types.d.ts +41 -0
- package/dist/release-rollback/types.js +2 -0
- package/dist/render/constants.d.ts +16 -0
- package/dist/render/constants.js +78 -0
- package/dist/render/framework-commands.d.ts +41 -0
- package/dist/render/framework-commands.js +416 -0
- package/dist/render/index.d.ts +15 -0
- package/dist/render/index.js +15 -0
- package/dist/render/prd-render.d.ts +14 -0
- package/dist/render/prd-render.js +79 -0
- package/dist/render/project-render.d.ts +20 -0
- package/dist/render/project-render.js +169 -0
- package/dist/render/roadmap-render.d.ts +8 -0
- package/dist/render/roadmap-render.js +387 -0
- package/dist/render/spec-render.d.ts +13 -0
- package/dist/render/spec-render.js +362 -0
- package/dist/render/spec-validate.d.ts +6 -0
- package/dist/render/spec-validate.js +157 -0
- package/dist/render/text-utils.d.ts +8 -0
- package/dist/render/text-utils.js +72 -0
- package/dist/scm/argv.d.ts +7 -0
- package/dist/scm/argv.js +54 -0
- package/dist/scm/binary.d.ts +11 -0
- package/dist/scm/binary.js +35 -0
- package/dist/scm/build-command.d.ts +11 -0
- package/dist/scm/build-command.js +23 -0
- package/dist/scm/call.d.ts +25 -0
- package/dist/scm/call.js +38 -0
- package/dist/scm/cli.d.ts +3 -0
- package/dist/scm/cli.js +7 -0
- package/dist/scm/constants.d.ts +11 -0
- package/dist/scm/constants.js +11 -0
- package/dist/scm/errors.d.ts +5 -0
- package/dist/scm/errors.js +8 -0
- package/dist/scm/gh-rest.d.ts +74 -0
- package/dist/scm/gh-rest.js +326 -0
- package/dist/scm/index.d.ts +11 -0
- package/dist/scm/index.js +11 -0
- package/dist/scm/main.d.ts +12 -0
- package/dist/scm/main.js +65 -0
- package/dist/scm/py-format.d.ts +9 -0
- package/dist/scm/py-format.js +31 -0
- package/dist/scm/rest-dispatch.d.ts +14 -0
- package/dist/scm/rest-dispatch.js +175 -0
- package/dist/scope/audit-log.d.ts +14 -0
- package/dist/scope/audit-log.js +186 -0
- package/dist/scope/capacity-stamp.d.ts +3 -0
- package/dist/scope/capacity-stamp.js +45 -0
- package/dist/scope/cli.d.ts +4 -0
- package/dist/scope/cli.js +11 -0
- package/dist/scope/constants.d.ts +19 -0
- package/dist/scope/constants.js +44 -0
- package/dist/scope/decompose.d.ts +42 -0
- package/dist/scope/decompose.js +1016 -0
- package/dist/scope/decomposed-refs.d.ts +6 -0
- package/dist/scope/decomposed-refs.js +173 -0
- package/dist/scope/demote.d.ts +24 -0
- package/dist/scope/demote.js +209 -0
- package/dist/scope/index.d.ts +12 -0
- package/dist/scope/index.js +12 -0
- package/dist/scope/main.d.ts +30 -0
- package/dist/scope/main.js +365 -0
- package/dist/scope/project-context.d.ts +6 -0
- package/dist/scope/project-context.js +55 -0
- package/dist/scope/project-definition-sync.d.ts +3 -0
- package/dist/scope/project-definition-sync.js +157 -0
- package/dist/scope/transition.d.ts +10 -0
- package/dist/scope/transition.js +133 -0
- package/dist/scope/undo.d.ts +25 -0
- package/dist/scope/undo.js +334 -0
- package/dist/scope/vbrief-json.d.ts +4 -0
- package/dist/scope/vbrief-json.js +8 -0
- package/dist/scope/vbrief-ref.d.ts +11 -0
- package/dist/scope/vbrief-ref.js +100 -0
- package/dist/scope/wip-cap-check.d.ts +11 -0
- package/dist/scope/wip-cap-check.js +23 -0
- package/dist/session/git.d.ts +14 -0
- package/dist/session/git.js +49 -0
- package/dist/session/index.d.ts +9 -0
- package/dist/session/index.js +9 -0
- package/dist/session/json.d.ts +7 -0
- package/dist/session/json.js +29 -0
- package/dist/session/resume-conditions.d.ts +56 -0
- package/dist/session/resume-conditions.js +486 -0
- package/dist/session/ritual-entrypoint.d.ts +20 -0
- package/dist/session/ritual-entrypoint.js +86 -0
- package/dist/session/ritual-sentinel.d.ts +58 -0
- package/dist/session/ritual-sentinel.js +338 -0
- package/dist/session/session-start-hook.d.ts +14 -0
- package/dist/session/session-start-hook.js +53 -0
- package/dist/session/session-start.d.ts +41 -0
- package/dist/session/session-start.js +290 -0
- package/dist/session/staleness.d.ts +8 -0
- package/dist/session/staleness.js +91 -0
- package/dist/session/time.d.ts +5 -0
- package/dist/session/time.js +19 -0
- package/dist/session/verify-session-ritual.d.ts +29 -0
- package/dist/session/verify-session-ritual.js +222 -0
- package/dist/slice/cli.d.ts +21 -0
- package/dist/slice/cli.js +248 -0
- package/dist/slice/constants.d.ts +18 -0
- package/dist/slice/constants.js +30 -0
- package/dist/slice/errors.d.ts +9 -0
- package/dist/slice/errors.js +15 -0
- package/dist/slice/existing.d.ts +53 -0
- package/dist/slice/existing.js +344 -0
- package/dist/slice/index.d.ts +10 -0
- package/dist/slice/index.js +10 -0
- package/dist/slice/json.d.ts +7 -0
- package/dist/slice/json.js +25 -0
- package/dist/slice/lock.d.ts +9 -0
- package/dist/slice/lock.js +59 -0
- package/dist/slice/project-context.d.ts +15 -0
- package/dist/slice/project-context.js +87 -0
- package/dist/slice/record.d.ts +50 -0
- package/dist/slice/record.js +139 -0
- package/dist/slice/validate.d.ts +3 -0
- package/dist/slice/validate.js +86 -0
- package/dist/story-ready/allocation.d.ts +14 -0
- package/dist/story-ready/allocation.js +61 -0
- package/dist/story-ready/evaluate.d.ts +23 -0
- package/dist/story-ready/evaluate.js +161 -0
- package/dist/story-ready/git.d.ts +6 -0
- package/dist/story-ready/git.js +26 -0
- package/dist/story-ready/index.d.ts +4 -0
- package/dist/story-ready/index.js +4 -0
- package/dist/subprocess/max-buffer.d.ts +18 -0
- package/dist/subprocess/max-buffer.js +18 -0
- package/dist/swarm/complete-cohort-cli.d.ts +3 -0
- package/dist/swarm/complete-cohort-cli.js +42 -0
- package/dist/swarm/complete-cohort.d.ts +34 -0
- package/dist/swarm/complete-cohort.js +407 -0
- package/dist/swarm/constants.d.ts +18 -0
- package/dist/swarm/constants.js +24 -0
- package/dist/swarm/index.d.ts +18 -0
- package/dist/swarm/index.js +18 -0
- package/dist/swarm/launch-cli.d.ts +5 -0
- package/dist/swarm/launch-cli.js +111 -0
- package/dist/swarm/launch.d.ts +78 -0
- package/dist/swarm/launch.js +587 -0
- package/dist/swarm/readiness-cli.d.ts +3 -0
- package/dist/swarm/readiness-cli.js +25 -0
- package/dist/swarm/readiness.d.ts +24 -0
- package/dist/swarm/readiness.js +606 -0
- package/dist/swarm/routing-set-cli.d.ts +3 -0
- package/dist/swarm/routing-set-cli.js +82 -0
- package/dist/swarm/routing-verify-cli.d.ts +3 -0
- package/dist/swarm/routing-verify-cli.js +51 -0
- package/dist/swarm/routing-verify.d.ts +20 -0
- package/dist/swarm/routing-verify.js +104 -0
- package/dist/swarm/routing.d.ts +57 -0
- package/dist/swarm/routing.js +173 -0
- package/dist/swarm/subagent-backend.d.ts +22 -0
- package/dist/swarm/subagent-backend.js +162 -0
- package/dist/swarm/subprocess.d.ts +10 -0
- package/dist/swarm/subprocess.js +34 -0
- package/dist/swarm/verify-review-clean-cli.d.ts +3 -0
- package/dist/swarm/verify-review-clean-cli.js +38 -0
- package/dist/swarm/verify-review-clean.d.ts +40 -0
- package/dist/swarm/verify-review-clean.js +240 -0
- package/dist/swarm/worktrees-cli.d.ts +9 -0
- package/dist/swarm/worktrees-cli.js +57 -0
- package/dist/swarm/worktrees.d.ts +39 -0
- package/dist/swarm/worktrees.js +178 -0
- package/dist/text/redos-safe.d.ts +29 -0
- package/dist/text/redos-safe.js +338 -0
- package/dist/triage/actions/candidates-log.d.ts +8 -0
- package/dist/triage/actions/candidates-log.js +195 -0
- package/dist/triage/actions/errors.d.ts +17 -0
- package/dist/triage/actions/errors.js +29 -0
- package/dist/triage/actions/index.d.ts +19 -0
- package/dist/triage/actions/index.js +305 -0
- package/dist/triage/actions/resume-on.d.ts +3 -0
- package/dist/triage/actions/resume-on.js +65 -0
- package/dist/triage/actions/types.d.ts +57 -0
- package/dist/triage/actions/types.js +2 -0
- package/dist/triage/bootstrap/gitignore.d.ts +16 -0
- package/dist/triage/bootstrap/gitignore.js +414 -0
- package/dist/triage/bootstrap/index.d.ts +44 -0
- package/dist/triage/bootstrap/index.js +572 -0
- package/dist/triage/bootstrap/types.d.ts +60 -0
- package/dist/triage/bootstrap/types.js +2 -0
- package/dist/triage/bulk/index.d.ts +99 -0
- package/dist/triage/bulk/index.js +454 -0
- package/dist/triage/classify/index.d.ts +88 -0
- package/dist/triage/classify/index.js +738 -0
- package/dist/triage/help/index.d.ts +25 -0
- package/dist/triage/help/index.js +212 -0
- package/dist/triage/help/registry-data.d.ts +555 -0
- package/dist/triage/help/registry-data.js +841 -0
- package/dist/triage/index.d.ts +23 -0
- package/dist/triage/index.js +23 -0
- package/dist/triage/queue/audit.d.ts +12 -0
- package/dist/triage/queue/audit.js +47 -0
- package/dist/triage/queue/build-queue.d.ts +9 -0
- package/dist/triage/queue/build-queue.js +133 -0
- package/dist/triage/queue/cache.d.ts +20 -0
- package/dist/triage/queue/cache.js +169 -0
- package/dist/triage/queue/constants.d.ts +22 -0
- package/dist/triage/queue/constants.js +28 -0
- package/dist/triage/queue/derive-group.d.ts +7 -0
- package/dist/triage/queue/derive-group.js +20 -0
- package/dist/triage/queue/index.d.ts +12 -0
- package/dist/triage/queue/index.js +12 -0
- package/dist/triage/queue/project.d.ts +6 -0
- package/dist/triage/queue/project.js +18 -0
- package/dist/triage/queue/ranking-labels.d.ts +10 -0
- package/dist/triage/queue/ranking-labels.js +54 -0
- package/dist/triage/queue/render.d.ts +9 -0
- package/dist/triage/queue/render.js +35 -0
- package/dist/triage/queue/repo.d.ts +5 -0
- package/dist/triage/queue/repo.js +36 -0
- package/dist/triage/queue/scope-walk.d.ts +13 -0
- package/dist/triage/queue/scope-walk.js +170 -0
- package/dist/triage/queue/selection.d.ts +28 -0
- package/dist/triage/queue/selection.js +109 -0
- package/dist/triage/queue/types.d.ts +58 -0
- package/dist/triage/queue/types.js +2 -0
- package/dist/triage/reconcile/audit.d.ts +4 -0
- package/dist/triage/reconcile/audit.js +62 -0
- package/dist/triage/reconcile/index.d.ts +5 -0
- package/dist/triage/reconcile/index.js +5 -0
- package/dist/triage/reconcile/parse-uri.d.ts +4 -0
- package/dist/triage/reconcile/parse-uri.js +43 -0
- package/dist/triage/reconcile/reconcile.d.ts +17 -0
- package/dist/triage/reconcile/reconcile.js +163 -0
- package/dist/triage/reconcile/types.d.ts +23 -0
- package/dist/triage/reconcile/types.js +70 -0
- package/dist/triage/refresh/drift.d.ts +15 -0
- package/dist/triage/refresh/drift.js +72 -0
- package/dist/triage/refresh/extract.d.ts +3 -0
- package/dist/triage/refresh/extract.js +43 -0
- package/dist/triage/refresh/index.d.ts +5 -0
- package/dist/triage/refresh/index.js +5 -0
- package/dist/triage/refresh/refresh.d.ts +16 -0
- package/dist/triage/refresh/refresh.js +95 -0
- package/dist/triage/refresh/types.d.ts +18 -0
- package/dist/triage/refresh/types.js +7 -0
- package/dist/triage/scope/cli.d.ts +23 -0
- package/dist/triage/scope/cli.js +257 -0
- package/dist/triage/scope/constants.d.ts +16 -0
- package/dist/triage/scope/constants.js +25 -0
- package/dist/triage/scope/coverage.d.ts +24 -0
- package/dist/triage/scope/coverage.js +96 -0
- package/dist/triage/scope/duration.d.ts +6 -0
- package/dist/triage/scope/duration.js +44 -0
- package/dist/triage/scope/evaluate.d.ts +18 -0
- package/dist/triage/scope/evaluate.js +161 -0
- package/dist/triage/scope/index.d.ts +14 -0
- package/dist/triage/scope/index.js +14 -0
- package/dist/triage/scope/milestone.d.ts +13 -0
- package/dist/triage/scope/milestone.js +178 -0
- package/dist/triage/scope/mutations-core.d.ts +24 -0
- package/dist/triage/scope/mutations-core.js +216 -0
- package/dist/triage/scope/mutations.d.ts +21 -0
- package/dist/triage/scope/mutations.js +203 -0
- package/dist/triage/scope/normalize.d.ts +5 -0
- package/dist/triage/scope/normalize.js +45 -0
- package/dist/triage/scope/python-repr.d.ts +7 -0
- package/dist/triage/scope/python-repr.js +25 -0
- package/dist/triage/scope/renderers.d.ts +9 -0
- package/dist/triage/scope/renderers.js +177 -0
- package/dist/triage/scope/resolve.d.ts +15 -0
- package/dist/triage/scope/resolve.js +122 -0
- package/dist/triage/scope/time.d.ts +6 -0
- package/dist/triage/scope/time.js +18 -0
- package/dist/triage/scope/validate.d.ts +11 -0
- package/dist/triage/scope/validate.js +272 -0
- package/dist/triage/scope-drift/add-ignore.d.ts +10 -0
- package/dist/triage/scope-drift/add-ignore.js +78 -0
- package/dist/triage/scope-drift/cache-walker.d.ts +8 -0
- package/dist/triage/scope-drift/cache-walker.js +103 -0
- package/dist/triage/scope-drift/compute.d.ts +9 -0
- package/dist/triage/scope-drift/compute.js +92 -0
- package/dist/triage/scope-drift/index.d.ts +6 -0
- package/dist/triage/scope-drift/index.js +6 -0
- package/dist/triage/scope-drift/render.d.ts +4 -0
- package/dist/triage/scope-drift/render.js +45 -0
- package/dist/triage/scope-drift/scope-rules.d.ts +16 -0
- package/dist/triage/scope-drift/scope-rules.js +149 -0
- package/dist/triage/scope-drift/types.d.ts +13 -0
- package/dist/triage/scope-drift/types.js +8 -0
- package/dist/triage/smoketest/index.d.ts +81 -0
- package/dist/triage/smoketest/index.js +335 -0
- package/dist/triage/subscribe/index.d.ts +38 -0
- package/dist/triage/subscribe/index.js +303 -0
- package/dist/triage/summary/index.d.ts +70 -0
- package/dist/triage/summary/index.js +431 -0
- package/dist/triage/summary/reconcilable.d.ts +12 -0
- package/dist/triage/summary/reconcilable.js +150 -0
- package/dist/triage/summary/scope-drift.d.ts +5 -0
- package/dist/triage/summary/scope-drift.js +219 -0
- package/dist/triage/welcome/constants.d.ts +24 -0
- package/dist/triage/welcome/constants.js +34 -0
- package/dist/triage/welcome/default-mode.d.ts +21 -0
- package/dist/triage/welcome/default-mode.js +48 -0
- package/dist/triage/welcome/index.d.ts +6 -0
- package/dist/triage/welcome/index.js +6 -0
- package/dist/triage/welcome/prior-state.d.ts +17 -0
- package/dist/triage/welcome/prior-state.js +170 -0
- package/dist/triage/welcome/summary.d.ts +23 -0
- package/dist/triage/welcome/summary.js +303 -0
- package/dist/triage/welcome/writers.d.ts +17 -0
- package/dist/triage/welcome/writers.js +157 -0
- package/dist/ts-check-lane/index.d.ts +3 -0
- package/dist/ts-check-lane/index.js +2 -0
- package/dist/ts-check-lane/run-lane.d.ts +53 -0
- package/dist/ts-check-lane/run-lane.js +98 -0
- package/dist/validate-content/capacity-policy.d.ts +82 -0
- package/dist/validate-content/capacity-policy.js +399 -0
- package/dist/validate-content/capacity-show.d.ts +60 -0
- package/dist/validate-content/capacity-show.js +336 -0
- package/dist/validate-content/filename.d.ts +3 -0
- package/dist/validate-content/filename.js +54 -0
- package/dist/validate-content/index.d.ts +9 -0
- package/dist/validate-content/index.js +9 -0
- package/dist/validate-content/link-parser.d.ts +5 -0
- package/dist/validate-content/link-parser.js +42 -0
- package/dist/validate-content/types.d.ts +8 -0
- package/dist/validate-content/types.js +2 -0
- package/dist/validate-content/validate-links.d.ts +17 -0
- package/dist/validate-content/validate-links.js +114 -0
- package/dist/validate-content/validate-strategy-output.d.ts +11 -0
- package/dist/validate-content/validate-strategy-output.js +120 -0
- package/dist/validate-content/verify-capacity.d.ts +14 -0
- package/dist/validate-content/verify-capacity.js +96 -0
- package/dist/vbrief-activate/activate.d.ts +13 -0
- package/dist/vbrief-activate/activate.js +184 -0
- package/dist/vbrief-activate/constants.d.ts +9 -0
- package/dist/vbrief-activate/constants.js +11 -0
- package/dist/vbrief-activate/index.d.ts +6 -0
- package/dist/vbrief-activate/index.js +4 -0
- package/dist/vbrief-activate/main.d.ts +14 -0
- package/dist/vbrief-activate/main.js +33 -0
- package/dist/vbrief-build/build.d.ts +13 -0
- package/dist/vbrief-build/build.js +123 -0
- package/dist/vbrief-build/constants.d.ts +13 -0
- package/dist/vbrief-build/constants.js +34 -0
- package/dist/vbrief-build/index.d.ts +12 -0
- package/dist/vbrief-build/index.js +11 -0
- package/dist/vbrief-build/json.d.ts +3 -0
- package/dist/vbrief-build/json.js +5 -0
- package/dist/vbrief-build/main.d.ts +5 -0
- package/dist/vbrief-build/main.js +65 -0
- package/dist/vbrief-build/parity-scenarios.d.ts +19 -0
- package/dist/vbrief-build/parity-scenarios.js +321 -0
- package/dist/vbrief-build/project-definition-io.d.ts +13 -0
- package/dist/vbrief-build/project-definition-io.js +117 -0
- package/dist/vbrief-build/routing.d.ts +13 -0
- package/dist/vbrief-build/routing.js +110 -0
- package/dist/vbrief-build/sources.d.ts +16 -0
- package/dist/vbrief-build/sources.js +294 -0
- package/dist/vbrief-build/speckit.d.ts +23 -0
- package/dist/vbrief-build/speckit.js +212 -0
- package/dist/vbrief-build/types.d.ts +18 -0
- package/dist/vbrief-build/types.js +7 -0
- package/dist/vbrief-reconcile/graph.d.ts +11 -0
- package/dist/vbrief-reconcile/graph.js +171 -0
- package/dist/vbrief-reconcile/index.d.ts +10 -0
- package/dist/vbrief-reconcile/index.js +9 -0
- package/dist/vbrief-reconcile/labels.d.ts +22 -0
- package/dist/vbrief-reconcile/labels.js +252 -0
- package/dist/vbrief-reconcile/main.d.ts +18 -0
- package/dist/vbrief-reconcile/main.js +149 -0
- package/dist/vbrief-reconcile/parity-scenarios.d.ts +16 -0
- package/dist/vbrief-reconcile/parity-scenarios.js +385 -0
- package/dist/vbrief-reconcile/py-repr.d.ts +3 -0
- package/dist/vbrief-reconcile/py-repr.js +5 -0
- package/dist/vbrief-reconcile/reconciliation.d.ts +20 -0
- package/dist/vbrief-reconcile/reconciliation.js +542 -0
- package/dist/vbrief-reconcile/swarm-deps.d.ts +8 -0
- package/dist/vbrief-reconcile/swarm-deps.js +142 -0
- package/dist/vbrief-reconcile/types.d.ts +128 -0
- package/dist/vbrief-reconcile/types.js +2 -0
- package/dist/vbrief-reconcile/umbrellas.d.ts +48 -0
- package/dist/vbrief-reconcile/umbrellas.js +462 -0
- package/dist/vbrief-validate/conformance.d.ts +26 -0
- package/dist/vbrief-validate/conformance.js +273 -0
- package/dist/vbrief-validate/constants.d.ts +13 -0
- package/dist/vbrief-validate/constants.js +36 -0
- package/dist/vbrief-validate/decomposition.d.ts +3 -0
- package/dist/vbrief-validate/decomposition.js +38 -0
- package/dist/vbrief-validate/epic-links.d.ts +4 -0
- package/dist/vbrief-validate/epic-links.js +152 -0
- package/dist/vbrief-validate/filename.d.ts +5 -0
- package/dist/vbrief-validate/filename.js +62 -0
- package/dist/vbrief-validate/folder-status.d.ts +4 -0
- package/dist/vbrief-validate/folder-status.js +30 -0
- package/dist/vbrief-validate/index.d.ts +14 -0
- package/dist/vbrief-validate/index.js +11 -0
- package/dist/vbrief-validate/main.d.ts +17 -0
- package/dist/vbrief-validate/main.js +127 -0
- package/dist/vbrief-validate/origin.d.ts +4 -0
- package/dist/vbrief-validate/origin.js +76 -0
- package/dist/vbrief-validate/paths.d.ts +11 -0
- package/dist/vbrief-validate/paths.js +83 -0
- package/dist/vbrief-validate/placeholders.d.ts +3 -0
- package/dist/vbrief-validate/placeholders.js +33 -0
- package/dist/vbrief-validate/plan-hooks.d.ts +9 -0
- package/dist/vbrief-validate/plan-hooks.js +145 -0
- package/dist/vbrief-validate/precutover.d.ts +7 -0
- package/dist/vbrief-validate/precutover.js +30 -0
- package/dist/vbrief-validate/project-definition.d.ts +4 -0
- package/dist/vbrief-validate/project-definition.js +166 -0
- package/dist/vbrief-validate/schema.d.ts +8 -0
- package/dist/vbrief-validate/schema.js +150 -0
- package/dist/vbrief-validate/staleness.d.ts +3 -0
- package/dist/vbrief-validate/staleness.js +106 -0
- package/dist/vbrief-validate/validate-all.d.ts +17 -0
- package/dist/vbrief-validate/validate-all.js +119 -0
- package/dist/vbrief-validation/fidelity.d.ts +22 -0
- package/dist/vbrief-validation/fidelity.js +508 -0
- package/dist/vbrief-validation/index.d.ts +11 -0
- package/dist/vbrief-validation/index.js +8 -0
- package/dist/vbrief-validation/legacy-sections.d.ts +13 -0
- package/dist/vbrief-validation/legacy-sections.js +124 -0
- package/dist/vbrief-validation/main.d.ts +5 -0
- package/dist/vbrief-validation/main.js +65 -0
- package/dist/vbrief-validation/normalize.d.ts +22 -0
- package/dist/vbrief-validation/normalize.js +126 -0
- package/dist/vbrief-validation/parity-scenarios.d.ts +14 -0
- package/dist/vbrief-validation/parity-scenarios.js +523 -0
- package/dist/vbrief-validation/safety.d.ts +38 -0
- package/dist/vbrief-validation/safety.js +422 -0
- package/dist/vbrief-validation/story-quality.d.ts +29 -0
- package/dist/vbrief-validation/story-quality.js +452 -0
- package/dist/vbrief-validation/types.d.ts +58 -0
- package/dist/vbrief-validation/types.js +2 -0
- package/dist/vbrief-validation/validation.d.ts +15 -0
- package/dist/vbrief-validation/validation.js +123 -0
- package/dist/verify-env/index.d.ts +6 -0
- package/dist/verify-env/index.js +6 -0
- package/dist/verify-env/node-runtime.d.ts +6 -0
- package/dist/verify-env/node-runtime.js +11 -0
- package/dist/verify-env/toolchain-check.d.ts +28 -0
- package/dist/verify-env/toolchain-check.js +68 -0
- package/dist/verify-env/verify-hooks-installed.d.ts +21 -0
- package/dist/verify-env/verify-hooks-installed.js +162 -0
- package/dist/verify-env/verify-no-task-runtime.d.ts +20 -0
- package/dist/verify-env/verify-no-task-runtime.js +383 -0
- package/dist/verify-env/verify-tools.d.ts +59 -0
- package/dist/verify-env/verify-tools.js +354 -0
- package/dist/verify-source/code-structure-validate.d.ts +48 -0
- package/dist/verify-source/code-structure-validate.js +678 -0
- package/dist/verify-source/content-manifest.d.ts +102 -0
- package/dist/verify-source/content-manifest.js +282 -0
- package/dist/verify-source/index.d.ts +7 -0
- package/dist/verify-source/index.js +7 -0
- package/dist/verify-source/python-call-scan.d.ts +14 -0
- package/dist/verify-source/python-call-scan.js +137 -0
- package/dist/verify-source/rule-ownership-lint.d.ts +33 -0
- package/dist/verify-source/rule-ownership-lint.js +179 -0
- package/dist/verify-source/scm-boundary.d.ts +26 -0
- package/dist/verify-source/scm-boundary.js +170 -0
- package/dist/verify-source/verify-stubs.d.ts +19 -0
- package/dist/verify-source/verify-stubs.js +185 -0
- package/dist/wip-cap/evaluate.d.ts +17 -0
- package/dist/wip-cap/evaluate.js +62 -0
- package/dist/wip-cap/index.d.ts +2 -0
- package/dist/wip-cap/index.js +2 -0
- package/package.json +206 -0
|
@@ -0,0 +1,1016 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* scope/decompose.ts -- Apply or validate an approved epic/phase -> story decomposition draft.
|
|
3
|
+
*
|
|
4
|
+
* Faithful TypeScript port of scripts/scope_decompose.py + scripts/_vbrief_story_quality.py.
|
|
5
|
+
* The command is deterministic: it never invents stories from a parent scope.
|
|
6
|
+
* A caller supplies a draft with child story definitions; this module validates
|
|
7
|
+
* that draft, writes the child story vBRIEFs, and updates the parent scope references.
|
|
8
|
+
*/
|
|
9
|
+
import { accessSync, constants, existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
10
|
+
import { basename, dirname, isAbsolute, join, resolve } from "node:path";
|
|
11
|
+
import { referenceWithDefaultTrust, slugify } from "../vbrief-build/build.js";
|
|
12
|
+
import { EMITTED_VBRIEF_VERSION } from "../vbrief-build/constants.js";
|
|
13
|
+
import { formatVbriefJson } from "./vbrief-json.js";
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
// Constants
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
const LIFECYCLE_FOLDERS = new Set(["proposed", "pending", "active", "completed", "cancelled"]);
|
|
18
|
+
const ACTIVE_DECOMPOSITION_STATUSES = new Set(["active", "running"]);
|
|
19
|
+
const READY = "ready";
|
|
20
|
+
const STORY_READINESS_STATES = new Set([READY, "sequential", "needs_refinement"]);
|
|
21
|
+
// ---------------------------------------------------------------------------
|
|
22
|
+
// DecompositionError
|
|
23
|
+
// ---------------------------------------------------------------------------
|
|
24
|
+
export class DecompositionError extends Error {
|
|
25
|
+
constructor(message) {
|
|
26
|
+
super(message);
|
|
27
|
+
this.name = "DecompositionError";
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
// ---------------------------------------------------------------------------
|
|
31
|
+
// File I/O helpers
|
|
32
|
+
// ---------------------------------------------------------------------------
|
|
33
|
+
function loadJson(path) {
|
|
34
|
+
let raw;
|
|
35
|
+
try {
|
|
36
|
+
raw = readFileSync(path, "utf8");
|
|
37
|
+
}
|
|
38
|
+
catch (err) {
|
|
39
|
+
throw new DecompositionError(`${path}: cannot read file: ${String(err)}`);
|
|
40
|
+
}
|
|
41
|
+
let data;
|
|
42
|
+
try {
|
|
43
|
+
data = JSON.parse(raw);
|
|
44
|
+
}
|
|
45
|
+
catch (err) {
|
|
46
|
+
throw new DecompositionError(`${path}: invalid JSON: ${String(err)}`);
|
|
47
|
+
}
|
|
48
|
+
if (typeof data !== "object" || data === null || Array.isArray(data)) {
|
|
49
|
+
throw new DecompositionError(`${path}: expected a JSON object`);
|
|
50
|
+
}
|
|
51
|
+
return data;
|
|
52
|
+
}
|
|
53
|
+
function writeJson(path, data) {
|
|
54
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
55
|
+
writeFileSync(path, formatVbriefJson(data), "utf8");
|
|
56
|
+
}
|
|
57
|
+
// ---------------------------------------------------------------------------
|
|
58
|
+
// Story quality helpers (ported from _vbrief_story_quality.py)
|
|
59
|
+
// ---------------------------------------------------------------------------
|
|
60
|
+
const BROAD_FILE_SCOPE_ROOTS = new Set(["backend", "frontend", "docs", "vbrief"]);
|
|
61
|
+
const CODE_PATH_TERMS = [
|
|
62
|
+
"api",
|
|
63
|
+
"cli",
|
|
64
|
+
"component",
|
|
65
|
+
"config",
|
|
66
|
+
"database",
|
|
67
|
+
"endpoint",
|
|
68
|
+
"file",
|
|
69
|
+
"handler",
|
|
70
|
+
"model",
|
|
71
|
+
"module",
|
|
72
|
+
"repository",
|
|
73
|
+
"route",
|
|
74
|
+
"schema",
|
|
75
|
+
"script",
|
|
76
|
+
"service",
|
|
77
|
+
"source",
|
|
78
|
+
"src/",
|
|
79
|
+
];
|
|
80
|
+
const VERIFY_EVIDENCE_TERMS = [
|
|
81
|
+
"assert",
|
|
82
|
+
"evidence",
|
|
83
|
+
"fixture",
|
|
84
|
+
"report",
|
|
85
|
+
"spec",
|
|
86
|
+
"test",
|
|
87
|
+
"tests/",
|
|
88
|
+
"verify",
|
|
89
|
+
];
|
|
90
|
+
const GENERIC_VERIFY_COMMANDS = new Set([
|
|
91
|
+
"cargo test",
|
|
92
|
+
"go test ./...",
|
|
93
|
+
"npm run test",
|
|
94
|
+
"npm test",
|
|
95
|
+
"pytest",
|
|
96
|
+
"task check",
|
|
97
|
+
]);
|
|
98
|
+
const PLACEHOLDER_ACCEPTANCE_PATTERNS = [
|
|
99
|
+
"acceptance criteria for",
|
|
100
|
+
"copy from parent",
|
|
101
|
+
"copy from specification",
|
|
102
|
+
"placeholder",
|
|
103
|
+
"refine from parent",
|
|
104
|
+
"tbd",
|
|
105
|
+
"to be defined",
|
|
106
|
+
"to refine",
|
|
107
|
+
"to refine from parent scope",
|
|
108
|
+
"todo",
|
|
109
|
+
];
|
|
110
|
+
const DOCS_ONLY_ACCEPTANCE_PATTERNS = [
|
|
111
|
+
"docs updated",
|
|
112
|
+
"documentation updated",
|
|
113
|
+
"readme updated",
|
|
114
|
+
"update docs",
|
|
115
|
+
"update documentation",
|
|
116
|
+
"update readme",
|
|
117
|
+
];
|
|
118
|
+
const GENERIC_IMPLEMENTATION_PATTERNS = [
|
|
119
|
+
"add tests so it works",
|
|
120
|
+
"change the code",
|
|
121
|
+
"implement the feature",
|
|
122
|
+
"make it work",
|
|
123
|
+
"update the code",
|
|
124
|
+
"works as expected",
|
|
125
|
+
];
|
|
126
|
+
const VAGUE_ACCEPTANCE_PATTERNS = [
|
|
127
|
+
"displays a message",
|
|
128
|
+
"handles errors",
|
|
129
|
+
"is implemented",
|
|
130
|
+
"is updated",
|
|
131
|
+
"passes tests",
|
|
132
|
+
"shows a message",
|
|
133
|
+
"the system displays a message",
|
|
134
|
+
"updates the ui",
|
|
135
|
+
"works as expected",
|
|
136
|
+
];
|
|
137
|
+
const OBSERVABLE_TERMS = [
|
|
138
|
+
"blocks",
|
|
139
|
+
"creates",
|
|
140
|
+
"deletes",
|
|
141
|
+
"displays",
|
|
142
|
+
"emits",
|
|
143
|
+
"fails",
|
|
144
|
+
"persists",
|
|
145
|
+
"records",
|
|
146
|
+
"redirects",
|
|
147
|
+
"rejects",
|
|
148
|
+
"renders",
|
|
149
|
+
"returns",
|
|
150
|
+
"saves",
|
|
151
|
+
"shows",
|
|
152
|
+
"stores",
|
|
153
|
+
"updates",
|
|
154
|
+
"validates",
|
|
155
|
+
"when ",
|
|
156
|
+
"given ",
|
|
157
|
+
"then ",
|
|
158
|
+
];
|
|
159
|
+
const USER_STORY_RE = /^\s*As\s+an?\s+[^,]+,\s*I\s+want\s+.+,\s*so\s+that\s+.+\.\s*$/is;
|
|
160
|
+
export function asStrList(value) {
|
|
161
|
+
if (value === null || value === undefined)
|
|
162
|
+
return [];
|
|
163
|
+
if (typeof value === "string")
|
|
164
|
+
return value.trim().length > 0 ? [value.trim()] : [];
|
|
165
|
+
if (Array.isArray(value)) {
|
|
166
|
+
return value.map((item) => String(item).trim()).filter((s) => s.length > 0);
|
|
167
|
+
}
|
|
168
|
+
return [];
|
|
169
|
+
}
|
|
170
|
+
export function acceptanceTextsFromItems(items) {
|
|
171
|
+
const texts = [];
|
|
172
|
+
if (!Array.isArray(items))
|
|
173
|
+
return texts;
|
|
174
|
+
for (const item of items) {
|
|
175
|
+
if (typeof item !== "object" || item === null || Array.isArray(item))
|
|
176
|
+
continue;
|
|
177
|
+
const obj = item;
|
|
178
|
+
const narrative = obj.narrative;
|
|
179
|
+
if (typeof narrative === "object" && narrative !== null && !Array.isArray(narrative)) {
|
|
180
|
+
const acc = narrative.Acceptance;
|
|
181
|
+
if (typeof acc === "string" && acc.trim().length > 0)
|
|
182
|
+
texts.push(acc.trim());
|
|
183
|
+
}
|
|
184
|
+
for (const childKey of ["items", "subItems"]) {
|
|
185
|
+
texts.push(...acceptanceTextsFromItems(obj[childKey]));
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return texts;
|
|
189
|
+
}
|
|
190
|
+
export function itemHasAcceptance(item) {
|
|
191
|
+
const narrative = item.narrative;
|
|
192
|
+
if (typeof narrative === "object" && narrative !== null && !Array.isArray(narrative)) {
|
|
193
|
+
const acc = narrative.Acceptance;
|
|
194
|
+
if (typeof acc === "string" && acc.trim().length > 0)
|
|
195
|
+
return true;
|
|
196
|
+
}
|
|
197
|
+
for (const childKey of ["items", "subItems"]) {
|
|
198
|
+
const children = item[childKey];
|
|
199
|
+
if (Array.isArray(children)) {
|
|
200
|
+
for (const child of children) {
|
|
201
|
+
if (typeof child === "object" && child !== null && !Array.isArray(child)) {
|
|
202
|
+
if (itemHasAcceptance(child))
|
|
203
|
+
return true;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
return false;
|
|
209
|
+
}
|
|
210
|
+
export function itemsHaveAcceptance(items) {
|
|
211
|
+
if (!Array.isArray(items))
|
|
212
|
+
return false;
|
|
213
|
+
return items.some((item) => typeof item === "object" &&
|
|
214
|
+
item !== null &&
|
|
215
|
+
!Array.isArray(item) &&
|
|
216
|
+
itemHasAcceptance(item));
|
|
217
|
+
}
|
|
218
|
+
export function itemHasTraces(item) {
|
|
219
|
+
const narrative = item.narrative;
|
|
220
|
+
if (typeof narrative === "object" && narrative !== null && !Array.isArray(narrative)) {
|
|
221
|
+
const val = narrative.Traces;
|
|
222
|
+
if (typeof val === "string" && val.trim().length > 0)
|
|
223
|
+
return true;
|
|
224
|
+
}
|
|
225
|
+
for (const childKey of ["items", "subItems"]) {
|
|
226
|
+
const children = item[childKey];
|
|
227
|
+
if (Array.isArray(children)) {
|
|
228
|
+
for (const child of children) {
|
|
229
|
+
if (typeof child === "object" && child !== null && !Array.isArray(child)) {
|
|
230
|
+
if (itemHasTraces(child))
|
|
231
|
+
return true;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
return false;
|
|
237
|
+
}
|
|
238
|
+
export function missingRequiredSwarmFields(swarm) {
|
|
239
|
+
const missing = [];
|
|
240
|
+
for (const key of ["file_scope", "verify_commands", "expected_outputs"]) {
|
|
241
|
+
if (asStrList(swarm[key]).length === 0)
|
|
242
|
+
missing.push(`plan.metadata.swarm.${key}`);
|
|
243
|
+
}
|
|
244
|
+
if (!("depends_on" in swarm))
|
|
245
|
+
missing.push("plan.metadata.swarm.depends_on");
|
|
246
|
+
for (const key of ["conflict_group", "size", "file_scope_confidence", "model_tier"]) {
|
|
247
|
+
const val = swarm[key];
|
|
248
|
+
if (typeof val !== "string" || val.trim().length === 0) {
|
|
249
|
+
missing.push(`plan.metadata.swarm.${key}`);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
return missing;
|
|
253
|
+
}
|
|
254
|
+
export function deprecatedSubitemsIssues(items, prefix = "plan.items") {
|
|
255
|
+
const issues = [];
|
|
256
|
+
function visit(children, path) {
|
|
257
|
+
if (!Array.isArray(children))
|
|
258
|
+
return;
|
|
259
|
+
for (let i = 0; i < children.length; i += 1) {
|
|
260
|
+
const item = children[i];
|
|
261
|
+
if (typeof item !== "object" || item === null || Array.isArray(item))
|
|
262
|
+
continue;
|
|
263
|
+
const obj = item;
|
|
264
|
+
const itemPath = `${path}[${i}]`;
|
|
265
|
+
if ("subItems" in obj)
|
|
266
|
+
issues.push(`${itemPath}.subItems is deprecated; use items`);
|
|
267
|
+
visit(obj.items, `${itemPath}.items`);
|
|
268
|
+
visit(obj.subItems, `${itemPath}.subItems`);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
visit(items, prefix);
|
|
272
|
+
return issues;
|
|
273
|
+
}
|
|
274
|
+
function sentenceCount(value) {
|
|
275
|
+
return value
|
|
276
|
+
.trim()
|
|
277
|
+
.split(/[.!?]+(?:\s+|$)/)
|
|
278
|
+
.filter((p) => p.trim().length > 0).length;
|
|
279
|
+
}
|
|
280
|
+
function stepCount(value) {
|
|
281
|
+
const lines = value
|
|
282
|
+
.split("\n")
|
|
283
|
+
.map((l) => l.trim())
|
|
284
|
+
.filter(Boolean);
|
|
285
|
+
const bulletLines = lines.filter((l) => /^([-*]|\d+[.)])\s+/.test(l));
|
|
286
|
+
if (bulletLines.length >= 2)
|
|
287
|
+
return bulletLines.length;
|
|
288
|
+
return sentenceCount(value);
|
|
289
|
+
}
|
|
290
|
+
function wordCount(value) {
|
|
291
|
+
return (value.match(/\b\w+\b/g) ?? []).length;
|
|
292
|
+
}
|
|
293
|
+
function normalizeStr(value) {
|
|
294
|
+
return value
|
|
295
|
+
.toLowerCase()
|
|
296
|
+
.replace(/[^a-z0-9]+/g, " ")
|
|
297
|
+
.trim();
|
|
298
|
+
}
|
|
299
|
+
function normalizeCommand(value) {
|
|
300
|
+
return value.trim().toLowerCase().replace(/\s+/g, " ");
|
|
301
|
+
}
|
|
302
|
+
function dedupe(values) {
|
|
303
|
+
return [...new Set(values)];
|
|
304
|
+
}
|
|
305
|
+
function descriptionIssues(description) {
|
|
306
|
+
if (!description.trim())
|
|
307
|
+
return ["plan.narratives.Description is required"];
|
|
308
|
+
if (sentenceCount(description) < 2 || wordCount(description) < 20) {
|
|
309
|
+
return ["plan.narratives.Description must contain at least two concrete sentences"];
|
|
310
|
+
}
|
|
311
|
+
return [];
|
|
312
|
+
}
|
|
313
|
+
function implementationPlanIssues(implementationPlan) {
|
|
314
|
+
if (!implementationPlan.trim())
|
|
315
|
+
return ["plan.narratives.ImplementationPlan is required"];
|
|
316
|
+
const issues = [];
|
|
317
|
+
if (stepCount(implementationPlan) < 2 || wordCount(implementationPlan) < 20) {
|
|
318
|
+
issues.push("plan.narratives.ImplementationPlan must contain at least two concrete steps");
|
|
319
|
+
}
|
|
320
|
+
const lower = implementationPlan.toLowerCase();
|
|
321
|
+
if (PLACEHOLDER_ACCEPTANCE_PATTERNS.some((p) => lower.includes(p))) {
|
|
322
|
+
issues.push("plan.narratives.ImplementationPlan must not be placeholder text");
|
|
323
|
+
}
|
|
324
|
+
if (GENERIC_IMPLEMENTATION_PATTERNS.some((p) => lower.includes(p)) ||
|
|
325
|
+
!(CODE_PATH_TERMS.some((t) => lower.includes(t)) &&
|
|
326
|
+
VERIFY_EVIDENCE_TERMS.some((t) => lower.includes(t)))) {
|
|
327
|
+
issues.push("plan.narratives.ImplementationPlan must identify concrete code paths and verification evidence");
|
|
328
|
+
}
|
|
329
|
+
return issues;
|
|
330
|
+
}
|
|
331
|
+
function fileScopeIssues(swarm) {
|
|
332
|
+
const issues = [];
|
|
333
|
+
for (const filePath of asStrList(swarm.file_scope)) {
|
|
334
|
+
const normalized = filePath.trim().replace(/^\/+|\/+$/g, "");
|
|
335
|
+
const root = normalized.split("/")[0] ?? "";
|
|
336
|
+
if (/[*?[]/.test(normalized) ||
|
|
337
|
+
BROAD_FILE_SCOPE_ROOTS.has(normalized) ||
|
|
338
|
+
filePath.replace(/\/$/, "") in BROAD_FILE_SCOPE_ROOTS ||
|
|
339
|
+
(BROAD_FILE_SCOPE_ROOTS.has(root) && (normalized === root || normalized === `${root}/*`))) {
|
|
340
|
+
issues.push(`broad file_scope is not swarm-ready: ${filePath}`);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
return issues;
|
|
344
|
+
}
|
|
345
|
+
function verifyCommandIssues(swarm) {
|
|
346
|
+
const commands = asStrList(swarm.verify_commands).map((c) => c.toLowerCase());
|
|
347
|
+
if (commands.length === 1 && GENERIC_VERIFY_COMMANDS.has(normalizeCommand(commands[0] ?? ""))) {
|
|
348
|
+
return [`generic verify command is not swarm-ready: ${commands[0]}`];
|
|
349
|
+
}
|
|
350
|
+
return [];
|
|
351
|
+
}
|
|
352
|
+
export function storyQualityIssues(opts) {
|
|
353
|
+
const { title, description, implementationPlan, userStory, acceptanceTexts, acceptanceCountJustification, swarm, concurrentReady = true, } = opts;
|
|
354
|
+
const issues = [];
|
|
355
|
+
if (!USER_STORY_RE.test(userStory ?? "")) {
|
|
356
|
+
issues.push("UserStory must match 'As a <role>, I want <capability>, so that <outcome>.'");
|
|
357
|
+
}
|
|
358
|
+
issues.push(...descriptionIssues(description));
|
|
359
|
+
issues.push(...implementationPlanIssues(implementationPlan));
|
|
360
|
+
if (!(acceptanceTexts.length >= 2 && acceptanceTexts.length <= 5) &&
|
|
361
|
+
!acceptanceCountJustification.trim()) {
|
|
362
|
+
issues.push("2-5 acceptance criteria required unless justified");
|
|
363
|
+
}
|
|
364
|
+
const normalizedTitle = normalizeStr(title);
|
|
365
|
+
const normalizedDescription = normalizeStr(description);
|
|
366
|
+
for (const criterion of acceptanceTexts) {
|
|
367
|
+
const lower = criterion.toLowerCase();
|
|
368
|
+
const normalized = normalizeStr(criterion);
|
|
369
|
+
if (PLACEHOLDER_ACCEPTANCE_PATTERNS.some((p) => lower.includes(p))) {
|
|
370
|
+
issues.push("placeholder acceptance criterion");
|
|
371
|
+
}
|
|
372
|
+
if (normalized && (normalized === normalizedTitle || normalized === normalizedDescription)) {
|
|
373
|
+
issues.push("acceptance criterion duplicates title or description");
|
|
374
|
+
}
|
|
375
|
+
if (DOCS_ONLY_ACCEPTANCE_PATTERNS.some((p) => lower.includes(p))) {
|
|
376
|
+
issues.push("vague docs-only acceptance criterion");
|
|
377
|
+
}
|
|
378
|
+
if (wordCount(criterion) < 8 || VAGUE_ACCEPTANCE_PATTERNS.some((p) => lower.includes(p))) {
|
|
379
|
+
issues.push("acceptance criterion must describe specific observable behavior");
|
|
380
|
+
}
|
|
381
|
+
if (!OBSERVABLE_TERMS.some((t) => lower.includes(t))) {
|
|
382
|
+
issues.push("acceptance criterion must describe observable behavior");
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
if (concurrentReady) {
|
|
386
|
+
issues.push(...fileScopeIssues(swarm));
|
|
387
|
+
issues.push(...verifyCommandIssues(swarm));
|
|
388
|
+
if (swarm.parallel_safe === false) {
|
|
389
|
+
issues.push("readiness=ready requires parallel_safe=true; use readiness=sequential or needs_refinement for non-concurrent work");
|
|
390
|
+
}
|
|
391
|
+
if (swarm.file_scope_confidence === "low") {
|
|
392
|
+
issues.push("readiness=ready requires file_scope_confidence above low");
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
return dedupe(issues);
|
|
396
|
+
}
|
|
397
|
+
// ---------------------------------------------------------------------------
|
|
398
|
+
// Path helpers
|
|
399
|
+
// ---------------------------------------------------------------------------
|
|
400
|
+
function vbriefDir(projectRoot) {
|
|
401
|
+
return join(resolve(projectRoot), "vbrief");
|
|
402
|
+
}
|
|
403
|
+
function relToVbrief(vbriefDirPath, path) {
|
|
404
|
+
const resolvedPath = resolve(path);
|
|
405
|
+
const resolvedVbrief = resolve(vbriefDirPath);
|
|
406
|
+
if (resolvedPath.startsWith(`${resolvedVbrief}/`) || resolvedPath === resolvedVbrief) {
|
|
407
|
+
return resolvedPath.slice(resolvedVbrief.length + 1).replace(/\\/g, "/");
|
|
408
|
+
}
|
|
409
|
+
throw new DecompositionError(`${path}: path must be inside ${vbriefDirPath}`);
|
|
410
|
+
}
|
|
411
|
+
function defaultStatusForFolderName(folderName) {
|
|
412
|
+
const map = {
|
|
413
|
+
proposed: "proposed",
|
|
414
|
+
pending: "pending",
|
|
415
|
+
active: "running",
|
|
416
|
+
completed: "completed",
|
|
417
|
+
cancelled: "cancelled",
|
|
418
|
+
};
|
|
419
|
+
return map[folderName] ?? "pending";
|
|
420
|
+
}
|
|
421
|
+
function normalizeStatus(value, defaultStatus) {
|
|
422
|
+
if (value === null || value === undefined)
|
|
423
|
+
return defaultStatus;
|
|
424
|
+
const s = String(value).trim().toLowerCase();
|
|
425
|
+
return s.length > 0 ? s : defaultStatus;
|
|
426
|
+
}
|
|
427
|
+
function isValidCreationDate(value) {
|
|
428
|
+
if (value.length !== 10)
|
|
429
|
+
return false;
|
|
430
|
+
const d = new Date(`${value}T00:00:00Z`);
|
|
431
|
+
if (Number.isNaN(d.getTime()))
|
|
432
|
+
return false;
|
|
433
|
+
return d.toISOString().slice(0, 10) === value;
|
|
434
|
+
}
|
|
435
|
+
// ---------------------------------------------------------------------------
|
|
436
|
+
// Story extraction helpers
|
|
437
|
+
// ---------------------------------------------------------------------------
|
|
438
|
+
function storySpecs(draft) {
|
|
439
|
+
let stories = draft.stories ?? draft.children ?? [];
|
|
440
|
+
if (typeof stories === "object" && stories !== null && !Array.isArray(stories)) {
|
|
441
|
+
stories = Object.values(stories);
|
|
442
|
+
}
|
|
443
|
+
if (!Array.isArray(stories)) {
|
|
444
|
+
throw new DecompositionError("draft must contain a stories array");
|
|
445
|
+
}
|
|
446
|
+
const normalized = [];
|
|
447
|
+
for (let i = 0; i < stories.length; i += 1) {
|
|
448
|
+
const story = stories[i];
|
|
449
|
+
if (typeof story !== "object" || story === null || Array.isArray(story)) {
|
|
450
|
+
throw new DecompositionError(`stories[${i + 1}] must be an object`);
|
|
451
|
+
}
|
|
452
|
+
normalized.push(story);
|
|
453
|
+
}
|
|
454
|
+
return normalized;
|
|
455
|
+
}
|
|
456
|
+
function storyId(story, index) {
|
|
457
|
+
const raw = story.id ?? story.story_id ?? story.key;
|
|
458
|
+
if (typeof raw === "string" && raw.trim().length > 0)
|
|
459
|
+
return raw.trim();
|
|
460
|
+
const title = String(story.title ?? `story-${index}`);
|
|
461
|
+
return slugify(title) || `story-${index}`;
|
|
462
|
+
}
|
|
463
|
+
function swarmMeta(story) {
|
|
464
|
+
const metadata = typeof story.metadata === "object" && story.metadata !== null && !Array.isArray(story.metadata)
|
|
465
|
+
? story.metadata
|
|
466
|
+
: {};
|
|
467
|
+
let swarm = story.swarm ?? metadata.swarm ?? {};
|
|
468
|
+
if (typeof swarm !== "object" || swarm === null || Array.isArray(swarm))
|
|
469
|
+
swarm = {};
|
|
470
|
+
const swarmObj = swarm;
|
|
471
|
+
for (const key of [
|
|
472
|
+
"readiness",
|
|
473
|
+
"parallel_safe",
|
|
474
|
+
"file_scope",
|
|
475
|
+
"verify_commands",
|
|
476
|
+
"expected_outputs",
|
|
477
|
+
"depends_on",
|
|
478
|
+
"conflict_group",
|
|
479
|
+
"size",
|
|
480
|
+
"file_scope_confidence",
|
|
481
|
+
"model_tier",
|
|
482
|
+
"missing_traces_justification",
|
|
483
|
+
]) {
|
|
484
|
+
if (key in story && !(key in swarmObj)) {
|
|
485
|
+
swarmObj[key] = story[key];
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
return swarmObj;
|
|
489
|
+
}
|
|
490
|
+
function storyHasTraces(story, items, sw) {
|
|
491
|
+
const narratives = story.narratives;
|
|
492
|
+
if (typeof narratives === "object" && narratives !== null && !Array.isArray(narratives)) {
|
|
493
|
+
const val = narratives.Traces;
|
|
494
|
+
if (typeof val === "string" && val.trim().length > 0)
|
|
495
|
+
return true;
|
|
496
|
+
}
|
|
497
|
+
if (asStrList(story.traces).length > 0)
|
|
498
|
+
return true;
|
|
499
|
+
if (items.some((item) => typeof item === "object" &&
|
|
500
|
+
item !== null &&
|
|
501
|
+
!Array.isArray(item) &&
|
|
502
|
+
itemHasTraces(item)))
|
|
503
|
+
return true;
|
|
504
|
+
if (asStrList(sw.missing_traces_justification).length > 0)
|
|
505
|
+
return true;
|
|
506
|
+
const refs = story.references;
|
|
507
|
+
if (Array.isArray(refs)) {
|
|
508
|
+
for (const ref of refs) {
|
|
509
|
+
if (typeof ref === "object" && ref !== null && !Array.isArray(ref)) {
|
|
510
|
+
if (ref.type === "x-vbrief/spec-section")
|
|
511
|
+
return true;
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
return false;
|
|
516
|
+
}
|
|
517
|
+
function storyDescription(story) {
|
|
518
|
+
const narratives = story.narratives;
|
|
519
|
+
if (typeof narratives === "object" && narratives !== null && !Array.isArray(narratives)) {
|
|
520
|
+
const val = narratives.Description;
|
|
521
|
+
if (typeof val === "string" && val.trim().length > 0)
|
|
522
|
+
return val.trim();
|
|
523
|
+
}
|
|
524
|
+
for (const key of ["description", "summary"]) {
|
|
525
|
+
const val = story[key];
|
|
526
|
+
if (typeof val === "string" && val.trim().length > 0)
|
|
527
|
+
return val.trim();
|
|
528
|
+
}
|
|
529
|
+
return "";
|
|
530
|
+
}
|
|
531
|
+
function storyImplementationPlan(story) {
|
|
532
|
+
const narratives = story.narratives;
|
|
533
|
+
if (typeof narratives === "object" && narratives !== null && !Array.isArray(narratives)) {
|
|
534
|
+
const val = narratives.ImplementationPlan;
|
|
535
|
+
if (typeof val === "string" && val.trim().length > 0)
|
|
536
|
+
return val.trim();
|
|
537
|
+
}
|
|
538
|
+
for (const key of ["implementation_plan", "ImplementationPlan"]) {
|
|
539
|
+
const values = asStrList(story[key]);
|
|
540
|
+
if (values.length > 0)
|
|
541
|
+
return values.join("\n");
|
|
542
|
+
}
|
|
543
|
+
return "";
|
|
544
|
+
}
|
|
545
|
+
function storyUserStory(story) {
|
|
546
|
+
const narratives = story.narratives;
|
|
547
|
+
if (typeof narratives === "object" && narratives !== null && !Array.isArray(narratives)) {
|
|
548
|
+
const val = narratives.UserStory;
|
|
549
|
+
if (typeof val === "string" && val.trim().length > 0)
|
|
550
|
+
return val.trim();
|
|
551
|
+
}
|
|
552
|
+
for (const key of ["user_story", "UserStory"]) {
|
|
553
|
+
const val = story[key];
|
|
554
|
+
if (typeof val === "string" && val.trim().length > 0)
|
|
555
|
+
return val.trim();
|
|
556
|
+
}
|
|
557
|
+
return "";
|
|
558
|
+
}
|
|
559
|
+
function acceptanceCountJustification(story, sw) {
|
|
560
|
+
for (const val of [
|
|
561
|
+
sw.acceptance_criteria_justification,
|
|
562
|
+
story.acceptance_criteria_justification,
|
|
563
|
+
]) {
|
|
564
|
+
if (typeof val === "string" && val.trim().length > 0)
|
|
565
|
+
return val.trim();
|
|
566
|
+
}
|
|
567
|
+
const narratives = story.narratives;
|
|
568
|
+
if (typeof narratives === "object" && narratives !== null && !Array.isArray(narratives)) {
|
|
569
|
+
const val = narratives.AcceptanceJustification;
|
|
570
|
+
if (typeof val === "string" && val.trim().length > 0)
|
|
571
|
+
return val.trim();
|
|
572
|
+
}
|
|
573
|
+
return "";
|
|
574
|
+
}
|
|
575
|
+
function itemsFromStory(stId, story) {
|
|
576
|
+
const items = story.items;
|
|
577
|
+
if (Array.isArray(items) && items.length > 0)
|
|
578
|
+
return items;
|
|
579
|
+
const acceptance = [...asStrList(story.acceptance), ...asStrList(story.acceptance_items)];
|
|
580
|
+
const traces = asStrList(story.traces).join(", ");
|
|
581
|
+
return acceptance.map((criterion, i) => {
|
|
582
|
+
const narrative = { Acceptance: criterion };
|
|
583
|
+
if (traces.length > 0)
|
|
584
|
+
narrative.Traces = traces;
|
|
585
|
+
return {
|
|
586
|
+
id: `${stId}-a${i + 1}`,
|
|
587
|
+
title: criterion,
|
|
588
|
+
status: "pending",
|
|
589
|
+
narrative,
|
|
590
|
+
};
|
|
591
|
+
});
|
|
592
|
+
}
|
|
593
|
+
// ---------------------------------------------------------------------------
|
|
594
|
+
// DAG validation
|
|
595
|
+
// ---------------------------------------------------------------------------
|
|
596
|
+
function validateDag(storyIds, depsByStory) {
|
|
597
|
+
const known = new Set(storyIds);
|
|
598
|
+
for (const [id, deps] of Object.entries(depsByStory)) {
|
|
599
|
+
for (const dep of deps) {
|
|
600
|
+
if (!known.has(dep)) {
|
|
601
|
+
throw new DecompositionError(`${id}: depends_on references unknown story '${dep}'`);
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
const visiting = new Set();
|
|
606
|
+
const visited = new Set();
|
|
607
|
+
function visit(id, path) {
|
|
608
|
+
if (visited.has(id))
|
|
609
|
+
return;
|
|
610
|
+
if (visiting.has(id)) {
|
|
611
|
+
const start = path.indexOf(id);
|
|
612
|
+
const cycle = [...(start >= 0 ? path.slice(start) : path), id].join(" -> ");
|
|
613
|
+
throw new DecompositionError(`dependency cycle detected: ${cycle}`);
|
|
614
|
+
}
|
|
615
|
+
visiting.add(id);
|
|
616
|
+
for (const dep of depsByStory[id] ?? []) {
|
|
617
|
+
visit(dep, [...path, id]);
|
|
618
|
+
}
|
|
619
|
+
visiting.delete(id);
|
|
620
|
+
visited.add(id);
|
|
621
|
+
}
|
|
622
|
+
for (const id of storyIds)
|
|
623
|
+
visit(id, []);
|
|
624
|
+
}
|
|
625
|
+
// ---------------------------------------------------------------------------
|
|
626
|
+
// validate_draft
|
|
627
|
+
// ---------------------------------------------------------------------------
|
|
628
|
+
export function validateDraft(stories) {
|
|
629
|
+
const storyIds = [];
|
|
630
|
+
const depsByStory = {};
|
|
631
|
+
const seen = new Set();
|
|
632
|
+
for (let i = 0; i < stories.length; i += 1) {
|
|
633
|
+
const story = stories[i];
|
|
634
|
+
const id = storyId(story, i + 1);
|
|
635
|
+
if (seen.has(id)) {
|
|
636
|
+
throw new DecompositionError(`duplicate story id '${id}'`);
|
|
637
|
+
}
|
|
638
|
+
seen.add(id);
|
|
639
|
+
storyIds.push(id);
|
|
640
|
+
const sw = swarmMeta(story);
|
|
641
|
+
const deps = asStrList(sw.depends_on ?? story.depends_on);
|
|
642
|
+
depsByStory[id] = deps;
|
|
643
|
+
const items = itemsFromStory(id, story);
|
|
644
|
+
const description = storyDescription(story);
|
|
645
|
+
const implementationPlan = storyImplementationPlan(story);
|
|
646
|
+
const userStory = storyUserStory(story);
|
|
647
|
+
const issues = [];
|
|
648
|
+
const rawId = story.id ?? story.story_id ?? story.key;
|
|
649
|
+
if (typeof rawId !== "string" || !rawId.trim())
|
|
650
|
+
issues.push("id");
|
|
651
|
+
const rawTitle = story.title;
|
|
652
|
+
if (typeof rawTitle !== "string" || !rawTitle.trim())
|
|
653
|
+
issues.push("title");
|
|
654
|
+
if (!description)
|
|
655
|
+
issues.push("plan.narratives.Description");
|
|
656
|
+
if (!implementationPlan)
|
|
657
|
+
issues.push("plan.narratives.ImplementationPlan");
|
|
658
|
+
if (!userStory)
|
|
659
|
+
issues.push("plan.narratives.UserStory");
|
|
660
|
+
const readiness = sw.readiness;
|
|
661
|
+
if (!STORY_READINESS_STATES.has(String(readiness ?? ""))) {
|
|
662
|
+
issues.push("plan.metadata.swarm.readiness");
|
|
663
|
+
}
|
|
664
|
+
const parallelSafe = sw.parallel_safe;
|
|
665
|
+
if (parallelSafe !== true && parallelSafe !== false) {
|
|
666
|
+
issues.push("plan.metadata.swarm.parallel_safe");
|
|
667
|
+
}
|
|
668
|
+
if (items.length === 0)
|
|
669
|
+
issues.push("plan.items");
|
|
670
|
+
if (items.length > 0 && !itemsHaveAcceptance(items)) {
|
|
671
|
+
issues.push("plan.items[].narrative.Acceptance");
|
|
672
|
+
}
|
|
673
|
+
issues.push(...deprecatedSubitemsIssues(items));
|
|
674
|
+
issues.push(...missingRequiredSwarmFields(sw));
|
|
675
|
+
if (!storyHasTraces(story, items, sw)) {
|
|
676
|
+
issues.push("Traces or missing_traces_justification");
|
|
677
|
+
}
|
|
678
|
+
issues.push(...storyQualityIssues({
|
|
679
|
+
title: String(story.title ?? id),
|
|
680
|
+
description,
|
|
681
|
+
implementationPlan,
|
|
682
|
+
userStory,
|
|
683
|
+
acceptanceTexts: acceptanceTextsFromItems(items),
|
|
684
|
+
acceptanceCountJustification: acceptanceCountJustification(story, sw),
|
|
685
|
+
swarm: sw,
|
|
686
|
+
concurrentReady: readiness === READY,
|
|
687
|
+
}));
|
|
688
|
+
if (issues.length > 0) {
|
|
689
|
+
throw new DecompositionError(`${id}: story invalid: ${issues.join(", ")}`);
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
validateDag(storyIds, depsByStory);
|
|
693
|
+
return storyIds;
|
|
694
|
+
}
|
|
695
|
+
// ---------------------------------------------------------------------------
|
|
696
|
+
// Reference normalization
|
|
697
|
+
// ---------------------------------------------------------------------------
|
|
698
|
+
function normalizeReferences(refs) {
|
|
699
|
+
if (!Array.isArray(refs))
|
|
700
|
+
return [];
|
|
701
|
+
return refs
|
|
702
|
+
.filter((ref) => typeof ref === "object" && ref !== null && !Array.isArray(ref))
|
|
703
|
+
.map((ref) => referenceWithDefaultTrust(ref));
|
|
704
|
+
}
|
|
705
|
+
function childProvenanceReferences(refs) {
|
|
706
|
+
return normalizeReferences(refs).filter((ref) => !String(ref.type ?? "")
|
|
707
|
+
.toLowerCase()
|
|
708
|
+
.includes("acceptance"));
|
|
709
|
+
}
|
|
710
|
+
function dedupeReferences(refs) {
|
|
711
|
+
const out = [];
|
|
712
|
+
const seen = new Set();
|
|
713
|
+
for (const ref of refs) {
|
|
714
|
+
const key = `${String(ref.uri ?? ref.url ?? "")}|${String(ref.type ?? "")}|${String(ref.title ?? "")}`;
|
|
715
|
+
if (seen.has(key))
|
|
716
|
+
continue;
|
|
717
|
+
seen.add(key);
|
|
718
|
+
out.push(ref);
|
|
719
|
+
}
|
|
720
|
+
return out;
|
|
721
|
+
}
|
|
722
|
+
// ---------------------------------------------------------------------------
|
|
723
|
+
// Build child vBRIEF
|
|
724
|
+
// ---------------------------------------------------------------------------
|
|
725
|
+
function storyNarratives(story) {
|
|
726
|
+
const narratives = {};
|
|
727
|
+
const raw = story.narratives;
|
|
728
|
+
if (typeof raw === "object" && raw !== null && !Array.isArray(raw)) {
|
|
729
|
+
for (const [k, v] of Object.entries(raw)) {
|
|
730
|
+
if (typeof v === "string" && v.trim().length > 0)
|
|
731
|
+
narratives[k] = v.trim();
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
for (const [draftKey, narrativeKey] of [
|
|
735
|
+
["description", "Description"],
|
|
736
|
+
["summary", "Description"],
|
|
737
|
+
["implementation_plan", "ImplementationPlan"],
|
|
738
|
+
["ImplementationPlan", "ImplementationPlan"],
|
|
739
|
+
["user_story", "UserStory"],
|
|
740
|
+
["UserStory", "UserStory"],
|
|
741
|
+
["traces", "Traces"],
|
|
742
|
+
]) {
|
|
743
|
+
if (narrativeKey in narratives)
|
|
744
|
+
continue;
|
|
745
|
+
const values = asStrList(story[draftKey]);
|
|
746
|
+
if (values.length > 0) {
|
|
747
|
+
const sep = narrativeKey === "ImplementationPlan" ? "\n" : ", ";
|
|
748
|
+
narratives[narrativeKey] = values.join(sep);
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
return narratives;
|
|
752
|
+
}
|
|
753
|
+
function childFilename(story, stId, title, date) {
|
|
754
|
+
const fn = story.filename;
|
|
755
|
+
if (typeof fn === "string" && fn.endsWith(".vbrief.json"))
|
|
756
|
+
return fn;
|
|
757
|
+
const sl = slugify(title) || slugify(stId) || "story";
|
|
758
|
+
return `${date}-${sl}.vbrief.json`;
|
|
759
|
+
}
|
|
760
|
+
function buildChildVbrief(opts) {
|
|
761
|
+
const { story, storyId: stId, storyIndex, parent, parentRel, status } = opts;
|
|
762
|
+
const title = String(story.title ?? stId);
|
|
763
|
+
const sw = swarmMeta(story);
|
|
764
|
+
const items = itemsFromStory(stId, story);
|
|
765
|
+
const metadata = typeof story.metadata === "object" && story.metadata !== null && !Array.isArray(story.metadata)
|
|
766
|
+
? { ...story.metadata }
|
|
767
|
+
: {};
|
|
768
|
+
metadata.kind = "story";
|
|
769
|
+
metadata.swarm = sw;
|
|
770
|
+
const parentPlan = typeof parent.plan === "object" && parent.plan !== null && !Array.isArray(parent.plan)
|
|
771
|
+
? parent.plan
|
|
772
|
+
: {};
|
|
773
|
+
const parentRefs = childProvenanceReferences(parentPlan.references);
|
|
774
|
+
const storyRefs = normalizeReferences(story.references);
|
|
775
|
+
return {
|
|
776
|
+
vBRIEFInfo: {
|
|
777
|
+
version: EMITTED_VBRIEF_VERSION,
|
|
778
|
+
description: `Story vBRIEF ${storyIndex} decomposed from ${parentRel}`,
|
|
779
|
+
},
|
|
780
|
+
plan: {
|
|
781
|
+
id: stId,
|
|
782
|
+
title,
|
|
783
|
+
status,
|
|
784
|
+
planRef: parentRel,
|
|
785
|
+
narratives: storyNarratives(story),
|
|
786
|
+
items,
|
|
787
|
+
metadata,
|
|
788
|
+
references: dedupeReferences([...parentRefs, ...storyRefs]),
|
|
789
|
+
},
|
|
790
|
+
};
|
|
791
|
+
}
|
|
792
|
+
export function applyDecomposition(opts) {
|
|
793
|
+
const { projectRoot, parentPath, draftPath, checkOnly, date } = opts;
|
|
794
|
+
const vbriefDirPath = vbriefDir(projectRoot);
|
|
795
|
+
const parent = loadJson(parentPath);
|
|
796
|
+
const draft = loadJson(draftPath);
|
|
797
|
+
const stories = storySpecs(draft);
|
|
798
|
+
const stIds = validateDraft(stories);
|
|
799
|
+
let outputDir;
|
|
800
|
+
const draftOutputDir = draft.output_dir;
|
|
801
|
+
if (typeof draftOutputDir === "string" && draftOutputDir.trim().length > 0) {
|
|
802
|
+
outputDir = isAbsolute(draftOutputDir.trim())
|
|
803
|
+
? draftOutputDir.trim()
|
|
804
|
+
: join(projectRoot, draftOutputDir.trim());
|
|
805
|
+
}
|
|
806
|
+
else {
|
|
807
|
+
outputDir = join(vbriefDirPath, "pending");
|
|
808
|
+
}
|
|
809
|
+
outputDir = resolve(outputDir);
|
|
810
|
+
const outputFolderName = basename(outputDir);
|
|
811
|
+
if (!LIFECYCLE_FOLDERS.has(outputFolderName)) {
|
|
812
|
+
throw new DecompositionError("output_dir must be a vbrief lifecycle folder");
|
|
813
|
+
}
|
|
814
|
+
if (!outputDir.startsWith(`${resolve(vbriefDirPath)}/`) && outputDir !== resolve(vbriefDirPath)) {
|
|
815
|
+
throw new DecompositionError("output_dir must be inside vbrief/");
|
|
816
|
+
}
|
|
817
|
+
if (outputFolderName === "active") {
|
|
818
|
+
throw new DecompositionError("output_dir must not be vbrief/active; write pending stories and use task scope:activate when work begins");
|
|
819
|
+
}
|
|
820
|
+
const status = normalizeStatus(draft.status, defaultStatusForFolderName(outputFolderName));
|
|
821
|
+
if (ACTIVE_DECOMPOSITION_STATUSES.has(status)) {
|
|
822
|
+
throw new DecompositionError("decomposition cannot create active/running child stories; write pending stories and use task scope:activate when work begins");
|
|
823
|
+
}
|
|
824
|
+
const parentRel = relToVbrief(vbriefDirPath, parentPath);
|
|
825
|
+
const actions = [`VALIDATED ${stories.length} story decomposition draft`];
|
|
826
|
+
const childPaths = [];
|
|
827
|
+
const childDocs = [];
|
|
828
|
+
for (let i = 0; i < stories.length; i += 1) {
|
|
829
|
+
const story = stories[i];
|
|
830
|
+
const stId = stIds[i];
|
|
831
|
+
const title = String(story.title ?? stId);
|
|
832
|
+
const storyStatus = normalizeStatus(story.status, status);
|
|
833
|
+
if (ACTIVE_DECOMPOSITION_STATUSES.has(storyStatus)) {
|
|
834
|
+
throw new DecompositionError(`${stId}: decomposition cannot create active/running child stories; write pending stories and use task scope:activate when work begins`);
|
|
835
|
+
}
|
|
836
|
+
const filename = childFilename(story, stId, title, date);
|
|
837
|
+
const target = join(outputDir, filename);
|
|
838
|
+
if (!checkOnly && existsSync(target)) {
|
|
839
|
+
throw new DecompositionError(`${target}: child story path already exists; overwriting is not supported`);
|
|
840
|
+
}
|
|
841
|
+
const child = buildChildVbrief({
|
|
842
|
+
story,
|
|
843
|
+
storyId: stId,
|
|
844
|
+
storyIndex: i + 1,
|
|
845
|
+
parent,
|
|
846
|
+
parentRel,
|
|
847
|
+
status: storyStatus,
|
|
848
|
+
});
|
|
849
|
+
childPaths.push({ target, storyId: stId, title });
|
|
850
|
+
childDocs.push(child);
|
|
851
|
+
const verb = checkOnly ? "CHECK" : "CREATE";
|
|
852
|
+
actions.push(`${verb} ${relToVbrief(vbriefDirPath, target)}`);
|
|
853
|
+
}
|
|
854
|
+
if (checkOnly)
|
|
855
|
+
return actions;
|
|
856
|
+
for (const { target } of childPaths) {
|
|
857
|
+
mkdirSync(dirname(target), { recursive: true });
|
|
858
|
+
}
|
|
859
|
+
for (let i = 0; i < childPaths.length; i += 1) {
|
|
860
|
+
// biome-ignore lint/style/noNonNullAssertion: loop bound ensures these exist
|
|
861
|
+
writeJson(childPaths[i].target, childDocs[i]);
|
|
862
|
+
}
|
|
863
|
+
let parentPlan = parent.plan;
|
|
864
|
+
if (parentPlan === null || parentPlan === undefined) {
|
|
865
|
+
parentPlan = {};
|
|
866
|
+
parent.plan = parentPlan;
|
|
867
|
+
}
|
|
868
|
+
if (typeof parentPlan !== "object" || Array.isArray(parentPlan)) {
|
|
869
|
+
throw new DecompositionError(`${parentPath}: plan must be an object`);
|
|
870
|
+
}
|
|
871
|
+
const planObj = parentPlan;
|
|
872
|
+
let metadata = planObj.metadata;
|
|
873
|
+
if (metadata === null || metadata === undefined) {
|
|
874
|
+
metadata = {};
|
|
875
|
+
planObj.metadata = metadata;
|
|
876
|
+
}
|
|
877
|
+
if (typeof metadata !== "object" || Array.isArray(metadata)) {
|
|
878
|
+
throw new DecompositionError(`${parentPath}: plan.metadata must be an object`);
|
|
879
|
+
}
|
|
880
|
+
const metaObj = metadata;
|
|
881
|
+
if (!metaObj.kind)
|
|
882
|
+
metaObj.kind = "epic";
|
|
883
|
+
let references = planObj.references;
|
|
884
|
+
if (references === null || references === undefined) {
|
|
885
|
+
references = [];
|
|
886
|
+
planObj.references = references;
|
|
887
|
+
}
|
|
888
|
+
if (!Array.isArray(references)) {
|
|
889
|
+
throw new DecompositionError(`${parentPath}: plan.references must be an array`);
|
|
890
|
+
}
|
|
891
|
+
for (const { target, title } of childPaths) {
|
|
892
|
+
references.push(referenceWithDefaultTrust({
|
|
893
|
+
uri: relToVbrief(vbriefDirPath, target),
|
|
894
|
+
type: "x-vbrief/plan",
|
|
895
|
+
title,
|
|
896
|
+
}));
|
|
897
|
+
}
|
|
898
|
+
planObj.references = dedupeReferences(references
|
|
899
|
+
.filter((r) => typeof r === "object" && r !== null && !Array.isArray(r))
|
|
900
|
+
.map((r) => r));
|
|
901
|
+
writeJson(parentPath, parent);
|
|
902
|
+
actions.push(`UPDATE ${parentRel} references`);
|
|
903
|
+
return actions;
|
|
904
|
+
}
|
|
905
|
+
// ---------------------------------------------------------------------------
|
|
906
|
+
// CLI
|
|
907
|
+
// ---------------------------------------------------------------------------
|
|
908
|
+
function parseDecomposeArgs(argv) {
|
|
909
|
+
let parent;
|
|
910
|
+
let draft;
|
|
911
|
+
let check = false;
|
|
912
|
+
let date;
|
|
913
|
+
let projectRoot = ".";
|
|
914
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
915
|
+
const arg = argv[i];
|
|
916
|
+
if (arg === "--draft") {
|
|
917
|
+
draft = argv[i + 1];
|
|
918
|
+
i += 1;
|
|
919
|
+
}
|
|
920
|
+
else if (arg?.startsWith("--draft=")) {
|
|
921
|
+
draft = arg.slice("--draft=".length);
|
|
922
|
+
}
|
|
923
|
+
else if (arg === "--check") {
|
|
924
|
+
check = true;
|
|
925
|
+
}
|
|
926
|
+
else if (arg === "--date") {
|
|
927
|
+
date = argv[i + 1];
|
|
928
|
+
i += 1;
|
|
929
|
+
}
|
|
930
|
+
else if (arg?.startsWith("--date=")) {
|
|
931
|
+
date = arg.slice("--date=".length);
|
|
932
|
+
}
|
|
933
|
+
else if (arg === "--project-root") {
|
|
934
|
+
projectRoot = argv[i + 1] ?? ".";
|
|
935
|
+
i += 1;
|
|
936
|
+
}
|
|
937
|
+
else if (arg?.startsWith("--project-root=")) {
|
|
938
|
+
projectRoot = arg.slice("--project-root=".length);
|
|
939
|
+
}
|
|
940
|
+
else if (!arg?.startsWith("-") && parent === undefined) {
|
|
941
|
+
parent = arg;
|
|
942
|
+
}
|
|
943
|
+
else {
|
|
944
|
+
return { check, projectRoot, error: `unrecognized argument: ${arg}` };
|
|
945
|
+
}
|
|
946
|
+
}
|
|
947
|
+
return { parent, draft, check, date, projectRoot };
|
|
948
|
+
}
|
|
949
|
+
/** CLI entry for scope-decompose (mirrors scope_decompose.py main()). */
|
|
950
|
+
export function decomposeMain(argv) {
|
|
951
|
+
const parsed = parseDecomposeArgs(argv);
|
|
952
|
+
if (parsed.error !== undefined) {
|
|
953
|
+
process.stderr.write(`ERROR: ${parsed.error}\n`);
|
|
954
|
+
return 2;
|
|
955
|
+
}
|
|
956
|
+
const { parent, draft, check, projectRoot } = parsed;
|
|
957
|
+
const projRoot = resolve(projectRoot);
|
|
958
|
+
if (parent === undefined && draft === undefined) {
|
|
959
|
+
if (check) {
|
|
960
|
+
process.stdout.write("OK no decomposition draft supplied; nothing to apply.\n");
|
|
961
|
+
return 0;
|
|
962
|
+
}
|
|
963
|
+
process.stderr.write("ERROR: parent path and --draft are required\n");
|
|
964
|
+
return 2;
|
|
965
|
+
}
|
|
966
|
+
if (parent === undefined || draft === undefined) {
|
|
967
|
+
process.stderr.write("ERROR: parent path and --draft are required\n");
|
|
968
|
+
return 2;
|
|
969
|
+
}
|
|
970
|
+
const parentPath = isAbsolute(parent) ? parent : join(projRoot, parent);
|
|
971
|
+
const draftPath = isAbsolute(draft) ? draft : join(projRoot, draft);
|
|
972
|
+
if (!existsSync(parentPath)) {
|
|
973
|
+
process.stderr.write(`ERROR: parent vBRIEF not found: ${parentPath}\n`);
|
|
974
|
+
return 2;
|
|
975
|
+
}
|
|
976
|
+
if (!existsSync(draftPath)) {
|
|
977
|
+
process.stderr.write(`ERROR: decomposition draft not found: ${draftPath}\n`);
|
|
978
|
+
return 2;
|
|
979
|
+
}
|
|
980
|
+
const dateStr = parsed.date ?? new Date().toISOString().slice(0, 10);
|
|
981
|
+
if (!isValidCreationDate(dateStr)) {
|
|
982
|
+
process.stderr.write(`ERROR: --date must be YYYY-MM-DD, got '${dateStr}'\n`);
|
|
983
|
+
return 2;
|
|
984
|
+
}
|
|
985
|
+
if (!check) {
|
|
986
|
+
try {
|
|
987
|
+
accessSync(parentPath, constants.W_OK);
|
|
988
|
+
}
|
|
989
|
+
catch {
|
|
990
|
+
process.stderr.write(`ERROR: parent vBRIEF is not writable: ${parentPath}\n`);
|
|
991
|
+
return 2;
|
|
992
|
+
}
|
|
993
|
+
}
|
|
994
|
+
try {
|
|
995
|
+
const actions = applyDecomposition({
|
|
996
|
+
projectRoot: projRoot,
|
|
997
|
+
parentPath: resolve(parentPath),
|
|
998
|
+
draftPath: resolve(draftPath),
|
|
999
|
+
checkOnly: check,
|
|
1000
|
+
date: dateStr,
|
|
1001
|
+
});
|
|
1002
|
+
for (const action of actions) {
|
|
1003
|
+
process.stdout.write(`${action}\n`);
|
|
1004
|
+
}
|
|
1005
|
+
return 0;
|
|
1006
|
+
}
|
|
1007
|
+
catch (err) {
|
|
1008
|
+
if (err instanceof DecompositionError) {
|
|
1009
|
+
process.stderr.write(`ERROR: ${err.message}\n`);
|
|
1010
|
+
return 1;
|
|
1011
|
+
}
|
|
1012
|
+
process.stderr.write(`ERROR: ${String(err)}\n`);
|
|
1013
|
+
return 1;
|
|
1014
|
+
}
|
|
1015
|
+
}
|
|
1016
|
+
//# sourceMappingURL=decompose.js.map
|