@tachikomagundam/abathur 0.2.1 → 0.2.2
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 +49 -13
- package/dist/test/opencode.test.js +20 -0
- package/package.json +7 -1
- package/plugin/abathur.ts +10 -5
package/README.md
CHANGED
|
@@ -139,8 +139,10 @@ abathur run --genome toy-smoke --dry-run # plan + requires[] probes, zero sp
|
|
|
139
139
|
### Inside opencode
|
|
140
140
|
|
|
141
141
|
Abathur ships an official opencode plugin adapter. The harness remains the
|
|
142
|
-
orchestrator, but once
|
|
143
|
-
directly:
|
|
142
|
+
orchestrator, but once set up an opencode session can also drive the CLI
|
|
143
|
+
directly. Two install routes:
|
|
144
|
+
|
|
145
|
+
**Route A — one command (tool + `/abathur` slash command).**
|
|
144
146
|
|
|
145
147
|
```bash
|
|
146
148
|
npm i -g @tachikomagundam/abathur
|
|
@@ -148,7 +150,22 @@ abathur opencode install # copies plugin assets into ~/.config/opencode/
|
|
|
148
150
|
# restart opencode
|
|
149
151
|
```
|
|
150
152
|
|
|
151
|
-
|
|
153
|
+
**Route B — config only (tool, no slash command).** Put the package name in
|
|
154
|
+
your opencode config and restart:
|
|
155
|
+
|
|
156
|
+
```jsonc
|
|
157
|
+
{ "plugin": ["@tachikomagundam/abathur"] }
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
opencode then downloads the package from npm at startup into its own cache
|
|
161
|
+
(`~/.cache/opencode/packages/…`) and loads the package's `./server` export —
|
|
162
|
+
no file copying, no uninstall step (delete the line). Two honest limits: the
|
|
163
|
+
`abathur` **CLI** still must exist on `PATH` (or `ABATHUR_BIN`) because the
|
|
164
|
+
tool spawns it, so keep the `npm i -g` install; and slash commands are plain
|
|
165
|
+
markdown files that plugins cannot register upstream, so `/abathur` is Route A
|
|
166
|
+
only.
|
|
167
|
+
|
|
168
|
+
Either route gives the session:
|
|
152
169
|
|
|
153
170
|
- the agent tool **`abathur`** — spawns the `abathur` CLI argv-only (never a
|
|
154
171
|
shell), restricted to eight commands (`genome`, `run`, `status`, `bundle`,
|
|
@@ -159,11 +176,13 @@ After a restart the session gets two things:
|
|
|
159
176
|
so the allowlist limits typos and UX, not capability. `promote` and
|
|
160
177
|
`tombstone` are deliberately NOT reachable through the tool: they are
|
|
161
178
|
human gates and must be run in a terminal.
|
|
162
|
-
- the user command **`/abathur <args…>`** — a slash command
|
|
163
|
-
agent to translate its arguments into a tool call and report
|
|
179
|
+
- the user command **`/abathur <args…>`** (Route A only) — a slash command
|
|
180
|
+
that tells the agent to translate its arguments into a tool call and report
|
|
181
|
+
the exit code.
|
|
164
182
|
|
|
165
|
-
`abathur opencode status` shows each
|
|
166
|
-
and state (up-to-date / outdated /
|
|
183
|
+
Route A ships its own manager commands: `abathur opencode status` shows each
|
|
184
|
+
target's path, installed/packaged sha256, and state (up-to-date / outdated /
|
|
185
|
+
foreign / absent).
|
|
167
186
|
`abathur opencode uninstall` removes only files carrying the abathur marker; a
|
|
168
187
|
foreign file at a target path makes both commands refuse with exit 2 and name
|
|
169
188
|
the path — nothing is ever overwritten or deleted behind your back (there is
|
|
@@ -408,8 +427,10 @@ abathur run --genome toy-smoke --dry-run # 计划 + requires[] 探针,零
|
|
|
408
427
|
|
|
409
428
|
### 在 opencode 里调用
|
|
410
429
|
|
|
411
|
-
Abathur 自带官方 opencode
|
|
412
|
-
会话也可以直接驱动 CLI
|
|
430
|
+
Abathur 自带官方 opencode 插件适配器。工装仍是编排者,但配置之后,opencode
|
|
431
|
+
会话也可以直接驱动 CLI。安装有两条路线:
|
|
432
|
+
|
|
433
|
+
**路线 A——一条命令(工具 + `/abathur` 斜杠命令)。**
|
|
413
434
|
|
|
414
435
|
```bash
|
|
415
436
|
npm i -g @tachikomagundam/abathur
|
|
@@ -417,7 +438,21 @@ abathur opencode install # 把插件资产复制进 ~/.config/opencode/
|
|
|
417
438
|
# 重启 opencode
|
|
418
439
|
```
|
|
419
440
|
|
|
420
|
-
|
|
441
|
+
**路线 B——纯配置(只有工具,没有斜杠命令)。** 把包名写进 opencode 配置再
|
|
442
|
+
重启:
|
|
443
|
+
|
|
444
|
+
```jsonc
|
|
445
|
+
{ "plugin": ["@tachikomagundam/abathur"] }
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
opencode 会在启动时自行从 npm 把包下载到它自己的缓存
|
|
449
|
+
(`~/.cache/opencode/packages/…`)并加载该包的 `./server` 导出——不复制文件,
|
|
450
|
+
也没有 uninstall 步骤(删掉那行即可)。两点诚实的限制:工具 spawn 的是
|
|
451
|
+
`abathur` **CLI**,所以 CLI 仍必须在 `PATH`(或 `ABATHUR_BIN`)上可达,
|
|
452
|
+
`npm i -g` 不能省;而斜杠命令在上游只是 markdown 文件、插件无法注册,
|
|
453
|
+
所以 `/abathur` 只有路线 A 提供。
|
|
454
|
+
|
|
455
|
+
任一路线都会让会话获得:
|
|
421
456
|
|
|
422
457
|
- 智能体工具 **`abathur`**——以纯 argv 方式 spawn `abathur` CLI(绝不经过
|
|
423
458
|
shell),顶层命令限定为八个(`genome`、`run`、`status`、`bundle`、`graft`、
|
|
@@ -426,10 +461,11 @@ abathur opencode install # 把插件资产复制进 ~/.config/opencode/
|
|
|
426
461
|
bash 等同的权限——`run` 与 `genome` 按设计就会 spawn 变异器/引擎二进制——
|
|
427
462
|
所以允许清单限制的是笔误与体验,而非能力。`promote` 与 `tombstone` 刻意
|
|
428
463
|
不可经由工具触达:它们是人类闸门,必须在终端里运行。
|
|
429
|
-
- 用户命令 **`/abathur
|
|
430
|
-
|
|
464
|
+
- 用户命令 **`/abathur <参数…>`**(仅路线 A)——斜杠命令,指示智能体把参数
|
|
465
|
+
翻译成工具调用并回报退出码。
|
|
431
466
|
|
|
432
|
-
|
|
467
|
+
路线 A 自带管理命令:`abathur opencode status` 逐目标打印路径、已安装/随包
|
|
468
|
+
sha256 与状态
|
|
433
469
|
(up-to-date / outdated / foreign / absent)。
|
|
434
470
|
`abathur opencode uninstall` 只删除带有 abathur 标记的文件;若目标路径上躺着
|
|
435
471
|
别人的文件,两条命令都会 exit 2 并点名路径——绝不会背着你覆盖或删除任何东西
|
|
@@ -255,6 +255,26 @@ test("shipped plugin assets carry zero machine literals (D7 discipline extended
|
|
|
255
255
|
}
|
|
256
256
|
}
|
|
257
257
|
});
|
|
258
|
+
test("npm name route: exports['./server'] ships the marker'd plugin + runtime dep declared", async () => {
|
|
259
|
+
const pkg = JSON.parse(await readFile(path.join(repoRoot, "package.json"), "utf8"));
|
|
260
|
+
// opencode picks the server entry via exports["./server"] (extractExportValue
|
|
261
|
+
// accepts a plain string; plugin/shared.ts resolvePackageEntrypoint).
|
|
262
|
+
const serverEntry = pkg.exports?.["./server"];
|
|
263
|
+
assert.equal(typeof serverEntry, "string", "./server export must be a plain string path");
|
|
264
|
+
const server = serverEntry;
|
|
265
|
+
const target = path.resolve(repoRoot, server);
|
|
266
|
+
const head = (await readFile(target, "utf8")).split("\n")[0] ?? "";
|
|
267
|
+
assert.ok(head.startsWith(PLUGIN_MARKER), `server entry must start with the plugin marker: ${head}`);
|
|
268
|
+
// The tarball must actually contain that file or the name route installs nothing to import.
|
|
269
|
+
assert.ok((pkg.files ?? []).some((entry) => server.startsWith(`./${entry}/`)), "server entry must live under a published files[] directory");
|
|
270
|
+
// Arborist installs the package's dependencies next to it in opencode's cache —
|
|
271
|
+
// that sibling copy is how the shipped import of @opencode-ai/plugin resolves (OMO mechanism).
|
|
272
|
+
const dep = pkg.dependencies?.["@opencode-ai/plugin"];
|
|
273
|
+
assert.equal(typeof dep, "string", "@opencode-ai/plugin must be a runtime dependency");
|
|
274
|
+
assert.ok((dep ?? "").length > 0, "dependency range must not be empty");
|
|
275
|
+
// Route B must serve the same bytes the route A installer copies: both resolve to plugin/abathur.ts.
|
|
276
|
+
assert.equal(serverEntry, "./plugin/abathur.ts", "server entry and installer asset must be one file");
|
|
277
|
+
});
|
|
258
278
|
test("CLI help: opencode is a registered top-level command", async (t) => {
|
|
259
279
|
const { env } = await makeEnv(t);
|
|
260
280
|
const help = abathur(env, "--help");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tachikomagundam/abathur",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "Evolution harness: observe failures, mutate, re-bench, select — human-gated promotion, offline lineage bundles.",
|
|
5
5
|
"author": "TachikomaGundam",
|
|
6
6
|
"type": "module",
|
|
@@ -20,6 +20,11 @@
|
|
|
20
20
|
"abathur": "dist/cli.js"
|
|
21
21
|
},
|
|
22
22
|
"main": "dist/cli.js",
|
|
23
|
+
"exports": {
|
|
24
|
+
".": "./dist/cli.js",
|
|
25
|
+
"./server": "./plugin/abathur.ts",
|
|
26
|
+
"./package.json": "./package.json"
|
|
27
|
+
},
|
|
23
28
|
"files": [
|
|
24
29
|
"dist",
|
|
25
30
|
"config",
|
|
@@ -33,6 +38,7 @@
|
|
|
33
38
|
"prepack": "npm run build"
|
|
34
39
|
},
|
|
35
40
|
"dependencies": {
|
|
41
|
+
"@opencode-ai/plugin": "^1.17.4",
|
|
36
42
|
"zod": "^4.0.0"
|
|
37
43
|
},
|
|
38
44
|
"devDependencies": {
|
package/plugin/abathur.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// abathur-opencode-plugin v0.2.
|
|
1
|
+
// abathur-opencode-plugin v0.2.2
|
|
2
2
|
// Official opencode plugin adapter for the abathur evolution harness.
|
|
3
3
|
// Registers ONE agent tool, `abathur`, that shells out to the abathur CLI —
|
|
4
4
|
// argv-only (node:child_process execFile, never a shell), top-level commands
|
|
@@ -8,10 +8,15 @@
|
|
|
8
8
|
// V1 plugin format (opencode >= 1.14): default export { id, server }, where
|
|
9
9
|
// server(input, options) resolves to Hooks; Hooks.tool is a
|
|
10
10
|
// { [name]: ToolDefinition } record (see @opencode-ai/plugin).
|
|
11
|
-
// This file is shipped as-is (package.json "files") and
|
|
12
|
-
//
|
|
13
|
-
//
|
|
14
|
-
//
|
|
11
|
+
// This file is shipped as-is (package.json "files") and reaches a session by
|
|
12
|
+
// two routes, neither compiling it through abathur's tsc:
|
|
13
|
+
// (A) copied into ~/.config/opencode/plugins/ by `abathur opencode install`
|
|
14
|
+
// (adds the /abathur command too); "@opencode-ai/plugin" then resolves in
|
|
15
|
+
// opencode's config-directory node_modules.
|
|
16
|
+
// (B) served as the package's "./server" export when the npm package name is
|
|
17
|
+
// listed in opencode.jsonc "plugin" — opencode's arborist install places
|
|
18
|
+
// @opencode-ai/plugin (runtime dependency) next to the package in its
|
|
19
|
+
// cache, so the same import resolves there too.
|
|
15
20
|
|
|
16
21
|
import { execFile } from "node:child_process";
|
|
17
22
|
import { tool } from "@opencode-ai/plugin";
|