Skip to content

feat: add OMP (Oh My Pi) as a new session backend - #353

Open
timkjr wants to merge 16 commits into
Ark0N:masterfrom
timkjr:omp-mode
Open

feat: add OMP (Oh My Pi) as a new session backend#353
timkjr wants to merge 16 commits into
Ark0N:masterfrom
timkjr:omp-mode

Conversation

@timkjr

@timkjr timkjr commented Aug 27, 2026

Copy link
Copy Markdown

Summary

Adds omp (Oh My Pi, https://github.com/can1357/omp) as an eighth CLI backend,
alongside Claude Code, OpenCode, Codex, Gemini, Antigravity, Pi, Grok and DeepSeek
Harness. It follows the existing external-CLI pattern exactly (own PTY, own tmux
session, own tab identity, isExternalCliMode()), and gets full support across
every surface that pattern touches: schemas, spawn-command building, Docker cases,
remote-SSH cases, multi-user clamping, the UI run-mode picker, and skill docs.

Two things make this more than routine plumbing:

  • Exact-conversation pinning. --continue alone is ambiguous the moment any
    other omp conversation has touched the same working directory more recently.
    omp-session-resolver.ts resolves and pins the real session id once, so every
    later respawn uses --resume <id> instead of re-guessing.
  • Kill-survival. omp-transcript.ts scans ~/.omp/agent/sessions/**/*.jsonl
    directly, so a conversation's history is recoverable in Past Sessions even when
    both the Codeman session record and the underlying tmux pane are gone —
    verified live against a full OS reboot, not just a killed pane.

Notable bugs found and fixed along the way

  • A boot-recovery bug where claudeSessionId (the field also used to alias an
    OMP session's own id) failed to resolve on a plain-reattach path. Root cause
    was two compounding issues: an unconditional second assignment that clobbered
    the correctly-resolved value, and a directory-mangling helper that assumed omp
    mirrors Claude Code's naming convention (keeps the $HOME prefix) when omp
    actually strips $HOME first. This second bug meant continuation pinning was
    silently a no-op for every real case directory under $HOME — only /tmp-based
    manual testing had ever exercised the code path, and it happened to produce the
    right answer there by coincidence.
  • OMP was never actually installed in docker/agent.Dockerfile, and had no
    credential-isolation entry, despite the docs already claiming full Docker
    support. Both fixed and verified against a real --no-cache image build.
    OMP is also the one CLI in this family where sessions/ needs to be a
    shared mount rather than seeded, since Codeman reads it host-side for the
    resume-pinning and history-recovery mechanisms above.

Note for reviewers: while verifying the Docker changes above, I found the
agent image's DeepSeek (dsh) plugin-install step currently fails on a fresh
build against unmodified master ("pnpm not found on PATH") — confirmed via
git diff origin/master that the failing line is untouched by this branch.
Unrelated to OMP; filed separately as #352.

Testing

  • Full suite: 6317 passed, 0 failures (npm test)
  • lint, typecheck, check:frontend-syntax, check:public-assets,
    check:lockfile all clean
  • Live-tested: session create/respawn/resume, TUI-exit + remove-tab,
    TUI-exit + tmux kill-session + restart, and a full server/OS reboot —
    all recover correctly, including first-turn content
  • Docker: verified omp/18.0.8 installs and runs inside a freshly built
    agent image

Known limitations (documented in docs/omp-integration.md)

  • No idle/completion hook — falls back to output-stabilization like every
    other external CLI
  • Killing a pane mid-turn (before an in-TUI /exit) loses the conversation for
    real; omp hasn't flushed its session file yet at that point. This isn't
    something Codeman can compensate for from outside the process.
  • Directory-mangling behavior on a symlinked $HOME is unverified

timkjr and others added 16 commits August 26, 2026 20:05
The rebase hand-repair dropped the closing brace of .welcome-btn-pi:hover
and .btn-toolbar.btn-run.mode-pi:hover before the inserted OMP rules.
The browser CSS parser drops every rule after an unclosed block, so the
deployed UI rendered as unstyled text bars (only ~456 of ~2583 rules
applied). Verified clean via esbuild --minify (no css-syntax-error) and
rebuilt dist.
Adds a Hide CLI buttons group to App Settings → Header & Panels (device-scoped,
client-only like the other per-device header toggles). Each checked mode is
hidden from the welcome screen, the Run dropdown, and the phone overview run
picker, layered on top of CLI availability gating.

- settings-ui: hiddenModes load/save (openAppSettings/saveAppSettings),
  isModeHidden() helper, welcome-button + header-settings re-apply
- session-ui: _refreshRunModeAvailability() also skips hidden modes
- mobile-overview: _buildMobileOverviewRunMenu() also skips hidden modes
- tests: run-mode-ui + mobile-overview cover the hide list
The id-fix edit for the OpenCode chip accidentally replaced the Pi chip
with a second OpenCode label, leaving both appSettingsHideOpenCode and
appSettingsHideOpencode in the DOM (two OpenCode chips, no Pi). Rename the
original chip to the JS-generated id and restore Pi.
…esolver

- omp-cli-resolver.ts already uses createCliExecutableResolver; add dedicated
  test/omp-cli-resolver.test.ts mirroring pi's (version-probe accept/reject,
  negative-cache backoff, VITEST hermeticity gate)
- dependency-registry omp entry now requires OMP_VERSION_REGEX match like pi,
  so codeman doctor and the run-mode resolver agree on what counts as installed
- system-routes /api/omp/status surfaces version
Two prose lists in skills/codeman/ named some but not all external CLI
modes after the omp-mode rebase, which is exactly the drift
test/agent-skill-mode-lists.test.ts exists to catch: SKILL.md's
no-hook-signals list was missing omp, and endpoints.md's version-probe
sentence named pi/grok/omp as a bare 3-mode run with no matching class.
resumeHistorySession() never sent mode when recreating a session from a
history/session-manager row, so the server default silently opened a
plain Claude session for every non-claude row -- reproduced live: OMP
rows spawned Claude sessions on click. Thread the row's mode through
every call site (welcome list, session manager, mobile overview) and
only send the Claude-specific resumeSessionId for claude rows.

Codeman has no live PTY-reattach outside server boot, and it's moot for
OMP anyway (exiting it kills the pane's only process), so route the
non-claude relaunch through each CLI's own continue-most-recent flag
instead of a context-free fresh start. OMP never got one: buildOmpCommand
only implemented --model/--resume despite omp --help documenting
-c/--continue. Added continueSession to OmpConfig end-to-end (type,
schema, builder) mirroring the existing opencode/pi/grok/deepseek
fields, and wired resumeHistorySession to use it.

Verified live: told a real omp session a secret, exited it, closed the
tab without killing tmux, relaunched with --continue in the same
directory, and had it recall the secret.
…here

respawnPane() -- the path used when a session's pane died (crash, idle
respawn, or the user's own /exit) but the Codeman session object is
still tracked -- never had ompConfig wired through at all, in either
its options destructure or its inner buildSpawnCommand() call. This is
a gap in the original OMP patch, distinct from the resumeHistorySession
fix (which only covers a session that has been fully closed and shows
up as a history row): reselecting a tab whose CLI process just exited
goes through this path instead, and always launched a bare, contextless
`omp` no matter what.

Beyond the wiring, respawning a dead pane is semantically different
from creating a brand-new session: the conversation is still "this
session" to the user, so _buildRespawnPaneOptions() now defaults
ompConfig to continueSession:true unless the session already carries
an explicit resumeSessionId (which still wins in buildOmpCommand).

Verified live: told a session a secret, exited OMP so the pane died
(session and tmux both left alone), forced the exact dead-pane-respawn
path, and the new process replied with the secret -- confirming
`omp --continue` fired instead of a blank omp.
…ed-only sessions

Every non-claude "Resume" click creates a brand-new Codeman session
(there is no id to reattach to), but the old row was never cleaned up
-- click resume on the same conversation a few times and the session
list fills up with duplicate rows sharing one name. resumeHistorySession
now retires the row it resumed from after the new one starts.

That retirement needs DELETE to actually work on a row that was never
live in the first place (the normal case for anything showing up in
"Resume Conversation"): findSessionOrFail only checks the in-memory
live-session map, so DELETE 404s on a persisted-only entry today. Give
the route a fallback: when the id isn't live, look it up in persisted
state instead and demote/remove it there (respecting the existing
pinned-session protection). Verified live against a real persisted-only
row via the API, and added route-test coverage for both the success
and still-truly-unknown-id cases (which needed a demoteOrRemoveSession
mock the route harness didn't have).

Also includes an unrelated pre-existing prettier drift fix picked up
by npm run format (omp-cli-resolver.ts, antigravity/opencode import
wrapping in session-routes.ts).
Claude conversations survive "Kill Tmux & Claude" because Codeman reads
them back independently from ~/.claude/projects, not from its own
session bookkeeping. omp conversations had no equivalent: kill the
Codeman session and the conversation vanished from Past Sessions
entirely, even though omp itself never forgot it on disk.

Adds omp-transcript.ts, a scanner over omp's own
~/.omp/agent/sessions/<mangled-cwd>/<uuid>.jsonl files (the same shape
as Claude Code's own transcript scanner, but simpler -- these files are
small enough to read whole instead of doing head/tail windows). Each
file's own "session" header line carries the real cwd and session id
directly, so unlike Claude's mangled-directory-name decoding this
never has to guess. Wired into gatherUnifiedInputs() as a second
history source alongside the Claude scan, and HistoryInput/
mergeUnifiedSessions() now carry an optional `mode` so a non-claude
history-only row still gets a real mode badge.

Also fixes the ambiguity behind the "continue picks the wrong
conversation" report from this session's testing: omp mints its OWN
session uuid, unrelated to Codeman's, so a live/persisted row and its
own history-scan row would otherwise show up as two separate entries
for the same conversation the moment the id gets resolved. Reuses the
existing claudeSessionId alias field (mergeUnifiedSessions' fold-into-
owner mechanism) to point at the resolved omp id, threading it through
every place `_claudeSessionId` gets (re)computed -- the constructor,
_resolvedOmpRespawnConfig, and a new _maybeCaptureOmpSessionId() that
opportunistically resolves it the first time a brand-new omp session
(one that has never gone through a respawn) goes idle.

Also closes a THIRD instance of the "ompConfig never got wired in
here" gap this session kept finding: restoreMuxSessions() in server.ts
restores every sibling CLI's config from persisted state on boot except
omp's, so a boot-recovered omp session always lost its resolved resume
id and fell back to guessing again.

Verified live end-to-end: told a session a secret, killed it fully
(Kill Tmux equivalent, killMux=true -- the Codeman session AND its tmux
pane both gone), and the conversation still showed up in the unified
list as a history-sourced row with the real first prompt as its title
and an omp mode badge, keyed by omp's own session id.

Known remaining gap, not fixed here: the claudeSessionId alias doesn't
yet resolve reliably on every boot-recovery path for a session that
was never respawned while alive (e.g. a plain re-attach to a pane that
was never dead) -- worth a follow-up, but doesn't affect the two things
that matter most: the conversation surviving a kill, and continuation
correctness once an id has been resolved (which happens on the very
next respawn either way).
Two bugs compounded to break continuation pinning on every real OMP
case (only /tmp-based manual testing happened to work by coincidence):

1. startInteractive() had a second, unconditional claudeSessionId
   assignment after the mux branch that clobbered its correctly
   resolved value back to the session's own id on every mux path.

2. mangleOmpWorkingDir() assumed omp mirrors Claude Code's directory
   naming (home prefix kept), but omp actually strips $HOME first.
   findLatestOmpSessionId() was silently returning null for every
   case under ~/codeman-cases/, so resumeSessionId never resolved for
   any real case dir - only /tmp paths (outside $HOME) worked, which
   is every dir this feature was previously tested against.

Verified live: killed and relaunched the omp-verify server process
mid-session (plain reattach, pane stayed alive) and confirmed
claudeSessionId now resolves to the real omp transcript uuid instead
of the Codeman session's own id.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…validation

Follow-up from a full-branch review pass (Opus) of the omp-mode integration:

- Add pinning tests for resolveOmpConfigForCreate() (session-routes.ts),
  exported to make it testable: the exact "resume this OMP row from
  history" pipeline that mangleOmpWorkingDir's earlier bug lived in had
  zero coverage despite being the resolver module's whole reason to exist.
- Log a warning when findLatestOmpSessionId() finds nothing on disk and
  continuation silently degrades to omp's own ambiguous --continue,
  in both call sites (session create and respawn pinning) - previously
  silent, making the degradation invisible to anyone debugging it.
- Require an absolute cwd before trusting a session file's working
  directory in omp-transcript.ts's parser, so a corrupted/malformed
  session file can't point a downstream resume at a relative or empty
  path.
- Document (don't speculatively fix) an unverified symlinked-$HOME edge
  case in mangleOmpWorkingDir(): the review's suggested realpath() fix
  assumes omp itself resolves symlinks before mangling, which is
  unconfirmed - guessing wrong there would trade one silent mismatch
  for a different one.
- Incidental: fixed unrelated pre-existing prettier drift in
  session-routes.ts (antigravity/opencode dynamic import line-wrapping)
  that was blocking the pre-commit formatting gate on this file.

Confirmed as a non-issue: the model-name regex allowing "/" is
intentional (provider/model ids like "crof/glm-5.2" were used
successfully in live testing).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ials

OMP had full routing at the Docker layer (default pane command, schema) but
was never actually installed in docker/agent.Dockerfile, and had no
credential-isolation entry in docker-hosts.ts's CRED_STORES - a Docker-mode
OMP session would have failed with "omp: command not found", and even with
the binary present would have had no config/auth seeded, despite the README
already claiming OMP has "seamless auth, isolated credentials" in Docker.

- docker/agent.Dockerfile: install omp via its own installer (standalone
  binary, same shape as grok/antigravity - not on npm). Verified against a
  real --no-cache build: the installer actually targets ~/.local/bin, not
  ~/.omp/bin as the resolver's OMP_SEARCH_DIRS ordering would suggest -
  confirmed omp/18.0.8 installs and runs correctly inside the image.
- src/docker-hosts.ts: add a .omp/agent CRED_STORES entry. Unlike every
  sibling CLI in this family, sessions/ is SHARED (RW), not seeded: Codeman
  reads ~/.omp/agent/sessions/**/*.jsonl host-side for history recovery and
  --resume pinning (omp-transcript.ts, omp-session-resolver.ts), the same
  reason codex's sessions/ is shared rather than seeded. Seeding it instead
  would silently break the kill-survival feature for Docker cases. Only the
  small config files (config.yml/mcp.json/models.yml/settings.yml) are
  seeded; the SQLite caches and terminal-sessions/ stay container-local.
- test/docker-hosts.test.ts: pin the new CRED_STORES entry's behavior.

Found in passing (NOT fixed here, unrelated and pre-existing on master): the
agent image's DeepSeek (dsh) plugin-install step currently fails on a fresh
build ("pnpm not found on PATH"), confirmed via git diff against
origin/master that this line is untouched by this branch. Worth a separate
issue/PR.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
OMP was the one external CLI mode with no dedicated user-guide doc, unlike
opencode/pi/grok/deepseek which each have one. Covers install, auth (omp
owns its own entirely - no Codeman-side login flow or bypass switch),
what Codeman wires up (OmpConfig), the exact-id pinning mechanism and the
directory-mangling bug behind it, kill-survival via transcript scanning,
terminal behavior, Docker/remote-SSH cases, and known gaps (no idle hook,
mid-turn kill data loss, unverified symlinked-$HOME behavior).

Cross-referenced from README.md's Multi-CLI doc list and docs/docker-cases.md's
credential-seeding summary (which now also documents OMP's sessions/-is-shared
exception to the seed-everything pattern the other CLIs use).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…onversation

Found live 2026-08-27 by Tim: clicking Run OMP to start a brand-new session
in a case directory with prior omp history launched --resume <old-id>
instead of a clean `omp` invocation.

Root cause: Session._resolvedOmpRespawnConfig() resolves-and-pins the
newest on-disk omp conversation as a side effect on this._ompConfig. That
is correct when reattaching to an ALREADY-TRACKED mux session (a dead-pane
respawn, or a boot-recovery reattach - the constructor sets _muxSession
from persisted state before startInteractive() ever runs there), but it
ran unconditionally. startInteractive() computes
`respawnPaneOptions: this._buildRespawnPaneOptions()` eagerly in the same
object literal that builds `createSessionOptions.ompConfig: this._ompConfig`,
so for a genuinely brand-new session (no muxSession in its create config,
_muxSession still null) the resolve-and-pin side effect ran and poisoned
this._ompConfig before that field was even read.

Fix: gate the resolve-and-pin logic on `this._muxSession` already being
set. A fresh session has no muxSession yet and now passes through
untouched; a real reattach (muxSession present since construction) keeps
resolving and pinning exactly as before.

Verified live in production against the exact reported scenario (a fresh
omp session in a case dir with 8+ hours of prior omp history) - confirmed
both via the API (ompConfig stays empty, claudeSessionId equals the
session's own id) and visually in the GUI. Regression test constructs a
real Session + TmuxManager to exercise the actual private-method
interaction directly, since no existing test called startInteractive() at
all.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@timkjr

timkjr commented Aug 28, 2026

Copy link
Copy Markdown
Author

Pushed one more fix after opening this PR: 13a19f7. A fresh "Run OMP" click was silently resuming an old conversation instead of starting clean, in any working directory with prior OMP history — found live while testing, root-caused, fixed, and verified in production. Full details in the commit message; test suite still green (6319 passed).

@Ark0N

Ark0N commented Aug 28, 2026

Copy link
Copy Markdown
Owner

Thanks for this, and for the write-up. The core is in good shape: it follows the external-CLI pattern faithfully, the resolver reuses createCliExecutableResolver instead of hand-rolling a fifth copy, the Docker cred-store entry reasons correctly about shared-vs-seeded, and omp-transcript.ts reading the session header instead of reverse-engineering the mangled directory name is exactly right (dsh taught us that mangling changes form). CI is green and the tests you added cover what you built.

I read the diff against omp upstream too (the repo is can1357/oh-my-pi, 28k stars, MIT, releasing daily, so a backend for it is worth having). A few things need to change first, and one of them is a correctness bug.

1. The newest-mtime pin breaks with two omp tabs in one case

findLatestOmpSessionId() is "newest file in the directory, full stop", and the comment argues callers only invoke it where that is unambiguous. Two of them are not:

  • _resolvedOmpRespawnConfig() runs from the eager respawnPaneOptions: this._buildRespawnPaneOptions() in startInteractive(), and your own guard comment notes _muxSession is already set on a boot-recovery reattach. So on every server restart it resolves and pins for each recovered omp session, including ones whose pane is alive and whose file is not the newest. Two omp sessions in the same case (w1-foo, w2-foo, the normal fan-out shape here) both alias onto the same id, and a later respawn of one resumes the other's conversation, with two processes appending to one session file.
  • _maybeCaptureOmpSessionId() on first idle is the same race in a narrower window.

This is the rule CLAUDE.md already carries for dsh: pair by the transcript's own header plus a launch window, never by newest mtime, because newest-mtime handed a fresh worker its predecessor's answer in the same case dir. You already parse that header in omp-transcript.ts ({"type":"session","id","cwd"}), so the pieces are there: snapshot the directory at spawn, accept only a file whose header cwd matches and that appeared after this session launched, and skip an id a live sibling already pinned.

Related: the pin is a side effect of building respawn options, which is what bit you in 13a19f7. Resolving where the respawn is actually issued would remove that whole class of bug rather than guarding it.

2. The env-allowlist and clamp claims do not match omp's docs

docs/omp-integration.md says omp "has no documented vendor-key namespace of its own (its provider credentials live in ~/.omp config files, not environment variables)", and CLAUDE.md gains "the multi-user clamp has nothing to gate". Per omp's own docs/environment-variables.md, neither holds:

  • omp reads roughly 40 provider keys from the environment (ANTHROPIC_API_KEY, OPENAI_API_KEY, XAI_API_KEY, HF_TOKEN, ...). That is pi's 34-key problem in the same shape. Keeping them out of the allowlist is correct, the stated reason is not.
  • omp's own knobs are mostly PI_*, not OMP_*, and PI_ is already allowlisted globally because pi mode needs it. So an omp session today already accepts PI_CONFIG_DIR ("config root dirname under home, default .omp"), PI_CODING_AGENT_DIR, PI_CODING_AGENT_SESSION_DIR, OMP_PROFILE/PI_PROFILE, PI_SUBPROCESS_CMD ("overrides subagent spawn command") and PI_SHELL_PREFIX. The first three also move the tree omp-session-resolver.ts and omp-transcript.ts hardcode, so pinning and history quietly stop working, which makes resolveOmpHome()'s "no known env override exists (unlike DSH_HOME); revisit if omp adds one" wrong as of today.
  • The OMP_ prefix this PR adds brings in OMP_AUTH_BROKER_URL + OMP_AUTH_BROKER_TOKEN, which is where omp resolves credentials from. That is the shape DEEPSEEK_BASE_URL gets dropped for in clampEnvOverridesForOwner().

None of this matters in single-user mode. It matters for a non-granted owner in multi-user mode, which is why pi and dsh both have explicit clamp branches. Please make the decision explicit instead of "nothing to gate": either add the config-root and broker keys to the clamp for omp, or write down why they are acceptable. Worth stating in the doc as well that omp's documented default tools.approvalMode is yolo, so an omp pane auto-approves exec with no flag from us.

3. Three changes in one PR

Besides the omp backend there are two riders:

  • resumeHistorySession() now creates the session in the row's own mode and DELETEs the old row. That changes behavior for opencode, pi, grok, deepseek, codex, gemini and antigravity users, not just omp. Mode fidelity is a real improvement (resuming a codex row as claude was silly). But codex, gemini and antigravity are not in the modeConfigKey map, so for them Resume now starts a fresh session with no continuation and retires the row it came from, which is a strange pairing. Either give those three their continuation flag, or only retire the row when the new session actually continues something.
  • DELETE /api/sessions/:id gained the persisted-only fallback that the above needs, and reimplements the ownership check inline rather than going through findSessionOrFail. I would rather extend the helper, since that function is where ownership enforcement is supposed to live. The persisted branch also does not broadcast session_deleted, so other tabs keep the row until their next fetch.
  • The per-device "Hide CLI buttons" setting is a feature of its own. Its mode list is ['claude','opencode','codex','gemini','antigravity','pi','omp'] in both the load and the save path, so grok and deepseek cannot be hidden.

I would rather take these as two or three PRs. If they stay together, the changeset has to describe all of it: right now it covers only the backend and lists the siblings as "Claude Code, OpenCode, Codex, Gemini, and Antigravity" with Pi, Grok and DeepSeek missing. That text lands verbatim in the release notes.

4. Smaller, all concrete

  • https://github.com/can1357/omp 404s. It is can1357/oh-my-pi, in the PR body and in docs/omp-integration.md.
  • CLAUDE.md now links #external-cli-modes-...-deepseek-omp, but docs/architecture-invariants.md still carries the -deepseek heading and is not touched by this PR, so the link is dead and omp has no entry in the deep-detail doc every other CLI has.
  • The doc says the installer places the binary in ~/.omp/bin, but your own Dockerfile comment says that guess was wrong, and upstream's installer is INSTALL_DIR="${PI_INSTALL_DIR:-$HOME/.local/bin}". The resolver's search order should probably lead with ~/.local/bin.
  • omp is the ninth CLI backend and tenth SessionMode, not the eighth (docs and changeset).
  • The case 'omp' added to appendResumeFlag() looks unreachable: it keys off the top-level resumeSessionId, which is validated against ~/.claude/projects for every mode, while the omp pin lands in ompConfig.resumeSessionId. Docker panes are built from defaultDockerCommandForMode and never see ompConfig, so the Docker section overstates it: host-side history recovery works there, --resume pinning does not reach the in-container omp. Worth a live check.
  • scanOmpSessionsHistory() is fully synchronous (readdirSync plus readFileSync of whole files, up to 2MB each, up to 2000 of them) inside gatherUnifiedInputs(), which the home screen hits on every visit. The claude scanner beside it is async with 16KB/128KB head windows for exactly that reason.
  • Stray comment fragment landed in the quick-start docker branch: // configured project. Skipped for external CLIs (they use their own systems). right after if (docker && docker.hooksEnabled && mode === 'claude') {.
  • Two jammed CSS lines survive from the block-closing commit: color: #eef2ff; transform: translateY(-1px); and color: #eef2ff;}.
  • The doc's version example says omp/17.4.0 while you tested 18.0.8.

Things I would keep as they are: the version probe demanding omp/<semver> (right instinct for a three-letter binary name), the $HOME-stripping mangling comment with the "silently returns null" warning, the shared-vs-seeded reasoning in CRED_STORES, and the honest Known Gaps section including the mid-turn kill.

Also: thanks for filing the dsh plugin-install breakage separately as #352 instead of folding it in here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants