Commit Graph
9 Commits
Author SHA1 Message Date
jennyf19andCopilot 670c5f0419 Address GHCP review: stash race, signal ordering, a11y, outcome schema, error handling
- extension.mjs: serialize stash read-modify-write behind a per-desk mutex;
  order signals by explicit ISO timestamp (clone-safe) not mtime; keep desks
  with malformed latest signal as 'awaiting'; gate calibration badge on a real
  gap value; add prefers-reduced-motion CSS; toast aria-live region; rename
  open_desk -> get_desk_path (returns path, no session); handle server.listen errors.
- signal-write/SKILL.md: document timestamp + run_id, ordering guidance, and the
  outcome (calibration) signal schema.
- workshop-ta.agent.md: a desk is a persistent workstream picked up by independent
  sessions, not one long-running process.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 26faf13e-639c-4a21-ac05-c0dc2bff7c62
2026-07-19 19:24:09 -07:00
jennyf19andCopilot 47ad74c5bd signal-write: drop false 'bundled with plugin' note
The signals-dashboard canvas is a standalone extension, not bundled in
the-workshop plugin. Removes the same inaccurate 'bundled' phrasing the
README fix corrected, keeping the subtype guidance intact.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 26faf13e-639c-4a21-ac05-c0dc2bff7c62
2026-07-19 18:49:05 -07:00
jennyf19andCopilot cb15ebdefd the-workshop: fix Cairn dashboard install docs
The dashboard is a canvas extension that ships standalone, not bundled
in the plugin. Installing the-workshop delivers skills/agent/desks only;
the signals-dashboard canvas installs separately and renders in the
GitHub Copilot app. Replaces the false 'bundled... nothing else to
install' claim with the real two-install path.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 26faf13e-639c-4a21-ac05-c0dc2bff7c62
2026-07-19 18:45:51 -07:00
jennyf19andCopilot d71864b706 fix(signals-dashboard): declare @github/copilot-sdk dependency
signals-dashboard imports '@github/copilot-sdk/extension' but shipped
without a package.json — the only SDK-importing extension in the repo
missing one (every peer that imports the SDK declares it). Without the
manifest the host has no dependency to resolve at load time. Add a
package.json matching the peer shape (type: module, main: extension.mjs,
'@github/copilot-sdk': latest — the modal peer convention).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 26faf13e-639c-4a21-ac05-c0dc2bff7c62
2026-07-19 18:19:22 -07:00
jennyf19andCopilot fcae8c506d fix(the-workshop): add HTTP error boundary and make workshop detection non-terminal
Two follow-up review findings:
- signals-dashboard: the async createServer callback had no top-level
  error boundary, so a malformed %-encoded path, a stash write on a
  read-only workshop, or a scan failure rejected a promise the server
  never awaits — hanging the request and risking an unhandled-rejection
  crash. Wrap the handler and return a controlled 500.
- workshop-create: Path A treated finding a marker (desks/, CAIRN.md,
  etc.) as 'just use it', an early stop that left partially initialized
  workshops incomplete. Make it detection-only and continue scaffolding
  whatever is missing, per the 'only add what's missing' principle.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 26faf13e-639c-4a21-ac05-c0dc2bff7c62
2026-07-18 19:58:49 -07:00
jennyf19andCopilot fa1f154155 docs(the-workshop): fix workshop scaffold, bench location, and component list
Address the remaining doc/skill review findings:
- workshop-create: 'gh repo create --clone' clones into the CWD, which
  nests the new repo when run from inside a checkout. Add an explicit
  clone-parent selection + 'rev-parse --is-inside-work-tree' guard, and
  run the create from that parent.
- workshop-create: desks/ and bench/ were scaffolded empty, so Git drops
  them and a later clone loses the scaffold. Scaffold .gitkeep in each
  and commit the placeholders.
- bench-read: make <workshop>/bench/ the primary shared location (the
  directory workshop-create actually establishes) with desk-local
  artifacts as a secondary source, instead of treating the repo root as
  the bench.
- the-workshop README: add the Workshop Create skill to the component
  table so all six packaged components are documented.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 26faf13e-639c-4a21-ac05-c0dc2bff7c62
2026-07-18 19:56:18 -07:00
jennyf19andCopilot f9061f6fcc fix(signals-dashboard): coerce untrusted signal fields, block cross-site POSTs, preserve focus
Second review round on the Cairn canvas extension:
- XSS via numeric fields: self-assessment scores, quality rating, and
  token counts are read from unvalidated agent JSON and interpolated
  into HTML/style/title. Coerce them at the source in scanSignals via
  toScore (clamped 0..5) and toCount (finite nonnegative int), and
  esc() the effort label, so a nonnumeric value can neither inject
  markup nor break layout/width.
- CSRF: /api/stash, /api/restore, /api/open are state-changing loopback
  POSTs that previously accepted any origin, so a web page that guessed
  the port could mutate .desk-stash.json. Add isCrossSiteRequest() and
  reject cross-site POST /api/* (Origin / Sec-Fetch-Site check), mirroring
  the loopback protection in connector-namespaces/server.mjs.
- Accessibility: the 5s auto-refresh replaced the whole #content subtree,
  dropping keyboard focus. Skip the swap when markup is unchanged and
  restore focus to the same desk/action button when it does change.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 26faf13e-639c-4a21-ac05-c0dc2bff7c62
2026-07-18 19:50:58 -07:00
jennyf19andCopilot 967f0d8ede fix(signals-dashboard): harden canvas against XSS, path traversal, and malformed signals
Address PR review findings on the Cairn canvas extension:
- XSS: replace inline onclick handlers (which used HTML-escape that
  does not escape single quotes) with event delegation via
  data-act/data-desk attributes and one document click listener that
  survives the innerHTML auto-refresh.
- Path traversal: add isValidDeskName() and enforce it in every HTTP
  and canvas-action handler that takes a desk name (reject empty, /,
  \\, null byte, '.' and '..').
- Crash safety: String()-coerce in esc()/truncate() and guard
  outcomeIssues with Array.isArray so a malformed signal cannot take
  down the whole dashboard render.
- Honest UI: the per-desk button no longer claims to 'open' a desk;
  it is relabeled 'path' and copies the desk's filesystem path to the
  clipboard with an accurate toast built via textContent (not innerHTML).
- Correctness: outcome signals only pair with a signal when emitted at
  or after it (within 1hr), and activeCount is computed by excluding
  stashed desks instead of subtracting counts (no longer goes negative).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 26faf13e-639c-4a21-ac05-c0dc2bff7c62
2026-07-18 19:44:45 -07:00
jennyf19andCopilot c33470a0b4 docs(the-workshop): install dashboard via awesome-copilot, not jennyf19 repo
The signals-dashboard canvas extension bundles with the-workshop
plugin (x-awesome-copilot.extensions), so installing the plugin from
awesome-copilot includes the dashboard. Drop the pointers telling
users to install from jennyf19/the-workshop.

Addresses PR review comments on README (Cairn Dashboard section),
signal-write SKILL note, and workshop-ta agent viewing-signals note.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 26faf13e-639c-4a21-ac05-c0dc2bff7c62
2026-07-18 19:36:20 -07:00