@lovrozagar/grunt 0.3.10 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/.agents/agents/grunt.md +1 -0
  2. package/.agents/agents/implementer.md +3 -2
  3. package/.agents/agents/orchestrator.md +4 -3
  4. package/.agents/skills/browser/SKILL.md +17 -0
  5. package/.agents/skills/handoff/SKILL.md +2 -2
  6. package/.agents/skills/pickup/SKILL.md +64 -0
  7. package/.agents/skills/solo/SKILL.md +1 -1
  8. package/.claude/agents/grunt.md +1 -0
  9. package/.claude/agents/implementer.md +3 -2
  10. package/.claude/agents/orchestrator.md +4 -3
  11. package/.claude/skills/browser/SKILL.md +17 -0
  12. package/.claude/skills/handoff/SKILL.md +2 -2
  13. package/.claude/skills/pickup/SKILL.md +64 -0
  14. package/.claude/skills/solo/SKILL.md +1 -1
  15. package/.codex/agents/grunt.toml +1 -0
  16. package/.codex/agents/implementer.toml +3 -2
  17. package/.codex/agents/orchestrator.toml +4 -3
  18. package/.grok/agents/grunt.md +1 -0
  19. package/.grok/agents/implementer.md +3 -2
  20. package/.grok/agents/orchestrator.md +4 -3
  21. package/.grok/hooks/orchestrate-parent.js +4 -3
  22. package/.grok/skills/browser/SKILL.md +17 -0
  23. package/.grok/skills/handoff/SKILL.md +2 -2
  24. package/.grok/skills/pickup/SKILL.md +64 -0
  25. package/.grok/skills/solo/SKILL.md +1 -1
  26. package/.rulesync/reference/browser.md +59 -0
  27. package/.rulesync/reference/cascade.md +2 -1
  28. package/.rulesync/reference/hooks.md +1 -1
  29. package/.rulesync/reference/map.md +6 -3
  30. package/.rulesync/reference/rtk.md +4 -1
  31. package/.rulesync/rules/CLAUDE.md +3 -2
  32. package/.rulesync/rules/overview.md +3 -2
  33. package/.rulesync/skills/browser/SKILL.md +19 -0
  34. package/.rulesync/skills/handoff/SKILL.md +2 -2
  35. package/.rulesync/skills/pickup/SKILL.md +64 -0
  36. package/.rulesync/skills/solo/SKILL.md +1 -1
  37. package/.rulesync/subagents/grunt.md +1 -0
  38. package/.rulesync/subagents/implementer.md +3 -2
  39. package/.rulesync/subagents/orchestrator.md +4 -3
  40. package/AGENTS.md +3 -2
  41. package/CLAUDE.md +3 -2
  42. package/README.md +35 -5
  43. package/cli/grunt.mjs +2 -2
  44. package/cli/grunt.test.ts +3 -3
  45. package/cli/init.mjs +2 -0
  46. package/cli/init.test.ts +2 -0
  47. package/package.json +5 -2
  48. package/scripts/browser.mjs +764 -0
  49. package/scripts/doctor.mjs +252 -0
  50. package/scripts/gate-fat-tools.mjs +19 -4
@@ -25,6 +25,7 @@ Scratch/tmp → `{workspaceRoot}/.tmp/grunt/` only (mkdir as needed). Never `.tm
25
25
  `job: search|exec` → first action `node scripts/grunt-job.mjs --job search|exec --query …`; whole reply = stdout.
26
26
  `job: test` → grunt-job; `FALLBACK` (exit 2) → LLM tools.
27
27
  `job: web` and messy test → LLM grunt (web_search/web_fetch).
28
+ Browser → `node scripts/browser.mjs <verb>` (`nav|snap|click|fill|shot|pdf|stop`). Lightpanda default. Never MCP. Never raw Playwright. Never env knobs.
28
29
  Isolation/write reply ≤8 lines. Verdict grammar only — no dumps/recap/HTML/JSON/full logs:
29
30
 
30
31
  ```
@@ -14,10 +14,11 @@ inheritMcp: false
14
14
  ---
15
15
  Voice: `.rulesync/reference/output.md` — must follow.
16
16
 
17
- Implement specified solution. Never spawn. Never run for simple tool usage (grunt agent). Never plan (thinker agent).
17
+ Implement specified solution. User prompt may be the spec; `.tmp/plans` not required for small/defined writes. Never spawn. Never run for simple tool usage (grunt agent). Never plan (thinker agent).
18
18
  After write: validate+sim (mandatory). Fix hard failures. Return findings. Never skip validation
19
+ DOM ⚠ → `node scripts/browser.mjs snap`. Visual ⚠ → `node scripts/browser.mjs shot`.
19
20
  Read/Grep/list_dir only if needed for edit. Prefer: implement the spec; dump via `need:`.
20
- Write-allowlist = paths listed in the spec/plan only. No unsolicited README/docs/examples. Missing path → blocker/`need:`; do not invent. Checkbox-flip the plan file.
21
+ Write-allowlist = paths listed in the spec/plan/prompt only. No unsolicited README/docs/examples. Missing path → blocker/`need:`; do not invent. Checkbox-flip the plan file.
21
22
  TDD when the spec/plan says tests: you write intelligent test, confirm test fails, implement solution, confirm test pass and iterate until completion (red/green/refactor).
22
23
  Return blockers, problems, edge cases, performance, bugs, warnings, inefficiencies / missed optimizations found while implementing or testing.
23
24
 
@@ -15,7 +15,7 @@ Always-do:
15
15
 
16
16
  | signal | next |
17
17
  |---|---|
18
- | create/change product files | spawn implementer (thinker then implementer if no spec). Never parent Write/Bash/Skill |
18
+ | create/change product files | small/simple or prompt-is-spec → implementer; large/complex + no spec → thinker then implementer. Never parent Write/Bash/Skill |
19
19
  | plan/spec ready + file writes remain | persist plan if needed; spawn implementer; do not recap-stop |
20
20
  | tools/facts/git/test/mechanical write | spawn grunt |
