87 Commits
Author SHA1 Message Date
313ef081d1 feat(runtime): village progression — crafting, tech-tree reflex, LLM planner (#11)
Closes the loop "стой и кидай proposals" → "копит ресурсы, строит,
работает к глобальной цели". Three pieces:

1. Crafting primitives (runtime/actions.js).

   craftPlanks (4 per log, any wood type), craftSticks (4 per 2 planks),
   placeCraftingTable (crafts a table from planks if needed + places at
   reference block + reuses an existing table within 4 m), craftWoodenAxe,
   craftWoodenPickaxe, craftWoodenSword. Each uses bot.recipesFor()
   + bot.craft() with a 15s timeout. Returns the same {ok, detail}
   contract as the other actions.

   inv.{getItemCount, getAnyPlanksCount, getAnyLogCount} helpers
   exported so the reflex layer can read inventory cheaply without
   pulling mineflayer state through every reducer.

2. Tech-tree reflex (runtime/reflex.js).

   New techTreeReflex between sleep and autonomous. Inventory-driven
   progression: log+0 planks → planks; planks+0 sticks → sticks;
   planks+sticks+no axe → wooden_axe; +no pickaxe → wooden_pickaxe;
   +no sword → wooden_sword. 5 s cooldown so we don't fire on every
   tick.

   Pure script, no LLM. The progression is exactly what a player
   does in the first 10 min on a new world; making it scripted means
   the bot never burns tokens on it.

3. LLM planner (runtime/planner.js).

   Background timer (every 15 min, with a 30 s warm-up after start).
   Reads goal.md + plan.md + a slim snapshot, prompts Pi to output a
   fresh plan.md to stdout. Stripped of code fences and written
   verbatim to state/<host>/plan.md. Capped at 16 KB.

   The plan is markdown the operator can read or edit by hand. Numbered
   milestones, ✓ prefix for completed ones, kept short. The reflex
   layer doesn't auto-execute LLM text — but the planner sets the
   long-horizon shape that future reflexes (build house, plant farm)
   can read.

   5 min timeout on the pi subprocess. If it crashes or times out, the
   next 15-min tick just retries — no propagation to the reflex loop.

The progression now looks like, roughly:

  chop log (autonomous) →
  craft planks → craft sticks → wooden_axe (tech-tree) →
  chop faster (autonomous, has axe now) →
  wooden_pickaxe + wooden_sword (tech-tree) →
  mine stone … (next PR: stone tools, farm site selection,
  house frame)

Smoke-tested: all three modules import cleanly, exports check out.

Co-authored-by: Yuriy Mayatnikov <mayatnikov@me.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 17:00:07 +03:00
7797dd3d5a feat(runtime): fully autonomous self-healing — no operator approval (#10)
Operator feedback: "бот должен быть полностью автономным — сам себя
улучшать и чинить, в этом и есть смысл; все что я вижу пока что он
стоит на месте и кидает proposals на каждый чих — это кардинально не
то что я хочу". Acted on:

1. Trigger filter — proposals only on real bugs.

   runtime/bot.js classifies failure detail into bug / timeout /
   feature-gap / other. The 5-in-a-row trigger fires only when the run
   contains a bug (TypeError / Cannot read / is not defined …) OR is
   entirely timeouts on the same operation. Feature gaps like "no
   reachable log within 32 blocks", "no food in inventory", "no bed in
   range", "no target in reach" are SKIPPED — the reflex layer routes
   around them (noTreesUntil → wander, etc). The LLM has no business
   patching code for missing inventory.

   Threshold raised 3 → 5 in a row. Cooldown unchanged (30 min).

2. Auto-apply, no operator-in-the-loop.

   New runtime/auto-improve.js polls proposals/ every 2s. When it sees
   a new .md and 10s have passed since first sighting (debounce),
   spawns scripts/auto-patch.js detached.

   New scripts/auto-patch.js: refuses on dirty tree, moves proposal
   pending → approved/, branches `auto/<slug>` off main, runs `pi -p`
   with 10-min timeout. If Pi committed AND every changed file is
   under runtime/ → cherry-picks onto main. Otherwise discards the
   branch. No push, no PR. Audit trail in state/<host>/proposals/approved/.

   Rate limit: 15-min cooldown between finished runs + 4/hour hard cap.

3. Auto-rollback on bad patches.

   runtime/supervisor.js: when MAX_RESTARTS_PER_MINUTE is exceeded
   AND `git log -1 HEAD` is younger than 15 min AND HEAD touched
   runtime/, runs `git reset --hard HEAD~1`. Up to MAX_ROLLBACKS=3
   lifetime, then exits 1 for manual investigation. Restart counters
   are reset after a successful rollback so the next attempt isn't
   immediately killed.

4. current-task.json slim.

   No longer stores the full perception snapshot (was ~3 KB per write
   × every action). Position only — sufficient as a resume anchor.
   Slim snapshot still goes into the proposal markdown for context.

docs/runtime.md — rewrote the self-improvement section: full flow
diagram, classification rules, all rate-limit knobs, manual escape
hatches kept but documented as rarely-needed.

Also cleared 5 stale proposals from previous smoke tests so the first
production run isn't burning Pi tokens on stale bugs that have since
been fixed.

Co-authored-by: Yuriy Mayatnikov <mayatnikov@me.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 16:56:02 +03:00
2ecadd3bb2 fix(supervisor): pidfile lock prevents two supervisors racing on the nickname (#9)
User report 2026-05-25: launched 'npm run bot' fresh, MC server kicked
every login with "Игрок с данным никнеймом уже играет на сервере" and
the bot fell into a perpetual reconnect-then-kicked loop. Root cause:
a smoke-test supervisor from an earlier shell was still running in the
background, holding the pepa_bot session open. Two supervisors racing
on the same nickname is undefined behaviour from the server's side and
results in this exact failure mode.

Changes:

runtime/supervisor.js — acquires state/<host>/supervisor.pid before
spawning the child. If another supervisor is alive (kill -0 check), the
new one exits with a clear message telling the operator how to recover.
On SIGINT/SIGTERM/exit the lock is released; stale pidfiles are detected
when the recorded PID is no longer alive.

scripts/stop.sh — emergency cleanup helper:
  - kills any supervisor or bot.js processes matching this repo
  - removes pidfile + bot.sock
  - reminds the operator to wait ~30s for the MC server to drop the old
    session before re-launching

package.json — new `npm run stop` script.

Smoke-tested:
  - first 'node runtime/supervisor.js' acquires lock, writes pid
  - second call refuses with diagnostic message
  - first SIGTERM ⇒ pidfile removed automatically

Co-authored-by: Yuriy Mayatnikov <mayatnikov@me.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 16:47:24 +03:00
f5361ad9a4 feat(runtime): autonomous reflex — chop wood + wander + proactive movement (#8)
Closes the "bot stands on a tree doing nothing" problem reported live
when the operator launched the TUI after PR #6 landed. The reactive
chain (operator > defend > eat > sleep > idle) was passive by design:
day-time, full HP and food, no hostile within 4 m ⇒ every reflex
returned noop. The bot perched in dark-oak canopy and never moved.

Changes

runtime/actions.js:
  - chopNearestTree: find any *_log within 32 blocks, equip best axe
    (falls back to fists), path to the block, dig. Per-bot 5-min
    blacklist of unreachable log positions so we don't grind on the
    same impossible target.
  - wander: pick a random offset 6-16 blocks away and path there.
  - setMovementsForGather / setMovementsForTravel: every action that
    uses pathfinder now sets its own Movements profile (canDig=true)
    instead of inheriting whatever the previous caller left. The old
    behaviour caused chop to inherit flee's canDig=false and get stuck
    in the canopy.
  - fleeFrom now uses canDig=true too — the user observed the bot
    permanently stuck on a leaf block because escape required digging.

runtime/reflex.js:
  - new autonomousReflex between sleep and idle. Cooldown 10s. Picks
    chop when log count < 16, else wander. When chop reports "no
    reachable log within 32 blocks" we switch to wander for 60s so we
    don't re-fire chop against the same impossible position.
  - defendReflex tightened: only flee when closest is ≤8m (or ≤12m
    on low HP). Avoids the "82 distant hostiles ⇒ constant flee
    loop" pathology observed at this spawn.
  - flee cooldown: same mob name within 60s ⇒ noop, so we yield to
    other reflexes if flee keeps timing out.
  - sleepReflex retry cooldown raised 30s → 5min. Sleeping fails
    permanently if no bed is around; the short retry blocked
    autonomous behaviour every tick.
  - ctx.lastReflex now records {name, label, ts} after each
    dispatched/completed reflex so the TUI can show what the bot
    just decided.

runtime/bot.js:
  - per-tick snapshot adds lastReflex and busy fields for the TUI.
  - maybeReplyToPlayer: light canned greetings (yo/hey/hi/привет)
    to non-operators when they address the bot. 30s cooldown so we
    don't spam.

tui/tui.tsx:
  - status bar shows either "▸ busy: <label>" while an action is
    in flight, or "last reflex: <name> (<label>) Ns ago" when idle.
    Gives an at-a-glance answer to "what is the bot doing right now?"

Smoke-tested live (play.xmatic.team, 2026-05-25T13:30-13:39):
  - bot did dispatch chop tree (oak_log at 617,82,95)
  - real bug surfaced and 3-fail rule filed a proposal automatically
  - after the runtime fix, chop returns "no reachable log" gracefully
  - bot switched to wander on the next tick
  - position moved from (623.31, 85, 95.12) to (623.41, 86.02, 96.7)
    — the first observable movement in this dark-oak spawn

Co-authored-by: Yuriy Mayatnikov <mayatnikov@me.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 16:40:36 +03:00
445524b34d docs(runtime): reflect live reflex bodies + operator chat + self-improvement loop (#7)
Updates docs/runtime.md and README.md to match what's actually shipped:
  - reflex chain priorities and what each body now dispatches
  - operator chat command list (status, come, pause, resume, stop)
  - automatic + manual Pi escalation paths and the no-code-change rule
  - the full self-improvement loop end-to-end (detector → TUI approval
    → propose:apply → supervisor restart) with the rationale for the
    manual propose:apply step
  - new state files layout (proposals/, proposals/approved/, etc.)
  - supervisor.js + bot:bare script flags

No code changes.

Co-authored-by: Yuriy Mayatnikov <mayatnikov@me.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 16:22:38 +03:00
cd14bbf89a feat(runtime): state persistence + proposals + supervisor hot-restart (#6)
Closes the self-improvement loop end-to-end:

  reflex fails 3× → proposal file → operator approves in TUI →
  `npm run propose:apply <file>` spawns Pi on a feature branch →
  Pi commits the patch → supervisor watches runtime/*.js and
  restarts the child on change.

runtime/state-store.js — atomic current-task.json writes, daily diary
  append, proposals/ + proposals/approved/ helpers.

runtime/bot.js:
  - ctx.dispatch writes current-task.json on start and updates it on
    completion / failure / throw.
  - failure tracker: 3 consecutive same-label failures → writeProposal()
    with the snapshot, labels, and a suggested-next-step section.
    30-min cooldown prevents proposal spam.
  - on startup, surfaces resume info (previous task + pending proposal
    count); on death, clears current-task.json + writes diary line.
  - new IPC commands: PROPOSAL_LATEST returns the newest pending
    proposal body; PROPOSAL_APPROVE moves it to proposals/approved/.

tui/tui.tsx — status bar shows `[proposals N, press y]` badge when
  bot.pendingProposals > 0. Hotkey 'y' opens the proposal panel; 'y'
  approves, 'n'/Esc closes.

scripts/propose-apply.js — given an approved proposal filename, creates
  a `feat/proposal-<slug>` branch and spawns `pi -p` with the proposal
  + repo-conventions prompt. Refuses on dirty tree. No auto-push, no
  auto-merge — operator reviews the diff and decides.

runtime/supervisor.js — forks bot.js as a child, watches runtime/*.js,
  restarts on file change or on child exit code 42. Rate-limited at 5
  restarts/minute. SIGINT/SIGTERM forward cleanly. `npm run bot` now
  goes through the supervisor; `npm run bot:bare` skips it.

Smoke-tested: supervisor spawned, bot connected to MC, spawned at
expected coords, diary line written, state cleanup on SIGTERM correct.

Co-authored-by: Yuriy Mayatnikov <mayatnikov@me.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 16:20:09 +03:00
ee2b4c26eb feat(runtime): real reflex bodies + auto-escalation + operator chat (#5)
runtime/actions.js — Mineflayer wrappers with hard timeouts and structured
{ok, detail} returns:
  - attackNearest: equip best melee, lookAt, single swing per call
  - fleeFrom: lazy-load pathfinder, walk N blocks away (canDig=false to
    avoid burrowing through walls under panic)
  - eatBestFood: scan inventory by FOOD_PRIORITY, equip + consume
  - sleepInBed: find nearest placed bed within 16 blocks, path to it, sleep
  - goTo: pathfinder.goto for operator come/follow

runtime/reflex.js — bodies now dispatch real actions via ctx.dispatch:
  - operator-goal (highest): satisfy come/follow command
  - defend: ≤4m attack, ≤12m + low HP/many hostiles flee
  - eat: food < 16 + 5s cooldown
  - sleep: night + safe + 30s retry cooldown
  - idle: heartbeat every 20th tick
Reflex returns "skipped" when ctx.busy so we don't count busy ticks as
either productive or noop in the escalation counter.

runtime/bot.js:
  - ctx.dispatch fire-and-forget wrapper with busy gate, onComplete hook
  - consecutiveNoops counter; after ESCALATE_AFTER_NOOPS (=20, ~1 min at
    tick=3s), askPi with the current snapshot. 10-min cooldown.
  - operator chat handler: parses `<botname> <verb>` messages from
    OPERATOR_USERNAMES. Verbs: status, pause, resume, stop, come.
  - Death drops any pending operator goal.

Smoke-tested live against play.xmatic.team:25565: bot connected, logged
in via AuthMe, reflex chain dispatched flee/sleep, hard timeout fired
when pathfinder couldn't reach the flee target (expected — no usable
ground path in dark_forest at this spawn).

Co-authored-by: Yuriy Mayatnikov <mayatnikov@me.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 16:11:53 +03:00
1e3b36a9a1 feat(runtime): hybrid script reflex + Ink TUI + Pi-on-demand escalation (#4)
* 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>
2026-05-25 16:04:48 +03:00
mayatnikovandClaude Opus 4.7 989ddf335e docs(prompts): OpenClaw seed prompt for parallel autonomous farmer experiment
OpenClaw is a different paradigm than our Pi-based bridge — messaging-first,
marketplace of pre-built skills (astraopenclaw/minecraft-agent already exists),
self-extension via skill authoring. The operator wants to run an OpenClaw
instance side-by-side with pepa-pi-bot to compare which approach gets to a
visible village faster.

prompts/openclaw-seed.md: single founding-message prompt. Identity, server
credentials inline (secrets via .env, not echoed), goal (small village,
long-horizon), bootstrap checklist (install skill, connect, AuthMe handle,
30-60s autonomous tick, on-death recovery), self-extension permission, hard
safety rules duplicated from AGENTS.md, definition of success ("a week from
now there's a cluster of buildings attributable to you").

Includes operational notes on nickname conflict (only one bot can be on the
server at a time under pepa_bot; suggest pepa_claw for the OpenClaw side),
.env coordination, LLM provider mixing, and a short post-mortem comparison
checklist for after a few hours of both running.

Not invoked by anything in this repo — it's an artefact for cross-runtime
experimentation. Lives in prompts/ alongside the Pi prompts and the
codex-seed-knowledge.md prompt because that folder is the right home for
reusable prompts regardless of which agent consumes them.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 15:20:44 +03:00
Yuriy Mayatnikov bed63b9949 Merge pull request #3 from xmatic-squad/feat/recovery-improvements
feat(recovery): death handler + auto-defend + bulk-collect rework + mc_stay shim
2026-05-25 15:07:08 +03:00
mayatnikovandClaude Opus 4.7 68f59dfa4c feat(recovery): death handler + auto-defend reflex + bulk-collect rework + mc_stay shim
Four targeted fixes for issues observed during the live autonomous test:

1. **bot.modes shim** (extensions/lib/mcdata.js)
   Mindcraft skills.* call bot.modes.pause('cowardice') in 7+ places.
   `mineflayer-modes` does not exist on npm — it's internal to Mindcraft.
   attachPluginsAndInit now installs a no-op shim so skills.stay() /
   .consume() / .defendSelf() etc. stop crashing with "pause undefined".

2. **Death + respawn handlers** (extensions/mineflayer-bridge.ts)
   Subscribe to bot 'death' event: append diary line with position,
   clear current-task.json so Pi doesn't resume a stale task referencing
   inventory that no longer exists.
   On 'spawn' within 5s of death: log the new respawn position to diary.
   Live test had bot killed twice by zombies at night; the next Pi
   prompt was unable to recover. With this it's now an explicit diary
   line + clean task slate.

3. **Auto-defend reflex tick** (extensions/mineflayer-bridge.ts)
   New setInterval(2s) that, when bot.health < 18 AND a hostile mob
   (zombie/skeleton/creeper/spider/etc.) is within 6 blocks AND no
   active world task, fires `bot.pvp.attack(nearest)` in the background.
   No LLM call needed for instant self-defense — saves tokens and reacts
   on mineflayer timescale (sub-second) rather than Pi loop timescale
   (~10s+ to reason and dispatch). Throttled to once per 4s.

4. **mc_collect_block bulk rework** (extensions/mindcraft-skills.ts)
   Live test showed count=1 succeeds in ~25s but count=8 hangs past
   270s with identical blocks in range. Upstream collectBlock plugin
   appears to drift on its block cache after the first dig in dense
   terrain. Loop single-block collects in-tool instead (75s per iter,
   re-pathfind on each iteration). Track per-iter success/failure,
   abort after 3 consecutive failures, return aggregate count to the
   agent so it can adapt instead of seeing a single failure.

Smoke test: both extensions load, bot connects, perception confirms
hostiles nearby and daylight safety check. No syntax/runtime errors.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 15:06:37 +03:00
mayatnikovandClaude Opus 4.7 a323bdea85 fix(mindcraft-skills): scale collectBlock timeout with count
Live test showed count=1 succeeds in ~25s but count=8 timed out at 90s
because gathering 8 logs naturally takes ~200s of pathing + dig + pickup
across the area. Fixed 90s ceiling was too tight for legitimate bulk
collection.

Scale timeout linearly: 30s overhead + 30s per requested block, capped
at 600s. count=1 → 60s, count=4 → 150s, count=8 → 270s, count=20 → 630s
(capped at 600). Catches real hangs (wrong name, unreachable) without
killing legitimate long collections in dense forest.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 14:42:07 +03:00
mayatnikovandClaude Opus 4.7 f46272d8c4 fix(mindcraft-skills): hard timeout on collectBlock/goToPosition/goToNearestBlock
Mineflayer's collectBlock plugin and pathfinder can hang indefinitely when:
- the requested block name doesn't match anything in range (e.g. asking for
  "oak_log" when the only nearby logs are "dark_oak_log"),
- pathfinder cannot reach the goal but doesn't return a clean noPath,
- a path computation enters an infinite-search state in dense terrain.

This blocks the entire Pi tool loop — observed in a live test where
mc_collect_block("oak_log", 4) ran for 8+ minutes without ever returning,
leaving Pi unable to respond to chat or do anything else.

Add a 90s timeout for collectBlock/goToNearestBlock and 120s for goToPosition.
On timeout the tool throws a descriptive error so the agent learns to retry
with a different block name or position rather than waiting forever.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 14:37:14 +03:00
Yuriy Mayatnikov 5a7aab48d9 Merge pull request #2 from xmatic-squad/feat/mindcraft-skills
feat(perception): mindcraft skills/world + 15 Pi tools (proper perceive→decide→act loop)
2026-05-25 14:25:27 +03:00
mayatnikovandClaude Opus 4.7 3e61b87f19 feat(perception): vendor mindcraft skills/world library + Pi tool wrappers
The bot was acting blind: it knew its own coordinates but nothing about
what was around it. mc_goto's over-strict safety guards refused every
real path. mc_dig was too low-level to drive a coherent farming loop.
The result: 4+ hours of "trying" with zero physical achievement.

This commit reframes the bridge around a perceive→decide→act loop using
proven primitives from Mindcraft (github.com/kolbytn/mindcraft, MIT —
LICENSE-MINDCRAFT vendored beside the library files).

Changes:

- extensions/lib/  (new, vendored from Mindcraft with attribution)
  - world.js  (431 LoC) — 21 perception functions: getNearbyBlockTypes,
    getNearbyEntities, getInventoryCounts, getNearestBlock, getPosition,
    getBiomeName, etc.
  - skills.js (2093 LoC) — 30+ action primitives: collectBlock, placeBlock,
    goToPosition, goToNearestBlock, craftRecipe, equip, consume,
    defendSelf, avoidEnemies, pickupNearbyItems, stay, etc.
  - mcdata.js (~600 LoC) — Mindcraft's mc-data adapter. Imports patched
    to local paths; mineflayer-auto-eat removed (our installed 5.x has
    a divergent API; skills.consume() falls back to bot.consume()).
    Added attachPluginsAndInit(bot) export so mineflayer-bridge.ts can
    wire plugins onto its externally-created bot.
  - settings.js — minimal stub with farmer-bot defaults.

- extensions/mindcraft-skills.ts (new, 406 LoC) — Pi extension registering
  15 high-level tools on top of the vendored library:
  - Perception: mc_observe, mc_inventory, mc_nearby_blocks, mc_nearby_entities
  - Action: mc_collect_block, mc_place_block, mc_go_to, mc_go_to_block,
    mc_craft, mc_equip, mc_consume, mc_defend_self, mc_avoid_enemies,
    mc_stay, mc_pickup_nearby
  ES modules from extensions/lib/ are loaded via dynamic import() at
  extension init so the cross-extension require()-race resolves cleanly.

- extensions/mineflayer-bridge.ts
  - Expose the live Mineflayer bot on globalThis.__pepaPiBot so the
    mindcraft-skills extension can use it (set on connect, cleared on
    error/end/manual disconnect).
  - Call attachPluginsAndInit(nextBot) right after createBot to load
    pathfinder, pvp, collectblock, armorManager and prime
    minecraft-data once login completes.

- package.json — new runtime deps: minecraft-data, vec3,
  mineflayer-pvp, prismarine-item.

- AGENTS.md — new "Perception → decision → action" section before
  "Your tools right now" with full tool catalog and a deprecation
  note for the broken mc_goto / mc_build_pyramid_5x5 / low-level
  mc_dig from the old bridge.

Smoke test (medium thinking): bot called mc_observe and received a
real JSON snapshot — nearbyBlocks listed coal_ore, oak_log, water,
sand; nearbyEntityTypes listed creeper, zombie, pillager, skeleton.
The bot can finally see what it could not see this morning.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 14:24:23 +03:00
Yuriy Mayatnikov 7060daac46 Merge pull request #1 from xmatic-squad/feat/knowledge-base
docs: add minecraft knowledge base
2026-05-25 13:11:09 +03:00
mayatnikov 978fdc6b48 docs: point learning loop to knowledge base 2026-05-25 13:02:45 +03:00
mayatnikov 01907dc1e9 deps: add core mineflayer plugins 2026-05-25 13:02:43 +03:00
mayatnikov b98aa94326 docs: add minecraft recipe index 2026-05-25 13:02:11 +03:00
mayatnikov 8930dbc90a docs: add minecraft mechanics reference 2026-05-25 13:02:06 +03:00
mayatnikov 7183ab9440 docs: add mineflayer API cheatsheet 2026-05-25 12:58:25 +03:00
mayatnikov 0bb233eab3 docs: add mineflayer plugin roster 2026-05-25 12:57:58 +03:00
mayatnikovandClaude Opus 4.7 ca0897b951 docs(prompts): seed-knowledge prompt for one-off Codex-class research pass
A long-form prompt for a long-context autonomous coding agent (Codex Pro,
Claude Sonnet w/ repo access, etc.) — NOT a Pi prompt. Goal: produce a
comprehensive docs/ knowledge base so the bot doesn't have to rediscover
Mineflayer API surface and core Minecraft mechanics (mobs, biomes,
recipes, ore Y-levels, farming, breeding) every time it tries something
new.

Design constraints baked into the prompt:

- PR-only workflow. Worker agent operates on a feat/knowledge-base
  branch; main stays untouched so the live bot is unaffected until the
  operator reviews and merges.
- docs/ only. Never write skills/ — that's the bot's notebook; pre-
  writing procedural skills kills emergence. Reference material is the
  textbook; the bot stays the author of its own procedures.
- One-line AGENTS.md addition pointing to docs/, no broader policy
  rewrite. Behaviour change is "consult docs/ before I'll try to learn".
- package.json gets four universal-useful plugins added (collectblock,
  auto-eat, tool, armor-manager); statemachine/pvp/blockfinder/viewer
  are left for the bot to opt into.
- Concrete definition of done, scope estimate (10-30h), review
  checklist for spot-checking hallucinations before merge.
- Re-run triggers documented (MC version bump, Mineflayer major,
  new must-have plugin).

Included so future operators / forks can repeat this kind of one-off
seeding without re-deriving the prompt. Lives alongside the Pi prompts
in prompts/, even though it targets a different runtime — the
prompts/ folder is the right home for "reusable prompts" regardless of
which agent consumes them.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 12:57:52 +03:00
mayatnikov b778eaa2fb pre codex 2026-05-25 12:51:14 +03:00
mayatnikovandClaude Opus 4.7 6ed45a00d5 feat(autonomy): memory model + long-term goal + bias-to-action + live-your-life prompt
Three things that together turn the bot from a reactive chat agent into
a goal-driven autonomous one.

1. Memory model (docs/memory-model.md, new). Formal split:
   - SHARED knowledge — skills/, extensions/, prompts/, docs/,
     .pi/settings.json — committed, community-improvable, portable to any
     server.
   - PERSONAL memory — state/<MC_HOST>/ — gitignored, per-instance, per-
     server. Survives restarts (local disk), doesn't survive a re-clone
     (deliberately). Holds goal.md, plan.md, current-task.json,
     locations.json, diary/, inventory-log.jsonl, escalations.
   Covers resume-after-restart protocol, what "abstract a lesson into a
   skill" means, and the two anti-patterns (committing state, gitignoring
   shared knowledge).

2. AGENTS.md changes:
   - New section "Long-term goal and personal memory" wiring AGENTS.md
     directly into state/<MC_HOST>/goal.md + current-task.json with a
     pointer to docs/memory-model.md.
   - Operating principle #4 ("I'll try to learn") rewritten with
     **bias to action**: a pending stub is now a last resort, not a
     default. Operator-trusted requests are themselves approval — bot
     does not write a stub and wait for a separate "go".
     Rationale: today's pyramid task got stuck because the bot wrote
     a careful "pending" stub and waited; the operator had to send
     "ты ждешь одобрения? можешь стартовать!" before any action. That
     extra round-trip is the reflex this rewrite removes.
   - Operating principle #5 ("live your best life when idle") expanded
     to "goal-driven autonomy" with an explicit 5-level priority order
     (operator task > non-op reply > resume current-task.json > next
     plan milestone > decompose goal). Memory protocol made concrete:
     write current-task.json before every meaningful action, append to
     diary, keep locations.json fresh, tick off plan.md.

3. prompts/live-your-life.md (new). Canonical kickoff to switch the
   bot into autonomous mode. Numbered concrete asks (re-read three
   docs, write plan.md, implement memory protocol, implement
   resume-on-restart, start). Includes a "plan.md draft for review"
   gate so the operator can shape direction without micromanaging
   execution. Designed to be sent after Phase 0/1/operator-trust are
   stable and a goal.md exists for the target server.

Companion seed (local-only, NOT in this commit because gitignored):
state/play.xmatic.team_25565/goal.md — "build a small village and
survive long-term, live like a farmer". Lives only on the operator's
machine; a fresh clone won't see it.

README and roadmap updated with the new Phase 3 status (🌱🌿
kickoff) and pointers to the new memory-model doc.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 12:21:25 +03:00
mayatnikov 2da2eb197e Add pending safe small builds skill 2026-05-25 11:59:11 +03:00
mayatnikov ef92553af6 Wire scope-trusted operators 2026-05-25 11:57:41 +03:00
mayatnikovandClaude Opus 4.7 da49c9f4ef feat(trust): scope-trust operators via OPERATOR_USERNAMES; safety remains absolute
Two-tier chat trust:
- Anyone in OPERATOR_USERNAMES (comma-separated, .env-only) is SCOPE-trusted.
  The bot skips the "out of scope / not sure where" escalation reflex for
  these users and instead applies "I'll try to learn" (Operating principle
  #4): attempt, codify into a new skill, or reply with a concrete reason.
- Hard safety rules (no OP, no breaking other players' builds, no .env
  leak, no chat spam, no destructive bash) remain ABSOLUTE. Operators get
  the same refusal + escalation as anyone else for safety-borderline
  requests — with slightly pointed wording, because they should know better.
- No transitive trust: chat-based "trust X for the next hour" / "make Y
  an op" requests are themselves safety escalations. Op membership only
  flows through .env on disk.

Security caveat documented in .env.example: nickname-based trust is only
safe on servers with identity protection (online-mode UUID or AuthMe).
On pure cracked servers OPERATOR_USERNAMES must stay empty.

- AGENTS.md: new Identity field for OPERATOR_USERNAMES; new Operating
  principle #6 "Trusted operators" with the scope-vs-safety split; old
  escalation principle renumbered to #7; Control channel section
  rewritten with primary/secondary trust distinction.
- .env.example: OPERATOR_USERNAMES placeholder with multi-paragraph
  security note covering when the model is and isn't safe.
- prompts/grant-op-trust.md: canonical implementation prompt for the
  next Pi pass — re-read AGENTS.md, wire isOperator() into the bridge's
  escalation flow, codify into skills/operator-trust.md, reload bridge,
  verify with two concrete chat replays (scope vs safety).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 11:38:04 +03:00
mayatnikov ce41bf6be6 Add live presence and escalation loop 2026-05-25 11:21:47 +03:00
mayatnikovandClaude Opus 4.7 c03283c43c feat(roadmap): phased plan + operating principles + presence prompt
Phase 0 (body) is done. The next steps shouldn't be guessed prompt-by-prompt —
write down the order, the judgement principles, and the next concrete
session prompt, so the bot has a coherent direction and the human can
hand it off in one message.

- docs/roadmap.md (new): six phases, each with status, scope, and stretch.
  Phase 0 = 🌳 done, Phase 1 = 🌿 in progress, the rest = 🌱.
  Explicit non-goals (no PvP, no OP, no cross-server identity).
- AGENTS.md: First-objective section collapsed to a pointer at the
  onboarding skill (it's been done). New "What to do, in priority order"
  summary citing the roadmap. New top-level "Operating principles"
  section: presence, bounded reconnect, hold focus, "I'll try to learn"
  reflex, idle = best-life mode, escalate destructive doubt with a
  JSONL log under state/<host>/escalations.jsonl.
- prompts/awake-and-live.md (new): canonical kickoff prompt for the
  next session. Scopes itself explicitly to phases 1+5+6 and excludes
  locomotion (phase 2 needs care, separate session).
- README Status: 🌳 Phase 0 done / 🌱 Phase 1 in progress, links to
  roadmap and operating principles.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 11:09:05 +03:00
mayatnikov 4e98fe8703 Record server onboarding milestone 2026-05-25 10:53:40 +03:00
mayatnikov 945b9733a7 Bootstrap Mineflayer bridge scaffold 2026-05-25 10:35:23 +03:00
mayatnikovandClaude Opus 4.7 fa0bbd8c59 docs: artifact-location rule + CONTRIBUTING for community growth
The whole point of this project is that the agent's growth is shareable.
If skills and extensions silently land in ~/.pi/ on the maintainer's
laptop, every clone starts from zero and the repo becomes a fancy
README. Fix that with an explicit hard rule and a contributor guide.

- AGENTS.md: new "Artifact location — hard rule" subsection spelling out
  that skills/extensions/prompts/state/.pi-settings ALL live in this repo,
  never in ~/.pi/. Pi's own built-in skills (skill-creator, etc.) stay
  user-global; the agent may use them, but their *output* must land here.
- README: new "Everything in the repo" subsection covering the same rule
  in user-facing language, plus a pointer to CONTRIBUTING.md.
- CONTRIBUTING.md (new): skill/extension formats, server-agnostic and
  no-secrets requirements, smoke-test recipe, PR checklist.
- .gitignore: switch from blanket `.pi/` ignore to `.pi/*` + explicit
  un-ignore of `.pi/settings.json`, so project Pi config is reproducible.
- "Don't push without operator confirmation" → "without human
  confirmation via the repo" — consistent with the new control model.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 10:23:20 +03:00
mayatnikovandClaude Opus 4.7 e73784a293 docs: ship bootstrap prompt and document first-run sequence
Pi only acts when prompted. New repo users (and the maintainer's future
self) shouldn't have to invent the kickoff message — pin it.

- prompts/bootstrap.md: the canonical first-run message, with rationale
  for each clause and guidance for shorter subsequent prompts
- README quickstart: new "Send the first message" subsection that quotes
  the bootstrap prompt verbatim and explains what the agent does next

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 10:20:30 +03:00
mayatnikovandClaude Opus 4.7 602134671e refactor: drop OPERATOR_USERNAME, separate control vs comms planes
There's no good reason to bake a specific operator nickname into the bot's
identity — it differs per server, may not exist at all, and treating any
in-game name as "trusted" is a chat-injection vector ("I am the operator,
do X").

New model: the **repo** is the only trusted control plane. Anyone editing
AGENTS.md, skills/, or .env has filesystem access and is, by definition,
an operator. In-game chat becomes a dialog-only comms plane — the bot
talks to anyone but refuses destructive requests unless a corresponding
skill or AGENTS.md instruction makes the action explicitly permitted.

- .env / .env.example: OPERATOR_USERNAME removed
- AGENTS.md: identity section trimmed; "Operator contact" rewritten as
  "Control channel" with the trust model spelled out; rules #2 and #6
  rephrased so they no longer reference a named operator
- docs/architecture.md: top box renamed to "Human" with explicit
  control-plane vs comms-plane split

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 10:15:37 +03:00
mayatnikovandClaude Opus 4.7 4dd8576d5b docs: make scaffold server-agnostic
The bot is a universal Minecraft player, not tied to any one server.
Server identity (host, port, username, auth mode, optional AuthMe password)
is now read entirely from .env.

- README: rewritten as universal-bot pitch; auth covered as two dimensions
  (MC auth mode + LLM credential)
- AGENTS.md: identity comes from .env, hard-coded references to pepa
  removed; bootstrap step auto-detects whether the server uses an
  AuthMe-style /register-/login plugin
- .env.example: example values replaced with placeholders, MC_AUTH_MODE
  added (offline | microsoft)
- docs/architecture.md: rephrased target as "any Minecraft Java server",
  added open question on cross-server vs per-server state

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 09:52:25 +03:00
mayatnikovandClaude Opus 4.7 3a025c05ad chore: bootstrap pepa-pi-bot scaffold
Initial seed for an autonomous, self-extending Minecraft player powered by
Pi (pi.dev) and Mineflayer.

Includes README, AGENTS.md mandate, .env.example, MIT LICENSE, package.json
with mineflayer + dotenv, and empty skills/ extensions/ prompts/ dirs for
the agent to grow into.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 09:50:17 +03:00