Repository navigation
Lore CLI 0.13.0
Added
-
The
opum-loreplugin now ships the Lore pane (LCLI-664; OPAG-1075) — a Claude Code
hooks module ("mod") that puts the repository's documentation bundle in a pane. It browses
the bundle's concepts by type fromlore queryand opens one rendered as Markdown or raw
with its frontmatter; internal link clicks navigate in the pane with a Back history; search
takes free text with type and tag filters, and a refs toggle adds--across-refsto read
open pull requests; New creates a document throughlore newand opens whatever id comes
back, so the pane mints no ids of its own and cannot collide with documents created on a
branch; a fields form rewrites the open document's frontmatter, then validates the written
file withlore validate, keeping the previous bytes and showing lore's own message when
validation fails; rename, supersede, link and unlink run the matchinglorecommand and
thenlore sync. Everything goes through the CLI rather than a reimplementation, so link
repointing on rename and managed task blocks stay lore's own behaviour. Body editing is the
fields form, a lightweight inline editor for the body (text, cursor, insert/delete and
undo/redo in aClientregion, drawn with the engine's own elements and saving through the
samelore validatepath), an Open in editor action that hands the file to the person's
own$EDITORthrough the session's shell escape (the inline editor is offered only on the
terminal and desktop surfaces, and the pane points at this action instead wherever the surface
has no editor region — the VS Code surface has none, and the mobile surface is told the pane
needs the terminal or desktop), and an Ask Claude… button that fills
the prompt box and sends nothing itself, so Claude's normal permissions and this
repository's documentation rules apply; Markdown, diff and syntax highlighting use the
engine's ownMarkdownandCodeelements rather than a bundled renderer, and the editing
model is vendored@codemirror/statewith its license and provenance recorded beside it
(a hooks module can import only its own files andclaude-code). The
pane ships in the plugin cut from this repository's release tag, so a plugin user gets the
pane matching the CLI version they installed; mods need Claude Code 2.1.287 or later. Its
component reference is Lore pane mod.
The module's tests run under the Claude Code engine against a stage of exactly what the
plugin ships —bun run test:mod(scripts/mod-test.mjs) — and CI runs them in a
mod gate (opum-lore plugin)job. That harness fails rather than skipping when it cannot
test anything (noclaude, one older than 2.1.287, a shipped directory absent, a stage with
no module), and it reports its typecheck as NOT TYPECHECKED rather than implying one it
could not run: the typecheck is machine-local against the engine's own declaration and CI
cannot assert it. Covered by the module's tests: browse, read, Back, Raw, search and its refs
toggle, New, the fields form with its validation-failure path, the inline editor (a key,
the cursor cell, undo, Save throughlore validate, and the rejected-save restore), and the
rename/lore syncargv. Not covered, and so not claimed: supersede, link, unlink, Ask
Claude…, Open in editor, and the uncommitted-changes landing strip. -
The Lore pane gains a full-screen toggle and an entry point of its own (LCLI-666, LCLI-667,
LCLI-668) — opum-doc's "add full screen mode and a toggle for it" and "'lore-pane' to just
'lore'".zinside the pane flips it between its normal size and the largest the surface
allows, and the dashboard tool'sfullargument opens it full screen directly; a second press,
orfullagain, returns it to normal, and the choice is remembered across sessions. In full
mode the pane draws the outline, or the search results, beside the open document once it has at
least 120 body columns, and keeps its stacked layout below that. The pane's command name moved
/lore-pane→/lorein the design and then off the slash surface entirely: the engine refuses
a mod command namedlore, which the plugin's ownloreskill owns, and registering one skips
the wholesession.starthook — so the pane ships no slash command of its own, and its only
entry point is the module'smcp__opum-lore__dashboardtool, which theloreskill routes to.
/lore dashboard(and the plain words "lore dashboard") opens the pane as it stands;
dashboard full,dashboard <doc-id>anddashboard search <text>map to the tool'sfull,
docandqueryinputs, and every argument that does not start withdashboardgoes to the
CLI as before. The tool never takes the keyboard — a Tab or a click gives the pane the keys.
Changed
-
The pinned Bun moves back to
1.3.14, andengines.bunnarrows to>=1.3.14(LCLI-686;
DEC-163 (8), opum-doc, 2026-10-06). The LCLI-660 two-window measurement found the Linux epoll
runtime race on the1.4.2pin (10/20 and 17/20 CI runs) and never on1.3.14(0/20 in both
windows), and that race is what failed the required ubuntulint · typecheck · testleg even on
diffs that cannot reach a test. The1.4.2floor existed for the LCLI-648 parser panic, which
DEC-163 (8) works around by avoiding the construct — lore's source carries noBun.Transpiler
and no top-leveldeclarebinding, so the panic cannot reach shipped code. The floor test that
exercises the repro now skips itself on1.3.14and names LCLI-648, re-arming if the pin moves
forward again. Breaking for consumers who readengines.bun, as LCLI-648's move was. -
The
lore agent contextpack footer now counts the eligible deck, and a
zero-score omission carries its own reason (LCLI-680; ODOC-437 slice 1, AC1).
total,shownandtruncatedare computed over the candidates that remain
after the zero-score exclusion — selection step 4 of the opum-doc task-context
contract,docs/specs/opum-task-context-and-evidence-contract.md, which drops a
candidate scoring zero once the task's own terms rank the deck. Such an exclusion
happens before any budget is spent, so it is not a budget cut and no longer sets
truncated: a pack that holds every eligible candidate reportstruncated: falsehowever many zero-score candidates it excluded (measured on this
repository's ownimplementationprofile: the LCLI-289 pack now reads
198 of 198; truncated: nowhere it previously counted the full declared deck;
the count moved from 197 to 198 because this change's own documentation edits
grew the declared deck).
The exclusion stays visible — the catalog reports a source all of whose
candidates were excluded this way with the new reasonomitted-by-relevance,
distinct fromomitted-by-budget, so a zero-relevance exclusion is never
reported as a budget cut. Contract-visible for consumers of
agent.context.export: the meaning of the footer'stotal/truncatedchanges
as described, so that envelope'sschemaVersionis bumped2→3under
cli-contract §7.1 — a meaning change to existing fields, scoped to thatkind.
Theagent.workflow.projectionenvelope is bumped1→2by the same change,
since it embeds a pack compiled by the same selection code, sototal,shown,
selectedCount,topScoreandreasonmove inside it too (lore help --json
now reportskindSchemaVersions: {"agent.context.export": 3, "agent.workflow.projection": 2}); its embedded pack stays hit-free. A source
dropped whole by relevance now reads a differentreasonthan one dropped by
budget; the newreasonvalue is additive under §7.1, as the workspace-only
reasons were.
Fixed
- The capacity measurement now stands for the largest pack a real task can compile (LCLI-662;
DEC-98 B, ADR-0025).
lore check'sagent-profile-capacitymeasurement previously excluded the bundle-wide query
section a reallore agent contextpack renders, and rendered its score placeholders one character
wide where real scores render seven to ten — so a green check could certify a profile whose real
task pack dropped a declared source by budget (measured: a declared set green at 2957 tokens
against a 2982-token budget,omitted-by-budgeton the pack; and hit-free packs up to ~500 tokens
larger than the measurement on this repository's own profiles). The measurement now reserves the
query section's worst case, task-independently, and renders score annotations at full width, so a
budget that satisfies it cannot start dropping declared evidence on a task — up to the one residual
ADR-0025 records and measures: the pack header renders the task text verbatim, so a task much
longer than the measurement's fixed stand-in can still consume the margin. The finding is still
computed from the declaration and the bundle, never from a task. This ships as a warning for
one release before LCLI-646 flips it to an error (DEC-11). - The Lore pane's full mode now follows the engine's own sizing, and its answers report what
actually drew (LCLI-675; DEC-154). The pane asked forrows - 6inline, where the engine caps
an inline pane atrows - 11, so a full request could never be granted as asked; its docked
request was computed from the conversation column — a shrink request that a kept
pluginPanes.dockColumnsthen beat anyway — and thedashboardtool answered with the size it
asked for rather than the size that drew. The module now asksrows - 11inline and recovers
the terminal width in the dock from one render (transcript + the drawn body + the divider, less
the engine's 24-column floor), asks once per toggle rather than on every resize, tells the
person plainly when a width they set is being kept (Width kept at 80 (you set it): drag the pane edge to change) instead of a generic hint — its first cut read "held" from an ask's
outcome and stayed quiet on a bare shortfall, which LCLI-676 corrected to the design's own
rule and Quest's board's, below — and reports the drawn size —the full sizeonly within
4 cells of the ask, the drawn size and its reason otherwise,full requestedwhen the draw
is not yet known. - The Lore pane's kept-width line, its tool answer and its mode control now read the same
state the same way (LCLI-676; seq 243,ODOC-OP-2026-10-03-74). The operator's re-test at
466dee64found the held-width line (Width kept at 80 (you set it): drag the pane edge to change) never drawing whilepluginPanes.dockColumnswas kept, and thedashboardtool
answeringopened at 80 columns; the pane kept its width— the not-held wording, with
"opened" twice — where Quest's board saidthe width is keptfor the same state. Measured
in a real pty on Claude Code 2.1.288: the line's condition suppressed the render that spends
a full ask, and a kept width makes the module's size request a no-op, so no further draw
came to say it on and the suppressed draw stood permanently. The line now reads the
design's own rule on every short docked draw (within 4 cells granted, anything further off
the person's own — the classification Quest's board makes of the same state, seq 234), the
tool's dock short case uses that classification and Quest's wording (Opened the Lore pane at 80 columns; the width is kept.), and the header's mode control shows the current state
with the key as its hint (Normal · z for full/Full · z for normal) rather than the
action it used to name.