@herbertgao/pi-extensions 2026.10.4 → 2026.10.6
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 +2 -2
- package/node_modules/@herbertgao/pi-cc-extensions/README.en.md +13 -9
- package/node_modules/@herbertgao/pi-cc-extensions/README.md +13 -9
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/config.ts +72 -16
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/panel.ts +262 -48
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/agent-summary/core.ts +2 -3
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/compact-thinking.ts +1 -1
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/context.ts +131 -28
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/reference/index.ts +2 -0
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/reference/subagent.ts +3 -0
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/shell/footer-currency.ts +29 -0
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/shell/footer.ts +96 -59
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/shell/git-stats.ts +162 -0
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/shell/token-rate.ts +204 -0
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/shell/working-message.ts +51 -86
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/compact-mode.ts +212 -74
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/default-mode.ts +50 -362
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/index.ts +35 -3
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/markdown-enhance.ts +16 -83
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/hover.ts +1 -1
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/interaction.ts +28 -26
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/packets.ts +1 -1
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/sticky-prompt.ts +450 -0
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/ask-user-question.ts +173 -0
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/ccstyle-tool.ts +467 -0
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/codemode.ts +5 -9
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/ansi-utils.ts +1 -24
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-edit-render.ts +64 -11
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-limits.ts +1 -1
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-presentation.ts +41 -0
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-renderer.ts +5 -1
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-text.ts +2 -1
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/diff-write-render.ts +36 -10
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/line-width-safety.ts +1 -1
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/grouping.ts +140 -51
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/message-display.ts +1 -1
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/names.ts +44 -4
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/result.ts +34 -803
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/tool-io.ts +735 -0
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/tool-state.ts +138 -0
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/utils/format.ts +9 -0
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/utils/patch-keys.ts +5 -0
- package/node_modules/@herbertgao/pi-cc-extensions/package.json +5 -4
- package/node_modules/@herbertgao/pi-cc-extensions/themes/cc-dark.json +2 -2
- package/node_modules/@herbertgao/pi-cc-extensions/themes/cc-light.json +3 -3
- package/node_modules/@herbertgao/pi-subagents/package.json +2 -1
- package/node_modules/@herbertgao/sol-pi/README.md +3 -3
- package/node_modules/@herbertgao/sol-pi/THIRD_PARTY_NOTICES.md +4 -4
- package/node_modules/@herbertgao/sol-pi/agents-install.md +3 -3
- package/node_modules/@herbertgao/sol-pi/docs/compatibility.md +1 -1
- package/package.json +2 -2
- package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/show-more-hint.ts +0 -48
|
@@ -11,7 +11,12 @@ import {
|
|
|
11
11
|
applyCustomFooter,
|
|
12
12
|
clearCustomFooter,
|
|
13
13
|
getFooterStatusSnapshot,
|
|
14
|
+
refreshFooterGitStats,
|
|
14
15
|
} from "../feature/shell/footer.ts";
|
|
16
|
+
import {
|
|
17
|
+
FOOTER_CURRENCY_PRESETS,
|
|
18
|
+
presetFooterCurrencyRate,
|
|
19
|
+
} from "../feature/shell/footer-currency.ts";
|
|
15
20
|
import {
|
|
16
21
|
footerChipDescription,
|
|
17
22
|
footerLineOfKey,
|
|
@@ -37,21 +42,24 @@ import {
|
|
|
37
42
|
EXPANDED_INPUT_MAX_LINES_VALUES,
|
|
38
43
|
EXPANDED_OUTPUT_MAX_LINES_VALUES,
|
|
39
44
|
EXPANDED_PREVIEW_MAX_LINES_VALUES,
|
|
45
|
+
FOOTER_GIT_STATS_MODES,
|
|
46
|
+
FOOTER_TOKEN_RATE_MODES,
|
|
40
47
|
formatExcludeRenderers,
|
|
41
48
|
getCompactThinkingConfig,
|
|
42
|
-
pickInputClip,
|
|
43
49
|
pickPositiveInt,
|
|
44
50
|
pickPositiveNumber,
|
|
45
|
-
|
|
51
|
+
pickToolLabelClip,
|
|
46
52
|
THINKING_ANIMATION_INTERVAL_VALUES,
|
|
47
53
|
THINKING_PREVIEW_LINES_VALUES,
|
|
48
|
-
|
|
54
|
+
TOOL_LABEL_CLIP_VALUES,
|
|
49
55
|
WRITE_DIFF_COLLAPSED_LINES_VALUES,
|
|
50
56
|
updateConfig,
|
|
51
57
|
type CompactStyleMode,
|
|
52
58
|
type Config,
|
|
53
59
|
type DiffIndicatorMode,
|
|
54
60
|
type DiffViewMode,
|
|
61
|
+
type FooterGitStatsMode,
|
|
62
|
+
type FooterTokenRateMode,
|
|
55
63
|
} from "./config.ts";
|
|
56
64
|
|
|
57
65
|
/** renderer 注入的渲染副作用,面板自身不触碰渲染状态。 */
|
|
@@ -62,7 +70,7 @@ export type CcstylePanelHooks = {
|
|
|
62
70
|
|
|
63
71
|
function modeSettingDescription(mode: CompactStyleMode): string {
|
|
64
72
|
if (mode === "compact") {
|
|
65
|
-
return "
|
|
73
|
+
return "One summary line per assistant round; edit/write reuse the same Diff preview settings as on.";
|
|
66
74
|
}
|
|
67
75
|
if (mode === "off") {
|
|
68
76
|
return "Pi native tool rendering. Diff options below still apply independently.";
|
|
@@ -81,6 +89,30 @@ function customFooterDescription(enabled: boolean): string {
|
|
|
81
89
|
return "Custom status bar with model, context, cache, cost, git, and plugin chips.";
|
|
82
90
|
}
|
|
83
91
|
|
|
92
|
+
function footerTokenRateDescription(enabled: boolean): string {
|
|
93
|
+
return enabled
|
|
94
|
+
? "Output rate chip after the cache hit rate. Turn off to hide it."
|
|
95
|
+
: "Output rate chip hidden.";
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function footerTokenRateModeDescription(mode: FooterTokenRateMode): string {
|
|
99
|
+
return mode === "live"
|
|
100
|
+
? "Sliding 1s rate while generating (live). Tool waits are excluded. Falls back to the run average between chunks and after the prompt."
|
|
101
|
+
: "Average over the whole user prompt (avg), including tool waits. Stays until the next prompt.";
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function footerTokenRateTtftDescription(enabled: boolean): string {
|
|
105
|
+
return enabled
|
|
106
|
+
? "Append time to first token, e.g. (TTFT: 812ms) or (TTFT: 1.2s). Turn off to show the rate only."
|
|
107
|
+
: "Time to first token hidden. The rate chip shows tok/s only.";
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function footerGitStatsDescription(mode: FooterGitStatsMode): string {
|
|
111
|
+
return mode === "branch"
|
|
112
|
+
? "Net changes since the merge base, including uncommitted edits. Base: origin/HEAD, then local main/master. Untracked files excluded; unavailable stats hidden."
|
|
113
|
+
: "Uncommitted net changes relative to HEAD (default). Includes staged and unstaged edits; excludes untracked files.";
|
|
114
|
+
}
|
|
115
|
+
|
|
84
116
|
function pluginChipsDescription(): string {
|
|
85
117
|
return `Arrange plugin chips: ${formatFooterChipSummary(config)}. Enter to edit.`;
|
|
86
118
|
}
|
|
@@ -281,10 +313,22 @@ function buildExcludeRenderersSubmenu(
|
|
|
281
313
|
};
|
|
282
314
|
}
|
|
283
315
|
|
|
284
|
-
|
|
285
|
-
|
|
316
|
+
function footerCurrencyRateLabel(rate: number | null): string {
|
|
317
|
+
return rate === null ? "-" : String(rate);
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* 手动输入子面板。accept 返回字符串则提交,undefined 取消,null 用 invalid 提示。
|
|
322
|
+
*/
|
|
323
|
+
function buildValueInputSubmenu(
|
|
286
324
|
theme: any,
|
|
287
|
-
|
|
325
|
+
options: {
|
|
326
|
+
prompt: string;
|
|
327
|
+
initial: string;
|
|
328
|
+
hint: string;
|
|
329
|
+
accept: (raw: string) => string | null | undefined;
|
|
330
|
+
invalid?: (raw: string) => string;
|
|
331
|
+
},
|
|
288
332
|
closeSubmenu: (selected?: string) => void,
|
|
289
333
|
): {
|
|
290
334
|
render: (width: number) => string[];
|
|
@@ -293,27 +337,28 @@ function buildNumberInputSubmenu(
|
|
|
293
337
|
} {
|
|
294
338
|
const input = new Input();
|
|
295
339
|
let error = "";
|
|
296
|
-
input.setValue(
|
|
340
|
+
input.setValue(options.initial);
|
|
297
341
|
input.onSubmit = (value: string) => {
|
|
298
342
|
const raw = value.trim();
|
|
299
|
-
|
|
300
|
-
|
|
343
|
+
const next = options.accept(raw);
|
|
344
|
+
if (next === undefined) {
|
|
345
|
+
closeSubmenu();
|
|
301
346
|
return;
|
|
302
347
|
}
|
|
303
|
-
if (
|
|
304
|
-
error =
|
|
348
|
+
if (next === null) {
|
|
349
|
+
error = options.invalid?.(raw) ?? "Invalid value";
|
|
305
350
|
return;
|
|
306
351
|
}
|
|
307
|
-
closeSubmenu(
|
|
352
|
+
closeSubmenu(next);
|
|
308
353
|
};
|
|
309
354
|
input.onEscape = () => closeSubmenu();
|
|
310
355
|
return {
|
|
311
356
|
render: (width: number) => {
|
|
312
357
|
const safe = Math.max(0, Math.floor(width));
|
|
313
358
|
const lines = [
|
|
314
|
-
theme.fg("dim",
|
|
359
|
+
theme.fg("dim", options.prompt),
|
|
315
360
|
...input.render(safe),
|
|
316
|
-
truncateToWidth(theme.fg("dim",
|
|
361
|
+
truncateToWidth(theme.fg("dim", options.hint), safe),
|
|
317
362
|
];
|
|
318
363
|
if (error !== "") lines.push(theme.fg("dim", ` ${error}`));
|
|
319
364
|
return lines;
|
|
@@ -323,6 +368,25 @@ function buildNumberInputSubmenu(
|
|
|
323
368
|
};
|
|
324
369
|
}
|
|
325
370
|
|
|
371
|
+
/** 数值项:预填当前值,空输入取消,非数字留下错误。 */
|
|
372
|
+
function buildNumberInputSubmenu(
|
|
373
|
+
theme: any,
|
|
374
|
+
setting: { label: string; currentValue: string },
|
|
375
|
+
closeSubmenu: (selected?: string) => void,
|
|
376
|
+
) {
|
|
377
|
+
return buildValueInputSubmenu(
|
|
378
|
+
theme,
|
|
379
|
+
{
|
|
380
|
+
prompt: ` ${setting.label} — custom value:`,
|
|
381
|
+
initial: setting.currentValue,
|
|
382
|
+
hint: " Enter to apply · Esc to go back",
|
|
383
|
+
accept: (raw) => (raw === "" ? undefined : Number.isFinite(Number(raw)) ? raw : null),
|
|
384
|
+
invalid: (raw) => `Invalid number: "${raw}"`,
|
|
385
|
+
},
|
|
386
|
+
closeSubmenu,
|
|
387
|
+
);
|
|
388
|
+
}
|
|
389
|
+
|
|
326
390
|
/** Section tabs for /ccstyle — matches Zentui-style "A / B / C" headers. */
|
|
327
391
|
type CcstyleSection = {
|
|
328
392
|
id: "style" | "diff" | "thinking" | "ui" | "feature" | "footer";
|
|
@@ -378,8 +442,8 @@ export async function showCcstylePanel(
|
|
|
378
442
|
id: "mode",
|
|
379
443
|
label: "Mode",
|
|
380
444
|
description: modeSettingDescription(config.mode),
|
|
381
|
-
currentValue: config.mode
|
|
382
|
-
values: ["on", "compact
|
|
445
|
+
currentValue: config.mode,
|
|
446
|
+
values: ["on", "compact", "off"],
|
|
383
447
|
};
|
|
384
448
|
// Tracks whether a nested submenu is open so Tab switches sections
|
|
385
449
|
// only at the top level (mirrors Zentui settings: Tab = switch sections).
|
|
@@ -409,15 +473,15 @@ export async function showCcstylePanel(
|
|
|
409
473
|
);
|
|
410
474
|
},
|
|
411
475
|
};
|
|
412
|
-
const
|
|
413
|
-
id: "
|
|
414
|
-
label: "
|
|
476
|
+
const toolLabelClipSetting = {
|
|
477
|
+
id: "toolLabelClip",
|
|
478
|
+
label: "Tool label clip",
|
|
415
479
|
description:
|
|
416
480
|
"Max characters for path/command/name in single and grouped tool summaries; 0 fits available width. Enter to type a custom value.",
|
|
417
|
-
currentValue: String(config.
|
|
418
|
-
values: [...
|
|
481
|
+
currentValue: String(config.toolLabelClip),
|
|
482
|
+
values: [...TOOL_LABEL_CLIP_VALUES],
|
|
419
483
|
submenu: (_current: string, closeSubmenu: (selected?: string) => void) =>
|
|
420
|
-
buildNumberInputSubmenu(theme,
|
|
484
|
+
buildNumberInputSubmenu(theme, toolLabelClipSetting, closeSubmenu),
|
|
421
485
|
};
|
|
422
486
|
const diffViewSetting = {
|
|
423
487
|
id: "diffViewMode",
|
|
@@ -447,7 +511,7 @@ export async function showCcstylePanel(
|
|
|
447
511
|
id: "editDiffCollapsedLines",
|
|
448
512
|
label: "Edit collapsed lines",
|
|
449
513
|
description:
|
|
450
|
-
"
|
|
514
|
+
"Edit diff body lines before the expand hint (Ctrl+O / click). 0 shows only change counts and the hint.",
|
|
451
515
|
currentValue: String(config.editDiffCollapsedLines),
|
|
452
516
|
values: [...DIFF_COLLAPSED_LINES_VALUES],
|
|
453
517
|
submenu: (_current: string, closeSubmenu: (selected?: string) => void) =>
|
|
@@ -551,14 +615,14 @@ export async function showCcstylePanel(
|
|
|
551
615
|
currentValue: config.showStartupHeader ? "on" : "off",
|
|
552
616
|
values: ["on", "off"],
|
|
553
617
|
};
|
|
554
|
-
const
|
|
555
|
-
id: "
|
|
556
|
-
label: "
|
|
557
|
-
description:
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
618
|
+
const stickyUserMessageSetting = {
|
|
619
|
+
id: "stickyUserMessage",
|
|
620
|
+
label: "Sticky user message",
|
|
621
|
+
description: config.stickyUserMessage
|
|
622
|
+
? "Fullscreen: pin a user message's first line once it scrolls off the top edge, until the next one takes over."
|
|
623
|
+
: "User messages scroll normally.",
|
|
624
|
+
currentValue: config.stickyUserMessage ? "on" : "off",
|
|
625
|
+
values: ["on", "off"],
|
|
562
626
|
};
|
|
563
627
|
|
|
564
628
|
// 额外功能开关:注册于扩展加载期,切换后需重启(/reload)生效。
|
|
@@ -604,6 +668,65 @@ export async function showCcstylePanel(
|
|
|
604
668
|
"Aliases disabled.",
|
|
605
669
|
config.enableAliases,
|
|
606
670
|
);
|
|
671
|
+
const footerCurrencySetting = {
|
|
672
|
+
id: "footerCurrency",
|
|
673
|
+
label: "Cost currency",
|
|
674
|
+
description:
|
|
675
|
+
"ISO code for the status-bar cost. Switching currency fills its preset rate. USD clears the rate.",
|
|
676
|
+
currentValue: config.footerCurrency,
|
|
677
|
+
values: [...FOOTER_CURRENCY_PRESETS],
|
|
678
|
+
submenu: (_current: string, closeSubmenu: (selected?: string) => void) => {
|
|
679
|
+
nestedSubmenuOpen = true;
|
|
680
|
+
nestedHint = " Enter to apply · Esc back to Footer";
|
|
681
|
+
return buildValueInputSubmenu(
|
|
682
|
+
theme,
|
|
683
|
+
{
|
|
684
|
+
prompt: " Cost currency — ISO code:",
|
|
685
|
+
initial: footerCurrencySetting.currentValue,
|
|
686
|
+
hint: " Enter to apply · Esc to go back",
|
|
687
|
+
accept: (raw) => (raw === "" ? undefined : raw),
|
|
688
|
+
},
|
|
689
|
+
(selected) => {
|
|
690
|
+
nestedSubmenuOpen = false;
|
|
691
|
+
nestedHint = "";
|
|
692
|
+
closeSubmenu(selected);
|
|
693
|
+
},
|
|
694
|
+
);
|
|
695
|
+
},
|
|
696
|
+
};
|
|
697
|
+
const footerCurrencyRateSetting = {
|
|
698
|
+
id: "footerCurrencyRate",
|
|
699
|
+
label: "Cost rate",
|
|
700
|
+
description:
|
|
701
|
+
"Display units per 1 USD of cost. Switching currency replaces this. Empty keeps the number and only changes the symbol.",
|
|
702
|
+
currentValue: footerCurrencyRateLabel(config.footerCurrencyRate),
|
|
703
|
+
submenu: (_current: string, closeSubmenu: (selected?: string) => void) => {
|
|
704
|
+
nestedSubmenuOpen = true;
|
|
705
|
+
nestedHint = " Enter to apply · empty clears · Esc back to Footer";
|
|
706
|
+
return buildValueInputSubmenu(
|
|
707
|
+
theme,
|
|
708
|
+
{
|
|
709
|
+
prompt: " Cost rate — display units per 1 cost unit:",
|
|
710
|
+
initial:
|
|
711
|
+
footerCurrencyRateSetting.currentValue === "-"
|
|
712
|
+
? ""
|
|
713
|
+
: footerCurrencyRateSetting.currentValue,
|
|
714
|
+
hint: " Enter to apply · empty clears conversion · Esc to go back",
|
|
715
|
+
accept: (raw) => {
|
|
716
|
+
if (raw === "" || raw === "-") return "-";
|
|
717
|
+
const n = Number(raw);
|
|
718
|
+
return Number.isFinite(n) && n > 0 ? raw : null;
|
|
719
|
+
},
|
|
720
|
+
invalid: () => "Rate must be a positive number",
|
|
721
|
+
},
|
|
722
|
+
(selected) => {
|
|
723
|
+
nestedSubmenuOpen = false;
|
|
724
|
+
nestedHint = "";
|
|
725
|
+
closeSubmenu(selected);
|
|
726
|
+
},
|
|
727
|
+
);
|
|
728
|
+
},
|
|
729
|
+
};
|
|
607
730
|
const footerNerdIconsSetting = {
|
|
608
731
|
id: "footerNerdIcons",
|
|
609
732
|
label: "Nerd Font icons",
|
|
@@ -620,6 +743,34 @@ export async function showCcstylePanel(
|
|
|
620
743
|
currentValue: config.enableCustomFooter ? "on" : "off",
|
|
621
744
|
values: ["on", "off"],
|
|
622
745
|
};
|
|
746
|
+
const footerGitStatsSetting = {
|
|
747
|
+
id: "footerGitStatsMode",
|
|
748
|
+
label: "Git changes",
|
|
749
|
+
description: footerGitStatsDescription(config.footerGitStatsMode),
|
|
750
|
+
currentValue: config.footerGitStatsMode,
|
|
751
|
+
values: FOOTER_GIT_STATS_MODES,
|
|
752
|
+
};
|
|
753
|
+
const footerTokenRateSetting = {
|
|
754
|
+
id: "footerTokenRate",
|
|
755
|
+
label: "Token rate",
|
|
756
|
+
description: footerTokenRateDescription(config.footerTokenRate),
|
|
757
|
+
currentValue: config.footerTokenRate ? "on" : "off",
|
|
758
|
+
values: ["on", "off"],
|
|
759
|
+
};
|
|
760
|
+
const footerTokenRateModeSetting = {
|
|
761
|
+
id: "footerTokenRateMode",
|
|
762
|
+
label: "Token rate mode",
|
|
763
|
+
description: footerTokenRateModeDescription(config.footerTokenRateMode),
|
|
764
|
+
currentValue: config.footerTokenRateMode,
|
|
765
|
+
values: FOOTER_TOKEN_RATE_MODES,
|
|
766
|
+
};
|
|
767
|
+
const footerTokenRateTtftSetting = {
|
|
768
|
+
id: "footerTokenRateTtft",
|
|
769
|
+
label: "Token rate TTFT",
|
|
770
|
+
description: footerTokenRateTtftDescription(config.footerTokenRateTtft),
|
|
771
|
+
currentValue: config.footerTokenRateTtft ? "on" : "off",
|
|
772
|
+
values: ["on", "off"],
|
|
773
|
+
};
|
|
623
774
|
const pluginChipsSetting = {
|
|
624
775
|
id: "footerPluginChips",
|
|
625
776
|
label: "Plugin chips",
|
|
@@ -663,6 +814,60 @@ export async function showCcstylePanel(
|
|
|
663
814
|
ctx.ui.notify(`Updated ${id}: ${value}`, "info");
|
|
664
815
|
return;
|
|
665
816
|
}
|
|
817
|
+
if (id === "footerCurrency") {
|
|
818
|
+
updateConfig({
|
|
819
|
+
footerCurrency: value,
|
|
820
|
+
footerCurrencyRate: presetFooterCurrencyRate(value),
|
|
821
|
+
});
|
|
822
|
+
footerCurrencySetting.currentValue = config.footerCurrency;
|
|
823
|
+
footerCurrencyRateSetting.currentValue = footerCurrencyRateLabel(config.footerCurrencyRate);
|
|
824
|
+
if (config.enableCustomFooter) applyCustomFooter(ctx);
|
|
825
|
+
ctx.ui.notify(
|
|
826
|
+
`Updated ${id}: ${config.footerCurrency} · ${footerCurrencyRateSetting.currentValue}`,
|
|
827
|
+
"info",
|
|
828
|
+
);
|
|
829
|
+
return;
|
|
830
|
+
}
|
|
831
|
+
if (id === "footerCurrencyRate") {
|
|
832
|
+
updateConfig({ footerCurrencyRate: value === "-" ? null : Number(value) });
|
|
833
|
+
footerCurrencyRateSetting.currentValue = footerCurrencyRateLabel(config.footerCurrencyRate);
|
|
834
|
+
if (config.enableCustomFooter) applyCustomFooter(ctx);
|
|
835
|
+
ctx.ui.notify(`Updated ${id}: ${footerCurrencyRateSetting.currentValue}`, "info");
|
|
836
|
+
return;
|
|
837
|
+
}
|
|
838
|
+
if (id === "footerGitStatsMode") {
|
|
839
|
+
updateConfig({ footerGitStatsMode: value as FooterGitStatsMode });
|
|
840
|
+
footerGitStatsSetting.currentValue = config.footerGitStatsMode;
|
|
841
|
+
footerGitStatsSetting.description = footerGitStatsDescription(config.footerGitStatsMode);
|
|
842
|
+
refreshFooterGitStats();
|
|
843
|
+
ctx.ui.notify(`Updated ${id}: ${value}`, "info");
|
|
844
|
+
return;
|
|
845
|
+
}
|
|
846
|
+
if (id === "footerTokenRate") {
|
|
847
|
+
const enabled = value === "on";
|
|
848
|
+
updateConfig({ footerTokenRate: enabled });
|
|
849
|
+
footerTokenRateSetting.currentValue = enabled ? "on" : "off";
|
|
850
|
+
footerTokenRateSetting.description = footerTokenRateDescription(enabled);
|
|
851
|
+
ctx.ui.notify(`Updated ${id}: ${value}`, "info");
|
|
852
|
+
return;
|
|
853
|
+
}
|
|
854
|
+
if (id === "footerTokenRateMode") {
|
|
855
|
+
updateConfig({ footerTokenRateMode: value as FooterTokenRateMode });
|
|
856
|
+
footerTokenRateModeSetting.currentValue = config.footerTokenRateMode;
|
|
857
|
+
footerTokenRateModeSetting.description = footerTokenRateModeDescription(
|
|
858
|
+
config.footerTokenRateMode,
|
|
859
|
+
);
|
|
860
|
+
ctx.ui.notify(`Updated ${id}: ${value}`, "info");
|
|
861
|
+
return;
|
|
862
|
+
}
|
|
863
|
+
if (id === "footerTokenRateTtft") {
|
|
864
|
+
const enabled = value === "on";
|
|
865
|
+
updateConfig({ footerTokenRateTtft: enabled });
|
|
866
|
+
footerTokenRateTtftSetting.currentValue = enabled ? "on" : "off";
|
|
867
|
+
footerTokenRateTtftSetting.description = footerTokenRateTtftDescription(enabled);
|
|
868
|
+
ctx.ui.notify(`Updated ${id}: ${value}`, "info");
|
|
869
|
+
return;
|
|
870
|
+
}
|
|
666
871
|
if (id === "footerNerdIcons") {
|
|
667
872
|
const enabled = value === "on";
|
|
668
873
|
updateConfig({ footerNerdIcons: enabled });
|
|
@@ -682,16 +887,14 @@ export async function showCcstylePanel(
|
|
|
682
887
|
return;
|
|
683
888
|
}
|
|
684
889
|
switch (id) {
|
|
685
|
-
case "
|
|
890
|
+
case "toolLabelClip":
|
|
686
891
|
updateConfig({
|
|
687
|
-
|
|
892
|
+
toolLabelClip: pickToolLabelClip(value),
|
|
688
893
|
});
|
|
689
|
-
|
|
894
|
+
toolLabelClipSetting.currentValue = String(config.toolLabelClip);
|
|
690
895
|
break;
|
|
691
896
|
case "mode": {
|
|
692
|
-
|
|
693
|
-
const mode: CompactStyleMode =
|
|
694
|
-
value === "compact (Experimental)" ? "compact" : (value as CompactStyleMode);
|
|
897
|
+
const mode = value as CompactStyleMode;
|
|
695
898
|
modeSetting.description = modeSettingDescription(mode);
|
|
696
899
|
hooks.applyStyleMode(mode, ctx, toolGrouping);
|
|
697
900
|
return;
|
|
@@ -719,7 +922,7 @@ export async function showCcstylePanel(
|
|
|
719
922
|
editDiffCollapsedLines: pickPositiveInt(
|
|
720
923
|
value,
|
|
721
924
|
DEFAULT_CONFIG.editDiffCollapsedLines,
|
|
722
|
-
|
|
925
|
+
0,
|
|
723
926
|
500,
|
|
724
927
|
),
|
|
725
928
|
});
|
|
@@ -800,6 +1003,13 @@ export async function showCcstylePanel(
|
|
|
800
1003
|
? "Thinking text uses the theme's dim color."
|
|
801
1004
|
: "Keep the default thinking text color.";
|
|
802
1005
|
break;
|
|
1006
|
+
case "stickyUserMessage": {
|
|
1007
|
+
updateConfig({ stickyUserMessage: value === "on" });
|
|
1008
|
+
stickyUserMessageSetting.description = config.stickyUserMessage
|
|
1009
|
+
? "Fullscreen: pin a user message's first line once it scrolls off the top edge, until the next one takes over."
|
|
1010
|
+
: "User messages scroll normally.";
|
|
1011
|
+
break;
|
|
1012
|
+
}
|
|
803
1013
|
case "showStartupHeader": {
|
|
804
1014
|
const enabled = value === "on";
|
|
805
1015
|
updateConfig({ showStartupHeader: enabled });
|
|
@@ -810,12 +1020,6 @@ export async function showCcstylePanel(
|
|
|
810
1020
|
else clearStartupHeader(ctx);
|
|
811
1021
|
break;
|
|
812
1022
|
}
|
|
813
|
-
case "scrollStepLines":
|
|
814
|
-
updateConfig({
|
|
815
|
-
scrollStepLines: pickPositiveInt(value, DEFAULT_CONFIG.scrollStepLines, 1, 50),
|
|
816
|
-
});
|
|
817
|
-
scrollStepSetting.currentValue = String(config.scrollStepLines);
|
|
818
|
-
break;
|
|
819
1023
|
default:
|
|
820
1024
|
return;
|
|
821
1025
|
}
|
|
@@ -850,9 +1054,9 @@ export async function showCcstylePanel(
|
|
|
850
1054
|
expandedOutputSetting,
|
|
851
1055
|
expandedMaxSetting,
|
|
852
1056
|
expandedCardBgSetting,
|
|
853
|
-
|
|
1057
|
+
toolLabelClipSetting,
|
|
1058
|
+
stickyUserMessageSetting,
|
|
854
1059
|
startupHeaderSetting,
|
|
855
|
-
scrollStepSetting,
|
|
856
1060
|
],
|
|
857
1061
|
},
|
|
858
1062
|
{
|
|
@@ -880,7 +1084,17 @@ export async function showCcstylePanel(
|
|
|
880
1084
|
{
|
|
881
1085
|
id: "footer",
|
|
882
1086
|
label: "Footer",
|
|
883
|
-
items: [
|
|
1087
|
+
items: [
|
|
1088
|
+
customFooterSetting,
|
|
1089
|
+
footerTokenRateSetting,
|
|
1090
|
+
footerTokenRateModeSetting,
|
|
1091
|
+
footerTokenRateTtftSetting,
|
|
1092
|
+
footerCurrencySetting,
|
|
1093
|
+
footerCurrencyRateSetting,
|
|
1094
|
+
footerNerdIconsSetting,
|
|
1095
|
+
footerGitStatsSetting,
|
|
1096
|
+
pluginChipsSetting,
|
|
1097
|
+
],
|
|
884
1098
|
},
|
|
885
1099
|
];
|
|
886
1100
|
|
|
@@ -39,9 +39,8 @@ function nonEmptyString(value: unknown): value is string {
|
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
function toolPath(args?: Record<string, unknown> | null): string | undefined {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
return nonEmptyString(args?.file_path) ? args.file_path : undefined;
|
|
42
|
+
const path = args?.path ?? args?.file_path;
|
|
43
|
+
return nonEmptyString(path) ? path : undefined;
|
|
45
44
|
}
|
|
46
45
|
|
|
47
46
|
/** 累积一次 agent 回合的工具统计;agent_start 时新建实例。 */
|
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
import { Box, Markdown, Spacer, Text, type Component } from "@earendil-works/pi-tui";
|
|
21
21
|
// 展开卡背景是 ccstyle 的渲染约定,不随上游 CompactThinkingConfig 走,直接读全局配置。
|
|
22
22
|
import { config as styleConfig } from "../config/config.ts";
|
|
23
|
-
import { isToolTuiFullscreen } from "../renderer/tool/
|
|
23
|
+
import { isToolTuiFullscreen } from "../renderer/tool/names.ts";
|
|
24
24
|
import {
|
|
25
25
|
animateCompactThinkingText,
|
|
26
26
|
formatThoughtDuration,
|