refactor(office): Office 技能统一读取包内 assets,移除包外 office-skills 拷贝与 DSH_BUNDLED_OFFICE_SKILLS

- web-app、sdk-app 的 skill-office 不再覆盖 assetRoot;pythonEnvironment 不变
- Desktop 与 Python SDK 打包不再生成 office-skills 资源目录,删除 prepareOfficeSkillAssets 与 skillSource
- Desktop 打包 smoke 校验 4 个 Office 技能可从运行时归档列出并加载
- 同步测试、README、Agent Note,新增升级指南 office-skill-resources
This commit is contained in:
yudshj authored and GitHub committed 2026-11-04 13:25:24 +00:00
1 parent 3f6cd80c9d
commit 9df26413ee
49 files changed
+232 -214

No files matched your search

+1 -21
View File
@@ -5,7 +5,7 @@ import { tmpdir } from 'node:os'
import { basename, join } from 'node:path'
import { zipSync } from 'fflate'
import { expect, it } from 'vitest'
import { downloadPrimaryRuntimeAsset, prepareOfficeSkillAssets, primaryRuntimePayloadDigest, prunePnpmForeignNativePackages, smokePrimaryRuntime, unpackPrimaryRuntimeWheel } from './prepare.ts'
import { downloadPrimaryRuntimeAsset, primaryRuntimePayloadDigest, prunePnpmForeignNativePackages, smokePrimaryRuntime, unpackPrimaryRuntimeWheel } from './prepare.ts'
import lock from './lock.json' with { type: 'json' }
it('covers every SDK wheel target with the shared interpreter lock', () => {
@@ -132,26 +132,6 @@ it('rejects library files requiring an unsupported installation scheme', async (
}
})
it('copies complete Office resources outside the application archive and removes obsolete assets', async () => {
const root = await mkdtemp(join(tmpdir(), 'desktop-office-assets-'))
try {
const source = join(root, 'package', 'assets')
const destination = join(root, 'Contents', 'Resources', 'runtime', 'office-skills')
await mkdir(source, { recursive: true })
for (const name of ['office-docx', 'office-pptx', 'office-xlsx']) {
await mkdir(join(source, name))
await writeFile(join(source, name, 'SKILL.md'), `# ${name}\n`)
}
await prepareOfficeSkillAssets(source, destination)
await writeFile(join(destination, 'obsolete.py'), 'old helper')
await prepareOfficeSkillAssets(source, destination)
for (const name of ['office-docx', 'office-pptx', 'office-xlsx']) {
expect(await readFile(join(destination, name, 'SKILL.md'), 'utf8')).toBe(`# ${name}\n`)
}
await expect(readFile(join(destination, 'obsolete.py'))).rejects.toMatchObject({ code: 'ENOENT' })
} finally { await rm(root, { recursive: true, force: true }) }
})
it('gives Python-only payloads a distinct identity', () => {
expect(primaryRuntimePayloadDigest('linux-x64', lock, undefined)).not.toBe(primaryRuntimePayloadDigest('linux-x64', lock, '11.7.0'))
})
+3 -19
View File
@@ -172,17 +172,6 @@ export function prunePnpmForeignNativePackages(pnpm: string, platform: NodeJS.Pl
}
}
/**
* Copy the skill package's complete asset tree to ordinary filesystem resources.
* @param source - The package's assets directory.
* @param destination - External Office skill resource directory.
* @returns Resolves after replacing the external assets with the complete package tree.
*/
export async function prepareOfficeSkillAssets(source: string, destination: string): Promise<void> {
rmSync(destination, { recursive: true, force: true })
await cp(source, destination, { recursive: true, dereference: true })
}
/** A locked interpreter and wheel target. */
export type PrimaryRuntimeTarget = keyof typeof lock.targets
@@ -190,7 +179,7 @@ export type PrimaryRuntimeTarget = keyof typeof lock.targets
export interface PreparePrimaryRuntimeOptions {
/** Target whose archives and wheels are downloaded. */
readonly target: PrimaryRuntimeTarget
/** Resource directory receiving primary-runtime/ and office-skills/. */
/** Resource directory receiving primary-runtime/. */
readonly output: string
/** SHA-256-addressed archive cache. */
readonly cache: string
@@ -198,16 +187,14 @@ export interface PreparePrimaryRuntimeOptions {
readonly version: string
/** Locked npm pnpm tarball for installed carriers; build hosts otherwise copy their installed pnpm. */
readonly pnpmArchive?: RuntimeNpmArchive
/** Ordinary filesystem Office assets; build hosts otherwise resolve the workspace package. */
readonly skillSource?: string
/** Omit Node.js and pnpm for carriers providing only Python. */
readonly pythonOnly?: boolean
}
/**
* Materialize locked interpreters, libraries and Office resources without executing target code.
* Materialize locked interpreters and libraries without executing target code.
* @param options - Explicit target and carrier-owned output locations.
* @returns Resolves after the complete payload and skills have been copied to the output directory.
* @returns Resolves after the complete payload has been copied to the output directory.
*/
export async function preparePrimaryRuntime(options: PreparePrimaryRuntimeOptions): Promise<void> {
const { target } = options
@@ -259,9 +246,6 @@ export async function preparePrimaryRuntime(options: PreparePrimaryRuntimeOption
} finally {
rmSync(staging, { recursive: true, force: true })
}
const assets = options.skillSource ?? join(dirname(createRequire(import.meta.url).resolve('@deepseek-ai/dsh-skill-office/package.json')), 'assets')
await prepareOfficeSkillAssets(assets,
join(paths.runtime, 'office-skills'))
}
/**