feat(extensions): make VCS adapters self-contained - #711
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
|
@greptile-apps review |
Greptile SummaryThis PR moves bundled VCS implementations behind the public extension contract and introduces an app-owned catalog threaded through startup, loading, reload, and watch behavior.
Confidence Score: 3/5The PR should not merge until external-repository reload performs staged discovery and provisional extension loading avoids executing extension factories twice. External-only repositories can lose repository configuration and local extensions when a live session moves into them, while initial startup can duplicate unscoped extension-factory side effects during its provisional and final load passes. Files Needing Attention: src/ui/AppHost.tsx, src/app/startup.ts Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[Resolve config with bundled VCS catalog] --> B[Load global, config, and CLI extensions]
B --> C[Collect provisional VCS adapters]
C --> D{External adapter changes project root?}
D -- No --> G[Build final session catalog and review]
D -- Yes --> E[Resolve repository config with provisional catalog]
E --> F[Load all extensions again]
F --> G
H[Live-session reload] --> I[Resolve config with bundled catalog]
I --> J[Optionally reload extensions]
J --> G
I -. Missing staged root pass .-> E
Prompt To Fix All With AI### Issue 1
src/ui/AppHost.tsx:123-127
**Reload skips external root discovery**
When a live-session reload moves into a repository recognized only by an external VCS adapter, configuration is resolved with the bundled catalog and extensions are loaded without the staged root-resolution pass used at initial startup. The reload therefore omits that repository's `.hunk/config.toml` and repo-local extensions, causing incorrect preferences or a missing adapter.
### Issue 2
src/app/startup.ts:309-317
**Staged bootstrap reruns extension factories**
When an external adapter changes the discovered project root, startup loads every global, configured, and CLI extension into a fresh registry a second time without cleaning up the first execution. Extensions whose factories start watchers, open connections, register process handlers, or write state leave duplicated work or leaked resources.
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.Reviews (1): Last reviewed commit: "feat(extensions): make VCS adapters self..." | Re-trigger Greptile |
Summary
Make bundled and third-party VCS adapters cross the same public extension boundary.
VcsCatalogand inject it through configuration, loading, reload, watch, and session resolution.hunkdiff/extension, remove Git-specific state from the generic load context, and enforce the ownership boundary with source tests.Before and after
src/core/vcssrc/extensions/default/vcs/<provider>core -> bundled extensions -> coresrc/appowns compositionhunkdiff/extension; source limits are structural public results and Git owns its process dependency.hunkis provider-independent and staged startup can discover roots through external adapterscore -> uicore -> extensions, bundled VCS -> core, and private extension API importsGit-format patch parsing remains shared in core because Git, Jujutsu, and Sapling all use it as a provider-neutral interchange format.
Before/after behavioral parity
I ran temporary differential harnesses against the same repositories through:
origin/main@c8ba80a45265ecThe harness normalized only absolute checkout/source paths and generated changeset timestamp IDs. It then compared complete changesets—including patches, file order, metadata, and statistics—plus exact source reads, repository roots, watch-signature lengths/hashes, and translated error types/messages/suggestions.
Git coverage
Working tree with and without untracked files, pathspecs, staged changes, staged pathspecs, revision ranges,
show,showpathspecs, stash reviews, invalid refs/ranges, and watch signatures. The fixture included text and binary changes, deletion, mode changes, staged-plus-unstaged edits, rename handling, Unicode paths, and large tracked/untracked files.Jujutsu coverage
Working-copy review with and without the untracked option, filesets, revision review,
show,showfilesets, unsupported staging, invalid revsets, and watch signatures. The fixture included text and binary changes, deletion, mode changes, rename handling, and Unicode paths.Sapling coverage
Working-copy review with and without unknown files, pathspecs, revision review,
show,showpathspecs, unsupported staging, invalid revsets, and watch signatures. The fixture included text and binary changes, deletion, mode changes, rename handling, Unicode paths, and a large unknown file.The intentional differences are architectural or additive: external-only repositories can now bootstrap correctly, repository selectors resolve nested paths to the nearest live root, and structural source-too-large answers are cached so adapters are not called repeatedly.
Verification
bun run typecheckbun run lintbun run format:checkbun run check:docsbun run check:packbun run testwith bothjjandslavailable — 2,010 passed, 4 skipped, 0 failedbun run test:integration— 101 passed, 0 failedbun run test:tty-smoke— 9 passed, 0 failedbun run build:binThis PR description was generated by Pi using gpt-5.6-sol