omp packages

pi-supernova0.11.0

CodeMode for Pi and OMP: read, edit, write and bash, with transactional files, source views and shared-input program batches.

adityavg13 Published 16 days ago MIT ~2.8K downloads/mo

Built for omp

The author tagged this package oh-my-pi.

Did it work for you?

Result

One report per person. A new report replaces your old one.

Reports 0

No reports yet.

Readme

pi-supernova

One supernova invocation. Inline code, a workspace program, or an explicit program batch. Four commands inside CodeMode.

const source = await read("validateRefreshToken");
return source;

The model submits JavaScript, not four separately advertised native tools. Ordinary JavaScript control flow remains available; the guest command bindings are only read, edit, write, and bash. Supernova supplies retrieval, transactional file operations, batching, bounded results and the grouped nova UI. There is no supernova object inside a program: use await bash(...), not const { bash } = supernova. Do not shadow the four command names with variables.

Contents

  1. Install and update
  2. Four guest commands
  3. Tokens: native tool calls vs Supernova
  4. TUI presentation
  5. Background terminal sessions
  6. JSON reports and targeted text audits
  7. Execution and automatic batching
  8. Context, caching and failure fidelity
  9. Optional workspace change notifications
  10. Security and host boundary
  11. Development and evidence
  12. Research and prior art
  13. Release notes
  14. Limits
  15. License

Install and update

Install the published package in your host:

pi install npm:pi-supernova
omp install npm:pi-supernova

Local checkout installs are for development, not distribution:

pi install /path/to/pi-stack/packages/pi-supernova

Image reads and returned images are validated with Sharp: at most 32 million decoded pixels across all frames, one image at a time, in a subprocess with a 5-second kill deadline; text-only work never loads it. Exact-content cache hits do not wait for unrelated decoders. Cancelled queued validations withdraw without releasing the active decoder's memory slot. Decoder errors retain that slot and watchdog until the child closes; repeated errors keep the original diagnostic. Whole image reads and whole text windows sign their loaded bytes rather than rereading the file; partial windows still sign the complete file. Keep Sharp's platform-specific optional dependencies enabled. For a local checkout, refresh dependencies before starting the host:

npm install --prefix /path/to/pi-stack/packages/pi-supernova --include=optional

Install dependencies on each target machine rather than copying node_modules between operating systems or CPU architectures. Published-package installation resolves these dependencies through the host's package manager.

Git pushes do not update npm installations. Publish the new npm version first, then reinstall it in your host. To pin 0.11.0 after it is published:

pi install npm:pi-supernova@0.11.0
omp install npm:pi-supernova@0.11.0

In Pi, pi list shows the configured package sources. A local path uses that checkout directly; an npm source uses the installed npm copy. Do not assume that pushing a checkout or running /reload updates the copy executing in your host.

Both host manifests use index.js. The old src/bridge/pi-extension.ts path remains a compatibility entrypoint but no longer imports Pi tool factories. After updating JavaScript sources, fully exit Pi and resume in a new process. Pi 0.85.1 can retain native ESM modules across /reload, even after its extension factory cache is cleared; /reload alone is not sufficient in that case. OMP uses the same shared engine; restart it after updating the link as well.

For deferred-context-engine, pin supernova in alwaysActive and neverDefer. Remove the four native names from those pins and restore their previous blocks if you want the wrapper to be the only file/shell surface. Preserve unrelated settings. The runtime does not silently rewrite your tool policy.

Four guest commands

Function Examples and behavior
read read(path, offset?, limit?), read({path,offset,limit}); one-based line windows
read return await read("plot.png"); displays images directly, without a browser
read read({path,json:".verdict"}); parse full JSON before bounded field selection
read read(directory), read("symbol or question"), read(path,{about:question}); a path is raw text, a symbol is a view
read read({query,resolve:true}); same view as read("symbol"): status, path, line, lines, text, complete
read read({query,evidence:true}); ranked evidence with provenance; optional path scopes discovery
read read({path,outline:true}); structural declarations
read read([path1,path2]); up to 64 paths, ordered values; rejects if any path fails
edit edit(path,oldText,newText), edit({path,edits:[{oldText,newText}]}); unique in the file
edit edit(view,text) CAS-replaces that span; edit(view,old,new) is unique inside it
edit edit({path,patch}); unified patch application
edit edit(async () => {...}); filesystem-only checkpoint, described below
write write(path,text,options?), write({path,content}); atomic replacement
bash bash(command,{cwd,timeoutMs}), bash({command,timeoutMs}); bounded output, nonzero exits throw
bash bash({command,args:[...]}); literal executable argv, without shell expansion of argument strings

Patch hunks must advance past the preceding hunk's output region, including its context lines. Neither nominal matches nor relocation may consume earlier output; adjacent hunks at the boundary remain valid. A rejected patch leaves its target unchanged, and an uncaught rejection rolls back the current staged writes.

bash also accepts timeout in seconds for familiar object arguments. timeoutMs is milliseconds and takes precedence. The owned adapter launches executable argv directly on every supported OS, including Windows; use the string form for shell builtins, functions or startup hooks. Literal argv never enters a captured shell executor. Windows string commands require native Git Bash on PATH, not WSL's System32/bash.exe; source search requires a spawnable native rg.exe. Put their real executable directories before WSL or broken WinGet links in the host's PATH. Windows limits process command lines to 32K characters; use a workspace script file for larger payloads. Argument payloads are not repeated in owned direct-execution errors; stdout/stderr, exit status and source context remain. Session environment variables are taken from the current execution context, not inherited from a different parent session. Pending owned writes are committed before foreground or background launch. A cwd created by those writes is accepted, including in-workspace symlink spellings. Unrelated missing directories, file paths, and escaping paths still fail before pending files commit; bash remains forbidden inside an edit checkpoint.

Shell strings are executed unchanged, including quoted executable paths. For inline Python/Node scripts, prefer literal argv with data instead of nested shell quotes:

{
  "code": "return await bash({command:\"python3\",args:[\"-c\",data.script]});",
  "data": {"script": "q = {'name': 'example'}\nprint(f\"{q['name']}\")\n"}
}

Shell syntax errors keep the original diagnostic and suggest argv or a quoted heredoc; commands are never automatically rewritten or retried. Invalid timeouts and null-byte arguments fail before flushing staged changes. Failure labels are bounded so a large script cannot crowd out its stderr.

Source questions locate a declaration in one command. An exact declaration match uses one bounded direct ripgrep search, without a prerequisite file listing, persistent index, embeddings or summarization. A transient filename listing is a fallback for unmatched content or unresolved bare filenames. Natural-language questions reuse lexical stemming. Source questions and focused about reads accept at most 16 keywords. Ripgrep must be available on PATH.

