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
49 changes: 35 additions & 14 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ Tree-sitter: `((a) (b))` — Plotnik: `{(a) (b)}`. The #1 syntax error.
```
crates/
plotnik-cli/ # CLI tool
src/commands/ # Subcommands (debug, docs, exec, langs, types)
src/commands/ # Subcommands (debug, exec, langs, types)
plotnik-core/ # Common code
plotnik-lib/ # Plotnik as library
src/
Expand All @@ -172,23 +172,44 @@ docs/

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

| Command | Purpose |
| ------- | ------------------------------- |
| `debug` | Inspect queries and source ASTs |
| `exec` | Execute query, output JSON |
| `types` | Generate TypeScript types |
| `langs` | List supported languages |
| Command | Purpose | Status |
| ------- | ------------------------------- | ------- |
| `debug` | Inspect queries and source ASTs | Working |
| `types` | Generate TypeScript types | Working |
| `langs` | List supported languages | Working |
| `exec` | Execute query, output JSON | Not yet |

Common: `-q/--query <Q>`, `--query-file <F>`, `--source <S>`, `-s/--source-file <F>`, `-l/--lang <L>`
## debug

`debug`: `--only-symbols`, `--cst`, `--raw`, `--spans`, `--arities`, `--graph`, `--graph-raw`, `--types`
`exec`: `--pretty`, `--verbose-nodes`, `--check`, `--entry <NAME>`
`types`: `--format <F>`, `--root-type <N>`, `--verbose-nodes`, `--no-node-type`, `--no-export`, `-o <F>`
Inspect query AST/CST or parse source files with tree-sitter.

```sh
cargo run -p plotnik-cli -- debug -q '(identifier) @id' --graph -l javascript
cargo run -p plotnik-cli -- exec -q '(identifier) @id' -s app.js --pretty
cargo run -p plotnik-cli -- types -q '(identifier) @id' -l javascript -o types.d.ts
cargo run -p plotnik-cli -- debug -q 'Test = (identifier) @id'
cargo run -p plotnik-cli -- debug -q 'Test = (identifier) @id' --only-symbols
cargo run -p plotnik-cli -- debug -q 'Test = (identifier) @id' --types
cargo run -p plotnik-cli -- debug -s app.ts
cargo run -p plotnik-cli -- debug -s app.ts --raw
```

Options: `--only-symbols`, `--cst`, `--raw`, `--spans`, `--arities`, `--types`

## types

Generate TypeScript type definitions from a query. Requires `-l/--lang` to validate node types against grammar.

```sh
cargo run -p plotnik-cli -- types -q 'Test = (identifier) @id' -l javascript
cargo run -p plotnik-cli -- types --query-file query.ptk -l typescript -o types.d.ts
```

Options: `--root-type <N>`, `--verbose-nodes`, `--no-node-type`, `--no-export`, `-o <F>`

## langs

List supported tree-sitter languages.

```sh
cargo run -p plotnik-cli -- langs
```

# Coding Rules
Expand Down
23 changes: 11 additions & 12 deletions crates/plotnik-cli/src/commands/debug/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,20 +40,13 @@ pub fn run(args: DebugArgs) {
None
};

let mut query = query_source.as_ref().map(|src| {
let query = query_source.as_ref().map(|src| {
Query::try_from(src.as_str()).unwrap_or_else(|e| {
eprintln!("error: {}", e);
std::process::exit(1);
})
});

// Auto-link when --lang is provided with a query
if args.lang.is_some()
&& let Some(ref mut _q) = query
{
unimplemented!();
}

let show_query = has_query_input && !args.symbols && !args.graph && !args.types;
let show_source = has_source_input;

Expand Down Expand Up @@ -81,11 +74,17 @@ pub fn run(args: DebugArgs) {
);
}

// Build graph if needed for --graph, --graph-raw, or --types
if (args.graph || args.graph_raw || args.types)
&& let Some(_) = query.take()
if args.graph || args.graph_raw {
eprintln!("error: --graph and --graph-raw are not yet implemented");
std::process::exit(1);
}

if args.types
&& let Some(ref q) = query
{
unimplemented!();
let output =
plotnik_lib::query::type_check::emit_typescript(q.type_context(), q.interner());
print!("{}", output);
}

if show_source {
Expand Down
4 changes: 3 additions & 1 deletion crates/plotnik-cli/src/commands/exec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,9 @@ pub fn run(args: ExecArgs) {

let _ = (args.pretty, args.verbose_nodes, args.check, args.entry);

todo!("IR emission and query execution not yet implemented")
eprintln!("error: query execution not yet implemented");
eprintln!("hint: use `plotnik types` to generate TypeScript types from queries");
std::process::exit(1);
}

fn load_query(args: &ExecArgs) -> String {
Expand Down
36 changes: 25 additions & 11 deletions crates/plotnik-cli/src/commands/types.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
#![allow(dead_code)]

use std::fs;
use std::io::{self, Read};
use std::io::{self, Read, Write};
use std::path::PathBuf;

use plotnik_langs::Lang;
use plotnik_lib::Query;
use plotnik_lib::query::type_check::{EmitConfig, emit_typescript_with_config};

pub struct TypesArgs {
pub query_text: Option<String>,
Expand All @@ -32,7 +31,7 @@ pub fn run(args: TypesArgs) {
}
let lang = resolve_lang_required(&args.lang);

// Parse and validate query
// Parse and analyze query
let query = Query::try_from(query_source.as_str())
.unwrap_or_else(|e| {
eprintln!("error: {}", e);
Expand All @@ -45,13 +44,25 @@ pub fn run(args: TypesArgs) {
std::process::exit(1);
}

// Link query against language
if !query.is_valid() {
eprint!("{}", query.diagnostics().render(query.source_map()));
std::process::exit(1);
}
// Emit TypeScript types
let config = EmitConfig {
export: args.export,
emit_node_type: !args.no_node_type,
root_type_name: args.root_type,
verbose_nodes: args.verbose_nodes,
};

unimplemented!();
let output = emit_typescript_with_config(query.type_context(), query.interner(), config);

// Write output
if let Some(ref path) = args.output {
fs::write(path, &output).unwrap_or_else(|e| {
eprintln!("error: failed to write {}: {}", path.display(), e);
std::process::exit(1);
});
} else {
io::stdout().write_all(output.as_bytes()).unwrap();
}
}

fn load_query(args: &TypesArgs) -> String {
Expand All @@ -66,7 +77,10 @@ fn load_query(args: &TypesArgs) -> String {
.expect("failed to read stdin");
return buf;
}
return fs::read_to_string(path).expect("failed to read query file");
return fs::read_to_string(path).unwrap_or_else(|e| {
eprintln!("error: failed to read query file: {}", e);
std::process::exit(1);
});
}
unreachable!("validation ensures query input exists")
}
Expand Down
Loading