pi-web-ui 0.64.6 → 0.64.8

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.
Files changed (70) hide show
  1. package/dist/server/agent-service.js +69 -33
  2. package/dist/server/settings-service.js +1 -1
  3. package/dist/server/subagents.js +2 -2
  4. package/dist/server/webui-context.js +3 -3
  5. package/package.json +1 -1
  6. package/web/dist/assets/{TerminalPanel-CoPFNu1d.js → TerminalPanel-DL8sTcRC.js} +1 -1
  7. package/web/dist/assets/{abnfDiagram-VCTEODGH-Dltz1N0G.js → abnfDiagram-VCTEODGH-BF9usV5C.js} +1 -1
  8. package/web/dist/assets/{arc-QOm2xRll.js → arc-BHXahvV5.js} +1 -1
  9. package/web/dist/assets/{architectureDiagram-5GKGNRK7-L3XUBFbb.js → architectureDiagram-5GKGNRK7-V2QNH_BW.js} +1 -1
  10. package/web/dist/assets/{blockDiagram-I7D4REHJ-CJmza4yx.js → blockDiagram-I7D4REHJ-DNWe8D5y.js} +1 -1
  11. package/web/dist/assets/{c4Diagram-7LVT6UL2-CwgA5WEW.js → c4Diagram-7LVT6UL2-Cd7YCdDn.js} +1 -1
  12. package/web/dist/assets/channel-DDCgqHU5.js +1 -0
  13. package/web/dist/assets/{chunk-2Q5K7J3B-DoqSiCVF.js → chunk-2Q5K7J3B-Dn4M1g1T.js} +1 -1
  14. package/web/dist/assets/{chunk-5VM5RSS4-CO14GhQ1.js → chunk-5VM5RSS4-U5uyVkTI.js} +1 -1
  15. package/web/dist/assets/{chunk-F27PBJKO-kRFf9SDx.js → chunk-F27PBJKO-lMqDdknq.js} +1 -1
  16. package/web/dist/assets/{chunk-IMKFNOWR-Cm6JOqm0.js → chunk-IMKFNOWR-DlzpFcKz.js} +1 -1
  17. package/web/dist/assets/{chunk-JWPE2WC7-DTpnGTdB.js → chunk-JWPE2WC7-BdI7zobW.js} +1 -1
  18. package/web/dist/assets/{chunk-POPQ4Y6H-CdSt_7xq.js → chunk-POPQ4Y6H-Dk7oA6BE.js} +1 -1
  19. package/web/dist/assets/{chunk-SVP7TREG-IQRTD_4U.js → chunk-SVP7TREG-BhXOKkNm.js} +1 -1
  20. package/web/dist/assets/{chunk-TICWLB2K-Duj1rt_5.js → chunk-TICWLB2K-DFW_5Q5s.js} +1 -1
  21. package/web/dist/assets/{chunk-XXDRQBXY-BFf3gcbL.js → chunk-XXDRQBXY-d-B9YyVA.js} +1 -1
  22. package/web/dist/assets/classDiagram-ZZMXUADV-DnlRT21K.js +1 -0
  23. package/web/dist/assets/classDiagram-v2-VYDZK3BY-DnlRT21K.js +1 -0
  24. package/web/dist/assets/{cose-bilkent-JH36ORCC-D5k0Z1dx.js → cose-bilkent-JH36ORCC-W3IYYiNN.js} +1 -1
  25. package/web/dist/assets/{cynefin-OW5HDTMX-OsV-x0h-.js → cynefin-OW5HDTMX-DVcVxvWj.js} +1 -1
  26. package/web/dist/assets/{cynefinDiagram-5FMLGOSQ-DM7XHm4s.js → cynefinDiagram-5FMLGOSQ-DdUHHDle.js} +1 -1
  27. package/web/dist/assets/{dagre-GXQ25YYZ-B0bIbgMh.js → dagre-GXQ25YYZ-DMqzPbm8.js} +1 -1
  28. package/web/dist/assets/{diagram-S7CK7UJ4-lMVsMjfI.js → diagram-S7CK7UJ4-g-T7ZpRp.js} +1 -1
  29. package/web/dist/assets/{diagram-UQ7AKVKN-BJDbkaYf.js → diagram-UQ7AKVKN-Cj1HB5mV.js} +1 -1
  30. package/web/dist/assets/{diagram-VSXAHHWV-1zUfVr-L.js → diagram-VSXAHHWV-D4Xgm5yq.js} +1 -1
  31. package/web/dist/assets/{diagram-VX7I27RA-B-Qy3dth.js → diagram-VX7I27RA-CPaDZ0sg.js} +1 -1
  32. package/web/dist/assets/{diagram-Z3DM3KII-DbKcoZFP.js → diagram-Z3DM3KII-BwroUmR-.js} +1 -1
  33. package/web/dist/assets/{ebnfDiagram-PWID7BFC-CuMZBzDi.js → ebnfDiagram-PWID7BFC-CymjTfGP.js} +1 -1
  34. package/web/dist/assets/{erDiagram-RLTQ6QDP-Dkw_Uhg2.js → erDiagram-RLTQ6QDP-CkCv1f0Q.js} +1 -1
  35. package/web/dist/assets/{flowDiagram-HODETNUW-CwDYMy38.js → flowDiagram-HODETNUW-IrWWLHqn.js} +1 -1
  36. package/web/dist/assets/{ganttDiagram-EL5Y4UJY-B2s3myqg.js → ganttDiagram-EL5Y4UJY-DhHylBej.js} +1 -1
  37. package/web/dist/assets/{gitGraphDiagram-WWUBYQGX-CJ3rUTG5.js → gitGraphDiagram-WWUBYQGX-C1O_4b0m.js} +1 -1
  38. package/web/dist/assets/{index-30RM921r.js → index-B-D8dBbi.js} +24 -24
  39. package/web/dist/assets/index-DWUw-5kk.css +10 -0
  40. package/web/dist/assets/{infoDiagram-27XIBGKW-DuIoOHyL.js → infoDiagram-27XIBGKW-B3SzbIHm.js} +1 -1
  41. package/web/dist/assets/{ishikawaDiagram-5VMMS53U-Fm14e_CH.js → ishikawaDiagram-5VMMS53U-CM5U90LI.js} +1 -1
  42. package/web/dist/assets/{journeyDiagram-3NMN7TZE-BuokOq_3.js → journeyDiagram-3NMN7TZE-BIWbaonv.js} +1 -1
  43. package/web/dist/assets/{kanban-definition-UXKFOSKX-D2FQMRnh.js → kanban-definition-UXKFOSKX-Cg0FRvzj.js} +1 -1
  44. package/web/dist/assets/{layout-CZUvkkNF.js → layout-BMZQTQDF.js} +1 -1
  45. package/web/dist/assets/{linear-tIFeS1QT.js → linear--htAmwBy.js} +1 -1
  46. package/web/dist/assets/{mermaid.core-BI5_3AOv.js → mermaid.core-Bxpg8jiH.js} +5 -5
  47. package/web/dist/assets/{mindmap-definition-YA3MSWOX-D5RmpgpB.js → mindmap-definition-YA3MSWOX-CNp9C6Gy.js} +1 -1
  48. package/web/dist/assets/{pegDiagram-XKGWAZYB-DpZxaRI3.js → pegDiagram-XKGWAZYB-B4mLGlJp.js} +1 -1
  49. package/web/dist/assets/{pieDiagram-E7YTZNPT-Co7MADQz.js → pieDiagram-E7YTZNPT-hP4zuAzM.js} +1 -1
  50. package/web/dist/assets/{quadrantDiagram-AXDQQJYC-BsRraVQ-.js → quadrantDiagram-AXDQQJYC-DVN-GEzm.js} +1 -1
  51. package/web/dist/assets/{railroadDiagram-O6MQD6OU-DW2pw5p_.js → railroadDiagram-O6MQD6OU-BjBVdCWk.js} +1 -1
  52. package/web/dist/assets/{requirementDiagram-BXWQKSXE-DeaEY9Dk.js → requirementDiagram-BXWQKSXE-BOwNWcER.js} +1 -1
  53. package/web/dist/assets/{sankeyDiagram-P5KCCOFB-BlKg1xhH.js → sankeyDiagram-P5KCCOFB-CkK6Y6CK.js} +1 -1
  54. package/web/dist/assets/{sequenceDiagram-WJ2MYXX4-C0ffpRmx.js → sequenceDiagram-WJ2MYXX4-D49cIkIS.js} +1 -1
  55. package/web/dist/assets/{sizeCapture-INFHLROL-DHFDdkAo.js → sizeCapture-INFHLROL-D9R6YbVj.js} +1 -1
  56. package/web/dist/assets/{stateDiagram-D77RDMKH-CwKStGSS.js → stateDiagram-D77RDMKH-DvwH4KPJ.js} +1 -1
  57. package/web/dist/assets/stateDiagram-v2-MP3YSRHH-CHVwI1ZU.js +1 -0
  58. package/web/dist/assets/{swimlanes-42K2YHIH-MB6Uskqk.js → swimlanes-42K2YHIH-DgpCt172.js} +1 -1
  59. package/web/dist/assets/swimlanesDiagram-VR7AAH4N-L7ZmzB2n.js +8 -0
  60. package/web/dist/assets/{timeline-definition-24CTP7MA-CkcuHQ1A.js → timeline-definition-24CTP7MA-Cy-6c2rf.js} +1 -1
  61. package/web/dist/assets/{vennDiagram-4TSXK5OY-DRiGv5ga.js → vennDiagram-4TSXK5OY-D05mFAgh.js} +1 -1
  62. package/web/dist/assets/{wardleyDiagram-VM6X3IG4-Cwldlf89.js → wardleyDiagram-VM6X3IG4--c9A1xky.js} +1 -1
  63. package/web/dist/assets/{xychartDiagram-S5SC5T6Z-Biqu8RpV.js → xychartDiagram-S5SC5T6Z-F6B_ZHcI.js} +1 -1
  64. package/web/dist/index.html +2 -2
  65. package/web/dist/assets/channel-VncP7yyT.js +0 -1
  66. package/web/dist/assets/classDiagram-ZZMXUADV-BWCNDr-F.js +0 -1
  67. package/web/dist/assets/classDiagram-v2-VYDZK3BY-BWCNDr-F.js +0 -1
  68. package/web/dist/assets/index-B_lYcsGw.css +0 -10
  69. package/web/dist/assets/stateDiagram-v2-MP3YSRHH-B0qJoPpx.js +0 -1
  70. package/web/dist/assets/swimlanesDiagram-VR7AAH4N-IYPIFoU6.js +0 -8
