capt-hook 9.2.0__tar.gz → 9.3.0__tar.gz

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 (130) hide show
  1. {capt_hook-9.2.0 → capt_hook-9.3.0}/PKG-INFO +1 -1
  2. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/cli.py +0 -4
  3. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/packs/manager.py +4 -40
  4. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/review/fix.py +6 -2
  5. {capt_hook-9.2.0 → capt_hook-9.3.0}/pyproject.toml +1 -1
  6. {capt_hook-9.2.0 → capt_hook-9.3.0}/LICENSE +0 -0
  7. {capt_hook-9.2.0 → capt_hook-9.3.0}/README.md +0 -0
  8. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/.claude-plugin/plugin.json +0 -0
  9. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/__init__.py +0 -0
  10. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/__main__.py +0 -0
  11. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/app.py +0 -0
  12. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/ast_grep.py +0 -0
  13. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/classifiers/__init__.py +0 -0
  14. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/classifiers/conductor.py +0 -0
  15. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/classifiers/droid.py +0 -0
  16. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/classifiers/native.py +0 -0
  17. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/conditions.py +0 -0
  18. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/context.py +0 -0
  19. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/contexts.py +0 -0
  20. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/decisions.py +0 -0
  21. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/dispatch.py +0 -0
  22. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/durable.py +0 -0
  23. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/events.py +0 -0
  24. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/fields.py +0 -0
  25. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/file.py +0 -0
  26. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/hooks/hooks.json +0 -0
  27. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/loader.py +0 -0
  28. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/log.py +0 -0
  29. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/once.py +0 -0
  30. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/packs/__init__.py +0 -0
  31. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/packs/fixes/__init__.py +0 -0
  32. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/packs/fixes/capt-hook.toml +0 -0
  33. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/packs/fixes/teammate_permissions.py +0 -0
  34. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/packs/general/__init__.py +0 -0
  35. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/packs/general/_lib.py +0 -0
  36. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/packs/general/capt-hook.toml +0 -0
  37. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/packs/general/commands.py +0 -0
  38. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/packs/general/comments.py +0 -0
  39. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/packs/general/detours.py +0 -0
  40. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/packs/general/docs.py +0 -0
  41. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/packs/general/models.py +0 -0
  42. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/packs/general/plans.py +0 -0
  43. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/packs/general/prompts/fragments/deliverable_rubric.md +0 -0
  44. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/packs/general/prompts/fragments/workflow_script_header.md +0 -0
  45. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/packs/general/prompts/models/implementation_spawn_nudge.md +0 -0
  46. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/packs/general/prompts/models/inline_edit_nudge.md +0 -0
  47. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/packs/general/prompts/models/prose_spawn_gate.md +0 -0
  48. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/packs/general/prompts/models/prose_workflow_nudge.md +0 -0
  49. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/packs/general/prompts/models/review_routing_spawn_nudge.md +0 -0
  50. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/packs/general/prompts/models/review_routing_workflow_nudge.md +0 -0
  51. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/packs/general/prompts/models/writing_docs_spawn_nudge.md +0 -0
  52. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/packs/general/prompts/models/writing_docs_workflow_nudge.md +0 -0
  53. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/packs/general/prompts.py +0 -0
  54. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/packs/general/review.py +0 -0
  55. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/packs/general/tasks.py +0 -0
  56. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/packs/general/tombstones.py +0 -0
  57. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/packs/go/__init__.py +0 -0
  58. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/packs/go/capt-hook.toml +0 -0
  59. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/packs/go/testing.py +0 -0
  60. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/packs/go/toolchain.py +0 -0
  61. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/packs/python/__init__.py +0 -0
  62. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/packs/python/capt-hook.toml +0 -0
  63. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/packs/python/style.py +0 -0
  64. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/packs/python/testing.py +0 -0
  65. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/packs/python/toolchain.py +0 -0
  66. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/packs/steering/__init__.py +0 -0
  67. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/packs/steering/capt-hook.toml +0 -0
  68. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/packs/steering/steering.py +0 -0
  69. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/packs/steering/teammates.py +0 -0
  70. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/primitives/__init__.py +0 -0
  71. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/primitives/commands.py +0 -0
  72. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/primitives/lint.py +0 -0
  73. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/primitives/llm.py +0 -0
  74. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/primitives/nudge.py +0 -0
  75. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/primitives/permissions.py +0 -0
  76. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/primitives/rewrite.py +0 -0
  77. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/primitives/workflow.py +0 -0
  78. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/prompt.py +0 -0
  79. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/py.typed +0 -0
  80. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/review/__init__.py +0 -0
  81. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/review/cli.py +0 -0
  82. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/review/dashboard.py +0 -0
  83. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/review/formats.py +0 -0
  84. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/review/judge.py +0 -0
  85. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/review/pipeline.py +0 -0
  86. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/review/prompts.py +0 -0
  87. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/review/repo.py +0 -0
  88. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/review/scan.py +0 -0
  89. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/review/settings.py +0 -0
  90. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/review/store.py +0 -0
  91. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/review/sync.py +0 -0
  92. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/session.py +0 -0
  93. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/settings.py +0 -0
  94. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/signals/__init__.py +0 -0
  95. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/signals/nlp.py +0 -0
  96. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/skills/authoring-hooks/SKILL.md +0 -0
  97. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/skills/authoring-hooks/references/capt-hook-api.md +0 -0
  98. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/skills/authoring-hooks/references/pattern-catalog.md +0 -0
  99. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/skills/authoring-hooks/references/pitfalls.md +0 -0
  100. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/skills/authoring-hooks/references/testing-hooks.md +0 -0
  101. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/skills/bootstrapping-hooks/SKILL.md +0 -0
  102. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/skills/scanning-sessions/SKILL.md +0 -0
  103. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/skills/scanning-sessions/references/pr-workflow.md +0 -0
  104. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/skills/scanning-sessions/references/review-cli.md +0 -0
  105. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/skills/translating-styleguides/SKILL.md +0 -0
  106. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/skills/translating-styleguides/references/llm-rule-patterns.md +0 -0
  107. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/skills/translating-styleguides/references/matcher-reference.md +0 -0
  108. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/skills/translating-styleguides/references/tier-rubric.md +0 -0
  109. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/state.py +0 -0
  110. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/style/__init__.py +0 -0
  111. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/style/ast_grep.py +0 -0
  112. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/style/matchers.py +0 -0
  113. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/style/scope.py +0 -0
  114. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/style/types.py +0 -0
  115. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/tasks.py +0 -0
  116. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/templates/example_hook.py.tmpl +0 -0
  117. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/testing/__init__.py +0 -0
  118. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/testing/helpers.py +0 -0
  119. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/testing/session_cache.py +0 -0
  120. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/testing/types.py +0 -0
  121. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/transcripts.py +0 -0
  122. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/types.py +0 -0
  123. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/util/__init__.py +0 -0
  124. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/util/automode.py +0 -0
  125. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/util/fs.py +0 -0
  126. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/util/http.py +0 -0
  127. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/util/model_cache.py +0 -0
  128. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/util/paths.py +0 -0
  129. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/util/proc.py +0 -0
  130. {capt_hook-9.2.0 → capt_hook-9.3.0}/captain_hook/util/text.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: capt-hook
