@lovrozagar/grunt 0.3.6 → 0.3.7

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lovrozagar/grunt",
3
- "version": "0.3.6",
3
+ "version": "0.3.7",
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",