@ai-fux/fux-dsh-comfymcp 0.5.0 → 0.5.1

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/index.js CHANGED
@@ -25,7 +25,7 @@ import { createWorkbenchMethods } from './lib/workbench.js'
25
25
  import * as persist from './lib/persist.js'
26
26
 
27
27
  export const name = '@ai-fux/fux-dsh-comfymcp'
28
- export const version = '0.5.0'
28
+ export const version = '0.5.1'
29
29
  export const description =
30
30
  'comfy-mcp 对接:自然语言设计可运行 ComfyUI 工作流、定制表单确认、强制保存运行与成果物回显。'
31
31
 
package/lib/bridge.js CHANGED
@@ -44,16 +44,26 @@ export class ComfymcpBridge {
44
44
  ((cfg) => {
45
45
  // 远程模式:直连 comfy-mcp 的 Streamable HTTP 端点(不 spawn 本地 stdio 宿主)
46
46
  if (cfg.embeddedServer !== true) return createHostFacade(this.newHttpClient(cfg), { log: (line) => this.log(line) })
47
- return new McpStdioClient({
48
- command: cfg.hostCommand,
49
- args: this.hostArgs(cfg),
50
- requestTimeoutMs: cfg.requestTimeoutMs,
51
- callTimeoutMs: cfg.callTimeoutMs,
52
- env: { ...process.env, COMFY_MCP_ENDPOINT: cfg.endpoint },
53
- log: (line) => this.log(line),
54
- })
47
+ // 内置模式:优先 stdio 宿主子进程。宿主入口解析不到(npm 全新安装形态不含
48
+ // TS 宿主工程,FIX202610170239)→ 回退直连内嵌 comfy-mcp 的 HTTP 端点,
49
+ // 绝不 spawn 占位入口(node DSH_COMFYMCP_HOST_ENTRY_NOT_CONFIGURED 必败重试)。
50
+ const host = this.resolveHostEntry(process.env)
51
+ if (host.entry !== '') {
52
+ return new McpStdioClient({
53
+ command: cfg.hostCommand,
54
+ args: [host.entry],
55
+ requestTimeoutMs: cfg.requestTimeoutMs,
56
+ callTimeoutMs: cfg.callTimeoutMs,
57
+ env: { ...process.env, COMFY_MCP_ENDPOINT: cfg.endpoint },
58
+ log: (line) => this.log(line),
59
+ })
60
+ }
61
+ this.hostFallback = { reason: 'host-entry-unresolved', candidates: host.candidates ?? [] }
62
+ this.log(`宿主入口未解析(npm 安装形态不含 TS 宿主工程)→ 回退 HTTP 直连 ${cfg.endpoint};需要 stdio 宿主时配置 hostEntry 或放置 ${host.candidates?.[0] ?? ''}`)
63
+ return createHostFacade(this.newHttpClient(cfg), { log: (line) => this.log(line) })
55
64
  })
56
65
  this.client = null
66
+ this.hostFallback = null
57
67
  this.embedded = null
58
68
  this.pluginDir = typeof options.pluginDir === 'string' ? options.pluginDir : ''
59
69
  this.runs = new Map()
@@ -82,9 +92,10 @@ export class ComfymcpBridge {
82
92
  })
83
93
  }
84
94
 
85
- /** 当前传输方式:远程=streamable-http,内置=stdio 宿主。 */
95
+ /** 当前传输方式:远程=streamable-http;内置=stdio 宿主,宿主缺失回退 HTTP 时为 streamable-http-fallback。 */
86
96
  transport() {
87
- return this.config.embeddedServer === true ? 'stdio' : 'streamable-http'
97
+ if (this.config.embeddedServer !== true) return 'streamable-http'
98
+ return this.hostFallback ? 'streamable-http-fallback' : 'stdio'
88
99
  }
89
100
 
