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.
- {ccgram-3.3.2 → ccgram-3.3.3}/CHANGELOG.md +9 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/PKG-INFO +1 -1
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/_version.py +2 -2
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/mailbox.py +2 -1
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/session_map.py +41 -14
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/session_monitor.py +22 -20
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/integration/conftest.py +7 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/.claude/rules/architecture.md +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/.claude/rules/message-handling.md +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/.claude/rules/topic-architecture.md +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/.claude/settings.json +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/.claude/skills/ccgram-messaging/SKILL.md +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/.claude/skills/releasing/SKILL.md +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/.env.example +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/.github/workflows/ci.yml +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/.github/workflows/release.yml +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/.gitignore +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/.markdownlint.json +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/CLAUDE.md +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/LICENSE +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/Makefile +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/README.md +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/cliff.toml +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/docs/ai-agents/README.md +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/docs/ai-agents/architecture-map.md +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/docs/ai-agents/codebase-index.md +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/docs/ai-agents/extension-and-fix-playbook.md +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/docs/ai-agents/tooling-and-tests.md +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/docs/architecture.md +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/docs/examples/toolbar.toml +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/docs/guides.md +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/docs/modularity-review/2026-05-01/modularity-review.html +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/docs/modularity-review/2026-05-01/modularity-review.md +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/docs/plans/completed/2026-04-27-telegram-ux-overhaul.md +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/docs/plans/completed/20260404-informative-output.md +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/docs/plans/completed/20260406-live-view.md +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/docs/plans/completed/20260409-enhance-telegram-ux.md +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/docs/plans/completed/20260411-send-command.md +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/docs/plans/completed/20260412-modularity-refactor.md +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/docs/plans/completed/20260413-architecture-refactor.md +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/docs/plans/completed/20260414-messaging-and-polling-refactor.md +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/docs/plans/completed/20260415-modularity-decouple.md +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/docs/plans/completed/20260416-modularity-fixes-round-3.md +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/docs/plans/completed/20260429-modularity-decouple-round-4-import-audit.md +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/docs/plans/completed/20260429-modularity-decouple-round-4.md +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/docs/plans/completed/20260429-modularity-review.html +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/docs/plans/completed/20260429-modularity-review.md +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/docs/plans/completed/20260501-modularity-decouple-round-5.md +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/docs/plans/completed/20260515-rc-feedback-and-worktree-topics.md +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/docs/plans/completed/20260522-screenshot-viewport-toolbar.md +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/docs/plans/ephemeral-tool-progress.md +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/docs/providers.md +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/llm.txt +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/pyproject.toml +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/scripts/generate_homebrew_formula.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/scripts/lint_lazy_imports.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/scripts/restart.sh +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/__init__.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/bootstrap.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/bot.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/cc_commands.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/claude_task_state.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/cli.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/command_catalog.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/config.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/doctor_cmd.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/entity_formatting.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/event_reader.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/expandable_quote.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/fonts/JetBrainsMono-Regular.ttf +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/fonts/LICENSE-JetBrainsMono.txt +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/fonts/LICENSE-NotoSansMono.txt +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/fonts/LICENSE-Symbola.txt +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/fonts/NotoSansMonoCJKsc-Regular.otf +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/fonts/Symbola.ttf +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/__init__.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/callback_data.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/callback_helpers.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/callback_registry.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/cleanup.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/command_history.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/commands/__init__.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/commands/failure_probe.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/commands/forward.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/commands/menu_sync.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/commands/status_snapshot.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/file_handler.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/hook_events.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/inline.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/interactive/__init__.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/interactive/interactive_callbacks.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/interactive/interactive_ui.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/last_reply.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/live/__init__.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/live/live_view.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/live/pane_callbacks.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/live/screenshot_callbacks.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/messaging/__init__.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/messaging/msg_broker.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/messaging/msg_delivery.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/messaging/msg_spawn.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/messaging/msg_telegram.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/messaging_pipeline/__init__.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/messaging_pipeline/message_queue.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/messaging_pipeline/message_routing.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/messaging_pipeline/message_sender.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/messaging_pipeline/message_task.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/messaging_pipeline/tool_batch.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/messaging_pipeline/topic_commands.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/polling/__init__.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/polling/periodic_tasks.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/polling/polling_coordinator.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/polling/polling_state.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/polling/polling_types.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/polling/window_tick/__init__.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/polling/window_tick/apply.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/polling/window_tick/decide.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/polling/window_tick/observe.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/reactions.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/recovery/__init__.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/recovery/history.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/recovery/history_callbacks.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/recovery/recovery_banner.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/recovery/recovery_callbacks.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/recovery/restore_command.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/recovery/resume_command.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/recovery/resume_picker.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/recovery/transcript_discovery.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/registry.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/response_builder.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/send/__init__.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/send/send_callbacks.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/send/send_command.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/send/send_security.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/sessions_dashboard.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/shell/__init__.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/shell/shell_capture.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/shell/shell_commands.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/shell/shell_context.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/shell/shell_prompt_orchestrator.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/status/__init__.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/status/rc_probe.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/status/status_bar_actions.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/status/status_bubble.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/status/topic_emoji.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/sync_command.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/text/__init__.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/text/text_handler.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/toolbar/__init__.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/toolbar/toolbar_callbacks.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/toolbar/toolbar_keyboard.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/topics/__init__.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/topics/directory_browser.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/topics/directory_callbacks.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/topics/new_command.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/topics/topic_lifecycle.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/topics/topic_orchestration.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/topics/window_callbacks.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/topics/worktree.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/upgrade.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/user_state.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/voice/__init__.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/voice/voice_callbacks.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/handlers/voice/voice_handler.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/hook.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/hooks/__init__.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/hooks/adapters.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/hooks/model.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/idle_tracker.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/last_unit.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/llm/__init__.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/llm/base.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/llm/httpx_completer.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/llm/summarizer.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/main.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/miniapp/__init__.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/miniapp/api/__init__.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/miniapp/api/terminal.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/miniapp/api/transcript.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/miniapp/auth.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/miniapp/server.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/miniapp/static/index.html +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/miniapp/static/panes.js +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/miniapp/static/terminal.js +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/miniapp/static/transcript.js +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/monitor_events.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/monitor_state.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/msg_cmd.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/msg_discovery.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/msg_skill.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/providers/__init__.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/providers/_jsonl.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/providers/base.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/providers/claude.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/providers/codex.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/providers/codex_format.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/providers/codex_status.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/providers/gemini.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/providers/pi.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/providers/pi_discovery.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/providers/pi_format.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/providers/process_detection.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/providers/registry.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/providers/shell.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/providers/shell_infra.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/screen_buffer.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/screenshot.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/session.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/session_lifecycle.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/session_query.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/session_resolver.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/spawn_request.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/state_persistence.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/status_cmd.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/telegram_client.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/telegram_draft.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/telegram_request.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/telegram_sender.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/terminal_parser.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/thread_router.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/tmux_manager.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/tool_format.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/toolbar_config.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/topic_state_registry.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/transcript_parser.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/transcript_reader.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/tts/__init__.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/tts/base.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/tts/edge.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/tts/openai.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/user_preferences.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/utils.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/whisper/__init__.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/whisper/base.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/whisper/httpx_transcriber.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/window_query.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/window_resolver.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/window_state_store.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/src/ccgram/window_view.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/_helpers.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/conftest.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/__init__.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/commands/__init__.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/commands/test_commands_subpackage_surface.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/commands/test_failure_probe.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/commands/test_forward.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/commands/test_menu_sync.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/commands/test_status_snapshot.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/conftest.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/interactive/test_interactive_ui.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/live/test_live_view.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/live/test_pane_callbacks.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/live/test_screenshot_commands.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/messaging/__init__.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/messaging/test_msg_broker.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/messaging/test_msg_delivery.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/messaging/test_msg_spawn.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/messaging/test_msg_telegram.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/messaging_pipeline/__init__.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/messaging_pipeline/test_ephemeral_tool_batch.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/messaging_pipeline/test_message_queue.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/messaging_pipeline/test_message_queue_properties.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/messaging_pipeline/test_message_routing.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/messaging_pipeline/test_message_sender.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/messaging_pipeline/test_message_task.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/messaging_pipeline/test_tool_batch.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/messaging_pipeline/test_tool_batching.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/polling/__init__.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/polling/test_pane_status_strategy.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/polling/test_polling_coordinator.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/polling/test_polling_strategies.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/polling/test_polling_types_purity.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/polling/test_status_polling.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/polling/test_tick_decision.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/polling/test_window_tick.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/polling/window_tick/__init__.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/polling/window_tick/test_decide.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/recovery/__init__.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/recovery/test_history.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/recovery/test_recovery_banner.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/recovery/test_recovery_subpackage_surface.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/recovery/test_recovery_ui.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/recovery/test_restore_command.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/recovery/test_resume_command.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/send/__init__.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/send/test_send_callbacks.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/send/test_send_command.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/send/test_send_security.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/shell/__init__.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/shell/test_shell_capture.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/shell/test_shell_commands.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/shell/test_shell_prompt_orchestrator.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/status/test_rc_probe.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/status/test_status_bar_actions.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/status/test_status_bubble.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/status/test_status_buttons.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/status/test_status_recall_callback.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/status/test_status_singleton.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/status/test_topic_emoji.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/test_bot_callbacks.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/test_callback_auth.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/test_callback_registry.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/test_cleanup.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/test_cleanup_gaps.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/test_command_history.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/test_emdash_integration.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/test_file_handler.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/test_hook_events.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/test_kill_command.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/test_last_reply.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/test_reactions.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/test_registry.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/test_response_builder.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/test_sessions_dashboard.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/test_sync_command.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/test_thinking_filter.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/text/test_text_handler.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/toolbar/test_toolbar.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/topics/__init__.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/topics/test_directory_browser.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/topics/test_directory_callbacks.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/topics/test_new_window_sync.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/topics/test_pending_creation_race.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/topics/test_selection.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/topics/test_topic_close.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/topics/test_topic_edited.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/topics/test_topic_lifecycle.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/topics/test_topic_orchestration.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/topics/test_window_callbacks.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/topics/test_worktree.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/handlers/voice/test_voice_handler.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/llm/__init__.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/llm/test_llm_completer.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/llm/test_llm_httpx.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/llm/test_llm_summarizer.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/llm/test_llm_text_completer.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/miniapp/__init__.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/miniapp/_helpers.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/miniapp/test_auth.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/miniapp/test_panes_grid.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/miniapp/test_server.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/miniapp/test_terminal_api.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/miniapp/test_transcript_api.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/providers/__init__.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/providers/conftest.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/providers/test_autodetect.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/providers/test_claude.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/providers/test_codex_format.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/providers/test_codex_status.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/providers/test_contracts.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/providers/test_jsonl_providers.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/providers/test_pi.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/providers/test_picker_capability_drift.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/providers/test_process_detection.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/providers/test_registry.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/providers/test_shell.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_bootstrap.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_cc_commands.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_claude_characterization.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_claude_task_state.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_cli.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_command_catalog.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_commands_command.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_config.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_doctor_cmd.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_entity_formatting.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_error_handler.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_event_reader.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_external_discovery.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_group_filter.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_handler_layering_invariants.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_hook.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_hook_provider_events.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_idle_tracker.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_last_unit.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_lint_lazy_imports.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_mailbox.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_monitor_state.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_msg_cmd.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_msg_discovery.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_msg_skill.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_new_command.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_query_layer_only_for_handlers.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_resilience.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_schedule_save_wiring.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_screen_buffer.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_screenshot.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_session.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_session_favorites.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_session_map_primary.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_session_map_provider_path_cross_check.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_session_map_unwired_store.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_session_monitor.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_session_monitor_events.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_spawn_request.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_state_migration.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_state_persistence.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_status_cmd.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_task_utils.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_telegram_client.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_telegram_draft.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_telegram_request.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_telegram_sender.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_terminal_parser.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_thread_router.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_tmux_autodetect.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_tool_format.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_toolbar_config.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_topic_state_registry.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_transcript_parser.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_utils.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_vim_mode.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_window_query.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_window_query_tool_calls.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_window_resolver.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_window_state_store.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/test_window_view.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/tts/__init__.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/tts/test_base.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/tts/test_edge.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/tts/test_openai.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/whisper/__init__.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/ccgram/whisper/test_transcriber.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/conftest.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/e2e/__init__.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/e2e/_helpers.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/e2e/conftest.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/e2e/test_claude_lifecycle.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/e2e/test_codex_lifecycle.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/e2e/test_gemini_lifecycle.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/e2e/test_voice_lifecycle.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/integration/test_autodetect_integration.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/integration/test_config_integration.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/integration/test_hook_pipeline.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/integration/test_import_no_cycles.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/integration/test_message_dispatch.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/integration/test_monitor_flow.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/integration/test_monitor_state_integration.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/integration/test_shell_dispatch.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/integration/test_shell_flow.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/integration/test_shell_llm_integration.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/integration/test_state_roundtrip.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/integration/test_tmux_manager.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/integration/test_toolbar_dispatch.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/integration/test_topic_name_sync.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/integration/test_whisper_integration.py +0 -0
- {ccgram-3.3.2 → ccgram-3.3.3}/tests/integration/test_worktree_flow.py +0 -0
- {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
|
|
@@ -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.
|
|
22
|
-
__version_tuple__ = version_tuple = (3, 3,
|
|
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
|
-
|
|
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
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
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
|
|
208
|
-
|
|
209
|
-
|
|
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(
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
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(
|
|
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
|
|
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
|
|
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
|
{ccgram-3.3.2 → ccgram-3.3.3}/docs/plans/completed/20260414-messaging-and-polling-refactor.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ccgram-3.3.2 → ccgram-3.3.3}/docs/plans/completed/20260515-rc-feedback-and-worktree-topics.md
RENAMED
|
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
|
|
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
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|