@dickpy/dsh-imagegen 1.0.2 → 1.0.3
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/README.md +4 -4
- package/lib/client.js +138 -107
- package/lib/client.js.map +1 -1
- package/lib/index.js +3 -1
- package/package.json +1 -1
- package/src/client/ImageGenPanel.tsx +22 -8
- package/src/client/SettingsCard.tsx +5 -0
- package/src/client/locales.ts +6 -0
- package/src/client/panel.module.css +40 -14
- package/src/client/settings-card.module.css +26 -0
- package/src/protocol.ts +3 -0
- package/src/updater.ts +2 -1
package/lib/index.js
CHANGED
|
@@ -13,6 +13,8 @@ import { spawn } from "node:child_process";
|
|
|
13
13
|
*/
|
|
14
14
|
/** Settings namespace this plugin owns (host settings seam + bridge). */
|
|
15
15
|
const IMAGEGEN_SETTINGS_NAMESPACE = "dsh-imagegen";
|
|
16
|
+
/** Published package version shared by the host updater and the client UI. */
|
|
17
|
+
const PLUGIN_VERSION = "1.0.3";
|
|
16
18
|
/** Same-origin route family (loopback-only, mirroring the dsh-ssh fence). */
|
|
17
19
|
const SETTINGS_API = {
|
|
18
20
|
describe: "/api/dsh-imagegen/settings/describe",
|
|
@@ -438,7 +440,7 @@ async function readHistoryImage(file) {
|
|
|
438
440
|
//#region src/updater.ts
|
|
439
441
|
/** GitHub Release discovery and explicit, user-triggered plugin updates. */
|
|
440
442
|
/** Keep this in sync with package.json for each published release. */
|
|
441
|
-
const CURRENT_VERSION =
|
|
443
|
+
const CURRENT_VERSION = PLUGIN_VERSION;
|
|
442
444
|
const PACKAGE_NAME = "@dickpy/dsh-imagegen";
|
|
443
445
|
const RELEASES_URL = "https://api.github.com/repos/dickpy/dsh-imagegen/releases/latest";
|
|
444
446
|
const CHECK_TIMEOUT_MS = 1e4;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dickpy/dsh-imagegen",
|
|
3
3
|
"description": "AI 生图 (image generation) plugin for the dsh web GUI: text-to-image and image-to-image through a configurable OpenAI-compatible endpoint (gpt-image-2 / gpt-image-1 / dall-e-3), with a settings card for api_url / api_key and a sidebar entry opening a split-pane generation studio.",
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.3",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
7
7
|
"exports": {
|
|
@@ -50,6 +50,13 @@ function useConfig(scope: ImageGenScope): ImageGenConfig | undefined {
|
|
|
50
50
|
return value
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
+
/** Track the redacted api-key presence bit exposed by the settings bridge. */
|
|
54
|
+
function useKeySet(scope: ImageGenScope): boolean {
|
|
55
|
+
const [keySet, setKeySet] = useState(scope.getKeySetSnapshot())
|
|
56
|
+
useEffect(() => scope.subscribeKeySet(() => { setKeySet(scope.getKeySetSnapshot()) }), [scope])
|
|
57
|
+
return keySet
|
|
58
|
+
}
|
|
59
|
+
|
|
53
60
|
/** Tick a seconds counter while `running`. */
|
|
54
61
|
function useElapsed(running: boolean, startedAt: number | null): number {
|
|
55
62
|
const [elapsed, setElapsed] = useState(0)
|
|
@@ -108,6 +115,8 @@ export function ImageGenPanel(props: {
|
|
|
108
115
|
const enabled = config?.enabled ?? true
|
|
109
116
|
const apiUrl = config?.apiUrl ?? ''
|
|
110
117
|
const configured = apiUrl.trim() !== ''
|
|
118
|
+
const keySet = useKeySet(scope)
|
|
119
|
+
const connected = enabled && configured && keySet
|
|
111
120
|
|
|
112
121
|
const [mode, setMode] = useState<GenerateMode>('text')
|
|
113
122
|
const [prompt, setPrompt] = useState('')
|
|
@@ -316,16 +325,21 @@ export function ImageGenPanel(props: {
|
|
|
316
325
|
return (
|
|
317
326
|
<div className={css.panel}>
|
|
318
327
|
<header className={css.panelHeader}>
|
|
319
|
-
<
|
|
320
|
-
|
|
328
|
+
<span className={css.panelHeading}>
|
|
329
|
+
<h2 className={css.panelTitle}>{tt('panel.title')}</h2>
|
|
330
|
+
<span className={css.panelSubtitle}>{tt('panel.subtitle')}</span>
|
|
331
|
+
</span>
|
|
332
|
+
<button
|
|
333
|
+
type="button"
|
|
334
|
+
className={css.connectionStatus}
|
|
335
|
+
data-connected={connected ? 'true' : 'false'}
|
|
336
|
+
aria-label={tt(connected ? 'connection.connected' : 'connection.disconnected')}
|
|
337
|
+
>
|
|
338
|
+
<span className={css.connectionDot} aria-hidden="true" />
|
|
339
|
+
{tt(connected ? 'connection.connected' : 'connection.disconnected')}
|
|
340
|
+
</button>
|
|
321
341
|
</header>
|
|
322
342
|
|
|
323
|
-
{!enabled
|
|
324
|
-
? <div className={css.banner} data-kind="warn">{tt('config.disabled')}</div>
|
|
325
|
-
: !configured
|
|
326
|
-
? <div className={css.banner} data-kind="warn">{tt('config.missing')}</div>
|
|
327
|
-
: <div className={css.banner} data-kind="ok">{tt('config.configured', { url: apiUrl })}</div>}
|
|
328
|
-
|
|
329
343
|
{update !== null ? (
|
|
330
344
|
<div className={css.updateBanner} data-kind={updateResult === 'success' ? 'ok' : 'warn'}>
|
|
331
345
|
<span className={css.updateText}>
|
|
@@ -11,6 +11,7 @@ import type { InjectFace, PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-cli
|
|
|
11
11
|
import { createSnapshotStore, type SnapshotStore } from '@deepseek-ai/dsh-client-runtime/client'
|
|
12
12
|
import { CardForm, booleanField, secretField, textField, type CardActions, type CardShell, type FieldState as CardFieldState } from './settings-form.ts'
|
|
13
13
|
import type { ImageGenScope } from './settings-scope.ts'
|
|
14
|
+
import { PLUGIN_VERSION } from '../protocol.ts'
|
|
14
15
|
import css from './settings-card.module.css'
|
|
15
16
|
|
|
16
17
|
/** The fields this card edits (the namespace's full schema). */
|
|
@@ -161,6 +162,10 @@ export function ImageGenSettingsCard(props: ImageGenSettingsCardProps) {
|
|
|
161
162
|
? (
|
|
162
163
|
<div className={css.body}>
|
|
163
164
|
{!state.writable ? <p className={css.readOnly} role="status">{t('settings.readOnly')}</p> : null}
|
|
165
|
+
<div className={css.versionRow}>
|
|
166
|
+
<span className={css.versionLabel}>{t('settings.currentVersion')}</span>
|
|
167
|
+
<code className={css.versionValue}>v{PLUGIN_VERSION}</code>
|
|
168
|
+
</div>
|
|
164
169
|
<ValueField
|
|
165
170
|
id="dsh-imagegen-settings-apikey"
|
|
166
171
|
label={t('settings.apiKey')}
|
package/src/client/locales.ts
CHANGED
|
@@ -76,6 +76,8 @@ export const zh = {
|
|
|
76
76
|
'config.missing': '尚未配置 API:请前往「设置 → 插件 → 可配置」为 AI 生图填写 api_url 与 api_key。',
|
|
77
77
|
'config.configured': '已连接 {url}',
|
|
78
78
|
'config.disabled': '插件已停用,请在设置中重新启用。',
|
|
79
|
+
'connection.connected': '已连接',
|
|
80
|
+
'connection.disconnected': '未连接',
|
|
79
81
|
// plugin update
|
|
80
82
|
'update.available': '检测到新版本:{version}',
|
|
81
83
|
'update.install': '在线更新',
|
|
@@ -86,6 +88,7 @@ export const zh = {
|
|
|
86
88
|
// settings card
|
|
87
89
|
'settings.title': 'AI 生图(dsh-imagegen)',
|
|
88
90
|
'settings.description': '配置图像生成 API 地址与密钥',
|
|
91
|
+
'settings.currentVersion': '当前版本',
|
|
89
92
|
'settings.apiUrl': 'API 地址(api_url)',
|
|
90
93
|
'settings.apiUrlHint': 'OpenAI 兼容接口基址,如 https://api.openai.com/v1;将自动拼接 /images/generations 与 /images/edits',
|
|
91
94
|
'settings.apiKey': 'API 密钥(api_key)',
|
|
@@ -178,6 +181,8 @@ export const en: Record<keyof typeof zh, string> = {
|
|
|
178
181
|
'config.missing': 'API not configured: open "Settings → Plugins → Configurable" and fill in api_url and api_key for AI Image.',
|
|
179
182
|
'config.configured': 'Connected to {url}',
|
|
180
183
|
'config.disabled': 'The plugin is disabled — re-enable it in Settings.',
|
|
184
|
+
'connection.connected': 'Connected',
|
|
185
|
+
'connection.disconnected': 'Disconnected',
|
|
181
186
|
'update.available': 'A new version is available: {version}',
|
|
182
187
|
'update.install': 'Update online',
|
|
183
188
|
'update.installing': 'Updating…',
|
|
@@ -186,6 +191,7 @@ export const en: Record<keyof typeof zh, string> = {
|
|
|
186
191
|
'update.release': 'View Release',
|
|
187
192
|
'settings.title': 'AI Image (dsh-imagegen)',
|
|
188
193
|
'settings.description': 'Configure the image generation API endpoint and key',
|
|
194
|
+
'settings.currentVersion': 'Current version',
|
|
189
195
|
'settings.apiUrl': 'API URL (api_url)',
|
|
190
196
|
'settings.apiUrlHint': 'OpenAI-compatible base URL, e.g. https://api.openai.com/v1; /images/generations and /images/edits are appended',
|
|
191
197
|
'settings.apiKey': 'API Key (api_key)',
|
|
@@ -121,10 +121,18 @@ html[data-dsh-imagegen-active]:not([data-dsh-taskboard-active]):not([data-dsh-ss
|
|
|
121
121
|
}
|
|
122
122
|
|
|
123
123
|
.panelHeader {
|
|
124
|
+
display: flex;
|
|
125
|
+
align-items: center;
|
|
126
|
+
justify-content: space-between;
|
|
127
|
+
gap: 12px;
|
|
128
|
+
flex: none;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
.panelHeading {
|
|
124
132
|
display: flex;
|
|
125
133
|
align-items: baseline;
|
|
126
134
|
gap: 10px;
|
|
127
|
-
|
|
135
|
+
min-width: 0;
|
|
128
136
|
}
|
|
129
137
|
|
|
130
138
|
.panelTitle {
|
|
@@ -143,27 +151,35 @@ html[data-dsh-imagegen-active]:not([data-dsh-taskboard-active]):not([data-dsh-ss
|
|
|
143
151
|
text-overflow: ellipsis;
|
|
144
152
|
}
|
|
145
153
|
|
|
146
|
-
/* ---
|
|
154
|
+
/* --- connection status and update notice -------------------------------------- */
|
|
147
155
|
|
|
148
|
-
.
|
|
156
|
+
.connectionStatus {
|
|
157
|
+
display: inline-flex;
|
|
158
|
+
align-items: center;
|
|
159
|
+
gap: 6px;
|
|
149
160
|
flex: none;
|
|
150
|
-
|
|
161
|
+
height: 28px;
|
|
162
|
+
padding: 0 10px;
|
|
163
|
+
border: 1px solid var(--dsw-alias-label-error);
|
|
164
|
+
border-radius: 8px;
|
|
165
|
+
background: transparent;
|
|
166
|
+
color: var(--dsw-alias-label-error);
|
|
167
|
+
font: inherit;
|
|
151
168
|
font-size: 12px;
|
|
152
|
-
line-height: 1
|
|
153
|
-
|
|
154
|
-
border: 1px solid var(--dsw-alias-border-l2);
|
|
155
|
-
color: var(--dsw-alias-label-secondary);
|
|
156
|
-
overflow-wrap: anywhere;
|
|
169
|
+
line-height: 1;
|
|
170
|
+
white-space: nowrap;
|
|
157
171
|
}
|
|
158
172
|
|
|
159
|
-
.
|
|
160
|
-
color: var(--dsw-alias-state-success-primary);
|
|
173
|
+
.connectionStatus[data-connected='true'] {
|
|
161
174
|
border-color: var(--dsw-alias-state-success-primary);
|
|
175
|
+
color: var(--dsw-alias-state-success-primary);
|
|
162
176
|
}
|
|
163
177
|
|
|
164
|
-
.
|
|
165
|
-
|
|
166
|
-
|
|
178
|
+
.connectionDot {
|
|
179
|
+
width: 6px;
|
|
180
|
+
height: 6px;
|
|
181
|
+
border-radius: 50%;
|
|
182
|
+
background: currentColor;
|
|
167
183
|
}
|
|
168
184
|
|
|
169
185
|
.updateBanner {
|
|
@@ -205,6 +221,16 @@ html[data-dsh-imagegen-active]:not([data-dsh-taskboard-active]):not([data-dsh-ss
|
|
|
205
221
|
}
|
|
206
222
|
|
|
207
223
|
@media (max-width: 700px) {
|
|
224
|
+
.panelHeader {
|
|
225
|
+
align-items: flex-start;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
.panelHeading {
|
|
229
|
+
align-items: flex-start;
|
|
230
|
+
flex-direction: column;
|
|
231
|
+
gap: 2px;
|
|
232
|
+
}
|
|
233
|
+
|
|
208
234
|
.updateBanner {
|
|
209
235
|
align-items: flex-start;
|
|
210
236
|
flex-direction: column;
|
|
@@ -95,6 +95,32 @@
|
|
|
95
95
|
padding-bottom: 8px;
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
+
.versionRow {
|
|
99
|
+
display: flex;
|
|
100
|
+
align-items: center;
|
|
101
|
+
justify-content: space-between;
|
|
102
|
+
gap: 12px;
|
|
103
|
+
padding: 12px 0;
|
|
104
|
+
border-bottom: 1px solid var(--dsw-alias-border-l2);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.versionLabel {
|
|
108
|
+
font-size: 13px;
|
|
109
|
+
font-weight: 500;
|
|
110
|
+
line-height: 1.5;
|
|
111
|
+
color: var(--dsw-alias-label-primary);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
.versionValue {
|
|
115
|
+
padding: 1px 8px;
|
|
116
|
+
border-radius: 999px;
|
|
117
|
+
background: var(--dsw-alias-bg-module-platform);
|
|
118
|
+
color: var(--dsw-alias-label-secondary);
|
|
119
|
+
font-family: var(--dsw-font-family-mono, monospace);
|
|
120
|
+
font-size: 12px;
|
|
121
|
+
line-height: 1.5;
|
|
122
|
+
}
|
|
123
|
+
|
|
98
124
|
/* --- fields (mirror of the official plugin-config fields) --------------------- */
|
|
99
125
|
|
|
100
126
|
.field {
|
package/src/protocol.ts
CHANGED
|
@@ -7,6 +7,9 @@
|
|
|
7
7
|
/** Settings namespace this plugin owns (host settings seam + bridge). */
|
|
8
8
|
export const IMAGEGEN_SETTINGS_NAMESPACE = 'dsh-imagegen'
|
|
9
9
|
|
|
10
|
+
/** Published package version shared by the host updater and the client UI. */
|
|
11
|
+
export const PLUGIN_VERSION = '1.0.3'
|
|
12
|
+
|
|
10
13
|
/** Same-origin route family (loopback-only, mirroring the dsh-ssh fence). */
|
|
11
14
|
export const SETTINGS_API = {
|
|
12
15
|
describe: '/api/dsh-imagegen/settings/describe',
|
package/src/updater.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
/** GitHub Release discovery and explicit, user-triggered plugin updates. */
|
|
2
2
|
|
|
3
3
|
import { spawn, type ChildProcess } from 'node:child_process'
|
|
4
|
+
import { PLUGIN_VERSION } from './protocol.ts'
|
|
4
5
|
|
|
5
6
|
/** Keep this in sync with package.json for each published release. */
|
|
6
|
-
export const CURRENT_VERSION =
|
|
7
|
+
export const CURRENT_VERSION = PLUGIN_VERSION
|
|
7
8
|
export const PACKAGE_NAME = '@dickpy/dsh-imagegen'
|
|
8
9
|
export const RELEASES_URL = 'https://api.github.com/repos/dickpy/dsh-imagegen/releases/latest'
|
|
9
10
|
|