forgedock 1.0.21 → 1.1.1
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/README.md +227 -174
- package/bin/cinema.mjs +320 -0
- package/bin/demo.mjs +386 -0
- package/bin/engine/phases.mjs +148 -0
- package/bin/engine/projector.mjs +32 -0
- package/bin/engine/reconcile.mjs +11 -0
- package/bin/engine/runlog.mjs +79 -0
- package/bin/engine/state.mjs +27 -0
- package/bin/engine-cli.mjs +50 -0
- package/bin/engine.mjs +138 -0
- package/bin/forgedock.mjs +693 -1393
- package/bin/init-detect.mjs +95 -0
- package/bin/journey.mjs +783 -0
- package/bin/runner.mjs +847 -0
- package/bin/settings-hook.mjs +112 -0
- package/bin/tui.mjs +6 -3
- package/commands/autopilot.md +4 -4
- package/commands/cleanup.md +85 -39
- package/commands/deploy-info.md +11 -5
- package/commands/design-bench.md +1 -0
- package/commands/design-render-critique-loop.md +1 -0
- package/commands/design.md +1 -0
- package/commands/forge-stats.md +2 -1
- package/commands/issue.md +1 -1
- package/commands/optimize.md +1 -1
- package/commands/orchestrate.md +346 -34
- package/commands/quality-gate.md +168 -80
- package/commands/review-pr-agents.md +69 -45
- package/commands/review-pr.md +54 -6
- package/commands/scope.md +11 -3
- package/commands/security-audit.md +24 -16
- package/commands/sync-ecosystem.md +2 -2
- package/commands/work-on/build/architect.md +47 -3
- package/commands/work-on/build/context.md +36 -5
- package/commands/work-on/build/implement.md +16 -4
- package/commands/work-on/build/validate.md +54 -8
- package/commands/work-on/build.md +27 -9
- package/commands/work-on/close.md +131 -3
- package/commands/work-on/investigate.md +24 -1
- package/commands/work-on/review.md +24 -0
- package/commands/work-on-monolithic.md +1 -0
- package/commands/work-on.md +271 -11
- package/docs/BRAND.md +6 -2
- package/docs/CONFIG.md +39 -34
- package/docs/site/.vitepress/config.mjs +85 -0
- package/docs/site/annotations-explained.md +55 -0
- package/docs/site/command-learning-path.md +104 -0
- package/docs/site/command-reference.md +3 -0
- package/docs/site/getting-started.md +42 -13
- package/docs/site/index.md +1 -1
- package/docs/site/troubleshooting.md +208 -0
- package/docs/spec/forge-protocol-v1.md +768 -0
- package/docs/superpowers/plans/2026-07-03-cinematic-onboarding-tui.md +2339 -0
- package/docs/superpowers/plans/2026-07-03-durable-execution-engine.md +1223 -0
- package/docs/superpowers/specs/2026-07-03-cinematic-onboarding-tui-design.md +157 -0
- package/docs/superpowers/specs/2026-07-03-durable-execution-engine-design.md +194 -0
- package/examples/forgedock-demo/README.md +113 -0
- package/examples/forgedock-demo/bootstrap.sh +125 -0
- package/examples/forgedock-demo/issues/01-bug-delete-missing-auth.md +37 -0
- package/examples/forgedock-demo/issues/02-feature-filter-notes.md +37 -0
- package/examples/forgedock-demo/issues/03-refactor-router-table.md +33 -0
- package/examples/forgedock-demo/issues/04-perf-index-lookup.md +35 -0
- package/examples/forgedock-demo/issues/05-docs-api-reference.md +39 -0
- package/examples/forgedock-demo/labels.json +21 -0
- package/examples/forgedock-demo/package.json +16 -0
- package/examples/forgedock-demo/scripts/smoke.js +61 -0
- package/examples/forgedock-demo/src/auth.js +28 -0
- package/examples/forgedock-demo/src/db.js +66 -0
- package/examples/forgedock-demo/src/routes/notes.js +64 -0
- package/examples/forgedock-demo/src/server.js +79 -0
- package/package.json +13 -3
- package/scripts/verify-env-vars.sh +18 -2
- package/scripts/verify-host-headers.sh +4 -4
- package/scripts/verify-route-registration.sh +2 -2
- package/scripts/worktree-lifecycle.sh +202 -0
- package/templates/forge.yaml.minimal +44 -0
|
@@ -81,6 +81,30 @@ Do NOT push this branch. Human review required to identify the source of the mer
|
|
|
81
81
|
fi
|
|
82
82
|
```
|
|
83
83
|
|
|
84
|
+
## Phase R1: Non-Empty Commit Guard (MANDATORY — run before push) <!-- Added: forge#1305 -->
|
|
85
|
+
|
|
86
|
+
Before pushing, verify the branch has at least one commit ahead of the PR base. This is the last-line defense against the phantom-commit hazard: a session that resumed from a partial FORGE:BUILDER comment (without `:COMPLETE`) would have skipped the commit step and could otherwise push an empty branch.
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
cd {WORKTREE_PATH}
|
|
90
|
+
# Count commits on this branch that are not reachable from origin/{PR_BASE}
|
|
91
|
+
COMMIT_COUNT=$(git rev-list --count HEAD ^origin/{PR_BASE} 2>/dev/null || echo "0")
|
|
92
|
+
if [ "$COMMIT_COUNT" -eq 0 ]; then
|
|
93
|
+
gh issue comment {NUMBER} {GH_FLAG} --body "## Push Blocked — No Commits Ahead of Base
|
|
94
|
+
|
|
95
|
+
Branch \`{BRANCH}\` has 0 commits ahead of \`origin/{PR_BASE}\`. Pushing this branch would create an empty PR.
|
|
96
|
+
|
|
97
|
+
**Likely cause**: Build was interrupted after the FORGE:BUILDER comment was posted (implement.md Phase I6) but before the commit was created (validate.md Phase V5). The branch was pushed with no implementation on it.
|
|
98
|
+
|
|
99
|
+
**Resolution**: Delete this branch, re-run \`/work-on {NUMBER}\` to restart the build phase. The partial FORGE:BUILDER comment (lacking \`FORGE:BUILDER:COMPLETE\`) will be detected and deleted, and the build will restart cleanly.
|
|
100
|
+
|
|
101
|
+
<!-- FORGE:PUSH_BLOCKED_EMPTY_BRANCH -->"
|
|
102
|
+
gh issue edit {NUMBER} {GH_FLAG} --add-label "needs-human"
|
|
103
|
+
exit 1
|
|
104
|
+
fi
|
|
105
|
+
echo "Commit count ahead of origin/{PR_BASE}: $COMMIT_COUNT — OK to push"
|
|
106
|
+
```
|
|
107
|
+
|
|
84
108
|
## Phase R1: Push Branch
|
|
85
109
|
|
|
86
110
|
```bash
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
description: "[BENCHMARK] Monolithic work-on — single-prompt pipeline with no Skill sub-phase boundaries"
|
|
3
3
|
argument-hint: [issue number]
|
|
4
|
+
install: internal
|
|
4
5
|
---
|
|
5
6
|
<!-- SPDX-FileCopyrightText: Copyright (c) RapierCraft Studios -->
|
|
6
7
|
<!-- SPDX-License-Identifier: AGPL-3.0-or-later -->
|
package/commands/work-on.md
CHANGED
|
@@ -96,6 +96,74 @@ Satellite repos (those without a `staging` branch) receive fast-lane PRs directl
|
|
|
96
96
|
|
|
97
97
|
## Phase 0: Resolve Issue & Load Context
|
|
98
98
|
|
|
99
|
+
### 0.0: Pre-Flight Checks (MANDATORY — run before any other Phase 0 step)
|
|
100
|
+
|
|
101
|
+
Validate the environment before the pipeline spends tokens. Each check fails fast with an actionable error and a pointer to the troubleshooting guide (`docs/site/troubleshooting.md`). Run all checks; report every failure, then STOP if any HARD check fails. <!-- Added: forge#1149 -->
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
PREFLIGHT_FAILED=0
|
|
105
|
+
|
|
106
|
+
# Check 1 — forge.yaml present (HARD)
|
|
107
|
+
if [ ! -f forge.yaml ]; then
|
|
108
|
+
echo "ERROR: forge.yaml not found in the repository root."
|
|
109
|
+
echo " Fix: run \`npx forgedock init\` to generate one, or copy forge.yaml.example."
|
|
110
|
+
echo " See: docs/site/troubleshooting.md#1-forgeyaml-not-found"
|
|
111
|
+
PREFLIGHT_FAILED=1
|
|
112
|
+
fi
|
|
113
|
+
|
|
114
|
+
# Check 2 — yq installed; forge.yaml is valid YAML (HARD, only if present)
|
|
115
|
+
if [ -f forge.yaml ]; then
|
|
116
|
+
if ! command -v yq >/dev/null 2>&1; then
|
|
117
|
+
echo "ERROR: yq is not installed. The pipeline requires yq to parse forge.yaml."
|
|
118
|
+
echo " Fix: install yq — https://github.com/mikefarah/yq#install"
|
|
119
|
+
echo " See: docs/site/troubleshooting.md#2-forgeyaml-has-a-syntax-error"
|
|
120
|
+
PREFLIGHT_FAILED=1
|
|
121
|
+
elif ! yq '.' forge.yaml >/dev/null 2>&1; then
|
|
122
|
+
echo "ERROR: forge.yaml has a YAML syntax error."
|
|
123
|
+
echo " Fix: run \`yq '.' forge.yaml\` to locate the offending line, then correct the indentation/quoting."
|
|
124
|
+
echo " See: docs/site/troubleshooting.md#2-forgeyaml-has-a-syntax-error"
|
|
125
|
+
PREFLIGHT_FAILED=1
|
|
126
|
+
fi
|
|
127
|
+
fi
|
|
128
|
+
|
|
129
|
+
# Check 3 — gh CLI authenticated (HARD)
|
|
130
|
+
if ! gh auth status >/dev/null 2>&1; then
|
|
131
|
+
echo "ERROR: gh CLI is not authenticated. The pipeline cannot read or write GitHub state."
|
|
132
|
+
echo " Fix: run \`gh auth login\` (ensure repo scope), then \`gh auth status\` to confirm."
|
|
133
|
+
echo " See: docs/site/troubleshooting.md#3-gh-cli-not-authenticated"
|
|
134
|
+
PREFLIGHT_FAILED=1
|
|
135
|
+
fi
|
|
136
|
+
|
|
137
|
+
# Check 4 — workflow labels exist on the repo (SOFT — warn, auto-recoverable)
|
|
138
|
+
if [ -f forge.yaml ] && gh auth status >/dev/null 2>&1; then
|
|
139
|
+
GH_REPO_PF="$(yq -r '.project.owner + "/" + .project.repo' forge.yaml 2>/dev/null)"
|
|
140
|
+
if [ -n "$GH_REPO_PF" ] && ! gh label list -R "$GH_REPO_PF" --search "workflow:" 2>/dev/null | grep -q "workflow:"; then
|
|
141
|
+
echo "WARNING: ForgeDock workflow:* labels not found on $GH_REPO_PF."
|
|
142
|
+
echo " Fix: run \`npx forgedock labels setup\` (or \`--repo $GH_REPO_PF\`) to bootstrap them."
|
|
143
|
+
echo " See: docs/site/troubleshooting.md#9-missing-workflow-labels"
|
|
144
|
+
fi
|
|
145
|
+
fi
|
|
146
|
+
|
|
147
|
+
# Check 5 — GitHub API rate limit headroom (SOFT — warn)
|
|
148
|
+
if gh auth status >/dev/null 2>&1; then
|
|
149
|
+
RL_REMAINING="$(gh api rate_limit --jq '.resources.core.remaining' 2>/dev/null || echo '')"
|
|
150
|
+
if [ -n "$RL_REMAINING" ] && [ "$RL_REMAINING" -lt 100 ] 2>/dev/null; then
|
|
151
|
+
RL_RESET="$(gh api rate_limit --jq '.resources.core.reset' 2>/dev/null)"
|
|
152
|
+
echo "WARNING: GitHub API rate limit low ($RL_REMAINING remaining; resets at epoch $RL_RESET)."
|
|
153
|
+
echo " Fix: wait for the reset, reduce orchestration parallelism, or use a higher-limit PAT."
|
|
154
|
+
echo " See: docs/site/troubleshooting.md#10-github-api-rate-limit-exceeded"
|
|
155
|
+
fi
|
|
156
|
+
fi
|
|
157
|
+
|
|
158
|
+
if [ "$PREFLIGHT_FAILED" -eq 1 ]; then
|
|
159
|
+
echo "Pre-flight checks failed. Resolve the errors above and re-run /work-on {NUMBER}."
|
|
160
|
+
echo "Full recovery guide: docs/site/troubleshooting.md"
|
|
161
|
+
exit 1
|
|
162
|
+
fi
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Worktree/branch-already-exists and stale-label conditions are surfaced later (Phase 3E worktree creation and the `## Error Handling` section) with their own recovery guidance in `docs/site/troubleshooting.md`.
|
|
166
|
+
|
|
99
167
|
### 0A: Parse input
|
|
100
168
|
Extract project prefix and issue number. If `next`/`pick`: list open issues sorted by priority, skip `needs-human` and `workflow:decomposed`, pick highest priority.
|
|
101
169
|
|
|
@@ -424,7 +492,16 @@ Use `forge.yaml → review.tech_stack` and the issue domain labels to identify e
|
|
|
424
492
|
grep -rn '\.field_name\s*=' services/ # Attribute assignments
|
|
425
493
|
```
|
|
426
494
|
If the field is written with different types in different code paths (e.g. dict in the standard path, string in the auth-gated path), document ALL variants. The fix must handle every variant — not just the one on the primary investigated code path. A type guard like `or {}` only protects against falsy values; a non-empty string is truthy and bypasses it.
|
|
427
|
-
4. Git blame — trace when/why the relevant code was written
|
|
495
|
+
4. Git blame — trace when/why the relevant code was written. Run bounded, local commands (no network round-trip):
|
|
496
|
+
```bash
|
|
497
|
+
# Introducing commit for each affected file (first commit that added it)
|
|
498
|
+
git log --reverse --format='%h %an %ad %s' --date=short -- {affected_file} | head -1
|
|
499
|
+
# Last-touch commit (most recent change)
|
|
500
|
+
git log -1 --format='%h %an %ad %s' --date=short -- {affected_file}
|
|
501
|
+
# Line-level blame for a specific suspect hunk, if the issue names one
|
|
502
|
+
git blame -L {start},{end} -- {affected_file}
|
|
503
|
+
```
|
|
504
|
+
Record the introducing commit and last-touch commit for each primary affected file — this feeds the mandatory **History findings** field in Phase 1C.
|
|
428
505
|
4.5. **Rogue commit pre-state comparison (conditional)**: If the issue body references a specific commit as rogue, bad, or unintended (e.g., "rogue commit `abc1234`", "bad commit", "this was never intended"), MUST run `git show {commit}^:{file}` to see the file before that commit. Compare the pre-commit state against the current file. Any block present in the current file but absent in the pre-commit state was introduced by that commit chain and is a candidate for full reversion — not just partial editing. Report the delta (pre vs. current) in the investigation report. Do NOT assume surrounding code near a named import/bug is correct simply because the issue only named a specific sub-problem. (Ref: forge#278 — investigator confirmed the broken import but never ran `git show 18a3a2cf3^:batch.py`; the surrounding 50-line feature gate was also rogue and was preserved by the fix PR, causing a P1 access regression for all non-Scale users)
|
|
429
506
|
5. Domain context discovery (narrow scope only, 1–5 files):
|
|
430
507
|
```bash
|
|
@@ -432,6 +509,14 @@ Use `forge.yaml → review.tech_stack` and the issue domain labels to identify e
|
|
|
432
509
|
gh issue list -R {GH_REPO} --state closed --limit 8 --search "{function_name}"
|
|
433
510
|
```
|
|
434
511
|
Keep only file/function-level overlap. Max 5 related issues.
|
|
512
|
+
|
|
513
|
+
**Pickaxe pass (prior fix / regression detection)** — bounded to one pass, capped at 5 hits: search for prior additions/removals of the suspected symbol or literal string named in the issue, independent of whether that fix was ever linked to a filed issue:
|
|
514
|
+
```bash
|
|
515
|
+
git log -S"{suspected_symbol_or_string}" --oneline -- {affected_files} | head -5
|
|
516
|
+
# Use -G instead of -S when the target is a regex pattern rather than a literal string
|
|
517
|
+
git log -G"{pattern}" --oneline -- {affected_files} | head -5
|
|
518
|
+
```
|
|
519
|
+
Any hit here is a candidate prior fix or reintroduced defect — read the commit body (`git show {hash}`) to confirm before citing it. Feed confirmed hits into the History findings field and let them inform the verdict (e.g. a defect being reintroduced raises severity).
|
|
435
520
|
6. Determine root cause
|
|
436
521
|
7. Identify affected files — full list of files that need changes
|
|
437
522
|
7.5. **Sibling Pattern Sweep** *(conditional — when the bug is a condition, gated function call, or field presence check)*: After identifying the affected files, grep for the same pattern in sibling files within the same directory. The issue spec may name only the file where the error was first observed — but the same commit or PR that introduced the bug often applied it uniformly across related handlers.
|
|
@@ -475,6 +560,12 @@ gh issue comment {NUMBER} {GH_FLAG} --body "<!-- FORGE:INVESTIGATOR -->
|
|
|
475
560
|
### Evidence
|
|
476
561
|
{specific findings — function names, line numbers, behavior observed}
|
|
477
562
|
|
|
563
|
+
### History Findings
|
|
564
|
+
**Introducing commit**: {hash — author — date — subject, per primary affected file}
|
|
565
|
+
**Last touched**: {hash — author — date — subject}
|
|
566
|
+
**Pickaxe hits (prior fixes / regressions)**: {commit(s) found via \`git log -S\`/\`-G\`, or 'None found' — max 5}
|
|
567
|
+
{This field is MANDATORY — populate from the git blame + pickaxe commands in step 4/5. If a file is newly created (no history), write 'New file — no history.'}
|
|
568
|
+
|
|
478
569
|
### Recommendation
|
|
479
570
|
{what to build/fix, concrete and actionable}
|
|
480
571
|
|
|
@@ -744,7 +835,17 @@ esac
|
|
|
744
835
|
|
|
745
836
|
<!-- FORGE:PHASE_COMPLETE — Entering Phase 3 (Build). See Universal Phase Dispatcher: sub-phases 3A–3M execute in sequence. No sub-phase completion is terminal. -->
|
|
746
837
|
|
|
747
|
-
**Skip if**: `<!-- FORGE:BUILDER -->`
|
|
838
|
+
**Skip if**: `<!-- FORGE:BUILDER:COMPLETE -->` is present in a BUILDER comment. <!-- Added: forge#1305 — require completion marker, not mere presence of BUILDER annotation -->
|
|
839
|
+
|
|
840
|
+
**Partial build detection**: If `<!-- FORGE:BUILDER -->` exists BUT `<!-- FORGE:BUILDER:COMPLETE -->` is ABSENT → the build was interrupted after implement.md Phase I6 (comment posted) but before validate.md Phase V5 (commit). Delete the partial comment and restart Phase 3 from the top: <!-- Added: forge#1305 -->
|
|
841
|
+
```bash
|
|
842
|
+
PARTIAL_ID=$(gh api repos/{GH_REPO}/issues/{NUMBER}/comments \
|
|
843
|
+
--jq '[.[] | select(.body | contains("FORGE:BUILDER") and (contains("FORGE:BUILDER:COMPLETE") | not))] | last | .id // ""')
|
|
844
|
+
if [ -n "$PARTIAL_ID" ]; then
|
|
845
|
+
gh api repos/{GH_REPO}/issues/comments/$PARTIAL_ID -X DELETE
|
|
846
|
+
echo "Deleted partial FORGE:BUILDER comment (no FORGE:BUILDER:COMPLETE) — restarting build"
|
|
847
|
+
fi
|
|
848
|
+
```
|
|
748
849
|
|
|
749
850
|
**CRITICAL: You MUST execute ALL sub-phases 3A–3M in order. Sub-phases 3C.5 (context) and 3C.6 (architect) are skipped ONLY for TRIVIAL tasks and Investigation tasks — see Phase 3B for classification. For STANDARD and COMPLEX tasks they post mandatory `FORGE:CONTEXT` and `FORGE:ARCHITECT` comments that Phase 3F reads as its primary input. Skipping them without a TRIVIAL/Investigation classification degrades build quality and causes review findings. After each sub-phase, continue to the next — no sub-phase is terminal.**
|
|
750
851
|
|
|
@@ -766,9 +867,9 @@ gh issue view {NUMBER} {GH_FLAG} --json number,title,body,labels,state,milestone
|
|
|
766
867
|
gh api repos/{GH_REPO}/issues/{NUMBER}/comments \
|
|
767
868
|
--jq '.[] | select(.body | contains("FORGE:INVESTIGATOR")) | .body'
|
|
768
869
|
|
|
769
|
-
# Check if build already completed
|
|
870
|
+
# Check if build already completed (require FORGE:BUILDER:COMPLETE — not just FORGE:BUILDER)
|
|
770
871
|
gh api repos/{GH_REPO}/issues/{NUMBER}/comments \
|
|
771
|
-
--jq '.[] | select(.body | contains("FORGE:BUILDER")) | .body'
|
|
872
|
+
--jq '.[] | select(.body | contains("FORGE:BUILDER:COMPLETE")) | .body'
|
|
772
873
|
|
|
773
874
|
# Check for existing COMPLEXITY_BAND from a prior run (resume path)
|
|
774
875
|
EXISTING_FAST_PATH=$(gh api repos/{GH_REPO}/issues/{NUMBER}/comments \
|
|
@@ -889,7 +990,12 @@ Run these queries (20s timeout each, 2 min total budget):
|
|
|
889
990
|
|
|
890
991
|
**C1: Past Review Findings on These Files**
|
|
891
992
|
```bash
|
|
892
|
-
|
|
993
|
+
# {AFFECTED_FILES} is a space-separated argument (see --files contract) — split
|
|
994
|
+
# explicitly on IFS=' ' into an array instead of a bare `for file in {AFFECTED_FILES}`,
|
|
995
|
+
# which word-splits on the shell's default IFS (space, tab, AND newline) and
|
|
996
|
+
# would corrupt any path containing a space.
|
|
997
|
+
IFS=' ' read -ra AFFECTED_FILES_ARR <<< "{AFFECTED_FILES}"
|
|
998
|
+
for file in "${AFFECTED_FILES_ARR[@]}"; do
|
|
893
999
|
basename=$(basename "$file" .py)
|
|
894
1000
|
gh issue list -R {GH_REPO} --state closed --label "review-finding" \
|
|
895
1001
|
--search "$basename" --limit 10 \
|
|
@@ -908,6 +1014,20 @@ git log --oneline -30 -- {AFFECTED_FILES} | grep -oE '#[0-9]+' | sort -u | head
|
|
|
908
1014
|
# For each issue: fetch title + root cause, keep only bug/fix/review-finding labeled. Max 5.
|
|
909
1015
|
```
|
|
910
1016
|
|
|
1017
|
+
**Direct commit-body read (bounded, prefer over `gh api` when it already answers "why")**: read the top 5 commit subjects+bodies on the affected files directly — local git is near-free relative to `gh api` round-trips, and commit bodies often explain the "why" without needing to fetch a linked issue at all:
|
|
1018
|
+
```bash
|
|
1019
|
+
git log -5 --format='%h %ad %s%n%b' --date=short -- {AFFECTED_FILES}
|
|
1020
|
+
```
|
|
1021
|
+
If a commit body fully explains a prior bug/fix (common for squashed or fix-up commits with no `#NNN` reference), use it directly as a "Past Bug in This Module" entry — do not require a linked GitHub issue to exist.
|
|
1022
|
+
|
|
1023
|
+
**Pickaxe pass (has this exact area been fixed before?)** — one bounded pass, capped at 5 hits, keyed on the suspected symbol/string from the Builder Contract or investigation report:
|
|
1024
|
+
```bash
|
|
1025
|
+
git log -S"{suspected_symbol_or_string}" --oneline -- {AFFECTED_FILES} | head -5
|
|
1026
|
+
# Use -G instead of -S for regex patterns
|
|
1027
|
+
git log -G"{pattern}" --oneline -- {AFFECTED_FILES} | head -5
|
|
1028
|
+
```
|
|
1029
|
+
Any hit is a candidate prior fix or reintroduced defect for this exact code area — read `git show {hash}` to confirm scope before including it in the output. This catches regressions the issue-number harvest above misses (e.g. a defect fixed via a squashed commit with no `#NNN` reference).
|
|
1030
|
+
|
|
911
1031
|
**C3: Related Code Paths** (callers/importers of FUNCTION_NAMES)
|
|
912
1032
|
```bash
|
|
913
1033
|
for fn in {FUNCTION_NAMES}; do
|
|
@@ -934,7 +1054,8 @@ gh issue comment {NUMBER} {GH_FLAG} --body "<!-- FORGE:CONTEXT -->
|
|
|
934
1054
|
{past review-finding issues}
|
|
935
1055
|
|
|
936
1056
|
### Past Bugs in This Module
|
|
937
|
-
{closed bug issues from git log mining
|
|
1057
|
+
{closed bug issues from git log mining, PLUS pickaxe-derived findings (commits with no linked issue, or commit
|
|
1058
|
+
bodies read directly per the C2 direct-commit-body step)}
|
|
938
1059
|
|
|
939
1060
|
### Related Code Paths (must stay consistent)
|
|
940
1061
|
{files that import/call changed functions}
|
|
@@ -1070,6 +1191,14 @@ esac
|
|
|
1070
1191
|
**Determine source branch**:
|
|
1071
1192
|
- Review-finding → parse `**Code branch**: \`{branch}\`` from issue body; branch from `origin/{branch}`
|
|
1072
1193
|
- **Milestone review-finding hybrid lane** (Code branch matches `milestone/*`): High-risk lane. NEVER use `git merge` to resolve conflicts — use `git rebase` or `git cherry-pick` only. If conflicts can't be resolved without merge, post comment, add `needs-human`, STOP.
|
|
1194
|
+
- **Missing ref fallback**: After parsing, verify the Code branch still exists on remote. If not (e.g., the source PR's head branch was deleted post-merge before a corrected stamp took effect), fall back to `PR_BASE` (the lane default) and note the fallback:
|
|
1195
|
+
```bash
|
|
1196
|
+
SOURCE_BRANCH="{CODE_BRANCH_FROM_ISSUE_BODY}"
|
|
1197
|
+
if ! git ls-remote --exit-code origin "$SOURCE_BRANCH" >/dev/null 2>&1; then
|
|
1198
|
+
echo "WARNING: Code branch '$SOURCE_BRANCH' not found on remote — falling back to PR_BASE '$PR_BASE'"
|
|
1199
|
+
SOURCE_BRANCH="$PR_BASE"
|
|
1200
|
+
fi
|
|
1201
|
+
```
|
|
1073
1202
|
- Feature lane (has milestone) → branch from `origin/{PR_BASE}` (PR_BASE now set above)
|
|
1074
1203
|
- Fast lane (no milestone) → branch from `origin/{PR_BASE}` (PR_BASE = `{STAGING_BRANCH}`)
|
|
1075
1204
|
|
|
@@ -1178,6 +1307,11 @@ if iteration == max_iterations AND not PASS:
|
|
|
1178
1307
|
|
|
1179
1308
|
All tool commands are read from `forge.yaml → verification.commands`. When a key is absent, the step logs `SKIPPED — not configured in verification.commands` and continues rather than silently passing.
|
|
1180
1309
|
|
|
1310
|
+
**Track skipped checks** — initialize before any check runs:
|
|
1311
|
+
```bash
|
|
1312
|
+
VERIFICATION_SKIPPED_CHECKS=""
|
|
1313
|
+
```
|
|
1314
|
+
|
|
1181
1315
|
**Python**:
|
|
1182
1316
|
```bash
|
|
1183
1317
|
cd {WORKTREE_PATH}
|
|
@@ -1187,6 +1321,7 @@ if [ -n "$PYTHON_FORMAT" ]; then
|
|
|
1187
1321
|
eval "$PYTHON_FORMAT" 2>&1
|
|
1188
1322
|
else
|
|
1189
1323
|
echo "SKIPPED — python.format not configured in verification.commands"
|
|
1324
|
+
VERIFICATION_SKIPPED_CHECKS="${VERIFICATION_SKIPPED_CHECKS:+$VERIFICATION_SKIPPED_CHECKS, }python.format"
|
|
1190
1325
|
fi
|
|
1191
1326
|
|
|
1192
1327
|
# Compile check always runs (no config needed — catches syntax errors)
|
|
@@ -1206,6 +1341,7 @@ if [ -n "$TS_FORMAT" ]; then
|
|
|
1206
1341
|
eval "$TS_FORMAT" 2>&1
|
|
1207
1342
|
else
|
|
1208
1343
|
echo "SKIPPED — typescript.format not configured in verification.commands"
|
|
1344
|
+
VERIFICATION_SKIPPED_CHECKS="${VERIFICATION_SKIPPED_CHECKS:+$VERIFICATION_SKIPPED_CHECKS, }typescript.format"
|
|
1209
1345
|
fi
|
|
1210
1346
|
|
|
1211
1347
|
if [ -n "$TS_TYPECHECK" ]; then
|
|
@@ -1216,6 +1352,7 @@ elif [ -n "$TS_BUILD" ]; then
|
|
|
1216
1352
|
TS_EXIT=$?
|
|
1217
1353
|
else
|
|
1218
1354
|
echo "SKIPPED — typescript.typecheck and typescript.build not configured in verification.commands"
|
|
1355
|
+
VERIFICATION_SKIPPED_CHECKS="${VERIFICATION_SKIPPED_CHECKS:+$VERIFICATION_SKIPPED_CHECKS, }typescript.typecheck/build"
|
|
1219
1356
|
TS_EXIT=0
|
|
1220
1357
|
fi
|
|
1221
1358
|
```
|
|
@@ -1257,10 +1394,11 @@ Skip if no changed Python files contain DB engine/session/pool patterns.
|
|
|
1257
1394
|
|
|
1258
1395
|
```bash
|
|
1259
1396
|
cd {WORKTREE_PATH}
|
|
1260
|
-
|
|
1397
|
+
while IFS= read -r f; do
|
|
1398
|
+
[ -z "$f" ] && continue
|
|
1261
1399
|
grep -qE "create_async_engine|AsyncSession|connect_args|pool_size|prepared_statement|engine_from_config|sessionmaker" "$f" 2>/dev/null && \
|
|
1262
1400
|
echo "DB CONFIG CHANGE DETECTED in: $f"
|
|
1263
|
-
done
|
|
1401
|
+
done < <(echo {CHANGED_FILES} | tr ' ' '\n' | grep -E '\.py$')
|
|
1264
1402
|
```
|
|
1265
1403
|
|
|
1266
1404
|
Advisory only — does not block build. Check for lambda/callable in connect_args (the exact bug class from PR #14391).
|
|
@@ -1335,7 +1473,7 @@ Stage all changes and commit:
|
|
|
1335
1473
|
```bash
|
|
1336
1474
|
cd {WORKTREE_PATH}
|
|
1337
1475
|
git add -u
|
|
1338
|
-
git commit -m "fix({SCOPE}): {description} (#{NUMBER})"
|
|
1476
|
+
git commit -s -m "fix({SCOPE}): {description} (#{NUMBER})"
|
|
1339
1477
|
```
|
|
1340
1478
|
|
|
1341
1479
|
Conventional prefix: `fix`/`feat`/`refactor`/`docs`. Reference `#{NUMBER}` in message.
|
|
@@ -1356,12 +1494,20 @@ Check off completed items, mark phases complete, add PR references.
|
|
|
1356
1494
|
|
|
1357
1495
|
### 3M: Post implementation comment
|
|
1358
1496
|
```bash
|
|
1497
|
+
# Compute verification status from VERIFICATION_SKIPPED_CHECKS (set in Phase 3H)
|
|
1498
|
+
if [ -z "$VERIFICATION_SKIPPED_CHECKS" ]; then
|
|
1499
|
+
VERIFICATION_STATUS="✅ All configured verification commands passed"
|
|
1500
|
+
else
|
|
1501
|
+
VERIFICATION_STATUS="⚠ Verification NOT run: ${VERIFICATION_SKIPPED_CHECKS} — verification.commands not configured for these checks"
|
|
1502
|
+
fi
|
|
1503
|
+
|
|
1359
1504
|
gh issue comment {NUMBER} {GH_FLAG} --body "<!-- FORGE:BUILDER -->
|
|
1360
1505
|
## Implementation Complete
|
|
1361
1506
|
|
|
1362
1507
|
**Branch**: \`{BRANCH}\`
|
|
1363
1508
|
**Commits**: {COMMIT_SHA(S)}
|
|
1364
1509
|
**Files changed**: {COUNT}
|
|
1510
|
+
**Verification Status**: ${VERIFICATION_STATUS}
|
|
1365
1511
|
|
|
1366
1512
|
### Approach
|
|
1367
1513
|
{what was built, key decisions}
|
|
@@ -1649,7 +1795,14 @@ fi
|
|
|
1649
1795
|
|
|
1650
1796
|
## Phase 7: Summary & Trajectory
|
|
1651
1797
|
|
|
1652
|
-
### 7A: Report
|
|
1798
|
+
### 7A: Report + Pipeline Summary Card
|
|
1799
|
+
|
|
1800
|
+
Output the terse report, then render the shareable **Pipeline Summary Card** — the shareable
|
|
1801
|
+
moment a developer screenshots. Gather real stats (commits, additions/deletions, PR target,
|
|
1802
|
+
review summary, elapsed time) and render exactly as specified in `work-on/close.md` Phase C4.5
|
|
1803
|
+
(`C4.5a` stats gathering → `C4.5b` box-drawing card to stdout → `C4.5c` machine-readable twin).
|
|
1804
|
+
This inline path and the delegated `close.md` path MUST produce an identical card.
|
|
1805
|
+
|
|
1653
1806
|
```
|
|
1654
1807
|
## Done: #{NUMBER} — {TITLE}
|
|
1655
1808
|
- Investigation: {VERDICT} ({CONFIDENCE})
|
|
@@ -1658,6 +1811,98 @@ fi
|
|
|
1658
1811
|
- Files changed: {COUNT}
|
|
1659
1812
|
```
|
|
1660
1813
|
|
|
1814
|
+
Then print the card to stdout (inner width 51; truncate long titles with `…`; missing stats
|
|
1815
|
+
render `—`; pipeline line reflects the actual terminal state — merged / decomposed / invalid /
|
|
1816
|
+
blocked; draft PRs append `(draft)`):
|
|
1817
|
+
|
|
1818
|
+
```
|
|
1819
|
+
╔═══════════════════════════════════════════════════╗
|
|
1820
|
+
║ ForgeDock Pipeline Complete ║
|
|
1821
|
+
╠═══════════════════════════════════════════════════╣
|
|
1822
|
+
║ ║
|
|
1823
|
+
║ Issue: #{NUMBER} — {TITLE} ║
|
|
1824
|
+
║ Pipeline: investigate → architect → build → ║
|
|
1825
|
+
║ review → merge ✓ ║
|
|
1826
|
+
║ Commits: {COMMITS} ({ADDITIONS} additions, {DELETIONS} deletions) ║
|
|
1827
|
+
║ PR: #{PR_NUMBER} (merged to {PR_BASE}) ║
|
|
1828
|
+
║ Review: {REVIEW_SUMMARY} ║
|
|
1829
|
+
║ Time: {ELAPSED} ║
|
|
1830
|
+
║ ║
|
|
1831
|
+
╚═══════════════════════════════════════════════════╝
|
|
1832
|
+
```
|
|
1833
|
+
|
|
1834
|
+
**Gather real stats** (C4.5a — this block MUST run on the inline path to populate card variables;
|
|
1835
|
+
do NOT rely on the cross-reference to `close.md` alone):
|
|
1836
|
+
|
|
1837
|
+
```bash
|
|
1838
|
+
PR_STATS=$(gh pr view {PR_NUMBER} {GH_FLAG} --json commits,additions,deletions,baseRefName,isDraft 2>/dev/null)
|
|
1839
|
+
COMMITS=$(echo "$PR_STATS" | jq -r '(.commits | length) // empty' 2>/dev/null); COMMITS=${COMMITS:-—}
|
|
1840
|
+
ADDITIONS=$(echo "$PR_STATS" | jq -r '.additions // empty' 2>/dev/null); ADDITIONS=${ADDITIONS:-—}
|
|
1841
|
+
DELETIONS=$(echo "$PR_STATS" | jq -r '.deletions // empty' 2>/dev/null); DELETIONS=${DELETIONS:-—}
|
|
1842
|
+
PR_TARGET=$(echo "$PR_STATS" | jq -r '.baseRefName // empty' 2>/dev/null); PR_TARGET=${PR_TARGET:-{PR_BASE}}
|
|
1843
|
+
IS_DRAFT=$(echo "$PR_STATS" | jq -r '.isDraft // false' 2>/dev/null)
|
|
1844
|
+
|
|
1845
|
+
REVIEW_BODIES=$(gh pr view {PR_NUMBER} {GH_FLAG} --json reviews,comments \
|
|
1846
|
+
--jq '[.reviews[].body // ""] + [.comments[].body // ""] | .[]' 2>/dev/null)
|
|
1847
|
+
# NOTE: `grep -c` already prints `0` on no match (and exits non-zero) — do NOT add
|
|
1848
|
+
# `|| echo 0`, which would append a second line ("0\n0") and break the arithmetic
|
|
1849
|
+
# and `--argjson` below. Swallow the non-zero exit with `|| true`, then default.
|
|
1850
|
+
APPROVED=$(echo "$REVIEW_BODIES" | grep -cE 'APPROVED:' 2>/dev/null || true); APPROVED=${APPROVED:-0}
|
|
1851
|
+
CHANGES=$(echo "$REVIEW_BODIES" | grep -cE 'CHANGES REQUESTED:' 2>/dev/null || true); CHANGES=${CHANGES:-0}
|
|
1852
|
+
TOTAL_AGENTS=$((APPROVED + CHANGES))
|
|
1853
|
+
BLOCKERS=$(echo "$REVIEW_BODIES" | grep -ciE 'blocker|merge.?block' 2>/dev/null || true); BLOCKERS=${BLOCKERS:-0}
|
|
1854
|
+
if [ "$TOTAL_AGENTS" -gt 0 ]; then
|
|
1855
|
+
REVIEW_SUMMARY="${APPROVED}/${TOTAL_AGENTS} agents passed, ${BLOCKERS} blockers"
|
|
1856
|
+
else
|
|
1857
|
+
REVIEW_SUMMARY="—" # review data unavailable (e.g. review skipped)
|
|
1858
|
+
fi
|
|
1859
|
+
|
|
1860
|
+
FIRST_TS=$(gh api repos/{GH_REPO}/issues/{NUMBER}/comments \
|
|
1861
|
+
--jq '[.[] | select(.body | contains("FORGE:")) | .created_at] | sort | .[0] // empty' 2>/dev/null)
|
|
1862
|
+
if [ -n "$FIRST_TS" ]; then
|
|
1863
|
+
START_EPOCH=$(date -u -d "$FIRST_TS" +%s 2>/dev/null \
|
|
1864
|
+
|| python3 -c "import sys,datetime; ts=sys.argv[1].rstrip('Z'); print(int(datetime.datetime.fromisoformat(ts+'+00:00').timestamp()))" "$FIRST_TS" 2>/dev/null \
|
|
1865
|
+
|| echo "")
|
|
1866
|
+
NOW_EPOCH=$(date -u +%s)
|
|
1867
|
+
if [ -n "$START_EPOCH" ]; then
|
|
1868
|
+
ELAPSED_SECS=$((NOW_EPOCH - START_EPOCH))
|
|
1869
|
+
ELAPSED=$(printf '%dm %02ds' $((ELAPSED_SECS / 60)) $((ELAPSED_SECS % 60)))
|
|
1870
|
+
else ELAPSED="—"; ELAPSED_SECS=0; fi
|
|
1871
|
+
else ELAPSED="—"; ELAPSED_SECS=0; fi
|
|
1872
|
+
|
|
1873
|
+
case "{TERMINAL_STATE}" in
|
|
1874
|
+
decomposed) PIPELINE_LINE="investigate → decompose ⏹"; CARD_STATUS="decomposed" ;;
|
|
1875
|
+
invalid) PIPELINE_LINE="investigate → invalid ✗"; CARD_STATUS="invalid" ;;
|
|
1876
|
+
blocked) PIPELINE_LINE="investigate → build → blocked ⚠"; CARD_STATUS="blocked" ;;
|
|
1877
|
+
*) PIPELINE_LINE="investigate → architect → build → review → merge ✓"; CARD_STATUS="merged" ;;
|
|
1878
|
+
esac
|
|
1879
|
+
[ "$IS_DRAFT" = "true" ] && PIPELINE_LINE="${PIPELINE_LINE} (draft)"
|
|
1880
|
+
```
|
|
1881
|
+
|
|
1882
|
+
**Build the machine-readable twin** (C4.5c — MUST run this block to assign `CARD_JSON` before
|
|
1883
|
+
Phase 7B embeds it; the cross-reference to `close.md` above is insufficient on the inline path): <!-- forge#1178 -->
|
|
1884
|
+
|
|
1885
|
+
```bash
|
|
1886
|
+
CARD_JSON=$(jq -nc \
|
|
1887
|
+
--argjson issue {NUMBER} \
|
|
1888
|
+
--arg title "{TITLE}" \
|
|
1889
|
+
--arg status "$CARD_STATUS" \
|
|
1890
|
+
--arg pipeline "$PIPELINE_LINE" \
|
|
1891
|
+
--arg pr "{PR_NUMBER}" \
|
|
1892
|
+
--arg target "$PR_TARGET" \
|
|
1893
|
+
--arg commits "$COMMITS" --arg adds "$ADDITIONS" --arg dels "$DELETIONS" \
|
|
1894
|
+
--arg review "$REVIEW_SUMMARY" --argjson blockers "${BLOCKERS:-0}" \
|
|
1895
|
+
--argjson elapsed "${ELAPSED_SECS:-0}" \
|
|
1896
|
+
'{issue:$issue, title:$title, status:$status, pipeline:$pipeline,
|
|
1897
|
+
pr:($pr|tonumber? // null), pr_target:$target,
|
|
1898
|
+
commits:($commits|tonumber? // null),
|
|
1899
|
+
additions:($adds|tonumber? // null),
|
|
1900
|
+
deletions:($dels|tonumber? // null),
|
|
1901
|
+
review:$review, blockers:$blockers, elapsed_seconds:$elapsed}')
|
|
1902
|
+
```
|
|
1903
|
+
|
|
1904
|
+
`CARD_JSON` is now set and embedded in the trajectory comment by 7B.
|
|
1905
|
+
|
|
1661
1906
|
### 7B: Trajectory Log (MANDATORY)
|
|
1662
1907
|
|
|
1663
1908
|
**Review-presence check** (run before filling in Phase 4-5 row): <!-- Added: forge#381 -->
|
|
@@ -1676,6 +1921,13 @@ This check is **audit-only** — it annotates the trajectory for visibility. It
|
|
|
1676
1921
|
Post `<!-- FORGE:TRAJECTORY -->` comment with phase-by-phase results table:
|
|
1677
1922
|
|
|
1678
1923
|
```bash
|
|
1924
|
+
# Compute verification row from VERIFICATION_SKIPPED_CHECKS (set in Phase 3H)
|
|
1925
|
+
if [ -z "$VERIFICATION_SKIPPED_CHECKS" ]; then
|
|
1926
|
+
VERIFICATION_ROW="✅ Ran"
|
|
1927
|
+
else
|
|
1928
|
+
VERIFICATION_ROW="⚠ Skipped — verification.commands not configured for: ${VERIFICATION_SKIPPED_CHECKS}"
|
|
1929
|
+
fi
|
|
1930
|
+
|
|
1679
1931
|
gh issue comment {NUMBER} {GH_FLAG} --body "<!-- FORGE:TRAJECTORY -->
|
|
1680
1932
|
## Pipeline Trajectory — #{NUMBER}
|
|
1681
1933
|
|
|
@@ -1686,14 +1938,22 @@ gh issue comment {NUMBER} {GH_FLAG} --body "<!-- FORGE:TRAJECTORY -->
|
|
|
1686
1938
|
| Phase 2: Decomposition | ⏭ Skipped | {reason} |
|
|
1687
1939
|
| Phase 3: Build | ✅ Complete | Branch: \`{BRANCH}\` |
|
|
1688
1940
|
| Phase 3G: Quality Gate | ✅ Gate passed | {iterations} iterations |
|
|
1941
|
+
| Phase 3H: Verification | ${VERIFICATION_ROW} | |
|
|
1689
1942
|
| Phase 4–5: Review + PR | {REVIEW_ROW} | PR #{PR_NUMBER} → \`{PR_BASE}\` |
|
|
1690
1943
|
| Phase 6: Close | ✅ Complete | Issue closed |
|
|
1691
1944
|
|
|
1692
1945
|
**Decisions**: {key decisions}
|
|
1693
1946
|
**Anomalies**: {anomalies or None}
|
|
1694
|
-
**Pipeline completed**: {TIMESTAMP}
|
|
1947
|
+
**Pipeline completed**: {TIMESTAMP}
|
|
1948
|
+
|
|
1949
|
+
<!-- FORGE:CARD ${CARD_JSON} -->"
|
|
1695
1950
|
```
|
|
1696
1951
|
|
|
1952
|
+
Append the `<!-- FORGE:CARD {...} -->` block (machine-readable twin from 7A / close.md C4.5c)
|
|
1953
|
+
as the last line of the trajectory comment. It is HTML-comment-wrapped so it stays hidden in
|
|
1954
|
+
the rendered view but greppable for platform consumption (`/orchestrate` Phase 6 reads it for
|
|
1955
|
+
per-issue cards). Additive — does not affect existing `FORGE:TRAJECTORY` table consumers.
|
|
1956
|
+
|
|
1697
1957
|
### 7C: Graph Decision Record (MANDATORY when PR exists)
|
|
1698
1958
|
|
|
1699
1959
|
**Skip if**: `{PR_NUMBER}` is empty (investigation-only tasks with no PR) OR `<!-- FORGE:DECISION_RECORD -->` already posted on the PR.
|
package/docs/BRAND.md
CHANGED
|
@@ -6,7 +6,10 @@ Status of reserved and blocked brand handles across platforms.
|
|
|
6
6
|
|
|
7
7
|
| Domain | Status |
|
|
8
8
|
|--------|--------|
|
|
9
|
-
| `forgedock.dev` | **
|
|
9
|
+
| `forgedock.dev` | **Unverified** — live content (2026-07-04) is a third-party product unrelated to ForgeDock; registrar verification pending. Do not use as a public-facing link until resolved. |
|
|
10
|
+
| `forgedock.io` | **Parked** — Porkbun parked page, HTTP-only (HTTPS does not connect). Not controlled by RapierCraft Studios. Do not use as a public-facing link. |
|
|
11
|
+
|
|
12
|
+
> **Rule**: No public ForgeDock surface (npm homepage, repo description, plugin manifests, docs) may point at a domain until its live content is verified as controlled by RapierCraft Studios.
|
|
10
13
|
|
|
11
14
|
## npm
|
|
12
15
|
|
|
@@ -45,7 +48,8 @@ Social handle registration is an operational task. Reserve handles before public
|
|
|
45
48
|
|
|
46
49
|
| Platform | Action |
|
|
47
50
|
|----------|--------|
|
|
48
|
-
| Domain |
|
|
51
|
+
| Domain (forgedock.dev) | Unverified — registrar check pending; do not use as live surface |
|
|
52
|
+
| Domain (forgedock.io) | Parked — not controlled by RapierCraft Studios; do not use as live surface |
|
|
49
53
|
| npm | Done |
|
|
50
54
|
| GitHub org slug | Blocked — use variant for App slug |
|
|
51
55
|
| Social handles | Reserve before L1 public launch |
|
package/docs/CONFIG.md
CHANGED
|
@@ -12,18 +12,26 @@ echo "forge.yaml" >> .gitignore # if your credentials path is sensitive
|
|
|
12
12
|
|
|
13
13
|
---
|
|
14
14
|
|
|
15
|
-
## CLI Flags
|
|
15
|
+
## CLI Flags
|
|
16
16
|
|
|
17
|
-
`npx forgedock init`
|
|
17
|
+
`--verbose` and `--fast` apply to both `npx forgedock` (the full install journey) and `npx forgedock init` (config-only regeneration); `--manual` and `--minimal` apply to `init` only:
|
|
18
18
|
|
|
19
19
|
| Flag | Behavior |
|
|
20
20
|
|------|----------|
|
|
21
|
-
| `--manual` |
|
|
22
|
-
| `--
|
|
21
|
+
| `--manual` | `npx forgedock init` only. Skips the annotated review screen and asks plain, one-field-at-a-time prompts instead, pre-filled with the detected values as defaults. |
|
|
22
|
+
| `--minimal` | `npx forgedock init` only. Skips detection enrichment and the review screen entirely, and writes a short `forge.yaml` containing only the three required sections (`project`, `paths`, `branches`) with detected values. |
|
|
23
|
+
| `--verbose` | Shows each field's detection source and confidence rationale on the review screen (e.g. `git remote`, `package.json`, `gh api`), instead of only flagging low-confidence fields. |
|
|
24
|
+
| `--fast` | Skips the animation/motion frames and jumps straight to the static screens. |
|
|
23
25
|
|
|
24
|
-
|
|
26
|
+
**Environment variables:**
|
|
25
27
|
|
|
26
|
-
|
|
28
|
+
| Variable | Behavior |
|
|
29
|
+
|----------|----------|
|
|
30
|
+
| `FORGE_NO_MOTION=1` | Same effect as `--fast` — disables animation frames. Color is unaffected. |
|
|
31
|
+
| `NO_COLOR=1` | Disables ANSI color output only. Motion is unaffected (monochrome choreography). |
|
|
32
|
+
| Non-TTY / piped output (or `CI=1`) | Plain sequential log: no color **and** no animation. |
|
|
33
|
+
|
|
34
|
+
The default (no flags) is the annotated review screen: detection runs, AI enrichment fills in what it can (when an API key is available), and you review the result on a single screen — Enter accepts everything, low-confidence fields are flagged with a `# TODO(forgedock:<field>)` comment if left unedited.
|
|
27
35
|
|
|
28
36
|
---
|
|
29
37
|
|
|
@@ -686,46 +694,43 @@ Downstream consumers read `field.value` for the raw value and `field.confidence`
|
|
|
686
694
|
|
|
687
695
|
---
|
|
688
696
|
|
|
689
|
-
##
|
|
697
|
+
## SessionStart Hook Integration
|
|
690
698
|
|
|
691
|
-
ForgeDock
|
|
699
|
+
ForgeDock does **not** write anything into your project's `CLAUDE.md` or `AGENTS.md`. Instead, `npx forgedock` registers a `SessionStart` hook in `~/.claude/settings.json` — a small script that runs at the start of every Claude Code session and prints ForgeDock's context straight to that session, without touching any file in your repo.
|
|
692
700
|
|
|
693
701
|
### How It Works
|
|
694
702
|
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
```
|
|
698
|
-
<!-- BEGIN FORGEDOCK -->
|
|
699
|
-
## ForgeDock — Autonomous Development Pipeline
|
|
700
|
-
...command index and conventions...
|
|
701
|
-
<!-- END FORGEDOCK -->
|
|
702
|
-
```
|
|
703
|
+
The hook resolves the current directory's state and reacts accordingly:
|
|
703
704
|
|
|
704
|
-
|
|
705
|
+
| State | Behavior |
|
|
706
|
+
|-------|----------|
|
|
707
|
+
| `managed-active` (`forge.yaml` present, not opted out) | Prints a summary of `forge.yaml` (project, repo, branches) plus the available pipeline commands |
|
|
708
|
+
| `managed-active`, no `forge.yaml` yet | Suggests running `npx forgedock init` |
|
|
709
|
+
| `managed-optedout` | Completely silent — no output |
|
|
710
|
+
| `unmanaged` | Prints a one-time, suppressible nudge to run `npx forgedock enable` |
|
|
705
711
|
|
|
706
|
-
|
|
712
|
+
The hook entry is registered idempotently: re-installing (`npx forgedock update`) will not duplicate it, and unrelated hooks or settings in `~/.claude/settings.json` are left untouched. If `settings.json` is malformed, the installer skips writing rather than risk corrupting it.
|
|
707
713
|
|
|
708
714
|
### Commands
|
|
709
715
|
|
|
710
716
|
| Command | Action |
|
|
711
717
|
|---------|--------|
|
|
712
|
-
| `npx forgedock
|
|
713
|
-
| `npx forgedock
|
|
718
|
+
| `npx forgedock` / `npx forgedock install` | Registers the SessionStart hook (along with installing commands and writing `forge.yaml`) |
|
|
719
|
+
| `npx forgedock update` | Re-registers the hook (relink only — does not touch `forge.yaml`) |
|
|
720
|
+
| `npx forgedock uninstall` | Removes the hook entry from `settings.json` |
|
|
714
721
|
|
|
715
722
|
### Opting Out
|
|
716
723
|
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
Alternatively, keep the markers but edit the content between them freely — ForgeDock will replace that section on the next run, so any manual edits inside the markers will be overwritten.
|
|
720
|
-
|
|
721
|
-
### Re-generating
|
|
722
|
-
|
|
723
|
-
The command index inside the block is auto-generated from the `description:` frontmatter in each `commands/*.md` file. To refresh it after a ForgeDock update:
|
|
724
|
+
Per-directory, independent of the global hook registration. Each command acts on the current working directory — run it inside the project directory:
|
|
724
725
|
|
|
725
726
|
```bash
|
|
726
|
-
npx forgedock
|
|
727
|
+
npx forgedock disable # the current directory goes silent (managed-optedout)
|
|
728
|
+
npx forgedock enable # re-activate the current directory
|
|
729
|
+
npx forgedock status # show the current directory's resolved state
|
|
727
730
|
```
|
|
728
731
|
|
|
732
|
+
See [Per-Directory State Registry](#per-directory-state-registry) below for how opt-out state is tracked.
|
|
733
|
+
|
|
729
734
|
---
|
|
730
735
|
|
|
731
736
|
## Per-Directory State Registry
|
|
@@ -788,22 +793,22 @@ If you downgrade to a build older than PR #467 **and** your project is accessed
|
|
|
788
793
|
- The one-time "Enable ForgeDock here?" nudge may reappear once.
|
|
789
794
|
- No data is lost. No crash. Fail-open behaviour holds throughout.
|
|
790
795
|
|
|
791
|
-
**Recovery**: after downgrading, re-apply your opt-out with the older build:
|
|
796
|
+
**Recovery**: after downgrading, re-apply your opt-out with the older build (run inside the project directory):
|
|
792
797
|
|
|
793
798
|
```bash
|
|
794
|
-
npx forgedock disable
|
|
799
|
+
npx forgedock disable
|
|
795
800
|
```
|
|
796
801
|
|
|
797
802
|
This re-writes the entry under the key form the older build expects.
|
|
798
803
|
|
|
799
804
|
### Managing Opt-Out State
|
|
800
805
|
|
|
801
|
-
Use the `forgedock enable` and `forgedock disable` commands to add or remove a directory from the opt-out set:
|
|
806
|
+
Use the `forgedock enable` and `forgedock disable` commands to add or remove a directory from the opt-out set. Each command acts on the current working directory by default — run it inside the project directory, or pass an explicit path:
|
|
802
807
|
|
|
803
808
|
```bash
|
|
804
|
-
npx forgedock enable [dir] # Remove directory from opt-out set (default: cwd)
|
|
805
|
-
npx forgedock disable [dir] # Add directory to opt-out set (default: cwd)
|
|
806
|
-
npx forgedock status [dir] # Show resolved state
|
|
809
|
+
npx forgedock enable [dir] # Remove a directory from the opt-out set (default: cwd)
|
|
810
|
+
npx forgedock disable [dir] # Add a directory to the opt-out set (default: cwd)
|
|
811
|
+
npx forgedock status [dir] # Show a directory's resolved state (default: cwd)
|
|
807
812
|
```
|
|
808
813
|
|
|
809
814
|
---
|