Skip to content

0.3.2: the meter before you spend, and a strip that stopped drawing - #14

Merged
lroolle merged 1 commit into
mainfrom
feat/settings-section
Aug 24, 2026
Merged

0.3.2: the meter before you spend, and a strip that stopped drawing#14
lroolle merged 1 commit into
mainfrom
feat/settings-section

Conversation

@lroolle

@lroolle lroolle commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Settings > Meter

The dock line needs a session that has already billed a request. So the one
question this plugin exists to answer — what does an hour cost, and when is it
cheap
— could not be asked until after you had paid to ask it.

The Meter section of dsh settings

It holds no controls, on purpose. Both config knobs already live in the
plugin's configuration, which the harness knows how to edit; a second write path
for two fields would be the settings-page reflex rather than the content.

The week grid is the point. The card's 24-hour strip answers "when does today
change"; weekends going off-peak made that a weekly question, and 35 amber
cells out of 168
is the fastest way to see that peak is 35 hours a week, not
49. It is laid out in the reader's local days rather than Beijing's, with every
cell asking tariffAt for its own instant — so the picture cannot drift from
the bill, and nobody converts timezones at 23:00.

The strip had been drawing a lie

tariffSchedule grew a day axis in 0.3.1 — 24 entries became a 7×24 grid — and
its only consumer went on indexing it by UTC hour:

schedule[middle.getUTCHours()]     // rows 0-6 → a row object; 7-23 → undefined

Neither is 'peak', so every cell rendered off-peak and the card drew a flat
day on a Tuesday afternoon. No throw, no warning. Same shape as the projection
break in #13: a producer changed shape, a duck-typed consumer kept reading, and
only the picture was wrong.

The reading is gone, not repaired — each cell asks tariffAt for its own
instant, which is what the schedule's own docstring recommends and leaves no
index to mistranslate. localMidnight / localTariffDays / localWeekStart
moved into lib/core.js, because they were in the browser half where nothing
could test them.

Tests

116 (23 new). Seven fail on the old reading, and they assert what a cell
holds rather than that the call returns — a test checking only
length === 24 passed throughout the outage, and one is kept to say so.
Dictionary parity too: a key in en missing from zh does not fail, it
silently half-translates.

Also

  • Rates print at DeepSeek's precision¥1.5, not ¥1.50. formatMoney
    pads a computed total so a column of session costs lines up; a rate is a
    quotation, and padding it put ¥0.0500 beside ¥1.50 in one column.
  • An easter egg in Chinese. 峰 and 谷 are the old words for time-of-use
    electricity, and the peak half is one character off the name of the man who
    founded the company selling the tokens. Hovering an hour slot in zh-Hans reads
    文峰 / 文谷; English keeps peak / off-peak. It lives in the locale
    dictionaries, so the surface never asks what language it is in.

Verified

Live on dsh 0.1.1-rc.2, both themes and both languages: the section renders
with 35 peak cells, the card strip is back to 7 on a day that has 7 (it was
0), and hover reads 周一 00:00 · 文峰 in zh-Hans, Mon 08:00 · off-peak in en.
Every colour, font and shadow in the surface is a --dsw-* token — no raw hex.

Two things, both about a surface that answered nothing.

The dock line needs a session that has already billed a request, so the
question this plugin exists to answer — what does an hour cost, and when is
it cheap — could not be asked until after you had paid to ask it. Settings >
Meter answers it cold: the tariff running now with its countdown, the week
as a 7x24 grid, the published card in the account's currency, the balance.

It holds no controls on purpose. Both config knobs already live in the
plugin's configuration, which the harness knows how to edit; a second write
path for two fields would be the settings-page reflex rather than the
content. The grid is the point — the card's strip answers "when does today
change", and weekends going off-peak made that a weekly question. 35 amber
cells out of 168 is the fastest way to see that peak is 35 hours a week, not
49.

And the strip had been drawing a lie. `tariffSchedule` grew a day axis in
0.3.1 — 24 entries became a 7x24 grid — and its only consumer went on
indexing it by UTC hour, so every cell came back a row object or `undefined`,
neither of which is 'peak', and the card drew a flat off-peak day on a
Tuesday afternoon. Same shape as the projection break this morning: a
producer changed shape, a duck-typed consumer kept reading, nothing threw,
and only the picture was wrong. The reading is gone rather than repaired —
each cell asks `tariffAt` for its own instant, leaving no index to
mistranslate — and the clock helpers moved into lib/core.js, because they
were in the browser half where nothing could test them.

Seven new tests fail on the old reading. They assert what a cell holds, not
that the call returns: a test checking only `length === 24` passed
throughout the outage, and one is kept to say so. Dictionary parity too — a
key in `en` missing from `zh` does not fail, it silently half-translates.

Rates now print at DeepSeek's own precision (¥1.5, not ¥1.50). formatMoney
pads a computed total so a column lines up; a rate is a quotation, and
padding it put ¥0.0500 beside ¥1.50 in one column.

In Chinese the hour slots carry a joke: 峰 and 谷 are the old words for
time-of-use electricity, and the peak half is one character off the name of
the man who founded the company selling the tokens. Hover reads 文峰 / 文谷.
English keeps peak / off-peak. It lives in the dictionaries, so the surface
never asks what language it is in.

Verified live on dsh 0.1.1-rc.2 in both themes and both languages: the
section renders with 35 peak cells, the card strip is back to 7 on a day
that has 7, and the hover titles read 周一 00:00 · 文峰 in zh-Hans and
Mon 08:00 · off-peak in en. 116 tests.
@lroolle
lroolle merged commit cfd2524 into main Aug 24, 2026
1 check passed
@lroolle
lroolle deleted the feat/settings-section branch August 24, 2026 12:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant