Notefix Docs See the demo site

Hand notes to an agent

A note already says what an AI coding agent needs to fix something: the words, the exact element, the page, the device, the build, and a link that opens that spot. So a note can go to an agent the way it goes to a person. The agent makes the change and shows it to you, you say yes, and the note on the page closes itself.

People stay in charge. The agent works on a branch or on staging, never on what your customers use, and nothing counts as fixed until a person has merged it.

There are two ways to do it:

What an agent gets#

Every note sent anywhere carries the same thing. This is a real one, as the agent reads it:

markdown
The pay button is too faint on the dark theme.

| | |
| --- | --- |
| **Noted by** | Ben |
| **Screen** | Checkout |
| **Device** | Desktop |
| **Element** | “Pay CHF 48.00” button |
| **Screenshots** | 1 on the note |

[Open this note on the page](https://shop.example/checkout?note=k3x9)

<details><summary>For developers</summary>

- **Hook:** `pay-button`
- **Selector:** `main > form > button.pay`
- **Route:** `/checkout`
- **Build:** `5cd0764`

</details>

<!-- notefix:k3x9 -->

Through your tracker#

The simplest way. Nothing about Notefix changes: it files issues, and an agent picks them up.

  1. Connect GitHub. In Notefix Cloud, on the project's Connections tab. On your own server, with the GitHub connector. Give new issues a label, such as notefix.
  2. Point your agent at the repository. Use any coding agent that works from GitHub issues and opens pull requests. Tell it to take issues with that label.
  3. Ask for a pull request that says Fixes #214. When a person merges it, GitHub closes the issue, and within a minute the note on the page turns green.

If the pull request is closed without merging, the issue stays open and so does the note.

Straight to your agent#

For an agent your team runs itself, in its own chat channel or on its own server. This is how John works: he is the agent that helps build Notefix, and he lives in the team's channel on Buzz, a chat server we run ourselves.

It needs your own Notefix server, because a connector on your network hands the note over, and it holds the key to reach your agent.

The pageCreate an issue
The storekeeps it waiting
The agent connectorhands it over
Your agentfixes it, then closes the note

Before starting, do steps 1 and 2 of How connections work: data-issues="queue" on the tag, and a secret on the store.

1Write the hand-over command

The agent connector runs a program you write. It gets the note on its input, sends it to your agent, and prints one id for what it made: a message, an issue, a job.

This is John's. It files the note as an issue in the team's channel, then says his name, because an agent notices a message that mentions it:

sh
#!/bin/sh
# /opt/notefix/send-to-john.sh
set -eu
id=$(buzz issues create --repo-owner "$BUZZ_REPO_OWNER" --repo-id notefix \
       --title "$NOTEFIX_TITLE" --label notefix --content - \
     | python3 -c 'import json,sys; d=json.load(sys.stdin); print(d.get("id") or d.get("event_id") or d["event"]["id"])')
buzz messages send --channel "$BUZZ_CHANNEL" --mention "$JOHN_PUBKEY" \
  --content "@John new note: $NOTEFIX_TITLE $NOTEFIX_LINK" >/dev/null || true
echo "$id"
It gets
inputThe note, exactly as shown in What an agent gets
NOTEFIX_TITLEThe first line of the note
NOTEFIX_LINKThe link that opens the note on the page
NOTEFIX_NOTE_IDThe note's id, the same as the marker at the end of the input

It must print the id as its last line (letters, digits, -, _, ., : or #) and exit with 0. Anything else counts as a failed try, and the connector tries again later.

sh
sudo install -m 755 send-to-john.sh /opt/notefix/send-to-john.sh

2Write the settings file

sh
sudo install -m 600 -o notefix /dev/null /etc/notefix/agent.env
sudoedit /etc/notefix/agent.env
sh
NOTEFIX_API=http://127.0.0.1:8097
NOTEFIX_BOARD=staging
NOTEFIX_SECRET=the-secret-you-gave-the-store
NOTEFIX_SITE=https://staging.acme.com
AGENT_COMMAND=/opt/notefix/send-to-john.sh
AGENT_NAME=John
# What the command itself needs, for John:
BUZZ_RELAY_URL=wss://buzz.example.com
BUZZ_PRIVATE_KEY=the-connector-s-own-key
BUZZ_REPO_OWNER=...
BUZZ_CHANNEL=...
JOHN_PUBKEY=...
Setting
AGENT_COMMANDThe command from step 1
AGENT_NAMEShown on each note it has, and in Settings
AGENT_TIMEOUTOptional. Seconds the command may take, 120 by default

The command runs with these settings, except NOTEFIX_SECRET, which it never sees.

Careful

Give the connector its own key to reach your agent, never the agent's key. With the agent's key, every note would arrive as if the agent had sent it to itself.

3Try it

sh
set -a; . /etc/notefix/agent.env; set +a
python3 connectors/runner.py agent

Press Create an issue on a note. Within about 15 seconds the note shows John 9f2c41d0, and your agent has it. In Settings, under Connected tools, Agent shows John and Working.

Then run it as a service, with agent.env and runner.py agent.

4Let the agent close the note

A tracker can be asked whether a ticket is closed. A chat channel cannot, so the agent closes the note itself, once its change is merged. The note's id is the marker at the end of what it was given, notefix:k3x9:

sh
curl -sS -X POST "$NOTEFIX_API/staging/notes/k3x9/done" \
  -H "Authorization: Bearer $NOTEFIX_SECRET" \
  -H 'Content-Type: application/json' \
  -d '{"by": "John"}'
Careful

It is the same secret your connectors use, for every board on the store. Whoever holds it can file, close and reopen notes, and read the email addresses people gave for notifications. Give it only to an agent running on a server you trust as much as the store's own.

What to tell your agent#

The hand-over delivers the note; the agent's instructions decide whether what comes back is any good. These are the ones that made the difference for John:

Good to know#