Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion .claude/settings.local.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,16 @@
"Skill(gsd-debug)",
"Skill(gsd-debug:*)",
"mcp__matlab__evaluate_matlab_code",
"mcp__matlab__run_matlab_test_file"
"mcp__matlab__run_matlab_test_file",
"Skill(superpowers:brainstorming)",
"Skill(superpowers:brainstorming:*)",
"Skill(gsd-do)",
"Skill(gsd-do:*)",
"Skill(gsd-quick)",
"Skill(gsd-quick:*)",
"mcp__matlab__run_matlab_file",
"Skill(gsd-add-backlog)",
"Skill(gsd-add-backlog:*)"
]
}
}
12 changes: 11 additions & 1 deletion .planning/ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -191,4 +191,14 @@ Plans:

## Backlog

(empty — last 5 items promoted to phases 1024-1028 on 2026-05-08)
### Phase 999.1: Unified in-app help / user-manual / wiki system (BACKLOG)

**Goal:** [Captured for future planning] Build a project-wide help system so every pane / widget / window can expose an Info button that opens a `uifigure` modal rendering markdown from `docs/help/<area>/<feature>.md`. Reuses `libs/Dashboard/MarkdownRenderer.m` and the existing Dashboard Info modal (260508-n8h). Scope includes: directory layout `docs/help/{companion,dashboard,webbridge,fastsense,sensor-threshold,event-detection}/`, index page with navigation, theme-aware rendering, search-across-docs, optional cross-link resolution, optional hooks into `scripts/generate_wiki.py`.

**Source:** Quick task 260519-bs4 (Tag Status Table) — user requested an info button + markdown; on reflection we agreed a one-off button would be premature; the proper solution is its own milestone-sized piece of work.
**Decisions to nail later:** repo location of help files (`docs/help/` vs. co-located under `libs/`); whether to ship a build-time wiki bundle or render at runtime; theming contract; how/whether to auto-generate from API docs (`scripts/generate_wiki.py` already exists).
**Requirements:** TBD
**Plans:** 0 plans

