docs(acceptance): verify B03 Windows permissions and composer recovery
This commit is contained in:
1 parent
1df1861a7a
commit
352d62d49a
24 files changed
+1723
No files matched your search
@@ -0,0 +1,127 @@
|
||||
# B03 验收 01:Windows 完全访问与底部授权
|
||||
|
||||
日期:2026-10-21,Asia/Shanghai。受测代码:**`adbbb3bd37f6043d10cbaa59d6c28ade6387a7f3`**。交付记录:[B03-交付-01](B03-交付-01.md)。
|
||||
|
||||
**结论:本轮 Windows 已测的核心功能通过,没有复现“完全访问仍反复弹普通授权”或“授权卡下面还有完整输入框”。本次还验证了真实会话授权、重建与客户端重启的不同生命周期。B03 仍保留未覆盖的边界和原版对照项,不能宣称全部 AC 或完整 1:1 关闭。**
|
||||
|
||||
验收端只改验收文档和提交的脱敏证据,没有修改产品源码、正式测试、依赖或构建配置。B04 不在 B03 受测 SHA 中;验收过程中收到的 B04 交付另按 `3428206` 验证,不混入本报告。B01/B02 的历史失败和未验证项继续保留。
|
||||
|
||||
## 1. 环境与隔离
|
||||
|
||||
- Windows;Node `24.21.0`、npm `11.19.0`、Electron `37.10.3`、实际 SDK `0.3.304`。
|
||||
- 在新的 `b03-accept-01` 工作树固定检出完整受测 SHA,独立执行 `npm ci --legacy-peer-deps`,`node_modules` 是本地目录,不是其他工作树的链接。
|
||||
- npm 未自动运行 Electron 安装脚本,因此另行执行 `node node_modules/electron/install.js`;没有升级依赖或执行 audit fix。
|
||||
- 生产构建之后启动测试专属实例,独立 userData、HOME、workspace、模型配置和本地 SSE 回环。未使用用户供应商、真实凭据、真实会话或当前 dev。
|
||||
- 全应用测试加载未修改的 `out/main/index.mjs`、preload、renderer,模型响应由本地固定 SSE 服务提供。SDK/CLI 和文件、命令执行是真实的;模型内容是夹具,不证明外部模型服务或开放式 Agent 决策正确。
|
||||
- 其他回环测试打包实际 `ClaudeKernel`,仅替换 Electron 的 userData 路径接口,SDK query 未 mock。
|
||||
- 受测工作树在验证后 `git status --short` 为空。临时探针只写忽略的 `.tmp`,不会随本次报告替换产品实现。
|
||||
|
||||
## 2. Windows 实际内核与 SDK:9 场景、26 次本地请求
|
||||
|
||||
使用交付中的回环协议,在验收端临时适配 Windows 环境、Git Bash 路径,并加入真实 PowerShell 操作和结果断言。没有删掉宿主策略、hook、callback、默认权限或模式边界。
|
||||
|
||||
| 场景 | 人工工具审批次数 | 实际结果 |
|
||||
| --- | ---: | --- |
|
||||
| 默认权限 craft | 1 | Write 按夹具拒绝,目标文件不存在 |
|
||||
| 切为完全访问 craft | 0 | Read/Edit/Write、简单与复合 Bash、PowerShell 成功;编辑、新建和删除结果与标记文件检查通过;业务追问 1 次 |
|
||||
| 完全访问偏好 + plan | 0 | Write 被模式边界拒绝,目标不存在 |
|
||||
| 完全访问偏好 + ask | 0 | Write 被模式边界拒绝,目标不存在 |
|
||||
| 返回默认权限 craft | 1 | 再次出现工具审批,按夹具拒绝 |
|
||||
| 完全访问 + 实际 SDK ask:Bash 规则 | 0 | 命令执行成功,callback 的 matchedAskRule=true 仍由宿主预授权 |
|
||||
| 默认权限 + 同一实际规则 | 1 | rule-intercept,拒绝后标记文件未追加 |
|
||||
| 销毁并重建完全访问内核 | 0 | Write 与业务追问正常;追问 1 次 |
|
||||
| 完全访问下不存在目标 Edit、Bash exit 7 | 0 | 两次实际工具错误,没有重新弹权限审批 |
|
||||
|
||||
PowerShell 夹具使用独立目录,实际新增目录和文件、删除文件和目录、写入完成标记;断言目录不存在、完成文件内容正确。Bash 也实际新增/删除临时对象并验证完成标记。
|
||||
|
||||
结果:[windows-loopback-results.json](evidence/B03-review-01/windows-loopback-results.json)、[日志](evidence/B03-review-01/windows-loopback.txt)、[验收探针](evidence/B03-review-01/windows-loopback.mjs)。
|
||||
|
||||
## 3. “本次会话内始终允许”:单独验证,未用完全访问替代
|
||||
|
||||
默认权限下以真实 `Bash(git init *)` 建议授权为夹具,执行范围仅限测试 workspace。第一次由实际 SDK 生成选项,验收回调调用真实宿主授权提交函数;后续由实际 SDK 匹配与执行。
|
||||
|
||||
| 场景 | 人工审批 | 结果 |
|
||||
| --- | ---: | --- |
|
||||
| 首次执行 | 1 | 提供 allow_once / allow_always / reject_once;选择会话授权并实际执行 |
|
||||
| 同内核下一轮 | 0 | 命中会话授权,实际成功 |
|
||||
| 同客户端进程、同宿主会话,销毁并重建内核 | 0 | grant 重放后成功 |
|
||||
| 新宿主会话 | 1 | 未继承前一个会话的 grant |
|
||||
| 已授权之后切到 plan / ask | 0 | 执行仍被模式边界拒绝 |
|
||||
|
||||
该组 6 场景、12 次本地请求通过,实际 `.git` 目录存在。[结果](evidence/B03-review-01/windows-session-grants-results.json)、[日志](evidence/B03-review-01/windows-session-grants.txt)、[探针](evidence/B03-review-01/windows-session-grants.mjs)。
|
||||
|
||||
另观察到 `printf` 重定向和普通 Write 的实际建议不符合现有可重放授权范围,因此界面只提供“允许一次”和“拒绝”,并提示不能安全恢复。这不是本轮证明所有命令都支持“始终允许”的证据。上述生命周期结论只针对实际返回了可重放建议的匹配规则,不扩张成全工具永久允许。
|
||||
|
||||
## 4. 完整生产应用:首发、底部授权、真实按钮和重启
|
||||
|
||||
两次独立 Electron 进程共享同一份全新的测试 userData,第一次 23 项、重启后 7 项,共 **30 项检查通过**,两次均无捕获到的 renderer console error。除实际正常通路外,测试启动器对首次 `chat:respond` / `chat:cancel` 分别注入一次失败,用于验证界面失败恢复;这两次错误是夹具,不是真实 SDK 故障的还原。
|
||||
|
||||
1. 新任务在首发前通过真实权限控件选择完全访问,再通过输入区发送。Write 和 PowerShell 实际成功,MutationObserver 未观察到活动授权卡;会话保存为 full-access。
|
||||
2. 切回默认权限并发起 Write。等待模型响应时输入一份后续草稿,再释放夹具响应。授权卡独占底部,原 input-stack 为 hidden/inert,计算 display 为 none,普通工具栏和发送按钮不存在,活动授权 dialog 只有一份。
|
||||
3. 焦点在活动授权区域;强行调用隐藏 textarea 的 focus 无效,原生键盘输入 X 不能改变隐藏草稿。首次“拒绝”由测试启动器注入提交失败,错误显示在原授权区,普通输入框仍隐藏;再次点击真实“拒绝”按钮完成审批。文件未创建,普通输入区恢复,后续草稿原样保留。
|
||||
4. 默认权限执行 `git init`,点击真实“本次会话内始终允许”按钮。实际命令成功;同会话下一轮再次执行,无重复授权卡。
|
||||
5. 再次选择完全访问,退出测试客户端进程并重新打开,选择保存的会话。full-access 标签、实际 Write、PowerShell 执行均正确,未出现授权卡。这不是仅重新加载 renderer。
|
||||
6. 重启后切回默认权限,再执行此前授权的 `git init`,重新出现会话授权选项,证明 grant 不跨客户端进程永久保存;测试选择拒绝结束。
|
||||
7. 另发起一轮确需审批的 Write,首次“停止当前运行”注入取消失败。错误明确显示在授权区域,普通编辑区仍隐藏;再次停止调用真实取消通路,输入框和工具栏恢复。
|
||||
|
||||
证据:[首次运行报告](evidence/B03-review-01/app-first-report.json)、[重启报告](evidence/B03-review-01/app-restart-report.json)、[全应用验收探针](evidence/B03-review-01/app-native.cjs)。
|
||||
|
||||
已人工查看底部授权、拒绝后草稿恢复截图:
|
||||
|
||||
- [底部授权替换](evidence/B03-review-01/app-first-bottom-approval.png)
|
||||
- [拒绝后草稿恢复](evidence/B03-review-01/app-first-draft-restored.png)
|
||||
- [实际会话授权选项](evidence/B03-review-01/app-first-session-grant.png)
|
||||
- [重启后重新询问会话授权](evidence/B03-review-01/app-restart-grant-reapproval.png)
|
||||
- [审批提交失败仍占据输入区](evidence/B03-review-01/app-first-approval-failure.png)
|
||||
- [停止失败的可见错误](evidence/B03-review-01/app-first-cancel-failure.png)
|
||||
|
||||
全应用测试进程日志另含测试启动器的“更新请求来源不受信任”、跳过托盘图标、固定夹具模型名未识别及上述主动注入失败等提示,不能把“0 renderer error”改写为整个进程无日志警告。本次没有更改更新模块信任校验,也没有把这些提示当成权限通路失败。
|
||||
|
||||
## 5. 构建与回归
|
||||
|
||||
| 命令 | 本轮 Windows 结果 |
|
||||
| --- | --- |
|
||||
| `npm run build` | 退出 0,包含类型检查 |
|
||||
| `npm test` | 退出 0,类型/消息/会话/持久化/会话渲染 |
|
||||
| 设置 jsdom 路径后 `npm run test:alignment:dom` | 退出 0,offline 11 套、DOM 7 套;包含 276 项 B03 mock-query policy、43 项实际组件 DOM 检查 |
|
||||
| `npm run test:reporting` | 退出 0 |
|
||||
| `npm run test:composer-capabilities` | 退出 0 |
|
||||
| `npm run test:tool-approvals` | 退出 0 |
|
||||
| `npm run check:tokens` | 退出 1,仍是既有六项、原计数;没有更新 baseline |
|
||||
|
||||
详见 [测试结果](evidence/B03-review-01/test-results.json)、[alignment 日志](evidence/B03-review-01/alignment.txt)、[构建日志](evidence/B03-review-01/build.txt)、[token 日志](evidence/B03-review-01/check-tokens.txt)。B01 原生脚本可移植性、B02 hover 断言和既有 CRLF 失败未因本轮其他检查通过而关闭。
|
||||
|
||||
## 6. AC 判定与剩余范围
|
||||
|
||||
| AC | 本轮判定 |
|
||||
| --- | --- |
|
||||
| 7.1 | Windows SDK 原生 Read/Edit/Write、Bash/PowerShell 四类操作核心验证通过;应用首发和重启后 Write/PowerShell 通过。SDK 独立目录工具及所有工具/后续轮次的排列组合未穷举。 |
|
||||
| 7.2 | 实际 Windows SDK default + host gate、真实 ask-rule 的 full/default 对照通过;合成未知/classifier/别名矩阵通过,不把合成字段等同原用户回调还原。 |
|
||||
| 7.3 | default、plan、ask、业务追问和实际执行错误通过。ExitPlanMode 当前主要为离线证据;Windows 文件系统 ACL 拒绝未另行实测。 |
|
||||
| 7.4 | 实装版本与实际 callback 通路有证据;原用户七次审批的具体原始判定字段仍未知。 |
|
||||
| 7.5 | 完整应用首发、权限切换、客户端进程重启和实际内核重建通过;策略失败闭锁/串行 race 为 mock-query 证据,未故障注入真实 CLI 控制通道。 |
|
||||
| 7.6 | 实际规则下的会话授权、下一轮、同进程内核重建、新会话隔离、模式边界、客户端重启过期均通过;不是全工具白名单,也不等于全部规则类型可重放。 |
|
||||
| 7.7 | 实际日志包含宿主权限、SDK 配置/控制确认模式来源、hook/callback、哈希关联和分支;未知类别/原因代码明确 unknown。未取得原用户历史回调。 |
|
||||
| 7.8 | 未修改生产应用中实际底部替换通过,有 Windows 截图;没有本轮 WorkBuddy 同状态 REA/像素比较。 |
|
||||
| 7.9 | 实际应用拒绝后草稿恢复、允许会话授权、原生焦点/隐藏输入防护,以及注入提交失败和取消失败后的重试通过。附件/引用/队列和迟到结果等另有 43 项组件 DOM 证据;完整应用 IME/读屏及全部会话切换异常组合未全覆盖。 |
|
||||
|
||||
本轮没有确认新的阻塞性产品缺陷;尚缺证据的项目保持“未验证”,不以测试绿灯替代完整验收。建议开发端把 Windows 回环、真实会话授权与完整应用重启探针整理为可维护的正式回归,并继续完成交付记录中的剩余范围。验收探针随报告提供,验收端未将其写入正式 scripts 或产品源码。
|
||||
|
||||
## 7. 证据复跑
|
||||
|
||||
在受测 SHA 的隔离检出独立安装并构建。证据中的三个脚本是验收临时探针,读取的都是自身生成的夹具,不依赖本机真实用户数据:
|
||||
|
||||
```powershell
|
||||
New-Item -ItemType Directory -Force .tmp/b03-acceptance | Out-Null
|
||||
Copy-Item docs/协作/evidence/B03-review-01/windows-loopback.mjs .tmp/b03-win-loopback.mjs
|
||||
Copy-Item docs/协作/evidence/B03-review-01/windows-session-grants.mjs .tmp/b03-session-grant.mjs
|
||||
Copy-Item docs/协作/evidence/B03-review-01/app-native.cjs .tmp/b03-acceptance/app-native.cjs
|
||||
node scripts/build-full-access-loopback-kernel.mjs
|
||||
node .tmp/b03-win-loopback.mjs --kernel
|
||||
node .tmp/b03-session-grant.mjs --kernel
|
||||
node .tmp/b03-acceptance/app-native.cjs
|
||||
```
|
||||
|
||||
Windows 探针中的 Git Bash 路径需要改为目标电脑实际安装路径;它不是产品路径配置。回环探针内部 100 秒 abort,全应用启动器每个测试进程有 120 秒上限,只结束自己创建的进程。临时目录独立生成;不准把用户真实会话或 dev 目录填成测试数据目录。
|
||||
|
||||
本次没有重新读取 WorkBuddy 安装包、脚本、页面或运行时,因此没有新的 REA Evidence ID。原版外观依据仍是需求中的用户截图和既有证据,不能宣称取得新的原版视觉结论。推送记录核对成功后,本批协作窗口交回开发端。
|
||||
@@ -0,0 +1,48 @@
|
||||
|
||||
> ycode@0.0.7 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":4.0756999999999834,"storeHydrationMs":0.28829999999999245,"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
|
||||
[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)
|
||||
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: 43 checks passed (not pixel/SDK verification)
|
||||
{"checks":37,"passed":true,"scope":"Isolated React DOM and CSS contracts; no native keyboard/layout/pixel acceptance"}
|
||||
{"result":"PASS","phase":"alignment-offline","suites":11}
|
||||
{"result":"PASS","phase":"alignment-dom","suites":7}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 85 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 81 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 84 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 74 KiB |
@@ -0,0 +1,100 @@
|
||||
{
|
||||
"codeSha": "adbbb3bd37f6043d10cbaa59d6c28ade6387a7f3",
|
||||
"scope": "Unchanged production app + main/preload/renderer + real Windows SDK/CLI with deterministic local SSE; fresh data; actual UI permission and send",
|
||||
"checks": [
|
||||
{
|
||||
"name": "initial home permission defaults",
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "full selected before first send",
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "full write executed",
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "full PowerShell executed",
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "no approval card under full",
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "persisted full permission",
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "normal input hidden",
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "normal input inert",
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "normal toolbar absent",
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "only one interactive permission dialog",
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "approval receives native focus",
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "hidden native editor cannot receive focus",
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "native typing cannot change hidden draft",
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "failed approval stays in replacement",
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "draft restored after denial",
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "normal toolbar restored",
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "default denied actual write",
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "UI session grant executes command",
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "grant next turn reaches completion",
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "session grant prevents repeated approval",
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "failed cancel error visible in replacement",
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "cancel retry restores normal input",
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "zero renderer console errors",
|
||||
"pass": true
|
||||
}
|
||||
],
|
||||
"requests": 11,
|
||||
"errors": []
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 79 KiB |
@@ -0,0 +1,58 @@
|
||||
const fs=require('node:fs/promises'), path=require('node:path'), assert=require('node:assert/strict');
|
||||
if(!process.versions.electron){(async()=>{
|
||||
const dir=await fs.mkdtemp(path.resolve('.tmp/b03-app-'));for(const n of ['data','home','workspace'])await fs.mkdir(path.join(dir,n));
|
||||
const net=require('node:net').createServer();await new Promise(r=>net.listen(0,'127.0.0.1',r));const port=net.address().port;await new Promise(r=>net.close(r));
|
||||
const model={id:'b03-local',name:'B03 Local Fixture',model:'claude-loopback',providerId:'custom',protocol:'anthropic',authMode:'api-key',apiKeyPlain:'local-fixture-placeholder',baseUrl:`http://127.0.0.1:${port}`,supportsToolCall:true,contextWindowTokens:200000,maxOutputTokens:4096};
|
||||
await fs.writeFile(path.join(dir,'data/models.json'),JSON.stringify({version:1,models:[model],selectedModelId:model.id}));
|
||||
await fs.writeFile(path.join(dir,'data/workspaces.json'),JSON.stringify({selectedWorkspaceId:'b03-space',workspaces:[{id:'b03-space',name:'QA Workspace',root:path.join(dir,'workspace'),createdAt:Date.now()}]}));
|
||||
await fs.writeFile(path.join(dir,'data/config.json'),JSON.stringify({workspaceRoot:path.join(dir,'workspace'),preventSleep:false,autoLaunch:false}));
|
||||
for(const phase of ['first','restart']){
|
||||
const env={...process.env,YCODE_USER_DATA_DIR:path.join(dir,'data'),YCODE_QA_DIRECTORY:dir,YCODE_SKIP_KERNEL_DATA_RESET:'1',YCODE_DISABLE_GPU:'1',YCODE_DISABLE_SYSTEM_INTEGRATION:'1',HOME:path.join(dir,'home'),USERPROFILE:path.join(dir,'home'),CLAUDE_CODE_GIT_BASH_PATH:'C:/Users/Administrator/scoop/apps/git/current/bin/bash.exe',CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC:'1',DISABLE_TELEMETRY:'1',DISABLE_ERROR_REPORTING:'1',B03_APP_DIR:dir,B03_APP_PORT:String(port),B03_APP_PHASE:phase};
|
||||
for(const k of Object.keys(env))if(/^(ANTHROPIC_|CLAUDE_CODE_OAUTH_TOKEN)/.test(k))delete env[k];delete env.ELECTRON_RUN_AS_NODE;delete env.ELECTRON_RENDERER_URL;
|
||||
const c=require('node:child_process').spawn(require('electron'),['--no-sandbox','--disable-gpu-sandbox',__filename],{env,windowsHide:true,stdio:['ignore','pipe','pipe']});let log='';c.stdout.on('data',x=>log+=x);c.stderr.on('data',x=>log+=x);const t=setTimeout(()=>c.kill(),120000);const exit=await new Promise(r=>c.on('exit',r));clearTimeout(t);await fs.writeFile(path.join(dir,phase+'-process.txt'),log);console.log(JSON.stringify({directory:dir,phase,exit}));if(exit!==0){console.error(log.slice(-8000));process.exitCode=1;break}
|
||||
}
|
||||
})().catch(e=>{console.error(e);process.exitCode=1})}else{
|
||||
const {app,BrowserWindow,ipcMain}=require('electron'),{pathToFileURL}=require('node:url'),{createServer}=require('node:http');
|
||||
const dir=process.env.B03_APP_DIR,phase=process.env.B03_APP_PHASE,workspace=path.join(dir,'workspace');app.disableHardwareAcceleration();app.setPath('home',path.join(dir,'home'));
|
||||
let rejectRespondOnce=phase==='first',rejectCancelOnce=phase==='first';const realHandle=ipcMain.handle.bind(ipcMain);ipcMain.handle=(channel,listener)=>realHandle(channel,async(...args)=>{if(channel==='chat:respond'&&rejectRespondOnce){rejectRespondOnce=false;throw Error('QA approval submission failure')}if(channel==='chat:cancel'&&rejectCancelOnce){rejectCancelOnce=false;throw Error('QA cancellation failure')}return listener(...args)});
|
||||
let win,stage='start',scenario='full',issued=0,requestCount=0,held,releaseHeld=false;const checks=[],errors=[];let approvals=0;
|
||||
const pause=ms=>new Promise(r=>setTimeout(r,ms)),read=s=>win.webContents.executeJavaScript(s);
|
||||
async function wait(s){for(let i=0;i<350;i++){const x=await read(s);if(x)return x;await pause(30)}throw Error('Timeout '+s)}
|
||||
function check(name,x){checks.push({name,pass:!!x});assert.ok(x,name)}
|
||||
async function shot(n){await pause(200);await fs.writeFile(path.join(dir,phase+'-'+n+'.png'),(await win.webContents.capturePage()).toPNG())}
|
||||
async function fill(text){await read('document.querySelector(".wb-composer textarea").focus()');await win.webContents.insertText(text);await wait('document.querySelector(".wb-composer textarea").value.includes('+JSON.stringify(text)+')')}
|
||||
async function send(text){await fill(text);await wait('!document.querySelector(".cr-input-toolbar__send:not(.cr-send-button--stop)").disabled');await read('document.querySelector(".cr-input-toolbar__send:not(.cr-send-button--stop)").click()')}
|
||||
async function settled(){await wait('!document.querySelector(".cr-send-button--stop") && !document.querySelector("[data-composer-approval]")');await pause(200)}
|
||||
async function permission(full){await read('document.querySelector(".yc-source-permission-trigger > button").click()');await wait('!!document.querySelector(".cr-permission-panel__row")');await read('document.querySelector(".cr-permission-panel__row").click()');if(full){await wait('!!document.querySelector(".permission-confirm-acknowledgement")');await read('document.querySelector(".permission-confirm-acknowledgement").click()');await wait('!document.querySelector(".wb-composer__danger-button").disabled');await read('document.querySelector(".wb-composer__danger-button").click()')};await wait('!document.querySelector(".cr-permission-panel") && !document.querySelector(".permission-confirm-dialog")')}
|
||||
const server=createServer((req,res)=>{if(++requestCount>35){res.writeHead(429).end();return}let raw='';req.on('data',x=>raw+=x);req.on('end',async()=>{
|
||||
try{if(!req.url.includes('/messages')){res.writeHead(200).end('{}');return}const body=JSON.parse(raw);if(scenario==='default'&&!releaseHeld){await new Promise(r=>held=r)};
|
||||
const steps=scenario==='full'?[{name:'Write',input:{file_path:path.join(workspace,phase+'-written.txt'),content:'verified'}},{name:'PowerShell',input:{command:`[IO.File]::WriteAllText('${phase}-command.txt','verified')`,timeout:5000}}]:scenario==='grant'?[{name:'Bash',input:{command:'git init app-grant-repo',timeout:5000}}]:[{name:'Write',input:{file_path:path.join(workspace,'default-must-not-write.txt'),content:'blocked'}}];
|
||||
const step=steps[issued++];const emit=(event,data)=>res.write(`event: ${event}\ndata: ${JSON.stringify(data)}\n\n`);res.writeHead(200,{'content-type':'text/event-stream'});
|
||||
emit('message_start',{type:'message_start',message:{id:'msg_'+requestCount,type:'message',role:'assistant',model:body.model,content:[],stop_reason:null,stop_sequence:null,usage:{input_tokens:10,output_tokens:1}}});emit('content_block_start',{type:'content_block_start',index:0,content_block:step?{type:'tool_use',id:'tool_'+requestCount,name:step.name,input:{}}:{type:'text',text:''}});emit('content_block_delta',{type:'content_block_delta',index:0,delta:step?{type:'input_json_delta',partial_json:JSON.stringify(step.input)}:{type:'text_delta',text:'B03 fixture complete.'}});emit('content_block_stop',{type:'content_block_stop',index:0});emit('message_delta',{type:'message_delta',delta:{stop_reason:step?'tool_use':'end_turn',stop_sequence:null},usage:{output_tokens:5}});emit('message_stop',{type:'message_stop'});res.end();}catch(e){res.destroy(e)}
|
||||
})});
|
||||
const timer=setTimeout(()=>{console.error('WATCHDOG',stage);app.exit(1)},100000);
|
||||
;(async()=>{await new Promise(r=>server.listen(Number(process.env.B03_APP_PORT),'127.0.0.1',r));await import(pathToFileURL(path.resolve('out/main/index.mjs')).href);await app.whenReady();win=BrowserWindow.getAllWindows()[0];win.setSize(1336,902);win.showInactive();win.webContents.on('console-message',(_e,l,m)=>{if(l>=3)errors.push(m)});
|
||||
await wait('!!window.ycode && !!document.querySelector(".wb-composer textarea")');await pause(500);
|
||||
if(phase==='first'){
|
||||
stage='first-full-selection';check('initial home permission defaults',!(await read('document.querySelector(".yc-source-permission-trigger > button").textContent')).includes('完全访问'));await permission(true);check('full selected before first send',(await read('document.querySelector(".yc-source-permission-trigger > button").textContent')).includes('完全访问'));
|
||||
}else{
|
||||
stage='restart-load';const sessionId=await fs.readFile(path.join(dir,'session-id.txt'),'utf8');const sessionSelector=JSON.stringify('[data-session-id="'+sessionId+'"]');await wait('!!document.querySelector('+sessionSelector+')');await read('document.querySelector('+sessionSelector+').click()');await wait('!document.querySelector(".yc-session-skeleton") && !!document.querySelector(".wb-composer textarea")');check('restart restores saved full label',(await read('document.querySelector(".yc-source-permission-trigger > button").textContent')).includes('完全访问'));
|
||||
}
|
||||
await read('window.__b03Observer=new MutationObserver(()=>{window.__b03Approvals=(window.__b03Approvals||0)+(document.querySelector("[data-composer-approval]")?1:0)});window.__b03Observer.observe(document.body,{subtree:true,childList:true});true');
|
||||
stage='full-send';await send('B03_'+phase+'_FULL');for(let i=0;issued<3&&i<600;i++)await pause(30);assert.ok(issued>=3,'three loopback model requests completed');await wait('document.querySelector(".chat-thread")?.textContent.includes("B03 fixture complete.")');await settled();check('full write executed',(await fs.readFile(path.join(workspace,phase+'-written.txt'),'utf8'))==='verified');check('full PowerShell executed',(await fs.readFile(path.join(workspace,phase+'-command.txt'),'utf8'))==='verified');check('no approval card under full',!(await read('window.__b03Approvals||0')));
|
||||
const sessions=await read('window.ycode.session.list()');const current=sessions.find(s=>s.permissionMode==='full-access');check('persisted full permission',!!current);await fs.writeFile(path.join(dir,'session-id.txt'),current.id);await shot('full-completed');
|
||||
if(phase==='first'){
|
||||
stage='default-selection';await permission(false);scenario='default';issued=0;await send('B03_DEFAULT_DENY');while(!held)await pause(30);await fill('PRESERVED_DRAFT');releaseHeld=true;held();
|
||||
stage='approval';await wait('!!document.querySelector("[data-composer-approval]")');check('normal input hidden',await read('document.querySelector(".conversation-input-area__input-stack").hidden && getComputedStyle(document.querySelector(".conversation-input-area__input-stack")).display==="none"'));check('normal input inert',await read('document.querySelector(".conversation-input-area__input-stack").hasAttribute("inert")'));check('normal toolbar absent',await read('!document.querySelector(".wb-composer__toolbar")'));check('only one interactive permission dialog',await read('document.querySelectorAll(".conversation-intercept-card[role=dialog]").length===1'));await shot('bottom-approval');
|
||||
check('approval receives native focus',await read('!!document.activeElement.closest("[data-composer-approval]")'));await read('document.querySelector(".wb-composer textarea").focus()');check('hidden native editor cannot receive focus',await read('!document.querySelector(".conversation-input-area__input-stack").contains(document.activeElement)'));win.webContents.sendInputEvent({type:'keyDown',keyCode:'X'});win.webContents.sendInputEvent({type:'char',keyCode:'x'});win.webContents.sendInputEvent({type:'keyUp',keyCode:'X'});await pause(80);check('native typing cannot change hidden draft',(await read('document.querySelector(".wb-composer textarea").value'))==='PRESERVED_DRAFT');
|
||||
await read('document.querySelector(".conversation-intercept-card__option--reject").click()');await wait('document.querySelector("[data-composer-approval] [role=alert]")?.textContent.includes("QA approval submission failure")');check('failed approval stays in replacement',await read('document.querySelector(".conversation-input-area__input-stack").hidden && !document.querySelector(".wb-composer__toolbar")'));await shot('approval-failure');
|
||||
await read('document.querySelector(".conversation-intercept-card__option--reject").click()');await wait('!document.querySelector("[data-composer-approval]")');await settled();check('draft restored after denial',(await read('document.querySelector(".wb-composer textarea").value'))==='PRESERVED_DRAFT');check('normal toolbar restored',await read('!!document.querySelector(".wb-composer__toolbar")'));let absent=false;try{await fs.stat(path.join(workspace,'default-must-not-write.txt'))}catch(e){absent=e.code==='ENOENT'}check('default denied actual write',absent);await shot('draft-restored');
|
||||
stage='grant-first';scenario='grant';issued=0;await send('B03_GRANT_FIRST');await wait('!!document.querySelector("[data-composer-approval] [data-option-id=allow-always]")');await shot('session-grant');await read('document.querySelector("[data-option-id=allow-always]").click()');for(let i=0;issued<2&&i<500;i++)await pause(30);await settled();check('UI session grant executes command',(await fs.stat(path.join(workspace,'app-grant-repo/.git'))).isDirectory());
|
||||
stage='grant-next';issued=0;await read('window.__b03Approvals=0');await send('B03_GRANT_NEXT');for(let i=0;issued<2&&i<500;i++)await pause(30);check('grant next turn reaches completion',issued>=2);await settled();check('session grant prevents repeated approval',!(await read('window.__b03Approvals||0')));stage='cancel-failure';scenario='default';issued=0;await send('B03_CANCEL');await wait('!!document.querySelector("[data-composer-approval]")');await read('document.querySelector(".wb-composer__approval-stop").click()');await wait('document.querySelector("[data-composer-approval] [role=alert]")?.textContent.includes("QA cancellation failure")');check('failed cancel error visible in replacement',await read('document.querySelector(".conversation-input-area__input-stack").hidden'));await shot('cancel-failure');await read('document.querySelector(".wb-composer__approval-stop").click()');await settled();check('cancel retry restores normal input',await read('!document.querySelector(".conversation-input-area__input-stack").hidden && !!document.querySelector(".wb-composer__toolbar")'));await permission(true);
|
||||
}
|
||||
if(phase==='restart'){
|
||||
stage='grant-expired-after-restart';await permission(false);scenario='grant';issued=0;await send('B03_GRANT_RESTART');await wait('!!document.querySelector("[data-composer-approval] [data-option-id=allow-always]")');check('session grant expires after process restart',true);await shot('grant-reapproval-after-restart');await read('document.querySelector(".conversation-intercept-card__option--reject").click()');for(let i=0;issued<2&&i<500;i++)await pause(30);await settled();
|
||||
}
|
||||
check('zero renderer console errors',errors.length===0);await fs.writeFile(path.join(dir,phase+'-report.json'),JSON.stringify({codeSha:'adbbb3bd37f6043d10cbaa59d6c28ade6387a7f3',scope:'Unchanged production app + main/preload/renderer + real Windows SDK/CLI with deterministic local SSE; fresh data; actual UI permission and send',checks,requests:requestCount,errors},null,2));clearTimeout(timer);server.closeAllConnections();server.close();app.exit(0);
|
||||
})().catch(async e=>{console.error(stage,e);if(win)await shot('failure').catch(()=>{});await fs.writeFile(path.join(dir,phase+'-failure.json'),JSON.stringify({stage,message:String(e),checks,errors},null,2));server.closeAllConnections();server.close();app.exit(1)})
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 77 KiB |
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"codeSha": "adbbb3bd37f6043d10cbaa59d6c28ade6387a7f3",
|
||||
"scope": "Unchanged production app + main/preload/renderer + real Windows SDK/CLI with deterministic local SSE; fresh data; actual UI permission and send",
|
||||
"checks": [
|
||||
{
|
||||
"name": "restart restores saved full label",
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "full write executed",
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "full PowerShell executed",
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "no approval card under full",
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "persisted full permission",
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "session grant expires after process restart",
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "zero renderer console errors",
|
||||
"pass": true
|
||||
}
|
||||
],
|
||||
"requests": 5,
|
||||
"errors": []
|
||||
}
|
||||
@@ -0,0 +1,660 @@
|
||||
|
||||
> ycode@0.0.7 build
|
||||
> npm run typecheck && electron-vite build
|
||||
|
||||
|
||||
> ycode@0.0.7 typecheck
|
||||
> tsc --noEmit -p tsconfig.node.json && tsc --noEmit -p tsconfig.web.json
|
||||
|
||||
vite v8.3.4 building ssr environment for production...
|
||||
transforming...
|
||||
✓ 444 modules transformed.
|
||||
rendering chunks...
|
||||
out/main/index.mjs 1,599.48 kB
|
||||
|
||||
✓ built in 375ms
|
||||
vite v8.3.4 building ssr environment for production...
|
||||
transforming...
|
||||
✓ 2 modules transformed.
|
||||
rendering chunks...
|
||||
out/preload/index.cjs 15.89 kB
|
||||
|
||||
✓ built in 21ms
|
||||
vite v8.3.4 building client environment for production...
|
||||
transforming...
|
||||
✓ 3039 modules transformed.
|
||||
rendering chunks...
|
||||
out/renderer/settings.html 1.57 kB
|
||||
out/renderer/index.html 1.75 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-FVRG9O7E.js 438.21 kB
|
||||
out/renderer/assets/worker-portable-D1lwTqsk-Dg0RNmO0.js 456.22 kB
|
||||
out/renderer/assets/landing-hero-B6659kdy.png 629.28 kB
|
||||
out/renderer/assets/html.worker-BC4B-9NY-BDdNc3ca.js 756.63 kB
|
||||
out/renderer/assets/css.worker-D7wyZb8r-YRw1jg-F.js 1,086.92 kB
|
||||
out/renderer/assets/ts.worker-BsXRl7a--BbqraoNr.js 8,187.30 kB
|
||||
out/renderer/assets/ArtifactPierreDiff-CNAfnhAF.css 1.16 kB
|
||||
out/renderer/assets/GeneralSettingsPanel-CntDyB52.css 1.25 kB
|
||||
out/renderer/assets/AgentsSettingsPanel-R0teGDyD.css 2.56 kB
|
||||
out/renderer/assets/AboutHelpSettingsPanel-ksqGLObi.css 5.72 kB
|
||||
out/renderer/assets/updates-ui-COSnOGKS.css 6.84 kB
|
||||
out/renderer/assets/AppearanceSettingsPanel-DcaRECSa.css 8.03 kB
|
||||
out/renderer/assets/ShortcutsSettingsPanel-Bu_5_488.css 18.05 kB
|
||||
out/renderer/assets/MemorySettingsPanel-C3dtDAif.css 32.49 kB
|
||||
out/renderer/assets/ModelSettingsPanel-BjNmxQAH.css 88.98 kB
|
||||
out/renderer/assets/PersonalizationSettingsPanel-DnAyzaM6.css 98.77 kB
|
||||
out/renderer/assets/app-DH7L1ZF2.css 259.93 kB
|
||||
out/renderer/assets/index-Cj0yjvuz.css 2,685.07 kB
|
||||
out/renderer/assets/pie-WAS4IAKB-1a9lbjhh.js 0.11 kB
|
||||
out/renderer/assets/info-A6RAGUB7-Dsq8pPGK.js 0.11 kB
|
||||
out/renderer/assets/radar-RG4KPBEZ-BwNT2qWb.js 0.11 kB
|
||||
out/renderer/assets/packet-AYTQ26CC-C-iOIVQo.js 0.11 kB
|
||||
out/renderer/assets/cynefin-OW5HDTMX-CTYbUR58.js 0.11 kB
|
||||
out/renderer/assets/treemap-WGGIJYW6-CWek0LQD.js 0.11 kB
|
||||
out/renderer/assets/wardley-WFR3VGLG-BnrEXTnU.js 0.11 kB
|
||||
out/renderer/assets/gitGraph-4MIJSDKK-NHpEvzKf.js 0.12 kB
|
||||
out/renderer/assets/railroad-74A4TZTK-CyYHr3KR.js 0.12 kB
|
||||
out/renderer/assets/treeView-Q6P3EWNA-CzdWA6Mh.js 0.12 kB
|
||||
out/renderer/assets/railroad-peg-WCYAUIDC-DyA9P8dX.js 0.12 kB
|
||||
out/renderer/assets/architecture-7GRP2DOG-VyF0wzFW.js 0.12 kB
|
||||
out/renderer/assets/railroad-abnf-HS5TGJTU-DWOH6PDU.js 0.12 kB
|
||||
out/renderer/assets/railroad-ebnf-LZEXJU2U-B8jXqV-T.js 0.12 kB
|
||||
out/renderer/assets/eventmodeling-NTZA5JFV-Dmu4IHsI.js 0.12 kB
|
||||
out/renderer/assets/array-75Ih5Qg4.js 0.16 kB
|
||||
out/renderer/assets/channel-DtQOCUrd.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-Rs0gEc5_.js 0.59 kB
|
||||
out/renderer/assets/prism-json-DxLGXN1o.js 0.62 kB
|
||||
out/renderer/assets/codeowners-C7Y3CTAA-BmB2_gvY.js 0.75 kB
|
||||
out/renderer/assets/prism-clike-BcH_eOfE.js 0.89 kB
|
||||
out/renderer/assets/tsv-DVa1_Ovr-BeS2kE5e.js 0.94 kB
|
||||
out/renderer/assets/shellsession-C0HwRpr0-B630Ulnl.js 0.96 kB
|
||||
out/renderer/assets/javascript-DGySzfUB-CQaVVFGk.js 0.99 kB
|
||||
out/renderer/assets/settings-CauUETdq.js 1.01 kB
|
||||
out/renderer/assets/infoDiagram-27XIBGKW-CjoHj39W.js 1.09 kB
|
||||
out/renderer/assets/swimlanesDiagram-VR7AAH4N-CDVwE8hU.js 1.09 kB
|
||||
out/renderer/assets/html-derivative-D3Jld805-D0QQ5MTi.js 1.10 kB
|
||||
out/renderer/assets/prism-go-Cw8Jg9YT.js 1.11 kB
|
||||
out/renderer/assets/classDiagram-ZZMXUADV-BwWcIhgv.js 1.16 kB
|
||||
out/renderer/assets/classDiagram-v2-VYDZK3BY-CDfTno2N.js 1.16 kB
|
||||
out/renderer/assets/stateDiagram-v2-MP3YSRHH-FppKH3cZ.js 1.16 kB
|
||||
out/renderer/assets/qmldir-DIq06gp2-CFVtueeV.js 1.20 kB
|
||||
out/renderer/assets/git-rebase-CgwCWTNR-Cpss9r90.js 1.23 kB
|
||||
out/renderer/assets/chunk-POPQ4Y6H-BrtzJQqe.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-DKrQczXm.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/git-commit-DGtBy1vY-s2uHofP2.js 1.47 kB
|
||||
out/renderer/assets/AgentsSettingsPanel-CMYBwUKH.js 1.56 kB
|
||||
out/renderer/assets/xsl-DV28r3Jw-B8bWzO_h.js 1.59 kB
|
||||
out/renderer/assets/dotenv-DXc2fSbR-CUbEjgJq.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-DAUou2oc.js 1.71 kB
|
||||
out/renderer/assets/prism-css-Cmyw76Xa.js 1.73 kB
|
||||
out/renderer/assets/ini-DMSv7OY2-xgSkktY4.js 1.74 kB
|
||||
out/renderer/assets/rolldown-runtime-BJCASTsb-DKQFAHUF.js 1.78 kB
|
||||
out/renderer/assets/line-AFMfUFqz.js 1.89 kB
|
||||
out/renderer/assets/fortran-fixed-form-D91DiZLE-NxoUlVkB.js 1.91 kB
|
||||
out/renderer/assets/docker-B7J3eHK7-C3FNXPS_.js 1.96 kB
|
||||
out/renderer/assets/hxml-938TheZ7-pE5ojWPT.js 1.97 kB
|
||||
out/renderer/assets/desktop-BwI-o01e-Da9rFJOd.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-CLkRQ9Hf.js 2.40 kB
|
||||
out/renderer/assets/prism-kotlin-Bc2NQYRR.js 2.43 kB
|
||||
out/renderer/assets/jssm-CIisorE2-ggX0kbSA.js 2.44 kB
|
||||
out/renderer/assets/prism-python-CTkfasgb.js 2.48 kB
|
||||
out/renderer/assets/reg-mzCtpvUf-BHC3bGU6.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-CZIpsKU0.js 2.61 kB
|
||||
out/renderer/assets/edge-DcEd3r9D-ZJX3cnY_.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-DgJJp7nh.js 2.78 kB
|
||||
out/renderer/assets/railroadDiagram-O6MQD6OU-CXLwcpeu.js 2.78 kB
|
||||
out/renderer/assets/diff-lAxbRYdS--5gtlmD4.js 2.79 kB
|
||||
out/renderer/assets/hy-BKymZdC0-4uNvYh3y.js 2.86 kB
|
||||
out/renderer/assets/dockerfile-CnkhFuxG-CfXHMZr-.js 3.01 kB
|
||||
out/renderer/assets/openscad-BRTETpP_-BThzc9qL.js 3.03 kB
|
||||
out/renderer/assets/pascaligo-DI1dd1Zd-D23AoFdQ.js 3.03 kB
|
||||
out/renderer/assets/log-Cn1ZE6kb-BE4srnlV.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-C7ph_xMt.js 3.12 kB
|
||||
out/renderer/assets/cairo-D_LzMZ4I-C21twps2.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-DsDdtWdB.js 3.20 kB
|
||||
out/renderer/assets/jsonl-Cn_fzNA8-cIG9lf61.js 3.21 kB
|
||||
out/renderer/assets/json-CKKhFIOr-DuiQFrCF.js 3.29 kB
|
||||
out/renderer/assets/mips-Df5bwPtM-DJn7b529.js 3.29 kB
|
||||
out/renderer/assets/jsonc-Bf3Xcgeq-BGBJ2TDY.js 3.31 kB
|
||||
out/renderer/assets/logo-BxqPaaID-DK9gUnx4.js 3.33 kB
|
||||
out/renderer/assets/abnfDiagram-VCTEODGH-84GndbAp.js 3.36 kB
|
||||
out/renderer/assets/go-BejFoqvR-BnGoIlsY.js 3.42 kB
|
||||
out/renderer/assets/po-DI6EG-tz-DIkePE8T.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-Ci88mndw.js 3.45 kB
|
||||
out/renderer/assets/mipsasm-U3SQfJCQ-kat_Vj1M.js 3.46 kB
|
||||
out/renderer/assets/sophia-foSZ3xPI-DGYIHURw.js 3.47 kB
|
||||
out/renderer/assets/tasl-C74Cvwdf-se1Ptgso.js 3.49 kB
|
||||
out/renderer/assets/genie-CjS3m_gh-DHydh9_z.js 3.56 kB
|
||||
out/renderer/assets/prism-swift-xplGsQ1n.js 3.56 kB
|
||||
out/renderer/assets/vala-DMgevQbf-ByJQiTkp.js 3.57 kB
|
||||
out/renderer/assets/pegDiagram-XKGWAZYB-CRHTDhUd.js 3.59 kB
|
||||
out/renderer/assets/rel-D6dNeDZv-CUAJzmkw.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-D_e5QUAT.js 3.65 kB
|
||||
out/renderer/assets/ebnfDiagram-PWID7BFC-Dz_QBkPG.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-DiRuAudw.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-BCOQigl1.js 3.81 kB
|
||||
out/renderer/assets/splunk-BdqSfgpd-BtOEh0Mo.js 3.81 kB
|
||||
out/renderer/assets/jsonnet-Bn71vRY8-QjPNMWdY.js 3.82 kB
|
||||
out/renderer/assets/ssh-config-BO51LXox-DkFt_ueS.js 3.82 kB
|
||||
out/renderer/assets/bicep-DujF3y-4-DHww3ZLF.js 3.87 kB
|
||||
out/renderer/assets/narrat-DdgkgBr0-CSyxDqta.js 3.87 kB
|
||||
out/renderer/assets/redis-Bo427DT4-DBDF4ZWx.js 3.88 kB
|
||||
out/renderer/assets/turtle-DAmmiOda-C48PN72o.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-BG7UwPdX.js 4.11 kB
|
||||
out/renderer/assets/zenscript-XbBI4c9W-C-aTQo6e.js 4.12 kB
|
||||
out/renderer/assets/glsl-CZF-bvQV-UaBdSZy0.js 4.14 kB
|
||||
out/renderer/assets/shell-DGp7WuK3-X00pamiI.js 4.15 kB
|
||||
out/renderer/assets/gn-DJxfXStl-BD_k0CWf.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-DLkP_pAB.js 4.27 kB
|
||||
out/renderer/assets/AppearanceSettingsPanel-B_352Jrg.js 4.28 kB
|
||||
out/renderer/assets/hurl-CDXCvJNd-Xd5k76nE.js 4.28 kB
|
||||
out/renderer/assets/cypher-CjfQI0Y9-9gjOyi6P.js 4.33 kB
|
||||
out/renderer/assets/pascal-CLPA94yO-C11lM2uy.js 4.35 kB
|
||||
out/renderer/assets/powershell-CaPzBwIT-C9KgMPOP.js 4.50 kB
|
||||
out/renderer/assets/tcl-D-NiFh9X-CYwv4uzi.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-DSHWRdSZ.js 4.72 kB
|
||||
out/renderer/assets/nextflow-DVTlkzu9-Cis-JUmb.js 4.75 kB
|
||||
out/renderer/assets/http-DhxVjYFh-CjwVOaui.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-DygHL4ZA.js 4.87 kB
|
||||
out/renderer/assets/prism-ruby-PgHh3fQm.js 4.91 kB
|
||||
out/renderer/assets/fennel-COJTUo2O-DYh8-dep.js 4.97 kB
|
||||
out/renderer/assets/bibtex-yEKRWsaj-xHthw1sC.js 5.00 kB
|
||||
out/renderer/assets/coffee-CcgZJF1B-DkN4xoBX.js 5.04 kB
|
||||
out/renderer/assets/llvm-DiFwU398-BQjCVu39.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-yP3bMkfO.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-B8x_JL1P.js 5.54 kB
|
||||
out/renderer/assets/restructuredtext-D2p7PcFG-DDHAm_JI.js 5.55 kB
|
||||
out/renderer/assets/dax-CmrIxjmL-CDTyHmZ_.js 5.56 kB
|
||||
out/renderer/assets/gdresource-4lq4eh4q-CjhvlVte.js 5.56 kB
|
||||
out/renderer/assets/qml-D6gd64uC-_ykXVPoZ.js 5.57 kB
|
||||
out/renderer/assets/bicep-wTwvD1CI-C568hcwN.js 5.58 kB
|
||||
out/renderer/assets/cssMode-Z-o80aSY-Co8Z3bSk.js 5.59 kB
|
||||
out/renderer/assets/awk-DTjcVAOD-BmfaVU4m.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-C5vNmx0q.js 5.81 kB
|
||||
out/renderer/assets/swift-C3A42nmX-BBVToPkN.js 5.83 kB
|
||||
out/renderer/assets/xml-bIkPj5aH-Bx1v5u6-.js 5.89 kB
|
||||
out/renderer/assets/ecl-CYzojQ6a-C8m0_osY.js 5.91 kB
|
||||
out/renderer/assets/jinja-Dl-Ji_JA-BBL5sTd0.js 5.92 kB
|
||||
out/renderer/assets/lean-Cu10prRO-BUTVAAdc.js 6.03 kB
|
||||
out/renderer/assets/yaml-GEMDST6R-D-0AGe4F.js 6.09 kB
|
||||
out/renderer/assets/moonbit-B8-g2u5v-CGBFUznC.js 6.10 kB
|
||||
out/renderer/assets/powerquery-tKWDTKOo-CejxekA_.js 6.11 kB
|
||||
out/renderer/assets/SourceCodePreview-DiJZfFca.js 6.11 kB
|
||||
out/renderer/assets/python-CHafhQyI-DmJIfgbV.js 6.14 kB
|
||||
out/renderer/assets/shaderlab-Df7nOKvI-0G488FSx.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-D5ytx6Ln.js 6.29 kB
|
||||
out/renderer/assets/htmlMode-BDZbYlMj-Dv5sUJ1A.js 6.40 kB
|
||||
out/renderer/assets/red-CYaKK_PD-iiAMl8iL.js 6.45 kB
|
||||
out/renderer/assets/min-dark-DGPfDRqJ-gZu6HtcU.js 6.48 kB
|
||||
out/renderer/assets/pug-EKWpNZSi-oQ708bsr.js 6.51 kB
|
||||
out/renderer/assets/prisma-CdZyz3OC-ChFCtYaa.js 6.53 kB
|
||||
out/renderer/assets/gdshader-ryZhEIxg-DpcQqwXn.js 6.55 kB
|
||||
out/renderer/assets/ara-_lrJyEFe-qigo-wGx.js 6.56 kB
|
||||
out/renderer/assets/clojure-WSq30mUj-Bswhoa1y.js 6.61 kB
|
||||
out/renderer/assets/toml-DPP887_3-aOuHoLTy.js 6.62 kB
|
||||
out/renderer/assets/postcss-CcIp2ENG-DpmxBCXW.js 6.64 kB
|
||||
out/renderer/assets/verilog-bragEGMk-CemzLugw.js 6.64 kB
|
||||
out/renderer/assets/solarized-light-BIMszn7B-vPMkTTwP.js 6.68 kB
|
||||
out/renderer/assets/cypher-COYrq2Yy-BtVrfsLp.js 6.75 kB
|
||||
out/renderer/assets/arc-LpCwTDer.js 6.75 kB
|
||||
out/renderer/assets/proto-CQIfhs_g-Deqofbl3.js 6.77 kB
|
||||
out/renderer/assets/smalltalk-BLGdLDJX-BKGgemER.js 6.79 kB
|
||||
out/renderer/assets/vb-D1Cw85Ss-BSz-V9M4.js 6.86 kB
|
||||
out/renderer/assets/talonscript-DA9pg7Tj-CPXKQ95R.js 6.96 kB
|
||||
out/renderer/assets/r-Bb2Mu7Fo-Dq0URONw.js 7.00 kB
|
||||
out/renderer/assets/solarized-dark-D_I-4EGa-BZbeAUhW.js 7.04 kB
|
||||
out/renderer/assets/diagram-Z3DM3KII-BZGyOvLJ.js 7.08 kB
|
||||
out/renderer/assets/riscv-CQHqXr1Z-BFlZFId-.js 7.11 kB
|
||||
out/renderer/assets/soy-DybHqX1A-DOhErZPj.js 7.15 kB
|
||||
out/renderer/assets/min-light-BF0EjVgr-DvViuJW_.js 7.16 kB
|
||||
out/renderer/assets/scheme-Dn0tgEWN-BK64z0tZ.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-B3FZWMVz.js 7.48 kB
|
||||
out/renderer/assets/mdx-Bdu4uO-C-BrzgNjCw.js 7.58 kB
|
||||
out/renderer/assets/qss-DkzwWM0J-04JPp7d-.js 7.67 kB
|
||||
out/renderer/assets/html-DKbmsqz6-Cnkf6ew3.js 7.69 kB
|
||||
out/renderer/assets/systemd-CS6mVasZ-HbzlQlDs.js 8.07 kB
|
||||
out/renderer/assets/monokai-CYqILLdj-CEXuJ8HO.js 8.08 kB
|
||||
out/renderer/assets/twig-r8vgPZrm-D2l24YwI.js 8.18 kB
|
||||
out/renderer/assets/updates-ui-BoiWSsup.js 8.22 kB
|
||||
out/renderer/assets/wgsl-D_5Qxf6T-D508aVGZ.js 8.27 kB
|
||||
out/renderer/assets/sdbl-BXfz6d3_-C4Qk7OPN.js 8.42 kB
|
||||
out/renderer/assets/regexp-Dv0OUts_-BqK6b4KR.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-frBdohcC.js 8.71 kB
|
||||
out/renderer/assets/vue-html-DvuHo2mm-b7I-opwf.js 8.71 kB
|
||||
out/renderer/assets/haml-CIYwkycC-3fSMp7m2.js 8.81 kB
|
||||
out/renderer/assets/scss-CLoW-2dr-BBC_GO_6.js 8.86 kB
|
||||
out/renderer/assets/dart-CBkkDIWs-ezKLFP5s.js 8.94 kB
|
||||
out/renderer/assets/horizon-CELVL8Ba-x0NmpRb6.js 8.97 kB
|
||||
out/renderer/assets/horizon-bright-DBDyMeUQ-Bhh-QDk3.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-DaQVAww0.js 9.18 kB
|
||||
out/renderer/assets/andromeeda--j5Bq-48-DxyWS_fJ.js 9.21 kB
|
||||
out/renderer/assets/dark-plus-FAPM6M6c-DKexDF--.js 9.29 kB
|
||||
out/renderer/assets/sas-BQIEUTPQ-Bwx-ZPYU.js 9.31 kB
|
||||
out/renderer/assets/slack-dark-nDxLkSCC-C5pzIEPN.js 9.31 kB
|
||||
out/renderer/assets/perl-Bec3eWyr-CDmSu3_s.js 9.32 kB
|
||||
out/renderer/assets/plastic-DY_h9Vzh-CZzPFkTC.js 9.49 kB
|
||||
out/renderer/assets/sass-Ysv8HTNa-CHNQIGaT.js 9.49 kB
|
||||
out/renderer/assets/st-BrgXZ-Ag-BUs-RRgp.js 9.58 kB
|
||||
out/renderer/assets/typst-Co5rZla4-COemceoz.js 9.61 kB
|
||||
out/renderer/assets/slack-ochin-7zJWY-K--C7KFpXik.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-BNek_9Kq.js 9.95 kB
|
||||
out/renderer/assets/sql-DviNlDJO-CwV6bDIP.js 9.97 kB
|
||||
out/renderer/assets/kotlin-DIw6ua6F-CdVnL0aF.js 10.01 kB
|
||||
out/renderer/assets/cmake-CyNDuJo8-2Hk4zQCd.js 10.07 kB
|
||||
out/renderer/assets/light-plus-DkScKIB5-e8Q5AKjf.js 10.14 kB
|
||||
out/renderer/assets/hcl-DoJdlYjN-DdpM5wFm.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-C4n-y8pc.js 10.58 kB
|
||||
out/renderer/assets/tex-gcnXexI3-BUpeblVA.js 10.60 kB
|
||||
out/renderer/assets/php-Bn8AF0uj-CBbpr2vs.js 10.62 kB
|
||||
out/renderer/assets/nextflow-groovy-D4ZyOBoZ-C7jziUwg.js 10.63 kB
|
||||
out/renderer/assets/dream-maker-5oXa1Z51-CLRrQkBL.js 10.67 kB
|
||||
out/renderer/assets/ts-tags-xeTAUNHG-CG_gr3En.js 10.70 kB
|
||||
out/renderer/assets/raku-Bfr41qeN-C7t9XlCj.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-Cu7vbJZs.js 10.97 kB
|
||||
out/renderer/assets/diagram-UQ7AKVKN-CjyZsemm.js 11.05 kB
|
||||
out/renderer/assets/elm-Dl1XrIiD-CwXBAFKd.js 11.18 kB
|
||||
out/renderer/assets/just-He7qscmV-Bkq-0zku.js 11.19 kB
|
||||
out/renderer/assets/redshift-Djb4PK3z-9Ar4PFWD.js 11.35 kB
|
||||
out/renderer/assets/github-light-B_J7N1HZ-DWSXFnsf.js 11.38 kB
|
||||
out/renderer/assets/ruby-CxOCB7_P-BzsjPJ6Z.js 11.48 kB
|
||||
out/renderer/assets/prolog-DAqMMM08-BFKdnH0S.js 11.56 kB
|
||||
out/renderer/assets/terraform-BW8B2WXV-zeRjs0zr.js 11.59 kB
|
||||
out/renderer/assets/github-dark-BgqEY2WG-C9QbkZU3.js 11.60 kB
|
||||
out/renderer/assets/puppet-CaR8DEdW-Biai9WKX.js 11.65 kB
|
||||
out/renderer/assets/pkl-DrXR3Dxy-Bno7kqPT.js 11.67 kB
|
||||
out/renderer/assets/laserwave-Clkc4Pj8-DOjuqF9n.js 11.69 kB
|
||||
out/renderer/assets/pieDiagram-E7YTZNPT-CDo9kO0D.js 11.95 kB
|
||||
out/renderer/assets/rst-BJFdabDk-Cv-fSo2B.js 12.04 kB
|
||||
out/renderer/assets/linear-WS155L0r.js 12.11 kB
|
||||
out/renderer/assets/wasm-DYwNZ-r4-BrA6oOvM.js 12.21 kB
|
||||
out/renderer/assets/hjson-CmvCiVhY-BdH9CbZ2.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-MC-VEvxc.js 12.52 kB
|
||||
out/renderer/assets/apache-BUbWdjM2-2Zu7IlVl.js 12.66 kB
|
||||
out/renderer/assets/vesper-B5lCMuIY-CXGQHRuW.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-CEJzP2ue.js 13.09 kB
|
||||
out/renderer/assets/fish-CaZR_ofm-BcO_q5kQ.js 13.24 kB
|
||||
out/renderer/assets/elixir-Lipcswxh-DnZCznfr.js 13.27 kB
|
||||
out/renderer/assets/v-wnWoBHkK-CzCOTyIp.js 13.41 kB
|
||||
out/renderer/assets/AboutHelpSettingsPanel-Ui_VOvh7.js 13.48 kB
|
||||
out/renderer/assets/vitesse-light-DQXFiRFx-Ct7fN8pJ.js 13.81 kB
|
||||
out/renderer/assets/aurora-x-9vUYYjHV-CImifmUW.js 13.85 kB
|
||||
out/renderer/assets/vitesse-black-cwK5rWgD-BGrq81WC.js 13.87 kB
|
||||
out/renderer/assets/vitesse-dark-CsfgW0oH-Dx8cqxrm.js 13.96 kB
|
||||
out/renderer/assets/ShortcutsSettingsPanel-KgJeI7QZ.js 14.15 kB
|
||||
out/renderer/assets/pug-D0UckVoV-BTWU19Nk.js 14.16 kB
|
||||
out/renderer/assets/synthwave-84-LX1B8mRG-yuUErnSx.js 14.23 kB
|
||||
out/renderer/assets/github-light-default-BRmIzqWc-B3gMi7zW.js 14.36 kB
|
||||
out/renderer/assets/clarity-AxkJPY5c-DfVHSVIk.js 14.48 kB
|
||||
out/renderer/assets/github-light-high-contrast-BUKIZOxn-DL0r2b0z.js 14.49 kB
|
||||
out/renderer/assets/github-dark-dimmed-DoIdqTey-CDc6YqEM.js 14.64 kB
|
||||
out/renderer/assets/github-dark-default-CwWjzI40-_0bgyJYv.js 14.64 kB
|
||||
out/renderer/assets/chunk-PWAF6VOD-BIFvN59P.js 14.76 kB
|
||||
out/renderer/assets/github-dark-high-contrast-bFLNMLvK-BUp3HmXY.js 14.80 kB
|
||||
out/renderer/assets/diagram-S7CK7UJ4-DONAXBsJ.js 14.98 kB
|
||||
out/renderer/assets/gnuplot-Dw3FRha5-D6o75ylb.js 14.98 kB
|
||||
out/renderer/assets/rust-C0Ih6nmc-Bm01RMLz.js 15.27 kB
|
||||
out/renderer/assets/actionscript-3-O8jnLcvn-C7OtofMN.js 15.41 kB
|
||||
out/renderer/assets/luau-BzxGbjcn-aQpsBeQB.js 15.64 kB
|
||||
out/renderer/assets/nix-zl191KBb-CxSq6jsB.js 15.85 kB
|
||||
out/renderer/assets/lua-BwTLfNCK-IuSxl8fO.js 16.04 kB
|
||||
out/renderer/assets/abap-FvPUHv8B-BVQp86jh.js 16.05 kB
|
||||
out/renderer/assets/solidity-96fhzG-Q-CZEni-ZB.js 16.28 kB
|
||||
out/renderer/assets/matlab-8ZQqHKQX-g_ODc8QU.js 16.29 kB
|
||||
out/renderer/assets/cue-eHSfcyUV-BO0bCEDm.js 16.40 kB
|
||||
out/renderer/assets/kusto-D8vBBISG-C0y2Wtyy.js 16.45 kB
|
||||
out/renderer/assets/powerquery-B7BjLMcF-BkVSWPtX.js 16.49 kB
|
||||
out/renderer/assets/elixir-B1NaQxrO-Ba6X-FuW.js 16.50 kB
|
||||
out/renderer/assets/react-DrereneL.js 16.50 kB
|
||||
out/renderer/assets/odin-B-YqhW9I-B-ZI05Ll.js 16.71 kB
|
||||
out/renderer/assets/solidity-Dpt2BLAA-BD_YSA0r.js 16.98 kB
|
||||
out/renderer/assets/bird2-BMkLvc4r-CyoW3El7.js 17.17 kB
|
||||
out/renderer/assets/kanagawa-wave-CM_o6oKV-VzWuxPSA.js 17.32 kB
|
||||
out/renderer/assets/kanagawa-lotus-Cj3XDpoG-cmeMwVaD.js 17.32 kB
|
||||
out/renderer/assets/kanagawa-dragon-D_NPnIy_-Cyd8MANv.js 17.33 kB
|
||||
out/renderer/assets/cynefinDiagram-5FMLGOSQ-BK5-wphO.js 17.61 kB
|
||||
out/renderer/assets/stateDiagram-D77RDMKH-hT0_t6tj.js 18.11 kB
|
||||
out/renderer/assets/chunk-L3NEJ4N5-DDp_gyKk.js 18.16 kB
|
||||
out/renderer/assets/liquid-D_7zu7XR-BZ3z6-Mj.js 18.46 kB
|
||||
out/renderer/assets/svelte-DUGqPubT-CAfIEh4G.js 18.60 kB
|
||||
out/renderer/assets/graphql-ObxcfEHH-9pUo2yjR.js 18.65 kB
|
||||
out/renderer/assets/jsonMode-DdQpkp6D-BpRyp_WL.js 18.79 kB
|
||||
out/renderer/assets/material-theme-q28j4V_0-s4HtqlFv.js 18.81 kB
|
||||
out/renderer/assets/material-theme-ocean-DAvlEnSm-Cyw7qD-l.js 18.83 kB
|
||||
out/renderer/assets/material-theme-darker-CHEuMVX9-D-hz3EEt.js 18.83 kB
|
||||
out/renderer/assets/material-theme-lighter-DY4T1_JG-C0HwKluR.js 18.84 kB
|
||||
out/renderer/assets/material-theme-palenight-CqDFvQ-v-RoTowTME.js 18.84 kB
|
||||
out/renderer/assets/gherkin-BcjDDslM-BdnbjalD.js 19.20 kB
|
||||
out/renderer/assets/gdscript-CekKc1U_-DVmAmHvE.js 19.21 kB
|
||||
out/renderer/assets/groovy-DH3arekX-StnUgJL0.js 19.38 kB
|
||||
out/renderer/assets/mdc-D-U85KZE-DPbAVRTg.js 19.85 kB
|
||||
out/renderer/assets/diagram-VSXAHHWV-DSqzbMQw.js 20.01 kB
|
||||
out/renderer/assets/move-CmExnPjU-DPj_eIaE.js 20.22 kB
|
||||
out/renderer/assets/ayu-dark-BeByMiYw-CS3MEELg.js 20.27 kB
|
||||
out/renderer/assets/ayu-mirage-C1jJ6Jfs-CnA8kJ7r.js 20.28 kB
|
||||
out/renderer/assets/ayu-light-DmTZeN54-CDULCKqM.js 20.35 kB
|
||||
out/renderer/assets/glimmer-js-D9ZnrcNN-BS431Ogg.js 20.44 kB
|
||||
out/renderer/assets/glimmer-ts-DuhFj6qR-CsFesiaT.js 20.44 kB
|
||||
out/renderer/assets/viml-DPVJ_KYe-De3CdqgJ.js 20.56 kB
|
||||
out/renderer/assets/nushell-Cd8Dwa1M-Dhf9XkYz.js 20.62 kB
|
||||
out/renderer/assets/snazzy-light-B8znOqT6-B1FX3-IF.js 20.97 kB
|
||||
out/renderer/assets/dagre-GXQ25YYZ-DDVr57nj.js 21.01 kB
|
||||
out/renderer/assets/dracula-DeMffiYO-Bl4juROY.js 21.26 kB
|
||||
out/renderer/assets/dracula-soft-BnfvpcDv-CYsUeSum.js 21.27 kB
|
||||
out/renderer/assets/twig-7zjsCqYg-CMujKsZl.js 21.44 kB
|
||||
out/renderer/assets/freemarker2-enkimFXA-0bWMkoTL.js 21.73 kB
|
||||
out/renderer/assets/PersonalizationSettingsPanel-B06BA6F_.js 21.87 kB
|
||||
out/renderer/assets/rose-pine-CEVQiaW0-DaA_4NNK.js 21.94 kB
|
||||
out/renderer/assets/rose-pine-moon-B9bum7Ik-B6_AhIsD.js 21.96 kB
|
||||
out/renderer/assets/rose-pine-dawn-2Q5fMoJp-DxMkAwKM.js 21.96 kB
|
||||
out/renderer/assets/powershell-ycAdP1r9-B7r4Hnhz.js 22.11 kB
|
||||
out/renderer/assets/common-lisp-DcFHcTKh-CWH5diwh.js 22.81 kB
|
||||
out/renderer/assets/gruvbox-dark-hard-gOzMLqif-DDlcfu4q.js 22.83 kB
|
||||
out/renderer/assets/gruvbox-dark-soft-CKvURktN-C6MJezBg.js 22.83 kB
|
||||
out/renderer/assets/gruvbox-light-hard-CMa_c48J-BUQ67Msp.js 22.84 kB
|
||||
out/renderer/assets/gruvbox-light-soft-yfAGJYsX-DNM2qqWB.js 22.84 kB
|
||||
out/renderer/assets/gruvbox-dark-medium-BQSVGwWb-qh8C4DPZ.js 22.84 kB
|
||||
out/renderer/assets/gruvbox-light-medium-B9S5UNr1-DZxV_o-P.js 22.84 kB
|
||||
out/renderer/assets/nim-CD961Jl3-CuyTrDpQ.js 22.91 kB
|
||||
out/renderer/assets/cadence-C2JmJjDr-B-b63Epg.js 23.87 kB
|
||||
out/renderer/assets/sql-C_oMiPb0-CRnSOxMo.js 23.87 kB
|
||||
out/renderer/assets/wit-CXpQol8Q-D2NEDOhy.js 24.11 kB
|
||||
out/renderer/assets/templ-gFcHJbF7-BqIwRUQe.js 24.38 kB
|
||||
out/renderer/assets/astro-kV3HjkbP-CH6o6jKA.js 24.46 kB
|
||||
out/renderer/assets/vhdl-Ci4REirV-D-qSzcJD.js 24.46 kB
|
||||
out/renderer/assets/purescript-DCsDAdnX-DsynrkKe.js 24.97 kB
|
||||
out/renderer/assets/vue-Cuk7Vimg-CFbFXIr8.js 25.25 kB
|
||||
out/renderer/assets/surrealql-GFjNBdcm-Vm68TOTE.js 25.34 kB
|
||||
out/renderer/assets/one-light-CMfGrl_P-B-1jUQM9.js 25.49 kB
|
||||
out/renderer/assets/night-owl-light-CAEa42tO-TPCLv7z5.js 26.10 kB
|
||||
out/renderer/assets/system-verilog-D_bVVpLE-C_dvOlr3.js 26.41 kB
|
||||
out/renderer/assets/angular-html-BrLPO2Fv-DJgz5E5d.js 26.48 kB
|
||||
out/renderer/assets/typespec-D5WYs8C4-AaOHagqW.js 26.72 kB
|
||||
out/renderer/assets/nord-DlCAGdjr-Div2jUYm.js 26.91 kB
|
||||
out/renderer/assets/codeql-DidIlXer-D6RBJOzg.js 27.08 kB
|
||||
out/renderer/assets/scss-BhK8Ovpn-DfDLQi2C.js 27.52 kB
|
||||
out/renderer/assets/coffee-DrMWXxy6-BoavQsuh.js 27.68 kB
|
||||
out/renderer/assets/java-DaupjRFz-zQd9RZAc.js 27.69 kB
|
||||
out/renderer/assets/razor-B2hRAVmz-Dj7TOgY5.js 27.72 kB
|
||||
out/renderer/assets/apl-C42PBett-BNW4FTmO.js 27.87 kB
|
||||
out/renderer/assets/chunk-SVP7TREG-CPHw5aFk.js 28.38 kB
|
||||
out/renderer/assets/fsharp-BHFgIxsY-CvR6tsY8.js 28.48 kB
|
||||
out/renderer/assets/marko-DXKHPFnH-C0z2-ucz.js 28.74 kB
|
||||
out/renderer/assets/GeneralSettingsPanel-CA6yOnsk.js 29.10 kB
|
||||
out/renderer/assets/night-owl-DegwdXaM-6ZGfBB7K.js 29.11 kB
|
||||
out/renderer/assets/c3-BOs4FlGA-BuhFXrRY.js 29.17 kB
|
||||
out/renderer/assets/MemorySettingsPanel-cqwWfj-O.js 29.75 kB
|
||||
out/renderer/assets/crystal-DlzoxO28-BWa_t1Io.js 29.84 kB
|
||||
out/renderer/assets/applescript-ij24h7OO-_xHQcvud.js 29.87 kB
|
||||
out/renderer/assets/tsMode-SiG-Sp2b-D8plNSSs.js 30.55 kB
|
||||
out/renderer/assets/pierre-dark-Daa2n9wr-D7rla9B_.js 30.74 kB
|
||||
out/renderer/assets/pierre-light-D_hZXvUj-DJnIOKLO.js 30.75 kB
|
||||
out/renderer/assets/pierre-dark-soft-BhNM3pgh-Dp_VeHWv.js 30.76 kB
|
||||
out/renderer/assets/pierre-light-soft-BVrSv6ZG-C6Na39F-.js 30.76 kB
|
||||
out/renderer/assets/ishikawaDiagram-5VMMS53U-DDYICLe4.js 30.78 kB
|
||||
out/renderer/assets/pierre-dark-tritanopia-CGKuoAZi-C0HpbU3l.js 30.78 kB
|
||||
out/renderer/assets/pierre-light-tritanopia-BiDEaWaH-wWduIsi3.js 30.78 kB
|
||||
out/renderer/assets/pierre-dark-protanopia-deuteranopia-Cs1lz9lE-enlgPsHw.js 30.82 kB
|
||||
out/renderer/assets/pierre-light-protanopia-deuteranopia-BM0RLBB_-Dz5iBHkO.js 30.82 kB
|
||||
out/renderer/assets/stylus-ZCryC73G-urFW3_yk.js 31.29 kB
|
||||
out/renderer/assets/diagram-VX7I27RA-C2Mi8cp0.js 31.44 kB
|
||||
out/renderer/assets/scala-BBsC3Oz3-VCjyobQG.js 31.48 kB
|
||||
out/renderer/assets/mermaid-D6CQfUGU-C6DHNxVz.js 33.37 kB
|
||||
out/renderer/assets/poimandres-EIt_jotH-DHKFQj5Q.js 33.69 kB
|
||||
out/renderer/assets/kanban-definition-UXKFOSKX-BeSTkz7K.js 33.91 kB
|
||||
out/renderer/assets/one-dark-pro-DR9QpZM3-BA4d4lw2.js 33.98 kB
|
||||
out/renderer/assets/mermaid-parser.core-CstzWfPU.js 34.66 kB
|
||||
out/renderer/assets/haxe-BWT5wSyZ-BuUsQb-h.js 35.38 kB
|
||||
out/renderer/assets/nginx-DhtViCEk-C18zABFg.js 35.58 kB
|
||||
out/renderer/assets/houston-BdS5A_yD-NUige_z1.js 35.61 kB
|
||||
out/renderer/assets/tokyo-night-BS1_DFu7-CYsPn2J-.js 35.86 kB
|
||||
out/renderer/assets/erlang-Dd62d0xZ-DHVWwcKa.js 37.71 kB
|
||||
out/renderer/assets/rough.esm-BX5QqLti.js 38.33 kB
|
||||
out/renderer/assets/mindmap-definition-YA3MSWOX-CefIRU5Q.js 38.59 kB
|
||||
out/renderer/assets/cobol-D7RZfOK--CEk2iYO9.js 39.37 kB
|
||||
out/renderer/assets/journeyDiagram-3NMN7TZE-BrEjlWwa.js 40.13 kB
|
||||
out/renderer/assets/julia-ZzkUXm0W-BIm_zTAN.js 40.32 kB
|
||||
out/renderer/assets/lspLanguageFeatures-DK9zifhE-DeEqLmGO.js 40.76 kB
|
||||
out/renderer/assets/asm-DYVIzeEk-Byg5xzam.js 40.91 kB
|
||||
out/renderer/assets/haskell-Ba6HbLj8-D0OYaIy8.js 41.78 kB
|
||||
out/renderer/assets/sankeyDiagram-P5KCCOFB-DQyGY2bs.js 41.83 kB
|
||||
out/renderer/assets/shellscript-B69gKcss-49Zm6IyC.js 41.97 kB
|
||||
out/renderer/assets/wardleyDiagram-VM6X3IG4-DlxcR-iD.js 42.40 kB
|
||||
out/renderer/assets/perl-Dv6Cq_FS-DIORmO5G.js 43.55 kB
|
||||
out/renderer/assets/pierre-dark-vibrant-BMsyYliQ-84Eeh-Uj.js 44.96 kB
|
||||
out/renderer/assets/pierre-light-vibrant-CWzM4Pa_-QZvTkTJe.js 44.97 kB
|
||||
out/renderer/assets/ruby-DWcdJvcx-q0K84ieK.js 46.50 kB
|
||||
out/renderer/assets/go-BOpYl7fu-BiT4MB-v.js 47.02 kB
|
||||
out/renderer/assets/apex-B48ZHHzN-BBt8sSNQ.js 47.18 kB
|
||||
out/renderer/assets/catppuccin-mocha-cPsH7Lup-SVLZehhk.js 47.46 kB
|
||||
out/renderer/assets/catppuccin-latte-DcEecI7n-jo2cPJyK.js 47.46 kB
|
||||
out/renderer/assets/catppuccin-frappe-BdOW2tdI-BI0Hc9cS.js 47.46 kB
|
||||
out/renderer/assets/catppuccin-macchiato-Bvz_yAZY-DWewRa4S.js 47.47 kB
|
||||
out/renderer/assets/ada-BT0j8ine-CLTLBE8n.js 48.28 kB
|
||||
out/renderer/assets/d-B1HbH29p-Bi6t8Ck6.js 49.10 kB
|
||||
out/renderer/assets/css-NFwnoVns-BvwuZkcY.js 49.49 kB
|
||||
out/renderer/assets/imba-C-oGt11l-CqKI0OVw.js 50.13 kB
|
||||
out/renderer/assets/requirementDiagram-BXWQKSXE-02T1DPau.js 51.39 kB
|
||||
out/renderer/assets/erDiagram-RLTQ6QDP-CJPuRub_.js 52.41 kB
|
||||
out/renderer/assets/browserify-C9uP_nIr.js 52.80 kB
|
||||
out/renderer/assets/gitGraphDiagram-WWUBYQGX-DzZwQ1ZK.js 53.82 kB
|
||||
out/renderer/assets/everforest-dark-gCM8XhEI-DzRrg06U.js 53.94 kB
|
||||
out/renderer/assets/everforest-light-DhK35DkL-BEDtvHw1.js 53.95 kB
|
||||
out/renderer/assets/timeline-definition-24CTP7MA-CkkqSZjt.js 54.31 kB
|
||||
out/renderer/assets/wikitext-CQNrXTmv-DJ18wIlO.js 56.09 kB
|
||||
out/renderer/assets/stata-BUONSdsT-BPnapjPC.js 57.23 kB
|
||||
out/renderer/assets/quadrantDiagram-AXDQQJYC-Bzh51MK6.js 58.21 kB
|
||||
out/renderer/assets/html-Dq1ixqYb-okJOhOmu.js 58.25 kB
|
||||
out/renderer/assets/chunk-OSK3NFVY-uIpNfy4k.js 58.56 kB
|
||||
out/renderer/assets/ocaml-CUdGm1iq-BKX30YEX.js 62.65 kB
|
||||
out/renderer/assets/model-settings-source-JYisGYmM.js 63.03 kB
|
||||
out/renderer/assets/ballerina-CpYcPBJI-D9ac3462.js 64.89 kB
|
||||
out/renderer/assets/markdown-BSrOIEaF-BFwOzGIM.js 65.52 kB
|
||||
out/renderer/assets/chunk-IMKFNOWR-K_k56tb2.js 67.22 kB
|
||||
out/renderer/assets/mojo-BNaitZ-7-E_psDM2x.js 70.00 kB
|
||||
out/renderer/assets/python-Cld0Iwtn-tcCJ5L_g.js 70.17 kB
|
||||
out/renderer/assets/blockDiagram-I7D4REHJ-B2ciwNEw.js 71.01 kB
|
||||
out/renderer/assets/bsl-CtP8370o-Pi14XlIU.js 71.07 kB
|
||||
out/renderer/assets/c-B4augMcT-B5ncIjy5.js 72.57 kB
|
||||
out/renderer/assets/chunk-75Z2AOVW-JUQFBHAM.js 72.67 kB
|
||||
out/renderer/assets/latex-g2Pus_l2-CP0G7LTN.js 72.85 kB
|
||||
out/renderer/assets/vyper-C1nscAY5-BTAKd5p2.js 74.85 kB
|
||||
out/renderer/assets/ModelSettingsPanel-Bq69xf7M.js 76.64 kB
|
||||
out/renderer/assets/xychartDiagram-S5SC5T6Z-CRxhfnTo.js 76.79 kB
|
||||
out/renderer/assets/chunk-GMAD6QVW-Bh7dgfzS.js 77.76 kB
|
||||
out/renderer/assets/hack-B1ag3l4X-CEYIfPfg.js 80.58 kB
|
||||
out/renderer/assets/src-DsgKm1PY.js 83.16 kB
|
||||
out/renderer/assets/chunk-TICWLB2K-T0W1tKxl.js 83.88 kB
|
||||
out/renderer/assets/fortran-free-form-CsgtTAg3-Dm0PhuY8.js 89.20 kB
|
||||
out/renderer/assets/vennDiagram-4TSXK5OY-_1_lRuy9.js 89.26 kB
|
||||
out/renderer/assets/csharp-YOPVljXo-CBjcozlW.js 89.91 kB
|
||||
out/renderer/assets/racket--xYIV9-n-NDM2V4Sc.js 92.62 kB
|
||||
out/renderer/assets/swift-CgzYrGBX-CaMD6i-j.js 94.14 kB
|
||||
out/renderer/assets/less-BGhX8xko-CbSvNyvq.js 99.00 kB
|
||||
out/renderer/assets/chunk-SHT3W25Y-Bhx-xs-0.js 104.10 kB
|
||||
out/renderer/assets/objective-c-CmcWiAft-DY5tZuMk.js 105.62 kB
|
||||
out/renderer/assets/blade-Bq8WPf0E-BehdttJf.js 105.98 kB
|
||||
out/renderer/assets/c4Diagram-7LVT6UL2-COxjNYvg.js 107.96 kB
|
||||
out/renderer/assets/php-X15vsN4N-ChBJUzAp.js 111.49 kB
|
||||
out/renderer/assets/dagre-CzI-C3sx.js 122.98 kB
|
||||
out/renderer/assets/ganttDiagram-EL5Y4UJY-BF255DSu.js 123.77 kB
|
||||
out/renderer/assets/graphlib-CoAzpIqe.js 127.44 kB
|
||||
out/renderer/assets/asciidoc-DJWalVNM-Daa-Gl9r.js 146.30 kB
|
||||
out/renderer/assets/mdx-C_Ato9sK-CDV72_N0.js 146.49 kB
|
||||
out/renderer/assets/editor.main-POO0Vbhx-joAkg4Ov.js 161.32 kB
|
||||
out/renderer/assets/cose-bilkent-JH36ORCC-CA60tZpq.js 165.63 kB
|
||||
out/renderer/assets/objective-cpp-BggTCHV8-BRaaCyEF.js 172.18 kB
|
||||
out/renderer/assets/javascript-AfZCJ9Uc-C_GZREFb.js 175.31 kB
|
||||
out/renderer/assets/tsx-BOlKGefW-D7XVyutE.js 176.00 kB
|
||||
out/renderer/assets/jsx-CPd9p36x-D5Ck2u9I.js 178.26 kB
|
||||
out/renderer/assets/sequenceDiagram-WJ2MYXX4-B9hxKtQH.js 190.05 kB
|
||||
out/renderer/assets/typescript-4sRsPriL-Ce01imBq.js 191.16 kB
|
||||
out/renderer/assets/mermaid.core-CYzT-hJp.js 191.57 kB
|
||||
out/renderer/assets/angular-ts-YduEkmVa-936ueej5.js 193.82 kB
|
||||
out/renderer/assets/vue-vine-DXhYlaTf-C8MW7tnI.js 201.27 kB
|
||||
out/renderer/assets/SourceSelect-Dd7kI5iL.js 203.20 kB
|
||||
out/renderer/assets/chunk-4HAMMTFA-Bx-ZDNkL.js 210.32 kB
|
||||
out/renderer/assets/swimlanes-42K2YHIH-CgEXyowS.js 265.51 kB
|
||||
out/renderer/assets/wolfram-BVoTES0L-W3A5YqXk.js 267.14 kB
|
||||
out/renderer/assets/chunk-DU6HZSFF-D1SCGf9S.js 271.07 kB
|
||||
out/renderer/assets/architectureDiagram-5GKGNRK7-BmVKhcu0.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-DcJkdGs4.js 622.62 kB
|
||||
out/renderer/assets/cpp-9jHBA231-DB3feGjZ.js 626.73 kB
|
||||
out/renderer/assets/app-4914IQSi.js 675.57 kB
|
||||
out/renderer/assets/emacs-lisp-DjtOxg4j-CzQ0CKOn.js 780.06 kB
|
||||
out/renderer/assets/cytoscape.esm-bVGYt-iW.js 869.69 kB
|
||||
out/renderer/assets/ArtifactPierreDiff-DpqRTCz8.js 1,119.58 kB
|
||||
out/renderer/assets/chunk-FOHPRMQF-BCllzKJD.js 1,154.18 kB
|
||||
out/renderer/assets/index-B5YSZ8Ro.js 3,765.41 kB
|
||||
out/renderer/assets/editor.api2-dPwET-7w-BYIQ9bT3.js 4,889.23 kB
|
||||
|
||||
✓ built in 3.90s
|
||||
@@ -0,0 +1,29 @@
|
||||
|
||||
> ycode@0.0.7 check:tokens
|
||||
> node scripts/check-design-tokens.mjs
|
||||
|
||||
设计 token 漂移检查(静态)
|
||||
扫描:src/renderer/src 共 367 个文件(用时 219 ms)
|
||||
baseline:scripts/design-token-baseline.json(334 个文件)
|
||||
门禁分类:adapter 8 | core 6 | local 279(合计 293 个文件)
|
||||
合计:裸 hex=611 裸 px=2680 !important=6 --wb-* 定义=525 var(--yc-*) 使用=1651 var(--wb-*) 使用=1209
|
||||
非门禁分类:vendor 2 | recovered 22 | source 47 | tokenSource 3(合计 74 个文件,仅记录不阻塞)
|
||||
合计:裸 hex=10642 裸 px=13642 !important=920 --wb-* 定义=17966 var(--yc-*) 使用=77 var(--wb-*) 使用=19638
|
||||
非门禁相对 baseline:文件 +0;裸 hex +78 裸 px +64 !important +0 --wb-* 定义 +0 var(--yc-*) 使用 +22 var(--wb-*) 使用 -120
|
||||
|
||||
结果:失败,共 6 项:
|
||||
[新增门禁文件] src/renderer/src/capabilities/recommended-flow.css(local):裸 px=21
|
||||
[新增门禁文件] src/renderer/src/capabilities/skill-detail-shell.css(local):裸 px=21
|
||||
[回归] src/renderer/src/capabilities/skills-host.css(local):裸 px 25 → 45(+20)
|
||||
[新增门禁文件] src/renderer/src/workbuddy/composer/capability-picker.css(local):裸 hex=26,裸 px=48
|
||||
[回归] src/renderer/src/workbuddy/composer/composer.css(local):裸 hex 23 → 38(+15);裸 px 83 → 139(+56)
|
||||
[新增门禁文件] src/renderer/src/workbuddy/composer/prompt-queue.css(local):裸 hex=8,裸 px=35
|
||||
|
||||
提示:确认变更符合预期后运行 `node scripts/check-design-tokens.mjs --update-baseline` 刷新 baseline;
|
||||
否则请改用 --yc-* token、复用现有值,或去掉重复的 --wb-* 定义。
|
||||
提示(不失败,仅记录):3 个门禁文件 token 使用数上升:
|
||||
src/renderer/src/capabilities/skills-host.css(local):var(--wb-*) 使用 12 → 19(+7)
|
||||
src/renderer/src/workbuddy/composer/composer.css(local):var(--yc-*) 使用 35 → 48(+13);var(--wb-*) 使用 0 → 1(+1)
|
||||
src/renderer/src/workbuddy/conversation/conversation.css(local):var(--yc-*) 使用 0 → 4(+4)
|
||||
提示(不失败):baseline 中 8 个文件已不存在:src/renderer/src/components/ReportedRunUsage.tsx;src/renderer/src/workbuddy/subagents/SourceMemberIcon.tsx;src/renderer/src/workbuddy/subagents/SubagentCollaboration.tsx;src/renderer/src/workbuddy/subagents/SubagentDetailPanel.tsx;src/renderer/src/workbuddy/subagents/adapters.css;src/renderer/src/workbuddy/subagents/member-view.ts;src/renderer/src/workbuddy/subagents/source.css;src/renderer/src/workbuddy/subagents/theme.css
|
||||
提示:新增门禁文件 36 个且无受控计数(允许):src/renderer/src/capabilities/CapabilityMaintenance.tsx(local);src/renderer/src/capabilities/RecommendedSkills.tsx(local);src/renderer/src/capabilities/SkillAvatar.tsx(local);src/renderer/src/capabilities/SkillDetailShell.tsx(local);src/renderer/src/capabilities/SkillModalPortal.tsx(local);src/renderer/src/capabilities/skill-modal-focus.ts(local);src/renderer/src/components/SessionLoading.tsx(local);src/renderer/src/components/TaskPopconfirm.tsx(local);src/renderer/src/components/session-loading.css(local);src/renderer/src/components/task-popconfirm.css(local);src/renderer/src/components/updates/UpdateSidebarCard.tsx(local);src/renderer/src/components/updates/update-ui-model.ts(local);src/renderer/src/components/updates/update-ui-store.ts(local);src/renderer/src/components/updates/updates-ui.css(local);src/renderer/src/ui/Button.tsx(local);src/renderer/src/ui/IconButton.tsx(local);src/renderer/src/ui/Input.tsx(local);src/renderer/src/ui/Popover.tsx(local);src/renderer/src/ui/Select.tsx(local);src/renderer/src/ui/Switch.tsx(local);…(还有 16 项,详见 --json)
|
||||
@@ -0,0 +1,88 @@
|
||||
|
||||
> ycode@0.0.7 test:composer-capabilities
|
||||
> node scripts/run-composer-capabilities-regression.mjs
|
||||
|
||||
prompt-queue-regression: cap, payload, order, isolation, delivery, stop, recovery and unknown checks passed
|
||||
{
|
||||
"result": "PASS",
|
||||
"checks": [
|
||||
{
|
||||
"name": "parallel same-instance enqueues preserve exactly 19 items",
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "duplicate take is serialized to one winner",
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "delivering item is immutable and notify does not duplicate delivery",
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "clear removes a non-delivering session queue and is idempotent",
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "first enqueue after an empty queue was paused resumes a new run without unpausing existing work",
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "incoming payload is validated before host side effects and persistence",
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "host-rebuilt capability labels are validated before persistence",
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "two queue instances cannot overwrite one another",
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "corrupt queue cannot redirect or duplicate item identity",
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "invalid revision, status and payload permission are rejected",
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "post-delivery removal failure becomes paused unknown instead of stuck delivering",
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "stale owner nonce is recovered without trusting a reused PID",
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "stale and expired lock files are reclaimed",
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "live foreign lock times out with an explicit error",
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "blocked notify does not create a state revision",
|
||||
"pass": true
|
||||
},
|
||||
{
|
||||
"name": "host resolver applies dispatch-time permission downgrade without mutating stored payload",
|
||||
"pass": true
|
||||
}
|
||||
]
|
||||
}
|
||||
input-composition-regression: precedence, takeover, queue preservation, task placement, toolbar and escape rules passed
|
||||
{"result":"PASS","checks":30}
|
||||
{
|
||||
"result": "PASS",
|
||||
"tests": [
|
||||
"serial model writes + frozen active turn",
|
||||
"send failure retry",
|
||||
"late result/event session isolation",
|
||||
"draft settings during first session creation",
|
||||
"nextRequestSettings whitelist"
|
||||
]
|
||||
}
|
||||
context-usage-regression: latest, previous, active-run, summary identity and failure cases passed
|
||||
{"result":"PASS","checks":36,"directory":"C:\\Users\\Administrator\\.codex\\worktrees\\b03-accept-01\\YCode\\.tmp\\claude-capabilities-CtzcVY"}
|
||||
@@ -0,0 +1,18 @@
|
||||
|
||||
> ycode@0.0.7 test:reporting
|
||||
> node --test scripts/regression-reporting.test.mjs
|
||||
|
||||
✔ alignment reports absent optional DOM coverage explicitly (3753.2111ms)
|
||||
✔ alignment requires DOM when requested by flag (70.8616ms)
|
||||
✔ alignment requires DOM when requested by environment (59.917ms)
|
||||
✔ alignment rejects an unloadable configured DOM module instead of skipping (58.2746ms)
|
||||
✔ backend never reports a skipped real package as PASS (1945.4468ms)
|
||||
✔ alignment rejects a configured module without a JSDOM export (61.8861ms)
|
||||
ℹ tests 6
|
||||
ℹ suites 0
|
||||
ℹ pass 6
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 6051.0998
|
||||
@@ -0,0 +1,22 @@
|
||||
[
|
||||
{
|
||||
"name": "test",
|
||||
"exitCode": 0
|
||||
},
|
||||
{
|
||||
"name": "test:reporting",
|
||||
"exitCode": 0
|
||||
},
|
||||
{
|
||||
"name": "test:composer-capabilities",
|
||||
"exitCode": 0
|
||||
},
|
||||
{
|
||||
"name": "test:tool-approvals",
|
||||
"exitCode": 0
|
||||
},
|
||||
{
|
||||
"name": "check:tokens",
|
||||
"exitCode": 1
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,5 @@
|
||||
|
||||
> ycode@0.0.7 test:tool-approvals
|
||||
> esbuild scripts/tool-approval-regression.tsx --bundle --platform=node --format=cjs --jsx=automatic --loader:.css=text --outfile=.tmp/tool-approval-regression.cjs --log-level=error && node .tmp/tool-approval-regression.cjs
|
||||
|
||||
Tool approval helper and inline source markup regression checks passed.
|
||||
@@ -0,0 +1,37 @@
|
||||
|
||||
> ycode@0.0.7 test
|
||||
> npm run test:core
|
||||
|
||||
|
||||
> ycode@0.0.7 test:core
|
||||
> npm run typecheck && npm run test:chat && npm run test:sessions && npm run test:persistence && npm run test:conversation
|
||||
|
||||
|
||||
> ycode@0.0.7 typecheck
|
||||
> tsc --noEmit -p tsconfig.node.json && tsc --noEmit -p tsconfig.web.json
|
||||
|
||||
|
||||
> ycode@0.0.7 test:chat
|
||||
> esbuild scripts/message-order-regression.ts scripts/chat-store-regression.ts scripts/chat-stream-committer-regression.ts --bundle --platform=node --format=esm --out-extension:.js=.mjs --outdir=.tmp/chat-tests --log-level=warning && node .tmp/chat-tests/message-order-regression.mjs && node .tmp/chat-tests/chat-store-regression.mjs && node .tmp/chat-tests/chat-stream-committer-regression.mjs
|
||||
|
||||
message-order-regression: all checks passed
|
||||
chat-store-regression: all checks passed
|
||||
chat-stream-committer-regression: all checks passed
|
||||
|
||||
> ycode@0.0.7 test:sessions
|
||||
> esbuild scripts/session-store-regression.ts --bundle --platform=node --format=esm --external:esbuild --outfile=.tmp/session-store-regression.mjs --log-level=warning && node .tmp/session-store-regression.mjs
|
||||
|
||||
session-store-regression: all checks passed
|
||||
|
||||
> ycode@0.0.7 test:persistence
|
||||
> esbuild scripts/chat-persistence-regression.ts --bundle --platform=node --format=esm --external:esbuild --outfile=.tmp/chat-persistence-regression.mjs --log-level=warning && node .tmp/chat-persistence-regression.mjs
|
||||
|
||||
chat-persistence-regression: all checks passed
|
||||
|
||||
> ycode@0.0.7 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
|
||||
@@ -0,0 +1,72 @@
|
||||
{
|
||||
"status": "PASS",
|
||||
"scope": "Actual ClaudeKernel and SDK; temporary preferences supplied, Windows Bash and PowerShell QA adaptation; no UI coverage",
|
||||
"requests": 26,
|
||||
"cases": [
|
||||
{
|
||||
"case": "craft-default",
|
||||
"approvals": 1,
|
||||
"questions": 0,
|
||||
"ruleApprovals": 0,
|
||||
"toolErrors": 1
|
||||
},
|
||||
{
|
||||
"case": "craft-full",
|
||||
"approvals": 0,
|
||||
"questions": 1,
|
||||
"ruleApprovals": 0,
|
||||
"toolErrors": 0,
|
||||
"compoundMarker": true,
|
||||
"disposableAbsent": true
|
||||
},
|
||||
{
|
||||
"case": "plan-full",
|
||||
"approvals": 0,
|
||||
"questions": 0,
|
||||
"ruleApprovals": 0,
|
||||
"toolErrors": 1
|
||||
},
|
||||
{
|
||||
"case": "ask-full",
|
||||
"approvals": 0,
|
||||
"questions": 0,
|
||||
"ruleApprovals": 0,
|
||||
"toolErrors": 1
|
||||
},
|
||||
{
|
||||
"case": "default-return",
|
||||
"approvals": 1,
|
||||
"questions": 0,
|
||||
"ruleApprovals": 0,
|
||||
"toolErrors": 1
|
||||
},
|
||||
{
|
||||
"case": "ask-rule-full",
|
||||
"approvals": 0,
|
||||
"questions": 0,
|
||||
"ruleApprovals": 0,
|
||||
"toolErrors": 0
|
||||
},
|
||||
{
|
||||
"case": "ask-rule-default",
|
||||
"approvals": 1,
|
||||
"questions": 0,
|
||||
"ruleApprovals": 1,
|
||||
"toolErrors": 1
|
||||
},
|
||||
{
|
||||
"case": "rebuilt-full",
|
||||
"approvals": 0,
|
||||
"questions": 1,
|
||||
"ruleApprovals": 0,
|
||||
"toolErrors": 0
|
||||
},
|
||||
{
|
||||
"case": "full-execution-errors",
|
||||
"approvals": 0,
|
||||
"questions": 0,
|
||||
"ruleApprovals": 0,
|
||||
"toolErrors": 2
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
// B03: real SDK/CLI, deterministic loopback model, disposable fixtures only.
|
||||
// Default: SDK protocol policy. --kernel: bundled production ClaudeKernel, real SDK.
|
||||
import assert from 'node:assert/strict'
|
||||
import { createServer } from 'node:http'
|
||||
import { mkdtemp, mkdir, writeFile, readFile, stat, rm } from 'node:fs/promises'
|
||||
import { tmpdir } from 'node:os'
|
||||
import { join, resolve } from 'node:path'
|
||||
|
||||
// QA Windows adaptation; real kernel and SDK retained.
|
||||
|
||||
const executable = resolve(`node_modules/@anthropic-ai/claude-agent-sdk-${process.platform}-${process.arch}/${process.platform === 'win32' ? 'claude.exe' : 'claude'}`)
|
||||
const root = await mkdtemp(join(tmpdir(), 'ycode-b03-loopback-'))
|
||||
const workspace = join(root, 'workspace')
|
||||
for (const name of ['workspace', 'home', 'config', 'tmp', 'user-data']) await mkdir(join(root, name))
|
||||
const env = {
|
||||
PATH: process.env.PATH, SystemRoot: process.env.SystemRoot, WINDIR: process.env.WINDIR, ComSpec: process.env.ComSpec, PATHEXT: process.env.PATHEXT, CLAUDE_CODE_GIT_BASH_PATH: 'C:/Users/Administrator/scoop/apps/git/current/bin/bash.exe', HOME: join(root, 'home'), USERPROFILE: join(root, 'home'),
|
||||
TMPDIR: join(root, 'tmp'), TMP: join(root, 'tmp'), TEMP: join(root, 'tmp'),
|
||||
CLAUDE_CONFIG_DIR: join(root, 'config'), CLAUDE_SECURESTORAGE_CONFIG_DIR: join(root, 'config'),
|
||||
CLAUDE_TEST_USER_DATA: join(root, 'user-data'),
|
||||
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: '1', DISABLE_TELEMETRY: '1', DISABLE_ERROR_REPORTING: '1',
|
||||
ANTHROPIC_API_KEY: 'isolated-loopback-placeholder-not-a-credential',
|
||||
ANTHROPIC_MODEL: 'claude-loopback', ANTHROPIC_DEFAULT_OPUS_MODEL: 'claude-loopback',
|
||||
ANTHROPIC_DEFAULT_SONNET_MODEL: 'claude-loopback', ANTHROPIC_DEFAULT_HAIKU_MODEL: 'claude-loopback'
|
||||
}
|
||||
// Clear inheritance before SDK import as well as passing an explicit child env.
|
||||
for (const key of Object.keys(process.env)) delete process.env[key]
|
||||
Object.assign(process.env, env)
|
||||
let stage = 'bind', activeCase, instance, kernel, requests = 0
|
||||
const kernelMode = process.argv.includes('--kernel')
|
||||
const results = []
|
||||
function send(res, event, data) { res.write(`event: ${event}\ndata: ${JSON.stringify(data)}\n\n`) }
|
||||
const server = createServer((req, res) => {
|
||||
if (++requests > 60) { res.writeHead(429).end(); return }
|
||||
if (req.method !== 'POST' || !req.url?.startsWith('/v1/messages')) { res.writeHead(404).end(); return }
|
||||
let raw = ''
|
||||
req.on('data', chunk => { raw += chunk; if (raw.length > 1024 * 1024) req.destroy() })
|
||||
req.on('end', () => {
|
||||
try {
|
||||
const body = JSON.parse(raw)
|
||||
const c = activeCase
|
||||
assert.ok(c)
|
||||
const next = c.steps[c.issued++]
|
||||
res.writeHead(200, { 'content-type': 'text/event-stream' })
|
||||
send(res, 'message_start', { type: 'message_start', message: { id: `msg_${requests}`, type: 'message', role: 'assistant', model: body.model, content: [], stop_reason: null, stop_sequence: null, usage: { input_tokens: 10, output_tokens: 1 } } })
|
||||
const content = next ? { type: 'tool_use', id: `tool_${requests}`, name: next.name, input: {} } : { type: 'text', text: '' }
|
||||
send(res, 'content_block_start', { type: 'content_block_start', index: 0, content_block: content })
|
||||
send(res, 'content_block_delta', { type: 'content_block_delta', index: 0, delta: next ? { type: 'input_json_delta', partial_json: JSON.stringify(next.input) } : { type: 'text_delta', text: 'Fixture complete.' } })
|
||||
send(res, 'content_block_stop', { type: 'content_block_stop', index: 0 })
|
||||
send(res, 'message_delta', { type: 'message_delta', delta: { stop_reason: next ? 'tool_use' : 'end_turn', stop_sequence: null }, usage: { output_tokens: 5 } })
|
||||
send(res, 'message_stop', { type: 'message_stop' }); res.end()
|
||||
} catch { res.destroy() }
|
||||
})
|
||||
})
|
||||
const abortController = new AbortController()
|
||||
const timer = setTimeout(() => abortController.abort(), 100000)
|
||||
const write = (file, content) => ({ name: 'Write', input: { file_path: join(workspace, file), content } })
|
||||
async function verifyCompound() {
|
||||
assert.equal(await readFile(join(workspace, 'compound-complete.txt'), 'utf8'), 'complete')
|
||||
await assert.rejects(stat(join(workspace, 'disposable')), { code: 'ENOENT' })
|
||||
await assert.rejects(stat(join(workspace, 'disposable/item.txt')), { code: 'ENOENT' })
|
||||
}
|
||||
const question = { name: 'AskUserQuestion', input: { questions: [{ question: 'Which fixture?', header: 'Fixture', multiSelect: false, options: [{ label: 'Alpha', description: 'First fixture' }, { label: 'Beta', description: 'Second fixture' }] }] } }
|
||||
try {
|
||||
// Binding is deliberately first: on denial do not import/start the SDK.
|
||||
await new Promise((ok, fail) => { server.once('error', fail); server.listen(0, '127.0.0.1', ok) })
|
||||
env.ANTHROPIC_BASE_URL = `http://127.0.0.1:${server.address().port}`
|
||||
Object.assign(process.env, env)
|
||||
stage = 'sdk-import'
|
||||
const { query } = await import('@anthropic-ai/claude-agent-sdk')
|
||||
await writeFile(join(workspace, 'existing.txt'), 'before\n')
|
||||
const cases = [
|
||||
{ label: 'craft-full', mode: 'craft', full: true, steps: [
|
||||
{ name: 'Read', input: { file_path: join(workspace, 'existing.txt') } },
|
||||
{ name: 'Edit', input: { file_path: join(workspace, 'existing.txt'), old_string: 'before', new_string: 'after' } },
|
||||
write('created.txt', 'created\n'),
|
||||
{ name: 'Bash', input: { command: 'printf simple > simple.txt', timeout: 5000 } },
|
||||
{ name: 'Bash', input: { command: 'mkdir disposable && printf fixture > disposable/item.txt && rm disposable/item.txt && rmdir disposable && printf complete > compound-complete.txt', timeout: 5000 } },
|
||||
{ name: 'PowerShell', input: { command: "[IO.File]::WriteAllText('powershell-simple.txt','powershell'); New-Item -ItemType Directory -Path ps-disposable | Out-Null; Set-Content ps-disposable/item.txt 'fixture'; Remove-Item ps-disposable/item.txt; Remove-Item ps-disposable; [IO.File]::WriteAllText('powershell-complete.txt','complete')", timeout: 5000 } }, question
|
||||
] },
|
||||
{ label: 'craft-default', mode: 'craft', full: false, steps: [write('default-denied.txt', 'blocked')] },
|
||||
{ label: 'plan-full', mode: 'plan', full: true, steps: [write('plan-denied.txt', 'blocked')] },
|
||||
{ label: 'ask-full', mode: 'ask', full: true, steps: [write('ask-denied.txt', 'blocked')] }
|
||||
]
|
||||
if (kernelMode) {
|
||||
stage = 'kernel-import'
|
||||
const { ClaudeKernel } = await import('./b03-real-kernel.mjs')
|
||||
const model = {
|
||||
profile: { id: 'b03-fixture', name: 'B03 fixture', model: 'claude-loopback', authMode: 'api-key', protocol: 'anthropic', contextWindowTokens: 200000 },
|
||||
config: { api: 'anthropic-messages', baseUrl: env.ANTHROPIC_BASE_URL + '/v1', model: 'claude-loopback', apiKey: env.ANTHROPIC_API_KEY, authMode: 'api-key' }
|
||||
}
|
||||
const makeKernel = permissionMode => new ClaudeKernel({ sessionId: crypto.randomUUID(), workspaceRoot: workspace, model, permissionMode, agentMode: 'craft', thinkingLevel: 'off', forceNewSession: true, onSessionId() {} })
|
||||
kernel = makeKernel('default-sandbox')
|
||||
const sequence = [cases[1], cases[0], cases[2], cases[3], { ...cases[1], label: 'default-return' },
|
||||
{ label: 'ask-rule-full', mode: 'craft', full: true, rule: true, steps: [{ name: 'Bash', input: { command: 'printf rule >> rule-marker.txt', timeout: 5000 } }] },
|
||||
{ label: 'ask-rule-default', mode: 'craft', full: false, rule: true, steps: [{ name: 'Bash', input: { command: 'printf rule >> rule-marker.txt', timeout: 5000 } }] },
|
||||
{ label: 'rebuilt-full', mode: 'craft', full: true, rebuild: true, steps: [write('rebuilt.txt', 'rebuilt'), question] },
|
||||
{ label: 'full-execution-errors', mode: 'craft', full: true, errors: true, steps: [
|
||||
{ name: 'Edit', input: { file_path: join(workspace, 'does-not-exist.txt'), old_string: 'before', new_string: 'after' } },
|
||||
{ name: 'Bash', input: { command: 'exit 7', timeout: 5000 } }
|
||||
] }]
|
||||
for (const c of sequence) {
|
||||
stage = c.label
|
||||
if (c.rebuild) { await kernel.close(); kernel = makeKernel('full-access') }
|
||||
await kernel.setPolicy(c.full ? 'full-access' : 'default-sandbox', c.mode)
|
||||
if (c.rule) {
|
||||
// Query is the real initialized SDK instance, not a replacement. This
|
||||
// API changes only its session flag layer, never user config files.
|
||||
assert.ok(kernel.instance)
|
||||
await kernel.instance.applyFlagSettings({ permissions: { ask: ['Bash'] } })
|
||||
}
|
||||
activeCase = { ...c, issued: 0 }
|
||||
let approvals = 0, questions = 0, ruleApprovals = 0
|
||||
const output = await kernel.runTurn({ runId: crypto.randomUUID(), userMessageId: crypto.randomUUID(), prompt: `Run deterministic fixture ${c.label}.`, signal: abortController.signal,
|
||||
emit() {}, interactions: {
|
||||
async approval(...args) { approvals++; if (args[5]?.requestKind === 'rule-intercept') ruleApprovals++; return { kind: 'approval', optionId: 'reject-once' } },
|
||||
async question(_id, _title, items) { questions++; return { kind: 'question', answer: { questions: items.map(item => ({ id: item.id, question: item.question, answers: ['Alpha'] })) } } }
|
||||
}
|
||||
})
|
||||
const toolErrors = output.tools.filter(tool => tool.status === 'error').length
|
||||
assert.equal(output.tools.length, c.steps.length)
|
||||
if (c.rule) {
|
||||
assert.equal(approvals, c.full ? 0 : 1)
|
||||
assert.equal(ruleApprovals, c.full ? 0 : 1)
|
||||
assert.equal(toolErrors, c.full ? 0 : 1)
|
||||
assert.equal(await readFile(join(workspace, 'rule-marker.txt'), 'utf8'), 'rule')
|
||||
} else if (c.errors) { assert.equal(approvals, 0); assert.equal(toolErrors, 2) }
|
||||
else if (c.mode === 'craft' && c.full) {
|
||||
assert.equal(approvals, 0); assert.equal(questions, 1); assert.equal(toolErrors, 0)
|
||||
if (c.rebuild) assert.equal(await readFile(join(workspace, 'rebuilt.txt'), 'utf8'), 'rebuilt')
|
||||
else { assert.equal(await readFile(join(workspace, 'existing.txt'), 'utf8'), 'after\n'); assert.equal(await readFile(join(workspace, 'created.txt'), 'utf8'), 'created\n'); assert.equal(await readFile(join(workspace, 'simple.txt'), 'utf8'), 'simple'); await verifyCompound(); assert.equal(await readFile(join(workspace, 'powershell-simple.txt'), 'utf8'), 'powershell'); assert.equal(await readFile(join(workspace, 'powershell-complete.txt'), 'utf8'), 'complete'); await assert.rejects(stat(join(workspace, 'ps-disposable')), {code:'ENOENT'}) }
|
||||
} else {
|
||||
assert.equal(toolErrors, 1)
|
||||
assert.equal(approvals, c.mode === 'craft' ? 1 : 0)
|
||||
await assert.rejects(readFile(join(workspace, `${c.mode === 'craft' ? 'default' : c.mode}-denied.txt`)), { code: 'ENOENT' })
|
||||
}
|
||||
results.push({ case: c.label, approvals, questions, ruleApprovals, toolErrors, ...(c.label === 'craft-full' ? { compoundMarker: true, disposableAbsent: true } : {}) })
|
||||
}
|
||||
await kernel.close(); kernel = undefined
|
||||
} else for (const c of cases) {
|
||||
stage = c.label
|
||||
activeCase = { ...c, issued: 0 }; let approvals = 0, questions = 0, hookDenials = 0, toolErrors = 0
|
||||
instance = query({ prompt: 'Run only the deterministic local fixture sequence.', options: {
|
||||
cwd: workspace, pathToClaudeCodeExecutable: executable, env, abortController,
|
||||
model: 'claude-loopback', permissionMode: 'default', permissionPrompts: 'host',
|
||||
settingSources: [], strictMcpConfig: true, mcpServers: {}, plugins: [], agents: {},
|
||||
persistSession: false, maxTurns: 12, tools: ['Read', 'Edit', 'Write', 'Bash', 'AskUserQuestion'],
|
||||
hooks: { PreToolUse: [{ hooks: [async hook => {
|
||||
if (hook.tool_name === 'AskUserQuestion') return { hookSpecificOutput: { hookEventName: 'PreToolUse', permissionDecision: 'ask' } }
|
||||
if (c.mode !== 'craft' && ['Write', 'Edit', 'Bash'].includes(hook.tool_name)) {
|
||||
hookDenials++; return { hookSpecificOutput: { hookEventName: 'PreToolUse', permissionDecision: 'deny', permissionDecisionReason: 'Fixture read-only mode' } }
|
||||
}
|
||||
return c.full && c.mode === 'craft' ? { hookSpecificOutput: { hookEventName: 'PreToolUse', permissionDecision: 'allow' } } : {}
|
||||
}] }] },
|
||||
canUseTool: async (name, input) => {
|
||||
if (name === 'AskUserQuestion') { questions++; return { behavior: 'allow', updatedInput: { ...input, answers: { 'Which fixture?': 'Alpha' } } } }
|
||||
approvals++; return { behavior: 'deny', message: 'Default fixture approval intentionally denied' }
|
||||
}
|
||||
} })
|
||||
let completed = false
|
||||
for await (const message of instance) {
|
||||
if (message.type === 'user' && Array.isArray(message.message?.content)) toolErrors += message.message.content.filter(x => x.type === 'tool_result' && x.is_error).length
|
||||
if (message.type === 'result') { assert.equal(message.subtype, 'success'); completed = true; break }
|
||||
}
|
||||
instance.close(); instance = undefined
|
||||
assert.ok(completed)
|
||||
if (c.label === 'craft-full') { assert.equal(approvals, 0); assert.equal(questions, 1); assert.equal(toolErrors, 0); assert.equal(await readFile(join(workspace, 'existing.txt'), 'utf8'), 'after\n'); assert.equal(await readFile(join(workspace, 'created.txt'), 'utf8'), 'created\n'); assert.equal(await readFile(join(workspace, 'simple.txt'), 'utf8'), 'simple'); await verifyCompound() }
|
||||
else { await assert.rejects(readFile(join(workspace, `${c.mode === 'craft' ? 'default' : c.mode}-denied.txt`)), { code: 'ENOENT' }); if (c.mode === 'craft') assert.ok(approvals > 0); else assert.ok(hookDenials > 0) }
|
||||
results.push({ case: c.label, approvals, questions, hookDenials, toolErrors })
|
||||
}
|
||||
console.log(JSON.stringify({ status: 'PASS', scope: kernelMode ? 'Actual ClaudeKernel and SDK; temporary preferences supplied, Windows Bash and PowerShell QA adaptation; no UI coverage' : 'SDK protocol fixture, not actual application kernel or Windows', requests, cases: results }))
|
||||
} catch (error) {
|
||||
console.error(JSON.stringify({ status: 'BLOCKED_OR_FAILED', stage, code: error?.code ?? null, name: error?.name ?? 'Error', message: error?.message, stack: error?.stack, completedCases: results }))
|
||||
process.exitCode = 1
|
||||
} finally {
|
||||
clearTimeout(timer); abortController.abort(); instance?.close(); await kernel?.close()
|
||||
server.closeAllConnections(); if (server.listening) await new Promise(ok => server.close(ok))
|
||||
await rm(root, { recursive: true, force: true })
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
[claude] [claude-code:unrecognized_model] {"model":"claude-loopback","query_source":"sdk"}
|
||||
[claude-permission] {"permissionMode":"default-sandbox","agentMode":"craft","sdkMode":"default","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"hook","toolCall":"43a3b2698eba905e","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":"unknown","branch":"sdk-policy"}
|
||||
[claude-permission] {"permissionMode":"default-sandbox","agentMode":"craft","sdkMode":"default","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"callback","toolCall":"43a3b2698eba905e","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":false,"branch":"permission-approval"}
|
||||
[claude-permission] {"permissionMode":"full-access","agentMode":"craft","sdkMode":"default","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"hook","toolCall":"4ed9abbf3162300a","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":"unknown","branch":"full-access-preauthorized"}
|
||||
[claude-permission] {"permissionMode":"full-access","agentMode":"craft","sdkMode":"default","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"hook","toolCall":"86fd4ab8db7f5f11","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":"unknown","branch":"full-access-preauthorized"}
|
||||
[claude-permission] {"permissionMode":"full-access","agentMode":"craft","sdkMode":"default","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"hook","toolCall":"7e2ee80a5e248272","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":"unknown","branch":"full-access-preauthorized"}
|
||||
[claude-permission] {"permissionMode":"full-access","agentMode":"craft","sdkMode":"default","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"hook","toolCall":"6db1fc2e4c48edb8","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":"unknown","branch":"full-access-preauthorized"}
|
||||
[claude-permission] {"permissionMode":"full-access","agentMode":"craft","sdkMode":"default","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"hook","toolCall":"6e7d36eb4db18cae","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":"unknown","branch":"full-access-preauthorized"}
|
||||
[claude-permission] {"permissionMode":"full-access","agentMode":"craft","sdkMode":"default","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"hook","toolCall":"36814c9006134245","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":"unknown","branch":"full-access-preauthorized"}
|
||||
[claude-permission] {"permissionMode":"full-access","agentMode":"craft","sdkMode":"default","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"hook","toolCall":"9ff3664e4c844d32","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":"unknown","branch":"business-question"}
|
||||
[claude-permission] {"permissionMode":"full-access","agentMode":"craft","sdkMode":"default","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"callback","toolCall":"9ff3664e4c844d32","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":false,"branch":"business-question"}
|
||||
[claude-permission] {"permissionMode":"full-access","agentMode":"plan","sdkMode":"plan","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"hook","toolCall":"cc04668a6ae49237","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":"unknown","branch":"mode-or-inactive-deny"}
|
||||
[claude-permission] {"permissionMode":"full-access","agentMode":"ask","sdkMode":"default","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"hook","toolCall":"11ffd38876c89a92","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":"unknown","branch":"mode-or-inactive-deny"}
|
||||
[claude-permission] {"permissionMode":"default-sandbox","agentMode":"craft","sdkMode":"default","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"hook","toolCall":"c8d4672b320d8e62","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":"unknown","branch":"sdk-policy"}
|
||||
[claude-permission] {"permissionMode":"default-sandbox","agentMode":"craft","sdkMode":"default","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"callback","toolCall":"c8d4672b320d8e62","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":false,"branch":"permission-approval"}
|
||||
[claude-permission] {"permissionMode":"full-access","agentMode":"craft","sdkMode":"default","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"hook","toolCall":"5d7efa6d743f9e03","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":"unknown","branch":"full-access-preauthorized"}
|
||||
[claude-permission] {"permissionMode":"full-access","agentMode":"craft","sdkMode":"default","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"callback","toolCall":"5d7efa6d743f9e03","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":true,"branch":"full-access-preauthorized"}
|
||||
[claude-permission] {"permissionMode":"default-sandbox","agentMode":"craft","sdkMode":"default","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"hook","toolCall":"17731bb84b6f9672","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":"unknown","branch":"sdk-policy"}
|
||||
[claude-permission] {"permissionMode":"default-sandbox","agentMode":"craft","sdkMode":"default","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"callback","toolCall":"17731bb84b6f9672","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":true,"branch":"rule-approval"}
|
||||
[claude] [claude-code:unrecognized_model] {"model":"claude-loopback","query_source":"sdk"}
|
||||
[claude-permission] {"permissionMode":"full-access","agentMode":"craft","sdkMode":"default","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"hook","toolCall":"8a6a3330fe99a401","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":"unknown","branch":"full-access-preauthorized"}
|
||||
[claude-permission] {"permissionMode":"full-access","agentMode":"craft","sdkMode":"default","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"hook","toolCall":"4db9b8eaf21b122c","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":"unknown","branch":"business-question"}
|
||||
[claude-permission] {"permissionMode":"full-access","agentMode":"craft","sdkMode":"default","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"callback","toolCall":"4db9b8eaf21b122c","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":false,"branch":"business-question"}
|
||||
[claude-permission] {"permissionMode":"full-access","agentMode":"craft","sdkMode":"default","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"hook","toolCall":"8f3f4861840d6744","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":"unknown","branch":"full-access-preauthorized"}
|
||||
{"status":"PASS","scope":"Actual ClaudeKernel and SDK; temporary preferences supplied, Windows Bash and PowerShell QA adaptation; no UI coverage","requests":26,"cases":[{"case":"craft-default","approvals":1,"questions":0,"ruleApprovals":0,"toolErrors":1},{"case":"craft-full","approvals":0,"questions":1,"ruleApprovals":0,"toolErrors":0,"compoundMarker":true,"disposableAbsent":true},{"case":"plan-full","approvals":0,"questions":0,"ruleApprovals":0,"toolErrors":1},{"case":"ask-full","approvals":0,"questions":0,"ruleApprovals":0,"toolErrors":1},{"case":"default-return","approvals":1,"questions":0,"ruleApprovals":0,"toolErrors":1},{"case":"ask-rule-full","approvals":0,"questions":0,"ruleApprovals":0,"toolErrors":0},{"case":"ask-rule-default","approvals":1,"questions":0,"ruleApprovals":1,"toolErrors":1},{"case":"rebuilt-full","approvals":0,"questions":1,"ruleApprovals":0,"toolErrors":0},{"case":"full-execution-errors","approvals":0,"questions":0,"ruleApprovals":0,"toolErrors":2}]}
|
||||
@@ -0,0 +1,57 @@
|
||||
{
|
||||
"status": "PASS",
|
||||
"scope": "Actual ClaudeKernel and SDK; temporary preferences supplied, Windows real session grant lifecycle; no UI coverage",
|
||||
"requests": 12,
|
||||
"cases": [
|
||||
{
|
||||
"case": "grant-first",
|
||||
"approvals": 1,
|
||||
"grants": 1,
|
||||
"toolErrors": 0,
|
||||
"proposalKinds": [
|
||||
"allow_once",
|
||||
"allow_always",
|
||||
"reject_once"
|
||||
]
|
||||
},
|
||||
{
|
||||
"case": "grant-next-turn",
|
||||
"approvals": 0,
|
||||
"grants": 0,
|
||||
"toolErrors": 0,
|
||||
"proposalKinds": []
|
||||
},
|
||||
{
|
||||
"case": "grant-rebuilt-same-session",
|
||||
"approvals": 0,
|
||||
"grants": 0,
|
||||
"toolErrors": 0,
|
||||
"proposalKinds": []
|
||||
},
|
||||
{
|
||||
"case": "grant-new-session",
|
||||
"approvals": 1,
|
||||
"grants": 1,
|
||||
"toolErrors": 0,
|
||||
"proposalKinds": [
|
||||
"allow_once",
|
||||
"allow_always",
|
||||
"reject_once"
|
||||
]
|
||||
},
|
||||
{
|
||||
"case": "grant-plan-boundary",
|
||||
"approvals": 0,
|
||||
"grants": 0,
|
||||
"toolErrors": 1,
|
||||
"proposalKinds": []
|
||||
},
|
||||
{
|
||||
"case": "grant-ask-boundary",
|
||||
"approvals": 0,
|
||||
"grants": 0,
|
||||
"toolErrors": 1,
|
||||
"proposalKinds": []
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
// B03: real SDK/CLI, deterministic loopback model, disposable fixtures only.
|
||||
// Default: SDK protocol policy. --kernel: bundled production ClaudeKernel, real SDK.
|
||||
import assert from 'node:assert/strict'
|
||||
import { createServer } from 'node:http'
|
||||
import { mkdtemp, mkdir, writeFile, readFile, stat, rm } from 'node:fs/promises'
|
||||
import { tmpdir } from 'node:os'
|
||||
import { join, resolve } from 'node:path'
|
||||
|
||||
// QA Windows adaptation; real kernel and SDK retained.
|
||||
|
||||
const executable = resolve(`node_modules/@anthropic-ai/claude-agent-sdk-${process.platform}-${process.arch}/${process.platform === 'win32' ? 'claude.exe' : 'claude'}`)
|
||||
const root = await mkdtemp(join(tmpdir(), 'ycode-b03-loopback-'))
|
||||
const workspace = join(root, 'workspace')
|
||||
for (const name of ['workspace', 'home', 'config', 'tmp', 'user-data']) await mkdir(join(root, name))
|
||||
const env = {
|
||||
PATH: process.env.PATH, SystemRoot: process.env.SystemRoot, WINDIR: process.env.WINDIR, ComSpec: process.env.ComSpec, PATHEXT: process.env.PATHEXT, CLAUDE_CODE_GIT_BASH_PATH: 'C:/Users/Administrator/scoop/apps/git/current/bin/bash.exe', HOME: join(root, 'home'), USERPROFILE: join(root, 'home'),
|
||||
TMPDIR: join(root, 'tmp'), TMP: join(root, 'tmp'), TEMP: join(root, 'tmp'),
|
||||
CLAUDE_CONFIG_DIR: join(root, 'config'), CLAUDE_SECURESTORAGE_CONFIG_DIR: join(root, 'config'),
|
||||
CLAUDE_TEST_USER_DATA: join(root, 'user-data'),
|
||||
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: '1', DISABLE_TELEMETRY: '1', DISABLE_ERROR_REPORTING: '1',
|
||||
ANTHROPIC_API_KEY: 'isolated-loopback-placeholder-not-a-credential',
|
||||
ANTHROPIC_MODEL: 'claude-loopback', ANTHROPIC_DEFAULT_OPUS_MODEL: 'claude-loopback',
|
||||
ANTHROPIC_DEFAULT_SONNET_MODEL: 'claude-loopback', ANTHROPIC_DEFAULT_HAIKU_MODEL: 'claude-loopback'
|
||||
}
|
||||
// Clear inheritance before SDK import as well as passing an explicit child env.
|
||||
for (const key of Object.keys(process.env)) delete process.env[key]
|
||||
Object.assign(process.env, env)
|
||||
let stage = 'bind', activeCase, instance, kernel, requests = 0
|
||||
const kernelMode = process.argv.includes('--kernel')
|
||||
const results = []
|
||||
function send(res, event, data) { res.write(`event: ${event}\ndata: ${JSON.stringify(data)}\n\n`) }
|
||||
const server = createServer((req, res) => {
|
||||
if (++requests > 60) { res.writeHead(429).end(); return }
|
||||
if (req.method !== 'POST' || !req.url?.startsWith('/v1/messages')) { res.writeHead(404).end(); return }
|
||||
let raw = ''
|
||||
req.on('data', chunk => { raw += chunk; if (raw.length > 1024 * 1024) req.destroy() })
|
||||
req.on('end', () => {
|
||||
try {
|
||||
const body = JSON.parse(raw)
|
||||
const c = activeCase
|
||||
assert.ok(c)
|
||||
const next = c.steps[c.issued++]
|
||||
res.writeHead(200, { 'content-type': 'text/event-stream' })
|
||||
send(res, 'message_start', { type: 'message_start', message: { id: `msg_${requests}`, type: 'message', role: 'assistant', model: body.model, content: [], stop_reason: null, stop_sequence: null, usage: { input_tokens: 10, output_tokens: 1 } } })
|
||||
const content = next ? { type: 'tool_use', id: `tool_${requests}`, name: next.name, input: {} } : { type: 'text', text: '' }
|
||||
send(res, 'content_block_start', { type: 'content_block_start', index: 0, content_block: content })
|
||||
send(res, 'content_block_delta', { type: 'content_block_delta', index: 0, delta: next ? { type: 'input_json_delta', partial_json: JSON.stringify(next.input) } : { type: 'text_delta', text: 'Fixture complete.' } })
|
||||
send(res, 'content_block_stop', { type: 'content_block_stop', index: 0 })
|
||||
send(res, 'message_delta', { type: 'message_delta', delta: { stop_reason: next ? 'tool_use' : 'end_turn', stop_sequence: null }, usage: { output_tokens: 5 } })
|
||||
send(res, 'message_stop', { type: 'message_stop' }); res.end()
|
||||
} catch { res.destroy() }
|
||||
})
|
||||
})
|
||||
const abortController = new AbortController()
|
||||
const timer = setTimeout(() => abortController.abort(), 100000)
|
||||
const write = (file, content) => ({ name: 'Write', input: { file_path: join(workspace, file), content } })
|
||||
async function verifyCompound() {
|
||||
assert.equal(await readFile(join(workspace, 'compound-complete.txt'), 'utf8'), 'complete')
|
||||
await assert.rejects(stat(join(workspace, 'disposable')), { code: 'ENOENT' })
|
||||
await assert.rejects(stat(join(workspace, 'disposable/item.txt')), { code: 'ENOENT' })
|
||||
}
|
||||
const question = { name: 'AskUserQuestion', input: { questions: [{ question: 'Which fixture?', header: 'Fixture', multiSelect: false, options: [{ label: 'Alpha', description: 'First fixture' }, { label: 'Beta', description: 'Second fixture' }] }] } }
|
||||
try {
|
||||
// Binding is deliberately first: on denial do not import/start the SDK.
|
||||
await new Promise((ok, fail) => { server.once('error', fail); server.listen(0, '127.0.0.1', ok) })
|
||||
env.ANTHROPIC_BASE_URL = `http://127.0.0.1:${server.address().port}`
|
||||
Object.assign(process.env, env)
|
||||
stage = 'sdk-import'
|
||||
const { query } = await import('@anthropic-ai/claude-agent-sdk')
|
||||
await writeFile(join(workspace, 'existing.txt'), 'before\n')
|
||||
const cases = [
|
||||
{ label: 'craft-full', mode: 'craft', full: true, steps: [
|
||||
{ name: 'Read', input: { file_path: join(workspace, 'existing.txt') } },
|
||||
{ name: 'Edit', input: { file_path: join(workspace, 'existing.txt'), old_string: 'before', new_string: 'after' } },
|
||||
write('created.txt', 'created\n'),
|
||||
{ name: 'Bash', input: { command: 'printf simple > simple.txt', timeout: 5000 } },
|
||||
{ name: 'Bash', input: { command: 'mkdir disposable && printf fixture > disposable/item.txt && rm disposable/item.txt && rmdir disposable && printf complete > compound-complete.txt', timeout: 5000 } },
|
||||
{ name: 'PowerShell', input: { command: "[IO.File]::WriteAllText('powershell-simple.txt','powershell'); New-Item -ItemType Directory -Path ps-disposable | Out-Null; Set-Content ps-disposable/item.txt 'fixture'; Remove-Item ps-disposable/item.txt; Remove-Item ps-disposable; [IO.File]::WriteAllText('powershell-complete.txt','complete')", timeout: 5000 } }, question
|
||||
] },
|
||||
{ label: 'craft-default', mode: 'craft', full: false, steps: [write('default-denied.txt', 'blocked')] },
|
||||
{ label: 'plan-full', mode: 'plan', full: true, steps: [write('plan-denied.txt', 'blocked')] },
|
||||
{ label: 'ask-full', mode: 'ask', full: true, steps: [write('ask-denied.txt', 'blocked')] }
|
||||
]
|
||||
if (kernelMode) {
|
||||
stage = 'kernel-import'
|
||||
const { ClaudeKernel } = await import('./b03-real-kernel.mjs')
|
||||
const model = {
|
||||
profile: { id: 'b03-fixture', name: 'B03 fixture', model: 'claude-loopback', authMode: 'api-key', protocol: 'anthropic', contextWindowTokens: 200000 },
|
||||
config: { api: 'anthropic-messages', baseUrl: env.ANTHROPIC_BASE_URL + '/v1', model: 'claude-loopback', apiKey: env.ANTHROPIC_API_KEY, authMode: 'api-key' }
|
||||
}
|
||||
let hostSessionId=crypto.randomUUID(); const makeKernel = permissionMode => new ClaudeKernel({ sessionId: hostSessionId, workspaceRoot: workspace, model, permissionMode, agentMode: 'craft', thinkingLevel: 'off', forceNewSession: true, onSessionId() {} })
|
||||
kernel = makeKernel('default-sandbox')
|
||||
const command={name:'Bash',input:{command:'git init grant-repo',timeout:5000}};
|
||||
const sequence=[{label:'grant-first',expected:1},{label:'grant-next-turn',expected:0},{label:'grant-rebuilt-same-session',expected:0,rebuild:true},{label:'grant-new-session',expected:1,rebuild:true,newSession:true},{label:'grant-plan-boundary',expected:0,mode:'plan'},{label:'grant-ask-boundary',expected:0,mode:'ask'}];
|
||||
for(const c of sequence){
|
||||
stage=c.label;
|
||||
if(c.rebuild){await kernel.close();if(c.newSession)hostSessionId=crypto.randomUUID();kernel=makeKernel('default-sandbox')}
|
||||
await kernel.setPolicy('default-sandbox',c.mode||'craft');
|
||||
activeCase={steps:[command],issued:0};let approvals=0,grants=0,proposalKinds=[];
|
||||
const output=await kernel.runTurn({runId:crypto.randomUUID(),userMessageId:crypto.randomUUID(),prompt:'Run deterministic grant fixture.',signal:abortController.signal,emit(){},interactions:{
|
||||
async approval(...args){approvals++;proposalKinds=args[2].map(x=>x.kind);console.log('GRANT_PROPOSAL',JSON.stringify({kinds:proposalKinds,details:args[5],hasApply:typeof args[6]}));const opt=args[2].find(x=>x.kind==='allow_always');assert.ok(opt,'real SDK must offer replayable session grant for fixture');await args[6]({kind:'approval',optionId:opt.optionId});grants++;return {kind:'approval',optionId:opt.optionId}},
|
||||
async question(){throw Error('Unexpected question')}
|
||||
}});
|
||||
const toolErrors=output.tools.filter(x=>x.status==='error').length;
|
||||
assert.equal(approvals,c.expected);assert.equal(grants,c.expected);assert.equal(toolErrors,c.mode?1:0);
|
||||
results.push({case:c.label,approvals,grants,toolErrors,proposalKinds});
|
||||
}
|
||||
assert.ok((await stat(join(workspace,'grant-repo/.git'))).isDirectory());
|
||||
await kernel.close(); kernel = undefined
|
||||
} else for (const c of cases) {
|
||||
stage = c.label
|
||||
activeCase = { ...c, issued: 0 }; let approvals = 0, questions = 0, hookDenials = 0, toolErrors = 0
|
||||
instance = query({ prompt: 'Run only the deterministic local fixture sequence.', options: {
|
||||
cwd: workspace, pathToClaudeCodeExecutable: executable, env, abortController,
|
||||
model: 'claude-loopback', permissionMode: 'default', permissionPrompts: 'host',
|
||||
settingSources: [], strictMcpConfig: true, mcpServers: {}, plugins: [], agents: {},
|
||||
persistSession: false, maxTurns: 12, tools: ['Read', 'Edit', 'Write', 'Bash', 'AskUserQuestion'],
|
||||
hooks: { PreToolUse: [{ hooks: [async hook => {
|
||||
if (hook.tool_name === 'AskUserQuestion') return { hookSpecificOutput: { hookEventName: 'PreToolUse', permissionDecision: 'ask' } }
|
||||
if (c.mode !== 'craft' && ['Write', 'Edit', 'Bash'].includes(hook.tool_name)) {
|
||||
hookDenials++; return { hookSpecificOutput: { hookEventName: 'PreToolUse', permissionDecision: 'deny', permissionDecisionReason: 'Fixture read-only mode' } }
|
||||
}
|
||||
return c.full && c.mode === 'craft' ? { hookSpecificOutput: { hookEventName: 'PreToolUse', permissionDecision: 'allow' } } : {}
|
||||
}] }] },
|
||||
canUseTool: async (name, input) => {
|
||||
if (name === 'AskUserQuestion') { questions++; return { behavior: 'allow', updatedInput: { ...input, answers: { 'Which fixture?': 'Alpha' } } } }
|
||||
approvals++; return { behavior: 'deny', message: 'Default fixture approval intentionally denied' }
|
||||
}
|
||||
} })
|
||||
let completed = false
|
||||
for await (const message of instance) {
|
||||
if (message.type === 'user' && Array.isArray(message.message?.content)) toolErrors += message.message.content.filter(x => x.type === 'tool_result' && x.is_error).length
|
||||
if (message.type === 'result') { assert.equal(message.subtype, 'success'); completed = true; break }
|
||||
}
|
||||
instance.close(); instance = undefined
|
||||
assert.ok(completed)
|
||||
if (c.label === 'craft-full') { assert.equal(approvals, 0); assert.equal(questions, 1); assert.equal(toolErrors, 0); assert.equal(await readFile(join(workspace, 'existing.txt'), 'utf8'), 'after\n'); assert.equal(await readFile(join(workspace, 'created.txt'), 'utf8'), 'created\n'); assert.equal(await readFile(join(workspace, 'simple.txt'), 'utf8'), 'simple'); await verifyCompound() }
|
||||
else { await assert.rejects(readFile(join(workspace, `${c.mode === 'craft' ? 'default' : c.mode}-denied.txt`)), { code: 'ENOENT' }); if (c.mode === 'craft') assert.ok(approvals > 0); else assert.ok(hookDenials > 0) }
|
||||
results.push({ case: c.label, approvals, questions, hookDenials, toolErrors })
|
||||
}
|
||||
console.log(JSON.stringify({ status: 'PASS', scope: kernelMode ? 'Actual ClaudeKernel and SDK; temporary preferences supplied, Windows real session grant lifecycle; no UI coverage' : 'SDK protocol fixture, not actual application kernel or Windows', requests, cases: results }))
|
||||
} catch (error) {
|
||||
console.error(JSON.stringify({ status: 'BLOCKED_OR_FAILED', stage, code: error?.code ?? null, name: error?.name ?? 'Error', message: error?.message, stack: error?.stack, completedCases: results }))
|
||||
process.exitCode = 1
|
||||
} finally {
|
||||
clearTimeout(timer); abortController.abort(); instance?.close(); await kernel?.close()
|
||||
server.closeAllConnections(); if (server.listening) await new Promise(ok => server.close(ok))
|
||||
await rm(root, { recursive: true, force: true })
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
[claude] [claude-code:unrecognized_model] {"model":"claude-loopback","query_source":"sdk"}
|
||||
[claude-permission] {"permissionMode":"default-sandbox","agentMode":"craft","sdkMode":"default","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"hook","toolCall":"43a3b2698eba905e","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":"unknown","branch":"sdk-policy"}
|
||||
[claude-permission] {"permissionMode":"default-sandbox","agentMode":"craft","sdkMode":"default","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"callback","toolCall":"43a3b2698eba905e","decisionCategory":"other","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":false,"branch":"permission-approval"}
|
||||
GRANT_PROPOSAL {"kinds":["allow_once","allow_always","reject_once"],"details":{"requestKind":"permission","toolName":"Bash","command":"git init grant-repo","reason":"This command requires approval","suggestedRules":["Bash(git init *)"],"allowScope":"session"},"hasApply":"function"}
|
||||
[claude-permission] {"permissionMode":"default-sandbox","agentMode":"craft","sdkMode":"default","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"hook","toolCall":"4ed9abbf3162300a","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":"unknown","branch":"sdk-policy"}
|
||||
[claude] [claude-code:unrecognized_model] {"model":"claude-loopback","query_source":"sdk"}
|
||||
[claude-permission] {"permissionMode":"default-sandbox","agentMode":"craft","sdkMode":"default","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"hook","toolCall":"7e2ee80a5e248272","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":"unknown","branch":"sdk-policy"}
|
||||
[claude] [claude-code:unrecognized_model] {"model":"claude-loopback","query_source":"sdk"}
|
||||
[claude-permission] {"permissionMode":"default-sandbox","agentMode":"craft","sdkMode":"default","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"hook","toolCall":"6e7d36eb4db18cae","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":"unknown","branch":"sdk-policy"}
|
||||
[claude-permission] {"permissionMode":"default-sandbox","agentMode":"craft","sdkMode":"default","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"callback","toolCall":"6e7d36eb4db18cae","decisionCategory":"other","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":false,"branch":"permission-approval"}
|
||||
GRANT_PROPOSAL {"kinds":["allow_once","allow_always","reject_once"],"details":{"requestKind":"permission","toolName":"Bash","command":"git init grant-repo","reason":"This command requires approval","suggestedRules":["Bash(git init *)"],"allowScope":"session"},"hasApply":"function"}
|
||||
[claude-permission] {"permissionMode":"default-sandbox","agentMode":"plan","sdkMode":"plan","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"hook","toolCall":"9ff3664e4c844d32","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":"unknown","branch":"mode-or-inactive-deny"}
|
||||
[claude-permission] {"permissionMode":"default-sandbox","agentMode":"ask","sdkMode":"default","sdkModeSource":"host-query-or-acknowledged-control","policyTransition":false,"source":"hook","toolCall":"cc04668a6ae49237","decisionCategory":"unknown","decisionCode":"unknown","decisionCodePresent":false,"matchedAskRule":"unknown","branch":"mode-or-inactive-deny"}
|
||||
{"status":"PASS","scope":"Actual ClaudeKernel and SDK; temporary preferences supplied, Windows real session grant lifecycle; no UI coverage","requests":12,"cases":[{"case":"grant-first","approvals":1,"grants":1,"toolErrors":0,"proposalKinds":["allow_once","allow_always","reject_once"]},{"case":"grant-next-turn","approvals":0,"grants":0,"toolErrors":0,"proposalKinds":[]},{"case":"grant-rebuilt-same-session","approvals":0,"grants":0,"toolErrors":0,"proposalKinds":[]},{"case":"grant-new-session","approvals":1,"grants":1,"toolErrors":0,"proposalKinds":["allow_once","allow_always","reject_once"]},{"case":"grant-plan-boundary","approvals":0,"grants":0,"toolErrors":1,"proposalKinds":[]},{"case":"grant-ask-boundary","approvals":0,"grants":0,"toolErrors":1,"proposalKinds":[]}]}
|
||||
Reference in new issue
Block a user