@bluealba/platform-cli 0.3.0-feature-platform-cli-222 → 0.3.1-feature-platform-cli-prefix-221

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. package/dist/index.js +311 -224
  2. package/package.json +1 -1
  3. package/templates/customization-ui-module-template/Dockerfile +4 -4
  4. package/templates/customization-ui-module-template/Dockerfile.development +1 -1
  5. package/templates/customization-ui-module-template/package.json +3 -3
  6. package/templates/customization-ui-module-template/tsconfig.json +1 -1
  7. package/templates/customization-ui-module-template/webpack.config.js +2 -2
  8. package/templates/platform-init-template/{core → {{platformName}}-core}/local/.env.example +1 -1
  9. package/templates/platform-init-template/{core/local/core-docker-compose.yml → {{platformName}}-core/local/{{platformName}}-core-docker-compose.yml} +5 -5
  10. package/templates/react-ui-module-template/Dockerfile +3 -3
  11. package/templates/react-ui-module-template/Dockerfile.development +1 -1
  12. package/templates/react-ui-module-template/package.json +1 -1
  13. package/templates/react-ui-module-template/src/Icon.tsx +1 -1
  14. /package/templates/customization-ui-module-template/src/{platform-customization-ui.tsx → {{platformName}}-customization-ui.tsx} +0 -0
  15. /package/templates/platform-init-template/{core → {{platformName}}-core}/.changeset/config.json +0 -0
  16. /package/templates/platform-init-template/{core → {{platformName}}-core}/.nvmrc +0 -0
  17. /package/templates/platform-init-template/{core → {{platformName}}-core}/.syncpackrc +0 -0
  18. /package/templates/platform-init-template/{core → {{platformName}}-core}/local/environment/pae-nestjs-gateway-service.env +0 -0
  19. /package/templates/platform-init-template/{core → {{platformName}}-core}/local/nginx.conf +0 -0
  20. /package/templates/platform-init-template/{core → {{platformName}}-core}/local/platform-docker-compose.yml +0 -0
  21. /package/templates/platform-init-template/{core → {{platformName}}-core}/local/ssl/cert.pem +0 -0
  22. /package/templates/platform-init-template/{core → {{platformName}}-core}/local/ssl/key.pem +0 -0
  23. /package/templates/platform-init-template/{core → {{platformName}}-core}/package.json +0 -0
  24. /package/templates/platform-init-template/{core → {{platformName}}-core}/packages-versions.json +0 -0
  25. /package/templates/platform-init-template/{core → {{platformName}}-core}/scripts/preinstall.mjs +0 -0
  26. /package/templates/platform-init-template/{core → {{platformName}}-core}/services/.gitkeep +0 -0
  27. /package/templates/platform-init-template/{core → {{platformName}}-core}/turbo.json +0 -0
  28. /package/templates/platform-init-template/{core → {{platformName}}-core}/ui/.gitkeep +0 -0
package/dist/index.js CHANGED
@@ -6,7 +6,7 @@ import { render } from "ink";
6
6
  // src/app.tsx
7
7
  import { createRequire } from "module";
8
8
  import { useState as useState3, useCallback as useCallback2 } from "react";
9
- import { Box as Box4, Text as Text6, useApp, useInput } from "ink";
9
+ import { Box as Box4, Text as Text7, useApp, useInput } from "ink";
10
10
 
11
11
  // src/components/prompt.tsx
12
12
  import { Box, Text } from "ink";