90
101
  /**
@@ -140,7 +151,7 @@ export class ComfymcpBridge {
140
151
  return { ...this.config }
141
152
  }
142
153
 
143
- /** Resolve a usable host entry: explicit config, env, then conventional workspace paths. */
154
+ /** Resolve a usable host entry: explicit config, env, then existence-checked conventional paths. */
144
155
  resolveHostEntry(env = {}) {
145
156
  if (typeof this.config.hostEntry === 'string' && this.config.hostEntry.trim().length > 0) {
146
157
  return { entry: this.config.hostEntry.trim(), source: 'config' }
@@ -149,11 +160,21 @@ export class ComfymcpBridge {
149
160
  if (typeof fromEnv === 'string' && fromEnv.trim().length > 0) {
150
161
  return { entry: fromEnv.trim(), source: 'env' }
151
162
  }
152
- return { entry: '', source: 'unset', candidates: candidateHostEntries('') }
163
+ // 约定候选路径:存在性探测(只认绝对路径,相对路径依赖 cwd 不可靠),命中即用
164
+ for (const candidate of candidateHostEntries(this.pluginDir)) {
165
+ if (!isAbsolute(candidate)) continue
166
+ try {
167
+ if (existsSync(candidate)) return { entry: candidate, source: 'candidate' }
168
+ } catch {
169
+ /* ignore */
170
+ }
171
+ }
172
+ return { entry: '', source: 'unset', candidates: candidateHostEntries(this.pluginDir) }
153
173
  }
154
174
 
155
175
  clientOrNull() {
156
176
  if (this.client === null) {
177
+ this.hostFallback = null
157
178
  this.client = this.clientFactory(this.config)
158
179
  }
159
180
  return this.client
@@ -266,10 +287,10 @@ export class ComfymcpBridge {
266
287
  error: '',
267
288
  }
268
289
  try {
269
- const transport = this.transport()
270
290
  const client = await this.ensureReady()
291
+ const transport = this.transport()
271
292
  if (transport === 'stdio') {
272
- const entry = this.resolveHostEntry()
293
+ const entry = this.resolveHostEntry(process.env)
273
294
  if (entry.entry === '') {
274
295
  result.error =
275
296
  'MCP 宿主入口未配置:设置 hostEntry 指向 projects/dsh-comfymcp/mcp/bin/fux-comfymcp-host.mjs(或环境变量 DSH_COMFYMCP_HOST_ENTRY)'
@@ -278,6 +299,7 @@ export class ComfymcpBridge {
278
299
  result.host = { ...client.status(), transport, entry: entry.entry, entrySource: entry.source }
279
300
  } else {
280
301
  result.host = { ...client.status(), transport, entry: this.config.endpoint, entrySource: 'endpoint' }
302
+ if (this.hostFallback) result.host.fallback = { ...this.hostFallback }
281
303
  }
282
304
  const status = await client.callTool('connection_status', {}, 20000)
283
305
  result.remote = status?.structuredContent ?? null
package/lib/config.js CHANGED
@@ -192,6 +192,9 @@ export function candidateHostEntries(pluginDir) {
192
192
  const entries = []
193
193
  if (pluginDir) {
194
194
  const normalized = pluginDir.replaceAll('\\', '/')
195
+ // 插件包内约定:vendor/fux-comfymcp-host.mjs(与 vendor/comfy-mcp-server.mjs 同层)。
196
+ // 当前 npm 包不含 TS 宿主工程;留此约定供手工放置或未来打包自包含宿主。
197
+ entries.push(`${normalized}/vendor/fux-comfymcp-host.mjs`)
195
198
  const marker = '/node_modules/'
196
199
  const cut = normalized.lastIndexOf(marker)
197
200
  if (cut > 0) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-fux/fux-dsh-comfymcp",
3
- "version": "0.5.0",
3
+ "version": "0.5.1",
4
4
  "type": "module",
5
5
  "description": "DSH 插件:对接 comfy-mcp 服务(自然语言设计可运行工作流、定制表单、运行与成果物回显)。",
6
6
  "license": "MIT",