This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

tools.covibe: run omp's own TUI via omnigent's pi-native harness

+81 -54
+26 -50
tools/covibe/flake-module.nix
··· 11 11 server = "https://omni.lassul.us"; 12 12 omp = inputs.llm-agents.packages.${system}.omp; 13 13 14 - # The agent this machine runs. omp speaks the Agent Client Protocol 15 - # (`omp acp`), so omnigent's generic `acp` harness drives it with no 16 - # adapter code. The command is the absolute store path because the spec 17 - # is consumed by the runner started here, and that path is in this 18 - # wrapper's closure — unlike the server-side catalog entry in 19 - # 2configs/omnigent.nix, which has to stay unqualified. 20 - # 21 - # os_env is what unlocks the dashboard's file panel: without it the 22 - # runner reports no OS environment and the changed-files/diff endpoints 23 - # 404. sandbox none because omp needs its own ~/.omp credential store and 24 - # unrestricted egress to the model APIs; confinement, if we want it, has 25 - # to happen a layer down (a separate uid, or nspawn), not here. 26 - # 27 - # omnigent_mcp: false is load-bearing. With it on, omnigent hands omp an 28 - # `mcpServers` entry in `session/new` whose command is 29 - # `sys.executable -I -m omnigent.claude_native_bridge serve-mcp`; `-I` 30 - # (isolated) makes that child ignore PYTHONPATH, so under a nixpkgs 31 - # console-script wrapping it cannot import omnigent. omp starts every 32 - # declared MCP server eagerly and fails the whole session when one dies — 33 - # `ACP session/new failed: Internal error`. The relay only bridges 34 - # *omnigent's* builtin tools into the agent, and omp brings its own, so 35 - # turning it off costs nothing here. 36 - spec = pkgs.writeText "omp-agent.yaml" '' 37 - name: omp 38 - prompt: You are omp (Oh My Pi), a concise coding assistant. 39 - 40 - executor: 41 - harness: acp 42 - acp_agent: 43 - name: Oh My Pi 44 - command: ${omp}/bin/omp acp 45 - omnigent_mcp: false 46 - 47 - os_env: 48 - type: caller_process 49 - cwd: "." 50 - sandbox: 51 - type: none 52 - ''; 14 + # omnigent's `pi-native` harness runs the agent's own TUI in a tmux pane, 15 + # attaches your TTY to it, and mirrors the session (transcript, tool 16 + # calls, terminal, files) to the server — the shape covibe always had, 17 + # now with omnigent's per-session ACLs behind it. It resolves the CLI by 18 + # the literal name `pi` (onboarding/harness_install.py: the readiness gate 19 + # is `resolve_cli_binary("pi")`, which ignores OMNIGENT_PI_PATH and the 20 + # config override), so omp has to reach it under that name. Version-gated 21 + # flags are satisfied by omp reporting 17.x >= pi's declared 0.79.0 floor. 22 + piShim = pkgs.writeShellApplication { 23 + name = "pi"; 24 + text = '' 25 + OMP_BIN=${omp}/bin/omp 26 + '' 27 + + builtins.readFile ./pi-shim.sh; 28 + }; 53 29 in 54 30 { 55 - # Launch omp as a session on the omni.lassul.us dashboard: the agent and 56 - # its runner stay on this machine (local runner + remote server 57 - # topology), while the server holds the transcript, the diff view and the 58 - # per-session ACLs, so a session can be shared read-only or read-write 59 - # with another pocket-id account. The terminal REPL and the browser drive 60 - # the same session. 31 + # Launch omp as a session on the omni.lassul.us dashboard: omp's own TUI 32 + # runs here, in a tmux pane owned by the local runner, while the server 33 + # holds the transcript, the diff view and the per-session ACLs — so a 34 + # session can be shared read-only or read-write with another pocket-id 35 + # account, and a teammate's message from the browser executes in this 36 + # TUI. 61 37 # 62 38 # First use per machine opens a browser for the pocket-id login; the 63 39 # session JWT is cached in ~/.omnigent/auth_tokens.json afterwards. 64 - # Arguments go to `omnigent run`, so `covibe -p "fix the tests"` runs one 65 - # non-interactive turn and `covibe --fork <session-id>` continues someone 66 - # else's session here. 40 + # Arguments go through to omp, e.g. `covibe --continue`; `covibe --resume` 41 + # (no value) opens omnigent's session picker. 67 42 packages.covibe = 68 43 (pkgs.writeShellApplication { 69 44 name = "covibe"; 70 45 runtimeInputs = [ 71 46 self'.packages.omnigent 72 - omp 47 + piShim 48 + pkgs.tmux 73 49 pkgs.jq 74 50 pkgs.git 75 51 ]; ··· 80 56 echo "covibe: no session for $server yet, logging in" >&2 81 57 omnigent login "$server" 82 58 fi 83 - exec omnigent run ${spec} --server "$server" "$@" 59 + exec omnigent pi --server "$server" "$@" 84 60 ''; 85 61 }).overrideAttrs 86 62 { passthru.usage = builtins.readFile ./usage.kdl; };
+51
tools/covibe/pi-shim.sh
··· 1 + # shellcheck shell=bash 2 + # Argument translation between omnigent's `pi-native` harness and omp. 3 + # 4 + # omnigent builds `--extension <js> [--approve] --session-dir <dir> 5 + # [--session <id>] <user args>` (omnigent/runner/native/orchestration.py 6 + # _build_pi_native_args) against the upstream `pi` CLI at 0.79.x. omp 17.x 7 + # differs in three ways: 8 + # 9 + # 1. `--approve` (pi's project-trust override) does not exist; omp exits 10 + # "unknown flag: --approve". Drop it — a human is attached to the TUI and 11 + # omp's own approval prompts are what we want. 12 + # 2. `--session <id>` is spelled `--resume <id>` in omp. 13 + # 3. omnigent's bridge extension is CommonJS (`module.exports = fn`), while 14 + # omp dynamic-imports the file and accepts only `module` / 15 + # `module.default` as the factory — a CJS file fails with "Extension does 16 + # not export a valid factory function". Point omp at a generated ESM 17 + # adapter that re-exports the CJS factory as a default export instead. 18 + # Verified: the status line then reads "· linked", prompts typed in the 19 + # TUI appear in the dashboard transcript, and messages sent from the 20 + # dashboard execute in the TUI. 21 + argv=() 22 + while [ "$#" -gt 0 ]; do 23 + case "$1" in 24 + --approve) 25 + shift 26 + ;; 27 + --session) 28 + argv+=(--resume "$2") 29 + shift 2 30 + ;; 31 + --extension) 32 + ext=$2 33 + shift 2 34 + adapter="$(dirname "$ext")/omnigent-esm-adapter.mjs" 35 + if [ ! -e "$adapter" ]; then 36 + cat >"$adapter" <<EOF 37 + import { createRequire } from "node:module"; 38 + const require = createRequire(import.meta.url); 39 + export default require("$ext"); 40 + EOF 41 + fi 42 + argv+=(--extension "$adapter") 43 + ;; 44 + *) 45 + argv+=("$1") 46 + shift 47 + ;; 48 + esac 49 + done 50 + 51 + exec "$OMP_BIN" "${argv[@]}"
+4 -4
tools/covibe/usage.kdl
··· 1 1 bin "covibe" 2 - about "Run omp as a session on the omni.lassul.us omnigent dashboard (agent stays local, transcript + diff view + sharing live on the server)" 2 + about "Run omp's TUI as a shared session on the omni.lassul.us omnigent dashboard (transcript, diff view and read-only/read-write sharing live on the server)" 3 3 4 - flag "-p --prompt" help="Run one non-interactive turn with this prompt and exit" 5 - flag "--fork" help="Continue an existing session id from its fork point on this machine" 6 - arg "[omnigent-run-args...]" help="Arguments passed through to `omnigent run`" 4 + flag "-c --continue" help="Continue the previous omp session in this directory" 5 + flag "-r --resume" help="Resume an omnigent session (no value opens the picker)" 6 + arg "[omp-args...]" help="Arguments passed through to omp"