mirror of
https://github.com/openclaw/openclaw.git
synced 2026-10-03 01:29:56 +00:00
fix(build): package preparation fails on unrelated test types (#157318)
* fix(build): bound standalone package declaration graphs Co-authored-by: steipete <58493+steipete@users.noreply.github.com> * fix(build): migrate declaration producer audit and fixture consumers Derive public audit roots from the existing canonical export mapper and supply the editor augmentation graph to maintained lint fixtures. Keep producer entries, public exports, diagnostics and runtime behavior unchanged. Co-authored-by: steipete <58493+steipete@users.noreply.github.com> --------- Co-authored-by: steipete <58493+steipete@users.noreply.github.com>
This commit is contained in:
parent
67384b481a
commit
5ae011b735
27 changed files with 503 additions and 193 deletions
|
|
@ -6,6 +6,7 @@ import path from "node:path";
|
|||
import { collectPluginSourceEntries } from "../scripts/lib/bundled-plugin-build-entries.mjs";
|
||||
import { createManagedHandoffBuildConfig } from "../scripts/lib/managed-handoff-build-config.mts";
|
||||
import { runtimeProcessBuildEntries } from "../scripts/lib/runtime-process-build-entries.mts";
|
||||
import { buildPackageDistEntriesFromExports } from "../scripts/lib/workspace-package-entries.mts";
|
||||
import { controlUiSource } from "../src/plugins/package-manifest.js";
|
||||
|
||||
const BUNDLED_PLUGIN_ROOT_DIR = "extensions";
|
||||
|
|
@ -538,6 +539,20 @@ const rootToolingAndWorkspaceDependencies = [
|
|||
"string-width",
|
||||
] as const;
|
||||
|
||||
function workspacePackage(packageDir: string, extraEntries: readonly string[] = []) {
|
||||
const workspace = path.join("packages", packageDir);
|
||||
return {
|
||||
// Package exports, not shell arguments, own these public source entrypoints.
|
||||
entry: [
|
||||
...Object.values(buildPackageDistEntriesFromExports(packageDir)).map(
|
||||
(source) => path.relative(workspace, source).replaceAll("\\", "/") + "!",
|
||||
),
|
||||
...extraEntries,
|
||||
],
|
||||
project: ["src/**/*.ts!"],
|
||||
} as const;
|
||||
}
|
||||
|
||||
function bundledPluginWorkspace(extraEntries: readonly string[] = []) {
|
||||
return {
|
||||
entry: [...bundledPluginEntries, ...extraEntries],
|
||||
|
|
@ -743,10 +758,7 @@ const config = {
|
|||
],
|
||||
project: ["src/**/*.ts!"],
|
||||
},
|
||||
"packages/sdk": {
|
||||
entry: ["src/index.ts!"],
|
||||
project: ["src/**/*.ts!"],
|
||||
},
|
||||
"packages/sdk": workspacePackage("sdk"),
|
||||
"packages/agent-core": {
|
||||
entry: [
|
||||
"src/index.ts!",
|
||||
|
|
@ -763,132 +775,21 @@ const config = {
|
|||
],
|
||||
project: ["src/**/*.ts!"],
|
||||
},
|
||||
"packages/gateway-client": {
|
||||
// Mirror package.json exports; these subpaths are published surfaces.
|
||||
entry: ["src/index.ts!", "src/readiness.ts!", "src/timeouts.ts!"],
|
||||
project: ["src/**/*.ts!"],
|
||||
},
|
||||
"packages/gateway-protocol": {
|
||||
// Mirror package.json exports; these subpaths are published surfaces.
|
||||
entry: [
|
||||
"src/index.ts!",
|
||||
"src/client-info.ts!",
|
||||
"src/connect-error-details.ts!",
|
||||
"src/frame-guards.ts!",
|
||||
"src/schema.ts!",
|
||||
"src/startup-unavailable.ts!",
|
||||
"src/version.ts!",
|
||||
],
|
||||
project: ["src/**/*.ts!"],
|
||||
},
|
||||
"packages/model-catalog-core": {
|
||||
// Mirror the published export map so package-owned runtime dependencies
|
||||
// are traced from the TypeScript sources instead of the JS fallback.
|
||||
entry: [
|
||||
"src/index.ts!",
|
||||
"src/configured-model-refs.ts!",
|
||||
"src/model-catalog-normalize.ts!",
|
||||
"src/model-catalog-refs.ts!",
|
||||
"src/model-catalog-types.ts!",
|
||||
"src/provider-id.ts!",
|
||||
"src/provider-model-id-normalization.ts!",
|
||||
"src/provider-model-id-normalize.ts!",
|
||||
],
|
||||
project: ["src/**/*.ts!"],
|
||||
},
|
||||
"packages/normalization-core": {
|
||||
// Mirror package.json exports; root and UI builds consume these source subpaths directly.
|
||||
entry: [
|
||||
"src/index.ts!",
|
||||
"src/agent-id.ts!",
|
||||
"src/boolean-coercion.ts!",
|
||||
"src/browser-error-runtime.ts!",
|
||||
"src/error-coercion.ts!",
|
||||
"src/expect.ts!",
|
||||
"src/json-coercion.ts!",
|
||||
"src/number-coercion.ts!",
|
||||
"src/phone-presentation.ts!",
|
||||
"src/record-coerce.ts!",
|
||||
"src/result.ts!",
|
||||
"src/string-coerce.ts!",
|
||||
"src/string-normalization.ts!",
|
||||
"src/utf16-slice.ts!",
|
||||
],
|
||||
project: ["src/**/*.ts!"],
|
||||
},
|
||||
"packages/net-policy": {
|
||||
entry: ["src/index.ts!", "src/ip.ts!"],
|
||||
project: ["src/**/*.ts!"],
|
||||
},
|
||||
"packages/markdown-core": {
|
||||
entry: [
|
||||
"src/index.ts!",
|
||||
"src/code-spans.ts!",
|
||||
"src/fences.ts!",
|
||||
"src/frontmatter.ts!",
|
||||
"src/ir.ts!",
|
||||
"src/render.ts!",
|
||||
"src/render-aware-chunking.ts!",
|
||||
"src/tables.ts!",
|
||||
"src/types.ts!",
|
||||
],
|
||||
project: ["src/**/*.ts!"],
|
||||
},
|
||||
"packages/media-core": {
|
||||
entry: [
|
||||
"src/index.ts!",
|
||||
"src/attachment-classify.ts!",
|
||||
"src/base64.ts!",
|
||||
"src/constants.ts!",
|
||||
"src/content-length.ts!",
|
||||
"src/file-name.ts!",
|
||||
"src/inbound-path-policy.ts!",
|
||||
"src/inline-image-data-url.ts!",
|
||||
"src/media-source-url.ts!",
|
||||
"src/mime.ts!",
|
||||
"src/read-byte-stream-with-limit.ts!",
|
||||
],
|
||||
project: ["src/**/*.ts!"],
|
||||
},
|
||||
"packages/acp-core": {
|
||||
entry: [
|
||||
"src/index.ts!",
|
||||
"src/meta.ts!",
|
||||
"src/session.ts!",
|
||||
"src/session-interaction-mode.ts!",
|
||||
"src/session-lineage-meta.ts!",
|
||||
"src/types.ts!",
|
||||
"src/runtime/error-text.ts!",
|
||||
"src/runtime/errors.ts!",
|
||||
"src/runtime/session-identifiers.ts!",
|
||||
"src/runtime/session-identity.ts!",
|
||||
"src/runtime/types.ts!",
|
||||
],
|
||||
project: ["src/**/*.ts!"],
|
||||
},
|
||||
"packages/terminal-core": {
|
||||
entry: [
|
||||
"src/index.ts!",
|
||||
"src/ansi.ts!",
|
||||
"src/decorative-emoji.ts!",
|
||||
"src/health-style.ts!",
|
||||
"src/links.ts!",
|
||||
"src/note.ts!",
|
||||
"src/osc-progress.ts!",
|
||||
"src/palette.ts!",
|
||||
"src/progress-line.ts!",
|
||||
"src/prompt-select-styled.ts!",
|
||||
"src/prompt-select-styled-params.ts!",
|
||||
"src/prompt-style.ts!",
|
||||
"src/restore.ts!",
|
||||
"src/safe-text.ts!",
|
||||
"src/stream-writer.ts!",
|
||||
"src/table.ts!",
|
||||
"src/terminal-link.ts!",
|
||||
"src/theme.ts!",
|
||||
],
|
||||
project: ["src/**/*.ts!"],
|
||||
},
|
||||
"packages/gateway-client": workspacePackage("gateway-client"),
|
||||
"packages/gateway-protocol": workspacePackage("gateway-protocol"),
|
||||
"packages/model-catalog-core": workspacePackage("model-catalog-core"),
|
||||
"packages/normalization-core": workspacePackage("normalization-core", [
|
||||
// extensions/qa-lab/web/vite.config.ts aliases error-runtime to this private browser implementation.
|
||||
"src/browser-error-runtime.ts!",
|
||||
]),
|
||||
"packages/net-policy": workspacePackage("net-policy"),
|
||||
"packages/markdown-core": workspacePackage("markdown-core"),
|
||||
"packages/media-core": workspacePackage("media-core"),
|
||||
"packages/acp-core": workspacePackage("acp-core"),
|
||||
"packages/terminal-core": workspacePackage("terminal-core"),
|
||||
"packages/retry": workspacePackage("retry"),
|
||||
"packages/media-generation-core": workspacePackage("media-generation-core"),
|
||||
"packages/media-understanding-common": workspacePackage("media-understanding-common"),
|
||||
"packages/memory-host-sdk": {
|
||||
entry: ["src/*.ts!", "src/host/embeddings.types.ts!"],
|
||||
project: ["src/**/*.ts!"],
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
{
|
||||
"extends": "../tsconfig.json",
|
||||
// This editor/lint graph includes tests; retain their compatibility augmentation.
|
||||
"files": ["../src/config/sessions/session-entry.test-compat.d.ts"],
|
||||
"include": [
|
||||
"../src/**/*.d.ts",
|
||||
"../ui/**/*.d.ts",
|
||||
|
|
|
|||
|
|
@ -69,6 +69,6 @@
|
|||
"@openclaw/normalization-core": "workspace:*"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsdown src/index.ts src/error-format.ts src/meta.ts src/session.ts src/session-interaction-mode.ts src/session-lineage-meta.ts src/types.ts src/runtime/error-text.ts src/runtime/errors.ts src/runtime/session-identifiers.ts src/runtime/session-identity.ts src/runtime/types.ts --no-config --platform node --format esm --dts --out-dir dist --clean"
|
||||
"build": "node --import ../../scripts/tsx.mjs ../../scripts/build-workspace-package.mts acp-core"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@
|
|||
}
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsdown src/index.ts src/browser.ts src/readiness.ts src/scope-upgrade.ts src/timeouts.ts src/websocket-data.ts --no-config --platform node --format esm --dts --out-dir dist --clean"
|
||||
"build": "node --import ../../scripts/tsx.mjs ../../scripts/build-workspace-package.mts gateway-client"
|
||||
},
|
||||
"dependencies": {
|
||||
"@openclaw/gateway-protocol": "workspace:*",
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@
|
|||
}
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsdown src/index.ts src/client-info.ts src/connect-error-details.ts src/frame-guards.ts src/gateway-error-details.ts src/restart-unavailable.ts src/schema.ts src/startup-unavailable.ts src/version.ts src/system-agent-context.ts src/theme.ts --no-config --platform node --format esm --dts --out-dir dist --clean && node --import tsx ../../scripts/check-protocol-registry-types.mts",
|
||||
"build": "node --import ../../scripts/tsx.mjs ../../scripts/build-workspace-package.mts gateway-protocol && node --import tsx ../../scripts/check-protocol-registry-types.mts",
|
||||
"prepack": "pnpm run build && node --import tsx ../../scripts/protocol-gen.ts --out ./protocol.schema.json"
|
||||
},
|
||||
"dependencies": {
|
||||
|
|
|
|||
|
|
@ -70,6 +70,6 @@
|
|||
"file-type": "22.1.0"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsdown src/index.ts src/attachment-classify.ts src/base64.ts src/constants.ts src/content-length.ts src/file-name.ts src/inbound-path-policy.ts src/inline-image-data-url.ts src/media-source-url.ts src/mime.ts src/read-byte-stream-with-limit.ts --no-config --platform node --format esm --dts --out-dir dist --clean"
|
||||
"build": "node --import ../../scripts/tsx.mjs ../../scripts/build-workspace-package.mts media-core"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,6 +39,6 @@
|
|||
}
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsdown src/index.ts src/capability-model-ref.ts src/catalog.ts src/model-ref.ts src/normalization.ts --no-config --platform node --format esm --dts --out-dir dist --clean"
|
||||
"build": "node --import ../../scripts/tsx.mjs ../../scripts/build-workspace-package.mts media-generation-core"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,6 +59,6 @@
|
|||
}
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsdown src/active-model.ts src/defaults.ts src/errors.ts src/format.ts src/openai-compatible-video.ts src/output-extract.ts src/provider-id.ts src/provider-supports.ts src/types.ts src/video.ts --no-config --platform node --format esm --dts --out-dir dist --clean"
|
||||
"build": "node --import ../../scripts/tsx.mjs ../../scripts/build-workspace-package.mts media-understanding-common"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@
|
|||
}
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsdown src/index.ts src/ip.ts src/ipv4.ts src/redact-sensitive-url.ts src/url-protocol.ts src/url-userinfo.ts --no-config --platform node --format esm --dts --out-dir dist --clean"
|
||||
"build": "node --import ../../scripts/tsx.mjs ../../scripts/build-workspace-package.mts net-policy"
|
||||
},
|
||||
"dependencies": {
|
||||
"@openclaw/normalization-core": "workspace:*",
|
||||
|
|
|
|||
|
|
@ -136,7 +136,7 @@
|
|||
}
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsdown src/index.ts src/agent-id.ts src/agent-run-terminal-outcome.ts src/boolean-coercion.ts src/cjk-chars.ts src/code-points.ts src/error-coercion.ts src/expect.ts src/grapheme.ts src/home-dir.ts src/json-coercion.ts src/json-schema.ts src/markdown-plain-text.ts src/mountinfo-path.ts src/node-crypto.ts src/number-coercion.ts src/phone-presentation.ts src/promise-like.ts src/record-coerce.ts src/result.ts src/stable-node-path.ts src/stable-stringify.ts src/string-coerce.ts src/string-normalization.ts src/utf16-slice.ts --no-config --platform node --format esm --dts --out-dir dist --clean"
|
||||
"build": "node --import ../../scripts/tsx.mjs ../../scripts/build-workspace-package.mts normalization-core"
|
||||
},
|
||||
"dependencies": {
|
||||
"libphonenumber-js": "1.13.13",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import fs from "node:fs";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { buildPackageDistEntriesFromExports } from "../../../scripts/lib/workspace-package-entries.mts";
|
||||
|
||||
type PackageManifest = {
|
||||
exports: Record<
|
||||
|
|
@ -19,6 +20,11 @@ const manifest = JSON.parse(fs.readFileSync(packageJsonPath, "utf8")) as Package
|
|||
|
||||
describe("normalization-core package exports", () => {
|
||||
it("builds every focused export from its matching source entry", () => {
|
||||
const entries = buildPackageDistEntriesFromExports("normalization-core");
|
||||
expect(manifest.scripts.build.split(/\s+/u).slice(-2)).toEqual([
|
||||
"../../scripts/build-workspace-package.mts",
|
||||
"normalization-core",
|
||||
]);
|
||||
for (const [subpath, target] of Object.entries(manifest.exports)) {
|
||||
const entryName = subpath === "." ? "index" : subpath.slice(2);
|
||||
expect(target).toEqual({
|
||||
|
|
@ -26,7 +32,9 @@ describe("normalization-core package exports", () => {
|
|||
import: `./dist/${entryName}.mjs`,
|
||||
default: `./dist/${entryName}.mjs`,
|
||||
});
|
||||
expect(manifest.scripts.build.split(/\s+/u)).toContain(`src/${entryName}.ts`);
|
||||
const source = `packages/normalization-core/src/${entryName}.ts`;
|
||||
expect(entries[entryName]).toBe(source);
|
||||
expect(fs.existsSync(source)).toBe(true);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -16,6 +16,6 @@
|
|||
}
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsdown src/index.ts --no-config --platform node --format esm --dts --out-dir dist --clean"
|
||||
"build": "node --import ../../scripts/tsx.mjs ../../scripts/build-workspace-package.mts retry"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
}
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsdown src/index.ts --no-config --platform node --format esm --dts --out-dir dist --clean"
|
||||
"build": "node --import ../../scripts/tsx.mjs ../../scripts/build-workspace-package.mts sdk"
|
||||
},
|
||||
"dependencies": {
|
||||
"@openclaw/gateway-client": "workspace:*",
|
||||
|
|
|
|||
109
scripts/build-workspace-package.mts
Normal file
109
scripts/build-workspace-package.mts
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
// Standalone package builds share the root build's entry and declaration ownership.
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import type { InlineConfig, PackageJsonWithPath, UserConfig } from "tsdown";
|
||||
import { isDirectRunUrl } from "./lib/direct-run.mjs";
|
||||
import { withDistArtifactOwnership } from "./lib/dist-artifact-ownership.mts";
|
||||
import { resolveRepoRoot } from "./lib/repo-root.mjs";
|
||||
import { tsdownPackageOutputRoot } from "./lib/tsdown-output-roots.mts";
|
||||
import { cleanTsdownOutputRoots, sanitizeTsdownBuildOutputRoots } from "./tsdown-build.mts";
|
||||
|
||||
export function selectWorkspacePackageBuildConfig(
|
||||
configs: UserConfig[],
|
||||
packageName: string,
|
||||
target: string | false,
|
||||
): InlineConfig {
|
||||
const outDir = tsdownPackageOutputRoot(packageName);
|
||||
const selected = configs.filter((config) => config.outDir === outDir);
|
||||
if (selected.length !== 1) {
|
||||
throw new Error(`Expected one build config for ${packageName}; found ${selected.length}`);
|
||||
}
|
||||
return {
|
||||
...selected[0],
|
||||
config: false,
|
||||
clean: false,
|
||||
dts: true,
|
||||
platform: "node",
|
||||
format: "esm",
|
||||
target,
|
||||
concurrency: 1,
|
||||
// Application folding and dependency policy do not belong to standalone libraries.
|
||||
env: {},
|
||||
deps: {},
|
||||
inputOptions: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
export async function buildWorkspacePackage(packageName: string) {
|
||||
const root = resolveRepoRoot(import.meta.url);
|
||||
const output = tsdownPackageOutputRoot(packageName);
|
||||
const packageJsonPath = path.join(root, "packages", packageName, "package.json");
|
||||
const manifest: PackageJsonWithPath = {
|
||||
...JSON.parse(fs.readFileSync(packageJsonPath, "utf8")),
|
||||
packageJsonPath,
|
||||
};
|
||||
const { minVersion } = await import("semver");
|
||||
const nodeEngine = manifest.engines?.node;
|
||||
const nodeVersion = nodeEngine ? minVersion(nodeEngine) : null;
|
||||
if (nodeEngine && !nodeVersion) {
|
||||
throw new Error(`Invalid Node engine for ${packageName}`);
|
||||
}
|
||||
const previousCwd = process.cwd();
|
||||
process.chdir(root);
|
||||
try {
|
||||
// The canonical config reads manifests relative to the repository root.
|
||||
const { default: configs } = await import("../tsdown.config.ts");
|
||||
const config = selectWorkspacePackageBuildConfig(
|
||||
configs,
|
||||
packageName,
|
||||
// No engine means no transformation, as in the package-local tsdown CLI.
|
||||
nodeVersion ? `node${nodeVersion.version}` : false,
|
||||
);
|
||||
const canonicalHooks = config.hooks;
|
||||
config.hooks = async (hooks) => {
|
||||
if (typeof canonicalHooks === "function") {
|
||||
await canonicalHooks(hooks);
|
||||
} else if (canonicalHooks) {
|
||||
hooks.addHooks(canonicalHooks);
|
||||
}
|
||||
// tsdown indexes package completion before this hook, but creates dependency
|
||||
// plugins afterward. Preserve its coordinator identity while supplying the
|
||||
// standalone library's metadata to its native dependency-policy owner.
|
||||
hooks.hook("build:prepare", ({ options }) => {
|
||||
if (!options.pkg) {
|
||||
throw new Error("Missing build package metadata");
|
||||
}
|
||||
options.pkg.dependencies = manifest.dependencies;
|
||||
options.pkg.peerDependencies = manifest.peerDependencies;
|
||||
options.pkg.peerDependenciesMeta = manifest.peerDependenciesMeta;
|
||||
options.pkg.optionalDependencies = manifest.optionalDependencies;
|
||||
});
|
||||
};
|
||||
await withDistArtifactOwnership(root, async () => {
|
||||
cleanTsdownOutputRoots({
|
||||
cwd: root,
|
||||
roots: [output],
|
||||
env: { ...process.env, OPENCLAW_RUN_NODE_SKIP_DTS_BUILD: "0" },
|
||||
});
|
||||
const { build } = await import("tsdown");
|
||||
const { bundles } = await build({ ...config, cwd: root });
|
||||
try {
|
||||
sanitizeTsdownBuildOutputRoots(["--out-dir", output], root);
|
||||
} finally {
|
||||
for (const bundle of bundles) {
|
||||
await bundle[Symbol.asyncDispose]();
|
||||
}
|
||||
}
|
||||
});
|
||||
} finally {
|
||||
process.chdir(previousCwd);
|
||||
}
|
||||
}
|
||||
|
||||
if (isDirectRunUrl(process.argv[1], import.meta.url)) {
|
||||
const [packageName, ...extra] = process.argv.slice(2);
|
||||
if (!packageName || extra.length) {
|
||||
throw new Error("Expected one workspace package name");
|
||||
}
|
||||
await buildWorkspacePackage(packageName);
|
||||
}
|
||||
|
|
@ -165,7 +165,8 @@ export function hasUnjoinedWork(value: unknown): boolean {
|
|||
if ("processTreeState" in current && current.processTreeState !== "terminated") {
|
||||
return true;
|
||||
}
|
||||
if (current instanceof AggregateError) {
|
||||
// Rolldown preserves plugin failures in a plain Error.errors array.
|
||||
if ("errors" in current && Array.isArray(current.errors)) {
|
||||
for (const error of current.errors) {
|
||||
pending.push(error);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ const TSDOWN_PACKAGE_NAMES = [
|
|||
"net-policy",
|
||||
"normalization-core",
|
||||
"retry",
|
||||
"sdk",
|
||||
"terminal-core",
|
||||
"acp-core",
|
||||
] as const;
|
||||
|
|
|
|||
30
scripts/lib/workspace-package-entries.mts
Normal file
30
scripts/lib/workspace-package-entries.mts
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
|
||||
/** Canonical source entries for workspace packages with dist ESM exports. */
|
||||
export function buildPackageDistEntriesFromExports(packageDir: string): Record<string, string> {
|
||||
const packageJsonPath = path.join("packages", packageDir, "package.json");
|
||||
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8")) as {
|
||||
exports?: Record<string, unknown>;
|
||||
};
|
||||
const entries: Record<string, string> = {};
|
||||
for (const [exportKey, value] of Object.entries(packageJson.exports ?? {})) {
|
||||
const entry =
|
||||
exportKey === "." ? "index" : exportKey.startsWith("./") ? exportKey.slice(2) : "";
|
||||
if (!entry || entry.includes("..")) {
|
||||
continue;
|
||||
}
|
||||
const importPath =
|
||||
typeof value === "object" && value !== null && !Array.isArray(value)
|
||||
? (value as Record<string, unknown>).import
|
||||
: value;
|
||||
if (typeof importPath !== "string" || !importPath.startsWith("./dist/")) {
|
||||
continue;
|
||||
}
|
||||
const sourcePath = importPath
|
||||
.replace(/^\.\/dist\//u, `packages/${packageDir}/src/`)
|
||||
.replace(/\.mjs$/u, ".ts");
|
||||
entries[entry] = sourcePath;
|
||||
}
|
||||
return Object.fromEntries(Object.entries(entries).toSorted(([a], [b]) => a.localeCompare(b)));
|
||||
}
|
||||
|
|
@ -1,5 +1,7 @@
|
|||
{
|
||||
"extends": "../tsconfig.json",
|
||||
// This editor/lint graph includes tests; retain their compatibility augmentation.
|
||||
"files": ["config/sessions/session-entry.test-compat.d.ts"],
|
||||
"compilerOptions": {
|
||||
"allowJs": true
|
||||
},
|
||||
|
|
|
|||
|
|
@ -321,12 +321,56 @@ describe("check-deadcode-exports", () => {
|
|||
});
|
||||
|
||||
it.each([
|
||||
"packages/agent-core",
|
||||
"packages/markdown-core",
|
||||
"packages/media-core",
|
||||
"packages/acp-core",
|
||||
"packages/terminal-core",
|
||||
] as const)("mirrors the published entry map for %s", (workspace) => {
|
||||
"gateway-client",
|
||||
"gateway-protocol",
|
||||
"sdk",
|
||||
"retry",
|
||||
"normalization-core",
|
||||
"net-policy",
|
||||
"media-understanding-common",
|
||||
"media-generation-core",
|
||||
"media-core",
|
||||
"acp-core",
|
||||
"markdown-core",
|
||||
"terminal-core",
|
||||
"model-catalog-core",
|
||||
] as const)("derives public audit roots from the %s export map", (packageDir) => {
|
||||
const workspace = "packages/" + packageDir;
|
||||
const manifest = JSON.parse(fs.readFileSync(workspace + "/package.json", "utf8")) as {
|
||||
exports: Record<string, { import: string }>;
|
||||
};
|
||||
const expected = Object.values(manifest.exports)
|
||||
.map(({ import: target }) => target.replace("./dist/", "src/").replace(/\.mjs$/u, ".ts!"))
|
||||
.toSorted();
|
||||
if (packageDir === "normalization-core") {
|
||||
// The QA Lab Vite alias is a distinct source consumer, not a package export.
|
||||
expect(fs.readFileSync("extensions/qa-lab/web/vite.config.ts", "utf8")).toContain(
|
||||
"../../../packages/normalization-core/src/browser-error-runtime.ts",
|
||||
);
|
||||
expected.push("src/browser-error-runtime.ts!");
|
||||
expected.sort();
|
||||
}
|
||||
const production = Object.entries(knipConfig.workspaces).find(
|
||||
([name]) => name === workspace,
|
||||
)?.[1];
|
||||
const full = allExportsKnipConfig.workspaces[workspace];
|
||||
expect(production?.entry.toSorted(), workspace).toEqual(expected);
|
||||
expect(production?.project).toEqual(["src/**/*.ts!"]);
|
||||
expect(full?.entry).toEqual(expect.arrayContaining(expected));
|
||||
for (const entry of expected) {
|
||||
expect(fs.existsSync(workspace + "/" + entry.slice(0, -1)), entry).toBe(true);
|
||||
}
|
||||
});
|
||||
|
||||
it("does not promote private implementation or build-only artifacts to public audit roots", () => {
|
||||
expect(knipConfig.workspaces["packages/gateway-client"].entry).not.toContain(
|
||||
"src/protocol-client.ts!",
|
||||
);
|
||||
expect(knipConfig.workspaces["packages/acp-core"].entry).not.toContain("src/error-format.ts!");
|
||||
});
|
||||
|
||||
it("preserves the agent-core relocated source-entry contract", () => {
|
||||
const workspace = "packages/agent-core";
|
||||
const packageJson = JSON.parse(
|
||||
fs.readFileSync(new URL(`../../${workspace}/package.json`, import.meta.url), "utf8"),
|
||||
) as { exports: Record<string, unknown> };
|
||||
|
|
@ -339,21 +383,18 @@ describe("check-deadcode-exports", () => {
|
|||
new URL(`../../${workspace}/${entry.slice(0, -"!".length)}`, import.meta.url),
|
||||
),
|
||||
);
|
||||
expect(missingConventionalEntries).toEqual(
|
||||
workspace === "packages/agent-core"
|
||||
? ["src/harness/compaction.ts!", "src/harness/branch-summarization.ts!"]
|
||||
: [],
|
||||
);
|
||||
if (workspace === "packages/agent-core") {
|
||||
for (const sourcePath of [
|
||||
"src/harness/compaction/compaction.ts",
|
||||
"src/harness/compaction/branch-summarization.ts",
|
||||
]) {
|
||||
expect(
|
||||
fs.existsSync(new URL(`../../${workspace}/${sourcePath}`, import.meta.url)),
|
||||
sourcePath,
|
||||
).toBe(true);
|
||||
}
|
||||
expect(missingConventionalEntries).toEqual([
|
||||
"src/harness/compaction.ts!",
|
||||
"src/harness/branch-summarization.ts!",
|
||||
]);
|
||||
for (const sourcePath of [
|
||||
"src/harness/compaction/compaction.ts",
|
||||
"src/harness/compaction/branch-summarization.ts",
|
||||
]) {
|
||||
expect(
|
||||
fs.existsSync(new URL(`../../${workspace}/${sourcePath}`, import.meta.url)),
|
||||
sourcePath,
|
||||
).toBe(true);
|
||||
}
|
||||
const expected = conventionalEntries
|
||||
.filter((entry) => !missingConventionalEntries.includes(entry))
|
||||
|
|
|
|||
|
|
@ -573,7 +573,7 @@ describe.skipIf(process.platform === "win32")("dist artifact ownership", () => {
|
|||
expect(fs.existsSync(path.join(resolveDistArtifactLockPath(root), "unjoined"))).toBe(false);
|
||||
});
|
||||
|
||||
it.for(["cause", "error", "cyclic aggregate"])(
|
||||
it.for(["cause", "error", "cyclic aggregate", "bundler errors"])(
|
||||
"retains ownership for unjoined work nested in %s",
|
||||
async (kind, { signal }) => {
|
||||
// Retention deliberately keeps lock handles open; a joined child owns
|
||||
|
|
@ -591,6 +591,7 @@ describe.skipIf(process.platform === "win32")("dist artifact ownership", () => {
|
|||
const aggregate = new AggregateError([], 'sibling cleanup');
|
||||
aggregate.errors.push(aggregate, new Error('command failed', { cause: uncertainty }));
|
||||
const error = kind === 'cyclic aggregate' ? aggregate
|
||||
: kind === 'bundler errors' ? Object.assign(new Error('Build failed'), { errors: [aggregate] })
|
||||
: new Error('command failed', { cause: kind === 'cause' ? uncertainty : { error: uncertainty } });
|
||||
const outcome = await withDistArtifactOwnership(process.cwd(), async () => {
|
||||
throw error;
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import { portableRelativePath } from "../../scripts/lib/build-artifact-cache.mts
|
|||
import { BoundaryInputSnapshot } from "../../scripts/lib/extension-boundary-inputs.mts";
|
||||
import { createDeclarationInputBoundary } from "../../scripts/lib/local-check-runtime.mts";
|
||||
import { emitNativeDeclarations } from "../../scripts/lib/native-declaration-emitter.mts";
|
||||
import { readNativeTypeScriptConfig } from "../../scripts/lib/native-typescript-config.mts";
|
||||
import { useAutoCleanupTempDirTracker } from "../helpers/temp-dir.js";
|
||||
import {
|
||||
installNativeAncestorTypes,
|
||||
|
|
@ -17,6 +18,55 @@ import {
|
|||
|
||||
const roots = useAutoCleanupTempDirTracker(afterEach);
|
||||
|
||||
it("keeps test-only ambient augmentation out of declaration roots but in test graphs", () => {
|
||||
const root = fs.realpathSync.native(roots.make("native-declaration-production-roots-"));
|
||||
// Use the actual production/test selection rules with a tiny semantic-free fixture.
|
||||
const testConfigs = [
|
||||
"test/tsconfig/tsconfig.test.json",
|
||||
"src/tsconfig.json",
|
||||
"ui/tsconfig.json",
|
||||
"extensions/tsconfig.json",
|
||||
];
|
||||
// Actual emit owners: tsgo:prod UI/plugin configs are noEmit typecheck graphs.
|
||||
const productionConfigs = [
|
||||
"tsconfig.json",
|
||||
"packages/plugin-sdk/tsconfig.json",
|
||||
"extensions/browser/tsconfig.json",
|
||||
];
|
||||
for (const config of [
|
||||
...productionConfigs,
|
||||
...testConfigs,
|
||||
"extensions/tsconfig.package-boundary.paths.json",
|
||||
"extensions/tsconfig.package-boundary.base.json",
|
||||
]) {
|
||||
writeNativeFixtureFile(root, config, fs.readFileSync(config, "utf8"));
|
||||
}
|
||||
const productionAmbient = "src/types/production.d.ts";
|
||||
const testAmbient = "src/config/sessions/session-entry.test-compat.d.ts";
|
||||
writeNativeFixtureFile(root, productionAmbient, "declare const productionOrigin: string;");
|
||||
writeNativeFixtureFile(root, testAmbient, 'import "./runtime.js";');
|
||||
writeNativeFixtureFile(root, "src/config/sessions/runtime.ts", "export const value = 1;");
|
||||
for (const file of [
|
||||
"packages/example/src/index.ts",
|
||||
"src/plugin-sdk/index.ts",
|
||||
"extensions/browser/src/index.ts",
|
||||
]) {
|
||||
writeNativeFixtureFile(root, file, "export const value = 1;");
|
||||
}
|
||||
const configuredRoots = (configFileName: string) =>
|
||||
readNativeTypeScriptConfig({ cwd: root, configFileName }).fileNames.map((file) =>
|
||||
path.relative(root, file).replaceAll(path.sep, "/"),
|
||||
);
|
||||
const production = configuredRoots("tsconfig.json");
|
||||
expect(production).toContain(productionAmbient);
|
||||
for (const config of productionConfigs) {
|
||||
expect(configuredRoots(config), config).not.toContain(testAmbient);
|
||||
}
|
||||
for (const config of testConfigs) {
|
||||
expect(configuredRoots(config), config).toContain(testAmbient);
|
||||
}
|
||||
});
|
||||
|
||||
it.each([true, false])(
|
||||
"diagnoses declaration escapes with an ancestor install=%s",
|
||||
(ancestorInstall) => {
|
||||
|
|
|
|||
|
|
@ -132,6 +132,33 @@ function readJson(filePath: string): unknown {
|
|||
return JSON5.parse(fs.readFileSync(filePath, "utf8"));
|
||||
}
|
||||
|
||||
function writeSessionCompatibilityFixture(root: string) {
|
||||
const directory = path.join(root, "src/config/sessions");
|
||||
fs.mkdirSync(directory, { recursive: true });
|
||||
// Real editor configs explicitly root this augmentation. Keep its real contents,
|
||||
// with fixture-owned base modules rather than importing the whole session graph.
|
||||
fs.copyFileSync(
|
||||
"src/config/sessions/session-entry.test-compat.d.ts",
|
||||
path.join(directory, "session-entry.test-compat.d.ts"),
|
||||
);
|
||||
for (const [file, interfaces] of [
|
||||
["types.ts", ["SessionEntry", "InternalSessionEntry"]],
|
||||
[
|
||||
"session-accessor.types.ts",
|
||||
[
|
||||
"SessionTranscriptRuntimeTarget",
|
||||
"SessionTranscriptTurnPersistResult",
|
||||
"SessionTranscriptReadTarget",
|
||||
],
|
||||
],
|
||||
] as const) {
|
||||
fs.writeFileSync(
|
||||
path.join(directory, file),
|
||||
interfaces.map((name) => "export interface " + name + " { id: string; }").join("\n"),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
describe("oxlint config", () => {
|
||||
it("enforces namespace, evaluation, and unused-binding policies with the installed binary", () => {
|
||||
const tempRoot = fs.realpathSync(createTempDir("openclaw-oxlint-policy-"));
|
||||
|
|
@ -262,6 +289,7 @@ describe("oxlint config", () => {
|
|||
fs.copyFileSync(file, target);
|
||||
}
|
||||
}
|
||||
writeSessionCompatibilityFixture(tempRoot);
|
||||
fs.symlinkSync(path.resolve("node_modules"), path.join(tempRoot, "node_modules"), "junction");
|
||||
const fixtures = {
|
||||
"src/imported.ts": "export function work(): Promise<void> { return Promise.resolve(); }",
|
||||
|
|
@ -376,6 +404,7 @@ describe("oxlint config", () => {
|
|||
fs.copyFileSync(file, target);
|
||||
}
|
||||
}
|
||||
writeSessionCompatibilityFixture(tempRoot);
|
||||
fs.symlinkSync(path.resolve("node_modules"), path.join(tempRoot, "node_modules"), "junction");
|
||||
const source = [
|
||||
'import { work } from "../packages/imported.js";',
|
||||
|
|
@ -464,6 +493,7 @@ describe("oxlint config", () => {
|
|||
fs.copyFileSync(file, target);
|
||||
}
|
||||
}
|
||||
writeSessionCompatibilityFixture(tempRoot);
|
||||
fs.symlinkSync(path.resolve("node_modules"), path.join(tempRoot, "node_modules"), "junction");
|
||||
const supportFiles = [
|
||||
"src/cli/diagnostics.test-support.ts",
|
||||
|
|
|
|||
|
|
@ -1042,6 +1042,37 @@ console.log("relocated Bash parser works without native grammar package");
|
|||
},
|
||||
);
|
||||
|
||||
it("gives every standalone declaration caller one canonical package config", () => {
|
||||
for (const packageName of [
|
||||
"gateway-client",
|
||||
"gateway-protocol",
|
||||
"sdk",
|
||||
"retry",
|
||||
"normalization-core",
|
||||
"net-policy",
|
||||
"media-understanding-common",
|
||||
"media-generation-core",
|
||||
"media-core",
|
||||
"acp-core",
|
||||
]) {
|
||||
const manifest = JSON.parse(
|
||||
fs.readFileSync(`packages/${packageName}/package.json`, "utf8"),
|
||||
) as { scripts: { build: string }; exports: Record<string, { import: string }> };
|
||||
expect(manifest.scripts.build).toContain(`build-workspace-package.mts ${packageName}`);
|
||||
const selected = configs.filter((config) => config.outDir === `packages/${packageName}/dist`);
|
||||
expect(selected, packageName).toHaveLength(1);
|
||||
const sources = Object.values(selected[0]!.entry ?? {});
|
||||
for (const entry of Object.values(manifest.exports)) {
|
||||
expect(sources).toContain(
|
||||
entry.import.replace("./dist/", `packages/${packageName}/src/`).replace(/\.mjs$/u, ".ts"),
|
||||
);
|
||||
}
|
||||
if (packageName === "acp-core") {
|
||||
expect(sources).toContain("packages/acp-core/src/error-format.ts");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
it("isolates runtime output from bounded declaration-only graphs", () => {
|
||||
const packageConfigs = configs.filter((entry) => entry.name === TSDOWN_PACKAGE_CONFIG_GROUP);
|
||||
const unifiedRuntimeConfig = configs.find(
|
||||
|
|
|
|||
|
|
@ -88,6 +88,118 @@ function nestedFixture(groups: readonly string[] = TSDOWN_PLUGIN_SDK_DTS_CONFIG_
|
|||
}
|
||||
|
||||
describe("tsdown checkout declaration resolution", () => {
|
||||
it("bounds standalone package builds while preserving public declarations and sibling outputs", () => {
|
||||
const { root, write } = containedFixture();
|
||||
fs.symlinkSync(
|
||||
fs.realpathSync("node_modules/semver"),
|
||||
path.join(root, "node_modules/semver"),
|
||||
"junction",
|
||||
);
|
||||
write(
|
||||
"scripts/build-workspace-package.mts",
|
||||
fs.readFileSync("scripts/build-workspace-package.mts", "utf8"),
|
||||
);
|
||||
const manifest = JSON.parse(
|
||||
fs.readFileSync("packages/gateway-client/package.json", "utf8"),
|
||||
) as {
|
||||
exports: Record<string, { import: string; types: string }>;
|
||||
dependencies?: Record<string, string>;
|
||||
};
|
||||
manifest.dependencies = { ...manifest.dependencies, "standalone-dependency": "1.0.0" };
|
||||
write("packages/gateway-client/package.json", JSON.stringify(manifest));
|
||||
write(
|
||||
"node_modules/standalone-dependency/package.json",
|
||||
JSON.stringify({
|
||||
name: "standalone-dependency",
|
||||
version: "1.0.0",
|
||||
type: "module",
|
||||
exports: { "./value": { types: "./value.d.ts", import: "./value.js" } },
|
||||
}),
|
||||
);
|
||||
write(
|
||||
"node_modules/standalone-dependency/value.d.ts",
|
||||
"export declare const externalValue: string;",
|
||||
);
|
||||
write(
|
||||
"node_modules/standalone-dependency/value.js",
|
||||
'export const externalValue = "package-owned";',
|
||||
);
|
||||
for (const entry of Object.values(manifest.exports)) {
|
||||
write(
|
||||
entry.import.replace("./dist/", "packages/gateway-client/src/").replace(/\.mjs$/u, ".ts"),
|
||||
'export const marker = "bounded";\n',
|
||||
);
|
||||
}
|
||||
write(
|
||||
"packages/gateway-client/src/index.ts",
|
||||
`
|
||||
export const marker = "bounded";
|
||||
export { externalValue } from "standalone-dependency/value";
|
||||
declare const process: { env: { NODE_ENV?: string } };
|
||||
export function runtimeMode(env: { NODE_ENV?: string }) {
|
||||
return env.NODE_ENV ?? process.env.NODE_ENV;
|
||||
}
|
||||
`,
|
||||
);
|
||||
write("packages/sdk/src/index.ts", 'export const sdkMarker = "sdk";\n');
|
||||
// Upstream whole-project declaration emit rejects this unselected test helper (TS4094).
|
||||
write(
|
||||
"src/unrelated.test-support.ts",
|
||||
"export const hidden = new (class { private value = 1; })();\n",
|
||||
);
|
||||
write("packages/gateway-client/dist/obsolete.d.mts", "export declare const retired: 1;");
|
||||
write("dist/keep.txt", "root output");
|
||||
write("packages/gateway-protocol/dist/keep.txt", "sibling output");
|
||||
const result = runFixtureModule(
|
||||
root,
|
||||
`
|
||||
import assert from "node:assert/strict";
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import { pathToFileURL } from "node:url";
|
||||
import { buildWorkspacePackage } from "./scripts/build-workspace-package.mts";
|
||||
import configs from "./tsdown.config.ts";
|
||||
const root = process.cwd();
|
||||
for (const [name, target] of [["sdk", undefined], ["gateway-client", ["node22.19.0"]]]) {
|
||||
const config = configs.find(config => config.outDir === "packages/" + name + "/dist");
|
||||
const original = config.hooks;
|
||||
config.hooks = async hooks => {
|
||||
await original(hooks);
|
||||
hooks.hook("build:prepare", ({ options }) => assert.deepEqual(options.target, target));
|
||||
};
|
||||
}
|
||||
await buildWorkspacePackage("sdk");
|
||||
assert.match(fs.readFileSync("packages/sdk/dist/index.d.mts", "utf8"), /sdkMarker.*"sdk"/);
|
||||
process.env.OPENCLAW_RUN_NODE_SKIP_DTS_BUILD = "1";
|
||||
const packageDir = path.join(root, "packages/gateway-client");
|
||||
process.chdir(packageDir);
|
||||
await buildWorkspacePackage("gateway-client");
|
||||
assert.equal(process.cwd(), packageDir);
|
||||
assert.equal(fs.existsSync("dist/obsolete.d.mts"), false);
|
||||
fs.writeFileSync(path.join(root, "node_modules/standalone-dependency/value.js"), 'export const externalValue = "installed-update";');
|
||||
process.env.NODE_ENV = "runtime-mode";
|
||||
const output = await import(pathToFileURL(path.join(packageDir, "dist/index.mjs")).href);
|
||||
assert.deepEqual(
|
||||
{ mode: output.runtimeMode({}), external: output.externalValue },
|
||||
{ mode: "runtime-mode", external: "installed-update" },
|
||||
);
|
||||
const manifest = JSON.parse(fs.readFileSync("package.json", "utf8"));
|
||||
for (const entry of Object.values(manifest.exports)) {
|
||||
assert.ok(fs.existsSync(entry.import), entry.import);
|
||||
assert.match(fs.readFileSync(entry.types, "utf8"), /marker.*"bounded"/);
|
||||
}
|
||||
assert.equal(fs.readFileSync(path.join(root, "dist/keep.txt"), "utf8"), "root output");
|
||||
assert.equal(fs.readFileSync(path.join(root, "packages/gateway-protocol/dist/keep.txt"), "utf8"), "sibling output");
|
||||
fs.writeFileSync("src/index.ts", 'export const invalid: number = "selected";');
|
||||
await assert.rejects(buildWorkspacePackage("gateway-client"), /Native declaration emit failed/);
|
||||
assert.equal(process.cwd(), packageDir);
|
||||
console.log("standalone package boundary verified");
|
||||
`,
|
||||
);
|
||||
expect(result.status, result.stdout + result.stderr).toBe(0);
|
||||
expect(result.stdout).toContain("standalone package boundary verified");
|
||||
});
|
||||
|
||||
it.runIf(process.platform === "win32")(
|
||||
"starts the checkout compiler when its Windows executable uses an extended-length path",
|
||||
() => {
|
||||
|
|
|
|||
|
|
@ -318,5 +318,5 @@
|
|||
}
|
||||
},
|
||||
"include": ["src/**/*", "ui/**/*", "extensions/**/*", "packages/**/*"],
|
||||
"exclude": ["node_modules", "dist", "**/dist/**"]
|
||||
"exclude": ["node_modules", "dist", "**/dist/**", "**/*.test-compat.d.ts"]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ import {
|
|||
createWorkerDeployBuildPlugin,
|
||||
WORKER_DEPLOY_OPTIONAL_NATIVE_MODULE_ID,
|
||||
} from "./scripts/lib/worker-deploy-build-plugin.mts";
|
||||
import { buildPackageDistEntriesFromExports } from "./scripts/lib/workspace-package-entries.mts";
|
||||
|
||||
type InputOptionsFactory = Extract<NonNullable<UserConfig["inputOptions"]>, Function>;
|
||||
type InputOptionsArg = InputOptionsFactory extends (
|
||||
|
|
@ -555,33 +556,6 @@ function buildAgentCoreDistEntries(): Record<string, string> {
|
|||
};
|
||||
}
|
||||
|
||||
function buildPackageDistEntriesFromExports(packageDir: string): Record<string, string> {
|
||||
const packageJsonPath = path.join("packages", packageDir, "package.json");
|
||||
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8")) as {
|
||||
exports?: Record<string, unknown>;
|
||||
};
|
||||
const entries: Record<string, string> = {};
|
||||
for (const [exportKey, value] of Object.entries(packageJson.exports ?? {})) {
|
||||
const entry =
|
||||
exportKey === "." ? "index" : exportKey.startsWith("./") ? exportKey.slice(2) : "";
|
||||
if (!entry || entry.includes("..")) {
|
||||
continue;
|
||||
}
|
||||
const importPath =
|
||||
typeof value === "object" && value !== null && !Array.isArray(value)
|
||||
? (value as Record<string, unknown>).import
|
||||
: value;
|
||||
if (typeof importPath !== "string" || !importPath.startsWith("./dist/")) {
|
||||
continue;
|
||||
}
|
||||
const sourcePath = importPath
|
||||
.replace(/^\.\/dist\//u, `packages/${packageDir}/src/`)
|
||||
.replace(/\.mjs$/u, ".ts");
|
||||
entries[entry] = sourcePath;
|
||||
}
|
||||
return Object.fromEntries(Object.entries(entries).toSorted(([a], [b]) => a.localeCompare(b)));
|
||||
}
|
||||
|
||||
function buildLlmCoreDistEntries(): Record<string, string> {
|
||||
return {
|
||||
index: "packages/llm-core/src/index.ts",
|
||||
|
|
@ -874,8 +848,23 @@ const configs: UserConfig[] = [
|
|||
}),
|
||||
nodeWorkspacePackageBuildConfig("normalization-core"),
|
||||
nodeWorkspacePackageBuildConfig("retry"),
|
||||
nodeWorkspacePackageBuildConfig("sdk", {
|
||||
deps: withExternalPackageSubpaths({
|
||||
neverBundle: [
|
||||
"@openclaw/gateway-client",
|
||||
"@openclaw/gateway-protocol",
|
||||
"@openclaw/normalization-core",
|
||||
],
|
||||
}),
|
||||
}),
|
||||
nodeWorkspacePackageBuildConfig("media-core"),
|
||||
nodeWorkspacePackageBuildConfig("acp-core"),
|
||||
nodeWorkspacePackageBuildConfig("acp-core", {
|
||||
entry: {
|
||||
...buildPackageDistEntriesFromExports("acp-core"),
|
||||
// Preserve the standalone package build's non-exported redactor artifact.
|
||||
"error-format": "packages/acp-core/src/error-format.ts",
|
||||
},
|
||||
}),
|
||||
nodeWorkspacePackageBuildConfig("terminal-core", {
|
||||
deps: {
|
||||
neverBundle: shouldExternalizeTerminalCoreDependency,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
{
|
||||
"extends": "../tsconfig.json",
|
||||
// This editor/lint graph includes tests; retain their compatibility augmentation.
|
||||
"files": ["../src/config/sessions/session-entry.test-compat.d.ts"],
|
||||
"include": [
|
||||
"**/*.ts",
|
||||
"**/*.tsx",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue