@huanlin/dsh-plugin-better-plan 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.
@@ -0,0 +1,58 @@
1
+ /**
2
+ * The `/better-plan/ws/delivery` push WebSocket: the host→browser channel
3
+ * for the sidebar's Plan tab (query `session=<sessionId>` attaches one view).
4
+ *
5
+ * The socket exists because the host half has no `betterSidebar` service —
6
+ * host→client pushes must ride a route the plugin owns. Two tagged JSON
7
+ * frames flow server→view:
8
+ * `{ kind: 'deliver', id, path, title }` — one plan delivery;
9
+ * `{ kind: 'review', review: ReviewState|null }` — the review state
10
+ * (replayed on attach, pushed on every change).
11
+ *
12
+ * @module @huanlin/dsh-plugin-better-plan/ws-route
13
+ */
14
+ import type { PlanDeliveryRegistry } from './delivery-registry.ts';
15
+ import type { LocaleDirectory } from './locale.ts';
16
+ import type { PlanReviewGate } from './review-gate.ts';
17
+ import { type FenceRequest } from './trust-fence.ts';
18
+ /** The exact upgrade path registered on the host webServer. */
19
+ export declare const DELIVERY_WS_PATH = "/better-plan/ws/delivery";
20
+ /** The upgrade request face the route handler receives (headers + url). */
21
+ export interface DeliveryUpgradeRequest extends FenceRequest {
22
+ url?: string;
23
+ }
24
+ /** The upgrade socket face the attach helper needs (the subset of `ws`'s WebSocket). */
25
+ export interface DeliverySocket {
26
+ send(data: string): void;
27
+ close(code?: number, reason?: string): void;
28
+ on(event: 'close' | 'error', listener: () => void): unknown;
29
+ }
30
+ /**
31
+ * Wire one delivery socket to the registries: parse `?session=` (and the
32
+ * view-reported `?locale=`, recorded so the host's user-facing copy follows
33
+ * the browser's active DSH locale), attach the delivery queue (replaying
34
+ * queued pushes) and the review gate (replaying the latest review state),
35
+ * and detach on close/error so later pushes queue instead of accumulating
36
+ * on a dead socket.
37
+ * @param registry - the delivery registry.
38
+ * @param gate - the review gate.
39
+ * @param ws - the connected socket.
40
+ * @param req - the upgrade request.
41
+ * @param directory - the locale directory the reported locale is recorded in.
42
+ */
43
+ export declare function attachDeliverySocket(registry: PlanDeliveryRegistry, gate: PlanReviewGate, ws: DeliverySocket, req: DeliveryUpgradeRequest, directory: LocaleDirectory): void;
44
+ /**
45
+ * Register the delivery upgrade route on the host webServer.
46
+ * @param registerUpgrade - the webServer's route registrar.
47
+ * @param registry - the delivery registry.
48
+ * @param gate - the review gate.
49
+ * @param trustedHosts - non-loopback authorities the deployment serves.
50
+ * @param directory - the locale directory view reports are recorded in.
51
+ * @returns the route disposer.
52
+ */
53
+ export declare function registerDeliveryRoute(registerUpgrade: (route: {
54
+ path: string;
55
+ handler: (req: DeliveryUpgradeRequest, socket: {
56
+ destroy(): void;
57
+ }, head: Uint8Array) => void | Promise<void>;
58
+ }) => () => void, registry: PlanDeliveryRegistry, gate: PlanReviewGate, trustedHosts: readonly string[], directory: LocaleDirectory): () => void;
package/package.json ADDED
@@ -0,0 +1,116 @@
1
+ {
2
+ "name": "@huanlin/dsh-plugin-better-plan",
3
+ "version": "0.4.0",
4
+ "publishConfig": {
5
+ "access": "public"
6
+ },
7
+ "keywords": [
8
+ "dsh-plugin",
9
+ "dsh-better-sidebar"
10
+ ],
11
+ "description": "取代 DSH 内置 plan mode 的计划交付体验:计划先写成 markdown 文件,经侧边栏「计划面板」展示,聊天里只剩紧凑审批卡(审批流与原版一致)。 | Replaces the built-in plan mode's plan delivery: plans are written to a markdown file first and shown in the better-sidebar plan panel, leaving only a compact review card in chat (approval flow unchanged).",
12
+ "type": "module",
13
+ "license": "AGPL-3.0",
14
+ "main": "./lib/index.js",
15
+ "types": "./lib/types/index.d.ts",
16
+ "exports": {
17
+ ".": {
18
+ "types": "./lib/types/index.d.ts",
19
+ "import": "./lib/index.js"
20
+ },
21
+ "./client": {
22
+ "types": "./lib/types/client/index.d.ts",
23
+ "default": "./lib/client.js"
24
+ },
25
+ "./package.json": "./package.json"
26
+ },
27
+ "files": [
28
+ "lib/",
29
+ "!lib/*.map",
30
+ "cordis.patch.yml"
31
+ ],
32
+ "dsh": {
33
+ "bundle": {
34
+ "patch": "./cordis.patch.yml"
35
+ },
36
+ "client": {
37
+ "inject": [],
38
+ "platform": "web"
39
+ }
40
+ },
41
+ "dependencies": {
42
+ "ws": "^8.18.0"
43
+ },
44
+ "peerDependencies": {
45
+ "@deepseek-ai/cordis": "^4.0.1",
46
+ "@deepseek-ai/dsh-agent": "^0.1.2-rc.1",
47
+ "@deepseek-ai/dsh-client-ui-primitives": "^0.1.2-rc.1",
48
+ "@deepseek-ai/dsh-llm": "^0.1.2-rc.1",
49
+ "@deepseek-ai/dsh-plan-mode": "^0.1.2-rc.1",
50
+ "@deepseek-ai/dsh-session": "^0.1.2-rc.1",
51
+ "@deepseek-ai/dsh-tools": "^0.1.2-rc.1",
52
+ "@deepseek-ai/dsh-user-questions": "^0.1.2-rc.1",
53
+ "dsh-better-sidebar": "^0.17.1",
54
+ "react": "^18.2.0",
55
+ "schemastery": "^3.18.0"
56
+ },
57
+ "peerDependenciesMeta": {
58
+ "@deepseek-ai/cordis": {
59
+ "optional": true
60
+ },
61
+ "@deepseek-ai/dsh-agent": {
62
+ "optional": true
63
+ },
64
+ "@deepseek-ai/dsh-client-ui-primitives": {
65
+ "optional": true
66
+ },
67
+ "@deepseek-ai/dsh-llm": {
68
+ "optional": true
69
+ },
70
+ "@deepseek-ai/dsh-plan-mode": {
71
+ "optional": true
72
+ },
73
+ "@deepseek-ai/dsh-session": {
74
+ "optional": true
75
+ },
76
+ "@deepseek-ai/dsh-tools": {
77
+ "optional": true
78
+ },
79
+ "@deepseek-ai/dsh-user-questions": {
80
+ "optional": true
81
+ },
82
+ "dsh-better-sidebar": {
83
+ "optional": true
84
+ },
85
+ "react": {
86
+ "optional": true
87
+ },
88
+ "schemastery": {
89
+ "optional": true
90
+ }
91
+ },
92
+ "devDependencies": {
93
+ "@testing-library/dom": "^10.4.0",
94
+ "@testing-library/react": "^16.1.0",
95
+ "@types/node": "^22.20.1",
96
+ "@types/react": "~18.3.31",
97
+ "@types/react-dom": "~18.3.1",
98
+ "@types/ws": "^8.5.10",
99
+ "jsdom": "^25.0.1",
100
+ "react": "^18.2.0",
101
+ "react-dom": "^18.2.0",
102
+ "schemastery": "^3.18.0",
103
+ "tsdown": "^0.22.2",
104
+ "typescript": "^5.9.2",
105
+ "vitest": "^3.2.7"
106
+ },
107
+ "engines": {
108
+ "node": ">=22.0.0"
109
+ },
110
+ "scripts": {
111
+ "typecheck": "tsc --noEmit -p tsconfig.json && tsc --noEmit -p tsconfig.client.json",
112
+ "test": "vitest run",
113
+ "build": "tsdown --config tsdown.config.ts && tsc -p tsconfig.build.json",
114
+ "bundle:client": "tsdown --config tsdown.config.ts"
115
+ }
116
+ }