@dickpy/dsh-imagegen 1.4.0 → 1.5.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 +201 -201
- package/README.md +270 -124
- package/cordis.patch.yml +8 -8
- package/docs/images/ecommerce-mode.png +0 -0
- package/docs/images/image-generation-studio-three-column.png +0 -0
- package/docs/images/imagegen-overview.png +0 -0
- package/docs/videos/agent-chat-edit.gif +0 -0
- package/docs/videos/agent-chat-edit.mp4 +0 -0
- package/lib/client.js +1859 -420
- package/lib/client.js.map +1 -1
- package/lib/index.js +327 -112
- package/package.json +69 -68
- package/src/agent-image-tools.ts +447 -418
- package/src/client/ImageGenPanel.tsx +1242 -348
- package/src/client/SettingsCard.tsx +936 -936
- package/src/client/TemplateLibrary.tsx +336 -336
- package/src/client/api.ts +203 -193
- package/src/client/channels-form.ts +263 -263
- package/src/client/controller.ts +46 -46
- package/src/client/conversation-sync.ts +14 -14
- package/src/client/css-modules.d.ts +5 -5
- package/src/client/helpers.ts +33 -33
- package/src/client/image-toolview.module.css +73 -73
- package/src/client/image-toolview.tsx +18 -18
- package/src/client/index.ts +22 -22
- package/src/client/locales.ts +156 -28
- package/src/client/mount.tsx +117 -117
- package/src/client/panel.module.css +1243 -455
- package/src/client/settings-card.module.css +1023 -1023
- package/src/client/settings-form.ts +336 -336
- package/src/client/settings-scope.ts +298 -298
- package/src/client/sidebar-entry.ts +190 -190
- package/src/client/templates.module.css +453 -453
- package/src/edit-image-command.ts +110 -0
- package/src/engine.ts +520 -520
- package/src/gallery-store.ts +306 -286
- package/src/generation-runtime.ts +84 -79
- package/src/history-store.ts +270 -250
- package/src/image-format.ts +11 -11
- package/src/image-models.ts +19 -19
- package/src/index.ts +337 -318
- package/src/model-catalog.ts +115 -115
- package/src/presets.ts +71 -71
- package/src/prompt-enhancer.ts +137 -137
- package/src/protocol.ts +380 -338
- package/src/routes.ts +964 -916
- package/src/task-queue.ts +113 -113
- package/src/templates/cases.json +10196 -10196
- package/src/templates-store.ts +278 -278
- package/src/updater.ts +117 -117
- package/docs/images/agent-chat-edit.png +0 -0
- package/docs/images/agent-chat-generate.png +0 -0
- package/docs/images/agent-chat-poster-workflow.png +0 -0
package/src/client/mount.tsx
CHANGED
|
@@ -15,23 +15,23 @@
|
|
|
15
15
|
* and both get the `position: relative` base in panel.module.css.
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
|
-
import type { ISessions } from '@deepseek-ai/dsh-client-runtime/client'
|
|
19
|
-
import { createRoot, type Root } from 'react-dom/client'
|
|
18
|
+
import type { ISessions } from '@deepseek-ai/dsh-client-runtime/client'
|
|
19
|
+
import { createRoot, type Root } from 'react-dom/client'
|
|
20
20
|
import type { ImageGenApi } from './api.ts'
|
|
21
21
|
import type { ImageGenController } from './controller.ts'
|
|
22
22
|
import { ImageGenPanel } from './ImageGenPanel.tsx'
|
|
23
|
-
import type { ImageGenScope } from './settings-scope.ts'
|
|
24
|
-
import type { ConversationService } from './conversation-sync.ts'
|
|
23
|
+
import type { ImageGenScope } from './settings-scope.ts'
|
|
24
|
+
import type { ConversationService } from './conversation-sync.ts'
|
|
25
25
|
import css from './panel.module.css'
|
|
26
26
|
|
|
27
27
|
/** The injected panel container (kept in the DOM, hidden when inactive). */
|
|
28
28
|
export const PANEL_VIEW_SELECTOR = '[data-dsh-imagegen-view]'
|
|
29
29
|
|
|
30
|
-
const CONVERSATION_COLUMN_SELECTOR = '[data-pane="conversation"], [class*="centerCol"]'
|
|
31
|
-
const ACTIVE_ATTR = 'data-dsh-imagegen-active'
|
|
32
|
-
const RESIZER_SELECTOR = '[data-dsh-imagegen-chat-resizer]'
|
|
33
|
-
const CHAT_WIDTH_STORAGE_KEY = 'dsh-imagegen:chat-width'
|
|
34
|
-
const CHAT_MIN_WIDTH = 320
|
|
30
|
+
const CONVERSATION_COLUMN_SELECTOR = '[data-pane="conversation"], [class*="centerCol"]'
|
|
31
|
+
const ACTIVE_ATTR = 'data-dsh-imagegen-active'
|
|
32
|
+
const RESIZER_SELECTOR = '[data-dsh-imagegen-chat-resizer]'
|
|
33
|
+
const CHAT_WIDTH_STORAGE_KEY = 'dsh-imagegen:chat-width'
|
|
34
|
+
const CHAT_MIN_WIDTH = 320
|
|
35
35
|
/** Sibling panels' activation attributes, removed when this panel opens. */
|
|
36
36
|
const OTHER_ACTIVE_ATTRS = ['data-dsh-taskboard-active', 'data-dsh-ssh-active']
|
|
37
37
|
/** Cross-plugin activation event; detail is the activating panel name. */
|
|
@@ -39,82 +39,82 @@ const ACTIVATE_EVENT = 'dsh-panel-activate'
|
|
|
39
39
|
const PANEL_NAME = 'imagegen'
|
|
40
40
|
|
|
41
41
|
/** Find the center column, or undefined while the frame is not mounted. */
|
|
42
|
-
function conversationColumn(): HTMLElement | undefined {
|
|
43
|
-
return document.querySelector<HTMLElement>(CONVERSATION_COLUMN_SELECTOR) ?? undefined
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
function readChatWidth(): number | undefined {
|
|
47
|
-
try {
|
|
48
|
-
const raw = window.localStorage.getItem(CHAT_WIDTH_STORAGE_KEY)
|
|
49
|
-
if (raw === null) return undefined
|
|
50
|
-
const value = Number(raw)
|
|
51
|
-
return Number.isFinite(value) && value >= CHAT_MIN_WIDTH ? value : undefined
|
|
52
|
-
} catch {
|
|
53
|
-
return undefined
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
function writeChatWidth(value: number): void {
|
|
58
|
-
try {
|
|
59
|
-
window.localStorage.setItem(CHAT_WIDTH_STORAGE_KEY, String(Math.round(value)))
|
|
60
|
-
} catch {
|
|
61
|
-
// Private browsing and embedded shells may disable localStorage.
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
function applyChatWidth(column: HTMLElement, clientX: number): void {
|
|
66
|
-
const bounds = column.getBoundingClientRect()
|
|
67
|
-
const max = Math.max(CHAT_MIN_WIDTH, bounds.width * 0.7)
|
|
68
|
-
const width = Math.min(max, Math.max(CHAT_MIN_WIDTH, bounds.right - clientX))
|
|
69
|
-
column.style.setProperty('--dsh-imagegen-chat-width', `${Math.round(width)}px`)
|
|
70
|
-
writeChatWidth(width)
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/** Create the visible handle that separates the image workspace and chat. */
|
|
74
|
-
function createChatResizer(column: HTMLElement): HTMLDivElement {
|
|
75
|
-
const resizer = document.createElement('div')
|
|
76
|
-
resizer.dataset.dshImagegenChatResizer = ''
|
|
77
|
-
resizer.className = css.chatResizer
|
|
78
|
-
resizer.setAttribute('role', 'separator')
|
|
79
|
-
resizer.setAttribute('aria-orientation', 'vertical')
|
|
80
|
-
resizer.setAttribute('aria-label', '调整对话区域宽度')
|
|
81
|
-
resizer.tabIndex = 0
|
|
82
|
-
|
|
83
|
-
const saved = readChatWidth()
|
|
84
|
-
if (saved !== undefined) column.style.setProperty('--dsh-imagegen-chat-width', `${saved}px`)
|
|
85
|
-
|
|
86
|
-
const onPointerDown = (event: PointerEvent): void => {
|
|
87
|
-
if (event.button !== 0) return
|
|
88
|
-
event.preventDefault()
|
|
89
|
-
resizer.setPointerCapture?.(event.pointerId)
|
|
90
|
-
const onMove = (move: PointerEvent): void => { applyChatWidth(column, move.clientX) }
|
|
91
|
-
const onUp = (): void => {
|
|
92
|
-
window.removeEventListener('pointermove', onMove)
|
|
93
|
-
window.removeEventListener('pointerup', onUp)
|
|
94
|
-
window.removeEventListener('pointercancel', onUp)
|
|
95
|
-
resizer.releasePointerCapture?.(event.pointerId)
|
|
96
|
-
document.documentElement.style.removeProperty('cursor')
|
|
97
|
-
document.documentElement.style.removeProperty('user-select')
|
|
98
|
-
}
|
|
99
|
-
window.addEventListener('pointermove', onMove)
|
|
100
|
-
window.addEventListener('pointerup', onUp)
|
|
101
|
-
window.addEventListener('pointercancel', onUp)
|
|
102
|
-
document.documentElement.style.setProperty('cursor', 'col-resize')
|
|
103
|
-
document.documentElement.style.setProperty('user-select', 'none')
|
|
104
|
-
}
|
|
105
|
-
const onKeyDown = (event: KeyboardEvent): void => {
|
|
106
|
-
if (event.key !== 'ArrowLeft' && event.key !== 'ArrowRight') return
|
|
107
|
-
event.preventDefault()
|
|
108
|
-
const bounds = column.getBoundingClientRect()
|
|
109
|
-
const current = column.style.getPropertyValue('--dsh-imagegen-chat-width')
|
|
110
|
-
const currentWidth = Number.parseFloat(current) || bounds.width * 0.36
|
|
111
|
-
const delta = event.key === 'ArrowLeft' ? -24 : 24
|
|
112
|
-
applyChatWidth(column, bounds.right - currentWidth - delta)
|
|
113
|
-
}
|
|
114
|
-
resizer.addEventListener('pointerdown', onPointerDown)
|
|
115
|
-
resizer.addEventListener('keydown', onKeyDown)
|
|
116
|
-
return resizer
|
|
117
|
-
}
|
|
42
|
+
function conversationColumn(): HTMLElement | undefined {
|
|
43
|
+
return document.querySelector<HTMLElement>(CONVERSATION_COLUMN_SELECTOR) ?? undefined
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function readChatWidth(): number | undefined {
|
|
47
|
+
try {
|
|
48
|
+
const raw = window.localStorage.getItem(CHAT_WIDTH_STORAGE_KEY)
|
|
49
|
+
if (raw === null) return undefined
|
|
50
|
+
const value = Number(raw)
|
|
51
|
+
return Number.isFinite(value) && value >= CHAT_MIN_WIDTH ? value : undefined
|
|
52
|
+
} catch {
|
|
53
|
+
return undefined
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function writeChatWidth(value: number): void {
|
|
58
|
+
try {
|
|
59
|
+
window.localStorage.setItem(CHAT_WIDTH_STORAGE_KEY, String(Math.round(value)))
|
|
60
|
+
} catch {
|
|
61
|
+
// Private browsing and embedded shells may disable localStorage.
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function applyChatWidth(column: HTMLElement, clientX: number): void {
|
|
66
|
+
const bounds = column.getBoundingClientRect()
|
|
67
|
+
const max = Math.max(CHAT_MIN_WIDTH, bounds.width * 0.7)
|
|
68
|
+
const width = Math.min(max, Math.max(CHAT_MIN_WIDTH, bounds.right - clientX))
|
|
69
|
+
column.style.setProperty('--dsh-imagegen-chat-width', `${Math.round(width)}px`)
|
|
70
|
+
writeChatWidth(width)
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** Create the visible handle that separates the image workspace and chat. */
|
|
74
|
+
function createChatResizer(column: HTMLElement): HTMLDivElement {
|
|
75
|
+
const resizer = document.createElement('div')
|
|
76
|
+
resizer.dataset.dshImagegenChatResizer = ''
|
|
77
|
+
resizer.className = css.chatResizer
|
|
78
|
+
resizer.setAttribute('role', 'separator')
|
|
79
|
+
resizer.setAttribute('aria-orientation', 'vertical')
|
|
80
|
+
resizer.setAttribute('aria-label', '调整对话区域宽度')
|
|
81
|
+
resizer.tabIndex = 0
|
|
82
|
+
|
|
83
|
+
const saved = readChatWidth()
|
|
84
|
+
if (saved !== undefined) column.style.setProperty('--dsh-imagegen-chat-width', `${saved}px`)
|
|
85
|
+
|
|
86
|
+
const onPointerDown = (event: PointerEvent): void => {
|
|
87
|
+
if (event.button !== 0) return
|
|
88
|
+
event.preventDefault()
|
|
89
|
+
resizer.setPointerCapture?.(event.pointerId)
|
|
90
|
+
const onMove = (move: PointerEvent): void => { applyChatWidth(column, move.clientX) }
|
|
91
|
+
const onUp = (): void => {
|
|
92
|
+
window.removeEventListener('pointermove', onMove)
|
|
93
|
+
window.removeEventListener('pointerup', onUp)
|
|
94
|
+
window.removeEventListener('pointercancel', onUp)
|
|
95
|
+
resizer.releasePointerCapture?.(event.pointerId)
|
|
96
|
+
document.documentElement.style.removeProperty('cursor')
|
|
97
|
+
document.documentElement.style.removeProperty('user-select')
|
|
98
|
+
}
|
|
99
|
+
window.addEventListener('pointermove', onMove)
|
|
100
|
+
window.addEventListener('pointerup', onUp)
|
|
101
|
+
window.addEventListener('pointercancel', onUp)
|
|
102
|
+
document.documentElement.style.setProperty('cursor', 'col-resize')
|
|
103
|
+
document.documentElement.style.setProperty('user-select', 'none')
|
|
104
|
+
}
|
|
105
|
+
const onKeyDown = (event: KeyboardEvent): void => {
|
|
106
|
+
if (event.key !== 'ArrowLeft' && event.key !== 'ArrowRight') return
|
|
107
|
+
event.preventDefault()
|
|
108
|
+
const bounds = column.getBoundingClientRect()
|
|
109
|
+
const current = column.style.getPropertyValue('--dsh-imagegen-chat-width')
|
|
110
|
+
const currentWidth = Number.parseFloat(current) || bounds.width * 0.36
|
|
111
|
+
const delta = event.key === 'ArrowLeft' ? -24 : 24
|
|
112
|
+
applyChatWidth(column, bounds.right - currentWidth - delta)
|
|
113
|
+
}
|
|
114
|
+
resizer.addEventListener('pointerdown', onPointerDown)
|
|
115
|
+
resizer.addEventListener('keydown', onKeyDown)
|
|
116
|
+
return resizer
|
|
117
|
+
}
|
|
118
118
|
|
|
119
119
|
/**
|
|
120
120
|
* Mount the panel React tree into the center column and bind its visibility
|
|
@@ -124,40 +124,40 @@ function createChatResizer(column: HTMLElement): HTMLDivElement {
|
|
|
124
124
|
* @param scope - the settings scope (config status banner).
|
|
125
125
|
* @returns disposer unmounting the tree and restoring the column.
|
|
126
126
|
*/
|
|
127
|
-
export function mountPanel(
|
|
128
|
-
controller: ImageGenController,
|
|
129
|
-
api: ImageGenApi,
|
|
130
|
-
scope: ImageGenScope,
|
|
131
|
-
services: {
|
|
132
|
-
sessions?: ISessions
|
|
133
|
-
conversation?: ConversationService
|
|
134
|
-
} = {},
|
|
135
|
-
): () => void {
|
|
136
|
-
let root: Root | undefined
|
|
137
|
-
let container: HTMLDivElement | undefined
|
|
138
|
-
let resizer: HTMLDivElement | undefined
|
|
127
|
+
export function mountPanel(
|
|
128
|
+
controller: ImageGenController,
|
|
129
|
+
api: ImageGenApi,
|
|
130
|
+
scope: ImageGenScope,
|
|
131
|
+
services: {
|
|
132
|
+
sessions?: ISessions
|
|
133
|
+
conversation?: ConversationService
|
|
134
|
+
} = {},
|
|
135
|
+
): () => void {
|
|
136
|
+
let root: Root | undefined
|
|
137
|
+
let container: HTMLDivElement | undefined
|
|
138
|
+
let resizer: HTMLDivElement | undefined
|
|
139
139
|
|
|
140
140
|
const ensure = (): void => {
|
|
141
141
|
if (container !== undefined) {
|
|
142
142
|
if (container.isConnected) return
|
|
143
143
|
// The conversation pane was replaced; drop the stale tree and remount.
|
|
144
|
-
root?.unmount()
|
|
145
|
-
root = undefined
|
|
146
|
-
container.remove()
|
|
147
|
-
container = undefined
|
|
148
|
-
resizer?.remove()
|
|
149
|
-
resizer = undefined
|
|
144
|
+
root?.unmount()
|
|
145
|
+
root = undefined
|
|
146
|
+
container.remove()
|
|
147
|
+
container = undefined
|
|
148
|
+
resizer?.remove()
|
|
149
|
+
resizer = undefined
|
|
150
150
|
}
|
|
151
151
|
const column = conversationColumn()
|
|
152
152
|
if (column === undefined) return
|
|
153
153
|
container = document.createElement('div')
|
|
154
154
|
container.dataset.dshImagegenView = ''
|
|
155
|
-
container.className = css.view
|
|
156
|
-
column.appendChild(container)
|
|
157
|
-
root = createRoot(container)
|
|
158
|
-
root.render(<ImageGenPanel api={api} scope={scope} {...services} />)
|
|
159
|
-
resizer = column.querySelector<HTMLDivElement>(RESIZER_SELECTOR) ?? createChatResizer(column)
|
|
160
|
-
if (resizer.parentElement !== column) column.appendChild(resizer)
|
|
155
|
+
container.className = css.view
|
|
156
|
+
column.appendChild(container)
|
|
157
|
+
root = createRoot(container)
|
|
158
|
+
root.render(<ImageGenPanel api={api} scope={scope} {...services} />)
|
|
159
|
+
resizer = column.querySelector<HTMLDivElement>(RESIZER_SELECTOR) ?? createChatResizer(column)
|
|
160
|
+
if (resizer.parentElement !== column) column.appendChild(resizer)
|
|
161
161
|
}
|
|
162
162
|
|
|
163
163
|
// The frame mounts after boot settlement; watch for the column's arrival.
|
|
@@ -203,11 +203,11 @@ export function mountPanel(
|
|
|
203
203
|
waitObserver.disconnect()
|
|
204
204
|
unsubscribe()
|
|
205
205
|
document.documentElement.removeAttribute(ACTIVE_ATTR)
|
|
206
|
-
root?.unmount()
|
|
207
|
-
root = undefined
|
|
208
|
-
container?.remove()
|
|
209
|
-
container = undefined
|
|
210
|
-
resizer?.remove()
|
|
211
|
-
resizer = undefined
|
|
212
|
-
}
|
|
213
|
-
}
|
|
206
|
+
root?.unmount()
|
|
207
|
+
root = undefined
|
|
208
|
+
container?.remove()
|
|
209
|
+
container = undefined
|
|
210
|
+
resizer?.remove()
|
|
211
|
+
resizer = undefined
|
|
212
|
+
}
|
|
213
|
+
}
|