Repository navigation
feat(desktop): let device users choose managed tools in Settings - #179
Merged
Merged
Conversation
Add a "Managed tools" card to the desktop Settings view, backed by the daemon's program management API. - Tauri commands `get_program_management` (GET /v1/programs) and `set_program_choice` (POST /v1/programs/choice) relay to the daemon. - The desktop model polls program management with the existing status poll and adds `setProgramChoice`, which shows the choice while saving and reports the daemon's error text when it refuses one. - When the policy allows a choice, the card offers All / Only these / None with a switch per configured tool; otherwise it lists the tools as managed by the organization. Each tool shows its last apply state, including "Opted out". - Stories cover each state, the choices sent, and the refused case. Refs #174
There was a problem hiding this comment.
🟢 Approval recommended
The UI, state handling, and IPC integration are consistent with daemon-owned policy enforcement, with no unresolved blocking findings.
0 open findings
What changed in this PR
Adds desktop Settings controls for choosing managed tools, building on #177’s daemon API for #174 while keeping policy enforcement in the daemon.
Changes:
- Adds All, Only these, and None choices with tool status badges and organization-managed states.
- Connects typed IPC commands to polling and optimistic saves.
- Adds component and full-app stories covering choices, saving, and refusal handling.
| File | Description |
|---|---|
| frontend/desktop/src/views/SettingsView.tsx | Adds the Managed tools card and controls. |
| frontend/desktop/src/views/SettingsView.stories.tsx | Covers card states and interactions. |
| frontend/desktop/src/useDesktopModel.ts | Adds polling, optimistic saves, and stale-response protection. |
| frontend/desktop/src/types.ts | Defines program management types. |
| frontend/desktop/src/styles.css | Styles tool rows and choice controls. |
| frontend/desktop/src/stories/StandaloneUsage.stories.tsx | Mocks the new management request. |
| frontend/desktop/src/stories/ManagedTools.stories.tsx | Tests opt-out success and daemon refusal. |
| frontend/desktop/src/stories/fixtures.ts | Adds program management fixtures. |
| frontend/desktop/src/stories/Appearance.stories.tsx | Mocks the new management request. |
| frontend/desktop/src/Desktop.tsx | Connects Settings to model state and actions. |
| frontend/desktop/src/backend.ts | Adds typed IPC wrappers. |
| crates/agentdesktop/src/main.rs | Registers daemon-relay commands. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
peterj
approved these changes
Oct 19, 2026
peterj
pushed a commit
that referenced
this pull request
Oct 19, 2026
…177) * feat: let device users choose which configured programs are managed Add `programSelection.allowUserChoice` to the daemon configuration (off by default). When it is on, the device user can opt out of every configured program, or keep only the ones they pick, with `agentdesktop programs set`. - The daemon stores the choice in its state directory and leaves the programs out before every apply, so each provider's existing cleanup removes only the files Agentdesktop owns. - Opted-out programs report a new `opted_out` state (proto, agent, controller) on every apply, so admins see it on the device page. - `GET /v1/programs` and `POST /v1/programs/choice` read and change the choice; a change re-applies right away and is reported to the controller. Refs #174 * fix(agent): keep program choice consistent across reports, --once and sign-in - Number each apply under the apply lock and publish re-apply outcomes through one helper that never replaces a later apply's outcome, so a tick that finishes after a program choice change cannot report the old choice to the controller. - Validate `--once` against the chosen programs: an opted-out Copilot CLI or VS Code, or an opted-out gateway program, is only cleaned up. - Start no automatic gateway sign-in (startup, cached and pushed configuration) while the device user has opted out of every program that uses the gateway and no local LLM proxy runs; opting back in starts the device authorization that was skipped. * feat(controller-web): show opted-out programs and build programSelection (#178) - Device page: the "Managed programs" card labels the `opted_out` state "Opted out" with a neutral badge and a title explaining that the device user opted out of the program. - Configuration builder: a "Program selection" section with a "Let device users choose which programs are managed" checkbox. When checked, the generated YAML includes `programSelection: { allowUserChoice: true }`, and a notice warns that daemons predating the setting reject it. The checkbox is seeded from the active daemon configuration. - Rename the `.sandbox-compatibility` notice style to `.config-notice` so both sections share it. - Stories: a device with an opted-out program, a configuration seeded with `programSelection`, and an interaction test that toggling the checkbox adds and removes the key. Refs #174 * feat(desktop): let device users choose managed tools in Settings (#179) Add a "Managed tools" card to the desktop Settings view, backed by the daemon's program management API. - Tauri commands `get_program_management` (GET /v1/programs) and `set_program_choice` (POST /v1/programs/choice) relay to the daemon. - The desktop model polls program management with the existing status poll and adds `setProgramChoice`, which shows the choice while saving and reports the daemon's error text when it refuses one. - When the policy allows a choice, the card offers All / Only these / None with a switch per configured tool; otherwise it lists the tools as managed by the organization. Each tool shows its last apply state, including "Opted out". - Stories cover each state, the choices sent, and the refused case. Refs #174
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.
Part of #174. Stacked on #177 (
feat/program-opt-out). Rebase ontomainafter #177 merges.What
This adds a Managed tools card to the desktop Settings view. It is built on the daemon's
GET /v1/programsandPOST /v1/programs/choiceroutes from #177.Native host (
crates/agentdesktop/src/main.rs)get_program_managementrelays toGET /v1/programs.set_program_choicerelays toPOST /v1/programs/choiceviaagentdesktop_client::post_json_decodeand returns the updatedProgramManagement.frontend/desktop/ARCHITECTURE.md.Model (
useDesktopModel.ts)setProgramChoice(choice)runs in a transition:useOptimisticshows the chosen mode while it saves.programSelection.allowUserChoiceis off.Settings card (
views/SettingsView.tsx)userChoiceAllowed: an All / Only these / None radio group, plus a switch for each configured tool. The switches are enabled only under "Only these".ToolIcon/friendlyTool) and a badge with its last apply state.opted_outreads "Opted out". A state's detail is linked as the switch's description..inline-preference,.switchand.badgestyles.Tests
SettingsView.stories.tsx:ProgramChoicesent for switch toggles, each radio, and "Only these" chosen from All.stories/ManagedTools.stories.tsxruns the full app over mocked IPC: opting out of every tool succeeds, and a 403 refusal shows the daemon's message and reverts the choice.a11y: { test: "error" }.cd frontend && pnpm checkpasses.cargo clippy -p agentdesktop --all-targets -- -D warningsis clean.cargo fmt --checkis clean.