Просмотр исходного кода

feat(marketplace): retire unused specialist agents

Alvin Unreal 4 дней назад
Родитель
Сommit
63a017903a

+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
   "name": "oh-my-opencode-slim",
-  "version": "3.0.0-beta.4",
+  "version": "3.0.0-beta.5",
   "packageManager": "bun@1.3.14",
   "description": "Lightweight agent orchestration plugin for OpenCode - a slimmed-down fork of oh-my-opencode",
   "main": "dist/index.js",

+ 15 - 15
src/marketplace-contract/index.ts

@@ -7,7 +7,10 @@ import {
   digestMarketplaceBundle,
 } from '../marketplace/canonical';
 import { MarketplaceRetiredError } from '../marketplace/errors';
-import { isMarketplacePackageRetired } from '../marketplace/retirements';
+import {
+  isMarketplacePackageRetired,
+  RETIRED_MARKETPLACE_PACKAGE_IDS,
+} from '../marketplace/retirements';
 import { renderMarketplaceAutoDelegationBlock } from '../marketplace/routing';
 import {
   MARKETPLACE_DIGEST_DOMAIN,
@@ -145,12 +148,6 @@ function validateRegistryEntries(
   }
 }
 
-const CANONICAL_MARKETPLACE_RETIREMENT_IDS = [
-  'alvin/deepwork-implementer',
-  'alvin/deepwork-recon',
-  'alvin/deepwork-reviewer',
-] as const;
-
 const MarketplaceRegistryIndexV3Schema = z
   .object({
     schemaVersion: z.literal(MARKETPLACE_REGISTRY_SCHEMA_VERSION),
@@ -183,7 +180,7 @@ const MarketplaceRegistryIndexV3Schema = z
         });
       }
     }
