Skip to content

[Epic] @maic SDK family: from in-app implementations to package consumers #720

Description

@wyuc

Goal

Evolve the app (and downstream consumers) from "ships its own slide stack" to a
standard consumer of the @maic/{dsl, renderer, importer, exporter} package
family. End state: the app keeps only business glue (media-store resolution,
lazy placeholders, app chrome); every contract, renderer, importer and exporter
lives in a package with a published boundary.

Dependency rule (established in #668, kept acyclic):
@maic/dsl → nothing; renderer / importer / exporter@maic/dsl only.

Where we are (done)

Phase 1 — Cleanup & consolidation (low risk, immediately actionable)

  • Delete dead legacy ThumbnailSlide/ + ThumbnailElement (zero imports
    after refactor(app): consume @maic/dsl + @maic/renderer in the app (slide types + read-only thumbnails) #707, ~217 LOC)
  • Repoint ~90 @/lib/types/slides import sites directly at @maic/dsl,
    then delete the shim
  • Fix @maic/dsl build: extensionless re-exports in dist/index.js break
    bare-node ESM resolution (emit .js extensions)
  • Publish @maic/dsl, @maic/renderer, @maic/importer to npm
    (publishConfig is already in place) — unlocks all out-of-workspace
    consumers

Phase 2 — Grow the DSL (needs contract design)

  • Promote the pure Stage / Scene / SceneContent types from
    lib/types/stage.ts into @maic/dsl (blocker: they currently couple to
    Action / Widget / generation types — split the pure parts first; already
    on the dsl README roadmap)
  • Bring the Action DSL (lib/types/action.ts) into the contract
    (@maic/dsl or a sibling package)
  • Add the JSON Schema + pure validators for the slide contract (serves
    non-TS consumers)
  • Activate DSL_VERSION + the migration registry

Phase 3 — renderer v2: the editing surface (largest item, critical path)

  • @maic/renderer v2: selection, drag/resize/rotate, operate handles,
    ProseMirror inline editing (v1 is read-only by design)
  • Absorb the app's components/slide-renderer/Editor/ (~38 files) and the
    full-size components/element/ renderers (~41 files) — the last big
    duplicated implementation in the app
  • After absorption, components/slide-renderer/ keeps only business glue
    (SlideThumbnail-style wrappers, ThumbnailInteractive)

Phase 4 — exporter & closing the family (parallel to Phase 3)

  • Create @maic/exporter (the reserved 4th member): extract PPTX / HTML /
    offline-ZIP export from lib/export
  • Switch the app's export paths to consume it; retire the
    sync-maic-importer.mjs vendor step in favor of normal package deps

Phase 5 — ecosystem consumers (unlocked by Phase 1 publish)

  • External editors/apps adopt @maic/dsl instead of vendored slide-type
    copies, @maic/importer for pptx import, and (where read-only suffices)
    @maic/renderer for display — peer requirements: React ≥18, Tailwind 4

Principles

  • Business glue (media-generation store resolution, lazy placeholders, app
    badges) stays in the consumer, never in the packages.
  • Migrate incrementally: shim/wrapper first, batch-switch imports, delete the
    legacy code last (the slides shim is the precedent).
  • @maic/dsl never gains a runtime dependency; cross-package enums stay
    regular enums.

Risks

  • renderer v2's editing surface is the bulk of the remaining work and gates
    Phase 3; worth starting design early.
  • The Stage/Action type split needs contract review before Phase 2 lands.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions