gm-oc 2.0.333 → 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 +2 -1
- package/skills/browser/SKILL.md +175 -0
- package/skills/create-lang-plugin/SKILL.md +180 -0
- package/skills/gm/SKILL.md +125 -0
- package/skills/gm-complete/SKILL.md +107 -0
- package/skills/gm-emit/SKILL.md +111 -0
- package/skills/gm-execute/SKILL.md +126 -0
- package/skills/planning/SKILL.md +93 -0
- package/skills/ssh/SKILL.md +86 -0
- package/skills/update-docs/SKILL.md +113 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gm-oc",
|
|
3
|
-
"version": "2.0.
|
|
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.
|