





















@@ -244,6 +244,28 @@ function writePluginEntry(root: string, relativePath: string) {
244244return pluginEntry;
245245}
246246247+function writeInstalledPluginEntry(params: {
248+installRoot: string;
249+packageName: string;
250+entry?: string;
251+}) {
252+const entry = params.entry ?? "dist/index.js";
253+const packageRoot = path.join(
254+params.installRoot,
255+"node_modules",
256+ ...params.packageName.split("/"),
257+);
258+const pluginEntry = path.join(packageRoot, entry);
259+mkdirSafeDir(path.dirname(pluginEntry));
260+fs.writeFileSync(
261+path.join(packageRoot, "package.json"),
262+JSON.stringify({ name: params.packageName, type: "module" }, null, 2),
263+"utf-8",
264+);
265+fs.writeFileSync(pluginEntry, 'export const plugin = "installed";\n', "utf-8");
266+return { packageRoot, pluginEntry };
267+}
268+247269function createUserInstalledPluginSdkAliasFixture() {
248270const { fixture, sourcePluginEntryPath, sourceRootAlias, sourceChannelRuntimePath } =
249271createPluginSdkAliasTargetFixture();
@@ -631,16 +653,15 @@ describe("plugin sdk alias helpers", () => {
631653expect(subpaths).toEqual(["core", "qa-channel", "qa-channel-protocol", "qa-lab", "qa-runtime"]);
632654});
633655634-it("adds the non-QA private Codex task runtime subpath only for bundled Codex", () => {
656+it("adds the non-QA private Codex task runtime subpath only for trusted Codex plugins", () => {
635657const fixture = createPluginSdkAliasFixture({
636658packageExports: {
637659"./plugin-sdk/core": { default: "./dist/plugin-sdk/core.js" },
638660},
639661});
640-fs.writeFileSync(
662+fs.rmSync(
641663path.join(fixture.root, "scripts", "lib", "plugin-sdk-private-local-only-subpaths.json"),
642-JSON.stringify(["codex-native-task-runtime", "qa-runtime"], null, 2),
643-"utf-8",
664+{ force: true },
644665);
645666fs.writeFileSync(
646667path.join(fixture.root, "src", "plugin-sdk", "codex-native-task-runtime.ts"),
@@ -660,6 +681,25 @@ describe("plugin sdk alias helpers", () => {
660681fixture.root,
661682bundledPluginFile("demo", "src/index.ts"),
662683);
684+const { packageRoot: installedCodexRoot, pluginEntry: installedCodexEntry } =
685+writeInstalledPluginEntry({
686+installRoot: path.join(makeTempDir(), ".openclaw", "npm"),
687+packageName: "@openclaw/codex",
688+});
689+const { packageRoot: installedOtherRoot, pluginEntry: installedOtherEntry } =
690+writeInstalledPluginEntry({
691+installRoot: path.join(makeTempDir(), ".openclaw", "npm"),
692+packageName: "@openclaw/demo",
693+});
694+const shadowCodexRoot = path.join(makeTempDir(), ".openclaw", "extensions", "codex-shadow");
695+const shadowCodexEntry = path.join(shadowCodexRoot, "dist", "index.js");
696+mkdirSafeDir(path.dirname(shadowCodexEntry));
697+fs.writeFileSync(
698+path.join(shadowCodexRoot, "package.json"),
699+JSON.stringify({ name: "@openclaw/codex", type: "module" }, null, 2),
700+"utf-8",
701+);
702+fs.writeFileSync(shadowCodexEntry, 'export const plugin = "shadow";\n', "utf-8");
663703664704const codexSubpaths = withEnv({ OPENCLAW_ENABLE_PRIVATE_QA_CLI: undefined }, () =>
665705listPluginSdkExportedSubpaths({
@@ -671,9 +711,36 @@ describe("plugin sdk alias helpers", () => {
671711modulePath: sourceOtherEntry,
672712}),
673713);
714+const installedCodexSubpaths = withCwd(installedCodexRoot, () =>
715+withEnv({ OPENCLAW_ENABLE_PRIVATE_QA_CLI: undefined }, () =>
716+listPluginSdkExportedSubpaths({
717+modulePath: installedCodexEntry,
718+argv1: path.join(fixture.root, "openclaw.mjs"),
719+}),
720+),
721+);
722+const installedOtherSubpaths = withCwd(installedOtherRoot, () =>
723+withEnv({ OPENCLAW_ENABLE_PRIVATE_QA_CLI: undefined }, () =>
724+listPluginSdkExportedSubpaths({
725+modulePath: installedOtherEntry,
726+argv1: path.join(fixture.root, "openclaw.mjs"),
727+}),
728+),
729+);
730+const shadowCodexSubpaths = withCwd(shadowCodexRoot, () =>
731+withEnv({ OPENCLAW_ENABLE_PRIVATE_QA_CLI: undefined }, () =>
732+listPluginSdkExportedSubpaths({
733+modulePath: shadowCodexEntry,
734+argv1: path.join(fixture.root, "openclaw.mjs"),
735+}),
736+),
737+);
674738675739expect(codexSubpaths).toEqual(["codex-native-task-runtime", "core"]);
740+expect(installedCodexSubpaths).toEqual(["codex-native-task-runtime", "core"]);
676741expect(otherSubpaths).toEqual(["core"]);
742+expect(installedOtherSubpaths).toEqual(["core"]);
743+expect(shadowCodexSubpaths).toEqual(["core"]);
677744});
678745679746it("does not reuse a non-private cached subpath list after private qa gets enabled", () => {
@@ -844,7 +911,7 @@ describe("plugin sdk alias helpers", () => {
844911);
845912});
846913847-it("aliases non-QA private plugin-sdk subpaths for bundled runtime source loading", () => {
914+it("aliases non-QA private plugin-sdk subpaths for trusted Codex runtime loading", () => {
848915const fixture = createPluginSdkAliasFixture({
849916packageExports: {
850917"./plugin-sdk/core": { default: "./dist/plugin-sdk/core.js" },
@@ -857,18 +924,30 @@ describe("plugin sdk alias helpers", () => {
857924"plugin-sdk",
858925"codex-native-task-runtime.ts",
859926);
927+const distRootAlias = path.join(fixture.root, "dist", "plugin-sdk", "root-alias.cjs");
928+const distCodexNativeTaskRuntimePath = path.join(
929+fixture.root,
930+"dist",
931+"plugin-sdk",
932+"codex-native-task-runtime.js",
933+);
860934const sourceQaRuntimePath = path.join(fixture.root, "src", "plugin-sdk", "qa-runtime.ts");
861935fs.writeFileSync(sourceRootAlias, "module.exports = {};\n", "utf-8");
862-fs.writeFileSync(
936+fs.writeFileSync(distRootAlias, "module.exports = {};\n", "utf-8");
937+fs.rmSync(
863938path.join(fixture.root, "scripts", "lib", "plugin-sdk-private-local-only-subpaths.json"),
864-JSON.stringify(["codex-native-task-runtime", "qa-runtime"], null, 2),
865-"utf-8",
939+{ force: true },
866940);
867941fs.writeFileSync(
868942sourceCodexNativeTaskRuntimePath,
869943"export const codexNativeTaskRuntime = true;\n",
870944"utf-8",
871945);
946+fs.writeFileSync(
947+distCodexNativeTaskRuntimePath,
948+"export const codexNativeTaskRuntime = true;\n",
949+"utf-8",
950+);
872951fs.writeFileSync(sourceQaRuntimePath, "export const qaRuntime = true;\n", "utf-8");
873952const sourcePluginEntry = writePluginEntry(
874953fixture.root,
@@ -878,6 +957,25 @@ describe("plugin sdk alias helpers", () => {
878957fixture.root,
879958bundledPluginFile("demo", "src/index.ts"),
880959);
960+const { packageRoot: installedCodexRoot, pluginEntry: installedCodexEntry } =
961+writeInstalledPluginEntry({
962+installRoot: path.join(makeTempDir(), ".openclaw", "npm"),
963+packageName: "@openclaw/codex",
964+});
965+const { packageRoot: installedOtherRoot, pluginEntry: installedOtherEntry } =
966+writeInstalledPluginEntry({
967+installRoot: path.join(makeTempDir(), ".openclaw", "npm"),
968+packageName: "@openclaw/demo",
969+});
970+const shadowCodexRoot = path.join(makeTempDir(), ".openclaw", "extensions", "codex-shadow");
971+const shadowCodexEntry = path.join(shadowCodexRoot, "dist", "index.js");
972+mkdirSafeDir(path.dirname(shadowCodexEntry));
973+fs.writeFileSync(
974+path.join(shadowCodexRoot, "package.json"),
975+JSON.stringify({ name: "@openclaw/codex", type: "module" }, null, 2),
976+"utf-8",
977+);
978+fs.writeFileSync(shadowCodexEntry, 'export const plugin = "shadow";\n', "utf-8");
881979882980const aliases = withEnv(
883981{ OPENCLAW_ENABLE_PRIVATE_QA_CLI: undefined, NODE_ENV: undefined },
@@ -887,15 +985,50 @@ describe("plugin sdk alias helpers", () => {
887985{ OPENCLAW_ENABLE_PRIVATE_QA_CLI: undefined, NODE_ENV: undefined },
888986() => buildPluginLoaderAliasMap(sourceOtherPluginEntry),
889987);
988+const installedAliases = withCwd(installedCodexRoot, () =>
989+withEnv({ OPENCLAW_ENABLE_PRIVATE_QA_CLI: undefined, NODE_ENV: undefined }, () =>
990+buildPluginLoaderAliasMap(
991+installedCodexEntry,
992+path.join(fixture.root, "openclaw.mjs"),
993+undefined,
994+"dist",
995+),
996+),
997+);
998+const shadowCodexAliases = withCwd(shadowCodexRoot, () =>
999+withEnv({ OPENCLAW_ENABLE_PRIVATE_QA_CLI: undefined, NODE_ENV: undefined }, () =>
1000+buildPluginLoaderAliasMap(
1001+shadowCodexEntry,
1002+path.join(fixture.root, "openclaw.mjs"),
1003+undefined,
1004+"dist",
1005+),
1006+),
1007+);
1008+const installedOtherAliases = withCwd(installedOtherRoot, () =>
1009+withEnv({ OPENCLAW_ENABLE_PRIVATE_QA_CLI: undefined, NODE_ENV: undefined }, () =>
1010+buildPluginLoaderAliasMap(
1011+installedOtherEntry,
1012+path.join(fixture.root, "openclaw.mjs"),
1013+undefined,
1014+"dist",
1015+),
1016+),
1017+);
89010188911019expect(fs.realpathSync(aliases["openclaw/plugin-sdk"] ?? "")).toBe(
8921020fs.realpathSync(sourceRootAlias),
8931021);
8941022expect(fs.realpathSync(aliases["openclaw/plugin-sdk/codex-native-task-runtime"] ?? "")).toBe(
8951023fs.realpathSync(sourceCodexNativeTaskRuntimePath),
8961024);
1025+expect(
1026+fs.realpathSync(installedAliases["openclaw/plugin-sdk/codex-native-task-runtime"] ?? ""),
1027+).toBe(fs.realpathSync(distCodexNativeTaskRuntimePath));
8971028expect(aliases["openclaw/plugin-sdk/qa-runtime"]).toBeUndefined();
8981029expect(otherAliases["openclaw/plugin-sdk/codex-native-task-runtime"]).toBeUndefined();
1030+expect(installedOtherAliases["openclaw/plugin-sdk/codex-native-task-runtime"]).toBeUndefined();
1031+expect(shadowCodexAliases["openclaw/plugin-sdk/codex-native-task-runtime"]).toBeUndefined();
8991032});
90010339011034it("applies explicit dist resolution to plugin-sdk subpath aliases too", () => {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。