@@ -18,13 +18,22 @@ ASYNC (setImmediate callback, still in extension.ts):
18181 . spawn PET process (` createNativePythonFinder ` )
1919 1 . sets up a JSON-RPC connection to it over stdin/stdout
20202 . register all built-in managers in parallel (Promise.all):
21- - for each manager (system, conda, pyenv, pipenv, poetry):
22- 1 . check if tool exists (e.g. ` getConda(nativeFinder) ` asks PET for the conda binary)
23- 2 . if tool not found → log, return early (manager not registered)
24- 3 . if tool found → create manager, call ` api.registerEnvironmentManager(manager) `
25- - this adds it to the ` EnvironmentManagers ` map
26- - fires ` onDidChangeEnvironmentManager ` → ` ManagerReady ` deferred resolves for this manager
27- 3 . all registrations complete (Promise.all resolves)
21+ - system: create SysPythonManager + VenvManager + PipPackageManager, register immediately
22+ - ✅ NO PET call — managers are created and registered with no tool detection
23+ - sets up file watcher for venv activation scripts
24+ - conda: ` getConda(nativeFinder) ` checks settings → cache → persistent state → PATH
25+ - if found → register CondaEnvManager + CondaPackageManager
26+ - if not found → PET fallback as last resort (rarely hit, conda is usually on PATH)
27+ - if not found at all → skip, send MANAGER_REGISTRATION.SKIPPED telemetry
28+ - pyenv: create PyEnvManager, register immediately
29+ - ✅ NO PET call — always registers unconditionally (lazy discovery)
30+ - pipenv: create PipenvManager, register immediately
31+ - ✅ NO PET call — always registers unconditionally (lazy discovery)
32+ - poetry: create PoetryManager + PoetryPackageManager, register immediately
33+ - ✅ NO PET call — always registers unconditionally (lazy discovery)
34+ - shellStartupVars: initialize
35+ - all managers fire ` onDidChangeEnvironmentManager ` → ManagerReady resolves
36+ 3 . all registrations complete (Promise.all resolves) — fast, typically milliseconds
2837
2938--- gate point: ` applyInitialEnvironmentSelection ` ---
3039 📊 TELEMETRY: ENV_SELECTION.STARTED { duration (activation→here), registeredManagerCount, registeredManagerIds, workspaceFolderCount }
@@ -55,26 +64,29 @@ ASYNC (setImmediate callback, still in extension.ts):
5564 managerDiscovery — P1, P2, or P4 won (manager → interpreter):
5665 ` resolvePriorityChainCore ` returns { manager, environment: undefined }
5766 → result.environment is undefined → falls through to ` await result.manager.get(scope) `
58- ` manager.get(scope) ` (e.g. ` CondaEnvManager.get() ` ):
67+ ` manager.get(scope) ` (e.g. ` CondaEnvManager.get() ` , ` PyEnvManager.get() ` ):
5968 4. ` initialize() ` — lazy, once-only per manager (guarded by deferred)
6069 a. ` nativeFinder.refresh(hardRefresh=false) ` :
61- → ` handleSoftRefresh() ` checks in-memory cache (Map) for key 'all' (bc one big scan, shared cache, all managers benefit)
70+ → ` handleSoftRefresh() ` checks in-memory cache (Map) for key 'all'
6271 - on reload: cache is empty (Map was destroyed) → cache miss
6372 - falls through to ` handleHardRefresh() `
6473 → ` handleHardRefresh() ` :
6574 - adds request to WorkerPool queue (concurrency 1, so serialized)
6675 - when its turn comes, calls ` doRefresh() ` :
6776 1. ` configure() ` — JSON-RPC to PET with search paths, conda/poetry/pipenv paths, cache dir
6877 2. ` refresh ` — JSON-RPC to PET, PET scans filesystem
78+ - PET has had time to warm up since spawn (registration was fast)
6979 - PET may use its own on-disk cache (cacheDirectory) to speed this up
7080 - PET streams back results as 'environment' and 'manager' notifications
7181 - envs missing version/prefix get an inline resolve() call
7282 3. returns NativeInfo[ ] (all envs of all types)
7383 - result stored in in-memory cache under key 'all'
7484 → subsequent managers calling nativeFinder.refresh(false) get cache hit → instant
75- b. filter results to this manager's env type (e.g. conda filters to kind=conda)
76- c. convert NativeEnvInfo → PythonEnvironment objects → populate collection
77- d. ` loadEnvMap() ` — reads persisted env path from workspace state
85+ b. filter results to this manager's env type (e.g. conda filters to kind=conda, pyenv to kind=pyenv)
86+ c. for pipenv/poetry/pyenv: if tool CLI was not found via PATH during registration,
87+ extract tool executable from PET's manager info in the refresh results
88+ d. convert NativeEnvInfo → PythonEnvironment objects → populate collection
89+ e. ` loadEnvMap() ` — reads persisted env path from workspace state
7890 → matches path against freshly discovered collection via ` findEnvironmentByPath() `
7991 → populates ` fsPathToEnv ` map
8092 5. look up scope in ` fsPathToEnv ` → return the matched env
@@ -86,6 +98,15 @@ ASYNC (setImmediate callback, still in extension.ts):
8698
8799 📊 TELEMETRY: EXTENSION.MANAGER_REGISTRATION_DURATION { duration (activation→here), result, failureStage?, errorType? }
88100
101+ SIDEBAR ACCESS (on-demand, if user opens Python environments panel):
102+ - view iterates ` providers.managers ` → all registered managers appear (including pyenv/pipenv/poetry)
103+ - user expands a manager node → ` getChildren() ` → ` manager.getEnvironments('all') `
104+ → ` initialize() ` (lazy, once-only) → ` nativeFinder.refresh(false) ` :
105+ - if cache populated from earlier env selection → instant cache hit
106+ - if first access → warm PET call (no concurrent pressure, single caller)
107+ → environments appear under the manager node
108+ → if no environments found → "No environments" placeholder shown
109+
89110POST-INIT:
901111 . register terminal package watcher
911122 . register settings change listener (` registerInterpreterSettingsChangeListener ` ) — re-runs priority chain if settings change
0 commit comments