@codigodoleo/wp-kit 3.1.1 → 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.
- package/lib/commands/init.js +19 -10
- package/lib/config/versions.js +5 -5
- package/lib/core/infer-ci-capabilities.js +17 -0
- package/lib/prompts/index.js +27 -17
- package/lib/utils/git.js +50 -13
- package/modules/blank-theme/index.js +71 -0
- package/modules/blank-theme/lint/.prettierrc.json +12 -0
- package/modules/blank-theme/lint/.stylelintrc.json +7 -0
- package/modules/{lint → blank-theme/lint}/eslint.config.mjs +2 -8
- package/modules/blank-theme/lint/pint.json +11 -0
- package/modules/blank-theme/prompts.js +36 -0
- package/modules/blank-theme/templates/.lando.yml.hbs +26 -0
- package/modules/blank-theme/templates/functions.php.hbs +46 -0
- package/modules/blank-theme/templates/package.json.hbs +16 -0
- package/modules/blank-theme/templates/style.css.hbs +7 -0
- package/modules/blank-theme/templates/vite.config.js.hbs +23 -0
- package/modules/deploy/.github/workflows/deploy-docker.yml +104 -0
- package/modules/deploy/.github/workflows/deploy-ssh.yml +128 -0
- package/modules/deploy/.github/workflows/release.yml +57 -0
- package/modules/deploy/index.js +77 -0
- package/modules/deploy/prompts.js +1 -3
- package/modules/deploy/templates/.github/workflows/ci.yml.hbs +29 -1
- package/modules/deploy/templates/.gitlab/ci/deploy-docker.yml.hbs +35 -0
- package/modules/deploy/templates/.gitlab/ci/deploy-ssh.yml.hbs +83 -0
- package/modules/deploy/templates/.gitlab/ci/lint-blank-theme.yml.hbs +35 -0
- package/modules/deploy/templates/.gitlab/ci/lint-mu-plugin.yml.hbs +19 -0
- package/modules/deploy/templates/.gitlab/ci/lint-plugin.yml.hbs +19 -0
- package/modules/deploy/templates/.gitlab/ci/lint-sage.yml.hbs +47 -0
- package/modules/deploy/templates/.gitlab/ci/release.yml.hbs +26 -0
- package/modules/git/.husky/commit-msg +8 -4
- package/modules/git/.husky/pre-commit +0 -3
- package/modules/git/templates/package.json.hbs +4 -4
- package/modules/git/templates/workspace.json.hbs +1 -1
- package/modules/lint/.commitlintrc.json +21 -0
- package/modules/lint/.prettierignore +15 -25
- package/modules/lint/.prettierrc.json +5 -16
- package/modules/lint/index.js +75 -8
- package/modules/lint/prompts.js +1 -8
- package/modules/lint/templates/.lando.yml.hbs +3 -8
- package/modules/lint/templates/package.json.hbs +4 -4
- package/modules/lint/templates/workspace.json.hbs +3 -3
- package/modules/mu-plugin/index.js +49 -0
- package/modules/mu-plugin/lint/.prettierrc.json +7 -0
- package/modules/mu-plugin/lint/eslint.config.mjs +30 -0
- package/modules/mu-plugin/lint/pint.json +11 -0
- package/modules/mu-plugin/prompts.js +29 -0
- package/modules/mu-plugin/templates/.lando.yml.hbs +15 -0
- package/modules/mu-plugin/templates/composer.json.hbs +14 -0
- package/modules/mu-plugin/templates/plugin.php.hbs +15 -0
- package/modules/php/templates/composer.json.hbs +15 -1
- package/modules/plugin/index.js +45 -0
- package/modules/plugin/lint/.prettierrc.json +7 -0
- package/modules/plugin/lint/eslint.config.mjs +30 -0
- package/modules/plugin/lint/pint.json +11 -0
- package/modules/plugin/prompts.js +29 -0
- package/modules/plugin/templates/.lando.yml.hbs +15 -0
- package/modules/plugin/templates/composer.json.hbs +14 -0
- package/modules/plugin/templates/plugin.php.hbs +15 -0
- package/modules/sage/index.js +139 -15
- package/modules/sage/lint/.prettierrc.json +12 -0
- package/modules/sage/lint/.stylelintrc.json +7 -0
- package/modules/sage/lint/eslint.config.mjs +30 -0
- package/modules/sage/lint/pint.json +11 -0
- package/modules/sage/prompts.js +22 -1
- package/modules/sage/templates/.devcontainer/devcontainer.json.hbs +7 -0
- package/modules/sage/templates/.devcontainer/docker-compose.override.yml.hbs +6 -0
- package/modules/sage/templates/.devcontainer/post-create.sh.hbs +11 -0
- package/modules/sage/templates/.lando.yml.hbs +43 -45
- package/modules/sage/templates/server/cmd/setup-sage-node.sh.hbs +23 -0
- package/modules/sage/templates/server/cmd/setup-sage-php.sh.hbs +24 -0
- package/modules/sage/templates/theme/app/Blocks/.gitkeep.hbs +0 -0
- package/modules/sage/templates/theme/app/Fields/.gitkeep.hbs +0 -0
- package/modules/sage/templates/theme/composer.json.hbs +25 -3
- package/modules/sage/templates/theme/package.json.hbs +15 -3
- package/modules/sage/templates/theme/resources/views/blocks/.gitkeep.hbs +0 -0
- package/modules/sage/templates/theme/vite.config.js.hbs +55 -13
- package/modules/sage/templates/workspace.json.hbs +94 -6
- package/modules/skills/index.js +18 -0
- package/modules/skills/prompts.js +21 -0
- package/modules/test/index.js +19 -0
- package/modules/test/prompts.js +8 -0
- package/modules/test/templates/composer.json.hbs +16 -0
- package/modules/test/templates/package.json.hbs +11 -0
- package/modules/test/templates/playwright.config.js.hbs +29 -0
- package/modules/test/tests/Pest.php +39 -0
- package/modules/test/tests/SmokeTest.php +15 -0
- package/modules/test/tests/e2e/example.spec.js +11 -0
- package/modules/test/tests/e2e/helpers/loginHelper.js +40 -0
- package/package.json +1 -1
- package/templates/.devcontainer/Dockerfile.hbs +24 -0
- package/templates/.devcontainer/config/nginx.conf +23 -0
- package/templates/.devcontainer/config/nginx.conf.hbs +23 -0
- package/templates/.devcontainer/devcontainer.json.hbs +29 -0
- package/templates/.devcontainer/docker-compose.yml.hbs +73 -0
- package/templates/.devcontainer/setup.sh.hbs +17 -0
- package/templates/.env.hbs +38 -15
- package/templates/.gitignore.hbs +84 -13
- package/templates/.lando.yml.hbs +61 -17
- package/templates/README.md.hbs +23 -7
- package/templates/composer.json.hbs +60 -12
- package/templates/package.json.hbs +0 -2
- package/templates/server/cmd/install-wp.sh.hbs +54 -43
- package/templates/server/cmd/setup-node.sh.hbs +11 -0
- package/templates/server/cmd/setup-php.sh.hbs +14 -0
- package/templates/server/www/vhosts.conf.hbs +54 -17
- package/templates/workspace.json.hbs +57 -1
- package/templates/wp-cli.yml.hbs +1 -0
- package/modules/lint/.eslintignore +0 -36
- package/modules/lint/.eslintrc.json +0 -8
- package/modules/lint/.stylelintignore +0 -19
- package/modules/lint/.stylelintrc.json +0 -9
- package/modules/lint/pint.json +0 -26
package/lib/commands/init.js
CHANGED
|
@@ -9,7 +9,6 @@ import { Generator } from '../core/generator.js';
|
|
|
9
9
|
import { log, color } from '../utils/logger.js';
|
|
10
10
|
import { inferCiCapabilities } from '../core/infer-ci-capabilities.js';
|
|
11
11
|
import { validateVersionCompatibility } from '../config/versions.js';
|
|
12
|
-
import { installSuperpowersSage } from '../utils/git.js';
|
|
13
12
|
|
|
14
13
|
const __filename = fileURLToPath(import.meta.url);
|
|
15
14
|
const __dirname = path.dirname(__filename);
|
|
@@ -20,12 +19,11 @@ export const initCommand = new Command('init')
|
|
|
20
19
|
.option('--debug', 'Ativa modo debug para logs detalhados')
|
|
21
20
|
.action(async ({ output, defaults, debug }) => {
|
|
22
21
|
const target = path.resolve(output);
|
|
23
|
-
const { enabledModules, ...context } = await runPrompts({ defaults });
|
|
22
|
+
const { enabledModules: promptedModules, ...context } = await runPrompts({ defaults });
|
|
23
|
+
let enabledModules = [...promptedModules];
|
|
24
24
|
|
|
25
25
|
// Normalização de chaves para consistência entre módulos
|
|
26
|
-
|
|
27
|
-
context.useSage = true;
|
|
28
|
-
}
|
|
26
|
+
context.useSage = context.enable_sage === true;
|
|
29
27
|
if (context.git_provider && !context.gitProvider) {
|
|
30
28
|
context.gitProvider = context.git_provider;
|
|
31
29
|
}
|
|
@@ -34,12 +32,12 @@ export const initCommand = new Command('init')
|
|
|
34
32
|
if (context.useSage && context.sageVersion === '11') {
|
|
35
33
|
context.phpVersion = '8.3';
|
|
36
34
|
context.nodeVersion = '22';
|
|
37
|
-
context.wpCoreVersion = '6.
|
|
35
|
+
context.wpCoreVersion = '6.9.4';
|
|
38
36
|
|
|
39
37
|
log(color.orange, '🔧 Sage 11 selected — automatically adjusting versions:');
|
|
40
38
|
log(color.orange, ' → PHP: 8.3');
|
|
41
39
|
log(color.orange, ' → Node: 22');
|
|
42
|
-
log(color.orange, ' → WP Core: 6.
|
|
40
|
+
log(color.orange, ' → WP Core: 6.9.4');
|
|
43
41
|
}
|
|
44
42
|
|
|
45
43
|
// 📋 Validar compatibilidade de versões (se Sage está habilitado)
|
|
@@ -71,6 +69,9 @@ export const initCommand = new Command('init')
|
|
|
71
69
|
if (context.ci.theme.paths.themeRoot) {
|
|
72
70
|
log(color.blue, ` → themeRoot: ${context.ci.theme.paths.themeRoot}`);
|
|
73
71
|
}
|
|
72
|
+
if (context.useSage) {
|
|
73
|
+
log(color.blue, ' → sageMode: advanced (automatic when Sage is enabled)');
|
|
74
|
+
}
|
|
74
75
|
|
|
75
76
|
const generator = new Generator(target);
|
|
76
77
|
await fs.ensureDir(target);
|
|
@@ -80,6 +81,13 @@ export const initCommand = new Command('init')
|
|
|
80
81
|
await generator.generateFile('.env', context);
|
|
81
82
|
await generator.generateFile('.editorconfig', context);
|
|
82
83
|
await generator.generateFile('server/cmd/install-wp.sh', context);
|
|
84
|
+
await generator.generateFile('server/cmd/setup-php.sh', context);
|
|
85
|
+
await generator.generateFile('server/cmd/setup-node.sh', context);
|
|
86
|
+
await generator.generateFile('.devcontainer/devcontainer.json', context);
|
|
87
|
+
await generator.generateFile('.devcontainer/docker-compose.yml', context);
|
|
88
|
+
await generator.generateFile('.devcontainer/Dockerfile', context);
|
|
89
|
+
await generator.generateFile('.devcontainer/setup.sh', context);
|
|
90
|
+
await generator.generateFile('.devcontainer/config/nginx.conf', context);
|
|
83
91
|
|
|
84
92
|
await generator.copyFile('.cspell.json');
|
|
85
93
|
|
|
@@ -93,6 +101,9 @@ export const initCommand = new Command('init')
|
|
|
93
101
|
|
|
94
102
|
await fs.chmod(path.join(target, 'content/uploads'), 0o777);
|
|
95
103
|
await fs.chmod(path.join(target, 'server/cmd/install-wp.sh'), 0o755);
|
|
104
|
+
await fs.chmod(path.join(target, 'server/cmd/setup-php.sh'), 0o755);
|
|
105
|
+
await fs.chmod(path.join(target, 'server/cmd/setup-node.sh'), 0o755);
|
|
106
|
+
await fs.chmod(path.join(target, '.devcontainer/setup.sh'), 0o755);
|
|
96
107
|
|
|
97
108
|
await generator.generateFile('server/www/vhosts.conf', context);
|
|
98
109
|
if (context.useRocket) {
|
|
@@ -101,6 +112,7 @@ export const initCommand = new Command('init')
|
|
|
101
112
|
|
|
102
113
|
await generator.copyFile('wp-config.php');
|
|
103
114
|
await generator.copyFile('index.php');
|
|
115
|
+
await generator.generateFile('wp-cli.yml', context);
|
|
104
116
|
|
|
105
117
|
log(color.blue, `🧩 Enabled modules: ${enabledModules.join(', ')}`);
|
|
106
118
|
|
|
@@ -154,8 +166,5 @@ export const initCommand = new Command('init')
|
|
|
154
166
|
// Gera CLAUDE.md com overview do projeto e referência ao AI Co-Pilot
|
|
155
167
|
await generator.generateFile('CLAUDE.md', context);
|
|
156
168
|
|
|
157
|
-
// Instala superpowers-sage em .claude/ do projeto gerado
|
|
158
|
-
await installSuperpowersSage(target);
|
|
159
|
-
|
|
160
169
|
log(color.green, '✅ Project initialized with templates.');
|
|
161
170
|
});
|
package/lib/config/versions.js
CHANGED
|
@@ -53,8 +53,8 @@ export const VERSION_REGISTRY = {
|
|
|
53
53
|
* Only actively supported versions per php.net
|
|
54
54
|
*/
|
|
55
55
|
php: {
|
|
56
|
-
latest: '8.
|
|
57
|
-
supported: ['8.3', '8.2', '8.1'],
|
|
56
|
+
latest: '8.4',
|
|
57
|
+
supported: ['8.4', '8.3', '8.2', '8.1'],
|
|
58
58
|
eol: ['8.0', '7.4', '7.3', '7.2'], // Deprecated - do not use
|
|
59
59
|
description: 'Supported PHP versions. PHP 7.4+ reached EOL on 2022-11-28',
|
|
60
60
|
// PHP version dates: https://www.php.net/supported-versions.php
|
|
@@ -70,9 +70,9 @@ export const VERSION_REGISTRY = {
|
|
|
70
70
|
* Tracks LTS and current stable releases
|
|
71
71
|
*/
|
|
72
72
|
node: {
|
|
73
|
-
latest: '
|
|
74
|
-
lts: ['22', '20', '18'],
|
|
75
|
-
all: ['22', '20', '18'],
|
|
73
|
+
latest: '24',
|
|
74
|
+
lts: ['24', '22', '20', '18'],
|
|
75
|
+
all: ['24', '22', '20', '18'],
|
|
76
76
|
deprecated: ['16', '14', '12', '10'],
|
|
77
77
|
description: 'Supported Node.js versions - prefer LTS releases',
|
|
78
78
|
// LTS information: https://nodejs.org/en/about/releases/
|
|
@@ -84,6 +84,23 @@ export function inferCiCapabilities(context) {
|
|
|
84
84
|
node: hasNode,
|
|
85
85
|
sage: hasSage,
|
|
86
86
|
},
|
|
87
|
+
lint: {
|
|
88
|
+
sage:
|
|
89
|
+
hasSage &&
|
|
90
|
+
Boolean(context.enable_lint) &&
|
|
91
|
+
(context.sage_lint_eslint !== false ||
|
|
92
|
+
context.sage_lint_pint !== false ||
|
|
93
|
+
context.sage_lint_stylelint !== false),
|
|
94
|
+
mu_plugin: Boolean(context.enable_mu_plugin && context.enable_lint),
|
|
95
|
+
plugin: Boolean(context.enable_plugin && context.enable_lint),
|
|
96
|
+
blank_theme: Boolean(context.enable_blank_theme && context.enable_lint),
|
|
97
|
+
any:
|
|
98
|
+
Boolean(context.enable_lint) &&
|
|
99
|
+
(hasSage ||
|
|
100
|
+
Boolean(context.enable_mu_plugin) ||
|
|
101
|
+
Boolean(context.enable_plugin) ||
|
|
102
|
+
Boolean(context.enable_blank_theme)),
|
|
103
|
+
},
|
|
87
104
|
deploy: {
|
|
88
105
|
docker: context.deploy_strategy === 'docker',
|
|
89
106
|
},
|
package/lib/prompts/index.js
CHANGED
|
@@ -6,6 +6,14 @@ import { Generator } from '../core/generator.js';
|
|
|
6
6
|
|
|
7
7
|
import { loadModulePrompts } from './loadModulePrompts.js';
|
|
8
8
|
|
|
9
|
+
function parseBooleanEnv(value) {
|
|
10
|
+
if (typeof value !== 'string') return null;
|
|
11
|
+
const normalized = value.trim().toLowerCase();
|
|
12
|
+
if (['1', 'true', 'yes', 'on'].includes(normalized)) return true;
|
|
13
|
+
if (['0', 'false', 'no', 'off'].includes(normalized)) return false;
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
|
|
9
17
|
export async function runPrompts({ defaults = false } = {}) {
|
|
10
18
|
const defaultsGit = getGitUserDefaults();
|
|
11
19
|
|
|
@@ -46,20 +54,7 @@ export async function runPrompts({ defaults = false } = {}) {
|
|
|
46
54
|
message: 'Repository URL:',
|
|
47
55
|
default: defaultsGit.gitRepository,
|
|
48
56
|
},
|
|
49
|
-
|
|
50
|
-
type: 'list',
|
|
51
|
-
name: 'phpVersion',
|
|
52
|
-
message: 'PHP version:',
|
|
53
|
-
choices: ['8.3', '8.2', '8.1'],
|
|
54
|
-
default: '8.3',
|
|
55
|
-
},
|
|
56
|
-
{
|
|
57
|
-
type: 'list',
|
|
58
|
-
name: 'nodeVersion',
|
|
59
|
-
message: 'Node.js version:',
|
|
60
|
-
choices: ['22', '20', '18'],
|
|
61
|
-
default: '22',
|
|
62
|
-
},
|
|
57
|
+
// phpVersion and nodeVersion are locked to '8.4' / '24' — injected into context, not prompted
|
|
63
58
|
{
|
|
64
59
|
type: 'list',
|
|
65
60
|
name: 'wpCoreVersion',
|
|
@@ -90,13 +85,26 @@ export async function runPrompts({ defaults = false } = {}) {
|
|
|
90
85
|
for (const prompt of allPrompts) {
|
|
91
86
|
if (prompt.when && !prompt.when(defaultAnswers)) continue;
|
|
92
87
|
const def = prompt.default;
|
|
93
|
-
defaultAnswers[prompt.name] = typeof def === 'function' ? def() : def;
|
|
88
|
+
defaultAnswers[prompt.name] = typeof def === 'function' ? def(defaultAnswers) : def;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const envEnableSage = parseBooleanEnv(process.env.WP_KIT_ENABLE_SAGE);
|
|
92
|
+
if (envEnableSage !== null) {
|
|
93
|
+
defaultAnswers.enable_sage = envEnableSage;
|
|
94
94
|
}
|
|
95
|
+
|
|
96
|
+
const envGitProvider = process.env.WP_KIT_GIT_PROVIDER;
|
|
97
|
+
if (envGitProvider) {
|
|
98
|
+
defaultAnswers.gitProvider = envGitProvider;
|
|
99
|
+
}
|
|
100
|
+
|
|
95
101
|
const enabledModules = Object.keys(modulePromptDefs).filter(
|
|
96
|
-
(mod) => defaultAnswers[`enable_${mod}`] === true
|
|
102
|
+
(mod) => defaultAnswers[`enable_${mod.replace(/-/g, '_')}`] === true
|
|
97
103
|
);
|
|
98
104
|
return {
|
|
99
105
|
...defaultAnswers,
|
|
106
|
+
phpVersion: '8.4',
|
|
107
|
+
nodeVersion: '24',
|
|
100
108
|
enabledModules,
|
|
101
109
|
projectDomain: `${defaultAnswers.projectName}.lndo.site`,
|
|
102
110
|
salts: Generator.generateSalts(),
|
|
@@ -106,10 +114,12 @@ export async function runPrompts({ defaults = false } = {}) {
|
|
|
106
114
|
const answers = await inquirer.prompt(allPrompts);
|
|
107
115
|
|
|
108
116
|
const enabledModules = Object.keys(modulePromptDefs).filter(
|
|
109
|
-
(mod) => answers[`enable_${mod}`] === true
|
|
117
|
+
(mod) => answers[`enable_${mod.replace(/-/g, '_')}`] === true
|
|
110
118
|
);
|
|
111
119
|
return {
|
|
112
120
|
...answers,
|
|
121
|
+
phpVersion: '8.4',
|
|
122
|
+
nodeVersion: '24',
|
|
113
123
|
enabledModules,
|
|
114
124
|
projectDomain: `${answers.projectName}.lndo.site`,
|
|
115
125
|
salts: Generator.generateSalts(),
|
package/lib/utils/git.js
CHANGED
|
@@ -23,16 +23,45 @@ export function getGitUserDefaults() {
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
/**
|
|
26
|
-
*
|
|
26
|
+
* Dirs que cada destino copia do repositório superpowers-sage.
|
|
27
|
+
* A subpasta de destino dentro do projeto é TARGET_CONFIG[key].dest.
|
|
28
|
+
*/
|
|
29
|
+
const TARGET_CONFIG = {
|
|
30
|
+
claude: {
|
|
31
|
+
dest: '.claude/plugins/superpowers-sage',
|
|
32
|
+
dirs: ['.claude-plugin', 'skills', 'agents', 'hooks'],
|
|
33
|
+
label: 'Claude Code (.claude/)',
|
|
34
|
+
},
|
|
35
|
+
cursor: {
|
|
36
|
+
dest: '.cursor/plugins/local/superpowers-sage',
|
|
37
|
+
dirs: ['.cursor-plugin', 'skills', 'agents', 'hooks', 'rules'],
|
|
38
|
+
label: 'Cursor (.cursor/)',
|
|
39
|
+
},
|
|
40
|
+
ai: {
|
|
41
|
+
dest: '.ai/superpowers-sage',
|
|
42
|
+
dirs: ['skills', 'agents', 'hooks'],
|
|
43
|
+
label: 'Agnóstico (.ai/)',
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Clona codigodoleo/superpowers-sage e copia o conteúdo para os destinos selecionados.
|
|
27
49
|
* Requer git instalado no host.
|
|
50
|
+
*
|
|
28
51
|
* @param {string} targetDir - Caminho absoluto do projeto gerado
|
|
52
|
+
* @param {string[]} targets - Lista de destinos: 'claude' | 'cursor' | 'ai'
|
|
29
53
|
*/
|
|
30
|
-
export async function installSuperpowersSage(targetDir) {
|
|
54
|
+
export async function installSuperpowersSage(targetDir, targets = ['claude']) {
|
|
31
55
|
const repo = 'https://github.com/codigodoleo/superpowers-sage.git';
|
|
32
56
|
const tmpDir = path.join(os.tmpdir(), `superpowers-sage-${Date.now()}`);
|
|
33
|
-
const claudeDir = path.join(targetDir, '.claude');
|
|
34
57
|
|
|
35
|
-
|
|
58
|
+
const validTargets = targets.filter((t) => TARGET_CONFIG[t]);
|
|
59
|
+
if (validTargets.length === 0) {
|
|
60
|
+
log(color.orange, '[skills] Nenhum destino válido informado. Pulando.');
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
log(color.blue, `🔌 Clonando superpowers-sage para: ${validTargets.join(', ')}...`);
|
|
36
65
|
|
|
37
66
|
const result = spawnSync('git', ['clone', '--depth=1', repo, tmpDir], {
|
|
38
67
|
stdio: 'inherit',
|
|
@@ -41,19 +70,27 @@ export async function installSuperpowersSage(targetDir) {
|
|
|
41
70
|
if (result.status !== 0) {
|
|
42
71
|
log(
|
|
43
72
|
color.orange,
|
|
44
|
-
'⚠️
|
|
73
|
+
'⚠️ Não foi possível clonar superpowers-sage (sem rede ou git indisponível). Pulando.'
|
|
45
74
|
);
|
|
46
75
|
return;
|
|
47
76
|
}
|
|
48
77
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
overwrite: true,
|
|
53
|
-
filter: (src) => !src.includes(`${path.sep}.git`),
|
|
54
|
-
});
|
|
78
|
+
for (const key of validTargets) {
|
|
79
|
+
const cfg = TARGET_CONFIG[key];
|
|
80
|
+
const destBase = path.join(targetDir, cfg.dest);
|
|
55
81
|
|
|
56
|
-
|
|
82
|
+
await fs.ensureDir(destBase);
|
|
83
|
+
|
|
84
|
+
for (const dir of cfg.dirs) {
|
|
85
|
+
const srcDir = path.join(tmpDir, dir);
|
|
86
|
+
if (!(await fs.pathExists(srcDir))) continue;
|
|
87
|
+
|
|
88
|
+
const destDir = path.join(destBase, dir);
|
|
89
|
+
await fs.copy(srcDir, destDir, { overwrite: true });
|
|
90
|
+
}
|
|
57
91
|
|
|
58
|
-
|
|
92
|
+
log(color.green, `✅ superpowers-sage instalado em ${cfg.dest}`);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
await fs.remove(tmpDir);
|
|
59
96
|
}
|
|
@@ -0,0 +1,71 @@
|
|
|
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 themeName = context.blank_theme_name || `${context.projectName}-theme`;
|
|
9
|
+
const themeDir = `content/themes/${themeName}`;
|
|
10
|
+
const absoluteThemeDir = path.join(generator.cwd, themeDir);
|
|
11
|
+
|
|
12
|
+
log(color.blue, `[blank-theme] 📂 Scaffolding blank theme: ${themeDir}`);
|
|
13
|
+
|
|
14
|
+
// 1. Ensure directories exist
|
|
15
|
+
await fs.ensureDir(path.join(absoluteThemeDir, 'src', 'js'));
|
|
16
|
+
await fs.ensureDir(path.join(absoluteThemeDir, 'src', 'scss'));
|
|
17
|
+
await fs.ensureDir(path.join(absoluteThemeDir, 'php'));
|
|
18
|
+
|
|
19
|
+
// 2. Generate static files
|
|
20
|
+
await generator.generateFile(
|
|
21
|
+
'style.css',
|
|
22
|
+
{ ...context, blank_theme_name: themeName },
|
|
23
|
+
'blank-theme',
|
|
24
|
+
`${themeDir}/style.css`
|
|
25
|
+
);
|
|
26
|
+
await generator.generateFile(
|
|
27
|
+
'functions.php',
|
|
28
|
+
{ ...context, blank_theme_name: themeName },
|
|
29
|
+
'blank-theme',
|
|
30
|
+
`${themeDir}/functions.php`
|
|
31
|
+
);
|
|
32
|
+
await generator.generateFile(
|
|
33
|
+
'vite.config.js',
|
|
34
|
+
{ ...context, blank_theme_name: themeName },
|
|
35
|
+
'blank-theme',
|
|
36
|
+
`${themeDir}/vite.config.js`
|
|
37
|
+
);
|
|
38
|
+
await generator.generateFile(
|
|
39
|
+
'package.json',
|
|
40
|
+
{ ...context, blank_theme_name: themeName },
|
|
41
|
+
'blank-theme',
|
|
42
|
+
`${themeDir}/package.json`
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
// 3. src/ scaffolds
|
|
46
|
+
await fs.ensureFile(path.join(absoluteThemeDir, 'src', 'js', 'app.js'));
|
|
47
|
+
await fs.ensureFile(path.join(absoluteThemeDir, 'src', 'scss', 'app.scss'));
|
|
48
|
+
|
|
49
|
+
// 4. Lint configs co-located in theme — always installed (IDE/editor support)
|
|
50
|
+
log(color.blue, '[blank-theme] 🔧 Installing lint configurations...');
|
|
51
|
+
await generator.copyFile('lint/.prettierrc.json', 'blank-theme', `${themeDir}/.prettierrc.json`);
|
|
52
|
+
if (context.blank_theme_lint_eslint !== false) {
|
|
53
|
+
await generator.copyFile(
|
|
54
|
+
'lint/eslint.config.mjs',
|
|
55
|
+
'blank-theme',
|
|
56
|
+
`${themeDir}/eslint.config.mjs`
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
if (context.blank_theme_lint_pint !== false) {
|
|
60
|
+
await generator.copyFile('lint/pint.json', 'blank-theme', `${themeDir}/pint.json`);
|
|
61
|
+
}
|
|
62
|
+
if (context.blank_theme_lint_stylelint !== false) {
|
|
63
|
+
await generator.copyFile(
|
|
64
|
+
'lint/.stylelintrc.json',
|
|
65
|
+
'blank-theme',
|
|
66
|
+
`${themeDir}/.stylelintrc.json`
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
log(color.green, `[blank-theme] ✅ Blank theme scaffolded: ${themeDir}`);
|
|
71
|
+
}
|
|
@@ -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
|
+
}
|
|
@@ -5,17 +5,11 @@ import globals from 'globals';
|
|
|
5
5
|
|
|
6
6
|
export default [
|
|
7
7
|
{
|
|
8
|
-
ignores: [
|
|
9
|
-
'**/node_modules/**',
|
|
10
|
-
'**/vendor/**',
|
|
11
|
-
'**/wp/**',
|
|
12
|
-
'**/public/build/**',
|
|
13
|
-
'**/dist/**',
|
|
14
|
-
'eslint.config.mjs',
|
|
15
|
-
],
|
|
8
|
+
ignores: ['node_modules/**', 'vendor/**', 'dist/**'],
|
|
16
9
|
},
|
|
17
10
|
js.configs.recommended,
|
|
18
11
|
{
|
|
12
|
+
files: ['src/js/**/*.{js,mjs,ts}'],
|
|
19
13
|
languageOptions: {
|
|
20
14
|
ecmaVersion: 2022,
|
|
21
15
|
sourceType: 'module',
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export default [
|
|
2
|
+
{
|
|
3
|
+
type: 'confirm',
|
|
4
|
+
name: 'enable_blank_theme',
|
|
5
|
+
message: 'Enable Blank Theme scaffold (Vite + SCSS, no Sage)?',
|
|
6
|
+
default: false,
|
|
7
|
+
},
|
|
8
|
+
{
|
|
9
|
+
type: 'input',
|
|
10
|
+
name: 'blank_theme_name',
|
|
11
|
+
message: 'Blank theme slug (used as directory name):',
|
|
12
|
+
default: (answers) => `${answers.projectName || 'wordpress'}-theme`,
|
|
13
|
+
when: (answers) => answers.enable_blank_theme,
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
type: 'confirm',
|
|
17
|
+
name: 'blank_theme_lint_eslint',
|
|
18
|
+
message: 'Blank Theme: enable ESLint for JS/TS?',
|
|
19
|
+
default: true,
|
|
20
|
+
when: (answers) => answers.enable_blank_theme && answers.enable_lint,
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
type: 'confirm',
|
|
24
|
+
name: 'blank_theme_lint_stylelint',
|
|
25
|
+
message: 'Blank Theme: enable Stylelint for CSS/SCSS?',
|
|
26
|
+
default: true,
|
|
27
|
+
when: (answers) => answers.enable_blank_theme && answers.enable_lint,
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
type: 'confirm',
|
|
31
|
+
name: 'blank_theme_lint_pint',
|
|
32
|
+
message: 'Blank Theme: enable Pint for PHP?',
|
|
33
|
+
default: true,
|
|
34
|
+
when: (answers) => answers.enable_blank_theme && answers.enable_lint,
|
|
35
|
+
},
|
|
36
|
+
];
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
tooling:
|
|
2
|
+
bt-dev:
|
|
3
|
+
service: build
|
|
4
|
+
description: Run Vite dev server for blank theme
|
|
5
|
+
cmd: npm run dev --prefix /app/content/themes/{{blank_theme_name}}
|
|
6
|
+
bt-build:
|
|
7
|
+
service: build
|
|
8
|
+
description: Build blank theme assets
|
|
9
|
+
cmd: npm run build --prefix /app/content/themes/{{blank_theme_name}}
|
|
10
|
+
{{#if enable_lint}}
|
|
11
|
+
bt-eslint:
|
|
12
|
+
service: build
|
|
13
|
+
description: Lint JS/TS in blank theme
|
|
14
|
+
cmd: npx eslint --fix src/js/ --config /app/content/themes/{{blank_theme_name}}/eslint.config.mjs
|
|
15
|
+
dir: /app/content/themes/{{blank_theme_name}}
|
|
16
|
+
bt-stylelint:
|
|
17
|
+
service: build
|
|
18
|
+
description: Lint CSS/SCSS in blank theme
|
|
19
|
+
cmd: npx stylelint --fix "src/scss/**/*.scss" --config /app/content/themes/{{blank_theme_name}}/.stylelintrc.json
|
|
20
|
+
dir: /app/content/themes/{{blank_theme_name}}
|
|
21
|
+
bt-pint:
|
|
22
|
+
service: appserver
|
|
23
|
+
description: Lint PHP in blank theme
|
|
24
|
+
dir: /app/content/themes/{{blank_theme_name}}
|
|
25
|
+
cmd: ./vendor/bin/pint
|
|
26
|
+
{{/if}}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
/**
|
|
3
|
+
* Theme functions and definitions.
|
|
4
|
+
*
|
|
5
|
+
* @package {{blank_theme_name}}
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
if (!defined('ABSPATH')) {
|
|
9
|
+
exit;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
define('{{blank_theme_name}}_VERSION', '{{projectVersion}}');
|
|
13
|
+
define('{{blank_theme_name}}_DIR', get_template_directory());
|
|
14
|
+
define('{{blank_theme_name}}_URI', get_template_directory_uri());
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Enqueue Vite-compiled assets.
|
|
18
|
+
*/
|
|
19
|
+
add_action('wp_enqueue_scripts', function () {
|
|
20
|
+
$manifest = {{blank_theme_name}}_DIR . '/dist/.vite/manifest.json';
|
|
21
|
+
|
|
22
|
+
if (!file_exists($manifest)) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
$data = json_decode(file_get_contents($manifest), true);
|
|
27
|
+
|
|
28
|
+
if (isset($data['src/js/app.js']['file'])) {
|
|
29
|
+
wp_enqueue_script(
|
|
30
|
+
'{{blank_theme_name}}-app',
|
|
31
|
+
{{blank_theme_name}}_URI . '/dist/' . $data['src/js/app.js']['file'],
|
|
32
|
+
[],
|
|
33
|
+
null,
|
|
34
|
+
true
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (isset($data['src/scss/app.scss']['file'])) {
|
|
39
|
+
wp_enqueue_style(
|
|
40
|
+
'{{blank_theme_name}}-app',
|
|
41
|
+
{{blank_theme_name}}_URI . '/dist/' . $data['src/scss/app.scss']['file'],
|
|
42
|
+
[],
|
|
43
|
+
null
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
});
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "{{blank_theme_name}}",
|
|
3
|
+
"version": "{{projectVersion}}",
|
|
4
|
+
"description": "{{projectDescription}}",
|
|
5
|
+
"private": true,
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "vite",
|
|
8
|
+
"build": "vite build",
|
|
9
|
+
"lint": "eslint src/js --ext .js,.ts",
|
|
10
|
+
"lint:css": "stylelint \"src/scss/**/*.scss\""
|
|
11
|
+
},
|
|
12
|
+
"devDependencies": {
|
|
13
|
+
"vite": "^6.0.0",
|
|
14
|
+
"sass-embedded": "^1.77.0"
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { defineConfig } from 'vite';
|
|
2
|
+
|
|
3
|
+
export default defineConfig({
|
|
4
|
+
base: '/app/content/themes/{{blank_theme_name}}/dist/',
|
|
5
|
+
build: {
|
|
6
|
+
outDir: 'dist',
|
|
7
|
+
rollupOptions: {
|
|
8
|
+
input: {
|
|
9
|
+
app: 'src/js/app.js',
|
|
10
|
+
styles: 'src/scss/app.scss',
|
|
11
|
+
},
|
|
12
|
+
},
|
|
13
|
+
manifest: true,
|
|
14
|
+
emptyOutDir: true,
|
|
15
|
+
},
|
|
16
|
+
css: {
|
|
17
|
+
preprocessorOptions: {
|
|
18
|
+
scss: {
|
|
19
|
+
api: 'modern-compiler',
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
});
|