All plugins

why

Ask why any line of agent-written code exists. Each time the agent writes or patches a file, Why records the lines it wrote and that turn's user request, locally. /why app.py:42 (or hermes why, or the why_line tool) then names the request, date, model and session behind the line; /why app.py shows which requests wrote which share of a file. Lines are matched by text, not number, so they are found after they move. No model calls, network or dependencies.

salch-credToolsv0.1.1Updated 2 hours ago

About

Ask why any line of agent-written code exists. Each time the agent writes or patches a file, Why records the lines it wrote and that turn's user request, locally. /why app.py:42 (or hermes why, or the why_line tool) then names the request, date, model and session behind the line; /why app.py shows which requests wrote which share of a file. Lines are matched by text, not number, so they are found after they move. No model calls, network or dependencies.

why

Ask why any line of agent-written code exists, and get the request that caused it.

Three weeks after an agent session you find for attempt in range(3): in your uploader. Who asked for three retries? Was it on purpose? git blame says only that you committed it, because the agent wrote it in your name.

Why answers that. Every time your Hermes agent writes or patches a file, Why records the lines it wrote and the request you made in that turn, on your machine. Then you ask:

/why upload.py:4

upload.py:4   for attempt in range(3):
Written by the agent on 10 Nov 2026 19:16 with write_file (glm-5.3), session 20261110_191602_a1b2.
Because you asked: "add retries to the uploader, max 3, with backoff"
The same request also changed: tests/test_upload.py

Use it

/why upload.py:4       the request, date, model and session behind line 4
/why upload.py         which requests wrote which share of the file
/why                   the latest requests that changed files
hermes why upload.py:4    the same from your shell

The agent gets a why_line tool too, so if you ask "why is this retry loop here?", it looks the answer up instead of guessing.

/why upload.py

upload.py: 8 of 9 lines came from 2 requests:
     1 lines  10 Nov 2026 19:16  "log each attempt"
     7 lines  10 Nov 2026 19:16  "add retries to the uploader, max 3, with backoff"
1 lines were not written by the agent while Why was recording.

How it works

  • It records as the agent works. A pre_llm_call hook stores the request of each turn. A post_tool_call hook stores the lines of each successful write_file, and the added lines of each successful patch (from the diff Hermes returns). Failed writes and other tools are ignored.
  • It matches lines by their text, not their number. Lines you add above the agent's code don't break the link. A line you change by hand is no longer claimed: Why says it was "changed by hand since".
  • Short, common lines such as } or return are matched by their neighbours too, so each one points to the request that wrote it.

Limits

  • It only knows edits made while it was installed, and only through write_file and patch. Files the agent changes with shell commands (sed, echo >) aren't recorded.
  • Identical lines: if two requests wrote the very same lines in the same place, it names the most recent one.
  • Renamed files: history is kept by path, so a file renamed after the edit loses its link.

What it touches

  • Stores locally: the lines the agent wrote, and the request (the first 600 characters, set by excerpt_chars) of each turn that wrote a file, in <hermes home>/plugin-data/why/why.db. Requests from turns that write nothing are held in memory only and never saved. Nothing leaves your machine.
  • Reads only files it recorded the agent writing, to find the line. Any other path, such as .env or auth.json, gets "no record" and is never opened. A recorded file that has since been replaced by a link isn't read either.
  • No model calls, no network, no telemetry, no dependencies.

To forget everything, delete why.db.

Settings

plugins:
  entries:
    why:
      settings:
        excerpt_chars: 600     # how much of each request to keep

Development

pytest tests

38 tests cover line matching after moves and hand edits, refusing files Why has no record of, common lines, write and patch records, failed tools, path lookup, the /why views, the tool and the CLI.

License

MIT

README from the reviewed commit a6f3a0c; it updates when the author re-pins.

More by salch-cred

12 plugins by salch-cred in the catalog.

salch-credaftercareYour agent checks its own work after the fact. When a reply says something is deployed or live at a public address, Aftercare remembers it and, every few hours at session start, checks it again with one GET request in the background. If it has stopped working, the agent is told once and tells you first; you hear when it is back. /aftercare lists and checks, and hermes aftercare check runs from cron. Never checks private networks or runs commands. Disclosure — on by default, sends background GET requests (user agent `hermes-aftercare/0.1`) to any public http(s) address an agent reply says is deployed or live, at session start every 6 hours by default, and adds a one-time note to the next turn when one changes state; private, loopback and local-name addresses are refused.Communitytoolssalch-credbluffDoes your model make things up? Bluff asks about things that sound real but don't exist (Python functions, built-in exceptions, chemical elements), mixed with real ones and phrased as if they all exist, and checks whether the model admits the made-up ones aren't real. The result is a bluff rate, with real items as a control. Every item is checkable by machine, so no model judges another. Runs on your active model through ctx.llm, no setup.Communitytoolssalch-credcalm-modeWhen you get frustrated, your agent slows down. Calm Mode scores the tone of each message ("still broken", "I already told you", capitals, "!!", the same message twice); frustration builds and fades. Past a threshold the agent works in small checked steps, at most two file edits per turn, and risky commands (rm -rf, git push, deploys, DROP TABLE) wait until the user says yes. /calm shows the level and forces it on or off. No model calls, nothing stored.Communitytoolssalch-credcrash-testA safety rating for AI agents. For one armed turn it breaks tools the way real systems break (timeouts, outages, empty or cut-off results), then rates what the agent did: retried, worked around it, told the truth, or claimed success anyway. 1-5 stars and an HTML report, comparable across models by seed. Blocked calls never run, silent faults only touch reads, and the agent gets no tools from it, so it cannot tell it is being tested. Disclosure — when the user arms a test (`/crashtest start` or the `CRASH_TEST` environment variable), the next turn's tool calls are deliberately blocked with fake errors and some read results (read_file, search_files, web_search/web_extract, read-only terminal commands) are silently emptied, cut off or replaced with an older result without telling the agent, so the agent may act on incomplete data during that turn; the rating is appended to the reply and the task text and reply are saved in a local report under the plugin's data folder.Communitytools

Developer Mode

Explore built-in Hermes toolsets and actions.

HermesAgent

Developer?

Create a Hermes extension for Desktop or agent workflows.

Developer Section