feat: add snyk.remediationAgent.fixFolder command [IDE-2052]#1331
feat: add snyk.remediationAgent.fixFolder command [IDE-2052]#1331bastiandoetsch wants to merge 4 commits into
Conversation
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
|
/describe |
|
PR Description updated to latest commit (8eb44e4) |
PR Reviewer Guide 🔍
|
2c0fbaf to
72120e8
Compare
|
/describe |
8eb44e4 to
a5d4002
Compare
|
PR Description updated to latest commit (a5d4002) |
72120e8 to
0e94ef1
Compare
|
/describe |
a5d4002 to
6095425
Compare
|
PR Description updated to latest commit (6095425) |
0e94ef1 to
694c381
Compare
eb547c1 to
0e101fe
Compare
|
/describe |
|
PR Description updated to latest commit (e36ab05) |
|
/describe |
|
PR Description updated to latest commit (e36ab05) |
…052] Add an LSP workspace/executeCommand named snyk.remediationAgent.fixFolder that takes one file:// folder URI and runs the remediation agent's fix workflow in place in that folder, delivering the resulting changes to the client via workspace/applyEdit. The folder is a caller-created git worktree (a detached-HEAD clone of the workspace root); the command runs the fix directly in it without creating a nested worktree, so edit paths stay keyed under the passed folder for the caller's prefix remap. The fix-on-a-directory capability reuses the existing remy provider via a new optional FolderRemediator interface (discovered by type assertion, mirroring FileChangeNotifier); the shared snapshot-run-diff logic is factored into collectFixEdits so the per-finding and folder paths do not duplicate it. The command is feature-gated: when the remediation provider is absent it returns an error rather than silently succeeding, and it requires the client to support workspace/applyEdit. FixFolder requires the passed folder to be the git repository root and rejects subdirectories explicitly instead of silently dropping edits. Also wires the remediation provider through command.NewService into the command factory, closing a gap where it was constructed but never reached the command service.
|
/describe |
|
PR Description updated to latest commit (e36ab05) |
|
/describe |
|
PR Description updated to latest commit (119ee0a) |
|
/describe |
|
PR Description updated to latest commit (119ee0a) |
…IDE-2052] The remy provider's per-file cache marked an entry stale only when a cached file's mtime was strictly after the entry's wall-clock creation time. On filesystems with coarse mtime granularity, a file modified just after the entry was created could carry an mtime that, once truncated, sorted before the nanosecond-precise creation time — so a genuinely changed file was treated as fresh and stale edits were retained. This made TestCacheValid_StaleFile fail nondeterministically on CI. Replace the timestamp comparison with a per-file SHA-256 content hash captured when the entry is populated and recompared on each lookup: any content change (including same-length edits that mtime/size checks miss) now reliably invalidates the entry, independent of filesystem timestamp resolution. The requested file's presence is checked before any hashing so a miss does no I/O, an empty entry is never stored, and the content and hash maps are kept in sync on every mutation. Also set core.checkStat=minimal in the fixFolder git test helpers (matching the remy test helper) to avoid an overlay-filesystem write-ordering flake when reading freshly written git objects in CI.
|
/describe |
|
PR Description updated to latest commit (87adbe8) |
|
/describe |
|
PR Description updated to latest commit (87adbe8) |
…ws [IDE-2052] The remy provider mixed non-canonical temporary paths with git's canonical paths. On macOS the temp dir is under /var (a symlink to /private/var) and on Windows it is an 8.3 short name; git rev-parse --show-toplevel returns the resolved form. The divergence made the per-finding Remediate flow's worktree diff and cache-key matching fail, so it returned an empty WorkspaceEdit on those platforms while passing on Linux. The failure was masked until now by an unrelated flaky test that aborted the package run first. Canonicalize paths with filepath.EvalSymlinks where the worktree flow needs git's view: Remediate resolves ContentRoot and FilePath (so cache write, serve, and invalidate keys agree), and runRemyInWorktree resolves the MkdirTemp parent. InvalidateFile resolves its path too, falling back to the parent directory when the file has already been deleted. FixFolder deliberately does NOT canonicalize: its caller remaps edits by the exact folder path it passed, so edits must stay keyed under that path; it runs git directly in that folder and needs no resolution. Also: guard NewRemyProvider against a nil runner with a nil engine, lower the empty-diff diagnostic to debug, and fix a folder-URI test that used a path that is not absolute on Windows. Regression tests reproduce the symlink class on Linux for Remediate, InvalidateFile (including the deleted-file path), and the FixFolder passed-path contract.
|
/describe |
|
PR Description updated to latest commit (a54cb36) |
User description
Summary
Adds the LSP
workspace/executeCommandsnyk.remediationAgent.fixFolderplus the remy provider integration/smoke tests.file://folder-URI argument and runs the remediation agent's fix workflow in place in that folder, which is a caller-created git worktree (a detached-HEAD clone of the workspace root).workspace/applyEdit, with edit paths keyed under the passed folder so the caller's path-prefix remap matches; the executeCommand response isnilon success, an error on failure.FolderRemediatorinterface (discovered by type assertion, mirroringFileChangeNotifier); shared snapshot→run→diff logic is factored intocollectFixEditsso the per-finding and folder paths don't duplicate it.workspace/applyEdit.FixFolderrequires the passed folder to be the git repository root and rejects subdirectories explicitly rather than silently dropping edits.command.NewServiceinto the command factory, closing a gap where it was constructed but never reached the command service.PR Stack — Merge Order
flowchart LR main(["main"]) PR0["#1330\nremy unit tests"] PR1["#1331 ← YOU ARE HERE\nfixFolder command + remy integ/smoke tests"] main --> PR0 --> PR1 style PR1 fill:#ffd700,color:#000Depends on: #1330
Testing
make testrecorded for the commit.Known environmental caveat
Test_Smoke_RemediationAgent_CodeAction(added in this stack) does not complete in the local dev environment: it fails in shared setup while downloading the ~149 MB Snyk CLI binary (unexpected EOF) and cloning fixture repos (git cloneexit 128). These are network/infra limitations of the local environment, not code defects — the failure occurs before any remediation logic runs. CI (with reliable network) should exercise it.Test plan
PR Type
enhancement
Description
Implement
snyk.remediationAgent.fixFoldercommand.Add
FolderRemediatorinterface and Remy provider implementation.Integrate into DI, command service, and LSP handlers.
Enhance cache validation with content hashing; add extensive tests.
Diagram Walkthrough
File Walkthrough
1 files
Define new command constant for fixFolder7 files
Define FolderRemediator interfaceImplement FixFolder, enhance cache validationImplement fixFolder command handler logicWire FolderRemediator into command serviceAdd FolderRemediator to CommandServiceCreate remediationFixFolderCommand handlerRegister fixFolder command in ExecuteCommandProvider11 files
Unit tests for remediationFixFolderCommand logicUnit tests for remediation.FixFolder implementationTests for cache validation and path handlingIntegration tests for FixFolder command wiringIntegration tests for command execution and capabilitiesSmoke test for RemediationAgent quickfix roundtripTest CreateFromCommandData wires provider and notifierExport helpers for testing remediation providerExport command constructors for testingAdd tests for non-AI-fixable and non-Code issuesAdd tests for various LSP type conversions5 files