create-alistt69-kit 0.3.1 โ†’ 0.3.2

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
@@ -38,6 +38,7 @@ It generates a ready-to-run **React + TypeScript + Webpack** starter with a prac
38
38
  | [Stylelint](https://stylelint.io/) | Stylesheet linting | Optional |
39
39
  | [Autoprefixer](https://github.com/postcss/autoprefixer) | Automatic CSS vendor prefixes | Optional |
40
40
  | [React Router](https://reactrouter.com/) | Client-side routing | Optional |
41
+ | [AGENTS.md](https://agents.md/) | Root instructions file for AI coding agents | Optional |
41
42
  | [Puppeteer](https://pptr.dev/) + [serve-handler](https://github.com/vercel/serve-handler) | Static HTML prerender after production build | Optional |
42
43
 
43
44
  ## ๐ŸŽฏ Why use it?
@@ -166,14 +167,14 @@ npm create alistt69-kit@latest my-app -- --defaults --overwrite
166
167
 
167
168
  ## โš™๏ธ CLI options
168
169
 
169
- | Option | Alias | Description |
170
- |--------|--------|-------------|
171
- | `--defaults` | `-def` | Skip prompts, use defaults |
172
- | `--overwrite` | โ€” | Overwrite target directory if it exists |
173
- | `--no-install` | โ€” | Skip dependency installation |
174
- | `--features <list>` | โ€” | Enable specific features (`eslint`, `react-router`, `all`) |
175
- | `--pm <name>` | โ€” | Choose package manager (`npm`, `pnpm`, `yarn`) |
176
- | `--help` | `-h` | Show help |
170
+ | Option | Alias | Description |
171
+ |---------------------|--------|-------------|
172
+ | `--defaults` | `-def` | Skip prompts, use defaults |
173
+ | `--overwrite` | โ€” | Overwrite target directory if it exists |
174
+ | `--no-install` | โ€” | Skip dependency installation |
175
+ | `--features <list>` | โ€” | Enable specific features (`agents-md`, `eslint`, `stylelint`, `autoprefixer`, `react-router`, `prerender`) |
176
+ | `--pm <name>` | โ€” | Choose package manager (`npm`, `pnpm`, `yarn`) |
177
+ | `--help` | `-h` | Show help |
177
178
 
178
179
  ## ๐Ÿงช Default behavior
179
180
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-alistt69-kit",
3
- "version": "0.3.1",
3
+ "version": "0.3.2",
4
4
  "description": "Opinionated React + TypeScript + Webpack project generator by alistt69",
5
5
  "keywords": [
6
6
  "create",
@@ -31,7 +31,7 @@ export function formatHelpMessage() {
31
31
  ' -def, --defaults Skip prompts and use defaults',
32
32
  ' --overwrite Overwrite target directory if it exists',
33
33
  ' --no-install Do not install dependencies',
34
- ' --features <comma-list> Example: eslint,stylelint,react-router,prerender',
34
+ ' --features <comma-list> Example: agents-md,eslint,stylelint,react-router,prerender',
35
35
  ' --features all Enable all features',
36
36
  ' --pm <npm|pnpm|yarn> Package manager',
37
37
  ' -h, --help Show help',
@@ -150,6 +150,17 @@ function formatProjectStructure(selectedFeatureIds) {
150
150
  function formatFeatureSpecificSections({ selectedFeatureIds, packageManager }) {
151
151
  const sections = [];
152
152
 
153
+ if (selectedFeatureIds.includes('agents-md')) {
154
+ sections.push([
155
+ '## AGENTS.md',
156
+ '',
157
+ 'When `AGENTS.md` is enabled, the project includes a root instruction file for AI coding agents.',
158
+ '',
159
+ '- Base file: `AGENTS.md`',
160
+ '- Other selected features may append their own sections into this file automatically during scaffolding.',
161
+ ].join('\n'));
162
+ }
163
+
153
164
  if (selectedFeatureIds.includes('react-router')) {
154
165
  sections.push([
155
166
  '## Page generator',
@@ -0,0 +1,37 @@
1
+ # AGENTS.md
2
+
3
+ ## Overview
4
+
5
+ This project was scaffolded with `create-alistt69-kit`.
6
+
7
+ ## Setup
8
+
9
+ - Install dependencies with the selected package manager.
10
+ - Start dev server with `npm run start`.
11
+ - Type-check with `npm run typecheck`.
12
+
13
+ ## Base stack
14
+
15
+ - React
16
+ - TypeScript
17
+ - Webpack
18
+ - SCSS Modules
19
+
20
+ ## General rules
21
+
22
+ - Keep code readable and explicit.
23
+ - Prefer small targeted changes over broad refactors.
24
+ - Do not rename public files or exported symbols unless required.
25
+ - Reuse existing project structure and conventions.
26
+
27
+ ## Validation
28
+
29
+ Before finishing a task, run the relevant checks available in `package.json`.
30
+
31
+ ## Project structure
32
+
33
+ - `src/app/` โ€” app bootstrap and providers
34
+ - `src/styles/` โ€” global styles
35
+ - `config/build/` โ€” webpack config parts
36
+
37
+ <!-- @agents-sections -->
@@ -0,0 +1,14 @@
1
+ import { dirname, resolve } from 'node:path';
2
+ import { fileURLToPath } from 'node:url';
3
+
4
+ import { defineFeature } from '../define-feature.js';
5
+
6
+ const currentFilePath = fileURLToPath(import.meta.url);
7
+ const currentDirPath = dirname(currentFilePath);
8
+
9
+ export const agentsMdFeature = defineFeature({
10
+ id: 'agents-md',
11
+ title: 'AGENTS.md',
12
+ hint: 'Root instructions file for AI coding agents',
13
+ copyFiles: resolve(currentDirPath, 'files'),
14
+ });
@@ -2,6 +2,7 @@ import { dirname, resolve } from 'node:path';
2
2
  import { fileURLToPath } from 'node:url';
3
3
 
4
4
  import { defineFeature } from '../define-feature.js';
5
+ import { appendAgentsSection } from '../../utils/agents-md.js';
5
6
 
6
7
  const currentFilePath = fileURLToPath(import.meta.url);
7
8
  const currentDirPath = dirname(currentFilePath);
@@ -16,4 +17,16 @@ export const autoprefixerFeature = defineFeature({
16
17
  },
17
18
  },
18
19
  copyFiles: resolve(currentDirPath, 'files'),
20
+ async apply({ projectPath }) {
21
+ await appendAgentsSection(
22
+ projectPath,
23
+ 'autoprefixer',
24
+ `
25
+ ## CSS compatibility
26
+
27
+ - Vendor prefixing is handled by Autoprefixer.
28
+ - Do not add manual prefixes unless there is a confirmed need.
29
+ `,
30
+ );
31
+ },
19
32
  });
@@ -2,6 +2,7 @@ import { dirname, resolve } from 'node:path';
2
2
  import { fileURLToPath } from 'node:url';
3
3
 
4
4
  import { defineFeature } from '../define-feature.js';
5
+ import { appendAgentsSection } from '../../utils/agents-md.js';
5
6
 
6
7
  const currentFilePath = fileURLToPath(import.meta.url);
7
8
  const currentDirPath = dirname(currentFilePath);
@@ -27,4 +28,17 @@ export const eslintFeature = defineFeature({
27
28
  },
28
29
  },
29
30
  copyFiles: resolve(currentDirPath, 'files'),
31
+ async apply({ projectPath }) {
32
+ await appendAgentsSection(
33
+ projectPath,
34
+ 'eslint',
35
+ `
36
+ ## ESLint
37
+
38
+ - Lint code with \`npm run lint\`.
39
+ - Apply safe autofixes with \`npm run lint:fix\`.
40
+ - Prefer fixing root-cause issues instead of disabling rules.
41
+ `,
42
+ );
43
+ },
30
44
  });
@@ -1,3 +1,4 @@
1
+ import { agentsMdFeature } from './agents-md/index.js';
1
2
  import { autoprefixerFeature } from './autoprefixer/index.js';
2
3
  import { eslintFeature } from './eslint/index.js';
3
4
  import { prerenderFeature } from './prerender/index.js';
@@ -5,6 +6,7 @@ import { reactRouterFeature } from './react-router/index.js';
5
6
  import { stylelintFeature } from './stylelint/index.js';
6
7
 
7
8
  export const features = [
9
+ agentsMdFeature,
8
10
  autoprefixerFeature,
9
11
  eslintFeature,
10
12
  prerenderFeature,
@@ -2,6 +2,7 @@ import { dirname, resolve } from 'node:path';
2
2
  import { fileURLToPath } from 'node:url';
3
3
 
4
4
  import { defineFeature } from '../define-feature.js';
5
+ import { appendAgentsSection } from '../../utils/agents-md.js';
5
6
 
6
7
  const currentFilePath = fileURLToPath(import.meta.url);
7
8
  const currentDirPath = dirname(currentFilePath);
@@ -16,10 +17,25 @@ export const prerenderFeature = defineFeature({
16
17
  'serve-handler': '^6.1.6',
17
18
  },
18
19
  scripts: {
20
+ build: 'npm run build:assets && npm run prerender',
19
21
  'build:assets': 'webpack --env mode=production',
22
+ 'build:prod': 'npm run build',
20
23
  prerender: 'node ./scripts/prerender.mjs',
21
- build: 'npm run build:assets && npm run prerender',
22
24
  },
23
25
  },
24
26
  copyFiles: resolve(currentDirPath, 'files'),
27
+ async apply({ projectPath }) {
28
+ await appendAgentsSection(
29
+ projectPath,
30
+ 'prerender',
31
+ `
32
+ ## Prerender
33
+
34
+ - Production build runs in two steps: \`npm run build:assets\` then \`npm run prerender\`.
35
+ - Prerender route manifest lives in \`prerender.routes.mjs\`.
36
+ - Prerender script lives in \`scripts/prerender.mjs\`.
37
+ - When adding static routes, keep \`prerender.routes.mjs\` updated.
38
+ `,
39
+ );
40
+ },
25
41
  });
@@ -2,6 +2,7 @@ import { dirname, resolve } from 'node:path';
2
2
  import { fileURLToPath } from 'node:url';
3
3
 
4
4
  import { defineFeature } from '../define-feature.js';
5
+ import { appendAgentsSection } from '../../utils/agents-md.js';
5
6
 
6
7
  const currentFilePath = fileURLToPath(import.meta.url);
7
8
  const currentDirPath = dirname(currentFilePath);
@@ -19,4 +20,18 @@ export const reactRouterFeature = defineFeature({
19
20
  },
20
21
  },
21
22
  copyFiles: resolve(currentDirPath, 'files'),
23
+ async apply({ projectPath }) {
24
+ await appendAgentsSection(
25
+ projectPath,
26
+ 'react-router',
27
+ `
28
+ ## React Router
29
+
30
+ - Routing is configured under \`src/app/providers/router/\`.
31
+ - Route-level pages live in \`src/pages/\`.
32
+ - Generate a new page with \`npm run generate:page -- <page-name>\`.
33
+ - Do not remove router marker comments used by the page generator unless you also disable auto-registration.
34
+ `,
35
+ );
36
+ },
22
37
  });
@@ -2,6 +2,7 @@ import { dirname, resolve } from 'node:path';
2
2
  import { fileURLToPath } from 'node:url';
3
3
 
4
4
  import { defineFeature } from '../define-feature.js';
5
+ import { appendAgentsSection } from '../../utils/agents-md.js';
5
6
 
6
7
  const currentFilePath = fileURLToPath(import.meta.url);
7
8
  const currentDirPath = dirname(currentFilePath);
@@ -21,4 +22,17 @@ export const stylelintFeature = defineFeature({
21
22
  },
22
23
  },
23
24
  copyFiles: resolve(currentDirPath, 'files'),
25
+ async apply({ projectPath }) {
26
+ await appendAgentsSection(
27
+ projectPath,
28
+ 'stylelint',
29
+ `
30
+ ## Stylelint
31
+
32
+ - Lint styles with \`npm run lint:styles\`.
33
+ - Apply autofixes with \`npm run lint:styles:fix\`.
34
+ - Keep styles compatible with the existing SCSS modules setup.
35
+ `,
36
+ );
37
+ },
24
38
  });
@@ -0,0 +1,53 @@
1
+ import { access, readFile, writeFile } from 'node:fs/promises';
2
+ import { resolve } from 'node:path';
3
+
4
+ const AGENTS_MD_PATH = 'AGENTS.md';
5
+ const SECTIONS_MARKER = '<!-- @agents-sections -->';
6
+
7
+ export function getAgentsMdPath(projectPath) {
8
+ return resolve(projectPath, AGENTS_MD_PATH);
9
+ }
10
+
11
+ export async function hasAgentsMd(projectPath) {
12
+ try {
13
+ await access(getAgentsMdPath(projectPath));
14
+ return true;
15
+ } catch (_) {
16
+ return false;
17
+ }
18
+ }
19
+
20
+ export async function appendAgentsSection(projectPath, sectionKey, content) {
21
+ if (!(await hasAgentsMd(projectPath))) {
22
+ return false;
23
+ }
24
+
25
+ const filepath = getAgentsMdPath(projectPath);
26
+ const fileContent = await readFile(filepath, 'utf8');
27
+
28
+ if (fileContent.includes(`<!-- @agents:${sectionKey} -->`)) {
29
+ return false;
30
+ }
31
+
32
+ const block = [
33
+ `<!-- @agents:${sectionKey} -->`,
34
+ content.trim(),
35
+ `<!-- /@agents:${sectionKey} -->`,
36
+ ].join('\n');
37
+
38
+ let nextContent;
39
+
40
+ if (fileContent.includes(SECTIONS_MARKER)) {
41
+ nextContent = fileContent.replace(
42
+ SECTIONS_MARKER,
43
+ `${block}\n\n${SECTIONS_MARKER}`,
44
+ );
45
+ } else {
46
+ const trimmed = fileContent.trimEnd();
47
+ nextContent = `${trimmed}\n\n${block}\n`;
48
+ }
49
+
50
+ await writeFile(filepath, nextContent, 'utf8');
51
+
52
+ return true;
53
+ }