feat(plugins): move game resources behind marketplace

This commit is contained in:
2026-08-31 10:45:20 +08:00
parent 62304dc85b
commit fe656dd865
33 changed files with 1413 additions and 1018 deletions

View File

@@ -128,6 +128,33 @@ function buildSkillOnlyArchive(
return zip.toBuffer();
}
function buildHostedArchive(): Buffer {
return buildSkillOnlyArchive({
'com.makelore/capability.json': JSON.stringify({
schemaVersion: 2,
pluginId: PLUGIN_ID,
contractVersion: 1,
scope: 'project',
runtime: { kind: 'platform_hosted', protocol: 'makelore-hosted.v1' },
skills: [{ id: 'example-skill', entry: '../skills/example-skill/SKILL.md', grants: ['example.write'] }],
tools: [{
name: 'example_write', label: 'Write', description: 'Write an example output',
capabilityId: 'example.write', operation: 'write', roles: ['parent'],
mutation: 'write', projectWriteLease: true,
permissions: ['hosted.example.write'], executionMode: 'synchronous',
inputSchema: {
type: 'object', additionalProperties: false, required: ['value'],
properties: { value: { type: 'string', minLength: 1, maxLength: 100 } },
},
outputSchema: {
type: 'object', additionalProperties: false, required: ['saved'],
properties: { saved: { type: 'boolean' } },
},
}],
}),
});
}
function signedGrant(
archive: Buffer,
options: {
@@ -536,6 +563,37 @@ describe('PluginPackageStore', () => {
expect(issueDownload).toHaveBeenCalledWith({ releaseId: RELEASE_ID, releaseAdmissionId: ADMISSION_ID });
});
it('persists a signed platform-hosted package with its write-lease tool contract', async () => {
temporaryRoot = await mkdtemp(path.join(process.cwd(), '.marketplace-test-'));
const archive = buildHostedArchive();
const { grant, publicKey } = signedGrant(archive);
const marketplace = {
resolve: vi.fn(async (input: ResolveRequest) => makeResolveResult(input, {
sha256: grant.sha256, sizeBytes: grant.sizeBytes,
})),
issueDownload: vi.fn(async () => grant),
downloadContent: vi.fn(async () => archive),
getCurrentAccountBinding: () => ACCOUNT_A,
} as unknown as MarketplaceClient;
const store = new PluginPackageStore({
rootDir: temporaryRoot,
marketplace,
clientVersion: '1.0.0',
keyStore: new Map([['test-key', publicKey]]),
getAccountBinding: () => ACCOUNT_A,
});
await expect(store.resolveAndInstall({ pluginId: PLUGIN_ID, makeloreVersion: '1.0.0' }))
.resolves.toMatchObject({ status: 'installed', pluginId: PLUGIN_ID });
await expect(store.getInstalled(PLUGIN_ID)).resolves.toMatchObject({
runtimeKind: 'platform_hosted',
definition: {
runtimeKind: 'platform_hosted', requiresBackend: true,
tools: [{ name: 'example_write', projectWriteLease: true, executionMode: 'synchronous' }],
},
});
});
it('assigns a distinct logical resolve identity to each new Package Store sync', async () => {
temporaryRoot = await mkdtemp(path.join(process.cwd(), '.marketplace-test-'));
const archive = buildSkillOnlyArchive();