惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
人人都是产品经理
人人都是产品经理
Cisco Talos Blog
Cisco Talos Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
V
V2EX
博客园 - 三生石上(FineUI控件)
Martin Fowler
Martin Fowler
WordPress大学
WordPress大学
D
Docker
S
SegmentFault 最新的问题
博客园 - 聂微东
美团技术团队
Apple Machine Learning Research
Apple Machine Learning Research
月光博客
月光博客
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Last Week in AI
Last Week in AI
M
MIT News - Artificial intelligence
F
Fortinet All Blogs
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
The GitHub Blog
The GitHub Blog
GbyAI
GbyAI
L
LangChain Blog
Vercel News
Vercel News
博客园 - 叶小钗
MongoDB | Blog
MongoDB | Blog
Stack Overflow Blog
Stack Overflow Blog
H
Help Net Security
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
The Cloudflare Blog
Engineering at Meta
Engineering at Meta
T
Threat Research - Cisco Blogs
T
Threatpost
Scott Helme
Scott Helme
T
Tailwind CSS Blog
Latest news
Latest news
Stack Overflow Blog
Stack Overflow Blog
Blog — PlanetScale
Blog — PlanetScale
The Register - Security
The Register - Security
罗磊的独立博客
P
Proofpoint News Feed
腾讯CDC
S
Schneier on Security
雷峰网
雷峰网
A
About on SuperTechFans
T
Tenable Blog
F
Full Disclosure
Cyberwarzone
Cyberwarzone
博客园_首页
有赞技术团队
有赞技术团队
K
Kaspersky official blog

Recent Commits to openclaw:main

