Persistent pantry-backed grocery checklist for OpenClaw, with Telegram inline buttons for marking items bought. Use when the user says they ran out of something, bought something, wants to see what groceries are needed, or taps grocery checklist buttons in Telegram.
Use this skill when the user wants a real grocery workflow, not a generic todo list.
This skill is the source of truth for:
Run the local wrapper directly:
bash <skill_dir>/scripts/grocery.sh ...
Do not use ACP, sessions, or memory files for grocery state.
When tools are available:
mutate_grocery_items for state changesrender_grocery_view for Telegram shopping/pantry UIItems only have two meaningful states:
neededhaveInterpret user intent as state changes:
I ran out of salt -> neededadd eggs and milk -> neededI bought eggs -> havemark milk bought -> haveExecution safety rule:
I didn't buy X, I forgot X, put X back -> needed (undo)This is not a task list. Do not create duplicate items for the same ingredient.
When the conversation contains Telegram metadata with a sender_id, treat that as the Telegram target for checklist rendering.
Stay conversational for normal grocery chat. Do not behave like a rigid command parser.
Intent guidance:
I ran out of salt, add eggs, put milk in the shopping list -> mutate grocery statemutate_grocery_items first; do not render as a substitute for the mutationwhat do I need to buy, show me the shopping list, shopping view -> render shopping listi'm shopping now, i'm going shopping now, and similar “I am shopping now” phrasing -> render shopping list immediatelyshow me the pantry, what do I have -> render pantry viewI bought eggs, got milk, picked up bread -> mark items haveI didn't buy X, I forgot X, missed X, put X back on the list -> revert to neededfix olive oil, merge requests, and rename requests -> canonicalize grocery itemsshould I go shopping today? or similar -> inspect current grocery state and answer briefly based on what is still neededTelegram button clicks arrive as plain text like:
callback_data: gchk:have:abc123def4
If the callback starts with gchk:, call:
bash <skill_dir>/scripts/grocery.sh handle-callback "<raw callback text>" --target "<sender_id>" --account grocery
The script will update state and redraw the Telegram checklist.
For Telegram UI actions:
render-telegram--mode allgchk:... callbacksdo not add a second explanatory message after the UI updates. The ideal model output after a successful UI action is exactly NO_REPLY.
Mark items needed:
bash <skill_dir>/scripts/grocery.sh need "salt" "eggs"
Mark items bought / in stock:
bash <skill_dir>/scripts/grocery.sh have "salt"
Remove items:
bash <skill_dir>/scripts/grocery.sh remove "salt"
Show current shopping list:
bash <skill_dir>/scripts/grocery.sh show
Render the Telegram checklist (--target is optional; omit to send to all active viewers):
bash <skill_dir>/scripts/grocery.sh render-telegram --account grocery
Show items that have been needed for more than 14 days:
bash <skill_dir>/scripts/grocery.sh stale
Override threshold:
bash <skill_dir>/scripts/grocery.sh stale --days 7
Render pantry view instead:
bash <skill_dir>/scripts/grocery.sh render-telegram --account grocery --mode all
what do I need to buy, render the Telegram checklist when sender_id is present; otherwise show the plain text list.sender_id is present.--mode all.Default state file:
~/.openclaw/data/grocery-checklist/state.json
Override with:
GROCERY_STATE_FILE