Stores durable facts in a categorized, plain-markdown vault on disk, alongside your agent's built-in memory.
Documents
ipython-analyst
Try itRun Python interactively to analyze data, debug code, profile performance, validate schemas, process large files, and inspect ASTs. Use this whenever the user needs hands-on Python execution — debugging a script, profiling slow code, regex stress-testing, parsing CSV/Excel/JSON, building ML baseline
What it does
Execute Python interactively for data analysis, code debugging, profiling, and scientific computing. Variables, imports, models, and figures persist across calls within the same session — build up state incrementally instead of re-running everything from scratch.
The skill document
IPython Analyst v7
Execute Python interactively for data analysis, code debugging, profiling, and scientific computing. Variables, imports, models, and figures persist across calls within the same session — build up state incrementally instead of re-running everything from scratch.
File Paths
| Path | Purpose |
|---|---|
/home/z/my-project/upload/ | User uploaded files (read) |
/home/z/my-project/download/ | Generated outputs (write — only place the user can download from) |
Workflow
-
Classify the task using the decision tree below. Pick the right reference file and script.
-
Read the matching reference (one file, not all of them) for domain-specific patterns and pitfalls.
-
Execute code via the ipython tool. Variables persist — reuse them. Save long-running setup (data loads, model fits) once.
-
For non-trivial utilities, import from
scripts/rather than re-typing the class. Each script is self-contained, tested, and imports cleanly. Add the scripts directory tosys.pathonce per session, then use normal imports:import sys SCRIPTS = '/home/z/my-project/skills/ipython-analyst/scripts' if SCRIPTS not in sys.path: sys.path.insert(0, SCRIPTS) # Then import as normal modules — no exec(), no open().read() from safe_execution import timeout_context, OperationTimeout from debug_utils import summarize_exception, post_mortem from code_analyzer import CodeAnalyzer, analyze_scriptThis is safer than
exec(open(...).read())because Python's import machinery validates the file is a proper module, caches it, and won't re-execute on subsequent imports. The scripts directory contains only skill-owned helper code; do not add untrusted paths tosys.path. -
Save final outputs to
/home/z/my-project/download/with descriptive filenames. Use the user's language for any labels or text in outputs. -
Present results with a brief explanation and the download path. Don't dump 500 lines of repr — summarize.
Decision Tree — Pick Your Reference
Read only the reference file that matches the task. Loading all of them wastes context.
| User wants… | Read this reference | Use these scripts |
|---|---|---|
| Debug a script (pdb, post-mortem, tracebacks, exceptions) | references/debugging.md | scripts/debug_utils.py, scripts/safe_execution.py |
| Profile slow code (CPU, memory, line-by-line) | references/debugging.md § Profiling | scripts/profiler.py |
| Analyze CSV/Excel/JSON, build a chart, compute stats | references/data-analysis.md | (uses pandas/numpy/seaborn inline) |
| Build ML baseline (classify/regress/cluster) | references/machine-learning.md | (uses sklearn inline) |
| Analyze a graph (centrality, communities, paths) | references/network-analysis.md | (uses networkx inline) |
| Static code analysis (complexity, smells, AST) | references/code-analysis.md | scripts/code_analyzer.py, scripts/dependency_analyzer.py, scripts/parse_tree.py |
| Debug a regex (risks, stress test, catastrophic backtracking) | references/code-analysis.md § Regex | scripts/regex_debugger.py |
| Run a function with mocked deps (filesystem, modules, env) | references/code-analysis.md § Isolation | scripts/function_isolator.py |
| Validate JSON/CSV against a schema | references/schema-validation.md | scripts/schema_validator.py |
| Generate edge-case tests for a parser | references/schema-validation.md § Test Gen | scripts/test_generator.py |
| Validate text chunking preserves data | references/schema-validation.md § Chunking | scripts/chunking_validator.py |
| Diff two outputs (regression testing, baseline compare) | references/schema-validation.md § Differ | scripts/output_differ.py |
| Parse and summarize log files | references/environment.md § Logs | scripts/log_analyzer.py |
| Detect format of an unknown file/content | references/environment.md § Format | scripts/format_detector.py |
| Verify installed packages / extract imports from a script | references/environment.md § Env | scripts/env_check.py |
| Process large CSV without OOM (chunked, streaming) | references/distributed.md | scripts/distributed.py |
| Parallel map / Dask cluster / parallel groupby | references/distributed.md | scripts/distributed.py |
| Track session memory, compress dormant variables | references/environment.md § Session | scripts/session_manager.py |
If multiple rows match, read the most specific one first (e.g., for "profile my regex", read code-analysis.md § Regex first, then debugging.md § Profiling if you need broader profiling context).
Available Libraries (verified in this environment)
| Category | Libraries |
|---|---|
| Data | pandas, numpy, dask (optional) |
| Visualization | matplotlib, seaborn, plotly |
| Statistics | scipy.stats, statsmodels |
| Optimization | scipy.optimize, PuLP |
| Symbolic | sympy, mpmath |
| ML | scikit-learn, torch (CPU) |
| Networks | networkx |
| Images | PIL, opencv |
| Code analysis | ast, dis, inspect, tokenize |
| Profiling | cProfile, pstats, tracemalloc |
| Testing | unittest, pytest |
| Compression | zlib, gzip, pickle, joblib |
| Distributed | multiprocessing, concurrent.futures, dask |
| Progress | tqdm (optional) |
Target Python 3.11+. Use modern features where they help: X | Y type unions, match/case, ExceptionGroup/TaskGroup for concurrent fan-out, tomllib for TOML parsing, fine-grained error locations in tracebacks.
Core Principles
1. Persist state, don't redo work
The ipython tool keeps variables across calls. Use this — load data once, then run multiple analyses on df without re-reading the file. Same for trained models, parsed ASTs, compiled regexes. Re-running 30 seconds of setup because you forgot to reuse df is a real cost.
2. Reach for scripts/ before rewriting
Each script in scripts/ is the polished version of a utility — bugs fixed, edge cases handled, tested. If you need a RegexDebugger, CodeAnalyzer, SchemaValidator, etc., load the script. Only hand-roll when the script genuinely doesn't fit (and if it's a recurring need, add it to the script).
3. Timeouts on unbounded work
Any regex match, parser run, or external call that might hang needs a timeout. Use safe_execution.timeout_context(seconds) (SIGALRM-based, interrupts blocking C code). This is mandatory for regex stress tests — catastrophic backtracking will otherwise lock the session.
4. Memory matters for big data
For files >500MB or DataFrames >2GB: stream with distributed.process_large_file(output_path=...) (writes chunks to disk, never accumulates in memory), or use DaskProcessor as a context manager (with DaskProcessor() as dp: ... — closes the cluster, prevents zombie processes).
5. Charts → use the charts skill
This skill produces diagnostic figures (a quick scatter to see a distribution, a profile plot). For publication-quality charts, dashboards, mind maps, or any deliverable where the chart is the final artifact, use the dedicated charts skill instead — it has proper layout engines, color systems, and per-chart-type recipes.
6. Don't shadow builtins
A common v6 bug was class TimeoutError(Exception) which shadowed the builtin TimeoutError and silently broke code that caught the builtin. v7 uses a distinct name (OperationTimeout) — preserve this.
Scripts Index
All scripts live at /home/z/my-project/skills/ipython-analyst/scripts/. Each is self-contained. To use them, add the directory to sys.path once, then import normally:
import sys
SCRIPTS = '/home/z/my-project/skills/ipython-analyst/scripts'
if SCRIPTS not in sys.path: sys.path.insert(0, SCRIPTS)
# Now: from debug_utils import post_mortem, summarize_exception
| Script | What it gives you |
|---|---|
safe_execution.py | resource_limits, timeout_context, OperationTimeout, safe_eval |
session_manager.py | SessionManager, VariableInfo, memory_report |
debug_utils.py | post_mortem, format_exception, extract_traceback, summarize_exception, breakpoint_helper |
code_analyzer.py | CodeAnalyzer, FunctionMetrics, ClassMetrics, analyze_script |
dependency_analyzer.py | DependencyAnalyzer, analyze_dependencies |
regex_debugger.py | RegexDebugger, debug_regex |
function_isolator.py | FunctionIsolator (mock modules, files, env) |
profiler.py | Profiler, profile decorator (memory + CPU) |
schema_validator.py | SchemaValidator, SchemaField, validate_schema |
test_generator.py | TestCaseGenerator, TestCase, generate_tests |
chunking_validator.py | ChunkingValidator, validate_chunking |
log_analyzer.py | LogAnalyzer, analyze_logs |
output_differ.py | OutputDiffer, BaselineManager, compare_outputs |
parse_tree.py | ParseTreeVisualizer, visualize_ast (DOT/SVG/PNG) |
format_detector.py | FormatDetector, detect_format |
distributed.py | DistributedProcessor, DaskProcessor, parallel_apply, process_large_csv |
env_check.py | check_requirements, verify_environment, _extract_imports |
Quick Recipes
Setup for all recipes: Add scripts to
sys.pathfirst:import sys SCRIPTS = '/home/z/my-project/skills/ipython-analyst/scripts' if SCRIPTS not in sys.path: sys.path.insert(0, SCRIPTS)
Debug a script that just crashed
from debug_utils import post_mortem, summarize_exception, format_exception
# Drop into post-mortem on the last uncaught exception:
post_mortem() # opens pdb at the failing frame
# Or summarize without entering pdb:
summary = summarize_exception(exc) # returns dict with type, message, frames, locals
Profile a slow function
from profiler import Profiler
result = Profiler().profile_both(my_func, *args) # CPU + memory in one pass
print(result['cpu']['stats'][:2000]) # top 20 by cumtime
print(f"Peak: {result['memory']['peak_mb']:.1f} MB")
Stress-test a regex for catastrophic backtracking
from regex_debugger import RegexDebugger
db = RegexDebugger(r'^(a+)+$')
print(db.detect_risks()) # [{'type': 'nested_quantifier', ...}]
print(db.stress_test(0.5)) # {'passed': 4, 'timeouts': 2, 'errors': 0}
Validate JSON against a schema
from schema_validator import SchemaField, validate_schema
schema = {
'name': SchemaField(type=str, required=True),
'age': SchemaField(type=int, min_value=0, max_value=150),
'email': SchemaField(type=str, pattern=r'^[\w.]+@[\w.]+$'),
}
result = validate_schema(data, schema)
print(result['errors'])
Process a large CSV in chunks (no OOM)
from distributed import process_large_csv
def agg(chunk): return chunk.groupby('product')['revenue'].sum()
result = process_large_csv(
'/home/z/my-project/upload/sales.csv',
process_func=agg, chunk_size=50_000,
output_path='/home/z/my-project/download/agg_by_product.csv',
show_progress=True,
)
Detect file format (with debug)
from format_detector import detect_format
with open('/home/z/my-project/upload/mystery.txt') as f: content = f.read()
fmt = detect_format(content, debug=True)
Output Guidelines
- Charts: PNG, dpi=150–200. Prefer
constrained_layout=Trueonplt.subplots()— do NOT combine it withtight_layout()orbbox_inches='tight'(they conflict and silently break margins). For legends, usebbox_to_anchoroutside the plot area, notloc='best'. - Data: CSV with
index=False; JSON for nested structures; joblib for ML models. - Language: Match the user's language for every text element (titles, labels, legends, captions). If you must deviate, explain why once.
- Naming: Descriptive filenames —
revenue_by_product_q4.pngnotchart1.png. - Reproducibility: Set seeds (
np.random.seed(42),random_state=42) for any ML or stochastic work.
What NOT to Use This Skill For
- Polished charts/dashboards → use the
chartsskill (proper layout engines, palettes, per-type recipes). - Word/PDF/Excel deliverables → use
docx/pdf/xlsxskills. - Building a Next.js web app → use
fullstack-devskill. - One-shot "write me a fib function" → just answer; don't invoke the skill.
- Image generation / VLM / TTS → use those specific media skills.
Bug Fixes Since v6
For reviewers familiar with v6, here's what changed. These were all real bugs found in v6's utilities; the v7 scripts have them fixed.
verify_environmentnow passes correct import names ('PIL'not'pil','cv2'stays'cv2') — v6 lowercased names so the check always reported Pillow/OpenCV as missing.OperationTimeoutreplaces the v6class TimeoutError(Exception)that shadowed the builtin and brokeexcept TimeoutError:callers.FormatDetector._score_formatnow scoresweightfor the first match (wasweight * 0.5); additional matches still add diminishing amounts, capped atweight.SchemaValidator._validate_fieldremoved the redundant ternary —isinstance(value, field.type)works for both single types and tuples.DistributedProcessor.process_large_fileno longer pre-reads the whole file just to count rows for the progress bar. It estimates from file size or counts chunks as they arrive.CodeAnalyzer._analyze_functionnow countsexcepthandlers, comprehensions, ternaries, boolean operators, andmatch/caseas branches. v6 only countedIf/For/Whileand missedast.ExceptHandler(a 2-except-handler function was reported as complexity 1),ast.ListComp/SetComp/DictComp/GeneratorExp,ast.IfExp(ternary),ast.BoolOp(and/orshort-circuits), andast.Match.resource_limitssaves and restores the original soft limit (was resetting toRLIM_INFINITYwhich silently fails when the hard limit is lower, and could leave the process with the wrong limit).SessionManager._get_object_sizereturns0on error (not-1) solist_variablestotals aren't distorted by failure.DependencyAnalyzerandenv_check._extract_importsusenode.names(correct) instead ofnode.aliases(doesn't exist onast.Import/ast.ImportFrom— v6 always raisedAttributeErroron any script with imports).
Security Hardening (post-v7.0 audit)
After publishing v7.0, a ClawHub security audit flagged 8 findings. I verified each against the actual code and confirmed 7 of them (1 was a false positive — the auditor misread a reference-file header as a skill-level activation trigger). The confirmed issues are fixed in v7.1:
safe_evalno longer useseval()(was AST2 / HIGH). Replaced with an AST-walking evaluator that whitelists node types (literals, arithmetic/comparison/boolean operators, calls to whitelisted functions) and rejects attribute access, subscripting, comprehensions, and lambdas — closing the().__class__.__subclasses__()escape path.allowed_namesnow validates that injected values are scalars or callables only (no modules, no dunder-named keys).exec(open(...).read())removed from all code examples (was LP3 + SQP-2). Replaced withsys.path.insert(0, SCRIPTS); from import— Python's import machinery validates the file is a proper module, caches it, and won't re-execute on subsequent imports. All 28 occurrences across SKILL.md + 5 reference files updated.test_generator.stress_testcorrectly tracks pass/fail (was SDI-4). The v7.0 implementation never incrementedfailed, and treated both "parser raised" and "parser accepted" aspassed— silently producing misleading results. The new implementation takesshould_accept/should_rejectpredicates per case, classifies each case's expected outcome, and incrementsfailedwhen the parser does the opposite of expected. Timeouts are always counted as failures.debug_utils.extract_traceback/format_exception/summarize_exceptiondefault to no locals (was SQP-2 × 2). Locals may contain credentials, PII, tokens, or other sensitive runtime state. The default is nowinclude_locals=False/show_locals=False; passTrueexplicitly for interactive debugging only.summarize_exceptiongained aninclude_localsparameter (was hardcoded toTrue).references/debugging.mdwarns about sensitive data in failing inputs (was SQP-2). The "save failing input to disk" guidance now says: treat the input as potentially sensitive, prefer in-memory repros, redact or synthesize before saving, ask the user for approval before persisting real inputs. Added a new "Sensitive Data in Debugging Output" section documenting the locals-exposure trade-off across all threedebug_utilshelpers.
Best Practices
- Memory: Use
SessionManagerfor accurate memory tracking. DataFrame sizes usememory_usage(deep=True); numpy arrays usenbytes. - Timeout: Wrap any regex/parser/IO call that might block in
timeout_context. Catastrophic backtracking will hang the session otherwise. - Large files:
process_large_csv(output_path=...)streams to disk.parallel_mapfor CPU-bound fan-out.DaskProcessoras awithblock for lazy evaluation on big data. - Profiling: For performance-critical code, always profile both CPU and memory — they often tell different stories. A function that's fast but allocates 5GB will OOM at scale.
- Reproducibility: Set seeds for any stochastic operation. Pin
random_state=42in sklearn,torch.manual_seed(42)in torch. - Untrusted code: Use
check_requirements(script_path)to see what a script imports before running it. Usesafe_evalfor user-supplied expressions (it restricts builtins and only exposesmath).
Related skills
Generate and edit Draw.io, Mermaid, and Excalidraw diagrams from natural language using a structured JSON spec.
Find why your productivity system keeps failing, then apply the smallest fix — capacity math, bottleneck routing, durable local notes.
Join a video meeting as an AI bot with voice, avatar, and screenshare across four operating modes.
Read and write Excel workbooks, worksheets, ranges, tables, and charts in OneDrive through Microsoft Graph with managed OAuth.
Fetch raw ad creative, app, ranking, and revenue data from AdMapix as structured JSON.
More from darkd
Browse all skillsResume multi-step tasks after session crashes with minimal-footprint checkpointing.
Detect where short-term optimization is building long-term fragility, dead ends, or collapse.
Comprehensive self-contained interpretation methodology for analyzing ANY text, statement, system, behavior, artifact, or phenomenon through multiple integra...
Comprehensive guide to runic wisdom, divination, and magic. Covers Elder Futhark (24 runes), Northumbrian runes (33 total + Solle + Wyrd = 35-rune divination...
Produce complete, publish-ready AI/ML datasets in HuggingFace format (parquet shards + README.md with YAML frontmatter + dataset card + provenance script). Use whenever the user wants to create, build, produce, assemble, package, or publish a dataset for training, fine-tuning, evaluation, benchmark.