@yadsh/dsh-qa-surface 0.1.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 (61) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/LICENSE +21 -0
  3. package/README.md +135 -0
  4. package/SPEC-dsh-qa-surface.md +1921 -0
  5. package/compatibility.json +15 -0
  6. package/cordis.patch.yml +9 -0
  7. package/docs/ARCHITECTURE.md +24 -0
  8. package/docs/COMPATIBILITY.md +13 -0
  9. package/docs/CONFIGURATION.md +18 -0
  10. package/docs/EMBEDDING.md +13 -0
  11. package/lib/client/QaConfigController.js +65 -0
  12. package/lib/client/QaConfigController.js.map +1 -0
  13. package/lib/client/QaRouteController.js +109 -0
  14. package/lib/client/QaRouteController.js.map +1 -0
  15. package/lib/client/QaSessionController.js +366 -0
  16. package/lib/client/QaSessionController.js.map +1 -0
  17. package/lib/client/QaSurface.js +109 -0
  18. package/lib/client/QaSurface.js.map +1 -0
  19. package/lib/client/QaTranscriptAdapter.js +92 -0
  20. package/lib/client/QaTranscriptAdapter.js.map +1 -0
  21. package/lib/client/components/Markdown.js +102 -0
  22. package/lib/client/components/Markdown.js.map +1 -0
  23. package/lib/client/components/QaComposer.js +33 -0
  24. package/lib/client/components/QaComposer.js.map +1 -0
  25. package/lib/client/components/QaMessage.js +14 -0
  26. package/lib/client/components/QaMessage.js.map +1 -0
  27. package/lib/client/index.js +46 -0
  28. package/lib/client/index.js.map +1 -0
  29. package/lib/client/styles.js +58 -0
  30. package/lib/client/styles.js.map +1 -0
  31. package/lib/client.js +1131 -0
  32. package/lib/client.js.map +1 -0
  33. package/lib/config.js +83 -0
  34. package/lib/config.js.map +1 -0
  35. package/lib/host-route.js +27 -0
  36. package/lib/host-route.js.map +1 -0
  37. package/lib/index.js +83 -0
  38. package/lib/index.js.map +1 -0
  39. package/lib/navigation-marker.js +3 -0
  40. package/lib/navigation-marker.js.map +1 -0
  41. package/lib/resolve-config.js +143 -0
  42. package/lib/resolve-config.js.map +1 -0
  43. package/lib/types/client/QaConfigController.d.ts +21 -0
  44. package/lib/types/client/QaRouteController.d.ts +43 -0
  45. package/lib/types/client/QaSessionController.d.ts +59 -0
  46. package/lib/types/client/QaSurface.d.ts +16 -0
  47. package/lib/types/client/QaTranscriptAdapter.d.ts +7 -0
  48. package/lib/types/client/components/Markdown.d.ts +5 -0
  49. package/lib/types/client/components/QaComposer.d.ts +11 -0
  50. package/lib/types/client/components/QaMessage.d.ts +8 -0
  51. package/lib/types/client/index.d.ts +19 -0
  52. package/lib/types/client/styles.d.ts +2 -0
  53. package/lib/types/config.d.ts +5 -0
  54. package/lib/types/host-route.d.ts +9 -0
  55. package/lib/types/index.d.ts +29 -0
  56. package/lib/types/navigation-marker.d.ts +3 -0
  57. package/lib/types/resolve-config.d.ts +6 -0
  58. package/lib/types/types.d.ts +114 -0
  59. package/lib/types.js +2 -0
  60. package/lib/types.js.map +1 -0
  61. package/package.json +137 -0
@@ -0,0 +1,43 @@
1
+ import type { ResolvedQaSurfaceConfig } from "../types.js";
2
+ export interface QaRouteSnapshot {
3
+ readonly pathname: string;
4
+ readonly active: boolean;
5
+ }
6
+ interface NavigationHistory {
7
+ pushState(data: unknown, unused: string, url?: string | URL | null): void;
8
+ replaceState(data: unknown, unused: string, url?: string | URL | null): void;
9
+ }
10
+ interface NavigationWindow {
11
+ readonly location: {
12
+ readonly pathname: string;
13
+ readonly search?: string;
14
+ };
15
+ readonly history: NavigationHistory;
16
+ addEventListener(type: "popstate", listener: () => void): void;
17
+ removeEventListener(type: "popstate", listener: () => void): void;
18
+ }
19
+ export declare function matchesQaRoute(pathname: string, route: ResolvedQaSurfaceConfig["route"]): boolean;
20
+ /** Observable route matcher with reversible History API instrumentation. */
21
+ export declare class QaRouteController {
22
+ private readonly target;
23
+ private readonly listeners;
24
+ private route;
25
+ private enabled;
26
+ private snapshot;
27
+ private readonly originalPushState;
28
+ private readonly originalReplaceState;
29
+ private readonly wrappedPushState;
30
+ private readonly wrappedReplaceState;
31
+ private disposed;
32
+ constructor(target?: NavigationWindow);
33
+ private readonly removePopstate;
34
+ getSnapshot: () => QaRouteSnapshot;
35
+ subscribe: (listener: () => void) => (() => void);
36
+ configure(config: ResolvedQaSurfaceConfig, ready?: boolean): void;
37
+ dispose(): void;
38
+ private project;
39
+ private restoreRedirectedPath;
40
+ private refresh;
41
+ }
42
+ export {};
43
+ //# sourceMappingURL=QaRouteController.d.ts.map
@@ -0,0 +1,59 @@
1
+ import type { HostDescriptionSource, IApiClient } from "@deepseek-ai/dsh-client-connection/client";
2
+ import type { ISessions, SessionListState } from "@deepseek-ai/dsh-client-runtime/client";
3
+ import type { QaSessionState, ResolvedQaSurfaceConfig } from "../types.js";
4
+ type QaSessionsApi = Pick<IApiClient["sessions"], "create" | "selectModel">;
5
+ export interface StorageLike {
6
+ getItem(key: string): string | null;
7
+ setItem(key: string, value: string): void;
8
+ removeItem(key: string): void;
9
+ }
10
+ export interface QaSessionControllerOptions {
11
+ readonly sessions: ISessions;
12
+ readonly api: QaSessionsApi;
13
+ readonly connection: HostDescriptionSource;
14
+ readonly config: ResolvedQaSurfaceConfig;
15
+ readonly storage?: StorageLike;
16
+ readonly timeoutMs?: number;
17
+ }
18
+ /** The only module that couples QA behavior to DSH Session/client APIs. */
19
+ export declare class QaSessionController {
20
+ private readonly listeners;
21
+ private readonly sessions;
22
+ private readonly api;
23
+ private readonly connection;
24
+ private readonly config;
25
+ private readonly storage;
26
+ private readonly timeoutMs;
27
+ private state;
28
+ private session;
29
+ private unsubscribeSession;
30
+ private readonly unsubscribeConnection;
31
+ private ensuring;
32
+ private operationError;
33
+ private admissionPending;
34
+ private connectedOnce;
35
+ private disposed;
36
+ private generation;
37
+ constructor(options: QaSessionControllerOptions);
38
+ getSnapshot: () => QaSessionState;
39
+ subscribe: (listener: () => void) => (() => void);
40
+ ensureSession(): Promise<void>;
41
+ send(text: string): Promise<boolean>;
42
+ stop(): Promise<void>;
43
+ reset(): Promise<void>;
44
+ dispose(): void;
45
+ private ensureSessionNow;
46
+ private createSession;
47
+ private bind;
48
+ private unbind;
49
+ private waitForConnection;
50
+ private publish;
51
+ private fail;
52
+ private storageKey;
53
+ private readPersisted;
54
+ private persist;
55
+ private clearPersisted;
56
+ private emit;
57
+ }
58
+ export type { SessionListState };
59
+ //# sourceMappingURL=QaSessionController.d.ts.map
@@ -0,0 +1,16 @@
1
+ import type { HostDescriptionSource, IApiClient } from "@deepseek-ai/dsh-client-connection/client";
2
+ import type { ISessions } from "@deepseek-ai/dsh-client-runtime/client";
3
+ import type { InjectFace, PropsRuntime } from "@deepseek-ai/dsh-client-ui-slots";
4
+ import type { QaConfigController } from "./QaConfigController.js";
5
+ import type { QaRouteController } from "./QaRouteController.js";
6
+ export interface QaSurfaceFace {
7
+ readonly route: QaRouteController;
8
+ readonly config: QaConfigController;
9
+ readonly sessions: ISessions;
10
+ readonly api: Pick<IApiClient["sessions"], "create" | "selectModel">;
11
+ readonly connection: HostDescriptionSource;
12
+ }
13
+ type QaSurfaceProps = PropsRuntime<"shell.overlay"> & InjectFace<QaSurfaceFace>;
14
+ export declare function QaSurface(props: QaSurfaceProps): import("react/jsx-runtime").JSX.Element | null;
15
+ export {};
16
+ //# sourceMappingURL=QaSurface.d.ts.map
@@ -0,0 +1,7 @@
1
+ import type { ConversationSnapshot } from "@deepseek-ai/dsh-client-runtime/client";
2
+ import type { QaMessage } from "../types.js";
3
+ /** Project only end-user-safe text from the public DSH conversation snapshot. */
4
+ export declare function projectTranscript(snapshot: ConversationSnapshot, options?: {
5
+ readonly showToolActivity?: boolean;
6
+ }): readonly QaMessage[];
7
+ //# sourceMappingURL=QaTranscriptAdapter.d.ts.map
@@ -0,0 +1,5 @@
1
+ /** Deliberately small, HTML-free Markdown renderer for assistant-visible text. */
2
+ export declare function Markdown({ text }: {
3
+ readonly text: string;
4
+ }): import("react/jsx-runtime").JSX.Element;
5
+ //# sourceMappingURL=Markdown.d.ts.map
@@ -0,0 +1,11 @@
1
+ export interface QaComposerProps {
2
+ readonly placeholder: string;
3
+ readonly canSend: boolean;
4
+ readonly canStop: boolean;
5
+ readonly running: boolean;
6
+ readonly showStop: boolean;
7
+ readonly onSend: (text: string) => Promise<boolean>;
8
+ readonly onStop: () => Promise<void>;
9
+ }
10
+ export declare function QaComposer(props: QaComposerProps): import("react/jsx-runtime").JSX.Element;
11
+ //# sourceMappingURL=QaComposer.d.ts.map
@@ -0,0 +1,8 @@
1
+ import type { QaMessage as QaMessageModel } from "../../types.js";
2
+ export interface QaMessageProps {
3
+ readonly message: QaMessageModel;
4
+ readonly renderMarkdown: boolean;
5
+ readonly showTimestamp: boolean;
6
+ }
7
+ export declare function QaMessage({ message, renderMarkdown, showTimestamp, }: QaMessageProps): import("react/jsx-runtime").JSX.Element;
8
+ //# sourceMappingURL=QaMessage.d.ts.map
@@ -0,0 +1,19 @@
1
+ import type { Context } from "@deepseek-ai/cordis";
2
+ import type { ConnectionHandle } from "@deepseek-ai/dsh-client-connection/client";
3
+ import type { ISessions } from "@deepseek-ai/dsh-client-runtime/client";
4
+ import type { SettingsScopeBinder } from "@deepseek-ai/dsh-client-ui-settings/client";
5
+ declare module "@deepseek-ai/cordis" {
6
+ interface Context {
7
+ connection: ConnectionHandle;
8
+ sessions: ISessions;
9
+ settingsScope: SettingsScopeBinder;
10
+ }
11
+ }
12
+ export declare const inject: string[];
13
+ /** Register the route-aware, full-frame QA entry in the additive overlay slot. */
14
+ export declare function apply(ctx: Context): void;
15
+ export { QaConfigController } from "./QaConfigController.js";
16
+ export { QaRouteController, matchesQaRoute } from "./QaRouteController.js";
17
+ export { QaSessionController } from "./QaSessionController.js";
18
+ export { projectTranscript } from "./QaTranscriptAdapter.js";
19
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,2 @@
1
+ export declare const QA_SURFACE_STYLES: string;
2
+ //# sourceMappingURL=styles.d.ts.map
@@ -0,0 +1,5 @@
1
+ import z from "@deepseek-ai/schemastery";
2
+ import type { QaSurfaceConfig } from "./types.js";
3
+ export declare const ConfigSchema: z<QaSurfaceConfig>;
4
+ export { DEFAULT_QA_SURFACE_CONFIG, normalizeRoutePath, resolveConfig, } from "./resolve-config.js";
5
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1,9 @@
1
+ import type { WebServer } from "@deepseek-ai/dsh-host-webserver";
2
+ import type { ResolvedQaSurfaceConfig } from "./types.js";
3
+ /**
4
+ * DSH 0.1.1 static hosting returns 404 for missing paths. Redirect a browser
5
+ * navigation through its canonical index entry; the client restores the
6
+ * requested pathname before activating the QA overlay.
7
+ */
8
+ export declare function registerQaNavigationRoute(webServer: Pick<WebServer, "register">, config: ResolvedQaSurfaceConfig): () => void;
9
+ //# sourceMappingURL=host-route.d.ts.map
@@ -0,0 +1,29 @@
1
+ import { Service, type Context } from "@deepseek-ai/cordis";
2
+ import type { QaSurfaceConfig, ResolvedQaSurfaceConfig } from "./types.js";
3
+ export declare const name = "qa-surface";
4
+ export declare const inject: readonly string[];
5
+ export declare const QA_SURFACE_SETTINGS_NAMESPACE: import("@deepseek-ai/dsh-settings").SettingsNamespace;
6
+ export declare const Config: import("@deepseek-ai/schemastery").default<QaSurfaceConfig>;
7
+ declare module "@deepseek-ai/cordis" {
8
+ interface Context {
9
+ qaSurface: QaSurface;
10
+ }
11
+ }
12
+ /** Small Host companion: validates config and exposes it through DSH settings. */
13
+ export declare class QaSurface extends Service {
14
+ static inject: readonly string[];
15
+ static Config: import("@deepseek-ai/schemastery").default<QaSurfaceConfig>;
16
+ private source;
17
+ private readonly logger;
18
+ private webServer;
19
+ private disposeRoute;
20
+ private routeKey;
21
+ constructor(ctx: Context, entry?: QaSurfaceConfig);
22
+ getConfig(): ResolvedQaSurfaceConfig;
23
+ private refreshRoute;
24
+ }
25
+ export { ConfigSchema, DEFAULT_QA_SURFACE_CONFIG, normalizeRoutePath, resolveConfig, } from "./config.js";
26
+ export { registerQaNavigationRoute } from "./host-route.js";
27
+ export type * from "./types.js";
28
+ export default QaSurface;
29
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,3 @@
1
+ /** Query hand-off used only by the Host navigation compatibility redirect. */
2
+ export declare const QA_NAVIGATION_MARKER = "__dsh_qa_route";
3
+ //# sourceMappingURL=navigation-marker.d.ts.map
@@ -0,0 +1,6 @@
1
+ import type { QaSurfaceConfig, ResolvedQaSurfaceConfig } from "./types.js";
2
+ export declare const DEFAULT_QA_SURFACE_CONFIG: ResolvedQaSurfaceConfig;
3
+ export declare function normalizeRoutePath(value: string): string;
4
+ /** Materialize defaults and enforce route/session/model safety constraints. */
5
+ export declare function resolveConfig(input?: QaSurfaceConfig): ResolvedQaSurfaceConfig;
6
+ //# sourceMappingURL=resolve-config.d.ts.map
@@ -0,0 +1,114 @@
1
+ export type QaSessionPolicy = "browser-persistent" | "new-on-load" | "fixed";
2
+ export interface QaSurfaceConfig {
3
+ readonly enabled?: boolean;
4
+ readonly route?: {
5
+ readonly path?: string;
6
+ readonly matchChildren?: boolean;
7
+ };
8
+ readonly branding?: {
9
+ readonly title?: string;
10
+ readonly subtitle?: string;
11
+ readonly welcomeMessage?: string;
12
+ readonly placeholder?: string;
13
+ readonly logoUrl?: string | null;
14
+ };
15
+ readonly session?: {
16
+ readonly policy?: QaSessionPolicy;
17
+ readonly storageKey?: string;
18
+ readonly workspaceId?: string | null;
19
+ readonly fixedSessionId?: string | null;
20
+ readonly agentPreset?: string | null;
21
+ readonly provider?: string | null;
22
+ readonly model?: string | null;
23
+ readonly reasoningEffort?: string | null;
24
+ };
25
+ readonly ui?: {
26
+ readonly showHeader?: boolean;
27
+ readonly showReset?: boolean;
28
+ readonly showStop?: boolean;
29
+ readonly showTimestamps?: boolean;
30
+ readonly showToolActivity?: boolean;
31
+ readonly showReasoning?: boolean;
32
+ readonly renderMarkdown?: boolean;
33
+ readonly maxContentWidth?: number;
34
+ };
35
+ readonly suggestedQuestions?: readonly string[];
36
+ readonly interaction?: {
37
+ readonly approvals?: "blocked";
38
+ readonly questions?: "unsupported";
39
+ };
40
+ readonly embedding?: {
41
+ readonly frameAncestors?: string | null;
42
+ };
43
+ }
44
+ export interface ResolvedQaSurfaceConfig {
45
+ readonly enabled: boolean;
46
+ readonly route: {
47
+ readonly path: string;
48
+ readonly matchChildren: boolean;
49
+ };
50
+ readonly branding: {
51
+ readonly title: string;
52
+ readonly subtitle: string;
53
+ readonly welcomeMessage: string;
54
+ readonly placeholder: string;
55
+ readonly logoUrl: string | null;
56
+ };
57
+ readonly session: {
58
+ readonly policy: QaSessionPolicy;
59
+ readonly storageKey: string;
60
+ readonly workspaceId: string | null;
61
+ readonly fixedSessionId: string | null;
62
+ readonly agentPreset: string | null;
63
+ readonly provider: string | null;
64
+ readonly model: string | null;
65
+ readonly reasoningEffort: string | null;
66
+ };
67
+ readonly ui: {
68
+ readonly showHeader: boolean;
69
+ readonly showReset: boolean;
70
+ readonly showStop: boolean;
71
+ readonly showTimestamps: boolean;
72
+ readonly showToolActivity: boolean;
73
+ readonly showReasoning: false;
74
+ readonly renderMarkdown: boolean;
75
+ readonly maxContentWidth: number;
76
+ };
77
+ readonly suggestedQuestions: readonly string[];
78
+ readonly interaction: {
79
+ readonly approvals: "blocked";
80
+ readonly questions: "unsupported";
81
+ };
82
+ readonly embedding: {
83
+ readonly frameAncestors: string | null;
84
+ };
85
+ }
86
+ export type QaMessage = {
87
+ readonly id: string;
88
+ readonly role: "user";
89
+ readonly text: string;
90
+ readonly status: "committed";
91
+ readonly timestamp?: number;
92
+ } | {
93
+ readonly id: string;
94
+ readonly role: "assistant";
95
+ readonly text: string;
96
+ readonly status: "streaming" | "committed" | "failed";
97
+ readonly timestamp?: number;
98
+ } | {
99
+ readonly id: string;
100
+ readonly role: "system";
101
+ readonly text: string;
102
+ readonly status: "info" | "error";
103
+ readonly timestamp?: number;
104
+ };
105
+ export type QaSessionPhase = "idle" | "creating" | "ready" | "running" | "reconnecting" | "blocked" | "error";
106
+ export interface QaSessionState {
107
+ readonly phase: QaSessionPhase;
108
+ readonly sessionId: string | null;
109
+ readonly messages: readonly QaMessage[];
110
+ readonly error: string | null;
111
+ readonly canSend: boolean;
112
+ readonly canStop: boolean;
113
+ }
114
+ //# sourceMappingURL=types.d.ts.map
package/lib/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,137 @@
1
+ {
2
+ "name": "@yadsh/dsh-qa-surface",
3
+ "version": "0.1.0",
4
+ "description": "A focused end-user QA surface backed by native DeepSeek Harness sessions",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "git+https://github.com/xarleyn/dsh-plugins.git",
8
+ "directory": "plugins/dsh-qa-surface"
9
+ },
10
+ "homepage": "https://github.com/xarleyn/dsh-plugins/tree/main/plugins/dsh-qa-surface#readme",
11
+ "bugs": {
12
+ "url": "https://github.com/xarleyn/dsh-plugins/issues"
13
+ },
14
+ "type": "module",
15
+ "main": "./lib/index.js",
16
+ "types": "./lib/types/index.d.ts",
17
+ "exports": {
18
+ ".": {
19
+ "types": "./lib/types/index.d.ts",
20
+ "default": "./lib/index.js"
21
+ },
22
+ "./client": {
23
+ "types": "./lib/types/client/index.d.ts",
24
+ "default": "./lib/client.js"
25
+ },
26
+ "./types": {
27
+ "types": "./lib/types/types.d.ts",
28
+ "default": "./lib/types.js"
29
+ },
30
+ "./package.json": "./package.json"
31
+ },
32
+ "dsh": {
33
+ "bundle": {
34
+ "patch": "./cordis.patch.yml"
35
+ },
36
+ "client": {
37
+ "external": [
38
+ "@deepseek-ai/dsh-client-ui-slots"
39
+ ],
40
+ "inject": [
41
+ "@deepseek-ai/dsh-api-gateway",
42
+ "@deepseek-ai/dsh-client-connection",
43
+ "@deepseek-ai/dsh-client-runtime",
44
+ "@deepseek-ai/dsh-client-ui-layout",
45
+ "@deepseek-ai/dsh-client-ui-settings",
46
+ "@deepseek-ai/dsh-client-ui-theme"
47
+ ],
48
+ "platform": "web"
49
+ }
50
+ },
51
+ "files": [
52
+ "lib/**/*.js",
53
+ "lib/**/*.js.map",
54
+ "lib/types/**/*.d.ts",
55
+ "cordis.patch.yml",
56
+ "compatibility.json",
57
+ "README.md",
58
+ "CHANGELOG.md",
59
+ "docs/*.md",
60
+ "SPEC-dsh-qa-surface.md",
61
+ "LICENSE"
62
+ ],
63
+ "scripts": {
64
+ "clean": "node -e \"require('node:fs').rmSync('lib', { recursive: true, force: true })\"",
65
+ "build": "pnpm run clean && tsdown && tsc -p tsconfig.build.json",
66
+ "lint": "eslint src tests scripts tsdown.config.ts",
67
+ "format": "prettier --check . --end-of-line auto",
68
+ "format:write": "prettier --write . --end-of-line auto",
69
+ "typecheck": "tsc -p tsconfig.json --noEmit",
70
+ "test": "vitest run",
71
+ "verify": "node scripts/verify-package.mjs",
72
+ "smoke:packed": "node scripts/smoke-packed-dsh.mjs",
73
+ "e2e:browser": "node scripts/smoke-packed-dsh.mjs --browser",
74
+ "check": "pnpm run format && pnpm run lint && pnpm run typecheck && pnpm run test && pnpm run build && pnpm run verify",
75
+ "prepack": "pnpm run build && pnpm run verify",
76
+ "prepublishOnly": "pnpm run check"
77
+ },
78
+ "keywords": [
79
+ "deepseek",
80
+ "deepseek-harness",
81
+ "dsh",
82
+ "dsh-plugin",
83
+ "qa",
84
+ "chat",
85
+ "web-ui"
86
+ ],
87
+ "license": "MIT",
88
+ "engines": {
89
+ "node": "^22.19.0 || >=24.0.0"
90
+ },
91
+ "peerDependencies": {
92
+ "@deepseek-ai/cordis": "catalog:dsh",
93
+ "@deepseek-ai/schemastery": "catalog:dsh",
94
+ "@deepseek-ai/dsh-api-gateway": "catalog:dsh",
95
+ "@deepseek-ai/dsh-client-connection": "catalog:dsh",
96
+ "@deepseek-ai/dsh-client-runtime": "catalog:dsh",
97
+ "@deepseek-ai/dsh-client-ui-layout": "catalog:dsh",
98
+ "@deepseek-ai/dsh-client-ui-settings": "catalog:dsh",
99
+ "@deepseek-ai/dsh-client-ui-slots": "catalog:dsh",
100
+ "@deepseek-ai/dsh-client-ui-theme": "catalog:dsh",
101
+ "@deepseek-ai/dsh-host-webserver": "catalog:dsh",
102
+ "@deepseek-ai/dsh-settings": "catalog:dsh",
103
+ "react": "^18.2.0"
104
+ },
105
+ "dependencies": {
106
+ "@yadsh/dsh-plugin-log": "workspace:^"
107
+ },
108
+ "devDependencies": {
109
+ "@deepseek-ai/cordis": "catalog:dsh-dev",
110
+ "@deepseek-ai/schemastery": "catalog:dsh-dev",
111
+ "@deepseek-ai/dsh-api-gateway": "catalog:dsh-dev",
112
+ "@deepseek-ai/dsh-client-connection": "catalog:dsh-dev",
113
+ "@deepseek-ai/dsh-client-runtime": "catalog:dsh-dev",
114
+ "@deepseek-ai/dsh-client-ui-layout": "catalog:dsh-dev",
115
+ "@deepseek-ai/dsh-client-ui-settings": "catalog:dsh-dev",
116
+ "@deepseek-ai/dsh-client-ui-slots": "catalog:dsh-dev",
117
+ "@deepseek-ai/dsh-client-ui-theme": "catalog:dsh-dev",
118
+ "@deepseek-ai/dsh-host-webserver": "catalog:dsh-dev",
119
+ "@deepseek-ai/dsh-settings": "catalog:dsh-dev",
120
+ "@testing-library/react": "^16.3.0",
121
+ "@types/node": "catalog:tooling",
122
+ "@types/react": "catalog:frontend-dev",
123
+ "@yadsh/dsh-config": "workspace:^",
124
+ "eslint": "catalog:tooling",
125
+ "jsdom": "catalog:tooling",
126
+ "playwright": "catalog:tooling",
127
+ "prettier": "catalog:tooling",
128
+ "react": "catalog:frontend-dev",
129
+ "tsdown": "catalog:tooling",
130
+ "typescript": "catalog:plugin-tooling",
131
+ "vitest": "catalog:tooling"
132
+ },
133
+ "publishConfig": {
134
+ "access": "public",
135
+ "registry": "https://registry.npmjs.org/"
136
+ }
137
+ }