@willh/copilotstatusline 0.2.3 → 0.2.4
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/LICENSE +2 -2
- package/README.md +2 -0
- package/dist/copilotstatusline.js +115 -56
- package/docs/USAGE.md +17 -0
- package/package.json +1 -1
package/LICENSE
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c) 2025 Matthew Breedlove (https://github.com/sirmalloc)
|
|
3
|
+
Copyright (c) 2025 Will 保哥, Matthew Breedlove (https://github.com/sirmalloc)
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
18
18
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
19
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
20
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -26,6 +26,8 @@ Choose `Install or repair Copilot integration`, or install non-interactively:
|
|
|
26
26
|
npx -y @willh/copilotstatusline@latest --install npm
|
|
27
27
|
```
|
|
28
28
|
|
|
29
|
+
Interactive menus support both the arrow keys and Vim-style navigation: `j` moves down and `k` moves up. Text and search inputs continue to treat these keys as ordinary characters.
|
|
30
|
+
|
|
29
31
|
The installer merges the following keys into the existing Copilot settings and preserves unrelated settings:
|
|
30
32
|
|
|
31
33
|
```json
|
|
@@ -15623,6 +15623,9 @@ function renderValue(config2, label, value) {
|
|
|
15623
15623
|
return `${config2.prefix}${body}${config2.suffix}`;
|
|
15624
15624
|
}
|
|
15625
15625
|
function numericValue(config2, label, value, formatter = formatTokens) {
|
|
15626
|
+
if (value === undefined) {
|
|
15627
|
+
return null;
|
|
15628
|
+
}
|
|
15626
15629
|
if (config2.hideWhenZero && value === 0) {
|
|
15627
15630
|
return null;
|
|
15628
15631
|
}
|
|
@@ -15632,7 +15635,7 @@ function contextUsed(status) {
|
|
|
15632
15635
|
if (status.context.usedPercentage !== undefined) {
|
|
15633
15636
|
return status.context.usedPercentage;
|
|
15634
15637
|
}
|
|
15635
|
-
if (status.context.limitTokens <= 0) {
|
|
15638
|
+
if (status.context.currentTokens === undefined || status.context.limitTokens === undefined || status.context.limitTokens <= 0) {
|
|
15636
15639
|
return null;
|
|
15637
15640
|
}
|
|
15638
15641
|
return status.context.currentTokens / status.context.limitTokens * 100;
|
|
@@ -15684,7 +15687,7 @@ function renderWidget(config2, context) {
|
|
|
15684
15687
|
case "model":
|
|
15685
15688
|
return status.modelName === undefined ? null : renderValue(config2, "Model", status.modelName);
|
|
15686
15689
|
case "model-id":
|
|
15687
|
-
return status.modelId === undefined ? null : renderValue(config2, "Model", status.modelId);
|
|
15690
|
+
return status.modelId === undefined ? null : renderValue(config2, "Model ID", status.modelId);
|
|
15688
15691
|
case "reasoning":
|
|
15689
15692
|
return status.reasoningEffort === undefined ? null : renderValue(config2, "Effort", status.reasoningEffort);
|
|
15690
15693
|
case "copilot-version":
|
|
@@ -15692,7 +15695,7 @@ function renderWidget(config2, context) {
|
|
|
15692
15695
|
case "session-id":
|
|
15693
15696
|
return status.sessionId === undefined ? null : renderValue(config2, "Session", status.sessionId);
|
|
15694
15697
|
case "session-name":
|
|
15695
|
-
return status.sessionName === undefined ? null : renderValue(config2, "Session", status.sessionName);
|
|
15698
|
+
return status.sessionName === undefined ? null : renderValue(config2, "Session Name", status.sessionName);
|
|
15696
15699
|
case "cwd":
|
|
15697
15700
|
return status.cwd === undefined ? null : renderValue(config2, "", status.cwd);
|
|
15698
15701
|
case "context-used": {
|
|
@@ -15714,7 +15717,7 @@ function renderWidget(config2, context) {
|
|
|
15714
15717
|
case "lines-removed":
|
|
15715
15718
|
return numericValue(config2, "-", status.cost.linesRemoved, (value) => String(value));
|
|
15716
15719
|
case "allow-all":
|
|
15717
|
-
return status.allowAll ===
|
|
15720
|
+
return status.allowAll === undefined ? null : renderValue(config2, "Allow All", status.allowAll ? "ON" : "OFF");
|
|
15718
15721
|
case "git-branch": {
|
|
15719
15722
|
const branch = cachedCommand(`git-branch:${status.cwd ?? ""}`, context.gitCacheTtlSeconds, () => runFile("git", ["--no-optional-locks", "branch", "--show-current"], status.cwd));
|
|
15720
15723
|
return branch === null ? null : renderValue(config2, "", branch);
|
|
@@ -15786,7 +15789,7 @@ var init_catalog = __esm(() => {
|
|
|
15786
15789
|
{ type: "session-duration", name: "Session Duration", description: "累計 session 時間", defaultColor: "brightBlack" },
|
|
15787
15790
|
{ type: "lines-added", name: "Lines Added", description: "本 session 新增行數", defaultColor: "green" },
|
|
15788
15791
|
{ type: "lines-removed", name: "Lines Removed", description: "本 session 刪除行數", defaultColor: "red" },
|
|
15789
|
-
{ type: "allow-all", name: "Allow All", description: "
|
|
15792
|
+
{ type: "allow-all", name: "Allow All", description: "是否啟用所有工具與路徑權限", defaultColor: "brightRed" },
|
|
15790
15793
|
{ type: "git-branch", name: "Git Branch", description: "目前 Git branch", defaultColor: "magenta" },
|
|
15791
15794
|
{ type: "git-changes", name: "Git Changes", description: "Git staged/unstaged/untracked 數量", defaultColor: "yellow" },
|
|
15792
15795
|
{ type: "jj-change", name: "Jujutsu Change", description: "目前 jj change ID", defaultColor: "magenta" },
|
|
@@ -54312,7 +54315,7 @@ var package_default;
|
|
|
54312
54315
|
var init_package = __esm(() => {
|
|
54313
54316
|
package_default = {
|
|
54314
54317
|
name: "@willh/copilotstatusline",
|
|
54315
|
-
version: "0.2.
|
|
54318
|
+
version: "0.2.4",
|
|
54316
54319
|
bugs: {
|
|
54317
54320
|
url: "https://github.com/doggy8088/copilotstatusline/issues"
|
|
54318
54321
|
},
|
|
@@ -54398,6 +54401,26 @@ var init_package = __esm(() => {
|
|
|
54398
54401
|
};
|
|
54399
54402
|
});
|
|
54400
54403
|
|
|
54404
|
+
// src/tui/vertical-navigation.ts
|
|
54405
|
+
function getVerticalNavigationDirection(input, key) {
|
|
54406
|
+
if (key.upArrow) {
|
|
54407
|
+
return -1;
|
|
54408
|
+
}
|
|
54409
|
+
if (key.downArrow) {
|
|
54410
|
+
return 1;
|
|
54411
|
+
}
|
|
54412
|
+
if (key.ctrl || key.meta) {
|
|
54413
|
+
return null;
|
|
54414
|
+
}
|
|
54415
|
+
if (input === "k") {
|
|
54416
|
+
return -1;
|
|
54417
|
+
}
|
|
54418
|
+
if (input === "j") {
|
|
54419
|
+
return 1;
|
|
54420
|
+
}
|
|
54421
|
+
return null;
|
|
54422
|
+
}
|
|
54423
|
+
|
|
54401
54424
|
// node_modules/react/cjs/react-jsx-dev-runtime.development.js
|
|
54402
54425
|
var require_react_jsx_dev_runtime_development = __commonJS((exports) => {
|
|
54403
54426
|
var React11 = __toESM(require_react());
|
|
@@ -54649,14 +54672,13 @@ function List({
|
|
|
54649
54672
|
latestSelectionChange.current?.(selectedValue, selectedIndex);
|
|
54650
54673
|
}
|
|
54651
54674
|
}, [selectedIndex, selectedValue]);
|
|
54652
|
-
use_input_default((
|
|
54675
|
+
use_input_default((input, key) => {
|
|
54653
54676
|
if (selectableItems.length === 0) {
|
|
54654
54677
|
return;
|
|
54655
54678
|
}
|
|
54656
|
-
|
|
54657
|
-
|
|
54658
|
-
|
|
54659
|
-
setSelectedIndex((index) => index === selectableItems.length - 1 ? 0 : index + 1);
|
|
54679
|
+
const direction = getVerticalNavigationDirection(input, key);
|
|
54680
|
+
if (direction !== null) {
|
|
54681
|
+
setSelectedIndex((index) => (index + direction + selectableItems.length) % selectableItems.length);
|
|
54660
54682
|
} else if (key.return && selectedItem !== undefined) {
|
|
54661
54683
|
onSelect(selectedItem.value, selectedIndex);
|
|
54662
54684
|
}
|
|
@@ -54799,13 +54821,13 @@ function ColorEditor({
|
|
|
54799
54821
|
}
|
|
54800
54822
|
return;
|
|
54801
54823
|
}
|
|
54802
|
-
|
|
54803
|
-
|
|
54804
|
-
setSelectedIndex((
|
|
54824
|
+
const direction = getVerticalNavigationDirection(input, key);
|
|
54825
|
+
if (direction !== null) {
|
|
54826
|
+
setSelectedIndex((index) => (index + direction + widgets.length) % widgets.length);
|
|
54805
54827
|
} else if ((key.leftArrow || key.rightArrow) && selectedWidget !== undefined) {
|
|
54806
|
-
const
|
|
54828
|
+
const direction2 = key.leftArrow ? -1 : 1;
|
|
54807
54829
|
const field = editingBackground ? "backgroundColor" : "color";
|
|
54808
|
-
onUpdate(widgets.map((widget2, index) => index === selectedIndex ? { ...widget2, [field]: cycleColor(widget2[field],
|
|
54830
|
+
onUpdate(widgets.map((widget2, index) => index === selectedIndex ? { ...widget2, [field]: cycleColor(widget2[field], direction2) } : widget2));
|
|
54809
54831
|
} else if (input === "f") {
|
|
54810
54832
|
setEditingBackground((value) => !value);
|
|
54811
54833
|
} else if (input === "b" && selectedWidget !== undefined) {
|
|
@@ -54881,7 +54903,7 @@ function ColorEditor({
|
|
|
54881
54903
|
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
54882
54904
|
dimColor: true,
|
|
54883
54905
|
children: [
|
|
54884
|
-
"
|
|
54906
|
+
"↑↓/j/k select, ←→ cycle",
|
|
54885
54907
|
" ",
|
|
54886
54908
|
editingBackground ? "background" : "foreground",
|
|
54887
54909
|
", (f) toggle bg/fg, (b)old, (r)eset, (c)lear all, ESC back"
|
|
@@ -55014,8 +55036,8 @@ function LineSelector({
|
|
|
55014
55036
|
return;
|
|
55015
55037
|
}
|
|
55016
55038
|
if (moveMode) {
|
|
55017
|
-
|
|
55018
|
-
|
|
55039
|
+
const direction = getVerticalNavigationDirection(input, key);
|
|
55040
|
+
if (direction !== null && lines.length > 1) {
|
|
55019
55041
|
const target = (selectedIndex + direction + lines.length) % lines.length;
|
|
55020
55042
|
const reordered = [...lines];
|
|
55021
55043
|
const current = reordered[selectedIndex];
|
|
@@ -55080,7 +55102,7 @@ function LineSelector({
|
|
|
55080
55102
|
}, undefined, false, undefined, this),
|
|
55081
55103
|
/* @__PURE__ */ jsx_dev_runtime3.jsxDEV(Text, {
|
|
55082
55104
|
dimColor: true,
|
|
55083
|
-
children: moveMode ? "
|
|
55105
|
+
children: moveMode ? "↑↓/j/k to move line, ESC or Enter to exit move mode" : allowEditing ? "↑↓/j/k select, (a) append line, (d) delete line, (m) move line, ESC back" : "↑↓/j/k select, ESC to go back"
|
|
55084
55106
|
}, undefined, false, undefined, this),
|
|
55085
55107
|
moveMode ? /* @__PURE__ */ jsx_dev_runtime3.jsxDEV(Box_default, {
|
|
55086
55108
|
marginTop: 1,
|
|
@@ -55209,6 +55231,10 @@ function MainMenu({
|
|
|
55209
55231
|
bold: true,
|
|
55210
55232
|
children: "Main Menu"
|
|
55211
55233
|
}, undefined, false, undefined, this),
|
|
55234
|
+
/* @__PURE__ */ jsx_dev_runtime4.jsxDEV(Text, {
|
|
55235
|
+
dimColor: true,
|
|
55236
|
+
children: "↑↓ or j/k to select, Enter to open"
|
|
55237
|
+
}, undefined, false, undefined, this),
|
|
55212
55238
|
/* @__PURE__ */ jsx_dev_runtime4.jsxDEV(List, {
|
|
55213
55239
|
items: menuItems(integration, hasChanges),
|
|
55214
55240
|
marginTop: 1,
|
|
@@ -55464,8 +55490,8 @@ function WidgetEditor({
|
|
|
55464
55490
|
return;
|
|
55465
55491
|
}
|
|
55466
55492
|
const current = pickerIndex < 0 ? 0 : pickerIndex;
|
|
55467
|
-
const
|
|
55468
|
-
const nextIndex = (current +
|
|
55493
|
+
const direction2 = key.upArrow ? -1 : 1;
|
|
55494
|
+
const nextIndex = (current + direction2 + filteredCatalog.length) % filteredCatalog.length;
|
|
55469
55495
|
setPicker({ ...picker, selectedType: filteredCatalog[nextIndex]?.type ?? null });
|
|
55470
55496
|
} else if (key.return && selectedPickerEntry !== undefined) {
|
|
55471
55497
|
applyPicker(selectedPickerEntry.type);
|
|
@@ -55481,9 +55507,9 @@ function WidgetEditor({
|
|
|
55481
55507
|
return;
|
|
55482
55508
|
}
|
|
55483
55509
|
if (moveMode) {
|
|
55484
|
-
|
|
55485
|
-
|
|
55486
|
-
const target = (selectedIndex +
|
|
55510
|
+
const direction2 = getVerticalNavigationDirection(input, key);
|
|
55511
|
+
if (direction2 !== null && widgets.length > 1) {
|
|
55512
|
+
const target = (selectedIndex + direction2 + widgets.length) % widgets.length;
|
|
55487
55513
|
const reordered = [...widgets];
|
|
55488
55514
|
const current = reordered[selectedIndex];
|
|
55489
55515
|
const replacement = reordered[target];
|
|
@@ -55506,9 +55532,9 @@ function WidgetEditor({
|
|
|
55506
55532
|
if (globalKeyAction === "ignore") {
|
|
55507
55533
|
return;
|
|
55508
55534
|
}
|
|
55509
|
-
|
|
55510
|
-
|
|
55511
|
-
setSelectedIndex((
|
|
55535
|
+
const direction = getVerticalNavigationDirection(input, key);
|
|
55536
|
+
if (direction !== null && widgets.length > 0) {
|
|
55537
|
+
setSelectedIndex((index) => (index + direction + widgets.length) % widgets.length);
|
|
55512
55538
|
} else if ((key.leftArrow || key.rightArrow) && currentWidget !== undefined) {
|
|
55513
55539
|
openPicker("change");
|
|
55514
55540
|
} else if (key.return && currentWidget !== undefined) {
|
|
@@ -55521,7 +55547,7 @@ function WidgetEditor({
|
|
|
55521
55547
|
const next = widgets.filter((_, index) => index !== selectedIndex);
|
|
55522
55548
|
onUpdate(next);
|
|
55523
55549
|
setSelectedIndex(Math.max(0, Math.min(selectedIndex, next.length - 1)));
|
|
55524
|
-
} else if (input === "
|
|
55550
|
+
} else if (input === "y" && currentWidget !== undefined) {
|
|
55525
55551
|
const clone3 = { ...currentWidget, id: randomUUID() };
|
|
55526
55552
|
const next = [...widgets];
|
|
55527
55553
|
next.splice(selectedIndex + 1, 0, clone3);
|
|
@@ -55686,7 +55712,7 @@ function WidgetEditor({
|
|
|
55686
55712
|
}, undefined, true, undefined, this),
|
|
55687
55713
|
/* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
|
|
55688
55714
|
dimColor: true,
|
|
55689
|
-
children: moveMode ? "
|
|
55715
|
+
children: moveMode ? "↑↓/j/k move widget, ESC or Enter exit move mode" : "↑↓/j/k select, ←→ change, Enter move, (a)dd, (i)nsert, (y) clone, (d)elete, (c)lear"
|
|
55690
55716
|
}, undefined, false, undefined, this),
|
|
55691
55717
|
/* @__PURE__ */ jsx_dev_runtime6.jsxDEV(Text, {
|
|
55692
55718
|
dimColor: true,
|
|
@@ -56484,7 +56510,7 @@ var CopilotStatusSchema = exports_external.looseObject({
|
|
|
56484
56510
|
allow_all: exports_external.boolean().optional()
|
|
56485
56511
|
});
|
|
56486
56512
|
function finiteNumber(value) {
|
|
56487
|
-
return typeof value === "number" && Number.isFinite(value) ? value :
|
|
56513
|
+
return typeof value === "number" && Number.isFinite(value) ? value : undefined;
|
|
56488
56514
|
}
|
|
56489
56515
|
function normalizeCopilotStatus(status) {
|
|
56490
56516
|
const model = status.model;
|
|
@@ -56497,7 +56523,15 @@ function normalizeCopilotStatus(status) {
|
|
|
56497
56523
|
const cacheWriteTokens = finiteNumber(context?.total_cache_write_tokens);
|
|
56498
56524
|
const reasoningTokens = finiteNumber(context?.total_reasoning_tokens);
|
|
56499
56525
|
const reportedTotal = finiteNumber(context?.total_tokens);
|
|
56500
|
-
const
|
|
56526
|
+
const componentTokens = [
|
|
56527
|
+
inputTokens,
|
|
56528
|
+
outputTokens,
|
|
56529
|
+
cacheReadTokens,
|
|
56530
|
+
cacheWriteTokens,
|
|
56531
|
+
reasoningTokens
|
|
56532
|
+
];
|
|
56533
|
+
const derivedTotal = componentTokens.some((value) => value !== undefined) ? componentTokens.reduce((sum, value) => sum + (value ?? 0), 0) : undefined;
|
|
56534
|
+
const totalTokens = reportedTotal ?? derivedTotal;
|
|
56501
56535
|
return {
|
|
56502
56536
|
sessionId: status.session_id,
|
|
56503
56537
|
sessionName: status.session_name ?? undefined,
|
|
@@ -56699,22 +56733,44 @@ async function loadState(statePath, copilotHome, sessionId, updatedAt, updatedAt
|
|
|
56699
56733
|
};
|
|
56700
56734
|
}
|
|
56701
56735
|
}
|
|
56702
|
-
function
|
|
56703
|
-
const
|
|
56736
|
+
function tokenCounters(status) {
|
|
56737
|
+
const cumulative = [
|
|
56704
56738
|
status.context.inputTokens,
|
|
56705
56739
|
status.context.outputTokens,
|
|
56706
56740
|
status.context.cacheReadTokens,
|
|
56707
56741
|
status.context.cacheWriteTokens,
|
|
56708
56742
|
status.context.reasoningTokens,
|
|
56709
|
-
status.context.totalTokens
|
|
56743
|
+
status.context.totalTokens
|
|
56744
|
+
];
|
|
56745
|
+
const optional2 = [
|
|
56710
56746
|
status.context.lastCallInputTokens,
|
|
56711
56747
|
status.context.lastCallOutputTokens,
|
|
56712
56748
|
status.context.currentTokens,
|
|
56713
56749
|
status.context.limitTokens
|
|
56714
56750
|
];
|
|
56715
|
-
|
|
56751
|
+
const present = [...cumulative, ...optional2].filter((value) => value !== undefined);
|
|
56752
|
+
if (!present.every((value) => Number.isSafeInteger(value) && value >= 0)) {
|
|
56716
56753
|
throw new Error("token counters must be non-negative safe integers");
|
|
56717
56754
|
}
|
|
56755
|
+
if (cumulative.some((value) => value === undefined)) {
|
|
56756
|
+
return;
|
|
56757
|
+
}
|
|
56758
|
+
const [
|
|
56759
|
+
inputTokens,
|
|
56760
|
+
outputTokens,
|
|
56761
|
+
cacheReadTokens,
|
|
56762
|
+
cacheWriteTokens,
|
|
56763
|
+
reasoningTokens,
|
|
56764
|
+
totalTokens
|
|
56765
|
+
] = cumulative;
|
|
56766
|
+
return {
|
|
56767
|
+
inputTokens: inputTokens ?? 0,
|
|
56768
|
+
outputTokens: outputTokens ?? 0,
|
|
56769
|
+
cacheReadTokens: cacheReadTokens ?? 0,
|
|
56770
|
+
cacheWriteTokens: cacheWriteTokens ?? 0,
|
|
56771
|
+
reasoningTokens: reasoningTokens ?? 0,
|
|
56772
|
+
totalTokens: totalTokens ?? 0
|
|
56773
|
+
};
|
|
56718
56774
|
}
|
|
56719
56775
|
function delta(current, previous) {
|
|
56720
56776
|
return Math.max(0, current - (previous ?? 0));
|
|
@@ -56740,7 +56796,10 @@ async function recordTokenUsage(status, options = {}) {
|
|
|
56740
56796
|
if (sessionId === undefined || sessionId.trim() === "") {
|
|
56741
56797
|
return { recorded: false };
|
|
56742
56798
|
}
|
|
56743
|
-
|
|
56799
|
+
const counters = tokenCounters(status);
|
|
56800
|
+
if (counters === undefined) {
|
|
56801
|
+
return { recorded: false };
|
|
56802
|
+
}
|
|
56744
56803
|
const now = options.now ?? new Date;
|
|
56745
56804
|
const timestamp = localIsoTimestamp(now);
|
|
56746
56805
|
const copilotHome = options.copilotHome ?? getCopilotHome();
|
|
@@ -56756,12 +56815,12 @@ async function recordTokenUsage(status, options = {}) {
|
|
|
56756
56815
|
const previous = state.sessions[sessionKey] ?? state.sessions[sessionId];
|
|
56757
56816
|
const model = status.modelName ?? status.modelId ?? "unknown";
|
|
56758
56817
|
const modelId = status.modelId ?? "unknown";
|
|
56759
|
-
const deltaInput = delta(
|
|
56760
|
-
const deltaOutput = delta(
|
|
56761
|
-
const deltaCacheRead = delta(
|
|
56762
|
-
const deltaCacheWrite = delta(
|
|
56763
|
-
const deltaReasoning = delta(
|
|
56764
|
-
const deltaTotal = delta(
|
|
56818
|
+
const deltaInput = delta(counters.inputTokens, previous?.inputTokens);
|
|
56819
|
+
const deltaOutput = delta(counters.outputTokens, previous?.outputTokens);
|
|
56820
|
+
const deltaCacheRead = delta(counters.cacheReadTokens, previous?.cacheReadTokens);
|
|
56821
|
+
const deltaCacheWrite = delta(counters.cacheWriteTokens, previous?.cacheWriteTokens);
|
|
56822
|
+
const deltaReasoning = delta(counters.reasoningTokens, previous?.reasoningTokens);
|
|
56823
|
+
const deltaTotal = delta(counters.totalTokens, previous?.totalTokens);
|
|
56765
56824
|
const previousModel = previous?.model ?? "";
|
|
56766
56825
|
const modelChanged = previousModel !== "" && previousModel !== model;
|
|
56767
56826
|
const turnNo = (previous?.turnNo ?? 0) + (deltaTotal > 0 ? 1 : 0);
|
|
@@ -56779,12 +56838,12 @@ async function recordTokenUsage(status, options = {}) {
|
|
|
56779
56838
|
previous_model: previousModel,
|
|
56780
56839
|
model_changed: modelChanged,
|
|
56781
56840
|
tokens: {
|
|
56782
|
-
input:
|
|
56783
|
-
output:
|
|
56784
|
-
cache_read:
|
|
56785
|
-
cache_write:
|
|
56786
|
-
reasoning:
|
|
56787
|
-
total:
|
|
56841
|
+
input: counters.inputTokens,
|
|
56842
|
+
output: counters.outputTokens,
|
|
56843
|
+
cache_read: counters.cacheReadTokens,
|
|
56844
|
+
cache_write: counters.cacheWriteTokens,
|
|
56845
|
+
reasoning: counters.reasoningTokens,
|
|
56846
|
+
total: counters.totalTokens,
|
|
56788
56847
|
last_call_input: status.context.lastCallInputTokens,
|
|
56789
56848
|
last_call_output: status.context.lastCallOutputTokens
|
|
56790
56849
|
},
|
|
@@ -56820,12 +56879,12 @@ async function recordTokenUsage(status, options = {}) {
|
|
|
56820
56879
|
turnNo,
|
|
56821
56880
|
model,
|
|
56822
56881
|
modelId,
|
|
56823
|
-
inputTokens:
|
|
56824
|
-
outputTokens:
|
|
56825
|
-
cacheReadTokens:
|
|
56826
|
-
cacheWriteTokens:
|
|
56827
|
-
reasoningTokens:
|
|
56828
|
-
totalTokens:
|
|
56882
|
+
inputTokens: counters.inputTokens,
|
|
56883
|
+
outputTokens: counters.outputTokens,
|
|
56884
|
+
cacheReadTokens: counters.cacheReadTokens,
|
|
56885
|
+
cacheWriteTokens: counters.cacheWriteTokens,
|
|
56886
|
+
reasoningTokens: counters.reasoningTokens,
|
|
56887
|
+
totalTokens: counters.totalTokens,
|
|
56829
56888
|
updatedAt: timestamp,
|
|
56830
56889
|
updatedAtEpochMs: now.getTime()
|
|
56831
56890
|
};
|
|
@@ -56841,7 +56900,7 @@ async function recordTokenUsage(status, options = {}) {
|
|
|
56841
56900
|
}
|
|
56842
56901
|
|
|
56843
56902
|
// src/copilotstatusline.ts
|
|
56844
|
-
var PACKAGE_VERSION = "0.2.
|
|
56903
|
+
var PACKAGE_VERSION = "0.2.4";
|
|
56845
56904
|
async function readStdin() {
|
|
56846
56905
|
process.stdin.setEncoding("utf8");
|
|
56847
56906
|
const chunks = [];
|
package/docs/USAGE.md
CHANGED
|
@@ -67,6 +67,8 @@ Uninstallation removes `statusLine` only when its command is recognized as belon
|
|
|
67
67
|
|
|
68
68
|
## Formatter settings
|
|
69
69
|
|
|
70
|
+
The interactive editor accepts Up/Down arrows or Vim-style `k`/`j` for vertical navigation. The same shortcuts move lines and widgets while move mode is active. Widget search and text-editing fields keep `j` and `k` as normal text input. In the widget editor, `y` clones the selected widget.
|
|
71
|
+
|
|
70
72
|
Default path:
|
|
71
73
|
|
|
72
74
|
```text
|
|
@@ -141,6 +143,21 @@ The normalized widgets currently use:
|
|
|
141
143
|
- cost: API duration, total duration, premium requests, and added/removed lines;
|
|
142
144
|
- permission state: `allow_all`.
|
|
143
145
|
|
|
146
|
+
Widget availability is divided by source:
|
|
147
|
+
|
|
148
|
+
| Source | Widgets | Availability |
|
|
149
|
+
| --- | --- | --- |
|
|
150
|
+
| Copilot payload | Model, Model ID, Copilot Version, Session ID, Current Directory | Shown when Copilot supplies the corresponding field or supported alias. |
|
|
151
|
+
| Optional Copilot payload | Reasoning, Session Name | Hidden when the active model has no reasoning effort or the session has no name. |
|
|
152
|
+
| Copilot token payload | Input Tokens, Output Tokens, Cache Read, Cache Write, Reasoning Tokens, Total Tokens, Last Call Input, Last Call Output | Zero is shown as a real value; a missing field is hidden instead of being converted to zero. |
|
|
153
|
+
| Copilot context payload | Current Context, Context Limit, Context Used, Context Remaining | Used percentage comes from the payload, or is derived when both the current value and limit are available. |
|
|
154
|
+
| Copilot cost payload | Premium Requests, API Duration, Session Duration, Lines Added, Lines Removed | Shown when the corresponding cumulative counter is available. |
|
|
155
|
+
| Copilot permission payload | Allow All | `Allow All: ON` and `Allow All: OFF` are rendered distinctly; a missing field is hidden. |
|
|
156
|
+
| Repository probes | Git Branch, Git Changes, Jujutsu Change | Requires the matching executable and repository. Failed or timed-out probes are hidden. |
|
|
157
|
+
| Local runtime | Terminal Width, Free Memory | Read from the current terminal and operating system. |
|
|
158
|
+
| User configuration | Custom Text, Custom Command | Requires configured text or a command that produces output. |
|
|
159
|
+
| Layout | Separator, Flex | Always available as formatting controls and does not represent Copilot payload data. |
|
|
160
|
+
|
|
144
161
|
## Diagnostics
|
|
145
162
|
|
|
146
163
|
Inspect integration status:
|