Skip to content

Commit 455fa5f

Browse files
authored
feat: add full Oh My Pi (OMP) support (#256)
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.
1 parent 1755c95 commit 455fa5f

53 files changed

Lines changed: 3915 additions & 273 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.github/workflows/ci.yml‎

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,39 @@ jobs:
215215
- name: Run E2E
216216
run: docker run --rm --platform linux/amd64 mc-e2e-pi
217217

218+
e2e-omp:
219+
name: E2E (Oh My Pi, real Docker)
220+
runs-on: ubuntu-latest
221+
needs: [check-pi-plugin]
222+
timeout-minutes: 25
223+
steps:
224+
- uses: actions/checkout@v5
225+
- uses: oven-sh/setup-bun@v2
226+
with:
227+
bun-version: latest
228+
229+
- name: Install workspace deps
230+
run: bun install --frozen-lockfile
231+
232+
- name: Build Pi-compatible plugin and OMP argv renderer
233+
run: |
234+
bun run --cwd packages/pi-plugin build
235+
bun run --cwd packages/pi-plugin build:e2e-argv
236+
237+
- name: Build CLI
238+
run: bun run --cwd packages/cli build
239+
240+
- name: Build real OMP E2E image
241+
run: |
242+
docker build \
243+
--platform linux/amd64 \
244+
-f tests/docker/Dockerfile.omp \
245+
-t mc-e2e-omp \
246+
.
247+
248+
- name: Run real OMP install and session smoke
249+
run: docker run --rm --platform linux/amd64 mc-e2e-omp
250+
218251
e2e-host-opencode:
219252
name: E2E (OpenCode, host behavior)
220253
runs-on: ubuntu-latest

‎.gitignore‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,3 +112,6 @@ packages/plugin/scripts/experiments/issue-195-repro.mjs
112112
packages/plugin/scripts/experiments/visual-memory/render-trimmed-memories.ts
113113
packages/plugin/scripts/experiments/visual-memory/trials/REPORT.md
114114
packages/plugin/scripts/mural-test-output/
115+
AgentLogs/
116+
.agent-logs/
117+
tests/docker/.generated/

‎CONFIGURATION.md‎

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
# Configuration Reference
22

3-
All settings are flat top-level keys in `magic-context.jsonc`. The schema is **shared between the OpenCode plugin and the Pi extension** — every setting documented here applies to both unless explicitly marked **Pi only** or **OpenCode only**.
3+
All settings are flat top-level keys in `magic-context.jsonc`. The schema is shared by the OpenCode plugin and the Pi-compatible extension used on both Pi and OMP.
44

55
### Configuration locations
66

7-
Magic Context reads config from **one shared CortexKit location**, the same for both harnesses (project overrides user):
7+
Magic Context reads config from one shared CortexKit location across OpenCode, Pi, and OMP (project overrides user):
88

99
| Path | Scope |
1010
|---|---|
@@ -19,12 +19,12 @@ Project config always merges on top of user config. The unified setup wizard (`n
1919

2020
Both plugins write to the same SQLite database at `~/.local/share/cortexkit/magic-context/context.db`. Tables are scoped by:
2121

22-
- `harness` column (`'opencode'` or `'pi'`) for **session-scoped** data — tags, compartments, session facts, notes
22+
- `harness` column (`'opencode'` or `'pi'`) for **session-scoped** data — OMP intentionally uses the Pi-compatible `'pi'` discriminator
2323
- `project_path` (resolved git root) for **project-scoped** data — memories, embeddings, dreamer runs, key-file pins, smart notes
2424

25-
So memories you write in OpenCode appear in Pi sessions for the same project (and vice versa), while per-session compartments and tags stay correctly attributed to their originating harness.
25+
Project memories therefore flow across OpenCode, Pi, and OMP, while per-session state remains scoped to the OpenCode or Pi-compatible runtime.
2626

27-
For semantic search to work cross-harness, both plugins resolve embedding config per project identity on every retrieval path. OpenCode and Pi can run in the same process against different projects without sharing one process-global embedding provider. For one project, keep the effective `embedding` block consistent across the OpenCode and Pi config stack; Magic Context tags stored vectors with the resolved model identity and clears stale vectors for that project when the provider/model changes.
27+
For semantic search to work cross-harness, every host resolves embedding config per project identity on each retrieval path. Keep the effective `embedding` block consistent across OpenCode, Pi, and OMP for the same project.
2828

2929
### Trusted-group shared storage
3030

@@ -92,19 +92,22 @@ A guidance override must be a readable complete `## Magic Context` section with
9292
If something isn't working, run the unified doctor to auto-detect installed harnesses and fix common issues:
9393

9494
```bash
95-
# Auto-detect installed harnesses; if both, picks the first or asks
95+
# Auto-detect installed harnesses; if multiple are present, pick or prompt
9696
npx @cortexkit/magic-context@latest doctor
9797

9898
# Target a specific harness explicitly
9999
npx @cortexkit/magic-context@latest doctor --harness opencode
100100
npx @cortexkit/magic-context@latest doctor --harness pi
101+
npx @cortexkit/magic-context@latest doctor --harness omp
101102
```
102103

103104
The OpenCode doctor checks: installation, CLI version vs npm latest, plugin registration (preserves local dev paths), `magic-context.jsonc` parses + loads through the schema, conflicts (compaction, DCP, OMO hooks), TUI sidebar configuration, embedding endpoint, shared-DB existence + `PRAGMA integrity_check` + row counts, plugin npm cache, and historian debug dumps.
104105

105106
The Pi doctor checks: Pi binary + version (requires `>= 0.71.0`), CLI version vs npm latest, settings registration, config validity, embedding endpoint reachability, shared-DB integrity, stale Pi extension caches, and historian debug dumps.
106107

107-
Both report `PASS X / WARN Y / FAIL Z` summary counts. Use `--force` to auto-fix what doctor can (clears stale plugin cache, repairs config) and `--issue` to produce a sanitized issue report.
108+
The OMP doctor checks the OMP version, effective plugin enable state, `PI_CODING_AGENT_DIR`/profile/XDG path agreement, native compaction and automatic-memory conflicts, config validity, and shared DB integrity. `--force` installs/enables the plugin and repairs conflicting OMP settings.
109+
110+
All doctors report `PASS X / WARN Y / FAIL Z` summary counts. Use `--force` for safe repairs and `--issue` to produce a sanitized issue report.
108111

109112
### SQLite backend
110113

‎README.md‎

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ Magic Context gives them one. It is the **hippocampus** for coding agents, the p
6969

7070
- **Capture.** As the historian compresses your history, it lifts the durable knowledge (decisions, constraints, conventions) into project memory. You get a memory system for free, from work you are already doing.
7171
- **Consolidate.** Overnight, dreamer agents do what sleep does for you: verify memories against the codebase, curate duplicates and stale entries, and promote what recurs.
72-
- **Recall.** The right memories surface automatically every turn, and the agent can search across memories, past conversations, and git history on demand. Across sessions, and across OpenCode and Pi.
72+
- **Recall.** The right memories surface automatically every turn, and the agent can search across memories, past conversations, and git history on demand. Across sessions, and across OpenCode, Pi, and OMP.
7373

7474
Two promises: your agent **never stops to manage its context** (no compaction pauses, no broken flow) and it **never forgets**.
7575

@@ -96,7 +96,7 @@ irm https://raw.githubusercontent.com/cortexkit/magic-context/master/scripts/ins
9696
npx @cortexkit/magic-context@latest setup
9797
```
9898

99-
The wizard auto-detects which harnesses you have (OpenCode, Pi, or both), adds the plugin, disables built-in compaction, helps you pick models for the historian, dreamer, and sidekick, and resolves conflicts with other context-management plugins. Target a specific harness with `--harness opencode` or `--harness pi`.
99+
The wizard auto-detects which harnesses you have (OpenCode, Pi, OMP, or any combination), adds the plugin, disables built-in compaction, helps you pick models for the historian, dreamer, and sidekick, and resolves conflicts with other context-management plugins. Target one with `--harness opencode`, `--harness pi`, or `--harness omp`.
100100

101101
> **Why disable built-in compaction?** Magic Context manages context itself. The host's compaction would interfere with its cache-aware deferred operations and double-compress.
102102
@@ -128,9 +128,11 @@ User-level config is `~/.config/cortexkit/magic-context.jsonc` on macOS/Linux an
128128

129129
**Pi:** `npx @cortexkit/magic-context@latest setup --harness pi` (requires Pi `>= 0.74.0`). The Pi extension shares the same database as OpenCode; project memories and embeddings pool across both.
130130

131-
**Troubleshooting:** `npx @cortexkit/magic-context@latest doctor` auto-detects your harnesses, checks for conflicts (compaction, OMO hooks, DCP), verifies the plugin and TUI sidebar, runs an integrity check on the database, and fixes what it can. Add `--issue` to file a ready-to-submit bug report.
131+
**Oh My Pi (OMP):** `npx @cortexkit/magic-context@latest setup --harness omp` (requires OMP `>= 17.1.7`). Setup installs the Pi-compatible extension through `omp plugin`, disables OMP native compaction and automatic memory, and honors OMP profiles, `PI_CODING_AGENT_DIR`, and initialized XDG layouts.
132132

133-
Works the same on a brand-new or a long-running project: install, restart the harness, and Magic Context captures context from that point forward. It does not backfill OpenCode or Pi sessions from before it was installed.
133+
**Troubleshooting:** `npx @cortexkit/magic-context@latest doctor` auto-detects your harnesses, checks host-specific conflicts, verifies plugin registration and database integrity, and fixes what it can. Add `--issue` to file a ready-to-submit bug report.
134+
135+
Works the same on a brand-new or a long-running project: install, restart the harness, and Magic Context captures context from that point forward. It does not backfill OpenCode, Pi, or OMP sessions from before it was installed.
134136

135137
<details>
136138
<summary><strong>Compatibility with other context-management plugins</strong></summary>
@@ -140,6 +142,8 @@ Works the same on a brand-new or a long-running project: install, restart the ha
140142
Magic Context owns context management end to end, so it **disables itself** if another plugin is already doing that job. Running two context managers at once would double-compress your history and thrash the prompt cache. On startup it checks for the following; setup and `doctor` help you resolve each, and until they're resolved Magic Context stays off (fail-safe) and tells you why:
141143

142144
- **OpenCode built-in compaction** (`compaction.auto` / `compaction.prune`) — Magic Context replaces it. Setup turns it off.
145+
- **OMP native compaction** (`compaction.enabled`) — Magic Context replaces it. OMP setup turns it off transactionally.
146+
- **OMP automatic memory** (`memory.backend`) — a second memory injector duplicates recall and retention. OMP setup sets it to `off`; existing data is not deleted.
143147
- **DCP** (`opencode-dcp`) — a separate context-pruning plugin. The two cannot run together; remove it from your `plugin` list.
144148
- **oh-my-opencode (OMO)** — setup offers to disable the three hooks that overlap:
145149
- `preemptive-compaction` — triggers compaction that conflicts with the historian.
@@ -232,7 +236,7 @@ Because it runs during idle time, the dreamer pairs well with local models, even
232236
- **`ctx_expand`**: pull a compressed history range back to the original `U:`/`A:` transcript when the agent needs the exact details.
233237
- **`ctx_note`**: a scratchpad for deferred intentions. Notes resurface at natural boundaries (after commits, after historian runs, when todos finish). **Smart notes** carry an open-ended condition the dreamer watches for.
234238

235-
Recall works **across sessions** (a new session inherits everything) and **across harnesses** (write a memory in OpenCode, retrieve it in Pi).
239+
Recall works **across sessions** (a new session inherits everything) and **across harnesses** (write a memory in OpenCode, retrieve it in Pi or OMP).
236240

237241
> **Auto search hints** *(on by default)* run a background `ctx_search` each turn and whisper a "vague recall" when something relevant exists — like almost remembering a note you took. It appends only compact fragments, never full content; set `memory.auto_search.enabled: false` to turn it off. **Git commit indexing** *(opt-in)* makes your project history semantically searchable as an additional `ctx_search` source — enable with `memory.git_commit_indexing.enabled: true`.
238242

‎packages/cli/package.json‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
{
22
"name": "@cortexkit/magic-context",
33
"version": "0.35.1",
4-
"description": "Unified CLI for Magic Context — setup, doctor, and migration across OpenCode and Pi",
4+
"description": "Unified CLI for Magic Context — setup, doctor, and migration across OpenCode, Pi, and OMP",
55
"keywords": [
66
"opencode",
77
"opencode-plugin",
88
"pi",
99
"pi-extension",
10+
"omp",
11+
"oh-my-pi",
1012
"magic-context",
1113
"cli",
1214
"setup",

‎packages/cli/src/adapters/index.ts‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1+
import { OmpAdapter } from "./omp";
12
import { OpenCodeAdapter } from "./opencode";
23
import { PiAdapter } from "./pi";
34
import type { HarnessAdapter, HarnessKind } from "./types";
45

56
export type { HarnessAdapter, HarnessKind } from "./types";
6-
export { OpenCodeAdapter, PiAdapter };
7+
export { OmpAdapter, OpenCodeAdapter, PiAdapter };
78

8-
const ALL: HarnessAdapter[] = [new OpenCodeAdapter(), new PiAdapter()];
9+
const ALL: HarnessAdapter[] = [new OpenCodeAdapter(), new PiAdapter(), new OmpAdapter()];
910

1011
/** Look up an adapter by kind. Throws on unknown kind. */
1112
export function getAdapter(kind: HarnessKind): HarnessAdapter {
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { afterEach, describe, expect, it } from "bun:test";
2+
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
3+
import { tmpdir } from "node:os";
4+
import { join } from "node:path";
5+
import { OmpAdapter } from "./omp";
6+
7+
const original = {
8+
HOME: process.env.HOME,
9+
PATH: process.env.PATH,
10+
PI_CODING_AGENT_DIR: process.env.PI_CODING_AGENT_DIR,
11+
XDG_DATA_HOME: process.env.XDG_DATA_HOME,
12+
};
13+
const roots: string[] = [];
14+
15+
afterEach(() => {
16+
for (const [key, value] of Object.entries(original)) {
17+
if (value === undefined) delete process.env[key];
18+
else process.env[key] = value;
19+
}
20+
for (const root of roots.splice(0)) rmSync(root, { recursive: true, force: true });
21+
});
22+
23+
describe("OmpAdapter", () => {
24+
it("detects an enabled Magic Context plugin from omp plugin list", () => {
25+
const root = mkdtempSync(join(tmpdir(), "mc-omp-adapter-"));
26+
roots.push(root);
27+
const bin = join(root, "bin");
28+
mkdirSync(bin, { recursive: true });
29+
const omp = join(bin, "omp");
30+
writeFileSync(
31+
omp,
32+
`#!/bin/sh
33+
if [ "$1 $2 $3" = "plugin list --json" ]; then
34+
printf '%s' '{"npm":[{"name":"@cortexkit/pi-magic-context","version":"0.33.0","enabled":true}],"marketplace":[]}'
35+
fi
36+
`,
37+
{ mode: 0o755 },
38+
);
39+
process.env.PATH = bin;
40+
process.env.HOME = root;
41+
delete process.env.XDG_DATA_HOME;
42+
43+
const adapter = new OmpAdapter();
44+
expect(adapter.isInstalled()).toBe(true);
45+
expect(adapter.hasPluginEntry()).toBe(true);
46+
expect(adapter.getInstalledPluginVersion()).toBe("0.33.0");
47+
});
48+
});

0 commit comments

Comments
 (0)