Metadata-Version: 2.4
Name: chewy-constellations
Version: 0.1.1
Summary: Local Terraform infrastructure graph indexer for Constellations
Author: Andrew Nguyen
Author-email: anguyen7@chewy.com
Requires-Python: >=3.10,<4.0
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Requires-Dist: PyYAML (>=6.0,<7.0)
Requires-Dist: mcp (>=1.9,<2.0)
Requires-Dist: neo4j (>=5.20,<6.0)
Requires-Dist: pydantic (>=2.8,<3.0)
Requires-Dist: tfparse (>=0.6.0)
Description-Content-Type: text/markdown

# Constellations

Just as ancient navigators used constellations to understand the night sky,
Constellations maps relationships between infrastructure and code into a
connected graph that can be explored, queried, and understood. Each resource is
a star. Each dependency is a line. Together, they form a local map of the
system.

Constellations is local-first. A developer runs one local Neo4j server, indexes
one or more repositories into graph snapshots, merges those snapshots when
cross-repository relationships matter, and queries the graph through the CLI or
MCP.

## What It Does

Constellations scans a service or infrastructure repository and creates a graph
fragment for that repo.

Current extraction supports:

- Terraform `aws_lambda_function`, `aws_sqs_queue`, and
  `aws_lambda_event_source_mapping`
- Java Gradle repositories from `settings.gradle`, `settings.gradle.kts`,
  `build.gradle`, and `build.gradle.kts`
- `Repository` and `CodeModule` nodes for Java modules
- `${ENV_VAR}` placeholders in base `application.yml` and `application.yaml`
- Lambda environment variables from Terraform
- Evidence on nodes and relationships, including file path and line numbers

Current merge behavior can derive cross-repository relationships such as:

- `SQSQueue -[:TRIGGERS]-> LambdaFunction`
- `LambdaFunction -[:RUNS_CODE]-> CodeModule`
- `CodeModule -[:WRITES_TO]-> SQSQueue`

The graph also preserves unresolved references and isolated nodes so users can
see where more repo context is needed.

## Install

```bash
pip install chewy-constellations
```

For local development in this folder:

```bash
pip install -r requirements.txt
```

Or with Poetry:

```bash
poetry install
```

## Core Workflow

1. Start Neo4j once on the developer machine.
2. Index each service or infrastructure repo into a local graph snapshot.
3. Merge indexed snapshots when questions need cross-repo traversal.
4. Write the merged graph to Neo4j with `--neo4j`.
5. Run the MCP server and ask questions from an MCP client.

## Local Neo4j

Start the local Neo4j server:

```bash
constellations start
```

The bundled Docker Compose setup installs APOC Core for local development and
persists plugin jars under `.constellations/neo4j/plugins`.

Neo4j Browser:

```text
http://localhost:7474
```

Default local connection:

```text
NEO4J_URI=bolt://localhost:7687
NEO4J_USERNAME=neo4j
NEO4J_PASSWORD=constellations
```

Stop the local server:

```bash
constellations stop
```

## Index A Repo

Run from a Terraform root or Java Gradle repository:

```bash
constellations index
```

You can also index a path without changing directories:

```bash
constellations index --path ../aggregator/wizmo-aggregator-lambda-terraform/terraform
```

Useful options:

```bash
constellations index \
  --repo wizmo-aggregator-lambda-terraform \
  --graph aggregator-infra \
  --service aggregator
```

Force a repository type when auto-detection is not desired:

```bash
constellations index --repo-type terraform
constellations index --repo-type java
```

`index` writes repo-local artifacts:

```text
.constellations/resources.json
.constellations/snapshot.json
.constellations/graphs.json
```

- `resources.json` is the raw parsed input model.
- `snapshot.json` is the Constellations graph fragment with nodes, edges,
  evidence, and unresolved references.
- `graphs.json` registers the snapshot locally and also updates the user-level
  registry at `~/.constellations/graphs.json`.
- `--output-dir` must point to the indexed repository's `.constellations`
  directory or under `~/.constellations`; other locations fail without writing
  metadata.

To index and immediately write that graph fragment to Neo4j:

```bash
constellations index --neo4j
```

## Inspect And Review

Inspect defaults to `.constellations/snapshot.json` in the current directory:

```bash
constellations inspect
```

It can also inspect a repository directory or a snapshot file:

```bash
constellations inspect ../aggregator/wizmo-aggregator-lambda-terraform/terraform
constellations inspect ../aggregator/wizmo-aggregator-lambda-terraform/terraform/.constellations/snapshot.json
```

Use inspection and the generated JSON to review:

- which nodes and relationships were created
- which source files and line numbers support each graph fact
- which references remain unresolved
- which nodes are isolated after merge
- which relationships were extracted directly versus resolved during merge

List registered local and global graphs:

