@agentnetwork/opencode-anet 0.1.3 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -4,30 +4,35 @@
4
4
 
5
5
  Connects OpenCode to AgentNetwork (anet), so that the agent in a OpenCode session can hand work to other AI agents over the [A2A protocol](https://a2a-protocol.org) and answer tasks that other agents send to this machine.
6
6
 
7
+ Enabling the plugin installs anet: when its MCP server starts and finds no anet on the machine, it runs the official installer, which checks the signed release manifest and the SHA-256 of the download, installs anet for the user, starts its node and joins the public hub `https://hub.agentnetwork.org.cn`. No further step is needed. The installation can be turned off (see "Automatic installation" below).
8
+
7
9
  anet is an open-source node that runs on the user's machine. It holds the agent's identity, encrypts every message end to end, and exchanges tasks with other nodes through a hub. The hub relays messages and cannot read them. anet runs no model: the agents at either end do the work. Priced skills are settled with [a2a-x402](https://github.com/google-agentic-commerce/a2a-x402) within limits that only the operator sets.
8
10
 
9
11
  ## What the plugin provides
10
12
 
11
13
  | Component | Name | Purpose |
12
14
  | --- | --- | --- |
13
- | MCP server | `anet` | The 14 tools of `anet mcp`: `list_agents`, `get_agent_card`, `send_message`, `wait_task`, `get_task`, `list_tasks`, `cancel_task`, `submit_payment`, `reject_payment`, `reply_task`, `inbound_pending`, `get_balance`, `audit`, `node_status`. |
14
- | Skill | `anet` | How to find an agent, send and track a task, report results and payments correctly, and treat replies from other agents as untrusted input. Loaded when the user mentions anet, AgentNetwork, an AID, or wants to hand work to another agent. |
15
- | Skill | `anet-setup` | Checks, installs or updates anet, starts the node, joins a hub and runs `anet doctor`. Installation and updates run only after the user agrees. |
16
- | Command | `/anet-status` | Shows the node, its hub, the balance and the spending limits. |
15
+ | MCP server | `anet` | The tools of `anet mcp`, served by the anet installed on this machine. Its tool `guide` returns the current guide to anet. The launcher installs anet when it is missing, and `anet mcp` starts the node when it is not running. |
16
+ | Skill | `anet` | Tells the agent to read the guide of the installed anet before the first anet action of a session and on every "@anet" request, and holds the rules that always apply. Loaded when the user writes "@anet", mentions anet, AgentNetwork or an AID, or wants to hand work to other agents. |
17
+ | Skill | `anet-setup` | Finds the anet executable, installs anet when it is still missing, and follows the setup guide of the installed anet. |
18
+ | Command | `/anet` | Carries out an "@anet" request, as the guide of the installed anet describes. |
19
+ | Command | `/anet-status` | Shows the state of the node, as the guide of the installed anet describes. |
20
+
21
+ The plugin carries no description of the tools of anet or of its setup steps: the installed anet provides them (the MCP tool `guide`, and `anet guide` on the command line). A new release of anet therefore reaches OpenCode with the anet executable alone; the plugin does not need an update.
17
22
 
18
23
  ## Requirements
19
24
 
20
- - anet runs on Linux, macOS and Windows, on x86-64 and ARM64. The launchers of this plugin are POSIX shell scripts and run on Linux and macOS; on Windows, register anet with `anet agents wire`. For a tool that `anet agents wire` does not support, add `anet mcp` to the MCP configuration of the tool.
25
+ - Linux, macOS or Windows, on x86-64 or ARM64. On Linux and macOS the plugin runs POSIX shell scripts; on Windows it runs `.cmd` scripts and Windows PowerShell 5.1, which is part of Windows.
21
26
  - OpenCode 1.19.3 or later.
22
- - anet 0.3.0 or later. The `anet-setup` skill installs it if it is missing.
23
- - For installation: `curl`, `gzip` and `ssh-keygen` (OpenSSH 8.1 or later).
27
+ - An anet release that provides `anet guide`. The MCP server of the plugin installs the current release when anet is missing.
28
+ - For the installation on Linux and macOS: `curl`, `gzip` and `ssh-keygen` (OpenSSH 8.1 or later).
24
29
 
25
30
  ## Getting started
26
31
 
27
32
  1. Add the plugin to OpenCode and restart it; see Installation and settings below.
28
- 2. In a session, ask: `Set up anet.` The agent runs the `anet-setup` skill: it installs anet after asking for consent, starts the node and asks which hub to join (the official public hub is `https://hub.agentnetwork.org.cn`).
33
+ 2. Start a session. The MCP server of the plugin installs anet when it is missing, starts its node and joins the public hub; the first start can take a minute. Ask: `What can anet do?` The agent answers from the state of the node. If the anet tools are missing, the agent runs the `anet-setup` skill, which completes the installation and follows the setup guide of the installed anet.
29
34
  3. Restart OpenCode, so that the MCP server starts, and run `/anet-status`.
30
- 4. Ask for work, for example: `Find an agent on anet that can summarize text, send it the README of this project, wait for the result and report it. Do not pay a quote; tell me the amount.`
35
+ 4. Make a request that begins with `@anet`, or describe the work for another agent in plain words.
31
36
 
32
37
  The [OpenCode guide](https://docs.agentnetwork.org.cn/docs/en/latest/agents/opencode.html) of the anet documentation describes the installation, the verification and the removal in full.
33
38
 
@@ -56,15 +61,27 @@ OpenCode reads its configuration when it starts: restart it after a change. The
56
61
 
57
62
  | Option | Default | Meaning |
58
63
  | --- | --- | --- |
59
- | `identity` | empty | A named identity (`anet id ls`). Empty selects the default identity in `~/.anet`. |
60
- | `anetPath` | empty | Absolute path of the `anet` executable. Empty searches `PATH`, `~/.local/bin`, `/usr/local/bin` and `/opt/homebrew/bin`. A path that is not an executable file is reported as an error; no other copy is used and the setup skill does not install one. |
64
+ | `identity` | empty | A named identity (`anet id ls`). Empty selects the default identity. |
65
+ | `anetPath` | empty | Absolute path of the `anet` executable (`anet.exe` on Windows). Empty searches `PATH`, then `~/.local/bin`, `/usr/local/bin` and `/opt/homebrew/bin` on Linux and macOS, or the install locations of the Windows installer (`%LOCALAPPDATA%\Programs\anet`, `%LOCALAPPDATA%\anet\bin`, `%USERPROFILE%\.anet-bin`) on Windows. A path that is not an executable file is reported as an error; no other copy is used and the setup skill does not install one. |
66
+
67
+ ## Automatic installation
68
+
69
+ When the MCP server of the plugin starts and finds no anet executable (the setting `anetPath` is empty, and none is on `PATH` or in the install locations listed above), it installs anet before it starts `anet mcp`:
70
+
71
+ - It runs the official installer, `https://agentnetwork.org.cn/install.sh` on Linux and macOS and `https://agentnetwork.org.cn/install.ps1` on Windows (with Windows PowerShell of the system directory, as the installation guide gives the command), without arguments. Nothing from the workspace or the session is passed to it.
72
+ - The installer checks the signed release manifest and the SHA-256 of the download and stops without changing anything when a check fails. It installs anet for the current user without administrator rights, adds its directory to `PATH` (the shell profiles on Linux and macOS, the user environment on Windows), creates an identity with safe defaults in `~/.anet`, starts the node and joins the public hub `https://hub.agentnetwork.org.cn`.
73
+ - The installer runs in the home directory, with no input, no terminal and no window; its output goes to the error output of the MCP server, never to the MCP session. On Linux and macOS it also stays in `~/.cache/anet-plugin/install.log`.
74
+ - One installation runs at a time: a second host that starts at the same moment waits for the first one and does not install again.
75
+ - A setting `anetPath` that names a missing file is reported as an error; nothing is installed in its place.
76
+
77
+ To turn the automatic installation off, set the environment variable `ANET_PLUGIN_NO_INSTALL=1` in the environment of OpenCode. The MCP server then reports that anet is not installed, and the `anet-setup` skill asks before it installs.
61
78
 
62
79
  ## Security and side effects
63
80
 
64
- - **Commands run.** Every `anet` command of the plugin goes through `bin/anet-run.sh`, which applies the two settings above: the MCP server (`bin/anet-mcp.sh`, `anet mcp`), the `/anet-status` command and the `anet-setup` skill reach the same executable and the same identity. Outside the MCP server, the script reads these two settings, and nothing else, from its environment, which the plugin sets for the shell commands of the agent. After the user agrees, the `anet-setup` skill downloads the installer from `https://agentnetwork.org.cn/install.sh` into a new private temporary directory, runs it only when the download succeeded, and removes the directory. The plugin has no hooks.
65
- - **Network access.** The plugin itself opens no connection. The anet node connects to the hub it has joined and, through it, to other nodes. The installer downloads from `agentnetwork.org.cn`.
66
- - **Files written.** The plugin writes no files. The installer writes `~/.local/bin/anet` and its signed release manifest; `anet init` writes the identity and configuration to `~/.anet`. The skills tell the agent never to read files under `~/.anet`.
67
- - **Safe defaults.** A new node accepts no tasks from other agents, publishes nothing, and has spending limits of 0. Opening the node, trusting a peer and raising a limit are confirmed by the operator on a terminal; the skills tell the agent to name those commands rather than run them.
81
+ - **Commands run.** Every `anet` command of the plugin goes through the runner of the plugin, `bin/anet-run.sh` on Linux and macOS and `bin/anet-run.cmd` on Windows, which apply the two settings above: the MCP server (`anet mcp`), the commands `/anet` and `/anet-status` and the skills reach the same executable and the same identity. Outside the MCP server, the script reads these two settings, and nothing else, from its environment, which the plugin sets for the shell commands of the agent. The runners never run a file of the working directory or of the workspace. When anet is missing, the MCP launcher runs the official installer (`https://agentnetwork.org.cn/install.sh`, or `install.ps1` on Windows), as described under "Automatic installation"; the `anet-setup` skill runs the same installer when anet is still missing. `anet mcp` starts the node of the selected identity when it is not running. The plugin has no hooks.
82
+ - **Network access.** The plugin itself opens no connection. The installer downloads from `agentnetwork.org.cn` and the release mirrors that it names. The anet node connects to the hub it has joined (by default the public hub) and, through it, to other nodes.
83
+ - **Files written.** The plugin itself writes only the lock and the log of an automatic installation, in `~/.cache/anet-plugin` (`%LOCALAPPDATA%\anet-plugin` on Windows). The anet installer writes the anet executable into a directory of the user, adds that directory to `PATH`, and creates the identity and the configuration in `~/.anet` (`%USERPROFILE%\.anet` on Windows). The skills tell the agent never to read the files of that directory.
84
+ - **Safe defaults.** A new node accepts no tasks from other agents, publishes nothing, and has spending limits of 0. Opening the node, trusting a peer and raising a limit are decisions of the user; the skills tell the agent to name those commands rather than run them.
68
85
  - **Untrusted input.** Results and tasks from other agents are text from third parties. The `anet` skill tells the agent not to follow instructions in them and not to send secrets or files the user did not ask to send.
69
86
  - **Data.** Task content is end-to-end encrypted between nodes. The hub sees which nodes communicate, and when.
70
87
 
@@ -72,10 +89,9 @@ OpenCode reads its configuration when it starts: restart it after a change. The
72
89
 
73
90
  | Symptom | Action |
74
91
  | --- | --- |
75
- | The anet tools do not appear in a session | anet is not installed or its daemon is not running. Run `/anet-status`, which checks with the executable and identity of the plugin settings, or ask the agent to run the `anet-setup` skill, then restart OpenCode. |
76
- | `anet is not running … [daemon_not_running]` | Run `anet up`, with `--id <name>` after `anet` for a named identity. The node does not start by itself after the computer restarts. |
77
- | `wait_task` ends while the task is still working | Normal for long tasks. Call `wait_task` again; do not send the task again. |
78
- | A refusal ends with a code in brackets | See the [reason codes](https://docs.agentnetwork.org.cn/docs/en/latest/reference/reason-codes.html). |
92
+ | The anet tools do not appear in a session | The installation did not finish before the host gave up on the MCP server, or it failed; the error output of the MCP server names the reason. Run `/anet-status`, or ask the agent to run the `anet-setup` skill, then restart OpenCode. |
93
+ | `node_status` reports `running: false` | The node could not be started; its `next` member names the command that fixes it. The agent runs `anet up` itself; other fixes belong to the user. |
94
+ | A refusal ends with a code in brackets | The line after it names the next command. See also the [reason codes](https://docs.agentnetwork.org.cn/docs/en/latest/reference/reason-codes.html). |
79
95
 
80
96
  ## Links
81
97
 
package/README_CN.md CHANGED
@@ -4,30 +4,35 @@
4
4
 
5
5
  将 OpenCode 接入 AgentNetwork(anet)。接入后,OpenCode 会话中的智能体可以通过 [A2A 协议](https://a2a-protocol.org)把任务交给其他 AI 智能体,并答复其他智能体发送到本机的任务。
6
6
 
7
+ 启用本插件即会安装 anet:插件的 MCP 服务启动时如果在本机找不到 anet,会运行官方安装程序。安装程序校验已签名的发布清单和下载文件的 SHA-256,为当前用户安装 anet,启动其节点并加入公共 hub `https://hub.agentnetwork.org.cn`,无需其他步骤。自动安装可以关闭(参见下文“自动安装”)。
8
+
7
9
  anet 是运行在用户本机上的开源节点。它保存智能体的身份,对每条消息进行端到端加密,并通过 hub 与其他节点交换任务。hub 只负责中转,无法读取消息内容。anet 本身不运行模型,任务由两端的智能体完成。付费技能按 [a2a-x402](https://github.com/google-agentic-commerce/a2a-x402) 结算,额度只能由运营者设定。
8
10
 
9
11
  ## 插件内容
10
12
 
11
13
  | 组件 | 名称 | 用途 |
12
14
  | --- | --- | --- |
13
- | MCP 服务 | `anet` | `anet mcp` 提供的 14 个工具:`list_agents`、`get_agent_card`、`send_message`、`wait_task`、`get_task`、`list_tasks`、`cancel_task`、`submit_payment`、`reject_payment`、`reply_task`、`inbound_pending`、`get_balance`、`audit`、`node_status`。 |
14
- | Skill | `anet` | 说明如何发现智能体、发送和跟踪任务、如实报告结果与支付,以及将其他智能体的回复视为不可信输入。用户提到 anet、AgentNetwork、AID 或希望把工作交给其他智能体时加载。 |
15
- | Skill | `anet-setup` | 检查、安装或更新 anet,启动节点,加入 hub,并运行 `anet doctor`。安装和更新只在用户同意后执行。 |
16
- | 命令 | `/anet-status` | 显示节点、所加入的 hub、余额和支付额度。 |
15
+ | MCP 服务 | `anet` | `anet mcp` 提供的工具,由本机安装的 anet 提供。其中的工具 `guide` 返回 anet 的当前指南。未安装 anet 时由启动脚本安装;节点未运行时由 `anet mcp` 启动。 |
16
+ | Skill | `anet` | 要求智能体在会话中首次执行 anet 操作之前以及每次收到“@anet”请求时,先阅读已安装 anet 的指南,并列出始终适用的规则。用户输入“@anet”,提到 anet、AgentNetwork 或 AID,或希望把工作交给其他智能体时加载。 |
17
+ | Skill | `anet-setup` | 查找 anet 可执行文件;anet 仍未安装时进行安装,然后按已安装 anet 的设置指南完成设置。 |
18
+ | 命令 | `/anet` | 按已安装 anet 的指南执行一项“@anet”请求。 |
19
+ | 命令 | `/anet-status` | 按已安装 anet 的指南显示节点状态。 |
20
+
21
+ 本插件不包含 anet 工具或设置步骤的说明,这些内容由已安装的 anet 提供(MCP 工具 `guide`,以及命令行中的 `anet guide`)。因此,anet 的新版本只需更新 anet 可执行文件即可在 OpenCode 中生效,插件无需更新。
17
22
 
18
23
  ## 环境要求
19
24
 
20
- - anet 可在 Linux、macOS 和 Windows 上运行,支持 x86-64 与 ARM64。本插件的启动器是 POSIX shell 脚本,可在 Linux 和 macOS 上运行;在 Windows 上,请用 `anet agents wire` 注册 anet。对于 `anet agents wire` 不支持的工具,请将 `anet mcp` 加入该工具的 MCP 配置。
25
+ - Linux、macOS 或 Windows,x86-64 或 ARM64。在 Linux 和 macOS 上,插件运行 POSIX shell 脚本;在 Windows 上,插件运行 `.cmd` 脚本和 Windows 自带的 Windows PowerShell 5.1。
21
26
  - OpenCode 1.19.3 或更高版本。
22
- - anet 0.3.0 或更高版本。未安装时,`anet-setup` skill 会引导安装。
23
- - 安装需要 `curl`、`gzip` 和 `ssh-keygen`(OpenSSH 8.1 或更高版本)。
27
+ - 提供 `anet guide` 命令的 anet 版本。未安装 anet 时,插件的 MCP 服务会安装当前版本。
28
+ - 在 Linux 和 macOS 上安装需要 `curl`、`gzip` 和 `ssh-keygen`(OpenSSH 8.1 或更高版本)。
24
29
 
25
30
  ## 快速开始
26
31
 
27
32
  1. 将插件添加到 OpenCode 并重启;见下文“安装与设置”。
28
- 2. 在会话中输入:`Set up anet.`(或"配置 anet")。智能体会运行 `anet-setup` skill:征得同意后安装 anet,启动节点,并询问要加入的 hub(官方公共 hub 为 `https://hub.agentnetwork.org.cn`)。
33
+ 2. 启动一个会话。未安装 anet 时,插件的 MCP 服务会安装 anet、启动其节点并加入公共 hub;首次启动可能需要约一分钟。然后输入:`What can anet do?`(或“anet 能做什么”)。智能体会根据节点的实际状态作答。如果会话中没有 anet 工具,智能体会运行 `anet-setup` skill,完成安装并按已安装 anet 的设置指南完成设置。
29
34
  3. 重启 OpenCode,使 MCP 服务启动,然后运行 `/anet-status`。
30
- 4. 交代任务,例如:`在 anet 上找一个能总结文本的智能体,把本项目的 README 发给它,等待结果并报告。不要支付报价,把金额告诉我。`
35
+ 4. 输入以 `@anet` 开头的请求,或直接描述要交给其他智能体的工作。
31
36
 
32
37
  anet 文档中的 [OpenCode 接入指南](https://docs.agentnetwork.org.cn/docs/zh-cn/latest/agents/opencode.html)完整说明了安装、验证与卸载。
33
38
 
@@ -56,15 +61,27 @@ OpenCode 在启动时读取配置:修改后须重启。若已存在 `mcp.anet`
56
61
 
57
62
  | 选项 | 默认值 | 含义 |
58
63
  | --- | --- | --- |
59
- | `identity` | 空 | 指定的命名身份(`anet id ls`)。为空时使用 `~/.anet` 中的默认身份。 |
60
- | `anetPath` | 空 | `anet` 可执行文件的绝对路径。为空时依次查找 `PATH`、`~/.local/bin`、`/usr/local/bin` 和 `/opt/homebrew/bin`。若该路径不是可执行文件,则报告错误;不会改用其他副本,安装 skill 也不会另行安装。 |
64
+ | `identity` | 空 | 指定的命名身份(`anet id ls`)。为空时使用默认身份。 |
65
+ | `anetPath` | 空 | `anet` 可执行文件(Windows 上为 `anet.exe`)的绝对路径。为空时先查找 `PATH`,然后在 Linux 和 macOS 上查找 `~/.local/bin`、`/usr/local/bin` 和 `/opt/homebrew/bin`,在 Windows 上查找 Windows 安装程序的安装位置(`%LOCALAPPDATA%\Programs\anet`、`%LOCALAPPDATA%\anet\bin`、`%USERPROFILE%\.anet-bin`)。若该路径不是可执行文件,则报告错误;不会改用其他副本,安装 skill 也不会另行安装。 |
66
+
67
+ ## 自动安装
68
+
69
+ 插件的 MCP 服务启动时,如果找不到 anet 可执行文件(设置项 `anetPath` 为空,且 `PATH` 和上述安装位置中都没有),会在启动 `anet mcp` 之前安装 anet:
70
+
71
+ - 运行官方安装程序,不带任何参数:Linux 和 macOS 上为 `https://agentnetwork.org.cn/install.sh`,Windows 上为 `https://agentnetwork.org.cn/install.ps1`(按安装指南给出的命令,使用系统目录中的 Windows PowerShell 运行)。工作区或会话中的任何内容都不会传给安装程序。
72
+ - 安装程序校验已签名的发布清单和下载文件的 SHA-256,任何一项校验失败即停止,不做任何改动。它无需管理员权限,为当前用户安装 anet,把安装目录加入 `PATH`(Linux 和 macOS 上写入 shell 配置文件,Windows 上写入用户环境变量),在 `~/.anet` 中以安全默认值创建身份,启动节点并加入公共 hub `https://hub.agentnetwork.org.cn`。
73
+ - 安装程序在用户主目录中运行,没有输入、终端或窗口;其输出写入 MCP 服务的错误输出,不会进入 MCP 会话。在 Linux 和 macOS 上,输出还保存在 `~/.cache/anet-plugin/install.log` 中。
74
+ - 同一时间只运行一个安装:同时启动的另一个宿主会等待第一个安装完成,不会重复安装。
75
+ - 如果设置项 `anetPath` 指向不存在的文件,会报告错误,不会改为安装其他副本。
76
+
77
+ 要关闭自动安装,请在 OpenCode 的运行环境中设置环境变量 `ANET_PLUGIN_NO_INSTALL=1`。此后 MCP 服务会报告 anet 未安装,`anet-setup` skill 会在安装前先征得同意。
61
78
 
62
79
  ## 安全与副作用
63
80
 
64
- - **执行的命令。** 插件的所有 `anet` 命令都经由 `bin/anet-run.sh` 执行,并应用上述两项设置:MCP 服务(`bin/anet-mcp.sh`,即 `anet mcp`)、`/anet-status` 命令与 `anet-setup` skill 使用同一可执行文件和同一身份。在 MCP 服务之外,该脚本只从自身环境变量中读取这两项设置,由插件为智能体的 shell 命令设置。用户同意后,`anet-setup` skill 将 `https://agentnetwork.org.cn/install.sh` 安装程序下载到新建的私有临时目录,仅在下载成功后运行,并在结束后删除该目录。本插件不包含 Hook。
65
- - **网络访问。** 插件本身不建立任何连接。anet 节点连接其加入的 hub,并经由 hub 与其他节点通信。安装程序从 `agentnetwork.org.cn` 下载。
66
- - **写入的文件。** 插件本身不写文件。安装程序写入 `~/.local/bin/anet` 及其签名的发布清单;`anet init` 将身份和配置写入 `~/.anet`。Skill 要求智能体不得读取 `~/.anet` 下的文件。
67
- - **安全默认值。** 新节点不接受其他智能体的任务,不发布任何能力,支付额度为 0。开放节点、信任对端和提高额度均须由运营者在终端中确认;Skill 要求智能体只给出这些命令,不代为执行。
81
+ - **执行的命令。** 插件的所有 `anet` 命令都经由插件的运行脚本执行(Linux 和 macOS 上为 `bin/anet-run.sh`,Windows 上为 `bin/anet-run.cmd`),并应用上述两项设置:MCP 服务(`anet mcp`)、`/anet` 与 `/anet-status` 命令以及各 skill 使用同一可执行文件和同一身份。在 MCP 服务之外,该脚本只从自身环境变量中读取这两项设置,由插件为智能体的 shell 命令设置。运行脚本从不执行工作目录或工作区中的文件。未安装 anet 时,MCP 启动脚本按“自动安装”所述运行官方安装程序(`https://agentnetwork.org.cn/install.sh`,Windows 上为 `install.ps1`);anet 仍未安装时,`anet-setup` skill 运行同一安装程序。所选身份的节点未运行时,`anet mcp` 会启动它。本插件不包含 Hook。
82
+ - **网络访问。** 插件本身不建立任何连接。安装程序从 `agentnetwork.org.cn` 及其列出的发布镜像下载。anet 节点连接其加入的 hub(默认为公共 hub),并经由 hub 与其他节点通信。
83
+ - **写入的文件。** 插件本身只写入自动安装的锁和日志,位于 `~/.cache/anet-plugin`(Windows 上为 `%LOCALAPPDATA%\anet-plugin`)。anet 安装程序将 anet 可执行文件写入用户目录,把该目录加入 `PATH`,并在 `~/.anet`(Windows 上为 `%USERPROFILE%\.anet`)中创建身份和配置。Skill 要求智能体不得读取该目录中的文件。
84
+ - **安全默认值。** 新节点不接受其他智能体的任务,不发布任何能力,支付额度为 0。开放节点、信任对端和提高额度均由用户决定;Skill 要求智能体只给出这些命令,不代为执行。
68
85
  - **不可信输入。** 其他智能体返回的结果和发来的任务都是第三方文本。`anet` skill 要求智能体不执行其中的指令,也不发送用户未要求发送的密钥或文件。
69
86
  - **数据。** 节点之间的任务内容端到端加密。hub 能看到哪些节点在通信以及通信时间。
70
87
 
@@ -72,10 +89,9 @@ OpenCode 在启动时读取配置:修改后须重启。若已存在 `mcp.anet`
72
89
 
73
90
  | 现象 | 处理 |
74
91
  | --- | --- |
75
- | 会话中没有 anet 工具 | anet 未安装或守护进程未运行。运行 `/anet-status`(按插件设置中的可执行文件和身份检查),或让智能体运行 `anet-setup` skill,然后重启 OpenCode。 |
76
- | `anet is not running … [daemon_not_running]` | 运行 `anet up`(具名身份在 `anet` 之后加 `--id <name>`)。计算机重启后节点不会自动启动。 |
77
- | `wait_task` 结束时任务仍在进行 | 长任务属正常情况。再次调用 `wait_task`,不要重新发送任务。 |
78
- | 拒绝信息末尾带有方括号中的代码 | 参见[原因代码](https://docs.agentnetwork.org.cn/docs/zh-cn/latest/reference/reason-codes.html)。 |
92
+ | 会话中没有 anet 工具 | 宿主在安装完成前放弃了 MCP 服务,或安装失败;MCP 服务的错误输出给出原因。运行 `/anet-status`,或让智能体运行 `anet-setup` skill,然后重启 OpenCode。 |
93
+ | `node_status` 报告 `running: false` | 节点无法启动;其 `next` 字段给出修复命令。智能体会自行运行 `anet up`;其他修复由用户决定。 |
94
+ | 拒绝信息末尾带有方括号中的代码 | 其下一行给出下一步命令。另请参见[原因代码](https://docs.agentnetwork.org.cn/docs/zh-cn/latest/reference/reason-codes.html)。 |
79
95
 
80
96
  ## 链接
81
97
 
@@ -0,0 +1,23 @@
1
+ @echo off
2
+ rem Installs the anet command line on Windows with the official installer.
3
+ rem
4
+ rem "anet-install.cmd" runs https://agentnetwork.org.cn/install.ps1 with Windows
5
+ rem PowerShell, over TLS 1.2. The installer checks the signed release manifest
6
+ rem and the SHA-256 of the binary, stops without changing anything when a check
7
+ rem fails, installs into a directory of this user and puts it on the user PATH.
8
+ rem The Windows counterpart of anet-install.sh.
9
+ rem
10
+ rem Every program is named by its full path: PowerShell as
11
+ rem %SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe, the scripts of
12
+ rem the plugin by the directory of this file. Nothing is looked up in the
13
+ rem working directory or on PATH, where cmd.exe would look in the working
14
+ rem directory (a workspace) first. SystemRoot is set by Windows for every
15
+ rem process and is not compared with the system directory here: cmd.exe cannot
16
+ rem ask Windows for that directory without running a program, which would have
17
+ rem to be found the same way, and a host that sets SystemRoot for its MCP
18
+ rem servers already chooses every program they run. (The automatic installation
19
+ rem of the MCP launcher, in anet-run.ps1, asks Windows for the system directory
20
+ rem with [Environment]::GetFolderPath.)
21
+ setlocal EnableExtensions DisableDelayedExpansion
22
+ %SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe -NoLogo -NoProfile -NonInteractive -ExecutionPolicy Bypass -Command "[Net.ServicePointManager]::SecurityProtocol=3072; & ([scriptblock]::Create((irm -UseBasicParsing https://agentnetwork.org.cn/install.ps1)))" 0<NUL
23
+ exit /b %ERRORLEVEL%
@@ -1,25 +1,312 @@
1
1
  #!/bin/sh
2
2
  # Installs the anet command line with the official installer.
3
3
  #
4
- # `sh install-anet.sh [installer arguments]` downloads https://agentnetwork.org.cn/install.sh
4
+ # `sh anet-install.sh [installer arguments]` downloads https://agentnetwork.org.cn/install.sh
5
5
  # into a new private directory, runs it only when the download succeeded, and
6
6
  # removes the directory afterwards. The installer checks the signed release
7
7
  # manifest and the SHA-256 of the binary and stops without changing anything
8
- # when a check fails. The script exists so that an agent host that refuses
9
- # command substitution in a shell command can still run the installation as one
10
- # plain command.
8
+ # when a check fails; by default it installs anet for this user, starts the
9
+ # node and joins the public hub. The script exists so that an agent host that
10
+ # refuses command substitution in a shell command can still run the
11
+ # installation as one plain command (the anet-setup skill).
12
+ #
13
+ # `sh anet-install.sh --mcp` is the first step of the MCP launcher
14
+ # (anet-mcp.sh): it installs anet when the runner finds no anet executable, so
15
+ # that enabling the plugin is enough to have anet installed and its node
16
+ # running. It does nothing when the environment variable ANET_PLUGIN_NO_INSTALL
17
+ # is set to a value other than 0, when the plugin setting anetPath is set (an
18
+ # invalid one is reported by the runner, and no other copy is installed), and
19
+ # in a POSIX shell on Windows (anet-mcp.cmd installs there). Otherwise it runs
20
+ # the installer without arguments: nothing from the workspace or the session
21
+ # reaches it, the user's settings select nothing of it either. The installer
22
+ # runs
23
+ # * with no input and no controlling terminal (in a session of its own, with
24
+ # setsid or Perl where available), so that it never asks for a password
25
+ # on the terminal of the host, and never reads the MCP session;
26
+ # * in the user's home directory, not in the working directory of the
27
+ # session (a workspace);
28
+ # * with its output written to install.log in the state directory, which is
29
+ # copied to standard error afterwards (the launcher sends this script's
30
+ # output to standard error: standard output is the MCP session). Because
31
+ # the installer does not write to the host's pipe and has a session of
32
+ # its own, a host that gives up on a slow start does not end it halfway;
33
+ # it finishes, and the next session finds anet.
34
+ # It waits for the installer at most 15 minutes, and exits with status 0 in
35
+ # every case: the launcher goes on, and the runner reports anet as missing
36
+ # when the installation did not succeed.
37
+ #
38
+ # One installation at a time. Both forms hold the lock directory
39
+ # <state>/install.lock while the installer runs, with the process ID of the
40
+ # holder and its start time (as ps prints it) in the file pid; <state> is
41
+ # $XDG_CACHE_HOME/anet-plugin, or ~/.cache/anet-plugin (an absolute path only;
42
+ # without one the --mcp form installs nothing). Another host that starts at
43
+ # the same moment waits for it, at most 10 minutes (5 for the plain form), and
44
+ # then installs nothing itself when the first installation left an anet
45
+ # behind. A lock whose holder no longer runs (no process with that ID, or one
46
+ # that started at another time: the ID was reused), or that is older than 30
47
+ # minutes, is removed.
11
48
  set -u
12
49
 
13
- umask 077
14
- dir=$(mktemp -d 2>/dev/null) || {
15
- echo "Error: a temporary directory could not be created." >&2
16
- exit 1
50
+ # Programs (sh, sed, uname and the others) are found only in the absolute
51
+ # directories of PATH: a relative entry (such as "." or an empty one) would
52
+ # find a file of the working directory of the session, which can be an
53
+ # untrusted workspace. This comes before the first command that is not built
54
+ # into the shell, and the scripts started from here inherit it.
55
+ _abs=
56
+ _ifs=$IFS
57
+ IFS=:
58
+ set -f
59
+ for _d in ${PATH:-}; do
60
+ case $_d in
61
+ /*) _abs=${_abs:+$_abs:}$_d ;;
62
+ esac
63
+ done
64
+ IFS=$_ifs
65
+ set +f
66
+ PATH=${_abs:-/usr/bin:/bin}
67
+ export PATH
68
+ unset _abs _ifs _d
69
+
70
+ here=$(cd "$(dirname "$0")" 2>/dev/null && pwd) || here=$(dirname "$0")
71
+ self="$here/anet-install.sh"
72
+
73
+ say() { printf '%s\n' "$*" >&2; }
74
+
75
+ # state_dir prints the directory of the lock and the log, or fails.
76
+ state_dir() {
77
+ _base=${XDG_CACHE_HOME:-}
78
+ case $_base in
79
+ /*) ;;
80
+ *) _base=${HOME:-}/.cache ;;
81
+ esac
82
+ case $_base in
83
+ /*) printf '%s/anet-plugin\n' "$_base" ;;
84
+ *) return 1 ;;
85
+ esac
86
+ }
87
+
88
+ # anet_missing: whether the runner finds no anet executable and no anetPath is
89
+ # set (its --resolve prints "executable: not found" exactly then).
90
+ anet_missing() {
91
+ [ "$(sh "$here/anet-run.sh" --resolve 2>/dev/null | sed -n 1p)" = "executable: not found" ]
92
+ }
93
+
94
+ # started PID prints when the process PID started, as one line, or nothing
95
+ # where ps cannot say.
96
+ started() {
97
+ ps -o lstart= -p "$1" 2>/dev/null | sed -e 's/ */ /g' -e 's/^ //' -e 's/ $//' -e 1q
98
+ }
99
+
100
+ # holder_runs LINE: whether the holder that the line of a lock names ("PID
101
+ # START") still runs: a process with that ID exists and, when the line has a
102
+ # start time and ps gives one, it started then. (kill -0 sends no signal; it
103
+ # only checks that the process exists.)
104
+ holder_runs() {
105
+ _pid=${1%% *}
106
+ case $_pid in
107
+ '' | *[!0-9]*) return 1 ;;
108
+ esac
109
+ kill -0 "$_pid" 2>/dev/null || return 1
110
+ _was=
111
+ case $1 in
112
+ *" "*) _was=${1#* } ;;
113
+ esac
114
+ [ -n "$_was" ] || return 0
115
+ _now=$(started "$_pid")
116
+ [ -z "$_now" ] || [ "$_now" = "$_was" ]
117
+ }
118
+
119
+ # take_lock SECONDS: takes the lock, waiting at most SECONDS. Sets waited=1
120
+ # when another installation held it.
121
+ waited=0
122
+ take_lock() {
123
+ _left=$1
124
+ while :; do
125
+ if mkdir "$lock" 2>/dev/null; then
126
+ _me=$(started "$$")
127
+ printf '%s\n' "$$${_me:+ $_me}" >"$lock/pid" && return 0
128
+ rmdir "$lock" 2>/dev/null
129
+ return 1
130
+ fi
131
+ _holder=$(cat "$lock/pid" 2>/dev/null) || _holder=
132
+ _stale=0
133
+ if [ -n "$(find "$lock" -prune -mmin +30 2>/dev/null)" ]; then
134
+ _stale=1
135
+ elif [ -n "$_holder" ]; then
136
+ holder_runs "$_holder" || _stale=1
137
+ elif [ -n "$(find "$lock" -prune -mmin +1 2>/dev/null)" ]; then
138
+ _stale=1 # created more than a minute ago and never given a holder
139
+ fi
140
+ if [ "$_stale" -eq 1 ]; then
141
+ # Moved aside first, so that of two processes that found it stale only
142
+ # one removes it; a lock that changed holder in the meantime is put back.
143
+ _aside="$lock.stale.$$"
144
+ if mv "$lock" "$_aside" 2>/dev/null; then
145
+ if [ "$(cat "$_aside/pid" 2>/dev/null)" = "$_holder" ]; then
146
+ rm -f "$_aside/pid"
147
+ rmdir "$_aside" 2>/dev/null
148
+ else
149
+ mv "$_aside" "$lock" 2>/dev/null || { rm -f "$_aside/pid"; rmdir "$_aside" 2>/dev/null; }
150
+ fi
151
+ fi
152
+ continue
153
+ fi
154
+ [ "$_left" -gt 0 ] || return 1
155
+ if [ "$waited" -eq 0 ]; then
156
+ say "Another installation of anet is running; waiting for it to finish."
157
+ fi
158
+ waited=1
159
+ sleep 1
160
+ _left=$((_left - 1))
161
+ done
17
162
  }
18
- trap 'rm -rf "$dir"' EXIT
19
- trap 'exit 1' HUP INT TERM
20
163
 
21
- if ! curl --proto '=https' --tlsv1.2 -fsSL https://agentnetwork.org.cn/install.sh -o "$dir/install.sh"; then
22
- echo "Error: the installer could not be downloaded." >&2
23
- exit 1
164
+ release_lock() {
165
+ _line=$(cat "${lock:-/nonexistent}/pid" 2>/dev/null) || _line=
166
+ if [ -n "${lock:-}" ] && [ "${_line%% *}" = "$$" ]; then
167
+ rm -f "$lock/pid"
168
+ rmdir "$lock" 2>/dev/null
169
+ fi
170
+ }
171
+
172
+ # lock_live: whether a running process holds the lock.
173
+ lock_live() {
174
+ _h=$(cat "$lock/pid" 2>/dev/null) || _h=
175
+ [ -n "$_h" ] && holder_runs "$_h"
176
+ }
177
+
178
+ # cleanup runs on exit: the lock of this process and the download directory.
179
+ _dir=
180
+ cleanup() {
181
+ release_lock
182
+ if [ -n "$_dir" ]; then
183
+ rm -rf "$_dir"
184
+ fi
185
+ }
186
+
187
+ # run_installer [installer arguments]: download and run the official installer.
188
+ run_installer() {
189
+ umask 077
190
+ _dir=$(mktemp -d 2>/dev/null) || {
191
+ _dir=
192
+ echo "Error: a temporary directory could not be created." >&2
193
+ return 1
194
+ }
195
+ if ! curl --proto '=https' --tlsv1.2 -fsSL https://agentnetwork.org.cn/install.sh -o "$_dir/install.sh"; then
196
+ echo "Error: the installer could not be downloaded." >&2
197
+ return 1
198
+ fi
199
+ # The home directory, not the working directory of the session: the node
200
+ # that the installer starts keeps its working directory.
201
+ case ${HOME:-} in
202
+ /*) cd "$HOME" 2>/dev/null || cd / ;;
203
+ *) cd / ;;
204
+ esac
205
+ sh "$_dir/install.sh" "$@"
206
+ }
207
+
208
+ # detached COMMAND...: COMMAND in a session of its own (no controlling
209
+ # terminal), where setsid or Perl can make one; otherwise as it is.
210
+ detached() {
211
+ if command -v setsid >/dev/null 2>&1; then
212
+ exec setsid "$@"
213
+ fi
214
+ if command -v perl >/dev/null 2>&1; then
215
+ exec perl -MPOSIX -e 'POSIX::setsid(); exec { $ARGV[0] } @ARGV or exit 127' -- "$@"
216
+ fi
217
+ exec "$@"
218
+ }
219
+
220
+ opted_out() {
221
+ case ${ANET_PLUGIN_NO_INSTALL:-} in
222
+ "" | 0) return 1 ;;
223
+ *) return 0 ;;
224
+ esac
225
+ }
226
+
227
+ case ${1:-} in
228
+ --mcp)
229
+ opted_out && exit 0
230
+ case $(uname -s 2>/dev/null) in
231
+ MINGW* | MSYS* | CYGWIN*) exit 0 ;;
232
+ esac
233
+ anet_missing || exit 0
234
+ state=$(state_dir) || {
235
+ say "anet is not installed, and it was not installed automatically: HOME is not an absolute path."
236
+ exit 0
237
+ }
238
+ (umask 077 && mkdir -p "$state") || exit 0
239
+ lock="$state/install.lock"
240
+ log="$state/install.log"
241
+ result=$(mktemp "$state/result.XXXXXX" 2>/dev/null) || exit 0
242
+ say "anet is not installed. Installing it with the official installer (https://agentnetwork.org.cn/install.sh),"
243
+ say "which checks the signed release manifest, installs anet for this user, starts its node and joins the public hub."
244
+ say "Set the environment variable ANET_PLUGIN_NO_INSTALL=1 to turn this off."
245
+ (detached sh "$self" --mcp-worker "$result" </dev/null >/dev/null 2>&1) &
246
+ worker=$!
247
+ left=900
248
+ gone=0
249
+ while [ ! -s "$result" ] && [ "$left" -gt 0 ]; do
250
+ # The worker is gone without a result and no installation holds the
251
+ # lock, for three seconds in a row: nothing is coming.
252
+ if ! kill -0 "$worker" 2>/dev/null && ! lock_live; then
253
+ gone=$((gone + 1))
254
+ [ "$gone" -lt 3 ] || break
255
+ else
256
+ gone=0
257
+ fi
258
+ sleep 1
259
+ left=$((left - 1))
260
+ done
261
+ outcome=$(cat "$result" 2>/dev/null) || outcome=
262
+ rm -f "$result"
263
+ case $outcome in
264
+ installed:*)
265
+ cat "$log" >&2 2>/dev/null
266
+ say "The anet installer ended with status ${outcome#installed:}."
267
+ ;;
268
+ other) say "Another installation of anet has finished." ;;
269
+ busy) say "Another installation of anet is still running; anet was not installed by this session." ;;
270
+ *) say "The installation of anet has not finished; it goes on in the background (log: $log)." ;;
271
+ esac
272
+ exit 0
273
+ ;;
274
+ --mcp-worker)
275
+ # The detached part of --mcp; $2 is the file for the outcome.
276
+ result=${2:-}
277
+ state=$(state_dir) || exit 0
278
+ lock="$state/install.lock"
279
+ log="$state/install.log"
280
+ if ! take_lock 600; then
281
+ printf 'busy\n' >"$result"
282
+ exit 0
283
+ fi
284
+ trap cleanup EXIT
285
+ trap 'exit 1' HUP INT TERM
286
+ if [ "$waited" -eq 1 ] && ! anet_missing; then
287
+ printf 'other\n' >"$result"
288
+ exit 0
289
+ fi
290
+ (umask 077 && : >"$log")
291
+ run_installer </dev/null >"$log" 2>&1
292
+ printf 'installed:%s\n' "$?" >"$result"
293
+ exit 0
294
+ ;;
295
+ esac
296
+
297
+ # The plain form: the installer with the given arguments, its output on this
298
+ # terminal.
299
+ trap cleanup EXIT
300
+ trap 'exit 1' HUP INT TERM
301
+ if state=$(state_dir) && (umask 077 && mkdir -p "$state"); then
302
+ lock="$state/install.lock"
303
+ if ! take_lock 300; then
304
+ echo "Error: another installation of anet is still running; try again when it has finished." >&2
305
+ exit 1
306
+ fi
307
+ if [ "$waited" -eq 1 ] && ! anet_missing; then
308
+ say "Another installation of anet has finished. Run the runner with --resolve to see it."
309
+ exit 0
310
+ fi
24
311
  fi
25
- sh "$dir/install.sh" "$@"
312
+ run_installer "$@"
package/bin/anet-mcp ADDED
@@ -0,0 +1,26 @@
1
+ #!/bin/sh
2
+ # Starts the MCP server of the local anet node through anet-mcp.sh, for a
3
+ # host that starts the launcher by its path: on Windows the same path, without
4
+ # an extension, selects anet-mcp.cmd.
5
+
6
+ # Programs (sh, sed, uname and the others) are found only in the absolute
7
+ # directories of PATH: a relative entry (such as "." or an empty one) would
8
+ # find a file of the working directory of the session, which can be an
9
+ # untrusted workspace. This comes before the first command that is not built
10
+ # into the shell, and the scripts started from here inherit it.
11
+ _abs=
12
+ _ifs=$IFS
13
+ IFS=:
14
+ set -f
15
+ for _d in ${PATH:-}; do
16
+ case $_d in
17
+ /*) _abs=${_abs:+$_abs:}$_d ;;
18
+ esac
19
+ done
20
+ IFS=$_ifs
21
+ set +f
22
+ PATH=${_abs:-/usr/bin:/bin}
23
+ export PATH
24
+ unset _abs _ifs _d
25
+
26
+ exec sh "$(dirname "$0")/anet-mcp.sh" "$@"
@@ -0,0 +1,16 @@
1
+ @echo off
2
+ rem Starts the MCP server of the local anet node ("anet mcp", stdio) for the
3
+ rem executable and identity of the plugin settings, which the host passes in
4
+ rem ANET_PLUGIN_BIN and ANET_PLUGIN_IDENTITY; see anet-run.cmd. The Windows
5
+ rem counterpart of anet-mcp.sh.
6
+ rem
7
+ rem ANET_RUN_INSTALL=missing asks anet-run.ps1 to install anet with the
8
+ rem official installer (install.ps1, which also starts the node and joins the
9
+ rem public hub) when it finds no anet.exe, unless ANET_PLUGIN_NO_INSTALL=1 is
10
+ rem set; all of its output goes to standard error, because standard output is
11
+ rem the MCP session. "anet mcp" then starts the node of the selected identity
12
+ rem when it is not running, and serves the tools even when the node cannot
13
+ rem run: node_status then names the reason and the command that fixes it.
14
+ set "ANET_PLUGIN_SETTINGS=env"
15
+ set "ANET_RUN_INSTALL=missing"
16
+ "%~dp0anet-run.cmd" mcp