feat: /mini-recap — recap every past session that mentions a term - #27
Open
LucasInstra wants to merge 22 commits into
Open
LucasInstra wants to merge 22 commits into
LucasInstra wants to merge 22 commits into
Conversation
- 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.
LucasInstra
force-pushed
the
v2-recap
branch
from
September 18, 2026 16:34
f44ec8f to
784ac68
Compare
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.
/mini-recap— recap every past session that mentions a termStacked on #26 (features) and #25 (V2 port) — please review/merge those first. Until they land, GitHub shows their commits here too; once they merge I will rebase so this PR contains only the recap commits.
What it does
/mini-recap [term]scans past sessions that mention a term and writes a consolidated recap: objective, timeline, decisions, current state, open questions and next steps, with the sessions used listed at the end./mini-recap mini session— current project scope (case- and accent-insensitive;-and_match spaces)./mini-recap --all— scan every project;--exclude popup— drop sessions whose title mentions something else.recapKeybind(for examplealt+r) triggers it without typing.The overlay action becomes Copy recap (OSC 52, copies only the document) and follow-up questions keep working in the same mini session without rescanning.
esccancels the scan and the abort is forwarded to the in-flight client fetches.How it works
client.session.list({ parentID: null, order: "desc" })with cursor paging; subagent sessions and mini sessions are always skipped.recapScope: "project"(default) keeps the current directory;recapExcludeDirsglobs exclude private trees.<subagent …>reports, code fences) do not count. Sessions belowrecapMinScore(default 4) are dropped;--excludematches titles.tokenLimitplus a per-session cap; sessions over budget are reported in the overlay notice.recapmode) with the digest inside<recap-context>; the model is told to cite sessions and dates, mark contradictions between sessions, and not to invent.A dry run on a real database (108 sessions) with
mini session --exclude popupselected exactly the two sessions about the project — 92 matches, ~1k tokens — and produced a faithful recap with the expected sections. Note: the server ignoresGET /api/session?search=today (three different terms returned the same page), which is why the content scan happens client-side.Configuration
recapKeybindstring | falsefalse/mini-recap.recapScope"project" | "all""project"--alloverrides it per run.recapSessionsnumber15recapScanLimitnumber50recapMinScorenumber4recapExcludeDirsstring[][]Tests
182 tests across 14 files (41 new), including scoring and normalization, milestone sampling, fact extraction, digest budgets, session filtering, abort and unreadable exports, and the recap flow inside the mini session.
tsc --noEmit,vitest run,npm run buildandnpm run test:packageall pass.Design notes
docs/recap-design.mddocuments the intended design, the accepted trade-offs and what is deferred (selection picker,--since/--yes/--refresh/--handoff, compaction summaries as the primary source, and server-side search once the parameter works).