Replay and visualise the living architecture of a Python application.
Project description
skeleton
Skeleton is a developer-understanding tool, not a profiler. It runs a Python script under a lightweight runtime tracer and turns the observed execution into an interactive, replayable architecture map.
Core promise:
Replay and visualise the living architecture of a Python application.
Skeleton produces runtime evidence in four complementary forms:
| Surface | Purpose |
|---|---|
trace.jsonl |
Ordered public call and return events. |
snapshot.json |
Graph-shaped modules, classes, functions, instances, and edges. |
workflow.md |
LLM-readable workflow evidence with stable event and node references. |
report.html |
Interactive visual replay for humans. |
Package naming:
Product name: Skeleton
PyPI package: skeleton-replay
Import name: skeleton_replay
CLI command: skeleton
Module entry: python -m skeleton_replay
MVP workflow
pip install skeleton-replay
skeleton run path/to/script.py
Skeleton writes:
~/.skeleton/<application-name>/
trace.jsonl
snapshot.json
workflow.md
report.html
The first version is intentionally non-invasive. You do not add decorators or modify application code. The runner wraps an existing script, traces only project-local public functions and methods by default, and records safe summaries of arguments and return values.
Skeleton is opinionated about what makes large Python systems understandable.
It promotes explicit architectural actors, clear dependency direction, and I/O
decoupled from business logic. Modules are visual shells, runtime object
instances live inside the modules that define their classes, module-level public
functions live inside their modules, and instance methods live inside the object
that handled the call. Class definitions remain metadata, not runtime graph
boxes. Entrypoints, services, repositories, adapters, and ports are roles or
boundaries unless the codebase has a concrete object that owns that
responsibility. See
docs/design/software-design-principles.md
for the design principles that guide the visual model.
workflow.md is a compact text explanation of the observed run. It is designed
for humans and LLMs: event ids, node ids, caller/callee relationships, safe
examples, and known trace gaps are written in a form that can be quoted and
reasoned over without scraping the HTML report.
Install and develop
make setup
make check
Use make test for normal or targeted local pytest runs. Use make test-cov
or make check when you want the full-suite coverage gate that CI enforces.
Print the local artifact locations:
make where
Run locally from the checkout:
uv run python -m skeleton_replay run examples/app.py
Generate a stable local demo report:
make demo
The demo writes artifacts to tests/dev/.temp/skeleton-demo/ and opens
report.html in your default browser. For a headless run that writes the same
files without opening a browser, use:
make demo-no-open
Pytest tests use tmp_path, so test-generated reports live in pytest-managed
temporary directories under tests/dev/.temp/pytest/. The stable report to open
while developing the UI is:
tests/dev/.temp/skeleton-demo/report.html
Regenerate it with:
make demo-no-open
CLI
skeleton run [options] path/to/script.py [args...]
The module entrypoint is also available:
python -m skeleton_replay run [options] path/to/script.py [args...]
Options:
--project-root PATH Root used to decide which files are project-local.
--out-dir PATH Output directory. Defaults to ~/.skeleton/<application-name>.
--include PATTERN Only trace matching relative paths or module names.
--exclude PATTERN Exclude matching relative paths or module names.
--max-events N Stop writing trace events after N events.
--no-html Skip report.html generation and opening.
--no-open Do not open report.html after generation.
Output location precedence:
--out-dir PATHSKELETON_OUT_DIRSKELETON_HOME/<application-name>~/.skeleton/<application-name>
When HTML generation is enabled, Skeleton opens report.html in your default
browser at the end of the run. Use --no-open for CI, scripts, or headless
environments.
Python API
Use TraceSession when you want to generate Skeleton artifacts from Python
without shelling out to the CLI:
from pathlib import Path
from skeleton_replay import TraceSession
result = TraceSession(
project_root=Path("path/to/project"),
out_dir=Path("path/to/project/.skeleton"),
).run_script("path/to/project/app.py")
print(result.report_path)
print(result.workflow_path)
The Python API writes the same trace.jsonl, snapshot.json, workflow.md,
and optional report.html artifacts as the CLI. Unlike the CLI, it does not
open the HTML report by default; pass open_report=True when that is wanted.
See docs/api/python-api.md.
What gets traced
Skeleton uses sys.setprofile and records Python call and return events
when all of these are true:
- The frame's file is under the project root.
- The file is not in ignored local infrastructure such as
.venv,.git, or.skeleton. - The callable name is public. Names beginning with
_are ignored.
The trace identifies the module, class where practical, function or method, caller, callee, instance identity where practical, call depth, event order, timestamp, safe argument summaries, and safe return summaries.
How it works
Skeleton does not patch your source code. It uses Python's own runtime introspection:
runpy.run_path()runs the target script as__main__inside a controlled runner.sys.setprofile()receives callbacks whenever Python enters or returns from a function.- Each callback receives a frame object. From that frame Skeleton reads
frame.f_code,frame.f_globals, andframe.f_localsto identify the file, module, function name, line number, arguments, and whether the call hasself. - When
selfis present, Skeleton recordstype(self).__name__andid(self), giving a run-local object identity such asservice.Greeter@0x.... - Values are summarized immediately, then the raw objects are discarded.
That is why the report can show instance-owned methods without decorators. It is not reading class source to guess behavior; it is watching Python call real functions on real objects. The object ids are only meaningful within one run, not across processes or commits.
For more detail, see
docs/design/runtime-introspection.md.
Current scope and next integrations
Skeleton currently runs a script path:
python -m skeleton_replay run scripts/replay_checkout.py
That script can drive any kind of Python code: CLI workflows, service objects, batch jobs, web-app internals, or library calls. The application being traced does not need to be a CLI application, but v0 does need a script entrypoint that exercises the behavior.
Planned integrations:
run-module: support module execution such aspython -m my_app.cli run-demo, exposed as something likeskeleton run-module my_app.cli -- run-demo.- pytest plugin: trace selected tests or test sessions, because tests often encode real business workflows.
- live web request tracing: trace one request or handler inside a running FastAPI, Flask, Django, or Starlette app through middleware or a capture context.
- PyCharm plugin: a thin IDE frontend that invokes Skeleton with the configured interpreter and opens the generated report.
See docs/api/python-api.md,
docs/development/missing-integration-plans.md,
and docs/development/pypi-release-plan.md.
Release history is tracked in CHANGELOG.md. Keep the
changelog updated in the same pull request or commit that changes user-visible
behavior.
Event schema
Each line in .skeleton/trace.jsonl is a JSON object:
{
"schema_version": 1,
"event_type": "call",
"order": 0,
"timestamp": 1782740000.0,
"depth": 0,
"caller": null,
"callee": {
"module": "app",
"class_name": null,
"function": "main",
"qualified_name": "app.main",
"file": "/project/app.py",
"line": 10,
"node_id": "function:app.main",
"instance_id": null
},
"args": {}
}
Return events use the same endpoint shape and include return_value.
Safety model
Skeleton records summaries, not full object contents.
- Strings are truncated.
- Containers include type, length, and a small preview.
- Objects include only class name and object id.
- Argument or mapping names containing
password,token,secret,key,auth, orcredentialare redacted.
This is not a debugger replacement and not a performance profiler. It is a runtime architecture replay tool for understanding how a codebase behaves.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file skeleton_replay-0.1.3.tar.gz.
File metadata
- Download URL: skeleton_replay-0.1.3.tar.gz
- Upload date:
- Size: 34.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e5148a8906e33b876f2f22e6068272085adc704f5f44a687dc1ce154647f65b5
|
|
| MD5 |
3439f0659bc6e3694b62d69b23e13aa9
|
|
| BLAKE2b-256 |
a02b98ba620e2f3c650f3aea173d3f9df3322aee137371f770b364288a57d223
|
Provenance
The following attestation bundles were made for skeleton_replay-0.1.3.tar.gz:
Publisher:
publish.yml on ml-affairs/skeleton
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
skeleton_replay-0.1.3.tar.gz -
Subject digest:
e5148a8906e33b876f2f22e6068272085adc704f5f44a687dc1ce154647f65b5 - Sigstore transparency entry: 2026842437
- Sigstore integration time:
-
Permalink:
ml-affairs/skeleton@5bd1c404233990bf83b112fa928df677eb1cdb5e -
Branch / Tag:
refs/tags/v0.1.3 - Owner: https://github.com/ml-affairs
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@5bd1c404233990bf83b112fa928df677eb1cdb5e -
Trigger Event:
release
-
Statement type:
File details
Details for the file skeleton_replay-0.1.3-py3-none-any.whl.
File metadata
- Download URL: skeleton_replay-0.1.3-py3-none-any.whl
- Upload date:
- Size: 42.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0e94624c5f9f2cd1499d24f66931215e3d034c52071a1b2f8187ca9c4f8e1955
|
|
| MD5 |
5d05b74eaaaa7b0152f545d87969da05
|
|
| BLAKE2b-256 |
c16b87f943dc997d5be3d3cc1131d77d1d3e762df386ae5504cf61ce259ab741
|
Provenance
The following attestation bundles were made for skeleton_replay-0.1.3-py3-none-any.whl:
Publisher:
publish.yml on ml-affairs/skeleton
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
skeleton_replay-0.1.3-py3-none-any.whl -
Subject digest:
0e94624c5f9f2cd1499d24f66931215e3d034c52071a1b2f8187ca9c4f8e1955 - Sigstore transparency entry: 2026842526
- Sigstore integration time:
-
Permalink:
ml-affairs/skeleton@5bd1c404233990bf83b112fa928df677eb1cdb5e -
Branch / Tag:
refs/tags/v0.1.3 - Owner: https://github.com/ml-affairs
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@5bd1c404233990bf83b112fa928df677eb1cdb5e -
Trigger Event:
release
-
Statement type: