diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 025e7d2aa9e..0a5a2c2a459 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1199,6 +1199,9 @@ jobs: - check_name: check-lint task: lint runner: blacksmith-16vcpu-ubuntu-2404 + - check_name: check-dependencies + task: dependencies + runner: ubuntu-24.04 - check_name: check-policy-guards task: policy-guards runner: ubuntu-24.04 @@ -1281,6 +1284,9 @@ jobs: lint) pnpm lint --threads=8 ;; + dependencies) + pnpm deadcode:dependencies + ;; policy-guards) pnpm lint:webhook:no-low-level-body-read pnpm lint:auth:no-pairing-store-group diff --git a/docs/ci.md b/docs/ci.md index 28d46dc3ea1..b74cfe20557 100644 --- a/docs/ci.md +++ b/docs/ci.md @@ -8,6 +8,8 @@ read_when: The CI runs on every push to `main` and every pull request. It uses smart scoping to skip expensive jobs when only unrelated areas changed. Manual `workflow_dispatch` runs intentionally bypass smart scoping and fan out the full normal CI graph for release candidates or broad validation, with Android lanes opt-in through `include_android` for standalone manual runs. Release-only plugin prerelease lanes live in the separate `Plugin Prerelease` workflow and run only from `Full Release Validation` or an explicit manual dispatch. +The `check-dependencies` shard runs `pnpm deadcode:dependencies`, a production Knip dependency-only pass pinned to the latest Knip version used by that script, with pnpm's minimum release age disabled for the `dlx` install. It gates newly unused, unlisted, unresolved, binary, or catalog dependencies without enabling Knip's full unused-file mode, which remains a manual audit because OpenClaw intentionally loads many plugin and runtime surfaces through manifests and string specifiers. + `Full Release Validation` is the manual umbrella workflow for "run everything before release." It accepts a branch, tag, or full commit SHA, dispatches the manual `CI` workflow with that target, dispatches `Plugin Prerelease` for diff --git a/knip.config.ts b/knip.config.ts index 077c6182242..b1c44aa9afc 100644 --- a/knip.config.ts +++ b/knip.config.ts @@ -18,6 +18,7 @@ const rootEntries = [ ] as const; const bundledPluginEntries = [ + "*.ts!", "index.ts!", "setup-entry.ts!", "{api,contract-api,helper-api,runtime-api,light-runtime-api,update-offset-runtime-api,channel-plugin-api,provider-plugin-api,setup-api}.ts!", @@ -26,6 +27,25 @@ const bundledPluginEntries = [ "src/subagent-hooks-api.ts!", ] as const; +const bundledPluginIgnoredRuntimeDependencies = [ + "@agentclientprotocol/claude-agent-acp", + "@azure/identity", + "@clawdbot/lobster", + "@discordjs/opus", + "@homebridge/ciao", + "@matrix-org/matrix-sdk-crypto-wasm", + "@mozilla/readability", + "@openai/codex", + "@pierre/theme", + "@tloncorp/tlon-skill", + "@zed-industries/codex-acp", + "jiti", + "linkedom", + "openclaw", + "pdfjs-dist", + "typebox", +] as const; + const config = { ignoreFiles: [ "scripts/**", @@ -93,7 +113,7 @@ const config = { workspaces: { ".": { entry: rootEntries, - ignoreDependencies: ["@openclaw/*"], + ignoreDependencies: ["@openclaw/*", "sqlite-vec"], project: [ "src/**/*.ts!", "scripts/**/*.{js,mjs,cjs,ts,mts,cts}!", @@ -114,7 +134,7 @@ const config = { // `index.ts` contracts, so Knip needs these convention-based entry files. entry: bundledPluginEntries, project: ["index.ts!", "src/**/*.ts!"], - ignoreDependencies: ["openclaw"], + ignoreDependencies: bundledPluginIgnoredRuntimeDependencies, }, }, } as const; diff --git a/package.json b/package.json index 47248abb7db..cc9fd4ba933 100644 --- a/package.json +++ b/package.json @@ -1300,6 +1300,7 @@ "config:schema:check": "node --import tsx scripts/generate-base-config-schema.ts --check", "config:schema:gen": "node --import tsx scripts/generate-base-config-schema.ts --write", "deadcode:ci": "pnpm deadcode:report:ci:knip", + "deadcode:dependencies": "pnpm --config.minimum-release-age=0 dlx knip@6.8.0 --config knip.config.ts --production --no-progress --reporter compact --dependencies --no-config-hints", "deadcode:knip": "pnpm dlx knip --config knip.config.ts --production --no-progress --reporter compact --files --dependencies", "deadcode:report": "pnpm deadcode:knip; pnpm deadcode:ts-prune; pnpm deadcode:ts-unused", "deadcode:report:ci:knip": "mkdir -p .artifacts/deadcode && pnpm deadcode:knip > .artifacts/deadcode/knip.txt 2>&1 || true",