Skip to content

fix: open QuickPick instantly and avoid subprocess for binary version#101

Open
ThiruvarankanM wants to merge 4 commits into
jaseci-labs:mainfrom
ThiruvarankanM:fix/quickpick-instant-open-version-cache
Open

fix: open QuickPick instantly and avoid subprocess for binary version#101
ThiruvarankanM wants to merge 4 commits into
jaseci-labs:mainfrom
ThiruvarankanM:fix/quickpick-instant-open-version-cache

Conversation

@ThiruvarankanM

@ThiruvarankanM ThiruvarankanM commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

What changed and why

Five bugs found after binary install support landed:

  1. QuickPick opened slowly — every click on the status bar ran jac --version (~1.8s) just to show the current version in the title. Fixed by reading the already-cached this.jacVersion instead.

  2. jac's runtime cache can't serve multiple binaries — each jac binary's gcStale wipes the other binaries' cache dirs in ~/.cache/jac/rt/ on every run. With 2+ jac installs (e.g. a release binary + a dev build), the cache only ever holds ONE binary's version — the other always fell through to a subprocess. Fixed with a persistent version memo owned by the extension (~/.cache/jac-vscode/versions.json), keyed by the binary's hash16 — a payload content hash read from the binary's 80-byte trailer in ~0ms. Content-derived key ⇒ entries never go stale; a replaced binary gets a new hash16 and re-learns once.

  3. Cold jac --version exceeded the timeout — a binary whose cache was GC'd re-extracts its full runtime payload on next run (10s+ measured), but the subprocess timeout was 5s → killed → no version shown at all, plus a 5s freeze on every QuickPick open. Timeout raised to 30s; the result lands in the memo so this cost is paid at most once per binary.

  4. Dev builds showed a stale version — a dev build (zig-out/bin/jac) reports the live <repo>/jac.toml version at runtime, but its cache dist-info holds the build-time version (e.g. binary says 0.30.5, cache says 0.30.3). Fixed by reading jac.toml directly for binaries under zig-out/bin/ — instant and always matches jac --version.

  5. Dev builds not detected / duplicate entrieszig-out/bin/jac never appeared in the picker unless the user edited PATH; build_install.sh --dev symlinks made the same binary show twice; .jac/venv/bin/jac (plugin venv symlink) showed as a phantom entry. All three fixed.


What was broken before

Situation Before After
Clicking status bar to open QuickPick ❌ ~1.8s delay ✅ Opens instantly
Version with 2+ jac binaries installed ❌ One binary always fell to subprocess (jac cache GC war) ✅ Persistent memo, ~2ms for all
Version after jac cache GC'd (cold binary) ❌ Subprocess killed at 5s → no version shown ✅ Memo hit ~2ms; first-ever learn gets 30s
Dev build version ❌ Stale build-time version (or none) ✅ Live jac.toml version
zig-out/bin/jac detection ❌ Not detected without PATH edit ✅ Auto-detected up to 2 levels deep
--dev symlink / .jac plugin venv ❌ Duplicate & phantom picker entries ✅ Deduplicated / skipped

Files changed

src/environment/manager.ts

  • QuickPick title uses this.jacVersion (cached at startup) instead of awaiting getJacVersion() before show()

src/utils/envVersion.ts

  • Version resolution order: dist-info (venvs) → live jac.toml (dev builds) → persistent memo → jac runtime cache → subprocess (result memoized)
  • getBinaryHash16(): reads the JACBIN01 trailer (last 80 bytes) for the payload content hash — the memo key and an exact, path-independent runtime-cache match
  • Persistent memo at ~/.cache/jac-vscode/versions.json — survives VS Code restarts and jac cache GC
  • getJacVersionFromDevSource(): binaries under zig-out/bin/ read live <repo>/jac.toml
  • Runtime cache scan handles both dir formats: new (≥0.30.3) <hash16>-<pathhash16> per binary; old (≤0.30.2) <hash16> shared — old format only trusted when no new-format dirs exist
  • Subprocess timeout 5s → 30s (cold extraction takes 10s+; runs at most once per binary)

src/utils/envDetection.ts

  • walkForVenvs: skips .jac/ dirs (project plugin venvs created by jac install, not standalone installs)
  • findInWorkspace: scans zig-out/bin/jac up to two levels deep (workspace may be jaseci/jac/, jaseci/, or a parent folder)
  • discoverJacEnvironments: deduplicates by realpath so --dev symlinks don't produce two entries for one binary

Validation

  • Two binaries installed (release ~/.local/bin/jac 0.30.3 + dev zig-out/bin/jac 0.30.5): both resolve in 1–2ms
  • Deliberately triggered jac's cache GC (ran one binary to wipe the other's cache): wiped binary still resolves in 2ms from the memo
  • Dev build correctly shows live jac.toml version (0.30.5) instead of stale build-time dist-info (0.30.3)
  • tsc clean

- Use cached this.jacVersion for QuickPick title instead of awaiting
  getJacVersion() before show() — eliminates 1.8s delay on open
- Add cache scan (~/cache/jac/rt/) as middle path in getJacVersion so
  binary installs report version without spawning jac --version subprocess
… scan

- Memo versions by binary trailer hash16 (~/.cache/jac-vscode/versions.json):
  jac's gcStale wipes other binaries' rt cache dirs, so with multiple
  binaries the rt cache alone can never resolve every version
- Dev builds read live <repo>/jac.toml (matches jac --version after bumps)
- Raise subprocess timeout to 30s (cold jac --version takes 10s+)
- Scan zig-out/bin/jac two levels deep (workspace may be a parent dir)
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