@adea-ai/plugins 4.0.0 → 4.0.6

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.
Files changed (147) hide show
  1. package/dist/agent-plugins-catalog.d.ts +2 -4
  2. package/dist/agent-plugins-catalog.js +42 -50
  3. package/dist/agent-plugins-catalog.js.map +1 -1
  4. package/dist/agent-plugins-schema.d.ts +8 -0
  5. package/dist/agent-plugins-schema.js +10 -1
  6. package/dist/agent-plugins-schema.js.map +1 -1
  7. package/dist/artifacts.d.ts +57 -0
  8. package/dist/artifacts.js +159 -0
  9. package/dist/artifacts.js.map +1 -0
  10. package/dist/build.d.ts +20 -0
  11. package/dist/build.js +103 -0
  12. package/dist/build.js.map +1 -0
  13. package/dist/capabilities.d.ts +7 -0
  14. package/dist/capabilities.js +116 -0
  15. package/dist/capabilities.js.map +1 -0
  16. package/dist/catalog-store.d.ts +76 -0
  17. package/dist/catalog-store.js +463 -0
  18. package/dist/catalog-store.js.map +1 -0
  19. package/dist/concurrency.d.ts +1 -0
  20. package/dist/concurrency.js +15 -0
  21. package/dist/concurrency.js.map +1 -0
  22. package/dist/consumer-index.d.ts +7 -29
  23. package/dist/consumer-index.js +24 -15
  24. package/dist/consumer-index.js.map +1 -1
  25. package/dist/digest.d.ts +13 -0
  26. package/dist/digest.js +47 -0
  27. package/dist/digest.js.map +1 -0
  28. package/dist/fs-atomic.d.ts +7 -0
  29. package/dist/fs-atomic.js +30 -0
  30. package/dist/fs-atomic.js.map +1 -0
  31. package/dist/harness.js +2 -1
  32. package/dist/harness.js.map +1 -1
  33. package/dist/icon-mirror.d.ts +5 -4
  34. package/dist/icon-mirror.js +73 -72
  35. package/dist/icon-mirror.js.map +1 -1
  36. package/dist/icons.d.ts +2 -2
  37. package/dist/icons.js +4 -12
  38. package/dist/icons.js.map +1 -1
  39. package/dist/index.d.ts +16 -309
  40. package/dist/index.js +12 -1900
  41. package/dist/index.js.map +1 -1
  42. package/dist/integrity-manifest.d.ts +43 -13
  43. package/dist/integrity-manifest.js +28 -17
  44. package/dist/integrity-manifest.js.map +1 -1
  45. package/dist/json-values.d.ts +3 -0
  46. package/dist/json-values.js +10 -0
  47. package/dist/json-values.js.map +1 -0
  48. package/dist/plugin-release.d.ts +38 -0
  49. package/dist/plugin-release.js +321 -0
  50. package/dist/plugin-release.js.map +1 -0
  51. package/dist/plugin-skips.d.ts +19 -0
  52. package/dist/plugin-skips.js +65 -0
  53. package/dist/plugin-skips.js.map +1 -0
  54. package/dist/policy.d.ts +13 -0
  55. package/dist/policy.js +26 -0
  56. package/dist/policy.js.map +1 -0
  57. package/dist/portable-catalog.d.ts +4 -4
  58. package/dist/portable-catalog.js +14 -126
  59. package/dist/portable-catalog.js.map +1 -1
  60. package/dist/portable-verify.d.ts +2 -0
  61. package/dist/portable-verify.js +68 -0
  62. package/dist/portable-verify.js.map +1 -0
  63. package/dist/publication.d.ts +12 -12
  64. package/dist/publication.js +31 -21
  65. package/dist/publication.js.map +1 -1
  66. package/dist/published-output.d.ts +17 -0
  67. package/dist/published-output.js +49 -0
  68. package/dist/published-output.js.map +1 -0
  69. package/dist/site-icons.d.ts +4 -3
  70. package/dist/site-icons.js +38 -11
  71. package/dist/site-icons.js.map +1 -1
  72. package/dist/snapshots.d.ts +39 -0
  73. package/dist/snapshots.js +238 -0
  74. package/dist/snapshots.js.map +1 -0
  75. package/dist/source-resolution.d.ts +28 -0
  76. package/dist/source-resolution.js +158 -0
  77. package/dist/source-resolution.js.map +1 -0
  78. package/dist/sources.d.ts +5 -1
  79. package/dist/sources.js +21 -27
  80. package/dist/sources.js.map +1 -1
  81. package/dist/synchronize.d.ts +44 -0
  82. package/dist/synchronize.js +118 -0
  83. package/dist/synchronize.js.map +1 -0
  84. package/dist/taxonomy.d.ts +23 -0
  85. package/dist/taxonomy.js +62 -0
  86. package/dist/taxonomy.js.map +1 -0
  87. package/dist/upstream.d.ts +42 -0
  88. package/dist/upstream.js +179 -0
  89. package/dist/upstream.js.map +1 -0
  90. package/dist/verify-artifacts.d.ts +36 -0
  91. package/dist/verify-artifacts.js +286 -0
  92. package/dist/verify-artifacts.js.map +1 -0
  93. package/native/build-provenance.txt +5 -5
  94. package/native/staged-reader-win32-arm64.node +0 -0
  95. package/native/staged-reader-win32-x64.node +0 -0
  96. package/package.json +3 -3
  97. package/src/agent-plugins-catalog.test.ts +2 -2
  98. package/src/agent-plugins-catalog.ts +46 -49
  99. package/src/agent-plugins-schema.ts +11 -1
  100. package/src/artifacts.test.ts +80 -0
  101. package/src/artifacts.ts +234 -0
  102. package/src/build.ts +131 -0
  103. package/src/capabilities.ts +153 -0
  104. package/src/catalog-store.ts +519 -0
  105. package/src/concurrency.ts +19 -0
  106. package/src/consumer-index.test.ts +147 -16
  107. package/src/consumer-index.ts +35 -43
  108. package/src/default-head.test.ts +143 -0
  109. package/src/digest.ts +55 -0
  110. package/src/fs-atomic.ts +32 -0
  111. package/src/harness.test.ts +4 -32
  112. package/src/harness.ts +2 -1
  113. package/src/icon-mirror.ts +78 -72
  114. package/src/icons.test.ts +0 -4
  115. package/src/icons.ts +4 -4
  116. package/src/index.test.ts +172 -46
  117. package/src/index.ts +58 -2562
  118. package/src/integrity-manifest.ts +41 -21
  119. package/src/json-values.ts +11 -0
  120. package/src/manifest-retry.test.ts +49 -0
  121. package/src/plugin-release.ts +457 -0
  122. package/src/plugin-skips.ts +110 -0
  123. package/src/policy.ts +39 -0
  124. package/src/portable-catalog.test.ts +0 -5
  125. package/src/portable-catalog.ts +16 -143
  126. package/src/portable-verify.ts +71 -0
  127. package/src/publication.test.ts +29 -1
  128. package/src/publication.ts +38 -22
  129. package/src/published-output.ts +60 -0
  130. package/src/site-icons.test.ts +73 -1
  131. package/src/site-icons.ts +31 -14
  132. package/src/snapshots.ts +287 -0
  133. package/src/source-config-sync.test.ts +84 -0
  134. package/src/source-digest.test.ts +61 -8
  135. package/src/source-resolution.ts +233 -0
  136. package/src/sources-json.test.ts +18 -2
  137. package/src/sources.ts +27 -33
  138. package/src/synchronize.ts +213 -0
  139. package/src/taxonomy.ts +87 -0
  140. package/src/upstream.ts +194 -0
  141. package/src/verify-artifacts.ts +365 -0
  142. package/src/write-artifacts.test.ts +374 -0
  143. package/dist/source-digest.d.ts +0 -2
  144. package/dist/source-digest.js +0 -12
  145. package/dist/source-digest.js.map +0 -1
  146. package/native/README.md +0 -24
  147. package/src/source-digest.ts +0 -14
@@ -0,0 +1,321 @@
1
+ import { byteDigest, digest, sourceDigest } from './digest.js';
2
+ import { capabilitySummary, classifyCapabilities, createCompatibility, createSecurity, } from './capabilities.js';
3
+ import { normalizeDisplayName } from './display-name.js';
4
+ import { stageIconBytes } from './icon-mirror.js';
5
+ import { iconAssetName, iconOverrideFor, inspectIconBytes, selectIconPath, } from './icons.js';
6
+ import { arrayValue, isString, stringValue } from './json-values.js';
7
+ import { PluginSafetyError } from './plugin-skips.js';
8
+ import { isVendorHomepage, resolveSiteIcon } from './site-icons.js';
9
+ import { resolvePluginSource, } from './source-resolution.js';
10
+ import { canonicalRepositoryUrl, parseJsonDocument, safeRelativePath, } from './sources.js';
11
+ import { normalizeCategory, productGroupingKey, stablePluginId, stableReleaseId, } from './taxonomy.js';
12
+ import { createSiteIconFetcher, SITE_FETCH_TIMEOUT_MS } from './upstream.js';
13
+ /**
14
+ * Marks the catalog format this compiler emits.
15
+ *
16
+ * Bumping or first introducing this value makes a synchronization replay its
17
+ * verified pins and rebuild, which is how a format change reaches the published
18
+ * catalog when no upstream source has moved. It is deliberately separate from
19
+ * the agent-package normalizer version, which describes package normalization
20
+ * and would misreport a change here.
21
+ */
22
+ export const CATALOG_CONTRACT_VERSION = 'adea-catalog/3';
23
+ export async function normalizePlugin(source, entry, input) {
24
+ const { policy } = input;
25
+ const resolved = await resolvePluginSource(entry.name, entry.source, source, input.resolveExternalRefs);
26
+ const snapshot = input.metadataOnly
27
+ ? { files: new Map(), symlinks: [] }
28
+ : await input.snapshotLoader.load(resolved.repositoryUrl, resolved.commitSha, resolved.subdirectory);
29
+ if (snapshot.symlinks.length > 0)
30
+ throw new PluginSafetyError('SYMLINK_ESCAPE', [...snapshot.symlinks].toSorted());
31
+ validateSnapshot(snapshot, policy, entry.name);
32
+ const contentDigest = input.metadataOnly
33
+ ? digest({
34
+ repositoryUrl: resolved.repositoryUrl,
35
+ subdirectory: resolved.subdirectory,
36
+ commitSha: resolved.commitSha,
37
+ entryDigest: entry.entryDigest,
38
+ })
39
+ : sourceDigest(snapshot.files);
40
+ const pluginManifest = findPluginManifest(snapshot);
41
+ const manifestDigest = pluginManifest ? digest(pluginManifest.metadata) : entry.entryDigest;
42
+ const capabilities = classifyCapabilities(snapshot.files, pluginManifest?.metadata, policy);
43
+ const iconOverride = iconOverrideFor(input.productIconOverrides, productGroupingKey(entry.name, input.productAliases));
44
+ const contentIcon = resolveContentIcon(snapshot, iconOverride, input.metadataOnly);
45
+ const favicon = contentIcon === undefined
46
+ ? await resolveFavicon({
47
+ entry,
48
+ iconOverride,
49
+ metadataOnly: input.metadataOnly,
50
+ live: input.resolveExternalRefs,
51
+ })
52
+ : undefined;
53
+ // Stage the mark while its bytes are in hand. Publication then needs no
54
+ // re-fetch, and a site icon cannot drift between resolution and release.
55
+ const mark = contentIcon
56
+ ? { ...contentIcon, bytes: snapshot.files.get(contentIcon.path) }
57
+ : favicon;
58
+ if (input.iconAssetsDirectory && mark?.bytes)
59
+ await stageIconBytes(input.iconAssetsDirectory, iconAssetName(mark.digest, mark.contentType), mark.bytes);
60
+ const releaseId = stableReleaseId(resolved.repositoryUrl, resolved.subdirectory, resolved.commitSha, contentDigest);
61
+ const originalRelease = createRelease({
62
+ source,
63
+ entry,
64
+ resolved,
65
+ contentDigest,
66
+ manifestDigest,
67
+ capabilities,
68
+ snapshot,
69
+ ...(pluginManifest ? { pluginManifest } : {}),
70
+ releaseId,
71
+ ...(contentIcon ? { contentIcon } : {}),
72
+ ...(favicon ? { favicon } : {}),
73
+ metadataOnly: input.metadataOnly,
74
+ });
75
+ const release = input.transformRelease && !input.metadataOnly
76
+ ? input.transformRelease(originalRelease, snapshot, entry.name)
77
+ : originalRelease;
78
+ const compatibility = input.releaseCompatibility?.(release) ??
79
+ createCompatibility(source.config.marketplaceDialect, capabilities, policy);
80
+ const security = createSecurity(capabilities, policy, input.metadataOnly);
81
+ const normalizedCategories = entry.categories.map((category) => normalizeCategory(category, input.categoryMap));
82
+ const productCategory = input.productCategories?.[entry.name];
83
+ const categories = [
84
+ ...new Set((productCategory
85
+ ? [productCategory, ...normalizedCategories.filter((category) => category !== 'other')]
86
+ : normalizedCategories.length > 0
87
+ ? normalizedCategories
88
+ : [input.categoryMap.fallback]).filter(Boolean)),
89
+ ].toSorted();
90
+ // The name a list renders: marketplace manifests are inconsistent (`Gmail`
91
+ // beside `zapier` beside `aws-agents-for-devsecops`), so the catalog
92
+ // publishes the written form once and every consumer shows the same thing.
93
+ const displayName = normalizeDisplayName(entry.displayName ?? pluginManifest?.displayName ?? entry.name);
94
+ const authors = entry.authors.length > 0
95
+ ? [...entry.authors]
96
+ : source.parsed.owner.length > 0
97
+ ? [...source.parsed.owner]
98
+ : ['Unknown'];
99
+ const keywords = [...new Set([...entry.keywords, ...entry.name.split(/[-_\s]+/g), ...categories])]
100
+ .filter(Boolean)
101
+ .toSorted();
102
+ const provenance = {
103
+ sourceId: source.config.sourceId,
104
+ repositoryUrl: canonicalRepositoryUrl(source.config.repositoryUrl),
105
+ manifestPath: source.config.manifestPath,
106
+ pluginSubdirectory: resolved.subdirectory || '.',
107
+ resolvedCommitSha: resolved.commitSha,
108
+ sourceManifestDigest: source.manifestDigest,
109
+ upstreamEntryDigest: entry.entryDigest,
110
+ };
111
+ return {
112
+ pluginId: stablePluginId(source.config.sourceId, entry.name),
113
+ displayName,
114
+ description: entry.description || pluginManifest?.description || '',
115
+ productGroupingKey: productGroupingKey(entry.name, input.productAliases),
116
+ categories,
117
+ keywords,
118
+ authors,
119
+ ...(entry.homepage ? { homepage: entry.homepage } : {}),
120
+ icons: entry.icons.length > 0 ? [...entry.icons].toSorted() : (pluginManifest?.icons ?? []),
121
+ sourceId: source.config.sourceId,
122
+ upstreamPluginName: entry.name,
123
+ currentReleaseId: releaseId,
124
+ availableReleases: [release],
125
+ capabilitySummary: capabilitySummary(capabilities),
126
+ harnessCompatibility: compatibility,
127
+ license: findLicense(entry, pluginManifest?.metadata),
128
+ provenance,
129
+ securityClassification: security,
130
+ };
131
+ }
132
+ function createRelease(input) {
133
+ const requiredCredentials = new Set();
134
+ const auth = input.entry.policy.authentication;
135
+ if (typeof auth === 'string' && auth !== 'NONE' && auth !== 'DISABLED')
136
+ requiredCredentials.add('authentication');
137
+ for (const value of arrayValue(input.entry.raw.requiredCredentials))
138
+ if (typeof value === 'string')
139
+ requiredCredentials.add(value);
140
+ const requiredConnectors = [
141
+ ...new Set(arrayValue(input.entry.raw.connectors).filter(isString)),
142
+ ].toSorted();
143
+ const permissionSensitiveChanges = input.capabilities
144
+ .filter((capability) => capability.securityImpact === 'sensitive')
145
+ .map((capability) => capability.type)
146
+ .toSorted();
147
+ const metadata = {
148
+ catalogContract: CATALOG_CONTRACT_VERSION,
149
+ marketplaceEntry: input.entry.raw,
150
+ ...(input.pluginManifest ? { pluginManifest: input.pluginManifest.metadata } : {}),
151
+ sourceDialect: input.source.config.marketplaceDialect,
152
+ };
153
+ const version = input.pluginManifest?.version ?? stringValue(input.entry.raw.version);
154
+ return {
155
+ releaseId: input.releaseId,
156
+ ...(version ? { upstreamVersion: version } : {}),
157
+ resolvedRepositoryUrl: input.resolved.repositoryUrl,
158
+ resolvedCommitSha: input.resolved.commitSha,
159
+ pluginSubdirectory: input.resolved.subdirectory || '.',
160
+ canonicalContentDigest: input.contentDigest,
161
+ manifestDigest: input.manifestDigest,
162
+ contentResolution: input.metadataOnly ? 'metadata-only' : 'complete',
163
+ releaseMetadata: metadata,
164
+ capabilities: [...input.capabilities].toSorted((left, right) => left.type.localeCompare(right.type) || left.name.localeCompare(right.name)),
165
+ requiredConnectors,
166
+ requiredCredentials: [...requiredCredentials].toSorted(),
167
+ permissionSensitiveChanges: [...new Set(permissionSensitiveChanges)],
168
+ fileIndex: [...input.snapshot.files.keys()].toSorted(),
169
+ publicationTimestamp: input.source.retrievedAt,
170
+ ...assembleIcon(input),
171
+ };
172
+ }
173
+ /**
174
+ * Resolves the product site's icon, for a plugin whose content ships no mark.
175
+ *
176
+ * Only a live build with complete content attempts this: a metadata-only or
177
+ * offline run must not reach out to vendor sites, and neither may a product the
178
+ * curator has already decided about.
179
+ */
180
+ async function resolveFavicon(input) {
181
+ if (!input.live || input.metadataOnly)
182
+ return undefined;
183
+ if (input.iconOverride?.forced === null || input.iconOverride?.forced)
184
+ return undefined;
185
+ const homepage = input.iconOverride?.site ?? input.entry.homepage;
186
+ if (!isVendorHomepage(homepage))
187
+ return undefined;
188
+ // Bound both fetches: a vendor site that never answers must not stall a
189
+ // catalogue build. A timeout simply leaves the product on its monogram.
190
+ const signal = AbortSignal.timeout(SITE_FETCH_TIMEOUT_MS);
191
+ const resolved = await resolveSiteIcon(homepage, createSiteIconFetcher(signal));
192
+ return 'contentType' in resolved ? resolved : undefined;
193
+ }
194
+ /**
195
+ * Picks and vets the brand mark for a release.
196
+ *
197
+ * A file in the plugin's own content is preferred, because it is the mark the
198
+ * vendor ships with the plugin. When the content has none, a live build falls
199
+ * back to the declared homepage's site icon: many plugins are a thin wrapper
200
+ * over a vendor API and point at the vendor's site rather than shipping a logo.
201
+ * Whatever the source, an icon that fails inspection is absent rather than
202
+ * advertised: the catalog never publishes content it would refuse to mirror.
203
+ */
204
+ function resolveContentIcon(snapshot, iconOverride, metadataOnly) {
205
+ if (metadataOnly || snapshot.files.size === 0)
206
+ return undefined;
207
+ // A curator override wins over every rule, including "publish no icon".
208
+ if (iconOverride?.forced === null)
209
+ return undefined;
210
+ const files = [...snapshot.files.keys()].toSorted();
211
+ const forced = iconOverride?.forced;
212
+ if (forced && !files.includes(forced))
213
+ return undefined;
214
+ const path = forced ?? selectIconPath(files);
215
+ if (!path)
216
+ return undefined;
217
+ const bytes = snapshot.files.get(path);
218
+ if (!bytes)
219
+ return undefined;
220
+ const inspected = inspectIconBytes(bytes);
221
+ if (!('contentType' in inspected))
222
+ return undefined;
223
+ return {
224
+ kind: 'content',
225
+ path,
226
+ contentType: inspected.contentType,
227
+ digest: byteDigest(bytes),
228
+ bytes: bytes.byteLength,
229
+ };
230
+ }
231
+ function assembleIcon(input) {
232
+ if (input.contentIcon)
233
+ return { icon: input.contentIcon };
234
+ if (input.favicon)
235
+ return {
236
+ icon: {
237
+ kind: 'favicon',
238
+ url: input.favicon.url,
239
+ homepage: input.favicon.homepage,
240
+ contentType: input.favicon.contentType,
241
+ digest: input.favicon.digest,
242
+ bytes: input.favicon.bytes.byteLength,
243
+ },
244
+ };
245
+ return {};
246
+ }
247
+ function validateSnapshot(snapshot, policy, pluginName) {
248
+ if (snapshot.files.size > policy.maxFilesPerPlugin)
249
+ throw new PluginSafetyError('PLUGIN_TOO_MANY_FILES', [pluginName]);
250
+ let total = 0;
251
+ for (const [path, bytes] of snapshot.files) {
252
+ try {
253
+ safeRelativePath(path, 'SNAPSHOT_PATH_INVALID');
254
+ }
255
+ catch {
256
+ throw new PluginSafetyError('SNAPSHOT_PATH_INVALID', [path]);
257
+ }
258
+ if (bytes.byteLength > policy.maxFileBytes)
259
+ throw new PluginSafetyError('PLUGIN_FILE_TOO_LARGE', [path]);
260
+ total += bytes.byteLength;
261
+ }
262
+ if (total > policy.maxBytesPerPlugin)
263
+ throw new PluginSafetyError('PLUGIN_TOO_LARGE', [pluginName]);
264
+ }
265
+ function findPluginManifest(snapshot) {
266
+ const candidates = [...snapshot.files.keys()]
267
+ .filter((path) => {
268
+ const lower = path.toLocaleLowerCase();
269
+ return lower === 'plugin.json' || lower.endsWith('/plugin.json') || lower === 'package.json';
270
+ })
271
+ .toSorted((left, right) => manifestRank(left) - manifestRank(right) || left.localeCompare(right));
272
+ const path = candidates[0];
273
+ if (!path)
274
+ return undefined;
275
+ try {
276
+ const bytes = snapshot.files.get(path);
277
+ if (!bytes)
278
+ return undefined;
279
+ const metadata = parseJsonDocument(new TextDecoder().decode(bytes));
280
+ return {
281
+ metadata,
282
+ ...((stringValue(metadata.displayName) ?? stringValue(metadata.name))
283
+ ? { displayName: stringValue(metadata.displayName) ?? stringValue(metadata.name) }
284
+ : {}),
285
+ ...(stringValue(metadata.description)
286
+ ? { description: stringValue(metadata.description) }
287
+ : {}),
288
+ ...(stringValue(metadata.version) ? { version: stringValue(metadata.version) } : {}),
289
+ icons: [metadata.icon, ...(Array.isArray(metadata.icons) ? metadata.icons : [])]
290
+ .filter(isString)
291
+ .toSorted(),
292
+ };
293
+ }
294
+ catch {
295
+ throw new PluginSafetyError('PLUGIN_MANIFEST_INVALID', [path]);
296
+ }
297
+ }
298
+ function manifestRank(path) {
299
+ // A root manifest is the plugin's own declaration and outranks harness copies.
300
+ if (path === 'plugin.json')
301
+ return -1;
302
+ const lower = path.toLocaleLowerCase();
303
+ if (lower.endsWith('/.claude-plugin/plugin.json'))
304
+ return 0;
305
+ if (lower.endsWith('/.cursor-plugin/plugin.json'))
306
+ return 1;
307
+ if (lower.endsWith('/.agents/plugin.json'))
308
+ return 2;
309
+ return lower === 'plugin.json' ? 3 : 4;
310
+ }
311
+ function findLicense(entry, metadata) {
312
+ const candidate = stringValue(metadata?.license) ?? stringValue(entry.raw.license);
313
+ if (!candidate)
314
+ return { name: 'Unknown', source: 'unknown' };
315
+ return {
316
+ name: candidate,
317
+ ...(candidate.startsWith('http') ? { url: candidate } : {}),
318
+ source: metadata?.license !== undefined ? 'plugin-manifest' : 'marketplace-entry',
319
+ };
320
+ }
321
+ //# sourceMappingURL=plugin-release.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-release.js","sourceRoot":"","sources":["../src/plugin-release.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import type { MarketplacePluginEntry } from './sources.js';
2
+ import type { ResolvedSource } from './source-resolution.js';
3
+ export type PluginSkipReasonCode = 'GIT_SUBMODULE_UNSUPPORTED' | 'PLUGIN_FILE_TOO_LARGE' | 'PLUGIN_FILE_UNAVAILABLE' | 'PLUGIN_MANIFEST_INVALID' | 'PLUGIN_PATH_NOT_FOUND' | 'PLUGIN_SCHEMA_INVALID' | 'PLUGIN_SIZE_POLICY' | 'PLUGIN_SOURCE_UNAVAILABLE' | 'PLUGIN_TOO_LARGE' | 'PLUGIN_TOO_MANY_FILES' | 'SNAPSHOT_PATH_INVALID' | 'SYMLINK_ESCAPE';
4
+ export interface SkippedPlugin {
5
+ readonly sourceId: string;
6
+ readonly pluginId: string;
7
+ readonly pluginName: string;
8
+ readonly reasonCode: PluginSkipReasonCode;
9
+ readonly securityReason: string;
10
+ readonly incompleteContent: true;
11
+ readonly paths: readonly string[];
12
+ }
13
+ export declare class PluginSafetyError extends Error {
14
+ readonly reasonCode: PluginSkipReasonCode;
15
+ readonly paths: readonly string[];
16
+ constructor(reasonCode: PluginSkipReasonCode, paths: readonly string[]);
17
+ }
18
+ export declare function createSkippedPlugin(source: ResolvedSource, entry: MarketplacePluginEntry, error: unknown): SkippedPlugin | undefined;
19
+ export declare const UPSTREAM_WEATHER_SKIP_CODES: ReadonlySet<PluginSkipReasonCode>;
@@ -0,0 +1,65 @@
1
+ import { stablePluginId } from './taxonomy.js';
2
+ export class PluginSafetyError extends Error {
3
+ reasonCode;
4
+ paths;
5
+ constructor(reasonCode, paths) {
6
+ super(`${reasonCode}${paths.length > 0 ? `: ${paths.join(',')}` : ''}`);
7
+ this.reasonCode = reasonCode;
8
+ this.paths = paths;
9
+ this.name = 'PluginSafetyError';
10
+ }
11
+ }
12
+ const pluginSkipReasons = {
13
+ GIT_SUBMODULE_UNSUPPORTED: 'The plugin contains a Git submodule, so the catalog excludes it rather than traversing an unpinned repository boundary.',
14
+ PLUGIN_FILE_TOO_LARGE: 'The plugin contains a file over the configured size limit, so the catalog excludes the plugin before publication.',
15
+ PLUGIN_FILE_UNAVAILABLE: 'A plugin file could not be fetched from upstream after retries, so the catalog excludes the plugin rather than publishing partial content.',
16
+ PLUGIN_MANIFEST_INVALID: 'The plugin manifest is malformed, so the catalog excludes the plugin before consuming its metadata.',
17
+ PLUGIN_PATH_NOT_FOUND: 'The declared plugin path does not exist at the pinned commit, so the catalog excludes the plugin.',
18
+ PLUGIN_SCHEMA_INVALID: 'The normalized plugin record exceeds the published catalog schema, so the catalog excludes it before publication.',
19
+ PLUGIN_SIZE_POLICY: 'The plugin exceeds the configured size policy, so the catalog excludes it before publication.',
20
+ PLUGIN_SOURCE_UNAVAILABLE: 'The plugin repository tree could not be fetched from upstream after retries, so the catalog excludes the plugin rather than publishing partial content.',
21
+ PLUGIN_TOO_LARGE: 'The plugin exceeds the configured aggregate size limit, so the catalog excludes it before publication.',
22
+ PLUGIN_TOO_MANY_FILES: 'The plugin exceeds the configured file-count limit, so the catalog excludes it before publication.',
23
+ SNAPSHOT_PATH_INVALID: 'The plugin snapshot contains an unsafe path, so the catalog excludes it rather than allowing repository escape.',
24
+ SYMLINK_ESCAPE: 'The plugin snapshot contains symlinks; symlinks are never followed, so the catalog excludes the plugin.',
25
+ };
26
+ export function createSkippedPlugin(source, entry, error) {
27
+ const parsed = error instanceof PluginSafetyError
28
+ ? { reasonCode: error.reasonCode, paths: error.paths }
29
+ : parsePluginSafetyError(error);
30
+ if (!parsed)
31
+ return undefined;
32
+ return {
33
+ sourceId: source.config.sourceId,
34
+ pluginId: stablePluginId(source.config.sourceId, entry.name),
35
+ pluginName: entry.name,
36
+ reasonCode: parsed.reasonCode,
37
+ securityReason: pluginSkipReasons[parsed.reasonCode],
38
+ incompleteContent: true,
39
+ paths: [...new Set(parsed.paths)].toSorted(),
40
+ };
41
+ }
42
+ function parsePluginSafetyError(error) {
43
+ const message = error instanceof Error ? error.message : String(error);
44
+ const match = /^([A-Z_]+)(?::\s?(.*))?$/.exec(message);
45
+ if (!match)
46
+ return undefined;
47
+ const reasonCode = match[1];
48
+ if (!(reasonCode in pluginSkipReasons))
49
+ return undefined;
50
+ return {
51
+ reasonCode,
52
+ paths: match[2]
53
+ ? match[2]
54
+ .split(',')
55
+ .map((path) => path.trim())
56
+ .filter(Boolean)
57
+ : [],
58
+ };
59
+ }
60
+ export const UPSTREAM_WEATHER_SKIP_CODES = new Set([
61
+ 'PLUGIN_SOURCE_UNAVAILABLE',
62
+ 'PLUGIN_FILE_UNAVAILABLE',
63
+ 'PLUGIN_PATH_NOT_FOUND',
64
+ ]);
65
+ //# sourceMappingURL=plugin-skips.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-skips.js","sourceRoot":"","sources":["../src/plugin-skips.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ export interface CatalogPolicy {
2
+ readonly allowedRepositoryProtocols: readonly string[];
3
+ readonly allowedRepositoryHosts: readonly string[];
4
+ readonly maxFilesPerPlugin: number;
5
+ readonly maxBytesPerPlugin: number;
6
+ readonly maxFileBytes: number;
7
+ readonly maxMarketplacePlugins: number;
8
+ readonly denyExecutableLifecycleScripts: boolean;
9
+ readonly publishRequiresCompleteContent: boolean;
10
+ readonly sensitiveCapabilityTypes: readonly string[];
11
+ }
12
+ export declare const DEFAULT_POLICY: CatalogPolicy;
13
+ export declare function assertRepositoryAllowed(repositoryUrl: string, policy: CatalogPolicy): void;
package/dist/policy.js ADDED
@@ -0,0 +1,26 @@
1
+ import { PACKAGE_LIMITS } from './agent-plugins-schema.js';
2
+ import { canonicalRepositoryUrl } from './sources.js';
3
+ export const DEFAULT_POLICY = {
4
+ allowedRepositoryProtocols: ['https:'],
5
+ allowedRepositoryHosts: ['github.com', 'www.github.com'],
6
+ ...PACKAGE_LIMITS,
7
+ maxMarketplacePlugins: 4096,
8
+ denyExecutableLifecycleScripts: true,
9
+ publishRequiresCompleteContent: false,
10
+ sensitiveCapabilityTypes: [
11
+ 'mcp-server',
12
+ 'connector',
13
+ 'hook',
14
+ 'browser',
15
+ 'scheduled-task',
16
+ 'executable',
17
+ ],
18
+ };
19
+ export function assertRepositoryAllowed(repositoryUrl, policy) {
20
+ const parsed = new URL(canonicalRepositoryUrl(repositoryUrl));
21
+ if (!policy.allowedRepositoryProtocols.includes(parsed.protocol))
22
+ throw new Error(`GIT_PROTOCOL_POLICY: ${parsed.protocol}`);
23
+ if (!policy.allowedRepositoryHosts.includes(parsed.hostname.toLowerCase()))
24
+ throw new Error(`GIT_HOST_POLICY: ${parsed.hostname}`);
25
+ }
26
+ //# sourceMappingURL=policy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy.js","sourceRoot":"","sources":["../src/policy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAA;AAC1D,OAAO,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAA;AAcrD,MAAM,CAAC,MAAM,cAAc,GAAkB;IAC3C,0BAA0B,EAAE,CAAC,QAAQ,CAAC;IACtC,sBAAsB,EAAE,CAAC,YAAY,EAAE,gBAAgB,CAAC;IACxD,GAAG,cAAc;IACjB,qBAAqB,EAAE,IAAI;IAC3B,8BAA8B,EAAE,IAAI;IACpC,8BAA8B,EAAE,KAAK;IACrC,wBAAwB,EAAE;QACxB,YAAY;QACZ,WAAW;QACX,MAAM;QACN,SAAS;QACT,gBAAgB;QAChB,YAAY;KACb;CACF,CAAA;AAED,MAAM,UAAU,uBAAuB,CAAC,aAAqB,EAAE,MAAqB;IAClF,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,sBAAsB,CAAC,aAAa,CAAC,CAAC,CAAA;IAC7D,IAAI,CAAC,MAAM,CAAC,0BAA0B,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC;QAC9D,MAAM,IAAI,KAAK,CAAC,wBAAwB,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAA;IAC5D,IAAI,CAAC,MAAM,CAAC,sBAAsB,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;QACxE,MAAM,IAAI,KAAK,CAAC,oBAAoB,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAA;AAC1D,CAAC"}
@@ -1,9 +1,9 @@
1
- import { type Catalog } from './schema.js';
2
- import { type SyncInput, type SyncResult } from './index.js';
3
- export declare const PACKAGE_METADATA_KEY = "agentPlugins";
1
+ import { PACKAGE_METADATA_KEY } from './agent-plugins-schema.js';
2
+ import { verifyPortableCatalog } from './portable-verify.js';
3
+ import { type SyncInput, type SyncResult } from './synchronize.js';
4
+ export { PACKAGE_METADATA_KEY, verifyPortableCatalog };
4
5
  /** Default compiler path: immutable upstream catalog + canonical portable package recipes.
5
6
  * The existing v1 catalog envelope remains stable; the extension is versioned inside
6
7
  * releaseMetadata, which v1 deliberately defines as extensible JSON.
7
8
  */
