mirror of
https://github.com/codewhale-hq/Codewhale.git
synced 2026-11-09 01:49:49 -10:00
main
15
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
5502f0a682 |
docs, scripts and CI: follow the host move; document stdio/websocket controls and usage statistics
Updates moved-file paths in the CI path filters, scripts, vitest config and editor/bridge sources; documents the Runtime API stdio/websocket controls and usage statistics (en and zh_hans); adds the usage-statistics and cache-call-receipts features to features.toml with regenerated web data; updates coarse-split design docs and crate maps, split scripts, the blocking-calls budget and release smoke scripts. Verification: whole-tree evidence only, not per group. A native21 build of the full dirty tree completed (patch sha ea25c782...), and an unsealed nextest rerun of all 389 selected existing checks passed 389/389 on it. The earlier sealed native20 run failed 369/20 before fixes and was not re-sealed. No CI run. Co-Authored-By: Claude Sonnet 5.5 <[email protected]> |
||
|
|
e34f207d21 |
refactor(engine): extract the shared runtime from the TUI [skip ci]
Move the Engine band, extension host, fixtures and shared test support into codewhale-engine; wire TUI/CLI to that owner. Preserve human-decision construction boundaries and lower reusable test helpers. Remove unused copied dependencies and repair path-based guards, scripts and crate maps. Correct the blocking scanner external-module scope leak; raised counts equal the corrected pre-move source. Refresh embedded built-in hashes after path-only bundle regeneration. Restore the provider-free prompt budget to the exact pre-b984e31290 macOS bytes and representative identities; tool catalogs are unchanged. Portable prompt-fixture pinning remains follow-up work. Local validation: Engine/TUI/CLI clippy --tests --no-deps -D warnings passed with the existing allow-list; production CLI check passed; fmt passed. Focused native run: 705 passed / 83 failed initially; after hash/path repairs, 81 affected cases plus 2 existing build-relocation cases passed (83/83). Thus 786/788 original cases pass; 2 compiled-release-image cases lack input and are not qualified. Frozen input inventories unchanged. macOS test-link unwind-table warnings remain. Four metric tests pass; all 55 budgets pass. Host Node: 413 pass, 7 skip; Bun: 414 pass, 6 skip. Existing scanner checks: 34 + 33 pass. Compiled-delivery synthetic fixtures: 7 pass. Web: 42 pass. Import, blocking, dead-code, coarse-map, version and facts checks pass. CW-7701. No hosted CI, provider call, release build or publication. Stage A part 2 and the old App Server/ratatui dependencies remain separate. |
||
|
|
73beac7ecf |
refactor(split): clear stage A's band boundaries for the coarse split
Stage A of docs/design/COARSE_SPLIT.md (engine / app-server / tui) now
measures zero upward refs, so the engine band can move as one crate.
Checker (scripts/split/crate_map.py):
- PATH_RE matched `super` as a prefix of `supervisor`, so
`super::supervisor::X` resolved as `super::super` and was charged to the
crate root. Fixed with `super\b`.
- Grouped imports (`use crate::a::{b::C, d}`) are now expanded into one
path per leaf; before, only the prefix was counted. This exposed
task_manager -> RuntimeThreadManager and remote_control -> chat relay.
Band placement (crate-map-coarse*.toml): runtime_threads/manager and
tools/registry go with the engine, which constructs and drives them (as
Codex's ThreadManager lives in codex-core); remote_control with app-server;
doctor and doctor_fix with the TUI, where the doctor command lives.
Code:
- runtime_account_api_base and its validator move from runtime_api to
profile_constitution, the engine-side caller; runtime_api, its secrets
routes and its test call the new owner.
- client.rs names codewhale_runtime::config instead of the lib.rs re-export.
Checks:
- crate_map.py check crate-map-coarse.toml: cycles=0 upward_edges=0
upward_refs=0 oversize=0 unassigned=0 duplicates=0
- crate-map-coarse-split.toml: upward_edges=1 upward_refs=73
- crate-map.toml: upward_edges=120 upward_refs=411
- scripts/dev-cargo.sh check -p codewhale-tui --tests --locked: ok, 0 warnings
- cargo test -p codewhale-tui --lib -- account_api_base profile_constitution
secrets: 42 passed; -- runtime_account_api: 1 passed
- cargo fmt --all -- --check: clean
Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
||
|
|
297b06da36 |
docs(split): crate map, coarse split plan, and the crate_map.py checker
scripts/split/crate_map.py builds the crates/tui unit graph (module_graph +
count_lines strict production lines) and checks a unit->crate TOML for
unassigned/duplicate units, oversize crates, crate cycles and upward edges.
docs/design/crate-map.toml + CRATE_MAP.md: a 66-crate fine map from a
judge-panel workflow (4 architects iterating against the checker, 3 judges,
1 synthesizer), plus an independent read-only review (Codex CLI,
gpt-6.1-sol) listing 14 problems the checker cannot see. runtime-wire is
renamed app-server-protocol per the founder's App Server v2 decision.
docs/design/COARSE_SPLIT.md + crate-map-coarse*.toml: the founder's
2026-10-31 direction to make the top line of crates ~400-500k lines like
Codex (162 packages, core/tui ~463k) and Grok Build (104, up to 551k).
Stage A, engine / app-server / tui: 35 upward refs over 3 edges. Stage B
splits the engine band (225k + 69k production lines): 96 refs.
TUI_DECONSTRUCTION.md points its Target map at CRATE_MAP.md, applies the
rename, and corrects the billing/catalog size (11,091 strict production
lines; 24,352 was partition_report's file-level figure).
Checks run on
|
||
|
|
492c3d5b30 |
fix(split): resolve test aliases and report root references [skip ci]
Include cfg(test) upstream aliases in re-export discovery and audit root-module relative paths even without an explicit crate::config use. W3 exposed both gaps: one root-local ProviderKind path escaped the tool, and test-only aliases could be left at a retired facade. Preserve cfg attributes on rewritten imports. Manual before/after artifact fixtures: root report zero to one site; test alias unrewritten to direct owner, guarded by cfg(test). Python syntax passes. Independent read-only Codex W3 review found no actionable issue. No native build or Rust behavior claim for this Python-only commit. Co-Authored-By: OpenAI Codex <[email protected]> |
||
|
|
d904b22c6d |
fix(split): preserve import guards and contain carved output [skip ci]
Retiring a facade can split one cfg(test)-guarded import into several statements. Both flattening and upstream regrouping previously left the extra statements unconditional. Reuse the existing mover attribute helper and repeat the guard on each resulting statement. Refuse carved output whose existing parent symlinks resolve outside the canonical repository, matching the source-path containment boundary. Local evidence: both import shapes lost their second cfg guard before this change and preserve it after; four extra attribute cases and the existing mover shape passed. Four Python modules parse; mover help exits 0. The symlink-output probe accepted before and refuses after, without writing any outside file. A formatted carve CLI dry-run on a real function exits 0. No Rust build, module move, CI, provider call, or release claim for this Python-only change. The active W2a Cargo source remains frozen separately. Co-Authored-By: OpenAI Codex <[email protected]> |
||
|
|
a0053edcda |
tooling(split): carve whole Rust items through journalled writes [skip ci]
Complete the stopped lane B carving helper for S51. Derive child imports
from existing use leaves and moved items; widen private definitions only
to the selected visibility and preserve test module attributes. Use the
existing splitlib compare-and-swap journal for writes. Dry runs now parse
and format the proposed Rust too. Refuse outside sources, unsafe or duplicate
module names, invalid visibility, empty/cut ranges and duplicated test items.
Verified against canonical main
|
||
|
|
035bd86a26 |
tooling(split): support crate-scoped visibility for in-crate carving [skip ci]
Complete stopped lane B widening work for S51. --vis pub(crate) now
widens private items and fields without exporting them outside the crate;
the default remains pub for cross-crate moves. Reject unsupported visibility
values rather than producing malformed Rust.
Verified on canonical main
|
||
|
|
7478d51f9c |
tooling(split): make rustfmt failures and unstable bases visible in the rewrite tools (W0 follow-up)
Follow-up to
|
||
|
|
3b35f098f7 |
tooling(split): split tooling v2 (S01/W0): journalled mover, re-export resolver, G11 preflight, widen v2, strict+file counters
Scripts only under scripts/split/. No Rust, no manifest, no budget touched. Base |
||
|
|
67ea906c79 |
tooling(split): move-modules.py rewrites callers instead of re-adding the tui alias block
Replaces add_alias, which re-created the lib.rs path alias that P1 deleted, with rewrite_callers (crate::<m> -> codewhale_runtime::<m> in crates/tui/src) plus an explicit import in lib.rs for unqualified uses. Predecessor: the alias block in the same script. Verified with --dry-run only on its own; the module move that exercises it is the next commit. Co-Authored-By: Claude Sonnet 5.5 <[email protected]> |
||
|
|
02a082097f |
tooling(split): add closure_report.py for per-crate dependency and reverse-closure size
Reports, per workspace crate, own Rust lines, lines in the workspace dependency
closure and lines in the reverse closure (what a change can rebuild). Baseline
at
|
||
|
|
ee60ebeb56 |
chore(split): add partition_report.py, the extraction-order measurement for the crate split
`docs/design/TUI_DECONSTRUCTION.md` step 0 asks for measurement before more crates are cut, and none existed: scripts/split held only the runtime->UI ratchet, the mover and the visibility widener. `partition_report.py` reuses the ratchet's lexer and module graph and condenses the production edges into strongly connected components: - per top-level module: production and test lines, distinct modules it references and is referenced by, cycle size, and an extraction wave (the longest chain of components it still depends on; wave 0 depends on nothing left to move) with the modules that block it - `--scc-edges N`: the N heaviest production edges inside the largest cycle, with the items they name - `--json` and `--module NAME` `module_graph.py` gains `load_graph()` (the graph loading `build_report` already did, now callable); `build_report` uses it and its behavior is unchanged. First run on this tree: the runtime is one 100-module cycle (the design doc counted 85); 30 modules (~17k production lines) are wave 0 and claimable now; the cycle contains `tui`, `commands` and `lib.rs` only through the 11 production back-edges the ratchet still counts (runtime_api->commands 9, tools->commands 2). Evidence (local): `module_graph.py --check` passes with identical totals (prod 11, test 35, 116 closure modules); `test_check_command_crate_boundaries.py` 30 tests OK; the new report runs end to end. Co-Authored-By: Claude Sonnet 5.5 <[email protected]> |
||
|
|
5cf09da776 |
feat: consolidate 0.10.1 Engine, reviewed TS mods and Ratatui integration
Use the existing Engine for ACP, children and recursive RLM; retain captured approval, deadline, history/checkpoint, delivery and one-bill usage authority. Move legacy thread controls to the authenticated canonical owner with complete history and durable operation receipts. Keep Rust wire/policy authority and opt-in extension/Native execution; adopt the pinned Ratatui kit and source/docs. Exact V22 local validation: Rust 1351 passed/0 failed/0 ignored; additional localization 54 passed/0 failed/0 ignored; workspace/all-target/all-feature Clippy passed under existing CI policy. CLI: 3 actual processes / 6 checks / 6 local fixture requests / 0 paid calls; approval, resume, cancellation and EOF effects passed. npm test + check:web: 1180 passed / 0 failed / 7 explicit skips (wrapper101, SDK19, host378, website682); strict TypeScript and production web passed. No hosted/platform/install/live ChatGPT/DO adapter/publication/release claim. Signed-off-by: CodeWhale Bot <[email protected]> |
||
|
|
24a7b99a73 |
refactor(split): codewhale-runtime crate and boundary ratchet (RS-0..RS-7) (#6586)
* ci(split): RS-0 runtime -> UI boundary ratchet and a hermetic step that cannot pass empty
First rail of the runtime/TUI crate split.
- scripts/split/module_graph.py: module graph of crates/tui/src and
crates/runtime/src with a comment/string-masking lexer and grouped
`use crate::{...}` expansion. Computes the runtime closure from the eight
seed modules (plus everything already in crates/runtime, plus test-only
support modules its tests use) and counts, per module pair:
prod / test references into UI code (tui, commands, remote_control,
context_report, composer_*, private lib.rs items), "late" references into
modules that move after the core (exec_agent, route_preferences), UI-library
uses (ratatui, crossterm, codewhale_tui, codewhale_palette), and intra-doc
links into UI code.
- scripts/runtime-boundary-baseline.json: prod 84, test 95, late 2, uilib 13,
doc 1 across 101 closure modules. Any rise or new pair fails with file:line;
a drop the baseline did not record also fails (`--update` lowers it and
refuses to raise).
- scripts/check-command-crate-boundaries.py is now table-driven
(BoundaryRule: package, metadata|tree dependency mode, forbidden packages,
source scan) and runs the ratchet. `tree` mode reads `cargo tree -p`, which
resolves features per package; `cargo metadata` unifies them and would see
palette's ratatui feature the TUI enables. The runtime entry lands with the
crate (RS-2).
- ci.yml hermetic safety step: `cargo test ... -- auto_review authority
sandbox` becomes `cargo nextest run --no-tests=fail -E 'test(auto_review) |
test(authority) | test(sandbox)'`, and the job installs nextest. After the
modules move, the old step would have matched 0 tests and passed.
Tests: python3 scripts/test_check_command_crate_boundaries.py -> Ran 19
tests, OK (11 existing + 8 new: tree mode, lexer masking, grouped imports,
late/uilib edges, runtime-crate closure, rise/drop, checked-in baseline).
python3 scripts/check-command-crate-boundaries.py -> PASS.
No Rust changed; no cargo build run for this commit.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01R9rJEoMuUSRWznU6QjkE7h
* docs(split): RS-1 record the runtime split sequence and its three departures
docs/design/TUI_DECONSTRUCTION.md gains the runtime split sequence (rails,
crate with live code, cut upward edges one blocker per slice, rename-only
core move, then the client contract) and records where it departs from the
older order in the same file, with why each is safe:
1. config moves inside the runtime's strongly connected component instead
of leaving first (#6034/#6143 become internal runtime work);
2. loop convergence is not a precondition for moving the engine, because
run_subagent and Engine::run_turn move into the same crate;
3. the moves use one root path alias in the TUI lib.rs, deleted at the end,
instead of rewriting every caller in the moving change.
It also states that the engine, turn loop and tools go into
codewhale-runtime (no separate codewhale-engine), why the runtime cannot
live in crates/core (command-contract depends on core), and that the TUI
stays the only terminal-output owner behind the host_terminal port.
docs/ARCHITECTURE.md points at that sequence in its boundary note and
corrects crates/secrets's ownership (it also owns the shared sanitizer and
redaction).
Docs only; no build or test run.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01R9rJEoMuUSRWznU6QjkE7h
* refactor(split): RS-2 create codewhale-runtime with 19 live leaf modules
`git mv` of the 19 leaf modules that reference nothing outside the batch in
production or test code and touch no UI library (7,149 lines):
session_tree native_memory goal_loop context_budget continual_harness
skill_state tool_history_repair retry_status llm_response_cache sleep_guard
media_originals regex_cache elapsed workspace_discovery hashing fast_hash
prompt_zones safe_label model_context.
- crates/runtime (codewhale-runtime): publishable (version.workspace, no
`publish = false`), `[lints] workspace = true`, the TUI's crate-level
`#![allow(clippy::uninlined_format_args)]` copied, no build.rs (nothing in
the batch needs one). Listed in scripts/release/crates.sh after
config/core/memory/models and before tui. The first crates.io
publication of the new name happens at the next release run; that is a
release-owner decision before this merges.
- TUI: 19 `mod` lines replaced by one private alias block
`use codewhale_runtime::{...};`, so no TUI file's content changes.
examples/zz_perf_probe.rs uses `codewhale_runtime::session_tree` instead of
a `#[path]` include.
- Visibility widened only where the compiler asked (scripts/split/widen.py,
lints capped to warnings during the loop, final pass with lints on):
25 items `pub(crate)` -> `pub` (fast_hash aliases, llm_response_cache
API, regex_cache::compile_user_regex, safe_label API and
safe_error_text, tool_history_repair receipt, workspace_discovery
helpers, hashing), and 12 `expect(dead_code)` / `cfg_attr(not(test),
expect(dead_code))` attributes removed because exported items are no
longer dead. No security-module items in this batch.
- `test-support` feature: retry_status's per-thread test state and readers,
SafeLabel::is_redacted and the WorldState diff renders move from
`cfg(test)` to `cfg(any(test, feature = "test-support"))`, all `pub`; the
TUI enables it from [dev-dependencies] only.
- Exported-only fixes: five rustdoc links from public `safe_error_text` to
private items became code spans; `WorldState::len` gets a local
`allow(clippy::len_without_is_empty)` instead of new API.
- Path sweep (scripts/split/move-modules.py): docs, AGENTS.md,
check-blocking-calls-budget.json key, check-runtime-contract-budget.py
fragment path, dev-test.sh examples; dev-test.sh gains a `runtime` area.
- Boundary checker: codewhale-runtime rule in `tree` mode (cargo tree -p,
per-package features) forbidding codewhale-tui/cli, ratatui*, crossterm,
ansi-to-tui and kit crates, plus a source scan of crates/runtime/src.
Ratchet unchanged: prod 84, test 95, late 2, uilib 13, doc 1.
Verification (local):
- widen.py final pass: cargo check -p codewhale-runtime -p codewhale-tui
--lib --tests --examples with lints on: 0 errors.
- cargo check -p codewhale-runtime --all-targets (standalone features): ok.
- cargo test -p codewhale-runtime --lib: 127 passed; 0 failed.
- cargo clippy -p codewhale-runtime --all-targets --all-features -D warnings: clean.
- RUSTDOCFLAGS=-Dwarnings cargo doc -p codewhale-runtime --no-deps: clean.
- cargo tree -p codewhale-runtime -e normal,build: 0 ratatui/crossterm/tui.
- python3 scripts/test_check_command_crate_boundaries.py: 21 tests OK;
check-command-crate-boundaries.py: PASS.
- validate-crate-publish-order.test.sh: passed.
- check-blocking-calls-budget.py: 717 sites, within budget.
Not run locally: TUI test execution (the TUI test binary build hit ENOSPC
on the shared volume; TUI tests are type-checked only), TUI clippy,
check-runtime-contract-budget.py measurement (it builds the TUI tests).
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01R9rJEoMuUSRWznU6QjkE7h
* refactor(palette): RS-3 make ratatui an optional default feature
The headless runtime needs palette's theme-setting and hex normalizers
(settings.rs) and RGB tokens (logging.rs), but palette pulled in ratatui
unconditionally. `ratatui` is now a default feature; without it the crate
is the renderer-free core:
- ids.rs (new): ThemeId with from_name/name/display_name/tagline,
SELECTABLE_THEMES, normalize_theme_name, USER_THEME_PREFIX,
normalize_user_theme_selector, normalize_theme_setting, and a
`(u8, u8, u8)` hex parser `parse_hex_rgb` behind normalize_hex_rgb_color
(same `#rrggbb` output as before).
- rgb.rs (new): the 161 `*_RGB` tuple tokens, split out of tokens.rs with
their comments; tokens.rs keeps the 103 `Color` roles.
- Behind `#[cfg(feature = "ratatui")]`: adapt, contrast, detect, grammar,
osc11, themes (UiTheme, ThemeId::ui_theme, parse_hex_rgb_color,
hex_rgb_string), tokens, user_theme, and the crate tests.
- The public API with default features is unchanged (lib.rs re-exports the
same names), so codewhale-tui needs no edit. The runtime will depend on
`codewhale-palette = { default-features = false }` when settings/logging
move (RS-14).
- Ratchet: codewhale_palette is no longer a UI library for the runtime
closure; uilib 13 -> 10 (settings.rs's 3 palette uses drop out).
Verification (local):
- cargo check -p codewhale-palette --no-default-features --all-targets: ok.
- cargo test -p codewhale-palette: 81 passed; 0 failed.
- cargo clippy -p codewhale-palette --all-targets -D warnings (default and
--no-default-features): clean.
- RUSTDOCFLAGS=-Dwarnings cargo doc -p codewhale-palette --no-deps
--no-default-features: clean.
- cargo check -p codewhale-tui --lib --tests: ok.
- python3 scripts/test_check_command_crate_boundaries.py: 21 tests OK.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01R9rJEoMuUSRWznU6QjkE7h
* refactor(split): RS-4 the host_terminal port, with raw mode as its first use
Runtime code toggled crossterm raw mode directly around interactive
children in three places (tools/shell.rs x2, shell_dispatcher.rs), each with
its own copy of a restore guard. That is the only crossterm use left in the
runtime closure's production code.
- codewhale_runtime::host_terminal: the one port for terminal side effects.
`HostTerminal` trait (suspend_raw_mode / resume_raw_mode), a first-wins
`OnceLock` install, a no-op host when nothing is installed, and
`suspend_raw_mode()` returning a `RawModeSuspension` guard that resumes
only if raw mode was on (issue #1690 semantics). RS-7 adds the
notification-delivery methods to the same trait.
- The three call sites use `crate::host_terminal::suspend_raw_mode()`; the
three hand-written guard structs are deleted.
- tui/ui/terminal.rs: `TuiHostTerminal` implements the port with crossterm;
`install_host_terminal()` is called at the top of `run_with_args`, so
every mode the binary runs (interactive, exec, serve) keeps today's
behavior. Stdio hosts can later be launched without it.
- integration harness: `use codewhale_runtime::host_terminal;` at the
harness root, like `tool_parser`, for its `#[path]` shell_dispatcher.
- Ratchet: uilib 10 -> 1 (tools|crossterm 7 -> 1, the remaining one is a
roster_routes test; shell_dispatcher|crossterm 3 -> 0).
Verification (local):
- cargo test -p codewhale-runtime --lib: 128 passed; 0 failed (adds
host_terminal::tests::no_host_suspension_is_a_no_op).
- cargo clippy -p codewhale-runtime --all-targets --all-features -D warnings: clean.
- RUSTDOCFLAGS=-Dwarnings cargo doc -p codewhale-runtime --no-deps: clean.
- cargo check -p codewhale-tui --lib --tests --examples (incl. the
integration harness): ok.
- python3 scripts/split/module_graph.py: PASS after --update.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01R9rJEoMuUSRWznU6QjkE7h
* refactor(split): RS-5 split the voice capture core out of commands::voice
runtime_api/voice.rs (the `/v1/voice` routes) imported
`crate::commands::voice`, a UI module, for recorder detection, ASR choice
and the headless dictation cycle.
- New runtime-side module `crate::voice` (774 lines) holds everything that
is not a slash command: recorder detection and `is_available`, WAV
encoding, `record_audio`, the send-suffix contract (`SEND_PHRASES`,
`split_send_suffix`), chat-completions transcription (provider, Groq,
local whisper), voice-control, ASR selection, and the headless
`dictate_once` / `DictateMode` / `DictateError` / `DictationOutcome`,
with their tests (vendor pin, WAV header, send suffix, recorder probe).
It uses `config` and `client`, so it moves into codewhale-runtime with
the core (M1).
- `commands::voice` keeps the three slash commands, the recording status
line, `VoiceCaptureOutcome` and `capture_and_transcribe` (it drives the
composer while the user speaks), importing the core from `crate::voice`.
Seven core functions become `pub(crate)` for that loop; nothing else
changes.
- runtime_api/voice.rs imports `crate::voice`.
- Ratchet: prod runtime_api|commands 10 -> 9.
Verification (local): cargo check -p codewhale-tui --lib --tests: ok.
The moved tests live in the TUI test binary, which was not linked locally
(shared volume at ~8 GB free); they are type-checked only.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01R9rJEoMuUSRWznU6QjkE7h
* refactor(split): RS-6 move the context-window formatter down into utils
fleet/capability_badges.rs (runtime) imported
`tui::model_picker::format_picker_context_window`, a pure formatter.
- It moves to `crate::utils::format_context_window` (same body: `1M`,
`1.05M`, `262K`, `500`); the picker's 10 call sites and the badges' 6
(including its `1M/1.05M/262K/500` assertions) call it there.
- Not merged with `agent_roster::format_tokens` (`1.2k`): that labels usage,
not window size, and merging would change output.
- Ratchet: prod fleet|tui 1 -> 0.
Verification (local): cargo check -p codewhale-tui --lib --tests: ok.
The badge and picker tests are in the TUI test binary, which was not
linked locally (shared volume at ~8 GB free); type-checked only.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01R9rJEoMuUSRWznU6QjkE7h
* refactor(split): RS-7 notification policy down, delivery behind host_terminal
Runtime code imported `tui::notifications` and friends: the `notify` tool
(tools/notify.rs), native notification preparation
(runtime_api/notification_delivery.rs) and headless exec (exec_agent.rs).
Per the plan's second review, delivery (OSC 9/99/777 escapes, taskbar and
title sequences, stdout writes) stays in the TUI, the one terminal-output
owner; only policy moves down.
- New runtime-side module `crate::notify`: `git mv` of
tui/notification_payload.rs -> notify/payload.rs,
tui/notification_audio.rs -> notify/audio.rs,
tui/sound_policy.rs -> notify/sound_policy.rs, plus the pure policy that
was in tui/notifications.rs: `Method`, `DeliveryOutcome` (+ receipts),
`NotificationGate`, `AttentionCondition` and its grace rule,
`native_attention_allowed`, and `settings_projection` (now takes
`&NotificationsConfig`). It uses `config`, so it moves into
codewhale-runtime with the core.
- `sanitize_stream_chunk` moves to `codewhale_secrets::sanitize` beside
`strip_ansi_into`; the payload and notifications call it there and
tui/ui/frame.rs re-exports it for the event loop, which does not change.
- host_terminal port gains `notify_model(title, body) -> receipt`,
`set_terminal_focused`, and `apply_notification_settings(&NotificationsConfig)`
(no-op / "no terminal host" receipt when nothing is installed). The TUI
host delegates to `tui::notifications::{notify_model,
set_terminal_focused, apply_settings}`; `settings(&Config)` is now a thin
wrapper over `apply_settings`, so its ~40 UI call sites are unchanged.
- tools/notify.rs calls the port; its emission-chain test (method=off
silences the sink) moves to tui::notifications tests, where the chain
lives. exec_agent.rs calls the port.
- notification_delivery.rs uses `crate::notify`; it still calls
`tui::notifications::notify_with_sinks` with null sinks, because that
function mixes the policy with transport selection. Known limitation,
written in notify/mod.rs: splitting transport out of notify_with_sinks is
the remaining step (1 prod runtime_api|tui reference left).
- Ratchet: prod 82 -> 75 (runtime_api|tui 5 -> 1, tools|tui 11 -> 8),
test 95 -> 89 (tools|tui 19 -> 14, config|tui 10 -> 9).
Plan note: RS-7 was scoped to wait for R3/R7 (exec_agent.rs) and #6569
(tui/ui/frame.rs); this branch touches those files and will need a rebase
after they land.
Verification (local):
- cargo check -p codewhale-tui --lib --tests --examples: ok.
- cargo test -p codewhale-runtime --lib: 128 passed; 0 failed.
- cargo test -p codewhale-secrets --lib: 76 passed; 0 failed; 1 ignored.
- cargo clippy -p codewhale-runtime -p codewhale-secrets --all-targets
--all-features -D warnings: clean.
- RUSTDOCFLAGS=-Dwarnings cargo doc -p codewhale-runtime --no-deps: clean.
The notification tests are in the TUI test binary, which was not linked
locally (shared volume at ~8 GB free); type-checked only.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01R9rJEoMuUSRWznU6QjkE7h
* wip: unfinished review fix-up (interrupted by the session usage limit)
Uncommitted edits from the fix-up stage, saved so nothing is lost. Not
compiled or tested after these edits; the next pass reviews and finishes them.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01R9rJEoMuUSRWznU6QjkE7h
* ci(split): run the ratchet's baseline-ref step under bash; wip fix-up reviewed
The boundary step uses `[[ =~ ]]` to skip an all-zero push `before` SHA, so
it names `shell: bash` instead of relying on the runner default.
This also closes the review of
|