create-bw-app 0.9.1 → 0.9.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -56,7 +56,8 @@ Current updater behavior:
56
56
  - platform apps include BrightWeb auth, shell wiring, and optional module starter surfaces
57
57
  - site apps include Next.js, Tailwind CSS v4, and local component primitives
58
58
  - writes `package.json`, `next.config.ts`, `.gitignore`, and `README.md` for both templates
59
- - platform apps also write `.env.local`, `AGENTS.md`, `docs/ai/README.md`, and generated config files for brand and module state
59
+ - platform apps also write `.env.local`, `AGENTS.md`, `docs/ai/README.md`, `docs/ai/examples.md`, `docs/ai/app-context.json`, and generated config files for brand and module state
60
+ - site apps also write `AGENTS.md`, `docs/ai/README.md`, `docs/ai/examples.md`, and `docs/ai/app-context.json` for app-local AI handoff
60
61
  - supports repo-local `workspace:*` wiring and future published dependency wiring
61
62
 
62
63
  ## Workspace mode extras
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "create-bw-app",
3
3
  "private": false,
4
- "version": "0.9.1",
4
+ "version": "0.9.3",
5
5
  "type": "module",
6
6
  "bin": "bin/create-bw-app.mjs",
7
7
  "files": [
package/src/constants.mjs CHANGED
@@ -66,13 +66,13 @@ export const MODULE_STARTER_FILES = {
66
66
  };
67
67
 
68
68
  export const APP_DEPENDENCY_DEFAULTS = {
69
- "@brightweblabs/app-shell": "^0.1.1",
70
- "@brightweblabs/core-auth": "^0.1.1",
71
- "@brightweblabs/infra": "^0.1.0",
72
- "@brightweblabs/module-admin": "^0.1.1",
73
- "@brightweblabs/module-crm": "^0.1.1",
74
- "@brightweblabs/module-projects": "^0.1.1",
75
- "@brightweblabs/ui": "^0.1.0",
69
+ "@brightweblabs/app-shell": "^0.3.0",
70
+ "@brightweblabs/core-auth": "^0.3.0",
71
+ "@brightweblabs/infra": "^0.2.0",
72
+ "@brightweblabs/module-admin": "^0.3.0",
73
+ "@brightweblabs/module-crm": "^0.3.0",
74
+ "@brightweblabs/module-projects": "^0.2.0",
75
+ "@brightweblabs/ui": "^0.3.0",
76
76
  "lucide-react": "^0.562.0",
77
77
  "next": "16.1.6",
78
78
  "react": "19.2.3",
package/src/generator.mjs CHANGED
@@ -414,6 +414,20 @@ function createGitignore() {
414
414
  ].join("\n");
415
415
  }
416
416
 
417
+ function getPlatformStarterRoutes(selectedModules) {
418
+ return [
419
+ "/",
420
+ "/bootstrap",
421
+ "/preview/app-shell",
422
+ "/playground/auth",
423
+ ...selectedModules.map((moduleKey) => `/playground/${moduleKey}`),
424
+ ];
425
+ }
426
+
427
+ function getSiteStarterRoutes() {
428
+ return ["/"];
429
+ }
430
+
417
431
  function createPlatformReadme({
418
432
  slug,
419
433
  selectedModules,
@@ -471,11 +485,14 @@ function createPlatformReadme({
471
485
  : []),
472
486
  "## Starter routes",
473
487
  "",
474
- "- `/`",
475
- "- `/bootstrap`",
476
- "- `/preview/app-shell`",
477
- "- `/playground/auth`",
478
- ...selectedModules.map((moduleKey) => `- /playground/${moduleKey}`),
488
+ ...getPlatformStarterRoutes(selectedModules).map((route) => `- \`${route}\``),
489
+ "",
490
+ "## AI handoff",
491
+ "",
492
+ "- `AGENTS.md`",
493
+ "- `docs/ai/README.md`",
494
+ "- `docs/ai/examples.md`",
495
+ "- `docs/ai/app-context.json`",
479
496
  "",
480
497
  ].join("\n");
481
498
  }
@@ -508,13 +525,143 @@ function createSiteReadme({ slug, workspaceMode, packageManager }) {
508
525
  "",
509
526
  "## Starter surfaces",
510
527
  "",
511
- "- `/`",
528
+ ...getSiteStarterRoutes().map((route) => `- \`${route}\``),
512
529
  "",
513
530
  "Edit `config/site.ts` to change the site name, copy, and public links.",
514
531
  "",
532
+ "## AI handoff",
533
+ "",
534
+ "- `AGENTS.md`",
535
+ "- `docs/ai/README.md`",
536
+ "- `docs/ai/examples.md`",
537
+ "- `docs/ai/app-context.json`",
538
+ "",
515
539
  ].join("\n");
516
540
  }
517
541
 
542
+ export function createAppContextFile({
543
+ slug,
544
+ template,
545
+ selectedModules = [],
546
+ dbInstallPlan = { resolvedOrder: [] },
547
+ }) {
548
+ if (template === "site") {
549
+ return `${JSON.stringify(
550
+ {
551
+ schemaVersion: 1,
552
+ template: "site",
553
+ app: {
554
+ slug,
555
+ name: titleizeSlug(slug),
556
+ },
557
+ docs: {
558
+ agentGuide: "AGENTS.md",
559
+ routingGuide: "docs/ai/README.md",
560
+ setupGuide: "README.md",
561
+ examples: "docs/ai/examples.md",
562
+ },
563
+ paths: {
564
+ readFirst: [
565
+ "AGENTS.md",
566
+ "docs/ai/README.md",
567
+ "README.md",
568
+ "config/site.ts",
569
+ "app/page.tsx",
570
+ "app/globals.css",
571
+ ],
572
+ appRoutesRoot: "app",
573
+ configRoot: "config",
574
+ componentsRoot: "components",
575
+ uiComponentsRoot: "components/ui",
576
+ libRoot: "lib",
577
+ },
578
+ starterRoutes: getSiteStarterRoutes(),
579
+ ownership: {
580
+ appOwned: [
581
+ "app/**",
582
+ "components/**",
583
+ "config/**",
584
+ "docs/ai/**",
585
+ "lib/**",
586
+ "public/**",
587
+ "AGENTS.md",
588
+ "README.md",
589
+ ],
590
+ packageOwned: [],
591
+ },
592
+ agentRules: {
593
+ editConfigBeforeCopyTweaks: true,
594
+ keepUiPrimitiveChangesLocal: true,
595
+ treatStarterHomeAsAppOwned: true,
596
+ },
597
+ },
598
+ null,
599
+ 2,
600
+ )}\n`;
601
+ }
602
+
603
+ return `${JSON.stringify(
604
+ {
605
+ schemaVersion: 1,
606
+ template: "platform",
607
+ app: {
608
+ slug,
609
+ name: titleizeSlug(slug),
610
+ },
611
+ modules: {
612
+ enabled: selectedModules,
613
+ resolvedDatabaseStack: dbInstallPlan.resolvedOrder,
614
+ },
615
+ docs: {
616
+ agentGuide: "AGENTS.md",
617
+ routingGuide: "docs/ai/README.md",
618
+ setupGuide: "README.md",
619
+ examples: "docs/ai/examples.md",
620
+ },
621
+ paths: {
622
+ readFirst: [
623
+ "AGENTS.md",
624
+ "docs/ai/README.md",
625
+ "README.md",
626
+ "config/brand.ts",
627
+ "config/modules.ts",
628
+ "config/client.ts",
629
+ "config/bootstrap.ts",
630
+ "config/shell.ts",
631
+ ".env.local",
632
+ ],
633
+ appRoutesRoot: "app",
634
+ configRoot: "config",
635
+ brandAssetsRoot: "public/brand",
636
+ },
637
+ starterRoutes: getPlatformStarterRoutes(selectedModules),
638
+ ownership: {
639
+ appOwned: [
640
+ "app/**",
641
+ "config/**",
642
+ "docs/ai/**",
643
+ "public/brand/**",
644
+ "AGENTS.md",
645
+ "README.md",
646
+ ],
647
+ packageOwned: [
648
+ ...CORE_PACKAGES,
649
+ ...SELECTABLE_MODULES
650
+ .filter((moduleDefinition) => selectedModules.includes(moduleDefinition.key))
651
+ .map((moduleDefinition) => moduleDefinition.packageName),
652
+ ],
653
+ },
654
+ agentRules: {
655
+ checkModulesBeforeEditing: true,
656
+ preferAppLevelCompositionOverPackageForks: true,
657
+ treatStarterRoutesAsRemovable: true,
658
+ },
659
+ },
660
+ null,
661
+ 2,
662
+ )}\n`;
663
+ }
664
+
518
665
  export function createPackageJson({
519
666
  slug,
520
667
  dependencyMode,
@@ -971,6 +1118,15 @@ async function scaffoldPlatformProject({
971
1118
  );
972
1119
  await fs.writeFile(path.join(targetDir, "config", "modules.ts"), createPlatformModulesConfigFile(selectedModules));
973
1120
  await fs.writeFile(path.join(targetDir, "config", "shell.ts"), createShellConfig(selectedModules));
1121
+ await fs.writeFile(
1122
+ path.join(targetDir, "docs", "ai", "app-context.json"),
1123
+ createAppContextFile({
1124
+ slug: answers.slug,
1125
+ template: "platform",
1126
+ selectedModules,
1127
+ dbInstallPlan,
1128
+ }),
1129
+ );
974
1130
 
975
1131
  const envFileContent = createEnvFileContent();
976
1132
 
@@ -1007,6 +1163,7 @@ async function scaffoldSiteProject({
1007
1163
  await ensureDirectory(path.dirname(targetDir));
1008
1164
  await copyDirectory(baseTemplateDir, targetDir);
1009
1165
  await ensureDirectory(path.join(targetDir, "config"));
1166
+ await ensureDirectory(path.join(targetDir, "docs", "ai"));
1010
1167
 
1011
1168
  await fs.writeFile(
1012
1169
  path.join(targetDir, "package.json"),
@@ -1025,6 +1182,13 @@ async function scaffoldSiteProject({
1025
1182
  await fs.writeFile(path.join(targetDir, "next.config.ts"), createNextConfig({ template: "site", selectedModules: [] }));
1026
1183
  await fs.writeFile(path.join(targetDir, ".gitignore"), createGitignore());
1027
1184
  await fs.writeFile(path.join(targetDir, "config", "site.ts"), createSiteConfigFile(answers.slug));
1185
+ await fs.writeFile(
1186
+ path.join(targetDir, "docs", "ai", "app-context.json"),
1187
+ createAppContextFile({
1188
+ slug: answers.slug,
1189
+ template: "site",
1190
+ }),
1191
+ );
1028
1192
  await fs.writeFile(
1029
1193
  path.join(targetDir, "README.md"),
1030
1194
  createSiteReadme({
package/src/update.mjs CHANGED
@@ -9,6 +9,7 @@ import {
9
9
  } from "./constants.mjs";
10
10
  import {
11
11
  TEMPLATE_ROOT,
12
+ createAppContextFile,
12
13
  createDbInstallPlan,
13
14
  createNextConfig,
14
15
  createPackageJson,
@@ -26,6 +27,11 @@ const MANAGED_PLATFORM_FILES = [
26
27
  "next.config.ts",
27
28
  path.join("config", "modules.ts"),
28
29
  path.join("config", "shell.ts"),
30
+ path.join("docs", "ai", "app-context.json"),
31
+ ];
32
+
33
+ const MANAGED_SITE_FILES = [
34
+ path.join("docs", "ai", "app-context.json"),
29
35
  ];
30
36
 
31
37
  function resolveUpdateTargetDirectory(runtimeOptions, argvOptions) {
@@ -337,7 +343,7 @@ export async function buildBrightwebAppUpdatePlan(argvOptions = {}, runtimeOptio
337
343
  const dbInstallPlan = template === "platform"
338
344
  ? createDbInstallPlan({
339
345
  selectedModules: installedModules,
340
- workspaceMode: true,
346
+ workspaceMode: dependencyMode === "workspace",
341
347
  registry: dbRegistry,
342
348
  })
343
349
  : {
@@ -373,6 +379,12 @@ export async function buildBrightwebAppUpdatePlan(argvOptions = {}, runtimeOptio
373
379
  "next.config.ts": createNextConfig({ template: "platform", selectedModules: installedModules }),
374
380
  [path.join("config", "modules.ts")]: createPlatformModulesConfigFile(installedModules),
375
381
  [path.join("config", "shell.ts")]: createShellConfig(installedModules),
382
+ [path.join("docs", "ai", "app-context.json")]: createAppContextFile({
383
+ slug: manifest.name || path.basename(targetDir),
384
+ template: "platform",
385
+ selectedModules: installedModules,
386
+ dbInstallPlan,
387
+ }),
376
388
  };
377
389
 
378
390
  for (const relativePath of MANAGED_PLATFORM_FILES) {
@@ -380,6 +392,28 @@ export async function buildBrightwebAppUpdatePlan(argvOptions = {}, runtimeOptio
380
392
  const currentContent = (await pathExists(targetPath)) ? await fs.readFile(targetPath, "utf8") : null;
381
393
  const nextContent = canonicalConfigFiles[relativePath];
382
394
 
395
+ if (currentContent !== nextContent) {
396
+ fileWrites.push({
397
+ relativePath,
398
+ targetPath,
399
+ content: nextContent,
400
+ type: "config",
401
+ });
402
+ }
403
+ }
404
+ } else {
405
+ const canonicalConfigFiles = {
406
+ [path.join("docs", "ai", "app-context.json")]: createAppContextFile({
407
+ slug: manifest.name || path.basename(targetDir),
408
+ template: "site",
409
+ }),
410
+ };
411
+
412
+ for (const relativePath of MANAGED_SITE_FILES) {
413
+ const targetPath = path.join(targetDir, relativePath);
414
+ const currentContent = (await pathExists(targetPath)) ? await fs.readFile(targetPath, "utf8") : null;
415
+ const nextContent = canonicalConfigFiles[relativePath];
416
+
383
417
  if (currentContent !== nextContent) {
384
418
  fileWrites.push({
385
419
  relativePath,
@@ -6,6 +6,8 @@ This generated project is a BrightWeb platform starter. Use this file as the loc
6
6
 
7
7
  - `README.md`: local setup commands and starter routes.
8
8
  - `docs/ai/README.md`: app-specific routing guide for agents.
9
+ - `docs/ai/examples.md`: common setup and customization flows.
10
+ - `docs/ai/app-context.json`: machine-readable app summary for quick discovery.
9
11
  - `config/brand.ts`: client identity, naming, and contact defaults.
10
12
  - `config/modules.ts`: selected module set and runtime enablement.
11
13
  - `config/client.ts`: starter-facing derived state used by the home page and setup surfaces.
@@ -15,6 +15,8 @@ This app is a normal Next.js App Router project with BrightWeb runtime wiring la
15
15
 
16
16
  ## Fast routing map
17
17
 
18
+ - `docs/ai/app-context.json`: machine-readable summary of this app's template, starter routes, and first-read files.
19
+ - `docs/ai/examples.md`: common setup and customization workflows.
18
20
  - `README.md`: first-run setup steps.
19
21
  - `config/brand.ts`: client name, product name, support inboxes, and brand color.
20
22
  - `config/modules.ts`: module metadata and enablement flags for CRM, Projects, and Admin.
@@ -0,0 +1,38 @@
1
+ # Agent Examples
2
+
3
+ Use these workflows after reading `AGENTS.md`, `docs/ai/README.md`, and `docs/ai/app-context.json`.
4
+
5
+ ## First local setup
6
+
7
+ Goal: get the generated starter running with real credentials.
8
+
9
+ - Review `.env.local` and replace placeholder values.
10
+ - Review `config/brand.ts` and confirm client identity.
11
+ - Review `config/modules.ts` before touching module routes.
12
+ - Run the local dev server for this app or workspace.
13
+ - Validate `/`, `/bootstrap`, `/preview/app-shell`, and `/playground/auth`.
14
+ - Validate `/playground/crm`, `/playground/projects`, and `/playground/admin` only when those modules are enabled.
15
+
16
+ ## Change brand identity
17
+
18
+ Goal: update the starter to the real client name and support details.
19
+
20
+ - Edit `config/brand.ts`.
21
+ - Check `config/client.ts` or `config/bootstrap.ts` if starter copy still references old defaults.
22
+ - Validate the home page and `/preview/app-shell` after the change.
23
+
24
+ ## Replace starter routes with product routes
25
+
26
+ Goal: move from validation surfaces to product-owned pages.
27
+
28
+ - Build the real routes in `app/` first.
29
+ - Update `config/shell.ts` if navigation or toolbar behavior changes.
30
+ - Remove `/bootstrap`, `/preview/app-shell`, or `/playground/*` only after links and config references are cleaned up.
31
+
32
+ ## Make a module-aware change
33
+
34
+ Goal: add or modify functionality without assuming a module exists.
35
+
36
+ - Check `config/modules.ts` first.
37
+ - If the module is enabled, edit the app-owned route or API surface before considering package forks.
38
+ - If the module is not enabled, do not create links or routes that assume it exists.
@@ -0,0 +1,25 @@
1
+ # AGENTS.md
2
+
3
+ This generated project is a BrightWeb site starter. Use this file as the local entrypoint for AI agents working inside the app.
4
+
5
+ ## Start here
6
+
7
+ - `README.md`: local setup commands and the starter surface list.
8
+ - `docs/ai/README.md`: app-specific routing guide for agents.
9
+ - `docs/ai/examples.md`: common setup and customization flows.
10
+ - `docs/ai/app-context.json`: machine-readable app summary for quick discovery.
11
+ - `config/site.ts`: site name, description, and starter CTAs.
12
+ - `app/page.tsx`: starter landing page composition.
13
+ - `app/globals.css`: global design language and theme tokens.
14
+
15
+ ## Working rules
16
+
17
+ - Treat this starter as app-owned. Prefer editing local routes, sections, and UI primitives instead of introducing shared BrightWeb runtime dependencies.
18
+ - Update `config/site.ts` before rewriting copy inline across multiple components.
19
+ - Keep reusable UI tweaks inside `components/ui/` when the change should affect multiple sections.
20
+
21
+ ## First validation pass
22
+
23
+ 1. Run the local dev server from this project or workspace.
24
+ 2. Open `/` and confirm the starter content renders correctly.
25
+ 3. Check `config/site.ts`, `app/page.tsx`, and `app/globals.css` together before making large copy or layout changes.
@@ -0,0 +1,37 @@
1
+ # Agent Guide
2
+
3
+ This file is the local routing guide for AI agents working inside a generated BrightWeb site app.
4
+
5
+ It is intentionally app-scoped. It explains the generated project you are in, not the maintainer-only BrightWeb monorepo internals.
6
+
7
+ ## Project shape
8
+
9
+ This app is a normal Next.js App Router project with a local UI layer and light configuration.
10
+
11
+ - `app/`: route tree, layouts, and the starter landing page.
12
+ - `components/ui/`: local UI primitives used by the starter surface.
13
+ - `config/site.ts`: generated site identity, description, and CTA defaults.
14
+ - `lib/`: helper utilities such as class merging.
15
+
16
+ ## Fast routing map
17
+
18
+ - `docs/ai/app-context.json`: machine-readable summary of this app's template, starter routes, and first-read files.
19
+ - `docs/ai/examples.md`: common setup and customization workflows.
20
+ - `README.md`: first-run setup steps.
21
+ - `config/site.ts`: site name, description, eyebrow, and starter CTA links.
22
+ - `app/page.tsx`: starter composition for the home page.
23
+ - `app/globals.css`: theme tokens, layout defaults, and base typography.
24
+ - `components/ui/*`: local component primitives used by the starter.
25
+
26
+ ## Editing strategy
27
+
28
+ - Change `config/site.ts` first when the task is mostly copy or link updates.
29
+ - Change `app/page.tsx` first when the task is about page structure or section flow.
30
+ - Change `app/globals.css` and `components/ui/*` when the task affects the visual system.
31
+ - Keep changes local to this app unless the task explicitly requires a shared BrightWeb package.
32
+
33
+ ## Validation checklist
34
+
35
+ 1. Run the app locally.
36
+ 2. Validate `/` on desktop and mobile sizes.
37
+ 3. If you changed the visual system, check both `app/globals.css` and the affected `components/ui/*` files.
@@ -0,0 +1,35 @@
1
+ # Agent Examples
2
+
3
+ Use these workflows after reading `AGENTS.md`, `docs/ai/README.md`, and `docs/ai/app-context.json`.
4
+
5
+ ## First local setup
6
+
7
+ Goal: get the generated site starter running and ready for edits.
8
+
9
+ - Run the local dev server for this app or workspace.
10
+ - Open `/` and confirm the starter renders correctly.
11
+ - Review `config/site.ts`, `app/page.tsx`, and `app/globals.css` before making large changes.
12
+
13
+ ## Change site identity
14
+
15
+ Goal: update the starter name, description, and CTA links.
16
+
17
+ - Edit `config/site.ts`.
18
+ - Validate `/` after the change.
19
+ - If copy still exists outside the config file, update `app/page.tsx`.
20
+
21
+ ## Restyle the starter
22
+
23
+ Goal: change the visual language without rewriting everything at once.
24
+
25
+ - Start in `app/globals.css` for colors, spacing, and typography direction.
26
+ - Update `components/ui/*` if shared primitives need to change.
27
+ - Validate `/` on both desktop and mobile sizes.
28
+
29
+ ## Replace the starter sections
30
+
31
+ Goal: turn the scaffold into a real site.
32
+
33
+ - Edit `app/page.tsx` section by section.
34
+ - Keep shared button, badge, and card behavior in `components/ui/*`.
35
+ - Remove starter content only after the replacement section is in place.