diff --git a/docs/user/permission-modes.md b/docs/user/permission-modes.md index 796e3f316122d..178c753dbfd78 100644 --- a/docs/user/permission-modes.md +++ b/docs/user/permission-modes.md @@ -27,12 +27,11 @@ the parent conversation with the subagent's name, so you can respond without swi ## Provider differences Providers enforce permissions differently. Some read-only actions can proceed in **Supervised**. -**Auto** uses automatic review on Codex, Claude, Cursor, Grok, and fx; providers without an equivalent, +**Auto** uses automatic review on Codex, Claude, Cursor, Grok, Muse Code, and fx; providers without an equivalent, including OpenCode and Antigravity, fall back to asking. On Grok, commands its review blocks come to you for approval. On fx, prompts it still sends also come to you. -Muse Code offers only **Supervised** and **Full access**. A Muse thread already set to another mode -runs in **Supervised**. +Muse Code offers no **Auto-accept edits**. A Muse thread already set to it runs in **Supervised**. T3 Code offers no **Auto-accept edits** or **Full access** for fx. An fx thread already set to either runs in **Supervised**. diff --git a/docs/user/providers-muse.md b/docs/user/providers-muse.md index df506e678bcc1..b6e87e8d49fce 100644 --- a/docs/user/providers-muse.md +++ b/docs/user/providers-muse.md @@ -45,9 +45,11 @@ can use under **Custom models** in the instance settings. ## Permissions and limitations -Muse offers two [permission modes](./permission-modes.md): **Supervised** asks -before commands and edits, and **Full access** runs them without asking. Muse has -no equivalent of **Auto-accept edits** or **Auto**, so they are not offered. +Muse offers three [permission modes](./permission-modes.md): **Supervised** asks +before commands and edits, **Auto** keeps the sandbox on and lets Muse's +automatic review decide actions the sandbox restricts, and **Full access** runs +everything without asking. Muse has no equivalent of **Auto-accept edits**, so +it is not offered. Muse can use T3 Code's tools. If Muse cannot reach them, the turn continues without them. Switching providers can pass conversation context as a handoff. diff --git a/packages/provider-muse/src/server/adapter.test.ts b/packages/provider-muse/src/server/adapter.test.ts index 76b46715c6020..5ae7b30bad212 100644 --- a/packages/provider-muse/src/server/adapter.test.ts +++ b/packages/provider-muse/src/server/adapter.test.ts @@ -420,6 +420,7 @@ describe("MuseAdapterV2", () => { Effect.gen(function* () { for (const [runtimeMode, profile, approvalMode] of [ ["approval-required", ":ask-me", "promptUnmatched"], + ["auto", ":auto-review", "onRequest"], ["full-access", ":unrestricted", "allowAll"], ] as const) { const policy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ diff --git a/packages/provider-muse/src/server/sdk.test.ts b/packages/provider-muse/src/server/sdk.test.ts index 739b8c04ff441..297b302fc12d6 100644 --- a/packages/provider-muse/src/server/sdk.test.ts +++ b/packages/provider-muse/src/server/sdk.test.ts @@ -16,7 +16,6 @@ import { createMuseSdkHost, createMuseSdkHostEffect, makeMuseEnvironment, - museApprovalMode, museLaunch, museVerbatimPath, museWorkspaceRoot, @@ -102,7 +101,6 @@ describe("Muse SDK host", () => { ? ["serve", "--trust-workspace", "--disable-sandbox"] : ["serve", "--trust-workspace"], }); - expect(museApprovalMode(mode)).toBe(mode === "full-access" ? "allowAll" : "promptUnmatched"); fake.startup.resolve(fake.ready); const host = await running; fake.shutdown.resolve({ code: 0, signal: null }); diff --git a/packages/provider-muse/src/server/sdk.ts b/packages/provider-muse/src/server/sdk.ts index 0269a64d9c967..068d2b89ba84e 100644 --- a/packages/provider-muse/src/server/sdk.ts +++ b/packages/provider-muse/src/server/sdk.ts @@ -132,13 +132,16 @@ export const museLaunch = Effect.fn("museLaunch")(function* ( }; }); +// Auto's onRequest asks only for actions the sandboxed profile restricts. export function museApprovalMode(runtimeMode: RuntimeMode) { - return runtimeMode === "full-access" ? "allowAll" : "promptUnmatched"; + if (runtimeMode === "full-access") return "allowAll"; + return runtimeMode === "auto" ? "onRequest" : "promptUnmatched"; } -// Select explicitly; Muse defaults may let an AI reviewer decide approvals. +// Select explicitly; Muse defaults may let an AI reviewer decide approvals, so only Auto opts in. export function musePermissionProfile(runtimeMode: RuntimeMode) { - return runtimeMode === "full-access" ? ":unrestricted" : ":ask-me"; + if (runtimeMode === "full-access") return ":unrestricted"; + return runtimeMode === "auto" ? ":auto-review" : ":ask-me"; } export function museServeArgs( diff --git a/packages/provider-muse/src/server/status.ts b/packages/provider-muse/src/server/status.ts index ef4940df11641..c7fbdb7b3863e 100644 --- a/packages/provider-muse/src/server/status.ts +++ b/packages/provider-muse/src/server/status.ts @@ -26,8 +26,8 @@ const MUSE_PRESENTATION = { displayName: "Muse Code", showInteractionModeToggle: false, reportsContextWindow: true, - // Muse has no accept-edits mode; map only :ask-me and :unrestricted. - supportedRuntimeModes: ["approval-required", "full-access"], + // Muse has no accept-edits mode; map only :ask-me, :auto-review, and :unrestricted. + supportedRuntimeModes: ["approval-required", "auto", "full-access"], } as const; const FALLBACK_CAPABILITIES = museModelCapabilities();