Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 17 additions & 15 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@
- Captures are flat by default: nesting in pattern ≠ nesting in output
- `{...} @x` or `[...] @x` creates a nested scope
- Scalar list (no internal captures): `(x)* @a` → `a: T[]`
- Row list (with internal captures): `{(x) @x}* @rows` → `rows: { x: T }[]`
- **Strict dimensionality**: `*`/`+` with internal captures requires row capture
- Row list (with internal captures): `(x @y)* @rows` → `rows: { y: T }[]`
- **Strict dimensionality**: `*`/`+` with internal captures requires row capture on the quantifier

## Alternations

Expand Down Expand Up @@ -111,15 +111,17 @@ Rule: anchor is as strict as its strictest operand.

## Type System Rules

**Strict dimensionality**: Quantifiers with internal captures require explicit row capture:
**Strict dimensionality**: Quantifiers with internal captures require a row capture on the quantifier:

```
{(a) @a (b) @b}* ; ERROR: internal captures, no row capture
{(a) @a (b) @b}* @rows ; OK: rows: { a: Node, b: Node }[]
(func (id) @name)* ; ERROR: internal capture without row
{(func (id) @name) @f}* @funcs ; OK: funcs: { f: Node, name: Node }[]
(func (id) @name)* ; ERROR: no row capture
(func (id) @name)* @funcs ; OK: funcs: { name: Node }[]
{(a) @a (b) @b}* ; ERROR: no row capture
{(a) @a (b) @b}* @rows ; OK: rows: { a: Node, b: Node }[]
```

Note: `{}` is for grouping siblings into a sequence, not for satisfying dimensionality.

**Optional bubbling**: `?` does NOT require row capture (no dimensionality added):

```
Expand Down Expand Up @@ -170,15 +172,15 @@ docs/

Run: `cargo run -p plotnik -- <command>`

| Command | Purpose |
| ------- | ----------------------------- |
| Command | Purpose |
| ------- | ------------------------------- |
| `ast` | Show AST of query and/or source |
| `check` | Validate query |
| `dump` | Show compiled bytecode |
| `infer` | Generate TypeScript types |
| `exec` | Execute query, output JSON |
| `trace` | Trace execution for debugging |
| `langs` | List supported languages |
| `check` | Validate query |
| `dump` | Show compiled bytecode |
| `infer` | Generate TypeScript types |
| `exec` | Execute query, output JSON |
| `trace` | Trace execution for debugging |
| `langs` | List supported languages |

## ast

Expand Down
92 changes: 48 additions & 44 deletions docs/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

```sh
# Explore a source file's tree-sitter AST
plotnik tree app.ts
plotnik ast app.ts

# Validate a query against a grammar
plotnik check -q 'Func = (function_declaration) @fn' -l typescript
Expand All @@ -22,38 +22,41 @@ plotnik langs

## Commands

| Command | Input | Purpose | `-l` flag |
| ------- | ------ | ------------------------- | ------------------------------------- |
| `tree` | source | Explore tree-sitter AST | Inferred from extension |
| `dump` | query | Show bytecode | Optional (enables linking) |
| `check` | query | Validate query | Optional (enables grammar validation) |
| `infer` | query | Generate type definitions | Required |
| `exec` | both | Run query, output JSON | Inferred from extension |
| `langs` | — | List supported languages | — |
| Command | Input | Purpose | `-l` flag |
| ------- | ----- | ------------------------------- | ------------------------------------- |
| `ast` | both | Show AST of query and/or source | Inferred from extension |
| `dump` | query | Show bytecode | Optional (enables linking) |
| `check` | query | Validate query | Optional (enables grammar validation) |
| `infer` | query | Generate type definitions | Required |
| `exec` | both | Run query, output JSON | Inferred from extension |
| `trace` | both | Trace query execution | Inferred from extension |
| `langs` | — | List supported languages | — |

---

### tree
### ast

Explore a source file's tree-sitter AST. Use this to discover node kinds and structure.
Show AST of query and/or source file. Use this to discover node kinds and structure.

```sh
# Show tree-sitter AST
plotnik tree app.ts
# Show tree-sitter AST of source file
plotnik ast app.ts

# Include anonymous nodes (literals, punctuation)
plotnik tree app.ts --raw
# Show query AST
plotnik ast query.ptk

# Show both query and source AST
plotnik ast query.ptk app.ts

# Show source positions
plotnik tree app.ts --spans
# Include anonymous nodes (literals, punctuation)
plotnik ast app.ts --raw
```

**Flags:**

| Flag | Purpose |
| --------- | -------------------------------------------------- |
| `--raw` | Include trivia (whitespace, comments, punctuation) |
| `--spans` | Show source positions |
| Flag | Purpose |
| ------- | ----------------------------------------------- |
| `--raw` | Include anonymous nodes (literals, punctuation) |

---

Expand Down Expand Up @@ -121,14 +124,15 @@ plotnik infer -q 'Q = (identifier) @id' -l js --no-node-type --no-export

**Flags:**

| Flag | Purpose |
| ------------------- | ---------------------------------- |
| `-l, --lang LANG` | Target language grammar (required) |
| `-o, --output FILE` | Write output to file |
| `--format FORMAT` | Output format (`typescript`, `ts`) |
| `--verbose-nodes` | Include line/column in Node type |
| `--no-node-type` | Don't emit Node/Point definitions |
| `--no-export` | Don't add `export` keyword |
| Flag | Purpose |
| ------------------- | --------------------------------------------- |
| `-l, --lang LANG` | Target language grammar (required) |
| `-o, --output FILE` | Write output to file |
| `--format FORMAT` | Output format (`typescript`, `ts`) |
| `--verbose-nodes` | Include line/column in Node type |
| `--no-node-type` | Don't emit Node/Point definitions |
| `--no-export` | Don't add `export` keyword |
| `--void-type TYPE` | Type for void results (`undefined` or `null`) |

### langs

Expand Down Expand Up @@ -218,16 +222,16 @@ plotnik trace query.ptk app.js -vv # very verbose

## Input Modes

### Query-Only Commands (tree, check, dump, infer)
### Query-Only Commands (check, dump, infer)

These commands take a single input. Use either:

- **Positional**: `plotnik tree app.ts` or `plotnik dump query.ptk`
- **Flag**: `plotnik tree -s 'let x' -l js` or `plotnik dump -q 'Q = ...'`
- **Positional**: `plotnik dump query.ptk`
- **Flag**: `plotnik dump -q 'Q = ...'`

### Query+Source Commands (exec, trace)
### Query+Source Commands (ast, exec, trace)

These commands take two inputs. Use any combination:
These commands can take query, source, or both inputs. Use any combination:

| Pattern | Query from | Source from |
| -------------------------------- | -------------- | -------------- |
Expand Down Expand Up @@ -256,7 +260,7 @@ Use `-` as the file argument:
echo 'Q = (identifier) @id' | plotnik dump -

# Source from stdin
cat app.ts | plotnik tree -
cat app.ts | plotnik ast -

# Exec: query from stdin, source from file
echo 'Q = (identifier) @id' | plotnik exec - app.js
Expand All @@ -271,7 +275,7 @@ echo 'Q = (identifier) @id' | plotnik exec - app.js
1. **Explore the source AST** to understand node structure:

```sh
plotnik tree example.ts
plotnik ast example.ts
```

2. **Write a query and validate** against the grammar:
Expand Down Expand Up @@ -307,7 +311,7 @@ Func = (function_declaration
```

```sh
plotnik infer --query-file queries/functions.ptk -l typescript -o types.d.ts
plotnik infer queries/functions.ptk -l typescript -o types.d.ts
```

---
Expand Down Expand Up @@ -342,12 +346,12 @@ help: did you mean 'function_declaration'?

Common errors:

| Error | Cause | Fix |
| --------------------------------- | ------------------------------------ | --------------------------------------------- |
| `unknown node type` | Typo in node kind | Check `plotnik debug -s file` for valid types |
| `missing closing )` | Unclosed tree pattern | Match parentheses |
| `expected expression` | Invalid syntax | Check query syntax |
| `strict dimensionality violation` | Quantified captures need row wrapper | Use `{...}* @rows` pattern |
| Error | Cause | Fix |
| --------------------------------- | ------------------------------------ | ---------------------------------------- |
| `unknown node type` | Typo in node kind | Check `plotnik ast file` for valid types |
| `missing closing )` | Unclosed tree pattern | Match parentheses |
| `expected expression` | Invalid syntax | Check query syntax |
| `strict dimensionality violation` | Quantified captures need row wrapper | Use `{...}* @rows` pattern |

---

Expand All @@ -362,7 +366,7 @@ Common errors:

## Tips

1. **Start with `tree`** to explore unfamiliar codebases
1. **Start with `ast`** to explore unfamiliar codebases
2. **Use `--raw`** to see all tokens including literals
3. **Run `check`** before `infer` to catch grammar errors early
4. **Use `dump`** to debug query parsing or bytecode
Expand Down