@goodandready/dsh-image-gen 0.12.0 → 0.12.2
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 +4 -4
- package/lib/index.js +6 -1
- package/lib/tools/character-sheet.js +2 -1
- package/lib/tools/diagram.js +2 -1
- package/lib/tools/pattern.js +2 -2
- package/lib/tools/processing-advanced.js +2 -2
- package/lib/tools/processing-basic.js +5 -5
- package/lib/tools/spritesheet.js +2 -2
- package/lib/tools/style-matrix.js +2 -2
- package/lib/tools/theme-pair.js +2 -1
- package/lib/tools/ui-asset.js +2 -2
- package/lib/tools/vision-ocr.js +2 -1
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -72,7 +72,7 @@ window.__ModuleLoader__.load({
|
|
|
72
72
|
} else if (typeof AbortController !== 'undefined') {
|
|
73
73
|
const ctrl = new AbortController()
|
|
74
74
|
timer = setTimeout(() => {
|
|
75
|
-
try { ctrl.abort(new Error('Request timeout')) } catch (_) {}
|
|
75
|
+
try { ctrl.abort(new Error('Request timeout')) } catch (_) { /* ignore abort race */ }
|
|
76
76
|
}, timeoutMs)
|
|
77
77
|
sig = ctrl.signal
|
|
78
78
|
}
|
|
@@ -82,7 +82,7 @@ window.__ModuleLoader__.load({
|
|
|
82
82
|
: (() => {
|
|
83
83
|
const ctrl = new AbortController()
|
|
84
84
|
timer = setTimeout(() => {
|
|
85
|
-
try { ctrl.abort(new Error('Request timeout')) } catch (_) {}
|
|
85
|
+
try { ctrl.abort(new Error('Request timeout')) } catch (_) { /* ignore abort race */ }
|
|
86
86
|
}, timeoutMs)
|
|
87
87
|
return ctrl.signal
|
|
88
88
|
})()
|
|
@@ -101,12 +101,12 @@ window.__ModuleLoader__.load({
|
|
|
101
101
|
if (typeof signal.addEventListener === 'function') {
|
|
102
102
|
signal.addEventListener('abort', onCallerAbort, { once: true })
|
|
103
103
|
removeCallerAbort = () => {
|
|
104
|
-
try { signal.removeEventListener('abort', onCallerAbort) } catch (_) {}
|
|
104
|
+
try { signal.removeEventListener('abort', onCallerAbort) } catch (_) { /* ignore listener cleanup */ }
|
|
105
105
|
}
|
|
106
106
|
}
|
|
107
107
|
}
|
|
108
108
|
timer = setTimeout(() => {
|
|
109
|
-
try { ctrl.abort(new Error('Request timeout')) } catch (_) {}
|
|
109
|
+
try { ctrl.abort(new Error('Request timeout')) } catch (_) { /* ignore abort race */ }
|
|
110
110
|
}, timeoutMs)
|
|
111
111
|
sig = ctrl.signal
|
|
112
112
|
}
|
package/lib/index.js
CHANGED
|
@@ -229,7 +229,7 @@ export function apply(ctx, rawConfig) {
|
|
|
229
229
|
if (typeof settingsSvc?.describe !== 'function') return null
|
|
230
230
|
try {
|
|
231
231
|
const row = settingsSvc.describe().find((r) => r?.ns === NS)
|
|
232
|
-
if (!row || row.status !==
|
|
232
|
+
if (!row || !row.value || (row.status !== undefined && row.status !== 'ready')) return null
|
|
233
233
|
return Config(structuredClone(plainConfig(row.value)))
|
|
234
234
|
} catch (_) {
|
|
235
235
|
return null
|
|
@@ -658,6 +658,11 @@ export function apply(ctx, rawConfig) {
|
|
|
658
658
|
|
|
659
659
|
// Reset loop guard when user sends a new message (#370)
|
|
660
660
|
if (typeof ctx.on === 'function') {
|
|
661
|
+
ctx.on('user/message', (session) => {
|
|
662
|
+
const sid = session?.id || session?.sessionId || session?.conversationId
|
|
663
|
+
if (sid) resetLoopGuard(sid)
|
|
664
|
+
else resetLoopGuard()
|
|
665
|
+
})
|
|
661
666
|
ctx.on('chat/message', (session) => {
|
|
662
667
|
if (session?.id) resetLoopGuard(session.id)
|
|
663
668
|
})
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { resolveInside } from '../security.js'
|
|
1
2
|
import { buildDualOutputMarkdown } from '../resolve-image.js'
|
|
2
3
|
// character-sheet.js — generate_character_sheet tool (#181, #358).
|
|
3
4
|
// Generates multi-angle character model sheets and turnarounds with visual consistency.
|
|
@@ -184,7 +185,7 @@ export function registerCharacterSheetTools(ctx, deps) {
|
|
|
184
185
|
|
|
185
186
|
const sessionCwd = execCtx?.agent?.session?.header?.cwd
|
|
186
187
|
const targetDir = cfg.outputDir || 'generated/images'
|
|
187
|
-
const outDir =
|
|
188
|
+
const outDir = resolveInside(sessionCwd || process.cwd(), targetDir)
|
|
188
189
|
await mkdir(outDir, { recursive: true })
|
|
189
190
|
diskPath = path.join(outDir, filename)
|
|
190
191
|
await writeFile(diskPath, Buffer.from(finalBytes))
|
package/lib/tools/diagram.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { resolveInside } from '../security.js'
|
|
1
2
|
// diagram.js — beautify_diagram tool (#185, #359).
|
|
2
3
|
// Transforms raw Mermaid / Graphviz diagrams into high-end 3D isometric architectural illustrations.
|
|
3
4
|
|
|
@@ -180,7 +181,7 @@ export function registerDiagramTools(ctx, deps) {
|
|
|
180
181
|
|
|
181
182
|
const sessionCwd = execCtx?.agent?.session?.header?.cwd
|
|
182
183
|
const targetDir = cfg.outputDir || 'generated/images'
|
|
183
|
-
const outDir =
|
|
184
|
+
const outDir = resolveInside(sessionCwd || process.cwd(), targetDir)
|
|
184
185
|
await mkdir(outDir, { recursive: true })
|
|
185
186
|
diskPath = path.join(outDir, filename)
|
|
186
187
|
await writeFile(diskPath, Buffer.from(finalBytes))
|
package/lib/tools/pattern.js
CHANGED
|
@@ -6,7 +6,7 @@ import path from 'node:path'
|
|
|
6
6
|
import { mkdir, writeFile } from 'node:fs/promises'
|
|
7
7
|
import { makeProviders, toLosslessJson, saveAttachmentSafe, sizeToPixels } from '../providers.js'
|
|
8
8
|
import { trackAndAssertLoopGuard } from '../loop-guard.js'
|
|
9
|
-
import { sanitizeErrorAndLogs } from '../security.js'
|
|
9
|
+
import { sanitizeErrorAndLogs, resolveInside } from '../security.js'
|
|
10
10
|
import {
|
|
11
11
|
buildSeamlessPrompt,
|
|
12
12
|
buildPatternCss,
|
|
@@ -95,7 +95,7 @@ export function registerPatternTools(ctx, deps) {
|
|
|
95
95
|
})
|
|
96
96
|
|
|
97
97
|
const sessionCwd = exec?.agent?.session?.header?.cwd
|
|
98
|
-
const outDir =
|
|
98
|
+
const outDir = resolveInside(sessionCwd || process.cwd(), cfg.outputDir || 'generated/images')
|
|
99
99
|
await mkdir(outDir, { recursive: true })
|
|
100
100
|
const filePath = path.join(outDir, name)
|
|
101
101
|
await writeFile(filePath, gen.bytes)
|
|
@@ -160,7 +160,7 @@ export function registerProcessingAdvancedTools(ctx, deps) {
|
|
|
160
160
|
const { attachment, localUrl } = await saveAttachmentSafe(ctx, { bytes: svgBuffer, mediaType: 'image/svg+xml', name })
|
|
161
161
|
|
|
162
162
|
const sessionCwd = exec?.agent?.session?.header?.cwd
|
|
163
|
-
const outDir =
|
|
163
|
+
const outDir = resolveInside(sessionCwd || process.cwd(), cfg.outputDir || 'generated/images')
|
|
164
164
|
await mkdir(outDir, { recursive: true })
|
|
165
165
|
const filePath = path.join(outDir, name)
|
|
166
166
|
await writeFile(filePath, svgBuffer)
|
|
@@ -330,7 +330,7 @@ export function registerProcessingAdvancedTools(ctx, deps) {
|
|
|
330
330
|
const { attachment, localUrl } = await saveAttachmentSafe(ctx, { bytes: svgBuffer, mediaType: 'image/svg+xml', name })
|
|
331
331
|
|
|
332
332
|
const sessionCwd = exec?.agent?.session?.header?.cwd
|
|
333
|
-
const outDir =
|
|
333
|
+
const outDir = resolveInside(sessionCwd || process.cwd(), cfg.outputDir || 'generated/images')
|
|
334
334
|
await mkdir(outDir, { recursive: true })
|
|
335
335
|
const filePath = path.join(outDir, name)
|
|
336
336
|
await writeFile(filePath, svgBuffer)
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
import { buildDualOutputMarkdown } from '../resolve-image.js'
|
|
18
18
|
import { assertBudgetAvailable, reserveSpend, recordSpend } from '../cost-meter.js'
|
|
19
19
|
import { trackAndAssertLoopGuard } from '../loop-guard.js'
|
|
20
|
-
import { sanitizeErrorAndLogs } from '../security.js'
|
|
20
|
+
import { sanitizeErrorAndLogs, resolveInside } from '../security.js'
|
|
21
21
|
|
|
22
22
|
export function registerProcessingTools(ctx, deps) {
|
|
23
23
|
const {
|
|
@@ -69,7 +69,7 @@ export function registerProcessingTools(ctx, deps) {
|
|
|
69
69
|
const name = `${stem}.png`
|
|
70
70
|
const { attachment, localUrl } = await saveAttachmentSafe(ctx, { bytes: res.bytes, mediaType: 'image/png', name })
|
|
71
71
|
const sessionCwd = exec?.agent?.session?.header?.cwd
|
|
72
|
-
const outDir =
|
|
72
|
+
const outDir = resolveInside(sessionCwd || process.cwd(), cfg.outputDir || 'generated/images')
|
|
73
73
|
await mkdir(outDir, { recursive: true })
|
|
74
74
|
const filePath = path.join(outDir, name)
|
|
75
75
|
await writeFile(filePath, res.bytes)
|
|
@@ -151,7 +151,7 @@ export function registerProcessingTools(ctx, deps) {
|
|
|
151
151
|
const name = `${stem}.png`
|
|
152
152
|
const { attachment, localUrl } = await saveAttachmentSafe(ctx, { bytes: res.bytes, mediaType: 'image/png', name })
|
|
153
153
|
const sessionCwd = exec?.agent?.session?.header?.cwd
|
|
154
|
-
const outDir =
|
|
154
|
+
const outDir = resolveInside(sessionCwd || process.cwd(), cfg.outputDir || 'generated/images')
|
|
155
155
|
await mkdir(outDir, { recursive: true })
|
|
156
156
|
const filePath = path.join(outDir, name)
|
|
157
157
|
await writeFile(filePath, res.bytes)
|
|
@@ -219,7 +219,7 @@ export function registerProcessingTools(ctx, deps) {
|
|
|
219
219
|
const stem = `${slugify(args.output_name || 'vector')}-${Date.now().toString(36)}`
|
|
220
220
|
const name = `${stem}.svg`
|
|
221
221
|
const sessionCwd = exec?.agent?.session?.header?.cwd
|
|
222
|
-
const outDir =
|
|
222
|
+
const outDir = resolveInside(sessionCwd || process.cwd(), cfg.outputDir || 'generated/images')
|
|
223
223
|
await mkdir(outDir, { recursive: true })
|
|
224
224
|
const filePath = path.join(outDir, name)
|
|
225
225
|
await writeFile(filePath, res.bytes)
|
|
@@ -302,7 +302,7 @@ export function registerProcessingTools(ctx, deps) {
|
|
|
302
302
|
const name = `${stem}.png`
|
|
303
303
|
const { attachment, localUrl } = await saveAttachmentSafe(ctx, { bytes: res.bytes, mediaType: 'image/png', name })
|
|
304
304
|
const sessionCwd = exec?.agent?.session?.header?.cwd
|
|
305
|
-
const outDir =
|
|
305
|
+
const outDir = resolveInside(sessionCwd || process.cwd(), cfg.outputDir || 'generated/images')
|
|
306
306
|
await mkdir(outDir, { recursive: true })
|
|
307
307
|
const filePath = path.join(outDir, name)
|
|
308
308
|
await writeFile(filePath, res.bytes)
|
package/lib/tools/spritesheet.js
CHANGED
|
@@ -6,7 +6,7 @@ import path from 'node:path'
|
|
|
6
6
|
import { mkdir, writeFile } from 'node:fs/promises'
|
|
7
7
|
import { makeProviders, toLosslessJson, saveAttachmentSafe } from '../providers.js'
|
|
8
8
|
import { trackAndAssertLoopGuard } from '../loop-guard.js'
|
|
9
|
-
import { sanitizeErrorAndLogs } from '../security.js'
|
|
9
|
+
import { sanitizeErrorAndLogs, resolveInside } from '../security.js'
|
|
10
10
|
import {
|
|
11
11
|
ANIMATION_PRESETS,
|
|
12
12
|
clampFrames,
|
|
@@ -112,7 +112,7 @@ export function registerSpritesheetTools(ctx, deps) {
|
|
|
112
112
|
})
|
|
113
113
|
|
|
114
114
|
const sessionCwd = exec?.agent?.session?.header?.cwd
|
|
115
|
-
const outDir =
|
|
115
|
+
const outDir = resolveInside(sessionCwd || process.cwd(), cfg.outputDir || 'generated/images')
|
|
116
116
|
await mkdir(outDir, { recursive: true })
|
|
117
117
|
const filePath = path.join(outDir, sheetName)
|
|
118
118
|
await writeFile(filePath, svgBuffer)
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { sanitizeErrorAndLogs } from '../security.js'
|
|
1
|
+
import { sanitizeErrorAndLogs, resolveInside } from '../security.js'
|
|
2
2
|
// style-matrix.js — generate_style_matrix tool (#286).
|
|
3
3
|
// Parallel 2×2 style matrix explorer with blind A/B compare and one-click preset selection.
|
|
4
4
|
|
|
@@ -154,7 +154,7 @@ export function registerStyleMatrixTools(ctx, deps) {
|
|
|
154
154
|
|
|
155
155
|
const sessionCwd = exec?.agent?.session?.header?.cwd
|
|
156
156
|
const targetDir = cfg.outputDir || 'generated/images'
|
|
157
|
-
const outDir =
|
|
157
|
+
const outDir = resolveInside(sessionCwd || process.cwd(), targetDir)
|
|
158
158
|
await mkdir(outDir, { recursive: true })
|
|
159
159
|
|
|
160
160
|
const tasks = activeStyles.map((styleName, idx) => async () => {
|
package/lib/tools/theme-pair.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { resolveInside } from '../security.js'
|
|
1
2
|
// theme-pair.js — generate_theme_pair tool (#189, #361).
|
|
2
3
|
// Generates complementary Light & Dark mode asset variants with synchronized compositions.
|
|
3
4
|
|
|
@@ -161,7 +162,7 @@ export function registerThemePairTools(ctx, deps) {
|
|
|
161
162
|
|
|
162
163
|
const sessionCwd = exec?.agent?.session?.header?.cwd
|
|
163
164
|
const targetDir = cfg.outputDir || 'generated/images'
|
|
164
|
-
const outDir =
|
|
165
|
+
const outDir = resolveInside(sessionCwd || process.cwd(), targetDir)
|
|
165
166
|
await mkdir(outDir, { recursive: true })
|
|
166
167
|
|
|
167
168
|
const slug = args.output_name ? slugify(args.output_name) : slugify(prompt).slice(0, 36)
|
package/lib/tools/ui-asset.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { sanitizeErrorAndLogs } from '../security.js'
|
|
1
|
+
import { sanitizeErrorAndLogs, resolveInside } from '../security.js'
|
|
2
2
|
// ui-asset.js — generate_ui_asset tool (#284).
|
|
3
3
|
// Specialized generator for UI icons, stickers, illustrations, and layout-aware banners with negative space.
|
|
4
4
|
|
|
@@ -221,7 +221,7 @@ export function registerUiAssetTools(ctx, deps) {
|
|
|
221
221
|
|
|
222
222
|
const sessionCwd = exec?.agent?.session?.header?.cwd
|
|
223
223
|
const targetDir = cfg.outputDir || 'generated/images'
|
|
224
|
-
const outDir =
|
|
224
|
+
const outDir = resolveInside(sessionCwd || process.cwd(), targetDir)
|
|
225
225
|
await mkdir(outDir, { recursive: true })
|
|
226
226
|
const filePath = path.join(outDir, filename)
|
|
227
227
|
await writeFile(filePath, finalBytes)
|
package/lib/tools/vision-ocr.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { resolveInside } from '../security.js'
|
|
1
2
|
// vision-ocr.js — replace_image_text tool (#180, #360).
|
|
2
3
|
// Grounding OCR, background inpainting, and typography re-rendering for visual localization.
|
|
3
4
|
|
|
@@ -295,7 +296,7 @@ export function registerVisionOcrTools(ctx, deps) {
|
|
|
295
296
|
const usedProvider = gen._fallback?.providerUsed || provider
|
|
296
297
|
const sessionCwd = execCtx?.agent?.session?.header?.cwd
|
|
297
298
|
const targetDir = cfg.outputDir || 'generated/images'
|
|
298
|
-
const outDir =
|
|
299
|
+
const outDir = resolveInside(sessionCwd || process.cwd(), targetDir)
|
|
299
300
|
await mkdir(outDir, { recursive: true })
|
|
300
301
|
const timestamp = Date.now()
|
|
301
302
|
const safeSlug = slugify(String(args.image || '').slice(0, 20)) || 'localized-image'
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@goodandready/dsh-image-gen",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.2",
|
|
4
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",
|