Skip to content

V2 features: mini handoff, slash questions, cleanup, continue actions, retry - #26

Open
LucasInstra wants to merge 19 commits into
karamanliev:mainfrom
LucasInstra:v2-features
Open

LucasInstra wants to merge 19 commits into
karamanliev:mainfrom
LucasInstra:v2-features

Conversation

@LucasInstra

Copy link
Copy Markdown

New features on top of the V2 port

Stacked on #25 (the V2 port) — please review/merge that one first. Until #25 lands, GitHub also shows the port commits in this diff; once it lands I will rebase this branch so the diff contains only the feature commits below.

Features

  • Stale session cleanup — mini sessions are tagged with metadata.opencodeMiniSession; tagged sessions untouched for 12h are removed on startup (cleanupStaleSessions, default on), so a crashed or force-closed client does not leak sessions into the list. It measures inactivity with time.updated, so a mini session still in use is never removed.
  • Configurable toolstools: ["read","glob","grep","webfetch"] allowlist for the plugin-managed mini agent (add websearch, or narrow to read). Everything else stays denied.
  • Slash questions/mini <question> and /mini-fresh <question> submit the question immediately instead of only opening the overlay (the raw command prefix is stripped).
  • Continue actionscontinueAction: "queue" | "clipboard": shift+enter queues the transcript into the main session (default) or copies it through the terminal clipboard (OSC 52); the action button label follows the mode.
  • Handoff mode/mini-handoff [instructions] opens the mini with the copied session context and asks for a handoff document for a new session. The action button becomes Copy handoff and copies only the document (the last assistant answer). On terminals that cannot send a distinct shift+enter, pressing Enter with an empty input copies the handoff (with feedback so it is not mistaken for a normal send).
  • Retry — the error state shows a Retry button that re-sends the last question.
  • Persisted preferences — the model chosen in the picker and the thinking toggle survive restarts (plugin storage); the picker highlights the current selection.

Polish

  • Remove dead code (unused HintBar, CMD_SUBMIT, formatModelLabel, ...) and clamp session instruction entries below the 256 KiB server cap, so a large copied context degrades into a truncated entry instead of a dropped one.
  • Extract the overlay state logic into answer-model.ts with dedicated tests.
  • Docs: new options, install requirements, V2 module errors, the npm Git restriction, and a local checkout recipe.

Tests

141 tests across 13 files (84 of them already in #25), including coverage for cleanup, tools parsing, slash questions, clipboard output, handoff mode, retry/preferences, and the extracted answer model.

Verification

  • tsc --noEmit, vitest run (141), npm run build, and npm run test:package pass.
  • Live checks: /mini <question> submits immediately; /mini-handoff generated a faithful handoff document from a real session; OSC 52 clipboard writes verified for both shift+enter encodings and the empty-Enter fallback.
  • Interactive round-trips against a live opencode 2.0.3 server; no plugin failed banner.

How to try it

git clone https://github.com/LucasInstra/opencode-mini-session.git -b v2-features

…then use the same local checkout recipe as in #25 (build, junction/symlink dist and node_modules into ~/.config/opencode/plugins/mini-session/, restart OpenCode).

- Add a CI workflow (push to main + pull requests) running typecheck, unit tests, build, and the packaged output check.
- Update verify-packaged-tui.mjs for the V2 entrypoint: assert the exported definition has an id and a setup function instead of the V1 tui function.
- Handle npm 11's npm pack --json object output and Windows' npm.cmd.
- Move @opencode/plugin to dependencies so the published package resolves the host module (per the V2 migration guide).
A parent npm run exports the user configuration into the child environment, and npm 12 rejects allow-scripts on the isolated --prefix install this script performs (EALLOWSCRIPTS). Strip the problematic keys from the child environment; the install already passes --ignore-scripts.
The OpenTUI packages declare node >= 26.4 engines, so npm installs on the CI Node 24 emit EBADENGINE warnings. bun install is the same path publish.yml already uses, satisfies the engine, and was verified locally with the committed package-lock.json.
opencode plugin add accepts Git package specs, but dist/ is not committed: without prepare the installed package had no entrypoint. prepare mirrors the publish-time build.
The prepare script runs inside the host package preparation step, where invoking npm recursively may not resolve. Run the build script with node instead.
OpenCode 2.0.8 replaced background.surface with background.raised, and reading the old field inside the app slot crashed the plugin. Read every theme token defensively with fallbacks for both shapes, and cover the 2.0.8 shape and a partial theme with tests. Also refresh the lockfile to @OpenCode 2.0.8 (same declared ranges).
…e, retry

- Clean up leaked ephemeral sessions: mini sessions are created with metadata.opencodeMiniSession and stale marked sessions (12h+) are removed on plugin start (cleanupStaleSessions option, default on).
- Configurable read-only tool allowlist for the plugin-managed mini agent (tools option; add websearch or narrow to read).
- /mini <question> and /mini-fresh <question> submit the question immediately instead of only opening the overlay.
- continueAction: 'queue' | 'clipboard' - shift+enter can copy the transcript to the clipboard (OSC52) instead of queueing it into the main session.
- Retry button re-sends the last question after a failure.
- Persist model and thinking preferences in plugin storage; highlight the current model in the picker.
- Refactor startQuestion/openMiniSession to a single options object.
- Tests: 97 passing across 8 files.
- Document /mini <question>, the Retry button, and the continueAction label change.
- Add the tools, continueAction, and cleanupStaleSessions options to the configuration table and example.
- Document ephemeral session metadata and stale-session cleanup, plus persisted model/thinking preferences.
The host can dispatch a slash command with its whole raw input line (for example /mini question) instead of only the arguments, which leaked the command text into the submitted question. Strip the command prefix before submitting and cover both dispatch shapes with tests.
Adds the mini.handoff command (palette and /mini-handoff [instructions]): it opens the mini with the copied session context and asks for a handoff document.
The overlay action becomes "Copy handoff"; shift+enter copies only the last assistant answer (the document) through the terminal clipboard (OSC 52) instead of queueing the transcript.
The handoff prompt summarizes from the copied context only (no workspace exploration) and answers in the session language.
Adds extractLastAssistantText, unit tests for the command wiring and the copy path, and README documentation.
/mini-handoff now forces a fresh dialog when a mini overlay is already open, so handoff mode (Copy handoff, document-only copy) always applies. resolveMiniRouteAction gained forceReopen and the routing tests cover it.
Restore the transcript guard in continueInMainThread: shift+enter with no question no longer queues the context scaffolding into the main session.
Allow copying the handoff document after a later follow-up fails (continueOnError).
Retry explains itself when there is nothing to resend (session creation failures).
Abort an in-flight startQuestion when the plugin is disposed: no orphan session, no leaked subscriptions.
Delete the unused HintBar component, CMD_SUBMIT, formatModelLabel, the unused ModelSource import and the never-read isOverlayOpen action.
Stale cleanup now measures inactivity from time.updated, so a mini session still in use is never removed (the comment now matches the behavior).
Clamp the session instruction entry below the 256 KiB server cap so a large copied context degrades into a truncated entry instead of dropping the whole instruction.
Add the missing model/tokenLimit parsing assertions and tests for the new behaviors.
Extract the pure overlay logic (message shaping, streaming merges, thinking/tool formatting, height estimation) into src/components/answer-model.ts so it can be unit tested without a renderer; the JSX shell keeps the OpenTUI rendering.
Add suites for the plugin setup wiring (slot registration, auto-update abort, stale cleanup, storage-backed preferences), the theme adapter and route helper, and the overlay model.
135 tests across 12 files.
The npm package still ships 1.x until this release is published, so the install command alone is not enough on V2. Document the 2.x requirement and the local checkout flow through the global plugin directory, which is verified end-to-end.
Add troubleshooting entries for updating the plugin, the Invalid V2 TUI plugin module error (1.x installed on V2) and npm 12 refusing Git package installs (allow-git).
Move the key features and the installation steps to the top of the README so readers get the pitch and a working install command first; the mechanics stay under What it does.
Terminals that do not negotiate extended keyboard support send plain enter for shift+enter, so the copy binding never fired. Pressing enter with the input empty now runs the same copy action for handoff and clipboard modes; queue mode is unchanged. The overlay also reports when a response is still loading or when no handoff document exists yet. Adds clipboard unit tests and documents the fallback.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant