Merge remote-tracking branch 'origin/master' into worktree-guifork

This commit is contained in:
imccyu
2026-07-28 10:23:48 +08:00
710 changed files with 24719 additions and 6603 deletions

View File

@@ -167,6 +167,28 @@ describe('run_code sub-calls through the real chat machinery', () => {
expect(view.getByText('Tool call')).toBeTruthy()
})
it('renders Cordis sub-calls with lifecycle titles over the generic variants', async () => {
const parent = 'call-cordis'
const code = 'return { name: "audit", apply(ctx) {} }'
const dispatches = new Map([[parent, [
subCall(11, parent, 1, 'cordis_inspect', { what: 'temporary' }, '## Temporary Plugins'),
subCall(12, parent, 2, 'cordis_mount', { code }, 'Temporary Plugin dyn-2 is running'),
subCall(13, parent, 3, 'cordis_unmount', { id: 'dyn-2' }, 'Temporary Plugin dyn-2 was unmounted and removed.'),
]]])
const b = await bench(snapshotWith([codeResult(10, parent)], dispatches))
const view = mountApp(b.slots)
const nest = view.container.querySelector('[data-subcalls]')!
expect(nest.querySelector('[data-tool="cordis_inspect"]')?.textContent).toContain('Inspect')
const mounted = nest.querySelector('[data-variant="code"]')
expect(mounted?.textContent).toContain(`Mount temporary Plugin${code}`)
expect(nest.querySelector('[data-tool="cordis_unmount"]')?.textContent)
.toContain('Unmount temporary Plugindyn-2')
fireEvent.click(mounted!.querySelector('button[aria-expanded]')!)
expect(mounted!.querySelector('pre.shiki')?.textContent).toBe(code)
})
it('expanding the code row reveals the program body verbatim (shiki-tokenized)', async () => {
const parent = 'call-64'
const b = await bench(snapshotWith([codeResult(10, parent)], new Map()))

View File

@@ -31,6 +31,9 @@ describe('tool-call-model', () => {
expect(classifyTool('grep')).toBe('search')
expect(classifyTool('write')).toBe('write')
expect(classifyTool('edit')).toBe('edit')
expect(classifyTool('cordis_inspect')).toBe('read')
expect(classifyTool('cordis_mount')).toBe('code')
expect(classifyTool('cordis_unmount')).toBe('others')
expect(classifyTool('todo_write')).toBe('others')
})
@@ -67,6 +70,33 @@ describe('tool-call-model', () => {
expect(toolRowModel('bash', running({ argsRaw: '' })).body).toBeNull()
expect(toolRowModel('bash', result({ call: null })).body).toBeNull()
})
it('gives Cordis lifecycle tools action titles over their generic variants', () => {
expect(toolRowModel('cordis_inspect', running({
name: 'cordis_inspect',
argsRaw: '{"what":"api","name":"tools"}',
}))).toMatchObject({
variant: 'read',
title: 'Inspect',
summary: 'api',
})
expect(toolRowModel('cordis_mount', running({
name: 'cordis_mount',
argsRaw: '{"code":"return { name: \\"audit\\", apply(ctx) {} }"}',
}))).toMatchObject({
variant: 'code',
title: 'Mount temporary Plugin',
summary: 'return { name: "audit", apply(ctx) {} }',
body: 'return { name: "audit", apply(ctx) {} }',
})
expect(toolRowModel('cordis_unmount', result({
call: { name: 'cordis_unmount', argsRaw: '{"id":"dyn-2"}' },
}))).toMatchObject({
variant: 'others',
title: 'Unmount temporary Plugin',
summary: 'dyn-2',
})
})
})
describe('ToolRow', () => {

View File

@@ -12,7 +12,7 @@
import { Context } from 'cordis'
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import { act, cleanup, render } from '@testing-library/react'
import { act, cleanup, fireEvent, render } from '@testing-library/react'
import { createSnapshotStore, SlotsService } from '@deepseek-ai/dsh-client-runtime/client'
import type {
ConversationSnapshot, SessionId, SessionListState, ToolResultNode, WorkspaceListState,
@@ -166,6 +166,25 @@ describe('keyed toolview hole through the real machinery', () => {
expect(view.getByText('Tool call')).toBeTruthy()
})
it('renders top-level Cordis calls with lifecycle titles over the generic variants', async () => {
const code = 'return { name: "audit", apply(ctx) {} }'
const b = await bench([
toolResult(3, 'cordis-1', 'cordis_inspect', '{"what":"api","name":"tools"}'),
toolResult(4, 'cordis-2', 'cordis_mount', JSON.stringify({ code })),
toolResult(5, 'cordis-3', 'cordis_unmount', '{"id":"dyn-2"}'),
])
const view = mountApp(b.slots)
expect(view.container.querySelector('[data-tool="cordis_inspect"]')?.textContent).toContain('Inspect')
const mounted = view.container.querySelector('[data-variant="code"]')
expect(mounted?.textContent).toContain(`Mount temporary Plugin${code}`)
expect(view.container.querySelector('[data-tool="cordis_unmount"]')?.textContent)
.toContain('Unmount temporary Plugindyn-2')
fireEvent.click(mounted!.querySelector('button[aria-expanded]')!)
expect(mounted!.querySelector('pre.shiki')?.textContent).toBe(code)
})
it('row clicks travel owner openDetails → chat inject → layout orchestration', async () => {
const b = await bench([toolResult(3, 'c1', 'bash')])
const view = mountApp(b.slots)