Metadata-Version: 2.4
Name: spine-pkg
Version: 0.0.1
Summary: Turn any repository into a queryable Program Knowledge Graph — deterministic, provenance-carrying code facts.
Project-URL: Homepage, https://github.com/synaptixs/spine-pkg
Project-URL: Repository, https://github.com/synaptixs/spine-pkg
Project-URL: Issues, https://github.com/synaptixs/spine-pkg/issues
Author-email: Synaptixs <noreply@synaptixs.dev>
License-Expression: MIT
License-File: LICENSE
Keywords: ast,code-analysis,knowledge-graph,provenance,rdf,static-analysis
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Documentation
Classifier: Topic :: Software Development :: Libraries
Requires-Python: >=3.12
Requires-Dist: pyshacl>=0.26
Requires-Dist: rdflib>=7.0
Requires-Dist: typer>=0.12
Provides-Extra: all
Requires-Dist: openpyxl>=3.1; extra == 'all'
Requires-Dist: pypdf>=4; extra == 'all'
Requires-Dist: python-docx>=1.1; extra == 'all'
Requires-Dist: sqlglot>=25; extra == 'all'
Requires-Dist: tree-sitter-c-sharp>=0.21; extra == 'all'
Requires-Dist: tree-sitter-c>=0.21; extra == 'all'
Requires-Dist: tree-sitter-cpp>=0.21; extra == 'all'
Requires-Dist: tree-sitter-go>=0.21; extra == 'all'
Requires-Dist: tree-sitter-java>=0.21; extra == 'all'
Requires-Dist: tree-sitter-typescript>=0.21; extra == 'all'
Requires-Dist: tree-sitter>=0.21; extra == 'all'
Provides-Extra: asr
Requires-Dist: openai-whisper>=20231117; extra == 'asr'
Provides-Extra: asr-api
Requires-Dist: httpx>=0.27; extra == 'asr-api'
Provides-Extra: c
Requires-Dist: tree-sitter-c>=0.21; extra == 'c'
Requires-Dist: tree-sitter>=0.21; extra == 'c'
Provides-Extra: cpp
Requires-Dist: tree-sitter-cpp>=0.21; extra == 'cpp'
Requires-Dist: tree-sitter>=0.21; extra == 'cpp'
Provides-Extra: csharp
Requires-Dist: tree-sitter-c-sharp>=0.21; extra == 'csharp'
Requires-Dist: tree-sitter>=0.21; extra == 'csharp'
Provides-Extra: dev
Requires-Dist: mypy>=1.11; extra == 'dev'
Requires-Dist: openpyxl>=3.1; extra == 'dev'
Requires-Dist: pypdf>=4; extra == 'dev'
Requires-Dist: pytest-cov>=5; extra == 'dev'
Requires-Dist: pytest>=8; extra == 'dev'
Requires-Dist: python-docx>=1.1; extra == 'dev'
Requires-Dist: ruff>=0.6; extra == 'dev'
Requires-Dist: sqlglot>=25; extra == 'dev'
Provides-Extra: docs
Requires-Dist: pypdf>=4; extra == 'docs'
Provides-Extra: go
Requires-Dist: tree-sitter-go>=0.21; extra == 'go'
Requires-Dist: tree-sitter>=0.21; extra == 'go'
Provides-Extra: java
Requires-Dist: tree-sitter-java>=0.21; extra == 'java'
Requires-Dist: tree-sitter>=0.21; extra == 'java'
Provides-Extra: media
Requires-Dist: pillow>=10; extra == 'media'
Requires-Dist: pytesseract>=0.3.10; extra == 'media'
Provides-Extra: office
Requires-Dist: openpyxl>=3.1; extra == 'office'
Requires-Dist: python-docx>=1.1; extra == 'office'
Provides-Extra: sql
Requires-Dist: sqlglot>=25; extra == 'sql'
Provides-Extra: typescript
Requires-Dist: tree-sitter-typescript>=0.21; extra == 'typescript'
Requires-Dist: tree-sitter>=0.21; extra == 'typescript'
Description-Content-Type: text/markdown

# Spine

Turn any repository into a queryable **Program Knowledge Graph** — symbols, calls,
imports, database schema, and documentation, as universal facts that carry provenance
back to the line they came from.

Extraction is **deterministic and model-free**. The same commit in always yields the
same facts out, so the output is diffable, cacheable, and safe to gate CI on.

```bash
pip install spine-pkg
spine extract .
```

## Commands

| | |
|---|---|
| `spine extract [path]` | Scan a repo, print a summary. `--query <symbol>` shows callers and blast radius; `--json` dumps facts. |
| `spine verify [path]` | Check graph invariants — dangling edges, unresolvable provenance, unjoined imports. Exits non-zero on error, so it can stand guard in CI. |
| `spine export [path]` | Export the whole graph as `sqlite`, `graphml`, `dot`, or `json`. Never truncated. |
| `spine docs [path] -d FILE` | Reconcile documentation claims against the code graph and report drift. |
| `spine languages` | Show which language front-ends are active in this install. |
| `spine media extract PATHS` | OCR images and transcribe audio/video into reviewable artifacts. Opt-in; see below. |

## Languages

Python works out of the box with no extra dependencies. Every other front-end
lazy-imports its parser, so the base install stays small and you pay only for what
you use:

```bash
pip install 'spine-pkg[java]'        # or typescript, csharp, c, cpp, go, sql
pip install 'spine-pkg[all]'         # every front-end at once
```

If a language's extra isn't installed, its files are invisible to the graph rather
than an error — so `spine extract` counts them and tells you what to install:

```
Scanned . — 0 grounded nodes, 0 external, 0 edges.

  ! 103 Go file(s) found but NOT extracted — install the front-end:  pip install 'spine-pkg[go]'
```

`spine languages` shows the same thing ahead of time. Both warnings go to stderr, so
`extract --json` and `export` stay pipe-safe.

## Documents and media

Markdown, reStructuredText, plain text, and HTML parse with the standard library.
PDF needs `[docs]`; Word and Excel need `[office]`.

`spine media extract` is deliberately separate from the graph build. It MAY run a
model and be slow, so it is explicit and opt-in: it writes reviewable artifacts under
`.spine-media/` that you commit, and the deterministic extractor only ever reads
those. Image OCR (`[media]`, plus a system `tesseract` binary) and `--asr local`
(`[asr]`) run entirely on your machine. `--asr api` uploads audio and video
off-machine and refuses to run without an explicit `--allow-remote`.

## Caching

Facts are cached per commit under `~/.cache/spine/`, and the cache is trusted only on
a clean working tree — a dirty tree always re-extracts, because a stale graph is
worse than a slow one.

## Design notes

- **The graph is the source of truth.** Consumers render facts; they never re-derive
  them from paths or filenames. A new fact means extending `facts.py` and the
  front-ends, not the renderer.
- **Bounded output is honest output.** Aggregations cap their results and record what
  was elided. Exports are the exception — they are always complete, because the point
  of handing the graph to another tool is that its filtering is better than ours.
- **Local paths only.** `spine` scans a checkout on disk and never clones for you.

## License

MIT
