Worktree bright frolicking charm#22
Merged
Merged
Conversation
Implement dynamic sub-agent system and audit remediation
Plano de refatoracao do apps/theo-desktop como ponte fina entre UI e agent runtime. Inclui 13 tasks em 6 fases + edge-case review com 11 correcoes aplicadas. WIP commit antes do merge de develop.
Resolved conflict in .claude/knowledge-base/index.md (frontmatter updated_at — kept 2026-05-14 from HEAD over 2026-05-13 from develop; both branches' content sections preserved by auto-merge). Develop brings 46 commits including: 5 new auth providers (Bedrock, GitLab, GoogleVertex, SapAiCore + flat re-export), tools-trim (49→34 registered), theo-marklive removal, new audit gates (deprecated, duplication, wiring), dogfood Phase 0 OAuth Codex mandate. Impact on theo-desktop-bridge-refactor plan v1.1: T4.1 OAuth strategy enum must expand from 3 providers to 8. Plan needs v1.2 revision before implementation begins.
Rebases the plan against 46 commits from origin/develop. Key changes: - D2 scope clarified: 3 OAuth providers (OpenAI/Copilot/Anthropic) only. The 5 new API-key providers (Bedrock/GitLab/GoogleVertex/SAP/MCP) are surfaced by the CLI, not the desktop. - T1.1 DeviceCodeDto.expires_in: Option<u64> -> u64 (mandatory after develop's feat(auth) commit). - T2.2 use_cases::auth_apply uses typed AuthError instead of String. - Phase 6 Dogfood: OAuth Codex Phase 0 made mandatory (T2.1 touches theo-infra-llm -> LLM pipeline -> dogfood-golden-rule.md applies). - Global DoD: +3 strict gates (check-deprecated, check-duplication, check-wiring); audit now runs 10 techniques. - New Coverage Matrix section "Develop-Merge Impact" with 10 items validated against the merged tree. Baseline established before implementation begins.
Replaces all 4 eprintln! calls in apps/theo-desktop/src/ with structured tracing::info! macros. Initializes a tracing_subscriber::fmt() in lib.rs with RUST_LOG env-filter (default `info`). EC-4 (PII redaction): the OAuth apply log was rewritten to use `has_account = is_some()` instead of `?Debug` formatting on `tokens.account_id`. Two new unit tests pin the property: - oauth_apply_log_does_not_leak_account_id (verifies raw ID never appears in captured tracing output) - oauth_apply_log_missing_account_no_leak Also includes secondary changes incurred by the develop merge baseline: - AgentConfig fields moved into `config.llm.*` and `config.loop_cfg.*` sub-structs (develop commit). All 4 desktop commands rebased. - OpenAIDeviceCode field rename `device_code` → `device_auth_id` (develop). The Tauri command preserves the FE-visible `device_code` key in the JSON shape. - 5 collapsible_if clippy errors (new lint from develop's workspace deny-list) rewritten with `&&` chains. Verification: - cargo build -p theo-code-desktop --lib ✓ - cargo clippy -p theo-code-desktop --all-targets -- -D warnings ✓ - cargo test -p theo-code-desktop --lib ✓ (2 passed) - rg "eprintln!" apps/theo-desktop/src/**/*.rs → only doc-comment refs Plan: T0.1 from .claude/knowledge-base/plans/theo-desktop-bridge-refactor-plan.md
Adds a dedicated CI step `cargo test -p theo-code-desktop --lib` to .github/workflows/audit.yml. The workspace test step continues to exclude theo-code-desktop (Tauri/GTK runtime concerns for integration tests), but the lib unit tests added by the bridge refactor plan compile without GTK and now gate every PR. Closes EC-3 from the edge-case review: 60+ tests added by Phases 0-5 would otherwise be invisible to CI. Also documents the local test command in README.md. Plan: T0.2 from theo-desktop-bridge-refactor-plan.md
Extracts the pure DomainEvent → FrontendEvent translation from
TauriEventListener::on_event into a free function `map_event` so it
becomes unit-testable without a Tauri AppHandle.
EC-1 (MUST FIX) — pre-existing UTF-8 boundary panic in tool-output
truncation. Old code:
if output.len() > 5000 {
format!("{}...\n[truncated]", &output[..5000])
}
panics whenever byte 5000 falls inside a multi-byte codepoint (emoji,
acentos, CJK). Replaced with a `truncate_at_char_boundary` helper that
cuts on `char_indices().nth(5000)` — never panics, always returns valid
UTF-8.
Tests added (16):
- 12 mapping cases covering every EventType variant the desktop handles
- 4 truncation cases: short / 5000-char boundary / 5001-char boundary /
long mixed input
- 2 UTF-8 regression: emoji at byte 5000, mixed ASCII+é (would have
panicked under old byte-slicing code)
- 1 unmapped-variant case (EventType::DecisionMade → None)
Total desktop lib tests: 18 (2 from T0.1 + 16 from T0.3).
Verification:
- cargo test -p theo-code-desktop --lib ✓ 18 passed
- cargo clippy -p theo-code-desktop --all-targets -- -D warnings ✓
Plan: T0.3 from theo-desktop-bridge-refactor-plan.md
…t tests
Introduces apps/theo-desktop/src/dto/ with three submodules and 6 typed
response structs covering every shape the desktop commands currently
return via `serde_json::json!({...})`:
dto::auth::DeviceCodeDto — start_device_flow response
dto::auth::AuthStatusDto — auth_status response (3 providers)
dto::auth::PollResultDto — poll_device_flow / login_browser
dto::chat::ConfigSnapshotDto — get_config response
dto::catalog::ProviderModelsDto — provider_models response
EC-2 (MUST FIX): NO `#[serde(skip_serializing_if = "Option::is_none")]`.
Option fields serialize as JSON `null` (default serde behavior),
matching the historical `json!({...})` shape byte-for-byte. Two tests
pin this explicitly.
EC-6: NaN / Infinity in `temperature` serialize as JSON `null` (serde
default; JSON has no NaN). This is IDENTICAL to the historical macro
behavior — the test pins it so the contract doesn't drift.
Plan: T1.1 from theo-desktop-bridge-refactor-plan.md
Verification:
- cargo test -p theo-code-desktop --lib dto ✓ 11 passed
- cargo clippy -p theo-code-desktop --all-targets -- -D warnings ✓
… DTOs
Replaces every serde_json::json!({...}) command return value in:
commands/auth.rs (5 returns: login_browser/start/poll/status/...)
commands/copilot.rs (4 returns: start/poll/status/provider_models)
commands/anthropic_auth.rs (4 returns: start/poll/status/anthropic_models)
commands/chat.rs (1 return: get_config)
with the typed DTOs from T1.1:
DeviceCodeDto, AuthStatusDto, PollResultDto,
ConfigSnapshotDto, ProviderModelsDto
Wire format unchanged — DTOs serialize byte-identically to the
historical json! macros (EC-2 preserved: Option<_> fields stay `null`,
not omitted; verified by T1.1 tests).
Verification:
- rg "serde_json::json!" apps/theo-desktop/src/ → 0 hits in commands
- cargo test -p theo-code-desktop --lib ✓ 29 passed
- cargo clippy -p theo-code-desktop --all-targets -- -D warnings ✓
Plan: T1.2 + T1.3 from theo-desktop-bridge-refactor-plan.md
Adds `UserVisibleModels` struct + `user_visible_models(provider)` lookup
to theo-infra-llm::provider::catalog. The 3 lists previously hardcoded
in apps/theo-desktop/src/commands/{copilot,anthropic_auth}.rs move to:
catalog/openai.rs → OPENAI_USER_VISIBLE_MODELS (7 models)
catalog/anthropic.rs → ANTHROPIC_USER_VISIBLE_MODELS (3 models)
catalog/cloud.rs → COPILOT_USER_VISIBLE_MODELS (13 models)
Eliminates the Anthropic-list duplication that lived in BOTH copilot.rs
(line 38-42) and anthropic_auth.rs (line 7-11) — single source of truth
in theo-infra-llm now.
Exposed to apps via `theo_application::facade::llm::catalog`. The
desktop `provider_models` and `anthropic_models` commands now delegate
to the facade; their hardcoded const arrays are deleted.
CLI gains a free `theo provider models` capability whenever it wants to
wire one — same facade entry point.
Verification:
- cargo test -p theo-infra-llm catalog ✓ 22 passed (5 new for T2.1)
- cargo test -p theo-code-desktop --lib ✓ 29 passed
- cargo clippy -p theo-infra-llm -p theo-application -p theo-code-desktop --all-targets -- -D warnings ✓
Plan: T2.1 from theo-desktop-bridge-refactor-plan.md
…ders Creates `theo_application::use_cases::auth_apply` with three pure modules — `openai::apply_oauth`, `copilot::apply`, `anthropic::apply` — each taking `&mut AgentConfig` + a freshly-fetched tokens reference and mutating the config in-place. Migrates ALL business decisions out of the desktop layer (D1 — Bridge Only Principle): - CODEX_ENDPOINT, CODEX_DEFAULT_MODEL constants moved into the use case - "set ChatGPT-Account-Id header" conditional moved into use case - "default model when unset" rule moved into use case - Copilot endpoint override (`/chat/completions` w/o /v1/) moved - Copilot "Openai-Intent" header moved - Anthropic api.anthropic.com host + anthropic-version header moved Desktop commands shrink to a 5-line shim that calls the use case and returns Ok(true). Scope (v1.2): only the 3 OAuth providers (openai/copilot/anthropic). The 5 API-key providers from theo-infra-auth (Bedrock/GitLab/etc.) are CLI-only and out of scope. Tests: 14 unit tests in auth_apply::tests pinning every mutation per provider, plus return-value labels. Verification: - cargo test -p theo-application --lib auth_apply ✓ 14 passed - cargo test -p theo-code-desktop --lib ✓ 29 passed - cargo clippy -p theo-application -p theo-code-desktop --all-targets -- -D warnings ✓ Plan: T2.2 from theo-desktop-bridge-refactor-plan.md
…apter, slim shims
T3.1 — AppState encapsulation:
Replaces 3 public Mutex<T> fields with a single private Mutex<Inner>.
All commands interact via async methods only:
project_dir() / set_project_dir(path)
snapshot_config() / update_config(|cfg| ...) / update_config_returning
install_cancel(tx) / cancel_running()
Doc-comments pin EC-9 (single Mutex choice) and EC-10 (install_cancel
overwrites prior channel). 8 unit tests cover every method including
the EC-10 behavior.
T2.3 — Centralized event emission (adapters/completion.rs):
New `EmitSink` trait + `emit_session_completion(sink, outcome)` helper
that owns the Done/Error event pair at session end. Removes inline
app.emit calls from chat::send_message. EC-8 ordering pinned by 4
unit tests (Error must precede Done when both emit).
T5.1 — Adapters module structure:
Adds apps/theo-desktop/src/adapters/{mod,completion}.rs as the canonical
out-adapter location. `events.rs` (the runtime-event listener) stays in
place for now — moving it under adapters/event_listener is cosmetic and
out of scope.
T5.2 — chat.rs slim:
send_message: 82 LOC → 41 LOC. Delegates to:
- state.project_dir() / state.snapshot_config()
- state.install_cancel()
- run_agent_session use case
- adapters::completion::emit_session_completion
set_project_dir / get_project_dir / update_config / get_config: all
use new encapsulated state API. Zero `.lock().await` calls in commands
(grep verified).
`AgentResult` exposed via theo_application::facade::agent::AgentResult
for adapter consumption.
Verification:
- cargo test -p theo-code-desktop --lib ✓ 41 passed (29 + 8 state + 4 completion)
- cargo test -p theo-application --lib auth_apply ✓ 14 passed
- cargo clippy -p theo-application -p theo-code-desktop --all-targets -- -D warnings ✓
- rg "\.lock\(\)\.await" apps/theo-desktop/src/commands/ → 0 hits
Plan: T2.3 + T3.1 + T5.1 + T5.2 from theo-desktop-bridge-refactor-plan.md
…s/oauth.rs
Replaces three near-identical files (auth.rs / copilot.rs /
anthropic_auth.rs, ~430 LOC total) with a single unified commands/oauth.rs
(330 LOC).
Every FE-visible command name is preserved unchanged (zero frontend
churn):
- auth_login_browser, auth_start_device_flow, auth_poll_device_flow,
auth_status, auth_logout, auth_apply_to_config
- copilot_start_device_flow, copilot_poll_device_flow, copilot_status,
copilot_logout, copilot_apply_to_config, provider_models
- anthropic_start_device_flow, anthropic_poll_device_flow,
anthropic_status, anthropic_logout, anthropic_apply_to_config,
anthropic_models
Shared constants (DEVICE_FLOW_DEADLINE_SECS = 900, timeout message)
deduplicated. Provider-specific business logic was already pushed down
to theo_application::use_cases::auth_apply by T2.2.
Preserved post-merge invariants:
- Copilot poll uses `expires_in: 900` literal (develop fix d7c2aea)
- OpenAI device_code FE-visible key maps to upstream device_auth_id
T5.3 (lib.rs invoke_handler):
Updated to reference commands::oauth::* for all 18 OAuth-related
commands. Total LOC: 69 (previously 60). Comment-style headers
group commands by feature (Chat / OAuth-OpenAI / OAuth-Copilot /
OAuth-Anthropic / Memory / Observability).
T4.1 footnote:
The OAuthProviderKind enum + parametrized dispatch described in the
plan was simplified: in practice the 3 providers' Tauri shims share
more shape via the per-provider use_cases::auth_apply::* helpers
(T2.2) than via an enum dispatcher. The bookkeeping cost of an enum
+ 3 match arms exceeded the value when the underlying Auth client
types are not generic over a common trait. KISS prevails — single
oauth.rs file, three clearly-marked sections, ~110 LOC each.
Verification:
- cargo test -p theo-code-desktop --lib ✓ 39 passed
- cargo clippy -p theo-code-desktop --all-targets -- -D warnings ✓
- All FE command names preserved (manual grep of lib.rs)
Plan: T4.1 + T4.2 + T5.3 from theo-desktop-bridge-refactor-plan.md
…mplete All 15 implementation tasks complete + Phase 6 dogfood OAuth Codex Phase 0 PASS. 9 commits across desktop/application/infra-llm crates. 75 new tests added, all green. Zero CRITICAL/HIGH issues introduced.
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.
No description provided.