dsh-comfyui-canvas 0.1.6 → 0.1.8
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
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
> [中文](README.zh.md) · English
|
|
4
4
|
|
|
5
5
|
[](LICENSE)
|
|
6
|
-
[](https://github.com/wbin0001/dsh-comfyui-canvas/releases)
|
|
7
7
|
[](https://github.com/wbin0001/dsh-comfyui-canvas)
|
|
8
8
|
[](https://github.com/DeepSeek-Harness/DSH)
|
|
9
9
|
[](https://github.com/comfyanonymous/ComfyUI)
|
package/README.zh.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
> 中文 · [English](README.md)
|
|
4
4
|
|
|
5
5
|
[](LICENSE)
|
|
6
|
-
[](https://github.com/wbin0001/dsh-comfyui-canvas/releases)
|
|
7
7
|
[](https://github.com/wbin0001/dsh-comfyui-canvas)
|
|
8
8
|
[](https://github.com/DeepSeek-Harness/DSH)
|
|
9
9
|
[](https://github.com/comfyanonymous/ComfyUI)
|
package/lib/client.js
CHANGED
|
@@ -952,10 +952,16 @@ function ComfyUISettingsRow(props) {
|
|
|
952
952
|
);
|
|
953
953
|
}
|
|
954
954
|
|
|
955
|
-
var inject = ["slots"
|
|
955
|
+
var inject = ["slots"];
|
|
956
956
|
|
|
957
957
|
function apply(ctx) {
|
|
958
|
-
|
|
958
|
+
// 2026-09-24: 核心 #4587 移除了客户端 settingsScope 服务,且 cordis ctx 代理对
|
|
959
|
+
// 未注入服务的属性访问(ctx.settingsScope)会直接抛 "cannot get property...
|
|
960
|
+
// without inject",导致客户端 apply 失败。改用 ctx.get()(缺失返回 undefined)。
|
|
961
|
+
var settingsScopeService = typeof ctx.get === "function" ? ctx.get("settingsScope") : undefined;
|
|
962
|
+
var scope = settingsScopeService && typeof settingsScopeService.bind === "function"
|
|
963
|
+
? settingsScopeService.bind({ namespace: NAMESPACE })
|
|
964
|
+
: undefined;
|
|
959
965
|
// 画布顶栏「重启 / 关闭 ComfyUI」按钮 → 写 settings.comfyControl,
|
|
960
966
|
// host watcher 执行 kill / restart(结果由可达性探测反映到状态圆点)。
|
|
961
967
|
document.addEventListener("dsh-comfyui-control", function (e) {
|
|
@@ -966,7 +972,7 @@ function apply(ctx) {
|
|
|
966
972
|
});
|
|
967
973
|
// 让画布 iframe 使用设置里的地址(并跟随变更)。
|
|
968
974
|
var syncConfig = function () {
|
|
969
|
-
var snap = scope.getSnapshot();
|
|
975
|
+
var snap = scope ? scope.getSnapshot() : undefined;
|
|
970
976
|
var v = snap && snap.value;
|
|
971
977
|
var base = v && typeof v.baseUrl === "string" && v.baseUrl
|
|
972
978
|
? v.baseUrl : DEFAULT_BASE;
|
|
@@ -984,7 +990,7 @@ function apply(ctx) {
|
|
|
984
990
|
// 实时应用右侧面板宽度(发布 CSS 变量,分屏挤压样式引用)。
|
|
985
991
|
applyRailWidth(v?.railWidth != null ? v.railWidth : DEFAULT_RAIL);
|
|
986
992
|
};
|
|
987
|
-
scope.subscribe(syncConfig);
|
|
993
|
+
if (scope) scope.subscribe(syncConfig);
|
|
988
994
|
|
|
989
995
|
// 全局看门狗:保证分屏标记与真实分屏态一致,杜绝 data-dsh-split-on 残留。
|
|
990
996
|
// 挤压规则只在 html[data-dsh-split-on="1"] 时生效;一旦残留打上该属性,
|
|
@@ -998,7 +1004,7 @@ function apply(ctx) {
|
|
|
998
1004
|
return tab ? (tab.textContent || "").trim() : "";
|
|
999
1005
|
};
|
|
1000
1006
|
var enforceSplitMarker = function () {
|
|
1001
|
-
var snap = scope.getSnapshot();
|
|
1007
|
+
var snap = scope ? scope.getSnapshot() : undefined;
|
|
1002
1008
|
var v = snap && snap.value ? snap.value : {};
|
|
1003
1009
|
var map = v.splitEnabledBySession || {};
|
|
1004
1010
|
var anyEnabled = Object.keys(map).some(function (k) { return map[k] === true; });
|
|
@@ -1026,7 +1032,7 @@ function apply(ctx) {
|
|
|
1026
1032
|
}
|
|
1027
1033
|
};
|
|
1028
1034
|
var splitWatchdog = null;
|
|
1029
|
-
scope.subscribe(enforceSplitMarker);
|
|
1035
|
+
if (scope) scope.subscribe(enforceSplitMarker);
|
|
1030
1036
|
if (typeof MutationObserver === "function") {
|
|
1031
1037
|
splitWatchdog = new MutationObserver(enforceSplitMarker);
|
|
1032
1038
|
splitWatchdog.observe(
|
|
@@ -1051,14 +1057,16 @@ function apply(ctx) {
|
|
|
1051
1057
|
var onNarrow = function () {
|
|
1052
1058
|
var now = narrowQuery ? narrowQuery.matches : (window.innerWidth < 1200);
|
|
1053
1059
|
if (now && !narrowWas) {
|
|
1054
|
-
var snap = scope.getSnapshot();
|
|
1060
|
+
var snap = scope ? scope.getSnapshot() : undefined;
|
|
1055
1061
|
var v = snap && snap.value ? snap.value : {};
|
|
1056
1062
|
var map = v.splitEnabledBySession || {};
|
|
1057
1063
|
var anyEnabled = Object.keys(map).some(function (k) { return map[k] === true; });
|
|
1058
1064
|
if (anyEnabled) {
|
|
1059
1065
|
var cleared = {};
|
|
1060
1066
|
for (var k in map) cleared[k] = false;
|
|
1061
|
-
|
|
1067
|
+
if (scope && typeof scope.set === "function") {
|
|
1068
|
+
scope.set("splitEnabledBySession", cleared).catch(function () { /* recover handled by scope */ });
|
|
1069
|
+
}
|
|
1062
1070
|
// 同步清理 DOM,避免 settings 异步落地前挤压样式/画布残留。
|
|
1063
1071
|
document.documentElement.removeAttribute("data-dsh-split-on");
|
|
1064
1072
|
document.documentElement.removeAttribute("data-dsh-rail-closed");
|
package/lib/index.js
CHANGED
|
@@ -303,6 +303,8 @@ export function apply(ctx) {
|
|
|
303
303
|
// Function-level handle to the settings scope (used by comfyui_config's
|
|
304
304
|
// activeView read); undefined when the settings service is unavailable.
|
|
305
305
|
let settingsScope = undefined
|
|
306
|
+
// Assigned after a successful settings.register; no-op until then.
|
|
307
|
+
let safeUpdate = () => undefined
|
|
306
308
|
// The background process handle of the ComfyUI launched by this plugin, so
|
|
307
309
|
// the canvas header's stop/restart buttons can kill it directly.
|
|
308
310
|
let comfyProc = null
|
|
@@ -344,6 +346,12 @@ export function apply(ctx) {
|
|
|
344
346
|
try {
|
|
345
347
|
const scope = settings.register(NAMESPACE, ConfigSchema, { applies: 'live' })
|
|
346
348
|
settingsScope = scope
|
|
349
|
+
// Every queued settings write is a promise. try/catch CANNOT see its
|
|
350
|
+
// rejection, and an unhandled rejection is fatal to boot (installFailLoud
|
|
351
|
+
// reports it as "fatal load failure"). Funnel all writes through here.
|
|
352
|
+
safeUpdate = (patch) => {
|
|
353
|
+
try { void Promise.resolve(scope.update(patch)).catch(() => undefined) } catch { /* best effort */ }
|
|
354
|
+
}
|
|
347
355
|
resolveBase = () => {
|
|
348
356
|
const value = scope.get()
|
|
349
357
|
const base = (value?.baseUrl || DEFAULT_BASE).replace(/\/+$/, '')
|
|
@@ -362,7 +370,7 @@ export function apply(ctx) {
|
|
|
362
370
|
void (async () => {
|
|
363
371
|
const fail = (message) => {
|
|
364
372
|
console.error(`[dsh-comfyui-canvas] ${message}`)
|
|
365
|
-
|
|
373
|
+
safeUpdate({ launchError: message })
|
|
366
374
|
}
|
|
367
375
|
try {
|
|
368
376
|
const cmd = (value?.launchCommand || '').trim()
|
|
@@ -371,7 +379,7 @@ export function apply(ctx) {
|
|
|
371
379
|
return
|
|
372
380
|
}
|
|
373
381
|
// Clear any stale error from a previous attempt before launching.
|
|
374
|
-
|
|
382
|
+
safeUpdate({ launchError: '' })
|
|
375
383
|
const workdir = (value?.comfyuiDir || '').trim() || undefined
|
|
376
384
|
const shell = ctx.get?.('shell')
|
|
377
385
|
if (shell && typeof shell.start === 'function') {
|
|
@@ -405,7 +413,7 @@ export function apply(ctx) {
|
|
|
405
413
|
}
|
|
406
414
|
} finally {
|
|
407
415
|
launching = false
|
|
408
|
-
|
|
416
|
+
safeUpdate({ launchRequested: false })
|
|
409
417
|
}
|
|
410
418
|
})()
|
|
411
419
|
})
|
|
@@ -426,7 +434,7 @@ export function apply(ctx) {
|
|
|
426
434
|
const base = resolveBase()
|
|
427
435
|
const result = await probeBridgeAuth(base, token)
|
|
428
436
|
try {
|
|
429
|
-
|
|
437
|
+
safeUpdate({ bridgeProbe: result, probeRequested: false })
|
|
430
438
|
} catch { /* best effort */ }
|
|
431
439
|
} finally {
|
|
432
440
|
probing = false
|
|
@@ -439,7 +447,7 @@ export function apply(ctx) {
|
|
|
439
447
|
try {
|
|
440
448
|
const pkgPath = fileURLToPath(new URL('../package.json', import.meta.url))
|
|
441
449
|
const version = String(JSON.parse(readFileSync(pkgPath, 'utf8')).version || '')
|
|
442
|
-
if (version)
|
|
450
|
+
if (version) safeUpdate({ pluginVersion: version })
|
|
443
451
|
} catch { /* best effort */ }
|
|
444
452
|
|
|
445
453
|
// Plugin-update watcher: the settings page sets updateRequest with
|
|
@@ -455,7 +463,7 @@ export function apply(ctx) {
|
|
|
455
463
|
updatingPlugin = true
|
|
456
464
|
void (async () => {
|
|
457
465
|
const setState = (patch) => {
|
|
458
|
-
|
|
466
|
+
safeUpdate(patch)
|
|
459
467
|
}
|
|
460
468
|
try {
|
|
461
469
|
const action = req.action === 'update' ? 'update' : 'check'
|
|
@@ -545,7 +553,7 @@ export function apply(ctx) {
|
|
|
545
553
|
controlling = true
|
|
546
554
|
void (async () => {
|
|
547
555
|
const setState = (patch) => {
|
|
548
|
-
|
|
556
|
+
safeUpdate(patch)
|
|
549
557
|
}
|
|
550
558
|
try {
|
|
551
559
|
const action = ctrl.action === 'restart' ? 'restart' : 'stop'
|
|
@@ -810,6 +818,9 @@ export function apply(ctx) {
|
|
|
810
818
|
},
|
|
811
819
|
matrix: {
|
|
812
820
|
type: 'object',
|
|
821
|
+
// Required by the tool-schema compiler: object params must declare
|
|
822
|
+
// additionalProperties explicitly (see packages/core/tools/src/schema.ts).
|
|
823
|
+
additionalProperties: true,
|
|
813
824
|
description: 'Declarative parameter sweep: {fields: [{nodeId, key, values}], mode: "zip"|"product"}. Expanded into runs. Use this OR runs, not both.',
|
|
814
825
|
},
|
|
815
826
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-comfyui-canvas",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.8",
|
|
4
4
|
"description": "Give DeepSeek Harness agents live control of your ComfyUI canvas (local or cloud): embed it as a split-screen tab, then read/edit/run workflows, debug errors, fetch output images, and batch-sweep parameters straight from the chat. Ships the ComfyUI-side bridge node.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -49,8 +49,7 @@
|
|
|
49
49
|
"client": {
|
|
50
50
|
"platform": "web",
|
|
51
51
|
"inject": [
|
|
52
|
-
"@deepseek-ai/dsh-client-ui-settings"
|
|
53
|
-
"@deepseek-ai/dsh-client-runtime"
|
|
52
|
+
"@deepseek-ai/dsh-client-ui-settings"
|
|
54
53
|
]
|
|
55
54
|
},
|
|
56
55
|
"bundle": { "patch": "./cordis.patch.yml" }
|