rainskills 0.1.27 → 0.1.29
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 +19 -3
- package/SKILL.md +4 -2
- package/bin/rainskills.js +7 -4
- package/install.sh +40 -10
- package/marketplace/rainskills/.claude-plugin/plugin.json +3 -1
- package/marketplace/rainskills/.codex-plugin/plugin.json +3 -1
- package/marketplace/rainskills/skills/rainskills/SKILL.md +5 -3
- package/package.json +5 -3
- package/rainbond-app-assistant/SKILL.md +4 -2
- package/rainbond-app-assistant/references/runtime-gate.md +4 -2
- package/rainbond-app-assistant/references/workflow-rules.md +1 -1
- package/rainbond-app-version-assistant/SKILL.md +3 -1
- package/rainbond-delivery-verifier/SKILL.md +3 -1
- package/rainbond-env-sync/SKILL.md +3 -1
- package/rainbond-fullstack-bootstrap/SKILL.md +3 -1
- package/rainbond-fullstack-troubleshooter/SKILL.md +3 -1
- package/rainbond-opensource-app-deploy/SKILL.md +1 -1
- package/rainbond-opensource-app-deploy/references/runtime-gate.md +3 -1
- package/rainbond-platform-installer/SKILL.md +1 -1
- package/rainbond-platform-installer/scripts/auto-update.js +7 -10
- package/rainbond-platform-installer/scripts/host-targets.js +61 -0
- package/rainbond-platform-installer/scripts/installed-version.js +1 -1
- package/rainbond-platform-installer/scripts/platform-installer.js +2 -1
- package/rainbond-platform-installer/scripts/runtime-state.js +2 -1
- package/rainbond-platform-installer/scripts/telemetry.js +3 -1
- package/rainbond-platform-installer/scripts/windows-onboarding.js +29 -22
- package/rainbond-platform-query/SKILL.md +3 -1
- package/rainbond-project-init/SKILL.md +3 -1
- package/rainbond-template-installer/SKILL.md +3 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Rainskills
|
|
2
2
|
|
|
3
|
-
Rainskills 是一组面向应用识别、部署、排障和交付的 AI Skills,支持 Codex、Claude Code 和
|
|
3
|
+
Rainskills 是一组面向应用识别、部署、排障和交付的 AI Skills,支持 Codex、Claude Code、Pi Agent、DeepSeek Harness 和 WorkBuddy。用户在市场中只会看到一个 `Rainskills` 产品,安装后 11 个 `rainbond-*` Skill 仍会独立触发。
|
|
4
4
|
|
|
5
5
|
## 安装
|
|
6
6
|
|
|
@@ -41,7 +41,23 @@ Claude Code:
|
|
|
41
41
|
/reload-plugins
|
|
42
42
|
```
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
DeepSeek Harness:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
npx --yes rainskills dsh
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
默认安装到 `${DSH_HOME:-~/.dsh}/skills`。DeepSeek Harness 使用原生 Skill catalog 和 `skill` loader 加载,不配置客户端 MCP。
|
|
51
|
+
|
|
52
|
+
WorkBuddy:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
npx --yes rainskills workbuddy
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
默认安装到 `${WORKBUDDY_CONFIG_DIR:-~/.workbuddy-ai}/skills`。如果安装发生在一个已经打开的 WorkBuddy 任务中,先刷新 Skill 列表或新建任务;部署时明确指定 Rainbond/Rainskills,或让项目保留 `rainbond.app.json`、`.rainbond/local.json` 标记,以避免被内置 Sites 路由抢占。
|
|
59
|
+
|
|
60
|
+
安装流程支持 Codex、Claude Code、Pi Agent、DeepSeek Harness 和 WorkBuddy;所有 Agent 共用同一组 Skills 和本地 Rainskills CLI,不提供单独的客户端 MCP adapter。macOS、Linux 和 WSL 不支持 OpenClaw 安装。不要手工复制 Skill、拼接凭据或修改 Agent 配置。
|
|
45
61
|
|
|
46
62
|
## 安装完成时用户会看到什么
|
|
47
63
|
|
|
@@ -223,7 +239,7 @@ node ~/.rainbond/lib/rainskills/bin/rainskills.js platform install --onboarding-
|
|
|
223
239
|
|
|
224
240
|
Rainskills 会在用户下一次发起业务动作时,由本地运行时立即返回环境查询结果,并另行启动后台任务静默检查更新。更新只跟随 npm `latest` 指向的正式版。当前版本是 RC 或其他预发布版本时不会查询、不会自动升级;npm 上的新 RC 版本也不参与正式版自动升级。
|
|
225
241
|
|
|
226
|
-
发现更高的正式版后,后台任务只委托到经过校验的精确版本,例如 `rainskills@0.1.
|
|
242
|
+
发现更高的正式版后,后台任务只委托到经过校验的精确版本,例如 `rainskills@0.1.29`,不会执行浮动的 `@latest` 业务代码。新版本原子刷新已经安装的 Rainskills Skills;当前业务继续使用启动时已经加载的版本,最迟从下一条新任务开始使用新版。npm 超时、版本检查失败、安装位置不安全或文件迁移失败时会保留旧版本,且不会阻塞或改变当前操作。
|
|
227
243
|
|
|
228
244
|
升级只更新 Rainskills 自身,不触发 Rainbond 安装、运行环境选择、登录授权或重新对接,也不会新增 Agent MCP 配置。更新内容仅包括 Skills 和本地 CLI。原始业务操作会继续执行;只有该业务操作本身需要运行环境时,才按既有门禁检查当前连接。可用连接直接复用,401 只重新授权一次,403 立即停止,从未连接过运行环境时才进入环境选择。
|
|
229
245
|
|
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`,
|
|
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 WorkBuddy=`workbuddy`. All five use the same installed Skills and protected local Rainskills CLI; Pi and DeepSeek Harness have no separate MCP adapter or generated extension. DeepSeek Harness installs to `$DSH_HOME/skills` (default `~/.dsh/skills`). WorkBuddy installs to `$WORKBUDDY_CONFIG_DIR/skills` (default `~/.workbuddy-ai/skills`). 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.
|
|
@@ -48,7 +48,9 @@ Rainskills 安装完成,下一条消息即可直接使用。
|
|
|
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
|
+
DeepSeek Harness 和 WorkBuddy 也必须保持原命令附着直到退出;如果宿主把长命令转成持久终端或后台任务,只能轮询该原始命令句柄,不得另起 `runtime status` 推测授权结果。WorkBuddy 安装后若当前任务的 Skill 清单尚未刷新,在下一条业务动作前先刷新 Skill 列表或新建任务,不得退回内置 Sites 代替 Rainbond 部署。
|
|
52
|
+
|
|
53
|
+
Rainskills 只保存一个全局运行环境,不维护环境列表、名称、默认值或环境 ID。使用固定 launcher `node <home>/.rainbond/lib/rainskills/bin/rainskills.js`(运行包版本 `rainskills@0.1.29`):
|
|
52
54
|
|
|
53
55
|
- 状态:执行 `runtime status --json`。
|
|
54
56
|
- 首次连接:执行 `runtime connect <target> --saas` 或 `runtime connect <target> --rainbond-url <Console origin>`。
|
package/bin/rainskills.js
CHANGED
|
@@ -13,6 +13,9 @@ const {
|
|
|
13
13
|
const {
|
|
14
14
|
renderCatalogUserMessage,
|
|
15
15
|
} = require("../rainbond-platform-installer/scripts/user-message.js");
|
|
16
|
+
const {
|
|
17
|
+
isHostTarget,
|
|
18
|
+
} = require("../rainbond-platform-installer/scripts/host-targets.js");
|
|
16
19
|
|
|
17
20
|
const AUTO_UPDATE_FALLBACK_EXIT_CODE = 75;
|
|
18
21
|
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;
|
|
@@ -67,7 +70,7 @@ function parseRuntimeAssertConnectArgs(args) {
|
|
|
67
70
|
throw new Error("runtime connect 内部门禁参数无效");
|
|
68
71
|
}
|
|
69
72
|
if (!UUID_PATTERN.test(args[3] || "")) throw new Error("runtime connect operation 无效");
|
|
70
|
-
if (!
|
|
73
|
+
if (!isHostTarget(args[5])) throw new Error("runtime connect target 无效");
|
|
71
74
|
if (!["saas", "private"].includes(args[7])) throw new Error("runtime connect environment kind 无效");
|
|
72
75
|
return {
|
|
73
76
|
operationId: args[3],
|
|
@@ -95,8 +98,8 @@ function parseRuntimeConnectArgs(args) {
|
|
|
95
98
|
throw new Error("不是 runtime connect 命令");
|
|
96
99
|
}
|
|
97
100
|
const targetClient = args[2];
|
|
98
|
-
if (!
|
|
99
|
-
throw new Error("runtime connect
|
|
101
|
+
if (!isHostTarget(targetClient)) {
|
|
102
|
+
throw new Error("runtime connect 需要固定的受支持宿主目标");
|
|
100
103
|
}
|
|
101
104
|
let environmentChoice = "";
|
|
102
105
|
let rainbondUrl = "";
|
|
@@ -319,7 +322,7 @@ async function runBuiltin(args, {
|
|
|
319
322
|
return true;
|
|
320
323
|
}
|
|
321
324
|
if (args[0] === "runtime" && args[1] === "reconnect") {
|
|
322
|
-
if (args.length !== 3 || !
|
|
325
|
+
if (args.length !== 3 || !isHostTarget(args[2])) {
|
|
323
326
|
throw new Error("runtime reconnect 参数无效");
|
|
324
327
|
}
|
|
325
328
|
const current = getSingleRuntimeStore().read();
|
package/install.sh
CHANGED
|
@@ -205,6 +205,8 @@ Usage:
|
|
|
205
205
|
./install.sh claude
|
|
206
206
|
./install.sh codex
|
|
207
207
|
./install.sh pi
|
|
208
|
+
./install.sh dsh
|
|
209
|
+
./install.sh workbuddy
|
|
208
210
|
./install.sh all
|
|
209
211
|
./install.sh --dest <path>
|
|
210
212
|
./install.sh all --saas
|
|
@@ -216,7 +218,9 @@ Options:
|
|
|
216
218
|
claude Install and configure Claude Code
|
|
217
219
|
codex Install and configure Codex
|
|
218
220
|
pi Install and configure Pi Agent
|
|
219
|
-
|
|
221
|
+
dsh Install and configure DeepSeek Harness
|
|
222
|
+
workbuddy Install and configure WorkBuddy
|
|
223
|
+
all Install and configure all supported agents
|
|
220
224
|
refresh Re-run browser login and refresh the protected CLI credential
|
|
221
225
|
--dest PATH Install skills to a custom directory only
|
|
222
226
|
--force Overwrite existing installed skills
|
|
@@ -240,6 +244,8 @@ Environment:
|
|
|
240
244
|
RAINBOND_PASSWORD Legacy: Rainbond login password for non-interactive runs
|
|
241
245
|
RAINBOND_LOGIN_TIMEOUT Browser login timeout in seconds (default 600)
|
|
242
246
|
RAINSKILLS_NO_BROWSER Set to 1 to print the authorization URL without opening it
|
|
247
|
+
DSH_HOME DeepSeek Harness home (default: ~/.dsh)
|
|
248
|
+
WORKBUDDY_CONFIG_DIR WorkBuddy config home (default: ~/.workbuddy-ai)
|
|
243
249
|
EOF
|
|
244
250
|
}
|
|
245
251
|
|
|
@@ -298,6 +304,12 @@ rainskills_install_client_for_target() {
|
|
|
298
304
|
pi)
|
|
299
305
|
printf 'pi\n'
|
|
300
306
|
;;
|
|
307
|
+
dsh)
|
|
308
|
+
printf 'deepseek_harness\n'
|
|
309
|
+
;;
|
|
310
|
+
workbuddy)
|
|
311
|
+
printf 'workbuddy\n'
|
|
312
|
+
;;
|
|
301
313
|
all)
|
|
302
314
|
printf 'all\n'
|
|
303
315
|
;;
|
|
@@ -461,7 +473,7 @@ event = {
|
|
|
461
473
|
"platform": platform,
|
|
462
474
|
"control_mode": control_mode,
|
|
463
475
|
"target": target,
|
|
464
|
-
"client": client if client in {"codex", "claude_code", "pi", "all", "both", "unknown"} else "unknown",
|
|
476
|
+
"client": client if client in {"codex", "claude_code", "pi", "deepseek_harness", "workbuddy", "all", "both", "unknown"} else "unknown",
|
|
465
477
|
"eid": eid or None,
|
|
466
478
|
"phase": None,
|
|
467
479
|
"lifecycle_phase": phase,
|
|
@@ -518,7 +530,7 @@ initialize_rainskills_installation_reporting() {
|
|
|
518
530
|
connect)
|
|
519
531
|
RAINSKILLS_INSTALL_ACTION="connect"
|
|
520
532
|
;;
|
|
521
|
-
codex|claude|pi|all)
|
|
533
|
+
codex|claude|pi|dsh|workbuddy|all)
|
|
522
534
|
target="$arg"
|
|
523
535
|
;;
|
|
524
536
|
esac
|
|
@@ -816,12 +828,12 @@ parse_args() {
|
|
|
816
828
|
ACTION="connect"
|
|
817
829
|
shift
|
|
818
830
|
;;
|
|
819
|
-
claude|codex|pi|all)
|
|
831
|
+
claude|codex|pi|dsh|workbuddy|all)
|
|
820
832
|
TARGET="$1"
|
|
821
833
|
shift
|
|
822
834
|
;;
|
|
823
835
|
openclaw)
|
|
824
|
-
die "macOS/Linux 安装器不再支持 OpenClaw,请使用 Codex、Claude Code 或
|
|
836
|
+
die "macOS/Linux 安装器不再支持 OpenClaw,请使用 Codex、Claude Code、Pi Agent、DeepSeek Harness 或 WorkBuddy。"
|
|
825
837
|
;;
|
|
826
838
|
--dest)
|
|
827
839
|
[[ $# -ge 2 ]] || die "--dest 需要一个路径值"
|
|
@@ -909,7 +921,7 @@ assert_internal_connect_entry() {
|
|
|
909
921
|
local target="" environment_kind="" console_origin="" mode=""
|
|
910
922
|
while [[ $# -gt 0 ]]; do
|
|
911
923
|
case "$1" in
|
|
912
|
-
codex|claude|pi|all)
|
|
924
|
+
codex|claude|pi|dsh|workbuddy|all)
|
|
913
925
|
[[ -z "$target" ]] || return 1
|
|
914
926
|
target="$1"
|
|
915
927
|
shift
|
|
@@ -1015,10 +1027,12 @@ resolve_target() {
|
|
|
1015
1027
|
log " 1) Codex"
|
|
1016
1028
|
log " 2) Claude Code"
|
|
1017
1029
|
log " 3) Pi Agent"
|
|
1018
|
-
log " 4)
|
|
1030
|
+
log " 4) DeepSeek Harness"
|
|
1031
|
+
log " 5) WorkBuddy"
|
|
1032
|
+
log " 6) 全部"
|
|
1019
1033
|
|
|
1020
1034
|
while true; do
|
|
1021
|
-
printf '请输入选项 [1-
|
|
1035
|
+
printf '请输入选项 [1-6]: '
|
|
1022
1036
|
read -r choice
|
|
1023
1037
|
case "$choice" in
|
|
1024
1038
|
1)
|
|
@@ -1033,12 +1047,20 @@ resolve_target() {
|
|
|
1033
1047
|
TARGET="pi"
|
|
1034
1048
|
return 0
|
|
1035
1049
|
;;
|
|
1036
|
-
4
|
|
1050
|
+
4)
|
|
1051
|
+
TARGET="dsh"
|
|
1052
|
+
return 0
|
|
1053
|
+
;;
|
|
1054
|
+
5)
|
|
1055
|
+
TARGET="workbuddy"
|
|
1056
|
+
return 0
|
|
1057
|
+
;;
|
|
1058
|
+
6|"")
|
|
1037
1059
|
TARGET="all"
|
|
1038
1060
|
return 0
|
|
1039
1061
|
;;
|
|
1040
1062
|
*)
|
|
1041
|
-
log "请输入 1、2、3 或
|
|
1063
|
+
log "请输入 1、2、3、4、5 或 6。"
|
|
1042
1064
|
;;
|
|
1043
1065
|
esac
|
|
1044
1066
|
done
|
|
@@ -1060,10 +1082,18 @@ collect_destinations() {
|
|
|
1060
1082
|
pi)
|
|
1061
1083
|
destinations+=("$HOME/.pi/agent/skills")
|
|
1062
1084
|
;;
|
|
1085
|
+
dsh)
|
|
1086
|
+
destinations+=("${DSH_HOME:-$HOME/.dsh}/skills")
|
|
1087
|
+
;;
|
|
1088
|
+
workbuddy)
|
|
1089
|
+
destinations+=("${WORKBUDDY_CONFIG_DIR:-$HOME/.workbuddy-ai}/skills")
|
|
1090
|
+
;;
|
|
1063
1091
|
all)
|
|
1064
1092
|
destinations+=("$HOME/.claude/skills")
|
|
1065
1093
|
destinations+=("$HOME/.codex/skills")
|
|
1066
1094
|
destinations+=("$HOME/.pi/agent/skills")
|
|
1095
|
+
destinations+=("${DSH_HOME:-$HOME/.dsh}/skills")
|
|
1096
|
+
destinations+=("${WORKBUDDY_CONFIG_DIR:-$HOME/.workbuddy-ai}/skills")
|
|
1067
1097
|
;;
|
|
1068
1098
|
*)
|
|
1069
1099
|
die "未知安装目标:$TARGET"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rainskills",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.29",
|
|
4
4
|
"description": "Install the complete Rainskills AI deployment skill suite as one product.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Goodrain",
|
|
@@ -13,6 +13,8 @@
|
|
|
13
13
|
"rainbond",
|
|
14
14
|
"codex",
|
|
15
15
|
"claude-code",
|
|
16
|
+
"deepseek-harness",
|
|
17
|
+
"workbuddy",
|
|
16
18
|
"skills",
|
|
17
19
|
"installer"
|
|
18
20
|
]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rainskills",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.29",
|
|
4
4
|
"description": "Install the complete Rainskills AI deployment skill suite as one product.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Goodrain",
|
|
@@ -13,6 +13,8 @@
|
|
|
13
13
|
"rainbond",
|
|
14
14
|
"codex",
|
|
15
15
|
"claude-code",
|
|
16
|
+
"deepseek-harness",
|
|
17
|
+
"workbuddy",
|
|
16
18
|
"skills",
|
|
17
19
|
"installer"
|
|
18
20
|
],
|
|
@@ -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`,
|
|
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 WorkBuddy=`workbuddy`. All five use the same installed Skills and protected local Rainskills CLI; Pi and DeepSeek Harness have no separate MCP adapter or generated extension. DeepSeek Harness installs to `$DSH_HOME/skills` (default `~/.dsh/skills`). WorkBuddy installs to `$WORKBUDDY_CONFIG_DIR/skills` (default `~/.workbuddy-ai/skills`). 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.29 <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
|
|
|
@@ -48,7 +48,9 @@ Rainskills 安装完成,下一条消息即可直接使用。
|
|
|
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
|
+
DeepSeek Harness 和 WorkBuddy 也必须保持原命令附着直到退出;如果宿主把长命令转成持久终端或后台任务,只能轮询该原始命令句柄,不得另起 `runtime status` 推测授权结果。WorkBuddy 安装后若当前任务的 Skill 清单尚未刷新,在下一条业务动作前先刷新 Skill 列表或新建任务,不得退回内置 Sites 代替 Rainbond 部署。
|
|
52
|
+
|
|
53
|
+
Rainskills 只保存一个全局运行环境,不维护环境列表、名称、默认值或环境 ID。使用固定 launcher `node <home>/.rainbond/lib/rainskills/bin/rainskills.js`(运行包版本 `rainskills@0.1.29`):
|
|
52
54
|
|
|
53
55
|
- 状态:执行 `runtime status --json`。
|
|
54
56
|
- 首次连接:执行 `runtime connect <target> --saas` 或 `runtime connect <target> --rainbond-url <Console origin>`。
|
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,
|
|
3
|
+
"version": "0.1.29",
|
|
4
|
+
"description": "Interactive Rainbond skill installer for Codex, Claude Code, Pi Agent, DeepSeek Harness, and WorkBuddy",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://github.com/goodrain/rainskills#readme",
|
|
7
7
|
"bugs": {
|
|
@@ -15,6 +15,8 @@
|
|
|
15
15
|
"rainbond",
|
|
16
16
|
"codex",
|
|
17
17
|
"claude-code",
|
|
18
|
+
"deepseek-harness",
|
|
19
|
+
"workbuddy",
|
|
18
20
|
"skills",
|
|
19
21
|
"installer"
|
|
20
22
|
],
|
|
@@ -65,7 +67,7 @@
|
|
|
65
67
|
"test:runtime-version": "node --test tests/runtime-version-sync.test.js",
|
|
66
68
|
"test:runtime-contracts": "node scripts/sync-runtime-contracts.mjs --check",
|
|
67
69
|
"test:auto-update": "node --test tests/auto-update.test.js",
|
|
68
|
-
"test:launcher": "node --test tests/console-origin.test.js tests/local-cli-installer.test.js tests/npx-launcher.test.js tests/runtime-state.test.js tests/single-runtime.test.js tests/single-runtime-cli.test.js tests/single-runtime-launcher.test.js tests/skill-manifest-builder.test.js",
|
|
70
|
+
"test:launcher": "node --test tests/console-origin.test.js tests/host-targets.test.js tests/local-cli-installer.test.js tests/npx-launcher.test.js tests/runtime-state.test.js tests/single-runtime.test.js tests/single-runtime-cli.test.js tests/single-runtime-launcher.test.js tests/skill-manifest-builder.test.js",
|
|
69
71
|
"test:api-bridge": "node --test tests/api-bridge.test.js",
|
|
70
72
|
"test:console-contract": "python3 tests/console_tool_contract_test.py",
|
|
71
73
|
"test:skill-profile": "node --test tests/skill-profile-builder.test.js tests/markdown-link-integrity.test.js tests/user-facing-output-contract.test.js",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: rainbond-app-assistant
|
|
3
|
-
description: "Use whenever a user asks to deploy, run, deliver, publish, inspect, repair, or troubleshoot source code
|
|
3
|
+
description: "Use whenever a user asks to deploy, run, deliver, publish, inspect, repair, or troubleshoot source code with Rainbond or Rainskills; when the current project contains rainbond.app.json or .rainbond/local.json; for a source directory/package, ordinary bare Git repository URL, private-image project, named application not identified as a third-party open-source suite, or a new app/component built from one container image. On WorkBuddy this takes priority over the built-in Sites skill whenever Rainbond/Rainskills is explicit or a Rainbond project marker exists. Trigger phrases: 帮我部署当前项目 / 使用 Rainbond 部署 / 用 Rainskills 部署 / 帮我把这个项目跑起来 / 帮我看看当前项目卡在哪 / 如果还没初始化就先初始化,然后自动继续到应该停止的位置 / 帮我处理一下这个应用 / 在团队下新建应用并使用镜像创建组件. Not for supplied third-party Compose, Helm, image-set descriptors, or an explicit named third-party open-source suite; use rainbond-opensource-app-deploy. Confirmed market templates use rainbond-template-installer."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Rainbond App Assistant
|
|
@@ -13,6 +13,7 @@ description: "Use whenever a user asks to deploy, run, deliver, publish, inspect
|
|
|
13
13
|
- 源码目录、源码包、私有镜像项目、普通裸 Git URL,以及未被明确识别为第三方开源套件的应用名称:由本 Skill 接管。
|
|
14
14
|
- 用户实际提供第三方 Docker Compose、Helm、镜像集合描述符,或明确要求部署 Harbor、Dify、n8n 等第三方开源套件:转到 rainbond-opensource-app-deploy。
|
|
15
15
|
- 已确认是 Rainbond 本地/云端市场模板:转到 rainbond-template-installer。
|
|
16
|
+
- WorkBuddy 中只要用户明确指定 Rainbond/Rainskills,或项目根目录存在 `rainbond.app.json`、`.rainbond/local.json`,本 Skill 必须优先于内置 `发布应用 / Sites`;不得把 WorkBuddy Sites 当作 Rainbond 部署的静默替代方案。用户明确指定 WorkBuddy Sites 且没有要求 Rainbond 时才离开本 Skill。
|
|
16
17
|
|
|
17
18
|
开始前读取 [routing](references/routing.md) 做静态归属判断。初始路由阶段只加载最终所属入口 Skill 的 Runtime Gate,不得提前读取专项 Skill 的 Gate。
|
|
18
19
|
|
|
@@ -27,7 +28,7 @@ description: "Use whenever a user asks to deploy, run, deliver, publish, inspect
|
|
|
27
28
|
| 需要对象边界或跨阶段状态语义 | [product object model](references/product-object-model.md) | 不相关工作流 |
|
|
28
29
|
| 需要生成最终结果或自动化契约 | [output contract](references/output-contract.md) | 不需要结果协议时不得读取 |
|
|
29
30
|
|
|
30
|
-
workspace context 包含 `enterprise_id`、`team_id`、`team_name` 和 `region_name
|
|
31
|
+
workspace context 包含 `enterprise_id`、`team_id`、`team_name` 和 `region_name`;`team_id` 可作为内部调用参数继续使用,但不得复制到用户可见的过程消息或最终结果中。app/component 标识只来自用户明确输入或本次实时查询/创建结果。它们都由当前任务携带,不写入 Runtime,也不得生成或传递 CLI 业务 operation ID、运行环境 ID 或 intent JSON。
|
|
31
32
|
|
|
32
33
|
## Runtime Gate
|
|
33
34
|
|
|
@@ -58,6 +59,7 @@ workspace context 包含 `enterprise_id`、`team_id`、`team_name` 和 `region_n
|
|
|
58
59
|
- 成功:说明项目、运行环境、工作空间、应用、真实 Rainbond 页面/访问地址及本轮实际完成操作;无法确认的字段省略,禁止猜测。
|
|
59
60
|
- 未完成:输出“部署失败。”、一句直接原因;仅在确有安全可执行方案时增加“解决办法”。
|
|
60
61
|
- 默认不得展示内部对象、状态枚举、Skill/工具名、YAML、JSON 或英文编排标题。
|
|
62
|
+
- 过程消息和最终结果中的工作空间一律用 `team_name` 展示,可连同 `region_name` 写成“工作空间 / 集群”;除非用户明确要求调试原始数据,不展示 `team_id`。
|
|
61
63
|
- 用户明确要求结构化结果或自动化契约时,读取 [output contract](references/output-contract.md),不得自行发明字段、枚举或状态。
|
|
62
64
|
|
|
63
65
|
## 停止条件
|
|
@@ -13,14 +13,16 @@ 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
|
+
固定 contract 中的 `<target>` 必须替换为当前宿主:Codex=`codex`、Claude Code=`claude`、Pi Agent=`pi`、DeepSeek Harness=`dsh`、WorkBuddy=`workbuddy`。DeepSeek Harness 和 WorkBuddy 若返回持久终端或后台任务句柄,只轮询该原始句柄直到进程退出,不另起状态命令推测完成。
|
|
17
|
+
|
|
18
|
+
`context resolve` 是无状态调用:单一工作空间直接返回上下文,多个候选返回组合选项;其中 `team_id` 是后续平台调用的内部参数,不得复制到用户可见的过程消息或最终结果中。用户选择后由当前任务直接携带 team/region 参数,不执行 `context select`,不写本地 operation。所有可变 `call` 仍需先取得 confirmation ID,再以完全相同的输入追加 `--confirm` 执行一次。
|
|
17
19
|
|
|
18
20
|
`required` 只声明要解析的维度,企业 ID 始终来自当前登录身份。用户明确给出的 team/region 必须放进 `hints` 做精确匹配;不得把企业名、team 名或选择对象作为顶层 `enterprise` / `workspace` 字段传入。多候选时只展示 CLI 返回的 label;用户选择后再次执行同一个无状态 `context resolve`,通过 `selection.option_id` 让 CLI 重新查询并验证当前候选,不写本地 context 状态。
|
|
19
21
|
|
|
20
22
|
```json
|
|
21
23
|
{
|
|
22
24
|
"schema": "rainskills.single-runtime-contract.v1",
|
|
23
|
-
"package_version": "rainskills@0.1.
|
|
25
|
+
"package_version": "rainskills@0.1.29",
|
|
24
26
|
"runtime_status": [
|
|
25
27
|
"node",
|
|
26
28
|
"<home>/.rainbond/lib/rainskills/bin/rainskills.js",
|
|
@@ -529,7 +529,7 @@
|
|
|
529
529
|
反例(来自真实回归 case `cs_1779149681822_3u`,2026-05-19):模型从 `rainbond_get_component_summary` 响应的 `recent_events` 段看到形如 `{"ID": 17740, "event_id": "...", "opt_type": "build-service"}`,直接把 `17740` 当成 `event_id` 传给 `rainbond_get_component_build_logs`,工具返回 `items: []`(找不到该 UUID 的日志)。正确做法:从同一 `recent_events[i].event_id` 字段取出 UUID 字符串,或调 `rainbond_get_component_events` 重查。
|
|
530
530
|
35. **会话内部叙述纪律 + 内部 preflight 工具不要主动调**。下列四类是"内部会话状态",对用户**无信息量**,禁止外漏到 assistant 可见消息:
|
|
531
531
|
- **专项 Skill 手册加载过程**:这是当前任务的内部准备。不要说"我先加载 bootstrap 手册"、"手册已加载"或"skill ready";读完直接进入下一个真实工具调用。
|
|
532
|
-
- **`rainbond_get_current_user`**:不得由 Agent 单独调用。`enterprise_id`、`team_id`、`team_name` 和 `region_name` 统一由受保护的 `context resolve`
|
|
532
|
+
- **`rainbond_get_current_user`**:不得由 Agent 单独调用。`enterprise_id`、`team_id`、`team_name` 和 `region_name` 统一由受保护的 `context resolve` 命令无状态解析并由当前任务携带;`team_id` 可继续用于后续平台调用,但不得在过程消息或最终报告中展示。只有 CLI 明确返回需要选择时才询问用户,并且只展示名称标签。
|
|
533
533
|
- **`rainbond_query_components` 同入参重复轮询**:服务端 30s 内的同 args 调用会走缓存;你**不要**在每个新 user turn 开头都"先查一下组件列表"。只有本次调用使用的 `enterprise_id`、`app_id` 和查询条件均未变化,且没有新的平台动作时,才可复用 priorTurnMessages 里的最近结果。
|
|
534
534
|
- **规则推理过程 / Rainbond Tool 内部限制 / 分类决策叙述**:你内部基于哪条 Iron Law / hard rule / 推断信号做的决策、具体 Tool 签名 / 字段限制、对组件 / 服务的分类判断("ClickHouse 是公认的列式分析数据库"这类),都属于内部状态,对用户**无信息量**。
|
|
535
535
|
|
|
@@ -25,6 +25,8 @@ 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
|
+
固定 contract 中的 `<target>` 必须替换为当前宿主:Codex=`codex`、Claude Code=`claude`、Pi Agent=`pi`、DeepSeek Harness=`dsh`、WorkBuddy=`workbuddy`。DeepSeek Harness 和 WorkBuddy 若返回持久终端或后台任务句柄,只轮询该原始句柄直到进程退出,不另起状态命令推测完成。
|
|
29
|
+
|
|
28
30
|
`context resolve` 是无状态调用:单一工作空间直接返回上下文,多个候选返回组合选项;用户选择后由当前任务直接携带 team/region 参数,不执行 `context select`,不写本地 operation。所有可变 `call` 仍需先取得 confirmation ID,再以完全相同的输入追加 `--confirm` 执行一次。
|
|
29
31
|
|
|
30
32
|
`required` 只声明要解析的维度,企业 ID 始终来自当前登录身份。用户明确给出的 team/region 必须放进 `hints` 做精确匹配;不得把企业名、team 名或选择对象作为顶层 `enterprise` / `workspace` 字段传入。多候选时只展示 CLI 返回的 label;用户选择后再次执行同一个无状态 `context resolve`,通过 `selection.option_id` 让 CLI 重新查询并验证当前候选,不写本地 context 状态。
|
|
@@ -32,7 +34,7 @@ Codex 中命令工具一旦返回 `session_id`,必须立即对该 `session_id`
|
|
|
32
34
|
```json
|
|
33
35
|
{
|
|
34
36
|
"schema": "rainskills.single-runtime-contract.v1",
|
|
35
|
-
"package_version": "rainskills@0.1.
|
|
37
|
+
"package_version": "rainskills@0.1.29",
|
|
36
38
|
"runtime_status": [
|
|
37
39
|
"node",
|
|
38
40
|
"<home>/.rainbond/lib/rainskills/bin/rainskills.js",
|
|
@@ -48,6 +48,8 @@ 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
|
+
固定 contract 中的 `<target>` 必须替换为当前宿主:Codex=`codex`、Claude Code=`claude`、Pi Agent=`pi`、DeepSeek Harness=`dsh`、WorkBuddy=`workbuddy`。DeepSeek Harness 和 WorkBuddy 若返回持久终端或后台任务句柄,只轮询该原始句柄直到进程退出,不另起状态命令推测完成。
|
|
52
|
+
|
|
51
53
|
`context resolve` 是无状态调用:单一工作空间直接返回上下文,多个候选返回组合选项;用户选择后由当前任务直接携带 team/region 参数,不执行 `context select`,不写本地 operation。所有可变 `call` 仍需先取得 confirmation ID,再以完全相同的输入追加 `--confirm` 执行一次。
|
|
52
54
|
|
|
53
55
|
`required` 只声明要解析的维度,企业 ID 始终来自当前登录身份。用户明确给出的 team/region 必须放进 `hints` 做精确匹配;不得把企业名、team 名或选择对象作为顶层 `enterprise` / `workspace` 字段传入。多候选时只展示 CLI 返回的 label;用户选择后再次执行同一个无状态 `context resolve`,通过 `selection.option_id` 让 CLI 重新查询并验证当前候选,不写本地 context 状态。
|
|
@@ -55,7 +57,7 @@ Codex 中命令工具一旦返回 `session_id`,必须立即对该 `session_id`
|
|
|
55
57
|
```json
|
|
56
58
|
{
|
|
57
59
|
"schema": "rainskills.single-runtime-contract.v1",
|
|
58
|
-
"package_version": "rainskills@0.1.
|
|
60
|
+
"package_version": "rainskills@0.1.29",
|
|
59
61
|
"runtime_status": [
|
|
60
62
|
"node",
|
|
61
63
|
"<home>/.rainbond/lib/rainskills/bin/rainskills.js",
|
|
@@ -25,6 +25,8 @@ 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
|
+
固定 contract 中的 `<target>` 必须替换为当前宿主:Codex=`codex`、Claude Code=`claude`、Pi Agent=`pi`、DeepSeek Harness=`dsh`、WorkBuddy=`workbuddy`。DeepSeek Harness 和 WorkBuddy 若返回持久终端或后台任务句柄,只轮询该原始句柄直到进程退出,不另起状态命令推测完成。
|
|
29
|
+
|
|
28
30
|
`context resolve` 是无状态调用:单一工作空间直接返回上下文,多个候选返回组合选项;用户选择后由当前任务直接携带 team/region 参数,不执行 `context select`,不写本地 operation。所有可变 `call` 仍需先取得 confirmation ID,再以完全相同的输入追加 `--confirm` 执行一次。
|
|
29
31
|
|
|
30
32
|
`required` 只声明要解析的维度,企业 ID 始终来自当前登录身份。用户明确给出的 team/region 必须放进 `hints` 做精确匹配;不得把企业名、team 名或选择对象作为顶层 `enterprise` / `workspace` 字段传入。多候选时只展示 CLI 返回的 label;用户选择后再次执行同一个无状态 `context resolve`,通过 `selection.option_id` 让 CLI 重新查询并验证当前候选,不写本地 context 状态。
|
|
@@ -32,7 +34,7 @@ Codex 中命令工具一旦返回 `session_id`,必须立即对该 `session_id`
|
|
|
32
34
|
```json
|
|
33
35
|
{
|
|
34
36
|
"schema": "rainskills.single-runtime-contract.v1",
|
|
35
|
-
"package_version": "rainskills@0.1.
|
|
37
|
+
"package_version": "rainskills@0.1.29",
|
|
36
38
|
"runtime_status": [
|
|
37
39
|
"node",
|
|
38
40
|
"<home>/.rainbond/lib/rainskills/bin/rainskills.js",
|
|
@@ -25,6 +25,8 @@ 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
|
+
固定 contract 中的 `<target>` 必须替换为当前宿主:Codex=`codex`、Claude Code=`claude`、Pi Agent=`pi`、DeepSeek Harness=`dsh`、WorkBuddy=`workbuddy`。DeepSeek Harness 和 WorkBuddy 若返回持久终端或后台任务句柄,只轮询该原始句柄直到进程退出,不另起状态命令推测完成。
|
|
29
|
+
|
|
28
30
|
`context resolve` 是无状态调用:单一工作空间直接返回上下文,多个候选返回组合选项;用户选择后由当前任务直接携带 team/region 参数,不执行 `context select`,不写本地 operation。所有可变 `call` 仍需先取得 confirmation ID,再以完全相同的输入追加 `--confirm` 执行一次。
|
|
29
31
|
|
|
30
32
|
`required` 只声明要解析的维度,企业 ID 始终来自当前登录身份。用户明确给出的 team/region 必须放进 `hints` 做精确匹配;不得把企业名、team 名或选择对象作为顶层 `enterprise` / `workspace` 字段传入。多候选时只展示 CLI 返回的 label;用户选择后再次执行同一个无状态 `context resolve`,通过 `selection.option_id` 让 CLI 重新查询并验证当前候选,不写本地 context 状态。
|
|
@@ -32,7 +34,7 @@ Codex 中命令工具一旦返回 `session_id`,必须立即对该 `session_id`
|
|
|
32
34
|
```json
|
|
33
35
|
{
|
|
34
36
|
"schema": "rainskills.single-runtime-contract.v1",
|
|
35
|
-
"package_version": "rainskills@0.1.
|
|
37
|
+
"package_version": "rainskills@0.1.29",
|
|
36
38
|
"runtime_status": [
|
|
37
39
|
"node",
|
|
38
40
|
"<home>/.rainbond/lib/rainskills/bin/rainskills.js",
|
|
@@ -48,6 +48,8 @@ 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
|
+
固定 contract 中的 `<target>` 必须替换为当前宿主:Codex=`codex`、Claude Code=`claude`、Pi Agent=`pi`、DeepSeek Harness=`dsh`、WorkBuddy=`workbuddy`。DeepSeek Harness 和 WorkBuddy 若返回持久终端或后台任务句柄,只轮询该原始句柄直到进程退出,不另起状态命令推测完成。
|
|
52
|
+
|
|
51
53
|
`context resolve` 是无状态调用:单一工作空间直接返回上下文,多个候选返回组合选项;用户选择后由当前任务直接携带 team/region 参数,不执行 `context select`,不写本地 operation。所有可变 `call` 仍需先取得 confirmation ID,再以完全相同的输入追加 `--confirm` 执行一次。
|
|
52
54
|
|
|
53
55
|
`required` 只声明要解析的维度,企业 ID 始终来自当前登录身份。用户明确给出的 team/region 必须放进 `hints` 做精确匹配;不得把企业名、team 名或选择对象作为顶层 `enterprise` / `workspace` 字段传入。多候选时只展示 CLI 返回的 label;用户选择后再次执行同一个无状态 `context resolve`,通过 `selection.option_id` 让 CLI 重新查询并验证当前候选,不写本地 context 状态。
|
|
@@ -55,7 +57,7 @@ Codex 中命令工具一旦返回 `session_id`,必须立即对该 `session_id`
|
|
|
55
57
|
```json
|
|
56
58
|
{
|
|
57
59
|
"schema": "rainskills.single-runtime-contract.v1",
|
|
58
|
-
"package_version": "rainskills@0.1.
|
|
60
|
+
"package_version": "rainskills@0.1.29",
|
|
59
61
|
"runtime_status": [
|
|
60
62
|
"node",
|
|
61
63
|
"<home>/.rainbond/lib/rainskills/bin/rainskills.js",
|
|
@@ -30,7 +30,7 @@ description: "Use when the user supplies a third-party Docker Compose file/conte
|
|
|
30
30
|
| workspace context 已解析,需要建模、部署、排障或交付 app/component | 读取 [deployment workflow](references/deployment-workflow.md) |
|
|
31
31
|
| 新鲜证据命中已知部署故障模式 | 再读取 [failure-mode playbook](references/failure-mode-playbook.md) |
|
|
32
32
|
|
|
33
|
-
正确顺序是:先验证官方部署清单,再加载 Runtime Gate。这里只允许加载本 Skill 的 Gate。workspace context 包含 `enterprise_id`、`team_id`、`team_name` 和 `region_name
|
|
33
|
+
正确顺序是:先验证官方部署清单,再加载 Runtime Gate。这里只允许加载本 Skill 的 Gate。workspace context 包含 `enterprise_id`、`team_id`、`team_name` 和 `region_name`;`team_id` 可作为内部调用参数继续使用,但不得复制到用户可见的过程消息或最终结果中。app/component 标识只来自用户明确输入或本次实时查询/创建结果。它们都由当前任务携带,不得生成 CLI 业务 operation ID、运行环境 ID 或 intent JSON。
|
|
34
34
|
|
|
35
35
|
## Runtime 与安全边界
|
|
36
36
|
|
|
@@ -13,6 +13,8 @@ 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
|
+
固定 contract 中的 `<target>` 必须替换为当前宿主:Codex=`codex`、Claude Code=`claude`、Pi Agent=`pi`、DeepSeek Harness=`dsh`、WorkBuddy=`workbuddy`。DeepSeek Harness 和 WorkBuddy 若返回持久终端或后台任务句柄,只轮询该原始句柄直到进程退出,不另起状态命令推测完成。
|
|
17
|
+
|
|
16
18
|
`context resolve` 是无状态调用:单一工作空间直接返回上下文,多个候选返回组合选项;用户选择后由当前任务直接携带 team/region 参数,不执行 `context select`,不写本地 operation。所有可变 `call` 仍需先取得 confirmation ID,再以完全相同的输入追加 `--confirm` 执行一次。
|
|
17
19
|
|
|
18
20
|
`required` 只声明要解析的维度,企业 ID 始终来自当前登录身份。用户明确给出的 team/region 必须放进 `hints` 做精确匹配;不得把企业名、team 名或选择对象作为顶层 `enterprise` / `workspace` 字段传入。多候选时只展示 CLI 返回的 label;用户选择后再次执行同一个无状态 `context resolve`,通过 `selection.option_id` 让 CLI 重新查询并验证当前候选,不写本地 context 状态。
|
|
@@ -20,7 +22,7 @@ Codex 中命令工具一旦返回 `session_id`,必须立即对该 `session_id`
|
|
|
20
22
|
```json
|
|
21
23
|
{
|
|
22
24
|
"schema": "rainskills.single-runtime-contract.v1",
|
|
23
|
-
"package_version": "rainskills@0.1.
|
|
25
|
+
"package_version": "rainskills@0.1.29",
|
|
24
26
|
"runtime_status": [
|
|
25
27
|
"node",
|
|
26
28
|
"<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.29` 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 连接或修改服务器。
|
|
@@ -8,6 +8,10 @@ const path = require("node:path");
|
|
|
8
8
|
const tls = require("node:tls");
|
|
9
9
|
|
|
10
10
|
const { createSecureStateStore } = require("./secure-state.js");
|
|
11
|
+
const {
|
|
12
|
+
destinationsForHostTarget,
|
|
13
|
+
isHostTarget,
|
|
14
|
+
} = require("./host-targets.js");
|
|
11
15
|
|
|
12
16
|
const OFFICIAL_LATEST_URL = "https://registry.npmjs.org/rainskills/latest";
|
|
13
17
|
const OFFICIAL_REGISTRY = "https://registry.npmjs.org/";
|
|
@@ -735,7 +739,7 @@ function buildStableUpdateEnvironment(source, { fromVersion, targetVersion, regi
|
|
|
735
739
|
};
|
|
736
740
|
}
|
|
737
741
|
|
|
738
|
-
function resolveInstallDestinations(args, home = os.homedir()) {
|
|
742
|
+
function resolveInstallDestinations(args, home = os.homedir(), env = process.env) {
|
|
739
743
|
if (
|
|
740
744
|
!Array.isArray(args)
|
|
741
745
|
|| args.includes("--help")
|
|
@@ -745,21 +749,14 @@ function resolveInstallDestinations(args, home = os.homedir()) {
|
|
|
745
749
|
let target = "all";
|
|
746
750
|
let customDestination = "";
|
|
747
751
|
for (let index = 0; index < args.length; index += 1) {
|
|
748
|
-
if (
|
|
752
|
+
if (isHostTarget(args[index])) target = args[index];
|
|
749
753
|
if (args[index] === "--dest" && typeof args[index + 1] === "string") {
|
|
750
754
|
customDestination = path.resolve(args[index + 1]);
|
|
751
755
|
index += 1;
|
|
752
756
|
}
|
|
753
757
|
}
|
|
754
758
|
if (customDestination) return [customDestination];
|
|
755
|
-
|
|
756
|
-
if (target === "claude") return [path.join(home, ".claude", "skills")];
|
|
757
|
-
if (target === "pi") return [path.join(home, ".pi", "agent", "skills")];
|
|
758
|
-
return [
|
|
759
|
-
path.join(home, ".claude", "skills"),
|
|
760
|
-
path.join(home, ".codex", "skills"),
|
|
761
|
-
path.join(home, ".pi", "agent", "skills"),
|
|
762
|
-
];
|
|
759
|
+
return destinationsForHostTarget(target, home, env);
|
|
763
760
|
}
|
|
764
761
|
|
|
765
762
|
function recordSkillInstallDestinations(args, {
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const path = require("node:path");
|
|
4
|
+
|
|
5
|
+
const HOST_TARGETS = Object.freeze([
|
|
6
|
+
"codex",
|
|
7
|
+
"claude",
|
|
8
|
+
"pi",
|
|
9
|
+
"dsh",
|
|
10
|
+
"workbuddy",
|
|
11
|
+
"all",
|
|
12
|
+
]);
|
|
13
|
+
const HOST_TARGET_SET = new Set(HOST_TARGETS);
|
|
14
|
+
|
|
15
|
+
function isHostTarget(value) {
|
|
16
|
+
return HOST_TARGET_SET.has(value);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function telemetryClientForTarget(target) {
|
|
20
|
+
if (target === "claude") return "claude_code";
|
|
21
|
+
if (target === "dsh") return "deepseek_harness";
|
|
22
|
+
if (isHostTarget(target)) return target;
|
|
23
|
+
return "unknown";
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function dshSkillsDirectory(home, env = process.env) {
|
|
27
|
+
const dshHome = typeof env.DSH_HOME === "string" && env.DSH_HOME.trim()
|
|
28
|
+
? env.DSH_HOME.trim()
|
|
29
|
+
: path.join(home, ".dsh");
|
|
30
|
+
return path.join(path.resolve(dshHome), "skills");
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function workBuddySkillsDirectory(home, env = process.env) {
|
|
34
|
+
const configHome = typeof env.WORKBUDDY_CONFIG_DIR === "string"
|
|
35
|
+
&& env.WORKBUDDY_CONFIG_DIR.trim()
|
|
36
|
+
? env.WORKBUDDY_CONFIG_DIR.trim()
|
|
37
|
+
: path.join(home, ".workbuddy-ai");
|
|
38
|
+
return path.join(path.resolve(configHome), "skills");
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function destinationsForHostTarget(target, home, env = process.env) {
|
|
42
|
+
const destinations = {
|
|
43
|
+
claude: path.join(home, ".claude", "skills"),
|
|
44
|
+
codex: path.join(home, ".codex", "skills"),
|
|
45
|
+
pi: path.join(home, ".pi", "agent", "skills"),
|
|
46
|
+
dsh: dshSkillsDirectory(home, env),
|
|
47
|
+
workbuddy: workBuddySkillsDirectory(home, env),
|
|
48
|
+
};
|
|
49
|
+
if (target === "all") return Object.values(destinations);
|
|
50
|
+
if (Object.hasOwn(destinations, target)) return [destinations[target]];
|
|
51
|
+
throw new Error(`未知安装目标:${target}`);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
module.exports = {
|
|
55
|
+
HOST_TARGETS,
|
|
56
|
+
destinationsForHostTarget,
|
|
57
|
+
dshSkillsDirectory,
|
|
58
|
+
isHostTarget,
|
|
59
|
+
telemetryClientForTarget,
|
|
60
|
+
workBuddySkillsDirectory,
|
|
61
|
+
};
|
|
@@ -30,6 +30,7 @@ const {
|
|
|
30
30
|
verifyRecoveryBundle,
|
|
31
31
|
} = require("./windows-platform.js");
|
|
32
32
|
const { createLifecycleTelemetry } = require("./telemetry.js");
|
|
33
|
+
const { isHostTarget } = require("./host-targets.js");
|
|
33
34
|
const { installHostCluster } = require("./host-cluster-installer.js");
|
|
34
35
|
const { installExistingKubernetes } = require("./existing-kubernetes-installer.js");
|
|
35
36
|
|
|
@@ -249,7 +250,7 @@ function readOnboardingState(filePath, expectedOperationId, stateStore = secureS
|
|
|
249
250
|
if (!UUID_PATTERN.test(state.operation_id || "")) {
|
|
250
251
|
throw new Error("状态文件中的 operation_id 无效");
|
|
251
252
|
}
|
|
252
|
-
if (!
|
|
253
|
+
if (!isHostTarget(state.target)) {
|
|
253
254
|
throw new Error("状态文件中的安装目标无效");
|
|
254
255
|
}
|
|
255
256
|
if (state.deployment_mode !== "self-hosted") {
|
|
@@ -7,12 +7,13 @@ const { isDeepStrictEqual } = require("node:util");
|
|
|
7
7
|
|
|
8
8
|
const { createSecureStateStore } = require("./secure-state.js");
|
|
9
9
|
const { validateMcp } = require("./windows-client-config.js");
|
|
10
|
+
const { HOST_TARGETS } = require("./host-targets.js");
|
|
10
11
|
|
|
11
12
|
const RUNTIME_SCHEMA = "rainskills.runtime-connection.v1";
|
|
12
13
|
const STATUS_SCHEMA = "rainskills.runtime-status.v1";
|
|
13
14
|
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;
|
|
14
15
|
const STATES = new Set(["not_started", "connecting", "connected"]);
|
|
15
|
-
const TARGET_CLIENTS = new Set(
|
|
16
|
+
const TARGET_CLIENTS = new Set(HOST_TARGETS);
|
|
16
17
|
const ENVIRONMENT_KINDS = new Set(["saas", "private"]);
|
|
17
18
|
const RUNTIME_STATE_LOCK_ID = "cf1c1a85-63e7-45f8-9dd5-20ea1d511c48";
|
|
18
19
|
const STATE_FIELDS = new Set([
|
|
@@ -8,7 +8,9 @@ const path = require("node:path");
|
|
|
8
8
|
const DEFAULT_REPORT_URL = "https://log.rainbond.com/api/rainskills/lifecycle-events";
|
|
9
9
|
const DEFAULT_LEGACY_REPORT_URL = "https://log.rainbond.com/api/rainskills/installations";
|
|
10
10
|
const SCHEMA = "rainskills.lifecycle-event.v1";
|
|
11
|
-
const CLIENTS = new Set([
|
|
11
|
+
const CLIENTS = new Set([
|
|
12
|
+
"codex", "claude_code", "pi", "deepseek_harness", "workbuddy", "all", "both", "unknown",
|
|
13
|
+
]);
|
|
12
14
|
const PLATFORMS = new Set(["darwin", "linux", "win32"]);
|
|
13
15
|
const CONTROL_MODES = new Set(["posix", "wsl", "windows-native"]);
|
|
14
16
|
const TARGETS = new Set(["local-linux", "local-macos", "local-windows", "remote-linux"]);
|
|
@@ -18,6 +18,11 @@ const {
|
|
|
18
18
|
} = require("./windows-auth.js");
|
|
19
19
|
const { validateMcp } = require("./windows-client-config.js");
|
|
20
20
|
const { createLifecycleTelemetry } = require("./telemetry.js");
|
|
21
|
+
const {
|
|
22
|
+
destinationsForHostTarget,
|
|
23
|
+
isHostTarget,
|
|
24
|
+
telemetryClientForTarget,
|
|
25
|
+
} = require("./host-targets.js");
|
|
21
26
|
|
|
22
27
|
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;
|
|
23
28
|
const CONTROL_MODES = new Set(["windows-native", "wsl", "posix"]);
|
|
@@ -82,7 +87,7 @@ function parseWindowsInstallerArgs(argv) {
|
|
|
82
87
|
|
|
83
88
|
for (let index = 0; index < argv.length; index += 1) {
|
|
84
89
|
const argument = argv[index];
|
|
85
|
-
if (
|
|
90
|
+
if (isHostTarget(argument)) {
|
|
86
91
|
options.target = argument;
|
|
87
92
|
} else if (argument === "--dest") {
|
|
88
93
|
options.customDest = requireValue(argv, index, argument);
|
|
@@ -117,18 +122,8 @@ function parseWindowsInstallerArgs(argv) {
|
|
|
117
122
|
return options;
|
|
118
123
|
}
|
|
119
124
|
|
|
120
|
-
function destinationsForTarget(target, home) {
|
|
121
|
-
|
|
122
|
-
if (target === "claude") return [path.join(home, ".claude", "skills")];
|
|
123
|
-
if (target === "pi") return [path.join(home, ".pi", "agent", "skills")];
|
|
124
|
-
if (target === "all") {
|
|
125
|
-
return [
|
|
126
|
-
path.join(home, ".claude", "skills"),
|
|
127
|
-
path.join(home, ".codex", "skills"),
|
|
128
|
-
path.join(home, ".pi", "agent", "skills"),
|
|
129
|
-
];
|
|
130
|
-
}
|
|
131
|
-
throw new Error(`未知安装目标:${target}`);
|
|
125
|
+
function destinationsForTarget(target, home, env = process.env) {
|
|
126
|
+
return destinationsForHostTarget(target, home, env);
|
|
132
127
|
}
|
|
133
128
|
|
|
134
129
|
function validateSkillDirectory(directory) {
|
|
@@ -294,7 +289,7 @@ function createOnboardingCheckpoint({
|
|
|
294
289
|
stateStore,
|
|
295
290
|
}) {
|
|
296
291
|
if (!UUID_PATTERN.test(operationId)) throw new Error("operation id 不是有效的 UUID");
|
|
297
|
-
if (!
|
|
292
|
+
if (!isHostTarget(target)) throw new Error("安装目标无效");
|
|
298
293
|
const controlDistro = validateControl(control);
|
|
299
294
|
const store = stateStore || (
|
|
300
295
|
process.platform === "win32"
|
|
@@ -367,7 +362,7 @@ async function authorizeAndConfigure({
|
|
|
367
362
|
platform: "win32",
|
|
368
363
|
control_mode: process.env.RAINSKILLS_TELEMETRY_CONTROL_MODE || "windows-native",
|
|
369
364
|
target: process.env.RAINSKILLS_TELEMETRY_TARGET || "local-windows",
|
|
370
|
-
client: target,
|
|
365
|
+
client: telemetryClientForTarget(target),
|
|
371
366
|
action: "install",
|
|
372
367
|
},
|
|
373
368
|
});
|
|
@@ -450,7 +445,7 @@ async function authorizeAndConfigure({
|
|
|
450
445
|
});
|
|
451
446
|
}
|
|
452
447
|
|
|
453
|
-
if (!
|
|
448
|
+
if (!isHostTarget(target)) throw new Error("安装目标无效");
|
|
454
449
|
const cliUrl = `${baseUrl}/console/mcp/rainskills/api/query`;
|
|
455
450
|
telemetry.record({
|
|
456
451
|
lifecycle_phase: "configure_cli",
|
|
@@ -511,13 +506,24 @@ async function installLocalCli({ packageRoot, home }) {
|
|
|
511
506
|
async function promptTarget() {
|
|
512
507
|
const terminal = readline.createInterface({ input: stdin, output: stdout });
|
|
513
508
|
try {
|
|
514
|
-
stdout.write(
|
|
509
|
+
stdout.write(
|
|
510
|
+
"请选择要安装和配置的平台:\n"
|
|
511
|
+
+ " 1) Codex\n"
|
|
512
|
+
+ " 2) Claude Code\n"
|
|
513
|
+
+ " 3) Pi Agent\n"
|
|
514
|
+
+ " 4) DeepSeek Harness\n"
|
|
515
|
+
+ " 5) WorkBuddy\n"
|
|
516
|
+
+ " 6) 全部\n"
|
|
517
|
+
);
|
|
515
518
|
for (;;) {
|
|
516
|
-
const answer = (await terminal.question("请输入选项 [1-
|
|
519
|
+
const answer = (await terminal.question("请输入选项 [1-6]: ")).trim();
|
|
517
520
|
if (answer === "1") return "codex";
|
|
518
521
|
if (answer === "2") return "claude";
|
|
519
|
-
if (answer === "
|
|
520
|
-
|
|
522
|
+
if (answer === "3") return "pi";
|
|
523
|
+
if (answer === "4") return "dsh";
|
|
524
|
+
if (answer === "5") return "workbuddy";
|
|
525
|
+
if (answer === "" || answer === "6") return "all";
|
|
526
|
+
stdout.write("请输入 1、2、3、4、5 或 6。\n");
|
|
521
527
|
}
|
|
522
528
|
} finally {
|
|
523
529
|
terminal.close();
|
|
@@ -590,7 +596,7 @@ async function resolveDeployment(options, {
|
|
|
590
596
|
}
|
|
591
597
|
|
|
592
598
|
function usage() {
|
|
593
|
-
stdout.write("Usage: npx rainskills [codex|claude|pi|all] [options]\n");
|
|
599
|
+
stdout.write("Usage: npx rainskills [codex|claude|pi|dsh|workbuddy|all] [options]\n");
|
|
594
600
|
}
|
|
595
601
|
|
|
596
602
|
async function main(argv, dependencies = {}) {
|
|
@@ -600,6 +606,7 @@ async function main(argv, dependencies = {}) {
|
|
|
600
606
|
return { status: "help" };
|
|
601
607
|
}
|
|
602
608
|
const home = dependencies.home || os.homedir();
|
|
609
|
+
const environment = dependencies.env || process.env;
|
|
603
610
|
const packageRoot = dependencies.packageRoot || path.resolve(__dirname, "..", "..");
|
|
604
611
|
const target = options.target || (
|
|
605
612
|
options.nonInteractive || !stdin.isTTY
|
|
@@ -608,7 +615,7 @@ async function main(argv, dependencies = {}) {
|
|
|
608
615
|
);
|
|
609
616
|
const destinations = options.customDest
|
|
610
617
|
? [path.resolve(options.customDest)]
|
|
611
|
-
: destinationsForTarget(target, home);
|
|
618
|
+
: destinationsForTarget(target, home, environment);
|
|
612
619
|
const skills = discoverSkills(packageRoot);
|
|
613
620
|
const logger = dependencies.logger || ((message) => stdout.write(`${message}\n`));
|
|
614
621
|
const detailLogger = options.verbose ? logger : () => {};
|
|
@@ -16,6 +16,8 @@ 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
|
+
固定 contract 中的 `<target>` 必须替换为当前宿主:Codex=`codex`、Claude Code=`claude`、Pi Agent=`pi`、DeepSeek Harness=`dsh`、WorkBuddy=`workbuddy`。DeepSeek Harness 和 WorkBuddy 若返回持久终端或后台任务句柄,只轮询该原始句柄直到进程退出,不另起状态命令推测完成。
|
|
20
|
+
|
|
19
21
|
`context resolve` 是无状态调用:单一工作空间直接返回上下文,多个候选返回组合选项;用户选择后由当前任务直接携带 team/region 参数,不执行 `context select`,不写本地 operation。所有可变 `call` 仍需先取得 confirmation ID,再以完全相同的输入追加 `--confirm` 执行一次。
|
|
20
22
|
|
|
21
23
|
`required` 只声明要解析的维度,企业 ID 始终来自当前登录身份。用户明确给出的 team/region 必须放进 `hints` 做精确匹配;不得把企业名、team 名或选择对象作为顶层 `enterprise` / `workspace` 字段传入。多候选时只展示 CLI 返回的 label;用户选择后再次执行同一个无状态 `context resolve`,通过 `selection.option_id` 让 CLI 重新查询并验证当前候选,不写本地 context 状态。
|
|
@@ -23,7 +25,7 @@ Codex 中命令工具一旦返回 `session_id`,必须立即对该 `session_id`
|
|
|
23
25
|
```json
|
|
24
26
|
{
|
|
25
27
|
"schema": "rainskills.single-runtime-contract.v1",
|
|
26
|
-
"package_version": "rainskills@0.1.
|
|
28
|
+
"package_version": "rainskills@0.1.29",
|
|
27
29
|
"runtime_status": [
|
|
28
30
|
"node",
|
|
29
31
|
"<home>/.rainbond/lib/rainskills/bin/rainskills.js",
|
|
@@ -25,6 +25,8 @@ 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
|
+
固定 contract 中的 `<target>` 必须替换为当前宿主:Codex=`codex`、Claude Code=`claude`、Pi Agent=`pi`、DeepSeek Harness=`dsh`、WorkBuddy=`workbuddy`。DeepSeek Harness 和 WorkBuddy 若返回持久终端或后台任务句柄,只轮询该原始句柄直到进程退出,不另起状态命令推测完成。
|
|
29
|
+
|
|
28
30
|
`context resolve` 是无状态调用:单一工作空间直接返回上下文,多个候选返回组合选项;用户选择后由当前任务直接携带 team/region 参数,不执行 `context select`,不写本地 operation。所有可变 `call` 仍需先取得 confirmation ID,再以完全相同的输入追加 `--confirm` 执行一次。
|
|
29
31
|
|
|
30
32
|
`required` 只声明要解析的维度,企业 ID 始终来自当前登录身份。用户明确给出的 team/region 必须放进 `hints` 做精确匹配;不得把企业名、team 名或选择对象作为顶层 `enterprise` / `workspace` 字段传入。多候选时只展示 CLI 返回的 label;用户选择后再次执行同一个无状态 `context resolve`,通过 `selection.option_id` 让 CLI 重新查询并验证当前候选,不写本地 context 状态。
|
|
@@ -32,7 +34,7 @@ Codex 中命令工具一旦返回 `session_id`,必须立即对该 `session_id`
|
|
|
32
34
|
```json
|
|
33
35
|
{
|
|
34
36
|
"schema": "rainskills.single-runtime-contract.v1",
|
|
35
|
-
"package_version": "rainskills@0.1.
|
|
37
|
+
"package_version": "rainskills@0.1.29",
|
|
36
38
|
"runtime_status": [
|
|
37
39
|
"node",
|
|
38
40
|
"<home>/.rainbond/lib/rainskills/bin/rainskills.js",
|
|
@@ -25,6 +25,8 @@ 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
|
+
固定 contract 中的 `<target>` 必须替换为当前宿主:Codex=`codex`、Claude Code=`claude`、Pi Agent=`pi`、DeepSeek Harness=`dsh`、WorkBuddy=`workbuddy`。DeepSeek Harness 和 WorkBuddy 若返回持久终端或后台任务句柄,只轮询该原始句柄直到进程退出,不另起状态命令推测完成。
|
|
29
|
+
|
|
28
30
|
`context resolve` 是无状态调用:单一工作空间直接返回上下文,多个候选返回组合选项;用户选择后由当前任务直接携带 team/region 参数,不执行 `context select`,不写本地 operation。所有可变 `call` 仍需先取得 confirmation ID,再以完全相同的输入追加 `--confirm` 执行一次。
|
|
29
31
|
|
|
30
32
|
`required` 只声明要解析的维度,企业 ID 始终来自当前登录身份。用户明确给出的 team/region 必须放进 `hints` 做精确匹配;不得把企业名、team 名或选择对象作为顶层 `enterprise` / `workspace` 字段传入。多候选时只展示 CLI 返回的 label;用户选择后再次执行同一个无状态 `context resolve`,通过 `selection.option_id` 让 CLI 重新查询并验证当前候选,不写本地 context 状态。
|
|
@@ -32,7 +34,7 @@ Codex 中命令工具一旦返回 `session_id`,必须立即对该 `session_id`
|
|
|
32
34
|
```json
|
|
33
35
|
{
|
|
34
36
|
"schema": "rainskills.single-runtime-contract.v1",
|
|
35
|
-
"package_version": "rainskills@0.1.
|
|
37
|
+
"package_version": "rainskills@0.1.29",
|
|
36
38
|
"runtime_status": [
|
|
37
39
|
"node",
|
|
38
40
|
"<home>/.rainbond/lib/rainskills/bin/rainskills.js",
|