A zot extension that implements "Run, Until, Goal Achieved". Save one session objective, then let the extension repeatedly run autonomous passes against it (single worker or swarm) until the goal check says achieved, a blocking-wall budget is spent, or the pass budget runs out. Written in TypeScript, runs with bun or node >= 22.6.
zot ext install https://github.com/patriceckhart/zot-goal/goal run (or /goal-swarm) spawns zot rpc worker subprocesses in the current cwd. Each pass sends the objective as one prompt and requires the worker to end its reply with:
GOAL_STATUS: achieved | blocked | continue
GOAL_REASON: <one line>
After each batch the runner:
- stops with outcome
achievedwhen any pass reports achieved (the saved goal is marked complete), - counts
blockedand errored passes as blocking walls; auth/permission patterns like "az login required", "permission denied", or "403 forbidden" in worker output are detected as walls automatically, - stops with outcome
blockedoncemax_wallswalls accumulate (setwalls 1to stop at the first wall), - waits
interval_seconds(default 10s) between passes, then checks again, - never loops forever: a hard
max_passesbudget (default 50) ends the run with outcomeexhausted.
Because workers are plain zot rpc subprocesses, they respect whatever flags you pass through rpc_args in goal-state.json (e.g. tool restrictions or jail-style limits) and zot's own configuration.
/goal finish the release checklist and verify the app still starts
/goal run [objective] run until achieved with one worker
/goal swarm [objective] run until achieved with parallel workers
/goal-swarm [objective] same as /goal swarm
/goal stop stop a running loop
/goal set walls 1 stop at the first blocking wall
/goal set interval 10 seconds between passes
/goal set passes 50 hard pass budget
/goal set workers 4 swarm size
/goal set timeout 900 per-pass timeout in seconds
/goal open the status panel
/goal continue | pause | resume | blocked | complete | clear
/goal <objective>saves a new active objective and starts a normal model turn for it (no loop)./goal runand/goal swarmaccept an inline objective or reuse the saved one.- The panel (
/goal,/goal view) shows objective, status, live run progress (passes, walls, last verdict), and config.
Tools exposed to the model:
| Tool | Purpose |
|---|---|
get_goal |
Read the saved objective, run state, and config. |
create_goal |
Save an objective when the user explicitly requests it. |
update_goal |
Mark the objective complete or blocked. |
index.ts extension entry point (wire protocol, commands, tools)
runner.ts run-until-achieved loop, zot rpc workers, wall detection
state.ts persisted state (goal, run info, config) in goal-state.json
ui.ts panel rendering and formatting
protocol.ts stdio framing helpers
run.sh launcher (bun if available, else node with type stripping)
test.mjs end-to-end tests using test/fake-rpc.mjs as a fake worker
Then restart zot or run /reload-ext.
The extension has zero runtime dependencies and runs straight from source: run.sh uses bun if available, otherwise node >= 22.6 with type stripping. No node_modules directory is needed to install or run it.
bun test.mjs # works without any install
bun install # only for `bun run typecheck` (typescript + @types/node)
bun run typecheckTests stub the worker via ZOT_GOAL_RPC_CMD, so they run without a real model or API key.
MIT