fix(plugins): load official hosted plugins from bundled resources

This commit is contained in:
2026-09-01 18:20:24 +08:00
parent 52e2a97a12
commit 1530ac7740
23 changed files with 835 additions and 48 deletions

View File

@@ -10,10 +10,14 @@ import {
BUNDLED_CODING_PLUGIN_PREVIEW_SURFACES,
BUNDLED_CODING_PLUGIN_SETTINGS_SURFACES,
CODE_OWNED_PLUGIN_PERMISSION_IDS,
GAME_RESOURCE_BUNDLED_RELEASE_ID,
GAME_RESOURCE_PLUGIN_ID,
DATA_SERVICE_CAPABILITY_IDS,
DATA_SERVICE_OPERATION_DEFINITIONS,
DATA_SERVICE_PLUGIN_ID,
DATA_SERVICE_TOOL_NAMES,
WEB_SEARCH_BUNDLED_RELEASE_ID,
WEB_SEARCH_PLUGIN_ID,
type AgentPluginsRootManifest,
type CodingPluginDefinition,
type CodingPluginAcquisitionMode,
@@ -26,14 +30,40 @@ import {
} from '../../shared/coding-plugins';
/**
* P0 deliberately has one statically enumerated package root. Keeping this
* list relative makes it impossible for an environment variable or a project
* The trusted code-owned catalog is statically enumerated. Keeping these
* roots relative makes it impossible for an environment variable or project
* file to add a package to the trusted catalog.
*/
export const BUNDLED_CODING_PLUGIN_ROOTS = Object.freeze([
'data-service',
'game-resource',
'web-search',
] as const);
const BUNDLED_CODING_PLUGIN_METADATA = Object.freeze({
'data-service': Object.freeze({
pluginId: DATA_SERVICE_PLUGIN_ID,
runtimeKind: 'bundled_typed' as const,
acquisitionMode: 'system_included' as const,
releaseId: null,
bundledV2: false,
}),
'game-resource': Object.freeze({
pluginId: GAME_RESOURCE_PLUGIN_ID,
runtimeKind: 'platform_hosted' as const,
acquisitionMode: 'user_acquired' as const,
releaseId: GAME_RESOURCE_BUNDLED_RELEASE_ID,
bundledV2: true,
}),
'web-search': Object.freeze({
pluginId: WEB_SEARCH_PLUGIN_ID,
runtimeKind: 'platform_hosted' as const,
acquisitionMode: 'user_acquired' as const,
releaseId: WEB_SEARCH_BUNDLED_RELEASE_ID,
bundledV2: true,
}),
});
const CAPABILITY_MANIFEST_RELATIVE_PATH = 'com.makelore/capability.json';
const PACKAGE_MANIFEST_FILE = 'plugin.json';
const SKILL_ID_PATTERN = /^[a-z][a-z0-9._-]{0,63}$/u;
@@ -160,11 +190,13 @@ export interface CodingPluginManifestParseOptions {
acquisitionMode?: CodingPluginAcquisitionMode;
releaseId?: string | null;
provenance?: CodingPluginPackageProvenance;
/** Only the fixed code-owned package catalog may opt schema 2 into bundled delivery. */
bundledV2?: boolean;
}
export type CodingPluginLoadOptions = Pick<
CodingPluginManifestParseOptions,
'runtimeKind' | 'acquisitionMode' | 'releaseId' | 'provenance'
'runtimeKind' | 'acquisitionMode' | 'releaseId' | 'provenance' | 'bundledV2'
>;
type UnknownRecord = Record<string, unknown>;
@@ -696,9 +728,16 @@ function trustedMetadata(
if (schemaVersion === 1 && releaseId !== null) {
fail(filePath, 'trusted metadata.releaseId', 'bundled schema-1 definitions cannot carry a Release ID');
}
const bundledV2 = schemaVersion === 2 && options.bundledV2 === true;
if (options.bundledV2 && !bundledV2) {
fail(filePath, 'trusted metadata.bundledV2', 'is valid only for schema 2 packages');
}
if (bundledV2 && (runtimeKind !== 'platform_hosted' || releaseId === null)) {
fail(filePath, 'trusted metadata.bundledV2', 'requires a hosted runtime and fixed Release ID');
}
const defaultProvenance: CodingPluginPackageProvenance = {
source: schemaVersion === 1 ? 'bundled' : 'marketplace',
packageRoot: schemaVersion === 1 ? path.basename(packageRoot) : path.resolve(packageRoot),
source: schemaVersion === 1 || bundledV2 ? 'bundled' : 'marketplace',
packageRoot: schemaVersion === 1 || bundledV2 ? path.basename(packageRoot) : path.resolve(packageRoot),
};
const provenance = options.provenance ?? defaultProvenance;
if (provenance.source !== defaultProvenance.source
@@ -1154,13 +1193,15 @@ export async function loadBundledCodingPluginDefinitions(
const roots = resolveBundledCodingPluginRootPaths(resourcesRoot);
const definitions = await Promise.all(roots.map(async (root, index) => {
const expectedRoot = BUNDLED_CODING_PLUGIN_ROOTS[index];
const metadata = BUNDLED_CODING_PLUGIN_METADATA[expectedRoot];
const definition = await loadCodingPluginDefinition(root, {
runtimeKind: 'bundled_typed',
acquisitionMode: 'system_included',
releaseId: null,
runtimeKind: metadata.runtimeKind,
acquisitionMode: metadata.acquisitionMode,
releaseId: metadata.releaseId,
provenance: { source: 'bundled', packageRoot: expectedRoot },
bundledV2: metadata.bundledV2,
});
if (definition.id !== `makelore.${expectedRoot}`) {
if (definition.id !== metadata.pluginId) {
throw new CodingPluginManifestError(
path.join(root, PACKAGE_MANIFEST_FILE),
'name',
@@ -1179,13 +1220,15 @@ export function loadBundledCodingPluginDefinitionsSync(
const roots = resolveBundledCodingPluginRootPaths(resourcesRoot);
const definitions = roots.map((root, index) => {
const expectedRoot = BUNDLED_CODING_PLUGIN_ROOTS[index];
const metadata = BUNDLED_CODING_PLUGIN_METADATA[expectedRoot];
const definition = loadCodingPluginDefinitionSync(root, {
runtimeKind: 'bundled_typed',
acquisitionMode: 'system_included',
releaseId: null,
runtimeKind: metadata.runtimeKind,
acquisitionMode: metadata.acquisitionMode,
releaseId: metadata.releaseId,
provenance: { source: 'bundled', packageRoot: expectedRoot },
bundledV2: metadata.bundledV2,
});
if (definition.id !== `makelore.${expectedRoot}`) {
if (definition.id !== metadata.pluginId) {
throw new CodingPluginManifestError(
path.join(root, PACKAGE_MANIFEST_FILE),
'name',