fix(memory): respect QMD status timeout fix(ui): prefer Talk source-reply final text · openclaw/openclaw@17c2e95 fix(scripts): timeout crabbox wrapper sanity checks · openclaw/openclaw@a0d2feb refactor(telegram): keep topic thread mapping plugin-local fix(memory): fail open when embedding recall stalls docs: expand MCP operator guide chore(ui): refresh fa control ui locale chore(ui): refresh nl control ui locale · openclaw/openclaw@53e0639 chore(ui): refresh vi control ui locale chore(ui): refresh pl control ui locale · openclaw/openclaw@ee39aa8 chore(ui): refresh th control ui locale chore(ui): refresh id control ui locale · openclaw/openclaw@fce45a2 chore(ui): refresh uk control ui locale chore(ui): refresh tr control ui locale · openclaw/openclaw@b335018 chore(ui): refresh ar control ui locale chore(ui): refresh it control ui locale · openclaw/openclaw@20ab73e chore(ui): refresh fr control ui locale · openclaw/openclaw@a041e39 chore(ui): refresh ko control ui locale · openclaw/openclaw@2e0d191 chore(ui): refresh ja-JP control ui locale · openclaw/openclaw@ec949a8 chore(ui): refresh es control ui locale · openclaw/openclaw@0b9193c chore(ui): refresh pt-BR control ui locale · openclaw/openclaw@aa56f59 chore(ui): refresh zh-TW control ui locale · openclaw/openclaw@10b4057 chore(ui): refresh zh-CN control ui locale · openclaw/openclaw@ecef6ae chore(ui): refresh de control ui locale · openclaw/openclaw@f456114 feat: improve MCP operator controls (#88536) · openclaw/openclaw@617c658 chore(lint): clean sms lint fallout · openclaw/openclaw@3258338 fix(ci): repair sms channel checks · openclaw/openclaw@3a4943e fix(e2e): make plugin sweep wrappers executable · openclaw/openclaw@84b025e fix(auto-reply): redact secrets in config show output (#88496) · openclaw/openclaw@a776de2 fix(ci): repair copilot sdk drift chore(lint): enable object and reassignment rules · openclaw/openclaw@f5eca3f docs: expand SMS channel setup guide · openclaw/openclaw@ea11b8a ci: harden Crabbox Testbox runs · openclaw/openclaw@d4f78c9 fix(webchat): preserve refresh-visible history and composer state (#8… fix(check): restore core typecheck feat: add Twilio SMS channel fix(telegram): support media message edits chore: remove stale unsafe assertion suppressions Revert "fix(ci): annotate unsafe boundary casts" fix(ci): keep unsafe assertion lint disabled Revert "fix(ci): clean core unsafe assertions" · openclaw/openclaw@4471335 test: remove channel test isolation hack fix(agents): clear stale compaction bindings fix(agents): skip below-target CLI compaction failures · openclaw/openclaw@5e1e029 chore: update dependencies · openclaw/openclaw@48ccc50 docs: add Skill Workshop guide docs: remove divider comments (#88115) fix(ci): clean core unsafe assertions fix(discord): deliver same-session channel replies fix(ci): annotate unsafe boundary casts · openclaw/openclaw@8a40f90 docs: add permission modes page · openclaw/openclaw@ae651e7 fix(ci): repair extension type drift · openclaw/openclaw@4d95ae3 perf: avoid blocking gateway bind on control ui build · openclaw/openclaw@e678225 chore(lint): enable structured clone rules · openclaw/openclaw@59694e8 Fix iMessage startup watch replay (#88406) · openclaw/openclaw@87664ed fix(ci): isolate timer-sensitive tests perf: lazy-load agent reply payload formatter · openclaw/openclaw@122ae5d refactor(telegram): persist plugin state in sqlite · openclaw/openclaw@930b371 chore(lint): enable additional cleanup rules · openclaw/openclaw@b9fe089 chore: remove stale dead code · openclaw/openclaw@444562b fix(ci): stabilize ui paste and telegram types · openclaw/openclaw@ce547bf fix(ci): satisfy strict nullish guards · openclaw/openclaw@d4d7fdb build(OpenClawKit): make ElevenLabsKit optional behind Talk trait · openclaw/openclaw@096bd13 chore(lint): enable more readability rules fix(ci): stop channel timers holding vitest open chore(lint): enable readability lint rules · openclaw/openclaw@deb7bc6 fix(ci): restore main validation · openclaw/openclaw@0211a3a perf: prewarm gateway runtime plugins · openclaw/openclaw@ade6e77 fix(slack): keep DM thread turns out of active steering · openclaw/openclaw@f1cb9f2 fix(commands): make /skill load workspace skills · openclaw/openclaw@667393b fix(telegram): align DM topic session routing · openclaw/openclaw@72c61bc test: keep timeout clamp checks under one second · openclaw/openclaw@b372af6 test: keep vitest cases under one second test: restore marketplace cleanup coverage · openclaw/openclaw@9f99acf fix(shared): restore number coercion barrel fix: clarify generated media reply prompts (#88458) · openclaw/openclaw@8a46790 fix(qa): clamp transport wait intervals fix(qa): clamp gateway restart polling fix(channels): clamp typing timers · openclaw/openclaw@92f1d90 fix(agents): clamp embedded run drain polling fix(sqlite): clamp WAL checkpoint intervals · openclaw/openclaw@287f531 fix(onboard): clamp gateway reachability polling · openclaw/openclaw@bb680a8 fix(feishu): clamp sequential queue timeouts · openclaw/openclaw@fab8d29 fix(nostr): bound seen tracker capacity · openclaw/openclaw@5b0036f fix(agents): clamp session suspension TTLs · openclaw/openclaw@11c050d fix(memory): clamp batch timeout minutes · openclaw/openclaw@84061c1 fix(gateway): clamp auth limiter prune intervals · openclaw/openclaw@a1d7a75 fix(memory): clamp sync interval timers · openclaw/openclaw@5c38c0c fix(channels): clamp draft stream throttles fix(gateway): clamp auth limiter durations fix(clickclack): normalize reconnect intervals fix(qa): clamp cron run poll intervals · openclaw/openclaw@83597b7 fix(gateway): bound health monitor intervals fix(auth): bound profile usage window expiries fix(auto-reply): clamp typing timers · openclaw/openclaw@db94eac fix(openai): convert realtime secret expiry · openclaw/openclaw@dca53af fix(heartbeat): advance stale scheduler deferrals · openclaw/openclaw@bbc4bee fix(build): preserve fresh startup metadata across rebuilds perf: cache log timestamp formatters fix(ui): localize tool error card label
feat(doctor): expose UI freshness health findings · openclaw/openclaw@2d3fa48
giodl73-repo · 2026-05-31 · via Recent Commits to openclaw:main

@@ -0,0 +1,123 @@

1+

import fs from "node:fs/promises";

2+

import os from "node:os";

3+

import path from "node:path";

4+

import { afterEach, describe, expect, it } from "vitest";

5+

import {

6+

detectUiProtocolFreshnessIssues,

7+

uiProtocolFreshnessIssueToHealthFinding,

8+

uiProtocolFreshnessIssueToRepairEffects,

9+

type UiProtocolFreshnessIssue,

10+

} from "./doctor-ui.js";

11+12+

const tempRoots: string[] = [];

13+14+

function issue(overrides: Partial<UiProtocolFreshnessIssue> = {}): UiProtocolFreshnessIssue {

15+

return {

16+

kind: "missing-assets",

17+

root: "/repo/openclaw",

18+

uiIndexPath: "/repo/openclaw/dist/control-ui/index.html",

19+

canBuild: true,

20+

...overrides,

21+

} as UiProtocolFreshnessIssue;

22+

}

23+24+

async function createOpenClawRoot(): Promise<string> {

25+

const root = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-doctor-ui-"));

26+

tempRoots.push(root);

27+

await fs.writeFile(path.join(root, "package.json"), JSON.stringify({ name: "openclaw" }));

28+

await fs.mkdir(path.join(root, "packages/gateway-protocol/src"), { recursive: true });

29+

await fs.writeFile(path.join(root, "packages/gateway-protocol/src/schema.ts"), "export {};\n");

30+

return root;

31+

}

32+33+

async function touch(filePath: string, date: Date): Promise<void> {

34+

await fs.mkdir(path.dirname(filePath), { recursive: true });

35+

await fs.writeFile(filePath, "");

36+

await fs.utimes(filePath, date, date);

37+

}

38+39+

describe("UI protocol freshness health mapping", () => {

40+

afterEach(async () => {

41+

await Promise.all(

42+

tempRoots.splice(0).map((root) => fs.rm(root, { recursive: true, force: true })),

43+

);

44+

});

45+46+

it("maps missing UI assets to a structured finding and dry-run effect", () => {

47+

const current = issue();

48+49+

expect(uiProtocolFreshnessIssueToHealthFinding(current)).toEqual(

50+

expect.objectContaining({

51+

checkId: "core/doctor/ui-protocol-freshness",

52+

severity: "warning",

53+

path: "/repo/openclaw/dist/control-ui/index.html",

54+

fixHint: expect.stringContaining("openclaw doctor --fix"),

55+

}),

56+

);

57+

expect(uiProtocolFreshnessIssueToRepairEffects(current)).toEqual([

58+

{

59+

kind: "process",

60+

action: "would-build-control-ui",

61+

target: "/repo/openclaw",

62+

dryRunSafe: false,

63+

},

64+

]);

65+

});

66+67+

it("maps stale UI assets to rebuild effects without file diffs", () => {

68+

const current = issue({

69+

kind: "stale-assets",

70+

changesSinceBuild: ["abc123 schema change"],

71+

});

72+

const finding = uiProtocolFreshnessIssueToHealthFinding(current);

73+74+

expect(finding.message).toContain("abc123 schema change");

75+

expect(finding.fixHint).toContain("openclaw doctor --fix --force");

76+

expect(uiProtocolFreshnessIssueToRepairEffects(current)).toEqual([

77+

{

78+

kind: "process",

79+

action: "would-rebuild-control-ui",

80+

target: "/repo/openclaw",

81+

dryRunSafe: false,

82+

},

83+

]);

84+

});

85+86+

it("does not report dry-run effects when UI sources are unavailable", () => {

87+

expect(uiProtocolFreshnessIssueToRepairEffects(issue({ canBuild: false }))).toEqual([]);

88+

});

89+90+

it("does not report stale assets when git finds no schema changes", async () => {

91+

const root = await createOpenClawRoot();

92+

const schemaPath = path.join(root, "packages/gateway-protocol/src/schema.ts");

93+

const uiIndexPath = path.join(root, "dist/control-ui/index.html");

94+

await touch(uiIndexPath, new Date("2026-01-01T00:00:00.000Z"));

95+

await touch(schemaPath, new Date("2026-01-02T00:00:00.000Z"));

96+97+

await expect(

98+

detectUiProtocolFreshnessIssues({

99+

root,

100+

async collectChangesSinceBuild() {

101+

return [];

102+

},

103+

}),

104+

).resolves.toEqual([]);

105+

});

106+107+

it("does not report stale assets when git history is unavailable", async () => {

108+

const root = await createOpenClawRoot();

109+

const schemaPath = path.join(root, "packages/gateway-protocol/src/schema.ts");

110+

const uiIndexPath = path.join(root, "dist/control-ui/index.html");

111+

await touch(uiIndexPath, new Date("2026-01-01T00:00:00.000Z"));

112+

await touch(schemaPath, new Date("2026-01-02T00:00:00.000Z"));

113+114+

await expect(

115+

detectUiProtocolFreshnessIssues({

116+

root,

117+

async collectChangesSinceBuild() {

118+

return null;

119+

},

120+

}),

121+

).resolves.toEqual([]);

122+

});

123+

});