claude-code-tools 1.19.5__tar.gz → 1.19.6__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 (125) hide show
  1. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/PKG-INFO +1 -1
  2. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/__init__.py +1 -1
  3. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/voice_type/overlay.py +67 -66
  4. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/pyproject.toml +2 -2
  5. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/.gitignore +0 -0
  6. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/LICENSE +0 -0
  7. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/README.md +0 -0
  8. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/action_rpc.py +0 -0
  9. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/agent_tunnel/__init__.py +0 -0
  10. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/agent_tunnel/backends.py +0 -0
  11. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/agent_tunnel/cli.py +0 -0
  12. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/agent_tunnel/config.py +0 -0
  13. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/agent_tunnel/convert.py +0 -0
  14. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/agent_tunnel/discord_bot.py +0 -0
  15. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/agent_tunnel/locking.py +0 -0
  16. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/agent_tunnel/paths.py +0 -0
  17. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/agent_tunnel/registry.py +0 -0
  18. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/agent_tunnel/session.py +0 -0
  19. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/agent_tunnel/store.py +0 -0
  20. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/agent_tunnel/tmux.py +0 -0
  21. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/agent_tunnel/trust.py +0 -0
  22. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/aichat.py +0 -0
  23. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/claude_continue.py +0 -0
  24. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/codex_continue.py +0 -0
  25. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/codex_server.py +0 -0
  26. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/codex_server_cli.py +0 -0
  27. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/codex_server_fingerprint.py +0 -0
  28. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/codex_server_generation.py +0 -0
  29. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/codex_server_legacy.py +0 -0
  30. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/codex_server_models.py +0 -0
  31. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/codex_server_process.py +0 -0
  32. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/codex_server_reservation.py +0 -0
  33. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/codex_server_retry.py +0 -0
  34. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/codex_server_reuse.py +0 -0
  35. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/codex_server_state.py +0 -0
  36. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/codex_server_supervisor.py +0 -0
  37. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/codex_server_worker.py +0 -0
  38. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/config.py +0 -0
  39. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/csv2gsheet.py +0 -0
  40. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/delete_session.py +0 -0
  41. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/dotenv_vault.py +0 -0
  42. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/env_safe.py +0 -0
  43. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/export_all.py +0 -0
  44. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/export_claude_session.py +0 -0
  45. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/export_codex_session.py +0 -0
  46. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/export_session.py +0 -0
  47. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/find_claude_session.py +0 -0
  48. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/find_codex_session.py +0 -0
  49. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/find_original_session.py +0 -0
  50. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/find_session.py +0 -0
  51. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/find_trimmed_sessions.py +0 -0
  52. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/fix_session.py +0 -0
  53. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/gdoc2docx.py +0 -0
  54. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/gdoc2md.py +0 -0
  55. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/gsheet2csv.py +0 -0
  56. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/md2gdoc.py +0 -0
  57. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/msg/__init__.py +0 -0
  58. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/msg/cli.py +0 -0
  59. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/msg/hooks.py +0 -0
  60. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/msg/models.py +0 -0
  61. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/msg/prompt_detect.py +0 -0
  62. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/msg/store.py +0 -0
  63. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/msg/watcher.py +0 -0
  64. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/node_menu_ui.py +0 -0
  65. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/port_claude_noise.py +0 -0
  66. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/port_claude_to_codex.py +0 -0
  67. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/port_codex_flatten.py +0 -0
  68. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/port_codex_to_claude.py +0 -0
  69. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/port_service.py +0 -0
  70. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/resolve_session.py +0 -0
  71. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/resolve_session_names.py +0 -0
  72. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/resolve_session_render.py +0 -0
  73. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/search_index.py +0 -0
  74. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/session_lineage.py +0 -0
  75. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/session_menu.py +0 -0
  76. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/session_menu_cli.py +0 -0
  77. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/session_utils.py +0 -0
  78. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/smart_trim.py +0 -0
  79. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/smart_trim_core.py +0 -0
  80. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/tmux_cli_controller.py +0 -0
  81. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/tmux_execution_helpers.py +0 -0
  82. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/tmux_remote_controller.py +0 -0
  83. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/trim_in_place.py +0 -0
  84. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/trim_session.py +0 -0
  85. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/trim_session_claude.py +0 -0
  86. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/trim_session_codex.py +0 -0
  87. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/voice_type/__init__.py +0 -0
  88. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/voice_type/app.py +0 -0
  89. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/voice_type/cli.py +0 -0
  90. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/voice_type/config.py +0 -0
  91. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/voice_type/engine_parakeet.py +0 -0
  92. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/voice_type/engine_parakeet_mlx.py +0 -0
  93. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/voice_type/engines.py +0 -0
  94. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/voice_type/hotkey.py +0 -0
  95. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/voice_type/inject.py +0 -0
  96. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/voice_type/logic.py +0 -0
  97. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/workflow_cli.py +0 -0
  98. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/workflow_cli_contract.py +0 -0
  99. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/workflow_cli_formatting.py +0 -0
  100. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/workflow_cli_identity_policy.py +0 -0
  101. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/workflow_cli_manifest.py +0 -0
  102. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/workflow_cli_projection.py +0 -0
  103. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/workflow_cli_rendering.py +0 -0
  104. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/workflow_cli_snapshots.py +0 -0
  105. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/workflow_cli_store_backends.py +0 -0
  106. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/workflow_processes.py +0 -0
  107. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/workflow_runs.py +0 -0
  108. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/workflow_store_io.py +0 -0
  109. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/claude_code_tools/workflow_validation.py +0 -0
  110. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/docs/agent-tunnel-spec.md +0 -0
  111. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/docs/claude-code-tmux-tutorials.md +0 -0
  112. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/docs/dot-zshrc.md +0 -0
  113. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/docs/find-claude-session.md +0 -0
  114. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/docs/intercom-spec.md +0 -0
  115. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/docs/lmsh.md +0 -0
  116. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/docs/local-llm-setup.md +0 -0
  117. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/docs/msg-phase-a-plan.md +0 -0
  118. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/docs/msg-plan-v2.md +0 -0
  119. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/docs/tmux-cli-instructions.md +0 -0
  120. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/docs/vault-documentation.md +0 -0
  121. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/hatch_build.py +0 -0
  122. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/node_ui/action_config.js +0 -0
  123. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/node_ui/menu.js +0 -0
  124. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/node_ui/package-lock.json +0 -0
  125. {claude_code_tools-1.19.5 → claude_code_tools-1.19.6}/node_ui/package.json +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: claude-code-tools
3
- Version: 1.19.5
3
+ Version: 1.19.6
4
4
  Summary: Collection of tools for working with Claude Code
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.11
@@ -1,3 +1,3 @@
1
1
  """Claude Code Tools - Collection of utilities for Claude Code."""
2
2
 
3
- __version__ = "1.19.5"
3
+ __version__ = "1.19.6"
@@ -21,14 +21,12 @@ from typing import Callable
21
21
  SampleFn = Callable[[], tuple[str, bool, float]]
22
22
  TickFn = Callable[[], None]
23
23
 
24
- _WIDTH = 460.0
25
- _HEIGHT = 92.0
26
- _MARGIN_BOTTOM = 110.0
27
- # Recent audio-level history (drives the local vibration envelope) and
28
- # the number of points the string is rendered with (smoothness).
29
- _HISTORY = 96
30
- _RENDER = 190
31
- _TICK_SECONDS = 0.033 # ~30 fps, smooth string motion
24
+ _WIDTH = 200.0
25
+ _HEIGHT = 150.0
26
+ _MARGIN_BOTTOM = 120.0
27
+ # Points around the blob's rim (smoothness) and frame rate.
28
+ _BLOB_POINTS = 108
29
+ _TICK_SECONDS = 0.033 # ~30 fps, smooth wobble
32
30
 
33
31
 
34
32
  def overlay_available() -> bool:
@@ -62,6 +60,7 @@ def run_overlay(sample: SampleFn, tick: TickFn, stopped: Callable[[], bool]) ->
62
60
  NSBackingStoreBuffered,
63
61
  NSBezierPath,
64
62
  NSColor,
63
+ NSGradient,
65
64
  NSMakeRect,
