v0.18 Theme Studio, Native theme library, Theme Bridge and Prompt None - #315
Open
raiseCatError wants to merge 16 commits into
Open
raiseCatError wants to merge 16 commits into
raiseCatError wants to merge 16 commits into
Conversation
…d host semantics - Prompt provider None: composer only (no prompt row, modules, right prompt or marker); promptless history snapshots; /prompt and Setup previews. - Historical prompt presentation Full / Compact / Minimal / Off over the unchanged stored snapshot. - Native theme library: stable-id assets (Custom/Imported by provenance), bounded, migrated from the single customTheme (kept as a deterministic mirror of the active asset), stable theme references and one pure semantic palette resolver. - Theme Studio with Built-in | Imported | Custom | Import tabs over one editor and the real Native preview; import parses and previews first. - Importers: NMSh JSON, Base16, Base24, Windows Terminal, Oh My Posh (JSON/YAML/TOML, static colors only), Kitty, Ghostty (allowlist), iTerm2 (bounded plist, no entities), WezTerm TOML (Lua rejected). Data-only parsers: yaml, smol-toml, fast-xml-parser. - Theme Bridge: per-target Independent / Follow NMSh / Choose theme with a master switch (default Off); fzf launch colors, less/man termcap and LS_COLORS through one validated shell-environment sink applied by the zsh/Bash/Fish adapters, tmux/Neovim/Vim managed artifacts with an ownership ledger, staged validated writes and exact reviewed includes; bat/delta reported as unsupported rather than faked. - /theme-bridge, /appearance destinations, Setup and Settings selection. - OSC 7 and OSC 133 projected from the OSC 777 lifecycle on capable hosts; NMSh-authored OSC 8 links kept distinct from raw PTY links.
… tests; docs - Tests: library migration/actions/export/deletion, every importer with malformed, oversized, unsafe and lossy fixtures, Theme Bridge modes, mappers, environment sink in real zsh/Bash/Fish, ownership ledger, exact includes, tmux/Vim artifacts loaded by real tmux/Vim, Prompt None layouts and history, historical prompt levels, OSC 7/133/8, Theme Studio and /theme-bridge UI, Setup rows, and live end-to-end NMSh sessions. - Fixes found by them: Prompt None framed as the one-line composer in the two-line layout, include planning on a symlinked home, Setup/Settings action rows keep "Open ›". - Docs: help, README, CHANGELOG and docs/design/theme-bridge.md.
27 of 37 tasks
…irmed activation Generated nmsh-bridge.toml in Helix's themes directory (syntax, markup, diff, diagnostic and editor UI scopes over a named palette), ownership ledger and staged validated writes, one confirmed theme assignment placed before the first table of config.toml, never replacing a user-selected theme, exact removal, factual status, tests and docs.
…ng colors, preview Chroma, /motion - Theme Bridge switch plus Apply themes policy (Manual / Follow NMSh / Choose theme with one global theme); per-target settings stay the Manual state and come back exactly; capability classes (direct, managed, detected); delta shown but never editable or inherited. - /theme-bridge is one panel: grouped table, inline expansion, Esc collapses first, view-only rows under global policies, Remove managed setup vs Set Independent, Review all / Apply all with a combined review defaulting No. - bat: generated data-only .tmTheme in bat's themes directory, reviewed bat cache --build with typed argv verified by bat --list-themes, BAT_THEME only when ready, automatic rebuilds only after that approval, Duplicate source to Custom. - File listing colors: GNU ls/gls get LS_COLORS and a session-only color-auto wrapper (never shadowing user aliases/functions); macOS/BSD ls gets CLICOLOR and LSCOLORS. - Integrations health planner; Helix activation state detection. - Theme Studio: local Preview Chroma (default Off) and Duplicate current theme to Custom; Setup Prompt/Appearance preview switch; Chroma row in Setup Prompt. - /motion opens the existing Motion screen.
…registry, integrations, dotfiles import, command surface cleanup
…against the detached retention cap
- Dotfiles: exact-copy is an explicit, fail-closed registry capability
(exactCopy validator). Parseable is not safe: Starship, Helix and bat
configs can run commands, so they are inspect-only with a stated reason.
Apply re-checks authority, so a forced copy mode writes nothing.
- tmux: the pane frontend is a fixed /bin/sh program; the NMSh path is
passed as shell-quoted argv data ("$1"), never as program text. Any
absolute path without control characters works literally; the validator
accepts only that exact form.
- Detached output: prompt metadata (alias/function lists) no longer
consumes the output retention budget, which made in-limit output look
truncated on Ubuntu (global compinit). The output cap is unchanged.
- Shell switch test reports shell state on timeout.
- Remove a stray committed .swp; ignore *.swp.
raiseCatError
force-pushed
the
feature/v018-theme-bridge
branch
from
October 5, 2026 00:24
d40e7a8 to
df92d51
Compare
…t-literal regression tests
Bash alias-expands `ls()` while parsing, so with ls already an alias
(Ubuntu's default bashrc) the generated bootstrap failed to parse and the
managed Bash never became ready. Use the `function ls { ... }` form; zsh
and fish were unaffected.
- Real bash/zsh/fish tests of the listing wrappers: parse with ls/gls
aliased, --color=auto before user argv, existing alias/function kept,
missing executables not wrapped, Off removes only NMSh's wrapper.
- Live managed Bash with an aliased ls in ~/.bashrc reaches ready.
- Native prompt: hostile Git branch names, repository names and context
values (zsh % escapes, $()/backtick/${}, quotes, ANSI/OSC/C1) render
literally and inertly in live, snapshot and historical prompts; no
canary runs. No renderer change was needed.
…l provenance
Shell frameworks and prompt engines
- /tools detects tools by an explicit strategy (executable or a registered
filesystem detector). Oh My Zsh, Powerlevel10k, Prezto, Zim, zinit and
Antidote are found by documented layouts only; detection grants no
install, uninstall, configuration or provider authority. Zsh-only tools
stay visible under Bash/Fish ("used by Zsh only").
- Oh My Zsh: guided install that never runs the installer. NMSh backs up
and fingerprints .zshrc, shows the official source and the documented
KEEP_ZSHRC=yes CHSH=no RUNZSH=no (REPO/REMOTE/BRANCH pinned) steps, and
verifies afterwards; an unexpected .zshrc change is reported, never
silently restored. .zshrc.pre-oh-my-zsh comparison with a reviewed
restore (default No, backup first, atomic replace, no merge).
- Powerlevel10k in /tools routes to the existing detector, provider and
p10k configurator.
- Oh My Posh: new Prompt provider (oh-my-posh print primary, argv only,
no TTY, bounded, timed out, cancellable, Native fallback) and a curated
homebrew/core install; Theme Studio import of its config stays static.
- Ask: typed routes for these requests; dotfiles treats .p10k.zsh, Oh My
Zsh themes/plugins and Oh My Posh configs as inspect-only.
Keep Awake (/caffeinate, /awake, /zoomies)
- One controller over the OS mechanism: /usr/bin/caffeinate,
systemd-inhibit (idle/sleep only, Display reported unsupported) and
SetThreadExecutionState from a fixed PowerShell helper (no away mode,
no powercfg). Detached so it outlives the window; ownership is a token
plus the exact command line, so unverifiable records are cleared and
nothing is killed. Strict timeouts, status, idempotent stop, confirmed
mode changes that start the new assertion first.
Homebrew
- A Homebrew keg is recognized from the Cellar layout and Homebrew's
INSTALL_RECEIPT; /update, /version, /status and doctor say so and point
to brew upgrade nmsh instead of touching the Cellar.
- Release workflow proposes the raiseCatError/homebrew-tap formula update
as a pull request for stable releases only.
…h; Keep Awake ownership check uses absolute PowerShell - The guided install's file lived at a predictable /tmp name another local user could replace between download, inspection and running. - On Windows the ownership check resolved powershell.exe through PATH; it now uses the System32 path like the backend itself.
…ser chrome; /tools selection is a real band Keep Awake - /caffeinate, /awake and /zoomies with no argument opened a panel that was never drawn (it was missing from the active-panel set), so the composer looked frozen, keys went to the hidden panel, Enter quietly started an assertion and only Ctrl+C (the panel's close key) gave the prompt back. The panel is registered (the Mise panel had the same omission), and a start, an accepted mode change or a stop now closes it and records one line under the command that opened it. The assertion was always an NMSh-owned detached process; nothing ran through the shell, and a typed shell caffeinate stays an ordinary foreground command. - Presentation: while active, "Awake · <mode>" is NMSh composer chrome, never prompt or provider output. Placement Composer edge (default) takes a plain top divider, else the bottom divider when a header prompt owns the top edge, else one row next to the composer; Above composer and Input row (only when the edit is single-line with room to spare; the editor's wrapping, caret, selection and hit testing use the narrowed width) are explicit choices. The decision is made with the screen plan each frame and never rewrites the saved setting. - Both composer edges render through one exact-width edge renderer, also used by the Chroma repaint, so an animated divider never erases the accessory and transition tints stay off it. - Status Strip: an active Keep Awake is always in an enabled strip (no per-item switch); it narrows (label, Awake, glyph) before anything would drop it, and a disabled strip stays disabled. - Idle reminder (default On, 30 s without NMSh input): adds the time and a muted /zoomies stop on the edge when it fits, else one muted row; the next input collapses it. Screensaver status (default On, Bottom left, six positions) is a small separate element; the saver and Vespyr are untouched. - Display Text / Icon / Icon + text through the semantic icon set (Safe mode keeps text). Colors are theme roles: accent while active, muted for the reminder. Off renders nothing anywhere. - The panel gains Duration and Presentation, Screensaver and Status Strip sections. Ask answers status questions and plans start, change, timed and stop requests through the same controller, deterministically. - A deterministic-only inert backend (NMSH_DETERMINISTIC=1 with NMSH_KEEP_AWAKE_BACKEND=inert) runs the real slash, controller, ownership and presentation paths for tests and recorded demos without keeping a machine awake. /tools - The selected row uses the shared selected band (the active tab's treatment): full width, bold label, quiet text lifted onto the band, and reverse video without color. README art - scripts/demos/vespyr-svg.ts renders a small transparent divider from Vespyr's real sprite pixels and blink pose.
…TECTURE.md Docs - README rewritten for a first visit: what NMSh is and is not, highlights, a short hero clip, a visual tour, source install (no Homebrew command until the tap exists), core commands, Keep Awake, shells/frameworks/ providers, terminals, accessibility, safety and ownership, limitations. Stale zsh-only, fixed-bottom, bat/Theme Bridge and badge claims fixed. - AGENTS.md: current shell model, composer edges and the screen plan, safety boundaries, current unreleased surfaces, PR #315, no-attribution rule, demo command. SECURITY.md: supported versions and the boundaries NMSh keeps. SUPPORT.md: nmsh doctor. CONTRIBUTING, ROADMAP (PR #315 in development; OSC 0/2 still deferred), llms.txt and the Theme Bridge doc updated; new docs/design/keep-awake.md and docs/demos.md. - ARCHITECTURE.md is linked as the high-level overview from README, CONTRIBUTING, AGENTS and llms.txt. - Prompt None: help, the prompt picker and Setup said "no marker"; the input marker has always stayed, and the wording now says so. Demos - npm run demos records every scripts/demos/*.tape with VHS against a disposable demo home (fixture repo ~/Projects/demo, neutral identity, no network, update checks and npm's notifier off), encodes GIFs and stills from VHS frames with ffmpeg, then stops everything still holding files in the demo home and fails if anything survives. Keep Awake is recorded with the inert backend; sessions detach with SIGHUP as a closing window does. - Clips: hero, composer and prompts, Theme Studio, Theme Bridge, providers and tools, live sessions, screensavers with Vespyr, Keep Awake; three stills; a Vespyr divider generated from the real sprite. - The old asciinema/tmux recorder, which recorded the real home directory, is removed; dev/tapes stays for development captures. - tests/docsAssets.test.ts checks local doc links and images, that every published clip has its tape, and that docs, tapes and vector art name no real home path or secret.
Clarify that NMSh should not be configured as the system/login shell. Explain that zsh, Bash or Fish remains the real shell underneath NMSh, while terminal apps such as Ghostty or Zed can be configured to launch NMSh automatically. This makes the distinction between “default terminal command” and “login shell” explicit and keeps Terminal.app or another host available as a normal-shell fallback.
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.
Refs #304
One implementation PR for the v0.18 Theme Studio / Theme Bridge pass, plus the shell-framework, prompt-provider, Keep Awake and Homebrew-provenance work that followed QA. No merge, release, version bump or publish: package metadata intentionally stays at 0.16.0.
Prompt
promptless), and history never substitutes another prompt./transcript, Settings, Setup): presentation only, over the unchanged stored snapshot.oh-my-posh print primarydirectly. Arguments are argv only (--pwd,--status/--no-status,--terminal-width,--escape=false,--config), with no TTY, bounded output, a timeout that kills the process group, and cancellation. Its ANSI goes through the same span parser as Starship and Powerlevel10k. Config comes from an optional NMSh path, elsePOSH_CONFIG, else Oh My Posh's built-in default. No shell rc file is changed.Native theme library and Theme Studio
themes(bounded to 64 assets, stable ids) plusnmsh.themeIdare canonical. A legacycustomThememigrates to one Custom asset and stays active./theme: Built-in · Imported · Custom · Import, one editor, and the real Native preview for every theme. Imported themes are ordinary Native themes (edit, rename, duplicate, export, select, pin).<name> - Custom).extendsand remote config are never evaluated or fetched..itermcolors, WezTerm TOML (Lua refused).Theme Bridge
ls/glsviaLS_COLORS(vivid when installed); macOS/BSDlsviaCLICOLOR/LSCOLORS..tmTheme, a reviewedbat cache --buildverified withbat --list-themes, andBAT_THEMEin NMSh shells.theme = "nmsh-bridge"activation that never replaces an existing user theme./integrationsshows health with Review all / Apply all.Providers and pickers
/providersis one inline panel (no nested panels). Picker query orientation follows the composer position. Provider shortcut commands:/picker,/suggestions,/navigation,/welcome,/history-provider.Tools, tmux, dotfiles
/tmux): general settings, keymaps/prefix with conflicts, Status Studio (status modules never run shell), and import of a supported subset of an existing tmux.conf./bin/shprogram with the NMSh path passed as quoted argv data. It falls back to the login shell inside an NMSh-started tmux, anddefault-shellis untouched./tools:.zshrc, then shows the official source and the documentedKEEP_ZSHRC=yes CHSH=no RUNZSH=nosettings (REPO/REMOTE/BRANCH pinned). You run it yourself, and NMSh then verifies what changed..zshrcchange is reported, never silently restored..zshrc.pre-oh-my-zshcomparison and reviewed restore: default No, backup first, atomic replace, and no shell-code merge./toolsreuses the existing detector, provider andp10k configureflow (which backs up.p10k.zshand.zshrc).Installed · Zsh framework · used by Zsh only)./dotfiles): plain, Git, Stow and chezmoi sources; nothing is run. tmux imports supported fields only..p10k.zsh, Oh My Zsh themes/plugins and all shell rc files are inspect-only, with a stated reason.Keep Awake (
/caffeinate, also/awake,/zoomies)45s,30m,2h),statusandstop./usr/bin/caffeinatewith fixed flags (-i,-d -i,-s,-d -i -s; System needs AC power).systemd-inhibit --what=idle|sleep|idle:sleep --mode=blockaround an NMSh-owned wait helper. No shutdown, lid or key inhibitors. Display is reported unsupported. No systemd means nothing is guessed.SetThreadExecutionState(CONTINUOUS | SYSTEM_REQUIRED, + DISPLAY_REQUIRED for Display/All) from a fixed hidden PowerShell helper. No away mode, nopowercfg, no elevation.Ask
Commands
/appearance,/motion,/cursor,/activity,/screensaver,/theme,/theme-bridge,/chroma,/chrome,/glyphs,/strip(also/status-strip)./prompt,/syntax,/layout(also/composer),/transcript,/keyboard./providers,/picker(also/pickers),/suggestions,/navigation,/welcome,/history-provider./tools,/configure,/tmux,/integrations,/dotfiles,/caffeinate(also/awake,/zoomies).Host semantics
/helpand task rows are kept separate from program links.Security hardening in this PR
exactCopycapability. Parseable is not safe: Starship custom commands, bat's pager and Helix:shkeys can all run programs. Adversarial fixtures prove no copy is offered, nothing is written, and nothing runs./bin/shparsers. 15 hostile directory names (spaces,; & | ( ) $ $( ) \' " \ < > #) were run through real/bin/sh` and real tmux, and no canary file was created.%escapes,$()/backticks/${}, quotes, ANSI/OSC/C1) render literally and inertly in live, snapshot and historical prompts, and no canary runs. No renderer change was needed: NMSh never hands repository text to a prompt parser.Stability fixes found by CI
ls()failed to parse whenlswas already an alias (Ubuntu's default bashrc), so the managed Bash never became ready. It now uses thefunction ls {…}form. Real-shell regression tests cover zsh, Bash and Fish, including a live managed Bash with an aliasedls.Homebrew (distribution infrastructure)
INSTALL_RECEIPT.json./update,/version,/statusandnmsh doctorsay so and point tobrew upgrade nmsh; NMSh never modifies the Cellar..github/workflows/homebrew-tap.ymlproposes theraiseCatError/homebrew-tapformula update as a PR for stable releases only. It needs a fine-grainedHOMEBREW_TAP_TOKENscoped to the tap.Automated verification
npm run verify:fast(63 tests),npm run verify(1677/1677),npm run verify:release(1677/1677, bench typecheck, timing smoke), andgit diff --check origin/dev, all passing.b2075dbda87eb770c5fff8fd2923b9ce7717e973(CI run 37251498550): Tests macOS 1/2 and 2/2, Tests Ubuntu 1/2 and 2/2, Quality (Node 26), Node 22 compatibility, CI, Verify (22.x) and Verify (26.x) all succeeded. Timing smoke and the Fedora subset are skipped by workflow conditions.Physical QA still required (nothing below is claimed as physically verified)
Previously physically confirmed: Vim
:colorscheme→nmsh-bridge; tmux Theme Bridge colors.ls/gls, bat, tmux (include and reload), Neovim, Vim and Helix (activation and removal); zsh/Bash/Fish propagation./providersinline panel; picker orientation with the composer at top and bottom..zshrc; previous-zshrc compare and restore; Powerlevel10k Configure from/tools.systemd-inhibit --list), and Windows (system/display awake, Stop, no power-plan change). Linux and Windows are covered only by mocked tests.Deferred