fix(marketplace): close client contract gaps
This commit is contained in:
@@ -782,8 +782,8 @@ function parseV2Tool(
|
||||
if (permissions.some((permission) => !hostedPermissionMatchesPlugin(permission, pluginId))) {
|
||||
fail(filePath, `tools[${index}].permissions`, 'permission is outside the plugin hosted namespace');
|
||||
}
|
||||
if (tool.executionMode !== 'synchronous' && tool.executionMode !== 'accepted') {
|
||||
fail(filePath, `tools[${index}].executionMode`, 'must be synchronous or accepted');
|
||||
if (tool.executionMode !== 'synchronous' && tool.executionMode !== 'job') {
|
||||
fail(filePath, `tools[${index}].executionMode`, 'must be synchronous or job');
|
||||
}
|
||||
validateV2SchemaNode(tool.inputSchema, filePath, `tools[${index}].inputSchema`);
|
||||
validateV2SchemaNode(tool.outputSchema, filePath, `tools[${index}].outputSchema`);
|
||||
|
||||
@@ -1040,43 +1040,50 @@ export class PluginPackageStore {
|
||||
const selected = currentSelection.current[validated]
|
||||
? records.find((record) => record.releaseId === currentSelection.current[validated])
|
||||
: undefined;
|
||||
if (!selected) {
|
||||
return {
|
||||
status: 'kept',
|
||||
pluginId: validated,
|
||||
reason: 'current_selection_missing',
|
||||
};
|
||||
}
|
||||
const protectedIds = new Set([
|
||||
...this.accountCache.referencedReleaseIds(),
|
||||
...(this.activeWorkerReleaseIds() ?? []),
|
||||
...this.activeWorkers,
|
||||
]);
|
||||
const removable = mode === 'explicit'
|
||||
? records.filter((record) => !protectedIds.has(record.releaseId))
|
||||
: records.length === 1 && !protectedIds.has(selected.releaseId)
|
||||
let removable: InstalledReleaseRecord[];
|
||||
if (mode === 'explicit') {
|
||||
removable = records.filter((record) => !protectedIds.has(record.releaseId));
|
||||
} else {
|
||||
if (!selected) {
|
||||
return {
|
||||
status: 'kept',
|
||||
pluginId: validated,
|
||||
reason: 'current_selection_missing',
|
||||
};
|
||||
}
|
||||
removable = records.length === 1 && !protectedIds.has(selected.releaseId)
|
||||
? records
|
||||
: records.filter((record) => (
|
||||
record.releaseId !== selected.releaseId && !protectedIds.has(record.releaseId)
|
||||
));
|
||||
if (removable.length === 0) {
|
||||
return {
|
||||
status: 'kept',
|
||||
pluginId: validated,
|
||||
releaseId: selected.releaseId,
|
||||
version: selected.version,
|
||||
...(selected.channel === undefined ? {} : { channel: selected.channel }),
|
||||
};
|
||||
if (removable.length === 0) {
|
||||
return {
|
||||
status: 'kept',
|
||||
pluginId: validated,
|
||||
releaseId: selected.releaseId,
|
||||
version: selected.version,
|
||||
...(selected.channel === undefined ? {} : { channel: selected.channel }),
|
||||
};
|
||||
}
|
||||
}
|
||||
const remaining = index.releases.filter((record) => !removable.includes(record));
|
||||
if (binding) this.assertBinding(binding);
|
||||
try {
|
||||
await this.writeIndex(this.indexPath, serializeIndex({ schema_version: INDEX_SCHEMA_VERSION, releases: remaining }));
|
||||
} catch {
|
||||
throw new PluginPackageStoreError('plugin_install_failed', 'package index cleanup failed');
|
||||
if (removable.length > 0) {
|
||||
try {
|
||||
await this.writeIndex(this.indexPath, serializeIndex({ schema_version: INDEX_SCHEMA_VERSION, releases: remaining }));
|
||||
} catch {
|
||||
throw new PluginPackageStoreError('plugin_install_failed', 'package index cleanup failed');
|
||||
}
|
||||
}
|
||||
const nextCurrent = { ...currentSelection.current };
|
||||
if (nextCurrent[validated] && !remaining.some((record) => (
|
||||
if (mode === 'explicit') {
|
||||
delete nextCurrent[validated];
|
||||
} else if (nextCurrent[validated] && !remaining.some((record) => (
|
||||
record.pluginId === validated && record.releaseId === nextCurrent[validated]
|
||||
))) delete nextCurrent[validated];
|
||||
await this.writeCurrentSelection({
|
||||
|
||||
Reference in New Issue
Block a user