cc-session-tools 3.10.3__tar.gz → 3.10.4__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.
- {cc_session_tools-3.10.3/src/cc_session_tools.egg-info → cc_session_tools-3.10.4}/PKG-INFO +1 -1
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/pyproject.toml +1 -1
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4/src/cc_session_tools.egg-info}/PKG-INFO +1 -1
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/hooks/context_window_warning.py +52 -2
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/hooks/model_info.py +12 -7
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_context_window_warning.py +96 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_model_info.py +17 -3
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/LICENSE +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/README.md +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/setup.cfg +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/__init__.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/cli/__init__.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/cli/ccd.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/cli/ccmsg.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/cli/ccr.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/cli/ccs.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/cli/ccsched.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/cli/ccst.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/cli/migrate_ccmsg.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/cli/migrate_ccsched.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/cli/migrate_sessions_db.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/cli/migrate_telemetry.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/config/hooks-bundle.json +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/config/session-tag-hook.json +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/hooks_install.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/__init__.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/bun_tools.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/claude_flags.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/claude_md_install.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/context_overrides.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/db.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/debug.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/doctor.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/doctor_mutes.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/hook_registry.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/install_sync.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/levenshtein.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/machine_identity.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/messaging/__init__.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/messaging/addressing.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/messaging/cursor.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/messaging/lock.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/messaging/message.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/messaging/move_safety.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/messaging/repository.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/messaging/retention.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/messaging/service.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/messaging/store.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/occupancy.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/paths.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/pdata/__init__.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/pdata/backup.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/pdata/classify.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/pdata/cutover.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/pdata/dump.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/pdata/formatting.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/pdata/importers.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/pdata/init_paths.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/pdata/init_service.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/pdata/manifest.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/pdata/naming.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/pdata/readiness.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/pdata/rehydrate.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/pdata/rename_group.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/pdata/reorganize.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/pdata/repository.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/pdata/resolve.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/pdata/service.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/pdata/session_output.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/pdata/store.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/pdata/sync_check.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/pdata/sync_lock.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/pdata/sync_notify.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/pdata/vector_clock.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/pdata/vector_clock_store.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/pdata/verify.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/pdata/write_log.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/picker.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/proc_lock.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/prompts.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/roots.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/rules.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/scheduler/__init__.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/scheduler/bundled_jobs.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/scheduler/cadence.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/scheduler/cursor.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/scheduler/digest.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/scheduler/due.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/scheduler/duration.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/scheduler/jobspec.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/scheduler/ledger.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/scheduler/lock.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/scheduler/notify.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/scheduler/reconcile.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/scheduler/registry.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/scheduler/runner.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/scheduler/state.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/scheduler/store.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/scheduler/surface.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/scheduler/throttle.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/scheduler/worker.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/session_gc.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/sessions.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/sessions_db.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/sessions_repair.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/shell_install.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/tasklist.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/telemetry_store.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/text_wrap.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/skills/analyse-cc-usage/SKILL.md +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/skills/clean-hook-sessions/SKILL.md +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/skills/clean-hook-sessions/scripts/clean-hook-sessions.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/skills/compact-smart/SKILL.md +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/skills/context-override/SKILL.md +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/skills/delete-sessions/SKILL.md +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/skills/delete-sessions/scripts/delete_sessions.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/skills/do-executor-critic-assessor-loop/SKILL.md +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/skills/extract-pptx/SKILL.md +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/skills/extract-pptx/scripts/extract_pptx.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/skills/extract-to-text/SKILL.md +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/skills/extract-to-text/scripts/extract_to_text.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/skills/find-claude-code-session/SKILL.md +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/skills/generate-8digit-code/SKILL.md +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/skills/generate-8digit-code/scripts/generate_8digit_code.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/skills/list-empty-sessions/SKILL.md +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/skills/list-empty-sessions/scripts/list_empty_sessions.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/skills/manage-recurring-cc-jobs-using-ccsched/SKILL.md +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/skills/move-session/SKILL.md +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/skills/move-session/hooks/sessionstart-pending-rename.sh +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/skills/move-session/scripts/cc_session_rules.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/skills/move-session/scripts/move_session.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/skills/pm-pdata-design-schema/SKILL.md +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/skills/pm-pdata-do-audit-and-prepare-to-migrate/SKILL.md +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/skills/pm-pdata-do-init/SKILL.md +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/skills/pm-pdata-do-manual-migration/SKILL.md +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/skills/pm-pdata-do-update-consuming-skills/SKILL.md +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/skills/pm-pdata-do-update-project-docs/SKILL.md +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/skills/pm-pdata-resolve-conflicts/SKILL.md +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/skills/pm-project-layout-reference/SKILL.md +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/skills/pm-update-central-files/SKILL.md +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/skills/reduce-persistent-context/CALIBRATION.md +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/skills/reduce-persistent-context/SKILL.md +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/skills/reduce-persistent-context/scripts/analyze_context.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/skills/reduce-persistent-context/scripts/duplicates.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/skills/reduce-persistent-context/scripts/measure.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/skills/reduce-persistent-context/scripts/report.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/skills/reduce-persistent-context/scripts/tokens.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/skills/reduce-persistent-context/scripts/usage.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/skills/select-agent-model/SKILL.md +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/skills/send-session-message/SKILL.md +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/skills/update-command-cache/SKILL.md +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/skills/update-command-cache/scripts/update_command_cache.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools.egg-info/SOURCES.txt +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools.egg-info/dependency_links.txt +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools.egg-info/entry_points.txt +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools.egg-info/requires.txt +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools.egg-info/top_level.txt +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/claude_code_usage/__init__.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/claude_code_usage/attribution.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/claude_code_usage/cache.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/claude_code_usage/ccusage_wrapper.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/claude_code_usage/cli.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/claude_code_usage/data/pricing.json +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/claude_code_usage/parent_inference.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/claude_code_usage/parser.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/claude_code_usage/pricing.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/claude_code_usage/query.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/claude_code_usage/report.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/claude_code_usage/schema.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/claude_code_usage/session_names.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/hooks/__init__.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/hooks/after_response.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/hooks/bash_hard_deny.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/hooks/bash_security_review.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/hooks/cache.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/hooks/catchup.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/hooks/confirm_8digit.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/hooks/last_screenshot.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/hooks/marker_allow.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/hooks/markers.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/hooks/messaging_deliver.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/hooks/normalise.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/hooks/pdata_sync.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/hooks/pending_migration.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/hooks/pending_rename.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/hooks/script_allowlist.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/hooks/session_tag.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/hooks/stats.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/hooks/telemetry.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/hooks/telemetry_query.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/hooks/telemetry_trim.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/hooks/transcript.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/hooks/worklog_guard.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_after_response.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_attribution.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_bash_hard_deny.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_bash_security_review.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_bash_security_review_allowlist.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_bun_tools.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_cache.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_cache_sqlite.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_ccr_orphans.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_ccs_emptiness.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_ccs_eta.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_ccs_list_mode.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_ccs_scope_flags.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_ccs_sentinel_sort.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_ccs_session_counts.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_ccst_bundle_discovery.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_ccst_ccsched_jobs_cli.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_ccst_cli.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_ccst_context_override_cli.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_ccst_doctor.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_ccst_gc_prune.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_ccst_gc_report.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_ccst_hook_dispatcher.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_ccst_hooks_allowlist.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_ccst_hooks_install_prune.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_ccst_hooks_install_zero_arg.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_ccst_hooks_uninstall.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_ccst_install_everything.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_ccst_machine_identity_cli.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_ccst_main_gate.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_ccst_pdata_cli.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_ccst_pdata_init_cli.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_ccst_pdata_readiness_cli.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_ccst_pdata_reconcile_cli.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_ccst_pdata_rename_group_cli.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_ccst_pdata_reorganize_cli.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_ccst_pdata_sync_cli.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_ccst_pdata_verify_cli.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_ccst_repair_sessions_cli.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_ccst_sessions_cli.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_ccst_shell_install.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_ccst_skills_install.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_ccst_skills_uninstall.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_ccst_telemetry_query.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_ccst_telemetry_trim.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_ccusage_wrapper.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_claude_flags.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_claude_md_install.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_cli.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_cli_ccd.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_cli_ccd_dry_run.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_cli_ccr.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_cli_ccs.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_cli_version.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_confirm_8digit.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_context_overrides.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_db.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_debug.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_doctor_mutes.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_empty_session.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_hook_cache.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_hooks_install.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_hooks_install_records.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_install_sync.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_last_screenshot.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_levenshtein.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_machine_identity.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_marker_allow.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_migrate_ccmsg.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_migrate_ccsched.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_migrate_sessions_db.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_migrate_telemetry.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_normalise.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_occupancy.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_parent_inference.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_parser.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_paths.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_pdata_audit_skill.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_pdata_post_migration_skills.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_pending_migration_hook.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_picker.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_pricing.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_proc_lock.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_prompts.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_query.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_report.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_roots.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_rules.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_scheduler_bundled_jobs.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_schema.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_script_allowlist.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_session_names.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_session_tag.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_sessions.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_sessions_db.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_sessions_db_migration_chain.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_sessions_repair.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_tasklist.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_telemetry.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_telemetry_store.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_text_wrap.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_transcript.py +0 -0
- {cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/tests/test_worklog_guard.py +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "cc-session-tools"
|
|
7
|
-
version = "3.10.
|
|
7
|
+
version = "3.10.4"
|
|
8
8
|
description = "Claude Code session management CLI tools (ccd, ccr, ccs, claude-code-usage, ccst) and hook library (hooks package)"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = { file = "LICENSE" }
|
|
@@ -26,6 +26,7 @@ from __future__ import annotations
|
|
|
26
26
|
|
|
27
27
|
import datetime
|
|
28
28
|
import json
|
|
29
|
+
import re
|
|
29
30
|
import sys
|
|
30
31
|
from decimal import ROUND_DOWN, Decimal
|
|
31
32
|
from pathlib import Path
|
|
@@ -155,6 +156,48 @@ def _reason(*, tokens: int, window: int, price: float, name: str, now: str, red:
|
|
|
155
156
|
)
|
|
156
157
|
|
|
157
158
|
|
|
159
|
+
REMEDIATION_HINT = (
|
|
160
|
+
"To fix: add the id to src/hooks/model_info.py in claude-code-session-tools; if ccst is just out "
|
|
161
|
+
"of date, run `uv tool upgrade cc-session-tools` (installed from PyPI with uv) or "
|
|
162
|
+
"`uv tool install --reinstall <path to your checkout>` (local checkout)."
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
_ID_DISALLOWED = re.compile(r"[^A-Za-z0-9._:<>\[\]-]")
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
def _model_phrase(model_id: str) -> str:
|
|
169
|
+
"""How the unknown model is named in the message. Characters outside the set real ids use are
|
|
170
|
+
replaced, so a corrupt or hostile transcript value cannot break the quoted lines the assistant
|
|
171
|
+
is told to echo."""
|
|
172
|
+
if not model_id:
|
|
173
|
+
return "an unknown model (no model id was recorded)"
|
|
174
|
+
return f"model `{_ID_DISALLOWED.sub('?', model_id)}`"
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
def _reason_unknown(*, tokens: int, window: int, price: float, model_id: str, now: str, red: bool) -> str:
|
|
178
|
+
"""Message for a model id missing from model_info's table: the window and price are
|
|
179
|
+
assumptions and the text says so, instead of presenting them as facts."""
|
|
180
|
+
k = _k_tokens(tokens)
|
|
181
|
+
pct = _pct_of_window(tokens, window)
|
|
182
|
+
label = _window_label(window)
|
|
183
|
+
cost = _format_cost(tokens=tokens, cache_read_price_per_mtok=price)
|
|
184
|
+
model = _model_phrase(model_id)
|
|
185
|
+
emoji = "🔴" if red else "🟠"
|
|
186
|
+
when = "when you get a natural break" if red else "whenever convenient"
|
|
187
|
+
return (
|
|
188
|
+
f"The context window has passed {k}k tokens. The session's {model} is not in ccst's model "
|
|
189
|
+
f"table, so the window size is ASSUMED to be {label} tokens; the real window may be much "
|
|
190
|
+
f"larger (1M for current models) and any percentage may be wrong. THIS IS A WARNING ONLY - "
|
|
191
|
+
f"output the two lines below at the start of your response, then end your turn as you "
|
|
192
|
+
f"normally would. Do not restart or repeat any work.\n"
|
|
193
|
+
f"'{emoji} CONTEXT ({now}): ~{k}k tokens used; window size ASSUMED ({label}) for {model} - "
|
|
194
|
+
f"the real window may be much larger, so ~{pct}% is unreliable. ~${cost}/turn assumes the "
|
|
195
|
+
f"default ${price:.2f}/MTok cache-read price. This is a nudge, not a limit - keep going; "
|
|
196
|
+
f"/compact {when}. {REMEDIATION_HINT}'\n"
|
|
197
|
+
f"'(To silence this warning for the rest of the session, run /context-override.)'"
|
|
198
|
+
)
|
|
199
|
+
|
|
200
|
+
|
|
158
201
|
def main(argv: list[str] | None = None) -> int:
|
|
159
202
|
try:
|
|
160
203
|
stdin_obj = json.loads(sys.stdin.read() or "{}")
|
|
@@ -183,11 +226,18 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
183
226
|
|
|
184
227
|
window = model_info.context_window(model_id)
|
|
185
228
|
price = model_info.cache_read_price_per_mtok(model_id)
|
|
186
|
-
name = model_info.display_name(model_id)
|
|
187
229
|
now = datetime.datetime.now().strftime("%H:%M")
|
|
188
230
|
red = tokens >= THRESHOLD_RED
|
|
189
231
|
|
|
190
|
-
|
|
232
|
+
if model_info.is_known(model_id):
|
|
233
|
+
reason = _reason(
|
|
234
|
+
tokens=tokens, window=window, price=price, name=model_info.display_name(model_id),
|
|
235
|
+
now=now, red=red,
|
|
236
|
+
)
|
|
237
|
+
else:
|
|
238
|
+
reason = _reason_unknown(
|
|
239
|
+
tokens=tokens, window=window, price=price, model_id=model_id, now=now, red=red,
|
|
240
|
+
)
|
|
191
241
|
print(json.dumps({"decision": "block", "reason": reason}))
|
|
192
242
|
return 0
|
|
193
243
|
|
|
@@ -13,11 +13,12 @@ They are not a fixed fraction of the input price: Fable 5.1 and Mythos 5.1 read
|
|
|
13
13
|
and Opus 5.5 at 0.05x, every other model here at 0.1x.
|
|
14
14
|
|
|
15
15
|
Re-check this table whenever a new model ships. A model not matched by any
|
|
16
|
-
case falls through to the default
|
|
17
|
-
|
|
18
|
-
model, so an
|
|
16
|
+
case (`is_known` is False) falls through to the default window and price
|
|
17
|
+
(200000 tokens / $0.50 per MTok) - deliberately the same window as every
|
|
18
|
+
pre-Claude-5 model, so an unknown model degrades to conservative,
|
|
19
19
|
already-correct-for-most-history behaviour rather than going quiet or firing
|
|
20
|
-
too early.
|
|
20
|
+
too early. Those defaults are assumptions, and the warning says so; only
|
|
21
|
+
`display_name` has no default (it raises KeyError for an unknown id).
|
|
21
22
|
|
|
22
23
|
Deliberately not `claude_code_usage.pricing`: that module imports pandas, too
|
|
23
24
|
heavy for a hook that runs on every Stop event. tests/test_pricing.py asserts
|
|
@@ -51,7 +52,6 @@ _NAME = {
|
|
|
51
52
|
}
|
|
52
53
|
_DEFAULT_WINDOW = 200_000
|
|
53
54
|
_DEFAULT_CACHE_READ_PRICE = 0.50
|
|
54
|
-
_DEFAULT_NAME = "an unrecognized model"
|
|
55
55
|
|
|
56
56
|
|
|
57
57
|
_DATED_SNAPSHOT = re.compile(r"(.+)-\d{8}")
|
|
@@ -60,7 +60,7 @@ _DATED_SNAPSHOT = re.compile(r"(.+)-\d{8}")
|
|
|
60
60
|
def _canonical(model_id: str) -> str:
|
|
61
61
|
"""A dated snapshot id (`<id>-YYYYMMDD`) resolves to its undated row. Applied once, and
|
|
62
62
|
only for an exactly-eight-digit suffix: any other suffix (or a snapshot of an unknown id)
|
|
63
|
-
stays
|
|
63
|
+
stays unknown. `[1m]`/`-latest` are not handled - transcripts' `message.model` never
|
|
64
64
|
carries them."""
|
|
65
65
|
match = _DATED_SNAPSHOT.fullmatch(model_id)
|
|
66
66
|
return match.group(1) if match else model_id
|
|
@@ -74,5 +74,10 @@ def cache_read_price_per_mtok(model_id: str) -> float:
|
|
|
74
74
|
return _CACHE_READ_PRICE.get(_canonical(model_id), _DEFAULT_CACHE_READ_PRICE)
|
|
75
75
|
|
|
76
76
|
|
|
77
|
+
def is_known(model_id: str) -> bool:
|
|
78
|
+
return _canonical(model_id) in _NAME
|
|
79
|
+
|
|
80
|
+
|
|
77
81
|
def display_name(model_id: str) -> str:
|
|
78
|
-
|
|
82
|
+
"""Raises KeyError for an unknown id: callers check `is_known` first."""
|
|
83
|
+
return _NAME[_canonical(model_id)]
|
|
@@ -250,3 +250,99 @@ def test_warning_still_fires_after_a_trailing_synthetic_entry(tmp_path, monkeypa
|
|
|
250
250
|
assert "~180k tokens" in reason
|
|
251
251
|
assert "Sonnet 5.5" in reason
|
|
252
252
|
assert "unrecognized" not in reason
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
def _fire(tmp_path, monkeypatch, capsys, model, tokens=162000):
|
|
256
|
+
entry = {"usage": {"input_tokens": tokens, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 0}}
|
|
257
|
+
if model is not None:
|
|
258
|
+
entry["model"] = model
|
|
259
|
+
p = tmp_path / "t.jsonl"
|
|
260
|
+
_write_transcript(p, [{"type": "assistant", "message": entry}])
|
|
261
|
+
monkeypatch.setattr(cww, "_is_overridden", lambda session_id: False)
|
|
262
|
+
rc, out = _run_main(monkeypatch, capsys, {"transcript_path": str(p), "session_id": "s1"})
|
|
263
|
+
assert rc == 0
|
|
264
|
+
return json.loads(out.out)["reason"]
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
def _assert_assumed_wording(reason: str) -> None:
|
|
268
|
+
instruction, visible = reason.split("\n")[0], reason.split("\n")[1]
|
|
269
|
+
for text in (instruction, visible):
|
|
270
|
+
assert "ASSUMED" in text
|
|
271
|
+
assert "may be much larger" in text
|
|
272
|
+
assert "200k" in text
|
|
273
|
+
assert "unreliable" in text or "may be wrong" in text
|
|
274
|
+
assert "unrecognized model" not in text
|
|
275
|
+
assert "unrecognised model" not in text
|
|
276
|
+
assert "unreliable" in visible
|
|
277
|
+
assert "assumes the default $0.50/MTok cache-read price" in visible
|
|
278
|
+
assert "~$0.08/turn" in visible
|
|
279
|
+
assert "src/hooks/model_info.py" in visible
|
|
280
|
+
assert "uv tool upgrade cc-session-tools" in visible
|
|
281
|
+
assert "uv tool install --reinstall" in visible
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
@pytest.mark.parametrize("model_id", ["claude-sonnet-9-9", "claude-sonnet-9-9-20261001"])
|
|
285
|
+
def test_unknown_model_warning_says_the_window_is_assumed_and_quotes_the_id(
|
|
286
|
+
tmp_path, monkeypatch, capsys, model_id
|
|
287
|
+
):
|
|
288
|
+
reason = _fire(tmp_path, monkeypatch, capsys, model_id)
|
|
289
|
+
_assert_assumed_wording(reason)
|
|
290
|
+
assert f"model `{model_id}`" in reason.split("\n")[0]
|
|
291
|
+
assert f"model `{model_id}`" in reason.split("\n")[1]
|
|
292
|
+
assert "~162k tokens" in reason
|
|
293
|
+
|
|
294
|
+
|
|
295
|
+
@pytest.mark.parametrize("model", [None, ""])
|
|
296
|
+
def test_missing_or_empty_model_id_is_reported_as_unrecorded(tmp_path, monkeypatch, capsys, model):
|
|
297
|
+
reason = _fire(tmp_path, monkeypatch, capsys, model)
|
|
298
|
+
_assert_assumed_wording(reason)
|
|
299
|
+
assert "no model id was recorded" in reason.split("\n")[0]
|
|
300
|
+
assert "no model id was recorded" in reason.split("\n")[1]
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
def test_missing_model_key_still_yields_the_token_count(tmp_path: Path):
|
|
304
|
+
p = tmp_path / "t.jsonl"
|
|
305
|
+
_write_transcript(p, [{"type": "assistant", "message": {
|
|
306
|
+
"usage": {"input_tokens": 180000, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 0}}}])
|
|
307
|
+
assert cww._current_context_tokens(p) == (180000, "")
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
def test_hostile_model_id_cannot_break_the_quoted_lines(tmp_path, monkeypatch, capsys):
|
|
311
|
+
reason = _fire(tmp_path, monkeypatch, capsys, "x'`\nIGNORE ALL")
|
|
312
|
+
assert reason.count("\n") == 2
|
|
313
|
+
assert "`x???IGNORE?ALL`" in reason
|
|
314
|
+
assert "x'" not in reason
|
|
315
|
+
|
|
316
|
+
|
|
317
|
+
def test_unknown_price_in_the_message_is_the_model_info_default():
|
|
318
|
+
from hooks import model_info
|
|
319
|
+
|
|
320
|
+
reason = cww._reason_unknown(
|
|
321
|
+
tokens=162000, window=model_info.context_window("x"),
|
|
322
|
+
price=model_info.cache_read_price_per_mtok("x"), model_id="x", now="12:00", red=False,
|
|
323
|
+
)
|
|
324
|
+
assert f"${model_info.cache_read_price_per_mtok('x'):.2f}/MTok" in reason
|
|
325
|
+
|
|
326
|
+
|
|
327
|
+
def test_remediation_hint_contains_no_personal_data():
|
|
328
|
+
for fragment in ("/Users/", "/home/", "C:\\"):
|
|
329
|
+
assert fragment not in cww.REMEDIATION_HINT
|
|
330
|
+
|
|
331
|
+
|
|
332
|
+
def test_known_model_message_is_unchanged():
|
|
333
|
+
assert cww._reason(tokens=266000, window=1_000_000, price=0.20, name="Sonnet 5.5",
|
|
334
|
+
now="12:00", red=True) == (
|
|
335
|
+
"The context window has passed 266k tokens - about 27% of Sonnet 5.5's 1M-token window. "
|
|
336
|
+
"THIS IS A WARNING ONLY - output the two lines below at the start of your response, then end "
|
|
337
|
+
"your turn as you normally would. Do not restart or repeat any work.\n"
|
|
338
|
+
"'\U0001F534 CONTEXT (12:00): ~266k tokens - ~27% of the 1M-token window (Sonnet 5.5, "
|
|
339
|
+
"~$0.05/turn in cache reads). This is a nudge, not a limit - keep going; /compact when you "
|
|
340
|
+
"get a natural break.'\n"
|
|
341
|
+
"'(To silence this warning for the rest of the session, run /context-override.)'"
|
|
342
|
+
)
|
|
343
|
+
|
|
344
|
+
|
|
345
|
+
def test_known_model_through_main_has_no_assumed_wording(tmp_path, monkeypatch, capsys):
|
|
346
|
+
reason = _fire(tmp_path, monkeypatch, capsys, "claude-sonnet-5-5")
|
|
347
|
+
assert "ASSUMED" not in reason
|
|
348
|
+
assert "Sonnet 5.5" in reason
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
|
|
1
3
|
from hooks import model_info
|
|
2
4
|
|
|
3
5
|
# (model id, context window, published cache-read price per MTok, display name)
|
|
@@ -28,11 +30,23 @@ def test_known_models():
|
|
|
28
30
|
def test_unrecognized_model_falls_back():
|
|
29
31
|
assert model_info.context_window("claude-nonexistent-9") == 200_000
|
|
30
32
|
assert model_info.cache_read_price_per_mtok("claude-nonexistent-9") == 0.50
|
|
31
|
-
assert model_info.
|
|
33
|
+
assert model_info.is_known("claude-nonexistent-9") is False
|
|
32
34
|
|
|
33
35
|
|
|
34
36
|
def test_empty_model_id_falls_back():
|
|
35
37
|
assert model_info.context_window("") == 200_000
|
|
38
|
+
assert model_info.is_known("") is False
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def test_known_and_dated_known_ids_are_known():
|
|
42
|
+
for model_id, *_ in CASES:
|
|
43
|
+
assert model_info.is_known(model_id) is True, model_id
|
|
44
|
+
assert model_info.is_known("claude-sonnet-5-5-20261001") is True
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def test_display_name_of_an_unknown_id_raises_rather_than_inventing_a_name():
|
|
48
|
+
with pytest.raises(KeyError):
|
|
49
|
+
model_info.display_name("claude-nonexistent-9")
|
|
36
50
|
|
|
37
51
|
|
|
38
52
|
def test_dated_snapshot_ids_resolve_like_their_family_id():
|
|
@@ -59,11 +73,11 @@ def test_unknown_dated_and_decorated_ids_stay_unrecognised():
|
|
|
59
73
|
"claude-haiku-4-5-garbage",
|
|
60
74
|
):
|
|
61
75
|
assert model_info.context_window(model_id) == 200_000, model_id
|
|
62
|
-
assert model_info.
|
|
76
|
+
assert model_info.is_known(model_id) is False, model_id
|
|
63
77
|
|
|
64
78
|
|
|
65
79
|
def test_id_that_merely_starts_with_a_known_id_is_not_recognised():
|
|
66
80
|
"""Guards against a future lazy prefix implementation (already true before the fix):
|
|
67
81
|
`claude-sonnet-5-9` must not inherit `claude-sonnet-5`'s row."""
|
|
68
82
|
assert model_info.context_window("claude-sonnet-5-9") == 200_000
|
|
69
|
-
assert model_info.
|
|
83
|
+
assert model_info.is_known("claude-sonnet-5-9") is False
|
|
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
|
{cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/cli/migrate_ccmsg.py
RENAMED
|
File without changes
|
{cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/cli/migrate_ccsched.py
RENAMED
|
File without changes
|
{cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/cli/migrate_sessions_db.py
RENAMED
|
File without changes
|
{cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/cli/migrate_telemetry.py
RENAMED
|
File without changes
|
{cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/config/hooks-bundle.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/claude_flags.py
RENAMED
|
File without changes
|
{cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/claude_md_install.py
RENAMED
|
File without changes
|
{cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/context_overrides.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/doctor_mutes.py
RENAMED
|
File without changes
|
{cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/hook_registry.py
RENAMED
|
File without changes
|
{cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/install_sync.py
RENAMED
|
File without changes
|
|
File without changes
|
{cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/machine_identity.py
RENAMED
|
File without changes
|
{cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/messaging/__init__.py
RENAMED
|
File without changes
|
{cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/messaging/addressing.py
RENAMED
|
File without changes
|
{cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/messaging/cursor.py
RENAMED
|
File without changes
|
{cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/messaging/lock.py
RENAMED
|
File without changes
|
{cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/messaging/message.py
RENAMED
|
File without changes
|
|
File without changes
|
{cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/messaging/repository.py
RENAMED
|
File without changes
|
{cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/messaging/retention.py
RENAMED
|
File without changes
|
{cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/messaging/service.py
RENAMED
|
File without changes
|
{cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/messaging/store.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/pdata/__init__.py
RENAMED
|
File without changes
|
{cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/pdata/backup.py
RENAMED
|
File without changes
|
{cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/pdata/classify.py
RENAMED
|
File without changes
|
{cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/pdata/cutover.py
RENAMED
|
File without changes
|
|
File without changes
|
{cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/pdata/formatting.py
RENAMED
|
File without changes
|
{cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/pdata/importers.py
RENAMED
|
File without changes
|
{cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/pdata/init_paths.py
RENAMED
|
File without changes
|
{cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/pdata/init_service.py
RENAMED
|
File without changes
|
{cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/pdata/manifest.py
RENAMED
|
File without changes
|
{cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/pdata/naming.py
RENAMED
|
File without changes
|
{cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/pdata/readiness.py
RENAMED
|
File without changes
|
{cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/pdata/rehydrate.py
RENAMED
|
File without changes
|
{cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/pdata/rename_group.py
RENAMED
|
File without changes
|
{cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/pdata/reorganize.py
RENAMED
|
File without changes
|
{cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/pdata/repository.py
RENAMED
|
File without changes
|
{cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/pdata/resolve.py
RENAMED
|
File without changes
|
{cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/pdata/service.py
RENAMED
|
File without changes
|
{cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/pdata/session_output.py
RENAMED
|
File without changes
|
|
File without changes
|
{cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/pdata/sync_check.py
RENAMED
|
File without changes
|
{cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/pdata/sync_lock.py
RENAMED
|
File without changes
|
{cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/pdata/sync_notify.py
RENAMED
|
File without changes
|
{cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/pdata/vector_clock.py
RENAMED
|
File without changes
|
|
File without changes
|
{cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/pdata/verify.py
RENAMED
|
File without changes
|
{cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/pdata/write_log.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/scheduler/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/scheduler/cadence.py
RENAMED
|
File without changes
|
{cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/scheduler/cursor.py
RENAMED
|
File without changes
|
{cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/scheduler/digest.py
RENAMED
|
File without changes
|
{cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/scheduler/due.py
RENAMED
|
File without changes
|
{cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/scheduler/duration.py
RENAMED
|
File without changes
|
{cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/scheduler/jobspec.py
RENAMED
|
File without changes
|
{cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/scheduler/ledger.py
RENAMED
|
File without changes
|
{cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/scheduler/lock.py
RENAMED
|
File without changes
|
{cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/scheduler/notify.py
RENAMED
|
File without changes
|
{cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/scheduler/reconcile.py
RENAMED
|
File without changes
|
{cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/scheduler/registry.py
RENAMED
|
File without changes
|
{cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/scheduler/runner.py
RENAMED
|
File without changes
|
{cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/scheduler/state.py
RENAMED
|
File without changes
|
{cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/scheduler/store.py
RENAMED
|
File without changes
|
{cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/scheduler/surface.py
RENAMED
|
File without changes
|
{cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/scheduler/throttle.py
RENAMED
|
File without changes
|
{cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/scheduler/worker.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/sessions_repair.py
RENAMED
|
File without changes
|
{cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/shell_install.py
RENAMED
|
File without changes
|
|
File without changes
|
{cc_session_tools-3.10.3 → cc_session_tools-3.10.4}/src/cc_session_tools/lib/telemetry_store.py
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
|