gm-cc 2.0.727 → 2.0.1063
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/.claude-plugin/marketplace.json +1 -1
- package/agents/gm.md +1 -3
- package/agents/memorize.md +22 -2
- package/agents/research-worker.md +36 -0
- package/agents/textprocessing.md +47 -0
- package/bin/bootstrap.js +624 -34
- package/bin/plugkit.js +95 -53
- package/bin/plugkit.sha256 +6 -6
- package/bin/plugkit.version +1 -1
- package/bin/rtk.sha256 +6 -0
- package/bin/rtk.version +1 -0
- package/hooks/hooks.json +2 -46
- package/hooks/hooks.spec.json +48 -0
- package/package.json +2 -2
- package/plugin.json +1 -1
- package/skills/browser/SKILL.md +18 -16
- package/skills/code-search/SKILL.md +15 -15
- package/skills/create-lang-plugin/SKILL.md +22 -26
- package/skills/gm/SKILL.md +30 -67
- package/skills/gm-cc/SKILL.md +19 -0
- package/skills/gm-codex/SKILL.md +19 -0
- package/skills/gm-complete/SKILL.md +52 -69
- package/skills/gm-copilot-cli/SKILL.md +19 -0
- package/skills/gm-cursor/SKILL.md +19 -0
- package/skills/gm-emit/SKILL.md +44 -61
- package/skills/gm-execute/SKILL.md +42 -79
- package/skills/gm-gc/SKILL.md +19 -0
- package/skills/gm-jetbrains/SKILL.md +19 -0
- package/skills/gm-kilo/SKILL.md +19 -0
- package/skills/gm-oc/SKILL.md +19 -0
- package/skills/gm-vscode/SKILL.md +19 -0
- package/skills/gm-zed/SKILL.md +19 -0
- package/skills/governance/SKILL.md +24 -23
- package/skills/pages/SKILL.md +42 -92
- package/skills/planning/SKILL.md +53 -86
- package/skills/research/SKILL.md +43 -0
- package/skills/ssh/SKILL.md +15 -9
- package/skills/textprocessing/SKILL.md +40 -0
- package/skills/update-docs/SKILL.md +27 -21
- package/.github/workflows/publish-npm.yml +0 -44
- package/hooks/post-tool-use-hook.js +0 -34
- package/hooks/pre-tool-use-hook.js +0 -45
- package/hooks/prompt-submit-hook.js +0 -19
- package/hooks/session-start-hook.js +0 -23
package/skills/pages/SKILL.md
CHANGED
|
@@ -3,41 +3,37 @@ name: pages
|
|
|
3
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
4
|
---
|
|
5
5
|
|
|
6
|
-
# Pages — GitHub Pages
|
|
6
|
+
# Pages — GitHub Pages site scaffolder
|
|
7
7
|
|
|
8
|
-
Scaffold a complete GH Pages site
|
|
9
|
-
|
|
10
|
-
**Follow full gm skill chain: planning → gm-execute → gm-emit → gm-complete → update-docs.**
|
|
8
|
+
Scaffold a complete GH Pages site with no local build step. Content via flatspace flat-file CMS, UI via webjsx + rippleui CDN, GH Actions builds and deploys. Follow the full chain: `planning → gm-execute → gm-emit → gm-complete → update-docs`.
|
|
11
9
|
|
|
12
10
|
## Stack
|
|
13
11
|
|
|
14
12
|
| Layer | Tool | How |
|
|
15
|
-
|
|
13
|
+
|---|---|---|
|
|
16
14
|
| UI rendering | [webjsx](https://webjsx.org) | ES module via importmap, `applyDiff` for DOM updates |
|
|
17
15
|
| Styling | [rippleui](https://ripple-ui.com) | CDN `<link>` — Tailwind-based component classes |
|
|
18
16
|
| Content CMS | [flatspace](https://npmjs.com/package/flatspace) | Aggregates `content/` → `docs/data/*.json` at build time |
|
|
19
17
|
| Build | GH Actions | `npx flatspace` runs in CI, commits output to `docs/` |
|
|
20
|
-
| Hosting | GitHub Pages | Source
|
|
18
|
+
| Hosting | GitHub Pages | Source set to "GitHub Actions" |
|
|
21
19
|
|
|
22
|
-
##
|
|
20
|
+
## Layout
|
|
23
21
|
|
|
24
22
|
```
|
|
25
23
|
<project>/
|
|
26
|
-
content/
|
|
27
|
-
pages/
|
|
28
|
-
posts/
|
|
29
|
-
data/
|
|
30
|
-
docs/
|
|
31
|
-
index.html
|
|
32
|
-
app.js
|
|
33
|
-
data/
|
|
34
|
-
.github/
|
|
35
|
-
|
|
36
|
-
pages.yml # Build + deploy workflow
|
|
37
|
-
flatspace.config.js # flatspace aggregation config
|
|
24
|
+
content/
|
|
25
|
+
pages/
|
|
26
|
+
posts/
|
|
27
|
+
data/
|
|
28
|
+
docs/
|
|
29
|
+
index.html # committed, never regenerated
|
|
30
|
+
app.js # committed
|
|
31
|
+
data/ # flatspace output, gitignored
|
|
32
|
+
.github/workflows/pages.yml
|
|
33
|
+
flatspace.config.js
|
|
38
34
|
```
|
|
39
35
|
|
|
40
|
-
## index.html
|
|
36
|
+
## index.html
|
|
41
37
|
|
|
42
38
|
```html
|
|
43
39
|
<!DOCTYPE html>
|
|
@@ -63,28 +59,19 @@ Scaffold a complete GH Pages site: **no local build step**, content managed via
|
|
|
63
59
|
</html>
|
|
64
60
|
```
|
|
65
61
|
|
|
66
|
-
## app.js
|
|
62
|
+
## app.js
|
|
67
63
|
|
|
68
64
|
```js
|
|
69
65
|
import { applyDiff } from 'webjsx';
|
|
70
66
|
|
|
71
67
|
const h = (tag, props, ...children) => ({ tag, props: props || {}, children });
|
|
72
|
-
|
|
73
68
|
const state = { page: null, data: {} };
|
|
74
69
|
|
|
75
|
-
async function loadData(path) {
|
|
76
|
-
|
|
77
|
-
return res.json();
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
function render() {
|
|
81
|
-
applyDiff(document.getElementById('root'), App(state));
|
|
82
|
-
}
|
|
70
|
+
async function loadData(path) { return (await fetch(path)).json(); }
|
|
71
|
+
function render() { applyDiff(document.getElementById('root'), App(state)); }
|
|
83
72
|
|
|
84
73
|
function App(s) {
|
|
85
|
-
if (!s.page) return h('div', { class: 'flex justify-center p-8' },
|
|
86
|
-
h('span', { class: 'spinner' })
|
|
87
|
-
);
|
|
74
|
+
if (!s.page) return h('div', { class: 'flex justify-center p-8' }, h('span', { class: 'spinner' }));
|
|
88
75
|
return h('div', { class: 'max-w-4xl mx-auto p-4' },
|
|
89
76
|
h('nav', { class: 'navbar bg-backgroundSecondary mb-6' },
|
|
90
77
|
h('span', { class: 'navbar-brand text-xl font-bold' }, s.page.title)
|
|
@@ -100,11 +87,7 @@ function Section(section) {
|
|
|
100
87
|
);
|
|
101
88
|
}
|
|
102
89
|
|
|
103
|
-
async function main() {
|
|
104
|
-
state.page = await loadData('./data/index.json');
|
|
105
|
-
render();
|
|
106
|
-
}
|
|
107
|
-
|
|
90
|
+
async function main() { state.page = await loadData('./data/index.json'); render(); }
|
|
108
91
|
main();
|
|
109
92
|
```
|
|
110
93
|
|
|
@@ -122,11 +105,10 @@ module.exports = {
|
|
|
122
105
|
};
|
|
123
106
|
```
|
|
124
107
|
|
|
125
|
-
##
|
|
108
|
+
## pages.yml
|
|
126
109
|
|
|
127
110
|
```yaml
|
|
128
111
|
name: Deploy GitHub Pages
|
|
129
|
-
|
|
130
112
|
on:
|
|
131
113
|
push:
|
|
132
114
|
branches: [main]
|
|
@@ -142,14 +124,10 @@ jobs:
|
|
|
142
124
|
runs-on: ubuntu-latest
|
|
143
125
|
steps:
|
|
144
126
|
- uses: actions/checkout@v4
|
|
145
|
-
|
|
146
127
|
- uses: actions/setup-node@v4
|
|
147
|
-
with:
|
|
148
|
-
node-version: '20'
|
|
149
|
-
|
|
128
|
+
with: { node-version: '20' }
|
|
150
129
|
- name: Build content with flatspace
|
|
151
130
|
run: npx flatspace
|
|
152
|
-
|
|
153
131
|
- name: Commit built data
|
|
154
132
|
run: |
|
|
155
133
|
git config user.name "github-actions[bot]"
|
|
@@ -157,11 +135,8 @@ jobs:
|
|
|
157
135
|
git add docs/data/
|
|
158
136
|
git diff --staged --quiet || git commit -m "chore: build content [skip ci]"
|
|
159
137
|
git push
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
uses: actions/upload-pages-artifact@v3
|
|
163
|
-
with:
|
|
164
|
-
path: docs/
|
|
138
|
+
- uses: actions/upload-pages-artifact@v3
|
|
139
|
+
with: { path: docs/ }
|
|
165
140
|
|
|
166
141
|
deploy:
|
|
167
142
|
needs: build
|
|
@@ -174,26 +149,14 @@ jobs:
|
|
|
174
149
|
uses: actions/deploy-pages@v4
|
|
175
150
|
```
|
|
176
151
|
|
|
177
|
-
##
|
|
152
|
+
## Scaffold sequence
|
|
178
153
|
|
|
179
|
-
|
|
154
|
+
Read existing `docs/` and `content/` if present — never clobber existing content. Create the directory structure. Write `docs/index.html`, `docs/app.js`, `flatspace.config.js`, `.github/workflows/pages.yml`, `content/pages/index.md` with minimal frontmatter (`title`, `sections` array). Add `docs/data/` to `.gitignore`. Verify GH Pages setting is "GitHub Actions" in repo Settings — remind the user if you can't verify.
|
|
180
155
|
|
|
181
|
-
|
|
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:
|
|
156
|
+
## rippleui classes
|
|
194
157
|
|
|
195
158
|
| Component | Class |
|
|
196
|
-
|
|
159
|
+
|---|---|
|
|
197
160
|
| Button | `btn btn-primary`, `btn btn-secondary`, `btn btn-ghost` |
|
|
198
161
|
| Card | `card p-4` |
|
|
199
162
|
| Input | `input input-primary` |
|
|
@@ -203,30 +166,18 @@ Use these directly in JSX className strings — no config needed:
|
|
|
203
166
|
| Spinner | `spinner` |
|
|
204
167
|
| Divider | `divider` |
|
|
205
168
|
|
|
206
|
-
Background
|
|
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.
|
|
169
|
+
Background `bg-backgroundPrimary`, `bg-backgroundSecondary`. Text `text-content1`, `text-content2`. rippleui CSS color vars (e.g. `--gray-2`) are raw space-separated RGB tuples — invalid in `rgb()` directly. Use the component classes instead.
|
|
215
170
|
|
|
216
|
-
|
|
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.
|
|
171
|
+
## webjsx
|
|
222
172
|
|
|
223
|
-
|
|
173
|
+
No JSX transpile needed. Use the `h()` factory in `.js` files served directly. `.jsx` with native importmap requires the server to set the correct MIME type, which GH Pages does not — stay in `.js` + `h()`.
|
|
224
174
|
|
|
225
|
-
|
|
175
|
+
`applyDiff(domNode, vnodeOrArray)` — never pass a string. State updates mutate `state` and call `render()`; no reactive system.
|
|
226
176
|
|
|
227
|
-
## Content
|
|
177
|
+
## Content format
|
|
228
178
|
|
|
229
179
|
Markdown with YAML frontmatter:
|
|
180
|
+
|
|
230
181
|
```markdown
|
|
231
182
|
---
|
|
232
183
|
title: Home
|
|
@@ -240,19 +191,18 @@ sections:
|
|
|
240
191
|
Full markdown body here.
|
|
241
192
|
```
|
|
242
193
|
|
|
243
|
-
|
|
194
|
+
Output `docs/data/pages/index.json`:
|
|
195
|
+
|
|
244
196
|
```json
|
|
245
197
|
{ "title": "Home", "sections": [...], "body": "<p>Full markdown body here.</p>", "slug": "index" }
|
|
246
198
|
```
|
|
247
199
|
|
|
248
|
-
##
|
|
249
|
-
|
|
250
|
-
**GH Pages must be set to "GitHub Actions"** in Settings → Pages. "Deploy from branch" ignores the deploy-pages action entirely.
|
|
200
|
+
## Gotchas
|
|
251
201
|
|
|
252
|
-
|
|
202
|
+
GH Pages must be set to "GitHub Actions" in Settings → Pages. "Deploy from branch" ignores the deploy-pages action.
|
|
253
203
|
|
|
254
|
-
|
|
204
|
+
`docs/data/` is gitignored; `docs/index.html` and `docs/app.js` are not — they are the committed source files.
|
|
255
205
|
|
|
256
|
-
|
|
206
|
+
`npx flatspace` cold-start is ~10s on first CI run; subsequent runs use the `actions/setup-node` cache.
|
|
257
207
|
|
|
258
|
-
|
|
208
|
+
Pin the webjsx CDN version in importmap (e.g. `@0.0.42`) — `@latest` breaks silently on upstream updates.
|
package/skills/planning/SKILL.md
CHANGED
|
@@ -1,92 +1,61 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: planning
|
|
3
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:
|
|
4
|
+
allowed-tools: Skill
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
# Planning —
|
|
7
|
+
# Planning — PLAN phase
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Translate the request into `.gm/prd.yml` and hand to `gm-execute`. Re-enter on any new unknown in any phase.
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
A `@<discipline>` sigil in the request scopes recall, codesearch, and memorize calls during PLAN to that discipline's store. Without one, retrievals fan across default plus enabled disciplines and writes land in default only.
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
Cross-cutting dispositions (autonomy, fix-on-sight, nothing-fake, browser-witness, scope, recall, memorize) live in `gm` SKILL.md; this skill only carries what is unique to PLAN.
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
exec:recall
|
|
17
|
-
<2-6 word query>
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
Triggers: matches prior topic | "have we seen this" | designing where prior decision likely exists | quirk feels familiar | sub-task in known project.
|
|
21
|
-
|
|
22
|
-
Hits = weak_prior; witness via EXECUTE before adopting. Skip recall only on brand-new project / trivially-bounded edit / surgical user instruction.
|
|
23
|
-
|
|
24
|
-
## MEMORIZE — HARD RULE
|
|
25
|
-
|
|
26
|
-
Every unknown→known = same-turn memorize. Background, parallel, never batched.
|
|
27
|
-
|
|
28
|
-
```
|
|
29
|
-
Agent(subagent_type='gm:memorize', model='haiku', run_in_background=true, prompt='## CONTEXT TO MEMORIZE\n<fact>')
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
Triggers: exec output answers prior unknown | code read confirms/refutes | CI log reveals root cause | user states preference/constraint | fix worked non-obviously | env quirk observed.
|
|
33
|
-
|
|
34
|
-
N facts → N parallel Agent calls in ONE message.
|
|
35
|
-
|
|
36
|
-
## STATE MACHINE
|
|
37
|
-
|
|
38
|
-
**FORWARD**: PLAN → `gm-execute` | EXECUTE → `gm-emit` | EMIT → `gm-complete` | VERIFY .prd remains → `gm-execute` | VERIFY .prd empty+pushed → `update-docs`
|
|
39
|
-
|
|
40
|
-
**REGRESSIONS**: new unknown anywhere → `planning` | EXECUTE unresolvable 2 passes → `planning` | EMIT logic error → `gm-execute` | VERIFY broken output → `gm-emit` | VERIFY logic wrong → `gm-execute`
|
|
15
|
+
## Transitions
|
|
41
16
|
|
|
42
|
-
|
|
17
|
+
- PLAN done → `gm-execute`
|
|
18
|
+
- New unknown anywhere in chain → re-enter PLAN
|
|
19
|
+
- EXECUTE unresolvable after 2 passes → PLAN
|
|
20
|
+
- VERIFY: `.prd` empty + git clean + pushed → `update-docs`; else → `gm-execute`
|
|
43
21
|
|
|
44
|
-
|
|
22
|
+
Cannot stop while `.gm/prd.yml` has items, git is dirty, or commits are unpushed.
|
|
45
23
|
|
|
46
|
-
|
|
24
|
+
## Orient
|
|
47
25
|
|
|
48
|
-
|
|
26
|
+
Open every plan with one parallel pack of `exec:recall` + `exec:codesearch` against the request's nouns. Hits land as `weak_prior`; misses confirm the unknown is fresh. The pack runs in one message.
|
|
49
27
|
|
|
50
|
-
**
|
|
28
|
+
**Auto-recall injection (skills-only platforms)**: derive a 2–6 word query from the request's nouns (subject, verb objects, key domain terms). Call `exec:recall <query>` at PLAN start before writing `.gm/prd.yml`, inline. This replaces the prompt-submit hook's auto-recall for platforms without hook infrastructure. Recall hits are injected as context into mutable discovery and PRD item acceptance criteria.
|
|
51
29
|
|
|
52
|
-
##
|
|
30
|
+
## Mutable discovery
|
|
53
31
|
|
|
54
|
-
|
|
32
|
+
For each aspect of the work, ask: what do I not know, what could go wrong, what depends on what, what am I assuming. Unwitnessed assumptions are mutables.
|
|
55
33
|
|
|
56
|
-
|
|
34
|
+
Fault surfaces to scan: file existence, API shape, data format, dep versions, runtime behavior, env differences, error conditions, concurrency, integration seams, backwards compat, rollback paths, CI correctness.
|
|
57
35
|
|
|
58
|
-
|
|
36
|
+
Tag every item with a route family (grounding | reasoning | state | execution | observability | boundary | representation) and cross-reference the 16-failure taxonomy. `governance` skill holds the table.
|
|
59
37
|
|
|
60
|
-
|
|
38
|
+
`existingImpl=UNKNOWN` is the default; resolve via `exec:codesearch` before adding the item. An existing concern routes to consolidation, not addition.
|
|
61
39
|
|
|
62
|
-
|
|
40
|
+
Plan exits when zero new unknowns surfaced last pass AND every item has acceptance criteria AND deps are mapped.
|
|
63
41
|
|
|
64
|
-
##
|
|
42
|
+
## .gm/mutables.yml — co-equal with .gm/prd.yml
|
|
65
43
|
|
|
66
|
-
|
|
44
|
+
Every unknown surfaced during PLAN lands as an entry in `.gm/mutables.yml` the same pass. Live during work, deleted when empty. Hook-gated: Write/Edit/NotebookEdit and `git commit`/`git push` are hard-blocked while any entry has `status: unknown`; turn-stop is hard-blocked the same way.
|
|
67
45
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
**EXIT PLAN**: zero new unknowns last pass AND every item has acceptance criteria AND deps mapped → launch subagents or invoke `gm-execute`.
|
|
77
|
-
|
|
78
|
-
## OBSERVABILITY — MANDATORY EVERY PASS
|
|
79
|
-
|
|
80
|
-
Server: every subsystem exposes `/debug/<subsystem>`. Structured logs `{subsystem, severity, ts}`.
|
|
81
|
-
Client: `window.__debug` live registry; modules register on mount.
|
|
82
|
-
|
|
83
|
-
`console.log` ≠ observability. Discovery of gap → add .prd item immediately, never deferred.
|
|
46
|
+
```yaml
|
|
47
|
+
- id: kebab-id
|
|
48
|
+
claim: One-line statement of what is assumed
|
|
49
|
+
witness_method: exec:codesearch <query> | exec:nodejs import | exec:recall <query> | Read <path>
|
|
50
|
+
witness_evidence: ""
|
|
51
|
+
status: unknown
|
|
52
|
+
```
|
|
84
53
|
|
|
85
|
-
|
|
54
|
+
`status: unknown` → `witnessed` only when `witness_evidence` is filled with concrete proof (file:line, codesearch hit, dispatched test output). Resolution lives in gm-execute. PRD items reference mutables via optional `mutables: [id1, id2]` field; an item is blocked while any referenced mutable is unresolved.
|
|
86
55
|
|
|
87
|
-
## .
|
|
56
|
+
## .prd format
|
|
88
57
|
|
|
89
|
-
Path: `./.gm/prd.yml`. Write via `
|
|
58
|
+
Path: `./.gm/prd.yml`. Write via the Write tool or by emitting a nodejs spool file (`in/nodejs/<N>.js`) that calls `fs.writeFileSync`. Delete the file when empty.
|
|
90
59
|
|
|
91
60
|
```yaml
|
|
92
61
|
- id: kebab-id
|
|
@@ -108,44 +77,42 @@ Path: `./.gm/prd.yml`. Write via `exec:nodejs` + `fs.writeFileSync`. Delete when
|
|
|
108
77
|
- failure mode
|
|
109
78
|
```
|
|
110
79
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
Status: pending → in_progress → completed (remove). Effort: small <15min | medium <45min | large >1h.
|
|
80
|
+
`load` is consequence-if-wrong: 0.9 = headline collapses, 0.7 = sub-argument rebuilt, 0.4 = local patch, 0.1 = nothing breaks. Verification budget = `load × (1 − tier_confidence)`. λ>0.75 must reach witnessed before EMIT.
|
|
114
81
|
|
|
115
|
-
|
|
82
|
+
`status`: pending → in_progress → completed (then remove). `effort`: small <15min | medium <45min | large >1h.
|
|
116
83
|
|
|
117
|
-
|
|
84
|
+
## Parallel subagent launch
|
|
118
85
|
|
|
119
|
-
`
|
|
86
|
+
After `.prd` is written, up to 3 parallel `gm:gm` subagents for independent items in one message. Browser tasks serialize.
|
|
120
87
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
88
|
+
```
|
|
89
|
+
Agent(subagent_type="gm:gm", prompt="Work on .prd item: <id>. .prd path: <path>. Item: <full YAML>.")
|
|
90
|
+
```
|
|
124
91
|
|
|
125
|
-
|
|
92
|
+
Items not parallelizable → invoke `gm-execute` directly.
|
|
126
93
|
|
|
127
|
-
|
|
94
|
+
## Observability gates in the plan
|
|
128
95
|
|
|
129
|
-
|
|
96
|
+
Server: every subsystem exposes `/debug/<subsystem>`; structured logs `{subsystem, severity, ts}`. Client: `window.__debug` live registry; modules register on mount. `console.log` is not observability. Discovery of a gap during PLAN adds a `.prd` item the same pass — never deferred.
|
|
130
97
|
|
|
131
|
-
|
|
98
|
+
`window.__debug` is THE in-page registry; `test.js` at project root is the sole out-of-page test asset. Any new file whose purpose is to exercise, smoke-test, demo, or sandbox in-page behavior outside that registry fights the discipline — extend the registry instead.
|
|
132
99
|
|
|
133
|
-
|
|
100
|
+
## Test discipline encoded in the plan
|
|
134
101
|
|
|
135
|
-
|
|
102
|
+
One `test.js` at project root, 200-line hard cap, real data, real system. No fixtures, mocks, or scattered tests. A second test runner under any name in any directory is a smuggled parallel surface.
|
|
136
103
|
|
|
137
|
-
|
|
104
|
+
The 200 lines are a *budget* for maximum surface coverage, not a target. Subsystems get one combined group each — names joined with `+` (`home+config+skin`, `mcp+swe+distributions+account+credpool`). When a new subsystem's failure mode overlaps an existing group's side-effects, fold the assertion in rather than creating a new group. When `wc -l test.js > 200`, the discipline is *merge groups + drop redundancy*, never split.
|
|
138
105
|
|
|
139
|
-
|
|
106
|
+
## Execution norms encoded in the plan
|
|
140
107
|
|
|
141
|
-
|
|
108
|
+
Code execution AND utility verbs both write to `.gm/exec-spool/in/<lang-or-verb>/<N>.<ext>`. Languages live under `in/<lang>/` (nodejs, python, bash, typescript, go, rust, c, cpp, java, deno); verbs live under `in/<verb>/` (codesearch, recall, memorize, wait, sleep, status, close, browser, runner, type, kill-port, forget, feedback, learn-status, learn-debug, learn-build, discipline, pause, health). The spool watcher runs the file and streams to `out/<N>.out` (stdout) + `out/<N>.err` (stderr) line-by-line, then writes `out/<N>.json` metadata (exitCode, durationMs, timedOut, startedAt, endedAt) at completion. Both streams return as systemMessage with `--- stdout ---` / `--- stderr ---` separators. `in/` and `out/` are wiped at session start and at real-exit session end. Only `git` (and `gh`) run directly via Bash; never `Bash(node/npm/npx/bun)`, never `Bash(exec:<anything>)`. Spool paths in nodejs files are platform-literal — use `os.tmpdir()` and `path.join`. The spool enforces per-task timeouts; on timeout, partial output is preserved and the watcher emits `[exec timed out after Nms; partial output above]`.
|
|
142
109
|
|
|
143
|
-
|
|
110
|
+
`exec:codesearch` only — Grep/Glob/Find/Explore are hook-blocked. Start two words, change/add one per pass, minimum four attempts before concluding absent.
|
|
144
111
|
|
|
145
|
-
|
|
112
|
+
Pack runs use `Promise.allSettled`, each idea its own try/catch, under 12s per call.
|
|
146
113
|
|
|
147
|
-
##
|
|
114
|
+
## Dev workflow encoded in the plan
|
|
148
115
|
|
|
149
|
-
|
|
116
|
+
No comments. 200-line per-file cap. Fail loud. No duplication. Scan before edit. AGENTS.md edits route through the memorize sub-agent only. CHANGELOG.md gets one entry per commit.
|
|
150
117
|
|
|
151
|
-
|
|
118
|
+
Minimal-code process, stop at the first that resolves: native → library → structure (map / pipeline) → write.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: research
|
|
3
|
+
description: Web research via parallel subagent fan-out. Use when a question needs the live web, spans multiple sources, requires comparison across vendors/papers/repos, or would saturate a single context window. Skip for one-page lookups answerable by a single WebFetch.
|
|
4
|
+
allowed-tools: Skill
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Research
|
|
8
|
+
|
|
9
|
+
Declare the discipline before fetching anything. The first line of work names the `@<discipline>` the corpus belongs to — fresh material lives at `.gm/disciplines/<name>/corpus/raw/`, concise rewrites at `.gm/disciplines/<name>/corpus/concise/<chunk-id>.md`, the merged synthesis at `.gm/disciplines/<name>/deep-understanding.md`. A run without a discipline declaration falls back to the default store and the orchestrator says so in one line.
|
|
10
|
+
|
|
11
|
+
Lead orchestrates. Workers fetch. Findings converge on disk. The lead never reads pages — workers do.
|
|
12
|
+
|
|
13
|
+
Treat a thousand-document corpus with the same care as a codebase. Material above roughly ten pages — about eight thousand tokens — splits at paragraph boundaries into chunks each owned by one parallel `gm:research-worker` (haiku model). Each worker emits a fact-preserving concise rewrite to `corpus/concise/<chunk-id>.md` — every claim, number, name, caveat from the source survives, prose density rises, citations stay attached. Once every chunk returns, the lead merges into `deep-understanding.md` enumerating the opportunities the corpus opens and the reasonable opinionations it forces. Concise files and the merged document auto-ingest via `exec:memorize @<name>` so the next pass recalls instead of re-fetching.
|
|
14
|
+
|
|
15
|
+
Effort matches stakes. A single fact is one short fetch. A vendor comparison is a handful of workers, each owning one vendor. A landscape survey is ten or more, each owning one axis. Spending a fan-out on a fact wastes tokens; spending a fact-fetch on a landscape under-delivers.
|
|
16
|
+
|
|
17
|
+
Breadth first, depth on demand. Open with a wide sweep that maps the terrain, then commit deep dives only where the sweep surfaces something load-bearing. A narrow opening misses the alternative the user actually needed.
|
|
18
|
+
|
|
19
|
+
## Worker contract
|
|
20
|
+
|
|
21
|
+
Each worker receives the precise question it owns, the shape of the answer (bullets, table row, prose paragraph), the boundary of what it must not pursue, and the destination path under `.gm/research/<slug>/<worker-id>.md`. Workers write structured findings to disk and return only a path plus a one-line summary. The lead reads the paths it cares about; the rest stay on disk. Returning full prose through the agent boundary burns context that the synthesis pass needs.
|
|
22
|
+
|
|
23
|
+
Workers run in parallel — independent questions launch in one message, never serialized.
|
|
24
|
+
|
|
25
|
+
## Citations
|
|
26
|
+
|
|
27
|
+
A claim without a source URL is a hallucination waiting to be quoted. Workers attach the URL and the quoted span beside every non-trivial assertion. The lead refuses to lift a claim into the final answer if its citation field is empty.
|
|
28
|
+
|
|
29
|
+
## Source quality
|
|
30
|
+
|
|
31
|
+
Vendor docs, RFCs, primary repos, dated blog posts from named authors, and academic preprints beat aggregator pages. When two sources disagree, the older primary usually beats the newer aggregator.
|
|
32
|
+
|
|
33
|
+
## Convergence
|
|
34
|
+
|
|
35
|
+
Synthesis happens once, after all workers return. Mid-flight summarisation truncates findings the next worker would have built on. If a worker's return reveals a new axis the original plan missed, expand the fan-out — do not stretch an existing worker past its brief.
|
|
36
|
+
|
|
37
|
+
## When not to fan out
|
|
38
|
+
|
|
39
|
+
One question, one page, one fetch. A single `WebFetch` answers it. The fan-out machinery has overhead; spending it on a lookup is the same mistake as skipping it on a survey.
|
|
40
|
+
|
|
41
|
+
## Handoff
|
|
42
|
+
|
|
43
|
+
Final answer cites every load-bearing claim, names the workers' output paths for audit, and surfaces disagreements rather than averaging them away.
|
package/skills/ssh/SKILL.md
CHANGED
|
@@ -3,13 +3,14 @@ name: ssh
|
|
|
3
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
4
|
---
|
|
5
5
|
|
|
6
|
-
# exec:ssh — Remote SSH
|
|
6
|
+
# exec:ssh — Remote SSH execution
|
|
7
7
|
|
|
8
|
-
Runs shell commands on remote host. No manual connection needed.
|
|
8
|
+
Runs shell commands on a remote host. No manual connection needed.
|
|
9
9
|
|
|
10
10
|
## Setup
|
|
11
11
|
|
|
12
12
|
`~/.claude/ssh-targets.json`:
|
|
13
|
+
|
|
13
14
|
```json
|
|
14
15
|
{
|
|
15
16
|
"default": { "host": "192.168.1.10", "port": 22, "username": "pi", "password": "pass" },
|
|
@@ -17,7 +18,7 @@ Runs shell commands on remote host. No manual connection needed.
|
|
|
17
18
|
}
|
|
18
19
|
```
|
|
19
20
|
|
|
20
|
-
|
|
21
|
+
`host` and `username` required. `port` defaults to 22. Auth: `password` OR `keyPath` + optional `passphrase`.
|
|
21
22
|
|
|
22
23
|
## Usage
|
|
23
24
|
|
|
@@ -26,28 +27,32 @@ exec:ssh
|
|
|
26
27
|
<shell command>
|
|
27
28
|
```
|
|
28
29
|
|
|
29
|
-
Named host with `@name` on first line:
|
|
30
|
+
Named host with `@name` on the first line:
|
|
31
|
+
|
|
30
32
|
```
|
|
31
33
|
exec:ssh
|
|
32
34
|
@prod
|
|
33
35
|
sudo systemctl restart myapp
|
|
34
36
|
```
|
|
35
37
|
|
|
36
|
-
## Process
|
|
38
|
+
## Process persistence
|
|
39
|
+
|
|
40
|
+
SSH kills child processes on close. To survive disconnect:
|
|
37
41
|
|
|
38
|
-
SSH kills child processes on close. To persist:
|
|
39
42
|
```
|
|
40
43
|
exec:ssh
|
|
41
44
|
sudo systemctl reset-failed myunit 2>/dev/null; systemd-run --unit=myunit bash -c 'your-command'
|
|
42
45
|
```
|
|
43
46
|
|
|
44
|
-
Unique name:
|
|
47
|
+
Unique unit name per launch:
|
|
48
|
+
|
|
45
49
|
```
|
|
46
50
|
exec:ssh
|
|
47
51
|
systemd-run --unit=job-$(date +%s) bash -c 'nohup myprogram &'
|
|
48
52
|
```
|
|
49
53
|
|
|
50
|
-
|
|
54
|
+
No-systemd fallback:
|
|
55
|
+
|
|
51
56
|
```
|
|
52
57
|
exec:ssh
|
|
53
58
|
setsid nohup bash -c 'myprogram > /tmp/out.log 2>&1' &
|
|
@@ -55,7 +60,8 @@ setsid nohup bash -c 'myprogram > /tmp/out.log 2>&1' &
|
|
|
55
60
|
|
|
56
61
|
## Dependency
|
|
57
62
|
|
|
58
|
-
Requires `ssh2`
|
|
63
|
+
Requires `ssh2` in `~/.claude/gm-tools`:
|
|
64
|
+
|
|
59
65
|
```
|
|
60
66
|
exec:bash
|
|
61
67
|
cd ~/.claude/gm-tools && npm install ssh2
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: textprocessing
|
|
3
|
+
description: The required surface for any text task whose correctness depends on understanding. Code does mechanics; this skill does meaning. Invoked via Agent(subagent_type='gm:textprocessing', model='haiku', ...).
|
|
4
|
+
allowed-tools: Skill
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Textprocessing — Meaning goes through Haiku
|
|
8
|
+
|
|
9
|
+
## Invocation
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
Agent(subagent_type='gm:textprocessing', model='haiku', prompt='## INPUT\n<body>\n\n## INSTRUCTION\n<task>')
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Background fire-and-forget: add `run_in_background=true`. Batch: N parallel `Agent` calls in one message, one per item.
|
|
16
|
+
|
|
17
|
+
## The split
|
|
18
|
+
|
|
19
|
+
Mechanics stay in code: char/word/token/line counts, byte length, split on delimiter, exact-string find/replace, regex match/extract, sort, group-by-key, dedup-by-equality, lower/uppercase, JSON parse/stringify, base64, URL encode, hash, diff, format/pretty-print.
|
|
20
|
+
|
|
21
|
+
Meaning goes through this skill: summarize, classify, extract entities or intents, rewrite for tone or audience, translate, semantic dedup (same meaning, different words), rank or score by quality, label by topic, decide whether two texts are about the same thing, paraphrase, simplify, expand outline → prose, headline-from-body, body-from-headline, fact-from-passage, sentiment, toxicity, relevance, similarity-by-meaning.
|
|
22
|
+
|
|
23
|
+
The bar: would a human have to *read and understand* the text to do this correctly? Yes → skill. No → code. A keyword-list, a regex on phrases like "important", or a string-similarity ratio loop deciding meaning is a stub of this skill. Replace it with one (or N parallel) Agent calls.
|
|
24
|
+
|
|
25
|
+
## Batch
|
|
26
|
+
|
|
27
|
+
Independent items run in parallel — one Agent call per item, all in one message. The runner Promise-allSettles. Sequential calls are wasteful when items don't depend on each other.
|
|
28
|
+
|
|
29
|
+
For one large body exceeding a single-prompt budget, the *caller* chunks deterministically (paragraph, section, fixed token count), fans out one Agent per chunk, and merges with a final reducer Agent if cross-chunk synthesis is needed. The agent itself never chunks — it processes whatever it receives in one shot.
|
|
30
|
+
|
|
31
|
+
## Output contract
|
|
32
|
+
|
|
33
|
+
Plain-text instruction → plain-text output, no fences, no labels. JSON instruction → exactly that JSON, parseable by `JSON.parse`. Multi-document input requested as a list → one entry per input doc in the same order. Ambiguous shape → defaults to plain text. Empty input → empty output.
|
|
34
|
+
|
|
35
|
+
## Constraints
|
|
36
|
+
|
|
37
|
+
- Model fixed at `haiku`. Escalate to opus only when haiku output fails an acceptance check.
|
|
38
|
+
- One transform per call. Three parallel calls beats one prompt asking for "summarize AND classify AND translate".
|
|
39
|
+
- Idempotent: same input + same instruction → same output, modulo sampling. Strict determinism callers specify `temperature=0` in the prompt.
|
|
40
|
+
- Output is the deliverable. No commentary, no "here is your output".
|