3
- Version: 9.2.0
3
+ Version: 9.3.0
4
4
  Summary: Stop repeating yourself to Claude.
5
5
  Keywords: claude,claude-code,hooks,llm,agents,guardrails,cli
6
6
  Author: Yasyf Mohamedali
@@ -161,10 +161,6 @@ def review_command() -> str:
161
161
  return f"{DEFAULT_PREFIX} review run"
162
162
 
163
163
 
164
- def sibling_settings(path: Path) -> Path:
165
- return path.parent / ("settings.json" if path.name == "settings.local.json" else "settings.local.json")
166
-
167
-
168
164
  def write_settings(settings_path: Path, data: dict[str, Any]) -> None:
169
165
  settings_path.parent.mkdir(parents=True, exist_ok=True)
170
166
  tmp = settings_path.with_suffix(f"{settings_path.suffix}.tmp")
@@ -212,16 +212,6 @@ def read_entries(path: Path) -> list[PackEntry]:
212
212
  return [parse_entry(name, table) for name, table in (tomllib.loads(path.read_text()).get("packs") or {}).items()]
213
213
 
214
214
 
215
- def read_launcher(path: Path) -> str | None:
216
- match tomllib.loads(path.read_text()).get("launcher") if path.exists() else None:
217
- case None:
218
- return None
219
- case str() as launcher:
220
- return launcher
221
- case other:
222
- raise PackError(f"invalid launcher in {path}: expected a string, got {type(other).__name__}")
223
-
224
-
225
215
  def render_entry(entry: PackEntry) -> str:
226
216
  match entry:
227
217
  case BuiltinPack(name=name):
@@ -234,34 +224,8 @@ def render_entry(entry: PackEntry) -> str:
234
224
  return f'[packs.{name}]\nsource = "{source}"\ncommit = "{commit}"\n\n'