read(path) stays raw text. read("symbol") is the same view as read({query, resolve:true}) -- not the file, not a path/range header:

const v = await read("validateRefreshToken");
if (v.status !== "found") return v;
await edit(v, v.text.replace("token.length > 3", "token.length > 5"));

The view contains status, path, the matching line, span lines, unchanged text, complete, and nextOffset when a model-facing preview continues. The internal view is not shortened to fit the display. A declaration snap is that span (complete is false unless the span is the whole file). Uncertain results report ambiguous, not_found or incomplete with no selected path. Use {path: directory, about: question} to narrow the scope. Scoping a query does not relabel a selected span as a complete file. Newly staged files and large staged source participate in discovery before commit. Raw offset/limit windows preserve LF/CRLF endings and the final newline; focused views add line labels. A matching window too large for the output budget is reported as budget-limited, not as an absent match. Do not combine incompatible modes such as outline:true and evidence:true.

Ordinary reads stay self-contained. Outlines and graph evidence remain explicit options, not mandatory stages of source resolution. An exact declaration-name about query expands matching declarations ahead of enclosing keyword-heavy scopes; this also preserves identifiers such as get that are prose stop words. Other questions retain relevance ranking, and folded declarations keep line-based recovery guidance. If the view exceeds its budget, expanded bodies appear before the folded declaration map with their original source line numbers; clipped navigation is explicitly disclosed. Views that fit retain source order. Focused outlines collect lexical caller hints for all expanded declarations in one workspace scan. The per-name order and counts are preserved, staged callers stay visible, and the matching-row snapshot lives only for that outline. Existing index cache rules still apply; these hints are not semantic caller resolution. Focused text shaping for files without declarations skips the unrelated caller catalog entirely. Ordinary calls also get:

  • Bounded fuzzy filename hints when a bare source name has no literal match. Existing frecency/directory ranking orders hints; fuzzy matches never select a path. This reuses filename discovery, examines at most 1024 paths and reports incomplete hints.
  • Post-edit source windows and structural warnings for both replacement and patch edits. Body-only edits reuse local declaration spans for lexical reference hints. Up to three names share one bounded, cancellable search; staged callers override disk. These hints do not build an index, are not semantic caller resolution, and report unavailable/truncated searches rather than silently claiming completeness.
  • Structural warnings on writes without echoing successful file contents.
  • Fresh workspace source around up to four failure locations, including shell timeouts and paths relative to the command cwd. Implicit snippets exclude external symlink targets and files over 1 MiB.

Distant edit regions have separate windows and continuation pointers for omitted lines. Structural warnings and source windows are not substitutes for tests.

Optional indexed source discovery

const view = await read({query:"formatLabel", path:"src/labels.js", indexed:true});
if (view.status !== "found") return view;
await edit(view, "label.trim()", "label.trimStart()");

This opt-in route uses a callable isearch tool (pi-indexer protocol 6), then performs Supernova's own byte read and returns an ordinary source view. Indexer text/fingerprints are locators, not read receipts or edit tokens. Returned paths must stay inside both the workspace and requested scope, including symlink targets. Canonical absolute locator paths for an aliased workspace are mapped back to its logical scoped path; this does not admit external paths or escaping symlinks. Multiple or incompletely selected candidates remain ambiguous. Staged writes use the existing overlay-aware resolver instead, so uncommitted source stays visible. Unavailable/disabled/excluded providers fail explicitly. The host's callable set is authoritative: on Pi v0.99, inactive codemode/deferred tools may remain callable, while hidden, model-only and inactive direct tools cannot be invoked. Normal call budgets and traces include the internal isearch operation.

Pi v0.99 delegation uses the current tool invocation's ctx.tools and ctx.executeTool(). Indexer and host overrides pass through host validation, permissions, cancellation and nested tool hooks; a denied call never falls back to a captured raw executor. No legacy event-bus delegation runs on that path. Older Pi hosts can use the synchronous, version-1 pi-indexer:readonly-provider handshake, bound to the active definition's schema identity and session. Exactly one provider is accepted; withdrawal, replacement, session changes and shutdown revoke access. That older read-only API does not replay nested Pi hooks. OMP keeps its native registry/approval route.

Both packages work independently. Ordinary source reads retain their existing resolver. Explicit windows, about, evidence, outline and JSON cannot combine with indexed:true. Named edits already read source internally; no new blanket prior-read authorization rule is claimed. View-span comparison and commit CAS are unchanged.

Safe read-modify-write

A plain file read returns its complete text up to the 64 MiB UTF-8 I/O limit, independently of model-facing character budgets. Explicit offset/limit reads return exact line windows, including long lines, BOM characters and LF/CRLF endings, or fail at the same byte ceiling. Malformed UTF-8 fails rather than discarding bytes. Only JSON parsing consumes a leading BOM. Staged and on-disk data obey the same ceiling. Line-statistics scans adapt to dense newline regions after collecting the bounded preview, then return to native searches for sparse regions; counts, EOF handling and preview bytes remain unchanged. complete:true additionally rejects a window that omits part of the file. For larger files/JSONL, use a bounded parser through bash({command,args}).

Compute on the full value and return only what the model needs. A direct large return is an explicitly truncated display, not a complete artifact to parse or write back. resolve:true source previews retain path/range/continuation metadata; clipped previews are not editable. Prefer edit for replacements. Plain read text is not an editable view: pass the filename to edit, or use read(path,{resolve:true}). Overlong edit/patch paths fail with bounded recovery guidance instead of echoing a source body mistaken for a filename. Near-match previews show exact nearby bytes without guessing why a replacement failed. A write after reading that path still requires edit or explicit replace:true. Writes reject Supernova truncation markers, including legacy host-result markers. For intentionally writing literal marker documentation only, opt in with write({path,content,allowReadArtifacts:true}). This is a data-loss guard, not full dataflow tracking or a security sandbox.

Read/modify/write conflict checks retain a signature of the actual disk bytes, including for empty windows, partial and large-file reads. A fresh explicit text read refreshes that observation; internal receipt reads and body-cache eviction do not. Commits reject changed content; explicit checkpoints also reject conflicting symlink aliases, including new file paths. Overlays, read observations and commits share canonical filesystem identity: reading through another symlink spelling sees staged bytes, including in directory listings and source queries. A retargeted observed or staged path conflicts rather than redirecting a write. Internal edit/patch reads do not refresh that observation. Logical paths remain in receipts. Identity lookups are shared only within one native operation; the next operation and commit resolve them afresh. Missing paths canonicalize their existing ancestors; case/Unicode collisions between new names are checked by the filesystem at publication, not guessed by case folding. These checks do not provide a cross-process lock or make shell/import mutations transactional. Extensionless filenames also support complete:true, for example read({path:"LICENSE",complete:true}).

