mirror of
https://github.com/deepseek-ai/deepseek-harness
synced 2026-08-15 21:04:50 +00:00
The picker listed presets alphabetically by id, so the shipped set read cordis, minimal, standard — reverse order of capability. A preset may now declare `order` in its metadata; the shipped three declare 1/2/3 and read standard, minimal, cordis. A preset that declares none sorts behind those that do, then by id, so authored presets stay stable. Editing had nowhere good to live. Inside a card it was squeezed into a ~268px column; hanging off the end of the grid it was orphaned from the card it edits. It now replaces the list: a back link, what is being edited, and the form at full width. One thing on screen at a time, which is what the form's height wanted all along. Cards in different grid rows sized independently, so a short description made a short card. `grid-auto-rows: 1fr` makes every row the same height. The trust badge lost its pill when the card CSS was rewritten, and `In use` never had one; both are tags now. Icon labels moved from `title` to a drawn tooltip — the native one waits about a second, which reads as nothing happening.
111 lines
4.4 KiB
TypeScript
111 lines
4.4 KiB
TypeScript
/**
|
|
* Display metadata is presentation, never capability: every way of getting it
|
|
* wrong degrades to "this preset has no display text" rather than to a
|
|
* preset that cannot be discovered or mounted. It also cannot carry identity
|
|
* — `id` is the directory and `trust` is the root, so neither is readable
|
|
* from the file a user can write.
|
|
*/
|
|
|
|
import { mkdtemp, mkdir, writeFile } from 'node:fs/promises'
|
|
import { tmpdir } from 'node:os'
|
|
import { join } from 'node:path'
|
|
import { describe, expect, it } from 'vitest'
|
|
import { METADATA_FILE, readPresetMetadata, renderPresetMetadata } from '../src/metadata.ts'
|
|
|
|
/** A preset directory holding exactly the given metadata text. */
|
|
async function presetDir(content?: string): Promise<string> {
|
|
const dir = await mkdtemp(join(tmpdir(), 'dsh-preset-meta-'))
|
|
await mkdir(dir, { recursive: true })
|
|
if (content !== undefined) await writeFile(join(dir, METADATA_FILE), content)
|
|
return dir
|
|
}
|
|
|
|
describe('reading display metadata', () => {
|
|
it('reads a name and a description', async () => {
|
|
const dir = await presetDir('name: 标准模式\ndescription: 完整的编码 agent。\n')
|
|
|
|
expect(await readPresetMetadata(dir)).toEqual({ name: '标准模式', description: '完整的编码 agent。' })
|
|
})
|
|
|
|
it('treats an absent file as no metadata', async () => {
|
|
// The common case: every preset authored by duplicating another starts
|
|
// without one, and a picker simply falls back to the id.
|
|
expect(await readPresetMetadata(await presetDir())).toEqual({})
|
|
})
|
|
|
|
it('treats malformed YAML as no metadata', async () => {
|
|
const dir = await presetDir('name: [unclosed\n')
|
|
|
|
// Display text is not worth failing discovery over — the composition
|
|
// beside it still mounts.
|
|
expect(await readPresetMetadata(dir)).toEqual({})
|
|
})
|
|
|
|
it.each([
|
|
['a list', '- name: x\n'],
|
|
['a scalar', 'just a string\n'],
|
|
['an empty document', ''],
|
|
])('treats %s as no metadata', async (_label, content) => {
|
|
expect(await readPresetMetadata(await presetDir(content))).toEqual({})
|
|
})
|
|
|
|
it('ignores fields that are not text', async () => {
|
|
const dir = await presetDir('name: 42\ndescription:\n nested: true\n')
|
|
|
|
expect(await readPresetMetadata(dir)).toEqual({})
|
|
})
|
|
|
|
it('ignores blank text rather than showing an empty name', async () => {
|
|
const dir = await presetDir('name: " "\ndescription: ""\n')
|
|
|
|
expect(await readPresetMetadata(dir)).toEqual({})
|
|
})
|
|
|
|
it('trims surrounding whitespace', async () => {
|
|
const dir = await presetDir('name: " 极简模式 "\n')
|
|
|
|
expect(await readPresetMetadata(dir)).toEqual({ name: '极简模式' })
|
|
})
|
|
|
|
it('reads a declared order', async () => {
|
|
const dir = await presetDir('name: 标准模式\norder: 1\n')
|
|
|
|
expect(await readPresetMetadata(dir)).toEqual({ name: '标准模式', order: 1 })
|
|
})
|
|
|
|
it('ignores an order that is not a finite number', async () => {
|
|
expect(await readPresetMetadata(await presetDir('order: first\n'))).toEqual({})
|
|
expect(await readPresetMetadata(await presetDir('order: .inf\n'))).toEqual({})
|
|
})
|
|
|
|
it('cannot carry identity or trust', async () => {
|
|
const dir = await presetDir('name: mine\nid: standard\ntrust: system\n')
|
|
|
|
// A locally authored preset writing `trust: system` must not become a
|
|
// shipped one; identity comes from the directory and the root it sits in.
|
|
expect(await readPresetMetadata(dir)).toEqual({ name: 'mine' })
|
|
})
|
|
})
|
|
|
|
describe('rendering display metadata', () => {
|
|
it('round-trips through a read', async () => {
|
|
const rendered = renderPresetMetadata({ name: '创造模式', description: '可以改自己的组装。' })
|
|
const dir = await presetDir(rendered)
|
|
|
|
expect(await readPresetMetadata(dir)).toEqual({ name: '创造模式', description: '可以改自己的组装。' })
|
|
})
|
|
|
|
it('omits an absent field rather than writing it blank', () => {
|
|
expect(renderPresetMetadata({ name: '极简模式' })).toBe('name: 极简模式\n')
|
|
// Description without a name is legal too: the picker falls back to the id.
|
|
expect(renderPresetMetadata({ description: '只做检索。' })).toBe('description: 只做检索。\n')
|
|
})
|
|
|
|
it('renders nothing when there is nothing to store', () => {
|
|
// Clearing both fields removes the file; an empty document would read as
|
|
// an intentional blank name.
|
|
expect(renderPresetMetadata({})).toBeUndefined()
|
|
expect(renderPresetMetadata({ name: ' ', description: '' })).toBeUndefined()
|
|
})
|
|
})
|