```bash
constellations graphs
constellations graphs --local
constellations graphs --global
```

Assign aliases to registered graphs:

```bash
constellations alias wizmo-consumers consumers-code
constellations alias wizmo-consumers-lambda-terraform consumers-infra
```

## Merge For Multi-Repo Questions

Single-repo indexing remains the base workflow. Multi-repo composition happens
by merging existing graph snapshots into a derived graph snapshot.

From a workspace directory, `merge` can discover one-level-deep snapshots:

```bash
constellations merge
```

It looks for:

```text
./*/.constellations/snapshot.json
```

You can also pass repository directories:

```bash
constellations merge \
  ../api/wizmo-nebula2-terraform/terraform \
  ../aggregator/wizmo-aggregator-lambda-terraform/terraform \
  ../aggregator/wizmo-aggregator-lambda
```

Or pass snapshot files directly:

```bash
constellations merge \
  ../api/wizmo-nebula2-terraform/terraform/.constellations/snapshot.json \
  ../aggregator/wizmo-aggregator-lambda-terraform/terraform/.constellations/snapshot.json \
  ../aggregator/wizmo-aggregator-lambda/.constellations/snapshot.json
```

Or pass registered graph names and aliases:

```bash
constellations merge consumers-code consumers-infra --graph wizmo
```

When `--graph` or `--name` is omitted, the merged graph name defaults to:

```text
merged_graph
```

When `--output` is omitted, the merged snapshot is written to:

```text
~/.constellations/merged_graphs/<graph>.snapshot.json
```

Write the merged graph to Neo4j so the MCP server can query it:

```bash
constellations merge snapshot1.json snapshot2.json --neo4j
```

Use a custom graph name when needed:

```bash
constellations merge snapshot1.json snapshot2.json --graph wizmo-dev --neo4j
```

Refresh a previously registered merged graph from the same source snapshots:

```bash
constellations merge --refresh merged_graph --neo4j
```

Merged graphs are registered in the user-level registry:

```text
~/.constellations/graphs.json
```

They do not create a `.constellations/graphs.json` in the directory where the
merge command happens to run.

## Push An Existing Snapshot

`push` writes an existing snapshot into Neo4j. Use it when the snapshot already
exists and you do not need to rebuild it.

```bash
constellations push
```

`push` can also accept a repository directory or snapshot file:

```bash
constellations push ../aggregator/wizmo-aggregator-lambda-terraform/terraform
constellations push ../aggregator/wizmo-aggregator-lambda-terraform/terraform/.constellations/snapshot.json
```

The `--neo4j` flag is for commands that create snapshots, such as `index`,
`from-json`, and `merge`. The `push` command is already a Neo4j write.

## MCP Server

Run the MCP server against the local Neo4j graph:

```bash
constellations mcp --graph merged_graph
```

If Neo4j contains exactly one Constellations graph, `--graph` can be omitted.
When multiple graphs exist, pass `--graph` to avoid ambiguity.

Useful connection options:

```bash
constellations mcp \
  --neo4j-uri bolt://localhost:7687 \
  --neo4j-user neo4j \
  --neo4j-password constellations \
  --graph merged_graph
```

### Use With Codex

After installing the package and writing a graph to Neo4j, register the MCP
server in Codex. Codex starts stdio MCP servers from its config, so the server
does not need to be started separately in another terminal.

Add this to `~/.codex/config.toml`, or to a trusted project's
`.codex/config.toml`:

```toml
[mcp_servers.constellations]
command = "constellations"
args = [
  "mcp",
  "--neo4j-uri", "bolt://localhost:7687",
  "--neo4j-user", "neo4j",
  "--neo4j-password", "constellations",
  "--graph", "merged_graph",
]
```

Restart Codex or start a new Codex session after changing MCP config. In the
Codex CLI TUI, `/mcp` shows active MCP servers.

The MCP server exposes these tools:

- `list_graphs`: list Constellations graphs currently stored in Neo4j.
- `index_repo`: index a local Java or Terraform repository and optionally
  write the indexed graph to Neo4j.
- `merge_graphs`: merge snapshot files, repository directories, registered
  graph names, or aliases and optionally write the merged graph to Neo4j.
- `graph_summary`: summarize labels, edge types, repositories, and unresolved
  references.
- `find_resources`: find nodes by text, label, isolated status, or inferred
  relationships.
- `ask_graph`: answer a natural-language question with bounded Neo4j traversal
  context.
- `readonly_cypher`: run a graph-scoped read-only Cypher query.

It also exposes resources:

```text
constellations://graphs
constellations://graph/{graph}/summary
constellations://graph/{graph}/isolated
constellations://graph/{graph}/inferred
```

## Architecture

For model details, relationship derivation, saved-resource rebuilds, and current
scope, see [docs/architecture.md](docs/architecture.md).

