| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354 |
- /** Run built Desktop Host task protection in a private development profile without Electron or installation. */
- import { spawn } from 'node:child_process'
- import { mkdir, mkdtemp, readFile, symlink, writeFile } from 'node:fs/promises'
- import { join, resolve } from 'node:path'
- import { fileURLToPath } from 'node:url'
- import { createDevelopmentProjectMetadata } from '../src/project-manager.ts'
- import { removeOwnedDirectory } from '../src/owned-directory.ts'
- import { DESKTOP_HOST_PROTOCOL_VERSION } from '../src/host-protocol.ts'
- const repo = resolve(import.meta.dirname, '../../..')
- const evidenceRoot = join(repo, 'apps/desktop/.desktop-build/qualification')
- await mkdir(evidenceRoot, { recursive: true })
- const root = await mkdtemp(join(evidenceRoot, 'host-updates-'))
- const project = join(root, 'project')
- const manifest = JSON.parse(await readFile(join(repo, 'apps/desktop/package.json'), 'utf8')) as { version: string }
- const pnpm = JSON.parse(await readFile(join(repo, 'apps/desktop/node_modules/pnpm/package.json'), 'utf8')) as { version: string }
- try {
- createDevelopmentProjectMetadata(project, {
- schemaVersion: 1, version: manifest.version, nodeVersion: process.versions.node,
- pnpmVersion: pnpm.version, hostProtocolVersion: DESKTOP_HOST_PROTOCOL_VERSION,
- })
- // This suite tests the Host, not dev.ts's dependency projection. Preserve pnpm's existing graph verbatim.
- await symlink(join(repo, 'node_modules/.pnpm/node_modules'), join(project, 'node_modules'),
- process.platform === 'win32' ? 'junction' : 'dir')
- await writeFile(join(project, 'cordis.patch.yml'), JSON.stringify([
- { id: 'webserver', config: { host: '127.0.0.1', port: 0 } },
- { id: 'llm-deepseek', disabled: true },
- { id: 'session-title-llm', disabled: true },
- { id: 'session-telemetry-otel', disabled: true },
- { id: 'agent-instructions', disabled: true },
- { id: 'agent-presets', config: { default: 'standard', includeUserRoot: false } },
- { insert: [{ id: 'update-qualification', name: new URL('../tests/fixtures/host-update-control.mjs', import.meta.url).href }] },
- ]))
- const environment = Object.fromEntries(Object.entries(process.env).filter(([name]) =>
- /^(?:path|systemroot|windir|comspec|pathext)$/iu.test(name)))
- const child = spawn(process.execPath, [fileURLToPath(new URL('../tests/fixtures/host-update-qualification.mjs', import.meta.url)), root], {
- cwd: root, env: { ...environment, DSH_HOME: join(root, 'home'), USERPROFILE: root, HOME: root,
- TEMP: root, TMP: root, TMPDIR: root }, stdio: 'inherit', windowsHide: true,
- })
- let timedOut = false
- const timeout = setTimeout(() => { timedOut = true; child.kill() }, 120_000)
- try {
- const result = await new Promise<{ code: number | null; signal: NodeJS.Signals | null }>((done, reject) => {
- child.once('error', reject)
- child.once('close', (code, signal) => { done({ code, signal }) })
- })
- if (timedOut || result.signal !== null || result.code !== 0) {
- throw new Error(`Host update qualification failed: timeout=${String(timedOut)}, signal=${String(result.signal)}, code=${String(result.code)}`)
- }
- console.log(`Host update evidence: ${root}`)
- } finally { clearTimeout(timeout) }
- } finally {
- removeOwnedDirectory(project)
- }
|