@adea-ai/plugins 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +74 -0
- package/dist/agent-plugins-catalog.d.ts +26 -0
- package/dist/agent-plugins-catalog.js +699 -0
- package/dist/agent-plugins-catalog.js.map +1 -0
- package/dist/agent-plugins-harness.d.ts +54 -0
- package/dist/agent-plugins-harness.js +212 -0
- package/dist/agent-plugins-harness.js.map +1 -0
- package/dist/agent-plugins-schema.d.ts +402 -0
- package/dist/agent-plugins-schema.js +200 -0
- package/dist/agent-plugins-schema.js.map +1 -0
- package/dist/consumer-index.d.ts +217 -0
- package/dist/consumer-index.js +358 -0
- package/dist/consumer-index.js.map +1 -0
- package/dist/display-name.d.ts +8 -0
- package/dist/display-name.js +160 -0
- package/dist/display-name.js.map +1 -0
- package/dist/harness.d.ts +13 -0
- package/dist/harness.js +169 -0
- package/dist/harness.js.map +1 -0
- package/dist/icon-mirror.d.ts +69 -0
- package/dist/icon-mirror.js +147 -0
- package/dist/icon-mirror.js.map +1 -0
- package/dist/icons.d.ts +65 -0
- package/dist/icons.js +268 -0
- package/dist/icons.js.map +1 -0
- package/dist/index.d.ts +304 -0
- package/dist/index.js +1877 -0
- package/dist/index.js.map +1 -0
- package/dist/portable-catalog.d.ts +9 -0
- package/dist/portable-catalog.js +175 -0
- package/dist/portable-catalog.js.map +1 -0
- package/dist/publication.d.ts +98 -0
- package/dist/publication.js +121 -0
- package/dist/publication.js.map +1 -0
- package/dist/schema.d.ts +705 -0
- package/dist/schema.js +267 -0
- package/dist/schema.js.map +1 -0
- package/dist/site-icons.d.ts +55 -0
- package/dist/site-icons.js +155 -0
- package/dist/site-icons.js.map +1 -0
- package/dist/sources.d.ts +54 -0
- package/dist/sources.js +306 -0
- package/dist/sources.js.map +1 -0
- package/package.json +102 -0
- package/schemas/agent-package.v1.json +387 -0
- package/schemas/catalog.v1.schema.json +407 -0
- package/schemas/compatibility.v1.schema.json +23 -0
- package/schemas/harness-profile.v1.json +75 -0
- package/schemas/installation-plan.v2.json +695 -0
- package/schemas/sources-lock.v1.schema.json +61 -0
- package/src/agent-plugins-catalog.test.ts +402 -0
- package/src/agent-plugins-catalog.ts +800 -0
- package/src/agent-plugins-harness.test.ts +272 -0
- package/src/agent-plugins-harness.ts +281 -0
- package/src/agent-plugins-schema.test.ts +27 -0
- package/src/agent-plugins-schema.ts +219 -0
- package/src/artifacts.test.ts +545 -0
- package/src/catalog-installation.test.ts +42 -0
- package/src/consumer-index.test.ts +465 -0
- package/src/consumer-index.ts +592 -0
- package/src/display-name.test.ts +56 -0
- package/src/display-name.ts +157 -0
- package/src/harness.ts +202 -0
- package/src/icon-mirror.ts +196 -0
- package/src/icons.test.ts +185 -0
- package/src/icons.ts +297 -0
- package/src/index.test.ts +888 -0
- package/src/index.ts +2538 -0
- package/src/portable-catalog.test.ts +186 -0
- package/src/portable-catalog.ts +203 -0
- package/src/publication.test.ts +117 -0
- package/src/publication.ts +171 -0
- package/src/schema.ts +309 -0
- package/src/site-icon-fallback.test.ts +267 -0
- package/src/site-icons.test.ts +171 -0
- package/src/site-icons.ts +161 -0
- package/src/sources.ts +360 -0
- package/src/upstream-headers.test.ts +148 -0
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import type { Catalog } from './schema.js';
|
|
2
|
+
import { type IconContentType } from './icons.js';
|
|
3
|
+
/**
|
|
4
|
+
* Placement policy that decides which source variant represents a product.
|
|
5
|
+
* Trusted compiler configuration; never derived from upstream plugin content.
|
|
6
|
+
*/
|
|
7
|
+
export interface ProductPreference {
|
|
8
|
+
readonly schemaVersion: 1;
|
|
9
|
+
readonly sourcePreference: readonly string[];
|
|
10
|
+
readonly canonicalOverrides?: Readonly<Record<string, string>>;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Source order used when no variant is published by the product's own vendor.
|
|
14
|
+
* The Claude Code marketplace leads because it carries the largest catalog;
|
|
15
|
+
* the knowledge-work marketplace re-publishes many of the same products.
|
|
16
|
+
*/
|
|
17
|
+
export declare const DEFAULT_SOURCE_PREFERENCE: readonly string[];
|
|
18
|
+
export declare const DEFAULT_TOP_COUNT = 6;
|
|
19
|
+
export declare function parseProductPreference(input: unknown): ProductPreference;
|
|
20
|
+
/**
|
|
21
|
+
* A brand mark resolved at compile time and mirrored into the catalog release,
|
|
22
|
+
* so a client renders it without a second lookup or an upstream fetch.
|
|
23
|
+
*/
|
|
24
|
+
export interface ProductIcon {
|
|
25
|
+
/** `content` is the vendor's own plugin file; `favicon` is the product site's. */
|
|
26
|
+
readonly kind: 'content' | 'favicon';
|
|
27
|
+
/** Release asset name; fetch it from the release for this `catalogId`. */
|
|
28
|
+
readonly asset: string;
|
|
29
|
+
/**
|
|
30
|
+
* Absolute, immutable URL for the asset, present when the build knows where
|
|
31
|
+
* the catalog will be published. A client renders this and never composes a
|
|
32
|
+
* URL; a deployment that hosts assets elsewhere substitutes its base here.
|
|
33
|
+
*/
|
|
34
|
+
readonly assetUrl?: string;
|
|
35
|
+
readonly digest: string;
|
|
36
|
+
readonly contentType: IconContentType;
|
|
37
|
+
readonly bytes: number;
|
|
38
|
+
/** Plugin-relative path the mark came from, for `content`. */
|
|
39
|
+
readonly path: string | null;
|
|
40
|
+
/** Site icon URL, for `favicon`. */
|
|
41
|
+
readonly url: string | null;
|
|
42
|
+
readonly homepage: string | null;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Deterministic rendering hint for a product without a brand mark: initials and
|
|
46
|
+
* a stable hue. Clients draw it locally, which keeps it crisp, themable and
|
|
47
|
+
* free of a network request.
|
|
48
|
+
*/
|
|
49
|
+
export interface ProductMonogram {
|
|
50
|
+
readonly text: string;
|
|
51
|
+
readonly hue: number;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* The install-relevant facts of the release a product installs.
|
|
55
|
+
*
|
|
56
|
+
* A browsing client shows a plugin, then plans an install from it: the digest it
|
|
57
|
+
* must pin, the connectors and credentials setup will ask for, and the
|
|
58
|
+
* capabilities the harness has to negotiate. Carrying them here means the grid
|
|
59
|
+
* needs no second artifact.
|
|
60
|
+
*/
|
|
61
|
+
export interface ConsumerRelease {
|
|
62
|
+
readonly releaseId: string;
|
|
63
|
+
readonly canonicalContentDigest: string;
|
|
64
|
+
readonly contentResolution: string;
|
|
65
|
+
readonly capabilities: readonly {
|
|
66
|
+
readonly type: string;
|
|
67
|
+
readonly name: string;
|
|
68
|
+
}[];
|
|
69
|
+
readonly requiredConnectors: readonly string[];
|
|
70
|
+
readonly requiredCredentials: readonly string[];
|
|
71
|
+
/** Commit the release was resolved from, for audit and update state. */
|
|
72
|
+
readonly sourceRevision: string;
|
|
73
|
+
readonly upstreamVersion?: string;
|
|
74
|
+
/** Canonical package status, when the release carries one. */
|
|
75
|
+
readonly packageStatus?: string;
|
|
76
|
+
readonly packageDigest?: string;
|
|
77
|
+
}
|
|
78
|
+
/** One installable product, resolved from every source variant that publishes it. */ /**
|
|
79
|
+
* The install-relevant facts of the release a product installs.
|
|
80
|
+
*
|
|
81
|
+
* A browsing client shows a plugin, then plans an install from it: the digest it
|
|
82
|
+
* must pin, the connectors and credentials setup will ask for, and the
|
|
83
|
+
* capabilities the harness has to negotiate. Carrying them here means the grid
|
|
84
|
+
* needs no second artifact.
|
|
85
|
+
*/
|
|
86
|
+
export interface ConsumerRelease {
|
|
87
|
+
readonly releaseId: string;
|
|
88
|
+
readonly canonicalContentDigest: string;
|
|
89
|
+
readonly contentResolution: string;
|
|
90
|
+
readonly capabilities: readonly {
|
|
91
|
+
readonly type: string;
|
|
92
|
+
readonly name: string;
|
|
93
|
+
}[];
|
|
94
|
+
readonly requiredConnectors: readonly string[];
|
|
95
|
+
readonly requiredCredentials: readonly string[];
|
|
96
|
+
/** Commit the release was resolved from, for audit and update state. */
|
|
97
|
+
readonly sourceRevision: string;
|
|
98
|
+
readonly upstreamVersion?: string;
|
|
99
|
+
/** Canonical package status, when the release carries one. */
|
|
100
|
+
readonly packageStatus?: string;
|
|
101
|
+
readonly packageDigest?: string;
|
|
102
|
+
}
|
|
103
|
+
/** One installable product, resolved from every source variant that publishes it. */
|
|
104
|
+
export interface ConsumerProduct {
|
|
105
|
+
readonly productKey: string;
|
|
106
|
+
readonly pluginId: string;
|
|
107
|
+
readonly variantPluginIds: readonly string[];
|
|
108
|
+
readonly variantsIdentical: boolean;
|
|
109
|
+
readonly displayName: string;
|
|
110
|
+
readonly upstreamName: string;
|
|
111
|
+
readonly description: string;
|
|
112
|
+
readonly sourceId: string;
|
|
113
|
+
/**
|
|
114
|
+
* Who publishes the product, from the canonical variant. A card renders the
|
|
115
|
+
* first author as the publisher, so it travels with the product.
|
|
116
|
+
*/
|
|
117
|
+
readonly authors: readonly string[];
|
|
118
|
+
/** Where the canonical release came from, for source links and audit. */
|
|
119
|
+
readonly provenance: {
|
|
120
|
+
readonly repositoryUrl: string;
|
|
121
|
+
readonly resolvedCommitSha: string;
|
|
122
|
+
readonly manifestPath: string;
|
|
123
|
+
readonly pluginSubdirectory: string;
|
|
124
|
+
};
|
|
125
|
+
readonly categories: readonly string[];
|
|
126
|
+
readonly primaryCategory: string;
|
|
127
|
+
readonly license: string;
|
|
128
|
+
readonly homepage?: string;
|
|
129
|
+
readonly capabilitySummary: Readonly<Record<string, number>>;
|
|
130
|
+
readonly compatibility: Readonly<Record<string, string>>;
|
|
131
|
+
readonly releaseId: string;
|
|
132
|
+
/** The release `pluginId` pins, with the facts an install needs. */
|
|
133
|
+
readonly release: ConsumerRelease;
|
|
134
|
+
readonly keywords: readonly string[];
|
|
135
|
+
/** Security classification of the canonical variant, for a detail panel. */
|
|
136
|
+
readonly securityClassification: {
|
|
137
|
+
readonly level: string;
|
|
138
|
+
readonly reasons: readonly string[];
|
|
139
|
+
readonly permissionSensitiveChanges: readonly string[];
|
|
140
|
+
readonly contentResolution: string;
|
|
141
|
+
};
|
|
142
|
+
readonly icon: ProductIcon | null;
|
|
143
|
+
readonly monogram: ProductMonogram;
|
|
144
|
+
}
|
|
145
|
+
export interface ConsumerCategory {
|
|
146
|
+
readonly category: string;
|
|
147
|
+
readonly productCount: number;
|
|
148
|
+
readonly pluginCount: number;
|
|
149
|
+
readonly pluginIds: readonly string[];
|
|
150
|
+
readonly productKeys: readonly string[];
|
|
151
|
+
readonly topProductKeys: readonly string[];
|
|
152
|
+
/** Artifact that carries full records for `topProductKeys`. */
|
|
153
|
+
readonly shelfArtifact: string;
|
|
154
|
+
/** Artifact that carries full records for every product in the category. */
|
|
155
|
+
readonly listArtifact: string;
|
|
156
|
+
}
|
|
157
|
+
/** A curated name that no longer resolves to a product in its category. */
|
|
158
|
+
export interface LeadingDiagnostic {
|
|
159
|
+
readonly category: string;
|
|
160
|
+
readonly name: string;
|
|
161
|
+
readonly reason: 'UNKNOWN_CATEGORY' | 'PRODUCT_NOT_FOUND' | 'PRODUCT_NOT_IN_CATEGORY';
|
|
162
|
+
}
|
|
163
|
+
/** Brand-mark coverage, so an incomplete set is visible rather than implied. */
|
|
164
|
+
export interface IconCoverage {
|
|
165
|
+
readonly total: number;
|
|
166
|
+
readonly content: number;
|
|
167
|
+
readonly favicon: number;
|
|
168
|
+
readonly monogramOnly: number;
|
|
169
|
+
/** Products still rendering a monogram, in display order: the curation list. */
|
|
170
|
+
readonly monogramProductKeys: readonly string[];
|
|
171
|
+
}
|
|
172
|
+
export declare function iconCoverage(index: Pick<ConsumerIndex, 'products'>): IconCoverage;
|
|
173
|
+
export interface ConsumerIndex {
|
|
174
|
+
readonly topCount: number;
|
|
175
|
+
readonly sourcePreference: readonly string[];
|
|
176
|
+
readonly counts: {
|
|
177
|
+
readonly plugins: number;
|
|
178
|
+
readonly products: number;
|
|
179
|
+
readonly redundantPlugins: number;
|
|
180
|
+
};
|
|
181
|
+
readonly products: Readonly<Record<string, ConsumerProduct>>;
|
|
182
|
+
readonly categories: readonly ConsumerCategory[];
|
|
183
|
+
readonly diagnostics: readonly LeadingDiagnostic[];
|
|
184
|
+
/** Present on the navigation artifact; summarised from `products`. */
|
|
185
|
+
readonly iconCoverage?: IconCoverage;
|
|
186
|
+
}
|
|
187
|
+
export declare const SHELF_ARTIFACT_PREFIX = "shelf-";
|
|
188
|
+
export declare const CATEGORY_ARTIFACT_PREFIX = "category-";
|
|
189
|
+
export declare const CATALOG_INDEX_ARTIFACT = "catalog-index.v1.json";
|
|
190
|
+
/** Shard artifact names are derived from the category so they stay stable. */
|
|
191
|
+
export declare function shardArtifactNames(category: string): {
|
|
192
|
+
shelf: string;
|
|
193
|
+
list: string;
|
|
194
|
+
};
|
|
195
|
+
/**
|
|
196
|
+
* Initials and a hue derived from the product key, so a product without a mark
|
|
197
|
+
* still renders a stable tile instead of a blank one.
|
|
198
|
+
*/
|
|
199
|
+
export declare function monogramFor(displayName: string, productKey: string): ProductMonogram;
|
|
200
|
+
/**
|
|
201
|
+
* Builds the deduplicated, pre-sorted consumer view of a catalog.
|
|
202
|
+
*
|
|
203
|
+
* Each product appears once, represented by its canonical variant, and each
|
|
204
|
+
* category carries a display order plus the curated shelf of top products.
|
|
205
|
+
* Nothing here is random: every order is either configured or derived from
|
|
206
|
+
* stable identifiers.
|
|
207
|
+
*/
|
|
208
|
+
export declare function buildConsumerIndex(input: {
|
|
209
|
+
readonly catalog: Pick<Catalog, 'plugins' | 'sources'>;
|
|
210
|
+
readonly leading?: Readonly<Record<string, readonly string[]>>;
|
|
211
|
+
readonly topCount?: number;
|
|
212
|
+
readonly preference?: ProductPreference;
|
|
213
|
+
/** Where the catalog will be published, so records can carry absolute URLs. */
|
|
214
|
+
readonly publicationRepositoryUrl?: string;
|
|
215
|
+
/** Committed asset base a browser can fetch directly; preferred when set. */
|
|
216
|
+
readonly publicationAssetsBaseUrl?: string;
|
|
217
|
+
}): ConsumerIndex;
|
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
import { iconAssetName } from './icons.js';
|
|
2
|
+
import { immutableAssetUrl } from './publication.js';
|
|
3
|
+
/**
|
|
4
|
+
* Source order used when no variant is published by the product's own vendor.
|
|
5
|
+
* The Claude Code marketplace leads because it carries the largest catalog;
|
|
6
|
+
* the knowledge-work marketplace re-publishes many of the same products.
|
|
7
|
+
*/
|
|
8
|
+
export const DEFAULT_SOURCE_PREFERENCE = [
|
|
9
|
+
'claude-official',
|
|
10
|
+
'cursor-official',
|
|
11
|
+
'openai-official',
|
|
12
|
+
'knowledge-work-official',
|
|
13
|
+
];
|
|
14
|
+
export const DEFAULT_TOP_COUNT = 6;
|
|
15
|
+
export function parseProductPreference(input) {
|
|
16
|
+
if (typeof input !== 'object' || input === null)
|
|
17
|
+
throw new Error('PRODUCT_PREFERENCE_INVALID');
|
|
18
|
+
const raw = input;
|
|
19
|
+
if (raw.schemaVersion !== 1)
|
|
20
|
+
throw new Error('PRODUCT_PREFERENCE_INVALID');
|
|
21
|
+
if (!Array.isArray(raw.sourcePreference) ||
|
|
22
|
+
raw.sourcePreference.length === 0 ||
|
|
23
|
+
raw.sourcePreference.some((value) => typeof value !== 'string' || value.length === 0))
|
|
24
|
+
throw new Error('PRODUCT_PREFERENCE_INVALID');
|
|
25
|
+
if (new Set(raw.sourcePreference).size !== raw.sourcePreference.length)
|
|
26
|
+
throw new Error('PRODUCT_PREFERENCE_DUPLICATE_SOURCE');
|
|
27
|
+
const overrides = raw.canonicalOverrides;
|
|
28
|
+
if (overrides !== undefined) {
|
|
29
|
+
if (typeof overrides !== 'object' || overrides === null)
|
|
30
|
+
throw new Error('PRODUCT_PREFERENCE_INVALID');
|
|
31
|
+
for (const [productKey, pluginId] of Object.entries(overrides))
|
|
32
|
+
if (typeof pluginId !== 'string' || !pluginId.startsWith('plugin:'))
|
|
33
|
+
throw new Error(`PRODUCT_PREFERENCE_OVERRIDE_INVALID: ${productKey}`);
|
|
34
|
+
}
|
|
35
|
+
return {
|
|
36
|
+
schemaVersion: 1,
|
|
37
|
+
sourcePreference: [...raw.sourcePreference],
|
|
38
|
+
...(overrides ? { canonicalOverrides: { ...overrides } } : {}),
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
export function iconCoverage(index) {
|
|
42
|
+
const products = Object.values(index.products);
|
|
43
|
+
const monogramOnly = products
|
|
44
|
+
.filter((product) => !product.icon)
|
|
45
|
+
.map((product) => product.productKey)
|
|
46
|
+
.toSorted();
|
|
47
|
+
return {
|
|
48
|
+
total: products.length,
|
|
49
|
+
content: products.filter((product) => product.icon?.kind === 'content').length,
|
|
50
|
+
favicon: products.filter((product) => product.icon?.kind === 'favicon').length,
|
|
51
|
+
monogramOnly: monogramOnly.length,
|
|
52
|
+
monogramProductKeys: monogramOnly,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
function isHumanFormatted(value) {
|
|
56
|
+
return /[A-Z]/.test(value) || /\s/.test(value);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Prefers content published by the product's own vendor over a marketplace's
|
|
60
|
+
* own wrapper package, then applies the configured source order.
|
|
61
|
+
*/
|
|
62
|
+
function selectCanonical(variants, sourceRepository, preference) {
|
|
63
|
+
const override = preference.canonicalOverrides?.[variants[0]?.productGroupingKey ?? ''];
|
|
64
|
+
const overridden = override ? variants.find((plugin) => plugin.pluginId === override) : undefined;
|
|
65
|
+
if (overridden)
|
|
66
|
+
return overridden;
|
|
67
|
+
const rank = (plugin) => {
|
|
68
|
+
const index = preference.sourcePreference.indexOf(plugin.sourceId);
|
|
69
|
+
return index === -1 ? preference.sourcePreference.length : index;
|
|
70
|
+
};
|
|
71
|
+
// A variant with no resolved release repository proves nothing about its
|
|
72
|
+
// origin, so it is treated as marketplace-shipped rather than vendor-published.
|
|
73
|
+
const vendorPublished = (plugin) => {
|
|
74
|
+
const repository = plugin.availableReleases[0]?.resolvedRepositoryUrl;
|
|
75
|
+
return repository !== undefined && repository !== sourceRepository.get(plugin.sourceId);
|
|
76
|
+
};
|
|
77
|
+
return [...variants].toSorted((left, right) => Number(vendorPublished(right)) - Number(vendorPublished(left)) ||
|
|
78
|
+
rank(left) - rank(right) ||
|
|
79
|
+
Number(isHumanFormatted(right.displayName)) - Number(isHumanFormatted(left.displayName)) ||
|
|
80
|
+
left.pluginId.localeCompare(right.pluginId))[0];
|
|
81
|
+
}
|
|
82
|
+
/** Picks the most presentable label among a product's variants. */
|
|
83
|
+
function selectDisplayName(variants, canonical) {
|
|
84
|
+
const formatted = variants
|
|
85
|
+
.map((plugin) => plugin.displayName)
|
|
86
|
+
.filter((value) => isHumanFormatted(value) && value !== '')
|
|
87
|
+
.toSorted();
|
|
88
|
+
return formatted[0] ?? canonical.displayName;
|
|
89
|
+
}
|
|
90
|
+
export const SHELF_ARTIFACT_PREFIX = 'shelf-';
|
|
91
|
+
export const CATEGORY_ARTIFACT_PREFIX = 'category-';
|
|
92
|
+
export const CATALOG_INDEX_ARTIFACT = 'catalog-index.v1.json';
|
|
93
|
+
/** Shard artifact names are derived from the category so they stay stable. */
|
|
94
|
+
export function shardArtifactNames(category) {
|
|
95
|
+
if (!/^[a-z0-9][a-z0-9-]{1,63}$/.test(category))
|
|
96
|
+
throw new Error(`CATEGORY_SLUG_INVALID: ${category}`);
|
|
97
|
+
return {
|
|
98
|
+
shelf: `${SHELF_ARTIFACT_PREFIX}${category}.v1.json`,
|
|
99
|
+
list: `${CATEGORY_ARTIFACT_PREFIX}${category}.v1.json`,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
/** The release a product's install target pins, when it is still resolvable. */
|
|
103
|
+
function currentRelease(plugin) {
|
|
104
|
+
return (plugin.availableReleases.find((release) => release.releaseId === plugin.currentReleaseId) ??
|
|
105
|
+
plugin.availableReleases[0]);
|
|
106
|
+
}
|
|
107
|
+
/** Reads a nested string out of untrusted release metadata. */
|
|
108
|
+
function nestedString(value, key) {
|
|
109
|
+
if (typeof value !== 'object' || value === null)
|
|
110
|
+
return undefined;
|
|
111
|
+
const nested = value[key];
|
|
112
|
+
return typeof nested === 'string' && nested.length > 0 ? nested : undefined;
|
|
113
|
+
}
|
|
114
|
+
function describeRelease(plugin) {
|
|
115
|
+
const release = currentRelease(plugin);
|
|
116
|
+
const packages = (release.releaseMetadata ?? {}).agentPlugins;
|
|
117
|
+
return {
|
|
118
|
+
releaseId: release.releaseId,
|
|
119
|
+
canonicalContentDigest: release.canonicalContentDigest,
|
|
120
|
+
contentResolution: release.contentResolution,
|
|
121
|
+
capabilities: release.capabilities.map((capability) => ({
|
|
122
|
+
type: capability.type,
|
|
123
|
+
name: capability.name,
|
|
124
|
+
})),
|
|
125
|
+
requiredConnectors: [...release.requiredConnectors],
|
|
126
|
+
requiredCredentials: [...release.requiredCredentials],
|
|
127
|
+
sourceRevision: release.resolvedCommitSha,
|
|
128
|
+
...(release.upstreamVersion ? { upstreamVersion: release.upstreamVersion } : {}),
|
|
129
|
+
...(nestedString(packages, 'status')
|
|
130
|
+
? { packageStatus: nestedString(packages, 'status') }
|
|
131
|
+
: {}),
|
|
132
|
+
...(nestedString(packages, 'packageDigest')
|
|
133
|
+
? { packageDigest: nestedString(packages, 'packageDigest') }
|
|
134
|
+
: {}),
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
/** Prefers the canonical variant's mark, then any variant that has one. */
|
|
138
|
+
function selectProductIcon(variants, canonical, catalogId, publicationRepositoryUrl, publicationAssetsBaseUrl) {
|
|
139
|
+
const ordered = [canonical, ...variants.filter((plugin) => plugin !== canonical)];
|
|
140
|
+
for (const plugin of ordered) {
|
|
141
|
+
const icon = currentRelease(plugin)?.icon;
|
|
142
|
+
if (!icon)
|
|
143
|
+
continue;
|
|
144
|
+
const asset = iconAssetName(icon.digest, icon.contentType);
|
|
145
|
+
return {
|
|
146
|
+
kind: icon.kind,
|
|
147
|
+
asset,
|
|
148
|
+
...(publicationAssetsBaseUrl
|
|
149
|
+
? { assetUrl: `${publicationAssetsBaseUrl}/${asset}` }
|
|
150
|
+
: publicationRepositoryUrl
|
|
151
|
+
? { assetUrl: immutableAssetUrl(publicationRepositoryUrl, catalogId, asset) }
|
|
152
|
+
: {}),
|
|
153
|
+
digest: icon.digest,
|
|
154
|
+
contentType: icon.contentType,
|
|
155
|
+
bytes: icon.bytes,
|
|
156
|
+
path: icon.kind === 'content' ? icon.path : null,
|
|
157
|
+
url: icon.kind === 'favicon' ? icon.url : null,
|
|
158
|
+
homepage: icon.kind === 'favicon' ? icon.homepage : null,
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
return null;
|
|
162
|
+
}
|
|
163
|
+
const MONOGRAM_HUE_OFFSETS = [0, 137, 274];
|
|
164
|
+
/**
|
|
165
|
+
* Initials and a hue derived from the product key, so a product without a mark
|
|
166
|
+
* still renders a stable tile instead of a blank one.
|
|
167
|
+
*/
|
|
168
|
+
export function monogramFor(displayName, productKey) {
|
|
169
|
+
const words = displayName.split(/[^\p{L}\p{N}]+/u).filter(Boolean);
|
|
170
|
+
const first = words[0] ?? productKey;
|
|
171
|
+
const second = words[1];
|
|
172
|
+
const text = (words.length > 1 && second ? (first[0] ?? '') + (second[0] ?? '') : first.slice(0, 2)).toUpperCase();
|
|
173
|
+
let hash = 0;
|
|
174
|
+
for (const character of productKey)
|
|
175
|
+
hash = (hash * 31 + character.codePointAt(0)) % 360;
|
|
176
|
+
// Keep adjacent hues off each other so side-by-side tiles stay distinct.
|
|
177
|
+
return { text: text || '?', hue: (hash + MONOGRAM_HUE_OFFSETS[hash % 3]) % 360 };
|
|
178
|
+
}
|
|
179
|
+
function compactCompatibility(plugin) {
|
|
180
|
+
return Object.fromEntries(Object.entries(plugin.harnessCompatibility).map(([harness, value]) => [harness, value.status]));
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Builds the deduplicated, pre-sorted consumer view of a catalog.
|
|
184
|
+
*
|
|
185
|
+
* Each product appears once, represented by its canonical variant, and each
|
|
186
|
+
* category carries a display order plus the curated shelf of top products.
|
|
187
|
+
* Nothing here is random: every order is either configured or derived from
|
|
188
|
+
* stable identifiers.
|
|
189
|
+
*/
|
|
190
|
+
export function buildConsumerIndex(input) {
|
|
191
|
+
const preference = input.preference ?? {
|
|
192
|
+
schemaVersion: 1,
|
|
193
|
+
sourcePreference: [...DEFAULT_SOURCE_PREFERENCE],
|
|
194
|
+
};
|
|
195
|
+
const leading = input.leading ?? {};
|
|
196
|
+
const topCount = input.topCount ?? DEFAULT_TOP_COUNT;
|
|
197
|
+
const sourceRepository = new Map(input.catalog.sources.map((source) => [source.sourceId, source.repositoryUrl]));
|
|
198
|
+
const variantsByProduct = new Map();
|
|
199
|
+
for (const plugin of input.catalog.plugins) {
|
|
200
|
+
const list = variantsByProduct.get(plugin.productGroupingKey);
|
|
201
|
+
if (list)
|
|
202
|
+
list.push(plugin);
|
|
203
|
+
else
|
|
204
|
+
variantsByProduct.set(plugin.productGroupingKey, [plugin]);
|
|
205
|
+
}
|
|
206
|
+
const catalogId = input.catalog.catalogId ?? '';
|
|
207
|
+
const products = {};
|
|
208
|
+
for (const [productKey, variants] of [...variantsByProduct].toSorted((left, right) => left[0].localeCompare(right[0]))) {
|
|
209
|
+
const canonical = selectCanonical(variants, sourceRepository, preference);
|
|
210
|
+
const variantPluginIds = variants
|
|
211
|
+
.map((plugin) => plugin.pluginId)
|
|
212
|
+
.toSorted((left, right) => left === canonical.pluginId
|
|
213
|
+
? -1
|
|
214
|
+
: right === canonical.pluginId
|
|
215
|
+
? 1
|
|
216
|
+
: left.localeCompare(right));
|
|
217
|
+
const releaseIds = new Set(variants.map((plugin) => plugin.currentReleaseId));
|
|
218
|
+
const productCategories = [
|
|
219
|
+
...new Set(variants.flatMap((plugin) => plugin.categories)),
|
|
220
|
+
].toSorted();
|
|
221
|
+
products[productKey] = {
|
|
222
|
+
productKey,
|
|
223
|
+
pluginId: canonical.pluginId,
|
|
224
|
+
variantPluginIds,
|
|
225
|
+
variantsIdentical: releaseIds.size === 1 && variants.length > 1,
|
|
226
|
+
displayName: selectDisplayName(variants, canonical),
|
|
227
|
+
upstreamName: canonical.upstreamPluginName,
|
|
228
|
+
description: canonical.description || (variants.find((v) => v.description)?.description ?? ''),
|
|
229
|
+
sourceId: canonical.sourceId,
|
|
230
|
+
authors: [...canonical.authors],
|
|
231
|
+
provenance: {
|
|
232
|
+
repositoryUrl: canonical.provenance.repositoryUrl,
|
|
233
|
+
resolvedCommitSha: currentRelease(canonical).resolvedCommitSha,
|
|
234
|
+
manifestPath: canonical.provenance.manifestPath,
|
|
235
|
+
pluginSubdirectory: canonical.provenance.pluginSubdirectory,
|
|
236
|
+
},
|
|
237
|
+
// A product's categories are the union across its variants: sources
|
|
238
|
+
// disagree (one marketplace files Slack under productivity, another under
|
|
239
|
+
// communication), and a product belongs wherever any variant is filed.
|
|
240
|
+
categories: productCategories,
|
|
241
|
+
primaryCategory: productCategories[0] ?? 'other',
|
|
242
|
+
license: canonical.license.name,
|
|
243
|
+
...(canonical.homepage ? { homepage: canonical.homepage } : {}),
|
|
244
|
+
capabilitySummary: { ...canonical.capabilitySummary },
|
|
245
|
+
compatibility: compactCompatibility(canonical),
|
|
246
|
+
releaseId: canonical.currentReleaseId,
|
|
247
|
+
release: describeRelease(canonical),
|
|
248
|
+
keywords: [...canonical.keywords],
|
|
249
|
+
securityClassification: {
|
|
250
|
+
level: canonical.securityClassification.level,
|
|
251
|
+
reasons: [...canonical.securityClassification.reasons],
|
|
252
|
+
permissionSensitiveChanges: [
|
|
253
|
+
...canonical.securityClassification.permissionSensitiveChanges,
|
|
254
|
+
],
|
|
255
|
+
contentResolution: canonical.securityClassification.contentResolution,
|
|
256
|
+
},
|
|
257
|
+
icon: selectProductIcon(variants, canonical, catalogId, input.publicationRepositoryUrl, input.publicationAssetsBaseUrl),
|
|
258
|
+
monogram: monogramFor(selectDisplayName(variants, canonical), productKey),
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
const categoryNames = [
|
|
262
|
+
...new Set(input.catalog.plugins.flatMap((plugin) => plugin.categories)),
|
|
263
|
+
].toSorted();
|
|
264
|
+
const diagnostics = [];
|
|
265
|
+
// Resolve every curated name first, so a category's shelf can never lose a
|
|
266
|
+
// curated product to another category that merely reached it by fill order.
|
|
267
|
+
const curatedByCategory = new Map();
|
|
268
|
+
for (const category of categoryNames) {
|
|
269
|
+
const members = input.catalog.plugins.filter((plugin) => plugin.categories.includes(category));
|
|
270
|
+
const curated = [];
|
|
271
|
+
for (const name of leading[category] ?? []) {
|
|
272
|
+
const matches = members.filter((plugin) => plugin.upstreamPluginName === name);
|
|
273
|
+
if (matches.length === 0) {
|
|
274
|
+
diagnostics.push({
|
|
275
|
+
category,
|
|
276
|
+
name,
|
|
277
|
+
reason: variantsByProduct.has(name) ? 'PRODUCT_NOT_IN_CATEGORY' : 'PRODUCT_NOT_FOUND',
|
|
278
|
+
});
|
|
279
|
+
continue;
|
|
280
|
+
}
|
|
281
|
+
const key = matches[0].productGroupingKey;
|
|
282
|
+
if (!curated.includes(key))
|
|
283
|
+
curated.push(key);
|
|
284
|
+
}
|
|
285
|
+
curatedByCategory.set(category, curated);
|
|
286
|
+
}
|
|
287
|
+
// A shelf product headlined once, assigned to the first category that curates
|
|
288
|
+
// it. Every curated product is reserved up front, so a later category's fill
|
|
289
|
+
// can never take it before its owner is processed.
|
|
290
|
+
const curatedOwner = new Map();
|
|
291
|
+
for (const category of categoryNames)
|
|
292
|
+
for (const productKey of curatedByCategory.get(category))
|
|
293
|
+
if (!curatedOwner.has(productKey))
|
|
294
|
+
curatedOwner.set(productKey, category);
|
|
295
|
+
const filled = new Set();
|
|
296
|
+
const categories = categoryNames.map((category) => {
|
|
297
|
+
const members = input.catalog.plugins.filter((plugin) => plugin.categories.includes(category));
|
|
298
|
+
const curated = curatedByCategory.get(category);
|
|
299
|
+
const curatedRank = new Map(curated.map((key, index) => [key, index]));
|
|
300
|
+
const productKeys = [...new Set(members.map((plugin) => plugin.productGroupingKey))].toSorted((left, right) => (curatedRank.get(left) ?? Number.POSITIVE_INFINITY) -
|
|
301
|
+
(curatedRank.get(right) ?? Number.POSITIVE_INFINITY) || left.localeCompare(right));
|
|
302
|
+
const memberIds = new Set(members.map((plugin) => plugin.pluginId));
|
|
303
|
+
// Curated first in configured order, canonical variant ahead of its own
|
|
304
|
+
// variants, then alphabetical for a predictable browsing tail.
|
|
305
|
+
const orderedIds = [];
|
|
306
|
+
for (const productKey of productKeys) {
|
|
307
|
+
const product = products[productKey];
|
|
308
|
+
for (const pluginId of product.variantPluginIds)
|
|
309
|
+
if (memberIds.has(pluginId))
|
|
310
|
+
orderedIds.push(pluginId);
|
|
311
|
+
}
|
|
312
|
+
// Curated products this category owns, then deterministic fill so a shelf
|
|
313
|
+
// stays full without repeating a product another category already shows.
|
|
314
|
+
const topProductKeys = [];
|
|
315
|
+
for (const productKey of productKeys) {
|
|
316
|
+
if (topProductKeys.length === topCount)
|
|
317
|
+
break;
|
|
318
|
+
if (curatedOwner.get(productKey) !== category)
|
|
319
|
+
continue;
|
|
320
|
+
topProductKeys.push(productKey);
|
|
321
|
+
}
|
|
322
|
+
for (const productKey of productKeys) {
|
|
323
|
+
if (topProductKeys.length === topCount)
|
|
324
|
+
break;
|
|
325
|
+
if (curatedOwner.has(productKey) || filled.has(productKey))
|
|
326
|
+
continue;
|
|
327
|
+
topProductKeys.push(productKey);
|
|
328
|
+
filled.add(productKey);
|
|
329
|
+
}
|
|
330
|
+
return {
|
|
331
|
+
category,
|
|
332
|
+
productCount: productKeys.length,
|
|
333
|
+
pluginCount: members.length,
|
|
334
|
+
pluginIds: orderedIds,
|
|
335
|
+
productKeys,
|
|
336
|
+
topProductKeys,
|
|
337
|
+
shelfArtifact: shardArtifactNames(category).shelf,
|
|
338
|
+
listArtifact: shardArtifactNames(category).list,
|
|
339
|
+
};
|
|
340
|
+
});
|
|
341
|
+
for (const category of Object.keys(leading))
|
|
342
|
+
if (!categoryNames.includes(category))
|
|
343
|
+
for (const name of leading[category])
|
|
344
|
+
diagnostics.push({ category, name, reason: 'UNKNOWN_CATEGORY' });
|
|
345
|
+
return {
|
|
346
|
+
topCount,
|
|
347
|
+
sourcePreference: [...preference.sourcePreference],
|
|
348
|
+
counts: {
|
|
349
|
+
plugins: input.catalog.plugins.length,
|
|
350
|
+
products: Object.keys(products).length,
|
|
351
|
+
redundantPlugins: input.catalog.plugins.length - Object.keys(products).length,
|
|
352
|
+
},
|
|
353
|
+
products,
|
|
354
|
+
categories,
|
|
355
|
+
diagnostics: diagnostics.toSorted((left, right) => left.category.localeCompare(right.category) || left.name.localeCompare(right.name)),
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
//# sourceMappingURL=consumer-index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"consumer-index.js","sourceRoot":"","sources":["../src/consumer-index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Title-cases a slug-shaped name and leaves a properly cased one alone.
|
|
3
|
+
*
|
|
4
|
+
* Separators become spaces (`adobe-for-creativity` → `Adobe for Creativity`),
|
|
5
|
+
* but a dot does not, so domain-style names keep their shape
|
|
6
|
+
* (`monday.com` → `Monday.com`).
|
|
7
|
+
*/
|
|
8
|
+
export declare function normalizeDisplayName(value: string): string;
|