@babylonjsmarket/cli 1.0.2 → 1.0.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.
@@ -2,27 +2,32 @@
2
2
  * Pure classifiers for the inject engine.
3
3
  *
4
4
  * `detectTarget` decides whether a seed of project files belongs in
5
- * `@babylonjsmarket/arcade-pro` (per-component, registered) or
6
- * `@babylonjsmarket/viz-pro` (flat per-layer barrels).
5
+ * `@babylonjsmarket/arcade` (per-component, registered) or the viz package
6
+ * (flat per-layer barrels).
7
7
  *
8
- * `detectLayer` decides which viz-pro layer (`core`, `solid`, `ecs`) owns a
8
+ * `detectLayer` decides which viz layer (`core`, `solid`, `ecs`) owns a
9
9
  * single source file. Order matters: rules are evaluated top-down and the
10
10
  * first match wins. The order mirrors the plan.
11
+ *
12
+ * Target naming: the canonical user-facing target names are `arcade` and
13
+ * `viz`. The legacy `arcade-pro` / `viz-pro` package names live on only as
14
+ * back-compat aliases (normalized to the canonical names by callers) and as
15
+ * import-prefix patterns we still recognize in existing seeds.
11
16
  */
12
- type Target = "arcade-pro" | "viz-pro";
17
+ type Target = "arcade" | "viz";
13
18
  type VizLayer = "core" | "solid" | "ecs";
14
19
  interface SeedFile {
15
20
  path: string;
16
21
  source: string;
17
22
  }
18
23
  /**
19
- * Classify a closure of seed files to one of the two pro packages. Any single
20
- * file extending a viz-pro System class or importing from `@babylonjsmarket/viz-pro`
21
- * tips the whole seed to `viz-pro`.
24
+ * Classify a closure of seed files to one of the two packages. Any single
25
+ * file extending a viz System class or importing from `@babylonjsmarket/viz`
26
+ * (or the legacy `@babylonjsmarket/viz-pro`) tips the whole seed to `viz`.
22
27
  */
23
28
  declare function detectTarget(seedFiles: SeedFile[]): Target;
24
29
  /**
25
- * Classify a single source file to a viz-pro layer.
30
+ * Classify a single source file to a viz layer.
26
31
  *
27
32
  * Order is load-bearing:
28
33
  * 1. *.test.ts(x) → route alongside the subject file (re-detect on the
@@ -1,10 +1,10 @@
1
1
  // src/lib/inject/detect-target.ts
2
2
  function detectTarget(seedFiles) {
3
3
  for (const { source } of seedFiles) {
4
- if (/from\s+['"]@babylonjsmarket\/viz-pro['"]/.test(source)) return "viz-pro";
5
- if (/extends\s+(PanelDebuggerSystem|StateStepperSystem)\b/.test(source)) return "viz-pro";
4
+ if (/from\s+['"]@babylonjsmarket\/viz(?:-pro)?['"]/.test(source)) return "viz";
5
+ if (/extends\s+(PanelDebuggerSystem|StateStepperSystem)\b/.test(source)) return "viz";
6
6
  }
7
- return "arcade-pro";
7
+ return "arcade";
8
8
  }
9
9
  function detectLayer(filePath, source, subjectLayer) {
10
10
  const base = filePath.split(/[\\/]/).pop() ?? filePath;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/lib/inject/detect-target.ts"],"sourcesContent":["/**\n * Pure classifiers for the inject engine.\n *\n * `detectTarget` decides whether a seed of project files belongs in\n * `@babylonjsmarket/arcade-pro` (per-component, registered) or\n * `@babylonjsmarket/viz-pro` (flat per-layer barrels).\n *\n * `detectLayer` decides which viz-pro layer (`core`, `solid`, `ecs`) owns a\n * single source file. Order matters: rules are evaluated top-down and the\n * first match wins. The order mirrors the plan.\n */\n\nexport type Target = \"arcade-pro\" | \"viz-pro\";\nexport type VizLayer = \"core\" | \"solid\" | \"ecs\";\n\nexport interface SeedFile {\n path: string;\n source: string;\n}\n\n/**\n * Classify a closure of seed files to one of the two pro packages. Any single\n * file extending a viz-pro System class or importing from `@babylonjsmarket/viz-pro`\n * tips the whole seed to `viz-pro`.\n */\nexport function detectTarget(seedFiles: SeedFile[]): Target {\n for (const { source } of seedFiles) {\n if (/from\\s+['\"]@babylonjsmarket\\/viz-pro['\"]/.test(source)) return \"viz-pro\";\n if (/extends\\s+(PanelDebuggerSystem|StateStepperSystem)\\b/.test(source)) return \"viz-pro\";\n }\n return \"arcade-pro\";\n}\n\n/**\n * Classify a single source file to a viz-pro layer.\n *\n * Order is load-bearing:\n * 1. *.test.ts(x) → route alongside the subject file (re-detect on the\n * subject's source if known, else default 'core').\n * 2. *.tsx that imports from 'solid-js' → 'solid'.\n * 3. extends (PanelDebuggerSystem|StateStepperSystem|System) or filename\n * ends in 'System.ts' → 'ecs'.\n * 4. extends Component and no Solid import → 'ecs'.\n * 5. contains `definePanel(` and no Solid import → 'core'.\n * 6. fallback → 'core'.\n *\n * `subjectLayer` lets the caller pin a test file to its subject's layer; pass\n * `undefined` when the subject isn't co-injected, which falls through to\n * rule (1)'s default.\n */\nexport function detectLayer(\n filePath: string,\n source: string,\n subjectLayer?: VizLayer,\n): VizLayer {\n const base = filePath.split(/[\\\\/]/).pop() ?? filePath;\n\n // (1) test files travel with their subject\n if (/\\.test\\.tsx?$/.test(base)) {\n return subjectLayer ?? \"core\";\n }\n\n const hasSolidImport = /from\\s+['\"]solid-js['\"]/.test(source);\n\n // (2) Solid .tsx\n if (/\\.tsx$/.test(base) && hasSolidImport) return \"solid\";\n\n // (3) System subclasses or *System.ts filenames\n if (/extends\\s+(PanelDebuggerSystem|StateStepperSystem|System)\\b/.test(source)) return \"ecs\";\n if (/System\\.ts$/.test(base)) return \"ecs\";\n\n // (4) Component subclasses (no Solid)\n if (/extends\\s+Component\\b/.test(source) && !hasSolidImport) return \"ecs\";\n\n // (5) definePanel files (no Solid)\n if (/\\bdefinePanel\\s*\\(/.test(source) && !hasSolidImport) return \"core\";\n\n // (6) fallback\n return \"core\";\n}\n"],"mappings":";AAyBO,SAAS,aAAa,WAA+B;AAC1D,aAAW,EAAE,OAAO,KAAK,WAAW;AAClC,QAAI,2CAA2C,KAAK,MAAM,EAAG,QAAO;AACpE,QAAI,uDAAuD,KAAK,MAAM,EAAG,QAAO;AAAA,EAClF;AACA,SAAO;AACT;AAmBO,SAAS,YACd,UACA,QACA,cACU;AACV,QAAM,OAAO,SAAS,MAAM,OAAO,EAAE,IAAI,KAAK;AAG9C,MAAI,gBAAgB,KAAK,IAAI,GAAG;AAC9B,WAAO,gBAAgB;AAAA,EACzB;AAEA,QAAM,iBAAiB,0BAA0B,KAAK,MAAM;AAG5D,MAAI,SAAS,KAAK,IAAI,KAAK,eAAgB,QAAO;AAGlD,MAAI,8DAA8D,KAAK,MAAM,EAAG,QAAO;AACvF,MAAI,cAAc,KAAK,IAAI,EAAG,QAAO;AAGrC,MAAI,wBAAwB,KAAK,MAAM,KAAK,CAAC,eAAgB,QAAO;AAGpE,MAAI,qBAAqB,KAAK,MAAM,KAAK,CAAC,eAAgB,QAAO;AAGjE,SAAO;AACT;","names":[]}
1
+ {"version":3,"sources":["../../../src/lib/inject/detect-target.ts"],"sourcesContent":["/**\n * Pure classifiers for the inject engine.\n *\n * `detectTarget` decides whether a seed of project files belongs in\n * `@babylonjsmarket/arcade` (per-component, registered) or the viz package\n * (flat per-layer barrels).\n *\n * `detectLayer` decides which viz layer (`core`, `solid`, `ecs`) owns a\n * single source file. Order matters: rules are evaluated top-down and the\n * first match wins. The order mirrors the plan.\n *\n * Target naming: the canonical user-facing target names are `arcade` and\n * `viz`. The legacy `arcade-pro` / `viz-pro` package names live on only as\n * back-compat aliases (normalized to the canonical names by callers) and as\n * import-prefix patterns we still recognize in existing seeds.\n */\n\nexport type Target = \"arcade\" | \"viz\";\nexport type VizLayer = \"core\" | \"solid\" | \"ecs\";\n\nexport interface SeedFile {\n path: string;\n source: string;\n}\n\n/**\n * Classify a closure of seed files to one of the two packages. Any single\n * file extending a viz System class or importing from `@babylonjsmarket/viz`\n * (or the legacy `@babylonjsmarket/viz-pro`) tips the whole seed to `viz`.\n */\nexport function detectTarget(seedFiles: SeedFile[]): Target {\n for (const { source } of seedFiles) {\n // Recognize BOTH the canonical `@babylonjsmarket/viz` and the legacy\n // `@babylonjsmarket/viz-pro` import prefix — existing seeds were ejected\n // against `viz-pro` and must still classify correctly.\n if (/from\\s+['\"]@babylonjsmarket\\/viz(?:-pro)?['\"]/.test(source)) return \"viz\";\n if (/extends\\s+(PanelDebuggerSystem|StateStepperSystem)\\b/.test(source)) return \"viz\";\n }\n return \"arcade\";\n}\n\n/**\n * Classify a single source file to a viz layer.\n *\n * Order is load-bearing:\n * 1. *.test.ts(x) → route alongside the subject file (re-detect on the\n * subject's source if known, else default 'core').\n * 2. *.tsx that imports from 'solid-js' → 'solid'.\n * 3. extends (PanelDebuggerSystem|StateStepperSystem|System) or filename\n * ends in 'System.ts' → 'ecs'.\n * 4. extends Component and no Solid import → 'ecs'.\n * 5. contains `definePanel(` and no Solid import → 'core'.\n * 6. fallback → 'core'.\n *\n * `subjectLayer` lets the caller pin a test file to its subject's layer; pass\n * `undefined` when the subject isn't co-injected, which falls through to\n * rule (1)'s default.\n */\nexport function detectLayer(\n filePath: string,\n source: string,\n subjectLayer?: VizLayer,\n): VizLayer {\n const base = filePath.split(/[\\\\/]/).pop() ?? filePath;\n\n // (1) test files travel with their subject\n if (/\\.test\\.tsx?$/.test(base)) {\n return subjectLayer ?? \"core\";\n }\n\n const hasSolidImport = /from\\s+['\"]solid-js['\"]/.test(source);\n\n // (2) Solid .tsx\n if (/\\.tsx$/.test(base) && hasSolidImport) return \"solid\";\n\n // (3) System subclasses or *System.ts filenames\n if (/extends\\s+(PanelDebuggerSystem|StateStepperSystem|System)\\b/.test(source)) return \"ecs\";\n if (/System\\.ts$/.test(base)) return \"ecs\";\n\n // (4) Component subclasses (no Solid)\n if (/extends\\s+Component\\b/.test(source) && !hasSolidImport) return \"ecs\";\n\n // (5) definePanel files (no Solid)\n if (/\\bdefinePanel\\s*\\(/.test(source) && !hasSolidImport) return \"core\";\n\n // (6) fallback\n return \"core\";\n}\n"],"mappings":";AA8BO,SAAS,aAAa,WAA+B;AAC1D,aAAW,EAAE,OAAO,KAAK,WAAW;AAIlC,QAAI,gDAAgD,KAAK,MAAM,EAAG,QAAO;AACzE,QAAI,uDAAuD,KAAK,MAAM,EAAG,QAAO;AAAA,EAClF;AACA,SAAO;AACT;AAmBO,SAAS,YACd,UACA,QACA,cACU;AACV,QAAM,OAAO,SAAS,MAAM,OAAO,EAAE,IAAI,KAAK;AAG9C,MAAI,gBAAgB,KAAK,IAAI,GAAG;AAC9B,WAAO,gBAAgB;AAAA,EACzB;AAEA,QAAM,iBAAiB,0BAA0B,KAAK,MAAM;AAG5D,MAAI,SAAS,KAAK,IAAI,KAAK,eAAgB,QAAO;AAGlD,MAAI,8DAA8D,KAAK,MAAM,EAAG,QAAO;AACvF,MAAI,cAAc,KAAK,IAAI,EAAG,QAAO;AAGrC,MAAI,wBAAwB,KAAK,MAAM,KAAK,CAAC,eAAgB,QAAO;AAGpE,MAAI,qBAAqB,KAAK,MAAM,KAAK,CAAC,eAAgB,QAAO;AAGjE,SAAO;AACT;","names":[]}
@@ -14,15 +14,15 @@ BabylonJS Market for curator review (reverse of ${cyan("arcade eject")}).
14
14
 
15
15
  With no ${bold("--target")}, the tool auto-detects per seed:
16
16
  * any file extending ${cyan("PanelDebuggerSystem")} / ${cyan("StateStepperSystem")} or
17
- importing from ${cyan("@babylonjsmarket/viz-pro")} \u2192 ${cyan("viz-pro")},
18
- * otherwise \u2192 ${cyan("arcade-pro")}.
17
+ importing from ${cyan("@babylonjsmarket/viz")} \u2192 ${cyan("viz")},
18
+ * otherwise \u2192 ${cyan("arcade")}.
19
19
 
20
20
  Multi-seed inputs must all detect to the same target.
21
21
 
22
22
  Options:
23
- --target <arcade-pro|viz-pro> skip auto-detection
23
+ --target <arcade|viz> skip auto-detection (legacy: arcade-pro, viz-pro)
24
24
  --source <path> override <cwd>/src/components/<Name>/
25
- --layer <core|solid|ecs> viz-pro only; skip per-file layer detection
25
+ --layer <core|solid|ecs> viz only; skip per-file layer detection
26
26
  --force allow overwriting an existing target
27
27
  --dry-run print the plan, write nothing, do not submit
28
28
  -h, --help print this help message
@@ -30,17 +30,17 @@ Options:
30
30
  Examples:
31
31
  bjs inject Foo # auto-detect target
32
32
  bjs inject Foo Bar --dry-run # multi-name, preview
33
- bjs inject MyPanelDebugger --target viz-pro
33
+ bjs inject MyPanelDebugger --target viz
34
34
  bjs inject Foo --source ./packages/demo/src/components/Foo
35
35
  `;
36
36
 
37
37
  // src/lib/inject/detect-target.ts
38
38
  function detectTarget(seedFiles) {
39
39
  for (const { source } of seedFiles) {
40
- if (/from\s+['"]@babylonjsmarket\/viz-pro['"]/.test(source)) return "viz-pro";
41
- if (/extends\s+(PanelDebuggerSystem|StateStepperSystem)\b/.test(source)) return "viz-pro";
40
+ if (/from\s+['"]@babylonjsmarket\/viz(?:-pro)?['"]/.test(source)) return "viz";
41
+ if (/extends\s+(PanelDebuggerSystem|StateStepperSystem)\b/.test(source)) return "viz";
42
42
  }
43
- return "arcade-pro";
43
+ return "arcade";
44
44
  }
45
45
  function detectLayer(filePath, source, subjectLayer) {
46
46
  const base = filePath.split(/[\\/]/).pop() ?? filePath;
@@ -167,7 +167,7 @@ function rewriteArcadeImports(src, injected) {
167
167
  }
168
168
  function rewriteVizImports(src, injected, layerOf, fromLayer) {
169
169
  return src.replace(
170
- /(['"])@babylonjsmarket\/(?:viz-pro|arcade|arcade-pro)\/([A-Z][A-Za-z0-9_]*)\1/g,
170
+ /(['"])@babylonjsmarket\/(?:viz-pro|viz|arcade|arcade-pro)\/([A-Z][A-Za-z0-9_]*)\1/g,
171
171
  (whole, quote, sibling) => {
172
172
  if (!injected.has(sibling)) return whole;
173
173
  const dest = layerOf(sibling);
@@ -181,7 +181,7 @@ function planArcadeProRegistry(existingRegistry, names, registryRelPath = "src/r
181
181
  const warnings = [];
182
182
  if (existingRegistry === void 0) {
183
183
  warnings.push(
184
- `! packages/arcade-pro/${registryRelPath} not found \u2014 add resolvers manually for: ${names.join(", ")}`
184
+ `! packages/arcade/${registryRelPath} not found \u2014 add resolvers manually for: ${names.join(", ")}`
185
185
  );
186
186
  return { lines: [], added: [], warnings, markerFound: false };
187
187
  }
@@ -271,7 +271,8 @@ async function inject(args, opts = {}) {
271
271
  const move = Boolean(argv.move);
272
272
  const confirm = Boolean(argv.confirm);
273
273
  const force = Boolean(argv.force);
274
- const explicitTarget = argv.target;
274
+ const rawTarget = argv.target;
275
+ const explicitTarget = rawTarget === "arcade-pro" ? "arcade" : rawTarget === "viz-pro" ? "viz" : rawTarget;
275
276
  const sourceOverride = argv.source;
276
277
  const layerOverride = argv.layer;
277
278
  const names = argv._.map(String);
@@ -297,8 +298,8 @@ async function inject(args, opts = {}) {
297
298
  process.exit(1);
298
299
  return;
299
300
  }
300
- if (explicitTarget && explicitTarget !== "arcade-pro" && explicitTarget !== "viz-pro") {
301
- console.error(yellow(`Unknown --target ${explicitTarget}. Use arcade-pro or viz-pro.`));
301
+ if (explicitTarget && explicitTarget !== "arcade" && explicitTarget !== "viz") {
302
+ console.error(yellow(`Unknown --target ${rawTarget}. Use arcade or viz.`));
302
303
  process.exit(1);
303
304
  return;
304
305
  }
@@ -373,10 +374,10 @@ async function inject(args, opts = {}) {
373
374
  let chosenRoot;
374
375
  if (mode === "apply") {
375
376
  try {
376
- if (target === "arcade-pro") {
377
+ if (target === "arcade") {
377
378
  if (!fs2.existsSync(packageRoot)) {
378
379
  throw new Error(
379
- `packages/arcade-pro is not checked out at ${packageRoot}. Run \`git submodule update --init packages/arcade-pro\` and retry.`
380
+ `packages/arcade is not checked out at ${packageRoot}. Run \`git submodule update --init packages/arcade\` and retry.`
380
381
  );
381
382
  }
382
383
  chosenRoot = packageRoot;
@@ -400,7 +401,7 @@ async function inject(args, opts = {}) {
400
401
  console.log(` target: ${cyan2(target)}`);
401
402
  console.log(` components: ${cyan2([...closure].sort().join(", "))}`);
402
403
  if (mode === "collect") {
403
- const result = target === "arcade-pro" ? collectArcadePro({ seeds, closure, componentsDir, sourceOverride }) : collectVizPro({ seeds, closure, componentsDir, sourceOverride, layerOverride });
404
+ const result = target === "arcade" ? collectArcadePro({ seeds, closure, componentsDir, sourceOverride }) : collectVizPro({ seeds, closure, componentsDir, sourceOverride, layerOverride });
404
405
  for (const f of result.files) console.log(green(` + packages/${target}/${f.path}`));
405
406
  for (const w of result.warnings) console.log(yellow(w));
406
407
  console.log(
@@ -408,7 +409,7 @@ async function inject(args, opts = {}) {
408
409
  );
409
410
  return { ...result, target };
410
411
  }
411
- if (target === "arcade-pro") {
412
+ if (target === "arcade") {
412
413
  await injectArcadePro({
413
414
  seeds,
414
415
  closure,
@@ -472,7 +473,7 @@ async function injectArcadePro(args) {
472
473
  const dest = path2.join(destComponents, name);
473
474
  if (fs2.existsSync(dest) && !force) {
474
475
  console.log(
475
- yellow(` ! packages/arcade-pro/src/Components/${name}/ already exists \u2014 pass --force to overwrite.`)
476
+ yellow(` ! packages/arcade/src/Components/${name}/ already exists \u2014 pass --force to overwrite.`)
476
477
  );
477
478
  continue;
478
479
  }
@@ -480,7 +481,7 @@ async function injectArcadePro(args) {
480
481
  if (fs2.existsSync(dest)) fs2.rmSync(dest, { recursive: true, force: true });
481
482
  fs2.cpSync(src, dest, { recursive: true });
482
483
  }
483
- console.log(green(` + packages/arcade-pro/src/Components/${name}/`));
484
+ console.log(green(` + packages/arcade/src/Components/${name}/`));
484
485
  }
485
486
  if (!dryRun) {
486
487
  for (const name of closure) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/lib/inject/engine.ts","../../../src/lib/inject/inject-options.ts","../../../src/lib/inject/detect-target.ts","../../../src/lib/inject/monorepo-root.ts"],"sourcesContent":["import fs from \"node:fs\";\nimport path from \"node:path\";\nimport mri from \"mri\";\nimport colors from \"picocolors\";\nimport { INJECT_HELP } from \"./inject-options.js\";\nimport {\n detectTarget,\n detectLayer,\n type Target,\n type VizLayer,\n type SeedFile,\n} from \"./detect-target.js\";\nimport { findMonorepoRoot } from \"./monorepo-root.js\";\n\nconst { cyan, green, yellow, dim, bold } = colors;\n\n// ─── Public collect-mode result shape ────────────────────────────────────────\n\nexport interface InjectPatch {\n /** Path of the file being patched, relative to the target package root. */\n file: string;\n kind: \"registry-append\" | \"barrel-append\";\n /** The line that would be appended/inserted. */\n line: string;\n}\n\nexport interface InjectFile {\n /** Path relative to the target package root (e.g. `src/Components/Foo/Foo.ts`). */\n path: string;\n contents: string;\n}\n\nexport interface InjectCollectResult {\n target: Target;\n files: InjectFile[];\n patches: InjectPatch[];\n warnings: string[];\n}\n\n// ─── Filesystem helpers (mirrors eject.ts) ────────────────────────────────────\n\n/** Every .ts/.tsx file inside a project component folder. */\nfunction componentFiles(dir: string): string[] {\n const out: string[] = [];\n const walk = (d: string) => {\n for (const e of fs.readdirSync(d, { withFileTypes: true })) {\n const p = path.join(d, e.name);\n if (e.isDirectory()) walk(p);\n else if (/\\.(ts|tsx)$/.test(e.name)) out.push(p);\n }\n };\n if (fs.existsSync(dir)) walk(dir);\n return out;\n}\n\n/** Every file (including non-ts assets like meta.json) inside a component folder. */\nfunction allComponentFiles(dir: string): string[] {\n const out: string[] = [];\n const walk = (d: string) => {\n for (const e of fs.readdirSync(d, { withFileTypes: true })) {\n const p = path.join(d, e.name);\n if (e.isDirectory()) walk(p);\n else out.push(p);\n }\n };\n if (fs.existsSync(dir)) walk(dir);\n return out;\n}\n\n/** All top-level project component names = `<project>/src/components/*` (minus `_shared`). */\nfunction projectComponentNames(projectDir: string): string[] {\n const dir = path.join(projectDir, \"src\", \"components\");\n if (!fs.existsSync(dir)) return [];\n return fs\n .readdirSync(dir, { withFileTypes: true })\n .filter((e) => e.isDirectory() && e.name !== \"_shared\")\n .map((e) => e.name);\n}\n\n/** Component names a given seed imports via `../Sibling/`, `~/components/Sibling/`, or its meta.json deps. */\nfunction directDeps(\n name: string,\n componentsDir: string,\n allNames: Set<string>,\n): Set<string> {\n const deps = new Set<string>();\n const metaPath = path.join(componentsDir, name, \"meta.json\");\n if (fs.existsSync(metaPath)) {\n try {\n const meta = JSON.parse(fs.readFileSync(metaPath, \"utf8\")) as { dependencies?: string[] };\n for (const d of meta.dependencies ?? []) if (allNames.has(d)) deps.add(d);\n } catch {\n /* tolerate malformed meta.json — import scan is the safety net */\n }\n }\n const relRe = /['\"]\\.\\.\\/([A-Z][A-Za-z0-9_]*)\\//g;\n const aliasRe = /['\"]~\\/components\\/([A-Z][A-Za-z0-9_]*)\\//g;\n for (const file of componentFiles(path.join(componentsDir, name))) {\n const src = fs.readFileSync(file, \"utf8\");\n let m: RegExpExecArray | null;\n while ((m = relRe.exec(src))) if (allNames.has(m[1])) deps.add(m[1]);\n while ((m = aliasRe.exec(src))) if (allNames.has(m[1])) deps.add(m[1]);\n }\n return deps;\n}\n\n/** Expand a seed set to its transitive sibling closure. */\nfunction resolveClosure(\n seed: Set<string>,\n componentsDir: string,\n allNames: string[],\n): Set<string> {\n const all = new Set(allNames);\n const out = new Set(seed);\n const queue = [...seed];\n while (queue.length) {\n const next = queue.pop()!;\n for (const dep of directDeps(next, componentsDir, all)) {\n if (!out.has(dep)) {\n out.add(dep);\n queue.push(dep);\n }\n }\n }\n return out;\n}\n\n/**\n * Reverse of eject's rewriteImports:\n *\n * `'@babylonjsmarket/arcade/<Sibling>'` → `'../<Sibling>/<Sibling>'`\n * `'@babylonjsmarket/arcade-pro/<Sibling>'` → `'../<Sibling>/<Sibling>'`\n *\n * …but only when <Sibling> is co-injected for the same target package. Other\n * package subpaths (including ecs / babylon / solid-js / etc.) are left alone.\n *\n * For arcade-pro, components share a parent (`src/Components/`), so the\n * relative path is always `../<Sibling>/<Sibling>`. For viz-pro the caller\n * supplies a `layerMap` and the originating file's layer; the relative path\n * resolves through the per-file layer routing.\n */\nfunction rewriteArcadeImports(src: string, injected: Set<string>): string {\n return src.replace(\n /(['\"])@babylonjsmarket\\/(?:arcade|arcade-pro)\\/([A-Z][A-Za-z0-9_]*)\\1/g,\n (whole, quote, sibling) => {\n if (injected.has(sibling)) {\n return `${quote}../${sibling}/${sibling}${quote}`;\n }\n return whole;\n },\n );\n}\n\n/**\n * viz-pro variant. Rewrites `@babylonjsmarket/viz-pro/<Sibling>` (or\n * `@babylonjsmarket/arcade/<Sibling>` referencing a viz-pro sibling) to the\n * correct flat-layer relative path: `../<targetLayer>/<Sibling>`. Same-layer\n * siblings collapse to `./<Sibling>`.\n */\nfunction rewriteVizImports(\n src: string,\n injected: Set<string>,\n layerOf: (name: string) => VizLayer | undefined,\n fromLayer: VizLayer,\n): string {\n return src.replace(\n /(['\"])@babylonjsmarket\\/(?:viz-pro|arcade|arcade-pro)\\/([A-Z][A-Za-z0-9_]*)\\1/g,\n (whole, quote, sibling) => {\n if (!injected.has(sibling)) return whole;\n const dest = layerOf(sibling);\n if (!dest) return whole;\n const rel = dest === fromLayer ? `./${sibling}` : `../${dest}/${sibling}`;\n return `${quote}${rel}${quote}`;\n },\n );\n}\n\n// ─── Registry / barrel patchers ───────────────────────────────────────────────\n\n/**\n * Append lazy resolver lines into ARCADE_PRO_COMPONENT_REGISTRY. Pure decision\n * step: returns what to add without touching disk.\n *\n * `existingRegistry` is the current registry.ts contents, or `undefined` when\n * the file isn't present (apply mode missing the marker emits a warning; in\n * collect mode we always assume the marker is present).\n */\nfunction planArcadeProRegistry(\n existingRegistry: string | undefined,\n names: string[],\n registryRelPath = \"src/registry.ts\",\n): { lines: string[]; added: string[]; warnings: string[]; markerFound: boolean } {\n const warnings: string[] = [];\n if (existingRegistry === undefined) {\n warnings.push(\n `! packages/arcade-pro/${registryRelPath} not found — add resolvers manually for: ${names.join(\", \")}`,\n );\n return { lines: [], added: [], warnings, markerFound: false };\n }\n const marker = /ARCADE_PRO_COMPONENT_REGISTRY:\\s*Record<string,\\s*LazyComponentResolver>\\s*=\\s*\\{/;\n if (!marker.test(existingRegistry)) {\n warnings.push(\n `! Could not find 'ARCADE_PRO_COMPONENT_REGISTRY' marker — add resolvers manually for: ${names.join(\", \")}`,\n );\n return { lines: [], added: [], warnings, markerFound: false };\n }\n const added: string[] = [];\n const lines: string[] = [];\n for (const name of names) {\n if (existingRegistry.includes(`./Components/${name}/${name}`)) continue; // already wired\n lines.push(` ${name}: () => import('./Components/${name}/${name}'),`);\n added.push(name);\n }\n return { lines, added, warnings, markerFound: true };\n}\n\n/** Append a lazy resolver line into ARCADE_PRO_COMPONENT_REGISTRY (idempotent, on-disk). */\nfunction patchArcadeProRegistry(\n arcadeProRoot: string,\n names: string[],\n dryRun: boolean,\n): string[] {\n const registryPath = path.join(arcadeProRoot, \"src\", \"registry.ts\");\n const existing = fs.existsSync(registryPath) ? fs.readFileSync(registryPath, \"utf8\") : undefined;\n const plan = planArcadeProRegistry(existing, names);\n if (plan.warnings.length) return plan.warnings;\n if (plan.added.length && !dryRun) {\n const marker = /ARCADE_PRO_COMPONENT_REGISTRY:\\s*Record<string,\\s*LazyComponentResolver>\\s*=\\s*\\{/;\n const next = (existing as string).replace(marker, (m) => `${m}\\n${plan.lines.join(\"\\n\")}`);\n fs.writeFileSync(registryPath, next);\n }\n return plan.added.map((n) => ` patched registry: ${n}`);\n}\n\n/**\n * Pure planner for the viz-pro layer barrel: returns the line to append if any.\n */\nfunction planVizProBarrel(\n existingBarrel: string | undefined,\n layer: VizLayer,\n fileName: string,\n): { line: string | null; warnings: string[] } {\n if (existingBarrel === undefined) {\n return {\n line: null,\n warnings: [\n `! packages/viz-pro/src/${layer}/index.ts not found — add the barrel re-export manually for ${fileName}`,\n ],\n };\n }\n const needle = `from './${fileName}'`;\n if (existingBarrel.includes(needle)) return { line: null, warnings: [] };\n return { line: `export * from './${fileName}';`, warnings: [] };\n}\n\n/** Append `export * from './<FileName>';` to a viz-pro layer barrel (idempotent, on-disk). */\nfunction patchVizProBarrel(\n vizProRoot: string,\n layer: VizLayer,\n fileName: string,\n dryRun: boolean,\n): string[] {\n const barrelPath = path.join(vizProRoot, \"src\", layer, \"index.ts\");\n const existing = fs.existsSync(barrelPath) ? fs.readFileSync(barrelPath, \"utf8\") : undefined;\n const plan = planVizProBarrel(existing, layer, fileName);\n if (plan.warnings.length) return plan.warnings;\n if (plan.line === null) return [];\n if (!dryRun) {\n const next = existing!.endsWith(\"\\n\")\n ? existing + plan.line + \"\\n\"\n : existing + \"\\n\" + plan.line + \"\\n\";\n fs.writeFileSync(barrelPath, next);\n }\n return [` patched ${layer}/index.ts: ${fileName}`];\n}\n\n/**\n * Strip a lazy-resolver line of the form\n * ` Foo: () => import('./components/Foo/Foo'),`\n * from `<project>/src/registry.ts`. Returns the list of names actually removed.\n */\nfunction stripProjectRegistry(\n projectDir: string,\n names: string[],\n dryRun: boolean,\n): string[] {\n const registryPath = path.join(projectDir, \"src\", \"registry.ts\");\n if (!fs.existsSync(registryPath)) return [];\n let text = fs.readFileSync(registryPath, \"utf8\");\n const removed: string[] = [];\n for (const name of names) {\n const re = new RegExp(\n `^\\\\s*${name}\\\\s*:\\\\s*\\\\(\\\\)\\\\s*=>\\\\s*import\\\\(\\\\s*['\"]\\\\.\\\\/components\\\\/${name}\\\\/${name}['\"]\\\\s*\\\\)\\\\s*,?\\\\s*\\\\r?\\\\n`,\n \"m\",\n );\n if (re.test(text)) {\n text = text.replace(re, \"\");\n removed.push(name);\n }\n }\n if (removed.length && !dryRun) fs.writeFileSync(registryPath, text);\n return removed;\n}\n\n// ─── Plan + main entry ────────────────────────────────────────────────────────\n\ninterface ResolvedSeed {\n /** Name as the operator typed it (and as it lives under `src/components/`). */\n name: string;\n /** Absolute path to the seed's source directory (post `--source` override). */\n sourceDir: string;\n}\n\nexport interface InjectOptions {\n /**\n * What the engine does with the resolved file list:\n * - 'apply' → writes into the resolved packageRoot/vizProRoot (operator mode).\n * - 'collect' → returns the file map + patch plan without touching disk\n * (member mode; payload goes to the marketplace endpoint).\n */\n mode?: \"apply\" | \"collect\";\n /** Tmpdir-friendly: the arcade-pro package root (the dir containing `src/registry.ts`). Apply mode only. */\n packageRoot?: string;\n /** Tmpdir-friendly: the viz-pro package root (the dir containing `src/{core,solid,ecs}/index.ts`). Apply mode only. */\n vizProRoot?: string;\n /** The project we're injecting FROM. Defaults to `cwd`. */\n projectDir?: string;\n /** Override for `process.cwd()`. Tests use this; the CLI entry passes `process.cwd()`. */\n cwd?: string;\n}\n\nexport async function inject(\n args: string[],\n opts: InjectOptions = {},\n): Promise<InjectCollectResult | void> {\n if (args.includes(\"-h\") || args.includes(\"--help\")) {\n console.log(INJECT_HELP);\n return;\n }\n\n const argv = mri(args, {\n boolean: [\"dry-run\", \"move\", \"confirm\", \"force\"],\n string: [\"target\", \"source\", \"layer\"],\n });\n\n const mode: \"apply\" | \"collect\" = opts.mode ?? \"apply\";\n const dryRun = Boolean(argv[\"dry-run\"]);\n const move = Boolean(argv.move);\n const confirm = Boolean(argv.confirm);\n const force = Boolean(argv.force);\n const explicitTarget = argv.target as Target | undefined;\n const sourceOverride = argv.source as string | undefined;\n const layerOverride = argv.layer as VizLayer | undefined;\n const names = argv._.map(String);\n\n const cwd = opts.cwd ?? process.cwd();\n const projectDir = opts.projectDir ?? cwd;\n\n // ─── Arg validation ───\n if (names.length === 0) {\n console.error(yellow(\"No component names given. Pass at least one, e.g. `bjs inject Foo`.\"));\n process.exit(1);\n return;\n }\n // --move / --confirm are operator-only knobs. In collect mode they're\n // meaningless (no project to mutate); flag and bail.\n if (mode === \"collect\" && (move || confirm)) {\n console.error(yellow(\"--move and --confirm are not available in member submission mode.\"));\n process.exit(1);\n return;\n }\n if (move && !confirm) {\n console.error(yellow(\"--move requires --confirm (it deletes project files). Pass --move --confirm.\"));\n process.exit(1);\n return;\n }\n if (move && dryRun) {\n console.error(yellow(\"--move and --dry-run are mutually exclusive. Drop one.\"));\n process.exit(1);\n return;\n }\n if (explicitTarget && explicitTarget !== \"arcade-pro\" && explicitTarget !== \"viz-pro\") {\n console.error(yellow(`Unknown --target ${explicitTarget}. Use arcade-pro or viz-pro.`));\n process.exit(1);\n return;\n }\n if (layerOverride && layerOverride !== \"core\" && layerOverride !== \"solid\" && layerOverride !== \"ecs\") {\n console.error(yellow(`Unknown --layer ${layerOverride}. Use core, solid, or ecs.`));\n process.exit(1);\n return;\n }\n if (sourceOverride && names.length > 1) {\n console.error(yellow(\"--source applies to a single seed; pass one NAME with --source.\"));\n process.exit(1);\n return;\n }\n\n // ─── Phase 0: resolve roots (apply mode only) ───\n let packageRoot = opts.packageRoot;\n let vizProRoot = opts.vizProRoot;\n if (mode === \"apply\" && (!packageRoot || !vizProRoot)) {\n try {\n const monorepo = findMonorepoRoot();\n packageRoot ??= monorepo.arcadeProRoot;\n vizProRoot ??= monorepo.vizProRoot;\n } catch (e) {\n console.error(yellow((e as Error).message));\n process.exit(1);\n return;\n }\n }\n\n // ─── Phase 1: locate seeds + walk closure ───\n const componentsDir = path.join(projectDir, \"src\", \"components\");\n const allProjectNames = projectComponentNames(projectDir);\n\n const seeds: ResolvedSeed[] = [];\n for (const name of names) {\n const sourceDir = sourceOverride\n ? path.resolve(cwd, sourceOverride)\n : path.join(componentsDir, name);\n if (!fs.existsSync(sourceDir)) {\n console.error(\n yellow(\n `Could not find source for \"${name}\". Looked at ${sourceDir}. ` +\n `Use --source <path> to point at the seed explicitly.`,\n ),\n );\n process.exit(1);\n return;\n }\n seeds.push({ name, sourceDir });\n }\n\n // Run the closure walk in the project's components dir (only when seeds live\n // under <project>/src/components/, which is the default and the case we can\n // reason about transitively). With --source we still inject the seed itself\n // but skip the transitive walk — caller is in unusual territory.\n const seedNames = new Set(seeds.map((s) => s.name));\n const closure: Set<string> = sourceOverride\n ? seedNames\n : resolveClosure(seedNames, componentsDir, allProjectNames);\n\n // ─── Phase 2: target detection ───\n const closureFiles: SeedFile[] = [];\n for (const name of closure) {\n const dir = sourceOverride && seedNames.has(name)\n ? seeds.find((s) => s.name === name)!.sourceDir\n : path.join(componentsDir, name);\n for (const f of componentFiles(dir)) {\n closureFiles.push({ path: f, source: fs.readFileSync(f, \"utf8\") });\n }\n }\n\n const target: Target = explicitTarget ?? detectTarget(closureFiles);\n\n // For multi-seed inputs, every seed individually must agree with `target`.\n if (!explicitTarget && seeds.length > 1) {\n for (const seed of seeds) {\n const dir = seed.sourceDir;\n const files: SeedFile[] = componentFiles(dir).map((f) => ({\n path: f,\n source: fs.readFileSync(f, \"utf8\"),\n }));\n const perSeed = detectTarget(files);\n if (perSeed !== target) {\n console.error(\n yellow(\n `Auto-detect disagrees across seeds: \"${seed.name}\" → ${perSeed}, ` +\n `others → ${target}. Pass --target explicitly or split into separate runs.`,\n ),\n );\n process.exit(1);\n return;\n }\n }\n }\n\n // ─── Apply-mode root checks ───\n let chosenRoot: string | undefined;\n if (mode === \"apply\") {\n try {\n if (target === \"arcade-pro\") {\n if (!fs.existsSync(packageRoot!)) {\n throw new Error(\n `packages/arcade-pro is not checked out at ${packageRoot}. Run \\`git submodule update --init packages/arcade-pro\\` and retry.`,\n );\n }\n chosenRoot = packageRoot!;\n } else {\n if (!fs.existsSync(vizProRoot!)) {\n throw new Error(\n `packages/viz-pro is not checked out at ${vizProRoot}. Run \\`git submodule update --init packages/viz-pro\\` and retry.`,\n );\n }\n chosenRoot = vizProRoot!;\n }\n } catch (e) {\n console.error(yellow((e as Error).message));\n process.exit(1);\n return;\n }\n }\n\n // ─── Plan logging header ───\n console.log(\n bold(dryRun ? \"\\nInject plan (dry run — nothing written):\" : \"\\nInjecting:\"),\n );\n console.log(` target: ${cyan(target)}`);\n console.log(` components: ${cyan([...closure].sort().join(\", \"))}`);\n\n // ─── Phase 3: copy files ───\n if (mode === \"collect\") {\n const result =\n target === \"arcade-pro\"\n ? collectArcadePro({ seeds, closure, componentsDir, sourceOverride })\n : collectVizPro({ seeds, closure, componentsDir, sourceOverride, layerOverride });\n for (const f of result.files) console.log(green(` + packages/${target}/${f.path}`));\n for (const w of result.warnings) console.log(yellow(w));\n console.log(\n dryRun\n ? dim(\"\\nRe-run without --dry-run to submit.\\n\")\n : dim(\"\\nCollect-mode plan ready (no submission performed by the library).\\n\"),\n );\n return { ...result, target };\n }\n\n // mode === 'apply'\n if (target === \"arcade-pro\") {\n await injectArcadePro({\n seeds,\n closure,\n componentsDir,\n sourceOverride,\n arcadeProRoot: chosenRoot!,\n dryRun,\n force,\n });\n } else {\n await injectVizPro({\n seeds,\n closure,\n componentsDir,\n sourceOverride,\n vizProRoot: chosenRoot!,\n dryRun,\n force,\n layerOverride,\n });\n }\n\n // ─── Phase 6 (optional): source cleanup ───\n if (move) {\n if (sourceOverride) {\n console.log(\n yellow(\n \" ! --move with --source: only the source dir is removed; cannot reliably patch a foreign project's registry.\",\n ),\n );\n }\n for (const seed of seeds) {\n if (fs.existsSync(seed.sourceDir)) {\n if (!dryRun) fs.rmSync(seed.sourceDir, { recursive: true, force: true });\n console.log(dim(` - ${path.relative(projectDir, seed.sourceDir)}/ (project copy removed)`));\n }\n }\n const removed = stripProjectRegistry(\n projectDir,\n seeds.map((s) => s.name),\n dryRun,\n );\n for (const name of removed) {\n console.log(dim(` - project registry entry: ${name}`));\n }\n }\n\n console.log(\n dryRun\n ? dim(\"\\nRe-run without --dry-run to apply.\\n\")\n : green(`\\nDone. Components landed in packages/${target}/.\\n`),\n );\n}\n\n// ─── arcade-pro injection (apply mode) ───────────────────────────────────────\n\nasync function injectArcadePro(args: {\n seeds: ResolvedSeed[];\n closure: Set<string>;\n componentsDir: string;\n sourceOverride: string | undefined;\n arcadeProRoot: string;\n dryRun: boolean;\n force: boolean;\n}): Promise<void> {\n const { seeds, closure, componentsDir, sourceOverride, arcadeProRoot, dryRun, force } = args;\n const destComponents = path.join(arcadeProRoot, \"src\", \"Components\");\n if (!dryRun) fs.mkdirSync(destComponents, { recursive: true });\n\n const sourceOf = (name: string): string => {\n const seed = seeds.find((s) => s.name === name);\n return seed && sourceOverride ? seed.sourceDir : path.join(componentsDir, name);\n };\n\n for (const name of [...closure].sort()) {\n const src = sourceOf(name);\n const dest = path.join(destComponents, name);\n if (fs.existsSync(dest) && !force) {\n console.log(\n yellow(` ! packages/arcade-pro/src/Components/${name}/ already exists — pass --force to overwrite.`),\n );\n continue;\n }\n if (!dryRun) {\n if (fs.existsSync(dest)) fs.rmSync(dest, { recursive: true, force: true });\n fs.cpSync(src, dest, { recursive: true });\n }\n console.log(green(` + packages/arcade-pro/src/Components/${name}/`));\n }\n\n // Phase 4: import rewriting across each copied folder.\n if (!dryRun) {\n for (const name of closure) {\n const dest = path.join(destComponents, name);\n if (!fs.existsSync(dest)) continue;\n rewriteTree(dest, (text) => rewriteArcadeImports(text, closure));\n }\n }\n\n // Phase 5: arcade-pro registry patch.\n for (const line of patchArcadeProRegistry(\n arcadeProRoot,\n [...closure].sort(),\n dryRun,\n )) {\n console.log(line.startsWith(\"!\") ? yellow(line) : dim(line));\n }\n}\n\n// ─── arcade-pro collection (collect mode) ────────────────────────────────────\n\nfunction collectArcadePro(args: {\n seeds: ResolvedSeed[];\n closure: Set<string>;\n componentsDir: string;\n sourceOverride: string | undefined;\n}): { files: InjectFile[]; patches: InjectPatch[]; warnings: string[] } {\n const { seeds, closure, componentsDir, sourceOverride } = args;\n const sourceOf = (name: string): string => {\n const seed = seeds.find((s) => s.name === name);\n return seed && sourceOverride ? seed.sourceDir : path.join(componentsDir, name);\n };\n\n const files: InjectFile[] = [];\n const warnings: string[] = [];\n\n for (const name of [...closure].sort()) {\n const src = sourceOf(name);\n if (!fs.existsSync(src)) {\n warnings.push(` ! source for ${name} missing at ${src}`);\n continue;\n }\n for (const abs of allComponentFiles(src)) {\n const rel = path.relative(src, abs);\n const baseRel = path.posix.join(\"src\", \"Components\", name, rel.split(path.sep).join(\"/\"));\n const isText = /\\.(ts|tsx)$/i.test(abs);\n const raw = fs.readFileSync(abs, \"utf8\");\n const contents = isText ? rewriteArcadeImports(raw, closure) : raw;\n files.push({ path: baseRel, contents });\n }\n }\n\n // Plan the registry patch — but submit the *desired* added lines, not the\n // raw existing+new file. The server applies the patch against whatever the\n // pro package looks like at merge time.\n const patches: InjectPatch[] = [];\n for (const name of [...closure].sort()) {\n patches.push({\n file: \"src/registry.ts\",\n kind: \"registry-append\",\n line: ` ${name}: () => import('./Components/${name}/${name}'),`,\n });\n }\n\n return { files, patches, warnings };\n}\n\n// ─── viz-pro injection (apply mode) ──────────────────────────────────────────\n\ninterface ViewFile {\n src: string;\n base: string;\n owner: string;\n source: string;\n layer: VizLayer;\n destBase: string;\n}\n\nfunction classifyVizFiles(args: {\n seeds: ResolvedSeed[];\n closure: Set<string>;\n componentsDir: string;\n sourceOverride: string | undefined;\n layerOverride: VizLayer | undefined;\n}): { files: ViewFile[]; primaryLayer: Map<string, VizLayer> } {\n const { seeds, closure, componentsDir, sourceOverride, layerOverride } = args;\n\n const sourceOf = (name: string): string => {\n const seed = seeds.find((s) => s.name === name);\n return seed && sourceOverride ? seed.sourceDir : path.join(componentsDir, name);\n };\n\n const files: ViewFile[] = [];\n\n // Pass A — non-tests\n for (const name of closure) {\n const dir = sourceOf(name);\n for (const abs of componentFiles(dir)) {\n const base = path.basename(abs);\n if (/\\.test\\.tsx?$/.test(base)) continue;\n const source = fs.readFileSync(abs, \"utf8\");\n const layer = layerOverride ?? detectLayer(abs, source);\n files.push({ src: abs, base, owner: name, source, layer, destBase: base });\n }\n }\n // Pass B — tests (look up their subject's layer)\n for (const name of closure) {\n const dir = sourceOf(name);\n for (const abs of componentFiles(dir)) {\n const base = path.basename(abs);\n if (!/\\.test\\.tsx?$/.test(base)) continue;\n const source = fs.readFileSync(abs, \"utf8\");\n const subjectBase = base.replace(/\\.test(\\.tsx?)$/, \"$1\");\n const subjectAlt = base.replace(/\\.test\\.tsx?$/, \".tsx\");\n const subject = files.find((f) => f.owner === name && (f.base === subjectBase || f.base === subjectAlt));\n const layer = layerOverride ?? detectLayer(abs, source, subject?.layer);\n files.push({ src: abs, base, owner: name, source, layer, destBase: base });\n }\n }\n\n const primaryLayer = new Map<string, VizLayer>();\n for (const f of files) {\n if (/\\.test\\.tsx?$/.test(f.base)) continue;\n if (!primaryLayer.has(f.owner)) primaryLayer.set(f.owner, f.layer);\n }\n\n return { files, primaryLayer };\n}\n\nasync function injectVizPro(args: {\n seeds: ResolvedSeed[];\n closure: Set<string>;\n componentsDir: string;\n sourceOverride: string | undefined;\n vizProRoot: string;\n dryRun: boolean;\n force: boolean;\n layerOverride: VizLayer | undefined;\n}): Promise<void> {\n const { closure, vizProRoot, dryRun, force } = args;\n const { files, primaryLayer } = classifyVizFiles(args);\n const layerOf = (name: string): VizLayer | undefined => primaryLayer.get(name);\n\n for (const f of files) {\n const dest = path.join(vizProRoot, \"src\", f.layer, f.destBase);\n if (fs.existsSync(dest) && !force) {\n console.log(\n yellow(\n ` ! packages/viz-pro/src/${f.layer}/${f.destBase} already exists — pass --force to overwrite.`,\n ),\n );\n }\n }\n\n for (const f of files) {\n const destDir = path.join(vizProRoot, \"src\", f.layer);\n const dest = path.join(destDir, f.destBase);\n if (fs.existsSync(dest) && !force) continue;\n if (!dryRun) {\n fs.mkdirSync(destDir, { recursive: true });\n const rewritten = rewriteVizImports(f.source, closure, layerOf, f.layer);\n fs.writeFileSync(dest, rewritten);\n }\n console.log(green(` + packages/viz-pro/src/${f.layer}/${f.destBase}`));\n }\n\n // Phase 5 — patch the layer barrels.\n const barrelNames = new Set<string>();\n for (const f of files) {\n if (/\\.test\\.tsx?$/.test(f.base)) continue;\n const stem = f.destBase.replace(/\\.tsx?$/, \"\");\n const key = `${f.layer}:${stem}`;\n if (barrelNames.has(key)) continue;\n barrelNames.add(key);\n for (const line of patchVizProBarrel(vizProRoot, f.layer, stem, dryRun)) {\n console.log(line.startsWith(\"!\") ? yellow(line) : dim(line));\n }\n }\n\n console.log(\n dim(\n \" hint: if you want named re-exports from the package root, edit packages/viz-pro/src/index.ts by hand.\",\n ),\n );\n}\n\n// ─── viz-pro collection (collect mode) ───────────────────────────────────────\n\nfunction collectVizPro(args: {\n seeds: ResolvedSeed[];\n closure: Set<string>;\n componentsDir: string;\n sourceOverride: string | undefined;\n layerOverride: VizLayer | undefined;\n}): { files: InjectFile[]; patches: InjectPatch[]; warnings: string[] } {\n const { closure } = args;\n const { files: classified, primaryLayer } = classifyVizFiles(args);\n const layerOf = (name: string): VizLayer | undefined => primaryLayer.get(name);\n\n const files: InjectFile[] = [];\n const warnings: string[] = [];\n\n for (const f of classified) {\n const rel = path.posix.join(\"src\", f.layer, f.destBase);\n const contents = rewriteVizImports(f.source, closure, layerOf, f.layer);\n files.push({ path: rel, contents });\n }\n\n const patches: InjectPatch[] = [];\n const barrelKeys = new Set<string>();\n for (const f of classified) {\n if (/\\.test\\.tsx?$/.test(f.base)) continue;\n const stem = f.destBase.replace(/\\.tsx?$/, \"\");\n const key = `${f.layer}:${stem}`;\n if (barrelKeys.has(key)) continue;\n barrelKeys.add(key);\n patches.push({\n file: `src/${f.layer}/index.ts`,\n kind: \"barrel-append\",\n line: `export * from './${stem}';`,\n });\n }\n\n return { files, patches, warnings };\n}\n\n/** Run a rewriter over every .ts/.tsx file under a directory tree. */\nfunction rewriteTree(dir: string, rewrite: (text: string) => string): void {\n for (const e of fs.readdirSync(dir, { withFileTypes: true })) {\n const p = path.join(dir, e.name);\n if (e.isDirectory()) rewriteTree(p, rewrite);\n else if (/\\.(ts|tsx)$/.test(e.name)) {\n const before = fs.readFileSync(p, \"utf8\");\n const after = rewrite(before);\n if (after !== before) fs.writeFileSync(p, after);\n }\n }\n}\n\n// Re-export pure classifiers + helpers so callers can pick them up from one place.\nexport { detectTarget, detectLayer };\nexport type { Target, VizLayer, SeedFile };\n","import colors from \"picocolors\";\n\nconst { cyan, bold } = colors;\n\nexport const INJECT_HELP = `\\\nUsage: bjs inject [OPTION]... NAME...\n\nSubmit a component or system from your project's ${cyan(\"src/components/<Name>/\")} to\nBabylonJS Market for curator review (reverse of ${cyan(\"arcade eject\")}).\n\nWith no ${bold(\"--target\")}, the tool auto-detects per seed:\n * any file extending ${cyan(\"PanelDebuggerSystem\")} / ${cyan(\"StateStepperSystem\")} or\n importing from ${cyan(\"@babylonjsmarket/viz-pro\")} → ${cyan(\"viz-pro\")},\n * otherwise → ${cyan(\"arcade-pro\")}.\n\nMulti-seed inputs must all detect to the same target.\n\nOptions:\n --target <arcade-pro|viz-pro> skip auto-detection\n --source <path> override <cwd>/src/components/<Name>/\n --layer <core|solid|ecs> viz-pro only; skip per-file layer detection\n --force allow overwriting an existing target\n --dry-run print the plan, write nothing, do not submit\n -h, --help print this help message\n\nExamples:\n bjs inject Foo # auto-detect target\n bjs inject Foo Bar --dry-run # multi-name, preview\n bjs inject MyPanelDebugger --target viz-pro\n bjs inject Foo --source ./packages/demo/src/components/Foo\n`;\n","/**\n * Pure classifiers for the inject engine.\n *\n * `detectTarget` decides whether a seed of project files belongs in\n * `@babylonjsmarket/arcade-pro` (per-component, registered) or\n * `@babylonjsmarket/viz-pro` (flat per-layer barrels).\n *\n * `detectLayer` decides which viz-pro layer (`core`, `solid`, `ecs`) owns a\n * single source file. Order matters: rules are evaluated top-down and the\n * first match wins. The order mirrors the plan.\n */\n\nexport type Target = \"arcade-pro\" | \"viz-pro\";\nexport type VizLayer = \"core\" | \"solid\" | \"ecs\";\n\nexport interface SeedFile {\n path: string;\n source: string;\n}\n\n/**\n * Classify a closure of seed files to one of the two pro packages. Any single\n * file extending a viz-pro System class or importing from `@babylonjsmarket/viz-pro`\n * tips the whole seed to `viz-pro`.\n */\nexport function detectTarget(seedFiles: SeedFile[]): Target {\n for (const { source } of seedFiles) {\n if (/from\\s+['\"]@babylonjsmarket\\/viz-pro['\"]/.test(source)) return \"viz-pro\";\n if (/extends\\s+(PanelDebuggerSystem|StateStepperSystem)\\b/.test(source)) return \"viz-pro\";\n }\n return \"arcade-pro\";\n}\n\n/**\n * Classify a single source file to a viz-pro layer.\n *\n * Order is load-bearing:\n * 1. *.test.ts(x) → route alongside the subject file (re-detect on the\n * subject's source if known, else default 'core').\n * 2. *.tsx that imports from 'solid-js' → 'solid'.\n * 3. extends (PanelDebuggerSystem|StateStepperSystem|System) or filename\n * ends in 'System.ts' → 'ecs'.\n * 4. extends Component and no Solid import → 'ecs'.\n * 5. contains `definePanel(` and no Solid import → 'core'.\n * 6. fallback → 'core'.\n *\n * `subjectLayer` lets the caller pin a test file to its subject's layer; pass\n * `undefined` when the subject isn't co-injected, which falls through to\n * rule (1)'s default.\n */\nexport function detectLayer(\n filePath: string,\n source: string,\n subjectLayer?: VizLayer,\n): VizLayer {\n const base = filePath.split(/[\\\\/]/).pop() ?? filePath;\n\n // (1) test files travel with their subject\n if (/\\.test\\.tsx?$/.test(base)) {\n return subjectLayer ?? \"core\";\n }\n\n const hasSolidImport = /from\\s+['\"]solid-js['\"]/.test(source);\n\n // (2) Solid .tsx\n if (/\\.tsx$/.test(base) && hasSolidImport) return \"solid\";\n\n // (3) System subclasses or *System.ts filenames\n if (/extends\\s+(PanelDebuggerSystem|StateStepperSystem|System)\\b/.test(source)) return \"ecs\";\n if (/System\\.ts$/.test(base)) return \"ecs\";\n\n // (4) Component subclasses (no Solid)\n if (/extends\\s+Component\\b/.test(source) && !hasSolidImport) return \"ecs\";\n\n // (5) definePanel files (no Solid)\n if (/\\bdefinePanel\\s*\\(/.test(source) && !hasSolidImport) return \"core\";\n\n // (6) fallback\n return \"core\";\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nexport interface MonorepoPaths {\n root: string;\n arcadeProRoot: string;\n vizProRoot: string;\n}\n\n/**\n * Walk up from this file (dist/lib/inject/monorepo-root.js or\n * src/lib/inject/monorepo-root.ts) looking for the umbrella `package.json`\n * whose `name === \"babylonjs-market-monorepo\"`. Returns the umbrella root plus\n * the two pro-package roots.\n *\n * Only called from `apply` mode — `collect` mode never touches the local\n * monorepo because it operates against a tmpdir workRoot supplied by the\n * caller.\n *\n * Does NOT validate that the pro-package directories exist — `requireTargetRoot`\n * does that lazily so callers can run --help / classifier-only paths without\n * the submodule being present.\n */\nexport function findMonorepoRoot(): MonorepoPaths {\n const here = path.dirname(fileURLToPath(import.meta.url));\n let dir = here;\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const pkgPath = path.join(dir, \"package.json\");\n if (fs.existsSync(pkgPath)) {\n try {\n const pkg = JSON.parse(fs.readFileSync(pkgPath, \"utf8\")) as { name?: string };\n if (pkg.name === \"babylonjs-market-monorepo\") {\n return {\n root: dir,\n arcadeProRoot: path.join(dir, \"packages\", \"arcade-pro\"),\n vizProRoot: path.join(dir, \"packages\", \"viz-pro\"),\n };\n }\n } catch {\n /* unreadable / non-JSON — keep walking */\n }\n }\n const parent = path.dirname(dir);\n if (parent === dir) {\n throw new Error(\n `Could not locate umbrella repo (no ancestor package.json with name \"babylonjs-market-monorepo\" above ${here}).`,\n );\n }\n dir = parent;\n }\n}\n\n/**\n * Verify the requested target package's submodule directory exists on disk.\n * Throws with a precise message naming the missing path so the operator knows\n * to `git submodule update --init` the relevant repo.\n */\nexport function requireTargetRoot(\n paths: MonorepoPaths,\n target: \"arcade-pro\" | \"viz-pro\",\n): string {\n const root = target === \"arcade-pro\" ? paths.arcadeProRoot : paths.vizProRoot;\n if (!fs.existsSync(root)) {\n throw new Error(\n `packages/${target} is not checked out at ${root}. Run \\`git submodule update --init packages/${target}\\` and retry.`,\n );\n }\n return root;\n}\n"],"mappings":"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","names":["fs","path","colors","cyan","bold","colors","fs","path"]}
1
+ {"version":3,"sources":["../../../src/lib/inject/engine.ts","../../../src/lib/inject/inject-options.ts","../../../src/lib/inject/detect-target.ts","../../../src/lib/inject/monorepo-root.ts"],"sourcesContent":["import fs from \"node:fs\";\nimport path from \"node:path\";\nimport mri from \"mri\";\nimport colors from \"picocolors\";\nimport { INJECT_HELP } from \"./inject-options.js\";\nimport {\n detectTarget,\n detectLayer,\n type Target,\n type VizLayer,\n type SeedFile,\n} from \"./detect-target.js\";\nimport { findMonorepoRoot } from \"./monorepo-root.js\";\n\nconst { cyan, green, yellow, dim, bold } = colors;\n\n// ─── Public collect-mode result shape ────────────────────────────────────────\n\nexport interface InjectPatch {\n /** Path of the file being patched, relative to the target package root. */\n file: string;\n kind: \"registry-append\" | \"barrel-append\";\n /** The line that would be appended/inserted. */\n line: string;\n}\n\nexport interface InjectFile {\n /** Path relative to the target package root (e.g. `src/Components/Foo/Foo.ts`). */\n path: string;\n contents: string;\n}\n\nexport interface InjectCollectResult {\n target: Target;\n files: InjectFile[];\n patches: InjectPatch[];\n warnings: string[];\n}\n\n// ─── Filesystem helpers (mirrors eject.ts) ────────────────────────────────────\n\n/** Every .ts/.tsx file inside a project component folder. */\nfunction componentFiles(dir: string): string[] {\n const out: string[] = [];\n const walk = (d: string) => {\n for (const e of fs.readdirSync(d, { withFileTypes: true })) {\n const p = path.join(d, e.name);\n if (e.isDirectory()) walk(p);\n else if (/\\.(ts|tsx)$/.test(e.name)) out.push(p);\n }\n };\n if (fs.existsSync(dir)) walk(dir);\n return out;\n}\n\n/** Every file (including non-ts assets like meta.json) inside a component folder. */\nfunction allComponentFiles(dir: string): string[] {\n const out: string[] = [];\n const walk = (d: string) => {\n for (const e of fs.readdirSync(d, { withFileTypes: true })) {\n const p = path.join(d, e.name);\n if (e.isDirectory()) walk(p);\n else out.push(p);\n }\n };\n if (fs.existsSync(dir)) walk(dir);\n return out;\n}\n\n/** All top-level project component names = `<project>/src/components/*` (minus `_shared`). */\nfunction projectComponentNames(projectDir: string): string[] {\n const dir = path.join(projectDir, \"src\", \"components\");\n if (!fs.existsSync(dir)) return [];\n return fs\n .readdirSync(dir, { withFileTypes: true })\n .filter((e) => e.isDirectory() && e.name !== \"_shared\")\n .map((e) => e.name);\n}\n\n/** Component names a given seed imports via `../Sibling/`, `~/components/Sibling/`, or its meta.json deps. */\nfunction directDeps(\n name: string,\n componentsDir: string,\n allNames: Set<string>,\n): Set<string> {\n const deps = new Set<string>();\n const metaPath = path.join(componentsDir, name, \"meta.json\");\n if (fs.existsSync(metaPath)) {\n try {\n const meta = JSON.parse(fs.readFileSync(metaPath, \"utf8\")) as { dependencies?: string[] };\n for (const d of meta.dependencies ?? []) if (allNames.has(d)) deps.add(d);\n } catch {\n /* tolerate malformed meta.json — import scan is the safety net */\n }\n }\n const relRe = /['\"]\\.\\.\\/([A-Z][A-Za-z0-9_]*)\\//g;\n const aliasRe = /['\"]~\\/components\\/([A-Z][A-Za-z0-9_]*)\\//g;\n for (const file of componentFiles(path.join(componentsDir, name))) {\n const src = fs.readFileSync(file, \"utf8\");\n let m: RegExpExecArray | null;\n while ((m = relRe.exec(src))) if (allNames.has(m[1])) deps.add(m[1]);\n while ((m = aliasRe.exec(src))) if (allNames.has(m[1])) deps.add(m[1]);\n }\n return deps;\n}\n\n/** Expand a seed set to its transitive sibling closure. */\nfunction resolveClosure(\n seed: Set<string>,\n componentsDir: string,\n allNames: string[],\n): Set<string> {\n const all = new Set(allNames);\n const out = new Set(seed);\n const queue = [...seed];\n while (queue.length) {\n const next = queue.pop()!;\n for (const dep of directDeps(next, componentsDir, all)) {\n if (!out.has(dep)) {\n out.add(dep);\n queue.push(dep);\n }\n }\n }\n return out;\n}\n\n/**\n * Reverse of eject's rewriteImports:\n *\n * `'@babylonjsmarket/arcade/<Sibling>'` → `'../<Sibling>/<Sibling>'`\n * `'@babylonjsmarket/arcade-pro/<Sibling>'` → `'../<Sibling>/<Sibling>'`\n *\n * …but only when <Sibling> is co-injected for the same target package. Other\n * package subpaths (including ecs / babylon / solid-js / etc.) are left alone.\n *\n * For arcade-pro, components share a parent (`src/Components/`), so the\n * relative path is always `../<Sibling>/<Sibling>`. For viz-pro the caller\n * supplies a `layerMap` and the originating file's layer; the relative path\n * resolves through the per-file layer routing.\n */\nfunction rewriteArcadeImports(src: string, injected: Set<string>): string {\n return src.replace(\n /(['\"])@babylonjsmarket\\/(?:arcade|arcade-pro)\\/([A-Z][A-Za-z0-9_]*)\\1/g,\n (whole, quote, sibling) => {\n if (injected.has(sibling)) {\n return `${quote}../${sibling}/${sibling}${quote}`;\n }\n return whole;\n },\n );\n}\n\n/**\n * viz variant. Rewrites `@babylonjsmarket/viz/<Sibling>` (the canonical name),\n * the legacy `@babylonjsmarket/viz-pro/<Sibling>`, or\n * `@babylonjsmarket/arcade/<Sibling>` referencing a viz sibling) to the\n * correct flat-layer relative path: `../<targetLayer>/<Sibling>`. Same-layer\n * siblings collapse to `./<Sibling>`. Both `viz` and `viz-pro` prefixes are\n * matched so seeds ejected against either package name still rewrite.\n */\nfunction rewriteVizImports(\n src: string,\n injected: Set<string>,\n layerOf: (name: string) => VizLayer | undefined,\n fromLayer: VizLayer,\n): string {\n return src.replace(\n /(['\"])@babylonjsmarket\\/(?:viz-pro|viz|arcade|arcade-pro)\\/([A-Z][A-Za-z0-9_]*)\\1/g,\n (whole, quote, sibling) => {\n if (!injected.has(sibling)) return whole;\n const dest = layerOf(sibling);\n if (!dest) return whole;\n const rel = dest === fromLayer ? `./${sibling}` : `../${dest}/${sibling}`;\n return `${quote}${rel}${quote}`;\n },\n );\n}\n\n// ─── Registry / barrel patchers ───────────────────────────────────────────────\n\n/**\n * Append lazy resolver lines into ARCADE_PRO_COMPONENT_REGISTRY. Pure decision\n * step: returns what to add without touching disk.\n *\n * `existingRegistry` is the current registry.ts contents, or `undefined` when\n * the file isn't present (apply mode missing the marker emits a warning; in\n * collect mode we always assume the marker is present).\n */\nfunction planArcadeProRegistry(\n existingRegistry: string | undefined,\n names: string[],\n registryRelPath = \"src/registry.ts\",\n): { lines: string[]; added: string[]; warnings: string[]; markerFound: boolean } {\n const warnings: string[] = [];\n if (existingRegistry === undefined) {\n warnings.push(\n `! packages/arcade/${registryRelPath} not found — add resolvers manually for: ${names.join(\", \")}`,\n );\n return { lines: [], added: [], warnings, markerFound: false };\n }\n const marker = /ARCADE_PRO_COMPONENT_REGISTRY:\\s*Record<string,\\s*LazyComponentResolver>\\s*=\\s*\\{/;\n if (!marker.test(existingRegistry)) {\n warnings.push(\n `! Could not find 'ARCADE_PRO_COMPONENT_REGISTRY' marker — add resolvers manually for: ${names.join(\", \")}`,\n );\n return { lines: [], added: [], warnings, markerFound: false };\n }\n const added: string[] = [];\n const lines: string[] = [];\n for (const name of names) {\n if (existingRegistry.includes(`./Components/${name}/${name}`)) continue; // already wired\n lines.push(` ${name}: () => import('./Components/${name}/${name}'),`);\n added.push(name);\n }\n return { lines, added, warnings, markerFound: true };\n}\n\n/** Append a lazy resolver line into ARCADE_PRO_COMPONENT_REGISTRY (idempotent, on-disk). */\nfunction patchArcadeProRegistry(\n arcadeProRoot: string,\n names: string[],\n dryRun: boolean,\n): string[] {\n const registryPath = path.join(arcadeProRoot, \"src\", \"registry.ts\");\n const existing = fs.existsSync(registryPath) ? fs.readFileSync(registryPath, \"utf8\") : undefined;\n const plan = planArcadeProRegistry(existing, names);\n if (plan.warnings.length) return plan.warnings;\n if (plan.added.length && !dryRun) {\n const marker = /ARCADE_PRO_COMPONENT_REGISTRY:\\s*Record<string,\\s*LazyComponentResolver>\\s*=\\s*\\{/;\n const next = (existing as string).replace(marker, (m) => `${m}\\n${plan.lines.join(\"\\n\")}`);\n fs.writeFileSync(registryPath, next);\n }\n return plan.added.map((n) => ` patched registry: ${n}`);\n}\n\n/**\n * Pure planner for the viz-pro layer barrel: returns the line to append if any.\n */\nfunction planVizProBarrel(\n existingBarrel: string | undefined,\n layer: VizLayer,\n fileName: string,\n): { line: string | null; warnings: string[] } {\n if (existingBarrel === undefined) {\n return {\n line: null,\n warnings: [\n `! packages/viz-pro/src/${layer}/index.ts not found — add the barrel re-export manually for ${fileName}`,\n ],\n };\n }\n const needle = `from './${fileName}'`;\n if (existingBarrel.includes(needle)) return { line: null, warnings: [] };\n return { line: `export * from './${fileName}';`, warnings: [] };\n}\n\n/** Append `export * from './<FileName>';` to a viz-pro layer barrel (idempotent, on-disk). */\nfunction patchVizProBarrel(\n vizProRoot: string,\n layer: VizLayer,\n fileName: string,\n dryRun: boolean,\n): string[] {\n const barrelPath = path.join(vizProRoot, \"src\", layer, \"index.ts\");\n const existing = fs.existsSync(barrelPath) ? fs.readFileSync(barrelPath, \"utf8\") : undefined;\n const plan = planVizProBarrel(existing, layer, fileName);\n if (plan.warnings.length) return plan.warnings;\n if (plan.line === null) return [];\n if (!dryRun) {\n const next = existing!.endsWith(\"\\n\")\n ? existing + plan.line + \"\\n\"\n : existing + \"\\n\" + plan.line + \"\\n\";\n fs.writeFileSync(barrelPath, next);\n }\n return [` patched ${layer}/index.ts: ${fileName}`];\n}\n\n/**\n * Strip a lazy-resolver line of the form\n * ` Foo: () => import('./components/Foo/Foo'),`\n * from `<project>/src/registry.ts`. Returns the list of names actually removed.\n */\nfunction stripProjectRegistry(\n projectDir: string,\n names: string[],\n dryRun: boolean,\n): string[] {\n const registryPath = path.join(projectDir, \"src\", \"registry.ts\");\n if (!fs.existsSync(registryPath)) return [];\n let text = fs.readFileSync(registryPath, \"utf8\");\n const removed: string[] = [];\n for (const name of names) {\n const re = new RegExp(\n `^\\\\s*${name}\\\\s*:\\\\s*\\\\(\\\\)\\\\s*=>\\\\s*import\\\\(\\\\s*['\"]\\\\.\\\\/components\\\\/${name}\\\\/${name}['\"]\\\\s*\\\\)\\\\s*,?\\\\s*\\\\r?\\\\n`,\n \"m\",\n );\n if (re.test(text)) {\n text = text.replace(re, \"\");\n removed.push(name);\n }\n }\n if (removed.length && !dryRun) fs.writeFileSync(registryPath, text);\n return removed;\n}\n\n// ─── Plan + main entry ────────────────────────────────────────────────────────\n\ninterface ResolvedSeed {\n /** Name as the operator typed it (and as it lives under `src/components/`). */\n name: string;\n /** Absolute path to the seed's source directory (post `--source` override). */\n sourceDir: string;\n}\n\nexport interface InjectOptions {\n /**\n * What the engine does with the resolved file list:\n * - 'apply' → writes into the resolved packageRoot/vizProRoot (operator mode).\n * - 'collect' → returns the file map + patch plan without touching disk\n * (member mode; payload goes to the marketplace endpoint).\n */\n mode?: \"apply\" | \"collect\";\n /** Tmpdir-friendly: the arcade-pro package root (the dir containing `src/registry.ts`). Apply mode only. */\n packageRoot?: string;\n /** Tmpdir-friendly: the viz-pro package root (the dir containing `src/{core,solid,ecs}/index.ts`). Apply mode only. */\n vizProRoot?: string;\n /** The project we're injecting FROM. Defaults to `cwd`. */\n projectDir?: string;\n /** Override for `process.cwd()`. Tests use this; the CLI entry passes `process.cwd()`. */\n cwd?: string;\n}\n\nexport async function inject(\n args: string[],\n opts: InjectOptions = {},\n): Promise<InjectCollectResult | void> {\n if (args.includes(\"-h\") || args.includes(\"--help\")) {\n console.log(INJECT_HELP);\n return;\n }\n\n const argv = mri(args, {\n boolean: [\"dry-run\", \"move\", \"confirm\", \"force\"],\n string: [\"target\", \"source\", \"layer\"],\n });\n\n const mode: \"apply\" | \"collect\" = opts.mode ?? \"apply\";\n const dryRun = Boolean(argv[\"dry-run\"]);\n const move = Boolean(argv.move);\n const confirm = Boolean(argv.confirm);\n const force = Boolean(argv.force);\n // Normalize the legacy package-name target aliases to the canonical target\n // names early, so existing user scripts passing `--target arcade-pro` or\n // `--target viz-pro` keep working:\n // arcade-pro → arcade (mirrors the original arcade alias)\n // viz-pro → viz\n const rawTarget = argv.target as string | undefined;\n const explicitTarget = (\n rawTarget === \"arcade-pro\" ? \"arcade\" : rawTarget === \"viz-pro\" ? \"viz\" : rawTarget\n ) as Target | undefined;\n const sourceOverride = argv.source as string | undefined;\n const layerOverride = argv.layer as VizLayer | undefined;\n const names = argv._.map(String);\n\n const cwd = opts.cwd ?? process.cwd();\n const projectDir = opts.projectDir ?? cwd;\n\n // ─── Arg validation ───\n if (names.length === 0) {\n console.error(yellow(\"No component names given. Pass at least one, e.g. `bjs inject Foo`.\"));\n process.exit(1);\n return;\n }\n // --move / --confirm are operator-only knobs. In collect mode they're\n // meaningless (no project to mutate); flag and bail.\n if (mode === \"collect\" && (move || confirm)) {\n console.error(yellow(\"--move and --confirm are not available in member submission mode.\"));\n process.exit(1);\n return;\n }\n if (move && !confirm) {\n console.error(yellow(\"--move requires --confirm (it deletes project files). Pass --move --confirm.\"));\n process.exit(1);\n return;\n }\n if (move && dryRun) {\n console.error(yellow(\"--move and --dry-run are mutually exclusive. Drop one.\"));\n process.exit(1);\n return;\n }\n if (explicitTarget && explicitTarget !== \"arcade\" && explicitTarget !== \"viz\") {\n console.error(yellow(`Unknown --target ${rawTarget}. Use arcade or viz.`));\n process.exit(1);\n return;\n }\n if (layerOverride && layerOverride !== \"core\" && layerOverride !== \"solid\" && layerOverride !== \"ecs\") {\n console.error(yellow(`Unknown --layer ${layerOverride}. Use core, solid, or ecs.`));\n process.exit(1);\n return;\n }\n if (sourceOverride && names.length > 1) {\n console.error(yellow(\"--source applies to a single seed; pass one NAME with --source.\"));\n process.exit(1);\n return;\n }\n\n // ─── Phase 0: resolve roots (apply mode only) ───\n let packageRoot = opts.packageRoot;\n let vizProRoot = opts.vizProRoot;\n if (mode === \"apply\" && (!packageRoot || !vizProRoot)) {\n try {\n const monorepo = findMonorepoRoot();\n packageRoot ??= monorepo.arcadeProRoot;\n vizProRoot ??= monorepo.vizProRoot;\n } catch (e) {\n console.error(yellow((e as Error).message));\n process.exit(1);\n return;\n }\n }\n\n // ─── Phase 1: locate seeds + walk closure ───\n const componentsDir = path.join(projectDir, \"src\", \"components\");\n const allProjectNames = projectComponentNames(projectDir);\n\n const seeds: ResolvedSeed[] = [];\n for (const name of names) {\n const sourceDir = sourceOverride\n ? path.resolve(cwd, sourceOverride)\n : path.join(componentsDir, name);\n if (!fs.existsSync(sourceDir)) {\n console.error(\n yellow(\n `Could not find source for \"${name}\". Looked at ${sourceDir}. ` +\n `Use --source <path> to point at the seed explicitly.`,\n ),\n );\n process.exit(1);\n return;\n }\n seeds.push({ name, sourceDir });\n }\n\n // Run the closure walk in the project's components dir (only when seeds live\n // under <project>/src/components/, which is the default and the case we can\n // reason about transitively). With --source we still inject the seed itself\n // but skip the transitive walk — caller is in unusual territory.\n const seedNames = new Set(seeds.map((s) => s.name));\n const closure: Set<string> = sourceOverride\n ? seedNames\n : resolveClosure(seedNames, componentsDir, allProjectNames);\n\n // ─── Phase 2: target detection ───\n const closureFiles: SeedFile[] = [];\n for (const name of closure) {\n const dir = sourceOverride && seedNames.has(name)\n ? seeds.find((s) => s.name === name)!.sourceDir\n : path.join(componentsDir, name);\n for (const f of componentFiles(dir)) {\n closureFiles.push({ path: f, source: fs.readFileSync(f, \"utf8\") });\n }\n }\n\n const target: Target = explicitTarget ?? detectTarget(closureFiles);\n\n // For multi-seed inputs, every seed individually must agree with `target`.\n if (!explicitTarget && seeds.length > 1) {\n for (const seed of seeds) {\n const dir = seed.sourceDir;\n const files: SeedFile[] = componentFiles(dir).map((f) => ({\n path: f,\n source: fs.readFileSync(f, \"utf8\"),\n }));\n const perSeed = detectTarget(files);\n if (perSeed !== target) {\n console.error(\n yellow(\n `Auto-detect disagrees across seeds: \"${seed.name}\" → ${perSeed}, ` +\n `others → ${target}. Pass --target explicitly or split into separate runs.`,\n ),\n );\n process.exit(1);\n return;\n }\n }\n }\n\n // ─── Apply-mode root checks ───\n let chosenRoot: string | undefined;\n if (mode === \"apply\") {\n try {\n if (target === \"arcade\") {\n if (!fs.existsSync(packageRoot!)) {\n throw new Error(\n `packages/arcade is not checked out at ${packageRoot}. Run \\`git submodule update --init packages/arcade\\` and retry.`,\n );\n }\n chosenRoot = packageRoot!;\n } else {\n if (!fs.existsSync(vizProRoot!)) {\n throw new Error(\n `packages/viz-pro is not checked out at ${vizProRoot}. Run \\`git submodule update --init packages/viz-pro\\` and retry.`,\n );\n }\n chosenRoot = vizProRoot!;\n }\n } catch (e) {\n console.error(yellow((e as Error).message));\n process.exit(1);\n return;\n }\n }\n\n // ─── Plan logging header ───\n console.log(\n bold(dryRun ? \"\\nInject plan (dry run — nothing written):\" : \"\\nInjecting:\"),\n );\n console.log(` target: ${cyan(target)}`);\n console.log(` components: ${cyan([...closure].sort().join(\", \"))}`);\n\n // ─── Phase 3: copy files ───\n if (mode === \"collect\") {\n const result =\n target === \"arcade\"\n ? collectArcadePro({ seeds, closure, componentsDir, sourceOverride })\n : collectVizPro({ seeds, closure, componentsDir, sourceOverride, layerOverride });\n for (const f of result.files) console.log(green(` + packages/${target}/${f.path}`));\n for (const w of result.warnings) console.log(yellow(w));\n console.log(\n dryRun\n ? dim(\"\\nRe-run without --dry-run to submit.\\n\")\n : dim(\"\\nCollect-mode plan ready (no submission performed by the library).\\n\"),\n );\n return { ...result, target };\n }\n\n // mode === 'apply'\n if (target === \"arcade\") {\n await injectArcadePro({\n seeds,\n closure,\n componentsDir,\n sourceOverride,\n arcadeProRoot: chosenRoot!,\n dryRun,\n force,\n });\n } else {\n await injectVizPro({\n seeds,\n closure,\n componentsDir,\n sourceOverride,\n vizProRoot: chosenRoot!,\n dryRun,\n force,\n layerOverride,\n });\n }\n\n // ─── Phase 6 (optional): source cleanup ───\n if (move) {\n if (sourceOverride) {\n console.log(\n yellow(\n \" ! --move with --source: only the source dir is removed; cannot reliably patch a foreign project's registry.\",\n ),\n );\n }\n for (const seed of seeds) {\n if (fs.existsSync(seed.sourceDir)) {\n if (!dryRun) fs.rmSync(seed.sourceDir, { recursive: true, force: true });\n console.log(dim(` - ${path.relative(projectDir, seed.sourceDir)}/ (project copy removed)`));\n }\n }\n const removed = stripProjectRegistry(\n projectDir,\n seeds.map((s) => s.name),\n dryRun,\n );\n for (const name of removed) {\n console.log(dim(` - project registry entry: ${name}`));\n }\n }\n\n console.log(\n dryRun\n ? dim(\"\\nRe-run without --dry-run to apply.\\n\")\n : green(`\\nDone. Components landed in packages/${target}/.\\n`),\n );\n}\n\n// ─── arcade-pro injection (apply mode) ───────────────────────────────────────\n\nasync function injectArcadePro(args: {\n seeds: ResolvedSeed[];\n closure: Set<string>;\n componentsDir: string;\n sourceOverride: string | undefined;\n arcadeProRoot: string;\n dryRun: boolean;\n force: boolean;\n}): Promise<void> {\n const { seeds, closure, componentsDir, sourceOverride, arcadeProRoot, dryRun, force } = args;\n const destComponents = path.join(arcadeProRoot, \"src\", \"Components\");\n if (!dryRun) fs.mkdirSync(destComponents, { recursive: true });\n\n const sourceOf = (name: string): string => {\n const seed = seeds.find((s) => s.name === name);\n return seed && sourceOverride ? seed.sourceDir : path.join(componentsDir, name);\n };\n\n for (const name of [...closure].sort()) {\n const src = sourceOf(name);\n const dest = path.join(destComponents, name);\n if (fs.existsSync(dest) && !force) {\n console.log(\n yellow(` ! packages/arcade/src/Components/${name}/ already exists — pass --force to overwrite.`),\n );\n continue;\n }\n if (!dryRun) {\n if (fs.existsSync(dest)) fs.rmSync(dest, { recursive: true, force: true });\n fs.cpSync(src, dest, { recursive: true });\n }\n console.log(green(` + packages/arcade/src/Components/${name}/`));\n }\n\n // Phase 4: import rewriting across each copied folder.\n if (!dryRun) {\n for (const name of closure) {\n const dest = path.join(destComponents, name);\n if (!fs.existsSync(dest)) continue;\n rewriteTree(dest, (text) => rewriteArcadeImports(text, closure));\n }\n }\n\n // Phase 5: arcade-pro registry patch.\n for (const line of patchArcadeProRegistry(\n arcadeProRoot,\n [...closure].sort(),\n dryRun,\n )) {\n console.log(line.startsWith(\"!\") ? yellow(line) : dim(line));\n }\n}\n\n// ─── arcade-pro collection (collect mode) ────────────────────────────────────\n\nfunction collectArcadePro(args: {\n seeds: ResolvedSeed[];\n closure: Set<string>;\n componentsDir: string;\n sourceOverride: string | undefined;\n}): { files: InjectFile[]; patches: InjectPatch[]; warnings: string[] } {\n const { seeds, closure, componentsDir, sourceOverride } = args;\n const sourceOf = (name: string): string => {\n const seed = seeds.find((s) => s.name === name);\n return seed && sourceOverride ? seed.sourceDir : path.join(componentsDir, name);\n };\n\n const files: InjectFile[] = [];\n const warnings: string[] = [];\n\n for (const name of [...closure].sort()) {\n const src = sourceOf(name);\n if (!fs.existsSync(src)) {\n warnings.push(` ! source for ${name} missing at ${src}`);\n continue;\n }\n for (const abs of allComponentFiles(src)) {\n const rel = path.relative(src, abs);\n const baseRel = path.posix.join(\"src\", \"Components\", name, rel.split(path.sep).join(\"/\"));\n const isText = /\\.(ts|tsx)$/i.test(abs);\n const raw = fs.readFileSync(abs, \"utf8\");\n const contents = isText ? rewriteArcadeImports(raw, closure) : raw;\n files.push({ path: baseRel, contents });\n }\n }\n\n // Plan the registry patch — but submit the *desired* added lines, not the\n // raw existing+new file. The server applies the patch against whatever the\n // pro package looks like at merge time.\n const patches: InjectPatch[] = [];\n for (const name of [...closure].sort()) {\n patches.push({\n file: \"src/registry.ts\",\n kind: \"registry-append\",\n line: ` ${name}: () => import('./Components/${name}/${name}'),`,\n });\n }\n\n return { files, patches, warnings };\n}\n\n// ─── viz-pro injection (apply mode) ──────────────────────────────────────────\n\ninterface ViewFile {\n src: string;\n base: string;\n owner: string;\n source: string;\n layer: VizLayer;\n destBase: string;\n}\n\nfunction classifyVizFiles(args: {\n seeds: ResolvedSeed[];\n closure: Set<string>;\n componentsDir: string;\n sourceOverride: string | undefined;\n layerOverride: VizLayer | undefined;\n}): { files: ViewFile[]; primaryLayer: Map<string, VizLayer> } {\n const { seeds, closure, componentsDir, sourceOverride, layerOverride } = args;\n\n const sourceOf = (name: string): string => {\n const seed = seeds.find((s) => s.name === name);\n return seed && sourceOverride ? seed.sourceDir : path.join(componentsDir, name);\n };\n\n const files: ViewFile[] = [];\n\n // Pass A — non-tests\n for (const name of closure) {\n const dir = sourceOf(name);\n for (const abs of componentFiles(dir)) {\n const base = path.basename(abs);\n if (/\\.test\\.tsx?$/.test(base)) continue;\n const source = fs.readFileSync(abs, \"utf8\");\n const layer = layerOverride ?? detectLayer(abs, source);\n files.push({ src: abs, base, owner: name, source, layer, destBase: base });\n }\n }\n // Pass B — tests (look up their subject's layer)\n for (const name of closure) {\n const dir = sourceOf(name);\n for (const abs of componentFiles(dir)) {\n const base = path.basename(abs);\n if (!/\\.test\\.tsx?$/.test(base)) continue;\n const source = fs.readFileSync(abs, \"utf8\");\n const subjectBase = base.replace(/\\.test(\\.tsx?)$/, \"$1\");\n const subjectAlt = base.replace(/\\.test\\.tsx?$/, \".tsx\");\n const subject = files.find((f) => f.owner === name && (f.base === subjectBase || f.base === subjectAlt));\n const layer = layerOverride ?? detectLayer(abs, source, subject?.layer);\n files.push({ src: abs, base, owner: name, source, layer, destBase: base });\n }\n }\n\n const primaryLayer = new Map<string, VizLayer>();\n for (const f of files) {\n if (/\\.test\\.tsx?$/.test(f.base)) continue;\n if (!primaryLayer.has(f.owner)) primaryLayer.set(f.owner, f.layer);\n }\n\n return { files, primaryLayer };\n}\n\nasync function injectVizPro(args: {\n seeds: ResolvedSeed[];\n closure: Set<string>;\n componentsDir: string;\n sourceOverride: string | undefined;\n vizProRoot: string;\n dryRun: boolean;\n force: boolean;\n layerOverride: VizLayer | undefined;\n}): Promise<void> {\n const { closure, vizProRoot, dryRun, force } = args;\n const { files, primaryLayer } = classifyVizFiles(args);\n const layerOf = (name: string): VizLayer | undefined => primaryLayer.get(name);\n\n for (const f of files) {\n const dest = path.join(vizProRoot, \"src\", f.layer, f.destBase);\n if (fs.existsSync(dest) && !force) {\n console.log(\n yellow(\n ` ! packages/viz-pro/src/${f.layer}/${f.destBase} already exists — pass --force to overwrite.`,\n ),\n );\n }\n }\n\n for (const f of files) {\n const destDir = path.join(vizProRoot, \"src\", f.layer);\n const dest = path.join(destDir, f.destBase);\n if (fs.existsSync(dest) && !force) continue;\n if (!dryRun) {\n fs.mkdirSync(destDir, { recursive: true });\n const rewritten = rewriteVizImports(f.source, closure, layerOf, f.layer);\n fs.writeFileSync(dest, rewritten);\n }\n console.log(green(` + packages/viz-pro/src/${f.layer}/${f.destBase}`));\n }\n\n // Phase 5 — patch the layer barrels.\n const barrelNames = new Set<string>();\n for (const f of files) {\n if (/\\.test\\.tsx?$/.test(f.base)) continue;\n const stem = f.destBase.replace(/\\.tsx?$/, \"\");\n const key = `${f.layer}:${stem}`;\n if (barrelNames.has(key)) continue;\n barrelNames.add(key);\n for (const line of patchVizProBarrel(vizProRoot, f.layer, stem, dryRun)) {\n console.log(line.startsWith(\"!\") ? yellow(line) : dim(line));\n }\n }\n\n console.log(\n dim(\n \" hint: if you want named re-exports from the package root, edit packages/viz-pro/src/index.ts by hand.\",\n ),\n );\n}\n\n// ─── viz-pro collection (collect mode) ───────────────────────────────────────\n\nfunction collectVizPro(args: {\n seeds: ResolvedSeed[];\n closure: Set<string>;\n componentsDir: string;\n sourceOverride: string | undefined;\n layerOverride: VizLayer | undefined;\n}): { files: InjectFile[]; patches: InjectPatch[]; warnings: string[] } {\n const { closure } = args;\n const { files: classified, primaryLayer } = classifyVizFiles(args);\n const layerOf = (name: string): VizLayer | undefined => primaryLayer.get(name);\n\n const files: InjectFile[] = [];\n const warnings: string[] = [];\n\n for (const f of classified) {\n const rel = path.posix.join(\"src\", f.layer, f.destBase);\n const contents = rewriteVizImports(f.source, closure, layerOf, f.layer);\n files.push({ path: rel, contents });\n }\n\n const patches: InjectPatch[] = [];\n const barrelKeys = new Set<string>();\n for (const f of classified) {\n if (/\\.test\\.tsx?$/.test(f.base)) continue;\n const stem = f.destBase.replace(/\\.tsx?$/, \"\");\n const key = `${f.layer}:${stem}`;\n if (barrelKeys.has(key)) continue;\n barrelKeys.add(key);\n patches.push({\n file: `src/${f.layer}/index.ts`,\n kind: \"barrel-append\",\n line: `export * from './${stem}';`,\n });\n }\n\n return { files, patches, warnings };\n}\n\n/** Run a rewriter over every .ts/.tsx file under a directory tree. */\nfunction rewriteTree(dir: string, rewrite: (text: string) => string): void {\n for (const e of fs.readdirSync(dir, { withFileTypes: true })) {\n const p = path.join(dir, e.name);\n if (e.isDirectory()) rewriteTree(p, rewrite);\n else if (/\\.(ts|tsx)$/.test(e.name)) {\n const before = fs.readFileSync(p, \"utf8\");\n const after = rewrite(before);\n if (after !== before) fs.writeFileSync(p, after);\n }\n }\n}\n\n// Re-export pure classifiers + helpers so callers can pick them up from one place.\nexport { detectTarget, detectLayer };\nexport type { Target, VizLayer, SeedFile };\n","import colors from \"picocolors\";\n\nconst { cyan, bold } = colors;\n\nexport const INJECT_HELP = `\\\nUsage: bjs inject [OPTION]... NAME...\n\nSubmit a component or system from your project's ${cyan(\"src/components/<Name>/\")} to\nBabylonJS Market for curator review (reverse of ${cyan(\"arcade eject\")}).\n\nWith no ${bold(\"--target\")}, the tool auto-detects per seed:\n * any file extending ${cyan(\"PanelDebuggerSystem\")} / ${cyan(\"StateStepperSystem\")} or\n importing from ${cyan(\"@babylonjsmarket/viz\")} → ${cyan(\"viz\")},\n * otherwise → ${cyan(\"arcade\")}.\n\nMulti-seed inputs must all detect to the same target.\n\nOptions:\n --target <arcade|viz> skip auto-detection (legacy: arcade-pro, viz-pro)\n --source <path> override <cwd>/src/components/<Name>/\n --layer <core|solid|ecs> viz only; skip per-file layer detection\n --force allow overwriting an existing target\n --dry-run print the plan, write nothing, do not submit\n -h, --help print this help message\n\nExamples:\n bjs inject Foo # auto-detect target\n bjs inject Foo Bar --dry-run # multi-name, preview\n bjs inject MyPanelDebugger --target viz\n bjs inject Foo --source ./packages/demo/src/components/Foo\n`;\n","/**\n * Pure classifiers for the inject engine.\n *\n * `detectTarget` decides whether a seed of project files belongs in\n * `@babylonjsmarket/arcade` (per-component, registered) or the viz package\n * (flat per-layer barrels).\n *\n * `detectLayer` decides which viz layer (`core`, `solid`, `ecs`) owns a\n * single source file. Order matters: rules are evaluated top-down and the\n * first match wins. The order mirrors the plan.\n *\n * Target naming: the canonical user-facing target names are `arcade` and\n * `viz`. The legacy `arcade-pro` / `viz-pro` package names live on only as\n * back-compat aliases (normalized to the canonical names by callers) and as\n * import-prefix patterns we still recognize in existing seeds.\n */\n\nexport type Target = \"arcade\" | \"viz\";\nexport type VizLayer = \"core\" | \"solid\" | \"ecs\";\n\nexport interface SeedFile {\n path: string;\n source: string;\n}\n\n/**\n * Classify a closure of seed files to one of the two packages. Any single\n * file extending a viz System class or importing from `@babylonjsmarket/viz`\n * (or the legacy `@babylonjsmarket/viz-pro`) tips the whole seed to `viz`.\n */\nexport function detectTarget(seedFiles: SeedFile[]): Target {\n for (const { source } of seedFiles) {\n // Recognize BOTH the canonical `@babylonjsmarket/viz` and the legacy\n // `@babylonjsmarket/viz-pro` import prefix — existing seeds were ejected\n // against `viz-pro` and must still classify correctly.\n if (/from\\s+['\"]@babylonjsmarket\\/viz(?:-pro)?['\"]/.test(source)) return \"viz\";\n if (/extends\\s+(PanelDebuggerSystem|StateStepperSystem)\\b/.test(source)) return \"viz\";\n }\n return \"arcade\";\n}\n\n/**\n * Classify a single source file to a viz layer.\n *\n * Order is load-bearing:\n * 1. *.test.ts(x) → route alongside the subject file (re-detect on the\n * subject's source if known, else default 'core').\n * 2. *.tsx that imports from 'solid-js' → 'solid'.\n * 3. extends (PanelDebuggerSystem|StateStepperSystem|System) or filename\n * ends in 'System.ts' → 'ecs'.\n * 4. extends Component and no Solid import → 'ecs'.\n * 5. contains `definePanel(` and no Solid import → 'core'.\n * 6. fallback → 'core'.\n *\n * `subjectLayer` lets the caller pin a test file to its subject's layer; pass\n * `undefined` when the subject isn't co-injected, which falls through to\n * rule (1)'s default.\n */\nexport function detectLayer(\n filePath: string,\n source: string,\n subjectLayer?: VizLayer,\n): VizLayer {\n const base = filePath.split(/[\\\\/]/).pop() ?? filePath;\n\n // (1) test files travel with their subject\n if (/\\.test\\.tsx?$/.test(base)) {\n return subjectLayer ?? \"core\";\n }\n\n const hasSolidImport = /from\\s+['\"]solid-js['\"]/.test(source);\n\n // (2) Solid .tsx\n if (/\\.tsx$/.test(base) && hasSolidImport) return \"solid\";\n\n // (3) System subclasses or *System.ts filenames\n if (/extends\\s+(PanelDebuggerSystem|StateStepperSystem|System)\\b/.test(source)) return \"ecs\";\n if (/System\\.ts$/.test(base)) return \"ecs\";\n\n // (4) Component subclasses (no Solid)\n if (/extends\\s+Component\\b/.test(source) && !hasSolidImport) return \"ecs\";\n\n // (5) definePanel files (no Solid)\n if (/\\bdefinePanel\\s*\\(/.test(source) && !hasSolidImport) return \"core\";\n\n // (6) fallback\n return \"core\";\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nexport interface MonorepoPaths {\n root: string;\n arcadeProRoot: string;\n vizProRoot: string;\n}\n\n/**\n * ⚠️ DEFUNCT DESTINATIONS — apply mode is being retired.\n *\n * The `arcadeProRoot` / `vizProRoot` destinations below point at\n * `packages/arcade-pro` and `packages/viz-pro`, which have been REMOVED from\n * the monorepo. Premium components are now authored directly in the game\n * project's `src/` and delivered per-component via the CLI's `collect` mode\n * (which never touches these paths); apply mode that copies into a local\n * pro-package checkout no longer has a valid target.\n *\n * This operator-only function is kept in place (not ripped out) so the\n * walk-up-to-umbrella logic stays available, but callers should not rely on\n * `arcadeProRoot` / `vizProRoot` resolving to real directories — they won't.\n *\n * Walk up from this file (dist/lib/inject/monorepo-root.js or\n * src/lib/inject/monorepo-root.ts) looking for the umbrella `package.json`\n * whose `name === \"babylonjs-market-monorepo\"`. Returns the umbrella root plus\n * the two (now-defunct) pro-package roots.\n *\n * Only called from `apply` mode — `collect` mode never touches the local\n * monorepo because it operates against a tmpdir workRoot supplied by the\n * caller.\n *\n * Does NOT validate that the pro-package directories exist — `requireTargetRoot`\n * does that lazily so callers can run --help / classifier-only paths without\n * the submodule being present.\n */\nexport function findMonorepoRoot(): MonorepoPaths {\n const here = path.dirname(fileURLToPath(import.meta.url));\n let dir = here;\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const pkgPath = path.join(dir, \"package.json\");\n if (fs.existsSync(pkgPath)) {\n try {\n const pkg = JSON.parse(fs.readFileSync(pkgPath, \"utf8\")) as { name?: string };\n if (pkg.name === \"babylonjs-market-monorepo\") {\n return {\n root: dir,\n arcadeProRoot: path.join(dir, \"packages\", \"arcade-pro\"),\n vizProRoot: path.join(dir, \"packages\", \"viz-pro\"),\n };\n }\n } catch {\n /* unreadable / non-JSON — keep walking */\n }\n }\n const parent = path.dirname(dir);\n if (parent === dir) {\n throw new Error(\n `Could not locate umbrella repo (no ancestor package.json with name \"babylonjs-market-monorepo\" above ${here}).`,\n );\n }\n dir = parent;\n }\n}\n\n/**\n * ⚠️ DEFUNCT — see findMonorepoRoot above. Both `packages/arcade-pro` and\n * `packages/viz-pro` have been removed, so this check can no longer succeed in\n * practice. Retained as operator-only scaffolding while apply mode is retired\n * in favor of authoring premium components in the game project's `src/`.\n *\n * Verify the requested target package's submodule directory exists on disk.\n * Throws with a precise message naming the missing path so the operator knows\n * to `git submodule update --init` the relevant repo.\n *\n * `target` uses the canonical names (`arcade` | `viz`); they map to the legacy\n * `packages/arcade-pro` / `packages/viz-pro` dirs that this defunct path used.\n */\nexport function requireTargetRoot(\n paths: MonorepoPaths,\n target: \"arcade\" | \"viz\",\n): string {\n const root = target === \"arcade\" ? paths.arcadeProRoot : paths.vizProRoot;\n const legacyPkg = target === \"arcade\" ? \"arcade-pro\" : \"viz-pro\";\n if (!fs.existsSync(root)) {\n throw new Error(\n `packages/${legacyPkg} is not checked out at ${root} (and is now defunct). ` +\n `Premium components are authored in the game project's src/ — apply mode is retired.`,\n );\n }\n return root;\n}\n"],"mappings":"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","names":["fs","path","colors","cyan","bold","colors","fs","path"]}
@@ -14,15 +14,15 @@ BabylonJS Market for curator review (reverse of ${cyan("arcade eject")}).
14
14
 
15
15
  With no ${bold("--target")}, the tool auto-detects per seed:
16
16
  * any file extending ${cyan("PanelDebuggerSystem")} / ${cyan("StateStepperSystem")} or
17
- importing from ${cyan("@babylonjsmarket/viz-pro")} \u2192 ${cyan("viz-pro")},
18
- * otherwise \u2192 ${cyan("arcade-pro")}.
17
+ importing from ${cyan("@babylonjsmarket/viz")} \u2192 ${cyan("viz")},
18
+ * otherwise \u2192 ${cyan("arcade")}.
19
19
 
20
20
  Multi-seed inputs must all detect to the same target.
21
21
 
22
22
  Options:
23
- --target <arcade-pro|viz-pro> skip auto-detection
23
+ --target <arcade|viz> skip auto-detection (legacy: arcade-pro, viz-pro)
24
24
  --source <path> override <cwd>/src/components/<Name>/
25
- --layer <core|solid|ecs> viz-pro only; skip per-file layer detection
25
+ --layer <core|solid|ecs> viz only; skip per-file layer detection
26
26
  --force allow overwriting an existing target
27
27
  --dry-run print the plan, write nothing, do not submit
28
28
  -h, --help print this help message
@@ -30,17 +30,17 @@ Options:
30
30
  Examples:
31
31
  bjs inject Foo # auto-detect target
32
32
  bjs inject Foo Bar --dry-run # multi-name, preview
33
- bjs inject MyPanelDebugger --target viz-pro
33
+ bjs inject MyPanelDebugger --target viz
34
34
  bjs inject Foo --source ./packages/demo/src/components/Foo
35
35
  `;
36
36
 
37
37
  // src/lib/inject/detect-target.ts
38
38
  function detectTarget(seedFiles) {
39
39
  for (const { source } of seedFiles) {
40
- if (/from\s+['"]@babylonjsmarket\/viz-pro['"]/.test(source)) return "viz-pro";
41
- if (/extends\s+(PanelDebuggerSystem|StateStepperSystem)\b/.test(source)) return "viz-pro";
40
+ if (/from\s+['"]@babylonjsmarket\/viz(?:-pro)?['"]/.test(source)) return "viz";
41
+ if (/extends\s+(PanelDebuggerSystem|StateStepperSystem)\b/.test(source)) return "viz";
42
42
  }
43
- return "arcade-pro";
43
+ return "arcade";
44
44
  }
45
45
  function detectLayer(filePath, source, subjectLayer) {
46
46
  const base = filePath.split(/[\\/]/).pop() ?? filePath;
@@ -167,7 +167,7 @@ function rewriteArcadeImports(src, injected) {
167
167
  }
168
168
  function rewriteVizImports(src, injected, layerOf, fromLayer) {
169
169
  return src.replace(
170
- /(['"])@babylonjsmarket\/(?:viz-pro|arcade|arcade-pro)\/([A-Z][A-Za-z0-9_]*)\1/g,
170
+ /(['"])@babylonjsmarket\/(?:viz-pro|viz|arcade|arcade-pro)\/([A-Z][A-Za-z0-9_]*)\1/g,
171
171
  (whole, quote, sibling) => {
172
172
  if (!injected.has(sibling)) return whole;
173
173
  const dest = layerOf(sibling);
@@ -181,7 +181,7 @@ function planArcadeProRegistry(existingRegistry, names, registryRelPath = "src/r
181
181
  const warnings = [];
182
182
  if (existingRegistry === void 0) {
183
183
  warnings.push(
184
- `! packages/arcade-pro/${registryRelPath} not found \u2014 add resolvers manually for: ${names.join(", ")}`
184
+ `! packages/arcade/${registryRelPath} not found \u2014 add resolvers manually for: ${names.join(", ")}`
185
185
  );
186
186
  return { lines: [], added: [], warnings, markerFound: false };
187
187
  }
@@ -271,7 +271,8 @@ async function inject(args, opts = {}) {
271
271
  const move = Boolean(argv.move);
272
272
  const confirm = Boolean(argv.confirm);
273
273
  const force = Boolean(argv.force);
274
- const explicitTarget = argv.target;
274
+ const rawTarget = argv.target;
275
+ const explicitTarget = rawTarget === "arcade-pro" ? "arcade" : rawTarget === "viz-pro" ? "viz" : rawTarget;
275
276
  const sourceOverride = argv.source;
276
277
  const layerOverride = argv.layer;
277
278
  const names = argv._.map(String);
@@ -297,8 +298,8 @@ async function inject(args, opts = {}) {
297
298
  process.exit(1);
298
299
  return;
299
300
  }
300
- if (explicitTarget && explicitTarget !== "arcade-pro" && explicitTarget !== "viz-pro") {
301
- console.error(yellow(`Unknown --target ${explicitTarget}. Use arcade-pro or viz-pro.`));
301
+ if (explicitTarget && explicitTarget !== "arcade" && explicitTarget !== "viz") {
302
+ console.error(yellow(`Unknown --target ${rawTarget}. Use arcade or viz.`));
302
303
  process.exit(1);
303
304
  return;
304
305
  }
@@ -373,10 +374,10 @@ async function inject(args, opts = {}) {
373
374
  let chosenRoot;
374
375
  if (mode === "apply") {
375
376
  try {
376
- if (target === "arcade-pro") {
377
+ if (target === "arcade") {
377
378
  if (!fs2.existsSync(packageRoot)) {
378
379
  throw new Error(
379
- `packages/arcade-pro is not checked out at ${packageRoot}. Run \`git submodule update --init packages/arcade-pro\` and retry.`
380
+ `packages/arcade is not checked out at ${packageRoot}. Run \`git submodule update --init packages/arcade\` and retry.`
380
381
  );
381
382
  }
382
383
  chosenRoot = packageRoot;
@@ -400,7 +401,7 @@ async function inject(args, opts = {}) {
400
401
  console.log(` target: ${cyan2(target)}`);
401
402
  console.log(` components: ${cyan2([...closure].sort().join(", "))}`);
402
403
  if (mode === "collect") {
403
- const result = target === "arcade-pro" ? collectArcadePro({ seeds, closure, componentsDir, sourceOverride }) : collectVizPro({ seeds, closure, componentsDir, sourceOverride, layerOverride });
404
+ const result = target === "arcade" ? collectArcadePro({ seeds, closure, componentsDir, sourceOverride }) : collectVizPro({ seeds, closure, componentsDir, sourceOverride, layerOverride });
404
405
  for (const f of result.files) console.log(green(` + packages/${target}/${f.path}`));
405
406
  for (const w of result.warnings) console.log(yellow(w));
406
407
  console.log(
@@ -408,7 +409,7 @@ async function inject(args, opts = {}) {
408
409
  );
409
410
  return { ...result, target };
410
411
  }
411
- if (target === "arcade-pro") {
412
+ if (target === "arcade") {
412
413
  await injectArcadePro({
413
414
  seeds,
414
415
  closure,
@@ -472,7 +473,7 @@ async function injectArcadePro(args) {
472
473
  const dest = path2.join(destComponents, name);
473
474
  if (fs2.existsSync(dest) && !force) {
474
475
  console.log(
475
- yellow(` ! packages/arcade-pro/src/Components/${name}/ already exists \u2014 pass --force to overwrite.`)
476
+ yellow(` ! packages/arcade/src/Components/${name}/ already exists \u2014 pass --force to overwrite.`)
476
477
  );
477
478
  continue;
478
479
  }
@@ -480,7 +481,7 @@ async function injectArcadePro(args) {
480
481
  if (fs2.existsSync(dest)) fs2.rmSync(dest, { recursive: true, force: true });
481
482
  fs2.cpSync(src, dest, { recursive: true });
482
483
  }
483
- console.log(green(` + packages/arcade-pro/src/Components/${name}/`));
484
+ console.log(green(` + packages/arcade/src/Components/${name}/`));
484
485
  }
485
486
  if (!dryRun) {
486
487
  for (const name of closure) {