openplanr 3.1.1 → 3.3.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/CHANGELOG.md +69 -0
- package/dist/cli/commands/groups/delivery.d.ts.map +1 -1
- package/dist/cli/commands/groups/delivery.js +2 -0
- package/dist/cli/commands/groups/delivery.js.map +1 -1
- package/dist/cli/commands/planning-artifacts.d.ts.map +1 -1
- package/dist/cli/commands/planning-artifacts.js +22 -12
- package/dist/cli/commands/planning-artifacts.js.map +1 -1
- package/dist/cli/commands/ship.d.ts +3 -0
- package/dist/cli/commands/ship.d.ts.map +1 -0
- package/dist/cli/commands/ship.js +65 -0
- package/dist/cli/commands/ship.js.map +1 -0
- package/dist/cli/commands/spec.d.ts +2 -1
- package/dist/cli/commands/spec.d.ts.map +1 -1
- package/dist/cli/commands/spec.js +45 -5
- package/dist/cli/commands/spec.js.map +1 -1
- package/dist/dashboard/.vite/manifest.json +1 -1
- package/dist/dashboard/assets/index-B_96uzCl.js +572 -0
- package/dist/dashboard/assets/index-B_96uzCl.js.map +1 -0
- package/dist/dashboard/dashboard-manifest.json +10 -10
- package/dist/dashboard/index.html +1 -1
- package/dist/models/schema.d.ts +39 -23
- package/dist/models/schema.d.ts.map +1 -1
- package/dist/models/schema.js +19 -12
- package/dist/models/schema.js.map +1 -1
- package/dist/models/types.d.ts +6 -0
- package/dist/models/types.d.ts.map +1 -1
- package/dist/services/claude-plugin-service.d.ts +5 -0
- package/dist/services/claude-plugin-service.d.ts.map +1 -1
- package/dist/services/claude-plugin-service.js +18 -2
- package/dist/services/claude-plugin-service.js.map +1 -1
- package/dist/services/codex-plugin-service.d.ts.map +1 -1
- package/dist/services/codex-plugin-service.js +11 -3
- package/dist/services/codex-plugin-service.js.map +1 -1
- package/dist/services/id-service.d.ts +1 -5
- package/dist/services/id-service.d.ts.map +1 -1
- package/dist/services/id-service.js +1 -34
- package/dist/services/id-service.js.map +1 -1
- package/dist/services/runtime-manager/codex-discovery.d.ts +1 -3
- package/dist/services/runtime-manager/codex-discovery.d.ts.map +1 -1
- package/dist/services/runtime-manager/codex-discovery.js +3 -16
- package/dist/services/runtime-manager/codex-discovery.js.map +1 -1
- package/dist/services/runtime-manager/doctor.d.ts +25 -0
- package/dist/services/runtime-manager/doctor.d.ts.map +1 -1
- package/dist/services/runtime-manager/doctor.js +480 -0
- package/dist/services/runtime-manager/doctor.js.map +1 -1
- package/dist/services/runtime-manager/errors.d.ts +12 -0
- package/dist/services/runtime-manager/errors.d.ts.map +1 -0
- package/dist/services/runtime-manager/errors.js +14 -0
- package/dist/services/runtime-manager/errors.js.map +1 -0
- package/dist/services/runtime-manager/global-state.d.ts +7 -0
- package/dist/services/runtime-manager/global-state.d.ts.map +1 -1
- package/dist/services/runtime-manager/global-state.js +116 -0
- package/dist/services/runtime-manager/global-state.js.map +1 -1
- package/dist/services/runtime-manager/host-version-probe.d.ts +8 -0
- package/dist/services/runtime-manager/host-version-probe.d.ts.map +1 -0
- package/dist/services/runtime-manager/host-version-probe.js +14 -0
- package/dist/services/runtime-manager/host-version-probe.js.map +1 -0
- package/dist/services/runtime-manager/install-plan.d.ts +25 -0
- package/dist/services/runtime-manager/install-plan.d.ts.map +1 -1
- package/dist/services/runtime-manager/install-plan.js +305 -0
- package/dist/services/runtime-manager/install-plan.js.map +1 -1
- package/dist/services/runtime-manager/inventory.d.ts +6 -0
- package/dist/services/runtime-manager/inventory.d.ts.map +1 -1
- package/dist/services/runtime-manager/inventory.js +16 -1
- package/dist/services/runtime-manager/inventory.js.map +1 -1
- package/dist/services/runtime-manager/legacy-adapters.d.ts +9 -0
- package/dist/services/runtime-manager/legacy-adapters.d.ts.map +1 -0
- package/dist/services/runtime-manager/legacy-adapters.js +187 -0
- package/dist/services/runtime-manager/legacy-adapters.js.map +1 -0
- package/dist/services/runtime-manager/paths.d.ts +18 -0
- package/dist/services/runtime-manager/paths.d.ts.map +1 -0
- package/dist/services/runtime-manager/paths.js +83 -0
- package/dist/services/runtime-manager/paths.js.map +1 -0
- package/dist/services/runtime-manager/runtime-package.d.ts +21 -0
- package/dist/services/runtime-manager/runtime-package.d.ts.map +1 -1
- package/dist/services/runtime-manager/runtime-package.js +77 -0
- package/dist/services/runtime-manager/runtime-package.js.map +1 -1
- package/dist/services/runtime-manager/storage.d.ts +47 -0
- package/dist/services/runtime-manager/storage.d.ts.map +1 -0
- package/dist/services/runtime-manager/storage.js +604 -0
- package/dist/services/runtime-manager/storage.js.map +1 -0
- package/dist/services/runtime-manager-service.d.ts +7 -17
- package/dist/services/runtime-manager-service.d.ts.map +1 -1
- package/dist/services/runtime-manager-service.js +32 -1695
- package/dist/services/runtime-manager-service.js.map +1 -1
- package/dist/services/ship-checks/changes.d.ts +24 -0
- package/dist/services/ship-checks/changes.d.ts.map +1 -0
- package/dist/services/ship-checks/changes.js +135 -0
- package/dist/services/ship-checks/changes.js.map +1 -0
- package/dist/services/ship-checks/contract.d.ts +93 -0
- package/dist/services/ship-checks/contract.d.ts.map +1 -0
- package/dist/services/ship-checks/contract.js +7 -0
- package/dist/services/ship-checks/contract.js.map +1 -0
- package/dist/services/ship-checks/coverage.d.ts +4 -0
- package/dist/services/ship-checks/coverage.d.ts.map +1 -0
- package/dist/services/ship-checks/coverage.js +113 -0
- package/dist/services/ship-checks/coverage.js.map +1 -0
- package/dist/services/ship-checks/discover.d.ts +10 -0
- package/dist/services/ship-checks/discover.d.ts.map +1 -0
- package/dist/services/ship-checks/discover.js +253 -0
- package/dist/services/ship-checks/discover.js.map +1 -0
- package/dist/services/ship-checks/glob.d.ts +5 -0
- package/dist/services/ship-checks/glob.d.ts.map +1 -0
- package/dist/services/ship-checks/glob.js +39 -0
- package/dist/services/ship-checks/glob.js.map +1 -0
- package/dist/services/ship-checks/hooks.d.ts +7 -0
- package/dist/services/ship-checks/hooks.d.ts.map +1 -0
- package/dist/services/ship-checks/hooks.js +65 -0
- package/dist/services/ship-checks/hooks.js.map +1 -0
- package/dist/services/ship-checks/packages.d.ts +29 -0
- package/dist/services/ship-checks/packages.d.ts.map +1 -0
- package/dist/services/ship-checks/packages.js +197 -0
- package/dist/services/ship-checks/packages.js.map +1 -0
- package/dist/services/ship-checks/related-tests.d.ts +13 -0
- package/dist/services/ship-checks/related-tests.d.ts.map +1 -0
- package/dist/services/ship-checks/related-tests.js +73 -0
- package/dist/services/ship-checks/related-tests.js.map +1 -0
- package/dist/services/ship-checks/scope.d.ts +8 -0
- package/dist/services/ship-checks/scope.d.ts.map +1 -0
- package/dist/services/ship-checks/scope.js +66 -0
- package/dist/services/ship-checks/scope.js.map +1 -0
- package/dist/services/ship-checks/task-requirements.d.ts +14 -0
- package/dist/services/ship-checks/task-requirements.d.ts.map +1 -0
- package/dist/services/ship-checks/task-requirements.js +145 -0
- package/dist/services/ship-checks/task-requirements.js.map +1 -0
- package/dist/services/ship-checks/workflows.d.ts +21 -0
- package/dist/services/ship-checks/workflows.d.ts.map +1 -0
- package/dist/services/ship-checks/workflows.js +208 -0
- package/dist/services/ship-checks/workflows.js.map +1 -0
- package/dist/services/spec-service.d.ts +18 -0
- package/dist/services/spec-service.d.ts.map +1 -1
- package/dist/services/spec-service.js +174 -9
- package/dist/services/spec-service.js.map +1 -1
- package/dist/services/template-service.d.ts +2 -0
- package/dist/services/template-service.d.ts.map +1 -1
- package/dist/services/template-service.js +4 -0
- package/dist/services/template-service.js.map +1 -1
- package/dist/templates/spec/spec-shaped.md.hbs +1 -1
- package/dist/templates/spec/spec.md.hbs +2 -2
- package/dist/utils/slugify.d.ts +1 -8
- package/dist/utils/slugify.d.ts.map +1 -1
- package/dist/utils/slugify.js +1 -25
- package/dist/utils/slugify.js.map +1 -1
- package/docs/CLI.md +96 -2
- package/lib/backlog-item.d.mts +49 -0
- package/lib/backlog-item.mjs +339 -0
- package/lib/host-packages/adapter-registry.json +5 -5
- package/lib/host-packages/capability-map.json +3 -3
- package/lib/host-packages/claude/.claude-plugin/marketplace.json +2 -2
- package/lib/host-packages/claude/openplanr/.claude-plugin/plugin.json +1 -1
- package/lib/host-packages/claude/openplanr/.openplanr-content.json +134 -94
- package/lib/host-packages/claude/openplanr/CONNECTORS.md +4 -6
- package/lib/host-packages/claude/openplanr/README.md +1 -1
- package/lib/host-packages/claude/openplanr/agents/planr-qa.md +5 -3
- package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-artifact-shell.mjs +1 -1
- package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-chunked-workspace-client.mjs +1 -1
- package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-document.mjs +471 -80
- package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-handoff.mjs +2 -2
- package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-resource-pack.mjs +1 -1
- package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-review.mjs +45 -4
- package/lib/host-packages/{cursor/openplanr/runtime/design/scripts/design-runtime-support-e34c388a8e59.mjs → claude/openplanr/runtime/design/scripts/design-runtime-support-25485dbf1cb2.mjs} +1 -1
- package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-share.mjs +8 -5
- package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-shared-artifact-support-dependencies-design-support-protocol-contracts-3d9b1a86.mjs +138 -12
- package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-shared-artifact-support-protocol-contracts-ea2cd15e.mjs +1 -1
- package/lib/host-packages/claude/openplanr/runtime/design/scripts/{design-shared-protocol-contracts-31a760fc.mjs → design-shared-protocol-contracts-b5f28f94.mjs} +413 -45
- package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-upload-spool.mjs +1 -1
- package/lib/host-packages/claude/openplanr/runtime/design/scripts/design.mjs +482 -79
- package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/notices/THIRD_PARTY_NOTICES.txt +32 -32
- package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/02-artifact-review-ui.js +23 -23
- package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/03-protocol-contracts.js +322 -45
- package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/06-artifact-review-ui.js +12 -12
- package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/08-artifact-review-ui.js +47 -14
- package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources.json +11 -10
- package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/package.json +4 -3
- package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.css +16 -11
- package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/01-module-runtime.js +7 -11
- package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/02-react.js +165 -276
- package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/03-react-dom-client-fiber-foundations.js +494 -967
- package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/04-react-dom-client-reconciliation-hooks.js +346 -678
- package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/05-react-dom-client-render-phases.js +382 -810
- package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/06-react-dom-client-commit-effects.js +406 -730
- package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/07-react-dom-client-work-loop-scheduling.js +259 -522
- package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/08-react-dom-client-dom-events-properties-hydration.js +585 -937
- package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/09-react-dom-client-public-roots.js +119 -244
- package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/10-react.js +7 -17
- package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/11-artifact-review-ui.js +3 -4
- package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/12-protocol-contracts.js +285 -0
- package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/13-design-review-experience.js +2773 -0
- package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/14-studio-shell.js +134 -0
- package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/15-canvas-engine.js +2207 -0
- package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/16-design-review-experience.js +16 -0
- package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/17-studio-shell.js +8 -0
- package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/18-interface-primitives.js +3883 -0
- package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/19-interface-primitives.js +966 -0
- package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/{16-studio-shell.js → 20-studio-shell.js} +122 -227
- package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/21-design-studio.js +1597 -0
- package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources.json +101 -47
- package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/protocol/package.json +6 -2
- package/lib/host-packages/{openai/openplanr/runtime/design/scripts/runtime/packages/protocol/schemas/v1.9.0 → claude/openplanr/runtime/design/scripts/runtime/packages/protocol/schemas/v1.22.0}/design-document.schema.json +207 -7
- package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/protocol/schemas/v1.22.0/design-review-bundle.schema.json +822 -0
- package/lib/host-packages/claude/openplanr/runtime/plan/scripts/design-protocol-contracts.mjs +324 -45
- package/lib/host-packages/claude/openplanr/runtime/plan/scripts/design.mjs +73 -12
- package/lib/host-packages/claude/openplanr/runtime/plan/scripts/runtime/packages/protocol/package.json +6 -2
- package/lib/host-packages/claude/openplanr/skills/connect/references/connectors.md +4 -6
- package/lib/host-packages/claude/openplanr/skills/design/SKILL.md +12 -0
- package/lib/host-packages/claude/openplanr/skills/design/references/craft.md +14 -3
- package/lib/host-packages/claude/openplanr/skills/design/references/design-system.md +48 -1
- package/lib/host-packages/claude/openplanr/skills/design/references/discovery.md +18 -4
- package/lib/host-packages/claude/openplanr/skills/design/references/generation.md +133 -2
- package/lib/host-packages/claude/openplanr/skills/design/references/hosted-canvas.md +62 -0
- package/lib/host-packages/claude/openplanr/skills/design/references/review.md +46 -1
- package/lib/host-packages/claude/openplanr/skills/design/references/utilities.md +17 -1
- package/lib/host-packages/claude/openplanr/skills/design/schemas/design-document.schema.json +207 -7
- package/lib/host-packages/claude/openplanr/skills/design-loop/references/craft.md +14 -3
- package/lib/host-packages/claude/openplanr/skills/design-loop/references/design-system.md +48 -1
- package/lib/host-packages/claude/openplanr/skills/design-loop/references/discovery.md +18 -4
- package/lib/host-packages/claude/openplanr/skills/design-loop/references/generation.md +133 -2
- package/lib/host-packages/claude/openplanr/skills/design-loop/references/review.md +46 -1
- package/lib/host-packages/claude/openplanr/skills/design-loop/references/utilities.md +17 -1
- package/lib/host-packages/claude/openplanr/skills/design-loop/schemas/design-document.schema.json +207 -7
- package/lib/host-packages/claude/openplanr/skills/design-review/references/craft.md +14 -3
- package/lib/host-packages/claude/openplanr/skills/design-review/references/design-system.md +48 -1
- package/lib/host-packages/claude/openplanr/skills/design-review/references/discovery.md +18 -4
- package/lib/host-packages/claude/openplanr/skills/design-review/references/generation.md +133 -2
- package/lib/host-packages/claude/openplanr/skills/design-review/references/review.md +46 -1
- package/lib/host-packages/claude/openplanr/skills/design-review/references/utilities.md +17 -1
- package/lib/host-packages/claude/openplanr/skills/design-review/schemas/design-document.schema.json +207 -7
- package/lib/host-packages/claude/openplanr/skills/investigate/SKILL.md +11 -2
- package/lib/host-packages/claude/openplanr/skills/investigate/references/findings.md +92 -0
- package/lib/host-packages/claude/openplanr/skills/investigate/scripts/backlog-item.mjs +339 -0
- package/lib/host-packages/claude/openplanr/skills/plan/SKILL.md +24 -11
- package/lib/host-packages/claude/openplanr/skills/plan/schemas/design-document.schema.json +207 -7
- package/lib/host-packages/claude/openplanr/skills/share/references/connectors.md +4 -6
- package/lib/host-packages/claude/openplanr/skills/ship/SKILL.md +46 -14
- package/lib/host-packages/claude/openplanr/skills/ship/references/findings.md +92 -0
- package/lib/host-packages/claude/openplanr/skills/ship/references/result-contract.md +3 -1
- package/lib/host-packages/claude/openplanr/skills/ship/scripts/backlog-item.mjs +339 -0
- package/lib/host-packages/claude/openplanr/skills/spec/SKILL.md +6 -0
- package/lib/host-packages/claude/openplanr/skills/spec/references/specification-contract.md +3 -1
- package/lib/host-packages/claude/openplanr/skills/sprint/references/connectors.md +4 -6
- package/lib/host-packages/claude/openplanr/skills/status/references/connectors.md +4 -6
- package/lib/host-packages/claude/openplanr/skills/sync/references/connectors.md +4 -6
- package/lib/host-packages/cursor/openplanr/.openplanr-content.json +132 -92
- package/lib/host-packages/cursor/openplanr/CONNECTORS.md +4 -6
- package/lib/host-packages/cursor/openplanr/manifest.json +1 -1
- package/lib/host-packages/cursor/openplanr/rules/planr-connect/references/connectors.md +4 -6
- package/lib/host-packages/cursor/openplanr/rules/planr-design/references/craft.md +14 -3
- package/lib/host-packages/cursor/openplanr/rules/planr-design/references/design-system.md +48 -1
- package/lib/host-packages/cursor/openplanr/rules/planr-design/references/discovery.md +18 -4
- package/lib/host-packages/cursor/openplanr/rules/planr-design/references/generation.md +133 -2
- package/lib/host-packages/cursor/openplanr/rules/planr-design/references/hosted-canvas.md +62 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-design/references/review.md +46 -1
- package/lib/host-packages/cursor/openplanr/rules/planr-design/references/utilities.md +17 -1
- package/lib/host-packages/cursor/openplanr/rules/planr-design/schemas/design-document.schema.json +207 -7
- package/lib/host-packages/cursor/openplanr/rules/planr-design-loop/references/craft.md +14 -3
- package/lib/host-packages/cursor/openplanr/rules/planr-design-loop/references/design-system.md +48 -1
- package/lib/host-packages/cursor/openplanr/rules/planr-design-loop/references/discovery.md +18 -4
- package/lib/host-packages/cursor/openplanr/rules/planr-design-loop/references/generation.md +133 -2
- package/lib/host-packages/cursor/openplanr/rules/planr-design-loop/references/review.md +46 -1
- package/lib/host-packages/cursor/openplanr/rules/planr-design-loop/references/utilities.md +17 -1
- package/lib/host-packages/cursor/openplanr/rules/planr-design-loop/schemas/design-document.schema.json +207 -7
- package/lib/host-packages/cursor/openplanr/rules/planr-design-review/references/craft.md +14 -3
- package/lib/host-packages/cursor/openplanr/rules/planr-design-review/references/design-system.md +48 -1
- package/lib/host-packages/cursor/openplanr/rules/planr-design-review/references/discovery.md +18 -4
- package/lib/host-packages/cursor/openplanr/rules/planr-design-review/references/generation.md +133 -2
- package/lib/host-packages/cursor/openplanr/rules/planr-design-review/references/review.md +46 -1
- package/lib/host-packages/cursor/openplanr/rules/planr-design-review/references/utilities.md +17 -1
- package/lib/host-packages/cursor/openplanr/rules/planr-design-review/schemas/design-document.schema.json +207 -7
- package/lib/host-packages/cursor/openplanr/rules/planr-design.mdc +12 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-investigate/references/findings.md +92 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-investigate/scripts/backlog-item.mjs +339 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-investigate.mdc +11 -2
- package/lib/host-packages/cursor/openplanr/rules/planr-plan/schemas/design-document.schema.json +207 -7
- package/lib/host-packages/cursor/openplanr/rules/planr-plan.mdc +24 -11
- package/lib/host-packages/cursor/openplanr/rules/planr-share/references/connectors.md +4 -6
- package/lib/host-packages/cursor/openplanr/rules/planr-ship/references/findings.md +92 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-ship/references/result-contract.md +3 -1
- package/lib/host-packages/cursor/openplanr/rules/planr-ship/scripts/backlog-item.mjs +339 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-ship.mdc +46 -14
- package/lib/host-packages/cursor/openplanr/rules/planr-spec/references/specification-contract.md +3 -1
- package/lib/host-packages/cursor/openplanr/rules/planr-spec.mdc +6 -0
- package/lib/host-packages/cursor/openplanr/rules/planr-sprint/references/connectors.md +4 -6
- package/lib/host-packages/cursor/openplanr/rules/planr-status/references/connectors.md +4 -6
- package/lib/host-packages/cursor/openplanr/rules/planr-sync/references/connectors.md +4 -6
- package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-artifact-shell.mjs +1 -1
- package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-chunked-workspace-client.mjs +1 -1
- package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-document.mjs +471 -80
- package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-handoff.mjs +2 -2
- package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-resource-pack.mjs +1 -1
- package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-review.mjs +45 -4
- package/lib/host-packages/{openai/openplanr/runtime/design/scripts/design-runtime-support-e34c388a8e59.mjs → cursor/openplanr/runtime/design/scripts/design-runtime-support-25485dbf1cb2.mjs} +1 -1
- package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-share.mjs +8 -5
- package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-shared-artifact-support-dependencies-design-support-protocol-contracts-3d9b1a86.mjs +138 -12
- package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-shared-artifact-support-protocol-contracts-ea2cd15e.mjs +1 -1
- package/lib/host-packages/{openai/openplanr/runtime/design/scripts/design-shared-protocol-contracts-31a760fc.mjs → cursor/openplanr/runtime/design/scripts/design-shared-protocol-contracts-b5f28f94.mjs} +413 -45
- package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-upload-spool.mjs +1 -1
- package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design.mjs +482 -79
- package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/notices/THIRD_PARTY_NOTICES.txt +32 -32
- package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/02-artifact-review-ui.js +23 -23
- package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/03-protocol-contracts.js +322 -45
- package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/06-artifact-review-ui.js +12 -12
- package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/08-artifact-review-ui.js +47 -14
- package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources.json +11 -10
- package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/package.json +4 -3
- package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.css +16 -11
- package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/01-module-runtime.js +7 -11
- package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/02-react.js +165 -276
- package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/03-react-dom-client-fiber-foundations.js +494 -967
- package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/04-react-dom-client-reconciliation-hooks.js +346 -678
- package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/05-react-dom-client-render-phases.js +382 -810
- package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/06-react-dom-client-commit-effects.js +406 -730
- package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/07-react-dom-client-work-loop-scheduling.js +259 -522
- package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/08-react-dom-client-dom-events-properties-hydration.js +585 -937
- package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/09-react-dom-client-public-roots.js +119 -244
- package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/10-react.js +7 -17
- package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/11-artifact-review-ui.js +3 -4
- package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/12-protocol-contracts.js +285 -0
- package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/13-design-review-experience.js +2773 -0
- package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/14-studio-shell.js +134 -0
- package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/15-canvas-engine.js +2207 -0
- package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/16-design-review-experience.js +16 -0
- package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/17-studio-shell.js +8 -0
- package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/18-interface-primitives.js +3883 -0
- package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/19-interface-primitives.js +966 -0
- package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/{16-studio-shell.js → 20-studio-shell.js} +122 -227
- package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/21-design-studio.js +1597 -0
- package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources.json +101 -47
- package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/protocol/package.json +6 -2
- package/lib/host-packages/{claude/openplanr/runtime/design/scripts/runtime/packages/protocol/schemas/v1.9.0 → cursor/openplanr/runtime/design/scripts/runtime/packages/protocol/schemas/v1.22.0}/design-document.schema.json +207 -7
- package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/protocol/schemas/v1.22.0/design-review-bundle.schema.json +822 -0
- package/lib/host-packages/cursor/openplanr/runtime/plan/scripts/design-protocol-contracts.mjs +324 -45
- package/lib/host-packages/cursor/openplanr/runtime/plan/scripts/design.mjs +73 -12
- package/lib/host-packages/cursor/openplanr/runtime/plan/scripts/runtime/packages/protocol/package.json +6 -2
- package/lib/host-packages/openai/.claude-plugin/marketplace.json +2 -2
- package/lib/host-packages/openai/openplanr/.codex-plugin/plugin.json +1 -1
- package/lib/host-packages/openai/openplanr/.openplanr-content.json +139 -99
- package/lib/host-packages/openai/openplanr/CONNECTORS.md +4 -6
- package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-artifact-shell.mjs +1 -1
- package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-chunked-workspace-client.mjs +1 -1
- package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-document.mjs +471 -80
- package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-handoff.mjs +2 -2
- package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-resource-pack.mjs +1 -1
- package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-review.mjs +45 -4
- package/lib/host-packages/{claude/openplanr/runtime/design/scripts/design-runtime-support-e34c388a8e59.mjs → openai/openplanr/runtime/design/scripts/design-runtime-support-25485dbf1cb2.mjs} +1 -1
- package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-share.mjs +8 -5
- package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-shared-artifact-support-dependencies-design-support-protocol-contracts-3d9b1a86.mjs +138 -12
- package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-shared-artifact-support-protocol-contracts-ea2cd15e.mjs +1 -1
- package/lib/host-packages/{cursor/openplanr/runtime/design/scripts/design-shared-protocol-contracts-31a760fc.mjs → openai/openplanr/runtime/design/scripts/design-shared-protocol-contracts-b5f28f94.mjs} +413 -45
- package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-upload-spool.mjs +1 -1
- package/lib/host-packages/openai/openplanr/runtime/design/scripts/design.mjs +482 -79
- package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/notices/THIRD_PARTY_NOTICES.txt +32 -32
- package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/02-artifact-review-ui.js +23 -23
- package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/03-protocol-contracts.js +322 -45
- package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/06-artifact-review-ui.js +12 -12
- package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources/08-artifact-review-ui.js +47 -14
- package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources.json +11 -10
- package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/package.json +4 -3
- package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.css +16 -11
- package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/01-module-runtime.js +7 -11
- package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/02-react.js +165 -276
- package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/03-react-dom-client-fiber-foundations.js +494 -967
- package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/04-react-dom-client-reconciliation-hooks.js +346 -678
- package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/05-react-dom-client-render-phases.js +382 -810
- package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/06-react-dom-client-commit-effects.js +406 -730
- package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/07-react-dom-client-work-loop-scheduling.js +259 -522
- package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/08-react-dom-client-dom-events-properties-hydration.js +585 -937
- package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/09-react-dom-client-public-roots.js +119 -244
- package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/10-react.js +7 -17
- package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/11-artifact-review-ui.js +3 -4
- package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/12-protocol-contracts.js +285 -0
- package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/13-design-review-experience.js +2773 -0
- package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/14-studio-shell.js +134 -0
- package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/15-canvas-engine.js +2207 -0
- package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/16-design-review-experience.js +16 -0
- package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/17-studio-shell.js +8 -0
- package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/18-interface-primitives.js +3883 -0
- package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/19-interface-primitives.js +966 -0
- package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/{16-studio-shell.js → 20-studio-shell.js} +122 -227
- package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/21-design-studio.js +1597 -0
- package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources.json +101 -47
- package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/protocol/package.json +6 -2
- package/lib/host-packages/{cursor/openplanr/runtime/design/scripts/runtime/packages/protocol/schemas/v1.9.0 → openai/openplanr/runtime/design/scripts/runtime/packages/protocol/schemas/v1.22.0}/design-document.schema.json +207 -7
- package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/protocol/schemas/v1.22.0/design-review-bundle.schema.json +822 -0
- package/lib/host-packages/openai/openplanr/runtime/plan/scripts/design-protocol-contracts.mjs +324 -45
- package/lib/host-packages/openai/openplanr/runtime/plan/scripts/design.mjs +73 -12
- package/lib/host-packages/openai/openplanr/runtime/plan/scripts/runtime/packages/protocol/package.json +6 -2
- package/lib/host-packages/openai/openplanr/skills/connect/references/connectors.md +4 -6
- package/lib/host-packages/openai/openplanr/skills/design/SKILL.md +12 -0
- package/lib/host-packages/openai/openplanr/skills/design/openplanr.skill.json +11 -0
- package/lib/host-packages/openai/openplanr/skills/design/references/craft.md +14 -3
- package/lib/host-packages/openai/openplanr/skills/design/references/design-system.md +48 -1
- package/lib/host-packages/openai/openplanr/skills/design/references/discovery.md +18 -4
- package/lib/host-packages/openai/openplanr/skills/design/references/generation.md +133 -2
- package/lib/host-packages/openai/openplanr/skills/design/references/hosted-canvas.md +62 -0
- package/lib/host-packages/openai/openplanr/skills/design/references/review.md +46 -1
- package/lib/host-packages/openai/openplanr/skills/design/references/utilities.md +17 -1
- package/lib/host-packages/openai/openplanr/skills/design/schemas/design-document.schema.json +207 -7
- package/lib/host-packages/openai/openplanr/skills/design-loop/references/craft.md +14 -3
- package/lib/host-packages/openai/openplanr/skills/design-loop/references/design-system.md +48 -1
- package/lib/host-packages/openai/openplanr/skills/design-loop/references/discovery.md +18 -4
- package/lib/host-packages/openai/openplanr/skills/design-loop/references/generation.md +133 -2
- package/lib/host-packages/openai/openplanr/skills/design-loop/references/review.md +46 -1
- package/lib/host-packages/openai/openplanr/skills/design-loop/references/utilities.md +17 -1
- package/lib/host-packages/openai/openplanr/skills/design-loop/schemas/design-document.schema.json +207 -7
- package/lib/host-packages/openai/openplanr/skills/design-review/references/craft.md +14 -3
- package/lib/host-packages/openai/openplanr/skills/design-review/references/design-system.md +48 -1
- package/lib/host-packages/openai/openplanr/skills/design-review/references/discovery.md +18 -4
- package/lib/host-packages/openai/openplanr/skills/design-review/references/generation.md +133 -2
- package/lib/host-packages/openai/openplanr/skills/design-review/references/review.md +46 -1
- package/lib/host-packages/openai/openplanr/skills/design-review/references/utilities.md +17 -1
- package/lib/host-packages/openai/openplanr/skills/design-review/schemas/design-document.schema.json +207 -7
- package/lib/host-packages/openai/openplanr/skills/investigate/SKILL.md +11 -2
- package/lib/host-packages/openai/openplanr/skills/investigate/agents/openai.yaml +1 -1
- package/lib/host-packages/openai/openplanr/skills/investigate/openplanr.skill.json +23 -1
- package/lib/host-packages/openai/openplanr/skills/investigate/references/findings.md +92 -0
- package/lib/host-packages/openai/openplanr/skills/investigate/scripts/backlog-item.mjs +339 -0
- package/lib/host-packages/openai/openplanr/skills/plan/SKILL.md +24 -11
- package/lib/host-packages/openai/openplanr/skills/plan/openplanr.skill.json +1 -1
- package/lib/host-packages/openai/openplanr/skills/plan/schemas/design-document.schema.json +207 -7
- package/lib/host-packages/openai/openplanr/skills/share/references/connectors.md +4 -6
- package/lib/host-packages/openai/openplanr/skills/ship/SKILL.md +46 -14
- package/lib/host-packages/openai/openplanr/skills/ship/agents/openai.yaml +1 -1
- package/lib/host-packages/openai/openplanr/skills/ship/openplanr.skill.json +23 -1
- package/lib/host-packages/openai/openplanr/skills/ship/references/findings.md +92 -0
- package/lib/host-packages/openai/openplanr/skills/ship/references/result-contract.md +3 -1
- package/lib/host-packages/openai/openplanr/skills/ship/scripts/backlog-item.mjs +339 -0
- package/lib/host-packages/openai/openplanr/skills/spec/SKILL.md +6 -0
- package/lib/host-packages/openai/openplanr/skills/spec/openplanr.skill.json +1 -1
- package/lib/host-packages/openai/openplanr/skills/spec/references/specification-contract.md +3 -1
- package/lib/host-packages/openai/openplanr/skills/sprint/references/connectors.md +4 -6
- package/lib/host-packages/openai/openplanr/skills/status/references/connectors.md +4 -6
- package/lib/host-packages/openai/openplanr/skills/sync/references/connectors.md +4 -6
- package/lib/json-schema.mjs +4 -0
- package/package.json +13 -13
- package/dist/dashboard/assets/index-G7ygVDGg.js +0 -572
- package/dist/dashboard/assets/index-G7ygVDGg.js.map +0 -1
- package/dist/templates/backlog/backlog-item.md.hbs +0 -40
- package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/12-design-review-experience.js +0 -3589
- package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/13-studio-shell.js +0 -184
- package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/14-interface-primitives.js +0 -5229
- package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/15-interface-primitives.js +0 -1733
- package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/17-design-studio.js +0 -1844
- package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/12-design-review-experience.js +0 -3589
- package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/13-studio-shell.js +0 -184
- package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/14-interface-primitives.js +0 -5229
- package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/15-interface-primitives.js +0 -1733
- package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/17-design-studio.js +0 -1844
- package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/12-design-review-experience.js +0 -3589
- package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/13-studio-shell.js +0 -184
- package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/14-interface-primitives.js +0 -5229
- package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/15-interface-primitives.js +0 -1733
- package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/17-design-studio.js +0 -1844
|
@@ -12,10 +12,13 @@ import {
|
|
|
12
12
|
ARTIFACT_WORKER_GUARD_SOURCE
|
|
13
13
|
} from "./design-sandbox-guards.mjs";
|
|
14
14
|
import {
|
|
15
|
+
atomicBytes,
|
|
15
16
|
atomicJson,
|
|
16
17
|
bundleLocalDocument,
|
|
18
|
+
currentDesign,
|
|
17
19
|
designSpecPath,
|
|
18
20
|
hash,
|
|
21
|
+
inspectLocalDocumentBody,
|
|
19
22
|
json,
|
|
20
23
|
loadReviewContext,
|
|
21
24
|
parse,
|
|
@@ -40,21 +43,83 @@ import {
|
|
|
40
43
|
resolveArtifactHtml
|
|
41
44
|
} from "./design-shared-artifact-support-protocol-contracts-ea2cd15e.mjs";
|
|
42
45
|
import {
|
|
43
|
-
|
|
44
|
-
|
|
46
|
+
DESIGN_DOCUMENT_SCHEMA,
|
|
47
|
+
assertDesignDocument,
|
|
48
|
+
initialFrameHeight,
|
|
49
|
+
validateDesignProps
|
|
50
|
+
} from "./design-shared-protocol-contracts-b5f28f94.mjs";
|
|
51
|
+
|
|
52
|
+
// packages/design/lib/design/frame-size.mjs
|
|
53
|
+
function designFrameLabel(frame) {
|
|
54
|
+
const dimensions = `${frame.width} \xD7 ${frame.height}`;
|
|
55
|
+
return frame.label.includes(dimensions) ? frame.label : `${frame.label} \xB7 ${dimensions}`;
|
|
56
|
+
}
|
|
57
|
+
function designFrameViewport(document2, frame) {
|
|
58
|
+
return {
|
|
59
|
+
width: frame.width,
|
|
60
|
+
height: frame.height === "auto" ? initialFrameHeight(document2) : frame.height
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
function matchesDesignFrame(frame, viewport) {
|
|
64
|
+
return Boolean(
|
|
65
|
+
frame && viewport?.width === frame.width && (frame.height === "auto" ? Number.isInteger(viewport.height) && viewport.height > 0 && viewport.height <= 16384 : viewport.height === frame.height)
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
function observeDesignFrameSize() {
|
|
69
|
+
let pending = false;
|
|
70
|
+
const measure = async () => {
|
|
71
|
+
if (pending) return;
|
|
72
|
+
pending = true;
|
|
73
|
+
try {
|
|
74
|
+
await document.fonts.ready;
|
|
75
|
+
await new Promise((resolve3) => requestAnimationFrame(() => requestAnimationFrame(resolve3)));
|
|
76
|
+
parent.postMessage(
|
|
77
|
+
{
|
|
78
|
+
type: "openplanr:design-size",
|
|
79
|
+
screenId: document.body.getAttribute("data-planr-screen"),
|
|
80
|
+
width: innerWidth,
|
|
81
|
+
height: Math.min(16384, Math.max(1, document.documentElement.scrollHeight))
|
|
82
|
+
},
|
|
83
|
+
"*"
|
|
84
|
+
);
|
|
85
|
+
} finally {
|
|
86
|
+
pending = false;
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
const schedule = () => {
|
|
90
|
+
void measure().catch((error) => {
|
|
91
|
+
parent.postMessage({ type: "openplanr:design-size-error", message: error.message }, "*");
|
|
92
|
+
});
|
|
93
|
+
};
|
|
94
|
+
addEventListener("message", (event) => {
|
|
95
|
+
if (event.source === parent && event.data?.type === "openplanr:design-measure") schedule();
|
|
96
|
+
});
|
|
97
|
+
addEventListener(
|
|
98
|
+
"load",
|
|
99
|
+
() => {
|
|
100
|
+
new ResizeObserver(schedule).observe(document.body);
|
|
101
|
+
schedule();
|
|
102
|
+
},
|
|
103
|
+
{ once: true }
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// packages/design/lib/design/layout-save.mjs
|
|
108
|
+
import { readFileSync as readFileSync6, statSync } from "node:fs";
|
|
109
|
+
import { join as join3 } from "node:path";
|
|
45
110
|
|
|
46
111
|
// packages/design/lib/design/document.mjs
|
|
47
112
|
import { randomUUID } from "node:crypto";
|
|
48
113
|
import {
|
|
49
114
|
existsSync as existsSync2,
|
|
50
115
|
mkdirSync,
|
|
51
|
-
readFileSync as
|
|
116
|
+
readFileSync as readFileSync5,
|
|
52
117
|
realpathSync,
|
|
53
118
|
renameSync,
|
|
54
119
|
rmSync,
|
|
55
120
|
writeFileSync
|
|
56
121
|
} from "node:fs";
|
|
57
|
-
import { dirname, join, resolve as resolve2 } from "node:path";
|
|
122
|
+
import { dirname, join as join2, resolve as resolve2 } from "node:path";
|
|
58
123
|
|
|
59
124
|
// packages/artifact/lib/artifact/bridge.mjs
|
|
60
125
|
import { randomBytes as randomBytes2 } from "node:crypto";
|
|
@@ -149,7 +214,9 @@ function createArtifactViewportGestures(window2, emit) {
|
|
|
149
214
|
mode: getter(window2.WheelEvent.prototype, "deltaMode")
|
|
150
215
|
};
|
|
151
216
|
let enabled = false, disposed = false, timer = 0, pending = null, pendingType = "";
|
|
217
|
+
let gestureScale = 1;
|
|
152
218
|
const clear = () => {
|
|
219
|
+
gestureScale = 1;
|
|
153
220
|
if (timer) cancel(timer);
|
|
154
221
|
timer = 0;
|
|
155
222
|
pending = null;
|
|
@@ -163,6 +230,29 @@ function createArtifactViewportGestures(window2, emit) {
|
|
|
163
230
|
pendingType = "";
|
|
164
231
|
if (enabled && !disposed && value) emit(type, value);
|
|
165
232
|
};
|
|
233
|
+
const queue = (type, value) => {
|
|
234
|
+
const deltaX = value.deltaX ?? 0;
|
|
235
|
+
const deltaY = value.deltaY ?? 0;
|
|
236
|
+
if (pendingType && pendingType !== type) flush();
|
|
237
|
+
pendingType = type;
|
|
238
|
+
pending = type === "viewport.zoom" ? {
|
|
239
|
+
...value,
|
|
240
|
+
deltaY: Math.max(
|
|
241
|
+
-ARTIFACT_VIEWPORT_ZOOM_MAX_DELTA,
|
|
242
|
+
Math.min(ARTIFACT_VIEWPORT_ZOOM_MAX_DELTA, (pending?.deltaY || 0) + deltaY)
|
|
243
|
+
)
|
|
244
|
+
} : {
|
|
245
|
+
deltaX: Math.max(
|
|
246
|
+
-ARTIFACT_VIEWPORT_PAN_MAX_DELTA,
|
|
247
|
+
Math.min(ARTIFACT_VIEWPORT_PAN_MAX_DELTA, (pending?.deltaX || 0) + deltaX)
|
|
248
|
+
),
|
|
249
|
+
deltaY: Math.max(
|
|
250
|
+
-ARTIFACT_VIEWPORT_PAN_MAX_DELTA,
|
|
251
|
+
Math.min(ARTIFACT_VIEWPORT_PAN_MAX_DELTA, (pending?.deltaY || 0) + deltaY)
|
|
252
|
+
)
|
|
253
|
+
};
|
|
254
|
+
if (!timer) timer = schedule(flush, 16);
|
|
255
|
+
};
|
|
166
256
|
const wheel = (event) => {
|
|
167
257
|
if (!enabled || disposed || !event.isTrusted || !event.cancelable) return;
|
|
168
258
|
let x, y, deltaX, deltaY, mode, zooming, shift;
|
|
@@ -213,34 +303,49 @@ function createArtifactViewportGestures(window2, emit) {
|
|
|
213
303
|
if (!value) return;
|
|
214
304
|
prevent.call(event);
|
|
215
305
|
stop.call(event);
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
306
|
+
queue(type, value);
|
|
307
|
+
};
|
|
308
|
+
const consumeGesture = (event) => {
|
|
309
|
+
if (!enabled || disposed || !event.isTrusted || !event.cancelable) return false;
|
|
310
|
+
prevent.call(event);
|
|
311
|
+
stop.call(event);
|
|
312
|
+
return true;
|
|
313
|
+
};
|
|
314
|
+
const gestureStart = (event) => {
|
|
315
|
+
if (consumeGesture(event)) gestureScale = 1;
|
|
316
|
+
};
|
|
317
|
+
const gestureChange = (raw) => {
|
|
318
|
+
if (!consumeGesture(raw)) return;
|
|
319
|
+
const event = raw;
|
|
320
|
+
if (!Number.isFinite(event.scale) || event.scale <= 0) return;
|
|
321
|
+
const deltaY = Math.max(
|
|
322
|
+
-ARTIFACT_VIEWPORT_ZOOM_MAX_DELTA,
|
|
323
|
+
Math.min(ARTIFACT_VIEWPORT_ZOOM_MAX_DELTA, -Math.log(event.scale / gestureScale) / 0.01)
|
|
324
|
+
);
|
|
325
|
+
gestureScale = event.scale;
|
|
326
|
+
const value = normalizeArtifactViewportZoom(
|
|
327
|
+
{ x: event.clientX, y: event.clientY, deltaY },
|
|
328
|
+
{ width: window2.innerWidth, height: window2.innerHeight }
|
|
329
|
+
);
|
|
330
|
+
if (value) queue("viewport.zoom", value);
|
|
331
|
+
};
|
|
332
|
+
const gestureEnd = (event) => {
|
|
333
|
+
if (consumeGesture(event)) gestureScale = 1;
|
|
235
334
|
};
|
|
236
335
|
const destroy = () => {
|
|
237
336
|
disposed = true;
|
|
238
337
|
enabled = false;
|
|
239
338
|
clear();
|
|
240
339
|
remove("wheel", wheel, true);
|
|
340
|
+
remove("gesturestart", gestureStart, true);
|
|
341
|
+
remove("gesturechange", gestureChange, true);
|
|
342
|
+
remove("gestureend", gestureEnd, true);
|
|
241
343
|
remove("pagehide", destroy);
|
|
242
344
|
};
|
|
243
345
|
add("wheel", wheel, { capture: true, passive: false });
|
|
346
|
+
add("gesturestart", gestureStart, { capture: true, passive: false });
|
|
347
|
+
add("gesturechange", gestureChange, { capture: true, passive: false });
|
|
348
|
+
add("gestureend", gestureEnd, { capture: true, passive: false });
|
|
244
349
|
add("pagehide", destroy, { once: true });
|
|
245
350
|
return Object.freeze({
|
|
246
351
|
setEnabled(value) {
|
|
@@ -288,8 +393,8 @@ function normalizeArtifactInspection(value, viewport) {
|
|
|
288
393
|
const descriptor = plain(entry) ? Object.getOwnPropertyDescriptor(entry, key) : null;
|
|
289
394
|
return descriptor && Object.hasOwn(descriptor, "value") ? descriptor.value : void 0;
|
|
290
395
|
};
|
|
291
|
-
const
|
|
292
|
-
if (!
|
|
396
|
+
const exact2 = (entry, keys) => plain(entry) && Object.keys(entry).length === keys.length && Object.keys(entry).every((key) => keys.includes(key));
|
|
397
|
+
if (!exact2(value, ["tagName", "anchor", "rect", "viewport", "styles", "accessibility"]))
|
|
293
398
|
return null;
|
|
294
399
|
const tagName = own(value, "tagName");
|
|
295
400
|
const anchor = own(value, "anchor");
|
|
@@ -298,7 +403,7 @@ function normalizeArtifactInspection(value, viewport) {
|
|
|
298
403
|
const styles = own(value, "styles");
|
|
299
404
|
const accessibility = own(value, "accessibility");
|
|
300
405
|
if (typeof tagName !== "string" || !/^[a-z][a-z0-9-]{0,63}$/.test(tagName)) return null;
|
|
301
|
-
if (!
|
|
406
|
+
if (!exact2(size, ["width", "height"]) || !exact2(rect, ["x", "y", "width", "height"])) return null;
|
|
302
407
|
if (!["width", "height"].every(
|
|
303
408
|
(key) => Number.isInteger(own(size, key)) && own(size, key) >= 1 && own(size, key) <= 16384 && own(size, key) === viewport?.[key]
|
|
304
409
|
))
|
|
@@ -308,14 +413,14 @@ function normalizeArtifactInspection(value, viewport) {
|
|
|
308
413
|
))
|
|
309
414
|
return null;
|
|
310
415
|
if (rect.x + rect.width > size.width || rect.y + rect.height > size.height) return null;
|
|
311
|
-
if (anchor !== null && (!
|
|
416
|
+
if (anchor !== null && (!exact2(anchor, own(anchor, "screen") === void 0 ? ["planrId"] : ["planrId", "screen"]) || typeof own(anchor, "planrId") !== "string" || !/^[A-Za-z0-9][A-Za-z0-9._:-]{0,511}$/.test(anchor.planrId) || own(anchor, "screen") !== void 0 && (typeof anchor.screen !== "string" || !/^[^\u0000-\u001f\u007f]{1,128}$/.test(anchor.screen))))
|
|
312
417
|
return null;
|
|
313
|
-
if (!
|
|
418
|
+
if (!exact2(styles, ARTIFACT_INSPECTION_PROPERTIES) || !ARTIFACT_INSPECTION_PROPERTIES.every((key) => {
|
|
314
419
|
const text = own(styles, key);
|
|
315
420
|
return typeof text === "string" && text.length <= 256 && !/[\u0000-\u001f\u007f]/.test(text) && !/(?:url\s*\(|https?:|file:)/i.test(text);
|
|
316
421
|
}))
|
|
317
422
|
return null;
|
|
318
|
-
if (!
|
|
423
|
+
if (!exact2(accessibility, ["role", "ariaLabel", "alt", "tabIndex", "disabled"]) || !["role", "ariaLabel", "alt"].every(
|
|
319
424
|
(key) => typeof own(accessibility, key) === "string" && own(accessibility, key).length <= 256 && !/[\u0000-\u001f\u007f]/.test(own(accessibility, key))
|
|
320
425
|
) || !Number.isInteger(own(accessibility, "tabIndex")) || accessibility.tabIndex < -1 || accessibility.tabIndex > 32767 || typeof own(accessibility, "disabled") !== "boolean")
|
|
321
426
|
return null;
|
|
@@ -340,20 +445,20 @@ function normalizeArtifactThumbnail(value) {
|
|
|
340
445
|
}
|
|
341
446
|
function normalizeArtifactBridgeToolResult(requestType, message, viewport) {
|
|
342
447
|
const base = ["channel", "schemaVersion", "type", "nonce", "artifactId", "requestId"];
|
|
343
|
-
const
|
|
448
|
+
const exact2 = (keys) => message && typeof message === "object" && !Array.isArray(message) && Object.keys(message).length === keys.length && Object.keys(message).every((key) => keys.includes(key)) && Object.values(Object.getOwnPropertyDescriptors(message)).every(
|
|
344
449
|
(descriptor) => Object.hasOwn(descriptor, "value")
|
|
345
450
|
);
|
|
346
451
|
if (requestType === "inspect.point" || requestType === "inspect.anchor") {
|
|
347
|
-
if (
|
|
348
|
-
if (!
|
|
452
|
+
if (exact2(base) && message.type === "inspect.miss") return { valid: true, value: null };
|
|
453
|
+
if (!exact2([...base, "inspection"]) || message.type !== "inspect.result")
|
|
349
454
|
return { valid: false };
|
|
350
455
|
const value = normalizeArtifactInspection(message.inspection, viewport);
|
|
351
456
|
return value ? { valid: true, value } : { valid: false };
|
|
352
457
|
}
|
|
353
458
|
if (requestType === "thumbnail.request") {
|
|
354
|
-
if (
|
|
459
|
+
if (exact2([...base, "reason"]) && message.type === "thumbnail.error" && typeof message.reason === "string" && message.reason.length <= 256)
|
|
355
460
|
return { valid: true, value: null };
|
|
356
|
-
if (!
|
|
461
|
+
if (!exact2([...base, "dataUrl", "width", "height", "label"]) || message.type !== "thumbnail.result")
|
|
357
462
|
return { valid: false };
|
|
358
463
|
const value = normalizeArtifactThumbnail({
|
|
359
464
|
dataUrl: message.dataUrl,
|
|
@@ -1517,6 +1622,15 @@ function lintDesign(html, opts = {}) {
|
|
|
1517
1622
|
const { designSystem = null } = opts;
|
|
1518
1623
|
const errors = [];
|
|
1519
1624
|
const warnings = [];
|
|
1625
|
+
if (opts.screen) {
|
|
1626
|
+
const values = Object.hasOwn(opts.variant?.props ?? {}, opts.screen.id) ? opts.variant.props[opts.screen.id] : {};
|
|
1627
|
+
errors.push(
|
|
1628
|
+
...validateDesignProps({
|
|
1629
|
+
screens: [opts.screen],
|
|
1630
|
+
variants: [{ props: { [opts.screen.id]: values } }]
|
|
1631
|
+
}).map((message) => ({ rule: "invalid-instance-prop", level: "error", message }))
|
|
1632
|
+
);
|
|
1633
|
+
}
|
|
1520
1634
|
const decls = [...styleBlockDecls(html), ...inlineStyleDecls(html)];
|
|
1521
1635
|
for (const d of decls) {
|
|
1522
1636
|
if (SPACING_PROP.test(d.prop)) {
|
|
@@ -1590,11 +1704,64 @@ function lintDesign(html, opts = {}) {
|
|
|
1590
1704
|
summary: `${errors.length} error(s), ${warnings.length} warning(s)`
|
|
1591
1705
|
};
|
|
1592
1706
|
}
|
|
1707
|
+
function withoutRootTheme(html) {
|
|
1708
|
+
if (!/theme-(?:light|dark)|data-theme/iu.test(html)) return null;
|
|
1709
|
+
const body = inspectLocalDocumentBody(html);
|
|
1710
|
+
if (!body) return null;
|
|
1711
|
+
const edits = [];
|
|
1712
|
+
for (const { name, value } of body.attrs) {
|
|
1713
|
+
const location = body.location.attrs?.[name];
|
|
1714
|
+
if (!location) continue;
|
|
1715
|
+
let replacement;
|
|
1716
|
+
if (name === "data-theme" && ["light", "dark"].includes(value)) replacement = "";
|
|
1717
|
+
if (name === "class") {
|
|
1718
|
+
const raw = html.slice(location.startOffset, location.endOffset);
|
|
1719
|
+
const quoted = /^(class\s*=\s*)(["'])([\s\S]*)\2$/iu.exec(raw);
|
|
1720
|
+
if (quoted) {
|
|
1721
|
+
const kept = quoted[3].replace(/(^|\s)theme-(?:light|dark)(?=\s|$)/gu, "$1");
|
|
1722
|
+
if (kept !== quoted[3]) replacement = `${quoted[1]}${quoted[2]}${kept}${quoted[2]}`;
|
|
1723
|
+
} else if (/^class\s*=\s*theme-(?:light|dark)$/iu.test(raw)) replacement = "";
|
|
1724
|
+
}
|
|
1725
|
+
if (replacement !== void 0) edits.push({ ...location, replacement });
|
|
1726
|
+
}
|
|
1727
|
+
if (!edits.length) return null;
|
|
1728
|
+
let normalized = html;
|
|
1729
|
+
for (const { startOffset, endOffset, replacement } of edits.sort(
|
|
1730
|
+
(a, b) => b.startOffset - a.startOffset
|
|
1731
|
+
))
|
|
1732
|
+
normalized = normalized.slice(0, startOffset) + replacement + normalized.slice(endOffset);
|
|
1733
|
+
return normalized;
|
|
1734
|
+
}
|
|
1735
|
+
function lintThemeOnlySources(sources) {
|
|
1736
|
+
const warnings = [];
|
|
1737
|
+
const seen = /* @__PURE__ */ new Map();
|
|
1738
|
+
for (const { screenId, source, html } of sources) {
|
|
1739
|
+
const normalized = withoutRootTheme(html);
|
|
1740
|
+
if (normalized === null) continue;
|
|
1741
|
+
const key = JSON.stringify({
|
|
1742
|
+
html: normalized,
|
|
1743
|
+
styles: source.styles ?? [],
|
|
1744
|
+
scripts: source.scripts ?? []
|
|
1745
|
+
});
|
|
1746
|
+
const previous = seen.get(key);
|
|
1747
|
+
if (previous && previous.screenId !== screenId && previous.source !== source.html && previous.html !== html)
|
|
1748
|
+
warnings.push({
|
|
1749
|
+
rule: "theme-only-source",
|
|
1750
|
+
level: "warn",
|
|
1751
|
+
screenId,
|
|
1752
|
+
message: `Screens ${previous.screenId} (${previous.source}) and ${screenId} (${source.html}) differ only by a root theme marker; declare a theme prop and share one source.`
|
|
1753
|
+
});
|
|
1754
|
+
else seen.set(key, { screenId, source: source.html, html });
|
|
1755
|
+
}
|
|
1756
|
+
return warnings;
|
|
1757
|
+
}
|
|
1593
1758
|
function lintCanvasData(data, { frames } = {}) {
|
|
1594
1759
|
const errors = [];
|
|
1595
1760
|
for (const section of data?.sections || []) {
|
|
1596
1761
|
for (const a of section.artboards || []) {
|
|
1597
|
-
const accepted = frames?.length ? frames.some(
|
|
1762
|
+
const accepted = frames?.length ? frames.some(
|
|
1763
|
+
(frame) => frame.width === a.width && (frame.height === "auto" ? a.height === "auto" || Number.isInteger(a.height) && a.height > 0 && a.height <= 16384 : frame.height === a.height)
|
|
1764
|
+
) : isCanonicalFrame({ w: a.width, h: a.height });
|
|
1598
1765
|
if (!accepted) {
|
|
1599
1766
|
errors.push({
|
|
1600
1767
|
rule: "frame-not-canonical",
|
|
@@ -1758,7 +1925,7 @@ function isRecord(value) {
|
|
|
1758
1925
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
1759
1926
|
}
|
|
1760
1927
|
var digest = (bytes) => createHash("sha256").update(bytes).digest("hex");
|
|
1761
|
-
function boundedRead(url, label, { limit, exact, links = false }) {
|
|
1928
|
+
function boundedRead(url, label, { limit, exact: exact2, links = false }) {
|
|
1762
1929
|
if (!links) {
|
|
1763
1930
|
const stat = lstatSync(url, { throwIfNoEntry: false });
|
|
1764
1931
|
if (!stat?.isFile()) throw new Error(`${label} must be a regular file, not a link.`);
|
|
@@ -1770,15 +1937,15 @@ function boundedRead(url, label, { limit, exact, links = false }) {
|
|
|
1770
1937
|
try {
|
|
1771
1938
|
const stat = fstatSync(descriptor);
|
|
1772
1939
|
if (!stat.isFile()) throw new Error(`${label} must be a regular file, not a link.`);
|
|
1773
|
-
if (
|
|
1774
|
-
throw new Error(`${label} is ${stat.size} bytes; expected ${
|
|
1775
|
-
const capacity = (
|
|
1940
|
+
if (exact2 !== void 0 ? stat.size !== exact2 : stat.size > limit)
|
|
1941
|
+
throw new Error(`${label} is ${stat.size} bytes; expected ${exact2 ?? `at most ${limit}`}.`);
|
|
1942
|
+
const capacity = (exact2 ?? Math.min(stat.size, limit)) + 1;
|
|
1776
1943
|
const buffer = Buffer.alloc(capacity);
|
|
1777
1944
|
let length = 0;
|
|
1778
1945
|
for (let read = -1; read !== 0 && length < capacity; length += read)
|
|
1779
1946
|
read = readSync(descriptor, buffer, length, capacity - length, null);
|
|
1780
1947
|
if (length === capacity) throw new Error(`${label} changed size while it was read.`);
|
|
1781
|
-
if (
|
|
1948
|
+
if (exact2 !== void 0 && length !== exact2)
|
|
1782
1949
|
throw new Error(`${label} changed size while it was read.`);
|
|
1783
1950
|
return buffer.subarray(0, length);
|
|
1784
1951
|
} finally {
|
|
@@ -1994,7 +2161,7 @@ function designNotes(document2) {
|
|
|
1994
2161
|
).join("")}</div></details>`;
|
|
1995
2162
|
}
|
|
1996
2163
|
function stageDetails(document2) {
|
|
1997
|
-
return `<div class="design-stage-context"><div><strong data-design-screen-title>${escapeHtml(document2.screens.find(({ id }) => id === document2.screenOrder[0]).title)}</strong><span data-design-stage-description>Every screen, one connected design</span></div><div class="design-stage-actions">${designNotes(document2)}<label class="design-frame-picker">Frame<select aria-label="Responsive frame" data-design-frame>${document2.frames.map((frame) => `<option value="${escapeHtml(frame.id)}">${escapeHtml(frame
|
|
2164
|
+
return `<div class="design-stage-context"><div><strong data-design-screen-title>${escapeHtml(document2.screens.find(({ id }) => id === document2.screenOrder[0]).title)}</strong><span data-design-stage-description>Every screen, one connected design</span></div><div class="design-stage-actions">${designNotes(document2)}<label class="design-frame-picker">Frame<select aria-label="Responsive frame" data-design-frame>${document2.frames.map((frame) => `<option value="${escapeHtml(frame.id)}">${escapeHtml(designFrameLabel(frame))}</option>`).join("")}</select></label></div></div>
|
|
1998
2165
|
<div class="design-canvas-tools" role="group" aria-label="Canvas controls"><div class="planr-segment design-interaction-picker" role="group" aria-label="Review mode">${iconButton("Interact", "pointer", 'data-planr-mode="interact" aria-pressed="true" aria-keyshortcuts="I"')}${iconButton("Annotate", "comment", 'data-planr-mode="comment" aria-pressed="false" aria-keyshortcuts="C"')}</div><span></span>${button("\u2212", 'data-design-zoom="out" aria-label="Zoom out"')}${button("100%", 'data-design-zoom="reset" aria-label="Reset zoom"')}${button("+", 'data-design-zoom="in" aria-label="Zoom in"')}<span></span>${button("100%", 'data-design-actual-size aria-label="Inspect screen at actual size" aria-pressed="false"')}${button("Focus", 'data-design-focus aria-label="Focus on the preview"')}${button("Fit", 'data-design-fit aria-label="Fit all visible artboards"')}${button("Pan", 'data-design-pan aria-pressed="false" aria-label="Pan canvas" aria-keyshortcuts="H Space" title="Pan canvas (H). Hold Space to pan temporarily; Escape returns to Interact."')}</div>
|
|
1999
2166
|
<div class="design-walkthrough-caption" hidden><div><span data-design-step></span><h2 data-design-narrative-title></h2><p data-design-narrative></p></div><div>${button("Previous", 'data-design-step-change="-1"')}${button("Next", 'data-design-step-change="1"')}</div></div>
|
|
2000
2167
|
<div class="design-notice" role="status" aria-live="polite" hidden><span data-design-notice-message></span><button type="button" data-design-dismiss-notice aria-label="Dismiss notification" title="Dismiss notification"><span aria-hidden="true">\xD7</span></button></div>`;
|
|
@@ -2016,7 +2183,8 @@ function renderDesignStudioMarkup({
|
|
|
2016
2183
|
stalePins = [],
|
|
2017
2184
|
reviewContext = null,
|
|
2018
2185
|
contextDigest = null,
|
|
2019
|
-
fingerprints = []
|
|
2186
|
+
fingerprints = [],
|
|
2187
|
+
contentIdentity = null
|
|
2020
2188
|
} = {}, {
|
|
2021
2189
|
stageRuntimeUrl = "./artifact-review-stage.js",
|
|
2022
2190
|
renderShell,
|
|
@@ -2047,6 +2215,7 @@ function renderDesignStudioMarkup({
|
|
|
2047
2215
|
reviewContext,
|
|
2048
2216
|
contextDigest,
|
|
2049
2217
|
fingerprints,
|
|
2218
|
+
contentIdentity,
|
|
2050
2219
|
artifactKinds: Object.fromEntries(
|
|
2051
2220
|
envelope.artifacts.map((artifact) => [artifact.id, artifact.kind])
|
|
2052
2221
|
),
|
|
@@ -2138,7 +2307,8 @@ function createDesignStudioEntries(document2, envelope) {
|
|
|
2138
2307
|
artifactId,
|
|
2139
2308
|
variantId: variant.id,
|
|
2140
2309
|
screenId,
|
|
2141
|
-
frameId: frame.id
|
|
2310
|
+
frameId: frame.id,
|
|
2311
|
+
...frame.height === "auto" ? { height: "auto" } : {}
|
|
2142
2312
|
});
|
|
2143
2313
|
}
|
|
2144
2314
|
}
|
|
@@ -2163,6 +2333,101 @@ function renderDesignStudio(input = {}, options = {}) {
|
|
|
2163
2333
|
);
|
|
2164
2334
|
}
|
|
2165
2335
|
|
|
2336
|
+
// packages/design/lib/design/view-context.mjs
|
|
2337
|
+
import { readFileSync as readFileSync4 } from "node:fs";
|
|
2338
|
+
import { join } from "node:path";
|
|
2339
|
+
var anchorPattern = new RegExp(DESIGN_DOCUMENT_SCHEMA.$defs.id.pattern, "u");
|
|
2340
|
+
var exact = (value, keys) => value !== null && typeof value === "object" && !Array.isArray(value) && Object.keys(value).length === keys.length && keys.every((key) => Object.hasOwn(value, key));
|
|
2341
|
+
var boardFields = ["screenId", "frameId", "variantId"];
|
|
2342
|
+
function validateDesignViewContext(input, current) {
|
|
2343
|
+
if (!exact(input, ["revision", "view", "visibleScreens", "selected", "dirty"]))
|
|
2344
|
+
throw new Error(
|
|
2345
|
+
"View context requires exactly revision, view, visibleScreens, selected and dirty."
|
|
2346
|
+
);
|
|
2347
|
+
if (input.revision !== current.revision)
|
|
2348
|
+
throw Object.assign(
|
|
2349
|
+
new Error(
|
|
2350
|
+
`View context revision ${input.revision} is stale; current revision is ${current.revision}.`
|
|
2351
|
+
),
|
|
2352
|
+
{ statusCode: 409 }
|
|
2353
|
+
);
|
|
2354
|
+
if (!["canvas", "prototype", "walkthrough"].includes(input.view))
|
|
2355
|
+
throw new Error(`Unknown view context view ${input.view}.`);
|
|
2356
|
+
if (typeof input.dirty !== "boolean")
|
|
2357
|
+
throw new Error(`View context dirty must be boolean; received ${input.dirty}.`);
|
|
2358
|
+
const board = (value, selected = false) => {
|
|
2359
|
+
if (!exact(value, selected ? [...boardFields, "planrId"] : boardFields))
|
|
2360
|
+
throw new Error(
|
|
2361
|
+
`View context ${selected ? "selected" : "visibleScreens entry"} has invalid fields.`
|
|
2362
|
+
);
|
|
2363
|
+
if (!current.entries.some((entry) => boardFields.every((key) => entry[key] === value[key])))
|
|
2364
|
+
throw new Error(`Unknown view context board ${JSON.stringify(value)}.`);
|
|
2365
|
+
return boardFields.map((key) => value[key]).join("/");
|
|
2366
|
+
};
|
|
2367
|
+
if (!Array.isArray(input.visibleScreens) || input.visibleScreens.length > current.entries.length)
|
|
2368
|
+
throw new Error(
|
|
2369
|
+
`View context visibleScreens must contain at most ${current.entries.length} boards.`
|
|
2370
|
+
);
|
|
2371
|
+
const keys = input.visibleScreens.map((value) => board(value));
|
|
2372
|
+
if (new Set(keys).size !== keys.length)
|
|
2373
|
+
throw new Error("View context visibleScreens contains duplicate boards.");
|
|
2374
|
+
board(input.selected, true);
|
|
2375
|
+
const { planrId } = input.selected;
|
|
2376
|
+
if (planrId !== null && (typeof planrId !== "string" || planrId.length > 128 || !anchorPattern.test(planrId)))
|
|
2377
|
+
throw new Error(
|
|
2378
|
+
`View context planrId ${JSON.stringify(planrId)} must be null or a document anchor ID of at most 128 characters.`
|
|
2379
|
+
);
|
|
2380
|
+
return structuredClone(input);
|
|
2381
|
+
}
|
|
2382
|
+
function saveDesignViewContext(file, input, clock) {
|
|
2383
|
+
const current = currentDesign(file);
|
|
2384
|
+
const context = validateDesignViewContext(input, current);
|
|
2385
|
+
const value = {
|
|
2386
|
+
kind: "openplanr-design-view-context",
|
|
2387
|
+
schemaVersion: "1.0.0",
|
|
2388
|
+
...context,
|
|
2389
|
+
updatedAt: clock().toISOString()
|
|
2390
|
+
};
|
|
2391
|
+
atomicJson(join(current.root, ".design/view-context.json"), value);
|
|
2392
|
+
return { ok: true };
|
|
2393
|
+
}
|
|
2394
|
+
function readDesignViewContext(file, { requestTime } = {}) {
|
|
2395
|
+
try {
|
|
2396
|
+
const current = currentDesign(file);
|
|
2397
|
+
const path = join(current.root, ".design/view-context.json");
|
|
2398
|
+
const bytes = readFileSync4(path);
|
|
2399
|
+
if (bytes.length > 128 * 1024) throw new Error(`${path} exceeds 128 KB.`);
|
|
2400
|
+
const value = JSON.parse(bytes.toString("utf8"));
|
|
2401
|
+
if (!exact(value, [
|
|
2402
|
+
"kind",
|
|
2403
|
+
"schemaVersion",
|
|
2404
|
+
"revision",
|
|
2405
|
+
"updatedAt",
|
|
2406
|
+
"view",
|
|
2407
|
+
"visibleScreens",
|
|
2408
|
+
"selected",
|
|
2409
|
+
"dirty"
|
|
2410
|
+
]) || value.kind !== "openplanr-design-view-context" || value.schemaVersion !== "1.0.0")
|
|
2411
|
+
throw new Error(`${path} is not a supported design view context.`);
|
|
2412
|
+
if (typeof value.updatedAt !== "string" || !Number.isFinite(Date.parse(value.updatedAt)))
|
|
2413
|
+
throw new Error(`${path} has an invalid updatedAt timestamp.`);
|
|
2414
|
+
const { kind, schemaVersion, updatedAt, ...input } = value;
|
|
2415
|
+
validateDesignViewContext(input, current);
|
|
2416
|
+
if (requestTime !== void 0) {
|
|
2417
|
+
const requestedAt = Date.parse(requestTime);
|
|
2418
|
+
if (!Number.isFinite(requestedAt))
|
|
2419
|
+
throw new Error(`Invalid view context request time ${requestTime}.`);
|
|
2420
|
+
if (Date.parse(updatedAt) < requestedAt)
|
|
2421
|
+
throw new Error(
|
|
2422
|
+
`View context updatedAt ${updatedAt} is older than request ${requestTime}.`
|
|
2423
|
+
);
|
|
2424
|
+
}
|
|
2425
|
+
return value;
|
|
2426
|
+
} catch (error) {
|
|
2427
|
+
return { viewContext: null, reason: error.message };
|
|
2428
|
+
}
|
|
2429
|
+
}
|
|
2430
|
+
|
|
2166
2431
|
// packages/design/lib/design/document.mjs
|
|
2167
2432
|
var DESIGN_VIEWS = Object.freeze(["canvas", "prototype", "walkthrough"]);
|
|
2168
2433
|
var DESIGN_RENDERER_VERSION = "1.3.0";
|
|
@@ -2184,7 +2449,7 @@ function inspectDesignDocument(file, { readSource } = {}) {
|
|
|
2184
2449
|
`This board needs ${sourceCount} screen sources and ${viewCount} viewport references. Split it into linked boards: one board supports 256 sources and 4096 views.`
|
|
2185
2450
|
);
|
|
2186
2451
|
const sources = new Set(document2.assets ?? []);
|
|
2187
|
-
if (existsSync2(
|
|
2452
|
+
if (existsSync2(join2(root, "review-context.json"))) sources.add("review-context.json");
|
|
2188
2453
|
if (document2.designSystem?.tokens) sources.add(document2.designSystem.tokens);
|
|
2189
2454
|
for (const screen of document2.screens)
|
|
2190
2455
|
for (const source of [
|
|
@@ -2212,7 +2477,7 @@ function inspectDesignDocument(file, { readSource } = {}) {
|
|
|
2212
2477
|
missing,
|
|
2213
2478
|
specPath: designSpecPath(root),
|
|
2214
2479
|
// Guarded source preparation is independent of local render cache state.
|
|
2215
|
-
current: readSource ? null : readJson(
|
|
2480
|
+
current: readSource ? null : readJson(join2(root, ".design/current.json"), null)
|
|
2216
2481
|
};
|
|
2217
2482
|
}
|
|
2218
2483
|
function prepareDesignDocument(file, { readSource, passive = false, maxBytes } = {}) {
|
|
@@ -2227,12 +2492,23 @@ function prepareDesignDocument(file, { readSource, passive = false, maxBytes } =
|
|
|
2227
2492
|
const sourceContents = new Map(
|
|
2228
2493
|
inspected.sources.map((source) => [
|
|
2229
2494
|
source,
|
|
2230
|
-
readSource ? readSource(source, root).value :
|
|
2495
|
+
readSource ? readSource(source, root).value : readFileSync5(resolveLocalDocumentFile(root, source))
|
|
2231
2496
|
])
|
|
2232
2497
|
);
|
|
2233
2498
|
for (const variant of document2.variants.filter((item) => item.status === "ready")) {
|
|
2499
|
+
const themeWarnings = lintThemeOnlySources(
|
|
2500
|
+
document2.screens.map((screen) => {
|
|
2501
|
+
const source = variant.sources?.[screen.id] ?? screen.source;
|
|
2502
|
+
return {
|
|
2503
|
+
screenId: screen.id,
|
|
2504
|
+
source,
|
|
2505
|
+
html: sourceContents.get(source.html).toString("utf8")
|
|
2506
|
+
};
|
|
2507
|
+
})
|
|
2508
|
+
);
|
|
2234
2509
|
for (const screenId of document2.screenOrder) {
|
|
2235
2510
|
const screen = document2.screens.find((item) => item.id === screenId);
|
|
2511
|
+
const values = Object.hasOwn(variant.props ?? {}, screenId) ? variant.props[screenId] : {};
|
|
2236
2512
|
const bundled = bundleLocalDocument({
|
|
2237
2513
|
root,
|
|
2238
2514
|
source: variant.sources?.[screenId] ?? screen.source,
|
|
@@ -2240,8 +2516,21 @@ function prepareDesignDocument(file, { readSource, passive = false, maxBytes } =
|
|
|
2240
2516
|
screenId,
|
|
2241
2517
|
readSource,
|
|
2242
2518
|
passive,
|
|
2519
|
+
...screen.props ? {
|
|
2520
|
+
screenProps: Object.fromEntries(
|
|
2521
|
+
Object.entries(screen.props).map(([name, declaration]) => [
|
|
2522
|
+
name,
|
|
2523
|
+
Object.hasOwn(values, name) ? values[name] : declaration.default
|
|
2524
|
+
])
|
|
2525
|
+
)
|
|
2526
|
+
} : {},
|
|
2243
2527
|
...maxBytes === void 0 ? {} : { maxBytes }
|
|
2244
2528
|
});
|
|
2529
|
+
if (document2.frames.some(({ height }) => height === "auto"))
|
|
2530
|
+
bundled.html = bundled.html.replace(
|
|
2531
|
+
"</body>",
|
|
2532
|
+
`<script>(${observeDesignFrameSize.toString()})()</script></body>`
|
|
2533
|
+
);
|
|
2245
2534
|
const navigate = `<script>document.addEventListener('click',function(event){var link=event.target.closest('[data-design-target],[data-planr-navigate],[data-design-navigate]');if(!link)return;event.preventDefault();parent.postMessage({type:'openplanr:design-navigate',screenId:link.getAttribute('data-design-target')||link.getAttribute('data-planr-navigate')||link.getAttribute('data-design-navigate')},'*')});document.addEventListener('submit',function(event){event.preventDefault()});</script>`;
|
|
2246
2535
|
if (!passive) bundled.html = bundled.html.replace("</body>", `${navigate}</body>`);
|
|
2247
2536
|
for (const name of bundled.files) {
|
|
@@ -2249,7 +2538,7 @@ function prepareDesignDocument(file, { readSource, passive = false, maxBytes } =
|
|
|
2249
2538
|
if (!sourceContents.has(name))
|
|
2250
2539
|
sourceContents.set(
|
|
2251
2540
|
name,
|
|
2252
|
-
readSource ? readSource(name, root).value :
|
|
2541
|
+
readSource ? readSource(name, root).value : readFileSync5(resolveLocalDocumentFile(root, name))
|
|
2253
2542
|
);
|
|
2254
2543
|
if (hash(sourceContents.get(name)) !== bundled.sourceDigests[name])
|
|
2255
2544
|
throw new Error(
|
|
@@ -2257,8 +2546,12 @@ function prepareDesignDocument(file, { readSource, passive = false, maxBytes } =
|
|
|
2257
2546
|
);
|
|
2258
2547
|
}
|
|
2259
2548
|
const report = lintDesign(bundled.html, {
|
|
2260
|
-
designSystem: document2.designSystem
|
|
2549
|
+
designSystem: document2.designSystem,
|
|
2550
|
+
screen,
|
|
2551
|
+
variant
|
|
2261
2552
|
});
|
|
2553
|
+
report.warnings.push(...themeWarnings.filter((item) => item.screenId === screenId));
|
|
2554
|
+
report.summary = `${report.errors.length} error(s), ${report.warnings.length} warning(s)`;
|
|
2262
2555
|
lint.push({ variantId: variant.id, screenId, ...report });
|
|
2263
2556
|
for (const anchor of screen.anchors ?? []) {
|
|
2264
2557
|
if (!bundled.html.includes(`data-planr-id="${anchor}"`) && !bundled.html.includes(`id="${anchor}"`))
|
|
@@ -2287,14 +2580,15 @@ function prepareDesignDocument(file, { readSource, passive = false, maxBytes } =
|
|
|
2287
2580
|
kind: "html",
|
|
2288
2581
|
title: `${screen.title} \xB7 ${variant.label} \xB7 ${frame.label}`,
|
|
2289
2582
|
sourceId,
|
|
2290
|
-
viewport:
|
|
2583
|
+
viewport: designFrameViewport(document2, frame),
|
|
2291
2584
|
colorScheme: "light"
|
|
2292
2585
|
});
|
|
2293
2586
|
entries.push({
|
|
2294
2587
|
artifactId,
|
|
2295
2588
|
screenId,
|
|
2296
2589
|
variantId: variant.id,
|
|
2297
|
-
frameId: frame.id
|
|
2590
|
+
frameId: frame.id,
|
|
2591
|
+
...frame.height === "auto" ? { height: "auto" } : {}
|
|
2298
2592
|
});
|
|
2299
2593
|
}
|
|
2300
2594
|
}
|
|
@@ -2347,7 +2641,7 @@ function designRendererRevision() {
|
|
|
2347
2641
|
(name) => name === "studio.js" || existsSync2(new URL(`../../templates/studio/${name}`, new URL("./runtime/packages/design/lib/design/document.mjs", import.meta.url).href))
|
|
2348
2642
|
).map(
|
|
2349
2643
|
(name) => hash(
|
|
2350
|
-
name === "studio.js" ? readDesignStudioRuntime() :
|
|
2644
|
+
name === "studio.js" ? readDesignStudioRuntime() : readFileSync5(new URL(`../../templates/studio/${name}`, new URL("./runtime/packages/design/lib/design/document.mjs", import.meta.url).href))
|
|
2351
2645
|
)
|
|
2352
2646
|
)
|
|
2353
2647
|
})
|
|
@@ -2418,22 +2712,34 @@ ${runtime}` : runtime;
|
|
|
2418
2712
|
{ stageRuntimeUrl: runtimeUrl }
|
|
2419
2713
|
);
|
|
2420
2714
|
}
|
|
2421
|
-
async function renderDesignDocument(file, {
|
|
2715
|
+
async function renderDesignDocument(file, options = {}) {
|
|
2716
|
+
return withDesignRenderLock(file, (render) => render(options));
|
|
2717
|
+
}
|
|
2718
|
+
async function withDesignRenderLock(file, action) {
|
|
2719
|
+
const { root } = loadDesignDocument(file);
|
|
2720
|
+
const work = join2(root, ".design");
|
|
2721
|
+
mkdirSync(work, { recursive: true });
|
|
2722
|
+
const release = await acquireStartLock(join2(work, "render.lock"), {
|
|
2723
|
+
timeout: 1e3,
|
|
2724
|
+
stale: 3e4
|
|
2725
|
+
});
|
|
2726
|
+
try {
|
|
2727
|
+
recoverDesignPublication(root, { ownsRenderLock: true });
|
|
2728
|
+
return await action((options) => renderDesignDocumentUnlocked(file, options));
|
|
2729
|
+
} finally {
|
|
2730
|
+
release();
|
|
2731
|
+
}
|
|
2732
|
+
}
|
|
2733
|
+
async function renderDesignDocumentUnlocked(file, {
|
|
2422
2734
|
beforeCommit,
|
|
2423
2735
|
writePointer = atomicJson,
|
|
2424
2736
|
rendererRevision = designRendererRevision(),
|
|
2425
2737
|
now = () => (/* @__PURE__ */ new Date()).toISOString()
|
|
2426
2738
|
} = {}) {
|
|
2427
2739
|
const { root } = loadDesignDocument(file);
|
|
2428
|
-
const work =
|
|
2429
|
-
mkdirSync(work, { recursive: true });
|
|
2430
|
-
const release = await acquireStartLock(join(work, "render.lock"), {
|
|
2431
|
-
timeout: 1e3,
|
|
2432
|
-
stale: 3e4
|
|
2433
|
-
});
|
|
2740
|
+
const work = join2(root, ".design");
|
|
2434
2741
|
let temporary;
|
|
2435
2742
|
try {
|
|
2436
|
-
recoverDesignPublication(root, { ownsRenderLock: true });
|
|
2437
2743
|
const prepared = prepareDesignDocument(file);
|
|
2438
2744
|
const errors = prepared.lint.flatMap(
|
|
2439
2745
|
(item) => item.errors.map((error) => `${item.screenId}: ${error.message}`)
|
|
@@ -2441,15 +2747,15 @@ async function renderDesignDocument(file, {
|
|
|
2441
2747
|
if (errors.length) throw new Error(`Design lint failed:
|
|
2442
2748
|
${errors.join("\n")}`);
|
|
2443
2749
|
const specPath = designSpecPath(root);
|
|
2444
|
-
const spec =
|
|
2750
|
+
const spec = readFileSync5(specPath, "utf8");
|
|
2445
2751
|
for (let section = 1; section <= 10; section++)
|
|
2446
2752
|
if (!new RegExp(`^## ${section}\\. `, "m").test(spec))
|
|
2447
2753
|
throw new Error(`design-spec.md is missing section ${section}.`);
|
|
2448
2754
|
prepared.revision = hash(json({ source: prepared.revision, spec, rendererRevision }));
|
|
2449
|
-
const directory =
|
|
2450
|
-
const previous = readJson(
|
|
2755
|
+
const directory = join2(work, "revisions", prepared.revision);
|
|
2756
|
+
const previous = readJson(join2(work, "current.json"), null);
|
|
2451
2757
|
const generatedAt = now();
|
|
2452
|
-
const manifest = existsSync2(directory) ? readJson(
|
|
2758
|
+
const manifest = existsSync2(directory) ? readJson(join2(directory, "render.json")).manifest : buildManifest({
|
|
2453
2759
|
framework: "vanilla",
|
|
2454
2760
|
designFormat: prepared.document.defaultView,
|
|
2455
2761
|
source: prepared.document.brief.source,
|
|
@@ -2474,39 +2780,39 @@ ${errors.join("\n")}`);
|
|
|
2474
2780
|
manifest
|
|
2475
2781
|
};
|
|
2476
2782
|
if (!existsSync2(directory)) {
|
|
2477
|
-
temporary =
|
|
2478
|
-
mkdirSync(
|
|
2479
|
-
writeFileSync(
|
|
2480
|
-
writeFileSync(
|
|
2481
|
-
writeFileSync(
|
|
2783
|
+
temporary = join2(work, `pending-${randomUUID()}`);
|
|
2784
|
+
mkdirSync(join2(temporary, "sources"), { recursive: true });
|
|
2785
|
+
writeFileSync(join2(temporary, "render.json"), json(record));
|
|
2786
|
+
writeFileSync(join2(temporary, "design-document.json"), json(prepared.document));
|
|
2787
|
+
writeFileSync(join2(temporary, "design-spec.md"), spec);
|
|
2482
2788
|
for (const source of prepared.sourceFiles) {
|
|
2483
|
-
const destination =
|
|
2789
|
+
const destination = join2(temporary, "sources", source);
|
|
2484
2790
|
mkdirSync(dirname(destination), { recursive: true });
|
|
2485
2791
|
writeFileSync(destination, prepared.sourceContents.get(source));
|
|
2486
2792
|
}
|
|
2487
2793
|
for (const view of DESIGN_VIEWS)
|
|
2488
|
-
writeFileSync(
|
|
2794
|
+
writeFileSync(join2(temporary, `${view}.html`), standaloneDesignHtml(record, view));
|
|
2489
2795
|
beforeCommit?.(record);
|
|
2490
2796
|
mkdirSync(dirname(directory), { recursive: true });
|
|
2491
2797
|
renameSync(temporary, directory);
|
|
2492
2798
|
temporary = null;
|
|
2493
2799
|
}
|
|
2494
|
-
const manifestPath =
|
|
2495
|
-
atomicJson(
|
|
2800
|
+
const manifestPath = join2(root, "finalized.json");
|
|
2801
|
+
atomicJson(join2(work, "publication.json"), {
|
|
2496
2802
|
revision: prepared.revision,
|
|
2497
2803
|
previousRevision: previous?.revision ?? null,
|
|
2498
2804
|
manifest,
|
|
2499
|
-
previousManifest: existsSync2(manifestPath) ?
|
|
2805
|
+
previousManifest: existsSync2(manifestPath) ? readFileSync5(manifestPath).toString("base64") : null
|
|
2500
2806
|
});
|
|
2501
2807
|
try {
|
|
2502
2808
|
atomicJson(manifestPath, manifest);
|
|
2503
|
-
writePointer(
|
|
2809
|
+
writePointer(join2(work, "current.json"), {
|
|
2504
2810
|
revision: prepared.revision,
|
|
2505
2811
|
previousRevision: previous?.revision === prepared.revision ? previous.previousRevision : previous?.revision ?? null,
|
|
2506
2812
|
iterations: manifest.iterations,
|
|
2507
2813
|
generatedAt: manifest.generated_at
|
|
2508
2814
|
});
|
|
2509
|
-
rmSync(
|
|
2815
|
+
rmSync(join2(work, "publication.json"), { force: true });
|
|
2510
2816
|
} catch (error) {
|
|
2511
2817
|
recoverDesignPublication(root, { ownsRenderLock: true });
|
|
2512
2818
|
throw error;
|
|
@@ -2515,20 +2821,100 @@ ${errors.join("\n")}`);
|
|
|
2515
2821
|
ok: true,
|
|
2516
2822
|
revision: prepared.revision,
|
|
2517
2823
|
document: resolve2(file),
|
|
2518
|
-
artifact:
|
|
2824
|
+
artifact: join2(directory, `${prepared.document.defaultView}.html`),
|
|
2519
2825
|
views: Object.fromEntries(
|
|
2520
|
-
DESIGN_VIEWS.map((view) => [view,
|
|
2826
|
+
DESIGN_VIEWS.map((view) => [view, join2(directory, `${view}.html`)])
|
|
2521
2827
|
),
|
|
2522
|
-
manifest:
|
|
2828
|
+
manifest: join2(root, "finalized.json"),
|
|
2523
2829
|
spec: specPath,
|
|
2524
2830
|
verification: "unverified"
|
|
2525
2831
|
};
|
|
2526
2832
|
} finally {
|
|
2527
2833
|
if (temporary) rmSync(temporary, { recursive: true, force: true });
|
|
2528
|
-
release();
|
|
2529
2834
|
}
|
|
2530
2835
|
}
|
|
2531
2836
|
|
|
2837
|
+
// packages/design/lib/design/layout-save.mjs
|
|
2838
|
+
async function saveDesignLayout(file, input) {
|
|
2839
|
+
if (!input || typeof input !== "object" || Array.isArray(input) || Object.keys(input).some((key) => !["revision", "boards", "restoreRevision"].includes(key)) || typeof input.revision !== "string" || Object.hasOwn(input, "boards") === Object.hasOwn(input, "restoreRevision"))
|
|
2840
|
+
throw new Error("Design layout requires a revision and either boards or restoreRevision.");
|
|
2841
|
+
return withDesignRenderLock(file, async (render) => {
|
|
2842
|
+
const current = currentDesign(file);
|
|
2843
|
+
if (input.revision !== current.revision)
|
|
2844
|
+
throw Object.assign(new Error("The design changed. Reload before saving its layout."), {
|
|
2845
|
+
statusCode: 409
|
|
2846
|
+
});
|
|
2847
|
+
const authored = prepareDesignDocument(file);
|
|
2848
|
+
const authoredContent = { ...authored.document };
|
|
2849
|
+
const committedContent = { ...current.document };
|
|
2850
|
+
delete authoredContent.layout;
|
|
2851
|
+
delete committedContent.layout;
|
|
2852
|
+
if (digestArtifactEnvelope(authored.envelope) !== digestArtifactEnvelope(current.envelope) || JSON.stringify(authored.fingerprints) !== JSON.stringify(current.fingerprints) || JSON.stringify(authoredContent) !== JSON.stringify(committedContent) || readFileSync6(designSpecPath(current.root), "utf8") !== readFileSync6(join3(current.directory, "design-spec.md"), "utf8"))
|
|
2853
|
+
throw Object.assign(
|
|
2854
|
+
new Error(
|
|
2855
|
+
"Design sources or content changed. Render the design and reload before saving its layout."
|
|
2856
|
+
),
|
|
2857
|
+
{ statusCode: 409 }
|
|
2858
|
+
);
|
|
2859
|
+
const previous = readFileSync6(file, "utf8");
|
|
2860
|
+
const mode = statSync(file).mode & 4095;
|
|
2861
|
+
const document2 = JSON.parse(previous);
|
|
2862
|
+
if (Object.hasOwn(input, "restoreRevision")) {
|
|
2863
|
+
if (typeof input.restoreRevision !== "string" || !/^[a-f0-9]{64}$/u.test(input.restoreRevision))
|
|
2864
|
+
throw new Error(`Invalid layout restore revision ${input.restoreRevision}.`);
|
|
2865
|
+
const restored = readJson(
|
|
2866
|
+
join3(current.root, ".design/revisions", input.restoreRevision, "design-document.json")
|
|
2867
|
+
);
|
|
2868
|
+
if (restored.layout === void 0) delete document2.layout;
|
|
2869
|
+
else document2.layout = structuredClone(restored.layout);
|
|
2870
|
+
} else {
|
|
2871
|
+
if (!input.boards || typeof input.boards !== "object" || Array.isArray(input.boards))
|
|
2872
|
+
throw new Error("Design layout boards must be an object of exact board keys.");
|
|
2873
|
+
const boards = { ...document2.layout?.boards };
|
|
2874
|
+
for (const [key, point] of Object.entries(input.boards)) {
|
|
2875
|
+
if (!current.entries.some(
|
|
2876
|
+
(entry) => `${entry.screenId}/${entry.frameId}/${entry.variantId}` === key
|
|
2877
|
+
))
|
|
2878
|
+
throw new Error(`Unknown exact design board key ${key}.`);
|
|
2879
|
+
if (point === null) delete boards[key];
|
|
2880
|
+
else {
|
|
2881
|
+
if (!point || typeof point !== "object" || Array.isArray(point) || Object.keys(point).some((field) => !["x", "y"].includes(field)) || !Number.isFinite(point.x) || !Number.isFinite(point.y) || Math.abs(point.x) > 1e7 || Math.abs(point.y) > 1e7)
|
|
2882
|
+
throw new Error(
|
|
2883
|
+
`Design board ${key} requires finite x and y coordinates within \xB110000000.`
|
|
2884
|
+
);
|
|
2885
|
+
boards[key] = { ...boards[key], x: point.x, y: point.y };
|
|
2886
|
+
}
|
|
2887
|
+
}
|
|
2888
|
+
document2.layout = { ...document2.layout, boards };
|
|
2889
|
+
if (!Object.keys(boards).length) delete document2.layout.boards;
|
|
2890
|
+
if (!Object.keys(document2.layout).length) delete document2.layout;
|
|
2891
|
+
}
|
|
2892
|
+
assertDesignDocument(document2);
|
|
2893
|
+
const indent = previous.match(/^([\t ]+)\S/mu)?.[1] ?? "";
|
|
2894
|
+
const formatted = indent ? JSON.stringify(document2, null, " ").replace(
|
|
2895
|
+
/^\t+/gmu,
|
|
2896
|
+
(tabs) => indent.repeat(tabs.length)
|
|
2897
|
+
) : JSON.stringify(document2);
|
|
2898
|
+
const written = `${formatted}${previous.endsWith("\n") ? "\n" : ""}`;
|
|
2899
|
+
atomicBytes(file, written, mode);
|
|
2900
|
+
try {
|
|
2901
|
+
const result = await render();
|
|
2902
|
+
return { revision: result.revision };
|
|
2903
|
+
} catch (error) {
|
|
2904
|
+
if (hash(readFileSync6(file)) !== hash(written))
|
|
2905
|
+
throw Object.assign(
|
|
2906
|
+
new Error(
|
|
2907
|
+
`The authored document ${file} changed during the save. Its newer contents were preserved; reload before saving its layout.`,
|
|
2908
|
+
{ cause: error }
|
|
2909
|
+
),
|
|
2910
|
+
{ statusCode: 409 }
|
|
2911
|
+
);
|
|
2912
|
+
atomicBytes(file, previous, mode);
|
|
2913
|
+
throw error;
|
|
2914
|
+
}
|
|
2915
|
+
});
|
|
2916
|
+
}
|
|
2917
|
+
|
|
2532
2918
|
export {
|
|
2533
2919
|
mintCapabilityToken,
|
|
2534
2920
|
isCapabilityToken,
|
|
@@ -2536,11 +2922,16 @@ export {
|
|
|
2536
2922
|
prepareArtifactDocument,
|
|
2537
2923
|
createArtifactBridgeNonce,
|
|
2538
2924
|
renderArtifactParentRuntime,
|
|
2925
|
+
matchesDesignFrame,
|
|
2539
2926
|
readRuntimeAsset,
|
|
2540
2927
|
renderDesignStudio,
|
|
2928
|
+
saveDesignLayout,
|
|
2929
|
+
saveDesignViewContext,
|
|
2930
|
+
readDesignViewContext,
|
|
2541
2931
|
inspectDesignDocument,
|
|
2542
2932
|
prepareDesignDocument,
|
|
2543
2933
|
designRendererRevision,
|
|
2544
2934
|
standaloneDesignHtml,
|
|
2545
|
-
renderDesignDocument
|
|
2935
|
+
renderDesignDocument,
|
|
2936
|
+
withDesignRenderLock
|
|
2546
2937
|
};
|