dsh-opendesign-corouter 0.1.4 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -5
- package/SECURITY.md +1 -1
- package/THIRD_PARTY_NOTICES.md +22 -1
- package/lib/browser-open.d.ts +104 -0
- package/lib/catalog.d.ts +9 -8
- package/lib/client.d.ts +8 -2
- package/lib/client.js +87 -12
- package/lib/device-auth.d.ts +5 -3
- package/lib/generated/typert.host.js +18 -4
- package/lib/generated/typert.remote-client.d.ts +2 -1
- package/lib/generated/typert.remote-client.js +18 -4
- package/lib/index.d.ts +5 -1
- package/lib/index.js +324 -16
- package/lib/index.js.map +3 -3
- package/lib/login.d.ts +10 -0
- package/lib/remote.d.ts +7 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -32,7 +32,7 @@ dsh plugin --profile web add dsh-opendesign-corouter
|
|
|
32
32
|
也可打开 [Actions → CI](https://github.com/KouzakiUmi/dsh-opendesign-corouter/actions/workflows/ci.yml),从成功构建下载 **`dsh-opendesign-corouter-build`** artifact。登录 GitHub 后解压 ZIP,取得 `.tgz` 与 `.sha256`,再安装本地包:
|
|
33
33
|
|
|
34
34
|
```console
|
|
35
|
-
dsh plugin --profile web add /absolute/path/to/dsh-opendesign-corouter-0.1.
|
|
35
|
+
dsh plugin --profile web add /absolute/path/to/dsh-opendesign-corouter-0.1.6.tgz
|
|
36
36
|
```
|
|
37
37
|
|
|
38
38
|
`web` 只是示例,请替换为目标 Profile。Desktop 使用桌面安装器提供的 `dsh` 入口;独立公共 CLI 不能代管保留的 `desktop` Profile。安装后的启用与重载按目标 DSH 的管理流程进行。
|
|
@@ -40,7 +40,7 @@ dsh plugin --profile web add /absolute/path/to/dsh-opendesign-corouter-0.1.4.tgz
|
|
|
40
40
|
### 2. 配置连接
|
|
41
41
|
|
|
42
42
|
1. 打开 **设置 → OpenDesign CoRouter → 连接与登录**。
|
|
43
|
-
2. 点击
|
|
43
|
+
2. 点击 **开始设备授权**,取得授权码后自动打开临时 Chrome 官方授权页,核对并确认;打开失败可用 **在新窗口打开授权页** 重试,也可复制链接到常用浏览器,或单独配置工作空间 API Key / 沿用 `COROUTER_API_KEY`。
|
|
44
44
|
3. 返回设置页等待保存成功。额度默认优先读取桌面登录态;要明确使用设备授权的账号,可关闭桌面优先。
|
|
45
45
|
4. 回到模型选择器,选择 **OpenDesign CoRouter · 套餐赠送** 或 **OpenDesign CoRouter · 付费模型**。
|
|
46
46
|
|
|
@@ -52,8 +52,8 @@ dsh plugin --profile web add /absolute/path/to/dsh-opendesign-corouter-0.1.4.tgz
|
|
|
52
52
|
|
|
53
53
|
| Provider | 模型数 | 用途 |
|
|
54
54
|
| --- | ---: | --- |
|
|
55
|
-
| `opendesign-corouter-plan` |
|
|
56
|
-
| `opendesign-corouter-paid` |
|
|
55
|
+
| `opendesign-corouter-plan` | 13 | Core / Design Plan 附赠通道,含预检确认覆盖的 MiniMax M3.1 Flash |
|
|
56
|
+
| `opendesign-corouter-paid` | 25 | Plan 套餐模型及其他钱包付费模型 |
|
|
57
57
|
|
|
58
58
|
上表为内置目录。模型页可从 OpenAI `/models` 端口刷新,逐个启用或停用模型,并配置温度、top-p、默认输出上限、上下文预算及思考深度。停用同时影响模型选择器和直接调用;参数会保存并应用到实际请求。媒体生成接口不在对话目录中,未知能力不按名称猜测。
|
|
59
59
|
|
|
@@ -72,7 +72,7 @@ dsh plugin --profile web add /absolute/path/to/dsh-opendesign-corouter-0.1.4.tgz
|
|
|
72
72
|
|
|
73
73
|
### 桌面优先,也能独立登录
|
|
74
74
|
|
|
75
|
-
|
|
75
|
+
独立登录采用设备授权,官方授权页可交给插件自己启动的临时 Chrome 窗口显示(不读取或改动你已有的浏览器配置),也可复制链接到你自己的浏览器沿用已有登录态、密码管理器和自动填充。确认后设备令牌保存到 DSH 凭据服务;取消、超时和卸载停止轮询并关闭临时窗口,不关闭你自己的浏览器,也不修改桌面配置。
|
|
76
76
|
|
|
77
77
|
<picture>
|
|
78
78
|
<source media="(prefers-color-scheme: dark)" srcset="docs/previews/theme-dark.png">
|
package/SECURITY.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
- 设备授权双令牌原子保存;runtimeKey 只自动提供给请求快照中的官方推理 origin,controlKey 只发往官方控制面。旧 Cookie grant 保留只读兼容。
|
|
7
7
|
- 推理自定义地址由用户显式配置;除本机回环外要求 HTTPS,拒绝 URL 内嵌凭据、查询串与片段。
|
|
8
8
|
- 额度分池不跨身份混合。桌面认证失效时,可回退到单独保存的控制台登录;权限不足和未知额度不伪装成 0。
|
|
9
|
-
-
|
|
9
|
+
- 独立登录使用设备授权。Host 可用 `playwright-core` 启动一个短暂的 Chrome 窗口显示官方激活页;这是插件自己创建的临时浏览器上下文,不创建、不驱动、不读取用户已有的浏览器配置或 Cookie,也不在该页面输入、点击或读取内容。由系统外壳拦截 `target="_blank"` 的宿主里,官方链接仍作为手动路径保留。deviceSecret 只在 Host 内存用于轮询;授权码、激活链接和到期时间仅在等待期提供给 UI,打开结果只返回固定代码,不返回 URL、浏览器句柄或错误正文。取消、超时和卸载中止请求,并有界请求关闭该临时窗口(每阶段最多约 5 秒,超时为尽力清理);不关闭用户自己的浏览器。持久化成功是不可撤回的提交边界,之后取消不会假称已撤回。
|
|
10
10
|
- `OPENDESIGN_VELA_PATH` 是用户信任的本地程序路径。插件仅以固定 argv 执行只读查询,不通过 shell;不校验该程序的签名或下载它。不要将此变量指向来源不明的程序。
|
|
11
11
|
- RPC 使用严格白名单解析;原始错误正文、Cookie、请求头、Key 和桌面本地路径不进入状态返回。并发保存有版本冲突检测。
|
|
12
12
|
- 请求、流空闲、额度接口、CLI、登录和 RPC 均有有界超时。停用插件会撤销 Provider / RPC 并中止自身请求。
|
package/THIRD_PARTY_NOTICES.md
CHANGED
|
@@ -1,11 +1,32 @@
|
|
|
1
1
|
# 第三方代码与资料
|
|
2
2
|
|
|
3
|
-
本项目的消息/图片兼容处理、套餐模型元数据参考 [dsh-opendesign-go 0.1.9](https://github.com/EliteOtaku/dsh-opendesign-go)。额度归一化及登录生命周期的基础处理改编自 [dsh-subusage 0.16.2](https://github.com/KouzakiUmi/dsh-subusage)
|
|
3
|
+
本项目的消息/图片兼容处理、套餐模型元数据参考 [dsh-opendesign-go 0.1.9](https://github.com/EliteOtaku/dsh-opendesign-go)。额度归一化及登录生命周期的基础处理改编自 [dsh-subusage 0.16.2](https://github.com/KouzakiUmi/dsh-subusage);临时授权窗口的 Chrome 启动策略改编自 [dsh-subusage 0.16.3](https://github.com/KouzakiUmi/dsh-subusage) 的 `lib/cookie-login.js`。空轮判定参考 [dsh-empty-turn-guard 0.4.0](https://github.com/FYTXY/dsh-empty-turn-guard)。设置布局参考 [dsh-code-pill](https://github.com/KouzakiUmi/dsh-code-pill)。
|
|
4
4
|
|
|
5
5
|
离线主题夹具使用 [DeepSeek Harness 官方主题令牌](https://github.com/deepseek-ai/deepseek-harness/blob/22ddee3792402c3e70ec5f86a63c3e3e895a2f60/packages/client/ui-theme/src/styles/design-platform.css),仅供测试,不随插件安装包分发。
|
|
6
6
|
|
|
7
7
|
Client bundle 内含 [Zod 4.6.6](https://github.com/colinhacks/zod) 与 DSH 协议辅助代码,分别保留 Colin McDonnell 与 DeepSeek 的 MIT 声明。
|
|
8
8
|
|
|
9
|
+
Host 侧运行时依赖 [playwright-core 1.63.0](https://github.com/microsoft/playwright)(Apache-2.0),只用于启动显示官方授权页的临时 Chrome 窗口:不下载浏览器,使用本机已安装的 Chrome。它按 npm 依赖安装,不并入本项目源码。
|
|
10
|
+
|
|
11
|
+
```text
|
|
12
|
+
Apache License
|
|
13
|
+
Version 2.0, January 2004
|
|
14
|
+
http://www.apache.org/licenses/
|
|
15
|
+
|
|
16
|
+
Copyright (c) Microsoft Corporation.
|
|
17
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
18
|
+
you may not use this file except in compliance with the License.
|
|
19
|
+
You may obtain a copy of the License at
|
|
20
|
+
|
|
21
|
+
https://www.apache.org/licenses/LICENSE-2.0
|
|
22
|
+
|
|
23
|
+
Unless required by applicable law or agreed to in writing, software
|
|
24
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
25
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
26
|
+
See the License for the specific language governing permissions and
|
|
27
|
+
limitations under the License.
|
|
28
|
+
```
|
|
29
|
+
|
|
9
30
|
以上项目为 MIT 许可。保留如下版权和许可声明,适用于相应移植与改编部分:
|
|
10
31
|
|
|
11
32
|
```text
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/** Bounds on one navigation; the window stays open for the user afterwards. */
|
|
2
|
+
export declare const ACTIVATION_NAVIGATE_TIMEOUT_MS = 15000;
|
|
3
|
+
/**
|
|
4
|
+
* End-to-end budget for one open request: launch + newPage + navigate. Kept below the
|
|
5
|
+
* client's 30 s RPC wait so a successful open is reported to the user, not a timeout.
|
|
6
|
+
*/
|
|
7
|
+
export declare const ACTIVATION_OPEN_BUDGET_MS = 20000;
|
|
8
|
+
/** Bound on closing a window; a wedged browser must not pin disposal. */
|
|
9
|
+
export declare const ACTIVATION_CLOSE_TIMEOUT_MS = 5000;
|
|
10
|
+
/** Why the window could not be offered. Codes are public; no URL or error text is echoed. */
|
|
11
|
+
export type ActivationOpenCode = 'opened' | 'invalid-url' | 'unavailable' | 'failed';
|
|
12
|
+
export interface ActivationOpenResult {
|
|
13
|
+
code: ActivationOpenCode;
|
|
14
|
+
/** True only when a Chrome window is showing the activation page. */
|
|
15
|
+
opened: boolean;
|
|
16
|
+
}
|
|
17
|
+
/** The subset of playwright-core this module uses, so tests can inject a stand-in. */
|
|
18
|
+
export interface ActivationPage {
|
|
19
|
+
goto(url: string, options: {
|
|
20
|
+
waitUntil: 'domcontentloaded';
|
|
21
|
+
timeout: number;
|
|
22
|
+
}): Promise<unknown>;
|
|
23
|
+
/** playwright's Page.close(); default does not run unload handlers. */
|
|
24
|
+
close?(): Promise<void>;
|
|
25
|
+
}
|
|
26
|
+
export interface ActivationBrowser {
|
|
27
|
+
close(): Promise<unknown>;
|
|
28
|
+
isConnected(): boolean;
|
|
29
|
+
newPage(): Promise<ActivationPage>;
|
|
30
|
+
on?(event: 'disconnected', listener: () => void): unknown;
|
|
31
|
+
}
|
|
32
|
+
export interface ActivationLauncherOptions {
|
|
33
|
+
/** Injected for offline tests; production resolves playwright-core lazily. */
|
|
34
|
+
launch?: () => Promise<ActivationBrowser>;
|
|
35
|
+
timeoutMs?: number;
|
|
36
|
+
/** Reports whether a launch is even possible, e.g. a missing Chrome install. */
|
|
37
|
+
available?: () => boolean;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Chrome without the automation flag subusage found counterproductive on guarded pages.
|
|
41
|
+
* `chromiumSandbox: true` is explicit on purpose: playwright otherwise appends
|
|
42
|
+
* `--no-sandbox` (verified in playwright-core 1.63.0), and this window renders a page
|
|
43
|
+
* this plugin does not control.
|
|
44
|
+
*/
|
|
45
|
+
export declare function chromeLaunchOptions(): {
|
|
46
|
+
channel: "chrome";
|
|
47
|
+
headless: boolean;
|
|
48
|
+
chromiumSandbox: boolean;
|
|
49
|
+
ignoreDefaultArgs: string[];
|
|
50
|
+
args: string[];
|
|
51
|
+
};
|
|
52
|
+
export declare class ActivationLauncher {
|
|
53
|
+
private browser;
|
|
54
|
+
private page;
|
|
55
|
+
private pending;
|
|
56
|
+
private disposal;
|
|
57
|
+
/** In-flight window closure, shared so disposal can join it. */
|
|
58
|
+
private closing;
|
|
59
|
+
/** Closures of handles that were never adopted; disposal joins them too. */
|
|
60
|
+
private tracked;
|
|
61
|
+
/** Chrome starts in flight, so disposal waits for the handle they will produce. */
|
|
62
|
+
private starting;
|
|
63
|
+
private disposed;
|
|
64
|
+
/** Bumped by `close()`: an attempt from an older session must not resurrect a window. */
|
|
65
|
+
private session;
|
|
66
|
+
private readonly options;
|
|
67
|
+
constructor(options?: ActivationLauncherOptions);
|
|
68
|
+
/**
|
|
69
|
+
* Show `url` in the temporary window, reusing one already open. Concurrent calls share
|
|
70
|
+
* a single attempt: the caller's button stays honest about what actually happened.
|
|
71
|
+
*/
|
|
72
|
+
open(url: string): Promise<ActivationOpenResult>;
|
|
73
|
+
/**
|
|
74
|
+
* Close the temporary window and stay usable: a cancelled or expired job takes its
|
|
75
|
+
* window away, while the next login may open a new one.
|
|
76
|
+
*/
|
|
77
|
+
close(): Promise<void>;
|
|
78
|
+
/**
|
|
79
|
+
* Retire the launcher for good. Cleanup is best-effort and bounded: it joins in-flight
|
|
80
|
+
* starts and closures, but a browser that ignores `close()` may outlive the 5 s wait.
|
|
81
|
+
*/
|
|
82
|
+
dispose(): Promise<void>;
|
|
83
|
+
/**
|
|
84
|
+
* Close the window this launcher owns right now. Ownership is taken before the async
|
|
85
|
+
* close, so a job that adopts a new window afterwards is not affected by this closure.
|
|
86
|
+
* The closure promise is shared so a later `dispose()` joins it.
|
|
87
|
+
*/
|
|
88
|
+
private closeCurrent;
|
|
89
|
+
private attempt;
|
|
90
|
+
/** The job that started this attempt ended, or the launcher retired. */
|
|
91
|
+
private stale;
|
|
92
|
+
private ensureBrowser;
|
|
93
|
+
private ensurePage;
|
|
94
|
+
/** A handle that arrived too late is closed, and still counts as work disposal joins. */
|
|
95
|
+
private trackClose;
|
|
96
|
+
private trackPageClose;
|
|
97
|
+
private adopt;
|
|
98
|
+
/**
|
|
99
|
+
* Bound one launch step by the attempt's shared deadline. A step that settles only
|
|
100
|
+
* after that deadline still hands its handle back: dropping it would leak a Chrome
|
|
101
|
+
* process nobody can close.
|
|
102
|
+
*/
|
|
103
|
+
private bounded;
|
|
104
|
+
}
|
package/lib/catalog.d.ts
CHANGED
|
@@ -16,16 +16,17 @@
|
|
|
16
16
|
* 分组语义(重要):`plan`/`paid` 是**本插件本地目录分类**,用于把“套餐赠送通道”与
|
|
17
17
|
* “其余付费通道”拆成两个 Provider,不是上游强制计费契约。最终可用性、扣哪个额度池、
|
|
18
18
|
* 是否先扣 Design Plan 额度再用套餐模型/钱包额度,全部由服务端按账号套餐决定。
|
|
19
|
-
*
|
|
20
|
-
*
|
|
19
|
+
* 2026-10-27 官方 GET /v1/models 实测补齐五个 ID,现为 plan 13 + paid 25。
|
|
20
|
+
* 同日桌面 Vela 按模型 billing preflight:M3.1 Flash 的 modelCovered=true /
|
|
21
|
+
* funding=coding_plan,新增于附赠通道;其余四项为 false / wallet,归付费通道。
|
|
22
|
+
* 此分类以当次工作区证据为依据,不保证其他账号或未来套餐权益。
|
|
23
|
+
* 新增项证据及名称来源见 docs/client-evidence.md;不从型号名推断能力。
|
|
21
24
|
*
|
|
22
|
-
*
|
|
23
|
-
* - 套餐模型组中尚未公开精确 ID 的 `Muse Spark 1.3`、`Gemini 4 Argon`:
|
|
24
|
-
* 前者详情页没有 `data-model`/模型 ID,后者在模型目录里没有详情页。
|
|
25
|
+
* 未收录:
|
|
25
26
|
* - 媒体模型 `GPT Image 2`、`Nano Banana 2`、`Seedream 5 Lite / Pro`:
|
|
26
27
|
* 走 `/api/v1/media/*`,不应出现在对话模型列表里,避免选中后 chat 请求必败。
|
|
27
28
|
*
|
|
28
|
-
* `paid`
|
|
29
|
+
* `paid` 25 款及新增 M3.1 Flash 的能力字段一律缺省:没有可核实的能力数值,
|
|
29
30
|
* 不按名称推断图像能力,也不给未知项填 `['text']` 谎称不支持图像。
|
|
30
31
|
*/
|
|
31
32
|
export interface CatalogModel {
|
|
@@ -38,8 +39,8 @@ export interface CatalogModel {
|
|
|
38
39
|
reasoningEfforts?: readonly string[];
|
|
39
40
|
}
|
|
40
41
|
/**
|
|
41
|
-
*
|
|
42
|
-
* 其余
|
|
42
|
+
* `plan` 为官网 12 款 Core / Design Plan 模型,加预检确认覆盖的 M3.1 Flash;
|
|
43
|
+
* 其余 25 项归 `paid`(Plan / 钱包付费通道)。
|
|
43
44
|
*/
|
|
44
45
|
export declare const MODELS: readonly CatalogModel[];
|
|
45
46
|
export declare function modelsFor(group: 'plan' | 'paid'): readonly CatalogModel[];
|
package/lib/client.d.ts
CHANGED
|
@@ -183,9 +183,15 @@ export interface AdvancedProps {
|
|
|
183
183
|
export declare function Advanced({ status, formSnapshot, setFormField, pendingField }: AdvancedProps): React.FunctionComponentElement<{
|
|
184
184
|
children?: React.ReactNode | undefined;
|
|
185
185
|
}>;
|
|
186
|
-
/** Approval
|
|
187
|
-
export declare function LoginApproval({ login }: {
|
|
186
|
+
/** Approval is an ordinary official link; the Host may also show it in a temporary window. */
|
|
187
|
+
export declare function LoginApproval({ login, onOpen, opening, notice }: {
|
|
188
188
|
login: LoginState | undefined;
|
|
189
|
+
onOpen?: () => void;
|
|
190
|
+
opening?: boolean;
|
|
191
|
+
notice?: {
|
|
192
|
+
kind: 'status' | 'error';
|
|
193
|
+
text: string;
|
|
194
|
+
} | null;
|
|
189
195
|
}): React.DetailedReactHTMLElement<{
|
|
190
196
|
className: string;
|
|
191
197
|
'aria-label': string;
|
package/lib/client.js
CHANGED
|
@@ -19927,22 +19927,29 @@ function record2(value) {
|
|
|
19927
19927
|
}
|
|
19928
19928
|
|
|
19929
19929
|
// src/device-auth.ts
|
|
19930
|
-
function validateActivationUrl(value, userCode) {
|
|
19930
|
+
function validateActivationUrl(value, userCode, deviceId) {
|
|
19931
19931
|
if (typeof value !== "string" || value.length > 512 || !/^https:\/\/open-design\.ai\/cloud\/cli\/activate(?:\?[^#]*)?$/u.test(value) || /[\s\\]/u.test(value)) return null;
|
|
19932
19932
|
try {
|
|
19933
19933
|
const url2 = new URL(value);
|
|
19934
19934
|
if (url2.origin !== "https://open-design.ai" || url2.pathname !== "/cloud/cli/activate" || url2.username || url2.password || url2.hash) return null;
|
|
19935
19935
|
const entries = [...url2.searchParams];
|
|
19936
|
-
if (entries.length
|
|
19937
|
-
|
|
19936
|
+
if (entries.length === 2) {
|
|
19937
|
+
if (entries.some(([key]) => key !== "deviceId" && key !== "userCode")) return null;
|
|
19938
|
+
const id = url2.searchParams.get("deviceId");
|
|
19939
|
+
const code = url2.searchParams.get("userCode");
|
|
19940
|
+
if (!validDeviceId(id) || !validUserCode(code) || deviceId !== void 0 && id !== deviceId || userCode !== void 0 && code !== userCode) return null;
|
|
19941
|
+
} else if (entries.length === 1) {
|
|
19938
19942
|
const entry = entries[0];
|
|
19939
19943
|
if (!["code", "user_code"].includes(entry[0]) || !validUserCode(entry[1]) || userCode !== void 0 && entry[1] !== userCode) return null;
|
|
19940
|
-
}
|
|
19944
|
+
} else if (entries.length > 2) return null;
|
|
19941
19945
|
return url2.href;
|
|
19942
19946
|
} catch {
|
|
19943
19947
|
return null;
|
|
19944
19948
|
}
|
|
19945
19949
|
}
|
|
19950
|
+
function validDeviceId(value) {
|
|
19951
|
+
return typeof value === "string" && /^[a-z0-9_-]{1,200}$/iu.test(value);
|
|
19952
|
+
}
|
|
19946
19953
|
function validUserCode(value) {
|
|
19947
19954
|
return typeof value === "string" && /^[a-z0-9][a-z0-9-]{3,31}$/iu.test(value);
|
|
19948
19955
|
}
|
|
@@ -20021,6 +20028,7 @@ var MAX_API_KEY = 16384;
|
|
|
20021
20028
|
var HTTP_ASCII = /^[\x21-\x7e]+$/u;
|
|
20022
20029
|
var ENV_REF = /^[A-Za-z_][A-Za-z0-9_]*$/u;
|
|
20023
20030
|
var MODEL_ID = /^[A-Za-z0-9._:/-]{1,128}$/u;
|
|
20031
|
+
var ACTIVATION_OPEN_CODES = ["opened", "no-link", "invalid-url", "unavailable", "failed"];
|
|
20024
20032
|
var LOGIN_PHASES = ["idle", "launching", "waiting", "verifying", "success", "cancelled", "error"];
|
|
20025
20033
|
var QUOTA_STATES = ["ok", "partial", "need-login", "error"];
|
|
20026
20034
|
var SESSION_SOURCES = ["desktop", "login", "environment"];
|
|
@@ -20196,6 +20204,10 @@ function parseSaveApiKeyRequest(value) {
|
|
|
20196
20204
|
if (key.length > MAX_API_KEY) throw new Error(`API Key \u4E0D\u80FD\u8D85\u8FC7 ${MAX_API_KEY} \u5B57\u7B26`);
|
|
20197
20205
|
return { value: key, expectedRevision: text(value.expectedRevision, "\u914D\u7F6E\u7248\u672C", MAX_REVISION) };
|
|
20198
20206
|
}
|
|
20207
|
+
function parseActivationOpenState(value) {
|
|
20208
|
+
if (!record2(value)) throw new Error("\u6388\u6743\u9875\u6253\u5F00\u7ED3\u679C\u5FC5\u987B\u662F\u5BF9\u8C61");
|
|
20209
|
+
return { code: member(value.code, ACTIVATION_OPEN_CODES, "\u6388\u6743\u9875\u6253\u5F00\u7ED3\u679C"), opened: flag(value.opened, "\u6388\u6743\u9875\u662F\u5426\u5DF2\u6253\u5F00") };
|
|
20210
|
+
}
|
|
20199
20211
|
|
|
20200
20212
|
// src/generated/typert.remote-client.ts
|
|
20201
20213
|
var StatusCodec = { mode: "strict", typeSymbol: "dsh-opendesign-corouter#Status", create: () => external_exports.unknown().transform((value) => parseStatus(value)) };
|
|
@@ -20203,6 +20215,7 @@ var QuotaSnapshotCodec = { mode: "strict", typeSymbol: "dsh-opendesign-corouter#
|
|
|
20203
20215
|
var LoginStateCodec = { mode: "strict", typeSymbol: "dsh-opendesign-corouter#LoginState", create: () => external_exports.unknown().transform((value) => parseLoginState(value)) };
|
|
20204
20216
|
var StartLoginRequestCodec = { mode: "strict", typeSymbol: "dsh-opendesign-corouter#StartLoginRequest", create: () => external_exports.unknown().transform((value) => parseStartLoginRequest(value)) };
|
|
20205
20217
|
var CancelLoginRequestCodec = { mode: "strict", typeSymbol: "dsh-opendesign-corouter#CancelLoginRequest", create: () => external_exports.unknown().transform((value) => parseCancelLoginRequest(value)) };
|
|
20218
|
+
var ActivationOpenStateCodec = { mode: "strict", typeSymbol: "dsh-opendesign-corouter#ActivationOpenState", create: () => external_exports.unknown().transform((value) => parseActivationOpenState(value)) };
|
|
20206
20219
|
var SaveApiKeyRequestCodec = { mode: "strict", typeSymbol: "dsh-opendesign-corouter#SaveApiKeyRequest", create: () => external_exports.unknown().transform((value) => parseSaveApiKeyRequest(value)) };
|
|
20207
20220
|
var TYPERT_REMOTE = createTypertRemoteInfo({ package: "dsh-opendesign-corouter", methods: {
|
|
20208
20221
|
"openDesignCoRouter/status": { service: "openDesignCoRouter", invocation: { kind: "direct" }, parameters: [], result: StatusCodec },
|
|
@@ -20212,6 +20225,7 @@ var TYPERT_REMOTE = createTypertRemoteInfo({ package: "dsh-opendesign-corouter",
|
|
|
20212
20225
|
"openDesignCoRouter/startLogin": { service: "openDesignCoRouter", invocation: { kind: "direct" }, parameters: [{ name: "input", source: "json", codec: StartLoginRequestCodec, strictCodec: StartLoginRequestCodec }], result: LoginStateCodec },
|
|
20213
20226
|
"openDesignCoRouter/loginStatus": { service: "openDesignCoRouter", invocation: { kind: "direct" }, parameters: [], result: LoginStateCodec },
|
|
20214
20227
|
"openDesignCoRouter/cancelLogin": { service: "openDesignCoRouter", invocation: { kind: "direct" }, parameters: [{ name: "input", source: "json", codec: CancelLoginRequestCodec, strictCodec: CancelLoginRequestCodec }], result: LoginStateCodec },
|
|
20228
|
+
"openDesignCoRouter/openActivationPage": { service: "openDesignCoRouter", invocation: { kind: "direct" }, parameters: [], result: ActivationOpenStateCodec },
|
|
20215
20229
|
"openDesignCoRouter/saveApiKey": { service: "openDesignCoRouter", invocation: { kind: "direct" }, parameters: [{ name: "input", source: "json", codec: SaveApiKeyRequestCodec, strictCodec: SaveApiKeyRequestCodec }], result: StatusCodec }
|
|
20216
20230
|
} }, external_exports);
|
|
20217
20231
|
var typert_remote_client_default = TYPERT_REMOTE;
|
|
@@ -20235,13 +20249,14 @@ var MAX_REQUEST_TIMEOUT_MS = 36e5;
|
|
|
20235
20249
|
var DEFAULT_STREAM_IDLE_TIMEOUT_MS = 3e5;
|
|
20236
20250
|
var MIN_STREAM_IDLE_TIMEOUT_MS = 1e3;
|
|
20237
20251
|
var MAX_STREAM_IDLE_TIMEOUT_MS = 18e5;
|
|
20252
|
+
var RPC_TIMEOUT_MS = 3e4;
|
|
20238
20253
|
var MAX_OUTPUT_TOKENS = 1e7;
|
|
20239
20254
|
var MAX_CONTEXT_WINDOW = 1e8;
|
|
20240
20255
|
var GENERIC_ERROR = "\u64CD\u4F5C\u672A\u5B8C\u6210\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002";
|
|
20241
20256
|
var LOGIN_LABELS = {
|
|
20242
20257
|
idle: "\u5C1A\u672A\u5F00\u59CB\u72EC\u7ACB\u767B\u5F55",
|
|
20243
20258
|
launching: "\u6B63\u5728\u7533\u8BF7\u8BBE\u5907\u6388\u6743\u7801\u2026",
|
|
20244
|
-
waiting: "\u8BF7\
|
|
20259
|
+
waiting: "\u8BF7\u5728\u6388\u6743\u7A97\u53E3\u6216\u5E38\u7528\u6D4F\u89C8\u5668\u4E2D\u786E\u8BA4\u672C\u6B21\u767B\u5F55\u3002",
|
|
20245
20260
|
verifying: "\u6B63\u5728\u4FDD\u5B58\u8BBE\u5907\u6388\u6743\u2026",
|
|
20246
20261
|
success: "\u767B\u5F55\u6210\u529F\uFF0C\u8BBE\u5907\u6388\u6743\u5DF2\u4FDD\u5B58\u3002",
|
|
20247
20262
|
cancelled: "\u5DF2\u53D6\u6D88\u672C\u6B21\u767B\u5F55\u3002",
|
|
@@ -20332,7 +20347,7 @@ function createCaller(ctx) {
|
|
|
20332
20347
|
if (!operation) throw new Error("Unknown generated Remote method");
|
|
20333
20348
|
const parameter = operation.parameters[0];
|
|
20334
20349
|
const input2 = operation.input({ strict: true }).create().parse(parameter ? { [parameter.wire]: request } : {});
|
|
20335
|
-
const response = await withTimeout(Promise.resolve(operation.invoke(remote, input2)),
|
|
20350
|
+
const response = await withTimeout(Promise.resolve(operation.invoke(remote, input2)), RPC_TIMEOUT_MS, controller.signal);
|
|
20336
20351
|
if (!("ok" in response) || !response.ok) throw new Error("RPC failed");
|
|
20337
20352
|
return response.value;
|
|
20338
20353
|
};
|
|
@@ -21101,7 +21116,14 @@ function Switch({ checked, disabled, label, hint, onChange }) {
|
|
|
21101
21116
|
function loginInFlight(state) {
|
|
21102
21117
|
return state === "launching" || state === "waiting" || state === "verifying";
|
|
21103
21118
|
}
|
|
21104
|
-
|
|
21119
|
+
var ACTIVATION_OPEN_LABELS = {
|
|
21120
|
+
opened: "\u5DF2\u5728\u65B0\u7A97\u53E3\u6253\u5F00\u5B98\u65B9\u6388\u6743\u9875\uFF1B\u8BF7\u5728\u8BE5\u7A97\u53E3\u786E\u8BA4\u8BBE\u5907\u7801\u3002",
|
|
21121
|
+
"no-link": "\u6388\u6743\u7801\u5DF2\u5931\u6548\uFF0C\u8BF7\u91CD\u65B0\u7533\u8BF7\u3002",
|
|
21122
|
+
"invalid-url": "\u6388\u6743\u94FE\u63A5\u672A\u901A\u8FC7\u6821\u9A8C\uFF0C\u8BF7\u590D\u5236\u94FE\u63A5\u624B\u52A8\u6253\u5F00\u3002",
|
|
21123
|
+
unavailable: "\u65E0\u6CD5\u542F\u52A8\u4E34\u65F6\u6D4F\u89C8\u5668\uFF0C\u8BF7\u786E\u8BA4\u5DF2\u5B89\u88C5 Chrome\uFF1B\u4E5F\u53EF\u590D\u5236\u94FE\u63A5\u624B\u52A8\u6253\u5F00\u3002",
|
|
21124
|
+
failed: "\u4E34\u65F6\u6D4F\u89C8\u5668\u7A97\u53E3\u672A\u80FD\u6253\u5F00\uFF0C\u8BF7\u590D\u5236\u94FE\u63A5\u624B\u52A8\u6253\u5F00\u3002"
|
|
21125
|
+
};
|
|
21126
|
+
function LoginApproval({ login, onOpen, opening, notice }) {
|
|
21105
21127
|
if (login?.state !== "waiting" || login.userCode === void 0 || login.expiresAt === void 0) return null;
|
|
21106
21128
|
const url2 = validateActivationUrl(login.activationUrl, login.userCode);
|
|
21107
21129
|
if (url2 === null) return null;
|
|
@@ -21113,10 +21135,19 @@ function LoginApproval({ login }) {
|
|
|
21113
21135
|
h(
|
|
21114
21136
|
"div",
|
|
21115
21137
|
{ className: "odc-actions" },
|
|
21116
|
-
h("
|
|
21138
|
+
h("button", {
|
|
21139
|
+
className: "odc-button odc-button-primary",
|
|
21140
|
+
type: "button",
|
|
21141
|
+
disabled: opening === true || onOpen === void 0,
|
|
21142
|
+
onClick: () => {
|
|
21143
|
+
onOpen?.();
|
|
21144
|
+
}
|
|
21145
|
+
}, opening === true ? "\u6B63\u5728\u6253\u5F00\u2026" : "\u5728\u65B0\u7A97\u53E3\u6253\u5F00\u6388\u6743\u9875"),
|
|
21146
|
+
h("a", { className: "odc-button", href: url2, target: "_blank", rel: "noreferrer noopener" }, "\u590D\u5236\u94FE\u63A5\u624B\u52A8\u6253\u5F00")
|
|
21117
21147
|
),
|
|
21118
|
-
h(
|
|
21119
|
-
h("p", { className: "odc-hint" },
|
|
21148
|
+
notice ? h(NoticeView, { notice }) : null,
|
|
21149
|
+
h("p", { className: "odc-hint" }, `\u6388\u6743\u7801\u6709\u6548\u81F3 ${formatTime(login.expiresAt)}\u3002\u5728\u6388\u6743\u7A97\u53E3\u786E\u8BA4\u540E\uFF0C\u8FD4\u56DE\u6B64\u9875\u67E5\u770B\u7ED3\u679C\u3002`),
|
|
21150
|
+
h("p", { className: "odc-hint" }, "\u65B0\u7A97\u53E3\u662F\u72EC\u7ACB\u7684\u4E34\u65F6 Chrome\uFF0C\u4E0D\u4F1A\u8BFB\u53D6\u6216\u6539\u52A8\u4F60\u6B63\u5728\u4F7F\u7528\u7684\u6D4F\u89C8\u5668\u914D\u7F6E\uFF1B\u9700\u8981\u6CBF\u7528\u5DF2\u6709\u767B\u5F55\u6001\u65F6\uFF0C\u53F3\u952E\u590D\u5236\u94FE\u63A5\u5230\u5E38\u7528\u6D4F\u89C8\u5668\u3002\u4EC5\u786E\u8BA4\u4F60\u672C\u4EBA\u53D1\u8D77\u7684\u6388\u6743\u3002")
|
|
21120
21151
|
);
|
|
21121
21152
|
}
|
|
21122
21153
|
function Connection({ status, formSnapshot, setFormField, pendingField, caller, loadStatus, refreshAfterLogin }) {
|
|
@@ -21126,23 +21157,39 @@ function Connection({ status, formSnapshot, setFormField, pendingField, caller,
|
|
|
21126
21157
|
const [notice, setNotice] = React.useState(null);
|
|
21127
21158
|
const [apiKey, setApiKey] = React.useState("");
|
|
21128
21159
|
const [keyBusy, setKeyBusy] = React.useState(false);
|
|
21160
|
+
const [opening, setOpening] = React.useState(false);
|
|
21161
|
+
const [activationNotice, setActivationNotice] = React.useState(null);
|
|
21162
|
+
const activationJob = React.useRef(null);
|
|
21163
|
+
const activationToken = React.useRef(0);
|
|
21164
|
+
const autoOpenPending = React.useRef(false);
|
|
21129
21165
|
React.useEffect(() => () => {
|
|
21130
21166
|
actionVersion.current += 1;
|
|
21131
21167
|
}, []);
|
|
21132
21168
|
const login = status?.login;
|
|
21169
|
+
React.useEffect(() => {
|
|
21170
|
+
const job = login?.jobId ?? null;
|
|
21171
|
+
if (activationJob.current === job) return;
|
|
21172
|
+
activationJob.current = job;
|
|
21173
|
+
activationToken.current += 1;
|
|
21174
|
+
setActivationNotice(null);
|
|
21175
|
+
setOpening(false);
|
|
21176
|
+
}, [login?.jobId]);
|
|
21133
21177
|
const state = login?.state ?? "idle";
|
|
21134
21178
|
const inFlight = loginInFlight(state);
|
|
21135
21179
|
const startLogin = async () => {
|
|
21136
21180
|
if (status === void 0 || busy || keyBusy) return;
|
|
21137
21181
|
const version2 = ++actionVersion.current;
|
|
21138
21182
|
setBusy(true);
|
|
21183
|
+
autoOpenPending.current = true;
|
|
21139
21184
|
setNotice({ kind: "status", text: "\u6B63\u5728\u7533\u8BF7\u8BBE\u5907\u6388\u6743\u2026" });
|
|
21140
21185
|
try {
|
|
21141
21186
|
const next = await caller("startLogin", { expectedRevision: status.revision });
|
|
21142
21187
|
if (!mounted.current || version2 !== actionVersion.current) return;
|
|
21143
21188
|
setNotice(null);
|
|
21189
|
+
setActivationNotice(null);
|
|
21144
21190
|
await (next.state === "success" ? refreshAfterLogin() : loadStatus());
|
|
21145
21191
|
} catch {
|
|
21192
|
+
autoOpenPending.current = false;
|
|
21146
21193
|
if (mounted.current && version2 === actionVersion.current) setNotice({ kind: "error", text: "\u65E0\u6CD5\u542F\u52A8\u767B\u5F55\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\u3002" });
|
|
21147
21194
|
} finally {
|
|
21148
21195
|
if (mounted.current && version2 === actionVersion.current) setBusy(false);
|
|
@@ -21186,6 +21233,32 @@ function Connection({ status, formSnapshot, setFormField, pendingField, caller,
|
|
|
21186
21233
|
if (mounted.current && version2 === actionVersion.current) setKeyBusy(false);
|
|
21187
21234
|
}
|
|
21188
21235
|
};
|
|
21236
|
+
const openActivation = async () => {
|
|
21237
|
+
if (status === void 0 || busy || keyBusy || opening || login?.state !== "waiting") return;
|
|
21238
|
+
const job = login.jobId;
|
|
21239
|
+
const token = ++activationToken.current;
|
|
21240
|
+
activationJob.current = job;
|
|
21241
|
+
setOpening(true);
|
|
21242
|
+
setActivationNotice(null);
|
|
21243
|
+
const current = () => mounted.current && activationToken.current === token && activationJob.current === job;
|
|
21244
|
+
try {
|
|
21245
|
+
const result = await caller("openActivationPage");
|
|
21246
|
+
if (current()) setActivationNotice({ kind: result.opened ? "status" : "error", text: ACTIVATION_OPEN_LABELS[result.code] });
|
|
21247
|
+
} catch {
|
|
21248
|
+
if (current()) setActivationNotice({ kind: "error", text: ACTIVATION_OPEN_LABELS.failed });
|
|
21249
|
+
} finally {
|
|
21250
|
+
if (mounted.current && activationToken.current === token) setOpening(false);
|
|
21251
|
+
}
|
|
21252
|
+
};
|
|
21253
|
+
React.useEffect(() => {
|
|
21254
|
+
if (!autoOpenPending.current || busy || keyBusy) return;
|
|
21255
|
+
if (state === "waiting") {
|
|
21256
|
+
autoOpenPending.current = false;
|
|
21257
|
+
void openActivation();
|
|
21258
|
+
} else if (state === "error" || state === "cancelled" || state === "success") {
|
|
21259
|
+
autoOpenPending.current = false;
|
|
21260
|
+
}
|
|
21261
|
+
}, [state, login?.jobId, busy, keyBusy]);
|
|
21189
21262
|
const desktopChecked = formSnapshot.value?.useDesktopCredential ?? status?.config.useDesktopCredential ?? true;
|
|
21190
21263
|
return h(
|
|
21191
21264
|
React.Fragment,
|
|
@@ -21214,7 +21287,7 @@ function Connection({ status, formSnapshot, setFormField, pendingField, caller,
|
|
|
21214
21287
|
"section",
|
|
21215
21288
|
{ className: "odc-card" },
|
|
21216
21289
|
h("h3", null, "\u8BBE\u5907\u6388\u6743\u767B\u5F55"),
|
|
21217
|
-
h("p", { className: "odc-hint" }, "\u7533\u8BF7\u6388\u6743\u7801\u540E\uFF0C\
|
|
21290
|
+
h("p", { className: "odc-hint" }, "\u7533\u8BF7\u6388\u6743\u7801\u540E\uFF0C\u7531\u63D2\u4EF6\u542F\u52A8\u4E34\u65F6\u7A97\u53E3\u663E\u793A\u5B98\u65B9\u6388\u6743\u9875\uFF0C\u4E5F\u53EF\u590D\u5236\u94FE\u63A5\u5230\u4F60\u81EA\u5DF1\u7684\u5E38\u7528\u6D4F\u89C8\u5668\u3002\u786E\u8BA4\u540E\u81EA\u52A8\u4FDD\u5B58\u8BBE\u5907\u4EE4\u724C\uFF0C\u7528\u4E8E\u67E5\u8BE2\u989D\u5EA6\u53CA\u5B98\u65B9\u7F51\u5173\u63A8\u7406\u3002"),
|
|
21218
21291
|
h(
|
|
21219
21292
|
"div",
|
|
21220
21293
|
{ className: "odc-actions", style: { marginTop: 14 } },
|
|
@@ -21226,7 +21299,9 @@ function Connection({ status, formSnapshot, setFormField, pendingField, caller,
|
|
|
21226
21299
|
} }, "\u53D6\u6D88\u767B\u5F55") : null,
|
|
21227
21300
|
h("a", { className: "odc-link", href: OFFICIAL_SITE, target: "_blank", rel: "noreferrer noopener" }, "\u6253\u5F00 CoRouter \u5B98\u7F51")
|
|
21228
21301
|
),
|
|
21229
|
-
h(LoginApproval, { login
|
|
21302
|
+
h(LoginApproval, { login, onOpen: () => {
|
|
21303
|
+
void openActivation();
|
|
21304
|
+
}, opening, notice: activationNotice }),
|
|
21230
21305
|
h("p", { className: "odc-meta", role: state === "error" ? "alert" : "status" }, login?.message ?? LOGIN_LABELS[state]),
|
|
21231
21306
|
h(NoticeView, { notice })
|
|
21232
21307
|
),
|
package/lib/device-auth.d.ts
CHANGED
|
@@ -3,8 +3,10 @@ export interface DeviceTokens {
|
|
|
3
3
|
runtimeKey: string;
|
|
4
4
|
}
|
|
5
5
|
export declare const DEVICE_AUTH_ENDPOINT = "https://amr-api.open-design.ai/api/v1/cli/device-authorizations";
|
|
6
|
-
export declare const DEVICE_AUTH_PLUGIN_VERSION = "0.1.
|
|
6
|
+
export declare const DEVICE_AUTH_PLUGIN_VERSION = "0.1.6";
|
|
7
7
|
export declare const DEVICE_REQUEST_TIMEOUT_MS = 20000;
|
|
8
|
+
/** One bounded launch step of the temporary activation window. */
|
|
9
|
+
export declare const DEVICE_OPEN_TIMEOUT_MS = 30000;
|
|
8
10
|
export declare const DEVICE_RESPONSE_MAX_BYTES = 65536;
|
|
9
11
|
export declare const DEVICE_POLL_MIN_MS = 1000;
|
|
10
12
|
export declare const DEVICE_POLL_MAX_MS = 300000;
|
|
@@ -12,8 +14,8 @@ export declare class DeviceAuthError extends Error {
|
|
|
12
14
|
readonly code: string;
|
|
13
15
|
constructor(code: string);
|
|
14
16
|
}
|
|
15
|
-
/** Strict public-link allowlist:
|
|
16
|
-
export declare function validateActivationUrl(value: unknown, userCode?: string): string | null;
|
|
17
|
+
/** Strict public-link allowlist: a legacy code or the public deviceId/userCode pair. */
|
|
18
|
+
export declare function validateActivationUrl(value: unknown, userCode?: string, deviceId?: string): string | null;
|
|
17
19
|
export interface DeviceAuthorization {
|
|
18
20
|
deviceId: string;
|
|
19
21
|
deviceSecret: string;
|
|
@@ -8,22 +8,29 @@ function record(value) {
|
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
// src/device-auth.ts
|
|
11
|
-
function validateActivationUrl(value, userCode) {
|
|
11
|
+
function validateActivationUrl(value, userCode, deviceId) {
|
|
12
12
|
if (typeof value !== "string" || value.length > 512 || !/^https:\/\/open-design\.ai\/cloud\/cli\/activate(?:\?[^#]*)?$/u.test(value) || /[\s\\]/u.test(value)) return null;
|
|
13
13
|
try {
|
|
14
14
|
const url = new URL(value);
|
|
15
15
|
if (url.origin !== "https://open-design.ai" || url.pathname !== "/cloud/cli/activate" || url.username || url.password || url.hash) return null;
|
|
16
16
|
const entries = [...url.searchParams];
|
|
17
|
-
if (entries.length
|
|
18
|
-
|
|
17
|
+
if (entries.length === 2) {
|
|
18
|
+
if (entries.some(([key]) => key !== "deviceId" && key !== "userCode")) return null;
|
|
19
|
+
const id = url.searchParams.get("deviceId");
|
|
20
|
+
const code = url.searchParams.get("userCode");
|
|
21
|
+
if (!validDeviceId(id) || !validUserCode(code) || deviceId !== void 0 && id !== deviceId || userCode !== void 0 && code !== userCode) return null;
|
|
22
|
+
} else if (entries.length === 1) {
|
|
19
23
|
const entry = entries[0];
|
|
20
24
|
if (!["code", "user_code"].includes(entry[0]) || !validUserCode(entry[1]) || userCode !== void 0 && entry[1] !== userCode) return null;
|
|
21
|
-
}
|
|
25
|
+
} else if (entries.length > 2) return null;
|
|
22
26
|
return url.href;
|
|
23
27
|
} catch {
|
|
24
28
|
return null;
|
|
25
29
|
}
|
|
26
30
|
}
|
|
31
|
+
function validDeviceId(value) {
|
|
32
|
+
return typeof value === "string" && /^[a-z0-9_-]{1,200}$/iu.test(value);
|
|
33
|
+
}
|
|
27
34
|
function validUserCode(value) {
|
|
28
35
|
return typeof value === "string" && /^[a-z0-9][a-z0-9-]{3,31}$/iu.test(value);
|
|
29
36
|
}
|
|
@@ -89,6 +96,7 @@ var MAX_API_KEY = 16384;
|
|
|
89
96
|
var HTTP_ASCII = /^[\x21-\x7e]+$/u;
|
|
90
97
|
var ENV_REF = /^[A-Za-z_][A-Za-z0-9_]*$/u;
|
|
91
98
|
var MODEL_ID = /^[A-Za-z0-9._:/-]{1,128}$/u;
|
|
99
|
+
var ACTIVATION_OPEN_CODES = ["opened", "no-link", "invalid-url", "unavailable", "failed"];
|
|
92
100
|
var LOGIN_PHASES = ["idle", "launching", "waiting", "verifying", "success", "cancelled", "error"];
|
|
93
101
|
var QUOTA_STATES = ["ok", "partial", "need-login", "error"];
|
|
94
102
|
var SESSION_SOURCES = ["desktop", "login", "environment"];
|
|
@@ -264,6 +272,10 @@ function parseSaveApiKeyRequest(value) {
|
|
|
264
272
|
if (key.length > MAX_API_KEY) throw new Error(`API Key \u4E0D\u80FD\u8D85\u8FC7 ${MAX_API_KEY} \u5B57\u7B26`);
|
|
265
273
|
return { value: key, expectedRevision: text(value.expectedRevision, "\u914D\u7F6E\u7248\u672C", MAX_REVISION) };
|
|
266
274
|
}
|
|
275
|
+
function parseActivationOpenState(value) {
|
|
276
|
+
if (!record(value)) throw new Error("\u6388\u6743\u9875\u6253\u5F00\u7ED3\u679C\u5FC5\u987B\u662F\u5BF9\u8C61");
|
|
277
|
+
return { code: member(value.code, ACTIVATION_OPEN_CODES, "\u6388\u6743\u9875\u6253\u5F00\u7ED3\u679C"), opened: flag(value.opened, "\u6388\u6743\u9875\u662F\u5426\u5DF2\u6253\u5F00") };
|
|
278
|
+
}
|
|
267
279
|
|
|
268
280
|
// src/generated/typert.remote-client.ts
|
|
269
281
|
var StatusCodec = { mode: "strict", typeSymbol: "dsh-opendesign-corouter#Status", create: () => z.unknown().transform((value) => parseStatus(value)) };
|
|
@@ -271,6 +283,7 @@ var QuotaSnapshotCodec = { mode: "strict", typeSymbol: "dsh-opendesign-corouter#
|
|
|
271
283
|
var LoginStateCodec = { mode: "strict", typeSymbol: "dsh-opendesign-corouter#LoginState", create: () => z.unknown().transform((value) => parseLoginState(value)) };
|
|
272
284
|
var StartLoginRequestCodec = { mode: "strict", typeSymbol: "dsh-opendesign-corouter#StartLoginRequest", create: () => z.unknown().transform((value) => parseStartLoginRequest(value)) };
|
|
273
285
|
var CancelLoginRequestCodec = { mode: "strict", typeSymbol: "dsh-opendesign-corouter#CancelLoginRequest", create: () => z.unknown().transform((value) => parseCancelLoginRequest(value)) };
|
|
286
|
+
var ActivationOpenStateCodec = { mode: "strict", typeSymbol: "dsh-opendesign-corouter#ActivationOpenState", create: () => z.unknown().transform((value) => parseActivationOpenState(value)) };
|
|
274
287
|
var SaveApiKeyRequestCodec = { mode: "strict", typeSymbol: "dsh-opendesign-corouter#SaveApiKeyRequest", create: () => z.unknown().transform((value) => parseSaveApiKeyRequest(value)) };
|
|
275
288
|
var TYPERT_REMOTE = createTypertRemoteInfo({ package: "dsh-opendesign-corouter", methods: {
|
|
276
289
|
"openDesignCoRouter/status": { service: "openDesignCoRouter", invocation: { kind: "direct" }, parameters: [], result: StatusCodec },
|
|
@@ -280,6 +293,7 @@ var TYPERT_REMOTE = createTypertRemoteInfo({ package: "dsh-opendesign-corouter",
|
|
|
280
293
|
"openDesignCoRouter/startLogin": { service: "openDesignCoRouter", invocation: { kind: "direct" }, parameters: [{ name: "input", source: "json", codec: StartLoginRequestCodec, strictCodec: StartLoginRequestCodec }], result: LoginStateCodec },
|
|
281
294
|
"openDesignCoRouter/loginStatus": { service: "openDesignCoRouter", invocation: { kind: "direct" }, parameters: [], result: LoginStateCodec },
|
|
282
295
|
"openDesignCoRouter/cancelLogin": { service: "openDesignCoRouter", invocation: { kind: "direct" }, parameters: [{ name: "input", source: "json", codec: CancelLoginRequestCodec, strictCodec: CancelLoginRequestCodec }], result: LoginStateCodec },
|
|
296
|
+
"openDesignCoRouter/openActivationPage": { service: "openDesignCoRouter", invocation: { kind: "direct" }, parameters: [], result: ActivationOpenStateCodec },
|
|
283
297
|
"openDesignCoRouter/saveApiKey": { service: "openDesignCoRouter", invocation: { kind: "direct" }, parameters: [{ name: "input", source: "json", codec: SaveApiKeyRequestCodec, strictCodec: SaveApiKeyRequestCodec }], result: StatusCodec }
|
|
284
298
|
} }, z);
|
|
285
299
|
var typert_remote_client_default = TYPERT_REMOTE;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { RemoteResult } from '@deepseek-ai/dsh-typert-protocol';
|
|
2
|
-
import type { Status, QuotaSnapshot, LoginState, StartLoginRequest, CancelLoginRequest, SaveApiKeyRequest } from '../remote.js';
|
|
2
|
+
import type { Status, QuotaSnapshot, LoginState, StartLoginRequest, CancelLoginRequest, ActivationOpenState, SaveApiKeyRequest } from '../remote.js';
|
|
3
3
|
export type CoRouterRemote = {
|
|
4
4
|
status: () => Promise<RemoteResult<Status>>;
|
|
5
5
|
refreshModels: () => Promise<RemoteResult<Status>>;
|
|
@@ -8,6 +8,7 @@ export type CoRouterRemote = {
|
|
|
8
8
|
startLogin: (input: StartLoginRequest) => Promise<RemoteResult<LoginState>>;
|
|
9
9
|
loginStatus: () => Promise<RemoteResult<LoginState>>;
|
|
10
10
|
cancelLogin: (input: CancelLoginRequest) => Promise<RemoteResult<LoginState>>;
|
|
11
|
+
openActivationPage: () => Promise<RemoteResult<ActivationOpenState>>;
|
|
11
12
|
saveApiKey: (input: SaveApiKeyRequest) => Promise<RemoteResult<Status>>;
|
|
12
13
|
};
|
|
13
14
|
declare module '@deepseek-ai/dsh-typert-protocol' {
|