mekugi

package module
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 7, 2026 License: MIT Imports: 8 Imported by: 0

README

mekugi

A mekugi is the small peg that pins a Japanese sword's handle to the blade. Take it out and the handle comes off. Leave it in and the blade is still the blade.

Mekugi adds compact, recoverable tools and live subagent activity to stock Codex. Codex keeps editing, execution, the sandbox, permissions, command sessions, and patch review. No fork, no config edits, no daemon.

Features · Install · Usage · UI · Metrics · Configuration · Documentation

Features

Agent-facing
  • Fewer tokens and round trips. Session helpers offer bounded and batched reads, semantic symbol lookup, and structural outlines.
  • Recoverable output and changes. Continue omitted output without rerunning, and review, revert, or reapply captured edits by ID. Gaps in coverage are labeled.
  • Leaner instructions. Omit marked instruction blocks for the session without changing instruction files or unmarked policy.
  • Duplicate-output references. Opt in with --duplicate-output to replace unchanged runs in tool output and attached file or skill content with references to earlier visible text in Mekugi mode. Full host results, retained evidence, and the UI stay intact; see the projection contract.
  • Task journal. Record plans, results, constraints, and blockers as durable work state, rather than repeating status summaries in conversation.
  • Journal context reset. Manual and context-full resets use retained journal, change and failure evidence by default, including subagents, without a provider summary request. Opt out with --journal-compaction=off; see recovery behavior and limits.
  • Session continuity. Retained journal and change evidence survives resume, forks, side threads, and compaction, subject to storage retention.
  • Custom tools. Extend the agent's capabilities with your own JavaScript tool plugins.
User-facing
  • Auto resume accidental stop. Continue unfinished journal work when the agent stops, including after answering a follow-up. Explicit user stops, blockers, and pending questions are respected. See the Journal pane.
  • Native terminal UI. Main, Diff, Activity, Journal, and Agents share one terminal without an external pane manager.
  • Task journal. Plans, results, and blockers stay visible without extra model requests for status reports. Work established complete by the final tool result needs no separate model-generated completion acknowledgment. See the Journal pane.
  • Live subagent activity. See model, effort, progress, and message excerpts in Main or the Agents pane, alongside elapsed time and edit activity.
  • Live diffs. Inspect streaming previews and saved edits; click an Edit event to open its captured file and hunk.
  • Readable command output. Open searchable retained output. With mekugi-exec, supported Bash and Linux dash-backed sh command lists show each command's streamed output, exit status, and timing. Markdown file links open local source in the same dialog. Supported single commands and pipelines, including Bash timed commands, show measured command time excluding startup and matching.
  • File, directory and skill attachments. Send selected contents or a bounded directory tree directly without a separate agent read; unreadable or oversized attachments have explicit notices.
  • Composer additions. Mention selected messages or diffs, and ask /btw side questions without interrupting Main.
  • Usage, throughput and cost. See per-thread usage and estimated API costs in Agents, with output tokens/sec in Main's composer and child-agent rows, plus launch-wide average throughput, usage coverage, retries, and diagnostics in /session.
  • Other providers and tiers. Use Grok or OpenCode Go and Zen, and choose service tiers.
  • Diagnostics. Inspect past sessions, record debug evidence, or replay the UI offline with CPU and heap profiling.

Bounded output and leaner instructions aim to reduce tokens and round trips; these savings don't guarantee better results on every task. For controlled comparisons, use codex-setup-ab.

Install

Requirements:

  • Codex CLI for tool execution in every launch mode.
  • For configured JavaScript plugins only: Node.js 24+ as node. Plugins declaring regex grammars also require ripgrep as rg on the router's PATH.
  • Built-in frontends need neither Node.js nor Bun; semantic lookup requires the language servers listed under agent-facing tools.
  • Any interpreter your agent picks, such as python3, on the executor's PATH.
Release binaries

Download an archive from GitHub Releases. Each archive includes mekugi and mekugi-exec; Go and a C toolchain are not needed.

Platform Archive Minimum OS
Linux x86-64 mekugi_linux_amd64.tar.gz glibc 2.39, such as Ubuntu 24.04
Linux ARM64 mekugi_linux_arm64.tar.gz glibc 2.39, such as Ubuntu 24.04
macOS Apple Silicon mekugi_darwin_arm64.tar.gz macOS 15

For example, install the Linux x86-64 release into ~/.local/bin:

(
  set -eu
  mekugi_install_tmp=$(mktemp -d)
  trap 'rm -rf "$mekugi_install_tmp"' EXIT
  cd "$mekugi_install_tmp"
  curl -fLO https://github.com/yusing/mekugi/releases/latest/download/mekugi_linux_amd64.tar.gz
  curl -fLO https://github.com/yusing/mekugi/releases/latest/download/SHA256SUMS
  sha256sum --ignore-missing -c SHA256SUMS
  tar -xzf mekugi_linux_amd64.tar.gz
  mkdir -p "$HOME/.local/bin"
  install -m 755 mekugi mekugi-exec "$HOME/.local/bin/"
)

Use the archive for your platform. On macOS, verify it with shasum -a 256 --ignore-missing -c SHA256SUMS instead of sha256sum. Add ~/.local/bin to your PATH if needed. Installing replaces both binaries at that destination. Linux releases need glibc and do not run on stock Alpine Linux; use a source build for other environments.

Build from source

Source installs require Go 1.27+, CGO enabled, and a C toolchain:

go install github.com/yusing/mekugi/cmd/mekugi@latest github.com/yusing/mekugi/cmd/mekugi-exec@latest

Add $GOBIN, or $(go env GOPATH)/bin if that is unset, to your PATH.

From a checkout with Make, run make install. It regenerates the optional plugin shared core and installs mekugi and mekugi-exec. make uninstall removes only those binaries. Running sessions keep their worker executable, so start a new session to pick up an update.

Usage

Start Mekugi

Choose a mode and authenticate with the provider it uses:

Launch Models Authentication
mekugi Authenticated third-party providers, using grok: and opencode*: IDs Grok credentials or OpenCode API keys; no Codex login
mekugi grok Grok only, using plain IDs such as grok-4.7 Grok credentials; no Codex login
mekugi codex Codex only, no third-party models codex login with ChatGPT authentication

Standalone mode fails at startup if no third-party provider has credentials. Its default uses Grok's model selection when authenticated, otherwise the first available OpenCode Go model, then Zen.

Mekugi opens its terminal workspace. Codex's configured approval and sandbox policy applies, and Mekugi also asks before remote repository writes; see Approvals. Add --yolo to disable Codex approvals and sandboxing; Mekugi's remote-write guard stays enabled. The guard requires unsandboxed command execution: configure sandbox_mode="danger-full-access" or use --yolo. Use --vcs-guard=false to disable the guard while retaining Codex's configured approval and sandbox policy.

Mekugi flags go before codex, grok, or standalone Codex arguments. Interactive launches accept --yolo, model and config options, and resume, resume THREAD_ID or resume --last; enter prompts in the UI. Noninteractive commands keep their ordinary Codex arguments and output:

mekugi exec "Explain this repository"
Launch behavior and limits

Independent sessions can run side by side. Ctrl-C during startup cancels the launch. On UI exit, Mekugi prints commands to resume with the original options or replay offline. Noninteractive commands retain Codex's exit status.

  • There is no standalone router or daemon. Fixed ports, custom provider endpoints, and --oss are not supported.
  • OpenAI sessions need secure WebSockets to ChatGPT. Mekugi falls back to HTTP only when ChatGPT explicitly rejects the upgrade, and never silently replays a request.
  • Grok and OpenCode requests use HTTP and their own credentials. Third-party credentials do not enable those providers in mekugi codex.
  • Mekugi-mode sessions require a model with Codex's JavaScript exec interface. Mekugi forces that interface for the invocation; unsupported models fail before inference.
  • Invocation-only overrides disable the plan tool and collaboration-mode instructions, route gpt-5.6-terra to gpt-6-sol, and select standard cybersecurity safeguards rather than Daybreak. No configuration files change.
  • Private replay records include tool inputs and change evidence. Native Codex tracing also records prompts and responses in a temporary directory with no disk cap; it is removed at shutdown, but a forced kill can leave it behind.
Approvals

Without --yolo, Codex's command, edit, and permission approval requests open a dialog above Main's composer with Codex's offered approval scopes, including session, command-prefix, or permission grants when available. It opens by itself only over an empty composer; otherwise a banner waits until you press Ctrl-B, then q. Number keys choose while the reason is empty; arrows choose, Enter confirms, and Esc hides the dialog without answering.

For command approvals in Mekugi mode, typing or pasting selects denial and edits an optional reason; Enter confirms. Your composer draft and attachments stay parked and return when the dialog closes. Hiding and reopening keeps the reason. Questions and approvals share the dock, so only one is open at a time. The model receives the native command rejection and your feedback in the current turn, without a new prompt or turn. Edit and permission choices stay unchanged. Proxy-free direct UI and passthrough retain Codex's original decisions without typed denial reasons.

In interactive UI launches, Mekugi asks before remote repository writes reached through guarded shell commands by default, independently of Codex's approval policy, including with --yolo. Disable only this guard with mekugi --vcs-guard=false codex or mekugi --vcs-guard=false for standalone mode. Command tracking remains enabled. Headless and noninteractive commands have no guard. Guarded writes include:

  • git push to any remote, including tag and mirror pushes, plus git send-email, git svn dcommit, git p4 submit, and Git LFS pushes and locks
  • gh commands that change GitHub state; unrecognized gh commands count as writes
  • hg push and hg email; svn commit, import, lock, and commands that change a repository URL directly, such as svn copy ^/trunk ^/tags/v1
  • jj git push and jj gerrit upload; unrecognized jj commands, including aliases, count as writes

Git aliases, git submodule foreach, rebase --exec, and bisect run scripts are checked before they run. Read-only commands such as git fetch or gh pr view run without asking.

The guard offers approval once, approval for this exact command and workdir for the UI session, or denial with an optional typed or pasted reason. Session approval matches the expanded argument list, workdir, and resolved executable; it also releases identical requests already waiting. It grants no command-prefix permission and expires when the UI closes, including before a resumed launch.

If you deny it, don't answer within 5 minutes, or the approval connection is blocked or unreachable, only that command fails, with exit status 1; the shell continues as it would after any failure. A user denial reports your supplied reason, or that no reason was given, on stderr. The denied command never runs. This shell exit status belongs to the guard; native Codex approval denial remains a tool rejection. If the command stops while waiting, its request is withdrawn. For example, git add -A; git commit -m msg; git push origin main; git log still runs git log, while the same list joined with && stops at the push.

Git subcommands that are neither built in nor aliases, such as git subtree push or a third-party git-* command, also ask, since they can push out of the guard's sight. A tool whose own write runs another guarded tool, such as gh pr create pushing your branch, asks again for that inner command.

The guard needs the default --mode mekugi, mekugi-exec installed beside mekugi, Codex's native command-hook support, and unsandboxed command execution (sandbox_mode="danger-full-access" or --yolo). Sandboxed execution is unsupported. Mekugi never silently changes Codex's approval or sandbox policy. It keeps Codex's selected shell, including Bash, sh and zsh. Direct commands and supported wrappers such as env, command, exec, xargs and timeout are guarded by name or by absolute or relative executable path, including paths with spaces and expanded paths such as "$tools/git". Nested shell -c commands are checked after their payload expands. Shell arguments, sandbox permissions and command sessions remain Codex-owned.

Before each new user turn, Mekugi verifies that the guard hook is enabled and trusted. A missing guard or a competing trusted synchronous shell hook blocks the turn with an explanation and preserves your draft. Explicit CLI overrides of hooks or hooks.PreToolUse conflict with the enabled guard and prevent launch. User configuration files are unchanged.

This is protection against accidental remote writes, not a process sandbox. It does not comprehensively intercept executable words computed entirely at runtime, eval, env -S payloads, sourced files, script files, or arbitrary programs that internally execute absolute VCS paths. Bash/zsh startup guards provide additional PATH and known-absolute-path coverage inside scripts, but these limits still apply. Hook failures outside Mekugi's handler follow Codex's failure policy and need not block execution. See the execution contract.

Headless slice plans

The headless --yolo subcommand reads one prompt from stdin and runs a new session to completion, continuing unfinished journal work and any planned slices:

mekugi --journal-compaction=slice headless --yolo < prompt.txt

The default auto resets at slice boundaries and for manual or context-full requests. Use off to continue slices in one context with provider compaction, or slice to reset only between slices and use provider compaction otherwise. Unlike the UI, headless journal continuations have no countdown delay. It accepts model and -c options, not resume or positional prompts. Prompts must be nonempty and at most 16 MiB. Unlike the UI, it requires explicit --yolo. It does not answer approval or user-input questions: those end the run with an error rather than hanging or guessing. Ctrl-C stops the run.

Stdout is JSONL containing host app-server messages and namespaced Mekugi reset and completion events. Diagnostics go to stderr. The event stream includes prompt, tool and answer content; it is session evidence, not sanitized metrics. A nonzero exit means the run or its shutdown failed. Ordinary codex exec is unchanged.

Options
Flag Default Purpose
--ansi-faint auto Dimming: auto detects mosh ancestry, on uses ANSI faint, off uses fixed muted colors
--mode mekugi Use passthrough with mekugi codex to forward traffic without Mekugi tools or plugins
--vcs-guard true Ask before remote VCS writes in the UI, even with --yolo; false disables only this guard
--post-compact-recovery true Use false to skip the post-compaction context hook
--journal-compaction auto Journal context reset without a provider request; off restores provider compaction; slice resets only between planned slices
--duplicate-output false Opt in to duplicate-output and attachment references in model input; full results and evidence stay intact; no effect in passthrough
--grok-auth-file ~/.grok/auth.json Select a Grok OAuth credential store
--timeout 10m Wait for the upstream response to start
--stream-idle-timeout 4m Limit gaps between provider messages during an active response, or HTTP response bytes
--capture-output PATH Disabled Append sanitized JSONL metrics
--debug Disabled Record diagnostics, capture, metrics, forwarded instruction/tool snapshots, runtime reads, and an AX report; print a session diagnosis command on exit

mekugi --mode passthrough --vcs-guard=false codex forwards traffic only. It doesn't need Node.js, and capture still works. Interactive passthrough can't guard remote writes, so it requires --vcs-guard=false and retains Codex's configured approval and sandbox policy. Passthrough implies --journal-compaction=off; explicit auto or slice is rejected.