-    for (const id of CANONICAL_MARKETPLACE_RETIREMENT_IDS) {
+    for (const id of RETIRED_MARKETPLACE_PACKAGE_IDS) {
       if (!seen.has(id)) {
         ctx.addIssue({
           code: 'custom',
@@ -250,16 +247,19 @@ export function createMarketplaceRegistryEntry(
 
 export function createMarketplaceRegistryIndex(
   entries: readonly MarketplaceRegistryEntry[],
-  retirements: readonly MarketplaceRegistryRetirement[] = CANONICAL_MARKETPLACE_RETIREMENT_IDS.map(
+  retirements: readonly MarketplaceRegistryRetirement[] = RETIRED_MARKETPLACE_PACKAGE_IDS.map(
     (id) => ({ id }),
   ),
 ): MarketplaceRegistryIndex {
-  const sorted = [...entries].sort(
-    (left, right) =>
-      compareMarketplaceCodeUnits(left.id, right.id) ||
-      compare(left.version, right.version) ||
-      compareMarketplaceCodeUnits(left.version, right.version),
-  );
+  const retiredIds = new Set(retirements.map(({ id }) => id));
+  const sorted = entries
+    .filter((entry) => !retiredIds.has(entry.id))
+    .sort(
+      (left, right) =>
+        compareMarketplaceCodeUnits(left.id, right.id) ||
+        compare(left.version, right.version) ||
+        compareMarketplaceCodeUnits(left.version, right.version),
+    );
   const sortedRetirements = [...retirements].sort((left, right) =>
     compareMarketplaceCodeUnits(left.id, right.id),
   );

+ 4 - 5
src/marketplace/activation.test.ts

@@ -364,7 +364,7 @@ describe('marketplace runtime activation', () => {
             work: {
               agents: {},
               marketplace: {
-                agents: ['alvin/deepwork-implementer'],
+                agents: ['alvin/evidence-scout'],
               },
             },
           },
@@ -373,14 +373,13 @@ describe('marketplace runtime activation', () => {
         'marketplace-retired-test',
       );
       expect(
-        registry.agents.some((agent) => agent.name === 'implementer'),
+        registry.agents.some((agent) => agent.name === 'evidencescout'),
       ).toBe(false);
       expect(registry.diagnostics).toEqual([
         {
-          packageId: 'alvin/deepwork-implementer',
+          packageId: 'alvin/evidence-scout',
           code: 'retired',
-          message:
-            'alvin/deepwork-implementer is retired and will not be activated',
+          message: 'alvin/evidence-scout is retired and will not be activated',
         },
       ]);
     } finally {

+ 7 - 1
src/marketplace/agents-only.test.ts

@@ -366,7 +366,13 @@ describe('agents-only marketplace contract', () => {
   );
 
   test('uses canonical retirement IDs and rejects them before install', () => {
-    expect(RETIRED_MARKETPLACE_PACKAGE_IDS).toHaveLength(3);
+    expect(RETIRED_MARKETPLACE_PACKAGE_IDS).toEqual([
+      'alvin/deepwork-implementer',
+      'alvin/deepwork-recon',
+      'alvin/deepwork-reviewer',
+      'alvin/evidence-scout',
+      'alvin/visual-inspector',
+    ]);
     const store = new MarketplaceStore({
       rootDir: mkdtempSync(join(tmpdir(), 'marketplace-retired-')),
     });

+ 14 - 8
src/marketplace/registry-client.test.ts

@@ -28,13 +28,12 @@ import {
   MARKETPLACE_REGISTRY_INDEX_URL,
   MarketplaceRegistryClient,
 } from './registry-client';
+import { RETIRED_MARKETPLACE_PACKAGE_IDS } from './retirements';
 import { MarketplaceService } from './service';
 
-const canonicalRetirements = [
-  { id: 'alvin/deepwork-implementer' },
-  { id: 'alvin/deepwork-recon' },
-  { id: 'alvin/deepwork-reviewer' },
-];
+const canonicalRetirements = RETIRED_MARKETPLACE_PACKAGE_IDS.map((id) => ({
+  id,
+}));
 
 function bundle(
   version = '1.0.0',
@@ -218,6 +217,8 @@ describe('marketplace registry contract', () => {
     for (const selector of [
       { id: 'alvin/deepwork-implementer' },
       { id: 'alvin/deepwork-implementer', version: '1.0.0' },
+      { id: 'alvin/evidence-scout' },
+      { id: 'alvin/visual-inspector', version: '1.0.0-beta.1' },
     ]) {
       expect(() =>
         resolveMarketplaceRegistryEntry(index, selector, {
@@ -225,6 +226,11 @@ describe('marketplace registry contract', () => {
         }),
       ).toThrow(MarketplaceRetiredError);
     }
+    expect(
+      createMarketplaceRegistryIndex([
+        createMarketplaceRegistryEntry(bundle('1.0.0', 'alvin/evidence-scout')),
+      ]).entries,
+    ).toEqual([]);
   });
 
   test('uses locale-independent code-unit ordering for JSON and catalog entries', () => {
@@ -291,7 +297,7 @@ describe('MarketplaceRegistryClient', () => {
       },
     });
     await expect(
-      client.download('alvin/deepwork-recon@1.0.0'),
+      client.download('alvin/evidence-scout@0.1.0-beta.1'),
     ).rejects.toBeInstanceOf(MarketplaceRetiredError);
     expect(fetches).toBe(0);
 
@@ -308,10 +314,10 @@ describe('MarketplaceRegistryClient', () => {
         },
       });
       await expect(
-        service.installRemote('alvin/deepwork-implementer'),
+        service.installRemote('alvin/visual-inspector'),
       ).rejects.toBeInstanceOf(MarketplaceRetiredError);
       await expect(
-        service.updateRemote('alvin/deepwork-reviewer'),
+        service.updateRemote('alvin/evidence-scout'),
       ).rejects.toBeInstanceOf(MarketplaceRetiredError);
       expect(downloads).toBe(0);
       expect(existsSync(service.store.paths.lockfilePath)).toBe(false);

+ 2 - 0
src/marketplace/retirements.ts

@@ -5,6 +5,8 @@ export const RETIRED_MARKETPLACE_PACKAGE_IDS = [
   'alvin/deepwork-implementer',
   'alvin/deepwork-recon',
   'alvin/deepwork-reviewer',
+  'alvin/evidence-scout',
+  'alvin/visual-inspector',
 ] as const;
 
 const retiredPackageIds = new Set<string>(RETIRED_MARKETPLACE_PACKAGE_IDS);

+ 2 - 2
src/marketplace/store.test.ts

@@ -95,10 +95,10 @@ describe('MarketplaceStore', () => {
     try {
       const store = new MarketplaceStore({ rootDir: root });
       expect(() =>
-        store.install(bundle('1.0.0', { id: 'alvin/deepwork-implementer' })),
+        store.install(bundle('1.0.0', { id: 'alvin/evidence-scout' })),
       ).toThrow(MarketplaceRetiredError);
       expect(() =>
-        store.update(bundle('2.0.0', { id: 'alvin/deepwork-reviewer' })),
+        store.update(bundle('2.0.0', { id: 'alvin/visual-inspector' })),
       ).toThrow(MarketplaceRetiredError);
       expect(existsSync(store.paths.lockfilePath)).toBe(false);
       expect(existsSync(store.paths.packagesDir)).toBe(false);