Archived
Align web at-space completion with TUI
This commit is contained in:
+3
-2
@@ -6,7 +6,7 @@ import fastifyWebsocket from "@fastify/websocket";
|
||||
import { ProjectStore } from "./storage/projectStore.js";
|
||||
import { ProjectService } from "./projects/projectService.js";
|
||||
import { WorkspaceService } from "./workspaces/workspaceService.js";
|
||||
import { listFileSuggestions } from "./workspaces/fileSuggestions.js";
|
||||
import { listFileSuggestions, listPathSuggestions } from "./workspaces/fileSuggestions.js";
|
||||
import { registerSessionProxyRoutes } from "./sessiond/sessionProxyRoutes.js";
|
||||
|
||||
const app = Fastify({ logger: true });
|
||||
@@ -36,9 +36,10 @@ app.get<{ Params: { projectId: string } }>("/api/projects/:projectId/workspaces"
|
||||
|
||||
registerSessionProxyRoutes(app);
|
||||
|
||||
app.get<{ Querystring: { cwd?: string; q?: string; kind?: "tracked" | "untracked" | "other" } }>("/api/files", async (request, reply) => {
|
||||
app.get<{ Querystring: { cwd?: string; q?: string; kind?: "tracked" | "untracked" | "other"; mode?: "file" | "path" } }>("/api/files", async (request, reply) => {
|
||||
if (request.query.cwd === undefined || request.query.cwd === "") return reply.code(400).send({ error: "cwd query parameter is required" });
|
||||
try {
|
||||
if (request.query.mode === "path") return await listPathSuggestions(request.query.cwd, request.query.q ?? "");
|
||||
return await listFileSuggestions(request.query.cwd, request.query.q ?? "", request.query.kind);
|
||||
} catch (error) {
|
||||
return reply.code(400).send({ error: error instanceof Error ? error.message : String(error) });
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import { execFile } from "node:child_process";
|
||||
import { readdir, stat } from "node:fs/promises";
|
||||
import { basename, dirname, join } from "node:path";
|
||||
import { promisify } from "node:util";
|
||||
import type { ClientFileSuggestion } from "../types.js";
|
||||
|
||||
@@ -14,6 +16,29 @@ export async function listFileSuggestions(cwd: string, query = "", kind?: Client
|
||||
.slice(0, 80);
|
||||
}
|
||||
|
||||
export async function listPathSuggestions(cwd: string, prefix = ""): Promise<ClientFileSuggestion[]> {
|
||||
const normalizedPrefix = prefix.replace(/^@/, "").replace(/\\/g, "/");
|
||||
const directoryPrefix = normalizedPrefix.endsWith("/") ? normalizedPrefix : dirname(normalizedPrefix) === "." ? "" : `${dirname(normalizedPrefix)}/`;
|
||||
const searchPrefix = normalizedPrefix.endsWith("/") ? "" : basename(normalizedPrefix);
|
||||
const entries = await readdir(join(cwd, directoryPrefix), { withFileTypes: true });
|
||||
const suggestions: ClientFileSuggestion[] = [];
|
||||
for (const entry of entries) {
|
||||
if (!entry.name.toLowerCase().startsWith(searchPrefix.toLowerCase())) continue;
|
||||
let isDirectory = entry.isDirectory();
|
||||
if (!isDirectory && entry.isSymbolicLink()) {
|
||||
try {
|
||||
isDirectory = (await stat(join(cwd, directoryPrefix, entry.name))).isDirectory();
|
||||
} catch {
|
||||
isDirectory = false;
|
||||
}
|
||||
}
|
||||
suggestions.push({ path: `${directoryPrefix}${entry.name}${isDirectory ? "/" : ""}`, kind: "other" });
|
||||
}
|
||||
return suggestions
|
||||
.sort((a, b) => Number(!a.path.endsWith("/")) - Number(!b.path.endsWith("/")) || a.path.localeCompare(b.path))
|
||||
.slice(0, 80);
|
||||
}
|
||||
|
||||
async function listGitFiles(cwd: string): Promise<ClientFileSuggestion[]> {
|
||||
const [tracked, untracked] = await Promise.all([
|
||||
git(cwd, ["ls-files"]),
|
||||
|
||||
Reference in New Issue
Block a user