@devrik-tools/claude-gates 0.4.0 → 0.7.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 (57) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/README.es.md +39 -4
  3. package/README.md +34 -5
  4. package/cli/config.mjs +126 -124
  5. package/cli/init.mjs +303 -276
  6. package/cli/install.mjs +281 -175
  7. package/cli/materialize.mjs +103 -102
  8. package/cli/registry.mjs +139 -136
  9. package/cli/smoke-fixtures.json +65 -0
  10. package/cli/task.mjs +140 -140
  11. package/package.json +1 -1
  12. package/plugins/gates/.claude-plugin/plugin.json +1 -1
  13. package/plugins/gates/hooks/ask-adoption.mjs +147 -147
  14. package/plugins/gates/hooks/doctor.mjs +207 -207
  15. package/plugins/gates/hooks/gates/atomic-commit/index.mjs +229 -0
  16. package/plugins/gates/hooks/gates/audit-before-build/index.mjs +110 -88
  17. package/plugins/gates/hooks/gates/autonomous-mode/index.mjs +50 -50
  18. package/plugins/gates/hooks/gates/bash-commands/index.mjs +215 -215
  19. package/plugins/gates/hooks/gates/brief-approved/index.mjs +216 -0
  20. package/plugins/gates/hooks/gates/brief-before-delegate/index.mjs +269 -265
  21. package/plugins/gates/hooks/gates/capability-map/index.mjs +701 -0
  22. package/plugins/gates/hooks/gates/circuit-breaker/index.mjs +527 -501
  23. package/plugins/gates/hooks/gates/diagnosis-before-patch/index.mjs +48 -43
  24. package/plugins/gates/hooks/gates/feature-catalog/index.mjs +83 -83
  25. package/plugins/gates/hooks/gates/force-parallel/index.mjs +134 -119
  26. package/plugins/gates/hooks/gates/forge-flow/index.mjs +134 -134
  27. package/plugins/gates/hooks/gates/implementation-pipeline/index.mjs +187 -187
  28. package/plugins/gates/hooks/gates/intent-flow/index.mjs +260 -260
  29. package/plugins/gates/hooks/gates/lint-commit/index.mjs +152 -149
  30. package/plugins/gates/hooks/gates/mandatory-flow/index.mjs +180 -180
  31. package/plugins/gates/hooks/gates/never-assume/index.mjs +59 -58
  32. package/plugins/gates/hooks/gates/no-blocking/index.mjs +163 -148
  33. package/plugins/gates/hooks/gates/no-coauthor/index.mjs +127 -0
  34. package/plugins/gates/hooks/gates/no-lint-suppression/index.mjs +183 -0
  35. package/plugins/gates/hooks/gates/protected-paths/index.mjs +149 -144
  36. package/plugins/gates/hooks/gates/recurrence-lock/index.mjs +91 -89
  37. package/plugins/gates/hooks/gates/reuse-before-build/index.mjs +263 -159
  38. package/plugins/gates/hooks/gates/risk-level/index.mjs +265 -263
  39. package/plugins/gates/hooks/gates/root-cause-first/index.mjs +57 -56
  40. package/plugins/gates/hooks/gates/root-whitelist/index.mjs +211 -131
  41. package/plugins/gates/hooks/gates/rule-skill-autodiscovery/index.mjs +181 -184
  42. package/plugins/gates/hooks/gates/sdd-specs/index.mjs +256 -256
  43. package/plugins/gates/hooks/gates/staged-lint/index.mjs +187 -0
  44. package/plugins/gates/hooks/gates/stop-pending/index.mjs +169 -164
  45. package/plugins/gates/hooks/gates/test-matrix/index.mjs +187 -187
  46. package/plugins/gates/hooks/gates/tool-map/index.mjs +168 -143
  47. package/plugins/gates/hooks/hooks.json +61 -0
  48. package/plugins/gates/hooks/lib/config.mjs +179 -172
  49. package/plugins/gates/hooks/lib/hook-io.mjs +367 -357
  50. package/plugins/gates/hooks/lib/signals.mjs +172 -127
  51. package/plugins/gates/hooks/wiring-check.mjs +227 -227
  52. package/plugins/tasks/.claude-plugin/plugin.json +1 -1
  53. package/plugins/tasks/hooks/hooks.json +26 -26
  54. package/plugins/tasks/hooks/lib/task-store.mjs +217 -197
  55. package/plugins/tasks/hooks/register-requests.mjs +145 -145
  56. package/plugins/tasks/hooks/session-tasks.mjs +108 -108
  57. package/registry.json +192 -1
package/registry.json CHANGED
@@ -293,6 +293,27 @@
293
293
  }
294
294
  ]
295
295
  },
