pi-web-ui 0.49.0 → 0.50.0

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.
@@ -1027,6 +1027,42 @@ export class ClientSession {
1027
1027
  conv.queueSteering = [...event.steering];
1028
1028
  conv.queueFollowUp = [...event.followUp];
1029
1029
  break;
1030
+ // 手动 /compact 或阈值/溢出自动压缩开始——立即反馈,避免「没反应」
1031
+ // (此前 compaction_start/end 事件被 switch 静默丢弃,issue #33)。
1032
+ case "compaction_start": {
1033
+ this.emit({
1034
+ type: "notice",
1035
+ level: "info",
1036
+ text: "正在压缩上下文…(压缩摘要将显示在消息区)",
1037
+ });
1038
+ break;
1039
+ }
1040
+ case "compaction_end": {
1041
+ if (event.errorMessage) {
1042
+ this.emit({
1043
+ type: "notice",
1044
+ level: "error",
1045
+ text: `压缩上下文失败:${event.errorMessage}`,
1046
+ });
1047
+ }
1048
+ else if (event.aborted) {
1049
+ this.emit({
1050
+ type: "notice",
1051
+ level: "warning",
1052
+ text: "压缩上下文已取消",
1053
+ });
1054
+ }
1055
+ else if (event.result) {
1056
+ const { tokensBefore, estimatedTokensAfter } = event.result;
1057
+ const after = estimatedTokensAfter ?? tokensBefore;
1058
+ this.emit({
1059
+ type: "notice",
1060
+ level: "info",
1061
+ text: `上下文压缩完成:${tokensBefore.toLocaleString()} → ${after.toLocaleString()} tokens(摘要已插入消息区)`,
1062
+ });
1063
+ }
1064
+ break;
1065
+ }
1030
1066
  // A run finished or a new entry was persisted — keep the session list fresh
1031
1067
  // (new chat + first message, completed turns, compaction, etc.).
1032
1068
  case "agent_end": {
@@ -1108,7 +1144,9 @@ export class ClientSession {
1108
1144
  // Snapshot checkpoint policy: deltas carry live rendering during streaming;
1109
1145
  // full snapshots are reconciliation checkpoints taken immediately at
1110
1146
  // run/tool boundaries and on a slow timer otherwise.
1111
- if (event.type === "agent_end" || event.type === "tool_execution_end") {
1147
+ if (event.type === "agent_end" ||
1148
+ event.type === "tool_execution_end" ||
1149
+ event.type === "compaction_end") {
1112
1150
  this.flushSnapshot();
1113
1151
  }
1114
1152
  else {
@@ -157,12 +157,10 @@ export class SlashCommandsService {
157
157
  try {
158
158
  await this.host.getSession().compact(args || undefined);
159
159
  }
160
- catch (err) {
161
- this.host.emit({
162
- type: "notice",
163
- level: "error",
164
- text: `压缩上下文失败:${err.message}`,
165
- });
160
+ catch {
161
+ // 压缩过程/结果/错误反馈统一由 agent-service onEvent 的
162
+ // compaction_start / compaction_end 事件处理(含 errorMessage),
163
+ // 这里不重复发通知;SDK 在 throw 前必发 compaction_end(issue #33)。
166
164
  }
167
165
  return true;
168
166
  case "cwd":
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-web-ui",
3
- "version": "0.49.0",
3
+ "version": "0.50.0",
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": {
@@ -3836,17 +3836,38 @@ span.msg-editor-hint svg {
3836
3836
  background: #0a0a0f !important;
3837
3837
  border: 1px solid var(--border);
3838
3838
  border-radius: 8px;
3839
- padding: 12px 14px;
3839
+ padding: 10px 0;
3840
3840
  overflow-x: auto;
3841
3841
  margin: 0;
3842
3842
  }
3843
- .codeblock code {
3843
+ /* 每个逻辑行一行(issue #36):行号 gutter + 自动换行主体 */
3844
+ .code-line {
3845
+ display: flex;
3846
+ align-items: flex-start;
3847
+ min-width: 0;
3848
+ padding: 0 14px;
3849
+ }
3850
+ .code-line .code-num {
3851
+ flex: 0 0 auto;
3852
+ text-align: right;
3853
+ color: var(--text-faint);
3854
+ font-family: var(--mono);
3855
+ font-size: 12.5px;
3856
+ line-height: 1.55;
3857
+ user-select: none;
3858
+ padding-right: 12px;
3859
+ }
3860
+ .codeblock code.code-line-body {
3844
3861
  background: transparent;
3845
3862
  border: none;
3846
3863
  padding: 0;
3847
3864
  font-family: var(--mono);
3848
3865
  font-size: 12.5px;
3849
3866
  line-height: 1.55;
3867
+ flex: 1;
3868
+ min-width: 0;
3869
+ white-space: pre-wrap;
3870
+ word-break: break-word;
3850
3871
  }
3851
3872
 
3852
3873
  .copy-btn {
@@ -7204,15 +7225,18 @@ span.msg-editor-hint svg {
7204
7225
  .fp-markdown .codeblock pre {
7205
7226
  max-width: 100%;
7206
7227
  min-width: 0;
7207
- padding: 14px 16px;
7228
+ padding: 14px 0;
7208
7229
  border-color: var(--border);
7209
7230
  border-radius: 10px;
7210
7231
  font-size: 12.5px;
7211
7232
  line-height: 1.65;
7212
7233
  }
7234
+ .fp-markdown .code-line {
7235
+ padding: 0 16px;
7236
+ }
7213
7237
  .fp-markdown .codeblock pre code {
7214
- white-space: pre;
7215
- word-break: normal;
7238
+ white-space: pre-wrap;
7239
+ word-break: break-word;
7216
7240
  }
7217
7241
  .fp-markdown img {
7218
7242
  display: block;
package/themes/dazzle.css CHANGED
@@ -3836,17 +3836,38 @@ span.msg-editor-hint svg {
3836
3836
  background: #0b0b14 !important;
3837
3837
  border: 1px solid var(--border);
3838
3838
  border-radius: 8px;
3839
- padding: 12px 14px;
3839
+ padding: 10px 0;
3840
3840
  overflow-x: auto;
3841
3841
  margin: 0;
3842
3842
  }
3843
- .codeblock code {
3843
+ /* 每个逻辑行一行(issue #36):行号 gutter + 自动换行主体 */
3844
+ .code-line {
3845
+ display: flex;
3846
+ align-items: flex-start;
3847
+ min-width: 0;
3848
+ padding: 0 14px;
3849
+ }
3850
+ .code-line .code-num {
3851
+ flex: 0 0 auto;
3852
+ text-align: right;
3853
+ color: var(--text-faint);
3854
+ font-family: var(--mono);
3855
+ font-size: 12.5px;
3856
+ line-height: 1.55;
3857
+ user-select: none;
3858
+ padding-right: 12px;
3859
+ }
3860
+ .codeblock code.code-line-body {
3844
3861
  background: transparent;
3845
3862
  border: none;
3846
3863
  padding: 0;
3847
3864
  font-family: var(--mono);
3848
3865
  font-size: 12.5px;
3849
3866
  line-height: 1.55;
3867
+ flex: 1;
3868
+ min-width: 0;
3869
+ white-space: pre-wrap;
3870
+ word-break: break-word;
3850
3871
  }
3851
3872
 
3852
3873
  .copy-btn {
@@ -7204,15 +7225,18 @@ span.msg-editor-hint svg {
7204
7225
  .fp-markdown .codeblock pre {
7205
7226
  max-width: 100%;
7206
7227
  min-width: 0;
7207
- padding: 14px 16px;
7228
+ padding: 14px 0;
7208
7229
  border-color: var(--border);
7209
7230
  border-radius: 10px;
7210
7231
  font-size: 12.5px;
7211
7232
  line-height: 1.65;
7212
7233
  }
7234
+ .fp-markdown .code-line {
7235
+ padding: 0 16px;
7236
+ }
7213
7237
  .fp-markdown .codeblock pre code {
7214
- white-space: pre;
7215
- word-break: normal;
7238
+ white-space: pre-wrap;
7239
+ word-break: break-word;
7216
7240
  }
7217
7241
  .fp-markdown img {
7218
7242
  display: block;
package/themes/light.css CHANGED
@@ -2391,7 +2391,7 @@ body.panel-resizing {
2391
2391
  color: var(--text);
2392
2392
  }
2393
2393
  .bg-task-cmd.open code {
2394
- white-space: pre-wrap;
2394
+ white-space: pre-wrap;
2395
2395
  overflow-wrap: anywhere;
2396
2396
  }
2397
2397
  .bg-task-stop {
@@ -3493,17 +3493,38 @@ body.panel-resizing {
3493
3493
  background: #f6f8fa !important;
3494
3494
  border: 1px solid var(--border);
3495
3495
  border-radius: 8px;
3496
- padding: 12px 14px;
3496
+ padding: 10px 0;
3497
3497
  overflow-x: auto;
3498
3498
  margin: 0;
3499
3499
  }
3500
- .codeblock code {
3500
+ /* 每个逻辑行一行(issue #36):行号 gutter + 自动换行主体 */
3501
+ .code-line {
3502
+ display: flex;
3503
+ align-items: flex-start;
3504
+ min-width: 0;
3505
+ padding: 0 14px;
3506
+ }
3507
+ .code-line .code-num {
3508
+ flex: 0 0 auto;
3509
+ text-align: right;
3510
+ color: var(--text-faint);
3511
+ font-family: var(--mono);
3512
+ font-size: 12.5px;
3513
+ line-height: 1.55;
3514
+ user-select: none;
3515
+ padding-right: 12px;
3516
+ }
3517
+ .codeblock code.code-line-body {
3501
3518
  background: transparent;
3502
3519
  border: none;
3503
3520
  padding: 0;
3504
3521
  font-family: var(--mono);
3505
3522
  font-size: 12.5px;
3506
3523
  line-height: 1.55;
3524
+ flex: 1;
3525
+ min-width: 0;
3526
+ white-space: pre-wrap;
3527
+ word-break: break-word;
3507
3528
  }
3508
3529
 
3509
3530
  .copy-btn {
@@ -6418,15 +6439,18 @@ body.panel-resizing {
6418
6439
  .fp-markdown .codeblock pre {
6419
6440
  max-width: 100%;
6420
6441
  min-width: 0;
6421
- padding: 14px 16px;
6442
+ padding: 14px 0;
6422
6443
  border-color: var(--border);
6423
6444
  border-radius: 10px;
6424
6445
  font-size: 12.5px;
6425
6446
  line-height: 1.65;
6426
6447
  }
6448
+ .fp-markdown .code-line {
6449
+ padding: 0 16px;
6450
+ }
6427
6451
  .fp-markdown .codeblock pre code {
6428
- white-space: pre;
6429
- word-break: normal;
6452
+ white-space: pre-wrap;
6453
+ word-break: break-word;
6430
6454
  }
6431
6455
  .fp-markdown img {
6432
6456
  display: block;