Skip to content

Commit 7e9861a

Browse files
committed
v2.0.0 — printer-table preview + ETA + tags/search/filters, multi-select bulk delete, guided RFID chip update, Elegoo % + colour-to-chip fixes
1 parent 657e9c5 commit 7e9861a

117 files changed

Lines changed: 3076 additions & 279 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.github/workflows/build.yml‎

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,32 @@ permissions:
99
contents: write
1010

1111
jobs:
12+
# ─────────────────────────────────────────────────────────────────
13+
# Runs FIRST — creates the draft release for this tag and fills its
14+
# body with the CHANGELOG.md section, BEFORE any platform build runs.
15+
# The three build jobs then just attach their assets to this already-
16+
# described draft, so none of them races to write (or accidentally
17+
# blank) the release body.
18+
# ─────────────────────────────────────────────────────────────────
19+
prepare-release:
20+
runs-on: ubuntu-latest
21+
steps:
22+
- uses: actions/checkout@v5
23+
24+
- name: Build release notes from CHANGELOG.md
25+
run: node scripts/extract-changelog.mjs "${{ github.ref_name }}" > release-notes.md
26+
27+
- name: Create draft release with description
28+
uses: softprops/action-gh-release@v3
29+
with:
30+
tag_name: ${{ github.ref_name }}
31+
draft: true
32+
body_path: release-notes.md
33+
env:
34+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
35+
1236
build:
37+
needs: prepare-release
1338
strategy:
1439
fail-fast: false
1540
matrix:

‎CHANGELOG.md‎

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,37 @@ Versions follow [Semantic Versioning](https://semver.org/).
55

66
---
77

8+
## v2.0.0 — 2026-07-07
9+
10+
Tiger Studio Manager turns **2.0** — a big round of printer-table upgrades, a proper guided flow for updating a chip, and a pile of fixes.
11+
12+
### Added
13+
14+
- **See what's printing, right in the table.** The Printers table now has a **Preview** column showing the model on the bed for whatever's currently printing — pulled live from each printer.
15+
- **Know when the printer's free.** A new **"Ends at"** column shows the wall-clock time the current job finishes (e.g. `21:23`), so you know exactly when to come back. Click the header to sort by soonest finish.
16+
- **Tags for your printers.** Give your printers labels the same way you tag spools — chips, autocomplete, the works — right in each printer's side card.
17+
- **Search & filter your printers.** The search bar now works in the Printers view (name, brand, model, IP…), and the filters next to it become **Brand · State (online/offline) · Tags** so you can zero in fast.
18+
- **Delete several at once.** A new multi-select mode lets you tick a bunch of spools — or printers — and remove them together, with a press-and-hold confirm. In the table, the tick column is always there (Shopify-style); click, shift-click a range, or Select all.
19+
20+
### Changed
21+
22+
- **Updating a chip is now guided.** Tapping "Please update RFID" opens a clear panel that shows your reader(s) waiting for the chip: place the right one and it lights up green, a wrong chip lights up red with a heads-up, and the update only runs once everything matches — no more guessing, and never a write to the wrong chip.
23+
- **Fresh chip, straight to work.** Scan a blank TigerTag chip and the "+ Material" panel opens right away so you can set it up on the spot.
24+
25+
### Fixed
26+
27+
- **Editing a filament's colour now actually reaches the chip.** Changing a colour and hitting Update used to leave the chip on its old colour (a rescan proved it) — the new colour is now written for real, and reads back correctly.
28+
- **Elegoo progress behaves.** The print percentage no longer jumps around between wild values mid-print — it climbs smoothly like it should.
29+
- **"Storage location" lights up again.** Clicking a spool's storage location jumps to Storage and highlights its slot, with everything else dimmed — as it used to.
30+
- **The "not stored" panel keeps up.** Recolour a spool that isn't in a rack and its picture refreshes immediately.
31+
- **Snapmaker firmware guide, in your language.** The recommended-firmware setup steps for the Snapmaker U1 are now translated across all 9 languages.
32+
33+
### Removed
34+
35+
- The redundant "N selected" label in the multi-select bar — the Delete (N) button already shows the count.
36+
37+
---
38+
839
## v1.10.31 — 2026-07-06
940

1041
### Added

‎CLAUDE.md‎

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -85,15 +85,18 @@ Before writing the `CHANGELOG.md` entry, do one final editorial pass on WORKLOG:
8585

8686
1. **Merge related items.** Several "TigerPOD modal" entries → one grouped bullet with sub-items.
8787
2. **Drop ephemeral noise.** Version bump, llms.txt update, internal refactors with no user-visible effect → omit or fold into a single "internal" line.
88-
3. **User-facing language.** CHANGELOG is read by end users. Rewrite technical entries in plain language ("Bambu MQTT: fix _normState null return" → "Bambu Lab: printer state no longer resets to idle when receiving a status update mid-print").
88+
3. **Changelog voice = register 1 (technical).** The `CHANGELOG.md` entry is the **exhaustive, technical source of record** — precise about behaviour *and* mechanism (see *Three copy registers* above). Keep it detailed; it is read by you, experts and agents, not by end users. The user-facing wording happens in registers 2 & 3, not here — so don't dumb the changelog down, and don't make it jokey.
89+
- **Sections** `### Added`, `### Changed`, `### Fixed`, `### Removed`.
90+
- One logical change per bullet; name the subsystem / brand / view; internal identifiers are allowed here (this is the one register where they belong).
8991
4. **Verify i18n delta.** Run `npm run i18n:check` — confirm key count matches WORKLOG before writing the CHANGELOG line.
9092

91-
### At commit time (3 steps, in order)
93+
### At commit time (in order)
9294

93-
1. **Synthesize `WORKLOG.md`** (Rule 3 above) → write the new `CHANGELOG.md` entry
94-
2. **Write the "What's New" entry** for the version → `data/whatsnew.json`. Run `npm run whatsnew:add -- <x.y.z> [--items N] [--date YYYY-MM-DD]` to scaffold an empty **9-locale** block, then fill each item's `icon` (emoji) + vulgarised `title`/`body` for **all 9 locales** (history is kept — never delete old versions). Verify with `npm run whatsnew:check` (must pass — no empty locale). This drives the in-app "What's New" modal shown once per version (and re-openable from Settings → About).
95-
3. **Include `WORKLOG.md` in the commit** — it is part of the repo history (future sessions can read it via `git show`)
96-
4. **Reset `WORKLOG.md` AND bump `package.json` to the NEXT version** immediately after committing — both left **uncommitted** (they ship with the next release). Bumping `package.json` here (not only at release time) means the **dev build shows the in-progress version number** (`#sbVersion`) instead of the previous release's — so while working on vN+1 the app reads `vN+1`, not `vN`. Consequence: at the next release `package.json` is **already** at the release version, so the release ritual doesn't re-bump it — it's committed as-is with the `vX.Y.Z —` commit. Replace `WORKLOG.md` with the blank template for the next version (bump the header too):
95+
1. **Synthesize `WORKLOG.md`** (Rule 3 above) → write the new `CHANGELOG.md` entry (register 1 — technical).
96+
2. **Write the release note** (register 2 — BambuLab style) → `data/release-notes/vX.Y.Z.md`. Rewrite the changelog into factual, jargon-free bullets (`Fixed an issue where …`, no internal code names); end with the standard footer (copy it from the previous version's file). This file becomes the **GitHub Release page body** verbatim via `scripts/extract-changelog.mjs`. Skipping it means the release page falls back to the raw changelog — avoid that.
97+
3. **Write the "What's New" entry** (register 3 — Discord/app voice) for the version → `data/whatsnew.json`. Run `npm run whatsnew:add -- <x.y.z> [--items N] [--date YYYY-MM-DD]` to scaffold an empty **9-locale** block, then fill each item's `icon` (emoji) + vulgarised `title`/`body` for **all 9 locales** (history is kept — never delete old versions). Verify with `npm run whatsnew:check` (must pass — no empty locale). This drives the in-app "What's New" modal shown once per version (and re-openable from Settings → About).
98+
4. **Include `WORKLOG.md` in the commit** — it is part of the repo history (future sessions can read it via `git show`)
99+
5. **Reset `WORKLOG.md` AND bump `package.json` to the NEXT version** immediately after committing — both left **uncommitted** (they ship with the next release). Bumping `package.json` here (not only at release time) means the **dev build shows the in-progress version number** (`#sbVersion`) instead of the previous release's — so while working on vN+1 the app reads `vN+1`, not `vN`. Consequence: at the next release `package.json` is **already** at the release version, so the release ritual doesn't re-bump it — it's committed as-is with the `vX.Y.Z —` commit. Replace `WORKLOG.md` with the blank template for the next version (bump the header too):
97100

98101
```markdown
99102
# Worklog — vX.Y.Z (in progress)
@@ -121,6 +124,28 @@ The working file is wiped so it stays clean and unambiguous: whatever is in `WOR
121124

122125
---
123126

127+
## ✍️ Three copy registers — Changelog ≠ Release note ≠ What's New
128+
129+
Every release ships the **same changes described three times**, at three altitudes, for three audiences. Each has its own file and its own voice. **Writing one in another's voice is a bug** — don't blur them, and don't auto-copy one into another verbatim.
130+
131+
| # | Register | Lives in | Audience | Voice |
132+
|---|----------|----------|----------|-------|
133+
| **1** | **Changelog** | `CHANGELOG.md` | You, experts, **AI / agents reading the repo** | **Exhaustive & technical — the source of record.** Precise about *behaviour AND mechanism*; may name subsystems, protocols, config keys, Firestore paths, magic values. Nothing is "too technical" here — this is the deepest of the three. English, one logical change per bullet. (Synthesized from `WORKLOG.md` at commit time.) |
134+
| **2** | **Release note** | `data/release-notes/vX.Y.Z.md` → **GitHub Release page** | Power users, integrators browsing releases | **BambuLab style** — factual & specific but **jargon-free**. Name the real feature / view / **printer brand**; `Fixed an issue where …` for fixes; one line per change; **NO internal code names** (no file / function / class / IPC names, no line numbers, no key counts). Higher-level and terser than the changelog. See [BambuLab releases](https://github.com/bambulab/BambuStudio/releases). |
135+
| **3** | **What's New + all in-app copy** | `data/whatsnew.json` **and every string in the app** (UI, buttons, empty states, errors, nudges) | Everyone, inside the app | **Playful, deadpan, Discord-style** — benefit-first, no jargon, never describes what doesn't exist. **9 locales.** (Full rule: memory `feedback-copy-tone` + the *Brand voice* rule below.) |
136+
137+
**The same fix, three ways** (Elegoo progress bug):
138+
- **Changelog (1):** *"Elegoo `_mergeStatus`: `machine_status.progress` (0-100, pushed ~2 s) is now the authoritative progress source and locks out the 1005 time-estimate; kills the 100 %↔10 % spikes from `api_status` pushes that carry `print_duration` but no `remaining_time_sec`."*
139+
- **Release note (2):** *"Fixed an issue where an Elegoo print's progress jumped erratically (e.g. 100 % → 10 % → 31 %) instead of climbing steadily."*
140+
- **What's New (3):** *"Your Elegoo prints finally count up like they mean it — no more panic-jumping from 100 % back to 10 %."*
141+
142+
**Plumbing & pitfalls:**
143+
- The GitHub Release body is built by `scripts/extract-changelog.mjs` (called by the `prepare-release` job in `.github/workflows/build.yml`). It prints `data/release-notes/vX.Y.Z.md` **verbatim** when present (that file already carries its footer), and only **falls back** to the `CHANGELOG.md` section — with a footer appended — when no dedicated note exists. So **register 2 is authored by hand**, it is *not* derived from the changelog.
144+
- `npm run whatsnew:import` (`whatsnew-import-changelog.mjs`) seeds the What's New EN baseline from `CHANGELOG.md` — treat its output as a **rough draft to rewrite into register 3**, never ship it verbatim (it'll be far too technical).
145+
- When in doubt which register you're editing: *who reads this file?* Repo/agent → 1. GitHub release page → 2. Inside the app → 3.
146+
147+
---
148+
124149
## Stack
125150
Electron (no bundler) + vanilla HTML/CSS/JS. Entry: `main.js`. Renderer: `renderer/inventory.html` + modular CSS in `renderer/css/` + `renderer/inventory.js`. Preload bridge: `preload.js`.
126151

@@ -183,7 +208,8 @@ assets/db/tigertag/ — TigerTag reference data (unified in v1.7.0, se
183208
data/ — non-migrated static assets (loaded via direct fetch in renderer)
184209
container_spool/spools_filament.json
185210
rack-presets.json
186-
whatsnew.json — "What's New" modal content, keyed by version, 9 locales inline (full history, browsable via the in-modal version picker). EN baseline imported from CHANGELOG via `npm run whatsnew:import`; recent versions hand-localised. Scaffold `npm run whatsnew:add`, validate `npm run whatsnew:check` (EN mandatory; entries are EN-only or fully 9-locale)
211+
whatsnew.json — "What's New" modal content (register 3 — playful/Discord), keyed by version, 9 locales inline (full history, browsable via the in-modal version picker). `npm run whatsnew:import` seeds an EN baseline from CHANGELOG (register 1) — a **rough draft to rewrite into register 3**, never shipped verbatim; recent versions hand-localised. Scaffold `npm run whatsnew:add`, validate `npm run whatsnew:check` (EN mandatory; entries are EN-only or fully 9-locale)
212+
release-notes/ — one `vX.Y.Z.md` per version: the BambuLab-style **release note** (register 2), pushed verbatim to the GitHub Release page by `scripts/extract-changelog.mjs`. See *Three copy registers*.
187213
printers/ — per-brand printer model catalogs (bbl/cre/eleg/ffg/snap)
188214
assets/svg/
189215
tigertag_logo.svg tigertag_logo_contouring.svg
@@ -435,7 +461,7 @@ The full per-category key list (App/status, Settings, Account, Login, Credential
435461
## Rules
436462
- **UI/UX — be autonomous, apply these by default (don't wait to be told each tweak):** (1) **Declutter** — cut redundant chrome (a `»` tab AND an ✕; titles repeating visible context; obvious subtitles). (2) **Context over labels** — if a state is already visible (selected item highlighted), don't repeat it. (3) **Consistency** — matching components look/size/behave identically (same size collapsed vs expanded; side-cards stack + get `»` tabs like group/material; collapse animation mirrors expand). (4) **Smooth motion, never jumpy** — elements stay put and the container resizes around them (no `justify-content:center` snap); slide don't pop; on a swap the incoming card covers before the outgoing closes; animate labels (max-width/opacity), not `display:none`. (5) **Real icons sized with presence** — masked SVGs over dots/glyphs, consistent sizes, centred on both axes (mind flex `min-width:auto` + top-heavy SVGs). (6) **Show the active/selected state.** (7) **Help/secondary actions in context + light.** (8) **Tighten space** — kill dead gaps, stacked paddings, useless separators. (9) Prefer **shared/generic** CSS-JS over per-file repetition. Propose refinements proactively with a one-line rationale. *(Full version: memory `feedback-ui-ux-autonomy`.)*
437463
- **Language**: Conversation with the user is in French. All project content — code comments, commit messages, documentation, instructions — must be written in English.
438-
- **Brand voice (all user-facing copy)**: every string a user reads — UI labels, buttons, empty states, prompts, nudges, error messages, modals, AND the "What's New" notes (`data/whatsnew.json`) — uses a **playful, deadpan, second-degree voice, Discord-style** (witty, self-aware, talks to you like a mate) — **NOT** Burger-King-style (no aggressive/provocative/troll edge). Lead with the **user benefit** in plain words; **no technical jargon** (avoid "modal", "toggle", "side panel", "header", class names, "TestFlight"…); **never describe what doesn't exist** or our process ("no emoji", "we removed X", "fixed bug Y"). Keep the tone natural in **every locale**. The CHANGELOG stays factual; this voice is for in-app copy + What's New. *(Same rule applies to the mobile app — see its CLAUDE.md.)*
464+
- **Brand voice (all user-facing copy)**: every string a user reads — UI labels, buttons, empty states, prompts, nudges, error messages, modals, AND the "What's New" notes (`data/whatsnew.json`) — uses a **playful, deadpan, second-degree voice, Discord-style** (witty, self-aware, talks to you like a mate) — **NOT** Burger-King-style (no aggressive/provocative/troll edge). Lead with the **user benefit** in plain words; **no technical jargon** (avoid "modal", "toggle", "side panel", "header", class names, "TestFlight"…); **never describe what doesn't exist** or our process ("no emoji", "we removed X", "fixed bug Y"). Keep the tone natural in **every locale**. This playful voice is **register 3** — for **in-app copy + What's New (`data/whatsnew.json`) ONLY**. It is one of **three distinct copy registers** (see [*Three copy registers*](#️-three-copy-registers--changelog--release-note--whats-new)): the **release note** (`data/release-notes/`, register 2) is BambuLab-style factual, and the **`CHANGELOG.md`** (register 1) is exhaustive & technical. Same change, three voices — never blur them, and never ship the technical changelog wording where the playful or the Bambu one belongs. *(Same rule applies to the mobile app — see its CLAUDE.md.)*
439465
- **i18n**: always add all **9** translations (en/fr/de/es/it/zh/pt/pt-pt/pl) in the same edit batch. **Use `npm run i18n:add` — do NOT hand-edit the locale JSON files.** See the *Adding new keys* section above for syntax.
440466
- **Commits**: no `Co-Authored-By` line. **Never commit without explicit user instruction** — make the change, then stop and wait for the order to commit.
441467
- **Naming — clear human semantics first**: every name you introduce (Firestore collection/field, function, variable, CSS class, IPC channel, config key) must read plainly to a human and say what it *is*, so the meaning is obvious without chasing the code. Prefer a self-describing name over a clever/encoded one — e.g. a collection `rfidList` over `rfidChips`, a boolean `rfidListed`/`rfidBackup` over a multi-state `rfidChip: 1|2`. **Avoid encoding several states into one cryptic value** (magic numbers, packed flags): split into separate, well-named booleans/fields. **Don't store what you can derive** — drop redundant fields when an existing one already implies the answer (e.g. no `startState`/type field when the presence of a `backup` already means "TigerTag+"). When a name turns out unclear, rename it (and its doc/schema) rather than letting it stand. Clear semantics now prevent compounding complexity later.

0 commit comments

Comments
 (0)