agmsg利用時に自動返信するツール
  • TypeScript 75.5%
  • Shell 24.5%
Find a file
answer.kazuya c85f91667d README を英語のみに整理
日本語併記(EN/JP形式)を廃止し、英語のみのシンプルな構成に変更。
内容(手順・オプション・仕組み)自体の変更はなし。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 01:21:28 +09:00
dist chore: add .gitignore, remove node_modules from tracking 2026-07-14 03:06:45 +00:00
scripts chore: add .gitignore, remove node_modules from tracking 2026-07-14 03:06:45 +00:00
src chore: add .gitignore, remove node_modules from tracking 2026-07-14 03:06:45 +00:00
.gitignore chore: add .gitignore, remove node_modules from tracking 2026-07-14 03:06:45 +00:00
package-lock.json fix: READMEのInstall手順を実際に動く内容に修正、パッケージ名をfieldcrmブランドから独立 2026-07-14 11:02:25 +00:00
package.json fix: READMEのInstall手順を実際に動く内容に修正、パッケージ名をfieldcrmブランドから独立 2026-07-14 11:02:25 +00:00
README.md README を英語のみに整理 2026-07-15 01:21:28 +09:00
tsconfig.json chore: add .gitignore, remove node_modules from tracking 2026-07-14 03:06:45 +00:00

agmsg-daemon-plugin

OpenCode plugin that sets up a systemd auto-reply daemon for agmsg agents (cross-agent messaging via SQLite). One line in opencode.json → daemon running.


What this solves

You run multiple opencode agents (deepseek, mimo, etc.) that listen for inbound agmsg messages. Each needs a polling daemon that:

  1. Watches the agmsg SQLite inbox every 5 seconds
  2. Injects unread messages into a fresh opencode run turn
  3. Marks messages read and sends auto-ack

Without this plugin, you'd hand-write systemd unit files with correct paths, environment variables, and override.conf for every agent and every machine.


Typical use cases

Claude Code → opencode sub-agent

Claude sends a research task via agmsg → opencode daemon picks it up, runs the task, replies with results. No need to keep a terminal session open.

Multi-agent swarm

deepseek + mimo + other opencode agents running in parallel, each with its own daemon, all on the same agmsg team.

CI / ephemeral machines

Spin up a new dev machine → git clone agmsg && git clone this plugin → daemon running in 10 seconds.

Headless agents

Agents that run autonomously even when no one is logged into a terminal session.


Prerequisites

This plugin only automates the systemd wiring for agents that already exist in agmsg. It does not create agmsg teams or agents — that step must be done first, manually, with agmsg itself.

  • Linux with systemd (systemctl --user must work)
  • agmsg installed at ~/.agents/skills/agmsg/
  • The target agent has already joined a team as codex type — run join.sh yourself first (see Example workflow below). Without this, the plugin finds nothing and does nothing.
  • opencode CLI in PATH

Install

This package is not published to npm (no registry account needed / nothing to authenticate). Install it as a local file-based opencode plugin instead — clone the repo and point opencode.json at the built dist/index.js with a file:// URL. dist/ is already committed pre-built, so no build step is required.

git clone https://git.answer.mydns.jp/kaz/agmsg-daemon.git
cd agmsg-daemon/agmsg-daemon-plugin
// opencode.json (global: ~/.config/opencode/opencode.json,
// or project: .opencode/opencode.json)
{
  "$schema": "https://opencode.ai/config.json",
  "plugin": ["file:///absolute/path/to/agmsg-daemon-plugin/dist/index.js"]
}

Use an absolute path. Restart opencode. On load, the plugin scans ~/.agents/skills/agmsg/teams/*/config.json for agents registered as codex type (agents already joined via join.sh — see Prerequisites above), generates systemd units, and starts them.


Options

These options live entirely in opencode.json — they configure the daemon's own opencode run subprocess for the target agent (e.g. deepseek, mimo), and have nothing to do with Claude Code or the model Claude Code itself is running as.

{
  "plugin": [
    ["file:///absolute/path/to/agmsg-daemon-plugin/dist/index.js", {
      "models": {
        "deepseek": "opencode-go/deepseek-v4-flash",
        "mimo": "opencode-go/mimo-v2.5"
      },
      "agmsgDir": "/path/to/agmsg",
      "storagePath": "/path/to/agmsg/db",
      "disableAutoSetup": false
    }]
  ]
}
Key Type Description
models Record<string, string> Per-agent model to pass as -m to opencode run
agmsgDir string agmsg installation directory (default: ~/.agents/skills/agmsg)
storagePath string Directory containing messages.db (default: <agmsgDir>/db)
disableAutoSetup boolean Skip auto-setup on plugin load; use daemon.setup manually

Custom tools

Tool Description
daemon.status Show status of all daemons (or specific agent with agent arg)
daemon.start Start daemon for a specific agent
daemon.stop Stop daemon for a specific agent
daemon.restart Restart daemon for a specific agent
daemon.remove Remove systemd unit for a specific agent
daemon.setup (Re)run setup for all agents or a specific one

Example workflow

1. Join agmsg team

bash ~/.agents/skills/agmsg/scripts/join.sh lab1 deepseek codex /home/user/project

2. Add plugin & restart

{ "plugin": ["file:///absolute/path/to/agmsg-daemon-plugin/dist/index.js"] }

Plugin auto-detects codex-type agents, generates systemd units, and starts them.

3. Verify

daemon.status
→ deepseek@lab1: RUNNING pid=247808
  mimo@lab1: RUNNING pid=247807

4. Done

When an agmsg message arrives for deepseek@lab1, the daemon picks it up, runs opencode run, marks it read, and sends auto-ack.


What gets created

  • ~/.config/systemd/user/agmsg-daemon-{agent}.service — systemd unit
  • ~/.config/systemd/user/agmsg-daemon-{agent}.service.d/override.conf — PROJECT_DIR, AGMSG_STORAGE_PATH
  • <agmsgDir>/scripts/agmsg-daemon.sh — self-contained daemon script
  • ~/.config/opencode/agmsg-daemon/setup-state.json — tracks which project setup ran for

Uninstall

daemon.remove deepseek
daemon.remove mimo

Remove the file://...agmsg-daemon-plugin/dist/index.js entry from opencode.json's plugin array.


How it works

opencode restart
  └─ plugin loads
       └─ scans teams/*/config.json for codex agents
            └─ for each agent:
                 ├─ generate systemd unit
                 ├─ copy daemon.sh to agmsg/scripts/
                 └─ systemctl --user enable --now

daemon.sh (5s loop)
  ├─ SELECT COUNT(*) FROM messages WHERE read_at IS NULL
  ├─ if unread > 0: opencode run "process these"
  └─ mark read + INSERT auto-ack

The daemon is fully self-contained: it resolves the SQLite path directly (no dependency on agmsg's storage.sh or send.sh), and uses inline SQL INSERT for auto-ack.


License

MIT