




















@@ -14,6 +14,7 @@ import { resolveDefaultPluginExtensionsDir } from "../plugins/install-paths.js";
1414import type { InstallSafetyOverrides } from "../plugins/install-security-scan.js";
1515import {
1616PLUGIN_INSTALL_ERROR_CODE,
17+installPluginFromNpmPackArchive,
1718installPluginFromNpmSpec,
1819installPluginFromPath,
1920} from "../plugins/install.js";
@@ -49,6 +50,7 @@ import {
4950createHookPackInstallLogger,
5051createPluginInstallLogger,
5152formatPluginInstallWithHookFallbackError,
53+parseNpmPackPrefixPath,
5254parseNpmPrefixSpec,
5355} from "./plugins-command-helpers.js";
5456import { persistHookPackInstall, persistPluginInstall } from "./plugins-install-persist.js";
@@ -379,6 +381,54 @@ async function tryInstallPluginOrHookPackFromNpmSpec(params: {
379381return { ok: true };
380382}
381383384+async function tryInstallPluginFromNpmPackArchive(params: {
385+snapshot: ConfigSnapshotForInstallPersist;
386+installMode: "install" | "update";
387+archivePath: string;
388+safetyOverrides: InstallSafetyOverrides;
389+extensionsDir: string;
390+runtime?: RuntimeEnv;
391+}): Promise<{ ok: true } | { ok: false }> {
392+const result = await installPluginFromNpmPackArchive({
393+ ...params.safetyOverrides,
394+mode: params.installMode,
395+archivePath: params.archivePath,
396+extensionsDir: params.extensionsDir,
397+logger: createPluginInstallLogger(params.runtime),
398+});
399+if (!result.ok) {
400+(params.runtime ?? defaultRuntime).error(result.error);
401+return { ok: false };
402+}
403+404+await persistPluginInstall({
405+snapshot: params.snapshot,
406+pluginId: result.pluginId,
407+install: {
408+source: "npm",
409+spec: result.npmResolution?.resolvedSpec ?? result.manifestName ?? result.pluginId,
410+sourcePath: params.archivePath,
411+installPath: result.targetDir,
412+ ...(result.version ? { version: result.version } : {}),
413+ ...(result.npmResolution?.name ? { resolvedName: result.npmResolution.name } : {}),
414+ ...(result.npmResolution?.version ? { resolvedVersion: result.npmResolution.version } : {}),
415+ ...(result.npmResolution?.resolvedSpec
416+ ? { resolvedSpec: result.npmResolution.resolvedSpec }
417+ : {}),
418+ ...(result.npmResolution?.integrity ? { integrity: result.npmResolution.integrity } : {}),
419+ ...(result.npmResolution?.shasum ? { shasum: result.npmResolution.shasum } : {}),
420+ ...(result.npmResolution?.resolvedAt ? { resolvedAt: result.npmResolution.resolvedAt } : {}),
421+artifactKind: "npm-pack",
422+artifactFormat: "tgz",
423+ ...(result.npmResolution?.integrity ? { npmIntegrity: result.npmResolution.integrity } : {}),
424+ ...(result.npmResolution?.shasum ? { npmShasum: result.npmResolution.shasum } : {}),
425+ ...(result.npmTarballName ? { npmTarballName: result.npmTarballName } : {}),
426+},
427+runtime: params.runtime,
428+});
429+return { ok: true };
430+}
431+382432async function tryInstallPluginFromGitSpec(params: {
383433snapshot: ConfigSnapshotForInstallPersist;
384434installMode: "install" | "update";
@@ -753,6 +803,26 @@ export async function runPluginInstallCommand(params: {
753803return;
754804}
755805806+const npmPackPath = parseNpmPackPrefixPath(raw);
807+if (npmPackPath !== null) {
808+if (!npmPackPath) {
809+runtime.error("unsupported npm-pack: spec: missing pack archive path");
810+return runtime.exit(1);
811+}
812+const npmPackResult = await tryInstallPluginFromNpmPackArchive({
813+ snapshot,
814+ installMode,
815+archivePath: npmPackPath,
816+ safetyOverrides,
817+ extensionsDir,
818+ runtime,
819+});
820+if (!npmPackResult.ok) {
821+return runtime.exit(1);
822+}
823+return;
824+}
825+756826if (gitSpec) {
757827const gitResult = await tryInstallPluginFromGitSpec({
758828 snapshot,
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。