@lesliechan721/aw-plugin-core 0.1.0-beta.7 → 0.1.0-beta.9
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/aw-capabilities.d.ts +27 -0
- package/dist/aw-capabilities.js +106 -0
- package/dist/aw-capabilities.js.map +1 -0
- package/dist/catalog-workspace-resolution.d.ts +3 -0
- package/dist/catalog-workspace-resolution.js +34 -0
- package/dist/catalog-workspace-resolution.js.map +1 -0
- package/dist/generated/{plugin-manifest-v1.d.ts → plugin-manifest-v2.d.ts} +44 -31
- package/dist/generated/{plugin-manifest-v1.js → plugin-manifest-v2.js} +1 -1
- package/dist/generated/plugin-manifest-v2.js.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/manifest-contract.d.ts +3 -6
- package/dist/manifest-contract.js +54 -63
- package/dist/manifest-contract.js.map +1 -1
- package/dist/manifest-type-contract.d.ts +2 -2
- package/dist/manifest.d.ts +8 -8
- package/dist/manifest.js +9 -7
- package/dist/manifest.js.map +1 -1
- package/dist/plugin-authoring-capabilities.js +4 -3
- package/dist/plugin-authoring-capabilities.js.map +1 -1
- package/dist/plugin-requirements.d.ts +34 -0
- package/dist/plugin-requirements.js +248 -0
- package/dist/plugin-requirements.js.map +1 -0
- package/dist/plugin-script-contract.d.ts +8 -0
- package/dist/plugin-script-contract.js +38 -1
- package/dist/plugin-script-contract.js.map +1 -1
- package/dist/types.d.ts +25 -22
- package/dist/workspace.d.ts +17 -9
- package/dist/workspace.js +299 -138
- package/dist/workspace.js.map +1 -1
- package/package.json +2 -2
- package/schemas/{plugin-manifest-v1.json → plugin-manifest-v2.json} +41 -11
- package/dist/generated/plugin-manifest-v1.js.map +0 -1
- package/dist/plugin-release.d.ts +0 -30
- package/dist/plugin-release.js +0 -187
- package/dist/plugin-release.js.map +0 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
import { isDeepStrictEqual } from 'node:util';
|
|
3
3
|
import fs from 'fs-extra';
|
|
4
|
+
import { computeAwCapabilitySetDigest, normalizeAwCapabilities, } from './aw-capabilities.js';
|
|
4
5
|
import { normalizePluginManifestSchemaVersion, PLUGIN_MANIFEST_SCHEMA_VERSION, SOURCE_PLUGIN_MANIFEST_CONTRACT_VERSION, } from './manifest.js';
|
|
5
6
|
import { readJsonFile } from './read-json.js';
|
|
6
7
|
import { parsePermissionCommand } from './permission-command.js';
|
|
@@ -29,7 +30,6 @@ const PLATFORM_PRODUCT_BY_NAME = {
|
|
|
29
30
|
};
|
|
30
31
|
const PLUGIN_NAME_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
31
32
|
const DIGEST_PATTERN = /^sha256:[0-9a-f]{64}$/;
|
|
32
|
-
export const DEFAULT_SOURCE_PLUGIN_AW_MIN_VERSION = '0.0.0';
|
|
33
33
|
const STRICT_SEMVER_PATTERN = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|(?:[0-9A-Za-z-]*[A-Za-z-][0-9A-Za-z-]*))(?:\.(?:0|[1-9]\d*|(?:[0-9A-Za-z-]*[A-Za-z-][0-9A-Za-z-]*)))*))?(?:\+([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?$/;
|
|
34
34
|
export const STRICT_SEMVER_VALIDATION_CODE = 'invalidStrictSemVer';
|
|
35
35
|
export class StrictSemVerValidationError extends Error {
|
|
@@ -265,30 +265,26 @@ function assertCatalogChannel(value, fieldName) {
|
|
|
265
265
|
}
|
|
266
266
|
return channel;
|
|
267
267
|
}
|
|
268
|
-
function
|
|
269
|
-
return {
|
|
270
|
-
aw: {
|
|
271
|
-
minVersion,
|
|
272
|
-
},
|
|
273
|
-
};
|
|
274
|
-
}
|
|
275
|
-
function normalizePluginCompatibility(value, fieldName, options) {
|
|
268
|
+
function normalizePluginRequirements(value, fieldName, options) {
|
|
276
269
|
if (value === undefined) {
|
|
277
|
-
if (options.allowMissing)
|
|
278
|
-
return
|
|
279
|
-
}
|
|
280
|
-
throw new Error(`Invalid ${fieldName}.aw.minVersion: expected a strict SemVer 2.0.0 string. Received undefined.`);
|
|
270
|
+
if (options.allowMissing)
|
|
271
|
+
return undefined;
|
|
272
|
+
throw new Error(`Invalid ${fieldName}: expected an object.`);
|
|
281
273
|
}
|
|
282
274
|
const input = assertObject(value, fieldName);
|
|
283
275
|
assertAllowedKeys(input, fieldName, ['aw']);
|
|
284
276
|
const aw = assertObject(input.aw, `${fieldName}.aw`);
|
|
285
|
-
assertAllowedKeys(aw, `${fieldName}.aw`, ['
|
|
286
|
-
|
|
287
|
-
}
|
|
288
|
-
function assertPluginMinVersionWithinCatalogBounds(options) {
|
|
289
|
-
if (compareStrictSemVer(options.pluginMinVersion, options.catalogMinVersion) > 0) {
|
|
290
|
-
throw new Error(`Invalid ${options.fieldName}: plugin "${options.pluginName}" requires aw ${options.pluginMinVersion}, which is higher than catalog minimum ${options.catalogMinVersion}.`);
|
|
277
|
+
assertAllowedKeys(aw, `${fieldName}.aw`, ['capabilities']);
|
|
278
|
+
if (aw.capabilities !== undefined && !Array.isArray(aw.capabilities)) {
|
|
279
|
+
throw new Error(`Invalid ${fieldName}.aw.capabilities: expected an array.`);
|
|
291
280
|
}
|
|
281
|
+
return {
|
|
282
|
+
aw: {
|
|
283
|
+
...(aw.capabilities === undefined
|
|
284
|
+
? {}
|
|
285
|
+
: { capabilities: normalizeAwCapabilities(aw.capabilities, `${fieldName}.aw.capabilities`) }),
|
|
286
|
+
},
|
|
287
|
+
};
|
|
292
288
|
}
|
|
293
289
|
function normalizeMarketplaceProducts(value, fieldName) {
|
|
294
290
|
if (value === undefined) {
|
|
@@ -619,15 +615,20 @@ function normalizeRuntimeExports(pluginRoot, value, fieldName) {
|
|
|
619
615
|
return value.map((entry, index) => {
|
|
620
616
|
const entryField = `${fieldName}[${index}]`;
|
|
621
617
|
const input = assertObject(entry, entryField);
|
|
622
|
-
assertAllowedKeys(input, entryField, ['name', 'source']);
|
|
618
|
+
assertAllowedKeys(input, entryField, ['name', 'source', 'requires']);
|
|
623
619
|
const name = normalizeRuntimeExportName(input.name, `${entryField}.name`);
|
|
624
620
|
if (names.has(name)) {
|
|
625
621
|
throw new Error(`Invalid ${fieldName}: duplicate export name "${name}".`);
|
|
626
622
|
}
|
|
627
623
|
names.add(name);
|
|
624
|
+
const requires = normalizePluginRequirements(input.requires, `${entryField}.requires`, { allowMissing: false });
|
|
625
|
+
if (requires.aw.capabilities === undefined) {
|
|
626
|
+
throw new Error(`Invalid ${entryField}.requires.aw.capabilities: expected an array.`);
|
|
627
|
+
}
|
|
628
628
|
return {
|
|
629
629
|
name,
|
|
630
630
|
source: normalizeCanonicalPluginFilePath(pluginRoot, input.source, `${entryField}.source`),
|
|
631
|
+
requires: { aw: { capabilities: requires.aw.capabilities } },
|
|
631
632
|
};
|
|
632
633
|
});
|
|
633
634
|
}
|
|
@@ -1394,13 +1395,24 @@ function normalizeArtifactRuntimeImports(value, fieldName, reservedImports) {
|
|
|
1394
1395
|
const resolvedInput = assertObject(input.resolved, `${entryField}.resolved`);
|
|
1395
1396
|
assertAllowedKeys(resolvedInput, `${entryField}.resolved`, [
|
|
1396
1397
|
'path', 'digest', 'providerPluginId', 'providerVersion', 'source',
|
|
1398
|
+
'requiredCapabilities', 'capabilitySetDigest',
|
|
1397
1399
|
]);
|
|
1400
|
+
if (!Array.isArray(resolvedInput.requiredCapabilities)) {
|
|
1401
|
+
throw new Error(`Invalid ${entryField}.resolved.requiredCapabilities: expected an array.`);
|
|
1402
|
+
}
|
|
1403
|
+
const requiredCapabilities = normalizeAwCapabilities(resolvedInput.requiredCapabilities, `${entryField}.resolved.requiredCapabilities`);
|
|
1404
|
+
const capabilitySetDigest = ensureDigestString(resolvedInput.capabilitySetDigest, `${entryField}.resolved.capabilitySetDigest`);
|
|
1405
|
+
if (capabilitySetDigest !== computeAwCapabilitySetDigest(requiredCapabilities)) {
|
|
1406
|
+
throw new Error(`Invalid ${entryField}.resolved.capabilitySetDigest: digest does not match requiredCapabilities.`);
|
|
1407
|
+
}
|
|
1398
1408
|
resolved = {
|
|
1399
1409
|
path: normalizePluginChildPath('', ensureString(resolvedInput.path, `${entryField}.resolved.path`), `${entryField}.resolved.path`),
|
|
1400
1410
|
digest: ensureDigestString(resolvedInput.digest, `${entryField}.resolved.digest`),
|
|
1401
1411
|
providerPluginId: ensureString(resolvedInput.providerPluginId, `${entryField}.resolved.providerPluginId`),
|
|
1402
1412
|
providerVersion: assertStrictSemVer(resolvedInput.providerVersion, `${entryField}.resolved.providerVersion`),
|
|
1403
1413
|
source: ensureString(resolvedInput.source, `${entryField}.resolved.source`),
|
|
1414
|
+
requiredCapabilities,
|
|
1415
|
+
capabilitySetDigest,
|
|
1404
1416
|
};
|
|
1405
1417
|
}
|
|
1406
1418
|
return {
|
|
@@ -2006,7 +2018,7 @@ export async function assertActualNativePluginCapability(pluginRoot, manifest, m
|
|
|
2006
2018
|
}
|
|
2007
2019
|
}
|
|
2008
2020
|
if (!skills && !slashCommands && !mcpServers && !apps && !bundled) {
|
|
2009
|
-
throw new Error('Invalid plugin manifest: portable-only plugins are not supported
|
|
2021
|
+
throw new Error('Invalid plugin manifest: portable-only plugins are not supported. Declare at least one non-empty native capability.');
|
|
2010
2022
|
}
|
|
2011
2023
|
}
|
|
2012
2024
|
export function validatePluginManifest(pluginRoot, rawManifest, options = {}) {
|
|
@@ -2020,7 +2032,7 @@ export function validatePluginManifest(pluginRoot, rawManifest, options = {}) {
|
|
|
2020
2032
|
'version',
|
|
2021
2033
|
'description',
|
|
2022
2034
|
'dependencies',
|
|
2023
|
-
'
|
|
2035
|
+
'requires',
|
|
2024
2036
|
'skills',
|
|
2025
2037
|
'slashCommands',
|
|
2026
2038
|
'mcpServers',
|
|
@@ -2039,12 +2051,11 @@ export function validatePluginManifest(pluginRoot, rawManifest, options = {}) {
|
|
|
2039
2051
|
name: ensureString(input.name, 'name'),
|
|
2040
2052
|
version: assertStrictSemVer(input.version, 'plugin manifest.version'),
|
|
2041
2053
|
description: ensureString(input.description, 'description'),
|
|
2042
|
-
compatibility: normalizePluginCompatibility(input.compatibility, 'compatibility', {
|
|
2043
|
-
allowMissing: (options.compatibilityMode ?? 'defaulted') === 'defaulted',
|
|
2044
|
-
defaultMinVersion: options.defaultMinVersion,
|
|
2045
|
-
}),
|
|
2046
2054
|
marketplace: normalizeMarketplaceMeta(input.marketplace, 'marketplace'),
|
|
2047
2055
|
};
|
|
2056
|
+
const requires = normalizePluginRequirements(input.requires, 'requires', { allowMissing: true });
|
|
2057
|
+
if (requires !== undefined)
|
|
2058
|
+
manifest.requires = requires;
|
|
2048
2059
|
if (input.dependencies !== undefined) {
|
|
2049
2060
|
const dependencies = ensureStringArray(input.dependencies, 'dependencies');
|
|
2050
2061
|
if (dependencies.length > 64) {
|
|
@@ -2289,18 +2300,7 @@ async function validateSourceJsonNativeAsset(pluginRoot, manifest, field) {
|
|
|
2289
2300
|
}
|
|
2290
2301
|
export async function validateSourcePluginManifest(pluginRoot, rawManifest, options = {}) {
|
|
2291
2302
|
await assertPluginInputTree(pluginRoot);
|
|
2292
|
-
const distributionsInput = rawManifest !== null
|
|
2293
|
-
&& typeof rawManifest === 'object'
|
|
2294
|
-
&& !Array.isArray(rawManifest)
|
|
2295
|
-
? rawManifest.distributions
|
|
2296
|
-
: undefined;
|
|
2297
|
-
const requiresExplicitMinVersion = distributionsInput !== null
|
|
2298
|
-
&& typeof distributionsInput === 'object'
|
|
2299
|
-
&& !Array.isArray(distributionsInput)
|
|
2300
|
-
&& Object.hasOwn(distributionsInput, 'agentSkills');
|
|
2301
2303
|
const manifest = validatePluginManifest(pluginRoot, rawManifest, {
|
|
2302
|
-
compatibilityMode: requiresExplicitMinVersion ? 'required' : 'defaulted',
|
|
2303
|
-
defaultMinVersion: DEFAULT_SOURCE_PLUGIN_AW_MIN_VERSION,
|
|
2304
2304
|
reservedImports: options.reservedImports,
|
|
2305
2305
|
});
|
|
2306
2306
|
const parsedVersion = parseStrictSemVer(manifest.version, 'plugin manifest.version');
|
|
@@ -2337,10 +2337,7 @@ export async function readPluginManifest(pluginRoot, options = {}) {
|
|
|
2337
2337
|
? await validateSourcePluginManifest(pluginRoot, rawManifest, {
|
|
2338
2338
|
reservedImports: options.reservedImports,
|
|
2339
2339
|
})
|
|
2340
|
-
: validatePluginManifest(pluginRoot, rawManifest, {
|
|
2341
|
-
compatibilityMode: 'required',
|
|
2342
|
-
reservedImports: options.reservedImports,
|
|
2343
|
-
});
|
|
2340
|
+
: validatePluginManifest(pluginRoot, rawManifest, { reservedImports: options.reservedImports });
|
|
2344
2341
|
if (mode === 'bundle')
|
|
2345
2342
|
await assertActualNativePluginCapability(pluginRoot, manifest, 'bundle');
|
|
2346
2343
|
return {
|
|
@@ -2438,9 +2435,6 @@ function assertCatalogChannelVersionContract(options) {
|
|
|
2438
2435
|
}
|
|
2439
2436
|
function normalizeCatalogManifestEntry(value, fieldName) {
|
|
2440
2437
|
const input = assertObject(value, fieldName);
|
|
2441
|
-
if (Object.hasOwn(input, 'dependencies')) {
|
|
2442
|
-
throw new Error(`Invalid ${fieldName}: "dependencies" is unsupported.`);
|
|
2443
|
-
}
|
|
2444
2438
|
assertAllowedKeys(input, fieldName, [
|
|
2445
2439
|
'name',
|
|
2446
2440
|
'version',
|
|
@@ -2450,7 +2444,8 @@ function normalizeCatalogManifestEntry(value, fieldName) {
|
|
|
2450
2444
|
'tags',
|
|
2451
2445
|
'strict',
|
|
2452
2446
|
'policy',
|
|
2453
|
-
'
|
|
2447
|
+
'dependencies',
|
|
2448
|
+
'requires',
|
|
2454
2449
|
'source',
|
|
2455
2450
|
'artifactDigest',
|
|
2456
2451
|
'manifestDigest',
|
|
@@ -2462,7 +2457,11 @@ function normalizeCatalogManifestEntry(value, fieldName) {
|
|
|
2462
2457
|
category: ensureString(input.category, `${fieldName}.category`),
|
|
2463
2458
|
strict: ensureBoolean(input.strict, `${fieldName}.strict`),
|
|
2464
2459
|
policy: normalizeMarketplacePolicy(input.policy, `${fieldName}.policy`),
|
|
2465
|
-
|
|
2460
|
+
dependencies: input.dependencies === undefined
|
|
2461
|
+
? []
|
|
2462
|
+
: normalizeComparableStringArray(ensureStringArray(input.dependencies, `${fieldName}.dependencies`))
|
|
2463
|
+
.map((dependency, index) => ensurePluginName(dependency, `${fieldName}.dependencies[${index}]`)),
|
|
2464
|
+
requires: normalizePluginRequirements(input.requires, `${fieldName}.requires`, {
|
|
2466
2465
|
allowMissing: false,
|
|
2467
2466
|
}),
|
|
2468
2467
|
source: normalizeCatalogRelativePath(input.source, `${fieldName}.source`),
|
|
@@ -2486,8 +2485,8 @@ export function normalizeCatalogManifestBase(input, fieldName) {
|
|
|
2486
2485
|
fieldName: `${fieldName}.catalogVersion`,
|
|
2487
2486
|
kind: 'catalog',
|
|
2488
2487
|
});
|
|
2489
|
-
const
|
|
2490
|
-
return { catalogVersion, channel,
|
|
2488
|
+
const requires = normalizePluginRequirements(input.requires, `${fieldName}.requires`, { allowMissing: false });
|
|
2489
|
+
return { catalogVersion, channel, requires };
|
|
2491
2490
|
}
|
|
2492
2491
|
export function normalizeCatalogManifestEntries(rawEntries, base, fieldName) {
|
|
2493
2492
|
if (!Array.isArray(rawEntries)) {
|
|
@@ -2508,16 +2507,10 @@ export function normalizeCatalogManifestEntries(rawEntries, base, fieldName) {
|
|
|
2508
2507
|
kind: 'plugin',
|
|
2509
2508
|
});
|
|
2510
2509
|
}
|
|
2511
|
-
assertPluginMinVersionWithinCatalogBounds({
|
|
2512
|
-
pluginName: entry.name,
|
|
2513
|
-
pluginMinVersion: entry.compatibility.aw.minVersion,
|
|
2514
|
-
catalogMinVersion: base.compatibility.aw.minVersion,
|
|
2515
|
-
fieldName: `${fieldName}.entries.${entry.name}.compatibility.aw.minVersion`,
|
|
2516
|
-
});
|
|
2517
2510
|
}
|
|
2518
2511
|
return entries;
|
|
2519
2512
|
}
|
|
2520
|
-
export function createBundleSourceManifest(plugin) {
|
|
2513
|
+
export function createBundleSourceManifest(plugin, requiredCapabilities) {
|
|
2521
2514
|
const scripts = plugin.manifest.scripts
|
|
2522
2515
|
? structuredClone(plugin.manifest.scripts)
|
|
2523
2516
|
: undefined;
|
|
@@ -2543,9 +2536,12 @@ export function createBundleSourceManifest(plugin) {
|
|
|
2543
2536
|
return {
|
|
2544
2537
|
...plugin.manifest,
|
|
2545
2538
|
buildConfig,
|
|
2546
|
-
|
|
2547
|
-
? structuredClone(plugin.manifest.
|
|
2548
|
-
:
|
|
2539
|
+
distributions: plugin.manifest.distributions
|
|
2540
|
+
? structuredClone(plugin.manifest.distributions)
|
|
2541
|
+
: undefined,
|
|
2542
|
+
requires: requiredCapabilities === undefined
|
|
2543
|
+
? structuredClone(plugin.manifest.requires)
|
|
2544
|
+
: { aw: { capabilities: normalizeAwCapabilities(requiredCapabilities) } },
|
|
2549
2545
|
extensions: plugin.manifest.extensions
|
|
2550
2546
|
? {
|
|
2551
2547
|
instructions: plugin.manifest.extensions.instructions
|
|
@@ -2580,11 +2576,6 @@ export function createPlatformManifestBase(plugin) {
|
|
|
2580
2576
|
name: plugin.manifest.name,
|
|
2581
2577
|
version: plugin.manifest.version,
|
|
2582
2578
|
description: plugin.manifest.description,
|
|
2583
|
-
compatibility: structuredClone(plugin.manifest.compatibility ?? {
|
|
2584
|
-
aw: {
|
|
2585
|
-
minVersion: '0.0.0',
|
|
2586
|
-
},
|
|
2587
|
-
}),
|
|
2588
2579
|
interface: plugin.manifest.interface,
|
|
2589
2580
|
};
|
|
2590
2581
|
}
|