gm-oc 2.0.332 → 2.0.334

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gm-oc",
3
- "version": "2.0.332",
3
+ "version": "2.0.334",
4
4
  "description": "State machine agent with hooks, skills, and automated git enforcement",
5
5
  "author": "AnEntrypoint",
6
6
  "license": "MIT",
@@ -37,6 +37,7 @@
37
37
  "agents/",
38
38
  "hooks/",
39
39
  "scripts/",
40
+ "skills/",
40
41
  "gm.js",
41
42
  "gm-oc.mjs",
42
43
  "index.js",
@@ -0,0 +1,175 @@
1
+ ---
2
+ name: browser
3
+ description: Browser automation via playwriter. Use when user needs to interact with websites, navigate pages, fill forms, click buttons, take screenshots, extract data, test web apps, or automate any browser task.
4
+ allowed-tools: Bash(browser:*), Bash(exec:browser*)
5
+ ---
6
+
7
+ # Browser Automation with playwriter
8
+
9
+ ## Two Pathways
10
+
11
+ **Session commands** — use `browser:` prefix via Bash for all browser control.
12
+
13
+ Create a session first, then run commands against it. Use `--direct` for CDP mode (no extension needed — requires Chrome with remote debugging):
14
+
15
+ ```
16
+ browser:
17
+ playwriter session new --direct
18
+ ```
19
+
20
+ Returns a numeric session ID (e.g. `1`). Use that ID for all subsequent commands.
21
+
22
+ If `--direct` fails, the user needs Chrome running with debugging enabled:
23
+ - Open `chrome://inspect/#remote-debugging` in Chrome, OR
24
+ - Launch Chrome with `chrome --remote-debugging-port=9222`
25
+
26
+ ```
27
+ browser:
28
+ playwriter -s 1 -e 'await page.goto("https://example.com")'
29
+ ```
30
+
31
+ ```
32
+ browser:
33
+ playwriter -s 1 -e 'await snapshot({ page })'
34
+ ```
35
+
36
+ ```
37
+ browser:
38
+ playwriter -s 1 -e 'await screenshotWithAccessibilityLabels({ page })'
39
+ ```
40
+
41
+ State persists across calls within a session:
42
+
43
+ ```
44
+ browser:
45
+ playwriter -s 1 -e 'state.x = 1'
46
+ ```
47
+
48
+ ```
49
+ browser:
50
+ playwriter -s 1 -e 'console.log(state.x)'
51
+ ```
52
+
53
+ List active sessions:
54
+
55
+ ```
56
+ browser:
57
+ playwriter session list
58
+ ```
59
+
60
+ **JS eval in browser** — use `exec:browser` via Bash when you need to run JavaScript in the page context directly.
61
+
62
+ ```
63
+ exec:browser
64
+ await page.goto('https://example.com')
65
+ await snapshot({ page })
66
+ ```
67
+
68
+ ```
69
+ exec:browser
70
+ const title = await page.title()
71
+ console.log(title)
72
+ ```
73
+
74
+ Always use single quotes for the `-e` argument to avoid shell quoting issues.
75
+
76
+ ## Core Workflow
77
+
78
+ Every browser automation follows this pattern:
79
+
80
+ 1. **Create session**: `playwriter session new` (note the returned ID)
81
+ 2. **Navigate**: `playwriter -s <id> -e 'await page.goto("https://example.com")'`
82
+ 3. **Snapshot**: `playwriter -s <id> -e 'await snapshot({ page })'`
83
+ 4. **Interact**: click, fill, type via JS expressions
84
+ 5. **Re-snapshot**: after navigation or DOM changes
85
+
86
+ ```
87
+ browser:
88
+ playwriter session new
89
+ playwriter -s 1 -e 'await page.goto("https://example.com/form")'
90
+ playwriter -s 1 -e 'await snapshot({ page })'
91
+ playwriter -s 1 -e 'await page.fill("[name=email]", "user@example.com")'
92
+ playwriter -s 1 -e 'await page.click("[type=submit]")'
93
+ playwriter -s 1 -e 'await page.waitForLoadState("networkidle")'
94
+ playwriter -s 1 -e 'await snapshot({ page })'
95
+ ```
96
+
97
+ ## Common Patterns
98
+
99
+ ### Navigation and Snapshot
100
+
101
+ ```
102
+ browser:
103
+ playwriter session new
104
+ playwriter -s 1 -e 'await page.goto("https://example.com")'
105
+ playwriter -s 1 -e 'await snapshot({ page })'
106
+ ```
107
+
108
+ ### Screenshot with Accessibility Labels
109
+
110
+ ```
111
+ browser:
112
+ playwriter -s 1 -e 'await screenshotWithAccessibilityLabels({ page })'
113
+ ```
114
+
115
+ ### Data Extraction
116
+
117
+ ```
118
+ exec:browser
119
+ await page.goto('https://example.com/products')
120
+ const items = await page.$$eval('.product-title', els => els.map(e => e.textContent))
121
+ console.log(JSON.stringify(items))
122
+ ```
123
+
124
+ ### Persistent State Across Steps
125
+
126
+ ```
127
+ browser:
128
+ playwriter -s 1 -e 'state.loginDone = false'
129
+ playwriter -s 1 -e 'await page.goto("https://app.example.com/login")'
130
+ playwriter -s 1 -e 'await page.fill("[name=user]", "admin")'
131
+ playwriter -s 1 -e 'await page.fill("[name=pass]", "secret")'
132
+ playwriter -s 1 -e 'await page.click("[type=submit]")'
133
+ playwriter -s 1 -e 'state.loginDone = true'
134
+ ```
135
+
136
+ ### Multiple Sessions
137
+
138
+ ```
139
+ browser:
140
+ playwriter session new
141
+ playwriter session new
142
+ playwriter -s 1 -e 'await page.goto("https://site-a.com")'
143
+ playwriter -s 2 -e 'await page.goto("https://site-b.com")'
144
+ playwriter session list
145
+ ```
146
+
147
+ ## JavaScript Evaluation (exec pathway)
148
+
149
+ Use `exec:browser` via Bash when you need direct page access. The body is plain JavaScript executed in the browser context.
150
+
151
+ ```
152
+ exec:browser
153
+ await page.goto('https://example.com')
154
+ await snapshot({ page })
155
+ ```
156
+
157
+ ```
158
+ exec:browser
159
+ const links = await page.$$eval('a', els => els.map(e => e.href))
160
+ console.log(JSON.stringify(links))
161
+ ```
162
+
163
+ Never add shell quoting or escaping to the exec body — write plain JavaScript directly.
164
+
165
+ ## Key Patterns for Agents
166
+
167
+ **Which pathway to use**:
168
+ - Multi-step session workflows → `browser:` prefix with `playwriter -s <id> -e '...'`
169
+ - Quick JS eval or data extraction → `exec:browser` with plain JS body
170
+
171
+ **Always use single quotes** for the `-e` argument to playwriter to avoid shell interpretation.
172
+
173
+ **Session IDs are numeric**: `playwriter session new` returns `1`, `2`, etc. Use the exact returned value.
174
+
175
+ **Snapshot before interacting**: always call `await snapshot({ page })` to understand current page state before clicking or filling.
@@ -0,0 +1,180 @@
1
+ ---
2
+ name: create-lang-plugin
3
+ description: Create a lang/ plugin that wires any CLI tool or language runtime into gm-cc — adds exec:<id> dispatch, optional LSP diagnostics, and optional prompt context injection. Zero hook configuration required.
4
+ ---
5
+
6
+ # CREATE LANG PLUGIN
7
+
8
+ A lang plugin is a single CommonJS file at `<projectDir>/lang/<id>.js`. gm-cc's hooks auto-discover it — no hook editing, no settings changes. The plugin gets three integration points: **exec dispatch**, **LSP diagnostics**, and **context injection**.
9
+
10
+ ## PLUGIN SHAPE
11
+
12
+ ```js
13
+ 'use strict';
14
+ module.exports = {
15
+ id: 'mytool', // must match filename: lang/mytool.js
16
+ exec: {
17
+ match: /^exec:mytool/, // regex tested against full "exec:mytool\n<code>" string
18
+ run(code, cwd) { // returns string or Promise<string>
19
+ // ...
20
+ }
21
+ },
22
+ lsp: { // optional — synchronous only
23
+ check(fileContent, cwd) { // returns Diagnostic[] synchronously
24
+ // ...
25
+ }
26
+ },
27
+ extensions: ['.ext'], // optional — file extensions lsp.check applies to
28
+ context: `=== mytool ===\n...` // optional — string or () => string
29
+ };
30
+ ```
31
+
32
+ ```ts
33
+ type Diagnostic = { line: number; col: number; severity: 'error'|'warning'; message: string };
34
+ ```
35
+
36
+ ## HOW IT WORKS
37
+
38
+ - **`exec.run`** is called in a child process (30s timeout) when Claude writes `exec:mytool\n<code>`. Output is returned as `exec:mytool output:\n\n<result>`. Async is fine here.
39
+ - **`lsp.check`** is called synchronously in the hook process on each prompt submit — must NOT be async. Use `execFileSync` or `spawnSync`.
40
+ - **`context`** is injected into every prompt's `additionalContext` (truncated to 2000 chars) and into the session-start context.
41
+ - **`match`** regex is tested against the full command string `exec:mytool\n<code>` — keep it simple: `/^exec:mytool/`.
42
+
43
+ ## STEP 1 — IDENTIFY THE TOOL
44
+
45
+ Answer these before writing any code:
46
+
47
+ 1. What is the tool's CLI name or npm package? (`gdlint`, `tsc`, `deno`, `ruff`, ...)
48
+ 2. How do you run a single expression/snippet? (`tool eval <expr>`, `tool -e <code>`, HTTP POST, ...)
49
+ 3. How do you run a file? (`tool run <file>`, `tool <file>`, ...)
50
+ 4. Does it have a lint/check mode? What does its output format look like?
51
+ 5. What file extensions does it apply to?
52
+ 6. Is the game/server running required, or does it work headlessly?
53
+
54
+ ## STEP 2 — IMPLEMENT exec.run
55
+
56
+ Pattern for **HTTP eval** (tool has a running server):
57
+
58
+ ```js
59
+ const http = require('http');
60
+ function httpPost(port, urlPath, body) {
61
+ return new Promise((resolve, reject) => {
62
+ const data = JSON.stringify(body);
63
+ const req = http.request(
64
+ { hostname: '127.0.0.1', port, path: urlPath, method: 'POST',
65
+ headers: { 'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(data) } },
66
+ (res) => { let raw = ''; res.on('data', c => raw += c); res.on('end', () => { try { resolve(JSON.parse(raw)); } catch { resolve({ raw }); } }); }
67
+ );
68
+ req.setTimeout(8000, () => { req.destroy(); reject(new Error('timeout')); });
69
+ req.on('error', reject);
70
+ req.write(data); req.end();
71
+ });
72
+ }
73
+ ```
74
+
75
+ Pattern for **file-based execution** (write temp file, run headlessly):
76
+
77
+ ```js
78
+ const fs = require('fs');
79
+ const os = require('os');
80
+ const path = require('path');
81
+ const { execFileSync } = require('child_process');
82
+
83
+ function runFile(code, cwd) {
84
+ const tmp = path.join(os.tmpdir(), `plugin_${Date.now()}.ext`);
85
+ fs.writeFileSync(tmp, code);
86
+ try {
87
+ return execFileSync('mytool', ['run', tmp], { cwd, encoding: 'utf8', timeout: 10000 });
88
+ } finally {
89
+ try { fs.unlinkSync(tmp); } catch (_) {}
90
+ }
91
+ }
92
+ ```
93
+
94
+ **Distinguish single expression vs multi-line** when both modes exist:
95
+
96
+ ```js
97
+ function isSingleExpr(code) {
98
+ return !code.trim().includes('\n') && !/\b(func|def|fn |class|import)\b/.test(code);
99
+ }
100
+ ```
101
+
102
+ ## STEP 3 — IMPLEMENT lsp.check (if applicable)
103
+
104
+ Must be **synchronous**. Parse the tool's stderr/stdout for diagnostics:
105
+
106
+ ```js
107
+ const { spawnSync } = require('child_process');
108
+ const fs = require('fs');
109
+ const os = require('os');
110
+ const path = require('path');
111
+
112
+ function check(fileContent, cwd) {
113
+ const tmp = path.join(os.tmpdir(), `lsp_${Math.random().toString(36).slice(2)}.ext`);
114
+ try {
115
+ fs.writeFileSync(tmp, fileContent);
116
+ const r = spawnSync('mytool', ['check', tmp], { encoding: 'utf8', cwd });
117
+ const output = r.stdout + r.stderr;
118
+ return output.split('\n').reduce((acc, line) => {
119
+ const m = line.match(/^.+:(\d+):(\d+):\s+(error|warning):\s+(.+)$/);
120
+ if (m) acc.push({ line: parseInt(m[1]), col: parseInt(m[2]), severity: m[3], message: m[4].trim() });
121
+ return acc;
122
+ }, []);
123
+ } catch (_) {
124
+ return [];
125
+ } finally {
126
+ try { fs.unlinkSync(tmp); } catch (_) {}
127
+ }
128
+ }
129
+ ```
130
+
131
+ Common output patterns to parse:
132
+ - `file:line:col: error: message` → standard
133
+ - `file:line: E001: message` → gdlint style (`E`=error, `W`=warning)
134
+ - JSON output → `JSON.parse(r.stdout).errors.map(...)`
135
+
136
+ ## STEP 4 — WRITE context STRING
137
+
138
+ Describe what `exec:<id>` does and when to use it. This appears in every prompt. Keep it under 300 chars:
139
+
140
+ ```js
141
+ context: `=== mytool exec: support ===
142
+ exec:mytool
143
+ <expression or code block>
144
+
145
+ Runs via <how>. Use for <when>.`
146
+ ```
147
+
148
+ ## STEP 5 — WRITE THE FILE
149
+
150
+ File goes at `lang/<id>.js` in the project root. The `id` field must match the filename (without `.js`).
151
+
152
+ Verify after writing:
153
+
154
+ ```
155
+ exec:nodejs
156
+ const p = require('/abs/path/to/lang/mytool.js');
157
+ console.log(p.id, typeof p.exec.run, p.exec.match.toString());
158
+ ```
159
+
160
+ Then test dispatch:
161
+
162
+ ```
163
+ exec:mytool
164
+ <a simple test expression>
165
+ ```
166
+
167
+ If it returns `exec:mytool output:` → working. If it errors → fix `exec.run`.
168
+
169
+ ## CONSTRAINTS
170
+
171
+ - `exec.run` may be async — it runs in a child process with a 30s timeout
172
+ - `lsp.check` must be synchronous — no Promises, no async/await
173
+ - Plugin must be CommonJS (`module.exports = { ... }`) — no ES module syntax
174
+ - No persistent processes — `exec.run` must complete and exit cleanly
175
+ - `id` must match the filename exactly
176
+ - First match wins — if multiple plugins could match, make `match` specific
177
+
178
+ ## EXAMPLE — gdscript plugin (reference implementation)
179
+
180
+ See `C:/dev/godot-kit/lang/gdscript.js` for a complete working example combining HTTP eval (single expressions via port 6009) with headless file execution fallback, synchronous gdlint LSP, and a context string.
@@ -0,0 +1,125 @@
1
+ ---
2
+ name: gm
3
+ description: Immutable programming state machine. Root orchestrator. Invoke for all work coordination via the Skill tool.
4
+ ---
5
+
6
+ # GM — Immutable Programming State Machine
7
+
8
+ You think in state, not prose. You are the root orchestrator of all work in this system.
9
+
10
+ **GRAPH POSITION**: `[ROOT ORCHESTRATOR]`
11
+ - **Entry**: The prompt-submit hook always invokes `gm` skill first.
12
+ - **Shared state**: .prd file (markdown format) on disk + witnessed execution output only. Nothing persists between skills. Delete .prd when empty — do not leave an empty file.
13
+ - **First action**: Invoke `planning` skill immediately.
14
+
15
+ ## THE STATE MACHINE
16
+
17
+ `PLAN → EXECUTE → EMIT → VERIFY → UPDATE-DOCS → COMPLETE`
18
+
19
+ **FORWARD (ladders)**:
20
+ - PLAN complete → invoke `gm-execute` skill
21
+ - EXECUTE complete → invoke `gm-emit` skill
22
+ - EMIT complete → invoke `gm-complete` skill
23
+ - COMPLETE with .prd items remaining → invoke `gm-execute` skill (next wave)
24
+
25
+ **BACKWARD (snakes) — any new unknown at any phase restarts from PLAN**:
26
+ - New unknown discovered → invoke `planning` skill, restart chain
27
+ - EXECUTE mutable unresolvable after 2 passes → invoke `planning` skill
28
+ - EMIT logic wrong → invoke `gm-execute` skill
29
+ - EMIT new unknown → invoke `planning` skill
30
+ - VERIFY file broken → invoke `gm-emit` skill
31
+ - VERIFY logic wrong → invoke `gm-execute` skill
32
+ - VERIFY new unknown or wrong requirements → invoke `planning` skill
33
+
34
+ **Runs until**: .prd empty AND git clean AND all pushes confirmed.
35
+
36
+ ## MUTABLE DISCIPLINE
37
+
38
+ A mutable is any unknown fact required to make a decision or write code.
39
+ - Name every unknown before acting: `apiShape=UNKNOWN`, `fileExists=UNKNOWN`
40
+ - Each mutable: name | expected | current | resolution method
41
+ - Resolve by witnessed execution only — output assigns the value
42
+ - Zero variance = resolved. Unresolved after 2 passes = new unknown = snake to `planning`
43
+ - Mutables live in conversation only. Never written to files.
44
+
45
+ ## CODE EXECUTION
46
+
47
+ **exec:<lang> is the only way to run code.** Bash tool body: `exec:<lang>\n<code>`
48
+
49
+ Languages: `exec:nodejs` (default) | `exec:bash` | `exec:python` | `exec:typescript` | `exec:go` | `exec:rust` | `exec:c` | `exec:cpp` | `exec:java` | `exec:deno` | `exec:cmd`
50
+
51
+ - Lang auto-detected if omitted. `cwd` field sets working directory.
52
+ - File I/O: `exec:nodejs` with `require('fs')`
53
+ - Only `git` runs directly in Bash. `Bash(node/npm/npx/bun)` = violations.
54
+
55
+ **Execution efficiency — pack every run:**
56
+ - Combine multiple independent operations into one exec call using `Promise.allSettled` or parallel subprocess spawning
57
+ - Each independent idea gets its own try/catch with independent error reporting — never let one failure block another
58
+ - Target under 12s per exec call; split work across multiple calls only when dependencies require it
59
+ - Prefer a single well-structured exec that does 5 things over 5 sequential execs
60
+
61
+ **Background tasks** (auto-backgrounded after 15s):
62
+ ```
63
+ exec:sleep
64
+ <task_id> [seconds]
65
+ ```
66
+ ```
67
+ exec:status
68
+ <task_id>
69
+ ```
70
+ ```
71
+ exec:close
72
+ <task_id>
73
+ ```
74
+
75
+ **Runner management**:
76
+ ```
77
+ exec:runner
78
+ start|stop|status
79
+ ```
80
+
81
+ ## CODEBASE EXPLORATION
82
+
83
+ ```
84
+ exec:codesearch
85
+ <natural language description>
86
+ ```
87
+
88
+ Alias: `exec:search`. **Glob, Grep, Read, Explore, WebSearch are hook-blocked** — the pre-tool-use hook denies them. Use `exec:codesearch` exclusively for all codebase discovery.
89
+
90
+ ## BROWSER AUTOMATION
91
+
92
+ Invoke `browser` skill. Escalation — exhaust each before advancing:
93
+ 1. `exec:browser\n<js>` — query DOM/state via JS
94
+ 2. `browser` skill — for full session workflows
95
+ 3. navigate/click/type — only when real events required
96
+ 4. screenshot — last resort only
97
+
98
+ ## SKILL REGISTRY
99
+
100
+ **`planning`** — Mutable discovery and .prd construction. Invoke at start and on any new unknown.
101
+ **`gm-execute`** — Resolve all mutables via witnessed execution.
102
+ **`gm-emit`** — Write files to disk when all mutables resolved.
103
+ **`gm-complete`** — End-to-end verification and git enforcement.
104
+ **`update-docs`** — Refresh README, CLAUDE.md, and docs to reflect session changes. Invoked by `gm-complete`.
105
+ **`browser`** — Browser automation. Invoke inside EXECUTE for all browser/UI work.
106
+
107
+ ## DO NOT STOP
108
+
109
+ **You may not respond to the user or stop working while any of these are true:**
110
+ - .prd file exists and has items
111
+ - git has uncommitted changes
112
+ - git has unpushed commits
113
+
114
+ Completing a phase is NOT stopping. After every phase: read .prd, check git, invoke next skill. Only when .prd is deleted AND git is clean AND all commits are pushed may you return a final response to the user.
115
+
116
+ ## CONSTRAINTS
117
+
118
+ **Tier 0**: no_crash, no_exit, ground_truth_only, real_execution
119
+ **Tier 1**: max_file_lines=200, hot_reloadable, checkpoint_state
120
+ **Tier 2**: no_duplication, no_hardcoded_values, modularity
121
+ **Tier 3**: no_comments, convention_over_code
122
+
123
+ **Never**: `Bash(node/npm/npx/bun)` | skip planning | sequential independent items | screenshot before JS exhausted | narrate past unresolved mutables | stop while .prd has items | ask the user what to do next while work remains
124
+
125
+ **Always**: invoke named skill at every transition | snake to planning on any new unknown | witnessed execution only | keep going until .prd deleted and git clean
@@ -0,0 +1,107 @@
1
+ ---
2
+ name: gm-complete
3
+ description: VERIFY and COMPLETE phase. End-to-end system verification and git enforcement. Any new unknown triggers immediate snake back to planning — restart chain.
4
+ ---
5
+
6
+ # GM COMPLETE — Verification and Completion
7
+
8
+ You are in the **VERIFY → COMPLETE** phase. Files are written. Prove the whole system works end-to-end. Any new unknown = snake to `planning`, restart chain.
9
+
10
+ **GRAPH POSITION**: `PLAN → EXECUTE → EMIT → [VERIFY] → UPDATE-DOCS → COMPLETE`
11
+ - **Entry**: All EMIT gates passed. Entered from `gm-emit`.
12
+
13
+ ## TRANSITIONS
14
+
15
+ **FORWARD**:
16
+ - .prd items remain → invoke `gm-execute` skill (next wave)
17
+ - .prd empty + feature work pushed → invoke `update-docs` skill
18
+
19
+ **BACKWARD**:
20
+ - Verification reveals broken file output → invoke `gm-emit` skill, fix, re-verify, return
21
+ - Verification reveals logic error → invoke `gm-execute` skill, re-resolve, re-emit, return
22
+ - Verification reveals new unknown → invoke `planning` skill, restart chain
23
+ - Verification reveals requirements wrong → invoke `planning` skill, restart chain
24
+
25
+ **TRIAGE on failure**: broken file output → snake to `gm-emit` | wrong logic → snake to `gm-execute` | new unknown or wrong requirements → snake to `planning`
26
+
27
+ **RULE**: Any surprise = new unknown = snake to `planning`. Never patch around surprises.
28
+
29
+ ## MUTABLE DISCIPLINE
30
+
31
+ - `witnessed_e2e=UNKNOWN` until real end-to-end run produces witnessed output
32
+ - `git_clean=UNKNOWN` until `exec:bash\ngit status --porcelain` returns empty
33
+ - `git_pushed=UNKNOWN` until `git log origin/main..HEAD --oneline` returns empty
34
+ - `prd_empty=UNKNOWN` until .prd file is deleted (not just empty — file must not exist)
35
+
36
+ All four must resolve to KNOWN before COMPLETE. Any UNKNOWN = absolute barrier.
37
+
38
+ ## END-TO-END VERIFICATION
39
+
40
+ Run the real system with real data. Witness actual output.
41
+
42
+ NOT verification: docs updates, status text, saying done, screenshots alone, marker files.
43
+
44
+ ```
45
+ exec:nodejs
46
+ const { fn } = await import('/abs/path/to/module.js');
47
+ console.log(await fn(realInput));
48
+ ```
49
+
50
+ For browser/UI: invoke `browser` skill with real workflows. Server + client features require both exec:nodejs AND browser. After every success: enumerate what remains — never stop at first green.
51
+
52
+ ## CODE EXECUTION
53
+
54
+ **exec:<lang> is the only way to run code.** Bash tool body: `exec:<lang>\n<code>`
55
+
56
+ `exec:nodejs` (default) | `exec:bash` | `exec:python` | `exec:typescript` | `exec:go` | `exec:rust` | `exec:java` | `exec:deno` | `exec:cmd`
57
+
58
+ Only git in bash directly. Background tasks: `exec:sleep\n<id>`, `exec:status\n<id>`, `exec:close\n<id>`. Runner: `exec:runner\nstart|stop|status`.
59
+
60
+ **Execution efficiency — pack every run:**
61
+ - Combine multiple independent operations into one exec call using `Promise.allSettled` or parallel subprocess spawning
62
+ - Each independent idea gets its own try/catch with independent error reporting — never let one failure block another
63
+ - Target under 12s per exec call; split work across multiple calls only when dependencies require it
64
+ - Prefer a single well-structured exec that does 5 things over 5 sequential execs
65
+
66
+ ## CODEBASE EXPLORATION
67
+
68
+ ```
69
+ exec:codesearch
70
+ <natural language description>
71
+ ```
72
+
73
+ ## GIT ENFORCEMENT
74
+
75
+ ```
76
+ exec:bash
77
+ git status --porcelain
78
+ ```
79
+ Must return empty.
80
+
81
+ ```
82
+ exec:bash
83
+ git log origin/main..HEAD --oneline
84
+ ```
85
+ Must return empty. If not: stage → commit → push → re-verify. Local commit without push ≠ complete.
86
+
87
+ ## COMPLETION DEFINITION
88
+
89
+ All of: witnessed end-to-end output | all failure paths exercised | .prd empty | git clean and pushed | `user_steps_remaining=0`
90
+
91
+ ## DO NOT STOP
92
+
93
+ After end-to-end verification passes: read .prd from disk. If any items remain, immediately invoke `gm-execute` skill — do not respond to the user. Only respond when .prd is deleted AND git is clean AND all commits are pushed.
94
+
95
+ ## CONSTRAINTS
96
+
97
+ **Never**: claim done without witnessed output | uncommitted changes | unpushed commits | .prd items remaining | stop at first green | absorb surprises silently | respond to user while .prd has items
98
+
99
+ **Always**: triage failure before snaking | witness end-to-end | snake to planning on any new unknown | enumerate remaining after every success | check .prd after every verification pass
100
+
101
+ ---
102
+
103
+ **→ FORWARD**: .prd items remain → invoke `gm-execute` skill (keep going, do not stop).
104
+ **→ FORWARD**: .prd deleted + feature work pushed → invoke `update-docs` skill.
105
+ **↩ SNAKE to EMIT**: file output wrong → invoke `gm-emit` skill.
106
+ **↩ SNAKE to EXECUTE**: logic wrong → invoke `gm-execute` skill.
107
+ **↩ SNAKE to PLAN**: new unknown or wrong requirements → invoke `planning` skill, restart chain.
@@ -0,0 +1,111 @@
1
+ ---
2
+ name: gm-emit
3
+ description: EMIT phase. Pre-emit debug, write files, post-emit verify from disk. Any new unknown triggers immediate snake back to planning — restart chain.
4
+ ---
5
+
6
+ # GM EMIT — Writing and Verifying Files
7
+
8
+ You are in the **EMIT** phase. Every mutable is KNOWN. Prove the write is correct, write, confirm from disk. Any new unknown = snake to `planning`, restart chain.
9
+
10
+ **GRAPH POSITION**: `PLAN → EXECUTE → [EMIT] → VERIFY → COMPLETE`
11
+ - **Entry**: All .prd mutables resolved. Entered from `gm-execute` or via snake from VERIFY.
12
+
13
+ ## TRANSITIONS
14
+
15
+ **FORWARD**: All gate conditions true simultaneously → invoke `gm-complete` skill
16
+
17
+ **SELF-LOOP**: Post-emit variance with known cause → fix immediately, re-verify, do not advance until zero variance
18
+
19
+ **BACKWARD**:
20
+ - Pre-emit reveals logic error (known mutable) → invoke `gm-execute` skill, re-resolve, return here
21
+ - Pre-emit reveals new unknown → invoke `planning` skill, restart chain
22
+ - Post-emit variance with unknown cause → invoke `planning` skill, restart chain
23
+ - Scope changed → invoke `planning` skill, restart chain
24
+ - From VERIFY: end-to-end reveals broken file → re-enter here, fix, re-verify, re-advance
25
+
26
+ ## MUTABLE DISCIPLINE
27
+
28
+ Each gate condition is a mutable. Pre-emit run witnesses expected value. Post-emit run witnesses current value. Zero variance = resolved. Variance with unknown cause = new unknown = snake to `planning`.
29
+
30
+ ## CODE EXECUTION
31
+
32
+ **exec:<lang> is the only way to run code.** Bash tool body: `exec:<lang>\n<code>`
33
+
34
+ `exec:nodejs` (default) | `exec:bash` | `exec:python` | `exec:typescript` | `exec:go` | `exec:rust` | `exec:java` | `exec:deno` | `exec:cmd`
35
+
36
+ Only git in bash directly. `Bash(node/npm/npx/bun)` = violations. File writes via exec:nodejs + require('fs').
37
+
38
+ **Execution efficiency — pack every run:**
39
+ - Combine multiple independent operations into one exec call using `Promise.allSettled` or parallel subprocess spawning
40
+ - Each independent idea gets its own try/catch with independent error reporting — never let one failure block another
41
+ - Target under 12s per exec call; split work across multiple calls only when dependencies require it
42
+ - Prefer a single well-structured exec that does 5 things over 5 sequential execs
43
+
44
+ ## PRE-EMIT DEBUGGING (before writing any file)
45
+
46
+ 1. Import actual module from disk via `exec:nodejs` — witness current on-disk behavior
47
+ 2. Run proposed logic in isolation WITHOUT writing — witness output with real inputs
48
+ 3. Debug failure paths with real error inputs — record expected values
49
+
50
+ ```
51
+ exec:nodejs
52
+ const { fn } = await import('/abs/path/to/module.js');
53
+ console.log(await fn(realInput));
54
+ ```
55
+
56
+ Pre-emit revealing unexpected behavior → new unknown → snake to `planning`.
57
+
58
+ ## WRITING FILES
59
+
60
+ `exec:nodejs` with `require('fs')`. Write only when every gate mutable is `resolved=true` simultaneously.
61
+
62
+ ## POST-EMIT VERIFICATION (immediately after writing)
63
+
64
+ 1. Re-import the actual file from disk — not in-memory version
65
+ 2. Run same inputs as pre-emit — output must match exactly
66
+ 3. For browser: reload from disk, re-inject `__gm` globals, re-run, compare captures
67
+ 4. Known variance → fix and re-verify | Unknown variance → snake to `planning`
68
+
69
+ ## GATE CONDITIONS (all true simultaneously before advancing)
70
+
71
+ - Pre-emit debug passed with real inputs and error inputs
72
+ - Post-emit verification matches pre-emit exactly
73
+ - Hot reloadable: state outside reloadable modules, handlers swap atomically
74
+ - Crash-proof: catch at every boundary, recovery hierarchy
75
+ - No mocks/fakes/stubs anywhere
76
+ - Files ≤200 lines, no duplicate code, no comments, no hardcoded values
77
+ - CLAUDE.md reflects actual behavior
78
+
79
+ ## CODEBASE EXPLORATION
80
+
81
+ ```
82
+ exec:codesearch
83
+ <natural language description>
84
+ ```
85
+
86
+ Alias: `exec:search`. **Glob, Grep, Read, Explore are hook-blocked** — use `exec:codesearch` exclusively.
87
+
88
+ ## BROWSER DEBUGGING
89
+
90
+ Invoke `browser` skill. Escalation: (1) `exec:browser\n<js>` → (2) `browser` skill → (3) navigate/click → (4) screenshot last resort.
91
+
92
+ ## SELF-CHECK (before and after each file)
93
+
94
+ File ≤200 lines | No duplication | Pre-emit passed | No mocks | No comments | Docs match | All spotted issues fixed
95
+
96
+ ## DO NOT STOP
97
+
98
+ Never respond to the user from this phase. When all gate conditions pass, immediately invoke `gm-complete` skill. Do not pause, summarize, or ask questions.
99
+
100
+ ## CONSTRAINTS
101
+
102
+ **Never**: write before pre-emit passes | advance with post-emit variance | absorb surprises silently | comments | hardcoded values | defer spotted issues | respond to user or pause for input
103
+
104
+ **Always**: pre-emit debug before writing | post-emit verify from disk | snake to planning on any new unknown | fix immediately | invoke next skill immediately when gates pass
105
+
106
+ ---
107
+
108
+ **→ FORWARD**: All gates pass → invoke `gm-complete` skill immediately.
109
+ **↺ SELF-LOOP**: Known post-emit variance → fix, re-verify.
110
+ **↩ SNAKE to EXECUTE**: Known logic error → invoke `gm-execute` skill.
111
+ **↩ SNAKE to PLAN**: Any new unknown → invoke `planning` skill, restart chain.
@@ -0,0 +1,126 @@
1
+ ---
2
+ name: gm-execute
3
+ description: EXECUTE phase. Resolve all mutables via witnessed execution. Any new unknown triggers immediate snake back to planning — restart chain from PLAN.
4
+ ---
5
+
6
+ # GM EXECUTE — Resolving Every Unknown
7
+
8
+ You are in the **EXECUTE** phase. Resolve every named mutable via witnessed execution. Any new unknown = stop, snake to `planning`, restart chain.
9
+
10
+ **GRAPH POSITION**: `PLAN → [EXECUTE] → EMIT → VERIFY → COMPLETE`
11
+ - **Entry**: .prd exists with all unknowns named. Entered from `planning` or via snake from EMIT/VERIFY.
12
+
13
+ ## TRANSITIONS
14
+
15
+ **FORWARD**: All mutables KNOWN → invoke `gm-emit` skill
16
+
17
+ **SELF-LOOP**: Mutable still UNKNOWN after one pass → re-run with different angle (max 2 passes then snake)
18
+
19
+ **BACKWARD**:
20
+ - New unknown discovered → invoke `planning` skill immediately, restart chain
21
+ - From EMIT: logic error → re-enter here, re-resolve mutable
22
+ - From VERIFY: runtime failure → re-enter here, re-resolve with real system state
23
+
24
+ ## MUTABLE DISCIPLINE
25
+
26
+ Each mutable: name | expected | current | resolution method. Execute → witness → assign → compare. Zero variance = resolved. Unresolved after 2 passes = new unknown = snake to `planning`. Never narrate past an unresolved mutable.
27
+
28
+ ## CODE EXECUTION
29
+
30
+ **exec:<lang> is the only way to run code.** Bash tool body: `exec:<lang>\n<code>`
31
+
32
+ `exec:nodejs` (default) | `exec:bash` | `exec:python` | `exec:typescript` | `exec:go` | `exec:rust` | `exec:c` | `exec:cpp` | `exec:java` | `exec:deno` | `exec:cmd`
33
+
34
+ Lang auto-detected if omitted. `cwd` sets directory. File I/O via exec:nodejs + require('fs'). Only git in bash directly. `Bash(node/npm/npx/bun)` = violations.
35
+
36
+ **Execution efficiency — pack every run:**
37
+ - Combine multiple independent operations into one exec call using `Promise.allSettled` or parallel subprocess spawning
38
+ - Each independent idea gets its own try/catch with independent error reporting — never let one failure block another
39
+ - Target under 12s per exec call; split work across multiple calls only when dependencies require it
40
+ - Prefer a single well-structured exec that does 5 things over 5 sequential execs
41
+
42
+ **Background tasks** (auto-backgrounded when execution exceeds 15s):
43
+ ```
44
+ exec:sleep
45
+ <task_id> [seconds]
46
+ ```
47
+ ```
48
+ exec:status
49
+ <task_id>
50
+ ```
51
+ ```
52
+ exec:close
53
+ <task_id>
54
+ ```
55
+
56
+ **Runner**:
57
+ ```
58
+ exec:runner
59
+ start|stop|status
60
+ ```
61
+
62
+ ## CODEBASE EXPLORATION
63
+
64
+ ```
65
+ exec:codesearch
66
+ <natural language description of what you need>
67
+ ```
68
+
69
+ Alias: `exec:search`. **Glob, Grep, Read, Explore, WebSearch are hook-blocked** — the pre-tool-use hook denies them. Use `exec:codesearch` exclusively for all codebase discovery.
70
+
71
+ ## IMPORT-BASED DEBUGGING
72
+
73
+ Always import actual codebase modules. Never rewrite logic inline.
74
+
75
+ ```
76
+ exec:nodejs
77
+ const { fn } = await import('/abs/path/to/module.js');
78
+ console.log(await fn(realInput));
79
+ ```
80
+
81
+ Witnessed import output = resolved mutable. Reimplemented output = UNKNOWN.
82
+
83
+ ## EXECUTION DENSITY
84
+
85
+ Pack every related hypothesis into one run. Each run ≤15s. Witnessed output = ground truth. Narrated assumption = nothing.
86
+
87
+ Parallel waves: ≤3 `gm:gm` subagents via Task tool — independent items simultaneously, never sequentially.
88
+
89
+ ## CHAIN DECOMPOSITION
90
+
91
+ Break every multi-step operation before running end-to-end:
92
+ 1. Number every distinct step
93
+ 2. Per step: input shape, output shape, success condition, failure mode
94
+ 3. Run each step in isolation — witness — assign mutable — KNOWN before next
95
+ 4. Debug adjacent pairs for handoff correctness
96
+ 5. Only when all pairs pass: run full chain end-to-end
97
+
98
+ Step failure revealing new unknown → snake to `planning`.
99
+
100
+ ## BROWSER DEBUGGING
101
+
102
+ Invoke `browser` skill. Escalation — exhaust each before advancing:
103
+ 1. `exec:browser\n<js>` — query DOM/state. Always first.
104
+ 2. `browser` skill — for full session workflows
105
+ 3. navigate/click/type — only when real events required
106
+ 4. screenshot — last resort
107
+
108
+ ## GROUND TRUTH
109
+
110
+ Real services, real data, real timing. Mocks/fakes/stubs = delete immediately. No .test.js/.spec.js. Delete on discovery.
111
+
112
+ ## DO NOT STOP
113
+
114
+ Never respond to the user from this phase. When all mutables are KNOWN, immediately invoke `gm-emit` skill. The chain continues until .prd is deleted and git is clean — that happens in `gm-complete`, not here.
115
+
116
+ ## CONSTRAINTS
117
+
118
+ **Never**: `Bash(node/npm/npx/bun)` | fake data | mock files | Glob/Grep/Read/Explore (hook-blocked — use exec:codesearch) | sequential independent items | absorb surprises silently | respond to user or pause for input
119
+
120
+ **Always**: witness every hypothesis | import real modules | snake to planning on any new unknown | fix immediately on discovery | invoke next skill immediately when done
121
+
122
+ ---
123
+
124
+ **→ FORWARD**: All mutables KNOWN → invoke `gm-emit` skill immediately.
125
+ **↺ SELF-LOOP**: Still UNKNOWN → re-run (max 2 passes).
126
+ **↩ SNAKE to PLAN**: Any new unknown → invoke `planning` skill, restart chain.
@@ -0,0 +1,93 @@
1
+ ---
2
+ name: planning
3
+ description: Mutable discovery and PRD construction. Invoke at session start and any time new unknowns surface during execution. Loop until no new mutables are discovered.
4
+ allowed-tools: Write
5
+ ---
6
+
7
+ # PRD Construction — Mutable Discovery Loop
8
+
9
+ You are in the **PLAN** phase. Your job is to discover every unknown before execution begins.
10
+
11
+ **GRAPH POSITION**: `[PLAN] → EXECUTE → EMIT → VERIFY → COMPLETE`
12
+ - **Entry chain**: prompt-submit hook → `gm` skill → `planning` skill (here).
13
+ - **Also entered**: any time a new unknown surfaces in EXECUTE, EMIT, or VERIFY.
14
+
15
+ ## TRANSITIONS
16
+
17
+ **FORWARD**:
18
+ - No new mutables discovered in latest pass → .prd is complete → invoke `gm-execute` skill
19
+
20
+ **SELF-LOOP (stay in PLAN)**:
21
+ - Each planning pass may surface new unknowns → add them to .prd → plan again
22
+ - Loop until a full pass produces zero new items
23
+ - Do not advance to EXECUTE while unknowns remain discoverable through reasoning alone
24
+
25
+ **BACKWARD (snakes back here from later phases)**:
26
+ - From EXECUTE: execution reveals an unknown not in .prd → snake here, add it, re-plan
27
+ - From EMIT: scope shifted mid-write → snake here, revise affected items, re-plan
28
+ - From VERIFY: end-to-end reveals requirement was wrong → snake here, rewrite items, re-plan
29
+
30
+ ## WHAT PLANNING MEANS
31
+
32
+ Planning = exhaustive mutable discovery. For every aspect of the task ask:
33
+ - What do I not know? → name it as a mutable
34
+ - What could go wrong? → name it as an edge case item
35
+ - What depends on what? → map blocking/blockedBy
36
+ - What assumptions am I making? → validate each as a mutable
37
+
38
+ **Iterate until**: a full reasoning pass adds zero new items to .prd.
39
+
40
+ Categories of unknowns to enumerate: file existence | API shape | data format | dependency versions | runtime behavior | environment differences | error conditions | concurrency | integration points | backwards compatibility | rollback paths | deployment steps | verification criteria
41
+
42
+ ## .PRD FORMAT
43
+
44
+ Path: exactly `./.prd` in current working directory. **JSON array** written via `exec:nodejs`.
45
+
46
+ **Delete the file when empty.** Do not leave an empty `.prd` on disk — remove it entirely when all items are completed.
47
+
48
+ ```json
49
+ [
50
+ {
51
+ "id": "descriptive-kebab-id",
52
+ "subject": "Imperative verb phrase — what must be true when done",
53
+ "status": "pending",
54
+ "description": "Precise completion criterion",
55
+ "effort": "small|medium|large",
56
+ "category": "feature|bug|refactor|infra",
57
+ "blocking": ["ids this prevents from starting"],
58
+ "blockedBy": ["ids that must complete first"],
59
+ "acceptance": ["measurable, binary criterion 1"],
60
+ "edge_cases": ["known failure mode 1"]
61
+ }
62
+ ]
63
+ ```
64
+
65
+ **Status flow**: `pending` → `in_progress` → `completed` (completed items are removed from array).
66
+ **Effort**: `small` = single execution, under 15min | `medium` = 2-3 rounds, under 45min | `large` = multiple rounds, over 1h.
67
+ **blocking/blockedBy**: always bidirectional. Every dependency must be explicit in both directions.
68
+ **Deletion rule**: when the last item is completed and removed, delete the `.prd` file. An empty file is a violation.
69
+
70
+ ## EXECUTION WAVES
71
+
72
+ Independent items (empty `blockedBy`) run in parallel waves of ≤3 subagents.
73
+ - Find all pending items with empty `blockedBy`
74
+ - Launch ≤3 parallel `gm:gm` subagents via Task tool
75
+ - Each subagent handles one item: resolves it, witnesses output, removes from .prd
76
+ - After each wave: check newly unblocked items, launch next wave
77
+ - Never run independent items sequentially. Never launch more than 3 at once.
78
+
79
+ ## COMPLETION CRITERION
80
+
81
+ .prd is ready when: one full reasoning pass produces zero new items AND all items have explicit acceptance criteria AND all dependencies are mapped.
82
+
83
+ **Skip planning entirely** if: task is single-step, trivially bounded, zero unknowns, under 5 minutes.
84
+
85
+ ## DO NOT STOP
86
+
87
+ Never respond to the user from this phase. When .prd is complete (zero new items in last pass), immediately invoke `gm-execute` skill. Do not pause, summarize, or ask for confirmation.
88
+
89
+ ---
90
+
91
+ **→ FORWARD**: No new mutables → invoke `gm-execute` skill immediately.
92
+ **↺ SELF-LOOP**: New items discovered → add to .prd → plan again.
93
+ **↩ SNAKE here**: New unknown surfaces in any later phase → add it, re-plan, re-advance.
@@ -0,0 +1,86 @@
1
+ ---
2
+ name: ssh
3
+ description: Run shell commands on remote SSH hosts via exec:ssh. Reads targets from ~/.claude/ssh-targets.json. Use for deploying, monitoring, or controlling remote machines.
4
+ ---
5
+
6
+ # exec:ssh — Remote SSH Execution
7
+
8
+ Runs shell commands on a remote host over SSH. No shell open, no manual connection — just write the command.
9
+
10
+ ## Setup
11
+
12
+ Create `~/.claude/ssh-targets.json`:
13
+
14
+ ```json
15
+ {
16
+ "default": {
17
+ "host": "192.168.1.10",
18
+ "port": 22,
19
+ "username": "pi",
20
+ "password": "yourpassword"
21
+ },
22
+ "prod": {
23
+ "host": "10.0.0.1",
24
+ "username": "ubuntu",
25
+ "keyPath": "/home/user/.ssh/id_rsa"
26
+ }
27
+ }
28
+ ```
29
+
30
+ Fields: `host` (required), `port` (default 22), `username` (required), `password` OR `keyPath` + optional `passphrase`.
31
+
32
+ ## Usage
33
+
34
+ ```
35
+ exec:ssh
36
+ <shell command>
37
+ ```
38
+
39
+ Target a named host with `@name` on the first line:
40
+
41
+ ```
42
+ exec:ssh
43
+ @prod
44
+ sudo systemctl restart myapp
45
+ ```
46
+
47
+ Multi-line scripts work:
48
+
49
+ ```
50
+ exec:ssh
51
+ cd /var/log && tail -20 syslog
52
+ ```
53
+
54
+ ## Process Persistence
55
+
56
+ SSH sessions kill child processes on close. To keep a process running after the command returns:
57
+
58
+ ```
59
+ exec:ssh
60
+ sudo systemctl reset-failed myunit 2>/dev/null; systemd-run --unit=myunit bash -c 'your-long-running-command'
61
+ ```
62
+
63
+ Always call `systemctl reset-failed <unit>` before reusing a unit name, or use a unique timestamped name:
64
+
65
+ ```
66
+ exec:ssh
67
+ systemd-run --unit=job-$(date +%s) bash -c 'nohup myprogram &'
68
+ ```
69
+
70
+ Fallback if systemd unavailable:
71
+
72
+ ```
73
+ exec:ssh
74
+ setsid nohup bash -c 'myprogram > /tmp/out.log 2>&1' &
75
+ ```
76
+
77
+ ## Dependency
78
+
79
+ Requires `ssh2` npm package. Install in `~/.claude/gm-tools`:
80
+
81
+ ```
82
+ exec:bash
83
+ cd ~/.claude/gm-tools && npm install ssh2
84
+ ```
85
+
86
+ The plugin searches: `~/.claude/gm-tools/node_modules/ssh2`, `~/.claude/plugins/node_modules/ssh2`, then global.
@@ -0,0 +1,113 @@
1
+ ---
2
+ name: update-docs
3
+ description: UPDATE-DOCS phase. Refresh README.md, CLAUDE.md, and docs/index.html to reflect changes made this session. Commits and pushes doc updates. Terminal phase — declares COMPLETE.
4
+ ---
5
+
6
+ # GM UPDATE-DOCS — Documentation Refresh
7
+
8
+ You are in the **UPDATE-DOCS** phase. Feature work is verified and pushed. Refresh all documentation to match the actual codebase state right now.
9
+
10
+ **GRAPH POSITION**: `PLAN → EXECUTE → EMIT → VERIFY → [UPDATE-DOCS] → COMPLETE`
11
+ - **Entry**: Feature work verified, committed, and pushed. Entered from `gm-complete`.
12
+
13
+ ## TRANSITIONS
14
+
15
+ **FORWARD**: All docs updated, committed, and pushed → COMPLETE (session ends)
16
+
17
+ **BACKWARD**:
18
+ - Diff reveals unknown architecture change → invoke `planning` skill, restart chain
19
+ - Doc write fails post-emit verify → fix and re-verify before advancing
20
+
21
+ ## EXECUTION SEQUENCE
22
+
23
+ **Step 1 — Understand what changed**:
24
+
25
+ ```
26
+ exec:bash
27
+ git log -5 --oneline
28
+ git diff HEAD~1 --stat
29
+ ```
30
+
31
+ Witness which files changed. Identify doc-sensitive changes: new skills, new states in the state machine, new platforms, modified architecture, new constraints, renamed files.
32
+
33
+ **Step 2 — Read current docs**:
34
+
35
+ ```
36
+ exec:nodejs
37
+ const fs = require('fs');
38
+ ['README.md', 'CLAUDE.md', 'docs/index.html',
39
+ 'plugforge-starter/agents/gm.md'].forEach(f => {
40
+ try { console.log(`=== ${f} ===\n` + fs.readFileSync(f, 'utf8')); }
41
+ catch(e) { console.log(`MISSING: ${f}`); }
42
+ });
43
+ ```
44
+
45
+ Identify every section that no longer matches the actual codebase state.
46
+
47
+ **Step 3 — Write updated docs**:
48
+
49
+ Write only sections that changed. Do not rewrite unchanged content. Rules per file:
50
+
51
+ **README.md**: platform count matches adapters in `platforms/`, skill tree diagram matches current state machine, quick start commands work.
52
+
53
+ **CLAUDE.md**: Only non-obvious technical caveats that required multiple runs to discover — things that could not be known without hitting the problem first. Remove anything that no longer applies. Never add anything obvious from reading the code or that any developer would already know. The test: "would a developer need to discover this the hard way, or is it self-evident?" If self-evident, exclude it.
54
+
55
+ **docs/index.html**: `PHASES` array matches current skill state machine phases. Platform lists match `platforms/` directory. State machine diagram updated if new phases added.
56
+
57
+ **plugforge-starter/agents/gm.md**: Skill chain on the `gm skill →` line updated if new skills were added.
58
+
59
+ ```
60
+ exec:nodejs
61
+ const fs = require('fs');
62
+ fs.writeFileSync('/abs/path/file.md', updatedContent);
63
+ ```
64
+
65
+ **Step 4 — Verify from disk**:
66
+
67
+ ```
68
+ exec:nodejs
69
+ const fs = require('fs');
70
+ const content = fs.readFileSync('/abs/path/file.md', 'utf8');
71
+ console.log(content.includes('expectedString'), content.length);
72
+ ```
73
+
74
+ Witness each written file from disk. Any variance from expected content → fix and re-verify.
75
+
76
+ **Step 5 — Commit and push**:
77
+
78
+ ```
79
+ exec:bash
80
+ git add README.md CLAUDE.md docs/index.html plugforge-starter/agents/gm.md
81
+ git diff --cached --stat
82
+ ```
83
+
84
+ Witness staged files. Then commit and push:
85
+
86
+ ```
87
+ exec:bash
88
+ git commit -m "docs: update documentation to reflect session changes"
89
+ git push -u origin HEAD
90
+ ```
91
+
92
+ Witness push confirmation. Zero variance = COMPLETE.
93
+
94
+ ## DOC FIDELITY RULES
95
+
96
+ Every claim in docs must be verifiable against disk right now:
97
+ - State machine phase names must match skill file `name:` frontmatter
98
+ - Platform names must match adapter class names in `platforms/`
99
+ - File paths must exist on disk
100
+ - Constraint counts must match actual constraints
101
+
102
+ If a doc section cannot be verified against disk: remove it, do not speculate.
103
+
104
+ ## CONSTRAINTS
105
+
106
+ **Never**: skip diff analysis | write docs from memory alone | push without verifying from disk | add comments to doc content | claim done without witnessed push output
107
+
108
+ **Always**: witness git diff first | read current file before overwriting | verify each file from disk after write | push doc changes | confirm with witnessed push output
109
+
110
+ ---
111
+
112
+ **→ COMPLETE**: Docs committed and pushed → session ends.
113
+ **↩ SNAKE to PLAN**: New unknown about codebase state → invoke `planning` skill.