claude-dev-env 1.0.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 (215) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +219 -0
  3. package/agents/agent-writer.md +157 -0
  4. package/agents/clasp-deployment-orchestrator.md +609 -0
  5. package/agents/clean-coder.md +295 -0
  6. package/agents/code-quality-agent.md +40 -0
  7. package/agents/code-standards-agent.md +93 -0
  8. package/agents/config-centralizer.md +686 -0
  9. package/agents/config-extraction-agent.md +225 -0
  10. package/agents/doc-orchestrator.md +47 -0
  11. package/agents/docs-agent.md +112 -0
  12. package/agents/docx-agent.md +211 -0
  13. package/agents/git-commit-crafter.md +100 -0
  14. package/agents/magic-value-eliminator-agent.md +72 -0
  15. package/agents/mandatory-agent-workflow-agent.md +88 -0
  16. package/agents/parallel-workflow-coordinator.md +779 -0
  17. package/agents/pdf-agent.md +302 -0
  18. package/agents/plan-executor.md +226 -0
  19. package/agents/pr-description-writer.md +87 -0
  20. package/agents/project-context-loader.md +238 -0
  21. package/agents/project-docs-analyzer.md +54 -0
  22. package/agents/project-structure-organizer-agent.md +72 -0
  23. package/agents/readability-review-agent.md +76 -0
  24. package/agents/refactoring-specialist.md +69 -0
  25. package/agents/right-sized-engineer.md +129 -0
  26. package/agents/session-continuity-manager.md +53 -0
  27. package/agents/skill-to-agent-converter.md +371 -0
  28. package/agents/skill-writer-agent.md +470 -0
  29. package/agents/stub-detector-agent.md +140 -0
  30. package/agents/tdd-test-writer.md +62 -0
  31. package/agents/test-data-builder.md +68 -0
  32. package/agents/tooling-builder.md +78 -0
  33. package/agents/user-docs-writer.md +67 -0
  34. package/agents/validation-expert.md +71 -0
  35. package/agents/workflow-visual-documenter.md +82 -0
  36. package/agents/xlsx-agent.md +169 -0
  37. package/bin/install.mjs +256 -0
  38. package/commands/commit.md +28 -0
  39. package/commands/docupdate.md +322 -0
  40. package/commands/implement.md +102 -0
  41. package/commands/initialize.md +91 -0
  42. package/commands/plan.md +63 -0
  43. package/commands/pr-comments.md +47 -0
  44. package/commands/readability-review.md +20 -0
  45. package/commands/review-plan.md +7 -0
  46. package/commands/right-size.md +15 -0
  47. package/commands/stubcheck.md +89 -0
  48. package/commands/sum.md +30 -0
  49. package/docs/CODE_RULES.md +186 -0
  50. package/docs/DJANGO_PATTERNS.md +80 -0
  51. package/docs/REACT_PATTERNS.md +185 -0
  52. package/docs/TEST_QUALITY.md +104 -0
  53. package/hooks/advisory/migration-safety-advisor.py +49 -0
  54. package/hooks/advisory/refactor-guard.py +205 -0
  55. package/hooks/blocking/block-main-commit.py +168 -0
  56. package/hooks/blocking/code-rules-enforcer.py +549 -0
  57. package/hooks/blocking/destructive-command-blocker.py +107 -0
  58. package/hooks/blocking/docker-settings-guard.py +44 -0
  59. package/hooks/blocking/hedging-language-blocker.py +130 -0
  60. package/hooks/blocking/parallel-task-blocker.py +69 -0
  61. package/hooks/blocking/pr-description-enforcer.py +87 -0
  62. package/hooks/blocking/pyautogui-scroll-blocker.py +74 -0
  63. package/hooks/blocking/sensitive-file-protector.py +70 -0
  64. package/hooks/blocking/tdd-enforcer.py +62 -0
  65. package/hooks/blocking/test-preflight-check.py +343 -0
  66. package/hooks/blocking/write-existing-file-blocker.py +63 -0
  67. package/hooks/git-hooks/post-commit.py +103 -0
  68. package/hooks/github-action/test_workflow.py +33 -0
  69. package/hooks/hooks.json +246 -0
  70. package/hooks/lifecycle/config-change-guard.py +84 -0
  71. package/hooks/lifecycle/session-end-cleanup.py +59 -0
  72. package/hooks/notification/attention-needed-notify.py +63 -0
  73. package/hooks/notification/claude-notification-handler.py +59 -0
  74. package/hooks/notification/notification_utils.py +206 -0
  75. package/hooks/rewrite-plugin-paths.py +116 -0
  76. package/hooks/session/bulk-edit-reminder.py +30 -0
  77. package/hooks/session/code-rules-reminder.py +97 -0
  78. package/hooks/session/compact-context-reinject.py +39 -0
  79. package/hooks/session/hook-structure-context.py +140 -0
  80. package/hooks/session/plugin-data-dir-cleanup.py +39 -0
  81. package/hooks/validation/code-style-validator.py +145 -0
  82. package/hooks/validation/e2e-test-validator.py +142 -0
  83. package/hooks/validation/hook-format-validator.py +66 -0
  84. package/hooks/validation/mypy_validator.py +180 -0
  85. package/hooks/validators/README.md +125 -0
  86. package/hooks/validators/VALIDATION_REPORT.md +287 -0
  87. package/hooks/validators/__init__.py +19 -0
  88. package/hooks/validators/abbreviation_checks.py +82 -0
  89. package/hooks/validators/code_quality_checks.py +133 -0
  90. package/hooks/validators/comment_checks.py +188 -0
  91. package/hooks/validators/file_structure_checks.py +182 -0
  92. package/hooks/validators/git_checks.py +107 -0
  93. package/hooks/validators/health_check.py +214 -0
  94. package/hooks/validators/magic_value_checks.py +81 -0
  95. package/hooks/validators/mypy_integration.py +52 -0
  96. package/hooks/validators/output_formatter.py +266 -0
  97. package/hooks/validators/pr_reference_checks.py +72 -0
  98. package/hooks/validators/python_antipattern_checks.py +110 -0
  99. package/hooks/validators/python_style_checks.py +364 -0
  100. package/hooks/validators/react_checks.py +90 -0
  101. package/hooks/validators/ruff_integration.py +80 -0
  102. package/hooks/validators/run_all_validators.py +772 -0
  103. package/hooks/validators/security_checks.py +135 -0
  104. package/hooks/validators/test_abbreviation_checks.py +76 -0
  105. package/hooks/validators/test_bad.tsx +7 -0
  106. package/hooks/validators/test_code_quality_checks.py +129 -0
  107. package/hooks/validators/test_file_structure_checks.py +307 -0
  108. package/hooks/validators/test_files/01_basic_component.tsx +10 -0
  109. package/hooks/validators/test_files/02_component_without_react.tsx +10 -0
  110. package/hooks/validators/test_files/03_pure_component.tsx +10 -0
  111. package/hooks/validators/test_files/04_pure_component_import.tsx +10 -0
  112. package/hooks/validators/test_files/05_typescript_generics.tsx +14 -0
  113. package/hooks/validators/test_files/06_typescript_two_generics.tsx +18 -0
  114. package/hooks/validators/test_files/07_multiline_declaration.tsx +11 -0
  115. package/hooks/validators/test_files/08_error_boundary_valid.tsx +14 -0
  116. package/hooks/validators/test_files/09_error_boundary_with_other_class.tsx +20 -0
  117. package/hooks/validators/test_files/10_inheritance_chain.tsx +16 -0
  118. package/hooks/validators/test_files/11_ts_file.ts +10 -0
  119. package/hooks/validators/test_files/12_non_react_class.tsx +14 -0
  120. package/hooks/validators/test_files/13_functional_component.tsx +8 -0
  121. package/hooks/validators/test_files/14_indented_class.tsx +13 -0
  122. package/hooks/validators/test_files/15_getDerivedStateFromError.tsx +14 -0
  123. package/hooks/validators/test_files/16_mixed_components.tsx +20 -0
  124. package/hooks/validators/test_files/EXECUTIVE_SUMMARY.md +175 -0
  125. package/hooks/validators/test_files/TEST_RESULTS_TABLE.txt +60 -0
  126. package/hooks/validators/test_files/VALIDATION_REPORT.md +201 -0
  127. package/hooks/validators/test_files/async_views.py +23 -0
  128. package/hooks/validators/test_files/async_with_imports.py +14 -0
  129. package/hooks/validators/test_files/bad_inline_imports.py +37 -0
  130. package/hooks/validators/test_files/management/commands/cmd_01_no_debug_check.py +10 -0
  131. package/hooks/validators/test_files/management/commands/cmd_02_proper_debug_check.py +14 -0
  132. package/hooks/validators/test_files/management/commands/cmd_03_debug_check_with_return.py +14 -0
  133. package/hooks/validators/test_files/management/commands/cmd_04_imported_DEBUG.py +14 -0
  134. package/hooks/validators/test_files/management/commands/cmd_05_debug_check_in_helper.py +16 -0
  135. package/hooks/validators/test_files/management/commands/cmd_06_debug_check_late.py +22 -0
  136. package/hooks/validators/test_files/management/commands/cmd_07_positive_debug_check.py +15 -0
  137. package/hooks/validators/test_files/management/commands/cmd_08_debug_with_and.py +14 -0
  138. package/hooks/validators/test_files/not_management_command.py +10 -0
  139. package/hooks/validators/test_files/skip_decorators/test_01_simple_skip.py +8 -0
  140. package/hooks/validators/test_files/skip_decorators/test_02_pytest_skipif.py +8 -0
  141. package/hooks/validators/test_files/skip_decorators/test_03_unittest_skipIf.py +8 -0
  142. package/hooks/validators/test_files/skip_decorators/test_04_skip_with_parens.py +8 -0
  143. package/hooks/validators/test_files/skip_decorators/test_05_xfail.py +7 -0
  144. package/hooks/validators/test_files/skip_decorators/test_06_custom_skip.py +11 -0
  145. package/hooks/validators/test_files/skip_decorators/test_07_capital_Skip.py +8 -0
  146. package/hooks/validators/test_files/skip_decorators/test_08_skipUnless.py +7 -0
  147. package/hooks/validators/test_files/skip_decorators/test_09_pytest_mark_skip_simple.py +7 -0
  148. package/hooks/validators/test_files/test_async_functions.py +45 -0
  149. package/hooks/validators/test_files/test_purecomponent/PureComponentExample.tsx +7 -0
  150. package/hooks/validators/test_files/test_purecomponent/ReactPureComponentExample.tsx +7 -0
  151. package/hooks/validators/test_git_checks.py +295 -0
  152. package/hooks/validators/test_good.tsx +5 -0
  153. package/hooks/validators/test_health_check.py +57 -0
  154. package/hooks/validators/test_magic_value_checks.py +63 -0
  155. package/hooks/validators/test_mypy_integration.py +27 -0
  156. package/hooks/validators/test_output_formatter.py +150 -0
  157. package/hooks/validators/test_pr_reference_checks.py +41 -0
  158. package/hooks/validators/test_python_antipattern_checks.py +113 -0
  159. package/hooks/validators/test_python_style_checks.py +439 -0
  160. package/hooks/validators/test_react_checks.py +213 -0
  161. package/hooks/validators/test_results.txt +25 -0
  162. package/hooks/validators/test_ruff_integration.py +27 -0
  163. package/hooks/validators/test_run_all_validators.py +228 -0
  164. package/hooks/validators/test_run_all_validators_integration.py +48 -0
  165. package/hooks/validators/test_safety_checks.py +243 -0
  166. package/hooks/validators/test_security_checks.py +105 -0
  167. package/hooks/validators/test_test_safety_checks.py +321 -0
  168. package/hooks/validators/test_todo_checks.py +39 -0
  169. package/hooks/validators/test_type_safety_checks.py +85 -0
  170. package/hooks/validators/test_useless_test_checks.py +55 -0
  171. package/hooks/validators/test_validator_base.py +26 -0
  172. package/hooks/validators/test_verify_paths.py +34 -0
  173. package/hooks/validators/todo_checks.py +59 -0
  174. package/hooks/validators/type_safety_checks.py +101 -0
  175. package/hooks/validators/useless_test_checks.py +92 -0
  176. package/hooks/validators/validator_base.py +19 -0
  177. package/hooks/validators/verify_paths.py +57 -0
  178. package/hooks/workflow/auto-formatter.py +114 -0
  179. package/hooks/workflow/investigation-tracker-reset.py +46 -0
  180. package/package.json +30 -0
  181. package/rules/agent-spawn-protocol.md +47 -0
  182. package/rules/cleanup-temp-files.md +27 -0
  183. package/rules/code-reviews.md +11 -0
  184. package/rules/code-standards.md +43 -0
  185. package/rules/conservative-action.md +20 -0
  186. package/rules/context7.md +12 -0
  187. package/rules/explore-thoroughly.md +27 -0
  188. package/rules/git-workflow.md +42 -0
  189. package/rules/parallel-tools.md +23 -0
  190. package/rules/research-mode.md +23 -0
  191. package/rules/right-sized-engineering.md +28 -0
  192. package/rules/tdd.md +7 -0
  193. package/rules/testing.md +12 -0
  194. package/skills/agent-prompt/SKILL.md +102 -0
  195. package/skills/anthropic-plan/SKILL.md +107 -0
  196. package/skills/everything-search/SKILL.md +144 -0
  197. package/skills/ingest/SKILL.md +40 -0
  198. package/skills/npm-creator/SKILL.md +183 -0
  199. package/skills/pr-review-responder/EXAMPLES.md +590 -0
  200. package/skills/pr-review-responder/PRINCIPLES.md +539 -0
  201. package/skills/pr-review-responder/README.md +209 -0
  202. package/skills/pr-review-responder/SKILL.md +202 -0
  203. package/skills/pr-review-responder/TESTING.md +407 -0
  204. package/skills/pr-review-responder/scripts/respond_to_reviews.py +376 -0
  205. package/skills/pr-review-responder/update_skill.py +297 -0
  206. package/skills/prompt-generator/REFERENCE.md +150 -0
  207. package/skills/prompt-generator/SKILL.md +154 -0
  208. package/skills/readability-review/SKILL.md +127 -0
  209. package/skills/recall/SKILL.md +27 -0
  210. package/skills/remember/SKILL.md +63 -0
  211. package/skills/rule-audit/SKILL.md +307 -0
  212. package/skills/rule-creator/SKILL.md +150 -0
  213. package/skills/skill-writer/REFERENCE.md +246 -0
  214. package/skills/skill-writer/SKILL.md +270 -0
  215. package/skills/tdd-team/SKILL.md +128 -0
