@kimiclaw/cli 1.0.44 → 1.0.45
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -19
- package/package.json +9 -9
- package/web/dist/assets/{AssistantsView-Y4TXobGE.js → AssistantsView-Y3nFezhd.js} +1 -1
- package/web/dist/assets/AutomationView-bf7_zU_p.js +4 -0
- package/web/dist/assets/Button-B43HsIQ3.js +1 -0
- package/web/dist/assets/{ChannelConfigView-WJ-zUV8p.js → ChannelConfigView---Dwl3Fk.js} +3 -3
- package/web/dist/assets/ChartsView-Dw6G-jf3.js +1 -0
- package/web/dist/assets/{ConnectorsView-DaHmxnGE.js → ConnectorsView-BWvdrpyK.js} +2 -2
- package/web/dist/assets/{DiffPreview-D8tIj_aF.js → DiffPreview-WQihq3bK.js} +57 -56
- package/web/dist/assets/{FileContextMenu-C5WYeBNu.js → FileContextMenu-CyjXlSHp.js} +1 -1
- package/web/dist/assets/FileTreeView-Cafy33nT.js +1 -0
- package/web/dist/assets/HookConfigView-D-lASVju.js +2 -0
- package/web/dist/assets/InboxView-BWajw-Yx.js +1 -0
- package/web/dist/assets/InputArea-CSqaA55j.js +31 -0
- package/web/dist/assets/Install-ClEm4oGX.js +2 -0
- package/web/dist/assets/MemoryView-DLri75dm.js +1 -0
- package/web/dist/assets/ModelsView-BBLUMzR5.js +1 -0
- package/web/dist/assets/PluginsView-C-fnbDGZ.js +1 -0
- package/web/dist/assets/ProjectsView-BruI2W_l.js +1 -0
- package/web/dist/assets/{SessionGrid-BQSrCDqQ.js → SessionGrid-7GLpwn6d.js} +4 -4
- package/web/dist/assets/SettingsModal-cc9Qu2QU.js +4 -0
- package/web/dist/assets/SkillsView-Bf-2-U_q.js +1 -0
- package/web/dist/assets/TemplatesTab-CKul8nbL.js +2 -0
- package/web/dist/assets/{ToolsView-CjdYiaNz.js → ToolsView-D_aluOsK.js} +1 -1
- package/web/dist/assets/WorkspaceDirPicker-Z42YqE4a.js +5 -0
- package/web/dist/assets/{agentIconSet-CDeMxTHf.js → agentIconSet-Cqhm4UOl.js} +1 -1
- package/web/dist/assets/api-BW4-5gtM.js +1 -0
- package/web/dist/assets/chatStore-D8Zzr1hE.js +242 -0
- package/web/dist/assets/cn-CoHJgTJ5.js +1 -0
- package/web/dist/assets/{common-CPZxdYLs.js → common-CP2UB8TN.js} +99 -99
- package/web/dist/assets/icons-CittejKL.js +1 -0
- package/web/dist/assets/imageUrl-BVgcEm7e.js +2 -0
- package/web/dist/assets/index-CEUbTcNL.css +1 -0
- package/web/dist/assets/index-CxrzleFg.js +122 -0
- package/web/dist/assets/{markdown-Cps-36Z5.js → markdown-DZQBOzWk.js} +1 -1
- package/web/dist/assets/{panels-DCwx2Pbu.js → panels-CuDz4aqU.js} +1 -1
- package/web/dist/assets/projectsStore-B7fdKRzl.js +1 -0
- package/web/dist/assets/{react-vendor-CXI113IS.js → react-vendor-BEA-EtI-.js} +1 -1
- package/web/dist/assets/{settingsStore-BSdi9gNd.js → settingsStore-DYqiXodu.js} +1 -1
- package/web/dist/assets/src-55YckF5W.js +2 -0
- package/web/dist/assets/{state-pOTP5BEk.js → state-A4wJ8QgR.js} +1 -1
- package/web/dist/assets/{statusAxesRefresh--2evRuAU.js → statusAxesRefresh-BBqszCp-.js} +1 -1
- package/web/dist/assets/sttLanguages-jnSk4aqg.js +6 -0
- package/web/dist/assets/threadStore-CQi4OzSe.js +1 -0
- package/web/dist/assets/useConfirm-kTv3x0H6.js +1 -0
- package/web/dist/assets/{useTranslation-gGKZZfux.js → useTranslation-2BGEBvJE.js} +1 -1
- package/web/dist/assets/websocket-DCs7f54y.js +1 -0
- package/web/dist/assets/whatsNewStore-DoCQvcMq.js +1 -0
- package/web/dist/index.html +27 -23
- package/web/dist/assets/AutomationView-DfAF2L92.js +0 -3
- package/web/dist/assets/Button-D-g7PgYh.js +0 -1
- package/web/dist/assets/ChartsView-CSAfGqTC.js +0 -1
- package/web/dist/assets/FileTreeView-B7IN0KmE.js +0 -1
- package/web/dist/assets/HookConfigView-9gqvrRhQ.js +0 -2
- package/web/dist/assets/InboxView-BcEfijbj.js +0 -1
- package/web/dist/assets/InputArea-D5F91Uwk.js +0 -14
- package/web/dist/assets/Install-Cuelo0If.js +0 -2
- package/web/dist/assets/MemoryView-BvZSh5-T.js +0 -1
- package/web/dist/assets/ModelsView-BgvMN8xv.js +0 -1
- package/web/dist/assets/PluginsView-C3d6e8vV.js +0 -1
- package/web/dist/assets/ProjectsView-CM7GOsoK.js +0 -1
- package/web/dist/assets/SettingsModal-BvGXq5EE.js +0 -4
- package/web/dist/assets/SkillsView-87kGRliE.js +0 -1
- package/web/dist/assets/TemplatesTab-8MLwVNwV.js +0 -1
- package/web/dist/assets/api-ZQf0Ys8y.js +0 -1
- package/web/dist/assets/icons-B8Ngx6rM.js +0 -1
- package/web/dist/assets/imageUrl-CrQM4gmf.js +0 -74
- package/web/dist/assets/index-Bm7r92T3.css +0 -1
- package/web/dist/assets/index-STsyoFCk.js +0 -145
- package/web/dist/assets/src-BK8SoTFV.js +0 -1
- package/web/dist/assets/sttLanguages-BPcOF0nQ.js +0 -2
- package/web/dist/assets/useConfirm-CQjBnYuP.js +0 -1
- package/web/dist/assets/websocket-CeKJTCdp.js +0 -1
- package/web/dist/assets/whatsNewStore-C0hbStfc.js +0 -1
- package/web/dist/assets/workspaceSemantics-CW8ytHq2.js +0 -3
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{C as e,E as t,S as n,T as r,_ as i,b as a,h as o,m as s,p as c,x as l,y as u}from"./threads-lr33dwqg.js";function d(e){return{schema:t(),...e}}var f=[],p=new Set;function m(e){for(let t of e){if(p.has(t.type))throw Error(`[protocol] duplicate event type: ${t.type}`);p.add(t.type),f.push(t)}return e}function h(e){return f.find(t=>t.type===e)}new Proxy({},{get:(e,t)=>typeof t==`string`?h(t)?.schema:void 0,has:(e,t)=>typeof t==`string`&&!!h(t)?.schema,ownKeys:()=>f.map(e=>e.type),getOwnPropertyDescriptor:(e,t)=>typeof t==`string`&&h(t)?{enumerable:!0,configurable:!0,value:h(t)?.schema}:void 0}),m([d({type:`connected`,description:`WebSocket 已连接`,category:`session`,emittedBy:[`server`],handledByCli:!0,handledByWeb:!0}),d({type:`session_created`,description:`新会话已创建`,category:`session`,emittedBy:[`server`,`core`],handledByCli:!0,handledByWeb:!0,note:`CLI/Web 均已处理(Web: systemHandlers session_created);background=true 表示后台新建,客户端只入列不抢前台`,schema:l({id:e(),newSessionId:e().optional(),title:e().optional(),workspaceDir:e().optional(),background:o().optional()}).partial()}),d({type:`session_resumed`,description:`会话从存储中恢复`,category:`session`,emittedBy:[`core`,`server`],handledByCli:!0,handledByWeb:!0,note:`CLI/Web 均已处理(Web: systemHandlers session_resumed)`,schema:l({id:e()}).partial()}),d({type:`session_forked`,description:`会话已复制(fork),新会话已创建并广播`,category:`session`,emittedBy:[`core`,`server`],handledByCli:!1,handledByWeb:!0,intentionalGap:!0,note:`Web: useWebSocket 收到广播后在标签栏插入新标签(已存在则跳过,且不夺走当前焦点)。CLI 侧为记录在案的刻意缺口(见 cli/hooks/forkCommand.ts)`,schema:l({sourceId:e(),newSessionId:e(),title:e()}).partial()}),d({type:`auth_required`,description:`需要认证`,category:`session`,emittedBy:[`server`],handledByCli:!0,handledByWeb:!0,note:`CLI 已处理(2026-07-18)`}),d({type:`auth_success`,description:`认证成功`,category:`session`,emittedBy:[`server`],handledByCli:!0,handledByWeb:!0,note:`CLI 已处理(2026-07-18)`}),d({type:`auth_failed`,description:`认证失败`,category:`session`,emittedBy:[`server`],handledByCli:!0,handledByWeb:!0,note:`CLI 已处理(2026-07-18)`}),d({type:`message_ack`,description:`消息确认`,category:`session`,emittedBy:[`client`],handledByCli:!1,handledByWeb:!1,note:`CLI 发送给服务器的入站事件,无需 handler`}),d({type:`workspace_changed`,description:`工作空间已切换`,category:`session`,emittedBy:[`server`],handledByCli:!0,handledByWeb:!0,schema:l({workspaceDir:e()}).partial()}),d({type:`session_switched`,description:`会话已切换`,category:`session`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,note:`CLI 已处理(2026-07-18); Web 已处理(切换 activeSessionId)`,schema:l({id:e()}).partial()}),d({type:`disconnected`,description:`连接断开`,category:`session`,emittedBy:[`server`],handledByCli:!0,handledByWeb:!1,note:`发射端(2026-10-26 补):server 的 /api/system/shutdown 在动手关闭**之前**广播一条,payload={reason,code:1001}。为什么只有这一处:socket 一死消息就送不出去,网络掉线那条路上任何服务端事件都是不可送达的,只能靠客户端 onclose 兜底(Web useWebSocket 的 endGeneration('WebSocket disconnected')、CLI 自己的连接态)。handledByWeb 改为 false —— web/src 里从来没有这个 handler,此前是虚报;Web 的断开态由 onclose 驱动,重复加一个 handler 等于两个写入者`}),d({type:`session_delegation_start`,description:`会话 A 向会话 B 发起委派任务(send_to_session 工具)`,category:`session`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,note:`客户端把 task 作为一条系统消息展示在目标会话(B)时间线上;A 阻塞等待 B 完成`,schema:l({fromSessionId:e(),fromTitle:e(),toSessionId:e(),toTitle:e(),task:e()}).partial()}),d({type:`session_delegation_end`,description:`会话委派任务完成(成功/失败)`,category:`session`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,note:`结果回填到 A 的 send_to_session 工具结果;客户端据此关闭目标会话的委派横幅`,schema:l({fromSessionId:e(),toSessionId:e(),fromTitle:e(),toTitle:e(),ok:o(),summary:e()}).partial()}),d({type:`session_direct_delivered`,description:`用户消息经会话 A 直连投递给会话 B(deliverDirectMessage,不经 A 的模型)`,category:`session`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,note:`投递卡渲染在 A(邮局)的时间线;queued=true 表示 B 正在跑、已排队作新一轮(复用 delegationQueue 互斥门)`,schema:l({fromSessionId:e(),fromTitle:e(),toSessionId:e(),toTitle:e(),text:e(),deliveryId:e(),traceId:e(),hopCount:a(),queued:o()}).partial()}),d({type:`session_direct_completed`,description:`直连消息在会话 B 执行完成(成功/失败),结果转达回 A`,category:`session`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,note:`回复卡渲染在 A 的时间线:summary 是展示优化,outputMessageIds 是事实链(可回溯 B 的原始输出)`,schema:l({fromSessionId:e(),toSessionId:e(),deliveryId:e(),traceId:e(),hopCount:a(),ok:o(),status:e(),summary:e(),outputMessageIds:s(e())}).partial()}),d({type:`session_run_changed`,description:`会话的 run 状态发生迁移(**只是刷新提示,不是状态**)`,category:`session`,emittedBy:[`core`],handledByCli:!1,handledByWeb:!0,intentionalGap:!0,note:"⚠️ **payload 刻意不含 status** —— 状态以 `GET /api/sessions` 的查询为准(响应里的 `status` 字段一直都在,本事件只用来标记「该重拉了」)。理由照抄 `worktree_service_changed`:事件是瞬时的,而「我下午回来看它还在跑吗」必须能重新查询;带上 status 就等于同时存在两份真相,必然漂移。⚠️ 本事件**只覆盖 `setActiveRun` 的迁移**(running / paused / complete / error / stopped / interrupted)。「等用户」那两态(等审批 / 等回答)**不走这里** —— 它们由既有的 `hook_ask` / `ask_user_question` 覆盖。消费方不要把它当成「所有分组变化」的统一广播点。接线:core 侧挂在 `SessionStore.onRunStatusChange` 的既有订阅上(与 watchdog、notifyDispatchedSessionTerminal 同一个订阅,**不改 setActiveRun** 那条热路径)。CLI 侧未接线(无「按需分组」消费面),故 intentionalGap 保持 true —— 该 flag 与 handledByCli 被 CLI 接线完整性门禁共用,提前置 false 会把它当成新缺口误报(同 worktree_service_changed 的口径)。设计:docs/architecture-design/SESSION_TRIAGE_PLAN.md 的 D1",schema:l({sessionId:e()}).partial()}),d({type:`effort_set`,description:`设置会话推理力度(入站控制消息:Web 的 chip / CLI 的 /effort 上行)`,category:`session`,emittedBy:[`client`],handledByCli:!1,handledByWeb:!1,note:`入站事件(client→server):core.handleControlMessage 处理,写 session.reasoningEffort 后回 reasoning_effort_ack`}),d({type:`undo_last_user`,description:`撤销最后一条用户消息(入站控制消息:Web 气泡的「撤销」)`,category:`session`,emittedBy:[`client`],handledByCli:!1,handledByWeb:!1,note:`入站事件(client→server):core.handleControlMessage 先停止该会话生成,再从尾部回滚最后一条 user 消息及其后内容(只回滚会话上下文,不动文件),回 undo_last_user_ack`}),d({type:`undo_last_user_ack`,description:`撤销最后一条用户消息的回执(携带被撤销消息的正文与附件,供回填输入框)`,category:`session`,emittedBy:[`core`],handledByCli:!1,handledByWeb:!0,note:`会话级回执:定向发往绑定该会话的连接。payload { ok, content, images?, files?, error }。`,schema:l({ok:o(),content:e(),images:s(e()),files:s(e()),error:e()}).partial()}),d({type:`watchdog_cancel`,description:`取消看门狗退避中的自动续跑(入站控制消息:Web 通知条上的「取消重试」)`,category:`session`,emittedBy:[`client`],handledByCli:!1,handledByWeb:!1,note:`入站事件(client→server):core.handleControlMessage → SessionWatchdog.cancelAutoResume。撤掉该会话待发的续跑计时器并清零中断链计次,随后由 core 回一条 watchdog_terminal 通知(退避中没有任何活跃 run 可 abort,因此不走 stop 路径,也不产生 stopped/complete)。`}),d({type:`reasoning_effort_ack`,description:`推理力度回执(会话级设置已生效,或输入被拒)`,category:`session`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,note:`会话级状态:server 用 sendToSession 定向发往**绑定了该会话**的连接(与 hook_auto_ack 同款,否则 A 会话改档会串到 B 会话客户端的显示上);无绑定连接时退化为广播(headless / 尚未 resume)。payload { ok, effort, ui, error }:effort 是归一后的 wire 值(与写进请求体的同一份),ui 是 UI 轴档位 off|low|medium|high|extra_high|max。客户端只认回执,不各自推档位。`,schema:l({ok:o(),effort:e(),ui:e(),error:e()}).partial()})]),m([d({type:`start`,description:`AI 开始生成`,category:`stream`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0}),d({type:`content`,description:`生成内容增量`,category:`stream`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,schema:l({text:e(),content:e(),index:a()}).partial(),note:`载荷 { text, index }:index 为服务端稳定 block index(TurnEngine 每轮分配),客户端据此把多段正文与思考/工具按时间序穿插;content 为兼容旧字段`}),d({type:`thinking`,description:`思考过程增量`,category:`stream`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,schema:l({text:e(),content:e(),index:a()}).partial(),note:`载荷 { text, index }:index 为服务端稳定 block index,客户端按 index upsert 成独立思考块(工具调用前后各一段)`}),d({type:`tool_call`,description:`工具调用流式增量`,category:`stream`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0}),d({type:`tool_result`,description:`工具执行结果`,category:`stream`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0}),d({type:`tool_execution_start`,description:`工具执行阶段开始(无流事件时段开始)`,category:`stream`,emittedBy:[`core`],handledByCli:!1,handledByWeb:!1,note:`纯 core 内部遥测:供运行时暂停/恢复 stall 心跳与全局看门狗;CLI/Web 无 handler(前端无需展示),仅 queryEngine 消费`,intentionalGap:!0}),d({type:`tool_execution_end`,description:`工具执行阶段结束(恢复 stall 心跳与全局看门狗)`,category:`stream`,emittedBy:[`core`],handledByCli:!1,handledByWeb:!1,note:`配合 tool_execution_start:防止 180s 心跳把合法长等待误判为流挂起而 abort + 重放整轮工具调用;CLI/Web 无 handler`,intentionalGap:!0}),d({type:`tool_diff`,description:`工具执行中的参数 diff 增量(P0-2 diffConsumer 生产者推送)`,category:`stream`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0}),d({type:`tool_output`,description:`工具执行期间的实时输出增量(stdout/stderr chunk,Phase0 OutputStream 生产者推送)`,category:`stream`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,schema:l({toolCallId:e(),stream:i([`stdout`,`stderr`]),chunk:e(),seq:a(),timestamp:a()}).partial(),note:`增量、可丢;权威输出仍是 tool_result,权威时序仍是 ExecutionLedger。生产者侧节流(时间窗聚合 + 每调用字节上限),不得用于 reset stall 心跳。命名对齐 tool_call/tool_result/tool_diff 家族`}),d({type:`step_start`,description:`步骤开始`,category:`stream`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,note:"发射端(2026-10-26 补):TurnEngine 每次 provider.streamChat 之前发一条,即「一次 LLM 响应 = 一个 step」。`id` 必须是本次响应内固定、跨响应唯一的值(这里是 step-<epochMs>-<seq>,seq 为模块级单调计数,防同一毫秒内两次响应撞 id):CLI parseStep 按 data.id 做 upsert,缺 id 时退化成 step-<Date.now()> → 每条事件各开一张卡;Web 的 ensureStep 反而只看「最新未结束的 step」,id 不参与判定。title 与 step 都给(CLI 读 title/name/action/message,Web 读 step)"}),d({type:`step_thinking`,description:`步骤思考`,category:`stream`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,note:`发射端:TurnEngine 在该步流结束后补一次(thinking 非空时),payload={id,thought}。**不逐 chunk 发**:两端都是整段替换同一字段,逐 chunk 只是白写 store`}),d({type:`step_action`,description:`步骤动作`,category:`stream`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,note:`发射端:TurnEngine 在该步流结束后补一次(该响应确实叫了工具时),payload={id,action},action=工具名逗号串。同一 step 只发一条 —— 两端都是覆盖写,多次工具调用只剩最后一个`}),d({type:`step_complete`,description:`步骤完成`,category:`stream`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,note:`发射端:TurnEngine 在该步流结束后发 payload={id,status:'success'};流抛错时由 guardStreamCompletion 补发 status:'error' + result(错误信息),错误随后原样抛给上层(重试/降级判定不变形)。异常路径必须收尾:Web 的 ensureStep 按「最新未结束的 step」定位,残留的 running 步会把下一条事件吸进僵尸步`}),d({type:`turn_summary`,description:`回合结束摘要(思考时长+工具计数+头条)`,category:`stream`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,note:`CLI/Web 渲染为折叠摘要行(Thought for Ns, ran N …)`}),d({type:`cache_stats`,description:`本轮 run 前缀缓存命中统计(命中/未命中 token、命中率、调用次数)`,category:`stream`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,note:`run 结束时由 queryEngine 发送;CLI/Web 在模型名旁展示命中率`,schema:l({cacheHitTokens:a(),cacheMissTokens:a(),cacheHitRate:a().optional(),cacheStatsCalls:a()}).partial()}),d({type:`web_search`,description:`模型内置联网搜索状态(DeepSeek Responses web_search_call:searching/completed/failed)`,category:`stream`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,note:`由服务端执行搜索,客户端仅展示状态(🔍搜索中 → ✅完成)`,schema:l({state:e()}).partial()}),d({type:`progress`,description:`通用进度(当前未使用)`,category:`stream`,emittedBy:[`none`],handledByCli:!1,handledByWeb:!1,deprecated:!0,note:`已定义但从未发送;原先唯一提及它的 SendMessageTool 空壳已于 2026-10-05 删除`}),d({type:`complete`,description:`生成完成`,category:`stream`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0}),d({type:`error`,description:`生成错误`,category:`stream`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,schema:l({message:e()}).partial()}),d({type:`generation_paused`,description:`生成已暂停`,category:`stream`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0}),d({type:`generation_resumed`,description:`生成已恢复`,category:`stream`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0}),d({type:`stall_detected`,description:`流级卡死检测(自动重试/通知)`,category:`stream`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,note:`由 StreamHeartbeat 或 StallDetector 触发;CLI/Web 显示重试进度`}),d({type:`task_interrupted`,description:`任务中断(服务重启/异常退出)`,category:`stream`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,note:`服务启动扫描时将 running activeRun 标记为 interrupted 后触发;对话会话由看门狗自动续跑(客户端提示「已开始自动续跑」),/continue 退化为手动接管入口,/resume 仍用于切换会话`}),d({type:`prompt_suggestion`,description:`回合结束后生成的下一条输入建议(预填输入框的幽灵提示)`,category:`stream`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,note:`core 在正常收场后用一次轻量 LLM 调用生成单条建议(settings.promptSuggestion.* 可关);CLI/Web 把它渲染成输入框里的幽灵文本,Enter 直接发送、任意键改写`,schema:l({text:e(),source:e().optional()}).partial()}),d({type:`step_prompt`,description:`步骤提示(Web 路由用)`,category:`stream`,emittedBy:[`none`],handledByCli:!1,handledByWeb:!0,note:`Web 路由的内部事件,不通过 WS 发送`}),d({type:`browser_frame`,description:`浏览器实时画面帧(A 方案截图流:Playwright 有头 Chromium 的页面帧推给 Web 渲染)`,category:`stream`,emittedBy:[`core`],handledByCli:!1,handledByWeb:!0,schema:l({tabId:e(),url:e(),title:e(),seq:a(),timestamp:a(),dataUri:e(),format:i([`jpeg`,`png`])}).partial(),note:`增量、可丢、只读呈现(A 方案「只能看」):由 BrowserFrameStream 生产者按帧率节流后推送;权威状态仍是浏览器本身与 browser_snapshot。dataUri 为 data:image/<format>;base64,... 内联帧;CLI 无 handler(终端无法渲染位图)`})]),m([d({type:`plan_mode_change`,description:`模式切换`,category:`plan`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,note:`历史名称,实际承载 act/goal/chat/normal 的模式切换(core modeManager 变更 → server 分发;Web 用户切换时也会回发)。data 携带 previousMode/newMode/frontendMode/sessionId/timestamp`}),d({type:`plan_mode_change_ack`,description:`模式切换 ACK(服务器确认模式变更)`,category:`plan`,emittedBy:[`server`],handledByCli:!0,handledByWeb:!1,note:`server app.ts 对 plan_mode_change 消息的应答;data 携带 mode/auto`}),d({type:`mode_state`,description:`模式状态同步(值 + 来源 + 锁定)`,category:`plan`,emittedBy:[`server`],handledByCli:!1,handledByWeb:!0,note:`server 在 ModeManager 任意变更时广播:data 携带 mode/previousMode/source(default|user_override|auto_router)/locked/reason/auto/autoLevel;Web 据此同步模式值、锁定状态与 auto 档位(autoLevel 是该会话的生效档位,已含会话 floor)——只覆盖基础模式,且不回发 plan_mode_change(否则一次广播会被 server 判成 user_override 误锁模式)`,schema:l({mode:e(),previousMode:e(),source:e(),locked:o(),reason:e(),auto:o(),autoLevel:a()}).partial()}),d({type:`mode_suggestion`,description:`自动评估建议切换模式(被用户锁定拦截,待用户确认)`,category:`plan`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,note:`queryEngine 仲裁拒绝自动建议时 emit(仅 user_override 场景)。Web 弹建议横幅,Apply 走既有 plan_mode_change(user_override 语义);CLI 以**非交互**方式消费:状态行上方一行「建议切到 X · 走 /X 应用」,到点自清(不弹窗、不抢键、不改模式)。CLI 没有确认入口这一事实不变,故不再标记 intentionalGap。`,schema:l({currentMode:e(),suggestedMode:e(),confidence:a(),reason:e(),decisionSource:e()}).partial()})]);var g=l({id:e().optional(),type:e().optional(),scope:e().optional(),confidence:a().optional(),priority:e().optional(),tokens:a().optional(),preview:e().optional(),summary:e().optional(),reason:e().optional()}).partial(),ee=l({id:e().optional(),type:e().optional(),scope:e().optional(),confidence:a().optional(),tags:s(e()).optional(),preview:e().optional()}).partial(),te=l({query:e().optional(),hits:s(ee).optional(),count:a().optional()}).partial();m([d({type:`token_update`,description:`Token 用量更新`,category:`context`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,note:"data 携带 promptTokens/completionTokens(+promptCache*),可选 model/source/workflowNodeTokens;core 在 provider delta 发射点就地补 costUsd(models.dev 单价,只有这一条路径会盖章),CLI/Web 据此累加会话级 `$ spent`"}),d({type:`context_compressed`,description:`上下文已压缩`,category:`context`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0}),d({type:`compaction_progress`,description:`压缩进度更新`,category:`context`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0}),d({type:`context_analysis`,description:`上下文分布分析`,category:`context`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,note:`CLI 已处理(2026-07-18); Web 有 handler 但路由不可达`}),d({type:`threshold_warning`,description:`Token 阈值警告`,category:`context`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,note:`CLI 已处理(2026-07-18); Web 有 handler 但路由不可达`}),d({type:`threshold_error`,description:`Token 阈值错误`,category:`context`,emittedBy:[`none`],handledByCli:!1,handledByWeb:!1,deprecated:!0,note:`功能存在但被 context_blocked 覆盖,事件未使用`}),d({type:`context_blocked`,description:`上下文已满,生成被阻止`,category:`context`,emittedBy:[`none`],handledByCli:!0,handledByWeb:!0,deprecated:!0,note:`已退役(2026-10-26):与 blocking_limit 是同一件事的两次命名,两处阻塞点(ContextManager.checkTokenBudget → onBlocked、queryEngine 的 isAtBlockingLimit 早退)**都只发 blocking_limit**;两端 handler 的动作也完全相同(Web 都只 setThresholdWarning,CLI 都只写 statusText),补发 context_blocked 就等于同一句话报两遍。handler 保留兼容旧服务端回放`}),d({type:`blocking_limit`,description:`已达到阻止极限`,category:`context`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,note:`CLI 已处理(2026-07-18)。发射端:context/ContextManager.ts 的 checkTokenBudget → onBlocked(装配在 core/index.ts)与 queryEngine 的 isAtBlockingLimit 早退,两处;payload 含 message + ThresholdWarningState。Web 已接线且在 STREAM 路由表内(useWebSocket ①,2026-10-26 复核)`}),d({type:`compaction_started`,description:`压缩任务已启动(phase/trigger)`,category:`context`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0}),d({type:`compaction_finished`,description:`压缩任务结束(done/failed/aborted)`,category:`context`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0}),d({type:`tool_retry`,description:`工具重试`,category:`context`,emittedBy:[`none`],handledByCli:!1,handledByWeb:!0,deprecated:!0,note:`重试信息已含于 tool_result/error,Web handler 保留但路由不可达`}),d({type:`model_fallback`,description:`模型回退`,category:`context`,emittedBy:[`none`],handledByCli:!1,handledByWeb:!0,deprecated:!0,note:`降级信息已含于 degradation_update,Web handler 保留但路由不可达`}),d({type:`usage`,description:`Token 用量`,category:`context`,emittedBy:[`none`],handledByCli:!0,handledByWeb:!1,deprecated:!0,note:`已退役(2026-10-26):两个口径都被更细的事件覆盖,本事件剩下的只是第三次重复 —— ① 单次调用用量+成本 = token_update(TurnEngine/queryEngine 共 4 处发射);② 上下文占满比例 = threshold_warning(percentLeft/currentUsage/effectiveContextWindow)。此前 handledByWeb:true 是**虚报**:web/src 里没有任何 usage handler,Web 容量条读的是 token_update。CLI 端 usage 与 token_update 两个 handler 写的是**同一个** appState.usage,而真正在写的是 token_update(useStreamHandlers.ts:1479 起,带 costUsd/缓存累加),消费方 ContextBar.tsx:60 —— 从没有人发 usage 事件,那条 handler 只是同一字段的第二条写路径。handler 保留兼容旧服务端回放`}),d({type:`context_breakdown`,description:`上下文容量分类占比(系统提示词/消息/工具/技能/MCP),供 Web 上下文条抽屉与 CLI 状态行容量横条展示`,category:`context`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,note:`每轮 query 上下文组装后估算各组件 token,并带出 contextWindow(容量条的分母);Web 端点状态栏上下文条上拉展示明细,CLI 只画同一条堆叠横条(不重复文字)`}),d({type:`memory_recall`,description:`本回合记忆召回快照(真正注入的条目 + 被预算挡掉的候选)`,category:`context`,emittedBy:[`core`],handledByCli:!1,handledByWeb:!0,note:`每轮上下文组装后发出。items = 预算截断后**真正进入 prompt** 的那批,dropped = 有相关性但被 maxItems/token 预算挡掉的候选(二者都只带 200 字预览,全文不下发 —— 每轮都发,全文会把 WS 单帧撑到几十 KB);turnId 供 Web 按回合分组、高亮当前回合。tool = 模型主动调 memory_search 的一次快照,由该工具执行后以**独立帧**发出(不带 turnId,客户端按会话累积)—— 同一个类型承载两种帧,靠字段区分。CLI 无 handler:终端没有右栏,/memory 命令走本地 store 另一条路。`,schema:l({turnId:e().optional(),query:e().optional(),items:s(g).optional(),dropped:s(g).optional(),itemCount:a().optional(),droppedCount:a().optional(),totalTokens:a().optional(),wasTruncated:o().optional(),tool:te.optional()}).partial()})]),m([d({type:`workflow_started`,description:`工作流已启动`,category:`workflow`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,note:`data.nodes 携带 LLM 合成完整节点清单(含 type/children/priority,前端可分层渲染)`,schema:l({workflowId:e().optional(),title:e().optional(),goalId:e().optional(),totalNodes:a().optional(),nodes:s(c()).optional()}).partial()}),d({type:`workflow_event`,description:`工作流事件`,category:`workflow`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0}),d({type:`workflow_progress`,description:`工作流进度`,category:`workflow`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,note:`nodeStatuses: 逐节点状态全量映射(断线重连可重建视图)`,schema:l({runId:e().optional(),status:e().optional(),completedNodes:a().optional(),totalNodes:a().optional(),tokensUsed:a().optional(),tokensRemaining:a().optional(),currentNodeId:e().optional(),nodeStatuses:n(e(),e()).optional()}).partial()}),d({type:`workflow_finished`,description:`工作流完成`,category:`workflow`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,schema:l({runId:e().optional(),status:e().optional(),output:c().optional(),error:e().optional()}).partial()}),d({type:`workflow_error`,description:`工作流错误`,category:`workflow`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0}),d({type:`workflow_checkpoint`,description:`工作流检查点`,category:`workflow`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0}),d({type:`workflow_node_start`,description:`工作流节点开始`,category:`workflow`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,schema:l({nodeId:e().optional(),title:e().optional(),type:e().optional()}).partial()}),d({type:`workflow_node_complete`,description:`工作流节点完成`,category:`workflow`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,note:`durationMs: 节点耗时;attempts: retry 重试次数(retry 原语节点)`,schema:l({nodeId:e().optional(),title:e().optional(),status:e().optional(),result:c().optional(),error:e().optional(),durationMs:a().optional(),attempts:a().optional()}).partial()}),d({type:`workflow_node_retry`,description:`工作流节点重试(retry 原语每次重试发出)`,category:`workflow`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,note:`attempt > 1 时发出;reason 为上一次尝试的失败原因`,schema:l({nodeId:e().optional(),childId:e().optional(),attempt:a().optional(),maxAttempts:a().optional(),reason:e().optional()}).partial()}),d({type:`workflow_paused`,description:`工作流已暂停`,category:`workflow`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0}),d({type:`workflow_resumed`,description:`工作流已恢复`,category:`workflow`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0}),d({type:`workflow_cancelled`,description:`工作流已取消`,category:`workflow`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0}),d({type:`workflow_recovered`,description:`工作流已恢复(从故障)`,category:`workflow`,emittedBy:[`none`],handledByCli:!1,handledByWeb:!1,deprecated:!0,note:`已被 workflow_resumed 覆盖,核心从未发送`}),d({type:`workflow_handoff`,description:`ReAct 转交 workflow(范式切换)`,category:`workflow`,emittedBy:[`none`],handledByCli:!0,handledByWeb:!0,deprecated:!0,note:`Agent Loop 单核模型重构后退役:workflow 判定改为计划注入(见 workflow_plan_ready),核心不再发送;CLI/Web 保留 handler 兼容旧服务端回放`}),d({type:`workflow_plan_ready`,description:`范式路由:LLM 合成的执行计划提案就绪(confirm=true 时等待用户确认)`,category:`workflow`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,note:`payload 携带 planId/title/nodes/parallelGroups/estimatedTokens/runtimeAvailable;confirm=false 保持兼容的立即执行路径`,schema:l({planId:e(),title:e().optional(),reason:e().optional(),confirm:o().optional(),nodes:s(c()).optional(),parallelGroups:s(s(e())).optional(),estimatedTokens:a().optional(),runtimeAvailable:o().optional()}).partial()}),d({type:`workflow_confirm_ack`,description:`工作流提案确认结果(start/cancel/change/runtime)`,category:`workflow`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,schema:l({planId:e().optional(),action:e().optional(),ok:o().optional(),auto:o().optional()}).partial()}),d({type:`workflow_status`,description:`workflow run 状态查询响应(状态对账:连接/重连后拉取终态)`,category:`workflow`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,note:`2026-08-14: 配合 get_workflow_status 请求,修复一次性事件流漏终态导致的 UI 卡死;runs[].nodeStatuses 为逐节点状态映射`,schema:l({runs:s(c()).optional()}).partial()})]),m([d({type:`dwf_offer`,description:`动态工作流确认请求(模型写了 _<name>_workflow.js,询问是否运行)`,category:`workflow`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,note:`回合尾嗅探到新写的 workflow 脚本时发出;用户经 dwf_confirm(run|view|no) 应答;执行期进度复用 workflow_* 事件`,schema:l({offerId:e(),sessionId:e().optional(),fileName:e(),filePath:e().optional(),title:e().optional(),description:e().optional(),phases:s(l({title:e(),detail:e().optional()})).optional(),agentCount:a().optional(),scriptPreview:e().optional(),tokenWarning:e().optional()}).partial()}),d({type:`dwf_confirm_ack`,description:`动态工作流确认应答(服务器处理 dwf_confirm 后回执)`,category:`workflow`,emittedBy:[`server`],handledByCli:!0,handledByWeb:!0,note:`data 携带 offerId/action/ok;view 时 scriptPreview 为全量脚本;未知 offerId → ok:false`,schema:l({offerId:e(),action:e(),ok:o(),scriptPreview:e().optional(),error:e().optional()}).partial()}),d({type:`dwf_cancelled`,description:`动态工作流已取消(用户 no / 运行中取消)`,category:`workflow`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,schema:l({offerId:e().optional(),runId:e().optional(),reason:e().optional()}).partial()}),d({type:`dwf_promotable`,description:`动态工作流可沉淀为模板(provenance 账本 successfulRuns ≥3,邀请 Save as template)`,category:`workflow`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,note:`run 终态后由 onTerminal 检测发出;门槛按成功 run 数(successfulRuns,COMPLETED 计数)计,总 run 含失败不达标;用户经 dwf_promote { workflowId } 确认沉淀;promote 成功后模板存在 → 不再提示;用户 No/本地 dismiss 仅清除提示不落服务端标记 → 后续成功 run 终态仍会再次提示(幂等提示而非只提示一次)`,schema:l({workflowId:e(),sessionId:e().optional(),name:e().optional(),runs:a().optional(),successRate:a().optional(),avgTokens:a().optional(),lastRunAt:a().optional()}).partial()}),d({type:`dwf_promote_ack`,description:`沉淀为模板的结果回执(处理 dwf_promote 后)`,category:`workflow`,emittedBy:[`server`],handledByCli:!0,handledByWeb:!0,schema:l({workflowId:e(),ok:o(),templateId:e().optional(),reason:e().optional()}).partial()})]),m([d({type:`filejob_start`,description:`文件处理任务开始(解析/渲染)`,category:`task`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,note:`对话内嵌文件处理面板;Web 已处理,CLI 已处理(2026-08-07 状态行)`}),d({type:`filejob_progress`,description:`文件处理进度更新`,category:`task`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,note:`解析/渲染进度百分比`,schema:l({progress:a()}).partial()}),d({type:`filejob_result`,description:`文件处理完成(结果文件列表)`,category:`task`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,note:`携带 RenderedFileResult[]`,schema:s(c())}),d({type:`filejob_error`,description:`文件处理失败`,category:`task`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,note:`脱敏错误详情`})]),m([d({type:`goal_created`,description:`目标已创建`,category:`goal`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,note:`2026-07-21: Web handled via goal_tasks/goal_task_update`}),d({type:`goal_tasks`,description:`目标任务列表(批量初始化看板)`,category:`goal`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,note:`2026-07-21: 统一看板数据源`}),d({type:`goal_task_update`,description:`目标任务更新`,category:`goal`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,note:`2026-07-21: Web 已添加 handler`}),d({type:`goal_update`,description:`目标元信息更新(retitle / 看板整体刷新)`,category:`goal`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,note:`漂移修复:goalManager.retitle / GoalTool 此前已在发射但未注册;tasks 为空数组时 Web 清空看板`}),d({type:`goal_completed`,description:`目标已完成(workflow 终态自动推导)`,category:`goal`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,note:`2026-08-14: 此前 goals.complete() 无任何调用点,goal 工作流跑完后 goal 永远停在 active —— 新增终态事件供两端对账`}),d({type:`goal_route_decision`,description:`Goal 智能路由结果(simple/medium/hard 分流结论)`,category:`goal`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,note:`2026-09-06 P1: goal 模式消息不再固定跑 4 子代理流水线。默认层只展示一行结论(tier 标签 + 一句话理由 + 耗时),完整判定细节走 debug 层日志`,schema:l({tier:i([`simple`,`medium`,`hard`]),summary:e().optional(),source:i([`override`,`llm`,`fallback`]).optional(),latencyMs:a().optional(),reason:e().optional(),confidence:a().optional(),goalId:e().optional(),runId:e().optional(),message:e().optional()}).partial()})]),m([d({type:`hook_ask`,description:`Hook 审批请求`,category:`hook`,emittedBy:[`server`],handledByCli:!0,handledByWeb:!0}),d({type:`hook_allow`,description:`Hook 允许响应`,category:`hook`,emittedBy:[`client`],handledByCli:!1,handledByWeb:!1,note:`入站事件(CLI→服务器),无需 handler`}),d({type:`hook_deny`,description:`Hook 拒绝响应`,category:`hook`,emittedBy:[`client`],handledByCli:!1,handledByWeb:!1,note:`入站事件(CLI→服务器),无需 handler`}),d({type:`hook_response_ack`,description:`Hook 响应确认`,category:`hook`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,note:`CLI 已添加 handler(2026-07-01); Web systemHandlers 已处理(2026-08-07)`}),d({type:`ask_user_question`,description:`向用户提问`,category:`hook`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0}),d({type:`question_answer_ack`,description:`提问回答确认`,category:`hook`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,note:`Web useWebSocket 已处理(dismiss 提问弹窗)`}),d({type:`form_request`,description:`右栏表单待填请求(collect_form)`,category:`hook`,emittedBy:[`core`],handledByCli:!1,handledByWeb:!0,note:`Web 已接线(2026-02):useWebSocket 早于 sessionId 守卫分派到 formStore → 右栏 FormWidget。CLI 物理上没有右栏,终端里 collect_form 靠超时退化成提问。`}),d({type:`form_answer`,description:`右栏表单提交(Web→服务器,转 core submitFormAnswer)`,category:`hook`,emittedBy:[`client`],handledByCli:!1,handledByWeb:!1,note:`入站事件(Web→服务器),由 server dispatch 转给 core,无需 handler`}),d({type:`form_answer_ack`,description:`表单提交确认(含会话中断取消)`,category:`hook`,emittedBy:[`core`],handledByCli:!1,handledByWeb:!0,note:`Web 已接线:useWebSocket → formStore.applyAck(成功转「已提交」摘要态,失败把 issues 摊回字段)。CLI 无右栏,不消费。`}),d({type:`form_cancelled`,description:`表单被会话中断/停止取消`,category:`hook`,emittedBy:[`core`],handledByCli:!1,handledByWeb:!0,note:`Web 已接线:→ formStore.markCancelled,卡不删(答案仍会落盘),只标注「AI 已不再等待」。CLI 无右栏,不消费。`}),d({type:`hook_auto_ack`,description:`Hook 自动模式确认`,category:`hook`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,note:`Web 已处理(2026-08-07 toast 提示)`}),d({type:`tool.approval_required`,description:`工具调用需要审批(无人值守运行触发,未放行即拒绝)`,category:`hook`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,note:`无人值守/定时运行写操作需审批的通知;Inbox 审批队列已退役,Web 显式 no-op,CLI 走 hook 链审批`}),d({type:`permission_decision`,description:`审批决策已落审计(结构化条目 + 环形缓冲)`,category:`hook`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,note:`两端已接线(2026-10):Web → useWebSocket 顶层分派 → toastStore;CLI → useStreamHandlers → pushAssistantMessage(落 scrollback 常驻一行,不用 approvalFlash:flash 是「刚点的按钮」的回执,几百毫秒就没)。只提示「没有弹窗」的来源(verdictReason !== user_denied),用户亲手拒绝的不复述。历史面板(/permissions Recently blocked)仍未做。`})]),m([d({type:`mcp_update`,description:`MCP 状态更新`,category:`mcp`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,note:`CLI 已添加 handler(2026-07-01)`})]),m([d({type:`doctor_result`,description:`诊断完成`,category:`diagnostic`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0}),d({type:`degradation`,description:`降级状态更新(遗留)`,category:`diagnostic`,emittedBy:[`none`],handledByCli:!0,handledByWeb:!0,deprecated:!0,note:"已退役(2026-10-26):与 degradation_update 同一件事的旧名,只发 degradation_update。CLI 端那个 handler 本身就先判 `event.type !== 'degradation_update'` 才收,即它吃的就是新名 —— 发旧名等于发了一条会被自己丢掉的事件"}),d({type:`degradation_update`,description:`降级状态更新`,category:`diagnostic`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,note:`发射端(2026-10-26 补):queryEngine 的 5xx 降级分支(shouldDegradeModel → getFallbackModel 命中时)发 active:true / mode:alternative,payload={active,mode,retryCount,maxRetries,message};恢复不收在同一处,而是在「真实产出重新流动」时补一条 active:false / mode:normal(wrappedEmit 内,与 retry 状态复位并列)。成对发、各自只发一次 —— 期间只发过 log 的话,两端都不渲染 log,用户看到的是「模型悄悄换了」`})]),m([d({type:`commands_list`,description:`命令列表(服务器→客户端)`,category:`system`,emittedBy:[`core`,`server`],handledByCli:!0,handledByWeb:!0,note:`CLI 已处理(setDynamicCommands); Web systemHandlers 已处理(2026-08-07)`}),d({type:`ping`,description:`心跳 Ping`,category:`system`,emittedBy:[`client`],handledByCli:!1,handledByWeb:!1,note:`由 Server 的 WS 层自动处理`}),d({type:`pong`,description:`心跳 Pong`,category:`system`,emittedBy:[`server`],handledByCli:!1,handledByWeb:!1,note:`由 Client 的 WS 层自动处理`}),d({type:`hello`,description:`客户端首帧握手`,category:`system`,emittedBy:[`client`],handledByCli:!1,handledByWeb:!1,note:`由 Server rpc/handshake.ts 拦截处理,不进事件总线;web 已接入(services/websocket.ts)。规范见 docs/protocol-compatibility.md`}),d({type:`hello_ack`,description:`首帧握手回执(serverVersion/protocolVersion/capabilities)`,category:`system`,emittedBy:[`server`],handledByCli:!1,handledByWeb:!1,note:`由 Client 的 WS 层拦截处理(web: services/websocket.ts → stores/connectionStore),不进事件总线;capabilities 是 R4 能力门禁的唯一合法依据`}),d({type:`log`,description:`服务端日志`,category:`system`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0}),d({type:`notification`,description:`通知消息`,category:`system`,emittedBy:[`server`],handledByCli:!0,handledByWeb:!0}),d({type:`channel_message`,description:`频道入站消息(转发到 Web UI)`,category:`system`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,note:`CLI 已处理(2026-07-18); Web 已处理(2026-08-07 通知)`}),d({type:`channel_status`,description:`频道连接状态变更`,category:`system`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,note:`CLI 已处理(2026-07-18); Web 已处理(channelsStore)`}),d({type:`channel_error`,description:`频道运行时错误`,category:`system`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,note:`CLI 已处理(2026-07-18); Web 已处理(2026-08-07 通知)。发射端(2026-10-26 补):core 的 ChannelHealthMonitor 重连失败(phase=reconnect)与 ChannelMessageDispatcher 轮询失败(phase=poll)两处,经 runtime.emit 发出;payload = ChannelErrorReport{channelId, channelType, channelName?, error, phase}。⚠️ 一个失败周期只报一次(成功轮询/重连后重新武装),不是每次失败都报 —— 轮询是秒级、重连是分钟级,逐次上报会变成前端 toast 风暴`}),d({type:`todo_update`,description:`待办事项更新`,category:`system`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0}),d({type:`todo_item_done`,description:`待办项完成`,category:`system`,emittedBy:[`none`],handledByCli:!1,handledByWeb:!0,deprecated:!0,note:`已退役:core/server 无发射点(待办统一走 todo_update 全表替换);Web handler 保留兼容`}),d({type:`todo_progress`,description:`待办进度`,category:`system`,emittedBy:[`none`],handledByCli:!1,handledByWeb:!1,deprecated:!0,note:`已退役:core/server 无发射点,CLI 无 handler,Web 侧为空 case`}),d({type:`board_update`,description:`共享工作板更新(作用域 = 工作目录 + 会话类型)`,category:`system`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,note:`BoardTool emit;payload.data 为 {items:[...]} 的 JSON 字符串。板按会话类型分作用域(board/boardBinding.ts),当前 PM 与 user 各有板(channel / thread 没有)。CLI 渲染 BoardPanel,Web 写入 workflowStore(source=board) 复用 TaskBoardWidget`}),d({type:`tombstone`,description:`消息已删除/墓碑`,category:`system`,emittedBy:[`none`],handledByCli:!1,handledByWeb:!1,deprecated:!0,note:`Web/CLI 本地消息删除渲染概念,无 WS 发射端`}),d({type:`status`,description:`状态更新(modelName/connected/statusText)`,category:`system`,emittedBy:[`core`,`server`],handledByCli:!0,handledByWeb:!0,schema:l({modelName:e(),connected:o(),statusText:e()}).partial()}),d({type:`model_name`,description:`当前模型名称`,category:`system`,emittedBy:[`core`,`server`],handledByCli:!0,handledByWeb:!0,schema:l({model:e(),modelRef:e(),source:i([`session`,`mode`,`global`]),data:e()}).partial(),note:`model 顶层裸模型 id;modelRef 为 provider:model 复合身份(同 id 多 provider 去歧义,CLI/Web 状态行 + 模型选择器用);source 标记模型来源 session/mode/global(session = 仅本会话切换)`}),d({type:`models_updated`,description:`模型列表已更新(models.dev 快照刷新后广播)`,category:`system`,emittedBy:[`server`],handledByCli:!0,handledByWeb:!0,note:`app.ts 模型端点写入 / config.yaml 外部变更后全量广播;CLI useAppConnection 重拉并预热列表,Web useWebSocket 转 window 'models-updated'(ModelsView / ModelPicker 监听刷新)。两端接线由 useWebSocket.modelsUpdated.test.tsx 从原始 wire 字节锁定`}),d({type:`throttle`,description:`速率限制状态`,category:`system`,emittedBy:[`core`],handledByCli:!1,handledByWeb:!0,note:`Web 已处理(2026-08-07 toast 提示;走 useWebSocket 的早分派分支,不进 systemHandlers)。发射端(2026-10-26 补):queryEngine 的通用重试分支,仅 category=rate_limit(429)时发,payload={message, category, attempt, maxRetries, retryAfterMs};**一个回合一条**(退避会连续重试多次,逐次发就是 toast 刷屏)。CLI 无 handler 且不需要:终端状态行由同一分支紧跟着的 status(Retrying N/M…) 覆盖,一条 toast 等价物在终端里就是那行字`}),d({type:`code_review_ready`,description:`代码审查结果就绪`,category:`system`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,note:`Web 已处理(2026-08-07 toast 提示)`}),d({type:`pdca_phase`,description:`PDCA 循环阶段`,category:`system`,emittedBy:[`none`],handledByCli:!0,handledByWeb:!1,deprecated:!0,note:`已退役:5-phase light pipeline 被 WorkflowRuntime 取代`}),d({type:`command_start`,description:`命令开始(Web 路由用)`,category:`system`,emittedBy:[`none`],handledByCli:!1,handledByWeb:!0,deprecated:!0,note:`Web systemHandler 有 case 但核心无发送方,保留兼容`}),d({type:`command_complete`,description:`命令完成(Web 路由用)`,category:`system`,emittedBy:[`none`],handledByCli:!1,handledByWeb:!0,deprecated:!0,note:`Web systemHandler 有 case 但核心无发送方,保留兼容`}),d({type:`command_error`,description:`命令错误(Web 路由用)`,category:`system`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,note:`core index.ts:1270 真实 emit;CLI useStreamHandlers:741 与 Web systemHandlers 均已处理`}),d({type:`worktree_service_changed`,description:`worktree 声明的服务已启动/停止(**只是刷新提示,不是状态**)`,category:`system`,emittedBy:[`core`],handledByCli:!1,handledByWeb:!0,intentionalGap:!0,note:"⚠️ **payload 刻意不含 status** —— 状态以 `GET /api/worktree-services` 的查询为准,事件只用来标记「该重拉了」。这是 thread.ts 文件头已经写死的那条不变量(「任何消费方都不能靠事件推导状态,必须以查询快照为准」),照抄而非新立。理由:事件是瞬时的,而「我下午回来看它还活着吗」必须能重新查询。接线:core 侧由 DeepSeekCodeRuntime 把 WorktreeServiceRuntime 的变更监听接到 emit;Web 已接线。CLI 侧未接线(S3 待定),故 intentionalGap 保持 true —— 该 flag 与 handledByCli 被 CLI 接线完整性门禁共用,提前置 false 会把它当成新缺口误报。设计:docs/architecture-design/WORKTREE_SERVICE_STATUS_UI_PLAN.md",schema:l({sessionId:e(),name:e(),action:i([`started`,`stopped`])}).partial()}),d({type:`visual_artifacts_updated`,description:`视觉产物注册表落了新版本(**只是刷新提示,不是状态**)`,category:`system`,emittedBy:[`core`],handledByCli:!1,handledByWeb:!0,intentionalGap:!0,note:"⚠️ payload 只给**地址**(sessionId + logicalId),不给版本号/类型/渲染器等内容 —— 内容以 `GET /api/visual-artifacts` 的查询为准。理由照抄上面 worktree_service_changed:事件是瞬时的,而「我下午回来看它还在不在」必须能重新查询;带上内容就等于同时存在两份真相,必然漂移。两个地址各有各的用处,且**必须都给**:sessionId 是清单刷新键(该会话的「产物」视图),logicalId 是版本链刷新键 —— 链的取数键**不含产者**(身份 = 工作区 + 产物路径,见 visualArtifacts/artifact.ts 文件头),所以「产者会话」与「正在看这条链的会话」可能不是同一个,少给 logicalId 就只能重拉产者自己那个槽。接线:core 侧由 createVisualArtifactRegistrar 的 notify(**落盘成功后**)→ runtime.emit;Web 已接线(useWebSocket → visualArtifactsStore.refreshPublished,只重拉**已持有**的槽与链)。CLI 侧未接线(无「产物」面板),故 intentionalGap 保持 true —— 该 flag 与 handledByCli 被CLI 接线完整性门禁共用,提前置 false 会把它当成新缺口误报(同 worktree_service_changed 的口径)。设计:docs/architecture-design/VISUAL_ARTIFACT_READ_SIDE_PLAN.md §4「实时刷新」行",schema:l({sessionId:e(),logicalId:e()}).partial()})]),m([d({type:`automation.update`,description:`自动化任务新增/更新/删除/状态变更`,category:`automation`,emittedBy:[`server`],handledByCli:!0,handledByWeb:!0,note:`REST /api/automations 已可用;Web 自动化视图消费`}),d({type:`automation.run`,description:`自动化触发运行(started/finished/error)`,category:`automation`,emittedBy:[`core`,`server`],handledByCli:!0,handledByWeb:!0,note:`CLI 状态提示;Web RunDetail 消费`})]),m([d({type:`inbox.delivered`,description:`消息进入收件箱(含来源与唤醒策略;去重合并时也发,payload 标记 merged)`,category:`inbox`,emittedBy:[`core`,`server`],handledByCli:!0,handledByWeb:!0,note:`REST /api/inbox 已可用;Web 收件箱视图消费;CLI 由 InboxPanel 消费`}),d({type:`inbox.wake`,description:`唤醒请求裁决结果(granted/coalesced/deferred/limit/next_drain)`,category:`inbox`,emittedBy:[`core`,`server`],handledByCli:!0,handledByWeb:!0,note:`granted 时触发 drain 会话(复用 automation runner);deferred/limit 需在 UI 可见`}),d({type:`inbox.drained`,description:`会话消化批次完成(处理结果摘要:done/deferred 计数)`,category:`inbox`,emittedBy:[`core`,`server`],handledByCli:!0,handledByWeb:!0,note:`REST POST /api/inbox/complete 回写后广播`})]),m([d({type:`agent_started`,description:`Agent 启动(统一生命周期)`,category:`system`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,note:`AgentRunner.beginLifecycle 注册控制面时 emit;data 携带 agentId/toolCallId/parentAgentId/rootId/depth/sessionId/scope/state/elapsedMs`,schema:l({agentId:e(),toolCallId:e().optional(),parentAgentId:e().optional(),rootId:e().optional(),depth:a().optional(),sessionId:e().optional(),scope:e().optional(),state:e().optional(),elapsedMs:a().optional()}).partial()}),d({type:`agent_progress`,description:`Agent 实时进度(派生行,零 LLM 成本)`,category:`system`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,note:`AgentRunner 包装 onProgress 节流(≥1s 或轮次变化穿透)后 emit;data 携带 agentId/toolCallId/iteration{current,max}/tools{current,recent}/lastContent/elapsedMs`,schema:l({agentId:e(),toolCallId:e().optional(),iteration:l({current:a(),max:a().optional()}).optional(),tools:l({current:e().optional(),recent:s(e()).optional()}).optional(),lastContent:e().optional(),elapsedMs:a().optional(),totalTokens:a().optional()}).partial()}),d({type:`agent_completed`,description:`Agent 正常完成`,category:`system`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,note:`AgentRunner endLifecycle(status=completed)时 emit`,schema:l({agentId:e(),toolCallId:e().optional(),scope:e().optional(),state:e().optional(),elapsedMs:a().optional()}).partial()}),d({type:`agent_cancelled`,description:`Agent 被用户/控制面停止(partial result 已返回)`,category:`system`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,note:`AgentRunner endLifecycle(status=cancelled)时 emit;detail 携带停止原因。语义 = 停止工作、整理已有发现,partial result 已随工具结果回传父 agent`,schema:l({agentId:e(),toolCallId:e().optional(),scope:e().optional(),state:e().optional(),elapsedMs:a().optional(),detail:e().optional()}).partial()}),d({type:`agent_failed`,description:`Agent 失败/超时/被硬杀`,category:`system`,emittedBy:[`core`],handledByCli:!0,handledByWeb:!0,note:`AgentRunner endLifecycle(status=error/timeout/max_iterations/budget_exceeded)或 kill 时 emit;error 携带原因`,schema:l({agentId:e(),toolCallId:e().optional(),scope:e().optional(),state:e().optional(),elapsedMs:a().optional(),error:e().optional()}).partial()})]);var _=i([`info`,`action_required`,`error`]),v={threadId:e(),runId:e().optional(),alias:e().optional(),severity:_.optional(),dedupKey:e().optional()};m([d({type:`thread_started`,description:`Thread 开始执行`,category:`thread`,emittedBy:[`core`],handledByCli:!1,handledByWeb:!0,intentionalGap:!0,note:`P0-A 立契约;P1 由 ThreadScheduler 发射。replyMode:batch,不进 outbox(易失可接受)`,schema:l({...v,source:e().optional(),model:e().optional(),branch:e().optional(),worktreePath:e().optional(),cwd:e().optional()}).partial()}),d({type:`thread_progress`,description:`Thread 中间进度(派生行,零 LLM 成本)`,category:`thread`,emittedBy:[`core`],handledByCli:!1,handledByWeb:!0,intentionalGap:!0,note:`P0-A 立契约;P1 由 RuntimeNotification 经 dispatcher 出口发射。⚠️ payload 摘要必须自带上界 ≤600 字符(对齐 goalNotifier.MAX_RESULT_CHARS),否则 batch 的 4000 字闸在合并多条后会立刻触发。replyMode:batch,不进 outbox`,schema:l({...v,summary:e().optional(),round:a().optional(),maxRounds:a().optional(),currentTool:e().optional(),elapsedMs:a().optional()}).partial()}),d({type:`thread_checkpoint`,description:`Thread 到达检查点(瞬态通知,**不是**状态)`,category:`thread`,emittedBy:[`core`],handledByCli:!1,handledByWeb:!0,intentionalGap:!0,note:`⚠️ 这是**通知事件**,不是 ThreadStatus 的取值(v9.1 §3.2(a):v9 曾把它写进状态枚举,导致 watcher 无法判断『还能不能 await』;处于 checkpoint 的 thread 实际仍是 RUNNING/PAUSED)`,schema:l({...v,checkpointId:e().optional(),label:e().optional(),resumable:o().optional()}).partial()}),d({type:`thread_completed`,description:`Thread 正常完成(全部 Run 终态)`,category:`thread`,emittedBy:[`core`],handledByCli:!1,handledByWeb:!0,intentionalGap:!0,note:`进 outbox + replyMode:immediate —— detach 后这是用户**唯一**的结果来源(v9.1 §10 约束②)`,schema:l({...v,summary:e().optional(),artifactCount:a().optional(),durationMs:a().optional()}).partial()}),d({type:`thread_failed`,description:`Thread 失败(Run 报错 / 审批超时且高风险 / 预算终止)`,category:`thread`,emittedBy:[`core`],handledByCli:!1,handledByWeb:!0,intentionalGap:!0,note:`进 outbox + replyMode:immediate(同 thread_completed,结果必须送达)`,schema:l({...v,error:e().optional(),reason:i([`run_error`,`approval_expired`,`budget_exceeded`,`interrupted`,`unknown`]).optional()}).partial()}),d({type:`thread_artifact`,description:`Thread 产出 Artifact(§3.4 的 Manifest 条目落定)`,category:`thread`,emittedBy:[`core`],handledByCli:!1,handledByWeb:!0,intentionalGap:!0,note:"replyMode:batch。⚠️ `id` 逐次唯一、`logicalId` 跨版本稳定 —— 消费方按 logicalId 归组、按 id 溯源(v9.1 §3.4:只有 id+version 时语义二义)。接线进展(P0-C A2):**core 侧已有 emitter** —— 产者用 `register_thread_artifact` 登记,经 ArtifactManifest 落定后由宿主出口发出(artifactStore 自己不发,§10 约束①)。消费端:Web 的项目「库」面板(`scheduleLibraryRefresh`)订阅本事件去**重拉**,事件只作提示、内容以 `GET /api/projects/:id/library` 为准(400ms 合并窗口,库未打开时零请求);CLI 侧仍无消费方,故 `intentionalGap` 保持 true;payload.locator 刻意不含 `content`(schema 无此字段,且正文由 path/commit 指过去)",schema:l({...v,artifactId:e().optional(),logicalId:e().optional(),version:a().optional(),producerRunId:e().optional(),artifactType:i([`patch`,`test-report`,`decision`,`design`,`benchmark`]).optional(),status:i([`draft`,`pending_review`,`approved`,`published`,`deprecated`]).optional(),locator:l({commit:e().optional(),files:s(e()).optional(),path:e().optional(),messageIds:s(e()).optional()}).partial().optional()}).partial()}),d({type:`thread_cost`,description:`Thread 成本汇总(token / 轮次)`,category:`thread`,emittedBy:[`core`],handledByCli:!1,handledByWeb:!0,intentionalGap:!0,note:`replyMode:batch,不进 outbox。数据源 = provider 返回的 usage,与预算强制点(§3.5)同处采集,不重复埋点。预算按 **Run** 计数(Thread 1:N Run,retry 应重置预算)`,schema:l({...v,tokensIn:a().optional(),tokensOut:a().optional(),rounds:a().optional(),maxTokens:a().optional(),utilization:a().optional()}).partial()}),d({type:`approval_expired`,description:`审批单据已失效(重启 sweep 或 TTL 到期)`,category:`thread`,emittedBy:[`core`],handledByCli:!1,handledByWeb:!0,intentionalGap:!0,note:"进 outbox + replyMode:immediate。作用是**清理悬空单据**:`permissions.ts` 的 pending Map 在内存,进程重启后 IM 侧那条『请回复 批准/拒绝』仍在,用户回复会落进『不认』分支 = 静默失败。发这条让它显式失效(v9.1 §8.2b)",schema:l({...v,approvalId:e().optional(),toolName:e().optional(),risk:e().optional(),expiredAt:e().optional(),cause:i([`ttl`,`restart`]).optional()}).partial()})]);var ne=i([`info`,`action_required`,`error`]),re=[`task-terminal`,`goal-raised`,`review-resolved`,`approval-resolved`,`escalation-raised`,`user-message`,`heartbeat-stall`,`alarm`],y={projectKey:e(),pmThreadId:e().optional(),runId:e().optional(),severity:ne.optional(),dedupKey:e().optional()};m([d({type:`pm_started`,description:`项目经理开始值守(启用/恢复)`,category:`pm`,emittedBy:[`core`],handledByCli:!1,handledByWeb:!0,intentionalGap:!0,note:`replyMode:batch(⚠️ 目标口径,见文件头注②),不进 outbox。项目页据此渲染 PM 面板的『值守中』态`,schema:l({...y,enabledBy:i([`user`,`im`,`config`,`restart`]).optional()}).partial()}),d({type:`pm_wakeup`,description:`项目经理被唤醒(事件驱动 turn 开始)`,category:`pm`,emittedBy:[`core`],handledByCli:!1,handledByWeb:!0,intentionalGap:!0,note:`replyMode:batch(⚠️ 目标口径,见文件头注②),不进 outbox(高频易失)。默认层只展示一行『被 X 唤醒』,合并窗口细节走 debug 日志`,schema:l({...y,reason:i(re).optional(),summary:e().optional()}).partial()}),d({type:`pm_report`,description:`项目经理进度汇报`,category:`pm`,emittedBy:[`core`],handledByCli:!1,handledByWeb:!0,intentionalGap:!0,note:`replyMode:batch(⚠️ 目标口径,见文件头注②),不进 outbox。IM 出向经 dispatcher(照 goalNotifier 模式);各摘要字段 ≤600 字符(文件头注③)`,schema:l({...y,title:e().optional(),progressSummary:e().optional(),blockers:e().optional(),nextAction:e().optional(),approvalsPending:a().optional(),route:l({kind:i([`answer`,`thread`,`goal`,`handoff`,`approval`,`session`]),refs:l({goalId:e().optional(),threadIds:s(e()).optional(),projectKey:e().optional()}).optional(),suggest:l({title:e(),seed:e().optional()}).optional(),reason:e()}).optional()}).partial()}),d({type:`pm_approval_requested`,description:`项目经理发起审批(L1 必审动作)`,category:`pm`,emittedBy:[`core`],handledByCli:!1,handledByWeb:!0,intentionalGap:!0,note:`replyMode:immediate(⚠️ 目标口径,见文件头注②:outbox 尚未实现)。action_required 不能被合并进 30s 窗口(v9.1 §10)。底层复用 escalation:escalationId 即 REST 裁决门 POST /api/threads/escalations/:id/resolve 的 id`,schema:l({...y,escalationId:e().optional(),title:e().optional(),summary:e().optional(),requestedAction:e().optional(),reason:i([`budget-exceeded`,`policy`,`external-send`]).optional()}).partial()}),d({type:`pm_approval_resolved`,description:`项目经理审批已决议(批准/拒绝)`,category:`pm`,emittedBy:[`core`],handledByCli:!1,handledByWeb:!0,intentionalGap:!0,note:`replyMode:immediate(⚠️ 目标口径,见文件头注②)。终态通知必须送达。决议同时触发 coordinatorWakeup(approval-resolved)唤醒 PM 继续或放弃`,schema:l({...y,escalationId:e().optional(),decision:i([`approved`,`rejected`]).optional(),comment:e().optional()}).partial()}),d({type:`pm_stopped`,description:`项目经理停止值守`,category:`pm`,emittedBy:[`core`],handledByCli:!1,handledByWeb:!0,intentionalGap:!0,note:`replyMode:immediate(⚠️ 目标口径,见文件头注②)。停止后不再唤醒;在跑 turn 自然结束;执行线程不受影响`,schema:l({...y,cause:i([`user`,`project-archived`,`error`]).optional()}).partial()}),d({type:`pm_duty_changed`,description:`全局值守经理(总经理)席位变更(选任/转回前台)`,category:`pm`,emittedBy:[`core`],handledByCli:!1,handledByWeb:!0,intentionalGap:!0,note:`replyMode:batch(⚠️ 目标口径,见文件头注②),不进 outbox。全局唯一席位的选任/清空(spec 2026-09-26);dutyProjectKey 为空 = 转回前台(席位空缺)。Web 经理名册据此翻转值守徽标`,schema:l({...y,dutyProjectKey:e().nullable().optional(),previousProjectKey:e().nullable().optional()}).partial()})]);var b=e().min(1).max(128).regex(/^[a-z][a-z0-9._-]*$/,`command id must match ^[a-z][a-z0-9._-]*$`);l({id:e().min(1).max(128),command:b,payload:t().optional(),timeoutMs:a().int().positive().max(3e5).optional(),sender:e().max(128).optional()}),l({success:o(),requestId:e(),command:b,result:t().optional(),error:e().optional(),durationMs:a().min(0).optional()});var x=l({capability:b,command:b,description:e().max(500).optional(),provider:e().max(128).optional()});l({version:u(`1`),capabilities:s(x)});var S=l({version:u(`1`),type:i([`ready`,`select`,`inspect`,`screenshot`,`highlight`,`command`,`event`]),requestId:e().min(1).max(128),payload:t().optional()}).passthrough();l({type:e().min(1).max(128).regex(/^[a-z][a-z0-9._-]*$/,`event type must match ^[a-z][a-z0-9._-]*$`),payload:t().optional(),source:e().max(128).optional(),timestamp:a().nonnegative().optional()}),l({type:u(`workspace_event`),sessionId:e().optional(),data:r([e(),S]).optional(),traceId:e().optional()});var ie=f.map(e=>({eventType:e.type,description:e.description,category:e.category,emittedBy:e.emittedBy,handledByCli:e.handledByCli,handledByWeb:e.handledByWeb,...e.deprecated===void 0?{}:{deprecated:e.deprecated},...e.intentionalGap===void 0?{}:{intentionalGap:e.intentionalGap},...e.note===void 0?{}:{note:e.note}})),C=[`none`,`minimal`,`low`,`medium`,`high`,`xhigh`,`max`,`ultra`,`persistent`];C.filter(e=>e!==`ultra`&&e!==`persistent`);var w={off:`none`,disable:`none`,disabled:`none`,no:`none`,extra_high:`xhigh`,"extra-high":`xhigh`,extrahigh:`xhigh`,very_high:`xhigh`,"very-high":`xhigh`,x_high:`xhigh`,"x-high":`xhigh`,default:`medium`};new Set(C);function T(e){if(typeof e!=`string`)return;let t=e.trim().toLowerCase();if(t)return w[t]??t}function E(e){return e===`ultra`?`max`:e===`persistent`?`disabled`:e}var D=[`off`,`low`,`medium`,`high`,`extra_high`,`max`],ae={off:{level:`off`,wire:`none`,label:`OFF`,hint:`关闭思考(wire: none)`},low:{level:`low`,wire:`low`,label:`LOW`,hint:`最省 token,适合一句话就能答的活`},medium:{level:`medium`,wire:`medium`,label:`MED`,hint:`默认档(wire 上等价于不指定)`},high:{level:`high`,wire:`high`,label:`HIGH`,hint:`高:复杂重构、长链路排查`},extra_high:{level:`extra_high`,wire:`xhigh`,label:`XHIGH`,hint:`超高:难调试的并发/跨包改动`},max:{level:`max`,wire:`max`,label:`MAX`,hint:`最高:最难的问题,更慢也更贵`}};function O(e){return typeof e==`string`&&D.includes(e)}function oe(e,t=`medium`){return O(e)?e:t}function se(e){let t=T(e);if(t===void 0)return;let n=E(t);if(n===`none`||n===`disabled`)return`off`;if(n===`minimal`||n===`low`)return`low`;if(n===`medium`)return`medium`;if(n===`high`)return`high`;if(n===`xhigh`)return`extra_high`;if(n===`max`)return`max`}function ce(e,t){let n=D.indexOf(e)+t;return n<0?D[0]:n>=D.length?D[D.length-1]:D[n]}var k=[{code:`zh`,name:`Simplified Chinese`,native:`简体中文`},{code:`en`,name:`English`,native:`English`},{code:`ja`,name:`Japanese`,native:`日本語`},{code:`ko`,name:`Korean`,native:`한국어`},{code:`de`,name:`German`,native:`Deutsch`},{code:`fr`,name:`French`,native:`Français`},{code:`es`,name:`Spanish`,native:`Español`},{code:`pt`,name:`Portuguese`,native:`Português`},{code:`ru`,name:`Russian`,native:`Русский`},{code:`it`,name:`Italian`,native:`Italiano`},{code:`ar`,name:`Arabic`,native:`العربية`},{code:`id`,name:`Indonesian`,native:`Bahasa Indonesia`}].map(e=>e.code);function A(e){return typeof e==`string`&&k.includes(e)}var j=[`1`];function M(e){return j.includes(e)}var N={maxFields:12,maxOptions:20,maxIdChars:40,maxTitleChars:120,maxSubmitLabelChars:20,maxLabelChars:60,maxHelpChars:200,maxPlaceholderChars:80,maxDescriptionChars:4e3,maxTextValueChars:2e4,maxAcceptChars:120,maxFiles:5,maxFileSizeMb:10,maxAnswerBytes:524288},P=/^f-[0-9]{8}-[0-9]{1,6}$/;function F(e){return typeof e==`string`&&P.test(e)}var I=`.agent/forms`,L=`.agent/uploads`;function R(e){return`${I}/${e}.answer.json`}function z(e){return`${L}/${e}`}var B=[`text`,`textarea`,`number`,`select`,`multi`,`boolean`,`date`,`file`];function V(e){switch(e.kind){case`number`:return null;case`boolean`:return!1;case`multi`:case`file`:return[];default:return``}}function H(e){return e==null?!0:typeof e==`string`?e.trim()===``:Array.isArray(e)?e.length===0:!1}function U(e){return e.maxLength??N.maxTextValueChars}function le(e){return e.maxSizeMb??N.maxFileSizeMb}var W=[`native`],ue=/^[A-Za-z_][A-Za-z0-9_]{0,39}$/,de=new Set(B);function G(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function K(e){return typeof e==`number`&&Number.isFinite(e)}function fe(e){let t;try{t=JSON.parse(e)}catch{return{ok:!1,issues:[{code:`descriptor.not_json`}]}}return q(t)}function q(e){if(!G(e))return{ok:!1,issues:[{code:`descriptor.not_object`}]};let t=[];e.type!==`form`&&t.push({code:`descriptor.bad_type`,value:Q(e.type)});let n=e.renderer;typeof n==`string`&&W.includes(n)||t.push({code:`descriptor.bad_renderer`,value:Q(n)});let r=e.version;typeof r==`string`&&M(r)||t.push({code:`descriptor.bad_version`,value:Q(r)});let i=e.source;if(!G(i))return t.push({code:`descriptor.bad_source`}),{ok:!1,issues:t};F(i.id)||t.push({code:`descriptor.bad_id`,value:Q(i.id)}),(typeof i.sessionId!=`string`||i.sessionId.trim()===``)&&t.push({code:`descriptor.bad_session`});let a=X(i.title,N.maxTitleChars,t),o=Z(i.description,N.maxDescriptionChars,`description`,t),s=Z(i.submitLabel,N.maxSubmitLabelChars,`submitLabel`,t),c=pe(i.fields,t);if(t.length>0)return{ok:!1,issues:t};let l={id:i.id,sessionId:i.sessionId,title:a,fields:c};return o!==void 0&&(l.description=o),s!==void 0&&(l.submitLabel=s),{ok:!0,value:{type:`form`,renderer:n,version:`1`,source:l}}}function pe(e,t){if(!Array.isArray(e)||e.length===0)return t.push({code:`descriptor.no_fields`}),[];e.length>N.maxFields&&t.push({code:`descriptor.too_many_fields`,limit:N.maxFields,actual:e.length});let n=[],r=new Set;return e.slice(0,N.maxFields).forEach((e,i)=>{let a=me(e,i,r,t);a&&n.push(a)}),n}function me(e,t,n,r){if(!G(e))return r.push({code:`descriptor.field_not_object`,fieldIndex:t}),null;let i=e.id;if(typeof i!=`string`||i.length>N.maxIdChars||!ue.test(i))return r.push({code:`descriptor.bad_field_id`,fieldIndex:t,value:Q(i)}),null;if(n.has(i))return r.push({code:`descriptor.duplicate_field_id`,fieldId:i}),null;n.add(i);let a=e.kind;if(typeof a!=`string`||!de.has(a))return r.push({code:`descriptor.bad_kind`,fieldId:i,fieldIndex:t,value:Q(a)}),null;let o=X(e.label,N.maxLabelChars,r,i);if(o===null)return null;let s={id:i,label:o};e.required!==void 0&&(typeof e.required==`boolean`?s.required=e.required:r.push({code:`descriptor.bad_required`,fieldId:i}));let c=Z(e.help,N.maxHelpChars,`help`,r,i);c!==void 0&&(s.help=c);let l=Z(e.placeholder,N.maxPlaceholderChars,`placeholder`,r,i);switch(l!==void 0&&(s.placeholder=l),a){case`text`:return{...s,...J(e,i,r),kind:`text`};case`textarea`:return{...s,...J(e,i,r),kind:`textarea`};case`number`:return{...s,...he(e,i,r),kind:`number`};case`select`:return{...s,...Y(e,i,r),kind:`select`};case`multi`:return{...s,...Y(e,i,r),kind:`multi`};case`boolean`:return{...s,kind:`boolean`};case`date`:return{...s,kind:`date`};case`file`:return{...s,...ge(e,i,r),kind:`file`}}}function J(e,t,n){let r=e.maxLength;return r===void 0?{}:!K(r)||r<=0||r>N.maxTextValueChars?(n.push({code:`descriptor.bad_limit`,fieldId:t,value:`maxLength`}),{}):{maxLength:Math.floor(r)}}function he(e,t,n){let r={};for(let i of[`min`,`max`,`step`]){let a=e[i];a!==void 0&&(!K(a)||i===`step`&&a<=0?n.push({code:`descriptor.bad_limit`,fieldId:t,value:i}):r[i]=a)}return r.min!==void 0&&r.max!==void 0&&r.min>r.max&&n.push({code:`descriptor.bad_limit`,fieldId:t,value:`min>max`}),r}function Y(e,t,n){let r=e.options;if(!Array.isArray(r)||r.length===0)return n.push({code:`descriptor.missing_options`,fieldId:t}),{options:[]};r.length>N.maxOptions&&n.push({code:`descriptor.too_many_options`,fieldId:t,limit:N.maxOptions,actual:r.length});let i=[],a=new Set;for(let e of r)typeof e!=`string`||e.trim()===``||e.length>N.maxLabelChars?n.push({code:`descriptor.bad_option`,fieldId:t,value:Q(e)}):a.has(e)?n.push({code:`descriptor.duplicate_option`,fieldId:t,value:e}):(a.add(e),i.push(e));return{options:i}}function ge(e,t,n){let r={},i=e.accept;i!==void 0&&(typeof i!=`string`||i.length>N.maxAcceptChars?n.push({code:`descriptor.bad_file_limit`,fieldId:t,value:`accept`}):i.trim()!==``&&(r.accept=i));let a=e.maxSizeMb;return a!==void 0&&(!K(a)||a<=0||a>N.maxFileSizeMb?n.push({code:`descriptor.bad_file_limit`,fieldId:t,value:`maxSizeMb`}):r.maxSizeMb=a),r}function X(e,t,n,r){let i=r?{fieldId:r}:{};return typeof e!=`string`||e.trim()===``?(n.push({code:r===void 0?`descriptor.missing_title`:`descriptor.missing_label`,...i}),null):e.length>t?(n.push({code:r===void 0?`descriptor.title_too_long`:`descriptor.label_too_long`,...i,limit:t,actual:e.length}),null):e}function Z(e,t,n,r,i){if(typeof e==`string`&&e.trim()!==``){if(e.length>t)r.push({code:{description:`descriptor.description_too_long`,submitLabel:`descriptor.submit_label_too_long`,help:`descriptor.help_too_long`,placeholder:`descriptor.placeholder_too_long`}[n],...i?{fieldId:i}:{},limit:t,actual:e.length});else return e}}function Q(e){return typeof e==`string`?e.slice(0,80):e===null?`null`:e===void 0?`undefined`:typeof e==`number`||typeof e==`boolean`?String(e):Array.isArray(e)?`array`:typeof e}var _e=[`openai-chat-completions`,`openai-completions`,`openai-responses`,`anthropic-messages`,`codex-responses`,`claude-code`],ve=[`mode_instruction`,`session_mentions`,`retry_instruction`,`system_stable`,`system_dynamic`,`memory_injection`,`session_memory_summary`,`pm_wakeup_context`,`thread_task_context`,`turn_reminder`];function $(e){return typeof e==`string`&&ve.includes(e)}var ye=/^<([a-z][a-z-]*)-reminder>/;function be(e){if(typeof e!=`string`)return;let t=ye.exec(e.trimStart());return t?t[1]:void 0}function xe(e){if($(e.kind))return!0;if(e.type!==`system`||typeof e.content!=`string`)return!1;let t=e.content.trimStart();return t.startsWith(`[Session Memory Summary]`)||be(t)!==void 0}ie.map(e=>e.eventType);export{ce as S,D as _,q as a,se as b,le as c,N as d,R as f,A as g,F as h,fe as i,H as l,M as m,xe as n,V as o,z as p,$ as r,U as s,_e as t,I as u,ae as v,O as x,oe as y};
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{i as e}from"./rolldown-runtime-COiEfhsA.js";import{bn as t,ni as n}from"./icons-B8Ngx6rM.js";import{t as r}from"./useTranslation-gGKZZfux.js";import{m as i}from"./imageUrl-CrQM4gmf.js";import{r as a}from"./Button-D-g7PgYh.js";import{S as o,_ as s,v as c,y as l}from"./src-BK8SoTFV.js";import{A as u,E as d,r as f}from"./settingsStore-BSdi9gNd.js";import{I as p}from"./markdown-Cps-36Z5.js";import{n as m}from"./websocket-CeKJTCdp.js";function h(e){return(String(e??``).trim().toLowerCase().split(/[-_]/)[0]??``)||`en`}var g=e(n(),1),_={off:`chat.effortOff`,low:`chat.effortLow`,medium:`chat.effortMedium`,high:`chat.effortHigh`,extra_high:`chat.effortExtraHigh`,max:`chat.effortMax`},v={off:`text-dark-muted`,low:`text-accent-green`,medium:`text-accent-yellow`,high:`text-accent-red`,extra_high:`text-accent-purple`,max:`text-accent-blue`},y=Object.fromEntries(Object.keys(_).map(e=>[e,{labelKey:_[e],color:v[e]}])),b=p(),x=s.filter(e=>e!==`off`),S=s.length-1,C=(0,g.memo)(function({syncSession:e=!0}){let{t:n}=r(),u=f(e=>e.effort),d=l(u),p=y[d],h=s.indexOf(d),_=c[d],v=(0,g.useRef)(null),C=(0,g.useCallback)(t=>{if(f.getState().setEffort(t),!e)return;let n=i.getState().activeSessionId;n&&m.setSessionId(n),m.send({type:`effort_set`,sessionId:n??void 0,data:JSON.stringify({effort:t})})},[e]),w=(0,g.useCallback)(e=>{let t=e.shiftKey||e.altKey?-1:1,n=o(l(f.getState().effort),t);n!==d&&C(n)},[C,d]),T=(0,g.useRef)(0);(0,g.useEffect)(()=>{let e=v.current;if(!e)return;let t=e=>{let t=Math.abs(e.deltaY)>=Math.abs(e.deltaX)?e.deltaY:0;if(t===0||(e.preventDefault(),T.current+=t,Math.abs(T.current)<30))return;let n=T.current>0?1:-1;T.current=0,C(o(l(f.getState().effort),n>0?-1:1))};return e.addEventListener(`wheel`,t,{passive:!1}),()=>e.removeEventListener(`wheel`,t)},[C]);let E=(0,g.useCallback)(e=>{let t=l(f.getState().effort),n=n=>{e.preventDefault(),C(o(t,n))};switch(e.key){case`ArrowUp`:case`ArrowRight`:n(1);break;case`ArrowDown`:case`ArrowLeft`:n(-1);break;case`Home`:e.preventDefault(),C(s[0]);break;case`End`:e.preventDefault(),C(s[S])}},[C]),D=[`${n(`chat.effort`)} ${h}/${S} · ${n(p.labelKey)} — ${_.hint}`,`wire: ${_.wire}${d===`medium`?` — ${n(`chat.effortImplicitHint`)}`:``}`,n(`chat.effortChipHint`)];return(0,b.jsxs)(`div`,{ref:v,role:`slider`,tabIndex:0,"data-testid":`effort-chip`,onClick:w,onKeyDown:E,title:D.join(`
|
|
2
|
-
`),"aria-label":n(`chat.effortChipAria`,{level:n(p.labelKey)}),"aria-valuemin":0,"aria-valuemax":S,"aria-valuenow":h,"aria-valuetext":`${n(p.labelKey)} (${h}/${S})`,className:`flex h-8 shrink-0 cursor-pointer items-center gap-1 rounded-full border border-dark-border bg-dark-surface px-2.5 text-meta font-medium transition-colors outline-none select-none hover:bg-dark-hover focus-visible:ring-1 focus-visible:ring-accent-yellow/60`,children:[(0,b.jsx)(t,{size:12,className:a(`shrink-0`,p.color),"aria-hidden":`true`}),(0,b.jsx)(`span`,{className:a(`flex items-end gap-[2px]`,p.color),"aria-hidden":`true`,children:x.map((e,t)=>{let n=h>=t+1;return(0,b.jsx)(`span`,{onClick:t=>{t.stopPropagation(),C(e)},className:a(`w-[3px] rounded-sm transition-colors`,n?`bg-current`:`bg-dark-border hover:bg-dark-muted/60`),style:{height:5+t*2}},e)})}),(0,b.jsx)(`span`,{className:p.color,children:n(p.labelKey)})]})}),w=[{code:`en`,label:`English`,short:`EN`},{code:`zh`,label:`中文`,short:`中`},{code:`ja`,label:`日本語`,short:`JA`},{code:`ko`,label:`한국어`,short:`KO`},{code:`fr`,label:`Français`,short:`FR`},{code:`de`,label:`Deutsch`,short:`DE`},{code:`es`,label:`Español`,short:`ES`},{code:`ru`,label:`Русский`,short:`RU`},{code:`pt`,label:`Português`,short:`PT`},{code:`it`,label:`Italiano`,short:`IT`}],T=`dsc.stt.lang`,E=new Set(w.map(e=>e.code));function D(e){let t=(e??``).trim().toLowerCase();return E.has(t)?t:null}function O(e){return D(e)??`en`}function k(e){return w.find(t=>t.code===e)??{code:`en`,label:`English`,short:`EN`}}function A(e){return O(h(e))}function j(){try{let e=D(localStorage.getItem(T));if(e)return e}catch{}let e=d;try{e=u(f.getState().language)}catch{}return A(e)}function M(e){try{localStorage.setItem(T,e)}catch{}}export{k as a,j as i,O as n,C as o,M as r,y as s,w as t};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{i as e}from"./rolldown-runtime-COiEfhsA.js";import{n as t,ni as n}from"./icons-B8Ngx6rM.js";import{t as r}from"./useTranslation-gGKZZfux.js";import{n as i,r as a,t as o}from"./Button-D-g7PgYh.js";import{I as s}from"./markdown-Cps-36Z5.js";var c=e(n(),1),l=0,u=``;function d(){l===0&&(u=document.body.style.overflow),l+=1,document.body.style.overflow=`hidden`}function f(){l=Math.max(0,l-1),l===0&&(document.body.style.overflow=u)}var p=[];function m({isOpen:e,onClose:t,lockScroll:n=!0}){let r=(0,c.useRef)(t);(0,c.useEffect)(()=>{r.current=t}),(0,c.useEffect)(()=>{if(!e)return;let t=Symbol(`overlay`);p.push(t);let i=e=>{e.key===`Escape`&&p[p.length-1]===t&&(e.defaultPrevented||(e.preventDefault(),e.stopPropagation(),r.current()))};return document.addEventListener(`keydown`,i,!0),n&&d(),()=>{document.removeEventListener(`keydown`,i,!0);let e=p.indexOf(t);e>=0&&p.splice(e,1),n&&f()}},[e,n])}var h=s(),g=`a[href],button:not([disabled]),textarea:not([disabled]),input:not([disabled]),select:not([disabled]),[tabindex]:not([tabindex="-1"])`;function _(e){let t=(0,c.useRef)(null);return(0,c.useEffect)(()=>{if(!e)return;let n=t.current;if(!n)return;let r=document.activeElement,i=()=>Array.from(n.querySelectorAll(g)),a=n.querySelector(`[data-modal-body]`);(n.querySelector(`[data-autofocus]`)??(a?a.querySelector(g):null)??i()[0]??n).focus();let o=e=>{if(e.key!==`Tab`)return;let t=i();if(t.length===0){e.preventDefault(),n.focus();return}let r=t[0],a=t[t.length-1],o=document.activeElement,s=o!==null&&n.contains(o);e.shiftKey?s&&o!==r||(e.preventDefault(),a.focus()):s&&o!==a||(e.preventDefault(),r.focus())};return document.addEventListener(`keydown`,o),()=>{document.removeEventListener(`keydown`,o),r&&typeof r.focus==`function`&&r.focus()}},[e]),t}function v({isOpen:e,onClose:n,title:r,children:o,size:s=`md`,className:l,bodyClassName:u=`p-6`}){m({isOpen:e,onClose:n});let{visible:d,phase:f}=i(e),p=(0,c.useId)(),g=_(d);return d?(0,h.jsxs)(`div`,{className:`fixed inset-0 z-50 flex items-center justify-center overflow-hidden p-4`,children:[(0,h.jsx)(`div`,{className:`absolute inset-0 ui-scrim ui-overlay-backdrop`,"data-phase":f,onClick:n}),(0,h.jsxs)(`div`,{ref:g,role:`dialog`,"aria-modal":`true`,"aria-labelledby":r?p:void 0,"data-phase":f,tabIndex:-1,className:a(`relative w-full mx-4 bg-dark-overlay ui-surface-overlay border border-dark-border rounded-xl shadow-pop ui-overlay-panel`,`max-h-[calc(100vh-2rem)] flex flex-col overflow-hidden`,{sm:`max-w-sm`,md:`max-w-md`,lg:`max-w-lg`,xl:`max-w-xl`,"2xl":`max-w-3xl`,"3xl":`max-w-5xl`}[s],l),children:[r&&(0,h.jsxs)(`div`,{className:`flex shrink-0 items-center justify-between px-6 py-4 border-b border-dark-border`,children:[(0,h.jsx)(`h2`,{id:p,className:`text-lg font-semibold text-dark-text`,children:r}),(0,h.jsx)(`button`,{onClick:n,"aria-label":`Close`,className:`p-1 rounded-lg text-dark-muted hover:text-dark-text hover:bg-dark-hover transition-colors`,children:(0,h.jsx)(t,{className:`w-5 h-5`,"aria-hidden":`true`})})]}),(0,h.jsx)(`div`,{"data-modal-body":!0,className:a(`min-h-0 overflow-y-auto custom-scrollbar`,u),children:o})]})]}):null}function y({isOpen:e,onClose:t,onConfirm:n,title:i,message:a,confirmText:s,cancelText:c,variant:l=`default`}){let{t:u}=r();return(0,h.jsxs)(v,{isOpen:e,onClose:t,title:i??u(`common.confirm`),size:`sm`,children:[(0,h.jsx)(`p`,{className:`text-dark-muted mb-6`,children:a}),(0,h.jsxs)(`div`,{className:`flex gap-3 justify-end`,children:[(0,h.jsx)(o,{onClick:t,children:c??u(`common.cancel`)}),(0,h.jsx)(o,{variant:l===`danger`?`danger`:`accent`,onClick:()=>{n(),t()},children:s??u(`common.confirm`)})]})]})}function b(){let[e,t]=(0,c.useState)(null),n=(0,c.useRef)(null),r=(0,c.useCallback)(e=>{let r=n.current;n.current=null,t(null),r?.(e)},[]),i=(0,c.useCallback)(e=>{let r=n.current;return n.current=null,r?.(!1),new Promise(r=>{n.current=r,t(e)})},[]);return[e?(0,h.jsx)(y,{isOpen:!0,onClose:()=>r(!1),onConfirm:()=>r(!0),title:e.title,message:e.message,confirmText:e.confirmText,cancelText:e.cancelText,variant:e.variant}):null,i]}export{m as i,y as n,v as r,b as t};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{n as e}from"./state-pOTP5BEk.js";import"./src-BK8SoTFV.js";var t=e()(e=>({serverVersion:null,protocolVersion:null,capabilities:[],setHelloAck:t=>e({serverVersion:t.serverVersion||null,protocolVersion:t.protocolVersion||null,capabilities:t.capabilities})}));function n(){return`err-${Date.now()}-${Math.random().toString(36).slice(2,7)}`}var r=e(e=>({errors:[],push:(t,r,i,a,o)=>{let s=``;return e(e=>{let c=e.errors.find(e=>!e.dismissed&&!e.action&&e.level===t&&e.title===r);if(c)return s=c.id,{errors:e.errors.map(e=>e.id===c.id?{...e,count:e.count+1,timestamp:Date.now()}:e)};let l=n();s=l;let u={id:l,level:t,title:r,detail:i,action:a,timestamp:Date.now(),dismissed:!1,durationMs:o,count:1};return{errors:[...e.errors.slice(-49),u]}}),s},dismiss:t=>e(e=>({errors:e.errors.map(e=>e.id===t?{...e,dismissed:!0}:e)})),clearAll:()=>e({errors:[]})})),i={info:(e,t,n)=>r.getState().push(`info`,e,t,void 0,n),warn:(e,t,n)=>r.getState().push(`warning`,e,t,void 0,n),error:(e,t,n)=>r.getState().push(`error`,e,t,void 0,n),critical:(e,t,n)=>r.getState().push(`critical`,e,t,void 0,n)},a=20,o=15e3,s=[500,1e3,2e3,5e3,1e4,o],c=3,l=`dscode_pending_frames`,u=new Set([`question_answer`,`hook_allow`,`hook_deny`,`form_answer`]),d=new Set([`get_workflow_status`,`get_commands`]);function f(){try{let e=localStorage.getItem(l);if(!e)return[];let t=JSON.parse(e);if(!Array.isArray(t))return[];let n=Date.now()-6e5;return t.filter(e=>!!e&&typeof e.type==`string`&&u.has(e.type)&&typeof e.queuedAt==`number`&&e.queuedAt>=n)}catch{return[]}}function p(e){try{localStorage.setItem(l,JSON.stringify(e.slice(-20)))}catch{}}var m=()=>{let e=window.location.protocol===`https:`?`wss:`:`ws:`,t=window.location.hostname,n=window.location.port,r=n?String(Number(n)+1):``;return`${e}//${r?`${t}:${r}`:t}/ws`},h=m(),g=`dscode_client_id`;function _(){try{let e=localStorage.getItem(g);if(e)return e;let t=`web-${typeof crypto<`u`&&crypto.randomUUID?crypto.randomUUID():Math.random().toString(36).slice(2,10)}`;return localStorage.setItem(g,t),t}catch{return`web-${Math.random().toString(36).slice(2,10)}`}}var v=new class e{ws=null;url;clientId=_();messageHandlers=new Set;openHandlers=new Set;closeHandlers=new Set;errorHandlers=new Set;reconnectAttempts=0;reconnectHandlers=new Set;reconnectSuccessHandlers=new Set;reconnectGiveUpHandlers=new Set;isManualClose=!1;authenticated=!1;bfCached=!1;sessionId=null;visibleSessions=new Set;pendingFrames=f();connectBuffer=[];static MAX_CONNECT_BUFFER=32;connectFlushTimer=null;authPending=!1;static CONNECT_FLUSH_FALLBACK_MS=4e3;heartbeatInterval=null;reconnectTimer=null;awaitingPong=0;HEARTBEAT_INTERVAL=15e3;MAX_MISSED_PONGS=3;static FOREGROUND_PROBE_TIMEOUT_MS=3e3;constructor(e){this.url=e||h,typeof window<`u`&&(window.addEventListener(`pagehide`,e=>{e.persisted&&this.enterBfCache()}),window.addEventListener(`pageshow`,e=>{e.persisted&&this.exitBfCache()}),window.addEventListener(`online`,()=>this.retryImmediately(`网络恢复`)),document.addEventListener(`visibilitychange`,()=>{document.visibilityState===`visible`&&this.probeOnForeground()}))}setSessionId(e){this.sessionId=e}setVisibleSessions(e){let t=new Set;for(let n of e)n&&t.add(n);if(t.size===this.visibleSessions.size){let e=!0;for(let n of t)if(!this.visibleSessions.has(n)){e=!1;break}if(e)return}this.visibleSessions=t,this.sendSubscribeSessions()}sendSubscribeSessions(){if(this.visibleSessions.size!==0&&this.ws?.readyState===WebSocket.OPEN)try{this.ws.send(JSON.stringify({type:`subscribe_sessions`,data:JSON.stringify({sessionIds:[...this.visibleSessions]})}))}catch{}}getSessionId(){return this.sessionId}getPendingFrameCount(){return this.pendingFrames.length}getPendingFrameIds(){return this.pendingFrames.map(e=>e.id||e.type).filter(Boolean)}clearPendingQueue(){this.pendingFrames=[],p([])}enqueueReliableFrame(e){let t=(()=>{try{return e.data?JSON.parse(e.data):{}}catch{return{}}})(),n={type:e.type,sessionId:e.sessionId,data:e.data,id:typeof t.questionId==`string`?t.questionId:typeof t.approvalId==`string`?t.approvalId:typeof t.formId==`string`?t.formId:void 0,queuedAt:Date.now()},r=n.id?this.pendingFrames.filter(e=>e.id!==n.id||e.type!==n.type):this.pendingFrames;this.pendingFrames=[...r,n].slice(-20),p(this.pendingFrames),console.warn(`[WS] reliable frame queued (awaiting ack) ${e.type}${n.id?` (${n.id})`:``}`)}ackReliableFrame(e){if(!e)return;let t=this.pendingFrames.filter(t=>t.id!==e);t.length!==this.pendingFrames.length&&(this.pendingFrames=t,p(t))}flushPendingFrames(){if(this.ws?.readyState!==WebSocket.OPEN)return;let e=f(),t=[...this.pendingFrames];for(let n of e){let e=t.findIndex(e=>e.id===n.id&&e.type===n.type);e>=0?t[e]=n:t.push(n)}if(t.length!==0){this.pendingFrames=t.slice(-20),p(this.pendingFrames);for(let e of this.pendingFrames){if(this.ws?.readyState!==WebSocket.OPEN)break;try{this.ws.send(JSON.stringify({type:e.type,sessionId:e.sessionId,data:e.data}))}catch(t){console.warn(`[WS] Failed to replay pending frame`,e.type,String(t));break}}}}getReconnectState(){return{attempts:this.reconnectAttempts,maxAttempts:a,reconnecting:this.reconnectAttempts>0&&this.ws?.readyState!==WebSocket.OPEN}}onReconnectAttempt(e){return this.reconnectHandlers.add(e),()=>this.reconnectHandlers.delete(e)}onReconnectSuccess(e){return this.reconnectSuccessHandlers.add(e),()=>this.reconnectSuccessHandlers.delete(e)}onReconnectGiveUp(e){return this.reconnectGiveUpHandlers.add(e),()=>this.reconnectGiveUpHandlers.delete(e)}connect(){if(this.ws?.readyState===WebSocket.OPEN||this.ws?.readyState===WebSocket.CONNECTING)return;this.isManualClose=!1;let e=new URLSearchParams;this.sessionId&&e.set(`sessionId`,this.sessionId),e.set(`clientId`,this.clientId);let t=e.toString()?`${this.url}?${e.toString()}`:this.url;this.ws=new WebSocket(t),this.ws.binaryType=`arraybuffer`,this.ws.onopen=()=>{let e=this.reconnectAttempts>0;if(this.reconnectAttempts=0,this.awaitingPong=0,e&&this.reconnectSuccessHandlers.forEach(e=>e()),this.ws?.readyState===WebSocket.OPEN)try{this.ws.send(JSON.stringify({type:`hello`,clientType:`web`,protocolVersion:1,capabilities:[]}))}catch{}this.startHeartbeat(),this.ws?.readyState===WebSocket.OPEN&&(this.awaitingPong=1,this.ws.send(JSON.stringify({type:`ping`}))),this.flushPendingFrames(),this.authPending=!1,this.authenticated=!1,this.armConnectFlushFallback(),this.sendSubscribeSessions(),this.openHandlers.forEach(e=>e())},this.ws.onclose=()=>{this.stopHeartbeat(),this.connectFlushTimer&&=(clearTimeout(this.connectFlushTimer),null),this.closeHandlers.forEach(e=>e()),!this.isManualClose&&!this.bfCached&&this.scheduleReconnect()},this.ws.onerror=e=>{this.reportConnectionTrouble(e.message||`Connection failed`),this.errorHandlers.forEach(e=>e())},this.ws.onmessage=e=>{this._onMessage(e)}}async _onMessage(e){try{let n;if(n=e.data instanceof Blob?await e.data.text():e.data instanceof ArrayBuffer?new TextDecoder().decode(e.data):typeof e.data==`string`?e.data:String(e.data),n=n.trim(),!n)return;let r=JSON.parse(n);if((r.type===`pong`||r.type===`ping`)&&(this.awaitingPong=0,r.type===`pong`))return;if(r.type===`hello_ack`){try{let e=typeof r.data==`string`?JSON.parse(r.data):r.data;e&&typeof e==`object`&&t.getState().setHelloAck({serverVersion:typeof e.serverVersion==`string`?e.serverVersion:``,protocolVersion:typeof e.protocolVersion==`number`?e.protocolVersion:0,capabilities:Array.isArray(e.capabilities)?e.capabilities.filter(e=>typeof e==`string`):[]})}catch{}this.flushConnectBuffer();return}if(r.type===`auth_required`?this.authPending=!0:r.type===`auth_success`&&(this.authPending=!1,this.authenticated=!0,this.flushConnectBuffer()),r.seq!==void 0&&r.seq>=0&&this.send({type:`message_ack`,data:JSON.stringify({seq:r.seq})}),r.type===`question_answer_ack`||r.type===`hook_response_ack`)try{let e=(typeof r.data==`string`?JSON.parse(r.data):r.data)||{};this.ackReliableFrame(typeof e.questionId==`string`?e.questionId:typeof e.approvalId==`string`?e.approvalId:void 0)}catch{}this.messageHandlers.forEach(e=>e(r))}catch(t){let n=e.data?.constructor?.name||typeof e.data,r;if(r=e.data instanceof Blob?`[Blob ${e.data.size} bytes]`:e.data instanceof ArrayBuffer?`[ArrayBuffer ${e.data.byteLength} bytes]`:String(e.data).slice(0,500),typeof e.data==`string`&&e.data.trim()){let t=e.data.trim();try{this.messageHandlers.forEach(e=>e({type:`log`,data:JSON.stringify({level:`info`,message:t})}));return}catch{}}i.error(`Failed to parse WebSocket message`,`type=${n} data=${r} error=${t}`)}}startHeartbeat(){this.stopHeartbeat(),this.awaitingPong=0,this.heartbeatInterval=setInterval(()=>{this.bfCached||(this.awaitingPong>=this.MAX_MISSED_PONGS?this.forceReconnect(`Heartbeat timeout (${this.awaitingPong} missed pongs)`):this.ws?.readyState===WebSocket.OPEN&&(this.awaitingPong+=1,this.send({type:`ping`})))},this.HEARTBEAT_INTERVAL)}stopHeartbeat(){this.heartbeatInterval&&=(clearInterval(this.heartbeatInterval),null),this.awaitingPong=0}enterBfCache(){this.bfCached=!0,this.stopHeartbeat(),this.reconnectTimer&&=(clearTimeout(this.reconnectTimer),null)}exitBfCache(){this.bfCached=!1,this.reconnectAttempts=0,this.ws?.readyState!==WebSocket.OPEN&&this.ws?.readyState!==WebSocket.CONNECTING&&this.connect()}scheduleReconnect(){if(this.reconnectAttempts++,this.reconnectAttempts>a){console.error(`[WS] Max reconnect attempts (${a}) reached — giving up.`),i.error(`WebSocket`,`Connection lost — max reconnect attempts (${a}) reached. Refresh the page to try again.`),this.reconnectGiveUpHandlers.forEach(e=>e());return}let e=s[Math.min(this.reconnectAttempts-1,s.length-1)]??o,t=Math.max(100,Math.round(e*(.8+Math.random()*.4)));this.reconnectHandlers.forEach(e=>e(this.reconnectAttempts,a)),this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=null,this.connect()},t)}reportConnectionTrouble(e){let t=Math.min(this.reconnectAttempts+1,a);this.reconnectAttempts<c?console.debug(`[WS] connection error (attempt ${t}/${a}): ${e}`):i.warn(`WebSocket 连接不稳定`,`正在重连(第 ${t}/${a} 次):${e}`)}retryImmediately(e){if(this.bfCached)return;let t=this.ws?.readyState;t!==WebSocket.OPEN&&t!==WebSocket.CONNECTING&&(this.reconnectAttempts!==0||this.reconnectTimer!==null)&&(console.debug(`[WS] ${e} → 立即重连(重置退避)`),this.reconnectTimer&&=(clearTimeout(this.reconnectTimer),null),this.reconnectAttempts=0,this.connect())}forceReconnect(e){console.warn(`[WS] ${e}, reconnecting...`),this.stopHeartbeat(),this.isManualClose=!0,this.ws?.close(),this.ws=null,this.scheduleReconnect()}probeOnForeground(){if(this.bfCached)return;let t=this.ws?.readyState;if(t===WebSocket.CONNECTING)return;if(t!==WebSocket.OPEN){this.retryImmediately(`标签页恢复可见`);return}if(this.awaitingPong<=0)return;this.awaitingPong+=1,this.send({type:`ping`});let n=this.awaitingPong;setTimeout(()=>{this.bfCached||this.ws?.readyState===WebSocket.OPEN&&this.awaitingPong>=n&&this.forceReconnect(`前台探活无应答(半开连接)`)},e.FOREGROUND_PROBE_TIMEOUT_MS)}disconnect(){this.isManualClose=!0,this.reconnectAttempts=0,this.stopHeartbeat(),this.reconnectTimer&&=(clearTimeout(this.reconnectTimer),null),this.ws?.close(),this.ws=null,this.connectFlushTimer&&=(clearTimeout(this.connectFlushTimer),null),this.connectBuffer=[]}send(e){if(e.type&&u.has(e.type)){if(this.enqueueReliableFrame(e),this.ws?.readyState===WebSocket.OPEN)try{this.ws.send(JSON.stringify(e))}catch{}return!0}if(this.ws?.readyState===WebSocket.OPEN){let t=JSON.stringify(e);return this.ws.send(t),!0}return this.ws?.readyState===WebSocket.CONNECTING&&d.has(e.type)?(this.bufferUntilOpen(e),!0):(console.warn(`[WS] NOT CONNECTED — dropping:`,e.type,e.sessionId,`readyState=`,this.ws?.readyState),!1)}bufferUntilOpen(t){let n=this.connectBuffer.findIndex(e=>e.type===t.type&&e.sessionId===t.sessionId);n>=0?this.connectBuffer[n]=t:(this.connectBuffer.length>=e.MAX_CONNECT_BUFFER&&this.connectBuffer.shift(),this.connectBuffer.push(t))}flushConnectBuffer(){if(this.connectFlushTimer&&=(clearTimeout(this.connectFlushTimer),null),this.connectBuffer.length===0)return;let e=this.connectBuffer;if(this.connectBuffer=[],this.ws?.readyState===WebSocket.OPEN)for(let t of e)try{this.ws.send(JSON.stringify(t))}catch{break}}armConnectFlushFallback(){this.connectBuffer.length!==0&&(this.connectFlushTimer&&clearTimeout(this.connectFlushTimer),this.connectFlushTimer=setTimeout(()=>{this.connectFlushTimer=null,!this.authPending&&this.flushConnectBuffer()},e.CONNECT_FLUSH_FALLBACK_MS))}onMessage(e){return this.messageHandlers.add(e),()=>this.messageHandlers.delete(e)}onOpen(e){return this.openHandlers.add(e),()=>this.openHandlers.delete(e)}onClose(e){return this.closeHandlers.add(e),()=>this.closeHandlers.delete(e)}onError(e){return this.errorHandlers.add(e),()=>this.errorHandlers.delete(e)}get isConnected(){return this.ws?.readyState===WebSocket.OPEN}setToken(e){try{sessionStorage.setItem(`auth_token`,e)}catch{}}get isAuthenticated(){return this.authenticated}setAuthenticated(e){this.authenticated=e,e&&(this.authPending=!1,this.flushConnectBuffer())}};export{r as i,v as n,i as r,m as t};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{n as e}from"./state-pOTP5BEk.js";var t=e(e=>({isOpen:!1,entries:null,openWhatsNew:t=>e({isOpen:!0,entries:t??null}),closeWhatsNew:()=>e({isOpen:!1})}));export{t};
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
var e=/^\s*\*\*\*\s+(?:Add|Update|Delete)\s+File:\s*(.+?)\s*$/,t=/^\s*\*\*\*\s+Move\s+to:\s*(.+?)\s*$/,n=/^---[ \t]+(.*)$/,r=/^\+\+\+[ \t]+(.*)$/,i=/^diff --git[ \t]+(?:"([^"]*)"|(\S+))[ \t]+(?:"([^"]*)"|(\S+))[ \t]*$/,a=/^rename (?:from|to)[ \t]+(.*)$/;function o(e){if(!e)return``;let t=e.split(` `)[0]??``;return t.length>=2&&t.startsWith(`"`)&&t.endsWith(`"`)&&(t=t.slice(1,-1)),t=t.trim(),!t||t===`/dev/null`?``:t.replace(/^[ab]\//,``)}function s(e){if(!e)return[];let t=[],s=new Set,c=e=>{let n=o(e);n&&!s.has(n)&&(s.add(n),t.push(n))},l=e.split(/\r?\n/);for(let e=0;e<l.length;e++){let t=l[e]??``;if(t.startsWith(`diff --git`)){let e=i.exec(t);e&&(c(e[1]??e[2]),c(e[3]??e[4]));continue}if(t.startsWith(`rename `)){c(a.exec(t)?.[1]);continue}let o=n.exec(t);if(!o)continue;let s=r.exec(l[e+1]??``);s&&(c(o[1]),c(s[1]),e++)}return t}function c(n){if(!n)return[];let r=[],i=new Set;for(let a of n.split(/\r?\n/)){let n=a.trim();if(!n.startsWith(`***`))continue;let o=e.exec(n),s=o?null:t.exec(n),c=o?.[1]??s?.[1];c&&(i.has(c)||(i.add(c),r.push(c)))}return r}var l=[`/etc/`,`/usr/lib/`,`/boot/`,`/dev/`,`/sys/`,`/proc/`,`C:\\Windows\\`,`C:\\Program Files\\`];function u(e){if(!e)return!1;let t=e.replace(/\\/g,`/`),n=t.toLowerCase();return l.some(e=>{let r=e.replace(/\\/g,`/`),i=r.endsWith(`/`)?r.slice(0,-1):r;return/^[a-z]:\//i.test(r)?n===i.toLowerCase()||n.startsWith(r.toLowerCase()):t===i||t.startsWith(r)})}function d(e){return e.find(e=>e&&u(e))??null}var f=[`.npmrc`,`.pypirc`,`.netrc`,`.pgpass`,`.git-credentials`,`.gitcookies`,`.htpasswd`,`id_rsa`,`id_dsa`,`id_ecdsa`,`id_ed25519`,`credentials.json`,`secrets.json`,`secrets.yaml`,`secrets.yml`,`.anthropic_oauth.json`,`.google_oauth.json`,`shadow`,`sudoers`],p=[`.ssh`,`.aws`,`.azure`,`.gcloud`,`.kube`,`.docker`,`.gnupg`],m=[`.pem`,`.key`,`.pfx`,`.p12`,`.kdbx`,`.jks`,`.keystore`],h=/(^|\/)\.env($|[^\w.])/,g=/\.(example|sample|template|dist)$|\.pub$/;function _(e){if(!e)return!1;let t=e.replace(/\\/g,`/`),n=t.toLowerCase(),r=n.split(`/`).pop()??``;return!r||g.test(r)?!1:h.test(n)||r===`.env`||r.startsWith(`.env.`)||f.some(e=>r===e.toLowerCase())||m.some(e=>r.endsWith(e))?!0:t.split(`/`).some(e=>p.includes(e.toLowerCase()))}function v(e){return e.find(e=>e&&_(e))??null}function y(e){return e===`auto-act`?`act`:e===`auto-goal`?`goal`:e}function b(e){return e===`auto-act`||e===`auto-goal`}function x(e){switch(e){case`act`:return`auto-act`;case`auto-act`:return`act`;case`goal`:return`auto-goal`;case`auto-goal`:return`goal`;case`chat`:return`chat`}}var S=[`act`,`goal`,`chat`];function C(e,t){return e===`chat`?`chat`:t?e===`act`?`auto-act`:`auto-goal`:e}function w(e){let t=[`act`,`goal`];return C(t[(t.indexOf(y(e))+1)%t.length]??`act`,b(e))}var T={act:{label:`Act`,accent:`green`},"auto-act":{label:`Auto-Act`,accent:`yellow`},goal:{label:`Goal`,accent:`magenta`},"auto-goal":{label:`Auto-Goal`,accent:`red`},chat:{label:`Chat`,accent:`cyan`}},E={low:{label:`Low`,accent:`green`},medium:{label:`Medium`,accent:`cyan`},high:{label:`High`,accent:`yellow`},critical:{label:`Critical`,accent:`red`}},D={allow:{label:`Allow`,key:`y`},deny:{label:`Deny`,key:`n`},allow_session:{label:`Allow session`,key:`s`},auto:{label:`Auto mode`,key:`a`}};function O(e){return e===`plan`||e===`auto-plan`?`act`:e===`act`||e===`auto-act`||e===`goal`||e===`auto-goal`||e===`chat`?e:`auto-act`}function k(e){return e>=1e6?`${(e/1e6).toFixed(1)}M`:e>=1e3?`${Math.round(e/1e3)}K`:String(e)}function A(e){return e<=0?``:e>=100?`${Math.round(e)}tok/s`:`${e.toFixed(1)}tok/s`}function j(e){if(!e)return 0;let t=(e.match(/[\u3000-\u303f\u3040-\u30ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff\uff00-\uffef]/g)||[]).length;return t*1.5+(e.length-t)*.25}function M(e=4e3){let t=[],n=n=>{let r=n-e;for(;t.length>0&&t[0].ts<r;)t.shift()};return{feed(e,r=Date.now()){let i=j(e);i<=0||(n(r),t.push({ts:r,tokens:i}))},rate(e=Date.now()){if(n(e),t.length===0)return 0;let r=0;for(let e of t)r+=e.tokens;let i=Math.max(e-t[0].ts,500);return r/i*1e3},reset(){t=[]}}}function N(e){if(e<=0)return``;let t=Math.round(e*10);return t<600?`${(t/10).toFixed(1)}s`:`${Math.floor(t/600)}m${(t%600/10).toFixed(1)}s`}function P(e,t){switch(e){case`bash`:case`shell`:case`PowerShell`:return`ran ${t} shell command${t>1?`s`:``}`;case`read_file`:return`read ${t} file${t>1?`s`:``}`;case`write_file`:return`wrote ${t} file${t>1?`s`:``}`;case`edit_file`:case`edit_file_line`:return`edited ${t} file${t>1?`s`:``}`;case`apply_patch`:return`patched ${t} file${t>1?`s`:``}`;default:return`ran ${t} ${e}${t>1?`s`:``}`}}function F(e){let t=Object.entries(e.toolCounts).filter(([,e])=>e>0).sort((e,t)=>t[1]-e[1]),n=e.headline||`Thought for ${N(Math.max(1,Math.round(e.durationMs/1e3)))}`,r=t.map(([e,t])=>P(e,t));return r.length>0?`${n}, ${r.join(`, `)}`:n}function I(e,t){let n=e.toLowerCase(),r=new Set(n.split(/[^a-z0-9]+/).filter(Boolean)),i=(...e)=>e.some(e=>r.has(e));return n===`apply_patch`?d(c(L(t)))?`critical`:`high`:i(`rm`,`del`,`delete`,`drop`,`truncate`,`format`,`mkfs`)?`critical`:i(`bash`,`shell`,`exec`,`cmd`,`powershell`,`terminal`)?/\b(rm\s+-rf|sudo|chmod\s+777|curl.*\|\s*(ba)?sh|wget.*-O|>\/dev\/|mkfs)\b/i.test(t)?`critical`:`high`:i(`write`,`edit`,`save`,`upload`,`deploy`,`publish`)?d(z(t))?`critical`:`high`:i(`install`,`uninstall`,`npm`,`pip`,`cargo`,`gem`,`apt`,`brew`,`choco`,`yum`,`dnf`)?`high`:i(`git`,`commit`,`push`,`merge`,`rebase`)?/\b(push|force|hard\s*reset|rebase)\b/i.test(t)?`high`:`medium`:i(`http`,`fetch`,`curl`,`wget`,`api`,`request`,`download`)?`medium`:i(`read`,`open`,`list`,`ls`,`dir`,`cat`,`view`,`search`,`find`,`grep`,`glob`)?v(z(t))?`high`:`low`:`medium`}function L(e){if(!e)return``;try{let t=JSON.parse(e);if(!t||typeof t!=`object`)return e;let n=t,r=(n.payload&&typeof n.payload==`object`?n.payload:n).patch;return typeof r==`string`?r:e}catch{return e}}var R=new Set([`file_path`,`filePath`,`filepath`,`path`,`notebook_path`,`notebookPath`,`file`]);function z(e){if(!e)return[];let t=[],n=new Set,r=e=>{typeof e==`string`&&e.trim()&&!n.has(e)&&(n.add(e),t.push(e))},i=(e,t)=>{if(!(t>4||!e||typeof e!=`object`)){if(Array.isArray(e))for(let n of e)r(n),i(n,t+1);else for(let[n,a]of Object.entries(e))R.has(n)?(r(a),Array.isArray(a)&&a.forEach(r)):i(a,t+1)}};try{i(JSON.parse(e),0)}catch{}if(t.length===0)for(let t of e.matchAll(/(?:file_path|filePath|path|file)["\s:=]+([^\s",}]+)/gi))r(t[1]);return t}function B(e,t,n){if(t==null)return null;let r=n?.unbounded===!0;if(/apply_patch/i.test(e)){let e=L(t),n=c(e),i=n.length>0?n.join(`
|
|
2
|
-
`):`(no file markers found)`;return r?`${i}\n${e}`:`${i}\n${e.split(/\r?\n/).slice(0,12).join(`
|
|
3
|
-
`)}`.slice(0,240)}if(/\b(bash|shell|exec|cmd|powershell|terminal)\b/i.test(e))return t||null;if(/\b(write|edit|save|create)\b/i.test(e)){let e=t.match(/(?:file_path|path|file)["\s:=]+([^\s",}]+)/i);return e?r?`${e[1]}\n${t}`:`${e[1]}\n${t.slice(0,200)}`:(r?t:t.slice(0,200))||null}return t&&t.length>0?r?t:t.length>200?`${t.slice(0,200)}...`:t:null}export{c as _,y as a,B as c,F as d,b as f,C as g,x as h,E as i,k as l,O as m,S as n,I as o,w as p,T as r,M as s,D as t,A as u,s as v};
|