// @vitest-environment node import { cp, mkdir, mkdtemp, rm, writeFile } from 'node:fs/promises'; import { createRequire } from 'node:module'; import { tmpdir } from 'node:os'; import path from 'node:path'; import { finished } from 'node:stream/promises'; import { afterEach, describe, expect, it } from 'vitest'; import { assertNodeEngineCompatible, classifyOpenCodeResourcePaths, collectAbsoluteManifestValues, collectForbiddenAsarPaths, collectForbiddenResourcePaths, verifyBundledCodingPluginResources, defaultProductExecutable, readPackagedMarketplaceTrustSource, verifyPackagedMarketplaceClientArtifact, validatePiArtifactMetadata, verifyMarketplaceClientArtifact, } from '../../scripts/lib/pi-product-artifact.mjs'; import { parsePiArtifactVerifierArgs } from '../../scripts/verify-pi-product-artifact.mjs'; const roots: string[] = []; const PI_PACKAGE = '@earendil-works/pi-coding-agent'; const { createPackage } = createRequire(import.meta.url)('@electron/asar'); const MARKETPLACE_ARTIFACT_TEXT = [ 'makelore-plugin-release.v1', 'skill_only', 'platform_hosted', 'plugin_signature_invalid', 'signing key is not trusted', 'makelore.game-resource', '/api/plugins/v1/hosted/game-resource/generations', 'makelore.web-search', '/api/plugins/v1/hosted/web-search/searches', 'plugin_receipt_unavailable', 'receipt_unavailable', '/api/coding/plugin-marketplace', 'plugin-marketplace\\/install\\/', 'plugin-marketplace\\/update\\/', 'effectiveSkillIds', 'pluginReleaseIds', '/api/coding/plugin-marketplace/catalog', '/api/coding/plugin-marketplace/library', '免费获取', '我的插件', ].join('\n'); async function createAsarFixture(source: string, archive: string) { const output = await createPackage(source, archive); await finished(output); } afterEach(async () => { await Promise.all(roots.splice(0).map((root) => rm(root, { recursive: true, force: true }))); }); function matchingMetadata() { return { rootPackage: { dependencies: { [PI_PACKAGE]: '0.84.2' } }, lockfile: { importers: { '.': { dependencies: { [PI_PACKAGE]: { specifier: '0.84.2', version: '0.84.2(ws@8.20.0)' } } }, }, }, packagedPackage: { dependencies: { [PI_PACKAGE]: '0.84.2' } }, runtimePackage: { name: PI_PACKAGE, version: '0.84.2', bin: { pi: 'dist/cli.js' }, }, manifest: { runtime: { packageName: PI_PACKAGE, version: '0.84.2', cliEntry: 'dist/cli.js', nodeEngine: '>=22.19.0', }, target: { platform: 'win32', arch: 'x64' }, }, runtimePlatform: { platform: 'win32', arch: 'x64', node: '24.18.1' }, }; } async function bundledResourceFixture({ schemaVersion = 1, includeSdkAssets = true } = {}) { const root = await mkdtemp(path.join(tmpdir(), 'makelore-bundled-plugin-')); roots.push(root); const projectRoot = path.join(root, 'project'); const sourceResources = path.join(projectRoot, 'resources'); const pluginRoot = path.join(sourceResources, 'coding-plugins', 'example'); const capability = { schemaVersion, pluginId: 'example.plugin', adapterId: 'example-adapter', ...(schemaVersion === 2 ? { runtime: { kind: 'platform_hosted', protocol: 'makelore-hosted.v1' } } : {}), skills: [{ id: 'example', entry: '../skills/example/SKILL.md', grants: [] }], tools: [{ name: 'example_read' }], }; await mkdir(path.join(pluginRoot, 'com.makelore'), { recursive: true }); await mkdir(path.join(pluginRoot, 'skills', 'example'), { recursive: true }); await mkdir(path.join(sourceResources, 'coding-skills', 'agent-browser'), { recursive: true }); await writeFile(path.join(pluginRoot, 'plugin.json'), JSON.stringify({ name: 'example.plugin', version: '1.0.0', extensions: { 'com.makelore': { capabilityManifest: './com.makelore/capability.json' } }, })); await writeFile(path.join(pluginRoot, 'com.makelore', 'capability.json'), JSON.stringify(capability)); await writeFile(path.join(pluginRoot, 'skills', 'example', 'SKILL.md'), '# Example Skill\n'); if (includeSdkAssets) { await mkdir(path.join(pluginRoot, 'skills', 'example', 'assets'), { recursive: true }); await writeFile(path.join(pluginRoot, 'skills', 'example', 'assets', 'sdk.ts'), 'export {};\n'); await writeFile(path.join(pluginRoot, 'skills', 'example', 'assets', 'sdk.js'), 'export {};\n'); } await writeFile(path.join(sourceResources, 'coding-skills', 'agent-browser', 'SKILL.md'), '# Browser\n'); const resourcesDirectory = path.join(root, 'packaged'); await cp(sourceResources, path.join(resourcesDirectory, 'resources'), { recursive: true }); return { projectRoot, resourcesDirectory, appAsarContents: Buffer.from('example.plugin example-adapter example_read'), }; } describe('final Pi product artifact verification', () => { it('requires the same pinned Pi version across package, lock, app, runtime, and manifest', () => { expect(validatePiArtifactMetadata(matchingMetadata())).toMatchObject({ expected: '0.84.2', rootDependency: '0.84.2', lockedVersion: '0.84.2', manifest: '0.84.2', }); const mismatch = matchingMetadata(); mismatch.packagedPackage.dependencies[PI_PACKAGE] = '0.84.1'; expect(() => validatePiArtifactMetadata(mismatch)).toThrow('versions do not match'); }); it('checks the packaged Node version against the exact supported engine shape', () => { expect(() => assertNodeEngineCompatible('>=22.19.0', '24.18.1')).not.toThrow(); expect(() => assertNodeEngineCompatible('>=22.19.0', '22.18.9')).toThrow('does not satisfy'); expect(() => assertNodeEngineCompatible('^22.19.0', '24.18.1')).toThrow('Unsupported'); }); it('rejects absolute manifest values and OpenCode-named artifact resources', async () => { expect(collectAbsoluteManifestValues({ entry: 'dist/cli.js', asset: 'node_modules/example/file.wasm', leaked: 'D:\\work\\pi-runtime', })).toEqual([{ at: '$.leaked', value: 'D:\\work\\pi-runtime' }]); const root = await mkdtemp(path.join(tmpdir(), 'makelore-pi-artifact-test-')); roots.push(root); await mkdir(path.join(root, 'pi-runtime', 'node_modules', 'opencode-ai'), { recursive: true }); await writeFile(path.join(root, 'pi-runtime', 'node_modules', 'opencode-ai', 'package.json'), '{}'); expect(await collectForbiddenResourcePaths(root)).toEqual([ 'pi-runtime/node_modules/opencode-ai', ]); expect(classifyOpenCodeResourcePaths([ 'app.asar.unpacked/resources/opencode-runtime', 'pi-runtime/node_modules/@earendil-works/pi-ai/dist/providers/opencode.js', 'app.asar/node_modules/@earendil-works/pi-ai/dist/providers/opencode-codex-responses.js', ])).toEqual({ productOwned: ['app.asar.unpacked/resources/opencode-runtime'], upstreamPiProvider: [ 'pi-runtime/node_modules/@earendil-works/pi-ai/dist/providers/opencode.js', 'app.asar/node_modules/@earendil-works/pi-ai/dist/providers/opencode-codex-responses.js', ], }); }); it('enumerates OpenCode-named paths inside app.asar instead of scanning only physical resources', async () => { const root = await mkdtemp(path.join(tmpdir(), 'makelore-pi-asar-paths-')); roots.push(root); const source = path.join(root, 'source'); await mkdir(path.join(source, 'node_modules', '@earendil-works', 'pi-ai', 'dist', 'providers'), { recursive: true, }); await mkdir(path.join(source, 'resources', 'opencode-runtime'), { recursive: true }); await writeFile( path.join(source, 'node_modules', '@earendil-works', 'pi-ai', 'dist', 'providers', 'opencode.js'), 'export {};', ); await writeFile(path.join(source, 'resources', 'opencode-runtime', 'legacy.js'), 'export {};'); const archive = path.join(root, 'app.asar'); await createAsarFixture(source, archive); const inventory = collectForbiddenAsarPaths(archive); expect(inventory.entryCount).toBeGreaterThan(2); expect(inventory.matches).toEqual(expect.arrayContaining([ 'app.asar/node_modules/@earendil-works/pi-ai/dist/providers/opencode.js', 'app.asar/resources/opencode-runtime', ])); expect(classifyOpenCodeResourcePaths(inventory.matches)).toMatchObject({ productOwned: expect.arrayContaining(['app.asar/resources/opencode-runtime']), upstreamPiProvider: expect.arrayContaining([ 'app.asar/node_modules/@earendil-works/pi-ai/dist/providers/opencode.js', ]), }); }); it('proves bundled plugin manifests, Skills, SDK assets, catalog, and core resources', async () => { const fixture = await bundledResourceFixture(); await expect(verifyBundledCodingPluginResources(fixture)).resolves.toMatchObject({ root: 'resources/coding-plugins', packages: [{ id: 'example.plugin', manifestPath: 'resources/coding-plugins/example/plugin.json', capabilityManifestPath: 'resources/coding-plugins/example/com.makelore/capability.json', skills: [{ id: 'example', path: 'skills/example/SKILL.md' }], sdkAssets: expect.arrayContaining([ 'resources/coding-plugins/example/skills/example/assets/sdk.ts', 'resources/coding-plugins/example/skills/example/assets/sdk.js', ]), adapterId: 'example-adapter', tools: ['example_read'], }], catalog: { adapters: ['example-adapter'], tools: ['example_read'], packagedInAsar: true }, coreResources: { root: 'resources/coding-skills', skills: ['agent-browser'] }, result: 'pass', }); }); it('accepts schema-2 hosted plugins whose implementation has no client SDK assets', async () => { const fixture = await bundledResourceFixture({ schemaVersion: 2, includeSdkAssets: false }); await expect(verifyBundledCodingPluginResources(fixture)).resolves.toMatchObject({ packages: [{ id: 'example.plugin', skills: [{ id: 'example', path: 'skills/example/SKILL.md' }], sdkAssets: [], adapterId: 'example.plugin', tools: ['example_read'], }], result: 'pass', }); }); it('proves the packaged Marketplace trust, routes, effective snapshot, and Renderer assets', () => { const artifact = Buffer.from(MARKETPLACE_ARTIFACT_TEXT); const trustSource = `export const CODE_OWNED_PLUGIN_SIGNING_KEYS = Object.freeze( {} as Readonly>, ); export const sourceMarker = 'makelore.plugin-trust.code-owned.v1';`; expect(verifyMarketplaceClientArtifact(artifact, trustSource)).toMatchObject({ schema2SkillOnly: true, schema2PlatformHosted: true, legacyMeowaClientAuthorityAbsent: true, webSearchProviderAuthorityAbsent: true, productionTrust: 'official-key-absent-fail-closed', libraryInstallAndEffectiveRoutes: true, rendererAssets: true, productionKeyIds: [], privateKeyMaterialInTrustSource: false, result: 'pass', }); }); it('rejects a packaged Marketplace missing a required asset or containing a private key', () => { const emptyTrust = 'CODE_OWNED_PLUGIN_SIGNING_KEYS = Object.freeze({} as Readonly>);'; expect(() => verifyMarketplaceClientArtifact(Buffer.from('makelore-plugin-release.v1'), emptyTrust)) .toThrow('Marketplace contract markers'); const complete = Buffer.from(MARKETPLACE_ARTIFACT_TEXT); expect(() => verifyMarketplaceClientArtifact( complete, `${emptyTrust}\nprocess.env.PLUGIN_KEY`, )).toThrow('empty code-owned fail-closed store'); expect(() => verifyMarketplaceClientArtifact( Buffer.from(`${MARKETPLACE_ARTIFACT_TEXT}\nMEOWA_API_KEY`), `${emptyTrust}\nmakelore.plugin-trust.code-owned.v1`, )).toThrow('provider authority'); expect(() => verifyMarketplaceClientArtifact( Buffer.from(`${MARKETPLACE_ARTIFACT_TEXT}\nWEB_SEARCH_OPENAI_API_KEY`), `${emptyTrust}\nmakelore.plugin-trust.code-owned.v1`, )).toThrow('provider authority'); }); it('proves Marketplace trust from the packaged app.asar rather than checkout source', async () => { const root = await mkdtemp(path.join(tmpdir(), 'makelore-marketplace-trust-asar-')); roots.push(root); const source = path.join(root, 'source'); await mkdir(path.join(source, 'dist-electron'), { recursive: true }); await writeFile(path.join(source, 'package.json'), JSON.stringify({ main: 'dist-electron/main.js' })); await writeFile(path.join(source, 'dist-electron', 'main.js'), [ 'const CODE_OWNED_PLUGIN_SIGNING_KEYS = Object.freeze({});', 'const unrelatedConfiguration = process.env.NIANCODE_E2E;', 'export const sourceMarker = "makelore.plugin-trust.code-owned.v1";', 'export const marketplace = true;', ].join('\n')); const appAsar = path.join(root, 'app.asar'); await createAsarFixture(source, appAsar); await expect(readPackagedMarketplaceTrustSource(appAsar)).resolves.toBe( 'CODE_OWNED_PLUGIN_SIGNING_KEYS = Object.freeze({})', ); }); it('recognizes a minified trust table only when its packaged provenance marker is present', async () => { const root = await mkdtemp(path.join(tmpdir(), 'makelore-marketplace-compiled-trust-asar-')); roots.push(root); const source = path.join(root, 'source'); await mkdir(path.join(source, 'dist-electron'), { recursive: true }); await writeFile(path.join(source, 'package.json'), JSON.stringify({ main: 'dist-electron/main.js' })); await writeFile(path.join(source, 'dist-electron', 'main.js'), [ 'const dC = Object.freeze({});', 'function createTrust() { return Object.freeze({ get: load, sourceMarker: "makelore.plugin-trust.code-owned.v1" }); }', ].join('\n')); const appAsar = path.join(root, 'app.asar'); await createAsarFixture(source, appAsar); await expect(readPackagedMarketplaceTrustSource(appAsar)).resolves.toContain( 'makelore.plugin-trust.code-owned.v1', ); expect(verifyMarketplaceClientArtifact( Buffer.from(MARKETPLACE_ARTIFACT_TEXT), 'const dC = Object.freeze({}); sourceMarker: makelore.plugin-trust.code-owned.v1', )).toMatchObject({ productionTrust: 'official-key-absent-fail-closed' }); }); it('does not accept a stale unreachable trust marker outside package.json.main reachability', async () => { const root = await mkdtemp(path.join(tmpdir(), 'makelore-marketplace-stale-trust-asar-')); roots.push(root); const source = path.join(root, 'source'); await mkdir(path.join(source, 'dist-electron'), { recursive: true }); await writeFile(path.join(source, 'package.json'), JSON.stringify({ main: 'dist-electron/main.js' })); await writeFile(path.join(source, 'dist-electron', 'main.js'), 'export const app = true;'); await writeFile(path.join(source, 'dist-electron', 'stale-trusted-keys.js'), [ 'const CODE_OWNED_PLUGIN_SIGNING_KEYS = Object.freeze({});', 'export const sourceMarker = "makelore.plugin-trust.code-owned.v1";', ].join('\n')); const appAsar = path.join(root, 'app.asar'); await createAsarFixture(source, appAsar); await expect(readPackagedMarketplaceTrustSource(appAsar)).rejects.toThrow('trust source'); }); it('binds Marketplace route, Renderer, and effective markers to the package main graph', async () => { const root = await mkdtemp(path.join(tmpdir(), 'makelore-marketplace-contract-asar-')); roots.push(root); const source = path.join(root, 'source'); await mkdir(path.join(source, 'dist-electron'), { recursive: true }); await mkdir(path.join(source, 'dist', 'assets'), { recursive: true }); await writeFile(path.join(source, 'package.json'), JSON.stringify({ main: 'dist-electron/main.js' })); await writeFile(path.join(source, 'dist-electron', 'main.js'), [ 'const CODE_OWNED_PLUGIN_SIGNING_KEYS = Object.freeze({});', 'export const sourceMarker = "makelore.plugin-trust.code-owned.v1";', 'loadFile("../dist/index.html");', ].join('\n')); await writeFile(path.join(source, 'dist', 'index.html'), [ '', ].join('\n')); await writeFile(path.join(source, 'dist', 'assets', 'index.js'), 'import("./project-plugins.js");'); await writeFile( path.join(source, 'dist', 'assets', 'project-plugins.js'), 'import{marketplace}from"./plugin-marketplace.js";export{marketplace};', ); await writeFile(path.join(source, 'dist', 'assets', 'plugin-marketplace.js'), [ 'makelore-plugin-release.v1 skill_only platform_hosted plugin_signature_invalid signing key is not trusted', 'makelore.game-resource /api/plugins/v1/hosted/game-resource/generations', 'makelore.web-search /api/plugins/v1/hosted/web-search/searches', 'plugin_receipt_unavailable receipt_unavailable', '/api/coding/plugin-marketplace plugin-marketplace\\/install\\/ plugin-marketplace\\/update\\/', 'effectiveSkillIds pluginReleaseIds', '/api/coding/plugin-marketplace/catalog /api/coding/plugin-marketplace/library 免费获取 我的插件', ].join('\n')); const appAsar = path.join(root, 'app.asar'); await createAsarFixture(source, appAsar); await expect(verifyPackagedMarketplaceClientArtifact(appAsar)).resolves.toMatchObject({ result: 'pass' }); const staleSource = path.join(root, 'stale-source'); await mkdir(path.join(staleSource, 'dist-electron'), { recursive: true }); await writeFile(path.join(staleSource, 'package.json'), JSON.stringify({ main: 'dist-electron/main.js' })); await writeFile(path.join(staleSource, 'dist-electron', 'main.js'), [ 'const CODE_OWNED_PLUGIN_SIGNING_KEYS = Object.freeze({});', 'export const sourceMarker = "makelore.plugin-trust.code-owned.v1";', ].join('\n')); await writeFile(path.join(staleSource, 'dist-electron', 'stale-marketplace.js'), [ 'makelore-plugin-release.v1 skill_only platform_hosted plugin_signature_invalid signing key is not trusted', 'makelore.game-resource /api/plugins/v1/hosted/game-resource/generations', '/api/coding/plugin-marketplace plugin-marketplace\\/install\\/ plugin-marketplace\\/update\\/', 'effectiveSkillIds pluginReleaseIds', '/api/coding/plugin-marketplace/catalog /api/coding/plugin-marketplace/library 免费获取 我的插件', ].join('\n')); const staleAsar = path.join(root, 'stale.asar'); await createAsarFixture(staleSource, staleAsar); await expect(verifyPackagedMarketplaceClientArtifact(staleAsar)) .rejects.toThrow('Marketplace contract markers'); }); it('rejects a packaged plugin tree that drops an SDK asset or catalog marker', async () => { const fixture = await bundledResourceFixture(); await rm(path.join( fixture.resourcesDirectory, 'resources', 'coding-plugins', 'example', 'skills', 'example', 'assets', 'sdk.js', )); await expect(verifyBundledCodingPluginResources(fixture)).rejects.toThrow('files differ'); const complete = await bundledResourceFixture(); await expect(verifyBundledCodingPluginResources({ ...complete, appAsarContents: Buffer.from('example.plugin example-adapter'), })).rejects.toThrow('adapter/tool catalog'); }); it('uses final unpacked-product paths and strictly parses verifier options', () => { expect(defaultProductExecutable('/repo', 'linux')) .toBe(path.resolve('/repo', 'release', 'linux-unpacked', 'niancode')); expect(defaultProductExecutable('D:\\repo', 'win32')) .toBe(path.resolve('D:\\repo', 'release', 'win-unpacked', 'Makelore.exe')); expect(parsePiArtifactVerifierArgs([ '--app-exe', 'release/custom/Makelore.exe', '--samples', '5', '--timeout-ms', '12000', '--report', 'release/evidence/pi.json', ], 'D:\\repo')).toMatchObject({ samples: 5, timeoutMs: 12_000 }); expect(parsePiArtifactVerifierArgs(['--', '--samples', '3'], 'D:\\repo')) .toMatchObject({ samples: 3 }); expect(() => parsePiArtifactVerifierArgs(['--samples', '0'], 'D:\\repo')) .toThrow('--samples must be a positive integer'); expect(() => parsePiArtifactVerifierArgs(['--unknown'], 'D:\\repo')) .toThrow('Unknown argument'); }); });