openplanr 2.2641.1 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (315) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/README.md +1 -1
  3. package/dist/cli/commands/artifact.js +1 -1
  4. package/dist/cli/commands/artifact.js.map +1 -1
  5. package/dist/cli/commands/doctor.d.ts.map +1 -1
  6. package/dist/cli/commands/doctor.js +19 -4
  7. package/dist/cli/commands/doctor.js.map +1 -1
  8. package/dist/cli/commands/github.d.ts.map +1 -1
  9. package/dist/cli/commands/github.js +7 -10
  10. package/dist/cli/commands/github.js.map +1 -1
  11. package/dist/cli/commands/linear.js +1 -1
  12. package/dist/cli/commands/linear.js.map +1 -1
  13. package/dist/cli/commands/report.d.ts.map +1 -1
  14. package/dist/cli/commands/report.js +28 -32
  15. package/dist/cli/commands/report.js.map +1 -1
  16. package/dist/cli/commands/upgrade.d.ts.map +1 -1
  17. package/dist/cli/commands/upgrade.js +12 -10
  18. package/dist/cli/commands/upgrade.js.map +1 -1
  19. package/dist/cli/error-boundary.d.ts.map +1 -1
  20. package/dist/cli/error-boundary.js +2 -1
  21. package/dist/cli/error-boundary.js.map +1 -1
  22. package/dist/dashboard/.vite/manifest.json +1 -1
  23. package/dist/dashboard/assets/{index-DGyC7RDz.js → index-Csby7_ur.js} +2 -2
  24. package/dist/dashboard/assets/{index-DGyC7RDz.js.map → index-Csby7_ur.js.map} +1 -1
  25. package/dist/dashboard/dashboard-manifest.json +8 -8
  26. package/dist/dashboard/index.html +1 -1
  27. package/dist/models/schema.d.ts +0 -4
  28. package/dist/models/schema.d.ts.map +1 -1
  29. package/dist/models/schema.js +0 -2
  30. package/dist/models/schema.js.map +1 -1
  31. package/dist/models/types.d.ts +1 -4
  32. package/dist/models/types.d.ts.map +1 -1
  33. package/dist/services/credentials-service.js +1 -1
  34. package/dist/services/credentials-service.js.map +1 -1
  35. package/dist/services/distribution-service.d.ts +1 -4
  36. package/dist/services/distribution-service.d.ts.map +1 -1
  37. package/dist/services/distribution-service.js +1 -60
  38. package/dist/services/distribution-service.js.map +1 -1
  39. package/dist/services/github-service.d.ts +7 -4
  40. package/dist/services/github-service.d.ts.map +1 -1
  41. package/dist/services/github-service.js +16 -15
  42. package/dist/services/github-service.js.map +1 -1
  43. package/dist/services/linear-push-service.d.ts +3 -4
  44. package/dist/services/linear-push-service.d.ts.map +1 -1
  45. package/dist/services/linear-push-service.js +5 -6
  46. package/dist/services/linear-push-service.js.map +1 -1
  47. package/dist/services/runtime-change-summary.d.ts +4 -0
  48. package/dist/services/runtime-change-summary.d.ts.map +1 -1
  49. package/dist/services/runtime-change-summary.js +7 -0
  50. package/dist/services/runtime-change-summary.js.map +1 -1
  51. package/dist/services/runtime-manager/doctor.js +1 -1
  52. package/dist/services/runtime-manager/doctor.js.map +1 -1
  53. package/dist/services/runtime-manager/runtime-package.d.ts +15 -0
  54. package/dist/services/runtime-manager/runtime-package.d.ts.map +1 -1
  55. package/dist/services/runtime-manager/runtime-package.js +50 -10
  56. package/dist/services/runtime-manager/runtime-package.js.map +1 -1
  57. package/dist/services/runtime-manager-service.d.ts +11 -0
  58. package/dist/services/runtime-manager-service.d.ts.map +1 -1
  59. package/dist/services/runtime-manager-service.js +88 -16
  60. package/dist/services/runtime-manager-service.js.map +1 -1
  61. package/dist/services/spec-service.d.ts.map +1 -1
  62. package/dist/services/spec-service.js +34 -69
  63. package/dist/services/spec-service.js.map +1 -1
  64. package/dist/services/upgrade-report.d.ts +2 -2
  65. package/dist/services/upgrade-report.d.ts.map +1 -1
  66. package/dist/services/upgrade-report.js +11 -2
  67. package/dist/services/upgrade-report.js.map +1 -1
  68. package/dist/services/upgrade-service.d.ts +8 -2
  69. package/dist/services/upgrade-service.d.ts.map +1 -1
  70. package/dist/services/upgrade-service.js +44 -12
  71. package/dist/services/upgrade-service.js.map +1 -1
  72. package/dist/templates/rules/shared/capability-map.md.hbs +1 -1
  73. package/docs/CLI.md +14 -15
  74. package/docs/TROUBLESHOOTING.md +9 -6
  75. package/install.ps1 +3 -3
  76. package/install.sh +3 -3
  77. package/lib/host-packages/adapter-registry.json +5 -5
  78. package/lib/host-packages/capability-map.json +8 -8
  79. package/lib/host-packages/claude/.claude-plugin/marketplace.json +2 -2
  80. package/lib/host-packages/claude/openplanr/.claude-plugin/plugin.json +2 -2
  81. package/lib/host-packages/claude/openplanr/.openplanr-content.json +91 -75
  82. package/lib/host-packages/claude/openplanr/README.md +8 -12
  83. package/lib/host-packages/claude/openplanr/agents/planr-backend.md +49 -55
  84. package/lib/host-packages/claude/openplanr/agents/planr-database.md +56 -92
  85. package/lib/host-packages/claude/openplanr/agents/planr-designer.md +35 -51
  86. package/lib/host-packages/claude/openplanr/agents/planr-devops.md +37 -51
  87. package/lib/host-packages/claude/openplanr/agents/planr-documentation.md +29 -52
  88. package/lib/host-packages/claude/openplanr/agents/planr-entity-scaffold.md +24 -23
  89. package/lib/host-packages/claude/openplanr/agents/planr-frontend.md +46 -58
  90. package/lib/host-packages/claude/openplanr/agents/planr-qa.md +4 -2
  91. package/lib/host-packages/claude/openplanr/agents/planr-specification.md +54 -51
  92. package/lib/host-packages/claude/openplanr/references/agents/shared/modes/default/backend.md +21 -65
  93. package/lib/host-packages/claude/openplanr/references/agents/shared/modes/default/designer.md +5 -6
  94. package/lib/host-packages/claude/openplanr/references/agents/shared/modes/default/devops.md +2 -3
  95. package/lib/host-packages/claude/openplanr/references/agents/shared/modes/default/doc-gen.md +3 -4
  96. package/lib/host-packages/claude/openplanr/references/agents/shared/modes/default/frontend.md +19 -64
  97. package/lib/host-packages/claude/openplanr/references/agents/shared/modes/default/specification.md +10 -12
  98. package/lib/host-packages/claude/openplanr/references/agents/shared/modes/spec-driven/backend.md +19 -62
  99. package/lib/host-packages/claude/openplanr/references/agents/shared/modes/spec-driven/designer.md +3 -4
  100. package/lib/host-packages/claude/openplanr/references/agents/shared/modes/spec-driven/devops.md +2 -3
  101. package/lib/host-packages/claude/openplanr/references/agents/shared/modes/spec-driven/doc-gen.md +2 -3
  102. package/lib/host-packages/claude/openplanr/references/agents/shared/modes/spec-driven/frontend.md +16 -59
  103. package/lib/host-packages/claude/openplanr/references/agents/shared/modes/spec-driven/specification.md +9 -11
  104. package/lib/host-packages/claude/openplanr/references/pipeline/stacks/database/mongodb.md +4 -4
  105. package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-review.mjs +24 -9
  106. package/lib/host-packages/claude/openplanr/runtime/design/scripts/design-share.mjs +3 -3
  107. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/artifact/lib/artifact/ui/studio-shell.css +1 -1
  108. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/package.json +4 -4
  109. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/enhancements.css +14 -4
  110. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/share.js +1 -1
  111. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.css +14 -5
  112. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/12-design-review-experience.js +28 -0
  113. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/16-studio-shell.js +105 -27
  114. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources.json +6 -6
  115. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/protocol/package.json +2 -2
  116. package/lib/host-packages/claude/openplanr/runtime/plan/scripts/design.mjs +1 -1
  117. package/lib/host-packages/claude/openplanr/runtime/plan/scripts/runtime/packages/protocol/package.json +2 -2
  118. package/lib/host-packages/claude/openplanr/skills/artifact/SKILL.md +2 -2
  119. package/lib/host-packages/claude/openplanr/skills/artifact/references/diagram-sharing.md +1 -1
  120. package/lib/host-packages/claude/openplanr/skills/ceo-review/SKILL.md +0 -1
  121. package/lib/host-packages/claude/openplanr/skills/ceo-review/references/operate-advisor-contract.md +25 -4
  122. package/lib/host-packages/claude/openplanr/skills/chair-review/SKILL.md +6 -2
  123. package/lib/host-packages/claude/openplanr/skills/challenger-review/SKILL.md +6 -2
  124. package/lib/host-packages/claude/openplanr/skills/cmo-review/SKILL.md +0 -1
  125. package/lib/host-packages/claude/openplanr/skills/cmo-review/references/operate-advisor-contract.md +25 -4
  126. package/lib/host-packages/claude/openplanr/skills/coo-review/SKILL.md +0 -1
  127. package/lib/host-packages/claude/openplanr/skills/coo-review/references/operate-advisor-contract.md +25 -4
  128. package/lib/host-packages/claude/openplanr/skills/cpo-review/SKILL.md +0 -1
  129. package/lib/host-packages/claude/openplanr/skills/cpo-review/references/operate-advisor-contract.md +25 -4
  130. package/lib/host-packages/claude/openplanr/skills/cto-review/SKILL.md +0 -1
  131. package/lib/host-packages/claude/openplanr/skills/cto-review/references/operate-advisor-contract.md +25 -4
  132. package/lib/host-packages/claude/openplanr/skills/delegate/SKILL.md +8 -1
  133. package/lib/host-packages/claude/openplanr/skills/delegate/references/capsule-contract.md +17 -2
  134. package/lib/host-packages/claude/openplanr/skills/delegate/references/operator-guide.md +7 -5
  135. package/lib/host-packages/claude/openplanr/skills/delegate/scripts/adapters/claude.mjs +11 -4
  136. package/lib/host-packages/claude/openplanr/skills/delegate/scripts/adapters/native.mjs +1 -1
  137. package/lib/host-packages/claude/openplanr/skills/delegate/scripts/backend-diagnostics.mjs +14 -48
  138. package/lib/host-packages/claude/openplanr/skills/delegate/scripts/context.mjs +84 -22
  139. package/lib/host-packages/claude/openplanr/skills/delegate/scripts/credentials.mjs +167 -0
  140. package/lib/host-packages/claude/openplanr/skills/delegate/scripts/presentation.mjs +3 -2
  141. package/lib/host-packages/claude/openplanr/skills/delegate/scripts/run-contract.mjs +5 -7
  142. package/lib/host-packages/claude/openplanr/skills/delegate/scripts/run-preparation.mjs +5 -3
  143. package/lib/host-packages/claude/openplanr/skills/delegate/scripts/run-record.mjs +2 -3
  144. package/lib/host-packages/claude/openplanr/skills/design/references/utilities.md +1 -1
  145. package/lib/host-packages/claude/openplanr/skills/design-loop/references/utilities.md +1 -1
  146. package/lib/host-packages/claude/openplanr/skills/design-review/references/utilities.md +1 -1
  147. package/lib/host-packages/claude/openplanr/skills/diagram/references/diagram-sharing.md +1 -1
  148. package/lib/host-packages/claude/openplanr/skills/doctor/SKILL.md +4 -1
  149. package/lib/host-packages/claude/openplanr/skills/doctor/references/upgrade.md +8 -0
  150. package/lib/host-packages/claude/openplanr/skills/operate/SKILL.md +5 -3
  151. package/lib/host-packages/claude/openplanr/skills/plan/SKILL.md +10 -4
  152. package/lib/host-packages/claude/openplanr/skills/sprint/SKILL.md +5 -4
  153. package/lib/host-packages/claude/openplanr/skills/sprint/references/tracker-connections.md +70 -0
  154. package/lib/host-packages/claude/openplanr/skills/status/SKILL.md +4 -3
  155. package/lib/host-packages/claude/openplanr/skills/status/references/tracker-connections.md +70 -0
  156. package/lib/host-packages/claude/openplanr/skills/sync/SKILL.md +11 -20
  157. package/lib/host-packages/claude/openplanr/skills/sync/references/tracker-connections.md +70 -0
  158. package/lib/host-packages/claude/openplanr/skills/sync/scripts/sync.mjs +2 -2
  159. package/lib/host-packages/cursor/openplanr/.openplanr-content.json +63 -47
  160. package/lib/host-packages/cursor/openplanr/manifest.json +1 -1
  161. package/lib/host-packages/cursor/openplanr/rules/planr-artifact/references/diagram-sharing.md +1 -1
  162. package/lib/host-packages/cursor/openplanr/rules/planr-artifact.mdc +2 -2
  163. package/lib/host-packages/cursor/openplanr/rules/planr-ceo-review/references/operate-advisor-contract.md +25 -4
  164. package/lib/host-packages/cursor/openplanr/rules/planr-chair-review.mdc +6 -1
  165. package/lib/host-packages/cursor/openplanr/rules/planr-challenger-review.mdc +6 -1
  166. package/lib/host-packages/cursor/openplanr/rules/planr-cmo-review/references/operate-advisor-contract.md +25 -4
  167. package/lib/host-packages/cursor/openplanr/rules/planr-coo-review/references/operate-advisor-contract.md +25 -4
  168. package/lib/host-packages/cursor/openplanr/rules/planr-cpo-review/references/operate-advisor-contract.md +25 -4
  169. package/lib/host-packages/cursor/openplanr/rules/planr-cto-review/references/operate-advisor-contract.md +25 -4
  170. package/lib/host-packages/cursor/openplanr/rules/planr-delegate/references/capsule-contract.md +17 -2
  171. package/lib/host-packages/cursor/openplanr/rules/planr-delegate/references/operator-guide.md +7 -5
  172. package/lib/host-packages/cursor/openplanr/rules/planr-delegate/scripts/adapters/claude.mjs +11 -4
  173. package/lib/host-packages/cursor/openplanr/rules/planr-delegate/scripts/adapters/native.mjs +1 -1
  174. package/lib/host-packages/cursor/openplanr/rules/planr-delegate/scripts/backend-diagnostics.mjs +14 -48
  175. package/lib/host-packages/cursor/openplanr/rules/planr-delegate/scripts/context.mjs +84 -22
  176. package/lib/host-packages/cursor/openplanr/rules/planr-delegate/scripts/credentials.mjs +167 -0
  177. package/lib/host-packages/cursor/openplanr/rules/planr-delegate/scripts/presentation.mjs +3 -2
  178. package/lib/host-packages/cursor/openplanr/rules/planr-delegate/scripts/run-contract.mjs +5 -7
  179. package/lib/host-packages/cursor/openplanr/rules/planr-delegate/scripts/run-preparation.mjs +5 -3
  180. package/lib/host-packages/cursor/openplanr/rules/planr-delegate/scripts/run-record.mjs +2 -3
  181. package/lib/host-packages/cursor/openplanr/rules/planr-delegate.mdc +8 -1
  182. package/lib/host-packages/cursor/openplanr/rules/planr-design/references/utilities.md +1 -1
  183. package/lib/host-packages/cursor/openplanr/rules/planr-design-loop/references/utilities.md +1 -1
  184. package/lib/host-packages/cursor/openplanr/rules/planr-design-review/references/utilities.md +1 -1
  185. package/lib/host-packages/cursor/openplanr/rules/planr-diagram/references/diagram-sharing.md +1 -1
  186. package/lib/host-packages/cursor/openplanr/rules/planr-doctor/references/upgrade.md +8 -0
  187. package/lib/host-packages/cursor/openplanr/rules/planr-doctor.mdc +4 -1
  188. package/lib/host-packages/cursor/openplanr/rules/planr-operate.mdc +5 -3
  189. package/lib/host-packages/cursor/openplanr/rules/planr-plan.mdc +10 -4
  190. package/lib/host-packages/cursor/openplanr/rules/planr-sprint/references/tracker-connections.md +70 -0
  191. package/lib/host-packages/cursor/openplanr/rules/planr-sprint.mdc +5 -4
  192. package/lib/host-packages/cursor/openplanr/rules/planr-status/references/tracker-connections.md +70 -0
  193. package/lib/host-packages/cursor/openplanr/rules/planr-status.mdc +4 -3
  194. package/lib/host-packages/cursor/openplanr/rules/planr-sync/references/tracker-connections.md +70 -0
  195. package/lib/host-packages/cursor/openplanr/rules/planr-sync/scripts/sync.mjs +2 -2
  196. package/lib/host-packages/cursor/openplanr/rules/planr-sync.mdc +11 -20
  197. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-review.mjs +24 -9
  198. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/design-share.mjs +3 -3
  199. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/artifact/lib/artifact/ui/studio-shell.css +1 -1
  200. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/package.json +4 -4
  201. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/enhancements.css +14 -4
  202. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/share.js +1 -1
  203. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.css +14 -5
  204. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/12-design-review-experience.js +28 -0
  205. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/16-studio-shell.js +105 -27
  206. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources.json +6 -6
  207. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/protocol/package.json +2 -2
  208. package/lib/host-packages/cursor/openplanr/runtime/plan/scripts/design.mjs +1 -1
  209. package/lib/host-packages/cursor/openplanr/runtime/plan/scripts/runtime/packages/protocol/package.json +2 -2
  210. package/lib/host-packages/openai/.claude-plugin/marketplace.json +2 -2
  211. package/lib/host-packages/openai/openplanr/.codex-plugin/plugin.json +1 -1
  212. package/lib/host-packages/openai/openplanr/.openplanr-content.json +72 -56
  213. package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-review.mjs +24 -9
  214. package/lib/host-packages/openai/openplanr/runtime/design/scripts/design-share.mjs +3 -3
  215. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/artifact/lib/artifact/ui/studio-shell.css +1 -1
  216. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/package.json +4 -4
  217. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/enhancements.css +14 -4
  218. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/share.js +1 -1
  219. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.css +14 -5
  220. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/12-design-review-experience.js +28 -0
  221. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/16-studio-shell.js +105 -27
  222. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources.json +6 -6
  223. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/protocol/package.json +2 -2
  224. package/lib/host-packages/openai/openplanr/runtime/plan/scripts/design.mjs +1 -1
  225. package/lib/host-packages/openai/openplanr/runtime/plan/scripts/runtime/packages/protocol/package.json +2 -2
  226. package/lib/host-packages/openai/openplanr/skills/artifact/SKILL.md +2 -2
  227. package/lib/host-packages/openai/openplanr/skills/artifact/references/diagram-sharing.md +1 -1
  228. package/lib/host-packages/openai/openplanr/skills/ceo-review/SKILL.md +0 -1
  229. package/lib/host-packages/openai/openplanr/skills/ceo-review/references/operate-advisor-contract.md +25 -4
  230. package/lib/host-packages/openai/openplanr/skills/chair-review/SKILL.md +6 -2
  231. package/lib/host-packages/openai/openplanr/skills/challenger-review/SKILL.md +6 -2
  232. package/lib/host-packages/openai/openplanr/skills/cmo-review/SKILL.md +0 -1
  233. package/lib/host-packages/openai/openplanr/skills/cmo-review/references/operate-advisor-contract.md +25 -4
  234. package/lib/host-packages/openai/openplanr/skills/coo-review/SKILL.md +0 -1
  235. package/lib/host-packages/openai/openplanr/skills/coo-review/references/operate-advisor-contract.md +25 -4
  236. package/lib/host-packages/openai/openplanr/skills/cpo-review/SKILL.md +0 -1
  237. package/lib/host-packages/openai/openplanr/skills/cpo-review/references/operate-advisor-contract.md +25 -4
  238. package/lib/host-packages/openai/openplanr/skills/cto-review/SKILL.md +0 -1
  239. package/lib/host-packages/openai/openplanr/skills/cto-review/references/operate-advisor-contract.md +25 -4
  240. package/lib/host-packages/openai/openplanr/skills/delegate/SKILL.md +8 -1
  241. package/lib/host-packages/openai/openplanr/skills/delegate/openplanr.skill.json +11 -0
  242. package/lib/host-packages/openai/openplanr/skills/delegate/references/capsule-contract.md +17 -2
  243. package/lib/host-packages/openai/openplanr/skills/delegate/references/operator-guide.md +7 -5
  244. package/lib/host-packages/openai/openplanr/skills/delegate/scripts/adapters/claude.mjs +11 -4
  245. package/lib/host-packages/openai/openplanr/skills/delegate/scripts/adapters/native.mjs +1 -1
  246. package/lib/host-packages/openai/openplanr/skills/delegate/scripts/backend-diagnostics.mjs +14 -48
  247. package/lib/host-packages/openai/openplanr/skills/delegate/scripts/context.mjs +84 -22
  248. package/lib/host-packages/openai/openplanr/skills/delegate/scripts/credentials.mjs +167 -0
  249. package/lib/host-packages/openai/openplanr/skills/delegate/scripts/presentation.mjs +3 -2
  250. package/lib/host-packages/openai/openplanr/skills/delegate/scripts/run-contract.mjs +5 -7
  251. package/lib/host-packages/openai/openplanr/skills/delegate/scripts/run-preparation.mjs +5 -3
  252. package/lib/host-packages/openai/openplanr/skills/delegate/scripts/run-record.mjs +2 -3
  253. package/lib/host-packages/openai/openplanr/skills/design/references/utilities.md +1 -1
  254. package/lib/host-packages/openai/openplanr/skills/design-loop/references/utilities.md +1 -1
  255. package/lib/host-packages/openai/openplanr/skills/design-review/references/utilities.md +1 -1
  256. package/lib/host-packages/openai/openplanr/skills/diagram/references/diagram-sharing.md +1 -1
  257. package/lib/host-packages/openai/openplanr/skills/doctor/SKILL.md +4 -1
  258. package/lib/host-packages/openai/openplanr/skills/doctor/references/upgrade.md +8 -0
  259. package/lib/host-packages/openai/openplanr/skills/operate/SKILL.md +5 -3
  260. package/lib/host-packages/openai/openplanr/skills/plan/SKILL.md +10 -4
  261. package/lib/host-packages/openai/openplanr/skills/sprint/SKILL.md +5 -4
  262. package/lib/host-packages/openai/openplanr/skills/sprint/openplanr.skill.json +11 -0
  263. package/lib/host-packages/openai/openplanr/skills/sprint/references/tracker-connections.md +70 -0
  264. package/lib/host-packages/openai/openplanr/skills/status/SKILL.md +4 -3
  265. package/lib/host-packages/openai/openplanr/skills/status/openplanr.skill.json +11 -0
  266. package/lib/host-packages/openai/openplanr/skills/status/references/tracker-connections.md +70 -0
  267. package/lib/host-packages/openai/openplanr/skills/sync/SKILL.md +11 -20
  268. package/lib/host-packages/openai/openplanr/skills/sync/openplanr.skill.json +11 -0
  269. package/lib/host-packages/openai/openplanr/skills/sync/references/tracker-connections.md +70 -0
  270. package/lib/host-packages/openai/openplanr/skills/sync/scripts/sync.mjs +2 -2
  271. package/lib/integrations.mjs +2 -2
  272. package/lib/node-runtime.d.mts +1 -1
  273. package/lib/node-runtime.mjs +2 -7
  274. package/package.json +4 -5
  275. package/bin/planr.js +0 -7
  276. package/dist/services/connectors/adapters/business-metrics.d.ts +0 -5
  277. package/dist/services/connectors/adapters/business-metrics.d.ts.map +0 -1
  278. package/dist/services/connectors/adapters/business-metrics.js +0 -41
  279. package/dist/services/connectors/adapters/business-metrics.js.map +0 -1
  280. package/dist/services/connectors/adapters/deployment-health.d.ts +0 -18
  281. package/dist/services/connectors/adapters/deployment-health.d.ts.map +0 -1
  282. package/dist/services/connectors/adapters/deployment-health.js +0 -67
  283. package/dist/services/connectors/adapters/deployment-health.js.map +0 -1
  284. package/dist/services/connectors/adapters/github.d.ts +0 -5
  285. package/dist/services/connectors/adapters/github.d.ts.map +0 -1
  286. package/dist/services/connectors/adapters/github.js +0 -31
  287. package/dist/services/connectors/adapters/github.js.map +0 -1
  288. package/dist/services/connectors/adapters/linear-jira.d.ts +0 -5
  289. package/dist/services/connectors/adapters/linear-jira.d.ts.map +0 -1
  290. package/dist/services/connectors/adapters/linear-jira.js +0 -26
  291. package/dist/services/connectors/adapters/linear-jira.js.map +0 -1
  292. package/dist/services/connectors/adapters/posthog.d.ts +0 -5
  293. package/dist/services/connectors/adapters/posthog.d.ts.map +0 -1
  294. package/dist/services/connectors/adapters/posthog.js +0 -31
  295. package/dist/services/connectors/adapters/posthog.js.map +0 -1
  296. package/dist/services/connectors/adapters/sentry.d.ts +0 -5
  297. package/dist/services/connectors/adapters/sentry.d.ts.map +0 -1
  298. package/dist/services/connectors/adapters/sentry.js +0 -31
  299. package/dist/services/connectors/adapters/sentry.js.map +0 -1
  300. package/dist/services/connectors/checkpoint-custody.d.ts +0 -45
  301. package/dist/services/connectors/checkpoint-custody.d.ts.map +0 -1
  302. package/dist/services/connectors/checkpoint-custody.js +0 -499
  303. package/dist/services/connectors/checkpoint-custody.js.map +0 -1
  304. package/dist/services/connectors/connector-registry.d.ts +0 -144
  305. package/dist/services/connectors/connector-registry.d.ts.map +0 -1
  306. package/dist/services/connectors/connector-registry.js +0 -423
  307. package/dist/services/connectors/connector-registry.js.map +0 -1
  308. package/dist/services/connectors/connector-runtime.d.ts +0 -208
  309. package/dist/services/connectors/connector-runtime.d.ts.map +0 -1
  310. package/dist/services/connectors/connector-runtime.js +0 -1305
  311. package/dist/services/connectors/connector-runtime.js.map +0 -1
  312. package/dist/services/connectors/credential-custody.d.ts +0 -96
  313. package/dist/services/connectors/credential-custody.d.ts.map +0 -1
  314. package/dist/services/connectors/credential-custody.js +0 -390
  315. package/dist/services/connectors/credential-custody.js.map +0 -1
@@ -0,0 +1,70 @@
1
+ # GitHub and Linear connections
2
+
3
+ These skills store and read no GitHub or Linear credentials. Remote steps run through a
4
+ connection the host already has; the planning files stay the source of truth.
5
+
6
+ ## Use the host's connection
7
+
8
+ - **Linear:** the host's Linear connection, whose tools read, create and update issues.
9
+ - **GitHub:** the host's GitHub connection, or the GitHub CLI when
10
+ `gh auth status --hostname github.com` succeeds.
11
+
12
+ Never ask the user for a token, read one from the environment or a file, or put one in a
13
+ command, URL or file.
14
+
15
+ ## When a connection is missing
16
+
17
+ Finish the local work first. Then report the remote step as not run and give the one
18
+ line for the current host:
19
+
20
+ | Host | Linear | GitHub |
21
+ | --- | --- | --- |
22
+ | Claude Code | Run `/plugin install linear@claude-plugins-official`, then sign in to Linear from `/mcp`. | Install the GitHub CLI (cli.github.com) and run `gh auth login`. |
23
+ | Codex | Run `codex mcp add linear --url https://mcp.linear.app/mcp`, then `codex mcp login linear`. | Install the GitHub plugin from `/plugins`, or run `gh auth login`. |
24
+ | Cursor | Add Linear from the Cursor Marketplace and sign in to Linear. | Install the GitHub CLI (cli.github.com) and run `gh auth login`. |
25
+
26
+ Ask the user to try again once connected; never retry the remote step on your own.
27
+
28
+ ## Status mapping
29
+
30
+ | Local status | Linear workflow state | GitHub issue |
31
+ | --- | --- | --- |
32
+ | `planning`, `pending` | Unstarted (for example Todo) | open |
33
+ | `in-progress` | Started (for example In Progress) | open |
34
+ | `done` | Completed (for example Done) | closed |
35
+ | Backlog `open` | Backlog, else Unstarted | open |
36
+ | Backlog `closed` | Completed | closed |
37
+ | Backlog `promoted` | Leave as it is | Leave as it is |
38
+
39
+ When reading state back, write only a status the item's type allows. A backlog item takes
40
+ `open` or `closed` and keeps `promoted`.
41
+
42
+ - Linear Completed or Canceled sets `done`, or `closed` for a backlog item. Started sets
43
+ `in-progress`, and Triage, Backlog or Unstarted sets `planning` for features and stories
44
+ and `pending` for quick tasks; a backlog item takes `open` from any of these. Epics and
45
+ task files keep their status.
46
+ - A closed GitHub issue sets `done`, or `closed` for a backlog item. An open issue sets
47
+ `in-progress` for a `done` item and `open` for a `closed` backlog item; other statuses
48
+ stay as they are.
49
+
50
+ ## Links
51
+
52
+ A linked item records its tracker identity in frontmatter. Update a linked item through
53
+ that identity instead of creating another, and record the identity of everything you
54
+ create.
55
+
56
+ - **GitHub:** each item is one issue, recorded as `githubIssue`.
57
+ - **Linear:** use the shapes the OpenPlanr CLI uses, so its later pushes reuse what you
58
+ create:
59
+ - An epic is a Linear project (`linearProjectId`, `linearProjectIdentifier`,
60
+ `linearProjectUrl`). When its `linearMappingStrategy` is `milestone-of` or `label-on`,
61
+ it is a milestone in an existing project (`linearMilestoneId`) or a team label
62
+ (`linearLabelId`) instead, and every issue under it carries that milestone
63
+ (`linearProjectMilestoneId`) or label (`linearLabelIds`).
64
+ - A feature, quick task or backlog item is one issue (`linearIssueId`,
65
+ `linearIssueIdentifier`, `linearIssueUrl`). A story is a sub-issue of its feature's
66
+ issue (`linearParentIssueId`).
67
+ - All task files of one feature share one task-list issue: a sub-issue of the feature's
68
+ issue whose checklist merges every task file, recorded in each task file. Its state is
69
+ Completed when every task file is `done`, Unstarted when every one is `pending`, and
70
+ Started otherwise.
@@ -5,7 +5,7 @@ import { access, readFile } from 'node:fs/promises';
5
5
  import { resolve } from 'node:path';
