feat: add DeepSeek Harness runtime

This commit is contained in:
lofyer
2026-08-14 10:04:34 +08:00
parent fca9888f83
commit 8286e120a1
69 changed files with 13660 additions and 351 deletions
+84
View File
@@ -49,6 +49,25 @@ interface ReleaseBuilderModule {
destination: string,
options: ReleaseOptions
) => void
verifyHarnessPackage: (
resources: string,
options: ReleaseOptions,
dependencies?: {
listPackage: (asarPath: string) => string[]
statFile: (
asarPath: string,
filePath: string
) => {
files?: Record<string, unknown>
link?: string
size?: number
}
extractFile: (
asarPath: string,
filePath: string
) => Buffer
}
) => void
verifyArtifacts: (
directory: string,
options: ReleaseOptions
@@ -237,6 +256,45 @@ describe('release build arguments', () => {
)
).toBe(false)
})
it('pins and unpacks every target-specific Harness native package', () => {
const packageJson = require('../package.json') as {
build: {
asarUnpack: string[]
npmRebuild: boolean
}
optionalDependencies: Record<string, string>
}
expect(packageJson.build.npmRebuild).toBe(false)
expect(packageJson.build.asarUnpack).toEqual(
expect.arrayContaining([
'out/main/package.json',
'out/main/deepseek-harness-*',
'out/main/chunks/**/*',
'node_modules/node-pty/lib/**/*',
'node_modules/node-pty/package.json',
'node_modules/node-pty/prebuilds/**/*',
'node_modules/node-pty/build/Release/**/*',
'node_modules/koffi/**/*',
'node_modules/@koromix/koffi-*/**/*',
'node_modules/@deepseek-ai/dsh-sandbox-windows-acl/**/*',
'node_modules/@deepseek-ai/node-addon-landlock-run/**/*',
'node_modules/@deepseek-ai/node-addon-landlock-run-*/**/*'
])
)
expect(packageJson.optionalDependencies).toEqual({
'@deepseek-ai/node-addon-landlock-run-linux-arm64':
'0.1.1',
'@deepseek-ai/node-addon-landlock-run-linux-x64':
'0.1.1',
'@koromix/koffi-darwin-arm64': '3.1.4',
'@koromix/koffi-darwin-x64': '3.1.4',
'@koromix/koffi-linux-arm64': '3.1.4',
'@koromix/koffi-linux-x64': '3.1.4',
'@koromix/koffi-win32-arm64': '3.1.4',
'@koromix/koffi-win32-x64': '3.1.4'
})
})
})
describe('release binary architecture detection', () => {
@@ -255,6 +313,32 @@ describe('release binary architecture detection', () => {
})
})
describe('release Harness package verification', () => {
it('fails closed when the packaged Harness Host is missing', () => {
const directory = mkdtempSync(
join(tmpdir(), 'goodbuddy-harness-closure-')
)
const resources = join(directory, 'resources')
try {
mkdirSync(resources, { recursive: true })
writeFileSync(join(resources, 'app.asar'), 'asar')
expect(() =>
releaseBuilder.verifyHarnessPackage(
resources,
windowsOptions,
{
listPackage: () => [],
statFile: () => ({ size: 1 }),
extractFile: () => Buffer.from('{}')
}
)
).toThrow('DeepSeek Harness Host缺失')
} finally {
rmSync(directory, { recursive: true, force: true })
}
})
})
describe('release output safety', () => {
it('preserves an existing portable ZIP when exclusive creation fails', async () => {
const directory = mkdtempSync(
+202
View File
@@ -0,0 +1,202 @@
import process from 'node:process'
import { Server } from '@modelcontextprotocol/sdk/server/index.js'
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
import {
CallToolRequestSchema,
ListToolsRequestSchema
} from '@modelcontextprotocol/sdk/types.js'
const server = new Server(
{
name: 'goodbuddy-web-3d-game-fixture',
version: '1.0.0'
},
{
capabilities: {
tools: {}
}
}
)
const blueprints = {
'neon-ruins': {
title: 'Prism Relay',
palette: {
sky: '#08111f',
floor: '#17243d',
player: '#68f6ff',
collectible: '#ffd166',
hazard: '#ff4d6d',
exit: '#7bf1a8'
},
setting:
'A compact neon ruin suspended above a dark energy field.'
},
'sky-temple': {
title: 'Aether Beacon',
palette: {
sky: '#87ceeb',
floor: '#d9c7a3',
player: '#235789',
collectible: '#f6ae2d',
hazard: '#d1495b',
exit: '#2a9d8f'
},
setting:
'A bright floating temple built from stone platforms and wind gates.'
},
'crystal-cavern': {
title: 'Crystal Circuit',
palette: {
sky: '#09051a',
floor: '#241b4b',
player: '#8be9fd',
collectible: '#f1fa8c',
hazard: '#ff79c6',
exit: '#50fa7b'
},
setting:
'A luminous cavern whose crystal relays awaken an ancient portal.'
}
}
server.setRequestHandler(ListToolsRequestSchema, async () => ({
tools: [
{
name: 'create_game_blueprint',
title: 'Create a deterministic 3D game blueprint',
description:
'Returns a bounded offline WebGL game design with controls, level geometry, rules, and play-test acceptance criteria.',
inputSchema: {
type: 'object',
properties: {
theme: {
type: 'string',
enum: ['neon-ruins', 'sky-temple', 'crystal-cavern']
},
seed: { type: 'string' },
targetCount: { type: 'number' }
},
required: ['theme', 'seed', 'targetCount'],
additionalProperties: false
},
annotations: {
readOnlyHint: true,
destructiveHint: false,
idempotentHint: true,
openWorldHint: false
}
}
]
}))
server.setRequestHandler(CallToolRequestSchema, async (request) => {
if (request.params.name !== 'create_game_blueprint') {
throw new Error('Unknown tool')
}
const args = request.params.arguments
const theme = args?.theme
const seed = args?.seed
const targetCount = args?.targetCount
if (
(theme !== 'neon-ruins' &&
theme !== 'sky-temple' &&
theme !== 'crystal-cavern') ||
typeof seed !== 'string' ||
seed.trim().length === 0 ||
seed.length > 64 ||
typeof targetCount !== 'number' ||
!Number.isInteger(targetCount) ||
targetCount < 3 ||
targetCount > 8
) {
throw new Error('Invalid blueprint arguments')
}
const selected = blueprints[theme]
const blueprint = {
schemaVersion: 1,
seed,
title: selected.title,
setting: selected.setting,
renderer: {
api: 'WebGL2',
projection: 'perspective',
requiredFeatures: [
'depth-test',
'directional-light',
'distance-fog',
'resize-aware-canvas'
],
networkAssets: false
},
player: {
spawn: [0, 0.6, 6],
moveSpeed: 5.5,
jumpVelocity: 7.5,
controls: {
move: ['WASD', 'Arrow keys'],
jump: ['Space'],
pause: ['Escape'],
restart: ['R']
}
},
objective: {
type: 'collect-and-exit',
collectible: 'energy prism',
targetCount,
exitUnlocksAt: targetCount,
victoryText: 'Relay synchronized'
},
level: {
bounds: { x: [-12, 12], z: [-10, 10], fallY: -5 },
platforms: [
{ center: [0, 0, 0], size: [18, 1, 14] },
{ center: [-8, 1.5, -5], size: [5, 1, 4] },
{ center: [8, 2.5, -4], size: [5, 1, 5] }
],
hazards: [
{
kind: 'moving-energy-bar',
axis: 'x',
range: [-6, 6],
speed: 2.4,
penalty: 'reset-player-and-increment-hits'
}
],
exit: { center: [0, 1, -8], lockedColor: '#56606f' }
},
palette: selected.palette,
feedback: [
'collectible-pulse-and-chime',
'hazard-flash-and-low-tone',
'exit-unlock-color-change',
'victory-overlay-with-restart'
],
acceptance: {
minimumFramesObserved: 30,
requiredStates: ['ready', 'playing', 'won'],
testSurface: 'window.__GOODBUDDY_GAME__',
checks: [
'keyboard and test inputs share the same action state',
'collecting every prism unlocks the exit',
'entering the unlocked exit wins',
'restart restores score, player, hazards, and exit',
'no external network requests or console errors'
]
}
}
return {
content: [
{
type: 'text',
text: JSON.stringify(blueprint)
}
]
}
})
await server.connect(
new StdioServerTransport(process.stdin, process.stdout, {
maxBufferSize: 1024 * 1024
})
)