openplanr 2.2641.2 → 3.0.1

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 (114) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/dist/cli/commands/doctor.d.ts.map +1 -1
  3. package/dist/cli/commands/doctor.js +19 -4
  4. package/dist/cli/commands/doctor.js.map +1 -1
  5. package/dist/cli/commands/upgrade.d.ts.map +1 -1
  6. package/dist/cli/commands/upgrade.js +15 -11
  7. package/dist/cli/commands/upgrade.js.map +1 -1
  8. package/dist/cli/error-boundary.d.ts.map +1 -1
  9. package/dist/cli/error-boundary.js +2 -1
  10. package/dist/cli/error-boundary.js.map +1 -1
  11. package/dist/dashboard/.vite/manifest.json +1 -1
  12. package/dist/dashboard/assets/{index-DI_TKz9J.js → index-n08LJ6bK.js} +2 -2
  13. package/dist/dashboard/assets/{index-DI_TKz9J.js.map → index-n08LJ6bK.js.map} +1 -1
  14. package/dist/dashboard/dashboard-manifest.json +8 -8
  15. package/dist/dashboard/index.html +1 -1
  16. package/dist/services/claude-plugin-service.d.ts +9 -0
  17. package/dist/services/claude-plugin-service.d.ts.map +1 -1
  18. package/dist/services/claude-plugin-service.js +12 -0
  19. package/dist/services/claude-plugin-service.js.map +1 -1
  20. package/dist/services/runtime-change-summary.d.ts +4 -0
  21. package/dist/services/runtime-change-summary.d.ts.map +1 -1
  22. package/dist/services/runtime-change-summary.js +7 -0
  23. package/dist/services/runtime-change-summary.js.map +1 -1
  24. package/dist/services/runtime-manager/doctor.js +1 -1
  25. package/dist/services/runtime-manager/doctor.js.map +1 -1
  26. package/dist/services/runtime-manager/runtime-package.d.ts +15 -0
  27. package/dist/services/runtime-manager/runtime-package.d.ts.map +1 -1
  28. package/dist/services/runtime-manager/runtime-package.js +50 -10
  29. package/dist/services/runtime-manager/runtime-package.js.map +1 -1
  30. package/dist/services/runtime-manager-service.d.ts +11 -0
  31. package/dist/services/runtime-manager-service.d.ts.map +1 -1
  32. package/dist/services/runtime-manager-service.js +88 -16
  33. package/dist/services/runtime-manager-service.js.map +1 -1
  34. package/dist/services/upgrade-report.d.ts +2 -2
  35. package/dist/services/upgrade-report.d.ts.map +1 -1
  36. package/dist/services/upgrade-report.js +14 -2
  37. package/dist/services/upgrade-report.js.map +1 -1
  38. package/dist/services/upgrade-service.d.ts +22 -2
  39. package/dist/services/upgrade-service.d.ts.map +1 -1
  40. package/dist/services/upgrade-service.js +108 -20
  41. package/dist/services/upgrade-service.js.map +1 -1
  42. package/docs/CLI.md +4 -1
  43. package/docs/TROUBLESHOOTING.md +9 -6
  44. package/install.ps1 +3 -3
  45. package/install.sh +3 -3
  46. package/lib/host-packages/adapter-registry.json +5 -5
  47. package/lib/host-packages/capability-map.json +1 -1
  48. package/lib/host-packages/claude/.claude-plugin/marketplace.json +2 -2
  49. package/lib/host-packages/claude/openplanr/.claude-plugin/plugin.json +2 -2
  50. package/lib/host-packages/claude/openplanr/.openplanr-content.json +21 -21
  51. package/lib/host-packages/claude/openplanr/README.md +1 -1
  52. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/artifact/lib/artifact/ui/studio-shell.css +1 -1
  53. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/package.json +4 -4
  54. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/enhancements.css +14 -4
  55. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.css +14 -5
  56. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/12-design-review-experience.js +28 -0
  57. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/16-studio-shell.js +238 -68
  58. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources.json +6 -6
  59. package/lib/host-packages/claude/openplanr/runtime/design/scripts/runtime/packages/protocol/package.json +6 -2
  60. package/lib/host-packages/claude/openplanr/runtime/plan/scripts/runtime/packages/protocol/package.json +6 -2
  61. package/lib/host-packages/claude/openplanr/skills/delegate/SKILL.md +1 -1
  62. package/lib/host-packages/claude/openplanr/skills/delegate/references/capsule-contract.md +1 -1
  63. package/lib/host-packages/claude/openplanr/skills/delegate/scripts/run-preparation.mjs +3 -3
  64. package/lib/host-packages/claude/openplanr/skills/design/references/utilities.md +1 -1
  65. package/lib/host-packages/claude/openplanr/skills/design-loop/references/utilities.md +1 -1
  66. package/lib/host-packages/claude/openplanr/skills/design-review/references/utilities.md +1 -1
  67. package/lib/host-packages/claude/openplanr/skills/doctor/SKILL.md +4 -1
  68. package/lib/host-packages/claude/openplanr/skills/doctor/references/upgrade.md +8 -0
  69. package/lib/host-packages/claude/openplanr/skills/plan/SKILL.md +2 -2
  70. package/lib/host-packages/cursor/openplanr/.openplanr-content.json +20 -20
  71. package/lib/host-packages/cursor/openplanr/manifest.json +1 -1
  72. package/lib/host-packages/cursor/openplanr/rules/planr-delegate/references/capsule-contract.md +1 -1
  73. package/lib/host-packages/cursor/openplanr/rules/planr-delegate/scripts/run-preparation.mjs +3 -3
  74. package/lib/host-packages/cursor/openplanr/rules/planr-delegate.mdc +1 -1
  75. package/lib/host-packages/cursor/openplanr/rules/planr-design/references/utilities.md +1 -1
  76. package/lib/host-packages/cursor/openplanr/rules/planr-design-loop/references/utilities.md +1 -1
  77. package/lib/host-packages/cursor/openplanr/rules/planr-design-review/references/utilities.md +1 -1
  78. package/lib/host-packages/cursor/openplanr/rules/planr-doctor/references/upgrade.md +8 -0
  79. package/lib/host-packages/cursor/openplanr/rules/planr-doctor.mdc +4 -1
  80. package/lib/host-packages/cursor/openplanr/rules/planr-plan.mdc +2 -2
  81. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/artifact/lib/artifact/ui/studio-shell.css +1 -1
  82. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/package.json +4 -4
  83. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/enhancements.css +14 -4
  84. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.css +14 -5
  85. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/12-design-review-experience.js +28 -0
  86. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/16-studio-shell.js +238 -68
  87. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources.json +6 -6
  88. package/lib/host-packages/cursor/openplanr/runtime/design/scripts/runtime/packages/protocol/package.json +6 -2
  89. package/lib/host-packages/cursor/openplanr/runtime/plan/scripts/runtime/packages/protocol/package.json +6 -2
  90. package/lib/host-packages/openai/.claude-plugin/marketplace.json +2 -2
  91. package/lib/host-packages/openai/openplanr/.codex-plugin/plugin.json +1 -1
  92. package/lib/host-packages/openai/openplanr/.openplanr-content.json +20 -20
  93. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/artifact/lib/artifact/ui/studio-shell.css +1 -1
  94. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/package.json +4 -4
  95. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/enhancements.css +14 -4
  96. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.css +14 -5
  97. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/12-design-review-experience.js +28 -0
  98. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/16-studio-shell.js +238 -68
  99. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources.json +6 -6
  100. package/lib/host-packages/openai/openplanr/runtime/design/scripts/runtime/packages/protocol/package.json +6 -2
  101. package/lib/host-packages/openai/openplanr/runtime/plan/scripts/runtime/packages/protocol/package.json +6 -2
  102. package/lib/host-packages/openai/openplanr/skills/delegate/SKILL.md +1 -1
  103. package/lib/host-packages/openai/openplanr/skills/delegate/references/capsule-contract.md +1 -1
  104. package/lib/host-packages/openai/openplanr/skills/delegate/scripts/run-preparation.mjs +3 -3
  105. package/lib/host-packages/openai/openplanr/skills/design/references/utilities.md +1 -1
  106. package/lib/host-packages/openai/openplanr/skills/design-loop/references/utilities.md +1 -1
  107. package/lib/host-packages/openai/openplanr/skills/design-review/references/utilities.md +1 -1
  108. package/lib/host-packages/openai/openplanr/skills/doctor/SKILL.md +4 -1
  109. package/lib/host-packages/openai/openplanr/skills/doctor/references/upgrade.md +8 -0
  110. package/lib/host-packages/openai/openplanr/skills/plan/SKILL.md +2 -2
  111. package/lib/node-runtime.d.mts +1 -1
  112. package/lib/node-runtime.mjs +2 -7
  113. package/package.json +5 -6
  114. package/bin/planr.js +0 -7
