Files
openclaw/scripts/check-no-deprecated-channel-access.ts
T
Peter Steinberger 8ee945b907 refactor(channels): flatten channel-turn dispatch naming layers (#121308)
* refactor(channels): flatten channel turn dispatch naming

* docs(plugin-sdk): narrow inbound reply compat guidance

* docs(channels): point stale references at turn defining modules

* fix(channels): preserve dispatch contracts after flattening

* chore(plugin-sdk): ratchet surface budgets after flattening

* chore(channels): ratchet removed export collisions

* fix(plugin-sdk): restore inbound reply compat exports

Restore eight still-existing legacy callable re-exports from canonical SDK seams and cover the deprecated package subpath with a table-driven compatibility test.

Raise the public export, callable export, and deprecated export budgets by exactly eight; the three maintainer-authorized zero-consumer symbols remain removed.

* test(channels): split channel turn kernel coverage

Replace the oversized kernel test with independently mocked delivery, pipeline, and finalize suites, preserving all 51 tests while removing the max-lines suppression and stale ratchet entry.

* chore(plugin-sdk): refresh inbound reply API hash

* fix(ci): align channel turn review fixes

Restore the test-local DeliveryResult type removed during the split.

Ratchet the public export, callable export, and deprecated export budgets by exactly seven: six channel-inbound plus one channel-outbound legacy re-export.
2026-08-09 22:22:46 -07:00

116 lines
3.9 KiB
TypeScript

// Check No Deprecated Channel Access script supports OpenClaw repository automation.
import fs from "node:fs";
import path from "node:path";
import { collectFilesSync, isCodeFile, relativeToCwd } from "./check-file-utils.js";
import { classifyBundledExtensionSourcePath } from "./lib/extension-source-classifier.mts";
type Rule = {
label: string;
pattern: RegExp;
};
const RULES: Rule[] = [
{
label: "deprecated channel runtime",
pattern:
/\.channel\.(?:reply\.(?:createReplyDispatcherWithTyping|resolveHumanDelayConfig|dispatchReplyFromConfig|finalizeInboundContext|formatInboundEnvelope)|session\.(?:resolveStorePath|recordInboundSession)|inbound\.(?:runPreparedReply|dispatchReply)|media\.fetchRemoteMedia)\b/u,
},
{
label: "caller-owned prepared channel dispatch",
pattern: /\b(?:runDispatch|onPreDispatchFailure)\b/u,
},
{
label: "caller-owned reply dispatcher lifecycle",
pattern:
/\b(?:createReplyDispatcherWithTyping|dispatchInboundMessage(?:WithBufferedDispatcher|WithDispatcher)?|settleReplyDispatcher)\s*\(/u,
},
{
label: "deprecated channel ingress resolver aliases",
pattern:
/\b(?:resolved|result|directResolved|groupResolved)\.(?:legacyAccess|senderReasonCode|commandAuthorized|shouldBlockControlCommand)\b/u,
},
{
label: "inline deprecated channel ingress legacyAccess projection",
pattern: /\)\.legacyAccess\b/u,
},
{
label: "deprecated pairing-store access helper",
pattern: /\breadStoreAllowFromForDmPolicy\b/u,
},
{
label: "deprecated DM/group access helper",
pattern: /\bresolveDmGroupAccessWith(?:Lists|CommandGate)\b/u,
},
{
label: "deprecated DM/group access reason constants",
pattern: /\bDM_GROUP_ACCESS_REASON\b/u,
},
{
label: "deprecated group policy access helper",
pattern:
/\b(?:resolveSenderScopedGroupPolicy|evaluateSenderGroupAccess(?:ForPolicy)?|evaluateGroupRouteAccessForPolicy|evaluateMatchedGroupAccessForPolicy)\b/u,
},
{
label: "deprecated group access compatibility module",
pattern: /from\s+["']openclaw\/plugin-sdk\/group-access["']/u,
},
{
label: "deprecated command authorization helper",
pattern: /\bresolveSenderCommandAuthorization(?:WithRuntime)?\b/u,
},
{
label: "deprecated command auth SDK facade",
pattern: /from\s+["']openclaw\/plugin-sdk\/command-auth["']/u,
},
];
function collectBundledPluginProductionFiles(): string[] {
const extensionsDir = path.join(process.cwd(), "extensions");
return collectFilesSync(extensionsDir, {
includeFile(filePath) {
if (!isCodeFile(filePath)) {
return false;
}
const repoPath = relativeToCwd(filePath);
const classified = classifyBundledExtensionSourcePath(repoPath);
return classified.isProductionSource;
},
}).toSorted((left, right) => relativeToCwd(left).localeCompare(relativeToCwd(right)));
}
function main() {
const offenders: Array<{ file: string; line: number; label: string; text: string }> = [];
for (const file of collectBundledPluginProductionFiles()) {
const content = fs.readFileSync(file, "utf8");
const lines = content.split(/\r?\n/u);
for (const [index, line] of lines.entries()) {
for (const rule of RULES) {
if (rule.pattern.test(line)) {
offenders.push({
file: relativeToCwd(file),
line: index + 1,
label: rule.label,
text: line.trim(),
});
}
}
}
}
if (offenders.length > 0) {
console.error(
"Bundled plugin production code must use modern channel runtime and access seams.",
);
for (const offender of offenders) {
console.error(`- ${offender.file}:${offender.line}: ${offender.label}: ${offender.text}`);
}
process.exit(1);
}
console.log(
"OK: bundled plugin production code avoids deprecated channel runtime and access seams.",
);
}
main();