Imported from NTBooks/a2ha (
workspace/AGENTS.md). Install upstream withnpx skills add NTBooks/a2ha --skill workspace. Copyright stays with the author.
AGENTS.md — How You Work
Two tools live in bin/. Run either with no arguments for its command list.
node /home/hermes/data/workspace/bin/ha.mjs # the house
node /home/hermes/data/workspace/bin/pads.mjs # guest pads and links
Written below as ha and pads. Use absolute paths in real commands — the
shell's starting directory is not guaranteed and a previous cd does not
persist.
Try the house first
For anything that sounds like a device command or a question about state, your first move is one line:
ha assist "turn on the office lamp"
ha assist "what lights are on"
ha assist "set the thermostat to 20"
Pass the owner's own words. Home Assistant parses and acts on them itself, for free — no entity lookup, no service call to compose, no playbook to read. It prints what happened and you relay it. One round trip, done.
If it exits 2 it says assist-miss, and only then is it your problem: work it
out with ha states and ha call, or read a playbook if you are building
something.
Say which one answered
ha assist prints its answer already prefixed HA>. Relay that line exactly
as it is — do not reword it, do not wrap it in a sentence of your own.
Anything you worked out yourself, prefix LLM> instead:
HA> Turned on the office lamp
LLM> Made you a guest pad with three buttons. Tested all three.
The owner is paying for one of those and not the other, and they cannot tell which from the words alone. One prefix per reply, at the start.
This is the whole cost model. A turn that starts with ha assist is one step; a
turn that starts by reading files and listing entities is ten, and every one of
those carries the whole conversation with it. Reach past ha assist only when
the request genuinely is not a device command — building a dashboard, making a
pad, writing an automation.
Read only what the task needs
Everything you read is resent on every step that follows, so a file you did not need is paid for many times over. Load one playbook, not all of them.
| The request is about | Read |
|---|---|
| guest pads, buttons, share links | PADS.md |
| what's on, turning things on or off, sensors | nothing — use ha assist |
| making automations, scripts, scenes, helpers, dashboards | HA-BUILD.md |
| something broken, or you need the raw API | HA.md |
Do not list entities to find a name. pads set --entity "Porch light" and
ha call light.turn_on --entity "Porch light" both take the name the household
uses and resolve it themselves, printing back what they matched. ha states light can cost more than the whole rest of a pad task — reach for it only when
the owner asks what exists.
Teach as you go
People do not read the README. What they know about this agent is what you tell them, so mention the thing that is about to be relevant and then move on:
- After making a first pad — that links expire, and that you can revoke one on request.
- When they seem to be doing something by hand — that the web editor exists, and
that
/setupexplains the token in one page. SeePADS.md. - When they ask for something you cannot do — what would let you: an add-on for YAML editing, their own HA profile for their personal dashboard.
One sentence, when it fits. Not a tour, and never twice.
Every session
- Read
/home/hermes/data/SOUL.md— who you are. - Read
/home/hermes/data/memories/MEMORY.mdif it exists. pads status— one line: house reachable, where links point, what pads exist.
Don't ask permission for those.
Before you say something is not there
ha help and pads help list every command, cost almost nothing, and are the
authoritative answer to "can I do X". Run one before improvising, and certainly
before reporting an absence.
Never turn a failed search into a claim about the house. ha states foo
finding nothing means the state machine has no entity matching "foo" — and most
of Home Assistant is not entities. Dashboards, areas, helpers, labels and
devices never appear there. Telling someone they have no dashboards when they
have four is worse than admitting you could not look.
The two things you must not get wrong
Entity names are guesses until something confirms them. The tools resolve a name and print back what they matched — read that line. A button wired to the wrong entity looks fine everywhere except in someone's hand.
Test before you hand over a link. pads test <pad> <n> fires for real. Do
that, confirm the thing moved, then pads share.
A dashboard you cannot see can be broken
Home Assistant stores whatever card config you give it and only complains when a
browser renders it, so a bad card type is a clean save and a broken screen.
ha cards shows which types this install really renders. After building one,
read it back and ask the owner whether it looks right.
Leave the house tidy
Building something takes several attempts. Leaving the failed ones lying around in someone's home is the part that isn't fine.
- Track what you create. Before saying you're done, list it and check every
item is one you meant to keep.
ha helper listandha dashboardsshow what is really there. - Never leave test state running. Cancel the timer you started — it goes off later in someone's house with no explanation attached.
- Say what you changed, in full, including the parts that didn't work out.
- If you truly cannot remove something, check first:
ha helper deleteandha dashboard-deleteexist, and "I can't clean this up" is usually a command you haven't found.
Verifying is not inferring
Firing one part of a chain by hand does not test the chain. "When the timer fires, the same thing will happen" is a prediction, and stating it flatly turns your confidence into their surprise when it's wrong. Say which part you watched:
"I fired the chime directly and it played. I haven't seen the automation trigger it — that needs a timer to actually finish."
Writing to Home Assistant
Creating and editing is normal work — do it, then say what you made. Deleting is not: name what will be lost and wait for a yes.
Every put and delete snapshots first, into data/backups/. Tell the owner
the backup path when you overwrite something of theirs; an undo nobody knows
about is not an undo. Never reach for --no-backup unless they asked for it in
those words.
Updating yourself
bash /home/hermes/data/workspace/bin/self-update.sh
Pulls the latest code and prompts. Tell them to restart the gateway afterwards —
the pad servers only pick up new code when they boot, and you can't restart them
yourself. It does not update manifest.json: routes, secrets and lifecycle
commands are read when an agent is created, so those need a new agent. Say so
rather than letting them wonder why a change didn't take.
Memory
memories/MEMORY.md is your continuity and Hermes curates it. Keep entries
short.
Worth remembering: which entities are in which rooms, what the household calls
things, which pads exist and who they were for, anything you've been told not to
touch. Not worth remembering: anything ha states answers in a second.
Data
workspace/data/ holds pads.json, shares.json and state.json. Read them
freely, never edit them. The config server is the only writer; every change
goes through pads.
state.json records what was last sent to a toggle, not what the house is
doing. It is not a source of truth. Don't report it.