chore(release): SemVer 도입 및 v1.0.0 첫 공식 릴리스#85
Closed
TejNote wants to merge 35 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>
기존 fork는 pyproject.toml version=0.1.0으로 박제된 채 변경 이력만 README에 누적되어 있어 "지금 어떤 버전이고 뭐가 새로 들어갔는지" 추적이 어려웠음. SemVer + CHANGELOG.md 체계로 전환해 슬랙 공유 시 vX.Y.Z 변경분만 전달 가능하게 함.
변경
- pyproject.toml: 0.1.0 → 1.0.0
- CHANGELOG.md 신설 (Keep a Changelog 포맷)
- v1.0.0 = fork 누적분 전체 (Codex routing, skill menu, MessageBatcher,
DirectMessage queue, ccbot send CLI, status msg orphan cleanup,
spinner 무시, busy-state guard 등)
- Added/Changed/Fixed/Pending upstream merges 카테고리로 재구성
- README.md Changelog 섹션 39줄 → 3줄로 단순화 (CHANGELOG.md 링크만 유지)
정책
- MAJOR: 호환성 깨는 변경 (state.json 스키마, .env 키 rename, CLI 인자)
- MINOR: 기능 추가 (provider, hook, 명령어)
- PATCH: 버그픽스, 안정성, 문서
다음 릴리스부터는 [Unreleased] 섹션에 누적 → 릴리스 시 promote + tag.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Author
|
잘못된 repo로 PR 생성됨. TejNote/ccbot fork 내부 운영 PR입니다. 닫고 fork 쪽에 다시 생성하겠습니다. |
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.
Summary
pyproject.toml버전을0.1.0→1.0.0으로 bumpCHANGELOG.md신설 (Keep a Changelog 포맷, SemVer 기준). v1.0.0은 fork 누적분 전체를 Added/Changed/Fixed/Pending upstream merges 카테고리로 재구성README.md의 Changelog 섹션 39줄 → 3줄로 단순화 (CHANGELOG.md 링크만 유지)Why
기존 fork는
pyproject.toml version=0.1.0으로 박제된 채 변경 이력만 README에 누적되어 있어 "지금 어떤 버전이고 뭐가 새로 들어갔는지" 추적이 어려웠음. SemVer + CHANGELOG.md 체계로 전환해 슬랙 공유 시vX.Y.Z변경분만 떼서 전달할 수 있게 함.정책
다음 릴리스 워크플로
[Unreleased]섹션에 변경 누적[Unreleased]→[1.x.y] - YYYY-MM-DD로 promotepyproject.tomlbump → tagvX.Y.Z생성Test plan
cat pyproject.toml | grep version→1.0.0CHANGELOG.md렌더 확인 (GitHub 미리보기)v1.0.0git tag 생성 + GitHub Release 발행🤖 Generated with Claude Code