feat: add plugin marketplace renderer

This commit is contained in:
2026-08-28 18:41:23 +08:00
parent 8b6824a8ba
commit 97c9ad1aad
27 changed files with 1585 additions and 23 deletions

View File

@@ -83,6 +83,7 @@ describe('coding plugin bounded product service', () => {
durableProjectId: '11111111-1111-4111-8111-111111111111',
},
policyStatus: 'current',
unknownPluginIds: [],
items: [expect.objectContaining({
id: DATA_SERVICE_PLUGIN_DEFINITION.id,
enabled: true,
@@ -112,6 +113,32 @@ describe('coding plugin bounded product service', () => {
expect(JSON.stringify(result)).not.toMatch(/secret upstream body|projectPath|entitlement_scope/u);
});
it('projects retained selected IDs without inventing package metadata', async () => {
const root = await mkdtemp(path.join(tmpdir(), 'makelore-plugin-unknown-'));
roots.push(root);
await createCodingProjectMetadata(root, { now: '2026-08-28T00:00:00.000Z' });
const service = createCodingProjectPluginService({
projects: { getProject: vi.fn().mockResolvedValue({ id: 'local-a', path: root }) },
projectPlugins: {
getEnabledPluginIds: vi.fn().mockResolvedValue([
'makelore.removed', DATA_SERVICE_PLUGIN_DEFINITION.id, 'makelore.removed',
]),
setEnabled: vi.fn(),
},
policyClient: {
refresh: vi.fn().mockResolvedValue(undefined),
getState: () => ({ status: 'unavailable' as const, revision: 0, lastVerifiedAt: null, catalog: null }),
},
adapters: [],
definitions: [DATA_SERVICE_PLUGIN_DEFINITION],
});
const result = await service.list('local-a');
expect(result.unknownPluginIds).toEqual(['makelore.removed']);
expect(result.items).toHaveLength(1);
expect(result.items).not.toContainEqual(expect.objectContaining({ id: 'makelore.removed' }));
});
it('projects the exact three capabilities and fourteen mixed-policy operations', async () => {
const root = await mkdtemp(path.join(tmpdir(), 'makelore-plugin-policy-join-'));
roots.push(root);