@@ -32,6 +32,34 @@
32
32
  /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("rect", { x: "127", y: "71", width: "18", height: "18", rx: "3", fill: "currentColor" })
33
33
  ] }) }) });
34
34
  }
35
+ function inlineGap(element) {
36
+ const view = element?.ownerDocument.defaultView;
37
+ return view && element ? parseFloat(view.getComputedStyle(element).gap) || 0 : 0;
38
+ }
39
+ function measureLeadingFloor(leading) {
40
+ const view = leading.ownerDocument.defaultView;
41
+ if (!view) return 128;
42
+ const leadingControls = [...leading.children].filter(
43
+ (node) => node instanceof view.HTMLElement && !node.classList.contains("planr-brand") && node.getClientRects().length > 0
44
+ );
45
+ const branding = [
46
+ ...leading.querySelectorAll(".planr-mark,.design-wordmark")
47
+ ].filter((node) => node.getClientRects().length);
48
+ const brandGap = inlineGap(leading.querySelector(".planr-brand"));
49
+ const brandingWidth = branding.reduce(
50
+ (total, node) => total + node.getBoundingClientRect().width + brandGap,
51
+ 0
52
+ );
53
+ const titleBlock = leading.querySelector(".planr-title-block");
54
+ const badge = titleBlock?.querySelector(".studio-type-badge");
55
+ const title = titleBlock?.querySelector("strong,.de-title");
56
+ const titleFloor = Math.max(36, parseFloat(view.getComputedStyle(title ?? leading).fontSize) * 3);
57
+ const identityFloor = Math.max(
58
+ 128,
59
+ (badge?.getBoundingClientRect().width || 0) + inlineGap(titleBlock) + titleFloor
60
+ );
61
+ return identityFloor + brandingWidth + leadingControls.reduce((total, control) => total + control.getBoundingClientRect().width, 0) + leadingControls.length * inlineGap(leading);
62
+ }
35
63
  function StudioToolbar({
36
64
  title,
37
65
  titleNode,
@@ -44,38 +72,123 @@
44
72
  viewPicker,
45
73
  status,
46
74
  actions,
75
+ secondaryActions,
47
76
  className = ""
48
77
  }) {
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" })
78
+ const toolbar = (0, import_react3.useRef)(null);
79
+ (0, import_react3.useLayoutEffect)(() => {
80
+ const element = toolbar.current;
81
+ const window2 = element?.ownerDocument.defaultView;
82
+ if (!element || !window2) return;
83
+ const center = element.querySelector(".studio-toolbar-center");
84
+ const trailing = element.querySelector(".studio-toolbar-trailing");
85
+ const leading2 = element.querySelector(".studio-toolbar-leading");
86
+ const secondary = element.querySelector(".studio-toolbar-secondary");
87
+ if (!center || !trailing || !leading2) return;
88
+ const measure = () => {
89
+ const width = element.getBoundingClientRect().width;
90
+ if (!width) return;
91
+ element.dataset.studioDensity = width <= 680 ? "narrow" : "regular";
92
+ const style = window2.getComputedStyle(element);
93
+ const available = width - parseFloat(style.paddingLeft) - parseFloat(style.paddingRight);
94
+ const gap = Math.max(12, parseFloat(style.columnGap) || 0);
95
+ element.dataset.studioCenter = "true";
96
+ const centerWidth = center.scrollWidth;
97
+ element.dataset.studioCenter = String(centerWidth > 0);
98
+ const controlSelector = 'button,a,summary,input,select,output,[role="status"]';
99
+ const controls = [
100
+ ...trailing.querySelectorAll(controlSelector),
101
+ ...secondary?.querySelectorAll(controlSelector) ?? []
102
+ ].filter(
103
+ (control) => control.getClientRects().length && !control.closest('[role="menu"],.studio-tooltip,[role="dialog"]') && (!control.closest("details") || !!control.closest("summary")) && !control.parentElement?.closest(controlSelector)
104
+ );
105
+ const actionWidth = controls.reduce((total, control) => {
106
+ if (secondary?.contains(control) && control.getAttribute("role") === "status") {
107
+ const range = element.ownerDocument.createRange();
108
+ range.selectNodeContents(control);
109
+ const textWidth = range.getBoundingClientRect().width;
110
+ const controlStyle = window2.getComputedStyle(control);
111
+ return total + textWidth + (parseFloat(controlStyle.paddingLeft) || 0) + (parseFloat(controlStyle.paddingRight) || 0);
112
+ }
113
+ return total + control.getBoundingClientRect().width;
114
+ }, 0) + Math.max(0, controls.length - 1) * (parseFloat(window2.getComputedStyle(trailing).gap) || 8);
115
+ const leadingFloor = measureLeadingFloor(leading2);
116
+ const outerWidth = Math.max(leadingFloor, actionWidth);
117
+ element.dataset.studioLayout = centerWidth > 0 ? width <= 680 || centerWidth + outerWidth * 2 + gap * 2 > available ? "compact" : "inline" : leadingFloor + actionWidth + gap > available ? "compact" : "inline";
118
+ };
119
+ measure();
120
+ let frame = 0;
121
+ const scheduleMeasure = () => {
122
+ if (frame) return;
123
+ frame = window2.requestAnimationFrame(() => {
124
+ frame = 0;
125
+ measure();
126
+ });
127
+ };
128
+ const resize = typeof window2.ResizeObserver === "function" ? new window2.ResizeObserver(scheduleMeasure) : null;
129
+ for (const node of [element, center, trailing, secondary]) if (node) resize?.observe(node);
130
+ const mutations = new window2.MutationObserver(scheduleMeasure);
131
+ mutations.observe(element, {
132
+ subtree: true,
133
+ childList: true,
134
+ characterData: true,
135
+ attributes: true,
136
+ attributeFilter: ["hidden"]
137
+ });
138
+ window2.addEventListener("resize", scheduleMeasure);
139
+ let active = true;
140
+ void element.ownerDocument.fonts?.ready.then(() => {
141
+ if (active) scheduleMeasure();
142
+ });
143
+ return () => {
144
+ active = false;
145
+ resize?.disconnect();
146
+ mutations.disconnect();
147
+ window2.cancelAnimationFrame(frame);
148
+ window2.removeEventListener("resize", scheduleMeasure);
149
+ };
150
+ }, [Tag]);
151
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
152
+ Tag,
153
+ {
154
+ ref: (node) => {
155
+ toolbar.current = node;
156
+ },
157
+ className: `planr-toolbar studio-toolbar ${className}`,
158
+ "data-studio-react-chrome": "true",
159
+ children: [
160
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "studio-toolbar-leading design-toolbar-leading", children: [
161
+ leading,
162
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "planr-brand", children: [
163
+ brand && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
164
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(StudioMark, {}),
165
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("span", { className: "design-wordmark", children: [
166
+ "Open",
167
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { children: "Planr" })
168
+ ] })
169
+ ] }),
170
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "studio-identity", children: [
171
+ 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: [
172
+ index2 > 0 && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { "aria-hidden": "true", children: " / " }),
173
+ item.href ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("a", { href: item.href, children: item.label }) : item.label
174
+ ] }, item.href ?? item.label)) }),
175
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("span", { className: "planr-title-block", children: [
176
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(StudioBadge, { children: kind === "artifact" ? "Artifact" : kind === "diagram" ? "Diagram" : "Design" }),
177
+ titleNode ?? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("strong", { title, children: title })
178
+ ] }),
179
+ subtitle && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { className: "studio-subtitle", children: subtitle })
180
+ ] })
58
181
  ] })