@@ -30,7 +30,7 @@ import { FilesService, workspacePath } from "./files-service.js";
30
30
  import { isExtensionDisabled, isExtensionEnabled, ClientStateStore } from "./client-state.js";
31
31
  import { SubagentTemplatesStore } from "./subagent-templates.js";
32
32
  import { applyHeadTail, makePersistentTerminalTools, makeTerminalBashTool, stripAnsi, TERMINAL_TOOLS_GUIDANCE, TERMINAL_TOOL_NAMES, } from "./terminals.js";
33
- import { WebUIContext } from "./webui-context.js";
33
+ import { WebUIContext, mockThemeProxy } from "./webui-context.js";
34
34
  import { makeSubagentTools, subagentTitle, } from "./subagents.js";
35
35
  import { buildAttachmentMessages } from "./attachments.js";
36
36
  import { serializeMessage, serializeStreamingMessage } from "./serialize.js";
@@ -84,14 +84,14 @@ export class QuiesceRejectedError extends Error {
84
84
  * programs wait for input that never comes. Legacy Chinese files are often
85
85
  * GBK/GB2312 — read them with the right encoding, never paste mojibake into
86
86
  * reasoning/answers. */
87
- const WINDOWS_PERSONA = `You are a coding agent running on Windows. The bash tool runs Git Bash (bash.exe), not PowerShell. Follow these rules to avoid hanging the session:
88
-
89
-
90
-
91
- - ALWAYS pass a timeout parameter to the bash tool (in seconds). There is NO default timeout — a command that never finishes (servers, watchers, infinite loops, slow downloads/installs) will hang the entire conversation indefinitely. Pick a generous timeout for long-running work, but never omit it.
92
- - NEVER run interactive or foreground long-running commands through the bash tool (vi, less, top, python -, node -, npm run dev, sleep 10000). For servers/daemons use background execution with output redirected to a log file, then poll the log; stop them when done.
93
- - In the interactive terminal (TTY) — which is Git Bash too, not PowerShell — NEVER use heredocs (<<'EOF' ... EOF) or here-strings, and NEVER start interactive programs (vi, less, python -, node -, npm init): they wait for keyboard input that never arrives and hang the terminal forever. Prefer writing a temp script file (e.g. .pi-tmp.sh) and running it non-interactively. ALWAYS pass a timeout to long-running commands (e.g. \`timeout 120 npm run dev\`).
94
-
87
+ const WINDOWS_PERSONA = `You are a coding agent running on Windows. The bash tool runs Git Bash (bash.exe), not PowerShell. Follow these rules to avoid hanging the session:
88
+
89
+
90
+
91
+ - ALWAYS pass a timeout parameter to the bash tool (in seconds). There is NO default timeout — a command that never finishes (servers, watchers, infinite loops, slow downloads/installs) will hang the entire conversation indefinitely. Pick a generous timeout for long-running work, but never omit it.
92
+ - NEVER run interactive or foreground long-running commands through the bash tool (vi, less, top, python -, node -, npm run dev, sleep 10000). For servers/daemons use background execution with output redirected to a log file, then poll the log; stop them when done.
93
+ - In the interactive terminal (TTY) — which is Git Bash too, not PowerShell — NEVER use heredocs (<<'EOF' ... EOF) or here-strings, and NEVER start interactive programs (vi, less, python -, node -, npm init): they wait for keyboard input that never arrives and hang the terminal forever. Prefer writing a temp script file (e.g. .pi-tmp.sh) and running it non-interactively. ALWAYS pass a timeout to long-running commands (e.g. \`timeout 120 npm run dev\`).
94
+
95
95
  Many legacy Chinese text files (.html/.txt/.md/.log, exported documents) are GBK/GB2312 encoded: the read tool decodes UTF-8 only and will show mojibake (乱码) for them. If a file's content looks garbled, read it through the terminal instead: in Git Bash use \`cat file | iconv -f GBK -t UTF-8\` (or \`iconv -f GBK -t UTF-8 file\`); in cmd use \`chcp 65001 && type file\`; in PowerShell use \`Get-Content -Encoding Default file\`. Never paste mojibake into your reasoning or answer — describe the decoded content instead.`;
96
96
  /** bash 工具输出限制/过滤管道引导:模型习惯套 `| tail/-n`、`| head`、`| grep`、`| less`
97
97
  * 等限输出。这些管道在持久终端里会①缓冲(可见终端全程哑火、看不到实时进度)②把退出码
@@ -604,14 +604,24 @@ export class ClientSession {
604
604
  });
605
605
  const conv = this.makeConversation(runtime, conversationId, terminals);
606
606
  conv.isSubagent = true;
607
+ // 派发时刻的 active 即父对话(子代理也可再派发,自然嵌套)。
608
+ conv.parentId = this.activeId || undefined;
607
609
  conv.subagentType = type;
608
610
  conv.listed = true;
609
611
  conv.title = subagentTitle(prompt);
610
612
  this.convs.set(conv.id, conv);
611
- // 扩展绑定(rpc 模式;不给 uiContext,避免与主对话的 widget 冲突)。
613
+ // 扩展绑定(rpc 模式;uiContext 只给无害的 mock theme/status 槽,避免与主对话
614
+ // 的 widget 冲突。无 uiContext 时扩展的 ctx.ui.theme.fg 会打到 TUI 真 theme
615
+ // 代理上抛 "Theme not initialized",每个扩展一条 error toast。)
612
616
  try {
613
617
  await conv.session.bindExtensions({
614
618
  mode: "rpc",
619
+ uiContext: {
620
+ theme: mockThemeProxy,
621
+ setStatus: () => { },
622
+ setWidget: () => { },
623
+ notify: () => { },
624
+ },
615
625
  onError: (err) => this.emit({ type: "notice", level: "error", text: err.error, textEn: err.error }),
616
626
  });
617
627
  }
@@ -622,7 +632,11 @@ export class ClientSession {
622
632
  // 给子代理会话换模型;全都不给 = 跟随主对话:把发起会话当前的模型也
623
633
  // 显式搬过来(新 runtime 的默认模型未必等于主对话刚选的模型)。
624
634
  const resolvedModel = model ?? (apply?.model?.trim() || null) ?? (this.settingsSvc.current.subagentDefaultModel || null);
625
- const followModel = resolvedModel ? resolvedModel : this.session.model ? `${this.session.model.provider}/${this.session.model.id}` : null;
635
+ const followModel = resolvedModel
636
+ ? resolvedModel
637
+ : this.session.model
638
+ ? `${this.session.model.provider}/${this.session.model.id}`
639
+ : null;
626
640
  if (followModel) {
627
641
  const slash = followModel.indexOf("/");
628
642
  const m = slash > 0 && slash < followModel.length - 1
@@ -2897,16 +2911,21 @@ export class ClientSession {
2897
2911
  // Retain while the session has active (queued/running) pi-subagents async
2898
2912
  // runs on disk — the extension host would otherwise be torn down and its
2899
2913
  // workflow controllers aborted mid-flight.
2900
- const retained = shouldRetainActive({
2901
- reviewing: conv.goal.reviewing,
2902
- wizardRunning: conv.wizardRunning,
2903
- streaming: conv.session.isStreaming,
2904
- openTerminals: conv.terminals.list().length,
2905
- listed: conv.listed,
2906
- promptedSinceActive: conv.promptedSinceActive,
2907
- hasActiveSubagentRun: () => hasActiveSubagentRun({ sessionId: conv.session.sessionFile }),
2908
- hasPendingWake: () => hasPendingWaitSubscription({ sessionId: conv.session.sessionFile }),
2909
- });
2914
+ // Also retain a parent while any live first-party subagent conversation
2915
+ // points at it: dropping an idle in-memory parent orphans the child row
2916
+ // (the child vanishes from Running Chats with no result available).
2917
+ const hasLiveChild = [...this.convs.values()].some((child) => child.parentId === conv.id);
2918
+ const retained = hasLiveChild ||
2919
+ shouldRetainActive({
2920
+ reviewing: conv.goal.reviewing,
2921
+ wizardRunning: conv.wizardRunning,
2922
+ streaming: conv.session.isStreaming,
2923
+ openTerminals: conv.terminals.list().length,
2924
+ listed: conv.listed,
2925
+ promptedSinceActive: conv.promptedSinceActive,
2926
+ hasActiveSubagentRun: () => hasActiveSubagentRun({ sessionId: conv.session.sessionFile }),
2927
+ hasPendingWake: () => hasPendingWaitSubscription({ sessionId: conv.session.sessionFile }),
2928
+ });
2910
2929
  if (retained) {
2911
2930
  conv.listed = true;
2912
2931
  return null;
@@ -2975,9 +2994,14 @@ export class ClientSession {
2975
2994
  * its project (see switchConversation). The client groups the list by cwd. */
2976
2995
  emitConversations() {
2977
2996
  const conversations = [];
2997
+ // Active parents are normally absent from Running. Keep them visible while
2998
+ // listed subagents hang under them, so both rows remain clickable.
2999
+ const visibleParents = new Set([...this.convs.values()]
3000
+ .filter((conv) => conv.listed)
3001
+ .map((conv) => conv.parentId)
3002
+ .filter(Boolean));
2978
3003
  for (const conv of this.convs.values()) {
2979
- // Only conversations that were displaced to the background while running.
2980
- if (!conv.listed)
3004
+ if (!conv.listed && !visibleParents.has(conv.id))
2981
3005
  continue;
2982
3006
  let messageCount = 0;
2983
3007
  let isStreaming = false;
@@ -2997,6 +3021,7 @@ export class ClientSession {
2997
3021
  isSubagent: !!conv.isSubagent,
2998
3022
  // 子代理带 error 标记:左栏红点提示(普通对话不参与)。
2999
3023
  ...(conv.isSubagent ? this.subagentRunOutcome(conv) : {}),
3024
+ parentId: conv.parentId,
3000
3025
  });
3001
3026
  }
3002
3027
  this.emit({
@@ -3283,16 +3308,19 @@ export class ClientSession {
3283
3308
  return;
3284
3309
  }
3285
3310
  // Streaming / retained conversations refuse dismissal — mirrors displaceActive retention.
3286
- const retained = shouldRetainActive({
3287
- reviewing: conv.goal.reviewing,
3288
- wizardRunning: conv.wizardRunning,
3289
- streaming: conv.session.isStreaming,
3290
- openTerminals: conv.terminals.list().length,
3291
- listed: conv.listed,
3292
- promptedSinceActive: conv.promptedSinceActive,
3293
- hasActiveSubagentRun: () => hasActiveSubagentRun({ sessionId: conv.session.sessionFile }),
3294
- hasPendingWake: () => hasPendingWaitSubscription({ sessionId: conv.session.sessionFile }),
3295
- });
3311
+ // A parent with live children also refuses: dropping it orphans the child rows.
3312
+ const hasLiveChild = [...this.convs.values()].some((child) => child.parentId === id);
3313
+ const retained = hasLiveChild ||
3314
+ shouldRetainActive({
3315
+ reviewing: conv.goal.reviewing,
3316
+ wizardRunning: conv.wizardRunning,
3317
+ streaming: conv.session.isStreaming,
3318
+ openTerminals: conv.terminals.list().length,
3319
+ listed: conv.listed,
3320
+ promptedSinceActive: conv.promptedSinceActive,
3321
+ hasActiveSubagentRun: () => hasActiveSubagentRun({ sessionId: conv.session.sessionFile }),
3322
+ hasPendingWake: () => hasPendingWaitSubscription({ sessionId: conv.session.sessionFile }),
3323
+ });
3296
3324
  if (retained) {
3297
3325
  if (conv.session.isStreaming) {
3298
3326
  this.emit({
@@ -3310,6 +3338,14 @@ export class ClientSession {
3310
3338
  textEn: `Conversation "${conv.title}" still has open terminals — close them before removing`,
3311
3339
  });
3312
3340
  }
3341
+ else if (hasLiveChild) {
3342
+ this.emit({
3343
+ type: "notice",
3344
+ level: "warning",
3345
+ text: `对话「${conv.title}」还有运行中的子代理,请先移出子代理后再移出`,
3346
+ textEn: `Conversation "${conv.title}" still has running subagents — remove them first`,
3347
+ });
3348
+ }
3313
3349
  else {
3314
3350
  this.emit({
3315
3351
  type: "notice",
@@ -255,7 +255,7 @@ export class SettingsService {
255
255
  }
256
256
  }
257
257
  // 稳定排序:provider 名 → 模型名。
258
- return out.sort((a, b) => (a.provider === b.provider ? a.label.localeCompare(b.label) : a.provider.localeCompare(b.provider)));
258
+ return out.sort((a, b) => a.provider === b.provider ? a.label.localeCompare(b.label) : a.provider.localeCompare(b.provider));
259
259
  }
260
260
  catch {
261
261
  // Session not ready yet — the picker stays empty until next push.
@@ -65,7 +65,7 @@ export function makeSubagentTools(host) {
65
65
  "subagent_steer 中途改向、subagent_stop 停止。" +
66
66
  "适合:长耗时探索、并行调研、独立子任务委派。可选 template 参数:使用设置面板配置的子代理模板" +
67
67
  "(角色系统提示词 + 技能/扩展白名单 + 可选模型);可选 model 参数:显式指定子代理模型(provider/id 格式," +
68
- "\"anthropic/claude-opus-4-5\"),优先级高于模板与设置面板的默认模型;都不传 = 跟随主对话当前模型。",
68
+ '如 "anthropic/claude-opus-4-5"),优先级高于模板与设置面板的默认模型;都不传 = 跟随主对话当前模型。',
69
69
  promptSnippet: "spawn an independent background subagent for a deliverable task (parallel work)",
70
70
  parameters: Type.Object({
71
71
  prompt: Type.String({ description: "交给子代理的完整指令(要达成的目标 + 约束 + 期望产出)。" }),
@@ -75,7 +75,7 @@ export function makeSubagentTools(host) {
75
75
  "模板 = 角色系统提示词 + 技能/扩展白名单 + 可选模型;不传 = 不使用模板,按主会话默认配置运行。",
76
76
  })),
77
77
  model: Type.Optional(Type.String({
78
- description: "可选:子代理模型 \"provider/id\"(如 \"anthropic/claude-opus-4-5\"),显式指定本次子代理的模型," +
78
+ description: '可选:子代理模型 "provider/id"(如 "anthropic/claude-opus-4-5"),显式指定本次子代理的模型,' +
79
79
  "优先级高于模板自带模型与设置面板默认模型;不传 = 模板模型 → 设置面板默认模型 → 跟随主对话当前模型。",
80
80
  })),
81
81
  cwd: Type.Optional(Type.String({ description: "子代理工作目录(相对/绝对)。默认继承主会话工作目录。" })),
@@ -7,7 +7,7 @@ export function stripAnsi(s) {
7
7
  return s.replace(ANSI_RE, "");
8
8
  }
9
9
  /** Mock theme: TUI color functions degrade to identity so widget text survives. */
10
- const mockTheme = new Proxy({
10
+ export const mockThemeProxy = new Proxy({
11
11
  fg: (_color, text) => text,
12
12
  bold: (text) => text,
13
13
  strikethrough: (text) => text,
@@ -37,7 +37,7 @@ const mockTui = new Proxy({
37
37
  * footer) are inert: dialogs resolve to cancellation instead of blocking.
38
38
  */
39
39
  export class WebUIContext {
40
- theme = mockTheme;
40
+ theme = mockThemeProxy;
41
41
  widgets = new Map();
42
42
  lastLines = new Map();
43
43
  emit;
@@ -59,7 +59,7 @@ export class WebUIContext {
59
59
  try {
60
60
  // Mock TUI/theme: extensions only read a handful of theme helpers;
61
61
  // everything else is a no-op, so the widget renders to plain text.
62
- comp = content(mockTui, mockTheme);
62
+ comp = content(mockTui, mockThemeProxy);
63
63
  }
64
64
  catch {
65
65
  comp = undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-web-ui",
3
- "version": "0.64.6",
3
+ "version": "0.64.8",
4
4
  "description": "Web chat interface for the pi coding agent, powered by the pi SDK (@earendil-works/pi-coding-agent) — one-command run, Docker/systemd/launchd deployable",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -1,4 +1,4 @@
1
- import{a as l,j as n}from"./markdown-BJJLXG-8.js";import{u as O,b as M,T as z,a as W,F as Y,c as H,d as Z,e as q,f as ee,g as ne,h as te,i as se,r as ae}from"./index-30RM921r.js";import{D as re,o as ie}from"./xterm-D1D2FVe3.js";import"./react-ezqUM1Or.js";function le(t){let c=null;return{clean:t.replace(/\r?\n?\[pi-term-exit:(-?\d+)\]\r?\n?/g,(a,h)=>(c=Number(h),`\r
1
+ import{a as l,j as n}from"./markdown-BJJLXG-8.js";import{u as O,b as M,T as z,a as W,F as Y,c as H,d as Z,e as q,f as ee,g as ne,h as te,i as se,r as ae}from"./index-B-D8dBbi.js";import{D as re,o as ie}from"./xterm-D1D2FVe3.js";import"./react-ezqUM1Or.js";function le(t){let c=null;return{clean:t.replace(/\r?\n?\[pi-term-exit:(-?\d+)\]\r?\n?/g,(a,h)=>(c=Number(h),`\r
2
2
  `)).replace(/\r?\n?\x1b\[90m\[(?:进程已退出,退出码 |Process exited with code )-?\d+\]\x1b\[0m\r?\n?/g,`\r
3
3
  `),exitCode:c}}function ce({conversationId:t,terminalId:c,command:f,cwd:a,title:h,active:u,running:b,exitCode:y,send:j,register:T}){const k=l.useRef(null),N=l.useRef(null),{locale:o}=O(),w=l.useRef(o);w.current=o;const F=f?JSON.stringify(f):"";l.useEffect(()=>{const m=k.current;if(!m)return;const r=new re({theme:M(),fontFamily:'"SF Mono", "JetBrains Mono", ui-monospace, Menlo, Consolas, monospace',fontSize:13,cursorBlink:!0,scrollback:8e3}),g=new ie;r.loadAddon(g),r.open(m),N.current={term:r,fit:g},u&&r.focus();const C=()=>{r.options.theme=M()};window.addEventListener(z,C),r.attachCustomKeyEventHandler(d=>{var A;if(d.type!=="keydown")return!0;const D=(A=d.key)==null?void 0:A.toLowerCase();if((d.ctrlKey||d.metaKey)&&D==="v")return!1;if(d.ctrlKey&&!d.shiftKey&&!d.altKey&&D==="c"&&r.hasSelection()){const E=r.textarea;return E&&(E.value=r.getSelection(),E.select()),!1}return!0});const _=T(t,c,{write:d=>r.write(le(d).clean),dispose:()=>r.dispose()}),$=()=>{try{g.fit(),j({type:"terminal_resize",terminalId:c,conversationId:t,cols:r.cols,rows:r.rows})}catch{}},B=requestAnimationFrame(()=>{try{g.fit()}catch{}j(f?{type:"run_command",terminalId:c,conversationId:t,command:f,cols:r.cols,rows:r.rows}:{type:"terminal_create",terminalId:c,title:h,locale:w.current,conversationId:t,cwd:a,cols:r.cols,rows:r.rows})}),S=r.onData(d=>{j({type:"terminal_input",terminalId:c,conversationId:t,data:d})});let v=null;return typeof ResizeObserver<"u"&&(v=new ResizeObserver(()=>{m.offsetWidth>0&&m.offsetHeight>0&&$()}),v.observe(m)),()=>{cancelAnimationFrame(B),S.dispose(),window.removeEventListener(z,C),v==null||v.disconnect(),_(),r.dispose(),N.current=null}},[t,c,F,j,T]),l.useEffect(()=>{if(!u)return;const m=requestAnimationFrame(()=>{const r=N.current;if(r){try{r.fit.fit(),j({type:"terminal_resize",terminalId:c,conversationId:t,cols:r.term.cols,rows:r.term.rows})}catch{}r.term.focus()}});return()=>cancelAnimationFrame(m)},[u]);const{t:R}=O(),x=l.useRef(void 0);return l.useEffect(()=>{if(b===x.current||(x.current=b,b!==!1))return;const m=N.current;m&&m.term.write(`\r
4
4
  \x1B[90m${R("exitBanner",{code:y??""})}\x1B[0m\r
@@ -1 +1 @@
1
- import{g as p,r as u,d as a}from"./chunk-SVP7TREG-IQRTD_4U.js";import{p as f}from"./chunk-JWPE2WC7-DTpnGTdB.js";import{_ as n,l as o}from"./mermaid.core-BI5_3AOv.js";import{M as c,b as d}from"./cynefin-OW5HDTMX-OsV-x0h-.js";import"./index-30RM921r.js";import"./markdown-BJJLXG-8.js";import"./react-ezqUM1Or.js";var v=d().RailroadAbnf.parser.LangiumParser,i=n(e=>{const r=e.alternatives.map(g);return r.length===1?r[0]:{type:"choice",alternatives:r}},"transformAlternation"),g=n(e=>{const r=e.elements.map(y);return r.length===1?r[0]:{type:"sequence",elements:r}},"transformConcatenation"),b=n(e=>{if(e.includes("*")){const[t,s]=e.split("*"),l=t?parseInt(t,10):0,m=s?parseInt(s,10):1/0;return{min:l,max:m}}const r=parseInt(e,10);return{min:r,max:r}},"parseRepeat"),y=n(e=>{const r=A(e.primary);if(!e.repeat)return r;const{min:t,max:s}=b(e.repeat);return t===0&&s===1?{type:"optional",element:r}:{type:"repetition",element:r,min:t,max:s}},"transformElement"),A=n(e=>{switch(e.$type){case"AbnfStringLiteral":return{type:"terminal",value:e.value};case"AbnfNumVal":return{type:"terminal",value:e.value};case"AbnfRuleName":return{type:"nonterminal",name:e.name};case"AbnfGroup":return i(e.element);case"AbnfOptionalGroup":return{type:"optional",element:i(e.element)};default:throw new Error(`Unsupported ABNF primary node: ${e.$type}`)}},"transformPrimary"),P=n(e=>({name:e.name,definition:i(e.definition)}),"transformRule"),h=n(e=>{f(e,a),e.title&&a.setTitle(e.title),e.rules.map(r=>a.addRule(P(r)))},"populateDb"),R={parse:n(e=>{a.clear(),o.debug("[ABNF Parser] Starting Langium parse");const r=v.parse(e);if(r.lexerErrors.length>0||r.parserErrors.length>0)throw new c(r);const t=r.value;o.debug("[ABNF Parser] Parsed rules:",t.rules.length),h(t),o.debug("[ABNF Parser] Parse complete")},"parse"),parser:{yy:a}},I={parser:R,db:a,renderer:u,styles:p};export{I as diagram};
1
+ import{g as p,r as u,d as a}from"./chunk-SVP7TREG-BhXOKkNm.js";import{p as f}from"./chunk-JWPE2WC7-BdI7zobW.js";import{_ as n,l as o}from"./mermaid.core-Bxpg8jiH.js";import{M as c,b as d}from"./cynefin-OW5HDTMX-DVcVxvWj.js";import"./index-B-D8dBbi.js";import"./markdown-BJJLXG-8.js";import"./react-ezqUM1Or.js";var v=d().RailroadAbnf.parser.LangiumParser,i=n(e=>{const r=e.alternatives.map(g);return r.length===1?r[0]:{type:"choice",alternatives:r}},"transformAlternation"),g=n(e=>{const r=e.elements.map(y);return r.length===1?r[0]:{type:"sequence",elements:r}},"transformConcatenation"),b=n(e=>{if(e.includes("*")){const[t,s]=e.split("*"),l=t?parseInt(t,10):0,m=s?parseInt(s,10):1/0;return{min:l,max:m}}const r=parseInt(e,10);return{min:r,max:r}},"parseRepeat"),y=n(e=>{const r=A(e.primary);if(!e.repeat)return r;const{min:t,max:s}=b(e.repeat);return t===0&&s===1?{type:"optional",element:r}:{type:"repetition",element:r,min:t,max:s}},"transformElement"),A=n(e=>{switch(e.$type){case"AbnfStringLiteral":return{type:"terminal",value:e.value};case"AbnfNumVal":return{type:"terminal",value:e.value};case"AbnfRuleName":return{type:"nonterminal",name:e.name};case"AbnfGroup":return i(e.element);case"AbnfOptionalGroup":return{type:"optional",element:i(e.element)};default:throw new Error(`Unsupported ABNF primary node: ${e.$type}`)}},"transformPrimary"),P=n(e=>({name:e.name,definition:i(e.definition)}),"transformRule"),h=n(e=>{f(e,a),e.title&&a.setTitle(e.title),e.rules.map(r=>a.addRule(P(r)))},"populateDb"),R={parse:n(e=>{a.clear(),o.debug("[ABNF Parser] Starting Langium parse");const r=v.parse(e);if(r.lexerErrors.length>0||r.parserErrors.length>0)throw new c(r);const t=r.value;o.debug("[ABNF Parser] Parsed rules:",t.rules.length),h(t),o.debug("[ABNF Parser] Parse complete")},"parse"),parser:{yy:a}},I={parser:R,db:a,renderer:u,styles:p};export{I as diagram};
@@ -1 +1 @@
1
- import{a0 as ln,a1 as an,a2 as y,a3 as tn,a4 as H,a5 as q,a6 as _,a7 as un,a8 as rn,a9 as L,aa as o,ab as B,ac as sn,ad as on,ae as fn}from"./mermaid.core-BI5_3AOv.js";function cn(l){return l.innerRadius}function yn(l){return l.outerRadius}function gn(l){return l.startAngle}function dn(l){return l.endAngle}function mn(l){return l&&l.padAngle}function pn(l,h,I,D,v,A,C,a){var O=I-l,i=D-h,n=C-v,d=a-A,u=d*O-n*i;if(!(u*u<y))return u=(n*(h-A)-d*(l-v))/u,[l+u*O,h+u*i]}function W(l,h,I,D,v,A,C){var a=l-I,O=h-D,i=(C?A:-A)/L(a*a+O*O),n=i*O,d=-i*a,u=l+n,s=h+d,f=I+n,c=D+d,F=(u+f)/2,t=(s+c)/2,m=f-u,g=c-s,R=m*m+g*g,T=v-A,P=u*c-f*s,S=(g<0?-1:1)*L(fn(0,T*T*R-P*P)),j=(P*g-m*S)/R,z=(-P*m-g*S)/R,w=(P*g+m*S)/R,p=(-P*m+g*S)/R,x=j-F,e=z-t,r=w-F,G=p-t;return x*x+e*e>r*r+G*G&&(j=w,z=p),{cx:j,cy:z,x01:-n,y01:-d,x11:j*(v/T-1),y11:z*(v/T-1)}}function hn(){var l=cn,h=yn,I=B(0),D=null,v=gn,A=dn,C=mn,a=null,O=ln(i);function i(){var n,d,u=+l.apply(this,arguments),s=+h.apply(this,arguments),f=v.apply(this,arguments)-an,c=A.apply(this,arguments)-an,F=un(c-f),t=c>f;if(a||(a=n=O()),s<u&&(d=s,s=u,u=d),!(s>y))a.moveTo(0,0);else if(F>tn-y)a.moveTo(s*H(f),s*q(f)),a.arc(0,0,s,f,c,!t),u>y&&(a.moveTo(u*H(c),u*q(c)),a.arc(0,0,u,c,f,t));else{var m=f,g=c,R=f,T=c,P=F,S=F,j=C.apply(this,arguments)/2,z=j>y&&(D?+D.apply(this,arguments):L(u*u+s*s)),w=_(un(s-u)/2,+I.apply(this,arguments)),p=w,x=w,e,r;if(z>y){var G=sn(z/u*q(j)),M=sn(z/s*q(j));(P-=G*2)>y?(G*=t?1:-1,R+=G,T-=G):(P=0,R=T=(f+c)/2),(S-=M*2)>y?(M*=t?1:-1,m+=M,g-=M):(S=0,m=g=(f+c)/2)}var J=s*H(m),K=s*q(m),N=u*H(T),Q=u*q(T);if(w>y){var U=s*H(g),V=s*q(g),X=u*H(R),Y=u*q(R),E;if(F<rn)if(E=pn(J,K,X,Y,U,V,N,Q)){var Z=J-E[0],$=K-E[1],b=U-E[0],k=V-E[1],nn=1/q(on((Z*b+$*k)/(L(Z*Z+$*$)*L(b*b+k*k)))/2),en=L(E[0]*E[0]+E[1]*E[1]);p=_(w,(u-en)/(nn-1)),x=_(w,(s-en)/(nn+1))}else p=x=0}S>y?x>y?(e=W(X,Y,J,K,s,x,t),r=W(U,V,N,Q,s,x,t),a.moveTo(e.cx+e.x01,e.cy+e.y01),x<w?a.arc(e.cx,e.cy,x,o(e.y01,e.x01),o(r.y01,r.x01),!t):(a.arc(e.cx,e.cy,x,o(e.y01,e.x01),o(e.y11,e.x11),!t),a.arc(0,0,s,o(e.cy+e.y11,e.cx+e.x11),o(r.cy+r.y11,r.cx+r.x11),!t),a.arc(r.cx,r.cy,x,o(r.y11,r.x11),o(r.y01,r.x01),!t))):(a.moveTo(J,K),a.arc(0,0,s,m,g,!t)):a.moveTo(J,K),!(u>y)||!(P>y)?a.lineTo(N,Q):p>y?(e=W(N,Q,U,V,u,-p,t),r=W(J,K,X,Y,u,-p,t),a.lineTo(e.cx+e.x01,e.cy+e.y01),p<w?a.arc(e.cx,e.cy,p,o(e.y01,e.x01),o(r.y01,r.x01),!t):(a.arc(e.cx,e.cy,p,o(e.y01,e.x01),o(e.y11,e.x11),!t),a.arc(0,0,u,o(e.cy+e.y11,e.cx+e.x11),o(r.cy+r.y11,r.cx+r.x11),t),a.arc(r.cx,r.cy,p,o(r.y11,r.x11),o(r.y01,r.x01),!t))):a.arc(0,0,u,T,R,t)}if(a.closePath(),n)return a=null,n+""||null}return i.centroid=function(){var n=(+l.apply(this,arguments)+ +h.apply(this,arguments))/2,d=(+v.apply(this,arguments)+ +A.apply(this,arguments))/2-rn/2;return[H(d)*n,q(d)*n]},i.innerRadius=function(n){return arguments.length?(l=typeof n=="function"?n:B(+n),i):l},i.outerRadius=function(n){return arguments.length?(h=typeof n=="function"?n:B(+n),i):h},i.cornerRadius=function(n){return arguments.length?(I=typeof n=="function"?n:B(+n),i):I},i.padRadius=function(n){return arguments.length?(D=n==null?null:typeof n=="function"?n:B(+n),i):D},i.startAngle=function(n){return arguments.length?(v=typeof n=="function"?n:B(+n),i):v},i.endAngle=function(n){return arguments.length?(A=typeof n=="function"?n:B(+n),i):A},i.padAngle=function(n){return arguments.length?(C=typeof n=="function"?n:B(+n),i):C},i.context=function(n){return arguments.length?(a=n??null,i):a},i}export{hn as d};
1
+ import{a0 as ln,a1 as an,a2 as y,a3 as tn,a4 as H,a5 as q,a6 as _,a7 as un,a8 as rn,a9 as L,aa as o,ab as B,ac as sn,ad as on,ae as fn}from"./mermaid.core-Bxpg8jiH.js";function cn(l){return l.innerRadius}function yn(l){return l.outerRadius}function gn(l){return l.startAngle}function dn(l){return l.endAngle}function mn(l){return l&&l.padAngle}function pn(l,h,I,D,v,A,C,a){var O=I-l,i=D-h,n=C-v,d=a-A,u=d*O-n*i;if(!(u*u<y))return u=(n*(h-A)-d*(l-v))/u,[l+u*O,h+u*i]}function W(l,h,I,D,v,A,C){var a=l-I,O=h-D,i=(C?A:-A)/L(a*a+O*O),n=i*O,d=-i*a,u=l+n,s=h+d,f=I+n,c=D+d,F=(u+f)/2,t=(s+c)/2,m=f-u,g=c-s,R=m*m+g*g,T=v-A,P=u*c-f*s,S=(g<0?-1:1)*L(fn(0,T*T*R-P*P)),j=(P*g-m*S)/R,z=(-P*m-g*S)/R,w=(P*g+m*S)/R,p=(-P*m+g*S)/R,x=j-F,e=z-t,r=w-F,G=p-t;return x*x+e*e>r*r+G*G&&(j=w,z=p),{cx:j,cy:z,x01:-n,y01:-d,x11:j*(v/T-1),y11:z*(v/T-1)}}function hn(){var l=cn,h=yn,I=B(0),D=null,v=gn,A=dn,C=mn,a=null,O=ln(i);function i(){var n,d,u=+l.apply(this,arguments),s=+h.apply(this,arguments),f=v.apply(this,arguments)-an,c=A.apply(this,arguments)-an,F=un(c-f),t=c>f;if(a||(a=n=O()),s<u&&(d=s,s=u,u=d),!(s>y))a.moveTo(0,0);else if(F>tn-y)a.moveTo(s*H(f),s*q(f)),a.arc(0,0,s,f,c,!t),u>y&&(a.moveTo(u*H(c),u*q(c)),a.arc(0,0,u,c,f,t));else{var m=f,g=c,R=f,T=c,P=F,S=F,j=C.apply(this,arguments)/2,z=j>y&&(D?+D.apply(this,arguments):L(u*u+s*s)),w=_(un(s-u)/2,+I.apply(this,arguments)),p=w,x=w,e,r;if(z>y){var G=sn(z/u*q(j)),M=sn(z/s*q(j));(P-=G*2)>y?(G*=t?1:-1,R+=G,T-=G):(P=0,R=T=(f+c)/2),(S-=M*2)>y?(M*=t?1:-1,m+=M,g-=M):(S=0,m=g=(f+c)/2)}var J=s*H(m),K=s*q(m),N=u*H(T),Q=u*q(T);if(w>y){var U=s*H(g),V=s*q(g),X=u*H(R),Y=u*q(R),E;if(F<rn)if(E=pn(J,K,X,Y,U,V,N,Q)){var Z=J-E[0],$=K-E[1],b=U-E[0],k=V-E[1],nn=1/q(on((Z*b+$*k)/(L(Z*Z+$*$)*L(b*b+k*k)))/2),en=L(E[0]*E[0]+E[1]*E[1]);p=_(w,(u-en)/(nn-1)),x=_(w,(s-en)/(nn+1))}else p=x=0}S>y?x>y?(e=W(X,Y,J,K,s,x,t),r=W(U,V,N,Q,s,x,t),a.moveTo(e.cx+e.x01,e.cy+e.y01),x<w?a.arc(e.cx,e.cy,x,o(e.y01,e.x01),o(r.y01,r.x01),!t):(a.arc(e.cx,e.cy,x,o(e.y01,e.x01),o(e.y11,e.x11),!t),a.arc(0,0,s,o(e.cy+e.y11,e.cx+e.x11),o(r.cy+r.y11,r.cx+r.x11),!t),a.arc(r.cx,r.cy,x,o(r.y11,r.x11),o(r.y01,r.x01),!t))):(a.moveTo(J,K),a.arc(0,0,s,m,g,!t)):a.moveTo(J,K),!(u>y)||!(P>y)?a.lineTo(N,Q):p>y?(e=W(N,Q,U,V,u,-p,t),r=W(J,K,X,Y,u,-p,t),a.lineTo(e.cx+e.x01,e.cy+e.y01),p<w?a.arc(e.cx,e.cy,p,o(e.y01,e.x01),o(r.y01,r.x01),!t):(a.arc(e.cx,e.cy,p,o(e.y01,e.x01),o(e.y11,e.x11),!t),a.arc(0,0,u,o(e.cy+e.y11,e.cx+e.x11),o(r.cy+r.y11,r.cx+r.x11),t),a.arc(r.cx,r.cy,p,o(r.y11,r.x11),o(r.y01,r.x01),!t))):a.arc(0,0,u,T,R,t)}if(a.closePath(),n)return a=null,n+""||null}return i.centroid=function(){var n=(+l.apply(this,arguments)+ +h.apply(this,arguments))/2,d=(+v.apply(this,arguments)+ +A.apply(this,arguments))/2-rn/2;return[H(d)*n,q(d)*n]},i.innerRadius=function(n){return arguments.length?(l=typeof n=="function"?n:B(+n),i):l},i.outerRadius=function(n){return arguments.length?(h=typeof n=="function"?n:B(+n),i):h},i.cornerRadius=function(n){return arguments.length?(I=typeof n=="function"?n:B(+n),i):I},i.padRadius=function(n){return arguments.length?(D=n==null?null:typeof n=="function"?n:B(+n),i):D},i.startAngle=function(n){return arguments.length?(v=typeof n=="function"?n:B(+n),i):v},i.endAngle=function(n){return arguments.length?(A=typeof n=="function"?n:B(+n),i):A},i.padAngle=function(n){return arguments.length?(C=typeof n=="function"?n:B(+n),i):C},i.context=function(n){return arguments.length?(a=n??null,i):a},i}export{hn as d};