skeleton-replay 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (26) hide show
  1. skeleton_replay-0.1.0/LICENSE +21 -0
  2. skeleton_replay-0.1.0/PKG-INFO +346 -0
  3. skeleton_replay-0.1.0/README.md +298 -0
  4. skeleton_replay-0.1.0/pyproject.toml +82 -0
  5. skeleton_replay-0.1.0/skeleton_replay/__init__.py +7 -0
  6. skeleton_replay-0.1.0/skeleton_replay/__main__.py +6 -0
  7. skeleton_replay-0.1.0/skeleton_replay/analysis/__init__.py +14 -0
  8. skeleton_replay-0.1.0/skeleton_replay/analysis/snapshot.py +249 -0
  9. skeleton_replay-0.1.0/skeleton_replay/analysis/static.py +141 -0
  10. skeleton_replay-0.1.0/skeleton_replay/cli.py +238 -0
  11. skeleton_replay-0.1.0/skeleton_replay/interface/__init__.py +7 -0
  12. skeleton_replay-0.1.0/skeleton_replay/interface/console.py +109 -0
  13. skeleton_replay-0.1.0/skeleton_replay/interface/output_paths.py +38 -0
  14. skeleton_replay-0.1.0/skeleton_replay/interface/report_opener.py +16 -0
  15. skeleton_replay-0.1.0/skeleton_replay/reporting/__init__.py +6 -0
  16. skeleton_replay-0.1.0/skeleton_replay/reporting/html.py +43 -0
  17. skeleton_replay-0.1.0/skeleton_replay/reporting/templates/__init__.py +1 -0
  18. skeleton_replay-0.1.0/skeleton_replay/reporting/templates/report.html +1621 -0
  19. skeleton_replay-0.1.0/skeleton_replay/reporting/workflow.py +101 -0
  20. skeleton_replay-0.1.0/skeleton_replay/runtime/__init__.py +15 -0
  21. skeleton_replay-0.1.0/skeleton_replay/runtime/events.py +76 -0
  22. skeleton_replay-0.1.0/skeleton_replay/runtime/filters.py +58 -0
  23. skeleton_replay-0.1.0/skeleton_replay/runtime/tracer.py +235 -0
  24. skeleton_replay-0.1.0/skeleton_replay/safety/__init__.py +5 -0
  25. skeleton_replay-0.1.0/skeleton_replay/safety/summariser.py +86 -0
  26. skeleton_replay-0.1.0/skeleton_replay/session.py +129 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 ml-affairs
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,346 @@
1
+ Metadata-Version: 2.3
2
+ Name: skeleton-replay
3
+ Version: 0.1.0
4
+ Summary: Replay and visualise the living architecture of a Python application.
5
+ Keywords: architecture,tracing,visualization,runtime,developer-tools
6
+ Author: Christos Hadjinikolis
7
+ Author-email: Christos Hadjinikolis <christos.hadjinikolis.subs@gmail.com>
8
+ License: MIT License
9
+
10
+ Copyright (c) 2026 ml-affairs
11
+
12
+ Permission is hereby granted, free of charge, to any person obtaining a copy
13
+ of this software and associated documentation files (the "Software"), to deal
14
+ in the Software without restriction, including without limitation the rights
15
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16
+ copies of the Software, and to permit persons to whom the Software is
17
+ furnished to do so, subject to the following conditions:
18
+
19
+ The above copyright notice and this permission notice shall be included in all
20
+ copies or substantial portions of the Software.
21
+
22
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28
+ SOFTWARE.
29
+ Classifier: Development Status :: 3 - Alpha
30
+ Classifier: Environment :: Console
31
+ Classifier: Intended Audience :: Developers
32
+ Classifier: License :: OSI Approved :: MIT License
33
+ Classifier: Operating System :: OS Independent
34
+ Classifier: Programming Language :: Python :: 3
35
+ Classifier: Programming Language :: Python :: 3.11
36
+ Classifier: Programming Language :: Python :: 3.12
37
+ Classifier: Programming Language :: Python :: 3.13
38
+ Classifier: Topic :: Software Development :: Debuggers
39
+ Classifier: Topic :: Software Development :: Documentation
40
+ Classifier: Topic :: Software Development :: Quality Assurance
41
+ Maintainer: Christos Hadjinikolis
42
+ Maintainer-email: Christos Hadjinikolis <christos.hadjinikolis.subs@gmail.com>
43
+ Requires-Python: >=3.11
44
+ Project-URL: Homepage, https://github.com/ml-affairs/skeleton
45
+ Project-URL: Repository, https://github.com/ml-affairs/skeleton
46
+ Project-URL: Issues, https://github.com/ml-affairs/skeleton/issues
47
+ Description-Content-Type: text/markdown
48
+
49
+ # skeleton
50
+
51
+ [![CI](https://github.com/ml-affairs/skeleton/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/ml-affairs/skeleton/actions/workflows/ci.yml)
52
+ ![Coverage](https://img.shields.io/badge/coverage-86%25-brightgreen)
53
+ ![Python](https://img.shields.io/badge/python-3.11%2B-blue)
54
+ ![License](https://img.shields.io/badge/license-MIT-green)
55
+
56
+ ![Skeleton: replay and visualise the living architecture of your code.](docs/images/readme.png)
57
+
58
+ Skeleton is a developer-understanding tool, not a profiler. It runs a Python
59
+ script under a lightweight runtime tracer and turns the observed execution into
60
+ an interactive, replayable architecture map.
61
+
62
+ Core promise:
63
+
64
+ > Replay and visualise the living architecture of a Python application.
65
+
66
+ Skeleton produces runtime evidence in four complementary forms:
67
+
68
+ | Surface | Purpose |
69
+ | --- | --- |
70
+ | ![Trace icon](docs/images/product/trace.svg) `trace.jsonl` | Ordered public call and return events. |
71
+ | ![Snapshot icon](docs/images/product/snapshot.svg) `snapshot.json` | Graph-shaped modules, classes, functions, instances, and edges. |
72
+ | ![Workflow icon](docs/images/product/workflow.svg) `workflow.md` | LLM-readable workflow evidence with stable event and node references. |
73
+ | ![Replay icon](docs/images/product/replay.svg) `report.html` | Interactive visual replay for humans. |
74
+
75
+ Package naming:
76
+
77
+ ```text
78
+ Product name: Skeleton
79
+ PyPI package: skeleton-replay
80
+ Import name: skeleton_replay
81
+ CLI command: skeleton
82
+ Module entry: python -m skeleton_replay
83
+ ```
84
+
85
+ ## MVP workflow
86
+
87
+ ```bash
88
+ pip install skeleton-replay
89
+ skeleton run path/to/script.py
90
+ ```
91
+
92
+ Skeleton writes:
93
+
94
+ ```text
95
+ ~/.skeleton/<application-name>/
96
+ trace.jsonl
97
+ snapshot.json
98
+ workflow.md
99
+ report.html
100
+ ```
101
+
102
+ The first version is intentionally non-invasive. You do not add decorators or
103
+ modify application code. The runner wraps an existing script, traces only
104
+ project-local public functions and methods by default, and records safe
105
+ summaries of arguments and return values.
106
+
107
+ Skeleton is opinionated about what makes large Python systems understandable.
108
+ It promotes explicit architectural actors, clear dependency direction, and I/O
109
+ decoupled from business logic. Modules are visual shells, runtime object
110
+ instances live inside the modules that define their classes, module-level public
111
+ functions live inside their modules, and instance methods live inside the object
112
+ that handled the call. Class definitions remain metadata, not runtime graph
113
+ boxes. Entrypoints, services, repositories, adapters, and ports are roles or
114
+ boundaries unless the codebase has a concrete object that owns that
115
+ responsibility. See
116
+ [`docs/design/software-design-principles.md`](docs/design/software-design-principles.md)
117
+ for the design principles that guide the visual model.
118
+
119
+ `workflow.md` is a compact text explanation of the observed run. It is designed
120
+ for humans and LLMs: event ids, node ids, caller/callee relationships, safe
121
+ examples, and known trace gaps are written in a form that can be quoted and
122
+ reasoned over without scraping the HTML report.
123
+
124
+ ## Install and develop
125
+
126
+ ```bash
127
+ make setup
128
+ make check
129
+ ```
130
+
131
+ Use `make test` for normal or targeted local pytest runs. Use `make test-cov`
132
+ or `make check` when you want the full-suite coverage gate that CI enforces.
133
+
134
+ Print the local artifact locations:
135
+
136
+ ```bash
137
+ make where
138
+ ```
139
+
140
+ Run locally from the checkout:
141
+
142
+ ```bash
143
+ uv run python -m skeleton_replay run examples/app.py
144
+ ```
145
+
146
+ Generate a stable local demo report:
147
+
148
+ ```bash
149
+ make demo
150
+ ```
151
+
152
+ The demo writes artifacts to `tests/dev/.temp/skeleton-demo/` and opens
153
+ `report.html` in your default browser. For a headless run that writes the same
154
+ files without opening a browser, use:
155
+
156
+ ```bash
157
+ make demo-no-open
158
+ ```
159
+
160
+ Pytest tests use `tmp_path`, so test-generated reports live in pytest-managed
161
+ temporary directories under `tests/dev/.temp/pytest/`. The stable report to open
162
+ while developing the UI is:
163
+
164
+ ```text
165
+ tests/dev/.temp/skeleton-demo/report.html
166
+ ```
167
+
168
+ Regenerate it with:
169
+
170
+ ```bash
171
+ make demo-no-open
172
+ ```
173
+
174
+ ## CLI
175
+
176
+ ```bash
177
+ skeleton run [options] path/to/script.py [args...]
178
+ ```
179
+
180
+ The module entrypoint is also available:
181
+
182
+ ```bash
183
+ python -m skeleton_replay run [options] path/to/script.py [args...]
184
+ ```
185
+
186
+ Options:
187
+
188
+ ```text
189
+ --project-root PATH Root used to decide which files are project-local.
190
+ --out-dir PATH Output directory. Defaults to ~/.skeleton/<application-name>.
191
+ --include PATTERN Only trace matching relative paths or module names.
192
+ --exclude PATTERN Exclude matching relative paths or module names.
193
+ --max-events N Stop writing trace events after N events.
194
+ --no-html Skip report.html generation and opening.
195
+ --no-open Do not open report.html after generation.
196
+ ```
197
+
198
+ Output location precedence:
199
+
200
+ 1. `--out-dir PATH`
201
+ 2. `SKELETON_OUT_DIR`
202
+ 3. `SKELETON_HOME/<application-name>`
203
+ 4. `~/.skeleton/<application-name>`
204
+
205
+ When HTML generation is enabled, Skeleton opens `report.html` in your default
206
+ browser at the end of the run. Use `--no-open` for CI, scripts, or headless
207
+ environments.
208
+
209
+ ## Python API
210
+
211
+ Use `TraceSession` when you want to generate Skeleton artifacts from Python
212
+ without shelling out to the CLI:
213
+
214
+ ```python
215
+ from pathlib import Path
216
+
217
+ from skeleton_replay import TraceSession
218
+
219
+ result = TraceSession(
220
+ project_root=Path("path/to/project"),
221
+ out_dir=Path("path/to/project/.skeleton"),
222
+ ).run_script("path/to/project/app.py")
223
+
224
+ print(result.report_path)
225
+ print(result.workflow_path)
226
+ ```
227
+
228
+ The Python API writes the same `trace.jsonl`, `snapshot.json`, `workflow.md`,
229
+ and optional `report.html` artifacts as the CLI. Unlike the CLI, it does not
230
+ open the HTML report by default; pass `open_report=True` when that is wanted.
231
+ See [`docs/api/python-api.md`](docs/api/python-api.md).
232
+
233
+ ## What gets traced
234
+
235
+ Skeleton uses `sys.setprofile` and records Python `call` and `return` events
236
+ when all of these are true:
237
+
238
+ - The frame's file is under the project root.
239
+ - The file is not in ignored local infrastructure such as `.venv`, `.git`, or
240
+ `.skeleton`.
241
+ - The callable name is public. Names beginning with `_` are ignored.
242
+
243
+ The trace identifies the module, class where practical, function or method,
244
+ caller, callee, instance identity where practical, call depth, event order,
245
+ timestamp, safe argument summaries, and safe return summaries.
246
+
247
+ ## How it works
248
+
249
+ Skeleton does not patch your source code. It uses Python's own runtime
250
+ introspection:
251
+
252
+ - `runpy.run_path()` runs the target script as `__main__` inside a controlled
253
+ runner.
254
+ - `sys.setprofile()` receives callbacks whenever Python enters or returns from a
255
+ function.
256
+ - Each callback receives a frame object. From that frame Skeleton reads
257
+ `frame.f_code`, `frame.f_globals`, and `frame.f_locals` to identify the file,
258
+ module, function name, line number, arguments, and whether the call has
259
+ `self`.
260
+ - When `self` is present, Skeleton records `type(self).__name__` and
261
+ `id(self)`, giving a run-local object identity such as
262
+ `service.Greeter@0x...`.
263
+ - Values are summarized immediately, then the raw objects are discarded.
264
+
265
+ That is why the report can show instance-owned methods without decorators. It is
266
+ not reading class source to guess behavior; it is watching Python call real
267
+ functions on real objects. The object ids are only meaningful within one run,
268
+ not across processes or commits.
269
+
270
+ For more detail, see
271
+ [`docs/design/runtime-introspection.md`](docs/design/runtime-introspection.md).
272
+
273
+ ## Current scope and next integrations
274
+
275
+ Skeleton currently runs a script path:
276
+
277
+ ```bash
278
+ python -m skeleton_replay run scripts/replay_checkout.py
279
+ ```
280
+
281
+ That script can drive any kind of Python code: CLI workflows, service objects,
282
+ batch jobs, web-app internals, or library calls. The application being traced
283
+ does not need to be a CLI application, but v0 does need a script entrypoint that
284
+ exercises the behavior.
285
+
286
+ Planned integrations:
287
+
288
+ - `run-module`: support module execution such as
289
+ `python -m my_app.cli run-demo`, exposed as something like
290
+ `skeleton run-module my_app.cli -- run-demo`.
291
+ - pytest plugin: trace selected tests or test sessions, because tests often
292
+ encode real business workflows.
293
+ - live web request tracing: trace one request or handler inside a running
294
+ FastAPI, Flask, Django, or Starlette app through middleware or a capture
295
+ context.
296
+ - PyCharm plugin: a thin IDE frontend that invokes Skeleton with the configured
297
+ interpreter and opens the generated report.
298
+
299
+ See [`docs/api/python-api.md`](docs/api/python-api.md),
300
+ [`docs/development/missing-integration-plans.md`](docs/development/missing-integration-plans.md),
301
+ and [`docs/development/pypi-release-plan.md`](docs/development/pypi-release-plan.md).
302
+
303
+ Release history is tracked in [`CHANGELOG.md`](CHANGELOG.md). Keep the
304
+ changelog updated in the same pull request or commit that changes user-visible
305
+ behavior.
306
+
307
+ ## Event schema
308
+
309
+ Each line in `.skeleton/trace.jsonl` is a JSON object:
310
+
311
+ ```json
312
+ {
313
+ "schema_version": 1,
314
+ "event_type": "call",
315
+ "order": 0,
316
+ "timestamp": 1782740000.0,
317
+ "depth": 0,
318
+ "caller": null,
319
+ "callee": {
320
+ "module": "app",
321
+ "class_name": null,
322
+ "function": "main",
323
+ "qualified_name": "app.main",
324
+ "file": "/project/app.py",
325
+ "line": 10,
326
+ "node_id": "function:app.main",
327
+ "instance_id": null
328
+ },
329
+ "args": {}
330
+ }
331
+ ```
332
+
333
+ Return events use the same endpoint shape and include `return_value`.
334
+
335
+ ## Safety model
336
+
337
+ Skeleton records summaries, not full object contents.
338
+
339
+ - Strings are truncated.
340
+ - Containers include type, length, and a small preview.
341
+ - Objects include only class name and object id.
342
+ - Argument or mapping names containing `password`, `token`, `secret`, `key`,
343
+ `auth`, or `credential` are redacted.
344
+
345
+ This is not a debugger replacement and not a performance profiler. It is a
346
+ runtime architecture replay tool for understanding how a codebase behaves.
@@ -0,0 +1,298 @@
1
+ # skeleton
2
+
3
+ [![CI](https://github.com/ml-affairs/skeleton/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/ml-affairs/skeleton/actions/workflows/ci.yml)
4
+ ![Coverage](https://img.shields.io/badge/coverage-86%25-brightgreen)
5
+ ![Python](https://img.shields.io/badge/python-3.11%2B-blue)
6
+ ![License](https://img.shields.io/badge/license-MIT-green)
7
+
8
+ ![Skeleton: replay and visualise the living architecture of your code.](docs/images/readme.png)
9
+
10
+ Skeleton is a developer-understanding tool, not a profiler. It runs a Python
11
+ script under a lightweight runtime tracer and turns the observed execution into
12
+ an interactive, replayable architecture map.
13
+
14
+ Core promise:
15
+
16
+ > Replay and visualise the living architecture of a Python application.
17
+
18
+ Skeleton produces runtime evidence in four complementary forms:
19
+
20
+ | Surface | Purpose |
21
+ | --- | --- |
22
+ | ![Trace icon](docs/images/product/trace.svg) `trace.jsonl` | Ordered public call and return events. |
23
+ | ![Snapshot icon](docs/images/product/snapshot.svg) `snapshot.json` | Graph-shaped modules, classes, functions, instances, and edges. |
24
+ | ![Workflow icon](docs/images/product/workflow.svg) `workflow.md` | LLM-readable workflow evidence with stable event and node references. |
25
+ | ![Replay icon](docs/images/product/replay.svg) `report.html` | Interactive visual replay for humans. |
26
+
27
+ Package naming:
28
+
29
+ ```text
30
+ Product name: Skeleton
31
+ PyPI package: skeleton-replay
32
+ Import name: skeleton_replay
33
+ CLI command: skeleton
34
+ Module entry: python -m skeleton_replay
35
+ ```
36
+
37
+ ## MVP workflow
38
+
39
+ ```bash
40
+ pip install skeleton-replay
41
+ skeleton run path/to/script.py
42
+ ```
43
+
44
+ Skeleton writes:
45
+
46
+ ```text
47
+ ~/.skeleton/<application-name>/
48
+ trace.jsonl
49
+ snapshot.json
50
+ workflow.md
51
+ report.html
52
+ ```
53
+
54
+ The first version is intentionally non-invasive. You do not add decorators or
55
+ modify application code. The runner wraps an existing script, traces only
56
+ project-local public functions and methods by default, and records safe
57
+ summaries of arguments and return values.
58
+
59
+ Skeleton is opinionated about what makes large Python systems understandable.
60
+ It promotes explicit architectural actors, clear dependency direction, and I/O
61
+ decoupled from business logic. Modules are visual shells, runtime object
62
+ instances live inside the modules that define their classes, module-level public
63
+ functions live inside their modules, and instance methods live inside the object
64
+ that handled the call. Class definitions remain metadata, not runtime graph
65
+ boxes. Entrypoints, services, repositories, adapters, and ports are roles or
66
+ boundaries unless the codebase has a concrete object that owns that
67
+ responsibility. See
68
+ [`docs/design/software-design-principles.md`](docs/design/software-design-principles.md)
69
+ for the design principles that guide the visual model.
70
+
71
+ `workflow.md` is a compact text explanation of the observed run. It is designed
72
+ for humans and LLMs: event ids, node ids, caller/callee relationships, safe
73
+ examples, and known trace gaps are written in a form that can be quoted and
74
+ reasoned over without scraping the HTML report.
75
+
76
+ ## Install and develop
77
+
78
+ ```bash
79
+ make setup
80
+ make check
81
+ ```
82
+
83
+ Use `make test` for normal or targeted local pytest runs. Use `make test-cov`
84
+ or `make check` when you want the full-suite coverage gate that CI enforces.
85
+
86
+ Print the local artifact locations:
87
+
88
+ ```bash
89
+ make where
90
+ ```
91
+
92
+ Run locally from the checkout:
93
+
94
+ ```bash
95
+ uv run python -m skeleton_replay run examples/app.py
96
+ ```
97
+
98
+ Generate a stable local demo report:
99
+
100
+ ```bash
101
+ make demo
102
+ ```
103
+
104
+ The demo writes artifacts to `tests/dev/.temp/skeleton-demo/` and opens
105
+ `report.html` in your default browser. For a headless run that writes the same
106
+ files without opening a browser, use:
107
+
108
+ ```bash
109
+ make demo-no-open
110
+ ```
111
+
112
+ Pytest tests use `tmp_path`, so test-generated reports live in pytest-managed
113
+ temporary directories under `tests/dev/.temp/pytest/`. The stable report to open
114
+ while developing the UI is:
115
+
116
+ ```text
117
+ tests/dev/.temp/skeleton-demo/report.html
118
+ ```
119
+
120
+ Regenerate it with:
121
+
122
+ ```bash
123
+ make demo-no-open
124
+ ```
125
+
126
+ ## CLI
127
+
128
+ ```bash
129
+ skeleton run [options] path/to/script.py [args...]
130
+ ```
131
+
132
+ The module entrypoint is also available:
133
+
134
+ ```bash
135
+ python -m skeleton_replay run [options] path/to/script.py [args...]
136
+ ```
137
+
138
+ Options:
139
+
140
+ ```text
141
+ --project-root PATH Root used to decide which files are project-local.
142
+ --out-dir PATH Output directory. Defaults to ~/.skeleton/<application-name>.
143
+ --include PATTERN Only trace matching relative paths or module names.
144
+ --exclude PATTERN Exclude matching relative paths or module names.
145
+ --max-events N Stop writing trace events after N events.
146
+ --no-html Skip report.html generation and opening.
147
+ --no-open Do not open report.html after generation.
148
+ ```
149
+
150
+ Output location precedence:
151
+
152
+ 1. `--out-dir PATH`
153
+ 2. `SKELETON_OUT_DIR`
154
+ 3. `SKELETON_HOME/<application-name>`
155
+ 4. `~/.skeleton/<application-name>`
156
+
157
+ When HTML generation is enabled, Skeleton opens `report.html` in your default
158
+ browser at the end of the run. Use `--no-open` for CI, scripts, or headless
159
+ environments.
160
+
161
+ ## Python API
162
+
163
+ Use `TraceSession` when you want to generate Skeleton artifacts from Python
164
+ without shelling out to the CLI:
165
+
166
+ ```python
167
+ from pathlib import Path
168
+
169
+ from skeleton_replay import TraceSession
170
+
171
+ result = TraceSession(
172
+ project_root=Path("path/to/project"),
173
+ out_dir=Path("path/to/project/.skeleton"),
174
+ ).run_script("path/to/project/app.py")
175
+
176
+ print(result.report_path)
177
+ print(result.workflow_path)
178
+ ```
179
+
180
+ The Python API writes the same `trace.jsonl`, `snapshot.json`, `workflow.md`,
181
+ and optional `report.html` artifacts as the CLI. Unlike the CLI, it does not
182
+ open the HTML report by default; pass `open_report=True` when that is wanted.
183
+ See [`docs/api/python-api.md`](docs/api/python-api.md).
184
+
185
+ ## What gets traced
186
+
187
+ Skeleton uses `sys.setprofile` and records Python `call` and `return` events
188
+ when all of these are true:
189
+
190
+ - The frame's file is under the project root.
191
+ - The file is not in ignored local infrastructure such as `.venv`, `.git`, or
192
+ `.skeleton`.
193
+ - The callable name is public. Names beginning with `_` are ignored.
194
+
195
+ The trace identifies the module, class where practical, function or method,
196
+ caller, callee, instance identity where practical, call depth, event order,
197
+ timestamp, safe argument summaries, and safe return summaries.
198
+
199
+ ## How it works
200
+
201
+ Skeleton does not patch your source code. It uses Python's own runtime
202
+ introspection:
203
+
204
+ - `runpy.run_path()` runs the target script as `__main__` inside a controlled
205
+ runner.
206
+ - `sys.setprofile()` receives callbacks whenever Python enters or returns from a
207
+ function.
208
+ - Each callback receives a frame object. From that frame Skeleton reads
209
+ `frame.f_code`, `frame.f_globals`, and `frame.f_locals` to identify the file,
210
+ module, function name, line number, arguments, and whether the call has
211
+ `self`.
212
+ - When `self` is present, Skeleton records `type(self).__name__` and
213
+ `id(self)`, giving a run-local object identity such as
214
+ `service.Greeter@0x...`.
215
+ - Values are summarized immediately, then the raw objects are discarded.
216
+
217
+ That is why the report can show instance-owned methods without decorators. It is
218
+ not reading class source to guess behavior; it is watching Python call real
219
+ functions on real objects. The object ids are only meaningful within one run,
220
+ not across processes or commits.
221
+
222
+ For more detail, see
223
+ [`docs/design/runtime-introspection.md`](docs/design/runtime-introspection.md).
224
+
225
+ ## Current scope and next integrations
226
+
227
+ Skeleton currently runs a script path:
228
+
229
+ ```bash
230
+ python -m skeleton_replay run scripts/replay_checkout.py
231
+ ```
232
+
233
+ That script can drive any kind of Python code: CLI workflows, service objects,
234
+ batch jobs, web-app internals, or library calls. The application being traced
235
+ does not need to be a CLI application, but v0 does need a script entrypoint that
236
+ exercises the behavior.
237
+
238
+ Planned integrations:
239
+
240
+ - `run-module`: support module execution such as
241
+ `python -m my_app.cli run-demo`, exposed as something like
242
+ `skeleton run-module my_app.cli -- run-demo`.
243
+ - pytest plugin: trace selected tests or test sessions, because tests often
244
+ encode real business workflows.
245
+ - live web request tracing: trace one request or handler inside a running
246
+ FastAPI, Flask, Django, or Starlette app through middleware or a capture
247
+ context.
248
+ - PyCharm plugin: a thin IDE frontend that invokes Skeleton with the configured
249
+ interpreter and opens the generated report.
250
+
251
+ See [`docs/api/python-api.md`](docs/api/python-api.md),
252
+ [`docs/development/missing-integration-plans.md`](docs/development/missing-integration-plans.md),
253
+ and [`docs/development/pypi-release-plan.md`](docs/development/pypi-release-plan.md).
254
+
255
+ Release history is tracked in [`CHANGELOG.md`](CHANGELOG.md). Keep the
256
+ changelog updated in the same pull request or commit that changes user-visible
257
+ behavior.
258
+
259
+ ## Event schema
260
+
261
+ Each line in `.skeleton/trace.jsonl` is a JSON object:
262
+
263
+ ```json
264
+ {
265
+ "schema_version": 1,
266
+ "event_type": "call",
267
+ "order": 0,
268
+ "timestamp": 1782740000.0,
269
+ "depth": 0,
270
+ "caller": null,
271
+ "callee": {
272
+ "module": "app",
273
+ "class_name": null,
274
+ "function": "main",
275
+ "qualified_name": "app.main",
276
+ "file": "/project/app.py",
277
+ "line": 10,
278
+ "node_id": "function:app.main",
279
+ "instance_id": null
280
+ },
281
+ "args": {}
282
+ }
283
+ ```
284
+
285
+ Return events use the same endpoint shape and include `return_value`.
286
+
287
+ ## Safety model
288
+
289
+ Skeleton records summaries, not full object contents.
290
+
291
+ - Strings are truncated.
292
+ - Containers include type, length, and a small preview.
293
+ - Objects include only class name and object id.
294
+ - Argument or mapping names containing `password`, `token`, `secret`, `key`,
295
+ `auth`, or `credential` are redacted.
296
+
297
+ This is not a debugger replacement and not a performance profiler. It is a
298
+ runtime architecture replay tool for understanding how a codebase behaves.