Skip to content

fix(pi-plugin): resolve the OMP host CLI via bin.omp — @oh-my-pi/pi-coding-agent declares no bin.pi - #413

Closed
Qiiks wants to merge 2 commits into
cortexkit:masterfrom
Qiiks:fix/omp-bin-key-resolution
Closed

fix(pi-plugin): resolve the OMP host CLI via bin.omp — @oh-my-pi/pi-coding-agent declares no bin.pi#413
Qiiks wants to merge 2 commits into
cortexkit:masterfrom
Qiiks:fix/omp-bin-key-resolution

Conversation

@Qiiks

@Qiiks Qiiks commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Problem

On OMP (oh-my-pi) hosts without a standalone pi install, every Magic Context subagent — historian, dreamer, recomp, wrapup, upgrade, sidekick — fails at spawn:

│ ⚠ subagent run failed (spawn_failed): Executable not found in $PATH: "pi"

This surfaced as /ctx-status reporting spawn_failed and the historian never running (context compaction silently dead) after the user removed Pi.

Root cause

resolvePiInvocation positively identifies the OMP host: it walks up from process.argv[1] and matches package names in PI_CODING_AGENT_PACKAGE_NAMES, which includes @oh-my-pi/pi-coding-agent (subagent-runner.ts:44-47). But resolvePiBin then only accepts bin.pi:

typeof (bin as Record<string, unknown>).pi === "string"
    ? (bin as Record<string, string>).pi
    : undefined;

OMP's package manifest declares bin: { omp: "dist/cli.js" } — there is no bin.pi — so resolution returns null for a package the resolver just positively identified. The fallback cascade then misses item by item (generic bun.exe runtime → skip; no bundled @earendil-works/pi-coding-agent peer → skip; no pi/pi.cmd on PATH → miss) and the final fallback spawns bare "pi".

Verified against a real OMP 18.1.4 install: @oh-my-pi/pi-coding-agent/package.json"bin": {"omp": "dist/cli.js"}.

Fix

resolvePiBin accepts the omp bin key after pi. Pi hosts (manifests with bin.pi) resolve identically; OMP hosts now resolve execPath + [realpath(dist/cli.js)] — the same "re-invoke the exact host CLI" strategy the resolver already prefers, and cross-platform-safe per the existing design notes (no shell, containment guard, realpath canonicalization all unchanged).

Verification

  • With a fixture mirroring OMP's real layout (@oh-my-pi/pi-coding-agent, bin: {omp: "dist/cli.js"}), the patched resolvePiInvocation returns {command: <bun>, prefixArgs: [<realpath>/dist/cli.js]} and the old code returned the bare-pi fallback.
  • The resolved invocation smoke-runs: bun <OMP>/dist/cli.js --versionomp/18.1.4, exit 0.
  • Full packages/pi-plugin suite (915 tests): failure set byte-identical before and after the change (23 pre-existing environment-specific failures on Windows — symlink-creation EPERM in test fixtures and host-PATH leakage — reproduced on pristine master and on the v0.41.1 tag; the change introduces no new failures).
  • tsc --noEmit clean.

Notes

  • The same one-line predicate exists in the bundled dist/ output; a patch release is sufficient for users (no manifest/config changes required).
  • Reproduction context: Windows 11, OMP 18.1.4, MC 0.41.2 (@cortexkit/pi-magic-context), Pi not installed.

View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.


Summary by cubic

Fixes Magic Context subagent spawn failures on OMP hosts without a standalone pi install. resolvePiBin now uses OMP’s bin.omp entry instead of falling back to bare pi; hosts declaring bin.pi behave unchanged.

  • Adds regression coverage for @oh-my-pi/pi-coding-agent, which declares only bin.omp.
  • Preserves realpath canonicalization, package-root containment, and fallback ordering; no manifest or config changes are required.

Written for commit 31b7002. Summary will update on new commits.

Review in cubic

Greptile Summary

The PR fixes hidden child-agent startup on OMP-only installations by resolving the host CLI from bin.omp while retaining bin.pi precedence and existing path-containment checks.

  • Extends package CLI resolution to recognize OMP’s declared executable.
  • Adds an OMP-specific package fixture and regression assertion for the resolved invocation.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
packages/pi-plugin/src/subagent-runner.ts Adds bin.omp as the fallback package-declared CLI after bin.pi, preserving existing canonicalization and containment validation.
packages/pi-plugin/src/subagent-runner.test.ts Adds an OMP-only package fixture and verifies that the resolver invokes its canonical dist/cli.js path through the current runtime.

Reviews (2): Last reviewed commit: "test(pi-plugin): cover the bin.omp OMP-h..." | Re-trigger Greptile

Context used:

…oding-agent declares no bin.pi

PiSubagentRunner's resolvePiInvocation positively identifies the running
host by package name (@oh-my-pi/pi-coding-agent is in
PI_CODING_AGENT_PACKAGE_NAMES) but then resolvePiBin only accepts
bin.pi. OMP's package declares bin: { omp: dist/cli.js }, so resolution
returns null, the fallback cascade misses (no bundled
@earendil-works/pi-coding-agent peer, no pi shim on PATH), and the
runner spawns bare 'pi' — 'Executable not found in $PATH: "pi"'
(spawn_failed) for every MC subagent (historian, dreamer, recomp,
wrapup, upgrade, sidekick) on hosts without Pi installed.

Accept the omp bin key after pi when resolving the host CLI. The
containment guard, realpath canonicalization, and fallback ordering
are unchanged; a Pi host with bin.pi still resolves identically.
Copilot AI lite review requested due to automatic review settings September 3, 2026 01:15
? (bin as Record<string, string>).pi
: undefined;
const binKeys = ["pi", "omp"];
let binEntry: string | undefined;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 OMP branch lacks regression coverage

The new bin.omp selection path has no committed fixture or assertion, so a later resolver change can restore the bare-pi fallback for OMP-only installations without the test suite detecting that all hidden child-agent workflows are broken.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The change is small, targeted, and aligns with the PR description; only minor formatting nits were identified.

Pull request overview

Updates Pi CLI resolution so Magic Context subagents can spawn correctly on OMP (oh-my-pi) hosts where the host package exposes its CLI via bin.omp instead of bin.pi, preventing fallback to a missing pi executable.

Changes:

  • Extend resolvePiBin to accept bin.omp (in addition to bin.pi) when selecting the host CLI entrypoint.
  • Update the function doc comment to describe the Pi vs OMP bin key difference and the containment/realpath guard behavior.
File summaries
File Description
packages/pi-plugin/src/subagent-runner.ts Adjusts package bin resolution to recognize OMP’s bin.omp, avoiding PATH-based pi fallback on OMP-only installs.
Review details

Suppressed comments (1)

packages/pi-plugin/src/subagent-runner.ts:183

  • There are two consecutive blank lines after if (!binEntry) return null; (introduced in this change). This creates a stray extra vertical gap and may violate formatting/lint rules if the repo enforces them.
	if (!binEntry) return null;


	const packageRoot = resolvePath(found.dir);
  • Files reviewed: 1/1 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +165 to +170
if (
typeof bin === "string" && key === "pi"
) {
binEntry = bin;
break;
}

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 1 file

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="packages/pi-plugin/src/subagent-runner.ts">

<violation number="1" location="packages/pi-plugin/src/subagent-runner.ts:162">
P2: Add a regression test with an OMP-only manifest (`bin.omp`) that asserts the resolver returns the host invocation, so this branch cannot regress to the bare `pi` fallback unnoticed.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

typeof (bin as Record<string, unknown>).pi === "string"
? (bin as Record<string, string>).pi
: undefined;
const binKeys = ["pi", "omp"];

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Add a regression test with an OMP-only manifest (bin.omp) that asserts the resolver returns the host invocation, so this branch cannot regress to the bare pi fallback unnoticed.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/pi-plugin/src/subagent-runner.ts, line 162:

<comment>Add a regression test with an OMP-only manifest (`bin.omp`) that asserts the resolver returns the host invocation, so this branch cannot regress to the bare `pi` fallback unnoticed.</comment>

<file context>
@@ -157,16 +159,27 @@ function resolvePiBin(
-					typeof (bin as Record<string, unknown>).pi === "string"
-				? (bin as Record<string, string>).pi
-				: undefined;
+	const binKeys = ["pi", "omp"];
+	let binEntry: string | undefined;
+	for (const key of binKeys) {
</file context>

Adds a regression test with an @oh-my-pi/pi-coding-agent fixture that
declares only bin.omp, asserting resolvePiInvocation returns the host
invocation (execPath + realpathed dist/cli.js) instead of falling
through to the bare 'pi' PATH fallback. Guards the OMP-only branch
against silent regression flagged by review.

Also flattens the bin-key loop's string-bin condition to match file
style and drops a stray double blank line.
@Qiiks

Qiiks commented Sep 3, 2026

Copy link
Copy Markdown
Contributor Author

Addressed all three review findings in 31b7002:

  1. Regression test (greptile + cubic, P2) — added "resolves the OMP host CLI via bin.omp", a fixture with @oh-my-pi/pi-coding-agent declaring only bin: {omp: "dist/cli.js"}, asserting resolvePiInvocation returns {command: execPath, prefixArgs: [realpath(dist/cli.js)]} instead of the bare-pi fallback. The fixture helper (writePiCliFixture) now takes a variant: "pi" | "omp" so both package layouts are covered by the same helper.
  2. Style (Copilot) — flattened the string-bin condition to a single line; restructured the object-bin branch into a single objectBin binding.
  3. Stray blank line (Copilot, suppressed comment) — removed the double blank after if (!binEntry) return null;.

Verification: new test passes (1 pass/0 fail with -t "OMP host CLI"), tsc --noEmit clean, and the full packages/pi-plugin suite failure set remains byte-identical to pristine master (the 23 pre-existing Windows environment failures noted in the PR description — symlink-EPERM fixtures and host PATH leakage, reproduced on the v0.41.1 tag).

ualtinok added a commit that referenced this pull request Sep 3, 2026
…pi/pi-coding-agent declares no bin.pi, so every subagent spawn on an OMP host without a standalone pi fell through to the bare-pi fallback since the #400 fix; with regression fixtures for the omp/pi/string/neither bin shapes

Co-authored-by: Alfonso <alfonso-magic-context@users.noreply.github.com>
ualtinok added a commit that referenced this pull request Sep 3, 2026
Co-authored-by: Alfonso <alfonso-magic-context@users.noreply.github.com>
@magic-alfonso

magic-alfonso Bot commented Sep 3, 2026

Copy link
Copy Markdown

Verified and landed. The registry manifest for @oh-my-pi/pi-coding-agent 18.1.4 is bin: { omp: "dist/cli.js" }, and our v0.41.1 launcher resolution accepted only bin.pi, so every subagent spawn on an OMP host without a standalone pi fell through to the bare-pi fallback — a regression we shipped, and your diagnosis was exact.

Your commit is on master with your authorship (cherry-picked as 3508f7bb, merged in 31deb406), followed by a commit adding the regression coverage greptile and cubic asked for: an OMP-only manifest fixture asserting the host invocation (proven red against the previous resolver — it returned the bare pi fallback with the script-detection miss), plus the bin.pi, string-bin, and neither-key cases. The two formatting nits are folded in.

This ships in v0.41.2 with a credit in the release notes. Closing the PR since GitHub cannot mark a cherry-picked merge as merged; the change is in.

@magic-alfonso magic-alfonso Bot closed this Sep 3, 2026
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