fix(plugins): use sentence case for built-in plugin English copy
Refs #6790
This commit is contained in:
1 parent
57fed3d7de
commit
b9d049d041
57 files changed
+138
-138
No files matched your search
@@ -86,7 +86,7 @@ describe('web e2e: Agent Teams panel', () => {
|
||||
const projectionReads = vi.spyOn(scaffold.ctx.sessionController, 'projections')
|
||||
onTestFinished(() => { projectionReads.mockRestore() })
|
||||
await page.locator('[data-team-action]').getByRole('button', { name: /Agent Team/iu }).click()
|
||||
const action = page.getByRole('dialog', { name: 'Agent Team', exact: true })
|
||||
const action = page.getByRole('dialog', { name: 'Agent team', exact: true })
|
||||
await action.getByText('No shared tasks yet. Create them through the conversation.').waitFor()
|
||||
await action.getByText('lead').waitFor()
|
||||
expect(projectionReads).not.toHaveBeenCalled()
|
||||
@@ -119,7 +119,7 @@ describe('web e2e: Agent Teams panel', () => {
|
||||
|
||||
it('keeps the panel inside the viewport and closes on outside click or Escape', async () => {
|
||||
onTestFailed(() => saveFailureShot(page, 'web-e2e-agent-team-panel-keyboard'))
|
||||
const panel = page.getByRole('dialog', { name: 'Agent Team', exact: true })
|
||||
const panel = page.getByRole('dialog', { name: 'Agent team', exact: true })
|
||||
const trigger = page.locator('[data-team-action]').getByRole('button', { name: /Agent Team/iu })
|
||||
const viewport = page.viewportSize()!
|
||||
await trigger.click()
|
||||
@@ -162,8 +162,8 @@ describe('web e2e: Agent Teams panel', () => {
|
||||
})
|
||||
|
||||
it('keeps the hovered panel open when the pointer returns directly to its trigger', async () => {
|
||||
const trigger = page.locator('[data-team-action]').getByRole('button', { name: 'Agent Team', exact: true })
|
||||
const panel = page.getByRole('dialog', { name: 'Agent Team', exact: true })
|
||||
const trigger = page.locator('[data-team-action]').getByRole('button', { name: 'Agent team', exact: true })
|
||||
const panel = page.getByRole('dialog', { name: 'Agent team', exact: true })
|
||||
await trigger.hover()
|
||||
await panel.waitFor()
|
||||
await panel.hover()
|
||||
@@ -182,8 +182,8 @@ describe('web e2e: Agent Teams panel', () => {
|
||||
writeScopes: [],
|
||||
})
|
||||
const viewport = page.viewportSize()!
|
||||
const trigger = page.locator('[data-team-action]').getByRole('button', { name: 'Agent Team', exact: true })
|
||||
const panel = page.getByRole('dialog', { name: 'Agent Team', exact: true })
|
||||
const trigger = page.locator('[data-team-action]').getByRole('button', { name: 'Agent team', exact: true })
|
||||
const panel = page.getByRole('dialog', { name: 'Agent team', exact: true })
|
||||
const card = panel.locator('article').filter({ hasText: 'Responsive task' })
|
||||
await trigger.click()
|
||||
await card.waitFor()
|
||||
|
||||
@@ -73,15 +73,15 @@ it.skipIf(process.platform !== 'darwin')('keeps system requests pending until fr
|
||||
expect(await card.getByRole('button', { name: /Accessibility permission|Screen Recording permission/ }).count()).toBe(0)
|
||||
await page.setViewportSize({ width: 1680, height: 600 })
|
||||
const plugins = page.locator('[data-plugin-panel]')
|
||||
const openDetails = page.getByRole('button', { name: 'View Computer Use', exact: true })
|
||||
const openDetails = page.getByRole('button', { name: 'View Computer use', exact: true })
|
||||
await openDetails.scrollIntoViewIfNeeded()
|
||||
expect(await plugins.evaluate(element => element.scrollTop)).toBeGreaterThan(0)
|
||||
await openDetails.click()
|
||||
const panel = page.locator('[data-cua-settings]')
|
||||
const accessibility = panel.getByRole('group', { name: 'Accessibility', exact: true })
|
||||
await accessibility.getByRole('button', { name: 'Request permission', exact: true }).waitFor()
|
||||
expect(await panel.getByRole('region', { name: 'Authorize Computer Use', exact: true }).getByRole('group').count()).toBe(4)
|
||||
expect(await panel.getByRole('region', { name: 'Manage applications Computer Use can access', exact: true }).count()).toBe(1)
|
||||
expect(await panel.getByRole('region', { name: 'Authorize computer use', exact: true }).getByRole('group').count()).toBe(4)
|
||||
expect(await panel.getByRole('region', { name: 'Manage applications computer use can access', exact: true }).count()).toBe(1)
|
||||
await expect.poll(() => panel.locator('li img').evaluate((image: HTMLImageElement) => image.naturalWidth)).toBe(1)
|
||||
expect(await panel.getByText('/fixture/app', { exact: true }).count()).toBe(0)
|
||||
expect(await accessibility.getByText('Visual Studio Code.app', { exact: true }).count()).toBe(1)
|
||||
@@ -177,7 +177,7 @@ it.skipIf(process.platform !== 'darwin')('keeps system requests pending until fr
|
||||
return { errors, layouts, documents, stop: () => { observer.disconnect(); cancelAnimationFrame(frame) } }
|
||||
})
|
||||
try {
|
||||
const toggle = page.locator('[data-plugin-panel]').getByRole('switch', { name: 'Enable Computer Use', exact: true })
|
||||
const toggle = page.locator('[data-plugin-panel]').getByRole('switch', { name: 'Enable Computer use', exact: true })
|
||||
for (const width of [1680, 390]) {
|
||||
await page.setViewportSize({ width, height: 1000 })
|
||||
if (width === 390) await page.locator('[data-sidebar-collapsed]').waitFor({ state: 'attached' })
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
- region "Authorize Computer Use":
|
||||
- heading "Authorize Computer Use" [level=3]
|
||||
- region "Authorize computer use":
|
||||
- heading "Authorize computer use" [level=3]
|
||||
- group "Default mode for new sessions":
|
||||
- strong: Default mode for new sessions
|
||||
- paragraph: Computer Use is available only in PTC mode.
|
||||
- paragraph: Computer use is available only in PTC mode.
|
||||
- button "Set to PTC"
|
||||
- group "PTC execution mode":
|
||||
- strong: PTC execution mode
|
||||
@@ -17,8 +17,8 @@
|
||||
- paragraph: In System Settings, allow Visual Studio Code.app to capture application windows.
|
||||
- button "Request permission"
|
||||
- paragraph: Manage permissions in System Settings for the application named by macOS.
|
||||
- region "Manage applications Computer Use can access":
|
||||
- heading "Manage applications Computer Use can access" [level=3]
|
||||
- region "Manage applications computer use can access":
|
||||
- heading "Manage applications computer use can access" [level=3]
|
||||
- heading "Always-allowed applications" [level=4]
|
||||
- list:
|
||||
- listitem:
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
- bundle: Developer Tools
|
||||
- bundle: Developer tools
|
||||
description: Inspect and debug raw session data, grouped chat messages, and the NodeJS backend.
|
||||
- component: NodeJS Inspector
|
||||
- component: NodeJS inspector
|
||||
description: Press Ctrl/Cmd+Shift+. to open Chrome DevTools in the bottom panel for development and debugging.
|
||||
- component: Session Log
|
||||
- component: Session log
|
||||
description: Enable analysis of the current session's raw data and grouped chat messages in the session sidebar.
|
||||
- session sidebar: Session Log
|
||||
- session sidebar: Session log
|
||||
description: Analyze raw logs and grouped chat messages for the current session in the sidebar.
|
||||
- NodeJS bottom: NodeJS Inspector
|
||||
- NodeJS bottom: NodeJS inspector
|
||||
@@ -35,7 +35,7 @@ it('opens bottom DevTools after the Developer Tools bundle is enabled on an alre
|
||||
|
||||
await page.getByRole('navigation', { name: 'Global panels' }).getByRole('button', { name: 'Plugins', exact: true }).click()
|
||||
const plugins = page.locator('[data-plugin-panel]')
|
||||
const toggle = plugins.getByRole('switch', { name: 'Enable Developer Tools', exact: true })
|
||||
const toggle = plugins.getByRole('switch', { name: 'Enable Developer tools', exact: true })
|
||||
await toggle.waitFor()
|
||||
expect(await toggle.getAttribute('aria-checked')).toBe('false')
|
||||
const panel = page.locator('[data-inspector-panel]')
|
||||
|
||||
@@ -921,14 +921,14 @@ describe('web e2e: plugin manager', () => {
|
||||
expect(await child.getByText('为智能体提供成员协调、消息通信和共享任务管理工具。', { exact: true }).count()).toBe(1)
|
||||
try {
|
||||
await setLanguage('en')
|
||||
await panel.getByRole('heading', { name: 'Agent Teams', exact: true }).waitFor()
|
||||
await panel.getByRole('heading', { name: 'Agent teams', exact: true }).waitFor()
|
||||
expect(await packageName.textContent()).toBe('@deepseek-ai/dsh-experimental-agent-team-profile')
|
||||
expect(await panel.getByText('Enable team collaboration, team tools, the member roster, and the shared task board.').count()).toBe(1)
|
||||
await child.getByText('Team Tools', { exact: true }).waitFor()
|
||||
await child.getByText('Team tools', { exact: true }).waitFor()
|
||||
expect(await child.getByText('Give agents tools to coordinate members, exchange messages, and manage shared tasks.', { exact: true }).count()).toBe(1)
|
||||
await panel.getByRole('button', { name: 'Back to plugins' }).click()
|
||||
await panel.getByRole('button', { name: 'View Agent Teams', exact: true }).waitFor()
|
||||
expect(await panel.getByRole('switch', { name: 'Enable Agent Teams', exact: true }).count()).toBe(1)
|
||||
await panel.getByRole('button', { name: 'View Agent teams', exact: true }).waitFor()
|
||||
expect(await panel.getByRole('switch', { name: 'Enable Agent teams', exact: true }).count()).toBe(1)
|
||||
// Schedule ships in the delivered composition, so no bundle card carries it in either language.
|
||||
expect(await panel.getByRole('button', { name: 'View Automation tasks', exact: true }).count()).toBe(0)
|
||||
// The official configuration pages follow the language too, from their own dictionary.
|
||||
|
||||
@@ -776,7 +776,7 @@ async function openSessionInspector(page: Page): Promise<void> {
|
||||
// The showcase opens with a file tab in the right sidebar; a new tab shows the guide entries.
|
||||
await page.getByRole('button', { name: 'New tab', exact: true }).click()
|
||||
await page.locator('[data-sidebar-right-guide-entry="session-inspector-log"]').click({ timeout: 30_000 })
|
||||
await page.getByRole('table', { name: 'Raw Log', exact: true }).waitFor({ timeout: 15_000 })
|
||||
await page.getByRole('table', { name: 'Raw log', exact: true }).waitFor({ timeout: 15_000 })
|
||||
expect(await setBundle(page, INSPECTOR_BUNDLE, false)).toBe('applied')
|
||||
}
|
||||
|
||||
|
||||
@@ -46,12 +46,12 @@ it.skipIf(webSnapshotMode() === 'record')('inspects a replayed Session log and C
|
||||
await page.locator('[data-sidebar-right-guide-entry="session-inspector-log"]').click()
|
||||
const mode = page.getByRole('combobox', { name: 'Presentation', exact: true })
|
||||
expect(await mode.inputValue()).toBe('session-log')
|
||||
const raw = page.getByRole('table', { name: 'Raw Log', exact: true })
|
||||
const raw = page.getByRole('table', { name: 'Raw log', exact: true })
|
||||
await raw.getByRole('button', { name: 'Filter types', exact: true }).click()
|
||||
await page.getByRole('combobox', { name: 'Type keyword', exact: true }).fill('user/message')
|
||||
await page.getByRole('option', { name: 'user/message', exact: true }).click()
|
||||
await raw.getByRole('button', { name: 'user/message', exact: true }).first().click()
|
||||
const panel = page.locator('section[aria-label="Raw Log"]')
|
||||
const panel = page.locator('section[aria-label="Raw log"]')
|
||||
const details = panel.getByRole('separator').locator('..').locator('ul').first()
|
||||
expect(await details.innerText()).toContain(prompts[0])
|
||||
expect(await details.locator('details:not([open])').count()).toBe(0)
|
||||
@@ -64,14 +64,14 @@ it.skipIf(webSnapshotMode() === 'record')('inspects a replayed Session log and C
|
||||
const replacements = [...new Set(times)].filter(value => /^\d{2}:\d{2}:\d{2}\.\d{3}$/.test(value))
|
||||
.map(value => [value, '{{time}}'] as const)
|
||||
await compareOrRefreshGolden(join(directory, 'log.expected.md'),
|
||||
await captureStableAria(page, 'section[aria-label="Raw Log"] table', scaffold.workspaceCwd, { replacements }), webSnapshotMode())
|
||||
await captureStableAria(page, 'section[aria-label="Raw log"] table', scaffold.workspaceCwd, { replacements }), webSnapshotMode())
|
||||
await mode.selectOption('chat-node')
|
||||
const groups = page.getByRole('table', { name: 'Chat Group', exact: true })
|
||||
const groups = page.getByRole('table', { name: 'Chat group', exact: true })
|
||||
expect(await groups.getByRole('columnheader', { name: 'Time (UTC)' }).count()).toBe(0)
|
||||
await groups.getByRole('button', { name: 'assistant-step', exact: true }).first().click()
|
||||
await page.getByRole('navigation', { name: 'Raw data navigation', exact: true }).waitFor()
|
||||
const groupPanel = page.locator('section[aria-label="Chat Group"]')
|
||||
await groupPanel.locator('summary').filter({ hasText: 'Node Data' }).click()
|
||||
const groupPanel = page.locator('section[aria-label="Chat group"]')
|
||||
await groupPanel.locator('summary').filter({ hasText: 'Node data' }).click()
|
||||
const blocks = groupPanel.getByText('blocks:', { exact: true }).locator('..')
|
||||
await blocks.click()
|
||||
await blocks.locator('..').getByText('Other properties:', { exact: true }).waitFor()
|
||||
@@ -104,7 +104,7 @@ it.skipIf(webSnapshotMode() === 'record')('highlights nearby Chat content when t
|
||||
await page.getByText('DONE', { exact: true }).waitFor()
|
||||
await page.getByRole('button', { name: 'Open right sidebar', exact: true }).click()
|
||||
await page.locator('[data-sidebar-right-guide-entry="session-inspector-log"]').click()
|
||||
const table = page.getByRole('table', { name: 'Raw Log', exact: true })
|
||||
const table = page.getByRole('table', { name: 'Raw log', exact: true })
|
||||
await table.getByRole('button', { name: 'Filter types', exact: true }).click()
|
||||
await page.getByRole('combobox', { name: 'Type keyword', exact: true }).fill('tool/call')
|
||||
await page.getByRole('button', { name: 'Apply filter', exact: true }).click()
|
||||
|
||||
@@ -42,7 +42,7 @@ it('toggles bottom DevTools from the page and iframe without a selected Session'
|
||||
const close = panel.getByRole('button', { name: 'Collapse', exact: true })
|
||||
expect(await close.textContent()).toBe('')
|
||||
expect(await close.locator('svg').count()).toBe(1)
|
||||
const divider = panel.getByRole('separator', { name: 'Resize NodeJS Inspector panel' })
|
||||
const divider = panel.getByRole('separator', { name: 'Resize NodeJS inspector panel' })
|
||||
const drag = async (deltaY: number): Promise<void> => {
|
||||
const box = (await divider.boundingBox())!
|
||||
const x = box.x + box.width / 2
|
||||
@@ -93,10 +93,10 @@ it.each([
|
||||
openSidebar: '打开右侧边栏', sidebarDescription: '在侧边栏分析当前会话原始日志和聊天分组数据',
|
||||
},
|
||||
{
|
||||
locale: 'en-US', file: 'en', plugins: 'Plugins', open: 'View Developer Tools', bundle: 'Developer Tools',
|
||||
locale: 'en-US', file: 'en', plugins: 'Plugins', open: 'View Developer tools', bundle: 'Developer tools',
|
||||
description: 'Inspect and debug raw session data, grouped chat messages, and the NodeJS backend.',
|
||||
inspector: 'NodeJS Inspector', inspectorDescription: 'Press Ctrl/Cmd+Shift+. to open Chrome DevTools in the bottom panel for development and debugging.',
|
||||
session: 'Session Log', sessionDescription: "Enable analysis of the current session's raw data and grouped chat messages in the session sidebar.",
|
||||
inspector: 'NodeJS inspector', inspectorDescription: 'Press Ctrl/Cmd+Shift+. to open Chrome DevTools in the bottom panel for development and debugging.',
|
||||
session: 'Session log', sessionDescription: "Enable analysis of the current session's raw data and grouped chat messages in the session sidebar.",
|
||||
openSidebar: 'Open right sidebar', sidebarDescription: 'Analyze raw logs and grouped chat messages for the current session in the sidebar.',
|
||||
},
|
||||
])('shows the Inspector bundle and component copy in $locale', async (copy) => {
|
||||
@@ -150,7 +150,7 @@ it.each([
|
||||
` description: ${await sessionGuide.getByText(copy.sidebarDescription, { exact: true }).innerText()}`,
|
||||
`- NodeJS bottom: ${await bottomTitle.innerText()}`)
|
||||
await sessionGuide.click()
|
||||
await page.getByRole('table', { name: copy.locale === 'zh-CN' ? '原始数据' : 'Raw Log', exact: true }).waitFor()
|
||||
await page.getByRole('table', { name: copy.locale === 'zh-CN' ? '原始数据' : 'Raw log', exact: true }).waitFor()
|
||||
await compareOrRefreshGolden(fileURLToPath(new URL(`./expected/shared-inspector/metadata-${copy.file}.expected.md`, import.meta.url)),
|
||||
snapshot.join('\n'), webSnapshotMode())
|
||||
})
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
- dialog "Agent Team":
|
||||
- dialog "Agent team":
|
||||
- heading "Members" [level=3]
|
||||
- button "lead Current chat Inactive" [disabled]
|
||||
- heading "Shared tasks 2" [level=3]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
- dialog "Agent Team":
|
||||
- dialog "Agent team":
|
||||
- heading "Members" [level=3]
|
||||
- button "lead Current chat Inactive" [disabled]
|
||||
- heading "Shared tasks 1" [level=3]
|
||||
|
||||
@@ -70,9 +70,9 @@ it('persists the Git Worktrees switch and removes its capability while retaining
|
||||
}
|
||||
let panel = await openPlugins()
|
||||
let card = panel.locator(`[data-plugin-group="more"] [data-plugin-package="${BUNDLE}"]`)
|
||||
await card.getByRole('button', { name: 'View Git Worktrees', exact: true }).waitFor()
|
||||
await card.getByRole('button', { name: 'View Git worktrees', exact: true }).waitFor()
|
||||
expect(await card.getByText('Experimental', { exact: true }).count()).toBe(1)
|
||||
let toggle = card.getByRole('switch', { name: 'Enable Git Worktrees', exact: true })
|
||||
let toggle = card.getByRole('switch', { name: 'Enable Git worktrees', exact: true })
|
||||
expect(await toggle.getAttribute('aria-checked')).toBe('false')
|
||||
expect(await selectedBundles()).not.toContain(BUNDLE)
|
||||
expect(rows()).toEqual([])
|
||||
@@ -92,7 +92,7 @@ it('persists the Git Worktrees switch and removes its capability while retaining
|
||||
await page.reload({ waitUntil: 'load' })
|
||||
panel = await openPlugins()
|
||||
card = panel.locator(`[data-plugin-group="more"] [data-plugin-package="${BUNDLE}"]`)
|
||||
toggle = card.getByRole('switch', { name: 'Enable Git Worktrees', exact: true })
|
||||
toggle = card.getByRole('switch', { name: 'Enable Git worktrees', exact: true })
|
||||
await expect.poll(() => toggle.getAttribute('aria-checked')).toBe('true')
|
||||
expect(tools()).toContain('create_worktree')
|
||||
await toggle.click()
|
||||
@@ -108,7 +108,7 @@ it('persists the Git Worktrees switch and removes its capability while retaining
|
||||
|
||||
await page.reload({ waitUntil: 'load' })
|
||||
panel = await openPlugins()
|
||||
await expect.poll(() => panel.getByRole('switch', { name: 'Enable Git Worktrees', exact: true })
|
||||
await expect.poll(() => panel.getByRole('switch', { name: 'Enable Git worktrees', exact: true })
|
||||
.getAttribute('aria-checked')).toBe('false')
|
||||
expect(tools()).not.toContain('create_worktree')
|
||||
expect(await selectedBundles()).not.toContain(BUNDLE)
|
||||
|
||||
@@ -380,7 +380,7 @@ export const en = {
|
||||
installGuideFill: 'Use example',
|
||||
installGuideFillAria: 'Use the example {example}',
|
||||
installGuideSafety: 'Install only plugins you trust: they run with your permissions and can damage DeepSeek Harness or leak your data.',
|
||||
installUpgradeNotice: 'On-demand Official plugins offer Update when their version differs from DSH. To update other plugins, uninstall and reinstall them.',
|
||||
installUpgradeNotice: 'On-demand official plugins offer Update when their version differs from DSH. To update other plugins, uninstall and reinstall them.',
|
||||
registryToggle: 'Registry',
|
||||
registryLegend: 'The npm registry the plugin is downloaded from',
|
||||
registryDefault: 'Default registry',
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||

|
||||

|
||||
|
||||
Ask the agent you are talking to, the lead, to split a job. It creates named teammates, puts the work on a shared task board, waits for their results, and reports back.
|
||||
|
||||
## How to use
|
||||
|
||||
- Ask in plain words, for example: "Use Agent Teams to split this task between two teammates, wait, and summarize."
|
||||
- Click **Agent Team** next to the conversation title to see **Members** and **Shared tasks**. Each task shows its status, **Owner**, **Write scopes**, and the tasks it is **Blocked by**.
|
||||
- Ask in plain words, for example: "Use agent teams to split this task between two teammates, wait, and summarize."
|
||||
- Click **Agent team** next to the conversation title to see **Members** and **Shared tasks**. Each task shows its status, **Owner**, **Write scopes**, and the tasks it is **Blocked by**.
|
||||
- Click a teammate to open its conversation and talk to it there.
|
||||
- The panel is read-only. To change tasks or teammates, ask the lead.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"meta": {
|
||||
"title": "Agent Teams",
|
||||
"title": "Agent teams",
|
||||
"description": "Enable team collaboration, team tools, the member roster, and the shared task board.",
|
||||
"detail": "docs/DETAIL.md"
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"meta": {
|
||||
"title": "Team Collaboration",
|
||||
"title": "Team collaboration",
|
||||
"description": "Manage team members, member messages, and shared tasks."
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"meta": {
|
||||
"title": "Auto Authorization Review",
|
||||
"title": "Auto authorization review",
|
||||
"description": "Add an Auto review permission mode that uses the model to assess authorization before each tool call.",
|
||||
"detail": "docs/DETAIL.md"
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"meta": {
|
||||
"title": "Browser Use (Chrome DevTools)",
|
||||
"title": "Browser use (Chrome DevTools)",
|
||||
"description": "Let the model inspect and operate web pages through Chrome DevTools MCP in a launched Chrome."
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"meta": {
|
||||
"title": "Browser Use (Playwright)",
|
||||
"title": "Browser use (Playwright)",
|
||||
"description": "Let the model browse and operate web pages through Playwright MCP in a launched Chromium."
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"meta": {
|
||||
"title": "Team Panel",
|
||||
"title": "Team panel",
|
||||
"description": "View team members and shared tasks, and navigate to member conversations."
|
||||
}
|
||||
}
|
||||
@@ -37,10 +37,10 @@ export type TeamKey = keyof typeof zh
|
||||
|
||||
/** English dictionary checked against the Chinese key set. */
|
||||
export const en = {
|
||||
trigger: 'Agent Team',
|
||||
loading: 'Loading Team…',
|
||||
trigger: 'Agent team',
|
||||
loading: 'Loading team…',
|
||||
unavailable: 'Team is unavailable',
|
||||
failure: 'Invalid persisted Team record: {message}',
|
||||
failure: 'Invalid persisted team record: {message}',
|
||||
empty: 'No shared tasks yet. Create them through the conversation.',
|
||||
roster: 'Members',
|
||||
tasks: 'Shared tasks',
|
||||
|
||||
@@ -82,7 +82,7 @@ describe('ui-team browser plugin', () => {
|
||||
locale: 'agent-team',
|
||||
})
|
||||
const t = b.ctx.locale.bind('agent-team')
|
||||
expect(t('trigger')).toBe('Agent Team')
|
||||
expect(t('trigger')).toBe('Agent team')
|
||||
|
||||
expect(b.navigation).toEqual([])
|
||||
|
||||
|
||||
@@ -7,10 +7,10 @@ export const NS = 'cotTranslation'
|
||||
/** English copy and key source. */
|
||||
export const en = {
|
||||
provider: 'Translation service', google: 'Google', bing: 'Bing',
|
||||
deepseekAccount: 'DeepSeek Flash — Account (paid)', deepseekOfficial: 'DeepSeek Flash — Official API (paid)',
|
||||
deepseekAccount: 'DeepSeek Flash — account (paid)', deepseekOfficial: 'DeepSeek Flash — official API (paid)',
|
||||
providerUnavailableOption: '{provider} — unavailable',
|
||||
providerUnavailable: 'This provider is unavailable. Configure your DeepSeek account or Official API provider, or choose an available service.',
|
||||
paidNotice: 'Each uncached fragment sends a separate paid DeepSeek Flash request through the selected account or Official API credentials. Reopening reasoning reuses saved results; changing the provider, language, source text, or request settings may send a new paid request.',
|
||||
providerUnavailable: 'This provider is unavailable. Configure your DeepSeek account or official API provider, or choose an available service.',
|
||||
paidNotice: 'Each uncached fragment sends a separate paid DeepSeek Flash request through the selected account or official API credentials. Reopening reasoning reuses saved results; changing the provider, language, source text, or request settings may send a new paid request.',
|
||||
anonymousNotice: 'Bing and Google need no translation login or API key. Their anonymous endpoints may reject or limit requests.', targetLanguage: 'Target language',
|
||||
targetLanguageHint: 'auto follows the UI language; language codes such as zh, en, and ja also work.',
|
||||
privacy: 'Expanded reasoning is sent to the selected service. It may contain private code or conversation details.',
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"meta": {
|
||||
"title": "Computer Use (Cua Driver MCP)",
|
||||
"title": "Computer use (Cua Driver MCP)",
|
||||
"description": "Let the model operate the desktop through a separately installed cua-driver executable."
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"meta": {
|
||||
"title": "Computer Use (Cua Driver)",
|
||||
"title": "Computer use (Cua Driver)",
|
||||
"description": "Let the model operate the desktop with the bundled Cua Driver runtime; needs desktop permissions for the app that launches dsh."
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,7 @@ Expand a **Think** row to read its reasoning in your interface language. Paragra
|
||||
|
||||
- The reasoning you expand can contain your code and conversation details.
|
||||
- Bing is the default; Google is also available. Neither needs an account or API key, but neither guarantees availability or a free quota.
|
||||
- With a DeepSeek account or Official API set up, **DeepSeek Flash — Account (paid)** and **DeepSeek Flash — Official API (paid)** also appear. Each text piece without a saved translation is then a paid request.
|
||||
- With a DeepSeek account or official API set up, **DeepSeek Flash — account (paid)** and **DeepSeek Flash — official API (paid)** also appear. Each text piece without a saved translation is then a paid request.
|
||||
- Translations are saved in the session and reused when you reopen it. The original reasoning and the model's input stay unchanged.
|
||||
- Collapsed summaries stay in the original language. Translation can change Markdown formatting or code.
|
||||
- Turning the plugin off removes its buttons and cancels pending translations; saved translations stay in the session.
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"meta": {
|
||||
"title": "Computer Use",
|
||||
"description": "Currently supports macOS; Windows support is in development. Loads Computer Use for existing and new PTC sessions. Switch to PTC mode and grant Accessibility and Screen Recording permissions to use it.",
|
||||
"title": "Computer use",
|
||||
"description": "Currently supports macOS; Windows support is in development. Loads computer use for existing and new PTC sessions. Switch to PTC mode and grant Accessibility and Screen Recording permissions to use it.",
|
||||
"detail": "docs/DETAIL.md"
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,7 @@ export type NativeArchitecture = 'arm64' | 'x64'
|
||||
* @throws When the current host has no native implementation.
|
||||
*/
|
||||
export function nativeHostArchitecture(platform: string, architecture: string): NativeArchitecture {
|
||||
if (platform !== 'darwin' || (architecture !== 'arm64' && architecture !== 'x64')) throw new Error('Computer Use currently requires macOS on Apple silicon or Intel. Windows support is in development')
|
||||
if (platform !== 'darwin' || (architecture !== 'arm64' && architecture !== 'x64')) throw new Error('Computer use currently requires macOS on Apple silicon or Intel. Windows support is in development')
|
||||
return architecture
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ async function compileNative(spec: NativeBuildSpec, signal: AbortSignal, executa
|
||||
signal.throwIfAborted()
|
||||
if (outcome.exitCode !== 0 || outcome.signal !== null) {
|
||||
const diagnostics = `${handle.collected.stdout?.readFrom(0).text ?? ''}${handle.collected.stderr?.readFrom(0).text ?? ''}`
|
||||
throw new Error(`Computer Use native preparation failed (${String(outcome.exitCode)}, ${String(outcome.signal)}): ${diagnostics}`)
|
||||
throw new Error(`Computer use native preparation failed (${String(outcome.exitCode)}, ${String(outcome.signal)}): ${diagnostics}`)
|
||||
}
|
||||
const built = await readFile(join(scratch, 'release', 'dsh-cua-native'))
|
||||
let previous: Buffer | undefined
|
||||
@@ -107,7 +107,7 @@ async function compileNative(spec: NativeBuildSpec, signal: AbortSignal, executa
|
||||
try { retained = await readFile(runtime) } catch (error) {
|
||||
if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error
|
||||
}
|
||||
if (retained && !retained.equals(built)) throw new Error('Computer Use retained executable does not match its content digest')
|
||||
if (retained && !retained.equals(built)) throw new Error('Computer use retained executable does not match its content digest')
|
||||
signal.throwIfAborted()
|
||||
if (!retained) await writeFileAtomic(runtime, built, { mode: 0o755 })
|
||||
await access(runtime, constants.X_OK)
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
en: ceb54d964dc355b6
|
||||
zh: 0892066fbceef7b9
|
||||
/deepseek-ai-dsh-cua/use-this-package/permission-controls:
|
||||
en: be53792edc381ea1
|
||||
en: 7315ac8d68cf5d02
|
||||
zh: 037407055d9f34a0
|
||||
/deepseek-ai-dsh-cua/understand-the-implementation:
|
||||
en: a32743fc5b545ab3
|
||||
|
||||
@@ -43,7 +43,7 @@ Actions return `dispatched:true, verified:false`; read fresh state to verify the
|
||||
|
||||
### Permission controls
|
||||
|
||||
The [Computer Use bundle](../cua-bundle/README.md) mounts this page with its native provider. **Authorize Computer Use** groups the new-session default, PTC execution mode, Accessibility, and Screen Recording inside one border, with dividers between the rows. Each system-permission row shows the system-reported responsible application’s `.app` bundle filename and icon together in a bordered label. **Manage applications Computer Use can access** places the application lists inside a separate bordered group. Choose **Request permission**, find that application in the macOS permission list, and enable its switch; if macOS names another application, follow that prompt. With no detected source, the page directs the user to the application named by macOS. Each system-permission row has one control: **Request permission** when access is missing, or an outlined **Allowed** button with a settings icon after authorization. Clicking it opens the corresponding privacy pane, where the user can revoke access; hovering shows **Open System Settings**. Unknown status uses the same button with an **Unknown** label; pending initial observations retain a single placeholder. The page refreshes on entry, when the window regains focus, and after permission actions. A failed query offers **Retry**. Follow any macOS quit-and-reopen prompt and restart DSH as needed.
|
||||
The [Computer Use bundle](../cua-bundle/README.md) mounts this page with its native provider. **Authorize computer use** groups the new-session default, PTC execution mode, Accessibility, and Screen Recording inside one border, with dividers between the rows. Each system-permission row shows the system-reported responsible application’s `.app` bundle filename and icon together in a bordered label. **Manage applications computer use can access** places the application lists inside a separate bordered group. Choose **Request permission**, find that application in the macOS permission list, and enable its switch; if macOS names another application, follow that prompt. With no detected source, the page directs the user to the application named by macOS. Each system-permission row has one control: **Request permission** when access is missing, or an outlined **Allowed** button with a settings icon after authorization. Clicking it opens the corresponding privacy pane, where the user can revoke access; hovering shows **Open System Settings**. Unknown status uses the same button with an **Unknown** label; pending initial observations retain a single placeholder. The page refreshes on entry, when the window regains focus, and after permission actions. A failed query offers **Retry**. Follow any macOS quit-and-reopen prompt and restart DSH as needed.
|
||||
|
||||
System-permission operations affect the computer running DSH. When accessing DSH remotely, complete authorization on that computer.
|
||||
|
||||
|
||||
@@ -145,8 +145,8 @@ export class ApplicationAccess {
|
||||
let result: AskUserQuestionAnswer
|
||||
try {
|
||||
result = await questions.ask({ agent, signal, questions: [{ id: 'cua-app-access',
|
||||
question: `Allow Computer Use to launch if needed, read, capture, and control ${identity.name}?`,
|
||||
detail: 'Session access lasts until DSH restarts or Computer Use is disabled.',
|
||||
question: `Allow computer use to launch if needed, read, capture, and control ${identity.name}?`,
|
||||
detail: 'Session access lasts until DSH restarts or computer use is disabled.',
|
||||
options }] })
|
||||
} catch (error) {
|
||||
if (error instanceof UserQuestionError && error.code === 'ASK_CANCELLED') {
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
export const NS = 'cuaPermissions'
|
||||
/** English permission-page dictionary. */
|
||||
export const en = {
|
||||
title: 'Authorize Computer Use',
|
||||
applicationsTitle: 'Manage applications Computer Use can access',
|
||||
setupTitle: 'Set up Computer Use before use',
|
||||
setupBody: 'Computer Use is enabled. Before using it, switch to PTC mode and grant Accessibility and Screen Recording permissions. Open the plugin details to complete setup.',
|
||||
setupQueryFailed: 'Computer Use is enabled, but system permissions could not be checked. Open the plugin details to see the error and retry.',
|
||||
title: 'Authorize computer use',
|
||||
applicationsTitle: 'Manage applications computer use can access',
|
||||
setupTitle: 'Set up computer use before use',
|
||||
setupBody: 'Computer use is enabled. Before using it, switch to PTC mode and grant Accessibility and Screen Recording permissions. Open the plugin details to complete setup.',
|
||||
setupQueryFailed: 'Computer use is enabled, but system permissions could not be checked. Open the plugin details to see the error and retry.',
|
||||
defaultTitle: 'Default mode for new sessions',
|
||||
defaultBody: 'Computer Use is available only in PTC mode.',
|
||||
defaultBody: 'Computer use is available only in PTC mode.',
|
||||
defaultConfirm: 'Set to PTC', defaultSet: 'PTC is the default',
|
||||
defaultUnavailable: 'Could not read the default mode. Check it in Settings.',
|
||||
defaultReadOnly: 'Default-mode settings are read-only.',
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
en: 76368b6b1da79c80
|
||||
zh: 52384aee991ac542
|
||||
/deepseek-ai-dsh-experimental-inspector-profile/use-this-package:
|
||||
en: 919c4baad08a10a6
|
||||
en: 01ff66653aa262e7
|
||||
zh: 0f0c82abda2f3630
|
||||
/deepseek-ai-dsh-experimental-inspector-profile/understand-the-implementation:
|
||||
en: c9afee7b01eff431
|
||||
|
||||
@@ -24,11 +24,11 @@ Enable this optional bundle to inspect Session data in the Sidebar and open Node
|
||||
<a id="use-this-package"></a>
|
||||
## Use this package
|
||||
|
||||
Enable **Developer Tools** in Plugin Manager's official group. This selects `@deepseek-ai/dsh-experimental-inspector-profile` for the current Web profile.
|
||||
Enable **Developer tools** in Plugin Manager's official group. This selects `@deepseek-ai/dsh-experimental-inspector-profile` for the current Web profile.
|
||||
|
||||
Open **Session Log** from the Sidebar's new-tab menu or guide. [Session Inspector](../session-inspector/README.md) provides one view with selectable Raw Log and Chat Group presentations; Raw Log is selected initially.
|
||||
Open **Session log** from the Sidebar's new-tab menu or guide. [Session Inspector](../session-inspector/README.md) provides one view with selectable Raw Log and Chat Group presentations; Raw Log is selected initially.
|
||||
|
||||
Press **Ctrl/Cmd+Shift+.** to open or collapse **NodeJS Inspector** in the bottom panel with the packaged DevTools frontend. Enabling this bundle starts the local debugging backend and unredacted Host fetch capture; no user override or debugging argument is required.
|
||||
Press **Ctrl/Cmd+Shift+.** to open or collapse **NodeJS inspector** in the bottom panel with the packaged DevTools frontend. Enabling this bundle starts the local debugging backend and unredacted Host fetch capture; no user override or debugging argument is required.
|
||||
|
||||
-----
|
||||
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||

|
||||

|
||||
|
||||
Use it when troubleshooting: check exactly what DSH recorded for a session, or debug DSH itself in Chrome DevTools. It does not change how the agent works.
|
||||
|
||||
## How to use
|
||||
|
||||
- In the right sidebar, click **+** (**New tab**), then choose **Session Log** on the **Start** page that opens.
|
||||
- **Raw Log** lists the session's events grouped by turn and step; click a row to see its full data. Switch the selector to **Chat Group** to see the chat messages and their groups instead.
|
||||
- In the right sidebar, click **+** (**New tab**), then choose **Session log** on the **Start** page that opens.
|
||||
- **Raw log** lists the session's events grouped by turn and step; click a row to see its full data. Switch the selector to **Chat group** to see the chat messages and their groups instead.
|
||||
- Click the crosshair button next to the selector, then click a message in the chat to find its record. Press Esc to cancel.
|
||||
- Press **Ctrl+Shift+.** (**Cmd+Shift+.** on macOS) to open or collapse **NodeJS Inspector** at the bottom of the window: Chrome DevTools, in English, connected to the DSH backend.
|
||||
- Press **Ctrl+Shift+.** (**Cmd+Shift+.** on macOS) to open or collapse **NodeJS inspector** at the bottom of the window: Chrome DevTools, in English, connected to the DSH backend.
|
||||
|
||||
## Good to know
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"meta": {
|
||||
"title": "Developer Tools",
|
||||
"title": "Developer tools",
|
||||
"description": "Inspect and debug raw session data, grouped chat messages, and the NodeJS backend.",
|
||||
"detail": "docs/DETAIL.md"
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
en: 331f844c32631a82
|
||||
zh: a9bc365f7d61d9ed
|
||||
/deepseek-ai-dsh-experimental-inspector/use-this-package:
|
||||
en: 6d290aabc543f878
|
||||
en: 7d4d718b1a6f92ae
|
||||
zh: 7ad283b159ae2c29
|
||||
/deepseek-ai-dsh-experimental-inspector/runtime-layout:
|
||||
en: 7db0c435e07d5005
|
||||
|
||||
@@ -35,7 +35,7 @@ For trusted local development, `pnpm run demo:inspector` explicitly mounts the s
|
||||
|
||||
The bundle sets `experimental-inspector` to `disabled: false` with `captureFetch: true`. The Host's optional `--inspect` argument hook only opens an external Chrome window; it does not control whether the Inspector runs.
|
||||
|
||||
When this component is enabled, **Ctrl/Cmd+Shift+.** toggles **NodeJS Inspector** in the full-width bottom panel without requiring a selected Session. Drag its top edge to resize it, taking space from the content above; the selected height is retained across collapse and navigation. The focused divider also accepts Up/Down, Home and End. Its iframe loads on the first open and remains mounted while collapsed and across Session or main-panel navigation; unloading the component resets it. The X button and shortcut restore the opening control's focus when that control remains connected. The iframe automatically connects to this Host and opens Console; the manual Connection panel is omitted. Each embedded frontend shows Host and only its embedding page's Client in Console, Sources and the Cordis tree. The printed `devtools://` URL shows all Clients.
|
||||
When this component is enabled, **Ctrl/Cmd+Shift+.** toggles **NodeJS inspector** in the full-width bottom panel without requiring a selected Session. Drag its top edge to resize it, taking space from the content above; the selected height is retained across collapse and navigation. The focused divider also accepts Up/Down, Home and End. Its iframe loads on the first open and remains mounted while collapsed and across Session or main-panel navigation; unloading the component resets it. The X button and shortcut restore the opening control's focus when that control remains connected. The iframe automatically connects to this Host and opens Console; the manual Connection panel is omitted. Each embedded frontend shows Host and only its embedding page's Client in Console, Sources and the Cordis tree. The printed `devtools://` URL shows all Clients.
|
||||
|
||||
The Host serves the mirrored DevTools frontend at the application-relative `inspector/devtools/devtools_app.html` path, using the existing Web login. The `inspector/devtools` prefix redirects to that entry; GET and HEAD serve files, missing resources return 404, and other methods return 405. Its `cdp` WebSocket route authenticates the same browser session and forwards only to this Inspector's Worker page target. The bottom panel supplies its claimed `clientSourceId` to the entry and automatic WebSocket endpoint; the selection follows that logical Client across reconnects. An absent selector includes all Clients, an unavailable selected Client leaves Host visible, and empty or repeated selectors reject the upgrade with 400. Explicit `ws` or `wss` query parameters override the automatic endpoint, including its selection.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"meta": {
|
||||
"title": "NodeJS Inspector",
|
||||
"title": "NodeJS inspector",
|
||||
"description": "Press Ctrl/Cmd+Shift+. to open Chrome DevTools in the bottom panel for development and debugging."
|
||||
}
|
||||
}
|
||||
@@ -9,11 +9,11 @@ export const zh = {
|
||||
|
||||
/** English labels checked against the bottom-panel dictionary. */
|
||||
export const en: Record<keyof typeof zh, string> = {
|
||||
title: 'NodeJS Inspector',
|
||||
toggle: 'Toggle NodeJS Inspector',
|
||||
title: 'NodeJS inspector',
|
||||
toggle: 'Toggle NodeJS inspector',
|
||||
close: 'Collapse',
|
||||
resize: 'Resize NodeJS Inspector panel',
|
||||
frameTitle: 'NodeJS Inspector',
|
||||
resize: 'Resize NodeJS inspector panel',
|
||||
frameTitle: 'NodeJS inspector',
|
||||
}
|
||||
|
||||
declare module '@deepseek-ai/dsh-client-ui-slots' {
|
||||
|
||||
@@ -50,7 +50,7 @@ it('opens on Mod+Shift+Period without a Session or Sidebar and retains the ifram
|
||||
expect(press(window, { ctrlKey: false }).defaultPrevented).toBe(false)
|
||||
expect(body.container.querySelector('iframe')).toBeNull()
|
||||
expect(press().defaultPrevented).toBe(true)
|
||||
const frame = body.view.getByTitle('NodeJS Inspector')
|
||||
const frame = body.view.getByTitle('NodeJS inspector')
|
||||
expect(frame.getAttribute('src')).toBe('inspector/devtools/devtools_app.html?disableLocaleInfoBar=true&clientSourceId=client-page')
|
||||
expect(frame.getAttribute('referrerpolicy')).toBe('no-referrer')
|
||||
expect(frame.getAttribute('name')).toBe('dsh-nodejs-inspector')
|
||||
@@ -62,7 +62,7 @@ it('opens on Mod+Shift+Period without a Session or Sidebar and retains the ifram
|
||||
press()
|
||||
expect(body.container.querySelector('section')?.hidden).toBe(true)
|
||||
press()
|
||||
expect(body.view.getByTitle('NodeJS Inspector')).toBe(frame)
|
||||
expect(body.view.getByTitle('NodeJS inspector')).toBe(frame)
|
||||
expect(body.container.querySelector('section')?.hidden).toBe(false)
|
||||
})
|
||||
|
||||
@@ -70,8 +70,8 @@ it('resizes with the owned pointer, bounds the height, and retains it across col
|
||||
const { body } = await setup()
|
||||
press()
|
||||
const panel = body.container.querySelector('section')!
|
||||
const frame = body.view.getByTitle('NodeJS Inspector')
|
||||
const divider = body.view.getByRole('separator', { name: 'Resize NodeJS Inspector panel' })
|
||||
const frame = body.view.getByTitle('NodeJS inspector')
|
||||
const divider = body.view.getByRole('separator', { name: 'Resize NodeJS inspector panel' })
|
||||
let captured: number | undefined
|
||||
Object.assign(divider, {
|
||||
setPointerCapture: (id: number) => { captured = id },
|
||||
@@ -113,7 +113,7 @@ it('resizes with the owned pointer, bounds the height, and retains it across col
|
||||
press()
|
||||
press()
|
||||
expect(height()).toBe(20)
|
||||
expect(body.view.getByTitle('NodeJS Inspector')).toBe(frame)
|
||||
expect(body.view.getByTitle('NodeJS inspector')).toBe(frame)
|
||||
})
|
||||
|
||||
it('resizes the horizontal divider with arrow keys and Home or End', async () => {
|
||||
@@ -137,7 +137,7 @@ it('routes frame input through the effective binding and restores opener focus',
|
||||
try {
|
||||
opener.focus()
|
||||
press(opener)
|
||||
const frame = body.view.getByTitle<HTMLIFrameElement>('NodeJS Inspector')
|
||||
const frame = body.view.getByTitle<HTMLIFrameElement>('NodeJS inspector')
|
||||
const document = frame.contentDocument!
|
||||
frame.focus()
|
||||
expect(press(document).defaultPrevented).toBe(true)
|
||||
@@ -168,7 +168,7 @@ it('keeps modal arbitration and updates locale without replacing the iframe', as
|
||||
expect(body.container.querySelector('iframe')).toBeNull()
|
||||
} finally { modal.remove() }
|
||||
press()
|
||||
const frame = body.view.getByTitle('NodeJS Inspector')
|
||||
const frame = body.view.getByTitle('NodeJS inspector')
|
||||
act(() => { locale.setLocale('zh') })
|
||||
expect(body.view.getByTitle('NodeJS 诊断')).toBe(frame)
|
||||
act(() => { body.view.getByRole('button', { name: '收起' }).click() })
|
||||
@@ -178,7 +178,7 @@ it('keeps modal arbitration and updates locale without replacing the iframe', as
|
||||
it('removes the command and frame on unload and starts a fresh closed panel on reload', async () => {
|
||||
const { runtime, locale, provider, body, plugin } = await setup()
|
||||
press()
|
||||
const frame = body.view.getByTitle('NodeJS Inspector')
|
||||
const frame = body.view.getByTitle('NodeJS inspector')
|
||||
await provider.dispose()
|
||||
expect(runtime.ctx.shortcuts.catalog.getSnapshot().find(row => row.id === ID)).toBeUndefined()
|
||||
expect(frame.isConnected).toBe(false)
|
||||
@@ -186,5 +186,5 @@ it('removes the command and frame on unload and starts a fresh closed panel on r
|
||||
await runtime.mount(plugin)
|
||||
expect(body.container.querySelector('iframe')).toBeNull()
|
||||
press()
|
||||
expect(body.view.getByTitle('NodeJS Inspector')).not.toBe(frame)
|
||||
expect(body.view.getByTitle('NodeJS inspector')).not.toBe(frame)
|
||||
})
|
||||
@@ -9,13 +9,13 @@
|
||||
en: 151ad1f553a733d7
|
||||
zh: b2992178863a80c7
|
||||
/deepseek-ai-dsh-experimental-session-inspector/summary:
|
||||
en: 9ba1ce1f7f3c36ff
|
||||
en: 3f0006953eb4adbe
|
||||
zh: a6aaf26eb598a80a
|
||||
/deepseek-ai-dsh-experimental-session-inspector/table-of-contents:
|
||||
en: 76368b6b1da79c80
|
||||
zh: 52384aee991ac542
|
||||
/deepseek-ai-dsh-experimental-session-inspector/use-this-package:
|
||||
en: a54a88121496d7d0
|
||||
en: ec05c30394d91d56
|
||||
zh: 85fb112b26ec0ccb
|
||||
/deepseek-ai-dsh-experimental-session-inspector/understand-the-implementation:
|
||||
en: 6d71dcef4dca024b
|
||||
|
||||
@@ -9,7 +9,7 @@ English | [中文](README.zh.md)
|
||||
|
||||
## Summary
|
||||
|
||||
Inspect raw Session logs and Chat structures through the optional [Developer Tools bundle](../inspector-profile/README.md). Open **Session Log** from the Sidebar's new-tab menu or guide, then choose **Raw Log** or **Chat Group** from its upper-left selector. Follow object references between Nodes, Turns, and Steps, or locate a selected Node in Chat. Stream chunks appear as child rows, and Chat updates briefly highlight their rows. Both presentations support older history and resizable details without a composer.
|
||||
Inspect raw Session logs and Chat structures through the optional [Developer Tools bundle](../inspector-profile/README.md). Open **Session log** from the Sidebar's new-tab menu or guide, then choose **Raw log** or **Chat group** from its upper-left selector. Follow object references between Nodes, Turns, and Steps, or locate a selected Node in Chat. Stream chunks appear as child rows, and Chat updates briefly highlight their rows. Both presentations support older history and resizable details without a composer.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
@@ -56,7 +56,7 @@ Chat picking prefers the exact Node and reasoning/response part, then its Group,
|
||||
|
||||
Session Log uses the same field renderer for parsed JSON, with every nested object and array initially expanded. Containers can be collapsed individually; there are no reference buttons, breadcrumbs, collection-property disclosures, or collection paging. JSON retains `[Circular]` markers and readable bigint strings. Inspection failures appear locally without disabling the table. Preview filtering never removes fields from either detail presentation.
|
||||
|
||||
Ancestor rows remain sticky beneath the table header, one nesting level below another, with an opaque tinted background. Each level follows the first row not covered by the header or earlier sticky levels. Automatic block closure keeps the visible row or surviving parent at its screen position and leaves unused space only below the data; new rows fill that space before normal tail following resumes. A manual disclosure keeps the clicked header at its measured viewport position and pauses following, retaining only the trailing space needed to keep it visible. **Follow Latest** clears reserved space and resumes following. Scrolling upward or choosing **Load earlier** also pauses following. Raw Log shows UTC timestamps with the server's millisecond precision; Chat Group has no time column.
|
||||
Ancestor rows remain sticky beneath the table header, one nesting level below another, with an opaque tinted background. Each level follows the first row not covered by the header or earlier sticky levels. Automatic block closure keeps the visible row or surviving parent at its screen position and leaves unused space only below the data; new rows fill that space before normal tail following resumes. A manual disclosure keeps the clicked header at its measured viewport position and pauses following, retaining only the trailing space needed to keep it visible. **Follow latest** clears reserved space and resumes following. Scrolling upward or choosing **Load earlier** also pauses following. Raw Log shows UTC timestamps with the server's millisecond precision; Chat Group has no time column.
|
||||
|
||||
-----
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"meta": {
|
||||
"title": "Session Log",
|
||||
"title": "Session log",
|
||||
"description": "Enable analysis of the current session's raw data and grouped chat messages in the session sidebar."
|
||||
}
|
||||
}
|
||||
@@ -44,13 +44,13 @@ export const zh = {
|
||||
'table.collapse': '收起子行',
|
||||
'table.removed': '该记录已移除或结算,请选择当前记录。',
|
||||
'object.node': 'Node',
|
||||
'object.nodeData': 'Node Data',
|
||||
'object.nodeData': 'Node data',
|
||||
'object.group': 'Group',
|
||||
'object.groupData': 'Group Data',
|
||||
'object.groupData': 'Group data',
|
||||
'object.turn': 'Turn',
|
||||
'object.turnData': 'Turn Data',
|
||||
'object.turnData': 'Turn data',
|
||||
'object.step': 'Step',
|
||||
'object.stepData': 'Step Data',
|
||||
'object.stepData': 'Step data',
|
||||
'object.accessor': '[Getter / Setter,未执行]',
|
||||
'object.empty': '空',
|
||||
'object.absent': '[空槽]',
|
||||
@@ -71,16 +71,16 @@ declare module '@deepseek-ai/dsh-client-ui-slots' {
|
||||
|
||||
/** English labels, checked against the Chinese key set. */
|
||||
export const en: Record<SessionInspectorKey, string> = {
|
||||
'tab.title': 'Session Log',
|
||||
'tab.title': 'Session log',
|
||||
'tab.description': 'Analyze raw logs and grouped chat messages for the current session in the sidebar.',
|
||||
'view.presentation': 'Presentation',
|
||||
'view.sessionLog': 'Raw Log',
|
||||
'view.chatNode': 'Chat Group',
|
||||
'picker.pick': 'Pick an element in Chat View',
|
||||
'view.sessionLog': 'Raw log',
|
||||
'view.chatNode': 'Chat group',
|
||||
'picker.pick': 'Pick an element in the chat view',
|
||||
'picker.cancel': 'Cancel picking (Esc)',
|
||||
'picker.instructions': 'Hover in the main Chat to preview, then click to select. Esc cancels.',
|
||||
'picker.instructions': 'Hover in the main chat to preview, then click to select. Esc cancels.',
|
||||
'picker.noMatch': 'No matching record in this table. Pick another element or press Esc to cancel.',
|
||||
'picker.noChat': 'Open this Session in the main Chat before picking.',
|
||||
'picker.noChat': 'Open this session in the main chat before picking.',
|
||||
'table.id': 'Index',
|
||||
'table.type': 'Type',
|
||||
'filter.title': 'Filter types',
|
||||
@@ -100,7 +100,7 @@ export const en: Record<SessionInspectorKey, string> = {
|
||||
'table.data': 'Data',
|
||||
'table.older': 'Load earlier',
|
||||
'table.loading': 'Loading…',
|
||||
'table.latest': 'Follow Latest',
|
||||
'table.latest': 'Follow latest',
|
||||
'table.empty': 'No records',
|
||||
'table.raw': 'Raw data',
|
||||
'table.rawError': 'This record could not be serialized. Select another record to continue.',
|
||||
@@ -110,14 +110,14 @@ export const en: Record<SessionInspectorKey, string> = {
|
||||
'table.collapse': 'Collapse children',
|
||||
'table.removed': 'This record was removed or settled. Select a current record.',
|
||||
'object.node': 'Node',
|
||||
'object.nodeData': 'Node Data',
|
||||
'object.nodeData': 'Node data',
|
||||
'object.group': 'Group',
|
||||
'object.groupData': 'Group Data',
|
||||
'object.groupData': 'Group data',
|
||||
'object.turn': 'Turn',
|
||||
'object.turnData': 'Turn Data',
|
||||
'object.turnData': 'Turn data',
|
||||
'object.step': 'Step',
|
||||
'object.stepData': 'Step Data',
|
||||
'object.accessor': '[Getter / Setter, not evaluated]',
|
||||
'object.stepData': 'Step data',
|
||||
'object.accessor': '[Getter / setter, not evaluated]',
|
||||
'object.empty': 'Empty',
|
||||
'object.absent': '[Empty slot]',
|
||||
'object.properties': 'Other properties',
|
||||
|
||||
@@ -143,7 +143,7 @@ it('expands Node Data inline but keeps its title navigable and cyclic references
|
||||
target: { nodeKey: 'node-1' }, read: () => data }
|
||||
props.index.set(data, reference)
|
||||
const ui = render(<InspectorObjectTree {...props} value={{ data }} />)
|
||||
const link = ui.getByRole('button', { name: '↗ Node Data · 1' })
|
||||
const link = ui.getByRole('button', { name: '↗ Node data · 1' })
|
||||
const branch = link.closest('details')!
|
||||
expect(branch.open).toBe(false)
|
||||
expect(ui.queryByText('"inline node data"')).toBeNull()
|
||||
@@ -151,7 +151,7 @@ it('expands Node Data inline but keeps its title navigable and cyclic references
|
||||
fireEvent(branch, new Event('toggle'))
|
||||
expect(ui.getByText('"inline node data"')).toBeTruthy()
|
||||
expect(props.navigate).not.toHaveBeenCalled()
|
||||
expect(ui.getAllByRole('button', { name: '↗ Node Data · 1' })).toHaveLength(2)
|
||||
expect(ui.getAllByRole('button', { name: '↗ Node data · 1' })).toHaveLength(2)
|
||||
expect(ui.container.querySelectorAll('details')).toHaveLength(2)
|
||||
fireEvent.click(link)
|
||||
expect(props.navigate).toHaveBeenCalledExactlyOnceWith(reference)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# After editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write packages/experimental/session-search/README.md
|
||||
/:
|
||||
en: ac0fb71830f58337
|
||||
en: c8e3f38d9f1a4e2f
|
||||
zh: 0ece950cf48261a1
|
||||
/deepseek-ai-dsh-experimental-session-search:
|
||||
en: f4f9c83d1dd36580
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
description: "Give Agents tools to search and read earlier sessions from the current workspace."
|
||||
description: "Give agents tools to search and read earlier sessions from the current workspace."
|
||||
kind: "package-bundle"
|
||||
---
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"meta": {
|
||||
"title": "Session search",
|
||||
"description": "Give Agents tools to search and read earlier sessions from the current workspace.",
|
||||
"description": "Give agents tools to search and read earlier sessions from the current workspace.",
|
||||
"detail": "docs/DETAIL.md"
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@deepseek-ai/dsh-experimental-session-search",
|
||||
"description": "Give Agents tools to search and read earlier sessions from the current workspace.",
|
||||
"description": "Give agents tools to search and read earlier sessions from the current workspace.",
|
||||
"version": "0.2.1-rc.2",
|
||||
"icon": "./icon.svg",
|
||||
"publishConfig": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"meta": {
|
||||
"title": "Team Tools",
|
||||
"title": "Team tools",
|
||||
"description": "Give agents tools to coordinate members, exchange messages, and manage shared tasks."
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,7 @@
|
||||
en: d152484eb41ac6b4
|
||||
zh: 2f8a621b991260a1
|
||||
/deepseek-ai-dsh-experimental-tool-worktree/use-this-package:
|
||||
en: f69d3fdeed949ff5
|
||||
en: 06074f9f6989911b
|
||||
zh: 05c9a85b7cdcfbad
|
||||
/deepseek-ai-dsh-experimental-tool-worktree/understand-the-implementation:
|
||||
en: c03f875211ab69a8
|
||||
|
||||
@@ -25,7 +25,7 @@ Add Git Worktrees from the GUI plugin manager to let a model create and enter a
|
||||
<a id="use-this-package"></a>
|
||||
## Use this package
|
||||
|
||||
In the GUI, open **Plugins → Official → Git Worktrees** and turn on the switch. The bundle loads the [worktree runtime](../worktree/README.md) and this tool together; it is off in every shipped profile. Turning it off removes `create_worktree` without deleting existing checkouts or branches. The built-in `working_directory` tool remains available.
|
||||
In the GUI, open **Plugins → Official → Git worktrees** and turn on the switch. The bundle loads the [worktree runtime](../worktree/README.md) and this tool together; it is off in every shipped profile. Turning it off removes `create_worktree` without deleting existing checkouts or branches. The built-in `working_directory` tool remains available.
|
||||
|
||||
For an explicit composition, mount this function plugin after the worktree runtime and tool registry.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"meta": {
|
||||
"title": "Git Worktrees",
|
||||
"title": "Git worktrees",
|
||||
"description": "Let the agent create a new Git branch and worktree, then continue there.",
|
||||
"detail": "docs/DETAIL.md"
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"meta": {
|
||||
"title": "Composer Decoration",
|
||||
"title": "Composer decoration",
|
||||
"description": "Displays a blue circle below the message composer."
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"meta": {
|
||||
"title": "Demo MCP Connection",
|
||||
"title": "Demo MCP connection",
|
||||
"description": "Connects a remote MCP server to make its tools available to the agent."
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
- table "Raw Log":
|
||||
- table "Raw log":
|
||||
- rowgroup:
|
||||
- row "Index Type Filter types T/S Time (UTC) Data":
|
||||
- columnheader "Index"
|
||||
|
||||
Reference in new issue
Block a user