create-blitzpack 0.1.15 → 0.1.17

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 (2) hide show
  1. package/dist/index.js +526 -6
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -555,7 +555,11 @@ import fs from "fs-extra";
555
555
  import { downloadTemplate } from "giget";
556
556
  import path2 from "path";
557
557
  var GITHUB_REPO = "github:CarboxyDev/blitzpack";
558
- var POST_DOWNLOAD_EXCLUDES = ["create-blitzpack", "apps/marketing"];
558
+ var POST_DOWNLOAD_EXCLUDES = [
559
+ "create-blitzpack",
560
+ "apps/marketing",
561
+ "CONTRIBUTING.md"
562
+ ];
559
563
  function getFeatureExclusions(features) {
560
564
  const exclusions = [];
561
565
  for (const [key, enabled] of Object.entries(features)) {
@@ -610,6 +614,353 @@ async function countFiles(dir) {
610
614
  // src/transform.ts
611
615
  import fs2 from "fs-extra";
612
616
  import path3 from "path";
617
+
618
+ // src/agent-doc-template.ts
619
+ var AGENT_DOC_TEMPLATE = `# CLAUDE.md
620
+
621
+ You are a Senior Full-stack Developer and an Expert in TypeScript, Next.js 16, React 19, Fastify, Prisma v7, PostgreSQL, TailwindCSS v5, and shadcn/ui. You are collaborating with a human developer on a production-ready full-stack application.
622
+
623
+ ---
624
+
625
+ ## Critical Requirements & Constraints
626
+
627
+ ### Forbidden Behaviors
628
+
629
+ - NEVER create markdown files unless the user explicitly asks for it. This is very important
630
+ - NEVER create \`index.ts\` barrel files. This is a strict requirement
631
+ - AVOID writing comments in code unless absolutely necessary for non-obvious edge cases
632
+
633
+ ### Workflow Requirements
634
+
635
+ - Make sure you aggressively prefer planning and waiting for user confirmation before writing code for medium to big tasks. This is a strict requirement
636
+ - If you are unsure about anything, ask the user for clarification. This is a strict requirement
637
+ - Prefer using commands or exec scripts (like \`pnpm dlx\`) for setup related tasks instead of making all the files manually. In case the command requires interactive input, ask the user to do it themselves and provide them with suitable guidance
638
+
639
+ ### Collaboration Principles
640
+
641
+ - Always be unbiased towards the code, the user's preference and opinions. If you do not agree with the user, make it clear with them. Treat them like a peer
642
+ - Always mention alternative approaches to the user if you think it's necessary
643
+ - Do not be afraid of hurting the user's feelings or making them feel bad about their skills. Having well-written and maintainable code is significantly more important than cozying up to the user
644
+ - Always give a brief and compact summary of all the changes done
645
+
646
+ ---
647
+
648
+ ## Common Commands
649
+
650
+ ### Development Commands
651
+
652
+ \`\`\`bash
653
+ pnpm dev
654
+ pnpm build
655
+ pnpm typecheck
656
+ pnpm lint
657
+ \`\`\`
658
+
659
+ <!-- @feature testing -->
660
+ \`\`\`bash
661
+ pnpm test
662
+ pnpm test:unit
663
+ pnpm test:integration
664
+ \`\`\`
665
+ <!-- @endfeature -->
666
+
667
+ ### Individual Package Commands
668
+
669
+ \`\`\`bash
670
+ # Web (Next.js on port 3000)
671
+ cd apps/web
672
+ pnpm dev
673
+ pnpm typecheck
674
+
675
+ # API (Fastify on port 8080)
676
+ cd apps/api
677
+ pnpm dev
678
+ pnpm start
679
+ \`\`\`
680
+
681
+ ### Database Commands (run from \`apps/api\`)
682
+
683
+ \`\`\`bash
684
+ pnpm db:generate # Generate Prisma Client
685
+ pnpm db:migrate # Create and apply migrations
686
+ pnpm db:push # Push schema changes (no migration files)
687
+ pnpm db:studio # Open Prisma Studio UI
688
+ pnpm db:seed # Seed database
689
+ \`\`\`
690
+
691
+ ---
692
+
693
+ ## Coding Standards
694
+
695
+ ### Code Style
696
+
697
+ - Type Definitions: Prefer \`interface\` for public-facing types and object shapes, \`type\` for unions, intersections, and computed types
698
+ - Use descriptive variable names with auxiliary verbs (\`isLoading\`, \`hasError\`, \`canSubmit\`)
699
+ - Favor default exports for pages and named exports for utilities or functions
700
+ - **IMPORTANT**: Always use import aliases for files in apps. For packages, use relative imports.
701
+
702
+ ### Error Handling
703
+
704
+ - Use our custom error classes from \`packages/utils/src/errors.ts\`
705
+ - Provide user-friendly error messages and avoid leaking implementation details
706
+
707
+ ---
708
+
709
+ ## Project Architecture
710
+
711
+ ### Packages
712
+
713
+ - All packages (\`@repo/packages-types\`, \`@repo/packages-utils\`) are consumed directly as TypeScript source files
714
+ - No build or watch required for these packages
715
+
716
+ ### Environment
717
+
718
+ - Environment variables are managed per-app with Zod validation
719
+ - Web: Only \`NEXT_PUBLIC_*\` variables are exposed to the browser
720
+ - Prisma CLI commands are wrapped with \`dotenv-cli\` to read from \`.env.local\`
721
+
722
+ ### Database
723
+
724
+ - The API uses Prisma 7 as the ORM with PostgreSQL
725
+ - Prisma queries are automatically logged based on \`LOG_LEVEL\`
726
+
727
+ ### Type Safety & Validation
728
+
729
+ - The codebase emphasizes runtime and compile-time type safety with **Zod v4 as the single validation library** across the entire stack
730
+ - No class-validator
731
+
732
+ <!-- @feature testing -->
733
+ ### Testing
734
+
735
+ Unit Tests: \`*.spec.ts\`
736
+ Integration Tests: \`*.integration.spec.ts\`
737
+ <!-- @endfeature -->
738
+
739
+ ### Authentication
740
+
741
+ - Uses Better Auth
742
+ - When creating users with password auth, set \`accountId\` to the user's email (not user.id)
743
+
744
+ ---
745
+
746
+ ## Web Architecture Patterns
747
+
748
+ ### State Management
749
+
750
+ - TanStack Query (React Query): For API calls and data synchronization
751
+ - Jotai: For client-side global state (UI state, user preferences)
752
+
753
+ ### API Integration
754
+
755
+ - API config centralized in \`apps/web/src/lib/api.ts\`
756
+ - **API Response Unwrapping**: The \`api.ts\` fetcher unwraps \`{ data: T }\` to \`T\` but preserves \`{ data: T[], pagination: {...} }\` responses intact
757
+
758
+ ### Authentication & Protected Routes
759
+
760
+ The web app uses Better Auth for authentication with modern patterns:
761
+
762
+ - **Auth Client**: Configured in \`apps/web/src/lib/auth.ts\`
763
+ - Provides \`useSession()\` hook for accessing current user/session
764
+ - Handles sign in/out, session persistence via cookies
765
+ - **Protected Routes**: \`<ProtectedRoute>\` wrapper component for page-level protection
766
+
767
+ ### UI Component Patterns
768
+
769
+ - Use Shadcn UI components as base, extend them before creating custom ones
770
+ - Implement thoughtful micro-interactions and hover states wherever needed
771
+ - Use Framer Motion for animations, Lucide React for icons
772
+ - Prefer using \`Skeleton\` components for loading states instead of spinners (especially for data fetching components)
773
+ - Always create a proper loading state for data fetching components.
774
+ - Always use \`cn\` helper for dynamic classnames
775
+ - Never write svg code. Always use existing icons from code or Lucide.
776
+
777
+ ---
778
+
779
+ ## API Architecture Patterns
780
+
781
+ ### Fastify Structure
782
+
783
+ - The Fastify API follows a plugin-based architecture
784
+ - Validation: Zod schemas directly in route definitions via \`fastify-type-provider-zod\`
785
+ - Dependency Injection: Manual DI via Fastify decorators
786
+
787
+ ### Logging
788
+
789
+ - The API uses Pino for structured logging with request tracing
790
+ - Verbosity controlled by \`LOG_LEVEL\` env var: \`minimal\` | \`normal\` | \`detailed\` | \`verbose\`
791
+ - **IMPORTANT**: Never use \`console.log\` in the API. Use the logger service instead
792
+
793
+ **Log Methods:**
794
+
795
+ - \`logger.info(message, context?)\` - Standard information
796
+ - \`logger.error(message, error?, context?)\` - Errors with automatic Error serialization
797
+ - \`logger.warn(message, context?)\` - Warnings
798
+ - \`logger.debug(message, context?)\` - Debug information (detailed+ level)
799
+ - \`logger.trace(message, context?)\` - Trace logs (verbose level only)
800
+ - \`logger.perf(message, metrics)\` - Performance metrics
801
+ `;
802
+
803
+ // src/ci-workflow-template.ts
804
+ var CI_WORKFLOW_TEMPLATE = `name: CI
805
+
806
+ on:
807
+ push:
808
+ branches: [main, development]
809
+ pull_request:
810
+ branches: [main, development]
811
+
812
+ # Cancel in-progress runs when a new commit is pushed
813
+ concurrency:
814
+ group: \${{ github.workflow }}-\${{ github.ref }}
815
+ cancel-in-progress: true
816
+
817
+ jobs:
818
+ # Fast checks that can run in parallel
819
+ lint:
820
+ runs-on: ubuntu-latest
821
+ steps:
822
+ - uses: actions/checkout@v4
823
+
824
+ - name: Setup pnpm
825
+ uses: pnpm/action-setup@v4
826
+
827
+ - name: Setup Node.js
828
+ uses: actions/setup-node@v4
829
+ with:
830
+ node-version: '20'
831
+ cache: 'pnpm'
832
+
833
+ - name: Install dependencies
834
+ run: pnpm install --frozen-lockfile
835
+
836
+ - name: Run lint
837
+ run: pnpm run lint
838
+
839
+ typecheck:
840
+ runs-on: ubuntu-latest
841
+ steps:
842
+ - uses: actions/checkout@v4
843
+
844
+ - name: Setup pnpm
845
+ uses: pnpm/action-setup@v4
846
+
847
+ - name: Setup Node.js
848
+ uses: actions/setup-node@v4
849
+ with:
850
+ node-version: '20'
851
+ cache: 'pnpm'
852
+
853
+ - name: Install dependencies
854
+ run: pnpm install --frozen-lockfile
855
+
856
+ - name: Run typecheck
857
+ run: pnpm run typecheck
858
+ env:
859
+ DATABASE_URL: postgresql://user:pass@localhost:5432/db
860
+
861
+ # @feature testing
862
+ # Tests and build run after lint/typecheck pass
863
+ test:
864
+ runs-on: ubuntu-latest
865
+ needs: [lint, typecheck]
866
+
867
+ # PostgreSQL service for integration tests
868
+ services:
869
+ postgres:
870
+ image: postgres:17-alpine
871
+ env:
872
+ POSTGRES_USER: postgres
873
+ POSTGRES_PASSWORD: postgres
874
+ POSTGRES_DB: app_dev_test
875
+ POSTGRES_HOST_AUTH_METHOD: trust
876
+ options: >-
877
+ --health-cmd "pg_isready -U postgres"
878
+ --health-interval 10s
879
+ --health-timeout 5s
880
+ --health-retries 5
881
+ ports:
882
+ - 5432:5432
883
+
884
+ env:
885
+ NODE_ENV: test
886
+ DATABASE_URL: postgresql://postgres:postgres@localhost:5432/app_dev
887
+ API_URL: http://localhost:8080
888
+ FRONTEND_URL: http://localhost:3000
889
+ PORT: 8080
890
+ LOG_LEVEL: minimal
891
+ COOKIE_SECRET: test-cookie-secret-for-ci
892
+ BETTER_AUTH_SECRET: test-secret-minimum-32-characters-long-for-ci
893
+ BETTER_AUTH_URL: http://localhost:8080
894
+
895
+ steps:
896
+ - uses: actions/checkout@v4
897
+
898
+ - name: Setup pnpm
899
+ uses: pnpm/action-setup@v4
900
+
901
+ - name: Setup Node.js
902
+ uses: actions/setup-node@v4
903
+ with:
904
+ node-version: '20'
905
+ cache: 'pnpm'
906
+
907
+ - name: Install dependencies
908
+ run: pnpm install --frozen-lockfile
909
+
910
+ - name: Generate Prisma Client
911
+ run: cd apps/api && npx prisma generate
912
+
913
+ - name: Run tests
914
+ run: pnpm run test
915
+ # @endfeature
916
+
917
+ build:
918
+ runs-on: ubuntu-latest
919
+ needs: [lint, typecheck]
920
+ steps:
921
+ - uses: actions/checkout@v4
922
+
923
+ - name: Setup pnpm
924
+ uses: pnpm/action-setup@v4
925
+
926
+ - name: Setup Node.js
927
+ uses: actions/setup-node@v4
928
+ with:
929
+ node-version: '20'
930
+ cache: 'pnpm'
931
+
932
+ - name: Install dependencies
933
+ run: pnpm install --frozen-lockfile
934
+
935
+ - name: Generate Prisma Client
936
+ run: pnpm --filter @repo/api db:generate
937
+ env:
938
+ DATABASE_URL: postgresql://user:pass@localhost:5432/db
939
+
940
+ - name: Setup Turborepo cache
941
+ uses: actions/cache@v4
942
+ with:
943
+ path: .turbo
944
+ key: \${{ runner.os }}-turbo-\${{ github.sha }}
945
+ restore-keys: |
946
+ \${{ runner.os }}-turbo-
947
+
948
+ - name: Build
949
+ run: pnpm run build
950
+ env:
951
+ NODE_ENV: production
952
+ API_URL: 'http://localhost:8080'
953
+ FRONTEND_URL: 'http://localhost:3000'
954
+ DATABASE_URL: 'postgresql://user:pass@localhost:5432/db'
955
+ PORT: '8080'
956
+ LOG_LEVEL: 'minimal'
957
+ COOKIE_SECRET: 'ci-test-secret-not-for-production'
958
+ BETTER_AUTH_SECRET: 'test-secret-minimum-32-characters-long-for-ci'
959
+ BETTER_AUTH_URL: 'http://localhost:8080'
960
+ NEXT_PUBLIC_API_URL: 'http://localhost:8080/api'
961
+ `;
962
+
963
+ // src/transform.ts
613
964
  var TESTING_SCRIPTS = [
614
965
  "test",
615
966
  "test:unit",
@@ -628,6 +979,16 @@ var TESTING_ROOT_DEVDEPS = [
628
979
  ];
629
980
  var TESTING_APP_DEVDEPS = ["vitest", "vite-tsconfig-paths"];
630
981
  var UPLOADS_API_DEPS = ["@aws-sdk/client-s3", "sharp"];
982
+ var TESTING_DIR_NAMES = /* @__PURE__ */ new Set(["__tests__", "test", "tests"]);
983
+ var TESTING_FILE_PATTERNS = [
984
+ /\.test\.[^/]+$/i,
985
+ /\.spec\.[^/]+$/i,
986
+ /^vitest(?:\.[^.]+)*\.(?:[cm]?[jt]sx?)$/i,
987
+ /^test-config\.(?:[cm]?[jt]sx?)$/i
988
+ ];
989
+ var TS_CONFIG_FILE_PATTERN = /^tsconfig(?:\.[^.]+)?\.json$/;
990
+ var AGENT_DOC_TARGETS = ["CLAUDE.md", "AGENTS.md"];
991
+ var CI_WORKFLOW_RELATIVE_PATH = ".github/workflows/ci.yml";
631
992
  var MARKER_FILES = [
632
993
  "apps/api/src/app.ts",
633
994
  "apps/api/src/plugins/services.ts",
@@ -637,22 +998,23 @@ function stripFeatureBlocks(content, disabledFeatures) {
637
998
  const lines = content.split("\n");
638
999
  const result = [];
639
1000
  let skipUntilEnd = false;
640
- let currentFeature = null;
641
1001
  for (const line of lines) {
642
- const featureStart = line.match(/\/\/\s*@feature\s+(\w+)/);
643
- const featureEnd = line.match(/\/\/\s*@endfeature/);
1002
+ const featureStart = line.match(
1003
+ /^\s*(?:\/\/|#|<!--)\s*@feature\s+(\w+)\s*(?:-->)?\s*$/
1004
+ );
1005
+ const featureEnd = line.match(
1006
+ /^\s*(?:\/\/|#|<!--)\s*@endfeature\s*(?:-->)?\s*$/
1007
+ );
644
1008
  if (featureStart) {
645
1009
  const feature = featureStart[1];
646
1010
  if (disabledFeatures.includes(feature)) {
647
1011
  skipUntilEnd = true;
648
- currentFeature = feature;
649
1012
  }
650
1013
  continue;
651
1014
  }
652
1015
  if (featureEnd) {
653
1016
  if (skipUntilEnd) {
654
1017
  skipUntilEnd = false;
655
- currentFeature = null;
656
1018
  }
657
1019
  continue;
658
1020
  }
@@ -800,6 +1162,8 @@ async function applyFeatureTransforms(targetDir, features) {
800
1162
  if (!features.testing) disabledFeatures.push("testing");
801
1163
  if (!features.admin) disabledFeatures.push("admin");
802
1164
  if (!features.uploads) disabledFeatures.push("uploads");
1165
+ if (!features.dockerDeploy) disabledFeatures.push("dockerDeploy");
1166
+ if (!features.ciCd) disabledFeatures.push("ciCd");
803
1167
  for (const relativePath of MARKER_FILES) {
804
1168
  const filePath = path3.join(targetDir, relativePath);
805
1169
  if (await fs2.pathExists(filePath)) {
@@ -812,8 +1176,13 @@ async function applyFeatureTransforms(targetDir, features) {
812
1176
  if (!features.testing) {
813
1177
  await transformForNoTesting(targetDir);
814
1178
  }
1179
+ await transformCiWorkflow(targetDir, disabledFeatures);
1180
+ await transformAgentDocs(targetDir, disabledFeatures);
815
1181
  }
816
1182
  async function transformForNoTesting(targetDir) {
1183
+ await removeTestingArtifacts(targetDir);
1184
+ await stripTestingFromWorkspacePackageJson(targetDir);
1185
+ await stripTestingFromTsConfigs(targetDir);
817
1186
  const turboPath = path3.join(targetDir, "turbo.json");
818
1187
  if (await fs2.pathExists(turboPath)) {
819
1188
  const content = await fs2.readFile(turboPath, "utf-8");
@@ -823,6 +1192,7 @@ async function transformForNoTesting(targetDir) {
823
1192
  delete turbo.tasks?.["test:integration"];
824
1193
  delete turbo.tasks?.["test:watch"];
825
1194
  delete turbo.tasks?.["test:coverage"];
1195
+ delete turbo.tasks?.["test:parallel"];
826
1196
  await fs2.writeFile(turboPath, JSON.stringify(turbo, null, 2) + "\n");
827
1197
  }
828
1198
  const huskyPath = path3.join(targetDir, ".husky/pre-push");
@@ -830,6 +1200,156 @@ async function transformForNoTesting(targetDir) {
830
1200
  await fs2.writeFile(huskyPath, "pnpm typecheck\n");
831
1201
  }
832
1202
  }
1203
+ function isTestingDependency(name) {
1204
+ return name === "vitest" || name.startsWith("@vitest/") || name.startsWith("@testing-library/") || name === "jsdom" || name === "vite-tsconfig-paths";
1205
+ }
1206
+ function isTestingIncludeEntry(value) {
1207
+ return value.includes("__tests__") || value.includes("/test") || value.includes("test/") || value.includes("tests/") || value.includes(".test.") || value.includes(".spec.");
1208
+ }
1209
+ async function removeTestingArtifacts(currentDir) {
1210
+ const entries = await fs2.readdir(currentDir);
1211
+ for (const entry of entries) {
1212
+ if (entry === ".git" || entry === "node_modules") {
1213
+ continue;
1214
+ }
1215
+ const fullPath = path3.join(currentDir, entry);
1216
+ const stat = await fs2.stat(fullPath);
1217
+ if (stat.isDirectory()) {
1218
+ if (TESTING_DIR_NAMES.has(entry)) {
1219
+ await fs2.remove(fullPath);
1220
+ continue;
1221
+ }
1222
+ await removeTestingArtifacts(fullPath);
1223
+ continue;
1224
+ }
1225
+ if (TESTING_FILE_PATTERNS.some((pattern) => pattern.test(entry))) {
1226
+ await fs2.remove(fullPath);
1227
+ }
1228
+ }
1229
+ }
1230
+ async function stripTestingFromWorkspacePackageJson(currentDir) {
1231
+ const entries = await fs2.readdir(currentDir);
1232
+ for (const entry of entries) {
1233
+ if (entry === ".git" || entry === "node_modules") {
1234
+ continue;
1235
+ }
1236
+ const fullPath = path3.join(currentDir, entry);
1237
+ const stat = await fs2.stat(fullPath);
1238
+ if (stat.isDirectory()) {
1239
+ await stripTestingFromWorkspacePackageJson(fullPath);
1240
+ continue;
1241
+ }
1242
+ if (entry !== "package.json") {
1243
+ continue;
1244
+ }
1245
+ const content = await fs2.readFile(fullPath, "utf-8");
1246
+ const pkg = JSON.parse(content);
1247
+ let changed = false;
1248
+ if (pkg.scripts && typeof pkg.scripts === "object") {
1249
+ for (const scriptName of Object.keys(pkg.scripts)) {
1250
+ if (scriptName === "test" || scriptName.startsWith("test:")) {
1251
+ delete pkg.scripts[scriptName];
1252
+ changed = true;
1253
+ }
1254
+ }
1255
+ }
1256
+ const dependencySections = [
1257
+ "dependencies",
1258
+ "devDependencies",
1259
+ "peerDependencies",
1260
+ "optionalDependencies"
1261
+ ];
1262
+ for (const section of dependencySections) {
1263
+ if (!pkg[section] || typeof pkg[section] !== "object") {
1264
+ continue;
1265
+ }
1266
+ for (const depName of Object.keys(pkg[section])) {
1267
+ if (isTestingDependency(depName)) {
1268
+ delete pkg[section][depName];
1269
+ changed = true;
1270
+ }
1271
+ }
1272
+ }
1273
+ if ("vitest" in pkg) {
1274
+ delete pkg.vitest;
1275
+ changed = true;
1276
+ }
1277
+ if (changed) {
1278
+ await fs2.writeFile(fullPath, JSON.stringify(pkg, null, 2) + "\n");
1279
+ }
1280
+ }
1281
+ }
1282
+ async function stripTestingFromTsConfigs(currentDir) {
1283
+ const entries = await fs2.readdir(currentDir);
1284
+ for (const entry of entries) {
1285
+ if (entry === ".git" || entry === "node_modules") {
1286
+ continue;
1287
+ }
1288
+ const fullPath = path3.join(currentDir, entry);
1289
+ const stat = await fs2.stat(fullPath);
1290
+ if (stat.isDirectory()) {
1291
+ await stripTestingFromTsConfigs(fullPath);
1292
+ continue;
1293
+ }
1294
+ if (!TS_CONFIG_FILE_PATTERN.test(entry)) {
1295
+ continue;
1296
+ }
1297
+ const content = await fs2.readFile(fullPath, "utf-8");
1298
+ const tsconfig = JSON.parse(content);
1299
+ let changed = false;
1300
+ const compilerOptions = tsconfig.compilerOptions;
1301
+ if (compilerOptions && typeof compilerOptions === "object") {
1302
+ if (Array.isArray(compilerOptions.types)) {
1303
+ const nextTypes = compilerOptions.types.filter(
1304
+ (value) => typeof value === "string" && !value.includes("vitest") && !value.includes("@testing-library")
1305
+ );
1306
+ if (nextTypes.length !== compilerOptions.types.length) {
1307
+ compilerOptions.types = nextTypes;
1308
+ changed = true;
1309
+ }
1310
+ }
1311
+ if (compilerOptions.paths && typeof compilerOptions.paths === "object") {
1312
+ if ("@test/*" in compilerOptions.paths) {
1313
+ delete compilerOptions.paths["@test/*"];
1314
+ changed = true;
1315
+ }
1316
+ if ("@tests/*" in compilerOptions.paths) {
1317
+ delete compilerOptions.paths["@tests/*"];
1318
+ changed = true;
1319
+ }
1320
+ }
1321
+ }
1322
+ if (Array.isArray(tsconfig.include)) {
1323
+ const nextInclude = tsconfig.include.filter(
1324
+ (value) => typeof value === "string" && !isTestingIncludeEntry(value)
1325
+ );
1326
+ if (nextInclude.length !== tsconfig.include.length) {
1327
+ tsconfig.include = nextInclude;
1328
+ changed = true;
1329
+ }
1330
+ }
1331
+ if (changed) {
1332
+ await fs2.writeFile(fullPath, JSON.stringify(tsconfig, null, 2) + "\n");
1333
+ }
1334
+ }
1335
+ }
1336
+ async function transformAgentDocs(targetDir, disabledFeatures) {
1337
+ let content = stripFeatureBlocks(AGENT_DOC_TEMPLATE, disabledFeatures);
1338
+ content = cleanEmptyLines(content).trimEnd() + "\n";
1339
+ for (const fileName of AGENT_DOC_TARGETS) {
1340
+ const filePath = path3.join(targetDir, fileName);
1341
+ const heading = fileName === "AGENTS.md" ? "# AGENTS.md" : "# CLAUDE.md";
1342
+ const fileContent = content.replace(/^#\s+CLAUDE\.md/m, heading);
1343
+ await fs2.writeFile(filePath, fileContent, "utf-8");
1344
+ }
1345
+ }
1346
+ async function transformCiWorkflow(targetDir, disabledFeatures) {
1347
+ const workflowPath = path3.join(targetDir, CI_WORKFLOW_RELATIVE_PATH);
1348
+ await fs2.ensureDir(path3.dirname(workflowPath));
1349
+ let content = stripFeatureBlocks(CI_WORKFLOW_TEMPLATE, disabledFeatures);
1350
+ content = cleanEmptyLines(content).trimEnd() + "\n";
1351
+ await fs2.writeFile(workflowPath, content, "utf-8");
1352
+ }
833
1353
 
834
1354
  // src/commands/create.ts
835
1355
  var ENV_FILES = [
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "create-blitzpack",
3
- "version": "0.1.15",
3
+ "version": "0.1.17",
4
4
  "description": "Create a new Blitzpack project - full-stack TypeScript monorepo with Next.js and Fastify",
5
5
  "type": "module",
6
6
  "bin": {
7
- "create-blitzpack": "./dist/index.js"
7
+ "create-blitzpack": "dist/index.js"
8
8
  },
9
9
  "files": [
10
10
  "dist"
@@ -47,7 +47,7 @@
47
47
  "license": "MIT",
48
48
  "repository": {
49
49
  "type": "git",
50
- "url": "https://github.com/CarboxyDev/blitzpack"
50
+ "url": "git+https://github.com/CarboxyDev/blitzpack.git"
51
51
  },
52
52
  "homepage": "https://github.com/CarboxyDev/blitzpack",
53
53
  "engines": {