@goodandready/dsh-image-gen 0.11.14 → 0.11.16

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 (3) hide show
  1. package/lib/client.js +15 -11
  2. package/lib/index.js +46 -40
  3. package/package.json +9 -9
package/lib/client.js CHANGED
@@ -3235,18 +3235,22 @@ window.__ModuleLoader__.load({
3235
3235
  )
3236
3236
  )
3237
3237
 
3238
- // Settings card item — sole slot registration for settings card (#208, #300)
3239
- registerSlotWhenReady('settings.plugin.item', () =>
3240
- ctx.slots.register(
3241
- {
3242
- name: 'settings.plugin.item',
3243
- key: SETTINGS_NS,
3244
- locale: NS,
3245
- inject: () => cardOnce().inject(),
3246
- },
3247
- (props) => react.createElement(ErrorBoundary, null, react.createElement(FalSettingsCard, props))
3238
+ // Settings card — settings.plugin.item was retired before DSH 0.1.7-rc.2, so
3239
+ // the card was mounted on no seat at all and had no configuration UI. Both
3240
+ // seats below exist in 0.1.7-rc.2 and 0.2.0 (#208, #300).
3241
+ for (const seat of ['plugins.item', 'plugins.row.config']) {
3242
+ registerSlotWhenReady(seat, () =>
3243
+ ctx.slots.register(
3244
+ {
3245
+ name: seat,
3246
+ key: SETTINGS_NS,
3247
+ locale: NS,
3248
+ inject: () => cardOnce().inject(),
3249
+ },
3250
+ (props) => react.createElement(ErrorBoundary, null, react.createElement(FalSettingsCard, props))
3251
+ )
3248
3252
  )
3249
- )
3253
+ }
3250
3254
  }
3251
3255
  // -------------------------------------------------------------- Asset Vault View (#159, #304)
3252
3256
  function AssetVaultView(props) {
package/lib/index.js CHANGED
@@ -73,9 +73,6 @@ export const name = '@goodandready/dsh-image-gen'
73
73
  /** Settings namespace the Web card edits. */
74
74
  const NS = 'dsh-image-gen'
75
75
 
76
- // The plugin was previously named dsh-fal-image-gen. Any settings saved
77
- // under the legacy namespace are read as fallback and migrated once on startup.
78
- const LEGACY_NS = 'dsh-fal-image-gen'
79
76
  export const inject = ['tools', 'attachments', 'credentials', 'webServer', 'settings', 'llm', 'systemPrompt']
80
77
 
81
78
  export function slugify(input) {
@@ -105,24 +102,6 @@ export async function resolveApiKey(ctx, ref) {
105
102
  return ''
106
103
  }
107
104
 
108
- /**
109
- * If the user configured the plugin under its old name (dsh-fal-image-gen), copy
110
- * those settings forward into dsh-image-gen once so existing keys and choices
111
- * are preserved. Only touches values that the user actually modified.
112
- */
113
- function migrateLegacySettings(sctx, scope) {
114
- try {
115
- if (!scope || typeof scope.update !== 'function') return
116
- const legacyScope = sctx.settings.get?.(LEGACY_NS)
117
- if (!legacyScope) return
118
- const legacy = legacyScope.get?.()
119
- if (!legacy || typeof legacy !== 'object') return
120
- scope.update(structuredClone(legacy))
121
- } catch (_) {
122
- // Settings migration skipped — fallback to default schema configuration
123
- }
124
- }
125
-
126
105
  /** Collect text chunks from llm.stream iterator.
127
106
  * Canonical implementation lives in prompt-enhancer.js; re-exported for backwards compat. */
128
107
  export { collectText } from './prompt-enhancer.js'
@@ -197,29 +176,56 @@ export function apply(ctx, rawConfig) {
197
176
  return undefined
198
177
  }
199
178
 
179
+ let settingsSvc = null
180
+
181
+ const readServedConfig = () => {
182
+ if (typeof settingsSvc?.describe !== 'function') return null
183
+ try {
184
+ const row = settingsSvc.describe().find((r) => r?.ns === NS)
185
+ if (!row || row.status !== 'ready' || !row.value) return null
186
+ return Config(structuredClone(plainConfig(row.value)))
187
+ } catch (_) {
188
+ return null
189
+ }
190
+ }
191
+
192
+ const adoptServed = () => {
193
+ const next = readServedConfig()
194
+ if (!next) return false
195
+ currentLiveConfig = next
196
+ getConfig = () => currentLiveConfig || config
197
+ return true
198
+ }
199
+
200
200
  ctx.inject(['settings'], (sctx) => {
201
- if (typeof sctx.settings?.register === 'function') {
202
- const scope = sctx.settings.register(NS, Config, { base: config })
203
- settingsApi = scope
204
- migrateLegacySettings(sctx, scope)
205
- getConfig = () => (scope?.get?.() ?? config) ?? config
206
- sctx.effect(() => () => {
207
- getConfig = () => config
208
- settingsApi = undefined
209
- })
210
- } else {
211
- settingsApi = createSettingsAdapter(sctx.settings)
212
- if (typeof sctx.settings?.describe === 'function') {
201
+ settingsSvc = sctx.settings
202
+ settingsApi = createSettingsAdapter(sctx.settings)
203
+ adoptServed()
204
+ sctx.effect(() => () => {
205
+ getConfig = () => config
206
+ settingsApi = undefined
207
+ })
208
+ })
209
+
210
+ // DSH 0.1.7-rc.2 and 0.2.0 share this contract: the Loader re-merges volatile
211
+ // profile entries in place and announces it with loader/volatile-update.
212
+ // settings.register exists in neither release, so the branch that used it was
213
+ // dead code and the card's writes never reached the host.
214
+ if (typeof ctx.on === 'function') {
215
+ try {
216
+ ctx.on('loader/volatile-update', () => {
213
217
  try {
214
- sctx.settings.describe(NS, Config)
215
- } catch (_) { /* bestEffort */ }
216
- }
217
- sctx.effect(() => () => {
218
- getConfig = () => config
219
- settingsApi = undefined
218
+ adoptServed()
219
+ } catch (err) {
220
+ const msg = `[dsh-image-gen] settings refresh failed: ${err?.message || err}`
221
+ if (typeof ctx.logger?.warn === 'function') ctx.logger.warn(msg)
222
+ }
220
223
  })
224
+ } catch (err) {
225
+ const msg = `[dsh-image-gen] volatile-update subscription failed: ${err?.message || err}`
226
+ if (typeof ctx.logger?.warn === 'function') ctx.logger.warn(msg)
221
227
  }
222
- })
228
+ }
223
229
 
224
230
  // Serve the stored image so the tool card can show it inline.
225
231
  const imageHandler = async (req, res) => {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@goodandready/dsh-image-gen",
3
- "version": "0.11.14",
4
- "description": "Image generation for DeepSeek Harness: a generate_image tool with pluggable providers \u2014 the FAL queue, any OpenAI-compatible images API, or a ChatGPT/Grok subscription with no API key at all. The picture is shown inline in the conversation; the model receives either a link (works with any chat model) or the image itself (needs dsh-vision-bridge or a vision-capable model).",
3
+ "version": "0.11.16",
4
+ "description": "Image generation for DeepSeek Harness: a generate_image tool with pluggable providers — the FAL queue, any OpenAI-compatible images API, or a ChatGPT/Grok subscription with no API key at all. The picture is shown inline in the conversation; the model receives either a link (works with any chat model) or the image itself (needs dsh-vision-bridge or a vision-capable model).",
5
5
  "keywords": [
6
6
  "deepseek-harness",
7
7
  "dsh",
@@ -59,13 +59,13 @@
59
59
  },
60
60
  "peerDependencies": {
61
61
  "@deepseek-ai/cordis": "^4.0.1",
62
- "@deepseek-ai/dsh-tools": "^0.1.0-rc.6",
63
- "@deepseek-ai/dsh-attachment": "^0.1.0-rc.6",
64
- "@deepseek-ai/dsh-credentials": "^0.1.0-rc.6",
65
- "@deepseek-ai/dsh-host-webserver": "^0.1.0-rc.6",
66
- "@deepseek-ai/dsh-settings": "^0.1.0-rc.6",
67
- "@deepseek-ai/dsh-llm": "^0.1.0-rc.6",
68
- "@deepseek-ai/dsh-system-prompt": "^0.1.0-rc.6",
62
+ "@deepseek-ai/dsh-tools": "^0.1.7-rc.2 || ^0.2.0-rc.1",
63
+ "@deepseek-ai/dsh-attachment": "^0.1.7-rc.2 || ^0.2.0-rc.1",
64
+ "@deepseek-ai/dsh-credentials": "^0.1.7-rc.2 || ^0.2.0-rc.1",
65
+ "@deepseek-ai/dsh-host-webserver": "^0.1.7-rc.2 || ^0.2.0-rc.1",
66
+ "@deepseek-ai/dsh-settings": "^0.1.7-rc.2 || ^0.2.0-rc.1",
67
+ "@deepseek-ai/dsh-llm": "^0.1.7-rc.2 || ^0.2.0-rc.1",
68
+ "@deepseek-ai/dsh-system-prompt": "^0.1.7-rc.2 || ^0.2.0-rc.1",
69
69
  "@deepseek-ai/schemastery": "^3.18.1"
70
70
  },
71
71
  "scripts": {