@dickpy/dsh-imagegen 1.0.5 → 1.0.7

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/index.js CHANGED
@@ -14,7 +14,7 @@ import { spawn } from "node:child_process";
14
14
  /** Settings namespace this plugin owns (host settings seam + bridge). */
15
15
  const IMAGEGEN_SETTINGS_NAMESPACE = "dsh-imagegen";
16
16
  /** Published package version shared by the host updater and the client UI. */
17
- const PLUGIN_VERSION = "1.0.5";
17
+ const PLUGIN_VERSION = "1.0.7";
18
18
  /** Same-origin route family (loopback-only, mirroring the dsh-ssh fence). */
19
19
  const SETTINGS_API = {
20
20
  describe: "/api/dsh-imagegen/settings/describe",
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.5",
4
+ "version": "1.0.7",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
7
7
  "exports": {
@@ -27,15 +27,15 @@
27
27
  },
28
28
  "devDependencies": {
29
29
  "@deepseek-ai/cordis": "^4.0.1",
30
- "@deepseek-ai/dsh-client-connection": "^0.1.0-rc.6",
31
- "@deepseek-ai/dsh-client-locale": "^0.1.0-rc.6",
32
- "@deepseek-ai/dsh-client-runtime": "^0.1.0-rc.6",
33
- "@deepseek-ai/dsh-client-ui-primitives": "^0.1.0-rc.6",
34
- "@deepseek-ai/dsh-client-ui-settings": "^0.1.0-rc.6",
35
- "@deepseek-ai/dsh-client-ui-slots": "^0.1.0-rc.6",
36
- "@deepseek-ai/dsh-host-webserver": "^0.1.0-rc.6",
37
- "@deepseek-ai/dsh-settings": "^0.1.0-rc.6",
38
- "@deepseek-ai/dsh-system-prompt": "^0.1.0-rc.6",
30
+ "@deepseek-ai/dsh-client-connection": "0.1.0-rc.7",
31
+ "@deepseek-ai/dsh-client-locale": "0.1.0-rc.7",
32
+ "@deepseek-ai/dsh-client-runtime": "0.1.0-rc.7",
33
+ "@deepseek-ai/dsh-client-ui-primitives": "0.1.0-rc.7",
34
+ "@deepseek-ai/dsh-client-ui-settings": "0.1.0-rc.7",
35
+ "@deepseek-ai/dsh-client-ui-slots": "0.1.0-rc.7",
36
+ "@deepseek-ai/dsh-host-webserver": "0.1.0-rc.7",
37
+ "@deepseek-ai/dsh-settings": "0.1.0-rc.7",
38
+ "@deepseek-ai/dsh-system-prompt": "0.1.0-rc.7",
39
39
  "@types/node": "^22.20.0",
40
40
  "@types/react": "~18.3.1",
41
41
  "@types/react-dom": "^18.3.5",
@@ -64,4 +64,4 @@
64
64
  "watch": "tsdown --watch",
65
65
  "typecheck": "tsc --noEmit"
66
66
  }
67
- }
67
+ }
@@ -1,127 +1,126 @@
1
- /**
2
- * Browser-half entry for the dsh-imagegen plugin — runs inside the dsh web
3
- * GUI.
4
- *
5
- * Registers the dsh-imagegen locale dictionaries, binds the plugin's own
6
- * settings scope (its bridge routes serve the namespace the official rc.6
7
- * allowlist would refuse), registers the settings card into the Web UI plugin
8
- * group slot, and mounts the two DOM surfaces: the sidebar entry row (toggles
9
- * the panel) and the generation studio in the center column. Failure policy:
10
- * DOM mounting problems are logged, never thrown — the web shell fails the
11
- * whole boot when a plugin apply throws, and an external plugin must not take
12
- * the GUI down.
13
- */
14
- import type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client'
15
- import type { ConnectionHandle } from '@deepseek-ai/dsh-client-connection/client'
16
- // Type-only: pulls the locale plugin's Context merge (ctx.locale).
17
- import type {} from '@deepseek-ai/dsh-client-locale/client'
18
- // Type-only: pulls the LocaleNamespaceMap merge table.
19
- import type {} from '@deepseek-ai/dsh-client-ui-slots'
20
- import { ImageGenApi } from './api.ts'
21
- import { ImageGenController } from './controller.ts'
22
- import { tt } from './helpers.ts'
23
- import { en, zh, type ImageGenKey } from './locales.ts'
24
- import { mountPanel } from './mount.tsx'
25
- import { mountSidebarEntry } from './sidebar-entry.ts'
26
- import { ImageGenSettingsCard, ImageGenSettingsCardController } from './SettingsCard.tsx'
27
- import { bindImageGenScope, type ImageGenScope } from './settings-scope.ts'
28
-
29
- /** Locale namespace this plugin owns. */
30
- const NS = 'dsh-imagegen'
31
-
32
- declare module '@deepseek-ai/dsh-client-ui-slots' {
33
- interface LocaleNamespaceMap {
34
- /** dsh-imagegen surface copy. */
35
- 'dsh-imagegen': ImageGenKey
36
- }
37
-
38
- interface SlotMap {
39
- /**
40
- * The official plugin-configuration slot the Settings → Plugins →
41
- * Configurable tab declares and renders. This card registers there as its
42
- * own standalone card — independent of the dsh-web-ui family group — so
43
- * this plugin never reads as part of that family. Spelled here with the
44
- * same shape so this package can register without depending on the
45
- * sibling UI package.
46
- */
47
- 'settings.plugin.item': { kind: 'list'; scope: 'root'; owner: ImageGenPluginItemOwnerProps }
48
- }
49
- }
50
-
51
- /** Owner share of a plugin card (the section supplies nothing). */
52
- export interface ImageGenPluginItemOwnerProps {
53
- /** Marker field: card owner props are intentionally empty. */
54
- children?: never
55
- }
56
-
57
- /** Required services (fiber inject waiting — the runtime must be up first). */
58
- export const inject = ['slots', 'locale', 'connection']
59
-
60
- /**
61
- * Mount the studio, its sidebar entry, and the settings card.
62
- * @param ctx - client root context (services: slots, locale, connection).
63
- */
64
- export function apply(ctx: ClientContext): void {
65
- ctx.effect(() => ctx.locale.register(NS, { zh, en }), 'dsh-imagegen: dictionaries')
66
-
67
- const connection = ctx.get('connection') as ConnectionHandle | undefined
68
- const loopback = connection?.isLoopback === true
69
- // The bridge routes are loopback-fenced; remote browsers get an unavailable
70
- // scope (the card explains the gap) instead of failing fetches.
71
- const scope: ImageGenScope = bindImageGenScope(loopback
72
- ? (input, init) => fetch(input, init)
73
- : () => { throw new Error('settings bridge is loopback-only') })
74
-
75
- // Re-read the scope whenever the connection resets (same invalidation the
76
- // official settings binder wires).
77
- ctx.effect(() => {
78
- const disposers = [
79
- ctx.on('connection/reset', () => { void scope.load() }),
80
- ]
81
- return () => { for (const dispose of disposers) dispose() }
82
- }, 'dsh-imagegen: settings scope invalidation')
83
-
84
- // Plugin configuration card: one staged form over the `dsh-imagegen` scope,
85
- // registered into the official plugin-configuration slot (Settings →
86
- // Plugins → Configurable) as a standalone card.
87
- const settingsCard = new ImageGenSettingsCardController(scope)
88
- ctx.slots.inject('settings.plugin.item', () => ctx.slots.register({
89
- name: 'settings.plugin.item',
90
- id: 'imagegen',
91
- order: 30,
92
- locale: NS,
93
- inject: () => settingsCard.inject(),
94
- }, ImageGenSettingsCard))
95
-
96
- // The sidebar entry and studio mount once the settings scope settles; while
97
- // the scope is still loading, the composition default is unknown, so nothing
98
- // mounts yet. Only an unavailable scope falls back to the default (enabled).
99
- let uiDisposer: (() => void) | undefined
100
- const mountUi = (): void => {
101
- if (uiDisposer !== undefined) return
102
- const controller = new ImageGenController()
103
- const api = new ImageGenApi()
104
- const disposers: Array<() => void> = []
105
- try {
106
- disposers.push(mountSidebarEntry(controller, tt('entry.label'), tt('entry.tooltip')))
107
- disposers.push(mountPanel(controller, api, scope))
108
- } catch (error) {
109
- // DOM failures degrade the studio, never the GUI.
110
- console.warn('[dsh-imagegen] mount failed:', error)
111
- }
112
- uiDisposer = () => {
113
- for (const dispose of disposers.splice(0)) dispose()
114
- uiDisposer = undefined
115
- }
116
- }
117
- const syncEnabled = (): void => {
118
- const snapshot = scope.getSnapshot()
119
- const enabled = snapshot.status === 'ready'
120
- ? snapshot.value?.enabled ?? true
121
- : snapshot.status === 'unavailable'
122
- if (enabled) mountUi()
123
- else uiDisposer?.()
124
- }
125
- scope.subscribe(syncEnabled)
126
- syncEnabled()
127
- }
1
+ /**
2
+ * Browser-half entry for the dsh-imagegen plugin — runs inside the dsh web
3
+ * GUI.
4
+ *
5
+ * Registers the dsh-imagegen locale dictionaries, binds the plugin's own
6
+ * settings scope (its bridge routes serve the namespace the official rc.6
7
+ * allowlist would refuse), registers the settings card into the Web UI plugin
8
+ * group slot, and mounts the two DOM surfaces: the sidebar entry row (toggles
9
+ * the panel) and the generation studio in the center column. Failure policy:
10
+ * DOM mounting problems are logged, never thrown — the web shell fails the
11
+ * whole boot when a plugin apply throws, and an external plugin must not take
12
+ * the GUI down.
13
+ */
14
+ import type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client'
15
+ import type { ConnectionHandle } from '@deepseek-ai/dsh-client-connection/client'
16
+ // Type-only: pulls the locale plugin's Context merge (ctx.locale).
17
+ import type {} from '@deepseek-ai/dsh-client-locale/client'
18
+ // Type-only: pulls the LocaleNamespaceMap merge table.
19
+ import type {} from '@deepseek-ai/dsh-client-ui-slots'
20
+ import { ImageGenApi } from './api.ts'
21
+ import { ImageGenController } from './controller.ts'
22
+ import { tt } from './helpers.ts'
23
+ import { en, zh, type ImageGenKey } from './locales.ts'
24
+ import { mountPanel } from './mount.tsx'
25
+ import { mountSidebarEntry } from './sidebar-entry.ts'
26
+ import { ImageGenSettingsCard, ImageGenSettingsCardController } from './SettingsCard.tsx'
27
+ import { bindImageGenScope, type ImageGenScope } from './settings-scope.ts'
28
+
29
+ /** Locale namespace this plugin owns. */
30
+ const NS = 'dsh-imagegen'
31
+
32
+ declare module '@deepseek-ai/dsh-client-ui-slots' {
33
+ interface LocaleNamespaceMap {
34
+ /** dsh-imagegen surface copy. */
35
+ 'dsh-imagegen': ImageGenKey
36
+ }
37
+
38
+ interface SlotMap {
39
+ /**
40
+ * The official plugin-configuration slot the Settings → Plugins →
41
+ * Configurable tab declares and renders. This card registers there as its
42
+ * own standalone card — independent of the dsh-web-ui family group — so
43
+ * this plugin never reads as part of that family. Spelled here with the
44
+ * same shape so this package can register without depending on the
45
+ * sibling UI package.
46
+ */
47
+ 'settings.plugin.item': { kind: 'keyed'; scope: 'root'; owner: ImageGenPluginItemOwnerProps }
48
+ }
49
+ }
50
+
51
+ /** Owner share of a plugin card (the section supplies nothing). */
52
+ export interface ImageGenPluginItemOwnerProps {
53
+ /** Marker field: card owner props are intentionally empty. */
54
+ children?: never
55
+ }
56
+
57
+ /** Required services (fiber inject waiting — the runtime must be up first). */
58
+ export const inject = ['slots', 'locale', 'connection']
59
+
60
+ /**
61
+ * Mount the studio, its sidebar entry, and the settings card.
62
+ * @param ctx - client root context (services: slots, locale, connection).
63
+ */
64
+ export function apply(ctx: ClientContext): void {
65
+ ctx.effect(() => ctx.locale.register(NS, { zh, en }), 'dsh-imagegen: dictionaries')
66
+
67
+ const connection = ctx.get('connection') as ConnectionHandle | undefined
68
+ const loopback = connection?.isLoopback === true
69
+ // The bridge routes are loopback-fenced; remote browsers get an unavailable
70
+ // scope (the card explains the gap) instead of failing fetches.
71
+ const scope: ImageGenScope = bindImageGenScope(loopback
72
+ ? (input, init) => fetch(input, init)
73
+ : () => { throw new Error('settings bridge is loopback-only') })
74
+
75
+ // Re-read the scope whenever the connection resets (same invalidation the
76
+ // official settings binder wires).
77
+ ctx.effect(() => {
78
+ const disposers = [
79
+ ctx.on('connection/reset', () => { void scope.load() }),
80
+ ]
81
+ return () => { for (const dispose of disposers) dispose() }
82
+ }, 'dsh-imagegen: settings scope invalidation')
83
+
84
+ // Plugin configuration card: one staged form over the `dsh-imagegen` scope,
85
+ // registered into the official plugin-configuration slot (Settings →
86
+ // Plugins → Configurable) as a standalone card.
87
+ const settingsCard = new ImageGenSettingsCardController(scope)
88
+ ctx.slots.inject('settings.plugin.item', () => ctx.slots.register({
89
+ name: 'settings.plugin.item',
90
+ key: 'dsh-imagegen',
91
+ locale: NS,
92
+ inject: () => settingsCard.inject(),
93
+ }, ImageGenSettingsCard))
94
+
95
+ // The sidebar entry and studio mount once the settings scope settles; while
96
+ // the scope is still loading, the composition default is unknown, so nothing
97
+ // mounts yet. Only an unavailable scope falls back to the default (enabled).
98
+ let uiDisposer: (() => void) | undefined
99
+ const mountUi = (): void => {
100
+ if (uiDisposer !== undefined) return
101
+ const controller = new ImageGenController()
102
+ const api = new ImageGenApi()
103
+ const disposers: Array<() => void> = []
104
+ try {
105
+ disposers.push(mountSidebarEntry(controller, tt('entry.label'), tt('entry.tooltip')))
106
+ disposers.push(mountPanel(controller, api, scope))
107
+ } catch (error) {
108
+ // DOM failures degrade the studio, never the GUI.
109
+ console.warn('[dsh-imagegen] mount failed:', error)
110
+ }
111
+ uiDisposer = () => {
112
+ for (const dispose of disposers.splice(0)) dispose()
113
+ uiDisposer = undefined
114
+ }
115
+ }
116
+ const syncEnabled = (): void => {
117
+ const snapshot = scope.getSnapshot()
118
+ const enabled = snapshot.status === 'ready'
119
+ ? snapshot.value?.enabled ?? true
120
+ : snapshot.status === 'unavailable'
121
+ if (enabled) mountUi()
122
+ else uiDisposer?.()
123
+ }
124
+ scope.subscribe(syncEnabled)
125
+ syncEnabled()
126
+ }
package/src/protocol.ts CHANGED
@@ -8,7 +8,7 @@
8
8
  export const IMAGEGEN_SETTINGS_NAMESPACE = 'dsh-imagegen'
9
9
 
10
10
  /** Published package version shared by the host updater and the client UI. */
11
- export const PLUGIN_VERSION = '1.0.5'
11
+ export const PLUGIN_VERSION = '1.0.7'
12
12
 
13
13
  /** Same-origin route family (loopback-only, mirroring the dsh-ssh fence). */
14
14
  export const SETTINGS_API = {