@lovrozagar/grunt 0.10.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. package/.agents/agents/orchestrator.md +1 -1
  2. package/.agents/hooks.json +2 -2
  3. package/.agents/skills/browser/SKILL.md +3 -3
  4. package/.agents/skills/clasp/SKILL.md +1 -1
  5. package/.agents/skills/explain/SKILL.md +1 -1
  6. package/.agents/skills/google-workspace/SKILL.md +3 -3
  7. package/.agents/skills/handoff/SKILL.md +2 -2
  8. package/.agents/skills/implement-plan/SKILL.md +2 -2
  9. package/.agents/skills/jev/SKILL.md +3 -3
  10. package/.agents/skills/listen/SKILL.md +3 -3
  11. package/.agents/skills/pickup/SKILL.md +1 -1
  12. package/.agents/skills/speak/SKILL.md +3 -3
  13. package/.agents/skills/tmp/SKILL.md +2 -2
  14. package/.agents/skills/write-plan/SKILL.md +4 -2
  15. package/.claude/agents/orchestrator.md +1 -1
  16. package/.claude/settings.json +3 -3
  17. package/.claude/skills/browser/SKILL.md +3 -3
  18. package/.claude/skills/clasp/SKILL.md +1 -1
  19. package/.claude/skills/explain/SKILL.md +1 -1
  20. package/.claude/skills/google-workspace/SKILL.md +3 -3
  21. package/.claude/skills/handoff/SKILL.md +2 -2
  22. package/.claude/skills/implement-plan/SKILL.md +2 -2
  23. package/.claude/skills/jev/SKILL.md +3 -3
  24. package/.claude/skills/listen/SKILL.md +3 -3
  25. package/.claude/skills/pickup/SKILL.md +1 -1
  26. package/.claude/skills/speak/SKILL.md +3 -3
  27. package/.claude/skills/tmp/SKILL.md +2 -2
  28. package/.claude/skills/write-plan/SKILL.md +4 -2
  29. package/.codex/agents/orchestrator.toml +1 -1
  30. package/.codex/hooks.json +3 -3
  31. package/.grok/agents/orchestrator.md +1 -1
  32. package/.grok/hooks/orchestrate-parent.js +9 -9
  33. package/.grok/skills/browser/SKILL.md +3 -3
  34. package/.grok/skills/clasp/SKILL.md +1 -1
  35. package/.grok/skills/explain/SKILL.md +1 -1
  36. package/.grok/skills/google-workspace/SKILL.md +3 -3
  37. package/.grok/skills/handoff/SKILL.md +2 -2
  38. package/.grok/skills/implement-plan/SKILL.md +2 -2
  39. package/.grok/skills/jev/SKILL.md +3 -3
  40. package/.grok/skills/listen/SKILL.md +3 -3
  41. package/.grok/skills/pickup/SKILL.md +1 -1
  42. package/.grok/skills/speak/SKILL.md +3 -3
  43. package/.grok/skills/tmp/SKILL.md +2 -2
  44. package/.grok/skills/write-plan/SKILL.md +4 -2
  45. package/.rulesync/hooks.jsonc +3 -3
  46. package/.rulesync/reference/INDEX.md +10 -10
  47. package/.rulesync/reference/browser.md +4 -4
  48. package/.rulesync/reference/cascade.md +2 -2
  49. package/.rulesync/reference/clasp.md +1 -1
  50. package/.rulesync/reference/google-workspace.md +29 -29
  51. package/.rulesync/reference/hooks.md +3 -3
  52. package/.rulesync/reference/implementation-format.md +2 -2
  53. package/.rulesync/reference/jev.md +3 -3
  54. package/.rulesync/reference/law.md +1 -1
  55. package/.rulesync/reference/listen.md +12 -12
  56. package/.rulesync/reference/map.md +25 -25
  57. package/.rulesync/reference/output.md +9 -1
  58. package/.rulesync/reference/refs-map.md +4 -4
  59. package/.rulesync/reference/rtk.md +1 -1
  60. package/.rulesync/reference/scope.md +12 -14
  61. package/.rulesync/reference/setup.md +7 -7
  62. package/.rulesync/reference/skills-map.md +5 -5
  63. package/.rulesync/reference/speak.md +6 -6
  64. package/.rulesync/rules/overview.md +9 -5
  65. package/{scripts → .rulesync/scripts}/doctor.mjs +2 -2
  66. package/{scripts → .rulesync/scripts}/feature-packs.mjs +1 -1
  67. package/{scripts → .rulesync/scripts}/folder-map.mjs +7 -3
  68. package/{scripts → .rulesync/scripts}/gate-fat-tools.mjs +3 -3
  69. package/{scripts → .rulesync/scripts}/google-workspace.mjs +2 -2
  70. package/{scripts → .rulesync/scripts}/grunt-job.mjs +2 -0
  71. package/{scripts → .rulesync/scripts}/guarded-md.mjs +10 -4
  72. package/{scripts → .rulesync/scripts}/hooks-union.mjs +13 -8
  73. package/{scripts → .rulesync/scripts}/jev.mjs +2 -2
  74. package/{scripts → .rulesync/scripts}/listen.mjs +6 -6
  75. package/{scripts → .rulesync/scripts}/pipeline.mjs +14 -14
  76. package/{scripts → .rulesync/scripts}/session-map.mjs +1 -1
  77. package/{scripts → .rulesync/scripts}/setup.mjs +4 -4
  78. package/{scripts → .rulesync/scripts}/speak.mjs +4 -4
  79. package/.rulesync/skills/browser/SKILL.md +3 -3
  80. package/.rulesync/skills/clasp/SKILL.md +1 -1
  81. package/.rulesync/skills/explain/SKILL.md +1 -1
  82. package/.rulesync/skills/google-workspace/SKILL.md +3 -3
  83. package/.rulesync/skills/handoff/SKILL.md +2 -2
  84. package/.rulesync/skills/implement-plan/SKILL.md +2 -2
  85. package/.rulesync/skills/jev/SKILL.md +3 -3
  86. package/.rulesync/skills/listen/SKILL.md +3 -3
  87. package/.rulesync/skills/pickup/SKILL.md +1 -1
  88. package/.rulesync/skills/speak/SKILL.md +3 -3
  89. package/.rulesync/skills/tmp/SKILL.md +2 -2
  90. package/.rulesync/skills/write-plan/SKILL.md +4 -2
  91. package/.rulesync/subagents/orchestrator.md +1 -1
  92. package/AGENTS.md +11 -5
  93. package/CHANGELOG.md +22 -0
  94. package/CLAUDE.md +2 -0
  95. package/README.md +23 -23
  96. package/cli/grunt.mjs +3 -3
  97. package/cli/grunt.test.ts +6 -6
  98. package/cli/init.mjs +64 -16
  99. package/cli/init.test.ts +310 -163
  100. package/cli/prompt.mjs +1 -1
  101. package/cli/self-update.mjs +1 -1
  102. package/package.json +15 -50
  103. /package/{scripts → .rulesync/scripts}/board.mjs +0 -0
  104. /package/{scripts → .rulesync/scripts}/browser.mjs +0 -0
  105. /package/{scripts → .rulesync/scripts}/check-globals.mjs +0 -0
  106. /package/{scripts → .rulesync/scripts}/emit-agent-shell-tools.mjs +0 -0
  107. /package/{scripts → .rulesync/scripts}/emit-gemini.mjs +0 -0
  108. /package/{scripts → .rulesync/scripts}/emit-maps.mjs +0 -0
  109. /package/{scripts → .rulesync/scripts}/emit-mcp-policy.mjs +0 -0
  110. /package/{scripts → .rulesync/scripts}/guarded-roots.mjs +0 -0
  111. /package/{scripts → .rulesync/scripts}/interactive.mjs +0 -0
  112. /package/{scripts → .rulesync/scripts}/jsonc.mjs +0 -0
  113. /package/{scripts → .rulesync/scripts}/package-manager.mjs +0 -0
  114. /package/{scripts → .rulesync/scripts}/parse-need.mjs +0 -0
  115. /package/{scripts → .rulesync/scripts}/persist-handoff.mjs +0 -0
  116. /package/{scripts → .rulesync/scripts}/persist-implementation.mjs +0 -0
  117. /package/{scripts → .rulesync/scripts}/persist-plan.mjs +0 -0
  118. /package/{scripts → .rulesync/scripts}/persist-tmp.mjs +0 -0
  119. /package/{scripts → .rulesync/scripts}/prompt.mjs +0 -0
  120. /package/{scripts → .rulesync/scripts}/purge-global-mcps.mjs +0 -0
  121. /package/{scripts → .rulesync/scripts}/scrub-spawn-prompt.mjs +0 -0
  122. /package/{scripts → .rulesync/scripts}/scrub-text +0 -0
  123. /package/{scripts → .rulesync/scripts}/scrub-text-lib.mjs +0 -0
  124. /package/{scripts → .rulesync/scripts}/skill-conflicts.mjs +0 -0
  125. /package/{scripts → .rulesync/scripts}/sync-global-settings.mjs +0 -0
package/cli/init.mjs CHANGED
@@ -7,7 +7,7 @@ import {
7
7
  findSkillContentConflicts,
8
8
  formatSkillConflictWarn,
9
9
  listSkillDirNames,
10
- } from "../scripts/skill-conflicts.mjs"
10
+ } from "../.rulesync/scripts/skill-conflicts.mjs"
11
11
  import {
12
12
  SENTINEL_BEGIN,
13
13
  extractGruntBody,
@@ -16,12 +16,12 @@ import {
16
16
  remergeGuardedRoots,
17
17
  withGuardedCheckInteriors,
18
18
  mergeReferenceMarkdown,
19
- } from "../scripts/guarded-md.mjs"
19
+ } from "../.rulesync/scripts/guarded-md.mjs"
20
20
  import {
21
21
  COMMANDS as PIPELINE_COMMANDS,
22
22
  PIPELINE_CONFIG_REL,
23
23
  inferPipelineSkip,
24
- } from "../scripts/pipeline.mjs"
24
+ } from "../.rulesync/scripts/pipeline.mjs"
25
25
  import {
26
26
  PACKAGE_MANAGERS,
27
27
  UNKNOWN_PACKAGE_MANAGER,
@@ -29,8 +29,8 @@ import {
29
29
  installArgs,
30
30
  isPackageManager,
31
31
  runScriptArgs,
32
- } from "../scripts/package-manager.mjs"
33
- import { LAW_REL, emitMaps } from "../scripts/emit-maps.mjs"
32
+ } from "../.rulesync/scripts/package-manager.mjs"
33
+ import { LAW_REL, emitMaps } from "../.rulesync/scripts/emit-maps.mjs"
34
34
  import {
35
35
  isUnselectedPackPath,
36
36
  resolvePackSelection,
@@ -38,7 +38,7 @@ import {
38
38
  unselectedRefNames,
39
39
  unselectedScriptNames,
40
40
  writePacks,
41
- } from "../scripts/feature-packs.mjs"
41
+ } from "../.rulesync/scripts/feature-packs.mjs"
42
42
 
43
43
  export {
44
44
  GUARDED_ROOT_FILES,
@@ -57,7 +57,7 @@ export {
57
57
  withGuardedCheckInteriors,
58
58
  extraH2Sections,
59
59
  mergeReferenceMarkdown,
60
- } from "../scripts/guarded-md.mjs"
60
+ } from "../.rulesync/scripts/guarded-md.mjs"
61
61
 
62
62
  const PKG_ROOT = path.join(path.dirname(fileURLToPath(import.meta.url)), "..")
63
63
 
@@ -102,12 +102,18 @@ export const PRODUCT_SCRIPTS = [
102
102
  ]
103
103
 
104
104
  const COPY_DIRS = [".rulesync", ".grok", ".codex", ".claude", ".agents"]
105
+ /** Product scripts home in the package and in consumers. */
106
+ export const SCRIPTS_REL = ".rulesync/scripts"
107
+ /** Pre-0.11 home. Grunt-owned names here move to SCRIPTS_REL on init/upgrade; consumer files stay. */
108
+ export const LEGACY_SCRIPTS_REL = "scripts"
109
+ /** Any of these in LEGACY_SCRIPTS_REL means grunt installed there before, so its product names are grunt's. */
110
+ const LEGACY_SCRIPTS_MARKERS = ["guarded-roots.mjs", "gate-fat-tools.mjs"]
105
111
  /** Generated on dest from the dest tree (grunt refs + consumer extras). Never stamp the package copies. */
