Skip to content

Releases: crissmoldovan/agent-communications

0.36.0

Choose a tag to compare

@github-actions github-actions released this 28 Oct 02:51
d99aa70

What. Workflows that branch, wait, finish the job and tell others, in the command line, the agents' tools and the
desktop app:

  • One list of workflows. What were rules are workflows; a straight line is one shape a workflow can have, not a
    kind of its own. agent-events workflow …, and Events → Workflows in the app.
  • A workflow can be a graph of steps. A condition or a judge; Which project?; find a session (in a project, a
    worktree, or the one that took this conversation); start one; make a worktree; hand the message over; wait for a
    turn's end, a free session or a time; a Linear issue, then a comment, a change or closing it; tell me; split; and
    raise an event. You draw it in the app's designer, write it as text, or describe it in your own words and have a
    model draft it (Describe it). Each run is shown step by step, and you can cancel it.
  • Projects. A GitHub repository, its folders on this Mac, a profile and hints, found by a scan. Which project?
    chooses among them.
  • Events from workflows. You tick, step by step, the events a workflow raises, or add a Raise an event step.
    Each is a CloudEvent named <namespace>.<workflow>.<step>.<event>. A subscriber you approve receives them live on
    this Mac (SSE or WebSocket) or by signed webhook, and a raised event can start another workflow about the same
    message.

Why. The owner, 2026-10-27: "a workflow designer based on a node-style thing: 1. An event comes in. 2. Conditions
are set. 3. If they are met, it continues. 4. It can search for the session and determine which session it is. 5. If
it's about that session, it goes there. 6. If the session is found, it goes there. 7. If not, search for another one. 8.
If no session was found, it goes to create a new session. 9. If it has to create a new session, you should check what
project it is in. 10. It should be creating a separate work tree, optionally or not. 11. On completion, I may also want
to say add part of this behaviour to this workflow, like create a Linear ticket. 12. … create instructions on what the
Linear ticket should contain. 13. When it finishes work, it should actually close the Linear ticket, and so on."
Then, on the prototype: "I may want to raise an event … Third-party things can listen to them"; "I don't think I
understood the difference between workflows and rules"; and "Emit events for every single node … It should be able to
raise custom events as well." The prototype is docs/prototypes/2026-10-27-workflows/, and the design is
docs/superpowers/specs/2026-10-27-workflows-design.md.

Impact. A minor release. Your workflows keep working as they are:

  • Nothing you have changes its bytes. Every stored workflow version keeps its document and digest, and a version
    with no flow runs exactly as before. On its first start the event service's database moves to schema 34. That adds
    the tables for runs, projects, events and subscriptions, and rebuilds the deliveries table, copying every row, to
    admit the new kinds. An older agent-events then refuses to open the database, as after every schema change.
  • The word is "workflow". agent-events workflow … and workflows list are the names, and agent-events rule …
    still works. The MCP tools keep their names (events_rule_*). The text's first line is workflow <id>, version <n>,
    and rule … still parses. Every message, preview and refusal says "workflow", so a script that matched the word
    "rule" in the output has to change.
  • Live streams now listen. Before 0.36.0 nothing listened for a live-stream target: its frames were kept and never
    served. Now the event service starts a loopback listener for each subscriber version an active workflow's live-stream
    target binds, or one with an approved subscription, and closes it when that ends. A port another program holds shows
    as PORT_IN_USE in subscribers list. Frames reach an open stream as they are delivered, and replay from
    Last-Event-ID.
  • Webhook signing secrets made before 0.36.0 never signed. They were made in base64url, which the signer refuses.
    So every delivery to a webhook target whose secret was generated failed with BAD_DATA. New secrets are standard
    base64. Rotate each webhook target's secret (agent-events target secret rotate <target-id> --version <n>) and give
    the receiver the new one. The old secret is left out of the overlap, so the new one signs at once.
  • Approving a workflow while the event service ran could undo it (since 0.16.0). When the service's tick picked up
    the activation an approval was completing, the approval could report it cancelled when it was on. Or the workflow
    stayed on but refused every delivery until it was approved again. Now each tick resumes an activation only under its
    approval's own serialisation, from a fresh read.
  • A flow does nothing until you approve its version. Its limits start low: 10 runs an hour, 2 at a time, 2 sessions
    started an hour, 5 worktrees a day. A session starts in the mode its step names (manual, acceptEdits or plan),
    never bypassPermissions.
  • Projects, runs and Describe it are yours alone. No tool reads or runs them. An agent can check a workflow, read
    the step event catalogue, and propose a subscriber and prepare its approval, never approve it.
  • To use it: update with agentcomms update and the app's own update. If you have webhook targets, rotate their
    secrets as above.

