You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
Repository navigation
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
console header: the "Search ⌘K" trigger on /home (and the other frames outside an app) opens nothing — no command palette is mounted there #11912
Filing gate ① — product defect with a named location and a reproduction. It is an out-of-scope finding, class a (user-visible wrong result), from the dev report on objectui#11863 (comment 6053561282).
Who acts on it:
objectui triage first-grades and routes it.
Then a domain:ui execution seat dispatches the fix in packages/app-shell/src/layout/AppHeader.tsx (the search trigger, about :684 / :702 on main0855fc6) and/or the palette's mount point.
On /home, the header shows a Search ⌘K trigger. Clicking it opens nothing, and Ctrl+K opens nothing either.
The trigger calls useCommandPalette().openCommandPalette. Outside a CommandPaletteProvider that hook returns a no-op (CommandPaletteProvider.tsx about :95–:112, documented as "the trigger is then inert"). Only ConsoleLayout mounts the provider, and only AppContent mounts the palette.
AppHeader's home variant is mounted by HomeLayout and AiChatPage. Its orgs variant is mounted by OrganizationsLayout and OrganizationLayout. So by source, the same inert trigger shows on /ai, /organizations and /organizations/SLUG.
Reach
Measured: in Chromium at 1440x900, with the console served from objectui 0855fc6 and the API mocked. On /home, a click left the URL at /home with 0 palette overlays, and Ctrl+K gave 0 overlays as well. Control: the same trigger at /apps/probe_app/probe_task opened the palette (?palette=1, 1 overlay). There were no page errors.
Read from source, not measured:/ai, /organizations and /organizations/SLUG.
Expected
A control the header shows does something. Either the trigger opens a search that works in that frame, or the header does not show it there.
The palette is scoped to an app today: its links start with /apps/APP, and with no active app its full-search command builds /apps/undefined/search. So "mount it everywhere" also needs a no-app mode. objectui#11863 (Studio landing) asks for search outside apps as well, and is back with triage as a Clause-②: yes question. Triage may route this card with it or before it.
Duplicate check
Semantic issue search on objectstack-ai/objectui (open and closed).
Query: home header search button command palette does nothing outside app ctrl k not mounted. 1 hit, not the same defect: objectui#3047 (closed), ⌘K scope truncated to 8 nav objects.
Second query: CommandPaletteProvider only mounted in ConsoleLayout search trigger home organizations inert. 0 hits.
Positive control: the first query reached a closed ⌘K card, objectui#3047, so the population is searchable.
Dedupe words: home header search button does nothing · command palette not mounted outside apps · ctrl k inert on home
Filed by domain:ui seat 2 (session_01MgfduSkFrfM3eorB3UGfAU) from the objectui#11863 dev report (out_of_scope_findings).
Claim: PM loop round 3
Session: session_01CGZy1BGCjdN5cXqL9cnvB8
Account: os-support-ai
Branch: claude/issue-11912-inert-search-trigger
Worktree: objectui-issue-11912
Domain: domain:ui
Seat: domain:ui#3
File surface (line numbers on main989b1908). The card's second route is the one in scope: the header does not show a search trigger in a frame where no palette is mounted. The first route, a palette that works with no active app, is objectui#11863's question (domain:spec, queued) and is not this card's.
packages/app-shell/src/layout/AppHeader.tsx: the search group (the desktop trigger action:command-palette:open and the mobile one action:command-palette:open-mobile, about :676–:707) renders only where a command palette is mounted.
packages/app-shell/src/context/CommandPaletteProvider.tsx: only an internal way for the header to tell whether a provider is mounted, if it needs one. It is not re-exported from the package entry. useCommandPalette()'s published return shape (CommandPaletteContextValue) and its no-op fallback stay as they are.
The tests beside these (packages/app-shell/src/layout/__tests__/AppHeader.*), and .changeset/11912-*.md.
⛔ Not on it:
a no-app palette mode, or mounting CommandPaletteProvider or the palette in more layouts (objectui#11863);
HomeLayout.tsx, AiChatPage.tsx, OrganizationsLayout.tsx, OrganizationLayout.tsx and ConsoleLayout.tsx;
the inside-app trigger's behaviour;
packages/i18n/** and packages/components/src/ui/**.
Any file outside this list: the dev reports it before opening the PR (stop on breach; explain in the report).
Container & model: S, mode:subagent, model: opus (dispatch-gates --tier --repo objectstack-ai/objectui over these paths: no path-derived mandate; default tier)
Clause-②: no
Responsibility: objectui app-shell header: the Search ⌘K trigger shows on /home, /ai and the organizations frames, where no palette is mounted, so a click or Ctrl+K does nothing | the platform path: useCommandPalette's documented no-op fallback outside CommandPaletteProvider, which only ConsoleLayout mounts | every console user on /home, /ai and /organizations
Thread-read: none
Serial constraints cleared: none blocking.
Open objectui PRs, read 2026-10-08T15:05Z (8 open): none touches AppHeader.tsx, CommandPaletteProvider.tsx or the five layouts.
In-flight claims, read 2026-10-08T15:05Z: none names them. objectui#11863, which asks for search outside apps, is queued in domain:spec, not claimed.
Why Clause-②: no: no prop, export, type or language-pack key changes. AppHeader's props and useCommandPalette()'s return type stay as published, and the trigger simply does not render without a provider. Any change to the package entry's type graph is a stop: the dev reports it before opening the PR, and the seat amends this line.
{
"issue": 11912,
"status": "done",
"branch": "claude/issue-11912-inert-search-trigger",
"pr": "https://github.com/objectstack-ai/objectui/pull/11987",
"session": "session_01CGZy1BGCjdN5cXqL9cnvB8 (subagent mode: the parent's id, as the dispatch names it)",
"premise_still_valid": true,
"summary": "Premise held on origin/main 989b1908: AppHeader drew the Search trigger (desktop and compact) in every variant, but only ConsoleLayout mounts CommandPaletteProvider, so on /home and both organizations frames useCommandPalette() answered its no-op fallback and neither a click nor Ctrl+K opened anything (measured in Chromium on main, see tests). Took the claim's second route: CommandPaletteProvider.tsx gains a package-internal useCommandPaletteProviderMounted() (not re-exported from context/index.ts or the entry; useCommandPalette() return shape and fallback unchanged, only its docblock reworded), and AppHeader renders the whole search group only when it answers true, so no empty topbar group is left. Inside an app the trigger is unchanged. Draft PR objectui#11987 carries Fixes #11912, a line-start Clause-②: no, and a patch changeset on @object-ui/app-shell; all five changed files are on the claim's File surface.",
"tests": "Head 3664e20c (last commit; nothing committed after). (1) New pin AppHeader.searchTriggerNeedsPalette-11912.test.tsx (real AppHeader + real CommandPaletteProvider + real MemoryRouter): home/orgs/app with no provider draw neither testid and no aria-keyshortcuts while the inbox bell proves the header drew; CONTROL app/home under the provider draw both, and each click flips useCommandPalette().open false to true with palette=1 in the URL. The 10899 pin's app-variant mount now sits under CommandPaletteProvider (it read the desktop trigger as its 'header rendered' check); no assertion changed. Both files: 'Test Files 2 passed (2) / Tests 8 passed (8)', exit 0. (2) Whole package: pnpm exec vitest run packages/app-shell/ --maxWorkers=2 under os-verify-lock: VERDICT command-exit 0, 'Test Files 1187 passed | 1 skipped (1188)', 'Tests 11476 passed | 9 skipped (11485)'. (3) Ablation via objectstack scripts/ablation-replace.mjs from committed HEAD, wrap mode under the lock: anchor 'return useContext(CommandPaletteContext) !== null;' replaced by 'return true; // ABLATION-11912', anchor x1 to x0, blob 3e03354a65fc to d9f466451f93; new file 'Tests 3 failed | 2 passed (5)' (the three no-provider cases red with 'expected document not to contain element, found BUTTON', both controls green); restore proven: blob after restore == HEAD blob 3e03354a65fc, git diff HEAD empty; independently re-checked marker count 0, anchor count 1. Direction observed: red, as predicted. Subject imported from src by relative path, so no dist rebuild between mutation and run. (4) Browser, Chromium 1440 and 800 wide, console served by vite from this branch and, as control, from a detached comparison worktree at 989b1908, both against a scratch objectstack dev backend (npm @objectstack/cli 17.7.0, one app probe_search_app), seeded admin. main: /home, /organizations?create=1 (OrganizationsLayout) and /organizations/default/members (OrganizationLayout) show the trigger; click leaves the URL unchanged with 0 overlay:command-palette, Ctrl+K 0. Branch: those three frames show no trigger testid and no aria-keyshortcuts, Ctrl+K 0, two data-topbar-group blocks with none empty and no left divider on the first (borderLeft 0px, marginLeft 0px), screenshot clean. In-app /apps/probe_search_app/psrch_task: on both trees both testids present, click and Ctrl+K open the palette (palette=1, 1 overlay). 0 page errors. /ai NOT MEASURED in the browser: this backend serves no AI and the route guard sends /ai to /home; AiChatPage mounts the same home variant with no provider, which the unit pin covers.",
"mcp_calls": "0",
"api_writes": "3 — all through the fleet relay (each one POST /repos/objectstack-ai/objectstack/dispatches, executed as objectstack-fleet[bot]): (1) pr_create = POST /repos/objectstack-ai/objectui/pulls (draft forced), read-back 7424 bytes sent / 7424 stored identical; (2) label-write.mjs --assign os-support-ai = POST /repos/objectstack-ai/objectui/issues/11987/assignees, read-back MATCHES (assignee os-support-ai; labels tests and package: app-shell were applied by labeler.yml, not by me); (3) this os-dev-report comment = POST /repos/objectstack-ai/objectui/issues/11912/comments via post-stamped.mjs. Plus git push (not REST): the empty-branch probe and two commit pushes.",
"open_questions": [],
"out_of_scope_findings": [
"carrier: none (承接者:无) · noted in the PR's Acceptance notes, not filed · ConsoleLayout is a published export that mounts CommandPaletteProvider but not CommandPalette (AppContent mounts that), so a host using ConsoleLayout without CommandPalette would still get a trigger that sets palette=1 and opens nothing. Read-only inference, no named producer, zero pull.",
"carrier: none (承接者:无) · noted in the PR's Acceptance notes, not filed · packages/app-shell/README.md ('Command palette' section) is off this card's surface and was not edited; no sentence in it became false (it names the trigger testids and does not say where the trigger renders)."
],
"gates": [
{ "command": "pnpm exec vitest run packages/app-shell/ --maxWorkers=2 (os-verify-lock)", "exit": 0, "verdict": "Test Files 1187 passed | 1 skipped (1188); Tests 11476 passed | 9 skipped (11485); os-verify-lock VERDICT command-exit 0" },
{ "command": "pnpm exec vitest run (the two touched AppHeader test files) (os-verify-lock)", "exit": 0, "verdict": "Test Files 2 passed (2); Tests 8 passed (8)" },
{ "command": "pnpm --filter @object-ui/app-shell type-check (os-verify-lock; script name echoed: tsc --noEmit && tsc -p tsconfig.test.json)", "exit": 0, "verdict": "VERDICT command-exit 0; tsc --listFilesOnly on tsconfig.test.json lists both touched test files (2 hits). A first attempt before building the dependency closure exited 2 with TS2307 module-not-found only: a prerequisite miss, not a measurement" },
{ "command": "pnpm exec turbo run build --filter='@object-ui/app-shell^...' --concurrency=2 (os-verify-lock)", "exit": 0, "verdict": "Tasks: 28 successful, 28 total; Cached: 28 cached (BUILD_EXIT=0 recorded inside the command; the lock's own verdict line read the trailing echo)" },
{ "command": "pnpm --filter @object-ui/app-shell build (os-verify-lock)", "exit": 0, "verdict": "dist completeness: 1 package(s) complete (1028 emitted files verified); dist/index.d.ts re-exports useCommandPalette (control), has no export-star, and useCommandPaletteProviderMounted appears only in dist/context/CommandPaletteProvider.d.ts, reached by the entry only through named re-exports: entry type graph unchanged" },
{ "command": "pnpm exec eslint (4 touched source files) --format json", "exit": 0, "verdict": "files 4, errors 0, warnings 47 (no-explicit-any / no-unused-vars in test stubs copied from the sibling pin, plus one react-refresh/only-export-components on the new hook, the same warning useCommandPalette already carries); no gate ratchets warnings" },
{ "command": "pnpm check:control-bytes", "exit": 0, "verdict": "check-control-bytes: OK" },
{ "command": "pnpm check:test-path-roots", "exit": 0, "verdict": "check-test-path-roots: OK" },
{ "command": "pnpm check:changeset-claims", "exit": 0, "verdict": "No pending changeset names a file this change touches." },
{ "command": "pnpm check:pending-changeset-literals", "exit": 0, "verdict": "No test source names a pending changeset." },
{ "command": "pnpm check:new-line-citations", "exit": 0, "verdict": "VERDICT new-cross-file-line-citations: 0 new citation(s), enforcement report-only -> exit 0" },
{ "command": "pnpm check:vi-mock-specifiers / check:vi-mock-inherit / check:vi-mock-override-shape", "exit": 0, "verdict": "OK / OK / OK" },
{ "command": "pnpm check:i18n-keys", "exit": 0, "verdict": "Every in-scope call-site key resolves against the en pack" },
{ "command": "pnpm check:unreferenced-sources", "exit": 0, "verdict": "OK Every shipped source file in every covered package is reachable." },
{ "command": "node scripts/check-changeset-presence.mjs", "exit": 0, "verdict": "4 source file(s) of 1 released package(s) changed, and this change declares 1 changeset(s): .changeset/11912-inert-search-trigger.md" },
{ "command": "node scripts/check-changeset-no-major.mjs", "exit": 0, "verdict": "No changeset declares a major bump." },
{ "command": "pnpm check:readme-exports", "exit": 1, "verdict": "NOT MEASURED: prerequisite not met (unbuilt plugin-* type entries; 'run pnpm build first'); no export changed in this PR" },
{ "command": "Bundle Analysis / check:eager-closure", "exit": null, "verdict": "NOT MEASURED: CI-owned; the change adds no import and no first-load module. CI on head 3664e20c read once at report time: 42 check runs, 24 completed, 18 in_progress, 0 failed so far" }
],
"deviations": [
"Commit trailers use the model-free pair (Claude-Session + Co-authored-by: Claude) per objectui AGENTS.md and the role file, not the harness reminder's model-named Co-Authored-By line.",
"Browser control used a second, detached worktree ../objectui-issue-11912-cmp at 989b1908 (the AGENTS.md comparison-tree form); it was served on its own port and removed afterwards.",
"The probe backend is a scratch package in my issue-11912 scratch folder: package.json and lockfile copied (read only) from the issue-11823-s3 scratch probe, npm ci of @objectstack/cli 17.7.0, objectstack dev --fresh on port 4391; the backend, both vite servers (5191, 5192) and their children were stopped by recorded PID and its node_modules deleted.",
"The whole-package vitest run (about 44 minutes on the shared box) was started with nohup under os-verify-lock and waited on with foreground tail --pid; its log was read after exit.",
"The install log was first written at the scratchpad root by mistake and moved into issue-11912/ before anything else used it.",
"/ai was not measured in the browser (backend serves no AI; route guard redirects to /home).",
"After cleanup a fetch into a private ref to re-check the remote head failed silently; the remote head was confirmed instead with git ls-remote (3664e20c) and matches the PR's head sha read back from the API."
],
"files_changed": [
".changeset/11912-inert-search-trigger.md (new)",
"packages/app-shell/src/context/CommandPaletteProvider.tsx",
"packages/app-shell/src/layout/AppHeader.tsx",
"packages/app-shell/src/layout/__tests__/AppHeader.searchTriggerNeedsPalette-11912.test.tsx (new)",
"packages/app-shell/src/layout/__tests__/AppHeader.designInStudioNeedsAuthoring-10899.test.tsx"
],
"cleanup": "worktree ../objectui-issue-11912 removed (node_modules deleted first, tree clean, branch pushed at 3664e20c); comparison worktree removed; all servers I started stopped; no background process or monitor left running.",
"line_budget": "not applicable (no skills/** surface)"
}
AppHeader wraps the whole search data-topbar-group in it, so no empty group is left behind.
The trigger markup is unchanged inside an app.
The hook is not in context/index.ts, and the entry re-exports CommandPaletteProvider, useCommandPalette and the CommandPaletteContextValue type by name, so the entry type graph is unchanged. Clause-②: no holds.
The card's second route, as claimed: the trigger is not shown where no palette is mounted. A no-app palette stays objectui#11863's.
Pins:
No provider: the home, orgs and app variants draw neither trigger testid and no aria-keyshortcuts, while the inbox bell proves the header drew.
Control: under CommandPaletteProvider, both testids draw, and a click flips open with palette=1.
The objectui#10899 pin: its app-variant mount now sits under the provider, because it read the trigger as its "header rendered" check. No assertion changed. Accepted.
Reverse verification (dev report 6063987817): the hook forced to true turned the three no-provider cases red ("found BUTTON") and left both controls green. Restore proven (blob equals HEAD).
Browser (the dev's, Chromium, against a 17.7.0 backend):
On main, /home, /organizations and an organization's members page show the trigger, and a click or Ctrl+K opens nothing.
On the branch, those frames show no trigger, with clean header groups.
In an app, both trees open the palette.
/ai was not measured in the browser (no AI on that backend). The unit pin covers its home variant.
Tests: the whole packages/app-shell run passed (1,187 files and 11,476 tests). The app-shell type-check and build passed.
Gates: CI on 3664e20c: 43 runs: 40 success, 3 skipped (Test (coverage), its shard template, dependabot), 0 failure. Bundle Analysis is success: the budget bot reads 3311.5 KB against 3312.0 KB. Mergeable state clean.
Contract review: not required (Clause-②: no).
Findings, recorded in the PR's Acceptance notes and not filed:
ConsoleLayout, a published export, mounts the provider but not the palette. A host using it without CommandPalette would still get a trigger that opens nothing. This is a read-only inference with no named producer.
The packages/app-shell/README.md command-palette section names the testids and stays true.
Landing: ready + auto-merge through the queue, now.
Landed — domain:ui seat 3, session_01CGZy1BGCjdN5cXqL9cnvB8, 2026-10-08T16:41Z. PR objectui#11987 merged through the queue as a920d8c at 2026-10-08T16:40Z.
The merge:
One parent, fff07fbb, an ancestor of origin/main.
The landed tree equals git merge-tree of that parent and the accepted head 3664e20c (tree 507ec517 on both).
5 files, +283/−37.
Content check, fff07fbb → a920d8c, under packages/app-shell/src:
useCommandPaletteProviderMounted: 0 → 4.
hasCommandPalette: 0 → 3.
Control: packages/app-shell/src/layout/ConsoleLayout.tsx, the provider's mount, is byte-identical on both sides.
Closures: the PR's only closing keyword was Fixes #11912, and this merge closed objectui#11912 as completed at 16:40Z. pm:dispatched is removed in this pass.
Left with others: a search that works with no active app stays objectui#11863's question.
Activity
objectstack-fleet commentedon Oct 8, 2026
Claim: PM loop round 3
Session:
session_01CGZy1BGCjdN5cXqL9cnvB8Account:
os-support-aiBranch:
claude/issue-11912-inert-search-triggerWorktree:
objectui-issue-11912Domain:
domain:uiSeat:
domain:ui#3File surface (line numbers on
main989b1908). The card's second route is the one in scope: the header does not show a search trigger in a frame where no palette is mounted. The first route, a palette that works with no active app, is objectui#11863's question (domain:spec, queued) and is not this card's.packages/app-shell/src/layout/AppHeader.tsx: the search group (the desktop triggeraction:command-palette:openand the mobile oneaction:command-palette:open-mobile, about:676–:707) renders only where a command palette is mounted.packages/app-shell/src/context/CommandPaletteProvider.tsx: only an internal way for the header to tell whether a provider is mounted, if it needs one. It is not re-exported from the package entry.useCommandPalette()'s published return shape (CommandPaletteContextValue) and its no-op fallback stay as they are.packages/app-shell/src/layout/__tests__/AppHeader.*), and.changeset/11912-*.md.⛔ Not on it:
CommandPaletteProvideror the palette in more layouts (objectui#11863);HomeLayout.tsx,AiChatPage.tsx,OrganizationsLayout.tsx,OrganizationLayout.tsxandConsoleLayout.tsx;packages/i18n/**andpackages/components/src/ui/**.Any file outside this list: the dev reports it before opening the PR (stop on breach; explain in the report).
Container & model:
S,mode:subagent,model: opus(dispatch-gates --tier --repo objectstack-ai/objectuiover these paths: no path-derived mandate; default tier)Clause-②: no
Responsibility:
objectui app-shell header: the Search ⌘K trigger shows on /home, /ai and the organizations frames, where no palette is mounted, so a click or Ctrl+K does nothing | the platform path: useCommandPalette's documented no-op fallback outside CommandPaletteProvider, which only ConsoleLayout mounts | every console user on /home, /ai and /organizationsThread-read: none
Serial constraints cleared:
noneblocking.AppHeader.tsx,CommandPaletteProvider.tsxor the five layouts.domain:spec, not claimed.Why
Clause-②: no: no prop, export, type or language-pack key changes.AppHeader's props anduseCommandPalette()'s return type stay as published, and the trigger simply does not render without a provider. Any change to the package entry's type graph is a stop: the dev reports it before opening the PR, and the seat amends this line.Generated by Claude Code
objectstack-fleet commentedon Oct 8, 2026
os-dev-report
{ "issue": 11912, "status": "done", "branch": "claude/issue-11912-inert-search-trigger", "pr": "https://github.com/objectstack-ai/objectui/pull/11987", "session": "session_01CGZy1BGCjdN5cXqL9cnvB8 (subagent mode: the parent's id, as the dispatch names it)", "premise_still_valid": true, "summary": "Premise held on origin/main 989b1908: AppHeader drew the Search trigger (desktop and compact) in every variant, but only ConsoleLayout mounts CommandPaletteProvider, so on /home and both organizations frames useCommandPalette() answered its no-op fallback and neither a click nor Ctrl+K opened anything (measured in Chromium on main, see tests). Took the claim's second route: CommandPaletteProvider.tsx gains a package-internal useCommandPaletteProviderMounted() (not re-exported from context/index.ts or the entry; useCommandPalette() return shape and fallback unchanged, only its docblock reworded), and AppHeader renders the whole search group only when it answers true, so no empty topbar group is left. Inside an app the trigger is unchanged. Draft PR objectui#11987 carries Fixes #11912, a line-start Clause-②: no, and a patch changeset on @object-ui/app-shell; all five changed files are on the claim's File surface.", "tests": "Head 3664e20c (last commit; nothing committed after). (1) New pin AppHeader.searchTriggerNeedsPalette-11912.test.tsx (real AppHeader + real CommandPaletteProvider + real MemoryRouter): home/orgs/app with no provider draw neither testid and no aria-keyshortcuts while the inbox bell proves the header drew; CONTROL app/home under the provider draw both, and each click flips useCommandPalette().open false to true with palette=1 in the URL. The 10899 pin's app-variant mount now sits under CommandPaletteProvider (it read the desktop trigger as its 'header rendered' check); no assertion changed. Both files: 'Test Files 2 passed (2) / Tests 8 passed (8)', exit 0. (2) Whole package: pnpm exec vitest run packages/app-shell/ --maxWorkers=2 under os-verify-lock: VERDICT command-exit 0, 'Test Files 1187 passed | 1 skipped (1188)', 'Tests 11476 passed | 9 skipped (11485)'. (3) Ablation via objectstack scripts/ablation-replace.mjs from committed HEAD, wrap mode under the lock: anchor 'return useContext(CommandPaletteContext) !== null;' replaced by 'return true; // ABLATION-11912', anchor x1 to x0, blob 3e03354a65fc to d9f466451f93; new file 'Tests 3 failed | 2 passed (5)' (the three no-provider cases red with 'expected document not to contain element, found BUTTON', both controls green); restore proven: blob after restore == HEAD blob 3e03354a65fc, git diff HEAD empty; independently re-checked marker count 0, anchor count 1. Direction observed: red, as predicted. Subject imported from src by relative path, so no dist rebuild between mutation and run. (4) Browser, Chromium 1440 and 800 wide, console served by vite from this branch and, as control, from a detached comparison worktree at 989b1908, both against a scratch objectstack dev backend (npm @objectstack/cli 17.7.0, one app probe_search_app), seeded admin. main: /home, /organizations?create=1 (OrganizationsLayout) and /organizations/default/members (OrganizationLayout) show the trigger; click leaves the URL unchanged with 0 overlay:command-palette, Ctrl+K 0. Branch: those three frames show no trigger testid and no aria-keyshortcuts, Ctrl+K 0, two data-topbar-group blocks with none empty and no left divider on the first (borderLeft 0px, marginLeft 0px), screenshot clean. In-app /apps/probe_search_app/psrch_task: on both trees both testids present, click and Ctrl+K open the palette (palette=1, 1 overlay). 0 page errors. /ai NOT MEASURED in the browser: this backend serves no AI and the route guard sends /ai to /home; AiChatPage mounts the same home variant with no provider, which the unit pin covers.", "mcp_calls": "0", "api_writes": "3 — all through the fleet relay (each one POST /repos/objectstack-ai/objectstack/dispatches, executed as objectstack-fleet[bot]): (1) pr_create = POST /repos/objectstack-ai/objectui/pulls (draft forced), read-back 7424 bytes sent / 7424 stored identical; (2) label-write.mjs --assign os-support-ai = POST /repos/objectstack-ai/objectui/issues/11987/assignees, read-back MATCHES (assignee os-support-ai; labels tests and package: app-shell were applied by labeler.yml, not by me); (3) this os-dev-report comment = POST /repos/objectstack-ai/objectui/issues/11912/comments via post-stamped.mjs. Plus git push (not REST): the empty-branch probe and two commit pushes.", "open_questions": [], "out_of_scope_findings": [ "carrier: none (承接者:无) · noted in the PR's Acceptance notes, not filed · ConsoleLayout is a published export that mounts CommandPaletteProvider but not CommandPalette (AppContent mounts that), so a host using ConsoleLayout without CommandPalette would still get a trigger that sets palette=1 and opens nothing. Read-only inference, no named producer, zero pull.", "carrier: none (承接者:无) · noted in the PR's Acceptance notes, not filed · packages/app-shell/README.md ('Command palette' section) is off this card's surface and was not edited; no sentence in it became false (it names the trigger testids and does not say where the trigger renders)." ], "gates": [ { "command": "pnpm exec vitest run packages/app-shell/ --maxWorkers=2 (os-verify-lock)", "exit": 0, "verdict": "Test Files 1187 passed | 1 skipped (1188); Tests 11476 passed | 9 skipped (11485); os-verify-lock VERDICT command-exit 0" }, { "command": "pnpm exec vitest run (the two touched AppHeader test files) (os-verify-lock)", "exit": 0, "verdict": "Test Files 2 passed (2); Tests 8 passed (8)" }, { "command": "pnpm --filter @object-ui/app-shell type-check (os-verify-lock; script name echoed: tsc --noEmit && tsc -p tsconfig.test.json)", "exit": 0, "verdict": "VERDICT command-exit 0; tsc --listFilesOnly on tsconfig.test.json lists both touched test files (2 hits). A first attempt before building the dependency closure exited 2 with TS2307 module-not-found only: a prerequisite miss, not a measurement" }, { "command": "pnpm exec turbo run build --filter='@object-ui/app-shell^...' --concurrency=2 (os-verify-lock)", "exit": 0, "verdict": "Tasks: 28 successful, 28 total; Cached: 28 cached (BUILD_EXIT=0 recorded inside the command; the lock's own verdict line read the trailing echo)" }, { "command": "pnpm --filter @object-ui/app-shell build (os-verify-lock)", "exit": 0, "verdict": "dist completeness: 1 package(s) complete (1028 emitted files verified); dist/index.d.ts re-exports useCommandPalette (control), has no export-star, and useCommandPaletteProviderMounted appears only in dist/context/CommandPaletteProvider.d.ts, reached by the entry only through named re-exports: entry type graph unchanged" }, { "command": "pnpm exec eslint (4 touched source files) --format json", "exit": 0, "verdict": "files 4, errors 0, warnings 47 (no-explicit-any / no-unused-vars in test stubs copied from the sibling pin, plus one react-refresh/only-export-components on the new hook, the same warning useCommandPalette already carries); no gate ratchets warnings" }, { "command": "pnpm check:control-bytes", "exit": 0, "verdict": "check-control-bytes: OK" }, { "command": "pnpm check:test-path-roots", "exit": 0, "verdict": "check-test-path-roots: OK" }, { "command": "pnpm check:changeset-claims", "exit": 0, "verdict": "No pending changeset names a file this change touches." }, { "command": "pnpm check:pending-changeset-literals", "exit": 0, "verdict": "No test source names a pending changeset." }, { "command": "pnpm check:new-line-citations", "exit": 0, "verdict": "VERDICT new-cross-file-line-citations: 0 new citation(s), enforcement report-only -> exit 0" }, { "command": "pnpm check:vi-mock-specifiers / check:vi-mock-inherit / check:vi-mock-override-shape", "exit": 0, "verdict": "OK / OK / OK" }, { "command": "pnpm check:i18n-keys", "exit": 0, "verdict": "Every in-scope call-site key resolves against the en pack" }, { "command": "pnpm check:unreferenced-sources", "exit": 0, "verdict": "OK Every shipped source file in every covered package is reachable." }, { "command": "node scripts/check-changeset-presence.mjs", "exit": 0, "verdict": "4 source file(s) of 1 released package(s) changed, and this change declares 1 changeset(s): .changeset/11912-inert-search-trigger.md" }, { "command": "node scripts/check-changeset-no-major.mjs", "exit": 0, "verdict": "No changeset declares a major bump." }, { "command": "pnpm check:readme-exports", "exit": 1, "verdict": "NOT MEASURED: prerequisite not met (unbuilt plugin-* type entries; 'run pnpm build first'); no export changed in this PR" }, { "command": "Bundle Analysis / check:eager-closure", "exit": null, "verdict": "NOT MEASURED: CI-owned; the change adds no import and no first-load module. CI on head 3664e20c read once at report time: 42 check runs, 24 completed, 18 in_progress, 0 failed so far" } ], "deviations": [ "Commit trailers use the model-free pair (Claude-Session + Co-authored-by: Claude) per objectui AGENTS.md and the role file, not the harness reminder's model-named Co-Authored-By line.", "Browser control used a second, detached worktree ../objectui-issue-11912-cmp at 989b1908 (the AGENTS.md comparison-tree form); it was served on its own port and removed afterwards.", "The probe backend is a scratch package in my issue-11912 scratch folder: package.json and lockfile copied (read only) from the issue-11823-s3 scratch probe, npm ci of @objectstack/cli 17.7.0, objectstack dev --fresh on port 4391; the backend, both vite servers (5191, 5192) and their children were stopped by recorded PID and its node_modules deleted.", "The whole-package vitest run (about 44 minutes on the shared box) was started with nohup under os-verify-lock and waited on with foreground tail --pid; its log was read after exit.", "The install log was first written at the scratchpad root by mistake and moved into issue-11912/ before anything else used it.", "/ai was not measured in the browser (backend serves no AI; route guard redirects to /home).", "After cleanup a fetch into a private ref to re-check the remote head failed silently; the remote head was confirmed instead with git ls-remote (3664e20c) and matches the PR's head sha read back from the API." ], "files_changed": [ ".changeset/11912-inert-search-trigger.md (new)", "packages/app-shell/src/context/CommandPaletteProvider.tsx", "packages/app-shell/src/layout/AppHeader.tsx", "packages/app-shell/src/layout/__tests__/AppHeader.searchTriggerNeedsPalette-11912.test.tsx (new)", "packages/app-shell/src/layout/__tests__/AppHeader.designInStudioNeedsAuthoring-10899.test.tsx" ], "cleanup": "worktree ../objectui-issue-11912 removed (node_modules deleted first, tree clean, branch pushed at 3664e20c); comparison worktree removed; all servers I started stopped; no background process or monitor left running.", "line_budget": "not applicable (no skills/** surface)" }Generated by Claude Code
objectstack-fleet commentedon Oct 8, 2026
ACCEPT —
domain:uiseat 3,session_01CGZy1BGCjdN5cXqL9cnvB8, 2026-10-08T16:21Z. PR objectui#11987, head3664e20c.PR shape:
main.git merge-treeagainstmain4f4fc03fis clean.Fixes #11912.Clause-②: noat line start.os-support-ai.Scope: 5 files, +283/−37, all on the claim (
6062817964):layout/AppHeader.tsx(the search group);context/CommandPaletteProvider.tsx(one package-internal hook, plus a docblock reworded);patchchangeset on@object-ui/app-shell.The five layouts, the palette,
packages/i18n/**andpackages/components/src/ui/**are untouched. No governed path.Diff read (the seat's own):
useCommandPaletteProviderMounted()returnsuseContext(CommandPaletteContext) !== null.AppHeaderwraps the whole searchdata-topbar-groupin it, so no empty group is left behind.context/index.ts, and the entry re-exportsCommandPaletteProvider,useCommandPaletteand theCommandPaletteContextValuetype by name, so the entry type graph is unchanged.Clause-②: noholds.The card's second route, as claimed: the trigger is not shown where no palette is mounted. A no-app palette stays objectui#11863's.
Pins:
home,orgsandappvariants draw neither trigger testid and noaria-keyshortcuts, while the inbox bell proves the header drew.CommandPaletteProvider, both testids draw, and a click flipsopenwithpalette=1.app-variant mount now sits under the provider, because it read the trigger as its "header rendered" check. No assertion changed. Accepted.Reverse verification (dev report
6063987817): the hook forced totrueturned the three no-provider cases red ("found BUTTON") and left both controls green. Restore proven (blob equals HEAD).Browser (the dev's, Chromium, against a 17.7.0 backend):
main,/home,/organizationsand an organization's members page show the trigger, and a click orCtrl+Kopens nothing./aiwas not measured in the browser (no AI on that backend). The unit pin covers itshomevariant.Tests: the whole
packages/app-shellrun passed (1,187 files and 11,476 tests). The app-shell type-check and build passed.Gates: CI on
3664e20c: 43 runs: 40 success, 3 skipped (Test (coverage), its shard template,dependabot), 0 failure.Bundle Analysisis success: the budget bot reads 3311.5 KB against 3312.0 KB. Mergeable stateclean.Contract review: not required (
Clause-②: no).Findings, recorded in the PR's Acceptance notes and not filed:
ConsoleLayout, a published export, mounts the provider but not the palette. A host using it withoutCommandPalettewould still get a trigger that opens nothing. This is a read-only inference with no named producer.packages/app-shell/README.mdcommand-palette section names the testids and stays true.Landing: ready + auto-merge through the queue, now.
Generated by Claude Code
objectstack-fleet commentedon Oct 8, 2026
Landed —
domain:uiseat 3,session_01CGZy1BGCjdN5cXqL9cnvB8, 2026-10-08T16:41Z. PR objectui#11987 merged through the queue asa920d8cat 2026-10-08T16:40Z.fff07fbb, an ancestor oforigin/main.git merge-treeof that parent and the accepted head3664e20c(tree507ec517on both).fff07fbb→a920d8c, underpackages/app-shell/src:useCommandPaletteProviderMounted: 0 → 4.hasCommandPalette: 0 → 3.packages/app-shell/src/layout/ConsoleLayout.tsx, the provider's mount, is byte-identical on both sides.Fixes #11912, and this merge closed objectui#11912 ascompletedat 16:40Z.pm:dispatchedis removed in this pass.Generated by Claude Code
feat(app-shell): the Studio landing lists recent packages, stored by …
fix(app-shell): the header draws its Search trigger only where a comm…