dsh-multi-chat 0.4.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 +21 -0
- package/README.md +163 -0
- package/bin/dsh-multi-chat.mjs +417 -0
- package/package.json +45 -0
- package/patches/multi-wall.yml +10 -0
- package/plugin/dsh-client-ui-multi-wall/README.md +45 -0
- package/plugin/dsh-client-ui-multi-wall/lib/client.js +755 -0
- package/plugin/dsh-client-ui-multi-wall/lib/index.js +790 -0
- package/plugin/dsh-client-ui-multi-wall/lib/invariant.js +27 -0
- package/plugin/dsh-client-ui-multi-wall/lib/types/client/WallToggle.d.ts +10 -0
- package/plugin/dsh-client-ui-multi-wall/lib/types/client/WallView.d.ts +16 -0
- package/plugin/dsh-client-ui-multi-wall/lib/types/client/index.d.ts +39 -0
- package/plugin/dsh-client-ui-multi-wall/lib/types/client/locales.d.ts +94 -0
- package/plugin/dsh-client-ui-multi-wall/lib/types/client/store.d.ts +27 -0
- package/plugin/dsh-client-ui-multi-wall/lib/types/client/wall-injected.d.ts +53 -0
- package/plugin/dsh-client-ui-multi-wall/lib/types/index.d.ts +67 -0
- package/plugin/dsh-client-ui-multi-wall/lib/types/invariant.d.ts +17 -0
- package/plugin/dsh-client-ui-multi-wall/package.json +84 -0
- package/scripts/gateway-hidden.vbs +35 -0
- package/scripts/gateway-start.ps1 +21 -0
- package/scripts/gateway-stop.ps1 +34 -0
- package/scripts/gateway.mjs +511 -0
- package/scripts/install-plugin.ps1 +65 -0
- package/scripts/start-multi.ps1 +180 -0
- package/scripts/stop-multi.ps1 +42 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
//#region lib/types/invariant.js
|
|
2
|
+
/**
|
|
3
|
+
* Package-owned invariant companion for
|
|
4
|
+
* `@deepseek-ai/dsh-client-ui-multi-wall`.
|
|
5
|
+
* @module @deepseek-ai/dsh-client-ui-multi-wall/invariant
|
|
6
|
+
*/
|
|
7
|
+
const PACKAGE_NAME = "@deepseek-ai/dsh-client-ui-multi-wall";
|
|
8
|
+
/** Cordis companion plugin name. */
|
|
9
|
+
const name = "client-ui-multi-wall-invariant";
|
|
10
|
+
/** Service required before the companion can reserve package ownership. */
|
|
11
|
+
const inject = ["invariants"];
|
|
12
|
+
/**
|
|
13
|
+
* No runtime invariant: the wall contributes the conversation view-ring entry
|
|
14
|
+
* (the wall surface) and the sidebar footer shortcut, whose disposal is
|
|
15
|
+
* proven by the HMR-safety spec — the plugin owns one store handle used by
|
|
16
|
+
* the view entry, emits no cordis events, and holds no cross-plugin mutable
|
|
17
|
+
* state.
|
|
18
|
+
*/
|
|
19
|
+
const install = () => {};
|
|
20
|
+
/**
|
|
21
|
+
* Register this package's invariant companion.
|
|
22
|
+
* @param ctx - Cordis context carrying the invariant service.
|
|
23
|
+
* @returns the installed registration's disposer after setup succeeds.
|
|
24
|
+
*/
|
|
25
|
+
const apply = (ctx) => Promise.resolve(ctx.invariants.register(PACKAGE_NAME, install));
|
|
26
|
+
//#endregion
|
|
27
|
+
export { apply, inject, name };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
|
|
2
|
+
/** Composed props: sidebar column state + locale. */
|
|
3
|
+
export type WallToggleProps = PropsRuntime<'sidebar.footer.action'> & PropsLocale<'multiWall'>;
|
|
4
|
+
/**
|
|
5
|
+
* Render the wall shortcut row (icon; label only in the wide column).
|
|
6
|
+
* @param props - composed slot props.
|
|
7
|
+
* @returns the shortcut row.
|
|
8
|
+
*/
|
|
9
|
+
export declare function WallToggle({ wide, t }: WallToggleProps): import("react").JSX.Element;
|
|
10
|
+
//# sourceMappingURL=WallToggle.d.ts.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { PropsLocale, PropsStore } from '@deepseek-ai/dsh-client-ui-slots';
|
|
2
|
+
import type { HandleOf } from '@deepseek-ai/dsh-client-ui-slots';
|
|
3
|
+
import type { ConvViewProps } from '@deepseek-ai/dsh-client-ui-conversation/client';
|
|
4
|
+
import type { createWallStore } from './store.ts';
|
|
5
|
+
import type { WallInjected } from './wall-injected.ts';
|
|
6
|
+
/** Composed props: the view-ring runtime share, the store, the probe face, and locale. */
|
|
7
|
+
export type WallViewProps = ConvViewProps & PropsStore<HandleOf<typeof createWallStore>> & WallInjected & PropsLocale<'multiWall'>;
|
|
8
|
+
/**
|
|
9
|
+
* Render the wall: toolbar plus the horizontally-filled pane grid. Discovery
|
|
10
|
+
* runs on mount and liveness polls every 5s; the store's persisted ports
|
|
11
|
+
* survive view switches and reloads.
|
|
12
|
+
* @param props - composed slot props.
|
|
13
|
+
* @returns the wall surface.
|
|
14
|
+
*/
|
|
15
|
+
export declare function WallView({ useStore, actions, discover, probe, stop, create, link, t }: WallViewProps): import("react").JSX.Element;
|
|
16
|
+
//# sourceMappingURL=WallView.d.ts.map
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Multi-window wall plugin, browser half: contributes the wall as a
|
|
3
|
+
* `conversation.view` ring entry (the official replace-the-chat-surface
|
|
4
|
+
* mechanism — the header grows a "多窗口墙" tab and the right panel swaps to
|
|
5
|
+
* the wall) plus a sidebar footer shortcut that jumps to that view. No
|
|
6
|
+
* existing slot is replaced and no original interaction logic changes; the
|
|
7
|
+
* wall is pure UI over the node half's /multi/api probe routes.
|
|
8
|
+
*
|
|
9
|
+
* Recursion guard: a wall pane embeds each instance as
|
|
10
|
+
* `http://127.0.0.1:<port>/?multi-wall=embed`; the embedded page sees the
|
|
11
|
+
* query flag and registers nothing, so a pane can never grow a wall of its
|
|
12
|
+
* own. The wall also never renders the port it is served on (SELF_PORT is
|
|
13
|
+
* filtered at render time and by the node half's discovery).
|
|
14
|
+
*/
|
|
15
|
+
import type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client';
|
|
16
|
+
import { type MultiWallKey } from './locales.ts';
|
|
17
|
+
export { WallView } from './WallView.tsx';
|
|
18
|
+
export type { WallViewProps } from './WallView.tsx';
|
|
19
|
+
export { WallToggle } from './WallToggle.tsx';
|
|
20
|
+
export type { WallToggleProps } from './WallToggle.tsx';
|
|
21
|
+
export type { MultiWallKey } from './locales.ts';
|
|
22
|
+
export { createWallStore } from './store.ts';
|
|
23
|
+
export type { WallState, WallActions } from './store.ts';
|
|
24
|
+
export type { ProbeRow, StopRow, WallInjected } from './wall-injected.ts';
|
|
25
|
+
declare module '@deepseek-ai/dsh-client-ui-slots' {
|
|
26
|
+
interface LocaleNamespaceMap {
|
|
27
|
+
/** Multi-window wall copy. */
|
|
28
|
+
multiWall: MultiWallKey;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/** Required services: slots for both registrations, locale for copy. */
|
|
32
|
+
export declare const inject: string[];
|
|
33
|
+
/**
|
|
34
|
+
* Client plugin body: register the dictionaries, the view-ring entry (the
|
|
35
|
+
* wall), and the sidebar footer shortcut. Embedded panes register nothing.
|
|
36
|
+
* @param ctx - client root context.
|
|
37
|
+
*/
|
|
38
|
+
export declare function apply(ctx: ClientContext): void;
|
|
39
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/** `multiWall` namespace dictionaries. */
|
|
2
|
+
/** Simplified Chinese dictionary (the key-set source of truth). */
|
|
3
|
+
export declare const zh: {
|
|
4
|
+
toggle: string;
|
|
5
|
+
'toggle.aria': string;
|
|
6
|
+
'view.multiWall': string;
|
|
7
|
+
'overlay.title': string;
|
|
8
|
+
'overlay.close': string;
|
|
9
|
+
scan: string;
|
|
10
|
+
'scan.from': string;
|
|
11
|
+
'scan.to': string;
|
|
12
|
+
create: string;
|
|
13
|
+
'create.done': string;
|
|
14
|
+
'create.failed': string;
|
|
15
|
+
'create.unknown': string;
|
|
16
|
+
exit: string;
|
|
17
|
+
'exit.aria': string;
|
|
18
|
+
link: string;
|
|
19
|
+
'link.aria': string;
|
|
20
|
+
'link.fetching': string;
|
|
21
|
+
'link.none': string;
|
|
22
|
+
'link.copy': string;
|
|
23
|
+
'link.copied': string;
|
|
24
|
+
'link.hint': string;
|
|
25
|
+
'link.reachable': string;
|
|
26
|
+
'link.unreachable': string;
|
|
27
|
+
columns: string;
|
|
28
|
+
'columns.auto': string;
|
|
29
|
+
refresh: string;
|
|
30
|
+
openTab: string;
|
|
31
|
+
reload: string;
|
|
32
|
+
remove: string;
|
|
33
|
+
stop: string;
|
|
34
|
+
'stop.confirm': string;
|
|
35
|
+
'stop.self': string;
|
|
36
|
+
'stop.done': string;
|
|
37
|
+
'stop.failed': string;
|
|
38
|
+
zoom: string;
|
|
39
|
+
loading: string;
|
|
40
|
+
empty: string;
|
|
41
|
+
'empty.hint': string;
|
|
42
|
+
'status.scanning': string;
|
|
43
|
+
'status.found': string;
|
|
44
|
+
'status.none': string;
|
|
45
|
+
'status.refreshed': string;
|
|
46
|
+
};
|
|
47
|
+
/** The multi-wall namespace key union. */
|
|
48
|
+
export type MultiWallKey = keyof typeof zh;
|
|
49
|
+
/** English dictionary, checked complete against the zh key set. */
|
|
50
|
+
export declare const en: {
|
|
51
|
+
toggle: string;
|
|
52
|
+
'toggle.aria': string;
|
|
53
|
+
'view.multiWall': string;
|
|
54
|
+
'overlay.title': string;
|
|
55
|
+
'overlay.close': string;
|
|
56
|
+
scan: string;
|
|
57
|
+
'scan.from': string;
|
|
58
|
+
'scan.to': string;
|
|
59
|
+
create: string;
|
|
60
|
+
'create.done': string;
|
|
61
|
+
'create.failed': string;
|
|
62
|
+
'create.unknown': string;
|
|
63
|
+
exit: string;
|
|
64
|
+
'exit.aria': string;
|
|
65
|
+
link: string;
|
|
66
|
+
'link.aria': string;
|
|
67
|
+
'link.fetching': string;
|
|
68
|
+
'link.none': string;
|
|
69
|
+
'link.copy': string;
|
|
70
|
+
'link.copied': string;
|
|
71
|
+
'link.hint': string;
|
|
72
|
+
'link.reachable': string;
|
|
73
|
+
'link.unreachable': string;
|
|
74
|
+
columns: string;
|
|
75
|
+
'columns.auto': string;
|
|
76
|
+
refresh: string;
|
|
77
|
+
openTab: string;
|
|
78
|
+
reload: string;
|
|
79
|
+
remove: string;
|
|
80
|
+
stop: string;
|
|
81
|
+
'stop.confirm': string;
|
|
82
|
+
'stop.self': string;
|
|
83
|
+
'stop.done': string;
|
|
84
|
+
'stop.failed': string;
|
|
85
|
+
zoom: string;
|
|
86
|
+
loading: string;
|
|
87
|
+
empty: string;
|
|
88
|
+
'empty.hint': string;
|
|
89
|
+
'status.scanning': string;
|
|
90
|
+
'status.found': string;
|
|
91
|
+
'status.none': string;
|
|
92
|
+
'status.refreshed': string;
|
|
93
|
+
};
|
|
94
|
+
//# sourceMappingURL=locales.d.ts.map
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wall store: which instances are shown and the grid columns. The ports list
|
|
3
|
+
* is the wall's whole business state — discovery writes it, removal filters
|
|
4
|
+
* it, and the grid renders from it. Open/closed is NOT stored here: the wall
|
|
5
|
+
* is a `conversation.view` ring entry, so the active view (chat store's
|
|
6
|
+
* `view` field) decides whether it renders.
|
|
7
|
+
*/
|
|
8
|
+
import { type EngineStoreHandle } from '@deepseek-ai/dsh-client-runtime/client';
|
|
9
|
+
/** Wall viewing state: displayed ports and grid columns. */
|
|
10
|
+
export type WallState = {
|
|
11
|
+
ports: number[];
|
|
12
|
+
columns: string;
|
|
13
|
+
};
|
|
14
|
+
/** The wall store's complete write set. */
|
|
15
|
+
export type WallActions = {
|
|
16
|
+
setPorts: (draft: WallState, ports: number[]) => void;
|
|
17
|
+
addPort: (draft: WallState, port: number) => void;
|
|
18
|
+
removePort: (draft: WallState, port: number) => void;
|
|
19
|
+
setColumns: (draft: WallState, columns: string) => void;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Create the wall store handle. Persisted under `dsh.multi-wall` so the port
|
|
23
|
+
* set and column choice survive view switches and reloads.
|
|
24
|
+
* @returns the store handle (spec + type + identity + factory in one).
|
|
25
|
+
*/
|
|
26
|
+
export declare function createWallStore(): EngineStoreHandle<WallState, WallActions>;
|
|
27
|
+
//# sourceMappingURL=store.d.ts.map
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Injected probe face for the wall view: same-origin fetches to the node
|
|
3
|
+
* half's /multi/api routes. Callbacks only — components never see ctx.
|
|
4
|
+
*/
|
|
5
|
+
/** One liveness row from /multi/api/status. */
|
|
6
|
+
export interface ProbeRow {
|
|
7
|
+
port: number;
|
|
8
|
+
alive: boolean;
|
|
9
|
+
status: number;
|
|
10
|
+
}
|
|
11
|
+
/** One stop result row from /multi/api/stop. */
|
|
12
|
+
export interface StopRow {
|
|
13
|
+
port: number;
|
|
14
|
+
ok: boolean;
|
|
15
|
+
error?: string;
|
|
16
|
+
}
|
|
17
|
+
/** One create result row from /multi/api/create. */
|
|
18
|
+
export interface CreateRow {
|
|
19
|
+
ok: boolean;
|
|
20
|
+
port?: number;
|
|
21
|
+
error?: string;
|
|
22
|
+
}
|
|
23
|
+
/** The phone-reachable link info from /multi/api/link. */
|
|
24
|
+
export interface LinkRow {
|
|
25
|
+
port: number;
|
|
26
|
+
host: string;
|
|
27
|
+
/** LAN URLs (`http://<lan-ip>:<port>/`), possibly empty. */
|
|
28
|
+
lan: string[];
|
|
29
|
+
/** Whether the instance is reachable off-loopback (binds 0.0.0.0). */
|
|
30
|
+
reachable: boolean;
|
|
31
|
+
/** Human hint when not reachable (restart / tunnel guidance). */
|
|
32
|
+
hint?: string;
|
|
33
|
+
}
|
|
34
|
+
/** The inject face delivered to the wall view registration. */
|
|
35
|
+
export interface WallInjected {
|
|
36
|
+
/** Discover live DSH instances (same-origin /multi/api/ports). */
|
|
37
|
+
discover: () => Promise<number[]>;
|
|
38
|
+
/** Probe liveness of specific ports (same-origin /multi/api/status). */
|
|
39
|
+
probe: (ports: number[]) => Promise<ProbeRow[]>;
|
|
40
|
+
/** Terminate the DSH instance on one port (same-origin /multi/api/stop). */
|
|
41
|
+
stop: (port: number) => Promise<StopRow>;
|
|
42
|
+
/** Start a new DSH instance and return its port (same-origin /multi/api/create). */
|
|
43
|
+
create: () => Promise<CreateRow>;
|
|
44
|
+
/** The phone-reachable link for this instance (same-origin /multi/api/link). */
|
|
45
|
+
link: () => Promise<LinkRow>;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Build the probe face bound to this origin's /multi/api routes.
|
|
49
|
+
* @param mount - the API base path ('' at the root, '/multi' when mounted).
|
|
50
|
+
* @returns the injected callbacks.
|
|
51
|
+
*/
|
|
52
|
+
export declare function createWallInjected(mount?: string): WallInjected;
|
|
53
|
+
//# sourceMappingURL=wall-injected.d.ts.map
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Multi-window wall plugin, node half: registers the `/multi/api/*` routes
|
|
3
|
+
* on the webserver. The browser half fetches these same-origin to discover
|
|
4
|
+
* which local ports are live DSH instances, to poll liveness, and to
|
|
5
|
+
* terminate a chosen instance (`/multi/api/stop`). The wall itself is pure
|
|
6
|
+
* UI — this half answers a few small JSON requests.
|
|
7
|
+
* @module @deepseek-ai/dsh-client-ui-multi-wall
|
|
8
|
+
*/
|
|
9
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
10
|
+
import z from '@deepseek-ai/schemastery';
|
|
11
|
+
/** Stable Cordis plugin name. */
|
|
12
|
+
export declare const name = "client-ui-multi-wall";
|
|
13
|
+
/** Services required before the probe routes can be registered. */
|
|
14
|
+
export declare const inject: string[];
|
|
15
|
+
/** Plugin config: the wall's auto-discovery scan range. */
|
|
16
|
+
export interface MultiWallConfig {
|
|
17
|
+
/** First port of the auto-discovery range. */
|
|
18
|
+
scanFrom?: number;
|
|
19
|
+
/** Last port of the auto-discovery range. */
|
|
20
|
+
scanTo?: number;
|
|
21
|
+
/** Optional fixed port list; when set, discovery ignores the scan range. */
|
|
22
|
+
ports?: number[];
|
|
23
|
+
/**
|
|
24
|
+
* External base URL reported by `/multi/api/link` (e.g. the authenticated
|
|
25
|
+
* gateway in front of this loopback instance). When set, the link route
|
|
26
|
+
* answers `{ lan: [publicUrl + '/'], reachable: true }`.
|
|
27
|
+
*/
|
|
28
|
+
publicUrl?: string;
|
|
29
|
+
}
|
|
30
|
+
/** Schema-validated config (the Loader resolves defaults for absent keys). */
|
|
31
|
+
export declare const Config: z<Schemastery.ObjectS<{
|
|
32
|
+
scanFrom: z<number, number>;
|
|
33
|
+
scanTo: z<number, number>;
|
|
34
|
+
ports: z<number[], number[]>;
|
|
35
|
+
publicUrl: z<string, string>;
|
|
36
|
+
}>, Schemastery.ObjectT<{
|
|
37
|
+
scanFrom: z<number, number>;
|
|
38
|
+
scanTo: z<number, number>;
|
|
39
|
+
ports: z<number[], number[]>;
|
|
40
|
+
publicUrl: z<string, string>;
|
|
41
|
+
}>>;
|
|
42
|
+
/** One stop result row from /multi/api/stop. */
|
|
43
|
+
export interface StopRow {
|
|
44
|
+
port: number;
|
|
45
|
+
ok: boolean;
|
|
46
|
+
/** Human-readable failure reason (absent on success). */
|
|
47
|
+
error?: string;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Terminate the DSH instance listening on one local port. The port serving
|
|
51
|
+
* this wall may also be terminated (the user may want to stop the instance
|
|
52
|
+
* they are viewing): the kill is deferred a beat so the HTTP response is
|
|
53
|
+
* written before the process dies, then the listener's PIDs are force-killed.
|
|
54
|
+
* @param port - the target port.
|
|
55
|
+
* @param selfPort - this instance's own listening port.
|
|
56
|
+
* @returns the stop result.
|
|
57
|
+
*/
|
|
58
|
+
export declare function stopPort(port: number, selfPort: number): Promise<StopRow>;
|
|
59
|
+
/**
|
|
60
|
+
* Register the probe routes. Everything lives under `/multi/api` so the
|
|
61
|
+
* plugin is purely additive: exact `ports` (auto-discovery) and `status`
|
|
62
|
+
* (liveness of a specific port list).
|
|
63
|
+
* @param ctx - plugin context carrying the webServer service.
|
|
64
|
+
* @param config - validated {@link MultiWallConfig}.
|
|
65
|
+
*/
|
|
66
|
+
export declare function apply(ctx: Context, config?: MultiWallConfig): void;
|
|
67
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Package-owned invariant companion for
|
|
3
|
+
* `@deepseek-ai/dsh-client-ui-multi-wall`.
|
|
4
|
+
* @module @deepseek-ai/dsh-client-ui-multi-wall/invariant
|
|
5
|
+
*/
|
|
6
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
7
|
+
/** Cordis companion plugin name. */
|
|
8
|
+
export declare const name = "client-ui-multi-wall-invariant";
|
|
9
|
+
/** Service required before the companion can reserve package ownership. */
|
|
10
|
+
export declare const inject: string[];
|
|
11
|
+
/**
|
|
12
|
+
* Register this package's invariant companion.
|
|
13
|
+
* @param ctx - Cordis context carrying the invariant service.
|
|
14
|
+
* @returns the installed registration's disposer after setup succeeds.
|
|
15
|
+
*/
|
|
16
|
+
export declare const apply: (ctx: Context) => Promise<() => void>;
|
|
17
|
+
//# sourceMappingURL=invariant.d.ts.map
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@deepseek-ai/dsh-client-ui-multi-wall",
|
|
3
|
+
"description": "Multi-window wall surface: a sidebar footer action that opens a full-screen wall of every running DSH instance (one pane per port), inside the official web GUI. Additive slots only 鈥?no existing row or interaction logic is changed.",
|
|
4
|
+
"version": "0.2.0",
|
|
5
|
+
"publishConfig": {
|
|
6
|
+
"access": "public"
|
|
7
|
+
},
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/deepseek-ai/deepseek-harness.git",
|
|
11
|
+
"directory": "packages/client/ui-multi-wall"
|
|
12
|
+
},
|
|
13
|
+
"type": "module",
|
|
14
|
+
"main": "lib/index.js",
|
|
15
|
+
"types": "lib/types/index.d.ts",
|
|
16
|
+
"exports": {
|
|
17
|
+
".": {
|
|
18
|
+
"types": "./lib/types/index.d.ts",
|
|
19
|
+
"default": "./lib/index.js"
|
|
20
|
+
},
|
|
21
|
+
"./invariant": {
|
|
22
|
+
"types": "./lib/types/invariant.d.ts",
|
|
23
|
+
"default": "./lib/invariant.js"
|
|
24
|
+
},
|
|
25
|
+
"./client": {
|
|
26
|
+
"types": "./lib/types/client/index.d.ts",
|
|
27
|
+
"default": "./lib/client.js"
|
|
28
|
+
},
|
|
29
|
+
"./src/*": "./src/*",
|
|
30
|
+
"./package.json": "./package.json"
|
|
31
|
+
},
|
|
32
|
+
"dsh": {
|
|
33
|
+
"client": {
|
|
34
|
+
"inject": [
|
|
35
|
+
"@deepseek-ai/dsh-client-runtime",
|
|
36
|
+
"@deepseek-ai/dsh-client-locale",
|
|
37
|
+
"@deepseek-ai/dsh-client-ui-layout",
|
|
38
|
+
"@deepseek-ai/dsh-client-ui-sidebar",
|
|
39
|
+
"@deepseek-ai/dsh-client-ui-primitives"
|
|
40
|
+
],
|
|
41
|
+
"platform": "web"
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
"scripts": {
|
|
45
|
+
"bundle": "tsdown",
|
|
46
|
+
"watch": "tsdown --watch"
|
|
47
|
+
},
|
|
48
|
+
"license": "MIT",
|
|
49
|
+
"peerDependencies": {
|
|
50
|
+
"@deepseek-ai/dsh-client-locale": "workspace:^",
|
|
51
|
+
"@deepseek-ai/dsh-client-runtime": "workspace:^",
|
|
52
|
+
"@deepseek-ai/dsh-client-ui-layout": "workspace:^",
|
|
53
|
+
"@deepseek-ai/dsh-client-ui-primitives": "workspace:^",
|
|
54
|
+
"@deepseek-ai/dsh-client-ui-sidebar": "workspace:^",
|
|
55
|
+
"@deepseek-ai/dsh-client-ui-slots": "workspace:^",
|
|
56
|
+
"@deepseek-ai/dsh-client-ui-conversation": "workspace:^",
|
|
57
|
+
"@deepseek-ai/dsh-invariants": "workspace:^",
|
|
58
|
+
"@deepseek-ai/cordis": "workspace:^",
|
|
59
|
+
"@deepseek-ai/schemastery": "workspace:^",
|
|
60
|
+
"react": "^18.2.0"
|
|
61
|
+
},
|
|
62
|
+
"devDependencies": {
|
|
63
|
+
"@deepseek-ai/dsh-client-locale": "workspace:^",
|
|
64
|
+
"@deepseek-ai/dsh-client-runtime": "workspace:^",
|
|
65
|
+
"@deepseek-ai/dsh-client-test-runtime": "workspace:^",
|
|
66
|
+
"@deepseek-ai/dsh-client-ui-layout": "workspace:^",
|
|
67
|
+
"@deepseek-ai/dsh-client-ui-primitives": "workspace:^",
|
|
68
|
+
"@deepseek-ai/dsh-client-ui-sidebar": "workspace:^",
|
|
69
|
+
"@deepseek-ai/dsh-client-ui-slots": "workspace:^",
|
|
70
|
+
"@deepseek-ai/dsh-client-ui-conversation": "workspace:^",
|
|
71
|
+
"@deepseek-ai/dsh-invariants": "workspace:^",
|
|
72
|
+
"@testing-library/react": "^16.1.0",
|
|
73
|
+
"@types/react": "~18.3.1",
|
|
74
|
+
"@deepseek-ai/cordis": "workspace:^",
|
|
75
|
+
"react": "^18.2.0",
|
|
76
|
+
"react-dom": "^18.2.0"
|
|
77
|
+
},
|
|
78
|
+
"files": [
|
|
79
|
+
"lib/index.js",
|
|
80
|
+
"lib/invariant.js",
|
|
81
|
+
"lib/client.js",
|
|
82
|
+
"lib/types/**/*.d.ts"
|
|
83
|
+
]
|
|
84
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
' gateway-hidden.vbs — launch the authenticated gateway with NO console window.
|
|
2
|
+
' Uses WScript.Shell.Run(..., 0, false) so no conhost window ever flashes.
|
|
3
|
+
'
|
|
4
|
+
' Usage:
|
|
5
|
+
' wscript.exe "D:\2026AppDev\dsh-plugins-multi-task\scripts\gateway-hidden.vbs"
|
|
6
|
+
'
|
|
7
|
+
' Or, to run with custom values, edit the constants below.
|
|
8
|
+
' The node process is detached (second Run arg = false), so it outlives this
|
|
9
|
+
' script. The hidden-window flag (0) keeps it fully invisible.
|
|
10
|
+
|
|
11
|
+
Option Explicit
|
|
12
|
+
|
|
13
|
+
' ---- config ----
|
|
14
|
+
Dim port, target, token, name
|
|
15
|
+
port = 8443
|
|
16
|
+
target = "127.0.0.1:3070"
|
|
17
|
+
token = "dsh2026"
|
|
18
|
+
name = "DSH"
|
|
19
|
+
' ----------------
|
|
20
|
+
|
|
21
|
+
Dim fso, shell, scriptAbs
|
|
22
|
+
Set fso = CreateObject("Scripting.FileSystemObject")
|
|
23
|
+
Set shell = CreateObject("WScript.Shell")
|
|
24
|
+
|
|
25
|
+
' Absolute path to gateway.mjs, resolved relative to THIS script file.
|
|
26
|
+
scriptAbs = fso.GetParentFolderName(WScript.ScriptFullName) & "\gateway.mjs"
|
|
27
|
+
|
|
28
|
+
' Quote the path defensively (spaces etc.).
|
|
29
|
+
scriptAbs = """" & scriptAbs & """"
|
|
30
|
+
|
|
31
|
+
Dim cmd
|
|
32
|
+
cmd = "node " & scriptAbs & " --target " & target & " --listen 0.0.0.0:" & CStr(port) & " --token " & token & " --name " & name
|
|
33
|
+
|
|
34
|
+
' 0 = hidden window, false = don't wait for it to finish.
|
|
35
|
+
shell.Run cmd, 0, false
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# gateway-start.ps1 — start the authenticated gateway with no console window.
|
|
2
|
+
# Wrapper around gateway-hidden.vbs (WScript.Shell window style 0 = invisible).
|
|
3
|
+
#
|
|
4
|
+
# Usage:
|
|
5
|
+
# .\scripts\gateway-start.ps1
|
|
6
|
+
#
|
|
7
|
+
# Values come from gateway-hidden.vbs (port 8443 -> 127.0.0.1:3070,
|
|
8
|
+
# token dsh2026). Edit that file to change them.
|
|
9
|
+
|
|
10
|
+
$ErrorActionPreference = 'Stop'
|
|
11
|
+
$root = Split-Path -Parent $PSScriptRoot
|
|
12
|
+
$vbs = Join-Path $root 'scripts\gateway-hidden.vbs'
|
|
13
|
+
|
|
14
|
+
if (-not (Test-Path $vbs)) { throw "未找到启动器:$vbs" }
|
|
15
|
+
|
|
16
|
+
# wscript runs the VBS with a hidden window (no console flash).
|
|
17
|
+
Start-Process -FilePath 'wscript.exe' -ArgumentList ('"' + $vbs + '"') -WindowStyle Hidden | Out-Null
|
|
18
|
+
|
|
19
|
+
Write-Host "网关已在后台静默启动(无窗口)。"
|
|
20
|
+
Write-Host "手机访问:http://<局域网IP>:8443 (口令 dsh2026)"
|
|
21
|
+
Write-Host "停止:.\scripts\gateway-stop.ps1"
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# gateway-stop.ps1 — stop the authenticated gateway (finds the node process
|
|
2
|
+
# listening on the gateway port and terminates it).
|
|
3
|
+
#
|
|
4
|
+
# Usage:
|
|
5
|
+
# .\scripts\gateway-stop.ps1 # default port 8443
|
|
6
|
+
# .\scripts\gateway-stop.ps1 -Port 8443
|
|
7
|
+
|
|
8
|
+
param(
|
|
9
|
+
[int]$Port = 8443
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
$ErrorActionPreference = 'Stop'
|
|
13
|
+
|
|
14
|
+
$conns = Get-NetTCPConnection -LocalPort $Port -State Listen -ErrorAction SilentlyContinue
|
|
15
|
+
if (-not $conns) {
|
|
16
|
+
Write-Host "端口 $Port 上没有正在监听的网关进程。"
|
|
17
|
+
exit 0
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
$pids = $conns | Select-Object -ExpandProperty OwningProcess -Unique
|
|
21
|
+
foreach ($pid in $pids) {
|
|
22
|
+
$proc = Get-Process -Id $pid -ErrorAction SilentlyContinue
|
|
23
|
+
if ($proc) {
|
|
24
|
+
Stop-Process -Id $pid -Force
|
|
25
|
+
Write-Host "已停止网关进程 (PID $pid, $($proc.ProcessName))。"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
Start-Sleep -Milliseconds 300
|
|
30
|
+
if (Get-NetTCPConnection -LocalPort $Port -State Listen -ErrorAction SilentlyContinue) {
|
|
31
|
+
Write-Warning "端口 $Port 仍有监听,可能未完全停止。"
|
|
32
|
+
} else {
|
|
33
|
+
Write-Host "端口 $Port 已释放。"
|
|
34
|
+
}
|