ccgram 3.3.2__tar.gz → 3.3.3__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 (448) hide show
  1. {ccgram-3.3.2 → ccgram-3.3.3}/CHANGELOG.md +9 -0
  2. {ccgram-3.3.2 → ccgram-3.3.3}/PKG-INFO +1 -1
  3. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/_version.py +2 -2
  4. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/mailbox.py +2 -1
  5. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/session_map.py +41 -14
  6. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/session_monitor.py +22 -20
  7. {ccgram-3.3.2 → ccgram-3.3.3}/tests/integration/conftest.py +7 -0
  8. {ccgram-3.3.2 → ccgram-3.3.3}/.claude/rules/architecture.md +0 -0
  9. {ccgram-3.3.2 → ccgram-3.3.3}/.claude/rules/message-handling.md +0 -0
  10. {ccgram-3.3.2 → ccgram-3.3.3}/.claude/rules/topic-architecture.md +0 -0
  11. {ccgram-3.3.2 → ccgram-3.3.3}/.claude/settings.json +0 -0
  12. {ccgram-3.3.2 → ccgram-3.3.3}/.claude/skills/ccgram-messaging/SKILL.md +0 -0
  13. {ccgram-3.3.2 → ccgram-3.3.3}/.claude/skills/releasing/SKILL.md +0 -0
  14. {ccgram-3.3.2 → ccgram-3.3.3}/.env.example +0 -0
  15. {ccgram-3.3.2 → ccgram-3.3.3}/.github/workflows/ci.yml +0 -0
  16. {ccgram-3.3.2 → ccgram-3.3.3}/.github/workflows/release.yml +0 -0
  17. {ccgram-3.3.2 → ccgram-3.3.3}/.gitignore +0 -0
  18. {ccgram-3.3.2 → ccgram-3.3.3}/.markdownlint.json +0 -0
  19. {ccgram-3.3.2 → ccgram-3.3.3}/CLAUDE.md +0 -0
  20. {ccgram-3.3.2 → ccgram-3.3.3}/LICENSE +0 -0
  21. {ccgram-3.3.2 → ccgram-3.3.3}/Makefile +0 -0
  22. {ccgram-3.3.2 → ccgram-3.3.3}/README.md +0 -0
  23. {ccgram-3.3.2 → ccgram-3.3.3}/cliff.toml +0 -0
  24. {ccgram-3.3.2 → ccgram-3.3.3}/docs/ai-agents/README.md +0 -0
  25. {ccgram-3.3.2 → ccgram-3.3.3}/docs/ai-agents/architecture-map.md +0 -0
  26. {ccgram-3.3.2 → ccgram-3.3.3}/docs/ai-agents/codebase-index.md +0 -0
  27. {ccgram-3.3.2 → ccgram-3.3.3}/docs/ai-agents/extension-and-fix-playbook.md +0 -0
  28. {ccgram-3.3.2 → ccgram-3.3.3}/docs/ai-agents/tooling-and-tests.md +0 -0
  29. {ccgram-3.3.2 → ccgram-3.3.3}/docs/architecture.md +0 -0
  30. {ccgram-3.3.2 → ccgram-3.3.3}/docs/examples/toolbar.toml +0 -0
  31. {ccgram-3.3.2 → ccgram-3.3.3}/docs/guides.md +0 -0
  32. {ccgram-3.3.2 → ccgram-3.3.3}/docs/modularity-review/2026-05-01/modularity-review.html +0 -0
  33. {ccgram-3.3.2 → ccgram-3.3.3}/docs/modularity-review/2026-05-01/modularity-review.md +0 -0
  34. {ccgram-3.3.2 → ccgram-3.3.3}/docs/plans/completed/2026-04-27-telegram-ux-overhaul.md +0 -0
  35. {ccgram-3.3.2 → ccgram-3.3.3}/docs/plans/completed/20260404-informative-output.md +0 -0
  36. {ccgram-3.3.2 → ccgram-3.3.3}/docs/plans/completed/20260406-live-view.md +0 -0
  37. {ccgram-3.3.2 → ccgram-3.3.3}/docs/plans/completed/20260409-enhance-telegram-ux.md +0 -0
  38. {ccgram-3.3.2 → ccgram-3.3.3}/docs/plans/completed/20260411-send-command.md +0 -0
  39. {ccgram-3.3.2 → ccgram-3.3.3}/docs/plans/completed/20260412-modularity-refactor.md +0 -0
  40. {ccgram-3.3.2 → ccgram-3.3.3}/docs/plans/completed/20260413-architecture-refactor.md +0 -0
  41. {ccgram-3.3.2 → ccgram-3.3.3}/docs/plans/completed/20260414-messaging-and-polling-refactor.md +0 -0
  42. {ccgram-3.3.2 → ccgram-3.3.3}/docs/plans/completed/20260415-modularity-decouple.md +0 -0
  43. {ccgram-3.3.2 → ccgram-3.3.3}/docs/plans/completed/20260416-modularity-fixes-round-3.md +0 -0
  44. {ccgram-3.3.2 → ccgram-3.3.3}/docs/plans/completed/20260429-modularity-decouple-round-4-import-audit.md +0 -0
  45. {ccgram-3.3.2 → ccgram-3.3.3}/docs/plans/completed/20260429-modularity-decouple-round-4.md +0 -0
  46. {ccgram-3.3.2 → ccgram-3.3.3}/docs/plans/completed/20260429-modularity-review.html +0 -0
  47. {ccgram-3.3.2 → ccgram-3.3.3}/docs/plans/completed/20260429-modularity-review.md +0 -0
  48. {ccgram-3.3.2 → ccgram-3.3.3}/docs/plans/completed/20260501-modularity-decouple-round-5.md +0 -0
  49. {ccgram-3.3.2 → ccgram-3.3.3}/docs/plans/completed/20260515-rc-feedback-and-worktree-topics.md +0 -0
  50. {ccgram-3.3.2 → ccgram-3.3.3}/docs/plans/completed/20260522-screenshot-viewport-toolbar.md +0 -0
  51. {ccgram-3.3.2 → ccgram-3.3.3}/docs/plans/ephemeral-tool-progress.md +0 -0
  52. {ccgram-3.3.2 → ccgram-3.3.3}/docs/providers.md +0 -0
  53. {ccgram-3.3.2 → ccgram-3.3.3}/llm.txt +0 -0
  54. {ccgram-3.3.2 → ccgram-3.3.3}/pyproject.toml +0 -0
  55. {ccgram-3.3.2 → ccgram-3.3.3}/scripts/generate_homebrew_formula.py +0 -0
  56. {ccgram-3.3.2 → ccgram-3.3.3}/scripts/lint_lazy_imports.py +0 -0
  57. {ccgram-3.3.2 → ccgram-3.3.3}/scripts/restart.sh +0 -0
  58. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/__init__.py +0 -0
  59. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/bootstrap.py +0 -0
  60. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/bot.py +0 -0
  61. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/cc_commands.py +0 -0
  62. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/claude_task_state.py +0 -0
  63. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/cli.py +0 -0
  64. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/command_catalog.py +0 -0
  65. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/config.py +0 -0
  66. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/doctor_cmd.py +0 -0
  67. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/entity_formatting.py +0 -0
  68. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/event_reader.py +0 -0
  69. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/expandable_quote.py +0 -0
  70. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/fonts/JetBrainsMono-Regular.ttf +0 -0
  71. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/fonts/LICENSE-JetBrainsMono.txt +0 -0
  72. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/fonts/LICENSE-NotoSansMono.txt +0 -0
  73. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/fonts/LICENSE-Symbola.txt +0 -0
  74. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/fonts/NotoSansMonoCJKsc-Regular.otf +0 -0
  75. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/fonts/Symbola.ttf +0 -0
  76. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/__init__.py +0 -0
  77. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/callback_data.py +0 -0
  78. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/callback_helpers.py +0 -0
  79. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/callback_registry.py +0 -0
  80. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/cleanup.py +0 -0
  81. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/command_history.py +0 -0
  82. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/commands/__init__.py +0 -0
  83. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/commands/failure_probe.py +0 -0
  84. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/commands/forward.py +0 -0
  85. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/commands/menu_sync.py +0 -0
  86. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/commands/status_snapshot.py +0 -0
  87. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/file_handler.py +0 -0
  88. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/hook_events.py +0 -0
  89. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/inline.py +0 -0
  90. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/interactive/__init__.py +0 -0
  91. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/interactive/interactive_callbacks.py +0 -0
  92. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/interactive/interactive_ui.py +0 -0
  93. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/last_reply.py +0 -0
  94. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/live/__init__.py +0 -0
  95. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/live/live_view.py +0 -0
  96. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/live/pane_callbacks.py +0 -0
  97. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/live/screenshot_callbacks.py +0 -0
  98. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/messaging/__init__.py +0 -0
  99. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/messaging/msg_broker.py +0 -0
  100. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/messaging/msg_delivery.py +0 -0
  101. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/messaging/msg_spawn.py +0 -0
  102. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/messaging/msg_telegram.py +0 -0
  103. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/messaging_pipeline/__init__.py +0 -0
  104. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/messaging_pipeline/message_queue.py +0 -0
  105. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/messaging_pipeline/message_routing.py +0 -0
  106. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/messaging_pipeline/message_sender.py +0 -0
  107. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/messaging_pipeline/message_task.py +0 -0
  108. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/messaging_pipeline/tool_batch.py +0 -0
  109. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/messaging_pipeline/topic_commands.py +0 -0
  110. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/polling/__init__.py +0 -0
  111. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/polling/periodic_tasks.py +0 -0
  112. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/polling/polling_coordinator.py +0 -0
  113. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/polling/polling_state.py +0 -0
  114. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/polling/polling_types.py +0 -0
  115. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/polling/window_tick/__init__.py +0 -0
  116. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/polling/window_tick/apply.py +0 -0
  117. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/polling/window_tick/decide.py +0 -0
  118. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/polling/window_tick/observe.py +0 -0
  119. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/reactions.py +0 -0
  120. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/recovery/__init__.py +0 -0
  121. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/recovery/history.py +0 -0
  122. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/recovery/history_callbacks.py +0 -0
  123. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/recovery/recovery_banner.py +0 -0
  124. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/recovery/recovery_callbacks.py +0 -0
  125. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/recovery/restore_command.py +0 -0
  126. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/recovery/resume_command.py +0 -0
  127. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/recovery/resume_picker.py +0 -0
  128. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/recovery/transcript_discovery.py +0 -0
  129. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/registry.py +0 -0
  130. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/response_builder.py +0 -0
  131. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/send/__init__.py +0 -0
  132. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/send/send_callbacks.py +0 -0
  133. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/send/send_command.py +0 -0
  134. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/send/send_security.py +0 -0
  135. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/sessions_dashboard.py +0 -0
  136. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/shell/__init__.py +0 -0
  137. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/shell/shell_capture.py +0 -0
  138. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/shell/shell_commands.py +0 -0
  139. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/shell/shell_context.py +0 -0
  140. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/shell/shell_prompt_orchestrator.py +0 -0
  141. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/status/__init__.py +0 -0
  142. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/status/rc_probe.py +0 -0
  143. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/status/status_bar_actions.py +0 -0
  144. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/status/status_bubble.py +0 -0
  145. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/status/topic_emoji.py +0 -0
  146. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/sync_command.py +0 -0
  147. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/text/__init__.py +0 -0
  148. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/text/text_handler.py +0 -0
  149. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/toolbar/__init__.py +0 -0
  150. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/toolbar/toolbar_callbacks.py +0 -0
  151. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/toolbar/toolbar_keyboard.py +0 -0
  152. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/topics/__init__.py +0 -0
  153. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/topics/directory_browser.py +0 -0
  154. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/topics/directory_callbacks.py +0 -0
  155. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/topics/new_command.py +0 -0
  156. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/topics/topic_lifecycle.py +0 -0
  157. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/topics/topic_orchestration.py +0 -0
  158. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/topics/window_callbacks.py +0 -0
  159. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/topics/worktree.py +0 -0
  160. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/upgrade.py +0 -0
  161. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/user_state.py +0 -0
  162. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/voice/__init__.py +0 -0
  163. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/voice/voice_callbacks.py +0 -0
  164. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/voice/voice_handler.py +0 -0
  165. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/hook.py +0 -0
  166. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/hooks/__init__.py +0 -0
  167. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/hooks/adapters.py +0 -0
  168. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/hooks/model.py +0 -0
  169. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/idle_tracker.py +0 -0
  170. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/last_unit.py +0 -0
  171. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/llm/__init__.py +0 -0
  172. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/llm/base.py +0 -0
  173. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/llm/httpx_completer.py +0 -0
  174. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/llm/summarizer.py +0 -0
  175. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/main.py +0 -0
  176. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/miniapp/__init__.py +0 -0
  177. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/miniapp/api/__init__.py +0 -0
  178. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/miniapp/api/terminal.py +0 -0
  179. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/miniapp/api/transcript.py +0 -0
  180. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/miniapp/auth.py +0 -0
  181. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/miniapp/server.py +0 -0
  182. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/miniapp/static/index.html +0 -0
  183. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/miniapp/static/panes.js +0 -0
  184. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/miniapp/static/terminal.js +0 -0
  185. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/miniapp/static/transcript.js +0 -0
  186. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/monitor_events.py +0 -0
  187. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/monitor_state.py +0 -0
  188. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/msg_cmd.py +0 -0
  189. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/msg_discovery.py +0 -0
  190. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/msg_skill.py +0 -0
  191. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/providers/__init__.py +0 -0
  192. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/providers/_jsonl.py +0 -0
  193. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/providers/base.py +0 -0
  194. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/providers/claude.py +0 -0
  195. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/providers/codex.py +0 -0
  196. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/providers/codex_format.py +0 -0
  197. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/providers/codex_status.py +0 -0
  198. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/providers/gemini.py +0 -0
  199. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/providers/pi.py +0 -0
  200. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/providers/pi_discovery.py +0 -0
  201. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/providers/pi_format.py +0 -0
  202. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/providers/process_detection.py +0 -0
  203. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/providers/registry.py +0 -0
  204. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/providers/shell.py +0 -0
  205. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/providers/shell_infra.py +0 -0
  206. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/screen_buffer.py +0 -0
  207. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/screenshot.py +0 -0
  208. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/session.py +0 -0
  209. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/session_lifecycle.py +0 -0
  210. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/session_query.py +0 -0
  211. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/session_resolver.py +0 -0
  212. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/spawn_request.py +0 -0
  213. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/state_persistence.py +0 -0
  214. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/status_cmd.py +0 -0
  215. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/telegram_client.py +0 -0
  216. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/telegram_draft.py +0 -0
  217. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/telegram_request.py +0 -0
  218. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/telegram_sender.py +0 -0
  219. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/terminal_parser.py +0 -0
  220. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/thread_router.py +0 -0
  221. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/tmux_manager.py +0 -0
  222. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/tool_format.py +0 -0
  223. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/toolbar_config.py +0 -0
  224. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/topic_state_registry.py +0 -0
  225. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/transcript_parser.py +0 -0
  226. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/transcript_reader.py +0 -0
  227. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/tts/__init__.py +0 -0
  228. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/tts/base.py +0 -0
  229. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/tts/edge.py +0 -0
  230. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/tts/openai.py +0 -0
  231. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/user_preferences.py +0 -0
  232. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/utils.py +0 -0
  233. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/whisper/__init__.py +0 -0
  234. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/whisper/base.py +0 -0
  235. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/whisper/httpx_transcriber.py +0 -0
  236. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/window_query.py +0 -0
  237. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/window_resolver.py +0 -0
  238. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/window_state_store.py +0 -0
  239. {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/window_view.py +0 -0
  240. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/_helpers.py +0 -0
  241. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/conftest.py +0 -0
  242. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/__init__.py +0 -0
  243. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/commands/__init__.py +0 -0
  244. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/commands/test_commands_subpackage_surface.py +0 -0
  245. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/commands/test_failure_probe.py +0 -0
  246. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/commands/test_forward.py +0 -0
  247. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/commands/test_menu_sync.py +0 -0
  248. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/commands/test_status_snapshot.py +0 -0
  249. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/conftest.py +0 -0
  250. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/interactive/test_interactive_ui.py +0 -0
  251. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/live/test_live_view.py +0 -0
  252. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/live/test_pane_callbacks.py +0 -0
  253. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/live/test_screenshot_commands.py +0 -0
  254. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/messaging/__init__.py +0 -0
  255. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/messaging/test_msg_broker.py +0 -0
  256. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/messaging/test_msg_delivery.py +0 -0
  257. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/messaging/test_msg_spawn.py +0 -0
  258. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/messaging/test_msg_telegram.py +0 -0
  259. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/messaging_pipeline/__init__.py +0 -0
  260. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/messaging_pipeline/test_ephemeral_tool_batch.py +0 -0
  261. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/messaging_pipeline/test_message_queue.py +0 -0
  262. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/messaging_pipeline/test_message_queue_properties.py +0 -0
  263. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/messaging_pipeline/test_message_routing.py +0 -0
  264. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/messaging_pipeline/test_message_sender.py +0 -0
  265. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/messaging_pipeline/test_message_task.py +0 -0
  266. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/messaging_pipeline/test_tool_batch.py +0 -0
  267. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/messaging_pipeline/test_tool_batching.py +0 -0
  268. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/polling/__init__.py +0 -0
  269. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/polling/test_pane_status_strategy.py +0 -0
  270. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/polling/test_polling_coordinator.py +0 -0
  271. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/polling/test_polling_strategies.py +0 -0
  272. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/polling/test_polling_types_purity.py +0 -0
  273. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/polling/test_status_polling.py +0 -0
  274. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/polling/test_tick_decision.py +0 -0
  275. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/polling/test_window_tick.py +0 -0
  276. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/polling/window_tick/__init__.py +0 -0
  277. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/polling/window_tick/test_decide.py +0 -0
  278. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/recovery/__init__.py +0 -0
  279. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/recovery/test_history.py +0 -0
  280. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/recovery/test_recovery_banner.py +0 -0
  281. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/recovery/test_recovery_subpackage_surface.py +0 -0
  282. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/recovery/test_recovery_ui.py +0 -0
  283. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/recovery/test_restore_command.py +0 -0
  284. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/recovery/test_resume_command.py +0 -0
  285. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/send/__init__.py +0 -0
  286. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/send/test_send_callbacks.py +0 -0
  287. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/send/test_send_command.py +0 -0
  288. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/send/test_send_security.py +0 -0
  289. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/shell/__init__.py +0 -0
  290. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/shell/test_shell_capture.py +0 -0
  291. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/shell/test_shell_commands.py +0 -0
  292. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/shell/test_shell_prompt_orchestrator.py +0 -0
  293. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/status/test_rc_probe.py +0 -0
  294. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/status/test_status_bar_actions.py +0 -0
  295. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/status/test_status_bubble.py +0 -0
  296. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/status/test_status_buttons.py +0 -0
  297. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/status/test_status_recall_callback.py +0 -0
  298. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/status/test_status_singleton.py +0 -0
  299. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/status/test_topic_emoji.py +0 -0
  300. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/test_bot_callbacks.py +0 -0
  301. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/test_callback_auth.py +0 -0
  302. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/test_callback_registry.py +0 -0
  303. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/test_cleanup.py +0 -0
  304. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/test_cleanup_gaps.py +0 -0
  305. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/test_command_history.py +0 -0
  306. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/test_emdash_integration.py +0 -0
  307. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/test_file_handler.py +0 -0
  308. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/test_hook_events.py +0 -0
  309. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/test_kill_command.py +0 -0
  310. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/test_last_reply.py +0 -0
  311. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/test_reactions.py +0 -0
  312. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/test_registry.py +0 -0
  313. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/test_response_builder.py +0 -0
  314. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/test_sessions_dashboard.py +0 -0
  315. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/test_sync_command.py +0 -0
  316. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/test_thinking_filter.py +0 -0
  317. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/text/test_text_handler.py +0 -0
  318. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/toolbar/test_toolbar.py +0 -0
  319. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/topics/__init__.py +0 -0
  320. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/topics/test_directory_browser.py +0 -0
  321. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/topics/test_directory_callbacks.py +0 -0
  322. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/topics/test_new_window_sync.py +0 -0
  323. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/topics/test_pending_creation_race.py +0 -0
  324. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/topics/test_selection.py +0 -0
  325. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/topics/test_topic_close.py +0 -0
  326. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/topics/test_topic_edited.py +0 -0
  327. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/topics/test_topic_lifecycle.py +0 -0
  328. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/topics/test_topic_orchestration.py +0 -0
  329. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/topics/test_window_callbacks.py +0 -0
  330. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/topics/test_worktree.py +0 -0
  331. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/voice/test_voice_handler.py +0 -0
  332. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/llm/__init__.py +0 -0
  333. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/llm/test_llm_completer.py +0 -0
  334. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/llm/test_llm_httpx.py +0 -0
  335. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/llm/test_llm_summarizer.py +0 -0
  336. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/llm/test_llm_text_completer.py +0 -0
  337. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/miniapp/__init__.py +0 -0
  338. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/miniapp/_helpers.py +0 -0
  339. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/miniapp/test_auth.py +0 -0
  340. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/miniapp/test_panes_grid.py +0 -0
  341. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/miniapp/test_server.py +0 -0
  342. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/miniapp/test_terminal_api.py +0 -0
  343. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/miniapp/test_transcript_api.py +0 -0
  344. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/providers/__init__.py +0 -0
  345. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/providers/conftest.py +0 -0
  346. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/providers/test_autodetect.py +0 -0
  347. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/providers/test_claude.py +0 -0
  348. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/providers/test_codex_format.py +0 -0
  349. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/providers/test_codex_status.py +0 -0
  350. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/providers/test_contracts.py +0 -0
  351. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/providers/test_jsonl_providers.py +0 -0
  352. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/providers/test_pi.py +0 -0
  353. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/providers/test_picker_capability_drift.py +0 -0
  354. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/providers/test_process_detection.py +0 -0
  355. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/providers/test_registry.py +0 -0
  356. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/providers/test_shell.py +0 -0
  357. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_bootstrap.py +0 -0
  358. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_cc_commands.py +0 -0
  359. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_claude_characterization.py +0 -0
  360. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_claude_task_state.py +0 -0
  361. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_cli.py +0 -0
  362. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_command_catalog.py +0 -0
  363. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_commands_command.py +0 -0
  364. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_config.py +0 -0
  365. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_doctor_cmd.py +0 -0
  366. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_entity_formatting.py +0 -0
  367. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_error_handler.py +0 -0
  368. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_event_reader.py +0 -0
  369. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_external_discovery.py +0 -0
  370. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_group_filter.py +0 -0
  371. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_handler_layering_invariants.py +0 -0
  372. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_hook.py +0 -0
  373. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_hook_provider_events.py +0 -0
  374. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_idle_tracker.py +0 -0
  375. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_last_unit.py +0 -0
  376. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_lint_lazy_imports.py +0 -0
  377. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_mailbox.py +0 -0
  378. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_monitor_state.py +0 -0
  379. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_msg_cmd.py +0 -0
  380. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_msg_discovery.py +0 -0
  381. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_msg_skill.py +0 -0
  382. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_new_command.py +0 -0
  383. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_query_layer_only_for_handlers.py +0 -0
  384. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_resilience.py +0 -0
  385. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_schedule_save_wiring.py +0 -0
  386. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_screen_buffer.py +0 -0
  387. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_screenshot.py +0 -0
  388. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_session.py +0 -0
  389. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_session_favorites.py +0 -0
  390. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_session_map_primary.py +0 -0
  391. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_session_map_provider_path_cross_check.py +0 -0
  392. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_session_map_unwired_store.py +0 -0
  393. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_session_monitor.py +0 -0
  394. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_session_monitor_events.py +0 -0
  395. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_spawn_request.py +0 -0
  396. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_state_migration.py +0 -0
  397. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_state_persistence.py +0 -0
  398. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_status_cmd.py +0 -0
  399. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_task_utils.py +0 -0
  400. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_telegram_client.py +0 -0
  401. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_telegram_draft.py +0 -0
  402. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_telegram_request.py +0 -0
  403. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_telegram_sender.py +0 -0
  404. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_terminal_parser.py +0 -0
  405. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_thread_router.py +0 -0
  406. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_tmux_autodetect.py +0 -0
  407. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_tool_format.py +0 -0
  408. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_toolbar_config.py +0 -0
  409. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_topic_state_registry.py +0 -0
  410. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_transcript_parser.py +0 -0
  411. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_utils.py +0 -0
  412. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_vim_mode.py +0 -0
  413. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_window_query.py +0 -0
  414. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_window_query_tool_calls.py +0 -0
  415. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_window_resolver.py +0 -0
  416. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_window_state_store.py +0 -0
  417. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_window_view.py +0 -0
  418. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/tts/__init__.py +0 -0
  419. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/tts/test_base.py +0 -0
  420. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/tts/test_edge.py +0 -0
  421. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/tts/test_openai.py +0 -0
  422. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/whisper/__init__.py +0 -0
  423. {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/whisper/test_transcriber.py +0 -0
  424. {ccgram-3.3.2 → ccgram-3.3.3}/tests/conftest.py +0 -0
  425. {ccgram-3.3.2 → ccgram-3.3.3}/tests/e2e/__init__.py +0 -0
  426. {ccgram-3.3.2 → ccgram-3.3.3}/tests/e2e/_helpers.py +0 -0
  427. {ccgram-3.3.2 → ccgram-3.3.3}/tests/e2e/conftest.py +0 -0
  428. {ccgram-3.3.2 → ccgram-3.3.3}/tests/e2e/test_claude_lifecycle.py +0 -0
  429. {ccgram-3.3.2 → ccgram-3.3.3}/tests/e2e/test_codex_lifecycle.py +0 -0
  430. {ccgram-3.3.2 → ccgram-3.3.3}/tests/e2e/test_gemini_lifecycle.py +0 -0
  431. {ccgram-3.3.2 → ccgram-3.3.3}/tests/e2e/test_voice_lifecycle.py +0 -0
  432. {ccgram-3.3.2 → ccgram-3.3.3}/tests/integration/test_autodetect_integration.py +0 -0
  433. {ccgram-3.3.2 → ccgram-3.3.3}/tests/integration/test_config_integration.py +0 -0
  434. {ccgram-3.3.2 → ccgram-3.3.3}/tests/integration/test_hook_pipeline.py +0 -0
  435. {ccgram-3.3.2 → ccgram-3.3.3}/tests/integration/test_import_no_cycles.py +0 -0
  436. {ccgram-3.3.2 → ccgram-3.3.3}/tests/integration/test_message_dispatch.py +0 -0
  437. {ccgram-3.3.2 → ccgram-3.3.3}/tests/integration/test_monitor_flow.py +0 -0
  438. {ccgram-3.3.2 → ccgram-3.3.3}/tests/integration/test_monitor_state_integration.py +0 -0
  439. {ccgram-3.3.2 → ccgram-3.3.3}/tests/integration/test_shell_dispatch.py +0 -0
  440. {ccgram-3.3.2 → ccgram-3.3.3}/tests/integration/test_shell_flow.py +0 -0
  441. {ccgram-3.3.2 → ccgram-3.3.3}/tests/integration/test_shell_llm_integration.py +0 -0
  442. {ccgram-3.3.2 → ccgram-3.3.3}/tests/integration/test_state_roundtrip.py +0 -0
  443. {ccgram-3.3.2 → ccgram-3.3.3}/tests/integration/test_tmux_manager.py +0 -0
  444. {ccgram-3.3.2 → ccgram-3.3.3}/tests/integration/test_toolbar_dispatch.py +0 -0
  445. {ccgram-3.3.2 → ccgram-3.3.3}/tests/integration/test_topic_name_sync.py +0 -0
  446. {ccgram-3.3.2 → ccgram-3.3.3}/tests/integration/test_whisper_integration.py +0 -0
  447. {ccgram-3.3.2 → ccgram-3.3.3}/tests/integration/test_worktree_flow.py +0 -0
  448. {ccgram-3.3.2 → ccgram-3.3.3}/uv.lock +0 -0
@@ -4,11 +4,20 @@ All notable changes to this project will be documented in this file.
4
4
 
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+ ## [3.3.3] - 2026-05-23
8
+
9
+ ### Changed
10
+ - Cut session_map.json reads + collapse repetitive poll-loop logs
11
+
7
12
  ## [3.3.2] - 2026-05-23
8
13
 
9
14
  ### Changed
10
15
  - Unify tool-call formatting + ephemeral bubble UX fixes ([#100](https://github.com/alexei-led/ccgram/pull/100))
11
16
 
17
+
18
+ ### Documentation
19
+ - Update CHANGELOG.md for v3.3.2
20
+
12
21
  ## [3.3.1] - 2026-05-22
13
22
 
14
23
  ### Added
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ccgram
3
- Version: 3.3.2
3
+ Version: 3.3.3
4
4
  Summary: CCGram — manage AI coding agents from Telegram via tmux
5
5
  Project-URL: Homepage, https://github.com/alexei-led/ccgram
6
6
  Project-URL: Repository, https://github.com/alexei-led/ccgram
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
18
18
  commit_id: str | None
19
19
  __commit_id__: str | None
20
20
 
21
- __version__ = version = '3.3.2'
22
- __version_tuple__ = version_tuple = (3, 3, 2)
21
+ __version__ = version = '3.3.3'
22
+ __version_tuple__ = version_tuple = (3, 3, 3)
23
23
 
24
24
  __commit_id__ = commit_id = None
@@ -377,7 +377,8 @@ class Mailbox:
377
377
  ]
378
378
  )
379
379
  removed = sum(self._sweep_dir(d) for d in dirs if d.is_dir())
380
- logger.debug("Sweep completed", removed=removed, window_id=window_id)
380
+ if removed:
381
+ logger.debug("Sweep completed", removed=removed, window_id=window_id)
381
382
  return removed
382
383
 
383
384
  def _sweep_dir(self, inbox_dir: Path) -> int:
@@ -42,6 +42,12 @@ logger = structlog.get_logger()
42
42
  _LEGACY_SESSION_PREFIX = "ccbot:"
43
43
  _DEFAULT_PRIMARY_SESSION_GRACE_SEC = 60.0
44
44
 
45
+ # Per-window memo of the last incoming session_id we logged a "preserve" for.
46
+ # Decision is stable across poll cycles (steady state: same nested sid arrives
47
+ # every ~1s); logging the conclusion every cycle is pure noise. Log only on
48
+ # transition — when the incoming sid we're rejecting changes.
49
+ _preserve_log_memo: dict[str, str] = {}
50
+
45
51
 
46
52
  def _primary_session_grace_sec() -> float:
47
53
  raw = os.getenv("CCGRAM_NESTED_SESSION_GRACE_SEC")
@@ -58,6 +64,24 @@ def _primary_session_grace_sec() -> float:
58
64
  return _DEFAULT_PRIMARY_SESSION_GRACE_SEC
59
65
 
60
66
 
67
+ async def read_session_map_raw() -> dict[str, Any] | None:
68
+ """Read and parse session_map.json once.
69
+
70
+ Returns the parsed dict, ``{}`` if the file does not exist, or ``None``
71
+ if read/parse failed. Caller passes the result to both
72
+ ``SessionMapSync.load_session_map`` and ``parse_session_map`` to avoid
73
+ re-reading the file twice per poll cycle.
74
+ """
75
+ if not config.session_map_file.exists():
76
+ return {}
77
+ try:
78
+ async with aiofiles.open(config.session_map_file, "r") as f:
79
+ content = await f.read()
80
+ return cast(dict[str, Any], json.loads(content))
81
+ except json.JSONDecodeError, OSError:
82
+ return None
83
+
84
+
61
85
  def _transcript_mtime(transcript_path: str) -> float | None:
62
86
  if not transcript_path:
63
87
  return None
@@ -105,12 +129,14 @@ def _prefer_existing_primary(
105
129
  if not existing_is_fresh and not existing_is_newer:
106
130
  return None
107
131
 
108
- logger.debug(
109
- "Preserving primary session for window_id %s: existing %s, incoming %s treated as nested",
110
- window_id,
111
- state.session_id,
112
- incoming_sid,
113
- )
132
+ if _preserve_log_memo.get(window_id) != incoming_sid:
133
+ _preserve_log_memo[window_id] = incoming_sid
134
+ logger.debug(
135
+ "Preserving primary session for window_id %s: existing %s, incoming %s treated as nested",
136
+ window_id,
137
+ state.session_id,
138
+ incoming_sid,
139
+ )
114
140
  return {
115
141
  "session_id": state.session_id,
116
142
  "cwd": state.cwd,
@@ -195,7 +221,7 @@ class SessionMapSync:
195
221
  # Public: async read/sync methods
196
222
  # ------------------------------------------------------------------
197
223
 
198
- async def load_session_map(self) -> None:
224
+ async def load_session_map(self, raw: dict[str, Any] | None = None) -> None:
199
225
  """Read session_map.json and update window_states with new session associations.
200
226
 
201
227
  Keys in session_map are formatted as "tmux_session:window_id" (e.g. "ccgram:@12").
@@ -203,15 +229,15 @@ class SessionMapSync:
203
229
  with "emdash-") are both processed. Emdash windows are marked as external.
204
230
  Also cleans up window_states entries not in current session_map.
205
231
  Updates window_display_names from the "window_name" field in values.
232
+
233
+ If ``raw`` is provided (e.g., by ``read_session_map_raw``), use it
234
+ directly to avoid a redundant file read. Otherwise read the file.
206
235
  """
207
- if not config.session_map_file.exists():
208
- return
209
- try:
210
- async with aiofiles.open(config.session_map_file, "r") as f:
211
- content = await f.read()
212
- session_map = json.loads(content)
213
- except (json.JSONDecodeError, OSError): # fmt: skip
236
+ if raw is None:
237
+ raw = await read_session_map_raw()
238
+ if not raw:
214
239
  return
240
+ session_map = raw
215
241
 
216
242
  prefix = f"{config.tmux_session_name}:"
217
243
  valid_wids, old_format_sids, old_format_keys, changed = (
@@ -403,6 +429,7 @@ class SessionMapSync:
403
429
  "Pruning dead session_map entry: %s (window %s)", key, window_id
404
430
  )
405
431
  del raw[key]
432
+ _preserve_log_memo.pop(window_id, None)
406
433
  if window_store.has_window(window_id):
407
434
  window_store.remove_window(window_id)
408
435
  changed_state = True
@@ -29,14 +29,13 @@ from .event_reader import read_new_events
29
29
  from .idle_tracker import IdleTracker
30
30
  from .monitor_state import MonitorState
31
31
  from .providers import get_provider_for_window, registry # noqa: F401 (used by test patches)
32
- from .session_map import parse_session_map
32
+ from .session_map import parse_session_map, read_session_map_raw
33
33
  from .session_lifecycle import session_lifecycle
34
34
  from .tmux_manager import tmux_manager
35
35
  from .monitor_events import NewMessage, NewWindowEvent, SessionInfo
36
36
  from .transcript_reader import TranscriptReader
37
37
  from .utils import task_done_callback
38
38
 
39
- import aiofiles
40
39
  import json
41
40
 
42
41
  # Re-export for backward-compatible imports from other modules
@@ -58,8 +57,6 @@ _MSG_PREVIEW_LENGTH = 80
58
57
 
59
58
  logger = structlog.get_logger()
60
59
 
61
- _SessionMapError = (json.JSONDecodeError, OSError)
62
-
63
60
 
64
61
  class SessionMonitor:
65
62
  """Monitors Claude Code sessions for new assistant messages.
@@ -245,18 +242,20 @@ class SessionMonitor:
245
242
  except _CallbackError:
246
243
  logger.exception("Hook event callback error for %s", event.event_type)
247
244
 
248
- async def _load_current_session_map(self) -> dict[str, dict[str, str]]:
249
- """Load current session_map and return window_key -> details mapping."""
250
- if config.session_map_file.exists():
251
- try:
252
- async with aiofiles.open(config.session_map_file, "r") as f:
253
- content = await f.read()
254
- raw = json.loads(content)
255
- prefix = f"{config.tmux_session_name}:"
256
- return parse_session_map(raw, prefix)
257
- except _SessionMapError:
258
- pass
259
- return {}
245
+ async def _load_current_session_map(
246
+ self, raw: dict | None = None
247
+ ) -> dict[str, dict[str, str]]:
248
+ """Load current session_map and return window_key -> details mapping.
249
+
250
+ If ``raw`` is provided (already read by the caller), parse it directly
251
+ to avoid a redundant file read. Otherwise read session_map.json.
252
+ """
253
+ if raw is None:
254
+ raw = await read_session_map_raw()
255
+ if not raw:
256
+ return {}
257
+ prefix = f"{config.tmux_session_name}:"
258
+ return parse_session_map(raw, prefix)
260
259
 
261
260
  async def _cleanup_all_stale_sessions(self) -> None:
262
261
  """Clean up all tracked sessions not in current session_map (startup)."""
@@ -275,9 +274,11 @@ class SessionMonitor:
275
274
  self._idle_tracker.clear_session(session_id)
276
275
  self.state.save_if_dirty()
277
276
 
278
- async def _detect_and_cleanup_changes(self) -> dict[str, dict[str, str]]:
277
+ async def _detect_and_cleanup_changes(
278
+ self, raw: dict | None = None
279
+ ) -> dict[str, dict[str, str]]:
279
280
  """Reconcile session_map; clean up replaced/removed sessions; fire new-window events."""
280
- current_map = await self._load_current_session_map()
281
+ current_map = await self._load_current_session_map(raw)
281
282
  result = session_lifecycle.reconcile(current_map, self._idle_tracker)
282
283
 
283
284
  for session_id in result.sessions_to_remove:
@@ -336,9 +337,10 @@ class SessionMonitor:
336
337
  while self._running:
337
338
  try:
338
339
  await self._read_hook_events()
339
- await session_map_sync.load_session_map()
340
+ raw_session_map = await read_session_map_raw()
341
+ await session_map_sync.load_session_map(raw_session_map)
340
342
 
341
- current_map = await self._detect_and_cleanup_changes()
343
+ current_map = await self._detect_and_cleanup_changes(raw_session_map)
342
344
 
343
345
  all_windows = await tmux_manager.list_windows()
344
346
  external_windows = await tmux_manager.discover_external_sessions()
@@ -11,6 +11,13 @@ from unittest.mock import AsyncMock, MagicMock
11
11
 
12
12
  import pytest
13
13
 
14
+ # Trigger SessionManager construction so the window_store / thread_router /
15
+ # session_map_sync proxies are wired before any integration test imports
16
+ # session_monitor or related modules in isolation. When the whole suite runs,
17
+ # some other test usually imports ccgram.session first; explicit import here
18
+ # guarantees per-file isolation.
19
+ import ccgram.session # noqa: F401 (import-for-side-effects)
20
+
14
21
 
15
22
  @pytest.fixture(autouse=True)
16
23
  def _default_replace_prompt_mode():
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes