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/lib/runtime-health.js
CHANGED
|
@@ -8,9 +8,12 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
const fs = require('node:fs');
|
|
11
|
+
const path = require('node:path');
|
|
11
12
|
const { execFileSync: defaultExecFileSync } = require('node:child_process');
|
|
12
13
|
|
|
13
14
|
const { checkLefthookStatus } = require('./lefthook-check');
|
|
15
|
+
const { resolveIssueBackend } = require('./issue-backend');
|
|
16
|
+
const { getInstallCommand, getAddDevCommand } = require('./package-manager-remediation');
|
|
14
17
|
|
|
15
18
|
const WINDOWS_GIT_BASH_CANDIDATES = [
|
|
16
19
|
String.raw`C:\Program Files\Git\bin\bash.exe`,
|
|
@@ -42,11 +45,149 @@ function normalizeHooksPath(value, platform = process.platform) {
|
|
|
42
45
|
return normalized;
|
|
43
46
|
}
|
|
44
47
|
|
|
45
|
-
function
|
|
48
|
+
function isAbsoluteForPlatform(value, platform = process.platform) {
|
|
49
|
+
const raw = toText(value).trim();
|
|
50
|
+
return platform === 'win32' ? path.win32.isAbsolute(raw) : path.posix.isAbsolute(raw);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function resolvesToExecutableHookCommand(line, matcher) {
|
|
54
|
+
const trimmed = line.trim();
|
|
55
|
+
if (!trimmed || trimmed.startsWith('#')) return false;
|
|
56
|
+
const firstCommand = commandName(commandTokens(trimmed)[0]);
|
|
57
|
+
if (firstCommand === 'echo' || firstCommand === 'printf') {
|
|
58
|
+
const chainIndex = trimmed.indexOf('&&');
|
|
59
|
+
return chainIndex === -1 ? false : matcher(trimmed.slice(chainIndex + 2).trim());
|
|
60
|
+
}
|
|
61
|
+
return matcher(trimmed);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function hasExecutableHookCommand(content, matcher) {
|
|
65
|
+
let heredocEnd = null;
|
|
66
|
+
|
|
67
|
+
for (const line of toText(content).split(/\r?\n/)) {
|
|
68
|
+
const trimmed = line.trim();
|
|
69
|
+
if (heredocEnd) {
|
|
70
|
+
if (trimmed === heredocEnd) heredocEnd = null;
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (resolvesToExecutableHookCommand(line, matcher)) return true;
|
|
75
|
+
|
|
76
|
+
const delimiter = heredocDelimiter(line);
|
|
77
|
+
if (delimiter) heredocEnd = delimiter;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function commandTokens(line) {
|
|
84
|
+
return line
|
|
85
|
+
.replace(/[;"'()]/g, ' ')
|
|
86
|
+
.split(/\s+/)
|
|
87
|
+
.filter(Boolean);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function commandName(token) {
|
|
91
|
+
return toText(token)
|
|
92
|
+
.replaceAll('\\', '/')
|
|
93
|
+
.split('/')
|
|
94
|
+
.pop()
|
|
95
|
+
.toLowerCase()
|
|
96
|
+
.replace(/\.(?:exe|cmd)$/, '');
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function isWhitespace(char) {
|
|
100
|
+
return char === ' ' || char === '\t' || char === '\r' || char === '\n';
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function isVariableNameStart(char) {
|
|
104
|
+
return (char >= 'A' && char <= 'Z') || (char >= 'a' && char <= 'z') || char === '_';
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function isVariableNameChar(char) {
|
|
108
|
+
return isVariableNameStart(char) || (char >= '0' && char <= '9');
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function isAssignmentToken(token) {
|
|
112
|
+
const text = toText(token);
|
|
113
|
+
const equalsIndex = text.indexOf('=');
|
|
114
|
+
if (equalsIndex <= 0 || !isVariableNameStart(text[0])) return false;
|
|
115
|
+
|
|
116
|
+
for (let index = 1; index < equalsIndex; index += 1) {
|
|
117
|
+
if (!isVariableNameChar(text[index])) return false;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return true;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function heredocDelimiter(line) {
|
|
124
|
+
const markerIndex = line.indexOf('<<');
|
|
125
|
+
if (markerIndex === -1 || line[markerIndex + 2] === '<') return null;
|
|
126
|
+
|
|
127
|
+
let cursor = markerIndex + 2;
|
|
128
|
+
if (line[cursor] === '-') cursor += 1;
|
|
129
|
+
while (cursor < line.length && isWhitespace(line[cursor])) cursor += 1;
|
|
130
|
+
|
|
131
|
+
const quote = line[cursor];
|
|
132
|
+
if (quote === '"' || quote === "'") {
|
|
133
|
+
cursor += 1;
|
|
134
|
+
const endQuote = line.indexOf(quote, cursor);
|
|
135
|
+
return endQuote === -1 ? line.slice(cursor).trim() || null : line.slice(cursor, endQuote) || null;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const start = cursor;
|
|
139
|
+
while (cursor < line.length && !isWhitespace(line[cursor])) cursor += 1;
|
|
140
|
+
return line.slice(start, cursor).trim() || null;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function isExecutingTokenPosition(tokens, index) {
|
|
144
|
+
const nonExecutingPreviousTokens = new Set(['-e', '-f', '-r', '-x', '[', 'test']);
|
|
145
|
+
const executingPreviousCommands = new Set(['bash', 'bun', 'env', 'exec', 'if', 'node', 'sh', 'then', '&&']);
|
|
146
|
+
|
|
147
|
+
let previousIndex = index - 1;
|
|
148
|
+
while (previousIndex >= 0 && isAssignmentToken(tokens[previousIndex])) {
|
|
149
|
+
previousIndex -= 1;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
if (previousIndex < 0) return true;
|
|
153
|
+
|
|
154
|
+
const previous = toText(tokens[previousIndex]).toLowerCase();
|
|
155
|
+
if (nonExecutingPreviousTokens.has(previous)) return false;
|
|
156
|
+
return executingPreviousCommands.has(commandName(previous));
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function invokesLefthook(line) {
|
|
160
|
+
return commandTokens(line).some((token) => commandName(token) === 'lefthook');
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
function invokesForgeHook(line) {
|
|
164
|
+
return commandTokens(line).some((token, index, tokens) => {
|
|
165
|
+
if (token.includes('=')) return false;
|
|
166
|
+
const normalized = token.replaceAll('\\', '/').toLowerCase();
|
|
167
|
+
if (!normalized.endsWith('.forge/hooks/check-tdd.js') && commandName(token) !== 'check-tdd.js') {
|
|
168
|
+
return false;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
return isExecutingTokenPosition(tokens, index);
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
function invokesBeadsHook(line, hookName) {
|
|
176
|
+
const tokens = commandTokens(line);
|
|
177
|
+
return tokens.some((token, index) => (
|
|
178
|
+
commandName(token) === 'bd'
|
|
179
|
+
&& toText(tokens[index + 1]).toLowerCase() === 'hooks'
|
|
180
|
+
&& toText(tokens[index + 2]).toLowerCase() === 'run'
|
|
181
|
+
&& toText(tokens[index + 3]).toLowerCase() === hookName
|
|
182
|
+
&& isExecutingTokenPosition(tokens, index)
|
|
183
|
+
));
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
function createDiagnostic(code, subject, message, repair, severity = 'hard-stop') {
|
|
46
187
|
return {
|
|
47
188
|
code,
|
|
48
189
|
subject,
|
|
49
|
-
severity
|
|
190
|
+
severity,
|
|
50
191
|
message,
|
|
51
192
|
...(repair ? { repair } : {})
|
|
52
193
|
};
|
|
@@ -75,32 +216,159 @@ function isUsableWindowsShellCandidate(candidate, options = {}) {
|
|
|
75
216
|
function checkHookInstallation(projectRoot, options = {}) {
|
|
76
217
|
const exec = options._exec || defaultExecFileSync;
|
|
77
218
|
const platform = options.platform || process.platform;
|
|
78
|
-
const
|
|
79
|
-
const
|
|
219
|
+
const expectedRelativeHooksPaths = ['.lefthook/hooks', '.beads/hooks'];
|
|
220
|
+
const requiredHooks = ['pre-commit', 'pre-push'];
|
|
221
|
+
|
|
222
|
+
function resolveGitRoot() {
|
|
223
|
+
try {
|
|
224
|
+
const output = exec('git', ['rev-parse', '--show-toplevel'], {
|
|
225
|
+
cwd: projectRoot,
|
|
226
|
+
encoding: 'utf8'
|
|
227
|
+
});
|
|
228
|
+
return toText(output).trim() || projectRoot;
|
|
229
|
+
} catch {
|
|
230
|
+
return projectRoot;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
const gitRoot = resolveGitRoot();
|
|
235
|
+
const expectedHooksPaths = new Set(expectedRelativeHooksPaths.flatMap((hooksPath) => [
|
|
236
|
+
normalizeHooksPath(hooksPath, platform),
|
|
237
|
+
normalizeHooksPath(`${gitRoot}/${normalizeHooksPath(hooksPath, platform)}`, platform)
|
|
238
|
+
]));
|
|
80
239
|
|
|
240
|
+
function resolveGitHooksDir() {
|
|
241
|
+
try {
|
|
242
|
+
const output = exec('git', ['rev-parse', '--git-path', 'hooks'], {
|
|
243
|
+
cwd: projectRoot,
|
|
244
|
+
encoding: 'utf8'
|
|
245
|
+
});
|
|
246
|
+
const rawPath = toText(output).trim();
|
|
247
|
+
if (!rawPath) return null;
|
|
248
|
+
return path.isAbsolute(rawPath) ? rawPath : path.resolve(projectRoot, rawPath);
|
|
249
|
+
} catch {
|
|
250
|
+
return null;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
function classifyHookFile(filePath, hookName, visited = new Set()) {
|
|
255
|
+
try {
|
|
256
|
+
const normalizedFilePath = path.resolve(filePath);
|
|
257
|
+
if (visited.has(normalizedFilePath)) {
|
|
258
|
+
return { active: false, provider: 'cycle' };
|
|
259
|
+
}
|
|
260
|
+
visited.add(normalizedFilePath);
|
|
261
|
+
|
|
262
|
+
const stat = fs.statSync(filePath);
|
|
263
|
+
const executable = platform === 'win32'
|
|
264
|
+
|| (typeof options._canExecuteHook === 'function'
|
|
265
|
+
? Boolean(options._canExecuteHook(filePath, stat))
|
|
266
|
+
: (stat.mode & 0o111) !== 0);
|
|
267
|
+
if (!stat.isFile() || stat.size === 0 || !executable) return { active: false, provider: 'missing' };
|
|
268
|
+
|
|
269
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
270
|
+
const runsLefthook = hasExecutableHookCommand(content, invokesLefthook);
|
|
271
|
+
const runsForgeHook = hasExecutableHookCommand(content, invokesForgeHook);
|
|
272
|
+
const runsBeadsHook = hasExecutableHookCommand(content, (line) => invokesBeadsHook(line, hookName));
|
|
273
|
+
|
|
274
|
+
if (runsLefthook) return { active: true, provider: 'lefthook' };
|
|
275
|
+
if (runsForgeHook) return { active: true, provider: 'forge' };
|
|
276
|
+
|
|
277
|
+
if (runsBeadsHook) {
|
|
278
|
+
const chainedHookPath = path.join(gitRoot, '.beads', 'hooks', hookName);
|
|
279
|
+
if (path.resolve(chainedHookPath) !== normalizedFilePath && fs.existsSync(chainedHookPath)) {
|
|
280
|
+
const chained = classifyHookFile(chainedHookPath, hookName, visited);
|
|
281
|
+
if (chained.active) {
|
|
282
|
+
return { active: true, provider: `beads->${chained.provider}` };
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
return { active: false, provider: 'beads-unverified' };
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
return { active: false, provider: 'unknown' };
|
|
290
|
+
} catch {
|
|
291
|
+
return { active: false, provider: 'missing' };
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
let hooksPath = null;
|
|
81
296
|
try {
|
|
82
297
|
const output = exec('git', ['config', '--get', 'core.hooksPath'], {
|
|
83
298
|
cwd: projectRoot,
|
|
84
299
|
encoding: 'utf8'
|
|
85
300
|
});
|
|
86
301
|
|
|
87
|
-
|
|
88
|
-
const active = hooksPath
|
|
302
|
+
hooksPath = normalizeHooksPath(output, platform);
|
|
303
|
+
const active = expectedHooksPaths.has(hooksPath);
|
|
304
|
+
|
|
305
|
+
if (active) {
|
|
306
|
+
const rawHooksPath = toText(output).trim();
|
|
307
|
+
const hooksDir = isAbsoluteForPlatform(rawHooksPath, platform)
|
|
308
|
+
? rawHooksPath
|
|
309
|
+
: path.resolve(gitRoot, normalizeHooksPath(rawHooksPath, platform));
|
|
310
|
+
const hookChecks = requiredHooks.map((hook) => ({
|
|
311
|
+
hook,
|
|
312
|
+
...classifyHookFile(path.join(hooksDir, hook), hook)
|
|
313
|
+
}));
|
|
314
|
+
const missingHooks = hookChecks.filter(check => !check.active).map(check => check.hook);
|
|
315
|
+
const verifiedActive = missingHooks.length === 0;
|
|
316
|
+
return {
|
|
317
|
+
active: verifiedActive,
|
|
318
|
+
state: verifiedActive ? 'active' : 'inactive',
|
|
319
|
+
verification: 'core.hooksPath',
|
|
320
|
+
hooksPath: hooksPath || null,
|
|
321
|
+
hooksDir,
|
|
322
|
+
providers: Object.fromEntries(hookChecks.map(check => [check.hook, check.provider])),
|
|
323
|
+
missingHooks,
|
|
324
|
+
message: verifiedActive
|
|
325
|
+
? ''
|
|
326
|
+
: `Git hooks directory is missing required hooks: ${missingHooks.join(', ')}.`
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
if (hooksPath) {
|
|
331
|
+
return {
|
|
332
|
+
active: false,
|
|
333
|
+
state: 'inactive',
|
|
334
|
+
verification: 'core.hooksPath',
|
|
335
|
+
hooksPath,
|
|
336
|
+
message: `Git core.hooksPath is set to "${hooksPath}", not ".lefthook/hooks" or ".beads/hooks".`
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
} catch {
|
|
340
|
+
// Fall through to git-path fallback for worktree-safe verification
|
|
341
|
+
}
|
|
89
342
|
|
|
343
|
+
const hooksDir = resolveGitHooksDir();
|
|
344
|
+
if (hooksDir) {
|
|
345
|
+
const hookChecks = requiredHooks.map((hook) => ({
|
|
346
|
+
hook,
|
|
347
|
+
...classifyHookFile(path.join(hooksDir, hook), hook)
|
|
348
|
+
}));
|
|
349
|
+
const missingHooks = hookChecks.filter(check => !check.active).map(check => check.hook);
|
|
350
|
+
const active = missingHooks.length === 0;
|
|
90
351
|
return {
|
|
91
352
|
active,
|
|
92
353
|
state: active ? 'active' : 'inactive',
|
|
354
|
+
verification: 'git-path-hooks',
|
|
93
355
|
hooksPath: hooksPath || null,
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
hooksPath: null,
|
|
101
|
-
message: 'Git hooks could not be verified.'
|
|
356
|
+
hooksDir,
|
|
357
|
+
providers: Object.fromEntries(hookChecks.map(check => [check.hook, check.provider])),
|
|
358
|
+
missingHooks,
|
|
359
|
+
message: active
|
|
360
|
+
? ''
|
|
361
|
+
: `Git hooks directory is missing required hooks: ${missingHooks.join(', ')}.`
|
|
102
362
|
};
|
|
103
363
|
}
|
|
364
|
+
|
|
365
|
+
return {
|
|
366
|
+
active: false,
|
|
367
|
+
state: 'unverified',
|
|
368
|
+
verification: 'unverified',
|
|
369
|
+
hooksPath: hooksPath || null,
|
|
370
|
+
message: 'Git hooks could not be verified.'
|
|
371
|
+
};
|
|
104
372
|
}
|
|
105
373
|
|
|
106
374
|
function checkCommandAvailability(command, projectRoot, options = {}) {
|
|
@@ -215,25 +483,50 @@ function normalizeProjectRoot(projectRoot) {
|
|
|
215
483
|
: process.cwd();
|
|
216
484
|
}
|
|
217
485
|
|
|
486
|
+
// Resolve the active issue backend for the health gate. An already-normalized
|
|
487
|
+
// `options.issueBackend` (passed by enforce-stage) wins; otherwise fall back to the
|
|
488
|
+
// shared resolver (env > .forge/config.yaml > default 'kernel'). Never throws and
|
|
489
|
+
// never warns from the health path.
|
|
490
|
+
function resolveHealthIssueBackend(options, projectRoot) {
|
|
491
|
+
if (options.issueBackend === 'kernel' || options.issueBackend === 'beads') {
|
|
492
|
+
return options.issueBackend;
|
|
493
|
+
}
|
|
494
|
+
return resolveIssueBackend({
|
|
495
|
+
deps: options.backendDeps || {},
|
|
496
|
+
env: options.env || process.env,
|
|
497
|
+
projectRoot,
|
|
498
|
+
warn: () => {}
|
|
499
|
+
});
|
|
500
|
+
}
|
|
501
|
+
|
|
218
502
|
function checkRuntimeHealth(projectRoot, options = {}) {
|
|
219
503
|
const platform = options.platform || process.platform;
|
|
220
504
|
const root = normalizeProjectRoot(projectRoot);
|
|
221
505
|
|
|
222
|
-
const lefthook = checkLefthookStatus(root);
|
|
223
506
|
const hooks = checkHookInstallation(root, options);
|
|
507
|
+
const lefthook = checkLefthookStatus(root);
|
|
224
508
|
const bd = checkCommandAvailability('bd', root, options);
|
|
225
509
|
const gh = checkCommandAvailability('gh', root, options);
|
|
226
510
|
const jq = checkCommandAvailability('jq', root, options);
|
|
227
511
|
const shell = normalizeShellRuntime(options.shellRuntime, platform, options);
|
|
228
512
|
|
|
513
|
+
const issueBackend = resolveHealthIssueBackend(options, root);
|
|
514
|
+
|
|
229
515
|
const diagnostics = [];
|
|
516
|
+
const advisories = [];
|
|
517
|
+
|
|
518
|
+
const lefthookMissing = lefthook.state === 'missing-dependency'
|
|
519
|
+
|| lefthook.state === 'missing-binary';
|
|
230
520
|
|
|
231
|
-
if (
|
|
521
|
+
if (lefthookMissing) {
|
|
522
|
+
const lefthookRepair = lefthook.state === 'missing-binary'
|
|
523
|
+
? getInstallCommand(root)
|
|
524
|
+
: getAddDevCommand(root, 'lefthook');
|
|
232
525
|
diagnostics.push(createDiagnostic(
|
|
233
526
|
'LEFTHOOK_MISSING',
|
|
234
527
|
'lefthook',
|
|
235
528
|
lefthook.message || 'lefthook is required for hook installation.',
|
|
236
|
-
|
|
529
|
+
lefthookRepair
|
|
237
530
|
));
|
|
238
531
|
}
|
|
239
532
|
|
|
@@ -247,11 +540,25 @@ function checkRuntimeHealth(projectRoot, options = {}) {
|
|
|
247
540
|
}
|
|
248
541
|
|
|
249
542
|
if (!bd.available) {
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
543
|
+
if (issueBackend === 'beads') {
|
|
544
|
+
// Beads is the active issue backend, so bd is a genuine hard prerequisite.
|
|
545
|
+
diagnostics.push(createDiagnostic(
|
|
546
|
+
'BD_MISSING',
|
|
547
|
+
'bd',
|
|
548
|
+
'bd is required for stage-entry workflow checks when the beads issue backend is selected.'
|
|
549
|
+
));
|
|
550
|
+
} else {
|
|
551
|
+
// Kernel is the default issue backend and needs no bd binary, so a missing bd
|
|
552
|
+
// must NOT hard-stop stage entry (the "no Beads install required" contract).
|
|
553
|
+
// Surface it as a non-blocking advisory instead.
|
|
554
|
+
advisories.push(createDiagnostic(
|
|
555
|
+
'BD_MISSING',
|
|
556
|
+
'bd',
|
|
557
|
+
'bd is not installed. The kernel issue backend does not require it; install bd only if you switch to the beads backend.',
|
|
558
|
+
undefined,
|
|
559
|
+
'advisory'
|
|
560
|
+
));
|
|
561
|
+
}
|
|
255
562
|
}
|
|
256
563
|
|
|
257
564
|
if (!gh.available) {
|
|
@@ -285,6 +592,7 @@ function checkRuntimeHealth(projectRoot, options = {}) {
|
|
|
285
592
|
ready: healthy,
|
|
286
593
|
hardStop: !healthy,
|
|
287
594
|
diagnostics,
|
|
595
|
+
advisories,
|
|
288
596
|
checks: {
|
|
289
597
|
projectRoot: root,
|
|
290
598
|
lefthook,
|
|
@@ -292,7 +600,8 @@ function checkRuntimeHealth(projectRoot, options = {}) {
|
|
|
292
600
|
bd,
|
|
293
601
|
gh,
|
|
294
602
|
jq,
|
|
295
|
-
shell
|
|
603
|
+
shell,
|
|
604
|
+
issueBackend
|
|
296
605
|
}
|
|
297
606
|
};
|
|
298
607
|
}
|