Resolves the remaining Copilot review comments.
Canvas extension (board-core.mjs, board.html):
- DNS-rebinding: pin the Host header to the exact 127.0.0.1:<port> authority and
require a per-server capability token (minted at startup, embedded in the served
page, sent as x-board-token) on ALL /api/* routes -- so GET /api/state can't leak
task data and POSTs can't be forged. Mirrors extensions/signals-dashboard.
- Destructive write: loadDoc only synthesizes a fresh board for ENOENT and now
propagates I/O + JSON parse errors, so a transient/malformed state file is never
overwritten by a later mutation.
- XSS: escape emoji (from the seed / add_task action) at render, like title/unit.
Skill (board.template.html, sample-board.html):
- a11y: each task card gets role=group + aria-label so screen readers get task context.
- counters: step=1 on the goal/update number inputs to match the positive-integer contract.
Verified headless (35/35): token gates reads+writes, CSRF + foreign-Host refused,
malformed file left intact. Repo plugin + skill validation green.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: cb356aa8-0af2-48f3-b3c6-8086c69d5308
Add action-oriented aria-labels to the suggest-mantra, focus, remove, add-note, park-thought,
and log-win buttons so screen readers announce the action instead of the emoji (template + sample).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 07e720ee-ca02-419e-9adb-300738b6fc76
Add a task-specific aria-label to the quadrant <select> and the editable label input so
screen-reader users know which task the control belongs to (template + regenerated sample).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 07e720ee-ca02-419e-9adb-300738b6fc76
- Validate task ids (^[A-Za-z0-9_-]+$) and dedupe before interpolating into data-* attributes,
so a malformed configured/persisted id can't break out of an attribute (template + sample).
- Seeded counters (current value >0 and below goal) now render as 'in progress', not 'to do'.
- Hide the 'not today' carryover control on done tasks; it was flipping a completed task to
carried and dropping it from the recap's Done tally.
- #eodmsg is now role=status aria-live=polite so screen-reader users hear save/copy results.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 07e720ee-ca02-419e-9adb-300738b6fc76
- Sanitize tagc to [A-Za-z0-9_-] before class-attribute interpolation, so a custom
class name cannot break out of the attribute and inject markup/handlers (template + sample).
- customize.md now points at .tagedit.<name> (the class the renderer actually applies).
- serve-board.ps1: fail when the port is already in use, capture and report the server PID
(with a stop command), and verify the process did not exit before opening the URL.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 07e720ee-ca02-419e-9adb-300738b6fc76
Executive-function-friendly daily focus board (self-contained HTML) you run by
talking to Ember. Registers it in the ember plugin (1.1.0) and regenerates the
skills index + marketplace.json.
Review fixes: emoji XSS escaping; keyboard a11y (semantic buttons + aria, plus
up/down move controls); tagc label colors; local-date storage key + recap
date/filename; guarded execCommand and localStorage; confetti animates only
while active and stops on reduce-motion; loopback serve bind + quoted dir;
JSON config injection with '<' escaped; minute rounding; reorder-to-end; clear
stale focus; counter goal guard; and doc corrections (id charset, sample
reference, counter contract, option-b, frontmatter length).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 07e720ee-ca02-419e-9adb-300738b6fc76