@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.
- package/dist/agent-plugins-catalog.d.ts +2 -4
- package/dist/agent-plugins-catalog.js +42 -50
- package/dist/agent-plugins-catalog.js.map +1 -1
- package/dist/agent-plugins-schema.d.ts +8 -0
- package/dist/agent-plugins-schema.js +10 -1
- package/dist/agent-plugins-schema.js.map +1 -1
- package/dist/artifacts.d.ts +57 -0
- package/dist/artifacts.js +159 -0
- package/dist/artifacts.js.map +1 -0
- package/dist/build.d.ts +20 -0
- package/dist/build.js +103 -0
- package/dist/build.js.map +1 -0
- package/dist/capabilities.d.ts +7 -0
- package/dist/capabilities.js +116 -0
- package/dist/capabilities.js.map +1 -0
- package/dist/catalog-store.d.ts +76 -0
- package/dist/catalog-store.js +463 -0
- package/dist/catalog-store.js.map +1 -0
- package/dist/concurrency.d.ts +1 -0
- package/dist/concurrency.js +15 -0
- package/dist/concurrency.js.map +1 -0
- package/dist/consumer-index.d.ts +7 -29
- package/dist/consumer-index.js +24 -15
- package/dist/consumer-index.js.map +1 -1
- package/dist/digest.d.ts +13 -0
- package/dist/digest.js +47 -0
- package/dist/digest.js.map +1 -0
- package/dist/fs-atomic.d.ts +7 -0
- package/dist/fs-atomic.js +30 -0
- package/dist/fs-atomic.js.map +1 -0
- package/dist/harness.js +2 -1
- package/dist/harness.js.map +1 -1
- package/dist/icon-mirror.d.ts +5 -4
- package/dist/icon-mirror.js +73 -72
- package/dist/icon-mirror.js.map +1 -1
- package/dist/icons.d.ts +2 -2
- package/dist/icons.js +4 -12
- package/dist/icons.js.map +1 -1
- package/dist/index.d.ts +16 -309
- package/dist/index.js +12 -1900
- package/dist/index.js.map +1 -1
- package/dist/integrity-manifest.d.ts +43 -13
- package/dist/integrity-manifest.js +28 -17
- package/dist/integrity-manifest.js.map +1 -1
- package/dist/json-values.d.ts +3 -0
- package/dist/json-values.js +10 -0
- package/dist/json-values.js.map +1 -0
- package/dist/plugin-release.d.ts +38 -0
- package/dist/plugin-release.js +321 -0
- package/dist/plugin-release.js.map +1 -0
- package/dist/plugin-skips.d.ts +19 -0
- package/dist/plugin-skips.js +65 -0
- package/dist/plugin-skips.js.map +1 -0
- package/dist/policy.d.ts +13 -0
- package/dist/policy.js +26 -0
- package/dist/policy.js.map +1 -0
- package/dist/portable-catalog.d.ts +4 -4
- package/dist/portable-catalog.js +14 -126
- package/dist/portable-catalog.js.map +1 -1
- package/dist/portable-verify.d.ts +2 -0
- package/dist/portable-verify.js +68 -0
- package/dist/portable-verify.js.map +1 -0
- package/dist/publication.d.ts +12 -12
- package/dist/publication.js +31 -21
- package/dist/publication.js.map +1 -1
- package/dist/published-output.d.ts +17 -0
- package/dist/published-output.js +49 -0
- package/dist/published-output.js.map +1 -0
- package/dist/site-icons.d.ts +4 -3
- package/dist/site-icons.js +38 -11
- package/dist/site-icons.js.map +1 -1
- package/dist/snapshots.d.ts +39 -0
- package/dist/snapshots.js +238 -0
- package/dist/snapshots.js.map +1 -0
- package/dist/source-resolution.d.ts +28 -0
- package/dist/source-resolution.js +158 -0
- package/dist/source-resolution.js.map +1 -0
- package/dist/sources.d.ts +5 -1
- package/dist/sources.js +21 -27
- package/dist/sources.js.map +1 -1
- package/dist/synchronize.d.ts +44 -0
- package/dist/synchronize.js +118 -0
- package/dist/synchronize.js.map +1 -0
- package/dist/taxonomy.d.ts +23 -0
- package/dist/taxonomy.js +62 -0
- package/dist/taxonomy.js.map +1 -0
- package/dist/upstream.d.ts +42 -0
- package/dist/upstream.js +179 -0
- package/dist/upstream.js.map +1 -0
- package/dist/verify-artifacts.d.ts +36 -0
- package/dist/verify-artifacts.js +286 -0
- package/dist/verify-artifacts.js.map +1 -0
- package/native/build-provenance.txt +5 -5
- package/native/staged-reader-win32-arm64.node +0 -0
- package/native/staged-reader-win32-x64.node +0 -0
- package/package.json +3 -3
- package/src/agent-plugins-catalog.test.ts +2 -2
- package/src/agent-plugins-catalog.ts +46 -49
- package/src/agent-plugins-schema.ts +11 -1
- package/src/artifacts.test.ts +80 -0
- package/src/artifacts.ts +234 -0
- package/src/build.ts +131 -0
- package/src/capabilities.ts +153 -0
- package/src/catalog-store.ts +519 -0
- package/src/concurrency.ts +19 -0
- package/src/consumer-index.test.ts +147 -16
- package/src/consumer-index.ts +35 -43
- package/src/default-head.test.ts +143 -0
- package/src/digest.ts +55 -0
- package/src/fs-atomic.ts +32 -0
- package/src/harness.test.ts +4 -32
- package/src/harness.ts +2 -1
- package/src/icon-mirror.ts +78 -72
- package/src/icons.test.ts +0 -4
- package/src/icons.ts +4 -4
- package/src/index.test.ts +172 -46
- package/src/index.ts +58 -2562
- package/src/integrity-manifest.ts +41 -21
- package/src/json-values.ts +11 -0
- package/src/manifest-retry.test.ts +49 -0
- package/src/plugin-release.ts +457 -0
- package/src/plugin-skips.ts +110 -0
- package/src/policy.ts +39 -0
- package/src/portable-catalog.test.ts +0 -5
- package/src/portable-catalog.ts +16 -143
- package/src/portable-verify.ts +71 -0
- package/src/publication.test.ts +29 -1
- package/src/publication.ts +38 -22
- package/src/published-output.ts +60 -0
- package/src/site-icons.test.ts +73 -1
- package/src/site-icons.ts +31 -14
- package/src/snapshots.ts +287 -0
- package/src/source-config-sync.test.ts +84 -0
- package/src/source-digest.test.ts +61 -8
- package/src/source-resolution.ts +233 -0
- package/src/sources-json.test.ts +18 -2
- package/src/sources.ts +27 -33
- package/src/synchronize.ts +213 -0
- package/src/taxonomy.ts +87 -0
- package/src/upstream.ts +194 -0
- package/src/verify-artifacts.ts +365 -0
- package/src/write-artifacts.test.ts +374 -0
- package/dist/source-digest.d.ts +0 -2
- package/dist/source-digest.js +0 -12
- package/dist/source-digest.js.map +0 -1
- package/native/README.md +0 -24
- package/src/source-digest.ts +0 -14
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { publishCatalog } from './catalog-store.js';
|
|
2
|
+
import { buildConsumerIndex, CATALOG_INDEX_ARTIFACT, iconCoverage, } from './consumer-index.js';
|
|
3
|
+
import { digest } from './digest.js';
|
|
4
|
+
import { publishedAssetOf } from './integrity-manifest.js';
|
|
5
|
+
import { catalogIdSuffix, immutableAssetUrl } from './publication.js';
|
|
6
|
+
export function createArtifacts(catalog, lock, options = {}) {
|
|
7
|
+
const index = buildConsumerIndex({ ...options, catalog });
|
|
8
|
+
const summary = {
|
|
9
|
+
schemaVersion: 1,
|
|
10
|
+
catalogId: catalog.catalogId,
|
|
11
|
+
generatedAt: catalog.generatedAt,
|
|
12
|
+
sourceCount: catalog.sources.length,
|
|
13
|
+
pluginCount: catalog.plugins.length,
|
|
14
|
+
categories: [...new Set(catalog.plugins.flatMap((plugin) => plugin.categories))].toSorted(),
|
|
15
|
+
productGroups: [
|
|
16
|
+
...new Set(catalog.plugins.map((plugin) => plugin.productGroupingKey)),
|
|
17
|
+
].toSorted(),
|
|
18
|
+
search: catalog.plugins
|
|
19
|
+
.map((plugin) => ({
|
|
20
|
+
pluginId: plugin.pluginId,
|
|
21
|
+
text: `${plugin.displayName} ${plugin.description} ${plugin.keywords.join(' ')}`.trim(),
|
|
22
|
+
}))
|
|
23
|
+
.toSorted((left, right) => left.pluginId.localeCompare(right.pluginId)),
|
|
24
|
+
};
|
|
25
|
+
const compatibility = {
|
|
26
|
+
schemaVersion: 1,
|
|
27
|
+
catalogId: catalog.catalogId,
|
|
28
|
+
plugins: catalog.plugins.map((plugin) => ({
|
|
29
|
+
pluginId: plugin.pluginId,
|
|
30
|
+
harnessCompatibility: plugin.harnessCompatibility,
|
|
31
|
+
})),
|
|
32
|
+
};
|
|
33
|
+
// Navigation stays small and points at the shards a client then fetches:
|
|
34
|
+
// `shelf-*` for a default view, `category-*` for "view more", and
|
|
35
|
+
// `catalog-index.v1.json` for the complete product list.
|
|
36
|
+
const navigation = {
|
|
37
|
+
schemaVersion: 1,
|
|
38
|
+
catalogId: catalog.catalogId,
|
|
39
|
+
generatedAt: catalog.generatedAt,
|
|
40
|
+
topCount: index.topCount,
|
|
41
|
+
sourcePreference: index.sourcePreference,
|
|
42
|
+
counts: index.counts,
|
|
43
|
+
catalogIndexArtifact: CATALOG_INDEX_ARTIFACT,
|
|
44
|
+
iconCoverage: iconCoverage(index),
|
|
45
|
+
// The index URL rides in the navigation artifact so a client can fetch the
|
|
46
|
+
// browsing index from the publication it was told about, verify it against
|
|
47
|
+
// the digest in integrity.json, and never compose a URL or need this
|
|
48
|
+
// service to proxy it. Absent for an unpublished build.
|
|
49
|
+
...(options.publicationCatalogsBaseUrl
|
|
50
|
+
? {
|
|
51
|
+
catalogIndexUrl: `${options.publicationCatalogsBaseUrl}/${catalogIdSuffix(catalog.catalogId)}/${CATALOG_INDEX_ARTIFACT}`,
|
|
52
|
+
}
|
|
53
|
+
: options.publicationAssetsBaseUrl
|
|
54
|
+
? { catalogIndexUrl: `${options.publicationAssetsBaseUrl}/${CATALOG_INDEX_ARTIFACT}` }
|
|
55
|
+
: options.publicationRepositoryUrl
|
|
56
|
+
? {
|
|
57
|
+
catalogIndexUrl: immutableAssetUrl(options.publicationRepositoryUrl, catalog.catalogId, CATALOG_INDEX_ARTIFACT),
|
|
58
|
+
}
|
|
59
|
+
: {}),
|
|
60
|
+
// Marks ride in the navigation artifact so a client that already receives it
|
|
61
|
+
// renders compiled brand marks without fetching the browsing index. Keys are
|
|
62
|
+
// sorted for a stable artifact.
|
|
63
|
+
brandMarks: Object.fromEntries(Object.keys(index.products)
|
|
64
|
+
.toSorted()
|
|
65
|
+
.flatMap((productKey) => {
|
|
66
|
+
const assetUrl = index.products[productKey]?.icon?.assetUrl;
|
|
67
|
+
return assetUrl ? [[productKey, assetUrl]] : [];
|
|
68
|
+
})),
|
|
69
|
+
categories: index.categories,
|
|
70
|
+
diagnostics: options.curationDiagnostics === false ? [] : index.diagnostics,
|
|
71
|
+
};
|
|
72
|
+
const shards = {
|
|
73
|
+
[CATALOG_INDEX_ARTIFACT]: json({
|
|
74
|
+
schemaVersion: 1,
|
|
75
|
+
catalogId: catalog.catalogId,
|
|
76
|
+
generatedAt: catalog.generatedAt,
|
|
77
|
+
topCount: index.topCount,
|
|
78
|
+
sourcePreference: index.sourcePreference,
|
|
79
|
+
counts: index.counts,
|
|
80
|
+
products: index.products,
|
|
81
|
+
categories: index.categories.map((category) => ({
|
|
82
|
+
category: category.category,
|
|
83
|
+
productCount: category.productCount,
|
|
84
|
+
productKeys: category.productKeys,
|
|
85
|
+
})),
|
|
86
|
+
}),
|
|
87
|
+
};
|
|
88
|
+
for (const category of index.categories) {
|
|
89
|
+
shards[category.shelfArtifact] = json({
|
|
90
|
+
schemaVersion: 1,
|
|
91
|
+
catalogId: catalog.catalogId,
|
|
92
|
+
category: category.category,
|
|
93
|
+
topCount: index.topCount,
|
|
94
|
+
products: category.topProductKeys.map((productKey) => index.products[productKey]),
|
|
95
|
+
});
|
|
96
|
+
shards[category.listArtifact] = json({
|
|
97
|
+
schemaVersion: 1,
|
|
98
|
+
catalogId: catalog.catalogId,
|
|
99
|
+
category: category.category,
|
|
100
|
+
productCount: category.productCount,
|
|
101
|
+
pluginCount: category.pluginCount,
|
|
102
|
+
products: category.productKeys.map((productKey) => index.products[productKey]),
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
const files = {
|
|
106
|
+
'catalog.v1.json': json(catalog),
|
|
107
|
+
'catalog-summary.v1.json': json(summary),
|
|
108
|
+
'sources.lock.json': json(lock),
|
|
109
|
+
'compatibility.v1.json': json(compatibility),
|
|
110
|
+
'categories.v1.json': json(navigation),
|
|
111
|
+
...shards,
|
|
112
|
+
};
|
|
113
|
+
const integrityBody = {
|
|
114
|
+
schemaVersion: 1,
|
|
115
|
+
catalogId: catalog.catalogId,
|
|
116
|
+
// An artifact's digest is the canonical digest of its text, not a hash of
|
|
117
|
+
// the file bytes: consumers read the artifact as a string and compare it
|
|
118
|
+
// with `canonicalDigest`, so a checker hashing the raw bytes will disagree
|
|
119
|
+
// with every published release. Mirrored marks below are the byte case,
|
|
120
|
+
// because a client stores those bytes.
|
|
121
|
+
files: Object.fromEntries(Object.entries(files)
|
|
122
|
+
.toSorted()
|
|
123
|
+
.map(([name, content]) => [name, digest(content)])),
|
|
124
|
+
// Mirrored brand marks are published next to the artifacts, never inside
|
|
125
|
+
// them: the digest and size let a consumer or the release check verify the
|
|
126
|
+
// bytes it fetched without trusting the release listing.
|
|
127
|
+
assets: iconAssets(index),
|
|
128
|
+
};
|
|
129
|
+
return { ...files, 'integrity.json': json(integrityBody) };
|
|
130
|
+
}
|
|
131
|
+
export function iconAssets(index) {
|
|
132
|
+
const assets = new Map();
|
|
133
|
+
for (const product of Object.values(index.products)) {
|
|
134
|
+
if (!product.icon)
|
|
135
|
+
continue;
|
|
136
|
+
assets.set(product.icon.asset, publishedAssetOf(product.icon));
|
|
137
|
+
}
|
|
138
|
+
return [...assets.values()].toSorted((left, right) => left.name.localeCompare(right.name));
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Publishes a verified artifact set to `generatedDirectory` under the output's
|
|
142
|
+
* coordination lock. See `catalog-store.ts` for the publication contract.
|
|
143
|
+
*/
|
|
144
|
+
export async function writeArtifacts(generatedDirectory, artifacts, options = {}) {
|
|
145
|
+
await publishCatalog(generatedDirectory, artifacts, options);
|
|
146
|
+
}
|
|
147
|
+
function sortArtifactKeys(value) {
|
|
148
|
+
if (Array.isArray(value))
|
|
149
|
+
return value.map(sortArtifactKeys);
|
|
150
|
+
if (value !== null && typeof value === 'object')
|
|
151
|
+
return Object.fromEntries(Object.keys(value)
|
|
152
|
+
.toSorted()
|
|
153
|
+
.map((key) => [key, sortArtifactKeys(value[key])]));
|
|
154
|
+
return value;
|
|
155
|
+
}
|
|
156
|
+
function json(value) {
|
|
157
|
+
return `${JSON.stringify(sortArtifactKeys(value), null, 2)}\n`;
|
|
158
|
+
}
|
|
159
|
+
//# sourceMappingURL=artifacts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"artifacts.js","sourceRoot":"","sources":["../src/artifacts.ts"],"names":[],"mappings":"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"}
|
package/dist/build.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type ReleaseOptions } from './plugin-release.js';
|
|
2
|
+
import { type SkippedPlugin } from './plugin-skips.js';
|
|
3
|
+
import { type CatalogPolicy } from './policy.js';
|
|
4
|
+
import { type Catalog } from './schema.js';
|
|
5
|
+
import type { ResolvedSource } from './source-resolution.js';
|
|
6
|
+
export interface BuildCatalogInput extends Omit<ReleaseOptions, 'policy' | 'metadataOnly' | 'resolveExternalRefs'> {
|
|
7
|
+
readonly resolvedSources: readonly ResolvedSource[];
|
|
8
|
+
/** Each category's curated products, which head the catalog in this order. */
|
|
9
|
+
readonly leading?: Readonly<Record<string, readonly string[]>>;
|
|
10
|
+
readonly policy?: CatalogPolicy;
|
|
11
|
+
readonly metadataOnly?: boolean;
|
|
12
|
+
readonly resolveExternalRefs?: boolean;
|
|
13
|
+
}
|
|
14
|
+
interface BuildCatalogResult {
|
|
15
|
+
readonly catalog: Catalog;
|
|
16
|
+
readonly skippedPlugins: readonly SkippedPlugin[];
|
|
17
|
+
}
|
|
18
|
+
export declare function buildCatalog(input: BuildCatalogInput): Promise<Catalog>;
|
|
19
|
+
export declare function buildCatalogInternal(input: BuildCatalogInput): Promise<BuildCatalogResult>;
|
|
20
|
+
export {};
|
package/dist/build.js
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { mapWithConcurrency } from './concurrency.js';
|
|
2
|
+
import { contentId } from './digest.js';
|
|
3
|
+
import { normalizePlugin } from './plugin-release.js';
|
|
4
|
+
import { createSkippedPlugin, PluginSafetyError, UPSTREAM_WEATHER_SKIP_CODES, } from './plugin-skips.js';
|
|
5
|
+
import { assertRepositoryAllowed, DEFAULT_POLICY } from './policy.js';
|
|
6
|
+
import { CatalogSchema, PluginSchema, } from './schema.js';
|
|
7
|
+
import { canonicalRepositoryUrl } from './sources.js';
|
|
8
|
+
import { orderLeadingPlugins } from './taxonomy.js';
|
|
9
|
+
export async function buildCatalog(input) {
|
|
10
|
+
return (await buildCatalogInternal(input)).catalog;
|
|
11
|
+
}
|
|
12
|
+
export async function buildCatalogInternal(input) {
|
|
13
|
+
const policy = input.policy ?? DEFAULT_POLICY;
|
|
14
|
+
const options = {
|
|
15
|
+
...input,
|
|
16
|
+
policy,
|
|
17
|
+
metadataOnly: input.metadataOnly ?? false,
|
|
18
|
+
resolveExternalRefs: input.resolveExternalRefs ?? false,
|
|
19
|
+
};
|
|
20
|
+
for (const source of input.resolvedSources) {
|
|
21
|
+
assertRepositoryAllowed(source.config.repositoryUrl, policy);
|
|
22
|
+
for (const entry of source.parsed.entries) {
|
|
23
|
+
if (entry.source.kind === 'git')
|
|
24
|
+
assertRepositoryAllowed(entry.source.repositoryUrl, policy);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
const sourceRecords = input.resolvedSources
|
|
28
|
+
.map(({ config, commitSha, retrievedAt, manifestDigest }) => ({
|
|
29
|
+
sourceId: config.sourceId,
|
|
30
|
+
displayName: config.displayName,
|
|
31
|
+
repositoryUrl: canonicalRepositoryUrl(config.repositoryUrl),
|
|
32
|
+
marketplaceDialect: config.marketplaceDialect,
|
|
33
|
+
manifestPath: config.manifestPath,
|
|
34
|
+
defaultBranch: config.defaultBranch,
|
|
35
|
+
resolvedCommitSha: commitSha,
|
|
36
|
+
retrievalTimestamp: retrievedAt,
|
|
37
|
+
trustClassification: config.trustClassification,
|
|
38
|
+
sourceManifestDigest: manifestDigest,
|
|
39
|
+
synchronizationStatus: 'synchronized',
|
|
40
|
+
}))
|
|
41
|
+
.toSorted((left, right) => left.sourceId.localeCompare(right.sourceId));
|
|
42
|
+
let plugins = [];
|
|
43
|
+
let skippedPlugins = [];
|
|
44
|
+
for (const source of input.resolvedSources) {
|
|
45
|
+
if (source.parsed.entries.length > policy.maxMarketplacePlugins)
|
|
46
|
+
throw new Error('MARKETPLACE_TOO_MANY_PLUGINS');
|
|
47
|
+
const normalized = await mapWithConcurrency(source.parsed.entries, 8, async (entry) => {
|
|
48
|
+
try {
|
|
49
|
+
const plugin = await normalizePlugin(source, entry, options);
|
|
50
|
+
try {
|
|
51
|
+
return { plugin: PluginSchema.parse(plugin) };
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
throw new PluginSafetyError('PLUGIN_SCHEMA_INVALID', []);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
const skipped = createSkippedPlugin(source, entry, error);
|
|
59
|
+
if (!skipped)
|
|
60
|
+
throw error;
|
|
61
|
+
return { skipped };
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
const sourcePlugins = [];
|
|
65
|
+
const sourceSkipped = [];
|
|
66
|
+
for (const result of normalized) {
|
|
67
|
+
if (result.plugin)
|
|
68
|
+
sourcePlugins.push(result.plugin);
|
|
69
|
+
if (result.skipped)
|
|
70
|
+
sourceSkipped.push(result.skipped);
|
|
71
|
+
}
|
|
72
|
+
const weatherSkips = sourceSkipped.filter((skipped) => UPSTREAM_WEATHER_SKIP_CODES.has(skipped.reasonCode));
|
|
73
|
+
if (source.parsed.entries.length > 0 && weatherSkips.length === source.parsed.entries.length)
|
|
74
|
+
throw new PluginSafetyError('PLUGIN_SOURCE_UNAVAILABLE', [
|
|
75
|
+
canonicalRepositoryUrl(source.config.repositoryUrl),
|
|
76
|
+
]);
|
|
77
|
+
for (const plugin of sourcePlugins)
|
|
78
|
+
plugins.push(plugin);
|
|
79
|
+
for (const skipped of sourceSkipped)
|
|
80
|
+
skippedPlugins.push(skipped);
|
|
81
|
+
}
|
|
82
|
+
plugins = plugins.toSorted((left, right) => left.pluginId.localeCompare(right.pluginId));
|
|
83
|
+
skippedPlugins = skippedPlugins.toSorted((left, right) => left.pluginId.localeCompare(right.pluginId) ||
|
|
84
|
+
left.reasonCode.localeCompare(right.reasonCode) ||
|
|
85
|
+
left.paths.join('\0').localeCompare(right.paths.join('\0')));
|
|
86
|
+
const body = {
|
|
87
|
+
schemaVersion: 1,
|
|
88
|
+
generatedAt: sourceRecords
|
|
89
|
+
.map((s) => s.retrievalTimestamp)
|
|
90
|
+
.toSorted()
|
|
91
|
+
.at(-1) ?? new Date(0).toISOString(),
|
|
92
|
+
sources: sourceRecords,
|
|
93
|
+
plugins: orderLeadingPlugins({ plugins }, input.leading).plugins,
|
|
94
|
+
};
|
|
95
|
+
return {
|
|
96
|
+
catalog: CatalogSchema.parse({
|
|
97
|
+
...body,
|
|
98
|
+
catalogId: contentId('catalog', body),
|
|
99
|
+
}),
|
|
100
|
+
skippedPlugins,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=build.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build.js","sourceRoot":"","sources":["../src/build.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type CatalogPolicy } from './policy.js';
|
|
2
|
+
import type { MarketplaceDialect } from './sources.js';
|
|
3
|
+
import { type Capability, type Harness, type HarnessCompatibility, type SecurityClassification } from './schema.js';
|
|
4
|
+
export declare function classifyCapabilities(files: ReadonlyMap<string, Uint8Array>, metadata?: Record<string, unknown>, policy?: CatalogPolicy): Capability[];
|
|
5
|
+
export declare function capabilitySummary(capabilities: readonly Capability[]): Record<Capability['type'], number>;
|
|
6
|
+
export declare function createCompatibility(dialect: MarketplaceDialect, capabilities: readonly Capability[], policy?: CatalogPolicy): Record<Harness, HarnessCompatibility>;
|
|
7
|
+
export declare function createSecurity(capabilities: readonly Capability[], policy: CatalogPolicy, metadataOnly: boolean): SecurityClassification;
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { basename } from 'node:path';
|
|
2
|
+
import { DEFAULT_POLICY } from './policy.js';
|
|
3
|
+
import { HarnessSchema, } from './schema.js';
|
|
4
|
+
export function classifyCapabilities(files, metadata, policy = DEFAULT_POLICY) {
|
|
5
|
+
const groups = new Map();
|
|
6
|
+
const add = (type, path) => groups.set(type, [...(groups.get(type) ?? []), path]);
|
|
7
|
+
for (const path of files.keys()) {
|
|
8
|
+
const lower = path.toLocaleLowerCase();
|
|
9
|
+
const file = basename(lower);
|
|
10
|
+
if (file === 'skill.md' || lower.includes('/skills/'))
|
|
11
|
+
add('skill', path);
|
|
12
|
+
if (file === '.mcp.json' || file === 'mcp.json' || lower.includes('/mcp-servers/'))
|
|
13
|
+
add('mcp-server', path);
|
|
14
|
+
if (lower.includes('/commands/') || lower.startsWith('commands/'))
|
|
15
|
+
add('command', path);
|
|
16
|
+
if (lower.includes('/agents/') || lower.startsWith('agents/') || lower.includes('/subagents/'))
|
|
17
|
+
add('agent', path);
|
|
18
|
+
if (lower.includes('/hooks/') || lower.startsWith('hooks/') || file === 'hooks.json')
|
|
19
|
+
add('hook', path);
|
|
20
|
+
if (lower.includes('/rules/') ||
|
|
21
|
+
lower.startsWith('rules/') ||
|
|
22
|
+
file === 'agents.md' ||
|
|
23
|
+
file === 'claude.md' ||
|
|
24
|
+
lower.includes('.cursor/rules/'))
|
|
25
|
+
add('rule', path);
|
|
26
|
+
if (lower.includes('browser') || lower.includes('playwright') || lower.includes('chrome'))
|
|
27
|
+
add('browser', path);
|
|
28
|
+
if (lower.includes('/schedule') || lower.includes('/cron') || file.includes('schedule'))
|
|
29
|
+
add('scheduled-task', path);
|
|
30
|
+
if (lower.includes('/ui/') || lower.startsWith('ui/') || lower.includes('/components/'))
|
|
31
|
+
add('ui-component', path);
|
|
32
|
+
if (lower.startsWith('bin/') ||
|
|
33
|
+
lower.startsWith('scripts/') ||
|
|
34
|
+
/\.(sh|bash|py|exe|bin)$/.test(file))
|
|
35
|
+
add('executable', path);
|
|
36
|
+
}
|
|
37
|
+
if (metadata && (metadata.mcpServers !== undefined || metadata.mcp !== undefined))
|
|
38
|
+
add('mcp-server', 'plugin-manifest');
|
|
39
|
+
if (metadata && (metadata.hooks !== undefined || metadata.hook !== undefined))
|
|
40
|
+
add('hook', 'plugin-manifest');
|
|
41
|
+
if (groups.size === 0)
|
|
42
|
+
groups.set('unknown', ['plugin-root']);
|
|
43
|
+
return [...groups.entries()].map(([type, paths]) => ({
|
|
44
|
+
type: type,
|
|
45
|
+
name: type,
|
|
46
|
+
paths: [...new Set(paths)].toSorted(),
|
|
47
|
+
metadata: {},
|
|
48
|
+
securityImpact: policy.sensitiveCapabilityTypes.includes(type) ? 'sensitive' : 'none',
|
|
49
|
+
}));
|
|
50
|
+
}
|
|
51
|
+
export function capabilitySummary(capabilities) {
|
|
52
|
+
const summary = {};
|
|
53
|
+
for (const capability of capabilities)
|
|
54
|
+
summary[capability.type] = capability.paths.length;
|
|
55
|
+
return summary;
|
|
56
|
+
}
|
|
57
|
+
export function createCompatibility(dialect, capabilities, policy = DEFAULT_POLICY) {
|
|
58
|
+
const types = [...new Set(capabilities.map((capability) => capability.type))].toSorted();
|
|
59
|
+
const sensitive = types.filter((type) => policy.sensitiveCapabilityTypes.includes(type));
|
|
60
|
+
const make = (status, reasons) => ({
|
|
61
|
+
status,
|
|
62
|
+
reasons: [...new Set(reasons)].toSorted(),
|
|
63
|
+
responsibleCapabilities: types,
|
|
64
|
+
});
|
|
65
|
+
const result = {};
|
|
66
|
+
for (const harness of HarnessSchema.options) {
|
|
67
|
+
const native = (harness === 'claude-code' && dialect === 'claude') ||
|
|
68
|
+
(harness === 'cursor' && dialect === 'cursor') ||
|
|
69
|
+
(harness === 'codex' && dialect === 'openai');
|
|
70
|
+
if (types.includes('executable'))
|
|
71
|
+
result[harness] = make('unsupported', [
|
|
72
|
+
'Executable components require harness-specific execution authority.',
|
|
73
|
+
]);
|
|
74
|
+
else if (types.includes('unknown'))
|
|
75
|
+
result[harness] = make('unknown', [
|
|
76
|
+
'The plugin content was not classified into a supported component type.',
|
|
77
|
+
]);
|
|
78
|
+
else if (native && sensitive.length === 0)
|
|
79
|
+
result[harness] = make('native', [
|
|
80
|
+
`The ${dialect} marketplace dialect matches the ${harness} harness.`,
|
|
81
|
+
]);
|
|
82
|
+
else if (sensitive.length > 0 && ['pi', 'hermes', 'opencode'].includes(harness))
|
|
83
|
+
result[harness] = make('partially-supported', [
|
|
84
|
+
`Sensitive capabilities require ${harness} policy and runtime review.`,
|
|
85
|
+
...sensitive.map((type) => `Capability ${type} is not granted by this catalog.`),
|
|
86
|
+
]);
|
|
87
|
+
else if (types.every((type) => ['skill', 'rule', 'mcp-server', 'command', 'agent'].includes(type)))
|
|
88
|
+
result[harness] = make(native ? 'native' : 'portable', native
|
|
89
|
+
? [`The ${dialect} marketplace dialect matches the ${harness} harness.`]
|
|
90
|
+
: ['Files can be copied or translated into the harness layout.']);
|
|
91
|
+
else
|
|
92
|
+
result[harness] = make('requires-translation', [
|
|
93
|
+
'One or more capabilities need a harness-specific projection.',
|
|
94
|
+
]);
|
|
95
|
+
}
|
|
96
|
+
return result;
|
|
97
|
+
}
|
|
98
|
+
export function createSecurity(capabilities, policy, metadataOnly) {
|
|
99
|
+
const sensitive = [
|
|
100
|
+
...new Set(capabilities
|
|
101
|
+
.filter((capability) => policy.sensitiveCapabilityTypes.includes(capability.type))
|
|
102
|
+
.map((capability) => capability.type)),
|
|
103
|
+
].toSorted();
|
|
104
|
+
const reasons = sensitive.length > 0
|
|
105
|
+
? sensitive.map((type) => `Contains ${type} capability metadata.`)
|
|
106
|
+
: metadataOnly
|
|
107
|
+
? ['Content was not fetched in metadata-only mode.']
|
|
108
|
+
: ['No permission-sensitive executable capability was detected.'];
|
|
109
|
+
return {
|
|
110
|
+
level: sensitive.length > 0 ? 'sensitive' : metadataOnly ? 'review' : 'low',
|
|
111
|
+
reasons,
|
|
112
|
+
permissionSensitiveChanges: sensitive,
|
|
113
|
+
contentResolution: metadataOnly ? 'metadata-only' : 'complete',
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=capabilities.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capabilities.js","sourceRoot":"","sources":["../src/capabilities.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
export type PublicationStep = 'acquiring' | 'staged' | 'backed-up' | 'swapped' | 'cleaned';
|
|
2
|
+
export interface CatalogCoordinationOptions {
|
|
3
|
+
/** How long to wait for another holder before failing; default 30 s. */
|
|
4
|
+
readonly waitMs?: number;
|
|
5
|
+
/** Heartbeat age after which a holder is considered dead; default 120 s. */
|
|
6
|
+
readonly staleAfterMs?: number;
|
|
7
|
+
/** Interval at which a holder refreshes its heartbeat; default 5 s. */
|
|
8
|
+
readonly heartbeatMs?: number;
|
|
9
|
+
/** Interval between lock attempts while waiting; default 50 ms. */
|
|
10
|
+
readonly pollMs?: number;
|
|
11
|
+
/** Test seam: called after each publication step while the lock is held. */
|
|
12
|
+
readonly onStep?: (step: PublicationStep) => void | Promise<void>;
|
|
13
|
+
/** Test seam: called once a lock is held. */
|
|
14
|
+
readonly onLocked?: (mode: LockMode) => void | Promise<void>;
|
|
15
|
+
}
|
|
16
|
+
export interface PublishOptions extends CatalogCoordinationOptions {
|
|
17
|
+
/**
|
|
18
|
+
* Fingerprint of the output the caller built from, as returned by
|
|
19
|
+
* {@link catalogFingerprint} inside {@link withCatalogRead}. When set, the
|
|
20
|
+
* publication fails with `CATALOG_BASE_CHANGED` if the output differs.
|
|
21
|
+
*/
|
|
22
|
+
readonly expectedBase?: string;
|
|
23
|
+
/** Runs after the swap while the lock is still held, e.g. to publish an index. */
|
|
24
|
+
readonly afterPublish?: () => Promise<void>;
|
|
25
|
+
}
|
|
26
|
+
type LockMode = 'read' | 'write';
|
|
27
|
+
export interface CatalogPaths {
|
|
28
|
+
readonly output: string;
|
|
29
|
+
readonly parent: string;
|
|
30
|
+
readonly backup: string;
|
|
31
|
+
readonly lock: string;
|
|
32
|
+
readonly owner: string;
|
|
33
|
+
readonly journal: string;
|
|
34
|
+
readonly stagePrefix: string;
|
|
35
|
+
}
|
|
36
|
+
/** Names the coordination files of one output, beside it in its real parent. */
|
|
37
|
+
export declare function catalogPathsIn(parent: string, name: string): CatalogPaths;
|
|
38
|
+
export declare class CatalogLock {
|
|
39
|
+
#private;
|
|
40
|
+
readonly paths: CatalogPaths;
|
|
41
|
+
readonly token: string;
|
|
42
|
+
constructor(paths: CatalogPaths, token: string, heartbeatMs: number);
|
|
43
|
+
/** Fails with `CATALOG_LOCK_LOST` if another process broke this lock. */
|
|
44
|
+
assertHeld(): Promise<void>;
|
|
45
|
+
release(): Promise<void>;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Completes or undoes an interrupted publication. Must run under the lock.
|
|
49
|
+
*
|
|
50
|
+
* | output | backup | staged dir | meaning | action |
|
|
51
|
+
* | ------ | ------ | ---------- | -------------------------------- | -------------- |
|
|
52
|
+
* | yes | no | any | not swapped, or already cleaned | drop staging |
|
|
53
|
+
* | no | yes | any | died between the two renames | roll back |
|
|
54
|
+
* | yes | yes | no | swapped, backup not yet removed | roll forward |
|
|
55
|
+
* | no | no | any | first publication never swapped | drop staging |
|
|
56
|
+
* | yes | yes | yes | inconsistent | stop, preserve |
|
|
57
|
+
*/
|
|
58
|
+
export declare function recoverCatalogOutput(paths: CatalogPaths): Promise<void>;
|
|
59
|
+
/**
|
|
60
|
+
* A digest of the output's entries and bytes, or `absent`. Run it under the
|
|
61
|
+
* lock (inside {@link withCatalogRead}) so it describes a published state.
|
|
62
|
+
*/
|
|
63
|
+
export declare function catalogFingerprint(output: string): Promise<string>;
|
|
64
|
+
/**
|
|
65
|
+
* Runs `read` while no writer can publish to `output`, after finishing any
|
|
66
|
+
* interrupted publication. Readers are serialized with writers and with each
|
|
67
|
+
* other; the lock is held only for the read itself.
|
|
68
|
+
*/
|
|
69
|
+
export declare function withCatalogRead<T>(output: string, read: () => Promise<T>, options?: CatalogCoordinationOptions): Promise<T>;
|
|
70
|
+
/**
|
|
71
|
+
* Replaces `output` with exactly `files`. The previous output stays in place
|
|
72
|
+
* until the new one is complete, and a coordinated reader sees either one or
|
|
73
|
+
* the other.
|
|
74
|
+
*/
|
|
75
|
+
export declare function publishCatalog(output: string, files: Readonly<Record<string, string | Uint8Array>>, options?: PublishOptions): Promise<void>;
|
|
76
|
+
export {};
|