diff --git a/docs/协作/B05-交付-01.md b/docs/协作/B05-交付-01.md new file mode 100644 index 0000000..4da1323 --- /dev/null +++ b/docs/协作/B05-交付-01.md @@ -0,0 +1,53 @@ +# B05 / YC-009:TodoWrite 交付记录 01 + +日期:2026-10-21。状态:开发实现与离线验证完成,待验收;不预填验收通过。 + +- 需求来源:`9069c604e03505b91b5b9731d11d47727b168635`,`B05-需求.md`。 +- 开发基线:`8d10743fb2643b8e0aaf4495b38eb84f71b1e7f7`。 +- 完整代码提交:`d423d59b08395360cd7263709d4560ab436d7c0c`。 +- 本批不发布安装包,不调整模型桥、权限策略、项目数据库或其他计划卡设计。 + +## 实现与关键决定 + +1. 新增 `TodoWriteView.tsx`:只读规范化 args / `_rawInput`,兼容既有 todos / steps 及历史工具别名;保留 task ID、content、activeForm 和状态。完成数和总数按规范化列表计算。 +2. 使用现代 `cr-tool-plan-task*` 结构与专用头部,去掉重复标题。merge 显示“进度 completed/total”;空与错误仅显示相应头部,运行中空列表附接收中状态。 +3. 复用既有 `selectPlanTasks` 纯窗口算法,默认最多五项。优先第一个进行中任务,否则最后一个已完成任务,再否则从首项开始;不新增分页或更多按钮。 +4. 完成项删除线并弱化,进行中使用 activeForm 和加粗,状态使用 SVG / 圆点,不再使用 OK / > / - / x 占位。样式按照需求提供的 REA 静态契约实现。 +5. `SourceToolExpandable` 增加仅 Todo 使用的 retained expand-signal 开关和独立 disclosure key。真实 isLastContent 边沿控制展开;同值重挂载保留手动选择;session / tool / part 身份隔离。其他工具默认行为不变。 +6. 不向普通列表追加 SDK 原始成功文本;不改写持久化结果、不合并历史工具快照。 +7. 增加专用可选 `onTodoTaskClick`,字段为 toolCallId / toolName / taskId,支持点击、Enter、Space。当前没有证实的应用宿主目标,因此默认不传回调、不显示按钮角色或动作箭头,不复用计划预览冒充待办操作。 + +## 变更文件 + +- `src/renderer/src/workbuddy/conversation/TodoWriteView.tsx`(新增) +- `src/renderer/src/workbuddy/conversation/todo-write.css`(新增) +- `src/renderer/src/workbuddy/conversation/ToolCallRenderer.tsx` +- `src/renderer/src/workbuddy/conversation/SourceToolHeader.tsx` +- `src/renderer/src/workbuddy/conversation/source-labels.ts` +- `scripts/todo-write-regression.tsx`(新增) +- `scripts/todo-write-dom-regression.tsx`(新增) +- `scripts/conversation-renderer-regression.tsx` +- `scripts/run-alignment-regression.mjs` + +## 验证 + +以下命令在 Linux 开发环境执行,没有启动真实 Claude SDK、外部模型服务或用户电脑,没有加载用户发布会话。 + +| 命令 | 结果 | 证据 | +|---|---|---| +| `npm run build` | exit 0,类型检查与生产构建通过 | `evidence/b05-01/build.log` | +| `npm run test:conversation` | exit 0 | `evidence/b05-01/conversation.log` | +| `npm run test:alignment` | exit 0,12 个离线套件;此单独运行明确跳过 DOM | `evidence/b05-01/alignment.log` | +| `YCODE_TEST_DOM_MODULE=/tmp/ycode-b01-dom/node_modules/jsdom npm run test:alignment:dom` | exit 0,12 个离线套件与 10 个 DOM 套件 | `evidence/b05-01/alignment-dom.log` | + +新增聚焦测试已接入上述 alignment 入口,共 29 项投影/SSR 检查与 42 项 DOM 断言:投影/SSR 覆盖窗口夹具、状态、标题、空/失败、别名、原始输入与非突变;DOM 覆盖真实 TodoWriteView 和 CompletedFold 组合、位置边沿、手动选择、相同信号重挂载、会话/工具隔离、合法历史快照和可选回调键盘事件。使用合成数据,不修改真实会话。 + +测试依赖按项目既有外置 jsdom 约定提供;上述绝对路径是本次环境路径,其他环境需替换为其已安装的 jsdom 模块路径。严格 DOM 入口缺少依赖会失败,不将跳过当通过。 + +## 剩余风险与验收边界 + +- AC9.8:组件可选回调已验证,但实际应用宿主任务点击目标未实现,不能宣称完整业务交互通过。默认非交互是刻意避免伪导航。 +- AC9.9:真实 Electron 浅色、深色、窄屏、长文本及七项任务截图未完成;DOM 不测真实像素、文本溢出和动画过程。当前浏览器执行环境受限,不绕过安全限制;由具备环境的验收端补测。 +- 复用了现有 recovered CheckIcon / LoaderIcon / FailedIcon。没有独立确认名为 TaskCheckIcon 的精确原版资产;不能声称图标逐像素一致。 +- 新 CSS 来自需求中已留存的 REA 静态数值,不代表当前原版 CSS 激活分支与实时动效已复核。仍需补原版 REA 运行证据。 +- 交付没有修改验收记录;验收端应固定完整代码 SHA 后记录实际结果。 diff --git a/docs/协作/evidence/b05-01/alignment-dom.log b/docs/协作/evidence/b05-01/alignment-dom.log new file mode 100644 index 0000000..31e9580 --- /dev/null +++ b/docs/协作/evidence/b05-01/alignment-dom.log @@ -0,0 +1,87 @@ +npm warn Unknown env config "http-proxy". This will stop working in the next major version of npm. + +> ycode@0.0.10 test:alignment:dom +> node scripts/run-alignment-regression.mjs --require-dom + +PASS model alignment: fresh/legacy migration, new/edit/default/delete/reload, valid selection (offline host fixtures) +PASS model settings: deferred owner switch, rename mapping, addition selection, empty deletion, immutable history +PASS session factory: first-send preference, mode preservation, invalid permission rejection (isolated ports) +{"historyMessages":10000,"bytes":747781,"parseMs":2.923016000000004,"storeHydrationMs":0.14862899999999968,"note":"Node parsing/store benchmark only, not browser rendering or Windows IPC performance"} +session-composer-alignment: loading/cache/retry/races/model/permissions/modes/SSR passed +alignment-conversation: local groups, original expanded order, question projection and truthful status passed +A01 native MessageBubble identity aliases, immutable inputs and ordinary raw output passed +A01 imported native card, linked dedup and unknown-position compatibility passed +question-answer-shell: structural and recovered CSS contracts passed +question-answer-shell: DOM hierarchy, controls linkage, click, Enter, Space and inert contracts passed +Runtime progress, session-grant scope and approval lifecycle regressions passed +Permission intercept static rendering passed; interactive keyboard/focus remains UI acceptance +PASS window six second active +PASS window seven fifth active +PASS window seven first active +PASS window seven last active +PASS window seven all pending +PASS window seven all completed +PASS window only fourth completed +PASS window multiple active uses first +PASS window empty +PASS window one +PASS window five +PASS window long middle +PASS alias TodoWrite +PASS alias todo_write +PASS alias todoWrite +PASS alias todo-write +PASS ordinary tools do not enter dedicated view +PASS args and raw input false +PASS args and raw input true +PASS args and raw input json +PASS historical steps retain compatible task aliases +PASS single dedicated title, modern status rows and output projection +PASS merge progress title computed from complete list not five-row window +PASS empty running is header only with receiving cue +PASS empty finished is header only without receiving cue +PASS failure is dedicated error header only +PASS without host callback rows are not fake buttons +PASS malformed raw input falls back without modifying original data +PASS long and escaped content stays plain text with full title +todo-write: 29 projection and SSR checks passed; real Electron visual acceptance not covered +[claude-permission] {"permissionMode":"default-sandbox","agentMode":"craft","sdkMode":"unknown","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"callback","toolCall":"e3b98a4da31a127d","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":false,"branch":"permission-approval"} +[claude-permission] {"permissionMode":"default-sandbox","agentMode":"craft","sdkMode":"unknown","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"callback","toolCall":"e3b98a4da31a127d","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":false,"branch":"permission-approval"} +[claude-permission] {"permissionMode":"default-sandbox","agentMode":"craft","sdkMode":"unknown","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"callback","toolCall":"e3b98a4da31a127d","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":false,"branch":"permission-approval"} +[claude-permission] {"permissionMode":"full-access","agentMode":"ask","sdkMode":"unknown","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"callback","toolCall":"e3b98a4da31a127d","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":false,"branch":"mode-or-inactive-deny"} +[claude-permission] {"permissionMode":"full-access","agentMode":"plan","sdkMode":"unknown","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"callback","toolCall":"e3b98a4da31a127d","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":false,"branch":"mode-or-inactive-deny"} +[claude-permission] {"permissionMode":"full-access","agentMode":"craft","sdkMode":"unknown","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"callback","toolCall":"e3b98a4da31a127d","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":false,"branch":"full-access-preauthorized"} +[claude-permission] {"permissionMode":"full-access","agentMode":"craft","sdkMode":"unknown","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"callback","toolCall":"e3b98a4da31a127d","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":true,"branch":"full-access-preauthorized"} +[claude-permission] {"permissionMode":"full-access","agentMode":"craft","sdkMode":"unknown","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"callback","toolCall":"e3b98a4da31a127d","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":false,"branch":"full-access-preauthorized"} +[claude-permission] {"permissionMode":"full-access","agentMode":"craft","sdkMode":"unknown","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"callback","toolCall":"e3b98a4da31a127d","decisionCategory":"subcommandResults","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":false,"branch":"full-access-preauthorized"} +[claude-permission] {"permissionMode":"full-access","agentMode":"craft","sdkMode":"unknown","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"callback","toolCall":"e3b98a4da31a127d","decisionCategory":"safetyCheck","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":false,"branch":"full-access-preauthorized"} +[claude-permission] {"permissionMode":"full-access","agentMode":"craft","sdkMode":"unknown","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"callback","toolCall":"e3b98a4da31a127d","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":true,"matchedAskRule":false,"branch":"full-access-preauthorized"} +[claude-permission] {"permissionMode":"full-access","agentMode":"craft","sdkMode":"unknown","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"callback","toolCall":"e3b98a4da31a127d","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":false,"branch":"full-access-preauthorized"} +[claude-permission] {"permissionMode":"full-access","agentMode":"craft","sdkMode":"unknown","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"callback","toolCall":"e3b98a4da31a127d","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":false,"branch":"full-access-preauthorized"} +[claude-permission] {"permissionMode":"default-sandbox","agentMode":"craft","sdkMode":"unknown","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"callback","toolCall":"e3b98a4da31a127d","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":true,"branch":"rule-approval"} +[claude-permission] {"permissionMode":"default-sandbox","agentMode":"craft","sdkMode":"unknown","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"callback","toolCall":"e3b98a4da31a127d","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":false,"branch":"permission-approval"} +[claude-permission] {"permissionMode":"default-sandbox","agentMode":"craft","sdkMode":"unknown","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"callback","toolCall":"e3b98a4da31a127d","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":false,"branch":"error-deny"} +[claude-permission] {"permissionMode":"default-sandbox","agentMode":"craft","sdkMode":"unknown","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"callback","toolCall":"e3b98a4da31a127d","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":false,"branch":"permission-approval"} +[claude-permission] {"permissionMode":"default-sandbox","agentMode":"craft","sdkMode":"unknown","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"callback","toolCall":"85aafbf52a5144b5","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":false,"branch":"business-question"} +[claude-permission] {"permissionMode":"default-sandbox","agentMode":"craft","sdkMode":"unknown","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"callback","toolCall":"85aafbf52a5144b5","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":false,"branch":"business-question"} +Claude host approval policy unit checks passed (no SDK process/application/matching verification) +[claude-permission] {"permissionMode":"full-access","agentMode":"plan","sdkMode":"plan","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"hook","toolCall":"unknown","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":"unknown","branch":"mode-or-inactive-deny"} +Mock SDK replay lifecycle passed: fail closed, retry, session isolation, independent mode guard +B03 offline host policy: 276 checks passed; no real SDK/CLI/model execution. +task popconfirm DOM regression: 34 checks passed (jsdom, not pixel validation) +question-interaction: 24 DOM behavioral checks passed +question-identity: 30 A01 DOM checks passed (not Electron/pixel/SDK acceptance) +Question composer DOM: 21 checks passed (not pixel/SDK verification) +completed-fold-nested: real question/tool/thinking/local-summary remount, event, keyboard and identity contracts passed +completed-fold-native-identity: real reducer done correction, native IDs, insertion/reorder, repeated outer toggles, message isolation and legacy fallback passed +Permission intercept DOM: 49 checks passed (not pixel/SDK verification) +{"result":"PASS","suite":"reasoning-follow-dom","assertions":63,"evidence":"Actual ReactDOM with synthetic geometry/RAF/resize; not native scroll or pixel evidence"} +todo-write-dom: 42 actual TodoWrite/CompletedFold checks passed; no Electron/pixel claim +{"checks":37,"passed":true,"scope":"Isolated React DOM and CSS contracts; no native keyboard/layout/pixel acceptance"} +{"result":"PASS","phase":"alignment-offline","suites":12} +{"result":"PASS","phase":"alignment-dom","suites":10} +npm notice +npm notice New major version of npm available! 11.9.0 -> 12.2.0 +npm notice Changelog: https://github.com/npm/cli/releases/tag/v12.2.0 +npm notice To update run: npm install -g npm@12.2.0 +npm notice diff --git a/docs/协作/evidence/b05-01/alignment.log b/docs/协作/evidence/b05-01/alignment.log new file mode 100644 index 0000000..f93c761 --- /dev/null +++ b/docs/协作/evidence/b05-01/alignment.log @@ -0,0 +1,72 @@ +npm warn Unknown env config "http-proxy". This will stop working in the next major version of npm. + +> ycode@0.0.10 test:alignment +> node scripts/run-alignment-regression.mjs + +PASS model alignment: fresh/legacy migration, new/edit/default/delete/reload, valid selection (offline host fixtures) +PASS model settings: deferred owner switch, rename mapping, addition selection, empty deletion, immutable history +PASS session factory: first-send preference, mode preservation, invalid permission rejection (isolated ports) +{"historyMessages":10000,"bytes":747781,"parseMs":2.8995029999999957,"storeHydrationMs":0.1266159999999985,"note":"Node parsing/store benchmark only, not browser rendering or Windows IPC performance"} +session-composer-alignment: loading/cache/retry/races/model/permissions/modes/SSR passed +alignment-conversation: local groups, original expanded order, question projection and truthful status passed +A01 native MessageBubble identity aliases, immutable inputs and ordinary raw output passed +A01 imported native card, linked dedup and unknown-position compatibility passed +question-answer-shell: structural and recovered CSS contracts passed +question-answer-shell: DOM checks NOT RUN (set YCODE_TEST_DOM_MODULE to an available jsdom module) +Runtime progress, session-grant scope and approval lifecycle regressions passed +Permission intercept static rendering passed; interactive keyboard/focus remains UI acceptance +PASS window six second active +PASS window seven fifth active +PASS window seven first active +PASS window seven last active +PASS window seven all pending +PASS window seven all completed +PASS window only fourth completed +PASS window multiple active uses first +PASS window empty +PASS window one +PASS window five +PASS window long middle +PASS alias TodoWrite +PASS alias todo_write +PASS alias todoWrite +PASS alias todo-write +PASS ordinary tools do not enter dedicated view +PASS args and raw input false +PASS args and raw input true +PASS args and raw input json +PASS historical steps retain compatible task aliases +PASS single dedicated title, modern status rows and output projection +PASS merge progress title computed from complete list not five-row window +PASS empty running is header only with receiving cue +PASS empty finished is header only without receiving cue +PASS failure is dedicated error header only +PASS without host callback rows are not fake buttons +PASS malformed raw input falls back without modifying original data +PASS long and escaped content stays plain text with full title +todo-write: 29 projection and SSR checks passed; real Electron visual acceptance not covered +[claude-permission] {"permissionMode":"default-sandbox","agentMode":"craft","sdkMode":"unknown","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"callback","toolCall":"e3b98a4da31a127d","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":false,"branch":"permission-approval"} +[claude-permission] {"permissionMode":"default-sandbox","agentMode":"craft","sdkMode":"unknown","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"callback","toolCall":"e3b98a4da31a127d","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":false,"branch":"permission-approval"} +[claude-permission] {"permissionMode":"default-sandbox","agentMode":"craft","sdkMode":"unknown","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"callback","toolCall":"e3b98a4da31a127d","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":false,"branch":"permission-approval"} +[claude-permission] {"permissionMode":"full-access","agentMode":"ask","sdkMode":"unknown","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"callback","toolCall":"e3b98a4da31a127d","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":false,"branch":"mode-or-inactive-deny"} +[claude-permission] {"permissionMode":"full-access","agentMode":"plan","sdkMode":"unknown","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"callback","toolCall":"e3b98a4da31a127d","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":false,"branch":"mode-or-inactive-deny"} +[claude-permission] {"permissionMode":"full-access","agentMode":"craft","sdkMode":"unknown","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"callback","toolCall":"e3b98a4da31a127d","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":false,"branch":"full-access-preauthorized"} +[claude-permission] {"permissionMode":"full-access","agentMode":"craft","sdkMode":"unknown","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"callback","toolCall":"e3b98a4da31a127d","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":true,"branch":"full-access-preauthorized"} +[claude-permission] {"permissionMode":"full-access","agentMode":"craft","sdkMode":"unknown","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"callback","toolCall":"e3b98a4da31a127d","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":false,"branch":"full-access-preauthorized"} +[claude-permission] {"permissionMode":"full-access","agentMode":"craft","sdkMode":"unknown","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"callback","toolCall":"e3b98a4da31a127d","decisionCategory":"subcommandResults","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":false,"branch":"full-access-preauthorized"} +[claude-permission] {"permissionMode":"full-access","agentMode":"craft","sdkMode":"unknown","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"callback","toolCall":"e3b98a4da31a127d","decisionCategory":"safetyCheck","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":false,"branch":"full-access-preauthorized"} +[claude-permission] {"permissionMode":"full-access","agentMode":"craft","sdkMode":"unknown","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"callback","toolCall":"e3b98a4da31a127d","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":true,"matchedAskRule":false,"branch":"full-access-preauthorized"} +[claude-permission] {"permissionMode":"full-access","agentMode":"craft","sdkMode":"unknown","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"callback","toolCall":"e3b98a4da31a127d","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":false,"branch":"full-access-preauthorized"} +[claude-permission] {"permissionMode":"full-access","agentMode":"craft","sdkMode":"unknown","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"callback","toolCall":"e3b98a4da31a127d","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":false,"branch":"full-access-preauthorized"} +[claude-permission] {"permissionMode":"default-sandbox","agentMode":"craft","sdkMode":"unknown","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"callback","toolCall":"e3b98a4da31a127d","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":true,"branch":"rule-approval"} +[claude-permission] {"permissionMode":"default-sandbox","agentMode":"craft","sdkMode":"unknown","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"callback","toolCall":"e3b98a4da31a127d","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":false,"branch":"permission-approval"} +[claude-permission] {"permissionMode":"default-sandbox","agentMode":"craft","sdkMode":"unknown","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"callback","toolCall":"e3b98a4da31a127d","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":false,"branch":"error-deny"} +[claude-permission] {"permissionMode":"default-sandbox","agentMode":"craft","sdkMode":"unknown","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"callback","toolCall":"e3b98a4da31a127d","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":false,"branch":"permission-approval"} +[claude-permission] {"permissionMode":"default-sandbox","agentMode":"craft","sdkMode":"unknown","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"callback","toolCall":"85aafbf52a5144b5","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":false,"branch":"business-question"} +[claude-permission] {"permissionMode":"default-sandbox","agentMode":"craft","sdkMode":"unknown","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"callback","toolCall":"85aafbf52a5144b5","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":false,"branch":"business-question"} +Claude host approval policy unit checks passed (no SDK process/application/matching verification) +[claude-permission] {"permissionMode":"full-access","agentMode":"plan","sdkMode":"plan","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"hook","toolCall":"unknown","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":"unknown","branch":"mode-or-inactive-deny"} +Mock SDK replay lifecycle passed: fail closed, retry, session isolation, independent mode guard +B03 offline host policy: 276 checks passed; no real SDK/CLI/model execution. +{"result":"PASS","phase":"alignment-offline","suites":12} +{"result":"SKIP","phase":"alignment-dom","suites":10,"reason":"YCODE_TEST_DOM_MODULE is not set; DOM coverage was not run. Use --require-dom to forbid this skip."} diff --git a/docs/协作/evidence/b05-01/build.log b/docs/协作/evidence/b05-01/build.log new file mode 100644 index 0000000..775ba20 --- /dev/null +++ b/docs/协作/evidence/b05-01/build.log @@ -0,0 +1,670 @@ +npm warn Unknown env config "http-proxy". This will stop working in the next major version of npm. + +> ycode@0.0.10 build +> npm run typecheck && electron-vite build + +npm warn Unknown env config "http-proxy". This will stop working in the next major version of npm. + +> ycode@0.0.10 typecheck +> tsc --noEmit -p tsconfig.node.json && tsc --noEmit -p tsconfig.web.json + +vite v8.3.4 building ssr environment for production... +transforming... +✓ 454 modules transformed. +rendering chunks... +out/main/index.mjs 1,656.15 kB + +✓ built in 504ms +vite v8.3.4 building ssr environment for production... +transforming... +✓ 2 modules transformed. +rendering chunks... +out/preload/index.cjs 16.06 kB + +✓ built in 10ms +vite v8.3.4 building client environment for production... +transforming... +✓ 3046 modules transformed. +rendering chunks... +out/renderer/settings.html 1.55 kB +out/renderer/index.html 1.73 kB +out/renderer/assets/KaTeX_Size3-Regular-CTq5MqoE.woff 4.42 kB +out/renderer/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 4.92 kB +out/renderer/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 5.20 kB +out/renderer/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 5.46 kB +out/renderer/assets/KaTeX_Size4-Regular-BF-4gkZK.woff 5.98 kB +out/renderer/assets/KaTeX_Size2-Regular-oD1tc_U0.woff 6.18 kB +out/renderer/assets/KaTeX_Size1-Regular-C195tn64.woff 6.49 kB +out/renderer/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 6.90 kB +out/renderer/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 6.91 kB +out/renderer/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf 7.58 kB +out/renderer/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff 7.65 kB +out/renderer/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff 7.71 kB +out/renderer/assets/archify-owner-avatar-BdE-HOjX.jpg 9.46 kB +out/renderer/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 9.64 kB +out/renderer/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 10.34 kB +out/renderer/assets/KaTeX_Size4-Regular-DWFBv043.ttf 10.36 kB +out/renderer/assets/KaTeX_Script-Regular-D5yQViql.woff 10.58 kB +out/renderer/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 11.31 kB +out/renderer/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 11.34 kB +out/renderer/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf 11.50 kB +out/renderer/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 12.02 kB +out/renderer/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 12.21 kB +out/renderer/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf 12.22 kB +out/renderer/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff 12.31 kB +out/renderer/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf 12.34 kB +out/renderer/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf 12.36 kB +out/renderer/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff 13.20 kB +out/renderer/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff 13.29 kB +out/renderer/assets/workbuddy-buddy-thumbnail-2713ed5b-CUhW0EYr.png 13.42 kB +out/renderer/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 13.56 kB +out/renderer/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff 14.11 kB +out/renderer/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff 14.40 kB +out/renderer/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff 16.02 kB +out/renderer/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 16.40 kB +out/renderer/assets/KaTeX_Math-Italic-t53AETM-.woff2 16.44 kB +out/renderer/assets/KaTeX_Script-Regular-C5JkGWo-.ttf 16.64 kB +out/renderer/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 16.78 kB +out/renderer/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 16.98 kB +out/renderer/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff 18.66 kB +out/renderer/assets/KaTeX_Math-Italic-DA0__PXp.woff 18.74 kB +out/renderer/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff 19.41 kB +out/renderer/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf 19.43 kB +out/renderer/assets/KaTeX_Fraktur-Regular-CB_wures.ttf 19.57 kB +out/renderer/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf 19.58 kB +out/renderer/assets/KaTeX_Main-Italic-BMLOBm91.woff 19.67 kB +out/renderer/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf 22.36 kB +out/renderer/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf 24.50 kB +out/renderer/assets/KaTeX_Main-Bold-Cx986IdX.woff2 25.32 kB +out/renderer/assets/KaTeX_Main-Regular-B22Nviop.woff2 26.27 kB +out/renderer/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf 27.55 kB +out/renderer/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 28.07 kB +out/renderer/assets/KaTeX_Main-Bold-Jm3AIy58.woff 29.91 kB +out/renderer/assets/KaTeX_Main-Regular-Dr94JaBh.woff 30.77 kB +out/renderer/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf 31.19 kB +out/renderer/assets/KaTeX_Math-Italic-flOr_0UB.ttf 31.30 kB +out/renderer/assets/design-case-3-DaIvrslH.png 32.76 kB +out/renderer/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf 32.96 kB +out/renderer/assets/KaTeX_AMS-Regular-DMm9YOAa.woff 33.51 kB +out/renderer/assets/KaTeX_Main-Italic-3WenGoN9.ttf 33.58 kB +out/renderer/assets/design-case-4-0hVdAJQR.png 45.16 kB +out/renderer/assets/design-case-2-BH_iQ5r3.png 45.56 kB +out/renderer/assets/KaTeX_Main-Bold-waoOVXN0.ttf 51.33 kB +out/renderer/assets/design-case-1-DOYiafVz.png 52.97 kB +out/renderer/assets/KaTeX_Main-Regular-ypZvNtVU.ttf 53.58 kB +out/renderer/assets/KaTeX_AMS-Regular-DRggAlZN.ttf 63.63 kB +out/renderer/assets/workbuddy-appearance-dark-CXQX3TZX.png 109.34 kB +out/renderer/assets/workbuddy-appearance-light-BbpPCukh.png 113.02 kB +out/renderer/assets/codicon-ngg6Pgfi-ngg6Pgfi.ttf 121.97 kB +out/renderer/assets/kimi-DiLyRSiJ.svg 129.22 kB +out/renderer/assets/json.worker-DEWrzUkU-DlQJfCLu.js 438.15 kB +out/renderer/assets/worker-portable-D1lwTqsk-D1lwTqsk.js 442.77 kB +out/renderer/assets/landing-hero-B6659kdy.png 629.28 kB +out/renderer/assets/html.worker-BC4B-9NY-C21OBAfO.js 756.13 kB +out/renderer/assets/css.worker-D7wyZb8r-DjOdNjkq.js 1,086.84 kB +out/renderer/assets/ts.worker-BsXRl7a--ByKYw2y-.js 8,119.57 kB +out/renderer/assets/ArtifactPierreDiff-Pvasiehm.css 1.15 kB +out/renderer/assets/GeneralSettingsPanel-BMcnXzoL.css 1.22 kB +out/renderer/assets/PrivateRuntimesSettingsPanel-EdeAJ36I.css 2.27 kB +out/renderer/assets/AgentsSettingsPanel-D7jOqSpF.css 2.48 kB +out/renderer/assets/AboutHelpSettingsPanel-CvF9RRxe.css 5.68 kB +out/renderer/assets/updates-ui-DMMyH1QT.css 6.55 kB +out/renderer/assets/AppearanceSettingsPanel-5CpGnhJ2.css 8.01 kB +out/renderer/assets/ShortcutsSettingsPanel-DwQcnFCC.css 17.84 kB +out/renderer/assets/MemorySettingsPanel-BborA2GL.css 32.21 kB +out/renderer/assets/ModelSettingsPanel-CFoDDMfH.css 88.96 kB +out/renderer/assets/PersonalizationSettingsPanel-D6czCIoD.css 98.51 kB +out/renderer/assets/app-BWjvCN9X.css 256.94 kB +out/renderer/assets/index-BQNslUuB.css 2,672.71 kB +out/renderer/assets/pie-WAS4IAKB-DKyretgv.js 0.11 kB +out/renderer/assets/info-A6RAGUB7-BbuYkEQc.js 0.11 kB +out/renderer/assets/radar-RG4KPBEZ-DxOoeCNQ.js 0.11 kB +out/renderer/assets/packet-AYTQ26CC-5rw3f48a.js 0.11 kB +out/renderer/assets/cynefin-OW5HDTMX-DcWHdUdD.js 0.11 kB +out/renderer/assets/treemap-WGGIJYW6-Db5Fv2Px.js 0.11 kB +out/renderer/assets/wardley-WFR3VGLG-Cw51bcpw.js 0.11 kB +out/renderer/assets/gitGraph-4MIJSDKK-CTA_mL7Y.js 0.12 kB +out/renderer/assets/railroad-74A4TZTK-DXj7b3sH.js 0.12 kB +out/renderer/assets/treeView-Q6P3EWNA-CwSIBnHm.js 0.12 kB +out/renderer/assets/railroad-peg-WCYAUIDC-DquA166b.js 0.12 kB +out/renderer/assets/architecture-7GRP2DOG-Bqw4dsRW.js 0.12 kB +out/renderer/assets/railroad-abnf-HS5TGJTU-BRdGQKor.js 0.12 kB +out/renderer/assets/railroad-ebnf-LZEXJU2U-DZkQfJQF.js 0.12 kB +out/renderer/assets/eventmodeling-NTZA5JFV-Cy7WZVhw.js 0.12 kB +out/renderer/assets/array-75Ih5Qg4.js 0.16 kB +out/renderer/assets/channel-BWQK_ajg.js 0.25 kB +out/renderer/assets/init-DHdG6DHP.js 0.27 kB +out/renderer/assets/chunk-Y2CYZVJY-CrOJDJJy.js 0.38 kB +out/renderer/assets/chunk-JWPE2WC7-BWmaSNkB.js 0.42 kB +out/renderer/assets/chunk-2Q5K7J3B-BBOGhvIe.js 0.44 kB +out/renderer/assets/prism-tsx-BJWEHjlk.js 0.48 kB +out/renderer/assets/chunk-5VM5RSS4-D50WUAUX.js 0.52 kB +out/renderer/assets/chunk-XXDRQBXY-BsO966Nz.js 0.58 kB +out/renderer/assets/flowDiagram-HODETNUW-BTgZ3hZ4.js 0.59 kB +out/renderer/assets/prism-json-DxLGXN1o.js 0.62 kB +out/renderer/assets/codeowners-C7Y3CTAA-DLFDeFSM.js 0.75 kB +out/renderer/assets/prism-clike-BcH_eOfE.js 0.89 kB +out/renderer/assets/tsv-DVa1_Ovr-Dcnz2zsv.js 0.94 kB +out/renderer/assets/shellsession-C0HwRpr0-DSJrX8zi.js 0.96 kB +out/renderer/assets/javascript-DGySzfUB-CQaVVFGk.js 0.99 kB +out/renderer/assets/settings-BqWrzhuc.js 1.01 kB +out/renderer/assets/infoDiagram-27XIBGKW-BpX7PJd3.js 1.09 kB +out/renderer/assets/swimlanesDiagram-VR7AAH4N-DftsxObZ.js 1.09 kB +out/renderer/assets/html-derivative-D3Jld805-DnSa01yF.js 1.10 kB +out/renderer/assets/prism-go-Cw8Jg9YT.js 1.11 kB +out/renderer/assets/classDiagram-ZZMXUADV-DfaHi3gl.js 1.16 kB +out/renderer/assets/classDiagram-v2-VYDZK3BY-CuhvyBCV.js 1.16 kB +out/renderer/assets/stateDiagram-v2-MP3YSRHH-BEU-HhX7.js 1.16 kB +out/renderer/assets/qmldir-DIq06gp2-Dk3xkylH.js 1.20 kB +out/renderer/assets/git-rebase-CgwCWTNR-Dy4BOb63.js 1.23 kB +out/renderer/assets/chunk-POPQ4Y6H-m-QFhyU7.js 1.23 kB +out/renderer/assets/azcli-Bsxmaz-H-Dgh56k5-.js 1.26 kB +out/renderer/assets/personalization-prefs-DASR3vwn.js 1.28 kB +out/renderer/assets/csv-BRhERoQG-g8SHvOgt.js 1.36 kB +out/renderer/assets/prism-latex-CHSuA_Lo.js 1.38 kB +out/renderer/assets/jsx-runtime-C48wkPcG.js 1.41 kB +out/renderer/assets/Switch-lqp_PN8l.js 1.46 kB +out/renderer/assets/git-commit-DGtBy1vY-D-8ck59F.js 1.47 kB +out/renderer/assets/AgentsSettingsPanel-COZMCaB6.js 1.56 kB +out/renderer/assets/xsl-DV28r3Jw-BVd5CgjJ.js 1.59 kB +out/renderer/assets/dotenv-DXc2fSbR-CJy04BVY.js 1.62 kB +out/renderer/assets/general-settings-icons-DOmPIusw.js 1.64 kB +out/renderer/assets/prism-scala-CRTYzCpy.js 1.65 kB +out/renderer/assets/ini-D4-1Iswn-DaNDgFS8.js 1.65 kB +out/renderer/assets/prism-typescript-D-7ZUUQ-.js 1.65 kB +out/renderer/assets/sizeCapture-INFHLROL-CCEMv_MJ.js 1.68 kB +out/renderer/assets/csp-Bsbijh2H-033SDyRW.js 1.69 kB +out/renderer/assets/sparql-Mj-YIaDH-BykJ7CZ3.js 1.71 kB +out/renderer/assets/prism-css-Cmyw76Xa.js 1.73 kB +out/renderer/assets/ini-DMSv7OY2-BXeXsWON.js 1.74 kB +out/renderer/assets/rolldown-runtime-BJCASTsb-DKQFAHUF.js 1.78 kB +out/renderer/assets/line-XXWW1d8G.js 1.89 kB +out/renderer/assets/fortran-fixed-form-D91DiZLE-CdOEPerJ.js 1.91 kB +out/renderer/assets/docker-B7J3eHK7-QmwgNdK9.js 1.96 kB +out/renderer/assets/hxml-938TheZ7-RCVJURv9.js 1.97 kB +out/renderer/assets/desktop-BwI-o01e-CG4hU2BG.js 2.03 kB +out/renderer/assets/ordinal-CmpyCcm_.js 2.22 kB +out/renderer/assets/prism-c-B7tsC1jE.js 2.23 kB +out/renderer/assets/rolldown-runtime-EITvVbkG.js 2.32 kB +out/renderer/assets/erb-BgMB3Uiw-DolD8jZl.js 2.40 kB +out/renderer/assets/prism-kotlin-Bc2NQYRR.js 2.43 kB +out/renderer/assets/jssm-CIisorE2-D_RzJT49.js 2.44 kB +out/renderer/assets/prism-python-CTkfasgb.js 2.48 kB +out/renderer/assets/reg-mzCtpvUf-CI4m8Oi6.js 2.54 kB +out/renderer/assets/bat-2PwuskcT-BbFmQdFU.js 2.55 kB +out/renderer/assets/prism-mermaid-DSoNsh6-.js 2.56 kB +out/renderer/assets/pla-HAHcX3CH-DHyEyFew.js 2.57 kB +out/renderer/assets/sb-O6mPt74--_nMcDiF8.js 2.60 kB +out/renderer/assets/chunk-GVQU2GXP-ofjj9lSj.js 2.61 kB +out/renderer/assets/edge-DcEd3r9D-CBXc5XSz.js 2.62 kB +out/renderer/assets/scheme-C-yCXfo--BHhgh59u.js 2.66 kB +out/renderer/assets/flow9-z3HgHIql-qOic_Sv2.js 2.72 kB +out/renderer/assets/prism-yaml-cmjQ_1eD.js 2.77 kB +out/renderer/assets/gleam-DEEAoY6G-BpQSljGj.js 2.78 kB +out/renderer/assets/railroadDiagram-O6MQD6OU-Bf48G_eC.js 2.78 kB +out/renderer/assets/diff-lAxbRYdS-DM8zs7pT.js 2.79 kB +out/renderer/assets/hy-BKymZdC0-CoHxmd7P.js 2.86 kB +out/renderer/assets/dockerfile-CnkhFuxG-CfXHMZr-.js 3.01 kB +out/renderer/assets/openscad-BRTETpP_-hMqJPCYB.js 3.03 kB +out/renderer/assets/pascaligo-DI1dd1Zd-D23AoFdQ.js 3.03 kB +out/renderer/assets/log-Cn1ZE6kb-B2Eb-ljU.js 3.05 kB +out/renderer/assets/objective-c-gNYZndaF-4hkcNMcE.js 3.06 kB +out/renderer/assets/sparql-DxWbGozt-B7qTmycl.js 3.08 kB +out/renderer/assets/prism-markup-templating-D4pSJIpH.js 3.11 kB +out/renderer/assets/prism-cpp-CEgmwlDT.js 3.11 kB +out/renderer/assets/cameligo-B6LDhzzR-DSNRk43W.js 3.12 kB +out/renderer/assets/wenyan-BVgiL1tD-BbCpcZMk.js 3.12 kB +out/renderer/assets/cairo-D_LzMZ4I-vxqtZBLC.js 3.17 kB +out/renderer/assets/prism-rust-Du0Qa8GC.js 3.18 kB +out/renderer/assets/lua-CJt09SGy-3O0VAMVx.js 3.19 kB +out/renderer/assets/graphql-C0cKWTiE-BQOKksLE.js 3.20 kB +out/renderer/assets/berry-DTcSbIs7-Bajq3gC1.js 3.20 kB +out/renderer/assets/jsonl-Cn_fzNA8-BaVvDATF.js 3.21 kB +out/renderer/assets/json-CKKhFIOr-s_zdeuXX.js 3.29 kB +out/renderer/assets/mips-Df5bwPtM-DJn7b529.js 3.29 kB +out/renderer/assets/jsonc-Bf3Xcgeq-dLcyekG4.js 3.31 kB +out/renderer/assets/logo-BxqPaaID-DryN2ftp.js 3.33 kB +out/renderer/assets/abnfDiagram-VCTEODGH-DScZ7qeo.js 3.36 kB +out/renderer/assets/go-BejFoqvR-BnGoIlsY.js 3.42 kB +out/renderer/assets/po-DI6EG-tz-B5Fqkzer.js 3.44 kB +out/renderer/assets/lexon-5NyrCfQ6-B1bdOCGH.js 3.45 kB +out/renderer/assets/prism-sql-BggiY1Ht.js 3.45 kB +out/renderer/assets/json5-BlijqrwT-RbfFZ0Ca.js 3.45 kB +out/renderer/assets/mipsasm-U3SQfJCQ-Bpofb6PH.js 3.46 kB +out/renderer/assets/sophia-foSZ3xPI-DGYIHURw.js 3.47 kB +out/renderer/assets/tasl-C74Cvwdf-odmyCWOH.js 3.49 kB +out/renderer/assets/genie-CjS3m_gh-DHg6VJ2c.js 3.56 kB +out/renderer/assets/prism-swift-xplGsQ1n.js 3.56 kB +out/renderer/assets/vala-DMgevQbf-D3glwiU9.js 3.57 kB +out/renderer/assets/pegDiagram-XKGWAZYB-XBo3nAy7.js 3.59 kB +out/renderer/assets/rel-D6dNeDZv-BuMJ00SL.js 3.60 kB +out/renderer/assets/prism-java-6uFEGwWz.js 3.63 kB +out/renderer/assets/fsharp-Ba-cvOiG-BoxQhS9v.js 3.64 kB +out/renderer/assets/chunk-P2QGCYS3-CxdLISr-.js 3.65 kB +out/renderer/assets/ebnfDiagram-PWID7BFC-zPt9Bbyk.js 3.66 kB +out/renderer/assets/qsharp-78iLGMHs-Dbh3PRIx.js 3.68 kB +out/renderer/assets/m3-Bu81_nWr-4t51Qx0i.js 3.69 kB +out/renderer/assets/chunk-F27PBJKO-CrA32sFu.js 3.70 kB +out/renderer/assets/pascal-DyPgZbsX-Ba58YM7a.js 3.71 kB +out/renderer/assets/path-CSWwviF2.js 3.79 kB +out/renderer/assets/fluent-BSSEgVQa-DxeZwjFt.js 3.81 kB +out/renderer/assets/splunk-BdqSfgpd-DI-JRPbG.js 3.81 kB +out/renderer/assets/jsonnet-Bn71vRY8-D3pjpEpa.js 3.82 kB +out/renderer/assets/ssh-config-BO51LXox-COpWXG2j.js 3.82 kB +out/renderer/assets/bicep-DujF3y-4-DHww3ZLF.js 3.87 kB +out/renderer/assets/narrat-DdgkgBr0-BdvjtlQ4.js 3.87 kB +out/renderer/assets/redis-Bo427DT4-DBDF4ZWx.js 3.88 kB +out/renderer/assets/turtle-DAmmiOda-BDuf0mmV.js 3.92 kB +out/renderer/assets/dist-CE9GMTNb.js 3.97 kB +out/renderer/assets/prism-jsx-BO0yI1A3.js 3.97 kB +out/renderer/assets/xml-BBFzlEmT-CqLnJtYa.js 3.99 kB +out/renderer/assets/java-Z7anYNQ6-DdC7WVZS.js 4.01 kB +out/renderer/assets/r-Xh-gXEK4-DKEPC8dA.js 4.02 kB +out/renderer/assets/ron-CdysqNkW-Biq2zrex.js 4.11 kB +out/renderer/assets/zenscript-XbBI4c9W-BIIQCk-W.js 4.12 kB +out/renderer/assets/glsl-CZF-bvQV-Fa2h6RFS.js 4.14 kB +out/renderer/assets/shell-DGp7WuK3-X00pamiI.js 4.15 kB +out/renderer/assets/gn-DJxfXStl-LnblnCw8.js 4.20 kB +out/renderer/assets/kotlin-C61BvWgT-B7MkJpdU.js 4.20 kB +out/renderer/assets/typespec-B704GmX3-f1l-QmOw.js 4.26 kB +out/renderer/assets/kdl-YTd72GVl-bT5ugZen.js 4.27 kB +out/renderer/assets/AppearanceSettingsPanel-CBK8fzZz.js 4.28 kB +out/renderer/assets/hurl-CDXCvJNd-B5COsIcP.js 4.28 kB +out/renderer/assets/cypher-CjfQI0Y9-9gjOyi6P.js 4.33 kB +out/renderer/assets/pascal-CLPA94yO-Ct0GT-Y8.js 4.35 kB +out/renderer/assets/powershell-CaPzBwIT-C9KgMPOP.js 4.50 kB +out/renderer/assets/tcl-D-NiFh9X-A6B_HfKB.js 4.63 kB +out/renderer/assets/apex-BE-040ts-wdfiR7V6.js 4.65 kB +out/renderer/assets/tcl-DowxIvU4-Bbhzqrsw.js 4.65 kB +out/renderer/assets/rosmsg-DDyuMVTo-DYKxOLYP.js 4.72 kB +out/renderer/assets/nextflow-DVTlkzu9-BuUjFRik.js 4.75 kB +out/renderer/assets/http-DhxVjYFh-CnuCwIDo.js 4.76 kB +out/renderer/assets/hcl-CbjaVS9i-DCS43mBd.js 4.79 kB +out/renderer/assets/rust-Ij2gfGoT-DLzaBWYs.js 4.83 kB +out/renderer/assets/polar-CwTxzzWE-FAjAWxw3.js 4.87 kB +out/renderer/assets/prism-ruby-PgHh3fQm.js 4.91 kB +out/renderer/assets/fennel-COJTUo2O-hFG5qwbk.js 4.97 kB +out/renderer/assets/bibtex-yEKRWsaj-Bi_6UN3n.js 5.00 kB +out/renderer/assets/coffee-CcgZJF1B-DkN4xoBX.js 5.04 kB +out/renderer/assets/llvm-DiFwU398-1mzrPGsR.js 5.25 kB +out/renderer/assets/less-CXux59mP-BM7SkPLH.js 5.27 kB +out/renderer/assets/msdax-DEyWhkWP-CwdIr_-P.js 5.29 kB +out/renderer/assets/prism-javascript-B6zosBCV.js 5.31 kB +out/renderer/assets/wgsl-Ds7VVNHP-DP7CKawS.js 5.34 kB +out/renderer/assets/markdown-CBag5COD-B_1rbk64.js 5.36 kB +out/renderer/assets/dart-DK8_VUW5-Bnb_Tn57.js 5.39 kB +out/renderer/assets/zig-BBWfbOQ5-FARukIbS.js 5.54 kB +out/renderer/assets/restructuredtext-D2p7PcFG-DDHAm_JI.js 5.55 kB +out/renderer/assets/dax-CmrIxjmL-Dts6UfZw.js 5.56 kB +out/renderer/assets/gdresource-4lq4eh4q-DVqedupl.js 5.56 kB +out/renderer/assets/qml-D6gd64uC-DRYar41A.js 5.57 kB +out/renderer/assets/bicep-wTwvD1CI-f8YJLLcJ.js 5.58 kB +out/renderer/assets/cssMode-Z-o80aSY-ghntTnpV.js 5.59 kB +out/renderer/assets/awk-DTjcVAOD-CzIppyvU.js 5.66 kB +out/renderer/assets/liquid-Dv-zz5BA-D9ukCDuL.js 5.71 kB +out/renderer/assets/csharp-DpS7Vfy9-CbQzv1ql.js 5.76 kB +out/renderer/assets/coq-BFytDJOI-ef_Ur-QP.js 5.81 kB +out/renderer/assets/swift-C3A42nmX-BBVToPkN.js 5.83 kB +out/renderer/assets/xml-bIkPj5aH-CwOW5xDz.js 5.89 kB +out/renderer/assets/ecl-CYzojQ6a-C8m0_osY.js 5.91 kB +out/renderer/assets/jinja-Dl-Ji_JA-TQEv_6fW.js 5.92 kB +out/renderer/assets/lean-Cu10prRO-DeNAbMo1.js 6.03 kB +out/renderer/assets/yaml-GEMDST6R-D-0AGe4F.js 6.09 kB +out/renderer/assets/moonbit-B8-g2u5v-CVTe6nNw.js 6.10 kB +out/renderer/assets/powerquery-tKWDTKOo-CH98Al2Y.js 6.11 kB +out/renderer/assets/SourceCodePreview-C1ztCBwf.js 6.11 kB +out/renderer/assets/python-CHafhQyI-DmJIfgbV.js 6.14 kB +out/renderer/assets/shaderlab-Df7nOKvI-BmJ1KXMD.js 6.16 kB +out/renderer/assets/css-sG8ozMHf-pZGexMoj.js 6.17 kB +out/renderer/assets/cpp-CipCPBaT-7uQRIwsC.js 6.17 kB +out/renderer/assets/vb-BKV3Sgm5-Dt7Ll8D7.js 6.29 kB +out/renderer/assets/htmlMode-BDZbYlMj-siLdeIso.js 6.40 kB +out/renderer/assets/red-CYaKK_PD-CzqFe3Tm.js 6.45 kB +out/renderer/assets/min-dark-DGPfDRqJ-HwLk1pky.js 6.48 kB +out/renderer/assets/pug-EKWpNZSi-oQ708bsr.js 6.51 kB +out/renderer/assets/prisma-CdZyz3OC-DHqg13Q1.js 6.53 kB +out/renderer/assets/gdshader-ryZhEIxg-DTUiAD-H.js 6.55 kB +out/renderer/assets/ara-_lrJyEFe-BMlXck3g.js 6.56 kB +out/renderer/assets/clojure-WSq30mUj-J-mHf2za.js 6.61 kB +out/renderer/assets/toml-DPP887_3-DwEWbgmd.js 6.62 kB +out/renderer/assets/postcss-CcIp2ENG-CYsMQTxy.js 6.64 kB +out/renderer/assets/verilog-bragEGMk-B0_YfS3E.js 6.64 kB +out/renderer/assets/PrivateRuntimesSettingsPanel-B4qZX77D.js 6.67 kB +out/renderer/assets/solarized-light-BIMszn7B-BHWshuHE.js 6.68 kB +out/renderer/assets/cypher-COYrq2Yy-BK3oZ1E6.js 6.75 kB +out/renderer/assets/arc-LpCwTDer.js 6.75 kB +out/renderer/assets/proto-CQIfhs_g-CtoFRVaP.js 6.77 kB +out/renderer/assets/smalltalk-BLGdLDJX-BnBPALl8.js 6.79 kB +out/renderer/assets/vb-D1Cw85Ss-BSz-V9M4.js 6.86 kB +out/renderer/assets/talonscript-DA9pg7Tj-RnGeNC0u.js 6.96 kB +out/renderer/assets/r-Bb2Mu7Fo-CdtUEa4x.js 7.00 kB +out/renderer/assets/solarized-dark-D_I-4EGa-dEDCUT49.js 7.04 kB +out/renderer/assets/diagram-Z3DM3KII-CDqXKLeu.js 7.08 kB +out/renderer/assets/riscv-CQHqXr1Z-Cpm-2Pe9.js 7.11 kB +out/renderer/assets/soy-DybHqX1A-DwQA3zJN.js 7.15 kB +out/renderer/assets/min-light-BF0EjVgr-CorKJXFA.js 7.16 kB +out/renderer/assets/scheme-Dn0tgEWN-Dx4kPKzi.js 7.37 kB +out/renderer/assets/prism-bash-B2ETaHUm.js 7.43 kB +out/renderer/assets/typescript-sfPIqb8J-DtIl1kXb.js 7.44 kB +out/renderer/assets/hlsl-CAmjcFpk-18jAR-hO.js 7.48 kB +out/renderer/assets/mdx-Bdu4uO-C-BrzgNjCw.js 7.58 kB +out/renderer/assets/qss-DkzwWM0J-zjH4M815.js 7.67 kB +out/renderer/assets/html-DKbmsqz6-Cnkf6ew3.js 7.69 kB +out/renderer/assets/systemd-CS6mVasZ-D_yvUREH.js 8.07 kB +out/renderer/assets/monokai-CYqILLdj-DvnA5NkK.js 8.08 kB +out/renderer/assets/twig-r8vgPZrm-D2l24YwI.js 8.18 kB +out/renderer/assets/updates-ui-BqpdtOLV.js 8.22 kB +out/renderer/assets/wgsl-D_5Qxf6T-D508aVGZ.js 8.27 kB +out/renderer/assets/sdbl-BXfz6d3_-CYe5PkP_.js 8.42 kB +out/renderer/assets/regexp-Dv0OUts_-CPlEBsRg.js 8.46 kB +out/renderer/assets/prism-php-dzcOOH50.js 8.49 kB +out/renderer/assets/systemverilog-BreNGkRs-RIXr4hNf.js 8.65 kB +out/renderer/assets/plsql-C-xpsZfV-D-CnN_to.js 8.71 kB +out/renderer/assets/vue-html-DvuHo2mm-0SkYmZrV.js 8.71 kB +out/renderer/assets/haml-CIYwkycC-Df8c_gw1.js 8.81 kB +out/renderer/assets/scss-CLoW-2dr-BBC_GO_6.js 8.86 kB +out/renderer/assets/dart-CBkkDIWs-pnVQUz7O.js 8.94 kB +out/renderer/assets/horizon-CELVL8Ba-C2I1M4mp.js 8.97 kB +out/renderer/assets/horizon-bright-DBDyMeUQ-Co9G8FSM.js 8.98 kB +out/renderer/assets/julia-DvNkK6LK-Bi3Rlfah.js 9.04 kB +out/renderer/assets/clojure-886L7m2N-BhGJsUM7.js 9.14 kB +out/renderer/assets/make-CsAfL-jc-motAe4hn.js 9.18 kB +out/renderer/assets/andromeeda--j5Bq-48-DCMNZFq_.js 9.21 kB +out/renderer/assets/dark-plus-FAPM6M6c-Bt70pA2P.js 9.29 kB +out/renderer/assets/sas-BQIEUTPQ-BIyx7TAp.js 9.31 kB +out/renderer/assets/slack-dark-nDxLkSCC-y2Ay7FmO.js 9.31 kB +out/renderer/assets/perl-Bec3eWyr-CDmSu3_s.js 9.32 kB +out/renderer/assets/plastic-DY_h9Vzh-CD0KLW0z.js 9.49 kB +out/renderer/assets/sass-Ysv8HTNa-BGj6JvvR.js 9.49 kB +out/renderer/assets/st-BrgXZ-Ag-BUs-RRgp.js 9.58 kB +out/renderer/assets/typst-Co5rZla4-OQ5Z92wn.js 9.61 kB +out/renderer/assets/slack-ochin-7zJWY-K--Dysf61-O.js 9.63 kB +out/renderer/assets/defaultLocale-QNqK0iCN.js 9.84 kB +out/renderer/assets/handlebars-CIJAyfa9-6toBlNYk.js 9.94 kB +out/renderer/assets/jison-Cbw0l5It-CxZxtz6O.js 9.95 kB +out/renderer/assets/sql-DviNlDJO-CwV6bDIP.js 9.97 kB +out/renderer/assets/kotlin-DIw6ua6F-TFNQT90V.js 10.01 kB +out/renderer/assets/cmake-CyNDuJo8-BZldhEGe.js 10.07 kB +out/renderer/assets/light-plus-DkScKIB5-7ug4iLR4.js 10.14 kB +out/renderer/assets/hcl-DoJdlYjN-CYB-uxe0.js 10.25 kB +out/renderer/assets/scala-Dj45wWzI-CAMCqIXS.js 10.40 kB +out/renderer/assets/postiats-SaHD9Qcv-FPvOr1pn.js 10.45 kB +out/renderer/assets/beancount-CyZf3Huc-DE4CAoDi.js 10.58 kB +out/renderer/assets/tex-gcnXexI3-DkpGyyGn.js 10.60 kB +out/renderer/assets/php-Bn8AF0uj-CBbpr2vs.js 10.62 kB +out/renderer/assets/nextflow-groovy-D4ZyOBoZ-B2EMVDGy.js 10.63 kB +out/renderer/assets/dream-maker-5oXa1Z51-D1LnccFA.js 10.67 kB +out/renderer/assets/ts-tags-xeTAUNHG-Bn9JKLph.js 10.70 kB +out/renderer/assets/raku-Bfr41qeN-D4VhQ2rr.js 10.72 kB +out/renderer/assets/mysql-CZJtil0v-CP4gK9vT.js 10.73 kB +out/renderer/assets/task-menu-icons-BRdNqJF0.js 10.78 kB +out/renderer/assets/prism-csharp-D9xOwbIN.js 10.91 kB +out/renderer/assets/yaml-CsitfczK-Dei6m9-K.js 10.97 kB +out/renderer/assets/diagram-UQ7AKVKN-BNly1nWm.js 11.05 kB +out/renderer/assets/elm-Dl1XrIiD-eMpXTcNa.js 11.18 kB +out/renderer/assets/just-He7qscmV-DoPzJKPC.js 11.19 kB +out/renderer/assets/redshift-Djb4PK3z-9Ar4PFWD.js 11.35 kB +out/renderer/assets/github-light-B_J7N1HZ-DMuZw_Uo.js 11.38 kB +out/renderer/assets/ruby-CxOCB7_P-BzsjPJ6Z.js 11.48 kB +out/renderer/assets/prolog-DAqMMM08-BuMDGWJy.js 11.56 kB +out/renderer/assets/terraform-BW8B2WXV-DHhZfkB5.js 11.59 kB +out/renderer/assets/github-dark-BgqEY2WG-Dnnmf1fd.js 11.60 kB +out/renderer/assets/puppet-CaR8DEdW-Bk1_hyzj.js 11.65 kB +out/renderer/assets/pkl-DrXR3Dxy-Bk_Dwe9f.js 11.67 kB +out/renderer/assets/laserwave-Clkc4Pj8-CKWIlHTc.js 11.69 kB +out/renderer/assets/pieDiagram-E7YTZNPT-BNLfmN4s.js 11.95 kB +out/renderer/assets/rst-BJFdabDk-D3rnvzr7.js 12.04 kB +out/renderer/assets/linear-WS155L0r.js 12.11 kB +out/renderer/assets/wasm-DYwNZ-r4-DxxDPMxJ.js 12.21 kB +out/renderer/assets/hjson-CmvCiVhY-C4ioDjCi.js 12.25 kB +out/renderer/assets/razor-D5kquflS-CWY5AfCS.js 12.39 kB +out/renderer/assets/abap-BJyKdrbp-hWIyERPx.js 12.52 kB +out/renderer/assets/handlebars-B1z64YSt-Dv-6oFzD.js 12.52 kB +out/renderer/assets/apache-BUbWdjM2-Drf7fe4P.js 12.66 kB +out/renderer/assets/vesper-B5lCMuIY-BEIZAJku.js 12.88 kB +out/renderer/assets/pgsql-BYm17UA1-Cvj1smQI.js 12.93 kB +out/renderer/assets/protobuf-BOGxqb2m-yTWn-oM_.js 12.98 kB +out/renderer/assets/bat-D2y8Uewi-Dag26b2Z.js 13.09 kB +out/renderer/assets/fish-CaZR_ofm-B5raXkjs.js 13.24 kB +out/renderer/assets/elixir-Lipcswxh-DnZCznfr.js 13.27 kB +out/renderer/assets/v-wnWoBHkK-Day6RbRE.js 13.41 kB +out/renderer/assets/AboutHelpSettingsPanel-BY1_9D5h.js 13.48 kB +out/renderer/assets/vitesse-light-DQXFiRFx-ClS7zZun.js 13.81 kB +out/renderer/assets/aurora-x-9vUYYjHV-Ctpf2PFJ.js 13.85 kB +out/renderer/assets/vitesse-black-cwK5rWgD-xb5LTMEn.js 13.87 kB +out/renderer/assets/vitesse-dark-CsfgW0oH-DRstyp0V.js 13.96 kB +out/renderer/assets/ShortcutsSettingsPanel-C0YAbSVE.js 14.15 kB +out/renderer/assets/pug-D0UckVoV-DTpPZPyJ.js 14.16 kB +out/renderer/assets/synthwave-84-LX1B8mRG-p2n15IVZ.js 14.23 kB +out/renderer/assets/github-light-default-BRmIzqWc-BssP3fWL.js 14.36 kB +out/renderer/assets/clarity-AxkJPY5c-DxQsyzW4.js 14.48 kB +out/renderer/assets/github-light-high-contrast-BUKIZOxn-ddD8WB0C.js 14.49 kB +out/renderer/assets/github-dark-dimmed-DoIdqTey-DVepSQBv.js 14.64 kB +out/renderer/assets/github-dark-default-CwWjzI40-RrXCLjwC.js 14.64 kB +out/renderer/assets/chunk-PWAF6VOD-B_xWZeTJ.js 14.76 kB +out/renderer/assets/github-dark-high-contrast-bFLNMLvK-BXKopV-S.js 14.80 kB +out/renderer/assets/diagram-S7CK7UJ4-HxWCw845.js 14.98 kB +out/renderer/assets/gnuplot-Dw3FRha5-D3M-xWAW.js 14.98 kB +out/renderer/assets/rust-C0Ih6nmc-NSyRjuKn.js 15.27 kB +out/renderer/assets/actionscript-3-O8jnLcvn-D3y3sBt8.js 15.41 kB +out/renderer/assets/luau-BzxGbjcn-DRqn7wkf.js 15.64 kB +out/renderer/assets/nix-zl191KBb-BbUoemNK.js 15.85 kB +out/renderer/assets/lua-BwTLfNCK-CwVt-Bud.js 16.04 kB +out/renderer/assets/abap-FvPUHv8B-BHnmFpIs.js 16.05 kB +out/renderer/assets/solidity-96fhzG-Q-BeFLe5_3.js 16.28 kB +out/renderer/assets/matlab-8ZQqHKQX-BhcRPlgD.js 16.29 kB +out/renderer/assets/cue-eHSfcyUV-DT6a09xa.js 16.40 kB +out/renderer/assets/kusto-D8vBBISG-MUlttHhz.js 16.45 kB +out/renderer/assets/powerquery-B7BjLMcF-BkVSWPtX.js 16.49 kB +out/renderer/assets/elixir-B1NaQxrO-C2KIFym7.js 16.50 kB +out/renderer/assets/react-DrereneL.js 16.50 kB +out/renderer/assets/odin-B-YqhW9I-B4nLtb__.js 16.71 kB +out/renderer/assets/solidity-Dpt2BLAA-BD_YSA0r.js 16.98 kB +out/renderer/assets/bird2-BMkLvc4r-DJUqkWBZ.js 17.17 kB +out/renderer/assets/kanagawa-wave-CM_o6oKV-BiCJ69Qw.js 17.32 kB +out/renderer/assets/kanagawa-lotus-Cj3XDpoG-DyyQ5zzx.js 17.32 kB +out/renderer/assets/kanagawa-dragon-D_NPnIy_-DsTAhavE.js 17.33 kB +out/renderer/assets/cynefinDiagram-5FMLGOSQ-Mcy-XBmQ.js 17.61 kB +out/renderer/assets/stateDiagram-D77RDMKH-Ce6yHAkh.js 18.11 kB +out/renderer/assets/chunk-L3NEJ4N5-BTj7ZXs5.js 18.16 kB +out/renderer/assets/liquid-D_7zu7XR-CXZ_m_sQ.js 18.46 kB +out/renderer/assets/svelte-DUGqPubT-Cg5Umebm.js 18.60 kB +out/renderer/assets/graphql-ObxcfEHH-CE1BS9vi.js 18.65 kB +out/renderer/assets/jsonMode-DdQpkp6D-ryNuzreF.js 18.79 kB +out/renderer/assets/material-theme-q28j4V_0-D4sopXzV.js 18.81 kB +out/renderer/assets/material-theme-ocean-DAvlEnSm-BNlRm3bO.js 18.83 kB +out/renderer/assets/material-theme-darker-CHEuMVX9-_HyRAmHW.js 18.83 kB +out/renderer/assets/material-theme-lighter-DY4T1_JG-CCMtFHoU.js 18.84 kB +out/renderer/assets/material-theme-palenight-CqDFvQ-v-BCUQCRA9.js 18.84 kB +out/renderer/assets/gherkin-BcjDDslM-Vee2W7jW.js 19.20 kB +out/renderer/assets/gdscript-CekKc1U_-DVYWisvp.js 19.21 kB +out/renderer/assets/groovy-DH3arekX-Ck1fPmLU.js 19.38 kB +out/renderer/assets/mdc-D-U85KZE-Da7cgSf8.js 19.85 kB +out/renderer/assets/diagram-VSXAHHWV-CYmzzVvl.js 20.01 kB +out/renderer/assets/move-CmExnPjU-CnmvqY5Z.js 20.22 kB +out/renderer/assets/ayu-dark-BeByMiYw-DMYpUV0j.js 20.27 kB +out/renderer/assets/ayu-mirage-C1jJ6Jfs-BNm6kYch.js 20.28 kB +out/renderer/assets/ayu-light-DmTZeN54-D_6LeGBp.js 20.35 kB +out/renderer/assets/glimmer-js-D9ZnrcNN-C_sv3tNP.js 20.44 kB +out/renderer/assets/glimmer-ts-DuhFj6qR-3vTIoInh.js 20.44 kB +out/renderer/assets/viml-DPVJ_KYe-7wnrr3JE.js 20.56 kB +out/renderer/assets/nushell-Cd8Dwa1M-BCLkjKh-.js 20.62 kB +out/renderer/assets/snazzy-light-B8znOqT6-B6ELzxzT.js 20.97 kB +out/renderer/assets/dagre-GXQ25YYZ-Dv6RL6rv.js 21.01 kB +out/renderer/assets/dracula-DeMffiYO-APAP0ZMF.js 21.26 kB +out/renderer/assets/dracula-soft-BnfvpcDv-DVKzJw-a.js 21.27 kB +out/renderer/assets/twig-7zjsCqYg-DxthtzQl.js 21.44 kB +out/renderer/assets/freemarker2-enkimFXA-0bWMkoTL.js 21.73 kB +out/renderer/assets/PersonalizationSettingsPanel-Cu4FSwRk.js 21.87 kB +out/renderer/assets/rose-pine-CEVQiaW0-B9wdQBUK.js 21.94 kB +out/renderer/assets/rose-pine-moon-B9bum7Ik-DV9wvzoF.js 21.96 kB +out/renderer/assets/rose-pine-dawn-2Q5fMoJp-9IwweoZR.js 21.96 kB +out/renderer/assets/powershell-ycAdP1r9-zBR5oucw.js 22.11 kB +out/renderer/assets/common-lisp-DcFHcTKh-ChYmZcml.js 22.81 kB +out/renderer/assets/gruvbox-dark-hard-gOzMLqif-1ffvJLYJ.js 22.83 kB +out/renderer/assets/gruvbox-dark-soft-CKvURktN-CTfPcZGR.js 22.83 kB +out/renderer/assets/gruvbox-light-hard-CMa_c48J-CiF1HZj7.js 22.84 kB +out/renderer/assets/gruvbox-light-soft-yfAGJYsX-DOBtCxv4.js 22.84 kB +out/renderer/assets/gruvbox-dark-medium-BQSVGwWb-XqSAmK9Z.js 22.84 kB +out/renderer/assets/gruvbox-light-medium-B9S5UNr1-DHFc3pZf.js 22.84 kB +out/renderer/assets/nim-CD961Jl3-GNJlFYEB.js 22.91 kB +out/renderer/assets/cadence-C2JmJjDr-CNsAMskX.js 23.87 kB +out/renderer/assets/sql-C_oMiPb0-eqfeiYFN.js 23.87 kB +out/renderer/assets/wit-CXpQol8Q-CgnX2mEY.js 24.11 kB +out/renderer/assets/templ-gFcHJbF7-CtGorYnD.js 24.38 kB +out/renderer/assets/astro-kV3HjkbP-DWkULF6m.js 24.46 kB +out/renderer/assets/vhdl-Ci4REirV-79GIduW4.js 24.46 kB +out/renderer/assets/purescript-DCsDAdnX-BHSmjuaf.js 24.97 kB +out/renderer/assets/vue-Cuk7Vimg-QGoH4Fqf.js 25.25 kB +out/renderer/assets/surrealql-GFjNBdcm-R--ilK2-.js 25.34 kB +out/renderer/assets/one-light-CMfGrl_P-BVh_cQxI.js 25.49 kB +out/renderer/assets/night-owl-light-CAEa42tO-C8k75joB.js 26.10 kB +out/renderer/assets/system-verilog-D_bVVpLE-D0CLrP2v.js 26.41 kB +out/renderer/assets/angular-html-BrLPO2Fv-DN2wP65A.js 26.48 kB +out/renderer/assets/typespec-D5WYs8C4-6KJNyQgC.js 26.72 kB +out/renderer/assets/nord-DlCAGdjr-Dq7-29jJ.js 26.91 kB +out/renderer/assets/codeql-DidIlXer-BXtoeXUa.js 27.08 kB +out/renderer/assets/scss-BhK8Ovpn-Bro8Wnj5.js 27.52 kB +out/renderer/assets/coffee-DrMWXxy6-DqnaejKc.js 27.68 kB +out/renderer/assets/java-DaupjRFz-BmH8F4Xu.js 27.69 kB +out/renderer/assets/razor-B2hRAVmz-DFoDL3Rc.js 27.72 kB +out/renderer/assets/apl-C42PBett-BV6hrP71.js 27.87 kB +out/renderer/assets/GeneralSettingsPanel-Dhp6WB35.js 27.94 kB +out/renderer/assets/chunk-SVP7TREG-Csis0frL.js 28.38 kB +out/renderer/assets/fsharp-BHFgIxsY-DiAA2GQQ.js 28.48 kB +out/renderer/assets/marko-DXKHPFnH-COCjppDO.js 28.74 kB +out/renderer/assets/night-owl-DegwdXaM-CAHni64B.js 29.11 kB +out/renderer/assets/c3-BOs4FlGA-BpND_1Oc.js 29.17 kB +out/renderer/assets/MemorySettingsPanel-Bxb72epL.js 29.75 kB +out/renderer/assets/crystal-DlzoxO28-jPE7UMPv.js 29.84 kB +out/renderer/assets/applescript-ij24h7OO-CfuGzwAx.js 29.87 kB +out/renderer/assets/tsMode-SiG-Sp2b-uJP6tDKM.js 30.55 kB +out/renderer/assets/pierre-dark-Daa2n9wr-jVOIM079.js 30.74 kB +out/renderer/assets/pierre-light-D_hZXvUj-B-I8Fy7S.js 30.75 kB +out/renderer/assets/pierre-dark-soft-BhNM3pgh-C21QEiBh.js 30.76 kB +out/renderer/assets/pierre-light-soft-BVrSv6ZG-B45EorIo.js 30.76 kB +out/renderer/assets/ishikawaDiagram-5VMMS53U-DTo9OLUj.js 30.78 kB +out/renderer/assets/pierre-dark-tritanopia-CGKuoAZi-BJEQ1Wx0.js 30.78 kB +out/renderer/assets/pierre-light-tritanopia-BiDEaWaH-CKL7emT7.js 30.78 kB +out/renderer/assets/pierre-dark-protanopia-deuteranopia-Cs1lz9lE-CdeAx_-I.js 30.82 kB +out/renderer/assets/pierre-light-protanopia-deuteranopia-BM0RLBB_-BCikKBoA.js 30.82 kB +out/renderer/assets/stylus-ZCryC73G-BNz0cuP0.js 31.29 kB +out/renderer/assets/diagram-VX7I27RA-BUBTTGEV.js 31.44 kB +out/renderer/assets/scala-BBsC3Oz3-BEVUQysb.js 31.48 kB +out/renderer/assets/mermaid-D6CQfUGU-BIokhzAy.js 33.37 kB +out/renderer/assets/poimandres-EIt_jotH-C68Hghjr.js 33.69 kB +out/renderer/assets/kanban-definition-UXKFOSKX---wf-Z-L.js 33.91 kB +out/renderer/assets/one-dark-pro-DR9QpZM3-DWXkK0aA.js 33.98 kB +out/renderer/assets/mermaid-parser.core-D9uZC-Qx.js 34.66 kB +out/renderer/assets/haxe-BWT5wSyZ-Bc0s339E.js 35.38 kB +out/renderer/assets/nginx-DhtViCEk-D_dlMkM2.js 35.58 kB +out/renderer/assets/houston-BdS5A_yD-B7tBMzJ_.js 35.61 kB +out/renderer/assets/tokyo-night-BS1_DFu7-DM9rDy1i.js 35.86 kB +out/renderer/assets/erlang-Dd62d0xZ-Dn5zmcXH.js 37.71 kB +out/renderer/assets/rough.esm-BX5QqLti.js 38.33 kB +out/renderer/assets/mindmap-definition-YA3MSWOX-CUizKTTG.js 38.59 kB +out/renderer/assets/cobol-D7RZfOK--CiunptQS.js 39.37 kB +out/renderer/assets/journeyDiagram-3NMN7TZE-_ouxsy-Y.js 40.13 kB +out/renderer/assets/julia-ZzkUXm0W-B05POQ1y.js 40.32 kB +out/renderer/assets/lspLanguageFeatures-DK9zifhE-DeEqLmGO.js 40.76 kB +out/renderer/assets/asm-DYVIzeEk-BdsmPhUV.js 40.91 kB +out/renderer/assets/haskell-Ba6HbLj8-C6aYe-tt.js 41.78 kB +out/renderer/assets/sankeyDiagram-P5KCCOFB-CBzEcjmt.js 41.83 kB +out/renderer/assets/shellscript-B69gKcss-BCpQfG2V.js 41.97 kB +out/renderer/assets/wardleyDiagram-VM6X3IG4-BHD45b_a.js 42.40 kB +out/renderer/assets/perl-Dv6Cq_FS-Qpttd9ok.js 43.55 kB +out/renderer/assets/pierre-dark-vibrant-BMsyYliQ-CUZmeWj8.js 44.96 kB +out/renderer/assets/pierre-light-vibrant-CWzM4Pa_-CEqHPLvH.js 44.97 kB +out/renderer/assets/ruby-DWcdJvcx-BvnxDDlL.js 46.50 kB +out/renderer/assets/go-BOpYl7fu-B0liyMKV.js 47.02 kB +out/renderer/assets/apex-B48ZHHzN-D3dPjLM0.js 47.18 kB +out/renderer/assets/catppuccin-mocha-cPsH7Lup-B1aKBIop.js 47.46 kB +out/renderer/assets/catppuccin-latte-DcEecI7n-DvwHc2S5.js 47.46 kB +out/renderer/assets/catppuccin-frappe-BdOW2tdI-DECg27lJ.js 47.46 kB +out/renderer/assets/catppuccin-macchiato-Bvz_yAZY-jtZXG4Wb.js 47.47 kB +out/renderer/assets/ada-BT0j8ine-D-uzx6Mf.js 48.28 kB +out/renderer/assets/d-B1HbH29p-m8z4Mb03.js 49.10 kB +out/renderer/assets/css-NFwnoVns-CFobPrFm.js 49.49 kB +out/renderer/assets/imba-C-oGt11l-BHSoATU3.js 50.13 kB +out/renderer/assets/requirementDiagram-BXWQKSXE-DF7sZnvW.js 51.39 kB +out/renderer/assets/erDiagram-RLTQ6QDP-B5kVdOsu.js 52.41 kB +out/renderer/assets/browserify-C9uP_nIr.js 52.80 kB +out/renderer/assets/gitGraphDiagram-WWUBYQGX-CKeLSGy2.js 53.82 kB +out/renderer/assets/everforest-dark-gCM8XhEI-BkULplJM.js 53.94 kB +out/renderer/assets/everforest-light-DhK35DkL-BWsjYbyt.js 53.95 kB +out/renderer/assets/timeline-definition-24CTP7MA-B52UdTo1.js 54.31 kB +out/renderer/assets/wikitext-CQNrXTmv-DmewJRQe.js 56.09 kB +out/renderer/assets/stata-BUONSdsT-BMio-HiN.js 57.23 kB +out/renderer/assets/quadrantDiagram-AXDQQJYC-XlPTPqNY.js 58.21 kB +out/renderer/assets/html-Dq1ixqYb-ikBZyjXh.js 58.25 kB +out/renderer/assets/chunk-OSK3NFVY-nxsF_2l9.js 58.56 kB +out/renderer/assets/ocaml-CUdGm1iq-CKVIVKNi.js 62.65 kB +out/renderer/assets/ballerina-CpYcPBJI-DUjr1anJ.js 64.89 kB +out/renderer/assets/markdown-BSrOIEaF-DTmUkziu.js 65.52 kB +out/renderer/assets/model-settings-source-Beswzs9F.js 65.56 kB +out/renderer/assets/chunk-IMKFNOWR-DMjCUg_X.js 67.22 kB +out/renderer/assets/mojo-BNaitZ-7-CNyrqsBu.js 70.00 kB +out/renderer/assets/python-Cld0Iwtn-Dc00FHqu.js 70.17 kB +out/renderer/assets/blockDiagram-I7D4REHJ-Dt5Nk8hT.js 71.01 kB +out/renderer/assets/bsl-CtP8370o-2oWsl7ro.js 71.07 kB +out/renderer/assets/c-B4augMcT-BnnD0pzw.js 72.57 kB +out/renderer/assets/chunk-75Z2AOVW-g5kYAQXn.js 72.67 kB +out/renderer/assets/latex-g2Pus_l2-jmHDzxNT.js 72.85 kB +out/renderer/assets/vyper-C1nscAY5-D__MF1ly.js 74.85 kB +out/renderer/assets/ModelSettingsPanel-gTozZxuT.js 76.73 kB +out/renderer/assets/xychartDiagram-S5SC5T6Z-C21HkgFK.js 76.79 kB +out/renderer/assets/chunk-GMAD6QVW-Dnp68ZTh.js 77.76 kB +out/renderer/assets/hack-B1ag3l4X-tyEt6EwS.js 80.58 kB +out/renderer/assets/src-DsgKm1PY.js 83.16 kB +out/renderer/assets/chunk-TICWLB2K-ySi6rtZ2.js 83.88 kB +out/renderer/assets/fortran-free-form-CsgtTAg3-DgulwIAi.js 89.20 kB +out/renderer/assets/vennDiagram-4TSXK5OY-BPjUg06I.js 89.26 kB +out/renderer/assets/csharp-YOPVljXo-BWs4xY0W.js 89.91 kB +out/renderer/assets/racket--xYIV9-n-BvSlC08n.js 92.62 kB +out/renderer/assets/swift-CgzYrGBX-pR4OWhlc.js 94.14 kB +out/renderer/assets/less-BGhX8xko-fBMPrmVZ.js 99.00 kB +out/renderer/assets/chunk-SHT3W25Y-Ck-aB5Uu.js 104.10 kB +out/renderer/assets/objective-c-CmcWiAft-BnWIdCJE.js 105.62 kB +out/renderer/assets/blade-Bq8WPf0E-BvQh51Wk.js 105.98 kB +out/renderer/assets/c4Diagram-7LVT6UL2-DaNs-p8D.js 107.96 kB +out/renderer/assets/php-X15vsN4N-BP3XzobV.js 111.49 kB +out/renderer/assets/dagre-CzI-C3sx.js 122.98 kB +out/renderer/assets/ganttDiagram-EL5Y4UJY-DRVfLdn1.js 123.77 kB +out/renderer/assets/graphlib-CoAzpIqe.js 127.44 kB +out/renderer/assets/asciidoc-DJWalVNM-CUrf9IhF.js 146.30 kB +out/renderer/assets/mdx-C_Ato9sK-Dw7GE6T0.js 146.49 kB +out/renderer/assets/editor.main-POO0Vbhx-Ckm40Z4F.js 161.32 kB +out/renderer/assets/cose-bilkent-JH36ORCC-CA60tZpq.js 165.63 kB +out/renderer/assets/objective-cpp-BggTCHV8-C8vqT1kg.js 172.18 kB +out/renderer/assets/javascript-AfZCJ9Uc-CBeTSWR3.js 175.31 kB +out/renderer/assets/tsx-BOlKGefW-DmB6MG_T.js 176.00 kB +out/renderer/assets/jsx-CPd9p36x-irxTBUcS.js 178.26 kB +out/renderer/assets/sequenceDiagram-WJ2MYXX4-DaqVHWoY.js 190.05 kB +out/renderer/assets/typescript-4sRsPriL-tBSOa5KM.js 191.16 kB +out/renderer/assets/mermaid.core-DHHVRzzC.js 191.57 kB +out/renderer/assets/angular-ts-YduEkmVa-D3Aj057l.js 193.82 kB +out/renderer/assets/vue-vine-DXhYlaTf-F_V-T9AA.js 201.27 kB +out/renderer/assets/SourceSelect-5sFypDRe.js 203.20 kB +out/renderer/assets/chunk-4HAMMTFA-DK0AoKOa.js 210.32 kB +out/renderer/assets/swimlanes-42K2YHIH-DjvqEQqr.js 265.51 kB +out/renderer/assets/wolfram-BVoTES0L-CQ8sM4xY.js 267.14 kB +out/renderer/assets/chunk-DU6HZSFF-CaRG2Ier.js 271.07 kB +out/renderer/assets/architectureDiagram-5GKGNRK7-DZMUubDN.js 318.23 kB +out/renderer/assets/katex-Y9ra-ykP.js 497.35 kB +out/renderer/assets/texmath-Bkeg3ZLn.js 594.25 kB +out/renderer/assets/wasm-CVjZL0jK-Dt2swvi2.js 622.62 kB +out/renderer/assets/cpp-9jHBA231-CBf5U9Ag.js 626.73 kB +out/renderer/assets/app-FL-TA-H2.js 677.26 kB +out/renderer/assets/emacs-lisp-DjtOxg4j-nrVZCSuO.js 780.06 kB +out/renderer/assets/cytoscape.esm-bVGYt-iW.js 869.69 kB +out/renderer/assets/ArtifactPierreDiff-fqHylWj_.js 1,119.58 kB +out/renderer/assets/chunk-FOHPRMQF-BCllzKJD.js 1,154.18 kB +out/renderer/assets/index-_D-I1Mwx.js 3,780.38 kB +out/renderer/assets/editor.api2-dPwET-7w-BYIQ9bT3.js 4,889.23 kB + +✓ built in 2.45s +npm notice +npm notice New major version of npm available! 11.9.0 -> 12.2.0 +npm notice Changelog: https://github.com/npm/cli/releases/tag/v12.2.0 +npm notice To update run: npm install -g npm@12.2.0 +npm notice diff --git a/docs/协作/evidence/b05-01/conversation.log b/docs/协作/evidence/b05-01/conversation.log new file mode 100644 index 0000000..75d6e7a --- /dev/null +++ b/docs/协作/evidence/b05-01/conversation.log @@ -0,0 +1,9 @@ +npm warn Unknown env config "http-proxy". This will stop working in the next major version of npm. + +> ycode@0.0.10 test:conversation +> esbuild scripts/conversation-renderer-regression.tsx scripts/composer-regression.tsx scripts/completed-fold-regression.tsx scripts/streaming-footer-regression.tsx --bundle --platform=node --format=cjs --jsx=automatic --loader:.css=text --out-extension:.js=.cjs --outdir=.tmp/conversation-tests --log-level=error && node .tmp/conversation-tests/conversation-renderer-regression.cjs && node .tmp/conversation-tests/composer-regression.cjs && node .tmp/conversation-tests/streaming-footer-regression.cjs && node .tmp/conversation-tests/completed-fold-regression.cjs + +Conversation specialized renderer SSR regression checks passed +Composer/message action regression cases passed +streaming-footer-regression: persistent stream status, delayed/paused rotation, brand/locale mapping, source CSS, and completed model footer passed +Completed-fold model and SSR regression checks passed diff --git a/scripts/conversation-renderer-regression.tsx b/scripts/conversation-renderer-regression.tsx index a668bba..0275367 100644 --- a/scripts/conversation-renderer-regression.tsx +++ b/scripts/conversation-renderer-regression.tsx @@ -557,18 +557,18 @@ const todoWriteRenderer = renderToStaticMarkup( }} /> ) -assert.match(todoWriteRenderer, /进度更新 1\/3/) +assert.match(todoWriteRenderer, /进度 1\/3/) assert.match(todoWriteRenderer, /Completed task/) assert.match(todoWriteRenderer, /Writing the active task/) assert.match(todoWriteRenderer, /Pending task/) -assert.match(todoWriteRenderer, /cb-plan-task--completed/) -assert.match(todoWriteRenderer, /cb-plan-task--in_progress/) -assert.match(todoWriteRenderer, /cb-plan-task--pending/) +assert.match(todoWriteRenderer, /cr-tool-plan-task__text--done/) +assert.match(todoWriteRenderer, /cr-tool-plan-task__text--running/) +assert.match(todoWriteRenderer, /data-task-status="pending"/) const todoStepsRenderer = renderToStaticMarkup( ) assert.match(todoStepsRenderer, /Compatibility step/) -assert.match(todoStepsRenderer, /cb-plan-task--in_progress/) +assert.match(todoStepsRenderer, /cr-tool-plan-task__text--running/) const fileListRenderer = renderToStaticMarkup( ) diff --git a/scripts/run-alignment-regression.mjs b/scripts/run-alignment-regression.mjs index c372106..639e8ba 100644 --- a/scripts/run-alignment-regression.mjs +++ b/scripts/run-alignment-regression.mjs @@ -22,7 +22,7 @@ if (domModule) { const tests = [ 'model-selection-alignment-regression.ts', 'model-settings-alignment-regression.ts', 'session-factory-alignment-regression.ts', 'session-composer-alignment-regression.tsx', 'alignment-conversation-regression.tsx', 'question-answer-shell-regression.tsx', - 'runtime-authorization-regression.ts', 'permission-intercept-regression.tsx' + 'runtime-authorization-regression.ts', 'permission-intercept-regression.tsx', 'todo-write-regression.tsx' ] for (const file of tests) { const format = file.endsWith('.tsx') ? 'cjs' : 'esm' @@ -42,7 +42,7 @@ for (const file of ['scripts/build-runtime-regressions.mjs', '.tmp/claude-approv // Optional DOM tests use separately installed jsdom, not Electron/CLI or an upstream model. if (domModule) { - for (const file of ['task-popconfirm-regression', 'question-interaction-regression', 'question-identity-regression', 'question-composer-dom-regression', 'completed-fold-nested-regression', 'completed-fold-native-identity-regression', 'permission-intercept-dom-regression', 'reasoning-follow-dom-regression']) { + for (const file of ['task-popconfirm-regression', 'question-interaction-regression', 'question-identity-regression', 'question-composer-dom-regression', 'completed-fold-nested-regression', 'completed-fold-native-identity-regression', 'permission-intercept-dom-regression', 'reasoning-follow-dom-regression', 'todo-write-dom-regression']) { const outfile = `.tmp/alignment-tests/${file}.cjs` await build({ entryPoints: [`scripts/${file}.tsx`], outfile, bundle: true, platform: 'node', format: 'cjs', jsx: 'automatic', loader: { '.css': 'empty' }, logLevel: 'warning' }) const result = spawnSync(process.execPath, [outfile], { stdio: 'inherit', timeout: 120000 }) @@ -56,5 +56,5 @@ if (domModule) { console.log(JSON.stringify({ result: 'PASS', phase: 'alignment-offline', suites: tests.length + 3 })) console.log(JSON.stringify(domModule - ? { result: 'PASS', phase: 'alignment-dom', suites: 9 } - : { result: 'SKIP', phase: 'alignment-dom', suites: 9, reason: 'YCODE_TEST_DOM_MODULE is not set; DOM coverage was not run. Use --require-dom to forbid this skip.' })) + ? { result: 'PASS', phase: 'alignment-dom', suites: 10 } + : { result: 'SKIP', phase: 'alignment-dom', suites: 10, reason: 'YCODE_TEST_DOM_MODULE is not set; DOM coverage was not run. Use --require-dom to forbid this skip.' })) diff --git a/scripts/todo-write-dom-regression.tsx b/scripts/todo-write-dom-regression.tsx new file mode 100644 index 0000000..32aadcb --- /dev/null +++ b/scripts/todo-write-dom-regression.tsx @@ -0,0 +1,97 @@ +/** B05 real React TodoWrite + CompletedFold DOM tests. Synthetic data only, no native UI claim. */ +import assert from 'node:assert/strict' +import { createRequire } from 'node:module' +import type { ConversationToolCall } from '../src/renderer/src/workbuddy/conversation/types' +const { JSDOM } = createRequire(process.cwd() + '/package.json')(process.env.YCODE_TEST_DOM_MODULE || 'jsdom') +const dom = new JSDOM('
', { pretendToBeVisual:true, url:'http://localhost/' }) +for (const key of ['window','document','Node','Element','HTMLElement','MouseEvent','KeyboardEvent','Event','CustomEvent']) Object.defineProperty(globalThis,key,{value:dom.window[key],configurable:true}) +Object.defineProperty(globalThis,'navigator',{value:dom.window.navigator,configurable:true}) +Object.assign(globalThis,{IS_REACT_ACT_ENVIRONMENT:true,requestAnimationFrame:dom.window.requestAnimationFrame.bind(dom.window),cancelAnimationFrame:dom.window.cancelAnimationFrame.bind(dom.window)}) +const { act } = require('react') as typeof import('react') +const { createRoot } = require('react-dom/client') as typeof import('react-dom/client') +const { CompletedFold } = require('../src/renderer/src/workbuddy/conversation/CompletedFold') as typeof import('../src/renderer/src/workbuddy/conversation/CompletedFold') +const { ToolCallRenderer } = require('../src/renderer/src/workbuddy/conversation/ToolCallRenderer') as typeof import('../src/renderer/src/workbuddy/conversation/ToolCallRenderer') +const { ThinkingBlock } = require('../src/renderer/src/workbuddy/conversation/SpecializedBlocks') as typeof import('../src/renderer/src/workbuddy/conversation/SpecializedBlocks') +const root = createRoot(document.getElementById('root')!) +let checks = 0 +function equal(actual:unknown, expected:unknown, label:string) { assert.deepEqual(actual,expected,label);checks++ } +const tasks = (count=7, active=4) => Array.from({length:count},(_,i)=>({id:String(i+1),content:`Task ${i+1}`,activeForm:`Working ${i+1}`,status:i===active?'in_progress':i={todos:tasks()}): ConversationToolCall => ({id,name:'TodoWrite',status:'executed',isLastContent:last,args,result:'Todos have been modified successfully...',output:'Todos have been modified successfully...'}) +const calls: Array<{toolCallId:string;toolName:string;taskId:string|number}> = [] +interface Options { session?:string; finished?:boolean; last?:boolean; remount?:number; second?:boolean; callback?:boolean; active?:number; count?:number } +function Fixture({session='session-a',finished=true,last=true,remount=0,second=false,callback=false,active=4,count=7}: Options) { + const parts = [{type:'tool',toolId:'todo-1'},{type:'reasoning',id:'thought',text:'Saved thought'},{type:'tool',toolId:'ordinary'},{type:'tool',toolId:'question'},...(second?[{type:'tool',toolId:'todo-2'}]:[]),{type:'text',text:'Answer'}] + return part.toolId==='question'?{role:'inline-question'}:undefined} + renderUnit={part=>part.type==='reasoning'?:part.type==='tool'?
+ calls.push(request):undefined} /> +
:

Answer

} /> +} +const find=(selector:string)=>{const el=document.querySelector(selector);assert.ok(el,selector);return el} +const todo='[data-fixture-tool="todo-1"] .cr-tool-head__main' +const secondTodo='[data-fixture-tool="todo-2"] .cr-tool-head__main' +const ordinary='[data-fixture-tool="ordinary"] .cr-tool-head__main' +const question='[data-fixture-tool="question"] .cr-tool-head__main' +const thought='.cr-reasoning > .cr-collapse__header' +const outer='.cr-collapse--completed > .cr-collapse__header' +const expanded=(selector:string)=>find(selector).getAttribute('aria-expanded') +const rows=()=>Array.from(document.querySelectorAll('[data-fixture-tool="todo-1"] .cr-tool-plan-task__row')).map(el=>el.getAttribute('data-task-id')) +async function render(options:Options={}) { await act(async()=>root.render()) } +async function click(selector:string) { await act(async()=>find(selector).dispatchEvent(new MouseEvent('click',{bubbles:true}))) } +async function key(selector:string,value:string) { await act(async()=>find(selector).dispatchEvent(new KeyboardEvent('keydown',{key:value,bubbles:true,cancelable:true}))) } +async function main() { + await render() + equal(expanded(outer),'false','finished outer starts closed') + await click(outer) + equal(expanded(todo),'true','last Todo initially open') + equal(rows(),['3','4','5','6','7'],'real component displays five centered rows') + equal(document.querySelector('[data-fixture-tool="todo-1"]')!.textContent!.includes('Todos have been modified successfully'),false,'SDK success hidden') + for(const selector of [ordinary,question,thought]) {equal(expanded(selector),'false',`${selector} starts independent`); await click(selector)} + await click(todo); equal(expanded(todo),'false','manual Todo close') + await render(); equal(expanded(todo),'false','same isLastContent preserves manual choice') + await click(outer); await click(outer) + equal(expanded(todo),'false','outer collapse/reopen preserves manual close') + for(const selector of [ordinary,question,thought]) equal(expanded(selector),'true','Todo state does not alter other disclosure') + await render({remount:1}); equal(expanded(todo),'false','same-value inner remount preserves manual choice') + await render({last:false,remount:1}); equal(expanded(todo),'false','true to false closes') + await render({last:true,remount:1}); equal(expanded(todo),'true','false to true opens') + await render({last:false,remount:2}); equal(expanded(todo),'false','real true-false edge concurrent with remount closes') + await click(todo); equal(expanded(todo),'true','manual open while not last') + await render({last:false,remount:3}); equal(expanded(todo),'true','same false remount does not overwrite manual open') + await click(todo); equal(expanded(todo),'false','manual close before next real edge') + await render({last:true,remount:4}); equal(expanded(todo),'true','false-true remount opens despite retained manual close') + await render({session:'session-b',last:false}); equal(expanded(outer),'false','session identity resets completed outer') + await click(outer); equal(expanded(todo),'false','same tool id in other session does not inherit') + for(const selector of [ordinary,question,thought]) equal(expanded(selector),'false','other disclosures isolated per session') + await render({session:'live-session',finished:false,last:true}) + equal(expanded(todo),'true','live Todo open') + await render({session:'live-session',finished:true,last:false}) + equal(expanded(todo),'false','live-to-completed reparent plus actual edge closes') + await click(outer); await click(todo) + await render({session:'live-session',finished:true,last:false,second:true}) + equal(expanded(todo),'true','older manually opened snapshot stays open after later call') + equal(expanded(secondTodo),'true','later call has own disclosure') + equal(document.querySelectorAll('.cr-tool-head--todo-write').length,2,'distinct historical calls are not merged') + equal(document.querySelectorAll('[data-fixture-tool="todo-2"] .cr-tool-plan-task__row').length,5,'second snapshot independently projected') + await click(secondTodo); equal(expanded(todo),'true','closing later Todo cannot close older snapshot') + await render({session:'live-session',finished:true,last:false,second:true,active:6}) + equal(rows(),['3','4','5','6','7'],'same call update refreshes window without data merge') + assert.match(find('[data-fixture-tool="todo-1"]').textContent!,/Working 7/); checks++ + await render({session:'callbacks',callback:true}) + await click(outer) + const row='[data-fixture-tool="todo-1"] [data-task-id="3"]' + equal(find(row).getAttribute('role'),'button','host callback exposes button semantics') + equal(find(row).getAttribute('tabindex'),'0','host callback exposes Tab target') + await click(row); await key(row,'Enter'); await key(row,' ') + equal(calls,[0,1,2].map(()=>({toolCallId:'todo-1',toolName:'TodoWrite',taskId:'3'})),'click and keyboard preserve exact event identity') + equal(expanded(todo),'true','row activation does not toggle parent') + await render({session:'callbacks',callback:false}) + equal(find(row).getAttribute('role'),null,'no fake role without actual host target') + equal(find(row).getAttribute('tabindex'),null,'no fake keyboard navigation without target') + await click(row); await key(row,'Enter'); equal(calls.length,3,'callback removed disables interaction') + await act(async()=>root.unmount());dom.window.close() + console.log(`todo-write-dom: ${checks} actual TodoWrite/CompletedFold checks passed; no Electron/pixel claim`) +} +main().then(()=>process.exit(0)).catch(error=>{console.error(error);dom.window.close();process.exit(1)}) diff --git a/scripts/todo-write-regression.tsx b/scripts/todo-write-regression.tsx new file mode 100644 index 0000000..33ffaa9 --- /dev/null +++ b/scripts/todo-write-regression.tsx @@ -0,0 +1,98 @@ +/** B05 projection and SSR checks; no SDK, network, or pixel claims. */ +import assert from 'node:assert/strict' +import { renderToStaticMarkup } from 'react-dom/server' +import { ToolCallRenderer, getCapturedToolKind } from '../src/renderer/src/workbuddy/conversation/ToolCallRenderer' +import { normalizeTodoWrite, windowTodoTasks } from '../src/renderer/src/workbuddy/conversation/TodoWriteView' +import type { ConversationToolCall } from '../src/renderer/src/workbuddy/conversation/types' +let checks = 0 +function check(name: string, run: () => void) { run(); checks++; console.log(`PASS ${name}`) } +const tasks = (count: number, active = -1, completed: number[] = []) => Array.from({ length: count }, (_, i) => ({ id: String(i + 1), content: `Task ${i + 1}`, activeForm: `Working ${i + 1}`, status: i === active ? 'in_progress' : completed.includes(i) ? 'completed' : 'pending' })) +const tool = (patch: Partial = {}): ConversationToolCall => ({ id: 'todo-1', name: 'TodoWrite', status: 'executed', isLastContent: true, args: { todos: tasks(7, 4) }, result: 'Todos have been modified successfully...', output: 'Todos have been modified successfully...', ...patch }) +const render = (value: ConversationToolCall) => renderToStaticMarkup() +const ids = (items: ReturnType) => windowTodoTasks(items).map(item => String(item.id)) +const fixtures: [string, ReturnType, string[]][] = [ + ['six second active', tasks(6, 1), ['1','2','3','4','5']], + ['seven fifth active', tasks(7, 4), ['3','4','5','6','7']], + ['seven first active', tasks(7, 0), ['1','2','3','4','5']], + ['seven last active', tasks(7, 6), ['3','4','5','6','7']], + ['seven all pending', tasks(7), ['1','2','3','4','5']], + ['seven all completed', tasks(7, -1, [0,1,2,3,4,5,6]), ['3','4','5','6','7']], + ['only fourth completed', tasks(7, -1, [3]), ['2','3','4','5','6']], + ['multiple active uses first', tasks(7, 1).map((x,i) => i === 5 ? {...x,status:'in_progress'} : x), ['1','2','3','4','5']], + ['empty', tasks(0), []], ['one', tasks(1), ['1']], ['five', tasks(5), ['1','2','3','4','5']], + ['long middle', tasks(100, 49), ['48','49','50','51','52']], +] +for (const [name,input,expected] of fixtures) check(`window ${name}`, () => { + const before = structuredClone(input) + assert.deepEqual(ids(input), expected); assert.deepEqual(input,before) + const html = render(tool({args:{todos:input}})) + assert.equal((html.match(/data-task-id=/g) || []).length,expected.length) + assert.doesNotMatch(html, /更多|下一页|上一页/) +}) +for (const alias of ['TodoWrite','todo_write','todoWrite','todo-write']) check(`alias ${alias}`, () => { + assert.equal(getCapturedToolKind(alias),'todo-write') + assert.match(render(tool({name:alias})), /cr-tool-head--todo-write/) +}) +check('ordinary tools do not enter dedicated view', () => { + assert.equal(getCapturedToolKind('NotTodoWrite'),undefined) + assert.doesNotMatch(render(tool({name:'NotTodoWrite'})), /cr-tool-head--todo-write/) +}) +for (const raw of [false,true,'json'] as const) check(`args and raw input ${raw}`, () => { + const input = { merge:true, todos:[{id:0, content:'Done', activeForm:'Doing',status:'completed'},{id:'a',content:'Active',activeForm:'Active now',status:'in_progress'}] } + const value = tool({args: raw ? {_rawInput:raw === 'json' ? JSON.stringify(input) : input} : input}) + const before = structuredClone(value), projection = normalizeTodoWrite(value) + assert.equal(projection.merge,true); assert.equal(projection.completedCount,1); assert.equal(projection.totalCount,2) + assert.equal(projection.tasks[0].id,0); assert.equal(projection.tasks[1].activeForm,'Active now') + render(value); assert.deepEqual(value,before) +}) +check('historical steps retain compatible task aliases', () => { + const value = tool({args:{steps:[{title:'Legacy task',status:'doing'}]}}) + assert.match(render(value),/Legacy task/); assert.match(render(value),/data-task-status="in_progress"/) +}) +check('single dedicated title, modern status rows and output projection', () => { + const value = tool({args:{todos:[...tasks(3,1,[0]),{id:'failed',content:'Failed task',status:'failed'}]}}) + const before = structuredClone(value), html = render(value) + assert.equal((html.match(/任务列表/g)||[]).length,1) + assert.match(html,/cr-tool-plan-task__text--done/) + assert.match(html,/cr-tool-plan-task__text--running/) + assert.match(html,/Working 2/); assert.doesNotMatch(html,/>Task 2 { + const html = render(tool({args:{merge:true,todos:tasks(7,6,[0,1,2,3,4,5])}})) + assert.match(html,/进度 6\/7/); assert.doesNotMatch(html,/任务列表|进度更新/) +}) +check('empty running is header only with receiving cue', () => { + const html = render(tool({status:'running',args:{todos:[]}})) + assert.match(html,/接收中/); assert.equal((html.match(/任务列表/g)||[]).length,1) + assert.doesNotMatch(html,/cr-tool-plan-task__row|cr-tool-exp__content-shell/) +}) +check('empty finished is header only without receiving cue', () => { + const html = render(tool({args:{todos:[]}})) + assert.match(html,/任务列表/); assert.doesNotMatch(html,/接收中|cr-tool-exp__content-shell/) +}) +check('failure is dedicated error header only', () => { + const html = render(tool({status:'failed',result:'error',output:'SDK ERROR RAW'})) + assert.match(html,/生成失败/); assert.match(html,/cr-tool-head__icon--error/) + assert.doesNotMatch(html,/cr-tool-plan-task__row|cr-tool-exp__content-shell|SDK ERROR RAW/) +}) +check('without host callback rows are not fake buttons', () => { + const html = render(tool()) + assert.doesNotMatch(html,/cr-tool-plan-task__row[^>]*role="button"|cr-tool-plan-task__action/) +}) +check('malformed raw input falls back without modifying original data', () => { + const value = tool({args:{_rawInput:'{bad JSON',todos:[null, 7, {}, {content:' '}, {id:0,content:'Safe task',activeForm:' ',status:'in_progress'}]}}) + const before = structuredClone(value), projection = normalizeTodoWrite(value) + assert.equal(projection.tasks.length,1); assert.equal(projection.tasks[0].id,0) + assert.equal(projection.tasks[0].activeForm,undefined) + const html = render(value); assert.match(html,/Safe task/); assert.deepEqual(value,before) +}) +check('long and escaped content stays plain text with full title', () => { + const content = 'Long task ' + ' '.repeat(20) + const html = render(tool({args:{todos:[{id:'long',content,status:'pending'}]}})) + assert.match(html,/title="Long task/); assert.match(html,/<script>/) + assert.doesNotMatch(html,/