dsh-image-gen 0.6.11 → 0.7.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/lib/client.js +78 -27
- package/lib/client.js.map +1 -1
- package/lib/index.js +744 -1075
- package/lib/types/client/gallery-view.d.ts +10 -0
- package/lib/types/client/index.d.ts +9 -2
- package/lib/types/client/settings-write.d.ts +4 -0
- package/lib/types/client/tl/studio-tl-canvas.d.ts +7 -0
- package/lib/types/config.d.ts +7 -1
- package/lib/types/shared.d.ts +6 -0
- package/package.json +20 -20
- package/lib/types/client/canvas/canvas-bridge.d.ts +0 -10
- package/lib/types/client/canvas/canvas-model.d.ts +0 -129
- package/lib/types/client/canvas/canvas-nodes.d.ts +0 -23
- package/lib/types/client/canvas/canvas-store.d.ts +0 -29
- package/lib/types/client/canvas/canvas-style.d.ts +0 -1
- package/lib/types/client/canvas/canvas-view.d.ts +0 -8
- package/lib/types/client/canvas/rf-base-css.d.ts +0 -2
- package/lib/types/client/studio-chat-panel.d.ts +0 -23
- package/lib/types/client/tl/diagram-landing.d.ts +0 -75
- package/lib/types/client/tl/diagram-layout.d.ts +0 -76
- package/lib/types/client/tl/diagram-measure.d.ts +0 -40
- package/lib/types/diagram.d.ts +0 -42
- package/lib/types/studio-chat.d.ts +0 -48
|
@@ -228,6 +228,16 @@ export interface GalleryViewTabProps {
|
|
|
228
228
|
defaultTab?: TabKey;
|
|
229
229
|
/** Canvas surface the studio opens with; the sidebar variant shows the tldraw infinite canvas directly. */
|
|
230
230
|
initialCanvasSurface?: 'preview' | 'infinite';
|
|
231
|
+
/**
|
|
232
|
+
* Sidebar tab visibility reader injected by DSH's `sidebar.right.pane.tab`
|
|
233
|
+
* seat (absent on hosts that mount this view elsewhere, e.g. the main-area
|
|
234
|
+
* conversation tab, where the hook is optional).
|
|
235
|
+
*/
|
|
236
|
+
useTabInfo?: (() => {
|
|
237
|
+
tab?: {
|
|
238
|
+
visible?: boolean;
|
|
239
|
+
};
|
|
240
|
+
}) | undefined;
|
|
231
241
|
}
|
|
232
242
|
export declare const GalleryViewTab: FC<GalleryViewTabProps>;
|
|
233
243
|
export { copyImageBlob } from './browser-image-utils.js';
|
|
@@ -7,7 +7,8 @@ export interface SettingsScopeSnapshot<T> {
|
|
|
7
7
|
export interface SettingsScope<T> {
|
|
8
8
|
getSnapshot(): SettingsScopeSnapshot<T>;
|
|
9
9
|
subscribe(listener: () => void): () => void;
|
|
10
|
-
|
|
10
|
+
/** New hosts return true/false; legacy settings scopes resolve to void. */
|
|
11
|
+
set(field: string, value: unknown): Promise<boolean | void>;
|
|
11
12
|
}
|
|
12
13
|
import type { InjectFace, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots';
|
|
13
14
|
import { type ComfyUIWorkflowEntry, type ImageProvider } from '../shared.js';
|
|
@@ -97,7 +98,13 @@ interface ImageResultNodeProps {
|
|
|
97
98
|
};
|
|
98
99
|
locale?: LocaleService | undefined;
|
|
99
100
|
}
|
|
100
|
-
/**
|
|
101
|
+
/**
|
|
102
|
+
* Required browser services. The settings form reader is deliberately absent:
|
|
103
|
+
* DSH 0.1.7 serves it as `configForms` (keyed by the Loader entry id) while
|
|
104
|
+
* 0.1.5/0.1.6 expose `settingsScope` (keyed by the legacy namespace), so it is
|
|
105
|
+
* probed at runtime in `apply`. A static inject of either name would park this
|
|
106
|
+
* fiber forever on hosts from the other generation — the issue #55 failure.
|
|
107
|
+
*/
|
|
101
108
|
export declare const inject: string[];
|
|
102
109
|
/** Mount the settings card, generated-image card, and native conversation gallery view. */
|
|
103
110
|
export declare function apply(ctx: Context): void;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** DSH 0.1.7 resolves refused writes to false; older settings scopes resolve to void. */
|
|
2
|
+
export declare function writeSetting(scope: {
|
|
3
|
+
set(field: string, value: unknown): Promise<boolean | void>;
|
|
4
|
+
}, field: string, value: unknown, rejectedMessage: string): Promise<void>;
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import { type FC } from 'react';
|
|
2
2
|
/** Reset canvas-owned data only. Gallery records and host attachments are untouched. */
|
|
3
3
|
export declare function clearStudioTlCanvases(): boolean;
|
|
4
|
+
/**
|
|
5
|
+
* Cancel in-editor selection on every mounted canvas, keeping shapes and sync
|
|
6
|
+
* untouched. Selection is interaction state tied to the surface: leaving the
|
|
7
|
+
* studio page cancels it so a stale selection can neither resurface on return
|
|
8
|
+
* nor linger in the host mirror.
|
|
9
|
+
*/
|
|
10
|
+
export declare function deselectStudioTlCanvases(): boolean;
|
|
4
11
|
export declare const StudioTlCanvas: FC<{
|
|
5
12
|
lang?: 'zh' | 'en';
|
|
6
13
|
}>;
|
package/lib/types/config.d.ts
CHANGED
|
@@ -70,8 +70,14 @@ export interface Config {
|
|
|
70
70
|
saveToWorkspace?: boolean;
|
|
71
71
|
/** Workspace subfolder for generated images; empty means the workspace root. */
|
|
72
72
|
workspaceFolder?: string;
|
|
73
|
+
/** Show the provider switcher beside the chat input. */
|
|
74
|
+
showProviderPill?: boolean;
|
|
73
75
|
}
|
|
74
|
-
/**
|
|
76
|
+
/**
|
|
77
|
+
* Cordis configuration schema. Volatile marking happens per field (see
|
|
78
|
+
* `volatile`); the `z<Config>` annotation keeps the plain output type for the
|
|
79
|
+
* rest of the codebase because the wrapping is unwrapped at the entry.
|
|
80
|
+
*/
|
|
75
81
|
export declare const Config: z<Config>;
|
|
76
82
|
/** Resolve exactly one provider profile for a tool call. */
|
|
77
83
|
export declare function resolveProvider(config: Config): {
|
package/lib/types/shared.d.ts
CHANGED
|
@@ -112,6 +112,12 @@ export interface CanvasStatePush {
|
|
|
112
112
|
}
|
|
113
113
|
/** Namespace persisted through DSH Settings. */
|
|
114
114
|
export declare const IMAGE_GENERATION_NAMESPACE = "image-generation";
|
|
115
|
+
/**
|
|
116
|
+
* Loader entry id of this plugin's composition entry (see cordis.patch.yml).
|
|
117
|
+
* DSH 0.1.7 serves a plugin's settings under its entry id as the namespace,
|
|
118
|
+
* so browser-side reads/writes bind `configForms` to this id.
|
|
119
|
+
*/
|
|
120
|
+
export declare const IMAGE_GENERATION_ENTRY_ID = "image-gen";
|
|
115
121
|
/** Supported providers. */
|
|
116
122
|
export declare const IMAGE_PROVIDERS: readonly ["google", "openai", "openai-compat", "seedream", "dashscope", "xai", "zhipu", "comfyui", "chatgpt-sub", "grok-sub", "google-sub"];
|
|
117
123
|
export type ImageProvider = typeof IMAGE_PROVIDERS[number];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-image-gen",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "Bring ChatGPT-like image generation to DeepSeek Harness — Gemini, OpenAI, Seedream, DashScope, local ComfyUI & more.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": "shanliuling",
|
|
@@ -106,25 +106,25 @@
|
|
|
106
106
|
}
|
|
107
107
|
},
|
|
108
108
|
"devDependencies": {
|
|
109
|
-
"@deepseek-ai/cordis": "4.0.
|
|
110
|
-
"@deepseek-ai/dsh-agent": "0.1.
|
|
111
|
-
"@deepseek-ai/dsh-api-remotes": "0.1.
|
|
112
|
-
"@deepseek-ai/dsh-attachment": "0.1.
|
|
113
|
-
"@deepseek-ai/dsh-client-connection": "0.1.
|
|
114
|
-
"@deepseek-ai/dsh-client-ui-conversation": "0.1.
|
|
115
|
-
"@deepseek-ai/dsh-client-ui-settings": "0.1.
|
|
116
|
-
"@deepseek-ai/dsh-client-ui-settings-plugins": "0.1.
|
|
117
|
-
"@deepseek-ai/dsh-client-ui-sidebar-right": "0.1.
|
|
118
|
-
"@deepseek-ai/dsh-client-ui-slots": "0.1.
|
|
119
|
-
"@deepseek-ai/dsh-client-ui-tool": "0.1.
|
|
120
|
-
"@deepseek-ai/dsh-credentials": "0.1.
|
|
121
|
-
"@deepseek-ai/dsh-host-webserver": "0.1.
|
|
122
|
-
"@deepseek-ai/dsh-llm": "0.1.
|
|
123
|
-
"@deepseek-ai/dsh-session": "0.1.
|
|
124
|
-
"@deepseek-ai/dsh-settings": "0.1.
|
|
125
|
-
"@deepseek-ai/dsh-tools": "0.1.
|
|
126
|
-
"@deepseek-ai/dsh-workspace": "0.1.
|
|
127
|
-
"@deepseek-ai/schemastery": "3.18.
|
|
109
|
+
"@deepseek-ai/cordis": "4.0.4",
|
|
110
|
+
"@deepseek-ai/dsh-agent": "0.1.7-rc.2",
|
|
111
|
+
"@deepseek-ai/dsh-api-remotes": "0.1.7-rc.2",
|
|
112
|
+
"@deepseek-ai/dsh-attachment": "0.1.7-rc.2",
|
|
113
|
+
"@deepseek-ai/dsh-client-connection": "0.1.7-rc.2",
|
|
114
|
+
"@deepseek-ai/dsh-client-ui-conversation": "0.1.7-rc.2",
|
|
115
|
+
"@deepseek-ai/dsh-client-ui-settings": "0.1.7-rc.2",
|
|
116
|
+
"@deepseek-ai/dsh-client-ui-settings-plugins": "0.1.7-rc.2",
|
|
117
|
+
"@deepseek-ai/dsh-client-ui-sidebar-right": "0.1.7-rc.2",
|
|
118
|
+
"@deepseek-ai/dsh-client-ui-slots": "0.1.7-rc.2",
|
|
119
|
+
"@deepseek-ai/dsh-client-ui-tool": "0.1.7-rc.2",
|
|
120
|
+
"@deepseek-ai/dsh-credentials": "0.1.7-rc.2",
|
|
121
|
+
"@deepseek-ai/dsh-host-webserver": "0.1.7-rc.2",
|
|
122
|
+
"@deepseek-ai/dsh-llm": "0.1.7-rc.2",
|
|
123
|
+
"@deepseek-ai/dsh-session": "0.1.7-rc.2",
|
|
124
|
+
"@deepseek-ai/dsh-settings": "0.1.7-rc.2",
|
|
125
|
+
"@deepseek-ai/dsh-tools": "0.1.7-rc.2",
|
|
126
|
+
"@deepseek-ai/dsh-workspace": "0.1.7-rc.2",
|
|
127
|
+
"@deepseek-ai/schemastery": "3.18.4",
|
|
128
128
|
"@types/node": "^22.20.0",
|
|
129
129
|
"@types/react": "~18.3.1",
|
|
130
130
|
"react": "^18.2.0",
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import type { StudioProviderProfile } from '../../shared.js';
|
|
2
|
-
export interface CanvasBridge {
|
|
3
|
-
updateNodeData: (nodeId: string, patch: Record<string, unknown>) => void;
|
|
4
|
-
requestGenerate: (nodeId: string) => void;
|
|
5
|
-
deleteNode: (nodeId: string) => void;
|
|
6
|
-
profiles: readonly StudioProviderProfile[];
|
|
7
|
-
lang: 'zh' | 'en';
|
|
8
|
-
}
|
|
9
|
-
export declare const CanvasBridgeContext: import("react").Context<CanvasBridge | undefined>;
|
|
10
|
-
export declare function useCanvasBridge(): CanvasBridge | undefined;
|
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Canvas domain model: pure node/edge helpers shared by the canvas view,
|
|
3
|
-
* the import bridge and unit tests. No React, no IO.
|
|
4
|
-
*/
|
|
5
|
-
import { type Edge, type Node } from '@xyflow/react';
|
|
6
|
-
import type { ImageAttachmentRef } from '@deepseek-ai/dsh-attachment';
|
|
7
|
-
import type { StudioGenerateRequest, StudioProviderProfile } from '../../shared.js';
|
|
8
|
-
export interface ImageNodeData extends Record<string, unknown> {
|
|
9
|
-
kind: 'image';
|
|
10
|
-
/** Durable attachment-backed image (generated results, conversation imports). */
|
|
11
|
-
attachment?: ImageAttachmentRef;
|
|
12
|
-
/** Locally uploaded image kept as base64 until used as a generation reference. */
|
|
13
|
-
encoded?: {
|
|
14
|
-
mediaType: string;
|
|
15
|
-
data: string;
|
|
16
|
-
};
|
|
17
|
-
prompt?: string;
|
|
18
|
-
pending?: boolean;
|
|
19
|
-
error?: string;
|
|
20
|
-
}
|
|
21
|
-
export interface TextNodeData extends Record<string, unknown> {
|
|
22
|
-
kind: 'text';
|
|
23
|
-
text: string;
|
|
24
|
-
}
|
|
25
|
-
export interface ConfigNodeData extends Record<string, unknown> {
|
|
26
|
-
kind: 'config';
|
|
27
|
-
provider: string;
|
|
28
|
-
model: string;
|
|
29
|
-
prompt: string;
|
|
30
|
-
ratio: string;
|
|
31
|
-
quality: string;
|
|
32
|
-
count: number;
|
|
33
|
-
generating?: boolean;
|
|
34
|
-
error?: string;
|
|
35
|
-
}
|
|
36
|
-
export type CanvasNode = Node<ImageNodeData | TextNodeData | ConfigNodeData>;
|
|
37
|
-
export type ConfigNode = Node<ConfigNodeData>;
|
|
38
|
-
export interface CanvasDocument {
|
|
39
|
-
nodes: CanvasNode[];
|
|
40
|
-
edges: Edge[];
|
|
41
|
-
viewport?: {
|
|
42
|
-
x: number;
|
|
43
|
-
y: number;
|
|
44
|
-
zoom: number;
|
|
45
|
-
};
|
|
46
|
-
updatedAt: number;
|
|
47
|
-
}
|
|
48
|
-
/** Collision-safe node id (also stable across sessions via the random suffix). */
|
|
49
|
-
export declare function newId(prefix: string): string;
|
|
50
|
-
/** Stable node id for one attachment so repeated imports/generations dedupe. */
|
|
51
|
-
export declare function imageNodeIdOf(attachmentId: string): string;
|
|
52
|
-
export declare function nodeKindOf(node: CanvasNode | undefined): string | undefined;
|
|
53
|
-
export declare function newTextNode(text: string | undefined, x: number, y: number): CanvasNode;
|
|
54
|
-
export declare function newConfigNode(profile: StudioProviderProfile | undefined, x: number, y: number): CanvasNode;
|
|
55
|
-
export declare function newImageNode(input: {
|
|
56
|
-
attachment?: ImageAttachmentRef;
|
|
57
|
-
encoded?: {
|
|
58
|
-
mediaType: string;
|
|
59
|
-
data: string;
|
|
60
|
-
};
|
|
61
|
-
prompt?: string;
|
|
62
|
-
pending?: boolean;
|
|
63
|
-
error?: string;
|
|
64
|
-
x: number;
|
|
65
|
-
y: number;
|
|
66
|
-
}, id?: string): CanvasNode;
|
|
67
|
-
/** Whether an edge is legal in the canvas graph: inputs feed configs, configs emit results, and images chain edits. */
|
|
68
|
-
export declare function isLegalConnection(source: CanvasNode | undefined, target: CanvasNode | undefined): boolean;
|
|
69
|
-
/** Everything a config node needs to know about its incoming edges. */
|
|
70
|
-
export interface ResolvedInputs {
|
|
71
|
-
promptParts: string[];
|
|
72
|
-
referenceAttachments: ImageAttachmentRef[];
|
|
73
|
-
encodedReferences: Array<{
|
|
74
|
-
mediaType: string;
|
|
75
|
-
data: string;
|
|
76
|
-
}>;
|
|
77
|
-
}
|
|
78
|
-
export declare function resolveConfigInputs(nodes: readonly CanvasNode[], edges: readonly Edge[], configNodeId: string): ResolvedInputs;
|
|
79
|
-
/** Build the studio request for one config node. Returns undefined when the prompt is empty. */
|
|
80
|
-
export declare function buildGenerationRequest(config: ConfigNode, inputs: ResolvedInputs): StudioGenerateRequest | undefined;
|
|
81
|
-
/** Position for the k-th output image spawned by one config node. */
|
|
82
|
-
export declare function outputPosition(config: CanvasNode, existingOutputCount: number, index: number): {
|
|
83
|
-
x: number;
|
|
84
|
-
y: number;
|
|
85
|
-
};
|
|
86
|
-
/** One imported generation record (gallery item or pending bridge payload). */
|
|
87
|
-
export interface ImportRecord {
|
|
88
|
-
attachmentId: string;
|
|
89
|
-
attachment: ImageAttachmentRef;
|
|
90
|
-
prompt?: string;
|
|
91
|
-
provider?: string;
|
|
92
|
-
model?: string;
|
|
93
|
-
createdAt?: number;
|
|
94
|
-
sourceAttachmentIds?: readonly string[];
|
|
95
|
-
}
|
|
96
|
-
/**
|
|
97
|
-
* Canonical canvas edge factory: the closed arrowhead is baked in here so
|
|
98
|
-
* generation edges, import edit-chain edges, and user-drawn edges all read
|
|
99
|
-
* direction the same way (React Flow's defaultEdgeOptions never applies to
|
|
100
|
-
* edges inserted directly through the edges state).
|
|
101
|
-
*/
|
|
102
|
-
export declare function canvasEdge(source: string, target: string, className?: string): Edge;
|
|
103
|
-
/** Rebuild image nodes and edit-chain edges from import records (ordered oldest first). */
|
|
104
|
-
export declare function buildImportGraph(records: readonly ImportRecord[]): {
|
|
105
|
-
nodes: CanvasNode[];
|
|
106
|
-
edges: Edge[];
|
|
107
|
-
};
|
|
108
|
-
/** Merge an import graph into existing canvas state (nodes dedupe by id, edges by key). */
|
|
109
|
-
export declare function mergeIntoCanvas(current: {
|
|
110
|
-
nodes: readonly CanvasNode[];
|
|
111
|
-
edges: readonly Edge[];
|
|
112
|
-
}, incoming: {
|
|
113
|
-
nodes: readonly CanvasNode[];
|
|
114
|
-
edges: readonly Edge[];
|
|
115
|
-
}, offset: {
|
|
116
|
-
x: number;
|
|
117
|
-
y: number;
|
|
118
|
-
}): {
|
|
119
|
-
nodes: CanvasNode[];
|
|
120
|
-
edges: Edge[];
|
|
121
|
-
};
|
|
122
|
-
/** Drop volatile runtime flags (generating/pending/selected) — before persisting AND after restoring, so a remount never shows a phantom in-flight generation. */
|
|
123
|
-
export declare function stripVolatile(node: CanvasNode): CanvasNode;
|
|
124
|
-
/** Serialize the graph for persistence (strips volatile flags). */
|
|
125
|
-
export declare function toDocument(nodes: readonly CanvasNode[], edges: readonly Edge[], viewport?: {
|
|
126
|
-
x: number;
|
|
127
|
-
y: number;
|
|
128
|
-
zoom: number;
|
|
129
|
-
}): CanvasDocument;
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Canvas node renderers: image (attachment or base64), text prompt, and the
|
|
3
|
-
* generation config form. Data mutations flow through the canvas bridge
|
|
4
|
-
* context, never through node data props.
|
|
5
|
-
*/
|
|
6
|
-
import { type FC } from 'react';
|
|
7
|
-
import { type NodeProps, type Node } from '@xyflow/react';
|
|
8
|
-
import type { ConfigNodeData, ImageNodeData, TextNodeData } from './canvas-model.js';
|
|
9
|
-
type ImageNodeType = Node<ImageNodeData, 'image'>;
|
|
10
|
-
type TextNodeType = Node<TextNodeData, 'text'>;
|
|
11
|
-
type ConfigNodeType = Node<ConfigNodeData, 'config'>;
|
|
12
|
-
/** Attachment-backed or base64 image node; source handle feeds config nodes. */
|
|
13
|
-
export declare const CanvasImageNode: FC<NodeProps<ImageNodeType>>;
|
|
14
|
-
/** Free-form prompt fragment node. */
|
|
15
|
-
export declare const CanvasTextNode: FC<NodeProps<TextNodeType>>;
|
|
16
|
-
/** Generation config form; incoming edges contribute prompt text and reference images. */
|
|
17
|
-
export declare const CanvasConfigNode: FC<NodeProps<ConfigNodeType>>;
|
|
18
|
-
export declare const canvasNodeTypes: {
|
|
19
|
-
readonly image: FC<NodeProps<ImageNodeType>>;
|
|
20
|
-
readonly text: FC<NodeProps<TextNodeType>>;
|
|
21
|
-
readonly config: FC<NodeProps<ConfigNodeType>>;
|
|
22
|
-
};
|
|
23
|
-
export {};
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* IndexedDB persistence for the canvas workspace plus the cross-view import
|
|
3
|
-
* bridge: conversation image cards enqueue pending imports, the canvas tab
|
|
4
|
-
* drains them (live when open, on mount otherwise). Mirrors gallery-store's
|
|
5
|
-
* schemaless pattern so optional fields never need a version bump.
|
|
6
|
-
*/
|
|
7
|
-
import type { ImageAttachmentRef } from '@deepseek-ai/dsh-attachment';
|
|
8
|
-
import type { CanvasDocument } from './canvas-model.js';
|
|
9
|
-
export interface PendingCanvasImport {
|
|
10
|
-
id: string;
|
|
11
|
-
attachment: ImageAttachmentRef;
|
|
12
|
-
prompt?: string;
|
|
13
|
-
provider?: string;
|
|
14
|
-
model?: string;
|
|
15
|
-
createdAt: number;
|
|
16
|
-
sourceAttachmentIds?: string[];
|
|
17
|
-
}
|
|
18
|
-
export declare function loadCanvasDocument(): Promise<CanvasDocument | undefined>;
|
|
19
|
-
export declare function saveCanvasDocument(doc: CanvasDocument): Promise<void>;
|
|
20
|
-
type CanvasListener = () => void;
|
|
21
|
-
/** Subscribe to pending-import arrivals so an open canvas can drain live. */
|
|
22
|
-
export declare function subscribeCanvas(listener: CanvasListener): () => void;
|
|
23
|
-
/** Enqueue one conversation image for the canvas. Fire-and-forget safe. */
|
|
24
|
-
export declare function enqueuePendingCanvasImport(item: Omit<PendingCanvasImport, 'id' | 'createdAt'> & {
|
|
25
|
-
createdAt?: number;
|
|
26
|
-
}): Promise<void>;
|
|
27
|
-
/** Read and clear the pending-import queue. */
|
|
28
|
-
export declare function drainPendingCanvasImports(): Promise<PendingCanvasImport[]>;
|
|
29
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const CANVAS_STYLE: string;
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { type FC } from 'react';
|
|
2
|
-
import type { LocaleService } from '../gallery-view.js';
|
|
3
|
-
export interface CanvasViewTabProps {
|
|
4
|
-
locale?: LocaleService;
|
|
5
|
-
sessionId?: string;
|
|
6
|
-
useSessions?: (selector: (state: any) => any) => any;
|
|
7
|
-
}
|
|
8
|
-
export declare const CanvasViewTab: FC<CanvasViewTabProps>;
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Workbench chat panel: the right-side DSH conversation surface.
|
|
3
|
-
*
|
|
4
|
-
* A dedicated archived agent session lives on the host side (studio-chat.ts);
|
|
5
|
-
* this panel pulls its projected event feed through CHAT_ROUTE with adaptive
|
|
6
|
-
* polling (?since=<seq> increments; faster while a turn is running, slower
|
|
7
|
-
* when idle, paused while the webview is hidden) and submits user turns with
|
|
8
|
-
* POST. Tool-generated images are mirrored onto the tldraw canvas through the
|
|
9
|
-
* landing queue and upserted into the gallery (the recent list refreshes via
|
|
10
|
-
* its subscription). The panel is intentionally unmount-friendly: re-pulls
|
|
11
|
-
* from seq 0 on remount, and both landing and gallery writes are deduped by
|
|
12
|
-
* attachmentId, so tab switches are safe.
|
|
13
|
-
*/
|
|
14
|
-
import { type FC } from 'react';
|
|
15
|
-
/** Workspace scoping mirrored onto gallery records; shape-compatible with StudioWorkspaceProps. */
|
|
16
|
-
export interface ChatWorkspaceScope {
|
|
17
|
-
workspaceId?: string | undefined;
|
|
18
|
-
path?: string | undefined;
|
|
19
|
-
}
|
|
20
|
-
export declare const StudioChatPanel: FC<{
|
|
21
|
-
lang: 'zh' | 'en';
|
|
22
|
-
workspace?: ChatWorkspaceScope | null | undefined;
|
|
23
|
-
}>;
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Land one create_diagram result onto a tldraw page.
|
|
3
|
-
*
|
|
4
|
-
* Shapes and their arrow bindings are created in a single editor.run
|
|
5
|
-
* transaction, and a history stopping point is marked BEFORE the batch:
|
|
6
|
-
* tldraw's HistoryManager pops diffs until the next stop mark on undo, so
|
|
7
|
-
* without the mark two diagrams landing back-to-back would undo together.
|
|
8
|
-
* With it, each diagram is one independent undo step (undo/redo verified
|
|
9
|
-
* against the HistoryManager source and on the real canvas).
|
|
10
|
-
*
|
|
11
|
-
* Arrows are ELBOW connectors with BOTH terminals bound. Each terminal's
|
|
12
|
-
* binding side is derived from dagre's polyline: the first/last segment's
|
|
13
|
-
* dominant axis says which node edge the route uses (back edges leave the
|
|
14
|
-
* source's top and re-enter the target's bottom through the corridor dagre
|
|
15
|
-
* reserved, instead of tldraw guessing a center-to-center route). tldraw
|
|
16
|
-
* then re-routes the middle segments itself from the bindings — the
|
|
17
|
-
* polyline is a per-terminal side hint, not a full path contract. Whether
|
|
18
|
-
* the final arrows avoid crossing nodes and whether labels sit clear of
|
|
19
|
-
* geometry is validated on the real canvas, not assumed here.
|
|
20
|
-
*
|
|
21
|
-
* Derived anchors are clamped to the middle band (0.2–0.8) of their edge:
|
|
22
|
-
* tldraw's getEdgeFromNormalizedAnchor resolves the side via |x-0.5| vs
|
|
23
|
-
* |y-0.5|, and a corner-ish anchor could resolve to the wrong side.
|
|
24
|
-
*
|
|
25
|
-
* Edge labels set labelPosition from dagre's arc-length ratio — a
|
|
26
|
-
* best-effort estimate, since tldraw applies the ratio to its own routed
|
|
27
|
-
* path.
|
|
28
|
-
*
|
|
29
|
-
* Self loops (empty dagre polyline) fall back to center bindings: tldraw
|
|
30
|
-
* draws bound self-loop arrows natively.
|
|
31
|
-
*
|
|
32
|
-
* Every created shape carries meta.diagramId, the same dedupe identity the
|
|
33
|
-
* landing reconcile uses for images' meta.galleryId.
|
|
34
|
-
*/
|
|
35
|
-
import { type Editor } from 'tldraw';
|
|
36
|
-
import { type DiagramLayout, type DiagramLayoutEdge, type DiagramLayoutNode, type DiagramPoint } from './diagram-layout.js';
|
|
37
|
-
import type { TlDiagramLanding } from './tl-canvas-bridge.js';
|
|
38
|
-
/** Terminal binding plan: the precise anchor, or a center fallback. */
|
|
39
|
-
export interface TerminalPlan {
|
|
40
|
-
anchor: {
|
|
41
|
-
x: number;
|
|
42
|
-
y: number;
|
|
43
|
-
};
|
|
44
|
-
precise: boolean;
|
|
45
|
-
}
|
|
46
|
-
/**
|
|
47
|
-
* Derive one terminal's binding side + precise anchor from dagre's
|
|
48
|
-
* polyline. The boundary point sits ON the node outline (dagre guarantees
|
|
49
|
-
* this via its node-intersection pass), so the binding side is the OUTLINE
|
|
50
|
-
* EDGE CLOSEST TO THE BOUNDARY POINT — not the segment direction. The last
|
|
51
|
-
* segment often enters at an angle because dagre projects the corridor
|
|
52
|
-
* point onto the outline (e.g. a back edge entering the target's bottom
|
|
53
|
-
* with a final dx=57, dy=-48 segment), and direction-dominance would
|
|
54
|
-
* misread that as `right`. The segment direction is only used to break
|
|
55
|
-
* exact corner ties. The boundary point gives the cross-axis position,
|
|
56
|
-
* clamped to the anchor band.
|
|
57
|
-
*/
|
|
58
|
-
export declare function terminalPlan(node: Pick<DiagramLayoutNode, 'x' | 'y' | 'w' | 'h'>, boundary: DiagramPoint, next: DiagramPoint): TerminalPlan;
|
|
59
|
-
/**
|
|
60
|
-
* Binding plans for one edge's two terminals. Self loops (no dagre
|
|
61
|
-
* polyline) get center plans: tldraw renders bound self loops natively.
|
|
62
|
-
*/
|
|
63
|
-
export declare function edgeTerminalPlans(edge: DiagramLayoutEdge, fromNode: DiagramLayoutNode, toNode: DiagramLayoutNode): {
|
|
64
|
-
start: TerminalPlan;
|
|
65
|
-
end: TerminalPlan;
|
|
66
|
-
};
|
|
67
|
-
/**
|
|
68
|
-
* Land one diagram with its top-left at `origin`. The caller passes the
|
|
69
|
-
* precomputed layout (it needs the layout bounds to pick the origin, so the
|
|
70
|
-
* layout is computed once and shared). No-op on empty layouts.
|
|
71
|
-
*/
|
|
72
|
-
export declare function landDiagram(editor: Editor, landing: TlDiagramLanding, layout: DiagramLayout, origin: {
|
|
73
|
-
x: number;
|
|
74
|
-
y: number;
|
|
75
|
-
}): void;
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
import type { DiagramNodeShape, DiagramSpec } from '../../shared.js';
|
|
2
|
-
/** One laid-out node: local id, label, outline, top-left position, size. */
|
|
3
|
-
export interface DiagramLayoutNode {
|
|
4
|
-
id: string;
|
|
5
|
-
label: string;
|
|
6
|
-
shape: DiagramNodeShape;
|
|
7
|
-
x: number;
|
|
8
|
-
y: number;
|
|
9
|
-
w: number;
|
|
10
|
-
h: number;
|
|
11
|
-
}
|
|
12
|
-
/** A point in graph space (same origin as the layout nodes). */
|
|
13
|
-
export interface DiagramPoint {
|
|
14
|
-
x: number;
|
|
15
|
-
y: number;
|
|
16
|
-
}
|
|
17
|
-
/** One laid-out edge between node local ids, with dagre's routing hint. */
|
|
18
|
-
export interface DiagramLayoutEdge {
|
|
19
|
-
from: string;
|
|
20
|
-
to: string;
|
|
21
|
-
label?: string;
|
|
22
|
-
/**
|
|
23
|
-
* dagre's polyline in graph space. points[0] lies on the source node's
|
|
24
|
-
* outline and points[last] on the target's. Self loops carry an empty
|
|
25
|
-
* array: dagre cannot route them, and the landing layer falls back to
|
|
26
|
-
* center bindings (tldraw draws bound self loops natively).
|
|
27
|
-
*/
|
|
28
|
-
points: DiagramPoint[];
|
|
29
|
-
/**
|
|
30
|
-
* Where the label sits along the polyline, as an arc-length ratio in
|
|
31
|
-
* [0, 1] (tldraw's arrow labelPosition shares the ratio semantics). This
|
|
32
|
-
* is a best-effort initial estimate: tldraw applies the ratio to its own
|
|
33
|
-
* routed path, which may differ from dagre's polyline in the middle
|
|
34
|
-
* segments. The final label position is validated on the real canvas.
|
|
35
|
-
*/
|
|
36
|
-
labelPosition?: number;
|
|
37
|
-
}
|
|
38
|
-
export interface DiagramLayout {
|
|
39
|
-
nodes: DiagramLayoutNode[];
|
|
40
|
-
edges: DiagramLayoutEdge[];
|
|
41
|
-
width: number;
|
|
42
|
-
height: number;
|
|
43
|
-
/** Growth direction of the layout, needed by the landing layer to pick
|
|
44
|
-
* binding anchors (TB connects bottom→top edges, LR right→left edges). */
|
|
45
|
-
direction: 'TB' | 'LR';
|
|
46
|
-
}
|
|
47
|
-
/** Node size in canvas units (top-left anchored, like tldraw shape props). */
|
|
48
|
-
export interface DiagramSize {
|
|
49
|
-
w: number;
|
|
50
|
-
h: number;
|
|
51
|
-
}
|
|
52
|
-
/** Measured sizes fed into the pure layout function. */
|
|
53
|
-
export interface DiagramMeasurements {
|
|
54
|
-
/** node id → measured node size. Missing entries fall back to the default. */
|
|
55
|
-
nodes: ReadonlyMap<string, DiagramSize>;
|
|
56
|
-
/**
|
|
57
|
-
* edge list index → measured label size. Only edges carrying a label are
|
|
58
|
-
* present; dagre reserves rank space for these labels.
|
|
59
|
-
*/
|
|
60
|
-
edgeLabels?: ReadonlyMap<number, DiagramSize>;
|
|
61
|
-
}
|
|
62
|
-
/** Fallback size for nodes the caller did not measure (defensive only). */
|
|
63
|
-
export declare const DEFAULT_NODE_SIZE: DiagramSize;
|
|
64
|
-
/**
|
|
65
|
-
* Where a point sits along a polyline, as an arc-length ratio in [0, 1].
|
|
66
|
-
* The point is projected onto the nearest polyline segment. Degenerate
|
|
67
|
-
* polylines return 0.5.
|
|
68
|
-
*/
|
|
69
|
-
export declare function arcRatioAlongPolyline(points: readonly DiagramPoint[], target: DiagramPoint): number;
|
|
70
|
-
/**
|
|
71
|
-
* Lay out a diagram spec with coordinates relative to (0, 0). The layout is
|
|
72
|
-
* deterministic: same spec + same measurements always produce the same
|
|
73
|
-
* coordinates (dagre is seeded by insertion order, which we keep stable by
|
|
74
|
-
* iterating the spec's arrays as given).
|
|
75
|
-
*/
|
|
76
|
-
export declare function layoutDiagram(diagram: DiagramSpec, measurements: DiagramMeasurements): DiagramLayout;
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Measure diagram node/edge-label sizes with tldraw's own DOM text measuring.
|
|
3
|
-
*
|
|
4
|
-
* This is the "real" half of the measurement/layout split: the editor's
|
|
5
|
-
* TextManager renders text with the same font family, size, line height and
|
|
6
|
-
* wrap width the landed geo shapes will use, so RECTANGLE node sizes track
|
|
7
|
-
* the rendered label 1:1 (no character-width heuristics).
|
|
8
|
-
*
|
|
9
|
-
* The measure parameters mirror tldraw's internal geo-shape constants for
|
|
10
|
-
* our landed shapes (font 'sans', size 'm'): theme.fontSize * 1.375,
|
|
11
|
-
* theme.lineHeight, label padding 16.
|
|
12
|
-
*
|
|
13
|
-
* Non-rectangular outlines are APPROXIMATE, not 1:1. tldraw re-wraps the
|
|
14
|
-
* label against the SHAPE's width (shape w - padding), and we size the
|
|
15
|
-
* shape from the text measured at the pre-inflation wrap width — so after
|
|
16
|
-
* inflation the label re-wraps into fewer, wider lines. For short labels
|
|
17
|
-
* (single line at the wrap width) the geometry below is exact. For long
|
|
18
|
-
* wrapped labels the re-wrapped block can grow past the outline's inscribed
|
|
19
|
-
* rectangle and crowd the diamond's slanted edges / the ellipse's arc:
|
|
20
|
-
* greedy text wrapping scales with shape width while the inscribed rectangle
|
|
21
|
-
* only halves it, so there is no closed-form fix. The create_diagram tool
|
|
22
|
-
* prompt steers long text to rectangles and keeps diamond labels short;
|
|
23
|
-
* whether a real label fits is ultimately a visual check on the real canvas
|
|
24
|
-
* (see the diagram-verify harness), not something this module can promise.
|
|
25
|
-
* - diamond: a single-line text rect (tw, th) fits exactly when
|
|
26
|
-
* tw/w + th/h <= 1, so doubling the text size (+ padding) is exact for
|
|
27
|
-
* unwrapped labels.
|
|
28
|
-
* - ellipse: a single-line corner point fits exactly when
|
|
29
|
-
* tw²/w² + th²/h² <= 1, so a √2 factor (+ padding) is exact for
|
|
30
|
-
* unwrapped labels.
|
|
31
|
-
*/
|
|
32
|
-
import type { Editor } from 'tldraw';
|
|
33
|
-
import type { DiagramSpec } from '../../shared.js';
|
|
34
|
-
import type { DiagramMeasurements } from './diagram-layout.js';
|
|
35
|
-
/**
|
|
36
|
-
* Measure every node and edge label of a spec against the editor's live
|
|
37
|
-
* theme and fonts. Node sizes carry the outline inflation for diamond and
|
|
38
|
-
* ellipse; edge-label sizes let dagre reserve rank space for labels.
|
|
39
|
-
*/
|
|
40
|
-
export declare function measureDiagram(editor: Editor, diagram: DiagramSpec): DiagramMeasurements;
|
package/lib/types/diagram.d.ts
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* create_diagram: a structure-only tool whose results land on the workbench
|
|
3
|
-
* infinite canvas.
|
|
4
|
-
*
|
|
5
|
-
* The model outputs a declarative DSL (nodes + edges with local ids, never
|
|
6
|
-
* coordinates). The tool call succeeds immediately — exactly like image
|
|
7
|
-
* generation — and the diagram rides the same landing bus: an open canvas
|
|
8
|
-
* renders it at once, a closed one renders it the moment it opens. The canvas
|
|
9
|
-
* computes the layered layout, creates geo shapes, and binds every arrow to
|
|
10
|
-
* its endpoints so the user can drag nodes around with arrows following.
|
|
11
|
-
*/
|
|
12
|
-
import type { Context } from '@deepseek-ai/cordis';
|
|
13
|
-
import { type DiagramDirection, type DiagramEdgeSpec, type DiagramNodeSpec } from './shared.js';
|
|
14
|
-
/** Value returned by create_diagram and echoed into the tool-result schema. */
|
|
15
|
-
export interface CreateDiagramValue {
|
|
16
|
-
diagramId: string;
|
|
17
|
-
title: string;
|
|
18
|
-
direction: DiagramDirection;
|
|
19
|
-
nodeCount: number;
|
|
20
|
-
edgeCount: number;
|
|
21
|
-
}
|
|
22
|
-
/** Untrusted create_diagram arguments as they arrive from the model. */
|
|
23
|
-
export interface CreateDiagramArgs {
|
|
24
|
-
title?: unknown;
|
|
25
|
-
direction?: unknown;
|
|
26
|
-
nodes?: unknown;
|
|
27
|
-
edges?: unknown;
|
|
28
|
-
}
|
|
29
|
-
/** Register the create_diagram tool on a host context. */
|
|
30
|
-
export declare function registerDiagramTool(ctx: Context): void;
|
|
31
|
-
/**
|
|
32
|
-
* Validate untrusted create_diagram arguments into a DiagramSpec. Returns
|
|
33
|
-
* undefined for anything structurally unusable (no nodes, duplicate ids,
|
|
34
|
-
* edges pointing at unknown nodes, over the caps) — the tool then fails with
|
|
35
|
-
* an actionable message and the model can retry with a corrected diagram.
|
|
36
|
-
*/
|
|
37
|
-
export declare function diagramSpecFromArgs(args: CreateDiagramArgs): {
|
|
38
|
-
title?: string;
|
|
39
|
-
direction?: DiagramDirection;
|
|
40
|
-
nodes: DiagramNodeSpec[];
|
|
41
|
-
edges: DiagramEdgeSpec[];
|
|
42
|
-
} | undefined;
|