Skip to content

feat(v0.4c): Socket system foundation — tag-gated socket snapping#36

Merged
longyi-xw merged 14 commits into
mainfrom
feat/v0.4c-socket-system
Jun 9, 2026
Merged

feat(v0.4c): Socket system foundation — tag-gated socket snapping#36
longyi-xw merged 14 commits into
mainfrom
feat/v0.4c-socket-system

Conversation

@longyi-xw

Copy link
Copy Markdown
Owner

What

v0.4 sub-stage C — the foundation of the Socket system for modular assembly. A node gets named local connection points (Socket {id, name, position, tag}); holding Ctrl/Cmd while dragging snaps a dragged socket onto a tag-compatible socket on another node (world positions coincide). Sockets are authored in the Properties panel, shown as viewport markers, persist with the project, and are undoable. Position-only alignment (orientation mating, rule engine, glb-embedded sockets, etc. are later stages — see roadmap Backlog).

How (TDD, per-task commits)

  • Socket schema (.optional() field — old projects load fine) + type
  • snapToSockets pure fn — tag-compatible, screen-pixel gate, world-nearest
  • setNodeSockets store mutation + SetNodeSocketsCommand (undoable, merges rapid edits)
  • Properties panel "Sockets" section (add/edit/remove)
  • Viewport: socket snap on gizmo drag + decoupled marker overlay (excluded from picking)

Key design decision (diverges from the approved spec, after visual verification)

The spec's chain was socket → B (node-align) → A (grid) unconditionally. In practice B (sub-stage #34, which snaps bbox faces) masked socket tag-gating — two boxes stuck face-to-face even with incompatible tags. Changed to: a node with any tagged socket snaps via sockets only (a miss falls through to grid A, never B), so tag compatibility truly gates whether parts connect. Nodes without sockets keep the B → A chain unchanged. (spec §6.3 has the divergence note.)

Spec: docs/superpowers/specs/2026-06-08-v0.4c-socket-system-design.md
Plan: docs/superpowers/plans/2026-06-08-v0.4c-socket-system-plan.md

Verification

  • ✅ Automated: pnpm lint (0 new) · pnpm typecheck (0) · pnpm test (469/469)
  • ✅ Visual smoke (pnpm tauri dev) — verified by maintainer:
    1. Properties "Sockets": add/edit name·x·y·z·tag/remove, undoable
    2. Markers visible (selected node highlighted), don't block picking
    3. Same-tag sockets on two boxes → Ctrl/Cmd drag → snap together at sockets; markers follow during drag
    4. Different tag → no snap (grid only) — tag gate visible
    5. Save → reopen → sockets persist; old project (no sockets field) loads fine

Includes 3 fixes found during smoke: tag input collapsed to 0-width; sockets dropped on save; markers froze mid-snap.

🤖 Generated with Claude Code

longyi-xw and others added 14 commits June 8, 2026 22:30
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…during snap)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The on-disk node body enumerated fields and omitted sockets; because the
schema field is .optional() the omission type-checked silently, so sockets
were lost on every save/reopen. Add sockets to the body + round-trip test.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…de-align)

A node with any tagged socket opts into socket-based assembly: it no longer
falls back to sub-stage B's whole-bbox face snap, so tag compatibility
actually gates whether two parts connect (incompatible tags no longer stick
via B). Nodes without sockets keep the B→A chain unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@longyi-xw longyi-xw merged commit 125adcf into main Jun 9, 2026
1 check passed
@longyi-xw longyi-xw deleted the feat/v0.4c-socket-system branch June 9, 2026 07:13
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.

1 participant