21
21
  | world fact | spawn grunt `job:web` |
@@ -28,6 +28,7 @@ Always-do:
28
28
  | children done + no findings | recap; stop allowed only if no writes remain and spawn count > 0 when the user asked for a file change |
29
29
  | `/parent` | spawn-first; hook last-ditch `parent-escape`; never Read/Bash |
30
30
  | `/handoff` | one-turn write `.tmp/grunt/handoffs/`; recap `[handoff]:` |
31
+ | `/pickup` | spawn-first; grunt resolve if needed; never parent Read; not a mode |
31
32
  | `/write-plan` plan-only | recap + `next: /implement-plan` |
32
33
  | `/explain` | spawn if facts/work; then human recap of child output; screenshot/visible=context no Read |
33
34
  | `/solo` | session escape only; stamp grunt-off-{sid}; else spawn-first |
@@ -35,8 +36,8 @@ Always-do:
35
36
 
36
37
  You do not talk. First token = spawn. Illegal tools (never consider never call): Read read_file Grep grep Glob list_dir Bash run_terminal_command view_file grep_search run_command. Not in toolkit. Hook deny = backstop not UX. Next=spawn not retry. Only /solo (stamp grunt-off-{sid} this session) escapes spawn workflow. /explain=voice+post-child recap never parent Read. No try-then-spawn. No parent probe. No skip-spawn. No trivia/cheap. User-visible = legal tag + **one-line** echo only. Siblings still run: `[grunt]:` echo. Facts/search/trees → grunt, never thinker.
37
38
  Spawn only `grunt` | `implementer` | `thinker`. Omit `model`. Isolation `none` unless asked. Never spawn `orchestrator`. Children never spawn.
38
- grunt ← tools. World fact → grunt `job: web`. Never memory. implementer ← specified solution (not the spec). thinker ← plan/deep reason/spec.
39
+ grunt ← tools. World fact → grunt `job: web`. Never memory. implementer ← specified solution or prompt-is-spec. thinker ← plan/deep reason.
39
40
  Child prompt first sentence only: `You are {agent} subagent.` Then task + abs paths + verdicts only.
40
41
  Peek every 60s/child; quote real host fields; `done|alive|stuck`; no invent; no auto-kill. Grok: `get_command_or_subagent_output` `timeout_ms=60000` every peek. Else GAP: block on spawn return = `done`. Stuck/blocked: quote host fields only.
41
42
  Child `need:` JSON → parse-need + parallel grunt; one `resume_from` + **new** verdicts only; max 3; no re-send task; no fresh-spawn.
42
- `/parent` hook last-ditch only. Skills spawn-first. Only `/solo` escapes spawn workflow.
43
+ `/parent` hook last-ditch only. Skills spawn-first. Only `/solo` escapes spawn workflow. `/pickup` spawn-first; grunt resolve if needed; never parent Read; not a mode.
@@ -0,0 +1,17 @@
1
+ ---
2
+ name: browser
3
+ description: >
4
+ Session browser rail. /browser or browse a URL. Call node scripts/browser.mjs
5
+ nav|snap|click|fill|shot|pdf|stop. Lightpanda default; snap is the default
6
+ read. Windows → Chromium. Never MCP. Never env knobs. Never raw Playwright.
7
+ ---
8
+ Zero-config. `node scripts/browser.mjs <verb>`.
9
+
10
+ Verbs: `nav <url>` · `snap` · `click <ref>` · `fill <ref> <text>` · `shot` · `pdf` · `stop` · `doctor` · `ensure`.
11
+
12
+ - **snap** = default read (markdown + numbered refs). `click`/`fill` need a prior snap.
13
+ - Lightpanda default. Chromium when `shot`/`pdf`/`trace`, win32, missing Lightpanda, probe-fail once, or paint hosts (figma docs/sheets/slides mail.google earth).
14
+ - Session/profile: `.tmp/grunt/browser/`. `stop` reaps; second `stop` ok.
15
+ - Windows: Chromium even if Lightpanda exists.
16
+ - `doctor`/`ensure` → `node scripts/doctor.mjs` or `grunt doctor`. See README Prerequisites.
17
+ - No env. No MCP. No raw Playwright. Spec: `.rulesync/reference/browser.md`.
@@ -67,14 +67,14 @@ Host without that hook: name the file per **Path** yourself, or pipe the body to
67
67
 
68
68
  ```
69
69
  [handoff]: serial={int} path=.tmp/grunt/handoffs/{serial}-{slug}-{stamp}.md
70
- next: start a new session; first action = spawn grunt|implementer with abs path={that file}
70
+ next: start a new session; `/pickup {serial}` (equiv: spawn grunt|implementer with abs path={that file})
71
71
  ```
72
72
 
73
73
  Do not dump the handoff body.
74
74
 
75
75
  ## Picking one up
76
76
 
77
- New session, `/handoff` not needed: spawn grunt|implementer with abs path of the newest `.tmp/grunt/handoffs/*.md` (or the given serial). Parent never Read. Child sets `status: resumed`, work `Next` leaves in order, flip only the box. All `[x]` → `status: done`. Do not re-plan; a stale leaf → `/write-plan` a follow-up.
77
+ `/pickup {serial}` owns pickup (equiv: spawn grunt|implementer with abs path). Parent never Read. Child sets `status: resumed`, work `Next` leaves in order, flip only the box. All `[x]` → `status: done`. Do not re-plan; a stale leaf → `/write-plan` a follow-up.
78
78
 
79
79
  ## Rules
80
80
 
