add Explain Code / Generate Tests code lenses - #866
Conversation
Reaching the agent about a specific function meant switching to the sidebar and pasting the code in. Every function, method and class now carries two inline links instead. Clicking one reveals the chat view and submits the symbol as a prompt: the instruction, a `file:startLine-endLine` locator and the source fenced with the document's language. The snippet is inlined rather than attached as an `@[file]` chip so the agent sees the one symbol that was clicked instead of the whole file. Symbols come from `vscode.executeDocumentSymbolProvider`, so the lenses follow whatever language servers the user already has and nothing here parses source. Lenses anchor on the symbol's selectionRange - the declaration line - while the command receives the full body range, so a preceding doc comment doesn't push the links away from the signature. A lens can be clicked before the sidebar has ever been opened, so the prompt is held in `_pendingPrompt` and flushed from `_initializeSessionIfReady`, which already runs both on webview ready and on ACP connect - whichever lands last. The two commands are hidden from the palette: they take a uri and a symbol range, so a bare invocation would have nothing to act on. `nanocoder.codeLens` turns the lenses off. Closes Nano-Collective#750.
_isWebviewReady was latched on the first shell and never cleared, so once the Nanocoder view had been disposed - hidden from its container, or moved to another one - the next lens click posted runPrompt into a replacement webview that had not run its script yet. The message went nowhere and the prompt was cleared, so the click did nothing at all. Reset the flag on every resolve and drop the view on dispose. The queued prompt is also bounded now. It used to sit indefinitely when the CLI was down and then fire from onConnectionReady whenever the agent happened to come up, answering about code the user had long moved past, with no feedback in the meantime. It expires after 30s with a warning instead, and the timer is disarmed once the prompt is handed over.
runPrompt drove the composer: it overwrote chat-input and called submitMessage, which then folded in attachedPaths and pendingImages. So clicking Explain Code discarded whatever the user was typing and sent any file chip or pasted image they had staged for a different question, then cleared them. Split the send tail out of submitMessage as dispatchPrompt and route the editor prompt straight through it, leaving the draft and the staged context untouched.
explainCode/generateTests are hidden from the palette but a keybinding or another extension can still invoke them bare. uri and range were assumed present, so openTextDocument(undefined) opened an untitled document and range.start then threw; guard and point the user at the lenses instead. Also dispose the onDidChangeCodeLenses emitter with the extension rather than leaking it, and resolve nanocoder.codeLens against the document so a folder-level override wins in a multi-root workspace - it is declared scope: resource to match.
|
Hey @addyCooks - nice work, this is a clean implementation. Using A few things before merge:
Smaller stuff: |
Closes #750.
Description
Adds inline
Explain Code/Generate Testscode lenses above every function, method and class. Clicking one reveals the chat view and submits that symbol as a prompt instruction, afile:startLine-endLinelocator, and the source fenced with the document's language. Previously, asking the agent about a specific function meant switching to the sidebar and pasting the code in.Type of Change
Changeset
pnpm changeset) describing this change for the changelogTesting
Automated Tests
.spec.ts/tsxfilespnpm test:allcompletes successfully)Manual Testing
Checklist