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 { 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 // The skill registry belongs to one agent's preset, behind an `isolate` // realm the host cannot resolve by name — so the roots under test are only // reachable through a composed agent, which is also the only shape that // ever asks. `serviceFor` is the same addressing the gateway's `skill.list` // uses 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.agentPresets.serviceFor(handle.agent, 'skills') if (skills === undefined) throw new Error('composed agent mounts no skill registry') const names = (await skills.list({ cwd: scaffold.workspaceCwd })).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 }) } } })