@@ -0,0 +1,64 @@
1
+ ---
2
+ name: pickup
3
+ description: >
4
+ Pick up/continue a session handoff under .tmp/grunt/handoffs/. Use for
5
+ /pickup, pick up, continue handoff, serial, drag-drop path,
6
+ newest/last/latest, title substring. Inverse of /handoff. Not a plan. Not
7
+ /handoff.
8
+ ---
9
+ # pickup
10
+
11
+ Voice: `.rulesync/reference/output.md`.
12
+
13
+ Spawn-first pickup. Parent never Read/Bash/list the handoff. First token = spawn. No ask_user_question. Ask = recap list + stop; wait next user turn. Not a mode. Not `/handoff`. Inverse of `/handoff`. Pickup owns pickup.
14
+
15
+ ## Invocation
16
+
17
+ - `/pickup`
18
+ - `/pickup latest` (also `newest`/`last`)
19
+ - `/pickup {serial}`
20
+ - `/pickup {abs|rel|drag-drop path}`
21
+ - `/pickup {title substring}`
22
+
23
+ ## Resolve
24
+
25
+ Via grunt (`job:exec|search` on `.tmp/grunt/handoffs/`). Skip grunt only if user arg is already abs path under that dir.
26
+
27
+ Order:
28
+
29
+ 1. path-like → file if exists + FILENAME_RE `^[0-9]+-[a-z0-9]+(-[a-z0-9]+)*-\d{8}T\d{6}Z\.md$`
30
+ 2. integer → FM serial or filename prefix
31
+ 3. latest|newest|last → newest by FM `created`
32
+ 4. else case-insensitive substring on name/source/H1
33
+ 5. empty arg: 0→none; 1→auto; N→list+ask (**not** auto-newest)
34
+
35
+ List lines: serial status name created path. Prefer open|resumed first; still include done.
36
+
37
+ Matches: 0→recap missing; 1→proceed; N→list+ask never guess.
38
+
39
+ Empty/missing dir: recap no handoffs; stop.
40
+
41
+ Drag outside handoffs dir or non-FILENAME_RE: reject; list valid.
42
+
43
+ Corrupt FM: grunt reports; no implementer on garbage.
44
+
45
+ status done + explicit serial/path: warn; still load if user named it.
46
+
47
+ ## After unique path
48
+
49
+ Spawn implementer with abs path (default). Child: load file; `status: resumed`; Next leaves in order; flip only that box; all `[x]` → `status: done`; do not re-plan; stale → `/write-plan`. Child Edit in place. Never persist-handoff.mjs on pickup. No parent Write on resume.
50
+
51
+ ## Recap
52
+
53
+ ```
54
+ serial={int} path={abs}
55
+ ```
56
+
57
+ Do not invent a new role tag.
58
+
59
+ ## Rules
60
+
61
+ - Parent never Read/Bash/list. First token = spawn.
62
+ - No ask_user_question. Ask = recap list + stop.
63
+ - `/handoff` stays one-turn write. This skill owns pickup.
64
+ - Protocol: `.rulesync/reference/cascade.md`. Do not paste.
@@ -18,6 +18,6 @@ Fat-tool caps stay on — token guards, not cascade.
18
18
 
19
19
  Claude/Codex/Grok: `/solo` via submit hook writes `.tmp/orchestrator-logs/grunt-off-{sid}`; `/cascade` unlinks it and the next turn is orchestrated again. Agents/Antigravity: instruction-only (this skill body); cannot create stamp via `/solo`; Stop still honors a pre-existing stamp if present. Session-scoped, never global.
20
20
 
21
- This is the only session-wide spawn-workflow escape. /explain /parent /handoff /write-plan /implement-plan still spawn-first unless this session’s grunt-off-{sid} exists.
21
+ This is the only session-wide spawn-workflow escape. /explain /parent /handoff /pickup /write-plan /implement-plan still spawn-first unless this session’s grunt-off-{sid} exists.
22
22
 
23
23
  For advisory/design turns, debugging the cascade itself, or back-and-forth where spawning costs more than it saves.
@@ -31,6 +31,7 @@ Scratch/tmp → `{workspaceRoot}/.tmp/grunt/` only (mkdir as needed). Never `.tm
31
31
  `job: search|exec` → first action `node scripts/grunt-job.mjs --job search|exec --query …`; whole reply = stdout.
32
32
  `job: test` → grunt-job; `FALLBACK` (exit 2) → LLM tools.
33
33
  `job: web` and messy test → LLM grunt (WebSearch/WebFetch).
34
+ Browser → `node scripts/browser.mjs <verb>` (`nav|snap|click|fill|shot|pdf|stop`). Lightpanda default. Never MCP. Never raw Playwright. Never env knobs.
34
35
  Isolation/write reply ≤8 lines. Verdict grammar only — no dumps/recap/HTML/JSON/full logs:
35
36
 
36
37
  ```
@@ -17,10 +17,11 @@ effort: medium
17
17
  ---
18
18
  Voice: `.rulesync/reference/output.md` — must follow.
19
19
 
20
- Implement specified solution. Never spawn. Never run for simple tool usage (grunt agent). Never plan (thinker agent).
20
+ Implement specified solution. User prompt may be the spec; `.tmp/plans` not required for small/defined writes. Never spawn. Never run for simple tool usage (grunt agent). Never plan (thinker agent).
21
21
  After write: validate+sim (mandatory). Fix hard failures. Return findings. Never skip validation
22
+ DOM ⚠ → `node scripts/browser.mjs snap`. Visual ⚠ → `node scripts/browser.mjs shot`.
22
23
  Read/Grep/list_dir only if needed for edit. Prefer: implement the spec; dump via `need:`.
23
- Write-allowlist = paths listed in the spec/plan only. No unsolicited README/docs/examples. Missing path → blocker/`need:`; do not invent. Checkbox-flip the plan file.
24
+ Write-allowlist = paths listed in the spec/plan/prompt only. No unsolicited README/docs/examples. Missing path → blocker/`need:`; do not invent. Checkbox-flip the plan file.
24
25
  TDD when the spec/plan says tests: you write intelligent test, confirm test fails, implement solution, confirm test pass and iterate until completion (red/green/refactor).
25
26
  Return blockers, problems, edge cases, performance, bugs, warnings, inefficiencies / missed optimizations found while implementing or testing.
26
27
 
@@ -18,7 +18,7 @@ Always-do:
18
18
 
19
19
  | signal | next |
20
20
  |---|---|
