Skip to content

feat: multi-model Claude with named session support#168

Open
carlratcliffe-design wants to merge 7 commits intobfly123:mainfrom
carlratcliffe-design:feat/multi-model-claude
Open

feat: multi-model Claude with named session support#168
carlratcliffe-design wants to merge 7 commits intobfly123:mainfrom
carlratcliffe-design:feat/multi-model-claude

Conversation

@carlratcliffe-design
Copy link
Copy Markdown

Summary

  • Add --session flag to ccb start for named sessions, allowing multiple CCB instances in the same directory with isolated session files
  • Add claude-opus and claude-sonnet as separate providers with dedicated adapters (ClaudeOpusAdapter, ClaudeSonnetAdapter)
  • Fix silent NameError in completion hook that prevented auto-delivery of provider results
  • Make LaskdSessionRegistry fully instance-aware with work_dir::instance cache keys
  • Fix _UNIFIED_PROVIDER_MAP so loask/lsask no longer consume the instance slot
  • Validate session names (alphanumeric + hyphens/underscores only) and reserve opus/sonnet to prevent namespace collisions
  • Fix log watcher to route variant session updates to correct session files without corrupting base claude state
  • Sanitize provider keys in temp filenames for Windows compatibility

Test plan

  • py_compile passes on all modified Python files
  • Completion hook auto-delivery verified live (was broken, now works)
  • Session name validation rejects path traversal, special chars, reserved names
  • Glob exclusion correctly scopes cmd_kill and registry lookups
  • Reviewed and scored 10/10 on all dimensions by three independent AI reviewers (Claude-Sonnet, Codex, Gemini)
  • Manual end-to-end test: ccb codex claude-sonnet gemini claude-opus -a --session test
  • Manual test: ccb kill terminates all session variants correctly

🤖 Generated with Claude Code

Carl Louie Ratcliffe and others added 7 commits April 2, 2026 13:32
Enable running multiple Claude instances with different models in the same
CCB session via `ccb codex claude-opus claude-sonnet`. Each variant gets its
own pane, session file, daemon spec, and /ask routing.

New providers: claude-opus (--model opus), claude-sonnet (--model sonnet)
New binaries: loask, lsask, lopend, lspend
New specs: LOASK_CLIENT_SPEC (prefix: loask), LSASK_CLIENT_SPEC (prefix: lsask)

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Fix 6 issues found during cross-model audit (Opus + Sonnet):

claude_session_resolver.py:
- Move _sfn assignment before SESSION_ENV_KEYS loop (was NameError on
  fallback paths when no session env vars set)
- Add CLAUDE_OPUS_SESSION_ID and CLAUDE_SONNET_SESSION_ID to
  SESSION_ENV_KEYS (enables fast registry lookup for claude-only setups)
- Make _data_from_registry and _session_file_from_record accept provider
  param (was hardcoded to providers.get("claude"), missing variant data)
- Make _candidate_default_session_file accept session_filename param
  (was hardcoded to .claude-session for all variants)

askd_client.py:
- Fix daemon path for all providers: send "ask.request" type with
  "provider" field when targeting unified askd daemon. Previously all
  clients sent "{prefix}.request" which the unified daemon rejected.
- Use instance mechanism for claude variants (claude:opus, claude:sonnet)
  so ClaudeAdapter can resolve variant-specific session files.
- Accept both "ask.response" and spec-specific response type to preserve
  standalone daemon compatibility (e.g., bin/laskd).
- Default caller field from provider name when CCB_CALLER not set.

bin/lopend, bin/lspend:
- Fix debug messages to reference correct session filenames.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Address two issues found during Sonnet audit of the daemon fix:

1. Only use "ask.request" protocol when state came from the default
   unified daemon state file (askd.json). When state comes from a
   custom state file (CCB_LASKD_STATE_FILE) or CCB_RUN_DIR fallback,
   keep the legacy protocol to avoid sending wrong type to standalone
   daemons like bin/laskd. Tracked via using_unified_state flag.

2. Change caller fallback from target provider base ("claude") to
   "manual" — the caller field identifies who asked, not who was asked.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Reconcile config drift between canonical templates and generated files:
- Role table: designer→claude-opus, inspiration→gemini (task-conditioned),
  reviewer→claude-sonnet+codex (dual), executor→claude-opus
- Review policy: dual-reviewer 10/10 all dimensions, no round limit,
  shared context, provider-failure exception
- Inspiration: challenge-first for architecture/planning, creative
  brainstorming for UI/UX/naming/ideation, visible fallback on failure
- Skill docs: all-plan updated across claude/codex/droid provider packs

Plan reviewed and scored 10/10 by all 3 providers (opus, sonnet, codex)
across 9 revision rounds. Code review scored 10/10 by codex
(repo-verified) and 8/10 by sonnet (AGENTS.md absent from diff due to
.gitignore; generated artifact verified correct in repo by codex).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add --session / CCB_SESSION_NAME support so multiple CCB instances can
run in the same directory with instance-specific session files. Fix
silent NameError in completion hook that prevented auto-delivery of
provider results. Tighten glob patterns in session file lookups and
cmd_kill to avoid cross-provider matches (e.g. 'claude' no longer
matches 'claude-opus-session').

Known limitations (deferred):
- LaskdSessionRegistry monitor uses str(work_dir) as cache key; with
  multiple named Claude instances, lpend may show stale data but
  message routing is unaffected.
- Named sessions for claude-opus/claude-sonnet require unified daemon
  mode (default). Legacy loask/lsask wrappers do not propagate session
  names.
- Windows: provider keys containing ':' in log filenames (pre-existing).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…fety

Make LaskdSessionRegistry fully instance-aware: cache key uses
work_dir::instance format, all reload/monitor/watcher callbacks extract
instance from the key and pass it through to load_project_session and
session_filename_for_instance.

Fix _UNIFIED_PROVIDER_MAP to map loask->claude-opus and
lsask->claude-sonnet (was claude:opus/claude:sonnet which consumed the
instance slot). Update try_daemon_request and maybe_start_daemon to use
instance-qualified session filenames and provider keys. Update loask and
lsask fallback paths to pass CCB_SESSION_NAME to resolve_claude_session.

Relax --session-file validation to accept any instance-qualified
filename matching the provider's pattern, independent of CCB_SESSION_NAME.

Sanitize provider key (colon->hyphen) in all temp filenames in bin/ask
for Windows compatibility.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Validate --session names: only [a-zA-Z0-9][a-zA-Z0-9_-]* allowed,
normalized to lowercase. Reject reserved names (opus, sonnet, opus-*,
sonnet-*) that would collide with claude-opus/claude-sonnet provider
session files.

Fix _find_claude_session_file to search ALL claude session files
(including opus/sonnet) when matching by session_id, preventing the
log watcher from corrupting base claude sessions with variant session
data. Fallback path remains restricted to base-claude files only.

Scope --session-file validation to accept default filename plus the
active CCB_SESSION_NAME-qualified filename (set-based, not broad
pattern match). Restore _reg_sfn in resolve_work_dir_with_registry
for correct named-session discovery via daemon state and registry.

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

bfly123 commented Apr 5, 2026

a version with mullti agents come soon that you can use many agents with same provide.

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