claude-dev-env 1.83.0 → 1.85.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 (186) hide show
  1. package/_shared/pr-loop/audit-contract.md +24 -12
  2. package/_shared/pr-loop/scripts/_claude_permissions_common.py +16 -5
  3. package/_shared/pr-loop/scripts/code_rules_gate.py +2 -3
  4. package/_shared/pr-loop/scripts/pr_loop_shared_constants/CLAUDE.md +1 -1
  5. package/_shared/pr-loop/scripts/pr_loop_shared_constants/terminology_sweep_constants.py +8 -0
  6. package/_shared/pr-loop/scripts/reviews_disabled.py +2 -0
  7. package/_shared/pr-loop/scripts/terminology_sweep.py +85 -39
  8. package/_shared/pr-loop/scripts/tests/test__claude_permissions_common.py +212 -0
  9. package/_shared/pr-loop/scripts/tests/test_agent_config_carveout.py +18 -0
  10. package/_shared/pr-loop/scripts/tests/test_claude_permissions_common.py +18 -0
  11. package/_shared/pr-loop/scripts/tests/test_code_rules_gate.py +37 -0
  12. package/_shared/pr-loop/scripts/tests/test_reviews_disabled.py +14 -0
  13. package/_shared/pr-loop/scripts/tests/test_terminology_sweep.py +94 -4
  14. package/agents/clean-coder.md +3 -0
  15. package/audit-rubrics/category_rubrics/category-o-docstring-vs-impl-drift.md +1 -1
  16. package/bin/install.mjs +16 -8
  17. package/bin/install.test.mjs +17 -6
  18. package/commands/CLAUDE.md +0 -1
  19. package/docs/CODE_RULES.md +1 -1
  20. package/hooks/blocking/CLAUDE.md +0 -4
  21. package/hooks/blocking/claude_md_orphan_file_blocker.py +1 -1
  22. package/hooks/blocking/code_rules_constants_config.py +5 -0
  23. package/hooks/blocking/code_rules_docstrings.py +133 -19
  24. package/hooks/blocking/code_rules_enforcer.py +4 -0
  25. package/hooks/blocking/code_rules_imports_logging.py +10 -6
  26. package/hooks/blocking/code_rules_magic_values.py +5 -0
  27. package/hooks/blocking/code_rules_naming_collection.py +15 -8
  28. package/hooks/blocking/code_rules_paired_test.py +3 -2
  29. package/hooks/blocking/code_rules_shared.py +34 -0
  30. package/hooks/blocking/code_rules_string_magic.py +1 -1
  31. package/hooks/blocking/code_rules_unused_imports.py +2 -2
  32. package/hooks/blocking/duplicate_rmtree_helper_blocker.py +4 -4
  33. package/hooks/blocking/test_code_rules_enforcer_docstring_args_span_scope.py +29 -0
  34. package/hooks/blocking/test_code_rules_enforcer_docstring_prose_wall_illustration.py +197 -0
  35. package/hooks/blocking/test_code_rules_enforcer_docstring_runon_sentence.py +27 -0
  36. package/hooks/blocking/test_code_rules_enforcer_naive_datetime.py +24 -0
  37. package/hooks/blocking/test_code_rules_enforcer_split_constants_config.py +33 -0
  38. package/hooks/blocking/test_code_rules_enforcer_split_shared.py +23 -0
  39. package/hooks/blocking/test_code_rules_magic_values.py +54 -0
  40. package/hooks/blocking/test_duplicate_rmtree_helper_blocker.py +0 -6
  41. package/hooks/blocking/test_pr_converge_bugteam_enforcer_state_tolerance.py +184 -0
  42. package/hooks/blocking/test_shared_stdin_adoption.py +5 -30
  43. package/hooks/hooks_constants/CLAUDE.md +0 -3
  44. package/hooks/hooks_constants/blocking_check_limits.py +4 -0
  45. package/hooks/hooks_constants/code_rules_path_utils_constants.py +1 -1
  46. package/hooks/hooks_constants/duplicate_rmtree_helper_blocker_constants.py +0 -1
  47. package/hooks/hooks_constants/post_tool_use_dispatcher_constants.py +0 -5
  48. package/hooks/validation/post_tool_use_dispatcher.py +1 -1
  49. package/hooks/validation/test_post_tool_use_dispatcher.py +51 -35
  50. package/hooks/workflow/CLAUDE.md +2 -8
  51. package/package.json +1 -1
  52. package/rules/CLAUDE.md +1 -1
  53. package/rules/docstring-prose-matches-implementation.md +1 -1
  54. package/rules/env-var-table-code-drift.md +1 -1
  55. package/rules/package-inventory-stale-entry.md +1 -1
  56. package/rules/paired-test-coverage.md +1 -1
  57. package/rules/plain-illustrative-docstrings.md +35 -1
  58. package/skills/CLAUDE.md +6 -1
  59. package/skills/_shared/pr-loop/CLAUDE.md +1 -0
  60. package/skills/_shared/pr-loop/scripts/CLAUDE.md +1 -0
  61. package/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/CLAUDE.md +1 -0
  62. package/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/handoff_constants.py +45 -0
  63. package/skills/_shared/pr-loop/scripts/test_write_handoff.py +201 -0
  64. package/skills/_shared/pr-loop/scripts/write_handoff.py +309 -0
  65. package/skills/autoconverge/SKILL.md +82 -58
  66. package/skills/autoconverge/reference/closing-report.md +6 -6
  67. package/skills/autoconverge/reference/convergence.md +17 -15
  68. package/skills/autoconverge/reference/gotchas.md +6 -3
  69. package/skills/autoconverge/workflow/autoconverge_report_constants/render_report_constants.py +2 -9
  70. package/skills/autoconverge/workflow/converge.contract.test.mjs +87 -13
  71. package/skills/autoconverge/workflow/converge.copilot-gate.test.mjs +1 -1
  72. package/skills/autoconverge/workflow/converge.merge-conflict.test.mjs +16 -9
  73. package/skills/autoconverge/workflow/converge.mjs +71 -74
  74. package/skills/autoconverge/workflow/render_report.py +7 -11
  75. package/skills/bugteam/CLAUDE.md +1 -1
  76. package/skills/bugteam/PROMPTS.md +7 -6
  77. package/skills/bugteam/SKILL.md +25 -72
  78. package/skills/bugteam/reference/CLAUDE.md +1 -3
  79. package/skills/bugteam/reference/README.md +1 -1
  80. package/skills/bugteam/reference/audit-and-teammates.md +1 -1
  81. package/skills/bugteam/reference/obstacles/fix-publish-summary.md +1 -1
  82. package/skills/bugteam/reference/team-setup.md +8 -7
  83. package/skills/bugteam/scripts/CLAUDE.md +0 -6
  84. package/skills/bugteam/scripts/README.md +0 -4
  85. package/skills/bugteam/scripts/bugteam_scripts_constants/CLAUDE.md +0 -1
  86. package/skills/code/SKILL.md +2 -0
  87. package/skills/copilot-review/CLAUDE.md +1 -1
  88. package/skills/copilot-review/SKILL.md +25 -23
  89. package/skills/findbugs/CLAUDE.md +2 -2
  90. package/skills/findbugs/SKILL.md +22 -83
  91. package/skills/fixbugs/SKILL.md +2 -4
  92. package/skills/log-audit/CLAUDE.md +20 -0
  93. package/skills/log-audit/SKILL.md +68 -0
  94. package/skills/log-audit/reference/CLAUDE.md +9 -0
  95. package/skills/log-audit/reference/charter.md +52 -0
  96. package/skills/log-audit/scripts/CLAUDE.md +27 -0
  97. package/skills/log-audit/scripts/cluster_recurrences.py +261 -0
  98. package/skills/log-audit/scripts/collect_log_window.py +199 -0
  99. package/skills/log-audit/scripts/log_audit_constants/CLAUDE.md +12 -0
  100. package/skills/log-audit/scripts/log_audit_constants/cluster_recurrences_constants.py +23 -0
  101. package/skills/log-audit/scripts/log_audit_constants/collect_log_window_constants.py +24 -0
  102. package/skills/log-audit/scripts/log_audit_constants/mine_copilot_findings_constants.py +49 -0
  103. package/skills/log-audit/scripts/mine_copilot_findings.py +302 -0
  104. package/skills/log-audit/scripts/test_cluster_recurrences.py +160 -0
  105. package/skills/log-audit/scripts/test_collect_log_window.py +111 -0
  106. package/skills/log-audit/scripts/test_mine_copilot_findings.py +126 -0
  107. package/skills/monitor-open-prs/SKILL.md +2 -2
  108. package/skills/post-audit-findings/SKILL.md +84 -0
  109. package/skills/pr-converge/CLAUDE.md +2 -0
  110. package/skills/pr-converge/SKILL.md +99 -60
  111. package/skills/pr-converge/reference/CLAUDE.md +1 -1
  112. package/skills/pr-converge/reference/convergence-gates.md +16 -19
  113. package/skills/pr-converge/reference/examples.md +5 -5
  114. package/skills/pr-converge/reference/fix-protocol.md +16 -43
  115. package/skills/pr-converge/reference/obstacles/fix-publish-summary.md +1 -1
  116. package/skills/pr-converge/reference/per-tick.md +24 -45
  117. package/skills/pr-converge/reference/state-schema.md +27 -0
  118. package/skills/pr-converge/scripts/README.md +3 -5
  119. package/skills/pr-fix-protocol/SKILL.md +70 -0
  120. package/skills/pr-loop-lifecycle/SKILL.md +73 -0
  121. package/skills/{bugteam → pr-loop-lifecycle}/reference/teardown-publish-permissions.md +22 -24
  122. package/skills/pr-scope-resolve/SKILL.md +48 -0
  123. package/skills/qbug/CLAUDE.md +4 -4
  124. package/skills/qbug/SKILL.md +46 -144
  125. package/skills/qbug/test_qbug_skill_audit_schema.py +2 -2
  126. package/skills/qbug/test_qbug_skill_post_fix_audit.py +1 -1
  127. package/skills/reviewer-gates/SKILL.md +96 -0
  128. package/skills/session-log/CLAUDE.md +7 -7
  129. package/skills/session-log/SKILL.md +27 -44
  130. package/skills/test_markdown_link_integrity.py +103 -0
  131. package/commands/doc-gist.md +0 -16
  132. package/hooks/blocking/_md_to_html_blocker_test_support.py +0 -65
  133. package/hooks/blocking/conftest.py +0 -30
  134. package/hooks/blocking/md_path_exemptions.py +0 -224
  135. package/hooks/blocking/md_to_html_blocker.py +0 -155
  136. package/hooks/blocking/test_md_to_html_blocker_exemptions.py +0 -434
  137. package/hooks/blocking/test_md_to_html_blocker_extensions.py +0 -157
  138. package/hooks/blocking/test_md_to_html_blocker_path_resolution.py +0 -336
  139. package/hooks/hooks_constants/doc_gist_auto_publish_constants.py +0 -18
  140. package/hooks/hooks_constants/html_companion_constants.py +0 -20
  141. package/hooks/hooks_constants/md_to_html_blocker_constants.py +0 -76
  142. package/hooks/hooks_constants/test_md_to_html_blocker_constants.py +0 -125
  143. package/hooks/workflow/doc_gist_auto_publish.py +0 -144
  144. package/hooks/workflow/md_to_html_companion.py +0 -358
  145. package/hooks/workflow/test_doc_gist_auto_publish.py +0 -117
  146. package/hooks/workflow/test_md_to_html_companion.py +0 -613
  147. package/skills/bugteam/reference/audit-contract.md +0 -163
  148. package/skills/bugteam/scripts/_bugteam_permissions_common.py +0 -455
  149. package/skills/bugteam/scripts/bugteam_scripts_constants/claude_permissions_common_constants.py +0 -69
  150. package/skills/bugteam/scripts/grant_project_claude_permissions.py +0 -280
  151. package/skills/bugteam/scripts/revoke_project_claude_permissions.py +0 -266
  152. package/skills/bugteam/scripts/test__bugteam_permissions_common.py +0 -160
  153. package/skills/bugteam/scripts/test_agent_config_carveout.py +0 -356
  154. package/skills/bugteam/scripts/test_bugteam_permissions_common.py +0 -140
  155. package/skills/doc-gist/CLAUDE.md +0 -25
  156. package/skills/doc-gist/SKILL.md +0 -97
  157. package/skills/doc-gist/references/CLAUDE.md +0 -9
  158. package/skills/doc-gist/references/examples/01-exploration-code-approaches.html +0 -453
  159. package/skills/doc-gist/references/examples/02-exploration-visual-designs.html +0 -515
  160. package/skills/doc-gist/references/examples/03-code-review-pr.html +0 -638
  161. package/skills/doc-gist/references/examples/04-code-understanding.html +0 -491
  162. package/skills/doc-gist/references/examples/05-design-system.html +0 -629
  163. package/skills/doc-gist/references/examples/06-component-variants.html +0 -605
  164. package/skills/doc-gist/references/examples/07-prototype-animation.html +0 -455
  165. package/skills/doc-gist/references/examples/08-prototype-interaction.html +0 -396
  166. package/skills/doc-gist/references/examples/09-slide-deck.html +0 -592
  167. package/skills/doc-gist/references/examples/10-svg-illustrations.html +0 -492
  168. package/skills/doc-gist/references/examples/11-status-report.html +0 -528
  169. package/skills/doc-gist/references/examples/12-incident-report.html +0 -596
  170. package/skills/doc-gist/references/examples/13-flowchart-diagram.html +0 -395
  171. package/skills/doc-gist/references/examples/14-research-feature-explainer.html +0 -381
  172. package/skills/doc-gist/references/examples/15-research-concept-explainer.html +0 -368
  173. package/skills/doc-gist/references/examples/16-implementation-plan.html +0 -702
  174. package/skills/doc-gist/references/examples/17-pr-writeup.html +0 -595
  175. package/skills/doc-gist/references/examples/18-editor-triage-board.html +0 -573
  176. package/skills/doc-gist/references/examples/19-editor-feature-flags.html +0 -663
  177. package/skills/doc-gist/references/examples/20-editor-prompt-tuner.html +0 -722
  178. package/skills/doc-gist/references/examples/21-decision-signoff.html +0 -546
  179. package/skills/doc-gist/references/examples/CLAUDE.md +0 -25
  180. package/skills/doc-gist/references/examples/README.md +0 -5
  181. package/skills/doc-gist/scripts/CLAUDE.md +0 -27
  182. package/skills/doc-gist/scripts/doc_gist_scripts_constants/CLAUDE.md +0 -10
  183. package/skills/doc-gist/scripts/doc_gist_scripts_constants/gist_upload_constants.py +0 -16
  184. package/skills/doc-gist/scripts/gist_upload.py +0 -177
  185. package/skills/doc-gist/scripts/test_gist_upload.py +0 -51
  186. /package/skills/{doc-gist/scripts/doc_gist_scripts_constants → log-audit/scripts/log_audit_constants}/__init__.py +0 -0
