forge-workflow 0.0.5 → 0.0.7
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/commands/dev.md +6 -1
- package/.claude/commands/plan.md +59 -14
- package/.claude/commands/premerge.md +10 -0
- package/.claude/commands/review.md +7 -1
- package/.claude/commands/ship.md +95 -47
- package/.claude/commands/status.md +42 -0
- package/.claude/commands/validate.md +7 -1
- package/.claude/commands/verify.md +52 -4
- package/.claude/rules/workflow.md +16 -0
- package/.claude/scripts/greptile-resolve.sh +32 -0
- package/.cline/workflows/dev.md +6 -1
- package/.cline/workflows/plan.md +59 -14
- package/.cline/workflows/premerge.md +10 -0
- package/.cline/workflows/review.md +7 -1
- package/.cline/workflows/ship.md +95 -47
- package/.cline/workflows/status.md +42 -0
- package/.cline/workflows/validate.md +7 -1
- package/.cline/workflows/verify.md +52 -4
- package/.codex/skills/dev/SKILL.md +6 -1
- package/.codex/skills/plan/SKILL.md +59 -14
- package/.codex/skills/premerge/SKILL.md +10 -0
- package/.codex/skills/review/SKILL.md +7 -1
- package/.codex/skills/ship/SKILL.md +95 -47
- package/.codex/skills/status/SKILL.md +42 -0
- package/.codex/skills/validate/SKILL.md +7 -1
- package/.codex/skills/verify/SKILL.md +52 -4
- package/.cursor/commands/dev.md +6 -1
- package/.cursor/commands/plan.md +59 -14
- package/.cursor/commands/premerge.md +10 -0
- package/.cursor/commands/review.md +7 -1
- package/.cursor/commands/ship.md +95 -47
- package/.cursor/commands/status.md +42 -0
- package/.cursor/commands/validate.md +7 -1
- package/.cursor/commands/verify.md +52 -4
- package/.cursorrules +149 -0
- package/.github/prompts/dev.prompt.md +6 -1
- package/.github/prompts/plan.prompt.md +59 -14
- package/.github/prompts/premerge.prompt.md +10 -0
- package/.github/prompts/review.prompt.md +7 -1
- package/.github/prompts/ship.prompt.md +95 -47
- package/.github/prompts/status.prompt.md +42 -0
- package/.github/prompts/validate.prompt.md +7 -1
- package/.github/prompts/verify.prompt.md +52 -4
- package/.kilocode/workflows/dev.md +6 -1
- package/.kilocode/workflows/plan.md +59 -14
- package/.kilocode/workflows/premerge.md +10 -0
- package/.kilocode/workflows/review.md +7 -1
- package/.kilocode/workflows/ship.md +95 -47
- package/.kilocode/workflows/status.md +42 -0
- package/.kilocode/workflows/validate.md +7 -1
- package/.kilocode/workflows/verify.md +52 -4
- package/.opencode/commands/dev.md +6 -1
- package/.opencode/commands/plan.md +59 -14
- package/.opencode/commands/premerge.md +10 -0
- package/.opencode/commands/review.md +7 -1
- package/.opencode/commands/ship.md +95 -47
- package/.opencode/commands/status.md +42 -0
- package/.opencode/commands/validate.md +7 -1
- package/.opencode/commands/verify.md +52 -4
- package/.roo/commands/dev.md +6 -1
- package/.roo/commands/plan.md +59 -14
- package/.roo/commands/premerge.md +10 -0
- package/.roo/commands/review.md +7 -1
- package/.roo/commands/ship.md +95 -47
- package/.roo/commands/status.md +42 -0
- package/.roo/commands/validate.md +7 -1
- package/.roo/commands/verify.md +52 -4
- package/AGENTS.md +97 -0
- package/CLAUDE.md +10 -0
- package/README.md +2 -2
- package/bin/forge-cmd.js +5 -1
- package/bin/forge-preflight.js +15 -2
- package/bin/forge.js +211 -9
- package/docs/ENHANCED_ONBOARDING.md +96 -86
- package/docs/ROADMAP.md +2 -2
- package/docs/TOOLCHAIN.md +23 -0
- package/docs/VALIDATION.md +1 -1
- package/lefthook.yml +11 -0
- package/lib/agents/README.md +46 -1
- package/lib/agents/cline.plugin.json +11 -4
- package/lib/agents/codex.plugin.json +2 -2
- package/lib/agents/copilot.plugin.json +5 -5
- package/lib/agents/cursor.plugin.json +1 -1
- package/lib/agents/kilocode.plugin.json +1 -1
- package/lib/agents/opencode.plugin.json +7 -4
- package/lib/agents/roo.plugin.json +10 -3
- package/lib/agents-config.js +129 -81
- package/lib/codex-skills.js +50 -0
- package/lib/commands/_registry.js +173 -0
- package/lib/commands/clean.js +181 -0
- package/lib/commands/commands-reset.js +147 -0
- package/lib/commands/dev.js +84 -0
- package/lib/commands/plan.js +18 -0
- package/lib/commands/push.js +196 -0
- package/lib/commands/recommend.js +1 -1
- package/lib/commands/setup.js +4295 -0
- package/lib/commands/ship.js +20 -0
- package/lib/commands/status.js +210 -44
- package/lib/commands/sync.js +71 -0
- package/lib/commands/team.js +37 -0
- package/lib/commands/test.js +207 -0
- package/lib/commands/validate.js +13 -0
- package/lib/commands/worktree.js +310 -0
- package/lib/detect-agent.js +38 -8
- package/lib/detection-utils.js +405 -0
- package/lib/docs-command.js +51 -0
- package/lib/docs-copy.js +50 -0
- package/lib/file-utils.js +260 -0
- package/lib/forge-context.js +42 -0
- package/lib/freshness-token.js +148 -0
- package/lib/frontmatter.js +79 -0
- package/lib/greptile-match.js +80 -0
- package/lib/husky-migration.js +113 -12
- package/lib/lefthook-check.js +27 -6
- package/lib/plugin-manager.js +225 -72
- package/lib/project-discovery.js +39 -5
- package/lib/reset.js +309 -0
- package/lib/runtime-health.js +305 -0
- package/lib/shell-utils.js +50 -0
- package/lib/task-ownership.js +117 -0
- package/lib/ui-utils.js +43 -0
- package/lib/validation-utils.js +163 -0
- package/lib/workflow/enforce-stage.js +179 -0
- package/lib/workflow/stages.js +201 -0
- package/lib/workflow/state.js +332 -0
- package/opencode.json +67 -0
- package/package.json +16 -6
- package/scripts/beads-context.sh +165 -22
- package/scripts/beads-context.test.js +5 -1
- package/scripts/check-agents.js +103 -0
- package/scripts/check-forge-token.js +98 -0
- package/scripts/conflict-detect.sh +2 -2
- package/scripts/dep-guard.sh +6 -28
- package/scripts/file-index.sh +117 -23
- package/scripts/forge-team/index.sh +86 -0
- package/scripts/forge-team/lib/agent-prompt.sh +52 -0
- package/scripts/forge-team/lib/claim.sh +256 -0
- package/scripts/forge-team/lib/dashboard.sh +341 -0
- package/scripts/forge-team/lib/epic.sh +332 -0
- package/scripts/forge-team/lib/hooks.sh +253 -0
- package/scripts/forge-team/lib/identity.sh +235 -0
- package/scripts/forge-team/lib/sync-github.sh +317 -0
- package/scripts/forge-team/lib/verify.sh +284 -0
- package/scripts/forge-team/lib/workload.sh +296 -0
- package/scripts/forge-team/tests/agent-prompt.test.sh +72 -0
- package/scripts/forge-team/tests/claim.test.sh +179 -0
- package/scripts/forge-team/tests/dashboard.test.sh +170 -0
- package/scripts/forge-team/tests/dispatcher.test.sh +79 -0
- package/scripts/forge-team/tests/epic.test.sh +176 -0
- package/scripts/forge-team/tests/hooks.test.sh +239 -0
- package/scripts/forge-team/tests/identity.test.sh +176 -0
- package/scripts/forge-team/tests/integration.test.sh +371 -0
- package/scripts/forge-team/tests/sync-github.test.sh +209 -0
- package/scripts/forge-team/tests/verify.test.sh +314 -0
- package/scripts/forge-team/tests/workflow-integration.test.sh +43 -0
- package/scripts/forge-team/tests/workload.test.sh +209 -0
- package/scripts/lib/eval-runner.js +39 -0
- package/scripts/lib/jsonl-lock.sh +48 -0
- package/scripts/lib/sanitize.sh +116 -0
- package/scripts/pr-coordinator.sh +756 -0
- package/scripts/smart-status.sh +58 -21
- package/scripts/sync-commands.js +49 -20
- package/scripts/sync-utils.sh +24 -29
- package/scripts/test.js +18 -1
package/.roo/commands/ship.md
CHANGED
|
@@ -47,6 +47,36 @@ BEHIND=$(git rev-list --count HEAD..origin/"$BASE")
|
|
|
47
47
|
|
|
48
48
|
This is NOT a full rebase — just a check. The rebase happens in /validate where the full test suite runs afterward.
|
|
49
49
|
|
|
50
|
+
### Parallel PR coordination (soft block)
|
|
51
|
+
|
|
52
|
+
Before creating the PR, check merge readiness:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
# Run merge simulation against base branch
|
|
56
|
+
bash scripts/pr-coordinator.sh merge-sim "$(git branch --show-current)" 2>&1
|
|
57
|
+
|
|
58
|
+
# Show recommended merge order
|
|
59
|
+
bash scripts/pr-coordinator.sh merge-order 2>&1 || true
|
|
60
|
+
|
|
61
|
+
# Auto-label the PR after creation (called after gh pr create below)
|
|
62
|
+
# bash scripts/pr-coordinator.sh auto-label <issue-id>
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
If merge simulation finds conflicts:
|
|
66
|
+
- Display conflicted files
|
|
67
|
+
- Ask: "Merge conflicts detected with base branch. These PRs should merge first: [list]. Proceed with PR creation anyway? (y/n)"
|
|
68
|
+
- If `n`: exit cleanly
|
|
69
|
+
- If `y`: log override via `bd comments add <id> "Ship override: creating PR despite merge conflicts"`, then continue
|
|
70
|
+
|
|
71
|
+
After PR creation completes:
|
|
72
|
+
```bash
|
|
73
|
+
# Auto-label the newly created PR
|
|
74
|
+
bash scripts/pr-coordinator.sh auto-label <issue-id>
|
|
75
|
+
|
|
76
|
+
# Check for stale worktrees (informational)
|
|
77
|
+
bash scripts/pr-coordinator.sh stale-worktrees 2>&1 || true
|
|
78
|
+
```
|
|
79
|
+
|
|
50
80
|
### Step 3: Update Beads
|
|
51
81
|
```bash
|
|
52
82
|
bd update <id> --status done
|
|
@@ -61,68 +91,86 @@ Use `--force-with-lease` because `/validate` may have rebased the branch, rewrit
|
|
|
61
91
|
git push --force-with-lease -u origin <branch-name>
|
|
62
92
|
```
|
|
63
93
|
|
|
64
|
-
### Step 5: Create PR
|
|
94
|
+
### Step 5: Create PR Using Project's PR Template
|
|
65
95
|
|
|
66
|
-
|
|
96
|
+
**CRITICAL**: Always use the project's own PR template. Never use a hardcoded body.
|
|
67
97
|
|
|
68
|
-
|
|
98
|
+
**Step 5a: Locate the PR template**
|
|
69
99
|
|
|
100
|
+
Check for a PR template in the project (in order of precedence):
|
|
70
101
|
```bash
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
102
|
+
# Check standard locations
|
|
103
|
+
PR_TEMPLATE=""
|
|
104
|
+
for path in .github/pull_request_template.md .github/PULL_REQUEST_TEMPLATE.md docs/pull_request_template.md pull_request_template.md; do
|
|
105
|
+
if [ -f "$path" ]; then
|
|
106
|
+
PR_TEMPLATE="$path"
|
|
107
|
+
break
|
|
108
|
+
fi
|
|
109
|
+
done
|
|
110
|
+
```
|
|
77
111
|
|
|
78
|
-
|
|
79
|
-
[What this PR does to solve it — approach, not implementation details]
|
|
112
|
+
**Step 5b: Read and populate the template**
|
|
80
113
|
|
|
81
|
-
|
|
82
|
-
|
|
114
|
+
If a PR template exists:
|
|
115
|
+
1. **Read the template file** using the Read tool
|
|
116
|
+
2. **Fill in every section** with actual data from the current PR context:
|
|
117
|
+
- Replace HTML comments (`<!-- ... -->`) with real content
|
|
118
|
+
- Check applicable checkboxes (`- [x]`)
|
|
119
|
+
- Fill in beads issue IDs (replace `beads-xxx` with actual ID)
|
|
120
|
+
- Fill in test results, validation status, and other concrete data
|
|
121
|
+
- Reference the design doc: `docs/plans/YYYY-MM-DD-<slug>-design.md`
|
|
122
|
+
3. **Do NOT remove any sections** — fill them all, even if "N/A"
|
|
123
|
+
4. **Do NOT restructure the template** — keep the project's chosen format
|
|
83
124
|
|
|
84
|
-
|
|
85
|
-
|
|
125
|
+
If no PR template exists, use this minimal fallback:
|
|
126
|
+
```
|
|
127
|
+
## Summary
|
|
128
|
+
[1-3 sentences: what this PR does and why]
|
|
86
129
|
|
|
87
|
-
|
|
88
|
-
|
|
130
|
+
## Changes
|
|
131
|
+
[Bulleted list of key changes]
|
|
89
132
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
- Scenarios covered: [list key scenarios]
|
|
133
|
+
## Testing
|
|
134
|
+
[How it was tested, test results]
|
|
93
135
|
|
|
94
|
-
|
|
95
|
-
-
|
|
96
|
-
- Automated scan: [result]
|
|
136
|
+
## Beads
|
|
137
|
+
Closes beads-xxx
|
|
97
138
|
|
|
98
|
-
|
|
99
|
-
|
|
139
|
+
🤖 Generated with [Claude Code](https://claude.com/claude-code)
|
|
140
|
+
```
|
|
100
141
|
|
|
101
|
-
|
|
102
|
-
See: docs/plans/YYYY-MM-DD-<slug>-decisions.md (if any undocumented decisions arose during /dev)
|
|
142
|
+
**Step 5c: Create the PR**
|
|
103
143
|
|
|
104
|
-
|
|
105
|
-
|
|
144
|
+
```bash
|
|
145
|
+
gh pr create --title "<type>: <concise description>" --body "<populated-template-content>"
|
|
146
|
+
```
|
|
106
147
|
|
|
107
|
-
|
|
108
|
-
|
|
148
|
+
Rules for the PR body:
|
|
149
|
+
- **Use the project's template structure** — never substitute your own format
|
|
150
|
+
- **Fill in concrete data** — commit counts, test results, actual file paths, real beads IDs
|
|
151
|
+
- **Check applicable checkboxes** — `[x]` for items that apply, `[ ]` for items that don't
|
|
152
|
+
- **Include "Closes beads-xxx"** in the Beads section (required for auto-close in /verify)
|
|
109
153
|
|
|
110
|
-
###
|
|
111
|
-
|
|
112
|
-
-
|
|
113
|
-
-
|
|
114
|
-
|
|
154
|
+
### Step 6: Validate Context and Record Stage Transition
|
|
155
|
+
```bash
|
|
156
|
+
bash scripts/beads-context.sh validate <id>
|
|
157
|
+
bash scripts/beads-context.sh stage-transition <id> ship review \
|
|
158
|
+
--summary "<PR created, checks pending>" \
|
|
159
|
+
--decisions "<template sections filled, beads linked>" \
|
|
160
|
+
--artifacts "<PR URL, branch name>" \
|
|
161
|
+
--next "<review focus areas>"
|
|
162
|
+
```
|
|
115
163
|
|
|
116
|
-
|
|
164
|
+
### Team sync after PR
|
|
117
165
|
|
|
118
|
-
|
|
119
|
-
EOF
|
|
120
|
-
)"
|
|
121
|
-
```
|
|
166
|
+
After PR is created, sync issue state to GitHub and verify 1:1 mapping:
|
|
122
167
|
|
|
123
|
-
### Step 6: Record Stage Transition
|
|
124
168
|
```bash
|
|
125
|
-
|
|
169
|
+
# Sync issue state to GitHub
|
|
170
|
+
bash scripts/forge-team/index.sh sync 2>&1 || true
|
|
171
|
+
|
|
172
|
+
# Verify 1:1 mapping
|
|
173
|
+
bash scripts/forge-team/index.sh verify 2>&1 || true
|
|
126
174
|
```
|
|
127
175
|
|
|
128
176
|
## Example Output
|
|
@@ -157,9 +205,9 @@ Stage 7: /verify → Post-merge CI check on main
|
|
|
157
205
|
|
|
158
206
|
## Tips
|
|
159
207
|
|
|
160
|
-
- **
|
|
161
|
-
- **
|
|
162
|
-
- **
|
|
163
|
-
- **
|
|
208
|
+
- **Use the project's PR template**: Always read `.github/pull_request_template.md` (or equivalent) and populate it — never substitute your own format
|
|
209
|
+
- **Fill every section**: Even if "N/A" — empty/missing sections cause review friction
|
|
210
|
+
- **Include "Closes beads-xxx"**: Required for auto-close in /verify
|
|
211
|
+
- **Concrete data only**: Test counts, file paths, commit SHAs — not placeholder text
|
|
164
212
|
- **Wait for checks**: Let GitHub Actions, Greptile, SonarCloud run
|
|
165
213
|
- **NO auto-merge**: Always wait for /review phase
|
package/.roo/commands/status.md
CHANGED
|
@@ -25,6 +25,7 @@ bash scripts/sync-utils.sh auto-sync
|
|
|
25
25
|
```
|
|
26
26
|
|
|
27
27
|
### Step 1: Smart Status (ranked issues with conflict detection)
|
|
28
|
+
|
|
28
29
|
```bash
|
|
29
30
|
bash scripts/smart-status.sh
|
|
30
31
|
```
|
|
@@ -32,6 +33,35 @@ This script dynamically computes and displays all issues ranked by composite sco
|
|
|
32
33
|
|
|
33
34
|
For full context on any issue: `bd show <id>`
|
|
34
35
|
|
|
36
|
+
### Step 1b: Reconcile stale in-progress issues
|
|
37
|
+
|
|
38
|
+
Check if any in-progress issues were already merged but not closed (can happen if `/verify` was skipped or backup was restored from stale snapshot):
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
# Detect default branch dynamically (prefer main over master)
|
|
42
|
+
DEFAULT_BRANCH=$(git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's|refs/remotes/origin/||')
|
|
43
|
+
if [ -z "$DEFAULT_BRANCH" ]; then
|
|
44
|
+
if git rev-parse --verify main >/dev/null 2>&1; then DEFAULT_BRANCH="main"
|
|
45
|
+
elif git rev-parse --verify master >/dev/null 2>&1; then DEFAULT_BRANCH="master"
|
|
46
|
+
else echo "ERROR: No main or master branch found — skipping stale reconciliation" >&2; DEFAULT_BRANCH=""; fi
|
|
47
|
+
fi
|
|
48
|
+
|
|
49
|
+
# For each in_progress issue, check if its PR was already merged
|
|
50
|
+
if [ -n "$DEFAULT_BRANCH" ]; then
|
|
51
|
+
bd list --status=in_progress --json 2>/dev/null | jq -r '.[].id' | while read id; do
|
|
52
|
+
# Search git log for the issue ID in commit messages (fixed-strings for literal match)
|
|
53
|
+
if git log --oneline --first-parent "$DEFAULT_BRANCH" --fixed-strings --grep="$id" | grep -q .; then
|
|
54
|
+
echo "STALE: $id — found in git history, likely already merged"
|
|
55
|
+
fi
|
|
56
|
+
done
|
|
57
|
+
fi
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
If stale issues are found, close them:
|
|
61
|
+
```bash
|
|
62
|
+
bd close <id> --force --reason="Already merged — detected during status reconciliation"
|
|
63
|
+
```
|
|
64
|
+
|
|
35
65
|
### Step 2: Review Recent Commits
|
|
36
66
|
```bash
|
|
37
67
|
git log --oneline -10
|
|
@@ -42,6 +72,18 @@ git log --oneline -10
|
|
|
42
72
|
- **Continuing work**: In-progress issues found, resume where left off
|
|
43
73
|
- **Review needed**: Work marked complete, needs review/merge
|
|
44
74
|
|
|
75
|
+
### Team context
|
|
76
|
+
|
|
77
|
+
Show current developer's active work and team overview:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
# Show my active issues
|
|
81
|
+
bash scripts/forge-team/index.sh workload --me 2>&1 || true
|
|
82
|
+
|
|
83
|
+
# One-line team summary
|
|
84
|
+
bash scripts/forge-team/index.sh dashboard 2>&1 | head -5 || true
|
|
85
|
+
```
|
|
86
|
+
|
|
45
87
|
## Next Steps
|
|
46
88
|
|
|
47
89
|
- **If starting new work**: Run `/plan <feature-name>`
|
|
@@ -229,7 +229,13 @@ until ALL FOUR show fresh output in this session:
|
|
|
229
229
|
"Should pass", "was passing earlier", and "I'm confident" are not evidence.
|
|
230
230
|
Run the commands. Show the output. THEN declare done.
|
|
231
231
|
|
|
232
|
-
5.
|
|
232
|
+
5. Context check: Run `bash scripts/beads-context.sh validate <id>` and address any warnings
|
|
233
|
+
6. Stage transition: Run the following → exit 0 confirmed:
|
|
234
|
+
bash scripts/beads-context.sh stage-transition <id> validate ship \
|
|
235
|
+
--summary "<all checks pass/fail summary>" \
|
|
236
|
+
--decisions "<any failures diagnosed and fixed>" \
|
|
237
|
+
--artifacts "<scripts and commands run>" \
|
|
238
|
+
--next "<ship readiness notes>"
|
|
233
239
|
</HARD-GATE>
|
|
234
240
|
```
|
|
235
241
|
|
package/.roo/commands/verify.md
CHANGED
|
@@ -146,19 +146,67 @@ Branch: <branch-name> deleted ✓
|
|
|
146
146
|
bd create --title="Post-merge: <description of issue>" --type=bug --priority=1
|
|
147
147
|
```
|
|
148
148
|
|
|
149
|
-
### Step 8: Close Beads
|
|
149
|
+
### Step 8: Close Beads Issues (if healthy)
|
|
150
150
|
|
|
151
|
-
If everything is clean, close
|
|
151
|
+
If everything is clean, close all Beads issues referenced in the merged PR.
|
|
152
|
+
|
|
153
|
+
**Auto-detect beads issues from PR body and branch name:**
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
# Get PR body and branch name
|
|
157
|
+
PR_BODY=$(gh pr view <number> --json body --jq '.body')
|
|
158
|
+
PR_BRANCH=$(gh pr view <number> --json headRefName --jq '.headRefName')
|
|
159
|
+
|
|
160
|
+
# Extract beads IDs from PR body (matches "Closes beads-xxx", "closes forge-xxx", etc.)
|
|
161
|
+
# Patterns: "Closes <prefix>-<id>", "Fixes <prefix>-<id>", "Resolves <prefix>-<id>"
|
|
162
|
+
BEADS_IDS=$(echo "$PR_BODY" | grep -oiE '(closes|fixes|resolves):?\s+[a-z]+-[a-z0-9]+' | grep -oiE '[a-z]+-[a-z0-9]{3,6}$')
|
|
163
|
+
|
|
164
|
+
# Validate each ID exists in beads
|
|
165
|
+
VALID_IDS=""
|
|
166
|
+
for id in $BEADS_IDS; do
|
|
167
|
+
if bd show "$id" >/dev/null 2>&1; then
|
|
168
|
+
VALID_IDS="$VALID_IDS $id"
|
|
169
|
+
fi
|
|
170
|
+
done
|
|
171
|
+
BEADS_IDS="$VALID_IDS"
|
|
172
|
+
|
|
173
|
+
# Also check branch name for beads ID — extract segment after last /
|
|
174
|
+
# then validate with bd show to avoid false matches like "pr-templa"
|
|
175
|
+
BRANCH_SLUG=$(echo "$PR_BRANCH" | sed 's|.*/||')
|
|
176
|
+
BRANCH_ID=$(echo "$BRANCH_SLUG" | grep -oE '[a-z]+-[a-z0-9]{3,6}' | head -1)
|
|
177
|
+
if [ -n "$BRANCH_ID" ] && ! bd show "$BRANCH_ID" >/dev/null 2>&1; then
|
|
178
|
+
BRANCH_ID="" # Not a valid beads ID — discard
|
|
179
|
+
fi
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
**Close each matched issue:**
|
|
152
183
|
|
|
153
184
|
```bash
|
|
154
|
-
|
|
185
|
+
# Close issues found in PR body
|
|
186
|
+
for id in $BEADS_IDS; do
|
|
187
|
+
bd close "$id" --reason="Merged and verified on master (PR #<number>)" 2>&1 || echo "Warning: could not close $id"
|
|
188
|
+
done
|
|
189
|
+
|
|
190
|
+
# If no issues found in body, try branch name match (skip if already closed above)
|
|
191
|
+
if [ -z "$BEADS_IDS" ] && [ -n "$BRANCH_ID" ]; then
|
|
192
|
+
bd close "$BRANCH_ID" --reason="Merged and verified on master (PR #<number>)" 2>&1 || echo "Warning: could not close $BRANCH_ID"
|
|
193
|
+
elif [ -n "$BRANCH_ID" ] && ! echo "$BEADS_IDS" | grep -qw "$BRANCH_ID"; then
|
|
194
|
+
bd close "$BRANCH_ID" --reason="Merged and verified on master (PR #<number>)" 2>&1 || echo "Warning: could not close $BRANCH_ID"
|
|
195
|
+
fi
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
**If no beads issues detected at all**, prompt the user:
|
|
199
|
+
```
|
|
200
|
+
⚠ No beads issue ID found in PR body or branch name.
|
|
201
|
+
If this PR closes a beads issue, run: bd close <id> --reason="Merged and verified on master (PR #<number>)"
|
|
155
202
|
```
|
|
156
203
|
|
|
157
204
|
```
|
|
158
205
|
<HARD-GATE: /verify exit>
|
|
159
206
|
Do NOT declare /verify complete until:
|
|
160
207
|
1. gh run list --branch master --limit 3 shows actual CI output (not "should be fine")
|
|
161
|
-
2. If healthy: Beads
|
|
208
|
+
2. If healthy: Beads issues extracted from PR body/branch and closed (bd close run and confirmed)
|
|
209
|
+
- If no beads ID found: user was warned and given manual close command
|
|
162
210
|
3. If issues found: Beads tracking issue created for every problem
|
|
163
211
|
4. Worktree removed (or confirmed already gone) — OR Step 6 was intentionally skipped because CI was unhealthy; if skipped, state explicitly: "cleanup deferred, CI was not healthy"
|
|
164
212
|
"It should be fine" is not evidence. Run the command. Show the output.
|
package/AGENTS.md
CHANGED
|
@@ -173,3 +173,100 @@ Task 2: Validation logic
|
|
|
173
173
|
- [docs/VALIDATION.md](docs/VALIDATION.md) - Enforcement and validation details
|
|
174
174
|
|
|
175
175
|
**Load these files when you need detailed instructions for a specific stage.**
|
|
176
|
+
|
|
177
|
+
## Descriptive Context Convention
|
|
178
|
+
|
|
179
|
+
Every stage transition should carry structured context so the next stage (or a new session) can resume without re-reading the full design doc. This convention is **advisory** — warnings are informational, not blocking.
|
|
180
|
+
|
|
181
|
+
### Required Fields at Each Stage Exit
|
|
182
|
+
|
|
183
|
+
| Stage Exit | Summary | Decisions | Artifacts | Next |
|
|
184
|
+
|------------|---------|-----------|-----------|------|
|
|
185
|
+
| /plan | Design approach chosen | Key trade-offs resolved | Design doc, task list paths | First dev task focus |
|
|
186
|
+
| /dev | Tasks completed, gate count | Spec gaps encountered | Changed files, test files | Validation priorities |
|
|
187
|
+
| /validate | All checks pass/fail summary | Failures diagnosed | Scripts/commands run | Ship readiness |
|
|
188
|
+
| /ship | PR created, checks pending | Template sections filled | PR URL, branch name | Review focus areas |
|
|
189
|
+
| /review | All feedback addressed | Comment resolutions | Fixed files, commit SHAs | Doc update needs |
|
|
190
|
+
| /premerge | Docs updated, CI green | N/A | Updated doc files | Merge instructions |
|
|
191
|
+
|
|
192
|
+
### Validation Command
|
|
193
|
+
|
|
194
|
+
Run at each stage exit to check for missing context:
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
bash scripts/beads-context.sh validate <beads-issue-id>
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
This checks: (1) issue has a description, (2) at least one stage transition exists, (3) most recent transition has a summary, (4) design metadata is set if past the plan stage. Exits 0 when context checks run (even if warnings are found); exits 1 only if the issue cannot be retrieved.
|
|
201
|
+
|
|
202
|
+
### Field Definitions
|
|
203
|
+
|
|
204
|
+
- **Summary**: 1-2 sentence recap of what was accomplished in this stage. Example: `--summary "All 5 tasks done, 1 decision gate fired"`
|
|
205
|
+
- **Decisions**: Key choices made during this stage that affect downstream work. Example: `--decisions "Used streaming parser over DOM for memory efficiency"`
|
|
206
|
+
- **Artifacts**: File paths or URLs produced by this stage. Example: `--artifacts "lib/parser.js test/parser.test.js docs/plans/2026-03-26-parser-design.md"`
|
|
207
|
+
- **Next**: Guidance for the next stage on what to focus on. Example: `--next "Run lint first — streaming approach may trigger no-await rule"`
|
|
208
|
+
|
|
209
|
+
### Usage in Stage Transitions
|
|
210
|
+
|
|
211
|
+
```bash
|
|
212
|
+
# Basic (backward compatible)
|
|
213
|
+
bash scripts/beads-context.sh stage-transition <id> dev validate
|
|
214
|
+
|
|
215
|
+
# With context fields (recommended)
|
|
216
|
+
bash scripts/beads-context.sh stage-transition <id> dev validate \
|
|
217
|
+
--summary "All 5 tasks done, 0 gates fired" \
|
|
218
|
+
--decisions "Used approach A per design doc" \
|
|
219
|
+
--artifacts "lib/foo.js test/foo.test.js" \
|
|
220
|
+
--next "Run type check and lint"
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
### Enforcement Level
|
|
224
|
+
|
|
225
|
+
This convention is **advisory only**. The `validate` subcommand prints warnings but always exits 0. It does not block any stage transition. The goal is to build good habits, not to create friction.
|
|
226
|
+
|
|
227
|
+
<!-- BEGIN BEADS INTEGRATION v:1 profile:minimal hash:ca08a54f -->
|
|
228
|
+
## Beads Issue Tracker
|
|
229
|
+
|
|
230
|
+
This project uses **bd (beads)** for issue tracking. Run `bd prime` to see full workflow context and commands.
|
|
231
|
+
|
|
232
|
+
### Quick Reference
|
|
233
|
+
|
|
234
|
+
```bash
|
|
235
|
+
bd ready # Find available work
|
|
236
|
+
bd show <id> # View issue details
|
|
237
|
+
bd update <id> --claim # Claim work
|
|
238
|
+
bd close <id> # Complete work
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
### Rules
|
|
242
|
+
|
|
243
|
+
- Use `bd` for ALL task tracking — do NOT use TodoWrite, TaskCreate, or markdown TODO lists. Exception: `/plan` Phase 3 generates task lists at `docs/plans/YYYY-MM-DD-<slug>-tasks.md` — these are approved artifacts consumed by `/dev`, but `bd` remains the source of truth for issue state. GitHub issues may be used for external/public tracking; CI may sync GitHub issue lifecycle to Beads (see `docs/BEADS_GITHUB_SYNC.md`).
|
|
244
|
+
- Run `bd prime` for detailed command reference and session close protocol
|
|
245
|
+
- Use `bd remember` for persistent knowledge — do NOT use MEMORY.md files
|
|
246
|
+
|
|
247
|
+
## Session Completion
|
|
248
|
+
|
|
249
|
+
**When ending a work session**, you MUST complete ALL steps below. Work is NOT complete until `git push` succeeds.
|
|
250
|
+
|
|
251
|
+
**MANDATORY WORKFLOW:**
|
|
252
|
+
|
|
253
|
+
1. **File issues for remaining work** - Create issues for anything that needs follow-up
|
|
254
|
+
2. **Run quality gates** (if code changed) - Tests, linters, builds
|
|
255
|
+
3. **Update issue status** - Close finished work, update in-progress items
|
|
256
|
+
4. **PUSH TO REMOTE** - This is MANDATORY:
|
|
257
|
+
```bash
|
|
258
|
+
git pull --rebase
|
|
259
|
+
bd dolt push # requires Dolt-backed Beads — run 'bd init' if missing
|
|
260
|
+
git push
|
|
261
|
+
git status # MUST show "up to date with origin"
|
|
262
|
+
```
|
|
263
|
+
5. **Clean up** - Clear stashes, prune remote branches
|
|
264
|
+
6. **Verify** - All changes committed AND pushed
|
|
265
|
+
7. **Hand off** - Provide context for next session
|
|
266
|
+
|
|
267
|
+
**CRITICAL RULES:**
|
|
268
|
+
- Work is NOT complete until `git push` succeeds
|
|
269
|
+
- NEVER stop before pushing - that leaves work stranded locally
|
|
270
|
+
- NEVER say "ready to push when you are" - YOU must push
|
|
271
|
+
- If push fails, resolve and retry until it succeeds
|
|
272
|
+
<!-- END BEADS INTEGRATION -->
|
package/CLAUDE.md
CHANGED
|
@@ -80,6 +80,16 @@ git commit --no-verify # Skip pre-commit hooks
|
|
|
80
80
|
|
|
81
81
|
**⚠️ AI agents must NEVER use `LEFTHOOK=0`, `--no-verify`, or any hook bypass.** If a hook fails, fix the underlying issue. Only humans may bypass hooks in emergencies, documented in the PR description.
|
|
82
82
|
|
|
83
|
+
**Preferred push workflow** (for AI agents and humans):
|
|
84
|
+
```bash
|
|
85
|
+
forge push # Runs branch protection + lint + tests, then pushes
|
|
86
|
+
forge push --quick # Review-cycle: lint-only push (CI runs full suite)
|
|
87
|
+
forge worktree create <slug> # Creates worktree with Beads integration
|
|
88
|
+
forge test # Runs tests with correct timeouts + Beads skip
|
|
89
|
+
forge sync # Syncs Beads data (dolt pull + push)
|
|
90
|
+
forge clean # Removes merged worktrees (stops Dolt servers)
|
|
91
|
+
```
|
|
92
|
+
|
|
83
93
|
See [.github/pull_request_template.md](.github/pull_request_template.md) for PR guidelines.
|
|
84
94
|
|
|
85
95
|
---
|
package/README.md
CHANGED
|
@@ -222,8 +222,8 @@ bunx forge setup --merge=smart # Intelligent merge
|
|
|
222
222
|
- Infers project stage (new, active, stable)
|
|
223
223
|
- Saves to `.forge/context.json`
|
|
224
224
|
|
|
225
|
-
**Workflow Profiles**
|
|
226
|
-
-
|
|
225
|
+
**Workflow Profiles** *(planned — not yet wired into setup)*
|
|
226
|
+
- Will adapt workflow based on work type (3-8 stages):
|
|
227
227
|
- `critical`: Full 8-stage workflow (auth, payments, security-sensitive)
|
|
228
228
|
- `standard`: 7-stage workflow (typical features)
|
|
229
229
|
- `refactor`: Behavior-preserving 5-stage workflow
|
package/bin/forge-cmd.js
CHANGED
|
@@ -223,7 +223,11 @@ async function main() { // NOSONAR S3776
|
|
|
223
223
|
const context = {
|
|
224
224
|
branch,
|
|
225
225
|
researchDoc: fs.existsSync('docs/research') ? fs.readdirSync('docs/research').find(f => f.endsWith('.md')) : null,
|
|
226
|
-
plan:
|
|
226
|
+
plan: (() => {
|
|
227
|
+
if (!fs.existsSync('docs/plans')) return null;
|
|
228
|
+
const slug = branch.replace(/^(feat|fix|docs|refactor)\//, '');
|
|
229
|
+
return fs.readdirSync('docs/plans').find(f => f.endsWith('.md') && f.includes(slug)) || null;
|
|
230
|
+
})(),
|
|
227
231
|
tests: (() => { try { return fs.readdirSync('test').filter(f => f.endsWith('.test.js')); } catch (error_) { void error_; return []; } })(), // NOSONAR S2486 - intentional: missing test dir
|
|
228
232
|
};
|
|
229
233
|
const stageResult = HANDLERS.status.detectStage(context);
|
package/bin/forge-preflight.js
CHANGED
|
@@ -199,8 +199,21 @@ function validateShip() {
|
|
|
199
199
|
check(
|
|
200
200
|
"Tests pass",
|
|
201
201
|
() => {
|
|
202
|
+
// Detect package manager from lock files (same heuristic as forge.js)
|
|
203
|
+
let cmd = "npm";
|
|
204
|
+
let cmdArgs = ["run", "test"];
|
|
205
|
+
if (fs.existsSync("bun.lockb") || fs.existsSync("bun.lock")) {
|
|
206
|
+
cmd = "bun";
|
|
207
|
+
cmdArgs = ["run", "test"];
|
|
208
|
+
} else if (fs.existsSync("pnpm-lock.yaml")) {
|
|
209
|
+
cmd = "pnpm";
|
|
210
|
+
cmdArgs = ["run", "test"];
|
|
211
|
+
} else if (fs.existsSync("yarn.lock")) {
|
|
212
|
+
cmd = "yarn";
|
|
213
|
+
cmdArgs = ["run", "test"];
|
|
214
|
+
}
|
|
202
215
|
try {
|
|
203
|
-
execFileSync(
|
|
216
|
+
execFileSync(cmd, cmdArgs, { stdio: "pipe" });
|
|
204
217
|
return true;
|
|
205
218
|
} catch (err) {
|
|
206
219
|
const output = ((err.stdout || "") + "\n" + (err.stderr || "")).trim();
|
|
@@ -210,7 +223,7 @@ function validateShip() {
|
|
|
210
223
|
return false;
|
|
211
224
|
}
|
|
212
225
|
},
|
|
213
|
-
"Tests are failing. Fix them before shipping
|
|
226
|
+
"Tests are failing. Fix them before shipping.",
|
|
214
227
|
);
|
|
215
228
|
|
|
216
229
|
check(
|