merge#87
Closed
TejNote wants to merge 40 commits into
Closed
Conversation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…pearance Claude TUI does not update its status line immediately after completing a response. Reading the terminal right after sending the response captured the previous 'thinking...' status and re-sent it as a new status message. Fix: sleep 150ms before _check_and_send_status at all 3 call sites.
…nd drops Claude TUI does not process key input during response generation. Commands sent while Claude is working were silently dropped with no feedback to user. Fix: capture pane and parse status line in send_to_window. If status contains 'esc to interrupt', return an error message instead of sending keys.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…lRegistry Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ge tracking Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… without description
…, complete file structure
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…CLI slash commands
/clear는 같은 프로세스 안에서 session_id만 리셋하기 때문에 SessionStart 훅이 재실행되지 않아 session_map.json이 갱신 안 됨. 결과: 새 세션의 JSONL이 모니터링 대상에서 빠져 텔레그램 전달 불가. _auto_detect_session_changes() 추가: - 매 폴링마다 각 window의 project dir에서 더 새로운 JSONL 확인 - 발견 시 session_map.json 자동 업데이트 - 성능 최적화: tracked JSONL이 활발히 크고 있으면 dir scan 스킵 (stat 1회로 판단), stale 시에만 glob 실행 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
CCBOT_BATCH_WINDOW > 0 일 때 batcher.flush_and_send / _timer_loop 가 safe_send 로 메시지를 직접 보내면서 message_queue worker 와 race — 결과적으로 텔레그램에 결과 응답이 먼저 도착하고 thinking/tool batch 요약이 뒤따라 도착하던 순서 역전 버그. batcher 도 enqueue_direct_message 로 큐를 통과시켜 다른 content task 와 같은 FIFO 줄에 서도록 수정. 큐 worker 가 user 별 단일 처리이므로 순서 보장. 검증: - ruff/pyright 통과 - 251 tests 통과 - ccbot 재시작 후 message queue worker 정상 시작 확인 Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ubcommand Problem: ccbot 재시작마다 이전 상태 메시지(Metamorphosing…, Baked for Ns 등)가 orphan으로 쌓여 Telegram 토픽에 메시지가 누적됨. Fix: - session.py: status_msg_ids를 state.json에 영속화 - bot.py post_init: 시작 시 orphaned 상태 메시지 일괄 삭제 - message_queue.py: send/delete/convert 시 state.json 동기화 (content 변환 시 ID 미삭제 → content 메시지 삭제되는 버그도 수정) - main.py: ccbot send 서브커맨드 디스패치 추가 Also: ~/.ccbot/.env에 CCBOT_SHOW_TOOL_CALLS=false 추가 권고 (tool_use/result 배치 제외 → 작업 중 요약 빈도 감소) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Codex topic routing now matches Claude-style Telegram flow Codex windows keep topic bindings by provider, send input through tmux paste-buffer, and surface Codex working state through a provider-specific status parser while final responses are pushed by the runtime ccbot bridge. Constraint: Preserve the existing 1 Topic = 1 Window = 1 Session contract and window_id-based routing. Rejected: Keep sending Codex pane snapshots from ccbot core | It produced noisy Telegram snapshots instead of Claude-style final responses. Confidence: high Scope-risk: moderate Directive: Runtime validation still depends on the external OMX ccbot-bridge.mjs hook for Codex turn-complete pushes. Tested: git diff --cached --check; uv run --extra dev ruff check src/ tests/; uv run --extra dev ruff format --check src/ tests/; uv run --extra dev pyright src/ccbot/; uv run --extra dev pytest (270 passed) Not-tested: MR creation and remote CI Co-authored-by: OmX <omx@oh-my-codex.dev> * Codex topic routing absorbs claude branch validation assets The Codex base branch (8773850) ships the architectural decisions — auto provider detection, Literal type hint, stale cleanup protection, bot.py / message_queue.py / hook.py integration — but lacks the validation/documentation assets developed on the claude branch (ccbot-codex-connect-by-cluade). This commit imports those assets without altering Codex base architecture. Constraint: Preserve every Codex base behavior (provider detection, session_map cleanup guard, paste-buffer composer route, polling parser); only add backward-compat, regression coverage, and design records. Rejected: Always serialize 'provider' in WindowState.to_dict | every existing state.json row would gain "provider": "claude", silently breaking grep/jq tooling and inflating storage for users on legacy state files. Rejected: Trust the first window_display_names fallback match | stale @old codex window_ids can remain after ccbot kickstart and would route ccbot send --window codex to a dead window_id — silent Telegram fail. Confidence: high Scope-risk: narrow (only WindowState serialization + send fallback guard mutate runtime; rest is docs and tests). Directive: Keep window_display_names fallback constrained to window_ids present in thread_bindings; omit default provider from to_dict; preserve claude branch's M1/M2 plan and the codex thinking pane trace as regression fixture. Imported assets: - plans/2026-05-07-codex-omx-ccbot-연동.md (M1 양방향 폐루프 design) - plans/2026-05-08-codex-thinking-status-알림-design.md (M2 spec) - plans/2026-05-08-codex-thinking-status-구현.md (M2 TDD plan) - tests/ccbot/fixtures/codex_thinking_trace.txt 3,237-line live capture-pane trace anchoring CODEX_THINKING_RE / CODEX_TOOL_RE regression coverage. Code changes: - src/ccbot/session.py — WindowState.to_dict omits provider when default ('claude'); from_dict already restores 'claude' on missing key. - src/ccbot/send.py — _resolve_routing fallback now intersects window_display_names with thread_bindings.values() so stale wids are not picked. Test deltas (+8 net): - tests/ccbot/test_session.py: +2 cases test_to_dict_omits_default_provider_for_backward_compat test_from_dict_legacy_state_defaults_to_claude - tests/ccbot/test_send.py: rebuilt as TestResolveRouting class state_file_missing_returns_none resolve_routing_by_window_name (codex base preserved) window_states_match_by_session_id fallback_to_display_names_when_window_states_empty fallback_skips_stale_window_id_not_in_thread_bindings (new guard) fallback_does_not_apply_for_session_id_only no_match_anywhere_returns_none no_thread_binding_returns_none Tested: uv run --extra dev pytest tests/ -q (278 passed); uv run --extra dev ruff check src/ tests/ (All checks passed); uv run --extra dev ruff format --check src/ tests/ (53 files formatted); uv run --extra dev pyright src/ccbot/ (0 errors, 0 warnings). Not-tested: MR creation and remote CI. Co-authored-by: claude (ccbot-codex-connect-by-cluade) Co-authored-by: codex (codex-connext-by-code, codex-connext-by-code-v2) --------- Co-authored-by: OmX <omx@oh-my-codex.dev>
…ue (#2) * fix(queue): drop immediate status enqueue after content tasks Status was being re-sent immediately after every content message via _check_and_send_status, pushing the latest answer above the status indicator. The user could not see their final answer because '⚙️ working' kept appearing below it. Delegate status display entirely to status_polling (1s interval). The answer now stays as the last visible message; status only appears in gaps longer than ~1s and is converted into the next content message via _convert_status_to_content. Removed 3 immediate _check_and_send_status calls (tool_result edit path, fallback edit path, normal content send path). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix: persist status message IDs and clean up orphans on restart Status messages were tracked in-memory only. On each ccbot restart, old status messages (Metamorphosing…, Baked for Ns, etc.) were orphaned in Telegram while new ones were created, causing them to accumulate with each restart. Fix: - session.py: add status_msg_ids field, persist to state.json - message_queue.py: call session_manager on send/delete - bot.py post_init: delete persisted status messages on startup Also adds ccbot send subcommand dispatch to main.py (from this session). Also: add CCBOT_SHOW_TOOL_CALLS=false to ~/.ccbot/.env so tool_use/ tool_result are filtered before the batcher, reducing batch summary noise. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix: clear persisted status msg ID when converting status to content _convert_status_to_content edits the Telegram message in-place to show Claude's response. The message ID is no longer a status message, but session_manager.status_msg_ids still held the old ID — causing ccbot to delete the content message on next restart. Clear the persisted ID immediately after popping from _status_msg_info, before any edit/delete attempt. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
When a turn ends but a backgrounded Bash tool is still alive, Claude Code briefly shows a spinner line like '· Sautéed for 3s · 1 shell still running' above the chrome separator. status_polling caught this as a working status and enqueued a new status message — but since the line lacks 'esc to interrupt', no further updates arrive and the message is left stale on Telegram after the background shell exits. Filter spinner lines that match the background-shell indicator pattern (/\d+ shells? still running/) and contain no 'esc to interrupt' signal — treat them as turn-complete, not as active working state. Tests cover both the filtering (1 shell / 2 shells / Generating variant) and the regression guard for genuine active working spinners. Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
상단에 fork notice 추가하여 TejNote/ccbot이 six-ddc/ccbot 의 fork임을 명확히 표시. Features 섹션을 'Upstream' / 'Fork additions' 두 그룹으로 분리해 어떤 기능이 fork 추가분인지 한눈에 보이도록 정리. Codex/OMX provider 라우팅, plugin skill menu (`/favorite`+사용 빈도 sorting), MessageBatcher, DirectMessage 큐, `ccbot send` CLI subcommand, status msg ID 영속화, parse_status_line의 background-shell spinner 차단 등 fork 추가 기능을 Fork additions 절에 항목별로 설명. 옵션 env 변수 표에도 🔱 마크로 fork-only 설정(`CCBOT_BATCH_WINDOW`, `CCBOT_SHOW_USER_MESSAGES`, `CCBOT_SHOW_TOOL_CALLS`)을 표시. File Structure 트리에 send.py / skill_registry.py / message_batcher.py 등 신규 파일과 수정된 모듈을 🔱 표시와 함께 명시. Changelog (fork) 섹션 신설 — 머지된 PR(#1, #2, #4, #5)과 주요 commit을 시간 역순으로 정리하고, 아직 fork에 반영 안 된 upstream 커밋 3건(six-ddc#67, six-ddc#73, f5ddd7f)을 'Pending upstream merges' 표로 트래킹. Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Keep a Changelog 포맷의 CHANGELOG.md 신설, pyproject.toml 0.1.0 → 1.0.0 bump, README Changelog 섹션 링크로 단순화. SemVer 정책(MAJOR/MINOR/PATCH) 도입.
upstream six-ddc/ccbot의 pending merge 3건(six-ddc#67, six-ddc#73, f5ddd7f)을 cherry-pick + 영향 받는 fork-only 테스트 1건 시그니처 갱신. pyproject.toml 1.0.0→1.0.1, CHANGELOG.md [1.0.1] 섹션 추가. 283/283 통과.
CLAUDE.md 상단에 글로벌(~/.claude/CLAUDE.md) 자동 로드 체인 + 시크릿·push 글로벌 위임 안내 추가. 관련 운영 메모리(reference_ccbot_infra, reference_ccbot_versioning, feedback_ccbot_version_bump_required) 명시. ccbot-src 수정 시 version bump 룰(feedback_ccbot_version_bump_required.md) 엄격 적용 — 코드 변경 없는 문서 보정도 patch bump 처리. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
tmux는 서버 재시작(재부팅)마다 window ID를 @0부터 재배정한다. 그래서 재부팅 전후로 @6 같은 ID가 "그대로 존재하지만 다른 창을 가리킬" 수 있다(창 추가로 ID가 한 칸씩 밀림). 기존 resolve_stale_ids는 "window_id가 live하면 무조건 신뢰"해서 ID가 가리키는 창이 바뀐 걸 감지 못하고 텔레그램 토픽을 엉뚱한 창으로 라우팅했다(과거 codex@6 토픽 → 재부팅 후 claude@6). 수정: live window의 실제 이름 ↔ 영속화된 display name을 대조(is_trustworthy) 하여 불일치 시 display name 기준으로 재매핑. window_states·thread_bindings· user_window_offsets 3곳에 동일 적용하고, persisted_name 헬퍼로 fallback을 대칭화(구형식 state.json 업그레이드 시 바인딩 유실 방지). orig_display 스냅샷으로 세 루프 간 in-place 변경 순서 의존성 제거. Constraint: thread_bindings는 window_id 기반 유지 (state.json 스키마 불변 → PATCH) Rejected: thread_binding을 window_name 기반으로 전환 → state 스키마 깨짐(MAJOR) + 동명 창 모호성, 과도 Confidence: high Tested: pytest 288 passed, ruff clean, pyright 0 errors (회귀 테스트 5건 추가) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Author
|
Sorry, this PR was opened by mistake while clicking the "Contribute" button. It's not intended for upstream. Closing it. 🙏 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
merge