@agimon-ai/po-domain 0.0.0-alpha.0
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/LICENSE +21 -0
- package/README.md +71 -0
- package/dist/apiContracts.cjs +17 -0
- package/dist/apiContracts.cjs.map +1 -0
- package/dist/apiContracts.d.mts +53 -0
- package/dist/apiContracts.d.mts.map +1 -0
- package/dist/apiContracts.mjs +13 -0
- package/dist/apiContracts.mjs.map +1 -0
- package/dist/apply.cjs +76 -0
- package/dist/apply.cjs.map +1 -0
- package/dist/apply.d.mts +23 -0
- package/dist/apply.d.mts.map +1 -0
- package/dist/apply.mjs +72 -0
- package/dist/apply.mjs.map +1 -0
- package/dist/domainText-Dm8k7p4z.mjs +97 -0
- package/dist/domainText-Dm8k7p4z.mjs.map +1 -0
- package/dist/domainText-UIRIz6-_.cjs +204 -0
- package/dist/domainText-UIRIz6-_.cjs.map +1 -0
- package/dist/extensions/mcp.cjs +26 -0
- package/dist/extensions/mcp.cjs.map +1 -0
- package/dist/extensions/mcp.d.mts +5 -0
- package/dist/extensions/mcp.d.mts.map +1 -0
- package/dist/extensions/mcp.mjs +21 -0
- package/dist/extensions/mcp.mjs.map +1 -0
- package/dist/extensions/server.cjs +229 -0
- package/dist/extensions/server.cjs.map +1 -0
- package/dist/extensions/server.d.mts +5 -0
- package/dist/extensions/server.d.mts.map +1 -0
- package/dist/extensions/server.mjs +221 -0
- package/dist/extensions/server.mjs.map +1 -0
- package/dist/extensions/web.mjs +26 -0
- package/dist/extensions/web.mjs.map +1 -0
- package/dist/index.cjs +19 -0
- package/dist/index.d.mts +84 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +3 -0
- package/dist/mcp.cjs +32 -0
- package/dist/mcp.cjs.map +1 -0
- package/dist/mcp.d.mts +52 -0
- package/dist/mcp.d.mts.map +1 -0
- package/dist/mcp.mjs +19 -0
- package/dist/mcp.mjs.map +1 -0
- package/dist/mcpFilter-CZNmU_VF.cjs +189 -0
- package/dist/mcpFilter-CZNmU_VF.cjs.map +1 -0
- package/dist/mcpFilter-Cf-czy8O.mjs +151 -0
- package/dist/mcpFilter-Cf-czy8O.mjs.map +1 -0
- package/dist/pluginMaterializer-C8IZ1PSY.cjs +267 -0
- package/dist/pluginMaterializer-C8IZ1PSY.cjs.map +1 -0
- package/dist/pluginMaterializer-D9-oDF-b.mjs +259 -0
- package/dist/pluginMaterializer-D9-oDF-b.mjs.map +1 -0
- package/dist/plugins.cjs +3 -0
- package/dist/plugins.d.mts +14 -0
- package/dist/plugins.d.mts.map +1 -0
- package/dist/plugins.mjs +2 -0
- package/dist/resourceCollector-CRY5cmeY.mjs +773 -0
- package/dist/resourceCollector-CRY5cmeY.mjs.map +1 -0
- package/dist/resourceCollector-Cu-lp5hJ.cjs +837 -0
- package/dist/resourceCollector-Cu-lp5hJ.cjs.map +1 -0
- package/dist/resources-BEjxE3Zn.d.mts +66 -0
- package/dist/resources-BEjxE3Zn.d.mts.map +1 -0
- package/dist/resources.cjs +12 -0
- package/dist/resources.d.mts +43 -0
- package/dist/resources.d.mts.map +1 -0
- package/dist/resources.mjs +2 -0
- package/dist/rolldown-runtime-VH7oDXx4.cjs +28 -0
- package/dist/toolNames-Ckp5VLMD.mjs +43 -0
- package/dist/toolNames-Ckp5VLMD.mjs.map +1 -0
- package/dist/toolNames-Cuu-u8r1.cjs +48 -0
- package/dist/toolNames-Cuu-u8r1.cjs.map +1 -0
- package/llms.txt +12 -0
- package/package.json +158 -0
- package/src/prompts/po-author-domain/SKILL.md +18 -0
- package/src/prompts/po-author-domain/references/domains-contract.md +165 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pluginMaterializer-C8IZ1PSY.cjs","names":["spawn","path","fs","poHomeDirectory","isRemotePluginSource","findPluginManifestPath"],"sources":["../src/services/pluginMaterializer/index.ts"],"sourcesContent":["import { spawn } from 'node:child_process';\nimport fs from 'node:fs';\nimport path from 'node:path';\n\nimport {\n findPluginManifestPath,\n type GitPluginSource,\n isRemotePluginSource,\n type NpmPluginSource,\n type PluginEntry,\n type PluginManifestMetadata,\n type PluginSkillDiscovery,\n} from '@agimon-ai/po-config/domains';\nimport { poHomeDirectory } from '@agimon-ai/po-core/piSettings';\n\nconst AGENT_PLUGIN_SCHEMA = 'https://agent-plugins.org/schemas/1.0.0/plugin.schema.json';\nconst INSTALL_MARKER = '.po-plugin.json';\nconst INSTALL_MARKER_VERSION = 1;\nconst OUTPUT_LIMIT = 64 * 1024;\n/** The staging project that declares the one npm plugin being installed. */\nconst STAGING_PACKAGE_NAME = 'po-plugin-staging';\nconst LATEST_TAG = 'latest';\n\ninterface CommandOptions {\n cwd?: string;\n environment?: NodeJS.ProcessEnv;\n}\n\ninterface InstallMarker {\n version: number;\n source: GitPluginSource | NpmPluginSource;\n}\n\ninterface InspectedPluginManifest {\n skillDiscovery: PluginSkillDiscovery;\n manifest: PluginManifestMetadata;\n}\n\nexport interface PluginSourceMaterializers {\n git: (source: GitPluginSource, workspace: string) => Promise<string>;\n npm: (source: NpmPluginSource, workspace: string) => Promise<string>;\n}\n\nexport interface PluginMaterializerOptions {\n materializers?: Partial<PluginSourceMaterializers>;\n}\n\nfunction appendOutput(current: string, chunk: Buffer): string {\n const next = current + chunk.toString('utf8');\n return next.length <= OUTPUT_LIMIT ? next : next.slice(-OUTPUT_LIMIT);\n}\n\nfunction runCommand(command: string, args: string[], options: CommandOptions = {}): Promise<string> {\n return new Promise((resolve, reject) => {\n const child = spawn(command, args, {\n cwd: options.cwd,\n env: options.environment ?? process.env,\n stdio: ['ignore', 'pipe', 'pipe'],\n });\n let stdout = '';\n let stderr = '';\n child.stdout.on('data', (chunk: Buffer) => {\n stdout = appendOutput(stdout, chunk);\n });\n child.stderr.on('data', (chunk: Buffer) => {\n stderr = appendOutput(stderr, chunk);\n });\n child.once('error', (error) => {\n reject(new Error(`Failed to run ${command}: ${error.message}`, { cause: error }));\n });\n child.once('close', (code, signal) => {\n if (code === 0) {\n resolve(stdout.trim());\n return;\n }\n const outcome = signal ? `signal ${signal}` : `exit code ${code ?? 'unknown'}`;\n const details = stderr.trim() || stdout.trim();\n reject(new Error(`${command} ${args.join(' ')} failed with ${outcome}${details ? `\\n${details}` : ''}`));\n });\n });\n}\n\nfunction assertContained(root: string, candidate: string, label: string): void {\n const relative = path.relative(root, candidate);\n if (relative === '' || (!relative.startsWith('..') && !path.isAbsolute(relative))) return;\n throw new Error(`${label} resolves outside ${root}`);\n}\n\nasync function materializeGitSource(source: GitPluginSource, workspace: string): Promise<string> {\n const checkout = path.join(workspace, 'checkout');\n const pluginRoot = source.path ? path.resolve(checkout, source.path) : checkout;\n if (source.path) assertContained(checkout, pluginRoot, 'Git plugin path');\n const cloneArgs = ['clone', '--filter=blob:none'];\n if (source.path) cloneArgs.push('--sparse', '--no-checkout');\n cloneArgs.push(source.url, checkout);\n const environment = { ...process.env, GIT_TERMINAL_PROMPT: '0' };\n await runCommand('git', cloneArgs, { environment });\n\n if (source.path) {\n await runCommand('git', ['sparse-checkout', 'set', '--no-cone', '--', source.path], {\n cwd: checkout,\n environment,\n });\n }\n if (source.sha) {\n await runCommand('git', ['checkout', source.sha], { cwd: checkout, environment });\n const checkedOutSha = await runCommand('git', ['rev-parse', 'HEAD'], { cwd: checkout, environment });\n if (checkedOutSha.toLowerCase() !== source.sha.toLowerCase()) {\n throw new Error(`Checked out Git SHA ${checkedOutSha} does not match requested SHA ${source.sha}`);\n }\n } else if (source.ref) {\n await runCommand('git', ['checkout', source.ref], { cwd: checkout, environment });\n } else if (source.path) {\n await runCommand('git', ['checkout'], { cwd: checkout, environment });\n }\n\n return pluginRoot;\n}\n\n/**\n * Installs an npm plugin into the staging workspace with upm: a one-dependency\n * project, never a spawned package manager. upm runs no lifecycle scripts, and\n * its store is Po's shared `<po home>/store`.\n */\nasync function materializeNpmSource(source: NpmPluginSource, workspace: string): Promise<string> {\n const prefix = path.join(workspace, 'npm');\n await fs.promises.mkdir(prefix, { recursive: true });\n await fs.promises.writeFile(\n path.join(prefix, 'package.json'),\n `${JSON.stringify(\n { name: STAGING_PACKAGE_NAME, private: true, dependencies: { [source.package]: source.version ?? LATEST_TAG } },\n null,\n 2,\n )}\\n`,\n );\n // Loaded on demand so upm stays off the path of every plugin that is already cached.\n const { installRuntimePackages } = await import('@agimon-ai/po-core/runtimePackages');\n await installRuntimePackages({\n dir: prefix,\n poHome: poHomeDirectory(),\n ...(source.registry ? { registry: source.registry } : {}),\n });\n const pluginRoot = path.resolve(prefix, 'node_modules', ...source.package.split('/'));\n assertContained(path.join(prefix, 'node_modules'), pluginRoot, 'npm plugin package');\n // upm links each package into node_modules; the copy reads the linked directory.\n return fs.promises.realpath(pluginRoot);\n}\n\nconst DEFAULT_MATERIALIZERS: PluginSourceMaterializers = {\n git: materializeGitSource,\n npm: materializeNpmSource,\n};\n\nasync function pathType(target: string): Promise<'directory' | 'missing' | 'other'> {\n try {\n const stat = await fs.promises.lstat(target);\n return stat.isDirectory() ? 'directory' : 'other';\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return 'missing';\n throw error;\n }\n}\n\nfunction optionalManifestString(manifest: Record<string, unknown>, key: string): string | undefined {\n const value = manifest[key];\n return typeof value === 'string' && value.trim() ? value.trim() : undefined;\n}\n\nfunction validatePluginManifest(pluginRoot: string, manifestPath: string): InspectedPluginManifest {\n try {\n const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8')) as unknown;\n if (typeof manifest !== 'object' || manifest === null || Array.isArray(manifest)) {\n throw new Error('manifest must contain a JSON object');\n }\n const record = manifest as Record<string, unknown>;\n const agentPluginSchema =\n manifestPath === path.join(pluginRoot, 'plugin.json') && record.$schema === AGENT_PLUGIN_SCHEMA\n ? AGENT_PLUGIN_SCHEMA\n : undefined;\n const name = optionalManifestString(record, 'name');\n const version = optionalManifestString(record, 'version');\n const description = optionalManifestString(record, 'description');\n return {\n skillDiscovery: agentPluginSchema ? 'direct-children' : 'recursive',\n manifest: {\n path: manifestPath,\n ...(name ? { name } : {}),\n ...(version ? { version } : {}),\n ...(description ? { description } : {}),\n ...(agentPluginSchema ? { agentPluginSchema } : {}),\n },\n };\n } catch (error) {\n throw new Error(\n `Invalid plugin manifest ${manifestPath}: ${error instanceof Error ? error.message : String(error)}`,\n {\n cause: error,\n },\n );\n }\n}\n\nasync function inspectInstallation(entry: PluginEntry): Promise<InspectedPluginManifest | false> {\n const type = await pathType(entry.directory);\n if (type === 'missing') return false;\n if (type !== 'directory') throw new Error(`Remote plugin cache path is not a directory: ${entry.directory}`);\n if (!entry.source || !isRemotePluginSource(entry.source)) {\n throw new Error(`Remote plugin entry is missing its source: ${entry.name ?? entry.directory}`);\n }\n\n let marker: InstallMarker;\n try {\n marker = JSON.parse(\n await fs.promises.readFile(path.join(entry.directory, INSTALL_MARKER), 'utf8'),\n ) as InstallMarker;\n } catch (error) {\n throw new Error(`Remote plugin cache is not managed by Po: ${entry.directory}`, { cause: error });\n }\n if (marker.version !== INSTALL_MARKER_VERSION || JSON.stringify(marker.source) !== JSON.stringify(entry.source)) {\n throw new Error(`Remote plugin cache metadata does not match ${entry.name ?? entry.directory}: ${entry.directory}`);\n }\n const manifestPath = findPluginManifestPath(entry.directory);\n if (!manifestPath) {\n throw new Error(`Remote plugin cache is missing a supported plugin manifest: ${entry.directory}`);\n }\n return validatePluginManifest(entry.directory, manifestPath);\n}\n\nasync function copyPluginSource(sourceRoot: string, destination: string): Promise<void> {\n if ((await pathType(sourceRoot)) !== 'directory') {\n throw new Error(`Materialized plugin source is not a directory: ${sourceRoot}`);\n }\n await fs.promises.cp(sourceRoot, destination, {\n recursive: true,\n filter: (candidate) => path.basename(candidate) !== '.git',\n });\n}\n\nfunction isRenameRace(error: unknown): boolean {\n const code = (error as NodeJS.ErrnoException).code;\n return code === 'EEXIST' || code === 'ENOTEMPTY';\n}\n\nasync function installRemotePlugin(entry: PluginEntry, materializers: PluginSourceMaterializers): Promise<PluginEntry> {\n if (!entry.source || !isRemotePluginSource(entry.source)) return entry;\n const existingManifest = await inspectInstallation(entry);\n if (existingManifest) return { ...entry, ...existingManifest };\n\n const parent = path.dirname(entry.directory);\n await fs.promises.mkdir(parent, { recursive: true, mode: 0o700 });\n if ((await pathType(parent)) !== 'directory') {\n throw new Error(`Remote plugin cache root is not a directory: ${parent}`);\n }\n await fs.promises.chmod(parent, 0o700);\n const workspace = await fs.promises.mkdtemp(path.join(parent, '.plugin-staging-'));\n const installation = path.join(workspace, 'installation');\n try {\n const sourceRoot =\n entry.source.type === 'git'\n ? await materializers.git(entry.source, workspace)\n : await materializers.npm(entry.source, workspace);\n await copyPluginSource(sourceRoot, installation);\n const manifestPath = findPluginManifestPath(installation);\n if (!manifestPath) {\n throw new Error(`Remote plugin ${entry.name ?? entry.directory} does not contain a supported plugin manifest`);\n }\n validatePluginManifest(installation, manifestPath);\n const markerPath = path.join(installation, INSTALL_MARKER);\n if ((await pathType(markerPath)) !== 'missing') {\n throw new Error(`Remote plugin contains reserved cache metadata path: ${INSTALL_MARKER}`);\n }\n const marker: InstallMarker = { version: INSTALL_MARKER_VERSION, source: entry.source };\n await fs.promises.writeFile(markerPath, `${JSON.stringify(marker, null, 2)}\\n`, {\n flag: 'wx',\n mode: 0o600,\n });\n try {\n await fs.promises.rename(installation, entry.directory);\n } catch (error) {\n if (!isRenameRace(error)) throw error;\n await fs.promises.rm(installation, { recursive: true, force: true });\n const racedManifest = await inspectInstallation(entry);\n if (!racedManifest) throw new Error(`Remote plugin installation race left no cache: ${entry.directory}`);\n return { ...entry, ...racedManifest };\n }\n const installedManifest = await inspectInstallation(entry);\n if (!installedManifest) throw new Error(`Remote plugin installation left no cache: ${entry.directory}`);\n return { ...entry, ...installedManifest };\n } catch (error) {\n throw new Error(\n `Failed to install remote plugin ${entry.name ?? entry.directory}: ${error instanceof Error ? error.message : String(error)}`,\n {\n cause: error,\n },\n );\n } finally {\n await fs.promises.rm(workspace, { recursive: true, force: true });\n }\n}\n\n/** Downloads selected remote plugins once into their content-addressed cache directories. */\nexport async function materializePluginEntries(\n entries: readonly PluginEntry[],\n options: PluginMaterializerOptions = {},\n): Promise<PluginEntry[]> {\n const materializers: PluginSourceMaterializers = {\n git: options.materializers?.git ?? DEFAULT_MATERIALIZERS.git,\n npm: options.materializers?.npm ?? DEFAULT_MATERIALIZERS.npm,\n };\n return Promise.all(entries.map((entry) => installRemotePlugin(entry, materializers)));\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { findPluginManifestPath, isRemotePluginSource } from "@agimon-ai/po-config/domains";
|
|
4
|
+
import { spawn } from "node:child_process";
|
|
5
|
+
import { poHomeDirectory } from "@agimon-ai/po-core/piSettings";
|
|
6
|
+
//#region src/services/pluginMaterializer/index.ts
|
|
7
|
+
const AGENT_PLUGIN_SCHEMA = "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json";
|
|
8
|
+
const INSTALL_MARKER = ".po-plugin.json";
|
|
9
|
+
const INSTALL_MARKER_VERSION = 1;
|
|
10
|
+
const OUTPUT_LIMIT = 65536;
|
|
11
|
+
/** The staging project that declares the one npm plugin being installed. */
|
|
12
|
+
const STAGING_PACKAGE_NAME = "po-plugin-staging";
|
|
13
|
+
const LATEST_TAG = "latest";
|
|
14
|
+
function appendOutput(current, chunk) {
|
|
15
|
+
const next = current + chunk.toString("utf8");
|
|
16
|
+
return next.length <= OUTPUT_LIMIT ? next : next.slice(-65536);
|
|
17
|
+
}
|
|
18
|
+
function runCommand(command, args, options = {}) {
|
|
19
|
+
return new Promise((resolve, reject) => {
|
|
20
|
+
const child = spawn(command, args, {
|
|
21
|
+
cwd: options.cwd,
|
|
22
|
+
env: options.environment ?? process.env,
|
|
23
|
+
stdio: [
|
|
24
|
+
"ignore",
|
|
25
|
+
"pipe",
|
|
26
|
+
"pipe"
|
|
27
|
+
]
|
|
28
|
+
});
|
|
29
|
+
let stdout = "";
|
|
30
|
+
let stderr = "";
|
|
31
|
+
child.stdout.on("data", (chunk) => {
|
|
32
|
+
stdout = appendOutput(stdout, chunk);
|
|
33
|
+
});
|
|
34
|
+
child.stderr.on("data", (chunk) => {
|
|
35
|
+
stderr = appendOutput(stderr, chunk);
|
|
36
|
+
});
|
|
37
|
+
child.once("error", (error) => {
|
|
38
|
+
reject(new Error(`Failed to run ${command}: ${error.message}`, { cause: error }));
|
|
39
|
+
});
|
|
40
|
+
child.once("close", (code, signal) => {
|
|
41
|
+
if (code === 0) {
|
|
42
|
+
resolve(stdout.trim());
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
const outcome = signal ? `signal ${signal}` : `exit code ${code ?? "unknown"}`;
|
|
46
|
+
const details = stderr.trim() || stdout.trim();
|
|
47
|
+
reject(/* @__PURE__ */ new Error(`${command} ${args.join(" ")} failed with ${outcome}${details ? `\n${details}` : ""}`));
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
function assertContained(root, candidate, label) {
|
|
52
|
+
const relative = path.relative(root, candidate);
|
|
53
|
+
if (relative === "" || !relative.startsWith("..") && !path.isAbsolute(relative)) return;
|
|
54
|
+
throw new Error(`${label} resolves outside ${root}`);
|
|
55
|
+
}
|
|
56
|
+
async function materializeGitSource(source, workspace) {
|
|
57
|
+
const checkout = path.join(workspace, "checkout");
|
|
58
|
+
const pluginRoot = source.path ? path.resolve(checkout, source.path) : checkout;
|
|
59
|
+
if (source.path) assertContained(checkout, pluginRoot, "Git plugin path");
|
|
60
|
+
const cloneArgs = ["clone", "--filter=blob:none"];
|
|
61
|
+
if (source.path) cloneArgs.push("--sparse", "--no-checkout");
|
|
62
|
+
cloneArgs.push(source.url, checkout);
|
|
63
|
+
const environment = {
|
|
64
|
+
...process.env,
|
|
65
|
+
GIT_TERMINAL_PROMPT: "0"
|
|
66
|
+
};
|
|
67
|
+
await runCommand("git", cloneArgs, { environment });
|
|
68
|
+
if (source.path) await runCommand("git", [
|
|
69
|
+
"sparse-checkout",
|
|
70
|
+
"set",
|
|
71
|
+
"--no-cone",
|
|
72
|
+
"--",
|
|
73
|
+
source.path
|
|
74
|
+
], {
|
|
75
|
+
cwd: checkout,
|
|
76
|
+
environment
|
|
77
|
+
});
|
|
78
|
+
if (source.sha) {
|
|
79
|
+
await runCommand("git", ["checkout", source.sha], {
|
|
80
|
+
cwd: checkout,
|
|
81
|
+
environment
|
|
82
|
+
});
|
|
83
|
+
const checkedOutSha = await runCommand("git", ["rev-parse", "HEAD"], {
|
|
84
|
+
cwd: checkout,
|
|
85
|
+
environment
|
|
86
|
+
});
|
|
87
|
+
if (checkedOutSha.toLowerCase() !== source.sha.toLowerCase()) throw new Error(`Checked out Git SHA ${checkedOutSha} does not match requested SHA ${source.sha}`);
|
|
88
|
+
} else if (source.ref) await runCommand("git", ["checkout", source.ref], {
|
|
89
|
+
cwd: checkout,
|
|
90
|
+
environment
|
|
91
|
+
});
|
|
92
|
+
else if (source.path) await runCommand("git", ["checkout"], {
|
|
93
|
+
cwd: checkout,
|
|
94
|
+
environment
|
|
95
|
+
});
|
|
96
|
+
return pluginRoot;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Installs an npm plugin into the staging workspace with upm: a one-dependency
|
|
100
|
+
* project, never a spawned package manager. upm runs no lifecycle scripts, and
|
|
101
|
+
* its store is Po's shared `<po home>/store`.
|
|
102
|
+
*/
|
|
103
|
+
async function materializeNpmSource(source, workspace) {
|
|
104
|
+
const prefix = path.join(workspace, "npm");
|
|
105
|
+
await fs.promises.mkdir(prefix, { recursive: true });
|
|
106
|
+
await fs.promises.writeFile(path.join(prefix, "package.json"), `${JSON.stringify({
|
|
107
|
+
name: STAGING_PACKAGE_NAME,
|
|
108
|
+
private: true,
|
|
109
|
+
dependencies: { [source.package]: source.version ?? LATEST_TAG }
|
|
110
|
+
}, null, 2)}\n`);
|
|
111
|
+
const { installRuntimePackages } = await import("@agimon-ai/po-core/runtimePackages");
|
|
112
|
+
await installRuntimePackages({
|
|
113
|
+
dir: prefix,
|
|
114
|
+
poHome: poHomeDirectory(),
|
|
115
|
+
...source.registry ? { registry: source.registry } : {}
|
|
116
|
+
});
|
|
117
|
+
const pluginRoot = path.resolve(prefix, "node_modules", ...source.package.split("/"));
|
|
118
|
+
assertContained(path.join(prefix, "node_modules"), pluginRoot, "npm plugin package");
|
|
119
|
+
return fs.promises.realpath(pluginRoot);
|
|
120
|
+
}
|
|
121
|
+
const DEFAULT_MATERIALIZERS = {
|
|
122
|
+
git: materializeGitSource,
|
|
123
|
+
npm: materializeNpmSource
|
|
124
|
+
};
|
|
125
|
+
async function pathType(target) {
|
|
126
|
+
try {
|
|
127
|
+
return (await fs.promises.lstat(target)).isDirectory() ? "directory" : "other";
|
|
128
|
+
} catch (error) {
|
|
129
|
+
if (error.code === "ENOENT") return "missing";
|
|
130
|
+
throw error;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
function optionalManifestString(manifest, key) {
|
|
134
|
+
const value = manifest[key];
|
|
135
|
+
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
136
|
+
}
|
|
137
|
+
function validatePluginManifest(pluginRoot, manifestPath) {
|
|
138
|
+
try {
|
|
139
|
+
const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf8"));
|
|
140
|
+
if (typeof manifest !== "object" || manifest === null || Array.isArray(manifest)) throw new Error("manifest must contain a JSON object");
|
|
141
|
+
const record = manifest;
|
|
142
|
+
const agentPluginSchema = manifestPath === path.join(pluginRoot, "plugin.json") && record.$schema === AGENT_PLUGIN_SCHEMA ? AGENT_PLUGIN_SCHEMA : void 0;
|
|
143
|
+
const name = optionalManifestString(record, "name");
|
|
144
|
+
const version = optionalManifestString(record, "version");
|
|
145
|
+
const description = optionalManifestString(record, "description");
|
|
146
|
+
return {
|
|
147
|
+
skillDiscovery: agentPluginSchema ? "direct-children" : "recursive",
|
|
148
|
+
manifest: {
|
|
149
|
+
path: manifestPath,
|
|
150
|
+
...name ? { name } : {},
|
|
151
|
+
...version ? { version } : {},
|
|
152
|
+
...description ? { description } : {},
|
|
153
|
+
...agentPluginSchema ? { agentPluginSchema } : {}
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
} catch (error) {
|
|
157
|
+
throw new Error(`Invalid plugin manifest ${manifestPath}: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
async function inspectInstallation(entry) {
|
|
161
|
+
const type = await pathType(entry.directory);
|
|
162
|
+
if (type === "missing") return false;
|
|
163
|
+
if (type !== "directory") throw new Error(`Remote plugin cache path is not a directory: ${entry.directory}`);
|
|
164
|
+
if (!entry.source || !isRemotePluginSource(entry.source)) throw new Error(`Remote plugin entry is missing its source: ${entry.name ?? entry.directory}`);
|
|
165
|
+
let marker;
|
|
166
|
+
try {
|
|
167
|
+
marker = JSON.parse(await fs.promises.readFile(path.join(entry.directory, INSTALL_MARKER), "utf8"));
|
|
168
|
+
} catch (error) {
|
|
169
|
+
throw new Error(`Remote plugin cache is not managed by Po: ${entry.directory}`, { cause: error });
|
|
170
|
+
}
|
|
171
|
+
if (marker.version !== INSTALL_MARKER_VERSION || JSON.stringify(marker.source) !== JSON.stringify(entry.source)) throw new Error(`Remote plugin cache metadata does not match ${entry.name ?? entry.directory}: ${entry.directory}`);
|
|
172
|
+
const manifestPath = findPluginManifestPath(entry.directory);
|
|
173
|
+
if (!manifestPath) throw new Error(`Remote plugin cache is missing a supported plugin manifest: ${entry.directory}`);
|
|
174
|
+
return validatePluginManifest(entry.directory, manifestPath);
|
|
175
|
+
}
|
|
176
|
+
async function copyPluginSource(sourceRoot, destination) {
|
|
177
|
+
if (await pathType(sourceRoot) !== "directory") throw new Error(`Materialized plugin source is not a directory: ${sourceRoot}`);
|
|
178
|
+
await fs.promises.cp(sourceRoot, destination, {
|
|
179
|
+
recursive: true,
|
|
180
|
+
filter: (candidate) => path.basename(candidate) !== ".git"
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
function isRenameRace(error) {
|
|
184
|
+
const code = error.code;
|
|
185
|
+
return code === "EEXIST" || code === "ENOTEMPTY";
|
|
186
|
+
}
|
|
187
|
+
async function installRemotePlugin(entry, materializers) {
|
|
188
|
+
if (!entry.source || !isRemotePluginSource(entry.source)) return entry;
|
|
189
|
+
const existingManifest = await inspectInstallation(entry);
|
|
190
|
+
if (existingManifest) return {
|
|
191
|
+
...entry,
|
|
192
|
+
...existingManifest
|
|
193
|
+
};
|
|
194
|
+
const parent = path.dirname(entry.directory);
|
|
195
|
+
await fs.promises.mkdir(parent, {
|
|
196
|
+
recursive: true,
|
|
197
|
+
mode: 448
|
|
198
|
+
});
|
|
199
|
+
if (await pathType(parent) !== "directory") throw new Error(`Remote plugin cache root is not a directory: ${parent}`);
|
|
200
|
+
await fs.promises.chmod(parent, 448);
|
|
201
|
+
const workspace = await fs.promises.mkdtemp(path.join(parent, ".plugin-staging-"));
|
|
202
|
+
const installation = path.join(workspace, "installation");
|
|
203
|
+
try {
|
|
204
|
+
await copyPluginSource(entry.source.type === "git" ? await materializers.git(entry.source, workspace) : await materializers.npm(entry.source, workspace), installation);
|
|
205
|
+
const manifestPath = findPluginManifestPath(installation);
|
|
206
|
+
if (!manifestPath) throw new Error(`Remote plugin ${entry.name ?? entry.directory} does not contain a supported plugin manifest`);
|
|
207
|
+
validatePluginManifest(installation, manifestPath);
|
|
208
|
+
const markerPath = path.join(installation, INSTALL_MARKER);
|
|
209
|
+
if (await pathType(markerPath) !== "missing") throw new Error(`Remote plugin contains reserved cache metadata path: ${INSTALL_MARKER}`);
|
|
210
|
+
const marker = {
|
|
211
|
+
version: INSTALL_MARKER_VERSION,
|
|
212
|
+
source: entry.source
|
|
213
|
+
};
|
|
214
|
+
await fs.promises.writeFile(markerPath, `${JSON.stringify(marker, null, 2)}\n`, {
|
|
215
|
+
flag: "wx",
|
|
216
|
+
mode: 384
|
|
217
|
+
});
|
|
218
|
+
try {
|
|
219
|
+
await fs.promises.rename(installation, entry.directory);
|
|
220
|
+
} catch (error) {
|
|
221
|
+
if (!isRenameRace(error)) throw error;
|
|
222
|
+
await fs.promises.rm(installation, {
|
|
223
|
+
recursive: true,
|
|
224
|
+
force: true
|
|
225
|
+
});
|
|
226
|
+
const racedManifest = await inspectInstallation(entry);
|
|
227
|
+
if (!racedManifest) throw new Error(`Remote plugin installation race left no cache: ${entry.directory}`);
|
|
228
|
+
return {
|
|
229
|
+
...entry,
|
|
230
|
+
...racedManifest
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
const installedManifest = await inspectInstallation(entry);
|
|
234
|
+
if (!installedManifest) throw new Error(`Remote plugin installation left no cache: ${entry.directory}`);
|
|
235
|
+
return {
|
|
236
|
+
...entry,
|
|
237
|
+
...installedManifest
|
|
238
|
+
};
|
|
239
|
+
} catch (error) {
|
|
240
|
+
throw new Error(`Failed to install remote plugin ${entry.name ?? entry.directory}: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
|
|
241
|
+
} finally {
|
|
242
|
+
await fs.promises.rm(workspace, {
|
|
243
|
+
recursive: true,
|
|
244
|
+
force: true
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
/** Downloads selected remote plugins once into their content-addressed cache directories. */
|
|
249
|
+
async function materializePluginEntries(entries, options = {}) {
|
|
250
|
+
const materializers = {
|
|
251
|
+
git: options.materializers?.git ?? DEFAULT_MATERIALIZERS.git,
|
|
252
|
+
npm: options.materializers?.npm ?? DEFAULT_MATERIALIZERS.npm
|
|
253
|
+
};
|
|
254
|
+
return Promise.all(entries.map((entry) => installRemotePlugin(entry, materializers)));
|
|
255
|
+
}
|
|
256
|
+
//#endregion
|
|
257
|
+
export { materializePluginEntries as t };
|
|
258
|
+
|
|
259
|
+
//# sourceMappingURL=pluginMaterializer-D9-oDF-b.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pluginMaterializer-D9-oDF-b.mjs","names":[],"sources":["../src/services/pluginMaterializer/index.ts"],"sourcesContent":["import { spawn } from 'node:child_process';\nimport fs from 'node:fs';\nimport path from 'node:path';\n\nimport {\n findPluginManifestPath,\n type GitPluginSource,\n isRemotePluginSource,\n type NpmPluginSource,\n type PluginEntry,\n type PluginManifestMetadata,\n type PluginSkillDiscovery,\n} from '@agimon-ai/po-config/domains';\nimport { poHomeDirectory } from '@agimon-ai/po-core/piSettings';\n\nconst AGENT_PLUGIN_SCHEMA = 'https://agent-plugins.org/schemas/1.0.0/plugin.schema.json';\nconst INSTALL_MARKER = '.po-plugin.json';\nconst INSTALL_MARKER_VERSION = 1;\nconst OUTPUT_LIMIT = 64 * 1024;\n/** The staging project that declares the one npm plugin being installed. */\nconst STAGING_PACKAGE_NAME = 'po-plugin-staging';\nconst LATEST_TAG = 'latest';\n\ninterface CommandOptions {\n cwd?: string;\n environment?: NodeJS.ProcessEnv;\n}\n\ninterface InstallMarker {\n version: number;\n source: GitPluginSource | NpmPluginSource;\n}\n\ninterface InspectedPluginManifest {\n skillDiscovery: PluginSkillDiscovery;\n manifest: PluginManifestMetadata;\n}\n\nexport interface PluginSourceMaterializers {\n git: (source: GitPluginSource, workspace: string) => Promise<string>;\n npm: (source: NpmPluginSource, workspace: string) => Promise<string>;\n}\n\nexport interface PluginMaterializerOptions {\n materializers?: Partial<PluginSourceMaterializers>;\n}\n\nfunction appendOutput(current: string, chunk: Buffer): string {\n const next = current + chunk.toString('utf8');\n return next.length <= OUTPUT_LIMIT ? next : next.slice(-OUTPUT_LIMIT);\n}\n\nfunction runCommand(command: string, args: string[], options: CommandOptions = {}): Promise<string> {\n return new Promise((resolve, reject) => {\n const child = spawn(command, args, {\n cwd: options.cwd,\n env: options.environment ?? process.env,\n stdio: ['ignore', 'pipe', 'pipe'],\n });\n let stdout = '';\n let stderr = '';\n child.stdout.on('data', (chunk: Buffer) => {\n stdout = appendOutput(stdout, chunk);\n });\n child.stderr.on('data', (chunk: Buffer) => {\n stderr = appendOutput(stderr, chunk);\n });\n child.once('error', (error) => {\n reject(new Error(`Failed to run ${command}: ${error.message}`, { cause: error }));\n });\n child.once('close', (code, signal) => {\n if (code === 0) {\n resolve(stdout.trim());\n return;\n }\n const outcome = signal ? `signal ${signal}` : `exit code ${code ?? 'unknown'}`;\n const details = stderr.trim() || stdout.trim();\n reject(new Error(`${command} ${args.join(' ')} failed with ${outcome}${details ? `\\n${details}` : ''}`));\n });\n });\n}\n\nfunction assertContained(root: string, candidate: string, label: string): void {\n const relative = path.relative(root, candidate);\n if (relative === '' || (!relative.startsWith('..') && !path.isAbsolute(relative))) return;\n throw new Error(`${label} resolves outside ${root}`);\n}\n\nasync function materializeGitSource(source: GitPluginSource, workspace: string): Promise<string> {\n const checkout = path.join(workspace, 'checkout');\n const pluginRoot = source.path ? path.resolve(checkout, source.path) : checkout;\n if (source.path) assertContained(checkout, pluginRoot, 'Git plugin path');\n const cloneArgs = ['clone', '--filter=blob:none'];\n if (source.path) cloneArgs.push('--sparse', '--no-checkout');\n cloneArgs.push(source.url, checkout);\n const environment = { ...process.env, GIT_TERMINAL_PROMPT: '0' };\n await runCommand('git', cloneArgs, { environment });\n\n if (source.path) {\n await runCommand('git', ['sparse-checkout', 'set', '--no-cone', '--', source.path], {\n cwd: checkout,\n environment,\n });\n }\n if (source.sha) {\n await runCommand('git', ['checkout', source.sha], { cwd: checkout, environment });\n const checkedOutSha = await runCommand('git', ['rev-parse', 'HEAD'], { cwd: checkout, environment });\n if (checkedOutSha.toLowerCase() !== source.sha.toLowerCase()) {\n throw new Error(`Checked out Git SHA ${checkedOutSha} does not match requested SHA ${source.sha}`);\n }\n } else if (source.ref) {\n await runCommand('git', ['checkout', source.ref], { cwd: checkout, environment });\n } else if (source.path) {\n await runCommand('git', ['checkout'], { cwd: checkout, environment });\n }\n\n return pluginRoot;\n}\n\n/**\n * Installs an npm plugin into the staging workspace with upm: a one-dependency\n * project, never a spawned package manager. upm runs no lifecycle scripts, and\n * its store is Po's shared `<po home>/store`.\n */\nasync function materializeNpmSource(source: NpmPluginSource, workspace: string): Promise<string> {\n const prefix = path.join(workspace, 'npm');\n await fs.promises.mkdir(prefix, { recursive: true });\n await fs.promises.writeFile(\n path.join(prefix, 'package.json'),\n `${JSON.stringify(\n { name: STAGING_PACKAGE_NAME, private: true, dependencies: { [source.package]: source.version ?? LATEST_TAG } },\n null,\n 2,\n )}\\n`,\n );\n // Loaded on demand so upm stays off the path of every plugin that is already cached.\n const { installRuntimePackages } = await import('@agimon-ai/po-core/runtimePackages');\n await installRuntimePackages({\n dir: prefix,\n poHome: poHomeDirectory(),\n ...(source.registry ? { registry: source.registry } : {}),\n });\n const pluginRoot = path.resolve(prefix, 'node_modules', ...source.package.split('/'));\n assertContained(path.join(prefix, 'node_modules'), pluginRoot, 'npm plugin package');\n // upm links each package into node_modules; the copy reads the linked directory.\n return fs.promises.realpath(pluginRoot);\n}\n\nconst DEFAULT_MATERIALIZERS: PluginSourceMaterializers = {\n git: materializeGitSource,\n npm: materializeNpmSource,\n};\n\nasync function pathType(target: string): Promise<'directory' | 'missing' | 'other'> {\n try {\n const stat = await fs.promises.lstat(target);\n return stat.isDirectory() ? 'directory' : 'other';\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return 'missing';\n throw error;\n }\n}\n\nfunction optionalManifestString(manifest: Record<string, unknown>, key: string): string | undefined {\n const value = manifest[key];\n return typeof value === 'string' && value.trim() ? value.trim() : undefined;\n}\n\nfunction validatePluginManifest(pluginRoot: string, manifestPath: string): InspectedPluginManifest {\n try {\n const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8')) as unknown;\n if (typeof manifest !== 'object' || manifest === null || Array.isArray(manifest)) {\n throw new Error('manifest must contain a JSON object');\n }\n const record = manifest as Record<string, unknown>;\n const agentPluginSchema =\n manifestPath === path.join(pluginRoot, 'plugin.json') && record.$schema === AGENT_PLUGIN_SCHEMA\n ? AGENT_PLUGIN_SCHEMA\n : undefined;\n const name = optionalManifestString(record, 'name');\n const version = optionalManifestString(record, 'version');\n const description = optionalManifestString(record, 'description');\n return {\n skillDiscovery: agentPluginSchema ? 'direct-children' : 'recursive',\n manifest: {\n path: manifestPath,\n ...(name ? { name } : {}),\n ...(version ? { version } : {}),\n ...(description ? { description } : {}),\n ...(agentPluginSchema ? { agentPluginSchema } : {}),\n },\n };\n } catch (error) {\n throw new Error(\n `Invalid plugin manifest ${manifestPath}: ${error instanceof Error ? error.message : String(error)}`,\n {\n cause: error,\n },\n );\n }\n}\n\nasync function inspectInstallation(entry: PluginEntry): Promise<InspectedPluginManifest | false> {\n const type = await pathType(entry.directory);\n if (type === 'missing') return false;\n if (type !== 'directory') throw new Error(`Remote plugin cache path is not a directory: ${entry.directory}`);\n if (!entry.source || !isRemotePluginSource(entry.source)) {\n throw new Error(`Remote plugin entry is missing its source: ${entry.name ?? entry.directory}`);\n }\n\n let marker: InstallMarker;\n try {\n marker = JSON.parse(\n await fs.promises.readFile(path.join(entry.directory, INSTALL_MARKER), 'utf8'),\n ) as InstallMarker;\n } catch (error) {\n throw new Error(`Remote plugin cache is not managed by Po: ${entry.directory}`, { cause: error });\n }\n if (marker.version !== INSTALL_MARKER_VERSION || JSON.stringify(marker.source) !== JSON.stringify(entry.source)) {\n throw new Error(`Remote plugin cache metadata does not match ${entry.name ?? entry.directory}: ${entry.directory}`);\n }\n const manifestPath = findPluginManifestPath(entry.directory);\n if (!manifestPath) {\n throw new Error(`Remote plugin cache is missing a supported plugin manifest: ${entry.directory}`);\n }\n return validatePluginManifest(entry.directory, manifestPath);\n}\n\nasync function copyPluginSource(sourceRoot: string, destination: string): Promise<void> {\n if ((await pathType(sourceRoot)) !== 'directory') {\n throw new Error(`Materialized plugin source is not a directory: ${sourceRoot}`);\n }\n await fs.promises.cp(sourceRoot, destination, {\n recursive: true,\n filter: (candidate) => path.basename(candidate) !== '.git',\n });\n}\n\nfunction isRenameRace(error: unknown): boolean {\n const code = (error as NodeJS.ErrnoException).code;\n return code === 'EEXIST' || code === 'ENOTEMPTY';\n}\n\nasync function installRemotePlugin(entry: PluginEntry, materializers: PluginSourceMaterializers): Promise<PluginEntry> {\n if (!entry.source || !isRemotePluginSource(entry.source)) return entry;\n const existingManifest = await inspectInstallation(entry);\n if (existingManifest) return { ...entry, ...existingManifest };\n\n const parent = path.dirname(entry.directory);\n await fs.promises.mkdir(parent, { recursive: true, mode: 0o700 });\n if ((await pathType(parent)) !== 'directory') {\n throw new Error(`Remote plugin cache root is not a directory: ${parent}`);\n }\n await fs.promises.chmod(parent, 0o700);\n const workspace = await fs.promises.mkdtemp(path.join(parent, '.plugin-staging-'));\n const installation = path.join(workspace, 'installation');\n try {\n const sourceRoot =\n entry.source.type === 'git'\n ? await materializers.git(entry.source, workspace)\n : await materializers.npm(entry.source, workspace);\n await copyPluginSource(sourceRoot, installation);\n const manifestPath = findPluginManifestPath(installation);\n if (!manifestPath) {\n throw new Error(`Remote plugin ${entry.name ?? entry.directory} does not contain a supported plugin manifest`);\n }\n validatePluginManifest(installation, manifestPath);\n const markerPath = path.join(installation, INSTALL_MARKER);\n if ((await pathType(markerPath)) !== 'missing') {\n throw new Error(`Remote plugin contains reserved cache metadata path: ${INSTALL_MARKER}`);\n }\n const marker: InstallMarker = { version: INSTALL_MARKER_VERSION, source: entry.source };\n await fs.promises.writeFile(markerPath, `${JSON.stringify(marker, null, 2)}\\n`, {\n flag: 'wx',\n mode: 0o600,\n });\n try {\n await fs.promises.rename(installation, entry.directory);\n } catch (error) {\n if (!isRenameRace(error)) throw error;\n await fs.promises.rm(installation, { recursive: true, force: true });\n const racedManifest = await inspectInstallation(entry);\n if (!racedManifest) throw new Error(`Remote plugin installation race left no cache: ${entry.directory}`);\n return { ...entry, ...racedManifest };\n }\n const installedManifest = await inspectInstallation(entry);\n if (!installedManifest) throw new Error(`Remote plugin installation left no cache: ${entry.directory}`);\n return { ...entry, ...installedManifest };\n } catch (error) {\n throw new Error(\n `Failed to install remote plugin ${entry.name ?? entry.directory}: ${error instanceof Error ? error.message : String(error)}`,\n {\n cause: error,\n },\n );\n } finally {\n await fs.promises.rm(workspace, { recursive: true, force: true });\n }\n}\n\n/** Downloads selected remote plugins once into their content-addressed cache directories. */\nexport async function materializePluginEntries(\n entries: readonly PluginEntry[],\n options: PluginMaterializerOptions = {},\n): Promise<PluginEntry[]> {\n const materializers: PluginSourceMaterializers = {\n git: options.materializers?.git ?? DEFAULT_MATERIALIZERS.git,\n npm: options.materializers?.npm ?? DEFAULT_MATERIALIZERS.npm,\n };\n return Promise.all(entries.map((entry) => installRemotePlugin(entry, materializers)));\n}\n"],"mappings":";;;;;;AAeA,MAAM,sBAAsB;AAC5B,MAAM,iBAAiB;AACvB,MAAM,yBAAyB;AAC/B,MAAM,eAAe;;AAErB,MAAM,uBAAuB;AAC7B,MAAM,aAAa;AA0BnB,SAAS,aAAa,SAAiB,OAAuB;CAC5D,MAAM,OAAO,UAAU,MAAM,SAAS,MAAM;CAC5C,OAAO,KAAK,UAAU,eAAe,OAAO,KAAK,MAAM,MAAa;AACtE;AAEA,SAAS,WAAW,SAAiB,MAAgB,UAA0B,CAAC,GAAoB;CAClG,OAAO,IAAI,SAAS,SAAS,WAAW;EACtC,MAAM,QAAQ,MAAM,SAAS,MAAM;GACjC,KAAK,QAAQ;GACb,KAAK,QAAQ,eAAe,QAAQ;GACpC,OAAO;IAAC;IAAU;IAAQ;GAAM;EAClC,CAAC;EACD,IAAI,SAAS;EACb,IAAI,SAAS;EACb,MAAM,OAAO,GAAG,SAAS,UAAkB;GACzC,SAAS,aAAa,QAAQ,KAAK;EACrC,CAAC;EACD,MAAM,OAAO,GAAG,SAAS,UAAkB;GACzC,SAAS,aAAa,QAAQ,KAAK;EACrC,CAAC;EACD,MAAM,KAAK,UAAU,UAAU;GAC7B,OAAO,IAAI,MAAM,iBAAiB,QAAQ,IAAI,MAAM,WAAW,EAAE,OAAO,MAAM,CAAC,CAAC;EAClF,CAAC;EACD,MAAM,KAAK,UAAU,MAAM,WAAW;GACpC,IAAI,SAAS,GAAG;IACd,QAAQ,OAAO,KAAK,CAAC;IACrB;GACF;GACA,MAAM,UAAU,SAAS,UAAU,WAAW,aAAa,QAAQ;GACnE,MAAM,UAAU,OAAO,KAAK,KAAK,OAAO,KAAK;GAC7C,uBAAO,IAAI,MAAM,GAAG,QAAQ,GAAG,KAAK,KAAK,GAAG,EAAE,eAAe,UAAU,UAAU,KAAK,YAAY,IAAI,CAAC;EACzG,CAAC;CACH,CAAC;AACH;AAEA,SAAS,gBAAgB,MAAc,WAAmB,OAAqB;CAC7E,MAAM,WAAW,KAAK,SAAS,MAAM,SAAS;CAC9C,IAAI,aAAa,MAAO,CAAC,SAAS,WAAW,IAAI,KAAK,CAAC,KAAK,WAAW,QAAQ,GAAI;CACnF,MAAM,IAAI,MAAM,GAAG,MAAM,oBAAoB,MAAM;AACrD;AAEA,eAAe,qBAAqB,QAAyB,WAAoC;CAC/F,MAAM,WAAW,KAAK,KAAK,WAAW,UAAU;CAChD,MAAM,aAAa,OAAO,OAAO,KAAK,QAAQ,UAAU,OAAO,IAAI,IAAI;CACvE,IAAI,OAAO,MAAM,gBAAgB,UAAU,YAAY,iBAAiB;CACxE,MAAM,YAAY,CAAC,SAAS,oBAAoB;CAChD,IAAI,OAAO,MAAM,UAAU,KAAK,YAAY,eAAe;CAC3D,UAAU,KAAK,OAAO,KAAK,QAAQ;CACnC,MAAM,cAAc;EAAE,GAAG,QAAQ;EAAK,qBAAqB;CAAI;CAC/D,MAAM,WAAW,OAAO,WAAW,EAAE,YAAY,CAAC;CAElD,IAAI,OAAO,MACT,MAAM,WAAW,OAAO;EAAC;EAAmB;EAAO;EAAa;EAAM,OAAO;CAAI,GAAG;EAClF,KAAK;EACL;CACF,CAAC;CAEH,IAAI,OAAO,KAAK;EACd,MAAM,WAAW,OAAO,CAAC,YAAY,OAAO,GAAG,GAAG;GAAE,KAAK;GAAU;EAAY,CAAC;EAChF,MAAM,gBAAgB,MAAM,WAAW,OAAO,CAAC,aAAa,MAAM,GAAG;GAAE,KAAK;GAAU;EAAY,CAAC;EACnG,IAAI,cAAc,YAAY,MAAM,OAAO,IAAI,YAAY,GACzD,MAAM,IAAI,MAAM,uBAAuB,cAAc,gCAAgC,OAAO,KAAK;CAErG,OAAO,IAAI,OAAO,KAChB,MAAM,WAAW,OAAO,CAAC,YAAY,OAAO,GAAG,GAAG;EAAE,KAAK;EAAU;CAAY,CAAC;MAC3E,IAAI,OAAO,MAChB,MAAM,WAAW,OAAO,CAAC,UAAU,GAAG;EAAE,KAAK;EAAU;CAAY,CAAC;CAGtE,OAAO;AACT;;;;;;AAOA,eAAe,qBAAqB,QAAyB,WAAoC;CAC/F,MAAM,SAAS,KAAK,KAAK,WAAW,KAAK;CACzC,MAAM,GAAG,SAAS,MAAM,QAAQ,EAAE,WAAW,KAAK,CAAC;CACnD,MAAM,GAAG,SAAS,UAChB,KAAK,KAAK,QAAQ,cAAc,GAChC,GAAG,KAAK,UACN;EAAE,MAAM;EAAsB,SAAS;EAAM,cAAc,GAAG,OAAO,UAAU,OAAO,WAAW,WAAW;CAAE,GAC9G,MACA,CACF,EAAE,GACJ;CAEA,MAAM,EAAE,2BAA2B,MAAM,OAAO;CAChD,MAAM,uBAAuB;EAC3B,KAAK;EACL,QAAQ,gBAAgB;EACxB,GAAI,OAAO,WAAW,EAAE,UAAU,OAAO,SAAS,IAAI,CAAC;CACzD,CAAC;CACD,MAAM,aAAa,KAAK,QAAQ,QAAQ,gBAAgB,GAAG,OAAO,QAAQ,MAAM,GAAG,CAAC;CACpF,gBAAgB,KAAK,KAAK,QAAQ,cAAc,GAAG,YAAY,oBAAoB;CAEnF,OAAO,GAAG,SAAS,SAAS,UAAU;AACxC;AAEA,MAAM,wBAAmD;CACvD,KAAK;CACL,KAAK;AACP;AAEA,eAAe,SAAS,QAA4D;CAClF,IAAI;EAEF,QAAO,MADY,GAAG,SAAS,MAAM,MAAM,EAAA,CAC/B,YAAY,IAAI,cAAc;CAC5C,SAAS,OAAO;EACd,IAAK,MAAgC,SAAS,UAAU,OAAO;EAC/D,MAAM;CACR;AACF;AAEA,SAAS,uBAAuB,UAAmC,KAAiC;CAClG,MAAM,QAAQ,SAAS;CACvB,OAAO,OAAO,UAAU,YAAY,MAAM,KAAK,IAAI,MAAM,KAAK,IAAI,KAAA;AACpE;AAEA,SAAS,uBAAuB,YAAoB,cAA+C;CACjG,IAAI;EACF,MAAM,WAAW,KAAK,MAAM,GAAG,aAAa,cAAc,MAAM,CAAC;EACjE,IAAI,OAAO,aAAa,YAAY,aAAa,QAAQ,MAAM,QAAQ,QAAQ,GAC7E,MAAM,IAAI,MAAM,qCAAqC;EAEvD,MAAM,SAAS;EACf,MAAM,oBACJ,iBAAiB,KAAK,KAAK,YAAY,aAAa,KAAK,OAAO,YAAY,sBACxE,sBACA,KAAA;EACN,MAAM,OAAO,uBAAuB,QAAQ,MAAM;EAClD,MAAM,UAAU,uBAAuB,QAAQ,SAAS;EACxD,MAAM,cAAc,uBAAuB,QAAQ,aAAa;EAChE,OAAO;GACL,gBAAgB,oBAAoB,oBAAoB;GACxD,UAAU;IACR,MAAM;IACN,GAAI,OAAO,EAAE,KAAK,IAAI,CAAC;IACvB,GAAI,UAAU,EAAE,QAAQ,IAAI,CAAC;IAC7B,GAAI,cAAc,EAAE,YAAY,IAAI,CAAC;IACrC,GAAI,oBAAoB,EAAE,kBAAkB,IAAI,CAAC;GACnD;EACF;CACF,SAAS,OAAO;EACd,MAAM,IAAI,MACR,2BAA2B,aAAa,IAAI,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,KACjG,EACE,OAAO,MACT,CACF;CACF;AACF;AAEA,eAAe,oBAAoB,OAA8D;CAC/F,MAAM,OAAO,MAAM,SAAS,MAAM,SAAS;CAC3C,IAAI,SAAS,WAAW,OAAO;CAC/B,IAAI,SAAS,aAAa,MAAM,IAAI,MAAM,gDAAgD,MAAM,WAAW;CAC3G,IAAI,CAAC,MAAM,UAAU,CAAC,qBAAqB,MAAM,MAAM,GACrD,MAAM,IAAI,MAAM,8CAA8C,MAAM,QAAQ,MAAM,WAAW;CAG/F,IAAI;CACJ,IAAI;EACF,SAAS,KAAK,MACZ,MAAM,GAAG,SAAS,SAAS,KAAK,KAAK,MAAM,WAAW,cAAc,GAAG,MAAM,CAC/E;CACF,SAAS,OAAO;EACd,MAAM,IAAI,MAAM,6CAA6C,MAAM,aAAa,EAAE,OAAO,MAAM,CAAC;CAClG;CACA,IAAI,OAAO,YAAY,0BAA0B,KAAK,UAAU,OAAO,MAAM,MAAM,KAAK,UAAU,MAAM,MAAM,GAC5G,MAAM,IAAI,MAAM,+CAA+C,MAAM,QAAQ,MAAM,UAAU,IAAI,MAAM,WAAW;CAEpH,MAAM,eAAe,uBAAuB,MAAM,SAAS;CAC3D,IAAI,CAAC,cACH,MAAM,IAAI,MAAM,+DAA+D,MAAM,WAAW;CAElG,OAAO,uBAAuB,MAAM,WAAW,YAAY;AAC7D;AAEA,eAAe,iBAAiB,YAAoB,aAAoC;CACtF,IAAK,MAAM,SAAS,UAAU,MAAO,aACnC,MAAM,IAAI,MAAM,kDAAkD,YAAY;CAEhF,MAAM,GAAG,SAAS,GAAG,YAAY,aAAa;EAC5C,WAAW;EACX,SAAS,cAAc,KAAK,SAAS,SAAS,MAAM;CACtD,CAAC;AACH;AAEA,SAAS,aAAa,OAAyB;CAC7C,MAAM,OAAQ,MAAgC;CAC9C,OAAO,SAAS,YAAY,SAAS;AACvC;AAEA,eAAe,oBAAoB,OAAoB,eAAgE;CACrH,IAAI,CAAC,MAAM,UAAU,CAAC,qBAAqB,MAAM,MAAM,GAAG,OAAO;CACjE,MAAM,mBAAmB,MAAM,oBAAoB,KAAK;CACxD,IAAI,kBAAkB,OAAO;EAAE,GAAG;EAAO,GAAG;CAAiB;CAE7D,MAAM,SAAS,KAAK,QAAQ,MAAM,SAAS;CAC3C,MAAM,GAAG,SAAS,MAAM,QAAQ;EAAE,WAAW;EAAM,MAAM;CAAM,CAAC;CAChE,IAAK,MAAM,SAAS,MAAM,MAAO,aAC/B,MAAM,IAAI,MAAM,gDAAgD,QAAQ;CAE1E,MAAM,GAAG,SAAS,MAAM,QAAQ,GAAK;CACrC,MAAM,YAAY,MAAM,GAAG,SAAS,QAAQ,KAAK,KAAK,QAAQ,kBAAkB,CAAC;CACjF,MAAM,eAAe,KAAK,KAAK,WAAW,cAAc;CACxD,IAAI;EAKF,MAAM,iBAHJ,MAAM,OAAO,SAAS,QAClB,MAAM,cAAc,IAAI,MAAM,QAAQ,SAAS,IAC/C,MAAM,cAAc,IAAI,MAAM,QAAQ,SAAS,GAClB,YAAY;EAC/C,MAAM,eAAe,uBAAuB,YAAY;EACxD,IAAI,CAAC,cACH,MAAM,IAAI,MAAM,iBAAiB,MAAM,QAAQ,MAAM,UAAU,8CAA8C;EAE/G,uBAAuB,cAAc,YAAY;EACjD,MAAM,aAAa,KAAK,KAAK,cAAc,cAAc;EACzD,IAAK,MAAM,SAAS,UAAU,MAAO,WACnC,MAAM,IAAI,MAAM,wDAAwD,gBAAgB;EAE1F,MAAM,SAAwB;GAAE,SAAS;GAAwB,QAAQ,MAAM;EAAO;EACtF,MAAM,GAAG,SAAS,UAAU,YAAY,GAAG,KAAK,UAAU,QAAQ,MAAM,CAAC,EAAE,KAAK;GAC9E,MAAM;GACN,MAAM;EACR,CAAC;EACD,IAAI;GACF,MAAM,GAAG,SAAS,OAAO,cAAc,MAAM,SAAS;EACxD,SAAS,OAAO;GACd,IAAI,CAAC,aAAa,KAAK,GAAG,MAAM;GAChC,MAAM,GAAG,SAAS,GAAG,cAAc;IAAE,WAAW;IAAM,OAAO;GAAK,CAAC;GACnE,MAAM,gBAAgB,MAAM,oBAAoB,KAAK;GACrD,IAAI,CAAC,eAAe,MAAM,IAAI,MAAM,kDAAkD,MAAM,WAAW;GACvG,OAAO;IAAE,GAAG;IAAO,GAAG;GAAc;EACtC;EACA,MAAM,oBAAoB,MAAM,oBAAoB,KAAK;EACzD,IAAI,CAAC,mBAAmB,MAAM,IAAI,MAAM,6CAA6C,MAAM,WAAW;EACtG,OAAO;GAAE,GAAG;GAAO,GAAG;EAAkB;CAC1C,SAAS,OAAO;EACd,MAAM,IAAI,MACR,mCAAmC,MAAM,QAAQ,MAAM,UAAU,IAAI,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,KAC1H,EACE,OAAO,MACT,CACF;CACF,UAAU;EACR,MAAM,GAAG,SAAS,GAAG,WAAW;GAAE,WAAW;GAAM,OAAO;EAAK,CAAC;CAClE;AACF;;AAGA,eAAsB,yBACpB,SACA,UAAqC,CAAC,GACd;CACxB,MAAM,gBAA2C;EAC/C,KAAK,QAAQ,eAAe,OAAO,sBAAsB;EACzD,KAAK,QAAQ,eAAe,OAAO,sBAAsB;CAC3D;CACA,OAAO,QAAQ,IAAI,QAAQ,KAAK,UAAU,oBAAoB,OAAO,aAAa,CAAC,CAAC;AACtF"}
|
package/dist/plugins.cjs
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { GitPluginSource, NpmPluginSource, PluginEntry } from "@agimon-ai/po-config/domains";
|
|
2
|
+
//#region src/services/pluginMaterializer/index.d.ts
|
|
3
|
+
interface PluginSourceMaterializers {
|
|
4
|
+
git: (source: GitPluginSource, workspace: string) => Promise<string>;
|
|
5
|
+
npm: (source: NpmPluginSource, workspace: string) => Promise<string>;
|
|
6
|
+
}
|
|
7
|
+
interface PluginMaterializerOptions {
|
|
8
|
+
materializers?: Partial<PluginSourceMaterializers>;
|
|
9
|
+
}
|
|
10
|
+
/** Downloads selected remote plugins once into their content-addressed cache directories. */
|
|
11
|
+
export declare function materializePluginEntries(entries: readonly PluginEntry[], options?: PluginMaterializerOptions): Promise<PluginEntry[]>;
|
|
12
|
+
//#endregion
|
|
13
|
+
export type { PluginMaterializerOptions, PluginSourceMaterializers };
|
|
14
|
+
//# sourceMappingURL=plugins.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugins.d.mts","names":[],"sources":["../src/services/pluginMaterializer/index.ts"],"mappings":";;UAsCiB;EACf,MAAM,QAAQ,iBAAiB,sBAAsB;EACrD,MAAM,QAAQ,iBAAiB,sBAAsB;;UAGtC;EACf,gBAAgB,QAAQ;;;wBAiQJ,yBACpB,kBAAkB,eAClB,UAAS,4BACR,QAAQ"}
|
package/dist/plugins.mjs
ADDED