Skip to content

CLI Quickstart

The graft CLI is a convenience wrapper around repository-mode SQLite pragmas. It also includes an embedded SQLite runner:

Terminal window
graft sql "SELECT 1;"

That command opens app.db through the embedded Graft VFS. You do not need to load libgraft_ext manually.

From the repository root:

Terminal window
cargo build -p graft-tool --bin graft --release

The binary is written to:

target/release/graft

Add it to your PATH however you prefer. For example:

Terminal window
mkdir -p ~/.local/bin
ln -sf "$(pwd)/target/release/graft" ~/.local/bin/graft
hash -r
graft --help
  1. Create a project directory.

    Terminal window
    mkdir graft-demo
    cd graft-demo
  2. Initialize the repository.

    Terminal window
    graft init

    This creates .graft/ next to app.db.

  3. Create and query data.

    Terminal window
    graft sql "CREATE TABLE users(id INTEGER PRIMARY KEY, name TEXT);"
    graft sql "INSERT INTO users(name) VALUES ('Alice'); SELECT * FROM users;"
  4. Check status.

    Terminal window
    graft status

    You should see untracked: app.db.

  5. Stage and commit.

    Terminal window
    graft add app.db
    graft commit -m "seed users"
  6. Modify the database again.

    Terminal window
    graft sql "INSERT INTO users(name) VALUES ('Bob'); SELECT * FROM users ORDER BY id;"
    graft status

    You should see modified: app.db.

  7. Commit the second snapshot and diff it.

    Terminal window
    graft add app.db
    graft commit -m "add bob"
    graft diff HEAD~1 HEAD app.db

If no SQL argument is passed, graft sql reads stdin:

Terminal window
cat <<'SQL' | graft sql
CREATE TABLE notes(id INTEGER PRIMARY KEY, body TEXT);
INSERT INTO notes(body) VALUES ('hello from stdin');
SELECT * FROM notes;
SQL

For scripts, you can initialize and write data in a single batch:

Terminal window
cat <<'SQL' | graft sql
PRAGMA graft_init;
CREATE TABLE users(id INTEGER PRIMARY KEY, name TEXT);
INSERT INTO users(name) VALUES ('Alice');
SELECT * FROM users;
SQL

Most commands map directly to repository pragmas:

graft status -> PRAGMA graft_status
graft add app.db -> PRAGMA graft_add = 'app.db'
graft commit -m "msg" -> PRAGMA graft_commit = 'msg'
graft diff HEAD~1 HEAD -> PRAGMA graft_diff = 'HEAD~1 HEAD'

That means the CLI and extension share the same semantics. The CLI should not grow a separate repository model.