feat: integrate marketplace plugins with coding runtime

This commit is contained in:
2026-08-28 18:02:51 +08:00
parent 1d64b89499
commit 05917a789a
21 changed files with 1921 additions and 29 deletions

View File

@@ -5,6 +5,7 @@ import { validateSessionKey } from '../../coding-projects/conversation-store';
import { resolveBundledCodingPluginRootPaths } from '../../coding-plugins/manifest';
import type { PiProviderSelection } from './provider-config';
import type { PiManagedInputRevision } from './managed-input-revision';
import type { EffectivePluginSnapshot } from '../../coding-plugins/effective-resolver';
const MANAGED_SEGMENT_PATTERN = /^[A-Za-z0-9][A-Za-z0-9_-]{0,127}$/;
@@ -38,6 +39,10 @@ export interface MaterializePiAgentResourcesOptions {
skillEntries: readonly PiSkillEntry[];
catalogRevision: number;
bundledSkillsDir: string;
/** Main-owned installed package roots for effective Marketplace Skills. */
skillRoots?: readonly string[];
/** The exact resolver output for this worker generation. */
effectiveSnapshot?: EffectivePluginSnapshot;
revision: PiManagedInputRevision;
}
@@ -50,6 +55,7 @@ export interface PiAgentResourceManifest {
skillEntries: PiSkillEntry[];
catalogRevision: number;
revision: PiManagedInputRevision;
effectivePluginSnapshot?: EffectivePluginSnapshot;
}
export interface PiAgentResourceSnapshot {
@@ -62,6 +68,7 @@ export interface PiAgentResourceSnapshot {
skillPaths: string[];
catalogRevision: number;
revision: PiManagedInputRevision;
effectivePluginSnapshot?: EffectivePluginSnapshot;
summary: {
projectId: string;
agentId: string;
@@ -69,6 +76,7 @@ export interface PiAgentResourceSnapshot {
skillEntries: PiSkillEntry[];
catalogRevision: number;
revision: PiManagedInputRevision;
effectivePluginSnapshot?: EffectivePluginSnapshot;
};
}
@@ -184,6 +192,7 @@ function pathWithin(root: string, entryPath: string): string | null {
async function resolveSkillEntryPath(
bundledSkillsDir: string,
entry: PiSkillEntry,
skillRoots: readonly string[] = [],
): Promise<string> {
const roots = [
path.resolve(bundledSkillsDir),
@@ -191,6 +200,7 @@ async function resolveSkillEntryPath(
path.dirname(path.resolve(bundledSkillsDir)),
'coding-plugins',
)),
...skillRoots.map((root) => path.resolve(root)),
];
for (const root of roots) {
const candidate = pathWithin(root, entry.entryPath);
@@ -208,10 +218,11 @@ async function resolveSkillEntryPath(
export async function resolveExplicitCodingSkillPaths(
bundledSkillsDir: string,
skillEntries: readonly PiSkillEntry[],
skillRoots: readonly string[] = [],
): Promise<{ skillIds: string[]; skillEntries: PiSkillEntry[]; skillPaths: string[] }> {
const normalizedEntries = normalizeSkillEntries(skillEntries);
const skillPaths = await Promise.all(normalizedEntries.map((entry) => (
resolveSkillEntryPath(bundledSkillsDir, entry)
resolveSkillEntryPath(bundledSkillsDir, entry, skillRoots)
)));
return {
skillIds: normalizedEntries.map(({ id }) => id),
@@ -235,6 +246,7 @@ export async function materializePiAgentResources(
const { skillIds, skillEntries, skillPaths } = await resolveExplicitCodingSkillPaths(
options.bundledSkillsDir,
options.skillEntries,
options.skillRoots,
);
const resolvedCatalogRevision = catalogRevision(options.catalogRevision);
const promptPath = path.join(projectPromptsDir, `${agentId}.md`);
@@ -248,6 +260,7 @@ export async function materializePiAgentResources(
skillEntries: structuredClone(skillEntries),
catalogRevision: resolvedCatalogRevision,
revision: { ...options.revision },
...(options.effectiveSnapshot ? { effectivePluginSnapshot: structuredClone(options.effectiveSnapshot) } : {}),
};
await atomicWriteText(promptPath, options.prompt);
await atomicWriteJson(manifestPath, manifest);
@@ -261,6 +274,7 @@ export async function materializePiAgentResources(
skillPaths,
catalogRevision: resolvedCatalogRevision,
revision: { ...options.revision },
...(options.effectiveSnapshot ? { effectivePluginSnapshot: structuredClone(options.effectiveSnapshot) } : {}),
summary: {
projectId,
agentId,
@@ -268,6 +282,7 @@ export async function materializePiAgentResources(
skillEntries: structuredClone(skillEntries),
catalogRevision: resolvedCatalogRevision,
revision: { ...options.revision },
...(options.effectiveSnapshot ? { effectivePluginSnapshot: structuredClone(options.effectiveSnapshot) } : {}),
},
};
}