Directory reads return complete string-entry arrays up to 10,000 unique entries. Larger listings fail with a path and bounded-parser guidance rather than silently returning an incomplete array. Metadata lookups overlap eight at a time.

Explicit read arrays reject missing/failed paths. For typed partial outcomes use Promise.allSettled(paths.map(path => read(path))). Successful arrays remain arrays. For literal file content or scripts, prefer the optional tool-level data parameter:

{
  "code": "await write(data.path,data.content); return await bash({command:\"python3\",args:[data.path]});",
  "data": {
    "path": "probe.py",
    "content": "print(\"literal `backticks` and ${braces}\")\n"
  }
}

data crosses the worker boundary as JSON, never as JavaScript source. For a single program its JSON-encoded length is capped separately at maxCodeChars; batches use the combined admission budget described below. Split larger inputs. The binding exists only when supplied, so older programs declaring their own data remain valid. Syntax errors run no commands and give quoting guidance. For inline source, use String.raw (escaping backtick delimiters) or JSON-quoted strings.

On hosts exposing sessionManager.getArtifactsDir(), bare agent://<id> and artifact://<number> read files from the calling session's artifact directory. They preserve ID casing and support offset/limit and structured continuation. These resources are read-only; ambiguous artifact IDs and escaping symlinks fail. A single ?q=.answer (URL-encoded when needed) selects JSON from either resource using the same bounded projection as read({path,json}). The resource must contain valid JSON; ordinary Markdown is not parsed heuristically. This is not the full OMP URI language: full jq, cross-session search and other schemes are not implemented. Hosts without an artifact directory report that limitation rather than treating the URI as a local path.

For unstructured logs/text, read(path,{about:"STT database"}) returns bounded, line-numbered matching windows, or explicitly reports no matching text. It is not a complete-file read. Write temporary investigation files under the workspace (e.g. .work/probe.py): ordinary write/edit paths cannot escape it, including absolute /tmp paths. Shell execution is a separate trusted boundary, not a sandbox.

Reuse a program without resending its source

Save a trusted JavaScript async body or arrow in the workspace, then invoke it:

{"file":".work/audit.js","data":{"paths":["src/a.js","src/b.js"],"term":"TODO"}}

Supply exactly one of code or file. File programs get the same four commands, optional data, limits, deadlines and transaction semantics. Each invocation rereads the file and starts a fresh guest; there is no implicit last-program state, auto-replay, or retained heap. Paths inside the program still resolve from the calling workspace, not the script directory. This runs a Nova program, not an arbitrary JavaScript module or a Python/shell script.

Program files must be regular UTF-8 files inside the workspace, including symlink targets. Invalid encoding, oversized input and syntax errors fail before commands; no truncated prefix is executed. A file changed during loading is rejected before compilation; diagnostic source windows omit unstable snapshots as well. Review untrusted source before running it. Use ordinary edit to revise saved programs. This is explicit source reuse, not conversation compression: prior calls and read results remain intact. Creation costs an additional call unless combined with other work, so prefer inline code for short one-off operations. See token measurements.

Batch already-known continuations

{
  "programs": [
    {"code": "return await edit(data.path,data.oldText,data.newText);", "data": {"path":"src/config.js","oldText":"limit = 8","newText":"limit = 16"}},
    {"code": "return await bash(\"npm test\");"},
    {"file": ".work/audit.js", "data": {"paths":["src/config.js"],"term":"limit"}}
  ],
  "timeoutMs": 60000
}

Supply 1--32 programs entries. Top-level code OR file supplies an optional source default; an entry's own code OR file replaces it. Without a shared source, every entry still requires its own. A shared file is reread when each entry runs, so earlier commits can create or update it.

Top-level data supplies an optional input default. By default, explicit entry data replaces it entirely, including null, false, 0 and empty strings. With mergeData:true, both the default and every explicit entry input must be objects: own entry fields override default fields in a shallow merge. Nested objects are replaced, not recursively merged. Each guest receives its own copy; mutations cannot leak between guests or back into caller-owned inputs.

The JSON-encoded array plus any shared code/file/data must fit maxCodeChars. Common source/input counts once, before expansion. Every entry is validated before any program runs. Result representations and output limits are unchanged. Entries run sequentially in fresh guests and commit separately. A successful entry can create the file executed by a later entry. No implicit retries, reordering, shared heap or nested batches are introduced.

For independent audits that use the same inputs, send them once:

{
  "data": {"paths": ["src/a.js", "src/b.js"]},
  "programs": [
    {"code": "return await read(data.paths);"},
    {"code": "return await Promise.all(data.paths.map(path => read({path, outline:true})));"}
  ]
}

This avoids repeating literal arguments, without a compression codec or result elision. Mutating data in one guest cannot affect the next. An entry with data:null receives null, not the shared object; there is no implicit object merge.

For the same program with varying inputs, no temporary script or input file is needed. For example, audit both files with a common term:

{
  "code": "const text=await read({path:data.path,complete:true}); return {path:data.path,found:text.includes(data.term),text};",
  "data": {"term":"TODO"},
  "mergeData": true,
  "programs": [
    {"data":{"path":"src/a.js"}},
    {"data":{"path":"src/b.js"}}
  ]
}

The complete source is still returned twice, once for each requested file; shared arguments do not authorize result deduplication or context rewriting. Existing programs that depend on whole-input replacement keep that behavior unless the caller explicitly requests mergeData:true.

Independent batch entries continue after ordinary failures, including in sequential mode. Cancellation/deadline, exhausted shared call/image budgets, or an uncertain filesystem outcome stop remaining work. Display-text and console-log clipping do not stop execution or mark a successful batch failed; clipped logs set details.logTruncated and carry a bounded warning. Completed edit/write steps remain saved; only an active explicit checkpoint's uncommitted writes roll back. Admission errors throw before any program. Execution failures return a typed partial/stop report, rather than throwing away prior results/images. A tool_result hook also projects the error flag into Pi, which otherwise treats a resolved tool call as successful. isError and details.ok identify failure, details.programs contains every attempted result with its zero-based details.programIndex. details.failedPrograms and details.notRunPrograms identify exactly what needs attention; details.attempted/total gives the counts. Single code/file invocations still throw on uncaught errors, but saved edits are listed in the error and details.savedPaths. Do not repeat them. Arbitrary dependent JavaScript cannot be resumed after an uncaught exception; split independent work into programs or use Promise.allSettled for independent commands.

