rainskills 0.1.9 → 0.1.11
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 +1 -1
- package/SKILL.md +1 -1
- package/bin/rainskills-tools.js +243 -12
- 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 +2 -2
- package/package.json +1 -1
- package/rainbond-app-assistant/SKILL.md +9 -5
- package/rainbond-app-version-assistant/SKILL.md +9 -5
- package/rainbond-delivery-verifier/SKILL.md +9 -5
- package/rainbond-env-sync/SKILL.md +9 -5
- package/rainbond-fullstack-bootstrap/SKILL.md +9 -5
- package/rainbond-fullstack-bootstrap/modules/40-source-and-package-rules.md +5 -9
- package/rainbond-fullstack-troubleshooter/SKILL.md +9 -5
- package/rainbond-opensource-app-deploy/SKILL.md +6 -2
- package/rainbond-platform-installer/SKILL.md +1 -1
- package/rainbond-platform-installer/scripts/installed-version.js +1 -1
- package/rainbond-platform-installer/scripts/runtime-intents.js +3 -0
- package/rainbond-platform-query/SKILL.md +16 -10
- package/rainbond-project-init/SKILL.md +9 -5
- package/rainbond-template-installer/SKILL.md +9 -5
package/README.md
CHANGED
|
@@ -228,7 +228,7 @@ node ~/.rainbond/lib/rainskills/bin/rainskills.js platform install --onboarding-
|
|
|
228
228
|
|
|
229
229
|
Rainskills 会在用户下一次发起业务动作时,由本地运行时立即返回环境查询结果,并另行启动后台任务静默检查更新。更新只跟随 npm `latest` 指向的正式版。当前版本是 RC 或其他预发布版本时不会查询、不会自动升级;npm 上的新 RC 版本也不参与正式版自动升级。
|
|
230
230
|
|
|
231
|
-
发现更高的正式版后,后台任务只委托到经过校验的精确版本,例如 `rainskills@0.1.
|
|
231
|
+
发现更高的正式版后,后台任务只委托到经过校验的精确版本,例如 `rainskills@0.1.11`,不会执行浮动的 `@latest` 业务代码。新版本原子刷新已经安装的 Rainskills Skills;当前业务继续使用启动时已经加载的版本,最迟从下一条新任务开始使用新版。npm 超时、版本检查失败、安装位置不安全或文件迁移失败时会保留旧版本,且不会阻塞或改变当前操作。
|
|
232
232
|
|
|
233
233
|
升级只更新 Rainskills 自身,不触发 Rainbond 安装、运行环境选择、登录授权或重新对接,也不会新增 Agent MCP 配置。更新内容仅包括 Skills 和本地 CLI。原始业务操作会继续执行;只有该业务操作本身需要运行环境时,才按既有门禁检查当前连接。可用连接直接复用,401 只重新授权一次,403 立即停止,从未连接过运行环境时才进入环境选择。
|
|
234
234
|
|
package/SKILL.md
CHANGED
|
@@ -38,7 +38,7 @@ Rainskills 安装完成,下一条消息即可直接使用。
|
|
|
38
38
|
|
|
39
39
|
## Manage Runtime Environments
|
|
40
40
|
|
|
41
|
-
环境是全局列表,不是项目绑定。本地状态命令必须定位已安装的同级 `rainbond-platform-installer/scripts/local-runtime.js`,解析为绝对路径后通过 `node` 以 argv 数组执行;不得为了查询本地环境访问 npm。只有连接或安装环境时才使用与当前技能包一致的固定 launcher `node <home>/.rainbond/lib/rainskills/bin/rainskills.js`(运行包版本 `rainskills@0.1.
|
|
41
|
+
环境是全局列表,不是项目绑定。本地状态命令必须定位已安装的同级 `rainbond-platform-installer/scripts/local-runtime.js`,解析为绝对路径后通过 `node` 以 argv 数组执行;不得为了查询本地环境访问 npm。只有连接或安装环境时才使用与当前技能包一致的固定 launcher `node <home>/.rainbond/lib/rainskills/bin/rainskills.js`(运行包版本 `rainskills@0.1.11`)。
|
|
42
42
|
|
|
43
43
|
- 列表:用本地 launcher 执行 `environment list --json`,只展示名称、类型、状态、是否默认和最近验证时间。
|
|
44
44
|
- 重命名:用本地 launcher 执行 `environment rename --environment-id <uuid> --name <name>`。
|
package/bin/rainskills-tools.js
CHANGED
|
@@ -6,6 +6,7 @@ const https = require("node:https");
|
|
|
6
6
|
const os = require("node:os");
|
|
7
7
|
const path = require("node:path");
|
|
8
8
|
const { createHash, randomUUID } = require("node:crypto");
|
|
9
|
+
const { spawnSync } = require("node:child_process");
|
|
9
10
|
|
|
10
11
|
const REQUEST_TIMEOUT_MS = 180_000;
|
|
11
12
|
const INPUT_MAX_BYTES = 1024 * 1024;
|
|
@@ -35,6 +36,24 @@ const RISK_POLICY = Object.freeze({
|
|
|
35
36
|
],
|
|
36
37
|
destructiveFragments: ["delete", "remove", "purge", "destroy"],
|
|
37
38
|
});
|
|
39
|
+
const CALL_OPTION_DEFINITIONS = Object.freeze({
|
|
40
|
+
"--confirm": Object.freeze({ property: "confirmation", pattern: OPERATION_ID_PATTERN }),
|
|
41
|
+
"--skill-id": Object.freeze({ property: "skillId", pattern: SKILL_ID_PATTERN }),
|
|
42
|
+
"--root-skill-id": Object.freeze({ property: "rootSkillId", pattern: SKILL_ID_PATTERN }),
|
|
43
|
+
});
|
|
44
|
+
const PACKAGE_UPLOAD_FIELDS = Object.freeze([
|
|
45
|
+
"url", "url_scope", "method", "content_type", "file_field", "authorization",
|
|
46
|
+
]);
|
|
47
|
+
const PACKAGE_UPLOAD_MAX_TIMEOUT_SECONDS = 3600;
|
|
48
|
+
const PLATFORM_QUERY_TO_RESOURCE = Object.freeze({
|
|
49
|
+
rainbond_get_current_user: "current-user",
|
|
50
|
+
rainbond_query_enterprises: "current-enterprise",
|
|
51
|
+
rainbond_query_teams: "teams",
|
|
52
|
+
rainbond_query_regions: "regions",
|
|
53
|
+
rainbond_query_apps: "apps",
|
|
54
|
+
rainbond_get_team_apps: "team-apps",
|
|
55
|
+
rainbond_query_components: "components",
|
|
56
|
+
});
|
|
38
57
|
|
|
39
58
|
const EXIT = Object.freeze({
|
|
40
59
|
USAGE: 2,
|
|
@@ -124,6 +143,23 @@ function requireRuntimeModule(filename) {
|
|
|
124
143
|
throw new BridgeError("installed Rainskills CLI runtime is incomplete", EXIT.CONFIG);
|
|
125
144
|
}
|
|
126
145
|
|
|
146
|
+
function requireRuntimeFile(...segments) {
|
|
147
|
+
const candidates = [
|
|
148
|
+
path.resolve(__dirname, "..", ...segments),
|
|
149
|
+
path.resolve(__dirname, "..", "lib", "rainskills", ...segments),
|
|
150
|
+
path.resolve(__dirname, "..", "lib", ...segments),
|
|
151
|
+
];
|
|
152
|
+
for (const candidate of candidates) {
|
|
153
|
+
try {
|
|
154
|
+
const info = fs.lstatSync(candidate);
|
|
155
|
+
if (info.isFile() && !info.isSymbolicLink()) return candidate;
|
|
156
|
+
} catch (error) {
|
|
157
|
+
if (error.code !== "ENOENT") throw error;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
throw new BridgeError("installed Rainskills package upload helper is incomplete", EXIT.CONFIG);
|
|
161
|
+
}
|
|
162
|
+
|
|
127
163
|
function loadOperationConfig({ homeDir, operationId, includeRuntime }) {
|
|
128
164
|
let operationStore;
|
|
129
165
|
const { createEnvironmentRegistry } = requireRuntimeModule("environment-registry.js");
|
|
@@ -219,7 +255,67 @@ function loadConfig({
|
|
|
219
255
|
return config;
|
|
220
256
|
}
|
|
221
257
|
|
|
258
|
+
function loadEnvironmentConfig({
|
|
259
|
+
homeDir = os.homedir(),
|
|
260
|
+
environmentId,
|
|
261
|
+
} = {}) {
|
|
262
|
+
const { createEnvironmentRegistry } = requireRuntimeModule("environment-registry.js");
|
|
263
|
+
const { createEnvironmentCredentialStore } = requireRuntimeModule("environment-credentials.js");
|
|
264
|
+
const registry = createEnvironmentRegistry({ home: homeDir });
|
|
265
|
+
const snapshot = registry.read();
|
|
266
|
+
const selectedId = environmentId || snapshot.default_environment_id;
|
|
267
|
+
if (!selectedId) {
|
|
268
|
+
throw new BridgeError("no default Rainbond environment is configured", EXIT.CONFIG);
|
|
269
|
+
}
|
|
270
|
+
const environment = snapshot.environments.find((entry) => entry.id === selectedId);
|
|
271
|
+
if (!environment || environment.connection_state !== "connected") {
|
|
272
|
+
throw new BridgeError("the selected Rainbond environment is unavailable", EXIT.CONFIG);
|
|
273
|
+
}
|
|
274
|
+
let credential;
|
|
275
|
+
try {
|
|
276
|
+
credential = createEnvironmentCredentialStore({ home: homeDir }).read({
|
|
277
|
+
environmentId: environment.id,
|
|
278
|
+
expectedOrigin: environment.console_origin,
|
|
279
|
+
});
|
|
280
|
+
} catch (_error) {
|
|
281
|
+
throw new BridgeError("the selected Rainbond environment credential is unavailable", EXIT.CONFIG);
|
|
282
|
+
}
|
|
283
|
+
const parsed = new URL(environment.console_origin);
|
|
284
|
+
return {
|
|
285
|
+
baseUrl: environment.console_origin,
|
|
286
|
+
jwt: credential.token,
|
|
287
|
+
environmentId: environment.id,
|
|
288
|
+
homeDir,
|
|
289
|
+
allowInsecureHttp: parsed.protocol === "http:",
|
|
290
|
+
isInsecureHttp: parsed.protocol === "http:",
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
|
|
222
294
|
function parseCommand(args) {
|
|
295
|
+
if (args[0] === "query") {
|
|
296
|
+
const toolName = args[1];
|
|
297
|
+
if (!Object.hasOwn(PLATFORM_QUERY_TO_RESOURCE, toolName || "")) {
|
|
298
|
+
throw new BridgeError("platform query tool is not allowed", EXIT.USAGE);
|
|
299
|
+
}
|
|
300
|
+
let environmentId;
|
|
301
|
+
let input;
|
|
302
|
+
for (let index = 2; index < args.length; index += 2) {
|
|
303
|
+
const option = args[index];
|
|
304
|
+
const value = args[index + 1];
|
|
305
|
+
if (!value || value.startsWith("--")) {
|
|
306
|
+
throw new BridgeError("platform query option requires a value", EXIT.USAGE);
|
|
307
|
+
}
|
|
308
|
+
if (option === "--environment-id" && !environmentId && OPERATION_ID_PATTERN.test(value)) {
|
|
309
|
+
environmentId = value;
|
|
310
|
+
} else if (option === "--input" && input === undefined && value === "-") {
|
|
311
|
+
input = value;
|
|
312
|
+
} else {
|
|
313
|
+
throw new BridgeError("invalid platform query command", EXIT.USAGE);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
if (input !== "-") throw new BridgeError("platform query requires --input -", EXIT.USAGE);
|
|
317
|
+
return { command: "query", toolName, input, environmentId };
|
|
318
|
+
}
|
|
223
319
|
const operationIndex = args.indexOf("--operation-id");
|
|
224
320
|
if (
|
|
225
321
|
operationIndex < 0
|
|
@@ -244,31 +340,69 @@ function parseCommand(args) {
|
|
|
244
340
|
if (command === "describe" && remaining.length === 2 && remaining[1]) {
|
|
245
341
|
return { command, toolName: remaining[1], operationId };
|
|
246
342
|
}
|
|
343
|
+
if (
|
|
344
|
+
command === "package-upload"
|
|
345
|
+
&& remaining.length === 5
|
|
346
|
+
&& remaining[1] === "--archive"
|
|
347
|
+
&& remaining[2]
|
|
348
|
+
&& !remaining[2].startsWith("--")
|
|
349
|
+
&& remaining[3] === "--input"
|
|
350
|
+
&& remaining[4] === "-"
|
|
351
|
+
) {
|
|
352
|
+
return { command, archive: remaining[2], input: remaining[4], operationId };
|
|
353
|
+
}
|
|
247
354
|
if (command === "read" && remaining.length === 4 && remaining[1] && remaining[2] === "--input" && remaining[3] === "-") {
|
|
248
355
|
return { command, toolName: remaining[1], input: remaining[3], operationId };
|
|
249
356
|
}
|
|
250
357
|
if (command === "call" && remaining.length >= 4 && remaining[1] && remaining[2] === "--input" && remaining[3] === "-") {
|
|
251
358
|
const parsed = { command, toolName: remaining[1], input: remaining[3], operationId };
|
|
252
|
-
const allowed = new Set(["--confirm", "--skill-id", "--root-skill-id"]);
|
|
253
359
|
for (let index = 4; index < remaining.length; index += 2) {
|
|
254
360
|
const option = remaining[index];
|
|
255
361
|
const value = remaining[index + 1];
|
|
256
|
-
|
|
257
|
-
if (
|
|
258
|
-
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
parsed.rootSkillId = value;
|
|
263
|
-
} else {
|
|
264
|
-
break;
|
|
362
|
+
const definition = CALL_OPTION_DEFINITIONS[option];
|
|
363
|
+
if (!definition) {
|
|
364
|
+
throw new BridgeError(`unsupported call option: ${String(option)}`, EXIT.USAGE);
|
|
365
|
+
}
|
|
366
|
+
if (!value || value.startsWith("--")) {
|
|
367
|
+
throw new BridgeError(`call option ${option} requires a value`, EXIT.USAGE);
|
|
265
368
|
}
|
|
266
|
-
if (
|
|
369
|
+
if (parsed[definition.property]) {
|
|
370
|
+
throw new BridgeError(`call option ${option} may be provided only once`, EXIT.USAGE);
|
|
371
|
+
}
|
|
372
|
+
if (!definition.pattern.test(value)) {
|
|
373
|
+
throw new BridgeError(`call option ${option} has an invalid value`, EXIT.USAGE);
|
|
374
|
+
}
|
|
375
|
+
parsed[definition.property] = value;
|
|
267
376
|
}
|
|
377
|
+
return parsed;
|
|
268
378
|
}
|
|
269
379
|
throw new BridgeError("invalid command; use status, list, describe, read, or call", EXIT.USAGE);
|
|
270
380
|
}
|
|
271
381
|
|
|
382
|
+
function platformQueryIntent(toolName, argumentsValue) {
|
|
383
|
+
const resource = PLATFORM_QUERY_TO_RESOURCE[toolName];
|
|
384
|
+
if (!resource) throw new BridgeError("platform query tool is not allowed", EXIT.USAGE);
|
|
385
|
+
const intent = { type: "platform-query", resource };
|
|
386
|
+
for (const field of ["enterprise_id", "team_id"]) {
|
|
387
|
+
if (argumentsValue[field] !== undefined) intent[field] = argumentsValue[field];
|
|
388
|
+
}
|
|
389
|
+
if (argumentsValue.app_id !== undefined) {
|
|
390
|
+
const value = argumentsValue.app_id;
|
|
391
|
+
if (!(
|
|
392
|
+
(Number.isInteger(value) && value > 0)
|
|
393
|
+
|| (typeof value === "string" && /^[1-9][0-9]*$/.test(value))
|
|
394
|
+
)) {
|
|
395
|
+
throw new BridgeError("platform query app_id must be a positive integer", EXIT.USAGE);
|
|
396
|
+
}
|
|
397
|
+
intent.app_id = String(value);
|
|
398
|
+
}
|
|
399
|
+
try {
|
|
400
|
+
return requireRuntimeModule("runtime-intents.js").validateIntent(intent);
|
|
401
|
+
} catch (_error) {
|
|
402
|
+
throw new BridgeError("platform query intent is invalid", EXIT.USAGE);
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
|
|
272
406
|
function readArguments(input) {
|
|
273
407
|
if (input !== "-") {
|
|
274
408
|
throw new BridgeError("read and call accept JSON only through --input - (stdin)", EXIT.USAGE);
|
|
@@ -304,6 +438,80 @@ function readArguments(input) {
|
|
|
304
438
|
return parsed;
|
|
305
439
|
}
|
|
306
440
|
|
|
441
|
+
function validatePackageUploadRequest(value) {
|
|
442
|
+
const allowed = new Set([...PACKAGE_UPLOAD_FIELDS, "timeout"]);
|
|
443
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
444
|
+
throw new BridgeError("package upload request must be an object", EXIT.USAGE);
|
|
445
|
+
}
|
|
446
|
+
for (const key of Object.keys(value)) {
|
|
447
|
+
if (!allowed.has(key)) throw new BridgeError("package upload request has unknown fields", EXIT.USAGE);
|
|
448
|
+
}
|
|
449
|
+
if (PACKAGE_UPLOAD_FIELDS.some((key) => typeof value[key] !== "string" || !value[key])) {
|
|
450
|
+
throw new BridgeError("package upload request is incomplete", EXIT.USAGE);
|
|
451
|
+
}
|
|
452
|
+
const timeout = value.timeout === undefined ? 1800 : value.timeout;
|
|
453
|
+
if (
|
|
454
|
+
!Number.isInteger(timeout)
|
|
455
|
+
|| timeout < 1
|
|
456
|
+
|| timeout > PACKAGE_UPLOAD_MAX_TIMEOUT_SECONDS
|
|
457
|
+
) {
|
|
458
|
+
throw new BridgeError("package upload timeout is invalid", EXIT.USAGE);
|
|
459
|
+
}
|
|
460
|
+
return { ...value, timeout };
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
function packageUploadEnvironment(baseUrl, source = process.env) {
|
|
464
|
+
const environment = { RAINBOND_URL: baseUrl };
|
|
465
|
+
for (const key of [
|
|
466
|
+
"PATH", "SystemRoot", "WINDIR", "ComSpec", "PATHEXT",
|
|
467
|
+
"TMPDIR", "TMP", "TEMP", "LANG", "LC_ALL",
|
|
468
|
+
"HTTP_PROXY", "HTTPS_PROXY", "NO_PROXY",
|
|
469
|
+
"http_proxy", "https_proxy", "no_proxy",
|
|
470
|
+
"SSL_CERT_FILE", "SSL_CERT_DIR", "CURL_CA_BUNDLE",
|
|
471
|
+
]) {
|
|
472
|
+
if (typeof source[key] === "string" && source[key]) environment[key] = source[key];
|
|
473
|
+
}
|
|
474
|
+
return environment;
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
function executePackageUpload(command, config, { spawnSyncFn = spawnSync } = {}) {
|
|
478
|
+
const request = validatePackageUploadRequest(command.argumentsValue);
|
|
479
|
+
const helper = requireRuntimeFile(
|
|
480
|
+
"rainbond-fullstack-bootstrap", "scripts", "upload_local_package.py"
|
|
481
|
+
);
|
|
482
|
+
const result = spawnSyncFn("python3", [
|
|
483
|
+
helper,
|
|
484
|
+
"upload",
|
|
485
|
+
"--archive", command.archive,
|
|
486
|
+
"--upload-url", request.url,
|
|
487
|
+
"--url-scope", request.url_scope,
|
|
488
|
+
"--method", request.method,
|
|
489
|
+
"--content-type", request.content_type,
|
|
490
|
+
"--file-field", request.file_field,
|
|
491
|
+
"--authorization", request.authorization,
|
|
492
|
+
"--timeout", String(request.timeout),
|
|
493
|
+
], {
|
|
494
|
+
encoding: "utf8",
|
|
495
|
+
env: packageUploadEnvironment(config.baseUrl),
|
|
496
|
+
maxBuffer: 256 * 1024,
|
|
497
|
+
shell: false,
|
|
498
|
+
timeout: (request.timeout + 2) * 1000,
|
|
499
|
+
});
|
|
500
|
+
if (result.error || result.status !== 0) {
|
|
501
|
+
throw new BridgeError("package upload failed", EXIT.TOOL);
|
|
502
|
+
}
|
|
503
|
+
let payload;
|
|
504
|
+
try {
|
|
505
|
+
payload = JSON.parse(result.stdout);
|
|
506
|
+
} catch {
|
|
507
|
+
throw new BridgeError("package upload helper returned invalid JSON", EXIT.TRANSPORT);
|
|
508
|
+
}
|
|
509
|
+
if (!payload || payload.uploaded !== true || Object.keys(payload).length !== 1) {
|
|
510
|
+
throw new BridgeError("package upload helper returned an invalid result", EXIT.TRANSPORT);
|
|
511
|
+
}
|
|
512
|
+
return payload;
|
|
513
|
+
}
|
|
514
|
+
|
|
307
515
|
function assertPrivateDirectory(directory) {
|
|
308
516
|
try {
|
|
309
517
|
const stat = fs.lstatSync(directory);
|
|
@@ -817,6 +1025,9 @@ async function listTools(config) {
|
|
|
817
1025
|
}
|
|
818
1026
|
|
|
819
1027
|
async function execute(command, config) {
|
|
1028
|
+
if (command.command === "package-upload") {
|
|
1029
|
+
return executePackageUpload(command, config);
|
|
1030
|
+
}
|
|
820
1031
|
if (command.command === "status") {
|
|
821
1032
|
const tools = await listTools(config);
|
|
822
1033
|
const cached = loadCachedCatalog(config);
|
|
@@ -929,11 +1140,26 @@ async function main(args = process.argv.slice(2)) {
|
|
|
929
1140
|
let argumentRedactions = [];
|
|
930
1141
|
try {
|
|
931
1142
|
command = parseCommand(args);
|
|
932
|
-
if (
|
|
1143
|
+
if (["read", "call", "package-upload", "query"].includes(command.command)) {
|
|
933
1144
|
const argumentsValue = readArguments(command.input);
|
|
934
1145
|
command.argumentsValue = argumentsValue;
|
|
935
1146
|
argumentRedactions = collectArgumentRedactions(argumentsValue);
|
|
936
1147
|
}
|
|
1148
|
+
if (command.command === "query") {
|
|
1149
|
+
platformQueryIntent(command.toolName, command.argumentsValue);
|
|
1150
|
+
config = loadEnvironmentConfig({ environmentId: command.environmentId });
|
|
1151
|
+
command = {
|
|
1152
|
+
command: "read",
|
|
1153
|
+
toolName: command.toolName,
|
|
1154
|
+
argumentsValue: command.argumentsValue,
|
|
1155
|
+
};
|
|
1156
|
+
if (config.isInsecureHttp) {
|
|
1157
|
+
process.stderr.write('{"warning":"using insecure HTTP transport"}\n');
|
|
1158
|
+
}
|
|
1159
|
+
const output = await execute(command, config);
|
|
1160
|
+
process.stdout.write(`${JSON.stringify(fitOutput(output))}\n`);
|
|
1161
|
+
return;
|
|
1162
|
+
}
|
|
937
1163
|
config = loadConfig({
|
|
938
1164
|
includeRuntime: true,
|
|
939
1165
|
operationId: command.operationId,
|
|
@@ -962,9 +1188,14 @@ module.exports = {
|
|
|
962
1188
|
CATALOG_TTL_MS,
|
|
963
1189
|
CLI_VERSION,
|
|
964
1190
|
loadConfig,
|
|
1191
|
+
executePackageUpload,
|
|
1192
|
+
packageUploadEnvironment,
|
|
965
1193
|
parseEnvFile,
|
|
966
1194
|
parseCommand,
|
|
1195
|
+
platformQueryIntent,
|
|
1196
|
+
loadEnvironmentConfig,
|
|
967
1197
|
rpcRequest,
|
|
1198
|
+
validatePackageUploadRequest,
|
|
968
1199
|
};
|
|
969
1200
|
|
|
970
1201
|
if (require.main === module) {
|
|
@@ -14,7 +14,7 @@ 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.11 <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
|
|
|
@@ -38,7 +38,7 @@ Rainskills 安装完成,下一条消息即可直接使用。
|
|
|
38
38
|
|
|
39
39
|
## Manage Runtime Environments
|
|
40
40
|
|
|
41
|
-
环境是全局列表,不是项目绑定。本地状态命令必须定位已安装的同级 `rainbond-platform-installer/scripts/local-runtime.js`,解析为绝对路径后通过 `node` 以 argv 数组执行;不得为了查询本地环境访问 npm。只有连接或安装环境时才使用与当前技能包一致的固定 launcher `node <home>/.rainbond/lib/rainskills/bin/rainskills.js`(运行包版本 `rainskills@0.1.
|
|
41
|
+
环境是全局列表,不是项目绑定。本地状态命令必须定位已安装的同级 `rainbond-platform-installer/scripts/local-runtime.js`,解析为绝对路径后通过 `node` 以 argv 数组执行;不得为了查询本地环境访问 npm。只有连接或安装环境时才使用与当前技能包一致的固定 launcher `node <home>/.rainbond/lib/rainskills/bin/rainskills.js`(运行包版本 `rainskills@0.1.11`)。
|
|
42
42
|
|
|
43
43
|
- 列表:用本地 launcher 执行 `environment list --json`,只展示名称、类型、状态、是否默认和最近验证时间。
|
|
44
44
|
- 重命名:用本地 launcher 执行 `environment rename --environment-id <uuid> --name <name>`。
|
package/package.json
CHANGED
|
@@ -87,10 +87,14 @@ description: "Use whenever a user asks to deploy, run, deliver, publish, inspect
|
|
|
87
87
|
只有“解决办法”确实存在并且可执行时才输出该项。默认用户回复不得出现 `Problem Judgment`、`Actions Taken`、`Verification Result`、`Follow-up Advice`、`Structured Output` 等诊断标题;不得展示内部状态码、枚举、对象字段、YAML、JSON、工具调用记录或英文状态表。只有用户明确要求结构化结果,或者自动化/评测明确要求结构化契约时,才允许输出后文的结构化格式。
|
|
88
88
|
<!-- rainskills-user-result:end -->
|
|
89
89
|
|
|
90
|
-
|
|
91
|
-
|
|
90
|
+
<!-- rainskills-runtime-gate:start -->
|
|
91
|
+
## 运行环境门禁(最高优先级)
|
|
92
92
|
|
|
93
|
-
|
|
93
|
+
### CLI 调用格式(强制)
|
|
94
|
+
|
|
95
|
+
所有可变 `call` 都必须使用完整 argv:`call <tool> --input - --operation-id <uuid> --skill-id rainbond-app-assistant`。CLI 返回确认 ID 后,只能在同一 argv 末尾加入 `--confirm <confirmation-id>`;不得省略 `--skill-id`、猜测参数,或根据泛化错误反复重试。
|
|
96
|
+
|
|
97
|
+
### 多运行环境操作契约
|
|
94
98
|
|
|
95
99
|
Node.js 前置检查通过后,每次用户业务请求都创建独立操作,不把项目绑定到任何环境、团队或应用。先执行本地 launcher + `["environment", "list", "--json"]`:用户明确说“运行环境/平台”时按环境名选择;明确说“团队”时表示默认环境中的团队;裸名称同时匹配环境和团队时必须让用户确认。未指定环境时使用全局默认环境;默认环境不可用时停止,禁止自动切换到其他环境。
|
|
96
100
|
|
|
@@ -98,7 +102,7 @@ description: "Use whenever a user asks to deploy, run, deliver, publish, inspect
|
|
|
98
102
|
|
|
99
103
|
第一步检查 Node.js 是否存在且主版本不低于 18。Node.js 缺失或低于 18 时,只说明“Rainskills 执行组件需要 Node.js 18 或更高版本”并停止:不选择运行环境,不调用 MCP,不猜测替代命令。只有用户或 agent 明确同意后才安装或升级 Node.js,再从同一原始 intent 继续。
|
|
100
104
|
|
|
101
|
-
固定 launcher 是 `["node", "<home>/.rainbond/lib/rainskills/bin/rainskills.js"]`;运行包版本标记为 `rainskills@0.1.
|
|
105
|
+
固定 launcher 是 `["node", "<home>/.rainbond/lib/rainskills/bin/rainskills.js"]`;运行包版本标记为 `rainskills@0.1.11`,且必须与本技能包 `package.json` 一致。把 launcher 与参数拼成 argv 数组直接执行,禁止使用 `rainskills@latest`,禁止拼接或执行 shell 字符串。
|
|
102
106
|
|
|
103
107
|
本地 launcher 必须从当前 Skill 所在目录的同级目录定位 `rainbond-platform-installer/scripts/local-runtime.js`,解析为绝对路径后使用 `["node", "<绝对路径>"]` 执行。`environment list`、`operation begin`、`operation complete` 和 `runtime message` 只能使用本地 launcher;本地 launcher 只读取已安装文件和本机受保护状态,不得访问 npm 或其它网络。只有用户选定连接或安装运行环境后,才使用上面的固定本地 launcher。
|
|
104
108
|
|
|
@@ -110,7 +114,7 @@ description: "Use whenever a user asks to deploy, run, deliver, publish, inspect
|
|
|
110
114
|
```json
|
|
111
115
|
{
|
|
112
116
|
"schema": "rainskills.skill-runtime-contract.v1",
|
|
113
|
-
"package_version": "rainskills@0.1.
|
|
117
|
+
"package_version": "rainskills@0.1.11",
|
|
114
118
|
"launcher": ["node", "<home>/.rainbond/lib/rainskills/bin/rainskills.js"],
|
|
115
119
|
"local_launcher": ["node", "<installed-skills-root>/rainbond-platform-installer/scripts/local-runtime.js"],
|
|
116
120
|
"local_argv": {
|
|
@@ -5,16 +5,20 @@ description: "Use when a user explicitly asks for an existing Rainbond app versi
|
|
|
5
5
|
|
|
6
6
|
# Rainbond App Version Assistant
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
<!-- rainskills-runtime-gate:start -->
|
|
9
|
+
## 运行环境门禁(最高优先级)
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
### CLI 调用格式(强制)
|
|
12
|
+
|
|
13
|
+
所有可变 `call` 都必须使用完整 argv:`call <tool> --input - --operation-id <uuid> --skill-id rainbond-app-version-assistant`。CLI 返回确认 ID 后,只能在同一 argv 末尾加入 `--confirm <confirmation-id>`;不得省略 `--skill-id`、猜测参数,或根据泛化错误反复重试。
|
|
14
|
+
|
|
15
|
+
### 多运行环境操作契约
|
|
12
16
|
|
|
13
17
|
Node.js 前置检查通过后,每次请求先执行本地 launcher + `["environment", "list", "--json"]`,按用户明确指定的运行环境选择不可变环境 ID;未指定时只用全局默认环境,默认不可用时停止且不回退。生成 UUID 后执行本地 launcher + `["operation", "begin", "--operation-id", "<uuid>", "--environment-id", "<id>", "--intent-json", "<intent-json>"]`,并在之后每个 Rainbond MCP 调用中加入 `rainskills_operation_id`。环境、团队和应用只属于本次操作,禁止保存项目绑定;同一项目可以部署到多个环境。明确“团队”表示环境内团队;明确“运行环境/平台”表示环境;裸名称同时匹配环境和团队时必须询问。
|
|
14
18
|
|
|
15
19
|
第一步检查 Node.js 是否存在且主版本不低于 18。Node.js 缺失或低于 18 时,只说明“Rainskills 执行组件需要 Node.js 18 或更高版本”并停止:不选择运行环境,不调用 MCP,不猜测替代命令。只有用户或 agent 明确同意后才安装或升级 Node.js,再从同一原始 intent 继续。
|
|
16
20
|
|
|
17
|
-
固定 launcher 是 `["node", "<home>/.rainbond/lib/rainskills/bin/rainskills.js"]`;运行包版本标记为 `rainskills@0.1.
|
|
21
|
+
固定 launcher 是 `["node", "<home>/.rainbond/lib/rainskills/bin/rainskills.js"]`;运行包版本标记为 `rainskills@0.1.11`,且必须与本技能包 `package.json` 一致。把 launcher 与参数拼成 argv 数组直接执行,禁止 `rainskills@latest` 或执行 shell 字符串。
|
|
18
22
|
|
|
19
23
|
本地 launcher 必须从当前 Skill 所在目录的同级目录定位 `rainbond-platform-installer/scripts/local-runtime.js`,解析为绝对路径后使用 `["node", "<绝对路径>"]` 执行。`environment list`、`operation begin`、`operation complete` 和 `runtime message` 只能使用本地 launcher;本地 launcher 只读取已安装文件和本机受保护状态,不得访问 npm 或其它网络。只有用户选定连接运行环境后,才使用上面的固定本地 launcher。
|
|
20
24
|
|
|
@@ -26,7 +30,7 @@ description: "Use when a user explicitly asks for an existing Rainbond app versi
|
|
|
26
30
|
```json
|
|
27
31
|
{
|
|
28
32
|
"schema": "rainskills.skill-runtime-contract.v1",
|
|
29
|
-
"package_version": "rainskills@0.1.
|
|
33
|
+
"package_version": "rainskills@0.1.11",
|
|
30
34
|
"launcher": ["node", "<home>/.rainbond/lib/rainskills/bin/rainskills.js"],
|
|
31
35
|
"local_launcher": ["node", "<installed-skills-root>/rainbond-platform-installer/scripts/local-runtime.js"],
|
|
32
36
|
"local_argv": {
|
|
@@ -37,16 +37,20 @@ description: "Use only when the user explicitly asks for final delivery or acces
|
|
|
37
37
|
只有“解决办法”确实存在并且可执行时才输出该项。默认用户回复不得出现 `Problem Judgment`、`Actions Taken`、`Verification Result`、`Follow-up Advice`、`Structured Output` 等诊断标题;不得展示内部状态码、枚举、对象字段、YAML、JSON、工具调用记录或英文状态表。只有用户明确要求结构化结果,或者自动化/评测明确要求结构化契约时,才允许输出后文的结构化格式。
|
|
38
38
|
<!-- rainskills-user-result:end -->
|
|
39
39
|
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
<!-- rainskills-runtime-gate:start -->
|
|
41
|
+
## 运行环境门禁(最高优先级)
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
### CLI 调用格式(强制)
|
|
44
|
+
|
|
45
|
+
所有可变 `call` 都必须使用完整 argv:`call <tool> --input - --operation-id <uuid> --skill-id rainbond-delivery-verifier`。CLI 返回确认 ID 后,只能在同一 argv 末尾加入 `--confirm <confirmation-id>`;不得省略 `--skill-id`、猜测参数,或根据泛化错误反复重试。
|
|
46
|
+
|
|
47
|
+
### 多运行环境操作契约
|
|
44
48
|
|
|
45
49
|
Node.js 前置检查通过后,每次请求先执行本地 launcher + `["environment", "list", "--json"]`,按用户明确指定的运行环境选择不可变环境 ID;未指定时只用全局默认环境,默认不可用时停止且不回退。生成 UUID 后执行本地 launcher + `["operation", "begin", "--operation-id", "<uuid>", "--environment-id", "<id>", "--intent-json", "<intent-json>"]`,并在之后每个 Rainbond MCP 调用中加入 `rainskills_operation_id`。环境、团队和应用只属于本次操作,禁止保存项目绑定;同一项目可以部署到多个环境。明确“团队”表示环境内团队;明确“运行环境/平台”表示环境;裸名称同时匹配环境和团队时必须询问。
|
|
46
50
|
|
|
47
51
|
第一步检查 Node.js 是否存在且主版本不低于 18。Node.js 缺失或低于 18 时,只说明“Rainskills 执行组件需要 Node.js 18 或更高版本”并停止:不选择运行环境,不调用 MCP,不猜测替代命令。只有用户或 agent 明确同意后才安装或升级 Node.js,再从同一原始 intent 继续。
|
|
48
52
|
|
|
49
|
-
固定 launcher 是 `["node", "<home>/.rainbond/lib/rainskills/bin/rainskills.js"]`;运行包版本标记为 `rainskills@0.1.
|
|
53
|
+
固定 launcher 是 `["node", "<home>/.rainbond/lib/rainskills/bin/rainskills.js"]`;运行包版本标记为 `rainskills@0.1.11`,且必须与本技能包 `package.json` 一致。把 launcher 与参数拼成 argv 数组直接执行,禁止 `rainskills@latest` 或执行 shell 字符串。
|
|
50
54
|
|
|
51
55
|
本地 launcher 必须从当前 Skill 所在目录的同级目录定位 `rainbond-platform-installer/scripts/local-runtime.js`,解析为绝对路径后使用 `["node", "<绝对路径>"]` 执行。`environment list`、`operation begin`、`operation complete` 和 `runtime message` 只能使用本地 launcher;本地 launcher 只读取已安装文件和本机受保护状态,不得访问 npm 或其它网络。只有用户选定连接运行环境后,才使用上面的固定本地 launcher。
|
|
52
56
|
|
|
@@ -58,7 +62,7 @@ description: "Use only when the user explicitly asks for final delivery or acces
|
|
|
58
62
|
```json
|
|
59
63
|
{
|
|
60
64
|
"schema": "rainskills.skill-runtime-contract.v1",
|
|
61
|
-
"package_version": "rainskills@0.1.
|
|
65
|
+
"package_version": "rainskills@0.1.11",
|
|
62
66
|
"launcher": ["node", "<home>/.rainbond/lib/rainskills/bin/rainskills.js"],
|
|
63
67
|
"local_launcher": ["node", "<installed-skills-root>/rainbond-platform-installer/scripts/local-runtime.js"],
|
|
64
68
|
"local_argv": {
|
|
@@ -5,16 +5,20 @@ description: "Use when a user explicitly asks to sync non-sensitive preview or p
|
|
|
5
5
|
|
|
6
6
|
# Rainbond Env Sync
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
<!-- rainskills-runtime-gate:start -->
|
|
9
|
+
## 运行环境门禁(最高优先级)
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
### CLI 调用格式(强制)
|
|
12
|
+
|
|
13
|
+
所有可变 `call` 都必须使用完整 argv:`call <tool> --input - --operation-id <uuid> --skill-id rainbond-env-sync`。CLI 返回确认 ID 后,只能在同一 argv 末尾加入 `--confirm <confirmation-id>`;不得省略 `--skill-id`、猜测参数,或根据泛化错误反复重试。
|
|
14
|
+
|
|
15
|
+
### 多运行环境操作契约
|
|
12
16
|
|
|
13
17
|
Node.js 前置检查通过后,每次请求先执行本地 launcher + `["environment", "list", "--json"]`,按用户明确指定的运行环境选择不可变环境 ID;未指定时只用全局默认环境,默认不可用时停止且不回退。生成 UUID 后执行本地 launcher + `["operation", "begin", "--operation-id", "<uuid>", "--environment-id", "<id>", "--intent-json", "<intent-json>"]`,并在之后每个 Rainbond MCP 调用中加入 `rainskills_operation_id`。环境、团队和应用只属于本次操作,禁止保存项目绑定;同一项目可以部署到多个环境。明确“团队”表示环境内团队;明确“运行环境/平台”表示环境;裸名称同时匹配环境和团队时必须询问。
|
|
14
18
|
|
|
15
19
|
第一步检查 Node.js 是否存在且主版本不低于 18。Node.js 缺失或低于 18 时,只说明“Rainskills 执行组件需要 Node.js 18 或更高版本”并停止:不选择运行环境,不调用 MCP,不猜测替代命令。只有用户或 agent 明确同意后才安装或升级 Node.js,再从同一原始 intent 继续。
|
|
16
20
|
|
|
17
|
-
固定 launcher 是 `["node", "<home>/.rainbond/lib/rainskills/bin/rainskills.js"]`;运行包版本标记为 `rainskills@0.1.
|
|
21
|
+
固定 launcher 是 `["node", "<home>/.rainbond/lib/rainskills/bin/rainskills.js"]`;运行包版本标记为 `rainskills@0.1.11`,且必须与本技能包 `package.json` 一致。把 launcher 与参数拼成 argv 数组直接执行,禁止 `rainskills@latest` 或执行 shell 字符串。
|
|
18
22
|
|
|
19
23
|
本地 launcher 必须从当前 Skill 所在目录的同级目录定位 `rainbond-platform-installer/scripts/local-runtime.js`,解析为绝对路径后使用 `["node", "<绝对路径>"]` 执行。`environment list`、`operation begin`、`operation complete` 和 `runtime message` 只能使用本地 launcher;本地 launcher 只读取已安装文件和本机受保护状态,不得访问 npm 或其它网络。只有用户选定连接运行环境后,才使用上面的固定本地 launcher。
|
|
20
24
|
|
|
@@ -26,7 +30,7 @@ description: "Use when a user explicitly asks to sync non-sensitive preview or p
|
|
|
26
30
|
```json
|
|
27
31
|
{
|
|
28
32
|
"schema": "rainskills.skill-runtime-contract.v1",
|
|
29
|
-
"package_version": "rainskills@0.1.
|
|
33
|
+
"package_version": "rainskills@0.1.11",
|
|
30
34
|
"launcher": ["node", "<home>/.rainbond/lib/rainskills/bin/rainskills.js"],
|
|
31
35
|
"local_launcher": ["node", "<installed-skills-root>/rainbond-platform-installer/scripts/local-runtime.js"],
|
|
32
36
|
"local_argv": {
|
|
@@ -5,16 +5,20 @@ description: "Use only when the user explicitly asks to create the Rainbond app
|
|
|
5
5
|
|
|
6
6
|
# Rainbond Fullstack Bootstrap
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
<!-- rainskills-runtime-gate:start -->
|
|
9
|
+
## 运行环境门禁(最高优先级)
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
### CLI 调用格式(强制)
|
|
12
|
+
|
|
13
|
+
所有可变 `call` 都必须使用完整 argv:`call <tool> --input - --operation-id <uuid> --skill-id rainbond-fullstack-bootstrap`。CLI 返回确认 ID 后,只能在同一 argv 末尾加入 `--confirm <confirmation-id>`;不得省略 `--skill-id`、猜测参数,或根据泛化错误反复重试。
|
|
14
|
+
|
|
15
|
+
### 多运行环境操作契约
|
|
12
16
|
|
|
13
17
|
Node.js 前置检查通过后,每次请求先执行本地 launcher + `["environment", "list", "--json"]`,按用户明确指定的运行环境选择不可变环境 ID;未指定时只用全局默认环境,默认不可用时停止且不回退。生成 UUID 后执行本地 launcher + `["operation", "begin", "--operation-id", "<uuid>", "--environment-id", "<id>", "--intent-json", "<intent-json>"]`,并在之后每个 Rainbond MCP 调用中加入 `rainskills_operation_id`。环境、团队和应用只属于本次操作,禁止保存项目绑定;同一项目可以部署到多个环境。明确“团队”表示环境内团队;明确“运行环境/平台”表示环境;裸名称同时匹配环境和团队时必须询问。
|
|
14
18
|
|
|
15
19
|
第一步检查 Node.js 是否存在且主版本不低于 18。Node.js 缺失或低于 18 时,只说明“Rainskills 执行组件需要 Node.js 18 或更高版本”并停止:不选择运行环境,不调用 MCP,不猜测替代命令。只有用户或 agent 明确同意后才安装或升级 Node.js,再从同一原始 intent 继续。
|
|
16
20
|
|
|
17
|
-
固定 launcher 是 `["node", "<home>/.rainbond/lib/rainskills/bin/rainskills.js"]`;运行包版本标记为 `rainskills@0.1.
|
|
21
|
+
固定 launcher 是 `["node", "<home>/.rainbond/lib/rainskills/bin/rainskills.js"]`;运行包版本标记为 `rainskills@0.1.11`,且必须与本技能包 `package.json` 一致。把 launcher 与参数拼成 argv 数组直接执行,禁止 `rainskills@latest` 或执行 shell 字符串。
|
|
18
22
|
|
|
19
23
|
本地 launcher 必须从当前 Skill 所在目录的同级目录定位 `rainbond-platform-installer/scripts/local-runtime.js`,解析为绝对路径后使用 `["node", "<绝对路径>"]` 执行。`environment list`、`operation begin`、`operation complete` 和 `runtime message` 只能使用本地 launcher;本地 launcher 只读取已安装文件和本机受保护状态,不得访问 npm 或其它网络。只有用户选定连接或安装运行环境后,才使用上面的固定本地 launcher。
|
|
20
24
|
|
|
@@ -26,7 +30,7 @@ description: "Use only when the user explicitly asks to create the Rainbond app
|
|
|
26
30
|
```json
|
|
27
31
|
{
|
|
28
32
|
"schema": "rainskills.skill-runtime-contract.v1",
|
|
29
|
-
"package_version": "rainskills@0.1.
|
|
33
|
+
"package_version": "rainskills@0.1.11",
|
|
30
34
|
"launcher": ["node", "<home>/.rainbond/lib/rainskills/bin/rainskills.js"],
|
|
31
35
|
"local_launcher": ["node", "<installed-skills-root>/rainbond-platform-installer/scripts/local-runtime.js"],
|
|
32
36
|
"local_argv": {
|
|
@@ -240,19 +240,15 @@ 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
|
|
244
|
-
- `
|
|
245
|
-
- `
|
|
246
|
-
-
|
|
247
|
-
- `upload_request.content_type` -> `--content-type`
|
|
248
|
-
- `upload_request.file_field` -> `--file-field`
|
|
249
|
-
- `upload_request.authorization` -> `--authorization`
|
|
250
|
-
- do not invent a URL, authorization mode, form field, HTTP method, or content type; the helper validates the same-Console-origin upload contract before invoking HTTP
|
|
243
|
+
3. Run the protected local CLI command `package-upload --archive <archive_path> --input - --operation-id <uuid>` using the fixed CLI launcher defined by the active Skill, passing the complete `upload_request` object through stdin as JSON:
|
|
244
|
+
- the CLI resolves the Console origin from the environment already bound to the protected operation; never ask the user for `RAINBOND_URL` and never take it from the current shell
|
|
245
|
+
- do not add `RAINBOND_URL`, JWT, upload credentials, or a Console address to argv or stdin
|
|
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
|
|
251
247
|
4. Run `upload_local_package.py cleanup` immediately after the HTTP attempt returns, whether upload succeeded, failed, or timed out. Pass the captured `archive_path`, `staging_root`, and `generated` flag. This cleanup must finish or be reported before any upload-status or component-create call.
|
|
252
248
|
5. If and only if the HTTP upload succeeded, call `rainbond_get_package_upload_status(event_id=...)`. The returned uploaded-file status must be non-empty and must identify at least one uploaded file.
|
|
253
249
|
6. If and only if status is non-empty, call `rainbond_create_component_from_package(event_id=...)`. Package creation is event-based; no local filesystem path belongs in this call.
|
|
254
250
|
|
|
255
|
-
The helper command is `python3 rainbond-fullstack-bootstrap/scripts/upload_local_package.py <prepare|
|
|
251
|
+
The helper command is used directly only for `prepare` and `cleanup`: `python3 rainbond-fullstack-bootstrap/scripts/upload_local_package.py <prepare|cleanup> ...`. The HTTP upload must use the protected local CLI `package-upload` command. Preserve JSON result fields exactly between phases; do not reconstruct paths or upload parameters from memory.
|
|
256
252
|
|
|
257
253
|
### Cleanup and Stop Rules
|
|
258
254
|
|
|
@@ -37,16 +37,20 @@ description: "Use only when the user explicitly asks for a bounded build, runtim
|
|
|
37
37
|
只有“解决办法”确实存在并且可执行时才输出该项。默认用户回复不得出现 `Problem Judgment`、`Actions Taken`、`Verification Result`、`Follow-up Advice`、`Structured Output` 等诊断标题;不得展示内部状态码、枚举、对象字段、YAML、JSON、工具调用记录或英文状态表。只有用户明确要求结构化结果,或者自动化/评测明确要求结构化契约时,才允许输出后文的结构化格式。
|
|
38
38
|
<!-- rainskills-user-result:end -->
|
|
39
39
|
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
<!-- rainskills-runtime-gate:start -->
|
|
41
|
+
## 运行环境门禁(最高优先级)
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
### CLI 调用格式(强制)
|
|
44
|
+
|
|
45
|
+
所有可变 `call` 都必须使用完整 argv:`call <tool> --input - --operation-id <uuid> --skill-id rainbond-fullstack-troubleshooter`。CLI 返回确认 ID 后,只能在同一 argv 末尾加入 `--confirm <confirmation-id>`;不得省略 `--skill-id`、猜测参数,或根据泛化错误反复重试。
|
|
46
|
+
|
|
47
|
+
### 多运行环境操作契约
|
|
44
48
|
|
|
45
49
|
Node.js 前置检查通过后,每次请求先执行本地 launcher + `["environment", "list", "--json"]`,按用户明确指定的运行环境选择不可变环境 ID;未指定时只用全局默认环境,默认不可用时停止且不回退。生成 UUID 后执行本地 launcher + `["operation", "begin", "--operation-id", "<uuid>", "--environment-id", "<id>", "--intent-json", "<intent-json>"]`,并在之后每个 Rainbond MCP 调用中加入 `rainskills_operation_id`。环境、团队和应用只属于本次操作,禁止保存项目绑定;同一项目可以部署到多个环境。明确“团队”表示环境内团队;明确“运行环境/平台”表示环境;裸名称同时匹配环境和团队时必须询问。
|
|
46
50
|
|
|
47
51
|
第一步检查 Node.js 是否存在且主版本不低于 18。Node.js 缺失或低于 18 时,只说明“Rainskills 执行组件需要 Node.js 18 或更高版本”并停止:不选择运行环境,不调用 MCP,不猜测替代命令。只有用户或 agent 明确同意后才安装或升级 Node.js,再从同一原始 intent 继续。
|
|
48
52
|
|
|
49
|
-
固定 launcher 是 `["node", "<home>/.rainbond/lib/rainskills/bin/rainskills.js"]`;运行包版本标记为 `rainskills@0.1.
|
|
53
|
+
固定 launcher 是 `["node", "<home>/.rainbond/lib/rainskills/bin/rainskills.js"]`;运行包版本标记为 `rainskills@0.1.11`,且必须与本技能包 `package.json` 一致。把 launcher 与参数拼成 argv 数组直接执行,禁止 `rainskills@latest` 或执行 shell 字符串。
|
|
50
54
|
|
|
51
55
|
本地 launcher 必须从当前 Skill 所在目录的同级目录定位 `rainbond-platform-installer/scripts/local-runtime.js`,解析为绝对路径后使用 `["node", "<绝对路径>"]` 执行。`environment list`、`operation begin`、`operation complete` 和 `runtime message` 只能使用本地 launcher;本地 launcher 只读取已安装文件和本机受保护状态,不得访问 npm 或其它网络。只有用户选定连接运行环境后,才使用上面的固定本地 launcher。
|
|
52
56
|
|
|
@@ -58,7 +62,7 @@ description: "Use only when the user explicitly asks for a bounded build, runtim
|
|
|
58
62
|
```json
|
|
59
63
|
{
|
|
60
64
|
"schema": "rainskills.skill-runtime-contract.v1",
|
|
61
|
-
"package_version": "rainskills@0.1.
|
|
65
|
+
"package_version": "rainskills@0.1.11",
|
|
62
66
|
"launcher": ["node", "<home>/.rainbond/lib/rainskills/bin/rainskills.js"],
|
|
63
67
|
"local_launcher": ["node", "<installed-skills-root>/rainbond-platform-installer/scripts/local-runtime.js"],
|
|
64
68
|
"local_argv": {
|
|
@@ -8,13 +8,17 @@ description: "Use when a user wants to deploy an open-source application that is
|
|
|
8
8
|
<!-- rainskills-runtime-gate:start -->
|
|
9
9
|
## 运行环境门禁(最高优先级)
|
|
10
10
|
|
|
11
|
+
### CLI 调用格式(强制)
|
|
12
|
+
|
|
13
|
+
所有可变 `call` 都必须使用完整 argv:`call <tool> --input - --operation-id <uuid> --skill-id rainbond-opensource-app-deploy`。CLI 返回确认 ID 后,只能在同一 argv 末尾加入 `--confirm <confirmation-id>`;不得省略 `--skill-id`、猜测参数,或根据泛化错误反复重试。
|
|
14
|
+
|
|
11
15
|
### 多运行环境操作契约
|
|
12
16
|
|
|
13
17
|
Node.js 前置检查通过后,每次请求先执行本地 launcher + `["environment", "list", "--json"]`,按用户明确指定的运行环境选择不可变环境 ID;未指定时只用全局默认环境,默认不可用时停止且不回退。生成 UUID 后执行本地 launcher + `["operation", "begin", "--operation-id", "<uuid>", "--environment-id", "<id>", "--intent-json", "<intent-json>"]`。此后每个 Rainbond 能力调用只能通过受保护的本地 Rainskills CLI 执行,并携带同一 operation ID;CLI 会将 `rainskills_operation_id` 写入审计元数据。环境、团队和应用只属于本次操作,禁止保存项目级绑定;同一项目可以部署到多个环境。明确“团队”表示环境内团队;明确“运行环境/平台”表示环境;裸名称同时匹配环境和团队时必须询问确认。
|
|
14
18
|
|
|
15
19
|
第一步检查 Node.js 是否存在且主版本不低于 18。Node.js 缺失或低于 18 时,只说明“Rainskills 执行组件需要 Node.js 18 或更高版本”并停止:不选择运行环境,不调用 MCP,不猜测替代命令。只有用户或 agent 明确同意后才安装或升级 Node.js,再从同一原始 intent 继续。
|
|
16
20
|
|
|
17
|
-
固定 launcher 是 `["node", "<home>/.rainbond/lib/rainskills/bin/rainskills.js"]`;运行包版本标记为 `rainskills@0.1.
|
|
21
|
+
固定 launcher 是 `["node", "<home>/.rainbond/lib/rainskills/bin/rainskills.js"]`;运行包版本标记为 `rainskills@0.1.11`,且必须与本技能包 `package.json` 一致。把 launcher 与参数拼成 argv 数组直接执行,禁止 `rainskills@latest`,禁止拼接或执行 shell 字符串。
|
|
18
22
|
|
|
19
23
|
本地 launcher 必须从当前 Skill 所在目录的同级目录定位 `rainbond-platform-installer/scripts/local-runtime.js`,解析为绝对路径后使用 `["node", "<绝对路径>"]` 执行。`environment list`、`operation begin`、`operation complete` 和 `runtime message` 只能使用本地 launcher;本地 launcher 只读取已安装文件和本机受保护状态,不得访问 npm 或其它网络。只有用户选定连接或安装运行环境后,才使用固定 launcher。
|
|
20
24
|
|
|
@@ -26,7 +30,7 @@ Node.js 前置检查通过后,每次请求先执行本地 launcher + `["enviro
|
|
|
26
30
|
```json
|
|
27
31
|
{
|
|
28
32
|
"schema": "rainskills.skill-runtime-contract.v1",
|
|
29
|
-
"package_version": "rainskills@0.1.
|
|
33
|
+
"package_version": "rainskills@0.1.11",
|
|
30
34
|
"launcher": ["node", "<home>/.rainbond/lib/rainskills/bin/rainskills.js"],
|
|
31
35
|
"local_launcher": ["node", "<installed-skills-root>/rainbond-platform-installer/scripts/local-runtime.js"],
|
|
32
36
|
"local_argv": {
|
|
@@ -31,7 +31,7 @@ Do not use it to deploy an application to an existing Rainbond. Route those requ
|
|
|
31
31
|
## Workflow
|
|
32
32
|
|
|
33
33
|
1. Read [installation-policy.md](references/installation-policy.md).
|
|
34
|
-
2. Use the installed local launcher `["node", "<home>/.rainbond/lib/rainskills/bin/rainskills.js"]`; its protected runtime package marker is `rainskills@0.1.
|
|
34
|
+
2. Use the installed local launcher `["node", "<home>/.rainbond/lib/rainskills/bin/rainskills.js"]`; its protected runtime package marker is `rainskills@0.1.11` 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.
|
|
35
35
|
3. 在任何平台安装命令之前,先执行 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`。若是没有原始业务 intent 的直接平台安装请求,已有环境连接使用受限 `{"type":"environment-add"}` intent。
|
|
36
36
|
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.
|
|
37
37
|
5. Obtain explicit confirmation before sending `y` to the waiting process or rerunning the exact command with `--yes`.
|
|
@@ -175,6 +175,9 @@ function validateIntent(input, { pathApi = path } = {}) {
|
|
|
175
175
|
if (CREDENTIAL_KEY_PATTERN.test(key)) throw new Error(`intent 不能包含凭据字段:${key}`);
|
|
176
176
|
}
|
|
177
177
|
const type = input.type;
|
|
178
|
+
if (type === undefined || type === null || type === "") {
|
|
179
|
+
throw new Error("intent 缺少必填字段:type");
|
|
180
|
+
}
|
|
178
181
|
if (!Object.hasOwn(INTENT_DEFINITIONS, type)) throw new Error(`未知 intent type:${String(type)}`);
|
|
179
182
|
const definition = INTENT_DEFINITIONS[type];
|
|
180
183
|
const allowed = new Set(["type", ...definition.required, ...definition.optional]);
|
|
@@ -8,32 +8,38 @@ description: Use for a user-requested, read-only Rainbond platform query about t
|
|
|
8
8
|
<!-- rainskills-runtime-gate:start -->
|
|
9
9
|
## 运行环境门禁(最高优先级)
|
|
10
10
|
|
|
11
|
+
### CLI 调用格式(强制)
|
|
12
|
+
|
|
13
|
+
所有可变 `call` 都必须使用完整 argv:`call <tool> --input - --operation-id <uuid> --skill-id rainbond-platform-query`。CLI 返回确认 ID 后,只能在同一 argv 末尾加入 `--confirm <confirmation-id>`;不得省略 `--skill-id`、猜测参数,或根据泛化错误反复重试。
|
|
14
|
+
|
|
11
15
|
### 多运行环境操作契约
|
|
12
16
|
|
|
13
|
-
Node.js
|
|
17
|
+
Node.js 前置检查通过后,平台只读查询只执行一次本地 `rainskills-tools.js query`。用户未指定运行环境时,不得先执行 `environment list`,由 CLI 直接使用全局默认环境;默认环境缺失或不可用时停止且不回退。用户明确指定运行环境时,才允许执行一次本地 launcher + `["environment", "list", "--json"]` 解析不可变环境 ID,随后执行带 `--environment-id` 的单次查询。CLI 直接从受保护环境注册表读取环境与凭据,校验完整 `platform-query` intent 后调用 Rainbond;只读查询不创建 `operation_id` 或 operation 记录。Agent 禁止生成 UUID、禁止传 `--intent-json`,也禁止调用 `operation begin` 或 `operation complete`。环境、团队和应用只属于本次查询,禁止保存项目级默认环境或绑定;同一项目可以在多个环境中查询。明确“团队”表示环境内团队;明确“运行环境/平台”表示环境;裸名称同时匹配环境和团队时必须询问。
|
|
18
|
+
|
|
19
|
+
查询入口只接受固定 Tool 映射:`rainbond_get_current_user`、`rainbond_query_enterprises`、`rainbond_query_teams`、`rainbond_query_regions`、`rainbond_query_apps`、`rainbond_get_team_apps`、`rainbond_query_components`。resource 和 intent 由 CLI 从 Tool 与输入参数构造并校验,Agent 不得自行拼接。CLI 参数校验失败表示命令尚未发起 Rainbond 查询,必须如实报告本地参数错误,不得表述为授权被拒绝。
|
|
14
20
|
|
|
15
21
|
第一步检查 Node.js 是否存在且主版本不低于 18。Node.js 缺失或低于 18 时,只说明“Rainskills 执行组件需要 Node.js 18 或更高版本”并停止:不选择运行环境,不调用 MCP,不猜测替代命令。只有用户或 agent 明确同意后才安装或升级 Node.js,再从同一原始 intent 继续。
|
|
16
22
|
|
|
17
|
-
固定 launcher 是 `["node", "<home>/.rainbond/lib/rainskills/bin/rainskills.js"]`;运行包版本标记为 `rainskills@0.1.
|
|
23
|
+
固定 launcher 是 `["node", "<home>/.rainbond/lib/rainskills/bin/rainskills.js"]`;运行包版本标记为 `rainskills@0.1.11`,且必须与本技能包 `package.json` 一致。把 launcher 与参数拼成 argv 数组直接执行,禁止 `rainskills@latest` 或执行 shell 字符串。
|
|
18
24
|
|
|
19
|
-
本地 launcher 必须从当前 Skill 所在目录的同级目录定位 `rainbond-platform-installer/scripts/local-runtime.js`,解析为绝对路径后使用 `["node", "<绝对路径>"]`
|
|
25
|
+
本地 launcher 必须从当前 Skill 所在目录的同级目录定位 `rainbond-platform-installer/scripts/local-runtime.js`,解析为绝对路径后使用 `["node", "<绝对路径>"]` 执行。仅在用户明确指定环境时使用 `environment list`;`runtime message` 仍使用本地 launcher。本地 launcher 只读取已安装文件和本机受保护状态,不得访问 npm 或其它网络。
|
|
20
26
|
|
|
21
|
-
所有 Rainbond
|
|
27
|
+
所有 Rainbond 查询必须通过本地 `~/.rainbond/bin/rainskills-tools.js` 的单次 `query` 命令执行。默认环境 argv 固定为 `["node", "<home>/.rainbond/bin/rainskills-tools.js", "query", "<tool>", "--input", "-"]`;明确环境 argv 固定为 `["node", "<home>/.rainbond/bin/rainskills-tools.js", "query", "<tool>", "--environment-id", "<environment-id>", "--input", "-"]`。JSON 只经 stdin 输入。禁止 Agent 直接调用 Rainbond MCP,也不得启动本地 Rainskills MCP 服务;不得把一次查询拆成 `environment list`、`operation begin`、`read`、`operation complete` 四次执行。
|
|
22
28
|
|
|
23
|
-
只有 CLI 返回并通过校验的 `rainskills.next-action.v1` argv 才能执行续接。普通失败一律禁止自动重试:不得再次执行原命令,不得执行 `--help`、`sleep`、`rg`、`grep`,不得搜索 Rainskills
|
|
29
|
+
只有 CLI 返回并通过校验的 `rainskills.next-action.v1` argv 才能执行续接。普通失败一律禁止自动重试:不得再次执行原命令,不得执行 `--help`、`sleep`、`rg`、`grep`,不得搜索 Rainskills 源码;只读查询不得手工补跑 `operation begin` 或 `operation complete`。
|
|
24
30
|
|
|
25
31
|
<!-- rainskills-runtime-contract:start -->
|
|
26
32
|
```json
|
|
27
33
|
{
|
|
28
34
|
"schema": "rainskills.skill-runtime-contract.v1",
|
|
29
|
-
"package_version": "rainskills@0.1.
|
|
35
|
+
"package_version": "rainskills@0.1.11",
|
|
30
36
|
"launcher": ["node", "<home>/.rainbond/lib/rainskills/bin/rainskills.js"],
|
|
31
37
|
"local_launcher": ["node", "<installed-skills-root>/rainbond-platform-installer/scripts/local-runtime.js"],
|
|
32
38
|
"local_argv": {
|
|
33
39
|
"environment-list": ["node", "<installed-skills-root>/rainbond-platform-installer/scripts/local-runtime.js", "environment", "list", "--json"],
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
"
|
|
40
|
+
"runtime-message": ["node", "<installed-skills-root>/rainbond-platform-installer/scripts/local-runtime.js", "runtime", "message", "--id", "<message-id>"],
|
|
41
|
+
"platform-query-default": ["node", "<home>/.rainbond/bin/rainskills-tools.js", "query", "<tool>", "--input", "-"],
|
|
42
|
+
"platform-query-selected": ["node", "<home>/.rainbond/bin/rainskills-tools.js", "query", "<tool>", "--environment-id", "<environment-id>", "--input", "-"]
|
|
37
43
|
},
|
|
38
44
|
"intents": {
|
|
39
45
|
"platform-query": {"required": ["resource"], "optional": ["enterprise_id", "team_id", "app_id"], "enums": {"resource": ["current-user", "current-enterprise", "teams", "regions", "apps", "team-apps", "components"]}}
|
|
@@ -79,7 +85,7 @@ Do not expand a narrow question into related resource queries. Never change reso
|
|
|
79
85
|
- apps in one team/region: `rainbond_get_team_apps({team_name, region_name})`
|
|
80
86
|
- components: `rainbond_query_components({enterprise_id, app_id})`
|
|
81
87
|
5. `enterprise_id`, `team_name`, and `region_name` must come from current session identity, an earlier query result, or explicit user context. `app_id` must be a positive integer; normalize a decimal string before the Tool call and reject values such as `app-123`.
|
|
82
|
-
6. Use the
|
|
88
|
+
6. Use the one-shot contract `query <tool> --input -` when using the CLI. Keep stdout JSON separate from stderr; do not use `2>&1`, `grep`, or `head` to process its output.
|
|
83
89
|
7. Report only fields needed for the question. Avoid email addresses, internal IDs, connection addresses, and configuration unless explicitly requested.
|
|
84
90
|
|
|
85
91
|
## Examples
|
|
@@ -5,16 +5,20 @@ description: "Use only when the user explicitly asks to initialize or link a loc
|
|
|
5
5
|
|
|
6
6
|
# Rainbond Project Init
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
<!-- rainskills-runtime-gate:start -->
|
|
9
|
+
## 运行环境门禁(最高优先级)
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
### CLI 调用格式(强制)
|
|
12
|
+
|
|
13
|
+
所有可变 `call` 都必须使用完整 argv:`call <tool> --input - --operation-id <uuid> --skill-id rainbond-project-init`。CLI 返回确认 ID 后,只能在同一 argv 末尾加入 `--confirm <confirmation-id>`;不得省略 `--skill-id`、猜测参数,或根据泛化错误反复重试。
|
|
14
|
+
|
|
15
|
+
### 多运行环境操作契约
|
|
12
16
|
|
|
13
17
|
Node.js 前置检查通过后,每次请求先执行本地 launcher + `["environment", "list", "--json"]`,按用户明确指定的运行环境选择不可变环境 ID;未指定时只用全局默认环境,默认不可用时停止且不回退。生成 UUID 后执行本地 launcher + `["operation", "begin", "--operation-id", "<uuid>", "--environment-id", "<id>", "--intent-json", "<intent-json>"]`,并在之后每个 Rainbond MCP 调用中加入 `rainskills_operation_id`。环境、团队和应用只属于本次操作,禁止保存项目绑定;同一项目可以部署到多个环境。明确“团队”表示环境内团队;明确“运行环境/平台”表示环境;裸名称同时匹配环境和团队时必须询问。
|
|
14
18
|
|
|
15
19
|
第一步检查 Node.js 是否存在且主版本不低于 18。Node.js 缺失或低于 18 时,只说明“Rainskills 执行组件需要 Node.js 18 或更高版本”并停止:不选择运行环境,不调用 MCP,不猜测替代命令。只有用户或 agent 明确同意后才安装或升级 Node.js,再从同一原始 intent 继续。
|
|
16
20
|
|
|
17
|
-
固定 launcher 是 `["node", "<home>/.rainbond/lib/rainskills/bin/rainskills.js"]`;运行包版本标记为 `rainskills@0.1.
|
|
21
|
+
固定 launcher 是 `["node", "<home>/.rainbond/lib/rainskills/bin/rainskills.js"]`;运行包版本标记为 `rainskills@0.1.11`,且必须与本技能包 `package.json` 一致。把 launcher 与参数拼成 argv 数组直接执行,禁止 `rainskills@latest` 或执行 shell 字符串。
|
|
18
22
|
|
|
19
23
|
本地 launcher 必须从当前 Skill 所在目录的同级目录定位 `rainbond-platform-installer/scripts/local-runtime.js`,解析为绝对路径后使用 `["node", "<绝对路径>"]` 执行。`environment list`、`operation begin`、`operation complete` 和 `runtime message` 只能使用本地 launcher;本地 launcher 只读取已安装文件和本机受保护状态,不得访问 npm 或其它网络。只有用户选定连接或安装运行环境后,才使用上面的固定本地 launcher。
|
|
20
24
|
|
|
@@ -26,7 +30,7 @@ description: "Use only when the user explicitly asks to initialize or link a loc
|
|
|
26
30
|
```json
|
|
27
31
|
{
|
|
28
32
|
"schema": "rainskills.skill-runtime-contract.v1",
|
|
29
|
-
"package_version": "rainskills@0.1.
|
|
33
|
+
"package_version": "rainskills@0.1.11",
|
|
30
34
|
"launcher": ["node", "<home>/.rainbond/lib/rainskills/bin/rainskills.js"],
|
|
31
35
|
"local_launcher": ["node", "<installed-skills-root>/rainbond-platform-installer/scripts/local-runtime.js"],
|
|
32
36
|
"local_argv": {
|
|
@@ -5,16 +5,20 @@ description: "Use when the user explicitly asks to install a local or cloud Rain
|
|
|
5
5
|
|
|
6
6
|
# Rainbond Template Installer
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
<!-- rainskills-runtime-gate:start -->
|
|
9
|
+
## 运行环境门禁(最高优先级)
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
### CLI 调用格式(强制)
|
|
12
|
+
|
|
13
|
+
所有可变 `call` 都必须使用完整 argv:`call <tool> --input - --operation-id <uuid> --skill-id rainbond-template-installer`。CLI 返回确认 ID 后,只能在同一 argv 末尾加入 `--confirm <confirmation-id>`;不得省略 `--skill-id`、猜测参数,或根据泛化错误反复重试。
|
|
14
|
+
|
|
15
|
+
### 多运行环境操作契约
|
|
12
16
|
|
|
13
17
|
Node.js 前置检查通过后,每次请求先执行本地 launcher + `["environment", "list", "--json"]`,按用户明确指定的运行环境选择不可变环境 ID;未指定时只用全局默认环境,默认不可用时停止且不回退。生成 UUID 后执行本地 launcher + `["operation", "begin", "--operation-id", "<uuid>", "--environment-id", "<id>", "--intent-json", "<intent-json>"]`,并在之后每个 Rainbond MCP 调用中加入 `rainskills_operation_id`。环境、团队和应用只属于本次操作,禁止保存项目绑定;同一项目可以部署到多个环境。明确“团队”表示环境内团队;明确“运行环境/平台”表示环境;裸名称同时匹配环境和团队时必须询问。
|
|
14
18
|
|
|
15
19
|
第一步检查 Node.js 是否存在且主版本不低于 18。Node.js 缺失或低于 18 时,只说明“Rainskills 执行组件需要 Node.js 18 或更高版本”并停止:不选择运行环境,不调用 MCP,不猜测替代命令。只有用户或 agent 明确同意后才安装或升级 Node.js,再从同一原始 intent 继续。
|
|
16
20
|
|
|
17
|
-
固定 launcher 是 `["node", "<home>/.rainbond/lib/rainskills/bin/rainskills.js"]`;运行包版本标记为 `rainskills@0.1.
|
|
21
|
+
固定 launcher 是 `["node", "<home>/.rainbond/lib/rainskills/bin/rainskills.js"]`;运行包版本标记为 `rainskills@0.1.11`,且必须与本技能包 `package.json` 一致。把 launcher 与参数拼成 argv 数组直接执行,禁止 `rainskills@latest` 或执行 shell 字符串。
|
|
18
22
|
|
|
19
23
|
本地 launcher 必须从当前 Skill 所在目录的同级目录定位 `rainbond-platform-installer/scripts/local-runtime.js`,解析为绝对路径后使用 `["node", "<绝对路径>"]` 执行。`environment list`、`operation begin`、`operation complete` 和 `runtime message` 只能使用本地 launcher;本地 launcher 只读取已安装文件和本机受保护状态,不得访问 npm 或其它网络。只有用户选定连接或安装运行环境后,才使用上面的固定本地 launcher。
|
|
20
24
|
|
|
@@ -26,7 +30,7 @@ description: "Use when the user explicitly asks to install a local or cloud Rain
|
|
|
26
30
|
```json
|
|
27
31
|
{
|
|
28
32
|
"schema": "rainskills.skill-runtime-contract.v1",
|
|
29
|
-
"package_version": "rainskills@0.1.
|
|
33
|
+
"package_version": "rainskills@0.1.11",
|
|
30
34
|
"launcher": ["node", "<home>/.rainbond/lib/rainskills/bin/rainskills.js"],
|
|
31
35
|
"local_launcher": ["node", "<installed-skills-root>/rainbond-platform-installer/scripts/local-runtime.js"],
|
|
32
36
|
"local_argv": {
|