dsh-qoder-connect 0.2.6 → 0.2.7
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.en.md +21 -6
- package/README.md +21 -6
- package/assets/3.png +0 -0
- package/assets/5.png +0 -0
- package/assets/6.png +0 -0
- package/assets/7.png +0 -0
- package/assets/8.png +0 -0
- package/lib/bin.js +109 -13
- package/lib/client.js +301 -117
- package/lib/index.d.ts +140 -22
- package/lib/index.js +72 -212
- package/lib/{variants-COxX6r1j.js → variants-B_ZzENbC.js} +459 -49
- package/package.json +1 -1
package/README.en.md
CHANGED
|
@@ -13,9 +13,10 @@ Configure only what you use: a variant with no saved PAT shows no model group an
|
|
|
13
13
|
|
|
14
14
|
## Features
|
|
15
15
|
|
|
16
|
-
- **
|
|
16
|
+
- **Multiple PATs, switched by hand** — each variant keeps a list of saved PATs and the card offers a select to choose the active one. Switching only changes the signing token: model toggles, context-window preferences, check-in and sidebar-quota settings are one shared configuration per variant and never follow the account. *Add PAT*, *Remove current* and *Clear all* manage the list; saving validates first, and removing or switching never touches another account's saved catalog or probe records.
|
|
17
|
+
- **PAT: save it and it works** — paste a PAT into the card and press *Save*; the token is validated live against that variant's region before anything is written, and the model group appears immediately — no DSH restart. A mistyped paste can never strand a working credential.
|
|
17
18
|
- **Two independent variants** — `qoder` (china) and `qoder-global` (global) keep separate credential files, routes and saved catalogs: a token minted on qoder.com does not work against the China deployment and vice versa.
|
|
18
|
-
- **Three-tier model catalog (live → saved → fallback)** — the card states where the list on screen came from: *“Model list updated …”* (fetched now), *“Showing the saved model list from …”* (this account's last successful fetch, restored after a restart or a failed fetch), or *“Showing the built-in model list (not yet updated from Qoder)”* (the roster compiled into the plugin). The reason of the most recent failed fetch is shown too, and
|
|
19
|
+
- **Three-tier model catalog (live → saved → fallback)** — the card states where the list on screen came from: *“Model list updated …”* (fetched now), *“Showing the saved model list from …”* (this account's last successful fetch, restored after a restart or a failed fetch), or *“Showing the built-in model list (not yet updated from Qoder)”* (the roster compiled into the plugin). The reason of the most recent failed fetch is shown too, and the card's *Refresh* action re-reads the status and re-fetches the model list.
|
|
19
20
|
- **One-toggle context window** — each variant card's *Context window* tab lists every model's capacity (the default and the largest declared window) and carries its own *“Use the largest declared context window”* preference (on by default): on, requests declare the maximum (e.g. Qwen3.8-Max at 1M); off, the default (200K). The two variants keep independent toggle state.
|
|
20
21
|
- **Model visibility toggles & batch controls** — each variant card provides a dedicated *Model Toggles* tab (between *Context window* and *Credit details*) to freely enable or hide individual models; disabled models are hidden from the DSH model picker, keeping it tidy; includes instant search by name/ID and one-click *Enable all* / *Disable all* batch operations.
|
|
21
22
|
- **Daily auto check-in & logs** — claims the daily 100 Credits automatically, **at a time you can set per variant on the card** (10:00 UTC+8 by default, the upstream's reset moment), with independent toggles and startup catch-up protection. The card features a dedicated *Check-in log* panel with audit trails, *Check in now*, *Refresh*, and *Clear logs* quick actions.
|
|
@@ -113,9 +114,23 @@ Swap the `--profile` value for the profile you use (`web` / `desktop` / `tui`, e
|
|
|
113
114
|
|
|
114
115
|
(The card repeats the same guidance: *“Generate a PAT in your qoder.com account settings (Account → Personal Access Token), then paste it here.”*)
|
|
115
116
|
|
|
116
|
-
### Save
|
|
117
|
+
### Save and switch on the card
|
|
117
118
|
|
|
118
|
-
DSH → Settings → Plugin Settings (插件设置) → the Qoder card: paste the PAT into the password field and press *Save* (*“Validating and saving…”* while it runs). The token is validated against that variant's region first — a refusal saves nothing and the card says *“That PAT was rejected — generate a new one in your account settings and try again
|
|
119
|
+
DSH → Settings → Plugin Settings (插件设置) → the Qoder card: paste the PAT into the password field and press *Save* (*“Validating and saving…”* while it runs). The token is validated against that variant's region first — a refusal saves nothing and the card says *“That PAT was rejected — generate a new one in your account settings and try again.”*
|
|
120
|
+
|
|
121
|
+
Each variant can hold several PATs: once a second one is saved, the account row shows a select — choosing an entry switches to it. *Add PAT* appends another (with an optional local-only label), *Remove current* deletes only the active one, and *Clear all* empties the list. **Configuration is shared**: model toggles, context-window preferences, check-in time and sidebar-quota settings belong to the variant, not to the account, and switching never changes them. Quota and check-in act on the active account. Check-in history is kept per variant, so switching does not retroactively check the new account in for today — use *Check in now* when needed. Do this on both cards to run both groups side by side.
|
|
122
|
+
|
|
123
|
+
### Command line (optional)
|
|
124
|
+
|
|
125
|
+
On a terminal-only profile the CLI manages the same list (`--provider` defaults to `qoder`):
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
dsh-qoder-connect pat set <token> --provider qoder # validate, save, and activate
|
|
129
|
+
dsh-qoder-connect pat list --provider qoder # list saved tokens (* = active)
|
|
130
|
+
dsh-qoder-connect pat use <id> --provider qoder # switch
|
|
131
|
+
dsh-qoder-connect pat rm <id> --provider qoder # remove
|
|
132
|
+
dsh-qoder-connect pat clear --provider qoder # remove all (logout is an alias)
|
|
133
|
+
```
|
|
119
134
|
|
|
120
135
|
### Environment-variable fallback
|
|
121
136
|
|
|
@@ -136,8 +151,8 @@ Everything the plugin owns lives in one data directory: `<profile>/.dsh-qoder-co
|
|
|
136
151
|
|
|
137
152
|
```text
|
|
138
153
|
<profile>/.dsh-qoder-connect/
|
|
139
|
-
├── .qoder-auth.json # China PAT ({version:
|
|
140
|
-
├── .qoder-global-auth.json # Global PAT
|
|
154
|
+
├── .qoder-auth.json # China PAT list ({version:3, activeId, credentials:[{id,pat,region,savedAt,label?}]})
|
|
155
|
+
├── .qoder-global-auth.json # Global PAT list
|
|
141
156
|
├── checkin-status.json # check-in status and history logs
|
|
142
157
|
└── state/
|
|
143
158
|
├── .qoder-catalog.json # China per-account saved catalog
|
package/README.md
CHANGED
|
@@ -13,9 +13,10 @@
|
|
|
13
13
|
|
|
14
14
|
## 功能
|
|
15
15
|
|
|
16
|
-
-
|
|
16
|
+
- **多 PAT 保存与手动切换**:每个变体可保存多枚 PAT,卡片上用下拉框切换当前账号(切换只换签名令牌,模型开关、上下文窗口、签到与侧栏额度等配置全部共享,不随账号变化);可「添加 PAT」「删除当前」「清除全部」。保存时先实时校验,通过才落盘;删除或切换不会误删其他账号的已保存模型目录与探测记录。
|
|
17
|
+
- **PAT 即存即用**:保存时先校验,通过才落盘,模型分组立即出现,无需重启 DSH;粘贴打错不会把可用凭据弄丢。
|
|
17
18
|
- **双变体独立配置**:`qoder`(china)与 `qoder-global`(global)各有自己的凭证文件、路由与已保存目录——qoder.com 生成的令牌对中国区无效,反之亦然,两套永不互串。
|
|
18
|
-
- **模型目录三级降级(live → saved → fallback)**:卡片明示当前列表来自哪里——「模型列表更新于 …」(实时拉取)、「当前显示已保存的模型列表,更新于 …」(本账号上次成功目录,重启或断网后顶上来)、「当前显示内置模型列表(尚未从 Qoder
|
|
19
|
+
- **模型目录三级降级(live → saved → fallback)**:卡片明示当前列表来自哪里——「模型列表更新于 …」(实时拉取)、「当前显示已保存的模型列表,更新于 …」(本账号上次成功目录,重启或断网后顶上来)、「当前显示内置模型列表(尚未从 Qoder 更新)」(编译进插件的兜底名单);最近一次拉取失败时附带原因,并可在卡片上手动「刷新」(同时刷新状态与模型列表)。
|
|
19
20
|
- **上下文窗口一键切换**:两张变体卡片的「上下文窗口」页列出每个模型的容量(默认值与上游声明的最大值),并各自提供「使用上游声明的最大上下文窗口」开关(默认勾选):勾选按最大窗口(如 Qwen3.8-Max 的 1M)发请求,不勾选按默认窗口(200K),两版开关状态独立保存、互不影响。
|
|
20
21
|
- **模型自由开关与批量管理**:两张变体卡片均提供「模型开关」页(位于上下文窗口与额度明细之间),可自由开启或关闭指定模型;关闭的模型将自动从 DeepSeek Harness 的模型选择器中隐藏,避免误选与列表冗长;顶部提供按名称/ID的即时搜索框,并支持全选与一键「批量开启」/「批量关闭」。
|
|
21
22
|
- **每日自动签到与日志明细**:支持每天自动签到领取 100 Credits 算力额度,**签到时刻可在卡片上自定义**(默认 10:00,即上游刷新时间,按 UTC+8),配备双端开关与开机防漏补签机制;卡片常驻「签到日志」面板,提供执行流水记录与「立即签到」、「刷新」、「清空日志」快捷操作。
|
|
@@ -113,9 +114,23 @@ dsh plugin --profile web add dsh-qoder-connect
|
|
|
113
114
|
|
|
114
115
|
(卡片内也有同样指引:「请先在 qoder.com.cn 的账号设置(账号 → 个人访问令牌)中生成 PAT,再粘贴到下方输入框。」)
|
|
115
116
|
|
|
116
|
-
###
|
|
117
|
+
### 在卡片上保存与切换
|
|
117
118
|
|
|
118
|
-
DSH → 设置 → 插件设置 → Qoder 卡片,展开后把 PAT 粘贴进密码输入框,点「保存」(期间显示「校验并保存中…」)。保存动作会先经 Qoder 校验令牌对该变体的区域有效,失败则不落盘并提示「PAT 无效或已过期 —
|
|
119
|
+
DSH → 设置 → 插件设置 → Qoder 卡片,展开后把 PAT 粘贴进密码输入框,点「保存」(期间显示「校验并保存中…」)。保存动作会先经 Qoder 校验令牌对该变体的区域有效,失败则不落盘并提示「PAT 无效或已过期 — 请到账号设置重新生成后再试。」
|
|
120
|
+
|
|
121
|
+
每个变体可以保存多枚 PAT:保存第二枚后,账号行出现下拉框,选中即切换;「添加 PAT」继续追加(可填一个仅本机显示的备注名),「删除当前」只删当前这一枚,「清除全部」一次清空。**配置永远共享**:模型开关、上下文窗口、签到时刻与侧栏额度设置都属于该变体的全局配置,切换账号不会改变;额度与签到作用于当前激活的账号。签到记录按变体保存,切换后不会自动为新账号补签当天,需要时可点「立即签到」。两版各填各的卡片即可两组并存。
|
|
122
|
+
|
|
123
|
+
### 命令行(可选)
|
|
124
|
+
|
|
125
|
+
终端环境可用 CLI 管理同一份多 PAT 列表(`--provider` 缺省为 `qoder`):
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
dsh-qoder-connect pat set <token> --provider qoder # 校验、保存并设为当前
|
|
129
|
+
dsh-qoder-connect pat list --provider qoder # 列出已保存(* = 当前)
|
|
130
|
+
dsh-qoder-connect pat use <id> --provider qoder # 切换
|
|
131
|
+
dsh-qoder-connect pat rm <id> --provider qoder # 删除
|
|
132
|
+
dsh-qoder-connect pat clear --provider qoder # 清除全部(logout 同义)
|
|
133
|
+
```
|
|
119
134
|
|
|
120
135
|
### 环境变量兜底
|
|
121
136
|
|
|
@@ -136,8 +151,8 @@ DSH → 设置 → 插件设置 → Qoder 卡片,展开后把 PAT 粘贴进密
|
|
|
136
151
|
|
|
137
152
|
```text
|
|
138
153
|
<profile>/.dsh-qoder-connect/
|
|
139
|
-
├── .qoder-auth.json # 国内版 PAT
|
|
140
|
-
├── .qoder-global-auth.json # 国际版 PAT
|
|
154
|
+
├── .qoder-auth.json # 国内版 PAT 列表({version:3, activeId, credentials:[{id,pat,region,savedAt,label?}]})
|
|
155
|
+
├── .qoder-global-auth.json # 国际版 PAT 列表
|
|
141
156
|
├── checkin-status.json # 签到状态与历史日志记录
|
|
142
157
|
└── state/
|
|
143
158
|
├── .qoder-catalog.json # 国内版按账号保存的模型目录
|
package/assets/3.png
CHANGED
|
Binary file
|
package/assets/5.png
CHANGED
|
Binary file
|
package/assets/6.png
CHANGED
|
Binary file
|
package/assets/7.png
CHANGED
|
Binary file
|
package/assets/8.png
CHANGED
|
Binary file
|
package/lib/bin.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
2
|
+
import { K as QoderCredentialStore, M as QoderCatalogStore, N as qoderCatalogPath, P as FALLBACK_QODER_MODELS, T as createQoderTransport, Y as qoderCredentialIdentity, _ as qoderProbePath, f as QODER_CONNECT_VERSION, i as variantFor, l as qoderHostHeartbeatPath, m as QoderProbeStore, r as QODER_VARIANTS, s as isHeartbeatProcessAlive, t as CHINA_VARIANT, u as readHostHeartbeat, w as validateApiKey, y as QoderUpstreamClient } from "./variants-B_ZzENbC.js";
|
|
3
3
|
import { readFile } from "node:fs/promises";
|
|
4
4
|
import { realpathSync } from "node:fs";
|
|
5
5
|
import { fileURLToPath } from "node:url";
|
|
@@ -16,8 +16,11 @@ function printHelp() {
|
|
|
16
16
|
"",
|
|
17
17
|
" doctor secret-free environment diagnostics",
|
|
18
18
|
" status credential state and remaining Qoder credit",
|
|
19
|
-
" pat set validate and
|
|
20
|
-
" pat
|
|
19
|
+
" pat set validate, store, and activate a Personal Access Token (arg, --file, or stdin)",
|
|
20
|
+
" pat list list saved tokens and mark the active one",
|
|
21
|
+
" pat use <id> switch to a saved token",
|
|
22
|
+
" pat rm <id> remove a saved token",
|
|
23
|
+
" pat clear remove every saved token",
|
|
21
24
|
" logout alias for `pat clear`",
|
|
22
25
|
" catalog refresh re-fetch the model list and save it for this account",
|
|
23
26
|
"",
|
|
@@ -147,8 +150,7 @@ async function status(jsonOutput, variant) {
|
|
|
147
150
|
}
|
|
148
151
|
}
|
|
149
152
|
/** Read a token from the positional arg, --file, or standard input. */
|
|
150
|
-
async function readPat(source,
|
|
151
|
-
const inline = rest.find((argument) => !argument.startsWith("--"));
|
|
153
|
+
async function readPat(source, inline) {
|
|
152
154
|
const pat = (source === void 0 ? inline ?? await readStdin() : source === "-" ? await readStdin() : await readFile(source, "utf8"))?.trim() ?? "";
|
|
153
155
|
if (pat === "") throw new Error("no token given: pass it as an argument, via --file <path>, or on standard input");
|
|
154
156
|
return pat;
|
|
@@ -158,9 +160,25 @@ async function readStdin() {
|
|
|
158
160
|
for await (const chunk of process.stdin) chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
159
161
|
return Buffer.concat(chunks).toString("utf8");
|
|
160
162
|
}
|
|
161
|
-
|
|
163
|
+
/**
|
|
164
|
+
* Drop the saved catalog and probe records that belong to one token.
|
|
165
|
+
*
|
|
166
|
+
* The host does this when a saved token is removed from the card; the CLI
|
|
167
|
+
* writes the same files, so it has to leave the same state behind. Leaving them
|
|
168
|
+
* would orphan another account's only copy — or resurrect data for a token the
|
|
169
|
+
* user just deleted.
|
|
170
|
+
*/
|
|
171
|
+
function forgetAccount(variant, credential) {
|
|
172
|
+
const identity = qoderCredentialIdentity(credential);
|
|
173
|
+
new QoderCatalogStore({ path: qoderCatalogPath(variant.catalogFilename) }).delete(identity);
|
|
174
|
+
new QoderProbeStore({
|
|
175
|
+
pluginVersion: QODER_CONNECT_VERSION,
|
|
176
|
+
path: qoderProbePath(variant.probeFilename)
|
|
177
|
+
}).clearFor(identity);
|
|
178
|
+
}
|
|
179
|
+
async function patSet(variant, file, inline) {
|
|
162
180
|
const store = makeStore(variant);
|
|
163
|
-
const pat = await readPat(file,
|
|
181
|
+
const pat = await readPat(file, inline);
|
|
164
182
|
process.stdout.write(`Validating a token against ${variant.displayName} (${variant.region})…\n`);
|
|
165
183
|
if (!await validateApiKey(pat, variant.region)) {
|
|
166
184
|
process.stderr.write(`dsh-qoder-connect: the token was refused by ${variant.displayName} (${variant.region}). Nothing was saved.\n`);
|
|
@@ -170,17 +188,79 @@ async function patSet(variant, file, rest) {
|
|
|
170
188
|
await store.save(pat, "cli");
|
|
171
189
|
const status = await store.status();
|
|
172
190
|
process.stdout.write([
|
|
173
|
-
`Saved
|
|
191
|
+
`Saved and activated in ${store.ownAuthPath()}${status.pat?.patTail === void 0 ? "" : ` (tail …${status.pat.patTail})`}`,
|
|
192
|
+
`${status.profiles?.length ?? 1} saved token(s); switch with \`dsh-qoder-connect pat use <id>\`.`,
|
|
174
193
|
"The running plugin picks the token up on its next sweep; no restart needed.",
|
|
175
194
|
""
|
|
176
195
|
].join("\n"));
|
|
177
196
|
return 0;
|
|
178
197
|
}
|
|
198
|
+
/** List the saved tokens, marking the active one; never prints a token. */
|
|
199
|
+
async function patList(jsonOutput, variant) {
|
|
200
|
+
const status = await makeStore(variant).status();
|
|
201
|
+
const profiles = status.profiles ?? [];
|
|
202
|
+
if (jsonOutput) {
|
|
203
|
+
printJson({
|
|
204
|
+
schemaVersion: JSON_SCHEMA_VERSION,
|
|
205
|
+
provider: variant.id,
|
|
206
|
+
activeId: status.activeId ?? null,
|
|
207
|
+
profiles,
|
|
208
|
+
...status.pat?.source === "env" ? { source: "env" } : {}
|
|
209
|
+
});
|
|
210
|
+
return 0;
|
|
211
|
+
}
|
|
212
|
+
if (profiles.length === 0) {
|
|
213
|
+
process.stdout.write(status.pat?.source === "env" ? `${variant.displayName}: no saved token; the environment token is in use${status.pat.patTail === void 0 ? "" : ` (tail …${status.pat.patTail})`}.\n` : `${variant.displayName}: no saved tokens.\n`);
|
|
214
|
+
return 0;
|
|
215
|
+
}
|
|
216
|
+
const lines = profiles.map((profile) => [
|
|
217
|
+
profile.id === status.activeId ? "*" : " ",
|
|
218
|
+
profile.id,
|
|
219
|
+
profile.label ?? "(no label)",
|
|
220
|
+
profile.patTail === void 0 ? "" : `tail …${profile.patTail}`
|
|
221
|
+
].filter((part) => part !== "").join(" "));
|
|
222
|
+
process.stdout.write([
|
|
223
|
+
`${variant.displayName} saved tokens (* = active):`,
|
|
224
|
+
...lines,
|
|
225
|
+
""
|
|
226
|
+
].join("\n"));
|
|
227
|
+
return 0;
|
|
228
|
+
}
|
|
229
|
+
/** Make one saved token active. */
|
|
230
|
+
async function patUse(variant, id) {
|
|
231
|
+
const entry = await makeStore(variant).activate(id);
|
|
232
|
+
if (entry === void 0) {
|
|
233
|
+
process.stderr.write(`dsh-qoder-connect: no saved token with id ${JSON.stringify(id)}; run \`pat list\` to see the ids.\n`);
|
|
234
|
+
return 1;
|
|
235
|
+
}
|
|
236
|
+
const tail = entry.pat.slice(-4);
|
|
237
|
+
process.stdout.write(`${variant.displayName}: active token is now ${entry.id}${tail.length === 4 ? ` (tail …${tail})` : ""}.\n`);
|
|
238
|
+
return 0;
|
|
239
|
+
}
|
|
240
|
+
/** Remove one saved token and the account-scoped data that belonged to it. */
|
|
241
|
+
async function patRemove(variant, id) {
|
|
242
|
+
const store = makeStore(variant);
|
|
243
|
+
const removed = await store.remove(id);
|
|
244
|
+
if (removed === void 0) {
|
|
245
|
+
process.stderr.write(`dsh-qoder-connect: no saved token with id ${JSON.stringify(id)}; run \`pat list\` to see the ids.\n`);
|
|
246
|
+
return 1;
|
|
247
|
+
}
|
|
248
|
+
forgetAccount(variant, removed);
|
|
249
|
+
const status = await store.status();
|
|
250
|
+
process.stdout.write([
|
|
251
|
+
`${variant.displayName}: removed ${removed.id}.`,
|
|
252
|
+
status.activeId === void 0 ? "No saved token remains; the plugin is signed out of this variant." : `Active token is now ${status.activeId}.`,
|
|
253
|
+
""
|
|
254
|
+
].join("\n"));
|
|
255
|
+
return 0;
|
|
256
|
+
}
|
|
179
257
|
async function patClear(variant) {
|
|
180
258
|
const store = makeStore(variant);
|
|
259
|
+
const saved = await store.entries();
|
|
260
|
+
for (const entry of saved) forgetAccount(variant, entry);
|
|
181
261
|
await store.clear();
|
|
182
262
|
const status = await store.status();
|
|
183
|
-
process.stdout.write(status.state === "configured" ? `${variant.displayName} Connect: removed
|
|
263
|
+
process.stdout.write(status.state === "configured" ? `${variant.displayName} Connect: removed ${saved.length} saved token(s), but a token is still active from the environment (${status.pat?.source ?? "env"}).\n` : `${variant.displayName} Connect: signed out; removed ${store.ownAuthPath()}\n`);
|
|
184
264
|
return 0;
|
|
185
265
|
}
|
|
186
266
|
async function catalogRefresh(variant) {
|
|
@@ -249,11 +329,18 @@ async function run(argv) {
|
|
|
249
329
|
}
|
|
250
330
|
let patCommand;
|
|
251
331
|
let catalogCommand;
|
|
332
|
+
/** The positional a subcommand takes: the token (`set`) or the entry id. */
|
|
333
|
+
let commandArg;
|
|
252
334
|
if (action === "pat") {
|
|
253
335
|
const sub = rest.shift();
|
|
254
|
-
patCommand = sub === "set" || sub === "clear" ? sub : void 0;
|
|
336
|
+
patCommand = sub === "set" || sub === "list" || sub === "use" || sub === "rm" || sub === "clear" ? sub : void 0;
|
|
255
337
|
if (patCommand === void 0) {
|
|
256
|
-
process.stderr.write(`dsh-qoder-connect: pat needs set or clear; got ${JSON.stringify(sub ?? "")}\n`);
|
|
338
|
+
process.stderr.write(`dsh-qoder-connect: pat needs set, list, use, rm, or clear; got ${JSON.stringify(sub ?? "")}\n`);
|
|
339
|
+
return 1;
|
|
340
|
+
}
|
|
341
|
+
if (patCommand !== "list" && patCommand !== "clear") commandArg = rest.shift();
|
|
342
|
+
if ((patCommand === "use" || patCommand === "rm") && (commandArg === void 0 || commandArg.startsWith("--"))) {
|
|
343
|
+
process.stderr.write(`dsh-qoder-connect: pat ${patCommand} needs an entry id; run \`pat list\` to see them\n`);
|
|
257
344
|
return 1;
|
|
258
345
|
}
|
|
259
346
|
}
|
|
@@ -265,7 +352,8 @@ async function run(argv) {
|
|
|
265
352
|
return 1;
|
|
266
353
|
}
|
|
267
354
|
}
|
|
268
|
-
|
|
355
|
+
const patListJson = action === "pat" && patCommand === "list";
|
|
356
|
+
if (rest.filter((flag) => flag !== "--json" && !flag.startsWith("--")).length > 0 || jsonOutput && action !== "doctor" && action !== "status" && !patListJson) {
|
|
269
357
|
process.stderr.write(`dsh-qoder-connect: invalid options for ${action}: ${flags.join(" ")}\n`);
|
|
270
358
|
return 1;
|
|
271
359
|
}
|
|
@@ -277,7 +365,15 @@ async function run(argv) {
|
|
|
277
365
|
switch (action) {
|
|
278
366
|
case "doctor": return await doctor(jsonOutput, variant);
|
|
279
367
|
case "status": return await status(jsonOutput, variant);
|
|
280
|
-
case "pat":
|
|
368
|
+
case "pat":
|
|
369
|
+
switch (patCommand) {
|
|
370
|
+
case "set": return await patSet(variant, file, commandArg);
|
|
371
|
+
case "list": return await patList(jsonOutput, variant);
|
|
372
|
+
case "use": return await patUse(variant, commandArg);
|
|
373
|
+
case "rm": return await patRemove(variant, commandArg);
|
|
374
|
+
case "clear": return await patClear(variant);
|
|
375
|
+
}
|
|
376
|
+
return 1;
|
|
281
377
|
case "logout": return await patClear(variant);
|
|
282
378
|
case "catalog": return await catalogRefresh(variant);
|
|
283
379
|
}
|