Conversation
…installs Plan files were hardcoded to <worktree>/.opencode/plans for git projects, and every discovered .opencode config directory got an automatic @opencode-ai/plugin dependency install plus generated package manifest, lockfile and .gitignore files. This pollutes every project plan mode is used in, with no way to opt out. - add plans_directory config key to relocate plan files (supports ~) - add OPENCODE_DISABLE_PLUGIN_DEPS=1 to skip the per-directory dependency install and generated files - extend the plan agent built-in edit/external_directory permissions to cover the configured plans directory Refs anomalyco#46189
Per-directory dependency installs used to write package manifest, lockfile and node_modules directly into config directories (~/.config/opencode and every project .opencode), violating the XDG base directory spec (anomalyco#27786) and polluting project trees. Installs now target a per-directory store under ~/.local/share/opencode/deps/<hash>/, and config dirs only get a node_modules symlink pointing there so bare imports from local plugins keep resolving through parent-directory traversal. Installs fall back to the config dir when symlinks are unavailable (e.g. unprivileged Windows) or when a real node_modules directory already exists there. Also documents plans_directory, OPENCODE_DISABLE_PLUGIN_DEPS and the new install location in the website docs. Refs anomalyco#46189, closes anomalyco#27786
…lugins The per-directory dependency install used to run for every config directory unconditionally, so plugin-less projects and state directories still got a node_modules symlink and an XDG store entry. The install now only runs for directories that actually have plugins, either declared in their opencode.json or auto-discovered under plugin(s)/. Plugin-less directories keep just the generated .gitignore. Plan files also start with a "Project: <path>" first line listing the project root(s) they belong to, so a shared plans_directory stays navigable when several projects write plans to the same directory.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Issue for this PR
Closes #46189
Closes #27786
Closes #28174 (closed feature request for a configurable plans directory, implemented here)
Closes #30337 (closed startup-hang report; the root cause is removed because new projects no longer get a node_modules tree to scan)
Type of change
What does this PR do?
Opening opencode in a git project and using plan mode creates
<project>/.opencode/plans/. On the next start, that directory is picked up as a config directory and gets an automatic@opencode-ai/plugindependency install, plus generated package manifest, lockfile and.gitignorefiles. Every project plan mode was used in ends up with its own copy, and~/.config/opencodegets one too when it is a git repo. There is currently no way to opt out (details and code refs in #46189).This PR adds three opt-outs/fixes, all default-preserving:
plans_directoryconfig key (supports~): plan files are written to the configured directory instead of the worktree/global defaults, e.g. the global data dir, so project trees stay untouched. The plan agent's built-inedit/external_directoryallows were extended to the configured directory so plan mode keeps working.OPENCODE_DISABLE_PLUGIN_DEPS=1env flag: skips the per-directory dependency install and the generated files. Config discovery (agents, commands, plugins) is unaffected.~/.local/share/opencode/deps/<hash>/(package manifest, lockfile,node_modules), and each config directory only gets anode_modulessymlink pointing there. Bareimport "@opencode-ai/plugin"from local plugin files keeps resolving through parent-directory traversal, while the dependency mass leaves~/.configand project trees. Installs fall back to the previous in-place behavior when symlinks are unavailable (e.g. unprivileged Windows) or when a realnode_modulesdirectory already exists in the config dir, so existing setups keep working untouched.opencode.jsonor discovered underplugin(s)/). Plugin-less directories keep just the generated.gitignore, so opening opencode in a project without plugins writes nothing but that one file.Project: <path>first line listing the project root path(s) they belong to, so a sharedplans_directorystays navigable when several projects use it.Default behavior is unchanged when neither
plans_directorynor the env flag is set, except that new installs land in the XDG data dir instead of the config dirs.How did you verify your code works?
Session.plan(): default paths (git / non-git),plans_directoryoverride (absolute,~, bare~, relative)~/.local/share/opencode/deps/<hash>,OPENCODE_DISABLE_PLUGIN_DEPSwriting nothing, existing realnode_modulesdirs left untouchedbun run typecheckclean;bun test test/config/config.test.ts110/110 andbun test test/session/plan.test.ts7/7 on bun 1.3.14.opencodedirectory is created in the projectScreenshots / recordings
Not a UI change.
Checklist
Supersedes #46199 (auto-closed by the compliance bot after a body edit broke the template section header; same branch, same commits).