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
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Shared Windows/WSL command bootstrap for bash entrypoints.
|
|
3
|
+
|
|
4
|
+
if [[ -n "${_FORGE_BOOTSTRAP_WINDOWS_TOOLS_LOADED:-}" ]]; then
|
|
5
|
+
return 0 2>/dev/null || exit 0
|
|
6
|
+
fi
|
|
7
|
+
_FORGE_BOOTSTRAP_WINDOWS_TOOLS_LOADED=1
|
|
8
|
+
|
|
9
|
+
_forge_to_unix_path() {
|
|
10
|
+
local raw="$1"
|
|
11
|
+
if command -v wslpath >/dev/null 2>&1; then
|
|
12
|
+
wslpath -u "$raw" 2>/dev/null && return 0
|
|
13
|
+
fi
|
|
14
|
+
if command -v cygpath >/dev/null 2>&1; then
|
|
15
|
+
cygpath -u "$raw" 2>/dev/null && return 0
|
|
16
|
+
fi
|
|
17
|
+
printf '%s\n' "$raw"
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
_forge_resolve_tool() {
|
|
21
|
+
local name="$1"
|
|
22
|
+
local found=""
|
|
23
|
+
|
|
24
|
+
found="$(command -v "$name" 2>/dev/null || true)"
|
|
25
|
+
if [[ -n "$found" ]]; then
|
|
26
|
+
printf '%s\n' "$found"
|
|
27
|
+
return 0
|
|
28
|
+
fi
|
|
29
|
+
|
|
30
|
+
if command -v where.exe >/dev/null 2>&1; then
|
|
31
|
+
found="$(where.exe "$name" 2>/dev/null | tr -d '\r' | head -n 1 || true)"
|
|
32
|
+
if [[ -n "$found" ]]; then
|
|
33
|
+
_forge_to_unix_path "$found"
|
|
34
|
+
return 0
|
|
35
|
+
fi
|
|
36
|
+
fi
|
|
37
|
+
|
|
38
|
+
return 1
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if [[ -z "${BD_CMD:-}" ]]; then
|
|
42
|
+
BD_CMD="$(_forge_resolve_tool bd || true)"
|
|
43
|
+
fi
|
|
44
|
+
if [[ -n "${BD_CMD:-}" ]]; then
|
|
45
|
+
export BD_CMD
|
|
46
|
+
fi
|
|
47
|
+
|
|
48
|
+
if [[ -z "${JQ_CMD:-}" ]]; then
|
|
49
|
+
JQ_CMD="$(_forge_resolve_tool jq || true)"
|
|
50
|
+
fi
|
|
51
|
+
if [[ -n "${JQ_CMD:-}" ]]; then
|
|
52
|
+
export JQ_CMD
|
|
53
|
+
fi
|
|
54
|
+
|
|
55
|
+
if [[ -z "${GH_CMD:-}" ]]; then
|
|
56
|
+
GH_CMD="$(_forge_resolve_tool gh || true)"
|
|
57
|
+
fi
|
|
58
|
+
if [[ -n "${GH_CMD:-}" ]]; then
|
|
59
|
+
export GH_CMD
|
|
60
|
+
fi
|
|
61
|
+
|
|
62
|
+
if [[ -n "${BD_CMD:-}" ]]; then
|
|
63
|
+
bd() {
|
|
64
|
+
command "$BD_CMD" "$@"
|
|
65
|
+
}
|
|
66
|
+
fi
|
|
67
|
+
|
|
68
|
+
if [[ -n "${JQ_CMD:-}" ]]; then
|
|
69
|
+
jq() {
|
|
70
|
+
command "$JQ_CMD" "$@"
|
|
71
|
+
}
|
|
72
|
+
fi
|
|
73
|
+
|
|
74
|
+
if [[ -n "${GH_CMD:-}" ]]; then
|
|
75
|
+
gh() {
|
|
76
|
+
command "$GH_CMD" "$@"
|
|
77
|
+
}
|
|
78
|
+
fi
|
|
@@ -131,7 +131,7 @@ function main() {
|
|
|
131
131
|
const currentBranch = getCurrentBranch();
|
|
132
132
|
|
|
133
133
|
if (isProtectedBranch(currentBranch)) {
|
|
134
|
-
//
|
|
134
|
+
// Beads runtime metadata is local state. Do not bypass protected branches for it.
|
|
135
135
|
try {
|
|
136
136
|
let upstream;
|
|
137
137
|
try {
|
|
@@ -150,8 +150,7 @@ function main() {
|
|
|
150
150
|
if (changedFiles.length === 0) {
|
|
151
151
|
console.error(`${YELLOW}Note: no changed files detected — nothing to bypass${RESET}`);
|
|
152
152
|
} else if (changedFiles.every(f => f.startsWith('.beads/'))) {
|
|
153
|
-
console.error(`${YELLOW}Beads
|
|
154
|
-
process.exit(0);
|
|
153
|
+
console.error(`${YELLOW}Beads metadata is local runtime state; protected branches do not accept .beads-only pushes.${RESET}`);
|
|
155
154
|
}
|
|
156
155
|
} catch (_e) {
|
|
157
156
|
console.error(`${YELLOW}Note: could not detect beads-only push (upstream ref missing?) — blocking by default${RESET}`);
|
package/scripts/check-agents.js
CHANGED
|
@@ -5,11 +5,12 @@
|
|
|
5
5
|
*
|
|
6
6
|
* CLI command that validates all agent configs are complete and in sync.
|
|
7
7
|
*
|
|
8
|
-
* 1. Runs
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
8
|
+
* 1. Runs the skills drift check (lib/skills-sync) to verify generated agent
|
|
9
|
+
* skill mirrors (e.g. .codex/skills) match the canonical root skills/ source.
|
|
10
|
+
* 2. Reads lib/agents/*.plugin.json to validate each plugin's schema/parity
|
|
11
|
+
* (support metadata, rules/skills scaffold paths, deprecated-tier consistency).
|
|
12
|
+
* 3. Reports: skill drift, missing/stale skills, plugin parity errors.
|
|
13
|
+
* 4. Exits 0 if all clean, exits non-zero if issues found.
|
|
13
14
|
*
|
|
14
15
|
* Usage:
|
|
15
16
|
* node scripts/check-agents.js
|
|
@@ -18,51 +19,22 @@
|
|
|
18
19
|
* checkAgents(repoRoot) -> { errors: string[], warnings: string[] }
|
|
19
20
|
*/
|
|
20
21
|
|
|
21
|
-
const { syncCommands } = require('./sync-commands');
|
|
22
|
-
const { AGENT_ADAPTERS } = require('./sync-commands');
|
|
23
22
|
const path = require('path');
|
|
24
23
|
const fs = require('fs');
|
|
24
|
+
const { checkSkillsSync } = require('../lib/skills-sync');
|
|
25
25
|
const { validatePluginSchema } = require('../lib/plugin-manager');
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
function normalizeRelativeDir(dir) {
|
|
39
|
-
if (!dir) return null;
|
|
40
|
-
return String(dir).replace(/\\/g, '/').replace(/\/+$/, '');
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
function getDeclaredCommandDir(plugin) {
|
|
44
|
-
const dirs = plugin.directories || {};
|
|
45
|
-
return dirs.commands || dirs.workflows || dirs.prompts || dirs.skills || null;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
function getExpectedCommandDir(plugin) {
|
|
49
|
-
const adapterId = SYNC_ADAPTER_BY_PLUGIN_ID[plugin.id];
|
|
50
|
-
if (!adapterId) {
|
|
51
|
-
return null;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const adapter = AGENT_ADAPTERS[adapterId];
|
|
55
|
-
if (!adapter) {
|
|
56
|
-
return null;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
if (plugin.id === 'codex') {
|
|
60
|
-
return normalizeRelativeDir(plugin.directories?.skills || adapter.baseDir);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
return normalizeRelativeDir(adapter.baseDir);
|
|
64
|
-
}
|
|
65
|
-
|
|
27
|
+
/**
|
|
28
|
+
* Validate a single plugin's schema + capability/scaffold parity.
|
|
29
|
+
*
|
|
30
|
+
* Command-surface parity is intentionally NOT validated: Forge is skills-only
|
|
31
|
+
* (the .claude/commands/.cursor/commands/.codex/skills command surface was
|
|
32
|
+
* removed in PR-A0). The surviving checks cover support metadata, the rules and
|
|
33
|
+
* skills scaffold paths, and deprecated-tier consistency.
|
|
34
|
+
*
|
|
35
|
+
* @param {object} plugin
|
|
36
|
+
* @param {string[]} errors - mutated with any parity errors
|
|
37
|
+
*/
|
|
66
38
|
function validatePluginParity(plugin, errors) {
|
|
67
39
|
const validation = validatePluginSchema(plugin);
|
|
68
40
|
if (!validation.valid) {
|
|
@@ -78,25 +50,6 @@ function validatePluginParity(plugin, errors) {
|
|
|
78
50
|
const dirs = plugin.directories || {};
|
|
79
51
|
const supportStatus = plugin.support?.status;
|
|
80
52
|
|
|
81
|
-
if (capabilities.commands) {
|
|
82
|
-
const expectedDir = getExpectedCommandDir(plugin);
|
|
83
|
-
const declaredDir = normalizeRelativeDir(getDeclaredCommandDir(plugin));
|
|
84
|
-
|
|
85
|
-
if (!expectedDir) {
|
|
86
|
-
errors.push(
|
|
87
|
-
`Plugin "${plugin.name}" (${plugin.id}) declares commands support but has no Forge sync adapter.`
|
|
88
|
-
);
|
|
89
|
-
} else if (!declaredDir) {
|
|
90
|
-
errors.push(
|
|
91
|
-
`Plugin "${plugin.name}" (${plugin.id}) declares commands support but has no command directory configured.`
|
|
92
|
-
);
|
|
93
|
-
} else if (declaredDir !== expectedDir) {
|
|
94
|
-
errors.push(
|
|
95
|
-
`Plugin "${plugin.name}" (${plugin.id}) command directory "${declaredDir}" does not match sync output "${expectedDir}".`
|
|
96
|
-
);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
53
|
if (capabilities.rules && !dirs.rules) {
|
|
101
54
|
errors.push(
|
|
102
55
|
`Plugin "${plugin.name}" (${plugin.id}) declares rules capability but has no scaffold path configured.`
|
|
@@ -136,47 +89,34 @@ function checkAgents(repoRoot) {
|
|
|
136
89
|
/** @type {string[]} */
|
|
137
90
|
const warnings = [];
|
|
138
91
|
|
|
139
|
-
// ---- 1.
|
|
140
|
-
let
|
|
92
|
+
// ---- 1. Skills drift check ----
|
|
93
|
+
let driftResult;
|
|
141
94
|
try {
|
|
142
|
-
|
|
95
|
+
driftResult = checkSkillsSync({ repoRoot });
|
|
143
96
|
} catch (err) {
|
|
144
|
-
errors.push(`
|
|
97
|
+
errors.push(`Skills sync check failed: ${err.message}`);
|
|
145
98
|
return { errors, warnings };
|
|
146
99
|
}
|
|
147
100
|
|
|
148
|
-
|
|
149
|
-
|
|
101
|
+
const canonicalSkillsDir = path.join(repoRoot, 'skills');
|
|
102
|
+
if (!fs.existsSync(canonicalSkillsDir)) {
|
|
103
|
+
errors.push('No canonical skills found in skills/ — cannot verify skill sync.');
|
|
150
104
|
return { errors, warnings };
|
|
151
|
-
}
|
|
152
|
-
if (syncResult.manifestMissing) {
|
|
153
|
-
warnings.push(
|
|
154
|
-
'Sync manifest (.forge/sync-manifest.json) not found — stale file detection skipped. ' +
|
|
155
|
-
'Run "node scripts/sync-commands.js" to generate it.'
|
|
156
|
-
);
|
|
157
|
-
}
|
|
105
|
+
}
|
|
158
106
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
}
|
|
166
|
-
}
|
|
107
|
+
if (driftResult.checkedAgents.length === 0) {
|
|
108
|
+
warnings.push(
|
|
109
|
+
'No generated agent skill directories found (e.g. .codex/skills) — skill drift check skipped. ' +
|
|
110
|
+
'Run "forge setup" or "skills sync" to populate them.'
|
|
111
|
+
);
|
|
112
|
+
}
|
|
167
113
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
const relPath = path.relative(repoRoot, filePath);
|
|
171
|
-
errors.push(`Stale file (no longer generated, should be removed): ${relPath}`);
|
|
172
|
-
}
|
|
173
|
-
}
|
|
114
|
+
for (const d of driftResult.drift) {
|
|
115
|
+
errors.push(`Out of sync [${d.agent}]: ${d.skill}/${d.file} (${d.status})`);
|
|
174
116
|
}
|
|
175
117
|
|
|
176
118
|
// ---- 2. Validate plugin catalog ----
|
|
177
119
|
const pluginDir = path.join(repoRoot, 'lib', 'agents');
|
|
178
|
-
/** @type {object[]} */
|
|
179
|
-
const plugins = [];
|
|
180
120
|
|
|
181
121
|
if (!fs.existsSync(pluginDir)) {
|
|
182
122
|
warnings.push('No plugin directory found at lib/agents/ — plugin catalog validation skipped.');
|
|
@@ -190,54 +130,11 @@ function checkAgents(repoRoot) {
|
|
|
190
130
|
for (const file of pluginFiles) {
|
|
191
131
|
try {
|
|
192
132
|
const plugin = JSON.parse(fs.readFileSync(path.join(pluginDir, file), 'utf8'));
|
|
193
|
-
plugins.push(plugin);
|
|
194
133
|
validatePluginParity(plugin, errors);
|
|
195
134
|
} catch (_err) {
|
|
196
135
|
errors.push(`Failed to parse plugin file: lib/agents/${file}`);
|
|
197
136
|
}
|
|
198
137
|
}
|
|
199
|
-
|
|
200
|
-
// For each plugin with commands: true, verify its command directory has files
|
|
201
|
-
for (const plugin of plugins) {
|
|
202
|
-
if (!plugin.capabilities || !plugin.capabilities.commands) {
|
|
203
|
-
continue;
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
// Find the command directory from the plugin's directories config
|
|
207
|
-
const dirs = plugin.directories || {};
|
|
208
|
-
// Plugins use different keys: commands, workflows, prompts, skills
|
|
209
|
-
const commandDir = dirs.commands || dirs.workflows || dirs.prompts;
|
|
210
|
-
|
|
211
|
-
if (!commandDir) {
|
|
212
|
-
// Plugin declares commands: true but has no command directory configured
|
|
213
|
-
// Codex is the only agent that uses skills as its command mechanism
|
|
214
|
-
if (plugin.id === 'codex' && dirs.skills) {
|
|
215
|
-
// Codex CLI: commands live in .codex/skills/<name>/SKILL.md — skip standard check
|
|
216
|
-
continue;
|
|
217
|
-
}
|
|
218
|
-
warnings.push(
|
|
219
|
-
`Plugin "${plugin.name}" (${plugin.id}) has commands: true but no command directory configured.`
|
|
220
|
-
);
|
|
221
|
-
continue;
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
const absCmdDir = path.join(repoRoot, commandDir);
|
|
225
|
-
|
|
226
|
-
if (!fs.existsSync(absCmdDir)) {
|
|
227
|
-
errors.push(
|
|
228
|
-
`Plugin "${plugin.name}" (${plugin.id}) has commands: true but directory "${commandDir}" does not exist.`
|
|
229
|
-
);
|
|
230
|
-
continue;
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
// Check the directory has at least one file
|
|
234
|
-
const files = fs.readdirSync(absCmdDir).filter((f) => !f.startsWith('.'));
|
|
235
|
-
if (files.length === 0) {
|
|
236
|
-
errors.push(
|
|
237
|
-
`Plugin "${plugin.name}" (${plugin.id}) has commands: true but directory "${commandDir}" is empty.`
|
|
238
|
-
);
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
138
|
}
|
|
242
139
|
|
|
243
140
|
return { errors, warnings };
|
package/scripts/commitlint.js
CHANGED
|
@@ -12,7 +12,9 @@ const isWindows = process.platform === 'win32';
|
|
|
12
12
|
|
|
13
13
|
const commitMsgFile = process.argv[2];
|
|
14
14
|
if (!commitMsgFile) {
|
|
15
|
-
|
|
15
|
+
// Write synchronously so the message is flushed before exit: on Windows the
|
|
16
|
+
// stderr pipe is async and process.exit() can otherwise truncate it.
|
|
17
|
+
require('node:fs').writeSync(2, '❌ No commit message file provided\n');
|
|
16
18
|
process.exit(1);
|
|
17
19
|
}
|
|
18
20
|
|
|
@@ -17,6 +17,9 @@
|
|
|
17
17
|
set -euo pipefail
|
|
18
18
|
|
|
19
19
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
20
|
+
if [[ -f "$SCRIPT_DIR/bootstrap-windows-tools.sh" ]]; then
|
|
21
|
+
source "$SCRIPT_DIR/bootstrap-windows-tools.sh"
|
|
22
|
+
fi
|
|
20
23
|
|
|
21
24
|
# Source file-index helpers (file_index_read, file_index_get)
|
|
22
25
|
source "$SCRIPT_DIR/file-index.sh" || { echo "FATAL: failed to source file-index.sh" >&2; exit 2; }
|
|
@@ -32,26 +32,61 @@ function normalizeSingleIssuePayload(payload) {
|
|
|
32
32
|
return {};
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
+
function readStdinPayload() {
|
|
36
|
+
const raw = fs.readFileSync(0, 'utf8');
|
|
37
|
+
if (!raw.trim()) {
|
|
38
|
+
throw new Error('Expected JSON payload on stdin');
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const payload = JSON.parse(raw);
|
|
42
|
+
return {
|
|
43
|
+
currentIssue: normalizeSingleIssuePayload(payload.currentIssue),
|
|
44
|
+
openIssues: normalizeListPayload(payload.openIssues),
|
|
45
|
+
inProgressIssues: normalizeListPayload(payload.inProgressIssues),
|
|
46
|
+
taskFile: payload.taskFile,
|
|
47
|
+
repositoryRoot: payload.repositoryRoot || process.cwd(),
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
35
51
|
function main() {
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
repositoryRoot = process.cwd(),
|
|
42
|
-
] = process.argv.slice(2);
|
|
52
|
+
const args = process.argv.slice(2);
|
|
53
|
+
let currentIssue;
|
|
54
|
+
let openIssues;
|
|
55
|
+
let taskFile;
|
|
56
|
+
let repositoryRoot;
|
|
43
57
|
|
|
44
|
-
if (
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
58
|
+
if (args[0] === '--stdin') {
|
|
59
|
+
const payload = readStdinPayload();
|
|
60
|
+
currentIssue = payload.currentIssue;
|
|
61
|
+
openIssues = [
|
|
62
|
+
...payload.openIssues,
|
|
63
|
+
...payload.inProgressIssues,
|
|
64
|
+
].filter((issue) => issue && issue.id && issue.id !== currentIssue.id);
|
|
65
|
+
taskFile = payload.taskFile;
|
|
66
|
+
repositoryRoot = payload.repositoryRoot;
|
|
67
|
+
} else {
|
|
68
|
+
const [
|
|
69
|
+
currentIssueFile,
|
|
70
|
+
openIssuesFile,
|
|
71
|
+
inProgressIssuesFile,
|
|
72
|
+
taskFileArg,
|
|
73
|
+
repositoryRootArg = process.cwd(),
|
|
74
|
+
] = args;
|
|
49
75
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
76
|
+
if (!currentIssueFile || !openIssuesFile || !inProgressIssuesFile || !taskFileArg) {
|
|
77
|
+
throw new Error(
|
|
78
|
+
'Usage: dep-guard-analyze.js <current-issue.json> <open-issues.json> <in-progress-issues.json> <task-file> [repository-root]',
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
currentIssue = normalizeSingleIssuePayload(readJsonFile(currentIssueFile));
|
|
83
|
+
openIssues = [
|
|
84
|
+
...normalizeListPayload(readJsonFile(openIssuesFile)),
|
|
85
|
+
...normalizeListPayload(readJsonFile(inProgressIssuesFile)),
|
|
86
|
+
].filter((issue) => issue && issue.id && issue.id !== currentIssue.id);
|
|
87
|
+
taskFile = taskFileArg;
|
|
88
|
+
repositoryRoot = repositoryRootArg;
|
|
89
|
+
}
|
|
55
90
|
|
|
56
91
|
const result = analyzePhase3Dependencies({
|
|
57
92
|
currentIssue,
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
const {
|
|
5
|
+
parseActiveIssueLines,
|
|
6
|
+
renderKeywordRippleReport,
|
|
7
|
+
} = require('../lib/dep-guard/keyword-ripple.js');
|
|
8
|
+
|
|
9
|
+
function main() {
|
|
10
|
+
try {
|
|
11
|
+
const report = renderKeywordRippleReport({
|
|
12
|
+
issueId: process.env.ISSUE_ID || '',
|
|
13
|
+
sourceTitle: process.env.SOURCE_TITLE || '',
|
|
14
|
+
activeIssues: parseActiveIssueLines(process.env.LIST_OUTPUT || ''),
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
if (report.overlapCount > 0) {
|
|
18
|
+
process.stdout.write(`⚠️ ${report.output}\n`);
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
process.stdout.write(`✅ ${report.output}\n`);
|
|
23
|
+
} catch (error) {
|
|
24
|
+
console.error(`dep-guard-keyword-ripple: ${error.message}`);
|
|
25
|
+
process.exit(1);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
main();
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
const fs = require('node:fs');
|
|
5
|
+
|
|
6
|
+
function readAnalysis() {
|
|
7
|
+
const raw = fs.readFileSync(0, 'utf8');
|
|
8
|
+
if (!raw.trim()) {
|
|
9
|
+
throw new Error('Expected JSON analysis payload on stdin');
|
|
10
|
+
}
|
|
11
|
+
return JSON.parse(raw);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function renderPhase3Review(analysis) {
|
|
15
|
+
const detectorCategories = Object.entries(analysis.scores ?? {})
|
|
16
|
+
.filter(([name, score]) => name !== 'rubric' && Number(score) > 0)
|
|
17
|
+
.map(([name]) => name);
|
|
18
|
+
|
|
19
|
+
const lines = [
|
|
20
|
+
'',
|
|
21
|
+
`Structured dependency review for ${analysis.currentIssue.id}...`,
|
|
22
|
+
'',
|
|
23
|
+
];
|
|
24
|
+
|
|
25
|
+
if (!Array.isArray(analysis.issues) || analysis.issues.length === 0) {
|
|
26
|
+
lines.push('No conflicts detected');
|
|
27
|
+
return `${lines.join('\n')}\n`;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const seenPairs = new Set();
|
|
31
|
+
for (const finding of analysis.issues) {
|
|
32
|
+
const key = `${analysis.currentIssue.id}->${finding.targetIssueId}`;
|
|
33
|
+
if (seenPairs.has(key)) {
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
seenPairs.add(key);
|
|
37
|
+
lines.push(`Issue pair: ${analysis.currentIssue.id} -> ${finding.targetIssueId}`);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
lines.push(`Rubric score: ${analysis.scores?.rubric ?? 0}`);
|
|
41
|
+
lines.push(
|
|
42
|
+
`Confidence: ${(analysis.confidence?.score ?? 0).toFixed(2)}${
|
|
43
|
+
analysis.confidence?.belowThreshold ? ' (below 70% threshold)' : ''
|
|
44
|
+
}`,
|
|
45
|
+
);
|
|
46
|
+
lines.push(`Detector categories: ${detectorCategories.join(', ') || 'none'}`);
|
|
47
|
+
lines.push(`Needs user decision: ${analysis.needsUserDecision ? 'yes' : 'no'}`);
|
|
48
|
+
|
|
49
|
+
if (Array.isArray(analysis.detectorConflicts) && analysis.detectorConflicts.length > 0) {
|
|
50
|
+
lines.push('Conflicts:');
|
|
51
|
+
for (const conflict of analysis.detectorConflicts) {
|
|
52
|
+
lines.push(` - ${conflict}`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (Array.isArray(analysis.proposals) && analysis.proposals.length > 0) {
|
|
57
|
+
lines.push('');
|
|
58
|
+
lines.push('Proposed dependency updates:');
|
|
59
|
+
for (const proposal of analysis.proposals) {
|
|
60
|
+
lines.push(` - ${proposal.dependentIssueId} depends on ${proposal.dependsOnIssueId}`);
|
|
61
|
+
if (Array.isArray(proposal.pros) && proposal.pros.length > 0) {
|
|
62
|
+
lines.push(` Pros: ${proposal.pros.join('; ')}`);
|
|
63
|
+
}
|
|
64
|
+
if (Array.isArray(proposal.cons) && proposal.cons.length > 0) {
|
|
65
|
+
lines.push(` Cons: ${proposal.cons.join('; ')}`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return `${lines.join('\n')}\n`;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function main() {
|
|
74
|
+
process.stdout.write(renderPhase3Review(readAnalysis()));
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
try {
|
|
78
|
+
main();
|
|
79
|
+
} catch (error) {
|
|
80
|
+
process.stderr.write(`${error.message}\n`);
|
|
81
|
+
process.exit(1);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
module.exports = {
|
|
85
|
+
renderPhase3Review,
|
|
86
|
+
};
|