@tscomfy/cli 0.0.0-stage → 0.1.0

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 (63) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +22 -2
  3. package/dist/args.d.ts +24 -0
  4. package/dist/args.d.ts.map +1 -0
  5. package/dist/args.js +66 -0
  6. package/dist/args.js.map +1 -0
  7. package/dist/check.d.ts +6 -0
  8. package/dist/check.d.ts.map +1 -0
  9. package/dist/check.js +185 -0
  10. package/dist/check.js.map +1 -0
  11. package/dist/generate.d.ts +17 -0
  12. package/dist/generate.d.ts.map +1 -0
  13. package/dist/generate.js +166 -0
  14. package/dist/generate.js.map +1 -0
  15. package/dist/index.d.ts +12 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +12 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/io.d.ts +26 -0
  20. package/dist/io.d.ts.map +1 -0
  21. package/dist/io.js +80 -0
  22. package/dist/io.js.map +1 -0
  23. package/dist/main.d.ts +3 -0
  24. package/dist/main.d.ts.map +1 -0
  25. package/dist/main.js +6 -0
  26. package/dist/main.js.map +1 -0
  27. package/dist/manifest.d.ts +47 -0
  28. package/dist/manifest.d.ts.map +1 -0
  29. package/dist/manifest.js +66 -0
  30. package/dist/manifest.js.map +1 -0
  31. package/dist/report.d.ts +13 -0
  32. package/dist/report.d.ts.map +1 -0
  33. package/dist/report.js +69 -0
  34. package/dist/report.js.map +1 -0
  35. package/dist/run.d.ts +9 -0
  36. package/dist/run.d.ts.map +1 -0
  37. package/dist/run.js +89 -0
  38. package/dist/run.js.map +1 -0
  39. package/dist/source.d.ts +28 -0
  40. package/dist/source.d.ts.map +1 -0
  41. package/dist/source.js +92 -0
  42. package/dist/source.js.map +1 -0
  43. package/dist/transpile.d.ts +6 -0
  44. package/dist/transpile.d.ts.map +1 -0
  45. package/dist/transpile.js +178 -0
  46. package/dist/transpile.js.map +1 -0
  47. package/dist/util.d.ts +33 -0
  48. package/dist/util.d.ts.map +1 -0
  49. package/dist/util.js +81 -0
  50. package/dist/util.js.map +1 -0
  51. package/package.json +56 -4
  52. package/src/args.ts +78 -0
  53. package/src/check.ts +224 -0
  54. package/src/generate.ts +198 -0
  55. package/src/index.ts +12 -0
  56. package/src/io.ts +99 -0
  57. package/src/main.ts +7 -0
  58. package/src/manifest.ts +105 -0
  59. package/src/report.ts +73 -0
  60. package/src/run.ts +90 -0
  61. package/src/source.ts +114 -0
  62. package/src/transpile.ts +201 -0
  63. package/src/util.ts +87 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 the tscomfy authors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,23 @@
1
- # Temporary Holding Version
1
+ # @tscomfy/cli
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ The `tscomfy` command: generates TypeScript types from a ComfyUI server's `/object_info`, checks
4
+ them for drift, and transpiles API prompts and UI workflows to typed code. It only sends
5
+ `GET` requests; it never queues anything. Runs on Node 24 or later and Bun 1.4 or later.
6
+
7
+ ```sh
8
+ npm install @tscomfy/core
9
+ npm install --save-dev @tscomfy/cli
10
+
11
+ npx tscomfy generate --url http://127.0.0.1:8188 --out src/comfy/local
12
+ npx tscomfy check --url http://127.0.0.1:8188 --out src/comfy/local
13
+ npx tscomfy transpile --workflow my-workflow.json --schema src/comfy/local --out src/my-workflow.ts
14
+ ```
15
+
16
+ `generate` writes `nodes.ts` (the types), `index.ts` (the typed schema), the raw
17
+ `object_info.json` and a `tscomfy.json` manifest. `tscomfy --help` and
18
+ `tscomfy help <command>` list every option. See the [guides](https://github.com/TheeKia/tscomfy/tree/main/docs/guides), starting with
19
+ [getting started](https://github.com/TheeKia/tscomfy/tree/main/docs/guides/getting-started.md).
20
+
21
+ ## License
22
+
23
+ MIT
package/dist/args.d.ts ADDED
@@ -0,0 +1,24 @@
1
+ /** One flag a command accepts: `--name value`, `--name=value`, or a boolean `--name`. */
2
+ export interface FlagSpec {
3
+ readonly name: string;
4
+ readonly takesValue: boolean;
5
+ /** A one-letter alias of a boolean flag: `h` for `-h`. */
6
+ readonly short?: string;
7
+ }
8
+ /** Parsed flags: the value of each given flag, `true` for a boolean one. */
9
+ export type Flags = ReadonlyMap<string, string | true>;
10
+ /** `-h, --help`, which every command takes. */
11
+ export declare const HELP: FlagSpec;
12
+ /**
13
+ * Parses the arguments after the command name. Throws a usage {@link CliError} (exit 2).
14
+ *
15
+ * A value given apart (`--out dir`) can't start with `-`, so a forgotten value isn't read from
16
+ * the next flag (`--out --from x`); `--out=-dir` gives such a value. Every value is recorded in
17
+ * a regenerate command, which can't keep control characters, so none may have one.
18
+ */
19
+ export declare function parseFlags(args: readonly string[], specs: readonly FlagSpec[]): Flags;
20
+ /** A flag's value, if given. */
21
+ export declare function value(flags: Flags, name: string): string | undefined;
22
+ /** A flag's value, which must be given. */
23
+ export declare function required(flags: Flags, name: string): string;
24
+ //# sourceMappingURL=args.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../src/args.ts"],"names":[],"mappings":"AAEA,yFAAyF;AACzF,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,0DAA0D;IAC1D,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,4EAA4E;AAC5E,MAAM,MAAM,KAAK,GAAG,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;AAEvD,+CAA+C;AAC/C,eAAO,MAAM,IAAI,EAAE,QAA0D,CAAC;AAE9E;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,KAAK,EAAE,SAAS,QAAQ,EAAE,GAAG,KAAK,CAyCrF;AAED,gCAAgC;AAChC,wBAAgB,KAAK,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAGpE;AAED,2CAA2C;AAC3C,wBAAgB,QAAQ,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAI3D"}
package/dist/args.js ADDED
@@ -0,0 +1,66 @@
1
+ import { CliError } from "./io.js";
2
+ /** `-h, --help`, which every command takes. */
3
+ export const HELP = { name: "help", takesValue: false, short: "h" };
4
+ /**
5
+ * Parses the arguments after the command name. Throws a usage {@link CliError} (exit 2).
6
+ *
7
+ * A value given apart (`--out dir`) can't start with `-`, so a forgotten value isn't read from
8
+ * the next flag (`--out --from x`); `--out=-dir` gives such a value. Every value is recorded in
9
+ * a regenerate command, which can't keep control characters, so none may have one.
10
+ */
11
+ export function parseFlags(args, specs) {
12
+ const flags = new Map();
13
+ for (let index = 0; index < args.length; index++) {
14
+ const arg = args[index] ?? "";
15
+ const short = /^-([A-Za-z])$/.exec(arg)?.[1];
16
+ if (short !== undefined) {
17
+ const spec = specs.find((each) => each.short === short);
18
+ if (spec === undefined)
19
+ throw new CliError(`Unknown option -${short}.`, 2);
20
+ if (flags.has(spec.name))
21
+ throw new CliError(`--${spec.name} is given twice.`, 2);
22
+ flags.set(spec.name, true);
23
+ continue;
24
+ }
25
+ if (!arg.startsWith("--"))
26
+ throw new CliError(`Unexpected argument ${JSON.stringify(arg)}.`, 2);
27
+ const equals = arg.indexOf("=");
28
+ const name = arg.slice(2, equals === -1 ? undefined : equals);
29
+ const spec = specs.find((each) => each.name === name);
30
+ if (spec === undefined)
31
+ throw new CliError(`Unknown option --${name}.`, 2);
32
+ if (flags.has(name))
33
+ throw new CliError(`--${name} is given twice.`, 2);
34
+ if (!spec.takesValue) {
35
+ if (equals !== -1)
36
+ throw new CliError(`--${name} takes no value.`, 2);
37
+ flags.set(name, true);
38
+ continue;
39
+ }
40
+ const given = equals === -1 ? args[++index] : arg.slice(equals + 1);
41
+ if (given === undefined || given === "")
42
+ throw new CliError(`--${name} needs a value.`, 2);
43
+ if (equals === -1 && given.startsWith("-")) {
44
+ throw new CliError(`--${name} needs a value; for one that starts with -, write --${name}=<value>.`, 2);
45
+ }
46
+ // oxlint-disable-next-line no-control-regex -- control characters are what this looks for
47
+ if (/[\u0000-\u001f\u007f]/.test(given)) {
48
+ throw new CliError(`--${name} has a control character, which a regenerate command can't keep.`, 2);
49
+ }
50
+ flags.set(name, given);
51
+ }
52
+ return flags;
53
+ }
54
+ /** A flag's value, if given. */
55
+ export function value(flags, name) {
56
+ const given = flags.get(name);
57
+ return typeof given === "string" ? given : undefined;
58
+ }
59
+ /** A flag's value, which must be given. */
60
+ export function required(flags, name) {
61
+ const given = value(flags, name);
62
+ if (given === undefined)
63
+ throw new CliError(`--${name} is required.`, 2);
64
+ return given;
65
+ }
66
+ //# sourceMappingURL=args.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"args.js","sourceRoot":"","sources":["../src/args.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { Io } from "./io.ts";
2
+ /** `tscomfy check --help`. */
3
+ export declare const CHECK_USAGE: string;
4
+ /** `tscomfy check`. */
5
+ export declare function checkCommand(io: Io, args: readonly string[]): Promise<number>;
6
+ //# sourceMappingURL=check.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../src/check.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAKlC,8BAA8B;AAC9B,eAAO,MAAM,WAAW,EAAE,MAazB,CAAC;AAmBF,uBAAuB;AACvB,wBAAsB,YAAY,CAAC,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAqEnF"}
package/dist/check.js ADDED
@@ -0,0 +1,185 @@
1
+ import { join } from "node:path";
2
+ import { CODEGEN_VERSION } from "@tscomfy/codegen";
3
+ import { diffSchemas, hashSchema, } from "@tscomfy/core";
4
+ import { HELP, parseFlags, required } from "./args.js";
5
+ import { regenerateCommand } from "./generate.js";
6
+ import { contentHash, FILES, MANIFEST, readGenerated, SNAPSHOT } from "./manifest.js";
7
+ import { count } from "./report.js";
8
+ import { loadSchema, readSource } from "./source.js";
9
+ /** `tscomfy check --help`. */
10
+ export const CHECK_USAGE = `Usage: tscomfy check (--url <server> | --from <object_info.json>) --out <dir>
11
+
12
+ Compares the server's node definitions with the snapshot in <dir>/${SNAPSHOT}, and checks
13
+ that the files in <dir> are exactly what \`tscomfy generate\` wrote (<dir>/${MANIFEST}). Exits
14
+ with 1 when anything differs, so it can guard a build. New files in upload and remote combos
15
+ (an uploaded image) are runtime state, not drift.
16
+
17
+ Options:
18
+ --url <server> A ComfyUI server, e.g. http://127.0.0.1:8188. Only GET requests.
19
+ --from <file> A saved /object_info response instead of a server.
20
+ --out <dir> The directory \`tscomfy generate\` wrote.
21
+ --verbose List every changed node, input and combo option, rather than the first few.
22
+ -h, --help Show this help.
23
+ `;
24
+ const FLAGS = [
25
+ { name: "url", takesValue: true },
26
+ { name: "from", takesValue: true },
27
+ { name: "out", takesValue: true },
28
+ { name: "verbose", takesValue: false },
29
+ HELP,
30
+ ];
31
+ /** How many node and input names a list shows before the rest are counted, unless verbose. */
32
+ const SHOWN_NAMES = 10;
33
+ /** How many combo options a change lists before the rest are counted, unless verbose. */
34
+ const SHOWN_OPTIONS = 5;
35
+ /** What follows a count of entries left out. */
36
+ const MORE = " (--verbose shows all)";
37
+ /** `tscomfy check`. */
38
+ export async function checkCommand(io, args) {
39
+ const flags = parseFlags(args, FLAGS);
40
+ if (flags.has("help")) {
41
+ io.out(CHECK_USAGE);
42
+ return 0;
43
+ }
44
+ const out = required(flags, "out");
45
+ const verbose = flags.has("verbose");
46
+ const { manifest, snapshotPath, snapshotText, schema: snapshot } = await readGenerated(io, out);
47
+ const source = await readSource(io, flags);
48
+ const current = loadSchema(source).schema;
49
+ // Files that don't hash as recorded were edited, removed or left half-written.
50
+ const stale = [];
51
+ for (const file of FILES) {
52
+ const hash = manifest.files[file];
53
+ // Sequential: a few small reads, and a stable order for the message.
54
+ // oxlint-disable-next-line no-await-in-loop
55
+ const text = file === SNAPSHOT ? snapshotText : await io.readText(join(out, file));
56
+ if (text === undefined || contentHash(text) !== hash)
57
+ stale.push(file);
58
+ }
59
+ // Another codegen, or another core normalizing the same snapshot differently.
60
+ const outdated = manifest.codegen !== CODEGEN_VERSION || manifest.schema !== hashSchema(snapshot);
61
+ const { diff, runtime } = withoutRuntimeOptions(diffSchemas(snapshot, current), current);
62
+ const drifted = diff.added.length + diff.removed.length + diff.changed.length > 0;
63
+ const ignored = runtime.length === 0
64
+ ? ""
65
+ : ` (changed files in ${count(runtime.length, "upload or remote combo")} aren't drift: ${listed(runtime, verbose, SHOWN_NAMES)})`;
66
+ if (!drifted && stale.length === 0 && !outdated) {
67
+ const nodes = Object.keys(current.nodes).length;
68
+ io.out(`Up to date: ${count(nodes, "node type")} ${nodes === 1 ? "matches" : "match"} ${snapshotPath}${ignored}.\n`);
69
+ return 0;
70
+ }
71
+ const lines = [];
72
+ if (stale.length > 0) {
73
+ lines.push(`${list(stale)} in ${out} ${stale.length === 1 ? "isn't" : "aren't"} what tscomfy generate wrote: edited, missing, or from an interrupted run.`);
74
+ }
75
+ if (outdated) {
76
+ lines.push(manifest.codegen === CODEGEN_VERSION
77
+ ? `${out} was generated by another version of tscomfy, which read the snapshot differently.`
78
+ : `${out} was generated by @tscomfy/codegen ${manifest.codegen}; this is ${CODEGEN_VERSION}.`);
79
+ }
80
+ if (drifted) {
81
+ lines.push(`${source.label} differs from ${snapshotPath}${ignored}:`, ...formatDiff(diff, verbose));
82
+ }
83
+ const command = regenerateCommand({
84
+ flag: source.flag,
85
+ out,
86
+ exportName: manifest.exportName,
87
+ importExtension: manifest.importExtension,
88
+ // With --url, the server says again.
89
+ ...(flags.has("from") && manifest.comfyVersion !== undefined
90
+ ? { comfyVersion: manifest.comfyVersion }
91
+ : {}),
92
+ });
93
+ lines.push(`Run ${command} to update.`);
94
+ io.out(`${lines.join("\n")}\n`);
95
+ return 1;
96
+ }
97
+ /**
98
+ * The diff without option changes of upload and remote combos (docs/plan.md §6.5): their options
99
+ * are the server's files, which change with every upload, and the types take any string there.
100
+ * Also returns those inputs, as `Class.input`.
101
+ */
102
+ function withoutRuntimeOptions(diff, current) {
103
+ const runtime = [];
104
+ const changed = [];
105
+ for (const change of diff.changed) {
106
+ const inputs = current.nodes[change.classType]?.inputs ?? [];
107
+ const kept = change.inputsChanged.filter((input) => {
108
+ const definition = inputs.find((each) => each.name === input.name);
109
+ const runtimeOnly = !input.specChanged &&
110
+ definition?.kind === "combo" &&
111
+ (definition.upload || definition.remote);
112
+ if (runtimeOnly)
113
+ runtime.push(`${change.classType}.${input.name}`);
114
+ return !runtimeOnly;
115
+ });
116
+ const rest = { ...change, inputsChanged: kept };
117
+ const empty = kept.length === 0 &&
118
+ rest.inputsAdded.length === 0 &&
119
+ rest.inputsRemoved.length === 0 &&
120
+ !rest.outputsChanged &&
121
+ !rest.detailsChanged;
122
+ if (!empty)
123
+ changed.push(rest);
124
+ }
125
+ return { diff: { ...diff, changed }, runtime };
126
+ }
127
+ /**
128
+ * The diff as indented lines: every list (nodes, inputs, options, changed nodes) cut to its
129
+ * first few entries unless `verbose`, so a server that differs a lot still gives short lines.
130
+ */
131
+ function formatDiff(diff, verbose) {
132
+ const lines = [];
133
+ if (diff.added.length > 0) {
134
+ lines.push(` + ${count(diff.added.length, "node")} added: ${listed(diff.added, verbose, SHOWN_NAMES)}`);
135
+ }
136
+ if (diff.removed.length > 0) {
137
+ lines.push(` - ${count(diff.removed.length, "node")} removed: ${listed(diff.removed, verbose, SHOWN_NAMES)}`);
138
+ }
139
+ if (diff.changed.length > 0) {
140
+ lines.push(` ~ ${count(diff.changed.length, "node")} changed:`);
141
+ const shown = verbose ? diff.changed : diff.changed.slice(0, SHOWN_NAMES);
142
+ for (const change of shown)
143
+ lines.push(...formatChange(change, verbose));
144
+ if (shown.length < diff.changed.length) {
145
+ lines.push(` … and ${String(diff.changed.length - shown.length)} more${MORE}`);
146
+ }
147
+ }
148
+ return lines;
149
+ }
150
+ function formatChange(change, verbose) {
151
+ const lines = [` ${change.classType}`];
152
+ if (change.inputsAdded.length > 0) {
153
+ lines.push(` inputs added: ${listed(change.inputsAdded, verbose, SHOWN_NAMES)}`);
154
+ }
155
+ if (change.inputsRemoved.length > 0) {
156
+ lines.push(` inputs removed: ${listed(change.inputsRemoved, verbose, SHOWN_NAMES)}`);
157
+ }
158
+ for (const input of change.inputsChanged) {
159
+ const options = (values) => listed(values.map((option) => JSON.stringify(option)), verbose, SHOWN_OPTIONS);
160
+ const parts = [
161
+ ...(input.optionsAdded.length > 0 ? [`+ ${options(input.optionsAdded)}`] : []),
162
+ ...(input.optionsRemoved.length > 0 ? [`- ${options(input.optionsRemoved)}`] : []),
163
+ ...(input.specChanged ? ["spec changed"] : []),
164
+ ];
165
+ lines.push(` ${input.name}: ${parts.join("; ")}`);
166
+ }
167
+ if (change.outputsChanged)
168
+ lines.push(" outputs changed");
169
+ if (change.detailsChanged)
170
+ lines.push(" details changed (name, category, description, flags or order)");
171
+ return lines;
172
+ }
173
+ /** `a, b, c`, or the first `limit` and `… and 4 more (--verbose shows all)` unless `verbose`. */
174
+ function listed(items, verbose, limit) {
175
+ const shown = verbose ? items : items.slice(0, limit);
176
+ const rest = items.length - shown.length;
177
+ return rest > 0 ? `${shown.join(", ")}, … and ${String(rest)} more${MORE}` : shown.join(", ");
178
+ }
179
+ /** `a`, `a and b`, `a, b and c`. */
180
+ function list(items) {
181
+ return items.length <= 1
182
+ ? items.join("")
183
+ : `${items.slice(0, -1).join(", ")} and ${items.at(-1) ?? ""}`;
184
+ }
185
+ //# sourceMappingURL=check.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check.js","sourceRoot":"","sources":["../src/check.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import { type Io } from "./io.ts";
2
+ /** `tscomfy generate --help`. */
3
+ export declare const GENERATE_USAGE: string;
4
+ /** `tscomfy generate`. */
5
+ export declare function generateCommand(io: Io, args: readonly string[]): Promise<number>;
6
+ /** What regenerates a directory: the recorded options, from a given source. */
7
+ export interface Regenerate {
8
+ /** `--url <server>` or `--from <file>`, as shell words. */
9
+ readonly flag: string;
10
+ readonly out: string;
11
+ readonly exportName: string;
12
+ readonly importExtension: ".js" | ".ts";
13
+ readonly comfyVersion?: string;
14
+ }
15
+ /** The `tscomfy generate` command for a POSIX shell; options at their defaults are left out. */
16
+ export declare function regenerateCommand(options: Regenerate): string;
17
+ //# sourceMappingURL=generate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../src/generate.ts"],"names":[],"mappings":"AAIA,OAAO,EAAY,KAAK,EAAE,EAAE,MAAM,SAAS,CAAC;AAa5C,iCAAiC;AACjC,eAAO,MAAM,cAAc,EAAE,MAsB5B,CAAC;AAcF,0BAA0B;AAC1B,wBAAsB,eAAe,CAAC,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAyDtF;AAqBD,+EAA+E;AAC/E,MAAM,WAAW,UAAU;IACzB,2DAA2D;IAC3D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,eAAe,EAAE,KAAK,GAAG,KAAK,CAAC;IACxC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;CAChC;AAED,gGAAgG;AAChG,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,UAAU,GAAG,MAAM,CAa7D"}
@@ -0,0 +1,166 @@
1
+ import { basename, dirname, join } from "node:path";
2
+ import { CODEGEN_VERSION, exportNameProblem, generate } from "@tscomfy/codegen";
3
+ import { hashSchema } from "@tscomfy/core";
4
+ import { HELP, parseFlags, required, value } from "./args.js";
5
+ import { CliError } from "./io.js";
6
+ import { contentHash, formatManifest, MANIFEST, readManifest, SNAPSHOT, } from "./manifest.js";
7
+ import { count, formatDiagnostic, reportDiagnostics, size } from "./report.js";
8
+ import { loadSchema, readSource } from "./source.js";
9
+ import { camelName, flagWords } from "./util.js";
10
+ /** `tscomfy generate --help`. */
11
+ export const GENERATE_USAGE = `Usage: tscomfy generate (--url <server> | --from <object_info.json>) --out <dir> [options]
12
+
13
+ Writes <dir>/nodes.ts (types), <dir>/index.ts (the typed schema), <dir>/${SNAPSHOT}
14
+ (the raw response, for regenerating offline and for \`tscomfy check\`) and <dir>/${MANIFEST}
15
+ (what was generated, for \`tscomfy check\` and \`tscomfy transpile\`).
16
+
17
+ Options:
18
+ --url <server> A ComfyUI server, e.g. http://127.0.0.1:8188. Only GET requests.
19
+ Credentials and the query are sent, never written or shown.
20
+ --from <file> A saved /object_info response instead of a server.
21
+ --out <dir> The directory to write into.
22
+ --name <identifier> The exported schema constant. Default: from the directory name,
23
+ camelCased (my-server → myServer).
24
+ --import-extension <ext> How index.ts imports nodes.ts: .js (default) or .ts.
25
+ --comfy-version <version> The ComfyUI version to record, with --from. Default: the one
26
+ recorded next to <file> when it is a snapshot generate wrote.
27
+ --verbose List every diagnostic.
28
+ --quiet Print errors only.
29
+ -h, --help Show this help.
30
+
31
+ The headers record the command that regenerates the files, for a POSIX shell in the directory
32
+ generate ran in. A value that starts with - is written --flag=<value>.
33
+ `;
34
+ const FLAGS = [
35
+ { name: "url", takesValue: true },
36
+ { name: "from", takesValue: true },
37
+ { name: "out", takesValue: true },
38
+ { name: "name", takesValue: true },
39
+ { name: "import-extension", takesValue: true },
40
+ { name: "comfy-version", takesValue: true },
41
+ { name: "verbose", takesValue: false },
42
+ { name: "quiet", takesValue: false },
43
+ HELP,
44
+ ];
45
+ /** `tscomfy generate`. */
46
+ export async function generateCommand(io, args) {
47
+ const flags = parseFlags(args, FLAGS);
48
+ if (flags.has("help")) {
49
+ io.out(GENERATE_USAGE);
50
+ return 0;
51
+ }
52
+ const out = required(flags, "out");
53
+ const exportName = readName(flags, out);
54
+ const importExtension = readExtension(flags);
55
+ if (flags.has("comfy-version") && !flags.has("from")) {
56
+ throw new CliError("--comfy-version goes with --from; with --url it comes from the server.", 2);
57
+ }
58
+ if (flags.has("verbose") && flags.has("quiet")) {
59
+ throw new CliError("--verbose and --quiet don't go together.", 2);
60
+ }
61
+ const read = await readSource(io, flags);
62
+ const source = await withSnapshotVersion(io, flags, read);
63
+ const schema = loadSchema(source);
64
+ const command = regenerateCommand({
65
+ flag: source.flag,
66
+ out,
67
+ exportName,
68
+ importExtension,
69
+ // With --url, the server says again.
70
+ ...(flags.has("from") && source.comfyVersion !== undefined
71
+ ? { comfyVersion: source.comfyVersion }
72
+ : {}),
73
+ });
74
+ const result = generate(schema.schema, { exportName, importExtension, command });
75
+ const files = [...result.files, { path: SNAPSHOT, contents: source.text }];
76
+ await Promise.all(files.map((file) => io.writeText(join(out, file.path), file.contents)));
77
+ // Last: a run interrupted before this leaves a manifest that doesn't match the files.
78
+ const manifest = {
79
+ codegen: CODEGEN_VERSION,
80
+ schema: hashSchema(schema.schema),
81
+ exportName,
82
+ importExtension,
83
+ ...(source.comfyVersion === undefined ? {} : { comfyVersion: source.comfyVersion }),
84
+ files: Object.fromEntries(files.map((file) => [file.path, contentHash(file.contents)])),
85
+ };
86
+ await io.writeText(join(out, MANIFEST), formatManifest(manifest));
87
+ const diagnostics = [...schema.diagnostics, ...result.diagnostics];
88
+ if (!flags.has("quiet")) {
89
+ const version = schema.schema.comfyVersion === undefined ? "" : ` (ComfyUI ${schema.schema.comfyVersion})`;
90
+ io.out(`Generated ${count(Object.keys(schema.schema.nodes).length, "node type")} from ${source.label}${version} into ${out}:\n` +
91
+ ` ${files.map((file) => `${file.path} ${size(byteLength(file.contents))}`).join(" · ")}\n`);
92
+ io.out(reportDiagnostics(diagnostics, schema.schema, source.text, flags.has("verbose")));
93
+ }
94
+ else {
95
+ const errors = diagnostics.filter((diagnostic) => diagnostic.severity === "error");
96
+ for (const diagnostic of errors)
97
+ io.err(`${formatDiagnostic(diagnostic)}\n`);
98
+ }
99
+ return 0;
100
+ }
101
+ /**
102
+ * `--from` a snapshot generate wrote, without `--comfy-version`: the version its manifest
103
+ * records, when the file is exactly the one recorded. Regenerating offline then keeps the
104
+ * version a `--url` run fetched. Anything else (another file, an edited snapshot, no manifest,
105
+ * or one that isn't ours) leaves the version unknown, as for any saved response.
106
+ */
107
+ async function withSnapshotVersion(io, flags, source) {
108
+ const from = value(flags, "from");
109
+ if (from === undefined || source.comfyVersion !== undefined || basename(from) !== SNAPSHOT) {
110
+ return source;
111
+ }
112
+ const manifest = await readManifest(io, dirname(from)).catch(() => undefined);
113
+ const recorded = manifest?.comfyVersion;
114
+ if (recorded === undefined || manifest?.files[SNAPSHOT] !== contentHash(source.text)) {
115
+ return source;
116
+ }
117
+ return { ...source, comfyVersion: recorded };
118
+ }
119
+ /** The `tscomfy generate` command for a POSIX shell; options at their defaults are left out. */
120
+ export function regenerateCommand(options) {
121
+ return [
122
+ "tscomfy generate",
123
+ options.flag,
124
+ flagWords("out", options.out),
125
+ ...(options.exportName === defaultName(options.out)
126
+ ? []
127
+ : [flagWords("name", options.exportName)]),
128
+ ...(options.importExtension === ".js" ? [] : [`--import-extension ${options.importExtension}`]),
129
+ ...(options.comfyVersion === undefined
130
+ ? []
131
+ : [flagWords("comfy-version", options.comfyVersion)]),
132
+ ].join(" ");
133
+ }
134
+ /** The export name from the output directory (see {@link camelName}), if it can be one. */
135
+ function defaultName(out) {
136
+ const name = camelName(basename(out));
137
+ return exportNameProblem(name) === undefined ? name : undefined;
138
+ }
139
+ function readName(flags, out) {
140
+ const given = value(flags, "name");
141
+ if (given === undefined) {
142
+ const derived = defaultName(out);
143
+ if (derived === undefined) {
144
+ const name = camelName(basename(out));
145
+ const why = name === "" ? "" : `: ${JSON.stringify(name)} won't do, ${exportNameProblem(name) ?? ""}`;
146
+ throw new CliError(`Can't make an export name from ${JSON.stringify(out)}${why}; pass --name.`, 2);
147
+ }
148
+ return derived;
149
+ }
150
+ const problem = exportNameProblem(given);
151
+ if (problem !== undefined) {
152
+ throw new CliError(`--name ${JSON.stringify(given)} isn't usable: ${problem}.`, 2);
153
+ }
154
+ return given;
155
+ }
156
+ function readExtension(flags) {
157
+ const extension = value(flags, "import-extension") ?? ".js";
158
+ if (extension !== ".js" && extension !== ".ts") {
159
+ throw new CliError("--import-extension is .js or .ts.", 2);
160
+ }
161
+ return extension;
162
+ }
163
+ function byteLength(text) {
164
+ return new TextEncoder().encode(text).length;
165
+ }
166
+ //# sourceMappingURL=generate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate.js","sourceRoot":"","sources":["../src/generate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * @module @tscomfy/cli
3
+ *
4
+ * The `tscomfy` command: generate types from a ComfyUI server, check them for drift against a
5
+ * snapshot, and transpile API prompts and UI workflows to code. The only package with I/O,
6
+ * through `node:fs`, `node:crypto` and `fetch`, so it runs on Node and Bun.
7
+ * Exported for running the CLI in-process: `run(args, systemIo())`, or with an {@link Io} of
8
+ * your own, which reports failures as {@link CliError}s.
9
+ */
10
+ export { CliError, type Io, systemIo } from "./io.ts";
11
+ export { CLI_VERSION, run } from "./run.ts";
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,12 @@
1
+ /**
2
+ * @module @tscomfy/cli
3
+ *
4
+ * The `tscomfy` command: generate types from a ComfyUI server, check them for drift against a
5
+ * snapshot, and transpile API prompts and UI workflows to code. The only package with I/O,
6
+ * through `node:fs`, `node:crypto` and `fetch`, so it runs on Node and Bun.
7
+ * Exported for running the CLI in-process: `run(args, systemIo())`, or with an {@link Io} of
8
+ * your own, which reports failures as {@link CliError}s.
9
+ */
10
+ export { CliError, systemIo } from "./io.js";
11
+ export { CLI_VERSION, run } from "./run.js";
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,QAAQ,EAAW,QAAQ,EAAE,MAAM,SAAS,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC"}
package/dist/io.d.ts ADDED
@@ -0,0 +1,26 @@
1
+ /** Everything the CLI does to the outside world, so commands can be tested without it. */
2
+ export interface Io {
3
+ /** Writes to standard output. */
4
+ readonly out: (text: string) => void;
5
+ /** Writes to standard error. */
6
+ readonly err: (text: string) => void;
7
+ /**
8
+ * GETs a URL's body; throws a {@link CliError} for a network error or a non-2xx status (with
9
+ * the message of an error body, such as `{"detail": "Not authenticated"}`).
10
+ */
11
+ readonly fetchText: (url: string) => Promise<string>;
12
+ /** A file's text (UTF-8, without a byte order mark), or `undefined` when it doesn't exist. */
13
+ readonly readText: (path: string) => Promise<string | undefined>;
14
+ /** Replaces a file's contents in one step, creating its directory. */
15
+ readonly writeText: (path: string, text: string) => Promise<void>;
16
+ }
17
+ /** A failure to report to the user: a message, and the exit code to end with. */
18
+ export declare class CliError extends Error {
19
+ /** 1 for a failure, 2 for a usage error. */
20
+ readonly exitCode: number;
21
+ /** A failure with `message`, ending the process with `exitCode`. */
22
+ constructor(message: string, exitCode?: number);
23
+ }
24
+ /** The real world: the process's streams, `fetch` and `node:fs`, which Node and Bun both have. */
25
+ export declare function systemIo(): Io;
26
+ //# sourceMappingURL=io.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"io.d.ts","sourceRoot":"","sources":["../src/io.ts"],"names":[],"mappings":"AAIA,0FAA0F;AAC1F,MAAM,WAAW,EAAE;IACjB,iCAAiC;IACjC,QAAQ,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,gCAAgC;IAChC,QAAQ,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC;;;OAGG;IACH,QAAQ,CAAC,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACrD,8FAA8F;IAC9F,QAAQ,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IACjE,sEAAsE;IACtE,QAAQ,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACnE;AAED,iFAAiF;AACjF,qBAAa,QAAS,SAAQ,KAAK;IACjC,4CAA4C;IAC5C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAE1B,oEAAoE;IACpE,YAAY,OAAO,EAAE,MAAM,EAAE,QAAQ,SAAI,EAIxC;CACF;AAID,kGAAkG;AAClG,wBAAgB,QAAQ,IAAI,EAAE,CAqD7B"}