AI Decision System
Replayable, offline-verifiable records for AI-assisted go/no-go decisions: experiment promotions, typed model answers and human-approved actions.
翻译准备中
An agent-aware terminal multiplexer: coding agents in real panes, and you always know which one needs you.
翻译准备中
取自仓库 README
正在加载完整 README。 以下为已保存的摘录。
An agent-aware terminal multiplexer. No AI of its own — it hosts coding agents (Claude Code, Codex, Pi, …) and shells in real terminal panes, and tells you which one needs you. Docs: https://manyeya.github.io/modisa.
Built with Bun and OpenTUI: real terminal panes, named spaces, an agent sidebar, a segmented status bar, mouse menus, and live themes.查看完整 README ↗An agent-aware terminal multiplexer. No AI of its own — it hosts coding agents (Claude Code, Codex, Pi, …) and shells in real terminal panes, and tells you which one needs you. Docs: https://manyeya.github.io/modisa.
Built in Rust with ratatui and alacritty_terminal, one small binary: real terminal panes, named spaces, an agent sidebar, a segmented status bar, mouse menus, and live themes.
curl -fsSL https://manyeya.github.io/modisa/install.sh | sh
Releases are built for macOS on Apple silicon and Linux on x64 and arm64. The installer checks the download against its published SHA-256 and puts modisa in ~/.local/bin (MODISA_INSTALL_DIR changes that; MODISA_CHANNEL=staging installs the latest prerelease).
Or install with a package manager, which then updates and removes it:
| With | Install | Remove |
|---|---|---|
| mise | mise use -g github:manyeya/modisa | mise uninstall github:manyeya/modisa |
| Debian, Ubuntu | sudo apt install ./modisa_<version>_<arch>.deb | sudo apt remove modisa |
| Fedora, RHEL | sudo dnf install ./modisa-<version>-1.<arch>.rpm | sudo dnf remove modisa |
Every release on GitHub Releases has the binaries, the .deb and .rpm packages, SHA256SUMS, the manifest.json the installer and updater read, and signed build provenance. To check that a file was built by this repository's release workflow from a tagged commit, run gh attestation verify modisa-darwin-arm64 -R manyeya/modisa.
When a newer release is out, the status row shows ↑ <version>: click it to update and restart the server (agents resume). From the command line: modisa version, modisa update, then modisa restart. If mise or a package installed modisa, update with that tool instead (modisa tells you the command). [update] channel = "staging" follows prereleases; [update] check = false turns the check off.
modisa uninstall # or: curl -fsSL https://manyeya.github.io/modisa/install.sh | sh -s -- --uninstall
It lists what it will do and asks first. Then it removes modisa's hooks and skill from every agent, stops running sessions, and deletes saved state in ~/.local/state/modisa. Your config in ~/.config/modisa stays unless you add --purge. If the install script put the binary there, uninstall deletes it too; if mise or a package did, finish with that tool's remove command.
From source (also the way to run it on an Intel Mac), with a Rust toolchain:
cargo install --path . # or just run it: cargo run --release
Prefix is Ctrl+B, then:
| Key | Action |
|---|---|
v / % | split right |
- / " | split down |
h j k l / arrows | focus pane |
H J K L | resize pane |
z | zoom pane |
x | close pane |
c | new tab |
n / p | next / previous tab |
w / W | switch space / new named space |
$ / & | rename / delete the current space (delete asks first) |
b | hide / show sidebar |
s / t | settings / settings on the theme section |
P | plugins: discover, install, update, remove |
o / 1-9 | pane picker / jump to agent |
e | open pane context menu |
a | launch an agent |
: / ? | command palette / keyboard guide |
Ctrl+B | send a literal Ctrl+B |
d | detach (panes keep running) |
Rebind any of them under [keys] in the config: zoom = "f", split-right = ["v", "|"], or "" for none, with actions named as the keyboard guide (?) names them. An action set there has only the keys given; x, d and Escape can't be given away. modisa config reset-keys puts modisa's keys and the C-b prefix back.
Mouse: click a pane to focus it, drag the border between two panes to resize them (the pointer turns into a move cursor over a border), drag the sidebar's edge to widen or narrow it, click a tab to switch, and scroll for scrollback. Right-click a pane or tab for split, zoom, rename, copy visible output, search, theme, sidebar, and close actions. Every menu, picker and dialog has a search field and works with the mouse: the pointer selects, a click chooses, the wheel scrolls, and a click outside closes. [mouse] hover = false (or the settings page) stops the pointer selecting rows just by resting on them. Clipboard copying uses OSC 52 where supported by your terminal.
Spaces are named groups of tabs and panes. The status row shows where the active space's focused pane's git repository stands: its name, the branch, ↑ commits to push, ↓ to pull (as of your last fetch) and ● files changed ([git] turns each part off). Agents show their logo in their brand colour and the task they're on: the logos are a small font modisa installs the first time it starts, for Ghostty, kitty and VS Code (restart the terminal once; modisa logos shows where they stand, modisa logos uninstall takes them out). Ctrl+B w (or a click on the space's name at the top left) lists the spaces; right-click one to rename or delete it — deleting asks first and closes its panes. The last space can't be deleted. A new space starts in the current space's working directory; creating one does not create a directory. Use the shell's cd command to change a pane's working directory.
The settings page (Ctrl+B s, or ⚙ settings in the sidebar) lists its sections down the side — theme, general, layout, git, indicators, sound, alerts, agents, integrations, plugins — and typing searches all of them. Tab switches section, ↑↓ or the pointer selects, ←→ changes a value, Enter or a click applies, Esc closes. Every change applies at once and is saved to ~/.config/modisa/config.toml, keeping your comments and other settings.
! ◆ ✓ ○, dots, or letters) and where they show: tab badge, pane border, sidebarThe sidebar hides automatically below 100 columns or 22 rows. If a split would become too small, the focused pane fills the available space; expanding the terminal restores the split layout. Use the pane picker (Ctrl+B, o) or directional focus keys to reach other panes. Overflowing tabs keep the active tab visible, with previous/next buttons at the right.
A background server owns every pane, so closing the terminal only detaches.
modisa # attach the default session (starts it if needed)
modisa new api --cwd ~/code/api
modisa ls # running sessions, plus saved ones you can restore
modisa kill api
modisa --remote ssh://devbox # thin client here, server there (needs modisa on the remote PATH)
Layouts, pane names, working directories, agents and panes' --env variables are saved in ~/.local/state/modisa/modisa.db, which only you can read. After a reboot, attaching restores the session: shells come back in their directories, agents are relaunched into the exact conversation their integration reported (claude --resume <id>, codex resume <id>, …) or else their latest one (claude --continue, …), and plain commands are typed back in but not run.
--remote splits modisa in two: the TUI runs on your machine, the server and every pane run on the far side. Your keybindings, theme, sounds and notifications stay local; the panes, the agents and their files are remote.
modisa --remote ssh://devbox # host
modisa --remote ssh://me@build-01:2222 # user and port
modisa --remote devbox # a Host alias from ~/.ssh/config
modisa -s api --remote ssh://devbox # a named session on that machine
There is no daemon to install and no port to open. Modisa shells out to your own ssh, so agent forwarding, jump hosts, Match blocks and keys from ~/.ssh/config all apply. The exact command it runs:
ssh -T devbox modisa proxy -s default # ssh://devbox
ssh -T -p 2222 me@build-01 modisa proxy -s api # ssh://me@build-01:2222, -s api
modisa proxy on the far side starts the session server if it isn't running, then bridges its unix socket to stdio. -T means no pty is allocated: the protocol is newline-delimited JSON, not a terminal.
Modisa must be on the remote machine, and by default it must be on the PATH of a
non-interactive ssh shell — which often excludes ~/.local/bin, where the installer puts it. If
--remote fails with something like modisa: command not found, set an absolute path in your
local config (~/.config/modisa/config.toml):
remote_command = "/home/me/.local/bin/modisa"
Check what the remote shell actually sees with ssh devbox 'command -v modisa'.
Other things worth knowing:
[plugin_keys].modisa ls lists local sessions; to see the remote ones, ssh devbox modisa ls.Ctrl+B d drops the ssh connection; the remote session keeps going, and so do the agents. Reattach from any machine.Ctrl+B copy actions reach your local clipboard through ssh in terminals that support it.modisa update on your laptop doesn't touch the remote install; run it there too, then modisa restart.MODISA_SSH overrides the ssh binary, which is how the test suite substitutes a fake.A modisa.toml in the directory you start from lays out a new session:
[[pane]]
name = "server"
run = "pnpm dev"
[[pane]]
name = "coder"
agent = "claude-code"
prompt = "read TODO.md and start on the first item"
modisa pane attach shows one pane full-screen in another terminal, which draws it itself: no sidebar or borders, just the program, in a second window or on another machine.
modisa pane attach @coder # drive it from this terminal
modisa pane attach p3 --observe # only watch it (q stops)
modisa pane attach @coder --remote ssh://devbox # one remote pane, over ssh
By default it takes the pane over: the pane takes this terminal's size and follows it, and typing from anywhere else (the TUI too, whose border says [attached elsewhere]) is dropped until you detach; pane run, pane keys and send still reach it. One terminal takes a pane over at a time. --observe leaves the pane at its own size and types nothing. Ctrl+B d (your prefix, then d) detaches and gives the pane back its place, and the prefix twice types it once. It exits 0 on detach, with the pane's own status if its program exits, and 3 if the connection drops.
Modisa has no AI of its own. It notices when a pane runs a known agent and tracks its state: blocked (needs you), working, done (finished while you weren't looking), or idle. The state shows in the pane border, the tab bar and the sidebar, and a background agent that gets blocked or finishes triggers a notification.
Known agents: Claude Code, Codex, Gemini CLI, Cursor Agent, Copilot CLI, OpenCode, Pi, OMP, Droid, Amp, Kiro CLI, Kimi Code, Kilo Code, Devin CLI, Grok CLI, Hermes Agent, Qoder CLI, Qwen Code, Antigravity CLI, Cline, MastraCode, Maki, Muse and Aider — found by process name, also when started through node, bun, python or a shell script.
State is read from the agent's screen with no setup: each agent has a manifest of rules over the live bottom of its screen, its terminal title and its OSC 9;4 progress (src/config/agents/manifests). Integrations use the agent's own hooks or plugins to add more:
claude --resume <id>, codex resume <id>, …). Their state stays on screen detection, because their hooks miss some transitions (interrupts, permission answers).modisa integration status # every agent: installed, update available, available, not found
modisa integration install all # everything recommended for the agents on this machine
modisa integration install codex # or one agent; uninstall takes out only modisa's entries
The settings page (Ctrl+B s → integrations) does the same. Integrations install on the machine the server runs on, where the agents are.
Installing an integration also drops in the modisa skill — a SKILL.md teaching the agent to split panes, spawn and message other agents, and wait on them, so it drives the session without you explaining the CLI each time. There's no separate command; it comes with the integration:
modisa integration install claude # hooks + the skill, for one agent
modisa integration install all # …for every agent on this machine
modisa integration status # "↻ update available" when a newer skill ships
modisa integration uninstall claude # takes the skill back out too
~/.agents/skills/modisa/SKILL.md the one copy
~/.claude/skills/modisa -> …/.agents/skills/modisa
~/.codex/skills/modisa -> …/.agents/skills/modisa
Every agent above gets it except MastraCode and OMP, whose skills directories aren't established. Kimi Code reads ~/.agents/skills itself, so it needs no link. Restart a running agent to pick the skill up.
Your own tools can report too: modisa report --source my-tool --agent my-agent --state working|blocked|idle [--seq n] [--session-id id], and --release hands the pane back to screen detection. Reports without --source don't change state.
Add an agent or override one with a TOML file in ~/.config/modisa/adapters/<id>.toml (name, process, launch, resume, resumeSession, and [[rules]] in the manifest format). modisa debug detect <pane> shows the matched rule, the reporting integration, and the title and progress it saw.
modisa notch puts the flock in your MacBook's notch, drawn in woodcut like modisa's emblem: the shepherd on one side of it, and on the other the agent that wants you most. Point at the notch and it opens into a pasture at night with a sheep for every agent in every session on the machine, each wearing a collar in its agent's colour. Working sheep walk to open grass and graze, stepping round each other. One that needs you runs to the shepherd and hops under a !, and he turns to it and raises his crook. A finished one stands with a ✓ and an idle one sleeps at the back. The moon lights them all, and gusts of wind cross the grass. Each sheep's name is along the bottom; point at a sheep for its agent, pane and state, and click it to focus its pane and bring its terminal forward. When an agent needs you, finishes, starts work in a pane you're not in, or joins, a line drops below the notch for a few seconds; click it to go there. A screen without a notch gets the same shape at the top.
It's off until you turn it on: flock in the notch on the settings page ([notch] show = true) starts it with modisa, and turning it off takes it out. Or start it once by hand:
modisa notch # starts it in the background (it survives closing the terminal)
modisa notch stop
Every pane gets MODISA_SOCKET and MODISA_PANE_ID, so any agent that can run shell commands can drive the workspace:
modisa pane split --name tests "pnpm test" # opens next to the caller
modisa wait tests --exited # prints "exited <code>"
modisa pane read tests --lines 80
modisa agent spawn codex --name reviewer --prompt "review src/auth"
modisa wait @reviewer --state idle
modisa send @reviewer "fixed, please re-check" # typed into the agent once it's idle
modisa inbox
modisa pane move tests --new-tab # the same process, in a tab of its own
modisa pane swap tests @reviewer # trade places, even across tabs
modisa pane split --ratio 0.3 --env PORT=4000 "bun dev" # 30% of the room, PORT set in it
modisa pane read tests --format ansi # with its colours
modisa notify "tests failed" --body "3 in src/auth" --tone blocked
modisa snapshot # the whole layout as JSON, read without attaching
modisa events --follow
pane move also puts a pane beside another (--target), into a tab (--tab) or in a new space (--new-workspace), closes a tab or space it leaves empty, and leaves your view where it is unless you add --focus. pane resize, pane zoom and pane focus --direction do what their keys do, for any pane. Creating commands print the new pane's id, or with --json the whole pane and its workspaceId and tabId; they take --env NAME=value once per variable (saved with the session, so a restart keeps it; never MODISA_*), and --cwd takes ~ and relative paths.
notify puts a toast in every attached TUI, titled with the sending pane; --system and --sound only take effect where that client's [notify] has them on. Each pane may send 3 every 10 seconds and all senders 6 (past that it exits 1, rate_limited); with no TUI attached it says so and exits 0. snapshot prints every space's tabs (split trees, focus, zoom) and every pane as JSON without attaching or resizing anything, and tab list lists the tabs. report --title "…" names a pane over its program's terminal title (an @name still wins) until --title "".
pane read prints the last --lines lines as the pane wraps them: --source recent-unwrapped joins soft-wrapped lines, --source visible is just the screen, and --format ansi keeps colours. pane layout, pane neighbor --direction d and pane edges say where a pane sits in its tab, and pane process-info gives its pid, the job in its foreground and its shell's directory.
modisa help lists every command, and the modisa skill teaches them to an agent that has it. Messages carry a hop count and a per-pair rate limit so two agents can't ping-pong forever, and Ctrl+B m pauses delivery. When an agent types into or closes a pane it didn't create, you get an allow / always / deny prompt; the policy is set in [permissions] in the config.
A plugin is a program modisa starts with each session, connected to the session's socket: it watches what happens, offers actions, and can put a little into the TUI. modisa plugin new scaffolds one in TypeScript with modisa's client library, a behavioural test, and AGENTS.md, a guide an agent can follow to write the rest.
modisa plugin new my-plugin # plugin.json, plugin.ts, a test, the client library, AGENTS.md
modisa plugin check my-plugin # manifest, build, then a throwaway session: starts, connects, passes its tests
modisa plugin link my-plugin # every session starts it; the running one starts it now
modisa plugin search [words] # GitHub repositories with the modisa-tui-plugin topic, and how to install each
modisa plugin install https://github.com/you/modisa-plugins --subdir attention-log --ref v1.2.0
modisa plugin marketplace add acme/modisa-plugins # a repository that lists plugins
modisa plugin install worktrees@acme # one it lists
modisa plugin update <name> # the latest of its ref, checked again, restarted where it runs
modisa plugin list | logs <name> | stop <name> | start <name>
modisa plugin run <name> <action> '{"any":"params"}'
modisa plugin unlink <name>
From inside modisa: Ctrl+B P (or "Plugins…" in the palette, or the settings page's plugins section) opens the plugin manager. Discover searches the plugin index and your marketplaces; choosing one shows exactly where it comes from (the repository, folder, ref and commit) with a warning that it runs unsandboxed as you, and installs it only when you say so, at that commit. Installed lists every plugin with its state and pid, with buttons to start or stop, restart, read its log, update (installed ones) and remove; a [[plugin]] line from config.toml only starts and stops. Marketplaces adds (owner/repo or a git URL), updates and removes them, and Add from URL… installs from a git URL and an optional ref. It all happens on the server's machine, so with --remote it manages the plugins where they run. Only you can: an agent in a pane can't install plugins through the session.
plugin.json names the plugin, its protocol version and how to start it (run, an argv run in its directory), and what it offers: actions (also listed in the command palette), panes, keys under the prefix, and links.
Marketplaces: a git repository with modisa-marketplace.json (or .modisa/marketplace.json) at the top, listing plugins. modisa plugin marketplace add owner/repo (or a git URL, --ref to pin one) clones it into the state directory; marketplace list, update [name] and remove <name> manage them, and plugin search lists their plugins beside the index's. A source is "./path" inside the marketplace's own repository (it must really be inside it: no .. or symlink out), "owner/repo" on GitHub, or { "git": url, "ref", "subdir" }. Its text is cleaned of escape and control characters before it's shown. A marketplace is a list someone keeps, not a review.
{ "name": "acme", "description": "Acme's plugins", "owner": "acme",
"plugins": [ { "name": "worktrees", "description": "a space per worktree", "source": "./plugins/worktrees" },
{ "name": "x", "source": { "git": "https://github.com/a/x.git", "ref": "v1", "subdir": "plugin" } },
{ "name": "y", "source": "owner/repo" } ] }
Update: plugin update <name> fetches what an installed plugin's ref (or, with none, its default branch) is at now, checks its directory and plugin.json again (a bad commit is undone), and restarts it in every running session that runs it. One from inside a marketplace brings that marketplace up to date first. A plugin you linked is updated where it lives.
Finding plugins: the plugin directory lists every public repository with the modisa-tui-plugin topic, searchable and sortable, refreshed daily; modisa plugin search asks GitHub the same question from the terminal. radar is one: every agent at a glance in the sidebar, grouped by repository.
A [[plugin]] run line in config.toml still starts a program with no manifest. examples/plugins/ is the full guide to the protocol underneath: the events, the methods, the error codes, and the rules that will bite you. attention-log/ is a complete plugin built with plugin new. worktrees/ is another, and a useful one: a space per git worktree (create, open, list, remove); modisa plugin link examples/plugins/worktrees turns it on.
Ctrl+B s opens the settings page; modisa config edit (or "Edit config.toml" in the command palette) opens ~/.config/modisa/config.toml itself; changes apply live (a change that doesn't parse is left out, with a toast). It covers the prefix key, [keys], theme, select on hover, sidebar, status row, git, pane borders, which notifications fire (toast, system, sound, bell), messaging limits, permissions, per-agent launch commands, remote_command for --remote, [plugin_keys], and [[plugin]] programs.
Beyond the settings page, nearly every part of modisa is yours to shape: your own themes (every colour and the
chrome's roles, light and dark, imported from Ghostty, iTerm2, Alacritty, kitty and others), formats for the status
row, tab labels, pane titles, the window title and the sidebar's agent rows, where the tab bar and sidebar go, pane
borders and dimming, keys without the prefix and key modes, commands of your own with prompts, hooks that run on
events or stop and change what agents do, per-agent notifications and sound packs, metadata any program can show,
and profiles that carry a whole setup. examples/config/CUSTOMIZE.md has all of it.
modisa config check reports what's wrong without a session: a file that doesn't parse (with its line and column), or a value modisa can't use, is an error (exit 1); a setting it doesn't know is a warning. --json gives the same as data. modisa config reset-keys takes out [keys] and [plugin_keys] and resets the prefix, keeping your comments and the old file as config.toml.bak.
cargo build --release # single binary at target/release/modisa
bun site/build.ts # the docs site into site/out, every link checked (bun, and the binary for its data)
Work lands on dev (CI: unit tests, a release build and the end-to-end suite on Linux and macOS). A pull request from dev to staging publishes a rolling staging prerelease; one from staging to main releases.
Every push to main is a release (.github/workflows/release.yml): the tests run, the next version is taken from the git tags — the patch goes up, or the minor/major when a commit since the last release says [minor]/[major] — each platform is compiled on its own runner, and the release gets the binaries, SHA256SUMS and manifest.json. The docs site deploys to GitHub Pages in the same run. A push that changes only docs skips the release and just redeploys the site.
cargo test # unit tests: layout math, config, keys, detection against captured screens, the mailbox, connections
parity/run.sh # the end-to-end suite (needs bun): every feature, each in its own sandboxed session
parity/run.sh test/e2e/panes.test.ts # one file of it
The end-to-end suite is the TypeScript build's, from its last commit: parity/run.sh takes its src/ and test/ out of
git history and points its harness at this binary, so the behaviour it pins down carried over unchanged.
tests/fixtures/ — captured agent screens used by the detection testssrc/main.rs — entry point; dispatches to the CLI, server, client or integrations, on one thread (a current-thread tokio runtime)src/cli/ — argument parsing, help, API commands, session commands (attach, ls, kill, restart), single-pane attach (pane_attach.rs), plugin commandssrc/core/ — paths, version and the split-tree layout mathsrc/protocol/ — shared types, the JSON-RPC schema (describe.json, what protocol.describe publishes), connections and transportssrc/config/ — config file and its check, prefix keys (keys.rs), themes, the agents modisa knows (agents/: process names, launch/resume, screen manifests), and plugins on disk: links and installs (plugins.rs), installing, updating and unlinking (plugin_manage.rs), marketplaces (marketplaces.rs)src/server/ — the session server
mod.rs startup/shutdown and shared state, attach.rs single-pane attach (takeover and observe), plugins.rs the plugin host, slots.rs plugins' pieces in modisa's chrome (checked, and who replaces what), views.rs what a plugin's view may hold, plugin_manager.rs the plugin manager's requests (user only), pty.rs pseudo-terminalsrpc/ — dispatch, TUI methods, public APIsession/ — spaces, tabs, panes; a PtyPane is a pty + a headless terminal (src/vt.rs)agents/ — detection (process identification, the manifest rule engine, integration authority), the monitor tick, the mailboxpersist/ — SQLite store, restore, modisa.toml templatessrc/client/ — the ratatui client: mod.rs startup and the App state, draw.rs, input.rs, keys.rs (keys as a pane's program expects them, kitty protocol included), actions.rs, modals.rs, settings.rs, views/ (plugin views), slots.rs (plugins' pieces of the chrome), sound.rssrc/vt.rs — the headless terminal: alacritty_terminal, with text and ANSI export and replaysrc/notch/ — modisa notch, the flock in the MacBook's notch: an AppKit panel through objc2 (), every session's agents polled from their sockets (), the open pasture as a little world the sheep steer about in (), the woodcut art of the shepherd (modisa's emblem), the sheep and the night (), drawn with a canvas-like layer over AppKit ()MIT. The agent detection manifests in src/config/agents/manifests are third-party files under the Apache License 2.0 (see the LICENSE and NOTICE there); the site's bundled fonts carry their own licenses in site/assets/fonts.
Install clones a git repository (optionally a --ref branch, tag or commit, and a --subdir), checks it, links it and starts it. It takes https://, ssh://, git:// and file:// URLs and user@host:path, never a remote-helper (<helper>::) URL or plain http, and git only uses those transports whatever your git config or environment says; your ssh agent, ssh command and credential helpers still apply. No build or dependency scripts run before the plugin starts, and it says when the plugin needs setup. plugin list shows each install's source and commit. Unlinking an install stops it in every running session, then deletes its checkout (never its data), or keeps the checkout and says why.
In the TUI: pieces in every part of modisa's own chrome (slots): the status row and its segments, tabs, spaces, pane borders, the agents' rows, sidebar sections (rich text, or whole elements: charts, gauges, lists), the AGENTS list itself, the pane, tab and space menus and the palette; toasts with rich text and buttons; and panes opened as a split, tab, zoomed pane, overlay or popup. A plugin adds before or after what modisa draws, or draws instead of it where you let it: [slots] in config.toml names who may replace what ("agent.row" = "radar", "pane.title" = "builtin"), and modisa plugin list shows who holds what. Modisa draws all of it in your theme, attributes every piece to its plugin, and limits how much each plugin can show. examples/plugins/CHROME.md has every slot.
Views: whole screens of a plugin's own, drawn by modisa in your theme over everything or over one pane: element trees of ratatui's constraint layouts, blocks and widgets (lists, tables, tabs, trees, gauges, charts, a canvas, a calendar), and highlighted code and diffs, Markdown, images, inputs and buttons, written as JSX or function calls with the client library. What you type, choose and scroll to there runs the plugin's actions. examples/plugins/VIEWS.md has every element and field.
Permissions and settings: a plugin says in its plugin.json what it may do through modisa, and gets only what you grant (modisa plugin grant/revoke); its settings show in modisa's settings page. modisa plugin validate checks one without running it, modisa plugin dev --watch restarts it as you edit, and the client library's renderView draws a view as text for snapshot tests. examples/plugins/TOOLING.md.
Keys: keys bind a key under the prefix to an action or a pane. A key modisa uses, or one two plugins want, is off; move one in [plugin_keys] ("<plugin>.<action or pane>" = "Y", or "" to turn it off). Each client binds keys with its own config.
Links: Ctrl+click an http(s) URL in a pane to hand it to a plugin's action, matched by a pattern URL glob or a regex in RE2 syntax (linear time, so no backreferences or lookaround). When several plugins match, you choose. Terminal hyperlinks (OSC 8) whose label differs from their destination aren't followed.
Remote: with --remote, plugins, their processes and their files stay on the server's machine, and your client draws their UI with your theme, keys and notification settings. A client too old for plugin UI simply doesn't show it.
Startup and event workflows aren't manifest hooks: a plugin is a long-lived program, so it subscribes to events (a snapshot of every pane, then each change) and reacts.
A plugin runs as you, with your files and network. It isn't sandboxed.
mod.rsflock.rsworld.rsart.rspen.rssrc/platform/ — process facts from the kernel (procs.rs: libproc on macOS, /proc on Linux) and the logo fontsrc/integrations/ — every agent integration (targets.rs), config-file editing, plugin sources, and modisa hooksrc/skills/ — the modisa skill (modisa/SKILL.md), installed by the integrationssrc/plugins/ — the plugin authoring kit: modisa-plugin.ts (the TypeScript client library plugins vendor) and the modisa plugin new templatesexamples/plugins/ — how to write a plugin, the attention log and the worktrees plugin (a space per git worktree; both built from modisa plugin new, checked by the e2e suite's plugin-authoring test, linked with modisa plugin link examples/plugins/<name>), and an older hand-written oneparity/ — runs the end-to-end suite against this buildsite/ — the docs site: build.ts (a dependency-free static generator), content/ (the landing page and docs; data.ts asks the binary for its agents, settings and plugins), assets/ (CSS, JS, icons).github/ — CI, the release workflow and its scripts; install.sh is the installer