6
6
  import { fileURLToPath } from 'node:url';
7
7
  import { promisify } from 'node:util';
8
- import { CLI_COMMAND, PLANNING_FOLDER } from './names.mjs';
8
+ import { PLANNING_FOLDER } from './names.mjs';
9
9
 
10
10
  const execFileAsync = promisify(execFile);
11
11
  const LINEAR_UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/iu;
@@ -147,7 +147,7 @@ export async function runPortableSync(
147
147
  } else if (args.provider === 'linear') {
148
148
  throw new IntegrationError(
149
149
  'E_SYNC_USAGE',
150
- `Linear synchronization runs through a Linear connector or the ${CLI_COMMAND} CLI (${CLI_COMMAND} linear push, ${CLI_COMMAND} linear sync).`,
150
+ "Linear synchronization runs through the host's Linear connection.",
151
151
  );
152
152
  } else {
153
153
  throw new IntegrationError(
@@ -6,31 +6,22 @@ alwaysApply: false
6
6
  # OpenPlanr Sync
7
7
 
8
8
  Reconcile local planning artifacts and, when requested, GitHub or Linear state.
9
- Reason about conflicts in this active session; deterministic mapping and GitHub
10
- transport may use a host connector or the packaged [sync helper](planr-sync/scripts/sync.mjs).
11
- Local and GitHub work never require the OpenPlanr CLI.
9
+ Reason about conflicts in this active session. Local and GitHub work never require
10
+ the OpenPlanr CLI.
12
11
 
13
- Resolution order:
12
+ Remote steps run through the host's own connections, as described in
13
+ [tracker connections](planr-sync/references/tracker-connections.md), which also holds the status
14
+ mapping and what to tell the user when a connection is missing:
14
15
 
15
- 1. use a host-native GitHub or Linear connector when available;
16
- 2. otherwise, for GitHub, use the packaged deterministic helper;
17
- 3. otherwise, for Linear, use the `openplanr linear` terminal utility when the user has
18
- installed it; `openplanr github` and `openplanr sync` are optional equivalents for the rest.
19
-
20
- Linear through the CLI:
21
-
22
- - the user runs `openplanr linear init` in a terminal once; it prompts for a personal
23
- access token, which the CLI stores;
24
- - audit with `openplanr linear sync --dry-run`, which reads Linear without writing;
25
- - before a real `openplanr linear sync`, ask how conflicts should resolve and pass
26
- `--on-conflict local` or `--on-conflict linear`; without a prompt it favors Linear;
27
- - `openplanr linear push <artifact-id>` creates or updates Linear issues; preview with
28
- `--dry-run`. Quick tasks and backlog items need `linear.standaloneProjectId` in the
29
- project config when no terminal prompt is available.
16
+ - GitHub: the host's GitHub connection, or, when the GitHub CLI is signed in, the
17
+ packaged [sync helper](planr-sync/scripts/sync.mjs), which creates and edits issues through `gh`;
18
+ close or reopen an issue with `gh issue close` or `gh issue reopen`. `openplanr github`
19
+ is an optional equivalent; `openplanr sync` only repairs local cross-references.
20
+ - Linear: the host's Linear connection.
30
21
 
31
22
  Audit is read-only by default. Apply local changes only when the request asks for
32
23
  reconciliation, and push remote changes only when the request asks for external
33
- synchronization. If credentials are unavailable, complete local reconciliation
24
+ synchronization. If a connection is unavailable, complete local reconciliation
34
25
  and report only the external step that could not run.
35
26
 
36
27
  ## Return
@@ -424,8 +424,12 @@ import { dirname, isAbsolute, join, resolve } from "node:path";
424
424
  import { fileURLToPath } from "node:url";
425
425
  var here = dirname(fileURLToPath(new URL("./runtime/packages/artifact/lib/artifact/review-server.mjs", import.meta.url).href));
426
426
  var STAGE_RUNTIME_PATH = join(here, "..", "..", "templates", "artifact-review-stage.js");
427
- var ARTIFACT_REVIEW_SERVER_VERSION = 2;
427
+ var ARTIFACT_REVIEW_SERVER_VERSION = 3;
428
428
  var ARTIFACT_REVIEW_SERVER_KIND = "artifact-review";
429
+ var CONTROL_HEADER = "x-openplanr-control";
430
+ var CONTROLLABLE_SERVER_VERSIONS = /* @__PURE__ */ new Set([2, ARTIFACT_REVIEW_SERVER_VERSION]);
431
+ var EXPORT_ONLY_SERVER_VERSIONS = /* @__PURE__ */ new Set([1]);
432
+ var AUTHORIZATION_CONTROL_VERSIONS = /* @__PURE__ */ new Set([1, 2]);
429
433
  var CONTROL_WINDOW_BYTES = 64 * 1024 * 1024;
430
434
  var ARTIFACT_REVIEW_MAX_CONTROL_BYTES = Math.ceil((MAX_ARTIFACT_HTML_BYTES * 2 + ARTIFACT_REVIEW_MAX_STATE_BYTES) / CONTROL_WINDOW_BYTES) * CONTROL_WINDOW_BYTES;
431
435
  var ARTIFACT_REVIEW_MAX_STATE_BYTES2 = ARTIFACT_REVIEW_MAX_STATE_BYTES;
@@ -481,6 +485,12 @@ var PERMISSIONS_POLICY = [
481
485
  function artifactError(code, message, fix = "", details) {
482
486
  return new PipelineError(code, message, fix, details);
483
487
  }
488
+ function artifactReviewControlHeaders(controlToken) {
489
+ return { [CONTROL_HEADER]: controlToken };
490
+ }
491
+ function stateControlHeaders(state) {
492
+ return AUTHORIZATION_CONTROL_VERSIONS.has(state.serverVersion) ? { authorization: `Bearer ${state.controlToken}` } : artifactReviewControlHeaders(state.controlToken);
493
+ }
484
494
  function reviewStateDir(env = process.env) {
485
495
  return join(planrHome(env), "artifact-daemon");
486
496
  }
@@ -563,9 +573,9 @@ function parseRequestPath(rawUrl) {
563
573
  });
564
574
  return { segments, trailingSlash };
565
575
  }
566
- function bearerToken(req) {
567
- const value = req.headers?.authorization;
568
- return typeof value === "string" && value.startsWith("Bearer ") ? value.slice(7) : "";
576
+ function presentedControlToken(req) {
577
+ const value = req.headers?.[CONTROL_HEADER];
578
+ return typeof value === "string" ? value : "";
569
579
  }
570
580
  function cloneAndValidateEnvelope(envelope) {
571
581
  let cloned;
@@ -875,7 +885,7 @@ function createArtifactReviewServer({
875
885
  return;
876
886
  }
877
887
  if (internal) {
878
- if (!timingSafeTokenEqual(bearerToken(req), controlToken)) {
888
+ if (!timingSafeTokenEqual(presentedControlToken(req), controlToken)) {
879
889
  sendJson(res, 403, { ok: false, error: "forbidden" });
880
890
  return;
881
891
  }
@@ -1449,7 +1459,7 @@ function createArtifactReviewServer({
1449
1459
  return controller;
1450
1460
  }
1451
1461
  function validState(value, requestedPort, { allowLegacy = false } = {}) {
1452
- return value?.schemaVersion === "1.0.0" && value.kind === ARTIFACT_REVIEW_SERVER_KIND && (value.serverVersion === ARTIFACT_REVIEW_SERVER_VERSION || allowLegacy && value.serverVersion === 1) && Number.isInteger(value.pid) && value.pid > 0 && Number.isInteger(value.port) && value.port > 0 && value.port <= 65535 && (requestedPort === 0 || value.port === requestedPort) && isCapabilityToken(value.instanceId, { bytes: SESSION_ID_BYTES }) && isCapabilityToken(value.controlToken, { bytes: CONTROL_TOKEN_BYTES });
1462
+ return value?.schemaVersion === "1.0.0" && value.kind === ARTIFACT_REVIEW_SERVER_KIND && (CONTROLLABLE_SERVER_VERSIONS.has(value.serverVersion) || allowLegacy && EXPORT_ONLY_SERVER_VERSIONS.has(value.serverVersion)) && Number.isInteger(value.pid) && value.pid > 0 && Number.isInteger(value.port) && value.port > 0 && value.port <= 65535 && (requestedPort === 0 || value.port === requestedPort) && isCapabilityToken(value.instanceId, { bytes: SESSION_ID_BYTES }) && isCapabilityToken(value.controlToken, { bytes: CONTROL_TOKEN_BYTES });
1453
1463
  }
1454
1464
  function readReviewServerState(path) {
1455
1465
  try {
@@ -1473,7 +1483,7 @@ async function controlRequest(descriptor, path, { method, body, fetchImpl } = {}
1473
1483
  const response = await fetchImpl(`http://${LOOPBACK_HOST}:${descriptor.state.port}${path}`, {
1474
1484
  method,
1475
1485
  headers: {
1476
- authorization: `Bearer ${descriptor.state.controlToken}`,
1486
+ ...stateControlHeaders(descriptor.state),
1477
1487
  ...body === void 0 ? {} : { "content-type": "application/json" }
1478
1488
  },
1479
1489
  ...body === void 0 ? {} : { body: JSON.stringify(body) },
@@ -2852,7 +2862,12 @@ async function startDesignReviewUnlocked(file, {
2852
2862
  server = createArtifactReviewServer({
2853
2863
  env,
2854
2864
  serverMetadata: { kind: "design", projectRoot: current.root },
2855
- prepareSource: (options) => prepareArtifactDocument({ ...options, allowLocalForms: true }),
2865
+ prepareSource: (options) => prepareArtifactDocument({
2866
+ ...options,
2867
+ allowLocalForms: true,
2868
+ prototypeState: true,
2869
+ screenId: current.entries.find((entry) => entry.artifactId === options.artifactId)?.screenId ?? options.artifactId
2870
+ }),
2856
2871
  async refreshSession(session) {
2857
2872
  current = currentDesign(file);
2858
2873
  if (session.designRevision === current.revision) return;
@@ -3214,7 +3229,7 @@ ${renderArtifactParentRuntime({ ...options, adapterRuntimeUrl: `${base}api/desig
3214
3229
  const registered = await fetchImpl(`${origin}/internal/v1/sessions`, {
3215
3230
  method: "POST",
3216
3231
  headers: {
3217
- authorization: `Bearer ${server.controlToken}`,
3232
+ ...artifactReviewControlHeaders(server.controlToken),
3218
3233
  "content-type": "application/json"
3219
3234
  },
3220
3235
  body: JSON.stringify({
@@ -92,7 +92,7 @@ ${current.document.id}`);
92
92
  const within = relative(project, root);
93
93
  if ((!allowMissing || existsSync(path)) && (within === "" || !within.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`) && within !== ".." && !isAbsolute(within)))
94
94
  throw new Error(
95
- "Design owner credentials must be stored outside the project. Set PLANR_HOME to a private user-level directory."
95
+ "Design owner keys must be stored outside the project. Set PLANR_HOME to a private user-level directory."
96
96
  );
97
97
  const legacyPath = !options.custodyRoot && !configuredPlanrHome(env) ? join(realpathSync(env.HOME || homedir()), ".openplanr", "design-shares", `${key}.json`) : null;
98
98
  return { root, path, current, legacyPath };
@@ -1785,10 +1785,10 @@ async function importDesignShareRecovery(file, { input, ...options } = {}) {
1785
1785
  throw new Error("Recovery belongs to a different design.");
1786
1786
  if (record && (record.custody.id !== custody.id || JSON.stringify(record.custody.ownerPublicKey) !== JSON.stringify(custody.ownerPublicKey)))
1787
1787
  throw new Error(
1788
- "This design already has different owner credentials. Recovery will not overwrite them."
1788
+ "This design already has different owner keys. Recovery will not overwrite them."
1789
1789
  );
1790
1790
  if (record && record.custody.version > custody.version)
1791
- throw new Error("This recovery file is older than the locally saved owner credentials.");
1791
+ throw new Error("This recovery file is older than the locally saved owner keys.");
1792
1792
  if (!custody.pendingCreate && !recovered.deleted && !recovered.revoked) {
1793
1793
  await getWorkspace(custody, { fetchImpl: options.fetchImpl });
1794
1794
  const bundle = await decryptWorkspaceRevision(custody, custody.currentRevision, {
@@ -1,2 +1,2 @@
1
1
  /* generated by scripts/typescript/compile-sources.mjs from studio-shell.source.css */
2
- .studio-toolbar{min-width:0;min-height:54px;gap:12px;font:400 13px / 1.4 var(--planr-font-body, "DM Sans", sans-serif);box-sizing:border-box;display:flex;align-items:center;flex-wrap:nowrap;padding:0 16px;width:100%}.studio-toolbar .planr-brand{display:flex;align-items:center;gap:8px;min-width:0;flex:1}.studio-toolbar .planr-mark{display:inline-flex;flex:none;width:28px;height:28px;color:var(--planr-color-primary)}.studio-toolbar .planr-mark svg{display:block;width:100%;height:100%}.studio-toolbar .design-wordmark{font-weight:500;white-space:nowrap;font-size:13px;color:var(--planr-color-text)}.studio-toolbar .design-wordmark>span{font-weight:600;color:var(--planr-color-primary)}.studio-toolbar .planr-title-block{display:flex;align-items:center;gap:7px;min-width:0}.studio-chrome-mount,.studio-panel-mount{display:contents}.studio-toolbar-leading,.studio-toolbar-trailing{min-width:0;display:flex;align-items:center;gap:8px}.studio-toolbar-leading{flex:1}.studio-toolbar-trailing{justify-content:flex-end}.studio-identity{min-width:0}.studio-toolbar .planr-title-block strong{max-width:min(25vw,300px)}.studio-subtitle,.studio-hierarchy{display:block;overflow:hidden;color:var(--planr-color-text-muted);font-size:10px;text-overflow:ellipsis;white-space:nowrap}.studio-hierarchy a{color:inherit}.studio-type-badge{display:inline-flex;flex:none;align-items:center;padding:2px 5px;border:1px solid var(--planr-color-rule);border-radius:var(--planr-radius-small, 5px);color:var(--planr-color-text-muted);font:500 10px / 1.2 var(--planr-font-body);white-space:nowrap}.studio-button,.studio-menu-content,.studio-tooltip,.studio-panel-dialog{border:1px solid var(--planr-color-rule);background:var(--planr-color-panel);color:var(--planr-color-text)}.studio-button{min-height:32px;display:inline-flex;justify-content:center;align-items:center;gap:6px;border-radius:var(--planr-radius-medium, 8px);padding:0 9px;font:500 13px / 1 var(--planr-font-body);cursor:pointer}.studio-button-ghost{background:transparent;border-color:transparent}.studio-button-primary{background:var(--planr-color-primary);border-color:var(--planr-color-primary);color:var(--planr-color-background)}.studio-button:not(:disabled):hover,.studio-button[aria-pressed=true],.studio-button[aria-expanded=true]{background:var(--planr-color-raised);color:var(--planr-color-primary)}.studio-button:disabled,.studio-menu-item[data-disabled]{opacity:0.45;cursor:not-allowed}.studio-button:focus-visible,.studio-menu-item:focus-visible{outline:2px solid var(--planr-color-primary);outline-offset:2px}.studio-menu{display:inline-flex}.studio-menu-content{min-width:180px;max-width:min(320px,calc(100vw - 16px));max-height:var(--radix-dropdown-menu-content-available-height);overflow-y:auto;padding:5px;z-index:160;border-radius:var(--planr-radius-medium, 8px);box-shadow:0 12px 30px color-mix(in srgb,var(--planr-color-background) 60%,transparent)}.studio-menu-item{width:100%;min-height:34px;padding:8px 10px;display:flex;align-items:center;text-align:left;border:0;border-radius:var(--planr-radius-small, 5px);background:transparent;color:inherit;font:500 13px / 1.3 var(--planr-font-body);cursor:pointer}.studio-menu-item[data-highlighted]{background:var(--planr-color-raised);outline:none;color:var(--planr-color-primary)}.studio-menu-group-start{border-top:1px solid var(--planr-color-rule);border-radius:0}.studio-tooltip{z-index:180;padding:6px 8px;border-radius:var(--planr-radius-small, 5px);font:12px / 1.4 var(--planr-font-body)}.studio-status{min-width:0;display:inline-flex;align-items:center;gap:4px;color:var(--planr-color-text-muted);font:10px / 1.3 var(--planr-font-body)}.studio-status[data-tone=error]{color:var(--planr-color-danger)}.studio-status .studio-button{width:24px;min-height:24px;padding:0}.studio-panel-overlay{position:absolute;inset:0;z-index:170;background:color-mix(in srgb,var(--planr-color-background) 72%,transparent)}.studio-panel-dialog{position:absolute;top:env(safe-area-inset-top,0px);bottom:env(safe-area-inset-bottom,0px);z-index:180;width:min(350px,calc(100% - 32px));box-shadow:0 8px 30px color-mix(in srgb,var(--planr-color-background) 50%,transparent)}.studio-panel-left{left:0}.studio-panel-right{right:0}.studio-panel-close{position:absolute;right:8px;top:8px;z-index:2;width:32px}.studio-panel-content{height:100%;min-height:0}.studio-panel-dialog .design-navigator,.studio-panel-dialog .planr-review-rail,.studio-panel-dialog .diagram-outline{position:static!important;width:100%!important;height:100%!important;max-height:100%!important;transform:none!important;overflow-y:auto;padding-top:42px;border:0}@media(max-width:680px){.studio-toolbar{gap:6px;padding-inline:8px}.studio-toolbar .planr-title-block strong{max-width:30vw}.studio-toolbar .design-wordmark{display:none}.studio-toolbar .design-button-label{display:none}.studio-toolbar .studio-status{max-width:90px}.studio-button{min-height:36px;padding-inline:8px}}.planr-shell[data-studio-framework=react]{--planr-toolbar-height: 60px;grid-template-rows:auto minmax(0,1fr)}.planr-shell[data-studio-framework=react] :is(.design-toolbar,.diagram-toolbar){display:flex;grid-template-columns:none;flex-wrap:wrap;min-height:var(--planr-toolbar-height);height:auto;padding-block:4px;overflow:visible}.planr-shell[data-studio-framework=react] .planr-brand{display:flex;gap:8px;max-width:none;min-width:min-content}.planr-shell[data-studio-framework=react] .studio-toolbar-leading{flex:1;min-width:min-content}.planr-shell[data-studio-framework=react] .studio-toolbar-trailing{flex:0 0 auto;flex-wrap:wrap;max-width:100%}.planr-shell[data-studio-framework=react] .design-toolbar .design-view-picker{display:inline-flex;width:auto;margin:0;border:0}.planr-shell[data-studio-framework=react] .design-export>button{display:inline-flex;width:auto;padding:0 9px}.planr-shell[data-studio-framework=react] .studio-menu-content{position:relative}.planr-shell[data-studio-framework=react] .planr-title-block{display:flex}.planr-shell[data-studio-framework=react]>.planr-workspace{position:relative}@media(max-width:680px){.planr-shell[data-studio-framework=react] .studio-toolbar.planr-toolbar{gap:2px;padding-inline:4px}.planr-shell[data-studio-framework=react] .studio-toolbar-leading,.planr-shell[data-studio-framework=react] .studio-toolbar-trailing{gap:2px}.planr-shell[data-studio-framework=react] .planr-brand{overflow:hidden}.planr-shell[data-studio-framework=react] .studio-identity{display:block;overflow:hidden}.planr-shell[data-studio-framework=react] .planr-mark{width:22px;height:22px}.planr-shell[data-studio-framework=react] .design-view-picker{height:44px;gap:0}.planr-shell[data-studio-framework=react] .design-view-picker button{width:44px;height:100%;padding:0}.planr-shell[data-studio-framework=react] .studio-button{min-width:44px;min-height:44px}.planr-shell[data-studio-framework=react] :is(.design-save-state,.design-preview-state){display:none}.planr-shell[data-studio-framework=react] :is(.design-export,.diagram-export)>button{font-size:0;width:44px;padding:0}.planr-shell[data-studio-framework=react] :is(.design-export,.diagram-export)>button span{font-size:16px}}@media(max-width:960px){.planr-shell[data-studio-framework=react] .design-wordmark{display:none}.planr-shell[data-studio-framework=react] .planr-workspace>:is(.design-navigator,.planr-review-rail){top:0;max-height:100%}}@media(max-width:1240px){.planr-shell[data-studio-framework=react] .planr-title-block{flex-direction:column;align-items:flex-start;gap:1px}.planr-shell[data-studio-framework=react] .planr-title-block strong{max-width:100%;line-height:1.1}.planr-shell[data-studio-framework=react] .design-preview-state{max-width:48px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}}.planr-diagram-editor[data-studio-framework=react]{--de-bar-height: 60px;grid-template-rows:auto minmax(0,1fr)}.planr-diagram-editor[data-studio-framework=react] .de-bar{display:block;padding:0;height:auto;overflow:visible;border-bottom:0}.planr-diagram-editor[data-studio-framework=react] .studio-toolbar{min-height:60px;height:auto;flex-wrap:wrap;padding:4px 16px;border:0;border-bottom:1px solid var(--de-rule);background:var(--de-panel)}.planr-diagram-editor[data-studio-framework=react] .studio-toolbar-leading{flex:1;min-width:min-content}.planr-diagram-editor[data-studio-framework=react] .studio-toolbar :is(.de-command-group,.studio-toolbar-trailing){flex:none}.planr-diagram-editor[data-studio-framework=react] .planr-brand{min-width:min-content;overflow:hidden}.planr-diagram-editor[data-studio-framework=react] .de-title{max-width:25vw;line-height:1.35}.planr-diagram-editor[data-studio-framework=react] .studio-subtitle .de-subtitle{line-height:1.3}.planr-diagram-editor[data-studio-framework=react] .de-alert{grid-row:2;top:var(--de-space-3)}.planr-diagram-editor[data-studio-framework=react][data-layout~=drawer] .design-wordmark,.planr-diagram-editor[data-studio-framework=react][data-layout~=drawer] .studio-subtitle{display:none}.planr-diagram-editor[data-studio-framework=react][data-layout~=drawer] .planr-title-block{flex-direction:column;align-items:flex-start;gap:1px}.planr-diagram-editor[data-studio-framework=react][data-layout~=compact] .studio-toolbar{padding:4px 8px;gap:8px}.planr-diagram-editor[data-studio-framework=react][data-layout~=compact] .studio-toolbar-trailing{gap:4px}.planr-diagram-editor[data-studio-framework=react][data-layout~=compact] .studio-menu:has([data-studio-palette-menu]){display:none}.planr-diagram-editor[data-studio-framework=react][data-layout~=compact] .de-more-menu{top:calc(100% + var(--de-space-2))}[data-studio-framework=react]{position:relative}[data-studio-framework=react] .studio-toolbar .studio-type-badge{display:inline-flex}[data-studio-framework=react] .studio-identity{flex:1;min-width:min-content}[data-studio-framework=react] .studio-toolbar .planr-title-block strong{contain:inline-size;display:block;align-self:stretch;width:auto;min-width:0;flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}[data-studio-framework=react] .studio-subtitle{contain:inline-size}[data-studio-framework=react]:has(.studio-panel-dialog) [data-planr-close-feedback],[data-studio-framework=react]:has(.studio-panel-dialog) .planr-review-rail [data-planr-close-feedback]{display:none}.studio-panel-dialog .design-nav-close,.studio-panel-dialog .studio-panel-content .planr-review-rail [data-planr-close-feedback]{display:none}.studio-preserved-control{display:contents}.studio-toolbar fieldset.planr-segment{margin:0;padding:0;min-inline-size:0}.diagram-shell[data-present=true] .studio-toolbar-trailing>:not([data-action=present]):not(.studio-menu){display:none}.diagram-shell[data-studio-framework=react] .diagram-presentation-nav button{color:var(--planr-color-text);background:var(--planr-color-panel)}.diagram-shell[data-studio-framework=react] .diagram-presentation-nav button:enabled:hover{background:var(--planr-color-raised)}@media(max-width:680px){.studio-panel-close{width:44px;min-height:44px}}@media(max-width:700px){.diagram-shell[data-present=true] .studio-toolbar-leading{flex:none}.diagram-shell[data-present=true] .diagram-presentation-nav{min-width:0;flex:1;gap:4px}.diagram-shell[data-present=true] .diagram-presentation-nav>div{min-width:0}}@media(min-width:681px)and (max-width:960px){.diagram-shell[data-studio-framework=react] .studio-toolbar-trailing{gap:4px}}@media(max-width:480px){.studio-toolbar .planr-mark{display:none}}
2
+ .studio-toolbar{min-width:0;min-height:54px;gap:12px;font:400 13px / 1.4 var(--planr-font-body, "DM Sans", sans-serif);box-sizing:border-box;display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:center;flex-wrap:nowrap;padding:0 16px;width:100%}.studio-toolbar .planr-brand{display:flex;align-items:center;gap:8px;min-width:0;max-width:none;flex:1}.studio-toolbar .planr-mark{display:inline-flex;flex:none;width:28px;height:28px;color:var(--planr-color-primary)}.studio-toolbar .planr-mark svg{display:block;width:100%;height:100%}.studio-toolbar .design-wordmark{font-weight:500;white-space:nowrap;font-size:13px;color:var(--planr-color-text)}.studio-toolbar .design-wordmark>span{font-weight:600;color:var(--planr-color-primary)}.studio-toolbar .planr-title-block{display:flex;align-items:center;gap:7px;min-width:0}.studio-toolbar[data-studio-react-chrome=true]{display:grid;padding-inline:16px}.studio-chrome-mount,.studio-panel-mount{display:contents}.studio-toolbar-leading,.studio-toolbar-trailing{min-width:0;display:flex;align-items:center;gap:8px}.studio-toolbar-leading{min-width:0}.studio-toolbar-trailing{justify-content:flex-end;justify-self:end;width:max-content;max-width:100%}.studio-toolbar-center{min-width:0;width:max-content;max-width:100%;justify-self:center}.studio-toolbar[data-studio-react-chrome=true] .studio-toolbar-center .planr-segment{display:inline-flex}.studio-toolbar[data-studio-center=false] .studio-toolbar-center,.studio-toolbar-center:empty,.studio-toolbar-status:empty,.studio-toolbar-actions:empty{display:none}.studio-toolbar-status,.studio-toolbar-actions{display:flex;align-items:center;min-width:0;gap:8px}.studio-toolbar-status{max-width:128px}.studio-toolbar-status>:is(output,.studio-status){display:inline-flex;align-items:center;min-width:0;max-width:none;overflow-wrap:normal}.studio-identity{min-width:0;flex:1;overflow:hidden}.studio-toolbar .planr-title-block strong{max-width:min(25vw,300px);min-width:0;display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.studio-toolbar[data-studio-react-chrome=true] .studio-type-badge{display:inline-flex}.studio-subtitle,.studio-hierarchy{display:block;overflow:hidden;color:var(--planr-color-text-muted);font-size:10px;text-overflow:ellipsis;white-space:nowrap}.studio-hierarchy a{color:inherit}.studio-type-badge{display:inline-flex;flex:none;align-items:center;padding:2px 5px;border:1px solid var(--planr-color-rule);border-radius:var(--planr-radius-small, 5px);color:var(--planr-color-text-muted);font:500 10px / 1.2 var(--planr-font-body);white-space:nowrap}.studio-button,.studio-menu-content,.studio-tooltip,.studio-panel-dialog,.studio-dialog{border:1px solid var(--planr-color-rule);background:var(--planr-color-panel);color:var(--planr-color-text)}.studio-button{min-height:32px;display:inline-flex;justify-content:center;align-items:center;gap:6px;border-radius:var(--planr-radius-medium, 8px);padding:0 9px;font:500 13px / 1.3 var(--planr-font-body);cursor:pointer}.studio-button-ghost{background:transparent;border-color:transparent}.studio-toolbar[data-studio-react-chrome=true] :is(.studio-button,.planr-toolbar-action){height:auto;min-height:32px;padding-block:4px;white-space:nowrap}.studio-button-primary{background:var(--planr-color-primary);border-color:var(--planr-color-primary);color:var(--planr-color-background)}.studio-button:not(:disabled):hover,.studio-button[aria-pressed=true],.studio-button[aria-expanded=true]{background:var(--planr-color-raised);color:var(--planr-color-primary)}.studio-button:disabled,.studio-menu-item[data-disabled]{opacity:0.45;cursor:not-allowed}.studio-button:focus-visible,.studio-menu-item:focus-visible{outline:2px solid var(--planr-color-primary);outline-offset:2px}.studio-menu{display:inline-flex}.studio-menu-content{min-width:180px;max-width:min(320px,calc(100vw - 16px));max-height:var(--radix-dropdown-menu-content-available-height);overflow-y:auto;padding:5px;z-index:160;border-radius:var(--planr-radius-medium, 8px);box-shadow:0 12px 30px color-mix(in srgb,var(--planr-color-background) 60%,transparent)}.studio-menu-item{width:100%;min-height:34px;padding:8px 10px;display:flex;align-items:center;text-align:left;border:0;border-radius:var(--planr-radius-small, 5px);background:transparent;color:inherit;font:500 13px / 1.3 var(--planr-font-body);cursor:pointer}.studio-menu-item[data-highlighted]{background:var(--planr-color-raised);outline:none;color:var(--planr-color-primary)}.studio-menu-group-start{border-top:1px solid var(--planr-color-rule);border-radius:0}.studio-tooltip{z-index:180;padding:6px 8px;border-radius:var(--planr-radius-small, 5px);font:12px / 1.4 var(--planr-font-body)}.studio-status{min-width:0;display:inline-flex;align-items:center;gap:4px;color:var(--planr-color-text-muted);font:10px / 1.3 var(--planr-font-body)}.studio-status[data-tone=error]{color:var(--planr-color-danger)}.studio-status .studio-button{width:24px;min-height:24px;padding:0}.studio-panel-overlay{position:absolute;inset:0;z-index:170;background:color-mix(in srgb,var(--planr-color-background) 72%,transparent)}.studio-panel-dialog{position:absolute;top:env(safe-area-inset-top,0px);bottom:env(safe-area-inset-bottom,0px);z-index:180;width:min(350px,calc(100% - 32px));box-shadow:0 8px 30px color-mix(in srgb,var(--planr-color-background) 50%,transparent)}.studio-panel-left{left:0}.studio-panel-right{right:0}.studio-panel-close{position:absolute;right:8px;top:8px;z-index:2;width:32px}.studio-dialog-overlay{position:fixed;inset:0;z-index:170;background:color-mix(in srgb,var(--planr-color-background) 72%,transparent)}.studio-dialog{position:fixed;z-index:180;inset:50% auto auto 50%;transform:translate(-50%,-50%);box-sizing:border-box;width:min(480px,calc(100vw - 32px));max-height:calc(100dvh - 32px);overflow:auto;padding:24px;border-radius:var(--planr-radius-large, 12px);box-shadow:0 8px 30px color-mix(in srgb,var(--planr-color-background) 50%,transparent);font:400 13px / 1.5 var(--planr-font-body)}.studio-dialog-title{margin:0 32px 12px 0;font:600 20px / 1.3 var(--planr-font-display)}.studio-dialog-description{color:var(--planr-color-text-muted)}.studio-panel-content{height:100%;min-height:0}.studio-panel-dialog .design-navigator,.studio-panel-dialog .planr-review-rail,.studio-panel-dialog .diagram-outline{position:static!important;width:100%!important;height:100%!important;max-height:100%!important;transform:none!important;overflow-y:auto;padding-top:42px;border:0}@media(max-width:680px){.studio-toolbar{gap:6px;padding-inline:8px}.studio-toolbar .planr-title-block strong{max-width:30vw}.studio-toolbar .design-wordmark{display:none}.studio-toolbar .design-button-label{display:none}.studio-toolbar .studio-status{max-width:90px}.studio-button{min-height:36px;padding-inline:8px}}.planr-shell[data-studio-framework=react]{--planr-toolbar-height: 60px;grid-template-rows:auto minmax(0,1fr)}.planr-shell[data-studio-framework=react] :is(.design-toolbar,.diagram-toolbar){display:grid;grid-template-columns:minmax(0,1fr) auto;min-height:var(--planr-toolbar-height);height:auto;padding-block:4px;overflow:visible}.planr-shell[data-studio-framework=react] .planr-brand{display:flex;gap:8px;max-width:none;min-width:0}.planr-shell[data-studio-framework=react] .studio-toolbar-leading{min-width:0}.planr-shell[data-studio-framework=react] .studio-toolbar-trailing{max-width:100%}.planr-shell[data-studio-framework=react] .design-toolbar .design-view-picker{display:inline-flex;width:auto;height:auto;min-height:32px;margin:0;border:0}.planr-shell[data-studio-framework=react] .design-export>button{display:inline-flex;width:auto;padding:0 9px}.planr-shell[data-studio-framework=react] .studio-menu-content{position:relative}.planr-shell[data-studio-framework=react] .planr-title-block{display:flex}.planr-shell[data-studio-framework=react]>.planr-workspace{position:relative}@media(max-width:680px){.planr-shell[data-studio-framework=react] .studio-toolbar.planr-toolbar{gap:2px;padding-inline:4px}.planr-shell[data-studio-framework=react] .studio-toolbar-leading,.planr-shell[data-studio-framework=react] .studio-toolbar-trailing{gap:2px}.planr-shell[data-studio-framework=react] .planr-brand{overflow:hidden}.planr-shell[data-studio-framework=react] .studio-identity{display:block;overflow:hidden}.planr-shell[data-studio-framework=react] .planr-mark{width:22px;height:22px}.planr-shell[data-studio-framework=react] .design-view-picker{height:auto;min-height:44px;gap:0}.planr-shell[data-studio-framework=react] .design-view-picker button{width:44px;height:auto;padding:0}.planr-shell[data-studio-framework=react] .studio-button{min-width:44px;min-height:44px}.planr-shell[data-studio-framework=react] :is(.design-export,.diagram-export)>button{font-size:0;width:44px;padding:0}.planr-shell[data-studio-framework=react] :is(.design-export,.diagram-export)>button span{font-size:16px}}@media(max-width:960px){.planr-shell[data-studio-framework=react] .design-wordmark{display:none}.planr-shell[data-studio-framework=react] .planr-workspace>:is(.design-navigator,.planr-review-rail){top:0;max-height:100%}}@media(max-width:1240px){.planr-shell[data-studio-framework=react] .planr-title-block{flex-direction:column;align-items:flex-start;gap:1px}.planr-shell[data-studio-framework=react] .planr-title-block strong{max-width:100%;line-height:1.1}.planr-shell[data-studio-framework=react] .design-preview-state{max-width:48px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}}.planr-diagram-editor[data-studio-framework=react]{--de-bar-height: 60px;grid-template-rows:auto minmax(0,1fr)}.planr-diagram-editor[data-studio-framework=react] .de-bar{display:block;padding:0;height:auto;overflow:visible;border-bottom:0}.planr-diagram-editor[data-studio-framework=react] .studio-toolbar{min-height:60px;height:auto;padding:4px 16px;border:0;border-bottom:1px solid var(--de-rule);background:var(--de-panel)}.planr-diagram-editor[data-studio-framework=react] .studio-toolbar-leading{min-width:0}.planr-diagram-editor[data-studio-framework=react] .studio-toolbar :is(.de-command-group,.studio-toolbar-trailing){flex:none}.planr-diagram-editor[data-studio-framework=react] .planr-brand{min-width:0;overflow:hidden}.planr-diagram-editor[data-studio-framework=react] .de-title{max-width:25vw;line-height:1.35}.planr-diagram-editor[data-studio-framework=react] .studio-subtitle .de-subtitle{line-height:1.3}.planr-diagram-editor[data-studio-framework=react] .de-alert{grid-row:2;top:var(--de-space-3)}.planr-diagram-editor[data-studio-framework=react][data-layout~=drawer] .design-wordmark,.planr-diagram-editor[data-studio-framework=react][data-layout~=drawer] .studio-subtitle{display:none}.planr-diagram-editor[data-studio-framework=react][data-layout~=drawer] .planr-title-block{flex-direction:column;align-items:flex-start;gap:1px}.planr-diagram-editor[data-studio-framework=react][data-layout~=compact] .studio-toolbar{padding:4px 8px;gap:8px}.planr-diagram-editor[data-studio-framework=react][data-layout~=compact] .studio-toolbar-trailing{gap:4px}.planr-diagram-editor[data-studio-framework=react][data-layout~=compact] .studio-menu:has([data-studio-palette-menu]){display:none}.planr-diagram-editor[data-studio-framework=react][data-layout~=compact] .de-more-menu{top:calc(100% + var(--de-space-2))}[data-studio-framework=react]{position:relative}[data-studio-framework=react] .studio-toolbar .studio-type-badge{display:inline-flex}[data-studio-framework=react] .studio-identity{flex:1;min-width:0}[data-studio-framework=react] .studio-toolbar .planr-title-block strong{contain:inline-size;display:block;align-self:stretch;width:auto;min-width:0;flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}[data-studio-framework=react] .studio-subtitle{contain:inline-size}[data-studio-framework=react]:has(.studio-panel-dialog) [data-planr-close-feedback],[data-studio-framework=react]:has(.studio-panel-dialog) .planr-review-rail [data-planr-close-feedback]{display:none}.studio-panel-dialog .design-nav-close,.studio-panel-dialog .studio-panel-content .planr-review-rail [data-planr-close-feedback]{display:none}.studio-preserved-control{display:contents}.studio-toolbar fieldset.planr-segment{margin:0;padding:0;min-inline-size:0}.diagram-shell[data-present=true] .studio-toolbar-actions>:not([data-action=present]):not(.studio-menu){display:none}.diagram-shell[data-studio-framework=react] .diagram-presentation-nav button{color:var(--planr-color-text);background:var(--planr-color-panel)}.diagram-shell[data-studio-framework=react] .diagram-presentation-nav button:enabled:hover{background:var(--planr-color-raised)}@media(max-width:680px){.studio-panel-close{width:44px;min-height:44px}}@media(max-width:700px){.diagram-shell[data-present=true] .studio-toolbar-leading{flex:none}.diagram-shell[data-present=true] .diagram-presentation-nav{min-width:0;flex:1;gap:4px}.diagram-shell[data-present=true] .diagram-presentation-nav>div{min-width:0}}@media(min-width:681px)and (max-width:960px){.diagram-shell[data-studio-framework=react] .studio-toolbar-trailing{gap:4px}}@media(max-width:480px){.studio-toolbar .planr-mark{display:none}}.studio-toolbar[data-studio-center=true],.planr-shell[data-studio-framework=react] .studio-toolbar[data-studio-center=true]{grid-template-columns:minmax(0,1fr) auto minmax(0,1fr)}.studio-toolbar[data-studio-layout=compact],.planr-shell[data-studio-framework=react] .studio-toolbar[data-studio-layout=compact]{grid-template-columns:minmax(0,1fr);grid-template-rows:none;grid-auto-rows:auto;row-gap:4px;padding-block:4px}:is(.studio-toolbar[data-studio-layout=compact],.planr-shell[data-studio-framework=react] .studio-toolbar[data-studio-layout=compact]) .studio-toolbar-leading{grid-column:1;grid-row:1;width:100%}:is(.studio-toolbar[data-studio-layout=compact],.planr-shell[data-studio-framework=react] .studio-toolbar[data-studio-layout=compact]) .studio-toolbar-trailing{grid-column:1;grid-row:2;width:100%;flex-wrap:wrap}:is(.studio-toolbar[data-studio-layout=compact],.planr-shell[data-studio-framework=react] .studio-toolbar[data-studio-layout=compact]) .studio-toolbar-actions{justify-content:flex-end;flex-wrap:wrap;max-width:100%}:is(.studio-toolbar[data-studio-layout=compact],.planr-shell[data-studio-framework=react] .studio-toolbar[data-studio-layout=compact]) .studio-toolbar-center{grid-column:1;grid-row:3}:is(.studio-toolbar[data-studio-layout=compact],.planr-shell[data-studio-framework=react] .studio-toolbar[data-studio-layout=compact]) .studio-toolbar-status{max-width:100%;width:100%;flex-basis:100%;flex-wrap:wrap;justify-content:flex-end}:is(.studio-toolbar[data-studio-layout=compact],.planr-shell[data-studio-framework=react] .studio-toolbar[data-studio-layout=compact]) .studio-toolbar-status>:is(output,.studio-status,.design-preview-state){max-width:100%;white-space:normal;overflow:visible;overflow-wrap:normal}.studio-toolbar[data-studio-density=narrow]{gap:4px;padding-inline:8px}.studio-toolbar[data-studio-density=narrow] .design-wordmark,.studio-toolbar[data-studio-density=narrow] .design-button-label,.studio-toolbar[data-studio-density=narrow] .planr-mark{display:none}.studio-toolbar[data-studio-density=narrow] .studio-button,.studio-toolbar[data-studio-density=narrow] .planr-toolbar-action,.studio-toolbar[data-studio-density=narrow] .design-view-picker button{min-height:44px;min-width:44px}.studio-toolbar[data-studio-density=narrow] .design-view-picker{height:auto;gap:0}.studio-toolbar[data-studio-density=narrow] .design-view-picker button{width:44px;height:auto;padding:0}.studio-toolbar[data-studio-density=narrow] .studio-toolbar-actions{gap:4px}.studio-toolbar[data-studio-density=narrow] .studio-toolbar-status{font-size:10px}.studio-toolbar[data-studio-density=narrow] :is(.design-export,.diagram-export)>button{font-size:0;width:44px;padding:0}.studio-toolbar[data-studio-density=narrow] :is(.design-export,.diagram-export)>button span{font-size:16px}@media(max-width:680px),(pointer:coarse){.studio-button,.studio-menu-item{min-width:44px;min-height:44px}}
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openplanr/design",
3
- "version": "0.4.4",
3
+ "version": "0.4.6",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "description": "Canonical OpenPlanr design helpers and design-loop engine",
@@ -43,11 +43,11 @@
43
43
  "LICENSE"
44
44
  ],
45
45
  "engines": {
46
- "node": ">=20.19.0"
46
+ "node": ">=22.13.0"
47
47
  },
48
48
  "dependencies": {
49
- "@openplanr/artifact": "0.6.4",
50
- "@openplanr/protocol": "0.10.2"
49
+ "@openplanr/artifact": "0.6.6",
50
+ "@openplanr/protocol": "0.11.0"
51
51
  },
52
52
  "scripts": {
53
53
  "test": "node --test --test-concurrency=2 tests/*.test.mjs",
@@ -267,8 +267,13 @@ html[data-design-theme="light"] .design-export > div { box-shadow:0 12px 30px #1
267
267
 
268
268
  /* A shared sizing contract keeps captions, tools and service status from
269
269
  overlapping. It belongs to the shell; iframe documents inherit none of it. */
270
- [data-design-studio] .design-stage-context { height:var(--design-stage-context-height); }
271
- [data-design-studio] .planr-shell:not([data-design-presentation="true"]) .planr-stage-scroll { inset-block-start:var(--design-stage-context-height); }
270
+ [data-design-studio] .design-stage-context { height:auto; min-height:var(--design-stage-context-height); flex-wrap:wrap; }
271
+ [data-design-studio] .design-stage-context > div:first-child { flex:1 1 220px; max-width:100%; }
272
+ [data-design-studio] .design-stage-context > .design-stage-actions { flex:0 1 auto; flex-wrap:wrap; max-width:100%; }
273
+ [data-design-studio] .design-frame-picker { min-width:0; max-width:100%; }
274
+ [data-design-studio] .design-frame-picker select { min-width:0; flex:1 1 auto; appearance:none; line-height:1.3; min-height:32px; padding-inline-end:26px; background-image:linear-gradient(45deg,transparent 50%,var(--planr-color-text) 50%),linear-gradient(135deg,var(--planr-color-text) 50%,transparent 50%); background-position:calc(100% - 12px) 50%,calc(100% - 8px) 50%; background-size:4px 4px; background-repeat:no-repeat; }
275
+ [data-design-studio] .design-guidance > summary { height:auto; min-height:30px; padding-block:4px; line-height:1.3; white-space:nowrap; }
276
+ [data-design-studio] .planr-shell:not([data-design-presentation="true"]) .planr-stage-scroll { inset-block-start:var(--design-stage-context-measured-height,var(--design-stage-context-height)); }
272
277
  [data-design-studio] .planr-shell[data-design-view="prototype"]:not([data-design-presentation="true"]) .planr-stage-scroll { bottom:calc(var(--design-tools-space) + var(--design-status-space)); }
273
278
  [data-design-studio] .planr-shell[data-design-view="walkthrough"]:not([data-design-presentation="true"]) .planr-stage-scroll { bottom:calc(var(--design-tools-space) + var(--design-caption-height) + var(--design-status-space)); }
274
279
  [data-design-studio] .design-walkthrough-caption { height:var(--design-caption-height); min-height:var(--design-caption-height); max-height:var(--design-caption-height); bottom:var(--design-status-space); }
@@ -286,14 +291,14 @@ html[data-design-theme="light"] .design-export > div { box-shadow:0 12px 30px #1
286
291
  font-size:var(--design-type-control); line-height:1.4; min-height:var(--design-touch-target);
287
292
  min-width:0; max-width:100%; border-radius:8px; padding:10px 12px; scroll-margin-block:16px;
288
293
  }
289
- :root[data-design-studio] body select { height:var(--design-touch-target); }
294
+ :root[data-design-studio] body select { height:auto; min-height:var(--design-touch-target); }
290
295
  :root[data-design-studio] body :is(button:not(.planr-pin):not(.design-minimap-close),.design-export > summary,.design-tools-menu > summary,.design-guidance > summary) {
291
296
  min-height:var(--design-touch-target); min-width:var(--design-touch-target); touch-action:manipulation;
292
297
  }
293
298
  :root[data-design-studio] body :is(.design-dialog-close,.design-nav-close,.planr-rail-close,.planr-composer-header button) {
294
299
  width:var(--design-touch-target); height:var(--design-touch-target); flex-basis:var(--design-touch-target);
295
300
  }
296
- :root[data-design-studio] .design-canvas-tools button { height:var(--design-touch-target); white-space:nowrap; }
301
+ :root[data-design-studio] .design-canvas-tools button { height:auto; min-height:var(--design-touch-target); white-space:nowrap; }
297
302
  :root[data-design-studio] :is(.design-dialog-content,.design-inspector,.planr-thread-comment,.planr-reply) { font-size:var(--design-type-body); }
298
303
  :root[data-design-studio] :is(.design-profile-form > label,.planr-annotation-composer label,.planr-identity label,.design-profile-form legend) { font-size:var(--design-type-label); }
299
304
  :root[data-design-studio] :is(.design-muted,.design-profile-form > .design-muted,.design-dialog-status) { font-size:var(--design-type-label); }
@@ -365,6 +370,11 @@ html[data-design-theme="light"] .design-export > div { box-shadow:0 12px 30px #1
365
370
  :root[data-design-studio] .planr-shell { height:var(--design-frozen-shell-height,100%); }
366
371
  :root[data-design-studio] .design-toolbar { grid-template-columns:auto minmax(0,1fr) auto; grid-template-rows:52px; padding:0 max(8px,env(safe-area-inset-right,0px)) 0 max(8px,env(safe-area-inset-left,0px)); }
367
372
  :root[data-design-studio] .design-toolbar .planr-brand { display:none; }
373
+ :root[data-design-studio] .planr-shell[data-studio-framework="react"] .design-toolbar[data-studio-layout="compact"] { grid-template-columns:auto minmax(0,1fr); }
374
+ :root[data-design-studio] .planr-shell[data-studio-framework="react"] .design-toolbar[data-studio-layout="compact"] .studio-toolbar-leading { grid-column:1; grid-row:1; width:auto; }
375
+ :root[data-design-studio] .planr-shell[data-studio-framework="react"] .design-toolbar[data-studio-layout="compact"] .studio-toolbar-trailing { grid-column:2; grid-row:1; width:auto; flex-wrap:nowrap; }
376
+ :root[data-design-studio] .planr-shell[data-studio-framework="react"] .design-toolbar[data-studio-layout="compact"] .studio-toolbar-center { grid-column:1 / -1; grid-row:2; }
377
+ :root[data-design-studio] .planr-shell[data-studio-framework="react"] .design-toolbar[data-studio-layout="compact"] .studio-toolbar-status { width:auto; flex-basis:auto; max-width:128px; }
368
378
  :root[data-design-studio] .design-toolbar-trailing { grid-column:3; }
369
379
  :root[data-design-studio] .design-view-picker { grid-column:2; grid-row:1; }
370
380
  :root[data-design-studio] .design-stage-context { flex-wrap:nowrap; padding:4px 12px; }
@@ -1,4 +1,4 @@
1
- /* Trusted local adapter. Owner credentials never enter this runtime. */
1
+ /* Trusted local adapter. Owner keys never enter this runtime. */
2
2
  (() => {
3
3
  'use strict';
4
4
  const options = globalThis.__OPENPLANR_DESIGN_STUDIO_OPTIONS__ || {};
@@ -506,6 +506,11 @@
506
506
  transform: translateX(-50%);
507
507
  display: flex;
508
508
  align-items: center;
509
+ flex-wrap: wrap;
510
+ justify-content: center;
511
+ width: max-content;
512
+ max-width: calc(100% - 32px);
513
+ box-sizing: border-box;
509
514
  gap: 2px;
510
515
  padding: 4px;
511
516
  border: 1px solid var(--planr-color-rule);
@@ -514,22 +519,26 @@
514
519
  box-shadow: 0 8px 28px #0006;
515
520
  }
516
521
  .design-canvas-tools button {
517
- height: 28px;
522
+ height: auto;
523
+ min-height: 28px;
518
524
  min-width: 28px;
519
- padding: 0 8px;
525
+ flex: none;
526
+ padding: 4px 8px;
520
527
  border: 0;
521
528
  border-radius: 4px;
522
529
  background: transparent;
523
530
  font-size: 11px;
531
+ line-height: 1.3;
532
+ white-space: nowrap;
524
533
  cursor: pointer;
525
534
  }
526
535
  .design-canvas-tools [data-design-zoom="reset"] {
527
- flex: 0 0 56px;
528
- width: 56px;
536
+ flex: 0 0 auto;
537
+ width: auto;
529
538
  min-width: 56px;
530
539
  font-variant-numeric: tabular-nums;
531
540
  }
532
- .design-interaction-picker { height:30px; padding:0; border:0; background:transparent; }
541
+ .design-interaction-picker { height:auto; min-height:30px; flex:none; padding:0; border:0; background:transparent; }
533
542
  .design-interaction-picker button { display:flex; align-items:center; gap:6px; }
534
543
  .design-interaction-picker .design-button-label { display:none; }
535
544
  .design-canvas-tools .design-interaction-picker button[aria-pressed="true"] { background:var(--planr-color-raised); color:var(--planr-color-primary); }
@@ -2307,6 +2307,33 @@ ${fence}`;
2307
2307
  );
2308
2308
  content.append(value, reason, save);
2309
2309
  }
2310
+ function installStageContextGeometry() {
2311
+ const context = q(".design-stage-context", root);
2312
+ if (!context) return;
2313
+ let frame = 0;
2314
+ const measure = () => {
2315
+ frame = 0;
2316
+ if (disposed) return;
2317
+ const height = Math.ceil(context.getBoundingClientRect().height);
2318
+ const value = `${height}px`;
2319
+ if (height && root.style.getPropertyValue("--design-stage-context-measured-height") !== value)
2320
+ root.style.setProperty("--design-stage-context-measured-height", value);
2321
+ };
2322
+ const schedule = () => {
2323
+ if (!frame && !disposed) frame = requestAnimationFrame(measure);
2324
+ };
2325
+ const observer = typeof ResizeObserver === "function" ? new ResizeObserver(schedule) : null;
2326
+ observer?.observe(context);
2327
+ on(window, "resize", schedule);
2328
+ on(root, "planr:design-render", schedule);
2329
+ void document.fonts?.ready.then(schedule);
2330
+ measure();
2331
+ destroyers.push(() => {
2332
+ observer?.disconnect();
2333
+ cancelAnimationFrame(frame);
2334
+ root.style.removeProperty("--design-stage-context-measured-height");
2335
+ });
2336
+ }
2310
2337
  function installCanvas() {
2311
2338
  const tools = q(".design-canvas-tools");
2312
2339
  const more = node("details", "", { class: "design-tools-menu" });
@@ -3494,6 +3521,7 @@ ${fence}`;
3494
3521
  installComposerCategory();
3495
3522
  installInspector();
3496
3523
  installCanvas();
3524
+ installStageContextGeometry();
3497
3525
  installThumbnails();
3498
3526
  installPersonalDrafts();
3499
3527
  about(true);
@@ -46,36 +46,114 @@
46
46
  actions,
47
47
  className = ""
48
48
  }) {
49
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(Tag, { className: `planr-toolbar studio-toolbar ${className}`, "data-studio-react-chrome": "true", children: [
50
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "studio-toolbar-leading design-toolbar-leading", children: [
51
- leading,
52
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "planr-brand", children: [
53
- brand && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
54
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(StudioMark, {}),
55
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("span", { className: "design-wordmark", children: [
56
- "Open",
57
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { children: "Planr" })
49
+ const toolbar = (0, import_react3.useRef)(null);
50
+ (0, import_react3.useLayoutEffect)(() => {
51
+ const element = toolbar.current;
52
+ const window2 = element?.ownerDocument.defaultView;
53
+ if (!element || !window2) return;
54
+ const center = element.querySelector(".studio-toolbar-center");
55
+ const trailing = element.querySelector(".studio-toolbar-trailing");
56
+ const leading2 = element.querySelector(".studio-toolbar-leading");
57
+ if (!center || !trailing || !leading2) return;
58
+ const measure = () => {
59
+ const width = element.getBoundingClientRect().width;
60
+ if (!width) return;
61
+ element.dataset.studioDensity = width <= 680 ? "narrow" : "regular";
62
+ const style = window2.getComputedStyle(element);
63
+ const available = width - parseFloat(style.paddingLeft) - parseFloat(style.paddingRight);
64
+ const gap = parseFloat(style.columnGap) || 0;
65
+ element.dataset.studioCenter = "true";
66
+ const centerWidth = center.scrollWidth;
67
+ element.dataset.studioCenter = String(centerWidth > 0);
68
+ const controlSelector = 'button,a,summary,input,select,output,[role="status"]';
69
+ const controls = [...trailing.querySelectorAll(controlSelector)].filter(
70
+ (control) => control.getClientRects().length && !control.closest('[role="menu"],.studio-tooltip,[role="dialog"]') && (!control.closest("details") || !!control.closest("summary")) && !control.parentElement?.closest(controlSelector)
71
+ );
72
+ const actionWidth = controls.reduce((total, control) => total + control.getBoundingClientRect().width, 0) + Math.max(0, controls.length - 1) * (parseFloat(window2.getComputedStyle(trailing).gap) || 8);
73
+ const leadingControl = leading2.firstElementChild;
74
+ const branding = [
75
+ ...leading2.querySelectorAll(".planr-mark,.design-wordmark")
76
+ ].filter((node) => node.getClientRects().length);
77
+ const brandingWidth = branding.reduce(
78
+ (total, node) => total + node.getBoundingClientRect().width + 8,
79
+ 0
80
+ );
81
+ const leadingFloor = 128 + brandingWidth + (leadingControl instanceof window2.HTMLElement && !leadingControl.classList.contains("planr-brand") ? leadingControl.getBoundingClientRect().width + 8 : 0);
82
+ const outerWidth = Math.max(leadingFloor, actionWidth);
83
+ element.dataset.studioLayout = centerWidth > 0 ? width <= 680 || centerWidth + outerWidth * 2 + gap * 2 > available ? "compact" : "inline" : leadingFloor + actionWidth + gap > available ? "compact" : "inline";
84
+ };
85
+ measure();
86
+ let frame = 0;
87
+ const scheduleMeasure = () => {
88
+ if (frame) return;
89
+ frame = window2.requestAnimationFrame(() => {
90
+ frame = 0;
91
+ measure();
92
+ });
93
+ };
94
+ const resize = typeof window2.ResizeObserver === "function" ? new window2.ResizeObserver(scheduleMeasure) : null;
95
+ for (const node of [element, center, trailing]) resize?.observe(node);
96
+ const mutations = new window2.MutationObserver(scheduleMeasure);
97
+ mutations.observe(element, {
98
+ subtree: true,
99
+ childList: true,
100
+ characterData: true,
101
+ attributes: true,
102
+ attributeFilter: ["hidden"]
103
+ });
104
+ window2.addEventListener("resize", scheduleMeasure);
105
+ let active = true;
106
+ void element.ownerDocument.fonts?.ready.then(() => {
107
+ if (active) scheduleMeasure();
108
+ });
109
+ return () => {
110
+ active = false;
111
+ resize?.disconnect();
112
+ mutations.disconnect();
113
+ window2.cancelAnimationFrame(frame);
114
+ window2.removeEventListener("resize", scheduleMeasure);
115
+ };
116
+ }, [Tag]);
117
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
118
+ Tag,
119
+ {
120
+ ref: (node) => {
121
+ toolbar.current = node;
122
+ },
123
+ className: `planr-toolbar studio-toolbar ${className}`,
124
+ "data-studio-react-chrome": "true",
125
+ children: [
126
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "studio-toolbar-leading design-toolbar-leading", children: [
127
+ leading,
128
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "planr-brand", children: [
129
+ brand && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
130
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(StudioMark, {}),
131
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("span", { className: "design-wordmark", children: [
132
+ "Open",
133
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { children: "Planr" })
134
+ ] })
135
+ ] }),
136
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "studio-identity", children: [
137
+ hierarchy.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("nav", { className: "studio-hierarchy", "aria-label": "Project path", children: hierarchy.map((item, index2) => /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("span", { children: [
138
+ index2 > 0 && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { "aria-hidden": "true", children: " / " }),
139
+ item.href ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("a", { href: item.href, children: item.label }) : item.label
140
+ ] }, item.href ?? item.label)) }),
141
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("span", { className: "planr-title-block", children: [
142
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(StudioBadge, { children: kind === "artifact" ? "Artifact" : kind === "diagram" ? "Diagram" : "Design" }),
143
+ titleNode ?? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("strong", { title, children: title })
144
+ ] }),
145
+ subtitle && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "studio-subtitle", children: subtitle })
146
+ ] })
58
147
  ] })
59
148
  ] }),
60
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "studio-identity", children: [
61
- hierarchy.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("nav", { className: "studio-hierarchy", "aria-label": "Project path", children: hierarchy.map((item, index2) => /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("span", { children: [
62
- index2 > 0 && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { "aria-hidden": "true", children: " / " }),
63
- item.href ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("a", { href: item.href, children: item.label }) : item.label
64
- ] }, item.href ?? item.label)) }),
65
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("span", { className: "planr-title-block", children: [
66
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(StudioBadge, { children: kind === "artifact" ? "Artifact" : kind === "diagram" ? "Diagram" : "Design" }),
67
- titleNode ?? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("strong", { title, children: title })
68
- ] }),
69
- subtitle && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "studio-subtitle", children: subtitle })
149
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "studio-toolbar-center", children: viewPicker }),
150
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "studio-toolbar-trailing design-toolbar-trailing", children: [
151
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "studio-toolbar-status", children: status }),
152
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "studio-toolbar-actions", children: actions })
70
153
  ] })
71
- ] })
72
- ] }),
73
- viewPicker,
74
- /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "studio-toolbar-trailing design-toolbar-trailing", children: [
75
- status,
76
- actions
77
- ] })
78
- ] });
154
+ ]
155
+ }
156
+ );
79
157
  }
80
158
  function StudioMenu({
81
159
  label,