forge-workflow 0.0.10 → 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 +150 -61
- package/CHANGELOG.md +681 -0
- package/CLAUDE.md +9 -118
- 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 +461 -489
- package/docs/INDEX.md +93 -0
- package/docs/PROJECT_DESIGN.md +685 -0
- package/docs/architecture/index.md +66 -0
- package/docs/architecture/notes/README.md +35 -0
- package/docs/architecture/subsystems/README.md +46 -0
- package/docs/forge/TOOLCHAIN.md +670 -0
- package/docs/forge/VALIDATION.md +82 -0
- package/docs/{AGENT_INSTALL_PROMPT.md → guides/AGENT_INSTALL_PROMPT.md} +3 -3
- package/docs/guides/BEADS_GITHUB_SYNC.md +32 -0
- package/docs/{ENHANCED_ONBOARDING.md → guides/ENHANCED_ONBOARDING.md} +16 -12
- package/docs/guides/GREPTILE_SETUP.md +46 -0
- package/docs/guides/MANUAL_REVIEW_GUIDE.md +58 -0
- package/docs/guides/MIGRATION.md +56 -0
- package/docs/guides/SETUP.md +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/{TOOLCHAIN.md → reference/TOOLCHAIN.md} +62 -47
- package/docs/reference/VALIDATION.md +82 -0
- package/docs/reference/agent-permissions.md +169 -0
- package/docs/reference/beads-to-kernel-migration-ux.md +61 -0
- package/docs/reference/control-plane-guarantees.md +125 -0
- package/docs/reference/dependency-chain.md +331 -0
- package/docs/reference/forge-kernel-issue-command-contract.md +161 -0
- package/docs/reference/forge-kernel-schema.md +72 -0
- package/docs/reference/kernel-conflict-evaluators.md +27 -0
- package/docs/reference/patch-md-format.md +77 -0
- package/docs/reference/protected-state-surfaces.md +59 -0
- package/docs/reference/shepherd.md +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 +121 -0
- package/lib/beads-sync-scaffold.js +25 -101
- package/lib/codex-skills.js +51 -1
- package/lib/commands/_issue.js +741 -77
- 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 +17 -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 +0 -1
- 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 +838 -972
- 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 +158 -21
- package/lib/commands/sync.js +34 -46
- package/lib/commands/team.js +4 -1
- package/lib/commands/test.js +43 -27
- package/lib/commands/update.js +2 -2
- package/lib/commands/upgrade.js +47 -0
- package/lib/commands/validate.js +43 -18
- package/lib/commands/worktree.js +307 -100
- 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 +2 -2
- package/lib/deprecated-sync-cleanup.js +362 -0
- package/lib/detect-agent.js +2 -28
- package/lib/detect-worktree.js +35 -9
- package/lib/doc-gate/declaration.js +177 -0
- package/lib/doc-gate/detect.js +289 -0
- package/lib/doc-gate/gate.js +375 -0
- package/lib/doc-gate/okf-config.js +128 -0
- package/lib/doc-gate/okf.js +429 -0
- package/lib/docs-command.js +1161 -6
- package/lib/forge-issues.js +382 -11
- package/lib/forge-lock.js +262 -0
- package/lib/gate-events.js +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/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 +3 -2
- package/lib/lefthook-wiring.js +413 -0
- package/lib/mcp-config-renderer.js +288 -0
- package/lib/memory/graphiti-mcp.js +106 -0
- package/lib/memory/router.js +387 -0
- package/lib/memory/typed-api.js +102 -0
- package/lib/memory-digest.js +195 -0
- package/lib/merge-rules.js +395 -0
- package/lib/migrate-dry-run.js +466 -0
- package/lib/orientation.js +863 -0
- package/lib/package-manager-remediation.js +103 -0
- package/lib/package-root.js +381 -0
- package/lib/patch-intent.js +890 -0
- package/lib/plugin-catalog.js +3 -4
- package/lib/plugin-manager.js +0 -5
- package/lib/pr-bundle.js +186 -0
- package/lib/pr-monitor/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 +99 -497
- 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 +241 -20
- package/lib/safety-config-renderer.js +268 -0
- package/lib/setup-action-log.js +1 -7
- package/lib/setup.js +27 -65
- package/lib/shell-utils.js +76 -6
- package/lib/skills-sync.js +330 -0
- package/lib/smart-status/scoring.js +17 -3
- package/lib/status/beads-snapshot.js +45 -2
- package/lib/status/presenter.js +169 -18
- package/lib/status/snapshot.js +186 -0
- package/lib/sync-backend.js +202 -0
- package/lib/untrusted-content.js +52 -0
- package/lib/upgrade-safety.js +199 -0
- package/lib/workflow/enforce-stage.js +296 -47
- package/lib/workflow/stage-transition.js +115 -0
- package/lib/workflow/stages.js +30 -6
- package/lib/workflow/state-manager.js +11 -22
- package/lib/workflow/state.js +23 -1
- package/lib/workflow-profiles.js +17 -5
- package/package.json +37 -35
- package/rules/documentation.md +19 -0
- package/rules/kernel-tracking.md +26 -0
- package/rules/security.md +22 -0
- package/rules/tdd.md +20 -0
- package/rules/workflow.md +27 -0
- package/scripts/auto-backing-issue.js +47 -0
- package/scripts/beads-context.sh +81 -57
- package/scripts/beads-upgrade-smoke.sh +24 -3
- package/scripts/bootstrap-windows-tools.sh +78 -0
- package/scripts/branch-protection.js +2 -3
- package/scripts/check-agents.js +34 -137
- package/scripts/commitlint.js +3 -1
- package/scripts/conflict-detect.sh +3 -0
- package/scripts/dep-guard.sh +22 -3
- package/scripts/file-index.sh +3 -0
- package/scripts/forge-team/lib/claim.sh +34 -18
- package/scripts/forge-team/lib/dashboard.sh +61 -86
- package/scripts/forge-team/lib/epic.sh +99 -263
- package/scripts/forge-team/lib/hooks.sh +26 -28
- package/scripts/forge-team/lib/identity.sh +4 -4
- package/scripts/forge-team/lib/sync-github.sh +49 -84
- package/scripts/forge-team/lib/verify.sh +93 -83
- package/scripts/forge-team/lib/workload.sh +41 -65
- package/scripts/forge-team/tests/claim.test.sh +25 -19
- package/scripts/forge-team/tests/dashboard.test.sh +31 -46
- package/scripts/forge-team/tests/epic.test.sh +52 -71
- package/scripts/forge-team/tests/hooks.test.sh +38 -50
- package/scripts/forge-team/tests/identity.test.sh +3 -3
- package/scripts/forge-team/tests/integration.test.sh +44 -66
- package/scripts/forge-team/tests/sync-github.test.sh +50 -83
- package/scripts/forge-team/tests/verify.test.sh +37 -46
- package/scripts/forge-team/tests/workflow-integration.test.sh +4 -4
- package/scripts/forge-team/tests/workload.test.sh +32 -66
- package/scripts/gen-command-manifest.js +153 -0
- package/scripts/gen-embedded-assets.mjs +129 -0
- package/scripts/install.ps1 +139 -0
- package/scripts/install.sh +268 -0
- package/scripts/lib/release-asset.mjs +84 -0
- package/scripts/parity-check.mjs +145 -0
- package/scripts/parity-check.test.mjs +58 -0
- package/scripts/pin-agentic-workflow-images.js +112 -0
- package/scripts/pr-coordinator.sh +3 -0
- package/scripts/preflight-sonar.eslint.config.mjs +44 -0
- package/scripts/preflight.sh +21 -94
- package/scripts/protected-state-check.js +104 -0
- package/scripts/smart-status.sh +60 -57
- package/scripts/spikes/config-race-bench.js +111 -0
- package/scripts/spikes/harness-capability-matrix.js +13 -0
- package/scripts/spikes/patch-anchor-stability-bench.js +125 -0
- package/scripts/spikes/protected-path-manifest.js +20 -0
- package/scripts/spikes/skill-auto-invoke-parity.js +292 -0
- package/scripts/sync-agent-skills.js +62 -0
- package/scripts/sync-utils.sh +3 -0
- package/scripts/test-ci-shard.js +13 -6
- package/scripts/test.js +95 -12
- package/skills/claim-safety/SKILL.md +102 -0
- package/skills/claim-safety/evals/evals.json +46 -0
- package/{.github/prompts/dev.prompt.md → skills/dev/SKILL.md} +44 -50
- package/skills/dev/evals/evals.json +50 -0
- package/skills/hermes-forge/SKILL.md +185 -0
- package/skills/hermes-forge/evals/evals.json +46 -0
- package/skills/issue-basics/SKILL.md +111 -0
- package/skills/issue-basics/evals/evals.json +46 -0
- package/skills/kernel/SKILL.md +166 -0
- package/skills/kernel/evals/evals.json +50 -0
- package/skills/memory/SKILL.md +102 -0
- package/skills/parallel-deep-research/SKILL.md +14 -11
- package/skills/parallel-deep-research/evals/evals.json +11 -27
- package/{.github/prompts/plan.prompt.md → skills/plan/SKILL.md} +132 -157
- package/skills/plan/evals/evals.json +42 -0
- package/skills/research/SKILL.md +195 -0
- package/skills/research/evals/evals.json +42 -0
- package/{.github/prompts/review.prompt.md → skills/review/SKILL.md} +98 -62
- package/skills/review/evals/evals.json +42 -0
- package/skills/rollback/SKILL.md +110 -0
- package/skills/rollback/evals/evals.json +46 -0
- package/skills/rollback/references/methods.md +204 -0
- package/{.cursor/commands/rollback.md → skills/rollback/references/workflow-integration.md} +10 -284
- package/skills/shepherd/SKILL.md +66 -0
- package/skills/shepherd/evals/evals.json +42 -0
- package/{.github/prompts/ship.prompt.md → skills/ship/SKILL.md} +81 -45
- package/skills/ship/evals/evals.json +42 -0
- package/skills/smith/SKILL.md +142 -0
- package/skills/smith/evals/evals.json +46 -0
- package/skills/smith/references/autonomy-and-gates.md +94 -0
- package/{.github/prompts/sonarcloud.prompt.md → skills/sonarcloud/SKILL.md} +14 -3
- package/skills/sonarcloud/evals/evals.json +46 -0
- package/skills/sonarcloud-analysis/SKILL.md +18 -13
- package/skills/sonarcloud-analysis/evals/evals.json +11 -15
- package/{.github/prompts/status.prompt.md → skills/status/SKILL.md} +20 -10
- package/skills/status/evals/evals.json +50 -0
- package/skills/triage-ready/SKILL.md +121 -0
- package/skills/triage-ready/evals/evals.json +42 -0
- package/{.github/prompts/validate.prompt.md → skills/validate/SKILL.md} +52 -29
- package/skills/validate/evals/evals.json +42 -0
- package/skills/verify/SKILL.md +299 -0
- package/skills/verify/evals/evals.json +50 -0
- package/.claude/commands/dev.md +0 -345
- package/.claude/commands/plan.md +0 -566
- package/.claude/commands/premerge.md +0 -186
- package/.claude/commands/research.md +0 -42
- package/.claude/commands/review.md +0 -451
- package/.claude/commands/rollback.md +0 -721
- package/.claude/commands/ship.md +0 -213
- package/.claude/commands/sonarcloud.md +0 -152
- package/.claude/commands/status.md +0 -90
- package/.claude/commands/validate.md +0 -288
- package/.claude/commands/verify.md +0 -269
- package/.claude/rules/workflow.md +0 -121
- package/.cline/workflows/dev.md +0 -342
- package/.cline/workflows/plan.md +0 -563
- package/.cline/workflows/premerge.md +0 -183
- package/.cline/workflows/research.md +0 -39
- package/.cline/workflows/review.md +0 -448
- package/.cline/workflows/rollback.md +0 -718
- package/.cline/workflows/ship.md +0 -210
- package/.cline/workflows/sonarcloud.md +0 -146
- package/.cline/workflows/status.md +0 -87
- package/.cline/workflows/validate.md +0 -285
- package/.cline/workflows/verify.md +0 -266
- package/.codex/config.toml +0 -11
- package/.codex/skills/dev/SKILL.md +0 -345
- package/.codex/skills/plan/SKILL.md +0 -566
- package/.codex/skills/premerge/SKILL.md +0 -186
- package/.codex/skills/research/SKILL.md +0 -42
- package/.codex/skills/review/SKILL.md +0 -451
- package/.codex/skills/rollback/SKILL.md +0 -721
- package/.codex/skills/ship/SKILL.md +0 -213
- package/.codex/skills/sonarcloud/SKILL.md +0 -149
- package/.codex/skills/status/SKILL.md +0 -90
- package/.codex/skills/validate/SKILL.md +0 -288
- package/.codex/skills/verify/SKILL.md +0 -269
- package/.cursor/commands/dev.md +0 -342
- package/.cursor/commands/plan.md +0 -563
- package/.cursor/commands/premerge.md +0 -183
- package/.cursor/commands/research.md +0 -39
- package/.cursor/commands/review.md +0 -448
- package/.cursor/commands/ship.md +0 -210
- package/.cursor/commands/sonarcloud.md +0 -146
- package/.cursor/commands/status.md +0 -87
- package/.cursor/commands/validate.md +0 -285
- package/.cursor/commands/verify.md +0 -266
- package/.cursorrules +0 -149
- package/.github/prompts/premerge.prompt.md +0 -188
- package/.github/prompts/research.prompt.md +0 -44
- package/.github/prompts/rollback.prompt.md +0 -723
- package/.github/prompts/verify.prompt.md +0 -271
- package/.github/workflows/beads-to-github.yml +0 -89
- package/.github/workflows/github-to-beads.yml +0 -100
- package/.kilocode/workflows/dev.md +0 -346
- package/.kilocode/workflows/plan.md +0 -567
- package/.kilocode/workflows/premerge.md +0 -187
- package/.kilocode/workflows/research.md +0 -43
- package/.kilocode/workflows/review.md +0 -452
- package/.kilocode/workflows/rollback.md +0 -722
- package/.kilocode/workflows/ship.md +0 -214
- package/.kilocode/workflows/sonarcloud.md +0 -150
- package/.kilocode/workflows/status.md +0 -91
- package/.kilocode/workflows/validate.md +0 -289
- package/.kilocode/workflows/verify.md +0 -270
- package/.opencode/commands/dev.md +0 -345
- package/.opencode/commands/plan.md +0 -566
- package/.opencode/commands/premerge.md +0 -186
- package/.opencode/commands/research.md +0 -42
- package/.opencode/commands/review.md +0 -451
- package/.opencode/commands/rollback.md +0 -721
- package/.opencode/commands/ship.md +0 -213
- package/.opencode/commands/sonarcloud.md +0 -149
- package/.opencode/commands/status.md +0 -90
- package/.opencode/commands/validate.md +0 -288
- package/.opencode/commands/verify.md +0 -269
- package/.roo/commands/dev.md +0 -346
- package/.roo/commands/plan.md +0 -567
- package/.roo/commands/premerge.md +0 -187
- package/.roo/commands/research.md +0 -43
- package/.roo/commands/review.md +0 -452
- package/.roo/commands/rollback.md +0 -722
- package/.roo/commands/ship.md +0 -214
- package/.roo/commands/sonarcloud.md +0 -150
- package/.roo/commands/status.md +0 -91
- package/.roo/commands/validate.md +0 -289
- package/.roo/commands/verify.md +0 -270
- package/docs/BEADS_GITHUB_SYNC.md +0 -281
- package/docs/GREPTILE_SETUP.md +0 -400
- package/docs/MANUAL_REVIEW_GUIDE.md +0 -106
- package/docs/SETUP.md +0 -663
- package/docs/VALIDATION.md +0 -363
- package/lib/agents/cline.plugin.json +0 -29
- package/lib/agents/copilot.plugin.json +0 -24
- package/lib/agents/kilocode.plugin.json +0 -22
- package/lib/agents/opencode.plugin.json +0 -23
- package/lib/agents/roo.plugin.json +0 -30
- package/lib/beads-bootstrap.js +0 -225
- package/lib/beads-health-check.js +0 -188
- package/lib/commands/commands-reset.js +0 -147
- package/opencode.json +0 -67
- package/scripts/beads-context.test.js +0 -584
- package/scripts/github-beads-sync/comment.mjs +0 -64
- package/scripts/github-beads-sync/config.mjs +0 -148
- package/scripts/github-beads-sync/github-api.mjs +0 -131
- package/scripts/github-beads-sync/index.mjs +0 -356
- package/scripts/github-beads-sync/label-mapper.mjs +0 -54
- package/scripts/github-beads-sync/mapping.mjs +0 -132
- package/scripts/github-beads-sync/reverse-sync-cli.mjs +0 -31
- package/scripts/github-beads-sync/reverse-sync.mjs +0 -162
- package/scripts/github-beads-sync/run-bd.mjs +0 -161
- package/scripts/github-beads-sync/sanitize.mjs +0 -121
- package/scripts/github-beads-sync.config.json +0 -26
- package/scripts/sync-commands.js +0 -600
package/lib/workflow/stages.js
CHANGED
|
@@ -15,7 +15,6 @@ const STAGE_IDS = Object.freeze([
|
|
|
15
15
|
'validate',
|
|
16
16
|
'ship',
|
|
17
17
|
'review',
|
|
18
|
-
'premerge',
|
|
19
18
|
'verify',
|
|
20
19
|
]);
|
|
21
20
|
|
|
@@ -25,7 +24,6 @@ const STAGE_LABELS = Object.freeze({
|
|
|
25
24
|
validate: 'Validate',
|
|
26
25
|
ship: 'Ship',
|
|
27
26
|
review: 'Review',
|
|
28
|
-
premerge: 'Premerge',
|
|
29
27
|
verify: 'Verify',
|
|
30
28
|
});
|
|
31
29
|
|
|
@@ -35,14 +33,13 @@ const STAGE_COMMANDS = Object.freeze({
|
|
|
35
33
|
validate: '/validate',
|
|
36
34
|
ship: '/ship',
|
|
37
35
|
review: '/review',
|
|
38
|
-
premerge: '/premerge',
|
|
39
36
|
verify: '/verify',
|
|
40
37
|
});
|
|
41
38
|
|
|
42
39
|
const WORKFLOW_STAGE_MATRIX = Object.freeze({
|
|
43
|
-
critical: Object.freeze(['plan', 'dev', 'validate', 'ship', 'review', '
|
|
44
|
-
standard: Object.freeze(['plan', 'dev', 'validate', 'ship', 'review'
|
|
45
|
-
refactor: Object.freeze(['plan', 'dev', 'validate', 'ship'
|
|
40
|
+
critical: Object.freeze(['plan', 'dev', 'validate', 'ship', 'review', 'verify']),
|
|
41
|
+
standard: Object.freeze(['plan', 'dev', 'validate', 'ship', 'review']),
|
|
42
|
+
refactor: Object.freeze(['plan', 'dev', 'validate', 'ship']),
|
|
46
43
|
simple: Object.freeze(['dev', 'validate', 'ship']),
|
|
47
44
|
hotfix: Object.freeze(['dev', 'validate', 'ship']),
|
|
48
45
|
// Docs-only work intentionally reuses /verify as a pre-ship content check to
|
|
@@ -51,6 +48,18 @@ const WORKFLOW_STAGE_MATRIX = Object.freeze({
|
|
|
51
48
|
docs: Object.freeze(['verify', 'ship']),
|
|
52
49
|
});
|
|
53
50
|
|
|
51
|
+
// Pre-merge is a task-type gate/checkpoint embedded inside existing stages
|
|
52
|
+
// (the doc-completion + PR-handoff checks that run before merge), not a
|
|
53
|
+
// standalone universal workflow stage. It is keyed with a hyphen ('pre-merge')
|
|
54
|
+
// so it never re-enters the stage model. `enabledFor` lists the classifications
|
|
55
|
+
// that run the gate; `embeddedIn` names the stages where it fires.
|
|
56
|
+
const WORKFLOW_GATES = Object.freeze({
|
|
57
|
+
'pre-merge': Object.freeze({
|
|
58
|
+
embeddedIn: Object.freeze(['ship', 'review']),
|
|
59
|
+
enabledFor: Object.freeze(['critical', 'standard', 'refactor']),
|
|
60
|
+
}),
|
|
61
|
+
});
|
|
62
|
+
|
|
54
63
|
const WORKFLOW_TERMINAL_STAGES = Object.freeze(Object.entries(WORKFLOW_STAGE_MATRIX).reduce((accumulator, [classification, path]) => {
|
|
55
64
|
accumulator[classification] = path.at(-1);
|
|
56
65
|
return accumulator;
|
|
@@ -77,6 +86,19 @@ function getWorkflowPath(classification) {
|
|
|
77
86
|
return normalized ? WORKFLOW_STAGE_MATRIX[normalized] : Object.freeze([]);
|
|
78
87
|
}
|
|
79
88
|
|
|
89
|
+
function getGatesForClassification(classification) {
|
|
90
|
+
const normalized = normalizeClassification(classification);
|
|
91
|
+
if (!normalized) {
|
|
92
|
+
return Object.freeze([]);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return Object.freeze(
|
|
96
|
+
Object.entries(WORKFLOW_GATES)
|
|
97
|
+
.filter(([, gate]) => gate.enabledFor.includes(normalized))
|
|
98
|
+
.map(([gateId]) => gateId),
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
|
|
80
102
|
function getStageWorkflow(stageId, classification) {
|
|
81
103
|
const normalizedStage = normalizeStageId(stageId);
|
|
82
104
|
const normalizedClassification = normalizeClassification(classification);
|
|
@@ -186,6 +208,7 @@ module.exports = {
|
|
|
186
208
|
STAGE_LABELS,
|
|
187
209
|
STAGE_COMMANDS,
|
|
188
210
|
WORKFLOW_STAGE_MATRIX,
|
|
211
|
+
WORKFLOW_GATES,
|
|
189
212
|
WORKFLOW_TERMINAL_STAGES,
|
|
190
213
|
STAGE_TRANSITIONS,
|
|
191
214
|
STAGE_MODEL,
|
|
@@ -193,6 +216,7 @@ module.exports = {
|
|
|
193
216
|
normalizeStageId,
|
|
194
217
|
isCanonicalStageId,
|
|
195
218
|
getWorkflowPath,
|
|
219
|
+
getGatesForClassification,
|
|
196
220
|
getStageWorkflow,
|
|
197
221
|
getAllowedTransitions,
|
|
198
222
|
canTransition,
|
|
@@ -105,7 +105,7 @@ function readBeadsIssue(issueId, options = {}) {
|
|
|
105
105
|
|
|
106
106
|
try {
|
|
107
107
|
const { projectRoot, ...execOptions } = options;
|
|
108
|
-
const raw = secureExecFileSync('
|
|
108
|
+
const raw = secureExecFileSync('forge', ['issue', 'show', issueId, '--json'], {
|
|
109
109
|
encoding: 'utf8',
|
|
110
110
|
cwd: projectRoot,
|
|
111
111
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
@@ -139,30 +139,19 @@ function readWorkflowStateFromBeads(issueId, options = {}) {
|
|
|
139
139
|
}
|
|
140
140
|
}
|
|
141
141
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
const state = extractWorkflowStateFromIssue(issue);
|
|
147
|
-
if (state) {
|
|
148
|
-
return state;
|
|
149
|
-
}
|
|
150
|
-
} catch (_error) {
|
|
151
|
-
// Fall through to comments-list fallback.
|
|
142
|
+
if (options.comments) {
|
|
143
|
+
const state = extractWorkflowStateFromComments(options.comments);
|
|
144
|
+
if (state) {
|
|
145
|
+
return state;
|
|
152
146
|
}
|
|
153
147
|
}
|
|
154
148
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
})
|
|
160
|
-
|
|
161
|
-
if (!comments) {
|
|
162
|
-
return null;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
return extractWorkflowStateFromComments(comments);
|
|
149
|
+
// `forge issue show --json` returns the issue together with its full comment
|
|
150
|
+
// history, so a single read covers both the structured issue and the raw
|
|
151
|
+
// comment text carrying the serialized WorkflowState marker. No separate
|
|
152
|
+
// comment-list read is required.
|
|
153
|
+
const issue = readBeadsIssue(issueId, { projectRoot: options.projectRoot });
|
|
154
|
+
return extractWorkflowStateFromIssue(issue);
|
|
166
155
|
}
|
|
167
156
|
|
|
168
157
|
function loadStateFromBeads(options, projectRoot) {
|
package/lib/workflow/state.js
CHANGED
|
@@ -5,7 +5,7 @@ const {
|
|
|
5
5
|
STAGE_IDS,
|
|
6
6
|
STAGE_MODEL,
|
|
7
7
|
getWorkflowPath,
|
|
8
|
-
normalizeStageId,
|
|
8
|
+
normalizeStageId: normalizeCanonicalStageId,
|
|
9
9
|
} = require('./stages.js');
|
|
10
10
|
|
|
11
11
|
const WORKFLOW_STATE_SCHEMA_VERSION = 2;
|
|
@@ -19,6 +19,28 @@ const LEGACY_STANDARD_WORKFLOW_PATH = Object.freeze([
|
|
|
19
19
|
'premerge',
|
|
20
20
|
'verify',
|
|
21
21
|
]);
|
|
22
|
+
|
|
23
|
+
// Stages that the canonical model no longer recognizes but that legacy
|
|
24
|
+
// schemaVersion 1 standard workflows persisted (e.g. pre-merge, retired as a
|
|
25
|
+
// standalone stage and re-homed as a task-type gate). We still accept these ids
|
|
26
|
+
// when normalizing legacy state so historical .forge-state.json files survive a
|
|
27
|
+
// read/write round-trip. The workflow-path membership checks below remain the
|
|
28
|
+
// real guard: a non-legacy classification whose path omits the stage still
|
|
29
|
+
// rejects it, so accepting the id here never leaks retired stages into current
|
|
30
|
+
// flows.
|
|
31
|
+
const LEGACY_STAGE_IDS = Object.freeze(
|
|
32
|
+
LEGACY_STANDARD_WORKFLOW_PATH.filter(stage => !normalizeCanonicalStageId(stage))
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
function normalizeStageId(stage) {
|
|
36
|
+
const canonical = normalizeCanonicalStageId(stage);
|
|
37
|
+
if (canonical) {
|
|
38
|
+
return canonical;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const value = typeof stage === 'string' ? stage.trim() : '';
|
|
42
|
+
return LEGACY_STAGE_IDS.includes(value) ? value : null;
|
|
43
|
+
}
|
|
22
44
|
const LEGACY_WORKFLOW_STATE_OPTIONS = Object.freeze({
|
|
23
45
|
allowLegacyDefaultClassification: true,
|
|
24
46
|
allowLegacyStandardVerify: true,
|
package/lib/workflow-profiles.js
CHANGED
|
@@ -9,10 +9,17 @@
|
|
|
9
9
|
/**
|
|
10
10
|
* Internal workflow profiles aligned with AGENTS.md specification
|
|
11
11
|
*/
|
|
12
|
+
// `stages` lists ONLY the numbered workflow stages (aligned with the canonical stage
|
|
13
|
+
// model in lib/workflow/stages.js). `/status` is a utility — an always-available
|
|
14
|
+
// status/shepherd command, not a stage in any workflow — so it lives under
|
|
15
|
+
// `utilities`, never inside `stages`.
|
|
16
|
+
const UTILITIES = ['/status'];
|
|
17
|
+
|
|
12
18
|
const PROFILES = {
|
|
13
19
|
critical: {
|
|
14
20
|
name: 'Critical (Maximum Rigor)',
|
|
15
|
-
stages: ['/
|
|
21
|
+
stages: ['/plan', '/dev', '/validate', '/ship', '/review', '/verify'],
|
|
22
|
+
utilities: UTILITIES,
|
|
16
23
|
tdd: 'strict',
|
|
17
24
|
research: 'required',
|
|
18
25
|
description: 'Security, auth, payments, data integrity, breaking changes',
|
|
@@ -21,7 +28,8 @@ const PROFILES = {
|
|
|
21
28
|
|
|
22
29
|
standard: {
|
|
23
30
|
name: 'Standard (Full Workflow)',
|
|
24
|
-
stages: ['/
|
|
31
|
+
stages: ['/plan', '/dev', '/validate', '/ship', '/review'],
|
|
32
|
+
utilities: UTILITIES,
|
|
25
33
|
tdd: 'required',
|
|
26
34
|
research: 'optional',
|
|
27
35
|
description: 'Most features and non-critical enhancements'
|
|
@@ -29,7 +37,8 @@ const PROFILES = {
|
|
|
29
37
|
|
|
30
38
|
simple: {
|
|
31
39
|
name: 'Simple (Streamlined)',
|
|
32
|
-
stages: ['/dev', '/validate', '/ship'
|
|
40
|
+
stages: ['/dev', '/validate', '/ship'],
|
|
41
|
+
utilities: UTILITIES,
|
|
33
42
|
tdd: 'recommended',
|
|
34
43
|
research: 'skip',
|
|
35
44
|
description: 'UI tweaks, small improvements, minor fixes'
|
|
@@ -38,6 +47,7 @@ const PROFILES = {
|
|
|
38
47
|
hotfix: {
|
|
39
48
|
name: 'Hotfix (Emergency)',
|
|
40
49
|
stages: ['/dev', '/validate', '/ship'],
|
|
50
|
+
utilities: UTILITIES,
|
|
41
51
|
tdd: 'required', // Must reproduce bug
|
|
42
52
|
research: 'skip',
|
|
43
53
|
description: 'Production bugs, urgent fixes',
|
|
@@ -46,7 +56,8 @@ const PROFILES = {
|
|
|
46
56
|
|
|
47
57
|
docs: {
|
|
48
58
|
name: 'Docs (Documentation Only)',
|
|
49
|
-
stages: ['/verify', '/ship'
|
|
59
|
+
stages: ['/verify', '/ship'],
|
|
60
|
+
utilities: UTILITIES,
|
|
50
61
|
tdd: 'no',
|
|
51
62
|
research: 'no',
|
|
52
63
|
description: 'Documentation updates, README changes'
|
|
@@ -54,7 +65,8 @@ const PROFILES = {
|
|
|
54
65
|
|
|
55
66
|
refactor: {
|
|
56
67
|
name: 'Refactor (Behavior-Preserving)',
|
|
57
|
-
stages: ['/plan', '/dev', '/validate', '/ship'
|
|
68
|
+
stages: ['/plan', '/dev', '/validate', '/ship'],
|
|
69
|
+
utilities: UTILITIES,
|
|
58
70
|
tdd: 'strict', // Must preserve behavior
|
|
59
71
|
research: 'optional',
|
|
60
72
|
description: 'Code cleanup, optimization, behavior-preserving improvements'
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "forge-workflow",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.1.0-beta.2",
|
|
4
|
+
"description": "Local runtime control plane for AI-assisted engineering workflows, gates, evidence, and all AI agents",
|
|
5
5
|
"bin": {
|
|
6
6
|
"forge": "bin/forge.js",
|
|
7
7
|
"forge-workflow": "bin/forge.js",
|
|
@@ -13,15 +13,21 @@
|
|
|
13
13
|
"scripts": {
|
|
14
14
|
"test": "bun test --timeout 15000",
|
|
15
15
|
"test:setup": "bash test-env/automation/setup-fixtures.sh",
|
|
16
|
-
"test:all": "bun run test:setup && bun test",
|
|
17
|
-
"test:coverage": "c8 --check-coverage bun test",
|
|
16
|
+
"test:all": "bun run test:setup && bun test --timeout 15000",
|
|
17
|
+
"test:coverage": "c8 --check-coverage bun test --timeout 15000",
|
|
18
18
|
"test:ci:shard": "node scripts/test-ci-shard.js",
|
|
19
19
|
"typecheck": "echo 'No TypeScript in project - skipping type check'",
|
|
20
|
+
"gen:manifest": "node scripts/gen-command-manifest.js",
|
|
21
|
+
"gen:manifest:check": "node scripts/gen-command-manifest.js --check",
|
|
22
|
+
"prebuild": "node scripts/gen-command-manifest.js",
|
|
20
23
|
"lint": "eslint . --max-warnings 0",
|
|
21
24
|
"check": "node scripts/validate.js",
|
|
22
25
|
"prepare": "lefthook install || echo 'Note: lefthook not installed. Git hooks disabled. Run: bun add -d lefthook'",
|
|
23
26
|
"setup": "node ./bin/forge.js setup",
|
|
24
27
|
"help": "node ./bin/forge.js --help",
|
|
28
|
+
"gen:assets": "bun scripts/gen-embedded-assets.mjs",
|
|
29
|
+
"build:binary": "bun scripts/gen-embedded-assets.mjs && bun build --compile --define FORGE_COMPILED=true ./bin/forge.js --outfile forge-bin",
|
|
30
|
+
"parity:binary": "bun scripts/parity-check.mjs",
|
|
25
31
|
"validate:yaml": "find . \\( -name '*.yml' -o -name '*.yaml' \\) | grep -v node_modules | while IFS= read -r file; do echo \"Checking $file...\" && bun x js-yaml \"$file\" > /dev/null || exit 1; done",
|
|
26
32
|
"test:mutation": "npx stryker run",
|
|
27
33
|
"test:benchmark": "node scripts/benchmark.js --output test-results/benchmark-results.json --profile-dir test-results/benchmark-profiles",
|
|
@@ -29,8 +35,8 @@
|
|
|
29
35
|
"test:full:parallel": "node scripts/test-full-suite.js",
|
|
30
36
|
"test:dashboard": "node scripts/test-dashboard.js",
|
|
31
37
|
"test:profile": "node scripts/test-profile.js --input-dir test-results --output test-results/test-profile.json --label local",
|
|
32
|
-
"test:randomized": "bun test --randomize",
|
|
33
|
-
"test:rerun": "bun test --rerun-each 2",
|
|
38
|
+
"test:randomized": "bun test --timeout 15000 --randomize",
|
|
39
|
+
"test:rerun": "bun test --timeout 15000 --rerun-each 2",
|
|
34
40
|
"agentic:sync": "node scripts/sync-agentic-workflow.js"
|
|
35
41
|
},
|
|
36
42
|
"peerDependencies": {
|
|
@@ -42,17 +48,18 @@
|
|
|
42
48
|
}
|
|
43
49
|
},
|
|
44
50
|
"devDependencies": {
|
|
45
|
-
"@commitlint/cli": "^
|
|
46
|
-
"@commitlint/config-conventional": "^
|
|
51
|
+
"@commitlint/cli": "^21.0.0",
|
|
52
|
+
"@commitlint/config-conventional": "^21.0.0",
|
|
47
53
|
"@eslint/js": "^10.0.1",
|
|
48
54
|
"@microsoft/eslint-formatter-sarif": "^3.1.0",
|
|
49
55
|
"@stryker-mutator/core": "^9.6.0",
|
|
50
56
|
"c8": "^11.0.0",
|
|
51
57
|
"eslint": "^10.0.2",
|
|
58
|
+
"eslint-plugin-sonarjs": "^4.1.0",
|
|
52
59
|
"globals": "^17.3.0",
|
|
53
|
-
"js-yaml": "^
|
|
60
|
+
"js-yaml": "^5.1.0",
|
|
54
61
|
"lefthook": "^2.1.4",
|
|
55
|
-
"
|
|
62
|
+
"typescript": "5.4.5"
|
|
56
63
|
},
|
|
57
64
|
"keywords": [
|
|
58
65
|
"ai",
|
|
@@ -61,17 +68,15 @@
|
|
|
61
68
|
"agents-md",
|
|
62
69
|
"claude-code",
|
|
63
70
|
"cursor",
|
|
64
|
-
"kilo-code",
|
|
65
|
-
"opencode",
|
|
66
|
-
"copilot",
|
|
67
|
-
"cline",
|
|
68
|
-
"roo-code",
|
|
69
71
|
"codex",
|
|
70
72
|
"development",
|
|
71
73
|
"testing"
|
|
72
74
|
],
|
|
73
75
|
"author": "Harsha Nandak",
|
|
74
76
|
"license": "MIT",
|
|
77
|
+
"engines": {
|
|
78
|
+
"node": ">=22.16.0"
|
|
79
|
+
},
|
|
75
80
|
"repository": {
|
|
76
81
|
"type": "git",
|
|
77
82
|
"url": "git+https://github.com/harshanandak/forge.git"
|
|
@@ -83,47 +88,44 @@
|
|
|
83
88
|
"files": [
|
|
84
89
|
"bin/",
|
|
85
90
|
"lib/",
|
|
91
|
+
"rules/",
|
|
86
92
|
"skills/",
|
|
87
|
-
".claude/commands/",
|
|
88
93
|
".claude/rules/",
|
|
89
94
|
".claude/scripts/",
|
|
90
95
|
".claude/skills/",
|
|
91
96
|
".cursor/",
|
|
92
97
|
"!.cursor/node_modules/",
|
|
93
|
-
".cline/",
|
|
94
|
-
"!.cline/node_modules/",
|
|
95
|
-
".roo/",
|
|
96
|
-
"!.roo/node_modules/",
|
|
97
|
-
".codex/",
|
|
98
|
-
"!.codex/node_modules/",
|
|
99
|
-
".kilocode/",
|
|
100
|
-
"!.kilocode/node_modules/",
|
|
101
|
-
".opencode/",
|
|
102
|
-
"!.opencode/node_modules/",
|
|
103
98
|
"scripts/",
|
|
104
|
-
"
|
|
99
|
+
"!scripts/github-beads-sync/",
|
|
100
|
+
"!scripts/github-beads-sync.config.json",
|
|
101
|
+
"!scripts/**/*.test.js",
|
|
105
102
|
".github/PLUGIN_TEMPLATE.json",
|
|
106
|
-
".github/workflows/github-to-beads.yml",
|
|
107
|
-
".github/workflows/beads-to-github.yml",
|
|
108
103
|
".forge/hooks/",
|
|
104
|
+
".forge/protected-paths.yaml",
|
|
105
|
+
"CHANGELOG.md",
|
|
106
|
+
"QUICKSTART.md",
|
|
109
107
|
"docs/*.md",
|
|
108
|
+
"docs/architecture/**/*.md",
|
|
109
|
+
"docs/guides/*.md",
|
|
110
|
+
"docs/reference/*.md",
|
|
111
|
+
"docs/forge/*.md",
|
|
110
112
|
"install.sh",
|
|
111
113
|
"lefthook.yml",
|
|
112
114
|
"AGENTS.md",
|
|
113
115
|
"CLAUDE.md",
|
|
114
|
-
".mcp.json.example"
|
|
115
|
-
".cursorrules",
|
|
116
|
-
"opencode.json"
|
|
116
|
+
".mcp.json.example"
|
|
117
117
|
],
|
|
118
118
|
"dependencies": {
|
|
119
|
-
"@babel/parser": "^
|
|
120
|
-
"fastest-levenshtein": "^1.0.16"
|
|
119
|
+
"@babel/parser": "^8.0.0",
|
|
120
|
+
"fastest-levenshtein": "^1.0.16",
|
|
121
|
+
"yaml": "^2.8.3"
|
|
121
122
|
},
|
|
122
123
|
"overrides": {
|
|
123
124
|
"eslint": "^10.0.2",
|
|
125
|
+
"fast-uri": "^3.1.2",
|
|
124
126
|
"flatted": "3.4.2",
|
|
125
127
|
"minimatch": "10.2.4",
|
|
126
|
-
"brace-expansion": "5.0.
|
|
128
|
+
"brace-expansion": "5.0.6",
|
|
127
129
|
"lodash": "4.18.1"
|
|
128
130
|
},
|
|
129
131
|
"c8": {
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Progressive documentation standards"
|
|
3
|
+
alwaysApply: false
|
|
4
|
+
globs: []
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Documentation Standards
|
|
8
|
+
|
|
9
|
+
Thin pointer — progressive documentation is part of every stage; the authoritative
|
|
10
|
+
guidance lives in `AGENTS.md` and the `ship`/`verify` skills. Do not duplicate it here.
|
|
11
|
+
|
|
12
|
+
Update documentation as you go, not at the end:
|
|
13
|
+
|
|
14
|
+
- **/plan** — record design intent, rationale, and alternatives in the plan doc.
|
|
15
|
+
- **/dev** — comment the *why* for non-obvious logic; keep JSDoc/TSDoc current.
|
|
16
|
+
- **/ship** — update README/CHANGELOG for user-facing or breaking changes.
|
|
17
|
+
- **/verify** — cross-check docs, validate examples, fix broken internal links.
|
|
18
|
+
|
|
19
|
+
Keep terminology consistent, link to code, and remove stale docs promptly.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Always: file every issue, idea, bug, and decision to the Forge Kernel"
|
|
3
|
+
alwaysApply: true
|
|
4
|
+
globs: []
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Kernel Tracking (nothing discussed goes missing)
|
|
8
|
+
|
|
9
|
+
**NON-NEGOTIABLE.** Anything raised in a session — a bug, an idea, a design
|
|
10
|
+
decision, a follow-up, a TODO, a risk you noticed in passing — MUST become a
|
|
11
|
+
Forge Kernel issue **immediately**, before it can be forgotten. This is a
|
|
12
|
+
structural rule, not a judgment call.
|
|
13
|
+
|
|
14
|
+
- Found or discussed something trackable? Run `forge issue create` right then —
|
|
15
|
+
do not wait for "later" or the end of the session.
|
|
16
|
+
- Triage it: set a type and link it to its epic/parent so it is discoverable.
|
|
17
|
+
- Deferring work? File the follow-up issue and reference it — never leave scope
|
|
18
|
+
cuts unfiled.
|
|
19
|
+
- The Kernel is the single source of truth. Do NOT use TodoWrite, markdown TODO
|
|
20
|
+
lists, or memory notes as a substitute for a filed issue.
|
|
21
|
+
|
|
22
|
+
This rule is a **thin pointer** — the authoritative workflow contract lives in
|
|
23
|
+
`AGENTS.md` (see "Forge Issue Tracker") and the stage skills in
|
|
24
|
+
`skills/<stage>/SKILL.md`. It is default-on and governed by the
|
|
25
|
+
`rail.kernel_tracking` runtime rail (`forge gate disable rail.kernel_tracking`
|
|
26
|
+
to turn it off). Do not duplicate policy here.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "OWASP Top 10 security checks"
|
|
3
|
+
alwaysApply: false
|
|
4
|
+
globs: []
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Security Scanning Guidelines
|
|
8
|
+
|
|
9
|
+
Thin pointer — full security analysis is documented in the plan design doc
|
|
10
|
+
(OWASP Top 10 pass during `/plan`) and enforced in the `validate` skill. Do not
|
|
11
|
+
duplicate the checklist here.
|
|
12
|
+
|
|
13
|
+
For every feature, analyze the **OWASP Top 10 (2021)**: broken access control,
|
|
14
|
+
cryptographic failures, injection (SQL/XSS/command), insecure design, security
|
|
15
|
+
misconfiguration, vulnerable components, auth failures, integrity failures,
|
|
16
|
+
logging/monitoring gaps, and SSRF.
|
|
17
|
+
|
|
18
|
+
- Parameterize queries; sanitize output; validate all inputs.
|
|
19
|
+
- Never store secrets or keys in code; reference env vars.
|
|
20
|
+
- Run dependency audits (`npm audit`) and add security test cases.
|
|
21
|
+
|
|
22
|
+
Load the `validate` skill and see `AGENTS.md` for the enforced gates.
|
package/rules/tdd.md
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "TDD patterns and enforcement"
|
|
3
|
+
alwaysApply: false
|
|
4
|
+
globs: ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# TDD Enforcement
|
|
8
|
+
|
|
9
|
+
Thin pointer — the full TDD procedure lives in the `dev` skill
|
|
10
|
+
(`skills/dev/SKILL.md`) and `AGENTS.md`. Do not duplicate it here.
|
|
11
|
+
|
|
12
|
+
**RED → GREEN → REFACTOR** is mandatory. No implementation without a failing
|
|
13
|
+
test first:
|
|
14
|
+
|
|
15
|
+
- **RED** — write the failing test first; run it and see it fail for the right reason.
|
|
16
|
+
- **GREEN** — write the minimal code to pass; nothing beyond the test's scope.
|
|
17
|
+
- **REFACTOR** — clean up while keeping tests green; commit each phase.
|
|
18
|
+
|
|
19
|
+
Test behavior, not implementation. Cover edge cases, errors, and OWASP-relevant
|
|
20
|
+
inputs. Load the `dev` skill for the enforced HARD-GATE loop and decision gate.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "When working with Forge workflow commands"
|
|
3
|
+
alwaysApply: true
|
|
4
|
+
globs: []
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Forge TDD Workflow Template
|
|
8
|
+
|
|
9
|
+
TDD-first workflow. This rule is a **thin pointer** — the authoritative contract
|
|
10
|
+
lives in `AGENTS.md`, and each stage's detailed steps live in its skill
|
|
11
|
+
(`skills/<stage>/SKILL.md`). Do not duplicate policy here.
|
|
12
|
+
|
|
13
|
+
Stages: `/plan` → `/dev` → `/validate` → `/ship` → `/review` → `/verify`
|
|
14
|
+
(pre-merge gate before merge). `/status` and `/shepherd` are utilities, not stages.
|
|
15
|
+
|
|
16
|
+
- `/plan` — design intent → research → branch + worktree + task list
|
|
17
|
+
- `/dev` — subagent-driven TDD per task (RED → GREEN → REFACTOR)
|
|
18
|
+
- `/validate` — type check, lint, tests, security (HARD-GATE on exit)
|
|
19
|
+
- `/ship` — push and open a PR referencing the design doc
|
|
20
|
+
- `/review` — resolve ALL PR feedback (CI, Greptile, SonarCloud)
|
|
21
|
+
- `/verify` — post-merge health check on the default branch
|
|
22
|
+
|
|
23
|
+
> **Pre-merge gate** (not a numbered stage): finish docs on the branch, confirm CI
|
|
24
|
+
> is green, hand off the PR. Embedded in `/ship` and `/review`, not a command.
|
|
25
|
+
|
|
26
|
+
Load the matching stage skill for the full procedure. Default stack: `bun` test
|
|
27
|
+
runner, Git conventional commits, OWASP-aware. See `AGENTS.md` for the rest.
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Pre-push auto-file rail (kernel issue a4b8f56f).
|
|
6
|
+
*
|
|
7
|
+
* Ensures the branch being pushed has a backing Kernel issue so a RAW `git push`
|
|
8
|
+
* (NOT routed through `forge push`, which wires the same rail) still auto-files
|
|
9
|
+
* started work — "nothing goes missing". BEST-EFFORT + NON-BLOCKING: a hook must
|
|
10
|
+
* never block a push on tracking, so `run()` swallows every error and the CLI entry
|
|
11
|
+
* ALWAYS exits 0. Idempotent via ensureBackingIssue (deduped by branch), so it never
|
|
12
|
+
* duplicates an issue `forge worktree`/`forge push` already filed.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
const { execFileSync } = require('node:child_process');
|
|
16
|
+
const path = require('node:path');
|
|
17
|
+
const fs = require('node:fs');
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @param {object} [deps] - injection seam for tests:
|
|
21
|
+
* { getBranch, ensureBackingIssue, buildDeps, projectRoot, existsSync }
|
|
22
|
+
* @returns {Promise<object|null>} the backing-issue descriptor, or null when skipped.
|
|
23
|
+
*/
|
|
24
|
+
async function run(deps = {}) {
|
|
25
|
+
try {
|
|
26
|
+
const projectRoot = deps.projectRoot || process.cwd();
|
|
27
|
+
const existsSync = deps.existsSync || fs.existsSync;
|
|
28
|
+
const getBranch = deps.getBranch || (() => execFileSync('git', ['branch', '--show-current'], { encoding: 'utf8' }).trim());
|
|
29
|
+
const branch = getBranch();
|
|
30
|
+
if (!branch) return null;
|
|
31
|
+
if (!existsSync(path.join(projectRoot, '.git'))) return null;
|
|
32
|
+
|
|
33
|
+
const ensure = deps.ensureBackingIssue || require('../lib/kernel/backing-issue').ensureBackingIssue;
|
|
34
|
+
const buildDeps = deps.buildDeps || (root => require('../lib/kernel/cli-broker-factory').buildMigratedKernelIssueDeps({ projectRoot: root }));
|
|
35
|
+
const { kernelDriver, kernelBroker } = await buildDeps(projectRoot);
|
|
36
|
+
return await ensure({ branch, projectRoot, driver: kernelDriver, broker: kernelBroker });
|
|
37
|
+
} catch {
|
|
38
|
+
// Non-blocking: tracking must never break a push.
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
module.exports = { run };
|
|
44
|
+
|
|
45
|
+
if (require.main === module) {
|
|
46
|
+
run().finally(() => process.exit(0));
|
|
47
|
+
}
|