feat(desktop): merge command menu search into one ranked list - #96153
feat(desktop): merge command menu search into one ranked list#96153puemos wants to merge 1 commit into
Conversation
|
React Doctor found 5 issues in 3 files · 5 warnings. 5 warnings
Reviewed by React Doctor for commit |
🤖 CI report
|
| File | Size | Δ vs base |
|---|---|---|
posthog-app/src/scenes/billing/BillingSection.js |
18.3 KiB | 🟢 -2.9 KiB (-13.9%) |
Posted automatically by build-bundle-size-report · uncompressed bytes from dist-report
✅ Eager graph — within budget
How much code each root ships on the eager path — downloaded and parsed before the surface is interactive. Measured from the esbuild output chunks (post-tree-shake, static imports only); lazy import() / React.lazy chunks are not counted.
| Root | Eager (shipped) | Δ vs base | Budget |
|---|---|---|---|
entry (logged-out pages, app bootstrap)src/index.tsx |
1.50 MiB · 22 files | no change | ███░░░░░░░ 33.2% of 4.51 MiB |
logged-out boot: index + App + bootApp (preloaded by every page, including /login)src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts |
5.25 MiB · 668 files | 🔺 +56 B (+0.0%) | █████████░ 93.3% of 5.63 MiB |
authenticated shell (every logged-in page)src/scenes/AuthenticatedShell.tsx |
7.67 MiB · 2,677 files | 🔺 +809 B (+0.0%) | █████████░ 87.4% of 8.77 MiB |
🟢 node_modules/monaco-editor/ stays out of src/index.tsx
🟢 src/lib/components/ActivityLog/describers stays out of src/index.tsx
🟢 [object Object] stays out of src/index.tsx
🟢 [object Object] stays out of src/index.tsx
🟢 node_modules/monaco-editor/ stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/layout/navigation-3000/navigationLogic.tsx stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 src/scenes/dashboard/dashboardLogic.tsx stays out of src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
🟢 node_modules/monaco-editor/ stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/lib/components/ActivityLog/describers stays out of src/scenes/AuthenticatedShell.tsx
🟢 [object Object] stays out of src/scenes/AuthenticatedShell.tsx
🟢 src/scenes/session-recordings/player/sessionRecordingPlayerLogic.ts stays out of src/scenes/AuthenticatedShell.tsx
🟢 [object Object] stays out of src/scenes/AuthenticatedShell.tsx
🟢 [object Object] stays out of src/scenes/AuthenticatedShell.tsx
Largest files eagerly shipped from src/index.tsx
| Size | File |
|---|---|
| 126.8 KiB | ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js |
| 24.6 KiB | ../node_modules/.pnpm/buffer@6.0.3/node_modules/buffer/index.js |
| 6.3 KiB | ../node_modules/.pnpm/react@18.3.1/node_modules/react/cjs/react.production.min.js |
| 4.5 KiB | ../node_modules/.pnpm/@jspm+core@2.1.0/node_modules/@jspm/core/nodelibs/browser/process.js |
| 3.9 KiB | ../node_modules/.pnpm/scheduler@0.23.2/node_modules/scheduler/cjs/scheduler.production.min.js |
| 1.4 KiB | ../node_modules/.pnpm/base64-js@1.5.1/node_modules/base64-js/index.js |
| 1.3 KiB | src/RootErrorBoundary.tsx |
| 1000 B | src/index.tsx |
| 912 B | ../node_modules/.pnpm/ieee754@1.2.1/node_modules/ieee754/index.js |
| 854 B | src/scenes/ChunkLoadErrorBoundary.tsx |
Largest files eagerly shipped from src/index.tsx + src/scenes/App.tsx + src/scenes/bootApp.ts
| Size | File |
|---|---|
| 276.1 KiB | ../node_modules/.pnpm/posthog-js@1.427.2_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs |
| 267.7 KiB | ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js |
| 255.2 KiB | src/taxonomy/core-filter-definitions-by-group.json |
| 126.8 KiB | ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js |
| 104.4 KiB | src/lib/api.ts |
| 79.1 KiB | src/products.tsx |
| 68.8 KiB | src/lib/lemon-ui/icons/icons.tsx |
| 62.5 KiB | src/lib/utils/eventUsageLogic.ts |
| 38.8 KiB | ../node_modules/.pnpm/@dnd-kit+core@6.0.8_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@dnd-kit/core/dist/core.esm.js |
| 33.9 KiB | ../node_modules/.pnpm/kea@4.0.0-pre.6_patch_hash=139b8d1f1304f9d9da452a9a1244c94ea679dbcb85687d8999563146879fb6f5_react@18.3.1/node_modules/kea/lib/index.cjs.js |
Largest files eagerly shipped from src/scenes/AuthenticatedShell.tsx
| Size | File |
|---|---|
| 276.1 KiB | ../node_modules/.pnpm/posthog-js@1.427.2_@types+react@18.3.27_react@18.3.1/node_modules/posthog-js/dist/module.mjs |
| 267.7 KiB | ../node_modules/.pnpm/@posthog+icons@0.38.0_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@posthog/icons/dist/posthog-icons.es.js |
| 255.2 KiB | src/taxonomy/core-filter-definitions-by-group.json |
| 153.8 KiB | ../node_modules/.pnpm/re2js@0.4.1/node_modules/re2js/build/index.esm.js |
| 126.8 KiB | ../node_modules/.pnpm/react-dom@18.3.1_react@18.3.1/node_modules/react-dom/cjs/react-dom.production.min.js |
| 104.4 KiB | src/lib/api.ts |
| 95.8 KiB | ../packages/quill/packages/quill/dist/index.js |
| 93.3 KiB | ../node_modules/.pnpm/prosemirror-view@1.40.1/node_modules/prosemirror-view/dist/index.js |
| 90.6 KiB | ../node_modules/.pnpm/@tiptap+core@3.20.6_@tiptap+pm@3.20.6/node_modules/@tiptap/core/dist/index.js |
| 79.1 KiB | src/products.tsx |
Posted automatically by check-eager-graph · sizes are eager output bytes (shipped, post-tree-shake) from the esbuild metafile · part of #32479
✅ Toolbar bundle — eager 2.28 MiB within budget
What the toolbar ships to customer pages, measured from the esbuild output (minified, post-tree-shake). The eager set is the entry plus everything statically imported from it — fetched before any feature runs; deferred chunks load lazily. The eager guardrail is 5.72 MiB. Each output file must also stay below 10 MB, where CloudFront stops compressing it. The module boundary is enforced separately by check-toolbar-graph.
| Metric | Size | Δ vs base | Budget |
|---|---|---|---|
| Eager (shipped) entry + static imports |
2.28 MiB · 18 files | 🔺 +56 B (+0.0%) | ████░░░░░░ 39.9% of 5.72 MiB |
| Deferred (lazy) | 2.11 MiB · 45 files | no change | n/a — loads on demand |
Loader dist/toolbar.js |
1.1 KiB | no change | █░░░░░░░░░ 5.8% of 19.5 KiB |
Largest eagerly-shipped chunks
| Size | File |
|---|---|
| 756.4 KiB | dist/toolbar/toolbar-app-TJXV6LBK.css |
| 602.9 KiB | dist/toolbar/chunk-chunk-JWEPY4DI.js |
| 484.7 KiB | dist/toolbar/chunk-chunk-D33R7XDZ.js |
| 136.5 KiB | dist/toolbar/chunk-chunk-YKMCCDSE.js |
| 131.8 KiB | dist/toolbar/chunk-chunk-FDH2IBXT.js |
| 72.2 KiB | dist/toolbar/toolbar-app-5LH6H543.js |
| 69.0 KiB | dist/toolbar/chunk-chunk-TSAL54PB.js |
| 35.6 KiB | dist/toolbar/chunk-chunk-QKSWTRVJ.js |
| 21.0 KiB | dist/toolbar/chunk-chunk-4F5LKQPS.js |
| 6.8 KiB | dist/toolbar/chunk-chunk-DV7IWQNF.js |
Posted automatically by check-toolbar-size · sizes are toolbar output bytes (shipped, post-tree-shake) from the esbuild metafile
✅ Dist folder size — 🔺 +74.1 KiB (+0.0%)
Total size of the built frontend/dist folder (all assets), compared against the base branch.
Total: 1457.54 MiB · 🔺 +74.1 KiB (+0.0%)
ℹ️ MCP UI apps size — 33 app(s), 17665.2 KB JS
Built size of each MCP UI app (main.js + styles.css).
| App | JS | CSS |
|---|---|---|
| debug | 600.0 KB | 195.2 KB |
| action | 458.2 KB | 195.2 KB |
| action-list | 564.9 KB | 195.2 KB |
| cohort | 457.2 KB | 195.2 KB |
| cohort-list | 563.8 KB | 195.2 KB |
| email-template | 457.0 KB | 195.2 KB |
| error-details | 472.9 KB | 195.2 KB |
| error-issue | 457.9 KB | 195.2 KB |
| error-issue-list | 564.7 KB | 195.2 KB |
| experiment | 562.0 KB | 195.2 KB |
| experiment-list | 565.6 KB | 195.2 KB |
| experiment-results | 567.1 KB | 195.2 KB |
| feature-flag | 567.6 KB | 195.2 KB |
| feature-flag-list | 571.4 KB | 195.2 KB |
| feature-flag-testing | 461.4 KB | 195.2 KB |
| inline-scan | 457.7 KB | 195.2 KB |
| insight-actors | 563.0 KB | 195.2 KB |
| invite-email-preview | 456.4 KB | 195.2 KB |
| llm-costs | 560.0 KB | 195.2 KB |
| session-recording | 459.0 KB | 195.2 KB |
| survey | 458.8 KB | 195.2 KB |
| survey-global-stats | 562.7 KB | 195.2 KB |
| survey-list | 565.5 KB | 195.2 KB |
| survey-stats | 562.7 KB | 195.2 KB |
| trace-span | 457.6 KB | 195.2 KB |
| trace-span-list | 564.7 KB | 195.2 KB |
| vision-observation-list | 563.9 KB | 195.2 KB |
| workflow | 457.5 KB | 195.2 KB |
| workflow-list | 564.2 KB | 195.2 KB |
| loops-review | 461.9 KB | 195.2 KB |
| query-results | 756.3 KB | 195.2 KB |
| render-ui | 839.5 KB | 195.2 KB |
| visual-review-snapshots | 462.0 KB | 195.2 KB |
⚠️ Django migration SQL — 2 new migrations to review
We've detected new migrations on this PR. Review the SQL output for each migration:
products/tasks/backend/migrations/0119_alter_tasksearchdocument_kind.py
BEGIN;
--
-- Alter field kind on tasksearchdocument
--
-- (no-op)
COMMIT;products/tasks/backend/migrations/0120_backfill_canvas_search_documents.py
--
-- Raw Python operation
--
-- THIS OPERATION CANNOT BE WRITTEN AS SQLLast updated: 2026-09-07 15:54 UTC (09b9c18)
❌ Django migration risk — blocked migration detected
We've analyzed your migrations for potential risks.
Summary: 0 Safe | 1 Needs Review | 1 Blocked
❌ Blocked
Causes locks or breaks compatibility
tasks.0120_backfill_canvas_search_documents
│ └─ #1 ⚠️ RunPython: RunPython data migration needs review for performance
│
└──> �[91m📋 POSTHOG POLICY VIOLATIONS:�[0m
⚠️ WARNING: atomic=False without CONCURRENTLY operations. This
loses transaction rollback safety. If migration fails midway,
partial changes are committed and retry will fail on non-
idempotent ops. Only use atomic=False if: (1) using CONCURRENTLY,
or (2) intentional for long-running ops with idempotent SQL (IF
NOT EXISTS, WHERE NOT EXISTS). Consider async migrations for
large data backfills instead. If this is an intentional long-
running data migration, add
'tasks.0120_backfill_canvas_search_documents' to posthog/manageme
nt/migration_analysis/atomic_false_acknowledged_migrations.txt to
accept the risk.
⚠️ Needs Review
May have performance impact
tasks.0119_alter_tasksearchdocument_kind
└─ #1 ⚠️ AlterField
Field alteration may cause table locks or data loss (check if changing type or constraints)
model: tasksearchdocument, field: kind, field_type: CharField
📚 How to Deploy These Changes Safely
RunPython:
Use batching for large data migrations:
- Use
.iterator()to avoid loading all rows into memory - Use
.bulk_update()instead of saving individual objects - Batch size: 1,000-10,000 rows per batch
- Add pauses between batches
- Consider background jobs for very large updates (millions of rows)
See the migration safety guide
Last updated: 2026-09-07 15:54 UTC (09b9c18)
480ef8e to
09b9c18
Compare
09b9c18 to
1671c92
Compare
Typing in the command menu split its answers across a remote "Search results" section and the local Tasks and Spaces sections, and every remote row wore the same document icon with no context under it. The palette now ranks tasks, spaces, canvases, pull requests and files into one list, draws each row with the icon and metadata line its task list already uses, and keeps every title to one line.
1671c92 to
6b0a045
Compare
Problem
A person searching in the PostHog Desktop command menu reads a page of near-identical rows. Every remote match wears the same document icon, carries no context under its title, and long titles wrap to three lines with raw Slack links and pasted JSON in them. The same search splits across a "Search results" section at the top and separate Tasks and Spaces sections below, so one answer sits in three places.
Sits on #96121, which ranks the matches and answers with the context a row shows. This PR is the palette half.
Changes
useSearchSectionsbecomesuseSearchRowsand returns rows instead of sections, ranking moves torankResultRows, and the row's types, facts, and metadata line each get their own module.Every row type at once, over invented data, because one project rarely holds all five:
Before, the same query drew a "Search results" block of identical document icons, wrapped titles, and no context, above a separate Tasks section. That screenshot is left out because it carries a reporter's own task titles.
Note
The app updates separately from the backend. Until the base PR deploys, the author, source, run status, and timestamp are absent, and rows fall back to the repository and the space. A canvas row reaching an older client is still a row that opens nothing.
How did you test this code?
useSearchRows.test.tsxcovers the dedupe of a task the palette already lists, the canvas row's space label and open action, spaces-off, and a Slack-linked title read as one line.rankResultRows.test.tscovers the order: an exact title first, a task above a file on an equal title match, a title match above a keyword-only match, and recency as the tie-break.CommandMenu.search.test.tsxrenders the palette and asserts a locally known task leads the list with no repeat below. That is the wiring the hook test cannot reach.title-text.test.tscovers the six title shapes a row has to flatten.Automatic notifications
Docs update
None.
🤖 Agent context
Autonomy: Human-driven (agent-assisted)
/posthog-desktop,/writing-ui-components,/writing-user-facing-copy,/writing-tests,/writing-pr-descriptions,/stacking-prs.Created with PostHog Desktop