Schema-less CLI state machine for LLM agents.
No schema. No database. Just append and go.
Quick Start · Commands · Examples
A CLI-first, file-persistent state machine with no predefined schema. Define your state structure on the fly with --field key=value. Every entry is appended to an append-only JSON log.
Built for LLM agents that need to track state across tool invocations — but works for anything.
$ notch --field phase=planning --field step=1
{"entryIndex":0,"historyLength":1,"entry":{"phase":"planning","step":1}}
$ notch --field step=2 --field done=true
{"entryIndex":1,"historyLength":2,"entry":{"step":2,"done":true}}
$ notch --status --group-by phase
{"historyLength":2,"groups":{"planning":[{"phase":"planning","step":1}]},"ungrouped":[{"step":2,"done":true}]}
Requires Bun.
# Clone and use directly
git clone https://github.com/thedotmack/notch.git
bun notch/src/notch.ts --field hello=world
# Or link globally
cd notch && npm link
notch --field hello=world| Command | Description |
|---|---|
--field key=value |
Append an entry with one or more fields (repeatable) |
--status |
Dump full state log as JSON |
--status --group-by <field> |
Group log entries by a field's value |
--reset |
Delete state file, start fresh |
--state-file <path> |
Use a custom state file (default: ./notch_state.json) |
--help |
Show usage |
Values are auto-parsed from strings:
| Input | Stored As | Type |
|---|---|---|
--field done=true |
true |
boolean |
--field done=false |
false |
boolean |
--field count=42 |
42 |
number |
--field pi=3.14 |
3.14 |
number |
--field cleared=null |
null |
null |
--field name=alex |
"alex" |
string |
notch --reset
notch --field thought="Define the problem" --field step=1 --field total=5
notch --field thought="Analyze constraints" --field step=2 --field total=5
notch --field thought="Wait, wrong approach" --field step=3 --field type=revision --field revises=1
notch --statusnotch --state-file deploy.json --field stage=build --field status=running
notch --state-file deploy.json --field stage=test --field status=running
notch --state-file deploy.json --field stage=test --field status=passed
notch --state-file deploy.json --status --group-by stagenotch --state-file sprint.json --field task="Auth flow" --field status=in-progress
notch --state-file bugs.json --field id=123 --field severity=highState is persisted as JSON with a single log array:
{
"log": [
{ "phase": "planning", "step": 1 },
{ "step": 2, "done": true }
]
}The log is append-only — entries are never modified or deleted. Use --reset to clear everything.
- Schema-less: No predefined fields. Store whatever you want.
- CLI-first: All interaction through command-line flags.
- File-persistent: JSON on disk. Survives restarts. No database.
- Append-only: Entries are never mutated. History is sacred.
- Zero dependencies: Just TypeScript and Bun.