Refactor app shell into MVVM layers and enforce architecture boundaries - #213
Merged
Merged
Conversation
AppRoot had grown into a single runtime object that owned routing, remote transport, conversation state and presentation at once, so every feature change reached across all of them. Split it along explicit boundaries: - pages/runtime for the composition root and lifecycle - pages/viewmodel for controllers and view models - pages/policy for pure decision helpers - pages/actions for the typed intent/action surface handed to components - pages/navigation and pages/layout for route and geometry contracts Components now receive typed action objects instead of reaching into view models, which lets Local and Remote share one conversation shell (ConversationRouteSurface on compact, WideConversationHost on wide). Behaviour changes that came out of the split: - Creating a chat from the "chat" option binds the desktop's assistant workspace first. The desktop ignores workspace_path for Claw sessions and always uses its assistant workspace, so the app used to keep showing the code workspace it was on while the session was actually created elsewhere - the new chat never appeared in the list. - Picking a workspace in the create sheet now pairs it with the code agent, so the picker is honoured instead of being silently dropped. - Compact remote conversations open the sidebar over the chat from a menu button, matching local chats, instead of popping back out of the conversation. The system back gesture still leaves the chat and reveals the drawer. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The MVVM split only holds if the import direction is enforced. Add `pnpm run harmony:architecture`, which fails when services import pages, when components import view models, when the page graph gains a cycle, or when action and hook interfaces are passed as anything but typed object literals. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Remove the parallel application connection and batch review surface, keeping the existing source policy and owner-specific permission controls as the single path. Reduce Web and TUI output, preserve remote and owner guards, and consume retired automatic defaults once without overwriting later user choices.
fix(agent): include goal lifecycle tools in Cowork
…-mode fix(remote-ssh): restore target selection and container stdin
…l-tools fix(agent): make goal lifecycle available to every primary agent
refactor(harmonyos): split the app shell into MVVM layers
…ine under sustained load
Subscription OAuth login, token refresh, and credential resolution now honor the global AI proxy (ai.proxy), including bare host:port URLs normalized to http://. Applies to Codex, Antigravity, and OpenCode subscription providers, and aligns TLS verification with the model configuration. Also reuse the credential committed by a concurrent refresh when the local conditional commit loses the race, instead of always failing on a revision conflict.
…ttings feat(web-ui): add pet switch settings action
fix(acp-agents): hide remote servers without deleting
- move the auto-title toggle into the section header - replace model radio options with a searchable model selector - align session-title labels and remove obsolete layout styles - update the Qwen help link to the Bailian console
chore(release): bump version to 0.2.17
fix(ai): route subscription auth through the configured proxy
… target The setup dialog asked for an approval policy and reported target model readiness, but protocol v4 carries both per turn and the composer already edits both. Choosing them once while picking a target contradicted that, and the model row pushed a manual, credential-bearing sync onto the user. The model picker was also broken for a restored projection. Its options came from the probe snapshot captured when the session was created, which lives only in renderer cache — never in the durable outbound record. A projection rebuilt from the controller index (invariant 28) therefore had an empty list, and the selector rendered nothing at all, so that session could never change model again. Models enabled locally after creation were likewise invisible. Setup now decides only what the target cannot change later: which target, which base revision, and whether uncommitted changes travel. - The new session's approval policy comes from this device's own permission default; the composer strip stays the only editor. Both mapping directions move into one module so they cannot drift. - Because the policy is switchable per turn, a target must advertise all three approval capabilities to be usable, not just the current one. - The dispatch model picker offers this device's catalog, unioning in the target's probed list rather than being replaced by it, and falls back to the local reasoning catalog and default model. - Submission pushes this controller's model configuration to a target that cannot serve the model, before any baseline is created, then re-probes. It stays visible as `model-sync` setup-audit rows in the preparation journal and the projected transcript, exactly like `cli-install`. A failed push is not fatal: the submission reports the target's own model diagnostic instead. - Older targets reject unknown audit actions, so those rows are forwarded only to a CLI advertising `setup_audit_model_sync`. The controller journal keeps them either way. Device targets have no such repair path and still fail closed. AI-assisted. Testing level: fully tested (automated) — dispatch suites in bitfun-core, bitfun-services-core and the CLI, plus the web-ui dispatch, ModelSelector and flow_chat suites. Not exercised against a live SSH host.
…-signing-pubkey fix(ci): pass public key when signing Windows installer
Prevent MiniApp local node_modules and build outputs from triggering false ThemeService contract failures during desktop builds.
…e-web-api-bindings # Conflicts: # scripts/check-github-config.test.mjs
…api-bindings fix(ci): generate web bindings in nightly build
…llisions fix(release): reject duplicate asset names before upload
Refactor app shell into MVVM layers and enforce architecture boundaries
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #
Type and Areas
Type:
Areas:
Motivation / Impact
Verification
Reviewer Notes
Checklist