@@ -0,0 +1,101 @@
1
+ """Type safety checks validator.
2
+
3
+ Implements:
4
+ - Check 39: Missing type hints on functions
5
+ - Check 40: Any type usage
6
+ """
7
+
8
+ import ast
9
+ import sys
10
+ from pathlib import Path
11
+ from typing import List
12
+
13
+ from validator_base import Violation
14
+
15
+
16
+ def check_missing_type_hints(tree: ast.AST, filename: str) -> List[Violation]:
17
+ violations: List[Violation] = []
18
+
19
+ for node in ast.walk(tree):
20
+ if isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef)):
21
+ if node.name.startswith("_") and node.name != "__init__":
22
+ continue
23
+
24
+ if node.returns is None:
25
+ violations.append(
26
+ Violation(
27
+ filename,
28
+ node.lineno,
29
+ f"Function '{node.name}' missing return type annotation",
30
+ )
31
+ )
32
+
33
+ for arg in node.args.args:
34
+ if arg.arg == "self" or arg.arg == "cls":
35
+ continue
36
+ if arg.annotation is None:
37
+ violations.append(
38
+ Violation(
39
+ filename,
40
+ node.lineno,
41
+ f"Parameter '{arg.arg}' in '{node.name}' missing type annotation",
42
+ )
43
+ )
44
+
45
+ return violations
46
+
47
+
48
+ def check_any_type(tree: ast.AST, filename: str) -> List[Violation]:
49
+ violations: List[Violation] = []
50
+
51
+ for node in ast.walk(tree):
52
+ if isinstance(node, ast.Name) and node.id == "Any":
53
+ violations.append(
54
+ Violation(
55
+ filename,
56
+ node.lineno,
57
+ "Any type used - use specific type or generic",
58
+ )
59
+ )
60
+
61
+ return violations
62
+
63
+
64
+ def validate_file(file_path: Path) -> List[Violation]:
65
+ violations: List[Violation] = []
66
+ filename = str(file_path)
67
+
68
+ try:
69
+ source = file_path.read_text(encoding="utf-8")
70
+ tree = ast.parse(source)
71
+ except Exception as error:
72
+ return [Violation(filename, 0, f"Error: {error}")]
73
+
74
+ violations.extend(check_missing_type_hints(tree, filename))
75
+ violations.extend(check_any_type(tree, filename))
76
+
77
+ return violations
78
+
79
+
80
+ def main() -> int:
81
+ if len(sys.argv) < 2:
82
+ print("Usage: type_safety_checks.py <file1.py> [file2.py ...]", file=sys.stderr)
83
+ return 1
84
+
85
+ all_violations: List[Violation] = []
86
+
87
+ for file_arg in sys.argv[1:]:
88
+ file_path = Path(file_arg)
89
+ if not file_path.exists():
90
+ print(f"Error: File not found: {file_path}", file=sys.stderr)
91
+ return 1
92
+ all_violations.extend(validate_file(file_path))
93
+
94
+ for violation in all_violations:
95
+ print(violation)
96
+
97
+ return 1 if all_violations else 0
98
+
99
+
100
+ if __name__ == "__main__":
101
+ sys.exit(main())
@@ -0,0 +1,92 @@
1
+ """Useless test detection validator.
2
+
3
+ Implements check 12: No useless tests.
4
+ Tests must verify behavior, not existence or constant values.
5
+ """
6
+
7
+ import ast
8
+ import sys
9
+ from pathlib import Path
10
+ from typing import List
11
+
12
+ from validator_base import Violation
13
+
14
+
15
+ def check_useless_tests(tree: ast.AST, filename: str) -> List[Violation]:
16
+ violations: List[Violation] = []
17
+
18
+ for node in ast.walk(tree):
19
+ if isinstance(node, ast.FunctionDef) and node.name.startswith("test_"):
20
+ for child in ast.walk(node):
21
+ if isinstance(child, ast.Assert):
22
+ if _is_callable_check(child):
23
+ violations.append(
24
+ Violation(filename, child.lineno, "Useless test: callable() check doesn't verify behavior")
25
+ )
26
+ elif _is_hasattr_check(child):
27
+ violations.append(
28
+ Violation(filename, child.lineno, "Useless test: hasattr() check doesn't verify behavior")
29
+ )
30
+ elif _is_constant_value_check(child):
31
+ violations.append(
32
+ Violation(filename, child.lineno, "Useless test: testing constant value doesn't verify behavior")
33
+ )
34
+
35
+ return violations
36
+
37
+
38
+ def _is_callable_check(node: ast.Assert) -> bool:
39
+ if isinstance(node.test, ast.Call):
40
+ if isinstance(node.test.func, ast.Name) and node.test.func.id == "callable":
41
+ return True
42
+ return False
43
+
44
+
45
+ def _is_hasattr_check(node: ast.Assert) -> bool:
46
+ if isinstance(node.test, ast.Call):
47
+ if isinstance(node.test.func, ast.Name) and node.test.func.id == "hasattr":
48
+ return True
49
+ return False
50
+
51
+
52
+ def _is_constant_value_check(node: ast.Assert) -> bool:
53
+ if isinstance(node.test, ast.Compare):
54
+ if len(node.test.ops) == 1 and isinstance(node.test.ops[0], ast.Eq):
55
+ left = node.test.left
56
+ right = node.test.comparators[0] if node.test.comparators else None
57
+ if isinstance(left, ast.Name) and left.id.isupper():
58
+ if isinstance(right, ast.Constant) and isinstance(right.value, str):
59
+ return True
60
+ return False
61
+
62
+
63
+ def validate_file(file_path: Path) -> List[Violation]:
64
+ filename = str(file_path)
65
+ if "test" not in filename.lower():
66
+ return []
67
+
68
+ try:
69
+ source = file_path.read_text(encoding="utf-8")
70
+ tree = ast.parse(source)
71
+ except Exception as error:
72
+ return [Violation(filename, 0, f"Error: {error}")]
73
+
74
+ return check_useless_tests(tree, filename)
75
+
76
+
77
+ def main() -> int:
78
+ if len(sys.argv) < 2:
79
+ return 1
80
+
81
+ all_violations: List[Violation] = []
82
+ for file_arg in sys.argv[1:]:
83
+ all_violations.extend(validate_file(Path(file_arg)))
84
+
85
+ for violation in all_violations:
86
+ print(violation)
87
+
88
+ return 1 if all_violations else 0
89
+
90
+
91
+ if __name__ == "__main__":
92
+ sys.exit(main())
@@ -0,0 +1,19 @@
1
+ """Base classes for validators.
2
+
3
+ Provides shared dataclasses used across all validator modules.
4
+ """
5
+
6
+ from dataclasses import dataclass
7
+
8
+
9
+ @dataclass(frozen=True)
10
+ class Violation:
11
+ """Represents a validation violation."""
12
+
13
+ file: str
14
+ line: int
15
+ message: str
16
+
17
+ def __str__(self) -> str:
18
+ """Format as file:line: message."""
19
+ return f"{self.file}:{self.line}: {self.message}"
@@ -0,0 +1,57 @@
1
+ """Verify all validator paths referenced in SKILL.md exist."""
2
+
3
+ import re
4
+ import sys
5
+ from pathlib import Path
6
+
7
+
8
+ SKILL_MD_PATH = Path(__file__).parent.parent.parent / "skills" / "pr-review-responder" / "SKILL.md"
9
+ VALIDATORS_DIR = Path(__file__).parent
10
+
11
+
12
+ def extract_validator_paths(content: str) -> list[str]:
13
+ """Extract validator file paths from SKILL.md content."""
14
+ pattern = r"validators[/\\](\w+\.py)"
15
+ matches = re.findall(pattern, content)
16
+ return list(set(matches))
17
+
18
+
19
+ def verify_validators() -> int:
20
+ """Verify all referenced validators exist.
21
+
22
+ Returns:
23
+ Exit code: 0 if all exist, 1 if any missing
24
+ """
25
+ if not SKILL_MD_PATH.exists():
26
+ print(f"ERROR: SKILL.md not found at {SKILL_MD_PATH}")
27
+ return 1
28
+
29
+ content = SKILL_MD_PATH.read_text(encoding="utf-8")
30
+ referenced_validators = extract_validator_paths(content)
31
+
32
+ print(f"Found {len(referenced_validators)} validator references in SKILL.md")
33
+ print()
34
+
35
+ missing = []
36
+ for validator_file in sorted(referenced_validators):
37
+ validator_path = VALIDATORS_DIR / validator_file
38
+ if validator_path.exists():
39
+ print(f" [OK] {validator_file}")
40
+ else:
41
+ print(f" [MISSING] {validator_file}")
42
+ missing.append(validator_file)
43
+
44
+ print()
45
+
46
+ if missing:
47
+ print(f"ERROR: {len(missing)} validator(s) missing:")
48
+ for validator_file in missing:
49
+ print(f" - {validator_file}")
50
+ return 1
51
+
52
+ print("All referenced validators exist.")
53
+ return 0
54
+
55
+
56
+ if __name__ == "__main__":
57
+ sys.exit(verify_validators())
@@ -0,0 +1,114 @@
1
+ #!/usr/bin/env python3
2
+
3
+ import json
4
+ import os
5
+ import subprocess
6
+ import sys
7
+ from pathlib import Path
8
+
9
+ PYTHON_EXTENSIONS = {".py"}
10
+ JS_EXTENSIONS = {".js", ".ts", ".tsx", ".jsx", ".mjs", ".cjs"}
11
+ JSON_EXTENSIONS = {".json"}
12
+ PLUGIN_ROOT = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
13
+ HOOKS_DIR = os.path.join(PLUGIN_ROOT, "hooks") + os.sep
14
+ PYTHON_FORMAT_TIMEOUT_SECONDS = 15
15
+ JS_FORMAT_TIMEOUT_SECONDS = 30
16
+ PRETTIER_CONFIG_NAMES = {
17
+ ".prettierrc",
18
+ ".prettierrc.json",
19
+ ".prettierrc.yml",
20
+ ".prettierrc.yaml",
21
+ ".prettierrc.js",
22
+ ".prettierrc.cjs",
23
+ ".prettierrc.mjs",
24
+ ".prettierrc.toml",
25
+ "prettier.config.js",
26
+ "prettier.config.cjs",
27
+ "prettier.config.mjs",
28
+ }
29
+
30
+
31
+ def has_prettier_config(file_path: str) -> bool:
32
+ each_ancestor = Path(file_path).resolve().parent
33
+ while True:
34
+ for config_name in PRETTIER_CONFIG_NAMES:
35
+ if (each_ancestor / config_name).exists():
36
+ return True
37
+ parent = each_ancestor.parent
38
+ if parent == each_ancestor:
39
+ break
40
+ each_ancestor = parent
41
+ return False
42
+
43
+
44
+ def is_untracked_in_git(file_path: str) -> bool:
45
+ """Check if file is untracked (brand new) by git."""
46
+ containing_directory = str(Path(file_path).parent)
47
+ try:
48
+ git_check = subprocess.run(
49
+ ["git", "ls-files", "--error-unmatch", file_path],
50
+ capture_output=True,
51
+ text=True,
52
+ cwd=containing_directory,
53
+ timeout=5,
54
+ )
55
+ return git_check.returncode != 0
56
+ except (FileNotFoundError, subprocess.TimeoutExpired):
57
+ return False
58
+
59
+
60
+ def main() -> None:
61
+ try:
62
+ hook_input = json.load(sys.stdin)
63
+ except (json.JSONDecodeError, ValueError):
64
+ sys.exit(0)
65
+
66
+ tool_name = hook_input.get("tool_name", "")
67
+ file_path = hook_input.get("tool_input", {}).get("file_path", "")
68
+ if not file_path:
69
+ sys.exit(0)
70
+
71
+ if tool_name == "Edit":
72
+ sys.exit(0)
73
+
74
+ if tool_name == "Write" and not is_untracked_in_git(file_path):
75
+ sys.exit(0)
76
+
77
+ if file_path.startswith(HOOKS_DIR):
78
+ sys.exit(0)
79
+
80
+ suffix = Path(file_path).suffix.lower()
81
+
82
+ if suffix in PYTHON_EXTENSIONS:
83
+ for each_formatter_command in [
84
+ ["ruff", "format", file_path],
85
+ [sys.executable, "-m", "ruff", "format", file_path],
86
+ ["black", file_path],
87
+ [sys.executable, "-m", "black", file_path],
88
+ ]:
89
+ try:
90
+ format_run = subprocess.run(each_formatter_command, capture_output=True, text=True, timeout=PYTHON_FORMAT_TIMEOUT_SECONDS)
91
+ if format_run.returncode == 0:
92
+ break
93
+ except FileNotFoundError:
94
+ continue
95
+ except subprocess.TimeoutExpired:
96
+ break
97
+ elif suffix in JS_EXTENSIONS or suffix in JSON_EXTENSIONS:
98
+ if not has_prettier_config(file_path):
99
+ sys.exit(0)
100
+ try:
101
+ subprocess.run(
102
+ ["npx", "--yes", "prettier", "--write", file_path],
103
+ capture_output=True,
104
+ text=True,
105
+ timeout=JS_FORMAT_TIMEOUT_SECONDS,
106
+ )
107
+ except (FileNotFoundError, subprocess.TimeoutExpired):
108
+ pass
109
+
110
+ sys.exit(0)
111
+
112
+
113
+ if __name__ == "__main__":
114
+ main()
@@ -0,0 +1,46 @@
1
+ #!/usr/bin/env python3
2
+ """PostToolUse hook — resets the serial investigation tracker when delegation occurs.
3
+
4
+ Clears the investigation timestamp tracker when the lead session delegates work
5
+ via Agent, Task, or TeamCreate tools. This allows the lead to resume limited
6
+ diagnostic calls after properly delegating.
7
+
8
+ Companion: blocking/serial-investigation-blocker.py (PreToolUse on Read|Bash|Grep)
9
+ """
10
+
11
+ import json
12
+ import os
13
+ import sys
14
+
15
+ TRACKER_STATE_PATH = os.path.join(
16
+ os.path.expanduser("~"), ".claude", "runtime", "investigation-tracker.json"
17
+ )
18
+
19
+ DELEGATION_TOOLS = frozenset({"Agent", "Task", "TeamCreate"})
20
+
21
+
22
+ def clear_investigation_tracker() -> None:
23
+ try:
24
+ os.remove(TRACKER_STATE_PATH)
25
+ except FileNotFoundError:
26
+ pass
27
+ except OSError:
28
+ pass
29
+
30
+
31
+ def main() -> None:
32
+ try:
33
+ hook_input = json.load(sys.stdin)
34
+ except json.JSONDecodeError:
35
+ sys.exit(0)
36
+
37
+ tool_name = hook_input.get("tool_name", "")
38
+ if tool_name not in DELEGATION_TOOLS:
39
+ sys.exit(0)
40
+
41
+ clear_investigation_tracker()
42
+ sys.exit(0)
43
+
44
+
45
+ if __name__ == "__main__":
46
+ main()
package/package.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "claude-dev-env",
3
+ "version": "1.0.0",
4
+ "description": "Claude Code development standards — rules, hooks, agents, commands, and skills",
5
+ "type": "module",
6
+ "bin": {
7
+ "claude-dev-env": "bin/install.mjs"
8
+ },
9
+ "files": [
10
+ "bin/",
11
+ "rules/",
12
+ "docs/",
13
+ "commands/",
14
+ "agents/",
15
+ "skills/",
16
+ "hooks/"
17
+ ],
18
+ "keywords": [
19
+ "claude-code",
20
+ "plugin",
21
+ "cli",
22
+ "tdd",
23
+ "code-quality"
24
+ ],
25
+ "license": "MIT",
26
+ "repository": {
27
+ "type": "git",
28
+ "url": "git+https://github.com/jl-cmd/claude-code-config.git"
29
+ }
30
+ }
@@ -0,0 +1,47 @@
1
+ # Agent Spawn Protocol (Mandatory)
2
+
3
+ **When this applies:** Before any Agent or Task tool invocation (Explore, implementation, research, or team subagents).
4
+
5
+ <agent_spawn_protocol>
6
+
7
+ ## Before spawning ANY agent — no exceptions
8
+
9
+ Every Agent and Task tool call must follow this protocol. This includes Explore agents, research agents, execution agents, and team members.
10
+
11
+ ### Step 1: Context sufficiency check
12
+
13
+ Before writing any agent prompt, verify you can answer all of these:
14
+ - [ ] What specific files, directories, or areas of the codebase are involved?
15
+ - [ ] What constraints apply? (patterns to follow, things NOT to change, boundaries)
16
+ - [ ] What does success look like? (expected output, acceptance criteria)
17
+ - [ ] Is the task unambiguous enough to delegate?
18
+
19
+ If ANY answer is "I don't know" -- investigate first (read files, search code) or ask the user. Do NOT spawn with incomplete context.
20
+
21
+ ### Step 2: Craft the prompt with /prompt-generator
22
+
23
+ Run the `/prompt-generator` skill to produce a structured prompt. Feed it:
24
+ - The task description and goal
25
+ - Target files/directories discovered in Step 1
26
+ - Constraints and boundaries
27
+ - Expected output format
28
+ - Acceptance criteria
29
+
30
+ The skill will ask 1-3 clarifying questions if information is missing -- this is the built-in context verification.
31
+
32
+ Use the skill's output as the agent's `prompt` parameter.
33
+
34
+ ### Step 3: Spawn the agent
35
+
36
+ Pass the structured prompt from Step 2 to the Agent/Task tool.
37
+
38
+ </agent_spawn_protocol>
39
+
40
+ ## Why
41
+
42
+ Agents receiving vague prompts waste tokens exploring in circles, produce code that misses constraints, and require expensive rework. A 30-second investment in prompt quality via /prompt-generator saves 5-minute agent failures. This applies equally to Explore agents (which waste context on unfocused searches) and execution agents (which write wrong code).
43
+
44
+ ## Relationship to other rules
45
+
46
+ - **conservative-action.md** gates acting when ambiguous. This extends that: do not delegate when the task is ambiguous—investigate or ask the user first.
47
+ - Project-specific rules or `~/.claude/CLAUDE.md` may define *whether* to use subagents or teams; this rule governs *how* to craft prompts when you do delegate.
@@ -0,0 +1,27 @@
1
+ # Clean Up Temporary Files
2
+
3
+ **When this applies:** After tasks that created scratch files, debug dumps, or one-off scripts the user did not ask to keep.
4
+
5
+ Source: [Anthropic — Reduce file creation in agentic coding](https://platform.claude.com/docs/en/build-with-claude/prompt-engineering/claude-prompting-best-practices#reduce-file-creation-in-agentic-coding)
6
+
7
+ ## During a task
8
+
9
+ - Prefer working in memory over creating scratchpad files. Use variables and tool results instead of writing intermediate data to disk.
10
+ - When a temporary file is genuinely needed (e.g., a helper script, a test fixture, a debug output), track it mentally for cleanup.
11
+
12
+ ## When a task is complete
13
+
14
+ - Remove every temporary file, script, or helper file you created during the task.
15
+ - Leave the working directory cleaner than you found it.
16
+ - If a file was created at the user's explicit request (not as a byproduct of your process), leave it in place.
17
+
18
+ ## What counts as temporary
19
+
20
+ - Scripts written to test a hypothesis or run a one-off check
21
+ - Debug output files, log dumps, or intermediate data exports
22
+ - Helper files created to work around tool limitations
23
+ - Any file the user did not ask for and would not expect to find after the task
24
+
25
+ ## Why
26
+
27
+ Temporary files accumulate across sessions and clutter the project root. Latest models sometimes use files as scratchpads during iteration, and these leftovers confuse both the user and future sessions if not cleaned up.
@@ -0,0 +1,11 @@
1
+ # Responding to Code Reviews
2
+
3
+ **When this applies:** GitHub PR review feedback on a branch you are fixing.
4
+
5
+ **MANDATORY PROTOCOL (use pr-review-responder skill):**
6
+
7
+ 1. Fetch ALL reviewer comments BEFORE any fixes
8
+ 2. Create TodoWrite checklist - One item per comment
9
+ 3. Fix systematically - Mark each todo complete
10
+ 4. Reply to EACH comment inline
11
+ 5. Create ONE review fix commit - DO NOT squash with original
@@ -0,0 +1,43 @@
1
+ # Code Standards
2
+
3
+ > **MANDATORY REFERENCE:** CODE_RULES.md - Load for ALL code generation.
4
+ > This is the single source of truth for code standards. Non-negotiable.
5
+
6
+ @${CLAUDE_PLUGIN_ROOT}/docs/CODE_RULES.md
7
+
8
+ **Key principles (see CODE_RULES.md for complete reference):**
9
+ - Self-documenting code (no comments)
10
+ - Centralized configuration (one source of truth)
11
+ - Reuse constants (search before creating)
12
+ - No magic values (everything named)
13
+ - No abbreviations (full words)
14
+ - Complete type hints
15
+ - TDD (test first)
16
+
17
+ ## Function Parameters - Required vs Optional
18
+
19
+ **Use required parameters when no valid use case exists for optional.**
20
+ **Remove unused parameters.**
21
+
22
+ ## Encapsulation - Logic Belongs in Models
23
+
24
+ **NEVER scatter construction logic in calling code.**
25
+
26
+ Path/URL building, formatting, transformations -> Put in model methods.
27
+ If you find yourself building the same string pattern in multiple places, it belongs in the model.
28
+
29
+ ## Document Temporary Code
30
+
31
+ **Scaffolding/placeholder code MUST have TODO comments.**
32
+
33
+ When code exists only to enable testing before full implementation:
34
+ - Add `// TODO: Replace with...` explaining what will replace it
35
+ - Explain WHY it's temporary, not just WHAT it does
36
+
37
+ ## Naming Reflects Behavior
38
+
39
+ **Name components after what they ARE, not abstract concepts.**
40
+
41
+ If it overlays the viewport -> "Overlay" not "Screen"
42
+ If it validates input -> "Validator" not "Handler"
43
+ Names should describe observable behavior or visual appearance.
@@ -0,0 +1,20 @@
1
+ # Conservative Action
2
+
3
+ Source: [Anthropic - Tool Usage](https://platform.claude.com/docs/en/build-with-claude/prompt-engineering/claude-prompting-best-practices#tool-usage)
4
+
5
+ <do_not_act_before_instructions>
6
+ When the user's intent is ambiguous, default to research and recommendations rather than taking action. Provide information, explain options, and surface tradeoffs — then let the user decide before making changes.
7
+
8
+ Proceed with edits, file modifications, or implementations only when the user explicitly requests them.
9
+ </do_not_act_before_instructions>
10
+
11
+ ## Deciding whether to act
12
+
13
+ - If the user asks a question, answer the question. Do not also fix the thing they asked about.
14
+ - If the user describes a problem, investigate and recommend. Do not jump to implementation.
15
+ - If the user says "do it", "go ahead", "make the change", or similarly explicit language, proceed with action.
16
+ - When in doubt, ask: "Would you like me to make this change, or just show you the approach?"
17
+
18
+ ## Why
19
+
20
+ Acting prematurely wastes effort and round-trips when the user wanted a different approach. Exploring first produces better outcomes than committing early. This is especially important with models that have a strong action bias.
@@ -0,0 +1,12 @@
1
+ ---
2
+ alwaysApply: true
3
+ ---
4
+
5
+ When working with libraries, frameworks, or APIs — use Context7 MCP to fetch current documentation instead of relying on training data. This includes setup questions, code generation, API references, and anything involving specific packages.
6
+
7
+ ## Steps
8
+
9
+ 1. Call `resolve-library-id` with the library name and the user's question
10
+ 2. Pick the best match — prefer exact names and version-specific IDs when a version is mentioned
11
+ 3. Call `query-docs` with the selected library ID and the user's question
12
+ 4. Answer using the fetched docs — include code examples and cite the version
@@ -0,0 +1,27 @@
1
+ # Explore Thoroughly
2
+
3
+ Source: [Anthropic - Overthinking and Excessive Thoroughness](https://platform.claude.com/docs/en/build-with-claude/prompt-engineering/claude-prompting-best-practices#overthinking-and-excessive-thoroughness)
4
+
5
+ Note: This deliberately chooses exploration depth over the "commit and execute quickly" pattern from the same source. Thorough upfront exploration is preferred for the intended workflow.
6
+
7
+ ## Before committing to an approach
8
+
9
+ - Read the relevant files. Understand what exists before proposing what to change.
10
+ - Map the existing patterns: naming conventions, file organization, architectural decisions.
11
+ - Identify constraints that could invalidate an approach before investing effort in it.
12
+ - For unfamiliar codebases or high-stakes changes, invest more time exploring than feels necessary.
13
+
14
+ ## Exploration scales with risk
15
+
16
+ - Small change to a familiar file: a quick read of the file and its immediate neighbors is sufficient.
17
+ - New feature or cross-cutting change: read broadly across the codebase to understand how similar things are done.
18
+ - Architectural decision: explore the full landscape before recommending a direction.
19
+
20
+ ## Relationship to other rules
21
+
22
+ - **conservative-action.md** gates *whether* to act. This rule governs *how deeply* to investigate.
23
+ - **research-mode.md** ensures factual claims are grounded. This rule ensures implementation plans are grounded in the actual codebase.
24
+
25
+ ## Why
26
+
27
+ Premature commitment leads to wasted effort when the chosen approach conflicts with existing patterns or misses important context. Thorough exploration surfaces constraints early and produces better-informed solutions.