claude-dev-env 1.83.0 → 1.84.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 (165) 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/reviews_disabled.py +2 -0
  5. package/_shared/pr-loop/scripts/tests/test__claude_permissions_common.py +212 -0
  6. package/_shared/pr-loop/scripts/tests/test_agent_config_carveout.py +18 -0
  7. package/_shared/pr-loop/scripts/tests/test_claude_permissions_common.py +18 -0
  8. package/_shared/pr-loop/scripts/tests/test_code_rules_gate.py +37 -0
  9. package/_shared/pr-loop/scripts/tests/test_reviews_disabled.py +14 -0
  10. package/agents/clean-coder.md +3 -0
  11. package/audit-rubrics/category_rubrics/category-o-docstring-vs-impl-drift.md +1 -1
  12. package/bin/install.mjs +16 -8
  13. package/bin/install.test.mjs +17 -6
  14. package/commands/CLAUDE.md +0 -1
  15. package/docs/CODE_RULES.md +1 -1
  16. package/hooks/blocking/CLAUDE.md +0 -4
  17. package/hooks/blocking/code_rules_constants_config.py +5 -0
  18. package/hooks/blocking/code_rules_docstrings.py +116 -6
  19. package/hooks/blocking/code_rules_enforcer.py +4 -0
  20. package/hooks/blocking/code_rules_magic_values.py +5 -0
  21. package/hooks/blocking/code_rules_naming_collection.py +11 -6
  22. package/hooks/blocking/code_rules_shared.py +34 -0
  23. package/hooks/blocking/duplicate_rmtree_helper_blocker.py +4 -4
  24. package/hooks/blocking/test_code_rules_enforcer_docstring_prose_wall_illustration.py +197 -0
  25. package/hooks/blocking/test_code_rules_enforcer_docstring_runon_sentence.py +27 -0
  26. package/hooks/blocking/test_code_rules_enforcer_split_constants_config.py +33 -0
  27. package/hooks/blocking/test_code_rules_enforcer_split_shared.py +23 -0
  28. package/hooks/blocking/test_code_rules_magic_values.py +54 -0
  29. package/hooks/blocking/test_duplicate_rmtree_helper_blocker.py +0 -6
  30. package/hooks/blocking/test_pr_converge_bugteam_enforcer_state_tolerance.py +184 -0
  31. package/hooks/blocking/test_shared_stdin_adoption.py +5 -30
  32. package/hooks/hooks_constants/CLAUDE.md +0 -3
  33. package/hooks/hooks_constants/blocking_check_limits.py +3 -0
  34. package/hooks/hooks_constants/code_rules_path_utils_constants.py +1 -1
  35. package/hooks/hooks_constants/duplicate_rmtree_helper_blocker_constants.py +0 -1
  36. package/hooks/hooks_constants/post_tool_use_dispatcher_constants.py +0 -5
  37. package/hooks/validation/post_tool_use_dispatcher.py +1 -1
  38. package/hooks/validation/test_post_tool_use_dispatcher.py +51 -35
  39. package/hooks/workflow/CLAUDE.md +2 -8
  40. package/package.json +1 -1
  41. package/rules/CLAUDE.md +1 -1
  42. package/rules/plain-illustrative-docstrings.md +35 -1
  43. package/skills/CLAUDE.md +6 -1
  44. package/skills/autoconverge/SKILL.md +38 -57
  45. package/skills/autoconverge/reference/closing-report.md +6 -6
  46. package/skills/autoconverge/reference/convergence.md +17 -15
  47. package/skills/autoconverge/reference/gotchas.md +6 -3
  48. package/skills/autoconverge/workflow/autoconverge_report_constants/render_report_constants.py +2 -9
  49. package/skills/autoconverge/workflow/converge.contract.test.mjs +87 -13
  50. package/skills/autoconverge/workflow/converge.copilot-gate.test.mjs +1 -1
  51. package/skills/autoconverge/workflow/converge.merge-conflict.test.mjs +16 -9
  52. package/skills/autoconverge/workflow/converge.mjs +70 -73
  53. package/skills/autoconverge/workflow/render_report.py +7 -11
  54. package/skills/bugteam/CLAUDE.md +1 -1
  55. package/skills/bugteam/PROMPTS.md +7 -6
  56. package/skills/bugteam/SKILL.md +25 -72
  57. package/skills/bugteam/reference/CLAUDE.md +1 -3
  58. package/skills/bugteam/reference/README.md +1 -1
  59. package/skills/bugteam/reference/audit-and-teammates.md +1 -1
  60. package/skills/bugteam/reference/obstacles/fix-publish-summary.md +1 -1
  61. package/skills/bugteam/reference/team-setup.md +8 -7
  62. package/skills/bugteam/scripts/CLAUDE.md +0 -6
  63. package/skills/bugteam/scripts/README.md +0 -4
  64. package/skills/bugteam/scripts/bugteam_scripts_constants/CLAUDE.md +0 -1
  65. package/skills/code/SKILL.md +2 -0
  66. package/skills/copilot-review/CLAUDE.md +1 -1
  67. package/skills/copilot-review/SKILL.md +25 -23
  68. package/skills/findbugs/CLAUDE.md +2 -2
  69. package/skills/findbugs/SKILL.md +22 -83
  70. package/skills/fixbugs/SKILL.md +2 -4
  71. package/skills/log-audit/CLAUDE.md +20 -0
  72. package/skills/log-audit/SKILL.md +68 -0
  73. package/skills/log-audit/reference/CLAUDE.md +9 -0
  74. package/skills/log-audit/reference/charter.md +52 -0
  75. package/skills/log-audit/scripts/CLAUDE.md +27 -0
  76. package/skills/log-audit/scripts/cluster_recurrences.py +261 -0
  77. package/skills/log-audit/scripts/collect_log_window.py +199 -0
  78. package/skills/log-audit/scripts/log_audit_constants/CLAUDE.md +12 -0
  79. package/skills/log-audit/scripts/log_audit_constants/cluster_recurrences_constants.py +23 -0
  80. package/skills/log-audit/scripts/log_audit_constants/collect_log_window_constants.py +24 -0
  81. package/skills/log-audit/scripts/log_audit_constants/mine_copilot_findings_constants.py +49 -0
  82. package/skills/log-audit/scripts/mine_copilot_findings.py +302 -0
  83. package/skills/log-audit/scripts/test_cluster_recurrences.py +160 -0
  84. package/skills/log-audit/scripts/test_collect_log_window.py +111 -0
  85. package/skills/log-audit/scripts/test_mine_copilot_findings.py +126 -0
  86. package/skills/monitor-open-prs/SKILL.md +2 -2
  87. package/skills/post-audit-findings/SKILL.md +84 -0
  88. package/skills/pr-converge/CLAUDE.md +2 -0
  89. package/skills/pr-converge/SKILL.md +72 -59
  90. package/skills/pr-converge/reference/CLAUDE.md +1 -1
  91. package/skills/pr-converge/reference/convergence-gates.md +16 -19
  92. package/skills/pr-converge/reference/examples.md +5 -5
  93. package/skills/pr-converge/reference/fix-protocol.md +16 -43
  94. package/skills/pr-converge/reference/obstacles/fix-publish-summary.md +1 -1
  95. package/skills/pr-converge/reference/per-tick.md +24 -45
  96. package/skills/pr-converge/reference/state-schema.md +15 -0
  97. package/skills/pr-converge/scripts/README.md +3 -5
  98. package/skills/pr-fix-protocol/SKILL.md +70 -0
  99. package/skills/pr-loop-lifecycle/SKILL.md +73 -0
  100. package/skills/{bugteam → pr-loop-lifecycle}/reference/teardown-publish-permissions.md +22 -24
  101. package/skills/pr-scope-resolve/SKILL.md +48 -0
  102. package/skills/qbug/CLAUDE.md +4 -4
  103. package/skills/qbug/SKILL.md +46 -144
  104. package/skills/qbug/test_qbug_skill_audit_schema.py +2 -2
  105. package/skills/qbug/test_qbug_skill_post_fix_audit.py +1 -1
  106. package/skills/reviewer-gates/SKILL.md +96 -0
  107. package/skills/session-log/CLAUDE.md +7 -7
  108. package/skills/session-log/SKILL.md +27 -44
  109. package/skills/test_markdown_link_integrity.py +103 -0
  110. package/commands/doc-gist.md +0 -16
  111. package/hooks/blocking/_md_to_html_blocker_test_support.py +0 -65
  112. package/hooks/blocking/conftest.py +0 -30
  113. package/hooks/blocking/md_path_exemptions.py +0 -224
  114. package/hooks/blocking/md_to_html_blocker.py +0 -155
  115. package/hooks/blocking/test_md_to_html_blocker_exemptions.py +0 -434
  116. package/hooks/blocking/test_md_to_html_blocker_extensions.py +0 -157
  117. package/hooks/blocking/test_md_to_html_blocker_path_resolution.py +0 -336
  118. package/hooks/hooks_constants/doc_gist_auto_publish_constants.py +0 -18
  119. package/hooks/hooks_constants/html_companion_constants.py +0 -20
  120. package/hooks/hooks_constants/md_to_html_blocker_constants.py +0 -76
  121. package/hooks/hooks_constants/test_md_to_html_blocker_constants.py +0 -125
  122. package/hooks/workflow/doc_gist_auto_publish.py +0 -144
  123. package/hooks/workflow/md_to_html_companion.py +0 -358
  124. package/hooks/workflow/test_doc_gist_auto_publish.py +0 -117
  125. package/hooks/workflow/test_md_to_html_companion.py +0 -613
  126. package/skills/bugteam/reference/audit-contract.md +0 -163
  127. package/skills/bugteam/scripts/_bugteam_permissions_common.py +0 -455
  128. package/skills/bugteam/scripts/bugteam_scripts_constants/claude_permissions_common_constants.py +0 -69
  129. package/skills/bugteam/scripts/grant_project_claude_permissions.py +0 -280
  130. package/skills/bugteam/scripts/revoke_project_claude_permissions.py +0 -266
  131. package/skills/bugteam/scripts/test__bugteam_permissions_common.py +0 -160
  132. package/skills/bugteam/scripts/test_agent_config_carveout.py +0 -356
  133. package/skills/bugteam/scripts/test_bugteam_permissions_common.py +0 -140
  134. package/skills/doc-gist/CLAUDE.md +0 -25
  135. package/skills/doc-gist/SKILL.md +0 -97
  136. package/skills/doc-gist/references/CLAUDE.md +0 -9
  137. package/skills/doc-gist/references/examples/01-exploration-code-approaches.html +0 -453
  138. package/skills/doc-gist/references/examples/02-exploration-visual-designs.html +0 -515
  139. package/skills/doc-gist/references/examples/03-code-review-pr.html +0 -638
  140. package/skills/doc-gist/references/examples/04-code-understanding.html +0 -491
  141. package/skills/doc-gist/references/examples/05-design-system.html +0 -629
  142. package/skills/doc-gist/references/examples/06-component-variants.html +0 -605
  143. package/skills/doc-gist/references/examples/07-prototype-animation.html +0 -455
  144. package/skills/doc-gist/references/examples/08-prototype-interaction.html +0 -396
  145. package/skills/doc-gist/references/examples/09-slide-deck.html +0 -592
  146. package/skills/doc-gist/references/examples/10-svg-illustrations.html +0 -492
  147. package/skills/doc-gist/references/examples/11-status-report.html +0 -528
  148. package/skills/doc-gist/references/examples/12-incident-report.html +0 -596
  149. package/skills/doc-gist/references/examples/13-flowchart-diagram.html +0 -395
  150. package/skills/doc-gist/references/examples/14-research-feature-explainer.html +0 -381
  151. package/skills/doc-gist/references/examples/15-research-concept-explainer.html +0 -368
  152. package/skills/doc-gist/references/examples/16-implementation-plan.html +0 -702
  153. package/skills/doc-gist/references/examples/17-pr-writeup.html +0 -595
  154. package/skills/doc-gist/references/examples/18-editor-triage-board.html +0 -573
  155. package/skills/doc-gist/references/examples/19-editor-feature-flags.html +0 -663
  156. package/skills/doc-gist/references/examples/20-editor-prompt-tuner.html +0 -722
  157. package/skills/doc-gist/references/examples/21-decision-signoff.html +0 -546
  158. package/skills/doc-gist/references/examples/CLAUDE.md +0 -25
  159. package/skills/doc-gist/references/examples/README.md +0 -5
  160. package/skills/doc-gist/scripts/CLAUDE.md +0 -27
  161. package/skills/doc-gist/scripts/doc_gist_scripts_constants/CLAUDE.md +0 -10
  162. package/skills/doc-gist/scripts/doc_gist_scripts_constants/gist_upload_constants.py +0 -16
  163. package/skills/doc-gist/scripts/gist_upload.py +0 -177
  164. package/skills/doc-gist/scripts/test_gist_upload.py +0 -51
  165. /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