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);
|
}, 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 () => {
|
test("receives server_info on websocket connect", async () => {
|
||||||
const client = new DaemonClient({
|
const client = new DaemonClient({
|
||||||
url: `ws://127.0.0.1:${ctx.daemon.port}/ws`,
|
url: `ws://127.0.0.1:${ctx.daemon.port}/ws`,
|
||||||
|
|||||||
@@ -174,7 +174,10 @@ import {
|
|||||||
type AgentUpdatesService,
|
type AgentUpdatesService,
|
||||||
} from "./session/agent-updates/agent-updates-service.js";
|
} from "./session/agent-updates/agent-updates-service.js";
|
||||||
import { expandTilde } from "../utils/path.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 { CheckoutDiffManager } from "./checkout-diff-manager.js";
|
||||||
import type { Resolvable } from "./speech/provider-resolver.js";
|
import type { Resolvable } from "./speech/provider-resolver.js";
|
||||||
import type { SpeechReadinessSnapshot } from "./speech/speech-runtime.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.
|
// the entire session message if they encounter an unknown provider.
|
||||||
const LEGACY_PROVIDER_IDS = new Set(["claude", "codex", "opencode"]);
|
const LEGACY_PROVIDER_IDS = new Set(["claude", "codex", "opencode"]);
|
||||||
const MIN_VERSION_ALL_PROVIDERS = "0.1.45";
|
const MIN_VERSION_ALL_PROVIDERS = "0.1.45";
|
||||||
const WORKSPACE_SEARCH_HIDDEN_DIRECTORIES = [
|
|
||||||
".agents",
|
|
||||||
".claude",
|
|
||||||
".codex",
|
|
||||||
".github",
|
|
||||||
".paseo",
|
|
||||||
".vscode",
|
|
||||||
];
|
|
||||||
|
|
||||||
function errorToFriendlyMessage(error: unknown): string {
|
function errorToFriendlyMessage(error: unknown): string {
|
||||||
if (error instanceof Error) return error.message;
|
if (error instanceof Error) return error.message;
|
||||||
if (typeof error === "string") return error;
|
if (typeof error === "string") return error;
|
||||||
|
|||||||
@@ -11,12 +11,13 @@ import { tmpdir } from "node:os";
|
|||||||
import path from "node:path";
|
import path from "node:path";
|
||||||
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
||||||
import { isPlatform } from "../test-utils/platform.js";
|
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 isWindows = isPlatform("win32");
|
||||||
const filesystemRootDirectoryName = isWindows ? "Windows" : "usr";
|
const filesystemRootDirectoryName = isWindows ? "Windows" : "usr";
|
||||||
const workspaceHiddenDirectories = [".agents", ".claude", ".codex", ".github", ".paseo", ".vscode"];
|
|
||||||
|
|
||||||
async function searchAbsoluteDirectoryPaths(options: {
|
async function searchAbsoluteDirectoryPaths(options: {
|
||||||
homeDir: string;
|
homeDir: string;
|
||||||
query: string;
|
query: string;
|
||||||
@@ -60,7 +61,7 @@ async function searchRelativeDirectoryEntries(options: {
|
|||||||
matchMode: options.matchMode,
|
matchMode: options.matchMode,
|
||||||
pathQueryPolicy: "slashes",
|
pathQueryPolicy: "slashes",
|
||||||
blankQueryBehavior: "children",
|
blankQueryBehavior: "children",
|
||||||
traversableHiddenDirectoryNames: workspaceHiddenDirectories,
|
traversableHiddenDirectoryNames: WORKSPACE_SEARCH_HIDDEN_DIRECTORIES,
|
||||||
limit: options.limit,
|
limit: options.limit,
|
||||||
maxDepth: options.maxDepth,
|
maxDepth: options.maxDepth,
|
||||||
maxEntriesScanned: options.maxEntriesScanned,
|
maxEntriesScanned: options.maxEntriesScanned,
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ export interface SearchDirectoryEntriesOptions {
|
|||||||
pathQueryPolicy?: PathQueryPolicy;
|
pathQueryPolicy?: PathQueryPolicy;
|
||||||
rootAliases?: string[];
|
rootAliases?: string[];
|
||||||
blankQueryBehavior?: BlankQueryBehavior;
|
blankQueryBehavior?: BlankQueryBehavior;
|
||||||
traversableHiddenDirectoryNames?: string[];
|
traversableHiddenDirectoryNames?: readonly string[];
|
||||||
limit?: number;
|
limit?: number;
|
||||||
maxDepth?: number;
|
maxDepth?: number;
|
||||||
maxEntriesScanned?: 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_MATCH_OFFSET = Number.MAX_SAFE_INTEGER;
|
||||||
const NO_FUZZY_SCORE = Number.MAX_SAFE_INTEGER;
|
const NO_FUZZY_SCORE = Number.MAX_SAFE_INTEGER;
|
||||||
const NO_MATCH_TIER = 5;
|
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([
|
const IGNORED_DIRECTORY_NAMES = new Set([
|
||||||
"node_modules",
|
"node_modules",
|
||||||
"venv",
|
"venv",
|
||||||
|
|||||||
Reference in New Issue
Block a user