feat(opencode): add session workspace directories and searchable add-directory UX.#14244
feat(opencode): add session workspace directories and searchable add-directory UX.#14244adampoit wants to merge 1 commit intoanomalyco:devfrom
Conversation
|
The following comment was made by an LLM, it may be inaccurate: Based on my search, I found a potentially related PR: Related PR:
The current PR (14244) is a more comprehensive implementation that builds upon earlier directory-related features. The search results also show several external_directory permission-related PRs (#5905, #5841, #6714) that provide context for the permission model being used. However, no exact duplicate PRs were found - PR #14244 appears to be a new consolidated feature that combines session workspace directory support with improved UX for the |
|
I somehow missed that this was implemented in #8943. I'm happy to close this out if we like the approach taken in the other PR. I can address Copilot's feedback if we choose to move forward. |
There was a problem hiding this comment.
Pull request overview
Adds session-scoped “workspace directory” support so users can allow and search additional (external) directories per session, and surfaces this in both TUI and app autocomplete/file discovery plus system prompt metadata.
Changes:
- Introduces
POST /session/:sessionID/workspace/directoryand aSession.addWorkspaceDirectoryflow that persists anexternal_directoryallow rule on the session. - Extends file discovery (
find.files, TUI@autocomplete, app file search) to include session workspace directories whensessionIDis provided. - Adds
/add-directoryUX (with inline directory autocomplete) and updates system prompt<directories>metadata to include workspace directories.
Reviewed changes
Copilot reviewed 19 out of 19 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/sdk/js/src/v2/gen/types.gen.ts | Adds new API/types for session workspace directory and sessionID support on find.files. |
| packages/sdk/js/src/v2/gen/sdk.gen.ts | Adds generated session.workspaceDirectory() client method and sessionID query for find.files. |
| packages/opencode/test/session/workspace-directory.test.ts | Unit tests for Session.addWorkspaceDirectory behavior (tilde, symlink canonicalization, duplicates, invalid paths). |
| packages/opencode/test/server/session-workspace-directory.test.ts | Endpoint tests for adding a workspace directory and basic body validation. |
| packages/opencode/test/file/search-external-directory.test.ts | Tests that external directories are only searched when sessionID is provided + permitted. |
| packages/opencode/test/cli/tui/prompt-directory.test.ts | Tests directory path formatting for slash directory autocomplete display/value. |
| packages/opencode/src/session/system.ts | Updates system prompt environment metadata to list working + workspace directories from permissions. |
| packages/opencode/src/session/prompt.ts | Ensures system prompt env uses current session permissions (re-fetches session in loop). |
| packages/opencode/src/session/index.ts | Implements addWorkspaceDirectory and response schema. |
| packages/opencode/src/server/routes/session.ts | Adds POST /:sessionID/workspace/directory route. |
| packages/opencode/src/server/routes/file.ts | Adds optional sessionID query to /find/file and passes through to File.search. |
| packages/opencode/src/file/index.ts | Extends File.search to merge in files/dirs from permitted external directories for a session. |
| packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx | Implements /add-directory submission flow (creates session if needed, calls API, shows toast). |
| packages/opencode/src/cli/cmd/tui/component/prompt/directory.ts | Adds helper for formatting directory suggestion values (absolute vs relative vs tilde). |
| packages/opencode/src/cli/cmd/tui/component/prompt/autocomplete.tsx | Reuses inline autocomplete surface to suggest directories for /add-directory and includes sessionID in file search. |
| packages/opencode/src/cli/cmd/tui/component/dialog-tag.tsx | Threads sessionID into dialog tag file search. |
| packages/app/src/pages/session/use-session-commands.tsx | Adds “Add workspace directory” session command (dialog + API call + toasts). |
| packages/app/src/i18n/en.ts | Adds i18n strings for the new session command and toasts. |
| packages/app/src/context/file.tsx | Includes sessionID when searching files so session workspace dirs are discoverable in app search. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if (!stat) throw new Error(`Directory not found: ${input.path}`) | ||
| if (!stat.isDirectory()) throw new Error(`Path is not a directory: ${input.path}`) |
There was a problem hiding this comment.
addWorkspaceDirectory throws plain Error for missing/non-directory paths. In the server this will be converted into a 500 response (since only NamedError / HTTPException are mapped), which contradicts the OpenAPI/SDK contract advertising 400/404 and will surface as an internal error to clients for invalid input. Please return a 4xx here (e.g., throw a HTTPException(400, ...), or introduce a typed NamedError and map it to 400) and consider adding a server test asserting invalid paths return 400.
| if (!stat) throw new Error(`Directory not found: ${input.path}`) | |
| if (!stat.isDirectory()) throw new Error(`Path is not a directory: ${input.path}`) | |
| if (!stat) throw new NotFoundError(`Directory not found: ${input.path}`) | |
| if (!stat.isDirectory()) throw new NotFoundError(`Path is not a directory: ${input.path}`) |
| if (input === "~") return process.env.HOME ?? input | ||
| if (input.startsWith("~/")) { | ||
| const home = process.env.HOME | ||
| if (!home) return input |
There was a problem hiding this comment.
expand() handles ~/... but not the Windows-style ~\... form, even though other parts of this change (e.g. Session.addWorkspaceDirectory and directoryPath) explicitly support ~\\. This will make /add-directory ~\... directory suggestions behave incorrectly on Windows. Consider updating expand() (and any other path expansion helpers here) to also expand ~\\ when HOME is set.
| if (input === "~") return process.env.HOME ?? input | |
| if (input.startsWith("~/")) { | |
| const home = process.env.HOME | |
| if (!home) return input | |
| const home = process.env.HOME | |
| if (input === "~") return home ?? input | |
| if (home && (input.startsWith("~/") || input.startsWith("~\\"))) { |
| const root = await state().then((x) => x.files()) | ||
| const extra = await external(input.sessionID) | ||
| const files = extra.files.length ? Array.from(new Set([...root.files, ...extra.files])) : root.files |
There was a problem hiding this comment.
File.search() now calls external(sessionID) on every invocation. That helper does a DB lookup (Session.get) and then walks each allowed external directory via Ripgrep.files, which can be very expensive during autocomplete (many calls per keystroke) and may cause noticeable latency on large directories. Consider caching external directory file/dir lists per session (keyed by permission set + maybe a short TTL), or precomputing them when a workspace directory is added, so search remains fast.
…directory UX Implement session-scoped workspace directory support behind `/add-directory`, persist external-directory permissions on the session, and include added directories in file discovery/autocomplete. Reuse the existing inline autocomplete surface for directory selection and update system prompt environment metadata so assistants can accurately report searchable directories.
1f9731f to
5b0af70
Compare
Implement session-scoped workspace directory support behind
/add-directory, persist external-directory permissions on the session, and include added directories in file discovery/autocomplete. Reuse the existing inline autocomplete surface for directory selection and update system prompt environment metadata so assistants can accurately report searchable directories.Issue for this PR
Closes #1543.
Type of change
What does this PR do?
POST /session/:sessionID/workspace/directoryexternal_directoryallow rules on the session permission setfind.files@autocomplete/add-directoryin TUI prompt flow and reuses the existing inline autocomplete panel<directories>includes both:How did you verify your code works?
nix develop -c bun run typecheck(frompackages/opencode)test/session/workspace-directory.test.tstest/file/search-external-directory.test.tstest/server/session-workspace-directory.test.ts/add-directory <path>works with and without an active session@autocomplete includes files from added workspace directories/add-directory ../and token fuzzy (iden) suggestion behavior~/...directory submission succeedsScreenshots / recordings
Checklist