Set parallel: true with programs to run independent entries concurrently (up to 8 at once). Each still gets a fresh guest and its own commit; results stay in submission order. A failed entry does not stop siblings. Two entries writing the same file race: the losing commit reports a conflict. Sequential remains the default. parallel and mergeData are invalid on a lone code or file call. Image budget overflow marks the batch failed and stops queued entries; already-running entries settle and their completed commits remain. Text/log overflow only clips delivery and sets details.returnTruncated or details.logTruncated; queued entries still run. Parallel execution does not multiply the aggregate allowances.

The outer deadline, host-call budget, batch log allowance, text budget and image limits are shared across the batch. Batch details.logs stays capped at the log allowance; individual receipts retain their bounded per-program logs. Individual read budgets are not reduced. Every attempted program's text is assembled in length-delimited blocks. Oversized batches divide the available text budget among per-program previews, so a large success does not hide a later failure. Extremely small budgets may also clip the framing. Images retain program/image labels. Return summaries or use focused windows when you need complete results on display.

Batch only continuations already chosen by the agent, such as edit then known verification, or create then run known audits. Keep a separate call whenever new source/results are needed to decide the next action. This does not lower reasoning settings, hide observations, or infer a plan on the agent's behalf.

Large inputs and report outputs

The default program limit is 48,000 UTF-16 code units (configurable via maxCodeChars and exposed in the tool schema). The same cap applies separately to serialized JSON data, including quote/newline escaping and object keys. Oversized input fails before commands run and reports its actual serialized size. Split larger documents into separate invocations: first write(path, firstChunk), then write({path,content:nextChunk,append:true}). Positional write(path,text,options) also accepts append, replace, and allowReadArtifacts boolean flags. Unknown options and mixed object/positional signatures reject; options never override the path or content arguments. Append uses the complete internal file buffer, never a bounded model-facing read; it retains conflict checks and explicit-checkpoint rollback. Missing files are created. Multiple invocations are not one atomic transaction: for an all-or-nothing publication, assemble a new staging file and publish it only when complete. External write overrides reject append.

Supernova supports bounded foreground execution and session-owned background terminals (see below), not durable jobs across host restarts. For long archive scans, use a background terminal or resumable chunks and write progress records under .work. Owned foreground bash returns complete combined stdout/stderr to the program within a 2,097,152 UTF-16-code-unit capture ceiling; model/trace output remains a bounded preview. Exceeding the capture ceiling throws instead of returning corrupted partial JSON. Redirect larger output to a file and use read({path,complete:true}) or JSON projection. External bash overrides remain authoritative and may have their own output limits.

Foreground shell commands inherit the current program timeoutMs unless they specify their own; increasing the outer deadline no longer leaves a hidden 60-second shell cap. Set the inner bash timeout shorter than the outer program timeout (for example 10 seconds inside a 20-second program). The outer deadline covers all waits and commands, including sleep; a shell's own timeout command does not extend it. On a deadline or cancellation, the worker stops and pending host calls get a bounded 250ms drain to retain owned-shell diagnostics and finalize process termination. Non-cooperating host executors may still outlive that drain. The same deadline covers the final workspace commit; cancelled queued commits withdraw without writing later or releasing another transaction's lock. Read-only results do not wait for that lock. In-progress filesystem I/O and safe rollback must settle before reporting completion, so they can extend elapsed time. Cancellation or session invalidation during publication triggers recovery, including on the final file. After a completed flush, cancellation keeps the committed files but prevents the pending external command from starting; those versions are not reported as rolled back. Cancellation is reported separately from timeout; neither triggers a retry. Progress files and completed edit/write steps survive later failures; active explicit checkpoint writes may roll back. Termination is a hard stop: guest catch/finally cleanup is not guaranteed to run. On macOS/Linux, foreground and background commands share process-group cleanup: normal leader exit, cancellation and timeout retire ordinary descendants before reporting completion. A shell's command & does not create a durable job; launch the long-running command itself with background:true instead.

Filesystem paths preserve literal leading/trailing filename whitespace; malformed Unicode paths are rejected instead of aliasing replacement-character filenames. Owned text writes, appends, edits and patches require well-formed Unicode. Unpaired UTF-16 surrogates are rejected rather than silently encoded as replacement characters. Valid surrogate pairs, BOMs, combining characters and line endings are preserved. Use an explicit byte-writing command for non-UTF-8 file content.

Large returned objects are bounded previews, not retained artifacts. Oversized named/record batches divide the display budget among sibling entries instead of letting the first file hide the rest. Clipped strings disclose their original UTF-16 length; collections that cannot fit disclose omitted item counts. Error messages escape lone surrogate code units before display budgeting, preserving valid Unicode and newlines. This does not shorten values inside the guest or create resumable artifact handles. Select fields and array windows before returning, rather than parsing a truncated preview; read explicit file windows when you need complete source.

Tokens: native tool calls vs Supernova

0.11.0 keeps complete results: committed native edits and writes stay, independent programs continue after ordinary errors, and indexed:true opens owned source. Source and result text are not compressed; the remaining lever is the standing definition (645 / 633 tokens on o200k_base / cl100k_base). Fixed 13-program replay (js-tiktoken 1.0.21): 28,130 -> 9,819 tokens on o200k_base (65% less than unbatched). Shared source and data, 16 programs, one model call: 17,771 -> 3,487 (80%). Eight programs sharing a 48-path input: 16,309 -> 5,527 (66%). Same six-call schedule versus d444eb7: 18,535 -> 9,819 (47%). Local 8-file worker, Apple M5 Max, Node 22.23.3: unbatched cold p95 19.7 ms (8 bridge calls); coalesced pristine-warm p95 3.1 ms (1 call). Method, both encodings, and limits: TOKEN_COSTS.md.

TUI presentation

