@lovrozagar/grunt 0.6.2 → 0.8.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.
@@ -0,0 +1,11 @@
1
+ ---
2
+ name: su
3
+ description: 'Short status update: done, next, and blockers or on-track ETA.'
4
+ ---
5
+ This reply only: a status update in two to four short lines. No process narration.
6
+
7
+ - Done: what is finished. Flag anything unverified.
8
+ - Next: the immediate next step.
9
+ - Health: if stuck, blocked, broken, or slipping, say so plainly. Otherwise "On track" with a rough ETA (minutes, ~1h, end of session).
10
+
11
+ Never soften bad news or claim progress not made.
@@ -73,6 +73,17 @@
73
73
  }
74
74
  ]
75
75
  }
76
+ ],
77
+ "SessionStart": [
78
+ {
79
+ "hooks": [
80
+ {
81
+ "type": "command",
82
+ "command": "node \"${GROK_WORKSPACE_ROOT:-${CLAUDE_PROJECT_DIR:-.}}/scripts/session-map.mjs\"",
83
+ "timeout": 5
84
+ }
85
+ ]
86
+ }
76
87
  ]
77
88
  },
78
89
  "enableAllProjectMcpServers": false,
@@ -0,0 +1,11 @@
1
+ ---
2
+ name: su
3
+ description: 'Short status update: done, next, and blockers or on-track ETA.'
4
+ ---
5
+ This reply only: a status update in two to four short lines. No process narration.
6
+
7
+ - Done: what is finished. Flag anything unverified.
8
+ - Next: the immediate next step.
9
+ - Health: if stuck, blocked, broken, or slipping, say so plainly. Otherwise "On track" with a rough ETA (minutes, ~1h, end of session).
10
+
11
+ Never soften bad news or claim progress not made.
package/.codex/hooks.json CHANGED
@@ -64,6 +64,17 @@
64
64
  }
65
65
  ]
66
66
  }
67
+ ],
68
+ "SessionStart": [
69
+ {
70
+ "hooks": [
71
+ {
72
+ "type": "command",
73
+ "command": "node \"${GROK_WORKSPACE_ROOT:-${CLAUDE_PROJECT_DIR:-.}}/scripts/session-map.mjs\"",
74
+ "timeout": 5
75
+ }
76
+ ]
77
+ }
67
78
  ]
68
79
  }
69
80
  }
@@ -87,7 +87,6 @@ function preToolUse(data) {
87
87
  });
88
88
  return 0;
89
89
  }
90
- emit({ decision: "allow" });
91
90
  return 0;
92
91
  }
93
92
  if (WRITE_TOOLS.has(toolKey)) {
@@ -96,7 +95,6 @@ function preToolUse(data) {
96
95
  }
97
96
  const fatCode = emitFat(data);
98
97
  if (fatCode !== null) return fatCode;
99
- emit({ decision: "allow" });
100
98
  return 0;
101
99
  }
102
100
 
