packaging-isolation.mjs 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637
  1. /** Minimal real Loader check under Node permissions; workspace source is unreadable. */
  2. import assert from 'node:assert/strict'
  3. import fs from 'node:fs'
  4. import path from 'node:path'
  5. import { createRequire } from 'node:module'
  6. import { pathToFileURL } from 'node:url'
  7. const [profile, hostAnchor, blockedSource, reportPath] = process.argv.slice(2)
  8. assert.equal(process.permission.has('fs.read', blockedSource), false)
  9. assert.throws(() => fs.readFileSync(blockedSource), { code: 'ERR_ACCESS_DENIED' })
  10. const require = createRequire(hostAnchor)
  11. const checkEmbedding = process.argv.includes('--embedding')
  12. const packageRequire = checkEmbedding
  13. ? createRequire(require.resolve('@linfengqaqtat/dsh-scriptor-full/package.json', { paths: [profile] }))
  14. : createRequire(path.join(profile, 'package.json'))
  15. const packageEntry = packageRequire.resolve('@linfengqaqtat/dsh-scriptor')
  16. const { boot } = await import(pathToFileURL(require.resolve('@deepseek-ai/dsh-app-boot')).href)
  17. const configPath = path.join(path.dirname(reportPath), 'isolation-loader.json')
  18. const config = [
  19. { id: 'skills', name: pathToFileURL(require.resolve('@deepseek-ai/dsh-skill')).href },
  20. { id: 'webnovel', name: pathToFileURL(packageEntry).href },
  21. ]
  22. if (checkEmbedding) {
  23. config.unshift({ id: 'llm', name: pathToFileURL(require.resolve('@deepseek-ai/dsh-llm')).href })
  24. config.unshift({ id: 'credentials', name: pathToFileURL(require.resolve('@deepseek-ai/dsh-credentials-local')).href,
  25. config: { path: path.join(path.dirname(reportPath), 'full-credentials.yaml'), watch: false } })
  26. config.push({ id: 'embedding', name: pathToFileURL(packageRequire.resolve('webnovel-embedding-provider')).href })
  27. }
  28. fs.writeFileSync(configPath, JSON.stringify(config))
  29. const ctx = await boot('packaging-source-isolation', configPath)
  30. try {
  31. const skills = await ctx.skills.list({ cwd: process.cwd() })
  32. assert.equal(skills.length, 10)
  33. for (const skill of skills) assert.ok((await ctx.skills.get(skill.name)).content.length > 100)
  34. if (checkEmbedding) assert.ok(ctx.get('embeddings'), 'Full package must load the embedding service')
  35. fs.writeFileSync(reportPath, JSON.stringify({ ok: true, sourceReadDenied: true, actualLoader: true, skills: skills.length, embeddingLoaded: checkEmbedding && !!ctx.get('embeddings') }, null, 2) + '\n')
  36. console.log('Source-blocked installed Host Loader: 10 skills passed')
  37. } finally { await ctx.fiber.dispose() }