Imported from toxicwind/tau-extensions (
packages/gsd-omp/AGENTS.md). Install upstream withnpx skills add toxicwind/tau-extensions --skill gsd-omp. Copyright stays with the author.
Repository Guidelines
Project Overview
gsd-omp is an independently maintained CommonJS host plugin that adapts @opengsd/gsd-core to Oh My Pi (OMP). It negotiates GSD Embeddable Orchestration System (EoS) protocol 1, projects GSD agents and skills into an OMP runtime profile, and exposes GSD commands, gsd_invoke, status surfaces, and native task/session integrations.
This is a pure Node.js package: there is no transpilation or bundling step. The npm pack tarball is the distribution artifact. The package requires Node.js >=24.0.0 and GSD Core >=1.11.0 (dependency range ^1.11.0).
Architecture & Data Flow
- Install and ownership —
bin/gsd-omp.cjsresolves the OMP runtime root (--root>PI_CODING_AGENT_DIR>~/.omp/agent), initializes EoS, checks the GSD Core version, builds projected artifacts, and performs a staged install..gsd-omp-manifest.jsonrecords SHA-256 ownership so modified or unmanaged files are protected. - EoS contract —
src/eos.cjsloads GSD Core's Host-Integration SDK, negotiates protocol1with theprogrammatic-cliprofile, and caches the imperative OMP adapter, passive model adapter, host hook bus, and filesystem state adapter. - Projection —
src/projection.cjsreads GSD Coreagents/,skills/, andcommands/gsd/. It rewrites runtime paths andgsd:<name>references, injects OMP tool/orchestration guidance, and emits artifacts under the selected runtime root'sagents/andskills/directories. Core files remain the source of truth. - OMP extension load — The generated
extensions/gsd-omp.tswrapper loadssrc/extension.cjsand passes the runtime root. The extension factory registers the GSD command surface,gsd_invoke, completions, resource discovery, status/widget/overlay integrations, and lifecycle handlers through capability-checked OMP APIs. - Command execution —
/gsd ...andgsd_invokeresolve the bundled GSD Coregsd-tools.cjs, run it with the project ascwd,GSD_RUNTIME=omp, and the effectiveGSD_AGENTS_DIR, then return bounded output as OMP messages. Hook subprocesses are bounded and fail open unless a hook explicitly blocks a call. - Native runtime state — OMP owns session lifecycle, model selection, approvals, native tasks, jobs, isolation, compaction, retries, aborts, and session navigation. GSD Core owns its CLI semantics and
.planning/artifacts.gsd-omptranslates between those boundaries and feeds project state, native task state, context signals, and Goal Mode state into/gsd-status, the widget, footer, and overlay. - Goal Mode —
goal_updatedis optional. The extension registers it inside a guarded block, validates and caches event state, and can recover the latest goal from the OMP session journal. It does not call private Goal APIs or mutate OMP's GoalRuntime. An active OMP goal holds a pending GSD continuation and instructs the user to pause/drop the goal before/gsd-next; OMP 17 remains functional without the event. - Localization — Shell CLI/EoS messages use
src/locale.cjsand POSIX environment precedence. In-session extension messages use the project'sresponse_language, intentionally keeping shell locale and project session language separate.
Key Directories
bin/— executable installer/updater and manifest ownership logic.src/— EoS adapter, OMP extension, artifact projection, localization, and graphify worker.src/locales/— English and Simplified Chinese message dictionaries.scripts/— release metadata synchronization and packed OMP host smoke testing.test/— Node built-in unit and contract tests with temporary-directory fixtures.docs/— architecture, configuration, development, testing, and getting-started guides..github/workflows/— Node unit CI, OMP 17/latest host smoke, upstream drift reporting, and automated release.
Development Commands
Install dependencies for an editable checkout, or reproduce CI's lockfile install:
npm install
npm ci
Run the package checks:
npm run lint # node --check for all shipped .cjs modules
npm test # node --test across test/
node --test test/extension.test.cjs # focused suite while iterating
prepack runs lint and tests. To inspect the actual distribution artifact without lifecycle scripts:
package_tarball="$(npm pack --silent --ignore-scripts)"
npm install --global "./${package_tarball}"
Exercise the installer without touching the normal OMP profile:
root="$(mktemp -d)"
PI_CODING_AGENT_DIR="$root" node bin/gsd-omp.cjs install --json
PI_CODING_AGENT_DIR="$root" node bin/gsd-omp.cjs doctor --json
PI_CODING_AGENT_DIR="$root" node bin/gsd-omp.cjs descriptor --json
PI_CODING_AGENT_DIR="$root" node bin/gsd-omp.cjs uninstall --json
rm -rf "$root"
The CLI supports install, update, uninstall, doctor, and descriptor; no command defaults to install. Common options are --root <path>, --force, and --json. Use doctor --json before considering --force.
For host integration, install the packed package and run both compatibility targets:
npm install --global "@oh-my-pi/pi-coding-agent@17.0.3"
OMP_VERSION=17.0.3 GSD_OMP_BIN=gsd-omp node scripts/host-smoke.cjs
npm install --global "@oh-my-pi/pi-coding-agent@latest"
OMP_VERSION=latest GSD_OMP_BIN=gsd-omp node scripts/host-smoke.cjs
Code Conventions & Common Patterns
- Keep source modules CommonJS:
require(...),module.exports,.cjs,'use strict', two-space indentation, semicolons, single-quoted strings, and the surrounding files' trailing-comma style. Usenode:prefixes for new Node built-ins. - Preserve the existing dependency-injection seams. The extension is a factory receiving
(pi, options), CLI operations accept option objects, and test-only helpers are exposed through module exports/_internalswhere needed. Prefer passing dependencies and paths as parameters over adding process-global coupling. - Treat OMP APIs as optional capabilities. Guard
registerShortcut,registerFlag, renderers,askDialog, session APIs, context APIs, and resource discovery withtypeofchecks. Keep fallback paths (for exampleselectwhenaskDialogis unavailable) and wrap optionalgoal_updatedregistration so OMP 17 still loads. - Use bounded async subprocesses and explicit abort/settlement cleanup.
invokeAsyncmust honor an already-aborted signal, terminate children cleanly, cap captured output, and settle once. Use OMP-managed timers and native tasks rather than shell backgrounding or a second job system. - Keep state project- and context-scoped. Native GSD task tracking uses ref-counts and terminal settlement to avoid stale or duplicate counts; clear Goal/session/runtime maps on shutdown, switch, branch, and tree changes. Ignore ordinary non-GSD OMP tasks in GSD status.
- Fail safely at boundaries: return structured errors, preserve user files, clean temporary state in
finally, and avoid silently falling back to an unrelated global executable. Installer paths must be relative to the selected root, point through regular directories, and reject symlink traversal;--forcedoes not bypass path-safety checks. - Keep localization dictionaries in key and placeholder parity.
src/locale.cjsuses own-property lookup, English fallback, and unchanged placeholders for missing parameters. Add matching keys to bothsrc/locales/en.cjsandsrc/locales/zh-CN.cjs. - Use
/gsd-statusas the user-facing GSD status entry point. Native task/session mechanisms remain internal integration details; do not add a competing status command when extending the native surface. - Keep versioned install URLs and release metadata synchronized through
scripts/bump-version.cjs; update both README files and the relevant guide when user-visible behavior changes. Do not hand-edit generated projected runtime artifacts as a source of truth.
Important Files
package.json— package entry point, Node/GSD engine requirements, scripts, dependency, packed-file list, and keywords.bin/gsd-omp.cjs— CLI parsing, runtime-root resolution, install/update/uninstall/doctor/descriptor, manifest validation, hashes, and transactional writes.src/eos.cjs— cached protocol-v1 EoS negotiation and adapter construction.src/extension.cjs— OMP extension factory; command/tool registration, child-process bridge, native task tracking, status surfaces, session controls, hooks, localization, and Goal Mode.src/projection.cjs— deterministic agent/skill projection, path rewriting, command-name conversion, and OMP orchestration text.src/locale.cjsandsrc/locales/*.cjs— shell/EoS locale selection and dictionaries.src/gsd-graphify-worker.cjs— detached graphify rebuild worker with lock/status handling.scripts/host-smoke.cjs— isolated packed-install and OMP RPC compatibility test.scripts/bump-version.cjs— semver metadata updater for package/lock files, install docs, andCHANGELOG.md.test/extension.test.cjs— primary extension, native OMP, status, task lifecycle, and Goal Mode regression coverage.test/installer.test.cjs,test/eos.test.cjs,test/projection.test.cjs,test/locale.test.cjs,test/release-metadata.test.cjs— focused contract suites for installer safety, EoS, projection, localization, and release synchronization..github/workflows/ci.ymland.github/workflows/release.yml— required CI matrix and automatic patch release flow.
Runtime/Tooling Preferences
- Use Node.js
24.xor newer for development, tests, lint, CLI work, and package operations. Use npm;package-lock.jsonis lockfile version 3. The source is not TypeScript/ESM and has no build command. - OMP's EoS declaration advertises
runtime: "bun"; the OMP host is installed separately for smoke tests. The extension still launches the resolved GSD Core CLI through Node child-process APIs. PI_CODING_AGENT_DIRselects the install/runtime root;--rootoverrides it. Preserve a pre-existingGSD_AGENTS_DIR; otherwise use<runtime-root>/agents.GSD_RUNTIME=ompis an internal child-process bridge setting.- Shell locale precedence is
GSD_OMP_LOCALE→LC_ALL→LC_MESSAGES→LANG; supported values normalize toenorzh-CN. Project-session language comes from.planning/config.jsonresponse_language. GITHUB_TOKEN/GH_TOKENare process-environment credentials for release lookup duringupdate.OMP_BIN,GSD_OMP_BIN,OMP_VERSION, andOPENAI_API_KEYare host-smoke controls; the smoke script uses a placeholder key only to start the host and does not make a model request.mainis protected. Work on a descriptive branch, run applicable checks, and use a pull request; CI covers Node 24 plus OMP17.0.3andlatest. The release workflow bumps patch versions, opens/merges a release PR, tags, and publishes the GitHub release.
Testing & QA
Tests use node:test and node:assert/strict; there is no external test framework or separate coverage command. Fixtures generally use fs.mkdtempSync(...), isolated runtime/project roots, and cleanup in finally, so tests should not depend on a developer's real ~/.omp/agent or .planning/ workspace.
The unit/contract suites cover:
- installer ownership, manifest validation, hashes, rollback, stale projections, modified files, directories, and symlink safety;
- protocol-v1 EoS negotiation and declared axes;
- deterministic projection, path rewriting, command rewriting, idempotence, and executor result protocol;
- locale precedence, fallback, own-property behavior, dictionary key parity, and placeholders;
- extension registration, command routing, native renderers, status/context/task/session behavior, abort handling, resource discovery, and Goal Mode event/journal/fallback behavior;
- package/lockfile version and README/Getting Started install URL synchronization.
For extension or installer changes, run npm run lint, npm test, and the packed host smoke against both OMP 17.0.3 and latest. The smoke test creates a temporary runtime root, verifies JSON install/doctor/descriptor, launches OMP in RPC mode, checks readiness and representative commands, validates gsd_invoke or the OMP 17 legacy RPC surface, and uninstalls the projection. OMP 17 is expected not to expose goal_updated; that absence is a compatibility path, not a failure.
Before opening a PR, also run git diff --check and inspect npm pack --silent --ignore-scripts contents when packaging or documentation files change. Add a focused regression test in the closest existing suite for each behavior or compatibility boundary changed; do not claim a check passed unless it was actually run.