Documentation
¶
Overview ¶
Package opencodehook manages OpenCode's plugin-based session-id tracker for Quil.
Quil tracks opencode session-id rotation (new session, /new, fork, compaction) by registering a small JS plugin via the OPENCODE_CONFIG_CONTENT env var (inline JSON containing an absolute path to our plugin file). The plugin lives under $QUIL_HOME/opencodehook/ and writes per-pane session ids to $QUIL_HOME/sessions/opencode-<paneID>.id.
This package never writes into ~/.config/opencode/ or any other user-owned opencode directory — the plugin is referenced per-spawn via env var. OPENCODE_CONFIG_CONTENT is merged with the user's existing config (verified against opencode 1.14.x) so user-installed plugins / agents / modes remain active inside Quil-spawned opencode panes.
Index ¶
- func BuildConfigContent(scriptPath string) (string, error)
- func EnsureScripts(quilDir string) error
- func IsValidSessionID(id string) bool
- func ReadPersistedSessionID(quilDir, paneID string) (id string, modTime time.Time, err error)
- func ScriptPath(quilDir string) string
- func ValidateQuilDir(quilDir string) error
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func BuildConfigContent ¶
BuildConfigContent returns the JSON string Quil passes to opencode via the OPENCODE_CONFIG_CONTENT env var. The single plugin entry is the absolute path returned by ScriptPath. opencode 1.14.x accepts raw absolute paths in the plugin array and merges them with the user's other config sources.
The path MUST be absolute — opencode resolves plugin entries against the child process's CWD, not the daemon's. With `prompts_cwd = true` (which the opencode plugin enables) the child runs in whatever directory the user picked, so a relative scriptPath would silently look for the plugin under that user-chosen dir and fail to load. Reject up-front so the failure is visible at spawn time instead of as a missing-tracking footgun later.
func EnsureScripts ¶
EnsureScripts writes the embedded plugin file to $quilDir/opencodehook/. Idempotent — atomic temp+rename so a concurrent opencode load never reads a truncated file. Mirrors claudehook.EnsureScripts.
func IsValidSessionID ¶
IsValidSessionID reports whether id matches the shape opencode emits on the session bus. Used by the daemon's restore path to filter ids that fail shape validation (corrupted file, partial write surviving rename, manual edit) before passing them to opencode as `--session <id>`.
func ReadPersistedSessionID ¶
ReadPersistedSessionID returns the session id our plugin last wrote for the given pane. errors.Is(err, os.ErrNotExist) for "no session event has fired yet" so callers can cleanly fall back to --continue.
Symlinks are rejected atomically via O_NOFOLLOW (no Lstat+Open TOCTOU window). On Windows O_NOFOLLOW resolves to 0; symlink creation there requires elevated privilege so the practical attack surface is narrower. The Stat is performed on the resulting file descriptor so the modTime reported always corresponds to the bytes returned, even under concurrent rotation by the plugin.
func ScriptPath ¶
ScriptPath returns the absolute path to the plugin file. EnsureScripts must have been called first.
func ValidateQuilDir ¶
ValidateQuilDir reports an error if quilDir contains characters that cannot be safely embedded into inline config JSON.
Types ¶
This section is empty.