Pi and OMP use the compact Nova result card. The default view stays anchored to its latest eight calls during execution and after completion, rather than jumping back to the earliest operations. Completion is explicitly labelled.

  • Successful collapsed cards show call rows, not returned source or JSON bodies; expand to inspect the result. JavaScript-only runs still show a short result. Latest-change previews use five diff rows; failures keep at most eight diagnostic rows with expansion hints. Failed or rolled-back changes are labelled as attempts, not successful persistence.
  • Expansion shows up to 24 recent calls, up to 24 diff rows per operation, logs, and a larger result preview. It is not an unlimited transcript or file artifact.
  • Partial updates deliver the latest state on a coalesced 32 ms cadence (about 31 updates/second at most), not one repaint per operation. Completion cancels queued updates; snapshot frames do not change after delivery.
  • Each displayed value has a 32,000-character UI text budget before layout. Long strings retain a labelled head/tail preview; clipping does not shorten the machine-facing value. Select fields or read explicit source windows when complete content is needed. Expansion does not remove the UI text budget.
  • Printable ASCII wraps in bulk; Unicode uses grapheme-aware wrapping. Each card retains one bounded, uncolored result layout across repaints and expansion. Content or width changes replace it; theme invalidation still repaints all rows. Terminal-width safety remains part of the renderer contract.

These are package-owned renderers using the host TUI, not modifications to Pi or a second terminal renderer. Headless host checks establish layout and repaint contracts, not live-terminal frame-rate, subjective smoothness or model speed.

Background terminal sessions

Start a command without waiting for it to finish:

return await bash({command:"npm test", background:true});
// {sessionId, pid, status:"running", pty:false, output, outputStart, cursor,
//  truncated:false, exitCode:null, signal:null}

Use pty:true for interactive programs that require a terminal, such as a browser/passkey publisher. Literal argv remains supported:

return await bash({command:"npm", args:["publish"], background:true, pty:true});

Starting a publish still requires the user's authorization. This API does not approve commands, bypass shell overrides or provide credentials. PTY mode uses /usr/bin/script on macOS/Linux and fails explicitly if unavailable; it adds no npm/native dependency. Pipes are the default. PTY output includes terminal echo, ANSI escapes and CRLF; it is a transcript, not a full-screen terminal renderer. PTY commands start at 80 columns by 24 rows; dynamic resizing is not supported.

Control the returned ID in a later Supernova invocation:

return await bash({sessionId:data.sessionId, action:"poll", cursor:0, waitMs:1000});
// waitMs waits for new output/exit only when cursor is at the current end.
await bash({sessionId:data.sessionId, action:"write", input:"yes\n"});
return await bash({sessionId:data.sessionId, action:"poll", cursor:data.cursor});
return await bash({action:"list"});
// Or: return await bash({sessionId:data.sessionId, action:"stop"});
  • Results are objects, not encoded JSON or foreground text. poll returns running, exited, stopped, timed_out, or failed, with nullable exitCode and signal. A nonzero child exit does not throw from poll; inspect it. Invalid arguments/IDs, startup failures and failed controls do throw. In PTY mode, exitCode is the system script utility's status; signal termination may be encoded there instead of in signal and is platform-dependent.
  • cursor is an absolute UTF-16 output offset. Pass the previous cursor for incremental output, or omit it to replay retained output. stdout/stderr share a 65,536-character tail. truncated:true and outputStart disclose discarded history; polling does not consume it. A retained boundary or manually supplied cursor inside a UTF-16 pair advances to the next complete code point, with outputStart and truncated:true disclosing the skipped partial character. waitMs is 0--30,000 (default 0).
  • Input is literal, at most 16,384 characters per call. Include \n for Enter and \u0003 for Ctrl-C in a PTY. Input is not echoed into tool traces, but the child/terminal may echo it into output. Do not send secrets casually.
  • Up to 8 running jobs and 32 retained sessions per extension instance. Oldest completed sessions are evicted when needed. list returns metadata without replaying output. IDs are scoped to the originating Pi session and workspace; controls still waiting when that session closes reject rather than returning results from the closed session.
  • A job defaults to a 30-minute deadline, independently of the starting Supernova call. Set its timeoutMs explicitly to change that deadline. Outer program timeouts/cancellation still bound start and control calls; cancelling a poll does not stop its job. Use stop to terminate it.
  • Launch, input and stop are external-mutation barriers; staged edits flush first. List/poll do not flush staged edits. None runs inside an edit checkpoint. Background effects are not transactional and may race edits; ordinary CAS checks still detect changed file bytes, not all external side effects.
  • On macOS/Linux, normal exit, explicit stop, job deadline and session shutdown clean up owned process groups, escalating to kill when necessary. Completion is reported only after cleanup, so ordinary orphaned children are not left running. Failed cleanup remains listed and consumes a job slot until a later stop/shutdown succeeds; it is not silently discarded. Windows pipe cleanup is best-effort (taskkill while the leader is alive), not POSIX group supervision. Jobs do not survive reload, session replacement, host restart or crash as managed sessions. Deliberately detached daemons are not a supported supervision model. Cleanup errors are reported. Launches and controls from an old session generation are rejected, including after a reload that retains the same Pi session ID. A guest started before replacement cannot list, poll, write to or stop the replacement's jobs. Identity is captured once per tool invocation, including queued sequential and parallel batch entries, rather than reread from a mutable host SessionManager. Replacement invalidates the whole guest bridge: further commands, delegated calls, session-resource lookups and pending commits are rejected. Queued commits recheck identity after waiting, and staged replacements recheck before each installation; a failed transaction restores any earlier replacements. Delegated executors recheck immediately before dispatch. External effects that already started or committed are not rolled back by a session change.
  • Background actions require Supernova's owned shell adapter. A registered shell override is rejected rather than silently ignoring background options or bypassing the override's permissions.

JSON reports and targeted text audits

For JSON, select fields inside the read adapter, before output budgeting:

const [verdict, values] = await read({path:"report.json",json:[".verdict",".values[5000:5003]"]});
return {verdict, values};

Selectors support "." (root), .field, .nested[0], .items[0:10], and .["quoted.key"]. Hyphenated names such as .credentials.openai-codex are literal own-property keys, not subtraction. Other punctuation and leading hyphens use quoted keys; selectors still never evaluate code or traverse prototypes. Use json:true for the complete parsed value. Put the selector in json (json:".field"), not a second selector key; a leftover selector folds when json is absent, true, or ".". Selectors are not full jq: pipes, filters, wildcards and negative indices fail explicitly. Missing keys and indices fail; false, zero and null remain values. Slices use an exclusive end and clamp to array length. Only own JSON properties are traversed; nothing is evaluated.

