Skip to content

feat(studio): tunnel Intent Form to in-process 3D pulse (C1) - #18

Merged
ZuluYokohama merged 4 commits into
masterfrom
feat/intent-pulse-tunnel
Jun 6, 2026
Merged

ZuluYokohama merged 4 commits into
masterfrom
feat/intent-pulse-tunnel

Conversation

@ZuluYokohama

@ZuluYokohama ZuluYokohama commented Jun 6, 2026 •

Copy link
Copy Markdown
Collaborator

C1: Tunnel Intent Form submissions to an in-process 3D pulse

Branch-target note: This fork has no dev branch and does not use main; default/active branch is master. This is an internal fork PR, not an upstream contribution, so it targets master.

Who is submitting this PR? (required)

Field Value
Your model + version Orchestration: Claude Opus 4.8 (claude-opus-4-8, 1M context). Implementation/review subagents: dispatched at the opus tier; the harness does not surface the exact minor version and the tier selector cannot pin 4.7, so workers most likely ran on the session default Opus 4.8, not 4.7. Disclosed honestly.
Harness + version Claude Code (CLI). Exact build/version not surfaced to the agent.
All plugins installed superpowers 5.1.0, plugin-dev, context7 (MCP). MCP servers: claude.ai Gmail / Google Calendar / Google Drive / Hugging Face.
Human partner who reviewed this diff b.jones@jtech.ai (ZuluYokohama)

What problem are you trying to solve?

The Feature Studio's Intent Form (ui/studio/src/app/ClientViews.tsx) responded to a submission by calling window.location.reload() — a full-page reload "for MVP". That destroys all client state, tears down and re-initializes the persistent React-Three-Fiber <Canvas> (causing WebGL context churn and a visible flash), and means a user "injecting an intent" gets a jarring reload instead of feedback in the 3D scene. The R3F implementation plan's Phase 1 Step 3 ("event tunnel / global state manager so DOM inputs trigger 3D animations") was the unchecked task addressing this.

What does this PR change?

Replaces the full-page reload with an in-process "intent pulse": a tiny framework-agnostic external store (src/lib/intentPulseStore.ts) plus a useSyncExternalStore hook (src/lib/useIntentPulse.ts). The Intent Form emits a pulse on submit; MatrixScene reacts by "popping" (scaling) the central core. Adds Vitest infrastructure and unit tests for the store. No new runtime dependencies (the store is hand-rolled, not zustand).

Is this change appropriate for the core library?

No. This is fork-specific UI behavior for the RotarySlider Feature Studio, not a general-purpose Superpowers skill. Internal fork PR only.

What alternatives did you consider?

  • zustand (already present transitively via drei/fiber) as the store — rejected: adding it as a direct runtime dependency is unnecessary weight for a single pulse value; React's built-in useSyncExternalStore over a 40-line pure store does the job with zero new deps and is trivially unit-testable in plain node.
  • React Context provider wrapping the app — rejected: the DOM form and the R3F scene live on opposite sides of the <Canvas> boundary; a module-level external store crosses that boundary without prop-drilling or nesting providers, and keeps the emit path callable from a plain event handler.
  • tunnel-rat / drei <View> (named in the plan as options) — rejected: those tunnel rendered DOM into 3D space, which is a different concern (already used for telemetry); here we need a state/event signal, not portalled markup.

Does this PR contain multiple unrelated changes?

No. Every file serves one goal: route an Intent Form submission to a 3D reaction. The Vitest config + tests exist to verify the store that does it.

Existing PRs

Environment tested

Harness Harness version Model Model version/ID
Claude Code (CLI) not surfaced to agent Claude Opus 4.8 orchestration; opus-tier subagents
  • npm test → 5/5 passing (intentPulseStore.test.ts): starts-empty, monotonic id + exact shape, subscribe/unsubscribe, snapshot reference stability, multiple independent subscribers.
  • npm run build → Compiled successfully (Next 14.2.35, 4/4 static pages).
  • npx tsc --noEmit → exit 0.
  • TDD followed: the store test was written first and observed failing (Failed to load url ../intentPulseStore) before the store was implemented.
  • Host: Windows 11 ARM64, node v22. The visual "pop" is not browser-verified (headless); the pulse logic is covered by unit tests + typecheck.

New harness support (required if this PR adds a new harness)

N/A — no new harness.

Evaluation

N/A for skill evals — this is an application feature, not a behavior-shaping skill. Functional evaluation: red→green TDD on the store (failing test → implementation → 5 passing), then two independent reviewer passes — a spec-compliance review (re-ran the suite, confirmed window.location.reload is gone and VisualGallery is byte-identical, confirmed no new runtime deps) and a code-quality review (verified useSyncExternalStore snapshot/subscribe semantics, flagged a frameloop="demand" robustness gap which was then hardened with invalidate()).

Rigor

  • Skills change — N/A (no skill content modified).
  • Tested adversarially — reviewers re-derived correctness from the code (snapshot reference stability, unsubscribe semantics, first-pulse off-by-one all checked), not from the implementer's report.
  • Did not modify behavior-shaping content.

Human review

  • A human has reviewed the COMPLETE proposed diff before submission.

Summary by CodeRabbit

  • New Features

    • Form submissions now clear and refresh related lists without a full page reload.
    • Submissions trigger a visible "pop" animation in the scene for immediate feedback.
  • Tests

    • Added a comprehensive test suite covering the intent pulse/tracking system.
  • Chores

    • Configured local test setup and added test/run scripts; added a start script for the studio.

