imxc 0.2.0 → 0.3.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/dist/index.js CHANGED
@@ -1,12 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  import { parseArgs } from 'node:util';
3
- import * as fs from 'node:fs';
4
3
  import * as path from 'node:path';
5
- import { parseFile, extractImports } from './parser.js';
6
- import { validate } from './validator.js';
7
- import { lowerComponent } from './lowering.js';
8
- import { emitComponent, emitComponentHeader, emitRoot } from './emitter.js';
9
- import { initProject } from './init.js';
4
+ import { initProject, addToProject } from './init.js';
5
+ import { compile } from './compile.js';
6
+ import { startWatch } from './watch.js';
10
7
  // Handle `imxc init [dir]` subcommand
11
8
  if (process.argv[2] === 'init') {
12
9
  const dir = process.argv[3] ?? '.';
@@ -14,115 +11,46 @@ if (process.argv[2] === 'init') {
14
11
  initProject(absDir, path.basename(absDir));
15
12
  process.exit(0);
16
13
  }
17
- const { values, positionals } = parseArgs({
18
- allowPositionals: true,
19
- options: { output: { type: 'string', short: 'o' } },
20
- });
21
- if (positionals.length === 0) {
22
- console.error('Usage: imxc <input.tsx ...> -o <output-dir>');
23
- console.error(' imxc init [project-dir]');
24
- process.exit(1);
14
+ // Handle `imxc add [dir]` subcommand
15
+ if (process.argv[2] === 'add') {
16
+ const dir = process.argv[3] ?? '.';
17
+ const absDir = path.resolve(dir);
18
+ addToProject(absDir);
19
+ process.exit(0);
25
20
  }
26
- const outputDir = values.output ?? '.';
27
- fs.mkdirSync(outputDir, { recursive: true });
28
- let hasErrors = false;
29
- const compiled = [];
30
- // Phase 1: Parse, validate, and lower all components
31
- for (const file of positionals) {
32
- if (!fs.existsSync(file)) {
33
- console.error(`${file}:1:1 - error: file not found`);
34
- hasErrors = true;
35
- continue;
36
- }
37
- const source = fs.readFileSync(file, 'utf-8');
38
- const parsed = parseFile(file, source);
39
- if (parsed.errors.length > 0) {
40
- parsed.errors.forEach(e => console.error(`${e.file}:${e.line}:${e.col} - error: ${e.message}`));
41
- hasErrors = true;
42
- continue;
43
- }
44
- const validation = validate(parsed);
45
- if (validation.errors.length > 0) {
46
- validation.errors.forEach(e => console.error(`${e.file}:${e.line}:${e.col} - error: ${e.message}`));
47
- hasErrors = true;
48
- continue;
21
+ // Handle `imxc watch <dir> -o <output-dir>` subcommand
22
+ if (process.argv[2] === 'watch') {
23
+ const watchDir = process.argv[3];
24
+ if (!watchDir) {
25
+ console.error('Usage: imxc watch <dir> -o <output-dir>');
26
+ process.exit(1);
49
27
  }
50
- const ir = lowerComponent(parsed, validation);
51
- const imports = extractImports(parsed.sourceFile);
52
- compiled.push({
53
- name: ir.name,
54
- stateCount: ir.stateSlots.length,
55
- bufferCount: ir.bufferCount,
56
- ir,
57
- imports,
58
- hasProps: ir.params.length > 0,
28
+ const { values } = parseArgs({
29
+ args: process.argv.slice(4),
30
+ allowPositionals: false,
31
+ options: { output: { type: 'string', short: 'o' } },
59
32
  });
33
+ const outputDir = values.output ?? '.';
34
+ startWatch(path.resolve(watchDir), path.resolve(outputDir));
60
35
  }
61
- if (hasErrors)
62
- process.exit(1);
63
- // Phase 2: Build lookup of compiled components for cross-file resolution
64
- const componentMap = new Map();
65
- for (const comp of compiled) {
66
- componentMap.set(comp.name, comp);
67
- }
68
- // Phase 3: Resolve imported component stateCount/bufferCount in IR, then emit
69
- for (const comp of compiled) {
70
- // Resolve cross-file custom component info
71
- resolveCustomComponents(comp.ir.body, componentMap);
72
- // Build import info for #include directives
73
- const importInfos = [];
74
- for (const [importedName] of comp.imports) {
75
- const importedComp = componentMap.get(importedName);
76
- if (importedComp && importedComp.hasProps) {
77
- importInfos.push({
78
- name: importedName,
79
- headerFile: `${importedName}.gen.h`,
80
- });
81
- }
82
- }
83
- // Emit .gen.cpp
84
- const cppOutput = emitComponent(comp.ir, importInfos);
85
- const baseName = comp.name;
86
- const outPath = path.join(outputDir, `${baseName}.gen.cpp`);
87
- fs.writeFileSync(outPath, cppOutput);
88
- console.log(` ${baseName} -> ${outPath}`);
89
- // Emit .gen.h for components with props
90
- if (comp.hasProps) {
91
- const headerOutput = emitComponentHeader(comp.ir);
92
- const headerPath = path.join(outputDir, `${baseName}.gen.h`);
93
- fs.writeFileSync(headerPath, headerOutput);
94
- console.log(` ${baseName} -> ${headerPath} (header)`);
36
+ else {
37
+ // Default: build command
38
+ const { values, positionals } = parseArgs({
39
+ allowPositionals: true,
40
+ options: { output: { type: 'string', short: 'o' } },
41
+ });
42
+ if (positionals.length === 0) {
43
+ console.error('Usage: imxc <input.tsx ...> -o <output-dir>');
44
+ console.error(' imxc init [project-dir]');
45
+ console.error(' imxc add [project-dir]');
46
+ console.error(' imxc watch <dir> -o <output-dir>');
47
+ process.exit(1);
95
48
  }
96
- }
97
- // Phase 4: Emit root entry point
98
- if (compiled.length > 0) {
99
- const root = compiled[0];
100
- const rootOutput = emitRoot(root.name, root.stateCount, root.bufferCount);
101
- const rootPath = path.join(outputDir, 'app_root.gen.cpp');
102
- fs.writeFileSync(rootPath, rootOutput);
103
- console.log(` -> ${rootPath} (root entry point)`);
104
- }
105
- console.log(`imxc: ${compiled.length} component(s) compiled successfully.`);
106
- /**
107
- * Walk IR nodes and update custom_component nodes with resolved stateCount/bufferCount
108
- * from the compiled component map.
109
- */
110
- function resolveCustomComponents(nodes, map) {
111
- for (const node of nodes) {
112
- if (node.kind === 'custom_component') {
113
- const target = map.get(node.name);
114
- if (target) {
115
- node.stateCount = target.stateCount;
116
- node.bufferCount = target.bufferCount;
117
- }
118
- }
119
- else if (node.kind === 'conditional') {
120
- resolveCustomComponents(node.body, map);
121
- if (node.elseBody)
122
- resolveCustomComponents(node.elseBody, map);
123
- }
124
- else if (node.kind === 'list_map') {
125
- resolveCustomComponents(node.body, map);
126
- }
49
+ const outputDir = values.output ?? '.';
50
+ const result = compile(positionals, outputDir);
51
+ if (!result.success) {
52
+ result.errors.forEach(e => console.error(e));
53
+ process.exit(1);
127
54
  }
55
+ console.log(`imxc: ${result.componentCount} component(s) compiled successfully.`);
128
56
  }
package/dist/init.d.ts CHANGED
@@ -1 +1,2 @@
1
+ export declare function addToProject(projectDir: string): void;
1
2
  export declare function initProject(projectDir: string, projectName?: string): void;
package/dist/init.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as fs from 'node:fs';
2
2
  import * as path from 'node:path';
3
- const MAIN_CPP = `#include <reimgui/runtime.h>
4
- #include <reimgui/renderer.h>
3
+ const MAIN_CPP = `#include <imx/runtime.h>
4
+ #include <imx/renderer.h>
5
5
 
6
6
  #include <imgui.h>
7
7
  #include <imgui_impl_glfw.h>
@@ -11,7 +11,7 @@ const MAIN_CPP = `#include <reimgui/runtime.h>
11
11
  struct App {
12
12
  GLFWwindow* window = nullptr;
13
13
  ImGuiIO* io = nullptr;
14
- reimgui::Runtime runtime;
14
+ imx::Runtime runtime;
15
15
  };
16
16
 
17
17
  static void render_frame(App& app) {
@@ -26,7 +26,7 @@ static void render_frame(App& app) {
26
26
  ImGui_ImplGlfw_NewFrame();
27
27
  ImGui::NewFrame();
28
28
 
29
- reimgui::render_root(app.runtime);
29
+ imx::render_root(app.runtime);
30
30
 
31
31
  ImGui::Render();
32
32
  glViewport(0, 0, fb_w, fb_h);
@@ -122,7 +122,7 @@ const APP_TSX = `export default function App() {
122
122
  );
123
123
  }
124
124
  `;
125
- const REIMGUI_DTS = `// reimgui.d.ts — Type definitions for ReImGui components
125
+ const IMX_DTS = `// imx.d.ts — Type definitions for IMX components
126
126
 
127
127
  interface Style {
128
128
  padding?: number;
@@ -140,7 +140,7 @@ interface Style {
140
140
 
141
141
  declare function useState<T>(initial: T): [T, (value: T) => void];
142
142
 
143
- interface WindowProps { title: string; style?: Style; children?: any; }
143
+ interface WindowProps { title: string; open?: boolean; onClose?: () => void; noTitleBar?: boolean; noResize?: boolean; noMove?: boolean; noCollapse?: boolean; noDocking?: boolean; noScrollbar?: boolean; style?: Style; children?: any; }
144
144
  interface ViewProps { style?: Style; children?: any; }
145
145
  interface RowProps { gap?: number; style?: Style; children?: any; }
146
146
  interface ColumnProps { gap?: number; style?: Style; children?: any; }
@@ -151,6 +151,21 @@ interface CheckboxProps { value: boolean; onChange: (v: boolean) => void; label?
151
151
  interface SeparatorProps {}
152
152
  interface PopupProps { id: string; style?: Style; children?: any; }
153
153
  interface DockSpaceProps { style?: Style; children?: any; }
154
+ interface DockLayoutProps { children?: any; }
155
+ interface DockSplitProps { direction: "horizontal" | "vertical"; size: number; children?: any; }
156
+ interface DockPanelProps { children?: any; }
157
+ interface ThemeProps {
158
+ preset: string;
159
+ accentColor?: [number, number, number, number];
160
+ backgroundColor?: [number, number, number, number];
161
+ textColor?: [number, number, number, number];
162
+ borderColor?: [number, number, number, number];
163
+ surfaceColor?: [number, number, number, number];
164
+ rounding?: number;
165
+ borderSize?: number;
166
+ spacing?: number;
167
+ children?: any;
168
+ }
154
169
  interface MenuBarProps { children?: any; }
155
170
  interface MenuProps { label: string; children?: any; }
156
171
  interface MenuItemProps { label: string; onPress?: () => void; shortcut?: string; }
@@ -171,6 +186,48 @@ interface ColorEditProps { label: string; value: number[]; onChange: (v: number[
171
186
  interface ListBoxProps { label: string; value: number; onChange: (v: number) => void; items: string[]; style?: Style; }
172
187
  interface ProgressBarProps { value: number; overlay?: string; style?: Style; }
173
188
  interface TooltipProps { text: string; }
189
+ interface BulletTextProps { style?: Style; children?: any; }
190
+ interface LabelTextProps { label: string; value: string; }
191
+ interface SelectableProps { label: string; selected?: boolean; onSelect?: () => void; style?: Style; }
192
+ interface RadioProps { label: string; value: number; index: number; onChange?: (v: number) => void; style?: Style; }
193
+ interface InputTextMultilineProps { label: string; value: string; style?: Style; }
194
+ interface ColorPickerProps { label: string; value: number[]; style?: Style; }
195
+ interface PlotLinesProps { label: string; values: number[]; overlay?: string; style?: Style; }
196
+ interface PlotHistogramProps { label: string; values: number[]; overlay?: string; style?: Style; }
197
+ interface ModalProps { title: string; open?: boolean; onClose?: () => void; style?: Style; children?: any; }
198
+ interface ImageProps { src: string; embed?: boolean; width?: number; height?: number; }
199
+ interface GroupProps { style?: Style; children?: any; }
200
+ interface IDProps { scope: string | number; children?: any; }
201
+ interface DragDropSourceProps { type: string; payload: number | string; children?: any; }
202
+ interface DragDropTargetProps { type: string; onDrop: (payload: any) => void; children?: any; }
203
+ interface CanvasProps { width: number; height: number; style?: Style; children?: any; }
204
+ interface DrawLineProps { p1: [number, number]; p2: [number, number]; color: [number, number, number, number]; thickness?: number; }
205
+ interface DrawRectProps { min: [number, number]; max: [number, number]; color: [number, number, number, number]; filled?: boolean; thickness?: number; rounding?: number; }
206
+ interface DrawCircleProps { center: [number, number]; radius: number; color: [number, number, number, number]; filled?: boolean; thickness?: number; }
207
+ interface DrawTextProps { pos: [number, number]; text: string; color: [number, number, number, number]; }
208
+ interface StyleColorProps {
209
+ text?: [number, number, number, number];
210
+ textDisabled?: [number, number, number, number];
211
+ windowBg?: [number, number, number, number];
212
+ frameBg?: [number, number, number, number];
213
+ frameBgHovered?: [number, number, number, number];
214
+ frameBgActive?: [number, number, number, number];
215
+ titleBg?: [number, number, number, number];
216
+ titleBgActive?: [number, number, number, number];
217
+ button?: [number, number, number, number];
218
+ buttonHovered?: [number, number, number, number];
219
+ buttonActive?: [number, number, number, number];
220
+ header?: [number, number, number, number];
221
+ headerHovered?: [number, number, number, number];
222
+ headerActive?: [number, number, number, number];
223
+ separator?: [number, number, number, number];
224
+ checkMark?: [number, number, number, number];
225
+ sliderGrab?: [number, number, number, number];
226
+ border?: [number, number, number, number];
227
+ popupBg?: [number, number, number, number];
228
+ tab?: [number, number, number, number];
229
+ children?: any;
230
+ }
174
231
 
175
232
  declare function Window(props: WindowProps): any;
176
233
  declare function View(props: ViewProps): any;
@@ -183,6 +240,10 @@ declare function Checkbox(props: CheckboxProps): any;
183
240
  declare function Separator(props: SeparatorProps): any;
184
241
  declare function Popup(props: PopupProps): any;
185
242
  declare function DockSpace(props: DockSpaceProps): any;
243
+ declare function DockLayout(props: DockLayoutProps): any;
244
+ declare function DockSplit(props: DockSplitProps): any;
245
+ declare function DockPanel(props: DockPanelProps): any;
246
+ declare function Theme(props: ThemeProps): any;
186
247
  declare function MenuBar(props: MenuBarProps): any;
187
248
  declare function Menu(props: MenuProps): any;
188
249
  declare function MenuItem(props: MenuItemProps): any;
@@ -203,8 +264,63 @@ declare function ColorEdit(props: ColorEditProps): any;
203
264
  declare function ListBox(props: ListBoxProps): any;
204
265
  declare function ProgressBar(props: ProgressBarProps): any;
205
266
  declare function Tooltip(props: TooltipProps): any;
267
+ declare function BulletText(props: BulletTextProps): any;
268
+ declare function LabelText(props: LabelTextProps): any;
269
+ declare function Selectable(props: SelectableProps): any;
270
+ declare function Radio(props: RadioProps): any;
271
+ declare function InputTextMultiline(props: InputTextMultilineProps): any;
272
+ declare function ColorPicker(props: ColorPickerProps): any;
273
+ declare function PlotLines(props: PlotLinesProps): any;
274
+ declare function PlotHistogram(props: PlotHistogramProps): any;
275
+ declare function Modal(props: ModalProps): any;
276
+ declare function Image(props: ImageProps): any;
277
+ declare function Group(props: GroupProps): any;
278
+ declare function ID(props: IDProps): any;
279
+ declare function StyleColor(props: StyleColorProps): any;
280
+ declare function Canvas(props: CanvasProps): any;
281
+ declare function DrawLine(props: DrawLineProps): any;
282
+ declare function DrawRect(props: DrawRectProps): any;
283
+ declare function DrawCircle(props: DrawCircleProps): any;
284
+ declare function DrawText(props: DrawTextProps): any;
285
+
286
+ interface StyleVarProps {
287
+ alpha?: number;
288
+ windowPadding?: [number, number];
289
+ windowRounding?: number;
290
+ framePadding?: [number, number];
291
+ frameRounding?: number;
292
+ frameBorderSize?: number;
293
+ itemSpacing?: [number, number];
294
+ itemInnerSpacing?: [number, number];
295
+ indentSpacing?: number;
296
+ cellPadding?: [number, number];
297
+ tabRounding?: number;
298
+ children?: any;
299
+ }
300
+ declare function StyleVar(props: StyleVarProps): any;
301
+ declare function DragDropSource(props: DragDropSourceProps): any;
302
+ declare function DragDropTarget(props: DragDropTargetProps): any;
303
+ interface DisabledProps { disabled?: boolean; children?: any; }
304
+ interface ChildProps { id: string; width?: number; height?: number; border?: boolean; style?: Style; children?: any; }
305
+ declare function Disabled(props: DisabledProps): any;
306
+ declare function Child(props: ChildProps): any;
307
+
308
+ declare function resetLayout(): void;
206
309
 
207
- declare module "reimgui/jsx-runtime" {
310
+ // --- Custom native widgets ---
311
+ // Declare your C++ registered widgets here for type checking:
312
+ //
313
+ // interface KnobProps {
314
+ // value: number;
315
+ // onChange: (value: number) => void;
316
+ // min: number;
317
+ // max: number;
318
+ // width?: number;
319
+ // height?: number;
320
+ // }
321
+ // declare function Knob(props: KnobProps): any;
322
+
323
+ declare module "imx/jsx-runtime" {
208
324
  export namespace JSX {
209
325
  type Element = any;
210
326
  interface IntrinsicElements { [tag: string]: any; }
@@ -222,12 +338,12 @@ const TSCONFIG = `{
222
338
  "module": "ES2022",
223
339
  "moduleResolution": "bundler",
224
340
  "jsx": "react-jsx",
225
- "jsxImportSource": "reimgui",
341
+ "jsxImportSource": "imx",
226
342
  "strict": false,
227
343
  "noEmit": true,
228
344
  "skipLibCheck": true
229
345
  },
230
- "include": ["src/**/*.tsx", "src/reimgui.d.ts"]
346
+ "include": ["src/**/*.tsx", "src/imx.d.ts"]
231
347
  }
232
348
  `;
233
349
  function cmakeTemplate(projectName, repoUrl) {
@@ -238,17 +354,20 @@ set(CMAKE_CXX_STANDARD 20)
238
354
  set(CMAKE_CXX_STANDARD_REQUIRED ON)
239
355
 
240
356
  include(FetchContent)
357
+ set(FETCHCONTENT_QUIET OFF)
241
358
 
242
359
  FetchContent_Declare(
243
- reimgui
360
+ imx
244
361
  GIT_REPOSITORY ${repoUrl}
245
362
  GIT_TAG main
363
+ GIT_PROGRESS TRUE
246
364
  )
247
- FetchContent_MakeAvailable(reimgui)
365
+ message(STATUS "Fetching IMX (includes ImGui + GLFW)...")
366
+ FetchContent_MakeAvailable(imx)
248
367
 
249
- include(ReImGuiCompile)
368
+ include(ImxCompile)
250
369
 
251
- reimgui_compile_tsx(GENERATED
370
+ imx_compile_tsx(GENERATED
252
371
  SOURCES src/App.tsx
253
372
  OUTPUT_DIR \${CMAKE_BINARY_DIR}/generated
254
373
  )
@@ -257,10 +376,73 @@ add_executable(${projectName}
257
376
  src/main.cpp
258
377
  \${GENERATED}
259
378
  )
260
- target_link_libraries(${projectName} PRIVATE reimgui::renderer)
379
+ target_link_libraries(${projectName} PRIVATE imx::renderer)
261
380
  target_include_directories(${projectName} PRIVATE \${CMAKE_BINARY_DIR}/generated)
381
+
382
+ # Copy public/ assets to output directory
383
+ add_custom_command(TARGET ${projectName} POST_BUILD
384
+ COMMAND \${CMAKE_COMMAND} -E copy_directory
385
+ \${CMAKE_CURRENT_SOURCE_DIR}/public
386
+ $<TARGET_FILE_DIR:${projectName}>
387
+ COMMENT "Copying public/ assets"
388
+ )
262
389
  `;
263
390
  }
391
+ export function addToProject(projectDir) {
392
+ const srcDir = path.join(projectDir, 'src');
393
+ if (fs.existsSync(path.join(srcDir, 'App.tsx'))) {
394
+ console.error(`Error: ${srcDir}/App.tsx already exists. Aborting.`);
395
+ process.exit(1);
396
+ }
397
+ fs.mkdirSync(srcDir, { recursive: true });
398
+ const publicDir = path.join(projectDir, 'public');
399
+ fs.mkdirSync(publicDir, { recursive: true });
400
+ // Write TSX source files only — no CMakeLists.txt or main.cpp
401
+ fs.writeFileSync(path.join(srcDir, 'App.tsx'), APP_TSX);
402
+ fs.writeFileSync(path.join(srcDir, 'imx.d.ts'), IMX_DTS);
403
+ fs.writeFileSync(path.join(projectDir, 'tsconfig.json'), TSCONFIG);
404
+ console.log(`imxc: added IMX sources to project`);
405
+ console.log('');
406
+ console.log(' Created:');
407
+ console.log(` src/App.tsx — your root component`);
408
+ console.log(` src/imx.d.ts — type definitions for IDE support`);
409
+ console.log(` tsconfig.json — TypeScript config`);
410
+ console.log(` public/ — static assets (copied to exe directory)`);
411
+ console.log('');
412
+ console.log(' Add to your CMakeLists.txt:');
413
+ console.log('');
414
+ console.log(' # --- IMX integration ---');
415
+ console.log(' include(FetchContent)');
416
+ console.log(' FetchContent_Declare(imx');
417
+ console.log(' GIT_REPOSITORY https://github.com/bgocumlu/imx.git');
418
+ console.log(' GIT_TAG main');
419
+ console.log(' )');
420
+ console.log(' FetchContent_MakeAvailable(imx)');
421
+ console.log(' include(ImxCompile)');
422
+ console.log('');
423
+ console.log(' imx_compile_tsx(GENERATED');
424
+ console.log(' SOURCES src/App.tsx');
425
+ console.log(' OUTPUT_DIR ${CMAKE_BINARY_DIR}/generated');
426
+ console.log(' )');
427
+ console.log('');
428
+ console.log(' # Add ${GENERATED} to your target sources:');
429
+ console.log(' target_sources(your_app PRIVATE ${GENERATED})');
430
+ console.log(' target_link_libraries(your_app PRIVATE imx::renderer)');
431
+ console.log(' target_include_directories(your_app PRIVATE ${CMAKE_BINARY_DIR}/generated)');
432
+ console.log('');
433
+ console.log(' # Copy assets to exe directory:');
434
+ console.log(' add_custom_command(TARGET your_app POST_BUILD');
435
+ console.log(' COMMAND ${CMAKE_COMMAND} -E copy_directory');
436
+ console.log(' ${CMAKE_CURRENT_SOURCE_DIR}/public $<TARGET_FILE_DIR:your_app>');
437
+ console.log(' )');
438
+ console.log('');
439
+ console.log(' Then add the IMX render call to your main loop:');
440
+ console.log('');
441
+ console.log(' #include <imx/runtime.h>');
442
+ console.log(' imx::Runtime runtime;');
443
+ console.log(' // In your frame loop, between NewFrame() and Render():');
444
+ console.log(' imx::render_root(runtime);');
445
+ }
264
446
  export function initProject(projectDir, projectName) {
265
447
  const name = projectName ?? path.basename(projectDir);
266
448
  const srcDir = path.join(projectDir, 'src');
@@ -269,20 +451,23 @@ export function initProject(projectDir, projectName) {
269
451
  process.exit(1);
270
452
  }
271
453
  fs.mkdirSync(srcDir, { recursive: true });
454
+ const publicDir = path.join(projectDir, 'public');
455
+ fs.mkdirSync(publicDir, { recursive: true });
272
456
  // Write files
273
457
  fs.writeFileSync(path.join(srcDir, 'main.cpp'), MAIN_CPP.replace('APP_NAME', name));
274
458
  fs.writeFileSync(path.join(srcDir, 'App.tsx'), APP_TSX);
275
- fs.writeFileSync(path.join(srcDir, 'reimgui.d.ts'), REIMGUI_DTS);
459
+ fs.writeFileSync(path.join(srcDir, 'imx.d.ts'), IMX_DTS);
276
460
  fs.writeFileSync(path.join(projectDir, 'tsconfig.json'), TSCONFIG);
277
- fs.writeFileSync(path.join(projectDir, 'CMakeLists.txt'), cmakeTemplate(name, 'https://github.com/bgocumlu/reimgui.git'));
461
+ fs.writeFileSync(path.join(projectDir, 'CMakeLists.txt'), cmakeTemplate(name, 'https://github.com/bgocumlu/imx.git'));
278
462
  console.log(`imxc: initialized project "${name}"`);
279
463
  console.log('');
280
464
  console.log(' Created:');
281
465
  console.log(` src/main.cpp — app shell (GLFW + OpenGL + ImGui)`);
282
466
  console.log(` src/App.tsx — your root component`);
283
- console.log(` src/reimgui.d.ts — type definitions for IDE support`);
467
+ console.log(` src/imx.d.ts — type definitions for IDE support`);
284
468
  console.log(` tsconfig.json — TypeScript config`);
285
469
  console.log(` CMakeLists.txt — build config with FetchContent`);
470
+ console.log(` public/ — static assets (copied to exe directory)`);
286
471
  console.log('');
287
472
  console.log(' Next steps:');
288
473
  console.log(` cmake -B build`);