If a detached multiplexer hides your mosh connection, use mekugi --ansi-faint=off codex for readable dimmed text. The setting applies only to that invocation and does not modify terminal configuration.

Grok models

Authenticate with grok login --oauth, or set XAI_API_KEY in the router's environment; an API key takes precedence. Codex credentials are never sent to Grok.

mekugi grok -m grok-4.7
mekugi -m grok:grok-4.7

The default follows [models].default in ~/.grok/config.toml, falling back to the latest standard model, currently grok-4.7. An explicit -m or -c model=... takes precedence. Standalone mode adds the grok: prefix to this default; mekugi grok uses plain IDs. The old --grok flag is not supported.

Subagents use the same IDs as their launch mode: grok-4.5, grok-4.6, grok-4.7, or grok-4.7-build-fast, prefixed with grok: in standalone mode. Use fresh context (fork_turns="none"). Build Fast requires Grok OAuth, not an API key. Grok can't read encrypted OpenAI history, so switching an existing OpenAI conversation to Grok isn't supported. See the Grok requirements.

OpenCode Go and Zen

Set an API key here or in Mekugi settings:

OPENCODE_GO_API_KEY='your-key' mekugi -m opencode-go:glm-5.3
OPENCODE_ZEN_API_KEY='your-key' mekugi -m opencode-zen:kimi-k3

Models, reasoning controls, and prices refresh from an hourly cache. The model picker updates on the next launch. See the provider contract.

OPENCODE_API_KEY overrides both service keys from the settings file. Per-service variables override it and any file keys; an empty per-service value disables that service.

UI

Every interactive launch lays out Main, Diff, Activity, Journal, and Agents panes in one terminal without an external pane manager. Main holds the conversation and composer. Inline Markdown code uses content-detected syntax colors; unrecognized spans stay plain with an accent. Fenced code uses its language tag. Markdown tables render as aligned grids that switch to a record layout in narrow panes. Completed Mermaid flowchart fences render as terminal diagrams with labeled solid/dashed edges and & fan-in/fan-out groups. Unsupported syntax (including subgraphs), incomplete fences, and diagrams too wide for the pane remain readable source.

The empty launch view shows the Mekugi and Codex versions. Release builds show their tag, such as mekugi-v1.2.3, rather than a commit SHA. Click tool output, long-content excerpts, or edit rows to open the shared scrollable dialog without leaving your current view. Close it with Esc or its top-right close button.

  • Ctrl-B, then 1/2/3/4/5, focuses Main, Diff, Activity, Agents, or Journal. Diff, Activity and Journal share the right column. Click a pane or its bottom selector to focus it. New sessions show Journal there. A live child spawn or follow-up temporarily shows Activity; when all children finish, Journal returns unless you selected another pane. Saved pane preferences still apply on resume.
  • Drag the dividers to resize panes or the file navigator. Ctrl-B, then arrow keys, resizes the main splits (up/down in the roster adjusts its height); Ctrl-B, then [/], resizes the file navigator. Narrow terminals show the focused pane full-width.
  • Ctrl-B, then PageUp/PageDown, browses Main history. The wheel scrolls the pane under the pointer.
  • Ctrl-C in an auxiliary pane returns focus to Main.

Main's top-right header shows the session title. Use /title <title> to rename it, even before the session has started or while a task is running. The new title appears immediately and is saved with the session; a save failure restores the last saved title and shows composer feedback. Manual renaming skips automatic title generation, including after resume or fork. For a new conversation without a title, the first successful upstream request starts a separate title-generation request using GPT-6 Luna with medium reasoning. This small additional model request does not block the conversation. If Codex credentials or Luna are unavailable, automatic naming is silently skipped, without switching to another model. Saved and inherited titles are reused on resume or fork.

Terminal titles and desktop notifications follow Codex's tui.notifications settings. Inside Herdr, its working, blocked, done, and idle indicators update even with notifications off.

See the UI contract.

Composer

Use input editing, file and skill pickers, steering, and queuing: Enter steers a running turn; Tab queues input. Type ? in an empty composer for the full shortcut list. The controls and attachment behavior are described below.

Use /lock to prevent Esc or Ctrl-C from interrupting work and to disable Ctrl-C exit on an empty draft. /unlock restores those shortcuts. Draft clearing, copying, and closing pickers still work while locked; /quit remains an explicit exit when idle. A persistent Locked indicator shows the protection, which is restored with the session on resume. It does not block explicit commands or steering new input.

  • Files and directory trees attach. @! also finds ignored files; neither picker lists VCS metadata such as .git. Selected text files attach their contents when you submit or queue the prompt, and large or unreadable files produce an explicit omission notice instead of truncated content. Directories attach a sorted tree of children and grandchildren, not file contents. Trees respect ancestor and nested .gitignore files, exclude VCS metadata, and list at most 256 entries within 16 KiB. A scan limit also bounds large directories; incomplete trees have an explicit truncation marker. Queued prompts retain the submitted tree.
  • Select to mention. Drag across Main, Activity, or the saved Diff and press r to add the selection as one short mention, such as [Selected message] or [Selected diff hunk @amber1:42-45]. The selected text is sent with the prompt without filling the composer or losing its formatting.
  • Skill references attach automatically. Complete enabled $skill-name references are recognized when you finish the word or submit a pasted prompt; unknown, disabled, or ambiguous names stay plain text. With skills-mgr, managed skills attach their actual instructions automatically, with an Attached skill receipt. Click successful file or skill attachment receipts to open their submitted contents, including after resume. Unreadable or oversized contents produce an explicit omission notice. Without it, contents come from Codex-discovered skill files. Use skills-mgr to manage its skills; /skills toggles Codex-discovered skills.
  • Waiting messages combine. Steers typed while an earlier one is still sending, and queued messages, each appear as one stack and send as one message, one entry per line. Alt+Up or Shift+Left returns all locally waiting input to the composer. Already-sent steers remain pending until Codex commits them or the turn ends. While a turn is active, Esc expedites pending or locally waiting steers: it interrupts the turn, then sends only uncommitted steers in a new turn, leaving your draft unchanged. Tab-queued input stays queued when a steer is resent. If all pending steers commit before interruption completes, nothing is resent and queued input returns to the composer as in a normal interrupt. Already-committed input is never resent. Ctrl-C clears the draft first, then interrupts and restores waiting input without resending it. With no pending steers, Esc interrupts and restores input without resending, and never quits. Closing a picker, help, or selection and returning scrollback to the bottom take precedence over Esc interruption.
  • Session controls. /compact performs a context reset by default. Enter interrupts the current turn and resets after Codex acknowledges its end, with or without instant_interrupt. Tab queues the reset until the current turn ends. After a successful busy reset, waiting input runs next; without waiting input, Mekugi sends a visible continuation message to resume the task. An idle reset stays idle, and failure or interruption never automatically continues it. Ctrl+C cancels a queued reset and restores waiting input without interrupting Main. Cancelling while an Enter-command interruption is pending prevents the reset but cannot undo that interruption; once the reset starts, Ctrl+C interrupts only that reset. /clear starts a fresh session and clears its transcript; it is available while idle and does not delete saved sessions or filesystem changes. A normal interrupt returns unsent input to the composer without automatically resending it; Esc with pending steers uses the expedited delivery above. Interrupting an uncommitted first message leaves an empty transcript.
  • Live diffs. Edits temporarily replace Main's transcript or the editing agent's Activity transcript, leaving other agents visible. Brief edits finish without opening this temporary view; their saved diffs remain available. Ctrl-B e cycles and pins files; Ctrl-B r resumes Main's live following. Completed edits stay together until the batch settles, then the transcript returns. /live toggles the view; /live on or /live off applies directly for the current session without stopping activity or capture. New launches, including resume, show it again.
  • Setting pickers. /model, /effort (also /reasoning), and /tier open a picker: Up/Down and Enter apply a choice, Esc cancels, and neither the command nor its choices enter the transcript. A value switches directly, such as /effort high or /tier priority; /tier default clears the tier. Changes also reach a running turn's next steps and never edit your config file.
  • Terminal requirements. /copy and text selection copy through OSC 52, which your terminal must allow. Pasting a clipboard image on Linux needs wl-paste (Wayland) or xclip (X11).

/btw QUESTION asks a side question about a snapshot of the conversation, even while Main is working. The answer streams in a panel above the composer, with shimmering Answering status and elapsed time. Drag across its content to copy or reference it, just as in Main. Repeat /btw QUESTION to follow up, use PgUp/PgDn to scroll, and press Esc to clear a selection or close the panel; Main keeps working and your draft stays. Closing discards the side conversation, and it can't be resumed. If the side question needs compaction, it is rejected and restored to the composer. Run /compact on Main, close the side panel, and retry to take a fresh snapshot.

Resume

resume THREAD_ID and resume --last work as in Codex. Startup resume and /resume restore the session's saved model, reasoning effort, and service tier; explicit -m and -c flags override only the settings they name. Resuming also restores pane layout, keyboard focus, the agent roster, Activity history, and the session's retained Diff changes. Scroll positions, filters, selections, and drafts are not restored. Successfully applied settings survive a fresh launch, including priority and default selections made before the first turn. Storage failures are reported in Activity. If no saved model settings are available, a notice explains that Codex defaults and explicit flags apply instead. Main histories larger than 16 MiB cannot resume in the UI. Older child activity loads on demand. In third-party modes, noninteractive exec resume and exec fork use the mode's default model rather than the saved one; pass -m to choose another. Codex does not save an empty conversation before its first turn. If Codex rejects restoring default reasoning, waiting input returns to the composer and stays blocked until you choose /effort VALUE or restart resume.

Bare resume, or /resume inside a session, opens a picker of saved sessions for the current workspace, newest first. Type to search, Tab to show every workspace, and Enter to resume. Esc clears the search, then starts a new session at launch or closes the picker in a session; Ctrl-C quits at launch. /resume switches the UI to the chosen session and is unavailable while a task runs; /resume THREAD_ID switches directly.

Live diff pane

The live diff viewer opens at the first edit or command; read-only turns don't open it. Main-agent and subagent calls get labeled cards that stream input as it arrives. When a turn finishes, the viewer switches to the saved diff. A failed or unfinished call never becomes a saved change.

  • v switches views; ? lists diff shortcuts.
  • In the saved Diff, s shows and focuses the file/Changes navigator; press it again to hide the navigator. t toggles tree/flat paths, / filters files.
  • The navigator and diff have separate focus. Arrow keys act on the focused region. Selecting or clicking a file previews it while keeping list focus; Enter opens it and focuses the diff. Click the diff to focus it, or press Esc from an opened diff to return to the list.
  • n/p change files, [/] jump between hunks, and j/k, Space/b, and g/G scroll. Opening a file starts at its header.
  • Tab switches the navigator to Changes: a graph of changes by caller (main or the agent's name) with each change's source, such as apply_patch, sed, or python3. {/} step through changes, a shows one caller's changes at a time, and 0 shows all callers. In the tab, Enter on a caller filters to it, and Enter or h/l on a change expands or collapses its files.
  • Click an Edit to inspect its captured diff in the shared dialog. Reply, question, and journal-agent links also open dialogs, leaving pane filters and scroll positions unchanged. Completed host file-change diffs open even while other commands in the same batch are still running. Esc dismisses the dialog.
  • New saved edits refresh the content without moving your chosen file or scroll position. Streaming previews still follow live edits until you browse; r resumes preview following.

See live view details.

Journal pane

Press Ctrl-B then 5 to open Journal. Its title counts tasks by state. Open tasks come first; subtrees start expanded and collapse oldest-first when space runs short. Use j/k or arrows to select, Space to expand or collapse, d to read full details, Enter to open a row, and c to copy the selected path. Click a ▸ marker to expand it, or click a row to open it. Esc returns to Main. Blocked tasks show their reason; notes have no state label. Entries replaced by later direction stay dimmed with superseded by and the path of their replacement. Delegated journals appear under their owning task, or in an Agents group after the owned plan. Agent headings show their lifecycle separately from task states; expanded descendants use local paths without repeating the agent name. Outcomes follow the work they summarize. Press c to copy their full journal address. Press Enter on, or click, an agent to open its Activity.

The plan strip stays above the composer while work remains. Main offers a continuation countdown after an agent stops with unfinished work, including after answering a follow-up. Esc cancels. Blocked tasks and pending questions pause automatic continuation. Explicitly stopped work stays paused across later questions, forks, and resume until reactivated. Ordinary continuation keeps the current context, while planned slice boundaries follow the selected compaction mode. Headless sessions use the same policy without a countdown and require interactive continuation when a question needs an answer.

Main shows task transitions and, while Journal is hidden, notes. Work updates appear in separate cards; open a card for full evidence and older notes. Ordinary answers remain in the conversation, and an unchanged plan does not add a report card. Task timers count active work, pause while blocked or the agent is inactive, and retain their totals when work resumes.

Agents pane

The Activity pane streams child activity, messages, and replies, including while Main waits. The Agents roster below the main columns shows children with their active elapsed time, provider round trips, output tokens/sec, and cumulative edited lines as +N -N. The roster header's +N -N reports the final composed outcome across agents, so superseded edits and files created then deleted do not inflate it. It uses recorded changes, not a live Git diff; incomplete or inconsistent evidence shows ?. Main's conversation and progress stay in Main. Usage and estimated API costs appear per thread and survive resume while their records are retained, including for completed agents. Missing consumption is not zero: ≥ marks known lower bounds (including restored totals), and unavailable metrics stay blank. Older sessions without retained accounting cannot recover usage from context counts. Elapsed timers exclude idle gaps and freeze when work stops; the separate last-response age continues counting. Main's output throughput appears only beside context in its composer, not in its roster row. The last valid provider-measured rate stays visible while streaming and between requests until a newer valid terminal measurement arrives. Throughput stays blank before the first valid measurement. Visible streaming omits hidden reasoning, so it is not used to estimate total output throughput. Measured rates survive resume. See Metrics for launch-wide totals.

  • Click an agent to inspect its activity; reply links address that agent.
  • In Activity or Agents, a toggles selected-agent filtering. The hint reads a all while filtered, and a only in the shared view.
  • Scrolling pauses following; End resumes it. The mouse wheel scrolls without changing keyboard focus.
  • When the Activity title shows Older history, focus Activity and press o to load an older page for the selected child, or the first child with older history in the shared view. Esc cancels the read; o retries a failed read. Intentionally unloaded history is distinct from unavailable evidence.

Redirected sessions keep ordinary Codex input/output and inline agent activity. Inside Herdr, Mekugi advertises the invocation through Herdr's agent hint. Herdr is optional and does not control Mekugi's internal panes.

Output dialog

Click a command, program, read, error, or long-content excerpt in Main or Activity to open its full content in the shared dialog above the panes, without expanding the transcript. Read source and unified diffs use syntax colors. Untyped command output above 8 KiB stays uncolored for responsiveness; its text remains available for reading, searching, and copying. File-specific and diff highlighting retain their 256 KiB limit. Supported Bash commands and Linux /bin/sh commands backed by dash use the same command tracking. Each segment of a command list streams its own output and shows its state and measured elapsed suffix; clicking it opens that segment's tab with its retained output and exit status in the shared dialog. Supported single commands use measured command time in the same suffix, leaving output unchanged. See command tracking for limits and overhead. Older history without timing evidence shows no per-command duration. Without retained output boundaries, the dialog labels the output as combined. Errors keep a short inline preview. Click details, or focus Main or Activity and press Ctrl-B then !, to read the full error, including restored JavaScript execution failures. The keyboard shortcut opens the newest error; Left/Right reaches the other retained errors in that transcript. Host-omitted text cannot be recovered.

Click a Markdown link to an existing local file in Main, Activity, or a dialog to read its current contents. Relative paths resolve against the session workspace; absolute paths and local file:/// links also work. A :line suffix scrolls to that source line when it exists. The path row uses workspace-relative display inside the workspace and stays absolute outside it. Drag to select the path or visible content, then y, c, or Ctrl-C copies it; y without a selection copies the original file contents. Files must be UTF-8 text no larger than 8 MiB. Read failures, oversized files, and binary/non-UTF-8 files show red, copyable errors. Terminal controls are sanitized for display. Reopening reads the file again; an open dialog does not monitor changes. HTTP(S) links still copy their destinations in Main and Activity; clicking them inside a dialog still does nothing. Missing or unrecognized file links keep their prior behavior.

  • Left/Right or a click switches tabs. j/k, PgUp/PgDn, and g/G scroll; live output follows its tail until you scroll up.
  • / searches, and n/N step through matches.
  • y copies the page's output. Drag to select text, then y, c, or Ctrl-C copies the selection.
  • The top-right [×] button, Esc, q, or a click outside closes it.

See activity display.

Recoverable output and change review

Saved diffs and mchanges record recognized source edits, including edits to ignored files, and the file changes of any other command that may write, such as a Python script, found by comparing workspace snapshots taken before and after it. Agents do not need apply_patch to have their edits recorded. Inside a Git repository, ignored paths such as an ignored node_modules/ stay out of the record unless an edit names them; outside Git, bulk new files in one directory are left out. Changes made by you while a command runs are attributed to that command. LiveDiff previews remain provisional.

Wrapped-session helpers

Session helpers let the agent read less output and recover what it omitted, or review and undo recorded edits. They are available only inside a wrapped session; you can ask the agent to use them.

Command Purpose Requirements
mread Continue bounded retained output by reference Access to the router's replay directory
mrun Bound a foreground command's output and optionally keep its ending The wrapped command
mchanges Review the current thread's edits, compose captured diffs, or read/revert/reapply explicit IDs Access to the router's replay directory
mcat Read raw UTF-8 rows, with multi-file batching, ranges, and tail selection None
msymbol Look up compact definitions and file-grouped references; batch queries in one call gopls for Go; TypeScript 7 as tsc for JS, TS, and JSON; pyright-langserver for Python
inspect_file Inspect a structural outline None
mchanges --list
mchanges amber1..amber3 --summary
mchanges revert amber2
mread REF
mcat --number source.ts 10-20 40:60
inspect_file source.ts
mrun --tail -n 20 go test ./internal/router

mchanges is the recorded view of agent changes, including ordinary Git-ignored files such as FIXME.md, not a live Git diff. Dependency trees are summarized as one directory status, such as M node_modules/, without descendant listings or content. Manifest and lockfile changes remain reviewable. Directory summaries cannot be reverted or reapplied because their contents are not retained. Tests, generators, and other commands without known targets also record changes observed while they ran. These are labeled observed during command window, since another writer may have made them; unavailable evidence is reported rather than treated as no changes. Like git revert, mchanges revert merges any later edits and marks overlaps with conflict markers. The revert is recorded as a new change, so it can be undone too. See the change record, reader, and execution contract.

Metrics

Open /session in Main for the current launch's request and retry counts, provider usage, usage-evidence coverage, average output tokens/sec, measured cache rate, capture health, and transport details. Average throughput is measured output tokens divided by the sum of their provider-request seconds, including request latency and automatic transport retries, not an average of individual rates or session wall time. Local preparation, tool execution, and idle time between requests are excluded. Measured rates use provider-response receipt time, before local processing and delivery of already-read output. Unread transport buffering and backpressure still count, so these rates describe observed provider-request throughput, not provider-only generation speed. Requests without timing or authoritative token totals are excluded from both sums; measured request count and duration show the coverage. Output includes provider-counted reasoning tokens. A measured zero-output request has zero throughput; missing timing is unavailable. Exchanges shows timings, errors, and each attempt's provider-returned service tier, not the configured tier; missing evidence stays unavailable. Left/Right or Tab switches Overview, Transport, and Exchanges; Up/Down, mouse wheel, and PgUp/PgDn scroll. In Exchanges, [ selects older and ] newer observations. r refreshes immediately; the open dialog also refreshes once per second. Escape closes without interrupting a turn. Metrics include all threads in this launch, not just the currently displayed session, and do not restore historical totals after resume. There is no browser dashboard.

The same sanitized metrics remain available through the local API:

curl -sS "${MEKUGI_BASE_URL%/v1}/api/metrics"
mekugi --capture-output capture.jsonl codex

Launch metrics stay in memory unless captured with --capture-output; captures hold sanitized measurements only, with no prompts, patches, or credentials. Provider-reported usage is authoritative; local token estimates are not billing figures. Costs are API estimates, not subscription charges. See the metrics reference.

mekugi --debug codex writes a private mekugi-debug-* bundle under $XDG_STATE_HOME/mekugi/debug (default ~/.local/state/mekugi/debug). Inactive bundles are removed after 14 days; copy a bundle elsewhere to keep it. Explicit external capture/read destinations are not removed. Existing temporary bundles are left untouched. /session shows the bundle path and measured application-write bytes in Overview; final metrics include the same accounting. These bytes cover this router's managed-record and debug/capture writes, not physical disk traffic or subprocess writes. On exit, “To diagnose this session” prints an inspection command ready to share with an agent. Debug bundles include private session content and are not sanitized. Repeated instruction/tool content is stored once and referenced by later requests, while request and wire-projection evidence remain available through the inspection command. Its report includes artifact sizes and application-write metrics to help identify bulky or incomplete evidence. Older bundles remain readable and are not rewritten. Debug mode records future requests only. See debug evidence.

Configuration

Mekugi settings

Create mekugi/config.toml in your user configuration directory: $XDG_CONFIG_HOME or ~/.config on Linux, ~/Library/Application Support on macOS.

# Optional overrides, keyed by exact model ID.
[service_tiers]
"gpt-6-astra" = "fast"
"gpt-5.6-sol" = "default"

[providers.opencode_go]
api_key = "your-go-key"

[providers.opencode_zen]
api_key = "your-zen-key"

Every section is optional. Settings are read at startup and never rewritten.

  • Service tiers replace the request's tier after model selection. The values are auto, default, fast (sent as priority), priority, and flex. The provider must support the tier you choose. The composer and /status show the effective tier, including this override, rather than only Codex's requested tier. /tier shows the effective current tier. Confirmed explicit choices, including default, override configured defaults for that thread and routed model during this invocation without changing your config file. /session reports the provider-returned tier, which can differ from the requested tier.
  • API keys: these file keys are optional alternatives to the OpenCode environment variables.
Troubleshooting and integrations
  • Post-compaction recovery: After compaction, Mekugi restores a bounded snapshot of Main's journal and changes. Subagents and passthrough mode are unaffected. This needs Codex's compact SessionStart hook support (tested with CLI 0.156.1). Opt out with --post-compact-recovery=false or /hooks. If Codex asks you to review the hook, use /hooks. Custom -c hooks=... settings are left alone; to enable recovery with them, add a SessionStart handler matching ^compact$ that runs /absolute/path/to/mekugi post-compact. Hook failures don't stop the task. See guidance behavior.
  • Journal context reset: The default --journal-compaction=auto uses retained task, constraint, change and failed-command evidence for /compact and context-full requests instead of asking the provider for a summary, including child threads. Unavailable or ambiguous identity, evidence, storage or recovery rendering stops the reset with a visible error and no provider request. Recovery keeps constraints and open work inline; completed task bodies and agent history stay available through journal reads when needed. This does not establish improved model success or token savings. Opt out with --journal-compaction=off for provider compaction. slice uses journal resets only at planned slice boundaries and provider compaction otherwise. When the latest host-reported context use reaches at least 70% of the model context window, the next model request reminds the agent to split work into slices. Ordinary unfinished-work continuation keeps context. At planned slice boundaries, auto and slice reset before continuing, while off continues without resetting. The UI offers a countdown; Esc cancels. An interrupted reset may require manual continuation. Auto-mode commands and progress say Context reset. Exact retained journal-answer evidence adds Context reset from journal; click it to read the recovery message shown to the model. Older or expired messages are marked unavailable. Generic reset rows do not claim journal provenance or zero provider tokens. See reset behavior.
  • Instructions: Wrapped sessions disable Codex's /goal feature. Anything between <!-- mekugi:omit --> and <!-- /mekugi:omit --> in instruction files is omitted for the session; the files themselves are not changed. When skills-mgr is on the PATH, Mekugi turns off Codex's stock skill catalog for the session. Managed $skill selections attach their instructions in the composer; other Codex-selected skill injections remain compact name references. See guidance behavior.
  • Issue reports: start with MEKUGI_DIAGNOSE=1 to give agents a report_issue tool. Each report runs the commands in hooks.diagnose of mekugi/settings.json in your user configuration directory. Commands are templates with .Title, .Body, shellquote, and format_markdown, for example gh issue create --title {{shellquote .Title}} --body {{shellquote .Body}}. See agent issue reports.
  • Plugins: put .js or .mjs modules in mekugi/plugins in your user configuration directory. See the plugin contract.
  • Executor environment: the router and executor must see the same workspace paths and runtime directory. MEKUGI_RUNTIME_DIR overrides the default temporary directory.
  • Failures: startup errors print before Codex launches. Session failures appear as user-only commentary; undelivered notices print to stderr after exit. A router translation fault ends the turn and suggests recovery steps.
Replay storage

Replay records live in $XDG_STATE_HOME/mekugi/replay, or ~/.local/state/mekugi/replay if that variable is unset. Resuming and side conversations need no extra flag. Replay doesn't rerun old commands or restore processes. Roster usage shares this managed store; existing records need no migration. Publication remains atomic for readers, with disk flushing left to the kernel. Sudden power loss may lose recent records; unavailable retained evidence is not recovered by rerunning the original operation.

For read-only storage diagnosis, use mekugi inspect-storage; see the storage inspection reference for selectors and output limits.

Mekugi retains up to 4 GiB of managed session data and deletes it after 14 days without activity. When storage is full, it removes the least recently active inactive sessions first, and never touches running work. Your Codex chats and workspace files are never deleted. If storage is full, Mekugi reports when evidence cannot be retained. Free space and retry retaining the evidence, not the completed command or edit. Cleanup can break old recovery and review references. To reset, stop all Mekugi wrappers and move the directory aside.

Inspect a session

This reads a Codex rollout without running anything or starting a router:

mekugi inspect-session --session /path/to/rollout.jsonl
mekugi inspect-session --debug-dir /path/to/debug --field diagnostic
mekugi inspect-session --failures
mekugi inspect-sessions --exclude-model '*grok*' --class production

The default JSON holds tool names, call IDs, outcomes, and sizes, but no private text. For a reported issue with a debug bundle, use the printed --debug-dir command to see failure evidence, capture health, metrics, and AX results. Use --request-id ID --field all to drill into one request's capture and instruction evidence. Values you request with --field may include private error text, instructions, source, and command output. See session inspection and AX evidence.

Replay a session

Review a retained session through the UI without running Codex, calling providers, executing commands, or answering questions:

mekugi replay-session --session SESSION_ID
mekugi replay-session --session SESSION_ID --debug-dir /path/to/debug --speed 4

Use the full session ID, not a rollout path. Mekugi finds the session in sessions or archived_sessions under CODEX_HOME (default ~/.codex). Missing or duplicate rollouts are reported as errors.

Playback defaults to 1.0x. Streaming is simulated from retained text and timing, not a screen recording; --seed 1 makes comparisons repeatable. Referenced child rollouts are included when available. Retained journal records restore task progress, delegated hierarchies, and completion cards when timing is available. Missing records are reported. Original keystrokes, window sizes, and live diff previews are not reconstructed.

The playback bar shows position, speed, and simulated-streaming status. p pauses, +/- steps through speed presets from 0.1x to 100x, [/] seeks ten seconds, r restarts, Ctrl-B 1–5 selects Main, Diff, Activity, Agents, or Journal, and q quits. In Journal, j/k or arrows select, Space expands or collapses, d/Enter opens read-only details, and the wheel scrolls the tree. Esc/q closes details before quitting replay. Outside Journal, Space also pauses and j/k or the wheel scrolls Main. Playback stops on its final frame until you quit. Use --from 5m --until 6m to review a recorded interval; earlier state is loaded first. The current terminal size controls layout.

For offline measurements, use --headless --width 160 --height 48; stdout is a JSON timing summary. Headless playback renders the UI but cannot measure terminal backpressure. Compare runs with the same inputs, seed, speed, and dimensions; use 1.0x for representative latency. Use the profiling build to collect profiles from live sessions or replay. Session contents remain local and may appear on screen. See the replay reference.

Older installations

Finish active sessions before replacing an older installation. Retire any old service and provider configuration separately, keeping unrelated settings and authentication. Then choose a current launch mode.

Documentation

Development

Profile live sessions and replay

From a checkout with the source-build prerequisites, run make mekugi-pprof. It regenerates the existing preview assets and builds bin/mekugi-pprof with optimized code, symbols, and the pprof build tag, plus its executable sibling bin/mekugi-exec. It does not install or replace mekugi. Use the diagnostic binary with your usual launch arguments, or replay offline:

bin/mekugi-pprof codex --yolo
# Alternatively:
bin/mekugi-pprof replay-session --session SESSION_ID --headless --width 160 --height 48 --seed 1 --speed 1

Before the UI takes over, stderr prints an invocation-specific URL: mekugi-pprof: http://127.0.0.1:PORT/debug/pprof/. While that session or replay is running, copy its URL into a second terminal:

umask 077
MEKUGI_PPROF_URL='http://127.0.0.1:PORT/debug/pprof/'
go tool pprof -seconds 30 bin/mekugi-pprof "${MEKUGI_PPROF_URL}profile"
go tool pprof bin/mekugi-pprof "${MEKUGI_PPROF_URL}heap"

Replace PORT with the printed port. The index also offers allocs, goroutine, block, mutex, and execution-trace endpoints. CPU and trace collection start only on request; block sampling uses a 1 ms blocked-time rate and mutex sampling records one in ten contention events. Instrumentation can perturb performance. Profiles cover Mekugi's router, UI, and replay process; separate Codex, executor, and worker processes need their own measurements.

The listener is private IPv4 loopback, with no additional authentication. Local callers can read command-line arguments and other private process data; keep captures private. Session or replay completion ends active captures and closes the listener. The normal build starts no profiling listener, and replay creates no automatic profile files. See the profiling contract and replay comparison limits.

Build and test

The build workflow tests and packages both commands for Linux amd64/arm64 and macOS arm64 on pushes to main, pull requests, and manual runs. Pushing a v* tag also publishes the three archives and SHA256SUMS to a GitHub release, with the tag embedded as the welcome version. Rerunning a tag build replaces that release's matching assets.

Before packaging, Linux amd64 runs the fresh full offline Go suite and make lint with pinned lint tools. Other platforms run command and welcome/version checks.

To review the UI without Codex or model requests, run make preview-native-ui in a terminal. It plays a synthetic session through the real panes and renderer: streaming and long messages, journal edits, retraction and flush, agent summaries, and Main/agent communication. Scroll, resize, and click reply links to inspect them. Keys behave as in the real UI: Enter steers the playing turn or, once idle, starts a new one that echoes your prompt; Tab queues for the next turn; Ctrl-C clears the draft, then interrupts playback, then exits, as does /quit.

For offline terminal-layout regression checks, run make test-ui-snapshots. Failures leave .txt.new candidates beside the reviewed fixtures and print a diff without replacing the baseline. After reviewing an intentional change, run make update-ui-snapshots SNAPSHOT='^TestUISnapshotJournalReply$', then rerun the check. Omitting SNAPSHOT updates all matching cases. See terminal UI snapshot testing for fixture locations and coverage limits.

The full offline Go suite includes configured-plugin fixtures and requires Node.js 24+ and ripgrep on PATH, even when using built-in frontends. make lint requires golangci-lint and deadcode on PATH; it does not install them. It runs the configured Go linters and deadcode analysis including test executables. Lint findings, deadcode findings, and tool failures all fail the command.

make preview-assets
make test
make lint

Built-in frontends are native Go. Go regenerates the optional plugin shared core; Bun is needed only for the separately invoked JavaScript plugin-host and shared-core tests: bun test ./internal/router/toolplugin/tests.

While implementing, select the affected Go packages and tests, for example make test TEST_PACKAGES=./internal/router TEST_RUN='^TestShellRunnerMRun'. The default checks all packages and uses Go's test cache; add TEST_FLAGS=-count=1 for an uncached run. See focused checks.

License

MIT. See LICENSE.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type ReviewAction

type ReviewAction string

ReviewAction classifies a committed before/after file identity. Renderers use this one classification instead of inferring operation labels independently.

const (
	ReviewAdd    ReviewAction = "add"
	ReviewUpdate ReviewAction = "update"
	ReviewDelete ReviewAction = "delete"
	ReviewMove   ReviewAction = "move"
)

func (ReviewAction) Title

func (action ReviewAction) Title() string

Title returns the user-facing operation name for reports and commentary.

type ReviewComposition

type ReviewComposition struct {
	// contains filtered or unexported fields
}

ReviewComposition composes one file's ordered, applied review captures. It retains only captured lines, not source files. Its zero value is ready to use. Hidden captures hide their regions without discarding the original baseline.

func (*ReviewComposition) ApplyWithHighlight

func (c *ReviewComposition) ApplyWithHighlight(file ReviewFile, hidden, highlighted bool) error

ApplyWithHighlight also marks touched net regions for auxiliary display. It validates the captured chain before publishing any new composition. The hidden flag prevents a late receipt from reviving already hidden content. Highlights follow source regions through composition, not rendered line numbers. Hidden captures cannot introduce highlights; a full revert removes them.

func (*ReviewComposition) Consistent

func (c *ReviewComposition) Consistent(content string) bool

Consistent reports whether content agrees with every source line the composition has learned at its current positions. An edit made outside the composed captures breaks this, even when no captured hunk would touch it.

func (*ReviewComposition) FilesWithHighlights

func (c *ReviewComposition) FilesWithHighlights() []ReviewHighlightedFile

FilesWithHighlights returns visible unhidden original-to-latest regions, with highlights introduced by ApplyWithHighlight. Matching captured context is included when available; unknown source is never synthesized. Path-only changes mark their header projection.

type ReviewFile

type ReviewFile struct {
	BeforePath string
	AfterPath  string
	Diff       string
	// Incomplete describes unavailable content; it is not an empty-file diff.
	Incomplete string `json:",omitzero"`
	// Directory is a metadata-only directory change. Its contents and descendant
	// paths are not retained and cannot be composed, reverted or reapplied.
	Directory bool `json:",omitzero"`
	// Binary marks intact non-text content, reviewed by size and hash only.
	Binary bool `json:",omitzero"`
	// Link marks a symbolic link on either side; its rows are link targets,
	// not file content.
	Link bool `json:",omitzero"`
	// CopyFrom names an unchanged source whose content an added file copies.
	CopyFrom string `json:",omitzero"`
	// Origin labels the tool that chose this file or its content. Empty means
	// the agent chose both.
	Origin     string `json:",omitzero"`
	OriginNote string `json:",omitzero"`
}

ReviewFile is an immutable original-to-final review projection. Unlike the executor patch it includes deleted content and preserves line-ending changes. Paths are empty on the absent side of an addition or deletion.

func RenderBinaryReviewFile

func RenderBinaryReviewFile(beforePath, afterPath string, beforeSize, afterSize int64, beforeHash, afterHash string) ReviewFile

RenderBinaryReviewFile reviews intact non-text content without source rows, in the spirit of git's "Binary files differ".

func RenderIncompleteReviewFile

func RenderIncompleteReviewFile(beforePath, afterPath, reason string) ReviewFile

RenderIncompleteReviewFile retains an applied operation's identity without inventing source rows when its contents could not be captured.

func RenderReviewFile

func RenderReviewFile(beforePath, afterPath, before, after string) ReviewFile

RenderReviewFile captures an operation-owned before/after pair using the same diff semantics as engine edits. An empty path denotes an absent side. Pure moves may supply empty contents on both sides without reading the source.

func RenderReviewPreviewFile

func RenderReviewPreviewFile(beforePath, afterPath, before, after string) ReviewFile

RenderReviewPreviewFile projects provisional before/after content with compact context. It is display-only, not completed historical capture evidence.

func RenderUnbasedReviewFile

func RenderUnbasedReviewFile(path, after, reason string) ReviewFile

RenderUnbasedReviewFile shows a file's current content when its prior content is unknown. The rows are context for review, not a diff against an empty file, so line counts stay unavailable.

func (ReviewFile) Action

func (file ReviewFile) Action() ReviewAction

Action classifies the committed file operation from its captured identities.

func (ReviewFile) Hunks

func (file ReviewFile) Hunks() ([]ReviewHunk, error)

Hunks exposes captured geometry without reading files or duplicating the engine's diff parser in viewers. Path-only changes return no hunks.

func (ReviewFile) LineCounts

func (file ReviewFile) LineCounts() (added, removed int)

LineCounts counts added and removed source rows in a captured review projection. File headers, context, and missing-final-newline markers are not source changes. Incomplete captures return -1 for both counts.

func (ReviewFile) Merge

func (file ReviewFile) Merge(current string, reverse bool, label string) (ReviewMerge, error)

Merge applies the captured hunks to current content: forward replays the recorded change and reverse undoes it. A hunk is located exactly near its recorded position first. Otherwise its surrounding context anchors a region that is merged three ways, leaving conflict markers where the region and the requested side both changed. A hunk without locatable context is rejected instead of guessed. Captures hold only hunk context, so no file is read.

func (ReviewFile) UnifiedDiff

func (file ReviewFile) UnifiedDiff() string

UnifiedDiff omits the redundant operation header when unified headers already describe the file. Header-only changes (empty files and pure moves) retain it. Rendering captured records here also keeps historical reads consistent.

func (ReviewFile) UnifiedDiffForWorkspace

func (file ReviewFile) UnifiedDiffForWorkspace(workspace string) string

UnifiedDiffForWorkspace shortens display headers without changing retained paths or source rows. Composition and filesystem operations use the originals.

type ReviewHighlightedFile

type ReviewHighlightedFile struct {
	ReviewFile
	Highlighted bool
}

ReviewHighlightedFile pairs a composed projection with process-local display metadata. Highlights are not part of immutable captured ReviewFile records.

type ReviewHunk

type ReviewHunk struct {
	BeforeStart, AfterStart int
	ChangedStart            int
	Rows                    []ReviewRow
}

ReviewHunk is one validated captured hunk with zero-based source coordinates. ChangedStart excludes leading context; deletions use their anchor. Rows exposes source content without diff framing.

type ReviewMerge

type ReviewMerge struct {
	Content string
	// Conflicts counts regions written with git-style conflict markers.
	Conflicts int
	// Satisfied counts hunks whose requested side was already present.
	Satisfied int
	// Rejected holds captured hunks, in review format, that could not be located.
	Rejected []string
}

ReviewMerge is the result of replaying or undoing one captured review against current content. Rejected hunks are left out of Content.

type ReviewRow

type ReviewRow struct {
	Kind byte
	Text string
}

ReviewRow is a validated source row. Kind is ' ', '-', or '+' for context, removal, or addition. Text retains source bytes, including its line terminator; a missing final newline is represented by the absence of that terminator.

Directories

Path Synopsis
Package capturer observes the router's existing client and provider seams without adding a listener or changing request and response bytes.
Package capturer observes the router's existing client and provider seams without adding a listener or changing request and response bytes.
cmd
mekugi command
mekugi-exec command
Command mekugi-exec tracks the segments of one Codex command script.
Command mekugi-exec tracks the segments of one Codex command script.
internal
appserver
Package appserver owns the Codex stdio RPC connection and its child process.
Package appserver owns the Codex stdio RPC connection and its child process.
chat
Package chat classifies Chat Completions wire facts.
Package chat classifies Chat Completions wire facts.
commentaryid
Package commentaryid owns the reserved IDs used for router-generated messages.
Package commentaryid owns the reserved IDs used for router-generated messages.
execsegment
Package execsegment splits a Codex command script into its top-level segments and instruments them for per-segment tracking.
Package execsegment splits a Codex command script into its top-level segments and instruments them for per-segment tracking.
gooutline
Package gooutline supplies declaration boundaries from the host Go grammar.
Package gooutline supplies declaration boundaries from the host Go grammar.
outputdedupe
Package outputdedupe finds repeated line runs in earlier visible text.
Package outputdedupe finds repeated line runs in earlier visible text.
persistence
Package persistence owns application-write accounting and atomic publication.
Package persistence owns application-write accounting and atomic publication.
responses
Package responses owns wire-level Responses event facts, not feature policy, transport lifetimes, or execution.
Package responses owns wire-level Responses event facts, not feature policy, transport lifetimes, or execution.
sharedwasm command
tokenizer
Source: github.com/tiktoken-go/tokenizer/codec/codec.go@v0.8.1 The splitting and byte-pair merge algorithm is retained verbatim; long pieces use an equivalent heap merge, and vocabulary storage is owned by tokenizer.go.
Source: github.com/tiktoken-go/tokenizer/codec/codec.go@v0.8.1 The splitting and byte-pair merge algorithm is retained verbatim; long pieces use an equivalent heap merge, and vocabulary storage is owned by tokenizer.go.
tokenizer/regex
Package codec registers the pinned upstream generated regex engines.
Package codec registers the pinned upstream generated regex engines.
ui/activity
Package activity renders display-only activity blocks, Markdown, and journal result layouts.
Package activity renders display-only activity blocks, Markdown, and journal result layouts.
ui/diffview
Package diffview presents captured diff navigation and provisional live cards.
Package diffview presents captured diff navigation and provisional live cards.
ui/mermaid
Package mermaid renders the bounded Codex flowchart subset without I/O. Source: codex-rs/mermaid/src/parse.rs:15:217@[687a119f0fcaace47e1f1abcc77cec6c813fd6da] parse Source: codex-rs/mermaid/src/syntax.rs:9:105@[687a119f0fcaace47e1f1abcc77cec6c813fd6da] statements
Package mermaid renders the bounded Codex flowchart subset without I/O. Source: codex-rs/mermaid/src/parse.rs:15:217@[687a119f0fcaace47e1f1abcc77cec6c813fd6da] parse Source: codex-rs/mermaid/src/syntax.rs:9:105@[687a119f0fcaace47e1f1abcc77cec6c813fd6da] statements
ui/terminal
Package terminal provides terminal input, scrolling, and raw-mode lifecycle primitives independently of router state and pane composition.
Package terminal provides terminal input, scrolling, and raw-mode lifecycle primitives independently of router state and pane composition.
uisnapshot
Package uisnapshot supports rendered UI regression fixtures in tests.
Package uisnapshot supports rendered UI regression fixtures in tests.
vcsguard
Package vcsguard decides which version-control invocations publish to a remote, and defines the approval channel between a guarded command and the router.
Package vcsguard decides which version-control invocations publish to a remote, and defines the approval channel between a guarded command and the router.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL