@whyour/qinglong-cli 0.1.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.en.md +156 -0
- package/README.md +156 -0
- package/dist/npm/commander-LICENSE +22 -0
- package/dist/npm/ql.js +110 -0
- package/dist/npm/ql.js.map +7 -0
- package/package.json +40 -0
- package/skills/qinglong-cli/SKILL.md +21 -0
- package/skills/qinglong-cli/references/openapi.md +213 -0
- package/skills/qinglong-cli/references/panel.md +57 -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 reasonable and customary use in describing the
|
|
141
|
+
origin of the Work and 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 Additional Liability. 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 additional liability.
|
|
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 2021 WHYOUR <https://github.com/whyour>.
|
|
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 implied.
|
|
200
|
+
See the License for the specific language governing permissions and
|
|
201
|
+
limitations under the License.
|
package/README.en.md
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
# QingLong 2.x remote management CLI
|
|
2
|
+
|
|
3
|
+
[简体中文](README.md) | **English**
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
The npm and panel-internal entries both use the name `ql`, but have separate Commander command trees. The npm entry only calls remote APIs; the internal entry only runs local tools. Verify the absolute executable path and `--help` before use. Installing the npm package does not migrate the built-in Shell commands.
|
|
7
|
+
|
|
8
|
+
`@whyour/qinglong-cli` is a standalone npm client for the panel's open API. It registers only `ql`, for the currently supported OpenAPI resources. Local execution, repo/raw workers, reload/update/account recovery belong to the panel's internal tools and are excluded from npm. Development publishing is outside both command sets.
|
|
9
|
+
|
|
10
|
+
## Installation and commands
|
|
11
|
+
|
|
12
|
+
Requires Node >=22.12; Node 24 is recommended. Commander is bundled with no additional runtime npm dependencies. There is no standalone CLI image.
|
|
13
|
+
|
|
14
|
+
```sh
|
|
15
|
+
npm install -g @whyour/qinglong-cli
|
|
16
|
+
ql --help
|
|
17
|
+
# Temporary use without replacing an existing panel ql
|
|
18
|
+
npm exec --package=@whyour/qinglong-cli -- ql --help
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
This branch has not published the package. Build with `npm ci --prefix cli` and `npm run build:cli`, then run `npm pack` in cli and install the local tgz. Global installation occupies the `ql` name. On a panel host use a separate npm prefix or `node /absolute/path/to/cli/dist/npm/ql.js`.
|
|
22
|
+
|
|
23
|
+
```sh
|
|
24
|
+
ql login --url https://ql.example.com
|
|
25
|
+
ql auth status --json
|
|
26
|
+
ql task list --search example --page 1 --size 50 --json
|
|
27
|
+
ql task get 12 --json
|
|
28
|
+
ql task logs 12 --tail 200 --json
|
|
29
|
+
ql task run 12 --json
|
|
30
|
+
ql task stop 12 --json
|
|
31
|
+
ql auth status --scope subscriptions --json
|
|
32
|
+
ql subscription list --json
|
|
33
|
+
ql subscription get 5 --json
|
|
34
|
+
ql subscription run 5 --json
|
|
35
|
+
ql subscription stop 5 --json
|
|
36
|
+
ql subscription logs 5 --tail 200 --json
|
|
37
|
+
ql subscription enable 5 --json
|
|
38
|
+
ql subscription disable 5 --json
|
|
39
|
+
ql auth logout --json
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Use command `--help` and `QL_LANG=en` for English. Command names and JSON fields do not change with language. The npm CLI never interprets unknown task actions as local scripts and does not register a separate `task` executable.
|
|
43
|
+
|
|
44
|
+
## Complete OpenAPI management
|
|
45
|
+
|
|
46
|
+
The CLI also supports task/subscription CRUD, application and secret management, environment variables, configuration, scripts, logs, dependencies, system, dashboard and user APIs. `ql api routes --json` lists all 143 active routes; three retired file-reading endpoints are excluded. CI compares the catalogue against backend routes. See the [complete bilingual reference](skills/qinglong-cli/references/openapi.md) for every command and payload.
|
|
47
|
+
|
|
48
|
+
```sh
|
|
49
|
+
ql task create --name demo --command 'task demo.js' --schedule '0 0 * * *' --json
|
|
50
|
+
ql subscription create --type public-repo --url https://example.com/repo.git --alias demo --schedule-type crontab --schedule '0 0 * * *' --json
|
|
51
|
+
ql app create --name agent --scopes crons,subscriptions --show-secrets --json
|
|
52
|
+
ql env create --data @envs.json --json
|
|
53
|
+
ql api request PUT /open/crons/run --data '[12,13]' --json
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Use --data JSON/@file/- for bodies, --query for query objects, --file for uploads and --output for downloads. New commands support --timeout seconds. Existing command contracts remain; raw API requests expose all fields and batch operations. Downloads do not overwrite files. App secrets require --show-secrets; other raw resources may contain sensitive data.
|
|
57
|
+
|
|
58
|
+
Remote ql system commands call the target panel API. Local reload/reset tools remain excluded from npm.
|
|
59
|
+
|
|
60
|
+
## Authentication
|
|
61
|
+
|
|
62
|
+
Protected requests use `Authorization: Bearer <token>`. Two credential sources are supported:
|
|
63
|
+
|
|
64
|
+
| Mode | Supply credentials | Persistence and refresh |
|
|
65
|
+
| --- | --- | --- |
|
|
66
|
+
| Application login | `ql login --url <panel-url>` prompts for Client ID / Client Secret; automation injects `QL_CLIENT_ID` and `QL_CLIENT_SECRET` | Exchanges credentials at `/open/auth/token`, saves credentials/token locally and refreshes expired tokens |
|
|
67
|
+
| Direct access token | Set `QL_URL` and `QL_ACCESS_TOKEN` together; accepts a valid application token or panel session token | Overrides saved configuration, is not persisted and is not refreshed |
|
|
68
|
+
|
|
69
|
+
### Application login
|
|
70
|
+
|
|
71
|
+
Create a dedicated panel application with the required scopes, such as crons, subscriptions or envs. `login` and `auth login` are equivalent. Interactive login hides the Client Secret; secret command-line arguments are not supported.
|
|
72
|
+
|
|
73
|
+
```sh
|
|
74
|
+
ql login --url https://ql.example.com
|
|
75
|
+
ql auth status --scope crons --json
|
|
76
|
+
# For automation, inject QL_CLIENT_ID and QL_CLIENT_SECRET before the same login command
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Credentials/token are stored in `~/.config/qinglong/cli.json`, a plaintext file owned by the current user with mode 0600. `QL_CLI_CONFIG` selects another file. Login validates application credentials, not every resource permission.
|
|
80
|
+
|
|
81
|
+
### Direct access token
|
|
82
|
+
|
|
83
|
+
Inject QL_URL and QL_ACCESS_TOKEN through your terminal or CI credential settings, then invoke commands without login:
|
|
84
|
+
|
|
85
|
+
```sh
|
|
86
|
+
ql auth status --scope apps --json
|
|
87
|
+
ql app list --json
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Both variables are required for protected commands; providing only one is a usage error. They take precedence over the file selected by QL_CLI_CONFIG. Running login still writes application configuration, but subsequent requests continue using the environment token. Run `unset QL_URL QL_ACCESS_TOKEN` in your own terminal to return to saved application credentials.
|
|
91
|
+
|
|
92
|
+
Application management requires apps permission or an authorized panel session. The current UI does not list every backend scope; the CLI never escalates automatically. Anonymous user login requires only QL_URL and accepts --data @credentials.json or --data -; the returned session is not automatically saved. A two-factor challenge (server 420) exits 3 and directs you to user two-factor-login with username/password/code in its JSON body. Do not put credentials in command arguments or chat.
|
|
93
|
+
|
|
94
|
+
### Permissions, logout and failures
|
|
95
|
+
|
|
96
|
+
Auth status checks crons read permission by default. Use --scope subscriptions, --scope apps or another supported scope for that resource. A representative read does not prove permission for every write. The crons scope covers reads and execution.
|
|
97
|
+
|
|
98
|
+
Auth logout deletes only saved application configuration. It neither revokes server tokens nor clears QL_ACCESS_TOKEN from the parent environment, so direct-token access may continue. Revoke access through the panel's application/session management. Resetting an application secret invalidates its old tokens; login again with the new secret.
|
|
99
|
+
|
|
100
|
+
Use the panel root URL with any proxy prefix, without /open. Remote connections require HTTPS; loopback HTTP is allowed. Requests never follow redirects. The 2.x application token endpoint carries credentials in query parameters; avoid logging that query at the proxy. Operations are not replayed after 401/403. An expired direct token must be replaced; the CLI does not fall back to saved application credentials.
|
|
101
|
+
|
|
102
|
+
## Tasks, subscriptions and output
|
|
103
|
+
|
|
104
|
+
Subscription commands include create/update/delete/list/get/run/stop/logs/enable/disable/status/log-files. Subscription lists return `{code:200,data:[...]}`, without task pagination. The subscription list/get commands omit repository URLs, fetch credentials, proxies and executable hooks; raw API responses and create/update results may contain sensitive fields. Logs are not automatically redacted.
|
|
105
|
+
|
|
106
|
+
Commands output pretty-printed JSON by default; `--json` produces a single line. Success goes to stdout and errors to stderr. Help with `--json` returns `{code:200,data:{help:"..."}}`.
|
|
107
|
+
|
|
108
|
+
- Task list: `{code:200,data:{data:[...tasks],total:123}}`. Default page size: 50; maximum: 200. Task fields retain server content.
|
|
109
|
+
- Task get: `{code:200,data:{id:12,...}}`.
|
|
110
|
+
- Logs: `{code:200,data:"log tail",logStatus:"completed",truncated:true}`. Default tail: 200 lines; maximum: 10000. `logStatus` is omitted when absent from the older API.
|
|
111
|
+
- Task run/stop: `{code:200,data:{taskId:12,action:"run",accepted:true}}`. Subscription run/stop/enable/disable use `subscriptionId`; CRUD and raw API operations retain their server response instead. Acceptance does not mean execution succeeded.
|
|
112
|
+
- Errors: `{code:1,message:"..."}`. Exit codes: 0 success, 1 API/network/configuration failure, 2 invalid arguments, 3 missing authentication, HTTP/API 401/403 or a two-factor challenge.
|
|
113
|
+
|
|
114
|
+
IDs must be positive integers. Each task run/stop request addresses one task. The 2.x API provides no separate run ID or idempotency key: an error may leave the outcome unknown. Inspect status before retrying. The CLI does not automatically retry HTTP requests.
|
|
115
|
+
|
|
116
|
+
Logs may belong to an earlier run; `completed` does not imply success. `--tail` truncates on the client and does not reduce server reads or network traffic. Neither task fields nor logs are automatically redacted.
|
|
117
|
+
|
|
118
|
+
## Skill, build and validation
|
|
119
|
+
|
|
120
|
+
The package includes `skills/qinglong-cli`, covering all remote commands. Copy it to your agent's skill directory and verify the remote npm entry. It contains no credentials and does not replace server permissions.
|
|
121
|
+
|
|
122
|
+
Strict TypeScript and Commander provide shared parsing/output with separate remote and internal entries. `dist/npm/ql.js` is a self-contained remote bundle; its build graph rejects local operational modules. The npm file allowlist includes only the remote bundle/map, licenses, bilingual documentation and remote skill. The full dist tree is panel-internal and is not published to npm.
|
|
123
|
+
|
|
124
|
+
```sh
|
|
125
|
+
npm ci --prefix cli
|
|
126
|
+
npm run check:cli
|
|
127
|
+
npm run test:cli
|
|
128
|
+
node cli/scripts/verify-package.cjs
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Tests cover requests, token refresh, output, errors, no automatic retries, permissions and isolated installation. Package verification installs the archive offline, verifies the sole ql executable and rejects local commands.
|
|
132
|
+
|
|
133
|
+
The CLI package workflow checks, builds and tests Node 22.12/24 on relevant PRs, develop/master pushes and manual runs. Node 24 uploads the archive verified by offline installation as `qinglong-cli-<commit>`. After both matrix jobs succeed, master pushes publish that exact archive to npm as latest, using GitHub Actions OIDC trusted publishing without an NPM_TOKEN secret. Manual runs publish only when run on master with publish enabled; PRs, develop and forks never publish. Configure the npm Trusted Publisher for repository `whyour/qinglong`, workflow `cli-package.yml`, with `npm publish` allowed. The panel package `@whyour/qinglong` separately trusts `build-docker-image.yml`. Publishing uses Node 24 with `id-token: write` granted only to the publish job. New packages need an initial publication before configuring their trusted publisher.
|
|
134
|
+
|
|
135
|
+
The CLI has an independent stable version in cli/package.json and cli/package-lock.json. Before releasing changes, run `npm version patch --prefix cli --no-git-tag-version` (or minor/major) and commit both files. Existing versions are skipped with a notice; registry failures stop publication. Only stable X.Y.Z versions are published by this workflow. Publication does not rebuild the verified archive or run package lifecycle scripts.
|
|
136
|
+
|
|
137
|
+
## Panel-internal tools
|
|
138
|
+
|
|
139
|
+
Local execution, subscription synchronization and maintenance ship with panel source/builds, using the full internal dist tree and a separate `qinglong-local` skill. See `cli/LOCAL.md` and `cli/LOCAL.en.md` in the source checkout. An npm installation is not a valid QL_CLI_ROOT. Recovery/reload must run on the actual panel host or inside its container, using docker exec for Docker installations.
|
|
140
|
+
|
|
141
|
+
API task run returns acceptance; a local runner waits for script completion. Their elapsed times are different measurements. Compare the internal TS runner against Shell using identical configuration/scripts; remote API management has no equivalent old Shell management command.
|
|
142
|
+
|
|
143
|
+
## Source layout
|
|
144
|
+
|
|
145
|
+
```text
|
|
146
|
+
src/
|
|
147
|
+
entrypoints/ # Executable composition
|
|
148
|
+
remote/ # commands / api / auth
|
|
149
|
+
internal/ # commands / execution / subscription / maintenance / runtime / integration
|
|
150
|
+
compatibility/ # Legacy entry and argument adapters
|
|
151
|
+
shared/ # cli / i18n / response types and errors
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Shared code cannot import business modules. Remote and internal modules may only import their own area and shared code; integration tests enforce these boundaries. Each surface owns its command registry, passed into the shared Commander parser.
|
|
155
|
+
|
|
156
|
+
Tests follow the same areas under test/. `npm run test:cli` (repository root) or `npm test` (cli/) discovers the standard suites; test/linux remains an explicitly invoked container integration suite. scripts/entrypoints.cjs preserves existing dist executable paths and dist/local/entrypoints.js and cronEntrypoint.js. Moving sources does not require changing QL_CLI_ROOT or cron commands.
|
package/README.md
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
# QingLong 2.x 远程管理 CLI
|
|
2
|
+
|
|
3
|
+
**简体中文** | [English](README.en.md)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
npm 与面板内部入口都叫 `ql`,但使用独立的 Commander 命令树:npm 入口只调用远程 API,内部入口只运行本机工具。使用前确认可执行文件的绝对路径和 `--help`;安装 npm 包不会迁移内置 Shell 命令。
|
|
7
|
+
|
|
8
|
+
`@whyour/qinglong-cli` 是独立 npm 包,覆盖当前 develop 的有效 OpenAPI,只注册一个 `ql` 命令。它不包含脚本执行器或本机运维实现;`task exec`、`repo/raw`、`reload/update/reset*` 等属于面板内部工具,不随 npm 包分发。开发发布也不属于 CLI 范围。
|
|
9
|
+
|
|
10
|
+
## 安装与使用
|
|
11
|
+
|
|
12
|
+
要求 Node >=22.12,推荐 Node 24。Commander 在构建时打包,无额外运行时 npm 依赖,不单独发布 CLI 镜像。
|
|
13
|
+
|
|
14
|
+
```sh
|
|
15
|
+
npm install -g @whyour/qinglong-cli
|
|
16
|
+
ql --help
|
|
17
|
+
# 临时使用,不覆盖面板已有的 ql
|
|
18
|
+
npm exec --package=@whyour/qinglong-cli -- ql --help
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
本分支尚未发布 npm 包。发布前从源码执行 `npm ci --prefix cli`、`npm run build:cli`,在 cli 目录执行 `npm pack`,然后安装本地 tgz。全局安装会占用 `ql` 名称;已有面板的机器建议使用独立 npm prefix 或直接执行 `node /absolute/path/to/cli/dist/npm/ql.js`。
|
|
22
|
+
|
|
23
|
+
```sh
|
|
24
|
+
ql login --url https://ql.example.com
|
|
25
|
+
ql auth status --json
|
|
26
|
+
ql task list --search 示例 --page 1 --size 50 --json
|
|
27
|
+
ql task get 12 --json
|
|
28
|
+
ql task logs 12 --tail 200 --json
|
|
29
|
+
ql task run 12 --json
|
|
30
|
+
ql task stop 12 --json
|
|
31
|
+
ql auth status --scope subscriptions --json
|
|
32
|
+
ql subscription list --json
|
|
33
|
+
ql subscription get 5 --json
|
|
34
|
+
ql subscription run 5 --json
|
|
35
|
+
ql subscription stop 5 --json
|
|
36
|
+
ql subscription logs 5 --tail 200 --json
|
|
37
|
+
ql subscription enable 5 --json
|
|
38
|
+
ql subscription disable 5 --json
|
|
39
|
+
ql auth logout --json
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
各命令支持 `--help`,`QL_LANG=en` 切换英文帮助;命令和 JSON 字段不随语言变化。`ql task` 中只包含 API 操作,不会把无效命令解释为本机脚本,也不提供独立 `task` npm 入口。
|
|
43
|
+
|
|
44
|
+
## 全量 OpenAPI 管理
|
|
45
|
+
|
|
46
|
+
现在还支持任务/订阅创建、修改、删除,应用管理与密钥重置,以及环境变量、配置、脚本、日志、依赖、系统、仪表盘和用户管理。`ql api routes --json` 列出全部 143 条有效路由;3 条已下线文件读取接口不包含在内。新增命令在 [完整双语参考](skills/qinglong-cli/references/openapi.md) 中逐项列出,路由覆盖由 CI 与后端代码核对。
|
|
47
|
+
|
|
48
|
+
```sh
|
|
49
|
+
ql task create --name demo --command 'task demo.js' --schedule '0 0 * * *' --json
|
|
50
|
+
ql subscription create --type public-repo --url https://example.com/repo.git --alias demo --schedule-type crontab --schedule '0 0 * * *' --json
|
|
51
|
+
ql app create --name agent --scopes crons,subscriptions --show-secrets --json
|
|
52
|
+
ql env create --data @envs.json --json
|
|
53
|
+
ql api request PUT /open/crons/run --data '[12,13]' --json
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
请求体使用 --data JSON/@file/-,查询使用 --query,上传 --file,下载 --output。新命令支持 --timeout 秒数;旧命令行为保留,完整参数可用 api request。下载不覆盖现有文件,应用密钥默认隐藏,明确加 --show-secrets 才输出。新增资源通常保留原始返回字段,注意环境、配置和会话信息可能敏感。
|
|
57
|
+
|
|
58
|
+
远程 `ql system ...` 调用面板 API;本机 reload/reset 等仍不在 npm 包中。不要将远程 API 覆盖理解为本机运维重新混入包。
|
|
59
|
+
|
|
60
|
+
## 认证
|
|
61
|
+
|
|
62
|
+
受保护的请求均使用 `Authorization: Bearer <token>`,支持以下两种凭据来源:
|
|
63
|
+
|
|
64
|
+
| 方式 | 提供方式 | 保存与刷新 |
|
|
65
|
+
| --- | --- | --- |
|
|
66
|
+
| 应用凭据登录 | `ql login --url <面板地址>`,输入 Client ID / Client Secret;自动化通过 `QL_CLIENT_ID`、`QL_CLIENT_SECRET` 注入 | 通过 `/open/auth/token` 换取 token,凭据和 token 保存到本机,过期自动刷新 |
|
|
67
|
+
| 直接访问令牌 | 环境中同时设置 `QL_URL`、`QL_ACCESS_TOKEN`,支持有效应用 token 或面板会话 token | 优先于保存的配置,不落盘、不自动刷新 |
|
|
68
|
+
|
|
69
|
+
### 应用凭据登录
|
|
70
|
+
|
|
71
|
+
在面板创建专用应用,按需授予 crons、subscriptions、envs 等权限。`login` 与 `auth login` 等价;交互输入 Client ID 和不回显的 Client Secret,密钥不支持命令行参数。
|
|
72
|
+
|
|
73
|
+
```sh
|
|
74
|
+
ql login --url https://ql.example.com
|
|
75
|
+
ql auth status --scope crons --json
|
|
76
|
+
# 自动化环境事先注入 QL_CLIENT_ID 和 QL_CLIENT_SECRET,再运行同一 login 命令
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
凭据和 token 保存到 `~/.config/qinglong/cli.json`,为当前用户所有的 0600 明文文件。`QL_CLI_CONFIG` 可选择其他配置文件。登录只验证应用凭据,不意味着具备所有资源权限。
|
|
80
|
+
|
|
81
|
+
### 直接使用访问令牌
|
|
82
|
+
|
|
83
|
+
在终端或 CI 的凭据配置中注入 `QL_URL` 与 `QL_ACCESS_TOKEN` 后,直接调用命令,无需再执行 login:
|
|
84
|
+
|
|
85
|
+
```sh
|
|
86
|
+
ql auth status --scope apps --json
|
|
87
|
+
ql app list --json
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
两个变量必须同时提供给受保护命令;只提供一个会报参数错误。此方式优先于 `QL_CLI_CONFIG` 指定的配置。即使重新执行 login 写入了应用配置,后续请求仍使用环境令牌;切回保存的应用配置时,在自己的终端执行 `unset QL_URL QL_ACCESS_TOKEN`。
|
|
91
|
+
|
|
92
|
+
应用管理需要 apps 权限或有效的授权面板会话;当前面板 UI 没有列出所有后端 scope,CLI 不自动提权。匿名 `user login` 可在仅设置 QL_URL 时使用 `--data @credentials.json` 或 `--data -` 提交凭据;返回的会话不会自动保存。启用双因素认证时,服务端 420 对应 CLI 退出码 3,随后使用 `user two-factor-login`,请求体包含 username/password/code。不要将凭据写入命令参数或聊天。
|
|
93
|
+
|
|
94
|
+
### 权限检查、退出与失败
|
|
95
|
+
|
|
96
|
+
`auth status` 默认检查 crons 读取权限,可用 `--scope subscriptions`、`--scope apps` 等检查对应资源。它只验证代表性读取,不代表所有写操作都获授权。2.x 的 crons scope 同时覆盖读取和执行。
|
|
97
|
+
|
|
98
|
+
`auth logout` 仅删除本机应用配置,不撤销服务端 token,也不清除父进程中的 QL_ACCESS_TOKEN。令牌模式仍可能继续访问;如需撤销访问,使用面板提供的应用或会话管理。重置应用密钥会使旧应用 token 失效,需要使用新密钥重新 login。
|
|
99
|
+
|
|
100
|
+
URL 使用面板根地址,可包含代理路径前缀,不附加 `/open`。远程连接要求 HTTPS,回环地址允许 HTTP;不跟随重定向。2.x 应用 token 接口以查询参数传递凭据,代理应避免记录该查询字符串。401/403 不自动重放操作;直接令牌失效时需更换,CLI 不会转而使用保存的应用凭据。
|
|
101
|
+
|
|
102
|
+
## 输出契约
|
|
103
|
+
|
|
104
|
+
订阅支持 create/update/delete/list/get/run/stop/logs/enable/disable/status/log-files。`subscription list/get` 保留管理字段投影;run/stop/enable/disable 返回 subscriptionId/action/accepted。创建、修改、删除及通用 API 请求保留服务端响应,可能包含敏感字段;不能将所有变更都解释为 accepted。
|
|
105
|
+
|
|
106
|
+
命令默认输出缩进 JSON,`--json` 输出单行 JSON;成功写 stdout,错误写 stderr,互不混用。帮助在 `--json` 下也使用 `{code:200,data:{help:"..."}}`。
|
|
107
|
+
|
|
108
|
+
- `task list`:`{code:200,data:{data:[...tasks],total:123}}`,默认每页 50,最多 200;任务字段保留服务端内容。
|
|
109
|
+
- `task get`:`{code:200,data:{id:12,...}}`。
|
|
110
|
+
- `task logs`:`{code:200,data:"日志尾部",logStatus:"completed",truncated:true}`。默认 200 行,最多 10000;旧接口若不返回 logStatus,该字段省略。
|
|
111
|
+
- `task run/stop`:`{code:200,data:{taskId:12,action:"run",accepted:true}}`。仅表示请求被接受,不表示任务成功完成。
|
|
112
|
+
- 错误:`{code:1,message:"..."}`;退出码 1 为 API/网络/配置错误,2 为参数错误,3 为未登录、HTTP/API 401/403 或需要双因素验证;成功退出码 0。
|
|
113
|
+
|
|
114
|
+
ID 必须为正整数,运行/停止一次操作一个任务。2.x 没有为此提供独立运行 ID 或幂等键,失败响应可能意味着执行结果未知,应先查询状态,禁止盲目重试。CLI 不自动重试 HTTP 请求。
|
|
115
|
+
|
|
116
|
+
日志是该任务最新日志,可能属于先前运行;`completed` 不代表成功。`--tail` 在客户端截取,不减少服务端读取量或网络传输量。日志与任务字段不自动脱敏,应按需读取并避免向聊天中暴露敏感信息。
|
|
117
|
+
|
|
118
|
+
## Skill、构建与验证
|
|
119
|
+
|
|
120
|
+
npm 包附带 `skills/qinglong-cli`,覆盖全部远程命令。复制到所用 Agent 的 skills 目录,并确认使用 npm 远程入口。Skill 不存放凭据,也不替代服务端权限。
|
|
121
|
+
|
|
122
|
+
源码使用 TypeScript 严格检查和 Commander 解析;共用参数/输出逻辑,分别构建远程入口和面板内部入口。`dist/npm/ql.js` 是可独立运行的远程 bundle,构建依赖图会拒绝引入本机运维模块;npm 文件白名单仅包含该 bundle、source map、许可证、中英文说明和远程 Skill。完整 `dist` 用于面板内部构建,不随 npm 发布。
|
|
123
|
+
|
|
124
|
+
```sh
|
|
125
|
+
npm ci --prefix cli
|
|
126
|
+
npm run check:cli
|
|
127
|
+
npm run test:cli
|
|
128
|
+
node cli/scripts/verify-package.cjs
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
测试覆盖请求格式、认证刷新、输出、错误、禁止自动重试、权限和独立安装。打包验证会离线安装 tgz,并确认唯一入口是 `ql`,本机命令不可调用。
|
|
132
|
+
|
|
133
|
+
CLI package 工作流在相关 PR、develop/master 推送和手动触发时执行 Node 22.12/24 类型检查、构建及测试。Node 24 上传通过离线安装验证的 `qinglong-cli-<commit>` artifact。两个矩阵任务成功后,master 推送会将这份已验证的 tgz 发布到 npm 的 latest 标签,通过 GitHub Actions OIDC 可信发布,无需 `NPM_TOKEN` Secret。手动运行需选择 master 并勾选 publish;PR、develop 和 fork 不发布。npm 的 Trusted Publisher 需绑定仓库 `whyour/qinglong` 和工作流 `cli-package.yml`,允许 `npm publish`;面板包 `@whyour/qinglong` 单独绑定 `build-docker-image.yml`。发布 job 使用 Node 24,并仅在该 job 授予 `id-token: write`。新包需先完成首次发布,再配置对应包的可信发布关系。
|
|
134
|
+
|
|
135
|
+
CLI 版本独立维护在 cli/package.json 和 cli/package-lock.json。发布改动前执行 `npm version patch --prefix cli --no-git-tag-version`(也可用 minor/major),提交这两个文件。已发布的版本会提示并跳过;registry 查询失败则停止发布。该流程仅发布 X.Y.Z 稳定版本,不重新构建产物或执行包生命周期脚本。
|
|
136
|
+
|
|
137
|
+
## 面板内部工具
|
|
138
|
+
|
|
139
|
+
本机执行、订阅同步和运维随面板源码/构建交付,使用完整内部 `dist` 与独立 `qinglong-local` Skill;源码说明见 `cli/LOCAL.md` 和 `cli/LOCAL.en.md`。npm 包不能用作 `QL_CLI_ROOT`。账号恢复、服务重载必须在实际面板宿主机或容器中执行;Docker 使用 `docker exec` 调用容器内选定入口。
|
|
140
|
+
|
|
141
|
+
API `task run` 返回请求接受,本机执行器等待脚本结束,二者耗时不能直接对比。Shell 迁移性能应比较相同配置和脚本下的内部 TS 执行器与原 Shell;远程 API 操作没有对应的旧 Shell 管理命令。
|
|
142
|
+
|
|
143
|
+
## 源码结构
|
|
144
|
+
|
|
145
|
+
```text
|
|
146
|
+
src/
|
|
147
|
+
entrypoints/ # 可执行入口组装
|
|
148
|
+
remote/ # commands / api / auth
|
|
149
|
+
internal/ # commands / execution / subscription / maintenance / runtime / integration
|
|
150
|
+
compatibility/ # 旧入口和参数适配
|
|
151
|
+
shared/ # cli / i18n / 响应类型与错误
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
shared 不能引用业务模块;remote 与 internal 只能引用各自区域及 shared,集成测试检查这些依赖边界。两套业务注册表分别注入共享 Commander 解析器。
|
|
155
|
+
|
|
156
|
+
测试按同样的区域分组。仓库根目录 `npm run test:cli` 或 cli/ 下 `npm test` 自动发现标准测试;test/linux 保持为显式执行的容器集成测试。scripts/entrypoints.cjs 保留现有 dist 可执行入口,以及 dist/local/entrypoints.js、cronEntrypoint.js;移动源码不要求修改 QL_CLI_ROOT 或 cron 命令。
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
(The MIT License)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2011 TJ Holowaychuk <tj@vision-media.ca>
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
6
|
+
a copy of this software and associated documentation files (the
|
|
7
|
+
'Software'), to deal in the Software without restriction, including
|
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
11
|
+
the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be
|
|
14
|
+
included in all copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
19
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
20
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
|
21
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
|
22
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|