gm-hermes 2.0.515

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.
@@ -0,0 +1,258 @@
1
+ ---
2
+ name: pages
3
+ description: Scaffold and maintain a GitHub Pages site. Buildless in browser (webjsx + rippleui via CDN), flatspace for content aggregation built during GH Actions. Use when user wants to create or update a GH Pages site.
4
+ ---
5
+
6
+ # Pages — GitHub Pages Site Scaffolder
7
+
8
+ Scaffold a complete GH Pages site: **no local build step**, content managed via flatspace flat-file CMS, UI via webjsx + rippleui CDN, GH Actions builds and deploys.
9
+
10
+ **Follow full gm skill chain: planning → gm-execute → gm-emit → gm-complete → update-docs.**
11
+
12
+ ## Stack
13
+
14
+ | Layer | Tool | How |
15
+ |-------|------|-----|
16
+ | UI rendering | [webjsx](https://webjsx.org) | ES module via importmap, `applyDiff` for DOM updates |
17
+ | Styling | [rippleui](https://ripple-ui.com) | CDN `<link>` — Tailwind-based component classes |
18
+ | Content CMS | [flatspace](https://npmjs.com/package/flatspace) | Aggregates `content/` → `docs/data/*.json` at build time |
19
+ | Build | GH Actions | `npx flatspace` runs in CI, commits output to `docs/` |
20
+ | Hosting | GitHub Pages | Source: `docs/` branch, or GH Actions deploy |
21
+
22
+ ## Directory Layout
23
+
24
+ ```
25
+ <project>/
26
+ content/ # Source content (markdown, json, yaml)
27
+ pages/ # Static pages (index.md, about.md, ...)
28
+ posts/ # Blog posts or articles
29
+ data/ # Structured data files
30
+ docs/ # GH Pages root (gitignored build output except index.html)
31
+ index.html # Entry point — committed, never regenerated
32
+ app.js # Main webjsx app — committed
33
+ data/ # flatspace output — gitignored, built by CI
34
+ .github/
35
+ workflows/
36
+ pages.yml # Build + deploy workflow
37
+ flatspace.config.js # flatspace aggregation config
38
+ ```
39
+
40
+ ## index.html — Buildless Entry
41
+
42
+ ```html
43
+ <!DOCTYPE html>
44
+ <html lang="en">
45
+ <head>
46
+ <meta charset="UTF-8">
47
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
48
+ <title>{{SITE_TITLE}}</title>
49
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/rippleui@1.12.1/dist/css/styles.css">
50
+ <script type="importmap">
51
+ {
52
+ "imports": {
53
+ "webjsx": "https://cdn.jsdelivr.net/npm/webjsx@0.0.42/dist/index.js",
54
+ "webjsx/jsx-runtime": "https://cdn.jsdelivr.net/npm/webjsx@0.0.42/dist/jsx-runtime.js"
55
+ }
56
+ }
57
+ </script>
58
+ <script type="module" src="./app.js"></script>
59
+ </head>
60
+ <body class="bg-backgroundPrimary text-content1 min-h-screen">
61
+ <div id="root"></div>
62
+ </body>
63
+ </html>
64
+ ```
65
+
66
+ ## app.js — webjsx App Pattern
67
+
68
+ ```js
69
+ import { applyDiff } from 'webjsx';
70
+
71
+ const h = (tag, props, ...children) => ({ tag, props: props || {}, children });
72
+
73
+ const state = { page: null, data: {} };
74
+
75
+ async function loadData(path) {
76
+ const res = await fetch(path);
77
+ return res.json();
78
+ }
79
+
80
+ function render() {
81
+ applyDiff(document.getElementById('root'), App(state));
82
+ }
83
+
84
+ function App(s) {
85
+ if (!s.page) return h('div', { class: 'flex justify-center p-8' },
86
+ h('span', { class: 'spinner' })
87
+ );
88
+ return h('div', { class: 'max-w-4xl mx-auto p-4' },
89
+ h('nav', { class: 'navbar bg-backgroundSecondary mb-6' },
90
+ h('span', { class: 'navbar-brand text-xl font-bold' }, s.page.title)
91
+ ),
92
+ h('main', {}, ...s.page.sections.map(Section))
93
+ );
94
+ }
95
+
96
+ function Section(section) {
97
+ return h('section', { class: 'card mb-4 p-6' },
98
+ h('h2', { class: 'text-2xl font-bold mb-2' }, section.title),
99
+ h('p', { class: 'text-content2' }, section.body)
100
+ );
101
+ }
102
+
103
+ async function main() {
104
+ state.page = await loadData('./data/index.json');
105
+ render();
106
+ }
107
+
108
+ main();
109
+ ```
110
+
111
+ ## flatspace.config.js
112
+
113
+ ```js
114
+ module.exports = {
115
+ input: './content',
116
+ output: './docs/data',
117
+ collections: {
118
+ pages: { dir: 'pages', format: 'markdown' },
119
+ posts: { dir: 'posts', format: 'markdown', sortBy: 'date', order: 'desc' },
120
+ data: { dir: 'data', format: 'json' }
121
+ }
122
+ };
123
+ ```
124
+
125
+ ## GH Actions Workflow — pages.yml
126
+
127
+ ```yaml
128
+ name: Deploy GitHub Pages
129
+
130
+ on:
131
+ push:
132
+ branches: [main]
133
+ workflow_dispatch:
134
+
135
+ permissions:
136
+ contents: write
137
+ pages: write
138
+ id-token: write
139
+
140
+ jobs:
141
+ build:
142
+ runs-on: ubuntu-latest
143
+ steps:
144
+ - uses: actions/checkout@v4
145
+
146
+ - uses: actions/setup-node@v4
147
+ with:
148
+ node-version: '20'
149
+
150
+ - name: Build content with flatspace
151
+ run: npx flatspace
152
+
153
+ - name: Commit built data
154
+ run: |
155
+ git config user.name "github-actions[bot]"
156
+ git config user.email "github-actions[bot]@users.noreply.github.com"
157
+ git add docs/data/
158
+ git diff --staged --quiet || git commit -m "chore: build content [skip ci]"
159
+ git push
160
+
161
+ - name: Upload Pages artifact
162
+ uses: actions/upload-pages-artifact@v3
163
+ with:
164
+ path: docs/
165
+
166
+ deploy:
167
+ needs: build
168
+ runs-on: ubuntu-latest
169
+ environment:
170
+ name: github-pages
171
+ url: ${{ steps.deployment.outputs.page_url }}
172
+ steps:
173
+ - id: deployment
174
+ uses: actions/deploy-pages@v4
175
+ ```
176
+
177
+ ## Scaffolding Steps
178
+
179
+ When user says "set up pages" or "create GH pages site":
180
+
181
+ 1. **Read** existing `docs/` and `content/` if present — never clobber existing content
182
+ 2. **Create** directory structure above
183
+ 3. **Write** `docs/index.html` with correct site title
184
+ 4. **Write** `docs/app.js` with webjsx app skeleton
185
+ 5. **Write** `flatspace.config.js`
186
+ 6. **Write** `.github/workflows/pages.yml`
187
+ 7. **Write** `content/pages/index.md` with minimal frontmatter (`title`, `sections` array)
188
+ 8. **Add** `docs/data/` to `.gitignore` (built by CI, not committed by humans)
189
+ 9. **Verify** GH Pages setting is "GitHub Actions" in repo Settings — remind user if can't verify
190
+
191
+ ## rippleui Component Classes Quick Reference
192
+
193
+ Use these directly in JSX className strings — no config needed:
194
+
195
+ | Component | Class |
196
+ |-----------|-------|
197
+ | Button | `btn btn-primary`, `btn btn-secondary`, `btn btn-ghost` |
198
+ | Card | `card p-4` |
199
+ | Input | `input input-primary` |
200
+ | Navbar | `navbar` + `navbar-brand` |
201
+ | Badge | `badge badge-primary` |
202
+ | Alert | `alert alert-success`, `alert alert-error` |
203
+ | Spinner | `spinner` |
204
+ | Divider | `divider` |
205
+
206
+ Background: `bg-backgroundPrimary`, `bg-backgroundSecondary`. Text: `text-content1`, `text-content2`.
207
+
208
+ **CSS variable warning**: rippleui color vars (e.g. `--gray-2`) are raw space-separated RGB tuples — not valid CSS colors. Never use them in `rgb()` directly from JS. Use the component classes instead.
209
+
210
+ ## webjsx Patterns
211
+
212
+ **No JSX transpile needed** — use `h()` factory or import from CDN with importmap and write JSX in `.jsx` files served directly (Chrome supports importmap natively).
213
+
214
+ For `.js` files without transpile, use the `h` factory pattern shown above.
215
+
216
+ For `.jsx` with native importmap (no build):
217
+ ```js
218
+ /** @jsxImportSource webjsx */
219
+ import { applyDiff } from 'webjsx';
220
+ ```
221
+ Only works if server sets correct MIME type for `.jsx` — GH Pages does not. Use `.js` + `h()` factory.
222
+
223
+ **applyDiff signature**: `applyDiff(domNode, vnodeOrArray)` — never pass a string, always pass a vnode from `h()`.
224
+
225
+ **State updates**: mutate `state`, call `render()` — no reactive system, explicit re-render on every change.
226
+
227
+ ## Content Format (flatspace input)
228
+
229
+ Markdown with YAML frontmatter:
230
+ ```markdown
231
+ ---
232
+ title: Home
233
+ sections:
234
+ - title: Welcome
235
+ body: Hello world
236
+ ---
237
+
238
+ # Home
239
+
240
+ Full markdown body here.
241
+ ```
242
+
243
+ flatspace outputs `docs/data/pages/index.json`:
244
+ ```json
245
+ { "title": "Home", "sections": [...], "body": "<p>Full markdown body here.</p>", "slug": "index" }
246
+ ```
247
+
248
+ ## Known Gotchas
249
+
250
+ **GH Pages must be set to "GitHub Actions"** in Settings → Pages. "Deploy from branch" ignores the deploy-pages action entirely.
251
+
252
+ **docs/data/ must be in .gitignore** but `docs/index.html` and `docs/app.js` must NOT be ignored — they are the committed source files.
253
+
254
+ **flatspace npx cold start**: first CI run downloads flatspace — takes ~10s extra. Subsequent runs use cache if `actions/setup-node` cache is configured.
255
+
256
+ **importmap browser support**: all modern browsers support importmap. No IE, no Safari < 16.4. For GH Pages this is fine.
257
+
258
+ **webjsx CDN version**: pin to explicit version in importmap (e.g. `@0.0.42`) — avoid `@latest` to prevent silent breakage on upstream updates.
@@ -0,0 +1,177 @@
1
+ ---
2
+ name: planning
3
+ description: State machine orchestrator. Mutable discovery, PRD construction, and full PLAN→EXECUTE→EMIT→VERIFY→COMPLETE lifecycle. Invoke at session start and on any new unknown.
4
+ allowed-tools: Write
5
+ ---
6
+
7
+ # Planning — State Machine Orchestrator
8
+
9
+ Root of all work. Runs `PLAN → EXECUTE → EMIT → VERIFY → UPDATE-DOCS → COMPLETE`.
10
+
11
+ **Entry**: prompt-submit hook → `gm` agent → invoke `planning` skill (here). Also re-entered any time a new unknown surfaces in any phase.
12
+
13
+ ## STATE MACHINE
14
+
15
+ **FORWARD**: PLAN complete → `gm-execute` | EXECUTE complete → `gm-emit` | EMIT complete → `gm-complete` | VERIFY .prd remains → `gm-execute` | VERIFY .prd empty+pushed → `update-docs`
16
+
17
+ **REGRESSIONS**: new unknown at any state → re-invoke `planning` | EXECUTE unresolvable 2 passes → `planning` | EMIT logic error → `gm-execute` | EMIT new unknown → `planning` | VERIFY broken output → `gm-emit` | VERIFY logic wrong → `gm-execute` | VERIFY new unknown → `planning`
18
+
19
+ **Runs until**: .gm/prd.yml empty AND git clean AND all pushes confirmed AND CI green.
20
+
21
+ ## ENFORCEMENT — COMPLETE EVERY TASK END-TO-END
22
+
23
+ **Cannot respond or stop while**:
24
+ - .gm/prd.yml exists and has items
25
+ - git has uncommitted changes
26
+ - git has unpushed commits
27
+
28
+ The skill chain MUST be followed completely end-to-end without exception. Partial execution = violation. After every phase: read .prd, check git, invoke next skill.
29
+
30
+ ## PLAN PHASE — MUTABLE DISCOVERY
31
+
32
+ Planning = exhaustive fault-surface enumeration. For every aspect of the task:
33
+ - What do I not know? → mutable (UNKNOWN)
34
+ - What could go wrong? → edge case item with failure mode
35
+ - What depends on what? → blocking/blockedBy mapped explicitly
36
+ - What assumptions am I making? → each = unwitnessed hypothesis = mutable until execution proves it
37
+
38
+ **Fault surfaces**: file existence | API shape | data format | dependency versions | runtime behavior | environment differences | error conditions | concurrency hazards | integration seams | backwards compatibility | rollback paths | deployment steps | CI/CD correctness
39
+
40
+ **MANDATORY CODEBASE SCAN**: For every planned item, add `existingImpl=UNKNOWN`. Resolve via exec:codesearch. Existing code serving same concern → consolidation task, not addition. `exec:codesearch` indexes PDFs page-by-page alongside source — spec PDFs, papers, vendor manuals, and RFCs are searchable as code. When planning against a protocol, hardware, or compliance requirement, search the PDF corpus the same way you search source: two words, iterate. A constraint the PRD is missing because it only lives in a PDF is a fault surface — enumerate doc PDFs as scan targets during mutable discovery.
41
+
42
+ **EXIT PLAN**: zero new unknowns in last pass AND all .prd items have explicit acceptance criteria AND all dependencies mapped → launch subagents or invoke `gm-execute`.
43
+
44
+ **SELF-LOOP**: new items discovered → add to .prd → plan again.
45
+
46
+ **Skip planning entirely** (this is the DEFAULT for small work) if ANY of these apply:
47
+ - Single-file, single-concern edit
48
+ - Task is trivially bounded and under ~5 minutes
49
+ - User gave explicit surgical instructions ("change X to Y")
50
+ - Bug fix where root cause is already identified
51
+ - Zero unknowns / no mutables to resolve
52
+
53
+ Heavy ceremony (PRD + parallel subagents) is for multi-file architectural work or genuinely unknown fault surfaces. Writing a 7-item PRD for a 3-line change is waste. Err toward skipping — if a new unknown surfaces mid-work, THAT is when you regress to planning, not preemptively.
54
+
55
+ **Contrast examples:**
56
+ - "Fix the hold-detect logic at apcKey25.cpp:163" → SKIP planning. Read, edit, done.
57
+ - "Add drift correction and watchdog and observability across the USB audio path" → DO plan. Multi-file, multiple unknowns.
58
+
59
+ ## OBSERVABILITY ENUMERATION — MANDATORY EVERY PASS
60
+
61
+ During every planning pass, enumerate every possible aspect of the app's runtime observability that can be improved. The goal is permanent structures — not ad-hoc logs — that make any future debugging session start from a complete, live picture of system state.
62
+
63
+ **Server-side permanent structures**: Every internal subsystem — state machine, queue, cache, connection pool, active task map, process registry, RPC handler, hook dispatcher — must expose a named, queryable inspection endpoint (e.g. `/debug/<subsystem>`). State must be readable, filterable, and ideally modifiable without restart. Profiling hooks on every hot path. Structured logs with subsystem tag, severity, and timestamp — filterable at runtime by subsystem, not just log level. Any internal state that requires a restart to inspect is an observability gap.
64
+
65
+ **Client-side permanent structures**: `window.__debug` must be a live, structured registry — not a dump. Every component's state, every active request, every event queue, every WebSocket connection, every rendered prop, every error boundary — all addressable by key, all queryable without refreshing. New modules register themselves into `window.__debug` on mount and deregister on unmount. Any execution path not traceable via `window.__debug` is an observability gap.
66
+
67
+ **Permanent vs ad-hoc**: `console.log` = ad-hoc = not observability. A structured logger with subsystem routing = permanent. `window.__debug.myModule.state` = permanent. `window.__debug = { ...window.__debug, tmp: x }` = ad-hoc = not acceptable. Permanent structures survive deploys and accumulate diagnostic value across sessions.
68
+
69
+ **Mandate**: on discovery of any observability gap → immediately add a .prd item. Observability improvements are highest-priority — never deferred. The agent must be able to see specifically anything it wants and nothing else — no guessing, no blind spots.
70
+
71
+ ## .PRD FORMAT
72
+
73
+ Path: `./.gm/prd.yml`. YAML via `exec:nodejs` (use `fs.writeFileSync`). Ensure `.gm/` dir exists before writing. Delete when empty — never leave empty file. Delete `.gm/` dir when completely empty.
74
+
75
+ ```yaml
76
+ - id: kebab-id
77
+ subject: Imperative verb phrase
78
+ status: pending
79
+ description: Precise criterion
80
+ effort: small|medium|large
81
+ category: feature|bug|refactor|infra
82
+ blocking: []
83
+ blockedBy: []
84
+ acceptance:
85
+ - binary criterion
86
+ edge_cases:
87
+ - failure mode
88
+ ```
89
+
90
+ Status: `pending` → `in_progress` → `completed` (remove completed items). Effort: small <15min | medium <45min | large >1h.
91
+
92
+ ## PARALLEL SUBAGENT LAUNCH
93
+
94
+ After .prd written, launch ≤3 parallel `gm:gm` subagents for all independent items simultaneously. Never sequential.
95
+
96
+ `Agent(subagent_type="gm:gm", prompt="Work on .prd item: <id>. .prd path: <path>. Item: <full YAML>.")`
97
+
98
+ After each wave: read .prd, find newly unblocked items, launch next wave. Exception: browser tasks serialize.
99
+
100
+ When parallelism not applicable: invoke `gm-execute` skill directly.
101
+
102
+ ## MUTABLE DISCIPLINE
103
+
104
+ Each mutable: name | expected | current | resolution method. Resolve by witnessed execution only. Zero variance = resolved. Unresolved after 2 passes = new unknown = re-invoke `planning`. Mutables live in conversation only.
105
+
106
+ ## CODE EXECUTION
107
+
108
+ `exec:<lang>` only. Bash body: `exec:<lang>\n<code>`
109
+
110
+ `exec:nodejs` | `exec:bash` | `exec:python` | `exec:typescript` | `exec:go` | `exec:rust` | `exec:c` | `exec:cpp` | `exec:java` | `exec:deno` | `exec:cmd`
111
+
112
+ File I/O: exec:nodejs + require('fs'). Git only in Bash directly. `Bash(node/npm/npx/bun)` = violation.
113
+
114
+ Pack runs: `Promise.allSettled` for parallel ops. Each idea its own try/catch. Under 12s per call.
115
+
116
+ Background: `exec:sleep <id>` | `exec:status <id>` | `exec:close <id>`. Runner: `exec:runner start|stop|status`.
117
+
118
+ ## CODEBASE EXPLORATION
119
+
120
+ `exec:codesearch` only. Glob/Grep/Read/Explore/WebSearch = hook-blocked. Start 2 words → change one word → add third → minimum 4 attempts before concluding absent.
121
+
122
+ ## BROWSER AUTOMATION
123
+
124
+ Invoke `browser` skill. Escalation: (1) `exec:browser <js>` → (2) browser skill → (3) navigate/click → (4) screenshot last resort. Browser tasks serialize — one Chrome instance per project.
125
+
126
+ ## SKILL REGISTRY
127
+
128
+ `gm-execute` → `gm-emit` → `gm-complete` → `update-docs` | `browser` | `memorize` (sub-agent, background only)
129
+
130
+ `memorize`: `Agent(subagent_type='memorize', model='haiku', run_in_background=true, prompt='## CONTEXT TO MEMORIZE\n<what>')`
131
+
132
+ ## MANDATORY DEV WORKFLOW
133
+
134
+ No comments. No scattered test files. 200-line limit — split before continuing. Fail loud. No duplication. Scan before every edit. Duplicate concern = regress to PLAN. Errors throw with context — no `|| default`, no `catch { return null }`. `window.__debug` exposes all client state. AGENTS.md via memorize only. CHANGELOG.md: append per commit.
135
+
136
+ **Minimal code / maximal DX process**: Before writing any logic, run this process in order — stop at the first step that resolves the need:
137
+ 1. **Native first** — does the language or runtime already do this? Use it exactly as designed.
138
+ 2. **Library second** — does an existing dependency already solve this pattern? Use its API directly.
139
+ 3. **Structure third** — can the problem be encoded as data (map, table, pipeline) so the structure enforces correctness and eliminates branching entirely?
140
+ 4. **Write last** — only author new logic when the above three are exhausted. New logic = new surface area = new bugs.
141
+
142
+ When structure eliminates a whole class of wrong states — name that pattern explicitly. Dispatch tables replacing switch chains, pipelines replacing loop-with-accumulator, maps replacing if/else forests — these are not just style preferences, they are correctness properties. Code that cannot be wrong because of how it is shaped is the goal. Readable top-to-bottom without mental simulation = done right. Requires decoding = not done.
143
+
144
+ ## SINGLE INTEGRATION TEST POLICY
145
+
146
+ Every project maintains exactly one `test.js` at project root. 200-line max. No other test files anywhere — no `.test.js`, `.spec.js`, `__tests__/`, `fixtures/`, `mocks/`. Delete all scattered tests on discovery and consolidate coverage into `test.js`.
147
+
148
+ **test.js replaces all unit tests.** It tests the real system end-to-end with real data. No mocks, no stubs, no test frameworks. Plain node assertions or process exit codes.
149
+
150
+ **Creation**: if `test.js` does not exist, create it during EXECUTE phase covering all testable surface of current work.
151
+
152
+ **Maintenance**: every code change that adds or modifies behavior must update `test.js` to cover it. Every bug fix must add a regression case that would have caught the bug.
153
+
154
+ **Structure**: group by subsystem, each subsystem gets a section. When approaching 200 lines, compress older stable tests into tighter assertions to make room for new coverage.
155
+
156
+ **Execution**: `gm-complete` runs `test.js` before allowing completion. Failure = regression to EXECUTE.
157
+
158
+ ## RESPONSE POLICY
159
+
160
+ Terse like smart caveman. Technical substance stays. Fluff dies. Default: **full**. Switch: `/caveman lite|full|ultra`.
161
+
162
+ Drop: articles, filler, pleasantries, hedging. Fragments OK. Short synonyms. Technical terms exact. Code unchanged. Pattern: `[thing] [action] [reason]. [next step].`
163
+
164
+ Levels: **lite** = no filler, full sentences | **full** = drop articles, fragments OK | **ultra** = abbreviate all, arrows for causality | **wenyan-full** = 文言文, 80-90% compression | **wenyan-ultra** = max classical terse.
165
+
166
+ Auto-Clarity: drop caveman for security warnings, irreversible confirmations, ambiguous sequences. Resume after. Code/commits/PRs write normal. "stop caveman" / "normal mode": revert.
167
+
168
+ ## CONSTRAINTS
169
+
170
+ **Tier 0**: no_crash, no_exit, ground_truth_only, real_execution, fail_loud
171
+ **Tier 1**: max_file_lines=200, hot_reloadable, checkpoint_state
172
+ **Tier 2**: no_duplication, no_hardcoded_values, modularity
173
+ **Tier 3**: no_comments, convention_over_code
174
+
175
+ **Never**: `Bash(node/npm/npx/bun)` | skip planning | partial execution | stop while .gm/prd.yml has items | stop while git dirty | sequential independent items | screenshot before JS exhausted | fallback/demo modes | silently swallow errors | duplicate concern | leave comments | create scattered test files (only root test.js) | write if/else chains where a map or pipeline suffices | write one-liners that require decoding | branch on enumerated cases when a dispatch table exists
176
+
177
+ **Always**: invoke named skill at every state transition | regress to planning on any new unknown | witnessed execution only | scan codebase before edits | enumerate every possible observability improvement every planning pass | follow skill chain completely end-to-end on every task without exception | prefer dispatch tables over switch/if chains | prefer pipelines over loop-with-accumulator | make wrong states structurally impossible | name patterns when structure eliminates a whole class of bugs
@@ -0,0 +1,89 @@
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
+ **Use gm subagents for all independent work items. Invoke all skills in the chain: planning → gm-execute → gm-emit → gm-complete → update-docs.**
9
+
10
+
11
+ Runs shell commands on a remote host over SSH. No shell open, no manual connection — just write the command.
12
+
13
+ ## Setup
14
+
15
+ Create `~/.claude/ssh-targets.json`:
16
+
17
+ ```json
18
+ {
19
+ "default": {
20
+ "host": "192.168.1.10",
21
+ "port": 22,
22
+ "username": "pi",
23
+ "password": "yourpassword"
24
+ },
25
+ "prod": {
26
+ "host": "10.0.0.1",
27
+ "username": "ubuntu",
28
+ "keyPath": "/home/user/.ssh/id_rsa"
29
+ }
30
+ }
31
+ ```
32
+
33
+ Fields: `host` (required), `port` (default 22), `username` (required), `password` OR `keyPath` + optional `passphrase`.
34
+
35
+ ## Usage
36
+
37
+ ```
38
+ exec:ssh
39
+ <shell command>
40
+ ```
41
+
42
+ Target a named host with `@name` on the first line:
43
+
44
+ ```
45
+ exec:ssh
46
+ @prod
47
+ sudo systemctl restart myapp
48
+ ```
49
+
50
+ Multi-line scripts work:
51
+
52
+ ```
53
+ exec:ssh
54
+ cd /var/log && tail -20 syslog
55
+ ```
56
+
57
+ ## Process Persistence
58
+
59
+ SSH sessions kill child processes on close. To keep a process running after the command returns:
60
+
61
+ ```
62
+ exec:ssh
63
+ sudo systemctl reset-failed myunit 2>/dev/null; systemd-run --unit=myunit bash -c 'your-long-running-command'
64
+ ```
65
+
66
+ Always call `systemctl reset-failed <unit>` before reusing a unit name, or use a unique timestamped name:
67
+
68
+ ```
69
+ exec:ssh
70
+ systemd-run --unit=job-$(date +%s) bash -c 'nohup myprogram &'
71
+ ```
72
+
73
+ Fallback if systemd unavailable:
74
+
75
+ ```
76
+ exec:ssh
77
+ setsid nohup bash -c 'myprogram > /tmp/out.log 2>&1' &
78
+ ```
79
+
80
+ ## Dependency
81
+
82
+ Requires `ssh2` npm package. Install in `~/.claude/gm-tools`:
83
+
84
+ ```
85
+ exec:bash
86
+ cd ~/.claude/gm-tools && npm install ssh2
87
+ ```
88
+
89
+ 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, AGENTS.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', 'AGENTS.md', 'docs/index.html',
39
+ 'gm-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
+ **AGENTS.md**: Launch memorize sub-agent in background with session learnings. Do not inline-edit AGENTS.md — the memorize agent handles extraction, deduplication, and writing. Use: `Agent(subagent_type='memorize', model='haiku', run_in_background=true, prompt='## CONTEXT TO MEMORIZE\n<session learnings>')`
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
+ **gm-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 docs/index.html gm-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.