Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ jobs:
packages/editor/components/AppHeader.webmcpIndicator.test.tsx
packages/ui/components/MathBlock.firstPaint.test.tsx
packages/ui/components/DiagramBlock.lazyRetry.test.tsx
packages/ui/components/DecisionControl.test.tsx

opencode-v2:
name: OpenCode 2 installed package
Expand Down
4 changes: 2 additions & 2 deletions packages/core/guide-viewer-manifest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import type { GuideViewerAssets } from "./guide-format";

export const GUIDE_VIEWER_MANIFEST: Omit<GuideViewerAssets, "baseUrl"> = {
js: "viewer.AnU5z-dd.js",
css: "viewer.BWA5Rzwo.css",
css: "viewer.D7WwEXBg.css",
jsIntegrity: "sha384-iOm8MrJ1lGtn93UvbQr02EvCOHwQqXcDd84+5pUwfCSoYy146a+tLaemgZjNql8c",
cssIntegrity: "sha384-Q9u2GcsAQO3r93fnqIo1YUOHl11vUm908qK7wPn0jiJd3rVoJZH/HqL4KPzwGWk0",
cssIntegrity: "sha384-9mL9Mhu3b+Tc4SXsoajp8zIRnjx6hy8eDVIPufiPADXCThZ0Dw45jSRUSCQUEGQv",
langs: {
"astro": "chunks/astro.BykyiR6i.js",
"c": "chunks/c.BIGW1oBm.js",
Expand Down
5 changes: 3 additions & 2 deletions packages/ui/HANDOFF.md
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ Don't import these in a host. Each hits hardcoded Plannotator endpoints:
- `utils/sharing` — Plannotator's public paste service (share-URL feature).
- `hooks/useUpdateCheck`, `components/MenuVersionSection`, `components/PlanHeaderMenu` — Plannotator release checks.
- `utils/planAgentInstructions`, `utils/reviewAgentInstructions` — generate agent instructions that curl Plannotator's local API.
- `components/DecisionControl`, `utils/decisionSpec`, `hooks/useDismissablePopover` — session decision chrome for Plannotator's own approve/deny/exit endpoints (a host's session decisions are its own outcomes against its own backend).

If Workspaces ever wants one of these surfaces, the path is the same as everything else: add a seam to the module in a Plannotator PR, don't fork the component.

Expand Down Expand Up @@ -676,8 +677,8 @@ Additive only, but required: `@plannotator/ui` 0.32.0 imports the new `@plannota

## Publishing & versioning

- The current pair is `@plannotator/ui` `0.37.0` on `@plannotator/core` `0.25.1`. Core 0.25.1 publishes the `annotation-threads` subpath already used by `AnnotationPanel` and `utils/parser`; UI pins that corrected core exactly. UI 0.37.0 adds the Viewer-owned document-header seam (a new public API, hence the minor bump; 0.36.1 was reserved for it but never published) while retaining the `hideQuickLabel` and `StickyHeaderLane` seams from the 0.35.x and 0.36.0 releases.
- Recent pairs, for the consumer's install matrix: ui 0.32.0 on core 0.25.0 (lockstep, `html-anchor`), ui 0.33.0 and ui 0.34.0 on core 0.25.0 (ui only), and ui 0.35.2, ui 0.36.0, and ui 0.37.0 on core 0.25.1 (0.36.1 was never published). Do not consume ui 0.35.0 externally because its published manifest contains `workspace:*`; do not consume ui 0.35.1 because its exact core 0.25.0 dependency lacks the `annotation-threads` export.
- The current pair is `@plannotator/ui` `0.38.0` on `@plannotator/core` `0.25.1`. UI 0.38.0 adds only internal decision-control primitives (`DecisionControl`, `decisionSpec`, `useDismissablePopover` — not host-supported surface, see the unsupported list). UI 0.37.0 added the Viewer-owned document-header seam (a new public API, hence the minor bump; 0.36.1 was reserved for it but never published) while retaining the `hideQuickLabel` and `StickyHeaderLane` seams from the 0.35.x and 0.36.0 releases; core 0.25.1 publishes the `annotation-threads` subpath already used by `AnnotationPanel` and `utils/parser`, and UI pins that corrected core exactly.
- Recent pairs, for the consumer's install matrix: ui 0.32.0 on core 0.25.0 (lockstep, `html-anchor`), ui 0.33.0 and ui 0.34.0 on core 0.25.0 (ui only), and ui 0.35.2, ui 0.36.0, ui 0.37.0, and ui 0.38.0 on core 0.25.1 (0.36.1 was never published). Do not consume ui 0.35.0 externally because its published manifest contains `workspace:*`; do not consume ui 0.35.1 because its exact core 0.25.0 dependency lacks the `annotation-threads` export.
- When both packages change, **publish `core` first**: ui 0.32.0 imports the `@plannotator/core/html-anchor` subpath, which no earlier published core (0.24.0 and before) has, just as ui 0.29.0 needed core 0.23.0 for `@plannotator/core/annotatable`. Bump core, update UI's exact core dependency to the same new version, and run `bun install` so `bun.lock` records the new workspace versions before packing either package.
- The HTML annotation seams also changed the guides.show viewer **stylesheet** (five utility rules from `HtmlSurfaceControls`; the viewer JS is unchanged), so `packages/core/guide-viewer-manifest.ts` now pins a CSS hash that exists on guides.show only after the deploy workflow has published this build's `/v1/` assets. A guide exported from this build before that deploy would pin a stylesheet the host does not serve yet: **deploy guides.show before any release that ships this manifest.**
- UI declares the already published core version exactly in its source manifest. Do not replace it with `workspace:*`: direct publication can preserve that protocol and make the package impossible to install outside this repository. Bun links the local core workspace whenever its version matches the exact dependency. Before publishing, run `bun run --cwd packages/ui smoke:package`; it checks the source and packed manifests, required tarball subpaths, local Bun linking, and a real pnpm install in an external temporary consumer. When both packages change, publish **`core` first, then `ui`**.
Expand Down
2 changes: 1 addition & 1 deletion packages/ui/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ npm install @plannotator/ui @plannotator/core
- `@plannotator/core` — pure utils + types, zero deps, browser-safe (CI enforces no `node:` imports). Published.
- `@plannotator/ui` — React components/hooks + theme + `configure()`. Depends on an exact published `@plannotator/core` version. Published.
- `@plannotator/shared`, `@plannotator/ai` — stay private to the monorepo; `shared` re-exports `core`'s modules via shims so Plannotator's internals are untouched.
- Currently `@plannotator/ui` 0.37.0 depends exactly on `@plannotator/core` 0.25.1. `core` is bumped only when something under `packages/core` changes, so `ui` can advance alone. Keep the published core version exact in `packages/ui/package.json`; do not use a `workspace:` protocol there, because a directly published manifest must remain installable outside this monorepo. Bun still links the matching local workspace during development. When both packages change, publish `core` first, then build and publish the UI tarball. See HANDOFF.md "Publishing & versioning" for the verification command.
- Currently `@plannotator/ui` 0.38.0 depends exactly on `@plannotator/core` 0.25.1. `core` is bumped only when something under `packages/core` changes, so `ui` can advance alone. Keep the published core version exact in `packages/ui/package.json`; do not use a `workspace:` protocol there, because a directly published manifest must remain installable outside this monorepo. Bun still links the matching local workspace during development. When both packages change, publish `core` first, then build and publish the UI tarball. See HANDOFF.md "Publishing & versioning" for the verification command.

## The one rule

Expand Down
11 changes: 10 additions & 1 deletion packages/ui/components/ActionMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,12 @@ interface ActionMenuItemProps {
subtitle?: string;
badge?: React.ReactNode;
disabled?: boolean;
/** ARIA menu semantics for hosts that render a real `role="menu"` popover
* (DecisionControl). Default undefined so existing consumers are unchanged. */
role?: 'menuitem';
/** Appended to the row's classes (e.g. a tone token). Default undefined so
* existing consumers are byte-identical. */
className?: string;
}

export const ActionMenuItem: React.FC<ActionMenuItemProps> = ({
Expand All @@ -78,13 +84,16 @@ export const ActionMenuItem: React.FC<ActionMenuItemProps> = ({
subtitle,
badge,
disabled = false,
role,
className,
}) => (
<button
data-pn-touch-target
type="button"
onClick={onClick}
disabled={disabled}
className="flex w-full items-center gap-2 px-3 py-2 text-left text-xs transition-colors hover:bg-muted disabled:cursor-not-allowed disabled:opacity-45 disabled:hover:bg-transparent"
role={role}
className={`flex w-full items-center gap-2 px-3 py-2 text-left text-xs transition-colors hover:bg-muted disabled:cursor-not-allowed disabled:opacity-45 disabled:hover:bg-transparent${className ? ` ${className}` : ''}`}
>
<span className="text-muted-foreground">{icon}</span>
{subtitle ? (
Expand Down
Loading