235
225
 
236
226
 
237
- def toml_basic_string(value: str) -> str:
238
- """Render ``value`` as a quoted TOML basic string, safe for non-BMP characters.
239
-
240
- ``json.dumps`` escapes chars above the BMP (emoji, rare CJK) as surrogate-pair
241
- ``\\uXXXX`` sequences, which the TOML spec rejects — ``tomllib`` then raises on the
242
- next read. This escapes only backslash, double quote, and the ``U+0000``–``U+001F`` /
243
- ``U+007F`` control chars, passing every other char through as literal UTF-8 so the
244
- value round-trips. For ASCII values without control chars the output is byte-identical
245
- to ``json.dumps``.
246
- """
247
-
248
- def escape(c: str) -> str:
249
- match c:
250
- case "\\":
251
- return "\\\\"
252
- case '"':
253
- return '\\"'
254
- case _ if ord(c) <= 0x1F or ord(c) == 0x7F:
255
- return f"\\u{ord(c):04x}"
256
- case _:
257
- return c
258
-
259
- return '"' + "".join(escape(c) for c in value) + '"'
260
-
261
-
262
- def render_packs_toml(entries: Sequence[PackEntry], launcher: str | None = None) -> str:
263
- head = "" if launcher is None else f"launcher = {toml_basic_string(launcher)}\n\n"
264
- return head + "".join(render_entry(e) for e in sorted(entries, key=lambda e: e.name))
227
+ def render_packs_toml(entries: Sequence[PackEntry]) -> str:
228
+ return "".join(render_entry(e) for e in sorted(entries, key=lambda e: e.name))
265
229
 
266
230
 
267
231
  def atomic_write(path: Path, text: str) -> None:
@@ -284,7 +248,7 @@ def atomic_write(path: Path, text: str) -> None:
284
248
  def upsert_entry(path: Path, entry: PackEntry) -> None:
285
249
  atomic_write(
286
250
  path,
287
- render_packs_toml([*(e for e in read_entries(path) if e.name != entry.name), entry], read_launcher(path)),
251
+ render_packs_toml([*(e for e in read_entries(path) if e.name != entry.name), entry]),
288
252
  )
289
253
 
290
254
 
@@ -292,7 +256,7 @@ def delete_entry(path: Path, name: str) -> None:
292
256
  entries = read_entries(path)
293
257
  if name not in {e.name for e in entries}:
294
258
  raise PackError(f"pack {name!r} is not enabled in {path}")
295
- atomic_write(path, render_packs_toml([e for e in entries if e.name != name], read_launcher(path)))
259
+ atomic_write(path, render_packs_toml([e for e in entries if e.name != name]))
296
260
 
297
261
 
298
262
  def packs_cache_root() -> Path:
@@ -143,9 +143,13 @@ def classify_marker(text: str) -> Marker | None:
143
143
 
144
144
  def fingerprint_of(event: TranscriptEvent) -> Fingerprint | None:
145
145
  match event:
146
- case AttachmentEvent(detail=HookAdditionalContext(content=content, tool_use_id=tool_use_id, hook_event=hook_event)):
146
+ case AttachmentEvent(
147
+ detail=HookAdditionalContext(content=content, tool_use_id=tool_use_id, hook_event=hook_event)
148
+ ):
147
149
  return Fingerprint(message="\n".join(content), tool_use_id=tool_use_id, event=hook_event)
148
- case AttachmentEvent(detail=HookBlockingError(blocking_error={"blockingError": blocking_error}, hook_event=hook_event)):
150
+ case AttachmentEvent(
151
+ detail=HookBlockingError(blocking_error={"blockingError": blocking_error}, hook_event=hook_event)
152
+ ):
149
153
  return Fingerprint(message=str(blocking_error), event=str(hook_event or "Stop"))
150
154
  case UserEvent(meta=meta, text=text) if meta.is_meta and text.startswith(STOP_FEEDBACK_PREFIX):
151
155
  return Fingerprint(message=text.removeprefix(STOP_FEEDBACK_PREFIX), event="Stop")
@@ -1,7 +1,7 @@
1
1
  [project]
2
2
  name = "capt-hook"
3
3
  # Inert sentinel — the real version is stamped from the release tag (uv version --frozen).
4
- version = "9.2.0"
4
+ version = "9.3.0"
5
5
  description = "Stop repeating yourself to Claude."
6
6
  readme = "README.md"
7
7
  license = "PolyForm-Noncommercial-1.0.0"
File without changes
File without changes
File without changes
File without changes