* feat(#2161): opt-in absolute token count on the statusline context meter New statusline.show_context_tokens config (default false). When enabled, the context meter shows the absolute token total after the percentage, e.g. "████░░░░░░ 46% (156k)" — summing input, cache-creation, cache-read, and output tokens from context_window.current_usage (matching /context). Default output is byte-for-byte unchanged when the flag is absent or false. The .planning config is now read once per render and shared with the last-command/position block instead of being re-read. Claude-Session: https://claude.ai/code/session_01Hme55Pvq6BhpgwBcyC5HAg * docs(#2161): changeset fragment for PR #2174 * fix(#2161): review fixes — k-to-M threshold, boundary tests, changeset format - formatTokens promotes to the M branch when k-rounding reaches 1000 (999,500-999,999 rendered "1000k" instead of "1.0M") - boundary tests at 999499/999500/999999/1000000/1000001 - Number() guards on the four usage fields (silent string-concat gap) - changeset body ends with the (#2161) citation per house convention Claude-Session: https://claude.ai/code/session_01Hme55Pvq6BhpgwBcyC5HAg * fix(#2161): round-2 review fixes — config-set coverage, precision claim, exports style - config-set accept/reject tests for statusline.show_context_tokens (mirrors the post-planning-gaps precedent the issue scope names) - changeset + docs no longer claim parity with /context: the suffix sums four fields while the meter %% derives from used_percentage (three), so the figures can diverge slightly - module.exports one entry per line Claude-Session: https://claude.ai/code/session_01Hme55Pvq6BhpgwBcyC5HAg * test: regenerate golden-install-parity fixtures for the statusline hook change Claude-Session: https://claude.ai/code/session_01Hme55Pvq6BhpgwBcyC5HAg --------- Co-authored-by: Tom Boucher <trekkie@nomorestars.com>
This commit is contained in:
@@ -41,7 +41,7 @@
|
||||
"gsd-core/bin/gsd-tools.cjs": "600e9ed0cb6ed7bb",
|
||||
"gsd-core/bin/gsd_run": "62d9b647ede212e6",
|
||||
"gsd-core/bin/shared/config-defaults.manifest.json": "517e6a7c1e9f4f16",
|
||||
"gsd-core/bin/shared/config-schema.manifest.json": "6bba2b9c9fa47cb8",
|
||||
"gsd-core/bin/shared/config-schema.manifest.json": "b67705431d738ae7",
|
||||
"gsd-core/bin/shared/model-catalog.json": "b55176ca044728d3",
|
||||
"gsd-core/bin/shared/runtime-aliases.manifest.json": "2df2c5ac1957911a",
|
||||
"gsd-core/bin/verify-reapply-patches.cjs": "8bc541aabc2e143c",
|
||||
@@ -328,7 +328,7 @@
|
||||
"hooks/gsd-read-guard.js": "9e423cd03e2d1b16",
|
||||
"hooks/gsd-read-injection-scanner.js": "eefea61f9b0e464c",
|
||||
"hooks/gsd-session-state.sh": "e54379ba86bf1b6d",
|
||||
"hooks/gsd-statusline.js": "8ae31be7a006204b",
|
||||
"hooks/gsd-statusline.js": "9e64af477e774de6",
|
||||
"hooks/gsd-update-banner.js": "55143a25f978f301",
|
||||
"hooks/gsd-validate-commit.sh": "bf5dd61d33cb3a38",
|
||||
"hooks/gsd-windsurf-pre-command.js": "948be1c6d14c79cd",
|
||||
|
||||
@@ -112,7 +112,7 @@
|
||||
"gsd-core/bin/gsd-tools.cjs": "37fb6081fcb18038",
|
||||
"gsd-core/bin/gsd_run": "62d9b647ede212e6",
|
||||
"gsd-core/bin/shared/config-defaults.manifest.json": "517e6a7c1e9f4f16",
|
||||
"gsd-core/bin/shared/config-schema.manifest.json": "6bba2b9c9fa47cb8",
|
||||
"gsd-core/bin/shared/config-schema.manifest.json": "b67705431d738ae7",
|
||||
"gsd-core/bin/shared/model-catalog.json": "b55176ca044728d3",
|
||||
"gsd-core/bin/shared/runtime-aliases.manifest.json": "2df2c5ac1957911a",
|
||||
"gsd-core/bin/verify-reapply-patches.cjs": "caec5dbce11e3904",
|
||||
@@ -399,7 +399,7 @@
|
||||
"hooks/gsd-read-guard.js": "9e423cd03e2d1b16",
|
||||
"hooks/gsd-read-injection-scanner.js": "c8800819f7443a15",
|
||||
"hooks/gsd-session-state.sh": "e54379ba86bf1b6d",
|
||||
"hooks/gsd-statusline.js": "3be32d2012c77fc1",
|
||||
"hooks/gsd-statusline.js": "3e633cd082663b99",
|
||||
"hooks/gsd-update-banner.js": "55143a25f978f301",
|
||||
"hooks/gsd-validate-commit.sh": "bf5dd61d33cb3a38",
|
||||
"hooks/gsd-windsurf-pre-command.js": "948be1c6d14c79cd",
|
||||
|
||||
@@ -111,7 +111,7 @@
|
||||
"gsd-core/bin/gsd-tools.cjs": "37fb6081fcb18038",
|
||||
"gsd-core/bin/gsd_run": "62d9b647ede212e6",
|
||||
"gsd-core/bin/shared/config-defaults.manifest.json": "517e6a7c1e9f4f16",
|
||||
"gsd-core/bin/shared/config-schema.manifest.json": "6bba2b9c9fa47cb8",
|
||||
"gsd-core/bin/shared/config-schema.manifest.json": "b67705431d738ae7",
|
||||
"gsd-core/bin/shared/model-catalog.json": "b55176ca044728d3",
|
||||
"gsd-core/bin/shared/runtime-aliases.manifest.json": "2df2c5ac1957911a",
|
||||
"gsd-core/bin/verify-reapply-patches.cjs": "caec5dbce11e3904",
|
||||
@@ -398,7 +398,7 @@
|
||||
"hooks/gsd-read-guard.js": "9e423cd03e2d1b16",
|
||||
"hooks/gsd-read-injection-scanner.js": "00d2449afefd2e5f",
|
||||
"hooks/gsd-session-state.sh": "e54379ba86bf1b6d",
|
||||
"hooks/gsd-statusline.js": "7c315416ffc99a9a",
|
||||
"hooks/gsd-statusline.js": "920558a55eb86587",
|
||||
"hooks/gsd-update-banner.js": "b457746cb76c1957",
|
||||
"hooks/gsd-validate-commit.sh": "bf5dd61d33cb3a38",
|
||||
"hooks/gsd-windsurf-pre-command.js": "948be1c6d14c79cd",
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
"gsd-core/bin/gsd-tools.cjs": "37fb6081fcb18038",
|
||||
"gsd-core/bin/gsd_run": "62d9b647ede212e6",
|
||||
"gsd-core/bin/shared/config-defaults.manifest.json": "517e6a7c1e9f4f16",
|
||||
"gsd-core/bin/shared/config-schema.manifest.json": "6bba2b9c9fa47cb8",
|
||||
"gsd-core/bin/shared/config-schema.manifest.json": "b67705431d738ae7",
|
||||
"gsd-core/bin/shared/model-catalog.json": "b55176ca044728d3",
|
||||
"gsd-core/bin/shared/runtime-aliases.manifest.json": "2df2c5ac1957911a",
|
||||
"gsd-core/bin/verify-reapply-patches.cjs": "caec5dbce11e3904",
|
||||
@@ -327,7 +327,7 @@
|
||||
"hooks/gsd-read-guard.js": "9e423cd03e2d1b16",
|
||||
"hooks/gsd-read-injection-scanner.js": "00d2449afefd2e5f",
|
||||
"hooks/gsd-session-state.sh": "e54379ba86bf1b6d",
|
||||
"hooks/gsd-statusline.js": "7c315416ffc99a9a",
|
||||
"hooks/gsd-statusline.js": "920558a55eb86587",
|
||||
"hooks/gsd-update-banner.js": "b457746cb76c1957",
|
||||
"hooks/gsd-validate-commit.sh": "bf5dd61d33cb3a38",
|
||||
"hooks/gsd-windsurf-pre-command.js": "948be1c6d14c79cd",
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
"gsd-core/bin/gsd-tools.cjs": "a84914f7cab74332",
|
||||
"gsd-core/bin/gsd_run": "62d9b647ede212e6",
|
||||
"gsd-core/bin/shared/config-defaults.manifest.json": "517e6a7c1e9f4f16",
|
||||
"gsd-core/bin/shared/config-schema.manifest.json": "6bba2b9c9fa47cb8",
|
||||
"gsd-core/bin/shared/config-schema.manifest.json": "b67705431d738ae7",
|
||||
"gsd-core/bin/shared/model-catalog.json": "b55176ca044728d3",
|
||||
"gsd-core/bin/shared/runtime-aliases.manifest.json": "2df2c5ac1957911a",
|
||||
"gsd-core/bin/verify-reapply-patches.cjs": "caec5dbce11e3904",
|
||||
|
||||
@@ -112,7 +112,7 @@
|
||||
"gsd-core/bin/gsd-tools.cjs": "37fb6081fcb18038",
|
||||
"gsd-core/bin/gsd_run": "62d9b647ede212e6",
|
||||
"gsd-core/bin/shared/config-defaults.manifest.json": "517e6a7c1e9f4f16",
|
||||
"gsd-core/bin/shared/config-schema.manifest.json": "6bba2b9c9fa47cb8",
|
||||
"gsd-core/bin/shared/config-schema.manifest.json": "b67705431d738ae7",
|
||||
"gsd-core/bin/shared/model-catalog.json": "b55176ca044728d3",
|
||||
"gsd-core/bin/shared/runtime-aliases.manifest.json": "2df2c5ac1957911a",
|
||||
"gsd-core/bin/verify-reapply-patches.cjs": "caec5dbce11e3904",
|
||||
@@ -399,7 +399,7 @@
|
||||
"hooks/gsd-read-guard.js": "9e423cd03e2d1b16",
|
||||
"hooks/gsd-read-injection-scanner.js": "7f7a7615b303369a",
|
||||
"hooks/gsd-session-state.sh": "e54379ba86bf1b6d",
|
||||
"hooks/gsd-statusline.js": "ef8dcb6d64fd4493",
|
||||
"hooks/gsd-statusline.js": "6ab2905537f885ba",
|
||||
"hooks/gsd-update-banner.js": "55143a25f978f301",
|
||||
"hooks/gsd-validate-commit.sh": "bf5dd61d33cb3a38",
|
||||
"hooks/gsd-windsurf-pre-command.js": "948be1c6d14c79cd",
|
||||
|
||||
@@ -147,7 +147,7 @@
|
||||
"gsd-core/bin/gsd-tools.cjs": "37fb6081fcb18038",
|
||||
"gsd-core/bin/gsd_run": "62d9b647ede212e6",
|
||||
"gsd-core/bin/shared/config-defaults.manifest.json": "517e6a7c1e9f4f16",
|
||||
"gsd-core/bin/shared/config-schema.manifest.json": "6bba2b9c9fa47cb8",
|
||||
"gsd-core/bin/shared/config-schema.manifest.json": "b67705431d738ae7",
|
||||
"gsd-core/bin/shared/model-catalog.json": "b55176ca044728d3",
|
||||
"gsd-core/bin/shared/runtime-aliases.manifest.json": "2df2c5ac1957911a",
|
||||
"gsd-core/bin/verify-reapply-patches.cjs": "caec5dbce11e3904",
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
"gsd-core/bin/gsd-tools.cjs": "600e9ed0cb6ed7bb",
|
||||
"gsd-core/bin/gsd_run": "62d9b647ede212e6",
|
||||
"gsd-core/bin/shared/config-defaults.manifest.json": "517e6a7c1e9f4f16",
|
||||
"gsd-core/bin/shared/config-schema.manifest.json": "6bba2b9c9fa47cb8",
|
||||
"gsd-core/bin/shared/config-schema.manifest.json": "b67705431d738ae7",
|
||||
"gsd-core/bin/shared/model-catalog.json": "b55176ca044728d3",
|
||||
"gsd-core/bin/shared/runtime-aliases.manifest.json": "2df2c5ac1957911a",
|
||||
"gsd-core/bin/verify-reapply-patches.cjs": "10226e9512dd44bf",
|
||||
|
||||
@@ -112,7 +112,7 @@
|
||||
"gsd-core/bin/gsd-tools.cjs": "db16ded31dd6eecf",
|
||||
"gsd-core/bin/gsd_run": "62d9b647ede212e6",
|
||||
"gsd-core/bin/shared/config-defaults.manifest.json": "517e6a7c1e9f4f16",
|
||||
"gsd-core/bin/shared/config-schema.manifest.json": "6bba2b9c9fa47cb8",
|
||||
"gsd-core/bin/shared/config-schema.manifest.json": "b67705431d738ae7",
|
||||
"gsd-core/bin/shared/model-catalog.json": "b55176ca044728d3",
|
||||
"gsd-core/bin/shared/runtime-aliases.manifest.json": "2df2c5ac1957911a",
|
||||
"gsd-core/bin/verify-reapply-patches.cjs": "caec5dbce11e3904",
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
"gsd-core/bin/gsd-tools.cjs": "b3f927ee4b4c4711",
|
||||
"gsd-core/bin/gsd_run": "62d9b647ede212e6",
|
||||
"gsd-core/bin/shared/config-defaults.manifest.json": "517e6a7c1e9f4f16",
|
||||
"gsd-core/bin/shared/config-schema.manifest.json": "6bba2b9c9fa47cb8",
|
||||
"gsd-core/bin/shared/config-schema.manifest.json": "b67705431d738ae7",
|
||||
"gsd-core/bin/shared/model-catalog.json": "b55176ca044728d3",
|
||||
"gsd-core/bin/shared/runtime-aliases.manifest.json": "2df2c5ac1957911a",
|
||||
"gsd-core/bin/verify-reapply-patches.cjs": "caec5dbce11e3904",
|
||||
@@ -328,7 +328,7 @@
|
||||
"hooks/gsd-read-guard.js": "1f58b020a91f032b",
|
||||
"hooks/gsd-read-injection-scanner.js": "f358eca3fa1eab24",
|
||||
"hooks/gsd-session-state.sh": "e54379ba86bf1b6d",
|
||||
"hooks/gsd-statusline.js": "861808560e60b233",
|
||||
"hooks/gsd-statusline.js": "34d2ae303558b917",
|
||||
"hooks/gsd-update-banner.js": "b457746cb76c1957",
|
||||
"hooks/gsd-validate-commit.sh": "bf5dd61d33cb3a38",
|
||||
"hooks/gsd-windsurf-pre-command.js": "948be1c6d14c79cd",
|
||||
|
||||
@@ -112,7 +112,7 @@
|
||||
"gsd-core/bin/gsd-tools.cjs": "37fb6081fcb18038",
|
||||
"gsd-core/bin/gsd_run": "62d9b647ede212e6",
|
||||
"gsd-core/bin/shared/config-defaults.manifest.json": "517e6a7c1e9f4f16",
|
||||
"gsd-core/bin/shared/config-schema.manifest.json": "6bba2b9c9fa47cb8",
|
||||
"gsd-core/bin/shared/config-schema.manifest.json": "b67705431d738ae7",
|
||||
"gsd-core/bin/shared/model-catalog.json": "b55176ca044728d3",
|
||||
"gsd-core/bin/shared/runtime-aliases.manifest.json": "2df2c5ac1957911a",
|
||||
"gsd-core/bin/verify-reapply-patches.cjs": "caec5dbce11e3904",
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
".kimi/hooks/gsd-read-guard.js": "9e423cd03e2d1b16",
|
||||
".kimi/hooks/gsd-read-injection-scanner.js": "c519598b9257aafa",
|
||||
".kimi/hooks/gsd-session-state.sh": "e54379ba86bf1b6d",
|
||||
".kimi/hooks/gsd-statusline.js": "2736b0885aa97bbf",
|
||||
".kimi/hooks/gsd-statusline.js": "ae0c0e7a934c5deb",
|
||||
".kimi/hooks/gsd-update-banner.js": "55143a25f978f301",
|
||||
".kimi/hooks/gsd-validate-commit.sh": "bf5dd61d33cb3a38",
|
||||
".kimi/hooks/gsd-windsurf-pre-command.js": "948be1c6d14c79cd",
|
||||
@@ -105,7 +105,7 @@
|
||||
"gsd-core/bin/gsd-tools.cjs": "37fb6081fcb18038",
|
||||
"gsd-core/bin/gsd_run": "62d9b647ede212e6",
|
||||
"gsd-core/bin/shared/config-defaults.manifest.json": "517e6a7c1e9f4f16",
|
||||
"gsd-core/bin/shared/config-schema.manifest.json": "6bba2b9c9fa47cb8",
|
||||
"gsd-core/bin/shared/config-schema.manifest.json": "b67705431d738ae7",
|
||||
"gsd-core/bin/shared/model-catalog.json": "b55176ca044728d3",
|
||||
"gsd-core/bin/shared/runtime-aliases.manifest.json": "2df2c5ac1957911a",
|
||||
"gsd-core/bin/verify-reapply-patches.cjs": "caec5dbce11e3904",
|
||||
|
||||
@@ -112,7 +112,7 @@
|
||||
"gsd-core/bin/gsd-tools.cjs": "37fb6081fcb18038",
|
||||
"gsd-core/bin/gsd_run": "62d9b647ede212e6",
|
||||
"gsd-core/bin/shared/config-defaults.manifest.json": "517e6a7c1e9f4f16",
|
||||
"gsd-core/bin/shared/config-schema.manifest.json": "6bba2b9c9fa47cb8",
|
||||
"gsd-core/bin/shared/config-schema.manifest.json": "b67705431d738ae7",
|
||||
"gsd-core/bin/shared/model-catalog.json": "b55176ca044728d3",
|
||||
"gsd-core/bin/shared/runtime-aliases.manifest.json": "2df2c5ac1957911a",
|
||||
"gsd-core/bin/verify-reapply-patches.cjs": "caec5dbce11e3904",
|
||||
@@ -399,7 +399,7 @@
|
||||
"hooks/gsd-read-guard.js": "9e423cd03e2d1b16",
|
||||
"hooks/gsd-read-injection-scanner.js": "f72060dfe035f706",
|
||||
"hooks/gsd-session-state.sh": "e54379ba86bf1b6d",
|
||||
"hooks/gsd-statusline.js": "9c132b5985800462",
|
||||
"hooks/gsd-statusline.js": "3dd40389fa786dd6",
|
||||
"hooks/gsd-update-banner.js": "55143a25f978f301",
|
||||
"hooks/gsd-validate-commit.sh": "bf5dd61d33cb3a38",
|
||||
"hooks/gsd-windsurf-pre-command.js": "948be1c6d14c79cd",
|
||||
|
||||
4
tests/fixtures/golden-install-parity/pi.json
vendored
4
tests/fixtures/golden-install-parity/pi.json
vendored
@@ -8,7 +8,7 @@
|
||||
"gsd-core/bin/gsd-tools.cjs": "37fb6081fcb18038",
|
||||
"gsd-core/bin/gsd_run": "62d9b647ede212e6",
|
||||
"gsd-core/bin/shared/config-defaults.manifest.json": "517e6a7c1e9f4f16",
|
||||
"gsd-core/bin/shared/config-schema.manifest.json": "6bba2b9c9fa47cb8",
|
||||
"gsd-core/bin/shared/config-schema.manifest.json": "b67705431d738ae7",
|
||||
"gsd-core/bin/shared/model-catalog.json": "b55176ca044728d3",
|
||||
"gsd-core/bin/shared/runtime-aliases.manifest.json": "2df2c5ac1957911a",
|
||||
"gsd-core/bin/verify-reapply-patches.cjs": "caec5dbce11e3904",
|
||||
@@ -295,7 +295,7 @@
|
||||
"hooks/gsd-read-guard.js": "9e423cd03e2d1b16",
|
||||
"hooks/gsd-read-injection-scanner.js": "f454242c010804cf",
|
||||
"hooks/gsd-session-state.sh": "e54379ba86bf1b6d",
|
||||
"hooks/gsd-statusline.js": "5539e1ae859b987e",
|
||||
"hooks/gsd-statusline.js": "41b0080cf0f3e7e9",
|
||||
"hooks/gsd-update-banner.js": "55143a25f978f301",
|
||||
"hooks/gsd-validate-commit.sh": "bf5dd61d33cb3a38",
|
||||
"hooks/gsd-windsurf-pre-command.js": "948be1c6d14c79cd",
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
"gsd-core/bin/gsd-tools.cjs": "6454021dec4d9563",
|
||||
"gsd-core/bin/gsd_run": "62d9b647ede212e6",
|
||||
"gsd-core/bin/shared/config-defaults.manifest.json": "517e6a7c1e9f4f16",
|
||||
"gsd-core/bin/shared/config-schema.manifest.json": "6bba2b9c9fa47cb8",
|
||||
"gsd-core/bin/shared/config-schema.manifest.json": "b67705431d738ae7",
|
||||
"gsd-core/bin/shared/model-catalog.json": "b55176ca044728d3",
|
||||
"gsd-core/bin/shared/runtime-aliases.manifest.json": "2df2c5ac1957911a",
|
||||
"gsd-core/bin/verify-reapply-patches.cjs": "caec5dbce11e3904",
|
||||
@@ -328,7 +328,7 @@
|
||||
"hooks/gsd-read-guard.js": "2c8d417d12b51040",
|
||||
"hooks/gsd-read-injection-scanner.js": "396574bd25e99ff9",
|
||||
"hooks/gsd-session-state.sh": "e54379ba86bf1b6d",
|
||||
"hooks/gsd-statusline.js": "739140996a3c0d49",
|
||||
"hooks/gsd-statusline.js": "5686cf31c721b2b1",
|
||||
"hooks/gsd-update-banner.js": "b457746cb76c1957",
|
||||
"hooks/gsd-validate-commit.sh": "bf5dd61d33cb3a38",
|
||||
"hooks/gsd-windsurf-pre-command.js": "948be1c6d14c79cd",
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
"gsd-core/bin/gsd-tools.cjs": "c28c9076058c5e73",
|
||||
"gsd-core/bin/gsd_run": "62d9b647ede212e6",
|
||||
"gsd-core/bin/shared/config-defaults.manifest.json": "517e6a7c1e9f4f16",
|
||||
"gsd-core/bin/shared/config-schema.manifest.json": "6bba2b9c9fa47cb8",
|
||||
"gsd-core/bin/shared/config-schema.manifest.json": "b67705431d738ae7",
|
||||
"gsd-core/bin/shared/model-catalog.json": "b55176ca044728d3",
|
||||
"gsd-core/bin/shared/runtime-aliases.manifest.json": "2df2c5ac1957911a",
|
||||
"gsd-core/bin/verify-reapply-patches.cjs": "caec5dbce11e3904",
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
"gsd-core/bin/gsd-tools.cjs": "568e7c6bdd415c1a",
|
||||
"gsd-core/bin/gsd_run": "62d9b647ede212e6",
|
||||
"gsd-core/bin/shared/config-defaults.manifest.json": "517e6a7c1e9f4f16",
|
||||
"gsd-core/bin/shared/config-schema.manifest.json": "6bba2b9c9fa47cb8",
|
||||
"gsd-core/bin/shared/config-schema.manifest.json": "b67705431d738ae7",
|
||||
"gsd-core/bin/shared/model-catalog.json": "b55176ca044728d3",
|
||||
"gsd-core/bin/shared/runtime-aliases.manifest.json": "2df2c5ac1957911a",
|
||||
"gsd-core/bin/verify-reapply-patches.cjs": "caec5dbce11e3904",
|
||||
|
||||
@@ -112,7 +112,7 @@
|
||||
"gsd-core/bin/gsd-tools.cjs": "37fb6081fcb18038",
|
||||
"gsd-core/bin/gsd_run": "62d9b647ede212e6",
|
||||
"gsd-core/bin/shared/config-defaults.manifest.json": "517e6a7c1e9f4f16",
|
||||
"gsd-core/bin/shared/config-schema.manifest.json": "6bba2b9c9fa47cb8",
|
||||
"gsd-core/bin/shared/config-schema.manifest.json": "b67705431d738ae7",
|
||||
"gsd-core/bin/shared/model-catalog.json": "b55176ca044728d3",
|
||||
"gsd-core/bin/shared/runtime-aliases.manifest.json": "2df2c5ac1957911a",
|
||||
"gsd-core/bin/verify-reapply-patches.cjs": "caec5dbce11e3904",
|
||||
|
||||
@@ -1190,5 +1190,176 @@ test('config-set rejects invalid statusline.context_position', () => {
|
||||
cleanup(tmpDir);
|
||||
}
|
||||
});
|
||||
|
||||
// Same write-path enforcement for the boolean statusline.show_context_tokens
|
||||
// key (#2161) — mirrors the workflow.post_planning_gaps precedent the issue's
|
||||
// scope names (tests/post-planning-gaps-2493.test.cjs).
|
||||
test('config-set statusline.show_context_tokens true → persisted as boolean', () => {
|
||||
const tmpDir = createTempProject();
|
||||
try {
|
||||
const r = runGsdTools(['config-set', 'statusline.show_context_tokens', 'true'], tmpDir);
|
||||
assert.ok(r.success, r.error);
|
||||
const config = JSON.parse(
|
||||
fs.readFileSync(path.join(tmpDir, '.planning', 'config.json'), 'utf-8'));
|
||||
assert.strictEqual(config.statusline.show_context_tokens, true);
|
||||
} finally {
|
||||
cleanup(tmpDir);
|
||||
}
|
||||
});
|
||||
|
||||
test('config-set statusline.show_context_tokens yes → rejected', () => {
|
||||
const tmpDir = createTempProject();
|
||||
try {
|
||||
const r = runGsdTools(['config-set', 'statusline.show_context_tokens', 'yes'], tmpDir);
|
||||
assert.equal(r.success, false, 'non-boolean value must be rejected');
|
||||
assert.match(r.error || r.output, /boolean|true|false/i);
|
||||
} finally {
|
||||
cleanup(tmpDir);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// ────────────────────────────────────────────────────────────────────────
|
||||
// Context meter token count (statusline.show_context_tokens)
|
||||
// ────────────────────────────────────────────────────────────────────────
|
||||
{
|
||||
const { test, describe } = require('node:test');
|
||||
const assert = require('node:assert/strict');
|
||||
const fs = require('node:fs');
|
||||
const os = require('node:os');
|
||||
const path = require('node:path');
|
||||
const { execFileSync } = require('node:child_process');
|
||||
const { cleanup } = require('./helpers.cjs');
|
||||
const { formatTokens, contextTokenSuffix } = require('../hooks/gsd-statusline.js');
|
||||
const { VALID_CONFIG_KEYS } = require('../gsd-core/bin/lib/config-schema.cjs');
|
||||
|
||||
const hookPath = path.join(__dirname, '..', 'hooks', 'gsd-statusline.js');
|
||||
|
||||
describe('config schema: statusline.show_context_tokens', () => {
|
||||
test('registers statusline.show_context_tokens', () => {
|
||||
assert.ok(
|
||||
VALID_CONFIG_KEYS.has('statusline.show_context_tokens'),
|
||||
'statusline.show_context_tokens must be in VALID_CONFIG_KEYS',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('formatTokens', () => {
|
||||
test('passes small counts through', () => {
|
||||
assert.equal(formatTokens(0), '0');
|
||||
assert.equal(formatTokens(999), '999');
|
||||
});
|
||||
test('rounds thousands to k', () => {
|
||||
assert.equal(formatTokens(1000), '1k');
|
||||
assert.equal(formatTokens(156342), '156k');
|
||||
assert.equal(formatTokens(156700), '157k');
|
||||
});
|
||||
test('formats millions with one decimal', () => {
|
||||
assert.equal(formatTokens(1000000), '1.0M');
|
||||
assert.equal(formatTokens(1234567), '1.2M');
|
||||
});
|
||||
test('k-to-M threshold boundary: limit-1 / limit / limit+1', () => {
|
||||
// 999,999 k-rounds to 1000 — must promote to the M branch, never "1000k"
|
||||
assert.equal(formatTokens(999999), '1.0M');
|
||||
assert.equal(formatTokens(1000000), '1.0M');
|
||||
assert.equal(formatTokens(1000001), '1.0M');
|
||||
// 999,499 is the last value that still k-rounds below 1000
|
||||
assert.equal(formatTokens(999499), '999k');
|
||||
assert.equal(formatTokens(999500), '1.0M');
|
||||
});
|
||||
});
|
||||
|
||||
describe('contextTokenSuffix', () => {
|
||||
test('returns empty string for absent/malformed usage', () => {
|
||||
assert.equal(contextTokenSuffix(null), '');
|
||||
assert.equal(contextTokenSuffix(undefined), '');
|
||||
assert.equal(contextTokenSuffix('nope'), '');
|
||||
assert.equal(contextTokenSuffix({}), '');
|
||||
});
|
||||
test('sums all four token dimensions', () => {
|
||||
const suffix = contextTokenSuffix({
|
||||
input_tokens: 1000,
|
||||
cache_creation_input_tokens: 2000,
|
||||
cache_read_input_tokens: 150000,
|
||||
output_tokens: 3000,
|
||||
});
|
||||
assert.equal(suffix, ' (156k)');
|
||||
});
|
||||
test('tolerates missing dimensions', () => {
|
||||
assert.equal(contextTokenSuffix({ input_tokens: 500 }), ' (500)');
|
||||
});
|
||||
});
|
||||
|
||||
describe('statusline output token suffix (e2e)', () => {
|
||||
function makeProject(flag) {
|
||||
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'ctx-tokens-'));
|
||||
fs.mkdirSync(path.join(dir, '.planning'), { recursive: true });
|
||||
if (flag !== undefined) {
|
||||
fs.writeFileSync(
|
||||
path.join(dir, '.planning', 'config.json'),
|
||||
JSON.stringify({ statusline: { show_context_tokens: flag } }),
|
||||
);
|
||||
}
|
||||
return dir;
|
||||
}
|
||||
|
||||
function runHook(dir) {
|
||||
const payload = JSON.stringify({
|
||||
model: { display_name: 'Claude' },
|
||||
workspace: { current_dir: dir },
|
||||
session_id: `test-tokens-${Date.now()}-${Math.random().toString(36).slice(2)}`,
|
||||
context_window: {
|
||||
remaining_percentage: 70,
|
||||
total_tokens: 200000,
|
||||
current_usage: {
|
||||
input_tokens: 1000,
|
||||
cache_read_input_tokens: 150000,
|
||||
output_tokens: 5000,
|
||||
},
|
||||
},
|
||||
});
|
||||
let stdout = '';
|
||||
try {
|
||||
stdout = execFileSync(process.execPath, [hookPath], {
|
||||
input: payload, encoding: 'utf8', timeout: 4000,
|
||||
});
|
||||
} catch (e) {
|
||||
stdout = e.stdout || '';
|
||||
}
|
||||
// eslint-disable-next-line no-control-regex -- stripping ANSI SGR sequences from captured CLI output
|
||||
return stdout.replace(/\x1b\[[0-9;]*m/g, '');
|
||||
}
|
||||
|
||||
test('flag=true appends the token count after the percentage', () => {
|
||||
const dir = makeProject(true);
|
||||
try {
|
||||
const out = runHook(dir);
|
||||
assert.match(out, /% \(156k\)/, `expected "(156k)" after the meter %; got: ${out}`);
|
||||
} finally {
|
||||
cleanup(dir);
|
||||
}
|
||||
});
|
||||
|
||||
test('default (flag absent) meter is unchanged — no token count', () => {
|
||||
const dir = makeProject(undefined);
|
||||
try {
|
||||
const out = runHook(dir);
|
||||
assert.doesNotMatch(out, /\(\d+(?:\.\d+)?[kM]?\)/, `expected no token suffix; got: ${out}`);
|
||||
} finally {
|
||||
cleanup(dir);
|
||||
}
|
||||
});
|
||||
|
||||
test('flag=false meter is unchanged — no token count', () => {
|
||||
const dir = makeProject(false);
|
||||
try {
|
||||
const out = runHook(dir);
|
||||
assert.doesNotMatch(out, /\(\d+(?:\.\d+)?[kM]?\)/, `expected no token suffix; got: ${out}`);
|
||||
} finally {
|
||||
cleanup(dir);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user