@dusted/anqst 0.1.0 → 0.1.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/dist/src/app.js CHANGED
@@ -12,11 +12,14 @@ exports.runCommand = runCommand;
12
12
  const node_path_1 = __importDefault(require("node:path"));
13
13
  const node_fs_1 = __importDefault(require("node:fs"));
14
14
  const node_child_process_1 = require("node:child_process");
15
- const parser_1 = require("./parser");
16
- const verify_1 = require("./verify");
17
15
  const errors_1 = require("./errors");
16
+ const debug_dump_1 = require("./debug-dump");
18
17
  const emit_1 = require("./emit");
19
18
  const project_1 = require("./project");
19
+ const layout_1 = require("./layout");
20
+ const parser_1 = require("./parser");
21
+ const verify_1 = require("./verify");
22
+ const ANQSTGEN_ACTIVE_STAMP_FILE = ".anqstgen-version-active.json";
20
23
  function renderHelp() {
21
24
  return [
22
25
  "Usage:",
@@ -24,19 +27,22 @@ function renderHelp() {
24
27
  "",
25
28
  "Commands:",
26
29
  " instill <WidgetName> Initialize AnQst in current npm project",
27
- " test Verify package.json AnQst spec",
28
- " build Generate artifacts from package.json AnQst spec",
30
+ " test Verify AnQst spec from package settings",
31
+ " build [--designerplugin[=true|false]] Generate artifacts from package settings",
29
32
  " generate <specFile> Generate artifacts from explicit spec file",
30
33
  " verify <specFile> Verify explicit spec file only",
31
34
  " clean <path> [-f|--force] Remove generated artifacts under path",
32
35
  "",
33
36
  "Options:",
37
+ " --designerplugin Build Qt Designer plugin (build command only, QWidget target required)",
34
38
  " -h, --help Show this help output"
35
39
  ].join("\n");
36
40
  }
37
41
  function usageFor(command) {
38
42
  if (command === "instill")
39
43
  return "Usage: anqst instill <WidgetName>";
44
+ if (command === "build")
45
+ return "Usage: anqst build [--designerplugin[=true|false]]";
40
46
  if (command === "verify")
41
47
  return "Usage: anqst verify <specFile>";
42
48
  if (command === "generate")
@@ -45,6 +51,50 @@ function usageFor(command) {
45
51
  return "Usage: anqst clean <path> [-f|--force]";
46
52
  return renderHelp();
47
53
  }
54
+ function resetGeneratedTargets(cwd, widgetName, targets) {
55
+ const layout = (0, layout_1.resolveGeneratedLayoutPaths)(cwd, widgetName);
56
+ const roots = new Set();
57
+ if (targets.emitAngularService) {
58
+ roots.add(layout.frontendRoot);
59
+ }
60
+ if (targets.emitNodeExpressWs) {
61
+ roots.add(layout.nodeExpressRoot);
62
+ }
63
+ if (targets.emitQWidget) {
64
+ roots.add(layout.cppQtWidgetRoot);
65
+ roots.add(layout.cppCmakeRoot);
66
+ }
67
+ if ((0, debug_dump_1.isDebugEnabled)()) {
68
+ roots.add(layout.debugIntermediateRoot);
69
+ }
70
+ for (const root of roots) {
71
+ node_fs_1.default.rmSync(root, { recursive: true, force: true });
72
+ }
73
+ }
74
+ function buildGenerateSummary(cwd, specPath, widgetName, generationTargets) {
75
+ const layout = (0, layout_1.resolveGeneratedLayoutPaths)(cwd, widgetName);
76
+ const relativeSpecFile = (0, layout_1.normalizeSlashes)(node_path_1.default.relative(cwd, specPath));
77
+ const servicePath = (0, layout_1.toProjectRelative)(cwd, node_path_1.default.join(layout.frontendRoot, "services"));
78
+ const typePath = (0, layout_1.toProjectRelative)(cwd, node_path_1.default.join(layout.frontendRoot, "types"));
79
+ const widgetRootPath = (0, layout_1.toProjectRelative)(cwd, layout.cppQtWidgetRoot);
80
+ const nodePath = (0, layout_1.toProjectRelative)(cwd, layout.nodeExpressRoot);
81
+ const messageLines = [];
82
+ messageLines.push(`AnQst spec ${relativeSpecFile} built.`);
83
+ if (generationTargets.emitAngularService) {
84
+ messageLines.push(` Services are available from ${servicePath}.`);
85
+ messageLines.push(` Generated types are available from ${typePath}.`);
86
+ }
87
+ if (generationTargets.emitQWidget) {
88
+ messageLines.push(` Widget library available in ${widgetRootPath}.`);
89
+ }
90
+ if (generationTargets.emitNodeExpressWs) {
91
+ messageLines.push(` Node Express WS module available in ${nodePath}.`);
92
+ }
93
+ if (!generationTargets.emitAngularService && !generationTargets.emitQWidget && !generationTargets.emitNodeExpressWs) {
94
+ messageLines.push(" No outputs selected by AnQst.generate.");
95
+ }
96
+ return `\n${messageLines.join("\n")}\n`;
97
+ }
48
98
  function runVerify(specArg) {
49
99
  const specPath = node_path_1.default.resolve(process.cwd(), specArg);
50
100
  const parsed = (0, parser_1.parseSpecFile)(specPath);
@@ -60,38 +110,16 @@ function runGenerate(specArg) {
60
110
  const parsed = (0, parser_1.parseSpecFile)(specPath);
61
111
  const verification = (0, verify_1.verifySpec)(parsed);
62
112
  const generationTargets = resolveGenerationTargetsFromCwd(cwd);
113
+ resetGeneratedTargets(cwd, parsed.widgetName, generationTargets);
63
114
  const outputs = (0, emit_1.generateOutputs)(parsed, generationTargets);
64
115
  (0, emit_1.writeGeneratedOutputs)(cwd, outputs);
65
- if (generationTargets.emitAngularService) {
66
- (0, emit_1.installTypeScriptOutputs)(cwd);
67
- }
68
116
  if (generationTargets.emitQWidget) {
69
117
  (0, emit_1.installQtIntegrationCMake)(cwd, parsed.widgetName);
70
118
  }
71
- const relativeSpecFile = normalizeSlashes(node_path_1.default.relative(cwd, specPath));
72
- const relativeTypeScriptInstallPath = normalizeSlashes(node_path_1.default.relative(cwd, node_path_1.default.join(cwd, "src", "anqst-generated")));
73
- const relativeCppLibraryPath = normalizeSlashes(node_path_1.default.relative(cwd, node_path_1.default.join(cwd, "generated_output", `${parsed.widgetName}_QtWidget`)));
74
- const relativeNodeModulePath = normalizeSlashes(node_path_1.default.relative(cwd, node_path_1.default.join(cwd, "generated_output", `${parsed.widgetName}_node_express_ws`)));
75
- const serviceList = parsed.services.map((s) => s.name).join(", ");
76
- const messageLines = [];
77
- messageLines.push(`AnQst spec ${relativeSpecFile} built.`);
78
- if (generationTargets.emitAngularService) {
79
- messageLines.push(` Services ${serviceList} are available from ${relativeTypeScriptInstallPath}/services.`);
80
- messageLines.push(` Generated types are available from ${relativeTypeScriptInstallPath}/types.`);
81
- }
82
- if (generationTargets.emitQWidget) {
83
- messageLines.push(` Widget library available in ${relativeCppLibraryPath}.`);
84
- }
85
- if (generationTargets.emitNodeExpressWs) {
86
- messageLines.push(` Node Express WS module available in ${relativeNodeModulePath}.`);
87
- }
88
- if (!generationTargets.emitAngularService && !generationTargets.emitQWidget && !generationTargets.emitNodeExpressWs) {
89
- messageLines.push(" No outputs selected by AnQst.generate.");
90
- }
91
119
  return {
92
120
  success: true,
93
121
  verificationMessage: verification.message,
94
- message: `\n${messageLines.join("\n")}\n`
122
+ message: buildGenerateSummary(cwd, specPath, parsed.widgetName, generationTargets)
95
123
  };
96
124
  }
97
125
  function runTest(cwd) {
@@ -103,57 +131,206 @@ function runTest(cwd) {
103
131
  message: verification.message
104
132
  };
105
133
  }
106
- function runBuild(cwd) {
107
- const specPath = (0, project_1.resolveAnQstSpecPath)(cwd);
108
- const generationTargets = resolveGenerationTargetsFromCwd(cwd, true);
109
- const parsed = (0, parser_1.parseSpecFile)(specPath);
110
- (0, verify_1.verifySpec)(parsed);
111
- const outputs = (0, emit_1.generateOutputs)(parsed, generationTargets);
112
- (0, emit_1.writeGeneratedOutputs)(cwd, outputs);
113
- if (generationTargets.emitAngularService) {
114
- (0, emit_1.installTypeScriptOutputs)(cwd);
134
+ function resolveAnQstGenRoot() {
135
+ return node_path_1.default.resolve(__dirname, "..", "..");
136
+ }
137
+ function readActiveBuildStamp() {
138
+ if (process.env.ANQST_BUILD_STAMP && process.env.ANQST_BUILD_STAMP.trim().length > 0) {
139
+ return process.env.ANQST_BUILD_STAMP.trim();
115
140
  }
116
- if (generationTargets.emitQWidget) {
117
- (0, emit_1.installQtIntegrationCMake)(cwd, parsed.widgetName);
141
+ const activePath = node_path_1.default.join(resolveAnQstGenRoot(), ANQSTGEN_ACTIVE_STAMP_FILE);
142
+ if (!node_fs_1.default.existsSync(activePath)) {
143
+ return "unknown_build_0";
118
144
  }
119
- const hasAngularProject = generationTargets.emitQWidget && node_fs_1.default.existsSync(node_path_1.default.join(cwd, "angular.json"));
120
- if (hasAngularProject && generationTargets.emitQWidget) {
121
- const angularBuild = (0, node_child_process_1.spawnSync)("npx", ["ng", "build", "--configuration", "production"], {
122
- cwd,
123
- stdio: "inherit",
124
- shell: process.platform === "win32"
125
- });
126
- if (angularBuild.status !== 0) {
127
- throw new errors_1.VerifyError("Angular build failed while preparing embedded widget assets.");
145
+ try {
146
+ const parsed = JSON.parse(node_fs_1.default.readFileSync(activePath, "utf8"));
147
+ if (typeof parsed.active === "string" && parsed.active.trim().length > 0) {
148
+ return parsed.active.trim();
128
149
  }
129
150
  }
130
- if (generationTargets.emitQWidget) {
131
- const embedded = (0, emit_1.installEmbeddedWebBundle)(cwd, parsed.widgetName);
132
- if (hasAngularProject && !embedded) {
133
- throw new errors_1.VerifyError("Unable to embed Angular output. Ensure ng build produced a dist bundle with index.html.");
134
- }
151
+ catch {
152
+ // Fallback to deterministic unknown stamp.
135
153
  }
136
- if (!generationTargets.emitAngularService && !generationTargets.emitQWidget && !generationTargets.emitNodeExpressWs) {
154
+ return "unknown_build_0";
155
+ }
156
+ function runDesignerPluginBuild(cwd, widgetName) {
157
+ const layout = (0, layout_1.resolveGeneratedLayoutPaths)(cwd, widgetName);
158
+ const pluginSourceDir = layout.designerPluginRoot;
159
+ const pluginBuildDir = layout.designerPluginBuildRoot;
160
+ const webBaseDir = process.env.ANQST_WEBBASE_DIR?.trim();
161
+ if (!webBaseDir) {
162
+ throw new errors_1.VerifyError("Missing ANQST_WEBBASE_DIR environment variable for --designerplugin build.");
163
+ }
164
+ const configureArgs = [
165
+ "-S",
166
+ pluginSourceDir,
167
+ "-B",
168
+ pluginBuildDir,
169
+ "-DCMAKE_BUILD_TYPE=Release",
170
+ `-DANQST_WEBBASE_DIR=${webBaseDir}`
171
+ ];
172
+ const configure = (0, node_child_process_1.spawnSync)("cmake", configureArgs, {
173
+ cwd,
174
+ stdio: "inherit",
175
+ shell: process.platform === "win32"
176
+ });
177
+ if (configure.status !== 0) {
178
+ throw new errors_1.VerifyError([
179
+ "CMake configure failed while building Qt Designer plugin.",
180
+ "If CMake reports missing Qt5UiPlugin, install qttools5-dev (Ubuntu/Debian) and re-run install_dependencies.sh."
181
+ ].join(" "));
182
+ }
183
+ const build = (0, node_child_process_1.spawnSync)("cmake", ["--build", pluginBuildDir, "--config", "Release"], {
184
+ cwd,
185
+ stdio: "inherit",
186
+ shell: process.platform === "win32"
187
+ });
188
+ if (build.status !== 0) {
189
+ throw new errors_1.VerifyError("CMake build failed while compiling Qt Designer plugin.");
190
+ }
191
+ }
192
+ function runBuild(cwd, designerPlugin = false) {
193
+ const buildVersion = readActiveBuildStamp();
194
+ process.env.ANQST_BUILD_STAMP = buildVersion;
195
+ try {
196
+ const specPath = (0, project_1.resolveAnQstSpecPath)(cwd);
197
+ const configuredWidgetName = (0, project_1.resolveAnQstWidgetName)(cwd);
198
+ const generationTargets = resolveGenerationTargetsFromCwd(cwd, true);
199
+ const parsed = (0, parser_1.parseSpecFile)(specPath);
200
+ (0, verify_1.verifySpec)(parsed);
201
+ if (parsed.widgetName !== configuredWidgetName) {
202
+ throw new errors_1.VerifyError(`Settings widgetName '${configuredWidgetName}' does not match spec namespace '${parsed.widgetName}'.`);
203
+ }
204
+ resetGeneratedTargets(cwd, parsed.widgetName, generationTargets);
205
+ const outputs = (0, emit_1.generateOutputs)(parsed, generationTargets);
206
+ (0, emit_1.writeGeneratedOutputs)(cwd, outputs);
207
+ if (generationTargets.emitQWidget) {
208
+ (0, emit_1.installQtIntegrationCMake)(cwd, parsed.widgetName);
209
+ }
210
+ const hasAngularProject = generationTargets.emitQWidget && node_fs_1.default.existsSync(node_path_1.default.join(cwd, "angular.json"));
211
+ if (hasAngularProject) {
212
+ const angularBuild = (0, node_child_process_1.spawnSync)("npx", ["ng", "build", "--configuration", "production"], {
213
+ cwd,
214
+ stdio: "inherit",
215
+ shell: process.platform === "win32"
216
+ });
217
+ if (angularBuild.status !== 0) {
218
+ throw new errors_1.VerifyError("Angular build failed while preparing embedded widget assets.");
219
+ }
220
+ }
221
+ if (generationTargets.emitQWidget) {
222
+ const embedded = (0, emit_1.installEmbeddedWebBundle)(cwd, parsed.widgetName);
223
+ if (hasAngularProject && !embedded) {
224
+ throw new errors_1.VerifyError("Unable to embed Angular output. Ensure ng build produced a dist bundle with index.html.");
225
+ }
226
+ }
227
+ let designerPluginBuilt = false;
228
+ if (designerPlugin) {
229
+ if (!generationTargets.emitQWidget) {
230
+ console.warn("[AnQst] --designerplugin requested but QWidget target is not enabled. Skipping designer plugin build.");
231
+ }
232
+ else {
233
+ const widgetCategory = (0, project_1.resolveAnQstWidgetCategory)(cwd);
234
+ (0, emit_1.installQtDesignerPluginCMake)(cwd, parsed.widgetName, { widgetCategory });
235
+ runDesignerPluginBuild(cwd, parsed.widgetName);
236
+ designerPluginBuilt = true;
237
+ }
238
+ }
239
+ if (!generationTargets.emitAngularService && !generationTargets.emitQWidget && !generationTargets.emitNodeExpressWs) {
240
+ return {
241
+ success: true,
242
+ message: [
243
+ "Build completed.",
244
+ ` anqst version ${buildVersion}`,
245
+ " No outputs selected by AnQst.generate."
246
+ ].join("\n")
247
+ };
248
+ }
249
+ const layout = (0, layout_1.resolveGeneratedLayoutPaths)(cwd, parsed.widgetName);
250
+ const detailLines = [];
251
+ if (generationTargets.emitAngularService) {
252
+ detailLines.push(" Target AngularService:");
253
+ detailLines.push(` - Services output: ${(0, layout_1.toProjectRelative)(cwd, node_path_1.default.join(layout.frontendRoot, "services"))}`);
254
+ detailLines.push(` - Types output: ${(0, layout_1.toProjectRelative)(cwd, node_path_1.default.join(layout.frontendRoot, "types"))}`);
255
+ }
256
+ if (generationTargets.emitQWidget) {
257
+ detailLines.push(" Target QWidget:");
258
+ detailLines.push(` - Qt integration CMake: ${(0, layout_1.toProjectRelative)(cwd, node_path_1.default.join(layout.cppCmakeRoot, "CMakeLists.txt"))}`);
259
+ detailLines.push(` - Widget output root: ${(0, layout_1.toProjectRelative)(cwd, layout.cppQtWidgetRoot)}`);
260
+ detailLines.push(" - Embedded web assets refreshed from Angular build");
261
+ }
262
+ if (generationTargets.emitNodeExpressWs) {
263
+ detailLines.push(" Target node_express_ws:");
264
+ detailLines.push(` - Module output root: ${(0, layout_1.toProjectRelative)(cwd, layout.nodeExpressRoot)}`);
265
+ }
266
+ if (designerPluginBuilt) {
267
+ const pluginBinaryPath = (0, layout_1.normalizeSlashes)(node_path_1.default.join((0, layout_1.toProjectRelative)(cwd, layout.designerPluginBuildRoot), designerPluginBinaryName(parsed.widgetName)));
268
+ detailLines.push(" Target QtDesignerPlugin:");
269
+ detailLines.push(` - Build output: ${(0, layout_1.toProjectRelative)(cwd, layout.designerPluginBuildRoot)}`);
270
+ detailLines.push(` - Plugin binary: ${pluginBinaryPath}`);
271
+ detailLines.push(" - Install target dir: <QT_INSTALL_PLUGINS>/designer");
272
+ detailLines.push(" - Discover QT_INSTALL_PLUGINS: qmake -query QT_INSTALL_PLUGINS");
273
+ detailLines.push(` - Example install: cp ${pluginBinaryPath} \"$(qmake -query QT_INSTALL_PLUGINS)/designer/\"`);
274
+ detailLines.push(` - User-local install: mkdir -p \"$HOME/.local/lib/qt5/plugins/designer\" && cp ${pluginBinaryPath} \"$HOME/.local/lib/qt5/plugins/designer/\"`);
275
+ }
137
276
  return {
138
277
  success: true,
139
- message: "Build completed: no outputs selected by AnQst.generate"
278
+ message: [
279
+ "Build completed.",
280
+ ` anqst version ${buildVersion}`,
281
+ ...detailLines
282
+ ].join("\n")
140
283
  };
141
284
  }
142
- const parts = [];
143
- if (generationTargets.emitAngularService) {
144
- parts.push("TypeScript installed to src/anqst-generated");
285
+ finally {
286
+ delete process.env.ANQST_BUILD_STAMP;
145
287
  }
146
- if (generationTargets.emitQWidget) {
147
- parts.push("Qt integration CMake emitted to anqst-cmake/");
148
- parts.push("C++ widget library refreshed with embedded web assets");
288
+ }
289
+ function parseSpecCommandArg(commandName, specArg, extraArgs) {
290
+ const allArgs = [specArg, ...extraArgs].filter((arg) => typeof arg === "string" && arg.length > 0);
291
+ const positional = [];
292
+ for (const arg of allArgs) {
293
+ if (arg.startsWith("-")) {
294
+ throw new Error(`Unknown ${commandName} flag '${arg}'. ${usageFor(commandName)}`);
295
+ }
296
+ positional.push(arg);
149
297
  }
150
- if (generationTargets.emitNodeExpressWs) {
151
- parts.push(`Node Express WS module emitted to generated_output/${parsed.widgetName}_node_express_ws`);
298
+ if (positional.length !== 1) {
299
+ throw new Error(usageFor(commandName));
152
300
  }
153
- return {
154
- success: true,
155
- message: `Build completed: ${parts.join(", ")}`
156
- };
301
+ return positional[0];
302
+ }
303
+ function parseBuildCommandArgs(specArg, extraArgs) {
304
+ const allArgs = [specArg, ...extraArgs].filter((arg) => typeof arg === "string" && arg.length > 0);
305
+ let designerPlugin = false;
306
+ const positional = [];
307
+ for (let i = 0; i < allArgs.length; i += 1) {
308
+ const arg = allArgs[i];
309
+ if (arg === "--designerplugin") {
310
+ const value = allArgs[i + 1];
311
+ if (value && !value.startsWith("-")) {
312
+ designerPlugin = value.toLowerCase() === "true";
313
+ i += 1;
314
+ }
315
+ else {
316
+ designerPlugin = true;
317
+ }
318
+ continue;
319
+ }
320
+ if (arg.startsWith("--designerplugin=")) {
321
+ const value = arg.slice("--designerplugin=".length);
322
+ designerPlugin = value.toLowerCase() === "true";
323
+ continue;
324
+ }
325
+ if (arg.startsWith("-")) {
326
+ throw new Error(`Unknown build flag '${arg}'. ${usageFor("build")}`);
327
+ }
328
+ positional.push(arg);
329
+ }
330
+ if (positional.length > 0) {
331
+ throw new Error(`Unexpected extra argument '${positional[0]}'. ${usageFor("build")}`);
332
+ }
333
+ return { designerPlugin };
157
334
  }
158
335
  function parseCleanCommandArgs(specArg, extraArgs) {
159
336
  const allArgs = [specArg, ...extraArgs].filter((arg) => typeof arg === "string" && arg.length > 0);
@@ -209,7 +386,7 @@ function formatCleanResult(targetRoot, rows) {
209
386
  const notFound = rows.filter((row) => row.status === "not_found");
210
387
  const failed = rows.filter((row) => row.status === "failed");
211
388
  const lines = [];
212
- lines.push(`[AnQst] Clean summary for ${normalizeSlashes(targetRoot)}`);
389
+ lines.push(`[AnQst] Clean summary for ${(0, layout_1.normalizeSlashes)(targetRoot)}`);
213
390
  if (deleted.length > 0) {
214
391
  lines.push(` Deleted (${deleted.length})`);
215
392
  for (const row of deleted)
@@ -231,14 +408,14 @@ function resolveGenerationTargetsFromCwd(cwd, requirePackageAnQst = false) {
231
408
  const packagePath = node_path_1.default.join(cwd, "package.json");
232
409
  if (!node_fs_1.default.existsSync(packagePath)) {
233
410
  if (requirePackageAnQst) {
234
- throw new errors_1.VerifyError("No package.json: Can only build AnQst inside an npm project.");
411
+ throw new errors_1.VerifyError("No package.json: AnQst commands must run inside an npm project.");
235
412
  }
236
413
  return toGenerationTargets([...project_1.DEFAULT_ANQST_GENERATE_TARGETS]);
237
414
  }
238
415
  const packageJson = JSON.parse(node_fs_1.default.readFileSync(packagePath, "utf8"));
239
416
  if (packageJson.AnQst === undefined) {
240
417
  if (requirePackageAnQst) {
241
- throw new errors_1.VerifyError("Missing package.json key 'AnQst.spec'. Run 'anqst instill <WidgetName>' first.");
418
+ throw new errors_1.VerifyError("Missing package.json key 'AnQst'. Run 'anqst instill <WidgetName>' first.");
242
419
  }
243
420
  return toGenerationTargets([...project_1.DEFAULT_ANQST_GENERATE_TARGETS]);
244
421
  }
@@ -251,40 +428,24 @@ function toGenerationTargets(targets) {
251
428
  emitNodeExpressWs: targets.includes("node_express_ws")
252
429
  };
253
430
  }
254
- function resolveAnQstSpecFromPackage(targetRoot) {
255
- const packagePath = node_path_1.default.join(targetRoot, "package.json");
256
- if (!node_fs_1.default.existsSync(packagePath)) {
257
- throw new Error(`No package.json with an AnQst key found at '${normalizeSlashes(targetRoot)}'. Use 'anqst clean ${normalizeSlashes(targetRoot)} --force' to clean anyway.`);
258
- }
259
- const packageJson = JSON.parse(node_fs_1.default.readFileSync(packagePath, "utf8"));
260
- const spec = packageJson.AnQst?.spec;
261
- if (!spec || spec.trim().length === 0) {
262
- throw new Error(`No package.json with an AnQst key found at '${normalizeSlashes(targetRoot)}'. Use 'anqst clean ${normalizeSlashes(targetRoot)} --force' to clean anyway.`);
263
- }
264
- return node_path_1.default.resolve(targetRoot, spec);
265
- }
266
431
  function runClean(pathArg, force) {
267
432
  const targetRoot = node_path_1.default.resolve(process.cwd(), pathArg);
268
- const broadDirs = [
269
- "generated_output",
270
- node_path_1.default.join("src", "anqst-generated"),
271
- "anqst-cmake"
272
- ];
273
433
  if (force) {
274
- const rows = runCleanup(targetRoot, broadDirs);
434
+ const rows = runCleanup(targetRoot, [(0, layout_1.normalizeSlashes)(node_path_1.default.join("AnQst", "generated"))]);
275
435
  return {
276
436
  success: true,
277
437
  message: formatCleanResult(targetRoot, rows),
278
438
  hadFailures: rows.some((row) => row.status === "failed")
279
439
  };
280
440
  }
281
- const specPath = resolveAnQstSpecFromPackage(targetRoot);
282
- const parsed = (0, parser_1.parseSpecFile)(specPath);
441
+ const context = (0, project_1.resolveAnQstSettings)(targetRoot);
442
+ const layout = (0, layout_1.resolveGeneratedLayoutPaths)(targetRoot, context.settings.widgetName);
283
443
  const widgetDirs = [
284
- node_path_1.default.join("generated_output", `${parsed.widgetName}_QtWidget`),
285
- node_path_1.default.join("generated_output", `${parsed.widgetName}_node_express_ws`),
286
- node_path_1.default.join("src", "anqst-generated"),
287
- "anqst-cmake"
444
+ (0, layout_1.normalizeSlashes)(node_path_1.default.relative(targetRoot, layout.frontendRoot)),
445
+ (0, layout_1.normalizeSlashes)(node_path_1.default.relative(targetRoot, layout.nodeExpressRoot)),
446
+ (0, layout_1.normalizeSlashes)(node_path_1.default.relative(targetRoot, layout.cppQtWidgetRoot)),
447
+ (0, layout_1.normalizeSlashes)(node_path_1.default.relative(targetRoot, layout.cppCmakeRoot)),
448
+ (0, layout_1.normalizeSlashes)(node_path_1.default.relative(targetRoot, layout.debugIntermediateRoot))
288
449
  ];
289
450
  const rows = runCleanup(targetRoot, widgetDirs);
290
451
  return {
@@ -293,8 +454,22 @@ function runClean(pathArg, force) {
293
454
  hadFailures: rows.some((row) => row.status === "failed")
294
455
  };
295
456
  }
296
- function normalizeSlashes(inputPath) {
297
- return inputPath.split(node_path_1.default.sep).join("/");
457
+ function designerPluginBinaryName(widgetName) {
458
+ const targetName = `${widgetName}DesignerPlugin`;
459
+ if (process.platform === "win32") {
460
+ return `${targetName}.dll`;
461
+ }
462
+ if (process.platform === "darwin") {
463
+ return `${targetName}.dylib`;
464
+ }
465
+ return `${targetName}.so`;
466
+ }
467
+ function renderInstallAliasMessage() {
468
+ const useColor = process.stdout.isTTY;
469
+ const text = "[AnQst] 'install' spotted. Muscle memory is undefeated - running 'instill' for you.";
470
+ if (!useColor)
471
+ return text;
472
+ return `\x1b[38;5;214m${text}\x1b[0m`;
298
473
  }
299
474
  function runCommand(command, specArg, extraArgs = []) {
300
475
  try {
@@ -306,7 +481,11 @@ function runCommand(command, specArg, extraArgs = []) {
306
481
  console.log(renderHelp());
307
482
  return 0;
308
483
  }
309
- if (command === "instill") {
484
+ const normalizedCommand = command === "install" ? "instill" : command;
485
+ if (command === "install") {
486
+ console.log(renderInstallAliasMessage());
487
+ }
488
+ if (normalizedCommand === "instill") {
310
489
  if (!specArg) {
311
490
  console.error(usageFor("instill"));
312
491
  return 1;
@@ -315,38 +494,33 @@ function runCommand(command, specArg, extraArgs = []) {
315
494
  console.log(msg);
316
495
  return 0;
317
496
  }
318
- if (command === "test") {
497
+ if (normalizedCommand === "test") {
319
498
  const res = runTest(process.cwd());
320
499
  console.log(res.message);
321
500
  return 0;
322
501
  }
323
- if (command === "build") {
324
- const res = runBuild(process.cwd());
502
+ if (normalizedCommand === "build") {
503
+ const parsedArgs = parseBuildCommandArgs(specArg, extraArgs);
504
+ const res = runBuild(process.cwd(), parsedArgs.designerPlugin);
325
505
  console.log(res.message);
326
506
  return 0;
327
507
  }
328
- if (command === "verify") {
329
- if (!specArg) {
330
- console.error(usageFor("verify"));
331
- return 1;
332
- }
333
- const res = runVerify(specArg);
508
+ if (normalizedCommand === "verify") {
509
+ const specArgParsed = parseSpecCommandArg("verify", specArg, extraArgs);
510
+ const res = runVerify(specArgParsed);
334
511
  console.log(res.message);
335
512
  return 0;
336
513
  }
337
- if (command === "generate") {
338
- if (!specArg) {
339
- console.error(usageFor("generate"));
340
- return 1;
341
- }
342
- const res = runGenerate(specArg);
514
+ if (normalizedCommand === "generate") {
515
+ const specArgParsed = parseSpecCommandArg("generate", specArg, extraArgs);
516
+ const res = runGenerate(specArgParsed);
343
517
  if (res.verificationMessage) {
344
518
  console.log(res.verificationMessage);
345
519
  }
346
520
  console.log(res.message);
347
521
  return 0;
348
522
  }
349
- if (command === "clean") {
523
+ if (normalizedCommand === "clean") {
350
524
  const parsed = parseCleanCommandArgs(specArg, extraArgs);
351
525
  const res = runClean(parsed.targetPathArg, parsed.force);
352
526
  console.log(res.message);
File without changes
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.isDebugEnabled = isDebugEnabled;
7
+ exports.writeDebugFile = writeDebugFile;
8
+ exports.inspectText = inspectText;
9
+ const node_fs_1 = __importDefault(require("node:fs"));
10
+ const node_path_1 = __importDefault(require("node:path"));
11
+ const node_util_1 = __importDefault(require("node:util"));
12
+ const layout_1 = require("./layout");
13
+ function isDebugEnabled() {
14
+ return process.env.ANQST_DEBUG === "true";
15
+ }
16
+ function baseIntermediateDir(cwd) {
17
+ return (0, layout_1.anqstDebugIntermediateRootDir)(cwd);
18
+ }
19
+ function writeDebugFile(cwd, relativePath, content) {
20
+ if (!isDebugEnabled())
21
+ return;
22
+ try {
23
+ const targetPath = node_path_1.default.join(baseIntermediateDir(cwd), relativePath);
24
+ node_fs_1.default.mkdirSync(node_path_1.default.dirname(targetPath), { recursive: true });
25
+ node_fs_1.default.writeFileSync(targetPath, content, "utf8");
26
+ }
27
+ catch (error) {
28
+ const message = error instanceof Error ? error.message : String(error);
29
+ console.warn(`[AnQst][debug] Failed writing ${relativePath}: ${message}`);
30
+ }
31
+ }
32
+ function inspectText(value) {
33
+ return node_util_1.default.inspect(value, {
34
+ depth: null,
35
+ maxArrayLength: null,
36
+ maxStringLength: null,
37
+ breakLength: 120,
38
+ compact: false
39
+ });
40
+ }