296
+ {
297
+ "id": "brief-approved",
298
+ "configKey": "requireApprovedBriefBeforeImplementing",
299
+ "default": true,
300
+ "event": "PreToolUse",
301
+ "tools": ["delegation"],
302
+ "description": "Denies implementing a cited feature whose brief has no recorded user approval (status: approved + approval_quote frontmatter).",
303
+ "script": "gates/brief-approved/index.mjs",
304
+ "params": [
305
+ {
306
+ "name": "catalogLocations",
307
+ "type": "string[]",
308
+ "description": "Paths searched for the feature catalog."
309
+ },
310
+ {
311
+ "name": "exemptSubagents",
312
+ "type": "string[]",
313
+ "description": "Subagent types exempt from the approval requirement."
314
+ }
315
+ ]
316
+ },
296
317
  {
297
318
  "id": "implementation-pipeline",
298
319
  "configKey": "requireImplementationPipeline",
@@ -563,6 +584,115 @@
563
584
  "description": "Milliseconds allowed for the lint run before it counts as a failure."
564
585
  }
565
586
  ]
587
+ },
588
+ {
589
+ "id": "staged-lint",
590
+ "configKey": "blockCommitWithStagedLintErrors",
591
+ "default": false,
592
+ "event": "PreToolUse",
593
+ "tools": ["shell"],
594
+ "description": "Denies a git commit when the STAGED files fail lint — lints only what you staged, not the whole repo, so your change can't add new lint debt while pre-existing debt in untouched files never blocks you. Autodetects eslint; escape hatch [skip-lint].",
595
+ "script": "gates/staged-lint/index.mjs",
596
+ "params": [
597
+ {
598
+ "name": "lintCommand",
599
+ "type": "string",
600
+ "description": "Command to run; staged paths are appended. Default: autodetect npx eslint when an eslint config exists."
601
+ },
602
+ {
603
+ "name": "lintExtensions",
604
+ "type": "string[]",
605
+ "description": "Staged file extensions that get linted. Replaces the built-in list."
606
+ },
607
+ {
608
+ "name": "lintTimeoutMs",
609
+ "type": "number",
610
+ "description": "Milliseconds allowed for the lint run before it counts as a failure."
611
+ },
612
+ {
613
+ "name": "escapeHatch",
614
+ "type": "string",
615
+ "description": "Substring in the commit command that skips the check once. Default [skip-lint]."
616
+ }
617
+ ]
618
+ },
619
+ {
620
+ "id": "atomic-commit",
621
+ "configKey": "blockNonAtomicCommits",
622
+ "default": false,
623
+ "event": "PreToolUse",
624
+ "tools": ["shell"],
625
+ "description": "Denies a git commit that is not atomic: one mixing more than N distinct natures of change (code/tests/deps/config...) or staging more reviewable files than a commit should carry. Docs/assets/generated files are not counted. Escape hatch [wip] for one deliberately broad commit.",
626
+ "script": "gates/atomic-commit/index.mjs",
627
+ "params": [
628
+ {
629
+ "name": "maxFiles",
630
+ "type": "number",
631
+ "description": "Max counted (reviewable) files in one commit. Default 12."
632
+ },
633
+ {
634
+ "name": "maxNatures",
635
+ "type": "number",
636
+ "description": "Max distinct counted natures of change in one commit. Default 2."
637
+ },
638
+ {
639
+ "name": "escapeHatch",
640
+ "type": "string",
641
+ "description": "Substring in the commit command that allows one deliberately broad commit. Default [wip]."
642
+ },
643
+ {
644
+ "name": "natures",
645
+ "type": "string[]",
646
+ "description": "Classification table ({name, source, counts}) mapping a path to a nature. Replaces the built-in list."
647
+ }
648
+ ]
649
+ },
650
+ {
651
+ "id": "no-coauthor",
652
+ "configKey": "blockCoauthorTrailers",
653
+ "default": true,
654
+ "event": "PreToolUse",
655
+ "tools": ["shell", "delegation"],
656
+ "description": "Denies a git commit whose message carries an AI/agent attribution trailer (Co-Authored-By, Generated with, session trailer). Escape hatch marker allows one legitimate co-author.",
657
+ "script": "gates/no-coauthor/index.mjs",
658
+ "params": [
659
+ {
660
+ "name": "attributionPatterns",
661
+ "type": "string[]",
662
+ "description": "Regex sources of attribution trailers/phrases to deny. Replaces the built-in list."
663
+ },
664
+ {
665
+ "name": "escapeHatch",
666
+ "type": "string",
667
+ "description": "Substring in the command that allows one commit to keep a co-author. Default [allow-coauthor]."
668
+ }
669
+ ]
670
+ },
671
+ {
672
+ "id": "no-lint-suppression",
673
+ "configKey": "blockLintSuppression",
674
+ "default": true,
675
+ "event": "PreToolUse",
676
+ "tools": ["write"],
677
+ "description": "Denies a write that silences the linter/type-checker (inline disable directive, or a config rule set off) instead of fixing the code. Escape hatch marker on the same line allows a documented false positive.",
678
+ "script": "gates/no-lint-suppression/index.mjs",
679
+ "params": [
680
+ {
681
+ "name": "suppressionPatterns",
682
+ "type": "string[]",
683
+ "description": "Regex sources marking an inline suppression directive. Replaces the built-in list."
684
+ },
685
+ {
686
+ "name": "watchedConfigFiles",
687
+ "type": "string[]",
688
+ "description": "Config file basenames whose edits are scanned for rule-weakening. Replaces the built-in list."
689
+ },
690
+ {
691
+ "name": "escapeHatch",
692
+ "type": "string",
693
+ "description": "Substring on the same line as a suppression that allows it (a documented false positive). Default lint-ok:."
694
+ }
695
+ ]
566
696
  }
