Socket rows now scope their optional template to their OWN slot only
(top-to-bottom resolution; other $input_M stay literal). Adds a durable
general-template row (kind: "general") that survives socket churn, is
resolved after all socket rows, and composes from both raw sockets
($input_N) and socket-row bindings ($test). Engine processes socket rows
first then general rows in order; general rows honor binding validation +
the internal flag. Frontend: kind discriminator, "Add template row"
affordance, general-aware reconcile that keeps general rows, inline
binding+template editor with a refs hint, conflict-scanner + docs updates.
Full UX rework of WP_ContextInjector to match the Context node's design
language. Adds per-row right-click context menu, collapse/expand of the
row's summary, and a per-row edit modal for setting both the variable
binding and an optional template string with $slot_name substitution
at engine time.
Frontend:
- InjectorRow gains a caret toggle + summary line under the row header;
flex-column root with .wp-inj-row-header wrapping the existing flex
row so summary can render below without breaking the existing layout.
- Right-click ctxmenu (Edit / Disable / Expand-Collapse / Move-to-top /
Move-to-bottom / Disconnect) reuses the shared ContextMenu component.
Header reads "Type · $var".
- NEW InjectorBindingModal.vue — per-row edit panel with binding name
field + optional template textarea + insert-slot dropdown ($own_slot
only, no cross-row noise). Draft buffer + Esc/Cmd+Enter keybinds
matching the module InstanceModal family. Tokenizer fixes a TDZ-
shaped infinite loop on bare `$` typed before a name.
- Lifted drop-indicator + drag tracking to InjectorWidget at list
level so the gap-opening margin doesn't oscillate the target under
the pointer. Drop bar paints via ::before/::after pseudo-elements
+ 14px margin gap so the slot opens visibly. Animation parity with
module rows (FLIP via shared flip.ts; drop-pulse via shared
row-primitives.css keyframes).
- Slot tag + collapse-button + summary moved into shared
row-primitives.css; ModuleRow & ContextWidget refactored to consume
the partial. Modules' right-click and bundle headers now also use a
type-icon + kind chip + title header on their ctxmenu (matches the
bundle pattern; was previously bundle-only).
- New conflict label helper `shortConflictLabel` in extension/conflicts
so injector + module rows surface identical compact wording for the
same conflict types.
- New `--wp-kind-injector` theme token + chip variant for Debug's
injector trace rows (added in the next commit).
- ContextMenu close-on-outside-click switched to pointerdown capture
so descendant `@click.stop` handlers can't swallow the close.
- _shared.ts widget host: track lastAutoSetHeight alongside
lastAutoSetWidth so each axis preserves user-resized values
independently. fillHost widgets always preserve height (no
ResizeObserver to bootstrap the delta-check).
Engine:
- wp_nodes/injector_node.py: per-row optional `template` field. When
set, engine substitutes `$<slot_name>` refs with the wired socket
value (Python str() — booleans render as "True"/"False" matching
the pass-through path's downstream stringification). Pass-through
unchanged when template is empty. Trace entries carry `value` so
Debug's value cell isn't blank for injector rows.