mirror of
https://github.com/deepseek-ai/deepseek-harness
synced 2026-08-15 21:04:50 +00:00
The persistence catalog recognizes SessionEventMap augmentations of '@deepseek-ai/dsh-session/types' alone, so the selected event's old root-specifier declaration compiled but silently vanished from the generated catalog. The hermetic scaffold e2e still addressed the skill registry as a preset-realm service; under the layered host registry the composed agent's view is a scope read, and the ambient-root isolation it proves is unchanged.
75 lines
3.0 KiB
TypeScript
75 lines
3.0 KiB
TypeScript
import { mkdir, mkdtemp, rm, writeFile } from 'node:fs/promises'
|
|
import { tmpdir } from 'node:os'
|
|
import { join } from 'node:path'
|
|
import { expect, it } from 'vitest'
|
|
import type {} from '@deepseek-ai/dsh-skill'
|
|
import { SessionId } from '@deepseek-ai/dsh-session'
|
|
import type {} from '@deepseek-ai/dsh-agent-presets'
|
|
import { launchWebScaffold, type WebScaffold } from './scaffold.ts'
|
|
|
|
async function writeSkill(root: string, name: string): Promise<void> {
|
|
const bundle = join(root, name)
|
|
await mkdir(bundle, { recursive: true })
|
|
await writeFile(join(bundle, 'SKILL.md'), `---
|
|
name: ${name}
|
|
description: Must not enter the Web replay scaffold
|
|
---
|
|
|
|
Ambient host state.
|
|
`)
|
|
}
|
|
|
|
it('isolates replay skill discovery from every ambient host root', async () => {
|
|
const ambient = await mkdtemp(join(tmpdir(), 'dsh-web-ambient-skills-'))
|
|
const dshHome = join(ambient, 'dsh-home')
|
|
const agentsHome = join(ambient, 'agents-home')
|
|
const bundled = join(ambient, 'bundled')
|
|
await Promise.all([
|
|
writeSkill(join(dshHome, 'skills'), 'ambient-dsh'),
|
|
writeSkill(join(agentsHome, 'skills'), 'ambient-agents'),
|
|
writeSkill(bundled, 'ambient-bundled'),
|
|
])
|
|
|
|
const originalDshHome = process.env.DSH_HOME
|
|
const originalAgentsHome = process.env.DSH_AGENTS_HOME
|
|
const originalBundled = process.env.DSH_BUNDLED_SKILL_DIR
|
|
process.env.DSH_HOME = dshHome
|
|
process.env.DSH_AGENTS_HOME = agentsHome
|
|
process.env.DSH_BUNDLED_SKILL_DIR = bundled
|
|
let scaffold: WebScaffold | undefined
|
|
try {
|
|
scaffold = await launchWebScaffold()
|
|
const ctx = scaffold.ctx
|
|
// Local skill discovery belongs to the agent's preset LAYER of the host
|
|
// registry, so the roots under test are only reachable through a composed
|
|
// agent's view — the same scope the gateway's `skill.list` resolves for a
|
|
// browser request about a session.
|
|
const handle = await ctx.agents.create({
|
|
sessionId: SessionId('hermetic-skills'),
|
|
setup: agentCtx => ctx.agentPresets.mount(agentCtx).then(() => undefined),
|
|
})
|
|
try {
|
|
const skills = ctx.get('skills')
|
|
if (skills === undefined) throw new Error('the composition mounts no skill registry')
|
|
const names = (await skills.list({ cwd: scaffold.workspaceCwd, scope: handle.agent })).map(skill => skill.name)
|
|
expect(names).not.toContain('ambient-dsh')
|
|
expect(names).not.toContain('ambient-agents')
|
|
expect(names).not.toContain('ambient-bundled')
|
|
} finally {
|
|
await handle.dispose()
|
|
}
|
|
} finally {
|
|
try {
|
|
await scaffold?.close()
|
|
} finally {
|
|
if (originalDshHome === undefined) delete process.env.DSH_HOME
|
|
else process.env.DSH_HOME = originalDshHome
|
|
if (originalAgentsHome === undefined) delete process.env.DSH_AGENTS_HOME
|
|
else process.env.DSH_AGENTS_HOME = originalAgentsHome
|
|
if (originalBundled === undefined) delete process.env.DSH_BUNDLED_SKILL_DIR
|
|
else process.env.DSH_BUNDLED_SKILL_DIR = originalBundled
|
|
await rm(ambient, { recursive: true, force: true })
|
|
}
|
|
}
|
|
})
|