RogueGringo and others added 3 commits June 6, 2026 00:20
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… tests

- invalidate() while kick decays so the pop survives a frameloop='demand' switch
- document the client-side-singleton/SSR assumption
- test snapshot reference stability (the useSyncExternalStore invariant)
- test multiple independent subscribers
@coderabbitai

coderabbitai Bot commented Jun 6, 2026 •

Copy link
Copy Markdown

Wondering what really moved? Review this PR in Change Stack to inspect semantic changes, definitions, and references.

Review Change Stack

📝 Walkthrough

Walkthrough

Adds an in-memory intent pulse store and types, a client hook, Vitest test setup and tests, package scripts/devDependency for Vitest, replaces full-page reload with intent emission + router.refresh on form submit, and drives MatrixScene pop animation from emitted pulses.

Changes

Intent Pulse System

Layer / File(s) Summary
Intent Pulse Store Contract and Core Implementation
ui/studio/src/lib/intentPulseStore.ts, ui/studio/src/lib/useIntentPulse.ts
Defines IntentPulse and PulseListener, implements a singleton in-memory store with emitIntentPulse, getIntentPulse, subscribeIntentPulse, adds __resetIntentPulseStore (test-only), and exports useIntentPulse using useSyncExternalStore.
Test Infrastructure and Store Tests
ui/studio/vitest.config.ts, ui/studio/package.json, ui/studio/src/lib/__tests__/intentPulseStore.test.ts
Adds ui/studio/vitest.config.ts (Node env, include src/lib/**/*.test.ts), updates package.json scripts (start, test, test:watch) and adds vitest devDependency ^1.6.0, and provides tests covering store behavior and subscriber lifecycle.
Form Submission Intent Emission
ui/studio/src/app/ClientViews.tsx
Imports emitIntentPulse and useRouter into IntentForm, clears form state, calls emitIntentPulse(name, metric, Date.now()), then router.refresh() instead of window.location.reload().
MatrixScene Animation Driven by Pulses
ui/studio/src/components/MatrixScene.tsx
Integrates useIntentPulse to detect new pulse IDs in the useFrame loop, sets a decaying kick scalar to scale the core mesh and calls state.invalidate() while the kick is active to create a pop effect.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I sent a tiny pulse, a twitch, a cheer,
The scene did pop — no reload near,
A hop, a kick, the core grew bright,
Signals hum through code at night,
I nibble bugs and guard the light.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 14.29% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: implementing an intent pulse mechanism to connect the Intent Form to a 3D animation in the MatrixScene, replacing full-page reloads with in-process updates.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/intent-pulse-tunnel

Comment @coderabbitai help to get the list of available commands and usage tips.

Restores the Active Intent Vectors list update that the old
window.location.reload() provided, via router.refresh() — a soft
App Router refresh that re-runs the /status server fetch while
preserving the persistent WebGL Canvas. Completes the end-to-end
intent loop alongside the in-process 3D pulse.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
ui/studio/src/app/ClientViews.tsx (1)

12-23: ⚠️ Potential issue | 🟠 Major

Guard post-submit actions behind HTTP success.

In ui/studio/src/app/ClientViews.tsx (lines 12–22), await fetch(...) is not checked for HTTP failure (no response.ok / status handling). The code then unconditionally clears inputs (setName, setMetric), emits emitIntentPulse, and calls router.refresh(), which can reflect a successful “pop” even when the POST returns 4xx/5xx—gate those actions on a successful HTTP response before updating UI/state.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ui/studio/src/app/ClientViews.tsx` around lines 12 - 23, In the submit
handler (function submit) ensure you inspect the fetch response before
proceeding: capture the result of await fetch('/intent', ...) into a variable,
check response.ok (or status) and only then call setName(''), setMetric(''),
emitIntentPulse(name, metric, Date.now()) and router.refresh(); on non-ok
responses handle the error path (log or set an error state and avoid clearing
inputs/emitting/refreshing) and optionally await response.json() to surface
server error details; keep the request method/headers/body as-is but gate all
post-submit side effects on a successful HTTP response.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@ui/studio/src/app/ClientViews.tsx`:
- Around line 12-23: In the submit handler (function submit) ensure you inspect
the fetch response before proceeding: capture the result of await
fetch('/intent', ...) into a variable, check response.ok (or status) and only
then call setName(''), setMetric(''), emitIntentPulse(name, metric, Date.now())
and router.refresh(); on non-ok responses handle the error path (log or set an
error state and avoid clearing inputs/emitting/refreshing) and optionally await
response.json() to surface server error details; keep the request
method/headers/body as-is but gate all post-submit side effects on a successful
HTTP response.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 17ea6026-4c4e-48e3-b6fb-c528da0b9635

📥 Commits

Reviewing files that changed from the base of the PR and between 489cb62 and df2a604.

📒 Files selected for processing (1)
  • ui/studio/src/app/ClientViews.tsx

@ZuluYokohama
ZuluYokohama merged commit 6333874 into master Jun 6, 2026
1 of 2 checks passed
@ZuluYokohama
ZuluYokohama deleted the feat/intent-pulse-tunnel branch June 6, 2026 06:14
ZuluYokohama added a commit that referenced this pull request Jun 6, 2026
Check Phase 1.3/2.3/2.4 (C1 #18 / C2 #20 / C3 #21), correct the canvas/ path drift, uncheck Phase 4.1-4.3 (DOM components, not the 3D meshes described), record the C4 (#17) prerequisite. CodeRabbit: approved.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants