@codigodoleo/wp-kit 3.2.0 → 3.3.0

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 (64) hide show
  1. package/lib/core/infer-ci-capabilities.js +17 -0
  2. package/lib/prompts/index.js +3 -3
  3. package/modules/blank-theme/index.js +71 -0
  4. package/modules/blank-theme/lint/.prettierrc.json +12 -0
  5. package/modules/blank-theme/lint/.stylelintrc.json +7 -0
  6. package/modules/{lint → blank-theme/lint}/eslint.config.mjs +2 -8
  7. package/modules/blank-theme/lint/pint.json +11 -0
  8. package/modules/blank-theme/prompts.js +36 -0
  9. package/modules/blank-theme/templates/.lando.yml.hbs +26 -0
  10. package/modules/blank-theme/templates/functions.php.hbs +46 -0
  11. package/modules/blank-theme/templates/package.json.hbs +16 -0
  12. package/modules/blank-theme/templates/style.css.hbs +7 -0
  13. package/modules/blank-theme/templates/vite.config.js.hbs +23 -0
  14. package/modules/deploy/.github/workflows/deploy-docker.yml +2 -0
  15. package/modules/deploy/.github/workflows/deploy-ssh.yml +2 -0
  16. package/modules/deploy/.github/workflows/release.yml +2 -0
  17. package/modules/deploy/index.js +38 -0
  18. package/modules/deploy/templates/.github/workflows/ci.yml.hbs +29 -1
  19. package/modules/deploy/templates/.gitlab/ci/lint-blank-theme.yml.hbs +35 -0
  20. package/modules/deploy/templates/.gitlab/ci/lint-mu-plugin.yml.hbs +19 -0
  21. package/modules/deploy/templates/.gitlab/ci/lint-plugin.yml.hbs +19 -0
  22. package/modules/deploy/templates/.gitlab/ci/lint-sage.yml.hbs +47 -0
  23. package/modules/git/templates/workspace.json.hbs +1 -1
  24. package/modules/lint/.commitlintrc.json +21 -0
  25. package/modules/lint/.prettierignore +15 -25
  26. package/modules/lint/.prettierrc.json +5 -16
  27. package/modules/lint/index.js +75 -8
  28. package/modules/lint/prompts.js +1 -8
  29. package/modules/lint/templates/.lando.yml.hbs +3 -8
  30. package/modules/lint/templates/workspace.json.hbs +3 -3
  31. package/modules/mu-plugin/index.js +49 -0
  32. package/modules/mu-plugin/lint/.prettierrc.json +7 -0
  33. package/modules/mu-plugin/lint/eslint.config.mjs +30 -0
  34. package/modules/mu-plugin/lint/pint.json +11 -0
  35. package/modules/mu-plugin/prompts.js +29 -0
  36. package/modules/mu-plugin/templates/.lando.yml.hbs +15 -0
  37. package/modules/mu-plugin/templates/composer.json.hbs +14 -0
  38. package/modules/mu-plugin/templates/plugin.php.hbs +15 -0
  39. package/modules/php/templates/composer.json.hbs +15 -1
  40. package/modules/plugin/index.js +45 -0
  41. package/modules/plugin/lint/.prettierrc.json +7 -0
  42. package/modules/plugin/lint/eslint.config.mjs +30 -0
  43. package/modules/plugin/lint/pint.json +11 -0
  44. package/modules/plugin/prompts.js +29 -0
  45. package/modules/plugin/templates/.lando.yml.hbs +15 -0
  46. package/modules/plugin/templates/composer.json.hbs +14 -0
  47. package/modules/plugin/templates/plugin.php.hbs +15 -0
  48. package/modules/sage/index.js +25 -0
  49. package/modules/sage/lint/.prettierrc.json +12 -0
  50. package/modules/sage/lint/.stylelintrc.json +7 -0
  51. package/modules/sage/lint/eslint.config.mjs +30 -0
  52. package/modules/sage/lint/pint.json +11 -0
  53. package/modules/sage/prompts.js +21 -0
  54. package/modules/sage/templates/.lando.yml.hbs +13 -1
  55. package/modules/sage/templates/theme/vite.config.js.hbs +4 -4
  56. package/package.json +1 -1
  57. package/templates/.gitignore.hbs +84 -13
  58. package/templates/composer.json.hbs +60 -13
  59. package/templates/workspace.json.hbs +1 -1
  60. package/modules/lint/.eslintignore +0 -36
  61. package/modules/lint/.eslintrc.json +0 -8
  62. package/modules/lint/.stylelintignore +0 -19
  63. package/modules/lint/.stylelintrc.json +0 -9
  64. package/modules/lint/pint.json +0 -26
@@ -1,29 +1,18 @@
1
1
  {
2
2
  "semi": true,
3
3
  "singleQuote": true,
4
- "trailingComma": "es5",
5
4
  "tabWidth": 2,
6
5
  "printWidth": 100,
6
+ "trailingComma": "es5",
7
7
  "bracketSpacing": true,
8
- "arrowParens": "avoid",
9
8
  "overrides": [
10
9
  {
11
- "files": ["*.scss", "*.css", "*.sass"],
12
- "options": {
13
- "singleQuote": false
14
- }
15
- },
16
- {
17
- "files": ["*.json", "*.yml", "*.yaml"],
18
- "options": {
19
- "tabWidth": 2
20
- }
10
+ "files": ["*.yml", "*.yaml"],
11
+ "options": { "tabWidth": 2 }
21
12
  },
22
13
  {
23
- "files": "*.html",
24
- "options": {
25
- "htmlWhitespaceSensitivity": "ignore"
26
- }
14
+ "files": "*.md",
15
+ "options": { "proseWrap": "always" }
27
16
  }
28
17
  ]
29
18
  }
@@ -1,14 +1,81 @@
1
+ import path from 'path';
2
+
3
+ import fs from 'fs-extra';
4
+
5
+ /**
6
+ * Builds the lint-staged entries object from active development modules.
7
+ * Each dev module contributes globs pointing to its own directory.
8
+ */
9
+ function buildLintStagedEntries(context) {
10
+ const entries = {};
11
+
12
+ // Infra: YAML, JSON, Markdown at root (never touching module folders)
13
+ entries['*.{yml,yaml}'] = ['prettier --write'];
14
+ entries['*.{json,md}'] = ['prettier --write'];
15
+
16
+ // Sage
17
+ if (context.enable_sage) {
18
+ const dir = `content/themes/${context.projectName}`;
19
+ if (context.sage_lint_eslint !== false) {
20
+ entries[`${dir}/resources/**/*.{js,ts,vue,mjs}`] = ['eslint --fix'];
21
+ }
22
+ if (context.sage_lint_stylelint !== false) {
23
+ entries[`${dir}/resources/**/*.{css,scss}`] = ['stylelint --fix'];
24
+ }
25
+ if (context.sage_lint_pint !== false) {
26
+ entries[`${dir}/app/**/*.php`] = ['pint'];
27
+ }
28
+ }
29
+
30
+ // MU-Plugin
31
+ if (context.enable_mu_plugin) {
32
+ const dir = `content/mu-plugins/${context.mu_plugin_name || `${context.projectName}-core`}`;
33
+ if (context.mu_plugin_lint_eslint !== false) {
34
+ entries[`${dir}/resources/**/*.{js,ts}`] = ['eslint --fix'];
35
+ }
36
+ if (context.mu_plugin_lint_pint !== false) {
37
+ entries[`${dir}/src/**/*.php`] = ['pint'];
38
+ }
39
+ }
40
+
41
+ // Plugin
42
+ if (context.enable_plugin) {
43
+ const dir = `content/plugins/${context.plugin_name || `${context.projectName}-plugin`}`;
44
+ if (context.plugin_lint_eslint !== false) {
45
+ entries[`${dir}/resources/**/*.{js,ts}`] = ['eslint --fix'];
46
+ }
47
+ if (context.plugin_lint_pint !== false) {
48
+ entries[`${dir}/src/**/*.php`] = ['pint'];
49
+ }
50
+ }
51
+
52
+ // Blank Theme
53
+ if (context.enable_blank_theme) {
54
+ const dir = `content/themes/${context.blank_theme_name || `${context.projectName}-theme`}`;
55
+ if (context.blank_theme_lint_eslint !== false) {
56
+ entries[`${dir}/src/**/*.{js,ts}`] = ['eslint --fix'];
57
+ }
58
+ if (context.blank_theme_lint_stylelint !== false) {
59
+ entries[`${dir}/src/**/*.{css,scss}`] = ['stylelint --fix'];
60
+ }
61
+ if (context.blank_theme_lint_pint !== false) {
62
+ entries[`${dir}/src/**/*.php`] = ['pint'];
63
+ }
64
+ }
65
+
66
+ return entries;
67
+ }
68
+
1
69
  export async function setupModule(context, generator) {
2
- await generator.copyFile('eslint.config.mjs', 'lint');
3
- await generator.copyFile('.prettierrc.json', 'lint');
70
+ if (!context.enable_lint) return;
4
71
 
72
+ // Root developer tooling (always present when lint is enabled)
73
+ await generator.copyFile('.commitlintrc.json', 'lint');
5
74
  await generator.copyFile('.prettierrc.json', 'lint');
6
75
  await generator.copyFile('.prettierignore', 'lint');
7
76
 
8
- await generator.copyFile('pint.json', 'lint');
9
-
10
- if (context.enable_stylelint) {
11
- await generator.copyFile('.stylelintrc.json', 'lint');
12
- await generator.copyFile('.stylelintignore', 'lint');
13
- }
77
+ // Compose .lintstagedrc.json from active modules
78
+ const entries = buildLintStagedEntries(context);
79
+ const lintStagedPath = path.join(generator.cwd, '.lintstagedrc.json');
80
+ await fs.outputFile(lintStagedPath, JSON.stringify(entries, null, 2) + '\n');
14
81
  }
@@ -3,14 +3,7 @@ export default [
3
3
  {
4
4
  type: 'confirm',
5
5
  name: 'enable_lint',
6
- message: 'Enable linting and formatting tools (ESLint + Prettier)?',
6
+ message: 'Enable developer tooling (Husky, commitlint, Prettier for infra files)?',
7
7
  default: true,
8
8
  },
9
- {
10
- type: 'confirm',
11
- name: 'enable_stylelint',
12
- message: 'Include Stylelint config?',
13
- default: true,
14
- when: answers => answers.enable_lint,
15
- },
16
9
  ];
@@ -1,10 +1,5 @@
1
1
  tooling:
2
- eslint:
2
+ commitlint:
3
3
  service: appserver
4
- cmd: yarn eslint
5
- prettier:
6
- service: appserver
7
- cmd: yarn prettier
8
- stylelint:
9
- service: appserver
10
- cmd: yarn stylelint **/*.{css,scss,vue}
4
+ description: Validate commit message format
5
+ cmd: npx commitlint --edit
@@ -3,9 +3,9 @@
3
3
  "editor.defaultFormatter": "esbenp.prettier-vscode",
4
4
  "editor.formatOnSave": false,
5
5
  "editor.codeActionsOnSave": {
6
- "source.fixAll": true,
7
- "source.fixAll.eslint": true,
8
- "source.organizeImports": true
6
+ "source.fixAll": "explicit",
7
+ "source.fixAll.eslint": "explicit",
8
+ "source.organizeImports": "explicit"
9
9
  },
10
10
  "prettier.requireConfig": true,
11
11
  "prettier.useEditorConfig": true,
@@ -0,0 +1,49 @@
1
+ import path from 'path';
2
+
3
+ import fs from 'fs-extra';
4
+
5
+ import { log, color } from '../../lib/utils/logger.js';
6
+
7
+ export async function setupModule(context, generator) {
8
+ const pluginName = context.mu_plugin_name || `${context.projectName}-core`;
9
+ const pluginDir = `content/mu-plugins/${pluginName}`;
10
+ const absolutePluginDir = path.join(generator.cwd, pluginDir);
11
+
12
+ log(color.blue, `[mu-plugin] 📂 Scaffolding MU plugin: ${pluginDir}`);
13
+
14
+ // 1. Ensure directory exists
15
+ await fs.ensureDir(absolutePluginDir);
16
+
17
+ // 2. Generate main plugin entry file
18
+ await generator.generateFile(
19
+ 'plugin.php',
20
+ { ...context, mu_plugin_name: pluginName },
21
+ 'mu-plugin',
22
+ `${pluginDir}/${pluginName}.php`
23
+ );
24
+
25
+ // 3. Generate composer.json
26
+ await generator.generateFile(
27
+ 'composer.json',
28
+ { ...context, mu_plugin_name: pluginName },
29
+ 'mu-plugin',
30
+ `${pluginDir}/composer.json`
31
+ );
32
+
33
+ // 4. Create src/ scaffold
34
+ await fs.ensureFile(path.join(absolutePluginDir, 'src', '.gitkeep'));
35
+
36
+ // 5. Lint configs co-located in plugin — always installed (IDE/editor support)
37
+ log(color.blue, '[mu-plugin] 🔧 Installing lint configurations...');
38
+ await generator.copyFile('lint/.prettierrc.json', 'mu-plugin', `${pluginDir}/.prettierrc.json`);
39
+ await generator.copyFile('lint/pint.json', 'mu-plugin', `${pluginDir}/pint.json`);
40
+ if (context.mu_plugin_lint_eslint === true) {
41
+ await generator.copyFile(
42
+ 'lint/eslint.config.mjs',
43
+ 'mu-plugin',
44
+ `${pluginDir}/eslint.config.mjs`
45
+ );
46
+ }
47
+
48
+ log(color.green, `[mu-plugin] ✅ MU plugin scaffolded: ${pluginDir}`);
49
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "semi": true,
3
+ "singleQuote": true,
4
+ "trailingComma": "es5",
5
+ "printWidth": 100,
6
+ "tabWidth": 2
7
+ }
@@ -0,0 +1,30 @@
1
+ import js from '@eslint/js';
2
+ import eslintConfigPrettier from 'eslint-config-prettier/flat';
3
+ import prettierPlugin from 'eslint-plugin-prettier';
4
+ import globals from 'globals';
5
+
6
+ export default [
7
+ {
8
+ ignores: ['node_modules/**', 'vendor/**', 'dist/**'],
9
+ },
10
+ js.configs.recommended,
11
+ {
12
+ files: ['resources/**/*.{js,mjs,ts}'],
13
+ languageOptions: {
14
+ ecmaVersion: 2022,
15
+ sourceType: 'module',
16
+ globals: {
17
+ ...globals.browser,
18
+ ...globals.node,
19
+ },
20
+ },
21
+ plugins: {
22
+ prettier: prettierPlugin,
23
+ },
24
+ rules: {
25
+ 'prettier/prettier': 'error',
26
+ 'no-unused-vars': ['error', { argsIgnorePattern: '^_', varsIgnorePattern: '^_' }],
27
+ },
28
+ },
29
+ eslintConfigPrettier,
30
+ ];
@@ -0,0 +1,11 @@
1
+ {
2
+ "preset": "psr12",
3
+ "rules": {
4
+ "array_syntax": {
5
+ "syntax": "short"
6
+ },
7
+ "binary_operator_spaces": {
8
+ "default": "single_space"
9
+ }
10
+ }
11
+ }
@@ -0,0 +1,29 @@
1
+ export default [
2
+ {
3
+ type: 'confirm',
4
+ name: 'enable_mu_plugin',
5
+ message: 'Enable MU Plugin scaffold?',
6
+ default: false,
7
+ },
8
+ {
9
+ type: 'input',
10
+ name: 'mu_plugin_name',
11
+ message: 'MU Plugin slug (used as directory name):',
12
+ default: (answers) => `${answers.projectName || 'wordpress'}-core`,
13
+ when: (answers) => answers.enable_mu_plugin,
14
+ },
15
+ {
16
+ type: 'confirm',
17
+ name: 'mu_plugin_lint_pint',
18
+ message: 'MU Plugin: enable Pint for PHP?',
19
+ default: true,
20
+ when: (answers) => answers.enable_mu_plugin && answers.enable_lint,
21
+ },
22
+ {
23
+ type: 'confirm',
24
+ name: 'mu_plugin_lint_eslint',
25
+ message: 'MU Plugin: enable ESLint for JS/TS?',
26
+ default: false,
27
+ when: (answers) => answers.enable_mu_plugin && answers.enable_lint,
28
+ },
29
+ ];
@@ -0,0 +1,15 @@
1
+ tooling:
2
+ {{#if enable_lint}}
3
+ mu-pint:
4
+ service: appserver
5
+ description: Lint PHP in the MU plugin
6
+ dir: /app/content/mu-plugins/{{mu_plugin_name}}
7
+ cmd: ./vendor/bin/pint
8
+ {{#if mu_plugin_lint_eslint}}
9
+ mu-eslint:
10
+ service: build
11
+ description: Lint JS/TS in the MU plugin
12
+ dir: /app/content/mu-plugins/{{mu_plugin_name}}
13
+ cmd: npx eslint --fix resources/
14
+ {{/if}}
15
+ {{/if}}
@@ -0,0 +1,14 @@
1
+ {
2
+ "description": "{{projectDescription}} — MU Plugin",
3
+ "autoload": {
4
+ "psr-4": {
5
+ "App\\MuPlugins\\": "src/"
6
+ }
7
+ },
8
+ "require-dev": {
9
+ "laravel/pint": "^1.21"
10
+ },
11
+ "scripts": {
12
+ "lint": ["./vendor/bin/pint --test"]
13
+ }
14
+ }
@@ -0,0 +1,15 @@
1
+ <?php
2
+ /**
3
+ * Plugin Name: {{mu_plugin_name}}
4
+ * Description: {{projectDescription}}
5
+ * Version: {{projectVersion}}
6
+ */
7
+
8
+ if (!defined('ABSPATH')) {
9
+ exit;
10
+ }
11
+
12
+ // Autoload via Composer
13
+ if (file_exists(__DIR__ . '/vendor/autoload.php')) {
14
+ require_once __DIR__ . '/vendor/autoload.php';
15
+ }
@@ -1 +1,15 @@
1
- { "require-dev": { "laravel/pint": "^1.29", "phpunit/phpunit": "^11.5", "phpstan/phpstan": "^2.1", "phpstan/extension-installer": "^1.4", "szepeviktor/phpstan-wordpress": "^2.0", "php-stubs/wordpress-stubs": "^6.8" }, "config": { "allow-plugins": { "phpstan/extension-installer": true } } }
1
+ {
2
+ "require-dev": {
3
+ "laravel/pint": "^1.29",
4
+ "phpunit/phpunit": "^12.5",
5
+ "phpstan/phpstan": "^2.1",
6
+ "phpstan/extension-installer": "^1.4",
7
+ "szepeviktor/phpstan-wordpress": "^2.0",
8
+ "php-stubs/wordpress-stubs": "^6.8"
9
+ },
10
+ "config": {
11
+ "allow-plugins": {
12
+ "phpstan/extension-installer": true
13
+ }
14
+ }
15
+ }
@@ -0,0 +1,45 @@
1
+ import path from 'path';
2
+
3
+ import fs from 'fs-extra';
4
+
5
+ import { log, color } from '../../lib/utils/logger.js';
6
+
7
+ export async function setupModule(context, generator) {
8
+ const pluginName = context.plugin_name || `${context.projectName}-plugin`;
9
+ const pluginDir = `content/plugins/${pluginName}`;
10
+ const absolutePluginDir = path.join(generator.cwd, pluginDir);
11
+
12
+ log(color.blue, `[plugin] 📂 Scaffolding plugin: ${pluginDir}`);
13
+
14
+ // 1. Ensure directory exists
15
+ await fs.ensureDir(absolutePluginDir);
16
+
17
+ // 2. Generate main plugin entry file
18
+ await generator.generateFile(
19
+ 'plugin.php',
20
+ { ...context, plugin_name: pluginName },
21
+ 'plugin',
22
+ `${pluginDir}/${pluginName}.php`
23
+ );
24
+
25
+ // 3. Generate composer.json
26
+ await generator.generateFile(
27
+ 'composer.json',
28
+ { ...context, plugin_name: pluginName },
29
+ 'plugin',
30
+ `${pluginDir}/composer.json`
31
+ );
32
+
33
+ // 4. Create src/ scaffold
34
+ await fs.ensureFile(path.join(absolutePluginDir, 'src', '.gitkeep'));
35
+
36
+ // 5. Lint configs co-located in plugin — always installed (IDE/editor support)
37
+ log(color.blue, '[plugin] 🔧 Installing lint configurations...');
38
+ await generator.copyFile('lint/.prettierrc.json', 'plugin', `${pluginDir}/.prettierrc.json`);
39
+ await generator.copyFile('lint/pint.json', 'plugin', `${pluginDir}/pint.json`);
40
+ if (context.plugin_lint_eslint === true) {
41
+ await generator.copyFile('lint/eslint.config.mjs', 'plugin', `${pluginDir}/eslint.config.mjs`);
42
+ }
43
+
44
+ log(color.green, `[plugin] ✅ Plugin scaffolded: ${pluginDir}`);
45
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "semi": true,
3
+ "singleQuote": true,
4
+ "trailingComma": "es5",
5
+ "printWidth": 100,
6
+ "tabWidth": 2
7
+ }
@@ -0,0 +1,30 @@
1
+ import js from '@eslint/js';
2
+ import eslintConfigPrettier from 'eslint-config-prettier/flat';
3
+ import prettierPlugin from 'eslint-plugin-prettier';
4
+ import globals from 'globals';
5
+
6
+ export default [
7
+ {
8
+ ignores: ['node_modules/**', 'vendor/**', 'dist/**'],
9
+ },
10
+ js.configs.recommended,
11
+ {
12
+ files: ['resources/**/*.{js,mjs,ts}'],
13
+ languageOptions: {
14
+ ecmaVersion: 2022,
15
+ sourceType: 'module',
16
+ globals: {
17
+ ...globals.browser,
18
+ ...globals.node,
19
+ },
20
+ },
21
+ plugins: {
22
+ prettier: prettierPlugin,
23
+ },
24
+ rules: {
25
+ 'prettier/prettier': 'error',
26
+ 'no-unused-vars': ['error', { argsIgnorePattern: '^_', varsIgnorePattern: '^_' }],
27
+ },
28
+ },
29
+ eslintConfigPrettier,
30
+ ];
@@ -0,0 +1,11 @@
1
+ {
2
+ "preset": "psr12",
3
+ "rules": {
4
+ "array_syntax": {
5
+ "syntax": "short"
6
+ },
7
+ "binary_operator_spaces": {
8
+ "default": "single_space"
9
+ }
10
+ }
11
+ }
@@ -0,0 +1,29 @@
1
+ export default [
2
+ {
3
+ type: 'confirm',
4
+ name: 'enable_plugin',
5
+ message: 'Enable Plugin scaffold?',
6
+ default: false,
7
+ },
8
+ {
9
+ type: 'input',
10
+ name: 'plugin_name',
11
+ message: 'Plugin slug (used as directory name):',
12
+ default: (answers) => `${answers.projectName || 'wordpress'}-plugin`,
13
+ when: (answers) => answers.enable_plugin,
14
+ },
15
+ {
16
+ type: 'confirm',
17
+ name: 'plugin_lint_pint',
18
+ message: 'Plugin: enable Pint for PHP?',
19
+ default: true,
20
+ when: (answers) => answers.enable_plugin && answers.enable_lint,
21
+ },
22
+ {
23
+ type: 'confirm',
24
+ name: 'plugin_lint_eslint',
25
+ message: 'Plugin: enable ESLint for JS/TS?',
26
+ default: false,
27
+ when: (answers) => answers.enable_plugin && answers.enable_lint,
28
+ },
29
+ ];
@@ -0,0 +1,15 @@
1
+ tooling:
2
+ {{#if enable_lint}}
3
+ plugin-pint:
4
+ service: appserver
5
+ description: Lint PHP in the plugin
6
+ dir: /app/content/plugins/{{plugin_name}}
7
+ cmd: ./vendor/bin/pint
8
+ {{#if plugin_lint_eslint}}
9
+ plugin-eslint:
10
+ service: build
11
+ description: Lint JS/TS in the plugin
12
+ dir: /app/content/plugins/{{plugin_name}}
13
+ cmd: npx eslint --fix resources/
14
+ {{/if}}
15
+ {{/if}}
@@ -0,0 +1,14 @@
1
+ {
2
+ "description": "{{projectDescription}} — Plugin",
3
+ "autoload": {
4
+ "psr-4": {
5
+ "App\\Plugins\\": "src/"
6
+ }
7
+ },
8
+ "require-dev": {
9
+ "laravel/pint": "^1.21"
10
+ },
11
+ "scripts": {
12
+ "lint": ["./vendor/bin/pint --test"]
13
+ }
14
+ }
@@ -0,0 +1,15 @@
1
+ <?php
2
+ /**
3
+ * Plugin Name: {{plugin_name}}
4
+ * Description: {{projectDescription}}
5
+ * Version: {{projectVersion}}
6
+ */
7
+
8
+ if (!defined('ABSPATH')) {
9
+ exit;
10
+ }
11
+
12
+ // Autoload via Composer
13
+ if (file_exists(__DIR__ . '/vendor/autoload.php')) {
14
+ require_once __DIR__ . '/vendor/autoload.php';
15
+ }
@@ -175,6 +175,31 @@ export async function setupModule(context, generator) {
175
175
  mergeStrategy: 'replace',
176
176
  });
177
177
 
178
+ // 8. Lint configs co-located in theme — always installed (IDE/editor support)
179
+ log(color.blue, '[sage] 🔧 Installing lint configurations...');
180
+ await generator.copyFile(
181
+ 'lint/.prettierrc.json',
182
+ 'sage',
183
+ `${relativeThemeDir}/.prettierrc.json`
184
+ );
185
+ if (context.sage_lint_eslint !== false) {
186
+ await generator.copyFile(
187
+ 'lint/eslint.config.mjs',
188
+ 'sage',
189
+ `${relativeThemeDir}/eslint.config.mjs`
190
+ );
191
+ }
192
+ if (context.sage_lint_pint !== false) {
193
+ await generator.copyFile('lint/pint.json', 'sage', `${relativeThemeDir}/pint.json`);
194
+ }
195
+ if (context.sage_lint_stylelint !== false) {
196
+ await generator.copyFile(
197
+ 'lint/.stylelintrc.json',
198
+ 'sage',
199
+ `${relativeThemeDir}/.stylelintrc.json`
200
+ );
201
+ }
202
+
178
203
  log(color.green, '[sage] ✅ Advanced Sage setup completed successfully');
179
204
  log(color.green, `[sage] ✅ Theme directory: ${relativeThemeDir}`);
180
205
  log(color.green, '[sage] ✅ Lando + Devcontainer command parity enabled');
@@ -0,0 +1,12 @@
1
+ {
2
+ "semi": true,
3
+ "singleQuote": true,
4
+ "trailingComma": "es5",
5
+ "printWidth": 100,
6
+ "tabWidth": 2,
7
+ "overrides": [
8
+ { "files": "*.blade.php", "options": { "parser": "html" } },
9
+ { "files": "*.vue", "options": { "parser": "vue" } },
10
+ { "files": "*.scss", "options": { "singleQuote": false } }
11
+ ]
12
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "extends": ["stylelint-config-standard-scss"],
3
+ "rules": {
4
+ "color-hex-length": "short",
5
+ "string-quotes": "double"
6
+ }
7
+ }
@@ -0,0 +1,30 @@
1
+ import js from '@eslint/js';
2
+ import eslintConfigPrettier from 'eslint-config-prettier/flat';
3
+ import prettierPlugin from 'eslint-plugin-prettier';
4
+ import globals from 'globals';
5
+
6
+ export default [
7
+ {
8
+ ignores: ['node_modules/**', 'vendor/**', 'public/build/**'],
9
+ },
10
+ js.configs.recommended,
11
+ {
12
+ files: ['resources/**/*.{js,mjs,ts,vue}'],
13
+ languageOptions: {
14
+ ecmaVersion: 2022,
15
+ sourceType: 'module',
16
+ globals: {
17
+ ...globals.browser,
18
+ ...globals.node,
19
+ },
20
+ },
21
+ plugins: {
22
+ prettier: prettierPlugin,
23
+ },
24
+ rules: {
25
+ 'prettier/prettier': 'error',
26
+ 'no-unused-vars': ['error', { argsIgnorePattern: '^_', varsIgnorePattern: '^_' }],
27
+ },
28
+ },
29
+ eslintConfigPrettier,
30
+ ];
@@ -0,0 +1,11 @@
1
+ {
2
+ "preset": "psr12",
3
+ "rules": {
4
+ "array_syntax": {
5
+ "syntax": "short"
6
+ },
7
+ "binary_operator_spaces": {
8
+ "default": "single_space"
9
+ }
10
+ }
11
+ }
@@ -13,4 +13,25 @@ export default [
13
13
  default: '11',
14
14
  when: (answers) => answers.enable_sage,
15
15
  },
16
+ {
17
+ type: 'confirm',
18
+ name: 'sage_lint_eslint',
19
+ message: 'Sage: enable ESLint for JS/TS/Vue?',
20
+ default: true,
21
+ when: (answers) => answers.enable_sage && answers.enable_lint,
22
+ },
23
+ {
24
+ type: 'confirm',
25
+ name: 'sage_lint_stylelint',
26
+ message: 'Sage: enable Stylelint for CSS/SCSS?',
27
+ default: true,
28
+ when: (answers) => answers.enable_sage && answers.enable_lint,
29
+ },
30
+ {
31
+ type: 'confirm',
32
+ name: 'sage_lint_pint',
33
+ message: 'Sage: enable Pint for PHP?',
34
+ default: true,
35
+ when: (answers) => answers.enable_sage && answers.enable_lint,
36
+ },
16
37
  ];