Default shipped UI sessions to workspace-write

This commit is contained in:
Tianyi Cui
2026-07-31 20:39:53 +08:00
parent e1eb581f2b
commit b694c33d18
48 changed files with 227 additions and 143 deletions

View File

@@ -70,14 +70,7 @@ describe('web e2e: Full access confirmation', () => {
const access = page.locator('button[aria-label^="访问模式"]').first()
await access.waitFor({ timeout: 10_000 })
// Normalize the starting preset through the real command path. The
// shipped web config may already start at Full access.
if ((await access.getAttribute('aria-label'))?.endsWith('Full access') === true) {
await access.click()
await page.getByRole('menuitem', { name: 'Workspace Write' }).click()
await expect.poll(() => access.getAttribute('aria-label'), { timeout: 10_000 })
.toBe('访问模式当前Workspace Write')
}
expect(await access.getAttribute('aria-label')).toBe('访问模式当前Workspace Write')
await access.click()
await page.getByRole('menuitem', { name: 'Full access' }).click()

View File

@@ -339,19 +339,19 @@ describe('web e2e: seeded history renders through cold resume', () => {
onTestFailed(() => saveFailureShot(page, 'web-e2e-seeded-command-row'))
// The Access chip submits `/permission <preset>` — a host command with no
// model call, so the settled row renders keylessly over this cold history.
// The row copy is the assertion: `permission · preset workspace-write`,
// The row copy is the assertion: `permission · preset read-only`,
// where neither half repeats the other (the dispatched `/` and its
// argument stay out of the title, and the settlement text never restates
// the command's own name).
await page.getByRole('button', { name: 'Access mode, current: Full access' }).click()
await page.getByRole('menuitem', { name: 'Workspace Write' }).click()
await page.getByRole('button', { name: 'Access mode, current: Workspace Write' }).waitFor({ timeout: 10_000 })
await page.getByRole('button', { name: 'Access mode, current: Workspace Write' }).click()
await page.getByRole('menuitem', { name: 'Read Only' }).click()
await page.getByRole('button', { name: 'Access mode, current: Read Only' }).waitFor({ timeout: 10_000 })
// Scoped to the row itself, so unrelated page text that happens to read
// `permission` (a future resident slash menu) cannot satisfy or break it.
const row = page.locator('[data-variant="others"]').filter({ hasText: 'preset workspace-write' })
const row = page.locator('[data-variant="others"]').filter({ hasText: 'preset read-only' })
await expect.poll(() => row.count(), { timeout: 10_000 }).toBe(1)
expect(await row.getByText('permission', { exact: true }).count()).toBe(1)
expect(await row.getByText('/permission workspace-write', { exact: true }).count()).toBe(0)
expect(await row.getByText('/permission read-only', { exact: true }).count()).toBe(0)
const snapshot = (await captureStableAria(page, '[class*="centerCol"]', scaffold.workspaceCwd))
.split(SEED_ID).join('{{seededId}}')
await compareOrRefreshGolden(COMMAND_ROW_EXPECTED, snapshot, MODE)

View File

@@ -57,7 +57,7 @@ describe('web e2e: settings modal and General preferences', () => {
expect(await trigger.getAttribute('aria-expanded')).toBe('true')
// General is active by default; Permission, Language and Appearance are functional.
expect(await dialog.getByRole('button', { name: '通用设置' }).getAttribute('aria-current')).toBe('true')
await dialog.getByRole('button', { name: 'Full access' }).waitFor({ timeout: 10_000 })
await dialog.getByRole('button', { name: 'Workspace Write' }).waitFor({ timeout: 10_000 })
await expect.poll(() => dialog.getByText('语言', { exact: true }).count(), { timeout: 5_000 }).toBe(1)
await expect.poll(() => dialog.getByText('外观', { exact: true }).count(), { timeout: 5_000 }).toBe(1)
// Golden of the freshly opened dialog (default zh, General active).
@@ -82,12 +82,12 @@ describe('web e2e: settings modal and General preferences', () => {
onTestFailed(() => saveFailureShot(page, 'web-e2e-settings-permission'))
const existing = scaffold.ctx.sessions.create(SessionId('settings-permission-before'))
expect(existing.events.find(event => event.type === 'permission/preset')?.data)
.toEqual({ preset: 'danger-full-access' })
.toEqual({ preset: 'workspace-write' })
await page.getByRole('button', { name: '设置', exact: true }).click()
const dialog = page.getByRole('dialog', { name: '设置' })
await dialog.waitFor({ timeout: 10_000 })
const selector = dialog.getByRole('button', { name: 'Full access' })
const selector = dialog.getByRole('button', { name: 'Workspace Write' })
await selector.waitFor({ timeout: 10_000 })
await expect.poll(() => selector.isEnabled(), { timeout: 5_000 }).toBe(true)
await selector.click()
@@ -98,7 +98,7 @@ describe('web e2e: settings modal and General preferences', () => {
expect(document).toContain('permission:')
expect(document).toContain('defaultPreset: read-only')
expect(existing.events.find(event => event.type === 'permission/preset')?.data)
.toEqual({ preset: 'danger-full-access' })
.toEqual({ preset: 'workspace-write' })
const created = scaffold.ctx.sessions.create(SessionId('settings-permission-after'))
expect(created.events.map(event => [event.type, event.data])).toEqual([

View File

@@ -10,6 +10,7 @@ import { canonicalPath, writableRoots } from '@deepseek-ai/dsh-sandbox'
import type {} from '@deepseek-ai/dsh-tools'
import type {} from '@deepseek-ai/dsh-sandbox-policy'
import type {} from '@deepseek-ai/dsh-user-approval'
import type {} from '@deepseek-ai/dsh-permission'
import { launchWebScaffold, type WebScaffold } from './scaffold.ts'
/**
@@ -63,7 +64,7 @@ afterEach(async () => {
scaffold = undefined
})
it('assembles the shipped Web catalog and keeps its access default', async () => {
it('assembles the shipped Web catalog with the confined access default', async () => {
scaffold = await launchWebScaffold()
const names = scaffold.ctx.tools.schemas().map(schema => schema.name).sort()
expect(names.filter(name => !RIPGREP_TOOLS.includes(name))).toEqual(EXPECTED_TOOLS)
@@ -76,8 +77,7 @@ it('assembles the shipped Web catalog and keeps its access default', async () =>
expect(writableRoots(scaffold.ctx.sandboxPolicy.resolve({ mode: 'workspace-write' }))).toEqual(
expect.arrayContaining([canonicalPath('/tmp'), canonicalPath(tmpdir())]),
)
// The Web surface keeps its shipped access default; the base's confined one
// reaches the TUI. Pinning both keeps a base change from moving Web silently.
expect(scaffold.ctx.sandboxPolicy.defaultMode).toBe('danger-full-access')
expect(scaffold.ctx.approval.config.policy).toBe('never')
expect(scaffold.ctx.sandboxPolicy.defaultMode).toBe('workspace-write')
expect(scaffold.ctx.approval.config.policy).toBe('ask')
expect(scaffold.ctx.permission.defaultPreset).toBe('workspace-write')
}, 120_000)

View File

@@ -39,7 +39,7 @@
- textbox "Message the agent"
- button "Commands":
- img
- 'button "Access mode, current: Full access"': Full access
- 'button "Access mode, current: Workspace Write"': Workspace Write
- button "Select model, current DeepSeek-V4-Flash":
- text: DeepSeek-V4-Flash
- img

View File

@@ -54,7 +54,7 @@
- textbox "Message the agent"
- button "Commands":
- img
- 'button "Access mode, current: Full access"': Full access
- 'button "Access mode, current: Workspace Write"': Workspace Write
- button "Select model, current DeepSeek-V4-Flash":
- text: DeepSeek-V4-Flash
- img

View File

@@ -34,7 +34,7 @@
- textbox "Message the agent"
- button "Commands":
- img
- 'button "Access mode, current: Full access"': Full access
- 'button "Access mode, current: Workspace Write"': Workspace Write
- button "Select model, current DeepSeek-V4-Flash":
- text: DeepSeek-V4-Flash
- img

View File

@@ -28,7 +28,7 @@
- textbox "Describe what you want to build"
- button "Commands":
- img
- 'button "Access mode, current: Full access"': Full access
- 'button "Access mode, current: Workspace Write"': Workspace Write
- button "Select model, current DeepSeek-V4-Flash":
- text: DeepSeek-V4-Flash
- img

View File

@@ -28,7 +28,7 @@
- textbox "Describe what you want to build"
- button "Commands":
- img
- 'button "Access mode, current: Full access"': Full access
- 'button "Access mode, current: Workspace Write"': Workspace Write
- button "Plan mode on, press to turn off": Plan
- button "Select model, current deepseek-v4-flash":
- text: deepseek-v4-flash

View File

@@ -26,7 +26,7 @@
- textbox "Message the agent"
- button "Commands":
- img
- 'button "Access mode, current: Full access"': Full access
- 'button "Access mode, current: Workspace Write"': Workspace Write
- button "Select model, current DeepSeek-V4-Flash":
- text: DeepSeek-V4-Flash
- img

View File

@@ -23,7 +23,7 @@
- textbox "Message the agent"
- button "Commands":
- img
- 'button "Access mode, current: Full access"': Full access
- 'button "Access mode, current: Workspace Write"': Workspace Write
- button "Select model, current DeepSeek-V4-Flash":
- text: DeepSeek-V4-Flash
- img

View File

@@ -19,7 +19,7 @@
- textbox "Message the agent"
- button "Commands":
- img
- 'button "Access mode, current: Full access"': Full access
- 'button "Access mode, current: Workspace Write"': Workspace Write
- button "Select model, current DeepSeek-V4-Flash":
- text: DeepSeek-V4-Flash
- img

View File

@@ -18,7 +18,7 @@
- textbox "Message the agent"
- button "Commands":
- img
- 'button "Access mode, current: Full access"': Full access
- 'button "Access mode, current: Workspace Write"': Workspace Write
- button "Select model, current DeepSeek-V4-Flash":
- text: DeepSeek-V4-Flash
- img

View File

@@ -28,7 +28,7 @@
- textbox "Message the agent"
- button "Commands":
- img
- 'button "Access mode, current: Full access"': Full access
- 'button "Access mode, current: Workspace Write"': Workspace Write
- button "Select model, current DeepSeek-V4-Flash":
- text: DeepSeek-V4-Flash
- img

View File

@@ -37,7 +37,7 @@
- textbox "Message the agent"
- button "Commands":
- img
- 'button "Access mode, current: Full access"': Full access
- 'button "Access mode, current: Workspace Write"': Workspace Write
- button "Select model, current deepseek-v4-flash":
- text: deepseek-v4-flash
- img

View File

@@ -39,7 +39,7 @@
- textbox "Message the agent"
- button "Commands":
- img
- 'button "Access mode, current: Full access"': Full access
- 'button "Access mode, current: Workspace Write"': Workspace Write
- button "Select model, current DeepSeek-V4-Flash":
- text: DeepSeek-V4-Flash
- img

View File

@@ -34,7 +34,7 @@
- textbox "Message the agent"
- button "Commands":
- img
- 'button "Access mode, current: Full access"': Full access
- 'button "Access mode, current: Workspace Write"': Workspace Write
- button "Select model, current DeepSeek-V4-Flash":
- text: DeepSeek-V4-Flash
- img

View File

@@ -19,7 +19,7 @@
- textbox "Message the agent"
- button "Commands":
- img
- 'button "Access mode, current: Full access"': Full access
- 'button "Access mode, current: Workspace Write"': Workspace Write
- button "Select model, current DeepSeek-V4-Flash":
- text: DeepSeek-V4-Flash
- img

View File

@@ -32,7 +32,7 @@
- textbox "Message the agent"
- button "Commands":
- img
- 'button "Access mode, current: Full access"': Full access
- 'button "Access mode, current: Workspace Write"': Workspace Write
- button "Select model, current DeepSeek-V4-Flash":
- text: DeepSeek-V4-Flash
- img

View File

@@ -25,7 +25,7 @@
- textbox "Message the agent"
- button "Commands":
- img
- 'button "Access mode, current: Full access"': Full access
- 'button "Access mode, current: Workspace Write"': Workspace Write
- button "Select model, current DeepSeek-V4-Flash":
- text: DeepSeek-V4-Flash
- img

View File

@@ -41,11 +41,11 @@
- img
- text: Context injection
- img
- text: permission preset workspace-write
- text: permission preset read-only
- textbox "Message the agent"
- button "Commands":
- img
- 'button "Access mode, current: Workspace Write"': Workspace Write
- 'button "Access mode, current: Read Only"': Read Only
- button "Select model, current deepseek-v4-flash":
- text: deepseek-v4-flash
- img

View File

@@ -43,7 +43,7 @@
- textbox "Message the agent"
- button "Commands":
- img
- 'button "Access mode, current: Full access"': Full access
- 'button "Access mode, current: Workspace Write"': Workspace Write
- button "Select model, current deepseek-v4-flash":
- text: deepseek-v4-flash
- img

View File

@@ -11,8 +11,8 @@
- img
- text: 关闭
- text: 权限 选择新会话的默认权限模式
- button "Full access":
- text: Full access
- button "Workspace Write":
- text: Workspace Write
- img
- text: 语言
- button "中文":

View File

@@ -35,7 +35,7 @@
- textbox "Message the agent"
- button "Commands":
- img
- 'button "Access mode, current: Full access"': Full access
- 'button "Access mode, current: Workspace Write"': Workspace Write
- button "Select model, current DeepSeek-V4-Flash":
- text: DeepSeek-V4-Flash
- img

View File

@@ -26,7 +26,7 @@
- textbox "Message the agent"
- button "Commands":
- img
- 'button "Access mode, current: Full access"': Full access
- 'button "Access mode, current: Workspace Write"': Workspace Write
- button "Select model, current DeepSeek-V4-Flash":
- text: DeepSeek-V4-Flash
- img