Skip to content

Latest commit

 

History

History
101 lines (67 loc) · 6.53 KB

README.en.md

File metadata and controls

101 lines (67 loc) · 6.53 KB

opencode-move-session-plugin

中文说明

An opencode plugin that adds a /move-session slash command for moving the current chat session to another project directory. Everything runs directly inside the plugin process — the LLM is never involved. Works on Windows, Linux, and macOS.

Usage

/move-session <target>
/move-session --debug <target>

<target> can be written as:

  • An absolute path: E:\repo\subdir or /Users/me/code/repo
  • A home-relative path: ~/Projects/foo
  • A relative path: ../sibling
  • The name of a known project — just its directory name, case-insensitive, e.g. myrepo
  • Fixed phrases:
    • here / current dir / this folder / current directory — the current directory
    • home / my home — your home directory
    • any word containing projects, code, src, or dev — resolves to the first existing ~/Projects, ~/projects, ~/code, ~/src, ~/dev

The phrases are a fixed list, not natural-language understanding; inputs containing those words are first treated as ordinary paths.

The problem it solves

opencode binds every session to a project (recorded in the project_id, directory, and path columns). Once a session exists there is no built-in way to relocate it — the session list at the target directory never shows it, because those columns still point at the old location.

This plugin does the whole move inside the command.execute.before hook:

  1. Resolve the target path (plain code, deterministic, no model needed).
  2. Rewrite project_id, directory, path, and workspace_id for the root session and all of its descendant subagent sessions in a single transaction.
  3. If the target is a git repository, determine its project identity using opencode's own precedence: an existing project row with the same worktree → sha1 of the normalized origin remote → the .git/opencode cache → the root commit hash, registering a new project row when necessary. Moving across repositories downgrades to global rather than hard-binding the session to an unrelated repo; the same downgrade happens on machines without git installed, with a warn log explaining why.
  4. Report the result as a toast (success / already there / the verbatim error); on success, inject a synthetic noReply system-reminder so the next turn knows the working directory changed. Finally throw to abort the command pipeline — no user message is ever recorded and the LLM is never called.

All you see is a brief toast confirmation; no /move-session trace remains in the conversation history, and no subagent sessions are created that would need cleaning up afterwards.

Files

File Purpose
plugins/move-session.js All of the logic: path resolution, git detection, writing opencode.db directly via bun:sqlite, toast and reminder injection
commands/move-session.md A stub slash command (its template is just $ARGUMENTS) whose only job is to register /move-session; the plugin replaces its content entirely

Install

Using the install script

On Windows:

.\install.ps1

On Linux and macOS:

./install.sh            # set OPENCODE_CONFIG_DIR to use a different config directory

The script simply copies the two files above into ~/.config/opencode/. If files from the original opencode-move-session or its PowerShell fork are detected, it prints a warning. Once you've confirmed the old version can go, re-run the script with -RemoveLegacy or --remove-legacy, or delete the old files yourself. Restart opencode afterwards.

Manual install

Manual installation is just copying two files from this repository into opencode's config directory:

  • plugins/move-session.js → ~/.config/opencode/plugins/ (%USERPROFILE%\.config\opencode\plugins\ on Windows)
  • commands/move-session.md → ~/.config/opencode/commands/ (%USERPROFILE%\.config\opencode\commands\ on Windows)

If you previously installed the older versions (session-env.js, move-session-auto-undo.js, or their command files), remove those too, otherwise the duplicate /move-session commands will conflict.

Implementation notes

  • The session ID comes straight from the hook arguments — no environment-variable injection needed. The database is read and written in-process via bun:sqlite (with a busy_timeout), and git detection shells out through Bun.spawn (degrading gracefully when git is missing instead of failing).
  • session.path follows the official formula (path.relative(project.directory, dir)); global sessions on Windows are stored without the drive letter, e.g. test/testfolder2.
  • Rewriting MSYS-style drive prefixes like /c/Users only happens on Windows; POSIX paths are left untouched.
  • --debug diagnostics go to the opencode log (service name move-session), never into any prompt text.

Relationship to previous implementations

The idea comes from opencode-move-session (the original bash version) and its PowerShell fork: the move rules and path semantics are identical, but "prompt-driven LLM running a script" has been replaced by direct execution inside the plugin, so there is no dependency on sqlite3 or PowerShell, and no subagent sessions or pending-cleanup files to worry about. The reasons for dropping the LLM call: it can cost money; sometimes there is no usable model at hand; the LLM may not follow exactly what the skill says or may misunderstand it, causing all sorts of problems; without LLM randomness the behavior is deterministic and much easier to debug; and execution is faster. The trade-off, of course, is losing the LLM's ability to "intelligently" locate the target path.

Caveats

  • This plugin modifies opencode.db directly. If opencode changes the session/project schema or filtering rules, this needs updating accordingly.
  • Already-running opencode instances may keep the old project assignment in memory; switch sessions or restart to see the new location.
  • Requires opencode to support the command.execute.before hook.
  • Without a TUI attached (headless or opencode run) you won't see the toast, but the move still completes and the result is written to the log.
  • Throwing to abort the pipeline surfaces server-side as a failed session.command request — that's expected.
  • Target paths are not symlink-resolved; if your project paths contain symlinks, worktree matching may be affected.

Uninstall

Delete these two files and restart opencode:

~/.config/opencode/plugins/move-session.js
~/.config/opencode/commands/move-session.md