@@ -162,7 +160,7 @@ export function isUnderTmp(filePath, workspaceRoot) {
162
160
 
163
161
  function parentWrite(data, toolInput) {
164
162
  if (!toolInput || typeof toolInput !== "object" || Array.isArray(toolInput)) {
165
- emit({ decision: "deny", reason: DENY_REASON });
163
+ emit(denyResponse(DENY_REASON));
166
164
  return 0;
167
165
  }
168
166
  const ws = workspaceRootOf(data);
@@ -200,7 +198,7 @@ function parentWrite(data, toolInput) {
200
198
  if (!isFullImplementationBody(content)) return null;
201
199
  const errors = validateImplementation(path.basename(abs), content);
202
200
  if (errors.length) {
203
- emit({ decision: "deny", reason: errors.join("; ") || invalid });
201
+ emit(denyResponse(errors.join("; ") || invalid));
204
202
  return 0;
205
203
  }
206
204
  const next = Object.assign({}, toolInput, {
@@ -224,10 +222,7 @@ function parentWrite(data, toolInput) {
224
222
  const content = typeof toolInput.content === "string" ? toolInput.content : "";
225
223
  const result = persist({ workspaceRoot: ws, content });
226
224
  if (!result.ok) {
227
- emit({
228
- decision: "deny",
229
- reason: result.error || invalid,
230
- });
225
+ emit(denyResponse(result.error || invalid));
231
226
  return 0;
232
227
  }
233
228
  const next = Object.assign({}, toolInput, {
@@ -0,0 +1,11 @@
1
+ ---
2
+ name: su
3
+ description: 'Short status update: done, next, and blockers or on-track ETA.'
4
+ ---
5
+ This reply only: a status update in two to four short lines. No process narration.
6
+
7
+ - Done: what is finished. Flag anything unverified.
8
+ - Next: the immediate next step.
9
+ - Health: if stuck, blocked, broken, or slipping, say so plainly. Otherwise "On track" with a rough ETA (minutes, ~1h, end of session).
10
+
11
+ Never soften bad news or claim progress not made.
@@ -25,6 +25,14 @@
25
25
  "timeout": 5
26
26
  }
27
27
  ],
28
+ "sessionStart": [
29
+ {
30
+ // Code-only folder map as additionalContext (hooks-union keeps it first).
31
+ "type": "command",
32
+ "command": "node \"${GROK_WORKSPACE_ROOT:-${CLAUDE_PROJECT_DIR:-.}}/scripts/session-map.mjs\"",
33
+ "timeout": 5
34
+ }
35
+ ],
28
36
  "beforeSubmitPrompt": [
29
37
  {
30
38
  "type": "command",
@@ -6,7 +6,7 @@ Protocol stays overview; domain fills this.
6
6
 
7
7
  ## Skills naming
8
8
 
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`.
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` `su` `tmp` `write-plan`.
10
10
 
11
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
12
 
@@ -32,6 +32,7 @@ Upgrade copies the current package trees and product scripts, then deletes cumul
32
32
  | listen | local | Speech-to-text via node scripts/listen.mjs (ffmpeg mic + local whisper.cpp, OpenAI fallback). Input only. | | | |
33
33
  | pickup | local | Continue a handoff under .tmp/grunt/handoffs/. | | | |
34
34
  | speak | local | Text-to-speech via node scripts/speak.mjs (ElevenLabs or OpenAI). Output only. | | | |
35
+ | su | local | Short status update: done, next, and blockers or on-track ETA. | | | |
35
36
  | tmp | local | Dump a one-off convo artifact under .tmp/grunt/. | | | |
36
37
  | write-plan | local | Write a local checklist under .tmp/grunt/plans/. Then /implement-plan {n}. | | | |
37
38
 
@@ -43,7 +44,7 @@ Upgrade copies the current package trees and product scripts, then deletes cumul
43
44
  | .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
45
  | .rulesync/reference/clasp.md | Clasp | clasp | Low-level Apps Script CLI. Optional. Doctor reports it. |
45
46
  | .rulesync/reference/google-workspace.md | google-workspace | google-workspace | Create and edit Google Sheets, Docs, Slides, Calendar events, and Gmail from the session. |
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… |
47
+ | .rulesync/reference/hooks.md | Hooks | hooks | SessionStart carries only the folder map: Claude / Codex run `../../scripts/session-map.mjs`, which injects the code-on… |
47
48
  | .rulesync/reference/implementation-format.md | Implementation format (SSOT) | | Local session journal for `/implement-plan`. Not a plan, handoff, or git commit. |
48
49
  | .rulesync/reference/law.md | Law | | Protocol stays overview; domain fills this. |
49
50
  | .rulesync/reference/listen.md | Listen | listen | Speech-to-text from the session. Input only. Not TTS. Not a live voice agent. Not MCP. |
@@ -4,7 +4,7 @@ tags: [hooks]
4
4
 
5
5
  # Hooks
6
6
 
7
- SessionStart: keep empty (token baseline). Do not inject context. Do not register a SessionStart hook on `../../.grok/hooks/orchestrate-parent.json`.
7
+ SessionStart carries only the folder map: Claude / Codex run `../../scripts/session-map.mjs`, which injects the code-only map from `../../scripts/folder-map.mjs` as `additionalContext` (budget 5k tokens, cache-stable, fail-open) and logs `{rows, tokens}` to `.tmp/grunt/sessions/<sid>/map.json`. Inject nothing else at SessionStart. Antigravity has no rulesync sessionStart. Do not register a SessionStart hook on `../../.grok/hooks/orchestrate-parent.json`.
8
8
 
9
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
 
@@ -4,7 +4,7 @@ Protocol stays overview; domain fills this.
4
4
 
5
5
  ## Skills naming
6
6
 
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`.
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` `su` `tmp` `write-plan`.
8
8
 
9
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
10
 
@@ -8,7 +8,7 @@
8
8
  | .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… |
9
9
  | .rulesync/reference/clasp.md | Clasp | clasp | Low-level Apps Script CLI. Optional. Doctor reports it. |
10
10
  | .rulesync/reference/google-workspace.md | google-workspace | google-workspace | Create and edit Google Sheets, Docs, Slides, Calendar events, and Gmail from the session. |
11
- | .rulesync/reference/hooks.md | Hooks | hooks | SessionStart: keep empty (token baseline). Do not inject context. Do not register a SessionStart hook on `../../.grok/h… |
11
+ | .rulesync/reference/hooks.md | Hooks | hooks | SessionStart carries only the folder map: Claude / Codex run `../../scripts/session-map.mjs`, which injects the code-on… |
12
12
  | .rulesync/reference/implementation-format.md | Implementation format (SSOT) | | Local session journal for `/implement-plan`. Not a plan, handoff, or git commit. |
13
13
  | .rulesync/reference/law.md | Law | | Protocol stays overview; domain fills this. |
14
14
  | .rulesync/reference/listen.md | Listen | listen | Speech-to-text from the session. Input only. Not TTS. Not a live voice agent. Not MCP. |
@@ -20,5 +20,6 @@
20
20
  | listen | local | Speech-to-text via node scripts/listen.mjs (ffmpeg mic + local whisper.cpp, OpenAI fallback). Input only. | | | |
21
21
  | pickup | local | Continue a handoff under .tmp/grunt/handoffs/. | | | |
22
22
  | speak | local | Text-to-speech via node scripts/speak.mjs (ElevenLabs or OpenAI). Output only. | | | |
23
+ | su | local | Short status update: done, next, and blockers or on-track ETA. | | | |
23
24
  | tmp | local | Dump a one-off convo artifact under .tmp/grunt/. | | | |
24
25
  | write-plan | local | Write a local checklist under .tmp/grunt/plans/. Then /implement-plan {n}. | | | |
@@ -12,8 +12,10 @@ You are the session agent. Do the work. Use en-US unless asked. Write concise co
12
12
 
13
13
  Size first. Straight shot: do it. Else read `.rulesync/reference/scope.md`.
14
14
  Default `/auto`: keep going; ask on blockers. `/ask`: one step, then ask.
15
+ Ask before destructive git (stash, reset, checkout, restore, clean, rebase, push -f); others share the tree. In a loop, skip it and edit code instead.
15
16
 
16
17
  Read `.rulesync/reference/INDEX.md` once. When a row matches the work, read that reference in full.
18
+ Use the folder map in session context to find code. Run `node scripts/folder-map.mjs <dir>` for depth before `ls` or `find`.
17
19
 
18
20
  Large dumps are compressed (search, test logs, snaps). Scratch and dumps live in `.tmp/grunt/` (gitignored). After a write, recap the path; edit with an offset slice when you need lines.
19
21
  Fat dumps: `node scripts/grunt-job.mjs --job search|exec|slice|fetch|test` first; spawn grunt only when the dump needs judgment.
@@ -0,0 +1,11 @@
1
+ ---
2
+ name: su
3
+ description: "Short status update: done, next, and blockers or on-track ETA."
4
+ ---
5
+ This reply only: a status update in two to four short lines. No process narration.
6
+
7
+ - Done: what is finished. Flag anything unverified.
8
+ - Next: the immediate next step.
9
+ - Health: if stuck, blocked, broken, or slipping, say so plainly. Otherwise "On track" with a rough ETA (minutes, ~1h, end of session).
10
+
11
+ Never soften bad news or claim progress not made.
package/AGENTS.md CHANGED
@@ -3,8 +3,10 @@ You are the session agent. Do the work. Use en-US unless asked. Write concise co
3
3
 
4
4
  Size first. Straight shot: do it. Else read `.rulesync/reference/scope.md`.
5
5
  Default `/auto`: keep going; ask on blockers. `/ask`: one step, then ask.
6
+ Ask before destructive git (stash, reset, checkout, restore, clean, rebase, push -f); others share the tree. In a loop, skip it and edit code instead.
6
7
 
7
8
  Read `.rulesync/reference/INDEX.md` once. When a row matches the work, read that reference in full.
9
+ Use the folder map in session context to find code. Run `node scripts/folder-map.mjs <dir>` for depth before `ls` or `find`.
8
10
 
9
11
  Large dumps are compressed (search, test logs, snaps). Scratch and dumps live in `.tmp/grunt/` (gitignored). After a write, recap the path; edit with an offset slice when you need lines.
10
12
  Fat dumps: `node scripts/grunt-job.mjs --job search|exec|slice|fetch|test` first; spawn grunt only when the dump needs judgment.
package/CHANGELOG.md CHANGED
@@ -7,6 +7,34 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.8.0] - 2026-10-03
11
+
12
+ ### Added
13
+
14
+ - `grunt map [dir]` / `node scripts/folder-map.mjs [dir]`: code-only folder map (folders only, git-tracked, gitignore applied). Package rows show name and full path; pass-through chains collapse; 12+ leaf dirs fold; 5k-token breadth-first budget with fair share; depth cap counts from package roots. Optional `.rulesync/grunt.map.jsonc`
15
+ - Claude / Codex SessionStart hook `scripts/session-map.mjs` injects the folder map and logs `{rows, tokens}` per session
16
+ - `/su` skill: short status update (done, next, blockers or on-track ETA)
17
+ - Root rule: ask before destructive git; in a loop, skip it and edit code instead
18
+
19
+ ### Fixed
20
+
21
+ - PreToolUse hooks no longer print top-level `decision: "allow"` / `"deny"`, which Claude rejected on every tool call; allow is empty stdout and deny is `block` plus `permissionDecision: "deny"`, so denies are enforced
22
+ - Fat-tool gate no longer rewrites compound shell (`|`, `;`, `&&`, heredocs) into grunt-job, which never ran them; rewritten queries are single-quoted so backticks and `$` stay literal
23
+ - Re-init replaces a grunt-owned SessionStart group instead of duplicating it
24
+
25
+ ## [0.7.0] - 2026-09-30
26
+
27
+ ### Added
28
+
29
+ - Package manager detection for init/generate/check/doctor/setup: lockfile or `package.json` `"packageManager"`, then how grunt was launched, then TTY ask. `--pm npm|yarn|pnpm|bun` overrides. Non-interactive with no signal fails instead of assuming npm.
30
+
31
+ ### Fixed
32
+
33
+ - Init no longer forces `npm install` / `npm run`
34
+ - Init keeps `@lovrozagar/grunt` in `devDependencies` (moves it out of `dependencies` when present; adds it when missing)
35
+ - Init INDEX/skills-map/refs-map are generated from the dest tree (grunt refs plus consumer extras) instead of copying the package maps
36
+ - Init writes root `.mcp.json` when dest is missing it
37
+
10
38
  ## [0.6.2] - 2026-09-17
11
39
 
12
40
  ### Changed
package/README.md CHANGED
@@ -23,23 +23,26 @@ OSS drop-in; merges existing configs; switches default provider flow to Grunt.
23
23
  ## Install
24
24
 
25
25
  - Node.js 22+
26
- - Consumer:
26
+ - Consumer (devDependency; init moves it there if it landed in `dependencies`):
27
27
 
28
28
  ```
29
- npm i -D @lovrozagar/grunt
30
- npm exec grunt
29
+ npm i -D @lovrozagar/grunt && npm exec grunt
30
+ pnpm add -D @lovrozagar/grunt && pnpm exec grunt
31
+ yarn add -D @lovrozagar/grunt && yarn grunt
32
+ bun add -D @lovrozagar/grunt && bunx grunt
31
33
  ```
32
34
 
33
- - Same as `npm exec grunt init` when no command
34
- - Do not `npm test` as a consumer
35
- - Package: `@lovrozagar/grunt` `0.6.0` MIT · https://github.com/lovrozagar/grunt
35
+ - Same as `grunt init` when no command
36
+ - Do not run this package's test script as a consumer
37
+ - Package: `@lovrozagar/grunt` MIT · https://github.com/lovrozagar/grunt
38
+ - Package manager: lockfile or `package.json` `"packageManager"`, then how grunt was launched, then TTY ask. `--pm npm|yarn|pnpm|bun` overrides. Non-interactive with no signal fails (does not assume npm).
36
39
 
37
40
  ## Prerequisites
38
41
 
39
42
  All OS. Print-only. Never auto-install.
40
43
 
41
44
  ```
42
- npm exec grunt doctor
45
+ grunt doctor
43
46
  node scripts/doctor.mjs
44
47
  ```
45
48
 
@@ -47,7 +50,8 @@ Exit 1 if any required missing; 0 if all required ok. Optional tools are reporte
47
50
 
48
51
  | tool | required | install |
49
52
  | --- | --- | --- |
50
- | node ≥22 + npm | yes | https://nodejs.org (≥22) · nvm / OS pkg · win `winget install OpenJS.NodeJS.LTS` |
53
+ | node ≥22 | yes | https://nodejs.org (≥22) · nvm / OS pkg · win `winget install OpenJS.NodeJS.LTS` |
54
+ | package manager | yes | npm (ships with Node ≥22) · yarn/pnpm `corepack enable` · bun https://bun.sh · detected from the repo, else how grunt was launched |
51
55
  | git | yes | linux `sudo apt install git` · mac `brew install git` · win `winget install Git.Git` |
52
56
  | rtk | yes | linux/mac `curl -fsSL https://raw.githubusercontent.com/rtk-ai/rtk/master/install.sh \| sh` or `brew install rtk` · win release zip `rtk.exe` on PATH or WSL curl ([docs](https://www.rtk-ai.app/docs/getting-started/installation/)) |
53
57
  | rulesync | yes | `npm i -D rulesync` / npx (PATH or npx-able) |
@@ -61,7 +65,7 @@ Exit 1 if any required missing; 0 if all required ok. Optional tools are reporte
61
65
  | whisper-cli | no | local STT for `/listen` · mac `brew install whisper-cpp` · first listen downloads `ggml-base.en.bin` · setup in `.rulesync/reference/listen.md` |
62
66
  | listen | no | `node scripts/listen.mjs` · STT input · `grunt setup` / `node scripts/setup.mjs listen` · local whisper.cpp then OpenAI Whisper |
63
67
 
64
- Rulesync schema doctor is separate: `npm run grunt:rulesync:doctor`.
68
+ Rulesync schema doctor is separate: `grunt:rulesync:doctor` (or SoT `rulesync:doctor`).
65
69
 
66
70
  ## Usage
67
71
 
@@ -73,14 +77,15 @@ Rulesync schema doctor is separate: `npm run grunt:rulesync:doctor`.
73
77
 
74
78
  ### Commands
75
79
 
76
- - `init` → `init()` — merge SoT, `npm install`, `grunt:rulesync:generate`, `grunt:sync:globals:apply`, `grunt:rulesync:check`
77
- - `generate` → `npm run grunt:rulesync:generate`
78
- - `check` → `npm run grunt:rulesync:check`
79
- - `sync-globals` → `npm run grunt:sync:globals` (dry-run); `--apply` → `grunt:sync:globals:apply`
80
- - `purge-mcps` → `npm run grunt:purge:global-mcps` (dry-run); `--apply` → `grunt:purge:global-mcps:apply`
81
- - `doctor` → `npm run grunt:doctor` (`npm exec grunt doctor` / `node scripts/doctor.mjs` stay). Rulesync schema: `npm run grunt:rulesync:doctor`
82
- - `setup` → `npm run grunt:setup` (`node scripts/setup.mjs`) — handheld speak / listen / google-workspace / browser. TTY walks each; flags for non-TTY keys/`--creds`
80
+ - `init` → `init()` — merge SoT, install, `grunt:rulesync:generate`, `grunt:sync:globals:apply`, `grunt:rulesync:check`
81
+ - `generate` → run `grunt:rulesync:generate`
82
+ - `check` → run `grunt:rulesync:check`
83
+ - `sync-globals` → run `grunt:sync:globals` (dry-run); `--apply` → `grunt:sync:globals:apply`
84
+ - `purge-mcps` → run `grunt:purge:global-mcps` (dry-run); `--apply` → `grunt:purge:global-mcps:apply`
85
+ - `doctor` → run `grunt:doctor` (`grunt doctor` / `node scripts/doctor.mjs` stay). Rulesync schema: `grunt:rulesync:doctor`
86
+ - `setup` → run `grunt:setup` (`node scripts/setup.mjs`) — handheld speak / listen / google-workspace / browser. TTY walks each; flags for non-TTY keys/`--creds`
83
87
  - `upgrade` → same merge as init for an already-inited repo: copy owned trees/scripts, prune retired grunt-owned names, print reserved skill names
88
+ - `map [dir]` → code-only folder map (`scripts/folder-map.mjs`); no package manager needed. See [Folder map](#folder-map)
84
89
  - `help`
85
90
  - `version`
86
91
 
@@ -90,25 +95,31 @@ Rulesync schema doctor is separate: `npm run grunt:rulesync:doctor`.
90
95
  - `--yes` / `-y` / `--non-interactive` — no TTY menu; default command still `init`. Not `--apply`
91
96
  - `--apply` — write for `sync-globals` / `purge-mcps`
92
97
  - `--host <id>` — `sync-globals --host <id>`
98
+ - `--pm <name>` — `npm` | `yarn` | `pnpm` | `bun`
93
99
 
94
100
  ## Init
95
101
 
96
- - Merge SoT `npm install` `grunt:rulesync:generate` `grunt:sync:globals:apply` `grunt:rulesync:check`
102
+ - Merge SoT, install with the detected package manager, `grunt:rulesync:generate` `grunt:sync:globals:apply` `grunt:rulesync:check`
103
+ - `@lovrozagar/grunt` is a consumer devDependency. Init moves it out of `dependencies` when it is there, and adds it when missing.
104
+ - INDEX / skills-map / refs-map are generated from the dest `.rulesync` tree (grunt files plus consumer extras). Package copies of those maps are not stamped over dest.
105
+ - Root `.mcp.json` is created when missing; generate still merges from `.rulesync/mcp-policy.jsonc`.
97
106
  - `--skip-globals` skips apply
98
107
  - TTY init asks `Apply global prompt optimizations? (recommended)` (default Yes; `--skip-globals` defaults No)
99
108
  - Non-interactive re-init auto-skips globals when `<!-- grunt:begin -->` in `AGENTS.md`/`CLAUDE.md`
100
109
  - First init (no sentinel) applies globals unless flagged
101
110
  - Owned trees/scripts refresh; extra `.rulesync` files kept; patches to grunt-owned files lost
102
111
  - `cp` cannot delete dest extras. Init/upgrade then prune: retired skills `parent` `solo` `cascade`, agents `implementer` `thinker` (plus `.grok/roles/{implementer,thinker}.toml` and `.gemini/agents/{name}/`), scripts `telemetry.mjs` `grunt-config.mjs`, paths `.grok/parent.md` `.grok/skills/shared` `.rulesync/grunt.config.jsonc` plus local overlay and example, and reserved skill dirs this package no longer ships. Consumer extras stay.
103
- - Breaking: consumer npm scripts are `grunt:<SoT-key>` (`grunt:rulesync:generate`, `grunt:doctor`). Re-init migrates `package.json` (owned unprefixed keys + suffixes; `npm run` refs in other dest scripts). CI/husky/`npm run rulesync:*` / `npm run doctor` must switch. No aliases. SoT repo scripts stay unprefixed (`npm run rulesync:generate`).
112
+ - Breaking: consumer scripts are `grunt:<SoT-key>` (`grunt:rulesync:generate`, `grunt:doctor`). Re-init migrates `package.json` (owned unprefixed keys + suffixes; `npm|yarn|pnpm|bun run` refs in other dest scripts). CI/husky/`run rulesync:*` / `run doctor` must switch. No aliases. SoT repo scripts stay unprefixed (`rulesync:generate`).
104
113
 
105
114
  ## Version bump
106
115
 
107
116
  Already-inited consumer (0.5.x → 0.6, and later):
108
117
 
109
118
  ```
110
- npm i -D @lovrozagar/grunt@latest
111
- npm exec grunt upgrade
119
+ npm i -D @lovrozagar/grunt@latest && npm exec grunt upgrade
120
+ pnpm add -D @lovrozagar/grunt@latest && pnpm exec grunt upgrade
121
+ yarn add -D @lovrozagar/grunt@latest && yarn grunt upgrade
122
+ bun add -D @lovrozagar/grunt@latest && bunx grunt upgrade
112
123
  ```
113
124
 
114
125
  `upgrade` is init plus a reserved-names print. Same merge, prune, and globals-skip rules as Init. New skills/scripts appear because they are in the package copy list. Dropped grunt-owned files disappear only if they are on the retired lists (or a reserved skill this package no longer ships). Do not expect a blind dest-dir mirror-delete; that would wipe consumer extras.
@@ -134,7 +145,7 @@ Lightpanda-first session CLI: `node scripts/browser.mjs`. Zero MCP. Zero env kno
134
145
 
135
146
  Present under `.claude` / `.rulesync` / `.agents` / `.grok` (`rulesync -f skills` mirrors SSOT):
136
147
 
137
- - `ask` `auto` `browser` `clasp` `commit` `commit-and-push` (1-release alias → `commit-push`) `commit-push` `commit-push-deploy` `commit-push-release` `explain` `google-workspace` `handoff` `implement-plan` `listen` `pickup` `speak` `tmp` `write-plan`
148
+ - `ask` `auto` `browser` `clasp` `commit` `commit-and-push` (1-release alias → `commit-push`) `commit-push` `commit-push-deploy` `commit-push-release` `explain` `google-workspace` `handoff` `implement-plan` `listen` `pickup` `speak` `su` `tmp` `write-plan`
138
149
 
139
150
  `/auto` (default) keeps going and asks on blockers. `/ask` finishes one step, recaps, then asks. `/auto` returns the session to auto.
140
151
 
@@ -155,7 +166,7 @@ Pipeline (no `-t geminicli`):
155
166
  3. `emit-gemini.mjs` — `GEMINI.md` `.gemini/agents/{id}/agent.md` MCP `.gemini/settings.json`
156
167
  4. `emit-agent-shell-tools` — Claude grunt body `Bash`; other hosts `run_terminal_command` (hooks-union)
157
168
 
158
- `check` = rulesync check. `doctor` = unified prereqs. Schema: `npm run rulesync:doctor`.
169
+ `check` = rulesync check. `doctor` = unified prereqs. Schema: `rulesync:doctor`.
159
170
 
160
171
  Emit writes other-CLI trees from `.rulesync` for the **next** process of that CLI. Not a live hop into another host.
161
172
 
@@ -166,11 +177,34 @@ Emit writes other-CLI trees from `.rulesync` for the **next** process of that CL
166
177
  - `sync-globals` / `purge-mcps`: dry-run default; `--apply` writes
167
178
  - Hosts: grok claude codex gemini antigravity
168
179
 
180
+ ### Folder map
181
+
182
+ Claude and Codex get a folder map at SessionStart (`scripts/session-map.mjs`), so agents skip `ls`/`find` loops. Agents run `node scripts/folder-map.mjs <dir>` (same as `grunt map <dir>`) for depth. Grok and Antigravity get the `AGENTS.md` line only.
183
+
184
+ - Folders only, never files. Source: `git ls-files --cached --others --exclude-standard`, so gitignored paths never show
185
+ - A folder shows when it or a descendant holds a code file (`codeExt`) and no path segment is a dot dir or in `skip`
186
+ - Package roots (`package.json`, `go.mod`, `Cargo.toml`, `pyproject.toml`) show `# name repo/relative/path`
187
+ - Pass-through single-child chains collapse (`a/b/c/`). 12+ plain leaf dirs under one parent fold into one row
188
+ - Budget (chars ÷ 4): breadth-first per top-level subtree; on overflow, cheapest subtrees first with an equal share; cut dirs end in `…` (the header names the command). Depth cap counts from the nearest package root
189
+ - Size per session: `.tmp/grunt/sessions/<sid>/map.json`
190
+
191
+ Optional `.rulesync/grunt.map.jsonc` (missing or invalid → defaults):
192
+
193
+ | key | default | |
194
+ |---|---|---|
195
+ | `budget` | `5000` | tokens |
196
+ | `depthCap` | `6` | levels below a package root |
197
+ | `foldAt` | `12` | leaf dirs before folding |
198
+ | `codeExt` | `ts tsx js jsx mjs cjs py go rs sql vue svelte astro` | |
199
+ | `skip` | `_gen gen generated dist build assets static public fixtures __fixtures__ __snapshots__ __mocks__ testdata vendor migrations locales i18n` | segment names |
200
+ | `include` | `[]` | globs always shown (`*` one segment, `**` any) |
201
+ | `exclude` | `[]` | globs never shown |
202
+
169
203
  ### Secrets (machine)
170
204
 
171
205
  Not git. Not `sync-globals`.
172
206
 
173
- First-hand: `npm exec grunt setup` (TTY). Per target: `node scripts/setup.mjs speak|listen|google-workspace|browser`. Spec: `.rulesync/reference/setup.md`.
207
+ First-hand: `grunt setup` (TTY). Per target: `node scripts/setup.mjs speak|listen|google-workspace|browser`. Spec: `.rulesync/reference/setup.md`.
174
208
 
175
209
  | | where |
176
210
  | --- | --- |