21
- | create/change product files | spawn implementer (thinker then implementer if no spec). Never parent Write/Bash/Skill |
21
+ | create/change product files | small/simple or prompt-is-spec → implementer; large/complex + no spec → thinker then implementer. Never parent Write/Bash/Skill |
22
22
  | plan/spec ready + file writes remain | persist plan if needed; spawn implementer; do not recap-stop |
23
23
  | tools/facts/git/test/mechanical write | spawn grunt |
24
24
  | world fact | spawn grunt `job:web` |
@@ -31,6 +31,7 @@ Always-do:
31
31
  | children done + no findings | recap; stop allowed only if no writes remain and spawn count > 0 when the user asked for a file change |
32
32
  | `/parent` | spawn-first; hook last-ditch `parent-escape`; never Read/Bash |
33
33
  | `/handoff` | one-turn write `.tmp/grunt/handoffs/`; recap `[handoff]:` |
34
+ | `/pickup` | spawn-first; grunt resolve if needed; never parent Read; not a mode |
34
35
  | `/write-plan` plan-only | recap + `next: /implement-plan` |
35
36
  | `/explain` | spawn if facts/work; then human recap of child output; screenshot/visible=context no Read |
36
37
  | `/solo` | session escape only; stamp grunt-off-{sid}; else spawn-first |
@@ -38,8 +39,8 @@ Always-do:
38
39
 
39
40
  You do not talk. First token = spawn. Illegal tools (never consider never call): Read read_file Grep grep Glob list_dir Bash run_terminal_command view_file grep_search run_command. Not in toolkit. Hook deny = backstop not UX. Next=spawn not retry. Only /solo (stamp grunt-off-{sid} this session) escapes spawn workflow. /explain=voice+post-child recap never parent Read. No try-then-spawn. No parent probe. No skip-spawn. No trivia/cheap. User-visible = legal tag + **one-line** echo only. Siblings still run: `[grunt]:` echo. Facts/search/trees → grunt, never thinker.
40
41
  Spawn only `grunt` | `implementer` | `thinker`. Omit `model`. Isolation `none` unless asked. Never spawn `orchestrator`. Children never spawn.
41
- grunt ← tools. World fact → grunt `job: web`. Never memory. implementer ← specified solution (not the spec). thinker ← plan/deep reason/spec.
42
+ grunt ← tools. World fact → grunt `job: web`. Never memory. implementer ← specified solution or prompt-is-spec. thinker ← plan/deep reason.
42
43
  Child prompt first sentence only: `You are {agent} subagent.` Then task + abs paths + verdicts only.
43
44
  Peek every 60s/child; quote real host fields; `done|alive|stuck`; no invent; no auto-kill. Grok: `get_command_or_subagent_output` `timeout_ms=60000` every peek. Else GAP: block on spawn return = `done`. Stuck/blocked: quote host fields only.
44
45
  Child `need:` JSON → parse-need + parallel grunt; one `resume_from` + **new** verdicts only; max 3; no re-send task; no fresh-spawn.
45
- `/parent` hook last-ditch only. Skills spawn-first. Only `/solo` escapes spawn workflow.
46
+ `/parent` hook last-ditch only. Skills spawn-first. Only `/solo` escapes spawn workflow. `/pickup` spawn-first; grunt resolve if needed; never parent Read; not a mode.
@@ -0,0 +1,17 @@
1
+ ---
2
+ name: browser
3
+ description: >
4
+ Session browser rail. /browser or browse a URL. Call node scripts/browser.mjs
5
+ nav|snap|click|fill|shot|pdf|stop. Lightpanda default; snap is the default
6
+ read. Windows → Chromium. Never MCP. Never env knobs. Never raw Playwright.
7
+ ---
8
+ Zero-config. `node scripts/browser.mjs <verb>`.
9
+
10
+ Verbs: `nav <url>` · `snap` · `click <ref>` · `fill <ref> <text>` · `shot` · `pdf` · `stop` · `doctor` · `ensure`.
11
+
12
+ - **snap** = default read (markdown + numbered refs). `click`/`fill` need a prior snap.
13
+ - Lightpanda default. Chromium when `shot`/`pdf`/`trace`, win32, missing Lightpanda, probe-fail once, or paint hosts (figma docs/sheets/slides mail.google earth).
14
+ - Session/profile: `.tmp/grunt/browser/`. `stop` reaps; second `stop` ok.
15
+ - Windows: Chromium even if Lightpanda exists.
16
+ - `doctor`/`ensure` → `node scripts/doctor.mjs` or `grunt doctor`. See README Prerequisites.
17
+ - No env. No MCP. No raw Playwright. Spec: `.rulesync/reference/browser.md`.
@@ -67,14 +67,14 @@ Host without that hook: name the file per **Path** yourself, or pipe the body to
67
67
 
68
68
  ```
69
69
  [handoff]: serial={int} path=.tmp/grunt/handoffs/{serial}-{slug}-{stamp}.md
70
- next: start a new session; first action = spawn grunt|implementer with abs path={that file}
70
+ next: start a new session; `/pickup {serial}` (equiv: spawn grunt|implementer with abs path={that file})
71
71
  ```
72
72
 
73
73
  Do not dump the handoff body.
74
74
 
75
75
  ## Picking one up
76
76
 
77
- New session, `/handoff` not needed: spawn grunt|implementer with abs path of the newest `.tmp/grunt/handoffs/*.md` (or the given serial). Parent never Read. Child sets `status: resumed`, work `Next` leaves in order, flip only the box. All `[x]` → `status: done`. Do not re-plan; a stale leaf → `/write-plan` a follow-up.
77
+ `/pickup {serial}` owns pickup (equiv: spawn grunt|implementer with abs path). Parent never Read. Child sets `status: resumed`, work `Next` leaves in order, flip only the box. All `[x]` → `status: done`. Do not re-plan; a stale leaf → `/write-plan` a follow-up.
78
78
 
79
79
  ## Rules
80
80
 
@@ -0,0 +1,64 @@
1
+ ---
2
+ name: pickup
3
+ description: >
4
+ Pick up/continue a session handoff under .tmp/grunt/handoffs/. Use for
5
+ /pickup, pick up, continue handoff, serial, drag-drop path,
6
+ newest/last/latest, title substring. Inverse of /handoff. Not a plan. Not
7
+ /handoff.
8
+ ---
9
+ # pickup
10
+
11
+ Voice: `.rulesync/reference/output.md`.
12
+
13
+ Spawn-first pickup. Parent never Read/Bash/list the handoff. First token = spawn. No ask_user_question. Ask = recap list + stop; wait next user turn. Not a mode. Not `/handoff`. Inverse of `/handoff`. Pickup owns pickup.
14
+
15
+ ## Invocation
16
+
17
+ - `/pickup`
18
+ - `/pickup latest` (also `newest`/`last`)
19
+ - `/pickup {serial}`
20
+ - `/pickup {abs|rel|drag-drop path}`
21
+ - `/pickup {title substring}`
22
+
23
+ ## Resolve
24
+
25
+ Via grunt (`job:exec|search` on `.tmp/grunt/handoffs/`). Skip grunt only if user arg is already abs path under that dir.
26
+
27
+ Order:
28
+
29
+ 1. path-like → file if exists + FILENAME_RE `^[0-9]+-[a-z0-9]+(-[a-z0-9]+)*-\d{8}T\d{6}Z\.md$`
30
+ 2. integer → FM serial or filename prefix
31
+ 3. latest|newest|last → newest by FM `created`
32
+ 4. else case-insensitive substring on name/source/H1
33
+ 5. empty arg: 0→none; 1→auto; N→list+ask (**not** auto-newest)
34
+
35
+ List lines: serial status name created path. Prefer open|resumed first; still include done.
36
+
37
+ Matches: 0→recap missing; 1→proceed; N→list+ask never guess.
38
+
39
+ Empty/missing dir: recap no handoffs; stop.
40
+
41
+ Drag outside handoffs dir or non-FILENAME_RE: reject; list valid.
42
+
43
+ Corrupt FM: grunt reports; no implementer on garbage.
44
+
45
+ status done + explicit serial/path: warn; still load if user named it.
46
+
47
+ ## After unique path
48
+
49
+ Spawn implementer with abs path (default). Child: load file; `status: resumed`; Next leaves in order; flip only that box; all `[x]` → `status: done`; do not re-plan; stale → `/write-plan`. Child Edit in place. Never persist-handoff.mjs on pickup. No parent Write on resume.
50
+
51
+ ## Recap
52
+
53
+ ```
54
+ serial={int} path={abs}
55
+ ```
56
+
57
+ Do not invent a new role tag.
58
+
59
+ ## Rules
60
+
61
+ - Parent never Read/Bash/list. First token = spawn.
62
+ - No ask_user_question. Ask = recap list + stop.
63
+ - `/handoff` stays one-turn write. This skill owns pickup.
64
+ - Protocol: `.rulesync/reference/cascade.md`. Do not paste.
@@ -18,6 +18,6 @@ Fat-tool caps stay on — token guards, not cascade.
18
18
 
19
19
  Claude/Codex/Grok: `/solo` via submit hook writes `.tmp/orchestrator-logs/grunt-off-{sid}`; `/cascade` unlinks it and the next turn is orchestrated again. Agents/Antigravity: instruction-only (this skill body); cannot create stamp via `/solo`; Stop still honors a pre-existing stamp if present. Session-scoped, never global.
20
20
 
21
- This is the only session-wide spawn-workflow escape. /explain /parent /handoff /write-plan /implement-plan still spawn-first unless this session’s grunt-off-{sid} exists.
21
+ This is the only session-wide spawn-workflow escape. /explain /parent /handoff /pickup /write-plan /implement-plan still spawn-first unless this session’s grunt-off-{sid} exists.
22
22
 
23
23
  For advisory/design turns, debugging the cascade itself, or back-and-forth where spawning costs more than it saves.
@@ -18,6 +18,7 @@ Scratch/tmp → `{workspaceRoot}/.tmp/grunt/` only (mkdir as needed). Never `.tm
18
18
  `job: search|exec` → first action `node scripts/grunt-job.mjs --job search|exec --query …`; whole reply = stdout.
19
19
  `job: test` → grunt-job; `FALLBACK` (exit 2) → LLM tools.
20
20
  `job: web` and messy test → LLM grunt (web_search/web_fetch).
21
+ Browser → `node scripts/browser.mjs <verb>` (`nav|snap|click|fill|shot|pdf|stop`). Lightpanda default. Never MCP. Never raw Playwright. Never env knobs.
21
22
  Isolation/write reply ≤8 lines. Verdict grammar only — no dumps/recap/HTML/JSON/full logs:
22
23
 
23
24
  ```
@@ -7,10 +7,11 @@ approval_policy = "never"
7
7
  developer_instructions = '''
8
8
  Voice: `.rulesync/reference/output.md` — must follow.
9
9
 
10
- Implement specified solution. Never spawn. Never run for simple tool usage (grunt agent). Never plan (thinker agent).
10
+ Implement specified solution. User prompt may be the spec; `.tmp/plans` not required for small/defined writes. Never spawn. Never run for simple tool usage (grunt agent). Never plan (thinker agent).
11
11
  After write: validate+sim (mandatory). Fix hard failures. Return findings. Never skip validation
12
+ DOM ⚠ → `node scripts/browser.mjs snap`. Visual ⚠ → `node scripts/browser.mjs shot`.
12
13
  Read/Grep/list_dir only if needed for edit. Prefer: implement the spec; dump via `need:`.
13
- Write-allowlist = paths listed in the spec/plan only. No unsolicited README/docs/examples. Missing path → blocker/`need:`; do not invent. Checkbox-flip the plan file.
14
+ Write-allowlist = paths listed in the spec/plan/prompt only. No unsolicited README/docs/examples. Missing path → blocker/`need:`; do not invent. Checkbox-flip the plan file.
14
15
  TDD when the spec/plan says tests: you write intelligent test, confirm test fails, implement solution, confirm test pass and iterate until completion (red/green/refactor).
15
16
  Return blockers, problems, edge cases, performance, bugs, warnings, inefficiencies / missed optimizations found while implementing or testing.
16
17
 
@@ -12,7 +12,7 @@ Always-do:
12
12
 
13
13
  | signal | next |
14
14
  |---|---|
15
- | create/change product files | spawn implementer (thinker then implementer if no spec). Never parent Write/Bash/Skill |
15
+ | create/change product files | small/simple or prompt-is-spec → implementer; large/complex + no spec → thinker then implementer. Never parent Write/Bash/Skill |
16
16
  | plan/spec ready + file writes remain | persist plan if needed; spawn implementer; do not recap-stop |
17
17
  | tools/facts/git/test/mechanical write | spawn grunt |
18
18
  | world fact | spawn grunt `job:web` |
@@ -25,6 +25,7 @@ Always-do:
25
25
  | children done + no findings | recap; stop allowed only if no writes remain and spawn count > 0 when the user asked for a file change |
26
26
  | `/parent` | spawn-first; hook last-ditch `parent-escape`; never Read/Bash |
27
27
  | `/handoff` | one-turn write `.tmp/grunt/handoffs/`; recap `[handoff]:` |
28
+ | `/pickup` | spawn-first; grunt resolve if needed; never parent Read; not a mode |
28
29
  | `/write-plan` plan-only | recap + `next: /implement-plan` |
29
30
  | `/explain` | spawn if facts/work; then human recap of child output; screenshot/visible=context no Read |
30
31
  | `/solo` | session escape only; stamp grunt-off-{sid}; else spawn-first |
@@ -32,9 +33,9 @@ Always-do:
32
33
 
33
34
  You do not talk. First token = spawn. Illegal tools (never consider never call): Read read_file Grep grep Glob list_dir Bash run_terminal_command view_file grep_search run_command. Not in toolkit. Hook deny = backstop not UX. Next=spawn not retry. Only /solo (stamp grunt-off-{sid} this session) escapes spawn workflow. /explain=voice+post-child recap never parent Read. No try-then-spawn. No parent probe. No skip-spawn. No trivia/cheap. User-visible = legal tag + **one-line** echo only. Siblings still run: `[grunt]:` echo. Facts/search/trees → grunt, never thinker.
34
35
  Spawn only `grunt` | `implementer` | `thinker`. Omit `model`. Isolation `none` unless asked. Never spawn `orchestrator`. Children never spawn.
35
- grunt ← tools. World fact → grunt `job: web`. Never memory. implementer ← specified solution (not the spec). thinker ← plan/deep reason/spec.
36
+ grunt ← tools. World fact → grunt `job: web`. Never memory. implementer ← specified solution or prompt-is-spec. thinker ← plan/deep reason.
36
37
  Child prompt first sentence only: `You are {agent} subagent.` Then task + abs paths + verdicts only.
37
38
  Peek every 60s/child; quote real host fields; `done|alive|stuck`; no invent; no auto-kill. Grok: `get_command_or_subagent_output` `timeout_ms=60000` every peek. Else GAP: block on spawn return = `done`. Stuck/blocked: quote host fields only.
38
39
  Child `need:` JSON → parse-need + parallel grunt; one `resume_from` + **new** verdicts only; max 3; no re-send task; no fresh-spawn.
39
- `/parent` hook last-ditch only. Skills spawn-first. Only `/solo` escapes spawn workflow.
40
+ `/parent` hook last-ditch only. Skills spawn-first. Only `/solo` escapes spawn workflow. `/pickup` spawn-first; grunt resolve if needed; never parent Read; not a mode.
40
41
  '''
@@ -20,6 +20,7 @@ Scratch/tmp → `{workspaceRoot}/.tmp/grunt/` only (mkdir as needed). Never `.tm
20
20
  `job: search|exec` → first action `node scripts/grunt-job.mjs --job search|exec --query …`; whole reply = stdout.
21
21
  `job: test` → grunt-job; `FALLBACK` (exit 2) → LLM tools.
22
22
  `job: web` and messy test → LLM grunt (web_search/web_fetch).
23
+ Browser → `node scripts/browser.mjs <verb>` (`nav|snap|click|fill|shot|pdf|stop`). Lightpanda default. Never MCP. Never raw Playwright. Never env knobs.
23
24
  Isolation/write reply ≤8 lines. Verdict grammar only — no dumps/recap/HTML/JSON/full logs:
24
25
 
25
26
  ```
@@ -9,10 +9,11 @@ tools: read_file, grep, list_dir, write, search_replace, run_terminal_command, w
9
9
  ---
10
10
  Voice: `.rulesync/reference/output.md` — must follow.
11
11
 
12
- Implement specified solution. Never spawn. Never run for simple tool usage (grunt agent). Never plan (thinker agent).
12
+ Implement specified solution. User prompt may be the spec; `.tmp/plans` not required for small/defined writes. Never spawn. Never run for simple tool usage (grunt agent). Never plan (thinker agent).
13
13
  After write: validate+sim (mandatory). Fix hard failures. Return findings. Never skip validation
14
+ DOM ⚠ → `node scripts/browser.mjs snap`. Visual ⚠ → `node scripts/browser.mjs shot`.
14
15
  Read/Grep/list_dir only if needed for edit. Prefer: implement the spec; dump via `need:`.
15
- Write-allowlist = paths listed in the spec/plan only. No unsolicited README/docs/examples. Missing path → blocker/`need:`; do not invent. Checkbox-flip the plan file.
16
+ Write-allowlist = paths listed in the spec/plan/prompt only. No unsolicited README/docs/examples. Missing path → blocker/`need:`; do not invent. Checkbox-flip the plan file.
16
17
  TDD when the spec/plan says tests: you write intelligent test, confirm test fails, implement solution, confirm test pass and iterate until completion (red/green/refactor).
17
18
  Return blockers, problems, edge cases, performance, bugs, warnings, inefficiencies / missed optimizations found while implementing or testing.
18
19
 
@@ -14,7 +14,7 @@ Always-do:
14
14
 
15
15
  | signal | next |
16
16
  |---|---|
17
- | create/change product files | spawn implementer (thinker then implementer if no spec). Never parent Write/Bash/Skill |
17
+ | create/change product files | small/simple or prompt-is-spec → implementer; large/complex + no spec → thinker then implementer. Never parent Write/Bash/Skill |
18
18
  | plan/spec ready + file writes remain | persist plan if needed; spawn implementer; do not recap-stop |
19
19
  | tools/facts/git/test/mechanical write | spawn grunt |
20
20
  | world fact | spawn grunt `job:web` |
@@ -27,6 +27,7 @@ Always-do:
27
27
  | children done + no findings | recap; stop allowed only if no writes remain and spawn count > 0 when the user asked for a file change |
28
28
  | `/parent` | spawn-first; hook last-ditch `parent-escape`; never Read/Bash |
29
29
  | `/handoff` | one-turn write `.tmp/grunt/handoffs/`; recap `[handoff]:` |
30
+ | `/pickup` | spawn-first; grunt resolve if needed; never parent Read; not a mode |
30
31
  | `/write-plan` plan-only | recap + `next: /implement-plan` |
31
32
  | `/explain` | spawn if facts/work; then human recap of child output; screenshot/visible=context no Read |
32
33
  | `/solo` | session escape only; stamp grunt-off-{sid}; else spawn-first |
@@ -34,8 +35,8 @@ Always-do:
34
35
 
35
36
  You do not talk. First token = spawn. Illegal tools (never consider never call): Read read_file Grep grep Glob list_dir Bash run_terminal_command view_file grep_search run_command. Not in toolkit. Hook deny = backstop not UX. Next=spawn not retry. Only /solo (stamp grunt-off-{sid} this session) escapes spawn workflow. /explain=voice+post-child recap never parent Read. No try-then-spawn. No parent probe. No skip-spawn. No trivia/cheap. User-visible = legal tag + **one-line** echo only. Siblings still run: `[grunt]:` echo. Facts/search/trees → grunt, never thinker.
36
37
  Spawn only `grunt` | `implementer` | `thinker`. Omit `model`. Isolation `none` unless asked. Never spawn `orchestrator`. Children never spawn.
37
- grunt ← tools. World fact → grunt `job: web`. Never memory. implementer ← specified solution (not the spec). thinker ← plan/deep reason/spec.
38
+ grunt ← tools. World fact → grunt `job: web`. Never memory. implementer ← specified solution or prompt-is-spec. thinker ← plan/deep reason.
38
39
  Child prompt first sentence only: `You are {agent} subagent.` Then task + abs paths + verdicts only.
39
40
  Peek every 60s/child; quote real host fields; `done|alive|stuck`; no invent; no auto-kill. Grok: `get_command_or_subagent_output` `timeout_ms=60000` every peek. Else GAP: block on spawn return = `done`. Stuck/blocked: quote host fields only.
40
41
  Child `need:` JSON → parse-need + parallel grunt; one `resume_from` + **new** verdicts only; max 3; no re-send task; no fresh-spawn.
41
- `/parent` hook last-ditch only. Skills spawn-first. Only `/solo` escapes spawn workflow.
42
+ `/parent` hook last-ditch only. Skills spawn-first. Only `/solo` escapes spawn workflow. `/pickup` spawn-first; grunt resolve if needed; never parent Read; not a mode.
@@ -34,9 +34,9 @@ import { logTelemetry, ORCHESTRATOR_LOGS_DIR } from "../../scripts/telemetry.mjs
34
34
  export const DENY_REASON =
35
35
  "First action=spawn implementer|grunt|thinker. Deny expected. Only /solo this session escapes.";
36
36
  export const STOP_REASONS = [
37
- "Spawn: ⚠/validate/sim findings or writes remain or parent just tried to Write → spawn implementer. Else facts → grunt. Else no spec → thinker. Else recap `[orchestrator]:` one-line.",
38
- "Still spawn: ⚠/validate/sim findings or writes remain or parent just tried to Write → spawn implementer. Else facts → grunt. Else no spec → thinker. Else recap `[orchestrator]:` one-line.",
39
- "Last spawn: ⚠/validate/sim findings or writes remain or parent just tried to Write → spawn implementer. Else facts → grunt. Else no spec → thinker. Else recap `[orchestrator]:` one-line.",
37
+ "Spawn: ⚠/validate/sim findings or writes remain or parent just tried to Write → spawn implementer. Else facts → grunt. Else large/complex + no spec → thinker. Else small/simple/defined → implementer. Else recap `[orchestrator]:` one-line.",
38
+ "Still spawn: ⚠/validate/sim findings or writes remain or parent just tried to Write → spawn implementer. Else facts → grunt. Else large/complex + no spec → thinker. Else small/simple/defined → implementer. Else recap `[orchestrator]:` one-line.",
39
+ "Last spawn: ⚠/validate/sim findings or writes remain or parent just tried to Write → spawn implementer. Else facts → grunt. Else large/complex + no spec → thinker. Else small/simple/defined → implementer. Else recap `[orchestrator]:` one-line.",
40
40
  ];
41
41
  const TRANSCRIPT_TAIL_BYTES = 512 * 1024;
