Skip to content

perf(commands): cache app/settings discovery metadata - #615

Closed
JustYannicc wants to merge 121 commits into
SuperCmdLabs:mainfrom
JustYannicc:codex/perf-command-discovery-cache-wave5
Closed

perf(commands): cache app/settings discovery metadata#615
JustYannicc wants to merge 121 commits into
SuperCmdLabs:mainfrom
JustYannicc:codex/perf-command-discovery-cache-wave5

Conversation

@JustYannicc

Copy link
Copy Markdown
Collaborator

What changed

  • Added a signature-keyed in-process discovery metadata cache for parsed plist JSON, NSBundle/JXA display-name lookups, and localized search-terms path resolution.
  • Reused the shared plist reader for CFBundleIcon metadata so app/settings discovery and icon extraction do not spawn duplicate plutil reads for the same Info.plist.
  • Added scripts/test-command-discovery-metadata-cache.mjs, a synthetic .app / .appex / .prefPane benchmark and regression harness that reports subprocess calls, plist reads, elapsed ms, and command parity.

Why

Full command refresh paths can still be expensive when the command disk cache is cold, stale, invalidated, or app search scope changes. This reduces repeated plutil/osascript work while keeping the existing command disk cache and icon cache behavior intact.

Compatibility impact

  • Preserves the existing display-name order: NSBundle/JXA lookup first, then local InfoPlist/Localizable fallback files.
  • Preserves Raycast command shape, icon extraction caching, and _bundlePath cleanup before command disk caching.
  • Adds test-only discovery hooks; runtime discovery roots and app scope are unchanged.
  • Rejected local-files-before-JXA because the existing NSBundle-first behavior is more compatible with macOS localization.
  • Rejected a persistent disk metadata cache for this wave because stale invalidation across localized resources has higher compatibility risk than the in-process signature cache.
  • Rejected wiring .searchTerms into full settings discovery because it is currently a dormant helper and doing so would expand behavior beyond the perf scope.

How tested

  • node scripts/test-command-discovery-metadata-cache.mjs
  • node scripts/test-command-metadata-cache.mjs && node scripts/test-extension-command-refresh-cache.mjs
  • node scripts/run-node-tests.mjs --exclude-perf
  • ./node_modules/.bin/tsc -p tsconfig.main.json --noEmit --pretty false
  • ./node_modules/.bin/tsc -p tsconfig.renderer.json --noEmit --pretty false
  • git diff --check
  • LSP diagnostics on src/main/commands.ts and scripts/test-command-discovery-metadata-cache.mjs: no diagnostics

Performance evidence

Initial harness before cache changes: cold/no disk cache 11.431 ms, 19 subprocess calls, 11 plist reads; repeat refresh 8.735 ms, 15 subprocess calls, 9 plist reads, with command parity.

Final harness, cache disabled vs enabled on the expanded fixture:

  • Legacy/no metadata cache cold full refresh: 14.126 ms, 25 subprocess calls, 14 plist reads.
  • Optimized cold/no disk cache: 10.741 ms, 20 subprocess calls, 9 plist reads.
  • Optimized stale-cache background refresh equivalent: 1.267 ms, 1 subprocess call, 0 plist reads.
  • Optimized quick structural invalidation: 1.396 ms, 1 subprocess call, 0 plist reads.
  • Optimized app-search-scope change: 3.164 ms, 4 subprocess calls, 1 plist read, with the added app discovered and existing commands reused.
  • Discovered command parity: true for legacy vs optimized cold fixture output.

Adjacent parent validations still pass in this branch:

  • Command metadata cache benchmark: optimized median 0.007 ms vs legacy median 0.095 ms, avoiding 60 structural discovery starts.
  • Extension command refresh benchmark: targeted median 2.043 ms vs legacy median 10.244 ms, avoiding 40 structural discovery starts.

Stack validation

Started from codex/perf-wave4-integrated-stack-20260705 at ac90ce403aeddab98d0a1b245afce268c48b8bfd, then branched to codex/perf-command-discovery-cache-wave5. The PR is from JustYannicc:codex/perf-command-discovery-cache-wave5 to SuperCmdLabs/SuperCmd:main.

Replaces

None.

(cherry picked from commit 83c2a89)
(cherry picked from commit 0a7560b)
# Conflicts:
#	src/renderer/src/raycast-api/hooks/use-cached-promise.ts
…launcher surfaces

# Conflicts:
#	src/renderer/src/raycast-api/list-runtime-renderers.tsx
#	src/renderer/src/raycast-api/list-runtime.tsx
…IO stalls

# Conflicts:
#	src/renderer/src/CameraExtension.tsx
# Conflicts:
#	src/renderer/src/raycast-api/list-runtime.tsx
…resh overhead

# Conflicts:
#	scripts/bench-script-command-discovery.mjs
#	scripts/benchmark-file-search-delete-batch.mjs
#	scripts/lib/script-command-runner-harness.mjs
#	scripts/lib/ts-import.mjs
#	scripts/test-file-search-delete-batch.mjs
#	scripts/test-script-command-runner.mjs
#	src/main/file-search-index.ts
#	src/main/main.ts
…hurn

# Conflicts:
#	scripts/lib/script-command-runner-harness.mjs
#	scripts/lib/ts-import.mjs
#	scripts/test-extension-lifecycle-sandbox.mjs
#	scripts/test-script-command-runner.mjs
#	src/main/main.ts
#	src/renderer/src/ExtensionView.tsx
… hot paths

# Conflicts:
#	scripts/test-use-frecency-sorting.mjs
#	src/renderer/src/raycast-api/form-runtime.tsx
#	src/renderer/src/raycast-api/grid-runtime-hooks.ts
#	src/renderer/src/raycast-api/grid-runtime-items.tsx
#	src/renderer/src/raycast-api/hooks/use-frecency-sorting.ts
# Conflicts:
#	.github/workflows/project-checks.yml
#	package.json
#	scripts/file-search-perf-harness.mjs
#	scripts/test-browser-search-performance.mjs
#	scripts/test-file-search-perf-harness.mjs
#	scripts/test-root-search-perf.mjs
#	src/renderer/src/CameraExtension.tsx
#	src/renderer/src/hooks/useBrowserSearch.ts
#	src/renderer/src/raycast-api/list-runtime.tsx
…cle and media fixes

# Conflicts:
#	scripts/lib/ts-import.mjs
#	scripts/measure-extension-bundle-cache.mjs
#	src/main/commands.ts
#	src/main/extension-runner.ts
#	src/main/main.ts
#	src/renderer/src/ExtensionView.tsx
#	src/renderer/src/raycast-api/grid-runtime-hooks.ts
#	src/renderer/src/raycast-api/list-runtime-hooks.ts
@JustYannicc

Copy link
Copy Markdown
Collaborator Author

Superseded by consolidated PR #620: #620

@JustYannicc JustYannicc closed this Jul 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant