@lovrozagar/grunt 0.3.6 → 0.3.8

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,24 @@
1
+ ---
2
+ name: cascade
3
+ description: >
4
+ Session mode. /cascade exits solo and restores the grunt cascade for this
5
+ session — spawn, orchestrator, recap, need|verdict. Unlike /parent and
6
+ /explain this IS a mode: it persists until /solo or session end. Not a
7
+ sticky second mode — exit solo / restore cascade.
8
+ ---
9
+ Exit solo / restore cascade. Not a sticky second mode.
10
+
11
+ Session mode, not one-turn. Persists until `/solo` or session end.
12
+
13
+ This session: cascade restored. You are the parent orchestrator.
14
+
15
+ - Spawn grunt|implementer|thinker.
16
+ - Recap tags. Recap `[orchestrator]:` `[grunt]:` `[implementer]:` `[thinker]:` `[handoff]:`.
17
+ - Spawn-first rule. `need:`/`verdict:` grammar.
18
+ - Voice unchanged: `.rulesync/reference/output.md`. `/explain` is still the voice escape.
19
+
20
+ Fat-tool caps stay on — token guards, not cascade.
21
+
22
+ Claude/Codex/Grok: `/cascade` via submit hook unlinks `.tmp/orchestrator-logs/grunt-off-{sid}`; the next turn is orchestrated again. Already orchestrated: no-op. Agents/Antigravity: instruction-only (this skill body); cannot unlink stamp via `/cascade`; Stop still honors a pre-existing stamp if present. Session-scoped, never global.
23
+
24
+ After `/solo`, or when spawn/recap/need|verdict must resume.
@@ -0,0 +1,24 @@
1
+ ---
2
+ name: cascade
3
+ description: >
4
+ Session mode. /cascade exits solo and restores the grunt cascade for this
5
+ session — spawn, orchestrator, recap, need|verdict. Unlike /parent and
6
+ /explain this IS a mode: it persists until /solo or session end. Not a
7
+ sticky second mode — exit solo / restore cascade.
8
+ ---
9
+ Exit solo / restore cascade. Not a sticky second mode.
10
+
11
+ Session mode, not one-turn. Persists until `/solo` or session end.
12
+
13
+ This session: cascade restored. You are the parent orchestrator.
14
+
15
+ - Spawn grunt|implementer|thinker.
16
+ - Recap tags. Recap `[orchestrator]:` `[grunt]:` `[implementer]:` `[thinker]:` `[handoff]:`.
17
+ - Spawn-first rule. `need:`/`verdict:` grammar.
18
+ - Voice unchanged: `.rulesync/reference/output.md`. `/explain` is still the voice escape.
19
+
20
+ Fat-tool caps stay on — token guards, not cascade.
21
+
22
+ Claude/Codex/Grok: `/cascade` via submit hook unlinks `.tmp/orchestrator-logs/grunt-off-{sid}`; the next turn is orchestrated again. Already orchestrated: no-op. Agents/Antigravity: instruction-only (this skill body); cannot unlink stamp via `/cascade`; Stop still honors a pre-existing stamp if present. Session-scoped, never global.
23
+
24
+ After `/solo`, or when spawn/recap/need|verdict must resume.
@@ -0,0 +1,24 @@
1
+ ---
2
+ name: cascade
3
+ description: >
4
+ Session mode. /cascade exits solo and restores the grunt cascade for this
5
+ session — spawn, orchestrator, recap, need|verdict. Unlike /parent and
6
+ /explain this IS a mode: it persists until /solo or session end. Not a
7
+ sticky second mode — exit solo / restore cascade.
8
+ ---
9
+ Exit solo / restore cascade. Not a sticky second mode.
10
+
11
+ Session mode, not one-turn. Persists until `/solo` or session end.
12
+
13
+ This session: cascade restored. You are the parent orchestrator.
14
+
15
+ - Spawn grunt|implementer|thinker.
16
+ - Recap tags. Recap `[orchestrator]:` `[grunt]:` `[implementer]:` `[thinker]:` `[handoff]:`.
17
+ - Spawn-first rule. `need:`/`verdict:` grammar.
18
+ - Voice unchanged: `.rulesync/reference/output.md`. `/explain` is still the voice escape.
19
+
20
+ Fat-tool caps stay on — token guards, not cascade.
21
+
22
+ Claude/Codex/Grok: `/cascade` via submit hook unlinks `.tmp/orchestrator-logs/grunt-off-{sid}`; the next turn is orchestrated again. Already orchestrated: no-op. Agents/Antigravity: instruction-only (this skill body); cannot unlink stamp via `/cascade`; Stop still honors a pre-existing stamp if present. Session-scoped, never global.
23
+
24
+ After `/solo`, or when spawn/recap/need|verdict must resume.
@@ -23,13 +23,13 @@ Cheap outline. Not a file dump.
23
23
  - `.grok/hooks/orchestrate-parent.js` + `orchestrate-parent.json` — parent spawn/fat/stop/plan-write / SubagentStop intercept
