This is the umbrella skill markdown for the OpenMarket CLI (om). Any shell-capable LLM client reads these files to learn how to drive the binary.
One binary, seven jobs:
- Market data:
om points,om markets,om symbols,om coins,om exchanges,om normalized-symbols,om block-sizes,om tenors,om enum,om usage,om subscribe,om polymarket,om metric. Calls the OpenMarket Data API athttps://api.openmarket.xyzvia the bundled SDK.om metric getcomputes any registered scalar metric (price, volume, funding_rate, open_interest, plus indicators like RSI / MACD / EMA / BB / ATR / Stoch) for a symbol on-demand; same metric registry the alert engine uses, so values match what an alert would fire on. - WRUN packages:
om installinstalls WRUN packages from local paths, GitHub repos, or registry tarballs;om wrun ...scaffolds, validates, builds, exports, installs, lists, removes, upgrades, and configures WRUN indicator packages. Installed outputs become metric ids likewrun/@scope/name/outputthat work with metric lookup, alerts, and chart adds (om collab indicator add --type wrun/...). Seemarketplace.mdfor the registry workflow and agent-native authoring. - Alert engine:
om alert ...to author alerts as JSON files under~/.openmarket/alerts/(typed conditions OR custom-script conditions backed by files under~/.openmarket/scripts/), optional Hyperliquid or Polymarket auto-execution viaon_fire.execute,om service installto install a launchd/systemd daemon that watches them,om alert watchto tail fire events in real time. - News / text-event feeds:
om news ...manages three products behind one capability-gated surface — alerts (name a trigger, get pinged when it happens), briefs (name a subject, get a few story cards a day), and streams (ready-made feeds from Synoptic's marketplace). Acquiring any of them auto-attaches a per-feed event-watch, so what they carry reaches journals and notification channels. Seenews.md. - Event watches:
om event-watch ...manages persistent event-stream monitors;om event-journal ...retrieves their local Markdown event journals on demand. Seeevent-watches.md. - Research studies:
om research studyruns strictly correlational event studies over accepted event-watch rows and one asset's candles. Use it to inspect event anchors and pre/post returns, never as a trade signal. Seeresearch.md. - Collab bridge:
om collab ...to inspect and mutate OpenMarket chart workspaces through a persistent WebSocket the daemon holds open tocollab-service. Commands are grouped by resource (session/workspace/chart/indicator/drawing) — the same shapekubectlanddockeruse so the surface scales as new server-side actions ship. Reads:om collab session status,om collab workspace list,om collab workspace state --workspace <id>. Mutations:om collab chart layout(multi-chart grid —3x1/2x2/...),om collab chart symbol/chart interval/chart plot-type(per-pane),om collab chart sync(symbol/interval/crosshair sync),om collab indicator add(RSI/MACD/EMA/...),om collab drawing add(TrendLine, FibonacciRetracement),om collab chart view(set the visible time range — ephemeral). Seechart-actions.mdfor the full workflow. A grid/layout request is achart layoutchange FIRST, then per-panechart symbol. - Strategies:
om signal+om strategywire a signal (over a watched event stream or a market metric) to automated trading on Polymarket or Hyperliquid — a signal emits a direction/conviction view, a strategy binds it to a pinned market + sizer, and the daemon evaluates enabled strategies each tick (observe / paper / dry_run / live). Author, thenom strategy resume; the daemon acts (no foreground strategy-run command). Seestrategy.md.
The same om binary owns all of these surfaces. There is no separate "data", "wrun", "runner", "research", or "collab" CLI.
Tool-call hygiene: when calling any create/edit tool, omit optional fields you have no user instruction for — never pass a field just to restate its default. Chat surfaces render what each call set versus defaulted, and explicitly passed defaults misreport as user choices.
Required environment:
| Var | Purpose |
|---|---|
OM_API_KEY |
OpenMarket Data API auth. Captured interactively by om init (stored in ~/.openmarket/om.sqlite) or exported as an env var. |
OM_BASE_URL (optional) |
Override the REST base URL; defaults to https://api.openmarket.xyz. |
OM_BIND (optional) |
Daemon HTTP bind target; defaults to 127.0.0.1:31337. Non-loopback binds require a token (auto-generated to ~/.openmarket/runner.token). |
Channels (Telegram, Discord, …) are configured via om init or om setup <channel> and persisted in ~/.openmarket/om.sqlite — no env vars needed.
How to load this skill
- Claude Code / Cursor / Aider (shell agents): point the agent at the
skills/directory or pipeom skill show openmarket/om skill show openmarket-researchinto context. - OpenClaw:
om setup openclawwrites the bundled skill (SKILL.md + supporting markdown) to~/.openclaw/skills/openmarket/, following the Agent Skills open standard. - Codex:
om setup codexwrites the bundled skill to~/.codex/skills/openmarket/, same Agent Skills layout. - Anything else (bash, cron, GitHub Actions): read the markdown directly. The skill is markdown-only — there's nothing client-specific in here.
Files
SKILL.md(this file) — umbrella index. Routes the agent to the right detail file for the user's question.alerts.md— alert anatomy, the supported condition shape, the discover-then-import workflow, error recovery. Read when the user mentions alerts, conditions, thresholds,om alert ..., or wants to be notified about a market. Also covers the optionalon_fire.executeblock — independent of the condition, so akind: scriptcondition can auto-execute too (a stateful strategy can place orders, not just notify).orders.md— one-shot order placement viaom order placeon a paired execution venue (Hyperliquid and Polymarket CLOB). Read when the user wants to act now — limit-bid a level, open or close a position — rather than wire a condition-triggered alert. Covers the flag and JSON-stdin forms, sizing modes, venue account reads, and the preview/confirm safety contract.marketplace.md: discover, install, and publish registry packages (om search/om install/om publish/om yank/om access), plus agent-native WRUN indicator authoring (wrun_author→wrun_build→ value-check → publish) with the metadata dialect and styling vocabulary. Read when the user mentions the marketplace or registry, wants to install or publish a package, or asks for a custom indicator to be built, styled, or put on a chart.metrics.md— compute scalar metric values ad-hoc viaom metric get, scan a universe viaom metric screen, and discover the registry viaom metric list. Covers every registered metric (price / delta_pct / volume / funding_rate / open_interest plus indicators: RSI / SMA / EMA / MACD / BB / ATR / Stoch) with canonical default params and prompting rules; CCI/MFI/OBV/VWAP/ADX/Ichimoku are chart overlays only, not metrics. Read when the user asks for the current value of any scalar metric on a symbol ("what's RSI on BTC?", "what's the price of SOL?", "give me the 4h MACD for ETH", "is BTC overbought right now?", "show me Bollinger Bands on SOL") or wants to verify what an alert would fire on right now.chart-actions.md— the Collab Service Bridge: agent commands for inspecting the orchestrator's WS connection (om collab session status), listing workspaces (om collab workspace list), reading the cached server state (om collab workspace state --workspace <id>), and mutating charts (om collab chart layout,om collab chart symbol,om collab chart interval,om collab chart plot-type,om collab chart sync,om collab indicator add,om collab drawing add,om collab chart view). Read when the user asks "is the orchestrator/bridge connected?", "what workspaces do I have?", "what's on my chart workspace?", or asks to: change the layout / grid (e.g.3x1,1x3,2x2, "three across", "split into two") / change a chart's symbol / interval / plot type / toggle multi-chart sync (symbol / interval / crosshair) / add a technical indicator (RSI / MACD / EMA / BB / ATR / Stoch / Liquidations) / seek / zoom / pan the visible range. For drawing tools (trendlines, fibs, shapes, positions, annotations) seechart-actions-tool-drawing.md. A grid dimension or "set up N charts with these symbols" is achart layoutchange FIRST, then per-panechart symbol— read this file before acting.chart-actions-tool-drawing.md— the drawing-tool detail forom collab drawing(auto / add / schema / remove). Read when the user asks to draw, add, place, mark, box, annotate, plot a fib, set up a long/short position, or remove a tool on a chart. Coversdrawing auto(anchors computed from market data — preferred),drawing add(caller-supplied role-tagged--anchors),drawing schema(discover a tool's anchor roles), anddrawing remove.news.md— text-event news/social alerts viaom news: vendor capabilities (Attention authoring vs Synoptic catalog), preview-before-create doctrine, publish/follow/fork etiquette, auto-attached event-watch verification, and noise/duplicate tuning. Read when the user mentions news, headlines, tweets, social posts, catalysts, or briefs, wants an alert on anything that arrives as text rather than a price, asks what news feeds they have, or complains about duplicate or noisy news pings.event-watches.md— creation, discovery, lifecycle, and on-demand journal retrieval for watched event streams.research.md— correlational event studies over accepted event-watch rows and one asset's candles. Read when the user asks whether a watched event stream coincided with market moves, wants to inspect event anchors, or wants pre/post returns around events.signal.md— theom signalproducer surface: the four signal kinds (text_long_short,constant,metric_level_rule,metric_band_rule) and their tunables — topic-as-policy, context/memory, model pins, the decision cache, bar/tick evaluation + cooldown, and the identity-change (force) guard. Read when the user asks what signal kinds or signal settings exist, wants to create or tune a signal on its own, or asks why a signal edit was refused. For binding a signal to a market and trading it,strategy.mdis the continuation.strategy.md— author and operate daemon-native, signal-driven strategies end to end (anom signal— over an event-watch or a market metric — bound to a pinned market as anom strategy, armed withom strategy resume, verified under the running daemon; executes on the Polymarket CLOB or Hyperliquid). Read when the user wants to wire an event/news or metric signal to automated trading, asks how a strategy runs, or asks why one is not trading.rooms-docs.md— the living-docs layer of OM Rooms chat: the space library (one head per doc, CAS revisions, om://doc pills) and thedoc_*lane verbs (list/read/search/history/write plus move/revert/archive/restore/access). Read when working inside a chat room with files or docs: the user asks what files are in this channel, wants a conversation captured into a doc, references an om://doc pill, or asks to edit, rename, file, revert, share, archive, or restrict a doc.secrets.md— sealed (end-to-end encrypted) chat messages:/secret, recipient cards, recovery codes. Read for private/sealed sends or secret recovery.
Channels
om setup <name> pairs an outbound notification channel. Routing is materialized — an alert stores exactly its top-level channels: string[] (channel ids), and there is no read-time fan-out. A create with no channels[] is seeded to the configured default channel (set via om setup default <name>), or the lone channel when only one is configured; with several channels and no default set the create is refused (pass --channel <name> or set a default: om setup default <name>); with no channels configured it is card-only (no push, no agent take). Pairing the very first channel also routes any still-card-only alerts and watches onto it, so specs authored before a channel existed get a real destination (a later second channel re-homes nothing).
| Channel | Setup |
|---|---|
telegram |
om setup telegram --token <bot-token> --chat-id <id> (or interactive) |
discord |
om setup discord --webhook-url <url> (or interactive) |
slack |
om setup slack --webhook-url <url> (or interactive) |
webhook |
om setup webhook --webhook-url <url> [--bearer-token <token>] (generic JSON POST to any http(s) endpoint; alert fires carry a structured alert block) |
Interactive mode (no credential flags) prompts for the channel name first (defaulting to the adapter id, e.g. telegram / discord) before collecting credentials — same as om init. Pass --name <name> to skip that prompt and supply the name on the command line. Pass --default to mark the new channel as the default for alerts without an explicit channels[] field.
Default-channel management: om setup default (show current), om setup default <name> (promote), om setup default --clear (drop the marker; with several channels a no-channels[] create is then refused until you set a default or name channels). om setup list shows a DEFAULT column with * next to the default row.
Per-channel view and routing: om channel <name> (name, id, or default) shows one channel's bound conversation thread and every alert and watch routed to it, and takes --add <alert-id|watch-slug> / --remove <alert-id|watch-slug> to route a spec on or off it, --rename <new-name> to rename the channel (its routes follow), and --format json. It flags a spec whose fire would post plainly here (this channel past the wake cap) and footnotes any other channel that shares the same chat.
System lifecycle messages (runner started / stopping, alert paused / resumed) always fan out to every configured channel — the default-channel preference only applies to alert fires.
om setup openclaw is a separate flow — it installs the OM skill into a local OpenClaw and registers OpenClaw's webhook as a passthrough target (raw receipt JSON, no rendering by the runner).
The runner
om service install registers a launchd (macOS) or systemd --user (Linux) unit that runs the tick loop in the background. It re-reads ~/.openmarket/alerts/*.json each tick (default 10s, override via --interval-ms), evaluates every alert, fires whenever the condition is TRUE (recurring mode) or once-and-terminates (once mode), and dispatches to configured channels via direct HTTPS POST. Edge semantics live in the leaf operator (crosses_above / crosses_below) for typed conditions, and in the script body for custom-script conditions — the runner itself is dumb. Lifecycle: om service [start|stop|restart|status|logs|uninstall]. Foreground mode (om run, no --service) is the dev-loop variant — same evaluator, no daemonization. Native Windows uses foreground only (no Task Scheduler integration yet).
The per-tick log line in runner.log has the form [tick] scanned=[ids] evaluated=[ids] fired=[ids] errors=[ids]. Each bracketed list is the set of alert IDs in that bucket, not a numeric tuple — scanned=[2,1] means alerts 2 and 1 were scanned, fired=[2] means alert 2 fired this tick.
Whenever the runner is up — foreground om run or background om service install — it also exposes a local HTTP surface on :31337: /healthz, /rpc/v1/alert/* (CRUD over HTTP), /events/v1 (SSE stream — alert_fired, event_watch_fired, channel_delivered, channel_failed, tick_completed), /api/v1/* (REST proxy to upstream), /ws/v1/* (WebSocket proxy). Most om alert * CLI commands route through /rpc/v1/alert/* when the runner is reachable and fall back to direct filesystem writes when it isn't, so authoring works either way. om alert watch is the one command that needs the runner (it consumes /events/v1).
Bundling into the binary
The compiled om binary embeds these files via Bun's text-import so om skill show [name] works without the repo on disk:
// packages/cli/src/skills/package.ts
import skill from "../../../../skills/SKILL.md" with { type: "text" };
import alerts from "../../../../skills/alerts.md" with { type: "text" };
import orders from "../../../../skills/orders.md" with { type: "text" };
import metrics from "../../../../skills/metrics.md" with { type: "text" };
import marketplace from "../../../../skills/marketplace.md" with { type: "text" };
import chartActions from "../../../../skills/chart-actions.md" with { type: "text" };
import eventWatches from "../../../../skills/event-watches.md" with { type: "text" };
import news from "../../../../skills/news.md" with { type: "text" };
import research from "../../../../skills/research.md" with { type: "text" };
import signal from "../../../../skills/signal.md" with { type: "text" };
import strategy from "../../../../skills/strategy.md" with { type: "text" };
om skill list enumerates them; om skill show [name] prints one to stdout.
Installed copies omit the generated command reference below: with a shell available, om --help and om <command> --help are the live surface, always current with the installed binary.
Command reference
-
om block-sizes(action:block_sizes) — List supported heatmap block sizes — values you can pass as--block-sizeto a BLOCK_BOOK_SNAPSHOT_AGG points query. -
om coins(action:coins) — List supported base coins (BTC, ETH, …) optionally filtered by metadata. -
om config— (bespoke; see narrative above) -
om config key-info(action:config_key_info) — Decode the configured OpenMarket API key (a JWT) and surface its claims — tier, account id (sub), token id (jti), issued/expires timestamps. -
om config show(action:config_show) — Inspect the local OpenMarket CLI configuration: which API key is currently in use (returned masked, with the source — env vs stored), whether an OM_API_KEY env var is shadowing a different stored key, which notification channels (telegram / discord / openclaw / …) are configured — each with theidan alert's or watch'schannels[]refers to, so you can name where a spec posts instead of quoting a raw id — which channel is the create-time default for new alerts that name no destination, and whether anonymous fleet telemetry (telemetry.fleet) is enabled. -
om enum(action:enum) — Dump known enum values from the SDK — exchanges, data types, intervals, sort fields, polymarket fields, etc. -
om exchanges(action:exchanges) — List exchanges matching the given filters. -
om logs(action:logs_tail) — Return the most recent N lines from the runner daemon'srunner.log(plus rotated archives, walked oldest-first). -
om markets(action:markets) — List tradeable markets, filtered by exchange / coin / category / type and optional symbol substring. -
om normalized-symbols(action:normalized_symbols) — List canonical normalized symbols (e.g. BTC-USDT) matching the given metadata filters. -
om points(action:points) — Fetch historical market data: candles (TRADE_SIDE_AGNOSTIC_AGG), open interest (OPEN_INTEREST_AGG), funding rates (FUNDING_RATE_AGG), liquidations (LIQUIDATION_AGG), volume profiles, TPO sessions, heatmap snapshots. -
om polymarket leaderboard(action:polymarket_leaderboard) — Top Polymarket wallets ranked by PnL, ROI, win rate, volume, or activity. -
om polymarket market-summary(action:polymarket_market_summary) — Aggregate stats (total volume, trader count, top wallets) for one Polymarket market. -
om polymarket platform-distribution(action:polymarket_platform_distribution) — Distribution of Polymarket traders / volume / activity across configurable percentile or decile bands. -
om polymarket platform-summary(action:polymarket_platform_summary) — Platform-wide Polymarket aggregates — total traders, volume, market count. -
om polymarket positions(action:polymarket_positions) — Polymarket position rows. -
om polymarket trader-profile(action:polymarket_trader_profile) — Full Polymarket stats for one trader wallet — realised/unrealised PnL, position count, win rate, holding duration. -
om polymarket user-categories(action:polymarket_user_categories) — Category breakdown (election / sports / crypto / …) of one trader's activity. -
om send(action:send_message) — Send a one-shot message to a configured channel (telegram / discord / generic webhook / …). -
om service— (bespoke; see narrative above) -
om service install(action:service_install) — Install the OpenMarket daemon as a launchd plist (macOS) or systemd --user unit (Linux). -
om service logs(action:logs_tail) — Return the most recent N lines from the runner daemon'srunner.log(plus rotated archives, walked oldest-first). -
om service restart(action:service_restart) — Stop and start the OpenMarket daemon via the supervisor (launchd: bootout + bootstrap; systemd: native restart). -
om service start(action:service_start) — Start the OpenMarket daemon (no-op if already running). -
om service status(action:service_status) — Report install + run state of the local OpenMarket daemon (launchd/systemd unit). -
om service stop(action:service_stop) — Stop the OpenMarket daemon. -
om service uninstall(action:service_uninstall) — Stop the OpenMarket daemon and remove its launchd plist / systemd unit. -
om status(action:system_status) — Probe every stateful local fact in one call: version state (CLI build, daemon build, latest release, update available?), daemon running?, API key configured (masked + source)?, LLM auth (provider/model/profile/credential-type), notification channels + default, venues paired (Hyperliquid: address + builder approval + network; Polymarket: signer + funder + wallet type + network), active alert count, event-watch count, settings overrides (history_turns, per-provider model). -
om symbols(action:symbols) — List raw exchange-native symbols matching the given metadata filters. -
om tenors(action:tenors) — List option tenors (ONE_W, ONE_M, …) available for the given metadata filters. -
om upgrade(action:system_upgrade) — Update the om binary to the latest release and restart the daemon on it. -
om usage(action:usage) — Report current API quota usage for the authenticated account —limit(weight per window),used,remaining,reset(unix seconds),window_seconds. -
om wrun create(action:wrun_create) — Scaffold a WRUN authoring workspace. -
om wrun list(action:wrun_list) — List installed WRUN packages and metric ids. -
om wrun source set(action:wrun_source_set) — Pin a Polymarket market as a WRUN odds input.