diff --git a/AGENTS.md b/AGENTS.md index bcf88075aad..daef230c6fe 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -127,14 +127,13 @@ - Node remains supported for running built output (`dist/*`) and production installs. - Mac packaging (dev): `scripts/package-mac-app.sh` defaults to current arch. - Type-check/build: `pnpm build` -- TypeScript checks are split by architecture boundary: +- TypeScript checks are split by architecture boundary, with four normal lanes: - `pnpm tsgo` / `pnpm tsgo:core`: core production roots (`src/`, `ui/`, `packages/`; no `extensions/` include roots). - `pnpm tsgo:core:test`: core colocated tests. - - `pnpm tsgo:core:test:agents` / `pnpm tsgo:core:test:non-agents`: core test slices for isolating the heavy agent graph while debugging type-check performance. - `pnpm tsgo:extensions`: bundled extension production graph. - `pnpm tsgo:extensions:test`: bundled extension colocated tests. - `pnpm tsgo:all`: every TypeScript graph above; this is what `pnpm check` runs. - - `pnpm tsgo:profile [core-test|core-test-agents|core-test-non-agents|extensions-test|--all]`: profile fresh graph cost into `.artifacts/tsgo-profile/`; if a core graph lists `extensions//`, treat that as boundary/perf debt from imports (usually plugin-sdk facades or shared helpers pulling extension sources). + - `pnpm tsgo:profile [core-test|extensions-test|--all]`: profile fresh graph cost into `.artifacts/tsgo-profile/`. Diagnostic-only profile slices (`core-test-agents`, `core-test-non-agents`) exist for investigating agent graph cost; do not treat them as normal user-facing checks. - Narrow aliases remain for local loops: `pnpm tsgo:test:src`, `pnpm tsgo:test:ui`, `pnpm tsgo:test:packages`. - Do not add `tsc --noEmit`, `typecheck`, or `check:types` lanes for repo type checking. Use `tsgo` graphs. `tsc` is allowed only when emitting declaration/package-boundary compatibility artifacts that `tsgo` does not replace. - Boundary rule: core must not know extension implementation details. Extensions hook into core through manifests, registries, capabilities, and public `openclaw/plugin-sdk/*` contracts. If you find core production code naming a specific extension, or a core test that is really testing extension-owned behavior, call it out and prefer moving coverage/logic to the owning extension or a generic contract test. diff --git a/package.json b/package.json index 23b40d600e1..5caebd32ccc 100644 --- a/package.json +++ b/package.json @@ -1474,8 +1474,6 @@ "tsgo:all": "pnpm tsgo:core && pnpm tsgo:core:test && pnpm tsgo:extensions && pnpm tsgo:extensions:test", "tsgo:core": "node scripts/run-tsgo.mjs -p tsconfig.core.json --incremental --tsBuildInfoFile .artifacts/tsgo-cache/core.tsbuildinfo", "tsgo:core:test": "node scripts/run-tsgo.mjs -p tsconfig.core.test.json --incremental --tsBuildInfoFile .artifacts/tsgo-cache/core-test.tsbuildinfo", - "tsgo:core:test:agents": "node scripts/run-tsgo.mjs -p tsconfig.core.test.agents.json --incremental --tsBuildInfoFile .artifacts/tsgo-cache/core-test-agents.tsbuildinfo", - "tsgo:core:test:non-agents": "node scripts/run-tsgo.mjs -p tsconfig.core.test.non-agents.json --incremental --tsBuildInfoFile .artifacts/tsgo-cache/core-test-non-agents.tsbuildinfo", "tsgo:extensions": "node scripts/run-tsgo.mjs -p tsconfig.extensions.json --incremental --tsBuildInfoFile .artifacts/tsgo-cache/extensions.tsbuildinfo", "tsgo:extensions:test": "node scripts/run-tsgo.mjs -p tsconfig.extensions.test.json --incremental --tsBuildInfoFile .artifacts/tsgo-cache/extensions-test.tsbuildinfo", "tsgo:prod": "pnpm tsgo:core && pnpm tsgo:extensions", diff --git a/scripts/profile-tsgo.mjs b/scripts/profile-tsgo.mjs index 52db37f8849..76439005fe7 100644 --- a/scripts/profile-tsgo.mjs +++ b/scripts/profile-tsgo.mjs @@ -24,11 +24,11 @@ const GRAPH_DEFINITIONS = { }, "core-test-agents": { config: "tsconfig.core.test.agents.json", - description: "core agent colocated test graph", + description: "diagnostic slice: core agent colocated tests", }, "core-test-non-agents": { config: "tsconfig.core.test.non-agents.json", - description: "core non-agent colocated test graph", + description: "diagnostic slice: core tests excluding agent test roots", }, extensions: { config: "tsconfig.extensions.json", diff --git a/src/infra/outbound/channel-adapters.test.ts b/src/infra/outbound/channel-adapters.test.ts index 4b66c32a207..0e6bdc969bb 100644 --- a/src/infra/outbound/channel-adapters.test.ts +++ b/src/infra/outbound/channel-adapters.test.ts @@ -1,4 +1,3 @@ -import { Container, Separator, TextDisplay } from "@buape/carbon"; import { beforeEach, describe, expect, it } from "vitest"; import type { ChannelPlugin } from "../../channels/plugins/types.js"; import { setActivePluginRegistry } from "../../plugins/runtime.js"; @@ -8,7 +7,17 @@ import { } from "../../test-utils/channel-plugins.js"; import { getChannelMessageAdapter } from "./channel-adapters.js"; -class TestDiscordUiContainer extends Container {} +class TestTextDisplay { + constructor(readonly content: string) {} +} + +class TestSeparator { + constructor(readonly options: { divider: boolean; spacing: string }) {} +} + +class TestDiscordUiContainer { + constructor(readonly components: Array) {} +} const discordCrossContextPlugin: Pick< ChannelPlugin, @@ -18,12 +27,12 @@ const discordCrossContextPlugin: Pick< messaging: { buildCrossContextComponents: ({ originLabel, message, cfg, accountId }) => { const trimmed = message.trim(); - const components: Array = []; + const components: Array = []; if (trimmed) { - components.push(new TextDisplay(message)); - components.push(new Separator({ divider: true, spacing: "small" })); + components.push(new TestTextDisplay(message)); + components.push(new TestSeparator({ divider: true, spacing: "small" })); } - components.push(new TextDisplay(`*From ${originLabel}*`)); + components.push(new TestTextDisplay(`*From ${originLabel}*`)); void cfg; void accountId; return [new TestDiscordUiContainer(components)]; @@ -68,9 +77,9 @@ describe("getChannelMessageAdapter", () => { expect(components).toHaveLength(1); expect(container).toBeInstanceOf(TestDiscordUiContainer); expect(container?.components).toEqual([ - expect.any(TextDisplay), - expect.any(Separator), - expect.any(TextDisplay), + expect.any(TestTextDisplay), + expect.any(TestSeparator), + expect.any(TestTextDisplay), ]); }); @@ -79,12 +88,16 @@ describe("getChannelMessageAdapter", () => { message: "Hello from chat", originLabel: "Telegram", accountId: "primary", - expectedComponents: [expect.any(TextDisplay), expect.any(Separator), expect.any(TextDisplay)], + expectedComponents: [ + expect.any(TestTextDisplay), + expect.any(TestSeparator), + expect.any(TestTextDisplay), + ], }, { message: " ", originLabel: "Signal", - expectedComponents: [expect.any(TextDisplay)], + expectedComponents: [expect.any(TestTextDisplay)], }, ])( "builds cross-context components for %j", diff --git a/src/infra/outbound/outbound-policy.test.ts b/src/infra/outbound/outbound-policy.test.ts index 33b9c9037d1..7bc69b405c3 100644 --- a/src/infra/outbound/outbound-policy.test.ts +++ b/src/infra/outbound/outbound-policy.test.ts @@ -1,4 +1,3 @@ -import { Container, Separator, TextDisplay } from "@buape/carbon"; import { beforeAll, beforeEach, describe, expect, it } from "vitest"; import { vi } from "vitest"; import type { ChannelMessageActionName } from "../../channels/plugins/types.js"; @@ -9,7 +8,17 @@ let buildCrossContextDecoration: typeof import("./outbound-policy.js").buildCros let enforceCrossContextPolicy: typeof import("./outbound-policy.js").enforceCrossContextPolicy; let shouldApplyCrossContextMarker: typeof import("./outbound-policy.js").shouldApplyCrossContextMarker; -class TestDiscordUiContainer extends Container {} +class TestTextDisplay { + constructor(readonly content: string) {} +} + +class TestSeparator { + constructor(readonly options: { divider: boolean; spacing: string }) {} +} + +class TestDiscordUiContainer { + constructor(readonly components: Array) {} +} const mocks = vi.hoisted(() => ({ getChannelMessageAdapter: vi.fn((channel: string) => @@ -24,12 +33,12 @@ const mocks = vi.hoisted(() => ({ message: string; }) => { const trimmed = message.trim(); - const components: Array = []; + const components: Array = []; if (trimmed) { - components.push(new TextDisplay(message)); - components.push(new Separator({ divider: true, spacing: "small" })); + components.push(new TestTextDisplay(message)); + components.push(new TestSeparator({ divider: true, spacing: "small" })); } - components.push(new TextDisplay(`*From ${originLabel}*`)); + components.push(new TestTextDisplay(`*From ${originLabel}*`)); return [new TestDiscordUiContainer(components)]; }, } diff --git a/src/types/pi-coding-agent.d.ts b/src/types/pi-coding-agent.d.ts index eeb0666602f..dd411117c46 100644 --- a/src/types/pi-coding-agent.d.ts +++ b/src/types/pi-coding-agent.d.ts @@ -1,4 +1,4 @@ -import "@mariozechner/pi-coding-agent"; +export type OpenClawPiCodingAgentSkillSourceAugmentation = never; declare module "@mariozechner/pi-coding-agent" { interface Skill {