Add 10 tests for StatusDot covering:
- All known STATUS_CONFIG statuses (online, offline, degraded,
failed, paused, not_configured, provisioning)
- Correct color class applied per status
- Glow class applied when declared in STATUS_CONFIG
- motion-safe:animate-pulse on provisioning status
- Fallback to bg-zinc-500 for unknown status
- size prop (sm/md) applies correct Tailwind dimension class
- aria-hidden="true" for accessibility tree isolation
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Pre-commit Hook: moved stray "Action:" line inside the section (was appended to
WCAG entry below it after a rebase conflict resolution)
- Removed duplicate text-ink-soft WCAG AA entry (lines 62-68 were a rebase artifact)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Controls: all three buttons (zoom in/out/fit) have aria-label attributes from
React Flow; verified from @xyflow/react source (index.mjs:4453). Removed "verify
if keyboard accessible" caveat.
- MiniMap: actually present in Canvas.tsx (rendered at line 310). The old audit
note "not present (mocked as null in tests)" referred to the minimap being absent
from unit test renders, not from production. Updated to reflect actual presence
and status-coloring behavior.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Fix arrow-key nudge description: was "20px/100px" (wrong), now "10px/50px" (matches useKeyboardShortcuts)
- Add Cmd/Ctrl+Arrow resize shortcut row to dialog (missing since PR #192)
- Fix 3 tests in useKeyboardShortcuts.test.tsx that asserted shrink below min dimensions:
"resizes height down" expected height:100, clamped to 110 (node starts at minHeight)
"resizes width down" expected width:200, clamped to 210 (node starts at minWidth)
"2px step with Shift" expected height:108, clamped to 110 (minHeight wins)
All three tests updated to assert clamped values with explanatory comments.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Pins all FROM image tags to exact SHA256 digests for reproducible
builds. Without digest pinning, a registry push of a new image to the
same tag can silently change the layer content between builds — a
supply-chain risk especially for prod-deployed images.
Pinned images (7 Dockerfiles):
- golang:1.25-alpine → sha256:c4ea15b... (workspace-server/Dockerfile,
Dockerfile.dev, Dockerfile.tenant, tests/harness/cp-stub/Dockerfile)
- alpine:3.20 → sha256:c64c687c... (workspace-server/Dockerfile,
tests/harness/cp-stub/Dockerfile)
- node:20-alpine → sha256:afdf982... (workspace-server/Dockerfile.tenant)
- node:22-alpine → sha256:cb15fca... (canvas/Dockerfile)
- python:3.11-slim → sha256:e78299e... (workspace/Dockerfile)
- nginx:1.27-alpine → sha256:62223d6... (tests/harness/cf-proxy/Dockerfile)
Note: docker-compose.yml service images (postgres, redis, clickhouse,
litellm, ollama) are intentionally left on major-version tags — those
are runtime-pulled and updated regularly for local-dev ergonomics.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Add 10 tests covering the Cmd/Ctrl+Arrow resize shortcut:
- ArrowUp/Down resizes height (−/+10px)
- ArrowLeft/Right resizes width (−/+10px)
- Shift modifier uses 2px step for fine control
- min-height constraint respected when shrinking
- Guard: no-op when no node selected
- Guard: skipped when modal dialog is open
- Plain arrow keys (no modifier) fire moveNode instead
- Alt+Arrow is skipped (not a resize combo)
Also extends the mock store state with `onNodesChange` and node
`width`/`height` fields needed for the resize tests.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Race-detector CI runs (-race) slow goroutines enough that a
prior sweeper goroutine (e.g. TestStartSweeper_TransientErrorDoesNotCrashLoop)
can still be running and incrementing pendingUploadsSweepErrors after
metricDelta() captures its baseline, but before the success-path sweeper
records its success metrics. The test then reads deltaError=1 instead of 0.
Fix: add waitForMetricDelta(t, deltaError, 0, 2*time.Second) before the
assertion, matching the polling pattern already used in the error-path
test (TestStartSweeper_RecordsMetricsOnError). This ensures the error
counter has settled before we assert on it.
Fixes molecule-core#22.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Replace all text-ink-soft usages across canvas components and app pages.
ink-soft (#8d92a0) on dark zinc (#0e1014) yields ~2.2:1 contrast,
failing WCAG 2.1 AA minimum of 4.5:1 for normal text.
ink-mid (#c8c2b4) on dark zinc yields ~7.6:1 — well above AA.
text-ink-mid is already the semantic token for secondary/caption text
in the warm-paper light mode; the dark-mode override was the gap.
52 files, 268 replacements. No functional change beyond contrast.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Canvas runs Next.js 15.5.15 (package-lock.json). Audit doc had
Next.js 14 App Router from before the upgrade. Also add
KeyboardShortcutsDialog.tsx to the directory structure tree.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Cmd/Ctrl+Arrow Up/Down resizes node height (±10px, ±2px with Shift).
Cmd/Ctrl+Arrow Left/Right resizes node width (±10px, ±2px with Shift).
Uses the same onNodesChange('dimensions') path that NodeResizer uses
— no new store action needed. Respects min-width/min-height matching
the NodeResizer constraints (360×200 with children, 210×110 without).
The Arrow-key move shortcut now skips when a modifier key is held,
so Cmd/Ctrl+Arrow unambiguously means resize (not move).
Updates canvas audit doc: Node Rendering section updated and
the LOW node-resize item marked done. All Remaining Gaps items
are now complete.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Issue #75 PR-D: two remaining `gh` CLI calls in .github/workflows/.
1. ci.yml canvas-deploy-reminder:
- Replaced `gh api POST repos/.../commits/.../comments` with writing
to GITHUB_STEP_SUMMARY. Gitea has no commit-comments API (confirmed
in issue #75), so the gh call always failed. GITHUB_STEP_SUMMARY works
on both GitHub Actions and Gitea Actions as the workflow-run summary
page, which is the natural place for post-deploy action items.
- Removed now-unnecessary GH_TOKEN env var and contents:write permission.
2. check-merge-group-trigger.yml:
- Converted to no-op stub. Gitea has no merge queue feature and no
merge_group: event type, so this workflow's lint would find nothing
to verify (all workflows vacuously pass). Keeping workflow+job name
unchanged preserves commit-status context names for branch protection
consumers. Dropped the merge_group: trigger since it would never fire
on Gitea. Dropped the full bash linter + gh api call.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>