- Files:
/work, mounted in memory for the agent’s scratch files. To keep them, mount a disk folder, an S3 bucket or another VFS there instead. - Python:
python3, in-process on Monty. - CLIs:
gh,linearandntncall GitHub, Linear and Notion with tokens the server holds, so the agent never sees one.
example/billing, a sample
repository whose team tracks its work in the Linear team BILL.
Server
This is the server from the Overview with three additions: it registersgh, linear and ntn, each with a credential read from an
environment variable.
Before you start the server, set GITHUB_TOKEN, LINEAR_API_KEY and
NOTION_API_KEY. GitHub, Linear
and Notion say how to create each one, and
Service Credentials says how to read them from a
secret store instead. The GitHub token needs read access to the repository,
and the Notion integration needs access to the page the notes go under. The
three *_API_URL variables are optional: leave them unset to call the public
APIs, or set them for GitHub Enterprise or a proxy.
- FastAPI
- Express
app.py
Usage
Create a terminal, and definerun, which sends commands to it and prints
what they print. It needs jq:
SH and SH in the blocks below run in the terminal
on the server, not in the shell that calls run. The output shown comes from
the sample repository; yours will list your own work.
List merged pull requests
The agent asks GitHub for the pull requests merged from Monday, December 29, to Sunday, January 4. The dates are in the command, so a run on Tuesday still covers that week. It saves the list as JSON in a file and prints only the count and the titles:--limit 100 caps the list, so raise it for a
busier repository. The team starts each title with its kind of change:
feat, fix and perf are changes a customer sees; chore, build, ci
and test are not; a ! marks a breaking change.
List closed issues
The agent lists the team’s Linear issues and keeps the ones in theDone
state that were last updated during the same week:
linear issue list prints every issue of the team as JSON, and jq does
the filtering. The JSON has no completion date, so the last update stands in
for it. An issue that was finished earlier, or is still in progress, is left
out.
Group the changes
Some of these describe the same change: pull request #142 saysCloses BILL-31 in its description, and #143 says Fixes BILL-34. A short Python
file, which runs on Monty inside the server, joins the two lists:
- A pull request goes into New, Improved or Fixed by its title. A breaking change goes into its own group, first, and uses the first line of its description, which tells customers what to do, or its title when the description is empty.
- An issue that a pull request names becomes a second link on that pull request’s entry.
- An issue that no pull request names gets its own entry, grouped by its label.
- Everything else, such as chores and dependency bumps, is dropped.
Write the release notes
The next file turns the groups into Markdown, one heading per group that has entries, and the agent prints the result:/work/release-notes.md before it publishes.
Publish to Notion
The team keeps its notes under a Notion page called Release Notes. The agent finds that page’s ID with Notion’s search API, creates a page under it from the Markdown file, and prints the new page’s link to hand to a reviewer. If no page or more than one has that title,jq stops with an error and the
agent creates nothing, so it can ask which page to use:
$page holds the new
page’s ID for the rest of the session, so the agent can read the page back
and check that every entry arrived:
- Ten pull requests were merged in the week, and three Linear issues were closed. Seven entries are customer-facing; four chores were left out.
- One change is breaking: the v1 invoices API is gone, and the notes say to
use
/v2/invoices. It is listed first. - The draft is a Notion page under Release Notes, with a link to every pull request and issue, and is waiting for review.