8
9
  export declare function synchronizePortable(options: SyncInput): Promise<SyncResult>;
9
- export declare function verifyPortableCatalog(catalog: Catalog, requirePortable?: boolean): void;
@@ -1,8 +1,10 @@
1
- import { CatalogSchema, HarnessSchema } from './schema.js';
2
- import { orderLeadingPlugins, synchronize, createArtifacts, verifyArtifacts, digest, } from './index.js';
3
- import { compileAgentPackage, verifyAgentPackage, NORMALIZER_VERSION, } from './agent-plugins-catalog.js';
4
- import { CATALOG_CONTRACT_VERSION } from './index.js';
5
- export const PACKAGE_METADATA_KEY = 'agentPlugins';
1
+ import { compileAgentPackage, verifyAgentPackage } from './agent-plugins-catalog.js';
2
+ import { NORMALIZER_VERSION, PACKAGE_METADATA_KEY } from './agent-plugins-schema.js';
3
+ import { CATALOG_CONTRACT_VERSION } from './plugin-release.js';
4
+ import { HarnessSchema } from './schema.js';
5
+ import { verifyPortableCatalog } from './portable-verify.js';
6
+ import { synchronize } from './synchronize.js';
7
+ export { PACKAGE_METADATA_KEY, verifyPortableCatalog };
6
8
  function currentContract(catalog) {
7
9
  return (!!catalog &&
8
10
  catalog.plugins.every((plugin) => plugin.availableReleases.every((release) => {
@@ -73,6 +75,10 @@ export async function synchronizePortable(options) {
73
75
  ...options,
74
76
  metadataOnly: options.metadataOnly === true || options.dryRun === true,
75
77
  transformRelease,
78
+ releaseCompatibility: (release) => {
79
+ const pkg = release.releaseMetadata[PACKAGE_METADATA_KEY];
80
+ return pkg ? compatibility(verifyAgentPackage(pkg)) : undefined;
81
+ },
76
82
  };
77
83
  let result = await synchronize(input);
78
84
  if (!result.changed &&
@@ -83,126 +89,8 @@ export async function synchronizePortable(options) {
83
89
  // need not change for a format migration, and dry runs still never publish.
84
90
  result = await synchronize({ ...input, fromLock: input.existingLock });
85
91
  }
86
- if (!result.catalog || !result.lock || input.metadataOnly)
87
- return result;
88
- const plugins = [];
89
- for (const plugin of result.catalog.plugins) {
90
- const releases = plugin.availableReleases;
91
- const selected = releases.find((release) => release.releaseId === plugin.currentReleaseId);
92
- const pkg = selected?.releaseMetadata[PACKAGE_METADATA_KEY];
93
- plugins.push({
94
- ...plugin,
95
- availableReleases: releases,
96
- ...(pkg ? { harnessCompatibility: compatibility(verifyAgentPackage(pkg)) } : {}),
97
- });
98
- }
99
- const { catalogId: _oldId, ...old } = CatalogSchema.parse(result.catalog);
100
- // Ordering is applied before the catalog ID is computed so the emitted
101
- // identifier digests the final plugin order: each category's leading
102
- // products head the list.
103
- const ordered = orderLeadingPlugins({ ...old, plugins }, options.leading);
104
- const catalog = CatalogSchema.parse({
105
- ...ordered,
106
- catalogId: `catalog:${digest(ordered).slice(7)}`,
107
- });
108
- verifyPortableCatalog(catalog);
109
- const artifacts = createArtifacts(catalog, result.lock, {
110
- ...(options.leading ? { leading: options.leading } : {}),
111
- ...(options.topCount !== undefined ? { topCount: options.topCount } : {}),
112
- ...(options.productPreference ? { productPreference: options.productPreference } : {}),
113
- // Without this the shipped artifacts cannot advertise where they are
114
- // published, so brand marks and the browsing index lose their URLs. This
115
- // path replaces the artifacts the legacy compiler already produced, which is
116
- // why it must repeat every option it needs.
117
- ...(options.publicationRepositoryUrl
118
- ? { publicationRepositoryUrl: options.publicationRepositoryUrl }
119
- : {}),
120
- ...(options.publicationAssetsBaseUrl
121
- ? { publicationAssetsBaseUrl: options.publicationAssetsBaseUrl }
122
- : {}),
123
- ...(options.publicationCatalogsBaseUrl
124
- ? { publicationCatalogsBaseUrl: options.publicationCatalogsBaseUrl }
125
- : {}),
126
- curationDiagnostics: (options.mode ?? 'live') !== 'offline',
127
- });
128
- verifyArtifacts(artifacts);
129
- const changed = catalog.plugins
130
- .filter((plugin) => {
131
- const prior = input.existingCatalog?.plugins.find((item) => item.pluginId === plugin.pluginId);
132
- return prior && digest(prior) !== digest(plugin);
133
- })
134
- .map((plugin) => plugin.pluginId);
135
- return {
136
- ...result,
137
- catalog,
138
- artifacts,
139
- changeReport: {
140
- ...result.changeReport,
141
- changedPlugins: [...new Set([...result.changeReport.changedPlugins, ...changed])].toSorted(),
142
- },
143
- };
144
- }
145
- /**
146
- * A single-line summary of why a release's package descriptor was refused.
147
- *
148
- * The schema's own failure is a structured issue list; the catalog's refusal
149
- * contract is one typed line. The first issue is kept as the detail, because
150
- * it names the field that was wrong.
151
- */
152
- function describeProvenanceFailure(error) {
153
- const issues = error.issues;
154
- if (Array.isArray(issues) && issues.length > 0) {
155
- const first = issues[0];
156
- const path = Array.isArray(first.path) ? first.path.join('.') : '';
157
- const message = typeof first.message === 'string' ? first.message : '';
158
- return [path, message].filter(Boolean).join(': ').replace(/\s+/g, ' ').slice(0, 200);
159
- }
160
- return error instanceof Error
161
- ? error.message.replace(/\s+/g, ' ').slice(0, 200)
162
- : 'the descriptor is not a package recipe';
163
- }
164
- export function verifyPortableCatalog(catalog, requirePortable = false) {
165
- const { catalogId, ...body } = CatalogSchema.parse(catalog);
166
- if (catalogId !== `catalog:${digest(body).slice(7)}`)
167
- throw new Error('CATALOG_ID_MISMATCH');
168
- const ids = new Set();
169
- for (const plugin of catalog.plugins) {
170
- if (ids.has(plugin.pluginId))
171
- throw new Error('DUPLICATE_PLUGIN_ID');
172
- ids.add(plugin.pluginId);
173
- const releases = new Set(plugin.availableReleases.map((release) => release.releaseId));
174
- if (releases.size !== plugin.availableReleases.length || !releases.has(plugin.currentReleaseId))
175
- throw new Error('RELEASE_SELECTION_INVALID');
176
- }
177
- for (const plugin of catalog.plugins)
178
- for (const release of plugin.availableReleases) {
179
- if (requirePortable && release.contentResolution !== 'complete')
180
- throw new Error('COMPLETE_SOURCE_REQUIRED');
181
- const descriptor = release.releaseMetadata[PACKAGE_METADATA_KEY];
182
- if (descriptor === undefined) {
183
- if (requirePortable && release.contentResolution === 'complete')
184
- throw new Error(`PORTABLE_RESYNC_REQUIRED: ${plugin.pluginId}`);
185
- continue;
186
- }
187
- let pkg;
188
- try {
189
- pkg = verifyAgentPackage(descriptor);
190
- }
191
- catch (error) {
192
- // A consumer imports a catalog it did not compile, so a malformed
193
- // provenance descriptor is an IMPORT failure, and it must be refused
194
- // the way every other failure here is refused: one typed, single-line
195
- // reason that names the plugin. The schema's own multi-line issue
196
- // dump is not a refusal a consumer can match on.
197
- throw new Error(`PACKAGE_PROVENANCE_INVALID: ${plugin.pluginId} (${describeProvenanceFailure(error)})`, { cause: error });
198
- }
199
- if (release.contentResolution !== 'complete' ||
200
- pkg.sourceDigest !== release.canonicalContentDigest)
201
- throw new Error(`PACKAGE_PROVENANCE_MISMATCH: ${plugin.pluginId}`);
202
- const sourcePaths = new Set(release.fileIndex);
203
- for (const file of pkg.files)
204
- if (file.action === 'copy' && !sourcePaths.has(file.sourcePath))
205
- throw new Error(`PACKAGE_SOURCE_FILE_MISSING: ${plugin.pluginId}`);
206
- }
92
+ if (result.catalog && !input.metadataOnly)
93
+ verifyPortableCatalog(result.catalog);
94
+ return result;
207
95
  }
208
96
  //# sourceMappingURL=portable-catalog.js.map