24
24
  - `.grok/hooks/rtk.json` — RTK
25
25
  - `.grok/skills/{write-plan,implement-plan,shared}/` — hand-only (no rulesync SSOT); point to cascade, do not paste
26
- - `.grok/skills/{parent,explain,handoff,solo,commit,commit-and-push}/` — generated from `.rulesync/skills/`; do not hand-edit
26
+ - `.grok/skills/{parent,explain,handoff,solo,cascade,commit,commit-and-push}/` — generated from `.rulesync/skills/`; do not hand-edit
27
27
  - `.grok/parent.md` — 1-line pointer to orchestrator agent; not SessionStart
28
28
  - `.grok/roles/*.toml`
29
29
  - `.grok/global-settings.toml` — merged into `~/.grok/config.toml` by `scripts/sync-global-settings.mjs` (not auto-loaded; project config cannot set `[features]`)
30
30
  - `.rulesync/global-settings/` — host manifest and reserved noop payloads
31
31
  - `.rulesync/mcp-policy.jsonc` — MCP deny-default SSOT (`default: deny`, `allow: []`)
32
- - `.rulesync/skills/{parent,explain,handoff,solo,commit,commit-and-push}/` — skill SSOT; `rulesync -f skills` emits `.grok/skills/`, `.claude/skills/`, `.agents/skills/` byte-equal. `/cascade` has no skill (hook-only: a `grunt`-adjacent listing entry risks mis-routing `Skill` vs `Agent`)
32
+ - `.rulesync/skills/{parent,explain,handoff,solo,cascade,commit,commit-and-push}/` — skill SSOT; `rulesync -f skills` emits `.grok/skills/`, `.claude/skills/`, `.agents/skills/` byte-equal. `/cascade` = exit solo / restore cascade (not a sticky second mode)
33
33
 
34
34
  ## Scripts
35
35
  - `scripts/check-globals.mjs` — `$HOME/.grok/config.toml` `[agent].name==orchestrator` + `[features].two_pass_compaction==true`; project `.grok/config.toml` must not have `[features]`/`[agent]`; wired as `sync:globals:check` (also after emit-mcp in `rulesync:check`)
@@ -58,7 +58,7 @@ Cheap outline. Not a file dump.
58
58
 
59
59
  ## Generated (do not hand-edit; committed, not gitignored)
60
60
  - `AGENTS.md`, `CLAUDE.md`
61
- - `.claude/skills/*`, `.agents/skills/*`, `.grok/skills/{parent,explain,handoff,solo,commit,commit-and-push}/` (from `.rulesync/skills/`)
61
+ - `.claude/skills/*`, `.agents/skills/*`, `.grok/skills/{parent,explain,handoff,solo,cascade,commit,commit-and-push}/` (from `.rulesync/skills/`)
62
62
  - `.grok/agents/*`
63
63
  - `.claude/agents/*`
64
64
  - `.codex/agents/*`
@@ -0,0 +1,24 @@
1
+ ---
2
+ name: cascade
3
+ description: >
4
+ Session mode. /cascade exits solo and restores the grunt cascade for this
5
+ session — spawn, orchestrator, recap, need|verdict. Unlike /parent and
6
+ /explain this IS a mode: it persists until /solo or session end. Not a
7
+ sticky second mode — exit solo / restore cascade.
8
+ ---
9
+ Exit solo / restore cascade. Not a sticky second mode.
10
+
11
+ Session mode, not one-turn. Persists until `/solo` or session end.
12
+
13
+ This session: cascade restored. You are the parent orchestrator.
14
+
15
+ - Spawn grunt|implementer|thinker.
16
+ - Recap tags. Recap `[orchestrator]:` `[grunt]:` `[implementer]:` `[thinker]:` `[handoff]:`.
17
+ - Spawn-first rule. `need:`/`verdict:` grammar.
18
+ - Voice unchanged: `.rulesync/reference/output.md`. `/explain` is still the voice escape.
19
+
20
+ Fat-tool caps stay on — token guards, not cascade.
21
+
22
+ Claude/Codex/Grok: `/cascade` via submit hook unlinks `.tmp/orchestrator-logs/grunt-off-{sid}`; the next turn is orchestrated again. Already orchestrated: no-op. Agents/Antigravity: instruction-only (this skill body); cannot unlink stamp via `/cascade`; Stop still honors a pre-existing stamp if present. Session-scoped, never global.
23
+
24
+ After `/solo`, or when spawn/recap/need|verdict must resume.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lovrozagar/grunt",
3
- "version": "0.3.6",
3
+ "version": "0.3.8",
4
4
  "description": "Multi-agent orchestrator SoT — deep-merge rulesync trees, product scripts, and generate pipeline into a consumer repo",
5
5
  "keywords": [
6
6
  "agents",
@@ -8,8 +8,8 @@
8
8
  * Grok SessionStart stays empty on orchestrate-parent.json.
9
9
  *
10
10
  * Consumer extras (if those scripts exist): SessionStart, check-behind,
11
- * validate+sim, platform/** deny. Gemini: SessionStart + AfterTool only;
12
- * check-behind / path deny stay caveats.
11
+ * validate+sim. Path deny from consumer `.rulesync/permissions.json`.
12
+ * Gemini: SessionStart + AfterTool only; check-behind / path deny stay caveats.
13
13
  *
14
14
  * node scripts/hooks-union.mjs apply then check
15
15
  * node scripts/hooks-union.mjs --check keep-list only
@@ -40,7 +40,6 @@ export const AUTORUN_NEEDLES = [
40
40
  "sim.mjs",
41
41
  ];
42
42
  export const GRUNT_NEEDLES = ["scrub-spawn-prompt.mjs", "gate-fat-tools.mjs"];
43
- export const PLATFORM_DENY = ["Write(platform/**)", "Edit(platform/**)"];
44
43
  export const GIT_HOOKS = [
45
44
  "scripts/git-hooks/pre-commit",
46
45
  "scripts/git-hooks/pre-commit.mjs",
@@ -52,7 +51,7 @@ export const POST_WRITE_MATCHER = "Write|Edit|write|search_replace";
52
51
  const CAVEAT_BEHIND =
53
52
  "NOT ported: PreToolUse check-behind.mjs. Gemini has no confirmed before-tool deny event.";
54
53
  const CAVEAT_PERMS =
55
- "NOT ported: Write/Edit(platform/**). Gemini tool controls are name-scoped, not path-scoped.";
54
+ "path-scoped permissions.deny not ported; Gemini is name-scoped";
56
55
 
57
56
  export function parseArgv(argv) {
58
57
  const args = Array.isArray(argv) ? argv : [];
@@ -83,8 +82,13 @@ function hasScript(root, name) {
83
82
  return fs.existsSync(path.join(root, "scripts", name));
84
83
  }
85
84
 
86
- function hasPlatform(root) {
87
- return fs.existsSync(path.join(root, "platform"));
85
+ function withoutWritePath(arr) {
86
+ return arr.filter((x) => typeof x === "string" && !x.startsWith("Write("));
87
+ }
88
+
89
+ function loadConsumerDeny(root) {
90
+ const data = loadJson(path.join(root, ".rulesync/permissions.json"));
91
+ return Array.isArray(data.deny) ? withoutWritePath(data.deny) : [];
88
92
  }
89
93
 
90
94
  function presentAutorun(root) {
@@ -229,8 +233,11 @@ function applyClaude(root) {
229
233
  const post = desiredPost(root);
230
234
  if (post) hooks.PostToolUse = upsertGroups(hooks.PostToolUse, post);
231
235
  const permissions = isPlainObject(live.permissions) ? { ...live.permissions } : {};
232
- const deny = Array.isArray(permissions.deny) ? [...permissions.deny] : [];
233
- permissions.deny = hasPlatform(root) ? uniq([...deny, ...PLATFORM_DENY]) : deny;
236
+ const liveDeny = Array.isArray(permissions.deny) ? permissions.deny : [];
237
+ permissions.deny = uniq([
238
+ ...liveDeny.filter((x) => typeof x !== "string" || !x.startsWith("Write(")),
239
+ ...loadConsumerDeny(root),
240
+ ]);
234
241
  const next = { ...live, permissions, hooks };
235
242
  saveJson(abs, next);
236
243
  }
@@ -313,11 +320,7 @@ export function checkUnion(opts = {}) {
313
320
  {
314
321
  id: "claude",
315
322
  path: ".claude/settings.json",
316
- needles: [
317
- ...GRUNT_NEEDLES,
318
- ...autorun,
319
- ...(hasPlatform(root) ? PLATFORM_DENY : []),
320
- ],
323
+ needles: [...GRUNT_NEEDLES, ...autorun, ...loadConsumerDeny(root)],
321
324
  },
322
325
  {
323
326
  id: "codex",