forge-workflow 0.0.10 → 0.1.0-beta.3
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/.claude/rules/{greptile-review-process.md → review-process.md} +56 -41
- package/.claude/scripts/{greptile-resolve.sh → review-resolve.sh} +13 -3
- package/.cursor/rules/permissions-guidance.mdc +2 -2
- package/.forge/hooks/check-tdd.js +82 -5
- package/.forge/hooks/forge-native-hook.js +431 -0
- package/.forge/protected-paths.yaml +157 -0
- package/AGENTS.md +151 -61
- package/CHANGELOG.md +709 -0
- package/CLAUDE.md +9 -118
- package/QUICKSTART.md +175 -0
- package/README.md +275 -365
- package/bin/forge-cmd.js +120 -9
- package/bin/forge-preflight.js +26 -5
- package/bin/forge.js +532 -489
- package/docs/INDEX.md +93 -0
- package/docs/PROJECT_DESIGN.md +685 -0
- package/docs/architecture/index.md +66 -0
- package/docs/architecture/notes/README.md +35 -0
- package/docs/architecture/subsystems/README.md +46 -0
- package/docs/forge/TOOLCHAIN.md +670 -0
- package/docs/forge/VALIDATION.md +82 -0
- package/docs/{AGENT_INSTALL_PROMPT.md → guides/AGENT_INSTALL_PROMPT.md} +3 -3
- package/docs/guides/BEADS_GITHUB_SYNC.md +32 -0
- package/docs/{ENHANCED_ONBOARDING.md → guides/ENHANCED_ONBOARDING.md} +16 -12
- package/docs/guides/GREPTILE_SETUP.md +46 -0
- package/docs/guides/MANUAL_REVIEW_GUIDE.md +58 -0
- package/docs/guides/MIGRATION.md +56 -0
- package/docs/guides/SETUP.md +121 -0
- package/docs/guides/SUPPORT.md +190 -0
- package/docs/guides/WORKFLOW_TEMPLATES.md +74 -0
- package/docs/guides/memory-backends.md +183 -0
- package/docs/reference/ADAPTERS.md +128 -0
- package/docs/reference/AGENT_SKILL_PARITY.md +175 -0
- package/docs/reference/COMMANDS.md +214 -0
- package/docs/reference/DECISION_DRIFT_GUARDS.md +97 -0
- package/docs/{EXAMPLES.md → reference/EXAMPLES.md} +7 -5
- package/docs/reference/FORGE_KERNEL_STORAGE_MODEL.md +135 -0
- package/docs/reference/HERMES_INTEGRATION.md +118 -0
- package/docs/reference/INSIGHTS_RECAP.md +63 -0
- package/docs/reference/INSTALL.md +164 -0
- package/docs/reference/KERNEL_TAXONOMY_VALIDATION.md +161 -0
- package/docs/reference/PROTECTED_PATH_MANIFEST.md +25 -0
- package/docs/reference/RELEASE.md +68 -0
- package/docs/reference/RESEARCH_TEMPLATE.md +292 -0
- package/docs/{ROADMAP.md → reference/ROADMAP.md} +12 -9
- package/docs/reference/SKILLS.md +35 -0
- package/docs/reference/STATUS_BOARD.md +80 -0
- package/docs/reference/TEMPLATES.md +106 -0
- package/docs/{TOOLCHAIN.md → reference/TOOLCHAIN.md} +62 -47
- package/docs/reference/VALIDATION.md +82 -0
- package/docs/reference/agent-permissions.md +169 -0
- package/docs/reference/beads-to-kernel-migration-ux.md +61 -0
- package/docs/reference/control-plane-guarantees.md +125 -0
- package/docs/reference/dependency-chain.md +331 -0
- package/docs/reference/forge-kernel-issue-command-contract.md +161 -0
- package/docs/reference/forge-kernel-schema.md +72 -0
- package/docs/reference/kernel-conflict-evaluators.md +27 -0
- package/docs/reference/patch-md-format.md +77 -0
- package/docs/reference/protected-state-surfaces.md +59 -0
- package/docs/reference/shepherd.md +155 -0
- package/docs/reference/superpowers-analysis.md +320 -0
- package/docs/reference/superpowers-integration-options.md +404 -0
- package/docs/reference/test-environment.md +519 -0
- package/docs/reference/upgrade-safety.md +59 -0
- package/lefthook.yml +18 -0
- package/lib/activation/ensure-forge-home.js +135 -0
- package/lib/adapter-cli.js +307 -0
- package/lib/adapters/beads-issue-adapter.js +127 -0
- package/lib/adapters/beads-kernel-compat.js +1109 -0
- package/lib/adapters/greptile-review-adapter.js +141 -0
- package/lib/adapters/kernel-issue-adapter.js +101 -0
- package/lib/adapters/pr-state-adapter.js +484 -0
- package/lib/adoption-profiles.js +139 -0
- package/lib/agents/README.md +2 -6
- package/lib/agents/claude.plugin.json +3 -8
- package/lib/agents/codex.plugin.json +9 -1
- package/lib/agents/cursor.plugin.json +2 -6
- package/lib/agents/hermes.plugin.json +22 -0
- package/lib/agents-config.js +39 -1236
- package/lib/audit-evidence.js +282 -0
- package/lib/beads-detect.js +60 -0
- package/lib/beads-nudge.js +91 -0
- package/lib/beads-setup.js +121 -0
- package/lib/beads-sync-scaffold.js +25 -101
- package/lib/codex-skills.js +51 -1
- package/lib/commands/_aliases.js +248 -0
- package/lib/commands/_issue.js +780 -77
- package/lib/commands/_manifest.js +93 -0
- package/lib/commands/_registry.js +99 -34
- package/lib/commands/_resolve-command-opts.js +230 -0
- package/lib/commands/_serve-security.js +270 -0
- package/lib/commands/adapter.js +12 -0
- package/lib/commands/add.js +118 -0
- package/lib/commands/audit.js +70 -0
- package/lib/commands/blocked.js +5 -0
- package/lib/commands/board.js +64 -0
- package/lib/commands/claim.js +21 -2
- package/lib/commands/claims.js +7 -0
- package/lib/commands/clean.js +485 -75
- package/lib/commands/close.js +2 -2
- package/lib/commands/comment.js +5 -0
- package/lib/commands/control.js +148 -0
- package/lib/commands/create.js +2 -2
- package/lib/commands/dev.js +185 -7
- package/lib/commands/doc-gate.js +336 -0
- package/lib/commands/doctor.js +156 -0
- package/lib/commands/explain.js +15 -0
- package/lib/commands/export.js +237 -0
- package/lib/commands/gate.js +209 -0
- package/lib/commands/hooks.js +377 -0
- package/lib/commands/inbox.js +118 -0
- package/lib/commands/init.js +604 -0
- package/lib/commands/insights.js +79 -0
- package/lib/commands/issue.js +12 -1
- package/lib/commands/issues.js +17 -0
- package/lib/commands/lint.js +5 -0
- package/lib/commands/list.js +2 -2
- package/lib/commands/memory.js +81 -0
- package/lib/commands/merge.js +312 -0
- package/lib/commands/migrate.js +362 -0
- package/lib/commands/new.js +12 -0
- package/lib/commands/options.js +241 -0
- package/lib/commands/orient.js +13 -0
- package/lib/commands/orphans.js +5 -0
- package/lib/commands/patch.js +67 -0
- package/lib/commands/plan.js +481 -29
- package/lib/commands/pr.js +88 -0
- package/lib/commands/preflight.js +211 -0
- package/lib/commands/prime.js +13 -0
- package/lib/commands/push.js +135 -2
- package/lib/commands/ready.js +2 -2
- package/lib/commands/recall.js +171 -0
- package/lib/commands/recap.js +75 -0
- package/lib/commands/recommend.js +0 -1
- package/lib/commands/release.js +104 -0
- package/lib/commands/remember.js +140 -0
- package/lib/commands/role.js +99 -0
- package/lib/commands/serve.js +581 -0
- package/lib/commands/setup.js +900 -971
- package/lib/commands/shepherd.js +501 -0
- package/lib/commands/ship.js +59 -1
- package/lib/commands/show.js +2 -2
- package/lib/commands/stage.js +192 -0
- package/lib/commands/stale.js +5 -0
- package/lib/commands/status.js +158 -21
- package/lib/commands/sync.js +34 -46
- package/lib/commands/team.js +4 -1
- package/lib/commands/test.js +43 -27
- package/lib/commands/update.js +2 -2
- package/lib/commands/upgrade.js +47 -0
- package/lib/commands/validate.js +43 -18
- package/lib/commands/worktree.js +362 -99
- package/lib/config-writer.js +202 -0
- package/lib/control-plane.js +236 -0
- package/lib/core/runtime-graph.js +977 -0
- package/lib/dep-guard/keyword-ripple.js +2 -2
- package/lib/deprecated-sync-cleanup.js +362 -0
- package/lib/detect-agent.js +2 -28
- package/lib/detect-worktree.js +35 -9
- package/lib/doc-gate/declaration.js +177 -0
- package/lib/doc-gate/detect.js +289 -0
- package/lib/doc-gate/gate.js +375 -0
- package/lib/doc-gate/okf-config.js +128 -0
- package/lib/doc-gate/okf.js +429 -0
- package/lib/docs-command.js +1161 -6
- package/lib/forge-issues.js +382 -11
- package/lib/forge-lock.js +262 -0
- package/lib/gate-events.js +192 -0
- package/lib/global-flags.js +104 -0
- package/lib/greptile-match.js +7 -63
- package/lib/grounding/context-events.js +230 -0
- package/lib/grounding/read-first.js +112 -0
- package/lib/harness-capability-matrix.js +380 -0
- package/lib/hook-global-installer.js +347 -0
- package/lib/hook-renderer.js +541 -0
- package/lib/inbox.js +391 -0
- package/lib/insights.js +397 -0
- package/lib/issue-adapter.js +156 -0
- package/lib/issue-backend.js +145 -0
- package/lib/issue-render.js +220 -0
- package/lib/kernel/backing-issue.js +311 -0
- package/lib/kernel/broker.js +1218 -0
- package/lib/kernel/cli-broker-factory.js +130 -0
- package/lib/kernel/conflict-signal.js +82 -0
- package/lib/kernel/evaluators.js +195 -0
- package/lib/kernel/fs-class.js +495 -0
- package/lib/kernel/issue-command-contract.js +559 -0
- package/lib/kernel/issue-id-resolver.js +186 -0
- package/lib/kernel/lease-enforcer.js +158 -0
- package/lib/kernel/migrations.js +333 -0
- package/lib/kernel/owned-kernel.js +43 -0
- package/lib/kernel/planning-buckets-schema.js +109 -0
- package/lib/kernel/projection-jsonl-writer.js +450 -0
- package/lib/kernel/readiness-model.js +329 -0
- package/lib/kernel/schema.js +356 -0
- package/lib/kernel/sqlite-driver.js +2540 -0
- package/lib/kernel/taxonomy-validator.js +394 -0
- package/lib/lefthook-check.js +3 -2
- package/lib/lefthook-wiring.js +413 -0
- package/lib/mcp-config-renderer.js +288 -0
- package/lib/memory/graphiti-mcp.js +106 -0
- package/lib/memory/router.js +387 -0
- package/lib/memory/typed-api.js +102 -0
- package/lib/memory-digest.js +195 -0
- package/lib/merge-rules.js +395 -0
- package/lib/migrate-dry-run.js +466 -0
- package/lib/orientation.js +863 -0
- package/lib/package-manager-remediation.js +103 -0
- package/lib/package-root.js +381 -0
- package/lib/patch-intent.js +890 -0
- package/lib/plugin-catalog.js +3 -4
- package/lib/plugin-manager.js +0 -5
- package/lib/pr-bundle.js +186 -0
- package/lib/pr-monitor/auto-actions.js +175 -0
- package/lib/pr-monitor/differ.js +195 -0
- package/lib/pr-monitor/digest.js +206 -0
- package/lib/pr-monitor/events.js +0 -0
- package/lib/pr-monitor/gather.js +124 -0
- package/lib/pr-monitor/journal.js +299 -0
- package/lib/pr-monitor/monitor.js +146 -0
- package/lib/pr-monitor/render-sticky.js +192 -0
- package/lib/pr-monitor/upsert-sticky.js +169 -0
- package/lib/pr-monitor/watch-lifecycle.js +95 -0
- package/lib/pr-monitor/watch.js +247 -0
- package/lib/pr-pull.js +1314 -0
- package/lib/pr-shepherd.js +494 -0
- package/lib/pr-state-validator.js +59 -0
- package/lib/preflight/gates.js +237 -0
- package/lib/preflight/runner.js +116 -0
- package/lib/project-discovery.js +0 -53
- package/lib/project-memory.js +99 -497
- package/lib/protected-path-manifest.js +281 -0
- package/lib/protected-state-surfaces.js +387 -0
- package/lib/release-readiness.js +2105 -0
- package/lib/reset.js +59 -45
- package/lib/review-adapter.js +68 -0
- package/lib/rules-sync.js +260 -0
- package/lib/runtime-health.js +241 -20
- package/lib/safety-config-renderer.js +268 -0
- package/lib/setup-action-log.js +1 -7
- package/lib/setup.js +27 -65
- package/lib/shell-utils.js +76 -6
- package/lib/skills-sync.js +330 -0
- package/lib/smart-status/scoring.js +17 -3
- package/lib/status/beads-snapshot.js +45 -2
- package/lib/status/presenter.js +169 -18
- package/lib/status/snapshot.js +186 -0
- package/lib/sync-backend.js +202 -0
- package/lib/untrusted-content.js +52 -0
- package/lib/upgrade-safety.js +251 -0
- package/lib/workflow/enforce-stage.js +351 -45
- package/lib/workflow/stage-transition.js +115 -0
- package/lib/workflow/stages.js +30 -6
- package/lib/workflow/state-manager.js +11 -22
- package/lib/workflow/state.js +23 -1
- package/lib/workflow-profiles.js +17 -5
- package/package.json +37 -35
- package/rules/documentation.md +19 -0
- package/rules/kernel-tracking.md +26 -0
- package/rules/security.md +22 -0
- package/rules/tdd.md +20 -0
- package/rules/workflow.md +27 -0
- package/scripts/auto-backing-issue.js +47 -0
- package/scripts/beads-context.sh +81 -57
- package/scripts/beads-upgrade-smoke.sh +24 -3
- package/scripts/bootstrap-windows-tools.sh +78 -0
- package/scripts/branch-protection.js +2 -3
- package/scripts/check-agents.js +34 -137
- package/scripts/commitlint.js +3 -1
- package/scripts/conflict-detect.sh +3 -0
- package/scripts/dep-guard.sh +22 -3
- package/scripts/file-index.sh +3 -0
- package/scripts/forge-team/lib/claim.sh +34 -18
- package/scripts/forge-team/lib/dashboard.sh +61 -86
- package/scripts/forge-team/lib/epic.sh +99 -263
- package/scripts/forge-team/lib/hooks.sh +26 -28
- package/scripts/forge-team/lib/identity.sh +4 -4
- package/scripts/forge-team/lib/sync-github.sh +49 -84
- package/scripts/forge-team/lib/verify.sh +93 -83
- package/scripts/forge-team/lib/workload.sh +41 -65
- package/scripts/forge-team/tests/claim.test.sh +25 -19
- package/scripts/forge-team/tests/dashboard.test.sh +31 -46
- package/scripts/forge-team/tests/epic.test.sh +52 -71
- package/scripts/forge-team/tests/hooks.test.sh +38 -50
- package/scripts/forge-team/tests/identity.test.sh +3 -3
- package/scripts/forge-team/tests/integration.test.sh +44 -66
- package/scripts/forge-team/tests/sync-github.test.sh +50 -83
- package/scripts/forge-team/tests/verify.test.sh +37 -46
- package/scripts/forge-team/tests/workflow-integration.test.sh +4 -4
- package/scripts/forge-team/tests/workload.test.sh +32 -66
- package/scripts/gen-command-manifest.js +153 -0
- package/scripts/gen-embedded-assets.mjs +129 -0
- package/scripts/install.ps1 +139 -0
- package/scripts/install.sh +268 -0
- package/scripts/lib/release-asset.mjs +84 -0
- package/scripts/parity-check.mjs +145 -0
- package/scripts/parity-check.test.mjs +58 -0
- package/scripts/pin-agentic-workflow-images.js +112 -0
- package/scripts/pr-auto-actions.js +93 -0
- package/scripts/pr-coordinator.sh +3 -0
- package/scripts/pr-verdict-label.js +50 -0
- package/scripts/preflight-sonar.eslint.config.mjs +44 -0
- package/scripts/preflight.sh +21 -94
- package/scripts/protected-state-check.js +104 -0
- package/scripts/smart-status.sh +60 -57
- package/scripts/spikes/config-race-bench.js +111 -0
- package/scripts/spikes/harness-capability-matrix.js +13 -0
- package/scripts/spikes/patch-anchor-stability-bench.js +125 -0
- package/scripts/spikes/protected-path-manifest.js +20 -0
- package/scripts/spikes/skill-auto-invoke-parity.js +292 -0
- package/scripts/sync-agent-skills.js +62 -0
- package/scripts/sync-utils.sh +3 -0
- package/scripts/test-ci-shard.js +13 -6
- package/scripts/test.js +95 -12
- package/skills/claim-safety/SKILL.md +102 -0
- package/skills/claim-safety/evals/evals.json +46 -0
- package/{.github/prompts/dev.prompt.md → skills/dev/SKILL.md} +44 -50
- package/skills/dev/evals/evals.json +50 -0
- package/skills/hermes-forge/SKILL.md +185 -0
- package/skills/hermes-forge/evals/evals.json +46 -0
- package/skills/issue-basics/SKILL.md +111 -0
- package/skills/issue-basics/evals/evals.json +46 -0
- package/skills/kernel/SKILL.md +166 -0
- package/skills/kernel/evals/evals.json +50 -0
- package/skills/memory/SKILL.md +102 -0
- package/skills/parallel-deep-research/SKILL.md +14 -11
- package/skills/parallel-deep-research/evals/evals.json +11 -27
- package/{.github/prompts/plan.prompt.md → skills/plan/SKILL.md} +132 -157
- package/skills/plan/evals/evals.json +42 -0
- package/skills/research/SKILL.md +195 -0
- package/skills/research/evals/evals.json +42 -0
- package/{.github/prompts/review.prompt.md → skills/review/SKILL.md} +98 -62
- package/skills/review/evals/evals.json +42 -0
- package/skills/rollback/SKILL.md +110 -0
- package/skills/rollback/evals/evals.json +46 -0
- package/skills/rollback/references/methods.md +204 -0
- package/{.cursor/commands/rollback.md → skills/rollback/references/workflow-integration.md} +10 -284
- package/skills/shepherd/SKILL.md +66 -0
- package/skills/shepherd/evals/evals.json +42 -0
- package/{.github/prompts/ship.prompt.md → skills/ship/SKILL.md} +81 -45
- package/skills/ship/evals/evals.json +42 -0
- package/skills/smith/SKILL.md +142 -0
- package/skills/smith/evals/evals.json +46 -0
- package/skills/smith/references/autonomy-and-gates.md +94 -0
- package/{.github/prompts/sonarcloud.prompt.md → skills/sonarcloud/SKILL.md} +14 -3
- package/skills/sonarcloud/evals/evals.json +46 -0
- package/skills/sonarcloud-analysis/SKILL.md +18 -13
- package/skills/sonarcloud-analysis/evals/evals.json +11 -15
- package/{.github/prompts/status.prompt.md → skills/status/SKILL.md} +20 -10
- package/skills/status/evals/evals.json +50 -0
- package/skills/triage-ready/SKILL.md +121 -0
- package/skills/triage-ready/evals/evals.json +42 -0
- package/{.github/prompts/validate.prompt.md → skills/validate/SKILL.md} +52 -29
- package/skills/validate/evals/evals.json +42 -0
- package/skills/verify/SKILL.md +299 -0
- package/skills/verify/evals/evals.json +50 -0
- package/.claude/commands/dev.md +0 -345
- package/.claude/commands/plan.md +0 -566
- package/.claude/commands/premerge.md +0 -186
- package/.claude/commands/research.md +0 -42
- package/.claude/commands/review.md +0 -451
- package/.claude/commands/rollback.md +0 -721
- package/.claude/commands/ship.md +0 -213
- package/.claude/commands/sonarcloud.md +0 -152
- package/.claude/commands/status.md +0 -90
- package/.claude/commands/validate.md +0 -288
- package/.claude/commands/verify.md +0 -269
- package/.claude/rules/workflow.md +0 -121
- package/.cline/workflows/dev.md +0 -342
- package/.cline/workflows/plan.md +0 -563
- package/.cline/workflows/premerge.md +0 -183
- package/.cline/workflows/research.md +0 -39
- package/.cline/workflows/review.md +0 -448
- package/.cline/workflows/rollback.md +0 -718
- package/.cline/workflows/ship.md +0 -210
- package/.cline/workflows/sonarcloud.md +0 -146
- package/.cline/workflows/status.md +0 -87
- package/.cline/workflows/validate.md +0 -285
- package/.cline/workflows/verify.md +0 -266
- package/.codex/config.toml +0 -11
- package/.codex/skills/dev/SKILL.md +0 -345
- package/.codex/skills/plan/SKILL.md +0 -566
- package/.codex/skills/premerge/SKILL.md +0 -186
- package/.codex/skills/research/SKILL.md +0 -42
- package/.codex/skills/review/SKILL.md +0 -451
- package/.codex/skills/rollback/SKILL.md +0 -721
- package/.codex/skills/ship/SKILL.md +0 -213
- package/.codex/skills/sonarcloud/SKILL.md +0 -149
- package/.codex/skills/status/SKILL.md +0 -90
- package/.codex/skills/validate/SKILL.md +0 -288
- package/.codex/skills/verify/SKILL.md +0 -269
- package/.cursor/commands/dev.md +0 -342
- package/.cursor/commands/plan.md +0 -563
- package/.cursor/commands/premerge.md +0 -183
- package/.cursor/commands/research.md +0 -39
- package/.cursor/commands/review.md +0 -448
- package/.cursor/commands/ship.md +0 -210
- package/.cursor/commands/sonarcloud.md +0 -146
- package/.cursor/commands/status.md +0 -87
- package/.cursor/commands/validate.md +0 -285
- package/.cursor/commands/verify.md +0 -266
- package/.cursorrules +0 -149
- package/.github/prompts/premerge.prompt.md +0 -188
- package/.github/prompts/research.prompt.md +0 -44
- package/.github/prompts/rollback.prompt.md +0 -723
- package/.github/prompts/verify.prompt.md +0 -271
- package/.github/workflows/beads-to-github.yml +0 -89
- package/.github/workflows/github-to-beads.yml +0 -100
- package/.kilocode/workflows/dev.md +0 -346
- package/.kilocode/workflows/plan.md +0 -567
- package/.kilocode/workflows/premerge.md +0 -187
- package/.kilocode/workflows/research.md +0 -43
- package/.kilocode/workflows/review.md +0 -452
- package/.kilocode/workflows/rollback.md +0 -722
- package/.kilocode/workflows/ship.md +0 -214
- package/.kilocode/workflows/sonarcloud.md +0 -150
- package/.kilocode/workflows/status.md +0 -91
- package/.kilocode/workflows/validate.md +0 -289
- package/.kilocode/workflows/verify.md +0 -270
- package/.opencode/commands/dev.md +0 -345
- package/.opencode/commands/plan.md +0 -566
- package/.opencode/commands/premerge.md +0 -186
- package/.opencode/commands/research.md +0 -42
- package/.opencode/commands/review.md +0 -451
- package/.opencode/commands/rollback.md +0 -721
- package/.opencode/commands/ship.md +0 -213
- package/.opencode/commands/sonarcloud.md +0 -149
- package/.opencode/commands/status.md +0 -90
- package/.opencode/commands/validate.md +0 -288
- package/.opencode/commands/verify.md +0 -269
- package/.roo/commands/dev.md +0 -346
- package/.roo/commands/plan.md +0 -567
- package/.roo/commands/premerge.md +0 -187
- package/.roo/commands/research.md +0 -43
- package/.roo/commands/review.md +0 -452
- package/.roo/commands/rollback.md +0 -722
- package/.roo/commands/ship.md +0 -214
- package/.roo/commands/sonarcloud.md +0 -150
- package/.roo/commands/status.md +0 -91
- package/.roo/commands/validate.md +0 -289
- package/.roo/commands/verify.md +0 -270
- package/docs/BEADS_GITHUB_SYNC.md +0 -281
- package/docs/GREPTILE_SETUP.md +0 -400
- package/docs/MANUAL_REVIEW_GUIDE.md +0 -106
- package/docs/SETUP.md +0 -663
- package/docs/VALIDATION.md +0 -363
- package/lib/agents/cline.plugin.json +0 -29
- package/lib/agents/copilot.plugin.json +0 -24
- package/lib/agents/kilocode.plugin.json +0 -22
- package/lib/agents/opencode.plugin.json +0 -23
- package/lib/agents/roo.plugin.json +0 -30
- package/lib/beads-bootstrap.js +0 -225
- package/lib/beads-health-check.js +0 -188
- package/lib/commands/commands-reset.js +0 -147
- package/opencode.json +0 -67
- package/scripts/beads-context.test.js +0 -584
- package/scripts/github-beads-sync/comment.mjs +0 -64
- package/scripts/github-beads-sync/config.mjs +0 -148
- package/scripts/github-beads-sync/github-api.mjs +0 -131
- package/scripts/github-beads-sync/index.mjs +0 -356
- package/scripts/github-beads-sync/label-mapper.mjs +0 -54
- package/scripts/github-beads-sync/mapping.mjs +0 -132
- package/scripts/github-beads-sync/reverse-sync-cli.mjs +0 -31
- package/scripts/github-beads-sync/reverse-sync.mjs +0 -162
- package/scripts/github-beads-sync/run-bd.mjs +0 -161
- package/scripts/github-beads-sync/sanitize.mjs +0 -121
- package/scripts/github-beads-sync.config.json +0 -26
- package/scripts/sync-commands.js +0 -600
|
@@ -1,17 +1,22 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Review Thread Handling Process
|
|
2
2
|
|
|
3
|
-
**Purpose**: Standardized process for AI agents to systematically handle
|
|
3
|
+
**Purpose**: Standardized process for AI agents to systematically handle PR
|
|
4
|
+
review threads from **any review agent** — CodeRabbit, Qodo, Greptile, or a
|
|
5
|
+
human reviewer. The mechanism (GitHub review threads via GraphQL/REST) is the
|
|
6
|
+
same regardless of which tool or person authored the comment; the examples below
|
|
7
|
+
name specific tools only as illustrations.
|
|
4
8
|
|
|
5
|
-
**Critical**:
|
|
9
|
+
**Critical**: Review threads left unresolved block merges. AI agents MUST follow
|
|
10
|
+
these exact steps for EVERY review comment, whoever authored it.
|
|
6
11
|
|
|
7
12
|
---
|
|
8
13
|
|
|
9
14
|
## Problem Background
|
|
10
15
|
|
|
11
16
|
**Previous Issues:**
|
|
12
|
-
- ❌ AI agents replied to PR with general comments instead of replying directly to each
|
|
17
|
+
- ❌ AI agents replied to the PR with general comments instead of replying directly to each review thread
|
|
13
18
|
- ❌ AI agents didn't mark conversation threads as "resolved" after fixing issues
|
|
14
|
-
- ❌ No systematic process for tracking which
|
|
19
|
+
- ❌ No systematic process for tracking which review comments are addressed vs pending
|
|
15
20
|
- ❌ Caused confusion and manual tracking overhead for maintainers
|
|
16
21
|
|
|
17
22
|
**Why This Matters:**
|
|
@@ -39,28 +44,31 @@
|
|
|
39
44
|
- Reply explains what was fixed and why
|
|
40
45
|
- Resolve marks the thread as addressed
|
|
41
46
|
|
|
47
|
+
These two GitHub operations are author-agnostic: they work identically for a
|
|
48
|
+
CodeRabbit thread, a Qodo thread, a Greptile thread, or a human reviewer's thread.
|
|
49
|
+
|
|
42
50
|
---
|
|
43
51
|
|
|
44
52
|
## For AI Agents: Mandatory Steps
|
|
45
53
|
|
|
46
|
-
When
|
|
54
|
+
When a review-agent quality gate fails or when review comments exist:
|
|
47
55
|
|
|
48
|
-
### Step 1: List ALL
|
|
56
|
+
### Step 1: List ALL Review Feedback (Inline + Direct Comments)
|
|
49
57
|
|
|
50
|
-
|
|
58
|
+
Review agents post feedback in **two places**:
|
|
51
59
|
1. **Inline review threads** — attached to specific code lines (resolvable via GraphQL)
|
|
52
|
-
2. **Direct PR issue comments** — "Additional Comments (N)" posted as regular PR comments (reply with `gh pr comment`)
|
|
60
|
+
2. **Direct PR issue comments** — summaries or "Additional Comments (N)" posted as regular PR comments (reply with `gh pr comment`)
|
|
53
61
|
|
|
54
62
|
Always run `list-all` to see both:
|
|
55
63
|
|
|
56
64
|
```bash
|
|
57
|
-
bash .claude/scripts/
|
|
65
|
+
bash .claude/scripts/review-resolve.sh list-all <pr-number>
|
|
58
66
|
```
|
|
59
67
|
|
|
60
68
|
Or just inline threads (unresolved only):
|
|
61
69
|
|
|
62
70
|
```bash
|
|
63
|
-
bash .claude/scripts/
|
|
71
|
+
bash .claude/scripts/review-resolve.sh list <pr-number> --unresolved
|
|
64
72
|
```
|
|
65
73
|
|
|
66
74
|
**Output shows:**
|
|
@@ -68,6 +76,7 @@ bash .claude/scripts/greptile-resolve.sh list <pr-number> --unresolved
|
|
|
68
76
|
- Comment ID (for replying to inline threads)
|
|
69
77
|
- File path and line number
|
|
70
78
|
- Issue description
|
|
79
|
+
- Author (so you can see whether it came from CodeRabbit, Greptile, Qodo, a human, etc.)
|
|
71
80
|
- Direct PR comment IDs and previews (reply with `gh pr comment`)
|
|
72
81
|
|
|
73
82
|
**Example:**
|
|
@@ -85,7 +94,7 @@ bash .claude/scripts/greptile-resolve.sh list <pr-number> --unresolved
|
|
|
85
94
|
|
|
86
95
|
1. **Read the comment** and understand the issue
|
|
87
96
|
- Use the file path and line number to locate the code
|
|
88
|
-
- Understand what
|
|
97
|
+
- Understand what the reviewer is flagging
|
|
89
98
|
|
|
90
99
|
2. **Fix the issue** if the comment is valid
|
|
91
100
|
- Make the necessary code changes
|
|
@@ -93,7 +102,7 @@ bash .claude/scripts/greptile-resolve.sh list <pr-number> --unresolved
|
|
|
93
102
|
|
|
94
103
|
3. **Reply to the thread** with explanation
|
|
95
104
|
```bash
|
|
96
|
-
bash .claude/scripts/
|
|
105
|
+
bash .claude/scripts/review-resolve.sh reply <pr-number> <comment-id> "✅ Fixed: [description]
|
|
97
106
|
|
|
98
107
|
Changed: [what was changed]
|
|
99
108
|
Reason: [why this fixes the issue]
|
|
@@ -102,14 +111,14 @@ bash .claude/scripts/greptile-resolve.sh list <pr-number> --unresolved
|
|
|
102
111
|
|
|
103
112
|
4. **Resolve the thread**
|
|
104
113
|
```bash
|
|
105
|
-
bash .claude/scripts/
|
|
114
|
+
bash .claude/scripts/review-resolve.sh resolve <pr-number> <thread-id>
|
|
106
115
|
```
|
|
107
116
|
|
|
108
117
|
5. **Track progress**: Mark comment as addressed in your notes
|
|
109
118
|
|
|
110
119
|
**Alternative (all-in-one):**
|
|
111
120
|
```bash
|
|
112
|
-
bash .claude/scripts/
|
|
121
|
+
bash .claude/scripts/review-resolve.sh reply-and-resolve <pr-number> <comment-id> <thread-id> "✅ Fixed: [description]
|
|
113
122
|
|
|
114
123
|
Changed: [what was changed]
|
|
115
124
|
Reason: [why this fixes the issue]
|
|
@@ -119,17 +128,17 @@ Commit: [commit-sha]"
|
|
|
119
128
|
### Step 3: Verify All Threads Resolved
|
|
120
129
|
|
|
121
130
|
```bash
|
|
122
|
-
bash .claude/scripts/
|
|
131
|
+
bash .claude/scripts/review-resolve.sh list <pr-number> --unresolved
|
|
123
132
|
```
|
|
124
133
|
|
|
125
134
|
**Should show**: "No unresolved comments" or empty list
|
|
126
135
|
|
|
127
136
|
**Confirm with stats:**
|
|
128
137
|
```bash
|
|
129
|
-
bash .claude/scripts/
|
|
138
|
+
bash .claude/scripts/review-resolve.sh stats <pr-number>
|
|
130
139
|
```
|
|
131
140
|
|
|
132
|
-
**Should show**:
|
|
141
|
+
**Should show**: all tracked review threads resolved.
|
|
133
142
|
|
|
134
143
|
### Step 4: Push Changes & Poll Briefly for Re-review
|
|
135
144
|
|
|
@@ -137,10 +146,10 @@ bash .claude/scripts/greptile-resolve.sh stats <pr-number>
|
|
|
137
146
|
git push
|
|
138
147
|
```
|
|
139
148
|
|
|
140
|
-
**
|
|
149
|
+
**The review agent will automatically:**
|
|
141
150
|
- Re-analyze the PR
|
|
142
|
-
- Update
|
|
143
|
-
- Re-run
|
|
151
|
+
- Update any confidence/quality score
|
|
152
|
+
- Re-run its quality gate check
|
|
144
153
|
|
|
145
154
|
---
|
|
146
155
|
|
|
@@ -148,7 +157,7 @@ git push
|
|
|
148
157
|
|
|
149
158
|
```bash
|
|
150
159
|
# 1. List unresolved threads
|
|
151
|
-
$ bash .claude/scripts/
|
|
160
|
+
$ bash .claude/scripts/review-resolve.sh list 24 --unresolved
|
|
152
161
|
|
|
153
162
|
✗ UNRESOLVED | docs/ROADMAP.md:280
|
|
154
163
|
Thread ID: PRRT_kwDORErEU85tuh6I
|
|
@@ -160,7 +169,7 @@ $ git add docs/ROADMAP.md
|
|
|
160
169
|
$ git commit -m "fix: replace Windows absolute paths with relative paths"
|
|
161
170
|
|
|
162
171
|
# 3. Reply and resolve in one step
|
|
163
|
-
$ bash .claude/scripts/
|
|
172
|
+
$ bash .claude/scripts/review-resolve.sh reply-and-resolve 24 2787717459 PRRT_kwDORErEU85tuh6I \
|
|
164
173
|
"✅ Fixed: Replaced Windows absolute paths with repo-relative paths
|
|
165
174
|
|
|
166
175
|
Changed: C:\\Users\\...\\plans\\... → .claude/plans/*.md
|
|
@@ -171,10 +180,10 @@ Commit: abc123"
|
|
|
171
180
|
✅ Thread resolved successfully
|
|
172
181
|
|
|
173
182
|
# 4. Verify all resolved
|
|
174
|
-
$ bash .claude/scripts/
|
|
183
|
+
$ bash .claude/scripts/review-resolve.sh stats 24
|
|
175
184
|
|
|
176
|
-
|
|
177
|
-
✓ All
|
|
185
|
+
Unresolved: 0
|
|
186
|
+
✓ All review threads resolved!
|
|
178
187
|
|
|
179
188
|
# 5. Push changes
|
|
180
189
|
$ git push
|
|
@@ -188,7 +197,7 @@ $ git push
|
|
|
188
197
|
- **Reply to EACH comment thread** using the script (not as separate PR comment)
|
|
189
198
|
- **Mark EACH thread as resolved** after fixing using the script
|
|
190
199
|
- **Track progress** (X of Y fixed) in your notes
|
|
191
|
-
- **Poll for
|
|
200
|
+
- **Poll for re-review for at most 60 seconds** after pushing fixes, then stop and hand off if it is still pending
|
|
192
201
|
- **Use comment ID for replies**, thread ID for resolving
|
|
193
202
|
- **Commit fixes BEFORE replying** so you can reference commit SHA
|
|
194
203
|
|
|
@@ -204,54 +213,60 @@ $ git push
|
|
|
204
213
|
|
|
205
214
|
## Script Commands Reference
|
|
206
215
|
|
|
216
|
+
The `.claude/scripts/review-resolve.sh` helper works for review threads authored
|
|
217
|
+
by any tool or person. The `list-all`, `resolve-all`, and `stats` commands
|
|
218
|
+
additionally recognize `greptile-apps`-authored threads as a built-in convenience
|
|
219
|
+
(Greptile is one supported review tool); the core commands below are fully
|
|
220
|
+
author-agnostic.
|
|
221
|
+
|
|
207
222
|
### List Threads
|
|
208
223
|
```bash
|
|
209
224
|
# All threads
|
|
210
|
-
bash .claude/scripts/
|
|
225
|
+
bash .claude/scripts/review-resolve.sh list <pr-number>
|
|
211
226
|
|
|
212
227
|
# Only unresolved
|
|
213
|
-
bash .claude/scripts/
|
|
228
|
+
bash .claude/scripts/review-resolve.sh list <pr-number> --unresolved
|
|
214
229
|
```
|
|
215
230
|
|
|
216
231
|
### Reply to Thread
|
|
217
232
|
```bash
|
|
218
|
-
bash .claude/scripts/
|
|
233
|
+
bash .claude/scripts/review-resolve.sh reply <pr-number> <comment-id> "<message>"
|
|
219
234
|
```
|
|
220
235
|
|
|
221
236
|
### Resolve Thread
|
|
222
237
|
```bash
|
|
223
|
-
bash .claude/scripts/
|
|
238
|
+
bash .claude/scripts/review-resolve.sh resolve <pr-number> <thread-id>
|
|
224
239
|
```
|
|
225
240
|
|
|
226
241
|
### Reply and Resolve (Recommended)
|
|
227
242
|
```bash
|
|
228
|
-
bash .claude/scripts/
|
|
243
|
+
bash .claude/scripts/review-resolve.sh reply-and-resolve <pr-number> <comment-id> <thread-id> "<message>"
|
|
229
244
|
```
|
|
230
245
|
|
|
231
246
|
### Batch Resolve (After all issues fixed)
|
|
232
247
|
```bash
|
|
233
|
-
bash .claude/scripts/
|
|
248
|
+
bash .claude/scripts/review-resolve.sh resolve-all <pr-number>
|
|
234
249
|
```
|
|
235
250
|
**⚠️ Warning**: Only use after ALL issues are fixed and replied to
|
|
236
251
|
|
|
237
252
|
### Statistics
|
|
238
253
|
```bash
|
|
239
|
-
bash .claude/scripts/
|
|
254
|
+
bash .claude/scripts/review-resolve.sh stats <pr-number>
|
|
240
255
|
```
|
|
241
256
|
|
|
242
257
|
---
|
|
243
258
|
|
|
244
259
|
## Integration with `/review` Command
|
|
245
260
|
|
|
246
|
-
The `/review` command
|
|
261
|
+
The `/review` command includes these steps:
|
|
247
262
|
|
|
248
263
|
1. Run `/review` as usual to analyze PR feedback
|
|
249
|
-
2. For
|
|
264
|
+
2. For review-agent comments (CodeRabbit, Qodo, Greptile, human), use the script to:
|
|
250
265
|
- List unresolved threads
|
|
251
266
|
- Fix each issue
|
|
252
267
|
- Reply and resolve systematically
|
|
253
268
|
3. Verify all threads resolved before declaring review complete
|
|
254
|
-
4. Push changes and poll briefly for
|
|
269
|
+
4. Push changes and poll briefly for re-review
|
|
255
270
|
|
|
256
271
|
---
|
|
257
272
|
|
|
@@ -269,17 +284,17 @@ The `/review` command should now include these steps:
|
|
|
269
284
|
**Cause**: GitHub UI caching
|
|
270
285
|
**Solution**: Refresh page, or check with GraphQL query
|
|
271
286
|
|
|
272
|
-
###
|
|
287
|
+
### Review score not updating after fixes
|
|
273
288
|
**Cause**: Must push commits to trigger re-analysis
|
|
274
|
-
**Solution**: `git push`, check once immediately, and poll for up to 60 seconds. If
|
|
289
|
+
**Solution**: `git push`, check once immediately, and poll for up to 60 seconds. If the review agent is still pending after that, stop and wait for the user to resume later.
|
|
275
290
|
|
|
276
291
|
---
|
|
277
292
|
|
|
278
293
|
## Success Criteria
|
|
279
294
|
|
|
280
295
|
**A review is complete when:**
|
|
281
|
-
- ✅ All
|
|
296
|
+
- ✅ All review threads are resolved (verified with the `stats` command)
|
|
282
297
|
- ✅ All threads have replies explaining fixes
|
|
283
|
-
- ✅
|
|
298
|
+
- ✅ Any review-agent quality gate passes
|
|
284
299
|
- ✅ Branch protection allows merge
|
|
285
300
|
- ✅ No manual tracking needed by maintainers
|
|
@@ -1,10 +1,20 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
|
-
#
|
|
3
|
-
#
|
|
4
|
-
#
|
|
2
|
+
# Review Thread Resolution Tool
|
|
3
|
+
# Resolves GitHub PR review threads from ANY review author — CodeRabbit, Qodo,
|
|
4
|
+
# Greptile, or a human reviewer — the mechanism is author-agnostic.
|
|
5
|
+
# Uses GitHub GraphQL API to systematically resolve review threads.
|
|
6
|
+
# Uses GitHub REST API to reply to review comments.
|
|
7
|
+
# Note: the `list-all`, `resolve-all`, and `stats` convenience commands additionally
|
|
8
|
+
# recognize `greptile-apps`-authored threads (Greptile is one supported review tool);
|
|
9
|
+
# the core list/reply/resolve/reply-and-resolve commands work for every author.
|
|
5
10
|
|
|
6
11
|
set -e
|
|
7
12
|
|
|
13
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
14
|
+
if [ -f "$SCRIPT_DIR/../../scripts/bootstrap-windows-tools.sh" ]; then
|
|
15
|
+
source "$SCRIPT_DIR/../../scripts/bootstrap-windows-tools.sh"
|
|
16
|
+
fi
|
|
17
|
+
|
|
8
18
|
# Colors for output (defined before use)
|
|
9
19
|
RED='\033[0;31m'
|
|
10
20
|
GREEN='\033[0;32m'
|
|
@@ -13,7 +13,7 @@ Bash(git status *), Bash(git log *), Bash(git diff *), Bash(git branch *)
|
|
|
13
13
|
Bash(git add *), Bash(git commit *), Bash(git push *), Bash(git stash *)
|
|
14
14
|
Bash(git checkout *), Bash(git switch *), Bash(git merge *), Bash(git worktree *)
|
|
15
15
|
Bash(bun *), Bash(bunx *), Bash(npm *), Bash(npx *), Bash(node *)
|
|
16
|
-
Bash(
|
|
16
|
+
Bash(forge *), Bash(gh *), Bash(openspec *)
|
|
17
17
|
Bash(ls *), Bash(cat *), Bash(grep *), Bash(find *), Bash(pwd *), Bash(which *)
|
|
18
18
|
Bash(echo *), Bash(head *), Bash(tail *), Bash(sort *), Bash(wc *)
|
|
19
19
|
Bash(mkdir *), Bash(touch *), Bash(cp *), Bash(mv *)
|
|
@@ -21,7 +21,7 @@ Bash(mkdir *), Bash(touch *), Bash(cp *), Bash(mv *)
|
|
|
21
21
|
|
|
22
22
|
## Confirm Before Running (prompt each time)
|
|
23
23
|
|
|
24
|
-
<!-- git reset --hard moved from Deny to Confirm
|
|
24
|
+
<!-- git reset --hard moved from Deny to Confirm ("ask" policy).
|
|
25
25
|
Rationale: agents may need it for worktree cleanup during /verify stage,
|
|
26
26
|
but it should always require user confirmation since it discards uncommitted changes. -->
|
|
27
27
|
```
|
|
@@ -14,6 +14,70 @@ const fs = require("node:fs");
|
|
|
14
14
|
const path = require("node:path");
|
|
15
15
|
const readline = require("node:readline");
|
|
16
16
|
|
|
17
|
+
// ── Config-honest enforcement (issue eda6d866) ──────────────────────────────
|
|
18
|
+
// This pre-commit gate must be INERT when the TDD rail is disabled in
|
|
19
|
+
// .forge/config.yaml. The hook is self-contained (target projects have
|
|
20
|
+
// .forge/hooks/*.js but NOT lib/), so it reads the config directly. `forge gate
|
|
21
|
+
// disable rail.tdd_intent` writes workflow.gates['rail.tdd_intent']; the `full`
|
|
22
|
+
// profile writes top-level rails.tdd_intent — honor either. Missing/unparseable
|
|
23
|
+
// config FAILS TOWARD enforcement (returns true) so a gate the user did not
|
|
24
|
+
// disable is never silently dropped.
|
|
25
|
+
function isTddEnabled(projectRoot) {
|
|
26
|
+
let raw;
|
|
27
|
+
try {
|
|
28
|
+
raw = fs.readFileSync(path.join(projectRoot, ".forge", "config.yaml"), "utf8");
|
|
29
|
+
} catch {
|
|
30
|
+
return true; // no config → enforce
|
|
31
|
+
}
|
|
32
|
+
if (!raw || !raw.trim()) return true;
|
|
33
|
+
|
|
34
|
+
const railDisabled = (config) =>
|
|
35
|
+
isExplicitlyDisabled(config?.workflow?.gates?.["rail.tdd_intent"]) ||
|
|
36
|
+
isExplicitlyDisabled(config?.rails?.tdd_intent);
|
|
37
|
+
|
|
38
|
+
let YAML;
|
|
39
|
+
try {
|
|
40
|
+
YAML = require("yaml");
|
|
41
|
+
} catch {
|
|
42
|
+
// The yaml MODULE is genuinely unavailable → conservative raw-text scan for the
|
|
43
|
+
// disabled block. Parser presence and parse success are split so a MALFORMED file
|
|
44
|
+
// never reaches this fuzzy scan.
|
|
45
|
+
return !(rawKeyDisabled(raw, "rail.tdd_intent") || rawKeyDisabled(raw, "tdd_intent"));
|
|
46
|
+
}
|
|
47
|
+
try {
|
|
48
|
+
const parsed = YAML.parse(raw);
|
|
49
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return true;
|
|
50
|
+
return !railDisabled(parsed);
|
|
51
|
+
} catch {
|
|
52
|
+
// MALFORMED YAML (module present, parse threw) → FAIL TOWARD ENFORCEMENT (return
|
|
53
|
+
// true). Never fall to the raw-text scan: a broken file with a `rail.tdd_intent:
|
|
54
|
+
// enabled: false` fragment must not switch the gate off (issue eda6d866).
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function isExplicitlyDisabled(node) {
|
|
60
|
+
return Boolean(node) && typeof node === "object" && node.enabled === false;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Scan raw YAML for a `<key>:` block whose immediate child is `enabled: false`.
|
|
64
|
+
function rawKeyDisabled(raw, key) {
|
|
65
|
+
const lines = String(raw).split(/\r?\n/);
|
|
66
|
+
const keyRe = new RegExp(`^(\\s*)"?${key.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}"?\\s*:\\s*$`);
|
|
67
|
+
for (let i = 0; i < lines.length; i += 1) {
|
|
68
|
+
const m = lines[i].match(keyRe);
|
|
69
|
+
if (!m) continue;
|
|
70
|
+
const parentIndent = m[1].length;
|
|
71
|
+
for (let j = i + 1; j < lines.length; j += 1) {
|
|
72
|
+
if (!lines[j].trim()) continue;
|
|
73
|
+
const childIndent = lines[j].match(/^\s*/)[0].length;
|
|
74
|
+
if (childIndent <= parentIndent) break;
|
|
75
|
+
if (/^\s*enabled\s*:\s*false\s*$/.test(lines[j])) return true;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
|
|
17
81
|
// Get staged files using git diff --cached
|
|
18
82
|
function getStagedFiles() {
|
|
19
83
|
try {
|
|
@@ -111,6 +175,9 @@ function hasTestFile(sourceFile, stagedFiles) {
|
|
|
111
175
|
sourceFile.replace(/^bin\//, 'test/cli/').replace(ext, `.spec${ext}`),
|
|
112
176
|
sourceFile.replace(/^bin\//, 'test/bin/').replace(ext, `.test${ext}`),
|
|
113
177
|
sourceFile.replace(/^bin\//, 'test/bin/').replace(ext, `.spec${ext}`),
|
|
178
|
+
// Workspace packages (packages/<pkg>/src/**/foo.js → packages/<pkg>/test/foo.test.js)
|
|
179
|
+
sourceFile.replace(/^(packages\/[^/]+)\/src\/(?:.*\/)?([^/]+)$/, `$1/test/$2`).replace(ext, `.test${ext}`),
|
|
180
|
+
sourceFile.replace(/^(packages\/[^/]+)\/src\/(?:.*\/)?([^/]+)$/, `$1/test/$2`).replace(ext, `.spec${ext}`),
|
|
114
181
|
];
|
|
115
182
|
|
|
116
183
|
// Check if test file exists in staged files or filesystem
|
|
@@ -160,6 +227,12 @@ function promptUser(question, options) {
|
|
|
160
227
|
|
|
161
228
|
// Main hook logic
|
|
162
229
|
async function main() {
|
|
230
|
+
// Project root is two levels up from this installed hook (<root>/.forge/hooks/).
|
|
231
|
+
// When the TDD rail is disabled in config, the gate is inert — allow the commit.
|
|
232
|
+
if (!isTddEnabled(path.resolve(__dirname, "..", ".."))) {
|
|
233
|
+
process.exit(0);
|
|
234
|
+
}
|
|
235
|
+
|
|
163
236
|
console.log("🔍 TDD Check: Verifying test coverage for staged files...\n");
|
|
164
237
|
|
|
165
238
|
const stagedFiles = getStagedFiles();
|
|
@@ -233,8 +306,12 @@ async function main() {
|
|
|
233
306
|
}
|
|
234
307
|
}
|
|
235
308
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
309
|
+
module.exports = { isTddEnabled };
|
|
310
|
+
|
|
311
|
+
// Run with error handling (only as a script, not when required by tests).
|
|
312
|
+
if (require.main === module) {
|
|
313
|
+
main().catch((error) => {
|
|
314
|
+
console.error("Error in TDD check hook:", error.message);
|
|
315
|
+
process.exit(1);
|
|
316
|
+
});
|
|
317
|
+
}
|