forge-orkes 0.74.0 → 0.77.0
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/experimental/m10/source/skills/orchestrating/SKILL.md +31 -2
- package/package.json +1 -1
- package/template/.claude/hooks/README.md +121 -0
- package/template/.claude/hooks/forge-reserve.sh +21 -4
- package/template/.claude/hooks/forge-state-rollup.sh +431 -0
- package/template/.claude/hooks/tests/README.md +20 -0
- package/template/.claude/hooks/tests/forge-reserve.test.sh +92 -0
- package/template/.claude/hooks/tests/forge-state-rollup.test.sh +282 -0
- package/template/.claude/settings.json +11 -0
- package/template/.claude/skills/chief-of-staff/SKILL.md +16 -11
- package/template/.claude/skills/executing/SKILL.md +23 -0
- package/template/.claude/skills/forge/SKILL.md +11 -7
- package/template/.forge/FORGE.md +5 -3
- package/template/.forge/migrations/0.77.0-state-rollup-executable.md +120 -0
- package/template/.forge/templates/project.yml +14 -0
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# Migration Guide: State rollup made mechanical (Forge 0.77.0)
|
|
2
|
+
|
|
3
|
+
Applies to projects upgrading to 0.77.0 or later. State Rollup 1.0 and the
|
|
4
|
+
Stream Rollup (ADR-015 addendum) — previously advisory skill prose that an
|
|
5
|
+
agent had to remember to run at boot — are now an executable,
|
|
6
|
+
`.claude/hooks/forge-state-rollup.sh`, invoked mechanically by a `SessionStart`
|
|
7
|
+
hook. A boot session can no longer skip the render and fall back to reading a
|
|
8
|
+
stale `.forge/state/index.yml` / `.forge/streams/active.yml` cache, or
|
|
9
|
+
hand-reconstruct the registries from memory — the exact failure mode filed as
|
|
10
|
+
issue #22.
|
|
11
|
+
|
|
12
|
+
`/upgrading` ships the new hook file (`.claude/hooks/forge-state-rollup.sh`)
|
|
13
|
+
like any other framework file. It does **not** wire the `SessionStart`
|
|
14
|
+
registration, because `.claude/settings.json` is a **user-owned file** —
|
|
15
|
+
upgrades never overwrite it (FORGE.md → State Ownership, "Stable shared"
|
|
16
|
+
class notes settings.json is gitignored-carve-out territory, propagated only
|
|
17
|
+
via explicit installer steps, never blanket overwrite). Without this
|
|
18
|
+
migration's one manual step, the hook ships but is never invoked: the
|
|
19
|
+
executable exists, nothing mechanically triggers it.
|
|
20
|
+
|
|
21
|
+
Projects that ran `initializing` fresh on 0.77.0+ (or already carry the
|
|
22
|
+
`SessionStart` block from an earlier partial adoption) need nothing further.
|
|
23
|
+
|
|
24
|
+
## Prerequisites
|
|
25
|
+
|
|
26
|
+
1. On the new version's framework files (`npx forge-orkes upgrade`, or the
|
|
27
|
+
`upgrading` skill) — so `.claude/hooks/forge-state-rollup.sh` and
|
|
28
|
+
`.claude/hooks/forge-release-fold.sh` are present and executable.
|
|
29
|
+
2. Working tree clean or changes committed — this migration edits
|
|
30
|
+
`.claude/settings.json`, a tracked file.
|
|
31
|
+
|
|
32
|
+
## Detection
|
|
33
|
+
|
|
34
|
+
Keyed on **the executable existing (or the version already at/above 0.77.0)
|
|
35
|
+
while the SessionStart wiring is absent** — the shipped-but-unwired gap. Uses
|
|
36
|
+
`jq` to inspect `.claude/settings.json`'s `hooks.SessionStart` array for an
|
|
37
|
+
entry referencing `forge-state-rollup`; degrades to a plain-text grep if `jq`
|
|
38
|
+
is not installed. Silent in a non-Forge / non-git tree, silent once the hook
|
|
39
|
+
is wired:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
git rev-parse --is-inside-work-tree >/dev/null 2>&1 || exit 0
|
|
43
|
+
[ -x .claude/hooks/forge-state-rollup.sh ] || exit 0
|
|
44
|
+
|
|
45
|
+
settings=".claude/settings.json"
|
|
46
|
+
[ -f "$settings" ] || {
|
|
47
|
+
echo "MIGRATE — forge-state-rollup.sh is present but $settings does not exist; add it with the SessionStart hook below"
|
|
48
|
+
exit 0
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if command -v jq >/dev/null 2>&1; then
|
|
52
|
+
wired="$(jq -r '
|
|
53
|
+
(.hooks.SessionStart // []) as $entries
|
|
54
|
+
| [$entries[].hooks[]?.command // "" | select(contains("forge-state-rollup"))]
|
|
55
|
+
| length > 0
|
|
56
|
+
' "$settings" 2>/dev/null)"
|
|
57
|
+
if [ "$wired" != "true" ]; then
|
|
58
|
+
echo "MIGRATE — $settings has no SessionStart hook referencing forge-state-rollup.sh; the executable shipped but nothing mechanically triggers it"
|
|
59
|
+
fi
|
|
60
|
+
else
|
|
61
|
+
if ! grep -q "forge-state-rollup" "$settings" 2>/dev/null; then
|
|
62
|
+
echo "MIGRATE — $settings has no reference to forge-state-rollup.sh (jq unavailable, ran plain-text check); add the SessionStart hook below"
|
|
63
|
+
fi
|
|
64
|
+
fi
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Migration steps
|
|
68
|
+
|
|
69
|
+
### 1. Add the SessionStart hook block
|
|
70
|
+
|
|
71
|
+
Open `.claude/settings.json` and add (or merge into) a `hooks.SessionStart`
|
|
72
|
+
array entry:
|
|
73
|
+
|
|
74
|
+
```json
|
|
75
|
+
{
|
|
76
|
+
"hooks": {
|
|
77
|
+
"SessionStart": [
|
|
78
|
+
{
|
|
79
|
+
"matcher": "startup|resume|clear",
|
|
80
|
+
"hooks": [
|
|
81
|
+
{
|
|
82
|
+
"type": "command",
|
|
83
|
+
"command": "[ -x \"$CLAUDE_PROJECT_DIR/.claude/hooks/forge-state-rollup.sh\" ] && \"$CLAUDE_PROJECT_DIR/.claude/hooks/forge-state-rollup.sh\" || true"
|
|
84
|
+
}
|
|
85
|
+
]
|
|
86
|
+
}
|
|
87
|
+
]
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
If `hooks.SessionStart` already has other entries (e.g. from a project-local
|
|
93
|
+
customization), append this object to the existing array rather than
|
|
94
|
+
replacing it. If `hooks` exists but has no `SessionStart` key yet, add the key
|
|
95
|
+
alongside the existing `PreToolUse`/`PostToolUse` blocks.
|
|
96
|
+
|
|
97
|
+
The `[ -x ... ] && ... || true` guard means the hook is a no-op — never a
|
|
98
|
+
boot failure — on any checkout where the script is absent or not executable
|
|
99
|
+
(SessionStart hooks are non-blocking; `forge-state-rollup.sh` itself also
|
|
100
|
+
always exits 0).
|
|
101
|
+
|
|
102
|
+
### 2. Commit the settings change
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
git add .claude/settings.json
|
|
106
|
+
git commit -m "chore(forge): wire forge-state-rollup SessionStart hook (0.77.0)"
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Validation
|
|
110
|
+
|
|
111
|
+
- Start a new session, or run `/clear` — the boot summary line should include
|
|
112
|
+
`[forge-state-rollup] rendered index.yml (…) …` (plus an `active.yml` clause
|
|
113
|
+
if `.forge/streams/` exists), confirming the hook actually ran.
|
|
114
|
+
- `jq '.hooks.SessionStart' .claude/settings.json` prints a non-null array
|
|
115
|
+
containing the `forge-state-rollup` command, not `null`.
|
|
116
|
+
- Re-running the Detection block above now prints nothing (exits silently) —
|
|
117
|
+
the gap is closed.
|
|
118
|
+
- `.forge/state/index.yml` and `.forge/streams/active.yml` (if applicable)
|
|
119
|
+
exist on disk and are fresh — their mtimes update on every boot, since the
|
|
120
|
+
hook re-renders unconditionally.
|
|
@@ -99,6 +99,20 @@ verification:
|
|
|
99
99
|
# # only — the private key lives host-side, in the deploy Environment).
|
|
100
100
|
# # Empty ⇒ git config gpg.ssh.allowedSignersFile.
|
|
101
101
|
|
|
102
|
+
# orchestration: # OPTIONAL — worktree behavior (M10 / streams). Absent → defaults.
|
|
103
|
+
# worktree_root: "" # Where Forge worktrees live. Default ../<repo-basename>-worktrees.
|
|
104
|
+
# # Relative → resolves against repo root; absolute / ~ honored verbatim.
|
|
105
|
+
# worktree_hydrate: [] # OPTIONAL list of superproject-relative paths — required-but-gitignored
|
|
106
|
+
# # artifacts copied into a fresh worktree so it can build and reach its
|
|
107
|
+
# # tools (a clean worktree checks out TRACKED files only). Guarded
|
|
108
|
+
# # source-exists && dest-absent: never overwrites, never git-adds, so a
|
|
109
|
+
# # secret-bearing file stays gitignored/untracked in both trees and never
|
|
110
|
+
# # enters git history (.mcp.json the canonical case). Applied by
|
|
111
|
+
# # orchestrating at creation AND asserted in executing's Workspace
|
|
112
|
+
# # Prerequisites → worktrees of ANY origin covered. Omit → no propagation.
|
|
113
|
+
# # e.g. [".mcp.json", ".env.local"]. Dependency install stays with the
|
|
114
|
+
# # executing/verifying preflight, not this key.
|
|
115
|
+
|
|
102
116
|
success_criteria: # How do we know we're done?
|
|
103
117
|
- "" # e.g., "User can create and edit posts"
|
|
104
118
|
- "" # e.g., "All tests pass with >80% coverage"
|