rainskills 0.1.30 → 0.1.34
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 +11 -3
- package/SKILL.md +8 -2
- package/bin/rainskills.js +27 -1
- package/install.sh +55 -10
- package/marketplace/rainskills/.claude-plugin/plugin.json +2 -1
- package/marketplace/rainskills/.codex-plugin/plugin.json +2 -1
- package/marketplace/rainskills/skills/rainskills/SKILL.md +9 -3
- package/package.json +3 -2
- package/rainbond-app-assistant/references/runtime-gate.md +7 -3
- package/rainbond-app-version-assistant/SKILL.md +6 -2
- package/rainbond-delivery-verifier/SKILL.md +6 -2
- package/rainbond-env-sync/SKILL.md +6 -2
- package/rainbond-fullstack-bootstrap/SKILL.md +21 -3
- package/rainbond-fullstack-bootstrap/modules/40-source-and-package-rules.md +1 -1
- package/rainbond-fullstack-troubleshooter/SKILL.md +6 -2
- package/rainbond-opensource-app-deploy/references/runtime-gate.md +6 -2
- package/rainbond-platform-installer/SKILL.md +1 -1
- package/rainbond-platform-installer/scripts/auto-update.js +2 -1
- package/rainbond-platform-installer/scripts/host-targets.js +11 -0
- package/rainbond-platform-installer/scripts/installed-version.js +1 -1
- package/rainbond-platform-installer/scripts/result-telemetry.js +3 -1
- package/rainbond-platform-installer/scripts/telemetry.js +1 -1
- package/rainbond-platform-installer/scripts/windows-onboarding.js +27 -8
- package/rainbond-platform-query/SKILL.md +6 -2
- package/rainbond-project-init/SKILL.md +6 -2
- package/rainbond-template-installer/SKILL.md +6 -2
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Rainskills
|
|
2
2
|
|
|
3
|
-
Rainskills 是一组面向应用识别、部署、排障和交付的 AI Skills,支持 Codex、Claude Code、Pi Agent、DeepSeek Harness 和
|
|
3
|
+
Rainskills 是一组面向应用识别、部署、排障和交付的 AI Skills,支持 Codex、Claude Code、Pi Agent、DeepSeek Harness、WorkBuddy 和 Hermes Agent。用户在市场中只会看到一个 `Rainskills` 产品,安装后 11 个 `rainbond-*` Skill 仍会独立触发。
|
|
4
4
|
|
|
5
5
|
## 安装
|
|
6
6
|
|
|
@@ -57,7 +57,15 @@ npx --yes rainskills workbuddy
|
|
|
57
57
|
|
|
58
58
|
默认安装到 `${WORKBUDDY_CONFIG_DIR:-~/.workbuddy-ai}/skills`。如果安装发生在一个已经打开的 WorkBuddy 任务中,先刷新 Skill 列表或新建任务;部署时明确指定 Rainbond/Rainskills,或让项目保留 `rainbond.app.json`、`.rainbond/local.json` 标记,以避免被内置 Sites 路由抢占。
|
|
59
59
|
|
|
60
|
-
|
|
60
|
+
Hermes Agent:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
npx --yes rainskills hermes
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
默认安装到 `${HERMES_HOME:-~/.hermes}/skills`,与其他宿主共用同一 CLI profile 和本地 Rainskills CLI,不配置客户端 MCP。如果安装发生在一个已经打开的 Hermes 会话中,执行 `/reset` 或新建会话后再使用新安装的 Skills。
|
|
67
|
+
|
|
68
|
+
安装流程支持 Codex、Claude Code、Pi Agent、DeepSeek Harness、WorkBuddy 和 Hermes Agent;所有 Agent 共用同一组 Skills、CLI profile 和本地 Rainskills CLI,不提供单独的客户端 MCP adapter。macOS、Linux 和 WSL 不支持 OpenClaw 安装。不要手工复制 Skill、拼接凭据或修改 Agent 配置。
|
|
61
69
|
|
|
62
70
|
## 安装完成时用户会看到什么
|
|
63
71
|
|
|
@@ -239,7 +247,7 @@ node ~/.rainbond/lib/rainskills/bin/rainskills.js platform install --onboarding-
|
|
|
239
247
|
|
|
240
248
|
Rainskills 会在用户下一次发起业务动作时,由本地运行时立即返回环境查询结果,并另行启动后台任务静默检查更新。更新只跟随 npm `latest` 指向的正式版。当前版本是 RC 或其他预发布版本时不会查询、不会自动升级;npm 上的新 RC 版本也不参与正式版自动升级。
|
|
241
249
|
|
|
242
|
-
发现更高的正式版后,后台任务只委托到经过校验的精确版本,例如 `rainskills@0.1.
|
|
250
|
+
发现更高的正式版后,后台任务只委托到经过校验的精确版本,例如 `rainskills@0.1.34`,不会执行浮动的 `@latest` 业务代码。新版本原子刷新已经安装的 Rainskills Skills;当前业务继续使用启动时已经加载的版本,最迟从下一条新任务开始使用新版。npm 超时、版本检查失败、安装位置不安全或文件迁移失败时会保留旧版本,且不会阻塞或改变当前操作。
|
|
243
251
|
|
|
244
252
|
升级只更新 Rainskills 自身,不触发 Rainbond 安装、运行环境选择、登录授权或重新对接,也不会新增 Agent MCP 配置。更新内容仅包括 Skills 和本地 CLI。原始业务操作会继续执行;只有该业务操作本身需要运行环境时,才按既有门禁检查当前连接。可用连接直接复用,401 只重新授权一次,403 立即停止,从未连接过运行环境时才进入环境选择。
|
|
245
253
|
|
package/SKILL.md
CHANGED
|
@@ -9,7 +9,7 @@ This is the single marketplace entry for the complete Rainskills product. The in
|
|
|
9
9
|
|
|
10
10
|
## Initialize
|
|
11
11
|
|
|
12
|
-
1. Detect the current host client and map it to exactly one supported installer target: Codex=`codex`, Claude Code=`claude`, Pi Agent=`pi`, DeepSeek Harness=`dsh`, or
|
|
12
|
+
1. Detect the current host client and map it to exactly one supported installer target: Codex=`codex`, Claude Code=`claude`, Pi Agent=`pi`, DeepSeek Harness=`dsh`, WorkBuddy=`workbuddy`, or Hermes Agent=`hermes`. All six use the same CLI profile, installed Skills, and protected local Rainskills CLI; none requires a separate client MCP adapter. DeepSeek Harness installs to `$DSH_HOME/skills` (default `~/.dsh/skills`). WorkBuddy installs to `$WORKBUDDY_CONFIG_DIR/skills` (default `~/.workbuddy-ai/skills`). Hermes Agent installs to `$HERMES_HOME/skills` (default `~/.hermes/skills`); `AI_AGENT=hermes-agent` or `HERMES_AGENT=true` is a reliable fallback when the host must be detected from a terminal subprocess. The macOS, Linux, and WSL installer intentionally does not support OpenClaw; report that limitation instead of invoking an unsupported target. Do not ask the user which supported client they are currently using. If the host cannot be determined reliably, omit the target and let the installer ask.
|
|
13
13
|
2. Resolve the directory containing this `SKILL.md`. On native Windows, if the adjacent `bin/rainskills.js` exists, run it by absolute path with the detected target in an attached interactive terminal: `node <skill-directory>/bin/rainskills.js <target>`. On macOS, Linux, or WSL, if the adjacent `install.sh` exists, run `bash <skill-directory>/install.sh <target>` the same way. Do not replace the installer with manual file copies.
|
|
14
14
|
3. Keep stdin, stdout, and stderr attached. When `RAINSKILLS_USER_INPUT_REQUIRED` appears, pause for that installer choice. If the installer emits `rainskills.next-action.v1`, execute only its fixed `argv` through the same launcher; never evaluate output as a shell command. If the adjacent `bin/rainskills.js` exists, use it for fixed next actions; otherwise use the same versioned npm package fallback described below.
|
|
15
15
|
4. Stay attached until every independent Skill is installed. Do not select, connect, or configure an application runtime during installation. In the user-facing response, output only the fixed completion message below.
|
|
@@ -24,6 +24,8 @@ Skills-only 安装不需要 Node.js;CDN fallback 只负责安装 Skill 文件
|
|
|
24
24
|
|
|
25
25
|
The installer emits this text inside `RAINSKILLS_USER_MESSAGE_BEGIN:install.completed` and the matching END marker, followed by `RAINSKILLS_AGENT_SUMMARY_REQUIRED:include-next-actions`. Relay only the body exactly and print nothing else; do not expose the markers, summarize, reformat, add a source link, or add verification details. If the host still summarizes instead of relaying, its installation summary must retain at least one example from “下一步可以直接说”.
|
|
26
26
|
|
|
27
|
+
For `target=hermes`, the emitted body additionally tells an already-open Hermes session to run `/reset` or start a new session so its cached Skill catalog includes every newly installed `rainbond-*` Skill. Relay that emitted Hermes body exactly; do not replace it with the generic example below.
|
|
28
|
+
|
|
27
29
|
```text
|
|
28
30
|
Rainskills 安装完成,下一条消息即可直接使用。
|
|
29
31
|
|
|
@@ -48,9 +50,11 @@ Rainskills 安装完成,下一条消息即可直接使用。
|
|
|
48
50
|
|
|
49
51
|
Codex 中命令工具一旦返回 `session_id`,必须立即对该 `session_id` 反复调用 `write_stdin`(空输入轮询),直到工具返回 `exit_code`。连接器输出 `[RAINSKILLS_AGENT_WAIT_REQUIRED:runtime-connect]` 后进入上述轮询;看到 `[RAINSKILLS_AGENT_WAIT_COMPLETE:runtime-connect]` 后仍须继续轮询,直到取得退出码和最终 JSON。
|
|
50
52
|
|
|
53
|
+
Hermes Agent 中必须使用 `terminal` 以 `background=true` 启动授权命令;取得 `session_id` 后,只对同一会话按需调用 `process(action="poll")` 获取授权地址,再调用 `process(action="wait")` 等待退出。`wait` 超时时只能继续等待同一 `session_id`;不得把后台启动或浏览器成功页面当作授权完成,也不得另起 `runtime status`。
|
|
54
|
+
|
|
51
55
|
DeepSeek Harness 和 WorkBuddy 也必须保持原命令附着直到退出;如果宿主把长命令转成持久终端或后台任务,只能轮询该原始命令句柄,不得另起 `runtime status` 推测授权结果。WorkBuddy 安装后若当前任务的 Skill 清单尚未刷新,在下一条业务动作前先刷新 Skill 列表或新建任务,不得退回内置 Sites 代替 Rainbond 部署。
|
|
52
56
|
|
|
53
|
-
Rainskills 只保存一个全局运行环境,不维护环境列表、名称、默认值或环境 ID。使用固定 launcher `node <home>/.rainbond/lib/rainskills/bin/rainskills.js`(运行包版本 `rainskills@0.1.
|
|
57
|
+
Rainskills 只保存一个全局运行环境,不维护环境列表、名称、默认值或环境 ID。使用固定 launcher `node <home>/.rainbond/lib/rainskills/bin/rainskills.js`(运行包版本 `rainskills@0.1.34`):
|
|
54
58
|
|
|
55
59
|
- 状态:执行 `runtime status --json`。
|
|
56
60
|
- 首次连接:执行 `runtime connect <target> --saas` 或 `runtime connect <target> --rainbond-url <Console origin>`。
|
|
@@ -58,6 +62,8 @@ Rainskills 只保存一个全局运行环境,不维护环境列表、名称、
|
|
|
58
62
|
- 重新授权:执行 `runtime reconnect <target>`;必须进入浏览器 Device Flow,不复用 Shell 中缓存的 JWT。
|
|
59
63
|
- 更换环境:明确告知用户会替换当前唯一环境;新授权和 live probe 成功后再覆盖凭据。
|
|
60
64
|
|
|
65
|
+
固定 contract 中的 `<target>` 必须替换为当前宿主:Codex=`codex`、Claude Code=`claude`、Pi Agent=`pi`、DeepSeek Harness=`dsh`、WorkBuddy=`workbuddy`、Hermes Agent=`hermes`。
|
|
66
|
+
|
|
61
67
|
所有 Rainbond 查询和变更继续通过 `~/.rainbond/bin/rainskills-tools.js`。不得配置客户端 MCP,也不得恢复环境枚举、业务 operation 生命周期、环境 ID 或 intent 恢复协议。
|
|
62
68
|
|
|
63
69
|
业务 CLI 默认只读取受保护的唯一运行环境文件,忽略 Shell 中遗留的 `RAINBOND_URL` / `RAINBOND_JWT`。CI 若要显式使用环境变量凭据,必须同时设置 `RAINSKILLS_CREDENTIAL_SOURCE=environment`。
|
package/bin/rainskills.js
CHANGED
|
@@ -4,6 +4,7 @@ const path = require("node:path");
|
|
|
4
4
|
const crypto = require("node:crypto");
|
|
5
5
|
const os = require("node:os");
|
|
6
6
|
const { spawn } = require("node:child_process");
|
|
7
|
+
const { pathToFileURL } = require("node:url");
|
|
7
8
|
const {
|
|
8
9
|
detectControlEnvironment,
|
|
9
10
|
} = require("../rainbond-platform-installer/scripts/control-environment.js");
|
|
@@ -275,8 +276,12 @@ async function runBuiltin(args, {
|
|
|
275
276
|
if (args.length !== 3 || args[2] !== "--json") {
|
|
276
277
|
throw new Error("runtime status 只支持固定参数 --json");
|
|
277
278
|
}
|
|
279
|
+
const packageVersion = require("../package.json").version;
|
|
278
280
|
if (runtimeStateManager) {
|
|
279
|
-
write(`${JSON.stringify(
|
|
281
|
+
write(`${JSON.stringify({
|
|
282
|
+
...(await runtimeStateManager.status()),
|
|
283
|
+
package_version: packageVersion,
|
|
284
|
+
})}\n`);
|
|
280
285
|
return true;
|
|
281
286
|
}
|
|
282
287
|
const runtime = getSingleRuntimeStore().read();
|
|
@@ -285,6 +290,7 @@ async function runBuiltin(args, {
|
|
|
285
290
|
schema: "rainskills.runtime-status.v1",
|
|
286
291
|
state: "not_started",
|
|
287
292
|
usable: false,
|
|
293
|
+
package_version: packageVersion,
|
|
288
294
|
})}\n`);
|
|
289
295
|
return true;
|
|
290
296
|
}
|
|
@@ -309,6 +315,7 @@ async function runBuiltin(args, {
|
|
|
309
315
|
usable: true,
|
|
310
316
|
console_origin: runtime.console_origin,
|
|
311
317
|
environment_kind: runtime.kind,
|
|
318
|
+
package_version: packageVersion,
|
|
312
319
|
})}\n`);
|
|
313
320
|
} catch {
|
|
314
321
|
write(`${JSON.stringify({
|
|
@@ -317,6 +324,7 @@ async function runBuiltin(args, {
|
|
|
317
324
|
usable: false,
|
|
318
325
|
console_origin: runtime.console_origin,
|
|
319
326
|
environment_kind: runtime.kind,
|
|
327
|
+
package_version: packageVersion,
|
|
320
328
|
})}\n`);
|
|
321
329
|
}
|
|
322
330
|
return true;
|
|
@@ -574,6 +582,13 @@ function resolveInvocation(args, {
|
|
|
574
582
|
};
|
|
575
583
|
}
|
|
576
584
|
|
|
585
|
+
if (args[0] === "package-upload") {
|
|
586
|
+
return {
|
|
587
|
+
executable: execPath,
|
|
588
|
+
args: [path.resolve(__dirname, "rainskills-tools.js"), ...args],
|
|
589
|
+
};
|
|
590
|
+
}
|
|
591
|
+
|
|
577
592
|
if (args[0] === "platform" && args[1] === "install") {
|
|
578
593
|
return {
|
|
579
594
|
executable: execPath,
|
|
@@ -608,6 +623,12 @@ function resolveInvocation(args, {
|
|
|
608
623
|
};
|
|
609
624
|
}
|
|
610
625
|
|
|
626
|
+
async function installLocalCliFromPackage({ sourceRoot, home }) {
|
|
627
|
+
const installerPath = path.join(sourceRoot, "scripts", "install-local-cli.mjs");
|
|
628
|
+
const { installLocalCli } = await import(pathToFileURL(installerPath).href);
|
|
629
|
+
return installLocalCli({ source_root: sourceRoot, home });
|
|
630
|
+
}
|
|
631
|
+
|
|
611
632
|
async function runAutoUpdatePhase(args, {
|
|
612
633
|
currentVersion = require("../package.json").version,
|
|
613
634
|
env = process.env,
|
|
@@ -616,6 +637,7 @@ async function runAutoUpdatePhase(args, {
|
|
|
616
637
|
packageRoot = path.resolve(__dirname, ".."),
|
|
617
638
|
checkForUpdate,
|
|
618
639
|
acquireArtifact,
|
|
640
|
+
installCli,
|
|
619
641
|
synchronizeSkills,
|
|
620
642
|
updateState,
|
|
621
643
|
delegate,
|
|
@@ -643,6 +665,10 @@ async function runAutoUpdatePhase(args, {
|
|
|
643
665
|
if (detectActive()) {
|
|
644
666
|
throw new Error("存在正在执行的 Rainskills 操作");
|
|
645
667
|
}
|
|
668
|
+
await (installCli || installLocalCliFromPackage)({
|
|
669
|
+
sourceRoot: packageRoot,
|
|
670
|
+
home,
|
|
671
|
+
});
|
|
646
672
|
(synchronizeSkills || autoUpdate.synchronizeInstalledSkills)({
|
|
647
673
|
packageRoot,
|
|
648
674
|
home,
|
package/install.sh
CHANGED
|
@@ -210,6 +210,7 @@ Usage:
|
|
|
210
210
|
./install.sh pi
|
|
211
211
|
./install.sh dsh
|
|
212
212
|
./install.sh workbuddy
|
|
213
|
+
./install.sh hermes
|
|
213
214
|
./install.sh all
|
|
214
215
|
./install.sh --dest <path>
|
|
215
216
|
./install.sh all --saas
|
|
@@ -223,6 +224,7 @@ Options:
|
|
|
223
224
|
pi Install and configure Pi Agent
|
|
224
225
|
dsh Install and configure DeepSeek Harness
|
|
225
226
|
workbuddy Install and configure WorkBuddy
|
|
227
|
+
hermes Install and configure Hermes Agent
|
|
226
228
|
all Install and configure all supported agents
|
|
227
229
|
refresh Re-run browser login and refresh the protected CLI credential
|
|
228
230
|
--dest PATH Install skills to a custom directory only
|
|
@@ -249,6 +251,7 @@ Environment:
|
|
|
249
251
|
RAINSKILLS_NO_BROWSER Set to 1 to print the authorization URL without opening it
|
|
250
252
|
DSH_HOME DeepSeek Harness home (default: ~/.dsh)
|
|
251
253
|
WORKBUDDY_CONFIG_DIR WorkBuddy config home (default: ~/.workbuddy-ai)
|
|
254
|
+
HERMES_HOME Hermes Agent home (default: ~/.hermes)
|
|
252
255
|
EOF
|
|
253
256
|
}
|
|
254
257
|
|
|
@@ -267,6 +270,23 @@ warn() {
|
|
|
267
270
|
|
|
268
271
|
print_capability_summary() {
|
|
269
272
|
printf '[RAINSKILLS_USER_MESSAGE_BEGIN:install.completed]\n'
|
|
273
|
+
if [[ "$TARGET" == "hermes" ]]; then
|
|
274
|
+
cat <<'EOF'
|
|
275
|
+
Rainskills 安装完成。
|
|
276
|
+
|
|
277
|
+
如果安装发生在已经打开的 Hermes 会话中,请执行 /reset,或新建会话后再使用。
|
|
278
|
+
|
|
279
|
+
下一步可以直接说:
|
|
280
|
+
|
|
281
|
+
- 帮我部署当前项目
|
|
282
|
+
- 帮我部署一个 Git 仓库
|
|
283
|
+
- 帮我通过镜像或安装包部署应用
|
|
284
|
+
- 帮我安装一个应用模板
|
|
285
|
+
- 帮我分析当前项目应该如何部署
|
|
286
|
+
|
|
287
|
+
也可以直接告诉我你想部署什么应用。
|
|
288
|
+
EOF
|
|
289
|
+
else
|
|
270
290
|
cat <<'EOF'
|
|
271
291
|
Rainskills 安装完成,下一条消息即可直接使用。
|
|
272
292
|
|
|
@@ -280,6 +300,7 @@ Rainskills 安装完成,下一条消息即可直接使用。
|
|
|
280
300
|
|
|
281
301
|
也可以直接告诉我你想部署什么应用。
|
|
282
302
|
EOF
|
|
303
|
+
fi
|
|
283
304
|
printf '[RAINSKILLS_USER_MESSAGE_END:install.completed]\n'
|
|
284
305
|
printf '[RAINSKILLS_AGENT_SUMMARY_REQUIRED:include-next-actions]\n'
|
|
285
306
|
}
|
|
@@ -367,6 +388,7 @@ rainskills_v2_agent() {
|
|
|
367
388
|
pi) printf 'pi\n' ;;
|
|
368
389
|
dsh|deepseek_harness|deepseek) printf 'deepseek\n' ;;
|
|
369
390
|
workbuddy) printf 'workbuddy\n' ;;
|
|
391
|
+
hermes|hermes_agent|hermes-agent) printf 'hermes_agent\n' ;;
|
|
370
392
|
other) printf 'other\n' ;;
|
|
371
393
|
*) printf 'unknown\n' ;;
|
|
372
394
|
esac
|
|
@@ -582,6 +604,9 @@ rainskills_install_client_for_target() {
|
|
|
582
604
|
workbuddy)
|
|
583
605
|
printf 'workbuddy\n'
|
|
584
606
|
;;
|
|
607
|
+
hermes)
|
|
608
|
+
printf 'hermes_agent\n'
|
|
609
|
+
;;
|
|
585
610
|
all)
|
|
586
611
|
printf 'all\n'
|
|
587
612
|
;;
|
|
@@ -747,7 +772,7 @@ event = {
|
|
|
747
772
|
"platform": platform,
|
|
748
773
|
"control_mode": control_mode,
|
|
749
774
|
"target": target,
|
|
750
|
-
"client": client if client in {"codex", "claude_code", "pi", "deepseek_harness", "workbuddy", "all", "both", "unknown"} else "unknown",
|
|
775
|
+
"client": client if client in {"codex", "claude_code", "pi", "deepseek_harness", "workbuddy", "hermes_agent", "all", "both", "unknown"} else "unknown",
|
|
751
776
|
"eid": eid or None,
|
|
752
777
|
"phase": None,
|
|
753
778
|
"lifecycle_phase": phase,
|
|
@@ -804,7 +829,7 @@ initialize_rainskills_installation_reporting() {
|
|
|
804
829
|
connect)
|
|
805
830
|
RAINSKILLS_INSTALL_ACTION="connect"
|
|
806
831
|
;;
|
|
807
|
-
codex|claude|pi|dsh|workbuddy|all)
|
|
832
|
+
codex|claude|pi|dsh|workbuddy|hermes|all)
|
|
808
833
|
target="$arg"
|
|
809
834
|
;;
|
|
810
835
|
esac
|
|
@@ -1083,6 +1108,11 @@ validate_skill_dir() {
|
|
|
1083
1108
|
|
|
1084
1109
|
install_local_cli() {
|
|
1085
1110
|
command -v node >/dev/null 2>&1 || return 0
|
|
1111
|
+
local node_version node_major
|
|
1112
|
+
node_version="$(node --version 2>/dev/null)" || return 0
|
|
1113
|
+
node_major="${node_version#v}"
|
|
1114
|
+
node_major="${node_major%%.*}"
|
|
1115
|
+
[[ "$node_major" =~ ^[0-9]+$ && "$node_major" -ge 18 ]] || return 0
|
|
1086
1116
|
local installer="$SCRIPT_DIR/scripts/install-local-cli.mjs"
|
|
1087
1117
|
[[ -f "$installer" ]] || die "Rainskills 本地 CLI 安装器缺失。"
|
|
1088
1118
|
node "$installer" --source-root "$SCRIPT_DIR" --home "$HOME" >/dev/null \
|
|
@@ -1139,12 +1169,12 @@ parse_args() {
|
|
|
1139
1169
|
ACTION="connect"
|
|
1140
1170
|
shift
|
|
1141
1171
|
;;
|
|
1142
|
-
claude|codex|pi|dsh|workbuddy|all)
|
|
1172
|
+
claude|codex|pi|dsh|workbuddy|hermes|all)
|
|
1143
1173
|
TARGET="$1"
|
|
1144
1174
|
shift
|
|
1145
1175
|
;;
|
|
1146
1176
|
openclaw)
|
|
1147
|
-
die "macOS/Linux 安装器不再支持 OpenClaw,请使用 Codex、Claude Code、Pi Agent、DeepSeek Harness 或
|
|
1177
|
+
die "macOS/Linux 安装器不再支持 OpenClaw,请使用 Codex、Claude Code、Pi Agent、DeepSeek Harness、WorkBuddy 或 Hermes Agent。"
|
|
1148
1178
|
;;
|
|
1149
1179
|
--dest)
|
|
1150
1180
|
[[ $# -ge 2 ]] || die "--dest 需要一个路径值"
|
|
@@ -1232,7 +1262,7 @@ assert_internal_connect_entry() {
|
|
|
1232
1262
|
local target="" environment_kind="" console_origin="" mode=""
|
|
1233
1263
|
while [[ $# -gt 0 ]]; do
|
|
1234
1264
|
case "$1" in
|
|
1235
|
-
codex|claude|pi|dsh|workbuddy|all)
|
|
1265
|
+
codex|claude|pi|dsh|workbuddy|hermes|all)
|
|
1236
1266
|
[[ -z "$target" ]] || return 1
|
|
1237
1267
|
target="$1"
|
|
1238
1268
|
shift
|
|
@@ -1329,6 +1359,11 @@ resolve_target() {
|
|
|
1329
1359
|
return 0
|
|
1330
1360
|
fi
|
|
1331
1361
|
|
|
1362
|
+
if [[ "${AI_AGENT:-}" == "hermes-agent" || "${HERMES_AGENT:-}" == "true" ]]; then
|
|
1363
|
+
TARGET="hermes"
|
|
1364
|
+
return 0
|
|
1365
|
+
fi
|
|
1366
|
+
|
|
1332
1367
|
if [[ "$NON_INTERACTIVE" -eq 1 || ! -t 0 ]]; then
|
|
1333
1368
|
TARGET="$DEFAULT_TARGET"
|
|
1334
1369
|
return 0
|
|
@@ -1340,10 +1375,11 @@ resolve_target() {
|
|
|
1340
1375
|
log " 3) Pi Agent"
|
|
1341
1376
|
log " 4) DeepSeek Harness"
|
|
1342
1377
|
log " 5) WorkBuddy"
|
|
1343
|
-
log " 6)
|
|
1378
|
+
log " 6) Hermes Agent"
|
|
1379
|
+
log " 7) 全部"
|
|
1344
1380
|
|
|
1345
1381
|
while true; do
|
|
1346
|
-
printf '请输入选项 [1-
|
|
1382
|
+
printf '请输入选项 [1-7]: '
|
|
1347
1383
|
read -r choice
|
|
1348
1384
|
case "$choice" in
|
|
1349
1385
|
1)
|
|
@@ -1366,12 +1402,16 @@ resolve_target() {
|
|
|
1366
1402
|
TARGET="workbuddy"
|
|
1367
1403
|
return 0
|
|
1368
1404
|
;;
|
|
1369
|
-
6
|
|
1405
|
+
6)
|
|
1406
|
+
TARGET="hermes"
|
|
1407
|
+
return 0
|
|
1408
|
+
;;
|
|
1409
|
+
7|"")
|
|
1370
1410
|
TARGET="all"
|
|
1371
1411
|
return 0
|
|
1372
1412
|
;;
|
|
1373
1413
|
*)
|
|
1374
|
-
log "请输入 1、2、3、4、5 或
|
|
1414
|
+
log "请输入 1、2、3、4、5、6 或 7。"
|
|
1375
1415
|
;;
|
|
1376
1416
|
esac
|
|
1377
1417
|
done
|
|
@@ -1399,12 +1439,16 @@ collect_destinations() {
|
|
|
1399
1439
|
workbuddy)
|
|
1400
1440
|
destinations+=("${WORKBUDDY_CONFIG_DIR:-$HOME/.workbuddy-ai}/skills")
|
|
1401
1441
|
;;
|
|
1442
|
+
hermes)
|
|
1443
|
+
destinations+=("${HERMES_HOME:-$HOME/.hermes}/skills")
|
|
1444
|
+
;;
|
|
1402
1445
|
all)
|
|
1403
1446
|
destinations+=("$HOME/.claude/skills")
|
|
1404
1447
|
destinations+=("$HOME/.codex/skills")
|
|
1405
1448
|
destinations+=("$HOME/.pi/agent/skills")
|
|
1406
1449
|
destinations+=("${DSH_HOME:-$HOME/.dsh}/skills")
|
|
1407
1450
|
destinations+=("${WORKBUDDY_CONFIG_DIR:-$HOME/.workbuddy-ai}/skills")
|
|
1451
|
+
destinations+=("${HERMES_HOME:-$HOME/.hermes}/skills")
|
|
1408
1452
|
;;
|
|
1409
1453
|
*)
|
|
1410
1454
|
die "未知安装目标:$TARGET"
|
|
@@ -1426,8 +1470,9 @@ collect_target_agents() {
|
|
|
1426
1470
|
pi) printf 'pi\n' ;;
|
|
1427
1471
|
dsh) printf 'dsh\n' ;;
|
|
1428
1472
|
workbuddy) printf 'workbuddy\n' ;;
|
|
1473
|
+
hermes) printf 'hermes\n' ;;
|
|
1429
1474
|
all)
|
|
1430
|
-
printf '%s\n' claude codex pi dsh workbuddy
|
|
1475
|
+
printf '%s\n' claude codex pi dsh workbuddy hermes
|
|
1431
1476
|
;;
|
|
1432
1477
|
*) printf 'unknown\n' ;;
|
|
1433
1478
|
esac
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rainskills",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.34",
|
|
4
4
|
"description": "Install the complete Rainskills AI deployment skill suite as one product.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Goodrain",
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
"claude-code",
|
|
16
16
|
"deepseek-harness",
|
|
17
17
|
"workbuddy",
|
|
18
|
+
"hermes-agent",
|
|
18
19
|
"skills",
|
|
19
20
|
"installer"
|
|
20
21
|
]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rainskills",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.34",
|
|
4
4
|
"description": "Install the complete Rainskills AI deployment skill suite as one product.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Goodrain",
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
"claude-code",
|
|
16
16
|
"deepseek-harness",
|
|
17
17
|
"workbuddy",
|
|
18
|
+
"hermes-agent",
|
|
18
19
|
"skills",
|
|
19
20
|
"installer"
|
|
20
21
|
],
|
|
@@ -9,12 +9,12 @@ This is the single marketplace entry for the complete Rainskills product. The in
|
|
|
9
9
|
|
|
10
10
|
## Initialize
|
|
11
11
|
|
|
12
|
-
1. Detect the current host client and map it to exactly one supported installer target: Codex=`codex`, Claude Code=`claude`, Pi Agent=`pi`, DeepSeek Harness=`dsh`, or
|
|
12
|
+
1. Detect the current host client and map it to exactly one supported installer target: Codex=`codex`, Claude Code=`claude`, Pi Agent=`pi`, DeepSeek Harness=`dsh`, WorkBuddy=`workbuddy`, or Hermes Agent=`hermes`. All six use the same CLI profile, installed Skills, and protected local Rainskills CLI; none requires a separate client MCP adapter. DeepSeek Harness installs to `$DSH_HOME/skills` (default `~/.dsh/skills`). WorkBuddy installs to `$WORKBUDDY_CONFIG_DIR/skills` (default `~/.workbuddy-ai/skills`). Hermes Agent installs to `$HERMES_HOME/skills` (default `~/.hermes/skills`); `AI_AGENT=hermes-agent` or `HERMES_AGENT=true` is a reliable fallback when the host must be detected from a terminal subprocess. The macOS, Linux, and WSL installer intentionally does not support OpenClaw; report that limitation instead of invoking an unsupported target. Do not ask the user which supported client they are currently using. If the host cannot be determined reliably, omit the target and let the installer ask.
|
|
13
13
|
2. Resolve the directory containing this `SKILL.md`. On native Windows, if the adjacent `bin/rainskills.js` exists, run it by absolute path with the detected target in an attached interactive terminal: `node <skill-directory>/bin/rainskills.js <target>`. On macOS, Linux, or WSL, if the adjacent `install.sh` exists, run `bash <skill-directory>/install.sh <target>` the same way. Do not replace the installer with manual file copies.
|
|
14
14
|
3. Keep stdin, stdout, and stderr attached. When `RAINSKILLS_USER_INPUT_REQUIRED` appears, pause for that installer choice. If the installer emits `rainskills.next-action.v1`, execute only its fixed `argv` through the same launcher; never evaluate output as a shell command. If the adjacent `bin/rainskills.js` exists, use it for fixed next actions; otherwise use the same versioned npm package fallback described below.
|
|
15
15
|
4. Stay attached until every independent Skill is installed. Do not select, connect, or configure an application runtime during installation. In the user-facing response, output only the fixed completion message below.
|
|
16
16
|
|
|
17
|
-
If the adjacent installer is missing, check the local Node.js version before choosing the fallback. With `npx` and Node.js 18 or newer, use `npx --yes rainskills@0.1.
|
|
17
|
+
If the adjacent installer is missing, check the local Node.js version before choosing the fallback. With `npx` and Node.js 18 or newer, use `npx --yes rainskills@0.1.34 <target>`. With no Node.js or a version below 18, use `bash <(curl -fsSL https://get.rainbond.com/rainskills/install.sh) <target>` instead. Omit `<target>` only when the host cannot be determined reliably. Keep either command attached to the interactive terminal. For an update or repair, refresh this marketplace Skill first, then run the installer again; it compares and updates every independent internal Skill.
|
|
18
18
|
|
|
19
19
|
Skills-only 安装不需要 Node.js;CDN fallback 只负责安装 Skill 文件,不代表运行环境连接、应用部署或平台安装已经可执行。用户首次提出需要运行环境的动作时,对应业务 Skill 才检查 Node.js;固定 Rainskills launcher 需要 Node.js 18 或更高版本。缺失或版本过低时保留原始 intent 并停止,等待用户或 agent 明确同意安装或升级 Node.js,安装完成消息不得提前提示 Node.js。
|
|
20
20
|
|
|
@@ -24,6 +24,8 @@ Skills-only 安装不需要 Node.js;CDN fallback 只负责安装 Skill 文件
|
|
|
24
24
|
|
|
25
25
|
The installer emits this text inside `RAINSKILLS_USER_MESSAGE_BEGIN:install.completed` and the matching END marker, followed by `RAINSKILLS_AGENT_SUMMARY_REQUIRED:include-next-actions`. Relay only the body exactly and print nothing else; do not expose the markers, summarize, reformat, add a source link, or add verification details. If the host still summarizes instead of relaying, its installation summary must retain at least one example from “下一步可以直接说”.
|
|
26
26
|
|
|
27
|
+
For `target=hermes`, the emitted body additionally tells an already-open Hermes session to run `/reset` or start a new session so its cached Skill catalog includes every newly installed `rainbond-*` Skill. Relay that emitted Hermes body exactly; do not replace it with the generic example below.
|
|
28
|
+
|
|
27
29
|
```text
|
|
28
30
|
Rainskills 安装完成,下一条消息即可直接使用。
|
|
29
31
|
|
|
@@ -48,9 +50,11 @@ Rainskills 安装完成,下一条消息即可直接使用。
|
|
|
48
50
|
|
|
49
51
|
Codex 中命令工具一旦返回 `session_id`,必须立即对该 `session_id` 反复调用 `write_stdin`(空输入轮询),直到工具返回 `exit_code`。连接器输出 `[RAINSKILLS_AGENT_WAIT_REQUIRED:runtime-connect]` 后进入上述轮询;看到 `[RAINSKILLS_AGENT_WAIT_COMPLETE:runtime-connect]` 后仍须继续轮询,直到取得退出码和最终 JSON。
|
|
50
52
|
|
|
53
|
+
Hermes Agent 中必须使用 `terminal` 以 `background=true` 启动授权命令;取得 `session_id` 后,只对同一会话按需调用 `process(action="poll")` 获取授权地址,再调用 `process(action="wait")` 等待退出。`wait` 超时时只能继续等待同一 `session_id`;不得把后台启动或浏览器成功页面当作授权完成,也不得另起 `runtime status`。
|
|
54
|
+
|
|
51
55
|
DeepSeek Harness 和 WorkBuddy 也必须保持原命令附着直到退出;如果宿主把长命令转成持久终端或后台任务,只能轮询该原始命令句柄,不得另起 `runtime status` 推测授权结果。WorkBuddy 安装后若当前任务的 Skill 清单尚未刷新,在下一条业务动作前先刷新 Skill 列表或新建任务,不得退回内置 Sites 代替 Rainbond 部署。
|
|
52
56
|
|
|
53
|
-
Rainskills 只保存一个全局运行环境,不维护环境列表、名称、默认值或环境 ID。使用固定 launcher `node <home>/.rainbond/lib/rainskills/bin/rainskills.js`(运行包版本 `rainskills@0.1.
|
|
57
|
+
Rainskills 只保存一个全局运行环境,不维护环境列表、名称、默认值或环境 ID。使用固定 launcher `node <home>/.rainbond/lib/rainskills/bin/rainskills.js`(运行包版本 `rainskills@0.1.34`):
|
|
54
58
|
|
|
55
59
|
- 状态:执行 `runtime status --json`。
|
|
56
60
|
- 首次连接:执行 `runtime connect <target> --saas` 或 `runtime connect <target> --rainbond-url <Console origin>`。
|
|
@@ -58,6 +62,8 @@ Rainskills 只保存一个全局运行环境,不维护环境列表、名称、
|
|
|
58
62
|
- 重新授权:执行 `runtime reconnect <target>`;必须进入浏览器 Device Flow,不复用 Shell 中缓存的 JWT。
|
|
59
63
|
- 更换环境:明确告知用户会替换当前唯一环境;新授权和 live probe 成功后再覆盖凭据。
|
|
60
64
|
|
|
65
|
+
固定 contract 中的 `<target>` 必须替换为当前宿主:Codex=`codex`、Claude Code=`claude`、Pi Agent=`pi`、DeepSeek Harness=`dsh`、WorkBuddy=`workbuddy`、Hermes Agent=`hermes`。
|
|
66
|
+
|
|
61
67
|
所有 Rainbond 查询和变更继续通过 `~/.rainbond/bin/rainskills-tools.js`。不得配置客户端 MCP,也不得恢复环境枚举、业务 operation 生命周期、环境 ID 或 intent 恢复协议。
|
|
62
68
|
|
|
63
69
|
业务 CLI 默认只读取受保护的唯一运行环境文件,忽略 Shell 中遗留的 `RAINBOND_URL` / `RAINBOND_JWT`。CI 若要显式使用环境变量凭据,必须同时设置 `RAINSKILLS_CREDENTIAL_SOURCE=environment`。
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rainskills",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "Interactive Rainbond skill installer for Codex, Claude Code, Pi Agent, DeepSeek Harness, and
|
|
3
|
+
"version": "0.1.34",
|
|
4
|
+
"description": "Interactive Rainbond skill installer for Codex, Claude Code, Pi Agent, DeepSeek Harness, WorkBuddy, and Hermes Agent",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://github.com/goodrain/rainskills#readme",
|
|
7
7
|
"bugs": {
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
"claude-code",
|
|
18
18
|
"deepseek-harness",
|
|
19
19
|
"workbuddy",
|
|
20
|
+
"hermes-agent",
|
|
20
21
|
"skills",
|
|
21
22
|
"installer"
|
|
22
23
|
],
|
|
@@ -5,7 +5,7 @@ Canonical progressive-loading contract: `rainskills.skill-runtime-contract.v1`.
|
|
|
5
5
|
<!-- rainskills-runtime-gate:start -->
|
|
6
6
|
## 单运行环境 CLI 门禁(最高优先级)
|
|
7
7
|
|
|
8
|
-
本机只允许连接一个 Rainbond 运行环境。当前 Skill 在本会话第一次调用 Rainbond 前,执行固定 launcher 的 `runtime status --json`。返回 `connected` 且 `usable=true`
|
|
8
|
+
本机只允许连接一个 Rainbond 运行环境。当前 Skill 在本会话第一次调用 Rainbond 前,执行固定 launcher 的 `runtime status --json`。返回 `connected` 且 `usable=true`,并且 `package_version` 与本 Skill JSON contract 的 `package_version` 完全一致后,所有查询和变更才可通过本地 `~/.rainbond/bin/rainskills-tools.js` 执行。缺少或不一致时必须先执行当前固定版本 `rainskills@0.1.34` 的更新/修复流程并重新取得一致状态;不得在版本错配时继续业务调用。不得配置或直接调用客户端 MCP,不得执行环境枚举或业务 operation 生命周期命令,也不得生成或传递运行环境 ID、业务 operation ID 或 intent JSON。
|
|
9
9
|
|
|
10
10
|
没有运行环境时,让用户选择 Rainbond Cloud 或一个已有/新建的私有 Rainbond,并执行对应的 `runtime connect`。连接和重新授权必须进入浏览器 Device Flow,不复用 Shell 中缓存的 JWT;新凭据通过 live probe 后才覆盖唯一运行环境。CLI 返回 401 时,只读调用可在 `runtime reconnect` 成功后重试一次;写调用不得自动重放,必须先查询平台真实状态。403 直接停止,不重新授权。
|
|
11
11
|
|
|
@@ -13,7 +13,11 @@ Canonical progressive-loading contract: `rainskills.skill-runtime-contract.v1`.
|
|
|
13
13
|
|
|
14
14
|
Codex 中命令工具一旦返回 `session_id`,必须立即对该 `session_id` 反复调用 `write_stdin`(空输入轮询),直到工具返回 `exit_code`。连接器输出 `[RAINSKILLS_AGENT_WAIT_REQUIRED:runtime-connect]` 后进入上述轮询;看到 `[RAINSKILLS_AGENT_WAIT_COMPLETE:runtime-connect]` 后仍须继续轮询,直到取得退出码和最终 JSON。
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
Hermes Agent 中必须使用 `terminal` 以 `background=true` 启动授权命令;取得 `session_id` 后,只对同一会话按需调用 `process(action="poll")` 获取授权地址,再调用 `process(action="wait")` 等待退出。`wait` 超时时只能继续等待同一 `session_id`;不得把后台启动或浏览器成功页面当作授权完成,也不得另起 `runtime status`。
|
|
17
|
+
|
|
18
|
+
Hermes Agent 执行带 `--input -` 的一次性业务命令时,使用 `terminal` 前台执行,并用单引号 heredoc 将完整 JSON 只写入 stdin;不得用 `echo`、把 JSON 放入 argv、合并 stderr 或把该短命令后台化。
|
|
19
|
+
|
|
20
|
+
固定 contract 中的 `<target>` 必须替换为当前宿主:Codex=`codex`、Claude Code=`claude`、Pi Agent=`pi`、DeepSeek Harness=`dsh`、WorkBuddy=`workbuddy`、Hermes Agent=`hermes`。DeepSeek Harness 和 WorkBuddy 若返回持久终端或后台任务句柄,只轮询该原始句柄直到进程退出,不另起状态命令推测完成。
|
|
17
21
|
|
|
18
22
|
`context resolve` 是无状态调用:单一工作空间直接返回上下文,多个候选返回组合选项;其中 `team_id` 是后续平台调用的内部参数,不得复制到用户可见的过程消息或最终结果中。用户选择后由当前任务直接携带 team/region 参数,不执行 `context select`,不写本地 operation。所有可变 `call` 仍需先取得 confirmation ID,再以完全相同的输入追加 `--confirm` 执行一次。
|
|
19
23
|
|
|
@@ -22,7 +26,7 @@ Codex 中命令工具一旦返回 `session_id`,必须立即对该 `session_id`
|
|
|
22
26
|
```json
|
|
23
27
|
{
|
|
24
28
|
"schema": "rainskills.single-runtime-contract.v1",
|
|
25
|
-
"package_version": "rainskills@0.1.
|
|
29
|
+
"package_version": "rainskills@0.1.34",
|
|
26
30
|
"runtime_status": [
|
|
27
31
|
"node",
|
|
28
32
|
"<home>/.rainbond/lib/rainskills/bin/rainskills.js",
|
|
@@ -25,7 +25,11 @@ description: "Use when a user explicitly asks for an existing Rainbond app versi
|
|
|
25
25
|
|
|
26
26
|
Codex 中命令工具一旦返回 `session_id`,必须立即对该 `session_id` 反复调用 `write_stdin`(空输入轮询),直到工具返回 `exit_code`。连接器输出 `[RAINSKILLS_AGENT_WAIT_REQUIRED:runtime-connect]` 后进入上述轮询;看到 `[RAINSKILLS_AGENT_WAIT_COMPLETE:runtime-connect]` 后仍须继续轮询,直到取得退出码和最终 JSON。
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
Hermes Agent 中必须使用 `terminal` 以 `background=true` 启动授权命令;取得 `session_id` 后,只对同一会话按需调用 `process(action="poll")` 获取授权地址,再调用 `process(action="wait")` 等待退出。`wait` 超时时只能继续等待同一 `session_id`;不得把后台启动或浏览器成功页面当作授权完成,也不得另起 `runtime status`。
|
|
29
|
+
|
|
30
|
+
Hermes Agent 执行带 `--input -` 的一次性业务命令时,使用 `terminal` 前台执行,并用单引号 heredoc 将完整 JSON 只写入 stdin;不得用 `echo`、把 JSON 放入 argv、合并 stderr 或把该短命令后台化。
|
|
31
|
+
|
|
32
|
+
固定 contract 中的 `<target>` 必须替换为当前宿主:Codex=`codex`、Claude Code=`claude`、Pi Agent=`pi`、DeepSeek Harness=`dsh`、WorkBuddy=`workbuddy`、Hermes Agent=`hermes`。DeepSeek Harness 和 WorkBuddy 若返回持久终端或后台任务句柄,只轮询该原始句柄直到进程退出,不另起状态命令推测完成。
|
|
29
33
|
|
|
30
34
|
`context resolve` 是无状态调用:单一工作空间直接返回上下文,多个候选返回组合选项;用户选择后由当前任务直接携带 team/region 参数,不执行 `context select`,不写本地 operation。所有可变 `call` 仍需先取得 confirmation ID,再以完全相同的输入追加 `--confirm` 执行一次。
|
|
31
35
|
|
|
@@ -34,7 +38,7 @@ Codex 中命令工具一旦返回 `session_id`,必须立即对该 `session_id`
|
|
|
34
38
|
```json
|
|
35
39
|
{
|
|
36
40
|
"schema": "rainskills.single-runtime-contract.v1",
|
|
37
|
-
"package_version": "rainskills@0.1.
|
|
41
|
+
"package_version": "rainskills@0.1.34",
|
|
38
42
|
"runtime_status": [
|
|
39
43
|
"node",
|
|
40
44
|
"<home>/.rainbond/lib/rainskills/bin/rainskills.js",
|
|
@@ -48,7 +48,11 @@ description: "Use only when the user explicitly asks for final delivery or acces
|
|
|
48
48
|
|
|
49
49
|
Codex 中命令工具一旦返回 `session_id`,必须立即对该 `session_id` 反复调用 `write_stdin`(空输入轮询),直到工具返回 `exit_code`。连接器输出 `[RAINSKILLS_AGENT_WAIT_REQUIRED:runtime-connect]` 后进入上述轮询;看到 `[RAINSKILLS_AGENT_WAIT_COMPLETE:runtime-connect]` 后仍须继续轮询,直到取得退出码和最终 JSON。
|
|
50
50
|
|
|
51
|
-
|
|
51
|
+
Hermes Agent 中必须使用 `terminal` 以 `background=true` 启动授权命令;取得 `session_id` 后,只对同一会话按需调用 `process(action="poll")` 获取授权地址,再调用 `process(action="wait")` 等待退出。`wait` 超时时只能继续等待同一 `session_id`;不得把后台启动或浏览器成功页面当作授权完成,也不得另起 `runtime status`。
|
|
52
|
+
|
|
53
|
+
Hermes Agent 执行带 `--input -` 的一次性业务命令时,使用 `terminal` 前台执行,并用单引号 heredoc 将完整 JSON 只写入 stdin;不得用 `echo`、把 JSON 放入 argv、合并 stderr 或把该短命令后台化。
|
|
54
|
+
|
|
55
|
+
固定 contract 中的 `<target>` 必须替换为当前宿主:Codex=`codex`、Claude Code=`claude`、Pi Agent=`pi`、DeepSeek Harness=`dsh`、WorkBuddy=`workbuddy`、Hermes Agent=`hermes`。DeepSeek Harness 和 WorkBuddy 若返回持久终端或后台任务句柄,只轮询该原始句柄直到进程退出,不另起状态命令推测完成。
|
|
52
56
|
|
|
53
57
|
`context resolve` 是无状态调用:单一工作空间直接返回上下文,多个候选返回组合选项;用户选择后由当前任务直接携带 team/region 参数,不执行 `context select`,不写本地 operation。所有可变 `call` 仍需先取得 confirmation ID,再以完全相同的输入追加 `--confirm` 执行一次。
|
|
54
58
|
|
|
@@ -57,7 +61,7 @@ Codex 中命令工具一旦返回 `session_id`,必须立即对该 `session_id`
|
|
|
57
61
|
```json
|
|
58
62
|
{
|
|
59
63
|
"schema": "rainskills.single-runtime-contract.v1",
|
|
60
|
-
"package_version": "rainskills@0.1.
|
|
64
|
+
"package_version": "rainskills@0.1.34",
|
|
61
65
|
"runtime_status": [
|
|
62
66
|
"node",
|
|
63
67
|
"<home>/.rainbond/lib/rainskills/bin/rainskills.js",
|
|
@@ -25,7 +25,11 @@ description: "Use when a user explicitly asks to sync non-sensitive preview or p
|
|
|
25
25
|
|
|
26
26
|
Codex 中命令工具一旦返回 `session_id`,必须立即对该 `session_id` 反复调用 `write_stdin`(空输入轮询),直到工具返回 `exit_code`。连接器输出 `[RAINSKILLS_AGENT_WAIT_REQUIRED:runtime-connect]` 后进入上述轮询;看到 `[RAINSKILLS_AGENT_WAIT_COMPLETE:runtime-connect]` 后仍须继续轮询,直到取得退出码和最终 JSON。
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
Hermes Agent 中必须使用 `terminal` 以 `background=true` 启动授权命令;取得 `session_id` 后,只对同一会话按需调用 `process(action="poll")` 获取授权地址,再调用 `process(action="wait")` 等待退出。`wait` 超时时只能继续等待同一 `session_id`;不得把后台启动或浏览器成功页面当作授权完成,也不得另起 `runtime status`。
|
|
29
|
+
|
|
30
|
+
Hermes Agent 执行带 `--input -` 的一次性业务命令时,使用 `terminal` 前台执行,并用单引号 heredoc 将完整 JSON 只写入 stdin;不得用 `echo`、把 JSON 放入 argv、合并 stderr 或把该短命令后台化。
|
|
31
|
+
|
|
32
|
+
固定 contract 中的 `<target>` 必须替换为当前宿主:Codex=`codex`、Claude Code=`claude`、Pi Agent=`pi`、DeepSeek Harness=`dsh`、WorkBuddy=`workbuddy`、Hermes Agent=`hermes`。DeepSeek Harness 和 WorkBuddy 若返回持久终端或后台任务句柄,只轮询该原始句柄直到进程退出,不另起状态命令推测完成。
|
|
29
33
|
|
|
30
34
|
`context resolve` 是无状态调用:单一工作空间直接返回上下文,多个候选返回组合选项;用户选择后由当前任务直接携带 team/region 参数,不执行 `context select`,不写本地 operation。所有可变 `call` 仍需先取得 confirmation ID,再以完全相同的输入追加 `--confirm` 执行一次。
|
|
31
35
|
|
|
@@ -34,7 +38,7 @@ Codex 中命令工具一旦返回 `session_id`,必须立即对该 `session_id`
|
|
|
34
38
|
```json
|
|
35
39
|
{
|
|
36
40
|
"schema": "rainskills.single-runtime-contract.v1",
|
|
37
|
-
"package_version": "rainskills@0.1.
|
|
41
|
+
"package_version": "rainskills@0.1.34",
|
|
38
42
|
"runtime_status": [
|
|
39
43
|
"node",
|
|
40
44
|
"<home>/.rainbond/lib/rainskills/bin/rainskills.js",
|
|
@@ -17,7 +17,7 @@ description: "Use only when the user explicitly asks to create the Rainbond app
|
|
|
17
17
|
<!-- rainskills-runtime-gate:start -->
|
|
18
18
|
## 单运行环境 CLI 门禁(最高优先级)
|
|
19
19
|
|
|
20
|
-
本机只允许连接一个 Rainbond 运行环境。当前 Skill 在本会话第一次调用 Rainbond 前,执行固定 launcher 的 `runtime status --json`。返回 `connected` 且 `usable=true`
|
|
20
|
+
本机只允许连接一个 Rainbond 运行环境。当前 Skill 在本会话第一次调用 Rainbond 前,执行固定 launcher 的 `runtime status --json`。返回 `connected` 且 `usable=true`,并且 `package_version` 与本 Skill JSON contract 的 `package_version` 完全一致后,所有查询和变更才可通过本地 `~/.rainbond/bin/rainskills-tools.js` 执行。缺少或不一致时必须先执行当前固定版本 `rainskills@0.1.34` 的更新/修复流程并重新取得一致状态;不得在版本错配时继续业务调用。不得配置或直接调用客户端 MCP,不得执行环境枚举或业务 operation 生命周期命令,也不得生成或传递运行环境 ID、业务 operation ID 或 intent JSON。
|
|
21
21
|
|
|
22
22
|
没有运行环境时,让用户选择 Rainbond Cloud 或一个已有/新建的私有 Rainbond,并执行对应的 `runtime connect`。连接和重新授权必须进入浏览器 Device Flow,不复用 Shell 中缓存的 JWT;新凭据通过 live probe 后才覆盖唯一运行环境。CLI 返回 401 时,只读调用可在 `runtime reconnect` 成功后重试一次;写调用不得自动重放,必须先查询平台真实状态。403 直接停止,不重新授权。
|
|
23
23
|
|
|
@@ -25,7 +25,11 @@ description: "Use only when the user explicitly asks to create the Rainbond app
|
|
|
25
25
|
|
|
26
26
|
Codex 中命令工具一旦返回 `session_id`,必须立即对该 `session_id` 反复调用 `write_stdin`(空输入轮询),直到工具返回 `exit_code`。连接器输出 `[RAINSKILLS_AGENT_WAIT_REQUIRED:runtime-connect]` 后进入上述轮询;看到 `[RAINSKILLS_AGENT_WAIT_COMPLETE:runtime-connect]` 后仍须继续轮询,直到取得退出码和最终 JSON。
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
Hermes Agent 中必须使用 `terminal` 以 `background=true` 启动授权命令;取得 `session_id` 后,只对同一会话按需调用 `process(action="poll")` 获取授权地址,再调用 `process(action="wait")` 等待退出。`wait` 超时时只能继续等待同一 `session_id`;不得把后台启动或浏览器成功页面当作授权完成,也不得另起 `runtime status`。
|
|
29
|
+
|
|
30
|
+
Hermes Agent 执行带 `--input -` 的一次性业务命令时,使用 `terminal` 前台执行,并用单引号 heredoc 将完整 JSON 只写入 stdin;不得用 `echo`、把 JSON 放入 argv、合并 stderr 或把该短命令后台化。
|
|
31
|
+
|
|
32
|
+
固定 contract 中的 `<target>` 必须替换为当前宿主:Codex=`codex`、Claude Code=`claude`、Pi Agent=`pi`、DeepSeek Harness=`dsh`、WorkBuddy=`workbuddy`、Hermes Agent=`hermes`。DeepSeek Harness 和 WorkBuddy 若返回持久终端或后台任务句柄,只轮询该原始句柄直到进程退出,不另起状态命令推测完成。
|
|
29
33
|
|
|
30
34
|
`context resolve` 是无状态调用:单一工作空间直接返回上下文,多个候选返回组合选项;用户选择后由当前任务直接携带 team/region 参数,不执行 `context select`,不写本地 operation。所有可变 `call` 仍需先取得 confirmation ID,再以完全相同的输入追加 `--confirm` 执行一次。
|
|
31
35
|
|
|
@@ -34,7 +38,7 @@ Codex 中命令工具一旦返回 `session_id`,必须立即对该 `session_id`
|
|
|
34
38
|
```json
|
|
35
39
|
{
|
|
36
40
|
"schema": "rainskills.single-runtime-contract.v1",
|
|
37
|
-
"package_version": "rainskills@0.1.
|
|
41
|
+
"package_version": "rainskills@0.1.34",
|
|
38
42
|
"runtime_status": [
|
|
39
43
|
"node",
|
|
40
44
|
"<home>/.rainbond/lib/rainskills/bin/rainskills.js",
|
|
@@ -130,6 +134,20 @@ Codex 中命令工具一旦返回 `session_id`,必须立即对该 `session_id`
|
|
|
130
134
|
],
|
|
131
135
|
"stdin_schema_source": "tool-catalog"
|
|
132
136
|
},
|
|
137
|
+
"package_upload": {
|
|
138
|
+
"argv": [
|
|
139
|
+
"node",
|
|
140
|
+
"<home>/.rainbond/bin/rainskills-tools.js",
|
|
141
|
+
"package-upload",
|
|
142
|
+
"--archive",
|
|
143
|
+
"<archive-path>",
|
|
144
|
+
"--input",
|
|
145
|
+
"-",
|
|
146
|
+
"--skill-id",
|
|
147
|
+
"rainbond-fullstack-bootstrap"
|
|
148
|
+
],
|
|
149
|
+
"stdin_schema_source": "rainbond_init_package_upload.upload_request"
|
|
150
|
+
},
|
|
133
151
|
"call": {
|
|
134
152
|
"argv": [
|
|
135
153
|
"node",
|
|
@@ -240,7 +240,7 @@ Follow this transaction in the exact order below:
|
|
|
240
240
|
- capture the helper's `archive_path`, `file_name`, `generated`, and `staging_root` result fields
|
|
241
241
|
- a supported package file is reused directly; a directory is converted to a zip archive by the helper
|
|
242
242
|
2. Call `rainbond_init_package_upload` with Rainbond context only. It must return a non-empty `event_id` and an `upload_request`. Do not continue when either is absent or malformed.
|
|
243
|
-
3. Run the
|
|
243
|
+
3. Run the exact `input_commands.package_upload.argv` from the active Skill Runtime Contract, passing the complete `upload_request` object through stdin as JSON. 不得替换为 runtime launcher,也不得省略或改写 argv:
|
|
244
244
|
- the CLI resolves the Console origin from the protected single-runtime store; never ask the user for `RAINBOND_URL` and never take it from the current shell
|
|
245
245
|
- do not add `RAINBOND_URL`, JWT, upload credentials, or a Console address to argv or stdin
|
|
246
246
|
- do not invent or rewrite the URL, authorization mode, form field, HTTP method, content type, or timeout; the CLI validates the same-Console-origin upload contract before invoking the local helper
|
|
@@ -48,7 +48,11 @@ description: "Use only when the user explicitly asks for a bounded build, runtim
|
|
|
48
48
|
|
|
49
49
|
Codex 中命令工具一旦返回 `session_id`,必须立即对该 `session_id` 反复调用 `write_stdin`(空输入轮询),直到工具返回 `exit_code`。连接器输出 `[RAINSKILLS_AGENT_WAIT_REQUIRED:runtime-connect]` 后进入上述轮询;看到 `[RAINSKILLS_AGENT_WAIT_COMPLETE:runtime-connect]` 后仍须继续轮询,直到取得退出码和最终 JSON。
|
|
50
50
|
|
|
51
|
-
|
|
51
|
+
Hermes Agent 中必须使用 `terminal` 以 `background=true` 启动授权命令;取得 `session_id` 后,只对同一会话按需调用 `process(action="poll")` 获取授权地址,再调用 `process(action="wait")` 等待退出。`wait` 超时时只能继续等待同一 `session_id`;不得把后台启动或浏览器成功页面当作授权完成,也不得另起 `runtime status`。
|
|
52
|
+
|
|
53
|
+
Hermes Agent 执行带 `--input -` 的一次性业务命令时,使用 `terminal` 前台执行,并用单引号 heredoc 将完整 JSON 只写入 stdin;不得用 `echo`、把 JSON 放入 argv、合并 stderr 或把该短命令后台化。
|
|
54
|
+
|
|
55
|
+
固定 contract 中的 `<target>` 必须替换为当前宿主:Codex=`codex`、Claude Code=`claude`、Pi Agent=`pi`、DeepSeek Harness=`dsh`、WorkBuddy=`workbuddy`、Hermes Agent=`hermes`。DeepSeek Harness 和 WorkBuddy 若返回持久终端或后台任务句柄,只轮询该原始句柄直到进程退出,不另起状态命令推测完成。
|
|
52
56
|
|
|
53
57
|
`context resolve` 是无状态调用:单一工作空间直接返回上下文,多个候选返回组合选项;用户选择后由当前任务直接携带 team/region 参数,不执行 `context select`,不写本地 operation。所有可变 `call` 仍需先取得 confirmation ID,再以完全相同的输入追加 `--confirm` 执行一次。
|
|
54
58
|
|
|
@@ -57,7 +61,7 @@ Codex 中命令工具一旦返回 `session_id`,必须立即对该 `session_id`
|
|
|
57
61
|
```json
|
|
58
62
|
{
|
|
59
63
|
"schema": "rainskills.single-runtime-contract.v1",
|
|
60
|
-
"package_version": "rainskills@0.1.
|
|
64
|
+
"package_version": "rainskills@0.1.34",
|
|
61
65
|
"runtime_status": [
|
|
62
66
|
"node",
|
|
63
67
|
"<home>/.rainbond/lib/rainskills/bin/rainskills.js",
|
|
@@ -13,7 +13,11 @@ Canonical progressive-loading contract: `rainskills.skill-runtime-contract.v1`.
|
|
|
13
13
|
|
|
14
14
|
Codex 中命令工具一旦返回 `session_id`,必须立即对该 `session_id` 反复调用 `write_stdin`(空输入轮询),直到工具返回 `exit_code`。连接器输出 `[RAINSKILLS_AGENT_WAIT_REQUIRED:runtime-connect]` 后进入上述轮询;看到 `[RAINSKILLS_AGENT_WAIT_COMPLETE:runtime-connect]` 后仍须继续轮询,直到取得退出码和最终 JSON。
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
Hermes Agent 中必须使用 `terminal` 以 `background=true` 启动授权命令;取得 `session_id` 后,只对同一会话按需调用 `process(action="poll")` 获取授权地址,再调用 `process(action="wait")` 等待退出。`wait` 超时时只能继续等待同一 `session_id`;不得把后台启动或浏览器成功页面当作授权完成,也不得另起 `runtime status`。
|
|
17
|
+
|
|
18
|
+
Hermes Agent 执行带 `--input -` 的一次性业务命令时,使用 `terminal` 前台执行,并用单引号 heredoc 将完整 JSON 只写入 stdin;不得用 `echo`、把 JSON 放入 argv、合并 stderr 或把该短命令后台化。
|
|
19
|
+
|
|
20
|
+
固定 contract 中的 `<target>` 必须替换为当前宿主:Codex=`codex`、Claude Code=`claude`、Pi Agent=`pi`、DeepSeek Harness=`dsh`、WorkBuddy=`workbuddy`、Hermes Agent=`hermes`。DeepSeek Harness 和 WorkBuddy 若返回持久终端或后台任务句柄,只轮询该原始句柄直到进程退出,不另起状态命令推测完成。
|
|
17
21
|
|
|
18
22
|
`context resolve` 是无状态调用:单一工作空间直接返回上下文,多个候选返回组合选项;用户选择后由当前任务直接携带 team/region 参数,不执行 `context select`,不写本地 operation。所有可变 `call` 仍需先取得 confirmation ID,再以完全相同的输入追加 `--confirm` 执行一次。
|
|
19
23
|
|
|
@@ -22,7 +26,7 @@ Codex 中命令工具一旦返回 `session_id`,必须立即对该 `session_id`
|
|
|
22
26
|
```json
|
|
23
27
|
{
|
|
24
28
|
"schema": "rainskills.single-runtime-contract.v1",
|
|
25
|
-
"package_version": "rainskills@0.1.
|
|
29
|
+
"package_version": "rainskills@0.1.34",
|
|
26
30
|
"runtime_status": [
|
|
27
31
|
"node",
|
|
28
32
|
"<home>/.rainbond/lib/rainskills/bin/rainskills.js",
|
|
@@ -32,7 +32,7 @@ Do not use it to deploy an application to an existing Rainbond. Route those requ
|
|
|
32
32
|
## Workflow
|
|
33
33
|
|
|
34
34
|
1. Read [installation-policy.md](references/installation-policy.md).
|
|
35
|
-
2. Use the installed local launcher `["node", "<home>/.rainbond/lib/rainskills/bin/rainskills.js"]`; its protected runtime package marker is `rainskills@0.1.
|
|
35
|
+
2. Use the installed local launcher `["node", "<home>/.rainbond/lib/rainskills/bin/rainskills.js"]`; its protected runtime package marker is `rainskills@0.1.34` and must equal this package's `package.json`. For a Rainskills marker, first validate schema `rainskills.next-action.v1`, action, onboarding id, and the bounded `argv` array, then append that array to the launcher. Never use `latest` or evaluate a shell string from output.
|
|
36
36
|
3. 业务 Skill 的四项运行环境菜单会把本机或独立服务器选择写入 `rainskills.next-action.v1` 的显式 `--location`;收到这类 next-action 后直接执行固定 argv,不得再次调用 `private-deployment-location`。只有用户直接要求安装 Rainbond 平台且尚未选择部署位置时,才执行 launcher + `["runtime", "message", "--id", "private-deployment-location"]` 并原样输出固定的三项部署位置消息:选择 1 后执行带 `["--location", "local", "--mode", "single-node"]` 的 `platform install`;选择 2 后执行带 `["--location", "server"]` 的 `platform install`,由 helper 继续显示固定的服务器类型消息;选择 3 后执行 launcher + `["runtime", "message", "--id", "private-console-origin"]` 并进入已有环境连接,不得执行 `platform install`。平台安装 onboarding 只保存安装断点,不保存或恢复业务 intent。
|
|
37
37
|
4. Let the helper perform one read-only preflight against the already selected local or remote target, then show resources, blockers, and applicable host changes. Never invoke `platform install` without an explicit `--location`; the helper must not ask for the deployment location again.
|
|
38
38
|
5. 主机集群开始前必须获得 explicit confirmation,并使用受限 AI 交接:首次调用在固定安装 argv 后追加 `--agent-handoff`,记录该子进程会话;用户确认后,使用相同固定 argv 追加 `--agent-handoff --yes` 一次。不得向等待进程写入 `y`、不得启动第二个竞争安装、不得 `kill` 安装进程,也不得让用户复制完整安装或恢复命令。用户取消时,仅使用同一 argv 追加 `--agent-handoff --cancel`;它只能清除匹配的待确认状态,不能建立 SSH 连接或修改服务器。
|
|
@@ -50,9 +50,10 @@ const DEFAULT_AGENT_ROOTS = Object.freeze([
|
|
|
50
50
|
[".codex", "skills"],
|
|
51
51
|
[".claude", "skills"],
|
|
52
52
|
[".agents", "skills"],
|
|
53
|
+
[".hermes", "skills"],
|
|
53
54
|
]);
|
|
54
55
|
const AUTO_UPDATE_ENVIRONMENT_KEYS = Object.freeze([
|
|
55
|
-
"HOME", "USERPROFILE", "PATH", "Path", "SystemRoot", "ComSpec",
|
|
56
|
+
"HOME", "USERPROFILE", "HERMES_HOME", "PATH", "Path", "SystemRoot", "ComSpec",
|
|
56
57
|
"TMPDIR", "TMP", "TEMP", "LANG", "LC_ALL",
|
|
57
58
|
"HTTP_PROXY", "HTTPS_PROXY", "NO_PROXY", "http_proxy", "https_proxy", "no_proxy",
|
|
58
59
|
]);
|
|
@@ -8,6 +8,7 @@ const HOST_TARGETS = Object.freeze([
|
|
|
8
8
|
"pi",
|
|
9
9
|
"dsh",
|
|
10
10
|
"workbuddy",
|
|
11
|
+
"hermes",
|
|
11
12
|
"all",
|
|
12
13
|
]);
|
|
13
14
|
const HOST_TARGET_SET = new Set(HOST_TARGETS);
|
|
@@ -19,6 +20,7 @@ function isHostTarget(value) {
|
|
|
19
20
|
function telemetryClientForTarget(target) {
|
|
20
21
|
if (target === "claude") return "claude_code";
|
|
21
22
|
if (target === "dsh") return "deepseek_harness";
|
|
23
|
+
if (target === "hermes") return "hermes_agent";
|
|
22
24
|
if (isHostTarget(target)) return target;
|
|
23
25
|
return "unknown";
|
|
24
26
|
}
|
|
@@ -38,6 +40,13 @@ function workBuddySkillsDirectory(home, env = process.env) {
|
|
|
38
40
|
return path.join(path.resolve(configHome), "skills");
|
|
39
41
|
}
|
|
40
42
|
|
|
43
|
+
function hermesSkillsDirectory(home, env = process.env) {
|
|
44
|
+
const hermesHome = typeof env.HERMES_HOME === "string" && env.HERMES_HOME.trim()
|
|
45
|
+
? env.HERMES_HOME.trim()
|
|
46
|
+
: path.join(home, ".hermes");
|
|
47
|
+
return path.join(path.resolve(hermesHome), "skills");
|
|
48
|
+
}
|
|
49
|
+
|
|
41
50
|
function destinationsForHostTarget(target, home, env = process.env) {
|
|
42
51
|
const destinations = {
|
|
43
52
|
claude: path.join(home, ".claude", "skills"),
|
|
@@ -45,6 +54,7 @@ function destinationsForHostTarget(target, home, env = process.env) {
|
|
|
45
54
|
pi: path.join(home, ".pi", "agent", "skills"),
|
|
46
55
|
dsh: dshSkillsDirectory(home, env),
|
|
47
56
|
workbuddy: workBuddySkillsDirectory(home, env),
|
|
57
|
+
hermes: hermesSkillsDirectory(home, env),
|
|
48
58
|
};
|
|
49
59
|
if (target === "all") return Object.values(destinations);
|
|
50
60
|
if (Object.hasOwn(destinations, target)) return [destinations[target]];
|
|
@@ -55,6 +65,7 @@ module.exports = {
|
|
|
55
65
|
HOST_TARGETS,
|
|
56
66
|
destinationsForHostTarget,
|
|
57
67
|
dshSkillsDirectory,
|
|
68
|
+
hermesSkillsDirectory,
|
|
58
69
|
isHostTarget,
|
|
59
70
|
telemetryClientForTarget,
|
|
60
71
|
workBuddySkillsDirectory,
|
|
@@ -8,7 +8,7 @@ const { randomUUID: defaultRandomUUID } = require("node:crypto");
|
|
|
8
8
|
const SCHEMA = "rainskills.telemetry-event.v2";
|
|
9
9
|
const DEFAULT_REPORT_URL = "https://log.rainbond.com/api/rainskills/events";
|
|
10
10
|
const UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
11
|
-
const AGENTS = new Set(["codex", "pi", "claude_code", "deepseek", "workbuddy", "other", "unknown"]);
|
|
11
|
+
const AGENTS = new Set(["codex", "pi", "claude_code", "deepseek", "workbuddy", "hermes_agent", "other", "unknown"]);
|
|
12
12
|
const MAX_PENDING_EVENTS = 100;
|
|
13
13
|
const MAX_PENDING_AGE_MS = 7 * 24 * 60 * 60 * 1000;
|
|
14
14
|
|
|
@@ -62,6 +62,8 @@ function normalizeAgent(value) {
|
|
|
62
62
|
claude: "claude_code",
|
|
63
63
|
dsh: "deepseek",
|
|
64
64
|
deepseek_harness: "deepseek",
|
|
65
|
+
hermes: "hermes_agent",
|
|
66
|
+
"hermes-agent": "hermes_agent",
|
|
65
67
|
};
|
|
66
68
|
const normalized = aliases[value] || value;
|
|
67
69
|
return AGENTS.has(normalized) ? normalized : "unknown";
|
|
@@ -9,7 +9,7 @@ const DEFAULT_REPORT_URL = "https://log.rainbond.com/api/rainskills/lifecycle-ev
|
|
|
9
9
|
const DEFAULT_LEGACY_REPORT_URL = "https://log.rainbond.com/api/rainskills/installations";
|
|
10
10
|
const SCHEMA = "rainskills.lifecycle-event.v1";
|
|
11
11
|
const CLIENTS = new Set([
|
|
12
|
-
"codex", "claude_code", "pi", "deepseek_harness", "workbuddy", "all", "both", "unknown",
|
|
12
|
+
"codex", "claude_code", "pi", "deepseek_harness", "workbuddy", "hermes_agent", "all", "both", "unknown",
|
|
13
13
|
]);
|
|
14
14
|
const PLATFORMS = new Set(["darwin", "linux", "win32"]);
|
|
15
15
|
const CONTROL_MODES = new Set(["posix", "wsl", "windows-native"]);
|
|
@@ -41,6 +41,19 @@ const CAPABILITY_SUMMARY = `Rainskills 安装完成,下一条消息即可直
|
|
|
41
41
|
- 帮我安装一个应用模板
|
|
42
42
|
- 帮我分析当前项目应该如何部署
|
|
43
43
|
|
|
44
|
+
也可以直接告诉我你想部署什么应用。`;
|
|
45
|
+
const HERMES_CAPABILITY_SUMMARY = `Rainskills 安装完成。
|
|
46
|
+
|
|
47
|
+
如果安装发生在已经打开的 Hermes 会话中,请执行 /reset,或新建会话后再使用。
|
|
48
|
+
|
|
49
|
+
下一步可以直接说:
|
|
50
|
+
|
|
51
|
+
- 帮我部署当前项目
|
|
52
|
+
- 帮我部署一个 Git 仓库
|
|
53
|
+
- 帮我通过镜像或安装包部署应用
|
|
54
|
+
- 帮我安装一个应用模板
|
|
55
|
+
- 帮我分析当前项目应该如何部署
|
|
56
|
+
|
|
44
57
|
也可以直接告诉我你想部署什么应用。`;
|
|
45
58
|
const AGENT_SUMMARY_REQUIREMENT = "[RAINSKILLS_AGENT_SUMMARY_REQUIRED:include-next-actions]";
|
|
46
59
|
|
|
@@ -518,17 +531,19 @@ async function promptTarget() {
|
|
|
518
531
|
+ " 3) Pi Agent\n"
|
|
519
532
|
+ " 4) DeepSeek Harness\n"
|
|
520
533
|
+ " 5) WorkBuddy\n"
|
|
521
|
-
+ " 6)
|
|
534
|
+
+ " 6) Hermes Agent\n"
|
|
535
|
+
+ " 7) 全部\n"
|
|
522
536
|
);
|
|
523
537
|
for (;;) {
|
|
524
|
-
const answer = (await terminal.question("请输入选项 [1-
|
|
538
|
+
const answer = (await terminal.question("请输入选项 [1-7]: ")).trim();
|
|
525
539
|
if (answer === "1") return "codex";
|
|
526
540
|
if (answer === "2") return "claude";
|
|
527
541
|
if (answer === "3") return "pi";
|
|
528
542
|
if (answer === "4") return "dsh";
|
|
529
543
|
if (answer === "5") return "workbuddy";
|
|
530
|
-
if (answer === "
|
|
531
|
-
|
|
544
|
+
if (answer === "6") return "hermes";
|
|
545
|
+
if (answer === "" || answer === "7") return "all";
|
|
546
|
+
stdout.write("请输入 1、2、3、4、5、6 或 7。\n");
|
|
532
547
|
}
|
|
533
548
|
} finally {
|
|
534
549
|
terminal.close();
|
|
@@ -601,7 +616,7 @@ async function resolveDeployment(options, {
|
|
|
601
616
|
}
|
|
602
617
|
|
|
603
618
|
function usage() {
|
|
604
|
-
stdout.write("Usage: npx rainskills [codex|claude|pi|dsh|workbuddy|all] [options]\n");
|
|
619
|
+
stdout.write("Usage: npx rainskills [codex|claude|pi|dsh|workbuddy|hermes|all] [options]\n");
|
|
605
620
|
}
|
|
606
621
|
|
|
607
622
|
async function main(argv, dependencies = {}) {
|
|
@@ -613,7 +628,11 @@ async function main(argv, dependencies = {}) {
|
|
|
613
628
|
const home = dependencies.home || os.homedir();
|
|
614
629
|
const environment = dependencies.env || process.env;
|
|
615
630
|
const packageRoot = dependencies.packageRoot || path.resolve(__dirname, "..", "..");
|
|
616
|
-
const
|
|
631
|
+
const detectedTarget = environment.AI_AGENT === "hermes-agent"
|
|
632
|
+
|| environment.HERMES_AGENT === "true"
|
|
633
|
+
? "hermes"
|
|
634
|
+
: "";
|
|
635
|
+
const target = options.target || detectedTarget || (
|
|
617
636
|
options.nonInteractive || !stdin.isTTY
|
|
618
637
|
? "all"
|
|
619
638
|
: await (dependencies.promptTarget || promptTarget)()
|
|
@@ -655,7 +674,7 @@ async function main(argv, dependencies = {}) {
|
|
|
655
674
|
})();
|
|
656
675
|
const targets = options.customDest
|
|
657
676
|
? ["unknown"]
|
|
658
|
-
: (target === "all" ? ["claude", "codex", "pi", "dsh", "workbuddy"] : [target]);
|
|
677
|
+
: (target === "all" ? ["claude", "codex", "pi", "dsh", "workbuddy", "hermes"] : [target]);
|
|
659
678
|
const deliveries = [];
|
|
660
679
|
try {
|
|
661
680
|
const counts = copySkills({
|
|
@@ -700,7 +719,7 @@ async function main(argv, dependencies = {}) {
|
|
|
700
719
|
detailLogger("");
|
|
701
720
|
detailLogger(`安装完成。本次:${counts.installed} 项新装 / ${counts.updated} 项已更新 / ${counts.unchanged} 项已是最新 / ${counts.forced} 项强制覆盖`);
|
|
702
721
|
detailLogger("");
|
|
703
|
-
logger(CAPABILITY_SUMMARY);
|
|
722
|
+
logger(target === "hermes" ? HERMES_CAPABILITY_SUMMARY : CAPABILITY_SUMMARY);
|
|
704
723
|
logger(AGENT_SUMMARY_REQUIREMENT);
|
|
705
724
|
return { status: "skills-installed", counts };
|
|
706
725
|
} catch (error) {
|
|
@@ -16,7 +16,11 @@ description: Use for a user-requested, read-only Rainbond platform query about t
|
|
|
16
16
|
|
|
17
17
|
Codex 中命令工具一旦返回 `session_id`,必须立即对该 `session_id` 反复调用 `write_stdin`(空输入轮询),直到工具返回 `exit_code`。连接器输出 `[RAINSKILLS_AGENT_WAIT_REQUIRED:runtime-connect]` 后进入上述轮询;看到 `[RAINSKILLS_AGENT_WAIT_COMPLETE:runtime-connect]` 后仍须继续轮询,直到取得退出码和最终 JSON。
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
Hermes Agent 中必须使用 `terminal` 以 `background=true` 启动授权命令;取得 `session_id` 后,只对同一会话按需调用 `process(action="poll")` 获取授权地址,再调用 `process(action="wait")` 等待退出。`wait` 超时时只能继续等待同一 `session_id`;不得把后台启动或浏览器成功页面当作授权完成,也不得另起 `runtime status`。
|
|
20
|
+
|
|
21
|
+
Hermes Agent 执行带 `--input -` 的一次性业务命令时,使用 `terminal` 前台执行,并用单引号 heredoc 将完整 JSON 只写入 stdin;不得用 `echo`、把 JSON 放入 argv、合并 stderr 或把该短命令后台化。
|
|
22
|
+
|
|
23
|
+
固定 contract 中的 `<target>` 必须替换为当前宿主:Codex=`codex`、Claude Code=`claude`、Pi Agent=`pi`、DeepSeek Harness=`dsh`、WorkBuddy=`workbuddy`、Hermes Agent=`hermes`。DeepSeek Harness 和 WorkBuddy 若返回持久终端或后台任务句柄,只轮询该原始句柄直到进程退出,不另起状态命令推测完成。
|
|
20
24
|
|
|
21
25
|
`context resolve` 是无状态调用:单一工作空间直接返回上下文,多个候选返回组合选项;用户选择后由当前任务直接携带 team/region 参数,不执行 `context select`,不写本地 operation。所有可变 `call` 仍需先取得 confirmation ID,再以完全相同的输入追加 `--confirm` 执行一次。
|
|
22
26
|
|
|
@@ -25,7 +29,7 @@ Codex 中命令工具一旦返回 `session_id`,必须立即对该 `session_id`
|
|
|
25
29
|
```json
|
|
26
30
|
{
|
|
27
31
|
"schema": "rainskills.single-runtime-contract.v1",
|
|
28
|
-
"package_version": "rainskills@0.1.
|
|
32
|
+
"package_version": "rainskills@0.1.34",
|
|
29
33
|
"runtime_status": [
|
|
30
34
|
"node",
|
|
31
35
|
"<home>/.rainbond/lib/rainskills/bin/rainskills.js",
|
|
@@ -25,7 +25,11 @@ description: "Use only when the user explicitly asks to initialize or link a loc
|
|
|
25
25
|
|
|
26
26
|
Codex 中命令工具一旦返回 `session_id`,必须立即对该 `session_id` 反复调用 `write_stdin`(空输入轮询),直到工具返回 `exit_code`。连接器输出 `[RAINSKILLS_AGENT_WAIT_REQUIRED:runtime-connect]` 后进入上述轮询;看到 `[RAINSKILLS_AGENT_WAIT_COMPLETE:runtime-connect]` 后仍须继续轮询,直到取得退出码和最终 JSON。
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
Hermes Agent 中必须使用 `terminal` 以 `background=true` 启动授权命令;取得 `session_id` 后,只对同一会话按需调用 `process(action="poll")` 获取授权地址,再调用 `process(action="wait")` 等待退出。`wait` 超时时只能继续等待同一 `session_id`;不得把后台启动或浏览器成功页面当作授权完成,也不得另起 `runtime status`。
|
|
29
|
+
|
|
30
|
+
Hermes Agent 执行带 `--input -` 的一次性业务命令时,使用 `terminal` 前台执行,并用单引号 heredoc 将完整 JSON 只写入 stdin;不得用 `echo`、把 JSON 放入 argv、合并 stderr 或把该短命令后台化。
|
|
31
|
+
|
|
32
|
+
固定 contract 中的 `<target>` 必须替换为当前宿主:Codex=`codex`、Claude Code=`claude`、Pi Agent=`pi`、DeepSeek Harness=`dsh`、WorkBuddy=`workbuddy`、Hermes Agent=`hermes`。DeepSeek Harness 和 WorkBuddy 若返回持久终端或后台任务句柄,只轮询该原始句柄直到进程退出,不另起状态命令推测完成。
|
|
29
33
|
|
|
30
34
|
`context resolve` 是无状态调用:单一工作空间直接返回上下文,多个候选返回组合选项;用户选择后由当前任务直接携带 team/region 参数,不执行 `context select`,不写本地 operation。所有可变 `call` 仍需先取得 confirmation ID,再以完全相同的输入追加 `--confirm` 执行一次。
|
|
31
35
|
|
|
@@ -34,7 +38,7 @@ Codex 中命令工具一旦返回 `session_id`,必须立即对该 `session_id`
|
|
|
34
38
|
```json
|
|
35
39
|
{
|
|
36
40
|
"schema": "rainskills.single-runtime-contract.v1",
|
|
37
|
-
"package_version": "rainskills@0.1.
|
|
41
|
+
"package_version": "rainskills@0.1.34",
|
|
38
42
|
"runtime_status": [
|
|
39
43
|
"node",
|
|
40
44
|
"<home>/.rainbond/lib/rainskills/bin/rainskills.js",
|
|
@@ -25,7 +25,11 @@ description: "Use when the user explicitly asks to install a local or cloud Rain
|
|
|
25
25
|
|
|
26
26
|
Codex 中命令工具一旦返回 `session_id`,必须立即对该 `session_id` 反复调用 `write_stdin`(空输入轮询),直到工具返回 `exit_code`。连接器输出 `[RAINSKILLS_AGENT_WAIT_REQUIRED:runtime-connect]` 后进入上述轮询;看到 `[RAINSKILLS_AGENT_WAIT_COMPLETE:runtime-connect]` 后仍须继续轮询,直到取得退出码和最终 JSON。
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
Hermes Agent 中必须使用 `terminal` 以 `background=true` 启动授权命令;取得 `session_id` 后,只对同一会话按需调用 `process(action="poll")` 获取授权地址,再调用 `process(action="wait")` 等待退出。`wait` 超时时只能继续等待同一 `session_id`;不得把后台启动或浏览器成功页面当作授权完成,也不得另起 `runtime status`。
|
|
29
|
+
|
|
30
|
+
Hermes Agent 执行带 `--input -` 的一次性业务命令时,使用 `terminal` 前台执行,并用单引号 heredoc 将完整 JSON 只写入 stdin;不得用 `echo`、把 JSON 放入 argv、合并 stderr 或把该短命令后台化。
|
|
31
|
+
|
|
32
|
+
固定 contract 中的 `<target>` 必须替换为当前宿主:Codex=`codex`、Claude Code=`claude`、Pi Agent=`pi`、DeepSeek Harness=`dsh`、WorkBuddy=`workbuddy`、Hermes Agent=`hermes`。DeepSeek Harness 和 WorkBuddy 若返回持久终端或后台任务句柄,只轮询该原始句柄直到进程退出,不另起状态命令推测完成。
|
|
29
33
|
|
|
30
34
|
`context resolve` 是无状态调用:单一工作空间直接返回上下文,多个候选返回组合选项;用户选择后由当前任务直接携带 team/region 参数,不执行 `context select`,不写本地 operation。所有可变 `call` 仍需先取得 confirmation ID,再以完全相同的输入追加 `--confirm` 执行一次。
|
|
31
35
|
|
|
@@ -34,7 +38,7 @@ Codex 中命令工具一旦返回 `session_id`,必须立即对该 `session_id`
|
|
|
34
38
|
```json
|
|
35
39
|
{
|
|
36
40
|
"schema": "rainskills.single-runtime-contract.v1",
|
|
37
|
-
"package_version": "rainskills@0.1.
|
|
41
|
+
"package_version": "rainskills@0.1.34",
|
|
38
42
|
"runtime_status": [
|
|
39
43
|
"node",
|
|
40
44
|
"<home>/.rainbond/lib/rainskills/bin/rainskills.js",
|