mirror of
https://github.com/getpaseo/paseo.git
synced 2026-07-29 12:01:31 +00:00
Find .opencode files in workspace search (#2049)
* fix(search): find .opencode workspace files Workspace autocomplete skips hidden directories unless they are explicitly allowlisted. The missing .opencode entry made provider commands and workflows invisible to file search. * refactor(search): centralize hidden directory policy
This commit is contained in:
@@ -892,6 +892,42 @@ test("returns typed relative suggestions within a requested directory", async ()
|
||||
}
|
||||
}, 30000);
|
||||
|
||||
test("finds workspace files inside the OpenCode directory", async () => {
|
||||
const cwd = mkdtempSync(path.join(tmpdir(), "paseo-opencode-suggestion-"));
|
||||
const target = path.join(
|
||||
cwd,
|
||||
".opencode",
|
||||
"command",
|
||||
"workflow",
|
||||
"00-kickoff",
|
||||
"00-user-stories.md",
|
||||
);
|
||||
|
||||
try {
|
||||
mkdirSync(path.dirname(target), { recursive: true });
|
||||
writeFileSync(target, "");
|
||||
|
||||
const result = await ctx.client.getDirectorySuggestions({
|
||||
cwd,
|
||||
query: "00-user-stories.md",
|
||||
includeFiles: true,
|
||||
includeDirectories: false,
|
||||
limit: 20,
|
||||
});
|
||||
|
||||
expect(result.error).toBeNull();
|
||||
expect(result.directories).toEqual([]);
|
||||
expect(result.entries).toEqual([
|
||||
{
|
||||
path: ".opencode/command/workflow/00-kickoff/00-user-stories.md",
|
||||
kind: "file",
|
||||
},
|
||||
]);
|
||||
} finally {
|
||||
rmSync(cwd, { recursive: true, force: true });
|
||||
}
|
||||
}, 30000);
|
||||
|
||||
test("receives server_info on websocket connect", async () => {
|
||||
const client = new DaemonClient({
|
||||
url: `ws://127.0.0.1:${ctx.daemon.port}/ws`,
|
||||
|
||||
@@ -174,7 +174,10 @@ import {
|
||||
type AgentUpdatesService,
|
||||
} from "./session/agent-updates/agent-updates-service.js";
|
||||
import { expandTilde } from "../utils/path.js";
|
||||
import { searchDirectoryEntries } from "../utils/directory-suggestions.js";
|
||||
import {
|
||||
searchDirectoryEntries,
|
||||
WORKSPACE_SEARCH_HIDDEN_DIRECTORIES,
|
||||
} from "../utils/directory-suggestions.js";
|
||||
import type { CheckoutDiffManager } from "./checkout-diff-manager.js";
|
||||
import type { Resolvable } from "./speech/provider-resolver.js";
|
||||
import type { SpeechReadinessSnapshot } from "./speech/speech-runtime.js";
|
||||
@@ -224,15 +227,6 @@ import { CreateAgentLifecycleDispatch } from "./agent/create-agent-lifecycle-dis
|
||||
// the entire session message if they encounter an unknown provider.
|
||||
const LEGACY_PROVIDER_IDS = new Set(["claude", "codex", "opencode"]);
|
||||
const MIN_VERSION_ALL_PROVIDERS = "0.1.45";
|
||||
const WORKSPACE_SEARCH_HIDDEN_DIRECTORIES = [
|
||||
".agents",
|
||||
".claude",
|
||||
".codex",
|
||||
".github",
|
||||
".paseo",
|
||||
".vscode",
|
||||
];
|
||||
|
||||
function errorToFriendlyMessage(error: unknown): string {
|
||||
if (error instanceof Error) return error.message;
|
||||
if (typeof error === "string") return error;
|
||||
|
||||
@@ -11,12 +11,13 @@ import { tmpdir } from "node:os";
|
||||
import path from "node:path";
|
||||
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
||||
import { isPlatform } from "../test-utils/platform.js";
|
||||
import { searchDirectoryEntries } from "./directory-suggestions.js";
|
||||
import {
|
||||
searchDirectoryEntries,
|
||||
WORKSPACE_SEARCH_HIDDEN_DIRECTORIES,
|
||||
} from "./directory-suggestions.js";
|
||||
|
||||
const isWindows = isPlatform("win32");
|
||||
const filesystemRootDirectoryName = isWindows ? "Windows" : "usr";
|
||||
const workspaceHiddenDirectories = [".agents", ".claude", ".codex", ".github", ".paseo", ".vscode"];
|
||||
|
||||
async function searchAbsoluteDirectoryPaths(options: {
|
||||
homeDir: string;
|
||||
query: string;
|
||||
@@ -60,7 +61,7 @@ async function searchRelativeDirectoryEntries(options: {
|
||||
matchMode: options.matchMode,
|
||||
pathQueryPolicy: "slashes",
|
||||
blankQueryBehavior: "children",
|
||||
traversableHiddenDirectoryNames: workspaceHiddenDirectories,
|
||||
traversableHiddenDirectoryNames: WORKSPACE_SEARCH_HIDDEN_DIRECTORIES,
|
||||
limit: options.limit,
|
||||
maxDepth: options.maxDepth,
|
||||
maxEntriesScanned: options.maxEntriesScanned,
|
||||
|
||||
@@ -24,7 +24,7 @@ export interface SearchDirectoryEntriesOptions {
|
||||
pathQueryPolicy?: PathQueryPolicy;
|
||||
rootAliases?: string[];
|
||||
blankQueryBehavior?: BlankQueryBehavior;
|
||||
traversableHiddenDirectoryNames?: string[];
|
||||
traversableHiddenDirectoryNames?: readonly string[];
|
||||
limit?: number;
|
||||
maxDepth?: number;
|
||||
maxEntriesScanned?: number;
|
||||
@@ -84,6 +84,15 @@ const NO_SEGMENT_INDEX = Number.MAX_SAFE_INTEGER;
|
||||
const NO_MATCH_OFFSET = Number.MAX_SAFE_INTEGER;
|
||||
const NO_FUZZY_SCORE = Number.MAX_SAFE_INTEGER;
|
||||
const NO_MATCH_TIER = 5;
|
||||
export const WORKSPACE_SEARCH_HIDDEN_DIRECTORIES = [
|
||||
".agents",
|
||||
".claude",
|
||||
".codex",
|
||||
".github",
|
||||
".opencode",
|
||||
".paseo",
|
||||
".vscode",
|
||||
] as const;
|
||||
const IGNORED_DIRECTORY_NAMES = new Set([
|
||||
"node_modules",
|
||||
"venv",
|
||||
|
||||
Reference in New Issue
Block a user