59
182
  ] }),
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 })
70
- ] })
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
- ] });
183
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "studio-toolbar-center", children: viewPicker }),
184
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "studio-toolbar-trailing design-toolbar-trailing", children: [
185
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "studio-toolbar-status", children: status }),
186
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "studio-toolbar-actions", children: actions })
187
+ ] }),
188
+ secondaryActions && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { className: "studio-toolbar-secondary", children: secondaryActions })
189
+ ]
190
+ }
191
+ );
79
192
  }
80
193
  function StudioMenu({
81
194
  label,
@@ -86,49 +199,106 @@
86
199
  onOpenChange
87
200
  }) {
88
201
  const trigger = (0, import_react3.useRef)(null);
89
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(dist_exports5.Root, { modal: false, open, onOpenChange, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("span", { className: `studio-menu ${className}`, children: [
90
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(dist_exports5.Trigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(StudioButton, { "aria-label": label, title: label, ...triggerAttributes, ref: trigger, children: [
91
- label,
92
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { "aria-hidden": "true", children: "⌄" })
93
- ] }) }),
94
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
95
- dist_exports5.Content,
96
- {
97
- className: "studio-menu-content",
98
- align: "end",
99
- sideOffset: 8,
100
- collisionPadding: 8,
101
- onCloseAutoFocus: (event) => {
102
- event.preventDefault();
103
- const content = event.target;
104
- const ownerDocument = content?.ownerDocument;
105
- const active = ownerDocument?.activeElement;
106
- if (active?.isConnected && active !== ownerDocument?.body && active !== ownerDocument?.documentElement && !content?.contains(active))
107
- return;
108
- if (trigger.current?.isConnected) trigger.current.focus();
109
- },
110
- children: items.map((item, index2) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
111
- dist_exports5.Item,
202
+ const mousePosition = (0, import_react3.useRef)(null);
203
+ const keyboardPosition = (0, import_react3.useRef)(null);
204
+ (0, import_react3.useLayoutEffect)(() => {
205
+ const ownerDocument = trigger.current?.ownerDocument;
206
+ if (!ownerDocument) return;
207
+ const move = (event) => {
208
+ if (event.pointerType !== "mouse") return;
209
+ const position = { x: event.clientX, y: event.clientY };
210
+ const previous = keyboardPosition.current;
211
+ if (previous && (previous.x !== position.x || previous.y !== position.y))
212
+ keyboardPosition.current = null;
213
+ mousePosition.current = position;
214
+ };
215
+ const down = (event) => {
216
+ keyboardPosition.current = null;
217
+ if (event.pointerType === "mouse")
218
+ mousePosition.current = { x: event.clientX, y: event.clientY };
219
+ };
220
+ ownerDocument.addEventListener("pointermove", move, true);
221
+ ownerDocument.addEventListener("pointerdown", down, true);
222
+ return () => {
223
+ ownerDocument.removeEventListener("pointermove", move, true);
224
+ ownerDocument.removeEventListener("pointerdown", down, true);
225
+ };
226
+ }, []);
227
+ const retainKeyboardFocus = (event) => {
228
+ const position = keyboardPosition.current;
229
+ if (event.pointerType === "mouse" && position?.x === event.clientX && position.y === event.clientY)
230
+ event.preventDefault();
231
+ };
232
+ const keyboardInput = () => {
233
+ keyboardPosition.current = mousePosition.current;
234
+ };
235
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
236
+ dist_exports5.Root,
237
+ {
238
+ modal: false,
239
+ open,
240
+ onOpenChange: (value) => {
241
+ if (!value) keyboardPosition.current = null;
242
+ onOpenChange?.(value);
243
+ },
244
+ children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("span", { className: `studio-menu ${className}`, children: [
245
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(dist_exports5.Trigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
246
+ StudioButton,
247
+ {
248
+ "aria-label": label,
249
+ title: label,
250
+ ...triggerAttributes,
251
+ ref: trigger,
252
+ onKeyDownCapture: keyboardInput,
253
+ children: [
254
+ label,
255
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { "aria-hidden": "true", children: "⌄" })
256
+ ]
257
+ }
258
+ ) }),
259
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
260
+ dist_exports5.Content,
112
261
  {
113
- asChild: true,
114
- disabled: item.disabled,
115
- onSelect: item.onSelect,
116
- children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
117
- "button",
262
+ className: "studio-menu-content",
263
+ align: "end",
264
+ sideOffset: 8,
265
+ collisionPadding: 8,
266
+ onKeyDownCapture: keyboardInput,
267
+ onCloseAutoFocus: (event) => {
268
+ event.preventDefault();
269
+ const content = event.target;
270
+ const ownerDocument = content?.ownerDocument;
271
+ const active = ownerDocument?.activeElement;
272
+ if (active?.isConnected && active !== ownerDocument?.body && active !== ownerDocument?.documentElement && !content?.contains(active))
273
+ return;
274
+ if (trigger.current?.isConnected) trigger.current.focus();
275
+ },
276
+ children: items.map((item, index2) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
277
+ dist_exports5.Item,
118
278
  {
119
- type: "button",
120
- className: `studio-menu-item${index2 > 0 && item.group !== items[index2 - 1].group ? " studio-menu-group-start" : ""}`,
279
+ asChild: true,
121
280
  disabled: item.disabled,
122
- ...item.attributes,
123
- children: item.label
124
- }
125
- )
126
- },
127
- item.id
128
- ))
129
- }
130
- )
131
- ] }) });
281
+ onSelect: item.onSelect,
282
+ onPointerMove: retainKeyboardFocus,
283
+ onPointerLeave: retainKeyboardFocus,
284
+ children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
285
+ "button",
286
+ {
287
+ type: "button",
288
+ className: `studio-menu-item${index2 > 0 && item.group !== items[index2 - 1].group ? " studio-menu-group-start" : ""}`,
289
+ disabled: item.disabled,
290
+ ...item.attributes,
291
+ children: item.label
292
+ }
293
+ )
294
+ },
295
+ item.id
296
+ ))
297
+ }
298
+ )
299
+ ] })
300
+ }
301
+ );
132
302
  }
