chore(packages): publish the @openmaic/* SDK family to npm (#778) (#780)

* chore(packages): publish the @openmaic/* SDK family to npm (#778)

Prepares the @openmaic/{dsl,renderer,importer} family for its first npm
publish, and moves the SDK packages onto the @openmaic scope.

Why the scope move: the @maic org name is unavailable on npm (an unscoped
`maic` package already holds the name), so @maic/* is not claimable. @openmaic
matches the project name, the scope is free, and the repo already ships an
@openmaic/docs package — so the SDK family now lines up with that convention.

- rename @maic/{dsl,renderer,importer} -> @openmaic/* across packages, the
  workspace glob, the package dir, and all import sites; lockfile regenerated
- renderer: add publishConfig (public, registry.npmjs.org) — was missing, so
  a scoped publish would default to the wrong registry / restricted access
- importer: add a files allowlist (dist, README, LICENSE) and drop the
  fragile .npmignore blacklist that shipped src; add an exports map so ESM
  consumers resolve dist/index.js instead of falling back to the .cjs main
- all three: add a prepublishOnly build (+ test/typecheck) guard so a publish
  can never ship a stale or empty dist
- add a tag-triggered publish workflow with npm provenance, pinned by name to
  the three @openmaic packages so the vendored forks (mathml2omml, pptxgenjs)
  are never published

Refs #778, #720 (Phase 1).

* fix(packages): address cross-review on the @openmaic publish prep

Cross-review (Claude /code-review + codex) on this PR surfaced:

- renderer's advertised CJS entry was broken: it keeps @openmaic/dsl external
  and imports a runtime enum from it, but dsl is ESM-only (no `require`
  condition), so `require('@openmaic/renderer')` would throw
  ERR_PACKAGE_PATH_NOT_EXPORTED. Make renderer ESM-only: drop the `.cjs`
  rollup output, `main` now points at the ESM build, and the `require`
  conditions are removed from `exports`. (importer is unaffected — it bundles
  dsl, so its CJS build still works.)
- prepublishOnly re-ran the test suite during `pnpm -r publish`, so a flaky
  test after dsl had already published gave a non-atomic partial release.
  Reduce prepublishOnly to a build-only guard (never ship stale/empty dist)
  and move the real test/typecheck gate into the workflow, before any publish.
- document that an @openmaic/* tag publishes the whole family via `pnpm -r`
  (pnpm skips already-published versions); the tag is a release marker, not a
  per-package gate.

Verified: dsl + renderer + importer build; renderer emits ESM only (0 .cjs),
all exports entries resolve; `npm pack` ships dist + README + LICENSE with no
src leak; frozen-lockfile passes.

Refs #778.

* style: reflow @openmaic/dsl type imports past print-width after rename

The @maic -> @openmaic rename lengthened two single-line type imports past
prettier's 100-col width; prettier --check flagged them. Pure formatting.

Refs #778.

* docs(importer): mark @openmaic/importer browser-only (cr-loop accepted limitation)

codex cross-review flagged that the published @openmaic/importer throws
`XMLHttpRequest is not a constructor` when loaded in a pure Node process —
its rollup build is browser-targeted (`nodeResolve({browser:true})` + a
browser pdf.js build). The app only consumes it client-side ('use client'),
so this is by design. Document it as an accepted limitation: prominent
browser-only note in the README and a `browser` field in the manifest.

Refs #778.
This commit is contained in:
wyuc authored and GitHub committed 2026-06-24 15:12:23 +08:00
1 parent fb4ce5341c
commit 7cb129183d
298 files changed
+423 -321

No files matched your search

+1 -1
View File
@@ -42,7 +42,7 @@ jobs:
run: pnpm test
- name: Unit Tests (importer)
run: pnpm --filter @maic/importer test
run: pnpm --filter @openmaic/importer test
e2e:
name: E2E Tests
+97
View File
@@ -0,0 +1,97 @@
name: Publish @openmaic packages
# Publishes the @openmaic/* package family (dsl, renderer, importer) to npm.
#
# Scope is pinned to those three packages by name on purpose: the workspace also
# contains vendored forks (mathml2omml, pptxgenjs) whose names we do NOT own, so
# a recursive publish must never touch them.
#
# Triggers:
# - push a tag like `@openmaic/dsl@0.1.0` (real publish). NOTE: any @openmaic/*
# tag runs `pnpm -r publish` over all three packages — pnpm skips versions
# already on the registry, so in steady state this is idempotent. The tag is a
# release marker, not a per-package gate: an unpublished version bump for a
# sibling package sitting in the repo will also be published by any tag. Bump
# only the package(s) you intend to release in the same change.
# - manual run via the Actions tab (dry-run by default; uncheck to publish)
#
# Prerequisites (one-time, see issue #778):
# - npm org `openmaic` created and owning the `@openmaic` scope
# - repo secret NPM_TOKEN: an automation/granular token with publish rights
# to @openmaic/*, 2FA set to "auth only" (not "auth and writes") so CI can publish
on:
push:
tags:
- "@openmaic/*@*"
workflow_dispatch:
inputs:
dry_run:
description: "Pack and validate only, do not publish"
type: boolean
default: true
concurrency:
group: publish-openmaic-${{ github.ref }}
cancel-in-progress: false
jobs:
publish:
name: Build, validate & publish
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write # required for npm provenance
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm
registry-url: https://registry.npmjs.org
- run: pnpm install --frozen-lockfile
# Build in dependency order (dsl first); renderer/importer resolve
# @openmaic/dsl through the workspace link.
- name: Build @openmaic packages
run: >-
pnpm -r
--filter "@openmaic/dsl"
--filter "@openmaic/renderer"
--filter "@openmaic/importer"
run build
# Gate BEFORE any publish: a failure here aborts before a single package
# reaches the registry. npm versions are immutable, so this prevents a
# partial release (e.g. dsl published, then a sibling's test fails).
- name: Test & typecheck (pre-publish gate)
run: |
pnpm --filter "@openmaic/dsl" --filter "@openmaic/importer" run test
pnpm --filter "@openmaic/dsl" --filter "@openmaic/renderer" run typecheck
# Always review tarball contents before any publish.
- name: Inspect tarball contents (dry-run pack)
run: |
for pkg in dsl renderer importer; do
echo "::group::@openmaic/$pkg"
( cd "packages/@openmaic/$pkg" && pnpm pack --dry-run )
echo "::endgroup::"
done
# Real publish. pnpm rewrites the workspace:* dep on @openmaic/dsl to the
# concrete published version and publishes in topological order.
- name: Publish to npm
if: github.event_name == 'push' || inputs.dry_run == false
run: >-
pnpm -r
--filter "@openmaic/dsl"
--filter "@openmaic/renderer"
--filter "@openmaic/importer"
publish --access public --provenance --no-git-checks
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
NPM_CONFIG_PROVENANCE: "true"
+1 -1
View File
@@ -33,7 +33,7 @@ CLAUDE.local.md
/build
/dist
# generated: synced from packages/@maic/importer/dist for runtime URL import
# generated: synced from packages/@openmaic/importer/dist for runtime URL import
/public/vendor/maic-importer
# misc
+3 -3
View File
@@ -6,10 +6,10 @@ node_modules/
packages/pptxgenjs/
packages/mathml2omml/
# @maic workspace packages: the source is formatted to the root style, but skip
# @openmaic workspace packages: the source is formatted to the root style, but skip
# generated build output and the vendored legacy reference under the importer.
packages/@maic/*/dist/
packages/@maic/importer/src1/
packages/@openmaic/*/dist/
packages/@openmaic/importer/src1/
# Docs site (separate Fumadocs app with its own toolchain)
packages/docs/
+1 -1
View File
@@ -4,7 +4,7 @@ import { useEffect, useState } from 'react';
import { ScreenElement } from '@/components/slide-renderer/Editor/ScreenElement';
import { SceneProvider } from '@/lib/contexts/scene-context';
import { useStageStore } from '@/lib/store/stage';
import type { PPTElement } from '@maic/dsl';
import type { PPTElement } from '@openmaic/dsl';
const EVAL_STAGE_ID = '__eval_stage__';
const EVAL_SCENE_ID = '__eval_scene__';
+1 -1
View File
@@ -6,7 +6,7 @@
Tailwind must scan its dist so those classes get generated. */
@source '../node_modules/streamdown/dist/*.js';
@source '../node_modules/@streamdown/code/dist/*.js';
@source "../node_modules/@maic/renderer/dist/**/*.{js,cjs}";
@source "../node_modules/@openmaic/renderer/dist/**/*.{js,cjs}";
/* slide-renderer-demo is gitignored (local sandbox), which makes Tailwind v4's
auto source detection skip it. Re-include it explicitly so the demo's
Tailwind classes (e.g. bg-violet-600) still get generated. */
+1 -1
View File
@@ -3,7 +3,7 @@ import localFont from 'next/font/local';
import { GeistSans } from 'geist/font/sans';
import { GeistMono } from 'geist/font/mono';
import './globals.css';
import '@maic/renderer/fonts.css';
import '@openmaic/renderer/fonts.css';
import 'animate.css';
import 'katex/dist/katex.min.css';
import { ThemeProvider } from '@/lib/hooks/use-theme';
+1 -1
View File
@@ -50,7 +50,7 @@ import {
revokeThumbnailSlideMediaUrls,
} from '@/lib/utils/stage-storage';
import { SlideThumbnail } from '@/components/slide-renderer/SlideThumbnail';
import type { Slide } from '@maic/dsl';
import type { Slide } from '@openmaic/dsl';
import { useMediaGenerationStore } from '@/lib/store/media-generation';
import { toast } from 'sonner';
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';
@@ -1,6 +1,6 @@
'use client';
import type { PPTElement } from '@maic/dsl';
import type { PPTElement } from '@openmaic/dsl';
import { AnchoredBar } from './AnchoredBar';
import { DeleteButton } from './DeleteButton';
import { ImageActions } from './ImageActions';
@@ -3,7 +3,7 @@
import { FlipHorizontal, FlipVertical, ImageUp } from 'lucide-react';
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';
import { useI18n } from '@/lib/hooks/use-i18n';
import type { PPTImageElement } from '@maic/dsl';
import type { PPTImageElement } from '@openmaic/dsl';
import { ImagePicker } from './ImagePicker';
import { replaceImageSrc, toggleImageFlip } from './use-slide-surface';
@@ -1,4 +1,4 @@
import type { PPTElement } from '@maic/dsl';
import type { PPTElement } from '@openmaic/dsl';
/**
* The single selected slide element — `undefined` unless exactly one element is
@@ -12,7 +12,7 @@ import { defaultRichTextAttrs } from '@/lib/prosemirror/utils';
import { useCanvasStore } from '@/lib/store/canvas';
import { useStageStore } from '@/lib/store/stage';
import type { SlideContent } from '@/lib/types/stage';
import type { PPTElement, PPTImageElement, SlideBackground } from '@maic/dsl';
import type { PPTElement, PPTImageElement, SlideBackground } from '@openmaic/dsl';
import { ImagePicker } from './ImagePicker';
import { BackgroundControl } from './BackgroundControl';
import { useSlideEditSession } from './slide-edit-session';
@@ -1,5 +1,5 @@
import { useMemo } from 'react';
import { ElementTypes, type PPTElement } from '@maic/dsl';
import { ElementTypes, type PPTElement } from '@openmaic/dsl';
import { ImageElement } from '../../components/element/ImageElement';
import { TextElement } from '../../components/element/TextElement';
import { LineElement } from '../../components/element/LineElement';
@@ -1,7 +1,7 @@
import { useMemo } from 'react';
import { useCanvasStore, useSceneSelector } from '@/lib/store';
import type { SlideContent } from '@/lib/types/stage';
import type { SlideBackground } from '@maic/dsl';
import type { SlideBackground } from '@openmaic/dsl';
export function GridLines() {
const gridLineSize = useCanvasStore.use.gridLineSize();
@@ -1,6 +1,11 @@
import { useMemo } from 'react';
import { useCanvasStore } from '@/lib/store';
import type { PPTVideoElement, PPTLatexElement, PPTAudioElement, PPTChartElement } from '@maic/dsl';
import type {
PPTVideoElement,
PPTLatexElement,
PPTAudioElement,
PPTChartElement,
} from '@openmaic/dsl';
import type { OperateResizeHandlers } from '@/lib/types/edit';
import { useCommonOperate } from '../hooks/useCommonOperate';
import { RotateHandler } from './RotateHandler';
@@ -1,6 +1,6 @@
import { useMemo } from 'react';
import { useCanvasStore } from '@/lib/store';
import type { PPTImageElement } from '@maic/dsl';
import type { PPTImageElement } from '@openmaic/dsl';
import type { OperateResizeHandlers } from '@/lib/types/edit';
import { useCommonOperate } from '../hooks/useCommonOperate';
import { RotateHandler } from './RotateHandler';
@@ -1,6 +1,6 @@
import { useMemo } from 'react';
import { useCanvasStore } from '@/lib/store';
import type { PPTLineElement } from '@maic/dsl';
import type { PPTLineElement } from '@openmaic/dsl';
import { OperateLineHandlers } from '@/lib/types/edit';
import { ResizeHandler } from './ResizeHandler';
@@ -1,6 +1,6 @@
import { useMemo, useEffect, useState } from 'react';
import { useCanvasStore } from '@/lib/store';
import type { PPTElement } from '@maic/dsl';
import type { PPTElement } from '@openmaic/dsl';
import { getElementListRange } from '@/lib/utils/element';
import type { OperateResizeHandlers, MultiSelectRange } from '@/lib/types/edit';
import { useCommonOperate } from '../hooks/useCommonOperate';
@@ -1,6 +1,6 @@
import { useMemo } from 'react';
import { useCanvasStore } from '@/lib/store';
import type { PPTShapeElement } from '@maic/dsl';
import type { PPTShapeElement } from '@openmaic/dsl';
import type { OperateResizeHandlers } from '@/lib/types/edit';
import { SHAPE_PATH_FORMULAS } from '@/configs/shapes';
import { useCommonOperate } from '../hooks/useCommonOperate';
@@ -1,6 +1,6 @@
import { useMemo } from 'react';
import { useCanvasStore } from '@/lib/store';
import type { PPTTableElement } from '@maic/dsl';
import type { PPTTableElement } from '@openmaic/dsl';
import type { OperateResizeHandlers } from '@/lib/types/edit';
import { useCommonOperate } from '../hooks/useCommonOperate';
import { RotateHandler } from './RotateHandler';
@@ -1,6 +1,6 @@
import { useMemo } from 'react';
import { useCanvasStore } from '@/lib/store';
import type { PPTTextElement } from '@maic/dsl';
import type { PPTTextElement } from '@openmaic/dsl';
import type { OperateResizeHandlers } from '@/lib/types/edit';
import { useCommonOperate } from '../hooks/useCommonOperate';
import { RotateHandler } from './RotateHandler';
@@ -10,7 +10,7 @@ import {
type PPTChartElement,
type Slide,
type PPTAnimation,
} from '@maic/dsl';
} from '@openmaic/dsl';
import type { OperateLineHandlers, OperateResizeHandlers } from '@/lib/types/edit';
import { ImageElementOperate } from './ImageElementOperate';
import { TextElementOperate } from './TextElementOperate';
@@ -1,7 +1,7 @@
import { useMemo, useEffect, useState } from 'react';
import { useCanvasStore } from '@/lib/store';
import { getElementListRange } from '@/lib/utils/element';
import type { PPTElement } from '@maic/dsl';
import type { PPTElement } from '@openmaic/dsl';
import type { ViewportStyles } from './hooks/useViewportSize';
interface RulerProps {
@@ -3,7 +3,7 @@ import { useKeyboardStore } from '@/lib/store/keyboard';
import { useCanvasStore, useSceneSelector } from '@/lib/store';
import type { CreateCustomShapeData } from '@/lib/types/edit';
import type { SlideContent } from '@/lib/types/stage';
import type { SlideTheme } from '@maic/dsl';
import type { SlideTheme } from '@openmaic/dsl';
import { toast } from 'sonner';
interface ShapeCreateCanvasProps {
@@ -3,7 +3,7 @@
import { useSceneSelector } from '@/lib/contexts/scene-context';
import { useSlideBackgroundStyle } from '@/lib/hooks/use-slide-background-style';
import type { SlideContent } from '@/lib/types/stage';
import type { SlideBackground } from '@maic/dsl';
import type { SlideBackground } from '@openmaic/dsl';
/**
* Viewport background component using Scene Context
@@ -1,7 +1,7 @@
import { useCallback } from 'react';
import { useCanvasStore, useKeyboardStore } from '@/lib/store';
import { useHistorySnapshot } from '@/lib/hooks/use-history-snapshot';
import type { PPTElement } from '@maic/dsl';
import type { PPTElement } from '@openmaic/dsl';
import type { AlignmentLineProps } from '@/lib/types/edit';
import { getRectRotatedRange, uniqAlignLines, type AlignLine } from '@/lib/utils/element';
import { useCanvasOperations } from '@/lib/hooks/use-canvas-operations';
@@ -1,7 +1,7 @@
import { useCallback } from 'react';
import { useKeyboardStore } from '@/lib/store/keyboard';
import { useCanvasStore } from '@/lib/store';
import type { PPTElement, PPTLineElement } from '@maic/dsl';
import type { PPTElement, PPTLineElement } from '@openmaic/dsl';
import { OperateLineHandlers } from '@/lib/types/edit';
import { useHistorySnapshot } from '@/lib/hooks/use-history-snapshot';
import { useCanvasOperations } from '@/lib/hooks/use-canvas-operations';
@@ -3,7 +3,7 @@ import { useCanvasStore } from '@/lib/store';
import { createElementId } from '@/lib/edit/element-id';
import { useCanvasOperations } from '@/lib/hooks/use-canvas-operations';
import type { CreateElementSelectionData } from '@/lib/types/edit';
import type { PPTTextElement } from '@maic/dsl';
import type { PPTTextElement } from '@openmaic/dsl';
// Click-fallback default size when the user clicks instead of drags (or wobbles
// under this in either dimension): a sensibly-sized text box at the start point.
@@ -1,7 +1,7 @@
import { useState, useCallback, type RefObject } from 'react';
import { useKeyboardStore } from '@/lib/store/keyboard';
import { useCanvasStore } from '@/lib/store';
import type { PPTElement } from '@maic/dsl';
import type { PPTElement } from '@openmaic/dsl';
import { getElementRange } from '@/lib/utils/element';
export function useMouseSelection(
@@ -1,5 +1,5 @@
import { useCallback } from 'react';
import type { PPTElement, PPTShapeElement } from '@maic/dsl';
import type { PPTElement, PPTShapeElement } from '@openmaic/dsl';
import { useHistorySnapshot } from '@/lib/hooks/use-history-snapshot';
import { SHAPE_PATH_FORMULAS } from '@/configs/shapes';
import { useCanvasOperations } from '@/lib/hooks/use-canvas-operations';
@@ -5,7 +5,7 @@ import type {
PPTVideoElement,
PPTAudioElement,
PPTChartElement,
} from '@maic/dsl';
} from '@openmaic/dsl';
import { useHistorySnapshot } from '@/lib/hooks/use-history-snapshot';
import { useCanvasOperations } from '@/lib/hooks/use-canvas-operations';
@@ -1,7 +1,7 @@
import { useCallback } from 'react';
import { useCanvasStore } from '@/lib/store';
import { useKeyboardStore } from '@/lib/store/keyboard';
import type { PPTElement, PPTLineElement, PPTImageElement, PPTShapeElement } from '@maic/dsl';
import type { PPTElement, PPTLineElement, PPTImageElement, PPTShapeElement } from '@openmaic/dsl';
import {
OperateResizeHandlers,
type AlignmentLineProps,
@@ -2,7 +2,7 @@ import { useCallback } from 'react';
import { uniq } from 'lodash';
import { useCanvasStore } from '@/lib/store';
import { useKeyboardStore } from '@/lib/store/keyboard';
import type { PPTElement } from '@maic/dsl';
import type { PPTElement } from '@openmaic/dsl';
/**
* Hook for handling element selection in Canvas
@@ -24,7 +24,7 @@ import { ElementCreateSelection } from './ElementCreateSelection';
import { ShapeCreateCanvas } from './ShapeCreateCanvas';
import { Ruler } from './Ruler';
import { GridLines } from './GridLines';
import type { PPTElement } from '@maic/dsl';
import type { PPTElement } from '@openmaic/dsl';
import type { AlignmentLineProps } from '@/lib/types/edit';
import type { ContextmenuItem } from './EditableElement';
import type { SlideContent } from '@/lib/types/stage';
@@ -4,7 +4,7 @@ import { useMemo } from 'react';
import { useSceneSelector } from '@/lib/contexts/scene-context';
import { useCanvasStore } from '@/lib/store/canvas';
import type { SlideContent } from '@/lib/types/stage';
import type { PPTElement } from '@maic/dsl';
import type { PPTElement } from '@openmaic/dsl';
/**
* Highlight overlay component
@@ -5,7 +5,7 @@ import { AnimatePresence } from 'motion/react';
import { useSceneSelector } from '@/lib/contexts/scene-context';
import { useCanvasStore } from '@/lib/store/canvas';
import type { SlideContent } from '@/lib/types/stage';
import type { PPTElement } from '@maic/dsl';
import type { PPTElement } from '@openmaic/dsl';
import { LaserOverlay } from './LaserOverlay';
interface LaserPointerOverlayProps {
@@ -9,7 +9,7 @@ import { useCanvasStore } from '@/lib/store';
import { useSceneSelector } from '@/lib/contexts/scene-context';
import { findElementGeometry } from '@/lib/utils/geometry';
import type { SlideContent } from '@/lib/types/stage';
import type { PPTElement, SlideBackground } from '@maic/dsl';
import type { PPTElement, SlideBackground } from '@openmaic/dsl';
import type { PercentageGeometry } from '@/lib/types/action';
import { useViewportSize } from './Canvas/hooks/useViewportSize';
import { useRef, useMemo } from 'react';
@@ -1,6 +1,6 @@
'use client';
import { ElementTypes, type PPTElement } from '@maic/dsl';
import { ElementTypes, type PPTElement } from '@openmaic/dsl';
import { useMemo } from 'react';
import { BaseImageElement } from '../components/element/ImageElement/BaseImageElement';
@@ -5,7 +5,7 @@ import { motion, AnimatePresence } from 'motion/react';
import { useSceneSelector } from '@/lib/contexts/scene-context';
import { useCanvasStore } from '@/lib/store/canvas';
import type { SlideContent } from '@/lib/types/stage';
import type { PPTElement } from '@maic/dsl';
import type { PPTElement } from '@openmaic/dsl';
interface SpotlightRect {
x: number;
+6 -6
View File
@@ -2,11 +2,11 @@
import { useMemo } from 'react';
import { Play } from 'lucide-react';
import type { Slide, PPTElement, PPTVideoElement } from '@maic/dsl';
import type { Slide, PPTElement, PPTVideoElement } from '@openmaic/dsl';
import { isMediaPlaceholder, useMediaGenerationStore } from '@/lib/store/media-generation';
import { useMediaStageId } from '@/lib/contexts/media-stage-context';
import { getVideoMediaRefForElement } from '@/lib/media/video-manifest';
import { SlideCanvas } from '@maic/renderer';
import { SlideCanvas } from '@openmaic/renderer';
interface SlideThumbnailProps {
/** Slide data */
@@ -43,7 +43,7 @@ function mediaTaskKeyFor(el: PPTElement): string | undefined {
* Resolve a slide's generated-media refs against the media-generation store so
* the thumbnail stays in sync as generation (and retries) complete.
*
* `@maic/renderer` is a pure package: it renders `element.src` as-is and knows
* `@openmaic/renderer` is a pure package: it renders `element.src` as-is and knows
* nothing about this app's async media generation. The store never mutates the
* slide's elements (it keeps the `gen_*`/`mediaRef` key and tracks the
* generated `objectUrl` in a task), so a static render would show the raw
@@ -105,7 +105,7 @@ function useResolvedSlide(slide: Slide): Slide {
}
/**
* Read-only thumbnail rendering for a video element. Replaces `@maic/renderer`'s
* Read-only thumbnail rendering for a video element. Replaces `@openmaic/renderer`'s
* default `<video controls>` with a muted, play-badged treatment suited to
* thumbnails. `BaseVideoElement` already supplies the absolutely-positioned,
* rotated wrapper, so this only paints the inner content. The `src` it receives
@@ -145,7 +145,7 @@ function renderThumbnailVideo(element: PPTVideoElement) {
}
/**
* Read-only slide thumbnail rendered via the extracted `@maic/renderer`
* Read-only slide thumbnail rendered via the extracted `@openmaic/renderer`
* package (`SlideCanvas`) instead of the in-app `ThumbnailSlide`/element
* renderers. `SlideCanvas` fills its parent and auto-fits the slide, so this
* wrapper owns the outer box sizing (explicit `size` vs parent-filling), the
@@ -157,7 +157,7 @@ function renderThumbnailVideo(element: PPTVideoElement) {
* Scope note: this covers all read-only slide-thumbnail surfaces — the playback
* scene sidebar, the home-page recent-course cards, and the editor nav rail
* (which renders through `SceneThumbnailContent`). The full-size editing canvas
* is intentionally untouched (`@maic/renderer` v1 is read-only; editing is v2).
* is intentionally untouched (`@openmaic/renderer` v1 is read-only; editing is v2).
*/
export function SlideThumbnail({
slide,
@@ -1,6 +1,6 @@
'use client';
import type { PPTChartElement } from '@maic/dsl';
import type { PPTChartElement } from '@openmaic/dsl';
import { ElementOutline } from '../ElementOutline';
import { Chart } from './Chart';
@@ -2,7 +2,7 @@
import { useEffect, useRef, useMemo } from 'react';
import tinycolor from 'tinycolor2';
import type { ChartData, ChartOptions, ChartType } from '@maic/dsl';
import type { ChartData, ChartOptions, ChartType } from '@openmaic/dsl';
import { getChartOption } from './chartOption';
import * as echarts from 'echarts/core';
@@ -6,7 +6,7 @@ import type {
ScatterSeriesOption,
RadarSeriesOption,
} from 'echarts/charts';
import type { ChartData, ChartType } from '@maic/dsl';
import type { ChartData, ChartType } from '@openmaic/dsl';
type EChartOption = ComposeOption<
BarSeriesOption | LineSeriesOption | PieSeriesOption | ScatterSeriesOption | RadarSeriesOption
@@ -1,6 +1,6 @@
'use client';
import type { PPTChartElement } from '@maic/dsl';
import type { PPTChartElement } from '@openmaic/dsl';
import { ElementOutline } from '../ElementOutline';
import { Chart } from './Chart';
@@ -2,7 +2,7 @@
import { useRef, useState, useEffect, useMemo, useCallback } from 'react';
import { motion, AnimatePresence } from 'motion/react';
import type { PPTCodeElement, CodeLine } from '@maic/dsl';
import type { PPTCodeElement, CodeLine } from '@openmaic/dsl';
// ==================== Shiki Singleton ====================
@@ -1,6 +1,6 @@
'use client';
import type { PPTElementOutline } from '@maic/dsl';
import type { PPTElementOutline } from '@openmaic/dsl';
import { useElementOutline } from './hooks/useElementOutline';
export interface ElementOutlineProps {
@@ -1,6 +1,6 @@
'use client';
import type { PPTImageElement } from '@maic/dsl';
import type { PPTImageElement } from '@openmaic/dsl';
import { useElementShadow } from '../hooks/useElementShadow';
import { useElementFlip } from '../hooks/useElementFlip';
import { useClipImage } from './useClipImage';
@@ -5,7 +5,7 @@ import { useKeyboardStore, useCanvasStore } from '@/lib/store';
import { KEYS } from '@/configs/hotkey';
import { OperateResizeHandlers } from '@/lib/types/edit';
import type { ImageClipedEmitData } from '@/lib/types/edit';
import type { ImageClipDataRange, ImageElementClip } from '@maic/dsl';
import type { ImageClipDataRange, ImageElementClip } from '@openmaic/dsl';
export interface ImageClipHandlerProps {
src: string;
@@ -1,6 +1,6 @@
'use client';
import type { PPTElementOutline } from '@maic/dsl';
import type { PPTElementOutline } from '@openmaic/dsl';
import { useElementOutline } from '../../hooks/useElementOutline';
export interface ImageEllipseOutlineProps {
@@ -1,6 +1,6 @@
'use client';
import type { PPTElementOutline } from '@maic/dsl';
import type { PPTElementOutline } from '@openmaic/dsl';
import { useElementOutline } from '../../hooks/useElementOutline';
export interface ImagePolygonOutlineProps {
@@ -1,6 +1,6 @@
'use client';
import type { PPTElementOutline } from '@maic/dsl';
import type { PPTElementOutline } from '@openmaic/dsl';
import { useElementOutline } from '../../hooks/useElementOutline';
export interface ImageRectOutlineProps {
@@ -1,6 +1,6 @@
'use client';
import type { PPTImageElement } from '@maic/dsl';
import type { PPTImageElement } from '@openmaic/dsl';
import { useClipImage } from '../useClipImage';
import { ImageRectOutline } from './image-rect-outline';
import { ImageEllipseOutline } from './image-ellipse-outline';
@@ -1,6 +1,6 @@
'use client';
import type { PPTImageElement, ImageElementClip } from '@maic/dsl';
import type { PPTImageElement, ImageElementClip } from '@openmaic/dsl';
import type { ImageClipedEmitData } from '@/lib/types/edit';
import { useCanvasStore } from '@/lib/store';
import { useCanvasOperations } from '@/lib/hooks/use-canvas-operations';
@@ -1,5 +1,5 @@
import { useMemo } from 'react';
import type { PPTImageElement } from '@maic/dsl';
import type { PPTImageElement } from '@openmaic/dsl';
import { CLIPPATHS, ClipPathTypes } from '@/configs/image-clip';
/**
@@ -1,5 +1,5 @@
import { useMemo } from 'react';
import type { ImageElementFilters } from '@maic/dsl';
import type { ImageElementFilters } from '@openmaic/dsl';
/**
* Calculate CSS filter string from image filters array
@@ -1,6 +1,6 @@
'use client';
import type { PPTImageElement } from '@maic/dsl';
import type { PPTImageElement } from '@openmaic/dsl';
import { useMediaStageId } from '@/lib/contexts/media-stage-context';
import {
useMediaGenerationStore,
@@ -1,7 +1,7 @@
'use client';
import { useRef, useState, useLayoutEffect } from 'react';
import type { PPTLatexElement } from '@maic/dsl';
import type { PPTLatexElement } from '@openmaic/dsl';
export interface BaseLatexElementProps {
elementInfo: PPTLatexElement;
@@ -1,7 +1,7 @@
'use client';
import { useRef, useState, useLayoutEffect } from 'react';
import type { PPTLatexElement } from '@maic/dsl';
import type { PPTLatexElement } from '@openmaic/dsl';
export { BaseLatexElement } from './BaseLatexElement';
@@ -1,7 +1,7 @@
'use client';
import { useMemo, useRef, useState, useEffect } from 'react';
import type { PPTLineElement } from '@maic/dsl';
import type { PPTLineElement } from '@openmaic/dsl';
import { getLineElementPath } from '@/lib/utils/element';
import { useElementShadow } from '../hooks/useElementShadow';
import { LinePointMarker } from './LinePointMarker';
@@ -1,4 +1,4 @@
import type { LinePoint } from '@maic/dsl';
import type { LinePoint } from '@openmaic/dsl';
type NonEmptyLinePoint = Exclude<LinePoint, ''>;
@@ -1,7 +1,7 @@
'use client';
import { useMemo } from 'react';
import type { PPTLineElement } from '@maic/dsl';
import type { PPTLineElement } from '@openmaic/dsl';
import { getLineElementPath } from '@/lib/utils/element';
import { useElementShadow } from '../hooks/useElementShadow';
import { LinePointMarker } from './LinePointMarker';
@@ -1,6 +1,6 @@
'use client';
import type { PPTShapeElement, ShapeText } from '@maic/dsl';
import type { PPTShapeElement, ShapeText } from '@openmaic/dsl';
import { useElementOutline } from '../hooks/useElementOutline';
import { useElementShadow } from '../hooks/useElementShadow';
import { useElementFlip } from '../hooks/useElementFlip';
@@ -1,4 +1,4 @@
import type { GradientColor, GradientType } from '@maic/dsl';
import type { GradientColor, GradientType } from '@openmaic/dsl';
interface GradientDefsProps {
id: string;
@@ -1,7 +1,7 @@
'use client';
import { useMemo, useState, useEffect, useCallback } from 'react';
import type { PPTShapeElement, ShapeText } from '@maic/dsl';
import type { PPTShapeElement, ShapeText } from '@openmaic/dsl';
import { useCanvasStore } from '@/lib/store';
import { useCanvasOperations } from '@/lib/hooks/use-canvas-operations';
import { useHistorySnapshot } from '@/lib/hooks/use-history-snapshot';
@@ -1,6 +1,6 @@
'use client';
import type { PPTTableElement } from '@maic/dsl';
import type { PPTTableElement } from '@openmaic/dsl';
import { StaticTable } from './StaticTable';
export interface BaseTableElementProps {
@@ -1,7 +1,7 @@
'use client';
import { useMemo } from 'react';
import type { PPTTableElement } from '@maic/dsl';
import type { PPTTableElement } from '@openmaic/dsl';
import { getTableSubThemeColor } from '@/lib/utils/element';
import { getTextStyle, formatText, getHiddenCells } from './tableUtils';
@@ -1,6 +1,6 @@
'use client';
import type { PPTTableElement } from '@maic/dsl';
import type { PPTTableElement } from '@openmaic/dsl';
import { StaticTable } from './StaticTable';
export { BaseTableElement } from './BaseTableElement';
@@ -1,5 +1,5 @@
import type { CSSProperties } from 'react';
import type { TableCell, TableCellStyle } from '@maic/dsl';
import type { TableCell, TableCellStyle } from '@openmaic/dsl';
/**
* Convert TableCellStyle to CSS properties
@@ -1,6 +1,6 @@
'use client';
import type { PPTTextElement } from '@maic/dsl';
import type { PPTTextElement } from '@openmaic/dsl';
import { useElementShadow } from '../hooks/useElementShadow';
import { ElementOutline } from '../ElementOutline';
@@ -4,7 +4,7 @@ import { useRef, useEffect, useState, useCallback } from 'react';
import { debounce } from 'lodash';
import { useCanvasStore } from '@/lib/store';
import { useHistorySnapshot } from '@/lib/hooks/use-history-snapshot';
import type { PPTTextElement } from '@maic/dsl';
import type { PPTTextElement } from '@openmaic/dsl';
import { useElementShadow } from '../hooks/useElementShadow';
import { ElementOutline } from '../ElementOutline';
import { ProsemirrorEditor } from '../ProsemirrorEditor';
@@ -2,7 +2,7 @@
import { useRef, useEffect } from 'react';
import { useAnimate } from 'motion/react';
import type { PPTVideoElement } from '@maic/dsl';
import type { PPTVideoElement } from '@openmaic/dsl';
import { useCanvasStore } from '@/lib/store/canvas';
import { useMediaGenerationStore, isMediaPlaceholder } from '@/lib/store/media-generation';
import { useSettingsStore } from '@/lib/store/settings';
@@ -1,6 +1,6 @@
'use client';
import type { PPTVideoElement } from '@maic/dsl';
import type { PPTVideoElement } from '@openmaic/dsl';
import { isMediaPlaceholder } from '@/lib/store/media-generation';
export interface VideoElementProps {
@@ -1,5 +1,5 @@
import { useMemo } from 'react';
import type { PPTShapeElement } from '@maic/dsl';
import type { PPTShapeElement } from '@openmaic/dsl';
/**
* Calculate element fill style
@@ -1,5 +1,5 @@
import { useMemo } from 'react';
import type { PPTElementOutline } from '@maic/dsl';
import type { PPTElementOutline } from '@openmaic/dsl';
/**
* Calculate element outline (border) styles
@@ -1,5 +1,5 @@
import { useMemo } from 'react';
import type { PPTElementShadow } from '@maic/dsl';
import type { PPTElementShadow } from '@openmaic/dsl';
/**
* Calculate element shadow style
+1 -1
View File
@@ -14,7 +14,7 @@ import { motion, AnimatePresence } from 'motion/react';
import { useStageStore } from '@/lib/store';
import { useCanvasStore } from '@/lib/store/canvas';
import { ScreenElement } from '@/components/slide-renderer/Editor/ScreenElement';
import type { PPTElement } from '@maic/dsl';
import type { PPTElement } from '@openmaic/dsl';
import { useI18n } from '@/lib/hooks/use-i18n';
export type WhiteboardCanvasHandle = {
+1 -1
View File
@@ -1,4 +1,4 @@
import type { TurningMode } from '@maic/dsl';
import type { TurningMode } from '@openmaic/dsl';
export const ANIMATION_DEFAULT_DURATION = 1000;
export const ANIMATION_DEFAULT_TRIGGER = 'click';
+1 -1
View File
@@ -1,4 +1,4 @@
import type { ChartData } from '@maic/dsl';
import type { ChartData } from '@openmaic/dsl';
export const CHART_TYPE_MAP: Record<string, string> = {
bar: '柱状图',
+1 -1
View File
@@ -1,4 +1,4 @@
import type { LinePoint, LineStyleType } from '@maic/dsl';
import type { LinePoint, LineStyleType } from '@openmaic/dsl';
export interface LinePoolItem {
path: string;
+1 -1
View File
@@ -1,6 +1,6 @@
// Non-professional designers can use this app to draw basic shapes: https://github.com/pipipi-pikachu/svgPathCreator
import { ShapePathFormulasKeys } from '@maic/dsl';
import { ShapePathFormulasKeys } from '@openmaic/dsl';
export interface ShapePoolItem {
viewBox: [number, number];
+1 -1
View File
@@ -1,4 +1,4 @@
import type { PPTElementOutline, PPTElementShadow } from '@maic/dsl';
import type { PPTElementOutline, PPTElementShadow } from '@openmaic/dsl';
export interface PresetTheme {
background: string;
+2 -2
View File
@@ -1,7 +1,7 @@
import type { SlideTheme } from '@maic/dsl';
import type { SlideTheme } from '@openmaic/dsl';
import { mockOutlines } from './scene-outlines';
/** Default theme matching @maic/dsl SlideTheme */
/** Default theme matching @openmaic/dsl SlideTheme */
const defaultTheme: SlideTheme = {
backgroundColor: '#ffffff',
themeColors: ['#5b9bd5', '#ed7d31', '#a5a5a5', '#ffc000', '#4472c4'],
+4 -4
View File
@@ -16,11 +16,11 @@ const eslintConfig = defineConfig([
'packages/docs/**',
'packages/mathml2omml/**',
'packages/pptxgenjs/**',
// Our own @maic/* packages: lint the source, but skip build output,
// Our own @openmaic/* packages: lint the source, but skip build output,
// installed deps, and the vendored JS sources under importer/src1.
'packages/@maic/*/dist/**',
'packages/@maic/*/node_modules/**',
'packages/@maic/importer/src1/**',
'packages/@openmaic/*/dist/**',
'packages/@openmaic/*/node_modules/**',
'packages/@openmaic/importer/src1/**',
// Generated importer bundle copied into public/ by the sync script (postinstall):
'public/vendor/**',
// Claude Code local files:
+1 -1
View File
@@ -1,5 +1,5 @@
import { chromium, type Browser, type Page } from '@playwright/test';
import type { PPTElement } from '@maic/dsl';
import type { PPTElement } from '@openmaic/dsl';
import { mkdirSync } from 'fs';
import { join } from 'path';
+1 -1
View File
@@ -3,7 +3,7 @@ import { useCanvasStore } from '@/lib/store/canvas';
import { useWhiteboardHistoryStore } from '@/lib/store/whiteboard-history';
import { ActionEngine } from '@/lib/action/engine';
import type { Action } from '@/lib/types/action';
import type { PPTElement } from '@maic/dsl';
import type { PPTElement } from '@openmaic/dsl';
import type { Stage, Scene } from '@/lib/types/stage';
interface InitialState {
+1 -1
View File
@@ -1,4 +1,4 @@
import type { PPTElement } from '@maic/dsl';
import type { PPTElement } from '@openmaic/dsl';
import type { Stage, Scene } from '@/lib/types/stage';
// ==================== Scenario ====================
+1 -1
View File
@@ -36,7 +36,7 @@ import type {
WidgetAnnotationAction,
WidgetRevealAction,
} from '@/lib/types/action';
import type { CodeLine } from '@maic/dsl';
import type { CodeLine } from '@openmaic/dsl';
import katex from 'katex';
import { createLogger } from '@/lib/logger';
+1 -1
View File
@@ -46,7 +46,7 @@ function truncate(s: string, max: number): string {
/**
* Pull the human-readable text out of a single slide element. Mirrors the
* @maic/dsl `PPTElement` union — each variant stashes its text differently:
* @openmaic/dsl `PPTElement` union — each variant stashes its text differently:
* - text: `content` (HTML string)
* - shape: `text.content` (ShapeText, HTML string)
* - table: `data` (TableCell[][], each cell carries `text`)
+1 -1
View File
@@ -7,7 +7,7 @@
*/
import type { SlideContent } from '@/lib/types/stage';
import type { SlideTheme, SlideBackground } from '@maic/dsl';
import type { SlideTheme, SlideBackground } from '@openmaic/dsl';
import { useCanvasStore } from '@/lib/store/canvas';
import type { StageStore, APIResult, HighlightOptions, SpotlightOptions } from './stage-api-types';
import { getScene } from './stage-api-defaults';
+1 -1
View File
@@ -6,7 +6,7 @@
*/
import type { SlideContent } from '@/lib/types/stage';
import type { PPTElement } from '@maic/dsl';
import type { PPTElement } from '@openmaic/dsl';
import type { StageStore, APIResult, CreateElementParams } from './stage-api-types';
import { generateId, getScene } from './stage-api-defaults';
+1 -1
View File
@@ -5,7 +5,7 @@
*/
import type { Stage, Scene, SceneContent, SceneType, StageMode } from '@/lib/types/stage';
import type { PPTElement } from '@maic/dsl';
import type { PPTElement } from '@openmaic/dsl';
import type { Action } from '@/lib/types/action';
// ==================== Type Definitions ====================
+1 -1
View File
@@ -6,7 +6,7 @@
*/
import type { Whiteboard } from '@/lib/types/stage';
import type { PPTElement } from '@maic/dsl';
import type { PPTElement } from '@openmaic/dsl';
import type { StageStore, APIResult } from './stage-api-types';
import { generateId } from './stage-api-defaults';
+1 -1
View File
@@ -16,7 +16,7 @@
import { isEqual } from 'lodash';
import type { SlideContent } from '@/lib/types/stage';
import type { PPTElement } from '@maic/dsl';
import type { PPTElement } from '@openmaic/dsl';
import { applySlideEditOperation, MAX_HISTORY } from '@/lib/edit/slide-ops';
import type { SlideEditHistory, SlideEditOperation } from '@/lib/edit/slide-ops';
+1 -1
View File
@@ -1,5 +1,5 @@
import { nanoid } from 'nanoid';
import type { Slide, SlideTheme, PPTElement } from '@maic/dsl';
import type { Slide, SlideTheme, PPTElement } from '@openmaic/dsl';
import type { Scene, SlideContent } from '@/lib/types/stage';
import type { Action } from '@/lib/types/action';
import { createElementIdMap } from '@/lib/utils/element';
+1 -1
View File
@@ -4,7 +4,7 @@ import type {
PPTShapeElement,
PPTTextElement,
Slide,
} from '@maic/dsl';
} from '@openmaic/dsl';
export interface ShapeSpec {
viewBox: [number, number];
+1 -1
View File
@@ -1,6 +1,6 @@
import { current, produce } from 'immer';
import type { SlideContent } from '@/lib/types/stage';
import type { PPTElement, Slide } from '@maic/dsl';
import type { PPTElement, Slide } from '@openmaic/dsl';
import { getElementListRange } from '@/lib/utils/element';
type ElementPatch = Partial<PPTElement>;
+1 -1
View File
@@ -1,7 +1,7 @@
// lib/export/classroom-zip-types.ts
import type { SceneType, SceneContent } from '@/lib/types/stage';
import type { Action } from '@/lib/types/action';
import type { Slide } from '@maic/dsl';
import type { Slide } from '@openmaic/dsl';
export const CLASSROOM_ZIP_FORMAT_VERSION = 1;
export const CLASSROOM_ZIP_EXTENSION = '.maic.zip';
+1 -1
View File
@@ -10,7 +10,7 @@ import { useStageStore } from '@/lib/store';
import { useCanvasStore } from '@/lib/store/canvas';
import { useMediaGenerationStore, isMediaPlaceholder } from '@/lib/store/media-generation';
import { useI18n } from '@/lib/hooks/use-i18n';
import type { Slide, PPTElementOutline, PPTElementShadow, PPTElementLink } from '@maic/dsl';
import type { Slide, PPTElementOutline, PPTElementShadow, PPTElementLink } from '@openmaic/dsl';
import type { Scene, SlideContent } from '@/lib/types/stage';
import type { SpeechAction } from '@/lib/types/action';
import { getElementRange, getLineElementPath, getTableSubThemeColor } from '@/lib/utils/element';
+1 -1
View File
@@ -14,7 +14,7 @@ import type {
ImageMapping,
} from '@/lib/types/generation';
import type { LanguageModel } from 'ai';
import type { Slide, SlideTheme } from '@maic/dsl';
import type { Slide, SlideTheme } from '@openmaic/dsl';
import type { Scene } from '@/lib/types/stage';
import type { Action } from '@/lib/types/action';
import { applyOutlineFallbacks } from './outline-generator';
+1 -1
View File
@@ -36,7 +36,7 @@ import {
formatImageDescription,
formatImagePlaceholder,
} from './prompt-formatters';
import type { PPTElement, Slide, SlideBackground, SlideTheme } from '@maic/dsl';
import type { PPTElement, Slide, SlideBackground, SlideTheme } from '@openmaic/dsl';
import type { QuizQuestion } from '@/lib/types/stage';
import type {
Action,
Loaded 100 of 298 files, more files were not shown because too many files have changed in this diff. Show more