@dsh-plugin/dsh-loader 1.1.0-dev.32287576957 → 1.2.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.
Files changed (62) hide show
  1. package/dist/adapters/dsh-1-x.js +4 -0
  2. package/dist/adapters/dsh-1-x.js.map +1 -1
  3. package/dist/api.d.ts +2 -0
  4. package/dist/api.js +18 -2
  5. package/dist/api.js.map +1 -1
  6. package/dist/client.d.ts +0 -1
  7. package/dist/client.js +13 -3
  8. package/dist/client.js.map +1 -1
  9. package/dist/index.js +7 -1
  10. package/dist/index.js.map +1 -1
  11. package/dist/patch.d.ts +112 -0
  12. package/dist/patch.js +179 -0
  13. package/dist/patch.js.map +1 -0
  14. package/dist/services/dsh-symbols.d.ts +70 -0
  15. package/dist/services/dsh-symbols.js +82 -0
  16. package/dist/services/dsh-symbols.js.map +1 -0
  17. package/dist/services/llm.d.ts +30 -0
  18. package/dist/services/llm.js +35 -0
  19. package/dist/services/llm.js.map +1 -0
  20. package/dist/services/registry.d.ts +144 -0
  21. package/dist/services/registry.js +209 -0
  22. package/dist/services/registry.js.map +1 -0
  23. package/dist/services/settings.d.ts +6 -0
  24. package/dist/services/settings.js +29 -1
  25. package/dist/services/settings.js.map +1 -1
  26. package/dist/services/web.js +20 -4
  27. package/dist/services/web.js.map +1 -1
  28. package/dist/setup.js +17 -1
  29. package/dist/setup.js.map +1 -1
  30. package/dist/types.d.ts +55 -0
  31. package/dist/version.d.ts +1 -1
  32. package/dist/version.js +1 -1
  33. package/lib/client.js +2775 -4
  34. package/lib/client.js.map +1 -1
  35. package/lib/types/adapters/dsh-1-x.d.ts +23 -0
  36. package/lib/types/adapters/index.d.ts +22 -0
  37. package/lib/types/client-ui.d.ts +40 -0
  38. package/lib/types/client.d.ts +156 -0
  39. package/lib/types/patch.d.ts +112 -0
  40. package/lib/types/registry.d.ts +35 -0
  41. package/lib/types/services/dsh-symbols.d.ts +70 -0
  42. package/lib/types/services/llm.d.ts +30 -0
  43. package/lib/types/services/registry.d.ts +144 -0
  44. package/lib/types/services/settings.d.ts +47 -0
  45. package/lib/types/types.d.ts +166 -0
  46. package/lib/types/ui/anchors.d.ts +56 -0
  47. package/lib/types/ui/components.d.ts +159 -0
  48. package/lib/types/ui/icons.d.ts +142 -0
  49. package/lib/types/ui/index.d.ts +30 -0
  50. package/lib/types/ui/menu.d.ts +104 -0
  51. package/lib/types/ui/slots.d.ts +152 -0
  52. package/lib/types/ui/style.d.ts +97 -0
  53. package/lib/types/version.d.ts +2 -0
  54. package/package.json +42 -9
  55. package/src/stable/compaction-basic.d.ts +1 -0
  56. package/src/stable/compaction-basic.js +5 -0
  57. package/src/stable/credentials.d.ts +1 -0
  58. package/src/stable/credentials.js +5 -0
  59. package/src/stable/subagent.d.ts +1 -0
  60. package/src/stable/subagent.js +5 -0
  61. package/src/stable/timeout.d.ts +1 -0
  62. package/src/stable/timeout.js +5 -0
@@ -0,0 +1,104 @@
1
+ /**
2
+ * The wrapped platform MENU (`DshMenu`).
3
+ *
4
+ * Consumers import this from `@dsh-plugin/dsh-loader/client` instead of
5
+ * importing `@deepseek-ai/dsh-client-ui-primitives` directly. The wrapper exists
6
+ * so that changes to the platform primitive — a renamed export, a moved package,
7
+ * an altered prop shape — are absorbed HERE, in one line's distance, instead of
8
+ * breaking every plugin that renders a dropdown.
9
+ *
10
+ * Two deliberate properties:
11
+ *
12
+ * 1. TYPES ARE HAND-WRITTEN, not re-exported. A shipped `.d.ts` that says
13
+ * `export { Menu } from '@deepseek-ai/...'` resolves from dshloader's own
14
+ * install — which consumers do not have (see docs/ui-kit.md, 铁律三) — so
15
+ * re-exported types break consumer typecheck the moment dshloader is
16
+ * published without devDependencies. These interfaces are written out and
17
+ * must be kept in sync with upstream BY HAND when a prop the plugins use
18
+ * changes; that maintenance cost is the price of consumer-side purity.
19
+ * 2. THE PLATFORM IMPORT IS STATIC AND SINGULAR. This file is the only place in
20
+ * dshloader that names the primitives package for menus. If it disappears or
21
+ * renames, the fix is contained here. The static import means dshloader's
22
+ * client bundle hard-depends on the primitive seed module — the same failure
23
+ * mode the direct imports had, so no regression — which is also why the
24
+ * missing-module degradation path is NOT attempted: with ESM compiled into
25
+ * the CJS closure factory there is no clean way to defer the require, and a
26
+ * half-working menu would be worse than an honest load error.
27
+ *
28
+ * @module @dsh-plugin/dsh-loader/ui/menu
29
+ */
30
+ import * as React from 'react';
31
+ /** One selectable row (optionally with a nested submenu). */
32
+ export interface MenuItem {
33
+ id: string;
34
+ label: React.ReactNode;
35
+ disabled?: boolean;
36
+ /** Leading icon. */
37
+ icon?: React.ReactNode;
38
+ /** Destructive row: error-coloured text/icon and danger hover fill. */
39
+ danger?: boolean;
40
+ /** Nested card opened to the right on hover/focus. */
41
+ submenu?: readonly MenuItem[];
42
+ }
43
+ /** Hairline between item groups (not selectable). */
44
+ export interface MenuSeparator {
45
+ type: 'separator';
46
+ id: string;
47
+ }
48
+ /** Non-interactive heading row above a group of items. */
49
+ export interface MenuLabel {
50
+ type: 'label';
51
+ id: string;
52
+ text: string;
53
+ }
54
+ /** One primary-menu entry: a row, a separator, or a heading label. */
55
+ export type MenuEntry = MenuItem | MenuSeparator | MenuLabel;
56
+ /** {@link DshMenu} props — structurally the platform Menu's contract. */
57
+ export interface DshMenuProps {
58
+ /** Whether the list is showing (owner-controlled). */
59
+ open: boolean;
60
+ /** The trigger element (rendered in place). */
61
+ anchor: React.ReactNode;
62
+ /** Selectable rows and optional separators/labels. */
63
+ items: readonly MenuEntry[];
64
+ /** Rows pinned below the scrolling items area. */
65
+ footer?: readonly MenuEntry[];
66
+ /** Row shown as selected. */
67
+ selectedId?: string | undefined;
68
+ /** Rows shown as selected with independent option groups. */
69
+ selectedIds?: readonly string[] | undefined;
70
+ /** Row click callback (not called for disabled rows). */
71
+ onSelect: (id: string) => void;
72
+ /** Invoked on outside click or Escape. */
73
+ onClose: () => void;
74
+ /** List alignment against the anchor (default `'start'`). */
75
+ align?: 'start' | 'end';
76
+ /** Open below (`'bottom'`, default), above, or to the right of the anchor. */
77
+ side?: 'bottom' | 'top' | 'right';
78
+ /**
79
+ * Render the list into `document.body`, fixed-positioned from the anchor rect.
80
+ * Use when an ancestor's overflow clipping would crop the in-place list.
81
+ */
82
+ portal?: boolean;
83
+ /**
84
+ * Close once the pointer has left both trigger and list for the grace period
85
+ * (default `false` keeps it open until outside click/Escape/selection).
86
+ */
87
+ closeOnPointerLeave?: boolean;
88
+ /** Reduce vertical row spacing only. */
89
+ dense?: boolean;
90
+ /** Reduced typography and spacing overall. */
91
+ compact?: boolean;
92
+ /** Portal mode only: supply the anchor rect directly. */
93
+ getAnchorRect?: () => DOMRect | null;
94
+ /** Extra class on the anchor wrapper. */
95
+ className?: string;
96
+ }
97
+ /**
98
+ * The stable menu surface for dshloader consumers.
99
+ *
100
+ * Forwards every prop verbatim to the platform primitive — this wrapper's job
101
+ * is ISOLATION (one import site, hand-owned types), not behaviour change. When
102
+ * the platform evolves, adaptation code goes here and consumers stay put.
103
+ */
104
+ export declare function DshMenu(props: DshMenuProps): React.ReactElement | null;
@@ -0,0 +1,152 @@
1
+ /**
2
+ * The dshloader UI SLOT engine (`ctx.dshLoader.ui` / `__dshLoader__.ui`).
3
+ *
4
+ * dsh's Web shell offers official slots for a few places (`settings.section`,
5
+ * `conversation.chat.node`, …) but not for everything plugins need to decorate.
6
+ * Today four plugins in this family each hand-roll the same DOM-injection
7
+ * boilerplate against hardcoded shell selectors:
8
+ *
9
+ * - dsh-thought-buddy → `[data-conversation-scroll] [role="status"]`
10
+ * - dsh-auxiliary → the Models page's editable model rows
11
+ * - dsh-code-review → `[data-shell-overlay]`, `.dshDesktopDetailsSurface`
12
+ * - dsh-better-sidebar → `#root [data-slot="conversation"]`, theme root, …
13
+ *
14
+ * Every one of them re-implements: a MutationObserver, requestAnimationFrame
15
+ * coalescing, an idempotence guard, self-healing after a React re-render, and
16
+ * teardown. This module implements that ONCE and moves the shell selectors into
17
+ * a named ANCHOR TABLE the version adapter owns — so when dsh moves its DOM,
18
+ * one anchor entry changes instead of four plugins.
19
+ *
20
+ * What it cannot do: invent an anchor that no longer exists. A vanished anchor
21
+ * turns N silent breakages into ONE diagnosable one (`ui.diagnose()`), which is
22
+ * the honest goal — DOM injection is centralised here, not made robust. The
23
+ * durable fix stays "get the anchor promoted to an official slot".
24
+ *
25
+ * @module @dsh-plugin/dsh-loader/ui/slots
26
+ */
27
+ import * as React from 'react';
28
+ /** Where a mount node is placed relative to its host element. */
29
+ export type InsertMode = 'prepend' | 'append' | 'before' | 'after';
30
+ /** How the active adapter locates one shell anchor. */
31
+ export interface AnchorSpec {
32
+ /** Human-readable description, used by {@link UiAPI.diagnose}. */
33
+ describe: string;
34
+ /** Primary locator. Return every element that should host a mount. */
35
+ find: () => Iterable<Element>;
36
+ /**
37
+ * Fallback locator, tried only when `find` yields nothing. Lets an anchor
38
+ * survive a narrow selector going stale (the pattern thought-buddy uses:
39
+ * scoped selector first, whole-document second).
40
+ */
41
+ fallback?: () => Iterable<Element>;
42
+ /** Extra predicate a candidate must satisfy (e.g. matching text content). */
43
+ accept?: (host: Element) => boolean;
44
+ /** Placement of the mount node. Defaults to `'append'`. */
45
+ insert?: InsertMode;
46
+ /** Tag name for the generated mount node. Defaults to `'span'`. */
47
+ tagName?: string;
48
+ }
49
+ /** One plugin-supplied mount against an anchor. */
50
+ export interface MountSpec {
51
+ /**
52
+ * Unique mount id, `'<plugin>:<what>'`. Doubles as the `data-dshl-slot`
53
+ * attribute value that makes mounting idempotent.
54
+ */
55
+ id: string;
56
+ /**
57
+ * Populate the mount node. Called once per host; return a cleanup that
58
+ * releases whatever was created.
59
+ */
60
+ render: (mount: HTMLElement, host: Element) => (() => void) | void;
61
+ /** Skip this host when the predicate returns false. */
62
+ when?: (host: Element) => boolean;
63
+ }
64
+ /** A React flavour of {@link MountSpec}. */
65
+ export interface ReactMountSpec {
66
+ /** Unique mount id, `'<plugin>:<what>'`. */
67
+ id: string;
68
+ /** Component rendered into the mount node; receives the host element. */
69
+ component: React.ComponentType<{
70
+ host: Element;
71
+ }>;
72
+ /** Skip this host when the predicate returns false. */
73
+ when?: (host: Element) => boolean;
74
+ }
75
+ /** Diagnostics for one registered anchor. */
76
+ export interface AnchorDiagnostic {
77
+ anchor: string;
78
+ describe: string;
79
+ /** Hosts the primary locator currently finds. */
80
+ hosts: number;
81
+ /** Whether the fallback locator had to be used. */
82
+ usedFallback: boolean;
83
+ /** Mount ids currently registered against this anchor. */
84
+ mounts: string[];
85
+ /** Live mount instances across all hosts. */
86
+ live: number;
87
+ }
88
+ /** The `ui` facade. */
89
+ export interface UiAPI {
90
+ /**
91
+ * Register (or replace) an anchor. The adapter seeds the built-ins at boot;
92
+ * a plugin may add its own for shell areas dshloader does not know yet.
93
+ * @returns a disposer removing the anchor and unmounting everything on it.
94
+ */
95
+ defineAnchor(name: string, spec: AnchorSpec): () => void;
96
+ /** Anchor names currently registered. */
97
+ anchors(): string[];
98
+ /**
99
+ * The elements an anchor currently resolves to. Use this for anchors that are
100
+ * READ rather than decorated — e.g. reading the layout frame's collapsed
101
+ * attribute or grid width instead of mounting into it.
102
+ */
103
+ hosts(anchor: string): Element[];
104
+ /**
105
+ * Subscribe to "the shell's DOM has settled": called once per coalesced
106
+ * mutation batch, on the same observer and the same rAF frame the mount sweep
107
+ * uses.
108
+ *
109
+ * This exists for injections whose HOST IDENTIFICATION is itself business
110
+ * logic and therefore does not fit the anchor model — dsh-auxiliary's model
111
+ * catalog is the motivating case: it cross-references `aria-label` inputs
112
+ * against a provider directory, re-reads settings on a debounce, and also
113
+ * listens for `input` events, so an `AnchorSpec.find()` could never express
114
+ * it. Such a caller keeps its own sweep but stops running a second
115
+ * MutationObserver over the whole document.
116
+ *
117
+ * The listener MUST be idempotent: it is invoked again after any batch,
118
+ * including batches its own writes caused.
119
+ *
120
+ * @returns an unsubscribe function.
121
+ */
122
+ onDomSettled(listener: () => void): () => void;
123
+ /**
124
+ * Mount imperative content on every element an anchor resolves to, now and
125
+ * whenever the shell re-renders. Idempotent per (host, mount id).
126
+ * @returns a disposer unmounting every instance of this mount.
127
+ */
128
+ mount(anchor: string, spec: MountSpec): () => void;
129
+ /**
130
+ * Mount a React component on every element an anchor resolves to. A React
131
+ * root is created per host and unmounted on teardown.
132
+ * @returns a disposer unmounting every instance of this mount.
133
+ */
134
+ mountReact(anchor: string, spec: ReactMountSpec): () => void;
135
+ /** Snapshot of anchor health — the single place to look when injection stops working. */
136
+ diagnose(): AnchorDiagnostic[];
137
+ /** Stop observing and unmount everything (called by the loader's own teardown). */
138
+ destroy(): void;
139
+ }
140
+ /** Options for {@link createUiAPI}. */
141
+ export interface CreateUiOptions {
142
+ /** Root to observe. Defaults to `document.documentElement`. */
143
+ observeRoot?: Element;
144
+ /** Diagnostic sink; defaults to `console.warn`. */
145
+ warn?: (message: string) => void;
146
+ }
147
+ /**
148
+ * Build the `ui` facade with its own observer. One engine serves every anchor
149
+ * and every mount, so the shell is observed exactly once regardless of how many
150
+ * plugins inject.
151
+ */
152
+ export declare function createUiAPI(options?: CreateUiOptions): UiAPI;
@@ -0,0 +1,97 @@
1
+ /**
2
+ * Design tokens and the idempotent stylesheet injector shared by every
3
+ * dshloader UI component.
4
+ *
5
+ * Tokens are the DSH shell's own CSS custom properties, each paired with a
6
+ * fallback so a component still renders sanely when the shell changes or the
7
+ * plugin is previewed outside it. The names were harvested from the shell
8
+ * styling the plugins in this family already rely on; when dsh renames one,
9
+ * this file is the single place to fix.
10
+ *
11
+ * @module @dsh-plugin/dsh-loader/ui/style
12
+ */
13
+ /** `var(--name, fallback)` — a token reference that degrades instead of breaking. */
14
+ export declare function token(name: string, fallback: string): string;
15
+ /** The DSH shell tokens dshloader components consume. */
16
+ export declare const T: {
17
+ /** Primary body text. */
18
+ readonly labelPrimary: string;
19
+ /** Secondary / supporting text. */
20
+ readonly labelSecondary: string;
21
+ /** Tertiary text (hints, units). */
22
+ readonly labelTertiary: string;
23
+ /** Caption / disabled text. */
24
+ readonly labelCaption: string;
25
+ /** Page / card background. */
26
+ readonly bgBase: string;
27
+ /** Raised surface inside a page (shell layer 1). */
28
+ readonly bgLayer1: string;
29
+ /** Subtle raised surface. */
30
+ readonly bgSubtle: string;
31
+ /** Hover wash for interactive rows. */
32
+ readonly bgHover: string;
33
+ /** Default control border. */
34
+ readonly border: string;
35
+ /** Lighter divider. */
36
+ readonly borderSubtle: string;
37
+ /** Primary button fill — the shell's own button colour, NOT the brand accent. */
38
+ readonly buttonPrimaryFill: string;
39
+ /** Text placed on top of {@link buttonPrimaryFill}. */
40
+ readonly buttonPrimaryForeground: string;
41
+ /** Brand accent (checked states, focus rings). */
42
+ readonly accent: string;
43
+ /** Accent text placed on top of the accent fill. */
44
+ readonly accentOn: string;
45
+ /** Destructive accent. */
46
+ readonly danger: string;
47
+ /** Success state (saved confirmations). */
48
+ readonly success: string;
49
+ /** Monospace stack for code / paths. */
50
+ readonly fontCode: string;
51
+ };
52
+ /**
53
+ * Shared control geometry so every dshloader control lines up.
54
+ *
55
+ * The values mirror the shell's native settings-page metrics (as established by
56
+ * dsh-auxiliary's section): pill-shaped primary buttons at height 32, inputs at
57
+ * height 28 with radius 6, cards with radius 10 and padding 16.
58
+ */
59
+ export declare const G: {
60
+ /** Control height for inputs / selects. */
61
+ readonly controlHeight: 28;
62
+ /** Compact control height. */
63
+ readonly controlHeightSm: 24;
64
+ /** Primary button height (the shell's buttons run taller than inputs). */
65
+ readonly buttonHeight: 32;
66
+ /** Standard corner radius (inputs). */
67
+ readonly radius: 6;
68
+ /** Card corner radius. */
69
+ readonly cardRadius: 10;
70
+ /** Pill radius (primary buttons, switches, chips). */
71
+ readonly radiusPill: 999;
72
+ /** Horizontal padding inside an input. */
73
+ readonly padX: 8;
74
+ /** Horizontal padding inside a primary button. */
75
+ readonly padXButton: 14;
76
+ /** Standard row gap. */
77
+ readonly gap: 8;
78
+ /** Base font size. */
79
+ readonly fontSize: 13;
80
+ /** Small font size (descriptions). */
81
+ readonly fontSizeSm: 12;
82
+ };
83
+ /**
84
+ * Inject a stylesheet once, tagged with the DSH client-module ownership
85
+ * attributes (`data-plugin` / `data-plugin-css`) so the HMR driver can reclaim
86
+ * it. Calling this repeatedly with the same `cssId` is a no-op.
87
+ *
88
+ * @param pluginId - owning plugin id (package name), for `data-plugin`.
89
+ * @param cssId - stylesheet id within the plugin, e.g. `'ui/components.css'`.
90
+ * @param css - the stylesheet text.
91
+ * @returns a disposer removing the tag, for callers that want one.
92
+ */
93
+ export declare function injectStyle(pluginId: string, cssId: string, css: string): () => void;
94
+ /** The class-name prefix every dshloader UI class carries. */
95
+ export declare const CX = "dshl";
96
+ /** Join truthy class names. */
97
+ export declare function cx(...parts: Array<string | false | null | undefined>): string;
@@ -0,0 +1,2 @@
1
+ export declare const LOADER_VERSION = "1.2.0";
2
+ export declare const LOG_PREFIX = "[dshloader]";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dsh-plugin/dsh-loader",
3
- "version": "1.1.0-dev.32287576957",
3
+ "version": "1.2.0",
4
4
  "description": "Runtime compatibility shim for dsh (DeepSeek Harness) cordis bundle plugins: decouples third-party plugins from real dsh internal service names, module paths, and RPC details via a version-aware adapter registry.",
