@liguoshuai/pi-web-chat 1.8.7 → 1.8.9

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/docs/CHANGELOG.md CHANGED
@@ -7,6 +7,30 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ---
9
9
 
10
+ ## [1.8.9] - 2026-08-29
11
+
12
+ ### Fixed
13
+ - **Markdown 下划线变量与标识符渲染保护 (Markdown Identifier & Underscore Parsing Protection)**:
14
+ - 优化行内 Markdown 解析器,限定下划线 `_` 仅在非单词边界(空格/标点包裹)时触发斜体,防止编程标识符与文件名(如 `user_id_list`、`process.env.NODE_ENV`)被误切分解析为斜体。
15
+ - 优化加粗与嵌套斜体(`**bold and *italic***`)的非贪婪匹配规则。
16
+ - **移动端模型选择菜单支持“设为默认” (Mobile Model Selector 'Set Default' Accessibility)**:
17
+ - 在移动端媒体查询下保持 `.btn-set-default` 可见(`opacity: 1`),修复手机端因缺少 hover 无法将模型设为全局默认的问题。
18
+ - **工具调用头部与顶栏弹性布局溢出保护 (Tool Block & Topbar Flex Overflow Protection)**:
19
+ - 给 `.tool-head .args` 增加 `min-width: 0`,防止长命令/长文件路径将右侧“复制”按钮与“执行状态”标签挤出卡片。
20
+ - 给桌面端 `.topbar .session-name` 增加 `min-width: 0`,防止窄屏下超长会话标题破坏顶栏胶囊布局。
21
+
22
+ ---
23
+
24
+ ## [1.8.8] - 2026-08-29
25
+
26
+ ### Fixed
27
+ - **消息发送框确认按钮上下居中与正圆对齐优化 (Composer Send Button Alignment & Circular Sizing)**:
28
+ - 修复默认单行输入状态下,发送按钮因与 `textarea` 存在高度差并在 `flex-end` 布局下导致严重偏下、没有垂直居中的问题。
29
+ - 精准对齐单行 `textarea` 高度(32px)与按钮高度(32px),使单行状态下发送/确认按钮在输入框内绝对垂直居中,多行输入时依然平滑吸底。
30
+ - 将桌面端发送按钮修正为标准正圆(`32px × 32px`,`border-radius: 50%`),并补充字号与行高约束,确保图标居中且不影响手机侧及响应式体验。
31
+
32
+ ---
33
+
10
34
  ## [1.8.5] - 2026-08-23
11
35
 
12
36
  ### Fixed
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@liguoshuai/pi-web-chat",
3
- "version": "1.8.7",
3
+ "version": "1.8.9",
4
4
  "description": "A ChatGPT/Gemini-style web UI for the pi coding agent, powered by pi's RPC mode.",
5
5
  "type": "module",
6
6
  "main": "server.js",
package/public/app.js CHANGED
@@ -422,16 +422,16 @@ function renderInlineMd(text) {
422
422
 
423
423
  // helper state bag attached to the function during line scan
424
424
  function mdInlineBlock(text) {
425
- function esc(s) { return escapeHtml(s); }
426
425
  let s = escapeHtml(text);
427
426
  // bold
428
- s = s.replace(/\*\*([^*]+)\*\*/g, "<strong>$1</strong>");
429
- s = s.replace(/__([^_]+)__/g, "<strong>$1</strong>");
427
+ s = s.replace(/\*\*(.+?)\*\*/g, "<strong>$1</strong>");
428
+ s = s.replace(/__(.+?)__/g, "<strong>$1</strong>");
430
429
  // strikethrough
431
- s = s.replace(/~~([^~]+)~~/g, "<del>$1</del>");
432
- // italic
433
- s = s.replace(/(^|[^*])\*([^*]+)\*/g, "$1<em>$2</em>");
434
- s = s.replace(/(^|[^_])_([^_]+)_/g, "$1<em>$2</em>");
430
+ s = s.replace(/~~(.+?)~~/g, "<del>$1</del>");
431
+ // italic (asterisk)
432
+ s = s.replace(/(^|[^*])\*([^*\s](?:[^*]*?[^*\s])?)\*(?!\*)/g, "$1<em>$2</em>");
433
+ // italic (underscore): only match boundary/space so identifier_names are preserved
434
+ s = s.replace(/(^|[\s(\[<,;:])_([^_\s](?:[^_]*?[^_\s])?)_(?=[\s)\]>,;:!?.]|$)/g, "$1<em>$2</em>");
435
435
  // links [txt](url)
436
436
  s = s.replace(/\[([^\]]+)\]\((https?:\/\/[^\s)]+)\)/g, '<a href="$2" target="_blank" rel="noopener">$1</a>');
