data-scientist skill
Processes and analyzes data with resident-kernel engines (DuckDB, Polars) and one-shot tools. Use for CSV/parquet/JSON analysis, group-by/join/aggregation, time series, distributions, cleaning, or plotting a dataset.
Is the data-scientist skill safe?
Serious findings: read the flagged lines first. We read 11 files in the folder on 2026-09-28.
- high
references/uv-setup.md:19Downloads a script and runs it in one step, so what runs is whatever that server sends that day. Common for installers, and still worth a look at the address.
curl -LsSf https://astral.sh/uv/install.sh | sh # official installer → ~/.local/bin/uv - high
scripts/setup-uv.sh:39Downloads a script and runs it in one step, so what runs is whatever that server sends that day. Common for installers, and still worth a look at the address.
curl -LsSf https://astral.sh/uv/install.sh | sh
Install the data-scientist skill
A skill is a folder. Copy it into your agent's skills folder and the agent loads it when the task matches its description. Read the findings above first.
git clone --depth 1 https://github.com/code-yeongyu/oh-my-openagent.git /tmp/oh-my-openagent mkdir -p ~/.claude/skills cp -r /tmp/oh-my-openagent/packages/shared-skills/skills/data-scientist ~/.claude/skills/data-scientist
In the Claude apps, zip the folder and upload it from the Skills settings. The folder on GitHub
The instructions your agent would load
SKILL.md as published, without the frontmatter. Read it on GitHub
Data Scientist: Hybrid-Engine Data Processing
Answer data questions through the cheapest engine and surface that can prove the answer, and decide where the computation should live before touching the data.
Execution surfaces: resident kernel first
A persistent REPL/eval kernel (many harnesses expose one for JavaScript and Python) is the default surface. Reason: each one-shot process pays roughly a second of spawn-plus-import overhead and re-scans the input file, while a resident connection amortizes both — after a one-time load, repeat queries return in milliseconds. Exploration is repeat queries, so this difference dominates the session.
import path for @duckdb/node-api. Dynamic-import it, connect once, query across cells.
- JavaScript kernel (Bun): run scripts/ensure-js-deps.sh once; it prints the absolute
typically resident; Polars and pyarrow come from scripts/ensure-py-deps.sh, which installs them once into a user cache keyed to the kernel's interpreter — sys.path.insert the printed directory and import. The interpreter itself is never mutated.
- Python kernel: the default surface for Python work. duckdb/numpy/matplotlib are
should not take the kernel down.
- uv lane (uv run --with ...): isolation for a heavy or crash-prone one-shot that
DuckDB-js, uv run python -c for the Python stack — batching several questions per process.
- No kernel (plain-shell harness): the same engines as one-shots — bun -e for
Per-surface patterns and pitfalls: read references/execution-surfaces.md before first use.
Engine selection
window functions. It queries CSV/Parquet/JSON in place without loading, spills to disk past its memory limit, and reads remote files with the same syntax.
- DuckDB for SQL-shaped work: direct file queries, joins, aggregation, subqueries,
streaming datasets past RAM — resident in the Python kernel via ensure-py-deps.sh. Read references/polars-lane.md — the current 1.x API differs from widely-memorized older spellings.
- Polars when the pipeline is DataFrame-shaped: expression-chain transforms, reshapes,
linear algebra, FFT, random sampling.
- numpy when numeric work goes beyond SQL/DataFrame aggregation: statistical tests,
quality bar and a mandatory visual check.
- matplotlib for every chart — read references/visualization.md first; it carries the
Performance folklore ("X is Nx faster at filtering") varies with data shape, cardinality, and hardware. When the engine choice materially matters, measure on the actual data instead of trusting remembered multipliers.
Placement: decide where the computation lives
Probe before you compute — one cell: file size, free RAM, and (when unclear) a row count via a direct scan. Then place the work:
the session will run repeated queries: CREATE TABLE t AS SELECT ... (or a collected DataFrame) once, then iterate. One scan up front converts every later query from a file re-scan into milliseconds.
- Load into memory when the working set stays within roughly a quarter of free RAM AND
DuckDB reads files directly (FROM 'data.csv'); past RAM, cap DuckDB's memory and let it spill, or use Polars' streaming engine in the Python kernel. NEVER load a larger-than-RAM dataset fully into memory — swapping stalls the whole machine, while streaming merely takes longer.
- Query in place / stream when the question is single-pass, or the data exceeds RAM:
Parquet and CSV with projection and predicate pushdown, so fetch the columns and rows the question needs, never the whole file. When data sits on another machine you can execute on, ship the query to the data and return the small result. Rule: result much smaller than data — move the query; repeated local iteration planned — move a pruned copy of the data once.
- Query remotely, in place when the data lives elsewhere: DuckDB reads http(s)/S3
Sizing heuristics and recipes: references/placement.md.
Hard rules
covers, and the environments this skill assumes do not ship it — .df() on a DuckDB result raises unless pandas is installed; convert with .pl() via Arrow instead.
- NEVER use pandas. DuckDB and Polars beat it decisively on every workload this skill
- Excel files are not read directly: export to CSV or Parquet first.
Output contract
Answer the question; report row counts and timing for anything heavy; then stop — no bonus charts, no extra exploration passes beyond what the question needed. Chart when asked, or when the answer is a shape (trend, distribution, comparison) that prose cannot carry — then follow references/visualization.md including its visual QA step.
References
CLI fallback
When no kernel or REPL surface exists, uv run scripts/quick-query.py [SQL] (--filter , --describe) answers ad-hoc questions with zero code. Supports CSV, Parquet, JSON, NDJSON.
More skills from code-yeongyu/oh-my-openagent
- Aast-grepSearches and rewrites code by AST shape across 25 languages. Use when the target is a syntax pattern (every call/class/import shaped like X, a codemod, a YAML rule) rather than literal text; for plain strings, comments, or filenames, use rg.
- AbrowserDrives a real browser through the omowright library from the js eval kernel: sites the user is already signed into, forms and clicks, JS-rendered pages, screenshots, web QA, extension popups, a human handoff for login, CAPTCHA or OTP, and a browser you own for scraping, bot-scored targets, network capture and QA traces. Use for any interactive browser task; not for a plain search or an unblocked static fetch.
- Acodex-qaQA the omo Codex Light edition (lazycodex / packages/omo-codex) itself, in strict isolation so ONLY our plugin is exercised, never the user's real ~/.codex. The first-party method drives the real `codex app-server` against an isolated CODEX_HOME plus a LOCAL mock model (no real API call), and proves a plugin hook fired by asserting hook/started + hook/completed notifications. Also: isolated install verification, per-component hook probes, a tmux TUI smoke, and runtime log observation (RUST_LOG / logs SQLite / /debug-config). Ships tested helper scripts each with a --self-test. Use whenever someone changes anything under packages/omo-codex or wants to QA, smoke-test, verify, or debug the Codex plugin, its hooks/components, the installer/config.toml, the app-server flow, or the Codex TUI. Triggers: codex qa, qa codex, codex-qa, test codex plugin, verify codex hook, codex app-server, lazycodex qa, isolated CODEX_HOME, prove codex hook fired, codex tui test.
- Acoding-agent-sessionsFinds, reads, and reconstructs coding-agent sessions across Codex, Claude, OpenCode, OMO/Senpi, and other local agent logs. Use when asked to find or search past sessions, transcripts, or subagent runs, or to recover what an earlier session did.
- Acomment-checkerUse when Codex needs to understand or respond to automatic comment-checker feedback emitted after an edit-like PostToolUse hook.
- Adag-libraryStores a DAG definition once and re-runs it by name, instead of pasting the definition into every run. Use when the user wants to save a DAG, run a saved one, or schedule the same multi-agent graph repeatedly.
- AdebuggingRuns a hypothesis-driven debugging loop across any language or binary, escalating to orthogonal oracle angles and locking the fix with a failing test. Use for crashes, silent failures, hangs, wrong responses, memory leaks, async misbehavior, or reverse engineering.
- Adev-browserBrowser automation with persistent page state. Use when users ask to navigate websites, fill forms, take screenshots, extract web data, test web apps, or automate browser workflows. Trigger phrases include "go to [url]", "click on", "fill out the form", "take a screenshot", "scrape", "automate", "test the website", "log into", or any browser interaction request.
- CfrontendBuilds, styles, and polishes web UI and UX. Use for any frontend, page, component, styling, layout, animation, or visual-quality task, or when asked to make an interface look or feel a certain way.
- AfrontendBuilds, styles, and polishes web UI and UX. Use for any frontend, page, component, styling, layout, animation, or visual-quality task, or when asked to make an interface look or feel a certain way.
- Aget-unpublished-changesCompare HEAD with the latest published npm versions and list all unpublished changes by release layer. Triggers: unpublished changes, changelog, what changed, whats new.
- Agit-masterHandles git work: atomic commits, rebase, squash, blame, bisect, reflog, and history questions. Use whenever a task needs a commit or a git-history investigation; skip for ordinary code edits.