mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 05:10:44 +00:00
fix(slack): isolate doctor contract API (#63192)
* Slack: isolate doctor contract API * chore: changelog * fix(slack): move doctor changelog entry to Unreleased * Plugins: lock Slack doctor sidecar metadata * Slack: fix changelog entry placement --------- Co-authored-by: @zimeg <zim@o526.net> Co-authored-by: George Pickett <gpickett00@gmail.com>
This commit is contained in:
@@ -42,6 +42,7 @@ Docs: https://docs.openclaw.ai
|
||||
- TTS/reply media: persist OpenClaw temp voice outputs into managed outbound media and allow them through reply-media normalization, so voice-note replies stop silently dropping. (#63511) Thanks @jetd1.
|
||||
- Agents/OpenAI: recover embedded GPT-style runs when reasoning-only or empty turns need bounded continuation, with replay-safe retry gating and incomplete-turn fallback when no visible answer arrives. (#66167) thanks @jalehman
|
||||
- Outbound/relay-status: suppress internal relay-status placeholder payloads (`No channel reply.`, `Replied in-thread.`, `Replied in #...`, wiki-update status variants ending in `No channel reply.`) before channel delivery so internal housekeeping text does not leak to users.
|
||||
- Slack/doctor: add a dedicated doctor-contract sidecar so config warmup paths such as `openclaw cron` no longer fall back to Slack's broader contract surface, which could trigger Slack-related config-read crashes on affected setups. (#63192) Thanks @shhtheonlyperson.
|
||||
|
||||
## 2026.4.12
|
||||
|
||||
|
||||
1
extensions/slack/doctor-contract-api.ts
Normal file
1
extensions/slack/doctor-contract-api.ts
Normal file
@@ -0,0 +1 @@
|
||||
export { normalizeCompatibilityConfig, legacyConfigRules } from "./src/doctor-contract.js";
|
||||
@@ -157,6 +157,13 @@ describe("bundled plugin metadata", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("keeps Slack's doctor contract sidecar on the bundled public surface", () => {
|
||||
const slack = listRepoBundledPluginMetadata().find((entry) => entry.dirName === "slack");
|
||||
expectArtifactPresence(slack?.publicSurfaceArtifacts, {
|
||||
contains: ["doctor-contract-api.js"],
|
||||
});
|
||||
});
|
||||
|
||||
it("loads tlon channel config metadata from the lightweight schema surface", () => {
|
||||
expect(collectRepoBundledChannelConfigsForTest("tlon")?.tlon).toEqual(
|
||||
expect.objectContaining({
|
||||
|
||||
@@ -61,6 +61,30 @@ describe("doctor-contract-registry getJiti", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("prefers doctor-contract-api over the broader contract-api surface", () => {
|
||||
const pluginRoot = makeTempDir();
|
||||
fs.writeFileSync(
|
||||
path.join(pluginRoot, "doctor-contract-api.js"),
|
||||
"export default {};\n",
|
||||
"utf-8",
|
||||
);
|
||||
fs.writeFileSync(path.join(pluginRoot, "contract-api.js"), "export default {};\n", "utf-8");
|
||||
mocks.loadPluginManifestRegistry.mockReturnValue({
|
||||
plugins: [{ id: "test-plugin", rootDir: pluginRoot }],
|
||||
diagnostics: [],
|
||||
});
|
||||
|
||||
listPluginDoctorLegacyConfigRules({
|
||||
workspaceDir: pluginRoot,
|
||||
env: {},
|
||||
});
|
||||
|
||||
expect(mocks.createJiti).toHaveBeenCalledTimes(1);
|
||||
expect(mocks.createJiti.mock.calls[0]?.[0]).toBe(
|
||||
path.join(pluginRoot, "doctor-contract-api.js"),
|
||||
);
|
||||
});
|
||||
|
||||
it("narrows touched-path doctor ids for scoped dry-run validation", () => {
|
||||
expect(
|
||||
collectRelevantDoctorPluginIdsForTouchedPaths({
|
||||
|
||||
Reference in New Issue
Block a user