Skip to content

fix: wait for SessionStart hook in window picker flow#35

Open
hscheema1979 wants to merge 7 commits intosix-ddc:mainfrom
hscheema1979:fix/session-tracking-and-status-polling
Open

fix: wait for SessionStart hook in window picker flow#35
hscheema1979 wants to merge 7 commits intosix-ddc:mainfrom
hscheema1979:fix/session-tracking-and-status-polling

Conversation

@hscheema1979
Copy link
Copy Markdown

Summary

Fixes race condition in window picker flow where ccbot binds a new topic to an existing tmux window before the SessionStart hook has written the session_map entry.

Problem

When creating a new Telegram topic and using the window picker to select an existing tmux window:

  1. User selects window from picker
  2. ccbot immediately calls bind_thread()
  3. User sends first message to the new topic
  4. ccbot tries to forward message but gets KeyError: "Session not in session_map"

Root cause: The SessionStart hook runs asynchronously and needs time to write session_map.json. The window picker flow was calling bind_thread() immediately after window selection, without waiting for the hook to complete.

Solution

Added wait_for_session_map_entry() call in the window picker callback handler (bot.py line ~1141):

  • Waits up to 5 seconds for session_map entry to appear
  • Returns early with user-friendly error if timeout occurs
  • Logs warning for troubleshooting
  • Only affects window picker flow (auto-create flow already had this fix)

Changes

  • bot.py: Added wait_for_session_map_entry() call before bind_thread() in CB_WIN_BIND handler
  • docs/TESTING_FIX.md: Added comprehensive testing procedure

Testing

See docs/TESTING_FIX.md for detailed testing procedure.

Success criteria:

  • ✅ Window picker successfully binds to existing windows
  • ✅ No "Session not in session_map" errors
  • ✅ Topic renames to match window name
  • ✅ Pending messages are forwarded correctly
  • ✅ session_map.json contains the new binding

Related

This mirrors the fix already applied to the auto-create flow (line 1033), ensuring consistency across both session creation paths.


🤖 Generated with Claude Code

hscheema1979 and others added 3 commits February 27, 2026 09:42
- Add filter in handle_new_message to skip content_type='thinking'
- Disable status polling to prevent annoying 'Brewing'/'Forging' messages
- Status polling can be re-enabled by uncommenting lines 1545-1546

This fixes issues where:
- Internal Claude thinking blocks were being sent to Telegram
- Terminal status line updates cluttered the conversation with
  messages like 'Brewed for 1m 21s' and 'Forging…' (57s)
Covers:
- Session tracking issues (session_map.json format, cwd field)
- Status message spam (Brewing/Forging)
- Thinking messages appearing in Telegram
- Wrong session being tracked
When creating a new topic and selecting an existing tmux window via the
window picker, ccbot would bind the thread before the SessionStart hook
had time to write the session_map.json entry. This caused race condition
errors: "Session not in session_map" when forwarding the first message.

Root cause: The window picker flow (CB_WIN_BIND handler) calls
bind_thread() immediately after window selection, without waiting for
the SessionStart hook to complete. The hook runs asynchronously and
needs time to write session_map.json.

Fix: Added wait_for_session_map_entry() call after window selection
and before bind_thread(). This polls session_map.json with a 5-second
timeout, ensuring the hook completes before proceeding.

Error handling: If timeout occurs, user sees "Session not ready" message
and can retry. The failure is logged for troubleshooting.

Testing: See docs/TESTING_FIX.md for detailed testing procedure.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 960296cdba

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

src/ccbot/bot.py Outdated
logger.info("Status polling task started")
# Status polling disabled - status messages ("Brewed", "Forging") are annoying
# To re-enable, uncomment the next two lines:
# _status_poll_task = asyncio.create_task(status_poll_loop(application.bot))
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Restore status polling task startup

Commenting out _status_poll_task = asyncio.create_task(status_poll_loop(application.bot)) disables the entire status_poll_loop, not just cosmetic status text. That loop is also responsible for periodic topic-deletion detection and cleanup (unpin_all_forum_topic_messages/clear_topic_state) and stale binding pruning in src/ccbot/handlers/status_polling.py, so this change can leave orphaned bindings/windows and stop background interactive UI detection for all users after startup.

Useful? React with 👍 / 👎.

# Wait for SessionStart hook to write session_map entry
# This ensures the session is fully initialized before binding
# (fixes race condition where bind_thread executes before hook completes)
if not await session_manager.wait_for_session_map_entry(selected_wid):
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Avoid gating window picker bind on existing session_map entry

Waiting for wait_for_session_map_entry(selected_wid) before binding creates a dead-end for selectable windows that do not already have a session_map row: the picker is built from all unbound tmux windows, but this branch returns early on timeout, and the pending text that could initialize the session is only sent later after bind_thread. In that scenario, users can repeatedly select the window and always get “Session not ready,” which regresses the existing window-attach flow.

Useful? React with 👍 / 👎.

Added TrustFolder UI pattern to detect Claude Code's startup prompt:
- Top markers: "Accessing workspace:" or "Quick safety check:"
- Bottom marker: "Enter to confirm · Esc to cancel"
- Status polling now checks for interactive UIs every 1 second

This fixes the issue where new sessions stuck at the "Trust this folder"
prompt would appear frozen in Telegram, with users not knowing they
need to respond in the tmux window.

Also re-enabled status polling (was disabled due to annoying status
messages like "Brewed", "Forged").

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@six-ddc
Copy link
Copy Markdown
Owner

six-ddc commented Feb 28, 2026

Thank you for your contribution. It seems that some useless doc files have been attached. Perhaps you should consider deleting them.

…ening (Revision 1)

- Create .ultra/ directory structure (queues, routines, state, schemas)
- Set restrictive permissions: 700 for directories, 600 for state files (Fix 3)
- Add JSON schemas for domain, queue, autoloop, and routine configuration
- Schemas include validation for all required fields
- Foundation ready for ultra-domain-setup and ultra-autoloop skills
…guration

All schemas use JSON Schema Draft 07 for validation:
- domain.json: Domain configuration (identity, stack, agents, routines, quality gates)
- queue.json: Task queue structure (intake, in-progress, review, completed, failed)
- autoloop.json: Autoloop state (active status, heartbeat, cycles, health metrics)
- routine.json: Routine task configuration (schedule, command, retry policy)

Foundation complete for ultra-domain-setup and ultra-autoloop skills.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants