diff --git a/CHANGELOG.md b/CHANGELOG.md index bba04f97956..a38fbb2c44a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -112,6 +112,7 @@ Docs: https://docs.openclaw.ai - Feishu: keep streaming cards to one live card per turn, flush throttled card edits after meaningful text boundaries, and skip exact block/partial repeats so tool-heavy replies do not duplicate card output. Thanks @allan0509. - Feishu: finish the streaming-card duplicate closeout by stripping leaked reasoning tags, preserving cross-block partial snapshots, enabling topic-thread streaming cards, omitting the generic `main` card header, surfacing transient tool/compaction status, and cleaning streaming state after close failures. Thanks @sesame437, @Vicky-v7, @maoku-family, @Pengxiao-Wang, and @Maple778. - Telegram: recover incomplete partial-stream previews by falling back to a final send when an ambiguous final edit failure would otherwise retain a strict prefix of the answer. Fixes #71525. (#71554) Thanks @sahilsatralkar. +- Packaged installs: preserve package-root runtime dependencies and their exported subpaths when bundled plugin runtime mirrors fall back to copying shared chunks, fixing Windows npm updates that could fail to load copied `dist` modules. - Heartbeat: clamp oversized scheduler delays through the shared safe timer helper, preventing `every` values over Node's timeout cap from becoming a 1 ms crash loop. Fixes #71414. (#71478) Thanks @hclsys. - Control UI/chat: collapse assistant token/model context details behind an explicit Context disclosure and show full dates in message footers, making historical transcript timing clear without noisy default metadata. (#71337) Thanks @BunsDev. - OpenAI/Codex OAuth: explain `unsupported_country_region_territory` token-exchange failures with a proxy/region hint instead of surfacing a generic OAuth error. Fixes #51175. (#71501) Thanks @vincentkoc and @wulala-xjj. diff --git a/src/plugins/loader.test.ts b/src/plugins/loader.test.ts index 153d73bbfd6..189ece88510 100644 --- a/src/plugins/loader.test.ts +++ b/src/plugins/loader.test.ts @@ -1586,6 +1586,9 @@ module.exports = { ".": { import: "./index.js", }, + "./oauth": { + import: "./oauth.js", + }, }, }), "utf-8", @@ -1595,11 +1598,19 @@ module.exports = { "export default { marker: 'root-ok' };\n", "utf-8", ); + fs.writeFileSync( + path.join(packageDepRoot, "oauth.js"), + "export const oauthMarker = 'oauth-ok';\n", + "utf-8", + ); fs.writeFileSync( path.join(packageRoot, "dist", "manifest-support.js"), - [`import support from "root-support";`, `export const marker = support.marker;`, ""].join( - "\n", - ), + [ + `import support from "root-support";`, + `import { oauthMarker } from "root-support/oauth";`, + `export const marker = [support.marker, oauthMarker].join(":");`, + "", + ].join("\n"), "utf-8", ); fs.writeFileSync( diff --git a/src/plugins/loader.ts b/src/plugins/loader.ts index 13f5d8d5983..b686ac05f49 100644 --- a/src/plugins/loader.ts +++ b/src/plugins/loader.ts @@ -516,6 +516,35 @@ function resolveRuntimePackageImportTarget(exportsField: unknown): string | null return null; } +function collectRuntimePackageImportTargets( + pkg: RuntimeDependencyPackageJson, +): Map { + const targets = new Map(); + const exportsField = pkg.exports; + if ( + exportsField && + typeof exportsField === "object" && + !Array.isArray(exportsField) && + Object.keys(exportsField).some((key) => key.startsWith(".")) + ) { + for (const [exportKey, exportValue] of Object.entries(exportsField)) { + if (!exportKey.startsWith(".") || exportKey.includes("*")) { + continue; + } + const resolved = resolveRuntimePackageImportTarget(exportValue); + if (resolved) { + targets.set(exportKey, resolved); + } + } + return targets; + } + const rootEntry = resolveRuntimePackageImportTarget(exportsField) ?? pkg.module ?? pkg.main; + if (rootEntry) { + targets.set(".", rootEntry); + } + return targets; +} + function registerBundledRuntimeDependencyJitiAliases(rootDir: string): void { const rootPackageJson = readRuntimeDependencyPackageJson(path.join(rootDir, "package.json")); if (!rootPackageJson) { @@ -532,22 +561,19 @@ function registerBundledRuntimeDependencyJitiAliases(rootDir: string): void { if (!dependencyPackageJson) { continue; } - const entry = - resolveRuntimePackageImportTarget(dependencyPackageJson.exports) ?? - dependencyPackageJson.module ?? - dependencyPackageJson.main; - if (!entry || entry.startsWith("#")) { - continue; - } const dependencyRoot = path.dirname(dependencyPackageJsonPath); - const targetPath = path.resolve(dependencyRoot, entry); - if (!isPathInside(dependencyRoot, targetPath) || !fs.existsSync(targetPath)) { - continue; + for (const [exportKey, entry] of collectRuntimePackageImportTargets(dependencyPackageJson)) { + if (!entry || entry.startsWith("#")) { + continue; + } + const targetPath = path.resolve(dependencyRoot, entry); + if (!isPathInside(dependencyRoot, targetPath) || !fs.existsSync(targetPath)) { + continue; + } + const aliasKey = + exportKey === "." ? dependencyName : `${dependencyName}${exportKey.slice(1)}`; + bundledRuntimeDependencyJitiAliases.set(aliasKey, normalizeJitiAliasTargetPath(targetPath)); } - bundledRuntimeDependencyJitiAliases.set( - dependencyName, - normalizeJitiAliasTargetPath(targetPath), - ); } }