/pi-native-e2e-dev
Spin up a live local Omnigent server + runner and exercise the native Pi TUI harness (pi-native) end-to-end — launch the real `pi` CLI via `omnigent pi`, drive turns through the web/bridge, smoke-test, and bug-bash. Load when developing, testing, or debugging the pi-native
$ npx -y skills add omnigent-ai/omnigent --skill pi-native-e2e-dev --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/pi-native-e2e-dev
Context preview
The summary Claude sees to decide when to auto-load this skill.
Spin up a live local Omnigent server + runner and exercise the native Pi TUI harness (pi-native) end-to-end — launch the real `pi` CLI via `omnigent pi`, drive turns through the web/bridge, smoke-test, and bug-bash. Load when developing, testing, or debugging the pi-native
SKILL.md
pi-native-e2e-dev.SKILL.mdname: pi-native-e2e-dev
description: Spin up a live local Omnigent server + runner and exercise the native Pi TUI harness (pi-native) end-to-end — launch the real `pi` CLI via `omnigent pi`, drive turns through the web/bridge, smoke-test, and bug-bash. Load when developing, testing, or debugging the pi-native harness (omnigent/inner/pi_native_executor.py, pi_native_harness.py, omnigent/pi_native.py, pi_native_bridge.py, pi_native_credentials.py) or its bridge / extension / auth / model behavior.
Pi native harness: end-to-end dev & testing (local server/runner)
The `pi-native` harness wraps the **real Pi coding-agent TUI** (`@earendil-works/pi-coding-agent`, the `pi` CLI). Unlike the SDK harnesses (cursor / copilot / antigravity), it does **not** run in-process: `omnigent pi` ensures a host daemon, the daemon spawns a **runner** that launches `pi` inside a runner-owned **tmux** terminal, and your TTY attaches to it. Omnigent's web-UI turns are forwarded into that live `pi` process through a **file-inbox bridge** + a packaged **JS extension** (`pi.sendUserMessage`). This skill is the proven recipe for running it **for real against a live local server + runner** — not just the unit tests.
> Like the other harnesses, the runner imports from your **current checkout**, so > testing here exercises exactly the code you're on. (CWD/venv selects the code, > not `PYTHONPATH`.)
What actually runs where
your TTY ── (attach / pexpect) ──► omnigent pi (CLI, local)
│ ensures
▼
host daemon ──► local Omnigent server (AP)
│ spawns ▲
▼ │ HTTP
runner ── launches ──► pi (TUI, in tmux)
│ loads
▼
omnigent pi-native extension (JS)Two ways a turn reaches Pi — test both:
1. **Type in the TUI** (your attached terminal). Exercises Pi natively; the extension mirrors the transcript back to the server (`POST …/events`). 2. **Web / API message.** Server → runner → **`PiNativeExecutor.run_turn`** → `enqueue_user_message()` writes `inbox/<ordinal>_msg_*.json` → the resident extension polls the inbox → `pi.sendUserMessage(...)`. This is the harness-specific path most worth covering.
Prerequisites (check these first)
1. **You're on the branch you want to test**, and running from that checkout (`.venv/bin/omnigent` / `.venv/bin/python` from this repo). 2. **The `pi` CLI is on PATH** — the harness can't launch without it:
which pi && pi --version
# install if missing: npm install -g @earendil-works/pi-coding-agent
# or point at an explicit binary: export OMNIGENT_PI_PATH=/path/to/pi
.venv/bin/python -c "from omnigent.onboarding.harness_readiness import harness_is_configured; print('pi-native ready:', harness_is_configured('pi-native'))"3. **`tmux` is on PATH.** The native wrapper attaches your TTY to the runner-owned Pi tmux pane (`_preflight_local_tools` hard-fails without it). 4. **`node` is on PATH.** The extension is JS executed inside Pi (also required by the e2e extension tests). `node --version`. 5. **Auth is resolvable (booleans/ids only — never print keys).** Native Pi normally logs in from its own `~/.pi/agent`. Omnigent bridges the provider you set with `omnigent setup` instead, writing a managed per-session `models.json` and passing `--provider omnigent --model <resolved>`. Verify what it will use:
.venv/bin/python -c "from omnigent.pi_native_credentials import resolve_pi_native_provider as r; p=r(); print('provider:', getattr(p,'provider_id',None), '| api:', getattr(p,'api',None), '| model:', getattr(p,'model',None))"`None` → no omnigent provider configured; Pi falls back to its own `/login` (run `omnigent setup`, or log into `pi` directly). A Databricks default resolves to the AI-Gateway `anthropic-messages` surface with a refreshed bearer token. 6. **Network egress to the model backend.** A turn that hangs/fails to connect on a locked-down host is usually egress, not a harness bug.
Step 1 — start a local server (real server + runner)
cd /path/to/omnigent
.venv/bin/omni server --background # detached managed server on a free loopback port
.venv/bin/omni server status # prints the URL, e.g. http://127.0.0.1:6767
SERVER=http://127.0.0.1:6767 # use the printed URL below
curl -s "$SERVER/health" # {"status":"ok"}(`omnigent pi --server ""` also auto-spawns a persistent local server and uses it — handy for a one-shot manual run, but a known `$SERVER` URL is better for scripted API observation below.)
Step 2 — launch the native Pi terminal against the local server
`omnigent pi` **attaches an interactive TUI**, so run it where you can hold it open. Two patterns:
**A. Background terminal (recommended for scripted drives).** Launch it in one terminal and drive/observe from another:
.venv/bin/omnigent pi --server "$SERVER" 2>&1 # attaches the Pi TUI; leave it running
It prints `Web UI: <url>` and a resume hint to stderr — grab the conversation id (the `…/c/<conv_…>` segment). Capture it for the API calls below:
CONV=conv_xxxxxxxx # from the "Web UI:" line / resume hint
**B. PTY driver (fully automated).** Drive it under `pexpect` exactly like the `claude-native-e2e-test` skill's `cuj_driver.py` (a proven, generalizable base): spawn `omnigent pi --server <url>` in a PTY with `cwd=<checkout>`, capture the conv id from the printed URL, send keystrokes / poll the API, then **tear down the whole process tree** (see Teardown — pexpect Ctrl-C only *detaches* tmux).
Read more
name: pi-native-e2e-dev description: Spin up a live local Omnigent server + runner and exercise the native Pi TUI harness (pi-native) end-to-end — launch the real `pi` CLI via `omnigent pi`, drive turns through the web/bridge, smoke-test, and bug-bash. Load when developing, testing, or debugging the pi-native harness (omnigent/inner/pi_native_executor.py, pi_native_harness.py, omnigent/pi_native.py, pi_native_bridge.py, pi_native_credentials.py) or its bridge / extension / auth / model behavior.
Pi native harness: end-to-end dev & testing (local server/runner)
The `pi-native` harness wraps the **real Pi coding-agent TUI** (`@earendil-works/pi-coding-agent`, the `pi` CLI). Unlike the SDK harnesses (cursor / copilot / antigravity), it does **not** run in-process: `omnigent pi` ensures a host daemon, the daemon spawns a **runner** that launches `pi` inside a runner-owned **tmux** terminal, and your TTY attaches to it. Omnigent's web-UI turns are forwarded into that live `pi` process through a **file-inbox bridge** + a packaged **JS extension** (`pi.sendUserMessage`). This skill is the proven recipe for running it **for real against a live local server + runner** — not just the unit tests.
> Like the other harnesses, the runner imports from your **current checkout**, so > testing here exercises exactly the code you're on. (CWD/venv selects the code, > not `PYTHONPATH`.)
What actually runs where
your TTY ── (attach / pexpect) ──► omnigent pi (CLI, local)
│ ensures
▼
host daemon ──► local Omnigent server (AP)
│ spawns ▲
▼ │ HTTP
runner ── launches ──► pi (TUI, in tmux)
│ loads
▼
omnigent pi-native extension (JS)Two ways a turn reaches Pi — test both:
1. **Type in the TUI** (your attached terminal). Exercises Pi natively; the extension mirrors the transcript back to the server (`POST …/events`). 2. **Web / API message.** Server → runner → **`PiNativeExecutor.run_turn`** → `enqueue_user_message()` writes `inbox/<ordinal>_msg_*.json` → the resident extension polls the inbox → `pi.sendUserMessage(...)`. This is the harness-specific path most worth covering.
Prerequisites (check these first)
1. **You're on the branch you want to test**, and running from that checkout (`.venv/bin/omnigent` / `.venv/bin/python` from this repo). 2. **The `pi` CLI is on PATH** — the harness can't launch without it:
which pi && pi --version
# install if missing: npm install -g @earendil-works/pi-coding-agent
# or point at an explicit binary: export OMNIGENT_PI_PATH=/path/to/pi
.venv/bin/python -c "from omnigent.onboarding.harness_readiness import harness_is_configured; print('pi-native ready:', harness_is_configured('pi-native'))"3. **`tmux` is on PATH.** The native wrapper attaches your TTY to the runner-owned Pi tmux pane (`_preflight_local_tools` hard-fails without it). 4. **`node` is on PATH.** The extension is JS executed inside Pi (also required by the e2e extension tests). `node --version`. 5. **Auth is resolvable (booleans/ids only — never print keys).** Native Pi normally logs in from its own `~/.pi/agent`. Omnigent bridges the provider you set with `omnigent setup` instead, writing a managed per-session `models.json` and passing `--provider omnigent --model <resolved>`. Verify what it will use:
.venv/bin/python -c "from omnigent.pi_native_credentials import resolve_pi_native_provider as r; p=r(); print('provider:', getattr(p,'provider_id',None), '| api:', getattr(p,'api',None), '| model:', getattr(p,'model',None))"`None` → no omnigent provider configured; Pi falls back to its own `/login` (run `omnigent setup`, or log into `pi` directly). A Databricks default resolves to the AI-Gateway `anthropic-messages` surface with a refreshed bearer token. 6. **Network egress to the model backend.** A turn that hangs/fails to connect on a locked-down host is usually egress, not a harness bug.
Step 1 — start a local server (real server + runner)
cd /path/to/omnigent
.venv/bin/omni server --background # detached managed server on a free loopback port
.venv/bin/omni server status # prints the URL, e.g. http://127.0.0.1:6767
SERVER=http://127.0.0.1:6767 # use the printed URL below
curl -s "$SERVER/health" # {"status":"ok"}(`omnigent pi --server ""` also auto-spawns a persistent local server and uses it — handy for a one-shot manual run, but a known `$SERVER` URL is better for scripted API observation below.)
Step 2 — launch the native Pi terminal against the local server
`omnigent pi` **attaches an interactive TUI**, so run it where you can hold it open. Two patterns:
**A. Background terminal (recommended for scripted drives).** Launch it in one terminal and drive/observe from another:
.venv/bin/omnigent pi --server "$SERVER" 2>&1 # attaches the Pi TUI; leave it running
It prints `Web UI: <url>` and a resume hint to stderr — grab the conversation id (the `…/c/<conv_…>` segment). Capture it for the API calls below:
CONV=conv_xxxxxxxx # from the "Web UI:" line / resume hint
**B. PTY driver (fully automated).** Drive it under `pexpect` exactly like the `claude-native-e2e-test` skill's `cuj_driver.py` (a proven, generalizable base): spawn `omnigent pi --server <url>` in a PTY with `cwd=<checkout>`, capture the conv id from the printed URL, send keystrokes / poll the API, then **tear down the whole process tree** (see Teardown — pexpect Ctrl-C only *detaches* tmux).
Omnigent is an open-source AI agent framework and meta-harness: orchestrate Claude Code, Codex, Cursor, Pi, and custom agents — swap harnesses without rewriting, enforce policies and sandboxing, and collaborate in real time from any device.
Repo: omnigent-ai/omnigent
Other skills on omnigent.
- /antigravity-native-e2e-dev
Spin up a live local Omnigent server + runner and exercise the native Antigravity (agy) TUI harness (antigravity-native) end-to-end — launch the real `agy` CLI via `omnigent antigravity`, drive turns through the web UI, smoke-test, and bug-bash. Load when developing, testing, or
Open skill - /antigravity-sdk-e2e-dev
Spin up a live local Omnigent server and exercise the Antigravity (Gemini) SDK harness end-to-end — build antigravity agents, run real turns, smoke-test, and bug-bash. Load when developing, testing, or debugging the antigravity harness (omnigent/inner/antigravity_executor.py,
Open skill - /cli-setup-verify
Verify the Omnigent CLI's setup/onboarding flow, terminal UI/UX, and critical user journeys in a completely isolated, reproducible loop. Drives the real `omnigent` binary through a PTY (pexpect) inside a throwaway OMNIGENT_CONFIG_HOME / OMNIGENT_DATA_DIR sandbox that never
Open skill - /copilot-sdk-e2e-dev
Spin up a live local Omnigent server and exercise the GitHub Copilot SDK harness end-to-end — build copilot agents, run real turns, smoke-test, and bug-bash. Load when developing, testing, or debugging the copilot harness (omnigent/inner/copilot_executor.py, copilot_harness.py,
Open skill - /cursor-sdk-e2e-dev
Spin up a live local Omnigent server and exercise the Cursor SDK harness end-to-end — build cursor agents, run real turns, smoke-test, and bug-bash. Load when developing, testing, or debugging the cursor harness (omnigent/inner/cursor_executor.py, cursor_harness.py,
Open skill - /harness-integration-guide
Reference guide for building new Omnigent harness integrations — covers SDK/subprocess harnesses and native harnesses as separate tracks, each with their own feature matrix, implementation patterns, and prioritized checklist.
Open skill