567
697
  ]
568
698
  },
@@ -577,13 +707,28 @@
577
707
  "default": false,
578
708
  "event": "PreToolUse",
579
709
  "tools": ["write", "delegation"],
580
- "description": "Consults the project tool map; blocks building a tool absent from it without an audit.",
710
+ "description": "Before building a tool/helper (by folder, name pattern, or extension), requires evidence the wheel was checked: an audit phrase, the tool's name already in the map (structural match), or a matching installed dependency. Covers helpers beyond scripts/hooks/tools/gates and Spanish build-intent.",
581
711
  "script": "gates/reuse-before-build/index.mjs",
582
712
  "params": [
583
713
  {
584
714
  "name": "toolMapFile",
585
715
  "type": "string",
586
716
  "description": "Path to the per-project tool map (default .ai/tool-map.json)."
717
+ },
718
+ {
719
+ "name": "toolFolders",
720
+ "type": "string[]",
721
+ "description": "Folder names marking a file as a tool/helper. Replaces the built-in list (scripts, hooks, tools, gates, lib, utils, helpers, composables, components, services...)."
722
+ },
723
+ {
724
+ "name": "toolNamePatterns",
725
+ "type": "string[]",
726
+ "description": "Regex sources; a new file whose basename matches any is treated as a helper regardless of folder (useX, XHelper, XUtil, XService...)."
727
+ },
728
+ {
729
+ "name": "toolExtensions",
730
+ "type": "string[]",
731
+ "description": "File extensions considered code that can reinvent a wheel."
587
732
  }
588
733
  ]
589
734
  },
@@ -698,6 +843,52 @@
698
843
  "tools": [],
699
844
  "description": "Warns when a registered hook is missing or a script is orphaned.",
700
845
  "script": "wiring-check.mjs"
846
+ },
847
+ {
848
+ "id": "capability-map",
849
+ "configKey": "injectCapabilityMap",
850
+ "default": true,
851
+ "event": "UserPromptSubmit",
852
+ "tools": [],
853
+ "description": "Injects the current catalog of the project's AI capabilities (skills, agents/subagents, commands) as compact context on every message, grouped by kind, read fresh from disk. Also persists it to .ai/capability-map.json like the tool map. Autosynced: it lists the directories, never a hardcoded copy. Never blocks.",
854
+ "script": "gates/capability-map/index.mjs",
855
+ "params": [
856
+ {
857
+ "name": "kinds",
858
+ "type": "string[]",
859
+ "description": "Which capability kinds to include: skills, agents, commands. Drop one to stop scanning it."
860
+ },
861
+ {
862
+ "name": "maxClauseChars",
863
+ "type": "number",
864
+ "description": "Hard cap on each entry's one-line blurb length. Default 90."
865
+ },
866
+ {
867
+ "name": "extraSkillsDirs",
868
+ "type": "string[]",
869
+ "description": "Extra skill roots (relative or absolute) scanned in addition to ~/.claude/skills and <project>/.claude/skills."
870
+ },
871
+ {
872
+ "name": "extraAgentsDirs",
873
+ "type": "string[]",
874
+ "description": "Extra agent roots scanned in addition to ~/.claude/agents and <project>/.claude/agents."
875
+ },
876
+ {
877
+ "name": "extraCommandsDirs",
878
+ "type": "string[]",
879
+ "description": "Extra command roots scanned in addition to ~/.claude/commands and <project>/.claude/commands."
880
+ },
881
+ {
882
+ "name": "persist",
883
+ "type": "boolean",
884
+ "description": "Whether to write the persisted map file. Default true."
885
+ },
886
+ {
887
+ "name": "mapFile",
888
+ "type": "string",
889
+ "description": "Path to the persisted capability map, relative to project root. Default .ai/capability-map.json."
890
+ }
891
+ ]
701
892
  }
702
893
  ]
703
894
  },