@@ -1,177 +0,0 @@
1
- """Upload an HTML file as a secret GitHub gist and emit the htmlpreview URL.
2
-
3
- Single-purpose transport. Takes HTML on stdin or via `--input <path>`, runs
4
- `gh gist create` (secret by default), parses the gist URL from gh's output,
5
- composes the htmlpreview.github.io preview URL, optionally opens it in the
6
- default browser, and prints both URLs.
7
-
8
- Designed to compose with anything that produces HTML — pipe in the output of
9
- a script, the contents of a hand-authored file, or have the auto-publish
10
- hook invoke it on a file Claude just wrote. The script does not opine on
11
- HTML shape, structure, or styling.
12
-
13
- Usage:
14
- gist_upload.py --input <path>
15
- gist_upload.py --input - --filename writeup.html < some.html
16
- """
17
-
18
- from __future__ import annotations
19
-
20
- import argparse
21
- import os
22
- import subprocess
23
- import sys
24
- import tempfile
25
- import webbrowser
26
- from pathlib import Path
27
- from urllib.parse import quote
28
-
29
- _script_directory = str(Path(__file__).resolve().parent)
30
- if _script_directory not in sys.path:
31
- sys.path.insert(0, _script_directory)
32
-
33
- from doc_gist_scripts_constants.gist_upload_constants import ( # noqa: E402
34
- GIST_DEFAULT_FILENAME,
35
- GIST_HOST_PREFIX,
36
- MINIMUM_GIST_URL_PARTS,
37
- PREVIEW_URL_TEMPLATE,
38
- UPLOAD_TIMEOUT_SECONDS,
39
- )
40
-
41
-
42
- def _read_html(input_argument: str) -> str:
43
- """Read HTML content from stdin (when input is '-') or a file path.
44
-
45
- Reads the full stdin stream when input_argument is '-'. Callers piping
46
- content through an external process should ensure bounded input.
47
- """
48
- if input_argument == "-":
49
- return sys.stdin.read()
50
- try:
51
- return Path(input_argument).expanduser().resolve().read_text(encoding="utf-8")
52
- except (OSError, UnicodeError) as error:
53
- raise SystemExit(f"Cannot read {input_argument}: {error}")
54
-
55
-
56
- def _resolve_filename(input_argument: str, override: str | None) -> str:
57
- """Pick the filename gh will use for the gist file."""
58
- default_filename = GIST_DEFAULT_FILENAME
59
- if override:
60
- return Path(override).name
61
- if input_argument != "-":
62
- return Path(input_argument).name
63
- return default_filename
64
-
65
-
66
- def _write_to_temp(html_text: str, filename: str, parent_directory: Path) -> Path:
67
- """Write HTML to a temp file inside parent_directory with the given filename."""
68
- target_path = parent_directory / filename
69
- target_path.write_text(html_text, encoding="utf-8")
70
- return target_path
71
-
72
-
73
- def _create_secret_gist(html_path: Path, description: str) -> str:
74
- """Run `gh gist create` against html_path and return the gist URL."""
75
- try:
76
- completed = subprocess.run(
77
- ["gh", "gist", "create", str(html_path), "--desc", description],
78
- check=False,
79
- capture_output=True,
80
- text=True,
81
- encoding="utf-8",
82
- errors="replace",
83
- timeout=UPLOAD_TIMEOUT_SECONDS,
84
- )
85
- except FileNotFoundError:
86
- raise SystemExit(
87
- "gh CLI not found. Install GitHub CLI (https://cli.github.com) and run `gh auth login`."
88
- )
89
- except subprocess.TimeoutExpired:
90
- raise SystemExit(
91
- f"gh gist create timed out after {UPLOAD_TIMEOUT_SECONDS}s. Check network and retry."
92
- )
93
- if completed.returncode != 0:
94
- message_text = completed.stderr.strip() or completed.stdout.strip()
95
- raise SystemExit(
96
- f"gh gist create failed:\n{message_text}\nRun `gh auth login` and retry."
97
- )
98
- output_lines = completed.stdout.strip().splitlines()
99
- if not output_lines:
100
- raise SystemExit("gh gist create produced no output.")
101
- last_line = output_lines[-1].strip()
102
- if not last_line.startswith(GIST_HOST_PREFIX):
103
- raise SystemExit(f"Unexpected gh gist create output: {last_line!r}")
104
- return last_line
105
-
106
-
107
- def _compose_preview_url(gist_url: str, filename: str) -> str:
108
- """Build the htmlpreview.github.io URL from the gist URL and the gist filename."""
109
- minimum_parts = MINIMUM_GIST_URL_PARTS
110
- preview_template = PREVIEW_URL_TEMPLATE
111
- path_after_host = gist_url[len(GIST_HOST_PREFIX) :]
112
- parts = path_after_host.split("/")
113
- if len(parts) < minimum_parts:
114
- raise SystemExit(f"Cannot parse gist URL: {gist_url!r}")
115
- return preview_template.format(user=parts[0], gist_id=parts[1], filename=quote(filename, safe=""))
116
-
117
-
118
- def _open_in_browser(url: str) -> None:
119
- """Open the URL in the default browser, deferring to OS-native behavior on Windows."""
120
- if sys.platform.startswith("win"):
121
- os.startfile(url)
122
- return
123
- webbrowser.open(url)
124
-
125
-
126
- def main() -> int:
127
- """Entry point — read HTML, upload as secret gist, print URLs, open preview.
128
-
129
- Returns:
130
- Process exit code (0 on success).
131
- """
132
- parser = argparse.ArgumentParser(
133
- description="Upload HTML as a secret gist; print gist + htmlpreview URLs."
134
- )
135
- parser.add_argument(
136
- "--input",
137
- required=True,
138
- help="Path to an .html file, or '-' for stdin.",
139
- )
140
- parser.add_argument(
141
- "--filename",
142
- default=None,
143
- help="Filename inside the gist. Defaults to the input filename, or 'doc.html' for stdin.",
144
- )
145
- parser.add_argument(
146
- "--description",
147
- default="HTML artifact",
148
- help="Gist description.",
149
- )
150
- parser.add_argument(
151
- "--no-open",
152
- action="store_true",
153
- help="Skip opening the preview URL in the default browser.",
154
- )
155
- arguments = parser.parse_args()
156
-
157
- html_text = _read_html(arguments.input)
158
- filename = _resolve_filename(arguments.input, arguments.filename)
159
-
160
- with tempfile.TemporaryDirectory(prefix="gist-upload-") as temp_directory:
161
- upload_path = _write_to_temp(html_text, filename, Path(temp_directory))
162
- gist_url = _create_secret_gist(upload_path, arguments.description)
163
- preview_url = _compose_preview_url(gist_url, filename)
164
-
165
- print(f"Gist: {gist_url}", file=sys.stderr)
166
- print(f"Preview: {preview_url}", file=sys.stderr)
167
-
168
- if not arguments.no_open:
169
- _open_in_browser(preview_url)
170
- print("Opened preview in default browser.", file=sys.stderr)
171
-
172
- print(preview_url)
173
- return 0
174
-
175
-
176
- if __name__ == "__main__":
177
- sys.exit(main())
@@ -1,51 +0,0 @@
1
- """Tests for gist_upload.py pure functions — URL composition and filename resolution."""
2
-
3
- from pathlib import Path
4
- import sys
5
-
6
- _script_directory = str(Path(__file__).resolve().parent)
7
- if _script_directory not in sys.path:
8
- sys.path.insert(0, _script_directory)
9
-
10
- from gist_upload import _compose_preview_url, _resolve_filename
11
-
12
-
13
- class TestResolveFilename:
14
- def test_uses_override_when_provided(self):
15
- assert (
16
- _resolve_filename("report.html", "custom-name.html") == "custom-name.html"
17
- )
18
-
19
- def test_strips_directory_from_override(self):
20
- assert (
21
- _resolve_filename("report.html", "/some/path/override.html")
22
- == "override.html"
23
- )
24
-
25
- def test_uses_input_filename_when_no_override(self):
26
- assert _resolve_filename("report.html", None) == "report.html"
27
-
28
- def test_uses_default_for_stdin_without_override(self):
29
- assert _resolve_filename("-", None) == "doc.html"
30
-
31
- def test_override_takes_precedence_over_stdin(self):
32
- assert _resolve_filename("-", "writeup.html") == "writeup.html"
33
-
34
-
35
- class TestComposePreviewUrl:
36
- def test_standard_gist_url(self):
37
- result = _compose_preview_url(
38
- "https://gist.github.com/user123/abc123def456",
39
- "report.html",
40
- )
41
- assert result == (
42
- "https://htmlpreview.github.io/"
43
- "?https://gist.githubusercontent.com/user123/abc123def456/raw/report.html"
44
- )
45
-
46
- def test_filename_with_spaces_is_encoded(self):
47
- result = _compose_preview_url(
48
- "https://gist.github.com/user123/abc123def456",
49
- "my report.html",
50
- )
51
- assert "my%20report.html" in result