Inputs are capped at 16 MiB, including staged files. JSON reads require regular files and reject named pipes without waiting for a writer. The entire input must be valid JSON before any selection. Each selector is budgeted before allocating the next slice; sparse selector/path/edit arrays are rejected. Selections have a separate 64 MiB estimated storage limit per read, including aggregate multi-selector expansion. Within it, arrays/objects/scalars retain their actual values, even when larger than the display. No routing object is substituted: .map and .filter work on the selected array. Multi-selector values remain independently mutable. Storage accounting charges scalar strings in the same pass rather than retaining a second string worklist; container and alias accounting, aggregate limits and failure guidance are unchanged. Plain .json reads are raw text, including malformed JSON; parsing is requested only by json. Explicit line windows are not necessarily JSON documents. Do not combine json with complete, line windows, or source views. External read overrides reject JSON projection rather than silently ignoring the option. Explicit read({path:"TOKEN"}) / read({target:"TOKEN"}) and path arrays mean filesystem reads even for extensionless names. Missing files throw, including with resolve:false, complete:true or line windows. Only a bare string without those options guesses between a filename and a symbol; use {query:"symbol"} or resolve:true when source search is intended. Source reads protect the resolved file from accidental write replacement even when the result is text or arrives in a streamed batch. JSON document fields such as path and status are data, never evidence that another file was read.

Uncaught read errors abort the program, including return {a:await read(...), b:await read(...)}; earlier successful values are not an implicit partial return. For optional sources, explicitly return await Promise.allSettled(paths.map(path => read(path))). This keeps successful text and per-path errors without weakening explicit checkpoint rollback. Completed edits outside a checkpoint remain saved.

Other read options, even false-valued flags, do not bypass a captured external read executor; its policy, transforms and failures remain authoritative.

For focused Markdown/log audits, use read(path,{about:"document path"}) or explicit offset/limit. Use complete reads for computation within the 64 MiB ceiling, and return a summary. JSON over 16 MiB needs a streaming parser via bash. Arbitrary returned objects still have bounded previews, not implicit continuation handles.

Successful subprocess cleanup wakes on pipe closure rather than waiting for the fallback poll. Completion still requires both closed output pipes and retired owned POSIX process groups; cancellation, escalation and cleanup deadlines are unchanged. This applies to source-search subprocesses and background terminals.

Execution and automatic batching

await Promise.all([
  edit("src/a.js", "oldA", "newA"),
  edit("src/b.js", "oldB", "newB"),
]);
return await bash("npm test");

Put already-known independent reads and checks in one Supernova program using Promise.all (or Promise.allSettled when failures should remain independent). Sequence edits and their known verification in that same program. Start another invocation only when the returned evidence is needed to decide what to do next; use focused read windows to keep the combined result within its output budget.

Compatible independently started reads coalesce at the worker/host boundary. No additional batching command is required. Individual promises preserve their values, errors and per-read safety limits. Reads and known native mutations to disjoint files overlap up to eight operations; same-file mutations stay ordered. Read/mutation transitions, shells, checkpoints and overrides remain barriers.

This does not reorder sequential awaits or predict future model decisions. Explicit path arrays and automatic coalescing share the same typed delivery. Small batches retain the single-reply fast path; beyond 64 KiB estimated storage, items stream to the guest with acknowledgements. Delivery holds its I/O slot until acknowledged, and the final read waits for its host barrier to settle.

Every program runs in a fresh worker. One pristine worker is prepared for the next invocation, then disposed on session shutdown. Executed workers are never reused, so guest globals cannot leak into a later program. Worker preparation still costs CPU and memory; it is moved off the next invocation's critical path, not eliminated.

maxHeapMb sets Node's native worker heap cap. A worker-local check also limits heap plus external buffers to 1.5 times that value, sampled every 50 ms and before host calls and final results. Process-wide RSS is never charged to an individual guest. These samples are best-effort: Bun does not enforce Node's native heap cap, and non-yielding code can prevent sampling until it reaches a command or returns. The outer deadline still terminates non-yielding workers. This is not a hard process-memory or security boundary.

Each successful edit or write command publishes its changes before returning. A later failed command, returned-image error, or uncaught exception does not undo those saved steps. A single multi-replacement edit({path,edits:[...]}) is still one atomic step: its replacements use original coordinates and must all validate. Use separate commands or independent programs for best-effort work; use an explicit checkpoint when the changes must succeed together. Shell execution flushes any pending changes; external shell side effects cannot be rolled back. Stale commits fail explicitly rather than silently overwriting successful concurrent changes. New files use atomic no-clobber publication, so filesystem-equivalent names and destinations created during staging conflict rather than replace existing data. This requires hard-link support on the workspace filesystem; unsupported creation fails without an unsafe rename/copy fallback. Existing files recheck their observed version after staging and before atomic replacement. These checks are not a cross-process filesystem lock. Outcomes explicitly report committed/rolledBack file versions (counted per flush/checkpoint, not unique paths) and external-call attempts. A successful explicit checkpoint publishes the group together before returning. Recovery checks destinations against the bytes this transaction published before restoring or removing them. Detected intervening changes remain intact, and any original backup is retained. Pending commits or failed recovery are reported as uncertain: inspect disk and recovery backups before retrying. Import-based mutations and shell side effects are outside the VFS counters; this is not a filesystem audit.

edit(async () => {...}) creates an explicit atomic filesystem checkpoint. It returns {ok:true,committed:true,value} on success. On failure it rolls back and rethrows the cause, so an ignored failed checkpoint cannot report program success. Use try { await edit(async () => {...}); } catch (error) {...} for deliberate recovery. Shell commands (including background terminal controls), overlapping/nested checkpoints, and concurrent commands outside the active callback are rejected. Await the checkpoint before running shell checks. A checkpoint cannot roll back external shell effects. For a temporary mutation test, save the original text, edit and run the check outside a checkpoint, then explicitly restore it. Catch the check failure and restore before reporting it. A completed finally restoration outside a checkpoint stays saved even if the program subsequently throws. Keep a backup: cancellation or a worker deadline can prevent cleanup from running.

Context, caching and failure fidelity

  • Plain reads are not replaced with earlier-context references. A local cache hit is not proof the model still retains an earlier result after compaction.
  • Concurrent windows into the same observed file version share only an in-flight conflict-signature hash. Completed hashes are not a read cache; every window still checks its own version, and writes retain compare-and-swap validation.
  • Text and JSON computation is independent of display limits. Source previews provide exact continuation; raw displayed text can be clipped and must not be parsed as a complete file. I/O/storage limits still fail explicitly.
  • Model attachments support PNG, JPEG, GIF and WebP. BMP and other unsupported MIME types fail before attachment or commit, rather than causing a provider HTTP 400 on the next request. Convert those sources to PNG first; Supernova does not silently convert, resize or modify the original image.
  • Returned images remain image content blocks, including in arrays/objects. Images not returned by the program stay out of model output. Returned images are limited to 16 attachments / 20 MiB. Overflow fails the program with the aggregate count and byte size, returns no images, and rolls back pending writes. Resize or return fewer images when necessary.
  • Dense multiline string arrays can render as verbatim source blocks instead of escaped string literals. Each block gives its array index and exact UTF-16 length; strings and result types are unchanged. This is output framing, not source compression. It is chosen only when shorter in characters than escaped output; it does not guarantee lower billed tokens for every tokenizer or input. Nested multiline strings use the same approach: the complete value structure references raw[n], followed by length-delimited verbatim string blocks. Literal "raw[0]" values stay quoted; duplicate source is never deduplicated. Small values keep their existing format. Machine-facing result values are unchanged.
  • Intermediate values stay inside CodeMode unless returned or logged. Final text, errors and logs are bounded with explicit truncation. Details support rendering; they are not a second model-facing transcript.
  • Source indexing/caching remains internal. Reads after mutations invalidate stale state. There is no claim of provider-cache or total-task token savings.

