Baseline for the v0.2.0 self-learning iteration. All 205 tests pass on this
state. Subsequent commits in this branch layer the knowledge base,
post-mortem coach, and persona narration on top.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Phase 1 of plans/autonomous-survival-bot-prd.md. The bot must always be
able to answer "what am I doing and why am I not doing more?" without
parsing the log stream.
New modules:
- runtime/state.js: pure FSM classifier emitting emergency / working /
recovering / planning / social / idle from snapshot + reflex context.
- runtime/no-progress.js: sliding-window detector that watches position
and inventory; when both are unchanged for 60 s+, emits one stable
reason code from REASONS (waiting_for_day, night_hostile_nearby,
no_food_source, inventory_full, no_reachable_target, planner_empty,
awaiting_action_cooldown).
- runtime/viewer.js: optional prismarine-viewer launcher behind
VIEWER_PORT. Lazy import so the dep is not required by default.
Wiring:
- runtime/bot.js: tick() now computes runtimeState + noProgressReason
every tick and stamps them on the snapshot along with activeSkill,
currentMilestone (read from plan.md, cached 30 s), lastResult,
failuresByCode and lastEscalation.
- runtime/bot.js: dispatchAction records lastResult and lastFailureAt
for the recovering-state classifier.
- runtime/planner.js: exports isPlannerBusy(), readNextMilestone()
and planExists() so the runtime can show planning state + current
milestone without spawning extra Pi calls.
- runtime/config.js: adds VIEWER_PORT support.
TUI:
- tui/tui.tsx: StatusBar gains a state badge, current-skill row,
milestone row, no-progress reason warning, last-result line with
ok/fail color, failures-by-class summary and last-escalation age.
Co-authored-by: Yuriy Mayatnikov <mayatnikov@me.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Phase 0 of plans/autonomous-survival-bot-prd.md: change the product
direction from operator-driven remote control to autonomous survival
resident. MC chat is dialog-only for everyone, including
OPERATOR_USERNAMES — commands like come/follow/build/pause/stop are
recorded in the diary but not dispatched. TUI remains the only local
control plane.
Runtime changes:
- Remove operatorGoalReflex from reflex.js (the come-here chat command).
- Replace handleOperatorChat in bot.js with a dialog-only handleChat
that answers greetings/status questions and records command-like
verbs (en+ru) without dispatching them.
- Default MC_VERSION to "auto" in runtime/config.js; mineflayer
receives `false` to trigger version auto-detection.
- Update auto-escalation prompt's reflex chain summary.
Docs:
- AGENTS.md: product pivot notice up top; chat-driven scope-trust is
flagged as legacy/Pi-only.
- README.md / docs/runtime.md: replace operator-chat command list with
dialog-only description; update reflex chain summary.
- docs/roadmap.md: Phase 2/3 marked superseded by the PRD where they
assumed chat-driven control.
Co-authored-by: Yuriy Mayatnikov <mayatnikov@me.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(mindcraft-skills): hard timeout on every skill call
mc_avoid_enemies (and 7 other tools) wrapped only in safeCall without a
withTimeout. When mindcraft's underlying pathfinder/pvp goal couldn't be
satisfied, the call never resolved — the Pi tick loop blocked forever.
Observed live: mc_avoid_enemies pending >10 minutes after one mc_observe.
safeCall now takes timeoutMs (default 30s) and wraps withTimeout itself,
so every tool gets a hard ceiling. Per-tool overrides:
- goToPosition / goToNearestBlock: 120s / 90s (unchanged from before)
- defendSelf / avoidEnemies: 45s
- stay: secs*1000 + 10s
- craft / consume / pickup / place: 30s
- equip: 15s
collectBlock still uses its bespoke per-iter 75s loop.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(runtime): script-driven reflex daemon + Ink TUI dashboard
Pure-Pi runtime had three failure modes in practice:
- slow: 20-60s per decision because LLM was in the hot path
- expensive: every tick (defend, eat, idle) paid for a reasoning pass
- invisible: required tmux capture-pane to know what the bot was doing
New runtime/ layer is a long-running Node daemon that owns the MC
connection, ticks a priority-ordered reflex chain (defend > eat > sleep
> idle) with NO LLM in the hot path, and exposes status + commands over
a Unix-socket IPC. tui/ is an Ink dashboard that attaches over IPC and
can detach freely — multiple TUI clients can connect at once.
Pi/Codex are still available, but as on-demand escalation: TUI hotkey
'a' spawns `pi -p "<prompt>"` as a subprocess and streams stdout into
the dashboard. The self-improvement loop (proposals → operator approval
→ Pi-driven patch → hot reload) is documented in docs/runtime.md but
not yet wired.
Reflex bodies are stubs today — they log decisions but don't drive
Mineflayer actions yet. The priority chain, IPC contract, and TUI are
fully working; subsequent commits will fill in defend/eat/sleep bodies
and wire automatic escalation.
Run with `npm run bot` + `npm run tui`. Pi-only fallback stays at
`npm run agent`.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Yuriy Mayatnikov <mayatnikov@me.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>