mirror of
https://github.com/backnotprop/plannotator.git
synced 2026-09-14 14:17:26 +08:00
95750ab657
* feat: search-based code navigation with peek view (#694) Add IDE-like code navigation to the review UI. Cmd/Ctrl+click a token in a diff to find its definitions and references across the repo via ripgrep, displayed in a VS Code-style peek panel below the diff. Backend: bounded rg search with language-aware definition patterns (TS/JS, Python, Go, Rust), ranked results (same file > changed files > same directory), confidence labels, and graceful degradation when rg is not installed. Both Bun and Pi servers implement the endpoints. Frontend: Dockview peek panel with syntax-highlighted full-file preview on the left and grouped reference list on the right. Clicking a reference scrolls the preview; double-clicking an in-diff result navigates to the file with a gold line flash. Closes #694 * fix: resolve Pi server TypeScript errors for code-nav Add missing spawn import, type the close callback parameter, and use double-cast for parseBody → CodeNavRequest. * fix: clear loading state on cached preview hits Without this, clicking a cached file while a fetch is in-flight leaves isLoading stuck true — the spinner hides the preview. * feat: show pointer cursor on Cmd/Ctrl+hover for navigable tokens Adds pn-token-nav class with thicker underline and pointer cursor when hovering a token while holding the modifier key, signaling the token is Cmd+clickable for code navigation. * refactor: remove go-to-diff navigation from peek panel Strip the in-diff badge, double-click-to-jump, highlightDiffLine wiring, and onCodeNavGoToDiff from the peek panel. The peek view is the primary interaction — jump-to-diff adds complexity without clear value at this stage. * chore: remove dead code from code-nav cleanup Delete unused highlightDiffLine.ts, remove codeNavChangedFiles and codeNavActiveSide from context and App.tsx, drop stale extractChangedFiles import. * chore: add code-nav endpoints to AGENTS.md, remove dead activeSide state * fix: don't classify bare indented calls as definitions Change the TS/JS method pattern from zero-or-more (*) to one-or-more (+) declaration keywords, so plain calls like startServer(config) are no longer misclassified as definitions. * feat: show toast when code-nav is unavailable in platform-only PR mode Instead of opening the peek panel and showing misleading "No results", Cmd+click in non-local PR mode shows a brief toast explaining that code navigation requires a local checkout. * fix: strip hljs hardcoded background from code-nav preview The highlight.js github-dark theme sets a fixed dark background on all .hljs elements. Apply transparent override for the entire peek preview so code inherits the active theme's background.
74 lines
1.7 KiB
TypeScript
74 lines
1.7 KiB
TypeScript
/**
|
|
* Code navigation — Bun runtime adapter and request handler.
|
|
*/
|
|
|
|
import {
|
|
type CodeNavRequest,
|
|
type CodeNavRuntime,
|
|
type CodeNavResponse,
|
|
resolveCodeNav,
|
|
validateCodeNavRequest,
|
|
extractChangedFiles,
|
|
} from "@plannotator/shared/code-nav";
|
|
|
|
export type { CodeNavRequest, CodeNavResponse };
|
|
|
|
const bunCodeNavRuntime: CodeNavRuntime = {
|
|
async runCommand(command, args, options) {
|
|
let proc;
|
|
try {
|
|
proc = Bun.spawn([command, ...args], {
|
|
cwd: options?.cwd,
|
|
stdout: "pipe",
|
|
stderr: "pipe",
|
|
});
|
|
} catch {
|
|
return { stdout: "", stderr: "command not found", exitCode: 1 };
|
|
}
|
|
|
|
let timer: ReturnType<typeof setTimeout> | undefined;
|
|
if (options?.timeoutMs) {
|
|
timer = setTimeout(() => proc.kill(), options.timeoutMs);
|
|
}
|
|
|
|
const [stdout, stderr, exitCode] = await Promise.all([
|
|
new Response(proc.stdout).text(),
|
|
new Response(proc.stderr).text(),
|
|
proc.exited,
|
|
]);
|
|
|
|
if (timer) clearTimeout(timer);
|
|
return { stdout, stderr, exitCode };
|
|
},
|
|
};
|
|
|
|
export async function handleCodeNavResolve(
|
|
req: Request,
|
|
cwd: string,
|
|
changedFiles: string[],
|
|
): Promise<Response> {
|
|
try {
|
|
const body = (await req.json()) as CodeNavRequest;
|
|
const error = validateCodeNavRequest(body);
|
|
if (error) {
|
|
return Response.json({ error }, { status: 400 });
|
|
}
|
|
|
|
const result = await resolveCodeNav(
|
|
bunCodeNavRuntime,
|
|
body,
|
|
cwd,
|
|
changedFiles,
|
|
);
|
|
|
|
return Response.json(result);
|
|
} catch (err) {
|
|
return Response.json(
|
|
{ error: err instanceof Error ? err.message : "Code navigation failed" },
|
|
{ status: 500 },
|
|
);
|
|
}
|
|
}
|
|
|
|
export { extractChangedFiles };
|