Plans:
- [ ] TBD (promote with /gsd:review-backlog when ready)
7 changes: 5 additions & 2 deletions .planning/STATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ milestone: v3.0
milestone_name: FastSense Companion
status: shipped
last_updated: "2026-05-12T09:20:00.000Z"
last_activity: 2026-05-14 -- Quick task 260513-s0y shipped (PR #143): Tile + Close all buttons on FastSenseCompanion top toolbar with 3 tracking fixes (sync from Engines_, public trackOpenedFigure hook, de-maximize + Units=pixels coercion). Verified live on industrial-plant demo. 9/9 sub-tests + 64/64 regression PASS.
last_activity: 2026-05-19 - Shipped quick task 260519-bs4 as PR #149: Tag Status Table window in FastSenseCompanion (12-col uitable, window-owned 1s polling, Activity column with 5-min inactive threshold, Type/Criticality/Activity chip filters, Pause/Resume polling toggle, Events count column). Verified on live industrial-plant demo. Filed backlog 999.1 for unified in-app help/wiki system. https://github.com/HanSur94/FastSense/pull/149
progress:
total_phases: 6
completed_phases: 2
Expand All @@ -20,7 +20,9 @@ Phase: 1028
Plan: Not started
Milestone: v3.0 FastSense Companion — SHIPPED 2026-04-30
Status: Awaiting next milestone (run `/gsd:new-milestone` to scope v3.x or v4.0)
Last activity: 2026-05-14 - Quick task 260513-s0y shipped as PR #143 (commits 182d6f1, 2867caa, 1be2cc8, e58bc35, c47c0c1, db9ef88). FastSenseCompanion: Tile + Close all toolbar buttons. Three tracking fixes uncovered by live verification: (1) syncOpenedFigures_ walks Engines_ — DashboardListPane fires OpenDashboardRequested BEFORE engine.render(), and run_demo's pre-rendered demo dashboard never goes through that event flow; (2) public trackOpenedFigure hook on the companion called from InspectorPane.onOpenDetail_ + CompanionEventViewer.openEventDashboard_ which spawn figures directly bypassing the event flow; (3) de-maximize + Units=pixels coercion before set(Position) — DashboardEngine.render defaults to Units=normalized so pixel rectangles got treated as screen fractions, pushing figures off-canvas (root cause of "Tile button does nothing" report). 9/9 sub-tests + 64/64 regression PASS. Verified on live industrial-plant demo.
Last activity: 2026-05-19 - Shipped quick task 260519-bs4 as PR #149 (commits b2ed937, e8a1be5, 43d2d3b, 2a24965, 50d464c, 10df740, 73a3bf1). FastSenseCompanion: Tag Status Table window — 12-col uitable, window-owned 1s polling (works regardless of companion.IsLive), Activity column with 5-min inactive threshold, Type/Criticality/Activity chip filters, broadened search (Key+Name+Units+Labels), Pause/Resume polling toggle, Events count column, "Last refreshed" header heartbeat. PR conflicted with main #143 (Tile+Close all) on the inner toolbar grid; resolved by combining to 1×7 grid (Events|Live|Tags|Tile|Close all|spacer|gear). Verified end-to-end (104/104 tests post-merge + live industrial-plant demo). Backlog 999.1 filed for unified in-app help/wiki system (deferred from a user-requested info button — escalated to milestone scope).

Previous activity: 2026-05-14 - Quick task 260513-s0y shipped as PR #143. FastSenseCompanion: Tile + Close all toolbar buttons. https://github.com/HanSur94/FastSense/pull/143

### Quick Tasks Completed

Expand Down Expand Up @@ -66,6 +68,7 @@ Last activity: 2026-05-14 - Quick task 260513-s0y shipped as PR #143 (commits 18
| 260513-q7w | Debounced post-resize refresh + ZOMBIE-PANEL fix that stops widgets going white during drag-resize and tab switching — TWO parallel timers on every figure resize event (300 ms cheap two-pass refresh + 1.2 s unconditional rerenderWidgets backstop). switchPage cancels both timers AND waits up to 3 s for in-flight rerenderWidgets to complete before mutating state. `IsRerendering_` flag prevents rerender-cascade scheduling. Re-entrancy guard aborts instead of self-rescheduling. **Root-cause fix**: rerenderWidgets now deletes the OUTER cell panel (via hCellPanel, falling back to hPanel for pre-realization widgets) — previous code deleted only `hPanel` which after realization points to the INNER content panel, leaving the outer cell + its WidgetButtonBar chrome alive on the canvas as "zombies" that stacked up over multiple rerenders and painted over freshly switched-to pages. test_dashboard_range_selector_integration 2/2, test_dashboard_time_sync_all_pages 5/5; canvas-children-count canary verifies zero zombie accumulation across 4 rerenders + resize + tab switch (constant 29) | 2026-05-13 | 577bf95, 99c8808, 4eda604, bc305dc, 54d5aa0, 20bcd4c | — | [260513-q7w-during-dashboard-figure-resize-fastsense](./quick/260513-q7w-during-dashboard-figure-resize-fastsense/) |
| 260513-sfp | Add auto-y-limit control buttons (V/A/L) to FastSenseWidget WidgetButtonBar — new YLimitMode property (auto-visible / auto-all / locked, default 'auto-visible' reproduces pre-260513-sfp behaviour), setYLimitMode public method (clears UserZoomedY on explicit click so click re-engages autoscale), autoScaleY_ refactored to dispatch on mode AFTER existing precedence guards (YLimits pin / UserZoomedY / FastSense.LiveViewMode=='follow') so 260513-ovt Follow semantics are preserved. DashboardLayout duck-types widget chrome via ismethod(widget,'setYLimitMode'), so future widgets that expose Y-rescale modes opt in without touching DashboardLayout. ASCII glyphs (V/A/L) match existing Info/Detach. reflowChrome_ re-anchors on resize. toStruct omits the default so legacy dashboards stay diff-invisible. test_fastsense_widget_ylimit_modes 11/11, test_fastsense_widget_tag 7/7, test_fastsense_follow_toggle 10/10, test_dashboard_time_sync_all_pages 5/5. Verified on live industrial-plant demo, all 8 scenarios approved. Known caveat: V/A/L cluster butts against Info button (0-px gap) — inherited from pre-existing addInfoIcon 28-px-typo, explicitly out-of-scope per plan; logged in deferred-items.md | 2026-05-13 | 4db9138, cc18c7f, a9cc181 | Verified | [260513-sfp-add-auto-y-limit-control-buttons-to-fast](./quick/260513-sfp-add-auto-y-limit-control-buttons-to-fast/) |
| 260513-s0y | Add Tile + Close all buttons to FastSenseCompanion top toolbar — private OpenedFigures_ tracking + syncOpenedFigures_ (walks Engines_ before tile/close-all) + public trackOpenedFigure hook (InspectorPane.onOpenDetail_ and CompanionEventViewer.openEventDashboard_ forward their figure handles). tileOpenedWindows: ceil(sqrt(N))×ceil(N/cols) grid on monitor containing the companion, 24px margin, 8px gutter, row-major top-down. Before set(Position), coerces each figure to WindowState='normal' + Units='pixels' — root cause of initial "Tile does nothing" report was DashboardEngine.render defaulting to Units='normalized' (pixel rects got treated as screen fractions, pushing figures off-canvas). closeAllOpenedWindows: snapshot + close(h) per handle (honors each figure's CloseRequestFcn). Inner toolbar grid 1×4→1×6 (Events / Live / Tile / Close all / spacer / gear; gear Layout.Column 4→6). 9 sub-tests in test_companion_tile_close_buttons.m PASS; TestFastSenseCompanion regression 64/64 PASS. Verified on live industrial-plant demo. Shipped as PR #143. | 2026-05-14 | 182d6f1, 2867caa, 1be2cc8, e58bc35, c47c0c1, db9ef88 | Shipped (PR #143) | [260513-s0y-add-tile-windows-and-close-all-windows-b](./quick/260513-s0y-add-tile-windows-and-close-all-windows-b/) |
| 260519-bs4 | Add Tag Status Table window to FastSenseCompanion — new `TagStatusTableWindow.m` (classical figure, not uifigure, per CONTEXT.md), opened via new **Tags ↗** button on companion top toolbar (col 3 in the post-merge 1×7 grid: Events / Live / Tags / Tile / Close all / spacer / gear). Detached-only window with 12-column `uitable`: Key, Name, Type, Criticality, Units, Latest, Status (smart per-type — Monitor→OK/ALARM, State→state label, others→—), Last updated (X(end) timestamp), Activity (Live/Inactive at 5-min threshold), Events (count from EventStore), Samples, Labels. All 18 demo tags listed (snapshot from `TagRegistry.find(@(t)true)`). Two parallel refresh paths: (a) push-on-write via existing `FastSenseCompanion.scanLiveTagUpdates_` → `markStatusTableDirty_(keys)` when companion is in Live mode, (b) window-owned `RefreshTimer_` (1s fixedSpacing, unique UUID name, BusyMode='drop', self-stop after 2 consecutive tick errors) so the table refreshes regardless of companion's IsLive — addresses user feedback that Activity/Last updated must stay correct when companion is idle. Pause/Resume polling toggle freezes both paths (markTagsDirty becomes a no-op while paused; header shows "Last refreshed: HH:MM:SS (paused)"). "Last refreshed" heartbeat label updates every tick. Filter chips mirror TagCatalogPane pattern: Type (Sensor/Monitor/Composite/State/Derived), Criticality (Low/Medium/High/Safety), Activity (Live/Inactive) — multi-toggle, AND-across-groups / OR-within-group; broadened free-text search across Key+Name+Units+Labels. Push-on-write hook in companion stays — both mechanisms run in parallel. Six atomic commits + 1 merge: 01 base class + 11 pure-logic tests; 02 companion wiring + 7 lifecycle tests; 03 Activity column + own timer (+5 logic + 2 lifecycle tests, deviation from "push-on-write only" CONTEXT decision per user); 04 last-refreshed header + chip filters + broader search (+4 logic + 2 lifecycle tests); 05 Pause/Resume polling toggle (+4 lifecycle tests); 06 Events count column (+4 logic + 1 lifecycle test); 07 merge with main (PR #143 toolbar grid conflict). Final test counts post-merge: `test_companion_tag_status_table` 24/24 (pure-logic), `TestTagStatusTableWindow` 16/16 (UI lifecycle), `test_companion_tile_close_buttons` 9/9 (main's new test still PASS), `TestFastSenseCompanion` 64/64 (no regression) = 113/113 total. Verified end-to-end on live industrial-plant demo: 4 MonitorTags showed real event counts (29/32/33/35), 14 others showed 0; Activity flipped Live→Inactive at exactly 5-min boundary via static buildRow_ proof; companion IsLive=0 throughout (window polled itself). Deferred / out-of-scope: (1) polling-scope clarification dismissed by user (heartbeat-only vs. passive-observation vs. only-update-changed-cells — left as-is, table updates all cells every tick); (2) Info button + markdown help — scoped up to a milestone-sized "unified in-app help/wiki" effort, parked as backlog 999.1. | 2026-05-19 | b2ed937, e8a1be5, 43d2d3b, 2a24965, 50d464c, 10df740, 73a3bf1 | Verified | [260519-bs4-implement-a-new-table-view-in-the-compan](./quick/260519-bs4-implement-a-new-table-view-in-the-compan/) |

## Progress Bar

Expand Down
Loading
Loading