@open-press/cli 0.7.1 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -13
- package/dist/cli.js +44 -195
- package/package.json +4 -5
- package/template/core/AGENTS.md +18 -14
- package/template/core/CHANGELOG.md +57 -9
- package/template/core/README.md +6 -3
- package/template/core/engine/cli.mjs +8 -8
- package/template/core/engine/commands/_shared.mjs +37 -15
- package/template/core/engine/commands/dev.mjs +2 -2
- package/template/core/engine/commands/image.mjs +29 -0
- package/template/core/engine/commands/skills-sync.mjs +71 -0
- package/template/core/engine/commands/typecheck.mjs +63 -1
- package/template/core/engine/commands/upgrade.mjs +3 -3
- package/template/core/engine/document-export.mjs +1 -1
- package/template/core/engine/output/chrome-pdf.mjs +110 -3
- package/template/core/engine/output/static-server.mjs +87 -9
- package/template/core/engine/react/comment-endpoint.mjs +13 -39
- package/template/core/engine/react/comment-marker.mjs +43 -19
- package/template/core/engine/react/document-entry.mjs +46 -28
- package/template/core/engine/react/document-export.mjs +328 -164
- package/template/core/engine/react/http-json.mjs +24 -0
- package/template/core/engine/react/mdx-compile.mjs +126 -3
- package/template/core/engine/react/measurement-css.mjs +114 -1
- package/template/core/engine/react/object-entities.mjs +204 -0
- package/template/core/engine/react/pagination/allocator.mjs +48 -3
- package/template/core/engine/react/pagination.mjs +1 -1
- package/template/core/engine/react/pipeline/allocate.mjs +41 -72
- package/template/core/engine/react/pipeline/frame-measurement.mjs +6 -0
- package/template/core/engine/react/press-tree-inspection.mjs +172 -0
- package/template/core/engine/react/project-asset-endpoint.mjs +6 -24
- package/template/core/engine/react/source-edit-endpoint.d.mts +10 -0
- package/template/core/engine/react/source-edit-endpoint.mjs +75 -0
- package/template/core/engine/react/sources/mdx-resolver.mjs +13 -15
- package/template/core/engine/react/style-discovery.mjs +23 -8
- package/template/core/engine/runtime/config.d.mts +8 -0
- package/template/core/engine/runtime/config.mjs +57 -60
- package/template/core/engine/runtime/file-utils.mjs +9 -1
- package/template/core/engine/runtime/file-walk.mjs +22 -0
- package/template/core/engine/runtime/inspection.mjs +1 -20
- package/template/core/engine/runtime/page-geometry.mjs +131 -0
- package/template/core/engine/runtime/path-utils.mjs +20 -0
- package/template/core/engine/runtime/source-text-tools.d.mts +102 -0
- package/template/core/engine/runtime/source-text-tools.mjs +551 -16
- package/template/core/engine/runtime/source-workspace.mjs +16 -34
- package/template/core/engine/runtime/validation.mjs +19 -10
- package/template/core/openpress.config.mjs +3 -7
- package/template/core/package.json +3 -5
- package/template/core/src/main.tsx +2 -2
- package/template/core/src/openpress/app/OpenPressApp.tsx +296 -0
- package/template/core/src/openpress/{renderer.tsx → app/OpenPressRuntime.tsx} +20 -9
- package/template/core/src/openpress/app/WorkspaceGalleryPage.tsx +219 -0
- package/template/core/src/openpress/app/index.ts +2 -0
- package/template/core/src/openpress/core/Frame.tsx +26 -15
- package/template/core/src/openpress/core/FrameContext.tsx +10 -3
- package/template/core/src/openpress/core/MdxArea.tsx +11 -12
- package/template/core/src/openpress/core/Press.tsx +25 -4
- package/template/core/src/openpress/core/Workspace.tsx +36 -0
- package/template/core/src/openpress/core/cn.ts +4 -0
- package/template/core/src/openpress/core/index.tsx +11 -3
- package/template/core/src/openpress/core/primitives.tsx +74 -6
- package/template/core/src/openpress/core/types.ts +94 -41
- package/template/core/src/openpress/core/useSource.ts +1 -1
- package/template/core/src/openpress/{anchorMap.ts → document-model/anchorMapModel.ts} +1 -1
- package/template/core/src/openpress/{indexes.ts → document-model/documentIndexes.ts} +1 -1
- package/template/core/src/openpress/{types.ts → document-model/documentTypes.ts} +51 -0
- package/template/core/src/openpress/document-model/index.ts +7 -0
- package/template/core/src/openpress/document-model/objectEntityModel.ts +55 -0
- package/template/core/src/openpress/{projectIdentity.ts → document-model/projectIdentityModel.ts} +1 -1
- package/template/core/src/openpress/{reactDocumentMetadata.ts → document-model/reactDocumentMetadataModel.ts} +1 -1
- package/template/core/src/openpress/document-model/workspaceManifestModel.ts +57 -0
- package/template/core/src/openpress/manuscript/index.tsx +49 -7
- package/template/core/src/openpress/mdx/index.ts +15 -7
- package/template/core/src/openpress/reader/PageThumbnailsPanel.tsx +168 -0
- package/template/core/src/openpress/{publicPage.tsx → reader/PublicReaderPage.tsx} +31 -51
- package/template/core/src/openpress/{workbenchPanels.tsx → reader/ReaderNavigationPanel.tsx} +6 -5
- package/template/core/src/openpress/reader/index.ts +11 -0
- package/template/core/src/openpress/reader/pageViewportScaleModel.ts +73 -0
- package/template/core/src/openpress/reader/readerTypes.ts +4 -0
- package/template/core/src/openpress/reader/usePageViewportScale.ts +119 -0
- package/template/core/src/openpress/reader/usePanelState.ts +56 -0
- package/template/core/src/openpress/reader/useReaderHashSync.ts +61 -0
- package/template/core/src/openpress/reader/useReaderKeyboardNav.ts +48 -0
- package/template/core/src/openpress/reader/useReaderRuntime.ts +146 -0
- package/template/core/src/openpress/reader/useReaderScrollAnchor.ts +64 -0
- package/template/core/src/openpress/shared/Panel.tsx +77 -0
- package/template/core/src/openpress/shared/index.ts +4 -0
- package/template/core/src/openpress/shared/numberUtils.ts +3 -0
- package/template/core/src/openpress/{runtimeMode.ts → shared/runtimeMode.ts} +0 -11
- package/template/core/src/openpress/workbench/Workbench.tsx +506 -0
- package/template/core/src/openpress/workbench/actions/DeploymentControl.tsx +157 -0
- package/template/core/src/openpress/workbench/actions/ExportImageControl.tsx +96 -0
- package/template/core/src/openpress/workbench/actions/PageZoomControl.tsx +182 -0
- package/template/core/src/openpress/workbench/actions/SearchControl.tsx +345 -0
- package/template/core/src/openpress/workbench/actions/deploymentStatusModel.ts +112 -0
- package/template/core/src/openpress/workbench/actions/index.ts +6 -0
- package/template/core/src/openpress/workbench/actions/useDeploymentWorkbench.ts +136 -0
- package/template/core/src/openpress/workbench/dialog/WorkbenchDialog.tsx +72 -0
- package/template/core/src/openpress/workbench/dialog/index.ts +1 -0
- package/template/core/src/openpress/workbench/document/components/DocumentPanel.tsx +127 -0
- package/template/core/src/openpress/workbench/document/components/InlineSourceEditorLayer.tsx +207 -0
- package/template/core/src/openpress/workbench/document/components/ReaderStage.tsx +9 -0
- package/template/core/src/openpress/workbench/document/hooks/useDocumentWorkbenchModel.ts +34 -0
- package/template/core/src/openpress/workbench/document/hooks/useInlineDocumentEditor.ts +525 -0
- package/template/core/src/openpress/workbench/document/index.ts +10 -0
- package/template/core/src/openpress/workbench/index.ts +2 -0
- package/template/core/src/openpress/workbench/inspector/InlineInspectorLayer.tsx +459 -0
- package/template/core/src/openpress/workbench/inspector/index.ts +5 -0
- package/template/core/src/openpress/workbench/inspector/inlineCommentModel.ts +125 -0
- package/template/core/src/openpress/workbench/inspector/inspectorGeometryModel.ts +160 -0
- package/template/core/src/openpress/workbench/inspector/inspectorModel.ts +408 -0
- package/template/core/src/openpress/workbench/inspector/useInspectorComments.ts +254 -0
- package/template/core/src/openpress/workbench/mentions/MentionSuggestionList.tsx +41 -0
- package/template/core/src/openpress/workbench/mentions/index.ts +2 -0
- package/template/core/src/openpress/{composerMentions.ts → workbench/mentions/useComposerMentions.ts} +1 -4
- package/template/core/src/openpress/workbench/panels/Panel.tsx +1 -0
- package/template/core/src/openpress/workbench/panels/PendingCommentsPanel.tsx +80 -0
- package/template/core/src/openpress/workbench/panels/WorkbenchControlPanel.tsx +29 -0
- package/template/core/src/openpress/workbench/panels/index.ts +3 -0
- package/template/core/src/openpress/workbench/project/ProjectEntryPanel.tsx +525 -0
- package/template/core/src/openpress/workbench/project/ProjectPreviewDialog.tsx +35 -0
- package/template/core/src/openpress/workbench/project/index.ts +2 -0
- package/template/core/src/openpress/workbench/project/projectPreviewTypes.ts +11 -0
- package/template/core/src/openpress/workbench/shell/WorkbenchShell.tsx +167 -0
- package/template/core/src/openpress/workbench/shell/index.ts +1 -0
- package/template/core/src/openpress/workbench/workbenchFormatters.ts +120 -0
- package/template/core/src/openpress/workbench/workbenchTypes.ts +35 -0
- package/template/core/src/styles/openpress/print-route.css +0 -2
- package/template/core/src/styles/openpress/{project-workspace.css → project-preview-panel.css} +13 -407
- package/template/core/src/styles/openpress/public-viewer.css +25 -320
- package/template/core/src/styles/openpress/reader-runtime.css +252 -55
- package/template/core/src/styles/openpress/responsive.css +145 -270
- package/template/core/src/styles/openpress/workbench-panels.css +327 -178
- package/template/core/src/styles/openpress/workbench.css +986 -451
- package/template/core/src/styles/openpress/workspace-gallery.css +300 -0
- package/template/core/src/styles/openpress.css +2 -1
- package/template/core/tsconfig.json +1 -1
- package/template/core/vite.config.ts +50 -0
- package/template/core/engine/commands/init.mjs +0 -24
- package/template/core/engine/init.mjs +0 -90
- package/template/core/src/openpress/App.tsx +0 -127
- package/template/core/src/openpress/inspector.ts +0 -282
- package/template/core/src/openpress/projectWorkspace.tsx +0 -919
- package/template/core/src/openpress/readerRuntime.ts +0 -230
- package/template/core/src/openpress/workbench.tsx +0 -1265
- package/template/core/src/openpress/workbenchTypes.ts +0 -4
- package/template/packs/academic-paper/document/chapters/01-introduction/content/01-introduction.mdx +0 -35
- package/template/packs/academic-paper/document/chapters/02-methods/content/01-methods.mdx +0 -50
- package/template/packs/academic-paper/document/chapters/03-results-and-discussion/content/01-results.mdx +0 -47
- package/template/packs/academic-paper/document/chapters/04-acknowledgment/content/01-acknowledgment.mdx +0 -26
- package/template/packs/academic-paper/document/chapters/05-references/content/01-references.mdx +0 -32
- package/template/packs/academic-paper/document/components/ChapterOpenerVisual/index.tsx +0 -76
- package/template/packs/academic-paper/document/components/Page.tsx +0 -60
- package/template/packs/academic-paper/document/components/TokenSwatchGrid/index.tsx +0 -46
- package/template/packs/academic-paper/document/components/TokenSwatchGrid/style.css +0 -63
- package/template/packs/academic-paper/document/components/TypeSpecimen/index.tsx +0 -38
- package/template/packs/academic-paper/document/components/TypeSpecimen/style.css +0 -111
- package/template/packs/academic-paper/document/design.md +0 -279
- package/template/packs/academic-paper/document/index.tsx +0 -123
- package/template/packs/academic-paper/document/media/README.md +0 -13
- package/template/packs/academic-paper/document/media/figure-placeholder.svg +0 -9
- package/template/packs/academic-paper/document/openpress.config.mjs +0 -26
- package/template/packs/academic-paper/document/theme/README.md +0 -11
- package/template/packs/academic-paper/document/theme/base/page-contract.css +0 -522
- package/template/packs/academic-paper/document/theme/base/print.css +0 -93
- package/template/packs/academic-paper/document/theme/base/typography.css +0 -333
- package/template/packs/academic-paper/document/theme/fonts.css +0 -3
- package/template/packs/academic-paper/document/theme/page-surfaces/back-cover.css +0 -43
- package/template/packs/academic-paper/document/theme/page-surfaces/chapter-opener.css +0 -205
- package/template/packs/academic-paper/document/theme/page-surfaces/cover.css +0 -294
- package/template/packs/academic-paper/document/theme/page-surfaces/toc.css +0 -149
- package/template/packs/academic-paper/document/theme/patterns/_chart-frame.css +0 -49
- package/template/packs/academic-paper/document/theme/patterns/figure-grid.css +0 -68
- package/template/packs/academic-paper/document/theme/patterns/table-utilities.css +0 -66
- package/template/packs/academic-paper/document/theme/shell/reader-controls.css +0 -761
- package/template/packs/academic-paper/document/theme/tokens.css +0 -80
- package/template/packs/academic-paper/openpress.config.mjs +0 -5
- package/template/packs/claude-document/document/chapters/01-document-shape/content/01-document-shape.mdx +0 -51
- package/template/packs/claude-document/document/chapters/02-review-loop/content/01-review-loop.mdx +0 -31
- package/template/packs/claude-document/document/components/ChapterOpenerVisual.tsx +0 -96
- package/template/packs/claude-document/document/components/Page.tsx +0 -37
- package/template/packs/claude-document/document/design.md +0 -142
- package/template/packs/claude-document/document/index.tsx +0 -94
- package/template/packs/claude-document/document/media/README.md +0 -13
- package/template/packs/claude-document/document/openpress.config.mjs +0 -26
- package/template/packs/claude-document/document/theme/README.md +0 -15
- package/template/packs/claude-document/document/theme/base/page-contract.css +0 -525
- package/template/packs/claude-document/document/theme/base/print.css +0 -93
- package/template/packs/claude-document/document/theme/base/typography.css +0 -612
- package/template/packs/claude-document/document/theme/fonts.css +0 -4
- package/template/packs/claude-document/document/theme/page-surfaces/back-cover.css +0 -72
- package/template/packs/claude-document/document/theme/page-surfaces/chapter-opener.css +0 -236
- package/template/packs/claude-document/document/theme/page-surfaces/cover.css +0 -309
- package/template/packs/claude-document/document/theme/page-surfaces/toc.css +0 -225
- package/template/packs/claude-document/document/theme/patterns/_chart-frame.css +0 -53
- package/template/packs/claude-document/document/theme/patterns/figure-grid.css +0 -68
- package/template/packs/claude-document/document/theme/patterns/table-utilities.css +0 -66
- package/template/packs/claude-document/document/theme/shell/reader-controls.css +0 -789
- package/template/packs/claude-document/document/theme/tokens.css +0 -89
- package/template/packs/claude-document/openpress.config.mjs +0 -5
- package/template/packs/editorial-monograph/document/chapters/01-product-and-use-cases/content/01-product-and-use-cases.mdx +0 -31
- package/template/packs/editorial-monograph/document/chapters/02-workflow/content/01-workflow.mdx +0 -89
- package/template/packs/editorial-monograph/document/chapters/03-agent-skills-contributors/content/01-agent-skills-contributors.mdx +0 -51
- package/template/packs/editorial-monograph/document/chapters/04-validation-deploy/content/01-validation-deploy.mdx +0 -39
- package/template/packs/editorial-monograph/document/components/ChapterOpenerVisual/index.tsx +0 -76
- package/template/packs/editorial-monograph/document/components/Page.tsx +0 -37
- package/template/packs/editorial-monograph/document/components/TokenSwatchGrid/index.tsx +0 -46
- package/template/packs/editorial-monograph/document/components/TokenSwatchGrid/style.css +0 -63
- package/template/packs/editorial-monograph/document/components/TypeSpecimen/index.tsx +0 -38
- package/template/packs/editorial-monograph/document/components/TypeSpecimen/style.css +0 -111
- package/template/packs/editorial-monograph/document/design.md +0 -279
- package/template/packs/editorial-monograph/document/index.tsx +0 -97
- package/template/packs/editorial-monograph/document/media/README.md +0 -13
- package/template/packs/editorial-monograph/document/openpress.config.mjs +0 -26
- package/template/packs/editorial-monograph/document/theme/README.md +0 -11
- package/template/packs/editorial-monograph/document/theme/base/page-contract.css +0 -505
- package/template/packs/editorial-monograph/document/theme/base/print.css +0 -93
- package/template/packs/editorial-monograph/document/theme/base/typography.css +0 -336
- package/template/packs/editorial-monograph/document/theme/fonts.css +0 -3
- package/template/packs/editorial-monograph/document/theme/page-surfaces/back-cover.css +0 -43
- package/template/packs/editorial-monograph/document/theme/page-surfaces/chapter-opener.css +0 -205
- package/template/packs/editorial-monograph/document/theme/page-surfaces/cover.css +0 -147
- package/template/packs/editorial-monograph/document/theme/page-surfaces/toc.css +0 -149
- package/template/packs/editorial-monograph/document/theme/patterns/_chart-frame.css +0 -49
- package/template/packs/editorial-monograph/document/theme/patterns/figure-grid.css +0 -68
- package/template/packs/editorial-monograph/document/theme/patterns/table-utilities.css +0 -66
- package/template/packs/editorial-monograph/document/theme/shell/reader-controls.css +0 -761
- package/template/packs/editorial-monograph/document/theme/tokens.css +0 -80
- package/template/packs/editorial-monograph/openpress.config.mjs +0 -5
- /package/template/core/src/openpress/{readerPageRegistry.ts → reader/readerPageRegistry.ts} +0 -0
- /package/template/core/src/openpress/{pageRoute.ts → reader/readerPageRoute.ts} +0 -0
- /package/template/core/src/openpress/{readerScroll.ts → reader/readerScroll.ts} +0 -0
- /package/template/core/src/openpress/{readerState.ts → reader/readerStateModel.ts} +0 -0
- /package/template/core/src/openpress/{frameScheduler.ts → shared/frameScheduler.ts} +0 -0
- /package/template/core/src/openpress/{projectSources.ts → workbench/project/projectSourceModel.ts} +0 -0
|
@@ -1,11 +1,67 @@
|
|
|
1
1
|
# @open-press/core
|
|
2
2
|
|
|
3
|
+
## 1.0.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- 8c528ad: 1.0 contract release. Breaking changes:
|
|
8
|
+
- `<Workspace>` is now required at the root of `press/index.tsx`; `<Press>` lives as a child, and multi-Press workspaces are first-class (each `<Press>` exports to `/openpress/<slug>/document.json`).
|
|
9
|
+
- Document metadata (`title` / `subtitle` / `organization` / `page` / `sources` / `captionNumbering`) moves onto `<Press>` JSX props. `export const config` and `export const sources` are removed.
|
|
10
|
+
- `openpress.config.mjs` is removed. Operational settings (deploy / pdf) live in the workspace `package.json` under the `"openpress"` field; paths are convention (`press/`, `press/<slug>/chapters/`, `press/theme/`, `public/openpress/`, `dist-react/`).
|
|
11
|
+
- Workspace folder renamed from `document/` → `press/`. The dogfood and starter skills are migrated.
|
|
12
|
+
- Reader gains a workspace gallery for multi-Press projects, per-page PNG export, page thumbnails for canvas-style Press, and a back-to-workspace button.
|
|
13
|
+
- New built-in page presets `a4`, `social-square`, `slide-16-9` and improved init metadata propagation.
|
|
14
|
+
|
|
15
|
+
## 0.8.0
|
|
16
|
+
|
|
17
|
+
### Minor Changes
|
|
18
|
+
|
|
19
|
+
- **Workbench architecture**: the monolithic `workbench.tsx` is split into a modular structure under `workbench/{shell,panels,actions,inspector,mentions,project,document}/`. New panels: `DeploymentControl`, `SearchControl`, `PendingCommentsPanel`, `DocumentPanel`, `ProjectEntryPanel`, plus `WorkbenchShell` and `InlineInspectorLayer`.
|
|
20
|
+
- **Module reorganization**: source tree split into typed subdirectories:
|
|
21
|
+
- `app/`: `OpenPressApp`, `OpenPressRuntime` (replaces the old `App.tsx` + `renderer.tsx`)
|
|
22
|
+
- `document-model/`: `anchorMap`, `documentIndexes`, `documentTypes`, `objectEntityModel`, `projectIdentity`, `reactDocumentMetadata`
|
|
23
|
+
- `reader/`: `PublicReaderPage`, `ReaderNavigationPanel`, `useReaderRuntime`, registry/route/scroll/state helpers
|
|
24
|
+
- `shared/`: `frameScheduler`, `runtimeMode`, `Panel`, `numberUtils`
|
|
25
|
+
- **Object-entity model**: `Frame` and `MdxArea` now expose `data-openpress-object-id`. New `document-model/objectEntityModel` defines the id format.
|
|
26
|
+
- **`MediaFigure` / `ImageFigure`**: new core primitives that accept `src/alt/caption` and resolve relative paths to `/openpress/media/...` automatically.
|
|
27
|
+
- **`<Sections>` default page**: `page` prop becomes optional; when omitted the built-in `DefaultSectionPage` renders the standard manuscript frame.
|
|
28
|
+
- **Engine helpers**: new `engine/react/{http-json,object-entities,source-edit-endpoint}.mjs` and `engine/runtime/{file-walk,path-utils}.mjs` runtime helpers. `engine/runtime/source-text-tools` exports TypeScript definitions.
|
|
29
|
+
- **Dev endpoints**: vite plugin wires `/__openpress/search` and `/__openpress/source-edit` middlewares for the new workbench search + inline editing flows.
|
|
30
|
+
- **Inline source editor**: ships the `InlineSourceEditorLayer` UI on top of `useInlineDocumentEditor` + `/__openpress/source-edit`. The hook now uses a `MutationObserver` so newly inserted blocks become editable, and routes mouse clicks through `focus()` to preserve selection on `contenteditable` boundaries. Workbench wires `sourceEditorTarget` state into the layer.
|
|
31
|
+
- **Table editing in the source pipeline**: table captions are emitted as standalone source blocks (`kind=element`, `name=caption`, `layout="attached"`) with `data-openpress-block-id`/`data-openpress-object-id` markers and preserved source positions; the allocator treats `layout="attached"` blocks as non-paginable. `applySourceBlockTableCellEditToText` (in `engine/runtime/source-text-tools`) accepts a `cellIndex` so the inline source editor can target a single `<td>`.
|
|
32
|
+
- **Reader pagination**: arrow-key pagination now defers to the user's active text selection. Shift-arrow / mouse-drag selections no longer get swallowed by the page-turn shortcut.
|
|
33
|
+
- **Page zoom + spread layout**: new `reader/pageViewportScaleModel` + `usePageViewportScale` hook drive a `--openpress-page-viewport-scale` CSS variable on the page container; the workbench toolbar exposes a `PageZoomControl` dropdown with fit-width / fit-page / fixed percentages plus a one-page / two-page spread toggle.
|
|
34
|
+
- **Inspector cell-precision comments**: `CommentDraft` gains an optional `targetObjectId` so a comment can point at a sub-block (e.g. a single table cell) while still attributing the source position to its enclosing block. `formatInspectorHint` carries the value through to the wire hint.
|
|
35
|
+
- **Shared `WorkbenchDialog` shell**: portal + backdrop + header (eyebrow / title / title-meta / close) + optional footer. `DeploymentControl`, `SearchControl`, and `ProjectPreviewDialog` all render through this shell now, replacing the prior per-dialog scaffolding under `openpress-deploy-dialog-*` / `openpress-search-dialog-*` / `openpress-project-preview-dialog__*`.
|
|
36
|
+
- **`WorkbenchControlPanel` registry**: `HtmlWorkbench` now accepts an `extraControlPanels?: WorkbenchPanel[]` prop and renders the right-side panel from a `{ id, render }` registry. Built-in panels (pending comments, project entry) ship as the first entries.
|
|
37
|
+
- **Workbench state hooks**: extract `useDeploymentWorkbench` and `useInspectorComments` from `HtmlWorkbench`; `useReaderRuntime` is split into focused sub-hooks (`usePanelState`, `useReaderScrollAnchor`, `useReaderHashSync`, `useReaderKeyboardNav`).
|
|
38
|
+
- **`InlineInspectorLayer` memoization**: now wrapped in `React.memo` with a stable `geometryVersion` prop so the geometry / event listeners no longer rebuild on every parent render.
|
|
39
|
+
- **Panels open lazily**: `usePanelState` now defaults both panels closed, so the reader opens with a clean stage; resize never auto-opens them.
|
|
40
|
+
|
|
41
|
+
### Patch Changes
|
|
42
|
+
|
|
43
|
+
- Inspector: fix comment-marker count and multi-target marker rendering.
|
|
44
|
+
- Inspector: object-entity id helpers consolidate in `document-model/objectEntityModel` instead of being duplicated inside `Frame`, `MdxArea`, manuscript `TocArea`, and `PublicReaderPage`.
|
|
45
|
+
- Inline editor: `useInlineDocumentEditor` exposes `onDocumentEdited`; `OpenPressApp` re-loads `/openpress/document.json` after a successful inline edit so derived indexes stay in sync.
|
|
46
|
+
- Dev: reset Vite optimizer cache so workspace-side dependencies are picked up.
|
|
47
|
+
- Workbench dialog: viewport-aware width + max-height so a big media preview doesn't blow up the dialog to full screen.
|
|
48
|
+
- Project composer: add `/apply-comments` to the skill mention list so pending comment resolution can be invoked from the workbench.
|
|
49
|
+
- Carries forward the 0.7.1 measurement + pagination fixes (font/image readiness, relative media src inlining, list-per-item paging, `OPENPRESS_DEBUG_ALLOC`, academic-paper starter body overflow).
|
|
50
|
+
|
|
51
|
+
### Breaking Changes
|
|
52
|
+
|
|
53
|
+
- `FrameContext.consumeArea(chainId)` return type changes from `ReactNode | null` to `{ indexInFrame: number; blocks: ReactNode | null }`. Custom `Frame` consumers must read `.blocks`.
|
|
54
|
+
- `App` export is renamed to `OpenPressApp` and now lives under `@open-press/core/app`. The old `renderer.tsx` is replaced by `OpenPressRuntime`.
|
|
55
|
+
- `data-openpress-mdx-area-empty` is now always emitted (`"true"` / `"false"`). Selectors that relied on the attribute being absent need updating.
|
|
56
|
+
- Reader `ViewMode` collapses to `"paged"` only — the legacy `"reading"` flow mode is removed. Use `usePageViewportScale` for free-scaling instead.
|
|
57
|
+
- Several internal module paths moved into subdirectories (`document-model/`, `reader/`, `shared/`, `workbench/...`). Consumers that deep-imported from the openpress source must switch to the new barrels.
|
|
58
|
+
- Shared dialog scaffolding (backdrop, container, header, close button) moved from per-dialog class families (`openpress-deploy-dialog-backdrop`, `__panel`, `__panel header`, `__close`, etc.) to the shared `openpress-workbench-dialog*` family. Per-dialog modifier classes (`openpress-deploy-dialog`, `openpress-search-dialog`, `openpress-project-preview-dialog`) are still applied for dialog-specific styling. Selectors that targeted the old scaffolding names (notably `*-backdrop` and `__panel`) need updating; selectors that combine the modifier class with new `__heading` / `__footer` / `__close` modifiers continue to work.
|
|
59
|
+
|
|
3
60
|
## 0.7.1
|
|
4
61
|
|
|
5
62
|
### Patch Changes
|
|
6
63
|
|
|
7
64
|
- Measurement pipeline + pagination fixes:
|
|
8
|
-
|
|
9
65
|
- **Measurement**: wait on `document.fonts.ready`, image `load`/`error` + `decode()`,
|
|
10
66
|
and two `requestAnimationFrame` ticks before sampling block heights so figures
|
|
11
67
|
no longer under-measure on cold loads.
|
|
@@ -27,7 +83,6 @@
|
|
|
27
83
|
- 718d2d1: **Press Tree render architecture** — full refresh of the React export pipeline (clean break, no v0.5 compatibility).
|
|
28
84
|
|
|
29
85
|
The render kernel no longer knows about `cover`, `toc`, `chapter`, or `back-cover` as built-in concepts. Workspaces describe their document as a React tree using three primitives:
|
|
30
|
-
|
|
31
86
|
- `Press` — root composition boundary.
|
|
32
87
|
- `Frame` — a single fixed-layout surface (replaces `BasePage` and friends).
|
|
33
88
|
- `MdxArea` — a measurable slot consuming a content chain, with `overflow="extend|truncate|error"` control.
|
|
@@ -62,7 +117,6 @@
|
|
|
62
117
|
MDX source resolution now derives manuscript TOC entries from actual `##` / `###` headings, not folder slugs. Heading numbering is written during export as `data-chapter="01"` / `data-section="1.1"` attributes so themes can render numbering with CSS without reader-side mutation.
|
|
63
118
|
|
|
64
119
|
**Removed (no compatibility layer):**
|
|
65
|
-
|
|
66
120
|
- `BasePage`, `BaseCoverPage`, `BaseTocPage`, `BaseContentPage`, `BaseBackCoverPage`.
|
|
67
121
|
- Legacy named exports (`cover`, `toc`, `backCover`) from `document/index.tsx`.
|
|
68
122
|
- The `migrate-to-react` CLI command.
|
|
@@ -74,15 +128,12 @@
|
|
|
74
128
|
All `<Frame>` instances require a stable `frameKey`; source roots and file-list entries must stay inside `document/`.
|
|
75
129
|
|
|
76
130
|
**Workspace data attributes:**
|
|
77
|
-
|
|
78
131
|
- `data-frame-role` (new, opaque role like `"manuscript.content"`).
|
|
79
132
|
- `data-page-kind` (derived from role's last segment — reader CSS keeps using this).
|
|
80
133
|
- `data-section-id` replaces `data-chapter-slug` for section-scoped CSS.
|
|
81
134
|
|
|
82
135
|
**Migration:** Workspaces written for v0.5.x must rewrite `document/index.tsx` to default-export a Press component. Pre-1.0 minor bump is acceptable per repo policy; no production deployments exist to break.
|
|
83
136
|
|
|
84
|
-
See `docs/superpowers/specs/2026-05-23-press-tree-render-architecture-design.md` for full design rationale.
|
|
85
|
-
|
|
86
137
|
## 0.6.0
|
|
87
138
|
|
|
88
139
|
### Minor Changes
|
|
@@ -123,7 +174,6 @@
|
|
|
123
174
|
- 0169cba: Agent-driven upgrade flow.
|
|
124
175
|
|
|
125
176
|
**New commands:**
|
|
126
|
-
|
|
127
177
|
- `npx open-press doctor` — diagnose workspace against latest framework state. Reports `@open-press/core` version vs npm latest, installed skill count, and any pending `docs/migrations/<version>.md` notes between current and latest. `--json` for machine-readable output, `--no-cache` to bypass the 24h cache. Always exits 0 (informational only).
|
|
128
178
|
|
|
129
179
|
- `npx open-press upgrade` — orchestrate the upgrade. Runs `npm update @open-press/core` (when the workspace declares the dep) and `npx skills upgrade`, then surfaces the list of migration notes for the agent to read. **Does not auto-edit `document/` content** — the agent reads the surfaced `docs/migrations/<version>.md` notes and proposes edits to the user with confirmation. Use `--dry-run` to preview, `--no-deps` / `--no-skills` to target one layer.
|
|
@@ -133,7 +183,6 @@
|
|
|
133
183
|
`open-press dev` now runs `doctor` before starting Vite. When the workspace is behind, a single line prints: `○ open-press: @open-press/core 0.4.0 → 0.5.0 · 1 migration note(s) — run npx open-press doctor for details.` Cached for 24h, network failure is silent, never blocks dev.
|
|
134
184
|
|
|
135
185
|
**Migration docs:**
|
|
136
|
-
|
|
137
186
|
- New `docs/migrations/_template.md` — each release with breaking changes ships a `docs/migrations/<version>.md` file with sections the agent reads.
|
|
138
187
|
- New `docs/migrations/0.4.0.md` — backfilled. Documents the SKILL fold (no document or CLI changes).
|
|
139
188
|
|
|
@@ -150,7 +199,6 @@
|
|
|
150
199
|
### Minor Changes
|
|
151
200
|
|
|
152
201
|
- 3cb4939: Consolidate internal skills (13 → 11).
|
|
153
|
-
|
|
154
202
|
- `openpress-update` folded into `openpress` as an "Updating An Existing Workspace" section. The release-upgrade flow, pre-flight checks, breaking-change reference, and do-not list are now part of the system-operation skill where they naturally belong.
|
|
155
203
|
- `openpress-document-hierarchy` folded into `openpress-writing` as a "Hierarchy" section. Hierarchy decisions (H2/H3/H4 model, TOC depth, appendix placement, H4 granularity) and prose decisions happen in the same workflow; one skill, one routing decision.
|
|
156
204
|
- `references/data-structures-outline.md` moved from the hierarchy skill into `openpress-writing/references/`.
|
package/template/core/README.md
CHANGED
|
@@ -5,10 +5,10 @@ Framework runtime, CLI engine, and Press Tree primitives for [open-press](https:
|
|
|
5
5
|
Most users do **not** install this package directly. Instead, scaffold a workspace with the CLI:
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
npx @open-press/cli init my-doc
|
|
8
|
+
npx @open-press/cli init my-doc
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
The scaffolded workspace contains a snapshot of this package.
|
|
11
|
+
The scaffolded workspace contains a snapshot of this package. Starter files are supplied by skills, not by `@open-press/core`.
|
|
12
12
|
|
|
13
13
|
## Direct use
|
|
14
14
|
|
|
@@ -31,7 +31,10 @@ import { mdxSource } from "@open-press/core/mdx";
|
|
|
31
31
|
import { Sections, Toc } from "@open-press/core/manuscript";
|
|
32
32
|
```
|
|
33
33
|
|
|
34
|
-
`document/index.tsx` default-exports a `<Press>` tree. `Frame` marks fixed-layout pages, `MdxArea` receives measured MDX blocks, and `mdxSource()` declares which MDX files participate in the render pipeline.
|
|
34
|
+
`press/index.tsx` or transitional `document/index.tsx` default-exports a `<Workspace>/<Press>` tree. `Frame` marks fixed-layout pages, `MdxArea` receives measured MDX blocks, and `mdxSource()` declares which MDX files participate in the render pipeline.
|
|
35
|
+
|
|
36
|
+
For the maintenance contract around Press Tree, page geometry presets, and the
|
|
37
|
+
allocation pipeline, see [`docs/press-tree.md`](https://github.com/quan0715/open-press/blob/main/docs/press-tree.md).
|
|
35
38
|
|
|
36
39
|
The CLI bin (`open-press`) supports dev / build / preview / validate / pdf / deploy / export commands. It requires a workspace with `openpress.config.mjs` and the surrounding framework files (which the scaffolder installs).
|
|
37
40
|
|
|
@@ -4,25 +4,25 @@ import * as deployCmd from "./commands/deploy.mjs";
|
|
|
4
4
|
import * as devCmd from "./commands/dev.mjs";
|
|
5
5
|
import * as doctorCmd from "./commands/doctor.mjs";
|
|
6
6
|
import * as exportCmd from "./commands/export.mjs";
|
|
7
|
-
import * as initCmd from "./commands/init.mjs";
|
|
8
7
|
import * as inspectCmd from "./commands/inspect.mjs";
|
|
8
|
+
import * as imageCmd from "./commands/image.mjs";
|
|
9
9
|
import * as pdfCmd from "./commands/pdf.mjs";
|
|
10
10
|
import * as previewCmd from "./commands/preview.mjs";
|
|
11
11
|
import * as replaceCmd from "./commands/replace.mjs";
|
|
12
12
|
import * as renderCmd from "./commands/render.mjs";
|
|
13
13
|
import * as searchCmd from "./commands/search.mjs";
|
|
14
|
+
import * as skillsSyncCmd from "./commands/skills-sync.mjs";
|
|
14
15
|
import * as typecheckCmd from "./commands/typecheck.mjs";
|
|
15
16
|
import * as upgradeCmd from "./commands/upgrade.mjs";
|
|
16
17
|
import * as validateCmd from "./commands/validate.mjs";
|
|
17
18
|
import { parseOptions } from "./commands/_shared.mjs";
|
|
18
19
|
import { loadConfig } from "./runtime/config.mjs";
|
|
19
|
-
import { listStylePackSkills } from "./init.mjs";
|
|
20
20
|
import { discoverWorkspace } from "./runtime/validation.mjs";
|
|
21
21
|
|
|
22
22
|
const COMMANDS = {
|
|
23
|
-
init: initCmd,
|
|
24
23
|
validate: validateCmd,
|
|
25
24
|
inspect: inspectCmd,
|
|
25
|
+
image: imageCmd,
|
|
26
26
|
search: searchCmd,
|
|
27
27
|
replace: replaceCmd,
|
|
28
28
|
export: exportCmd,
|
|
@@ -34,6 +34,8 @@ const COMMANDS = {
|
|
|
34
34
|
deploy: deployCmd,
|
|
35
35
|
doctor: doctorCmd,
|
|
36
36
|
upgrade: upgradeCmd,
|
|
37
|
+
migrate: upgradeCmd,
|
|
38
|
+
"skills:sync": skillsSyncCmd,
|
|
37
39
|
};
|
|
38
40
|
|
|
39
41
|
const args = process.argv.slice(2);
|
|
@@ -71,12 +73,9 @@ async function main(commandName, argv) {
|
|
|
71
73
|
}
|
|
72
74
|
|
|
73
75
|
async function printHelp() {
|
|
74
|
-
const packs = await listStylePackSkills();
|
|
75
|
-
const skillList = packs.length ? packs.join(" | ") : "(none installed)";
|
|
76
76
|
console.log(`Usage: node engine/cli.mjs <command> [path] [options]
|
|
77
77
|
|
|
78
78
|
Commands:
|
|
79
|
-
init <target> [--skill <name>] [--force]
|
|
80
79
|
validate
|
|
81
80
|
inspect [--json] [--no-build] [--dry-run]
|
|
82
81
|
search [path] <query> [--json] [--scope content|all]
|
|
@@ -86,11 +85,12 @@ Commands:
|
|
|
86
85
|
preview --renderer react [--host 127.0.0.1] [--port 5173] [--no-build] [--dry-run]
|
|
87
86
|
dev --renderer react [--host 127.0.0.1] [--port 5173] [--no-build] [--dry-run]
|
|
88
87
|
typecheck
|
|
88
|
+
image [--output <outputDir>] [--no-build] [--dry-run]
|
|
89
89
|
pdf [--output <outputDir>/<pdf.filename>] [--no-build] [--dry-run]
|
|
90
90
|
deploy --confirm [--dry-run]
|
|
91
91
|
doctor [--json] [--no-cache] # version + skill staleness check
|
|
92
92
|
upgrade [--dry-run] [--no-deps] [--no-skills] [--json] # apply updates; agent-driven
|
|
93
|
-
|
|
94
|
-
|
|
93
|
+
migrate [--dry-run] [--no-deps] [--no-skills] [--json] # alias for upgrade; reads migration notes
|
|
94
|
+
skills:sync [--source <owner/repo>] [--dry-run] # refresh installed agent skills
|
|
95
95
|
`);
|
|
96
96
|
}
|
|
@@ -2,7 +2,7 @@ import { spawn, spawnSync } from "node:child_process";
|
|
|
2
2
|
import fs from "node:fs/promises";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
|
-
import { printUrlToPdf, stopChildProcess, waitForPrintReady } from "../output/chrome-pdf.mjs";
|
|
5
|
+
import { captureUrlPagesToPng, printUrlToPdf, stopChildProcess, waitForPrintReady } from "../output/chrome-pdf.mjs";
|
|
6
6
|
import { loadConfig, publicPdfHref } from "../runtime/config.mjs";
|
|
7
7
|
import { exportDocument } from "../document-export.mjs";
|
|
8
8
|
import { optimizePdfMediaForStaticRoot } from "../output/pdf-media.mjs";
|
|
@@ -23,6 +23,9 @@ export function parseOptions(argv) {
|
|
|
23
23
|
else if (value === "--force") options.force = true;
|
|
24
24
|
else if (value === "--confirm") options.confirm = true;
|
|
25
25
|
else if (value === "--json") options.json = true;
|
|
26
|
+
else if (value === "--no-cache") options.noCache = true;
|
|
27
|
+
else if (value === "--no-deps") options.noDeps = true;
|
|
28
|
+
else if (value === "--no-skills") options.noSkills = true;
|
|
26
29
|
else if (value === "--no-build") options.noBuild = true;
|
|
27
30
|
else if (value === "--apply") options.apply = true;
|
|
28
31
|
else if (value === "--include-code") options.includeCode = true;
|
|
@@ -38,20 +41,6 @@ export function parseOptions(argv) {
|
|
|
38
41
|
return options;
|
|
39
42
|
}
|
|
40
43
|
|
|
41
|
-
export function parseInitOptions(argv) {
|
|
42
|
-
const options = { force: false };
|
|
43
|
-
const positional = [];
|
|
44
|
-
for (let i = 0; i < argv.length; i += 1) {
|
|
45
|
-
const value = argv[i];
|
|
46
|
-
if (value === "--skill") options.skill = argv[++i];
|
|
47
|
-
else if (value === "--force") options.force = true;
|
|
48
|
-
else if (value.startsWith("--")) throw new Error(`Unknown option: ${value}`);
|
|
49
|
-
else positional.push(value);
|
|
50
|
-
}
|
|
51
|
-
options.target = positional[0];
|
|
52
|
-
return options;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
44
|
export function formatDisplayPath(absolutePath) {
|
|
56
45
|
const relative = path.relative(process.cwd(), absolutePath);
|
|
57
46
|
if (!relative || relative.startsWith("..")) return absolutePath;
|
|
@@ -118,6 +107,39 @@ export async function buildReactPdf({
|
|
|
118
107
|
return { pdfPath: outPath };
|
|
119
108
|
}
|
|
120
109
|
|
|
110
|
+
export async function buildReactImages({
|
|
111
|
+
root,
|
|
112
|
+
config,
|
|
113
|
+
outDir,
|
|
114
|
+
host = "127.0.0.1",
|
|
115
|
+
port = "5186",
|
|
116
|
+
noBuild = false,
|
|
117
|
+
recurse,
|
|
118
|
+
}) {
|
|
119
|
+
config ??= await loadConfig(root);
|
|
120
|
+
outDir ??= path.join(config.paths.outputDir, "images");
|
|
121
|
+
const renderCode = await buildReactStatic({ root, noBuild, recurse });
|
|
122
|
+
if (renderCode !== 0) throw new Error(`React render failed with exit code ${renderCode}`);
|
|
123
|
+
await fs.mkdir(outDir, { recursive: true });
|
|
124
|
+
|
|
125
|
+
const server = await startStaticServer(root, config, host, port);
|
|
126
|
+
try {
|
|
127
|
+
const result = await captureUrlPagesToPng({
|
|
128
|
+
root,
|
|
129
|
+
url: `http://${host}:${port}/?print=1`,
|
|
130
|
+
outDir,
|
|
131
|
+
waitForReady: waitForPrintReady,
|
|
132
|
+
debuggingPortBase: 9700,
|
|
133
|
+
debuggingPortRange: 600,
|
|
134
|
+
profilePrefix: "chrome-image",
|
|
135
|
+
});
|
|
136
|
+
console.log(`${result.files.length} OpenPress pages exported to PNG`);
|
|
137
|
+
return { outDir, files: result.files, pageCount: result.pageCount };
|
|
138
|
+
} finally {
|
|
139
|
+
await stopChildProcess(server);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
121
143
|
export function startStaticServer(root, config, host, port) {
|
|
122
144
|
return new Promise((resolve, reject) => {
|
|
123
145
|
const child = spawn("node", [STATIC_SERVER, config.outputDir, "--host", host, "--port", port, "--workspace", "."], {
|
|
@@ -16,7 +16,7 @@ export async function run({ root, options }) {
|
|
|
16
16
|
if (!options.noBuild) {
|
|
17
17
|
console.log(`Command: ${formatNodeScriptCommand(root, CLI_ENTRY)} export .`);
|
|
18
18
|
}
|
|
19
|
-
console.log(`Command: npx vite --config vite.config.ts --host ${host} --port ${port}`);
|
|
19
|
+
console.log(`Command: npx vite --force --config vite.config.ts --host ${host} --port ${port}`);
|
|
20
20
|
return 0;
|
|
21
21
|
}
|
|
22
22
|
if (!options.noBuild) {
|
|
@@ -27,7 +27,7 @@ export async function run({ root, options }) {
|
|
|
27
27
|
await printDoctorNoticeIfStale(root);
|
|
28
28
|
|
|
29
29
|
console.log(`OpenPress dev: ${url}`);
|
|
30
|
-
return runCommand("npx", ["vite", "--config", "vite.config.ts", "--host", host, "--port", port], root);
|
|
30
|
+
return runCommand("npx", ["vite", "--force", "--config", "vite.config.ts", "--host", host, "--port", port], root);
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
async function printDoctorNoticeIfStale(root) {
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { CLI_ENTRY, STATIC_SERVER, buildReactImages, formatNodeScriptCommand } from "./_shared.mjs";
|
|
3
|
+
|
|
4
|
+
export async function run({ root, config, options, recurse }) {
|
|
5
|
+
const outputDir = options.output ? path.resolve(root, options.output) : path.join(config.paths.outputDir, "images");
|
|
6
|
+
const host = options.host ?? "127.0.0.1";
|
|
7
|
+
const port = options.port ?? "5186";
|
|
8
|
+
|
|
9
|
+
if (options.dryRun) {
|
|
10
|
+
console.log(`Command: ${formatNodeScriptCommand(root, CLI_ENTRY)} render . --renderer react`);
|
|
11
|
+
console.log(`Command: ${formatNodeScriptCommand(root, STATIC_SERVER)} ${config.outputDir} --host ${host} --port ${port} --workspace .`);
|
|
12
|
+
console.log(`Chrome image export URL: http://${host}:${port}/?print=1`);
|
|
13
|
+
console.log(`Output: ${path.relative(root, path.join(outputDir, "page-001.png"))}`);
|
|
14
|
+
return 0;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const result = await buildReactImages({
|
|
18
|
+
root,
|
|
19
|
+
config,
|
|
20
|
+
outDir: outputDir,
|
|
21
|
+
host,
|
|
22
|
+
port,
|
|
23
|
+
noBuild: options.noBuild,
|
|
24
|
+
recurse,
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
console.log(`OpenPress images: ${path.relative(root, result.outDir)} (${result.files.length} pages)`);
|
|
28
|
+
return 0;
|
|
29
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { existsSync } from "node:fs";
|
|
3
|
+
import { readFile } from "node:fs/promises";
|
|
4
|
+
import { runCommand } from "./_shared.mjs";
|
|
5
|
+
|
|
6
|
+
const DEFAULT_SOURCE = "quan0715/open-press";
|
|
7
|
+
|
|
8
|
+
// Refresh installed agent skills against the workspace's lock file.
|
|
9
|
+
// Behavior:
|
|
10
|
+
// - If skills-lock.json exists, run `npx skills upgrade` (refreshes all
|
|
11
|
+
// currently-installed sources to their latest published versions).
|
|
12
|
+
// - If skills-lock.json is missing, install the OpenPress framework
|
|
13
|
+
// skill bundle (and any user-supplied --source) as a first-time setup.
|
|
14
|
+
// - If a --source flag is passed, also add that source on top of any
|
|
15
|
+
// existing installations.
|
|
16
|
+
//
|
|
17
|
+
// Always exits 0 unless the underlying `skills` tool fails.
|
|
18
|
+
export async function run({ root, options }) {
|
|
19
|
+
const lockPath = path.join(root, "skills-lock.json");
|
|
20
|
+
const lockExists = existsSync(lockPath);
|
|
21
|
+
const extraSource = options?.source;
|
|
22
|
+
|
|
23
|
+
if (options?.dryRun) {
|
|
24
|
+
if (lockExists) {
|
|
25
|
+
console.log("Command: npx -y skills@latest upgrade");
|
|
26
|
+
} else {
|
|
27
|
+
console.log(`Command: npx -y skills@latest add ${DEFAULT_SOURCE}`);
|
|
28
|
+
}
|
|
29
|
+
if (extraSource) {
|
|
30
|
+
console.log(`Command: npx -y skills@latest add ${extraSource}`);
|
|
31
|
+
}
|
|
32
|
+
return 0;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (lockExists) {
|
|
36
|
+
const sources = await readLockSources(lockPath);
|
|
37
|
+
if (sources.length === 0) {
|
|
38
|
+
console.log("skills-lock.json has no sources; installing framework default…");
|
|
39
|
+
const code = await runCommand("npx", ["-y", "skills@latest", "add", DEFAULT_SOURCE], root);
|
|
40
|
+
if (code !== 0) return code;
|
|
41
|
+
} else {
|
|
42
|
+
console.log(`Refreshing ${sources.length} installed source(s)…`);
|
|
43
|
+
for (const src of sources) console.log(` ${src}`);
|
|
44
|
+
const code = await runCommand("npx", ["-y", "skills@latest", "upgrade"], root);
|
|
45
|
+
if (code !== 0) return code;
|
|
46
|
+
}
|
|
47
|
+
} else {
|
|
48
|
+
console.log(`No skills-lock.json; installing framework default: ${DEFAULT_SOURCE}`);
|
|
49
|
+
const code = await runCommand("npx", ["-y", "skills@latest", "add", DEFAULT_SOURCE], root);
|
|
50
|
+
if (code !== 0) return code;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (extraSource) {
|
|
54
|
+
console.log(`Adding extra source: ${extraSource}`);
|
|
55
|
+
const code = await runCommand("npx", ["-y", "skills@latest", "add", extraSource], root);
|
|
56
|
+
if (code !== 0) return code;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
console.log("✓ Skills synced");
|
|
60
|
+
return 0;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
async function readLockSources(lockPath) {
|
|
64
|
+
try {
|
|
65
|
+
const lock = JSON.parse(await readFile(lockPath, "utf8"));
|
|
66
|
+
const sources = Array.isArray(lock?.sources) ? lock.sources : [];
|
|
67
|
+
return sources.map((s) => s?.source).filter((s) => typeof s === "string");
|
|
68
|
+
} catch {
|
|
69
|
+
return [];
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -1,5 +1,67 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { createRequire } from "node:module";
|
|
1
4
|
import { runCommand } from "./_shared.mjs";
|
|
2
5
|
|
|
6
|
+
// Run typecheck via the locally installed typescript. The previous
|
|
7
|
+
// implementation used `npx tsc`; npm 11 + Node 24 (our CI / release
|
|
8
|
+
// pin) changed npx's bin lookup so it no longer walks pnpm's nested
|
|
9
|
+
// `.bin/` symlink farm and falls back to fetching the legacy
|
|
10
|
+
// `tsc@2.0.4` shim, which crashes.
|
|
11
|
+
//
|
|
12
|
+
// Resolution order:
|
|
13
|
+
// 1. `node <resolved tsc>` via require.resolve(typescript/package.json)
|
|
14
|
+
// — works with npm-hoisted layouts and most pnpm installs.
|
|
15
|
+
// 2. Walk up node_modules/.bin/tsc — covers downstream npm/yarn.
|
|
16
|
+
// 3. Fall back to `pnpm exec tsc` — pnpm knows its own symlink farm
|
|
17
|
+
// even when bare require.resolve doesn't, which is what CI hits.
|
|
3
18
|
export async function run({ root }) {
|
|
4
|
-
|
|
19
|
+
const absoluteRoot = path.resolve(root);
|
|
20
|
+
|
|
21
|
+
const tscBin = resolveTscBin(absoluteRoot);
|
|
22
|
+
if (tscBin) {
|
|
23
|
+
return runCommand("node", [tscBin, "--noEmit", "-p", "tsconfig.json"], absoluteRoot);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (hasCommand("pnpm")) {
|
|
27
|
+
return runCommand("pnpm", ["exec", "tsc", "--noEmit", "-p", "tsconfig.json"], absoluteRoot);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
console.error("[openpress] typescript is not installed in this workspace.");
|
|
31
|
+
console.error("Add it with: npm install --save-dev typescript");
|
|
32
|
+
return 1;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function resolveTscBin(absoluteRoot) {
|
|
36
|
+
try {
|
|
37
|
+
const require = createRequire(path.join(absoluteRoot, "package.json"));
|
|
38
|
+
const pkgPath = require.resolve("typescript/package.json");
|
|
39
|
+
return path.join(path.dirname(pkgPath), "bin", "tsc");
|
|
40
|
+
} catch {
|
|
41
|
+
// fall through to .bin probe
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
let dir = absoluteRoot;
|
|
45
|
+
while (true) {
|
|
46
|
+
const candidate = path.join(dir, "node_modules", ".bin", "tsc");
|
|
47
|
+
if (fs.existsSync(candidate)) return candidate;
|
|
48
|
+
const parent = path.dirname(dir);
|
|
49
|
+
if (parent === dir) return null;
|
|
50
|
+
dir = parent;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function hasCommand(name) {
|
|
55
|
+
const PATH = process.env.PATH ?? "";
|
|
56
|
+
const sep = process.platform === "win32" ? ";" : ":";
|
|
57
|
+
const exts = process.platform === "win32"
|
|
58
|
+
? (process.env.PATHEXT ?? ".EXE;.CMD;.BAT").split(";")
|
|
59
|
+
: [""];
|
|
60
|
+
for (const dir of PATH.split(sep)) {
|
|
61
|
+
if (!dir) continue;
|
|
62
|
+
for (const ext of exts) {
|
|
63
|
+
if (fs.existsSync(path.join(dir, name + ext))) return true;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return false;
|
|
5
67
|
}
|
|
@@ -46,7 +46,7 @@ export async function run({ root, options }) {
|
|
|
46
46
|
if (!json) {
|
|
47
47
|
process.stdout.write("dry run — nothing changed. The agent should:\n");
|
|
48
48
|
process.stdout.write(" 1. read each docs/migrations/<version>.md for document-level changes\n");
|
|
49
|
-
process.stdout.write(" 2. apply edits to
|
|
49
|
+
process.stdout.write(" 2. apply edits to press/ where needed\n");
|
|
50
50
|
process.stdout.write(" 3. re-run: npx open-press upgrade (without --dry-run)\n");
|
|
51
51
|
} else {
|
|
52
52
|
process.stdout.write(JSON.stringify({ status: "dry-run", before }, null, 2) + "\n");
|
|
@@ -98,11 +98,11 @@ export async function run({ root, options }) {
|
|
|
98
98
|
}
|
|
99
99
|
}
|
|
100
100
|
process.stdout.write(
|
|
101
|
-
"\nAgent: open each file, identify document-level changes, grep
|
|
101
|
+
"\nAgent: open each file, identify document-level changes, grep press/ for affected patterns, propose edits before applying.\n",
|
|
102
102
|
);
|
|
103
103
|
}
|
|
104
104
|
|
|
105
|
-
process.stdout.write("\nVerify with:\n npm run
|
|
105
|
+
process.stdout.write("\nVerify with:\n npm run build\n\n");
|
|
106
106
|
return 0;
|
|
107
107
|
}
|
|
108
108
|
|
|
@@ -10,6 +10,6 @@ export async function exportDocument(root = ROOT) {
|
|
|
10
10
|
if (reactResult) return reactResult;
|
|
11
11
|
|
|
12
12
|
throw new Error(
|
|
13
|
-
"React/MDX document entry not found. Expected
|
|
13
|
+
"React/MDX document entry not found. Expected press/index.tsx with a Press default export before exporting.",
|
|
14
14
|
);
|
|
15
15
|
}
|