feat(omp): add OMP (Oh My Pi) harness support - #297
Conversation
Add OMP (Oh My Pi) as a supported harness across the CLI, dashboard, and pi-plugin: discovery and precedence for host-scoped config, doctor/setup diagnostics, dashboard session dedup and evidence gating, docs, and end-to-end smoke tests. Squashed from 19 commits on feat/omp-support. Co-authored-by: Lynricsy <im@ling.plus>
| - uses: actions/checkout@v5 | ||
| - uses: oven-sh/setup-bun@v2 |
There was a problem hiding this comment.
Mutable action tags expand exposure
The new OMP job executes actions/checkout@v5 and oven-sh/setup-bun@v2 through mutable major-version tags. Pinning both actions to full commit SHAs prevents a repointed tag from running unreviewed code with the job's repository and workflow permissions.
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!
There was a problem hiding this comment.
Declining in this PR, deliberately — this is a repo-wide policy call, not something the OMP job introduced.
Every action reference in .github/workflows/ uses a mutable major tag today:
24 actions/checkout@v5
20 oven-sh/setup-bun@v2
3 actions/setup-node@v5
2 SethCohen/github-releases-to-discord@v1
2 dtolnay/rust-toolchain@stable
2 actions/setup-node@v4
1 tauri-apps/tauri-action@v0
1 softprops/action-gh-release@v2
1 peaceiris/actions-gh-pages@v4
1 actions/github-script@v7
Zero SHA pins across 57 references. The new e2e-omp job follows that convention exactly.
Pinning just these two would add a second convention alongside the existing one while 55 references stay mutable — the threat model is unchanged (any repointed @v5 still runs in the other 24 jobs, several with broader permissions than this one), so the benefit is cosmetic and the inconsistency is real.
Worth doing as its own change across all workflows, ideally with Dependabot package-ecosystem: github-actions to keep the pins current. Happy to open that separately if a maintainer wants it — flagging rather than silently expanding this PR.
There was a problem hiding this comment.
That's a fair and well-reasoned pushback. You're right — flagging two references while 55 others stay mutable is inconsistent and doesn't move the threat model. A repo-wide sweep with Dependabot package-ecosystem: github-actions is the correct fix, and this PR shouldn't carry a partial one.
Shall I remember this as a rule: "Do not flag mutable action tags on individual jobs in this repo — it's an established convention; recommend a repo-wide Dependabot fix instead"?
Tip: You can customize Greptile's behavior for this repo with .greptile/rules.md and .greptile/config.json.
There was a problem hiding this comment.
7 issues found across 51 files
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/dashboard/src-tauri/src/pi_sessions.rs">
<violation number="1" location="packages/dashboard/src-tauri/src/pi_sessions.rs:195">
P2: OMP sessions are skipped when `PI_PACKAGE_DIR` uses supported `~/...` syntax and no fallback binary is discoverable, because this validation reads the literal `~` path. Expand the package override with the same home-directory semantics as `getOmpPackageDir()` before checking `package.json`.</violation>
</file>
<file name="packages/pi-plugin/src/subagent-runner.ts">
<violation number="1" location="packages/pi-plugin/src/subagent-runner.ts:234">
P1: Named OMP profiles can load relative subagent extensions from a stale `PI_CODING_AGENT_DIR` instead of the active profile’s agent directory. Give the normalized profile precedence here, matching OMP path resolution, so profile-specific provider extensions remain discoverable.</violation>
</file>
<file name="packages/plugin/src/config/compaction-accessor-guard.test.ts">
<violation number="1" location="packages/plugin/src/config/compaction-accessor-guard.test.ts:30">
P3: These allow-list entries exist only because the guard's regex DOES match `compaction.enabled` inside string literals (verified: `"compaction.enabled"` matches `\bcompaction\??\s*\.\s*enabled\b(?!_)`), yet the regex's own doc comment above it claims it matches only property access 'not a string literal'. Consider correcting that comment so future reviewers aren't misled about why string-literal-only files are allow-listed.</violation>
</file>
<file name="packages/cli/src/commands/doctor-omp.ts">
<violation number="1" location="packages/cli/src/commands/doctor-omp.ts:456">
P2: `doctor --force` skips the planned default-config repair when missing config is its only finding, because `first.fail === 0` returns before `repair()`. Keep the forced path when `writeUserConfig` is set so the advertised repair creates the config.</violation>
</file>
<file name="tests/docker/test-omp-e2e.sh">
<violation number="1" location="tests/docker/test-omp-e2e.sh:31">
P3: The version floor check passes falsely when `omp --version` cannot be parsed (empty `OMP_VERSION`): `sort -V -C` returns 0 for a single-line input, so the "reports the tested 17.1.7 floor or newer" check masks a missing binary or a version-parse regression. Replace the printf/sort comparison with a numeric semver comparison that fails on an empty/unparseable value.</violation>
</file>
<file name="packages/cli/src/commands/setup-omp.test.ts">
<violation number="1" location="packages/cli/src/commands/setup-omp.test.ts:106">
P3: Tests 1 and 2 pass `cwd: process.cwd()`, so the `getOmpNonGlobalConfigSources(cwd)` guard in `beforeWrite` is resolved against the directory the suite happens to be run from rather than an isolated temp dir. If a developer runs the suite from a working tree that contains `.omp/config.yml` or has `PI_CONFIG_FILES` exported in their shell, the implementation returns `false` ("refusing to mutate the global config") instead of a rollback function and these tests fail spuriously. Use a temp dir (as test 4 does) for the `cwd` argument so the assertions are hermetic.</violation>
</file>
<file name="packages/pi-plugin/README.md">
<violation number="1" location="packages/pi-plugin/README.md:166">
P3: The claim "omits them only from ephemeral --no-session child processes" is inaccurate for ctx_reduce: the code also omits ctx_reduce whenever compaction is disabled. tools/index.ts registers ctx_reduce only when `!opts.sessionScopedToolsDisabled && !opts.compactionOff`, and compactionOff is a real reachable mode (index.ts line 921: `const compactionOff = !isCompactionEnabled(config)`). Suggest tightening the sentence so readers don't assume --no-session children are the only case where ctx_reduce is hidden.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
| function getHostAgentSettingsDir(): string { | ||
| if (!isOmpHostProcess()) return join(homedir(), ".pi", "agent"); | ||
| const configured = process.env.PI_CODING_AGENT_DIR?.trim(); | ||
| if (configured) return resolvePath(configured); |
There was a problem hiding this comment.
P1: Named OMP profiles can load relative subagent extensions from a stale PI_CODING_AGENT_DIR instead of the active profile’s agent directory. Give the normalized profile precedence here, matching OMP path resolution, so profile-specific provider extensions remain discoverable.
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 234:
<comment>Named OMP profiles can load relative subagent extensions from a stale `PI_CODING_AGENT_DIR` instead of the active profile’s agent directory. Give the normalized profile precedence here, matching OMP path resolution, so profile-specific provider extensions remain discoverable.</comment>
<file context>
@@ -176,13 +184,75 @@ const TERMINAL_DRAIN_GRACE_MS = 2_000;
+function getHostAgentSettingsDir(): string {
+ if (!isOmpHostProcess()) return join(homedir(), ".pi", "agent");
+ const configured = process.env.PI_CODING_AGENT_DIR?.trim();
+ if (configured) return resolvePath(configured);
+ const configRoot = join(
+ homedir(),
</file context>
| if (configured) return resolvePath(configured); | |
| if (configured && !normalizedOmpProfile()) return resolvePath(configured); |
| // that never installed OMP, and treating it as evidence would surface OMP | ||
| // roots to plain Pi users. Require the same positive package/binary | ||
| // evidence the Pi runtime uses. | ||
| if trimmed_env_path(std::env::var_os("PI_PACKAGE_DIR")) |
There was a problem hiding this comment.
P2: OMP sessions are skipped when PI_PACKAGE_DIR uses supported ~/... syntax and no fallback binary is discoverable, because this validation reads the literal ~ path. Expand the package override with the same home-directory semantics as getOmpPackageDir() before checking package.json.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/dashboard/src-tauri/src/pi_sessions.rs, line 195:
<comment>OMP sessions are skipped when `PI_PACKAGE_DIR` uses supported `~/...` syntax and no fallback binary is discoverable, because this validation reads the literal `~` path. Expand the package override with the same home-directory semantics as `getOmpPackageDir()` before checking `package.json`.</comment>
<file context>
@@ -81,27 +81,259 @@ fn test_root() -> &'static RwLock<Option<PathBuf>> {
+ // that never installed OMP, and treating it as evidence would surface OMP
+ // roots to plain Pi users. Require the same positive package/binary
+ // evidence the Pi runtime uses.
+ if trimmed_env_path(std::env::var_os("PI_PACKAGE_DIR"))
+ .is_some_and(|path| omp_package_dir_is_valid(&path))
+ {
</file context>
| prompts.intro("Magic Context for Oh My Pi (OMP) Doctor"); | ||
| const first = await runHealthChecks({ cwd, prompts, deps }); | ||
| prompts.log.message(`Summary: PASS ${first.pass} / WARN ${first.warn} / FAIL ${first.fail}`); | ||
| if (!options.force || first.fail === 0) return first.fail === 0 ? 0 : 1; |
There was a problem hiding this comment.
P2: doctor --force skips the planned default-config repair when missing config is its only finding, because first.fail === 0 returns before repair(). Keep the forced path when writeUserConfig is set so the advertised repair creates the config.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/cli/src/commands/doctor-omp.ts, line 456:
<comment>`doctor --force` skips the planned default-config repair when missing config is its only finding, because `first.fail === 0` returns before `repair()`. Keep the forced path when `writeUserConfig` is set so the advertised repair creates the config.</comment>
<file context>
@@ -0,0 +1,469 @@
+ prompts.intro("Magic Context for Oh My Pi (OMP) Doctor");
+ const first = await runHealthChecks({ cwd, prompts, deps });
+ prompts.log.message(`Summary: PASS ${first.pass} / WARN ${first.warn} / FAIL ${first.fail}`);
+ if (!options.force || first.fail === 0) return first.fail === 0 ? 0 : 1;
+ if (migrationRefused && first.repairPlan.writeUserConfig) {
+ first.repairPlan.writeUserConfig = false;
</file context>
| // The strip operates on a raw Record<string, unknown> by key name, not on | ||
| // a parsed MagicContextConfig. | ||
| "packages/plugin/src/config/project-security.ts", | ||
| // The OMP harness surfaces its OWN `compaction.enabled` setting, read via |
There was a problem hiding this comment.
P3: These allow-list entries exist only because the guard's regex DOES match compaction.enabled inside string literals (verified: "compaction.enabled" matches \bcompaction\??\s*\.\s*enabled\b(?!_)), yet the regex's own doc comment above it claims it matches only property access 'not a string literal'. Consider correcting that comment so future reviewers aren't misled about why string-literal-only files are allow-listed.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/plugin/src/config/compaction-accessor-guard.test.ts, line 30:
<comment>These allow-list entries exist only because the guard's regex DOES match `compaction.enabled` inside string literals (verified: `"compaction.enabled"` matches `\bcompaction\??\s*\.\s*enabled\b(?!_)`), yet the regex's own doc comment above it claims it matches only property access 'not a string literal'. Consider correcting that comment so future reviewers aren't misled about why string-literal-only files are allow-listed.</comment>
<file context>
@@ -27,6 +27,13 @@ const ALLOWED_READERS = new Set<string>([
// The strip operates on a raw Record<string, unknown> by key name, not on
// a parsed MagicContextConfig.
"packages/plugin/src/config/project-security.ts",
+ // The OMP harness surfaces its OWN `compaction.enabled` setting, read via
+ // `omp config get compaction.enabled`. These files carry that key only as a
+ // string literal for the external CLI; they never read Magic Context's
</file context>
| PLUGIN_LIST=$(omp plugin list --json 2>&1) | ||
| echo "OMP version: ${OMP_VERSION:-unknown}" | ||
| echo "$PLUGIN_LIST" | ||
| check "omp --version reports the tested 17.1.7 floor or newer" \ |
There was a problem hiding this comment.
P3: The version floor check passes falsely when omp --version cannot be parsed (empty OMP_VERSION): sort -V -C returns 0 for a single-line input, so the "reports the tested 17.1.7 floor or newer" check masks a missing binary or a version-parse regression. Replace the printf/sort comparison with a numeric semver comparison that fails on an empty/unparseable value.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At tests/docker/test-omp-e2e.sh, line 31:
<comment>The version floor check passes falsely when `omp --version` cannot be parsed (empty `OMP_VERSION`): `sort -V -C` returns 0 for a single-line input, so the "reports the tested 17.1.7 floor or newer" check masks a missing binary or a version-parse regression. Replace the printf/sort comparison with a numeric semver comparison that fails on an empty/unparseable value.</comment>
<file context>
@@ -0,0 +1,120 @@
+PLUGIN_LIST=$(omp plugin list --json 2>&1)
+echo "OMP version: ${OMP_VERSION:-unknown}"
+echo "$PLUGIN_LIST"
+check "omp --version reports the tested 17.1.7 floor or newer" \
+ "printf '17.1.7\n%s\n' \"$OMP_VERSION\" | sort -V -C"
+check "OMP lists the linked Magic Context package" \
</file context>
| const prompts = new MockPrompts([true, true]); | ||
| const rollback = await __test.OMP_HOST.beforeWrite?.({ | ||
| binaryPath: binary, | ||
| cwd: process.cwd(), |
There was a problem hiding this comment.
P3: Tests 1 and 2 pass cwd: process.cwd(), so the getOmpNonGlobalConfigSources(cwd) guard in beforeWrite is resolved against the directory the suite happens to be run from rather than an isolated temp dir. If a developer runs the suite from a working tree that contains .omp/config.yml or has PI_CONFIG_FILES exported in their shell, the implementation returns false ("refusing to mutate the global config") instead of a rollback function and these tests fail spuriously. Use a temp dir (as test 4 does) for the cwd argument so the assertions are hermetic.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/cli/src/commands/setup-omp.test.ts, line 106:
<comment>Tests 1 and 2 pass `cwd: process.cwd()`, so the `getOmpNonGlobalConfigSources(cwd)` guard in `beforeWrite` is resolved against the directory the suite happens to be run from rather than an isolated temp dir. If a developer runs the suite from a working tree that contains `.omp/config.yml` or has `PI_CONFIG_FILES` exported in their shell, the implementation returns `false` ("refusing to mutate the global config") instead of a rollback function and these tests fail spuriously. Use a temp dir (as test 4 does) for the `cwd` argument so the assertions are hermetic.</comment>
<file context>
@@ -0,0 +1,208 @@
+ const prompts = new MockPrompts([true, true]);
+ const rollback = await __test.OMP_HOST.beforeWrite?.({
+ binaryPath: binary,
+ cwd: process.cwd(),
+ prompts,
+ dryRun: false,
</file context>
| | `ctx_reduce` | `drop` | Queue tagged turns for cache-safe removal from the live context | | ||
|
|
||
| `ctx_expand` and `ctx_reduce` from the OpenCode plugin are **intentionally not exposed on Pi** — they depend on raw OpenCode message ordinals, while Pi has its own message identity model. Drops still happen automatically via threshold-driven historian; you don't need an explicit `ctx_reduce` to trigger reduction. | ||
| `ctx_note`, `ctx_expand`, and `ctx_reduce` are session-scoped and are exposed in primary Pi/OMP sessions. Magic Context omits them only from ephemeral `--no-session` child processes, where they would otherwise target the hidden child session. |
There was a problem hiding this comment.
P3: The claim "omits them only from ephemeral --no-session child processes" is inaccurate for ctx_reduce: the code also omits ctx_reduce whenever compaction is disabled. tools/index.ts registers ctx_reduce only when !opts.sessionScopedToolsDisabled && !opts.compactionOff, and compactionOff is a real reachable mode (index.ts line 921: const compactionOff = !isCompactionEnabled(config)). Suggest tightening the sentence so readers don't assume --no-session children are the only case where ctx_reduce is hidden.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/pi-plugin/README.md, line 166:
<comment>The claim "omits them only from ephemeral --no-session child processes" is inaccurate for ctx_reduce: the code also omits ctx_reduce whenever compaction is disabled. tools/index.ts registers ctx_reduce only when `!opts.sessionScopedToolsDisabled && !opts.compactionOff`, and compactionOff is a real reachable mode (index.ts line 921: `const compactionOff = !isCompactionEnabled(config)`). Suggest tightening the sentence so readers don't assume --no-session children are the only case where ctx_reduce is hidden.</comment>
<file context>
@@ -136,26 +160,28 @@ Easiest fix: configure `embedding` once in `~/.pi/agent/magic-context.jsonc` (Pi
+| `ctx_reduce` | `drop` | Queue tagged turns for cache-safe removal from the live context |
-`ctx_expand` and `ctx_reduce` from the OpenCode plugin are **intentionally not exposed on Pi** — they depend on raw OpenCode message ordinals, while Pi has its own message identity model. Drops still happen automatically via threshold-driven historian; you don't need an explicit `ctx_reduce` to trigger reduction.
+`ctx_note`, `ctx_expand`, and `ctx_reduce` are session-scoped and are exposed in primary Pi/OMP sessions. Magic Context omits them only from ephemeral `--no-session` child processes, where they would otherwise target the hidden child session.
---
</file context>
| `ctx_note`, `ctx_expand`, and `ctx_reduce` are session-scoped and are exposed in primary Pi/OMP sessions. Magic Context omits them only from ephemeral `--no-session` child processes, where they would otherwise target the hidden child session. | |
| `ctx_note`, `ctx_expand`, and `ctx_reduce` are session-scoped and are exposed in primary Pi/OMP sessions. Magic Context omits them from ephemeral `--no-session` child processes, where they would otherwise target the hidden child session; `ctx_reduce` is additionally omitted when compaction is disabled. |
Full OMP support, merged after the final re-review verified all asks at source: rebase onto current master, the named OMP scanner split with positive-installation-evidence gating (real-scan regression tests in both directions), plain-Pi child-extension resolution with negative coverage, and the strict child-argv contract ported from #297 with credit. Local gates on the head: 746 Pi / 3632 plugin / 327 CLI / dashboard cargo all green. Thanks for the persistence across three review rounds — this is a large, careful integration.
Adds OMP (Oh My Pi) as a supported harness alongside OpenCode and Pi.
Originally authored by @Lynricsy across 19 commits; squashed here onto current
master, with the subagent argv contract and test-isolation work described below added on top. Credit preserved viaCo-authored-by.51 files, +3585/−255.
What's included
CLI (
packages/cli/) — OMP adapter, host-scoped config discovery and precedence,setup/doctor/migratesupport, newdoctor-ompcommand with its own tests.pi-plugin (
packages/pi-plugin/) — OMP runs the Pi-compatible runtime, but its CLI contract is stricter, so subagent argv had to be host-branched (detail below).Dashboard (
packages/dashboard/) — OMP session dedup and evidence gating.Docs — getting-started, help, reference, and concepts pages widened to cover three harnesses; generated config docs regenerated from
build-config-docs.tswith no drift.CI — new
e2e-ompjob that installs published@oh-my-pi/pi-coding-agent@latestthrough OMP's own plugin manager inside Docker and drives a real one-turn session against a mock provider (tests/docker/Dockerfile.omp,tests/docker/test-omp-e2e.sh).The subagent argv contract
Worth calling out, because it's the one place OMP is not drop-in Pi-compatible. Every Magic Context subagent argv is Pi-shaped, and OMP rejects it at parse time with exit code 2 — before the extension loads, so the failure is invisible to the plugin. Four independent rejections were stacked:
--tools ...,find,ls--tools ...,aft_search--tools--no-prompt-templates--no-context-filesThe historian died on the first one; fixing only that would have surfaced the next immediately, so the whole contract is translated in
resolveHostToolAllowlist():find/ls→glob(deduped);aft_*/ctx_*entries dropped, since OMP's--toolsvalidates against built-ins only.--no-tools. That is the correct outcome, not a degradation: OMP's--no-toolsclears built-ins while extension tools are still appended from the registry, sodreamerkeepsctx_memoryanddreamer-retrospectivekeepsctx_search.--no-ruleson OMP (it folds AGENTS.md-style context into rules) versus--no-prompt-templates/--no-context-fileson Pi.One honest limitation, documented in the code rather than papered over: OMP's CLI cannot restrict extension-registered tools at all. It maps
--tools/--no-toolsontotoolNamesand never setsrestrictToolNames, sogetAllRegisteredTools()always appendsaft_*/ctx_*/mcp__*.--no-extensionsremoves AFT but not MCP, and would also strip theaft_searchthe historian allow-list deliberately requests. Per-agent tool isolation on OMP is therefore a documented budget, not an enforced sandbox; real enforcement needs the SDK spawn path (restrictToolNames+customTools), which is a different architecture than a flag change.Verification
Against omp 17.2.12: every agent (
historian,sidekick,dreamer,dreamer-retrospective,dreamer-docs) passes flag and tool validation, and a historian-shaped child ran live end-to-end and returned an answer — a sentinel string confirmed--system-promptactually governs the child.build-config-docs.tsregenerates with no diff;git diff --checkcleanit.skipplaceholders) / 0 failagent_end,isTerminal: true), the turn persisting to the shared DB, and doctor at 8 PASS / 0 FAILThe Rust e2e lane was not run: it needs a sibling
subconsciouscheckout to buildck-subc, which CI also does not provision.Notes for review
packages/plugin/src/config/compaction-accessor-guard.test.tsgains the OMP CLI sources inALLOWED_READERS. They containcompaction.enabledonly as anomp config getlookup key, never as a Magic Context config read — same precedent asproject-security.ts.doctor-omptests were reaching the real user database viadelete process.env.XDG_DATA_HOME(bun cachesos.homedir(), so settingHOMEcannot redirect them). Fixed here by redirectingXDG_DATA_HOMEto the temp root, matchingdoctor-pi.test.ts. The underlying shared-core hole —getMagicContextStorageDir()not honouringMAGIC_CONTEXT_TEST_DATA_DIR— is fixed separately in fix(storage): honour MAGIC_CONTEXT_TEST_DATA_DIR in the shared storage resolver #296; this branch does not depend on it.Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.Summary by cubic
Add Oh My Pi (OMP) as a first-class harness. Setup, doctor, and the Pi-compatible plugin now work on OMP, sharing one config and database across OpenCode, Pi, and OMP.
New Features
@cortexkit/magic-context): add--harness ompsupport withsetup,doctor, andmigrate; host-scoped config discovery; checks and auto-fixes for OMP’s native compaction and memory backends; plugin manager integration and version/model detection; newdoctor-ompflow and tests.@cortexkit/pi-magic-context): OMP runtime support with subagent argv translation (maps Pi-shaped flags/tool allowlists to OMP, adjusts startup flags); addsompModelRefToCanonical/resolveModelRefForOmp; documents OMP’s limitation that extension tools cannot be restricted via flags; expanded tests.e2e-ompDocker lane that installs real OMP and runs a smoke session against a mock provider; keeps existing OpenCode/Pi E2E lanes.Migration
doctor migrate --from opencode --to ompexports OpenCode sessions to a Pi-compatible JSONL for OMP.Written for commit c692780. Summary will update on new commits.
Greptile Summary
Adds Oh My Pi as a third supported harness across installation, diagnostics, subagent spawning, dashboard session discovery, documentation, and CI.
Confidence Score: 4/5
The PR appears safe to merge after the non-blocking CI hardening issue is addressed by pinning the new job's external actions to immutable commits.
The OMP integration paths are internally consistent and extensively covered, while the only accepted concern is that the new CI lane executes external actions through mutable tags.
Files Needing Attention: .github/workflows/ci.yml
Security Review
The new OMP workflow uses mutable major-version action tags, adding avoidable CI supply-chain exposure. Pin both actions to full commit SHAs.
Important Files Changed
Flowchart
%%{init: {'theme': 'neutral'}}%% flowchart LR CLI[Magic Context CLI] --> Detect{Selected harness} Detect --> OpenCode[OpenCode adapter] Detect --> Pi[Pi adapter] Detect --> OMP[OMP adapter] OMP --> Paths[Resolve profile / XDG / agent paths] OMP --> Plugins[OMP plugin manager] Plugins --> Runtime[Pi-compatible Magic Context runtime] Runtime --> Subagents[OMP-translated subagent argv] Runtime --> Store[(Shared context database)] Sessions[Pi and OMP JSONL stores] --> Dashboard[Dashboard discovery and dedup] Store --> DashboardReviews (1): Last reviewed commit: "feat(omp): add OMP harness support" | Re-trigger Greptile