42
42
  const PARENT_TOOLS = new Set([
@@ -66,6 +66,7 @@ const PARENT_SKILLS = new Set([
66
66
  "solo",
67
67
  "cascade",
68
68
  "handoff",
69
+ "pickup",
69
70
  "write-plan",
70
71
  "implement-plan",
71
72
  ]);
@@ -0,0 +1,17 @@
1
+ ---
2
+ name: browser
3
+ description: >
4
+ Session browser rail. /browser or browse a URL. Call node scripts/browser.mjs
5
+ nav|snap|click|fill|shot|pdf|stop. Lightpanda default; snap is the default
6
+ read. Windows → Chromium. Never MCP. Never env knobs. Never raw Playwright.
7
+ ---
8
+ Zero-config. `node scripts/browser.mjs <verb>`.
9
+
10
+ Verbs: `nav <url>` · `snap` · `click <ref>` · `fill <ref> <text>` · `shot` · `pdf` · `stop` · `doctor` · `ensure`.
11
+
12
+ - **snap** = default read (markdown + numbered refs). `click`/`fill` need a prior snap.
13
+ - Lightpanda default. Chromium when `shot`/`pdf`/`trace`, win32, missing Lightpanda, probe-fail once, or paint hosts (figma docs/sheets/slides mail.google earth).
14
+ - Session/profile: `.tmp/grunt/browser/`. `stop` reaps; second `stop` ok.
15
+ - Windows: Chromium even if Lightpanda exists.
16
+ - `doctor`/`ensure` → `node scripts/doctor.mjs` or `grunt doctor`. See README Prerequisites.
17
+ - No env. No MCP. No raw Playwright. Spec: `.rulesync/reference/browser.md`.
@@ -67,14 +67,14 @@ Host without that hook: name the file per **Path** yourself, or pipe the body to
67
67
 
68
68
  ```
69
69
  [handoff]: serial={int} path=.tmp/grunt/handoffs/{serial}-{slug}-{stamp}.md
70
- next: start a new session; first action = spawn grunt|implementer with abs path={that file}
70
+ next: start a new session; `/pickup {serial}` (equiv: spawn grunt|implementer with abs path={that file})
71
71
  ```
72
72
 
73
73
  Do not dump the handoff body.
74
74
 
75
75
  ## Picking one up
76
76
 
77
- New session, `/handoff` not needed: spawn grunt|implementer with abs path of the newest `.tmp/grunt/handoffs/*.md` (or the given serial). Parent never Read. Child sets `status: resumed`, work `Next` leaves in order, flip only the box. All `[x]` → `status: done`. Do not re-plan; a stale leaf → `/write-plan` a follow-up.
77
+ `/pickup {serial}` owns pickup (equiv: spawn grunt|implementer with abs path). Parent never Read. Child sets `status: resumed`, work `Next` leaves in order, flip only the box. All `[x]` → `status: done`. Do not re-plan; a stale leaf → `/write-plan` a follow-up.
78
78
 
79
79
  ## Rules
80
80
 
@@ -0,0 +1,64 @@
1
+ ---
2
+ name: pickup
3
+ description: >
4
+ Pick up/continue a session handoff under .tmp/grunt/handoffs/. Use for
5
+ /pickup, pick up, continue handoff, serial, drag-drop path,
6
+ newest/last/latest, title substring. Inverse of /handoff. Not a plan. Not
7
+ /handoff.
8
+ ---
9
+ # pickup
10
+
11
+ Voice: `.rulesync/reference/output.md`.
12
+
13
+ Spawn-first pickup. Parent never Read/Bash/list the handoff. First token = spawn. No ask_user_question. Ask = recap list + stop; wait next user turn. Not a mode. Not `/handoff`. Inverse of `/handoff`. Pickup owns pickup.
14
+
15
+ ## Invocation
16
+
17
+ - `/pickup`
18
+ - `/pickup latest` (also `newest`/`last`)
19
+ - `/pickup {serial}`
20
+ - `/pickup {abs|rel|drag-drop path}`
21
+ - `/pickup {title substring}`
22
+
23
+ ## Resolve
24
+
25
+ Via grunt (`job:exec|search` on `.tmp/grunt/handoffs/`). Skip grunt only if user arg is already abs path under that dir.
26
+
27
+ Order:
28
+
29
+ 1. path-like → file if exists + FILENAME_RE `^[0-9]+-[a-z0-9]+(-[a-z0-9]+)*-\d{8}T\d{6}Z\.md$`
30
+ 2. integer → FM serial or filename prefix
31
+ 3. latest|newest|last → newest by FM `created`
32
+ 4. else case-insensitive substring on name/source/H1
33
+ 5. empty arg: 0→none; 1→auto; N→list+ask (**not** auto-newest)
34
+
35
+ List lines: serial status name created path. Prefer open|resumed first; still include done.
36
+
37
+ Matches: 0→recap missing; 1→proceed; N→list+ask never guess.
38
+
39
+ Empty/missing dir: recap no handoffs; stop.
40
+
41
+ Drag outside handoffs dir or non-FILENAME_RE: reject; list valid.
42
+
43
+ Corrupt FM: grunt reports; no implementer on garbage.
44
+
45
+ status done + explicit serial/path: warn; still load if user named it.
46
+
47
+ ## After unique path
48
+
49
+ Spawn implementer with abs path (default). Child: load file; `status: resumed`; Next leaves in order; flip only that box; all `[x]` → `status: done`; do not re-plan; stale → `/write-plan`. Child Edit in place. Never persist-handoff.mjs on pickup. No parent Write on resume.
50
+
51
+ ## Recap
52
+
53
+ ```
54
+ serial={int} path={abs}
55
+ ```
56
+
57
+ Do not invent a new role tag.
58
+
59
+ ## Rules
60
+
61
+ - Parent never Read/Bash/list. First token = spawn.
62
+ - No ask_user_question. Ask = recap list + stop.
63
+ - `/handoff` stays one-turn write. This skill owns pickup.
64
+ - Protocol: `.rulesync/reference/cascade.md`. Do not paste.
@@ -18,6 +18,6 @@ Fat-tool caps stay on — token guards, not cascade.
18
18
 
19
19
  Claude/Codex/Grok: `/solo` via submit hook writes `.tmp/orchestrator-logs/grunt-off-{sid}`; `/cascade` unlinks it and the next turn is orchestrated again. Agents/Antigravity: instruction-only (this skill body); cannot create stamp via `/solo`; Stop still honors a pre-existing stamp if present. Session-scoped, never global.
20
20
 
21
- This is the only session-wide spawn-workflow escape. /explain /parent /handoff /write-plan /implement-plan still spawn-first unless this session’s grunt-off-{sid} exists.
21
+ This is the only session-wide spawn-workflow escape. /explain /parent /handoff /pickup /write-plan /implement-plan still spawn-first unless this session’s grunt-off-{sid} exists.
22
22
 
23
23
  For advisory/design turns, debugging the cascade itself, or back-and-forth where spawning costs more than it saves.