437
437
  return s;
package/public/style.css CHANGED
@@ -202,6 +202,7 @@ body {
202
202
  color: var(--text);
203
203
  font-weight: 500;
204
204
  flex: 1;
205
+ min-width: 0;
205
206
  white-space: nowrap;
206
207
  overflow: hidden;
207
208
  text-overflow: ellipsis;
@@ -496,7 +497,7 @@ body {
496
497
  }
497
498
  .tool-head .ic { color: var(--accent); font-size: 12px; }
498
499
  .tool-head .name { font-weight: 600; color: var(--text); }
499
- .tool-head .args { color: var(--text-muted); font-family: monospace; flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
500
+ .tool-head .args { color: var(--text-muted); font-family: monospace; flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
500
501
  .tool-head .state { font-size: 11px; color: var(--text-dim); padding: 2px 8px; background: #2a2a2a; border-radius: 999px; }
501
502
  .tool-head .state.error { color: var(--danger); background: #3a1a1a; }
502
503
  .tool-body {
@@ -718,13 +719,14 @@ body {
718
719
  }
719
720
  .composer textarea {
720
721
  flex: 1; background: transparent; border: none; outline: none; resize: none;
721
- color: var(--text); font-family: inherit; font-size: 15px; line-height: 1.5;
722
- padding: 10px 0; max-height: 200px; min-height: 24px;
722
+ color: var(--text); font-family: inherit; font-size: 15px; line-height: 20px;
723
+ padding: 6px 0; max-height: 200px; min-height: 32px;
723
724
  }
724
725
  .composer .send-btn {
725
- width: 36px; height: 32px; border-radius: 18px; border: none; cursor: pointer;
726
+ width: 32px; height: 32px; border-radius: 50%; border: none; cursor: pointer;
726
727
  background: var(--accent); color: #fff; display: flex; align-items: center; justify-content: center;
727
- flex-shrink: 0; transition: background .15s, opacity .15s, transform .1s;
728
+ flex-shrink: 0; font-size: 16px; font-weight: 600; line-height: 1;
729
+ transition: background .15s, opacity .15s, transform .1s;
728
730
  }
729
731
  .composer .send-btn:disabled { background: #3a3a3a; color: #6f6f6f; cursor: not-allowed; }
730
732
  .composer .send-btn.stop { background: var(--danger); }
@@ -1364,6 +1366,11 @@ body {
1364
1366
  .model-menu-list {
1365
1367
  max-height: calc(100dvh - 130px);
1366
1368
  }
1369
+ .btn-set-default {
1370
+ opacity: 1;
1371
+ font-size: 10px;
1372
+ padding: 2px 6px;
1373
+ }
1367
1374
 
1368
1375
  .empty-model-banner {
1369
1376
  padding: 10px 12px;
@@ -1453,20 +1460,23 @@ body {
1453
1460
  }
1454
1461
 
1455
1462
  .composer-inner {
1456
- padding: 4px 6px 4px 12px;
1457
- border-radius: 20px;
1463
+ padding: 6px 8px 6px 14px;
1464
+ border-radius: 22px;
1458
1465
  gap: 6px;
1459
1466
  }
1460
1467
 
1461
1468
  .composer textarea {
1462
- padding: 8px 0;
1469
+ padding: 6px 0;
1463
1470
  font-size: 14px;
1471
+ line-height: 20px;
1472
+ min-height: 32px;
1464
1473
  max-height: 160px;
1465
1474
  }
1466
1475
 
1467
1476
  .composer .send-btn {
1468
1477
  width: 32px;
1469
1478
  height: 32px;
1479
+ border-radius: 50%;
1470
1480
  }
1471
1481
 
1472
1482
  /* CWD Modal Mobile Adjustments */