@lovrozagar/grunt 0.5.0 → 0.6.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.
- package/.agents/agents/grunt.md +2 -23
- package/.agents/agents/orchestrator.md +5 -45
- package/.agents/skills/ask/SKILL.md +11 -0
- package/.agents/skills/auto/SKILL.md +13 -0
- package/.agents/skills/browser/SKILL.md +4 -7
- package/.agents/skills/clasp/SKILL.md +11 -0
- package/.agents/skills/commit/SKILL.md +3 -1
- package/.agents/skills/commit-push/SKILL.md +2 -0
- package/.agents/skills/commit-push-deploy/SKILL.md +2 -0
- package/.agents/skills/commit-push-release/SKILL.md +2 -0
- package/.agents/skills/explain/SKILL.md +7 -13
- package/.agents/skills/google-workspace/SKILL.md +13 -0
- package/.agents/skills/handoff/SKILL.md +7 -11
- package/.agents/skills/implement-plan/SKILL.md +5 -108
- package/.agents/skills/listen/SKILL.md +15 -0
- package/.agents/skills/pickup/SKILL.md +6 -12
- package/.agents/skills/speak/SKILL.md +13 -0
- package/.agents/skills/tmp/SKILL.md +54 -0
- package/.agents/skills/write-plan/SKILL.md +5 -74
- package/.claude/agents/grunt.md +2 -25
- package/.claude/agents/orchestrator.md +12 -45
- package/.claude/skills/ask/SKILL.md +11 -0
- package/.claude/skills/auto/SKILL.md +13 -0
- package/.claude/skills/browser/SKILL.md +4 -7
- package/.claude/skills/clasp/SKILL.md +11 -0
- package/.claude/skills/commit/SKILL.md +3 -1
- package/.claude/skills/commit-push/SKILL.md +2 -0
- package/.claude/skills/commit-push-deploy/SKILL.md +2 -0
- package/.claude/skills/commit-push-release/SKILL.md +2 -0
- package/.claude/skills/explain/SKILL.md +7 -13
- package/.claude/skills/google-workspace/SKILL.md +13 -0
- package/.claude/skills/handoff/SKILL.md +7 -11
- package/.claude/skills/implement-plan/SKILL.md +5 -108
- package/.claude/skills/listen/SKILL.md +15 -0
- package/.claude/skills/pickup/SKILL.md +6 -12
- package/.claude/skills/speak/SKILL.md +13 -0
- package/.claude/skills/tmp/SKILL.md +54 -0
- package/.claude/skills/write-plan/SKILL.md +5 -74
- package/.codex/agents/grunt.toml +2 -25
- package/.codex/agents/orchestrator.toml +4 -45
- package/.grok/agents/grunt.md +2 -23
- package/.grok/agents/orchestrator.md +4 -43
- package/.grok/global-settings.toml +1 -3
- package/.grok/hooks/orchestrate-parent.js +278 -228
- package/.grok/skills/ask/SKILL.md +11 -0
- package/.grok/skills/auto/SKILL.md +13 -0
- package/.grok/skills/browser/SKILL.md +4 -7
- package/.grok/skills/clasp/SKILL.md +11 -0
- package/.grok/skills/commit/SKILL.md +3 -1
- package/.grok/skills/commit-push/SKILL.md +2 -0
- package/.grok/skills/commit-push-deploy/SKILL.md +2 -0
- package/.grok/skills/commit-push-release/SKILL.md +2 -0
- package/.grok/skills/explain/SKILL.md +7 -13
- package/.grok/skills/google-workspace/SKILL.md +13 -0
- package/.grok/skills/handoff/SKILL.md +7 -11
- package/.grok/skills/implement-plan/SKILL.md +5 -108
- package/.grok/skills/listen/SKILL.md +15 -0
- package/.grok/skills/pickup/SKILL.md +6 -12
- package/.grok/skills/speak/SKILL.md +13 -0
- package/.grok/skills/tmp/SKILL.md +54 -0
- package/.grok/skills/write-plan/SKILL.md +5 -74
- package/.rulesync/hooks.jsonc +1 -1
- package/.rulesync/mcp-policy.jsonc +0 -2
- package/.rulesync/reference/INDEX.md +30 -17
- package/.rulesync/reference/browser.md +13 -6
- package/.rulesync/reference/cascade.md +6 -84
- package/.rulesync/reference/clasp.md +21 -0
- package/.rulesync/reference/google-workspace.md +79 -0
- package/.rulesync/reference/hooks.md +7 -9
- package/.rulesync/reference/implementation-format.md +113 -0
- package/.rulesync/reference/law.md +5 -3
- package/.rulesync/reference/listen.md +80 -0
- package/.rulesync/reference/map.md +39 -31
- package/.rulesync/reference/output.md +3 -41
- package/.rulesync/reference/plan-format.md +14 -12
- package/.rulesync/reference/refs-map.md +12 -5
- package/.rulesync/reference/rtk.md +3 -2
- package/.rulesync/reference/scope.md +37 -0
- package/.rulesync/reference/setup.md +27 -0
- package/.rulesync/reference/skills-map.md +13 -9
- package/.rulesync/reference/speak.md +59 -0
- package/.rulesync/rules/CLAUDE.md +3 -44
- package/.rulesync/rules/overview.md +9 -42
- package/.rulesync/skills/ask/SKILL.md +11 -0
- package/.rulesync/skills/auto/SKILL.md +11 -0
- package/.rulesync/skills/browser/SKILL.md +4 -8
- package/.rulesync/skills/clasp/SKILL.md +9 -0
- package/.rulesync/skills/commit/SKILL.md +3 -1
- package/.rulesync/skills/commit-push/SKILL.md +2 -0
- package/.rulesync/skills/commit-push-deploy/SKILL.md +2 -0
- package/.rulesync/skills/commit-push-release/SKILL.md +2 -0
- package/.rulesync/skills/explain/SKILL.md +7 -14
- package/.rulesync/skills/google-workspace/SKILL.md +11 -0
- package/.rulesync/skills/handoff/SKILL.md +7 -11
- package/.rulesync/skills/implement-plan/SKILL.md +5 -116
- package/.rulesync/skills/listen/SKILL.md +13 -0
- package/.rulesync/skills/pickup/SKILL.md +6 -12
- package/.rulesync/skills/speak/SKILL.md +13 -0
- package/.rulesync/skills/tmp/SKILL.md +54 -0
- package/.rulesync/skills/write-plan/SKILL.md +5 -80
- package/.rulesync/subagents/grunt.md +2 -23
- package/.rulesync/subagents/orchestrator.md +14 -54
- package/AGENTS.md +9 -42
- package/CHANGELOG.md +89 -0
- package/CLAUDE.md +1 -44
- package/README.md +97 -88
- package/cli/grunt.mjs +29 -13
- package/cli/grunt.test.ts +62 -20
- package/cli/init.mjs +218 -31
- package/cli/init.test.ts +669 -46
- package/cli/prompt.mjs +8 -0
- package/cli/prompt.test.ts +14 -0
- package/package.json +13 -1
- package/scripts/browser.mjs +98 -5
- package/scripts/doctor.mjs +82 -1
- package/scripts/emit-gemini.mjs +1 -1
- package/scripts/emit-mcp-policy.mjs +1 -1
- package/scripts/gate-fat-tools.mjs +223 -173
- package/scripts/google-workspace.mjs +713 -0
- package/scripts/grunt-job.mjs +453 -69
- package/scripts/listen.mjs +829 -0
- package/scripts/parse-need.mjs +21 -2
- package/scripts/persist-implementation.mjs +278 -0
- package/scripts/persist-plan.mjs +17 -2
- package/scripts/persist-tmp.mjs +123 -0
- package/scripts/scrub-spawn-prompt.mjs +4 -51
- package/scripts/setup.mjs +746 -0
- package/scripts/speak.mjs +291 -0
- package/.agents/agents/implementer.md +0 -32
- package/.agents/agents/thinker.md +0 -28
- package/.agents/skills/cascade/SKILL.md +0 -26
- package/.agents/skills/parent/SKILL.md +0 -6
- package/.agents/skills/solo/SKILL.md +0 -23
- package/.claude/agents/implementer.md +0 -37
- package/.claude/agents/thinker.md +0 -35
- package/.claude/skills/cascade/SKILL.md +0 -26
- package/.claude/skills/parent/SKILL.md +0 -6
- package/.claude/skills/solo/SKILL.md +0 -23
- package/.codex/agents/implementer.toml +0 -26
- package/.codex/agents/thinker.toml +0 -25
- package/.grok/agents/implementer.md +0 -27
- package/.grok/agents/thinker.md +0 -26
- package/.grok/parent.md +0 -1
- package/.grok/roles/implementer.toml +0 -5
- package/.grok/roles/thinker.toml +0 -5
- package/.grok/skills/cascade/SKILL.md +0 -26
- package/.grok/skills/parent/SKILL.md +0 -6
- package/.grok/skills/solo/SKILL.md +0 -23
- package/.rulesync/skills/cascade/SKILL.md +0 -26
- package/.rulesync/skills/parent/SKILL.md +0 -6
- package/.rulesync/skills/solo/SKILL.md +0 -23
- package/.rulesync/subagents/implementer.md +0 -49
- package/.rulesync/subagents/thinker.md +0 -48
|
@@ -2,42 +2,55 @@
|
|
|
2
2
|
|
|
3
3
|
# Law
|
|
4
4
|
|
|
5
|
-
Protocol stays
|
|
5
|
+
Protocol stays overview; domain fills this.
|
|
6
6
|
|
|
7
7
|
## Skills naming
|
|
8
8
|
|
|
9
|
-
Reserved (do not reuse in consumer custom skills): `browser` `
|
|
9
|
+
Reserved (do not reuse in consumer custom skills): `ask` `auto` `browser` `clasp` `commit` `commit-and-push` `commit-push` `commit-push-deploy` `commit-push-release` `explain` `google-workspace` `handoff` `implement-plan` `listen` `pickup` `speak` `tmp` `write-plan`.
|
|
10
10
|
|
|
11
|
-
Override: same name → one SSOT path (`.rulesync/skills/<name>/`). Re-init force-refresh overwrites grunt-owned names; consumer extras kept. Maps `origin` badge ≠ content picker.
|
|
11
|
+
Override: same name → one SSOT path (`.rulesync/skills/<name>/`). Re-init / `grunt upgrade` force-refresh overwrites grunt-owned names; consumer extras kept. Maps `origin` badge ≠ content picker.
|
|
12
|
+
|
|
13
|
+
Upgrade copies the current package trees and product scripts, then deletes cumulative retired grunt-owned names (skills `parent` `solo` `cascade`; agents `implementer` `thinker`; scripts `telemetry.mjs` `grunt-config.mjs`; paths `.grok/parent.md` `.grok/skills/shared` `.rulesync/grunt.config.jsonc` `.rulesync/grunt.config.local.jsonc` `.rulesync/grunt.config.local.jsonc.example`) and any reserved skill dir this package no longer ships. `fs.cpSync` does not remove dest extras; prune is what drops them. Consumer skills/refs/scripts not on those lists stay.
|
|
12
14
|
|
|
13
15
|
# Skills
|
|
14
16
|
|
|
15
17
|
| name | origin | description | task | commandPath | refs |
|
|
16
18
|
| --- | --- | --- | --- | --- | --- |
|
|
17
|
-
|
|
|
18
|
-
|
|
|
19
|
+
| ask | local | Session flag. Finish one step, recap, then ask before the next. | | | |
|
|
20
|
+
| auto | local | Session flag. Default. Work the task through. Ask on blockers instead of monkey-patching. | | | |
|
|
21
|
+
| browser | local | Browse via node scripts/browser.mjs (Lightpanda). App e2e uses Playwright. | | | |
|
|
22
|
+
| clasp | local | Low-level Apps Script CLI. Prefer /google-workspace for sheet, doc, meeting, mail. | | | |
|
|
19
23
|
| commit | local | Inspect the diff and commit with a Conventional Commits subject line. Use for /commit, "commit this", "commit these cha… | | | |
|
|
20
24
|
| commit-and-push | local | Alias of commit-push (1-release stub). Use for /commit-and-push, "commit and push", "commit this and push". Must push.… | | | |
|
|
21
25
|
| commit-push | local | Commit with a Conventional Commits subject, then push. Use for /commit-push, "commit and push", "commit this and push".… | | | |
|
|
22
26
|
| commit-push-deploy | local | Commit, push, then deploy only if allowlisted infra already exists. Use for /commit-push-deploy, "commit push deploy",… | | | |
|
|
23
27
|
| commit-push-release | local | Commit, push, bump package.json, tag vX.Y.Z, push the tag. CI publishes. Use for /commit-push-release, "commit push rel… | | | |
|
|
24
|
-
| explain | local |
|
|
25
|
-
|
|
|
26
|
-
|
|
|
27
|
-
|
|
|
28
|
-
|
|
|
29
|
-
|
|
|
30
|
-
|
|
|
28
|
+
| explain | local | Longer human recap this reply only. | | | |
|
|
29
|
+
| google-workspace | local | Google Sheets, Docs, Slides, Calendar, Gmail via node scripts/google-workspace.mjs. | | | |
|
|
30
|
+
| handoff | local | Write a session handoff under .tmp/grunt/handoffs/. Continue with /pickup. | | | |
|
|
31
|
+
| implement-plan | local | Execute remaining leaves in a .tmp/grunt/plans checklist. Skip [x]. | | | |
|
|
32
|
+
| listen | local | Speech-to-text via node scripts/listen.mjs (ffmpeg mic + local whisper.cpp, OpenAI fallback). Input only. | | | |
|
|
33
|
+
| pickup | local | Continue a handoff under .tmp/grunt/handoffs/. | | | |
|
|
34
|
+
| speak | local | Text-to-speech via node scripts/speak.mjs (ElevenLabs or OpenAI). Output only. | | | |
|
|
35
|
+
| tmp | local | Dump a one-off convo artifact under .tmp/grunt/. | | | |
|
|
36
|
+
| write-plan | local | Write a local checklist under .tmp/grunt/plans/. Then /implement-plan {n}. | | | |
|
|
31
37
|
|
|
32
38
|
# Refs
|
|
33
39
|
|
|
34
40
|
| path | title | tags | summary |
|
|
35
41
|
| --- | --- | --- | --- |
|
|
36
|
-
| .rulesync/reference/browser.md | Browser | browser | Zero-config in-tree session rail. Not MCP. Not env. Not raw Playwright. |
|
|
37
|
-
| .rulesync/reference/cascade.md |
|
|
42
|
+
| .rulesync/reference/browser.md | Browser | browser | Zero-config in-tree session rail. Not MCP. Not env. Not raw Playwright. Lightpanda first; swap to Chromium when blocked. |
|
|
43
|
+
| .rulesync/reference/cascade.md | Protocol | cascade | The session agent has tools. Fat Read/Grep/Bash dumps are rewritten to `scripts/grunt-job.mjs` (squeez + stash). Isolat… |
|
|
44
|
+
| .rulesync/reference/clasp.md | Clasp | clasp | Low-level Apps Script CLI. Optional. Doctor reports it. |
|
|
45
|
+
| .rulesync/reference/google-workspace.md | google-workspace | google-workspace | Create and edit Google Sheets, Docs, Slides, Calendar events, and Gmail from the session. |
|
|
38
46
|
| .rulesync/reference/hooks.md | Hooks | hooks | SessionStart: keep empty (token baseline). Do not inject context. Do not register a SessionStart hook on `../../.grok/h… |
|
|
39
|
-
| .rulesync/reference/
|
|
47
|
+
| .rulesync/reference/implementation-format.md | Implementation format (SSOT) | | Local session journal for `/implement-plan`. Not a plan, handoff, or git commit. |
|
|
48
|
+
| .rulesync/reference/law.md | Law | | Protocol stays overview; domain fills this. |
|
|
49
|
+
| .rulesync/reference/listen.md | Listen | listen | Speech-to-text from the session. Input only. Not TTS. Not a live voice agent. Not MCP. |
|
|
40
50
|
| .rulesync/reference/map.md | Map | map | Cheap outline. Not a file dump. |
|
|
41
|
-
| .rulesync/reference/output.md | Output | output | en-US unless asked.
|
|
42
|
-
| .rulesync/reference/plan-format.md | Plan format (SSOT) | | Local
|
|
51
|
+
| .rulesync/reference/output.md | Output | output | en-US unless asked. Concise complete sentences with natural grammar. Skip filler and fluff. |
|
|
52
|
+
| .rulesync/reference/plan-format.md | Plan format (SSOT) | | Local session checklist. Not a design doc, PR stack, or DAG. |
|
|
43
53
|
| .rulesync/reference/rtk.md | RTK | rtk | Shell stdout compression. PreToolUse: Bash → `rtk <cmd>`. Not Read/Grep/Glob/prompts/images. |
|
|
54
|
+
| .rulesync/reference/scope.md | Scope | scope | Default: do the work. Escalate only when it is not a straight shot. This file is the size-gate SSOT. |
|
|
55
|
+
| .rulesync/reference/setup.md | Setup | setup | Handheld machine setup for optional integrations. Any OS. Secrets stay in `~/.grunt/` (Windows `%USERPROFILE%\.grunt`).… |
|
|
56
|
+
| .rulesync/reference/speak.md | Speak | speak | Text-to-speech from the session. Output only. Not STT. Not a mic. Not MCP. Speech-to-text is `/listen`: `.rulesync/refe… |
|
|
@@ -4,13 +4,13 @@ tags: [browser]
|
|
|
4
4
|
|
|
5
5
|
# Browser
|
|
6
6
|
|
|
7
|
-
Zero-config in-tree session rail. Not MCP. Not env. Not raw Playwright.
|
|
7
|
+
Zero-config in-tree session rail. Not MCP. Not env. Not raw Playwright. Lightpanda first; swap to Chromium when blocked.
|
|
8
8
|
|
|
9
9
|
```
|
|
10
|
-
node scripts/browser.mjs nav|snap|click|fill|shot|pdf|stop|doctor|ensure
|
|
10
|
+
node scripts/browser.mjs nav|snap|click|fill|scroll|wait|hover|select|shot|pdf|stop|doctor|ensure
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
Default engine: **Lightpanda** (`lightpanda` on PATH). Chromium
|
|
13
|
+
Default engine: **Lightpanda** (`lightpanda` on PATH). Chromium when a rule below requires it. Never report "can't browse" while Chromium is available.
|
|
14
14
|
|
|
15
15
|
## Verbs
|
|
16
16
|
|
|
@@ -20,6 +20,10 @@ Default engine: **Lightpanda** (`lightpanda` on PATH). Chromium only when a rule
|
|
|
20
20
|
| `snap` | markdown + numbered AX refs (default read) |
|
|
21
21
|
| `click <ref>` | click a ref from last `snap` |
|
|
22
22
|
| `fill <ref> <text>` | fill a ref from last `snap` |
|
|
23
|
+
| `scroll [ref|down|up|N]` | scroll a snap ref into view, or the window |
|
|
24
|
+
| `wait [ms]` | pause (default 1000, cap 15000) |
|
|
25
|
+
| `hover <ref>` | hover a snap ref |
|
|
26
|
+
| `select <ref> <value>` | set a select/option value |
|
|
23
27
|
| `shot` | screenshot (Chromium paint) |
|
|
24
28
|
| `pdf` | PDF (Chromium paint) |
|
|
25
29
|
| `stop` | reap engine pid; clear session; idempotent |
|
|
@@ -30,7 +34,7 @@ Session + profile + artifacts: `.tmp/grunt/browser/` only.
|
|
|
30
34
|
|
|
31
35
|
## Install
|
|
32
36
|
|
|
33
|
-
Run `grunt doctor` / `node scripts/doctor.mjs`.
|
|
37
|
+
Run `grunt doctor` / `node scripts/doctor.mjs`. Handheld engine hints (no keys): `node scripts/setup.mjs browser`. Doctor/setup is enough. Do not read a README unless those are missing; then https://github.com/lovrozagar/grunt#prerequisites (not the consumer README).
|
|
34
38
|
|
|
35
39
|
## Engine
|
|
36
40
|
|
|
@@ -40,9 +44,12 @@ Chromium immediately when any of:
|
|
|
40
44
|
|
|
41
45
|
- verb is `shot` | `pdf` | `trace`
|
|
42
46
|
- `process.platform === "win32"`
|
|
43
|
-
-
|
|
47
|
+
- Chromium-first host: figma, Google docs / sheets / slides, mail.google, earth, amazon
|
|
44
48
|
- `lightpanda` missing from PATH and a Chromium binary is present
|
|
45
49
|
- Lightpanda probe fails **once** → one Chromium replay of last URL; no loop
|
|
50
|
+
- `snap` on Lightpanda is empty, a bot/JS wall, or client-rendered junk → one Chromium replay, then snap again
|
|
51
|
+
|
|
52
|
+
The session agent does not invent a "can't" for Amazon or other client-rendered sites. The rail swaps. One swap cap. App e2e stays Playwright (`playwright test`), not this CLI.
|
|
46
53
|
|
|
47
54
|
No user env. Never `GRUNT_BROWSER*`. Never `LIGHTPANDA_CDP_URL`.
|
|
48
55
|
|
|
@@ -50,7 +57,7 @@ No user env. Never `GRUNT_BROWSER*`. Never `LIGHTPANDA_CDP_URL`.
|
|
|
50
57
|
|
|
51
58
|
- MCP browser servers
|
|
52
59
|
- user env knobs
|
|
53
|
-
- raw Playwright as the
|
|
60
|
+
- raw Playwright as the browse tool (Playwright is the app e2e runner)
|
|
54
61
|
- grunt `job:browse`
|
|
55
62
|
- teaching thinker / orchestrator to browse
|
|
56
63
|
|
|
@@ -2,92 +2,14 @@
|
|
|
2
2
|
tags: [cascade]
|
|
3
3
|
---
|
|
4
4
|
|
|
5
|
-
#
|
|
5
|
+
# Protocol
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
The session agent has tools. Fat Read/Grep/Bash dumps are rewritten to `scripts/grunt-job.mjs` (squeez + stash). Isolation facts stay ≤8 lines.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Run `node scripts/grunt-job.mjs --job search|exec|slice|fetch|test` first. Spawn a grunt model only when the dump needs judgment (browse snap, messy test log). Isolation work may run as grunt.
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
⚠ / validate / sim → spawn implementer; not stop.
|
|
13
|
-
Child prompt first sentence only: `You are {agent} subagent.` Then task + abs paths + verdicts only.
|
|
11
|
+
`need:` JSON (search|exec|slice|fetch) may be intercepted in-hook (cap 4). Peek/kill if a child is running: Grok `get_command_or_subagent_output` `timeout_ms=60000`. Other hosts: block on spawn return.
|
|
14
12
|
|
|
15
|
-
|
|
16
|
-
Create/change product files → grunt facts first; then thinker advise/plan/stop unless small/simple or prompt-is-spec → implementer. Default without detailed spec = grunt check → thinker advise/plan → stop. Advise-first stop wins until unlock. Unlock implementer only on: numbered/label pick1 or pick2 or `/implement-plan {n}` or explicit implement (=pick1). `ok`/`yes`/`y`/`continue` ≠ either implement path (`continue` = write-plan file gate only). Thinker recap alone ≠ spec-ready; do not auto-implement. Conversational advise recap = stop.
|
|
17
|
-
Advise leftover: numbered pick each on own line after tagged recap (not same-line):
|
|
18
|
-
1. Implementer with verbal plan
|
|
19
|
-
2. Implementer with file plan
|
|
20
|
-
3. Tweak
|
|
21
|
-
Match number or full leftover label (or unique tail `verbal plan` / `file plan`). Always-do leftover match; not Skill-name (`2` ≠ write-plan). 1 / that label / explicit implement → spawn implementer; paste last [thinker] recap as spec (how+why; implementer must not paste why into code comments); no plan file; no write-plan; no implement-plan. Bare `implement`/`implementer` → pick1 only (shared prefix; do not substring-match both picks). 2 / that label → persist `.tmp/plans/{n}` then spawn implementer with `plan=/abs/...` path only (write-plan then implement-plan one-shot; skip inspect pause; no user slash). Parent still no Write — existing write-plan path/skill sequencing. 3 / Tweak → stay advise; no implementer. Extra user text = revision notes → thinker; bare 3/Tweak = stop wait notes. `/write-plan` persist-only inspect-pause; remainder ask `/implement-plan {n}`. Not a leftover number. `/implement-plan {n}` stays disk/file run; ≠ conversational verbal pick. Disk leftover may invoke without user slash; verbal ≠ implement-plan.
|
|
22
|
-
Never parent Write/Edit/Bash/Skill-that-writes. Child returned is not terminal if writes remain after that gate or spawn count is 0 on a pick1/pick2/`/implement-plan {n}`/spec/small file-change turn. plan/spec ready + writes remain → spawn implementer only on that gate; else recap-stop. plan-only `/write-plan` → recap + remainder `/implement-plan` (ask).
|
|
13
|
+
Session flags: `/auto` (default) keeps going and asks on blockers instead of monkey-patching. `/ask` finishes one step, recaps, then asks. Slash `/ask` stamps `.tmp/grunt/orchestrator-logs/session-gate-{sid}`; `/auto` unlinks.
|
|
23
14
|
|
|
24
|
-
|
|
25
|
-
1. Tools (facts / search / exec / git / web / test / low-reason mechanical write) → grunt. Facts/search → grunt, never thinker.
|
|
26
|
-
2. Write defined solution (prompt-is-spec or small/simple) → implementer. **Blocked if advise-class stems present** unless prompt-is-spec / obvious comment-spec false+. Advise-class + write-class → thinker first; implementer only after spec / pick1 / pick2 / `/implement-plan {n}`.
|
|
27
|
-
3. Think / plan / advise / recommend / how / why / explain (ask-us; not slash `/explain`; not one-cmd/last-log/source-token) → thinker. Facts=grunt/`need:`. **No implementer this turn**. Unsure → thinker. Cheap false+: I think / terraform plan / `/implement-plan` / `/solo` / source tokens / one-cmd / how- last-log / why. Why = judgment not patch not dump; parent cannot invent why; **parent cannot drop why**. Thinker recap without why = incomplete (leftover 3 / re-spawn; not silent; not invent). One re-spawn max then recap-as-is + flag.
|
|
28
|
-
Reuse iff ALL: (1) same parent transcript already has finished `[thinker]:` (or the fact recap they’re poking); (2) user turn is advise-class again with no new path/error/snippet/name/“what about/also/now/but/instead”; (3) no implementer or grunt after that answer; no unresolved `need:`; (4) not “more/deeper/details/walk through/wrong”. Any tick fail / new session / `/pickup` / `/handoff` / compaction ate the body → spawn. Echo last `[thinker]:` recap one-line (don’t paraphrase; no-strip why; no compress-to-verdict). Advise leftover still adds numbered pick on own lines. Prose → `/explain` on visible child. Always-why recap ≠ `/explain`. Not grunt for parrot. Tag `[orchestrator]:` on no-spawn — don’t fake `[thinker]:`. Pitfalls: deeper→thinker; code moved invalidates; `need:` open; compaction.
|
|
29
|
-
4. Fresh/world facts → grunt `job: web`. Never answer from memory.
|
|
30
|
-
|
|
31
|
-
Spawn only `grunt` | `implementer` | `thinker`. Omit `model`. Isolation `none` unless asked.
|
|
32
|
-
|
|
33
|
-
Implementer may tiny-Read/Grep/list_dir. Thinker named-file Read of prompt SSOT only; investigate/search/trees → `need:` grunt. Fat dumps via `need:` JSON.
|
|
34
|
-
|
|
35
|
-
Long parent sessions rely on two-pass compaction; prefer a new parent session per task rather than unbounded resume chains. `[features] two_pass_compaction = true` must live in `~/.grok/config.toml` (from `.grok/global-settings.toml` via `npm run sync:globals` dry-run / `npm run sync:globals:apply`). Project `.grok/config.toml` cannot set `[features]`. Do not add a SessionStart hook.
|
|
36
|
-
|
|
37
|
-
## Wait / peek
|
|
38
|
-
|
|
39
|
-
Parent-only. Non-blocking spawn so each child has a host id immediately. Per-child, not one global timer.
|
|
40
|
-
Every 60s peek is real host status (no `sleep` then guess). `timeout_ms=60000` every peek.
|
|
41
|
-
Quote host fields only (`status`, elapsed since spawn, last activity/output snippet) or quote the error. Never invent.
|
|
42
|
-
Classify `done` | `alive` | `stuck` vs prior peek: **done** (completed/failed), **alive** (running + fields/output changed), **stuck** (running + unchanged). Unchanged snippet = stuck, not “still working”.
|
|
43
|
-
Loop until done. No auto-kill. Kill only if the user asks and the host has a kill tool.
|
|
44
|
-
Final recap uses [output.md](output.md) natural buckets (completed / in-flight / remainder / blocker; omit empty). Do not redo the child's work. Exceptions: in-flight wait = `[orchestrator]: wait grunt` only; `need:` stop = JSON only; max 3 `resume_from` → blocker recap + gathered verdicts (ask).
|
|
45
|
-
|
|
46
|
-
Parent Stop (`MAX_STOP=3`): do not waive fenced/impl finals for `tools-used` stamp. Parent `end_turn` is tagged recap (advise leftover numbered pick on own lines after) or `[orchestrator]: wait grunt`. First non-empty line must match legal `[orchestrator|grunt|implementer|thinker|handoff]:`. Advise leftover numbered pick may follow the tagged recap (format only; hook does not map `1`/`2`/`3` → skills). Siblings still run → role tag + one-line echo. In-flight wait recap is `[orchestrator]: wait grunt` only. Mid-turn stays exactly `[orchestrator]: wait grunt`. Or consume `parent-escape-{sid}` once. Else block. No `isCheap` / trivia / long definitions.
|
|
47
|
-
`/handoff` is the other in-parent turn: context large + work unfinished → parent writes one `.tmp/grunt/handoffs/` file from its own transcript (no child sees the session), recaps `[handoff]: serial=… path=…`, tells the user to continue in a new session. No spawn, one write, not a mode.
|
|
48
|
-
`/pickup` is spawn-first pickup, not in-parent write; parent never Read. Inverse of `/handoff`.
|
|
49
|
-
`/solo` is the session mode (not one-turn): `beforeSubmitPrompt` writes `.tmp/orchestrator-logs/grunt-off-{sid}`, every gate short-circuits while it exists, `/cascade` unlinks it. Everything above resumes next turn. Antigravity: skill-only, no stamp create (see hooks.md). `/parent` is last-ditch hook stamp (not a mode, not skill-instructed Read/Bash): UserPromptSubmit writes `.tmp/orchestrator-logs/parent-escape-{sid}`; Stop consumes+unlinks once. Next Stop resumes spawn/recap rules. `/explain` is human recap after children; never parent Read; not a mode; not spawn-escape. Skills point here; do not paste this file. Never parent-Read protocol files.
|
|
50
|
-
|
|
51
|
-
Host mapping (in-tree only; do not invent peek/kill APIs). GAP rows: no fake peeks, no auto-kill.
|
|
52
|
-
|
|
53
|
-
| Host | Spawn | Peek | Kill |
|
|
54
|
-
| --- | --- | --- | --- |
|
|
55
|
-
| Grok | `spawn_subagent` `background:true` → `task_id` | `get_command_or_subagent_output` + `timeout_ms=60000` | `kill_command_or_subagent` (user-ask only) |
|
|
56
|
-
| Claude Code | `Agent` if the parent session exposes it | GAP unless an in-tree schema names a status/output tool on that id (do not invent `TaskOutput`); else block on Agent return and classify `done`. Agent launch ≠ child done; in-flight host Stop → only `[orchestrator]: wait grunt`; no SendMessage | GAP unless in-tree; no auto-kill |
|
|
57
|
-
| Codex | host agent/call | GAP; block on host agent/call return; classify `done` | GAP; no auto-kill |
|
|
58
|
-
| Antigravity | main-session parent | GAP peek/kill; main-session parent | GAP; no auto-kill |
|
|
59
|
-
| Gemini | not emitted; tracked gap | GAP; no fake peeks | GAP; no auto-kill |
|
|
60
|
-
|
|
61
|
-
## Late dump (`need:` + `resume_from`)
|
|
62
|
-
|
|
63
|
-
If implementer/thinker still needs a fat dump: it **stops**. The stop message for dumps is this JSON line only (no prose):
|
|
64
|
-
|
|
65
|
-
```
|
|
66
|
-
need: [{"job":"search","query":"..."}]
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
`job` ∈ search|exec|web|test. 1–N jobs. Cap one batch at 4 jobs; overflow stays for the next loop. Do not emit N sequential single-job stops for known-parallel dumps.
|
|
70
|
-
|
|
71
|
-
If a child still emits `need:` and every job is `search|exec`, SubagentStop (and child `Stop` with `subagentType`) runs grunt-job in-hook and continues the child with concatenated `verdict:` blobs (`decision: "block"` + `additionalContext`). Mixed / web / test batches are not intercepted: parent `scripts/parse-need.mjs` + LLM grunt. Thinker has no bash; intercept still applies.
|
|
72
|
-
|
|
73
|
-
Parent: parse with `scripts/parse-need.mjs` (same grammar). If parse succeeds, fan out those jobs as parallel grunt spawns; do not interpret surrounding prose. Wait; one `resume_from: <child id>` with **new** `verdict:` blobs only. Do not fresh-spawn. Max 3 `resume_from` for one child id; then parent blocker recap + the verdicts already gathered (ask).
|
|
74
|
-
|
|
75
|
-
Resume prompt = `You are {agent} subagent.` plus the new verdicts. Do not re-send the original task, cascade, or prior verdicts (`resume_from` already has the transcript).
|
|
76
|
-
|
|
77
|
-
Voice: [output](output.md). Does not change need:/verdict:/plan grammar.
|
|
78
|
-
|
|
79
|
-
## Isolation grunt `verdict:`
|
|
80
|
-
|
|
81
|
-
```
|
|
82
|
-
verdict: ok|fail|empty
|
|
83
|
-
n: <count>
|
|
84
|
-
- path:line — fact
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
Fail: first 3 error lines. ≤8 lines. No dumps, recap, HTML, JSON, full logs.
|
|
88
|
-
|
|
89
|
-
Implementer/thinker: fat dumps via `need:` JSON. Implementer shell via rtk; cat/rg/curl/tests without rtk → fat `need:`.
|
|
90
|
-
|
|
91
|
-
Child prompt first sentence only: `You are {agent} subagent.` Then task + abs paths + verdicts only.
|
|
92
|
-
|
|
93
|
-
Grok PostToolUse is observe-only. SessionStart stays empty (token baseline). See [hooks](hooks.md).
|
|
15
|
+
Scratch: `.tmp/grunt/`. Stash: `.tmp/grunt/stash/`. Sessions: `.tmp/grunt/sessions/{sid}/`. Browser: `.tmp/grunt/browser/`.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
tags: [clasp]
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Clasp
|
|
6
|
+
|
|
7
|
+
Low-level Apps Script CLI. Optional. Doctor reports it.
|
|
8
|
+
|
|
9
|
+
For create/edit sheet, doc, slide, meeting, or mail, use **google-workspace**: `.rulesync/reference/google-workspace.md` and `node scripts/google-workspace.mjs`. Do not start from clasp.
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
npm i -g @google/clasp
|
|
13
|
+
clasp login
|
|
14
|
+
clasp create --type standalone --title <name>
|
|
15
|
+
clasp pull
|
|
16
|
+
clasp push
|
|
17
|
+
clasp run <function>
|
|
18
|
+
clasp status
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Script files live next to `appsscript.json`. Git tracks them. `clasp run` needs the Apps Script API and an API-executable deployment. That path is for custom `.gs`, not day-to-day Workspace.
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
---
|
|
2
|
+
tags: [google-workspace]
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# google-workspace
|
|
6
|
+
|
|
7
|
+
Create and edit Google Sheets, Docs, Slides, Calendar events, and Gmail from the session.
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
node scripts/google-workspace.mjs whoami
|
|
11
|
+
node scripts/google-workspace.mjs scopes
|
|
12
|
+
node scripts/google-workspace.mjs login
|
|
13
|
+
node scripts/google-workspace.mjs sheet create --title "Q3" --csv "item,qty\nA,2"
|
|
14
|
+
node scripts/google-workspace.mjs sheet set --id ID --cell A1 --value x
|
|
15
|
+
node scripts/google-workspace.mjs sheet get --id ID --range A1:B10
|
|
16
|
+
node scripts/google-workspace.mjs sheet append --id ID --csv "c,3"
|
|
17
|
+
node scripts/google-workspace.mjs sheet clear --id ID --range A1:Z
|
|
18
|
+
node scripts/google-workspace.mjs doc create --title "Notes" --body "hello"
|
|
19
|
+
node scripts/google-workspace.mjs doc append --id ID --body "more"
|
|
20
|
+
node scripts/google-workspace.mjs drive list --query "mimeType='application/vnd.google-apps.spreadsheet'"
|
|
21
|
+
node scripts/google-workspace.mjs slide create --title "Deck"
|
|
22
|
+
node scripts/google-workspace.mjs meeting create --title "Standup" --start 2026-09-15T09:00:00Z --end 2026-09-15T09:15:00Z --attendees a@x.com,b@y.com
|
|
23
|
+
node scripts/google-workspace.mjs mail send --to you@example.com --subject hi --body hello
|
|
24
|
+
node scripts/google-workspace.mjs mail list
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Each person has their own Google Cloud app. Creds stay in `~/.grunt/` on that machine. Do not share OAuth JSON or tokens. Do not commit them. Inviting others to a meeting is attendee emails, not shared creds.
|
|
28
|
+
|
|
29
|
+
Handheld (any OS): `node scripts/setup.mjs google-workspace` or `npm exec grunt setup` → google-workspace. Opens each Cloud Console page, waits, copies the Desktop JSON into `~/.grunt/google-oauth.json`, then browser Allow. Non-TTY: `--creds PATH` to a Desktop download. `--account NAME` for a second Google user.
|
|
30
|
+
|
|
31
|
+
Doctor reports google-workspace as optional: `ok` when Desktop OAuth JSON, tokens, gcloud ADC, or `~/.clasprc.json` exists, else `missing (optional)`. It prints source names (`oauth` `tokens` `adc` `clasprc`), not secrets. `clasprc` is Drive-only.
|
|
32
|
+
|
|
33
|
+
Two Google accounts on one machine: `--account NAME` (or `WORKSPACE_ACCOUNT`). Default is `default` (legacy files `~/.grunt/google-oauth.json` + `workspace-tokens.json` still work). Other accounts use `~/.grunt/workspace/NAME/`.
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
node scripts/google-workspace.mjs --account work login
|
|
37
|
+
node scripts/google-workspace.mjs --account work whoami
|
|
38
|
+
node scripts/google-workspace.mjs accounts
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Each account needs its own Desktop JSON in that folder (`google-oauth.json`) and its own `login`.
|
|
42
|
+
|
|
43
|
+
Clasp’s public OAuth client is Drive-only. Calendar and Gmail are restricted; Google blocks extra scopes on that app. Use **your** Desktop OAuth client.
|
|
44
|
+
|
|
45
|
+
## Agent: setup e2e
|
|
46
|
+
|
|
47
|
+
If `whoami` works but `meeting` / `mail` / `sheet set` fail with missing scope or “app is blocked”, run **this user** through `node scripts/setup.mjs google-workspace` (TTY). Do not reuse another person’s JSON. Do not invent a client JSON.
|
|
48
|
+
|
|
49
|
+
Local dir is created by setup (`~/.grunt/`, mode 700 on Unix). Manual equivalent: `mkdir -p "$HOME/.grunt" && chmod 700 "$HOME/.grunt"` then:
|
|
50
|
+
|
|
51
|
+
1. Open `https://console.cloud.google.com/projectcreate` — **Create**. Org can be their Workspace org. Note **Project ID** from the dashboard URL (`?project=`).
|
|
52
|
+
2. Open `https://console.cloud.google.com/auth/overview/create?project=PROJECT_ID` (or **Google Auth Platform → Branding**).
|
|
53
|
+
- App name: anything (`autorun` is fine). That string is only the Allow screen.
|
|
54
|
+
- User support email: their address.
|
|
55
|
+
- Audience: **Internal** if the Google account is a paid Workspace org (e.g. `@rearm.co`). **Testing** + add their own address as a test user if it is a personal `@gmail.com` (Internal is not offered). APIs work on both; only this consent type changes.
|
|
56
|
+
- Next / Create through the wizard.
|
|
57
|
+
3. Open `https://console.cloud.google.com/flows/enableapi?apiid=calendar-json.googleapis.com,gmail.googleapis.com,sheets.googleapis.com,docs.googleapis.com,drive.googleapis.com&project=PROJECT_ID` — **Enable**.
|
|
58
|
+
4. Open `https://console.cloud.google.com/auth/clients/create?project=PROJECT_ID`.
|
|
59
|
+
- Application type: **Desktop app**.
|
|
60
|
+
- Create → **Download JSON**.
|
|
61
|
+
5. Copy the download to `$HOME/.grunt/google-oauth.json` (Windows: `%USERPROFILE%\.grunt\google-oauth.json`). chmod 600 on Unix. Confirm it has `"installed"` and `client_id`. For `--account NAME`, use `$HOME/.grunt/workspace/NAME/google-oauth.json`.
|
|
62
|
+
6. From the repo: `node scripts/google-workspace.mjs login` (or `--account NAME`) — browser Allow. Tokens write beside the JSON (`workspace-tokens.json` or `workspace/NAME/tokens.json`).
|
|
63
|
+
7. Smoke:
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
node scripts/google-workspace.mjs whoami
|
|
67
|
+
node scripts/google-workspace.mjs scopes
|
|
68
|
+
node scripts/google-workspace.mjs sheet create --title smoke-sheet --csv "k,v\nok,1"
|
|
69
|
+
node scripts/google-workspace.mjs doc create --title smoke-doc --body ok
|
|
70
|
+
node scripts/google-workspace.mjs slide create --title smoke-slide
|
|
71
|
+
node scripts/google-workspace.mjs meeting create --title smoke-meeting --start 2026-09-16T09:00:00Z --end 2026-09-16T09:15:00Z
|
|
72
|
+
node scripts/google-workspace.mjs mail send --to THEIR_EMAIL --subject smoke --body ok
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
`scopes` must include `calendar`, `gmail.modify` or `gmail.send`, `spreadsheets`, `documents`, `drive`. If login times out, they did not finish Allow; re-run `login`.
|
|
76
|
+
|
|
77
|
+
If `google-oauth.json` is missing, `login` prints `setup: node scripts/setup.mjs google-workspace`. Prefer the handheld setup (it opens the Project ID URLs). Manual steps above still work.
|
|
78
|
+
|
|
79
|
+
`gcloud` on PATH is an alternate login (`gcloud auth application-default login` with the extra scopes). Still per person, still local.
|
|
@@ -6,20 +6,18 @@ tags: [hooks]
|
|
|
6
6
|
|
|
7
7
|
SessionStart: keep empty (token baseline). Do not inject context. Do not register a SessionStart hook on `../../.grok/hooks/orchestrate-parent.json`.
|
|
8
8
|
|
|
9
|
-
Grok PostToolUse /
|
|
9
|
+
Grok PostToolUse / SessionStart are observe-only — do not attempt output scrub; compress via RTK / spawn / isolation facts only. Do not add PostToolUse scrub hooks. Grok UserPromptSubmit may emit a one-line `sessionGate=auto|ask` plus session receipt (`hookSpecificOutput.additionalContext`). Skip host Stop banners. `/ask` exact-match slash stamps `session-gate-{sid}` to `ask`. `/auto` unlinks. Sid-less: no stamp. Default: `auto`.
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
In `sessionGate=ask`, parent Stop on `end_turn` blocks unless the recap asks (`?`) or is exactly `[orchestrator]: wait grunt`. Reason: `ask after this step`. Cap 3. `sessionGate=auto` does not Stop-block.
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
Claude / Codex / Antigravity PreToolUse still run `../../scripts/scrub-spawn-prompt.mjs` and `../../scripts/gate-fat-tools.mjs`. Grok spawn/fat rewrite is `../../.grok/hooks/orchestrate-parent.js`. RTK stays `../../.grok/hooks/rtk.json`.
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
Session agent tools are on. Fat Read/Grep/Glob/Bash still gate. Writes under `.tmp/grunt/plans/`, `.tmp/grunt/handoffs/`, `.tmp/grunt/implementations/`, and `.tmp/grunt/` root files persist via `../../scripts/persist-plan.mjs` / `persist-handoff.mjs` / `persist-implementation.mjs` / `persist-tmp.mjs`. Invalid body denies.
|
|
16
16
|
|
|
17
|
-
SubagentStop (and child Stop with `subagentType`) intercepts a parseable `need:` whose jobs are all `search|exec` (cap 4): runs grunt-job in-hook and continues the child with concatenated
|
|
17
|
+
SubagentStop (and child Stop with `subagentType`) intercepts a parseable `need:` whose jobs are all `search|exec|slice|fetch` (cap 4): runs grunt-job in-hook and continues the child with concatenated facts. Mixed/web/test, parse fail, FALLBACK, `stopHookActive`, or more than 3 intercepts per child session → empty stdout (allow stop).
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
Stop and SubagentStop timeout is 30s (grunt-job cap is 20s). PreToolUse / UserPromptSubmit stay at 5s.
|
|
20
20
|
|
|
21
|
-
rulesync canonical event is `beforeSubmitPrompt` (→ Claude/Codex `UserPromptSubmit`), not `userPromptSubmit
|
|
22
|
-
|
|
23
|
-
Stop and SubagentStop timeout is 30s (grunt-job cap is 20s). PreToolUse / PostToolUse / UserPromptSubmit stay at 5s. If the intercept times out, the hook fail-opens and the child stops without verdicts.
|
|
21
|
+
rulesync canonical event is `beforeSubmitPrompt` (→ Claude/Codex `UserPromptSubmit`), not `userPromptSubmit`.
|
|
24
22
|
|
|
25
23
|
`[features] two_pass_compaction` must live in `~/.grok/config.toml` (from `.grok/global-settings.toml` via `npm run sync:globals` / `npm run sync:globals:apply`). Project `.grok/config.toml` cannot set `[features]`.
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# Implementation format (SSOT)
|
|
2
|
+
|
|
3
|
+
Local session journal for `/implement-plan`. Not a plan, handoff, or git commit.
|
|
4
|
+
|
|
5
|
+
Created when `/implement-plan` starts. Straight shots skip this file. Do not merge into the plan (plan = flip the box only).
|
|
6
|
+
|
|
7
|
+
## Path
|
|
8
|
+
|
|
9
|
+
`.tmp/grunt/implementations/{serial}-{slug}-{YYYYMMDDTHHMMSSZ}.md`
|
|
10
|
+
|
|
11
|
+
- **serial:** own counter (not plan serials). Unpadded decimal int ≥ 1. Never `0001`.
|
|
12
|
+
- **filename:** unpadded serial, slug, UTC datetime stamp. Same regex as new plans: `^[0-9]+-[a-z0-9]+(-[a-z0-9]+)*-\d{8}T\d{6}Z\.md$`
|
|
13
|
+
- **lookup:** integer equality on leading digits.
|
|
14
|
+
- Frontmatter `serial:` line must match `^serial: [1-9][0-9]*$`.
|
|
15
|
+
- New writes always stamped. Collision: increment serial, same stamp.
|
|
16
|
+
|
|
17
|
+
## Link
|
|
18
|
+
|
|
19
|
+
Frontmatter `plan:` is the plan serial (`6`) or `none`. Own serial stays independent.
|
|
20
|
+
|
|
21
|
+
## Slugify / allocate
|
|
22
|
+
|
|
23
|
+
Same as plans (`slugify`, `nextSerial` on this dir). Body line 1: `IMPL_NAME: <3-6 word name>`. Optional `IMPL_PLAN: <n|none>` (default `none`).
|
|
24
|
+
|
|
25
|
+
## Frontmatter (required)
|
|
26
|
+
|
|
27
|
+
```yaml
|
|
28
|
+
---
|
|
29
|
+
serial: 1
|
|
30
|
+
plan: 6 # unpadded int or none
|
|
31
|
+
name: add-auth
|
|
32
|
+
status: in-progress # in-progress | done | blocked
|
|
33
|
+
created: 2026-08-26T14:30:00Z
|
|
34
|
+
source: "<≤120 chars of user task>"
|
|
35
|
+
---
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Status machine
|
|
39
|
+
|
|
40
|
+
`in-progress` → `done` | `blocked`
|
|
41
|
+
|
|
42
|
+
- Fresh write: `in-progress`
|
|
43
|
+
- Plan Verify done and journal caught up: `done`
|
|
44
|
+
- Cannot finish: `blocked` (`## Blockers` must not be `(none)`)
|
|
45
|
+
|
|
46
|
+
## Body headings (this order only)
|
|
47
|
+
|
|
48
|
+
`# {slug}`, `## Done`, `## Issue`, `## Files`, `## Log`, `## Blockers`, `## Notes`
|
|
49
|
+
|
|
50
|
+
No other `##` headings.
|
|
51
|
+
|
|
52
|
+
| Section | Amount |
|
|
53
|
+
|---|---|
|
|
54
|
+
| Done | bullets. What landed and why. Past tense. Fresh: `(none)` |
|
|
55
|
+
| Issue | bug root cause bullets, or `(none)` |
|
|
56
|
+
| Files | repo-relative product paths as `- path` bullets. Default `/commit` stage set. No abs paths. No `.tmp/`. Fresh: `(none)` |
|
|
57
|
+
| Log | append-only. Fresh: `(none)`. After each plan leaf: `N.M [x] one line` (notes, fail, skip). `[x]` allowed |
|
|
58
|
+
| Blockers | open problems. `(none)` unless `status: blocked` |
|
|
59
|
+
| Notes | short leftovers, or `(none)` |
|
|
60
|
+
|
|
61
|
+
## Write
|
|
62
|
+
|
|
63
|
+
Write under `.tmp/grunt/implementations/` (any filename in that dir). Grok `orchestrate-parent.js` runs `scripts/persist-implementation.mjs` on create (`IMPL_NAME:`): serial/slug from the name, injects frontmatter, rewrites path + content. Updates to an existing file keep the path; full-body writes are validated in place. Invalid create/update denies — fix the body, do not retry elsewhere.
|
|
64
|
+
|
|
65
|
+
Host without that hook: name the file per **Path**, or pipe the body to `node scripts/persist-implementation.mjs --workspace {repo}` and use its `path`.
|
|
66
|
+
|
|
67
|
+
Never allocate a new serial to log a leaf. Append Log, update Files/Done, flip the plan box.
|
|
68
|
+
|
|
69
|
+
## Validation checklist
|
|
70
|
+
|
|
71
|
+
- filename stamped unpadded; serial int equals leading digits; `name` equals slug
|
|
72
|
+
- frontmatter keys: `serial`, `plan`, `name`, `status`, `created`, `source`
|
|
73
|
+
- `plan` is `none` or unpadded int ≥ 1; `status` ∈ `in-progress` | `done` | `blocked`
|
|
74
|
+
- headings in order only; no extra `##`
|
|
75
|
+
- Done / Issue / Files / Log / Blockers / Notes: bullets and/or `(none)`; none of those sections empty
|
|
76
|
+
- Files: repo-relative; reject abs and `.tmp/`
|
|
77
|
+
- `status: blocked` ⇒ Blockers is not only `(none)`
|
|
78
|
+
|
|
79
|
+
## Worked example
|
|
80
|
+
|
|
81
|
+
File: `.tmp/grunt/implementations/1-add-tmp-ignore-20260826T143000Z.md`
|
|
82
|
+
|
|
83
|
+
```markdown
|
|
84
|
+
---
|
|
85
|
+
serial: 1
|
|
86
|
+
plan: 6
|
|
87
|
+
name: add-tmp-ignore
|
|
88
|
+
status: in-progress
|
|
89
|
+
created: 2026-08-26T14:30:00Z
|
|
90
|
+
source: "gitignore .tmp so local plans stay untracked"
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
# add-tmp-ignore
|
|
94
|
+
|
|
95
|
+
## Done
|
|
96
|
+
- Repo `.gitignore` ignores `.tmp/` so plans stay untracked
|
|
97
|
+
|
|
98
|
+
## Issue
|
|
99
|
+
(none)
|
|
100
|
+
|
|
101
|
+
## Files
|
|
102
|
+
- .gitignore
|
|
103
|
+
|
|
104
|
+
## Log
|
|
105
|
+
1.1 [x] read existing gitignore
|
|
106
|
+
1.2 [x] appended .tmp/
|
|
107
|
+
|
|
108
|
+
## Blockers
|
|
109
|
+
(none)
|
|
110
|
+
|
|
111
|
+
## Notes
|
|
112
|
+
(none)
|
|
113
|
+
```
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
# Law
|
|
2
2
|
|
|
3
|
-
Protocol stays
|
|
3
|
+
Protocol stays overview; domain fills this.
|
|
4
4
|
|
|
5
5
|
## Skills naming
|
|
6
6
|
|
|
7
|
-
Reserved (do not reuse in consumer custom skills): `browser` `
|
|
7
|
+
Reserved (do not reuse in consumer custom skills): `ask` `auto` `browser` `clasp` `commit` `commit-and-push` `commit-push` `commit-push-deploy` `commit-push-release` `explain` `google-workspace` `handoff` `implement-plan` `listen` `pickup` `speak` `tmp` `write-plan`.
|
|
8
8
|
|
|
9
|
-
Override: same name → one SSOT path (`.rulesync/skills/<name>/`). Re-init force-refresh overwrites grunt-owned names; consumer extras kept. Maps `origin` badge ≠ content picker.
|
|
9
|
+
Override: same name → one SSOT path (`.rulesync/skills/<name>/`). Re-init / `grunt upgrade` force-refresh overwrites grunt-owned names; consumer extras kept. Maps `origin` badge ≠ content picker.
|
|
10
|
+
|
|
11
|
+
Upgrade copies the current package trees and product scripts, then deletes cumulative retired grunt-owned names (skills `parent` `solo` `cascade`; agents `implementer` `thinker`; scripts `telemetry.mjs` `grunt-config.mjs`; paths `.grok/parent.md` `.grok/skills/shared` `.rulesync/grunt.config.jsonc` `.rulesync/grunt.config.local.jsonc` `.rulesync/grunt.config.local.jsonc.example`) and any reserved skill dir this package no longer ships. `fs.cpSync` does not remove dest extras; prune is what drops them. Consumer skills/refs/scripts not on those lists stay.
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
---
|
|
2
|
+
tags: [listen]
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Listen
|
|
6
|
+
|
|
7
|
+
Speech-to-text from the session. Input only. Not TTS. Not a live voice agent. Not MCP.
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
node scripts/listen.mjs whoami
|
|
11
|
+
node scripts/listen.mjs devices
|
|
12
|
+
node scripts/listen.mjs rec [--seconds 8] [--device D] [--clip]
|
|
13
|
+
node scripts/listen.mjs start [--device D]
|
|
14
|
+
node scripts/listen.mjs stop [--clip]
|
|
15
|
+
node scripts/listen.mjs toggle [--clip]
|
|
16
|
+
node scripts/listen.mjs status
|
|
17
|
+
node scripts/listen.mjs file --path clip.wav [--clip]
|
|
18
|
+
node scripts/listen.mjs latest
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
`rec` records then transcribes (default 8s, cap 120s). `toggle` is the hotkey verb: first run starts, second run stops and prints the transcript. Audio and `latest.txt` live under `.tmp/grunt/listen/`. `--cwd /path/to/repo` when the hotkey does not already run in the repo.
|
|
22
|
+
|
|
23
|
+
## Auth and capture
|
|
24
|
+
|
|
25
|
+
Handheld (any OS): `node scripts/setup.mjs listen` or `npm exec grunt setup` → listen. Prints OS install commands for ffmpeg / whisper-cli (does not run them), optional ggml download into `~/.grunt/whisper/`, OpenAI fallback key if local STT is missing.
|
|
26
|
+
|
|
27
|
+
If ffmpeg, whisper-cli, a ggml model, or `OPENAI_API_KEY` is missing, the CLI prints `setup: node scripts/setup.mjs listen` and exits 1. Agents should show that line, not a stack or JSON. Do not invent a key.
|
|
28
|
+
|
|
29
|
+
STT prefers **local whisper.cpp**. Install the binary; the first `listen` downloads `ggml-base.en.bin` (~142MB) into `~/.grunt/whisper/`. No API cost after that. If the binary or download is missing, it falls back to OpenAI `whisper-1` (`OPENAI_API_KEY` or `~/.grunt/speak.json`). Force with `LISTEN_STT=local` or `LISTEN_STT=openai`. Never commit keys.
|
|
30
|
+
|
|
31
|
+
| | env | `~/.grunt/speak.json` |
|
|
32
|
+
| --- | --- | --- |
|
|
33
|
+
| Local model | `WHISPER_MODEL` | `listen.whisperModel` |
|
|
34
|
+
| Force engine | `LISTEN_STT` | `listen.stt` (`auto` / `local` / `openai`) |
|
|
35
|
+
| OpenAI key | `OPENAI_API_KEY` | `openai.apiKey` |
|
|
36
|
+
| OpenAI model | `LISTEN_MODEL` | `listen.model` (default `whisper-1`) |
|
|
37
|
+
| Device | `LISTEN_DEVICE` | `listen.device` |
|
|
38
|
+
| Seconds | `LISTEN_SECONDS` | `listen.seconds` |
|
|
39
|
+
|
|
40
|
+
### Local Whisper (preferred)
|
|
41
|
+
|
|
42
|
+
One install:
|
|
43
|
+
|
|
44
|
+
- mac: `brew install whisper-cpp` (provides `whisper-cli`)
|
|
45
|
+
- linux: build https://github.com/ggml-org/whisper.cpp (`whisper-cli` on PATH)
|
|
46
|
+
- win: whisper.cpp release `whisper-cli.exe` on PATH
|
|
47
|
+
|
|
48
|
+
Then `node scripts/listen.mjs whoami` or `rec`. The first run fetches `ggml-base.en.bin` to `~/.grunt/whisper/`. Do not pip-install OpenAI Whisper. Do not curl the model yourself unless the auto-download fails.
|
|
49
|
+
|
|
50
|
+
Larger models: put another `ggml-*.bin` in that folder or set `WHISPER_MODEL`. Doctor reports `whisper-cli` as optional. `whoami` prints `stt=local` or `stt=openai`.
|
|
51
|
+
|
|
52
|
+
### ffmpeg (mic only)
|
|
53
|
+
|
|
54
|
+
- mac: `brew install ffmpeg`
|
|
55
|
+
- linux: `sudo apt install ffmpeg`
|
|
56
|
+
- win: `winget install Gyan.FFmpeg`
|
|
57
|
+
|
|
58
|
+
`file` and `latest` work without a mic. Doctor reports ffmpeg as optional.
|
|
59
|
+
|
|
60
|
+
`rec` detaches ffmpeg and does not attach it to the IDE TTY. AVFoundation can stall forever on a VS Code / Electron PTY even when Visual Studio Code already has Microphone access.
|
|
61
|
+
|
|
62
|
+
Default devices: mac `:0` (AVFoundation audio 0), linux Pulse `default` (ALSA if the id is `hw:…`), Windows requires `--device` or `LISTEN_DEVICE` from `listen devices`.
|
|
63
|
+
|
|
64
|
+
## Hotkeys
|
|
65
|
+
|
|
66
|
+
Bind one key to toggle. Include `--clip` so the transcript is on the clipboard as well as `latest.txt`.
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
node /ABS/grunt/scripts/listen.mjs toggle --clip --cwd /ABS/grunt
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Replace `/ABS/grunt` with the repo root.
|
|
73
|
+
|
|
74
|
+
- **mac:** Shortcuts (Run Shell Script) or skhd: `hyper - r : node /ABS/grunt/scripts/listen.mjs toggle --clip --cwd /ABS/grunt`
|
|
75
|
+
- **win:** PowerToys Keyboard Manager or AutoHotkey: `^!r:: Run, node C:\ABS\grunt\scripts\listen.mjs toggle --clip --cwd C:\ABS\grunt, C:\ABS\grunt, Hide`
|
|
76
|
+
- **linux:** desktop custom shortcut or sxhkd to the same command.
|
|
77
|
+
|
|
78
|
+
No daemon. Each keypress is one CLI. First press records; second press transcribes.
|
|
79
|
+
|
|
80
|
+
`--clip` uses `pbcopy` (mac), `clip` (win), or `wl-copy` / `xclip` / `xsel` (linux).
|