@@ -54,53 +54,76 @@ var CommandPalette = React.memo(function CommandPalette2({ commands, selectedInd
54
54
  });
55
55
 
56
56
  // src/components/scrollback-history.tsx
57
- import { Static, Text as Text4 } from "ink";
57
+ import { Static, Text as Text5 } from "ink";
58
58
 
59
59
  // src/components/welcome-banner.tsx
60
+ import React3 from "react";
61
+ import { Box as Box3, Text as Text4 } from "ink";
62
+
63
+ // src/components/working-directory.tsx
60
64
  import React2 from "react";
61
- import { Box as Box3, Text as Text3 } from "ink";
65
+ import { Text as Text3 } from "ink";
66
+ import { cwd } from "process";
67
+ import { homedir } from "os";
62
68
  import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
69
+ function shortenPath(fullPath) {
70
+ const home = homedir();
71
+ return fullPath.startsWith(home) ? `~${fullPath.slice(home.length)}` : fullPath;
72
+ }
73
+ var WorkingDirectory = React2.memo(function WorkingDirectory2() {
74
+ const dir = shortenPath(cwd());
75
+ return /* @__PURE__ */ jsxs3(Text3, { dimColor: true, children: [
76
+ " ",
77
+ /* @__PURE__ */ jsx3(Text3, { color: "cyan", children: "cwd:" }),
78
+ " ",
79
+ dir
80
+ ] });
81
+ });
82
+
83
+ // src/components/welcome-banner.tsx
84
+ import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
63
85
  var ASCII_ART = [
64
86
  "|---. .---|",
65
87
  "| \\/ |",
66
88
  "| /\\ |",
67
89
  "|---' '---|"
68
90
  ];
69
- var WelcomeBanner = React2.memo(function WelcomeBanner2({ version: version2 }) {
70
- return /* @__PURE__ */ jsxs3(Box3, { borderStyle: "round", flexDirection: "column", paddingX: 1, paddingY: 1, children: [
71
- /* @__PURE__ */ jsxs3(Text3, { bold: true, color: "cyan", children: [
91
+ var WelcomeBanner = React3.memo(function WelcomeBanner2({ version: version2 }) {
92
+ return /* @__PURE__ */ jsxs4(Box3, { borderStyle: "round", flexDirection: "column", paddingX: 1, paddingY: 1, children: [
93
+ /* @__PURE__ */ jsxs4(Text4, { bold: true, color: "cyan", children: [
72
94
  "Blue Alba Platform CLI v",
73
95
  version2
74
96
  ] }),
75
- /* @__PURE__ */ jsxs3(Box3, { marginTop: 1, children: [
76
- /* @__PURE__ */ jsx3(Box3, { flexDirection: "column", marginRight: 2, children: ASCII_ART.map((line, i) => /* @__PURE__ */ jsx3(Text3, { color: "yellow", children: line }, i)) }),
77
- /* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", justifyContent: "center", marginRight: 2, children: [
78
- /* @__PURE__ */ jsx3(Text3, { bold: true, children: "Welcome to the" }),
79
- /* @__PURE__ */ jsx3(Text3, { bold: true, children: "Blue Alba Platform!" })
97
+ /* @__PURE__ */ jsxs4(Box3, { marginTop: 1, children: [
98
+ /* @__PURE__ */ jsx4(Box3, { flexDirection: "column", marginRight: 2, children: ASCII_ART.map((line, i) => /* @__PURE__ */ jsx4(Text4, { color: "yellow", children: line }, i)) }),
99
+ /* @__PURE__ */ jsxs4(Box3, { flexDirection: "column", justifyContent: "center", marginRight: 2, children: [
100
+ /* @__PURE__ */ jsx4(Text4, { bold: true, children: "Welcome to the" }),
101
+ /* @__PURE__ */ jsx4(Text4, { bold: true, children: "Blue Alba Platform!" })
80
102
  ] }),
81
- /* @__PURE__ */ jsx3(Box3, { flexDirection: "column", children: ASCII_ART.map((_, i) => /* @__PURE__ */ jsx3(Text3, { dimColor: true, children: "\u2502" }, i)) }),
82
- /* @__PURE__ */ jsxs3(Box3, { flexDirection: "column", marginLeft: 2, children: [
83
- /* @__PURE__ */ jsx3(Text3, { bold: true, color: "cyan", children: "Tips for getting started" }),
84
- /* @__PURE__ */ jsxs3(Text3, { children: [
103
+ /* @__PURE__ */ jsx4(Box3, { flexDirection: "column", children: ASCII_ART.map((_, i) => /* @__PURE__ */ jsx4(Text4, { dimColor: true, children: "\u2502" }, i)) }),
104
+ /* @__PURE__ */ jsxs4(Box3, { flexDirection: "column", marginLeft: 2, children: [
105
+ /* @__PURE__ */ jsx4(Text4, { bold: true, color: "cyan", children: "Tips for getting started" }),
106
+ /* @__PURE__ */ jsxs4(Text4, { children: [
85
107
  "Run ",
86
- /* @__PURE__ */ jsx3(Text3, { color: "green", children: "/init" }),
108
+ /* @__PURE__ */ jsx4(Text4, { color: "green", children: "/init" }),
87
109
  " to start building a platform"
88
110
  ] })
89
111
  ] })
90
- ] })
112
+ ] }),
113
+ /* @__PURE__ */ jsx4(WorkingDirectory, {})
91
114
  ] });
92
115
  });
93
116
 
94
117
  // src/components/scrollback-history.tsx
95
- import { jsx as jsx4 } from "react/jsx-runtime";
118
+ import { jsx as jsx5 } from "react/jsx-runtime";
96
119
  function ScrollbackHistory({ items, version: version2 }) {
97
- return /* @__PURE__ */ jsx4(Static, { items, children: (item) => item.kind === "banner" ? /* @__PURE__ */ jsx4(WelcomeBanner, { version: version2 }, item.id) : /* @__PURE__ */ jsx4(Text4, { children: item.line }, item.id) });
120
+ return /* @__PURE__ */ jsx5(Static, { items, children: (item) => item.kind === "banner" ? /* @__PURE__ */ jsx5(WelcomeBanner, { version: version2 }, item.id) : /* @__PURE__ */ jsx5(Text5, { children: item.line }, item.id) });
98
121
  }
99
122
 
100
123
  // src/components/spinner.tsx
101
124
  import { useState, useEffect } from "react";
102
- import { Text as Text5 } from "ink";
103
- import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
125
+ import { Text as Text6 } from "ink";
126
+ import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
104
127
  var FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
105
128
  var INTERVAL_MS = 80;
106
129
  function Spinner({ label }) {
@@ -111,12 +134,12 @@ function Spinner({ label }) {
111
134
  }, INTERVAL_MS);
112
135
  return () => clearInterval(id);
113
136
  }, []);
114
- return /* @__PURE__ */ jsxs4(Text5, { children: [
115
- /* @__PURE__ */ jsxs4(Text5, { color: "cyan", children: [
137
+ return /* @__PURE__ */ jsxs5(Text6, { children: [
138
+ /* @__PURE__ */ jsxs5(Text6, { color: "cyan", children: [
116
139
  FRAMES[frame],
117
140
  " "
118
141
  ] }),
119
- label && /* @__PURE__ */ jsx5(Text5, { dimColor: true, children: label })
142
+ label && /* @__PURE__ */ jsx6(Text6, { dimColor: true, children: label })
120
143
  ] });
121
144
  }
122
145
 
@@ -124,7 +147,7 @@ function Spinner({ label }) {
124
147
  import { Fzf } from "fzf";
125
148
 
126
149
  // src/commands/create-application/create-application.command.ts
127
- import { join as join10, resolve } from "path";
150
+ import { join as join11, resolve } from "path";
128
151
  import { mkdir as mkdir2 } from "fs/promises";
129
152
 
130
153
  // src/commands/create-application/scaffold-application-monorepo.ts
@@ -289,8 +312,8 @@ var nestjsServiceModuleTemplateDir = join6(
289
312
  "templates",
290
313
  "nestjs-service-module-template"
291
314
  );
292
- async function scaffoldNestjsService(serviceDir, organizationName, applicationName, applicationDisplayName, serviceBaseDir, logger) {
293
- const serviceName = `${applicationName}-service`;
315
+ async function scaffoldNestjsService(serviceDir, organizationName, platformName, applicationName, applicationDisplayName, serviceBaseDir, logger) {
316
+ const serviceName = `${platformName}-${applicationName}-service`;
294
317
  const serviceDisplayName = `${applicationDisplayName} Service`;
295
318
  logger.log(`Creating NestJS service "${serviceName}"...`);
296
319
  await applyTemplate(
@@ -321,33 +344,35 @@ async function addModuleEntry(bootstrapServiceDir, applicationName, entry, logge
321
344
  }
322
345
 
323
346
  // src/commands/create-application/module-entry-builders.ts
324
- function buildServiceModuleEntry(organizationName, applicationName, applicationDisplayName) {
347
+ function buildServiceModuleEntry(organizationName, platformName, applicationName, applicationDisplayName) {
348
+ const serviceName = `${platformName}-${applicationName}-service`;
325
349
  return {
326
- name: `@${organizationName}/${applicationName}-service`,
350
+ name: `@${organizationName}/${serviceName}`,
327
351
  displayName: `${applicationDisplayName} Service`,
328
352
  type: "service",
329
- baseUrl: `/${applicationName}-service`,
353
+ baseUrl: `/${serviceName}`,
330
354
  service: {
331
- host: `${applicationName}-service`,
355
+ host: serviceName,
332
356
  port: 80
333
357
  },
334
358
  dependsOn: []
335
359
  };
336
360
  }
337
- function buildUiModuleEntry(organizationName, applicationName, applicationDisplayName) {
361
+ function buildUiModuleEntry(organizationName, platformName, applicationName, applicationDisplayName) {
362
+ const uiName = `${platformName}-${applicationName}-ui`;
338
363
  return {
339
- name: `@${organizationName}/${applicationName}-ui`,
364
+ name: `@${organizationName}/${uiName}`,
340
365
  displayName: applicationDisplayName,
341
366
  type: "app",
342
- baseUrl: `/${applicationName}-ui`,
367
+ baseUrl: `/${uiName}`,
343
368
  service: {
344
- host: `${applicationName}-ui`,
369
+ host: uiName,
345
370
  port: 80
346
371
  },
347
372
  ui: {
348
373
  route: `/${applicationName}`,
349
374
  mountAtSelector: "#pae-shell-ui-content",
350
- bundleFile: `${organizationName}-${applicationName}-ui.js`,
375
+ bundleFile: `${organizationName}-${uiName}.js`,
351
376
  customProps: {}
352
377
  },
353
378
  dependsOn: [`@bluealba/pae-shell-ui`]
@@ -357,9 +382,10 @@ function buildUiModuleEntry(organizationName, applicationName, applicationDispla
357
382
  // src/commands/create-application/create-docker-compose.ts
358
383
  import { writeFile as writeFile3 } from "fs/promises";
359
384
  function buildBootstrapBlock(platformName, applicationName) {
360
- return ` ${applicationName}-bootstrap-service:
385
+ const bootstrapName = `${platformName}-${applicationName}-bootstrap-service`;
386
+ return ` ${bootstrapName}:
361
387
  build:
362
- context: ../../${platformName}-${applicationName}/services/${applicationName}-bootstrap-service
388
+ context: ../../${platformName}-${applicationName}/services/${bootstrapName}
363
389
  dockerfile: Dockerfile.development
364
390
  environment:
365
391
  - NODE_TLS_REJECT_UNAUTHORIZED=0
@@ -376,9 +402,10 @@ function buildBootstrapBlock(platformName, applicationName) {
376
402
  `;
377
403
  }
378
404
  function buildUiBlock(platformName, applicationName, uiPort) {
379
- return ` ${applicationName}-ui:
405
+ const uiName = `${platformName}-${applicationName}-ui`;
406
+ return ` ${uiName}:
380
407
  build:
381
- context: ../../${platformName}-${applicationName}/ui/${applicationName}-ui
408
+ context: ../../${platformName}-${applicationName}/ui/${uiName}
382
409
  dockerfile: Dockerfile.development
383
410
  ports:
384
411
  - ${uiPort}:80
@@ -387,9 +414,10 @@ function buildUiBlock(platformName, applicationName, uiPort) {
387
414
  `;
388
415
  }
389
416
  function buildBackendBlock(platformName, applicationName, servicePort) {
390
- return ` ${applicationName}-service:
417
+ const serviceName = `${platformName}-${applicationName}-service`;
418
+ return ` ${serviceName}:
391
419
  build:
392
- context: ../../${platformName}-${applicationName}/services/${applicationName}-service
420
+ context: ../../${platformName}-${applicationName}/services/${serviceName}
393
421
  dockerfile: Dockerfile.development
394
422
  args:
395
423
  - BA_NPM_AUTH_TOKEN=$BA_NPM_AUTH_TOKEN
@@ -422,9 +450,8 @@ async function createDockerCompose(dockerComposePath, applicationName, platformN
422
450
  // src/commands/create-application/port-allocator.ts
423
451
  import { join as join8 } from "path";
424
452
  import { readdir as readdir2, readFile as readFile3 } from "fs/promises";
425
- async function getNextAvailablePort(rootDir) {
453
+ async function getNextAvailablePort(localDir) {
426
454
  const allPorts = [];
427
- const localDir = join8(rootDir, "core", "local");
428
455
  try {
429
456
  const files = await readdir2(localDir);
430
457
  const ymlFiles = files.filter((f) => f.endsWith(".yml") || f.endsWith(".yaml"));
@@ -449,32 +476,76 @@ function formatError(err) {
449
476
  return err instanceof Error ? err.message : String(err);
450
477
  }
451
478
 
452
- // src/utils/platform-check.ts
479
+ // src/utils/platform-layout.ts
480
+ import { access, readdir as readdir3 } from "fs/promises";
481
+ import { join as join9, dirname as dirname7 } from "path";
453
482
  import { cwd as cwd2 } from "process";
454
- import { dirname as dirname7 } from "path";
483
+ async function findCoreDirIn(dir) {
484
+ let entries;
485
+ try {
486
+ entries = await readdir3(dir, { withFileTypes: true });
487
+ } catch {
488
+ return null;
489
+ }
490
+ const dirs = entries.filter((e) => e.isDirectory());
491
+ for (const entry of dirs) {
492
+ if (entry.name.endsWith("-core")) {
493
+ try {
494
+ await access(join9(dir, entry.name, "product.manifest.json"));
495
+ return entry.name;
496
+ } catch {
497
+ }
498
+ }
499
+ }
500
+ const coreEntry = dirs.find((e) => e.name === "core");
501
+ if (coreEntry) {
502
+ try {
503
+ await access(join9(dir, "core", "product.manifest.json"));
504
+ return "core";
505
+ } catch {
506
+ }
507
+ }
508
+ return null;
509
+ }
510
+ async function findPlatformLayout(startDir = cwd2()) {
511
+ let dir = startDir;
512
+ while (true) {
513
+ const coreDirName = await findCoreDirIn(dir);
514
+ if (coreDirName) {
515
+ const coreDir = join9(dir, coreDirName);
516
+ return {
517
+ rootDir: dir,
518
+ coreDir,
519
+ coreDirName,
520
+ localDir: join9(coreDir, "local")
521
+ };
522
+ }
523
+ const parent = dirname7(dir);
524
+ if (parent === dir) {
525
+ return null;
526
+ }
527
+ dir = parent;
528
+ }
529
+ }
530
+
531
+ // src/utils/platform-check.ts
532
+ async function isPlatformInitialized() {
533
+ return await findPlatformLayout() !== null;
534
+ }
455
535
 
456
536
  // src/utils/manifest.ts
457
- import { readFile as readFile4, writeFile as writeFile4, access } from "fs/promises";
458
- import { join as join9 } from "path";
459
- import { cwd } from "process";
460
- var MANIFEST_RELATIVE_PATH = join9("core", "product.manifest.json");
461
- function manifestPath(rootDir) {
462
- return join9(rootDir, MANIFEST_RELATIVE_PATH);
537
+ import { readFile as readFile4, writeFile as writeFile4, access as access2 } from "fs/promises";
538
+ import { join as join10 } from "path";
539
+ import { cwd as cwd3 } from "process";
540
+ function manifestPath(rootDir, coreDirName = "core") {
541
+ return join10(rootDir, coreDirName, "product.manifest.json");
463
542
  }
464
- async function readManifest(rootDir = cwd()) {
465
- const content = await readFile4(manifestPath(rootDir), "utf-8");
543
+ async function readManifest(rootDir = cwd3(), coreDirName = "core") {
544
+ const content = await readFile4(manifestPath(rootDir, coreDirName), "utf-8");
466
545
  return JSON.parse(content);
467
546
  }
468
- async function writeManifest(manifest, rootDir = cwd()) {
469
- await writeFile4(manifestPath(rootDir), JSON.stringify(manifest, null, 2), "utf-8");
470
- }
471
- async function manifestExists(rootDir = cwd()) {
472
- try {
473
- await access(manifestPath(rootDir));
474
- return true;
475
- } catch {
476
- return false;
477
- }
547
+ async function writeManifest(manifest, rootDir = cwd3(), coreDirName = "core") {
548
+ await writeFile4(manifestPath(rootDir, coreDirName), JSON.stringify(manifest, null, 2), "utf-8");
478
549
  }
479
550
  function createInitialManifest(params) {
480
551
  const { organizationName, platformName, platformDisplayName } = params;
@@ -496,24 +567,6 @@ function addApplicationToManifest(manifest, app) {
496
567
  };
497
568
  }
498
569
 
499
- // src/utils/platform-check.ts
500
- async function findRootDir(startDir = cwd2()) {
501
- let dir = startDir;
502
- while (true) {
503
- if (await manifestExists(dir)) {
504
- return dir;
505
- }
506
- const parent = dirname7(dir);
507
- if (parent === dir) {
508
- return null;
509
- }
510
- dir = parent;
511
- }
512
- }
513
- async function isPlatformInitialized() {
514
- return await findRootDir() !== null;
515
- }
516
-
517
570
  // src/commands/create-application/create-application.command.ts
518
571
  var CREATE_APPLICATION_COMMAND_NAME = "create-application";
519
572
  var createApplicationCommand = {
@@ -528,22 +581,24 @@ async function createApplication(params, logger) {
528
581
  hasUserInterface,
529
582
  hasBackendService
530
583
  } = params;
531
- const rootDir = await findRootDir();
532
- if (!rootDir) {
584
+ const layout = await findPlatformLayout();
585
+ if (!layout) {
533
586
  logger.log("Error: Cannot create an application \u2014 no platform initialized in this directory.");
534
587
  return;
535
588
  }
589
+ const { rootDir, coreDirName, localDir } = layout;
536
590
  let manifest;
537
591
  try {
538
- manifest = await readManifest(rootDir);
592
+ manifest = await readManifest(rootDir, coreDirName);
539
593
  } catch (err) {
540
594
  logger.log(`Error: Could not read product manifest \u2014 ${formatError(err)}`);
541
595
  return;
542
596
  }
543
597
  const { organization: organizationName, name: platformName } = manifest.product;
544
598
  const localPath = `../${platformName}-${applicationName}`;
545
- const applicationDir = resolve(join10(rootDir, "core"), localPath);
546
- const bootstrapServiceDir = join10(applicationDir, "services", `${applicationName}-bootstrap-service`);
599
+ const applicationDir = resolve(join11(rootDir, coreDirName), localPath);
600
+ const bootstrapServiceName = `${platformName}-${applicationName}-bootstrap-service`;
601
+ const bootstrapServiceDir = join11(applicationDir, "services", bootstrapServiceName);
547
602
  logger.log(`Creating application monorepo "${applicationName}"...`);
548
603
  try {
549
604
  await scaffoldApplicationMonorepo(applicationDir, organizationName, platformName, applicationName, logger);
@@ -551,12 +606,12 @@ async function createApplication(params, logger) {
551
606
  logger.log(`Error: Could not scaffold application monorepo \u2014 ${formatError(err)}`);
552
607
  return;
553
608
  }
554
- await mkdir2(join10(applicationDir, "services"), { recursive: true });
555
- await mkdir2(join10(applicationDir, "ui"), { recursive: true });
556
- logger.log(`Creating bootstrap service "${applicationName}-bootstrap-service"...`);
557
- const bootstrapServiceDir_var = `${platformName}-${applicationName}/services`;
609
+ await mkdir2(join11(applicationDir, "services"), { recursive: true });
610
+ await mkdir2(join11(applicationDir, "ui"), { recursive: true });
611
+ logger.log(`Creating bootstrap service "${bootstrapServiceName}"...`);
612
+ const bootstrapServiceBaseDir = `${platformName}-${applicationName}/services`;
558
613
  try {
559
- await scaffoldBootstrap(bootstrapServiceDir, organizationName, applicationName, bootstrapServiceDir_var, logger);
614
+ await scaffoldBootstrap(bootstrapServiceDir, organizationName, `${platformName}-${applicationName}`, bootstrapServiceBaseDir, logger);
560
615
  } catch (err) {
561
616
  logger.log(`Error: Could not scaffold bootstrap service \u2014 ${formatError(err)}`);
562
617
  return;
@@ -572,7 +627,7 @@ async function createApplication(params, logger) {
572
627
  await addModuleEntry(
573
628
  bootstrapServiceDir,
574
629
  applicationName,
575
- buildUiModuleEntry(organizationName, applicationName, applicationDisplayName),
630
+ buildUiModuleEntry(organizationName, platformName, applicationName, applicationDisplayName),
576
631
  logger
577
632
  );
578
633
  }
@@ -580,12 +635,13 @@ async function createApplication(params, logger) {
580
635
  await addModuleEntry(
581
636
  bootstrapServiceDir,
582
637
  applicationName,
583
- buildServiceModuleEntry(organizationName, applicationName, applicationDisplayName),
638
+ buildServiceModuleEntry(organizationName, platformName, applicationName, applicationDisplayName),
584
639
  logger
585
640
  );
586
641
  }
587
642
  if (hasUserInterface) {
588
- const uiDir = join10(applicationDir, "ui", `${applicationName}-ui`);
643
+ const uiName = `${platformName}-${applicationName}-ui`;
644
+ const uiDir = join11(applicationDir, "ui", uiName);
589
645
  const uiBaseDir = `${platformName}-${applicationName}/ui`;
590
646
  try {
591
647
  await scaffoldUiModule(uiDir, organizationName, platformName, applicationName, applicationDisplayName, uiBaseDir, logger);
@@ -595,17 +651,18 @@ async function createApplication(params, logger) {
595
651
  }
596
652
  }
597
653
  if (hasBackendService) {
598
- const serviceDir = join10(applicationDir, "services", `${applicationName}-service`);
654
+ const serviceName = `${platformName}-${applicationName}-service`;
655
+ const serviceDir = join11(applicationDir, "services", serviceName);
599
656
  const serviceBaseDir = `${platformName}-${applicationName}/services`;
600
657
  try {
601
- await scaffoldNestjsService(serviceDir, organizationName, applicationName, applicationDisplayName, serviceBaseDir, logger);
658
+ await scaffoldNestjsService(serviceDir, organizationName, platformName, applicationName, applicationDisplayName, serviceBaseDir, logger);
602
659
  } catch (err) {
603
660
  logger.log(`Error: Could not scaffold NestJS service \u2014 ${formatError(err)}`);
604
661
  return;
605
662
  }
606
663
  }
607
- const dockerComposePath = join10(rootDir, "core", "local", `${applicationName}-docker-compose.yml`);
608
- const basePort = await getNextAvailablePort(rootDir);
664
+ const dockerComposePath = join11(localDir, `${platformName}-${applicationName}-docker-compose.yml`);
665
+ const basePort = await getNextAvailablePort(localDir);
609
666
  const uiPort = hasUserInterface ? basePort : 0;
610
667
  const servicePort = hasBackendService ? hasUserInterface ? basePort + 1 : basePort : 0;
611
668
  await createDockerCompose(
@@ -626,7 +683,7 @@ async function createApplication(params, logger) {
626
683
  repository: null
627
684
  });
628
685
  try {
629
- await writeManifest(updatedManifest, rootDir);
686
+ await writeManifest(updatedManifest, rootDir, coreDirName);
630
687
  logger.log(`Updated product manifest with application "${applicationName}".`);
631
688
  } catch (err) {
632
689
  logger.log(`Warning: Could not update product manifest \u2014 ${formatError(err)}`);
@@ -635,8 +692,8 @@ async function createApplication(params, logger) {
635
692
  }
636
693
 
637
694
  // src/commands/init/init.command.ts
638
- import { join as join16 } from "path";
639
- import { cwd as cwd3 } from "process";
695
+ import { join as join17 } from "path";
696
+ import { cwd as cwd4 } from "process";
640
697
 
641
698
  // src/utils/string.ts
642
699
  function camelize(name) {
@@ -645,8 +702,8 @@ function camelize(name) {
645
702
 
646
703
  // src/commands/init/scaffold-platform.ts
647
704
  import { fileURLToPath as fileURLToPath6 } from "url";
648
- import { join as join11, dirname as dirname8 } from "path";
649
- var templateDir = join11(
705
+ import { join as join12, dirname as dirname8 } from "path";
706
+ var templateDir = join12(
650
707
  dirname8(fileURLToPath6(import.meta.url)),
651
708
  "..",
652
709
  "templates",
@@ -658,8 +715,8 @@ async function scaffoldPlatform(outputDir, variables, logger) {
658
715
 
659
716
  // src/commands/init/scaffold-platform-bootstrap.ts
660
717
  import { fileURLToPath as fileURLToPath7 } from "url";
661
- import { join as join12, dirname as dirname9 } from "path";
662
- var templateDir2 = join12(
718
+ import { join as join13, dirname as dirname9 } from "path";
719
+ var templateDir2 = join13(
663
720
  dirname9(fileURLToPath7(import.meta.url)),
664
721
  "..",
665
722
  "templates",
@@ -671,8 +728,8 @@ async function scaffoldPlatformBootstrap(outputDir, variables, logger) {
671
728
 
672
729
  // src/commands/init/scaffold-customization-ui.ts
673
730
  import { fileURLToPath as fileURLToPath8 } from "url";
674
- import { join as join13, dirname as dirname10 } from "path";
675
- var templateDir3 = join13(
731
+ import { join as join14, dirname as dirname10 } from "path";
732
+ var templateDir3 = join14(
676
733
  dirname10(fileURLToPath8(import.meta.url)),
677
734
  "..",
678
735
  "templates",
@@ -683,19 +740,20 @@ async function scaffoldCustomizationUi(outputDir, variables, logger) {
683
740
  }
684
741
 
685
742
  // src/commands/init/register-customization-module.ts
686
- import { join as join14 } from "path";
743
+ import { join as join15 } from "path";
687
744
  import { readFile as readFile5, writeFile as writeFile5 } from "fs/promises";
688
- async function registerCustomizationModule(bootstrapServiceDir, organizationName, logger) {
689
- const modulesJsonPath = join14(bootstrapServiceDir, "src", "data", "platform", "modules.json");
745
+ async function registerCustomizationModule(bootstrapServiceDir, organizationName, logger, platformName = "platform") {
746
+ const modulesJsonPath = join15(bootstrapServiceDir, "src", "data", "platform", "modules.json");
747
+ const customizationUiName = `${platformName}-customization-ui`;
690
748
  const entry = {
691
- name: `@${organizationName}/platform-customization-ui`,
749
+ name: `@${organizationName}/${customizationUiName}`,
692
750
  displayName: "Platform Customization UI",
693
751
  type: "app",
694
- baseUrl: "/platform-customization-ui",
695
- service: { host: "platform-customization-ui", port: 80 },
752
+ baseUrl: `/${customizationUiName}`,
753
+ service: { host: customizationUiName, port: 80 },
696
754
  ui: {
697
755
  route: "/",
698
- bundleFile: "platform-customization-ui.js",
756
+ bundleFile: `${customizationUiName}.js`,
699
757
  isPlatformCustomization: true,
700
758
  customProps: {}
701
759
  },
@@ -709,7 +767,7 @@ async function registerCustomizationModule(bootstrapServiceDir, organizationName
709
767
 
710
768
  // src/commands/init/generate-local-env.ts
711
769
  import { readFile as readFile6, writeFile as writeFile6 } from "fs/promises";
712
- import { join as join15 } from "path";
770
+ import { join as join16 } from "path";
713
771
 
714
772
  // src/utils/random.ts
715
773
  import { randomBytes } from "crypto";
@@ -718,10 +776,10 @@ function generateRandomSecret() {
718
776
  }
719
777
 
720
778
  // src/commands/init/generate-local-env.ts
721
- async function generateLocalEnv(outputDir, logger) {
722
- const examplePath = join15(outputDir, "core", "local", ".env.example");
723
- const envPath = join15(outputDir, "core", "local", ".env");
724
- logger.log("Generating core/local/.env with random secrets...");
779
+ async function generateLocalEnv(outputDir, logger, coreDirName = "core") {
780
+ const examplePath = join16(outputDir, coreDirName, "local", ".env.example");
781
+ const envPath = join16(outputDir, coreDirName, "local", ".env");
782
+ logger.log(`Generating ${coreDirName}/local/.env with random secrets...`);
725
783
  const content = await readFile6(examplePath, "utf-8");
726
784
  const result = content.replace(/^(PAE_AUTH_JWT_SECRET|PAE_GATEWAY_SERVICE_ACCESS_SECRET|PAE_DB_PASSWORD)=$/gm, (_, key) => {
727
785
  return `${key}=${generateRandomSecret()}`;
@@ -742,15 +800,18 @@ async function init(params, logger) {
742
800
  }
743
801
  const { organizationName, platformName, platformDisplayName } = params;
744
802
  const platformTitle = camelize(platformName);
745
- const outputDir = cwd3();
803
+ const outputDir = cwd4();
746
804
  logger.log(`Initializing ${platformTitle} platform for @${organizationName}...`);
805
+ const coreDirName = `${platformName}-core`;
806
+ const bootstrapServiceName = `${platformName}-bootstrap-service`;
807
+ const customizationUiName = `${platformName}-customization-ui`;
747
808
  const variables = {
748
809
  organizationName,
749
810
  platformName,
750
811
  platformTitle,
751
812
  platformDisplayName,
752
- bootstrapName: "platform",
753
- bootstrapServiceDir: "core/services"
813
+ bootstrapName: platformName,
814
+ bootstrapServiceDir: `${coreDirName}/services`
754
815
  };
755
816
  try {
756
817
  await scaffoldPlatform(outputDir, variables, logger);
@@ -759,22 +820,22 @@ async function init(params, logger) {
759
820
  return;
760
821
  }
761
822
  try {
762
- await generateLocalEnv(outputDir, logger);
823
+ await generateLocalEnv(outputDir, logger, coreDirName);
763
824
  } catch (err) {
764
- logger.log(`Error: Could not generate core/local/.env \u2014 ${formatError(err)}`);
825
+ logger.log(`Error: Could not generate ${coreDirName}/local/.env \u2014 ${formatError(err)}`);
765
826
  return;
766
827
  }
767
828
  try {
768
829
  const manifest = createInitialManifest({ organizationName, platformName, platformDisplayName });
769
- await writeManifest(manifest, outputDir);
770
- logger.log("Created product manifest: core/product.manifest.json");
830
+ await writeManifest(manifest, outputDir, coreDirName);
831
+ logger.log(`Created product manifest: ${coreDirName}/product.manifest.json`);
771
832
  } catch (err) {
772
833
  logger.log(`Error: Could not write product manifest \u2014 ${formatError(err)}`);
773
834
  return;
774
835
  }
775
836
  try {
776
837
  await scaffoldPlatformBootstrap(
777
- join16(outputDir, "core", "services", "platform-bootstrap-service"),
838
+ join17(outputDir, coreDirName, "services", bootstrapServiceName),
778
839
  variables,
779
840
  logger
780
841
  );
@@ -784,7 +845,7 @@ async function init(params, logger) {
784
845
  }
785
846
  try {
786
847
  await scaffoldCustomizationUi(
787
- join16(outputDir, "core", "ui", "platform-customization-ui"),
848
+ join17(outputDir, coreDirName, "ui", customizationUiName),
788
849
  variables,
789
850
  logger
790
851
  );
@@ -794,9 +855,10 @@ async function init(params, logger) {
794
855
  }
795
856
  try {
796
857
  await registerCustomizationModule(
797
- join16(outputDir, "core", "services", "platform-bootstrap-service"),
858
+ join17(outputDir, coreDirName, "services", bootstrapServiceName),
798
859
  organizationName,
799
- logger
860
+ logger,
861
+ platformName
800
862
  );
801
863
  } catch (err) {
802
864
  logger.log(`Error: Could not register customization module \u2014 ${formatError(err)}`);
@@ -806,7 +868,7 @@ async function init(params, logger) {
806
868
  }
807
869
 
808
870
  // src/commands/configure-idp/configure-idp.command.ts
809
- import { join as join17 } from "path";
871
+ import { join as join18 } from "path";
810
872
  import { fetch as undiciFetch, Agent } from "undici";
811
873
 
812
874
  // src/utils/env-reader.ts
@@ -884,12 +946,12 @@ var configureIdpCommand = {
884
946
  description: "Configure an Identity Provider (IDP) in the gateway"
885
947
  };
886
948
  async function configureIdp(params, logger) {
887
- const rootDir = await findRootDir();
888
- if (!rootDir) {
949
+ const layout = await findPlatformLayout();
950
+ if (!layout) {
889
951
  logger.log("Error: Cannot configure an IDP \u2014 no platform initialized in this directory.");
890
952
  return;
891
953
  }
892
- const envPath = join17(rootDir, "core", "local", ".env");
954
+ const envPath = join18(layout.localDir, ".env");
893
955
  let env;
894
956
  try {
895
957
  env = await readEnvFile(envPath);
@@ -941,13 +1003,13 @@ async function configureIdp(params, logger) {
941
1003
  }
942
1004
 
943
1005
  // src/commands/create-service-module/create-service-module.command.ts
944
- import { join as join19, resolve as resolve2 } from "path";
945
- import { access as access2 } from "fs/promises";
1006
+ import { join as join20, resolve as resolve2 } from "path";
1007
+ import { access as access3 } from "fs/promises";
946
1008
 
947
1009
  // src/commands/create-service-module/scaffold-service-module.ts
948
1010
  import { fileURLToPath as fileURLToPath9 } from "url";
949
- import { join as join18, dirname as dirname11 } from "path";
950
- var nestjsServiceModuleTemplateDir2 = join18(
1011
+ import { join as join19, dirname as dirname11 } from "path";
1012
+ var nestjsServiceModuleTemplateDir2 = join19(
951
1013
  dirname11(fileURLToPath9(import.meta.url)),
952
1014
  "..",
953
1015
  "templates",
@@ -1016,14 +1078,15 @@ var createServiceModuleCommand = {
1016
1078
  };
1017
1079
  async function createServiceModule(params, logger) {
1018
1080
  const { applicationName, serviceName, serviceDisplayName } = params;
1019
- const rootDir = await findRootDir();
1020
- if (!rootDir) {
1081
+ const layout = await findPlatformLayout();
1082
+ if (!layout) {
1021
1083
  logger.log("Error: Cannot create a service module \u2014 no platform initialized in this directory.");
1022
1084
  return;
1023
1085
  }
1086
+ const { rootDir, coreDirName, localDir } = layout;
1024
1087
  let manifest;
1025
1088
  try {
1026
- manifest = await readManifest(rootDir);
1089
+ manifest = await readManifest(rootDir, coreDirName);
1027
1090
  } catch (err) {
1028
1091
  logger.log(`Error: Could not read product manifest \u2014 ${formatError(err)}`);
1029
1092
  return;
@@ -1034,17 +1097,17 @@ async function createServiceModule(params, logger) {
1034
1097
  logger.log(`Error: The specified application "${applicationName}" is not registered in the product manifest.`);
1035
1098
  return;
1036
1099
  }
1037
- const applicationDir = resolve2(join19(rootDir, "core"), appEntry.localPath);
1100
+ const applicationDir = resolve2(join20(rootDir, coreDirName), appEntry.localPath);
1038
1101
  try {
1039
- await access2(applicationDir);
1102
+ await access3(applicationDir);
1040
1103
  } catch {
1041
1104
  logger.log(`Error: The specified application "${applicationName}" does not exist in the platform.`);
1042
1105
  return;
1043
1106
  }
1044
- const fullServiceName = `${serviceName}-service`;
1045
- const serviceDir = join19(applicationDir, "services", fullServiceName);
1107
+ const fullServiceName = `${platformName}-${serviceName}-service`;
1108
+ const serviceDir = join20(applicationDir, "services", fullServiceName);
1046
1109
  try {
1047
- await access2(serviceDir);
1110
+ await access3(serviceDir);
1048
1111
  logger.log(`Error: A service named "${fullServiceName}" already exists in application "${applicationName}".`);
1049
1112
  return;
1050
1113
  } catch {
@@ -1063,26 +1126,27 @@ async function createServiceModule(params, logger) {
1063
1126
  logger.log(`Error: Could not scaffold NestJS service \u2014 ${formatError(err)}`);
1064
1127
  return;
1065
1128
  }
1066
- const bootstrapServiceDir = join19(applicationDir, "services", `${applicationName}-bootstrap-service`);
1129
+ const bootstrapServiceDir = join20(applicationDir, "services", `${platformName}-${applicationName}-bootstrap-service`);
1067
1130
  const moduleEntry = buildCustomServiceModuleEntry(organizationName, fullServiceName, serviceDisplayName);
1068
1131
  await addModuleEntry(bootstrapServiceDir, applicationName, moduleEntry, logger);
1069
- const dockerComposePath = join19(rootDir, "core", "local", `${applicationName}-docker-compose.yml`);
1070
- const port = await getNextAvailablePort(rootDir);
1132
+ const dockerComposePath = join20(localDir, `${platformName}-${applicationName}-docker-compose.yml`);
1133
+ const port = await getNextAvailablePort(localDir);
1071
1134
  await appendServiceToDockerCompose(dockerComposePath, fullServiceName, platformName, applicationName, port, logger);
1072
1135
  logger.log(`Done! Service module "${fullServiceName}" added to application "${applicationName}".`);
1073
1136
  }
1074
1137
 
1075
1138
  // src/commands/create-ui-module/create-ui-module.command.ts
1076
- import { join as join20, resolve as resolve3 } from "path";
1077
- import { access as access3, readdir as readdir3 } from "fs/promises";
1139
+ import { join as join21, resolve as resolve3 } from "path";
1140
+ import { access as access4, readdir as readdir4 } from "fs/promises";
1078
1141
 
1079
1142
  // src/commands/create-ui-module/append-ui-docker-compose.ts
1080
1143
  import { readFile as readFile9, writeFile as writeFile8 } from "fs/promises";
1081
1144
  async function appendUiToDockerCompose(dockerComposePath, platformName, applicationName, port, logger) {
1145
+ const uiName = `${platformName}-${applicationName}-ui`;
1082
1146
  const block = `
1083
- ${applicationName}-ui:
1147
+ ${uiName}:
1084
1148
  build:
1085
- context: ../../${platformName}-${applicationName}/ui/${applicationName}-ui
1149
+ context: ../../${platformName}-${applicationName}/ui/${uiName}
1086
1150
  dockerfile: Dockerfile.development
1087
1151
  ports:
1088
1152
  - ${port}:80
@@ -1107,14 +1171,15 @@ var createUiModuleCommand = {
1107
1171
  };
1108
1172
  async function createUiModule(params, logger) {
1109
1173
  const { applicationName, applicationDisplayName } = params;
1110
- const rootDir = await findRootDir();
1111
- if (!rootDir) {
1174
+ const layout = await findPlatformLayout();
1175
+ if (!layout) {
1112
1176
  logger.log("Error: Cannot create a UI module \u2014 no platform initialized in this directory.");
1113
1177
  return;
1114
1178
  }
1179
+ const { rootDir, coreDirName, localDir } = layout;
1115
1180
  let manifest;
1116
1181
  try {
1117
- manifest = await readManifest(rootDir);
1182
+ manifest = await readManifest(rootDir, coreDirName);
1118
1183
  } catch (err) {
1119
1184
  logger.log(`Error: Could not read product manifest \u2014 ${formatError(err)}`);
1120
1185
  return;
@@ -1125,16 +1190,16 @@ async function createUiModule(params, logger) {
1125
1190
  logger.log(`Error: The specified application "${applicationName}" is not registered in the product manifest.`);
1126
1191
  return;
1127
1192
  }
1128
- const applicationDir = resolve3(join20(rootDir, "core"), appEntry.localPath);
1193
+ const applicationDir = resolve3(join21(rootDir, coreDirName), appEntry.localPath);
1129
1194
  try {
1130
- await access3(applicationDir);
1195
+ await access4(applicationDir);
1131
1196
  } catch {
1132
1197
  logger.log(`Error: The specified application "${applicationName}" does not exist in the platform.`);
1133
1198
  return;
1134
1199
  }
1135
- const uiDir = join20(applicationDir, "ui");
1200
+ const uiDir = join21(applicationDir, "ui");
1136
1201
  try {
1137
- const uiEntries = await readdir3(uiDir);
1202
+ const uiEntries = await readdir4(uiDir);
1138
1203
  const existingUiModules = uiEntries.filter((e) => e !== ".gitkeep");
1139
1204
  if (existingUiModules.length > 0) {
1140
1205
  logger.log(`Error: Currently we support only one UI module per application. Application "${applicationName}" already has a UI module.`);
@@ -1142,7 +1207,8 @@ async function createUiModule(params, logger) {
1142
1207
  }
1143
1208
  } catch {
1144
1209
  }
1145
- const uiOutputDir = join20(uiDir, `${applicationName}-ui`);
1210
+ const uiName = `${platformName}-${applicationName}-ui`;
1211
+ const uiOutputDir = join21(uiDir, uiName);
1146
1212
  const uiBaseDir = `${platformName}-${applicationName}/ui`;
1147
1213
  try {
1148
1214
  await scaffoldUiModule(uiOutputDir, organizationName, platformName, applicationName, applicationDisplayName, uiBaseDir, logger);
@@ -1150,13 +1216,13 @@ async function createUiModule(params, logger) {
1150
1216
  logger.log(`Error: Could not scaffold UI module \u2014 ${formatError(err)}`);
1151
1217
  return;
1152
1218
  }
1153
- const bootstrapServiceDir = join20(applicationDir, "services", `${applicationName}-bootstrap-service`);
1154
- const moduleEntry = buildUiModuleEntry(organizationName, applicationName, applicationDisplayName);
1219
+ const bootstrapServiceDir = join21(applicationDir, "services", `${platformName}-${applicationName}-bootstrap-service`);
1220
+ const moduleEntry = buildUiModuleEntry(organizationName, platformName, applicationName, applicationDisplayName);
1155
1221
  await addModuleEntry(bootstrapServiceDir, applicationName, moduleEntry, logger);
1156
- const dockerComposePath = join20(rootDir, "core", "local", `${applicationName}-docker-compose.yml`);
1157
- const port = await getNextAvailablePort(rootDir);
1222
+ const dockerComposePath = join21(localDir, `${platformName}-${applicationName}-docker-compose.yml`);
1223
+ const port = await getNextAvailablePort(localDir);
1158
1224
  await appendUiToDockerCompose(dockerComposePath, platformName, applicationName, port, logger);
1159
- logger.log(`Done! UI module "${applicationName}-ui" added to application "${applicationName}".`);
1225
+ logger.log(`Done! UI module "${uiName}" added to application "${applicationName}".`);
1160
1226
  }
1161
1227
 
1162
1228
  // src/commands/registry.ts
@@ -1432,7 +1498,7 @@ function useCommandRunner({ appendStaticItem, setState }) {
1432
1498
  }
1433
1499
 
1434
1500
  // src/app.tsx
1435
- import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
1501
+ import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
1436
1502
  var require2 = createRequire(import.meta.url);
1437
1503
  var { version } = require2("../package.json");
1438
1504
  function App() {
@@ -1519,17 +1585,17 @@ function App() {
1519
1585
  function renderActiveArea() {
1520
1586
  switch (state) {
1521
1587
  case APP_STATE.EXECUTING:
1522
- return /* @__PURE__ */ jsxs5(Box4, { flexDirection: "row", gap: 1, children: [
1523
- /* @__PURE__ */ jsx6(Spinner, { label: "Running\u2026" }),
1524
- /* @__PURE__ */ jsx6(Text6, { dimColor: true, children: "(esc to cancel)" })
1588
+ return /* @__PURE__ */ jsxs6(Box4, { flexDirection: "row", gap: 1, children: [
1589
+ /* @__PURE__ */ jsx7(Spinner, { label: "Running\u2026" }),
1590
+ /* @__PURE__ */ jsx7(Text7, { dimColor: true, children: "(esc to cancel)" })
1525
1591
  ] });
1526
1592
  case APP_STATE.PROMPTING:
1527
- return /* @__PURE__ */ jsxs5(Box4, { flexDirection: "column", children: [
1528
- /* @__PURE__ */ jsx6(Text6, { color: "cyan", children: promptMessage }),
1529
- /* @__PURE__ */ jsx6(Prompt, { value: promptValue, onChange: setPromptValue, onSubmit: handlePromptSubmit })
1593
+ return /* @__PURE__ */ jsxs6(Box4, { flexDirection: "column", children: [
1594
+ /* @__PURE__ */ jsx7(Text7, { color: "cyan", children: promptMessage }),
1595
+ /* @__PURE__ */ jsx7(Prompt, { value: promptValue, onChange: setPromptValue, onSubmit: handlePromptSubmit })
1530
1596
  ] });
1531
1597
  default:
1532
- return /* @__PURE__ */ jsx6(
1598
+ return /* @__PURE__ */ jsx7(
1533
1599
  Prompt,
1534
1600
  {
1535
1601
  value: inputValue,
@@ -1542,10 +1608,10 @@ function App() {
1542
1608
  );
1543
1609
  }
1544
1610
  }
1545
- return /* @__PURE__ */ jsxs5(Box4, { flexDirection: "column", children: [
1546
- /* @__PURE__ */ jsx6(ScrollbackHistory, { items: staticItems, version }),
1611
+ return /* @__PURE__ */ jsxs6(Box4, { flexDirection: "column", children: [
1612
+ /* @__PURE__ */ jsx7(ScrollbackHistory, { items: staticItems, version }),
1547
1613
  renderActiveArea(),
1548
- state === APP_STATE.PALETTE && /* @__PURE__ */ jsx6(CommandPalette, { commands: filteredCommands, selectedIndex })
1614
+ state === APP_STATE.PALETTE && /* @__PURE__ */ jsx7(CommandPalette, { commands: filteredCommands, selectedIndex })
1549
1615
  ] });
1550
1616
  }
1551
1617
 
@@ -1630,8 +1696,8 @@ async function configureIdpCliController(args2) {
1630
1696
 
1631
1697
  // src/commands/local-scripts/docker-compose-orchestrator.ts
1632
1698
  import { spawn } from "child_process";
1633
- import { access as access4 } from "fs/promises";
1634
- import { join as join21 } from "path";
1699
+ import { access as access5 } from "fs/promises";
1700
+ import { join as join22 } from "path";
1635
1701
  function runDockerCompose(args2, logger, rootDir, signal) {
1636
1702
  return new Promise((resolvePromise) => {
1637
1703
  const child = spawn("docker", ["compose", ...args2], {
@@ -1676,42 +1742,62 @@ function runDockerCompose(args2, logger, rootDir, signal) {
1676
1742
  });
1677
1743
  });
1678
1744
  }
1679
- async function getAppComposePaths(rootDir, manifest) {
1745
+ async function getAppComposePaths(localDir, platformName, manifest) {
1680
1746
  const results = [];
1681
1747
  for (const app of manifest.applications) {
1682
- const composePath = join21(rootDir, "core", "local", `${app.name}-docker-compose.yml`);
1748
+ const prefixedPath = join22(localDir, `${platformName}-${app.name}-docker-compose.yml`);
1749
+ const unprefixedPath = join22(localDir, `${app.name}-docker-compose.yml`);
1750
+ let resolved = null;
1683
1751
  try {
1684
- await access4(composePath);
1685
- results.push({ composePath, appName: app.name });
1752
+ await access5(prefixedPath);
1753
+ resolved = prefixedPath;
1686
1754
  } catch {
1755
+ try {
1756
+ await access5(unprefixedPath);
1757
+ resolved = unprefixedPath;
1758
+ } catch {
1759
+ }
1760
+ }
1761
+ if (resolved) {
1762
+ results.push({ composePath: resolved, appName: app.name });
1687
1763
  }
1688
1764
  }
1689
1765
  return results;
1690
1766
  }
1691
- async function buildAllComposeArgs(rootDir, manifest, logger) {
1692
- const localDir = join21(rootDir, "core", "local");
1767
+ async function buildAllComposeArgs(layout, manifest, logger) {
1768
+ const { rootDir, coreDirName, localDir } = layout;
1769
+ const platformName = manifest.product.name;
1770
+ const prefixedCoreCompose = join22(localDir, `${coreDirName}-docker-compose.yml`);
1771
+ const unprefixedCoreCompose = join22(localDir, "core-docker-compose.yml");
1772
+ let coreComposePath;
1773
+ try {
1774
+ await access5(prefixedCoreCompose);
1775
+ coreComposePath = prefixedCoreCompose;
1776
+ } catch {
1777
+ coreComposePath = unprefixedCoreCompose;
1778
+ }
1693
1779
  const fileArgs = [
1694
1780
  "-f",
1695
- join21(localDir, "platform-docker-compose.yml"),
1781
+ join22(localDir, "platform-docker-compose.yml"),
1696
1782
  "-f",
1697
- join21(localDir, "core-docker-compose.yml")
1783
+ coreComposePath
1698
1784
  ];
1699
- const appEntries = await getAppComposePaths(rootDir, manifest);
1700
- for (const { composePath, appName } of appEntries) {
1785
+ const appEntries = await getAppComposePaths(localDir, platformName, manifest);
1786
+ for (const { composePath } of appEntries) {
1701
1787
  fileArgs.push("-f", composePath);
1702
1788
  }
1703
1789
  for (const app of manifest.applications) {
1704
1790
  if (!appEntries.find((e) => e.appName === app.name)) {
1705
- logger.log(`Warning: No docker-compose found for application "${app.name}" in core/local/ \u2014 skipping.`);
1791
+ logger.log(`Warning: No docker-compose found for application "${app.name}" in ${coreDirName}/local/ \u2014 skipping.`);
1706
1792
  }
1707
1793
  }
1708
1794
  return fileArgs;
1709
1795
  }
1710
- async function startEnvironment(rootDir, manifest, logger, signal) {
1796
+ async function startEnvironment(layout, manifest, logger, signal) {
1797
+ const { rootDir, localDir } = layout;
1711
1798
  const platformName = manifest.product.name;
1712
- const envFile = join21(rootDir, "core", "local", ".env");
1713
- const fileArgs = await buildAllComposeArgs(rootDir, manifest, logger);
1714
- const localDir = join21(rootDir, "core", "local");
1799
+ const envFile = join22(localDir, ".env");
1800
+ const fileArgs = await buildAllComposeArgs(layout, manifest, logger);
1715
1801
  logger.log("Starting environment...");
1716
1802
  await runDockerCompose(
1717
1803
  [
@@ -1732,11 +1818,11 @@ async function startEnvironment(rootDir, manifest, logger, signal) {
1732
1818
  signal
1733
1819
  );
1734
1820
  }
1735
- async function stopEnvironment(rootDir, manifest, logger, signal) {
1821
+ async function stopEnvironment(layout, manifest, logger, signal) {
1822
+ const { rootDir, localDir } = layout;
1736
1823
  const platformName = manifest.product.name;
1737
- const envFile = join21(rootDir, "core", "local", ".env");
1738
- const fileArgs = await buildAllComposeArgs(rootDir, manifest, logger);
1739
- const localDir = join21(rootDir, "core", "local");
1824
+ const envFile = join22(localDir, ".env");
1825
+ const fileArgs = await buildAllComposeArgs(layout, manifest, logger);
1740
1826
  logger.log("Stopping environment...");
1741
1827
  await runDockerCompose(
1742
1828
  [
@@ -1754,11 +1840,11 @@ async function stopEnvironment(rootDir, manifest, logger, signal) {
1754
1840
  signal
1755
1841
  );
1756
1842
  }
1757
- async function destroyEnvironment(rootDir, manifest, logger, signal) {
1843
+ async function destroyEnvironment(layout, manifest, logger, signal) {
1844
+ const { rootDir, localDir } = layout;
1758
1845
  const platformName = manifest.product.name;
1759
- const envFile = join21(rootDir, "core", "local", ".env");
1760
- const fileArgs = await buildAllComposeArgs(rootDir, manifest, logger);
1761
- const localDir = join21(rootDir, "core", "local");
1846
+ const envFile = join22(localDir, ".env");
1847
+ const fileArgs = await buildAllComposeArgs(layout, manifest, logger);
1762
1848
  logger.log("Destroying environment...");
1763
1849
  await runDockerCompose(
1764
1850
  [
@@ -1782,8 +1868,8 @@ async function destroyEnvironment(rootDir, manifest, logger, signal) {
1782
1868
 
1783
1869
  // src/commands/local-scripts/npm-orchestrator.ts
1784
1870
  import { spawn as spawn2 } from "child_process";
1785
- import { access as access5 } from "fs/promises";
1786
- import { join as join22, resolve as resolve4 } from "path";
1871
+ import { access as access6 } from "fs/promises";
1872
+ import { resolve as resolve4, join as join23 } from "path";
1787
1873
  function runCommand(command, args2, workDir, logger, signal) {
1788
1874
  return new Promise((resolvePromise) => {
1789
1875
  const child = spawn2(command, args2, {
@@ -1830,24 +1916,24 @@ function runCommand(command, args2, workDir, logger, signal) {
1830
1916
  }
1831
1917
  async function dirExists(dirPath) {
1832
1918
  try {
1833
- await access5(dirPath);
1919
+ await access6(dirPath);
1834
1920
  return true;
1835
1921
  } catch {
1836
1922
  return false;
1837
1923
  }
1838
1924
  }
1839
- async function installDependencies(rootDir, manifest, logger, signal) {
1840
- const coreDir = join22(rootDir, "core");
1925
+ async function installDependencies(layout, manifest, logger, signal) {
1926
+ const { coreDir, coreDirName } = layout;
1841
1927
  const appDirs = [];
1842
1928
  for (const app of manifest.applications) {
1843
- const appDir = resolve4(join22(rootDir, "core"), app.localPath);
1929
+ const appDir = resolve4(join23(coreDir), app.localPath);
1844
1930
  if (!await dirExists(appDir)) {
1845
1931
  logger.log(`Warning: Application directory "${app.name}" not found at ${appDir} \u2014 skipping install.`);
1846
1932
  continue;
1847
1933
  }
1848
1934
  appDirs.push({ name: app.name, dir: appDir });
1849
1935
  }
1850
- const targets = [{ name: "core", dir: coreDir }, ...appDirs];
1936
+ const targets = [{ name: coreDirName, dir: coreDir }, ...appDirs];
1851
1937
  logger.log(`Installing dependencies in parallel: ${targets.map((t) => t.name).join(", ")}...`);
1852
1938
  await Promise.all(
1853
1939
  targets.map(
@@ -1857,14 +1943,14 @@ async function installDependencies(rootDir, manifest, logger, signal) {
1857
1943
  )
1858
1944
  );
1859
1945
  }
1860
- async function buildAll(rootDir, manifest, logger, signal) {
1861
- const coreDir = join22(rootDir, "core");
1862
- logger.log("Building core/...");
1946
+ async function buildAll(layout, manifest, logger, signal) {
1947
+ const { coreDir, coreDirName } = layout;
1948
+ logger.log(`Building ${coreDirName}/...`);
1863
1949
  await runCommand("npx", ["turbo", "build"], coreDir, logger, signal);
1864
1950
  if (signal?.aborted) return;
1865
1951
  const appDirs = [];
1866
1952
  for (const app of manifest.applications) {
1867
- const appDir = resolve4(join22(rootDir, "core"), app.localPath);
1953
+ const appDir = resolve4(join23(coreDir), app.localPath);
1868
1954
  if (!await dirExists(appDir)) {
1869
1955
  logger.log(`Warning: Application directory "${app.name}" not found at ${appDir} \u2014 skipping build.`);
1870
1956
  continue;
@@ -1889,33 +1975,34 @@ var START_COMMAND_NAME = "start";
1889
1975
  var STOP_COMMAND_NAME = "stop";
1890
1976
  var DESTROY_COMMAND_NAME = "destroy";
1891
1977
  async function runLocalScript(scriptName, logger, signal) {
1892
- const rootDir = await findRootDir();
1893
- if (!rootDir) {
1978
+ const layout = await findPlatformLayout();
1979
+ if (!layout) {
1894
1980
  logger.log(`Error: Cannot run "${scriptName}" \u2014 no platform initialized in this directory.`);
1895
1981
  return;
1896
1982
  }
1983
+ const { rootDir, coreDirName } = layout;
1897
1984
  let manifest;
1898
1985
  try {
1899
- manifest = await readManifest(rootDir);
1986
+ manifest = await readManifest(rootDir, coreDirName);
1900
1987
  } catch (err) {
1901
1988
  logger.log(`Error: Could not read product manifest \u2014 ${formatError(err)}`);
1902
1989
  return;
1903
1990
  }
1904
1991
  switch (scriptName) {
1905
1992
  case START_COMMAND_NAME:
1906
- await startEnvironment(rootDir, manifest, logger, signal);
1993
+ await startEnvironment(layout, manifest, logger, signal);
1907
1994
  break;
1908
1995
  case STOP_COMMAND_NAME:
1909
- await stopEnvironment(rootDir, manifest, logger, signal);
1996
+ await stopEnvironment(layout, manifest, logger, signal);
1910
1997
  break;
1911
1998
  case DESTROY_COMMAND_NAME:
1912
- await destroyEnvironment(rootDir, manifest, logger, signal);
1999
+ await destroyEnvironment(layout, manifest, logger, signal);
1913
2000
  break;
1914
2001
  case INSTALL_COMMAND_NAME:
1915
- await installDependencies(rootDir, manifest, logger, signal);
2002
+ await installDependencies(layout, manifest, logger, signal);
1916
2003
  break;
1917
2004
  case BUILD_COMMAND_NAME:
1918
- await buildAll(rootDir, manifest, logger, signal);
2005
+ await buildAll(layout, manifest, logger, signal);
1919
2006
  break;
1920
2007
  default:
1921
2008
  logger.log(`Error: Unknown script "${scriptName}".`);
@@ -2045,10 +2132,10 @@ function parseKeyValueArgs(args2) {
2045
2132
  }
2046
2133
 
2047
2134
  // src/index.tsx
2048
- import { jsx as jsx7 } from "react/jsx-runtime";
2135
+ import { jsx as jsx8 } from "react/jsx-runtime";
2049
2136
  var args = process.argv.slice(2);
2050
2137
  if (args.length === 0) {
2051
- render(/* @__PURE__ */ jsx7(App, {}));
2138
+ render(/* @__PURE__ */ jsx8(App, {}));
2052
2139
  } else {
2053
2140
  const commandName = args[0];
2054
2141
  const params = parseKeyValueArgs(args.slice(1));