133
303
  function StudioPanelDialog({
134
304
  open,
@@ -2,8 +2,8 @@
2
2
  "kind": "openplanr-runtime-asset-sources",
3
3
  "schemaVersion": "1.0.0",
4
4
  "asset": "studio.js",
5
- "bytes": 1136703,
6
- "sha256": "24745f5b2327275efa2cb904652c4451b16a6893d4284e375a3ce986d909f49e",
5
+ "bytes": 1146075,
6
+ "sha256": "f649b59fe0a31ec9055d6e5bf5b68425c1fe4e996224c35603d84f91021949cf",
7
7
  "scopes": [
8
8
  {
9
9
  "id": "bundle",
@@ -143,8 +143,8 @@
143
143
  "packages/design/lib/design/ui/enhancements.mjs",
144
144
  "packages/design/lib/design/ui/handoff-center.mjs"
145
145
  ],
146
- "bytes": 151613,
147
- "sha256": "c40392e1328eb17f9d0a778d1f20e44118731d7c6a0a25f0aa731304a86994a0"
146
+ "bytes": 152776,
147
+ "sha256": "9e2ac3d6b99028c7335aacf548f9e04fdf709d15f889db3e35bbebc389631000"
148
148
  },
149
149
  {
150
150
  "path": "studio.js.sources/13-studio-shell.js",
@@ -238,8 +238,8 @@
238
238
  "packages/artifact/lib/artifact/ui/studio-shell-components.mjs",
239
239
  "packages/artifact/lib/artifact/ui/studio-shell-mount-impl.mjs"
240
240
  ],
241
- "bytes": 19068,
242
- "sha256": "a84049d6a41dd3f655e85a4a39e4874a4c7f6f2013ad9d8c192d22a7082bf407"
241
+ "bytes": 27277,
242
+ "sha256": "81af29a6a5a15fd4f0ef41fc48e1eca63c30b3745fd1d92830ba83f7cf2ba603"
243
243
  },
244
244
  {
245
245
  "path": "studio.js.sources/17-design-studio.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openplanr/protocol",
3
- "version": "0.10.3",
3
+ "version": "0.12.0",
4
4
  "type": "module",
5
5
  "description": "Canonical OpenPlanr schemas, registries, typed errors, and portable contract validation",
6
6
  "license": "MIT",
@@ -115,6 +115,10 @@
115
115
  "./sharing-security-contracts": {
116
116
  "types": "./src/sharing-security-contracts.d.mts",
117
117
  "import": "./src/sharing-security-contracts.mjs"
118
+ },
119
+ "./enterprise-journey-contracts": {
120
+ "types": "./src/enterprise-journey-contracts.d.mts",
121
+ "import": "./src/enterprise-journey-contracts.mjs"
118
122
  }
119
123
  },
120
124
  "files": [
@@ -132,7 +136,7 @@
132
136
  "test": "node --test ../../tests/protocol/*.test.mjs"
133
137
  },
134
138
  "engines": {
135
- "node": ">=20"
139
+ "node": ">=22.13.0"
136
140
  },
137
141
  "repository": {
138
142
  "type": "git",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openplanr/protocol",
3
- "version": "0.10.3",
3
+ "version": "0.12.0",
4
4
  "type": "module",
5
5
  "description": "Canonical OpenPlanr schemas, registries, typed errors, and portable contract validation",
6
6
  "license": "MIT",
@@ -115,6 +115,10 @@
115
115
  "./sharing-security-contracts": {
116
116
  "types": "./src/sharing-security-contracts.d.mts",
117
117
  "import": "./src/sharing-security-contracts.mjs"
118
+ },
119
+ "./enterprise-journey-contracts": {
120
+ "types": "./src/enterprise-journey-contracts.d.mts",
121
+ "import": "./src/enterprise-journey-contracts.mjs"
118
122
  }
119
123
  },
120
124
  "files": [
@@ -132,7 +136,7 @@
132
136
  "test": "node --test ../../tests/protocol/*.test.mjs"
133
137
  },
134
138
  "engines": {
135
- "node": ">=20"
139
+ "node": ">=22.13.0"
136
140
  },
137
141
  "repository": {
138
142
  "type": "git",
@@ -4,14 +4,14 @@
4
4
  "name": "OpenPlanr"
5
5
  },
6
6
  "metadata": {
7
- "version": "2.2641.2",
7
+ "version": "3.0.1",
8
8
  "description": "Generated local OpenPlanr package."
9
9
  },
10
10
  "plugins": [
11
11
  {
12
12
  "name": "planr",
13
13
  "source": "./openplanr",
14
- "version": "2.2641.2",
14
+ "version": "3.0.1",
15
15
  "description": "Close the loop from intent to delivery. Plan, design, build, review, and operate from durable context in your repository.",
16
16
  "strict": true
17
17
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "planr",
3
- "version": "2.2641.2",
3
+ "version": "3.0.1",
4
4
  "description": "Close the loop from intent to delivery. Plan, design, build, review, and operate from durable context in your repository.",
5
5
  "author": {
6
6
  "name": "OpenPlanr",
@@ -8,7 +8,7 @@
8
8
  "files": [
9
9
  {
10
10
  "path": ".codex-plugin/plugin.json",
11
- "digest": "sha256:10f28fc04cc1d302086cde8f7f8d1b897a216754f98f6cc6c5b0e28889792287"
11
+ "digest": "sha256:627d400733ee719b2d665f813f48df312fb125b9509ce231eb78eea208f73fc6"
12
12
  },
13
13
  {
14
14
  "path": "LICENSE",
@@ -112,7 +112,7 @@
112
112
  },
113
113
  {
114
114
  "path": "runtime/design/scripts/runtime/packages/artifact/lib/artifact/ui/studio-shell.css",
115
- "digest": "sha256:4449fbe06d25ae0ad9b2faf15a4558f1c6fc8506d357e785dfdbc8befe69df59"
115
+ "digest": "sha256:514295a7c32cf8359385de2cdf8369aa41ccc6b119c93daad757182099067661"
116
116
  },
117
117
  {
118
118
  "path": "runtime/design/scripts/runtime/packages/artifact/templates/artifact-review-stage.js.sources.json",
@@ -152,11 +152,11 @@
152
152
  },
153
153
  {
154
154
  "path": "runtime/design/scripts/runtime/packages/design/package.json",
155
- "digest": "sha256:b3d397b4bb27c37799f143ee6a83c7000f3d1a38aba3e321778ed6cc8916d702"
155
+ "digest": "sha256:f1bd16719287e54ade15a9d4e6f889dd3385b6f1a8bf851332992533475cf3b5"
156
156
  },
157
157
  {
158
158
  "path": "runtime/design/scripts/runtime/packages/design/templates/studio/enhancements.css",
159
- "digest": "sha256:df58a7ee4ffcadac780d3170abbeb00cfecb1f42db692ba62eb6f66a251bd0ea"
159
+ "digest": "sha256:bdb55a9464e96fba112aad73354d54b6ccb8ac5d9bc100a90b51df4633ff11f7"
160
160
  },
161
161
  {
162
162
  "path": "runtime/design/scripts/runtime/packages/design/templates/studio/handoff-center.css",
@@ -172,11 +172,11 @@
172
172
  },
173
173
  {
174
174
  "path": "runtime/design/scripts/runtime/packages/design/templates/studio/studio.css",
175
- "digest": "sha256:c9291e20366315b23c73e920ec5426d4c33d0880863d39650d4c535956984b1c"
175
+ "digest": "sha256:75ca0c3036d5c281e60a4155765ad8c2e9373bd39d34d4facebfe9bf26278c88"
176
176
  },
177
177
  {
178
178
  "path": "runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources.json",
179
- "digest": "sha256:268b66e770a35e3f5606a4c7b44f6fb6bd5659c15d1813f7421781ef3e9bcf99"
179
+ "digest": "sha256:fb0d23636597168f9f139c21ce9c5af63e225ad765231b1f0b7c2af2675d8cb6"
180
180
  },
181
181
  {
182
182
  "path": "runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/01-module-runtime.js",
@@ -224,7 +224,7 @@
224
224
  },
225
225
  {
226
226
  "path": "runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/12-design-review-experience.js",
227
- "digest": "sha256:c40392e1328eb17f9d0a778d1f20e44118731d7c6a0a25f0aa731304a86994a0"
227
+ "digest": "sha256:9e2ac3d6b99028c7335aacf548f9e04fdf709d15f889db3e35bbebc389631000"
228
228
  },
229
229
  {
230
230
  "path": "runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/13-studio-shell.js",
@@ -240,7 +240,7 @@
240
240
  },
241
241
  {
242
242
  "path": "runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/16-studio-shell.js",
243
- "digest": "sha256:a84049d6a41dd3f655e85a4a39e4874a4c7f6f2013ad9d8c192d22a7082bf407"
243
+ "digest": "sha256:81af29a6a5a15fd4f0ef41fc48e1eca63c30b3745fd1d92830ba83f7cf2ba603"
244
244
  },
245
245
  {
246
246
  "path": "runtime/design/scripts/runtime/packages/design/templates/studio/studio.js.sources/17-design-studio.js",
@@ -248,7 +248,7 @@
248
248
  },
249
249
  {
250
250
  "path": "runtime/design/scripts/runtime/packages/protocol/package.json",
251
- "digest": "sha256:037b4f8f4fd2f1db03d5106ec974e250502d1a4ce39a018e668ab7e07d93de43"
251
+ "digest": "sha256:ad2e601d993087146fcd4d049ddd1cf7e06f7102eb178e2c65017624a2252393"
252
252
  },
253
253
  {
254
254
  "path": "runtime/design/scripts/runtime/packages/protocol/registries/artifact-theme.json",
@@ -368,7 +368,7 @@
368
368
  },
369
369
  {
370
370
  "path": "runtime/plan/scripts/runtime/packages/protocol/package.json",
371
- "digest": "sha256:037b4f8f4fd2f1db03d5106ec974e250502d1a4ce39a018e668ab7e07d93de43"
371
+ "digest": "sha256:ad2e601d993087146fcd4d049ddd1cf7e06f7102eb178e2c65017624a2252393"
372
372
  },
373
373
  {
374
374
  "path": "runtime/plan/scripts/runtime/packages/protocol/schemas/v1.1.0/artifact-review.schema.json",
@@ -568,7 +568,7 @@
568
568
  },
569
569
  {
570
570
  "path": "skills/delegate/references/capsule-contract.md",
571
- "digest": "sha256:9bd80db920018a43cecc02f4996d65d5eb54a121fce6caa3c9198cb0ca01bf6a"
571
+ "digest": "sha256:22e5daac9ad9cb0951222fef4d0f45ae35de4a6b7ee2b47d660cc6b672188fff"
572
572
  },
573
573
  {
574
574
  "path": "skills/delegate/references/integration-review.md",
@@ -672,7 +672,7 @@
672
672
  },
673
673
  {
674
674
  "path": "skills/delegate/scripts/run-preparation.mjs",
675
- "digest": "sha256:dbc03621c77946ad77e97db84d826714d2fe75eccd15963756791b1439b46589"
675
+ "digest": "sha256:746630b00e1c252cae6dd7e78cde4b2d6c65e75f1ef19a092111e1e4de5152e3"
676
676
  },
677
677
  {
678
678
  "path": "skills/delegate/scripts/run-record.mjs",
@@ -684,7 +684,7 @@
684
684
  },
685
685
  {
686
686
  "path": "skills/delegate/SKILL.md",
687
- "digest": "sha256:e3bc67ad5506a9d360344a4071e9cad1667e0481603789c5fb7b45ae0e39f826"
687
+ "digest": "sha256:344d272793e81025c73d2c62333e786f4a073dec30f1ac8eb8ed560bea2c8e4f"
688
688
  },
689
689
  {
690
690
  "path": "skills/design-loop/agents/openai.yaml",
@@ -728,7 +728,7 @@
728
728
  },
729
729
  {
730
730
  "path": "skills/design-loop/references/utilities.md",
731
- "digest": "sha256:df4414af1974d8268af25cfb33ce27d967e0a7f0ca29e75de82b91f3dacf2543"
731
+ "digest": "sha256:cedeae549cda5434a768846dc3d83a1baddfa74940276485db6fba1c649301b5"
732
732
  },
733
733
  {
734
734
  "path": "skills/design-loop/schemas/design-document.schema.json",
@@ -792,7 +792,7 @@
792
792
  },
793
793
  {
794
794
  "path": "skills/design-review/references/utilities.md",
795
- "digest": "sha256:df4414af1974d8268af25cfb33ce27d967e0a7f0ca29e75de82b91f3dacf2543"
795
+ "digest": "sha256:cedeae549cda5434a768846dc3d83a1baddfa74940276485db6fba1c649301b5"
796
796
  },
797
797
  {
798
798
  "path": "skills/design-review/schemas/design-document.schema.json",
@@ -856,7 +856,7 @@
856
856
  },
857
857
  {
858
858
  "path": "skills/design/references/utilities.md",
859
- "digest": "sha256:df4414af1974d8268af25cfb33ce27d967e0a7f0ca29e75de82b91f3dacf2543"
859
+ "digest": "sha256:cedeae549cda5434a768846dc3d83a1baddfa74940276485db6fba1c649301b5"
860
860
  },
861
861
  {
862
862
  "path": "skills/design/schemas/design-document.schema.json",
@@ -916,11 +916,11 @@
916
916
  },
917
917
  {
918
918
  "path": "skills/doctor/references/upgrade.md",
919
- "digest": "sha256:7370954450db1bac591d4f90b58df9022f6edac5b32d05051f93dbd35b0e35b9"
919
+ "digest": "sha256:b137e82d63ceeecef4e5c1cac72acbaaa2edbc29798214507ab9613d16088fde"
920
920
  },
921
921
  {
922
922
  "path": "skills/doctor/SKILL.md",
923
- "digest": "sha256:417b1d1f860db1ccd59820c52cfd6873c7feed80a639537c43babea8d76ef3d3"
923
+ "digest": "sha256:ae1c90830273a51d54c60a846ea00e8c4412f50e43ad8172a2e112e2b51e6412"
924
924
  },
925
925
  {
926
926
  "path": "skills/investigate/agents/openai.yaml",
@@ -1024,7 +1024,7 @@
1024
1024
  },
1025
1025
  {
1026
1026
  "path": "skills/plan/SKILL.md",
1027
- "digest": "sha256:6cfa23c318f29fbd5c6f34541c43a84bf7681376563170cfd241d99b49951f16"
1027
+ "digest": "sha256:a2e82ebfbc71ceff6186779a60ba1a3b47ec8a6c42444a6953abb0bebbfa8c54"
1028
1028
  },
1029
1029
  {
1030
1030
  "path": "skills/release/agents/openai.yaml",
@@ -1171,5 +1171,5 @@
1171
1171
  "digest": "sha256:a90f713ac4cda7fc0df0c2b40256ddba3cfa1ee8ea809705f1cf735324952022"
1172
1172
  }
1173
1173
  ],
1174
- "contentDigest": "sha256:13d8e15bcaf9a2e643db0c2b5b9c6c08da6565f5419ea7c6021756c5bdfce5fb"
1174
+ "contentDigest": "sha256:cbc8a482b485ddbc3f62ffec1e6f6a070d4445e0633cd53c039701b73f13be8f"
1175
1175
  }