sense run <file>
0 on success; on any
SenseError (see Error Reference) prints
SenseError: [line N] ... to stderr and exits 1. A Python
RecursionError from a too-deeply-recursive Sense program is caught and
reported the same way, not as a raw traceback.
If sense isn’t on your PATH, call the module directly:
--dry-run — every action’s .commit()/
.rollback() still runs its real capability/approval checks, but the body
that would perform the actual effect is skipped and simulated instead.
Prints a leading banner and, after the run finishes, a trailing summary
of everything that would have committed:
action only,
never tool, and .commit()/.rollback() return nil instead of a real
value since the body never ran.
sense repl
exit or quit to leave, or press Ctrl-D / Ctrl-C.
: executes immediately — no
need to press enter twice for ordinary lines.
sense test <file|directory>
test "description": ... block found while
executing each discovered file, and prints a PASS/FAIL report plus a
summary line:
test_*.sns or
*_test.sns (the same convention pytest uses) — an ordinary example
file sitting alongside your tests won’t get swept in. An error outside
any test block (a syntax error, or an unhandled exception in ordinary
top-level code) prints as ERROR rather than a named FAIL, since it
isn’t tied to a specific test description. Exit code 1 if any test
failed or any file errored; 0 otherwise, including when zero test files
are found (that’s reported, not treated as a failure).
sense fmt <file|directory>
.sns file found recursively — no
naming restriction (unlike sense test’s test_*.sns/*_test.sns
convention). Default (no flags) is non-destructive: it prints to stdout
and touches nothing on disk. See the dedicated
Formatter page for what’s preserved (comments,
blank lines), what’s canonicalized (single-rule policy:, requires
ordering, inline blocks), and the two guarantees (never changes behavior,
idempotent) that back it.
sense inspect <file> [--port PORT]
sense run — any top-level print(...)/side
effects execute normally), then serves a live, local, browser-based
console over the resulting program’s declared surface: every
tool, action,
agent, memory,
skill, and
MCP server the file declares, plus the current
policy state and a live audit log
— rendered as a call tree, indented and breadcrumbed by which
agent/tool/action call each event happened inside of, not just a flat
chronological list.
Unlike a static docs page, every panel is a real “try it out” against the
same running Interpreter your file just populated — not a mockup:
1
Tools & Skills
A typed form per parameter; clicking Call runs the tool for real and
shows the actual return value or the actual
SensePolicyError.2
Actions
Prepare, Verify, Commit, and (for a
reversible action — which,
since rollback is mandatory on one, is the only check needed)
Rollback as literal buttons — each disabled until
the action reaches the state that makes it legal, mirroring the
interpreter’s own prepared → verified → committed checks exactly.3
Agents
Start and Resume buttons on the real agent. A sync agent’s Start
blocks until it pauses or completes, same as calling
start(agent)
from Sense code would — watching it hit pause() and answering it
from the browser is the one thing here with no REST/Swagger analog.4
Memory
A key/value table; a
persistent memory’s table adds a history
lookup per key (history(key)’s version log).--port defaults to 4300 (falls through to whatever’s actually
available if that port is taken, printing the real URL either way).
Stdlib-only — no new dependency, and the console’s own page loads with no
network access — the same “doesn’t need the network to work” principle
inference("mock", ...) follows for ask(), not something ask() does
by itself regardless of provider.
--dry-run — the exact same flag sense run has (above), applied to
the console: every Commit/Rollback clicked in the browser is
simulated, never running the action’s real body. A “DRY RUN” badge is
always visible in the topbar so it’s never ambiguous whether a click is
real. See Actions: Dry run
for exactly what this does and doesn’t cover.
connect_mcp servers are shown read-only — same reason McpTool has no
direct call syntax in the language itself.sense memory-path [file]
persistent memory declared in file would actually
store its SQLite file — without running the file at all. Parses it
(lexer + parser only) and walks the whole AST for every persistent memory declaration, however deeply nested (inside a
session/agent/if/…
body, not just the top level) — deliberately never executes it, since a
real declaration can have a genuine side effect (creating the file, an
initial schema) the moment it runs, which a pure “where would this go”
query shouldn’t trigger.
Each line is labeled explicit path (whatever
persistent memory name: "path" gave it, unchanged) or default (see
Memory for the exact default-location rule) —
default -- via SENSE_MEMORY_DIR specifically when that environment
variable is what’s driving the answer.
Run with no file to just check the current configuration and see the
exact command to change it:
There’s no Sense-specific config file for this —
SENSE_MEMORY_DIR is a
plain OS environment variable, the same mechanism ANTHROPIC_API_KEY/
OPENAI_API_KEY already use for inference(...).sense --version
Exit codes
Contributing
Building from source, the project layout, and how to run the test suite are covered in Installation — not repeated here. Insidesrc/sense_lang/: lexer.py (indentation-tracking scanner),
parser.py (recursive-descent parser → AST), ast_nodes.py,
environment.py (scoping + delegation/policy/agent-context resolution —
see Architecture),
interpreter.py (the tree-walking evaluator, builtins, agent threading),
values.py, providers.py (ModelProvider + MockModelProvider),
formatter.py (sense fmt), inspector.py (sense inspect’s discovery
- RPC layer),
inspector_static/(sense inspect’s browser console — one static HTML/CSS/JS file, no build step, no CDN), andcli.pyitself.
Continue
Formatter
sense fmt’s canonicalization rules and its two guarantees.Error reference
What the CLI prints for each failure mode.
Architecture
How source text becomes a running program, end to end.

