rainskills 0.1.19 → 0.1.21
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 +34 -39
- package/SKILL.md +12 -10
- package/bin/rainskills-tools.js +114 -240
- package/bin/rainskills.js +134 -591
- package/install.sh +68 -94
- package/marketplace/rainskills/.claude-plugin/plugin.json +1 -1
- package/marketplace/rainskills/.codex-plugin/plugin.json +1 -1
- package/marketplace/rainskills/skills/rainskills/SKILL.md +13 -11
- package/package.json +2 -2
- package/rainbond-app-assistant/SKILL.md +116 -151
- package/rainbond-app-version-assistant/SKILL.md +98 -98
- package/rainbond-delivery-verifier/SKILL.md +98 -68
- package/rainbond-env-sync/SKILL.md +98 -69
- package/rainbond-fullstack-bootstrap/SKILL.md +101 -89
- package/rainbond-fullstack-bootstrap/modules/10-context-loading.md +1 -1
- package/rainbond-fullstack-troubleshooter/SKILL.md +98 -68
- package/rainbond-opensource-app-deploy/SKILL.md +102 -81
- package/rainbond-platform-installer/SKILL.md +4 -4
- package/rainbond-platform-installer/scripts/auto-update.js +0 -9
- package/rainbond-platform-installer/scripts/installed-version.js +1 -1
- package/rainbond-platform-installer/scripts/platform-installer.js +3 -89
- package/rainbond-platform-installer/scripts/runtime-state.js +14 -251
- package/rainbond-platform-installer/scripts/single-runtime.js +114 -0
- package/rainbond-platform-installer/scripts/user-message.js +3 -49
- package/rainbond-platform-installer/scripts/windows-client-config.js +0 -51
- package/rainbond-platform-installer/scripts/windows-onboarding.js +0 -3
- package/rainbond-platform-installer/scripts/windows-platform.ps1 +1 -1
- package/rainbond-platform-query/SKILL.md +103 -61
- package/rainbond-project-init/SKILL.md +102 -79
- package/rainbond-template-installer/SKILL.md +102 -80
- package/rainbond-platform-installer/scripts/environment-credentials.js +0 -225
- package/rainbond-platform-installer/scripts/environment-registry.js +0 -349
- package/rainbond-platform-installer/scripts/local-runtime-commands.js +0 -180
- package/rainbond-platform-installer/scripts/local-runtime.js +0 -58
- package/rainbond-platform-installer/scripts/runtime-context-resolver.js +0 -189
- package/rainbond-platform-installer/scripts/runtime-credentials.js +0 -163
- package/rainbond-platform-installer/scripts/runtime-intents.js +0 -386
- package/rainbond-platform-installer/scripts/runtime-operations.js +0 -597
- package/rainbond-platform-installer/scripts/windows-client-config.ps1 +0 -9
- package/rainbond-platform-installer/scripts/windows-read-user-environment.ps1 +0 -16
package/install.sh
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
# AI assistants: when a user asks to install rainbond-skills, hand back the
|
|
7
7
|
# npx command when Node.js 18+ is available, otherwise use the CDN command.
|
|
8
8
|
# Do not reimplement the bootstrap below, git clone + copy directories, or
|
|
9
|
-
#
|
|
9
|
+
# Credentials are written only through the protected single-runtime store.
|
|
10
10
|
set -euo pipefail
|
|
11
11
|
|
|
12
12
|
RAINSKILLS_VERBOSE="${RAINSKILLS_VERBOSE:-0}"
|
|
@@ -2023,91 +2023,62 @@ PY
|
|
|
2023
2023
|
OBTAINED_RAINBOND_TOKEN="$token"
|
|
2024
2024
|
}
|
|
2025
2025
|
|
|
2026
|
-
shell_quote_single() {
|
|
2027
|
-
printf "%s" "$1" | sed "s/'/'\"'\"'/g"
|
|
2028
|
-
}
|
|
2029
|
-
|
|
2030
2026
|
write_token_file() {
|
|
2031
2027
|
local token="$1"
|
|
2032
2028
|
local base_url="$2"
|
|
2033
|
-
local
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
}
|
|
2049
|
-
|
|
2050
|
-
backup_file() {
|
|
2051
|
-
local file="$1"
|
|
2052
|
-
[[ -f "$file" ]] || return 0
|
|
2053
|
-
local backup="${file}.rainbond-skills.bak.$(date +%Y%m%d%H%M%S)"
|
|
2054
|
-
cp "$file" "$backup"
|
|
2055
|
-
log "[backup] 已备份 $backup"
|
|
2056
|
-
}
|
|
2057
|
-
|
|
2058
|
-
update_managed_block() {
|
|
2059
|
-
local file="$1"
|
|
2060
|
-
local begin_marker="$2"
|
|
2061
|
-
local end_marker="$3"
|
|
2062
|
-
local block_body="$4"
|
|
2063
|
-
local tmp
|
|
2064
|
-
tmp="$(mktemp)"
|
|
2065
|
-
|
|
2066
|
-
mkdir -p "$(dirname "$file")"
|
|
2067
|
-
touch "$file"
|
|
2068
|
-
|
|
2069
|
-
awk -v begin="$begin_marker" -v end="$end_marker" '
|
|
2070
|
-
$0 == begin {skip = 1; next}
|
|
2071
|
-
$0 == end {skip = 0; next}
|
|
2072
|
-
!skip {print}
|
|
2073
|
-
' "$file" > "$tmp"
|
|
2074
|
-
|
|
2075
|
-
if [[ -s "$tmp" ]]; then
|
|
2076
|
-
printf '\n' >> "$tmp"
|
|
2077
|
-
fi
|
|
2078
|
-
printf '%s\n%s\n%s\n' "$begin_marker" "$block_body" "$end_marker" >> "$tmp"
|
|
2079
|
-
mv "$tmp" "$file"
|
|
2080
|
-
}
|
|
2081
|
-
|
|
2082
|
-
detect_shell_rc_file() {
|
|
2083
|
-
local shell_name
|
|
2084
|
-
shell_name="$(basename "${SHELL:-zsh}")"
|
|
2085
|
-
|
|
2086
|
-
case "$shell_name" in
|
|
2087
|
-
zsh)
|
|
2088
|
-
printf '%s\n' "$HOME/.zshrc"
|
|
2089
|
-
;;
|
|
2090
|
-
bash)
|
|
2091
|
-
printf '%s\n' "$HOME/.bashrc"
|
|
2092
|
-
;;
|
|
2093
|
-
*)
|
|
2094
|
-
printf '%s\n' "$HOME/.profile"
|
|
2095
|
-
;;
|
|
2096
|
-
esac
|
|
2097
|
-
}
|
|
2098
|
-
|
|
2099
|
-
configure_shell_autoload() {
|
|
2100
|
-
local token_file="$HOME/.rainbond/mcp.env"
|
|
2101
|
-
local rc_file
|
|
2102
|
-
rc_file="$(detect_shell_rc_file)"
|
|
2103
|
-
local begin_marker="# >>> rainbond skills mcp >>>"
|
|
2104
|
-
local end_marker="# <<< rainbond skills mcp <<<"
|
|
2105
|
-
local block='[ -f "$HOME/.rainbond/mcp.env" ] && source "$HOME/.rainbond/mcp.env"'
|
|
2029
|
+
local kind="private"
|
|
2030
|
+
if [[ "$base_url" == "$SAAS_DEFAULT_URL" ]]; then
|
|
2031
|
+
kind="saas"
|
|
2032
|
+
fi
|
|
2033
|
+
local allow_insecure_http="false"
|
|
2034
|
+
[[ "$base_url" == http://* ]] && allow_insecure_http="true"
|
|
2035
|
+
RAINBOND_JWT="$token" RAINBOND_URL="$base_url" RAINSKILLS_RUNTIME_KIND="$kind" \
|
|
2036
|
+
RAINSKILLS_ALLOW_INSECURE_HTTP="$allow_insecure_http" python3 - "$HOME" <<'PY' \
|
|
2037
|
+
|| die "Rainbond 单运行环境凭据写入失败。"
|
|
2038
|
+
import datetime
|
|
2039
|
+
import json
|
|
2040
|
+
import os
|
|
2041
|
+
import pathlib
|
|
2042
|
+
import secrets
|
|
2043
|
+
import sys
|
|
2106
2044
|
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2045
|
+
home = pathlib.Path(sys.argv[1]).resolve()
|
|
2046
|
+
directory = home / ".rainbond" / "rainskills"
|
|
2047
|
+
target = directory / "single-runtime-v1.json"
|
|
2048
|
+
directory.mkdir(parents=True, exist_ok=True, mode=0o700)
|
|
2049
|
+
os.chmod(directory, 0o700)
|
|
2050
|
+
now = datetime.datetime.now(datetime.timezone.utc).isoformat(timespec="milliseconds").replace("+00:00", "Z")
|
|
2051
|
+
created_at = now
|
|
2052
|
+
if target.exists():
|
|
2053
|
+
with target.open("r", encoding="utf-8") as stream:
|
|
2054
|
+
current = json.load(stream)
|
|
2055
|
+
if isinstance(current.get("created_at"), str):
|
|
2056
|
+
created_at = current["created_at"]
|
|
2057
|
+
payload = {
|
|
2058
|
+
"schema": "rainskills.single-runtime.v1",
|
|
2059
|
+
"version": 1,
|
|
2060
|
+
"console_origin": os.environ["RAINBOND_URL"],
|
|
2061
|
+
"kind": os.environ["RAINSKILLS_RUNTIME_KIND"],
|
|
2062
|
+
"token": os.environ["RAINBOND_JWT"],
|
|
2063
|
+
"allow_insecure_http": os.environ["RAINSKILLS_ALLOW_INSECURE_HTTP"] == "true",
|
|
2064
|
+
"created_at": created_at,
|
|
2065
|
+
"updated_at": now,
|
|
2066
|
+
}
|
|
2067
|
+
temporary = directory / (".single-runtime-v1.json." + secrets.token_hex(8))
|
|
2068
|
+
descriptor = os.open(temporary, os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o600)
|
|
2069
|
+
try:
|
|
2070
|
+
with os.fdopen(descriptor, "w", encoding="utf-8") as stream:
|
|
2071
|
+
json.dump(payload, stream, ensure_ascii=False, indent=2)
|
|
2072
|
+
stream.write("\n")
|
|
2073
|
+
stream.flush()
|
|
2074
|
+
os.fsync(stream.fileno())
|
|
2075
|
+
os.replace(temporary, target)
|
|
2076
|
+
os.chmod(target, 0o600)
|
|
2077
|
+
finally:
|
|
2078
|
+
if temporary.exists():
|
|
2079
|
+
temporary.unlink()
|
|
2080
|
+
PY
|
|
2081
|
+
log "[write] 已写入受保护的单运行环境凭据"
|
|
2111
2082
|
}
|
|
2112
2083
|
|
|
2113
2084
|
validate_mcp_connectivity() {
|
|
@@ -2378,7 +2349,7 @@ obtain_rainbond_token() {
|
|
|
2378
2349
|
die "--token 提供的值不是合法的 JWT(应形如 xxx.yyy.zzz)。"
|
|
2379
2350
|
fi
|
|
2380
2351
|
warn "RAINBOND_JWT 不是合法的 JWT(应形如 xxx.yyy.zzz);忽略并改走浏览器登录。"
|
|
2381
|
-
warn "
|
|
2352
|
+
warn "检测到无效的 RAINBOND_JWT;将忽略并重新登录。"
|
|
2382
2353
|
RAINBOND_TOKEN_INPUT=""
|
|
2383
2354
|
elif [[ "$RAINBOND_TOKEN_FROM_FLAG" -eq 1 ]]; then
|
|
2384
2355
|
check_reusable_token_or_clear "--token 提供的 Rainbond JWT" || true
|
|
@@ -2444,14 +2415,19 @@ obtain_rainbond_token() {
|
|
|
2444
2415
|
}
|
|
2445
2416
|
|
|
2446
2417
|
read_cached_rainbond_url() {
|
|
2447
|
-
local
|
|
2448
|
-
[[ -f "$
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2418
|
+
local runtime_file="$HOME/.rainbond/rainskills/single-runtime-v1.json"
|
|
2419
|
+
[[ -f "$runtime_file" ]] || return 1
|
|
2420
|
+
python3 - "$runtime_file" <<'PY'
|
|
2421
|
+
import json
|
|
2422
|
+
import sys
|
|
2423
|
+
|
|
2424
|
+
with open(sys.argv[1], "r", encoding="utf-8") as stream:
|
|
2425
|
+
payload = json.load(stream)
|
|
2426
|
+
origin = payload.get("console_origin")
|
|
2427
|
+
if not isinstance(origin, str) or not origin:
|
|
2428
|
+
raise SystemExit(1)
|
|
2429
|
+
print(origin)
|
|
2430
|
+
PY
|
|
2455
2431
|
}
|
|
2456
2432
|
|
|
2457
2433
|
do_refresh() {
|
|
@@ -2471,7 +2447,7 @@ do_refresh() {
|
|
|
2471
2447
|
cached_url="$(read_cached_rainbond_url 2>/dev/null || true)"
|
|
2472
2448
|
if [[ -n "$cached_url" ]]; then
|
|
2473
2449
|
RAINBOND_URL_INPUT="$cached_url"
|
|
2474
|
-
log "[refresh]
|
|
2450
|
+
log "[refresh] 使用单运行环境中已记录的地址:$cached_url"
|
|
2475
2451
|
fi
|
|
2476
2452
|
fi
|
|
2477
2453
|
|
|
@@ -2511,7 +2487,6 @@ do_refresh() {
|
|
|
2511
2487
|
|
|
2512
2488
|
export RAINBOND_JWT="$token"
|
|
2513
2489
|
write_token_file "$token" "$base_url"
|
|
2514
|
-
configure_shell_autoload
|
|
2515
2490
|
set_rainskills_failure_context "configuration" "cli_configuration_failed"
|
|
2516
2491
|
report_rainskills_lifecycle_event "configure_cli" "install_cli" "configure_cli" "started"
|
|
2517
2492
|
install_local_cli
|
|
@@ -2595,7 +2570,6 @@ configure_runtime_connection() {
|
|
|
2595
2570
|
|| die "runtime connect 凭据安全写入失败。"
|
|
2596
2571
|
else
|
|
2597
2572
|
write_token_file "$token" "$base_url"
|
|
2598
|
-
configure_shell_autoload
|
|
2599
2573
|
fi
|
|
2600
2574
|
|
|
2601
2575
|
set_rainskills_failure_context "configuration" "cli_configuration_failed"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: rainskills
|
|
3
|
-
description: Use when a user asks to install, set up, initialize, update, repair, start using Rainskills, or
|
|
3
|
+
description: Use when a user asks to install, set up, initialize, update, repair, start using Rainskills, or connect, reconnect, inspect, or replace the single Rainskills runtime.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Rainskills
|
|
@@ -14,11 +14,11 @@ This is the single marketplace entry for the complete Rainskills product. The in
|
|
|
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.21 <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
|
|
|
21
|
-
执行优化:同一会话内只检查一次 Node.js
|
|
21
|
+
执行优化:同一会话内只检查一次 Node.js 和运行环境状态;仅在 Node.js、Rainskills 或唯一运行环境发生变化后失效。固定 launcher 和 argv 已在本 Skill 中,禁止读取、搜索或探测 `rainskills.js`,也禁止执行 `npm root -g`。
|
|
22
22
|
|
|
23
23
|
## Completion Message
|
|
24
24
|
|
|
@@ -38,18 +38,20 @@ Rainskills 安装完成,下一条消息即可直接使用。
|
|
|
38
38
|
也可以直接告诉我你想部署什么应用。
|
|
39
39
|
```
|
|
40
40
|
|
|
41
|
-
## Manage Runtime
|
|
41
|
+
## Manage the Single Runtime
|
|
42
42
|
|
|
43
43
|
受限沙箱(包括 Codex)执行本地状态命令时,必须申请用户级受保护目录访问权限;在 Codex 中使用 `require_escalated`。不得修改 `~/.rainbond` 权限、复制受保护状态到工作区,或因沙箱权限错误建议重装。
|
|
44
44
|
|
|
45
45
|
涉及浏览器或设备授权的 `runtime connect`,以及恢复/安装场景中的 `rainskills <target> --self-hosted`,必须在附加交互终端(TTY)中运行;在 Codex 中设置 `tty: true` 并保持进程附着直到授权完成。禁止通过非交互命令要求用户粘贴 JWT;非交互模式只可复用已存在的受保护凭据。
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
Rainskills 只保存一个全局运行环境,不维护环境列表、名称、默认值或环境 ID。使用固定 launcher `node <home>/.rainbond/lib/rainskills/bin/rainskills.js`(运行包版本 `rainskills@0.1.21`):
|
|
48
48
|
|
|
49
|
-
-
|
|
50
|
-
-
|
|
51
|
-
-
|
|
52
|
-
-
|
|
53
|
-
-
|
|
49
|
+
- 状态:执行 `runtime status --json`。
|
|
50
|
+
- 首次连接:执行 `runtime connect <target> --saas` 或 `runtime connect <target> --rainbond-url <Console origin>`。
|
|
51
|
+
- 安装私有环境:执行 `runtime connect <target> --install-private --location local|server`。
|
|
52
|
+
- 重新授权:执行 `runtime reconnect <target>`;必须进入浏览器 Device Flow,不复用 Shell 中缓存的 JWT。
|
|
53
|
+
- 更换环境:明确告知用户会替换当前唯一环境;新授权和 live probe 成功后再覆盖凭据。
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
所有 Rainbond 查询和变更继续通过 `~/.rainbond/bin/rainskills-tools.js`。不得配置客户端 MCP,也不得恢复环境枚举、业务 operation 生命周期、环境 ID 或 intent 恢复协议。
|
|
56
|
+
|
|
57
|
+
业务 CLI 默认只读取受保护的唯一运行环境文件,忽略 Shell 中遗留的 `RAINBOND_URL` / `RAINBOND_JWT`。CI 若要显式使用环境变量凭据,必须同时设置 `RAINSKILLS_CREDENTIAL_SOURCE=environment`。
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rainskills",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.21",
|
|
4
4
|
"description": "Interactive Rainbond skill installer for Codex, Claude Code, and Pi Agent",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://github.com/goodrain/rainskills#readme",
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
"test:runtime-version": "node --test tests/runtime-version-sync.test.js",
|
|
65
65
|
"test:runtime-contracts": "node scripts/sync-runtime-contracts.mjs --check",
|
|
66
66
|
"test:auto-update": "node --test tests/auto-update.test.js",
|
|
67
|
-
"test:launcher": "node --test tests/console-origin.test.js tests/
|
|
67
|
+
"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",
|
|
68
68
|
"test:api-bridge": "node --test tests/api-bridge.test.js",
|
|
69
69
|
"test:console-contract": "python3 tests/console_tool_contract_test.py",
|
|
70
70
|
"test:skill-profile": "node --test tests/skill-profile-builder.test.js tests/markdown-link-integrity.test.js",
|
|
@@ -88,153 +88,124 @@ description: "Use whenever a user asks to deploy, run, deliver, publish, inspect
|
|
|
88
88
|
<!-- rainskills-user-result:end -->
|
|
89
89
|
|
|
90
90
|
<!-- rainskills-runtime-gate:start -->
|
|
91
|
-
##
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
"
|
|
126
|
-
"
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
"
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
"
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
"
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
"
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
"
|
|
156
|
-
"
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
"operation": "summary",
|
|
164
|
-
"app_id": "app"
|
|
165
|
-
}
|
|
166
|
-
},
|
|
167
|
-
"troubleshoot": {
|
|
168
|
-
"type": "troubleshoot",
|
|
169
|
-
"required": ["type", "operation"],
|
|
170
|
-
"optional": ["team_id", "app_id", "service_id"],
|
|
171
|
-
"enums": {
|
|
172
|
-
"operation": ["auto", "build", "runtime", "access"]
|
|
173
|
-
},
|
|
174
|
-
"example": {
|
|
175
|
-
"type": "troubleshoot",
|
|
176
|
-
"operation": "build",
|
|
177
|
-
"app_id": "app"
|
|
178
|
-
}
|
|
179
|
-
},
|
|
180
|
-
"modify": {
|
|
181
|
-
"type": "modify",
|
|
182
|
-
"required": ["type", "team_id", "app_id", "operation"],
|
|
183
|
-
"optional": ["service_id"],
|
|
184
|
-
"enums": {
|
|
185
|
-
"operation": ["component-config", "build-source", "ports", "env", "storage", "dependency"]
|
|
186
|
-
},
|
|
187
|
-
"example": {
|
|
188
|
-
"type": "modify",
|
|
189
|
-
"team_id": "team",
|
|
190
|
-
"app_id": "app",
|
|
191
|
-
"operation": "env"
|
|
192
|
-
}
|
|
91
|
+
## 单运行环境 CLI 门禁(最高优先级)
|
|
92
|
+
|
|
93
|
+
本机只允许连接一个 Rainbond 运行环境。当前 Skill 在本会话第一次调用 Rainbond 前,执行固定 launcher 的 `runtime status --json`。返回 `connected` 且 `usable=true` 后,所有查询和变更直接通过本地 `~/.rainbond/bin/rainskills-tools.js` 执行。不得配置或直接调用客户端 MCP,不得执行环境枚举或业务 operation 生命周期命令,也不得生成或传递运行环境 ID、业务 operation ID 或 intent JSON。
|
|
94
|
+
|
|
95
|
+
没有运行环境时,让用户选择 Rainbond Cloud 或一个已有/新建的私有 Rainbond,并执行对应的 `runtime connect`。连接和重新授权必须进入浏览器 Device Flow,不复用 Shell 中缓存的 JWT;新凭据通过 live probe 后才覆盖唯一运行环境。CLI 返回 401 时,只读调用可在 `runtime reconnect` 成功后重试一次;写调用不得自动重放,必须先查询平台真实状态。403 直接停止,不重新授权。
|
|
96
|
+
|
|
97
|
+
`context resolve` 是无状态调用:单一工作空间直接返回上下文,多个候选返回组合选项;用户选择后由当前任务直接携带 team/region 参数,不执行 `context select`,不写本地 operation。所有可变 `call` 仍需先取得 confirmation ID,再以完全相同的输入追加 `--confirm` 执行一次。
|
|
98
|
+
|
|
99
|
+
```json
|
|
100
|
+
{
|
|
101
|
+
"schema": "rainskills.single-runtime-contract.v1",
|
|
102
|
+
"package_version": "rainskills@0.1.21",
|
|
103
|
+
"runtime_status": [
|
|
104
|
+
"node",
|
|
105
|
+
"<home>/.rainbond/lib/rainskills/bin/rainskills.js",
|
|
106
|
+
"runtime",
|
|
107
|
+
"status",
|
|
108
|
+
"--json"
|
|
109
|
+
],
|
|
110
|
+
"runtime_connect": {
|
|
111
|
+
"saas": [
|
|
112
|
+
"node",
|
|
113
|
+
"<home>/.rainbond/lib/rainskills/bin/rainskills.js",
|
|
114
|
+
"runtime",
|
|
115
|
+
"connect",
|
|
116
|
+
"<target>",
|
|
117
|
+
"--saas"
|
|
118
|
+
],
|
|
119
|
+
"private_existing": [
|
|
120
|
+
"node",
|
|
121
|
+
"<home>/.rainbond/lib/rainskills/bin/rainskills.js",
|
|
122
|
+
"runtime",
|
|
123
|
+
"connect",
|
|
124
|
+
"<target>",
|
|
125
|
+
"--rainbond-url",
|
|
126
|
+
"<console-origin>"
|
|
127
|
+
],
|
|
128
|
+
"install_private": [
|
|
129
|
+
"node",
|
|
130
|
+
"<home>/.rainbond/lib/rainskills/bin/rainskills.js",
|
|
131
|
+
"runtime",
|
|
132
|
+
"connect",
|
|
133
|
+
"<target>",
|
|
134
|
+
"--install-private",
|
|
135
|
+
"--location",
|
|
136
|
+
"<local-or-server>"
|
|
137
|
+
],
|
|
138
|
+
"reconnect": [
|
|
139
|
+
"node",
|
|
140
|
+
"<home>/.rainbond/lib/rainskills/bin/rainskills.js",
|
|
141
|
+
"runtime",
|
|
142
|
+
"reconnect",
|
|
143
|
+
"<target>"
|
|
144
|
+
]
|
|
145
|
+
},
|
|
146
|
+
"input_commands": {
|
|
147
|
+
"context_resolve": {
|
|
148
|
+
"argv": [
|
|
149
|
+
"node",
|
|
150
|
+
"<home>/.rainbond/bin/rainskills-tools.js",
|
|
151
|
+
"context",
|
|
152
|
+
"resolve",
|
|
153
|
+
"--input",
|
|
154
|
+
"-",
|
|
155
|
+
"--skill-id",
|
|
156
|
+
"rainbond-app-assistant"
|
|
157
|
+
],
|
|
158
|
+
"stdin": {
|
|
159
|
+
"required": [
|
|
160
|
+
"enterprise",
|
|
161
|
+
"workspace"
|
|
162
|
+
]
|
|
193
163
|
}
|
|
194
164
|
},
|
|
195
|
-
"
|
|
196
|
-
"
|
|
197
|
-
|
|
165
|
+
"read": {
|
|
166
|
+
"argv": [
|
|
167
|
+
"node",
|
|
168
|
+
"<home>/.rainbond/bin/rainskills-tools.js",
|
|
169
|
+
"read",
|
|
170
|
+
"<tool>",
|
|
171
|
+
"--input",
|
|
172
|
+
"-",
|
|
173
|
+
"--skill-id",
|
|
174
|
+
"rainbond-app-assistant"
|
|
175
|
+
],
|
|
176
|
+
"stdin_schema_source": "tool-catalog"
|
|
198
177
|
},
|
|
199
|
-
"
|
|
200
|
-
"
|
|
201
|
-
|
|
202
|
-
|
|
178
|
+
"call": {
|
|
179
|
+
"argv": [
|
|
180
|
+
"node",
|
|
181
|
+
"<home>/.rainbond/bin/rainskills-tools.js",
|
|
182
|
+
"call",
|
|
183
|
+
"<tool>",
|
|
184
|
+
"--input",
|
|
185
|
+
"-",
|
|
186
|
+
"--skill-id",
|
|
187
|
+
"rainbond-app-assistant"
|
|
188
|
+
],
|
|
189
|
+
"stdin_schema_source": "tool-catalog"
|
|
203
190
|
},
|
|
204
|
-
"
|
|
205
|
-
"
|
|
206
|
-
"
|
|
207
|
-
"
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
"
|
|
213
|
-
"
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
"read": {
|
|
219
|
-
"argv": ["node", "<home>/.rainbond/bin/rainskills-tools.js", "read", "<tool>", "--input", "-", "--operation-id", "<uuid>", "--skill-id", "rainbond-app-assistant"],
|
|
220
|
-
"stdin_schema_source": "tool-catalog"
|
|
221
|
-
},
|
|
222
|
-
"call": {
|
|
223
|
-
"argv": ["node", "<home>/.rainbond/bin/rainskills-tools.js", "call", "<tool>", "--input", "-", "--operation-id", "<uuid>", "--skill-id", "rainbond-app-assistant"],
|
|
224
|
-
"stdin_schema_source": "tool-catalog"
|
|
225
|
-
}
|
|
191
|
+
"call_confirm": {
|
|
192
|
+
"argv": [
|
|
193
|
+
"node",
|
|
194
|
+
"<home>/.rainbond/bin/rainskills-tools.js",
|
|
195
|
+
"call",
|
|
196
|
+
"<tool>",
|
|
197
|
+
"--input",
|
|
198
|
+
"-",
|
|
199
|
+
"--skill-id",
|
|
200
|
+
"rainbond-app-assistant",
|
|
201
|
+
"--confirm",
|
|
202
|
+
"<confirmation-id>"
|
|
203
|
+
],
|
|
204
|
+
"stdin_schema_source": "same-confirmed-input"
|
|
226
205
|
}
|
|
227
206
|
}
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
`deploy`/`create` 含 `service_id` 时属于 existing,否则属于 new;`query`、`troubleshoot`、`modify` 始终属于 existing。意图不明确时先澄清,不执行 connect。target 只允许 `codex`、`claude`、`pi`、`all`。连接前校验 intent,只执行其 scope 在契约中允许的完整 argv。只消费 schema 为 `rainskills.next-action.v1` 且完成字段校验后的 `argv` 数组。
|
|
232
|
-
|
|
233
|
-
连接或平台安装完成后,用固定 `onboarding-id` 执行 launcher + `["intent", "resume", "--onboarding-id", "<同一 onboarding-id>"]`,恢复原始 intent 和 `resume_step`,不得重新猜测动作。
|
|
234
|
-
|
|
235
|
-
同一条附着命令先输出 `runtime.device-authorization`、随后输出 schema 为 `rainskills.runtime-connect-result.v1` 且 `state=connected` 时,最终 connected 结果覆盖前面的等待授权消息。不得再次展示旧授权消息、不得等待用户回复“已授权”;必须在同一轮立即使用同一 `onboarding-id` 执行 `intent resume`。
|
|
236
|
-
|
|
237
|
-
业务 MCP 返回 401 时,先执行 launcher + `["runtime", "record-failure", "--onboarding-id", "<同一 onboarding-id>", "--step", "<当前固定步骤>", "--reason", "credential-expired"]`,再仅一次执行 launcher + `["runtime", "reconnect", "--onboarding-id", "<同一 onboarding-id>"]`,然后 resume 并只重试该步骤;第二次 401 立即停止。403 时执行 launcher + `["runtime", "record-failure", "--onboarding-id", "<同一 onboarding-id>", "--step", "<当前固定步骤>", "--reason", "permission-denied"]` 后停止,不得 reconnect、重新授权或自动重试,只说明缺少的权限。
|
|
207
|
+
}
|
|
208
|
+
```
|
|
238
209
|
<!-- rainskills-runtime-gate:end -->
|
|
239
210
|
|
|
240
211
|
受限沙箱(包括 Codex)执行本地状态命令时,必须申请用户级受保护目录访问权限;在 Codex 中使用 `require_escalated`。不得修改 `~/.rainbond` 权限、复制受保护状态到工作区,或因沙箱权限错误建议重装。
|
|
@@ -269,17 +240,11 @@ description: "Use whenever a user asks to deploy, run, deliver, publish, inspect
|
|
|
269
240
|
请提示“请选择应用要运行的环境:”,并只显示:
|
|
270
241
|
|
|
271
242
|
1) 云端环境(免费体验)
|
|
272
|
-
2)
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
请选择部署位置:
|
|
277
|
-
|
|
278
|
-
1、部署到本机
|
|
279
|
-
2、部署到独立服务器
|
|
280
|
-
3、部署到已有 Rainbond
|
|
243
|
+
2) 本机环境
|
|
244
|
+
3) 独立服务器
|
|
245
|
+
4) 已有 Rainbond
|
|
281
246
|
|
|
282
|
-
选择 1 时执行 `install-private` route,并在完整 argv 中使用 `["--location", "local"]`;选择
|
|
247
|
+
选择 1 时执行 `saas` route;选择 2 时执行 `install-private` route,并在完整 argv 中使用 `["--location", "local"]`;选择 3 时执行 `install-private` route,并使用 `["--location", "server"]`;选择 4 时执行本地 launcher + `["runtime", "message", "--id", "private-console-origin"]`,收到地址后执行 `private-existing`。不得显示“私有环境”或部署位置中间层,不得在平台安装器中重复询问部署位置,也不得在环境准备完成前询问应用来源。
|
|
283
248
|
|
|
284
249
|
### 已有应用
|
|
285
250
|
|