@artenx/dshb 0.1.32 → 0.1.34

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.
@@ -70,6 +70,46 @@ declare class SyncSshTransport {
70
70
  private fetchDataOperation;
71
71
  private requestHandshake;
72
72
  }
73
+ interface SyncRemoteProbeDraft {
74
+ host: string;
75
+ port: number;
76
+ username: string;
77
+ authKind: 'password' | 'key';
78
+ }
79
+ interface SyncRemoteProbeProfile {
80
+ name: string;
81
+ dshbInstalled: boolean;
82
+ home: string;
83
+ }
84
+ interface SyncRemoteProbeHandshake {
85
+ port: number;
86
+ instanceId: string;
87
+ }
88
+ interface SyncRemoteProbeResult {
89
+ homes: string[];
90
+ profiles: SyncRemoteProbeProfile[];
91
+ /** 握手命中的全部端口(同机多实例时可能有多个;配置端口的命中排最前)。 */
92
+ handshakes: SyncRemoteProbeHandshake[];
93
+ webPort?: number;
94
+ instanceId?: string;
95
+ processHints: string[];
96
+ hostKeyFingerprint: string;
97
+ }
98
+ declare const REMOTE_PROBE_BEGIN_MARKER = "DSHB_PROBE_BEGIN";
99
+ declare const REMOTE_PROBE_END_MARKER = "DSHB_PROBE_END";
100
+ /**
101
+ * 生成远端发现脚本:纯 POSIX sh + 远端 node(DSH 所在机器必然有 node)。
102
+ * 三个动作:① 多候选定位 DSH_HOME(含桌面版常见路径);② 列出 profiles 及
103
+ * dshb 安装标记;③ 握手探测真实 Web 端口(仅远端回环,桌面版 127.0.0.1:3080
104
+ * 即可命中)。输出以 BEGIN/END 标记包裹,逐行 "key value"。
105
+ */
106
+ declare function buildRemoteProbeScript(dshHome?: string, preferredWebPort?: number): string;
107
+ /** 解析探测输出:仅在 BEGIN/END 标记之间取行,容忍未知行。 */
108
+ declare function parseRemoteProbeOutput(output: string, hostKeyFingerprint: string, preferredWebPort?: number): SyncRemoteProbeResult;
109
+ declare class SyncRemoteProbe {
110
+ /** 探测远端:SSH 登录 + 单次 exec 发现脚本;主机密钥自动接受(只读发现,指纹随结果返回)。 */
111
+ probeRemote(draft: SyncRemoteProbeDraft, secrets: SyncPeerSecrets, preferredWebPort?: number): Promise<SyncRemoteProbeResult>;
112
+ }
73
113
  //#endregion
74
- export { SyncSshProbeError as a, buildSyncSshConnectConfig as c, SyncSshErrorCategory as i, SyncRemoteNodeManifest as n, SyncSshSession as o, SyncSessionDeltaPrefixError as r, SyncSshTransport as s, SyncRemoteHandshake as t };
75
- //# sourceMappingURL=ssh-transport-B2oNDs0D.d.ts.map
114
+ export { parseRemoteProbeOutput as _, SyncRemoteProbe as a, SyncRemoteProbeProfile as c, SyncSshErrorCategory as d, SyncSshProbeError as f, buildSyncSshConnectConfig as g, buildRemoteProbeScript as h, SyncRemoteNodeManifest as i, SyncRemoteProbeResult as l, SyncSshTransport as m, REMOTE_PROBE_END_MARKER as n, SyncRemoteProbeDraft as o, SyncSshSession as p, SyncRemoteHandshake as r, SyncRemoteProbeHandshake as s, REMOTE_PROBE_BEGIN_MARKER as t, SyncSessionDeltaPrefixError as u };
115
+ //# sourceMappingURL=ssh-transport-C7povM0s.d.ts.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@artenx/dshb",
3
- "version": "0.1.32",
3
+ "version": "0.1.34",
4
4
  "description": "Routes DSH filesystem, shell, subprocess, and PTY operations to local, SSH, and Docker execution nodes, with a node registry, an authentication gate, a mobile-aware management UI, and per-workspace custom project instructions.",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
@@ -8,7 +8,6 @@
8
8
  "exports": {
9
9
  ".": "./lib/index.js",
10
10
  "./auth": "./lib/auth/index.js",
11
- "./auth/startup": "./lib/auth/startup.js",
12
11
  "./auth/decorate-webserver": "./lib/auth/decorate-webserver.js",
13
12
  "./auth/loopback": "./lib/auth/loopback.js",
14
13
  "./auth/loopback-compat": "./lib/auth/loopback-compat.js",
@@ -83,8 +82,8 @@
83
82
  "./package.json": "./package.json"
84
83
  },
85
84
  "files": [
86
- "lib",
87
- "cordis.patch.yml"
85
+ "cordis.patch.yml",
86
+ "lib"
88
87
  ],
89
88
  "dsh": {
90
89
  "bundle": {
@@ -180,5 +179,8 @@
180
179
  "homepage": "https://github.com/Artenx/dsh-honeybee#readme",
181
180
  "bugs": {
182
181
  "url": "https://github.com/Artenx/dsh-honeybee/issues"
182
+ },
183
+ "bin": {
184
+ "dshb-auth-reset": "./lib/auth/reset-cli.js"
183
185
  }
184
186
  }
@@ -1,15 +0,0 @@
1
- import { Context } from "@deepseek-ai/cordis";
2
- //#region src/auth/startup.d.ts
3
- declare const name = "web-startup";
4
- declare const inject: string[];
5
- declare const WEB_STARTUP_SERVICE = "webStartup";
6
- interface WebStartupValues {
7
- openBrowser: boolean;
8
- host?: string;
9
- port?: number;
10
- trustedHosts: string[];
11
- }
12
- declare function apply(ctx: Context): void;
13
- //#endregion
14
- export { WEB_STARTUP_SERVICE, WebStartupValues, apply, inject, name };
15
- //# sourceMappingURL=startup.d.ts.map
@@ -1,68 +0,0 @@
1
- import { sanitizeUsername, sharedCredentialStore } from "./credentials.js";
2
- import { Command } from "commander";
3
- import { parseCmdline } from "@deepseek-ai/dsh-cmdline";
4
- //#region src/auth/startup.ts
5
- const name = "web-startup";
6
- const inject = ["cmdlineArgs"];
7
- const WEB_STARTUP_SERVICE = "webStartup";
8
- function runAuthReset(args) {
9
- const store = sharedCredentialStore();
10
- if (!store.isInitialized()) {
11
- console.error("auth-reset: 尚未初始化管理员账号");
12
- process.exit(1);
13
- }
14
- let password;
15
- let username;
16
- for (let i = 1; i < args.length; i++) if (args[i] === "--password") password = args[++i];
17
- else if (args[i] === "--username") username = args[++i];
18
- if (password === void 0 && username === void 0) {
19
- console.error("auth-reset: 需要 --password <新密码> 和/或 --username <新用户名>");
20
- process.exit(1);
21
- }
22
- if (password !== void 0 && password.length < 8) {
23
- console.error("auth-reset: 密码至少 8 个字符");
24
- process.exit(1);
25
- }
26
- if (username !== void 0) {
27
- username = sanitizeUsername(username);
28
- if (!username) {
29
- console.error("auth-reset: 用户名不能为空");
30
- process.exit(1);
31
- }
32
- }
33
- if (password !== void 0) store.changePassword(username ?? store.username, password);
34
- else store.changeUsername(username);
35
- console.log("auth-reset: 已更新凭据并轮换会话密钥,全部已签发会话作废");
36
- process.exit(0);
37
- }
38
- function webCommand() {
39
- return new Command().name("dsh --profile web").description("Serve the DeepSeek Harness UI.").helpOption("-h, --help", "show this help").option("--host <host>", "bind host").option("--no-open", "do not open the UI in the default browser").option("--port <port>", "listen port; pass 0 to let the OS pick a free one").option("--trusted-host <authority...>", "extra authority the /api browser-trust fence accepts (host or host:port; repeatable)").addHelpText("after", `
40
- Examples:
41
- dsh --profile web serve on the composed host and port
42
- dsh --profile web --no-open serve without opening a browser (desktop app ignores this)
43
- dsh --profile web --port 8080 serve on another port
44
- dsh --profile web --host 0.0.0.0 serve on all interfaces (DSHB: auth plugin guards access)
45
- dsh --profile web auth-reset --password <新密码> reset admin credentials and revoke all sessions
46
- `);
47
- }
48
- function apply(ctx) {
49
- const args = ctx.cmdlineArgs?.get() ?? [];
50
- if (args[0] === "auth-reset") runAuthReset(args);
51
- const program = webCommand();
52
- program.action(() => {
53
- const options = program.opts();
54
- if (options.port !== void 0 && !/^\d+$/.test(options.port)) program.error(`error: --port must be a number, got ${JSON.stringify(options.port)}`);
55
- const values = {
56
- openBrowser: options.open,
57
- ...options.host !== void 0 && { host: options.host },
58
- ...options.port !== void 0 && { port: Number(options.port) },
59
- trustedHosts: options.trustedHost ?? []
60
- };
61
- ctx.provide(WEB_STARTUP_SERVICE, values);
62
- });
63
- parseCmdline(ctx, program);
64
- }
65
- //#endregion
66
- export { WEB_STARTUP_SERVICE, apply, inject, name };
67
-
68
- //# sourceMappingURL=startup.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"startup.js","names":[],"sources":["../../src/auth/startup.ts"],"sourcesContent":["import { Command } from 'commander'\nimport { parseCmdline } from '@deepseek-ai/dsh-cmdline'\nimport type { Context } from '@deepseek-ai/cordis'\nimport { sanitizeUsername, sharedCredentialStore } from './credentials.js'\n\nexport const name = 'web-startup'\n\nexport const inject = ['cmdlineArgs']\n\nexport const WEB_STARTUP_SERVICE = 'webStartup'\n\nexport interface WebStartupValues {\n openBrowser: boolean\n host?: string\n port?: number\n trustedHosts: string[]\n}\n\nfunction runAuthReset(args: readonly string[]): never {\n const store = sharedCredentialStore()\n if (!store.isInitialized()) {\n console.error('auth-reset: 尚未初始化管理员账号')\n process.exit(1)\n }\n let password: string | undefined\n let username: string | undefined\n for (let i = 1; i < args.length; i++) {\n if (args[i] === '--password') password = args[++i]\n else if (args[i] === '--username') username = args[++i]\n }\n if (password === undefined && username === undefined) {\n console.error('auth-reset: 需要 --password <新密码> 和/或 --username <新用户名>')\n process.exit(1)\n }\n if (password !== undefined && password.length < 8) {\n console.error('auth-reset: 密码至少 8 个字符')\n process.exit(1)\n }\n if (username !== undefined) {\n username = sanitizeUsername(username)\n if (!username) {\n console.error('auth-reset: 用户名不能为空')\n process.exit(1)\n }\n }\n if (password !== undefined) store.changePassword(username ?? store.username!, password)\n else store.changeUsername(username!)\n console.log('auth-reset: 已更新凭据并轮换会话密钥,全部已签发会话作废')\n process.exit(0)\n}\n\nfunction webCommand(): Command {\n return new Command()\n .name('dsh --profile web')\n .description('Serve the DeepSeek Harness UI.')\n .helpOption('-h, --help', 'show this help')\n .option('--host <host>', 'bind host')\n .option('--no-open', 'do not open the UI in the default browser')\n .option('--port <port>', 'listen port; pass 0 to let the OS pick a free one')\n .option(\n '--trusted-host <authority...>',\n 'extra authority the /api browser-trust fence accepts (host or host:port; repeatable)',\n )\n .addHelpText(\n 'after',\n `\nExamples:\n dsh --profile web serve on the composed host and port\n dsh --profile web --no-open serve without opening a browser (desktop app ignores this)\n dsh --profile web --port 8080 serve on another port\n dsh --profile web --host 0.0.0.0 serve on all interfaces (DSHB: auth plugin guards access)\n dsh --profile web auth-reset --password <新密码> reset admin credentials and revoke all sessions\n`,\n )\n}\n\nexport function apply(ctx: Context): void {\n const args = ctx.cmdlineArgs?.get() ?? []\n if (args[0] === 'auth-reset') runAuthReset(args)\n const program = webCommand()\n program.action(() => {\n const options = program.opts()\n if (options.port !== undefined && !/^\\d+$/.test(options.port)) {\n program.error(`error: --port must be a number, got ${JSON.stringify(options.port)}`)\n }\n const values: WebStartupValues = {\n openBrowser: options.open,\n ...(options.host !== undefined && { host: options.host }),\n ...(options.port !== undefined && { port: Number(options.port) }),\n trustedHosts: options.trustedHost ?? [],\n }\n ctx.provide(WEB_STARTUP_SERVICE, values)\n })\n parseCmdline(ctx, program)\n}\n"],"mappings":";;;;AAKA,MAAa,OAAO;AAEpB,MAAa,SAAS,CAAC,aAAa;AAEpC,MAAa,sBAAsB;AASnC,SAAS,aAAa,MAAgC;CACpD,MAAM,QAAQ,sBAAsB;CACpC,IAAI,CAAC,MAAM,cAAc,GAAG;EAC1B,QAAQ,MAAM,wBAAwB;EACtC,QAAQ,KAAK,CAAC;CAChB;CACA,IAAI;CACJ,IAAI;CACJ,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,QAAQ,KAC/B,IAAI,KAAK,OAAO,cAAc,WAAW,KAAK,EAAE;MAC3C,IAAI,KAAK,OAAO,cAAc,WAAW,KAAK,EAAE;CAEvD,IAAI,aAAa,KAAA,KAAa,aAAa,KAAA,GAAW;EACpD,QAAQ,MAAM,uDAAuD;EACrE,QAAQ,KAAK,CAAC;CAChB;CACA,IAAI,aAAa,KAAA,KAAa,SAAS,SAAS,GAAG;EACjD,QAAQ,MAAM,wBAAwB;EACtC,QAAQ,KAAK,CAAC;CAChB;CACA,IAAI,aAAa,KAAA,GAAW;EAC1B,WAAW,iBAAiB,QAAQ;EACpC,IAAI,CAAC,UAAU;GACb,QAAQ,MAAM,qBAAqB;GACnC,QAAQ,KAAK,CAAC;EAChB;CACF;CACA,IAAI,aAAa,KAAA,GAAW,MAAM,eAAe,YAAY,MAAM,UAAW,QAAQ;MACjF,MAAM,eAAe,QAAS;CACnC,QAAQ,IAAI,oCAAoC;CAChD,QAAQ,KAAK,CAAC;AAChB;AAEA,SAAS,aAAsB;CAC7B,OAAO,IAAI,QAAQ,CAAC,CACjB,KAAK,mBAAmB,CAAC,CACzB,YAAY,gCAAgC,CAAC,CAC7C,WAAW,cAAc,gBAAgB,CAAC,CAC1C,OAAO,iBAAiB,WAAW,CAAC,CACpC,OAAO,aAAa,2CAA2C,CAAC,CAChE,OAAO,iBAAiB,mDAAmD,CAAC,CAC5E,OACC,iCACA,sFACF,CAAC,CACA,YACC,SACA;;;;;;;CAQF;AACJ;AAEA,SAAgB,MAAM,KAAoB;CACxC,MAAM,OAAO,IAAI,aAAa,IAAI,KAAK,CAAC;CACxC,IAAI,KAAK,OAAO,cAAc,aAAa,IAAI;CAC/C,MAAM,UAAU,WAAW;CAC3B,QAAQ,aAAa;EACnB,MAAM,UAAU,QAAQ,KAAK;EAC7B,IAAI,QAAQ,SAAS,KAAA,KAAa,CAAC,QAAQ,KAAK,QAAQ,IAAI,GAC1D,QAAQ,MAAM,uCAAuC,KAAK,UAAU,QAAQ,IAAI,GAAG;EAErF,MAAM,SAA2B;GAC/B,aAAa,QAAQ;GACrB,GAAI,QAAQ,SAAS,KAAA,KAAa,EAAE,MAAM,QAAQ,KAAK;GACvD,GAAI,QAAQ,SAAS,KAAA,KAAa,EAAE,MAAM,OAAO,QAAQ,IAAI,EAAE;GAC/D,cAAc,QAAQ,eAAe,CAAC;EACxC;EACA,IAAI,QAAQ,qBAAqB,MAAM;CACzC,CAAC;CACD,aAAa,KAAK,OAAO;AAC3B"}