Skip to content

release: 0.4.0 — FTS5 search, theme system v2, TUI redesign, curator lifecycle - #79

Closed
ApiliumDevTeam wants to merge 23 commits into
mainfrom
release/0.4.0
Closed

ApiliumDevTeam wants to merge 23 commits into
mainfrom
release/0.4.0

Conversation

@ApiliumDevTeam

Copy link
Copy Markdown
Collaborator

Release 0.4.0

Major release with FTS5 session search, theme system v2 (custom themes, colorblind, monochrome), complete TUI redesign, skill curator lifecycle, and migration to the official agent stack.

Highlights

Search

  • FTS5-backed session search with BM25 ranking, multi-word queries, role/timestamp/session filters, and snippet generation. Falls back to linear scan when node:sqlite is unavailable.

Themes

  • 13 built-in themes including colorblind-optimized (Okabe-Ito) and monochrome palettes.
  • Custom themes from ~/.mayros/themes/*.json.
  • Auto-detection of terminal dark/light preference.

Terminal UI

  • Inline image rendering in tool results (Kitty/iTerm2, text fallback).
  • Cross-platform clipboard (Windows, Wayland, WSL).
  • Per-section detail visibility (tools/thinking: hidden/collapsed/expanded).
  • Incremental streaming markdown (O(n²)→O(n)).
  • Extended keyboard protocols (Kitty/modifyOtherKeys).
  • Accessible TUI command parity.
  • Files split into focused modules (tui.ts 1087→591, handlers 1402→351).

Skills

  • Skill curator lifecycle: activity tracking, auto-archive of stale skills (30/90 day thresholds).

Agent stack

  • Migrated to @earendil-works/*@0.80.6 (official scope).
  • 21 runtime dependencies refreshed.

Breaking changes

  • Vim mode removed (was silently broken). Emacs/readline keybindings remain.
  • Agent dependency scope changed to @earendil-works.
  • CLI palette accent changed from orange to gold (unified with TUI).

Release preparation

  • Circular dependency in session-search fixed (CLI was crashing).
  • Plugin versions synced across 54 extensions.
  • CHANGELOG updated for 0.3.0–0.4.0.
  • README updated with accurate feature list.
  • /vim removed from help, version resolution fixed, theme config widened.

Test plan

  • pnpm build — succeeds
  • pnpm tsgo — 0 errors
  • pnpm lint — 0 errors, 359 warnings
  • pnpm release:check — npm pack contents OK
  • node mayros.mjs --version — shows 0.4.0
  • node mayros.mjs --help — lists all commands

Formalize the lint configuration that was previously running on oxlint
defaults via the --type-aware flag. The config:
- Activates type-aware rules (no-floating-promises, no-misused-promises,
  await-thenable, no-base-to-string, restrict-template-expressions).
- Formalizes the repo no-explicit-any policy as a warning.
- Disables noisy rules in test files where type strictness is less
  valuable (unbound-method, no-floating-promises, any).
- Keeps correctness category as warnings, not errors, to preserve a
  green baseline while surfacing 364 items of technical debt for
  incremental cleanup.
Add a Dependency Supply Chain section to SECURITY.md covering the
controls the project already enforces via package.json:
- The 48-hour release age floor (minimumReleaseAge: 2880).
- The rationale requirement for every pnpm.overrides entry, tied to a
  CVE or regression.
- The hard rule that patchedDependencies must use exact versions.
- Lockfile discipline: frozen-lockfile in CI, deps: commits for
  dependency changes, reviewed transitive bumps.
- The onlyBuiltDependencies allowlist limiting native build scripts.

This formalizes existing practice as written policy so maintainers and
contributors have a single source of truth for dependency trust
decisions.
…undary

Introduce a Trust Model section that states the project's governing
security principle: operating-system level isolation is the only
load-bearing boundary, and every in-process defense (approval gate,
output redaction, scanners, rate limiters, the WASM sandbox) is a
heuristic that reduces attack surface but does not contain a
determined adversary with in-process code execution.

The section classifies real boundaries (separate users, containers,
VMs, namespaces, seccomp, Landlock) against in-process defenses, and
gives concrete implications for operators running untrusted skills and
plugins. This sharpens the existing Plugin Trust Boundary section,
which now reads as a specific case of the general model.
Add a CI step on pull requests that fails when pnpm-lock.yaml changes
without a deps-scoped commit or a corresponding manifest change
(package.json, pnpm-workspace.yaml). This implements the lockfile
discipline documented in SECURITY.md as an automated gate rather than
relying on review alone.

The check is implemented as scripts/check-lockfile-policy.mjs so it can
also run locally (node scripts/check-lockfile-policy.mjs --base <ref>)
before pushing. On CI it only runs on pull_request events, where the
base ref is well-defined.
Remove every `as any` escape hatch in production code (the 20
occurrences flagged by no-explicit-any once the rule was formalized).
Each replacement uses a concrete type:

- mattermost/channel.ts: params is already Record<string, unknown>, so
  the casts were unnecessary — access the fields directly with typeof
  narrowing.
- agent-mesh/index.ts: model the on-disk mayros.json and auth-profiles
  shapes with structural types instead of Record<string, any>; forward
  the heterogeneous Mamoru gateway handlers through a typed callable.
- feishu/bot.ts: narrow the Lark SDK response with a minimal
  FeishuUserResponse type; widen the logger signature to unknown[].
- feishu/docx.ts: introduce a FeishuBlock structural type for the
  document blocks used by sortBlocksByFirstLevel, with a type-guard
  filter.
- mcp-server/index.ts: type registerCli's program as Command and the
  dashboard respond callback with its structural signature.

Also extend the oxlint test override to *.test-helpers.ts so test
fixtures are not held to production type strictness.
Formalize the project's prompt-cache invariant and add a drift signal to
the cache trace so cache-breaking changes become visible.

AGENTS.md:
- Add a Prompt Cache Discipline section stating the governing principle:
  the system prompt must stay stable across runs that have no reason to
  change it, slash commands that mutate state invalidate only on the
  next turn, and hooks must be deterministic. This makes the contract
  explicit for contributors.

cache-trace.ts:
- Track the last system digest per session key in a module-level map.
- When wrapStreamFn sees a different system digest for the same session
  on a consecutive call, emit a new cache:system-drift event carrying
  both the current and previous digests. This turns silent cache
  invalidations (which multiply token cost) into a diagnosable signal.
- Propagate previousSystemDigest through the event pipeline.

cache-trace.test.ts:
- Unit tests covering first-call (no drift), drift on change, stability
  across repeated calls, and independent per-session tracking.
Add docs/platforms/tui-redesign.md capturing the current state of the
terminal UI, the gaps found during an internal audit, and a prioritized
P0/P1/P2 roadmap for the next redesign pass.

The audit covers rendering, input, slash commands, themes, vim mode,
accessibility, and platform coverage. It documents the architectural
constraints (shared terminal UI dependency as rendering floor, mandatory
gateway, mutable state, two parallel TUI implementations, two palette
systems) that bound the redesign, and calls out two P0 items that block
trustworthy feature work: verifying the vim bridge is actually wired,
and bringing the accessibility TUI to feature parity.
…servability (#65)

## Summary

First pass of a stabilization effort focused on type safety, security
documentation, and cache observability. No behavior changes to
user-facing features.

- **Lint configuration**: add `.oxlintrc.json` to formalize the
type-aware rules (no-floating-promises, no-misused-promises,
await-thenable, no-base-to-string, restrict-template-expressions) that
were running on defaults. Keeps the green baseline while surfacing
technical debt for incremental cleanup.
- **Type safety**: replace every `as any` escape hatch in production
code with proper types (structural types, type guards, inferred
signatures). Removes the soft type-escape across five modules.
- **Security documentation**: add a dependency supply-chain policy
section (release-age floor, override rationale, patched-dependency
version rule, lockfile discipline) and a trust-model section stating
that OS-level isolation is the only load-bearing boundary, with
in-process defenses classified as heuristics rather than containment.
- **CI**: add a pull-request gate that fails when `pnpm-lock.yaml`
changes without a `deps:`-scoped commit or a manifest change. Implements
the documented lockfile discipline as an automated check; also runnable
locally.
- **Cache observability**: formalize the prompt-cache invariant in the
contribution guide and add a system-prompt drift signal to the cache
trace. When the system digest changes between consecutive turns of a
session without a session restart, a `cache:system-drift` event is
emitted so silent cache invalidations become diagnosable. Includes unit
tests.
- **TUI roadmap**: document the current terminal UI state and a
prioritized P0/P1/P2 redesign plan covering rendering, input, vim mode,
accessibility, and platform coverage.

## Test plan

- [x] `pnpm tsgo` passes (0 errors)
- [x] `pnpm lint` passes (0 errors, 344 warnings — pre-existing
technical debt surfaced by the new config)
- [x] `pnpm exec vitest run src/agents/cache-trace.test.ts` — 4/4 new
tests pass
- [x] `node scripts/check-lockfile-policy.mjs --base origin/dev` —
passes locally
- [x] All 13 changed files pass `pnpm exec oxfmt --check`
The @mariozechner/pi-{agent-core,ai,coding-agent,tui} packages were renamed
and deprecated ("use @earendil-works/... going forward"); their last published
version (0.73.1) is still affected by 3 open advisories with no fix. Migrate
the whole suite to @earendil-works/pi-* ^0.80.2, which carries the fixes.

- Repoint all import specifiers @mariozechner/pi-* -> @earendil-works/pi-*
  across src, extensions, scripts, skills, docs and the mac packaging script.
- Bump the 4 root deps to ^0.80.2.
- Adapt to the 0.54 -> 0.80 API surface:
  - pi-ai: legacy helpers (complete/completeSimple/stream/streamSimple/getModel/
    getEnvApiKey/streamOpenAIResponses) moved to the `@earendil-works/pi-ai/compat`
    subpath; OAuth helpers to `@earendil-works/pi-ai/oauth`; deep `/dist/...`
    imports repointed (types -> root, google-shared -> /api); onPayload callback
    now (payload, model); ProviderHeaders allows null values; typebox re-exported
    from pi-ai.
  - pi-tui: dropped the `Editor` infix (getKeybindings/setKeybindings/
    KeybindingsConfig/KeybindingsManager); KeybindingsManager(definitions,
    userBindings?); namespaced keybinding ids; async 4-arg AutocompleteProvider.
  - pi-coding-agent: codingTools -> createCodingTools(cwd); Skill.source ->
    Skill.sourceInfo.source; ModelRegistry.create(...)/getApiKeyForProvider;
    generateSummary headers param; createAgentSession tools is a name allowlist.
  - pi-agent-core: agent.replaceMessages/setSystemPrompt -> agent.state.*.
- Add pnpm override "@apilium/mayros": "workspace:*" so the bluebubbles plugin
  resolves its peer to the workspace package instead of pulling the published
  0.1.1, which bundled the old vulnerable pi suite.

Closes the 3 remaining pi-coding-agent advisories: pnpm audit no longer reports
any @mariozechner/pi or pi-coding-agent finding, and @earendil-works has none.

Verified: pnpm install, pnpm tsgo (0 errors), pnpm lint (0 errors), oxfmt on
changed files. Full test suite not run here (native deps + live keys); needs a
CI run and a smoke test of the agent runtime before merge.
Move the four core libraries to the latest patch on the 0.80 line
(@earendil-works/pi-agent-core, pi-ai, pi-coding-agent, pi-tui: 0.80.2
-> 0.80.6). The 0.80.6 release internally consumes zod 4.4.3, so align
the workspace to zod ^4.4.3 and add a pnpm override pinning zod to 4.4.3
to keep a single resolved version across the tree.

Refresh 21 runtime and dev dependencies to their current minor/patch
releases: @aws-sdk/client-bedrock, @clack/prompts, @grammyjs/types,
@homebridge/ciao, @noble/curves, @slack/bolt, @slack/web-api,
@vitest/coverage-v8, ajv, dotenv, grammy, jiti, lit, markdown-it, oxlint,
semver, tslog, tsx, vitest, ws.

Exact-pinned and security-overridden dependencies (hono, tar, undici,
yaml, typebox, playwright-core, etc.) are left untouched by design.

Skip the symlink-based config test on Windows where unprivileged symlink
creation is not permitted.
…cy (#67)

* fix(tui): resolve readline temporal-dead-zone in accessible mode

The accessible TUI created its readline interface after wiring the
gateway client's disconnect handler and after client.start(). If the
client disconnected in that window, the handler referenced the readline
binding before its initialization, throwing a ReferenceError. Move the
readline creation before the disconnect wiring so the reference is
always initialized.

* feat(tui): make Ctrl+C abort the active run

Ctrl+C now follows a three-state priority: abort an active run, clear
non-empty input, or exit on a second press within one second. Escape
remains a secondary abort path. This unblocks users of modal editors
(where Escape is consumed to switch modes) and aligns the interrupt
behavior with terminal conventions.

* feat(tui): share slash-command handling between graphical and accessible modes

The accessible TUI previously supported only /quit and /exit. Introduce a
renderer-agnostic shared command core (shared-commands.ts) that calls
the gateway client directly and reports results through an injected
text sink. The accessible TUI now routes /abort, /new, /reset,
/compact, /status, /sessions, /session <key>, /model, and /help
through this core, reaching feature parity with the graphical TUI for
every command that does not require a visual picker.

The graphical TUI continues to use its full handler for overlay-based
commands. Both TUIs share logic (the gateway calls and command parsing)
without sharing presentation.

* fix(tui): render diffs with theme colors

The diff renderer hardcoded chalk.green/red/cyan/white, so added and
removed lines were hard to read under light or high-contrast themes.
Thread optional DiffColors through renderDiff and formatDiffStatsLine;
when the TUI calls them it passes the active theme's success/error/
accent/dim functions, keeping diff colors consistent across every theme
preset. Callers without a theme fall back to the previous defaults.

* refactor(terminal): align CLI palette with the TUI dark palette

The CLI and the terminal UI used different accent colors (orange in the
CLI, gold in the TUI), so running `mayros` then `mayros code` showed
two different identities. Derive the CLI palette tokens from the TUI dark
palette so both surfaces share accent, success, warn, and error values.
The CLI's accentBright maps to the TUI accentSoft; accentDim is a
darkened accent; info reuses accentSoft. The visual identity is now
consistent across every Mayros surface.

* feat(tui): enable extended keyboard protocols where supported

Add term-capabilities.ts to detect and manage extended keyboard
protocols. Capable terminals (kitty, WezTerm, ghostty get the kitty
keyboard protocol; iTerm, vscode, tmux, windows-terminal, Apple
Terminal get xterm modifyOtherKeys level 2) are upgraded at TUI startup
so modifier combinations like Shift+Enter and Ctrl+Shift survive instead
of being collapsed by plain raw-mode stdin. The protocol is popped on
exit/SIGINT/SIGTERM so the terminal is restored for the shell.

Detection is conservative: terminals outside the allow-list get no
upgrade, so escape sequences are never emitted to a terminal that cannot
parse them back.

* chore(tui): remove unused input-history store

The input-history store was never wired into the TUI main loop; it was
dead code that looked like a feature. Remove it and its test to reduce
confusion. Cross-session input history can be reintroduced as a real
feature later, but shipping a dormant implementation invites false
confidence.

* test(tui): align session rename test with the new API and skip symlink on Windows

The session rename API field changed from displayName to label in the
0.80 surface; update the assertion to match the implementation. The
symlink-follows test requires Developer Mode or admin rights to create
a symlink on Windows (EPERM otherwise), so skip it on win32; CI on
Linux exercises it normally.
…ility (#69)

* feat(tui): auto-detect dark/light theme from the terminal

When config.ui.theme is unset or set to "auto", query the terminal for
its color-scheme preference before the first render. The detection uses
two concurrent queries with a 150 ms timeout each: the DSR color-scheme
report (CSI ? 996 n, a direct dark/light answer) and the OSC 11
background-color query (parsed to RGB and classified via Rec. 709
relative luminance). The fastest signal wins; an unresponsive terminal
falls back to the default dark preset without blocking startup.

Add "auto" to the ui.theme config type so users can opt in explicitly,
and document the query ladder in term-capabilities.ts. The manual /theme
command continues to override the detected preset for the session.

* test(tui): cover paste-collapse and grapheme caret behavior

Add no-regression coverage for the two input features inherited from the
terminal UI dependency: grapheme-aware caret movement (Intl.Segmenter)
and paste-collapse markers. Both are implemented in the Editor class the
TUI extends, so the tests pin the environment contract rather than the
Editor internals.

The grapheme tests verify that emoji with skin-tone modifiers, flag
emoji, and CJK characters each count as a single grapheme — the
invariant the caret relies on. The paste-marker tests verify the marker
shape ([paste #N +M lines], [paste #N M chars], [paste #N]) so that
cursor movement and submission expansion keep working if the format
changes upstream.

Also update the welcome-screen quick-start hint to reflect that Ctrl+C
now aborts the active run (Esc remains a secondary path).

* perf(tui): split streaming markdown at the stable block boundary

Re-parsing the full markdown on every streaming delta is O(n²) over a
response. Split the assistant message text at the last stable block
boundary (a blank line outside any open code fence) into a stable prefix
and an active suffix. Only the suffix is re-parsed per delta; the prefix
reuses the Markdown component's internal render cache, which turns the
per-delta cost into O(n).

Add stream-boundary.ts with a pure, unit-tested findStableBoundary
function that walks backwards through blank lines and skips any that
sit inside an open code fence. Refactor AssistantMessageComponent to
hold two Markdown instances (prefix + suffix) and only update the
prefix when its text actually grows.

* feat(tui): per-section detail visibility for tools and thinking

Replace the binary expanded/collapsed toggle with a three-state model:
hidden, collapsed, and expanded. Each section cycles independently via
its keyboard shortcut.

- Tools (Ctrl+O): hidden renders only the header line, collapsed shows a
  12-line preview, expanded shows the full output.
- Thinking (Ctrl+T): hidden suppresses thinking text, collapsed and
  expanded both show it (a truncated thinking mode is deferred to a
  follow-up that restructures the composer).

The section state is the new source of truth in TuiStateAccess; the
existing toolsExpanded and showThinking fields are kept as compatibility
shims. Add a nextSectionState helper and unit tests for the cycle.
The vim mode implementation was structurally broken: the editor bridge
that connects vim motions to the buffer was never wired, so every
editing operation silently no-op'd while the mode indicator claimed vim
was active. Keys were consumed without editing, leaving users with a
non-functional editor.

Disable vim honestly instead of leaving the broken experience: /vim now
reports that the feature is unavailable, the dead handler and tests are
removed (730 LOC), all vim wiring is stripped from the TUI, the config
flag is deprecated, and docs are updated. Emacs/readline-style
keybindings remain available.
…72)

* feat(tui): custom themes, colorblind palettes, and monochrome mode

Generalize the theme system so users can define custom palettes in
~/.mayros/themes/*.json. Each file must contain the 22 palette color
tokens as #RRGGBB hex strings; the loader validates, caches by mtime,
and registers them so /theme <name> and config.ui.theme accept custom
names alongside the built-ins.

Add three new built-in palettes:
- colorblind-dark and colorblind-light: Okabe-Ito hues that avoid the
  red/green pairing for error/success (error = vermilion, success = sky
  blue), so deuteranopic and protanopic users get distinguishable
  semantic colors.
- monochrome: all tokens use the same foreground, for NO_COLOR
  environments or users who prefer a minimal terminal.

Generalize ThemePreset from a closed union to string (with BuiltinPreset
for the 13 built-ins), add a custom palette registry, and relax the
/theme handler and config guards to accept custom names. The loader
runs at TUI startup before the config theme is resolved.

* chore(tui): dedupe theme presets and migrate stderr to subsystem logger

Remove the duplicated THEME_PRESETS array from commands.ts (it was a
local copy that had already drifted — missing the three new palettes
added in the theme system update). Import the canonical list from
palettes.ts instead so there is a single source of truth.

Migrate the three process.stderr.write call sites in
tui-command-handlers.ts (fast-mode) and compact-handler.ts to the
shared subsystem logger (createSubsystemLogger("tui")), so TUI
diagnostics route through the same logging infrastructure as the rest
of the codebase instead of writing raw stderr.
)

* fix(tui): cross-platform clipboard support for Windows and Wayland

The /copy command and teleport export hardcoded pbcopy/xclip, so they
were broken on Windows (no pbcopy/xclip) and Wayland (no xclip under
pure Wayland). Replace the spawn and shell-pipeline approaches with the
existing cross-platform copyToClipboard helper from infra/clipboard.ts,
which has a fallback chain covering pbcopy, xclip, wl-copy, clip.exe,
and PowerShell Set-Clipboard.

Add Windows and Wayland support to clipboard image capture:
- Windows: PowerShell + System.Windows.Forms to read clipboard PNG.
- Wayland: wl-paste -t image/png when WAYLAND_DISPLAY is set, with
  xclip fallback for XWayland sessions.

* feat(tui): render image content blocks inline where supported

Tool results that contain image content blocks now render inline using
the terminal image component when the terminal supports it (Kitty
graphics protocol or iTerm2 inline images). The Image component handles
capability detection internally and falls back to a text placeholder
([image/png 12kb]) when the terminal cannot display images, so no escape
sequences leak to unsupported terminals.

Backend change: stop stripping the base64 data from image content blocks
in sanitizeToolResult. The omitted: true flag already prevents the image
from entering the model context, so retaining data does not inflate
token usage — it only makes the base64 available for TUI rendering.

* refactor(tui): extract pure helpers from tui.ts into tui-helpers.ts

Move 7 standalone functions (createEditorSubmitHandler,
shouldEnableWindowsGitBashPasteFallback, createSubmitBurstCoalescer,
resolveTuiSessionKey, tryInlinePairingApproval,
resolveGatewayDisconnectState, createBackspaceDeduper) out of tui.ts
into a dedicated tui-helpers.ts module. These functions are pure
factories and resolvers with no dependency on the TUI instance or
mutable state, and are already covered by tui.test.ts.

Reduces tui.ts from 1087 to 883 LOC. Further extraction of the state
factory, status renderer, and connection handlers is tracked as a
follow-up — the remaining sections are tightly coupled to runTui's
closures and require more careful refactoring.
* feat(search): FTS5-backed session search with BM25 ranking

Replace the linear substring scan with a dedicated SQLite FTS5 index for
session message search. The index lives at
~/.mayros/agents/<agentId>/sessions/search.sqlite and uses an
external-content virtual table with triggers for automatic sync.

The search now supports multi-word queries with BM25 relevance ranking,
role/timestamp/session filters, and snippet generation via the FTS5
snippet() function. Indexing is incremental (lazy sync on each query,
skipping unchanged files by mtime+size), so no background watchers are
needed.

The public searchSessions API is unchanged — it tries FTS5 first and
falls back to the original linear scan when node:sqlite is unavailable,
so search always works regardless of the runtime.

* feat(search): FTS5-backed session search with BM25 ranking

Replace the linear substring scan with a dedicated SQLite FTS5 index for
session message search. The index lives at
~/.mayros/agents/<agentId>/sessions/search.sqlite and uses an
external-content virtual table with triggers for automatic sync.

The search now supports multi-word queries with BM25 relevance ranking,
role/timestamp/session filters, and snippet generation via the FTS5
snippet() function. Indexing is incremental (lazy sync on each query,
skipping unchanged files by mtime+size), so no background watchers are
needed.

The public searchSessions API is unchanged — it tries FTS5 first and
falls back to the original linear scan when node:sqlite is unavailable,
so search always works regardless of the runtime. Results are sorted by
timestamp descending and sessionsSearched counts files scanned, matching
the original contract.

* feat(skills): curator lifecycle with activity tracking and auto-archive

Add a skill lifecycle manager that automatically transitions skills
through active → stale → archived states based on invocation activity.

Activity tracking (activity-store.ts): a JSON sidecar at
~/.mayros/skills/skill-activity.json records lastInvokedAt,
invocationCount, and firstInvokedAt per skill. Updated on every skill
invocation.

Lifecycle metadata: extend MayrosSkillMetadata with state, pinned,
created, and updated fields. Parsed from SKILL.md frontmatter.

Curator sweep (skill-curator.ts): a self-throttled background sweep
(mirroring session-reaper.ts) that transitions active skills to stale
after 30 days of inactivity and stale skills to archived after 90 days.
Pinned skills are never transitioned. Only agent-created skills
(source: mayros-managed) are eligible for archival — user skills can
go stale but are never auto-archived. Archived skills are moved to
~/.mayros/skills.archived/.
* TUI: split status renderer, keybindings, and connection handlers from tui.ts

* TUI: split command handlers into per-group modules with dispatcher
The FTS5 session search module imported extractTextContent and search
types from session-search.ts, while session-search.ts dynamically
imported session-search-fts.ts — creating a circular dependency that
deadlocked the bundler's module initialization order and crashed every
CLI invocation (mayros --version, --help, all commands).

Extract extractTextContent and the SearchOptions/SearchResult/
SearchSummary types into a shared session-search-types.ts module that
neither file imports from the other. Verified: pnpm build succeeds,
node mayros.mjs --version and --help both work, all 27 search tests
pass.
Align all 54 extension package.json versions and changelogs with the
root package via pnpm plugins:sync. Required for pnpm release:check
to pass.
Write CHANGELOG entries for 0.3.0 through 0.4.0 (file was two minor
versions behind). The 0.4.0 entry covers all 10 merged PRs: FTS5
search, theme system v2, inline images, cross-platform clipboard,
per-section visibility, streaming markdown, skill curator, keyboard
protocols, prompt cache drift detection, accessible TUI parity, agent
stack migration, and the TUI modularization — plus the breaking
changes (vim removal, scope migration, palette accent change).

Update README: theme count (13 built-in + custom, not 3), add FTS5
search, colorblind/monochrome palettes, auto-theme detection, inline
images, cross-platform clipboard, per-section visibility, and keyboard
protocols to the feature list.
…olution, widen theme config

Remove the disabled /vim command from the TUI help text and command
list — a non-functional command in the help listing is confusing UX.

Fix CORE_PACKAGE_NAME in version.ts from "mayros" to "@apilium/mayros"
so that --version resolves correctly from package.json instead of
relying solely on build-info.json as a fallback.

Widen the config.ui.theme type from a closed union to string, so users
can set any built-in preset (colorblind-dark, monochrome, etc.) or a
custom theme name from ~/.mayros/themes/*.json in their config file.
@github-actions

Copy link
Copy Markdown

This pull request has been automatically marked as stale due to inactivity.
Please add updates or it will be closed.

@github-actions github-actions Bot added the stale label Jul 22, 2026
@github-actions

Copy link
Copy Markdown

Closing due to inactivity.
If you believe this PR should be revived, please open a new one with updated context.

@github-actions github-actions Bot closed this Jul 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant