@el-j/magic-agent-helix 4.0.0-beta.1 โ†’ 4.0.0-beta.3

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/cli.mjs CHANGED
@@ -1,22 +1,22 @@
1
1
  #!/usr/bin/env node
2
2
  import * as p from "node:fs";
3
- import { realpathSync as se, readFileSync as ie } from "node:fs";
4
- import * as f from "node:path";
5
- import { resolve as re, dirname as ae, join as ce } from "node:path";
6
- import { fileURLToPath as Y } from "node:url";
7
- import { Command as le } from "commander";
3
+ import { realpathSync as te, readFileSync as oe } from "node:fs";
4
+ import * as d from "node:path";
5
+ import { resolve as ne, dirname as se, join as ie } from "node:path";
6
+ import { fileURLToPath as U } from "node:url";
7
+ import { Command as re } from "commander";
8
8
  import t from "picocolors";
9
- import { loadUserConfig as N, mergeConfigs as L, PluginRegistry as T, getFormatter as Q, BUILT_IN_TEMPLATE_DIR as K, validateInstructions as ge } from "@el-j/magic-helix-core";
9
+ import { loadUserConfig as N, mergeConfigs as L, PluginRegistry as C, getFormatter as Y, validateInstructions as ae } from "@el-j/magic-helix-core";
10
10
  import W from "inquirer";
11
11
  import j from "ora";
12
12
  import q from "gradient-string";
13
- import { glob as ue } from "glob";
14
- async function de() {
13
+ import { glob as ce } from "glob";
14
+ async function le() {
15
15
  console.log(t.cyan(`๐Ÿงน Cleaning generated instruction files...
16
16
  `));
17
17
  const e = j("Loading configuration...").start(), n = N(), s = L(n);
18
18
  e.succeed("Configuration loaded.");
19
- const r = f.resolve(
19
+ const r = d.resolve(
20
20
  process.cwd(),
21
21
  s.outputDirectory
22
22
  );
@@ -58,7 +58,7 @@ async function de() {
58
58
  let i = 0, l = 0;
59
59
  for (const g of a)
60
60
  try {
61
- p.unlinkSync(f.join(r, g)), i++;
61
+ p.unlinkSync(d.join(r, g)), i++;
62
62
  } catch (u) {
63
63
  console.error(
64
64
  t.red(` โŒ Error deleting ${g}: ${u.message}`)
@@ -72,9 +72,9 @@ async function de() {
72
72
  )
73
73
  );
74
74
  }
75
- const G = "magic-helix.config.json", z = "ai_templates", fe = {
75
+ const _ = "magic-helix.config.json", O = "ai_templates", ge = {
76
76
  target: "github-copilot",
77
- templateDirectory: z,
77
+ templateDirectory: O,
78
78
  outputDirectory: ".github/instructions",
79
79
  dependencyTagMap: {
80
80
  // "my-internal-package": "domain-my-rules"
@@ -91,17 +91,17 @@ const G = "magic-helix.config.json", z = "ai_templates", fe = {
91
91
  // ]
92
92
  }
93
93
  };
94
- async function pe() {
94
+ async function ue() {
95
95
  const e = j(
96
96
  t.bold("Initializing Magic Helix for custom rules...")
97
- ).start(), n = f.resolve(process.cwd(), G), s = f.resolve(process.cwd(), z);
97
+ ).start(), n = d.resolve(process.cwd(), _), s = d.resolve(process.cwd(), O);
98
98
  if (p.existsSync(n)) {
99
99
  e.stop();
100
100
  const { overwrite: a } = await W.prompt([
101
101
  {
102
102
  type: "confirm",
103
103
  name: "overwrite",
104
- message: `A ${G} file already exists. Do you want to overwrite it with a minimal example?`,
104
+ message: `A ${_} file already exists. Do you want to overwrite it with a minimal example?`,
105
105
  default: !1
106
106
  }
107
107
  ]);
@@ -114,20 +114,20 @@ async function pe() {
114
114
  try {
115
115
  p.writeFileSync(
116
116
  n,
117
- JSON.stringify(fe, null, 2),
117
+ JSON.stringify(ge, null, 2),
118
118
  "utf-8"
119
119
  ), e.succeed(
120
- t.green(`Created minimal config file: ${t.bold(G)}`)
120
+ t.green(`Created minimal config file: ${t.bold(_)}`)
121
121
  );
122
122
  } catch (a) {
123
123
  e.fail(t.red(`Error writing config file: ${a.message}`));
124
124
  return;
125
125
  }
126
126
  e.start("Creating templates directory..."), p.existsSync(s) || p.mkdirSync(s, { recursive: !0 });
127
- const r = f.resolve(s, "my-custom-rule.md");
127
+ const r = d.resolve(s, "my-custom-rule.md");
128
128
  p.existsSync(r) ? e.succeed(
129
129
  t.green(
130
- `Templates directory ${t.bold(z)} already exists.`
130
+ `Templates directory ${t.bold(O)} already exists.`
131
131
  )
132
132
  ) : (p.writeFileSync(
133
133
  r,
@@ -138,7 +138,7 @@ async function pe() {
138
138
  "utf-8"
139
139
  ), e.succeed(
140
140
  t.green(
141
- `Created templates directory and example file: ${t.bold(z)}`
141
+ `Created templates directory and example file: ${t.bold(O)}`
142
142
  )
143
143
  )), console.log(
144
144
  q.pastel.multiline(
@@ -147,19 +147,19 @@ async function pe() {
147
147
  )
148
148
  ), console.log(t.cyan(`
149
149
  Next steps:`)), console.log(
150
- ` 1. Edit ${t.bold(G)} to define your team's "tags".`
150
+ ` 1. Edit ${t.bold(_)} to define your team's "tags".`
151
151
  ), console.log(
152
- ` 2. Add your custom .md instruction files to ${t.bold(z)}.`
152
+ ` 2. Add your custom .md instruction files to ${t.bold(O)}.`
153
153
  ), console.log(
154
154
  ` 3. Run ${t.bold("npx @el-j/magic-agent-helix run")} to generate your files.`
155
155
  );
156
156
  }
157
- async function me() {
157
+ async function de() {
158
158
  console.log(t.cyan(`๐Ÿ“‹ Listing project information...
159
159
  `));
160
160
  const e = j("Loading configuration...").start(), n = N(), s = L(n);
161
161
  e.succeed("Configuration loaded.");
162
- const { dependencyTagMap: r, configFileTagMap: a, fileGlobTagMap: o, tagTemplateMap: c } = s, i = j("Scanning for projects...").start(), l = await ye();
162
+ const { dependencyTagMap: r, configFileTagMap: a, fileGlobTagMap: o, tagTemplateMap: c } = s, i = j("Scanning for projects...").start(), l = await fe();
163
163
  if (l.length === 0) {
164
164
  i.warn(t.yellow("No projects found."));
165
165
  return;
@@ -167,7 +167,7 @@ async function me() {
167
167
  i.succeed(`Found ${l.length} projects.`);
168
168
  const g = j("Analyzing projects...").start();
169
169
  for (const u of l)
170
- await he(
170
+ await pe(
171
171
  u,
172
172
  r,
173
173
  a,
@@ -181,40 +181,40 @@ async function me() {
181
181
  console.log(t.yellow(" No tags detected"));
182
182
  else {
183
183
  console.log(t.green(` Tags: ${[...u.tags].join(", ")}`));
184
- const y = [];
184
+ const h = [];
185
185
  for (const w of u.tags) {
186
186
  const m = c[w];
187
187
  if (m)
188
- for (const x of m)
189
- y.push(`${u.name}.${x.suffix}`);
188
+ for (const v of m)
189
+ h.push(`${u.name}.${v.suffix}`);
190
190
  }
191
- y.length > 0 && console.log(t.gray(` Would generate: ${y.join(", ")}`));
191
+ h.length > 0 && console.log(t.gray(` Would generate: ${h.join(", ")}`));
192
192
  }
193
193
  console.log();
194
194
  }
195
195
  console.log(t.cyan(t.bold(`Configuration:
196
196
  `))), console.log(t.gray(` Output directory: ${s.outputDirectory}`)), console.log(t.gray(` Template directory: ${s.templateDirectory}`)), console.log(t.gray(` Target: ${s.target}`));
197
197
  }
198
- async function ye() {
199
- const e = [], n = process.cwd(), s = T.getInstance();
198
+ async function fe() {
199
+ const e = [], n = process.cwd(), s = C.getInstance();
200
200
  await s.initialize();
201
201
  const a = (await s.detectAllProjects(n)).map((o) => o.metadata);
202
202
  if (a.length === 0)
203
203
  return [];
204
204
  for (const o of a) {
205
- const c = f.relative(n, o.projectPath);
205
+ const c = d.relative(n, o.projectPath);
206
206
  e.push({
207
- name: o.name || f.basename(o.projectPath),
207
+ name: o.name || d.basename(o.projectPath),
208
208
  path: c || ".",
209
209
  tags: /* @__PURE__ */ new Set()
210
210
  });
211
211
  }
212
212
  return e;
213
213
  }
214
- async function he(e, n, s, r) {
215
- const a = f.resolve(process.cwd(), e.path);
214
+ async function pe(e, n, s, r) {
215
+ const a = d.resolve(process.cwd(), e.path);
216
216
  try {
217
- const i = (await T.getInstance().detectAllProjects(a)).map((l) => l.metadata);
217
+ const i = (await C.getInstance().detectAllProjects(a)).map((l) => l.metadata);
218
218
  if (i.length > 0) {
219
219
  const l = i[0];
220
220
  if (l.tags?.length)
@@ -230,7 +230,7 @@ async function he(e, n, s, r) {
230
230
  }
231
231
  try {
232
232
  for (const o in s) {
233
- const c = s[o], i = f.join(a, o);
233
+ const c = s[o], i = d.join(a, o);
234
234
  p.existsSync(i) && e.tags.add(c);
235
235
  }
236
236
  } catch {
@@ -248,10 +248,10 @@ async function he(e, n, s, r) {
248
248
  } catch {
249
249
  }
250
250
  }
251
- async function we(e = {}) {
251
+ async function me(e = {}) {
252
252
  console.log(t.blue("๐Ÿ”Œ MagicAgentHelix Plugin System")), console.log();
253
253
  try {
254
- const n = T.getInstance();
254
+ const n = C.getInstance();
255
255
  await n.initialize({ verbose: e.verbose });
256
256
  const s = await n.getAllPlugins(), r = n.getStatistics();
257
257
  if (s.length === 0) {
@@ -289,7 +289,7 @@ async function we(e = {}) {
289
289
  ), process.exit(1);
290
290
  }
291
291
  }
292
- const $e = {
292
+ const ye = {
293
293
  // Frameworks
294
294
  "framework-vue": {
295
295
  extensions: ["vue"],
@@ -324,6 +324,54 @@ const $e = {
324
324
  extensions: ["py"],
325
325
  description: "Python files"
326
326
  },
327
+ "lang-rust": {
328
+ extensions: ["rs"],
329
+ description: "Rust files"
330
+ },
331
+ "rust-embedded": {
332
+ extensions: ["rs"],
333
+ description: "Embedded Rust files"
334
+ },
335
+ hardware2rust: {
336
+ extensions: ["rs"],
337
+ description: "Hardware2Rust project files"
338
+ },
339
+ "lang-java": {
340
+ extensions: ["java"],
341
+ description: "Java files"
342
+ },
343
+ "lang-swift": {
344
+ extensions: ["swift"],
345
+ description: "Swift files"
346
+ },
347
+ "lang-ruby": {
348
+ extensions: ["rb"],
349
+ description: "Ruby files"
350
+ },
351
+ "lang-php": {
352
+ extensions: ["php"],
353
+ description: "PHP files"
354
+ },
355
+ "lang-csharp": {
356
+ extensions: ["cs"],
357
+ description: "C# files"
358
+ },
359
+ "lang-cpp": {
360
+ extensions: ["cpp", "hpp", "cc", "h", "cxx", "hxx"],
361
+ description: "C++ files"
362
+ },
363
+ "lang-c": {
364
+ extensions: ["c", "h"],
365
+ description: "C files"
366
+ },
367
+ "lang-kotlin": {
368
+ extensions: ["kt", "kts"],
369
+ description: "Kotlin files"
370
+ },
371
+ "lang-scala": {
372
+ extensions: ["scala", "sc"],
373
+ description: "Scala files"
374
+ },
327
375
  // Styling
328
376
  "style-tailwind": {
329
377
  extensions: ["ts", "tsx", "js", "jsx", "vue"],
@@ -381,13 +429,13 @@ const $e = {
381
429
  description: "Files using Zustand"
382
430
  }
383
431
  };
384
- function je(e) {
385
- return $e[e]?.extensions || [];
432
+ function he(e) {
433
+ return ye[e]?.extensions || [];
386
434
  }
387
- function X(e, n, s) {
435
+ function K(e, n, s) {
388
436
  const r = /* @__PURE__ */ new Set();
389
437
  for (const c of n) {
390
- const i = je(c);
438
+ const i = he(c);
391
439
  for (const l of i)
392
440
  r.add(l);
393
441
  }
@@ -402,23 +450,23 @@ function X(e, n, s) {
402
450
  }
403
451
  return o;
404
452
  }
405
- function Z(e) {
453
+ function Q(e) {
406
454
  return e.quiet ? "quiet" : e.verbose ? "verbose" : "normal";
407
455
  }
408
- function v(e, n) {
456
+ function $(e, n) {
409
457
  return !(n === "quiet" && e !== "error" || n === "normal" && e === "verbose");
410
458
  }
411
- async function ve(e = {}) {
412
- Z(e);
459
+ async function we(e = {}) {
460
+ Q(e);
413
461
  const n = j("Loading configurations...").start(), s = N(e.config), r = L(s);
414
462
  e.target && (r.target = e.target), n.succeed("Configuration loaded.");
415
- const { dependencyTagMap: a, configFileTagMap: o, fileGlobTagMap: c, tagTemplateMap: i } = r, l = f.resolve(
463
+ const { dependencyTagMap: a, configFileTagMap: o, fileGlobTagMap: c, tagTemplateMap: i } = r, l = d.resolve(
416
464
  process.cwd(),
417
465
  r.templateDirectory
418
- ), g = f.resolve(
466
+ ), g = d.resolve(
419
467
  process.cwd(),
420
468
  r.outputDirectory
421
- ), u = Q(r.target);
469
+ ), u = Y(r.target);
422
470
  if (!p.existsSync(g)) {
423
471
  console.log(
424
472
  t.yellow(
@@ -429,62 +477,62 @@ async function ve(e = {}) {
429
477
  );
430
478
  return;
431
479
  }
432
- const y = j("Scanning for projects...").start(), w = await xe();
480
+ const h = j("Scanning for projects...").start(), w = await $e();
433
481
  if (w.length === 0) {
434
- y.warn(
482
+ h.warn(
435
483
  t.yellow(
436
484
  'No projects found. Make sure your root package.json has a "workspaces" field.'
437
485
  )
438
486
  );
439
487
  return;
440
488
  }
441
- y.succeed(`Found ${w.length} projects.`);
489
+ h.succeed(`Found ${w.length} projects.`);
442
490
  const m = j("Analyzing project tags...").start();
443
- let x = 0;
444
- for (const h of w)
445
- await be(
446
- h,
491
+ let v = 0;
492
+ for (const y of w)
493
+ await je(
494
+ y,
447
495
  a,
448
496
  o,
449
497
  c
450
- ), x += h.tags.size;
451
- m.succeed(`Project analysis complete. Found ${x} tags.`), console.log(
498
+ ), v += y.tags.size;
499
+ m.succeed(`Project analysis complete. Found ${v} tags.`), console.log(
452
500
  t.cyan(`
453
501
  Refreshing instruction files in ${r.outputDirectory}...`)
454
502
  );
455
503
  let D = 0, E = 0;
456
- for (const h of w) {
457
- if (h.tags.size === 0) {
458
- console.log(t.gray(` Skipping: ${h.name} (No matching tags)`)), E++;
504
+ for (const y of w) {
505
+ if (y.tags.size === 0) {
506
+ console.log(t.gray(` Skipping: ${y.name} (No matching tags)`)), E++;
459
507
  continue;
460
508
  }
461
- console.log(t.bold(` Processing: ${h.name}`)), console.log(t.gray(` Tags: ${[...h.tags].join(", ")}`));
462
- const M = X(h.path, h.tags);
463
- for (const F of h.tags) {
464
- const O = i[F];
465
- if (O)
466
- for (const S of O) {
467
- const C = `${h.name}.${S.suffix}`, A = f.join(g, C);
468
- if (!p.existsSync(A)) {
509
+ console.log(t.bold(` Processing: ${y.name}`)), console.log(t.gray(` Tags: ${[...y.tags].join(", ")}`));
510
+ const z = K(y.path, y.tags);
511
+ for (const S of y.tags) {
512
+ const M = i[S];
513
+ if (M)
514
+ for (const P of M) {
515
+ const T = `${y.name}.${P.suffix}`, F = d.join(g, T);
516
+ if (!p.existsSync(F)) {
469
517
  console.log(
470
- t.yellow(` โš ๏ธ File not found, skipping: ${C}`)
518
+ t.yellow(` โš ๏ธ File not found, skipping: ${T}`)
471
519
  );
472
520
  continue;
473
521
  }
474
- let d = J(l, S.template), $ = "Custom";
475
- if (d || (d = J(K, S.template), $ = "Built-in"), !d) {
476
- console.warn(t.yellow(` โš ๏ธ Template not found: ${S.template}`));
522
+ const f = xe(l, P.template), x = "Custom";
523
+ if (!f) {
524
+ console.warn(t.yellow(` โš ๏ธ Template not found: ${P.template}`));
477
525
  continue;
478
526
  }
479
- const R = u.getFrontmatter(M, h.name), k = u.format(
480
- d,
481
- M,
482
- h.name
527
+ const R = u.getFrontmatter(z, y.name), k = u.format(
528
+ f,
529
+ z,
530
+ y.name
483
531
  ), b = `${R}
484
532
  ${k}`;
485
- p.writeFileSync(A, b), D++, console.log(
533
+ p.writeFileSync(F, b), D++, console.log(
486
534
  t.green(
487
- ` โœ… Refreshed: ${t.bold(C)} (from ${$})`
535
+ ` โœ… Refreshed: ${t.bold(T)} (from ${x})`
488
536
  )
489
537
  );
490
538
  }
@@ -493,26 +541,26 @@ ${k}`;
493
541
  console.log(`
494
542
  โœจ Refresh complete!`), console.log(t.green(` Updated: ${D} files`)), console.log(t.gray(` Skipped: ${E} projects`));
495
543
  }
496
- async function xe() {
497
- const e = [], n = process.cwd(), s = T.getInstance();
544
+ async function $e() {
545
+ const e = [], n = process.cwd(), s = C.getInstance();
498
546
  await s.initialize();
499
547
  const a = (await s.detectAllProjects(n)).map((o) => o.metadata);
500
548
  if (a.length === 0)
501
549
  return [];
502
550
  for (const o of a) {
503
- const c = f.relative(n, o.projectPath);
551
+ const c = d.relative(n, o.projectPath);
504
552
  e.push({
505
- name: o.name || f.basename(o.projectPath),
553
+ name: o.name || d.basename(o.projectPath),
506
554
  path: c || ".",
507
555
  tags: /* @__PURE__ */ new Set()
508
556
  });
509
557
  }
510
558
  return e;
511
559
  }
512
- async function be(e, n, s, r) {
513
- const a = f.resolve(process.cwd(), e.path);
560
+ async function je(e, n, s, r) {
561
+ const a = d.resolve(process.cwd(), e.path);
514
562
  try {
515
- const i = (await T.getInstance().detectAllProjects(a)).map((l) => l.metadata);
563
+ const i = (await C.getInstance().detectAllProjects(a)).map((l) => l.metadata);
516
564
  if (i.length > 0) {
517
565
  const l = i[0];
518
566
  if (l.tags?.length)
@@ -533,7 +581,7 @@ async function be(e, n, s, r) {
533
581
  }
534
582
  try {
535
583
  for (const o in s) {
536
- const c = s[o], i = f.join(a, o);
584
+ const c = s[o], i = d.join(a, o);
537
585
  p.existsSync(i) && e.tags.add(c);
538
586
  }
539
587
  } catch (o) {
@@ -561,15 +609,15 @@ async function be(e, n, s, r) {
561
609
  );
562
610
  }
563
611
  }
564
- function J(e, n) {
565
- const s = f.join(e, n);
612
+ function xe(e, n) {
613
+ const s = d.join(e, n);
566
614
  try {
567
615
  return p.readFileSync(s, "utf-8");
568
616
  } catch {
569
617
  return null;
570
618
  }
571
619
  }
572
- async function Se() {
620
+ async function ve() {
573
621
  console.log(
574
622
  q.pastel.multiline("๐Ÿค– MagicAgentHelix Interactive Setup Wizard")
575
623
  ), console.log(`Let's configure your AI instruction generation...
@@ -626,141 +674,173 @@ async function Se() {
626
674
  โœ… Configuration complete! Starting analysis...
627
675
  `)), n;
628
676
  }
629
- async function U(e = {}) {
677
+ async function J(e = {}) {
630
678
  let n = e;
631
- e.wizard && (n = { ...await Se(), ...e });
632
- const s = Z(n);
633
- v("normal", s) && console.log(
679
+ e.wizard && (n = { ...await ve(), ...e });
680
+ const s = Q(n);
681
+ $("normal", s) && console.log(
634
682
  q.pastel.multiline("๐Ÿค– Running AI Convention Aligner...")
635
- ), n.dryRun && v("normal", s) && console.log(t.yellow(`๐Ÿ” DRY RUN MODE - No files will be written
683
+ ), n.dryRun && $("normal", s) && console.log(t.yellow(`๐Ÿ” DRY RUN MODE - No files will be written
636
684
  `));
637
685
  const r = j("Loading configurations...").start(), a = N(n.config), o = L(a);
638
686
  n.outputDir && (o.outputDirectory = n.outputDir), n.target && (o.target = n.target), r.succeed("Configuration loaded.");
639
- const { dependencyTagMap: c, configFileTagMap: i, fileGlobTagMap: l, tagTemplateMap: g } = o, u = f.resolve(
687
+ const { dependencyTagMap: c, configFileTagMap: i, fileGlobTagMap: l, tagTemplateMap: g } = o, u = d.resolve(
640
688
  process.cwd(),
641
689
  o.templateDirectory
642
- ), y = f.resolve(
690
+ ), h = d.resolve(
643
691
  process.cwd(),
644
692
  o.outputDirectory
645
- ), w = Q(o.target), m = j("Scanning for projects...").start(), x = await Ce();
646
- if (x.length === 0) {
693
+ ), w = Y(o.target), m = j("Scanning for projects...").start(), v = await Pe();
694
+ if (v.length === 0) {
647
695
  m.warn(
648
696
  t.yellow(
649
- 'No projects found. Make sure your root package.json has a "workspaces" field.'
697
+ "No projects detected. The tool could not find any supported project types in the current directory."
698
+ )
699
+ ), console.log(
700
+ t.gray(
701
+ `
702
+ Supported project types: Node.js, Python, Go, Rust, Java, Ruby, PHP, C#, Swift, C/C++, PlatformIO`
703
+ )
704
+ ), console.log(
705
+ t.gray(
706
+ 'For monorepos, ensure your root package.json has a "workspaces" field.'
707
+ )
708
+ ), console.log(
709
+ t.gray(
710
+ "For standalone projects, ensure you have the appropriate manifest file (package.json, go.mod, Cargo.toml, platformio.ini, etc.)"
650
711
  )
651
712
  );
652
713
  return;
653
714
  }
654
- m.succeed(`Found ${x.length} projects.`);
715
+ m.succeed(`Found ${v.length} projects.`);
655
716
  const D = j("Analyzing project tags...").start();
656
717
  let E = 0;
657
- for (const d of x) {
658
- if (n.project && d.name !== n.project) {
659
- v("verbose", s) && console.log(t.gray(`Skipping ${d.name} (not target project)`));
718
+ for (const f of v) {
719
+ if (n.project && f.name !== n.project) {
720
+ $("verbose", s) && console.log(t.gray(`Skipping ${f.name} (not target project)`));
660
721
  continue;
661
722
  }
662
- await Re(
663
- d,
723
+ await Te(
724
+ f,
664
725
  c,
665
726
  i,
666
727
  l
667
- ), E += d.tags.size;
728
+ ), E += f.tags.size;
668
729
  }
669
- D.succeed(`Project analysis complete. Found ${E} tags.`), n.dryRun ? v("verbose", s) && console.log(t.gray(`Would ensure directory: ${y}`)) : Pe(y);
670
- let h = g;
730
+ D.succeed(`Project analysis complete. Found ${E} tags.`), n.dryRun ? $("verbose", s) && console.log(t.gray(`Would ensure directory: ${h}`)) : be(h);
731
+ let y = g;
671
732
  if (n.template) {
672
- const d = n.template.split(",").map(($) => $.trim());
673
- h = {};
674
- for (const [$, R] of Object.entries(g)) {
675
- const k = R.filter((b) => d.some((P) => {
676
- if (P.includes("*")) {
677
- const I = new RegExp(P.replace(/\*/g, ".*"));
678
- return I.test(b.template) || I.test($);
733
+ const f = n.template.split(",").map((x) => x.trim());
734
+ y = {};
735
+ for (const [x, R] of Object.entries(g)) {
736
+ const k = R.filter((b) => f.some((A) => {
737
+ if (A.includes("*")) {
738
+ const I = new RegExp(A.replace(/\*/g, ".*"));
739
+ return I.test(b.template) || I.test(x);
679
740
  }
680
- return b.template.includes(P) || $.includes(P);
741
+ return b.template.includes(A) || x.includes(A);
681
742
  }));
682
- k.length > 0 && (h[$] = k);
743
+ k.length > 0 && (y[x] = k);
683
744
  }
684
- v("verbose", s) && console.log(
745
+ $("verbose", s) && console.log(
685
746
  t.gray(`Template filter applied: ${n.template}`)
686
747
  );
687
748
  }
688
- const M = await Te(), F = {};
689
- for (const [d, $] of Object.entries(h))
690
- F[d] = $.map((R) => ({
749
+ const z = await Se(), S = {};
750
+ for (const [f, x] of Object.entries(y))
751
+ S[f] = x.map((R) => ({
691
752
  template: R.template,
692
753
  suffix: R.suffix
693
754
  }));
694
- for (const [d, $] of Object.entries(M))
695
- F[d] || (F[d] = []), F[d].push(...$);
696
- v("normal", s) && console.log(
755
+ for (const [f, x] of Object.entries(z))
756
+ S[f] || (S[f] = []), S[f].push(...x);
757
+ $("verbose", s) && (console.log(t.gray(`
758
+ --- Template Map Debug ---`)), console.log(
759
+ t.gray(
760
+ `Plugin templates: ${Object.keys(z).length} tags`
761
+ )
762
+ ), console.log(
763
+ t.gray(` Tags: ${Object.keys(z).join(", ")}`)
764
+ ), console.log(
765
+ t.gray(
766
+ `Config templates: ${Object.keys(y).length} tags`
767
+ )
768
+ ), console.log(
769
+ t.gray(` Tags: ${Object.keys(y).join(", ")}`)
770
+ ), console.log(
771
+ t.gray(
772
+ `Combined templates: ${Object.keys(S).length} tags`
773
+ )
774
+ ), console.log(
775
+ t.gray(` Tags: ${Object.keys(S).join(", ")}`)
776
+ )), $("normal", s) && console.log(
697
777
  t.cyan(`
698
778
  Generating instruction files in ${o.outputDirectory}...`)
699
779
  );
700
- const O = j("Generating instruction files...").start(), S = [];
701
- let C = 0, A = 0;
702
- for (const d of x) {
703
- if (n.project && d.name !== n.project)
780
+ const M = j("Generating instruction files...").start(), P = [];
781
+ let T = 0, F = 0;
782
+ for (const f of v) {
783
+ if (n.project && f.name !== n.project)
704
784
  continue;
705
- if (d.tags.size === 0) {
706
- v("normal", s) && console.log(t.gray(` Skipping: ${d.name} (No matching tags)`));
785
+ if (f.tags.size === 0) {
786
+ $("normal", s) && console.log(t.gray(` Skipping: ${f.name} (No matching tags)`));
707
787
  continue;
708
788
  }
709
- C++, v("normal", s) && console.log(t.bold(` Processing: ${d.name}`)), v("verbose", s) && console.log(t.gray(` Tags: ${[...d.tags].join(", ")}`));
710
- const $ = X(
711
- d.path,
712
- d.tags,
789
+ T++, $("normal", s) && console.log(t.bold(` Processing: ${f.name}`)), $("verbose", s) && console.log(t.gray(` Tags: ${[...f.tags].join(", ")}`));
790
+ const x = K(
791
+ f.path,
792
+ f.tags,
713
793
  n.exclude
714
794
  );
715
- for (const R of d.tags) {
716
- const k = F[R];
795
+ for (const R of f.tags) {
796
+ const k = S[R];
717
797
  if (k)
718
798
  for (const b of k) {
719
- A++;
720
- let P = b.inlineContent ?? H(u, b.template), I = b.inlineContent ? "Plugin (inline)" : "Custom";
721
- if (P || (P = H(K, b.template), I = "Built-in"), !P) {
799
+ F++;
800
+ const A = b.inlineContent ?? Re(u, b.template), I = b.inlineContent ? "Plugin" : "Custom";
801
+ if (!A) {
722
802
  console.warn(t.yellow(` โš ๏ธ Template not found: ${b.template}`));
723
803
  continue;
724
804
  }
725
- const ee = w.getFrontmatter($, d.name), te = w.format(
726
- P,
727
- $,
728
- d.name
729
- ), oe = `${ee}
730
- ${te}`, _ = `${d.name}.${b.suffix}`, ne = f.join(y, _);
731
- S.push(_), n.dryRun ? v("normal", s) && console.log(
805
+ const B = w.getFrontmatter(x, f.name), X = w.format(
806
+ A,
807
+ x,
808
+ f.name
809
+ ), Z = `${B}
810
+ ${X}`, G = b.suffix, ee = d.join(h, G);
811
+ P.push(G), n.dryRun ? $("normal", s) && console.log(
732
812
  t.cyan(
733
- ` ๐Ÿ“ Would generate: ${t.bold(_)} (from ${I})`
813
+ ` ๐Ÿ“ Would generate: ${t.bold(G)} (from ${I})`
734
814
  )
735
- ) : (p.writeFileSync(ne, oe), v("normal", s) && console.log(
815
+ ) : (p.writeFileSync(ee, Z), $("normal", s) && console.log(
736
816
  t.green(
737
- ` โœ… Generated: ${t.bold(_)} (from ${I})`
817
+ ` โœ… Generated: ${t.bold(G)} (from ${I})`
738
818
  )
739
819
  ));
740
820
  }
741
821
  }
742
822
  }
743
- O.succeed(
744
- `Generated ${S.length} files from ${A} templates across ${C} projects`
745
- ), !n.dryRun && !n.skipPruning ? await Fe(y, S, n.force) : n.dryRun && v("verbose", s) && console.log(t.gray(`
746
- Would check for old files to prune...`)), v("normal", s) && (console.log(`
823
+ M.succeed(
824
+ `Generated ${P.length} files from ${F} templates across ${T} projects`
825
+ ), !n.dryRun && !n.skipPruning ? await Fe(h, P, n.force) : n.dryRun && $("verbose", s) && console.log(t.gray(`
826
+ Would check for old files to prune...`)), $("normal", s) && (console.log(`
747
827
  ${"โ•".repeat(60)}`), n.dryRun ? (console.log(t.cyan("โœจ Dry run complete! No files were modified.")), console.log(
748
828
  t.gray(
749
- `๐Ÿ“‹ Would have generated ${S.length} instruction file(s)`
829
+ `๐Ÿ“‹ Would have generated ${P.length} instruction file(s)`
750
830
  )
751
831
  ), console.log(
752
832
  t.gray(
753
- `๐Ÿ“Š From ${A} template(s) across ${C} project(s)`
833
+ `๐Ÿ“Š From ${F} template(s) across ${T} project(s)`
754
834
  )
755
835
  )) : (console.log(t.green("โœจ AI instruction alignment complete!")), console.log(
756
- t.bold(`๐Ÿ“ Generated ${S.length} instruction file(s)`)
836
+ t.bold(`๐Ÿ“ Generated ${P.length} instruction file(s)`)
757
837
  ), console.log(
758
838
  t.gray(
759
- `๐Ÿ“Š From ${A} template(s) across ${C} project(s)`
839
+ `๐Ÿ“Š From ${F} template(s) across ${T} project(s)`
760
840
  )
761
841
  ), console.log(
762
842
  t.gray(`๐Ÿ“‚ Files are located in: ${t.bold(o.outputDirectory)}`)
763
- )), console.log("โ•".repeat(60))), o.target === "github-copilot" && v("normal", s) && (console.log(`
843
+ )), console.log("โ•".repeat(60))), o.target === "github-copilot" && $("normal", s) && (console.log(`
764
844
  --- VS Code + GitHub Copilot Tip ---`), console.log(
765
845
  "To maximize Copilot's awareness, add this to your workspace .vscode/settings.json:"
766
846
  ), console.log(`
@@ -771,7 +851,7 @@ ${"โ•".repeat(60)}`), n.dryRun ? (console.log(t.cyan("โœจ Dry run complete! No
771
851
  "This tells Copilot to *always* read these files. Restart VS Code after adding."
772
852
  ));
773
853
  }
774
- function Pe(e) {
854
+ function be(e) {
775
855
  const n = j(`Checking target directory: ${e}`).start();
776
856
  if (p.existsSync(e))
777
857
  n.succeed("Target directory OK.");
@@ -788,19 +868,25 @@ function Pe(e) {
788
868
  }
789
869
  }
790
870
  }
791
- async function V() {
792
- await T.getInstance().initialize();
871
+ async function H() {
872
+ await C.getInstance().initialize();
793
873
  }
794
- async function Te() {
795
- await V();
796
- const e = T.getInstance(), n = [];
874
+ async function Se() {
875
+ await H();
876
+ const e = C.getInstance();
877
+ let n = [];
797
878
  try {
798
- if (typeof e.getAllPlugins == "function") {
799
- const r = e.getAllPlugins;
800
- n.push(...await r());
801
- }
802
- } catch {
879
+ n = await e.getAllPlugins();
880
+ } catch (r) {
881
+ console.warn(
882
+ t.yellow(`โš ๏ธ Failed to get plugins: ${r.message}`)
883
+ ), console.warn(
884
+ t.yellow(
885
+ `โš ๏ธ Registry type: ${typeof e}, has getAllPlugins: ${typeof e?.getAllPlugins}`
886
+ )
887
+ );
803
888
  }
889
+ n.length === 0 && console.warn(t.yellow("โš ๏ธ No plugins loaded from registry!"));
804
890
  const s = {};
805
891
  for (const r of n) {
806
892
  let a = [];
@@ -837,26 +923,32 @@ async function Te() {
837
923
  }
838
924
  return s;
839
925
  }
840
- async function Ce() {
841
- await V();
842
- const e = [], n = process.cwd(), r = await T.getInstance().detectAllProjects(n);
926
+ async function Pe() {
927
+ await H();
928
+ const e = [], n = process.cwd(), r = await C.getInstance().detectAllProjects(n);
843
929
  if (r.length === 0)
844
930
  return [];
845
931
  for (const a of r) {
846
- const o = f.relative(n, a.metadata.projectPath);
932
+ const o = d.relative(n, a.metadata.projectPath);
847
933
  e.push({
848
- name: a.metadata.name || f.basename(a.metadata.projectPath),
934
+ name: Ce(
935
+ a.metadata.name || d.basename(a.metadata.projectPath)
936
+ ),
849
937
  path: o || ".",
850
938
  tags: /* @__PURE__ */ new Set()
851
939
  });
852
940
  }
853
941
  return e;
854
942
  }
855
- async function Re(e, n, s, r) {
856
- await V();
857
- const a = f.resolve(process.cwd(), e.path);
943
+ function Ce(e) {
944
+ let s = e.trim().replace(/^@/, "").replace(/[\\/\s]+/g, "-");
945
+ return s = s.replace(/-+/g, "-"), s;
946
+ }
947
+ async function Te(e, n, s, r) {
948
+ await H();
949
+ const a = d.resolve(process.cwd(), e.path);
858
950
  try {
859
- const c = await T.getInstance().detectAllProjects(a);
951
+ const c = await C.getInstance().detectAllProjects(a);
860
952
  if (c.length > 0) {
861
953
  const i = c[0].metadata;
862
954
  if (i.tags?.length)
@@ -877,7 +969,7 @@ async function Re(e, n, s, r) {
877
969
  }
878
970
  try {
879
971
  for (const o in s) {
880
- const c = s[o], i = f.join(a, o);
972
+ const c = s[o], i = d.join(a, o);
881
973
  p.existsSync(i) && e.tags.add(c);
882
974
  }
883
975
  } catch (o) {
@@ -890,7 +982,7 @@ async function Re(e, n, s, r) {
890
982
  try {
891
983
  for (const o in r) {
892
984
  const c = r[o];
893
- (await ue(o, {
985
+ (await ce(o, {
894
986
  cwd: a,
895
987
  nodir: !0,
896
988
  dot: !0
@@ -905,8 +997,8 @@ async function Re(e, n, s, r) {
905
997
  );
906
998
  }
907
999
  }
908
- function H(e, n) {
909
- const s = f.join(e, n);
1000
+ function Re(e, n) {
1001
+ const s = d.join(e, n);
910
1002
  try {
911
1003
  return p.readFileSync(s, "utf-8");
912
1004
  } catch {
@@ -936,7 +1028,7 @@ async function Fe(e, n, s = !1) {
936
1028
  let c = 0;
937
1029
  for (const i of a)
938
1030
  try {
939
- p.unlinkSync(f.join(e, i)), c++;
1031
+ p.unlinkSync(d.join(e, i)), c++;
940
1032
  } catch (l) {
941
1033
  console.error(
942
1034
  t.red(` โŒ Error deleting ${i}: ${l.message}`)
@@ -946,14 +1038,14 @@ async function Fe(e, n, s = !1) {
946
1038
  }
947
1039
  }
948
1040
  }
949
- async function Ae() {
1041
+ async function ke() {
950
1042
  console.log(
951
1043
  t.cyan(`๐Ÿ” Validating instruction files with quality scoring...
952
1044
  `)
953
1045
  );
954
1046
  const e = j("Loading configuration...").start(), n = N(), s = L(n);
955
1047
  e.succeed("Configuration loaded.");
956
- const r = f.resolve(
1048
+ const r = d.resolve(
957
1049
  process.cwd(),
958
1050
  s.outputDirectory
959
1051
  );
@@ -977,9 +1069,9 @@ async function Ae() {
977
1069
  let o = { track: () => {
978
1070
  } };
979
1071
  try {
980
- const y = await import("@el-j/magic-helix-core");
981
- if (typeof y.createTelemetry == "function") {
982
- const w = y.createTelemetry;
1072
+ const h = await import("@el-j/magic-helix-core");
1073
+ if (typeof h.createTelemetry == "function") {
1074
+ const w = h.createTelemetry;
983
1075
  o = w({});
984
1076
  }
985
1077
  } catch {
@@ -987,13 +1079,13 @@ async function Ae() {
987
1079
  let c = 0, i = 0;
988
1080
  const l = [];
989
1081
  for (const u of a) {
990
- const y = f.join(r, u);
1082
+ const h = d.join(r, u);
991
1083
  try {
992
- const w = p.readFileSync(y, "utf-8"), m = ge(w), x = ke(m.overallScore);
993
- l.push({ file: u, score: m.overallScore, grade: x }), m.overallScore >= 70 ? c++ : i++;
1084
+ const w = p.readFileSync(h, "utf-8"), m = ae(w), v = Ae(m.overallScore);
1085
+ l.push({ file: u, score: m.overallScore, grade: v }), m.overallScore >= 70 ? c++ : i++;
994
1086
  const D = m.overallScore >= 90 ? t.green : m.overallScore >= 70 ? t.blue : t.yellow;
995
1087
  console.log(
996
- D(`${x} ${m.overallScore}/100`) + t.gray(` - ${u}`)
1088
+ D(`${v} ${m.overallScore}/100`) + t.gray(` - ${u}`)
997
1089
  ), m.missingElements.length > 0 && console.log(
998
1090
  t.red(` Missing: ${m.missingElements.join(", ")}`)
999
1091
  ), m.recommendations.length > 0 && m.overallScore < 90 && console.log(t.gray(` Tip: ${m.recommendations[0]}`)), o.track({
@@ -1012,7 +1104,7 @@ async function Ae() {
1012
1104
  console.log(t.bold(`
1013
1105
  === Validation Summary ===
1014
1106
  `)), console.log(t.green(`โœ… Passed (โ‰ฅ70): ${c}`)), console.log(t.red(`โŒ Failed (<70): ${i}`));
1015
- const g = l.reduce((u, y) => u + y.score, 0) / l.length;
1107
+ const g = l.reduce((u, h) => u + h.score, 0) / l.length;
1016
1108
  console.log(t.cyan(`๐Ÿ“Š Average Score: ${Math.round(g)}/100`)), o.track({
1017
1109
  type: "summary",
1018
1110
  files: l.length,
@@ -1027,25 +1119,25 @@ async function Ae() {
1027
1119
  )
1028
1120
  );
1029
1121
  }
1030
- function ke(e) {
1122
+ function Ae(e) {
1031
1123
  return e >= 90 ? "A" : e >= 80 ? "B" : e >= 70 ? "C" : e >= 60 ? "D" : "F";
1032
1124
  }
1033
1125
  function De() {
1034
1126
  try {
1035
- const e = Y(import.meta.url), n = ae(e), s = ce(n, "..", "package.json");
1036
- return JSON.parse(ie(s, "utf-8")).version;
1127
+ const e = U(import.meta.url), n = se(e), s = ie(n, "..", "package.json");
1128
+ return JSON.parse(oe(s, "utf-8")).version;
1037
1129
  } catch {
1038
1130
  return "2.0.0-beta.1";
1039
1131
  }
1040
1132
  }
1041
- async function Ie() {
1133
+ async function ze() {
1042
1134
  try {
1043
- const e = new le();
1135
+ const e = new re();
1044
1136
  e.name("magic-helix").description(
1045
1137
  "Magic Helix CLI for aligning AI instructions in your monorepo."
1046
1138
  ).version(De()), e.command("init").description(
1047
1139
  "Initialize a custom magic-helix.config.json to extend the built-in rules."
1048
- ).action(pe), e.command("run").description(
1140
+ ).action(ue), e.command("run").description(
1049
1141
  "Scan the monorepo and generate AI instruction files based on built-in and custom rules."
1050
1142
  ).option(
1051
1143
  "--dry-run",
@@ -1059,25 +1151,25 @@ async function Ie() {
1059
1151
  ).option(
1060
1152
  "--exclude <pattern>",
1061
1153
  "Exclude files matching pattern (e.g., 'test/**,*.spec.ts')"
1062
- ).action(U), e.command("refresh").description(
1154
+ ).action(J), e.command("refresh").description(
1063
1155
  "Rescan the project and update existing instruction files with changed project information."
1064
1156
  ).alias("resync").option("--config <path>", "Path to custom config file").option(
1065
1157
  "--target <assistant>",
1066
1158
  "AI assistant target (github-copilot, claude, copilot-chat, generic)"
1067
- ).option("--verbose", "Show detailed output").option("--quiet", "Show minimal output").option("--project <name>", "Target a specific project only").action(ve), e.command("list").description(
1159
+ ).option("--verbose", "Show detailed output").option("--quiet", "Show minimal output").option("--project <name>", "Target a specific project only").action(we), e.command("list").description(
1068
1160
  "Show detected projects, tags, and templates without generating files."
1069
- ).action(me), e.command("validate").description("Check instruction files for common issues and integrity.").action(Ae), e.command("clean").description("Remove all generated instruction files.").action(de), e.command("plugins").description(
1161
+ ).action(de), e.command("validate").description("Check instruction files for common issues and integrity.").action(ke), e.command("clean").description("Remove all generated instruction files.").action(le), e.command("plugins").description(
1070
1162
  "List available language detection plugins and their status."
1071
- ).option("--verbose", "Show detailed plugin information").action((n) => we(n)), process.argv.length < 3 && e.action(U), await e.parseAsync(process.argv);
1163
+ ).option("--verbose", "Show detailed plugin information").action((n) => me(n)), process.argv.length < 3 && e.action(J), await e.parseAsync(process.argv);
1072
1164
  } catch (e) {
1073
1165
  console.error(
1074
1166
  t.red(`โŒ An unexpected error occurred: ${e.message}`)
1075
1167
  ), process.exit(1);
1076
1168
  }
1077
1169
  }
1078
- const Ee = Y(import.meta.url), B = process.argv[1] ? se(re(process.argv[1])) : null;
1079
- B && Ee === B && Ie();
1170
+ const Ee = U(import.meta.url), V = process.argv[1] ? te(ne(process.argv[1])) : null;
1171
+ V && Ee === V && ze();
1080
1172
  export {
1081
- Ie as main
1173
+ ze as main
1082
1174
  };
1083
1175
  //# sourceMappingURL=cli.mjs.map