A framework for AI-driven economic activity. Declarative, composable, observable, deterministic.
# Add to your Claude Code skills
git clone https://github.com/OpenWhale-Org/OpenWhaleLast scanned: 5/30/2026
{
"issues": [
{
"type": "npm-audit",
"message": "esbuild: esbuild enables any website to send any requests to the development server and read the response",
"severity": "medium"
},
{
"type": "npm-audit",
"message": "vite: Vite Vulnerable to Path Traversal in Optimized Deps `.map` Handling",
"severity": "medium"
},
{
"type": "npm-audit",
"message": "vite-node: Vulnerability found",
"severity": "medium"
},
{
"type": "npm-audit",
"message": "vitest: Vulnerability found",
"severity": "medium"
}
],
"status": "PASSED",
"scannedAt": "2026-05-30T16:20:07.657Z",
"npmAuditRan": true,
"pipAuditRan": true
}OpenWhale is an open-source ai agents skill for AI coding assistants such as Claude Code, Codex CLI, and ChatGPT, built by OpenWhale-Org. A framework for AI-driven economic activity. Declarative, composable, observable, deterministic. It has 142 GitHub stars.
Yes. OpenWhale passed SkillsLLM's automated security scan — a dependency vulnerability audit plus prompt-injection heuristics — with no high-severity issues. You can read the full report in the Security Report section on this page.
Clone the repository with "git clone https://github.com/OpenWhale-Org/OpenWhale" and add it to your Claude Code skills directory (see the Installation section above).
OpenWhale is primarily written in TypeScript. It is open-source under OpenWhale-Org on GitHub, so you can review or fork the full source.
Yes. SkillsLLM lists many other AI Agents skills you can browse and compare side by side. Open the AI Agents category from the badge at the top of this page, or use the Related Skills and comparison links further down to weigh OpenWhale against similar tools.
No comments yet. Be the first to share your thoughts!
⚠️ Third-Party Software Notice
This skill is third-party open-source software developed and hosted independently on GitHub. SkillsLLM is an informational directory and does not control or maintain the underlying repository.
Any security checks, ratings, or warnings displayed by SkillsLLM are automated and limited in scope. They do not constitute a security certification or guarantee that the software is safe, error-free, or free from malicious code, vulnerabilities, compromised dependencies, or prompt-injection risks.
Review the source code, permissions, dependencies, and configuration before installing or running any third-party skill. Use is at your own risk. To the maximum extent permitted by applicable law, SkillsLLM is not liable for losses arising from third-party software.
The programmable layer for composable, AI-native economic strategies
OpenWhale is a TypeScript framework for building automated economic strategies. Monitors, Strategies, and Executors are fully decoupled — the same strategy code runs on any venue, plugs into any data source, and can be written, audited, and evolved by an AI.
exchange/perp × binance, exchange/spot × hyperliquid, …). Domain packages define the vocabulary, venue packages fill the cells, and a data-driven ccxt roster ships twelve venues out of the box.skills/openwhale-dev skill that teaches any Claude the full framework contract so it can produce installable plugins with tests.| Concept | What it is |
|---|---|
| Monitor | Collects data and emits keyed records (venue:symbol, …). Declared as a contract with one or more implementations; users create per-key instances, optionally credential-bound. Emits persist as JSONL and drive triggers. |
| Strategy | Pure decision logic. Declares monitor/executor/account dependencies by label, receives triggers, returns ExecutionInstruction[]. Params split into base (required) and tunable (defaulted, AI-optimizable) zod schemas. |
| Executor | Turns instructions into venue actions through adapter sessions: retry discipline, idempotent client order ids, per-order latency and slippage capture. Credential slots resolve to sessions (by kind) or raw credential data (raw: true — e.g. a bot token); optional: true slots let instances activate unbound and the executor degrade gracefully. Strategies stay pure. |
| Instance | A strategy + params + account bindings, activated as a unit. Everything observable hangs off the instance: live events, executions, run traces, logs. |
| Account | A named entity binding a credential to an account implementation (generic or venue-specialized). Strategies read balances and positions only through their bound account's Reader. |
| Trigger | Cron schedules and monitor conditions (multi-source AND within a time window). Subscriptions keep monitors collecting without waking the strategy; a live strategy can add sources it discovers at runtime (addMonitorSource). |
| Portfolio journal | Optional instance-scoped history owned by a strategy. Strategies commit idempotent snapshots, fills, decisions, and market bars; Core stores them transactionally and derives equity, drawdown, and trade reports without knowing the strategy's trace format. |
Monitor (data collection)
↓ emit(key, data)
TriggerManager (cron + monitor conditions)
↓ StrategyContext
Strategy (rules / AI inference) → run trace persisted
↓ ExecutionInstruction[]
ExecutionQueue
↓
Executor (venue actions via adapter sessions)
plots() convention: line/bar/candles plus a sortable table kind, single- and multi-select pickers, record-window control..meta() drives the UI: sections, sliders, unit suffixes, conditional visibility, searchable market pickers (single and multi), per-value availability verdicts against the bound venue, editable row-table list params for ladders, and sandboxed interactive illustrations that redraw live as you edit values.scripts: [...]) that run on demand against the live runtime and return a monospace report: plan previews, fit inspectors, one-off audits. Params render as a small form, with live-resolved dropdowns for runtime values such as instance ids.skills/openwhale-dev and have it write the plugin.const decls = {
monitors: [{ name: 'exchange/ticker', label: 'price' }],
executors: [{ name: 'exchange/perp-trading', label: 'perp' }],
accounts: [{ account: PerpAccount, label: 'main' }],
} as const satisfies StrategyDeclarations
class MomentumStrategy extends BaseStrategy<typeof decls> {
readonly strategyId = 'momentum'
override readonly monitors = decls.monitors
override readonly executors = decls.executors
override readonly accounts = decls.accounts
readonly baseParamsSchema = z.object({
symbol: z.string().meta({ displayName: 'Symbol' }),
threshold: z.number().meta({ displayName: 'Entry price' }),
})
async evaluate(context: StrategyContext) {
const { symbol, threshold } = this.baseParamsSchema.parse(this.params.base)
const tick = context.getData('price', `${this.accountVenue('main')}:${symbol}`)
this.trace('tick:read', { tick }) // lands in the run trace
if (!tick || tick.price < threshold) return []
return [
this.instruction('perp', 'placeOrder', {
symbol, side: 'buy', type: 'market', amount: 0.01,
}),
]
}
}
const runtime = new OpenWhaleRuntime({ database, credentialStore })
runtime.loadPlugin(binancePlugin, {})
runtime.loadPlugin(hyperliquidPlugin, {})
await runtime.start()
await runtime.activate({
strategyId: 'my-plugin/momentum',
credentials: { main: 'My Binance' }, // the account binding decides the venue
params: { base: { symbol: 'BTC/USDT:USDT', threshold: 60000 } },
})
async evaluate(context: StrategyContext) {
const data = await this.monitorData('market')?.readLatest(this.accountVenue('main'))
const { action, confidence } = await this.llm({
messages: [{ role: 'user', content: JSON.stringify(data) }],
schema: z.object({
action: z.enum(['buy', 'sell', 'hold']),
confidence: z.number(),
}),
})
if (action === 'hold' || confidence < 0.7) return []
return [
this.instruction('perp', 'placeOrder', {
symbol: 'BTC/USDC:USDC', side: action, type: 'market', amount: 0.01,
}),
]
}
export const planPreview: ScriptDefinition = {
id: 'plan-preview',
name: 'Plan preview',
paramsSchema: z.object({ instance: z.string().default('') }),
paramOptions: async (runtime) => ({ instance: await listMyInstances(runtime) }),
run: async ({ params, runtime }) => ({ text: await renderPlan(runtime, params) }),
}
A plugin is a package with a default-exported factory returning its registrations:
export default definePlugin((ctx) => ({
name: 'my-plugin',
version: '1.0.0',
monitorImplementations: [ /* contract / implementation / instance model */ ],
executors: [ /* … */ ],
strategies: [ /* … */ ],
scripts: [ /* operator utilities for the Scripts page */ ],
credentialTypes: [ /* venue credential recipes: schema, raw opt-in, connectivity test */ ],
adapters: [ /* (kind × venue) matrix cells */ ],
accounts: [ /* account implementations */ ],
}))
Install from the dashboard's Plugins page — a built .js/.mjs bundle, a GitHub repository (owner/repo, or paste the address bar; optional branch/tag/commit), or an npm name or local path — or runtime.loadPlugin() in code. Components register namespaced (my-plugin/momentum); hot reload is supported.
A GitHub install is cloned and built by npm, so a repo shipping only TypeScript sources needs a prepare script in its package.json ("prepare": "npm run build"); private repos need OPENWHALE_GITHUB_TOKEN set on the engine.
A plugin's declared name is its default namespace — the my-plugin/ every id it registers is prefixed w