106
112
  export const GENERATED_MAP_FILES = new Set(["INDEX.md", "skills-map.md", "refs-map.md"])
107
113
  const COPY_ROOT_IF_MISSING = [".mcp.json"]
108
114
  export const RETIRED_SKILLS = ["parent", "solo", "cascade"]
109
115
  export const RETIRED_AGENTS = ["implementer", "thinker"]
110
- /** Cumulative. Dest `scripts/<name>` deleted on init/upgrade even if no longer shipped. */
116
+ /** Cumulative. Dest `<SCRIPTS_REL|LEGACY_SCRIPTS_REL>/<name>` deleted on init/upgrade even if no longer shipped. */
111
117
  export const RETIRED_SCRIPTS = ["telemetry.mjs", "grunt-config.mjs"]
112
118
  /** Repo-relative paths grunt used to ship. Deleted on init/upgrade. Consumer extras elsewhere kept. */
113
119
  export const RETIRED_PATHS = [
@@ -238,13 +244,40 @@ export function pruneRetired(dest, { pkgRoot } = {}) {
238
244
  rmQuiet(path.join(root, ".grok", "roles", `${name}.toml`))
239
245
  }
240
246
  for (const name of RETIRED_SCRIPTS) {
241
- rmQuiet(path.join(root, "scripts", name))
247
+ rmQuiet(path.join(root, ...SCRIPTS_REL.split("/"), name))
248
+ rmQuiet(path.join(root, LEGACY_SCRIPTS_REL, name))
242
249
  }
243
250
  for (const rel of RETIRED_PATHS) {
244
251
  rmQuiet(path.join(root, ...rel.split("/")))
245
252
  }
246
253
  }
247
254
 
255
+ /** Drop grunt-owned names from the pre-0.11 root `scripts/`; remove the dir only when that leaves it empty. */
256
+ export function pruneLegacyScripts(dest) {
257
+ const dir = path.join(path.resolve(dest), LEGACY_SCRIPTS_REL)
258
+ if (!LEGACY_SCRIPTS_MARKERS.some((name) => fs.existsSync(path.join(dir, name)))) return
259
+ for (const name of PRODUCT_SCRIPTS) rmQuiet(path.join(dir, name))
260
+ if (fs.readdirSync(dir).length === 0) fs.rmdirSync(dir)
261
+ }
262
+
263
+ const LEGACY_SCRIPT_REF_RE = new RegExp(
264
+ `(^|[\\s"'\`=(]|\\./|\\}/)${LEGACY_SCRIPTS_REL}/(${PRODUCT_SCRIPTS.map(escapeRe).join("|")})(?![\\w.-])`,
265
+ "g",
266
+ )
267
+
268
+ /** Rewrite pre-0.11 `scripts/<grunt name>` command refs to SCRIPTS_REL. Consumer script refs stay. */
269
+ export function rewriteLegacyScriptRefs(text) {
270
+ return String(text).replace(LEGACY_SCRIPT_REF_RE, `$1${SCRIPTS_REL}/$2`)
271
+ }
272
+
273
+ function rewriteLegacyPipelineConfig(dest) {
274
+ const abs = path.join(dest, PIPELINE_CONFIG_REL)
275
+ if (!fs.existsSync(abs)) return
276
+ const text = fs.readFileSync(abs, "utf8")
277
+ const next = rewriteLegacyScriptRefs(text)
278
+ if (next !== text) fs.writeFileSync(abs, next)
279
+ }
280
+
248
281
  export function mergeGitignore(dest) {
249
282
  const gi = path.join(dest, ".gitignore")
250
283
  const text = fs.existsSync(gi) ? fs.readFileSync(gi, "utf8") : ""
@@ -478,7 +511,12 @@ export function mergePackageJson(dest, pkgRoot) {
478
511
  if (destPkg.name === "@lovrozagar/grunt") return
479
512
 
480
513
  const srcPkg = JSON.parse(fs.readFileSync(path.join(pkgRoot, "package.json"), "utf8"))
481
- destPkg.scripts = { ...(destPkg.scripts || {}) }
514
+ destPkg.scripts = Object.fromEntries(
515
+ Object.entries(destPkg.scripts || {}).map(([k, v]) => [
516
+ k,
517
+ typeof v === "string" ? rewriteLegacyScriptRefs(v) : v,
518
+ ]),
519
+ )
482
520
  const srcKeys = []
483
521
  for (const [k, v] of Object.entries(srcPkg.scripts || {})) {
484
522
  if (k === "test" || k.endsWith(":raw") || k in LAUNCH_SCRIPTS) continue
@@ -603,8 +641,10 @@ export function init(dest, { pkgRoot: pkgRootOpt, execFileSync: exec = execFileS
603
641
  const refSnap = self ? {} : snapshotReferenceDocs(dest)
604
642
  let destPipelineSrc = ""
605
643
  if (!self) {
606
- const destPipeline = path.join(dest, "scripts", "pipeline.mjs")
607
- if (fs.existsSync(destPipeline)) destPipelineSrc = fs.readFileSync(destPipeline, "utf8")
644
+ const destPipeline = [SCRIPTS_REL, LEGACY_SCRIPTS_REL]
645
+ .map((rel) => path.join(dest, ...rel.split("/"), "pipeline.mjs"))
646
+ .find((p) => fs.existsSync(p))
647
+ if (destPipeline) destPipelineSrc = rewriteLegacyScriptRefs(fs.readFileSync(destPipeline, "utf8"))
608
648
  }
609
649
 
610
650
  for (const dir of COPY_DIRS) {
@@ -616,7 +656,12 @@ export function init(dest, { pkgRoot: pkgRootOpt, execFileSync: exec = execFileS
616
656
  copyTree(src, d, (s) => path.basename(s) !== "settings.json" && allowPack(s))
617
657
  mergeClaudeSettings(dest, pkgRoot)
618
658
  } else if (dir === ".rulesync") {
619
- copyTree(src, d, (s) => !GENERATED_MAP_FILES.has(path.basename(s)) && allowPack(s))
659
+ const scriptsSrc = path.join(pkgRoot, ...SCRIPTS_REL.split("/"))
660
+ copyTree(
661
+ src,
662
+ d,
663
+ (s) => s !== scriptsSrc && !GENERATED_MAP_FILES.has(path.basename(s)) && allowPack(s),
664
+ )
620
665
  } else {
621
666
  copyTree(src, d, allowPack)
622
667
  }
@@ -628,21 +673,24 @@ export function init(dest, { pkgRoot: pkgRootOpt, execFileSync: exec = execFileS
628
673
  mergeGuardedMarkdown(dest, pkgRoot, file)
629
674
  }
630
675
 
631
- fs.mkdirSync(path.join(dest, "scripts"), { recursive: true })
676
+ const scriptsDest = path.join(dest, ...SCRIPTS_REL.split("/"))
677
+ fs.mkdirSync(scriptsDest, { recursive: true })
632
678
  const skipScripts = unselectedScriptNames(selected)
633
679
  for (const name of PRODUCT_SCRIPTS) {
634
680
  if (skipScripts.has(name)) continue
635
- const src = path.join(pkgRoot, "scripts", name)
636
- const d = path.join(dest, "scripts", name)
681
+ const src = path.join(pkgRoot, ...SCRIPTS_REL.split("/"), name)
682
+ const d = path.join(scriptsDest, name)
637
683
  if (samePath(src, d)) continue
638
684
  copyTree(src, d)
639
685
  }
686
+ if (!self) pruneLegacyScripts(dest)
640
687
 
641
688
  fs.mkdirSync(path.join(dest, ".tmp"), { recursive: true })
642
689
  mergeGitignore(dest)
643
690
 
644
691
  if (!self) {
645
692
  remergeReferenceDocs(dest, refSnap, pkgRoot, unselectedRefNames(selected))
693
+ rewriteLegacyPipelineConfig(dest)
646
694
  seedPipelineConfig(dest, destPipelineSrc)
647
695
  mergePackageJson(dest, pkgRoot)
648
696
  copyRootIfMissing(dest, pkgRoot)