66
65
  NSPanel,
67
66
  NSScreen,
@@ -69,21 +68,21 @@ def run_overlay(sample: SampleFn, tick: TickFn, stopped: Callable[[], bool]) ->
69
68
  )
70
69
 
71
70
  class WaveView(AppKit.NSView): # noqa: D401
72
- """A translucent string that lies flat and vibrates with the voice.
73
-
74
- The line is pinned at both ends (like a plucked string) and its
75
- oscillation amplitude tracks the live, gain-adjusted mic level:
76
- silence reads as a near-flat line, speech makes it ripple. The
77
- recent-level history modulates the amplitude ALONG the string
78
- (and scrolls), so the shape reflects the actual audio rather
79
- than a fixed animation.
71
+ """A glowing blue blob that wobbles and swells with the voice.
72
+
73
+ A soft orb sits at the bottom of the screen: it breathes gently
74
+ in silence and, as the live gain-adjusted mic level rises, its
75
+ rim deforms (organic multi-harmonic wobble) and the whole blob
76
+ swells so its shape reflects the actual audio. Bluish, with a
77
+ radial gradient core, a rim highlight, and an outer halo for
78
+ presence.
80
79
  """
81
80
 
82
81
  def initWithFrame_(self, frame): # noqa: ANN001, ANN201, N802
83
82
  self = objc.super(WaveView, self).initWithFrame_(frame)
84
83
  if self is None:
85
84
  return None
86
- self.levels = [0.0] * _HISTORY
85
+ self.amp = 0.0 # smoothed audio level driving the wobble
87
86
  self.phase = 0.0
88
87
  self.recording = False
89
88
  return self
@@ -91,72 +90,74 @@ def run_overlay(sample: SampleFn, tick: TickFn, stopped: Callable[[], bool]) ->
91
90
  def push_(self, sample): # noqa: ANN001, ANN201, N802
92
91
  _label, recording, level = sample
93
92
  level = max(0.0, min(1.0, float(level)))
94
- # Mild smoothing so the string settles rather than jitters.
95
- prev = self.levels[-1]
96
- smoothed = prev + 0.5 * (level - prev)
97
- self.levels = self.levels[1:] + [smoothed]
98
- self.phase += 0.42 # advance the travelling wave each frame
93
+ # Fast attack, slow release: pops on speech, settles gently.
94
+ k = 0.55 if level > self.amp else 0.15
95
+ self.amp += k * (level - self.amp)
96
+ self.phase += 0.16
99
97
  self.recording = bool(recording)
100
98
  self.setNeedsDisplay_(True)
101
99
 
102
- def _string_path(self, width, mid, max_amp): # noqa: ANN001, ANN202
100
+ def _blob_path(self, cx, cy, base_r): # noqa: ANN001, ANN202
103
101
  import math
104
102
 
105
103
  path = NSBezierPath.bezierPath()
106
- path.setLineJoinStyle_(AppKit.NSLineJoinStyleRound)
107
- path.setLineCapStyle_(AppKit.NSLineCapStyleRound)
108
- n = len(self.levels)
109
- for i in range(_RENDER + 1):
110
- u = i / _RENDER # 0..1 along the string
111
- # local amplitude from the level history at this point
112
- fpos = u * (n - 1)
113
- lo = int(fpos)
114
- frac = fpos - lo
115
- lvl = self.levels[lo]
116
- if lo + 1 < n:
117
- lvl += frac * (self.levels[lo + 1] - lvl)
118
- window = math.sin(math.pi * u) # pin both ends to flat
119
- amp = lvl * max_amp * window
120
- disp = amp * (
121
- math.sin(u * 7.0 * math.pi + self.phase)
122
- + 0.4 * math.sin(u * 13.0 * math.pi - 1.7 * self.phase)
123
- ) / 1.4
124
- x = u * width
125
- y = mid + disp
104
+ wob = 0.09 + 0.42 * self.amp # rim deformation depth
105
+ breathe = 0.05 * math.sin(self.phase * 0.5)
106
+ swell = 1.0 + 0.24 * self.amp # overall growth with volume
107
+ for i in range(_BLOB_POINTS + 1):
108
+ a = 2.0 * math.pi * i / _BLOB_POINTS
109
+ shape = (
110
+ math.sin(3 * a + self.phase)
111
+ + 0.6 * math.sin(5 * a - 1.3 * self.phase)
112
+ + 0.3 * math.sin(7 * a + 1.7 * self.phase)
113
+ ) / 1.9
114
+ r = base_r * swell * (1.0 + breathe + wob * shape)
115
+ x = cx + r * math.cos(a)
116
+ y = cy + r * math.sin(a)
126
117
  if i == 0:
127
118
  path.moveToPoint_((x, y))
128
119
  else:
129
120
  path.lineToPoint_((x, y))
121
+ path.closePath()
130
122
  return path
131
123
 
132
124
  def drawRect_(self, rect): # noqa: ANN001, ANN201, N802
133
125
  b = self.bounds()
134
- # Ultra-faint rounded backdrop: just enough to read the
135
- # string over any wallpaper, without looking like a panel.
136
- pad = 6.0
137
- back = NSMakeRect(
138
- pad, pad, b.size.width - 2 * pad, b.size.height - 2 * pad
139
- )
140
- r = back.size.height / 2
141
- NSColor.colorWithCalibratedWhite_alpha_(0.0, 0.16).setFill()
142
- NSBezierPath.bezierPathWithRoundedRect_xRadius_yRadius_(
143
- back, r, r
144
- ).fill()
145
-
146
- mid = b.size.height / 2
147
- max_amp = b.size.height / 2 - 16.0
148
- path = self._string_path(b.size.width, mid, max_amp)
149
- # soft glow behind, then the crisp translucent string
126
+ cx, cy = b.size.width / 2, b.size.height / 2
127
+ base_r = min(b.size.width, b.size.height) * 0.26
128
+
129
+ # outer halo for presence
130
+ halo = self._blob_path(cx, cy, base_r * 1.28)
150
131
  NSColor.colorWithCalibratedRed_green_blue_alpha_(
151
- 1.0, 0.30, 0.26, 0.16
152
- ).setStroke()
153
- path.setLineWidth_(7.0)
154
- path.stroke()
132
+ 0.30, 0.62, 1.0, 0.20
133
+ ).setFill()
134
+ halo.fill()
135
+
136
+ # the blob: radial gradient core -> deeper blue rim
137
+ blob = self._blob_path(cx, cy, base_r)
138
+ core = NSColor.colorWithCalibratedRed_green_blue_alpha_(
139
+ 0.60, 0.85, 1.0, 0.85
140
+ )
141
+ edge = NSColor.colorWithCalibratedRed_green_blue_alpha_(
142
+ 0.16, 0.44, 0.98, 0.70
143
+ )
144
+ grad = NSGradient.alloc().initWithStartingColor_endingColor_(
145
+ core, edge
146
+ )
147
+ if grad is not None:
148
+ grad.drawInBezierPath_relativeCenterPosition_(
149
+ blob, (0.0, 0.28)
150
+ )
151
+ else: # pragma: no cover - gradient unavailable
152
+ edge.setFill()
153
+ blob.fill()
154
+
155
+ # bright rim
155
156
  NSColor.colorWithCalibratedRed_green_blue_alpha_(
156
- 1.0, 0.42, 0.38, 0.55
157
+ 0.75, 0.92, 1.0, 0.9
157
158
  ).setStroke()
158
- path.setLineWidth_(2.0)
159
- path.stroke()
159
+ blob.setLineWidth_(2.0)
160
+ blob.stroke()
160
161
 
161
162
  class Driver(AppKit.NSObject):
162
163
  """NSTimer target: samples audio, ticks the app, ends the loop.
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "claude-code-tools"
3
- version = "1.19.5"
3
+ version = "1.19.6"
4
4
  description = "Collection of tools for working with Claude Code"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -131,7 +131,7 @@ markers = [
131
131
 
132
132
  [tool.commitizen]
133
133
  name = "cz_conventional_commits"
134
- version = "1.19.5"
134
+ version = "1.19.6"
135
135
  tag_format = "v$version"
136
136
  version_files = [
137
137
  "pyproject.toml:version",