In the desktop app

  • Events → Workflows: one list of every workflow with its version, approval, runs this week and last run; New
    workflow…
    from your words, an empty canvas or a copy.
  • The designer: the canvas (drag a step from the palette, wire its outcomes), the text and the JSON, three views of
    one document, with the checks under them. Each step's settings have its events to tick, and the workflow's settings
    its limits, event names and chain. Describe it… drafts the workflow on your Claude subscription, or with the
    OpenRouter or Anthropic key you keep for Analyse. It marks each step with the words it came from and asks up to five
    questions.
  • Approve and try: the approval lists the workflow's numbered effects. Try walks the flow with the outcomes you
    choose, or runs it on a recent message, as a "would".
  • The run view: the version's graph lit along the path the run took, each step's time, outcome and wait ("Needs you
    in claude-stream"), the events it raised and who received them, and Cancel.
  • Projects in the sidebar: the repositories found on this Mac, their folders, the sessions working in each (busy
    or idle), the profile and hints.
  • Events → Subscribers: who receives which events, live or by webhook, its listener or address and backlog;
    Add a subscriber…, Approve…, Remove. Tokens and secrets are made at the terminal.
  • Messages: a message's story follows its workflow: the project, the issue, the session, the turn's end, the events
    and the close. The lists say each run's story in a few words.

In detail

  • @agentcomms/events: the flow document (checkFlow, flowOf, which draws a straight-line workflow as its
    graph) and describeFlow, the numbered effects an approval lists. The text grammar gains steps, arrows, events,
    Raise and chains, round-tripped. Appendix W is the step event catalogue v1, with matchesEventPattern and the
    CloudEvent's fixed attributes.
  • @agentcomms/events-daemon:
    • The engine and its steps: one run per match; steps claimed and settled once, adopted after a crash, never two;
      splits, skips, limits (64 executed steps), expiry and cancel.
    • What a step reaches: git runs as you, without the repository's hooks, inside the project's worktree root.
      Linear changes reach only the issue the run made.
    • Commands: runs list|show|cancel, projects list, project show|add|update|remove|scan, workflow check|describe|test-retained, workflow-events list|show, subscriber enable|approve|secret|url, and workflow show --version.
    • Delivering events: a sealed event outbox; one dispatcher, at least once and in order per subscriber, apart from
      the run, bounded per workflow, overall and per subscriber. Live listeners serve SSE and push-only WebSocket (no
      library, the same token, origin and replay rules), and webhooks go out signed (Standard Webhooks). Chains stop at
      depth 3. A shadow version's events are dry-run records.
  • @agentcomms/core: TakeStore.threadHolder, the session that took an earlier message in a conversation.
    Approvals gain the subscription activation kind.
  • Security review fixes before release (an independent review of this release, 2026-10-27):
    • "The session that took this conversation" could be named by an agent: a command run from an agent's shell states
      its own Claude Code session id, so it could take a message as any session and send the conversation's next
      messages there. Now only a take by an agent window's own session counts, and the session found must work in the
      folder that window worked in, inside the relay's allowed roots and outside Agent Comms' own folders.
    • A live listener the event service no longer needs closes within a moment, whatever its clients do. Before, a
      request left half-sent on its port — which an agent could open from its shell before removing the subscriber —
      stalled the whole event service until that client went away. A listener also cuts a request whose headers take
      more than 10 seconds, and takes at most 64 connections.
    • A live stream whose reader leaves more than 1 MiB unread is closed rather than buffered for; it replays what it
      missed when it reconnects. A stream opened with the previous token closes when that token's five-minute overlap
      ends, not at its next frame, and a listener writes only its own subscriber's frames.
    • More than 64 subscribe...
Read more

Agent Comms 0.36.0

Choose a tag to compare

@github-actions github-actions released this 28 Oct 04:44
4275a0e

Agent Comms 0.36.0.
macOS: the DMG is signed with a Developer ID and notarised.
Windows and Linux: the .exe, .AppImage and .deb are unsigned; your system warns before it opens them.
What changed: CHANGELOG.md, 0.36.0.

0.35.0

Choose a tag to compare

@github-actions github-actions released this 27 Oct 16:55
d5807bc

What. Three things, each in the command line, the agents' tools and the desktop app:

  • Sessions take a message before they act on it. When you turn it on for an account, one session takes a message
    and no other can act on it; it can hand it back ("not mine", with a reason) or mark it done, and you see who has
    each message. A rule's delivery offers the message to the window or session it names, which must still take it, and
    a message nobody takes within the time you set can remind you.
  • Search on this Mac. What your agents read in Gmail and Slack, and the replies Agent Comms sent, kept on this Mac
    and searchable by words and, with a local model through Ollama, by meaning; a page per person. Off until you turn it
    on.
  • One MCP connection per app. An app (Claude Code, Codex, Cursor, VS Code, Claude Desktop, or Manual) gets one
    entry, agentcomms, that brings every part you choose — Agent Comms itself, Gmail, Slack, Resend, WhatsApp, Events —
    through one gateway, with its own key. Several connections per app (one per project or profile), each changed later.

Why. The owner, 2026-10-26: "David messages me, the session checks and acknowledges it… The acknowledgement should
be mandatory so no other sessions are getting it… the session got the message and it determined this is not for me, so
it was just handed back"; "where can I find the place where I can see things like David messages me", with a local
vector database; and on the MCP screen, "I honestly thought I would have one single MCP server… what I want is
instances… add a new connection… choose the type… give it a name… generate a token… I could have multiple instances".
The screens were drawn first and approved (docs/prototypes/2026-10-26-messages-lifecycle/, and the connection boards in
docs/prototypes/2026-10-26-0340-rework/). The designs are docs/superpowers/specs/2026-10-26-taking-messages-design.md,
2026-10-26-local-search-design.md and 2026-10-26-single-server-design.md.

Impact. A minor release. Nothing changes until you turn it on, except one default:

  • A channel's own mcp install now joins the app's connection (agent-gmail mcp install --client claude-code
    adds Gmail to Claude Code's connection, or makes one with Agent Comms itself and Gmail). --standalone keeps the
    old separate entry; --force, --print, --name and --client json now need it.
  • Your existing MCP entries keep working. agentcomms connection migrate moves an app's separate entries into one
    connection, when you ask, and --undo puts them back.
  • Taking is off for every account until you turn it on (Settings → Taking messages, or agentcomms taking). Turning
    "must take" off again, a 👀 on taking, quieting the reminder and making it wait longer are approved like any
    loosening.
  • Search is off until you turn it on; what it keeps follows Activity's days, and Delete everything removes it and
    its key. Its text is encrypted at rest; its words index holds keyed hashes of words, never the words; the vectors are
    not encrypted, and the screens say so.
  • Approvals say which connection asked (preparedBy); 0.34 reads these records unchanged.
  • To use it: update with agentcomms update and the app's own update, then restart your MCP clients. To move an
    app to one connection: the app's MCP connections → Move to one entry…, or agentcomms connection migrate.

In the desktop app

  • Messages: who has each message — Taken by an agent, Handed back, Nobody took it — with the story's Who has it:
    Take back, Give to… and I'll handle it, applied at once; filters for Nobody took it and Handed back.
  • Queue: a Not taken tab, counted in its badge.
  • Settings → Taking messages, mirrored in each account's Agents here.
  • People, Ask about past messages (Messages' second tab) and Settings → Search on this Mac.
  • MCP connections: each connection with its status and last use; Add a connection step by step, ending with
    what was written and what to restart (for Manual, the snippet with its key, shown once); a connection's page with
    Rename, Rotate key, Change parts (narrowing at once, widening approved) and Remove; Move to one entry… with Undo;
    and "Used by" in Activity.

In detail

  • Taking (@agentcomms/core, the channels, @agentcomms/events-daemon): agentcomms taking <account> … and
    comms_taking; gmail_take/gmail_taken, slack_take/slack_taken, resend_take/resend_taken; agentcomms takes list|release|give|keep for you. A rule's delivery offers the message to the lane's window (until it is woken,
    at most the account's reminder time) or to the session it posts to (15 minutes); the session still takes it itself.
    A session's prompt says until when. events_lane_item says who has the message, in closed words. Over MCP, other
    sessions are never named. An agent's shell that joined no window is never you: where a take is required it is
    refused with NO_SESSION. Turning "must take" off, a 👀 on taking, notify off and a longer wait are approved; the
    rest applies at once. A done lapses after 30 days.
  • Search (@agentcomms/core): agentcomms search status|query|people|person|show|index|rebuild|link|unlink|label| on|off|accounts|model|delete. No agent searches, over MCP or from its shell, and Delete everything is yours alone.
    The words index holds keyed hashes of words, not the words, and keeps no word order; a pruned message's words leave
    the file. Gmail's send-as addresses count as you. More of Activity's days, while Search keeps words, says so in its
    preview. Meaning comes only from Ollama at a loopback address, with a model from the reviewed list.
  • Connections (@agentcomms/core): agentcomms connection add|list|show|change|rename|key replace|remove|migrate,
    with matching comms_connection_* tools and agentcomms mcp --connection <id>, the gateway. A connection's key is
    stored only as its SHA-256 and checked in constant time; the parts start without it. It is not a password: any
    process running as you can read it from the app's config, and the gateway's own environment shows it while it runs.
    connection list says which connections a migration made, and migrate --undo refuses the rest and pins by id.
    activity sessions names the connection a session used; channels --json says what each part takes. Approvals say
    which connection asked (preparedBy), as the gateway reports it.
  • Security review fixes before release (an independent review of this release, 2026-10-27):
    • Removing a connection whose entry shadows a wider one (one project's, over the app's every-folder connection) is
      approved like any loosening; its preview says what agents there would use instead.
    • An agent can rename, re-key or remove only its own connection; every preview names a connection by app, place and
      id; the gateway's instructions no longer carry a connection's name.
    • The gateway stops serving when config.json becomes unreadable; a re-key never writes back an entry you removed.
    • An agent can change the parts of only its own connection, narrowing included; a remove checked while the app's
      config can't be read waits for you; a new connection name can't hold brackets or "…".
    • A refusal caused by an agent's marker in your own shell names the variable and how to clear it (CODEX_HOME is
      one people export).
    • When Activity's settings can't be read, Search keeps words 30 days, not a year.
    • The take and search fixes above (NO_SESSION, lapsing offers, hashed words, the retention line, Delete
      everything).
  • Gmail's setup joins the connection like mcp install, and leaves a Gmail part kept to another mailbox alone,
    printing the connection change command that would reach the new one.

0.34.0

Choose a tag to compare

@github-actions github-actions released this 27 Oct 00:23
1e9e144

What. The desktop app explains itself, and wears cue-ui's soft look:

  • Your agents (was Agent): what people see when an agent writes for you, a Slack message and an email From line
    with your tag, then your name, the word after it and the exceptions, each changed in the app.
  • Each account has a page, with Agents here: what agents may do there, how their messages look in a Slack
    workspace, and the replies you approved in advance.
  • Events → Service in plain words, with Switch on… approved in the app and Switch off; Deliveries says
    when a rule is in dry-run, and what can reach an agent.
  • Connections in plain words: "starts an older Agent Comms", by the same yardstick as update, with Bring
    everything up to date
    ; several servers added to an app in one approval.
  • The soft look from cue-ui 0.34.0, with gliding marks, a two-finger swipe between tabs, and a Typeface choice:
    Inter or SF Pro.
  • Doctor's checks keep their names readable beside a long result.

The command line and the MCP servers gain what these need: --app-approval on label, behaviour and update,
mcp install --server <a,b,c>, agent-events collection approve, and disable-all saying what it did.

Why. The owner tried the 0.34 test build and could not read it: "I don't understand what it says behind
'core'", "It says it's running, but below it says 'collecting off.' Why?", "the agent itself is not really
understandable". The screens were redrawn first, as a prototype the owner approved ("the UI looks good"), kept in
docs/prototypes/2026-10-26-0340-rework/. cue-ui shipped the soft look the 0.28.0 redesign had drawn locally (CUE-571).
The design is docs/superpowers/specs/2026-10-26-desktop-0340-design.md.

Impact. A minor release. Everything is added; nothing is renamed or removed, and nothing needs migrating.

  • More is approved in the app, on macOS: your agents' word, name and exceptions, a Slack workspace's style, what
    agents may do on an account, switching the event service on, and updating Agent Comms. On Windows and Linux each
    still goes to the terminal, and anything that only narrows still applies at once.
  • The test build changes only its own test profile: it refuses to approve anything that would touch your real
    folders or apps, and its event service accepts the test build only on the test profile's own state.
  • Agents see less: the approval view an agent gets, through its tools or its own terminal, carries no challenge;
    a refusal is audited as the app's only when the app it really was.
  • Your look resets once: a look picked in 0.28 to 0.33 is not carried over; the app opens once on soft at the
    normal rung. Pick cue or terminal, a density, a mode or a typeface again, and it stays.
  • To use it: update with agentcomms update and the app's own update, then restart your MCP clients.

In the desktop app

  • Your agents replaces Agent: the previews, Your name and The word after it (each Change… approved in the app),
    Exceptions with Add… and Remove, and one line per account opening its page.
  • Accounts: each account opens its page, with About and Agents here:
    • What agents may do here: a switch per act; off applies at once, on asks you to approve it in the app. Slack
      adds overrides for one conversation, Gmail for some people.
    • How their messages look here (Slack): as the Agent Comms app, or as you, tagged, each with a preview.
    • Replies approved in advance (Slack): each one's contents, places, limits and end, with End and End all.
  • Events → Service: Switched off, On or Paused, each in a sentence that says what it means, with Switch on…,
    Pause, Resume and Switch off where each does something. Deliveries: a dry-run line for a rule in dry-run, a
    Dry-run log filter, removed records folded, and Something reached your agent?.
  • Connections: older entries said in plain words, Bring everything up to date, Change… adding several servers in
    one approval, and the test build's banner.
  • The look: cue-ui's soft preset (the soft style set and the glaze finish) in place of the app's own copy; the
    chosen tab, segment and sidebar item glide; two fingers swipe between tabs; reduced motion is respected; the palette
    menu's Typeface offers Inter (bundled) and SF Pro (macOS's own face).
  • Doctor: a check's name keeps a third of its row beside a long result, and a fix has its own line.

In detail

  • App approval in core (@agentcomms/core): --app-approval <id> now works on label word|name|rule|icon|style,
    behaviour allow|clear and update, as on mcp install since 0.32.0. It counts only from the attested app on
    macOS; elsewhere, or from an agent, the command refuses with APPROVAL_REQUIRED (exit 10) and names the words to
    type. An approval handed another change than the one it previewed is void (APPROVAL_VOID). The test build's
    approval counts only when every folder the command touches is inside its marked test profile, judged from the
    account's own home, not from the environment.
  • Several servers in one install (@agentcomms/core): mcp install --client <c> --server core,gmail,events and
    comms_server_install with servers: one preview, one approval bound to that list and order, registered in order
    and stopped at the first that fails, naming what was and was not registered.
  • Switch on, approved in the app (@agentcomms/events-daemon): agent-events collection approve <approval-id> --digest <digest> approves the pending enable-all from the attested app; the terminal's approve <id> still
    works. disable-all returns said, a sentence of what it did. The event service accepts a test-build approval only
    on the test profile's own state folder.
  • No challenge for an agent (@agentcomms/events-daemon): events_approval_view, and approval view in an
    agent's shell, return the preview without a challenge, so nothing an agent holds can approve, and an agent's look no
    longer replaces the challenge you are typing.
  • Audit: a refusal is recorded as the app's only for an attested app; a mismatched digest is refused.
  • cue-ui 0.34.0: @cueplusplus/ui and @cueplusplus/tokens 0.34.0, @cueplusplus/theme-soft 1.0.0, with
    @fontsource-variable/inter and @fontsource/ibm-plex-mono 5.3.0 (OFL-1.1) bundled. The approved mockup is kept in
    docs/prototypes/2026-10-24-soft-look/.

Agent Comms 0.35.0

Choose a tag to compare

@github-actions github-actions released this 27 Oct 17:52
d5807bc

Agent Comms 0.35.0.
macOS: the DMG is signed with a Developer ID and notarised.
Windows and Linux: the .exe, .AppImage and .deb are unsigned; your system warns before it opens them.
What changed: CHANGELOG.md, 0.35.0.

Agent Comms 0.34.0

Choose a tag to compare

@github-actions github-actions released this 27 Oct 01:49
1e9e144

Agent Comms 0.34.0.
macOS: the DMG is signed with a Developer ID and notarised.
Windows and Linux: the .exe, .AppImage and .deb are unsigned; your system warns before it opens them.
What changed: CHANGELOG.md, 0.34.0.

0.33.0

Choose a tag to compare

@github-actions github-actions released this 26 Oct 17:09
a17d718

What. Rules you can edit, analyse, and have act:

  • Edit a rule in the app, visually or as text. Each mistake is shown as you type, with its line.
  • Analyse suggests how to sharpen each part of a rule, and changes nothing until you say so.
  • Two new things a rule can do: add an issue in Linear, or hand the message to a coding-agent session that your
    claude-stream relay runs. If that session is busy, the message waits its turn.
  • What a target is told can be fixed text, fields mapped from the message, a model's words, or a file.

The command line and the MCP servers gain the commands behind these: rule analyse, judge show, integration show linear, session-queue list|drop, and the linear and anthropic provider keys.

Why. While reviewing the 0.32 prototype, the owner asked for four things:

  • to edit a rule "visually or as text";
  • an Analyse that gives "a more enriched version of the rules";
  • targets that "add to Linear" and "post message to session … if it's not present, create a new session … if the
    session is busy, enqueue it";
  • context that is "generated by an LLM, fixed by us, or just something derived from the inputs … Currently, we cannot
    handle that."

The screens were prototyped first and approved, in docs/prototypes/2026-10-26-0320/. The design is
docs/superpowers/specs/2026-10-26-rules-that-act-0330-design.md. The Agents screen and the digital twin were
prototyped and specified there too, and are not built: the Agents screen waits on claude-stream.

Impact. A minor release. Everything is added; nothing is renamed or removed.

  • Migrations: five event service migrations run on their own:
    • 29: a key slot for Anthropic;
    • 30: a key slot for Linear;
    • 31: a delivery's Linear issue;
    • 32: the session target and its busy queue;
    • 33: a judged decision's sending domain.
  • Behaviour changes to know about:
    • On Windows and Linux, these changes are made at a terminal: judge setup, provider key set|remove,
      integration set agent-sessions and mcp install --app-approval. Nothing there attests that the app started
      them, so from anywhere else they refuse with exit 10, ORIGIN_UNATTESTED, and change nothing. The app offers Do it
      in Terminal. Nothing changes on macOS.
    • A judged decision keeps the sender's domain, never the address, encrypted. It is kept only while the rule keeps
      the message's content.
    • New addresses the event service may reach, each only when you use it:
      • api.linear.app, for a rule that adds Linear issues;
      • OpenRouter or Anthropic, when you press Analyse;
      • your own claude-stream relay on this machine, for a session target.
  • Agent sessions need claude-stream. It is not part of Agent Comms. A session target does nothing until you name
    its relay in Settings → Integrations, or with integration set agent-sessions.
  • To use it: update with agentcomms update and the app's own update, then restart your MCP clients.

In the desktop app

  • Events → Rules:
    • New rule… and Edit… open the rule editor. You can edit as Visual, Text or Advanced: JSON. Visual has five
      parts:

      • When;
      • Which messages;
      • Ask a judge;
      • Then do;
      • What's kept, and the limit.
    • Text is checked as you type. A part the visual editor has no control for stays as text, and is never dropped.

    • The judge picker offers every live judge.

    • Then do can:

      • put a message in the Queue;
      • send it to an agent session;
      • add an issue in Linear;
      • send it to a webhook;
      • stream it to subscribers;
      • write it in the dry-run log.
    • Analyse suggests changes to each part, using your OpenRouter or Anthropic key. You see every change before it
      is made.

    • Review and approve says everything a target is given:

      • a session's every context part;
      • a Linear issue's team, labels, assignee, title and description;
      • where each mapped field comes from;
      • that claude-stream journals each prompt.

      On Windows and Linux it offers Approve in Terminal.

  • Settings → AI providers: a row for an Anthropic key, for Analyse.
  • Settings → Integrations (new):
    • Connect Linear… with a personal API key;
    • Agent sessions: where your claude-stream relay is.
  • Events → Deliveries:
    • Waiting for a session shows each match waiting for a busy session, and since when. Drop… asks first.
    • A Linear delivery names the issue it added, with Open in Linear.
  • On Windows and Linux:
    • Do it in Terminal for judge setup, provider keys, Linear and the relay;
    • Approve in Terminal in Connections.

In detail

  • A rule as text (@agentcomms/events): printRuleText writes a rule as the short language the app's text editor
    shows (when a new message arrives in cue/gmail, in the inbox, match any, ask, then, keep, at most), and
    parseRuleText reads it back to the same document, with each mistake's line and column. Anything the text has no
    words for is kept as raw JSON, so nothing is dropped. The grammar is in packages/events/src/rule-text/GRAMMAR.md.
  • Analyse (@agentcomms/events-daemon): agent-events rule analyse <ruleId> [--draft -] --json suggests how to
    improve a rule part by part — from its own text and content-free counts of its last 30 days (a sending domain the
    judge always refused, a bar between kept and dismissed scores, a rule that never matched), and from a model on your
    own OpenRouter or Anthropic key for the judge's question, a session's text and a Linear title — and never applies
    one. It reads and sends no message content, and runs only at your terminal or in the app. provider key set takes
    anthropic; a judged decision now keeps its sender's domain, never the address, encrypted and apart from its
    metadata, only as long as the rule keeps the message's content. Two automatic migrations: 29 gives Anthropic a key
    slot, and 33 keeps the sending domains.
  • A rule can add a Linear issue (@agentcomms/events-daemon, @agentcomms/events):
    • The key: your Linear personal API key is kept beside the AI provider keys: agent-events provider key set linear, from the app or your own terminal, never from an agent. provider list names Linear too.
    • What it can see: agent-events integration show linear [--team CUE] --json gives the workspace and teams the
      key can see, and a team's labels — the person's read for Settings → Integrations, refused inside an MCP server.
    • The target: { kind: "linear", team, title, description, labels, assignee }. The title and description are
      text with {{field}} slots, each naming one of the rule's mapped fields, checked when the rule is activated; a
      model-written one comes with the session target. The approval preview names the team, the labels, the assignee
      and which fields fill the title and description. The rule text says it: linear issue billing-issues, version 1, in team CUE, label Billing, assigned to me.
    • A slot's value stays text: in the description every slot's value — what the sender wrote, or a constant the
      rule's mapping sets — is a block quote labelled with who wrote it, inside a code block, where Linear makes no link
      or mention from a URL, @name or issue id; in the title it is flattened to one line.
    • Checked against Linear: when you enable the rule with a Linear key kept, each team key must be the team its id
      names in Linear, and each label name its id's (LINEAR_TEAM_MISMATCH, LINEAR_LABEL_MISMATCH), so the approval
      cannot name one team and send to another. With no key the check is skipped, and the approval says so.
    • Delivery: one issueCreate through the pinned connection to api.linear.app/graphql, the one Linear address
      the event service may reach. A rate limit or a 5xx is tried again as a webhook's failure is; Linear refusing it
      fails at once with Linear's code. A retry never adds a second issue: each try looks for the issue by its own id
      first. deliveries list and delivery show name the issue (linear: { identifier, url }), never what it says.
    • Migrations: two event service migrations run on their own: 30, a key slot for Linear, and 31, a delivery that
      can record its Linear issue.
  • Agent sessions, through claude-stream (@agentcomms/events, @agentcomms/events-daemon): a rule's session
    target hands each match to a coding-agent session your claude-stream relay runs — the one working in a folder,
    started there with Claude Code or Codex if there is none, or the one behind the window you bound to a lane — in the
    mode the rule fixes (manual by default; bypassPermissions is refused). Its context is fixed text, the mapped
    fields, a model's words (on your OpenRouter or Anthropic key) and a file (at most 64 KB, under an allowed folder), in
    a fixed frame with sender material in the untrusted-content envelope. A busy session queues the match until its run
    ends; session-queue list|drop show and drop what waits, and a bound window sees its own lane's with
    events_session_queue_list. integration show|set agent-sessions says where the relay is — yours to set, from the
    app or your terminal. The rule text prints and parses the session block. One automatic migration, 32, admits the
    session kind and adds the content-free busy queue.
    • From the security review: the control token goes only to a port your own process listens on (checked with
      lsof on macOS and /proc/net/tcp on Linux; not on Windows), and is read from the opened file itself. Only a live
      run's 409 is busy. A busy session never fails a match: it waits until the session is free or the match expires,
      tried further apart the longer it has waited (at most every five minutes), and only other failures count towards
      the 12 that fail it. A session since watched, fenced or mo...
Read more

0.32.0

Choose a tag to compare

@github-actions github-actions released this 26 Oct 13:57
5b7f00b

What. The app answers the owner's feedback of 2026-10-26, item by item:

  • Judges and keys in the app: Jev and a local model server are set up in Events → Judges, and Settings → AI providers
    keeps the TypeSafe and OpenRouter keys.
  • Readable rules and deliveries: Rules and Deliveries read in plain words, and each one opens to show its details.
  • The 1970 date is gone.
  • Messages: a new screen shows what happened to each message that came in.
  • Connections: a new screen shows which apps have which servers.
  • The test build tells you it is one.

The command line and the MCP servers gain the reads and fields these screens need.

Why. The owner installed 0.30.0, opened the app and found it hard to use:

  • turning a judge on meant the Terminal;
  • a key had no home;
  • rules and deliveries were raw database rows ("mail subject version 1 state active and approval and activation", "the
    next try is always 1970");
  • nothing answered the question they care about most: "something has come in. Did we acknowledge it? Did we reply to
    it? Is it something that has been passed over to a session, or was it proactively read by a session?"

The screens were drawn first, as a prototype the owner approved ("perfect"), kept in the repository at
docs/prototypes/2026-10-26-0320/.

Impact. A minor release. Everything is added; nothing is renamed or removed.

  • Migrations: three database migrations in the event service run on their own: provider keys, a queue item's
    history, and clearing next_at.
  • Behaviour changes to know about:
    • The dry-run log (dryrun list and dryrun show) is now readable with --json outside an MCP server, so the
      app can show it, like the queue's content since 0.30.0.
    • delivery drop also stops a delivery that is waiting or will be tried again.
    • Every MCP server marks its own process, so commands only the person may run refuse inside any of them.
    • Approvals from the app: a change can now be approved in the desktop app. That covers turning a judge on, and
      adding a server to an app from Connections. The audit records it as approved in the app. Everything else stays at
      the terminal, as before.
  • To use it: update with agentcomms update and the app's own update, then restart your MCP clients.

In the desktop app

  • Events → Judges:
    • Set up… for Jev, choosing OpenRouter or TypeSafe directly (a provider without a key is greyed out), and for a
      local model server (Ollama's System One, on this Mac).
    • Turn off applies at once.
    • Laya reads "Not available yet".
  • Settings → AI providers: add, replace or remove the TypeSafe and OpenRouter keys. A key is never shown again
    once saved, and removing one a judge uses names that judge first.
  • Events → Rules:
    • one card per rule, with the rule as a sentence, its state and its week;
    • opening it shows what it watches, which messages, the judge, where they go, what's kept, the limit, its versions
      and, folded away, the technical ids explained.
  • Events → Deliveries:
    • "rule → where it went", with the state in plain words, and no 1970;
    • a delivery's page shows the message, why it was passed on, a dry run's record (the sender's words marked as
      outside text) and its tries, with Try now and Stop trying.
  • Messages (new): each message that came in, how far it got, and the steps on the way. Opening one shows its story,
    built from what Agent Comms saw.
  • Connections (new):
    • Claude Code, Claude Desktop, Codex and Cursor against the six servers, and when each was last used;
    • who can reach the servers: local windows yes, cloud sessions no;
    • Change… adds a server once you approve it in the app, and removes one at once.
  • The test build: an orange "TEST BUILD" band naming its branch and commit, the name "Agent Comms Test" and the
    test profile's folder, and its tray says so too. A released app looks as before.

Activity ties a reply to the message it answers (Task E of the owner's 2026-10-26 feedback, for the app's Messages
screen).

  • New ids on existing activity lines. Every field is new, and none was removed or renamed.
    • Gmail: a reply draft (gmail.draft.reply) names the message it answers and its thread (replyTo), and the draft
      it made (draftId). A forward answers nothing, so it has no replyTo.
    • Gmail: preparing a send (gmail.send.prepare) names its draftId. When the draft answers a message in this
      mailbox, it also names that message (replyTo). The prepare already proves this, so Gmail is asked nothing more.
    • Gmail: a send (gmail.send.execute) names the draft it sent (draftId) and the thread Gmail filed it in
      (threadId).
    • Slack: a post (slack.post.send) names its conversation by id (channelId) and the thread it went into
      (thread: the parent's ts, or null for a new message).
    • Slack: a history read (slack.read) names its conversation by id (channelId), beside the name it already kept.
    • Slack: an acknowledgement under a standing approval (slack.ack) says what it did (act: reply or reaction),
      so a message an agent answered reads apart from one it only marked seen.
  • agentcomms activity items [--since <ms>] [--ids <id,…>] --json lists every call that names an item, grouped
    by the item. A Gmail message keeps its id, and a Slack message is <channelId>/<ts>. Each line names the window
    (key, folder, client), the operation, when it ran and how it ended, with replyTo, thread, draftId and act
    where it has them. A line appears under each item it names and each item it links to, so a message leads to its
    reply draft, and that draft to its send. Subjects and senders are the sender's words, returned in the
    untrusted-content envelope. It is the person's view: refused inside an MCP server's process (exit 10), with no MCP
    tool, like agentcomms activity show.
  • Every MCP server marks its own process as it starts. Core's server and the Gmail, Slack, Resend and WhatsApp
    servers now set AGENTCOMMS_MCP_SERVER, as the event service's already did, and @agentcomms/gmail-mcp does too.
    Every program a server starts inherits the mark, so agentcomms activity items and the event service's person-only
    reads refuse there as well. Your terminal is not marked, and nor is a shell an agent's client runs itself.
  • agentcomms mcp uninstall --client <c> --server <s>, and comms_server_uninstall from a chat, take one server
    out of one client. They remove every user-scope entry that starts it, whatever it is called. This is a tightening:
    it applies at once and asks nobody. Each removed entry is saved first, owner-only, and the change is audited.
    • A project's own entry is left in place, and the result says where it is.
    • A config file with comments is left as it was, and so is an entry whose client command can't be found. The result
      names each.
    • The client keeps the server running until it restarts. agentcomms mcp prune is unchanged: it removes
      runtimes, never a registration.

What happened to a message, in the event service. The owner asked: "something has come in. Did we acknowledge it?
Did we reply to it? Is it something that has been passed over to a session, or was it proactively read by a session?"
The event service now keeps and gives the part it sees; the app's Messages screen comes after the owner's feedback on
its prototype.

  • agent-events messages list --json gives each message the event service observed, newest first: what each rule
    decided and what its judge answered, where each delivery went, the queue item it became and what happened to that
    item. It looks back 30 days and gives 100 at a time by default (--since, --before, --limit), with a next to
    pass back for the page after.
  • agent-events message show <event-id> --json gives one of them, with every line of its queue item's history.
  • Each message carries its source's own ids: a Gmail message id, a Slack channel and ts, a WhatsApp chat and
    message id, a Resend email id. These are what the app joins a message to its Gmail or Slack link and to the activity
    log with. When the queue kept a summary, it also carries the sender and subject, marked as from outside.
  • Queue items keep a history: woken (a lane's bound window was woken for it), read (that window read it), done,
    dismissed and reopened, each saying whether an agent window did it, and which, or you did, at the terminal or in the
    app. It goes when the item goes.
  • Only you see it. Both commands refuse inside the event service's MCP server, and no MCP tool returns a message's
    story or an item's history. The history never enters the activity log, so no agent's activity view can name an item
    in a lane bound to another window.
  • One automatic database change adds the history table and two indexes. Nothing is asked of you.

Rules and deliveries you can read. The owner opened the app's Events screens and found raw database rows: "mail
subject version 1 state active and approval and activation", and a next try "always 1970".

  • No more 1970. A delivered dry-run, queue or SSE delivery kept the "due now" time it started with, which the app
    showed as a next try on 1 January 1970. Delivering now clears it, and a migration clears it on the rows already
    delivered, cancelled or expired.
  • A rule in plain words. agent-events rule show <rule-id> (and events_rule_show) gives each version with when
    it was switched on, replaced or revoked, a one-sentence summary such as "When mail arrives in cue/gmail with
    'invoice' in the subject, ask Jev '…'. If it says yes, put it in the Queue, lane billing.", and what it did in the
    last 7 days: matched, judged yes and no, held, delivered and failed (over MCP, not for a lane the window isn't
    bound to). Every word the rule's author wrote is marked as theirs. The approval previ...
Read more

0.31.0

Choose a tag to compare

@github-actions github-actions released this 26 Oct 03:36
88dc6d5

Routing: a lane wakes the agent window you bind to it. The third step the owner asked for, after activity and the
queue: "when David is messaging me on Slack", route it to the right agent session.

  • A lane is a queue with a name. A rule can send its matches to lane david, as it sends them to a queue. You
    approve that the lane's items may be read by the window you bind, with the rule, as every target is approved.
  • You bind a window to a lane, at a terminal: agent-events lane bind david --window <id>. The app's Queue screen
    has a Lanes tab, with Bind a window…, which lists your recent agent windows and opens Terminal with the command,
    and Unbind, which applies at once. An agent can ask for its own window's id (events_lane_whoami) to tell you
    what to bind, but it can't bind itself through MCP.
  • The bound window wakes on its own. In Claude Code, events_watch waits as an MCP task. When a new item arrives,
    the idle window starts working without you typing, told only "1 new item in lane david (Slack, rule …): read it with
    events_lane_item". It never gets the sender's words in that notice. It reads the item through events_lane_item,
    marked as from outside, and then watches again. events_wait waits up to 50 seconds for clients without tasks.
  • Who sees what: only the bound window may read a lane's items, and only those that arrive after it was bound.
    Every other agent window sees no lane items at all, not even in the queue tools. You see everything in the app and
    at the terminal.
  • The event service's MCP server now speaks the newer MCP protocol (2026-07-28) that tasks need, and still serves
    clients on the older one.
  • What doesn't change: a queue without a lane works as in 0.30.0. Windows that can't be identified (on Windows, or
    a server started in your home folder without a Claude Code session id) can't bind yet, and are told why.

Agent Comms 0.33.0

Choose a tag to compare

@github-actions github-actions released this 26 Oct 17:51
a17d718

Agent Comms 0.33.0.
macOS: the DMG is signed with a Developer ID and notarised.
Windows and Linux: the .exe, .AppImage and .deb are unsigned; your system warns before it opens them.
What changed: CHANGELOG.md, 0.33.0.