[FEATURE] Neutral Plugins #5

Merged
dunemask merged 2 commits from ep/May13-2026/FrameworkNeutralRuntime into main 2026-05-14 16:26:34 +00:00
Owner
No description provided.
Split `@lion-turtle/vite` into framework-agnostic core + per-framework
adapters so Vue/Svelte/vanilla apps can use lion-turtle without shipping
React. Move DevShell out of consumer bundle entirely — plugin-served
page at `/`, app runs in iframe at `/?_embed=1`.

Subpath exports:
  - /core   bridge, store, sync, env, splash, log-pipe, devshell-control,
            subscribeBridge/Store/Env, types. No framework deps.
  - /react  useBridge/useStore/useSync/useEnv + ShellProvider.
  - /vue    Vue 3 composables (Ref-based).
  - /svelte Svelte 4/5 stores (Readable-based).
  - /runtime kept as a back-compat alias of /core.

DevShell extensions use a framework-neutral mount-fn shape — each panel
and topbar slot is a micro-app:

    defineDevPanel({ id, label, icon: "Clock", mount(container, ctx) {...} })

Consumer wires modules via plugin config:

    lionTurtle({
      devShell: {
        panels: "./src/dev/panels.ts",
        topbarSlots: "./src/dev/topbar.ts",
        bridgeHandlers: "./src/dev/handlers.ts",
        parentSetup: "./src/dev/setup.ts",
      },
    })

Plugin emits `virtual:lion-turtle/devshell-extensions` re-exporting the
modules; DevShell entry imports + threads them as props. Migration
notes for the old consumer-mounted `<DevShell panels={...} />` pattern
in `docs/extension-api.md`.

Verified:
  - workspace tsc clean across all 6 packages
  - prod build: 210kB JS bundle, 0 DevShell artifacts, 4kB CSS (was 30kB)
  - dev curl: `/` and `/?_embed=1` branch correctly, virtual extensions
    module resolves with undefined defaults when no config provided.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Review feedback from independent pass.

- transformIndexHtml previously stripped *every* `<script type="module"
  src=...>` from the parent page, including PWA-injected service-worker
  registration scripts and anything sibling plugins added. Now reads the
  raw `index.html` on `configResolved` and remembers the exact entry
  `src` values; only those get stripped on `/`. Other module scripts
  pass through untouched. Regex tolerates arbitrary attribute order.

- Drop StrictMode from devshell-app/main.tsx. The mount-fn panel
  contract is not required to tolerate double-invoke (React `createRoot`
  warns; Vue/Svelte mounts leak the first instance). DevShell never
  ships to prod so StrictMode's prod-safety value doesn't apply.

- `bridge.on` unsubscribe now looks up the subscriber Set by `type`
  every cleanup, instead of closing over the original Set ref — which
  could become a dead container if the type was deleted-when-empty +
  re-created.

- Proper `.d.ts` shim for `virtual:lion-turtle/devshell-extensions`
  (drops the `@ts-expect-error`).

- `parentSetup` / panels / topbarSlots / bridgeHandlers paths emitted
  via `/@fs/<abs>` URLs instead of raw absolute paths — survives
  cross-platform path encoding edge cases.

- `isEmbedRequest` uses URLSearchParams instead of manual split.

- Doc clarification: lucide icon names are lucide-react export names
  (PascalCase, e.g. "MoreHorizontal"). Auto-capitalize is a convenience
  for single-word names only.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
dunemask referenced this pull request from a commit 2026-05-14 16:26:34 +00:00
dunemask deleted branch ep/May13-2026/FrameworkNeutralRuntime 2026-05-14 16:26:38 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
dunemask/lion-turtle!5
No description provided.