5
5
  "type": "module",
6
6
  "repository": {
@@ -10,7 +10,10 @@
10
10
  "main": "dist/index.js",
11
11
  "exports": {
12
12
  ".": "./dist/index.js",
13
- "./client": "./lib/client.js",
13
+ "./client": {
14
+ "types": "./lib/types/client-ui.d.ts",
15
+ "default": "./lib/client.js"
16
+ },
14
17
  "./registry": "./dist/registry.js",
15
18
  "./cordis.patch.yml": "./cordis.patch.yml",
16
19
  "./package.json": "./package.json",
@@ -23,7 +26,12 @@
23
26
  "./tools": "./src/stable/tools.js",
24
27
  "./llm": "./src/stable/llm.js",
25
28
  "./agent": "./src/stable/agent.js",
26
- "./settings": "./src/stable/settings.js"
29
+ "./settings": "./src/stable/settings.js",
30
+ "./timeout": "./src/stable/timeout.js",
31
+ "./subagent": "./src/stable/subagent.js",
32
+ "./credentials": "./src/stable/credentials.js",
33
+ "./compaction-basic": "./src/stable/compaction-basic.js",
34
+ "./patch": "./dist/patch.js"
27
35
  },
28
36
  "bin": {
29
37
  "dshloader": "./bin/dshloader.mjs"
@@ -34,33 +42,55 @@
34
42
  "bin",
35
43
  "lib/client.js",
36
44
  "lib/client.js.map",
45
+ "lib/types",
37
46
  "cordis.patch.yml",
38
47
  "README.md",
39
48
  "LICENSE"
40
49
  ],
41
50
  "scripts": {
42
- "build": "tsc -p tsconfig.build.json && tsdown --config tsdown.client.config.mjs",
51
+ "build": "tsc -p tsconfig.build.json && tsc -p tsconfig.client.types.json && tsdown --config tsdown.client.config.mjs",
43
52
  "build:host": "tsc -p tsconfig.build.json",
44
- "build:client": "tsdown --config tsdown.client.config.mjs",
45
- "typecheck": "tsc --noEmit",
53
+ "build:client": "tsc -p tsconfig.client.types.json && tsdown --config tsdown.client.config.mjs",
54
+ "typecheck": "tsc --noEmit && tsc -p tsconfig.client.json --noEmit",
46
55
  "pretest": "npm run build:host",
47
- "test": "node --test \"tests/**/*.test.mjs\"",
56
+ "test": "node --test \"tests/**/*.test.mjs\" && vitest run",
48
57
  "test:l1": "node --test \"tests/*.test.mjs\"",
49
58
  "test:l2": "node --test \"tests/module/*.test.mjs\"",
50
59
  "test:l3": "node --test \"tests/integration/*.test.mjs\"",
60
+ "test:ui": "vitest run",
51
61
  "setup": "node bin/dshloader.mjs setup"
52
62
  },
53
63
  "engines": {
54
64
  "node": ">=18"
55
65
  },
56
66
  "dependencies": {
67
+ "@icon-park/react": "^1.4.2",
57
68
  "semver": "^7.8.5"
58
69
  },
70
+ "peerDependencies": {
71
+ "react": ">=18",
72
+ "react-dom": ">=18"
73
+ },
74
+ "peerDependenciesMeta": {
75
+ "react": {
76
+ "optional": true
77
+ },
78
+ "react-dom": {
79
+ "optional": true
80
+ }
81
+ },
59
82
  "devDependencies": {
83
+ "@deepseek-ai/dsh-client-ui-primitives": "^0.1.0-rc.6",
60
84
  "@types/node": "^26.2.0",
85
+ "@types/react": "^18.3.31",
86
+ "@types/react-dom": "^18.3.7",
61
87
  "@types/semver": "^7.8.0",
88
+ "jsdom": "^25.0.0",
89
+ "react": "^18.3.1",
90
+ "react-dom": "^18.3.1",
62
91
  "tsdown": "^0.22.2",
63
- "typescript": "^7.0.2"
92
+ "typescript": "^7.0.2",
93
+ "vitest": "^2.1.0"
64
94
  },
65
95
  "dsh": {
66
96
  "bundle": {
@@ -68,7 +98,10 @@
68
98
  },
69
99
  "client": {
70
100
  "platform": "web",
71
- "immediately": true
101
+ "immediately": true,
102
+ "inject": [
103
+ "@deepseek-ai/dsh-client-ui-primitives"
104
+ ]
72
105
  }
73
106
  },
74
107
  "license": "LGPL-3.0-only"
@@ -0,0 +1 @@
1
+ export * from '@deepseek-ai/dsh-compaction-basic';
@@ -0,0 +1,5 @@
1
+ // Stable re-export: @dsh-plugin/dsh-loader/compaction-basic
2
+ //
3
+ // The BasicCompactionEngine base class plugins subclass.
4
+ // When dsh renames the package, only this file changes.
5
+ export * from '@deepseek-ai/dsh-compaction-basic';
@@ -0,0 +1 @@
1
+ export * from '@deepseek-ai/dsh-credentials';
@@ -0,0 +1,5 @@
1
+ // Stable re-export: @dsh-plugin/dsh-loader/credentials
2
+ //
3
+ // Credential references (credentialRef).
4
+ // When dsh renames the package, only this file changes.
5
+ export * from '@deepseek-ai/dsh-credentials';
@@ -0,0 +1 @@
1
+ export * from '@deepseek-ai/dsh-subagent';
@@ -0,0 +1,5 @@
1
+ // Stable re-export: @dsh-plugin/dsh-loader/subagent
2
+ //
3
+ // Subagent helpers (delegationDepthOf).
4
+ // When dsh renames the package, only this file changes.
5
+ export * from '@deepseek-ai/dsh-subagent';
@@ -0,0 +1 @@
1
+ export * from '@deepseek-ai/dsh-timeout';
@@ -0,0 +1,5 @@
1
+ // Stable re-export: @dsh-plugin/dsh-loader/timeout
2
+ //
3
+ // Timer / deadline helpers (MAX_TIMER_DELAY_MS, deadline).
4
+ // When dsh renames the package, only this file changes.
5
+ export * from '@deepseek-ai/dsh-timeout';