forge-workflow 0.0.9 → 0.1.0-beta.2
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 +3 -0
- package/.forge/hooks/forge-native-hook.js +245 -0
- package/.forge/protected-paths.yaml +157 -0
- package/AGENTS.md +151 -61
- package/CHANGELOG.md +681 -0
- package/CLAUDE.md +9 -106
- package/QUICKSTART.md +171 -0
- package/README.md +271 -363
- package/bin/forge-cmd.js +120 -9
- package/bin/forge-preflight.js +26 -5
- package/bin/forge.js +466 -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/{TOOLCHAIN.md → forge/TOOLCHAIN.md} +56 -47
- 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 +118 -0
- package/docs/guides/SUPPORT.md +185 -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 +205 -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/reference/TOOLCHAIN.md +658 -0
- 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 +115 -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/adapter-cli.js +307 -0
- package/lib/adapters/beads-issue-adapter.js +127 -0
- package/lib/adapters/beads-kernel-compat.js +1042 -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 +126 -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-setup.js +225 -28
- package/lib/beads-sync-scaffold.js +36 -107
- package/lib/codex-skills.js +51 -1
- package/lib/commands/_issue.js +744 -70
- package/lib/commands/_manifest.js +91 -0
- package/lib/commands/_registry.js +85 -34
- package/lib/commands/_resolve-command-opts.js +261 -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 +192 -0
- package/lib/commands/hooks.js +242 -0
- package/lib/commands/inbox.js +118 -0
- package/lib/commands/init.js +598 -0
- package/lib/commands/insights.js +79 -0
- package/lib/commands/issue.js +12 -1
- package/lib/commands/issues.js +66 -0
- package/lib/commands/lint.js +5 -0
- package/lib/commands/list.js +2 -2
- package/lib/commands/merge.js +312 -0
- package/lib/commands/migrate.js +523 -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 +436 -24
- package/lib/commands/preflight.js +211 -0
- package/lib/commands/prime.js +13 -0
- package/lib/commands/push.js +69 -2
- package/lib/commands/ready.js +2 -2
- package/lib/commands/recall.js +116 -0
- package/lib/commands/recap.js +61 -0
- package/lib/commands/recommend.js +22 -2
- package/lib/commands/release.js +91 -0
- package/lib/commands/remember.js +74 -0
- package/lib/commands/role.js +99 -0
- package/lib/commands/serve.js +581 -0
- package/lib/commands/setup.js +851 -979
- package/lib/commands/shepherd.js +436 -0
- package/lib/commands/ship.js +23 -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 +329 -11
- package/lib/commands/sync.js +34 -46
- package/lib/commands/team.js +15 -2
- package/lib/commands/test.js +58 -7
- package/lib/commands/update.js +2 -2
- package/lib/commands/upgrade.js +47 -0
- package/lib/commands/validate.js +56 -25
- package/lib/commands/worktree.js +308 -128
- package/lib/config-writer.js +202 -0
- package/lib/control-plane.js +236 -0
- package/lib/core/runtime-graph.js +946 -0
- package/lib/dep-guard/keyword-ripple.js +184 -0
- package/lib/deprecated-sync-cleanup.js +362 -0
- package/lib/detect-agent.js +2 -28
- package/lib/detect-worktree.js +42 -17
- 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 +697 -0
- package/lib/forge-lock.js +262 -0
- package/lib/gate-events.js +193 -0
- package/lib/global-flags.js +74 -0
- package/lib/greptile-match.js +7 -63
- package/lib/harness-capability-matrix.js +380 -0
- package/lib/hook-global-installer.js +347 -0
- package/lib/hook-renderer.js +451 -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/issue-sync/authority.js +100 -0
- package/lib/issue-sync/github-pull.js +184 -0
- package/lib/issue-sync/import-primitives.js +98 -0
- package/lib/issue-sync/legacy-link-bridge.js +436 -0
- package/lib/issue-sync/link-store.js +292 -0
- package/lib/issue-sync/project-github.js +123 -0
- package/lib/issue-sync/reconcile.js +195 -0
- package/lib/issue-sync/schema.js +126 -0
- package/lib/kernel/backing-issue.js +305 -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/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 +2504 -0
- package/lib/kernel/taxonomy-validator.js +394 -0
- package/lib/lefthook-check.js +8 -4
- 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/differ.js +195 -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 +157 -0
- package/lib/pr-monitor/watch-lifecycle.js +95 -0
- package/lib/pr-monitor/watch.js +247 -0
- package/lib/pr-pull.js +1273 -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 +166 -0
- package/lib/protected-path-manifest.js +281 -0
- package/lib/protected-state-surfaces.js +387 -0
- package/lib/release-readiness.js +2089 -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 +332 -23
- 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/conflicts.js +205 -0
- package/lib/smart-status/scoring.js +191 -0
- package/lib/status/beads-snapshot.js +145 -0
- package/lib/status/presenter.js +216 -0
- 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 +199 -0
- package/lib/workflow/enforce-stage.js +298 -47
- package/lib/workflow/stage-transition.js +115 -0
- package/lib/workflow/stages.js +30 -6
- package/lib/workflow/state-manager.js +159 -14
- package/lib/workflow/state.js +23 -1
- package/lib/workflow-profiles.js +17 -5
- package/package.json +46 -36
- 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 +165 -22
- package/scripts/beads-migrate-to-dolt.sh +7 -0
- package/scripts/beads-upgrade-smoke.sh +284 -0
- package/scripts/behavioral-judge.sh +115 -11
- package/scripts/benchmark.js +349 -63
- 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-analyze.js +52 -17
- package/scripts/dep-guard-keyword-ripple.js +29 -0
- package/scripts/dep-guard-render-review.js +86 -0
- package/scripts/dep-guard.sh +64 -232
- 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 +144 -47
- 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 +183 -79
- 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/beads-migrate-to-dolt.mjs +503 -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-coordinator.sh +3 -0
- package/scripts/preflight-sonar.eslint.config.mjs +44 -0
- package/scripts/preflight.sh +108 -0
- package/scripts/protected-state-check.js +104 -0
- package/scripts/smart-status-score.js +31 -0
- package/scripts/smart-status-sessions.js +51 -0
- package/scripts/smart-status.sh +117 -369
- 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-agentic-workflow.js +48 -0
- package/scripts/sync-utils.sh +3 -0
- package/scripts/test-ci-shard.js +251 -0
- package/scripts/test-dashboard.js +188 -52
- package/scripts/test-full-suite.js +186 -0
- package/scripts/test-profile.js +278 -0
- package/scripts/test.js +302 -28
- package/scripts/validate.js +143 -0
- package/scripts/validate.sh +18 -1
- 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} +46 -52
- 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} +134 -159
- 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/skills/ship/SKILL.md +251 -0
- 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/skills/status/SKILL.md +102 -0
- 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/ship.prompt.md +0 -215
- package/.github/prompts/status.prompt.md +0 -92
- package/.github/prompts/verify.prompt.md +0 -271
- package/.github/workflows/beads-to-github.yml +0 -56
- package/.github/workflows/github-to-beads.yml +0 -97
- 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 -255
- 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-health-check.js +0 -143
- package/lib/commands/commands-reset.js +0 -147
- package/opencode.json +0 -67
- package/scripts/beads-context.test.js +0 -567
- 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 -332
- package/scripts/github-beads-sync/label-mapper.mjs +0 -54
- package/scripts/github-beads-sync/mapping.mjs +0 -78
- package/scripts/github-beads-sync/reverse-sync-cli.mjs +0 -31
- package/scripts/github-beads-sync/reverse-sync.mjs +0 -138
- 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
package/scripts/dep-guard.sh
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
# dep-guard.sh
|
|
2
|
+
# dep-guard.sh -- Dependency-guard helper for pre-change impact analysis.
|
|
3
3
|
#
|
|
4
4
|
# Subcommands:
|
|
5
5
|
# find-consumers <file-path> Find files that import/require a given module
|
|
@@ -14,9 +14,29 @@ set -euo pipefail
|
|
|
14
14
|
|
|
15
15
|
# Source shared sanitize library
|
|
16
16
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
17
|
+
if [[ -f "$SCRIPT_DIR/bootstrap-windows-tools.sh" ]]; then
|
|
18
|
+
source "$SCRIPT_DIR/bootstrap-windows-tools.sh"
|
|
19
|
+
fi
|
|
20
|
+
NODE_CMD="${NODE_CMD:-node}"
|
|
17
21
|
source "$SCRIPT_DIR/lib/sanitize.sh"
|
|
18
22
|
|
|
19
|
-
|
|
23
|
+
node_script_path() {
|
|
24
|
+
case "$1" in
|
|
25
|
+
/[A-Za-z]/*)
|
|
26
|
+
_drive="$(printf '%s' "${1:1:1}" | tr '[:lower:]' '[:upper:]')"
|
|
27
|
+
printf '%s:/%s\n' "$_drive" "${1:3}"
|
|
28
|
+
;;
|
|
29
|
+
*)
|
|
30
|
+
if command -v cygpath >/dev/null 2>&1; then
|
|
31
|
+
cygpath -m "$1"
|
|
32
|
+
else
|
|
33
|
+
printf '%s\n' "$1"
|
|
34
|
+
fi
|
|
35
|
+
;;
|
|
36
|
+
esac
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
# ---- Helpers ----------------------------------------------------------------
|
|
20
40
|
|
|
21
41
|
usage() {
|
|
22
42
|
cat >&2 <<'EOF'
|
|
@@ -212,90 +232,28 @@ extract_task_file_from_design() {
|
|
|
212
232
|
}
|
|
213
233
|
|
|
214
234
|
run_phase3_analyzer() {
|
|
215
|
-
local
|
|
216
|
-
local
|
|
217
|
-
local
|
|
235
|
+
local current_json="$1"
|
|
236
|
+
local open_json="$2"
|
|
237
|
+
local in_progress_json="$3"
|
|
218
238
|
local task_file="$4"
|
|
219
239
|
local repository_root="$5"
|
|
220
240
|
local analyzer_script="${DEP_GUARD_ANALYZE_SCRIPT:-scripts/dep-guard-analyze.js}"
|
|
221
241
|
|
|
222
|
-
|
|
223
|
-
"$
|
|
224
|
-
"$
|
|
225
|
-
"$
|
|
226
|
-
"$task_file" \
|
|
227
|
-
"$repository_root"
|
|
242
|
+
printf '{"currentIssue":%s,"openIssues":%s,"inProgressIssues":%s,"taskFile":%s,"repositoryRoot":%s}' \
|
|
243
|
+
"$current_json" \
|
|
244
|
+
"${open_json:-[]}" \
|
|
245
|
+
"${in_progress_json:-[]}" \
|
|
246
|
+
"$(printf '%s' "$task_file" | jq -R '.')" \
|
|
247
|
+
"$(printf '%s' "$repository_root" | jq -R '.')" \
|
|
248
|
+
| "$NODE_CMD" "$(node_script_path "$analyzer_script")" --stdin
|
|
228
249
|
}
|
|
229
250
|
|
|
230
251
|
render_phase3_review() {
|
|
231
|
-
local
|
|
232
|
-
|
|
233
|
-
node - "$analysis_file" <<'NODE'
|
|
234
|
-
const fs = require('node:fs');
|
|
235
|
-
|
|
236
|
-
const analysisPath = process.argv[2];
|
|
237
|
-
const analysis = JSON.parse(fs.readFileSync(analysisPath, 'utf8'));
|
|
238
|
-
const detectorCategories = Object.entries(analysis.scores ?? {})
|
|
239
|
-
.filter(([name, score]) => name !== 'rubric' && Number(score) > 0)
|
|
240
|
-
.map(([name]) => name);
|
|
241
|
-
|
|
242
|
-
const lines = [
|
|
243
|
-
'',
|
|
244
|
-
`Structured dependency review for ${analysis.currentIssue.id}...`,
|
|
245
|
-
'',
|
|
246
|
-
];
|
|
247
|
-
|
|
248
|
-
if (!Array.isArray(analysis.issues) || analysis.issues.length === 0) {
|
|
249
|
-
lines.push('No conflicts detected');
|
|
250
|
-
process.stdout.write(`${lines.join('\n')}\n`);
|
|
251
|
-
process.exit(0);
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
const seenPairs = new Set();
|
|
255
|
-
for (const finding of analysis.issues) {
|
|
256
|
-
const key = `${analysis.currentIssue.id}->${finding.targetIssueId}`;
|
|
257
|
-
if (seenPairs.has(key)) {
|
|
258
|
-
continue;
|
|
259
|
-
}
|
|
260
|
-
seenPairs.add(key);
|
|
261
|
-
lines.push(`Issue pair: ${analysis.currentIssue.id} -> ${finding.targetIssueId}`);
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
lines.push(`Rubric score: ${analysis.scores?.rubric ?? 0}`);
|
|
265
|
-
lines.push(
|
|
266
|
-
`Confidence: ${(analysis.confidence?.score ?? 0).toFixed(2)}${
|
|
267
|
-
analysis.confidence?.belowThreshold ? ' (below 70% threshold)' : ''
|
|
268
|
-
}`,
|
|
269
|
-
);
|
|
270
|
-
lines.push(`Detector categories: ${detectorCategories.join(', ') || 'none'}`);
|
|
271
|
-
lines.push(`Needs user decision: ${analysis.needsUserDecision ? 'yes' : 'no'}`);
|
|
272
|
-
|
|
273
|
-
if (Array.isArray(analysis.detectorConflicts) && analysis.detectorConflicts.length > 0) {
|
|
274
|
-
lines.push('Conflicts:');
|
|
275
|
-
for (const conflict of analysis.detectorConflicts) {
|
|
276
|
-
lines.push(` - ${conflict}`);
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
if (Array.isArray(analysis.proposals) && analysis.proposals.length > 0) {
|
|
281
|
-
lines.push('');
|
|
282
|
-
lines.push('Proposed dependency updates:');
|
|
283
|
-
for (const proposal of analysis.proposals) {
|
|
284
|
-
lines.push(` - ${proposal.dependentIssueId} depends on ${proposal.dependsOnIssueId}`);
|
|
285
|
-
if (Array.isArray(proposal.pros) && proposal.pros.length > 0) {
|
|
286
|
-
lines.push(` Pros: ${proposal.pros.join('; ')}`);
|
|
287
|
-
}
|
|
288
|
-
if (Array.isArray(proposal.cons) && proposal.cons.length > 0) {
|
|
289
|
-
lines.push(` Cons: ${proposal.cons.join('; ')}`);
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
process.stdout.write(`${lines.join('\n')}\n`);
|
|
295
|
-
NODE
|
|
252
|
+
local renderer_script="${DEP_GUARD_RENDER_SCRIPT:-scripts/dep-guard-render-review.js}"
|
|
253
|
+
"$NODE_CMD" "$(node_script_path "$renderer_script")"
|
|
296
254
|
}
|
|
297
255
|
|
|
298
|
-
#
|
|
256
|
+
# ---- Subcommands ------------------------------------------------------------
|
|
299
257
|
|
|
300
258
|
cmd_find_consumers() {
|
|
301
259
|
if [[ $# -lt 1 || -z "$1" ]]; then
|
|
@@ -343,11 +301,11 @@ cmd_check_ripple_keyword_v1() {
|
|
|
343
301
|
local issue_id
|
|
344
302
|
issue_id="$(sanitize "$1")"
|
|
345
303
|
|
|
346
|
-
#
|
|
304
|
+
# ---- Step 1: Validate issue exists ----------------------------------------
|
|
347
305
|
local src_json
|
|
348
306
|
src_json="$(bd_show_json "$issue_id")"
|
|
349
307
|
|
|
350
|
-
#
|
|
308
|
+
# ---- Step 2: Extract source title ----------------------------------------
|
|
351
309
|
local src_title=""
|
|
352
310
|
if command -v jq &>/dev/null; then
|
|
353
311
|
src_title="$(printf '%s' "$src_json" | jq -r '.title // ""' 2>/dev/null)" || true
|
|
@@ -358,15 +316,15 @@ cmd_check_ripple_keyword_v1() {
|
|
|
358
316
|
fi
|
|
359
317
|
|
|
360
318
|
if [[ -z "$src_title" ]]; then
|
|
361
|
-
echo "
|
|
319
|
+
echo "Warning: could not extract title for ${issue_id} - ripple check skipped" >&2
|
|
362
320
|
return 0
|
|
363
321
|
fi
|
|
364
322
|
|
|
365
323
|
echo ""
|
|
366
|
-
printf '%s\n' "
|
|
324
|
+
printf '%s\n' "Ripple check for ${issue_id}..."
|
|
367
325
|
echo ""
|
|
368
326
|
|
|
369
|
-
#
|
|
327
|
+
# ---- Step 3: Collect active issues ---------------------------------------
|
|
370
328
|
# Run bd list for open and in_progress separately, combine results
|
|
371
329
|
local list_output=""
|
|
372
330
|
local open_list=""
|
|
@@ -390,122 +348,24 @@ cmd_check_ripple_keyword_v1() {
|
|
|
390
348
|
fi
|
|
391
349
|
|
|
392
350
|
if [[ -z "$list_output" ]]; then
|
|
393
|
-
echo "
|
|
351
|
+
echo "Warning: could not fetch active issue list - ripple check skipped" >&2
|
|
394
352
|
return 0
|
|
395
353
|
fi
|
|
396
354
|
|
|
397
|
-
#
|
|
398
|
-
# Format:
|
|
399
|
-
#
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
# Stop words to exclude from keyword matching
|
|
404
|
-
local stop_words=" the a an and or is in to for of with on at by from add fix update implement create remove delete make use get set run test check all this that it be as not no but if do we they are was were been have has had will would could should may can each every both also into than then when where which what how why who its new first last same other "
|
|
405
|
-
|
|
406
|
-
# Tokenize source title: lowercase, split on non-alpha, filter stop words + short terms
|
|
407
|
-
local src_terms=""
|
|
408
|
-
src_terms="$(printf '%s' "$src_title" | tr '[:upper:]' '[:lower:]' | tr -cs '[:alpha:]' '\n' | sort -u)"
|
|
409
|
-
|
|
410
|
-
# Filter source terms
|
|
411
|
-
local filtered_src_terms=""
|
|
412
|
-
while IFS= read -r term; do
|
|
413
|
-
[[ -z "$term" ]] && continue
|
|
414
|
-
# Skip terms < 3 characters
|
|
415
|
-
[[ ${#term} -lt 3 ]] && continue
|
|
416
|
-
# Skip stop words
|
|
417
|
-
if [[ "$stop_words" == *" ${term} "* ]]; then
|
|
418
|
-
continue
|
|
419
|
-
fi
|
|
420
|
-
filtered_src_terms="${filtered_src_terms} ${term}"
|
|
421
|
-
done <<< "$src_terms"
|
|
422
|
-
|
|
423
|
-
# Process each line in list_output
|
|
424
|
-
while IFS= read -r line; do
|
|
425
|
-
[[ -z "$line" ]] && continue
|
|
426
|
-
|
|
427
|
-
# Extract issue ID (forge-xxx pattern)
|
|
428
|
-
local cand_id=""
|
|
429
|
-
cand_id="$(printf '%s' "$line" | grep -oE 'forge-[a-zA-Z0-9]+(\.[a-zA-Z0-9]+)*' | head -1)" || continue
|
|
430
|
-
[[ -z "$cand_id" ]] && continue
|
|
431
|
-
|
|
432
|
-
# Skip the source issue itself
|
|
433
|
-
[[ "$cand_id" == "$issue_id" ]] && continue
|
|
434
|
-
|
|
435
|
-
# Extract status symbol and map to label
|
|
436
|
-
local cand_status="open"
|
|
437
|
-
if printf '%s' "$line" | grep -q '◐'; then
|
|
438
|
-
cand_status="in_progress"
|
|
439
|
-
fi
|
|
440
|
-
|
|
441
|
-
# Extract priority (P1, P2, P3, etc.)
|
|
442
|
-
local cand_priority=""
|
|
443
|
-
cand_priority="$(printf '%s' "$line" | grep -oE 'P[0-9]+' | head -1)" || true
|
|
444
|
-
[[ -z "$cand_priority" ]] && cand_priority="P2"
|
|
445
|
-
|
|
446
|
-
# Extract title (everything after " - ")
|
|
447
|
-
local cand_title=""
|
|
448
|
-
cand_title="$(printf '%s' "$line" | sed 's/^[^]]*\] [^]]*\] - //')" || continue
|
|
449
|
-
[[ -z "$cand_title" ]] && continue
|
|
450
|
-
|
|
451
|
-
# Tokenize candidate title
|
|
452
|
-
local cand_terms=""
|
|
453
|
-
cand_terms="$(printf '%s' "$cand_title" | tr '[:upper:]' '[:lower:]' | tr -cs '[:alpha:]' '\n' | sort -u)"
|
|
454
|
-
|
|
455
|
-
# Filter candidate terms
|
|
456
|
-
local filtered_cand_terms=""
|
|
457
|
-
while IFS= read -r term; do
|
|
458
|
-
[[ -z "$term" ]] && continue
|
|
459
|
-
[[ ${#term} -lt 3 ]] && continue
|
|
460
|
-
if [[ "$stop_words" == *" ${term} "* ]]; then
|
|
461
|
-
continue
|
|
462
|
-
fi
|
|
463
|
-
filtered_cand_terms="${filtered_cand_terms} ${term}"
|
|
464
|
-
done <<< "$cand_terms"
|
|
465
|
-
|
|
466
|
-
# ── Step 6: Find shared meaningful terms ───────────────────────────────
|
|
467
|
-
local shared_terms=""
|
|
468
|
-
local shared_count=0
|
|
469
|
-
for src_t in $filtered_src_terms; do
|
|
470
|
-
for cand_t in $filtered_cand_terms; do
|
|
471
|
-
if [[ "$src_t" == "$cand_t" ]]; then
|
|
472
|
-
if [[ -z "$shared_terms" ]]; then
|
|
473
|
-
shared_terms="\"${src_t}\""
|
|
474
|
-
else
|
|
475
|
-
shared_terms="${shared_terms}, \"${src_t}\""
|
|
476
|
-
fi
|
|
477
|
-
shared_count=$((shared_count + 1))
|
|
478
|
-
break
|
|
479
|
-
fi
|
|
480
|
-
done
|
|
481
|
-
done
|
|
482
|
-
|
|
483
|
-
# ── Step 7: Report if >= 2 shared terms ────────────────────────────────
|
|
484
|
-
if [[ $shared_count -ge 2 ]]; then
|
|
485
|
-
overlap_count=$((overlap_count + 1))
|
|
486
|
-
overlap_report="${overlap_report} ${cand_id} (${cand_status}, ${cand_priority}): \"${cand_title}\""$'\n'
|
|
487
|
-
overlap_report="${overlap_report} Overlap: keyword match — ${shared_terms}"$'\n'
|
|
488
|
-
overlap_report="${overlap_report} Confidence: LOW (keyword only, no contract data)"$'\n'
|
|
489
|
-
overlap_report="${overlap_report}"$'\n'
|
|
490
|
-
overlap_report="${overlap_report} Options:"$'\n'
|
|
491
|
-
overlap_report="${overlap_report} (a) Add dependency: bd dep add ${issue_id} ${cand_id}"$'\n'
|
|
492
|
-
overlap_report="${overlap_report} (b) Proceed — no real conflict"$'\n'
|
|
493
|
-
overlap_report="${overlap_report} (c) Investigate: bd show ${cand_id}"$'\n'
|
|
494
|
-
overlap_report="${overlap_report}"$'\n'
|
|
495
|
-
fi
|
|
496
|
-
|
|
497
|
-
done <<< "$list_output"
|
|
498
|
-
|
|
499
|
-
# ── Step 8: Output final report ──────────────────────────────────────
|
|
500
|
-
if [[ $overlap_count -gt 0 ]]; then
|
|
501
|
-
printf '%s\n' "⚠️ Potential overlap with ${overlap_count} issue(s):"
|
|
502
|
-
echo ""
|
|
503
|
-
printf '%s' "$overlap_report"
|
|
504
|
-
else
|
|
505
|
-
printf '%s\n' "✅ No conflicts detected"
|
|
355
|
+
# ---- Step 4: Parse each active issue (excluding source) ------------------
|
|
356
|
+
# Format: - forge-xxx [P2] [feature] - Title of the issue
|
|
357
|
+
# - forge-yyy [P1] [task] - Another issue title
|
|
358
|
+
if ! command -v "$NODE_CMD" >/dev/null 2>&1; then
|
|
359
|
+
echo "Error: ${NODE_CMD} is required but not found." >&2
|
|
360
|
+
exit 1
|
|
506
361
|
fi
|
|
507
362
|
|
|
363
|
+
ISSUE_ID="$issue_id" \
|
|
364
|
+
SOURCE_TITLE="$src_title" \
|
|
365
|
+
LIST_OUTPUT="$list_output" \
|
|
366
|
+
"$NODE_CMD" "$(node_script_path "$SCRIPT_DIR/dep-guard-keyword-ripple.js")"
|
|
508
367
|
return 0
|
|
368
|
+
|
|
509
369
|
}
|
|
510
370
|
|
|
511
371
|
cmd_check_ripple() {
|
|
@@ -529,7 +389,7 @@ cmd_check_ripple() {
|
|
|
529
389
|
fi
|
|
530
390
|
|
|
531
391
|
if [[ -z "$src_title" ]]; then
|
|
532
|
-
echo "
|
|
392
|
+
echo "Warning: could not extract title for ${issue_id} - ripple check skipped" >&2
|
|
533
393
|
return 0
|
|
534
394
|
fi
|
|
535
395
|
|
|
@@ -544,7 +404,7 @@ cmd_check_ripple() {
|
|
|
544
404
|
local task_file=""
|
|
545
405
|
task_file="$(extract_task_file_from_design "$design_text" || true)"
|
|
546
406
|
if [[ -z "$task_file" || ! -f "$task_file" ]]; then
|
|
547
|
-
echo "
|
|
407
|
+
echo "Warning: structured analyzer unavailable, falling back to keyword-only ripple check." >&2
|
|
548
408
|
cmd_check_ripple_keyword_v1 "$issue_id"
|
|
549
409
|
return 0
|
|
550
410
|
fi
|
|
@@ -555,51 +415,23 @@ cmd_check_ripple() {
|
|
|
555
415
|
in_progress_json="$(${BD_CMD:-bd} list --status=in_progress --json 2>/dev/null)" || true
|
|
556
416
|
|
|
557
417
|
if [[ -z "$open_json" && -z "$in_progress_json" ]]; then
|
|
558
|
-
echo "
|
|
418
|
+
echo "Warning: could not fetch active issue list - ripple check skipped" >&2
|
|
559
419
|
return 0
|
|
560
420
|
fi
|
|
561
421
|
|
|
562
|
-
local tmp_dir
|
|
563
|
-
tmp_dir="$(mktemp -d)"
|
|
564
|
-
# On Windows/Git Bash, normalize to a mixed-mode path so both bash file I/O
|
|
565
|
-
# and Node.js resolve to the same physical location (cygpath -m → C:/...).
|
|
566
|
-
# Preserve the original POSIX path if conversion fails or returns empty.
|
|
567
|
-
if command -v cygpath &>/dev/null; then
|
|
568
|
-
local mixed_tmp_dir
|
|
569
|
-
mixed_tmp_dir="$(cygpath -m "$tmp_dir" 2>/dev/null)" || true
|
|
570
|
-
if [[ -n "$mixed_tmp_dir" && -d "$mixed_tmp_dir" ]]; then
|
|
571
|
-
tmp_dir="$mixed_tmp_dir"
|
|
572
|
-
fi
|
|
573
|
-
fi
|
|
574
|
-
trap 'rm -rf "$tmp_dir"' RETURN
|
|
575
|
-
|
|
576
|
-
printf '%s' "$src_json" > "${tmp_dir}/current.json"
|
|
577
|
-
printf '%s' "${open_json:-[]}" > "${tmp_dir}/open.json"
|
|
578
|
-
printf '%s' "${in_progress_json:-[]}" > "${tmp_dir}/in-progress.json"
|
|
579
422
|
|
|
580
423
|
local repository_root="${DEP_GUARD_REPOSITORY_ROOT:-$PWD}"
|
|
581
424
|
if run_phase3_analyzer \
|
|
582
|
-
"$
|
|
583
|
-
"${
|
|
584
|
-
"${
|
|
425
|
+
"$src_json" \
|
|
426
|
+
"${open_json:-[]}" \
|
|
427
|
+
"${in_progress_json:-[]}" \
|
|
585
428
|
"$task_file" \
|
|
586
429
|
"$repository_root" \
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
trap - RETURN
|
|
590
|
-
rm -rf "$tmp_dir"
|
|
591
|
-
return 0
|
|
592
|
-
fi
|
|
593
|
-
echo "⚠️ Phase 3 review rendering failed — falling back to keyword-only ripple check." >&2
|
|
594
|
-
else
|
|
595
|
-
echo "⚠️ Structured analyzer unavailable, falling back to keyword-only ripple check." >&2
|
|
596
|
-
if [[ -s "${tmp_dir}/analysis.err" ]]; then
|
|
597
|
-
cat "${tmp_dir}/analysis.err" >&2
|
|
598
|
-
fi
|
|
430
|
+
| render_phase3_review; then
|
|
431
|
+
return 0
|
|
599
432
|
fi
|
|
600
433
|
|
|
601
|
-
|
|
602
|
-
rm -rf "$tmp_dir"
|
|
434
|
+
echo "Warning: structured analyzer unavailable, falling back to keyword-only ripple check." >&2
|
|
603
435
|
cmd_check_ripple_keyword_v1 "$issue_id"
|
|
604
436
|
}
|
|
605
437
|
|
|
@@ -624,7 +456,7 @@ cmd_apply_decision() {
|
|
|
624
456
|
die "Failed to add dependency ${dependent_issue} -> ${depends_on_issue}"
|
|
625
457
|
}
|
|
626
458
|
|
|
627
|
-
# Check for cycles
|
|
459
|
+
# Check for cycles -- use exit code as primary signal
|
|
628
460
|
if ! ${BD_CMD:-bd} dep cycles &>/dev/null; then
|
|
629
461
|
rollback_dependency "$dependent_issue" "$depends_on_issue"
|
|
630
462
|
die "Cycle detected for ${dependent_issue} -> ${depends_on_issue}"
|
|
@@ -722,7 +554,7 @@ cmd_extract_contracts() {
|
|
|
722
554
|
local all_contracts=""
|
|
723
555
|
|
|
724
556
|
while IFS= read -r line || [[ -n "$line" ]]; do
|
|
725
|
-
# New task block
|
|
557
|
+
# New task block -- flush previous
|
|
726
558
|
if [[ "$line" =~ ^##\ Task ]]; then
|
|
727
559
|
local _emitted
|
|
728
560
|
_emitted="$(emit_contracts "$current_files" "$current_what")"
|
|
@@ -777,7 +609,7 @@ cmd_extract_contracts() {
|
|
|
777
609
|
printf '%s\n' "$contracts"
|
|
778
610
|
}
|
|
779
611
|
|
|
780
|
-
#
|
|
612
|
+
# ---- Main dispatcher --------------------------------------------------------
|
|
781
613
|
|
|
782
614
|
if [[ $# -lt 1 ]]; then
|
|
783
615
|
usage
|
package/scripts/file-index.sh
CHANGED
|
@@ -21,6 +21,9 @@ fi
|
|
|
21
21
|
|
|
22
22
|
# Source shared libraries
|
|
23
23
|
_FI_SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
24
|
+
if [[ -f "$_FI_SCRIPT_DIR/bootstrap-windows-tools.sh" ]]; then
|
|
25
|
+
source "$_FI_SCRIPT_DIR/bootstrap-windows-tools.sh"
|
|
26
|
+
fi
|
|
24
27
|
source "$_FI_SCRIPT_DIR/lib/sanitize.sh"
|
|
25
28
|
if [[ -f "$_FI_SCRIPT_DIR/lib/jsonl-lock.sh" ]]; then
|
|
26
29
|
source "$_FI_SCRIPT_DIR/lib/jsonl-lock.sh"
|
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
# forge_team_claim — Top-level dispatcher entry point
|
|
11
11
|
#
|
|
12
12
|
# Env overrides (for testing):
|
|
13
|
-
# GH_CMD
|
|
14
|
-
#
|
|
13
|
+
# GH_CMD — Path to gh binary
|
|
14
|
+
# FORGE_CMD — Path to forge binary
|
|
15
15
|
#
|
|
16
16
|
# This file does NOT set errexit/pipefail — callers manage their own shell options.
|
|
17
17
|
|
|
@@ -61,16 +61,22 @@ _claim_prompt() {
|
|
|
61
61
|
fi
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
# _get_github_issue_number <
|
|
65
|
-
# Extracts
|
|
64
|
+
# _get_github_issue_number <issue-id>
|
|
65
|
+
# Extracts the GitHub issue number from the issue's github_issue:<n> label.
|
|
66
|
+
# Returns the number or empty.
|
|
66
67
|
_get_github_issue_number() {
|
|
67
|
-
local
|
|
68
|
-
local
|
|
69
|
-
local
|
|
70
|
-
|
|
68
|
+
local issue_id="$1"
|
|
69
|
+
local forge_cmd="${FORGE_CMD:-forge}"
|
|
70
|
+
local show_output
|
|
71
|
+
show_output="$("$forge_cmd" issue show "$issue_id" --json 2>/dev/null)" || return 1
|
|
71
72
|
|
|
72
73
|
local issue_num
|
|
73
|
-
issue_num="$(printf '%s' "$
|
|
74
|
+
issue_num="$(printf '%s' "$show_output" | jq -r '
|
|
75
|
+
(.data.issue // .data // {})
|
|
76
|
+
| (.labels // [])
|
|
77
|
+
| map(select(startswith("github_issue:")))
|
|
78
|
+
| (.[0] // "")
|
|
79
|
+
| ltrimstr("github_issue:")' 2>/dev/null)"
|
|
74
80
|
if [[ -z "$issue_num" ]]; then
|
|
75
81
|
return 1
|
|
76
82
|
fi
|
|
@@ -90,7 +96,7 @@ _get_github_assignee() {
|
|
|
90
96
|
# _claim_lock_dir — Returns the path to the claim lock directory
|
|
91
97
|
_claim_lock_dir() {
|
|
92
98
|
local root="${TEAM_MAP_ROOT:-.}"
|
|
93
|
-
printf '%s' "$root/.
|
|
99
|
+
printf '%s' "$root/.forge"
|
|
94
100
|
}
|
|
95
101
|
|
|
96
102
|
# ── Public API ───────────────────────────────────────────────────────────
|
|
@@ -149,7 +155,7 @@ claim_with_lock() {
|
|
|
149
155
|
fi
|
|
150
156
|
|
|
151
157
|
local gh_cmd="${GH_CMD:-gh}"
|
|
152
|
-
local
|
|
158
|
+
local forge_cmd="${FORGE_CMD:-forge}"
|
|
153
159
|
local lock_dir
|
|
154
160
|
lock_dir="$(_claim_lock_dir)"
|
|
155
161
|
mkdir -p "$lock_dir"
|
|
@@ -186,8 +192,13 @@ claim_with_lock() {
|
|
|
186
192
|
exit 1
|
|
187
193
|
fi
|
|
188
194
|
fi
|
|
189
|
-
# Claim on both
|
|
190
|
-
|
|
195
|
+
# Claim on both the Forge issue backend and GitHub. The Forge claim is the
|
|
196
|
+
# authoritative backend update, so a failure must abort (exit the flock
|
|
197
|
+
# subshell non-zero); the GitHub assignee edit stays best-effort.
|
|
198
|
+
"$forge_cmd" issue claim "$beads_id" >/dev/null 2>&1 || {
|
|
199
|
+
_claim_error "Failed to claim $beads_id in Forge"
|
|
200
|
+
exit 1
|
|
201
|
+
}
|
|
191
202
|
"$gh_cmd" issue edit "$issue_num" --add-assignee "$current_user" >/dev/null 2>&1 || true
|
|
192
203
|
) 200>"$lock_file"
|
|
193
204
|
local subshell_rc=$?
|
|
@@ -215,8 +226,13 @@ claim_with_lock() {
|
|
|
215
226
|
return 1
|
|
216
227
|
fi
|
|
217
228
|
fi
|
|
218
|
-
# Claim on both
|
|
219
|
-
|
|
229
|
+
# Claim on both the Forge issue backend and GitHub. The Forge claim is the
|
|
230
|
+
# authoritative backend update, so a failure must abort (return non-zero so
|
|
231
|
+
# the RETURN trap releases the lock); the GitHub assignee edit stays best-effort.
|
|
232
|
+
"$forge_cmd" issue claim "$beads_id" >/dev/null 2>&1 || {
|
|
233
|
+
_claim_error "Failed to claim $beads_id in Forge"
|
|
234
|
+
return 1
|
|
235
|
+
}
|
|
220
236
|
"$gh_cmd" issue edit "$issue_num" --add-assignee "$current_user" >/dev/null 2>&1 || true
|
|
221
237
|
fi
|
|
222
238
|
|
|
@@ -234,13 +250,13 @@ forge_team_claim() {
|
|
|
234
250
|
return 1
|
|
235
251
|
fi
|
|
236
252
|
|
|
237
|
-
local
|
|
253
|
+
local forge_cmd="${FORGE_CMD:-forge}"
|
|
238
254
|
|
|
239
255
|
if [[ "$force_flag" == "--force" ]]; then
|
|
240
256
|
# Skip pre-claim check, claim directly (pass --force to skip lock re-check too)
|
|
241
257
|
claim_with_lock "$beads_id" "--force" || return 1
|
|
242
|
-
# Log override
|
|
243
|
-
"$
|
|
258
|
+
# Log the override as an issue comment
|
|
259
|
+
"$forge_cmd" issue comment "$beads_id" "Force-claimed by $(get_github_user 2>/dev/null || echo 'unknown')" >/dev/null 2>&1 || true
|
|
244
260
|
_claim_info "$beads_id force-claimed successfully"
|
|
245
261
|
return 0
|
|
246
262
|
fi
|