Skip to content

perf: reuse stale extension command builds#594

Closed
JustYannicc wants to merge 115 commits into
SuperCmdLabs:mainfrom
JustYannicc:codex/perf-wave4-stale-extension-builds
Closed

perf: reuse stale extension command builds#594
JustYannicc wants to merge 115 commits into
SuperCmdLabs:mainfrom
JustYannicc:codex/perf-wave4-stale-extension-builds

Conversation

@JustYannicc

Copy link
Copy Markdown
Collaborator

What changed

  • Added a .sc-build/.sc-build-stamp.json signature for extension command builds.
  • Reuse unchanged command bundles instead of deleting .sc-build and rebundling every compatible command.
  • Rebuild only stale commands when source inputs change, while preserving batched esbuild for cold/stale builds.
  • Preserve pre-built outputs when source files are missing so bundle installs are not destroyed by manual rebuild paths.
  • Extended the multi-command extension runner test harness with stale-skip, partial rebuild, config invalidation, and opt-in timing evidence.

Why

Install, update, and manual rebuild paths called buildAllCommands() even when extension source, manifest, tsconfig, externals, and dependency-affecting inputs were unchanged. The old path invalidated caches, deleted .sc-build, and paid esbuild startup and filesystem work every time.

Compatibility impact

Raycast-compatible command discovery, platform filtering, manifest externals, dependency installation/recovery, missing bare-import retry, and on-demand bundle fallback are preserved. Build stamps are additive files under .sc-build; missing or stale stamps fall back to rebuilding. Native build scripts were not changed.

How tested

  • node --test scripts/test-extension-runner-multi-command-build.mjs scripts/test-extension-bundle-cache.mjs
  • SUPERCMD_EXTENSION_BUILD_MEASURE=1 node --test scripts/test-extension-runner-multi-command-build.mjs
  • npm run build:main
  • Codex LSP diagnostics on src/main/extension-runner.ts: no diagnostics
  • npm test

Performance evidence

Before, three repeated fixture builds invoked esbuild three times for every size: 1 command [13.65, 13.56, 12.46] ms, 5 commands [13.79, 13.61, 14.41] ms, 20 commands [16.86, 17.61, 16.73] ms.

After, only the first build invokes esbuild; repeated unchanged calls reuse stamped outputs: 1 command [13.69, 0.35, 0.20] ms, 5 commands [15.51, 0.55, 0.47] ms, 20 commands [18.82, 1.45, 1.57] ms. Esbuild calls dropped from 3 to 1 across each three-call fixture run.

Stack validation

Started from codex/perf-wave3-integration-stack-20260704 at 206eab8280a2eb91a57e4e74ea6df99e45a55cb4; branch is codex/perf-wave4-stale-extension-builds with commit 925b2d8. Read docs/extension-install-flow.md before changing extension build behavior. Full final npm test: 321 tests, 318 pass, 3 skipped.

Replaces

None.

…perf-wave2-integration-stack-20260704

# Conflicts:
#	src/renderer/src/raycast-api/hooks/use-cached-promise.ts
…perf-wave2-integration-stack-20260704

# Conflicts:
#	src/renderer/src/raycast-api/list-runtime-renderers.tsx
#	src/renderer/src/raycast-api/list-runtime.tsx
…perf-wave2-integration-stack-20260704

# Conflicts:
#	src/renderer/src/CameraExtension.tsx
…perf-wave2-integration-stack-20260704

# Conflicts:
#	src/renderer/src/raycast-api/list-runtime.tsx
…perf-wave2-integration-stack-20260704

# 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
…perf-wave2-integration-stack-20260704

# 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
…perf-wave2-integration-stack-20260704

# Conflicts:
#	.github/workflows/project-checks.yml
#	scripts/test-root-search-perf.mjs
#	src/renderer/src/CameraExtension.tsx
#	src/renderer/src/raycast-api/list-runtime.tsx
…erf-wave3-integration-stack-20260704

# Conflicts:
#	package.json
#	scripts/measure-extension-bundle-cache.mjs
#	scripts/test-icon-runtime-file-icon-cache.mjs
#	src/main/extension-runner.ts
#	src/renderer/src/components/HiddenExtensionRunners.tsx
#	src/renderer/src/raycast-api/icon-runtime-render.tsx
…/perf-wave3-integration-stack-20260704

# Conflicts:
#	scripts/test-browser-search-performance.mjs
#	scripts/test-root-search-perf.mjs
@JustYannicc

Copy link
Copy Markdown
Collaborator Author

Closing in favor of #601, which fully replaces this granular PR in the wave4 runtime/main consolidation. Literal validation now passes with /opt/homebrew/opt/node@22/bin/npm run build:main, and #601 is ready for review.

@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