From 32ea3f51c10410f6185bef21421799ccc49ef236 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 14 Jul 2026 15:00:43 +0000 Subject: [PATCH] chore: release packages --- .changeset/action-param-visible.md | 13 - .changeset/adr-0037-mobile-live-canvas.md | 20 - .changeset/adr-0057-chatdock-default-on.md | 12 - .changeset/adr-0057-dock-polish.md | 13 - .changeset/adr-0057-final-cleanup.md | 27 - .changeset/adr-0057-mobile-fullpage-bridge.md | 22 - .changeset/adr-0057-p3-followups.md | 16 - .changeset/adr-0057-p3a-chatdock.md | 28 -- .changeset/adr-0057-p3b-fab-launcher.md | 13 - .changeset/adr-0057-p3c-maximized-dock.md | 24 - .changeset/adr-0057-p4-handoff-context.md | 29 -- .changeset/adr-0057-p4-handoff-reliability.md | 26 - .changeset/adr-0057-p4-open-in-builder.md | 26 - .changeset/adr-0057-studio-dock-ux.md | 17 - .changeset/adr-0089-visible-when-renderer.md | 15 - .changeset/ask-decline-pending-indicator.md | 9 - .changeset/cloud-816-capability-rendering.md | 22 - .changeset/console-ai-ux-batch.md | 23 - .changeset/console-chat-conversation-key.md | 30 -- .changeset/console-surface-agent-resolver.md | 30 -- ...xport-filename-and-import-template-i18n.md | 14 - .../fix-2450-resume-handoff-autosend.md | 28 -- .changeset/fix-build-card-mobile-overflow.md | 14 - .../form-widget-hint-section-fallback.md | 13 - .changeset/gantt-api-data-source.md | 17 - .changeset/gantt-border-color-field.md | 9 - .changeset/gantt-dependency-guards.md | 11 - .changeset/gantt-drawer-lock.md | 9 - .changeset/gantt-tree-aware-filter.md | 8 - .changeset/gantt-write-readback-refresh.md | 8 - .changeset/list-search-keyword-chip.md | 11 - .../metadata-client-authenticated-fetch.md | 28 -- .changeset/permission-set-reset-copy.md | 7 - .changeset/phone-password-login.md | 26 - .changeset/plenty-cities-worry.md | 5 - .changeset/profile-card-i18n.md | 32 -- .changeset/resolve-action-param-visible.md | 15 - .changeset/sharing-rule-form-pickers.md | 32 -- apps/console/CHANGELOG.md | 57 +++ apps/console/package.json | 2 +- packages/app-shell/CHANGELOG.md | 475 ++++++++++++++++++ packages/app-shell/package.json | 2 +- packages/auth/CHANGELOG.md | 32 ++ packages/auth/package.json | 2 +- packages/cli/CHANGELOG.md | 11 + packages/cli/package.json | 2 +- packages/collaboration/CHANGELOG.md | 8 + packages/collaboration/package.json | 2 +- packages/components/CHANGELOG.md | 54 ++ packages/components/package.json | 2 +- packages/core/CHANGELOG.md | 22 + packages/core/package.json | 2 +- packages/create-plugin/CHANGELOG.md | 2 + packages/create-plugin/package.json | 2 +- packages/data-objectstack/CHANGELOG.md | 39 ++ packages/data-objectstack/package.json | 2 +- packages/fields/CHANGELOG.md | 46 ++ packages/fields/package.json | 2 +- packages/i18n/CHANGELOG.md | 51 ++ packages/i18n/package.json | 2 +- packages/layout/CHANGELOG.md | 40 ++ packages/layout/package.json | 2 +- packages/mobile/CHANGELOG.md | 8 + packages/mobile/package.json | 2 +- packages/permissions/CHANGELOG.md | 8 + packages/permissions/package.json | 2 +- packages/plugin-ai/CHANGELOG.md | 14 + packages/plugin-ai/package.json | 2 +- packages/plugin-calendar/CHANGELOG.md | 21 + packages/plugin-calendar/package.json | 2 +- packages/plugin-charts/CHANGELOG.md | 17 + packages/plugin-charts/package.json | 2 +- packages/plugin-chatbot/CHANGELOG.md | 139 +++++ packages/plugin-chatbot/package.json | 2 +- packages/plugin-dashboard/CHANGELOG.md | 18 + packages/plugin-dashboard/package.json | 2 +- packages/plugin-designer/CHANGELOG.md | 21 + packages/plugin-designer/package.json | 2 +- packages/plugin-detail/CHANGELOG.md | 49 ++ packages/plugin-detail/package.json | 2 +- packages/plugin-editor/CHANGELOG.md | 14 + packages/plugin-editor/package.json | 2 +- packages/plugin-form/CHANGELOG.md | 19 + packages/plugin-form/package.json | 2 +- packages/plugin-gantt/CHANGELOG.md | 60 +++ packages/plugin-gantt/package.json | 2 +- packages/plugin-grid/CHANGELOG.md | 25 + packages/plugin-grid/package.json | 2 +- packages/plugin-kanban/CHANGELOG.md | 20 + packages/plugin-kanban/package.json | 2 +- packages/plugin-list/CHANGELOG.md | 33 ++ packages/plugin-list/package.json | 2 +- packages/plugin-map/CHANGELOG.md | 14 + packages/plugin-map/package.json | 2 +- packages/plugin-markdown/CHANGELOG.md | 14 + packages/plugin-markdown/package.json | 2 +- packages/plugin-report/CHANGELOG.md | 19 + packages/plugin-report/package.json | 2 +- packages/plugin-timeline/CHANGELOG.md | 15 + packages/plugin-timeline/package.json | 2 +- packages/plugin-tree/CHANGELOG.md | 39 ++ packages/plugin-tree/package.json | 2 +- packages/plugin-view/CHANGELOG.md | 25 + packages/plugin-view/package.json | 2 +- packages/providers/CHANGELOG.md | 8 + packages/providers/package.json | 2 +- packages/react-runtime/CHANGELOG.md | 2 + packages/react-runtime/package.json | 2 +- packages/react/CHANGELOG.md | 28 ++ packages/react/package.json | 2 +- packages/runner/CHANGELOG.md | 16 + packages/runner/package.json | 2 +- packages/sdui-parser/CHANGELOG.md | 2 + packages/sdui-parser/package.json | 2 +- packages/tenant/CHANGELOG.md | 8 + packages/tenant/package.json | 2 +- packages/types/CHANGELOG.md | 41 ++ packages/types/package.json | 2 +- packages/vscode-extension/CHANGELOG.md | 11 + packages/vscode-extension/package.json | 2 +- 120 files changed, 1586 insertions(+), 743 deletions(-) delete mode 100644 .changeset/action-param-visible.md delete mode 100644 .changeset/adr-0037-mobile-live-canvas.md delete mode 100644 .changeset/adr-0057-chatdock-default-on.md delete mode 100644 .changeset/adr-0057-dock-polish.md delete mode 100644 .changeset/adr-0057-final-cleanup.md delete mode 100644 .changeset/adr-0057-mobile-fullpage-bridge.md delete mode 100644 .changeset/adr-0057-p3-followups.md delete mode 100644 .changeset/adr-0057-p3a-chatdock.md delete mode 100644 .changeset/adr-0057-p3b-fab-launcher.md delete mode 100644 .changeset/adr-0057-p3c-maximized-dock.md delete mode 100644 .changeset/adr-0057-p4-handoff-context.md delete mode 100644 .changeset/adr-0057-p4-handoff-reliability.md delete mode 100644 .changeset/adr-0057-p4-open-in-builder.md delete mode 100644 .changeset/adr-0057-studio-dock-ux.md delete mode 100644 .changeset/adr-0089-visible-when-renderer.md delete mode 100644 .changeset/ask-decline-pending-indicator.md delete mode 100644 .changeset/cloud-816-capability-rendering.md delete mode 100644 .changeset/console-ai-ux-batch.md delete mode 100644 .changeset/console-chat-conversation-key.md delete mode 100644 .changeset/console-surface-agent-resolver.md delete mode 100644 .changeset/export-filename-and-import-template-i18n.md delete mode 100644 .changeset/fix-2450-resume-handoff-autosend.md delete mode 100644 .changeset/fix-build-card-mobile-overflow.md delete mode 100644 .changeset/form-widget-hint-section-fallback.md delete mode 100644 .changeset/gantt-api-data-source.md delete mode 100644 .changeset/gantt-border-color-field.md delete mode 100644 .changeset/gantt-dependency-guards.md delete mode 100644 .changeset/gantt-drawer-lock.md delete mode 100644 .changeset/gantt-tree-aware-filter.md delete mode 100644 .changeset/gantt-write-readback-refresh.md delete mode 100644 .changeset/list-search-keyword-chip.md delete mode 100644 .changeset/metadata-client-authenticated-fetch.md delete mode 100644 .changeset/permission-set-reset-copy.md delete mode 100644 .changeset/phone-password-login.md delete mode 100644 .changeset/plenty-cities-worry.md delete mode 100644 .changeset/profile-card-i18n.md delete mode 100644 .changeset/resolve-action-param-visible.md delete mode 100644 .changeset/sharing-rule-form-pickers.md diff --git a/.changeset/action-param-visible.md b/.changeset/action-param-visible.md deleted file mode 100644 index 7c61fb6cd..000000000 --- a/.changeset/action-param-visible.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -"@object-ui/core": patch -"@object-ui/app-shell": patch ---- - -Action params support a `visible` CEL predicate — the param dialog omits a param -when it evaluates false, against the same scope as action `visible` (features / -user / app / data). Fixes the create-user form offering a **Phone Number** field -the default backend rejects ("Phone numbers require the phoneNumber auth plugin"): -paired with the framework gating that param on `features.phoneNumber`, the form -now follows the plugin — no phone field unless the opt-in phoneNumber auth plugin -is loaded. `filterVisibleParams` is exported + unit-tested (feature-off hides, -feature-on shows, malformed predicate fails open). diff --git a/.changeset/adr-0037-mobile-live-canvas.md b/.changeset/adr-0037-mobile-live-canvas.md deleted file mode 100644 index 188eadf5a..000000000 --- a/.changeset/adr-0037-mobile-live-canvas.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -"@object-ui/app-shell": patch -"@object-ui/i18n": patch ---- - -fix(console-ai): Live Canvas is a full-screen, opt-in preview on mobile — not a broken split (#2481) - -On a phone the beside-chat Live Canvas split overflowed the viewport (the chat -column's fixed min-width plus the preview exceeded the screen, and the resize -handle is desktop-only, so it was stuck clipped). Under `md` the canvas is now: - -- **Full-width chat, no split** — the build streams in the chat as before. -- **Opt-in + full-screen** — when the preview is available a floating "Preview - app" pill appears; tapping it (or a Preview button on a draft card) takes the - canvas full-screen over the chat. Closing returns to the chat with the - preview one tap away. The auto-drafted canvas never covers the streaming - chat unprompted. - -Desktop is unchanged (the resizable beside-chat split). Adds the -`console.ai.previewApp` string (en/zh). diff --git a/.changeset/adr-0057-chatdock-default-on.md b/.changeset/adr-0057-chatdock-default-on.md deleted file mode 100644 index c6b25c93c..000000000 --- a/.changeset/adr-0057-chatdock-default-on.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -"@object-ui/app-shell": patch ---- - -feat(console-ai): the ChatDock is now DEFAULT ON (ADR-0057 P3 go-live) - -`features.chatDock` flips from opt-in to opt-out: the right-docked chat rail -(FAB as launcher, `/ai` as the panel maximized, Studio right dock with center -`[Canvas | Properties]` tabs) is the console's default chat presentation. The -flag survives only as a server-side kill-switch — an operator sending -`chatDock: false` restores the floating-overlay console until the final -cleanup removes that path (epic #2409). diff --git a/.changeset/adr-0057-dock-polish.md b/.changeset/adr-0057-dock-polish.md deleted file mode 100644 index 8aa61aa1a..000000000 --- a/.changeset/adr-0057-dock-polish.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -"@object-ui/app-shell": patch ---- - -polish(console-ai): ease the dock's canvas auto-maximize, and give Studio its own chat width (ADR-0057 UX follow-ups, #2477) - -- **#4** The rail now eases to its new width (200ms) when the Live Canvas opens - (auto-maximize) or closes (tuck), instead of snapping. The transition is - suppressed during a manual resize drag so the width still tracks the pointer - 1:1. -- **#6** The Studio dock persists its width under its own key, separate from the - console dock. A wide console chat no longer squeezes the Studio design canvas - (and vice-versa) — each surface remembers the width that suits it. diff --git a/.changeset/adr-0057-final-cleanup.md b/.changeset/adr-0057-final-cleanup.md deleted file mode 100644 index 1b27b25fc..000000000 --- a/.changeset/adr-0057-final-cleanup.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -"@object-ui/app-shell": patch ---- - -refactor(console-ai)!: ADR-0057 final cleanup — remove the chatDock flag, the floating-overlay console chat, and the legacy left Studio copilot - -The docked chat is now the console's ONE chat presentation, unconditionally: - -- `features.chatDock` is removed from the runtime config (it had already - flipped to default-on; the kill-switch is retired with the code path it - guarded). -- `ConsoleFloatingChatbot` (the FAB-armed floating overlay) and its - `agentPicker` helper are deleted; `ConsoleChatbotFab` is now a small - dependency-free launcher (`{ appLabel, onOpenDock }`) that opens the dock — - including on `/home`, where it opens the full-page `/ai` surface (the dock - maximized) since Home has no shell to host a rail. -- The legacy left `StudioAiCopilot` panel is deleted; the Studio copilot's one - home is the right `StudioChatDock`. The ADR-0080 `aiSlot` injection seam is - untouched. -- The runtime SDUI `type: 'chatbot'` bubble (end-user apps) is unchanged - (ADR-0057 §4). -- Fix: the mobile chat sheet no longer shows a "maximize" button. At 85svh the - sheet is already the maximal mobile chat, and navigating to full-page `/ai` - from an OPEN Radix sheet tore it down mid-close (the route change unmounts - the console synchronously, so the scroll-lock/overlay never released and the - destination landed blank-and-frozen — "tap maximize → the chat's just gone"). - Full-page `/ai` stays reachable via normal navigation. diff --git a/.changeset/adr-0057-mobile-fullpage-bridge.md b/.changeset/adr-0057-mobile-fullpage-bridge.md deleted file mode 100644 index a54898a61..000000000 --- a/.changeset/adr-0057-mobile-fullpage-bridge.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -"@object-ui/app-shell": patch ---- - -feat(console-ai): mobile chat sheet bridges to full-page /ai (conversation history + share) — cleanly (ADR-0057 UX #2477 item 1) - -The mobile chat bottom sheet gets a maximize button back — it opens the -full-page `/ai`, which on mobile already carries the conversation-history -sidebar and share, so the sheet doesn't need a second copy of either. This is -the missing mobile path to switch/resume threads. - -The button navigates **deferred**: an earlier cut jumped straight from the -click and tore the still-open Radix sheet down mid-close (the route change -unmounts the console synchronously, leaking the sheet's scroll-lock/overlay -onto the destination — "tap maximize → the chat's just gone"). Now the click -only closes the sheet; a `useEffect` fires the navigation once `open` has -flipped false — after Radix released the body on that commit and before the -sheet unmounts — so `/ai` lands clean. Applies to both the console sheet -(→ `/ai`) and the Studio copilot sheet (→ `/ai/build?package=…`, same thread). - -Live Canvas on mobile `/ai` (the beside-chat split has no room on a phone) is -tracked separately (#2481). diff --git a/.changeset/adr-0057-p3-followups.md b/.changeset/adr-0057-p3-followups.md deleted file mode 100644 index 29942a0fd..000000000 --- a/.changeset/adr-0057-p3-followups.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -"@object-ui/app-shell": patch ---- - -feat(console-ai): ChatDock follow-ups — mobile sheet, wide side-by-side properties, exact collapse landing (ADR-0057 P3) - -- Under `md` the dock presents as a bottom sheet (`ChatDockMobileSheet`) — - console FAB opens it; Studio gets a mobile-visible edge launcher. -- The folded Studio layout keeps canvas AND properties side by side on 2xl+ - viewports; tabs (and their auto-switch) only exist where width forces them. -- Folded tabs mode flattens the source page's nested Source/Props tabs — the - Properties tab body is the code editor directly. -- Maximize remembers its origin, so `/ai`'s collapse-to-dock returns to the - exact page (console or Studio) the user left, immune to history churn. -- The dock's conversation honors `app.defaultAgent` via the one resolver, - matching the FAB's behavior. diff --git a/.changeset/adr-0057-p3a-chatdock.md b/.changeset/adr-0057-p3a-chatdock.md deleted file mode 100644 index 8257c7e4f..000000000 --- a/.changeset/adr-0057-p3a-chatdock.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -"@object-ui/app-shell": minor -"@object-ui/layout": minor ---- - -feat(console-ai): ChatDock — right-docked AI rail behind a default-off flag (ADR-0057 P3a) - -Stands up the ADR-0057 P3 docked rail as an ADDITIVE, DEFAULT-OFF shell: until an -operator sets `features.chatDock`, nothing changes and the FAB stays the -canonical entry. - -- `@object-ui/layout`: `AppShell` gains an optional `rightRail` prop, rendered as - a flex sibling of the main content so the rail REFLOWS the content beside it - (VS Code / Cursor idiom), not overlaying it. Absent → unchanged single-pane. -- `@object-ui/app-shell`: new `ChatDock` — a collapsible, resizable right rail - that reuses the shared `ChatPane` engine over the P1 `(user, app, product=ask)` - conversation (the same ambient thread the FAB/`/ai` shows; it's a VIEW, not a - new conversation). Default COLLAPSED (a fixed edge launcher → zero layout cost - until invoked); ⌘/Ctrl+Shift+I toggles it. Gated on `useAiSurfaceEnabled` AND - the flag, so OSS / no-seat runtimes render nothing. -- `runtime-config`: `chatDock?` rollout flag, parsed default-OFF (opt-in only). - -Live-verified with the flag forced on: the launcher expands to a rail rendering -the ask chat, the dashboard content reflows narrower beside it, and collapse -restores the launcher. Unit-tested: width clamp, the composer-safe shortcut -matcher (⌘⇧I, no collision with the ⌘⇧O/S page shortcuts), and the flag's -default-off/opt-in parse. FAB retirement (P3b) and `/ai`-as-maximized-dock + -Studio reflow (P3c) follow. diff --git a/.changeset/adr-0057-p3b-fab-launcher.md b/.changeset/adr-0057-p3b-fab-launcher.md deleted file mode 100644 index 810df0749..000000000 --- a/.changeset/adr-0057-p3b-fab-launcher.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -"@object-ui/app-shell": patch ---- - -feat(console-ai): the FAB becomes the ChatDock launcher when the dock is on (ADR-0057 P3b) - -When `features.chatDock` is enabled, the console FAB opens the docked rail instead -of the floating overlay — one entry point, the ADR's "FAB → launcher" step. In -dock mode the FAB stays the lightweight button (it never mounts the heavy floating -chatbot; the rail loads the chat on demand), and a designer "Ask AI" open signal -(assistantBus) opens the dock too. With the flag OFF the FAB is unchanged (floating -overlay). Supersedes P3a's edge launcher (the dock is gated on the same -`showChatbot`, so the FAB is always present to launch it). diff --git a/.changeset/adr-0057-p3c-maximized-dock.md b/.changeset/adr-0057-p3c-maximized-dock.md deleted file mode 100644 index b380a31b1..000000000 --- a/.changeset/adr-0057-p3c-maximized-dock.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -"@object-ui/app-shell": patch ---- - -feat(console-ai): /ai = the ChatDock maximized + Studio right-dock reflow (ADR-0057 P3c) - -The final P3 slice, all behind the default-off `features.chatDock` flag: - -- **/ai ⇄ rail continuity**: the dock header gains a maximize button that opens - the full-page `/ai` surface, and the `/ai` page gains a collapse-to-dock button - that returns to the console with the rail expanded — same thread both ways - (the P1 `(user, app, product)` conversation key). Deep links - (`/ai/:agent/:conversationId`, ADR-0013) are untouched and keep working. -- **Studio reflow** (the ADR's decided grid `[left: nav/tree] [center: canvas + - properties] [right: chat]`): the AI copilot leaves the left `w-96` panel and - renders as the shared right dock (`ChatDockPanel` + `ChatDockLauncher`), same - package-scoped build thread; the Interfaces pillar's right inspector folds - into center `[Canvas | Properties]` tabs with select-a-block auto-switch. An - injected `aiSlot` (cloud seam, ADR-0080) keeps the legacy left panel. -- **Live Canvas** (ADR-0037): in the rail, the dock auto-maximizes while the - canvas is open and tucks back on close (manual resize wins); maximized (`/ai`) - keeps the existing beside-the-chat split. - -With the flag OFF, `/ai` and Studio are pixel-identical to before. diff --git a/.changeset/adr-0057-p4-handoff-context.md b/.changeset/adr-0057-p4-handoff-context.md deleted file mode 100644 index fb8579ddf..000000000 --- a/.changeset/adr-0057-p4-handoff-context.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -"@object-ui/plugin-chatbot": minor -"@object-ui/app-shell": minor ---- - -feat(console-ai): ask→build handoff carries conversation context (ADR-0057 P4 / cloud#817) - -The P4 "Open in Builder →" handoff previously carried only the build prompt + an -optional package, so the Builder started cold and the user re-explained -themselves. It now also carries the **source `ask` conversation** as context — -ADR-0057 P4 / cloud#817 — so the build agent's first turn starts with the thread -the user already had. - -- `@object-ui/app-shell`: both handoff sites (the full-page `AiChatPage` and the - console FAB) now append `?parentConversationId=` to the - `/ai/build` URL. The build surface reads it and forwards it to `useObjectChat`; - the existing URL-mirror drops it once the build conversation id is minted, so a - reload never re-carries it. -- `@object-ui/plugin-chatbot`: `useObjectChat` accepts `parentConversationId` and - sends it as `context.parentConversationId` on the **first turn only** (held in a - ref, consumed once) — the backend redeems it into the turn's context and the - client owns history from there. New pure helper `withHandoffContext` (unit - tested) does the non-mutating `context` merge. - -Requires the cloud handoff-context contract (service-ai, cloud#817): the build -agent redeems `context.parentConversationId` into a single system block on its -first turn — ownership-checked, and carrying only the user/assistant text the -user already saw (ADR-0063 governance boundary). Without it the console degrades -cleanly: the id is sent but ignored, and the handoff is a (working) cold start. diff --git a/.changeset/adr-0057-p4-handoff-reliability.md b/.changeset/adr-0057-p4-handoff-reliability.md deleted file mode 100644 index a8ad57481..000000000 --- a/.changeset/adr-0057-p4-handoff-reliability.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -"@object-ui/plugin-chatbot": patch -"@object-ui/app-shell": patch ---- - -fix(console-ai): reliable ask→build handoff auto-send + second-handoff context re-carry (ADR-0057 P4) - -Two follow-ups to the P4 "Open in Builder →" handoff: - -- **Auto-send swallow.** The handoff's auto-sent first message could be dropped on - a brand-new build conversation: the seed gated on the async-resolved - `activeAgent`, which can settle *after* the conversation id is minted, so the - deferred-send replay ran with an empty pending and never re-fired. The seed now - gates on the **route** (`agentSegment`, synchronous) and bumps a `pendingSignal` - that `useDeferredFirstSend` lists in its replay deps, so the seed always fires — - no more empty build conversation on handoff. - -- **Second-handoff re-carry.** A second "Open in Builder →" into the (singleton) - build conversation now re-carries the latest ask context. The transport re-arms - `parentConversationId` on each falsy→truthy transition of the prop (the ask - thread is a singleton, so the same id repeats — the fresh-arrival signal is the - transition the URL-mirror produces, not a changed value), and the seed re-arms - on each new `handoffPrompt`. - -Unit-tested: deferred-send replays a post-id seed via the signal; the transport -re-carries across a strip→re-supply cycle. diff --git a/.changeset/adr-0057-p4-open-in-builder.md b/.changeset/adr-0057-p4-open-in-builder.md deleted file mode 100644 index 06a06f60f..000000000 --- a/.changeset/adr-0057-p4-open-in-builder.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -"@object-ui/plugin-chatbot": minor -"@object-ui/app-shell": minor ---- - -feat(console-ai): explicit "Open in Builder →" ask→build handoff (ADR-0057 P4) - -When the `ask` agent declines an app-authoring request it now calls the cloud -`suggest_builder` tool (structured decline). The console renders that as an -explicit **"Open in Builder →"** action that opens the full-page build surface -seeded with the handoff prompt — ADR-0063 decline-and-redirect: an explicit, -user-initiated switch, never a silent re-route into authoring. - -- `@object-ui/plugin-chatbot`: `detectBuilderHandoff` lifts the - `{ status:'build_handoff', prompt, packageId? }` result onto the tool - invocation; `ChatbotEnhanced` renders the "Open in Builder →" card and calls a - new `onOpenBuilder` prop (disabled when no host wires it). -- `@object-ui/app-shell`: the full-page `AiChatPage` (`ask`) and the console FAB - wire `onOpenBuilder` to navigate to `/ai/build?package=…&handoffPrompt=…`; the - build surface seeds that prompt as its first message (auto-sent once the - conversation is minted), and the URL-mirror strips `?handoffPrompt` so a reload - never re-sends it. Full ask-conversation context transfer is a later upgrade - (cloud#817); v1 carries the build prompt + optional package. - -Requires the cloud `suggest_builder` signal (service-ai-studio) to light up; the -console degrades cleanly (no card) without it. diff --git a/.changeset/adr-0057-studio-dock-ux.md b/.changeset/adr-0057-studio-dock-ux.md deleted file mode 100644 index 97bc878eb..000000000 --- a/.changeset/adr-0057-studio-dock-ux.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -"@object-ui/app-shell": patch ---- - -fix(console-ai): Studio dock remembers a collapse; folded canvas+properties go side-by-side at `xl` (ADR-0057 UX follow-ups, #2477) - -- **Studio dock collapse is now remembered** (per-tab). The right copilot still - mounts expanded by default, but collapsing it to get the classic three-zone - canvas no longer re-opens on every pillar / package switch or Studio - re-entry. Backed by an explicit `'0'`/`'1'` stored flag (a default-expanded - surface couldn't remember a collapse when "collapsed" meant "key removed"), - under a Studio-specific key so it never shares state with the console dock. -- **Folded layout shows canvas + properties side by side from `xl`** (1280), - lowered from `2xl`. On the common laptop the folded center used to fall into - tabs, which auto-hide the canvas the moment you select a block — breaking the - WYSIWYG "edit and watch it apply" loop. The side-by-side inspector is slimmer - at `xl` (and grows at `2xl`) so the canvas keeps usable width beside the dock. diff --git a/.changeset/adr-0089-visible-when-renderer.md b/.changeset/adr-0089-visible-when-renderer.md deleted file mode 100644 index d52b32485..000000000 --- a/.changeset/adr-0089-visible-when-renderer.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -"@object-ui/react": minor -"@object-ui/types": minor ---- - -ADR-0089: read the canonical `visibleWhen` conditional-visibility predicate in the form + page renderers. - -`@objectstack/spec` now unifies conditional visibility under a single canonical key, `visibleWhen`, and folds the deprecated `visibleOn` (view form) / `visibility` (page component) aliases into it at parse. This updates ObjectUI to read the canonical key: - -- **Page renderer** (`SchemaRenderer`) — evaluates `visibleWhen` first (show-when-truthy), then the deprecated `visibleOn` / `visibility` as a defensive read for raw / un-normalized metadata. `visibleWhen` is stripped from DOM props. -- **Spec→node bridges** — the page bridge maps a component's `visibleWhen ?? visibility` onto the node's canonical `visibleWhen`; the form-view bridge maps a field's `visibleWhen ?? visibleOn` onto the ObjectForm view-level predicate slot. -- **Form renderers** — the `@object-ui/react` `FormRenderer` prefers `visibleWhen` over the `visibleOn` alias. (`ObjectForm`/`form.tsx` already evaluated `visibleWhen`.) -- **Types** — the component base schema (`BaseSchema` / `base.zod`) gains the canonical `visibleWhen`; `visibleOn` is marked `@deprecated`. - -Fully back-compat: existing `visibleOn` / `visibility` metadata keeps working through the alias reads. diff --git a/.changeset/ask-decline-pending-indicator.md b/.changeset/ask-decline-pending-indicator.md deleted file mode 100644 index d01a112ad..000000000 --- a/.changeset/ask-decline-pending-indicator.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -"@object-ui/plugin-chatbot": patch ---- - -Make the ask-decline wait feel responsive: live thinking indicator + handoff card the moment `suggest_builder` lands (#2458 item 3). - -When the `ask` agent declines a build-shaped request, the ~20s before the "Open in Builder →" card is dominated by the LLM's time-to-tool-call. During that wait the chat could show dead air — a blank bubble, or the static "执行过程" activity note (a hydrated-history affordance) when the backend streamed a `(called …)` tool-call placeholder. - -`ChatbotEnhanced` now shows the existing live thinking indicator (`ThinkingDots`) whenever a streaming assistant turn has nothing visible yet — including whitespace-only content, a mid-stream `(called …)` placeholder, and hidden reasoning in `summary` mode. The static "执行过程" note is reserved for FINISHED (re-hydrated) tool-call-only turns (#772 preserved). The `builderHandoff` card already renders at `output-available` with no gate on the trailing prose, so it surfaces the instant the tool result arrives; the typing cursor now only paints beside real streaming prose (no lone cursor during the tool phase). diff --git a/.changeset/cloud-816-capability-rendering.md b/.changeset/cloud-816-capability-rendering.md deleted file mode 100644 index f50031bb4..000000000 --- a/.changeset/cloud-816-capability-rendering.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -"@object-ui/plugin-chatbot": minor -"@object-ui/app-shell": patch ---- - -feat(console-ai): render agent behavior by declared capability (cloud#816 / ADR-0057 "B+") - -`GET /api/v1/ai/agents` now serves per-agent `capabilities`; the console -consumes them instead of hard-coding `isBuildAgent(name)`: - -- `@object-ui/plugin-chatbot`: `AgentDescriptor.capabilities` (normalized from - the catalog) + new `agentHasCapability(agents, name, cap)` — declaration wins - when present; falls back to the legacy `isBuildAgent(name)` check when absent - (older server), so shipping order doesn't matter. -- `@object-ui/app-shell`: the build-doctor drawer + `showDebug` key off - `'debug'`, the FAB's resume-vs-fresh keys off `'resume'`, HomePage's - "Build with AI" availability keys off `'authoring'`. The ADR-0063 product-axis - sites (surface→agent resolver, conversation scope keying, picker availability) - intentionally stay name-based — capability describes RENDERED behavior, not - which product an agent is. - -A future skill-driven build variant now needs no console change. diff --git a/.changeset/console-ai-ux-batch.md b/.changeset/console-ai-ux-batch.md deleted file mode 100644 index 4c46ec5cd..000000000 --- a/.changeset/console-ai-ux-batch.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -"@object-ui/app-shell": minor -"@object-ui/plugin-chatbot": minor ---- - -feat(console-ai): package binding chip + inert handoff cards + honest send hint (#2458 / ADR-0057 A1.a) - -Three UX improvements from live magic-flow testing: - -- **A1.a — package binding chip** (`app-shell`): the build surface header shows - the package the conversation is bound to (`📦 `), or **"New app"** when - unbound — so the edit blast-radius is always visible (Claude-Code-shows-the-repo - idiom). The magic flow starts unbound and binds the moment its build mints a - package (`deriveBoundPackageId` reads `?package=` else the latest draft/handoff - result; unit-tested). -- **UX#5 — only the latest handoff card is actionable** (`plugin-chatbot`): when - a thread accumulates several "Open in Builder →" cards, only the newest stays - clickable; older (superseded) cards' buttons are disabled — derived from - message order, so it survives the navigation the button triggers and the pane - remount that follows. A stale prompt in an older card can't be re-fired. -- **UX#7 — honest send hint** (`plugin-chatbot`): the composer already sends on - plain Enter (Shift+Enter = newline); dropped the misleading `⌘` glyph from the - hint so it no longer implies Cmd+Enter. diff --git a/.changeset/console-chat-conversation-key.md b/.changeset/console-chat-conversation-key.md deleted file mode 100644 index 9cab4a6fb..000000000 --- a/.changeset/console-chat-conversation-key.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -"@object-ui/app-shell": patch ---- - -feat(console-ai): key AI chat conversations on `(user, app, product)`, not on surface (ADR-0057 P1) - -The console rendered AI chat through parallel shells that **forked the -conversation**: the Studio design copilot scoped its thread as -`studio:${packageId}:${agent}` while the full-page `/ai/build` focus view scoped -on the agent alone — so opening the *same app* in both showed an empty "Build -with AI" copilot beside an active full-page build thread (indistinguishable from -data loss). - -Per ADR-0057 (**surface = view · conversation = model · product = binding -axis**), conversations are now keyed on `(user, app, product)`: - -- New pure, unit-tested `chatConversationScope({ appId, product })` + - `chatProductOfAgent(name)` helper (`hooks/chatScope.ts`) is the single place - the scope key is formed. `product` is the ADR-0063 axis (`ask` | `build`), - derived from the resolved agent — never a per-surface choice. -- `StudioAiCopilot` and the full-page `AiChatPage` both resolve - `app:${packageId}:${product}` for a package-scoped surface (the Studio copilot - editing package X and the `/ai/build?package=X` "Edit with AI" focus view now - resume ONE shared thread). The legacy `studio:` surface prefix is dropped. -- A generic `/ai/:agent` visit with no `?package=` degrades to the product alone - (`build` / `ask`) — unchanged behaviour for that surface. - -Enablement stays on the single access-filtered agent-catalog gate -(`useAiSurfaceEnabled`, ADR-0068) — a seat-less user's empty catalog hides the -whole AI surface. No layout change. diff --git a/.changeset/console-surface-agent-resolver.md b/.changeset/console-surface-agent-resolver.md deleted file mode 100644 index 389c1ea43..000000000 --- a/.changeset/console-surface-agent-resolver.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -"@object-ui/app-shell": patch ---- - -feat(console-ai): one declarative surface→agent resolver (ADR-0057 P2) - -The console re-implemented the ADR-0063 surface→agent chain in ~5 places, each -spelled slightly differently — and `ConsoleLayout` carried an AI-Studio-off -downgrade special case that existed nowhere else. This collapses them into one -pure, unit-tested resolver so ADR-0063 (exactly two products `ask`/`build`, -bound by surface — no roster, no per-turn classifier) becomes a **structural** -guarantee. - -- New `hooks/surfaceAgent.ts`: `resolveSurfaceAgent(surface, { agents, - appDefaultAgent, aiStudioEnabled })` + `SURFACE_DEFAULT`. `app.defaultAgent` is - **bounded** to ask/build (alias-aware) — a withdrawn tenant custom agent is - rejected, not passed through, so no roster is representable (ADR-0057 open - question #4). The AI-Studio-off `build → ask` downgrade is folded in ONCE. -- `StudioAiCopilot` (studio-build → build) and the console FAB (`default` → ask) - resolve through it. The FAB keeps #771's "prefer build when the catalog unlocks - it and nothing pinned a product" by passing that as its default PRODUCT input — - so the resolver still owns bounding + the downgrade, which now also applies to - the #771 preference (closing the leak where an authoring-disabled deployment - could still open build). -- `ConsoleLayout`'s bespoke `!aiStudioEnabled && isBuildAgent(...)` downgrade is - deleted; it passes the raw `app.defaultAgent` and the resolver downgrades. - -Ships a unit table proving the ADR-0063 rows: Studio→build, other→ask, -AI-Studio-off downgrade, `app.defaultAgent` bounded (valid override wins, roster -rejected), alias-aware catalog resolution, empty catalog → inert (ADR-0025). diff --git a/.changeset/export-filename-and-import-template-i18n.md b/.changeset/export-filename-and-import-template-i18n.md deleted file mode 100644 index 48143296f..000000000 --- a/.changeset/export-filename-and-import-template-i18n.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -'@object-ui/core': patch -'@object-ui/plugin-grid': patch -'@object-ui/plugin-list': patch -'@object-ui/plugin-view': patch -'@object-ui/app-shell': patch -'@object-ui/i18n': patch ---- - -导出/导入模板的下载文件名与内容本地化。 - -**导出文件名**:CSV/Excel/JSON 导出下载不再是 `<对象名>.<扩展名>`(如 `contracts.csv`),改为「对象显示名-视图名-时间戳.扩展名」(如 `任务-In Progress-20260714-153045.xlsx`);`exportOptions.fileNamePrefix` 配置仍优先(且作为完整前缀,不再追加视图名)。视图名与对象名重复时自动省略;`@object-ui/core` 新增 `buildExportFileName(ext, { prefix, label, objectName, viewLabel }, now?)` 与 `sanitizeFileNameBase(raw)`,ObjectGrid 与 ListView 的所有导出路径(服务端流式与前端兜底)统一走它。app-shell/plugin-view 的 ObjectView 现将当前视图的显示标签写进传给 ListView 的 schema(`label`),使导出文件名能区分同一对象的不同保存视图。 - -**导入模板**:「下载模板」修复两处英文漏出——示例行的 select/多选取值改为优先取选项**显示标签**(如 `准备中`)而非 ASCII slug(`prepare`,服务端导入两者都接受);模板文件名本地化为 `{{object}}-导入模板.csv`(新增 i18n key `grid.import.templateFileName`,英文回退 `{{object}}-import-template.csv`)。 diff --git a/.changeset/fix-2450-resume-handoff-autosend.md b/.changeset/fix-2450-resume-handoff-autosend.md deleted file mode 100644 index 17ff19d18..000000000 --- a/.changeset/fix-2450-resume-handoff-autosend.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -"@object-ui/app-shell": patch ---- - -fix(console-ai): second handoff's auto-send no longer dies in the stale-scope pane (#2450) - -Mid ask→build transition, `useChatConversation` briefly still holds the OLD -scope's conversation id (the same stale window the URL-mirror already guards). -`` was fed that raw id, so a DOOMED pane (build chatApi + stale ask id, -about to remount) could mount — and the deferred first-send replay consumed the -handoff stash into it, where the send died with the unmount before reaching the -wire (observed live as "conversation resumes, zero `…/chat` POST"). - -Two-layer fix: - -- **Scope-gated pane feed (structural):** the page now hands `` a - conversation id/messages ONLY when `conversationScope === chatScope`. During - the stale window the pane mounts as `…:pending`, holds the stash, and replays - exactly once in the correctly-scoped pane — extending the existing URL-mirror - guard to the pane itself. -- **Targeted stash (defense-in-depth):** the handoff seed is stamped - `targetAgentRoute: 'build'`; `useDeferredFirstSend` refuses to consume a - targeted stash in a pane bound to another agent (untargeted user-typed sends - keep the legacy consume-anywhere behavior). - -Per product decision, a second handoff landing on a conversation with a -blueprint still Awaiting Approval just auto-sends — the build agent sees the -pending plan in context and decides merge/supersede itself. diff --git a/.changeset/fix-build-card-mobile-overflow.md b/.changeset/fix-build-card-mobile-overflow.md deleted file mode 100644 index 10027e971..000000000 --- a/.changeset/fix-build-card-mobile-overflow.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -"@object-ui/plugin-chatbot": patch ---- - -fix(plugin-chatbot): build-result summary truncates on mobile instead of overflowing (#2493) - -The draft-review card's summary line (`built N artifact(s) — …`) is a nowrap -`truncate` span, but its flex row lacked the `min-w-0` that lets `truncate` -actually bite — so on a phone the long summary expanded the chat column past -the viewport and the whole chat scrolled sideways. The span now gets -`min-w-0 flex-1` (truncating within the row) and the action row is `flex-wrap` -so its buttons drop to a new line on a narrow screen rather than forcing -horizontal scroll. Desktop is unchanged (there's room, so nothing wraps or -truncates). diff --git a/.changeset/form-widget-hint-section-fallback.md b/.changeset/form-widget-hint-section-fallback.md deleted file mode 100644 index 099a5f547..000000000 --- a/.changeset/form-widget-hint-section-fallback.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -"@object-ui/components": patch ---- - -Form fields honor their object-schema `widget` render hint on the field-group / -section layout path. `ObjectForm` renders objects that declare field groups -(e.g. `sys_sharing_rule`) via an auto-derived section layout that passed each -field's metadata through without hoisting its `widget` override to the top-level -form-field config, so a field with `widget: 'object-ref'` (or `filter-condition` -/ `recipient-picker`) degraded to its bare `type` input — an admin was asked to -hand-type an object name instead of picking it. The form renderer now falls back -to the field metadata's own `widget` when no top-level override is present, so -the pickers render on sectioned forms just as they do on flat ones. diff --git a/.changeset/gantt-api-data-source.md b/.changeset/gantt-api-data-source.md deleted file mode 100644 index 4b399e8d1..000000000 --- a/.changeset/gantt-api-data-source.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -"@object-ui/plugin-gantt": patch ---- - -ObjectGantt now supports the `api` data source for **both read and write-back**. -Previously `provider: 'api'` logged "API provider not yet implemented" and rendered -nothing, and every write-back (reschedule, dependency edit, delete, drawer -inline-edit) was hard-wired to the context ObjectQL `dataSource` + `objectName`, -so the api provider's `write` config was never used. - -All reads and writes now flow through a single adapter resolved by -`resolveDataSource(schema.data, dataSource)`: `object` → context DataSource -(unchanged), `api` → `ApiDataSource` (executes the `read`/`write` HttpRequest -config), `value` → in-memory `ValueDataSource`. A pure-api view needs no -`objectName` and no context `dataSource` prop. Object-backed views are behavior- -preserving. Lookup/master_detail quick-filter option domains still resolve from -the context object backend (they degrade to distinct in-row values when absent). diff --git a/.changeset/gantt-border-color-field.md b/.changeset/gantt-border-color-field.md deleted file mode 100644 index 4838fb511..000000000 --- a/.changeset/gantt-border-color-field.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -"@object-ui/plugin-gantt": patch ---- - -新增逐任务预警描边(#2436 第 3 项):视图配置 `borderColorField` 指向 -记录上的预警颜色字段(常为服务端计算的超期/临期字段),该行条形在保留 -原有填充色的同时,以该颜色描边并加 2px 光晕——任务条、里程碑菱形、 -汇总条均生效。语义色名(red/orange/…)映射为调色板 hex,其余 CSS 颜色 -原样透传;空值不描边。开启关键路径高亮时,关键路径样式在其标记行上优先。 diff --git a/.changeset/gantt-dependency-guards.md b/.changeset/gantt-dependency-guards.md deleted file mode 100644 index d176603c5..000000000 --- a/.changeset/gantt-dependency-guards.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -"@object-ui/plugin-gantt": patch ---- - -拖拽连线增加内建校验与宿主否决钩子(#2436 第 1、2 项)。落点为锁定行 -(`locked`)或分组行(`type: 'group'`)时,悬停不再高亮、松手不再创建; -成环依赖(直接回边、跨层级传递回边)基于**全量任务集**检测并拒绝——不受 -折叠子树导致可见连线缺边的影响。新增 `onBeforeDependencyCreate(source, -target, type)` 钩子,在内建校验通过后调用,返回 `false` 可否决本次连线 -(即 DHTMLX `onBeforeLinkAdd` / Syncfusion `actionBegin` 惯例)。 -`wouldCreateDependencyCycle` 从 `scheduling` 导出并单测覆盖。 diff --git a/.changeset/gantt-drawer-lock.md b/.changeset/gantt-drawer-lock.md deleted file mode 100644 index 910edc10b..000000000 --- a/.changeset/gantt-drawer-lock.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -"@object-ui/plugin-detail": patch -"@object-ui/plugin-gantt": patch ---- - -修复记录抽屉绕过甘特图行级锁定的问题(#2436 第 5 项)。 - -- `RecordDetailDrawer` 的编辑/删除能力现在由调用方是否传入 `onFieldSave` / `onDelete` 决定:两者都省略时抽屉严格只读(无内联编辑、无删除入口)。此前抽屉硬编码 `inlineEdit` 与 `showDelete: true`,并无条件向内层 DetailView 传包装函数,导致锁定记录仍可"编辑"(且改动静默丢失)。 -- `ObjectGantt` 对 `lockField` 锁定的行、以及全局 `readOnly` 的甘特图,不再向抽屉传入 `onFieldSave` / `onDelete`,与时间轴上禁止拖拽/调整的行为保持一致。 diff --git a/.changeset/gantt-tree-aware-filter.md b/.changeset/gantt-tree-aware-filter.md deleted file mode 100644 index 36ef9d0e9..000000000 --- a/.changeset/gantt-tree-aware-filter.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -"@object-ui/plugin-gantt": patch ---- - -快速筛选改为树感知(#2436 第 4 项):命中任务的**全部祖先链**一并保留。 -此前 `displayTasks` 是平铺过滤,项目/产品等分组行本身没有可筛字段值, -一筛就被丢掉,命中的子任务成孤儿、树结构被打散。现在祖先随命中下级 -自动保留、无命中下级时照常剔除,多分支命中共享祖先不重复。 diff --git a/.changeset/gantt-write-readback-refresh.md b/.changeset/gantt-write-readback-refresh.md deleted file mode 100644 index f8d831f26..000000000 --- a/.changeset/gantt-write-readback-refresh.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -"@object-ui/plugin-gantt": patch ---- - -甘特图写后回读 + 工具栏手动刷新按钮(#2436 第 6/7 项)。 - -- 拖拽改期、依赖增删、抽屉内联编辑、删除记录成功后,静默重新读取数据源,让服务端重算的字段(父级汇总、预警颜色、工期重算)刷新到图上;此前乐观补丁只保留客户端写入的字段,派生字段一直陈旧直到整页刷新。静默刷新不闪 loading、不卸载 GanttView(保留滚动/折叠状态),并发请求按序号防乱序覆盖;失败时保留屏上最后一份好数据。 -- GanttView 工具栏新增手动刷新按钮(`onRefresh` / `refreshing` props),object 数据源自动接线;内联 value 数据无可回读来源,不显示按钮。 diff --git a/.changeset/list-search-keyword-chip.md b/.changeset/list-search-keyword-chip.md deleted file mode 100644 index 5bd3223a3..000000000 --- a/.changeset/list-search-keyword-chip.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -"@object-ui/plugin-list": patch ---- - -The list toolbar search button now shows the active keyword inline (mirroring -the Sort button's count badge). Previously a search term restored from -localStorage after navigating away and back kept filtering the list while the -search popover stayed collapsed — the only cue was a slightly darker magnifier -icon, so users couldn't tell a keyword filter was still active. The keyword is -rendered (truncated at 8rem) next to the magnifier whenever a search is active, -and clicking it opens the popover pre-filled for editing or clearing. diff --git a/.changeset/metadata-client-authenticated-fetch.md b/.changeset/metadata-client-authenticated-fetch.md deleted file mode 100644 index f6e1dedf1..000000000 --- a/.changeset/metadata-client-authenticated-fetch.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -"@object-ui/app-shell": patch ---- - -fix(metadata-admin): authenticate console MetadataClient requests (Bearer token) - -Studio / metadata-admin surfaces issued `/api/v1/meta/*` requests (list types, -`?package=…` reads, `_drafts`, the `/meta` root) that came back `401 -unauthenticated` in the token-based console, while the runtime data adapter's -reads (`/meta/object|view|app`) succeeded — so the same page showed some -metadata requests failing and others working. - -Root cause: `useMetadataClient` and `MetadataProvider`'s draft-preview client -constructed `MetadataClient` without a `fetch`, so it fell back to the bare -`globalThis.fetch` and sent no `Authorization` header. The console -authenticates by a Bearer token in localStorage (`auth-session-token`) — there -is no session cookie — so those requests were unauthenticated. A same-origin -cookie deployment masks the bug, which is why it went unnoticed and regressed -twice. - -Both sites (and every future console surface) now construct through a single -`createConsoleMetadataClient` factory that bakes in `createAuthenticatedFetch` -(Bearer token + `X-Tenant-ID` + `Accept-Language`), matching the runtime data -adapter. This is additive for cookie deployments — `credentials` is untouched, -so a same-origin session cookie still flows. A -`metadata-client-auth.ratchet.test.ts` guard forbids a bare -`new MetadataClient(` elsewhere in app-shell so authentication can't silently -regress again. diff --git a/.changeset/permission-set-reset-copy.md b/.changeset/permission-set-reset-copy.md deleted file mode 100644 index 468abdc34..000000000 --- a/.changeset/permission-set-reset-copy.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"@object-ui/app-shell": patch ---- - -Say "reset to shipped baseline" instead of "delete" when removing a package-owned permission set (ADR-0094). - -Deleting a `sys_permission_set` row whose `managed_by === 'package'` doesn't remove it — the backend drops the environment customization overlay and resets the set to its shipped baseline, so the row stays in the list. The confirmation dialog and success toast now say so (with `resetPackageSetConfirm` / `resetPackageSetSuccess` i18n, en + zh), instead of promising an irreversible delete the user can see doesn't happen. Environment-authored sets keep the plain delete copy. The grid row-delete passes the record through so the check needs no extra fetch; the SDUI header delete falls back to a `findOne` lookup. diff --git a/.changeset/phone-password-login.md b/.changeset/phone-password-login.md deleted file mode 100644 index c619398b7..000000000 --- a/.changeset/phone-password-login.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -"@object-ui/auth": minor -"@object-ui/console": patch ---- - -feat(auth): phone number + password sign-in on the login page - -The login page's password mode now accepts an **email OR a phone number** as the -identifier and routes by shape — email → `/sign-in/email`, phone → -`/sign-in/phone-number` (better-auth phoneNumber plugin, framework#2780). It -coexists with the existing phone-OTP mode. - -- Gated on `features.phoneNumber` (phoneNumber plugin enabled). Unlike phone-OTP - it needs no SMS service, so it uses that coarser capability flag, not - `features.phoneNumberOtp`. When the flag is off the field stays email-only. -- New `AuthClient.signInWithPhonePassword(phoneNumber, password)` wired through - `AuthContext` / `AuthProvider` / `useAuth`. -- New `normalizePhoneIdentifier` / `looksLikePhoneIdentifier` helpers that mirror - the backend's `normalizePhoneNumber` exactly (strip `[\s\-().]`, validate - `^\+?[0-9]{6,15}$`, **no** forced E.164 / country code — the backend stores the - light-stripped form, so anything heavier would break the lookup). -- SSO stays email-only (a phone-shaped identifier no longer attempts domain - routing). - -Only works for accounts that have both a phone number and a password set; -phone-only accounts set a password on first OTP sign-in. diff --git a/.changeset/plenty-cities-worry.md b/.changeset/plenty-cities-worry.md deleted file mode 100644 index dc50496db..000000000 --- a/.changeset/plenty-cities-worry.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@object-ui/console": major ---- - -align with objectstack diff --git a/.changeset/profile-card-i18n.md b/.changeset/profile-card-i18n.md deleted file mode 100644 index c46663cf1..000000000 --- a/.changeset/profile-card-i18n.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -'@object-ui/console': patch -'@object-ui/i18n': patch -'@object-ui/app-shell': patch -'@object-ui/plugin-detail': patch -'@object-ui/plugin-tree': patch ---- - -i18n: translate the Profile page, honor inline i18n label objects under bare -base-language codes, and localize managed-by badges / record quick actions. - -- `pickLocalized` now upgrades a bare base language (`zh`) to any - region-qualified key sharing the base (`zh-CN`) — runtime language is - normalized to the base code while metadata authors write full BCP-47 tags, - so inline `{ en, 'zh-CN', ... }` label objects previously fell back to - English. -- ProfilePage (`account:profile_card` / `/system/profile`): every hardcoded - string — page title/subtitle, avatar Upload/Replace/Remove, Personal - Information card, Change/Set Password card — now goes through - `useObjectTranslation()` with `profile.*` keys (new namespace in all ten - locale bundles); the lazy-load fallback reuses `common.loading`. -- `ManagedByBadge` chips/tooltips (Config/System/Append-only/Identity) now - resolve through new `managedByBadge.*` keys with `{{provider}}` - interpolation. -- `record:quick_actions` resolves action labels via the - `objects.{object}._actions.{action}.label` convention plus `pickLocalized`, - so object action buttons (Change Password, Enable 2FA, …) localize. -- `record:details` / `record:related_list` / `record:alert` / `ObjectTree` - pass inline label objects through `pickLocalized`. -- Locale bundles: added `managedByBadge` namespace to all ten locales and - backfilled `list.inlineEditShort` / `inlineEditLabel` / - `recordEditingTitle` for ja/es/ko/de/fr/pt/ru/ar. diff --git a/.changeset/resolve-action-param-visible.md b/.changeset/resolve-action-param-visible.md deleted file mode 100644 index 0e29128fe..000000000 --- a/.changeset/resolve-action-param-visible.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -"@object-ui/app-shell": patch ---- - -fix(app-shell): propagate action-param `visible` predicate through resolveActionParams - -The create-user phone fix (#2406) gated the `phoneNumber` param with -`visible: 'features.phoneNumber == true'`, but `resolveActionParam` dropped -`visible` when flattening raw spec params into `ActionParamDef` — so -`ActionParamDialog`'s `filterVisibleParams` never saw the predicate and the -phone field kept rendering even with the phoneNumber auth plugin off. - -Propagate `visible` in all three resolve branches (inline / field-backed / -missing-field), unwrapping the spec's `{ dialect, source }` ExpressionInput -envelope to a plain CEL string. Completes the create-user phone fix end to end. diff --git a/.changeset/sharing-rule-form-pickers.md b/.changeset/sharing-rule-form-pickers.md deleted file mode 100644 index 49bd846ed..000000000 --- a/.changeset/sharing-rule-form-pickers.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -"@object-ui/fields": minor -"@object-ui/components": minor -"@object-ui/data-objectstack": minor -"@object-ui/types": minor ---- - -Sharing-rule form: pick, don't type. Three new widget-hint field components make -the generic object form render pickers where an admin previously had to type -machine data (driven by the framework `widget` hints on `sys_sharing_rule`; -generalizes the `capability-multiselect` pattern). All degrade to the underlying -`type` renderer when a widget is unregistered. - -- **`object-ref`** — choose a registered object by name (searchable `Combobox`), - backed by the new `DataSource.getObjects()` (`ObjectStackAdapter` lists code- - and DB-defined objects via `/api/v1/meta/object`), falling back to a - `sys_metadata` query. Stores the object's `name`. -- **`filter-condition`** — a visual criteria builder (`FilterBuilder`) scoped to - the fields of the object chosen in a sibling field (via `getObjectSchema`), - round-tripping the stored **MongoDB-style** FilterCondition JSON. Criteria the - builder can't represent (or invalid JSON) fall back to a raw-JSON editor, with - an always-available "Edit as JSON" toggle — nothing is hidden or lost. -- **`recipient-picker`** — a record picker whose target object follows a sibling - `recipient_type` (`user`→sys_user, `team`→sys_team, `business_unit`/ - `unit_and_subordinates`→sys_business_unit, `position`→sys_position), storing the - value the evaluator matches on (a record id, or the position **name**). Resets - the stored id when the type changes. - -Wiring: the three keys join `DATA_SOURCE_FIELD_TYPES` (form.tsx) so the form -threads `dataSource` + `dependentValues` to them, and `INLINE_EXCLUDED_FIELD_TYPES` -(they're authored in the record form, not a grid cell). `DataSource.getObjects()` -is optional on the interface; the ObjectStack adapter implements it. diff --git a/apps/console/CHANGELOG.md b/apps/console/CHANGELOG.md index 6af37c0a6..fb51c14ca 100644 --- a/apps/console/CHANGELOG.md +++ b/apps/console/CHANGELOG.md @@ -1,5 +1,62 @@ # @object-ui/console +## 14.0.0 + +### Major Changes + +- 2f3ab55: align with objectstack + +### Patch Changes + +- 94d00d4: feat(auth): phone number + password sign-in on the login page + + The login page's password mode now accepts an **email OR a phone number** as the + identifier and routes by shape — email → `/sign-in/email`, phone → + `/sign-in/phone-number` (better-auth phoneNumber plugin, framework#2780). It + coexists with the existing phone-OTP mode. + + - Gated on `features.phoneNumber` (phoneNumber plugin enabled). Unlike phone-OTP + it needs no SMS service, so it uses that coarser capability flag, not + `features.phoneNumberOtp`. When the flag is off the field stays email-only. + - New `AuthClient.signInWithPhonePassword(phoneNumber, password)` wired through + `AuthContext` / `AuthProvider` / `useAuth`. + - New `normalizePhoneIdentifier` / `looksLikePhoneIdentifier` helpers that mirror + the backend's `normalizePhoneNumber` exactly (strip `[\s\-().]`, validate + `^\+?[0-9]{6,15}$`, **no** forced E.164 / country code — the backend stores the + light-stripped form, so anything heavier would break the lookup). + - SSO stays email-only (a phone-shaped identifier no longer attempts domain + routing). + + Only works for accounts that have both a phone number and a password set; + phone-only accounts set a password on first OTP sign-in. + +- 5971cc4: i18n: translate the Profile page, honor inline i18n label objects under bare + base-language codes, and localize managed-by badges / record quick actions. + + - `pickLocalized` now upgrades a bare base language (`zh`) to any + region-qualified key sharing the base (`zh-CN`) — runtime language is + normalized to the base code while metadata authors write full BCP-47 tags, + so inline `{ en, 'zh-CN', ... }` label objects previously fell back to + English. + - ProfilePage (`account:profile_card` / `/system/profile`): every hardcoded + string — page title/subtitle, avatar Upload/Replace/Remove, Personal + Information card, Change/Set Password card — now goes through + `useObjectTranslation()` with `profile.*` keys (new namespace in all ten + locale bundles); the lazy-load fallback reuses `common.loading`. + - `ManagedByBadge` chips/tooltips (Config/System/Append-only/Identity) now + resolve through new `managedByBadge.*` keys with `{{provider}}` + interpolation. + - `record:quick_actions` resolves action labels via the + `objects.{object}._actions.{action}.label` convention plus `pickLocalized`, + so object action buttons (Change Password, Enable 2FA, …) localize. + - `record:details` / `record:related_list` / `record:alert` / `ObjectTree` + pass inline label objects through `pickLocalized`. + - Locale bundles: added `managedByBadge` namespace to all ten locales and + backfilled `list.inlineEditShort` / `inlineEditLabel` / + `recordEditingTitle` for ja/es/ko/de/fr/pt/ru/ar. + - @object-ui/react-runtime@14.0.0 + - @object-ui/sdui-parser@14.0.0 + ## 13.2.0 ### Patch Changes diff --git a/apps/console/package.json b/apps/console/package.json index 11df4dbbc..fb6513d33 100644 --- a/apps/console/package.json +++ b/apps/console/package.json @@ -1,6 +1,6 @@ { "name": "@object-ui/console", - "version": "13.2.0", + "version": "14.0.0", "description": "ObjectStack Console — opinionated, fork-ready runtime console built on @object-ui/app-shell with the full plugin set wired up. Ships as a Hono UI plugin serving a pre-built SPA.", "license": "MIT", "type": "module", diff --git a/packages/app-shell/CHANGELOG.md b/packages/app-shell/CHANGELOG.md index 9b909f0b7..0a0bc5254 100644 --- a/packages/app-shell/CHANGELOG.md +++ b/packages/app-shell/CHANGELOG.md @@ -1,5 +1,480 @@ # @object-ui/app-shell — Changelog +## 14.0.0 + +### Minor Changes + +- 06e92ac: feat(console-ai): ChatDock — right-docked AI rail behind a default-off flag (ADR-0057 P3a) + + Stands up the ADR-0057 P3 docked rail as an ADDITIVE, DEFAULT-OFF shell: until an + operator sets `features.chatDock`, nothing changes and the FAB stays the + canonical entry. + + - `@object-ui/layout`: `AppShell` gains an optional `rightRail` prop, rendered as + a flex sibling of the main content so the rail REFLOWS the content beside it + (VS Code / Cursor idiom), not overlaying it. Absent → unchanged single-pane. + - `@object-ui/app-shell`: new `ChatDock` — a collapsible, resizable right rail + that reuses the shared `ChatPane` engine over the P1 `(user, app, product=ask)` + conversation (the same ambient thread the FAB/`/ai` shows; it's a VIEW, not a + new conversation). Default COLLAPSED (a fixed edge launcher → zero layout cost + until invoked); ⌘/Ctrl+Shift+I toggles it. Gated on `useAiSurfaceEnabled` AND + the flag, so OSS / no-seat runtimes render nothing. + - `runtime-config`: `chatDock?` rollout flag, parsed default-OFF (opt-in only). + + Live-verified with the flag forced on: the launcher expands to a rail rendering + the ask chat, the dashboard content reflows narrower beside it, and collapse + restores the launcher. Unit-tested: width clamp, the composer-safe shortcut + matcher (⌘⇧I, no collision with the ⌘⇧O/S page shortcuts), and the flag's + default-off/opt-in parse. FAB retirement (P3b) and `/ai`-as-maximized-dock + + Studio reflow (P3c) follow. + +- 7b4fc36: feat(console-ai): ask→build handoff carries conversation context (ADR-0057 P4 / cloud#817) + + The P4 "Open in Builder →" handoff previously carried only the build prompt + an + optional package, so the Builder started cold and the user re-explained + themselves. It now also carries the **source `ask` conversation** as context — + ADR-0057 P4 / cloud#817 — so the build agent's first turn starts with the thread + the user already had. + + - `@object-ui/app-shell`: both handoff sites (the full-page `AiChatPage` and the + console FAB) now append `?parentConversationId=` to the + `/ai/build` URL. The build surface reads it and forwards it to `useObjectChat`; + the existing URL-mirror drops it once the build conversation id is minted, so a + reload never re-carries it. + - `@object-ui/plugin-chatbot`: `useObjectChat` accepts `parentConversationId` and + sends it as `context.parentConversationId` on the **first turn only** (held in a + ref, consumed once) — the backend redeems it into the turn's context and the + client owns history from there. New pure helper `withHandoffContext` (unit + tested) does the non-mutating `context` merge. + + Requires the cloud handoff-context contract (service-ai, cloud#817): the build + agent redeems `context.parentConversationId` into a single system block on its + first turn — ownership-checked, and carrying only the user/assistant text the + user already saw (ADR-0063 governance boundary). Without it the console degrades + cleanly: the id is sent but ignored, and the handoff is a (working) cold start. + +- 7dea792: feat(console-ai): explicit "Open in Builder →" ask→build handoff (ADR-0057 P4) + + When the `ask` agent declines an app-authoring request it now calls the cloud + `suggest_builder` tool (structured decline). The console renders that as an + explicit **"Open in Builder →"** action that opens the full-page build surface + seeded with the handoff prompt — ADR-0063 decline-and-redirect: an explicit, + user-initiated switch, never a silent re-route into authoring. + + - `@object-ui/plugin-chatbot`: `detectBuilderHandoff` lifts the + `{ status:'build_handoff', prompt, packageId? }` result onto the tool + invocation; `ChatbotEnhanced` renders the "Open in Builder →" card and calls a + new `onOpenBuilder` prop (disabled when no host wires it). + - `@object-ui/app-shell`: the full-page `AiChatPage` (`ask`) and the console FAB + wire `onOpenBuilder` to navigate to `/ai/build?package=…&handoffPrompt=…`; the + build surface seeds that prompt as its first message (auto-sent once the + conversation is minted), and the URL-mirror strips `?handoffPrompt` so a reload + never re-sends it. Full ask-conversation context transfer is a later upgrade + (cloud#817); v1 carries the build prompt + optional package. + + Requires the cloud `suggest_builder` signal (service-ai-studio) to light up; the + console degrades cleanly (no card) without it. + +- cd778d4: feat(console-ai): package binding chip + inert handoff cards + honest send hint (#2458 / ADR-0057 A1.a) + + Three UX improvements from live magic-flow testing: + + - **A1.a — package binding chip** (`app-shell`): the build surface header shows + the package the conversation is bound to (`📦 `), or **"New app"** when + unbound — so the edit blast-radius is always visible (Claude-Code-shows-the-repo + idiom). The magic flow starts unbound and binds the moment its build mints a + package (`deriveBoundPackageId` reads `?package=` else the latest draft/handoff + result; unit-tested). + - **UX#5 — only the latest handoff card is actionable** (`plugin-chatbot`): when + a thread accumulates several "Open in Builder →" cards, only the newest stays + clickable; older (superseded) cards' buttons are disabled — derived from + message order, so it survives the navigation the button triggers and the pane + remount that follows. A stale prompt in an older card can't be re-fired. + - **UX#7 — honest send hint** (`plugin-chatbot`): the composer already sends on + plain Enter (Shift+Enter = newline); dropped the misleading `⌘` glyph from the + hint so it no longer implies Cmd+Enter. + +### Patch Changes + +- 443360a: Action params support a `visible` CEL predicate — the param dialog omits a param + when it evaluates false, against the same scope as action `visible` (features / + user / app / data). Fixes the create-user form offering a **Phone Number** field + the default backend rejects ("Phone numbers require the phoneNumber auth plugin"): + paired with the framework gating that param on `features.phoneNumber`, the form + now follows the plugin — no phone field unless the opt-in phoneNumber auth plugin + is loaded. `filterVisibleParams` is exported + unit-tested (feature-off hides, + feature-on shows, malformed predicate fails open). +- c70bca7: fix(console-ai): Live Canvas is a full-screen, opt-in preview on mobile — not a broken split (#2481) + + On a phone the beside-chat Live Canvas split overflowed the viewport (the chat + column's fixed min-width plus the preview exceeded the screen, and the resize + handle is desktop-only, so it was stuck clipped). Under `md` the canvas is now: + + - **Full-width chat, no split** — the build streams in the chat as before. + - **Opt-in + full-screen** — when the preview is available a floating "Preview + app" pill appears; tapping it (or a Preview button on a draft card) takes the + canvas full-screen over the chat. Closing returns to the chat with the + preview one tap away. The auto-drafted canvas never covers the streaming + chat unprompted. + + Desktop is unchanged (the resizable beside-chat split). Adds the + `console.ai.previewApp` string (en/zh). + +- d06de4a: feat(console-ai): the ChatDock is now DEFAULT ON (ADR-0057 P3 go-live) + + `features.chatDock` flips from opt-in to opt-out: the right-docked chat rail + (FAB as launcher, `/ai` as the panel maximized, Studio right dock with center + `[Canvas | Properties]` tabs) is the console's default chat presentation. The + flag survives only as a server-side kill-switch — an operator sending + `chatDock: false` restores the floating-overlay console until the final + cleanup removes that path (epic #2409). + +- 1a12d69: polish(console-ai): ease the dock's canvas auto-maximize, and give Studio its own chat width (ADR-0057 UX follow-ups, #2477) + + - **#4** The rail now eases to its new width (200ms) when the Live Canvas opens + (auto-maximize) or closes (tuck), instead of snapping. The transition is + suppressed during a manual resize drag so the width still tracks the pointer + 1:1. + - **#6** The Studio dock persists its width under its own key, separate from the + console dock. A wide console chat no longer squeezes the Studio design canvas + (and vice-versa) — each surface remembers the width that suits it. + +- b800960: refactor(console-ai)!: ADR-0057 final cleanup — remove the chatDock flag, the floating-overlay console chat, and the legacy left Studio copilot + + The docked chat is now the console's ONE chat presentation, unconditionally: + + - `features.chatDock` is removed from the runtime config (it had already + flipped to default-on; the kill-switch is retired with the code path it + guarded). + - `ConsoleFloatingChatbot` (the FAB-armed floating overlay) and its + `agentPicker` helper are deleted; `ConsoleChatbotFab` is now a small + dependency-free launcher (`{ appLabel, onOpenDock }`) that opens the dock — + including on `/home`, where it opens the full-page `/ai` surface (the dock + maximized) since Home has no shell to host a rail. + - The legacy left `StudioAiCopilot` panel is deleted; the Studio copilot's one + home is the right `StudioChatDock`. The ADR-0080 `aiSlot` injection seam is + untouched. + - The runtime SDUI `type: 'chatbot'` bubble (end-user apps) is unchanged + (ADR-0057 §4). + - Fix: the mobile chat sheet no longer shows a "maximize" button. At 85svh the + sheet is already the maximal mobile chat, and navigating to full-page `/ai` + from an OPEN Radix sheet tore it down mid-close (the route change unmounts + the console synchronously, so the scroll-lock/overlay never released and the + destination landed blank-and-frozen — "tap maximize → the chat's just gone"). + Full-page `/ai` stays reachable via normal navigation. + +- 47b497f: feat(console-ai): mobile chat sheet bridges to full-page /ai (conversation history + share) — cleanly (ADR-0057 UX #2477 item 1) + + The mobile chat bottom sheet gets a maximize button back — it opens the + full-page `/ai`, which on mobile already carries the conversation-history + sidebar and share, so the sheet doesn't need a second copy of either. This is + the missing mobile path to switch/resume threads. + + The button navigates **deferred**: an earlier cut jumped straight from the + click and tore the still-open Radix sheet down mid-close (the route change + unmounts the console synchronously, leaking the sheet's scroll-lock/overlay + onto the destination — "tap maximize → the chat's just gone"). Now the click + only closes the sheet; a `useEffect` fires the navigation once `open` has + flipped false — after Radix released the body on that commit and before the + sheet unmounts — so `/ai` lands clean. Applies to both the console sheet + (→ `/ai`) and the Studio copilot sheet (→ `/ai/build?package=…`, same thread). + + Live Canvas on mobile `/ai` (the beside-chat split has no room on a phone) is + tracked separately (#2481). + +- 804a101: feat(console-ai): ChatDock follow-ups — mobile sheet, wide side-by-side properties, exact collapse landing (ADR-0057 P3) + + - Under `md` the dock presents as a bottom sheet (`ChatDockMobileSheet`) — + console FAB opens it; Studio gets a mobile-visible edge launcher. + - The folded Studio layout keeps canvas AND properties side by side on 2xl+ + viewports; tabs (and their auto-switch) only exist where width forces them. + - Folded tabs mode flattens the source page's nested Source/Props tabs — the + Properties tab body is the code editor directly. + - Maximize remembers its origin, so `/ai`'s collapse-to-dock returns to the + exact page (console or Studio) the user left, immune to history churn. + - The dock's conversation honors `app.defaultAgent` via the one resolver, + matching the FAB's behavior. + +- 3001e20: feat(console-ai): the FAB becomes the ChatDock launcher when the dock is on (ADR-0057 P3b) + + When `features.chatDock` is enabled, the console FAB opens the docked rail instead + of the floating overlay — one entry point, the ADR's "FAB → launcher" step. In + dock mode the FAB stays the lightweight button (it never mounts the heavy floating + chatbot; the rail loads the chat on demand), and a designer "Ask AI" open signal + (assistantBus) opens the dock too. With the flag OFF the FAB is unchanged (floating + overlay). Supersedes P3a's edge launcher (the dock is gated on the same + `showChatbot`, so the FAB is always present to launch it). + +- 159d7db: feat(console-ai): /ai = the ChatDock maximized + Studio right-dock reflow (ADR-0057 P3c) + + The final P3 slice, all behind the default-off `features.chatDock` flag: + + - **/ai ⇄ rail continuity**: the dock header gains a maximize button that opens + the full-page `/ai` surface, and the `/ai` page gains a collapse-to-dock button + that returns to the console with the rail expanded — same thread both ways + (the P1 `(user, app, product)` conversation key). Deep links + (`/ai/:agent/:conversationId`, ADR-0013) are untouched and keep working. + - **Studio reflow** (the ADR's decided grid `[left: nav/tree] [center: canvas + +properties] [right: chat]`): the AI copilot leaves the left `w-96` panel and + renders as the shared right dock (`ChatDockPanel` + `ChatDockLauncher`), same + package-scoped build thread; the Interfaces pillar's right inspector folds + into center `[Canvas | Properties]` tabs with select-a-block auto-switch. An + injected `aiSlot` (cloud seam, ADR-0080) keeps the legacy left panel. + - **Live Canvas** (ADR-0037): in the rail, the dock auto-maximizes while the + canvas is open and tucks back on close (manual resize wins); maximized (`/ai`) + keeps the existing beside-the-chat split. + + With the flag OFF, `/ai` and Studio are pixel-identical to before. + +- 1273f1e: fix(console-ai): reliable ask→build handoff auto-send + second-handoff context re-carry (ADR-0057 P4) + + Two follow-ups to the P4 "Open in Builder →" handoff: + + - **Auto-send swallow.** The handoff's auto-sent first message could be dropped on + a brand-new build conversation: the seed gated on the async-resolved + `activeAgent`, which can settle _after_ the conversation id is minted, so the + deferred-send replay ran with an empty pending and never re-fired. The seed now + gates on the **route** (`agentSegment`, synchronous) and bumps a `pendingSignal` + that `useDeferredFirstSend` lists in its replay deps, so the seed always fires — + no more empty build conversation on handoff. + + - **Second-handoff re-carry.** A second "Open in Builder →" into the (singleton) + build conversation now re-carries the latest ask context. The transport re-arms + `parentConversationId` on each falsy→truthy transition of the prop (the ask + thread is a singleton, so the same id repeats — the fresh-arrival signal is the + transition the URL-mirror produces, not a changed value), and the seed re-arms + on each new `handoffPrompt`. + + Unit-tested: deferred-send replays a post-id seed via the signal; the transport + re-carries across a strip→re-supply cycle. + +- 48d06da: fix(console-ai): Studio dock remembers a collapse; folded canvas+properties go side-by-side at `xl` (ADR-0057 UX follow-ups, #2477) + + - **Studio dock collapse is now remembered** (per-tab). The right copilot still + mounts expanded by default, but collapsing it to get the classic three-zone + canvas no longer re-opens on every pillar / package switch or Studio + re-entry. Backed by an explicit `'0'`/`'1'` stored flag (a default-expanded + surface couldn't remember a collapse when "collapsed" meant "key removed"), + under a Studio-specific key so it never shares state with the console dock. + - **Folded layout shows canvas + properties side by side from `xl`** (1280), + lowered from `2xl`. On the common laptop the folded center used to fall into + tabs, which auto-hide the canvas the moment you select a block — breaking the + WYSIWYG "edit and watch it apply" loop. The side-by-side inspector is slimmer + at `xl` (and grows at `2xl`) so the canvas keeps usable width beside the dock. + +- 9d0fdb1: feat(console-ai): render agent behavior by declared capability (cloud#816 / ADR-0057 "B+") + + `GET /api/v1/ai/agents` now serves per-agent `capabilities`; the console + consumes them instead of hard-coding `isBuildAgent(name)`: + + - `@object-ui/plugin-chatbot`: `AgentDescriptor.capabilities` (normalized from + the catalog) + new `agentHasCapability(agents, name, cap)` — declaration wins + when present; falls back to the legacy `isBuildAgent(name)` check when absent + (older server), so shipping order doesn't matter. + - `@object-ui/app-shell`: the build-doctor drawer + `showDebug` key off + `'debug'`, the FAB's resume-vs-fresh keys off `'resume'`, HomePage's + "Build with AI" availability keys off `'authoring'`. The ADR-0063 product-axis + sites (surface→agent resolver, conversation scope keying, picker availability) + intentionally stay name-based — capability describes RENDERED behavior, not + which product an agent is. + + A future skill-driven build variant now needs no console change. + +- 9442310: feat(console-ai): key AI chat conversations on `(user, app, product)`, not on surface (ADR-0057 P1) + + The console rendered AI chat through parallel shells that **forked the + conversation**: the Studio design copilot scoped its thread as + `studio:${packageId}:${agent}` while the full-page `/ai/build` focus view scoped + on the agent alone — so opening the _same app_ in both showed an empty "Build + with AI" copilot beside an active full-page build thread (indistinguishable from + data loss). + + Per ADR-0057 (**surface = view · conversation = model · product = binding + axis**), conversations are now keyed on `(user, app, product)`: + + - New pure, unit-tested `chatConversationScope({ appId, product })` + + `chatProductOfAgent(name)` helper (`hooks/chatScope.ts`) is the single place + the scope key is formed. `product` is the ADR-0063 axis (`ask` | `build`), + derived from the resolved agent — never a per-surface choice. + - `StudioAiCopilot` and the full-page `AiChatPage` both resolve + `app:${packageId}:${product}` for a package-scoped surface (the Studio copilot + editing package X and the `/ai/build?package=X` "Edit with AI" focus view now + resume ONE shared thread). The legacy `studio:` surface prefix is dropped. + - A generic `/ai/:agent` visit with no `?package=` degrades to the product alone + (`build` / `ask`) — unchanged behaviour for that surface. + + Enablement stays on the single access-filtered agent-catalog gate + (`useAiSurfaceEnabled`, ADR-0068) — a seat-less user's empty catalog hides the + whole AI surface. No layout change. + +- 9442310: feat(console-ai): one declarative surface→agent resolver (ADR-0057 P2) + + The console re-implemented the ADR-0063 surface→agent chain in ~5 places, each + spelled slightly differently — and `ConsoleLayout` carried an AI-Studio-off + downgrade special case that existed nowhere else. This collapses them into one + pure, unit-tested resolver so ADR-0063 (exactly two products `ask`/`build`, + bound by surface — no roster, no per-turn classifier) becomes a **structural** + guarantee. + + - New `hooks/surfaceAgent.ts`: `resolveSurfaceAgent(surface, { agents, +appDefaultAgent, aiStudioEnabled })` + `SURFACE_DEFAULT`. `app.defaultAgent` is + **bounded** to ask/build (alias-aware) — a withdrawn tenant custom agent is + rejected, not passed through, so no roster is representable (ADR-0057 open + question #4). The AI-Studio-off `build → ask` downgrade is folded in ONCE. + - `StudioAiCopilot` (studio-build → build) and the console FAB (`default` → ask) + resolve through it. The FAB keeps #771's "prefer build when the catalog unlocks + it and nothing pinned a product" by passing that as its default PRODUCT input — + so the resolver still owns bounding + the downgrade, which now also applies to + the #771 preference (closing the leak where an authoring-disabled deployment + could still open build). + - `ConsoleLayout`'s bespoke `!aiStudioEnabled && isBuildAgent(...)` downgrade is + deleted; it passes the raw `app.defaultAgent` and the resolver downgrades. + + Ships a unit table proving the ADR-0063 rows: Studio→build, other→ask, + AI-Studio-off downgrade, `app.defaultAgent` bounded (valid override wins, roster + rejected), alias-aware catalog resolution, empty catalog → inert (ADR-0025). + +- 05e56ca: 导出/导入模板的下载文件名与内容本地化。 + + **导出文件名**:CSV/Excel/JSON 导出下载不再是 `<对象名>.<扩展名>`(如 `contracts.csv`),改为「对象显示名-视图名-时间戳.扩展名」(如 `任务-In Progress-20260714-153045.xlsx`);`exportOptions.fileNamePrefix` 配置仍优先(且作为完整前缀,不再追加视图名)。视图名与对象名重复时自动省略;`@object-ui/core` 新增 `buildExportFileName(ext, { prefix, label, objectName, viewLabel }, now?)` 与 `sanitizeFileNameBase(raw)`,ObjectGrid 与 ListView 的所有导出路径(服务端流式与前端兜底)统一走它。app-shell/plugin-view 的 ObjectView 现将当前视图的显示标签写进传给 ListView 的 schema(`label`),使导出文件名能区分同一对象的不同保存视图。 + + **导入模板**:「下载模板」修复两处英文漏出——示例行的 select/多选取值改为优先取选项**显示标签**(如 `准备中`)而非 ASCII slug(`prepare`,服务端导入两者都接受);模板文件名本地化为 `{{object}}-导入模板.csv`(新增 i18n key `grid.import.templateFileName`,英文回退 `{{object}}-import-template.csv`)。 + +- 9d0fdb1: fix(console-ai): second handoff's auto-send no longer dies in the stale-scope pane (#2450) + + Mid ask→build transition, `useChatConversation` briefly still holds the OLD + scope's conversation id (the same stale window the URL-mirror already guards). + `` was fed that raw id, so a DOOMED pane (build chatApi + stale ask id, + about to remount) could mount — and the deferred first-send replay consumed the + handoff stash into it, where the send died with the unmount before reaching the + wire (observed live as "conversation resumes, zero `…/chat` POST"). + + Two-layer fix: + + - **Scope-gated pane feed (structural):** the page now hands `` a + conversation id/messages ONLY when `conversationScope === chatScope`. During + the stale window the pane mounts as `…:pending`, holds the stash, and replays + exactly once in the correctly-scoped pane — extending the existing URL-mirror + guard to the pane itself. + - **Targeted stash (defense-in-depth):** the handoff seed is stamped + `targetAgentRoute: 'build'`; `useDeferredFirstSend` refuses to consume a + targeted stash in a pane bound to another agent (untargeted user-typed sends + keep the legacy consume-anywhere behavior). + + Per product decision, a second handoff landing on a conversation with a + blueprint still Awaiting Approval just auto-sends — the build agent sees the + pending plan in context and decides merge/supersede itself. + +- 9138e68: fix(metadata-admin): authenticate console MetadataClient requests (Bearer token) + + Studio / metadata-admin surfaces issued `/api/v1/meta/*` requests (list types, + `?package=…` reads, `_drafts`, the `/meta` root) that came back `401 +unauthenticated` in the token-based console, while the runtime data adapter's + reads (`/meta/object|view|app`) succeeded — so the same page showed some + metadata requests failing and others working. + + Root cause: `useMetadataClient` and `MetadataProvider`'s draft-preview client + constructed `MetadataClient` without a `fetch`, so it fell back to the bare + `globalThis.fetch` and sent no `Authorization` header. The console + authenticates by a Bearer token in localStorage (`auth-session-token`) — there + is no session cookie — so those requests were unauthenticated. A same-origin + cookie deployment masks the bug, which is why it went unnoticed and regressed + twice. + + Both sites (and every future console surface) now construct through a single + `createConsoleMetadataClient` factory that bakes in `createAuthenticatedFetch` + (Bearer token + `X-Tenant-ID` + `Accept-Language`), matching the runtime data + adapter. This is additive for cookie deployments — `credentials` is untouched, + so a same-origin session cookie still flows. A + `metadata-client-auth.ratchet.test.ts` guard forbids a bare + `new MetadataClient(` elsewhere in app-shell so authentication can't silently + regress again. + +- 780b60a: Say "reset to shipped baseline" instead of "delete" when removing a package-owned permission set (ADR-0094). + + Deleting a `sys_permission_set` row whose `managed_by === 'package'` doesn't remove it — the backend drops the environment customization overlay and resets the set to its shipped baseline, so the row stays in the list. The confirmation dialog and success toast now say so (with `resetPackageSetConfirm` / `resetPackageSetSuccess` i18n, en + zh), instead of promising an irreversible delete the user can see doesn't happen. Environment-authored sets keep the plain delete copy. The grid row-delete passes the record through so the check needs no extra fetch; the SDUI header delete falls back to a `findOne` lookup. + +- 5971cc4: i18n: translate the Profile page, honor inline i18n label objects under bare + base-language codes, and localize managed-by badges / record quick actions. + + - `pickLocalized` now upgrades a bare base language (`zh`) to any + region-qualified key sharing the base (`zh-CN`) — runtime language is + normalized to the base code while metadata authors write full BCP-47 tags, + so inline `{ en, 'zh-CN', ... }` label objects previously fell back to + English. + - ProfilePage (`account:profile_card` / `/system/profile`): every hardcoded + string — page title/subtitle, avatar Upload/Replace/Remove, Personal + Information card, Change/Set Password card — now goes through + `useObjectTranslation()` with `profile.*` keys (new namespace in all ten + locale bundles); the lazy-load fallback reuses `common.loading`. + - `ManagedByBadge` chips/tooltips (Config/System/Append-only/Identity) now + resolve through new `managedByBadge.*` keys with `{{provider}}` + interpolation. + - `record:quick_actions` resolves action labels via the + `objects.{object}._actions.{action}.label` convention plus `pickLocalized`, + so object action buttons (Change Password, Enable 2FA, …) localize. + - `record:details` / `record:related_list` / `record:alert` / `ObjectTree` + pass inline label objects through `pickLocalized`. + - Locale bundles: added `managedByBadge` namespace to all ten locales and + backfilled `list.inlineEditShort` / `inlineEditLabel` / + `recordEditingTitle` for ja/es/ko/de/fr/pt/ru/ar. + +- 2fb38ed: fix(app-shell): propagate action-param `visible` predicate through resolveActionParams + + The create-user phone fix (#2406) gated the `phoneNumber` param with + `visible: 'features.phoneNumber == true'`, but `resolveActionParam` dropped + `visible` when flattening raw spec params into `ActionParamDef` — so + `ActionParamDialog`'s `filterVisibleParams` never saw the predicate and the + phone field kept rendering even with the phoneNumber auth plugin off. + + Propagate `visible` in all three resolve branches (inline / field-backed / + missing-field), unwrapping the spec's `{ dialect, source }` ExpressionInput + envelope to a plain CEL string. Completes the create-user phone fix end to end. + +- Updated dependencies [443360a] +- Updated dependencies [c70bca7] +- Updated dependencies [06e92ac] +- Updated dependencies [7b4fc36] +- Updated dependencies [1273f1e] +- Updated dependencies [7dea792] +- Updated dependencies [86c69c3] +- Updated dependencies [bfea27f] +- Updated dependencies [9d0fdb1] +- Updated dependencies [cd778d4] +- Updated dependencies [05e56ca] +- Updated dependencies [408f4ba] +- Updated dependencies [a44e7b6] +- Updated dependencies [eef832b] +- Updated dependencies [b66d8ee] +- Updated dependencies [94d00d4] +- Updated dependencies [5971cc4] +- Updated dependencies [6a74160] + - @object-ui/core@14.0.0 + - @object-ui/i18n@14.0.0 + - @object-ui/layout@14.0.0 + - @object-ui/plugin-chatbot@14.0.0 + - @object-ui/react@14.0.0 + - @object-ui/types@14.0.0 + - @object-ui/plugin-grid@14.0.0 + - @object-ui/plugin-list@14.0.0 + - @object-ui/plugin-view@14.0.0 + - @object-ui/components@14.0.0 + - @object-ui/plugin-detail@14.0.0 + - @object-ui/auth@14.0.0 + - @object-ui/fields@14.0.0 + - @object-ui/data-objectstack@14.0.0 + - @object-ui/plugin-calendar@14.0.0 + - @object-ui/plugin-charts@14.0.0 + - @object-ui/plugin-dashboard@14.0.0 + - @object-ui/plugin-designer@14.0.0 + - @object-ui/plugin-editor@14.0.0 + - @object-ui/plugin-form@14.0.0 + - @object-ui/plugin-kanban@14.0.0 + - @object-ui/plugin-report@14.0.0 + - @object-ui/collaboration@14.0.0 + - @object-ui/permissions@14.0.0 + - @object-ui/providers@14.0.0 + ## 13.2.0 ### Minor Changes diff --git a/packages/app-shell/package.json b/packages/app-shell/package.json index 1fa1a2f43..3e13275c6 100644 --- a/packages/app-shell/package.json +++ b/packages/app-shell/package.json @@ -1,6 +1,6 @@ { "name": "@object-ui/app-shell", - "version": "13.2.0", + "version": "14.0.0", "type": "module", "license": "MIT", "description": "Minimal application shell for ObjectUI - framework-agnostic rendering engine", diff --git a/packages/auth/CHANGELOG.md b/packages/auth/CHANGELOG.md index abafff360..770aa1923 100644 --- a/packages/auth/CHANGELOG.md +++ b/packages/auth/CHANGELOG.md @@ -1,5 +1,37 @@ # @object-ui/auth +## 14.0.0 + +### Minor Changes + +- 94d00d4: feat(auth): phone number + password sign-in on the login page + + The login page's password mode now accepts an **email OR a phone number** as the + identifier and routes by shape — email → `/sign-in/email`, phone → + `/sign-in/phone-number` (better-auth phoneNumber plugin, framework#2780). It + coexists with the existing phone-OTP mode. + + - Gated on `features.phoneNumber` (phoneNumber plugin enabled). Unlike phone-OTP + it needs no SMS service, so it uses that coarser capability flag, not + `features.phoneNumberOtp`. When the flag is off the field stays email-only. + - New `AuthClient.signInWithPhonePassword(phoneNumber, password)` wired through + `AuthContext` / `AuthProvider` / `useAuth`. + - New `normalizePhoneIdentifier` / `looksLikePhoneIdentifier` helpers that mirror + the backend's `normalizePhoneNumber` exactly (strip `[\s\-().]`, validate + `^\+?[0-9]{6,15}$`, **no** forced E.164 / country code — the backend stores the + light-stripped form, so anything heavier would break the lookup). + - SSO stays email-only (a phone-shaped identifier no longer attempts domain + routing). + + Only works for accounts that have both a phone number and a password set; + phone-only accounts set a password on first OTP sign-in. + +### Patch Changes + +- Updated dependencies [86c69c3] +- Updated dependencies [6a74160] + - @object-ui/types@14.0.0 + ## 13.2.0 ### Patch Changes diff --git a/packages/auth/package.json b/packages/auth/package.json index 24a29d72a..594b9ce59 100644 --- a/packages/auth/package.json +++ b/packages/auth/package.json @@ -1,6 +1,6 @@ { "name": "@object-ui/auth", - "version": "13.2.0", + "version": "14.0.0", "type": "module", "license": "MIT", "description": "Authentication system for Object UI with AuthProvider, useAuth hook, AuthGuard, and form components.", diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index 7b8fda3d8..b347187fc 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -1,5 +1,16 @@ # @object-ui/cli +## 14.0.0 + +### Patch Changes + +- Updated dependencies [86c69c3] +- Updated dependencies [a44e7b6] +- Updated dependencies [6a74160] + - @object-ui/react@14.0.0 + - @object-ui/types@14.0.0 + - @object-ui/components@14.0.0 + ## 13.2.0 ### Patch Changes diff --git a/packages/cli/package.json b/packages/cli/package.json index 6b2aa4ebf..c30710537 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@object-ui/cli", - "version": "13.2.0", + "version": "14.0.0", "description": "Standalone CLI for Object UI — scaffold, develop, build and validate JSON/YAML schema-driven applications.", "type": "module", "homepage": "https://www.objectui.org/docs/utilities/cli", diff --git a/packages/collaboration/CHANGELOG.md b/packages/collaboration/CHANGELOG.md index c9cd1a4f0..6941fb9e4 100644 --- a/packages/collaboration/CHANGELOG.md +++ b/packages/collaboration/CHANGELOG.md @@ -1,5 +1,13 @@ # @object-ui/collaboration +## 14.0.0 + +### Patch Changes + +- Updated dependencies [86c69c3] +- Updated dependencies [6a74160] + - @object-ui/types@14.0.0 + ## 13.2.0 ### Patch Changes diff --git a/packages/collaboration/package.json b/packages/collaboration/package.json index 45b8ac96a..8cac326d7 100644 --- a/packages/collaboration/package.json +++ b/packages/collaboration/package.json @@ -1,6 +1,6 @@ { "name": "@object-ui/collaboration", - "version": "13.2.0", + "version": "14.0.0", "type": "module", "license": "MIT", "description": "Real-time collaboration for Object UI with presence tracking, live cursors, conflict resolution, and comment threads.", diff --git a/packages/components/CHANGELOG.md b/packages/components/CHANGELOG.md index 79878b6a6..b6e3d41b0 100644 --- a/packages/components/CHANGELOG.md +++ b/packages/components/CHANGELOG.md @@ -1,5 +1,59 @@ # @object-ui/components +## 14.0.0 + +### Minor Changes + +- 6a74160: Sharing-rule form: pick, don't type. Three new widget-hint field components make + the generic object form render pickers where an admin previously had to type + machine data (driven by the framework `widget` hints on `sys_sharing_rule`; + generalizes the `capability-multiselect` pattern). All degrade to the underlying + `type` renderer when a widget is unregistered. + + - **`object-ref`** — choose a registered object by name (searchable `Combobox`), + backed by the new `DataSource.getObjects()` (`ObjectStackAdapter` lists code- + and DB-defined objects via `/api/v1/meta/object`), falling back to a + `sys_metadata` query. Stores the object's `name`. + - **`filter-condition`** — a visual criteria builder (`FilterBuilder`) scoped to + the fields of the object chosen in a sibling field (via `getObjectSchema`), + round-tripping the stored **MongoDB-style** FilterCondition JSON. Criteria the + builder can't represent (or invalid JSON) fall back to a raw-JSON editor, with + an always-available "Edit as JSON" toggle — nothing is hidden or lost. + - **`recipient-picker`** — a record picker whose target object follows a sibling + `recipient_type` (`user`→sys_user, `team`→sys_team, `business_unit`/ + `unit_and_subordinates`→sys_business_unit, `position`→sys_position), storing the + value the evaluator matches on (a record id, or the position **name**). Resets + the stored id when the type changes. + + Wiring: the three keys join `DATA_SOURCE_FIELD_TYPES` (form.tsx) so the form + threads `dataSource` + `dependentValues` to them, and `INLINE_EXCLUDED_FIELD_TYPES` + (they're authored in the record form, not a grid cell). `DataSource.getObjects()` + is optional on the interface; the ObjectStack adapter implements it. + +### Patch Changes + +- a44e7b6: Form fields honor their object-schema `widget` render hint on the field-group / + section layout path. `ObjectForm` renders objects that declare field groups + (e.g. `sys_sharing_rule`) via an auto-derived section layout that passed each + field's metadata through without hoisting its `widget` override to the top-level + form-field config, so a field with `widget: 'object-ref'` (or `filter-condition` + / `recipient-picker`) degraded to its bare `type` input — an admin was asked to + hand-type an object name instead of picking it. The form renderer now falls back + to the field metadata's own `widget` when no top-level override is present, so + the pickers render on sectioned forms just as they do on flat ones. +- Updated dependencies [443360a] +- Updated dependencies [c70bca7] +- Updated dependencies [86c69c3] +- Updated dependencies [05e56ca] +- Updated dependencies [5971cc4] +- Updated dependencies [6a74160] + - @object-ui/core@14.0.0 + - @object-ui/i18n@14.0.0 + - @object-ui/react@14.0.0 + - @object-ui/types@14.0.0 + - @object-ui/react-runtime@14.0.0 + - @object-ui/sdui-parser@14.0.0 + ## 13.2.0 ### Patch Changes diff --git a/packages/components/package.json b/packages/components/package.json index db8566813..7b49603e4 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -1,6 +1,6 @@ { "name": "@object-ui/components", - "version": "13.2.0", + "version": "14.0.0", "type": "module", "license": "MIT", "description": "Standard UI component library for Object UI, built with Shadcn UI + Tailwind CSS", diff --git a/packages/core/CHANGELOG.md b/packages/core/CHANGELOG.md index eb73089dc..615b1e98b 100644 --- a/packages/core/CHANGELOG.md +++ b/packages/core/CHANGELOG.md @@ -1,5 +1,27 @@ # @object-ui/core +## 14.0.0 + +### Patch Changes + +- 443360a: Action params support a `visible` CEL predicate — the param dialog omits a param + when it evaluates false, against the same scope as action `visible` (features / + user / app / data). Fixes the create-user form offering a **Phone Number** field + the default backend rejects ("Phone numbers require the phoneNumber auth plugin"): + paired with the framework gating that param on `features.phoneNumber`, the form + now follows the plugin — no phone field unless the opt-in phoneNumber auth plugin + is loaded. `filterVisibleParams` is exported + unit-tested (feature-off hides, + feature-on shows, malformed predicate fails open). +- 05e56ca: 导出/导入模板的下载文件名与内容本地化。 + + **导出文件名**:CSV/Excel/JSON 导出下载不再是 `<对象名>.<扩展名>`(如 `contracts.csv`),改为「对象显示名-视图名-时间戳.扩展名」(如 `任务-In Progress-20260714-153045.xlsx`);`exportOptions.fileNamePrefix` 配置仍优先(且作为完整前缀,不再追加视图名)。视图名与对象名重复时自动省略;`@object-ui/core` 新增 `buildExportFileName(ext, { prefix, label, objectName, viewLabel }, now?)` 与 `sanitizeFileNameBase(raw)`,ObjectGrid 与 ListView 的所有导出路径(服务端流式与前端兜底)统一走它。app-shell/plugin-view 的 ObjectView 现将当前视图的显示标签写进传给 ListView 的 schema(`label`),使导出文件名能区分同一对象的不同保存视图。 + + **导入模板**:「下载模板」修复两处英文漏出——示例行的 select/多选取值改为优先取选项**显示标签**(如 `准备中`)而非 ASCII slug(`prepare`,服务端导入两者都接受);模板文件名本地化为 `{{object}}-导入模板.csv`(新增 i18n key `grid.import.templateFileName`,英文回退 `{{object}}-import-template.csv`)。 + +- Updated dependencies [86c69c3] +- Updated dependencies [6a74160] + - @object-ui/types@14.0.0 + ## 13.2.0 ### Patch Changes diff --git a/packages/core/package.json b/packages/core/package.json index 56d332257..66f71ec05 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@object-ui/core", - "version": "13.2.0", + "version": "14.0.0", "type": "module", "sideEffects": false, "license": "MIT", diff --git a/packages/create-plugin/CHANGELOG.md b/packages/create-plugin/CHANGELOG.md index 40a92ec71..4abec72e7 100644 --- a/packages/create-plugin/CHANGELOG.md +++ b/packages/create-plugin/CHANGELOG.md @@ -1,5 +1,7 @@ # @object-ui/create-plugin +## 14.0.0 + ## 13.2.0 ## 13.1.0 diff --git a/packages/create-plugin/package.json b/packages/create-plugin/package.json index 81a47ae84..c3247b21a 100644 --- a/packages/create-plugin/package.json +++ b/packages/create-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@object-ui/create-plugin", - "version": "13.2.0", + "version": "14.0.0", "description": "CLI tool to scaffold ObjectUI plugins", "type": "module", "license": "MIT", diff --git a/packages/data-objectstack/CHANGELOG.md b/packages/data-objectstack/CHANGELOG.md index 8b47e5a9a..e0920d8a7 100644 --- a/packages/data-objectstack/CHANGELOG.md +++ b/packages/data-objectstack/CHANGELOG.md @@ -1,5 +1,44 @@ # @object-ui/data-objectstack +## 14.0.0 + +### Minor Changes + +- 6a74160: Sharing-rule form: pick, don't type. Three new widget-hint field components make + the generic object form render pickers where an admin previously had to type + machine data (driven by the framework `widget` hints on `sys_sharing_rule`; + generalizes the `capability-multiselect` pattern). All degrade to the underlying + `type` renderer when a widget is unregistered. + + - **`object-ref`** — choose a registered object by name (searchable `Combobox`), + backed by the new `DataSource.getObjects()` (`ObjectStackAdapter` lists code- + and DB-defined objects via `/api/v1/meta/object`), falling back to a + `sys_metadata` query. Stores the object's `name`. + - **`filter-condition`** — a visual criteria builder (`FilterBuilder`) scoped to + the fields of the object chosen in a sibling field (via `getObjectSchema`), + round-tripping the stored **MongoDB-style** FilterCondition JSON. Criteria the + builder can't represent (or invalid JSON) fall back to a raw-JSON editor, with + an always-available "Edit as JSON" toggle — nothing is hidden or lost. + - **`recipient-picker`** — a record picker whose target object follows a sibling + `recipient_type` (`user`→sys_user, `team`→sys_team, `business_unit`/ + `unit_and_subordinates`→sys_business_unit, `position`→sys_position), storing the + value the evaluator matches on (a record id, or the position **name**). Resets + the stored id when the type changes. + + Wiring: the three keys join `DATA_SOURCE_FIELD_TYPES` (form.tsx) so the form + threads `dataSource` + `dependentValues` to them, and `INLINE_EXCLUDED_FIELD_TYPES` + (they're authored in the record form, not a grid cell). `DataSource.getObjects()` + is optional on the interface; the ObjectStack adapter implements it. + +### Patch Changes + +- Updated dependencies [443360a] +- Updated dependencies [86c69c3] +- Updated dependencies [05e56ca] +- Updated dependencies [6a74160] + - @object-ui/core@14.0.0 + - @object-ui/types@14.0.0 + ## 13.2.0 ### Patch Changes diff --git a/packages/data-objectstack/package.json b/packages/data-objectstack/package.json index 54b833665..0cd02e529 100644 --- a/packages/data-objectstack/package.json +++ b/packages/data-objectstack/package.json @@ -1,6 +1,6 @@ { "name": "@object-ui/data-objectstack", - "version": "13.2.0", + "version": "14.0.0", "description": "ObjectStack Data Adapter for Object UI", "license": "MIT", "type": "module", diff --git a/packages/fields/CHANGELOG.md b/packages/fields/CHANGELOG.md index 3cc33de36..425f8b34e 100644 --- a/packages/fields/CHANGELOG.md +++ b/packages/fields/CHANGELOG.md @@ -1,5 +1,51 @@ # @object-ui/fields +## 14.0.0 + +### Minor Changes + +- 6a74160: Sharing-rule form: pick, don't type. Three new widget-hint field components make + the generic object form render pickers where an admin previously had to type + machine data (driven by the framework `widget` hints on `sys_sharing_rule`; + generalizes the `capability-multiselect` pattern). All degrade to the underlying + `type` renderer when a widget is unregistered. + + - **`object-ref`** — choose a registered object by name (searchable `Combobox`), + backed by the new `DataSource.getObjects()` (`ObjectStackAdapter` lists code- + and DB-defined objects via `/api/v1/meta/object`), falling back to a + `sys_metadata` query. Stores the object's `name`. + - **`filter-condition`** — a visual criteria builder (`FilterBuilder`) scoped to + the fields of the object chosen in a sibling field (via `getObjectSchema`), + round-tripping the stored **MongoDB-style** FilterCondition JSON. Criteria the + builder can't represent (or invalid JSON) fall back to a raw-JSON editor, with + an always-available "Edit as JSON" toggle — nothing is hidden or lost. + - **`recipient-picker`** — a record picker whose target object follows a sibling + `recipient_type` (`user`→sys_user, `team`→sys_team, `business_unit`/ + `unit_and_subordinates`→sys_business_unit, `position`→sys_position), storing the + value the evaluator matches on (a record id, or the position **name**). Resets + the stored id when the type changes. + + Wiring: the three keys join `DATA_SOURCE_FIELD_TYPES` (form.tsx) so the form + threads `dataSource` + `dependentValues` to them, and `INLINE_EXCLUDED_FIELD_TYPES` + (they're authored in the record form, not a grid cell). `DataSource.getObjects()` + is optional on the interface; the ObjectStack adapter implements it. + +### Patch Changes + +- Updated dependencies [443360a] +- Updated dependencies [c70bca7] +- Updated dependencies [86c69c3] +- Updated dependencies [05e56ca] +- Updated dependencies [a44e7b6] +- Updated dependencies [5971cc4] +- Updated dependencies [6a74160] + - @object-ui/core@14.0.0 + - @object-ui/i18n@14.0.0 + - @object-ui/react@14.0.0 + - @object-ui/types@14.0.0 + - @object-ui/components@14.0.0 + - @object-ui/providers@14.0.0 + ## 13.2.0 ### Patch Changes diff --git a/packages/fields/package.json b/packages/fields/package.json index c3f87b8ad..bbc3926f5 100644 --- a/packages/fields/package.json +++ b/packages/fields/package.json @@ -1,6 +1,6 @@ { "name": "@object-ui/fields", - "version": "13.2.0", + "version": "14.0.0", "description": "Field renderers and registry for Object UI", "license": "MIT", "type": "module", diff --git a/packages/i18n/CHANGELOG.md b/packages/i18n/CHANGELOG.md index 26e15b989..12e428078 100644 --- a/packages/i18n/CHANGELOG.md +++ b/packages/i18n/CHANGELOG.md @@ -1,5 +1,56 @@ # @object-ui/i18n +## 14.0.0 + +### Patch Changes + +- c70bca7: fix(console-ai): Live Canvas is a full-screen, opt-in preview on mobile — not a broken split (#2481) + + On a phone the beside-chat Live Canvas split overflowed the viewport (the chat + column's fixed min-width plus the preview exceeded the screen, and the resize + handle is desktop-only, so it was stuck clipped). Under `md` the canvas is now: + + - **Full-width chat, no split** — the build streams in the chat as before. + - **Opt-in + full-screen** — when the preview is available a floating "Preview + app" pill appears; tapping it (or a Preview button on a draft card) takes the + canvas full-screen over the chat. Closing returns to the chat with the + preview one tap away. The auto-drafted canvas never covers the streaming + chat unprompted. + + Desktop is unchanged (the resizable beside-chat split). Adds the + `console.ai.previewApp` string (en/zh). + +- 05e56ca: 导出/导入模板的下载文件名与内容本地化。 + + **导出文件名**:CSV/Excel/JSON 导出下载不再是 `<对象名>.<扩展名>`(如 `contracts.csv`),改为「对象显示名-视图名-时间戳.扩展名」(如 `任务-In Progress-20260714-153045.xlsx`);`exportOptions.fileNamePrefix` 配置仍优先(且作为完整前缀,不再追加视图名)。视图名与对象名重复时自动省略;`@object-ui/core` 新增 `buildExportFileName(ext, { prefix, label, objectName, viewLabel }, now?)` 与 `sanitizeFileNameBase(raw)`,ObjectGrid 与 ListView 的所有导出路径(服务端流式与前端兜底)统一走它。app-shell/plugin-view 的 ObjectView 现将当前视图的显示标签写进传给 ListView 的 schema(`label`),使导出文件名能区分同一对象的不同保存视图。 + + **导入模板**:「下载模板」修复两处英文漏出——示例行的 select/多选取值改为优先取选项**显示标签**(如 `准备中`)而非 ASCII slug(`prepare`,服务端导入两者都接受);模板文件名本地化为 `{{object}}-导入模板.csv`(新增 i18n key `grid.import.templateFileName`,英文回退 `{{object}}-import-template.csv`)。 + +- 5971cc4: i18n: translate the Profile page, honor inline i18n label objects under bare + base-language codes, and localize managed-by badges / record quick actions. + + - `pickLocalized` now upgrades a bare base language (`zh`) to any + region-qualified key sharing the base (`zh-CN`) — runtime language is + normalized to the base code while metadata authors write full BCP-47 tags, + so inline `{ en, 'zh-CN', ... }` label objects previously fell back to + English. + - ProfilePage (`account:profile_card` / `/system/profile`): every hardcoded + string — page title/subtitle, avatar Upload/Replace/Remove, Personal + Information card, Change/Set Password card — now goes through + `useObjectTranslation()` with `profile.*` keys (new namespace in all ten + locale bundles); the lazy-load fallback reuses `common.loading`. + - `ManagedByBadge` chips/tooltips (Config/System/Append-only/Identity) now + resolve through new `managedByBadge.*` keys with `{{provider}}` + interpolation. + - `record:quick_actions` resolves action labels via the + `objects.{object}._actions.{action}.label` convention plus `pickLocalized`, + so object action buttons (Change Password, Enable 2FA, …) localize. + - `record:details` / `record:related_list` / `record:alert` / `ObjectTree` + pass inline label objects through `pickLocalized`. + - Locale bundles: added `managedByBadge` namespace to all ten locales and + backfilled `list.inlineEditShort` / `inlineEditLabel` / + `recordEditingTitle` for ja/es/ko/de/fr/pt/ru/ar. + ## 13.2.0 ### Patch Changes diff --git a/packages/i18n/package.json b/packages/i18n/package.json index de3b45d67..155420d13 100644 --- a/packages/i18n/package.json +++ b/packages/i18n/package.json @@ -1,6 +1,6 @@ { "name": "@object-ui/i18n", - "version": "13.2.0", + "version": "14.0.0", "type": "module", "sideEffects": false, "license": "MIT", diff --git a/packages/layout/CHANGELOG.md b/packages/layout/CHANGELOG.md index e4f61419a..d86961648 100644 --- a/packages/layout/CHANGELOG.md +++ b/packages/layout/CHANGELOG.md @@ -1,5 +1,45 @@ # @object-ui/layout +## 14.0.0 + +### Minor Changes + +- 06e92ac: feat(console-ai): ChatDock — right-docked AI rail behind a default-off flag (ADR-0057 P3a) + + Stands up the ADR-0057 P3 docked rail as an ADDITIVE, DEFAULT-OFF shell: until an + operator sets `features.chatDock`, nothing changes and the FAB stays the + canonical entry. + + - `@object-ui/layout`: `AppShell` gains an optional `rightRail` prop, rendered as + a flex sibling of the main content so the rail REFLOWS the content beside it + (VS Code / Cursor idiom), not overlaying it. Absent → unchanged single-pane. + - `@object-ui/app-shell`: new `ChatDock` — a collapsible, resizable right rail + that reuses the shared `ChatPane` engine over the P1 `(user, app, product=ask)` + conversation (the same ambient thread the FAB/`/ai` shows; it's a VIEW, not a + new conversation). Default COLLAPSED (a fixed edge launcher → zero layout cost + until invoked); ⌘/Ctrl+Shift+I toggles it. Gated on `useAiSurfaceEnabled` AND + the flag, so OSS / no-seat runtimes render nothing. + - `runtime-config`: `chatDock?` rollout flag, parsed default-OFF (opt-in only). + + Live-verified with the flag forced on: the launcher expands to a rail rendering + the ask chat, the dashboard content reflows narrower beside it, and collapse + restores the launcher. Unit-tested: width clamp, the composer-safe shortcut + matcher (⌘⇧I, no collision with the ⌘⇧O/S page shortcuts), and the flag's + default-off/opt-in parse. FAB retirement (P3b) and `/ai`-as-maximized-dock + + Studio reflow (P3c) follow. + +### Patch Changes + +- Updated dependencies [443360a] +- Updated dependencies [86c69c3] +- Updated dependencies [05e56ca] +- Updated dependencies [a44e7b6] +- Updated dependencies [6a74160] + - @object-ui/core@14.0.0 + - @object-ui/react@14.0.0 + - @object-ui/types@14.0.0 + - @object-ui/components@14.0.0 + ## 13.2.0 ### Patch Changes diff --git a/packages/layout/package.json b/packages/layout/package.json index 5e0cfc1ef..d1f127ac8 100644 --- a/packages/layout/package.json +++ b/packages/layout/package.json @@ -1,6 +1,6 @@ { "name": "@object-ui/layout", - "version": "13.2.0", + "version": "14.0.0", "type": "module", "sideEffects": false, "main": "dist/index.umd.cjs", diff --git a/packages/mobile/CHANGELOG.md b/packages/mobile/CHANGELOG.md index 054d566f0..87c24b33f 100644 --- a/packages/mobile/CHANGELOG.md +++ b/packages/mobile/CHANGELOG.md @@ -1,5 +1,13 @@ # @object-ui/mobile +## 14.0.0 + +### Patch Changes + +- Updated dependencies [86c69c3] +- Updated dependencies [6a74160] + - @object-ui/types@14.0.0 + ## 13.2.0 ### Patch Changes diff --git a/packages/mobile/package.json b/packages/mobile/package.json index c0148e07c..7e16f4bf3 100644 --- a/packages/mobile/package.json +++ b/packages/mobile/package.json @@ -1,6 +1,6 @@ { "name": "@object-ui/mobile", - "version": "13.2.0", + "version": "14.0.0", "type": "module", "license": "MIT", "description": "Mobile optimization for Object UI with responsive components, PWA support, and touch gesture handling.", diff --git a/packages/permissions/CHANGELOG.md b/packages/permissions/CHANGELOG.md index 1208c98d0..1523c0401 100644 --- a/packages/permissions/CHANGELOG.md +++ b/packages/permissions/CHANGELOG.md @@ -1,5 +1,13 @@ # @object-ui/permissions +## 14.0.0 + +### Patch Changes + +- Updated dependencies [86c69c3] +- Updated dependencies [6a74160] + - @object-ui/types@14.0.0 + ## 13.2.0 ### Patch Changes diff --git a/packages/permissions/package.json b/packages/permissions/package.json index b94c46336..2e27f49d7 100644 --- a/packages/permissions/package.json +++ b/packages/permissions/package.json @@ -1,6 +1,6 @@ { "name": "@object-ui/permissions", - "version": "13.2.0", + "version": "14.0.0", "type": "module", "license": "MIT", "description": "RBAC permission system for Object UI with object/field/row-level access control, permission guards, and hooks.", diff --git a/packages/plugin-ai/CHANGELOG.md b/packages/plugin-ai/CHANGELOG.md index a7917160c..50fe0a99e 100644 --- a/packages/plugin-ai/CHANGELOG.md +++ b/packages/plugin-ai/CHANGELOG.md @@ -1,5 +1,19 @@ # @object-ui/plugin-ai +## 14.0.0 + +### Patch Changes + +- Updated dependencies [443360a] +- Updated dependencies [86c69c3] +- Updated dependencies [05e56ca] +- Updated dependencies [a44e7b6] +- Updated dependencies [6a74160] + - @object-ui/core@14.0.0 + - @object-ui/react@14.0.0 + - @object-ui/types@14.0.0 + - @object-ui/components@14.0.0 + ## 13.2.0 ### Patch Changes diff --git a/packages/plugin-ai/package.json b/packages/plugin-ai/package.json index 1ebea676b..eecde772c 100644 --- a/packages/plugin-ai/package.json +++ b/packages/plugin-ai/package.json @@ -1,6 +1,6 @@ { "name": "@object-ui/plugin-ai", - "version": "13.2.0", + "version": "14.0.0", "type": "module", "main": "dist/index.umd.cjs", "module": "dist/index.js", diff --git a/packages/plugin-calendar/CHANGELOG.md b/packages/plugin-calendar/CHANGELOG.md index 1a39766c4..95dd284f8 100644 --- a/packages/plugin-calendar/CHANGELOG.md +++ b/packages/plugin-calendar/CHANGELOG.md @@ -1,5 +1,26 @@ # @object-ui/plugin-calendar +## 14.0.0 + +### Patch Changes + +- Updated dependencies [443360a] +- Updated dependencies [c70bca7] +- Updated dependencies [86c69c3] +- Updated dependencies [05e56ca] +- Updated dependencies [a44e7b6] +- Updated dependencies [eef832b] +- Updated dependencies [5971cc4] +- Updated dependencies [6a74160] + - @object-ui/core@14.0.0 + - @object-ui/i18n@14.0.0 + - @object-ui/react@14.0.0 + - @object-ui/types@14.0.0 + - @object-ui/components@14.0.0 + - @object-ui/plugin-detail@14.0.0 + - @object-ui/fields@14.0.0 + - @object-ui/mobile@14.0.0 + ## 13.2.0 ### Patch Changes diff --git a/packages/plugin-calendar/package.json b/packages/plugin-calendar/package.json index bbe05b6ed..6249794bb 100644 --- a/packages/plugin-calendar/package.json +++ b/packages/plugin-calendar/package.json @@ -1,6 +1,6 @@ { "name": "@object-ui/plugin-calendar", - "version": "13.2.0", + "version": "14.0.0", "type": "module", "license": "MIT", "description": "Calendar view plugins for Object UI - includes both ObjectQL-integrated and standalone calendar components", diff --git a/packages/plugin-charts/CHANGELOG.md b/packages/plugin-charts/CHANGELOG.md index bf996f30f..1af2a795d 100644 --- a/packages/plugin-charts/CHANGELOG.md +++ b/packages/plugin-charts/CHANGELOG.md @@ -1,5 +1,22 @@ # @object-ui/plugin-charts +## 14.0.0 + +### Patch Changes + +- Updated dependencies [443360a] +- Updated dependencies [c70bca7] +- Updated dependencies [86c69c3] +- Updated dependencies [05e56ca] +- Updated dependencies [a44e7b6] +- Updated dependencies [5971cc4] +- Updated dependencies [6a74160] + - @object-ui/core@14.0.0 + - @object-ui/i18n@14.0.0 + - @object-ui/react@14.0.0 + - @object-ui/types@14.0.0 + - @object-ui/components@14.0.0 + ## 13.2.0 ### Patch Changes diff --git a/packages/plugin-charts/package.json b/packages/plugin-charts/package.json index 38c2b3f60..061a9b6bc 100644 --- a/packages/plugin-charts/package.json +++ b/packages/plugin-charts/package.json @@ -1,6 +1,6 @@ { "name": "@object-ui/plugin-charts", - "version": "13.2.0", + "version": "14.0.0", "type": "module", "license": "MIT", "description": "Chart components plugin for Object UI, powered by Recharts", diff --git a/packages/plugin-chatbot/CHANGELOG.md b/packages/plugin-chatbot/CHANGELOG.md index 961ea7c66..c05c44e0a 100644 --- a/packages/plugin-chatbot/CHANGELOG.md +++ b/packages/plugin-chatbot/CHANGELOG.md @@ -1,5 +1,144 @@ # @object-ui/plugin-chatbot +## 14.0.0 + +### Minor Changes + +- 7b4fc36: feat(console-ai): ask→build handoff carries conversation context (ADR-0057 P4 / cloud#817) + + The P4 "Open in Builder →" handoff previously carried only the build prompt + an + optional package, so the Builder started cold and the user re-explained + themselves. It now also carries the **source `ask` conversation** as context — + ADR-0057 P4 / cloud#817 — so the build agent's first turn starts with the thread + the user already had. + + - `@object-ui/app-shell`: both handoff sites (the full-page `AiChatPage` and the + console FAB) now append `?parentConversationId=` to the + `/ai/build` URL. The build surface reads it and forwards it to `useObjectChat`; + the existing URL-mirror drops it once the build conversation id is minted, so a + reload never re-carries it. + - `@object-ui/plugin-chatbot`: `useObjectChat` accepts `parentConversationId` and + sends it as `context.parentConversationId` on the **first turn only** (held in a + ref, consumed once) — the backend redeems it into the turn's context and the + client owns history from there. New pure helper `withHandoffContext` (unit + tested) does the non-mutating `context` merge. + + Requires the cloud handoff-context contract (service-ai, cloud#817): the build + agent redeems `context.parentConversationId` into a single system block on its + first turn — ownership-checked, and carrying only the user/assistant text the + user already saw (ADR-0063 governance boundary). Without it the console degrades + cleanly: the id is sent but ignored, and the handoff is a (working) cold start. + +- 7dea792: feat(console-ai): explicit "Open in Builder →" ask→build handoff (ADR-0057 P4) + + When the `ask` agent declines an app-authoring request it now calls the cloud + `suggest_builder` tool (structured decline). The console renders that as an + explicit **"Open in Builder →"** action that opens the full-page build surface + seeded with the handoff prompt — ADR-0063 decline-and-redirect: an explicit, + user-initiated switch, never a silent re-route into authoring. + + - `@object-ui/plugin-chatbot`: `detectBuilderHandoff` lifts the + `{ status:'build_handoff', prompt, packageId? }` result onto the tool + invocation; `ChatbotEnhanced` renders the "Open in Builder →" card and calls a + new `onOpenBuilder` prop (disabled when no host wires it). + - `@object-ui/app-shell`: the full-page `AiChatPage` (`ask`) and the console FAB + wire `onOpenBuilder` to navigate to `/ai/build?package=…&handoffPrompt=…`; the + build surface seeds that prompt as its first message (auto-sent once the + conversation is minted), and the URL-mirror strips `?handoffPrompt` so a reload + never re-sends it. Full ask-conversation context transfer is a later upgrade + (cloud#817); v1 carries the build prompt + optional package. + + Requires the cloud `suggest_builder` signal (service-ai-studio) to light up; the + console degrades cleanly (no card) without it. + +- 9d0fdb1: feat(console-ai): render agent behavior by declared capability (cloud#816 / ADR-0057 "B+") + + `GET /api/v1/ai/agents` now serves per-agent `capabilities`; the console + consumes them instead of hard-coding `isBuildAgent(name)`: + + - `@object-ui/plugin-chatbot`: `AgentDescriptor.capabilities` (normalized from + the catalog) + new `agentHasCapability(agents, name, cap)` — declaration wins + when present; falls back to the legacy `isBuildAgent(name)` check when absent + (older server), so shipping order doesn't matter. + - `@object-ui/app-shell`: the build-doctor drawer + `showDebug` key off + `'debug'`, the FAB's resume-vs-fresh keys off `'resume'`, HomePage's + "Build with AI" availability keys off `'authoring'`. The ADR-0063 product-axis + sites (surface→agent resolver, conversation scope keying, picker availability) + intentionally stay name-based — capability describes RENDERED behavior, not + which product an agent is. + + A future skill-driven build variant now needs no console change. + +- cd778d4: feat(console-ai): package binding chip + inert handoff cards + honest send hint (#2458 / ADR-0057 A1.a) + + Three UX improvements from live magic-flow testing: + + - **A1.a — package binding chip** (`app-shell`): the build surface header shows + the package the conversation is bound to (`📦 `), or **"New app"** when + unbound — so the edit blast-radius is always visible (Claude-Code-shows-the-repo + idiom). The magic flow starts unbound and binds the moment its build mints a + package (`deriveBoundPackageId` reads `?package=` else the latest draft/handoff + result; unit-tested). + - **UX#5 — only the latest handoff card is actionable** (`plugin-chatbot`): when + a thread accumulates several "Open in Builder →" cards, only the newest stays + clickable; older (superseded) cards' buttons are disabled — derived from + message order, so it survives the navigation the button triggers and the pane + remount that follows. A stale prompt in an older card can't be re-fired. + - **UX#7 — honest send hint** (`plugin-chatbot`): the composer already sends on + plain Enter (Shift+Enter = newline); dropped the misleading `⌘` glyph from the + hint so it no longer implies Cmd+Enter. + +### Patch Changes + +- 1273f1e: fix(console-ai): reliable ask→build handoff auto-send + second-handoff context re-carry (ADR-0057 P4) + + Two follow-ups to the P4 "Open in Builder →" handoff: + + - **Auto-send swallow.** The handoff's auto-sent first message could be dropped on + a brand-new build conversation: the seed gated on the async-resolved + `activeAgent`, which can settle _after_ the conversation id is minted, so the + deferred-send replay ran with an empty pending and never re-fired. The seed now + gates on the **route** (`agentSegment`, synchronous) and bumps a `pendingSignal` + that `useDeferredFirstSend` lists in its replay deps, so the seed always fires — + no more empty build conversation on handoff. + + - **Second-handoff re-carry.** A second "Open in Builder →" into the (singleton) + build conversation now re-carries the latest ask context. The transport re-arms + `parentConversationId` on each falsy→truthy transition of the prop (the ask + thread is a singleton, so the same id repeats — the fresh-arrival signal is the + transition the URL-mirror produces, not a changed value), and the seed re-arms + on each new `handoffPrompt`. + + Unit-tested: deferred-send replays a post-id seed via the signal; the transport + re-carries across a strip→re-supply cycle. + +- bfea27f: Make the ask-decline wait feel responsive: live thinking indicator + handoff card the moment `suggest_builder` lands (#2458 item 3). + + When the `ask` agent declines a build-shaped request, the ~20s before the "Open in Builder →" card is dominated by the LLM's time-to-tool-call. During that wait the chat could show dead air — a blank bubble, or the static "执行过程" activity note (a hydrated-history affordance) when the backend streamed a `(called …)` tool-call placeholder. + + `ChatbotEnhanced` now shows the existing live thinking indicator (`ThinkingDots`) whenever a streaming assistant turn has nothing visible yet — including whitespace-only content, a mid-stream `(called …)` placeholder, and hidden reasoning in `summary` mode. The static "执行过程" note is reserved for FINISHED (re-hydrated) tool-call-only turns (#772 preserved). The `builderHandoff` card already renders at `output-available` with no gate on the trailing prose, so it surfaces the instant the tool result arrives; the typing cursor now only paints beside real streaming prose (no lone cursor during the tool phase). + +- 408f4ba: fix(plugin-chatbot): build-result summary truncates on mobile instead of overflowing (#2493) + + The draft-review card's summary line (`built N artifact(s) — …`) is a nowrap + `truncate` span, but its flex row lacked the `min-w-0` that lets `truncate` + actually bite — so on a phone the long summary expanded the chat column past + the viewport and the whole chat scrolled sideways. The span now gets + `min-w-0 flex-1` (truncating within the row) and the action row is `flex-wrap` + so its buttons drop to a new line on a narrow screen rather than forcing + horizontal scroll. Desktop is unchanged (there's room, so nothing wraps or + truncates). + +- Updated dependencies [443360a] +- Updated dependencies [86c69c3] +- Updated dependencies [05e56ca] +- Updated dependencies [a44e7b6] +- Updated dependencies [6a74160] + - @object-ui/core@14.0.0 + - @object-ui/react@14.0.0 + - @object-ui/types@14.0.0 + - @object-ui/components@14.0.0 + ## 13.2.0 ### Patch Changes diff --git a/packages/plugin-chatbot/package.json b/packages/plugin-chatbot/package.json index 43e2b1462..c74d14151 100644 --- a/packages/plugin-chatbot/package.json +++ b/packages/plugin-chatbot/package.json @@ -1,6 +1,6 @@ { "name": "@object-ui/plugin-chatbot", - "version": "13.2.0", + "version": "14.0.0", "type": "module", "license": "MIT", "description": "Chatbot interface plugin for Object UI", diff --git a/packages/plugin-dashboard/CHANGELOG.md b/packages/plugin-dashboard/CHANGELOG.md index fb8faa2e1..73a813a35 100644 --- a/packages/plugin-dashboard/CHANGELOG.md +++ b/packages/plugin-dashboard/CHANGELOG.md @@ -1,5 +1,23 @@ # @object-ui/plugin-dashboard +## 14.0.0 + +### Patch Changes + +- Updated dependencies [443360a] +- Updated dependencies [c70bca7] +- Updated dependencies [86c69c3] +- Updated dependencies [05e56ca] +- Updated dependencies [a44e7b6] +- Updated dependencies [5971cc4] +- Updated dependencies [6a74160] + - @object-ui/core@14.0.0 + - @object-ui/i18n@14.0.0 + - @object-ui/react@14.0.0 + - @object-ui/types@14.0.0 + - @object-ui/components@14.0.0 + - @object-ui/fields@14.0.0 + ## 13.2.0 ### Patch Changes diff --git a/packages/plugin-dashboard/package.json b/packages/plugin-dashboard/package.json index a87595d04..c8a3aefae 100644 --- a/packages/plugin-dashboard/package.json +++ b/packages/plugin-dashboard/package.json @@ -1,6 +1,6 @@ { "name": "@object-ui/plugin-dashboard", - "version": "13.2.0", + "version": "14.0.0", "type": "module", "license": "MIT", "description": "Dashboard plugin for Object UI", diff --git a/packages/plugin-designer/CHANGELOG.md b/packages/plugin-designer/CHANGELOG.md index 85faacc0d..a29ac218f 100644 --- a/packages/plugin-designer/CHANGELOG.md +++ b/packages/plugin-designer/CHANGELOG.md @@ -1,5 +1,26 @@ # @object-ui/plugin-designer +## 14.0.0 + +### Patch Changes + +- Updated dependencies [443360a] +- Updated dependencies [c70bca7] +- Updated dependencies [86c69c3] +- Updated dependencies [05e56ca] +- Updated dependencies [a44e7b6] +- Updated dependencies [5971cc4] +- Updated dependencies [6a74160] + - @object-ui/core@14.0.0 + - @object-ui/i18n@14.0.0 + - @object-ui/react@14.0.0 + - @object-ui/types@14.0.0 + - @object-ui/plugin-grid@14.0.0 + - @object-ui/components@14.0.0 + - @object-ui/fields@14.0.0 + - @object-ui/data-objectstack@14.0.0 + - @object-ui/plugin-form@14.0.0 + ## 13.2.0 ### Patch Changes diff --git a/packages/plugin-designer/package.json b/packages/plugin-designer/package.json index 20794a679..87168cacb 100644 --- a/packages/plugin-designer/package.json +++ b/packages/plugin-designer/package.json @@ -1,6 +1,6 @@ { "name": "@object-ui/plugin-designer", - "version": "13.2.0", + "version": "14.0.0", "type": "module", "license": "MIT", "description": "Visual designer plugin for Object UI with page, data model, process, and report designers plus collaborative editing.", diff --git a/packages/plugin-detail/CHANGELOG.md b/packages/plugin-detail/CHANGELOG.md index 91118a89e..0197bf4e9 100644 --- a/packages/plugin-detail/CHANGELOG.md +++ b/packages/plugin-detail/CHANGELOG.md @@ -1,5 +1,54 @@ # @object-ui/plugin-detail +## 14.0.0 + +### Patch Changes + +- eef832b: 修复记录抽屉绕过甘特图行级锁定的问题(#2436 第 5 项)。 + + - `RecordDetailDrawer` 的编辑/删除能力现在由调用方是否传入 `onFieldSave` / `onDelete` 决定:两者都省略时抽屉严格只读(无内联编辑、无删除入口)。此前抽屉硬编码 `inlineEdit` 与 `showDelete: true`,并无条件向内层 DetailView 传包装函数,导致锁定记录仍可"编辑"(且改动静默丢失)。 + - `ObjectGantt` 对 `lockField` 锁定的行、以及全局 `readOnly` 的甘特图,不再向抽屉传入 `onFieldSave` / `onDelete`,与时间轴上禁止拖拽/调整的行为保持一致。 + +- 5971cc4: i18n: translate the Profile page, honor inline i18n label objects under bare + base-language codes, and localize managed-by badges / record quick actions. + + - `pickLocalized` now upgrades a bare base language (`zh`) to any + region-qualified key sharing the base (`zh-CN`) — runtime language is + normalized to the base code while metadata authors write full BCP-47 tags, + so inline `{ en, 'zh-CN', ... }` label objects previously fell back to + English. + - ProfilePage (`account:profile_card` / `/system/profile`): every hardcoded + string — page title/subtitle, avatar Upload/Replace/Remove, Personal + Information card, Change/Set Password card — now goes through + `useObjectTranslation()` with `profile.*` keys (new namespace in all ten + locale bundles); the lazy-load fallback reuses `common.loading`. + - `ManagedByBadge` chips/tooltips (Config/System/Append-only/Identity) now + resolve through new `managedByBadge.*` keys with `{{provider}}` + interpolation. + - `record:quick_actions` resolves action labels via the + `objects.{object}._actions.{action}.label` convention plus `pickLocalized`, + so object action buttons (Change Password, Enable 2FA, …) localize. + - `record:details` / `record:related_list` / `record:alert` / `ObjectTree` + pass inline label objects through `pickLocalized`. + - Locale bundles: added `managedByBadge` namespace to all ten locales and + backfilled `list.inlineEditShort` / `inlineEditLabel` / + `recordEditingTitle` for ja/es/ko/de/fr/pt/ru/ar. + +- Updated dependencies [443360a] +- Updated dependencies [c70bca7] +- Updated dependencies [86c69c3] +- Updated dependencies [05e56ca] +- Updated dependencies [a44e7b6] +- Updated dependencies [5971cc4] +- Updated dependencies [6a74160] + - @object-ui/core@14.0.0 + - @object-ui/i18n@14.0.0 + - @object-ui/react@14.0.0 + - @object-ui/types@14.0.0 + - @object-ui/components@14.0.0 + - @object-ui/fields@14.0.0 + - @object-ui/permissions@14.0.0 + ## 13.2.0 ### Patch Changes diff --git a/packages/plugin-detail/package.json b/packages/plugin-detail/package.json index 0b6fdf2ab..0a88f1f6a 100644 --- a/packages/plugin-detail/package.json +++ b/packages/plugin-detail/package.json @@ -1,6 +1,6 @@ { "name": "@object-ui/plugin-detail", - "version": "13.2.0", + "version": "14.0.0", "type": "module", "license": "MIT", "description": "DetailView plugin for Object UI - comprehensive detail page with sections, tabs, and related lists", diff --git a/packages/plugin-editor/CHANGELOG.md b/packages/plugin-editor/CHANGELOG.md index b928bd622..ba34b5714 100644 --- a/packages/plugin-editor/CHANGELOG.md +++ b/packages/plugin-editor/CHANGELOG.md @@ -1,5 +1,19 @@ # @object-ui/plugin-editor +## 14.0.0 + +### Patch Changes + +- Updated dependencies [443360a] +- Updated dependencies [86c69c3] +- Updated dependencies [05e56ca] +- Updated dependencies [a44e7b6] +- Updated dependencies [6a74160] + - @object-ui/core@14.0.0 + - @object-ui/react@14.0.0 + - @object-ui/types@14.0.0 + - @object-ui/components@14.0.0 + ## 13.2.0 ### Patch Changes diff --git a/packages/plugin-editor/package.json b/packages/plugin-editor/package.json index 17e5e5e29..e3ca411c1 100644 --- a/packages/plugin-editor/package.json +++ b/packages/plugin-editor/package.json @@ -1,6 +1,6 @@ { "name": "@object-ui/plugin-editor", - "version": "13.2.0", + "version": "14.0.0", "type": "module", "license": "MIT", "description": "Rich text editor plugin for Object UI, powered by Monaco Editor", diff --git a/packages/plugin-form/CHANGELOG.md b/packages/plugin-form/CHANGELOG.md index 2963f7bc0..fcacd3da7 100644 --- a/packages/plugin-form/CHANGELOG.md +++ b/packages/plugin-form/CHANGELOG.md @@ -1,5 +1,24 @@ # @object-ui/plugin-form +## 14.0.0 + +### Patch Changes + +- Updated dependencies [443360a] +- Updated dependencies [c70bca7] +- Updated dependencies [86c69c3] +- Updated dependencies [05e56ca] +- Updated dependencies [a44e7b6] +- Updated dependencies [5971cc4] +- Updated dependencies [6a74160] + - @object-ui/core@14.0.0 + - @object-ui/i18n@14.0.0 + - @object-ui/react@14.0.0 + - @object-ui/types@14.0.0 + - @object-ui/components@14.0.0 + - @object-ui/fields@14.0.0 + - @object-ui/permissions@14.0.0 + ## 13.2.0 ### Patch Changes diff --git a/packages/plugin-form/package.json b/packages/plugin-form/package.json index 4b9f683b1..e20a698db 100644 --- a/packages/plugin-form/package.json +++ b/packages/plugin-form/package.json @@ -1,6 +1,6 @@ { "name": "@object-ui/plugin-form", - "version": "13.2.0", + "version": "14.0.0", "type": "module", "license": "MIT", "description": "Form plugin for Object UI", diff --git a/packages/plugin-gantt/CHANGELOG.md b/packages/plugin-gantt/CHANGELOG.md index 25fe5b376..fb83781e6 100644 --- a/packages/plugin-gantt/CHANGELOG.md +++ b/packages/plugin-gantt/CHANGELOG.md @@ -1,5 +1,65 @@ # @object-ui/plugin-gantt +## 14.0.0 + +### Patch Changes + +- a506e6d: ObjectGantt now supports the `api` data source for **both read and write-back**. + Previously `provider: 'api'` logged "API provider not yet implemented" and rendered + nothing, and every write-back (reschedule, dependency edit, delete, drawer + inline-edit) was hard-wired to the context ObjectQL `dataSource` + `objectName`, + so the api provider's `write` config was never used. + + All reads and writes now flow through a single adapter resolved by + `resolveDataSource(schema.data, dataSource)`: `object` → context DataSource + (unchanged), `api` → `ApiDataSource` (executes the `read`/`write` HttpRequest + config), `value` → in-memory `ValueDataSource`. A pure-api view needs no + `objectName` and no context `dataSource` prop. Object-backed views are behavior- + preserving. Lookup/master_detail quick-filter option domains still resolve from + the context object backend (they degrade to distinct in-row values when absent). + +- 42b36c4: 新增逐任务预警描边(#2436 第 3 项):视图配置 `borderColorField` 指向 + 记录上的预警颜色字段(常为服务端计算的超期/临期字段),该行条形在保留 + 原有填充色的同时,以该颜色描边并加 2px 光晕——任务条、里程碑菱形、 + 汇总条均生效。语义色名(red/orange/…)映射为调色板 hex,其余 CSS 颜色 + 原样透传;空值不描边。开启关键路径高亮时,关键路径样式在其标记行上优先。 +- 8a7d5af: 拖拽连线增加内建校验与宿主否决钩子(#2436 第 1、2 项)。落点为锁定行 + (`locked`)或分组行(`type: 'group'`)时,悬停不再高亮、松手不再创建; + 成环依赖(直接回边、跨层级传递回边)基于**全量任务集**检测并拒绝——不受 + 折叠子树导致可见连线缺边的影响。新增 `onBeforeDependencyCreate(source, +target, type)` 钩子,在内建校验通过后调用,返回 `false` 可否决本次连线 + (即 DHTMLX `onBeforeLinkAdd` / Syncfusion `actionBegin` 惯例)。 + `wouldCreateDependencyCycle` 从 `scheduling` 导出并单测覆盖。 +- eef832b: 修复记录抽屉绕过甘特图行级锁定的问题(#2436 第 5 项)。 + + - `RecordDetailDrawer` 的编辑/删除能力现在由调用方是否传入 `onFieldSave` / `onDelete` 决定:两者都省略时抽屉严格只读(无内联编辑、无删除入口)。此前抽屉硬编码 `inlineEdit` 与 `showDelete: true`,并无条件向内层 DetailView 传包装函数,导致锁定记录仍可"编辑"(且改动静默丢失)。 + - `ObjectGantt` 对 `lockField` 锁定的行、以及全局 `readOnly` 的甘特图,不再向抽屉传入 `onFieldSave` / `onDelete`,与时间轴上禁止拖拽/调整的行为保持一致。 + +- 0b03b34: 快速筛选改为树感知(#2436 第 4 项):命中任务的**全部祖先链**一并保留。 + 此前 `displayTasks` 是平铺过滤,项目/产品等分组行本身没有可筛字段值, + 一筛就被丢掉,命中的子任务成孤儿、树结构被打散。现在祖先随命中下级 + 自动保留、无命中下级时照常剔除,多分支命中共享祖先不重复。 +- 07b2cda: 甘特图写后回读 + 工具栏手动刷新按钮(#2436 第 6/7 项)。 + + - 拖拽改期、依赖增删、抽屉内联编辑、删除记录成功后,静默重新读取数据源,让服务端重算的字段(父级汇总、预警颜色、工期重算)刷新到图上;此前乐观补丁只保留客户端写入的字段,派生字段一直陈旧直到整页刷新。静默刷新不闪 loading、不卸载 GanttView(保留滚动/折叠状态),并发请求按序号防乱序覆盖;失败时保留屏上最后一份好数据。 + - GanttView 工具栏新增手动刷新按钮(`onRefresh` / `refreshing` props),object 数据源自动接线;内联 value 数据无可回读来源,不显示按钮。 + +- Updated dependencies [443360a] +- Updated dependencies [c70bca7] +- Updated dependencies [86c69c3] +- Updated dependencies [05e56ca] +- Updated dependencies [a44e7b6] +- Updated dependencies [eef832b] +- Updated dependencies [5971cc4] +- Updated dependencies [6a74160] + - @object-ui/core@14.0.0 + - @object-ui/i18n@14.0.0 + - @object-ui/react@14.0.0 + - @object-ui/types@14.0.0 + - @object-ui/components@14.0.0 + - @object-ui/plugin-detail@14.0.0 + - @object-ui/fields@14.0.0 + ## 13.2.0 ### Patch Changes diff --git a/packages/plugin-gantt/package.json b/packages/plugin-gantt/package.json index 78d3dec5b..243511db0 100644 --- a/packages/plugin-gantt/package.json +++ b/packages/plugin-gantt/package.json @@ -1,6 +1,6 @@ { "name": "@object-ui/plugin-gantt", - "version": "13.2.0", + "version": "14.0.0", "type": "module", "license": "MIT", "description": "Gantt chart plugin for Object UI", diff --git a/packages/plugin-grid/CHANGELOG.md b/packages/plugin-grid/CHANGELOG.md index 205b1032e..e54e65c84 100644 --- a/packages/plugin-grid/CHANGELOG.md +++ b/packages/plugin-grid/CHANGELOG.md @@ -1,5 +1,30 @@ # @object-ui/plugin-grid +## 14.0.0 + +### Patch Changes + +- 05e56ca: 导出/导入模板的下载文件名与内容本地化。 + + **导出文件名**:CSV/Excel/JSON 导出下载不再是 `<对象名>.<扩展名>`(如 `contracts.csv`),改为「对象显示名-视图名-时间戳.扩展名」(如 `任务-In Progress-20260714-153045.xlsx`);`exportOptions.fileNamePrefix` 配置仍优先(且作为完整前缀,不再追加视图名)。视图名与对象名重复时自动省略;`@object-ui/core` 新增 `buildExportFileName(ext, { prefix, label, objectName, viewLabel }, now?)` 与 `sanitizeFileNameBase(raw)`,ObjectGrid 与 ListView 的所有导出路径(服务端流式与前端兜底)统一走它。app-shell/plugin-view 的 ObjectView 现将当前视图的显示标签写进传给 ListView 的 schema(`label`),使导出文件名能区分同一对象的不同保存视图。 + + **导入模板**:「下载模板」修复两处英文漏出——示例行的 select/多选取值改为优先取选项**显示标签**(如 `准备中`)而非 ASCII slug(`prepare`,服务端导入两者都接受);模板文件名本地化为 `{{object}}-导入模板.csv`(新增 i18n key `grid.import.templateFileName`,英文回退 `{{object}}-import-template.csv`)。 + +- Updated dependencies [443360a] +- Updated dependencies [c70bca7] +- Updated dependencies [86c69c3] +- Updated dependencies [05e56ca] +- Updated dependencies [a44e7b6] +- Updated dependencies [5971cc4] +- Updated dependencies [6a74160] + - @object-ui/core@14.0.0 + - @object-ui/i18n@14.0.0 + - @object-ui/react@14.0.0 + - @object-ui/types@14.0.0 + - @object-ui/components@14.0.0 + - @object-ui/fields@14.0.0 + - @object-ui/mobile@14.0.0 + ## 13.2.0 ### Minor Changes diff --git a/packages/plugin-grid/package.json b/packages/plugin-grid/package.json index 2688e3edf..b62610414 100644 --- a/packages/plugin-grid/package.json +++ b/packages/plugin-grid/package.json @@ -1,6 +1,6 @@ { "name": "@object-ui/plugin-grid", - "version": "13.2.0", + "version": "14.0.0", "type": "module", "license": "MIT", "description": "Grid plugin for Object UI", diff --git a/packages/plugin-kanban/CHANGELOG.md b/packages/plugin-kanban/CHANGELOG.md index 2ef31253d..95c416811 100644 --- a/packages/plugin-kanban/CHANGELOG.md +++ b/packages/plugin-kanban/CHANGELOG.md @@ -1,5 +1,25 @@ # @object-ui/plugin-kanban +## 14.0.0 + +### Patch Changes + +- Updated dependencies [443360a] +- Updated dependencies [c70bca7] +- Updated dependencies [86c69c3] +- Updated dependencies [05e56ca] +- Updated dependencies [a44e7b6] +- Updated dependencies [eef832b] +- Updated dependencies [5971cc4] +- Updated dependencies [6a74160] + - @object-ui/core@14.0.0 + - @object-ui/i18n@14.0.0 + - @object-ui/react@14.0.0 + - @object-ui/types@14.0.0 + - @object-ui/components@14.0.0 + - @object-ui/plugin-detail@14.0.0 + - @object-ui/fields@14.0.0 + ## 13.2.0 ### Patch Changes diff --git a/packages/plugin-kanban/package.json b/packages/plugin-kanban/package.json index c1992ee45..e41c79304 100644 --- a/packages/plugin-kanban/package.json +++ b/packages/plugin-kanban/package.json @@ -1,6 +1,6 @@ { "name": "@object-ui/plugin-kanban", - "version": "13.2.0", + "version": "14.0.0", "type": "module", "license": "MIT", "description": "Kanban board plugin for Object UI, powered by dnd-kit", diff --git a/packages/plugin-list/CHANGELOG.md b/packages/plugin-list/CHANGELOG.md index 57a5b6310..eaa50cf13 100644 --- a/packages/plugin-list/CHANGELOG.md +++ b/packages/plugin-list/CHANGELOG.md @@ -1,5 +1,38 @@ # @object-ui/plugin-list +## 14.0.0 + +### Patch Changes + +- 05e56ca: 导出/导入模板的下载文件名与内容本地化。 + + **导出文件名**:CSV/Excel/JSON 导出下载不再是 `<对象名>.<扩展名>`(如 `contracts.csv`),改为「对象显示名-视图名-时间戳.扩展名」(如 `任务-In Progress-20260714-153045.xlsx`);`exportOptions.fileNamePrefix` 配置仍优先(且作为完整前缀,不再追加视图名)。视图名与对象名重复时自动省略;`@object-ui/core` 新增 `buildExportFileName(ext, { prefix, label, objectName, viewLabel }, now?)` 与 `sanitizeFileNameBase(raw)`,ObjectGrid 与 ListView 的所有导出路径(服务端流式与前端兜底)统一走它。app-shell/plugin-view 的 ObjectView 现将当前视图的显示标签写进传给 ListView 的 schema(`label`),使导出文件名能区分同一对象的不同保存视图。 + + **导入模板**:「下载模板」修复两处英文漏出——示例行的 select/多选取值改为优先取选项**显示标签**(如 `准备中`)而非 ASCII slug(`prepare`,服务端导入两者都接受);模板文件名本地化为 `{{object}}-导入模板.csv`(新增 i18n key `grid.import.templateFileName`,英文回退 `{{object}}-import-template.csv`)。 + +- b66d8ee: The list toolbar search button now shows the active keyword inline (mirroring + the Sort button's count badge). Previously a search term restored from + localStorage after navigating away and back kept filtering the list while the + search popover stayed collapsed — the only cue was a slightly darker magnifier + icon, so users couldn't tell a keyword filter was still active. The keyword is + rendered (truncated at 8rem) next to the magnifier whenever a search is active, + and clicking it opens the popover pre-filled for editing or clearing. +- Updated dependencies [443360a] +- Updated dependencies [c70bca7] +- Updated dependencies [86c69c3] +- Updated dependencies [05e56ca] +- Updated dependencies [a44e7b6] +- Updated dependencies [5971cc4] +- Updated dependencies [6a74160] + - @object-ui/core@14.0.0 + - @object-ui/i18n@14.0.0 + - @object-ui/react@14.0.0 + - @object-ui/types@14.0.0 + - @object-ui/components@14.0.0 + - @object-ui/fields@14.0.0 + - @object-ui/mobile@14.0.0 + - @object-ui/permissions@14.0.0 + ## 13.2.0 ## 13.1.0 diff --git a/packages/plugin-list/package.json b/packages/plugin-list/package.json index d8f8024ef..d63b2e7ed 100644 --- a/packages/plugin-list/package.json +++ b/packages/plugin-list/package.json @@ -1,6 +1,6 @@ { "name": "@object-ui/plugin-list", - "version": "13.2.0", + "version": "14.0.0", "type": "module", "license": "MIT", "description": "ListView plugin for Object UI - unified view component with view type switching", diff --git a/packages/plugin-map/CHANGELOG.md b/packages/plugin-map/CHANGELOG.md index 2e17a071c..92e9682b1 100644 --- a/packages/plugin-map/CHANGELOG.md +++ b/packages/plugin-map/CHANGELOG.md @@ -1,5 +1,19 @@ # @object-ui/plugin-map +## 14.0.0 + +### Patch Changes + +- Updated dependencies [443360a] +- Updated dependencies [86c69c3] +- Updated dependencies [05e56ca] +- Updated dependencies [a44e7b6] +- Updated dependencies [6a74160] + - @object-ui/core@14.0.0 + - @object-ui/react@14.0.0 + - @object-ui/types@14.0.0 + - @object-ui/components@14.0.0 + ## 13.2.0 ### Patch Changes diff --git a/packages/plugin-map/package.json b/packages/plugin-map/package.json index 0a644b9ea..cb90eb3df 100644 --- a/packages/plugin-map/package.json +++ b/packages/plugin-map/package.json @@ -1,6 +1,6 @@ { "name": "@object-ui/plugin-map", - "version": "13.2.0", + "version": "14.0.0", "type": "module", "license": "MIT", "description": "Map visualization plugin for Object UI", diff --git a/packages/plugin-markdown/CHANGELOG.md b/packages/plugin-markdown/CHANGELOG.md index 0cfebdb22..62717d6b2 100644 --- a/packages/plugin-markdown/CHANGELOG.md +++ b/packages/plugin-markdown/CHANGELOG.md @@ -1,5 +1,19 @@ # @object-ui/plugin-markdown +## 14.0.0 + +### Patch Changes + +- Updated dependencies [443360a] +- Updated dependencies [86c69c3] +- Updated dependencies [05e56ca] +- Updated dependencies [a44e7b6] +- Updated dependencies [6a74160] + - @object-ui/core@14.0.0 + - @object-ui/react@14.0.0 + - @object-ui/types@14.0.0 + - @object-ui/components@14.0.0 + ## 13.2.0 ### Patch Changes diff --git a/packages/plugin-markdown/package.json b/packages/plugin-markdown/package.json index 44d68c3a7..f52002b57 100644 --- a/packages/plugin-markdown/package.json +++ b/packages/plugin-markdown/package.json @@ -1,6 +1,6 @@ { "name": "@object-ui/plugin-markdown", - "version": "13.2.0", + "version": "14.0.0", "type": "module", "license": "MIT", "description": "Markdown rendering plugin for Object UI, powered by react-markdown", diff --git a/packages/plugin-report/CHANGELOG.md b/packages/plugin-report/CHANGELOG.md index e23c1cbe9..933e0a884 100644 --- a/packages/plugin-report/CHANGELOG.md +++ b/packages/plugin-report/CHANGELOG.md @@ -1,5 +1,24 @@ # @object-ui/plugin-report +## 14.0.0 + +### Patch Changes + +- Updated dependencies [443360a] +- Updated dependencies [c70bca7] +- Updated dependencies [86c69c3] +- Updated dependencies [05e56ca] +- Updated dependencies [a44e7b6] +- Updated dependencies [5971cc4] +- Updated dependencies [6a74160] + - @object-ui/core@14.0.0 + - @object-ui/i18n@14.0.0 + - @object-ui/react@14.0.0 + - @object-ui/types@14.0.0 + - @object-ui/plugin-grid@14.0.0 + - @object-ui/components@14.0.0 + - @object-ui/fields@14.0.0 + ## 13.2.0 ### Patch Changes diff --git a/packages/plugin-report/package.json b/packages/plugin-report/package.json index ff2c5cc68..772ddf972 100644 --- a/packages/plugin-report/package.json +++ b/packages/plugin-report/package.json @@ -1,6 +1,6 @@ { "name": "@object-ui/plugin-report", - "version": "13.2.0", + "version": "14.0.0", "type": "module", "main": "dist/index.umd.cjs", "module": "dist/index.js", diff --git a/packages/plugin-timeline/CHANGELOG.md b/packages/plugin-timeline/CHANGELOG.md index 8f8fe3b49..cd3ed697c 100644 --- a/packages/plugin-timeline/CHANGELOG.md +++ b/packages/plugin-timeline/CHANGELOG.md @@ -1,5 +1,20 @@ # @object-ui/plugin-timeline +## 14.0.0 + +### Patch Changes + +- Updated dependencies [443360a] +- Updated dependencies [86c69c3] +- Updated dependencies [05e56ca] +- Updated dependencies [a44e7b6] +- Updated dependencies [6a74160] + - @object-ui/core@14.0.0 + - @object-ui/react@14.0.0 + - @object-ui/types@14.0.0 + - @object-ui/components@14.0.0 + - @object-ui/mobile@14.0.0 + ## 13.2.0 ### Patch Changes diff --git a/packages/plugin-timeline/package.json b/packages/plugin-timeline/package.json index 14cb4afe9..7294865c4 100644 --- a/packages/plugin-timeline/package.json +++ b/packages/plugin-timeline/package.json @@ -1,6 +1,6 @@ { "name": "@object-ui/plugin-timeline", - "version": "13.2.0", + "version": "14.0.0", "type": "module", "license": "MIT", "description": "Timeline component plugin for Object UI", diff --git a/packages/plugin-tree/CHANGELOG.md b/packages/plugin-tree/CHANGELOG.md index 02ac04cc1..9cd96ce3b 100644 --- a/packages/plugin-tree/CHANGELOG.md +++ b/packages/plugin-tree/CHANGELOG.md @@ -1,5 +1,44 @@ # @object-ui/plugin-tree +## 14.0.0 + +### Patch Changes + +- 5971cc4: i18n: translate the Profile page, honor inline i18n label objects under bare + base-language codes, and localize managed-by badges / record quick actions. + + - `pickLocalized` now upgrades a bare base language (`zh`) to any + region-qualified key sharing the base (`zh-CN`) — runtime language is + normalized to the base code while metadata authors write full BCP-47 tags, + so inline `{ en, 'zh-CN', ... }` label objects previously fell back to + English. + - ProfilePage (`account:profile_card` / `/system/profile`): every hardcoded + string — page title/subtitle, avatar Upload/Replace/Remove, Personal + Information card, Change/Set Password card — now goes through + `useObjectTranslation()` with `profile.*` keys (new namespace in all ten + locale bundles); the lazy-load fallback reuses `common.loading`. + - `ManagedByBadge` chips/tooltips (Config/System/Append-only/Identity) now + resolve through new `managedByBadge.*` keys with `{{provider}}` + interpolation. + - `record:quick_actions` resolves action labels via the + `objects.{object}._actions.{action}.label` convention plus `pickLocalized`, + so object action buttons (Change Password, Enable 2FA, …) localize. + - `record:details` / `record:related_list` / `record:alert` / `ObjectTree` + pass inline label objects through `pickLocalized`. + - Locale bundles: added `managedByBadge` namespace to all ten locales and + backfilled `list.inlineEditShort` / `inlineEditLabel` / + `recordEditingTitle` for ja/es/ko/de/fr/pt/ru/ar. + +- Updated dependencies [443360a] +- Updated dependencies [86c69c3] +- Updated dependencies [05e56ca] +- Updated dependencies [a44e7b6] +- Updated dependencies [6a74160] + - @object-ui/core@14.0.0 + - @object-ui/react@14.0.0 + - @object-ui/types@14.0.0 + - @object-ui/components@14.0.0 + ## 13.2.0 ### Patch Changes diff --git a/packages/plugin-tree/package.json b/packages/plugin-tree/package.json index 67259fa24..47b813bb7 100644 --- a/packages/plugin-tree/package.json +++ b/packages/plugin-tree/package.json @@ -1,6 +1,6 @@ { "name": "@object-ui/plugin-tree", - "version": "13.2.0", + "version": "14.0.0", "type": "module", "license": "MIT", "description": "Tree / tree-grid visualization plugin for Object UI", diff --git a/packages/plugin-view/CHANGELOG.md b/packages/plugin-view/CHANGELOG.md index 1d2450a00..d9385e35e 100644 --- a/packages/plugin-view/CHANGELOG.md +++ b/packages/plugin-view/CHANGELOG.md @@ -1,5 +1,30 @@ # @object-ui/plugin-view +## 14.0.0 + +### Patch Changes + +- 05e56ca: 导出/导入模板的下载文件名与内容本地化。 + + **导出文件名**:CSV/Excel/JSON 导出下载不再是 `<对象名>.<扩展名>`(如 `contracts.csv`),改为「对象显示名-视图名-时间戳.扩展名」(如 `任务-In Progress-20260714-153045.xlsx`);`exportOptions.fileNamePrefix` 配置仍优先(且作为完整前缀,不再追加视图名)。视图名与对象名重复时自动省略;`@object-ui/core` 新增 `buildExportFileName(ext, { prefix, label, objectName, viewLabel }, now?)` 与 `sanitizeFileNameBase(raw)`,ObjectGrid 与 ListView 的所有导出路径(服务端流式与前端兜底)统一走它。app-shell/plugin-view 的 ObjectView 现将当前视图的显示标签写进传给 ListView 的 schema(`label`),使导出文件名能区分同一对象的不同保存视图。 + + **导入模板**:「下载模板」修复两处英文漏出——示例行的 select/多选取值改为优先取选项**显示标签**(如 `准备中`)而非 ASCII slug(`prepare`,服务端导入两者都接受);模板文件名本地化为 `{{object}}-导入模板.csv`(新增 i18n key `grid.import.templateFileName`,英文回退 `{{object}}-import-template.csv`)。 + +- Updated dependencies [443360a] +- Updated dependencies [c70bca7] +- Updated dependencies [86c69c3] +- Updated dependencies [05e56ca] +- Updated dependencies [a44e7b6] +- Updated dependencies [5971cc4] +- Updated dependencies [6a74160] + - @object-ui/core@14.0.0 + - @object-ui/i18n@14.0.0 + - @object-ui/react@14.0.0 + - @object-ui/types@14.0.0 + - @object-ui/plugin-grid@14.0.0 + - @object-ui/components@14.0.0 + - @object-ui/plugin-form@14.0.0 + ## 13.2.0 ### Patch Changes diff --git a/packages/plugin-view/package.json b/packages/plugin-view/package.json index 7cfdb890c..cbe0cefb7 100644 --- a/packages/plugin-view/package.json +++ b/packages/plugin-view/package.json @@ -1,6 +1,6 @@ { "name": "@object-ui/plugin-view", - "version": "13.2.0", + "version": "14.0.0", "type": "module", "license": "MIT", "description": "Object View plugin for Object UI", diff --git a/packages/providers/CHANGELOG.md b/packages/providers/CHANGELOG.md index bb57cebff..cd3760ad1 100644 --- a/packages/providers/CHANGELOG.md +++ b/packages/providers/CHANGELOG.md @@ -1,5 +1,13 @@ # @object-ui/providers — Changelog +## 14.0.0 + +### Patch Changes + +- Updated dependencies [86c69c3] +- Updated dependencies [6a74160] + - @object-ui/types@14.0.0 + ## 13.2.0 ### Patch Changes diff --git a/packages/providers/package.json b/packages/providers/package.json index 724096826..788548a7e 100644 --- a/packages/providers/package.json +++ b/packages/providers/package.json @@ -1,6 +1,6 @@ { "name": "@object-ui/providers", - "version": "13.2.0", + "version": "14.0.0", "type": "module", "license": "MIT", "description": "Reusable context providers for ObjectUI applications", diff --git a/packages/react-runtime/CHANGELOG.md b/packages/react-runtime/CHANGELOG.md index a384b08dc..47c6df040 100644 --- a/packages/react-runtime/CHANGELOG.md +++ b/packages/react-runtime/CHANGELOG.md @@ -1,5 +1,7 @@ # @object-ui/react-runtime +## 14.0.0 + ## 13.2.0 ## 13.1.0 diff --git a/packages/react-runtime/package.json b/packages/react-runtime/package.json index 5493a39d7..1132a8ebc 100644 --- a/packages/react-runtime/package.json +++ b/packages/react-runtime/package.json @@ -1,6 +1,6 @@ { "name": "@object-ui/react-runtime", - "version": "13.2.0", + "version": "14.0.0", "type": "module", "sideEffects": false, "license": "MIT", diff --git a/packages/react/CHANGELOG.md b/packages/react/CHANGELOG.md index 8e032e648..748a68b5a 100644 --- a/packages/react/CHANGELOG.md +++ b/packages/react/CHANGELOG.md @@ -1,5 +1,33 @@ # @object-ui/react +## 14.0.0 + +### Minor Changes + +- 86c69c3: ADR-0089: read the canonical `visibleWhen` conditional-visibility predicate in the form + page renderers. + + `@objectstack/spec` now unifies conditional visibility under a single canonical key, `visibleWhen`, and folds the deprecated `visibleOn` (view form) / `visibility` (page component) aliases into it at parse. This updates ObjectUI to read the canonical key: + + - **Page renderer** (`SchemaRenderer`) — evaluates `visibleWhen` first (show-when-truthy), then the deprecated `visibleOn` / `visibility` as a defensive read for raw / un-normalized metadata. `visibleWhen` is stripped from DOM props. + - **Spec→node bridges** — the page bridge maps a component's `visibleWhen ?? visibility` onto the node's canonical `visibleWhen`; the form-view bridge maps a field's `visibleWhen ?? visibleOn` onto the ObjectForm view-level predicate slot. + - **Form renderers** — the `@object-ui/react` `FormRenderer` prefers `visibleWhen` over the `visibleOn` alias. (`ObjectForm`/`form.tsx` already evaluated `visibleWhen`.) + - **Types** — the component base schema (`BaseSchema` / `base.zod`) gains the canonical `visibleWhen`; `visibleOn` is marked `@deprecated`. + + Fully back-compat: existing `visibleOn` / `visibility` metadata keeps working through the alias reads. + +### Patch Changes + +- Updated dependencies [443360a] +- Updated dependencies [c70bca7] +- Updated dependencies [86c69c3] +- Updated dependencies [05e56ca] +- Updated dependencies [5971cc4] +- Updated dependencies [6a74160] + - @object-ui/core@14.0.0 + - @object-ui/i18n@14.0.0 + - @object-ui/types@14.0.0 + - @object-ui/data-objectstack@14.0.0 + ## 13.2.0 ### Patch Changes diff --git a/packages/react/package.json b/packages/react/package.json index 0bd67854d..884992e0d 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,6 +1,6 @@ { "name": "@object-ui/react", - "version": "13.2.0", + "version": "14.0.0", "type": "module", "license": "MIT", "description": "React bindings and SchemaRenderer component for Object UI", diff --git a/packages/runner/CHANGELOG.md b/packages/runner/CHANGELOG.md index 8b480e983..5861fbbc1 100644 --- a/packages/runner/CHANGELOG.md +++ b/packages/runner/CHANGELOG.md @@ -1,5 +1,21 @@ # @object-ui/runner +## 14.0.0 + +### Patch Changes + +- Updated dependencies [443360a] +- Updated dependencies [86c69c3] +- Updated dependencies [05e56ca] +- Updated dependencies [a44e7b6] +- Updated dependencies [6a74160] + - @object-ui/core@14.0.0 + - @object-ui/react@14.0.0 + - @object-ui/types@14.0.0 + - @object-ui/components@14.0.0 + - @object-ui/plugin-charts@14.0.0 + - @object-ui/plugin-kanban@14.0.0 + ## 13.2.0 ### Patch Changes diff --git a/packages/runner/package.json b/packages/runner/package.json index cb5a24ff5..0c9dd4350 100644 --- a/packages/runner/package.json +++ b/packages/runner/package.json @@ -1,7 +1,7 @@ { "name": "@object-ui/runner", "private": false, - "version": "13.2.0", + "version": "14.0.0", "description": "Universal Object UI Application Runner", "type": "module", "homepage": "https://www.objectui.org/docs/utilities/runner", diff --git a/packages/sdui-parser/CHANGELOG.md b/packages/sdui-parser/CHANGELOG.md index 9921f04a9..01711e845 100644 --- a/packages/sdui-parser/CHANGELOG.md +++ b/packages/sdui-parser/CHANGELOG.md @@ -1,5 +1,7 @@ # @object-ui/sdui-parser +## 14.0.0 + ## 13.2.0 ## 13.1.0 diff --git a/packages/sdui-parser/package.json b/packages/sdui-parser/package.json index 94a76a590..357018795 100644 --- a/packages/sdui-parser/package.json +++ b/packages/sdui-parser/package.json @@ -1,6 +1,6 @@ { "name": "@object-ui/sdui-parser", - "version": "13.2.0", + "version": "14.0.0", "type": "module", "sideEffects": false, "license": "MIT", diff --git a/packages/tenant/CHANGELOG.md b/packages/tenant/CHANGELOG.md index df079aafd..2a8bacacf 100644 --- a/packages/tenant/CHANGELOG.md +++ b/packages/tenant/CHANGELOG.md @@ -1,5 +1,13 @@ # @object-ui/tenant +## 14.0.0 + +### Patch Changes + +- Updated dependencies [86c69c3] +- Updated dependencies [6a74160] + - @object-ui/types@14.0.0 + ## 13.2.0 ### Patch Changes diff --git a/packages/tenant/package.json b/packages/tenant/package.json index addd7cfd0..10bf75156 100644 --- a/packages/tenant/package.json +++ b/packages/tenant/package.json @@ -1,6 +1,6 @@ { "name": "@object-ui/tenant", - "version": "13.2.0", + "version": "14.0.0", "type": "module", "license": "MIT", "description": "Multi-tenancy support for Object UI with tenant isolation, scoped queries, and custom branding.", diff --git a/packages/types/CHANGELOG.md b/packages/types/CHANGELOG.md index 1b5db87b8..faa8a1891 100644 --- a/packages/types/CHANGELOG.md +++ b/packages/types/CHANGELOG.md @@ -1,5 +1,46 @@ # @object-ui/types +## 14.0.0 + +### Minor Changes + +- 86c69c3: ADR-0089: read the canonical `visibleWhen` conditional-visibility predicate in the form + page renderers. + + `@objectstack/spec` now unifies conditional visibility under a single canonical key, `visibleWhen`, and folds the deprecated `visibleOn` (view form) / `visibility` (page component) aliases into it at parse. This updates ObjectUI to read the canonical key: + + - **Page renderer** (`SchemaRenderer`) — evaluates `visibleWhen` first (show-when-truthy), then the deprecated `visibleOn` / `visibility` as a defensive read for raw / un-normalized metadata. `visibleWhen` is stripped from DOM props. + - **Spec→node bridges** — the page bridge maps a component's `visibleWhen ?? visibility` onto the node's canonical `visibleWhen`; the form-view bridge maps a field's `visibleWhen ?? visibleOn` onto the ObjectForm view-level predicate slot. + - **Form renderers** — the `@object-ui/react` `FormRenderer` prefers `visibleWhen` over the `visibleOn` alias. (`ObjectForm`/`form.tsx` already evaluated `visibleWhen`.) + - **Types** — the component base schema (`BaseSchema` / `base.zod`) gains the canonical `visibleWhen`; `visibleOn` is marked `@deprecated`. + + Fully back-compat: existing `visibleOn` / `visibility` metadata keeps working through the alias reads. + +- 6a74160: Sharing-rule form: pick, don't type. Three new widget-hint field components make + the generic object form render pickers where an admin previously had to type + machine data (driven by the framework `widget` hints on `sys_sharing_rule`; + generalizes the `capability-multiselect` pattern). All degrade to the underlying + `type` renderer when a widget is unregistered. + + - **`object-ref`** — choose a registered object by name (searchable `Combobox`), + backed by the new `DataSource.getObjects()` (`ObjectStackAdapter` lists code- + and DB-defined objects via `/api/v1/meta/object`), falling back to a + `sys_metadata` query. Stores the object's `name`. + - **`filter-condition`** — a visual criteria builder (`FilterBuilder`) scoped to + the fields of the object chosen in a sibling field (via `getObjectSchema`), + round-tripping the stored **MongoDB-style** FilterCondition JSON. Criteria the + builder can't represent (or invalid JSON) fall back to a raw-JSON editor, with + an always-available "Edit as JSON" toggle — nothing is hidden or lost. + - **`recipient-picker`** — a record picker whose target object follows a sibling + `recipient_type` (`user`→sys_user, `team`→sys_team, `business_unit`/ + `unit_and_subordinates`→sys_business_unit, `position`→sys_position), storing the + value the evaluator matches on (a record id, or the position **name**). Resets + the stored id when the type changes. + + Wiring: the three keys join `DATA_SOURCE_FIELD_TYPES` (form.tsx) so the form + threads `dataSource` + `dependentValues` to them, and `INLINE_EXCLUDED_FIELD_TYPES` + (they're authored in the record form, not a grid cell). `DataSource.getObjects()` + is optional on the interface; the ObjectStack adapter implements it. + ## 13.2.0 ## 13.1.0 diff --git a/packages/types/package.json b/packages/types/package.json index 7d318aa78..01cb2816e 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@object-ui/types", - "version": "13.2.0", + "version": "14.0.0", "description": "Pure TypeScript type definitions for Object UI - The Protocol Layer", "type": "module", "sideEffects": false, diff --git a/packages/vscode-extension/CHANGELOG.md b/packages/vscode-extension/CHANGELOG.md index 5b2e7b24c..ff38299be 100644 --- a/packages/vscode-extension/CHANGELOG.md +++ b/packages/vscode-extension/CHANGELOG.md @@ -1,5 +1,16 @@ # Changelog +## 14.0.0 + +### Patch Changes + +- Updated dependencies [443360a] +- Updated dependencies [86c69c3] +- Updated dependencies [05e56ca] +- Updated dependencies [6a74160] + - @object-ui/core@14.0.0 + - @object-ui/types@14.0.0 + ## 13.2.0 ### Patch Changes diff --git a/packages/vscode-extension/package.json b/packages/vscode-extension/package.json index adc195867..f179de64e 100644 --- a/packages/vscode-extension/package.json +++ b/packages/vscode-extension/package.json @@ -2,7 +2,7 @@ "name": "object-ui", "displayName": "Object UI", "description": "VSCode extension for Object UI - Schema-driven UI development with IntelliSense, validation, and live preview", - "version": "13.2.0", + "version": "14.0.0", "publisher": "objectui", "private": true, "icon": "icon.svg",