

























@@ -1,5 +1,4 @@
11import { spawnSync } from "node:child_process";
2-import fs from "node:fs";
32import path from "node:path";
43import { fileURLToPath, pathToFileURL } from "node:url";
54import { createJiti } from "jiti";
@@ -54,143 +53,13 @@ function resolveRepoRoot(): string {
5453return path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
5554}
565557-function resolvePackageRoot(modulePath: string): string {
58-let cursor = path.dirname(path.resolve(modulePath));
59-while (true) {
60-if (fs.existsSync(path.join(cursor, "package.json"))) {
61-return cursor;
62-}
63-const parent = path.dirname(cursor);
64-if (parent === cursor) {
65-throw new Error(`package root not found for ${modulePath}`);
66-}
67-cursor = parent;
68-}
69-}
70-71-function shouldRetryViaIsolatedCopy(error: unknown): boolean {
72-if (!error || typeof error !== "object") {
73-return false;
74-}
75-const code = "code" in error ? error.code : undefined;
76-const message = "message" in error && typeof error.message === "string" ? error.message : "";
77-return code === "ERR_MODULE_NOT_FOUND" && message.includes(`${path.sep}node_modules${path.sep}`);
78-}
79-8056function isMissingExecutableError(error: unknown): boolean {
8157if (!error || typeof error !== "object") {
8258return false;
8359}
8460return "code" in error && error.code === "ENOENT";
8561}
866287-const SOURCE_FILE_EXTENSIONS = [".ts", ".tsx", ".mts", ".cts", ".js", ".jsx", ".mjs", ".cjs"];
88-89-function resolveImportCandidates(basePath: string): string[] {
90-const extension = path.extname(basePath);
91-const candidates = new Set<string>([basePath]);
92-if (extension) {
93-const stem = basePath.slice(0, -extension.length);
94-for (const sourceExtension of SOURCE_FILE_EXTENSIONS) {
95-candidates.add(`${stem}${sourceExtension}`);
96-}
97-} else {
98-for (const sourceExtension of SOURCE_FILE_EXTENSIONS) {
99-candidates.add(`${basePath}${sourceExtension}`);
100-candidates.add(path.join(basePath, `index${sourceExtension}`));
101-}
102-}
103-return Array.from(candidates);
104-}
105-106-function resolveRelativeImportPath(fromFile: string, specifier: string): string | null {
107-for (const candidate of resolveImportCandidates(
108-path.resolve(path.dirname(fromFile), specifier),
109-)) {
110-if (fs.existsSync(candidate) && fs.statSync(candidate).isFile()) {
111-return candidate;
112-}
113-}
114-return null;
115-}
116-117-function collectRelativeImportGraph(entryPath: string): Set<string> {
118-const discovered = new Set<string>();
119-const queue = [path.resolve(entryPath)];
120-const importPattern =
121-/(?:import|export)\s+(?:[^"'`]*?\s+from\s+)?["'`]([^"'`]+)["'`]|import\(\s*["'`]([^"'`]+)["'`]\s*\)/g;
122-123-while (queue.length > 0) {
124-const currentPath = queue.pop();
125-if (!currentPath || discovered.has(currentPath)) {
126-continue;
127-}
128-discovered.add(currentPath);
129-130-const source = fs.readFileSync(currentPath, "utf8");
131-for (const match of source.matchAll(importPattern)) {
132-const specifier = match[1] ?? match[2];
133-if (!specifier?.startsWith(".")) {
134-continue;
135-}
136-const resolved = resolveRelativeImportPath(currentPath, specifier);
137-if (resolved) {
138-queue.push(resolved);
139-}
140-}
141-}
142-143-return discovered;
144-}
145-146-function resolveCommonAncestor(paths: Iterable<string>): string {
147-const resolvedPaths = Array.from(paths, (entry) => path.resolve(entry));
148-const [first, ...rest] = resolvedPaths;
149-if (!first) {
150-throw new Error("cannot resolve common ancestor for empty path set");
151-}
152-let ancestor = first;
153-for (const candidate of rest) {
154-while (path.relative(ancestor, candidate).startsWith(`..${path.sep}`)) {
155-const parent = path.dirname(ancestor);
156-if (parent === ancestor) {
157-return ancestor;
158-}
159-ancestor = parent;
160-}
161-}
162-return ancestor;
163-}
164-165-function copyModuleImportGraphWithoutNodeModules(params: {
166-modulePath: string;
167-repoRoot: string;
168-}): {
169-copiedModulePath: string;
170-cleanup: () => void;
171-} {
172-const packageRoot = resolvePackageRoot(params.modulePath);
173-const relativeFiles = collectRelativeImportGraph(params.modulePath);
174-const copyRoot = resolveCommonAncestor([packageRoot, ...relativeFiles]);
175-const relativeModulePath = path.relative(copyRoot, params.modulePath);
176-const tempParent = path.join(params.repoRoot, ".openclaw-config-doc-cache");
177-fs.mkdirSync(tempParent, { recursive: true });
178-const isolatedRoot = fs.mkdtempSync(path.join(tempParent, `${path.basename(packageRoot)}-`));
179-180-for (const sourcePath of relativeFiles) {
181-const relativePath = path.relative(copyRoot, sourcePath);
182-const targetPath = path.join(isolatedRoot, relativePath);
183-fs.mkdirSync(path.dirname(targetPath), { recursive: true });
184-fs.copyFileSync(sourcePath, targetPath);
185-}
186-return {
187-copiedModulePath: path.join(isolatedRoot, relativeModulePath),
188-cleanup: () => {
189-fs.rmSync(isolatedRoot, { recursive: true, force: true });
190-},
191-};
192-}
193-19463export async function loadChannelConfigSurfaceModule(
19564modulePath: string,
19665options?: { repoRoot?: string },
@@ -300,20 +169,7 @@ export async function loadChannelConfigSurfaceModule(
300169return null;
301170};
302171303-try {
304-return loadFromPath(modulePath);
305-} catch (error) {
306-if (!shouldRetryViaIsolatedCopy(error)) {
307-throw error;
308-}
309-310-const isolatedCopy = copyModuleImportGraphWithoutNodeModules({ modulePath, repoRoot });
311-try {
312-return loadFromPath(isolatedCopy.copiedModulePath);
313-} finally {
314-isolatedCopy.cleanup();
315-}
316-}
172+return loadFromPath(modulePath);
317173}
318174319175if (import.meta.url === pathToFileURL(process.argv[1] ?? "").href) {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。