rainskills 0.1.0-rc.0
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/LICENSE +201 -0
- package/README.md +374 -0
- package/bin/rainskills.js +71 -0
- package/install.sh +1919 -0
- package/package.json +55 -0
- package/rainbond-app-assistant/SKILL.md +1319 -0
- package/rainbond-app-assistant/evals/01-linked-topology-missing.expected.yaml +21 -0
- package/rainbond-app-assistant/evals/01-linked-topology-missing.response.md +53 -0
- package/rainbond-app-assistant/evals/02-linked-topology-building.expected.yaml +19 -0
- package/rainbond-app-assistant/evals/02-linked-topology-building.response.md +53 -0
- package/rainbond-app-assistant/evals/03-runtime-healthy-delivery-unknown.expected.yaml +19 -0
- package/rainbond-app-assistant/evals/03-runtime-healthy-delivery-unknown.response.md +53 -0
- package/rainbond-app-assistant/evals/04-delivered-stop-without-promotion.expected.yaml +21 -0
- package/rainbond-app-assistant/evals/04-delivered-stop-without-promotion.response.md +58 -0
- package/rainbond-app-assistant/evals/05-delivered-explicit-dev-to-test.expected.yaml +21 -0
- package/rainbond-app-assistant/evals/05-delivered-explicit-dev-to-test.response.md +80 -0
- package/rainbond-app-assistant/evals/06-manual-validation-stop.expected.yaml +16 -0
- package/rainbond-app-assistant/evals/06-manual-validation-stop.response.md +58 -0
- package/rainbond-app-assistant/evals/07-cluster-capacity-blocked.expected.yaml +15 -0
- package/rainbond-app-assistant/evals/07-cluster-capacity-blocked.response.md +53 -0
- package/rainbond-app-assistant/evals/08-code-build-handoff-stop.expected.yaml +21 -0
- package/rainbond-app-assistant/evals/08-code-build-handoff-stop.response.md +56 -0
- package/rainbond-app-assistant/evals/09-source-backed-failure-no-fallback.expected.yaml +22 -0
- package/rainbond-app-assistant/evals/09-source-backed-failure-no-fallback.response.md +56 -0
- package/rainbond-app-assistant/evals/10-identity-ambiguous-stop.expected.yaml +21 -0
- package/rainbond-app-assistant/evals/10-identity-ambiguous-stop.response.md +45 -0
- package/rainbond-app-assistant/evals/11-delivered-with-proxy-and-local-binding.expected.yaml +28 -0
- package/rainbond-app-assistant/evals/11-delivered-with-proxy-and-local-binding.response.md +64 -0
- package/rainbond-app-assistant/evals/12-complex-suite-needs-descriptor-stop.expected.yaml +24 -0
- package/rainbond-app-assistant/evals/12-complex-suite-needs-descriptor-stop.response.md +45 -0
- package/rainbond-app-assistant/evals/13-explicit-git-url-locks-source.expected.yaml +28 -0
- package/rainbond-app-assistant/evals/13-explicit-git-url-locks-source.response.md +53 -0
- package/rainbond-app-assistant/evals/14-strategy-switch-cleans-residue.expected.yaml +22 -0
- package/rainbond-app-assistant/evals/14-strategy-switch-cleans-residue.response.md +53 -0
- package/rainbond-app-assistant/evals/15-turn-discipline-reuse-alias.expected.yaml +23 -0
- package/rainbond-app-assistant/evals/15-turn-discipline-reuse-alias.response.md +53 -0
- package/rainbond-app-assistant/schemas/app-assistant-result.schema.yaml +279 -0
- package/rainbond-app-assistant/scripts/run_app_assistant_evals.py +80 -0
- package/rainbond-app-assistant/scripts/validate_app_assistant_output.py +935 -0
- package/rainbond-app-version-assistant/SKILL.md +444 -0
- package/rainbond-delivery-verifier/SKILL.md +372 -0
- package/rainbond-delivery-verifier/evals/01-delivered-verified.expected.yaml +19 -0
- package/rainbond-delivery-verifier/evals/01-delivered-verified.response.md +31 -0
- package/rainbond-delivery-verifier/evals/02-delivered-manual-validation.expected.yaml +19 -0
- package/rainbond-delivery-verifier/evals/02-delivered-manual-validation.response.md +31 -0
- package/rainbond-delivery-verifier/evals/03-partially-delivered-building.expected.yaml +20 -0
- package/rainbond-delivery-verifier/evals/03-partially-delivered-building.response.md +31 -0
- package/rainbond-delivery-verifier/evals/04-blocked-capacity.expected.yaml +18 -0
- package/rainbond-delivery-verifier/evals/04-blocked-capacity.response.md +31 -0
- package/rainbond-delivery-verifier/evals/05-blocked-no-usable-url.expected.yaml +20 -0
- package/rainbond-delivery-verifier/evals/05-blocked-no-usable-url.response.md +31 -0
- package/rainbond-delivery-verifier/evals/06-blocked-runtime-unhealthy.expected.yaml +19 -0
- package/rainbond-delivery-verifier/evals/06-blocked-runtime-unhealthy.response.md +31 -0
- package/rainbond-delivery-verifier/schemas/delivery-verification-result.schema.yaml +84 -0
- package/rainbond-delivery-verifier/scripts/run_delivery_verifier_evals.py +78 -0
- package/rainbond-delivery-verifier/scripts/validate_delivery_verifier_output.py +728 -0
- package/rainbond-env-sync/SKILL.md +496 -0
- package/rainbond-fullstack-bootstrap/SKILL.md +262 -0
- package/rainbond-fullstack-bootstrap/evals/01-reuse-only.expected.yaml +27 -0
- package/rainbond-fullstack-bootstrap/evals/01-reuse-only.prompt.md +1 -0
- package/rainbond-fullstack-bootstrap/evals/01-reuse-only.response.md +43 -0
- package/rainbond-fullstack-bootstrap/evals/02-deferred-dependency.expected.yaml +27 -0
- package/rainbond-fullstack-bootstrap/evals/02-deferred-dependency.prompt.md +1 -0
- package/rainbond-fullstack-bootstrap/evals/02-deferred-dependency.response.md +44 -0
- package/rainbond-fullstack-bootstrap/evals/03-capacity-blocked.expected.yaml +26 -0
- package/rainbond-fullstack-bootstrap/evals/03-capacity-blocked.prompt.md +1 -0
- package/rainbond-fullstack-bootstrap/evals/03-capacity-blocked.response.md +43 -0
- package/rainbond-fullstack-bootstrap/evals/04-template-skip.expected.yaml +31 -0
- package/rainbond-fullstack-bootstrap/evals/04-template-skip.prompt.md +1 -0
- package/rainbond-fullstack-bootstrap/evals/04-template-skip.response.md +43 -0
- package/rainbond-fullstack-bootstrap/evals/05-source-ambiguity-stop.expected.yaml +33 -0
- package/rainbond-fullstack-bootstrap/evals/05-source-ambiguity-stop.prompt.md +1 -0
- package/rainbond-fullstack-bootstrap/evals/05-source-ambiguity-stop.response.md +43 -0
- package/rainbond-fullstack-bootstrap/evals/06-external-artifact-unreachable.expected.yaml +23 -0
- package/rainbond-fullstack-bootstrap/evals/06-external-artifact-unreachable.response.md +39 -0
- package/rainbond-fullstack-bootstrap/evals/07-provider-connection-contract.expected.yaml +29 -0
- package/rainbond-fullstack-bootstrap/evals/07-provider-connection-contract.response.md +43 -0
- package/rainbond-fullstack-bootstrap/evals/08-explicit-dependency-after-manual-components.expected.yaml +30 -0
- package/rainbond-fullstack-bootstrap/evals/08-explicit-dependency-after-manual-components.prompt.md +1 -0
- package/rainbond-fullstack-bootstrap/evals/08-explicit-dependency-after-manual-components.response.md +43 -0
- package/rainbond-fullstack-bootstrap/evals/09-inferred-provider-consumer-gate.expected.yaml +32 -0
- package/rainbond-fullstack-bootstrap/evals/09-inferred-provider-consumer-gate.prompt.md +1 -0
- package/rainbond-fullstack-bootstrap/evals/09-inferred-provider-consumer-gate.response.md +41 -0
- package/rainbond-fullstack-bootstrap/evals/10-compose-service-name-not-hostname.expected.yaml +34 -0
- package/rainbond-fullstack-bootstrap/evals/10-compose-service-name-not-hostname.prompt.md +1 -0
- package/rainbond-fullstack-bootstrap/evals/10-compose-service-name-not-hostname.response.md +43 -0
- package/rainbond-fullstack-bootstrap/evals/11-reverse-proxy-not-dropped.expected.yaml +46 -0
- package/rainbond-fullstack-bootstrap/evals/11-reverse-proxy-not-dropped.prompt.md +1 -0
- package/rainbond-fullstack-bootstrap/evals/11-reverse-proxy-not-dropped.response.md +48 -0
- package/rainbond-fullstack-bootstrap/evals/12-optional-services-disclose-not-deploy.expected.yaml +43 -0
- package/rainbond-fullstack-bootstrap/evals/12-optional-services-disclose-not-deploy.prompt.md +1 -0
- package/rainbond-fullstack-bootstrap/evals/12-optional-services-disclose-not-deploy.response.md +63 -0
- package/rainbond-fullstack-bootstrap/evals/13-env-reference-dependency-completeness.expected.yaml +47 -0
- package/rainbond-fullstack-bootstrap/evals/13-env-reference-dependency-completeness.prompt.md +1 -0
- package/rainbond-fullstack-bootstrap/evals/13-env-reference-dependency-completeness.response.md +60 -0
- package/rainbond-fullstack-bootstrap/modules/10-context-loading.md +157 -0
- package/rainbond-fullstack-bootstrap/modules/20-scope-and-boundaries.md +105 -0
- package/rainbond-fullstack-bootstrap/modules/30-creation-rules.md +337 -0
- package/rainbond-fullstack-bootstrap/modules/40-source-and-package-rules.md +245 -0
- package/rainbond-fullstack-bootstrap/modules/50-workflow-and-convergence.md +198 -0
- package/rainbond-fullstack-bootstrap/modules/60-verification-and-handoffs.md +143 -0
- package/rainbond-fullstack-bootstrap/modules/70-output-contract.md +152 -0
- package/rainbond-fullstack-bootstrap/references/manifest-v1-reference.md +150 -0
- package/rainbond-fullstack-bootstrap/references/quick-reference.md +101 -0
- package/rainbond-fullstack-bootstrap/references/source-build-parameter-guide.md +264 -0
- package/rainbond-fullstack-bootstrap/references/sql-init-recipe.md +83 -0
- package/rainbond-fullstack-bootstrap/schemas/bootstrap-result.schema.yaml +217 -0
- package/rainbond-fullstack-bootstrap/scripts/run_bootstrap_evals.py +74 -0
- package/rainbond-fullstack-bootstrap/scripts/validate_bootstrap_output.py +615 -0
- package/rainbond-fullstack-troubleshooter/SKILL.md +870 -0
- package/rainbond-fullstack-troubleshooter/evals/01-source-build-failed.expected.yaml +29 -0
- package/rainbond-fullstack-troubleshooter/evals/01-source-build-failed.response.md +55 -0
- package/rainbond-fullstack-troubleshooter/evals/02-source-build-still-running.expected.yaml +20 -0
- package/rainbond-fullstack-troubleshooter/evals/02-source-build-still-running.response.md +53 -0
- package/rainbond-fullstack-troubleshooter/evals/03-dependency-missing.expected.yaml +21 -0
- package/rainbond-fullstack-troubleshooter/evals/03-dependency-missing.response.md +59 -0
- package/rainbond-fullstack-troubleshooter/evals/04-wrong-connection-values.expected.yaml +19 -0
- package/rainbond-fullstack-troubleshooter/evals/04-wrong-connection-values.response.md +58 -0
- package/rainbond-fullstack-troubleshooter/evals/05-env-naming-incompatibility.expected.yaml +18 -0
- package/rainbond-fullstack-troubleshooter/evals/05-env-naming-incompatibility.response.md +59 -0
- package/rainbond-fullstack-troubleshooter/evals/06-frontend-access-path-issue.expected.yaml +21 -0
- package/rainbond-fullstack-troubleshooter/evals/06-frontend-access-path-issue.response.md +56 -0
- package/rainbond-fullstack-troubleshooter/evals/07-cluster-capacity-blocked.expected.yaml +20 -0
- package/rainbond-fullstack-troubleshooter/evals/07-cluster-capacity-blocked.response.md +57 -0
- package/rainbond-fullstack-troubleshooter/evals/08-code-or-build-handoff-needed.expected.yaml +21 -0
- package/rainbond-fullstack-troubleshooter/evals/08-code-or-build-handoff-needed.response.md +55 -0
- package/rainbond-fullstack-troubleshooter/evals/09-external-artifact-unreachable.expected.yaml +28 -0
- package/rainbond-fullstack-troubleshooter/evals/09-external-artifact-unreachable.response.md +53 -0
- package/rainbond-fullstack-troubleshooter/schemas/troubleshoot-result.schema.yaml +217 -0
- package/rainbond-fullstack-troubleshooter/scripts/run_troubleshooter_evals.py +80 -0
- package/rainbond-fullstack-troubleshooter/scripts/validate_troubleshoot_output.py +789 -0
- package/rainbond-project-init/SKILL.md +1001 -0
- package/rainbond-template-installer/SKILL.md +410 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
Apache License
|
|
2
|
+
Version 2.0, January 2004
|
|
3
|
+
http://www.apache.org/licenses/
|
|
4
|
+
|
|
5
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
6
|
+
|
|
7
|
+
1. Definitions.
|
|
8
|
+
|
|
9
|
+
"License" shall mean the terms and conditions for use, reproduction,
|
|
10
|
+
and distribution as defined by Sections 1 through 9 of this document.
|
|
11
|
+
|
|
12
|
+
"Licensor" shall mean the copyright owner or entity authorized by
|
|
13
|
+
the copyright owner that is granting the License.
|
|
14
|
+
|
|
15
|
+
"Legal Entity" shall mean the union of the acting entity and all
|
|
16
|
+
other entities that control, are controlled by, or are under common
|
|
17
|
+
control with that entity. For the purposes of this definition,
|
|
18
|
+
"control" means (i) the power, direct or indirect, to cause the
|
|
19
|
+
direction or management of such entity, whether by contract or
|
|
20
|
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
21
|
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
22
|
+
|
|
23
|
+
"You" (or "Your") shall mean an individual or Legal Entity
|
|
24
|
+
exercising permissions granted by this License.
|
|
25
|
+
|
|
26
|
+
"Source" form shall mean the preferred form for making modifications,
|
|
27
|
+
including but not limited to software source code, documentation
|
|
28
|
+
source, and configuration files.
|
|
29
|
+
|
|
30
|
+
"Object" form shall mean any form resulting from mechanical
|
|
31
|
+
transformation or translation of a Source form, including but
|
|
32
|
+
not limited to compiled object code, generated documentation,
|
|
33
|
+
and conversions to other media types.
|
|
34
|
+
|
|
35
|
+
"Work" shall mean the work of authorship, whether in Source or
|
|
36
|
+
Object form, made available under the License, as indicated by a
|
|
37
|
+
copyright notice that is included in or attached to the work
|
|
38
|
+
(an example is provided in the Appendix below).
|
|
39
|
+
|
|
40
|
+
"Derivative Works" shall mean any work, whether in Source or Object
|
|
41
|
+
form, that is based on (or derived from) the Work and for which the
|
|
42
|
+
editorial revisions, annotations, elaborations, or other modifications
|
|
43
|
+
represent, as a whole, an original work of authorship. For the purposes
|
|
44
|
+
of this License, Derivative Works shall not include works that remain
|
|
45
|
+
separable from, or merely link (or bind by name) to the interfaces of,
|
|
46
|
+
the Work and Derivative Works thereof.
|
|
47
|
+
|
|
48
|
+
"Contribution" shall mean any work of authorship, including
|
|
49
|
+
the original version of the Work and any modifications or additions
|
|
50
|
+
to that Work or Derivative Works thereof, that is intentionally
|
|
51
|
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
52
|
+
or by an individual or Legal Entity authorized to submit on behalf of
|
|
53
|
+
the copyright owner. For the purposes of this definition, "submitted"
|
|
54
|
+
means any form of electronic, verbal, or written communication sent
|
|
55
|
+
to the Licensor or its representatives, including but not limited to
|
|
56
|
+
communication on electronic mailing lists, source code control systems,
|
|
57
|
+
and issue tracking systems that are managed by, or on behalf of, the
|
|
58
|
+
Licensor for the purpose of discussing and improving the Work, but
|
|
59
|
+
excluding communication that is conspicuously marked or otherwise
|
|
60
|
+
designated in writing by the copyright owner as "Not a Contribution."
|
|
61
|
+
|
|
62
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
63
|
+
on behalf of whom a Contribution has been received by Licensor and
|
|
64
|
+
subsequently incorporated within the Work.
|
|
65
|
+
|
|
66
|
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
67
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
68
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
69
|
+
copyright license to reproduce, prepare Derivative Works of,
|
|
70
|
+
publicly display, publicly perform, sublicense, and distribute the
|
|
71
|
+
Work and such Derivative Works in Source or Object form.
|
|
72
|
+
|
|
73
|
+
3. Grant of Patent License. Subject to the terms and conditions of
|
|
74
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
75
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
76
|
+
(except as stated in this section) patent license to make, have made,
|
|
77
|
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
78
|
+
where such license applies only to those patent claims licensable
|
|
79
|
+
by such Contributor that are necessarily infringed by their
|
|
80
|
+
Contribution(s) alone or by combination of their Contribution(s)
|
|
81
|
+
with the Work to which such Contribution(s) was submitted. If You
|
|
82
|
+
institute patent litigation against any entity (including a
|
|
83
|
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
84
|
+
or a Contribution incorporated within the Work constitutes direct
|
|
85
|
+
or contributory patent infringement, then any patent licenses
|
|
86
|
+
granted to You under this License for that Work shall terminate
|
|
87
|
+
as of the date such litigation is filed.
|
|
88
|
+
|
|
89
|
+
4. Redistribution. You may reproduce and distribute copies of the
|
|
90
|
+
Work or Derivative Works thereof in any medium, with or without
|
|
91
|
+
modifications, and in Source or Object form, provided that You
|
|
92
|
+
meet the following conditions:
|
|
93
|
+
|
|
94
|
+
(a) You must give any other recipients of the Work or
|
|
95
|
+
Derivative Works a copy of this License; and
|
|
96
|
+
|
|
97
|
+
(b) You must cause any modified files to carry prominent notices
|
|
98
|
+
stating that You changed the files; and
|
|
99
|
+
|
|
100
|
+
(c) You must retain, in the Source form of any Derivative Works
|
|
101
|
+
that You distribute, all copyright, patent, trademark, and
|
|
102
|
+
attribution notices from the Source form of the Work,
|
|
103
|
+
excluding those notices that do not pertain to any part of
|
|
104
|
+
the Derivative Works; and
|
|
105
|
+
|
|
106
|
+
(d) If the Work includes a "NOTICE" text file as part of its
|
|
107
|
+
distribution, then any Derivative Works that You distribute must
|
|
108
|
+
include a readable copy of the attribution notices contained
|
|
109
|
+
within such NOTICE file, excluding those notices that do not
|
|
110
|
+
pertain to any part of the Derivative Works, in at least one
|
|
111
|
+
of the following places: within a NOTICE text file distributed
|
|
112
|
+
as part of the Derivative Works; within the Source form or
|
|
113
|
+
documentation, if provided along with the Derivative Works; or,
|
|
114
|
+
within a display generated by the Derivative Works, if and
|
|
115
|
+
wherever such third-party notices normally appear. The contents
|
|
116
|
+
of the NOTICE file are for informational purposes only and
|
|
117
|
+
do not modify the License. You may add Your own attribution
|
|
118
|
+
notices within Derivative Works that You distribute, alongside
|
|
119
|
+
or as an addendum to the NOTICE text from the Work, provided
|
|
120
|
+
that such additional attribution notices cannot be construed
|
|
121
|
+
as modifying the License.
|
|
122
|
+
|
|
123
|
+
You may add Your own copyright statement to Your modifications and
|
|
124
|
+
may provide additional or different license terms and conditions
|
|
125
|
+
for use, reproduction, or distribution of Your modifications, or
|
|
126
|
+
for any such Derivative Works as a whole, provided Your use,
|
|
127
|
+
reproduction, and distribution of the Work otherwise complies with
|
|
128
|
+
the conditions stated in this License.
|
|
129
|
+
|
|
130
|
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
131
|
+
any Contribution intentionally submitted for inclusion in the Work
|
|
132
|
+
by You to the Licensor shall be under the terms and conditions of
|
|
133
|
+
this License, without any additional terms or conditions.
|
|
134
|
+
Notwithstanding the above, nothing herein shall supersede or modify
|
|
135
|
+
the terms of any separate license agreement you may have executed
|
|
136
|
+
with Licensor regarding such Contributions.
|
|
137
|
+
|
|
138
|
+
6. Trademarks. This License does not grant permission to use the trade
|
|
139
|
+
names, trademarks, service marks, or product names of the Licensor,
|
|
140
|
+
except as required for describing the origin of the Work and
|
|
141
|
+
reproducing the content of the NOTICE file.
|
|
142
|
+
|
|
143
|
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
144
|
+
agreed to in writing, Licensor provides the Work (and each
|
|
145
|
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
146
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
147
|
+
implied, including, without limitation, any warranties or conditions
|
|
148
|
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
149
|
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
150
|
+
appropriateness of using or redistributing the Work and assume any
|
|
151
|
+
risks associated with Your exercise of permissions under this License.
|
|
152
|
+
|
|
153
|
+
8. Limitation of Liability. In no event and under no legal theory,
|
|
154
|
+
whether in tort (including negligence), contract, or otherwise,
|
|
155
|
+
unless required by applicable law (such as deliberate and grossly
|
|
156
|
+
negligent acts) or agreed to in writing, shall any Contributor be
|
|
157
|
+
liable to You for damages, including any direct, indirect, special,
|
|
158
|
+
incidental, or consequential damages of any character arising as a
|
|
159
|
+
result of this License or out of the use or inability to use the
|
|
160
|
+
Work (including but not limited to damages for loss of goodwill,
|
|
161
|
+
work stoppage, computer failure or malfunction, or any and all
|
|
162
|
+
other commercial damages or losses), even if such Contributor
|
|
163
|
+
has been advised of the possibility of such damages.
|
|
164
|
+
|
|
165
|
+
9. Accepting Warranty or Support. While redistributing
|
|
166
|
+
the Work or Derivative Works thereof, You may choose to offer,
|
|
167
|
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
168
|
+
or other liability obligations and/or rights consistent with this
|
|
169
|
+
License. However, in accepting such obligations, You may act only
|
|
170
|
+
on Your own behalf and on Your sole responsibility, not on behalf
|
|
171
|
+
of any other Contributor, and only if You agree to indemnify,
|
|
172
|
+
defend, and hold each Contributor harmless for any liability
|
|
173
|
+
incurred by, or claims asserted against, such Contributor by reason
|
|
174
|
+
of your accepting any such warranty or support.
|
|
175
|
+
|
|
176
|
+
END OF TERMS AND CONDITIONS
|
|
177
|
+
|
|
178
|
+
APPENDIX: How to apply the Apache License to your work.
|
|
179
|
+
|
|
180
|
+
To apply the Apache License to your work, attach the following
|
|
181
|
+
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
182
|
+
replaced with your own identifying information. (Don't include
|
|
183
|
+
the brackets!) The text should be enclosed in the appropriate
|
|
184
|
+
comment syntax for the file format. We also recommend that a
|
|
185
|
+
file or class name and description of purpose be included on the
|
|
186
|
+
same "printed page" as the copyright notice for easier
|
|
187
|
+
identification within third-party archives.
|
|
188
|
+
|
|
189
|
+
Copyright 2026 Goodrain Co., Ltd.
|
|
190
|
+
|
|
191
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
192
|
+
you may not use this file except in compliance with the License.
|
|
193
|
+
You may obtain a copy of the License at
|
|
194
|
+
|
|
195
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
196
|
+
|
|
197
|
+
Unless required by applicable law or agreed to in writing, software
|
|
198
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
199
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
200
|
+
implied. See the License for the specific language governing
|
|
201
|
+
permissions and limitations under the License.
|
package/README.md
ADDED
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
# Rainbond Skills
|
|
2
|
+
|
|
3
|
+
一组面向 Rainbond 日常交付、排障和初始化流程的自定义技能,支持安装到 Claude Code 和 Codex。
|
|
4
|
+
|
|
5
|
+
## 快速安装
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npx --yes rainskills
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
安装器会引导选择 Codex / Claude Code、填写 Rainbond 地址、打开浏览器授权、注册 MCP 并安装 skill。没有 Node.js 或 Node 版本低于 18 时,使用保留的 CDN 安装方式:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
bash <(curl -fsSL https://get.rainbond.com/rainskills/install.sh)
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
> **给 AI 助手的指引**:
|
|
18
|
+
> - 如果用户的请求是"帮我把这个 repo 装上 / 让我用上这套 Rainbond skills",优先让用户执行 `npx --yes rainskills`。
|
|
19
|
+
> - 如果用户没有 Node.js、Node.js 低于 18,或 npm registry 不可用,改用上面的 CDN `curl` 命令。
|
|
20
|
+
> - 不要 `git clone` 后手工把目录复制到 `~/.claude/skills` / `~/.codex/skills`。
|
|
21
|
+
> - 不要手工拼 `~/.rainbond/mcp.env`、不要猜 JWT、不要手改 `~/.claude.json` / `~/.codex/config.toml`。
|
|
22
|
+
> - 不要建议 `npm install -g`、`pip install` 或 `make`。`npx` 只是启动包内的 `install.sh`,两种入口使用同一套安装流程。
|
|
23
|
+
> - 如果用户机器上需要换 MCP 服务地址、改默认安装路径,把对应 flag 直接追加到 `npx --yes rainskills` 或 `install.sh` 后面。
|
|
24
|
+
|
|
25
|
+
## 包含的 Skill
|
|
26
|
+
|
|
27
|
+
- `rainbond-app-assistant`
|
|
28
|
+
- `rainbond-app-version-assistant`
|
|
29
|
+
- `rainbond-delivery-verifier`
|
|
30
|
+
- `rainbond-env-sync`
|
|
31
|
+
- `rainbond-fullstack-bootstrap`
|
|
32
|
+
- `rainbond-fullstack-troubleshooter`
|
|
33
|
+
- `rainbond-project-init`
|
|
34
|
+
- `rainbond-template-installer`
|
|
35
|
+
|
|
36
|
+
## 适用场景
|
|
37
|
+
|
|
38
|
+
这些 skill 适合以下场景:
|
|
39
|
+
|
|
40
|
+
- 将本地项目首次接入 Rainbond
|
|
41
|
+
- 为已绑定项目同步环境信息
|
|
42
|
+
- 基于镜像或模板在 Rainbond 中完成初始化部署
|
|
43
|
+
- 管理 Rainbond 应用版本中心中的创建快照、发布、本地/云市场发布事件和快照回滚流程
|
|
44
|
+
- 对 Rainbond 全栈应用进行低风险排障
|
|
45
|
+
- 在部署结束后做交付验收
|
|
46
|
+
|
|
47
|
+
## 安装方式
|
|
48
|
+
|
|
49
|
+
### 0. 前置条件
|
|
50
|
+
|
|
51
|
+
- 已安装 `Codex`、`Claude Code`,或两者之一
|
|
52
|
+
- 推荐 Node.js 22 或 24;`npx` 入口最低支持 Node.js 18
|
|
53
|
+
- Node.js 18/20 已结束维护,安装器会警告但仍继续;Node.js 低于 18 请使用 CDN 安装方式
|
|
54
|
+
- 本机可执行 `bash`、`curl`、`python3`;CDN 入口还需要 `tar`
|
|
55
|
+
- 已有可登录的 Rainbond 账号
|
|
56
|
+
|
|
57
|
+
### 1. 一行命令安装(推荐)
|
|
58
|
+
|
|
59
|
+
支持 macOS 和 Linux:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
npx --yes rainskills
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
npm 包已经携带完整安装器和所有 skill,不会再次下载仓库 tarball。`npx` 保留终端交互,因此选择客户端、填写私有化地址和浏览器授权流程与原安装脚本完全一致。
|
|
66
|
+
|
|
67
|
+
常用参数可以直接追加:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
npx --yes rainskills codex --saas
|
|
71
|
+
npx --yes rainskills claude --self-hosted --rainbond-url <url>
|
|
72
|
+
npx --yes rainskills all --force
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### 2. CDN 安装(保留的兜底方式)
|
|
76
|
+
|
|
77
|
+
国内推荐用 OSS 入口(CDN 加速,无需翻墙):
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
bash <(curl -fsSL https://get.rainbond.com/rainskills/install.sh)
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
海外或源码党可以直接用 GitHub 入口:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
bash <(curl -fsSL https://raw.githubusercontent.com/goodrain/rainskills/main/install.sh)
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
脚本会按 **用户覆盖 → OSS → GitHub** 的顺序自动尝试下载仓库 tarball,解压到 `~/.rainbond/skills`(可通过 `RAINBOND_SKILLS_HOME` 覆盖),然后继续走交互式安装流程。
|
|
90
|
+
|
|
91
|
+
可通过环境变量自定义下载源:
|
|
92
|
+
|
|
93
|
+
- `RAINBOND_SKILLS_TARBALL_URL` — 用户显式指定的 tarball URL(最高优先)
|
|
94
|
+
- `RAINBOND_SKILLS_OSS_URL` — OSS tarball URL(默认 `https://get.rainbond.com/rainskills/rainskills-latest.tar.gz`)
|
|
95
|
+
- `RAINBOND_SKILLS_HOME` — 安装目录(默认 `~/.rainbond/skills`)
|
|
96
|
+
|
|
97
|
+
> 谨慎模式:如果不想让远程脚本直接执行,可以先下载再阅读:
|
|
98
|
+
>
|
|
99
|
+
> ```bash
|
|
100
|
+
> curl -fsSLO https://get.rainbond.com/rainskills/install.sh
|
|
101
|
+
> less install.sh # 自行审阅
|
|
102
|
+
> bash install.sh
|
|
103
|
+
> ```
|
|
104
|
+
|
|
105
|
+
### 3. 已有本地仓库
|
|
106
|
+
|
|
107
|
+
如果你已经 `git clone` 了 rainbond-skills 仓库,直接进入仓库根目录执行:
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
./install.sh
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
如果只是让 Codex 或 CI 在非交互模式下覆盖本地 skill,直接执行 `./install.sh --force` 即可;未提供 Rainbond 参数时,脚本会自动跳过 MCP 配置。
|
|
114
|
+
|
|
115
|
+
### 安装脚本会做的事
|
|
116
|
+
|
|
117
|
+
不论使用 npx、CDN 还是本地仓库,安装器都会引导你完成这些动作:
|
|
118
|
+
|
|
119
|
+
- 选择安装到 `Codex`、`Claude Code`,或两个都装
|
|
120
|
+
- 选择 Rainbond 部署形态:
|
|
121
|
+
- **Rainbond Cloud(SaaS,默认)**:地址固定为 `https://run.rainbond.com`
|
|
122
|
+
- **私有化部署**:你自己输入 Console 地址;交互选择后会先醒目提示 Rainbond 前置条件、官方快速安装命令和安装文档,但不会中断 RainSkills 流程
|
|
123
|
+
- 浏览器中完成登录并授权(无需在终端输入用户名/密码)
|
|
124
|
+
- 自动接收 JWT 并写入 `~/.rainbond/mcp.env`
|
|
125
|
+
- 自动配置 `Codex` / `Claude Code` 的 RainSkills 专用 MCP 地址
|
|
126
|
+
- 自动把环境变量加载逻辑写入当前 shell 的 rc 文件
|
|
127
|
+
- 自动验证所选客户端的专用 MCP 地址是否可用:
|
|
128
|
+
- Codex:`/console/mcp/rainskills/codex/query`
|
|
129
|
+
- Claude Code:`/console/mcp/rainskills/claude-code/query`
|
|
130
|
+
|
|
131
|
+
#### 安装效果统计
|
|
132
|
+
|
|
133
|
+
安装脚本会把安装流程状态异步上报到固定地址 `https://log.rainbond.com/api/rainskills/installations`,用于统计脚本执行、授权和配置成功率。每次执行使用一个随机的 `install_attempt_id` 串联以下阶段:
|
|
134
|
+
|
|
135
|
+
- `started`:脚本开始执行
|
|
136
|
+
- `authorized`:完成 Rainbond 授权,并取得当前企业的 `eid`
|
|
137
|
+
- `configured`:Codex / Claude Code MCP 配置完成
|
|
138
|
+
- `failed`:流程失败,仅记录固定的失败阶段和分类
|
|
139
|
+
|
|
140
|
+
上报字段只包含安装尝试 ID、`eid`、客户端类型、安装或刷新动作、阶段和状态。不会上报 JWT、账号、密码、用户名、邮箱、Rainbond 地址、原始错误信息或本地代码。统计请求在后台执行;统计服务不可用、超时或企业信息读取失败都不会改变原安装结果。
|
|
141
|
+
|
|
142
|
+
#### 浏览器登录是怎么发生的
|
|
143
|
+
|
|
144
|
+
1. 安装脚本在本机起一个临时回调(`http://127.0.0.1:<随机端口>/cli-callback`)。
|
|
145
|
+
2. 自动打开浏览器到 `<Rainbond 地址>/#/cli-auth?callback=...&state=...`。
|
|
146
|
+
3. 浏览器里你按部署形态用现成方式登录(SaaS 是手机号验证码、私有化通常是用户名密码或 SSO)。
|
|
147
|
+
4. 在「授权命令行工具」页面点确认,浏览器把当前账号的 JWT 发回本机回调。
|
|
148
|
+
5. 安装脚本校验 `state`、保存 token,然后继续走完 MCP 配置和验证。
|
|
149
|
+
|
|
150
|
+
默认技能安装目录:
|
|
151
|
+
|
|
152
|
+
- `~/.claude/skills`
|
|
153
|
+
- `~/.codex/skills`
|
|
154
|
+
|
|
155
|
+
#### 显式指定部署形态
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
# npx 模式
|
|
159
|
+
npx --yes rainskills all --saas
|
|
160
|
+
npx --yes rainskills all --self-hosted --rainbond-url <url>
|
|
161
|
+
|
|
162
|
+
# CDN 模式:参数追加在脚本之后
|
|
163
|
+
bash <(curl -fsSL https://get.rainbond.com/rainskills/install.sh) all --saas
|
|
164
|
+
bash <(curl -fsSL https://get.rainbond.com/rainskills/install.sh) all --self-hosted --rainbond-url <url>
|
|
165
|
+
|
|
166
|
+
# 本地仓库模式
|
|
167
|
+
./install.sh all --saas # Rainbond Cloud
|
|
168
|
+
./install.sh all --self-hosted --rainbond-url <url> # 私有化
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### 4. 只安装到单个平台
|
|
172
|
+
|
|
173
|
+
只装并配置 Claude Code:
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
npx --yes rainskills claude
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
只装并配置 Codex:
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
npx --yes rainskills codex
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
同时装并配置两个平台:
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
npx --yes rainskills all
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### 5. CI / 无桌面环境兜底
|
|
192
|
+
|
|
193
|
+
非交互场景(CI、SSH 远程会话、不带浏览器的服务器)下浏览器登录拿不到 token,可以两条路:
|
|
194
|
+
|
|
195
|
+
1. **预先在浏览器拿到 JWT 再传进来**(推荐):
|
|
196
|
+
|
|
197
|
+
```bash
|
|
198
|
+
./install.sh all --non-interactive \
|
|
199
|
+
--self-hosted --rainbond-url https://your-rainbond.example.com \
|
|
200
|
+
--token "$RAINBOND_JWT"
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
`RAINBOND_JWT` 可以从浏览器 cookie 拿,或在浏览器里访问 `/#/cli-auth?...` 走一次授权页人工拷贝。
|
|
204
|
+
|
|
205
|
+
2. **私有化兼容用户名/密码(已不推荐,未来移除)**:
|
|
206
|
+
|
|
207
|
+
```bash
|
|
208
|
+
./install.sh all --non-interactive \
|
|
209
|
+
--self-hosted --rainbond-url http://your-rainbond.example.com:7070 \
|
|
210
|
+
--username admin \
|
|
211
|
+
--allow-insecure-http
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
仅当部署没有开 `USE_SAAS`、确实是用户名/密码模式时可用;SaaS 模式下没有这个登录入口。
|
|
215
|
+
|
|
216
|
+
如果你的 Rainbond 还是 `http://`,安装脚本会明确提示风险,并要求你确认(交互模式)或要求显式 `--allow-insecure-http`(非交互模式)。
|
|
217
|
+
|
|
218
|
+
### 6. 当前终端的环境变量说明
|
|
219
|
+
|
|
220
|
+
脚本会把 JWT 保存到:
|
|
221
|
+
|
|
222
|
+
```bash
|
|
223
|
+
~/.rainbond/mcp.env
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
并自动把下面这类加载逻辑写入当前 shell 的 rc 文件:
|
|
227
|
+
|
|
228
|
+
```bash
|
|
229
|
+
[ -f "$HOME/.rainbond/mcp.env" ] && source "$HOME/.rainbond/mcp.env"
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
注意:
|
|
233
|
+
|
|
234
|
+
- 新开的终端会自动加载 `RAINBOND_JWT`
|
|
235
|
+
- 当前已经打开的终端不会被子进程脚本直接改写
|
|
236
|
+
- 安装完成后,如果你想立刻在当前终端运行 `codex` 或 `claude`,请执行脚本最后提示的 `source ~/.zshrc` 或 `source ~/.bashrc`
|
|
237
|
+
|
|
238
|
+
### 7. 覆盖已安装版本
|
|
239
|
+
|
|
240
|
+
如果目标目录里已经存在同名 skill,默认会跳过,避免覆盖本地修改。
|
|
241
|
+
|
|
242
|
+
需要强制覆盖时:
|
|
243
|
+
|
|
244
|
+
```bash
|
|
245
|
+
npx --yes rainskills --force
|
|
246
|
+
npx --yes rainskills codex --force
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### 8. 安装到自定义目录
|
|
250
|
+
|
|
251
|
+
```bash
|
|
252
|
+
npx --yes rainskills --dest ~/.claude/skills
|
|
253
|
+
npx --yes rainskills --dest ~/.codex/skills --force
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
`--dest` 适合:
|
|
257
|
+
|
|
258
|
+
- 调试安装过程
|
|
259
|
+
- 安装到非标准目录
|
|
260
|
+
- 在 CI 或临时目录中做验证
|
|
261
|
+
|
|
262
|
+
注意:`--dest` 只复制 skill,不会自动配置 Rainbond MCP。
|
|
263
|
+
|
|
264
|
+
## 更新方式
|
|
265
|
+
|
|
266
|
+
npx 模式:显式使用 `latest` 并覆盖已有 skill:
|
|
267
|
+
|
|
268
|
+
```bash
|
|
269
|
+
npx --yes rainskills@latest --force
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
CDN 模式:再跑一次同一行命令即可。脚本会重新下载最新 tarball 解压到 `~/.rainbond/skills`,然后继续安装流程:
|
|
273
|
+
|
|
274
|
+
```bash
|
|
275
|
+
bash <(curl -fsSL https://get.rainbond.com/rainskills/install.sh) --force
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
本地仓库模式:
|
|
279
|
+
|
|
280
|
+
```bash
|
|
281
|
+
git pull
|
|
282
|
+
./install.sh --force
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
如果只想更新某一个平台:
|
|
286
|
+
|
|
287
|
+
```bash
|
|
288
|
+
./install.sh claude --force
|
|
289
|
+
./install.sh codex --force
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
## 目录结构
|
|
293
|
+
|
|
294
|
+
```text
|
|
295
|
+
rainbond-skills/
|
|
296
|
+
README.md
|
|
297
|
+
install.sh
|
|
298
|
+
package.json
|
|
299
|
+
bin/rainskills.js
|
|
300
|
+
.gitignore
|
|
301
|
+
rainbond-app-assistant/
|
|
302
|
+
SKILL.md
|
|
303
|
+
rainbond-delivery-verifier/
|
|
304
|
+
SKILL.md
|
|
305
|
+
...
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
## 产品对象模型
|
|
309
|
+
|
|
310
|
+
`docs/product-object-model.md` 描述了 skills 之间共享的产品对象(project、app、component、environment、delivery 等)和跨-skill 边界。如果你要扩展某个 skill 的输入/输出,或新增一个 skill,先看它。
|
|
311
|
+
|
|
312
|
+
## 仓库维护约定
|
|
313
|
+
|
|
314
|
+
- 每个 skill 使用单独目录,目录名和 skill 名保持一致
|
|
315
|
+
- 每个 skill 至少包含一个 `SKILL.md`
|
|
316
|
+
- 如果后续需要补充 `scripts/`、`references/`、`assets/`,请放在对应 skill 目录下
|
|
317
|
+
- 安装脚本默认复制所有 `rainbond-*` 目录
|
|
318
|
+
|
|
319
|
+
## 常见问题
|
|
320
|
+
|
|
321
|
+
### 1. 安装后没有生效
|
|
322
|
+
|
|
323
|
+
请重启 Claude Code 或 Codex,或者开启一个新的会话。
|
|
324
|
+
|
|
325
|
+
### 2. 为什么当前终端里还是连不上 MCP
|
|
326
|
+
|
|
327
|
+
因为 `./install.sh` 是一个子进程,不能直接改写你当前 shell 的环境变量。
|
|
328
|
+
|
|
329
|
+
处理方式:
|
|
330
|
+
|
|
331
|
+
- 直接执行脚本最后提示的 `source ~/.zshrc` 或 `source ~/.bashrc`
|
|
332
|
+
- 或者开一个新的终端
|
|
333
|
+
|
|
334
|
+
### 3. 为什么默认不覆盖已有 skill
|
|
335
|
+
|
|
336
|
+
因为有些使用者会在本地做二次调整。默认跳过更安全,`--force` 才会覆盖。
|
|
337
|
+
|
|
338
|
+
### 4. JWT 会保存在哪里
|
|
339
|
+
|
|
340
|
+
保存在:
|
|
341
|
+
|
|
342
|
+
```bash
|
|
343
|
+
~/.rainbond/mcp.env
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
脚本不会保存你的 Rainbond 用户名和密码。
|
|
347
|
+
|
|
348
|
+
### 5. 用 Claude / Codex 时 MCP 突然返回 401 / 403 怎么办
|
|
349
|
+
|
|
350
|
+
通常是 `~/.rainbond/mcp.env` 里的 JWT 到期了。无需重装 skills,也不要手工改文件,直接用下面任一命令刷新:
|
|
351
|
+
|
|
352
|
+
```bash
|
|
353
|
+
npx --yes rainskills refresh
|
|
354
|
+
# 或:bash <(curl -fsSL https://get.rainbond.com/rainskills/install.sh) refresh
|
|
355
|
+
# 或:bash ~/.rainbond/skills/install.sh refresh
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
`refresh` 不会改动 skill 文件。它会刷新 `~/.rainbond/mcp.env`,并检查 RainSkills 早期版本写入的旧通用 MCP 地址。只有地址完全等于当前 Rainbond 的 `/console/mcp/query` 且认证配置仍是脚本管理格式时,才会先生成 `.rainskills-backup` 备份,再迁移到对应客户端的专用地址;自定义 MCP 地址不会被修改。迁移失败时会恢复原配置。
|
|
359
|
+
|
|
360
|
+
注意:刷新完成后必须重启 Claude Code 或 Codex(它们在启动时一次性读取 `RAINBOND_JWT`,已经在跑的进程读到的还是旧 token)。
|
|
361
|
+
|
|
362
|
+
### 6. 如何确认安装到了哪里
|
|
363
|
+
|
|
364
|
+
脚本会输出每个目标目录和每个 skill 的安装结果。
|
|
365
|
+
|
|
366
|
+
## 开发者说明
|
|
367
|
+
|
|
368
|
+
如果你要新增或修改 skill,建议流程如下:
|
|
369
|
+
|
|
370
|
+
1. 在仓库里直接修改对应 skill 目录
|
|
371
|
+
2. 先查看 `docs/product-object-model.md`,它是当前产品对象模型和跨-skill 边界的主文档
|
|
372
|
+
3. 执行 `npm test` 跑安装器、包内容和 PTY 信号测试;测试在隔离临时目录中运行,无需输入,也不应打开真实浏览器
|
|
373
|
+
4. 执行 `./install.sh --dest /tmp/rainbond-skills-test --force` 做一次本地验证
|
|
374
|
+
5. 确认无误后再提交到 Git 仓库
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const path = require("node:path");
|
|
4
|
+
const { spawn } = require("node:child_process");
|
|
5
|
+
|
|
6
|
+
function classifyNodeMajor(major) {
|
|
7
|
+
if (major < 18) {
|
|
8
|
+
return "unsupported";
|
|
9
|
+
}
|
|
10
|
+
if (major === 18 || major === 20) {
|
|
11
|
+
return "eol";
|
|
12
|
+
}
|
|
13
|
+
return "supported";
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function run() {
|
|
17
|
+
const major = Number.parseInt(process.versions.node.split(".", 1)[0], 10);
|
|
18
|
+
const support = classifyNodeMajor(major);
|
|
19
|
+
|
|
20
|
+
if (support === "unsupported") {
|
|
21
|
+
console.error(
|
|
22
|
+
`错误:RainSkills 的 npx 安装方式需要 Node.js 18 或更高版本,当前为 ${process.version}。`
|
|
23
|
+
);
|
|
24
|
+
console.error(
|
|
25
|
+
"请升级到 Node.js 22/24,或改用:bash <(curl -fsSL https://get.rainbond.com/rainskills/install.sh)"
|
|
26
|
+
);
|
|
27
|
+
process.exitCode = 1;
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (support === "eol") {
|
|
32
|
+
console.error(
|
|
33
|
+
`警告:当前 ${process.version} 已结束维护;本次仍会继续,建议升级到 Node.js 22 或 24。`
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const installerPath = path.resolve(__dirname, "..", "install.sh");
|
|
38
|
+
const child = spawn("bash", [installerPath, ...process.argv.slice(2)], {
|
|
39
|
+
env: process.env,
|
|
40
|
+
stdio: "inherit",
|
|
41
|
+
});
|
|
42
|
+
let spawnFailed = false;
|
|
43
|
+
|
|
44
|
+
const forwardSigint = () => child.kill("SIGINT");
|
|
45
|
+
const forwardSigterm = () => child.kill("SIGTERM");
|
|
46
|
+
process.on("SIGINT", forwardSigint);
|
|
47
|
+
process.on("SIGTERM", forwardSigterm);
|
|
48
|
+
|
|
49
|
+
child.on("error", (error) => {
|
|
50
|
+
spawnFailed = true;
|
|
51
|
+
console.error(`错误:无法启动 RainSkills 安装器:${error.message}`);
|
|
52
|
+
process.exitCode = 1;
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
child.on("close", (code, signal) => {
|
|
56
|
+
process.removeListener("SIGINT", forwardSigint);
|
|
57
|
+
process.removeListener("SIGTERM", forwardSigterm);
|
|
58
|
+
|
|
59
|
+
if (signal) {
|
|
60
|
+
process.kill(process.pid, signal);
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
process.exitCode = spawnFailed ? 1 : code === null ? 1 : code;
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
module.exports = { classifyNodeMajor };
|
|
68
|
+
|
|
69
|
+
if (require.main === module) {
|
|
70
|
+
run();
|
|
71
|
+
}
|