Files
DemonGatanjieu-Anomalous_Mo…/tests/load_order.mjs
T
DemonGatanjieuandClaude Opus 5.5 139380e960 Give the AI what it needs: answers it can read, hints on an empty canvas, AMB always loading
- An answer past Antigravity's size is filed away unread (eight LoRA
  searches in the exam): search_models answers small (loaders once,
  four trigger words, a LoRA's author weight); describe_canvas gives a
  big canvas's last nodes a line each; mcp_fit.py keeps any other list
  answer within the size and names what it left out.
- An empty canvas: run_workflow, describe_canvas and get_situation say
  to open a workflow first; get_image_info says a picture's workflow
  opens with open_workflow.
- ask_user does not put a "test" question to the user; a task's picture
  count counts what its runs made.
- AMB failed to load now and then: ComfyUI loads every file at once and
  ui_ai_workbench.js set ui_ai_toolbox.js's sideHost before it was made
  when the toolbox file ran first. Connected on first draw now;
  tests/load_order.mjs runs every file first.
- input_facts moved to api/picture_mask.py to keep mcp_tools.py short.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-06 20:53:50 +08:00

39 lines
2.0 KiB
JavaScript

// ComfyUI loads every .js file of the plugin as an extension, all at once, so any of them may be the
// first to run. In an import cycle the one that runs first can find a binding of another file not
// made yet ("Cannot access 'x' before initialization"), and then the whole plugin fails to load
// (1.63: ui_ai_workbench.js set ui_ai_toolbox.js's sideHost at load). This enters each file first,
// in a Node of its own with the page stood in for (tests/load_order/), and fails on any such error.
import assert from 'node:assert/strict';
import { execFile } from 'node:child_process';
import fs from 'node:fs';
import os from 'node:os';
import path from 'node:path';
import { fileURLToPath, pathToFileURL } from 'node:url';
const here = path.dirname(fileURLToPath(import.meta.url));
const web = path.join(here, '..', 'web');
const files = [
...fs.readdirSync(web).filter(name => name.endsWith('.js')),
...fs.readdirSync(path.join(web, 'modules')).filter(name => name.endsWith('.js')).map(name => `modules/${name}`),
];
const page = pathToFileURL(path.join(here, 'load_order', 'page.mjs')).href;
const enter = path.join(here, 'load_order', 'enter.mjs');
const first = file => new Promise(done => {
execFile(process.execPath, ['--import', page, enter, path.join(web, file)], { timeout: 30000, encoding: 'utf8' },
(error, stdout) => done(String(stdout || '').trim().split('\n').pop() || `ERR ${error?.message || 'no answer'}`));
});
const failed = [];
let next = 0;
async function worker() {
while (next < files.length) {
const file = files[next++];
const said = await first(file);
if (/before initialization/.test(said)) failed.push(`${file}: ${said.slice(4)}`);
}
}
await Promise.all(Array.from({ length: Math.max(2, Math.min(8, os.cpus().length - 1)) }, worker));
assert.deepEqual(failed, [], `run first, these files find a binding not made yet; the plugin would not load:\n${failed.join('\n')}`);
console.log(`load_order: each of ${files.length} files can run first`);