import { type IntegrityCheckResult } from '../security/tool-integrity-monitor.js'; export type InstalledPluginsLookup = (shortName: string) => boolean; export type InstallScope = 'global' | 'project' | 'user'; export interface ProcessRunner { run(argv: string[], options?: { cwd?: string; }): Promise; } export declare class PluginInstallerService { private readonly runner; private readonly isPluginInstalled; constructor(runner: ProcessRunner, isPluginInstalled?: InstalledPluginsLookup); install(pluginRef: string, scope: InstallScope, integrity?: string, version?: string): Promise; installFromTarball(tgzPath: string, scope: InstallScope): Promise; uninstall(pluginRef: string, scope: InstallScope): void; private downloadRegistryTarball; private extractTarball; private installWithVisited; private materialize; private packLocalDirectory; } /** * Compute a sha256 SRI string for a tarball. Format matches the `integrity` * field of npm and the registry.json entries: "sha256-". */ export declare function computeTarballIntegrity(tgzPath: string): string; /** * Verify that a tarball's sha256 matches the expected SRI string from the * registry. Throws on mismatch — the caller is responsible for cleaning up. */ export declare function verifyTarballIntegrity(tgzPath: string, expected: string): void; /** * Walk the tarball entry list and refuse extraction if any entry is absolute * or contains a `..` segment. Tarslip mitigation independent of the host * `tar`'s default policy (which varies between BSD and GNU implementations). * * Name-only listing (`-tf`) is not enough on its own: a symlink or hardlink * entry can carry a perfectly safe-looking name while its link target points * anywhere on the host filesystem (another plugin's signing key, `/etc/passwd`, * etc.) — any later read through a manifest-declared path (codeEntrypoint, * validators[].module, ...) would follow that link. A FIFO entry is even * worse: a non-root tarball can create one, and reading it via `readFileSync` * with no writer on the other end blocks forever — a real denial of service. * A second, verbose listing (`-tvf`) exposes each entry's type via the * leading permission-string character (`-` regular file, `d` directory in * both GNU and BSD tar); anything else (symlink, hardlink, FIFO, socket, * device) is rejected. Allowlisting the two expected types, rather than * blocklisting each bad type as it's discovered, means a future/overlooked * special entry type is rejected by default. Checked separately from the name * scan below since parsing a real filename back out of the verbose columns is * unreliable (names may contain spaces). */ export declare function assertSafeTarball(tgzPath: string): void; export declare function peekTarballManifest(tgzPath: string): { name: string; version: string; }; export declare function resolvePackageName(input: string): string; export declare function shortNameFromPackage(packageName: string): string; /** * Fingerprint content for rug-pull detection: the manifest, its declared code * entrypoint, declared validator modules, the `hooks.json`/`mcps.json` files * themselves, and any script file their `command` fields reference — the * executable-surface files a plugin can ship. Covering only the JSON text * would let an update swap the referenced script's actual content (the code * that runs on every tool call, for hooks) without tripping a fingerprint * change at all. */ export declare function computePluginFingerprintContent(targetDir: string): string; /** * Fingerprint a plugin directory's content and compare it against the * last-known baseline for `plugin:${shortName}` — the same key format used * at install time, so a baseline set during install is found and compared * correctly here. Exported so `di/container.ts` can re-run this exact check * at plugin LOAD time (every `valora` startup), not just install time: * install-time-only checking left a tamper-after-install window where a * plugin's hooks.json/mcps.json/codeEntrypoint/validator modules could be * modified on disk after the one-time install check passed and would be * activated with full trust on every subsequent run, no re-verification. */ export declare function checkPluginContentDrift(pluginDir: string, shortName: string): IntegrityCheckResult; //# sourceMappingURL=plugin-installer.service.d.ts.map