molecule-core/canvas
security-auditor c0f4c16cc9
Some checks failed
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 7s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 7s
Handlers Postgres Integration / detect-changes (pull_request) Successful in 7s
Harness Replays / detect-changes (pull_request) Successful in 8s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 2s
CI / Python Lint & Test (pull_request) Successful in 3s
CI / Platform (Go) (pull_request) Successful in 4s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 4s
Runtime PR-Built Compatibility / PR-built wheel + import smoke (pull_request) Successful in 5s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 5s
CI / Canvas (Next.js) (pull_request) Failing after 1m24s
CI / Canvas Deploy Reminder (pull_request) Has been skipped
CodeQL / Analyze (${{ matrix.language }}) (go) (pull_request) Successful in 1s
CodeQL / Analyze (${{ matrix.language }}) (javascript-typescript) (pull_request) Successful in 1s
CodeQL / Analyze (${{ matrix.language }}) (python) (pull_request) Successful in 1s
Retarget main PRs to staging / Retarget to staging (pull_request) Has been skipped
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 5s
Harness Replays / Harness Replays (pull_request) Failing after 37s
Check merge_group trigger on required workflows / Required workflows have merge_group trigger (pull_request) Successful in 5s
CI / Detect changes (pull_request) Successful in 6s
E2E API Smoke Test / detect-changes (pull_request) Successful in 7s
Lint curl status-code capture / Scan workflows for curl status-capture pollution (pull_request) Successful in 6s
Runtime PR-Built Compatibility / detect-changes (pull_request) Successful in 8s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 4m0s
feat(canvas): ActivityTab subscribes to ACTIVITY_LOGGED — drop 5s polling
Stage 3 of #61 (final stage). Replaces the 5s setInterval poll with:
  1. Initial bootstrap on mount + on filter-change + on workspaceId-
     change (preserved from existing useEffect on loadActivities).
  2. Manual Refresh button (preserved — still triggers loadActivities).
  3. useSocketEvent subscription to ACTIVITY_LOGGED — every event
     for THIS workspace prepends to the list, gated on the user's
     autoRefresh toggle and current filter selection.

No interval poll. Steady-state HTTP traffic from this tab drops from
12 req/min (5s × 1 active workspace) to 0 outside of bootstraps and
manual refreshes. Live update latency drops from up to 5s to ~10ms.

The autoRefresh ("Live" / "Paused") toggle now gates LIVE updates
instead of polling cadence — semantically the same (paused = list
stays frozen), implementationally simpler.

The filter selection is honoured by the WS handler so a user
filtering to "Tasks" doesn't see live a2a_send rows trickle in. Same
shape the server-side `?type=<filter>` enforces on the bootstrap.

Test changes:
  - 27 existing tests pass unchanged (filter / autoRefresh /
    Refresh / loading / error / empty / count / row-content all
    preserved)
  - 7 new WS-subscription tests:
      - WS push for matching workspace prepends with NO HTTP call
      - WS push for different workspace ignored
      - WS push respects active filter (non-matching ignored)
      - WS push respects active filter (matching renders)
      - WS push while autoRefresh paused ignored
      - WS push for already-in-list row deduped (no double-render)
      - NO 5s interval polling after mount

Mutation-tested:
  - drop workspace_id filter → "different workspace" test fails
  - drop autoRefresh gate → "paused" test fails
  - drop filter gate → "non-matching activity_type" test fails
  - drop dedup-by-id → "already in list deduped" test fails

Full canvas suite: 1396 passing, 0 failing. tsc clean.

No API or schema change. /workspaces/:id/activity HTTP endpoint
stays — used for bootstrap + manual refresh + filter-change reload.
ACTIVITY_LOGGED event shape unchanged.

Hostile self-review (three weakest spots):
  1. Server-side activity_logs row UPDATES (status flips, etc.) are
     not reflected post-#61 — the dedup-by-id check skips a re-fired
     ACTIVITY_LOGGED for an existing row. Acceptable: activity_logs
     is append-only by design (audit trail); status updates surface
     as new task_update rows, not as in-place mutations. If a future
     server change adds in-place updates, fire ACTIVITY_UPDATED as a
     distinct event so this dedup logic stays simple.
  2. WS handler is recreated on every render (filter / autoRefresh /
     workspaceId state changes). useSocketEvent's ref-based pattern
     keeps the bus subscription stable, but the handler closure
     re-captures each render. Side effect: fine — handler call cost
     is negligible.
  3. The "error" filter matches activity_type === "error" (mirrors
     server semantics). It does NOT match status === "error" rows
     of other activity types — same as the polling version. Worth
     re-evaluating in a separate PR if users expect the broader
     semantic.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 15:21:38 -07:00
..
e2e canvas/e2e: surface admin-orgs row + workspace body on failure 2026-05-03 14:01:50 -07:00
public chore: replace brand icon and add HANDOFF.md 2026-04-13 13:03:40 -07:00
src feat(canvas): ActivityTab subscribes to ACTIVITY_LOGGED — drop 5s polling 2026-05-07 15:21:38 -07:00
.env.example fix(canvas): close 4 gaps in WS status indicator (env, toast, tests) 2026-04-14 08:26:38 +00:00
.gitignore feat(canvas): SaaS cross-origin — slug header + cookie credentials (Phase F) 2026-04-14 20:08:39 -07:00
components.json fix(canvas): restore text-white on saturated buttons + close zinc gaps 2026-05-03 02:04:20 -07:00
Dockerfile chore(canvas): upgrade node:20-alpine → node:22-alpine 2026-04-24 18:54:30 +00:00
next.config.ts fix(canvas,dotenv): review-driven hardening of fit gate + parser parity 2026-04-24 22:23:51 -07:00
package-lock.json fix(canvas): regenerate lockfile with cross-platform optional deps 2026-05-03 01:52:42 -07:00
package.json feat(canvas): warm-paper theme + Tailwind v4 migration 2026-05-03 01:43:55 -07:00
playwright.config.ts initial commit — Molecule AI platform 2026-04-13 11:55:37 -07:00
playwright.staging.config.ts feat(e2e): canary + canvas Playwright workflows; delegation mechanics 2026-04-21 04:15:10 -07:00
postcss.config.js feat(canvas): warm-paper theme + Tailwind v4 migration 2026-05-03 01:43:55 -07:00
tsconfig.json initial commit — Molecule AI platform 2026-04-13 11:55:37 -07:00
vitest.config.ts feat(canvas): vitest coverage instrumentation (#1815, no CI gate yet) 2026-04-26 23:44:07 -07:00