Default limits are in src/config/config.default.json. Configuration loads from ~/.pi/agent/supernova.json, the configured host directory, or PI_SUPERNOVA_CONFIG.

Citation elision is disabled by default (seenWindow: 0): each result remains self-contained within the normal output budgets. A positive seenWindow explicitly opts into an experimental ledger with known retention gaps: hidden message details, later context transforms and missing citation targets can invalidate its assumptions. It is not a proven lossless optimization and is not recommended for production. Text limits are character budgets, not tokenizer counts. /supernova reports programs and output characters without labelling characters as tokens.

Optional workspace change notifications

Supernova works without another search package. On hosts exposing pi.events, it provides an advisory workspace:changed event for independent cache/index consumers:

{ version: 1, cwd: "/absolute/workspace", paths: ["/absolute/workspace/file.js"] }

cwd identifies the calling workspace. paths contains absolute file paths after a successful disk flush; paths may contain filesystem aliases. The frozen event and path array contain no source text. Checkpoint merges, restored rollbacks, and read-only programs emit no change event. A shell boundary can flush paths before a later program failure, so notifications are not conditional on overall tool success.

paths: null means the changed paths are unknown: shell or delegated mutation attempts emit this even on failure, as does an incomplete commit recovery. Consumers should invalidate conservatively, not interpret it as an empty change list or a guarantee that shell effects stayed inside cwd.

Subscribe with pi.events.on("workspace:changed", handler). Mark cached state dirty synchronously, then refresh when queried; asynchronous listeners are not awaited. Observer failures cannot roll back writes. This is an optional extension convention, not a built-in host standard, durable event log, or cross-process filesystem watcher. There is no dependency on or automatic routing to any consumer package.

Optional file-read receipts

A successful program may emit workspace:read with the same frozen {version:1,cwd,paths} envelope, containing at most 256 distinct absolute paths. These are file-open hints from native on-disk text reads, not source versions or proof that the model saw the text. A program can summarize a read and still qualify. Receipts cover ordinary, ranged and resolved text reads, including inline/streamed batches; paths may contain filesystem aliases.

Provenance is carried by a private host-side marker, never inferred from source content, result-shaped JSON or the truncated tool trace. Staged overlay reads, empty windows, failed reads, JSON projections, directories, images and structural/focused-only outputs do not qualify. Failed programs publish no read receipt; caught read failures do not discard successfully delivered siblings. Checkpoint merges do not publish before outer program success. Successful earlier programs in a later-failing batch may already have published, like disk commits.

pi.events.on("workspace:read", handler) is optional, synchronous and best-effort. Subscriber errors do not fail the read/program, and there is no import or requirement on an indexer, cache or memory service. A consumer should deduplicate these hints and apply its own repository/inclusion rules; this is neither a complete I/O audit nor an authenticated or durable cross-process event stream.

Security and host boundary

CodeMode executes trusted JavaScript in a terminable worker, not a security sandbox. The four adapters constrain writes/edits to the workspace and allow explicit external reads. Absolute temporary-directory paths outside the workspace are not write destinations: use a workspace path such as .work/verification.log, or a separately authorized external command. Errors identify the rejected path and workspace, including symlink escapes. JavaScript imports and shell commands still have process privileges. Do not run untrusted programs as though these adapters isolate them.

Pi preflights the outer supernova call. It registers with model-only exposure on hosts supporting that contract, preventing recursive invocation by native codemode. The guest surface is still exactly read, write, edit, and bash; this does not expose arbitrary registered tools as guest functions.

Owned filesystem primitives keep their transactional adapters and do not emit ordinary native tool_call events, so third-party guards that only recognize top-level edit or bash need CodeMode-aware handling. On Pi v0.99, delegated host overrides and indexed discovery emit real nested hooks with the host's parent IDs. Their usage is aggregated by Pi, not added again by Supernova. Configured exclusions and supported host-session execution safeguards remain enforced. Guards inspecting code/file inputs must also understand the programs array; its entries do not emit separate top-level tool_call events. Actual-host smoke checks are not a claim that every third-party permission extension has been validated.

Delegated tools with outputSchema can return structuredContent: successful values reach the existing command as data, independently of UI text/details. Oversized structured values become explicitly clipped JSON display strings under maxCallResultChars, never silently reshaped objects or complete-file claims. Host errors still throw through the guest command, even when the nested outcome stores its error flag outside the result. Redaction hooks can remove structured content; Supernova then uses the redacted text rather than stale data. Use explicit read({path:...}) for remote filenames that could otherwise look like symbols.

Development and evidence

Implementation is grouped under src/; all replacement tests are under tests/. Read-budget assertions now test the deliberate 0.9.0 contract: complete internal values and bounded model-facing output. Frozen token snapshots are unchanged. Strict regressions cover batching fidelity, image/context retention, checkpoints, mutation ordering, external symlinks, deadlines, worker isolation, bounded read delivery, and execution-context environment.

Module boundaries

Responsibility Modules
Registration and session lifecycle index.js
Program admission and batching runtime/program.js, runtime/batch-input.js, runtime/program-batch.js
Worker ownership and guest RPC runtime/runtime.js, runtime/worker-pool.js, runtime/guest-worker.js, runtime/guest-api.js
Host permissions, ordering and trace bridge/host-bridge.js, bridge/tool-registry.js, bridge/trace.js
Read routing and typed readers adapters/read.js, adapters/read-{text,json,image,focus}.js
Image validation and isolated decoding shared/png.js, shared/image.js, shared/image-worker.js
Bounded I/O and atomic transactions fs/file-io.js, fs/read-window.js, fs/vfs.js, fs/commit.js
Foreground/background process ownership fs/workspace.js, fs/process-tree.js, fs/background.js
Source search and ranking context/query.js, context/snap-search.js, context/source-entry.js, context/evidence-{graph,rank}.js
Model output and host rendering output/final.js, output/outcome.js, ui/host-render.js, ui/trace.js, ui/render.js

Paths above are relative to src/, except index.js. Layer tests require an acyclic import graph and prohibit context modules from importing runtime code.

Verification

Portability pass, 2026-09-22: the current product sources, including the in-flight terminal-poll shutdown guard, passed the package suite on real hosts:

Host Node Bun 1.4.0
macOS, Node 26.7.0 357 passed 355 passed
DGX Spark, Linux arm64, Node 24.16.0 357 passed 355 passed
Windows x64, Node 24.16.0 348 passed, 9 skipped 346 passed, 9 skipped

A fresh Pi 0.87 loader followed the configured Supernova symlink into this checkout, registered its single supernova tool, and executed read/write. The restarted active extension also completed a pipe job and interactive PTY with stdin, output, and exit code 7. This does not inspect Pi's in-memory module cache or test remote provider sessions.

Commands: npm test --prefix packages/pi-supernova locally; in the standalone remote package, node --test tests/*/*.test.mjs; for Bun, bun --run test on a clean tree. The remote archive contained macOS AppleDouble ._background.test.mjs metadata, which Bun mistakenly discovered as a test; the successful Spark/Windows Bun reruns explicitly selected real files with bun test tests/*/[!.]*.test.mjs (PowerShell constructed the same filtered file list on Windows). New macOS verification archives should use tar --no-mac-metadata --no-xattrs to prevent AppleDouble entries. Final fixture-only changes were additionally checked on macOS/Spark with node --test tests/codemode/{papercuts,guest-contracts}.test.mjs (59 passed) and bun test tests/codemode/{papercuts,guest-contracts}.test.mjs (57 passed); Windows reran the full suite. Totals are reported by each runtime's test runner.

Windows verification selected native Git Bash and the real ripgrep executable directory in the test process's PATH. Its SSH token's backup/restore privileges were disabled only for the test process so real deny-read/execute/write ACLs could exercise permission errors. No machine-wide configuration was changed. Bun 1.4.0 was installed into the temporary Windows verification directory; the machine's older Bun 1.3.14 test runner is not a passing result.

The nine Windows skips remain explicit POSIX/platform-specific cases: shell startup/quoted-script behavior, FIFO admission, alias and descendant semantics, and the large JSON allocation case. Windows literal argv now runs the same ownership/malformed-argument tests as POSIX. PTY tests verify explicit Windows rejection rather than silently skipping or treating pipes as terminals.

Mutation checks rejected lost native-argv ownership, missing-parent and source/ evidence-path regressions, dropped cleanup errors, and unmapped launch failures. A surviving ambiguous-source-path mutant led to a stronger regression. Tests also exercise both synchronous Windows and asynchronous POSIX launch failures. These results do not claim native Windows PTYs, exhaustive interleavings, or new Pi/OMP/provider end-to-end coverage on the remote hosts. Root release gates were not run in this pass.

The historical 0.9.0 release candidate was verified on macOS:

Check Result
Node 26.7 package suite 315 passed; zero failures or skips
Bun 1.4 package suite 315 passed; zero failures or skips
Pi 0.86.1 / OMP 18.2.6 Actual host execution checks passed; Pi TUI checks passed
Clean production-only tarball installation Node/Bun and actual Pi/OMP smoke checks passed
Lint, frozen token gates, repository release check and publish preflight Passed

Failure-first regressions cover corrupt image data, malformed base64, MIME mismatches, decoded-pixel limits and nonfatal batch-text clipping. Additional checks cover animated images, content-based validation reuse, cancellation, decoder-watchdog recovery, and real failures after clipped output. The compiled OMP native-module issue is covered by the actual-host checks, not only unit tests.

Coverage limits: a live Codex round-trip and Linux/Spark smoke checks were not rerun after the final image-validation changes. These results are not a claim of exhaustive platform coverage or guaranteed acceptance by every model provider.

Test user-visible contracts through registered programs: exact source, on-disk results, failure/rollback, isolation, bounded output, and usable host rendering. Inject filesystem faults only to exercise real failure paths; do not prescribe private helper layouts, staging filenames, or syscall counts. New regressions must fail before the fix; for existing behavior, verify that a named deliberate defect makes the intended test fail before accepting it. Preserve existing assertions unless an explicitly requested contract changes; then test both the new behavior and the retained safety boundary. Cost gates cover avoidable search processes, per-read safety limits and progress flooding; latency claims belong in the explicit measurement lane, not arbitrary wall-clock assertions.

npm test --prefix packages/pi-supernova
npm run lint:supernova
npm run measure --prefix packages/pi-supernova
npm run test:tokens --prefix packages/pi-supernova

PI_SUPERNOVA_PI_ROOT=/path/to/pi-coding-agent \
PI_SUPERNOVA_OMP=/path/to/omp \
npm run test:hosts --prefix packages/pi-supernova

The explicit host runner requires macOS network sandboxing and fails, rather than skips, when prerequisites are absent. Verified locally against Pi 0.86.1 and OMP 18.2.6: CodeMode execution, four primitives, automatic read coalescing, checkpoints, images and failed execution. Pi's actual loader/runner and TUI are exercised; OMP runs in a disposable process through its actual session registry, with networking denied. The Pi runner supplies a minimal tool registry, not a full provider session.

The local measurement compares identical eight-file programs with coalescing off, coalescing on, and a pristine-ready worker. It reports latency percentiles, observed maxima, raw samples and bridge calls. Set SUPERNOVA_MEASURE_SAMPLES (20 to 10000; default 200) for longer runs. Maxima describe the measured sample, not hard real-time guarantees. It excludes model latency, provider tokens and prewarm time; it is not a universal comparison against every CodeMode implementation.

Supernova retains its own execution engine and supported public Pi/OMP host APIs. A rebase onto native Pi codemode is not part of this release.

See the changelog for changes and compatibility notes.

Research and prior art

These references describe internal algorithms, not additional guest commands.

The existing implementation references are retained below. Mechanisms requiring an additional model call are not silently invoked by the tools.

Work What we use it for Where
Zero-Mem: Zero-Token Memory Operations for LLM Agents, Xiao, Zhu, Zhang, Chen, Hong, Zhuang, Zhang, Chen, Ouyang, Ren, Huang (arXiv:2607.29377) Evidence selection: entity-context graph with co-occurrence weights (eq. 3