@inglorious/create-app 1.4.2 → 1.5.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/README.md +13 -11
- package/bin/index.js +34 -0
- package/bin/lib/cli.js +1 -0
- package/bin/lib/pwa.js +18 -14
- package/bin/lib/skills.js +44 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -25,16 +25,18 @@ The CLI will guide you through the setup process, asking for a project name and
|
|
|
25
25
|
|
|
26
26
|
For the JavaScript and TypeScript Vite templates, the CLI then asks about the app's features:
|
|
27
27
|
|
|
28
|
-
| Question | Flag | Adds
|
|
29
|
-
| ------------------------- | ---------------------------------------------------- |
|
|
30
|
-
| Use Inglorious UI? | `--ui` / `--no-ui` | `@inglorious/ui`, its base styles and an app bar
|
|
31
|
-
| Which theme? | `--theme=inglorious\|material\|bootstrap` | The theme's stylesheet and class
|
|
32
|
-
| Is it a mobile app? | `--mobile` / `--no-mobile` | Capacitor for Android and iOS; with Inglorious UI, a bottom tab bar and safe-area spacing
|
|
33
|
-
| Add routing? | `--routing` / `--no-routing` | The Router, a home and an about page, and navigation between them
|
|
34
|
-
| Animate page transitions? | `--transitions` / `--no-transitions` | View transitions between pages (with routing and Inglorious UI)
|
|
35
|
-
| Which icon packs? | `--icons=material,fontawesome,lucide` / `--no-icons` | Iconify icon sets, drawn by Inglorious UI's `Icon` (with Inglorious UI)
|
|
36
|
-
| Translate the app? | `--i18n` / `--no-i18n`, `--languages=en,it` | `@inglorious/i18n`, a catalogue per language and a language picker; the first language is the default
|
|
37
|
-
| Enable PWA support? | `--pwa` / `--no-pwa` | `vite-plugin-pwa`, a manifest, icons and service worker
|
|
28
|
+
| Question | Flag | Adds |
|
|
29
|
+
| ------------------------- | ---------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- |
|
|
30
|
+
| Use Inglorious UI? | `--ui` / `--no-ui` | `@inglorious/ui`, its base styles and an app bar |
|
|
31
|
+
| Which theme? | `--theme=inglorious\|material\|bootstrap` | The theme's stylesheet and class |
|
|
32
|
+
| Is it a mobile app? | `--mobile` / `--no-mobile` | Capacitor for Android and iOS; with Inglorious UI, a bottom tab bar and safe-area spacing |
|
|
33
|
+
| Add routing? | `--routing` / `--no-routing` | The Router, a home and an about page, and navigation between them |
|
|
34
|
+
| Animate page transitions? | `--transitions` / `--no-transitions` | View transitions between pages (with routing and Inglorious UI) |
|
|
35
|
+
| Which icon packs? | `--icons=material,fontawesome,lucide` / `--no-icons` | Iconify icon sets, drawn by Inglorious UI's `Icon` (with Inglorious UI) |
|
|
36
|
+
| Translate the app? | `--i18n` / `--no-i18n`, `--languages=en,it` | `@inglorious/i18n`, a catalogue per language and a language picker; the first language is the default |
|
|
37
|
+
| Enable PWA support? | `--pwa` / `--no-pwa` | `vite-plugin-pwa`, a manifest, icons, and a service worker that keeps installed apps on the latest version |
|
|
38
|
+
|
|
39
|
+
Every template except `minimal` then asks whether to add agent skills (`--skills` / `--no-skills`). Saying yes runs the [skills CLI](https://skills.sh) in the new project. It asks which coding agents to install for, and installs the [Inglorious Forge skills](https://github.com/IngloriousCoderz/forge-skills) that match your choices: `forge`, `forge-best-practices`, `store`, `web` and `web-best-practices` always, plus `ssx`, `vite-plugin-jsx` or `vite-plugin-vue`, `ui` and `ui-best-practices`, and `i18n` when the project uses them. If the install fails, the CLI prints the command to retry it.
|
|
38
40
|
|
|
39
41
|
The app is generated in the syntax you chose: lit-html, JSX or Vue. Every question answered on the command line is skipped, so a project can be created without any prompt:
|
|
40
42
|
|
|
@@ -45,7 +47,7 @@ The app is generated in the syntax you chose: lit-html, JSX or Vue. Every questi
|
|
|
45
47
|
| Select a rendering syntax | `--syntax=lit-html\|jsx\|vue` |
|
|
46
48
|
|
|
47
49
|
```bash
|
|
48
|
-
npm create @inglorious/app@latest -- my-app --template=ts --syntax=jsx --ui --theme=material --routing --transitions --icons=material --languages=en,it --no-mobile --no-pwa
|
|
50
|
+
npm create @inglorious/app@latest -- my-app --template=ts --syntax=jsx --ui --theme=material --routing --transitions --icons=material --languages=en,it --no-mobile --no-pwa --skills
|
|
49
51
|
```
|
|
50
52
|
|
|
51
53
|
## Templates
|
package/bin/index.js
CHANGED
|
@@ -21,6 +21,7 @@ import { copyDir } from "./lib/file.js"
|
|
|
21
21
|
import { addMobileSupport } from "./lib/mobile.js"
|
|
22
22
|
import { addPwaSupport } from "./lib/pwa.js"
|
|
23
23
|
import { askAppFeatures } from "./lib/questions.js"
|
|
24
|
+
import { installSkills, skillsCommand, skillsFor } from "./lib/skills.js"
|
|
24
25
|
|
|
25
26
|
async function main() {
|
|
26
27
|
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
|
@@ -107,6 +108,29 @@ async function main() {
|
|
|
107
108
|
)
|
|
108
109
|
}
|
|
109
110
|
|
|
111
|
+
let withSkills = false
|
|
112
|
+
|
|
113
|
+
if (baseTemplate !== "minimal") {
|
|
114
|
+
const { addSkills } = await prompts(
|
|
115
|
+
{
|
|
116
|
+
type: cliOptions.skills === null ? "confirm" : null,
|
|
117
|
+
name: "addSkills",
|
|
118
|
+
message: "Add agent skills for coding agents? (Claude Code, Codex...)",
|
|
119
|
+
initial: true,
|
|
120
|
+
},
|
|
121
|
+
{ onCancel },
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
if (canceled) {
|
|
125
|
+
console.log("Operation canceled.")
|
|
126
|
+
return
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
withSkills = cliOptions.skills ?? addSkills
|
|
130
|
+
} else if (cliOptions.skills) {
|
|
131
|
+
console.warn("Agent skills are not available for the minimal template.")
|
|
132
|
+
}
|
|
133
|
+
|
|
110
134
|
const spinner = ora(`Creating project "${projectName}"...`).start()
|
|
111
135
|
|
|
112
136
|
try {
|
|
@@ -179,6 +203,16 @@ async function main() {
|
|
|
179
203
|
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, INDENTATION) + EOL)
|
|
180
204
|
|
|
181
205
|
spinner.succeed(`Created ${projectName} at ${targetDir}`)
|
|
206
|
+
|
|
207
|
+
if (withSkills) {
|
|
208
|
+
const skills = skillsFor({ baseTemplate, renderer, ...features })
|
|
209
|
+
if (!installSkills(targetDir, skills)) {
|
|
210
|
+
console.warn(`\nCould not add the agent skills. To retry, run:`)
|
|
211
|
+
console.warn(` cd ${projectName}`)
|
|
212
|
+
console.warn(` ${skillsCommand(skills)}`)
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
182
216
|
console.log(`\nNext steps:`)
|
|
183
217
|
console.log(` cd ${projectName}`)
|
|
184
218
|
console.log(` pnpm install`)
|
package/bin/lib/cli.js
CHANGED
package/bin/lib/pwa.js
CHANGED
|
@@ -91,33 +91,37 @@ export function writePwaRegistration(targetDir) {
|
|
|
91
91
|
fs.writeFileSync(pwaPath, createPwaRegistrationSource(extension))
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
+
// The worker waits for the SKIP_WAITING message `watchPwaUpdate` sends: on
|
|
95
|
+
// its own, a new version would wait for every tab of the app to close, which
|
|
96
|
+
// for a PWA installed on a phone is never.
|
|
94
97
|
export function createPwaRegistrationSource(extension) {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
// typings, whose global JSX would replace Inglorious's.
|
|
98
|
-
/// <reference types="vite-plugin-pwa/vanillajs" />
|
|
99
|
-
import { isNative } from "@inglorious/web/mobile"
|
|
98
|
+
const registration = `import { isNative } from "@inglorious/web/mobile"
|
|
99
|
+
import { watchPwaUpdate } from "@inglorious/web/pwa"
|
|
100
100
|
import { registerSW } from "virtual:pwa-register"
|
|
101
101
|
|
|
102
102
|
if (!isNative()) {
|
|
103
|
-
registerSW(
|
|
103
|
+
registerSW({
|
|
104
|
+
onRegisteredSW(url, registration) {
|
|
105
|
+
if (registration) watchPwaUpdate(registration)
|
|
106
|
+
},
|
|
107
|
+
})
|
|
104
108
|
}
|
|
105
109
|
`
|
|
106
|
-
}
|
|
107
110
|
|
|
108
|
-
|
|
109
|
-
|
|
111
|
+
if (extension === ".ts") {
|
|
112
|
+
return `// Only the framework-free helpers: "client" also loads React's and Preact's
|
|
113
|
+
// typings, whose global JSX would replace Inglorious's.
|
|
114
|
+
/// <reference types="vite-plugin-pwa/vanillajs" />
|
|
115
|
+
${registration}`
|
|
116
|
+
}
|
|
110
117
|
|
|
111
|
-
|
|
112
|
-
registerSW()
|
|
113
|
-
}
|
|
114
|
-
`
|
|
118
|
+
return registration
|
|
115
119
|
}
|
|
116
120
|
|
|
117
121
|
export function createVitePwaConfig(projectName) {
|
|
118
122
|
return `VitePWA({
|
|
119
123
|
injectRegister: false,
|
|
120
|
-
registerType: "
|
|
124
|
+
registerType: "prompt",
|
|
121
125
|
pwaAssets: {
|
|
122
126
|
image: "public/logo.png",
|
|
123
127
|
preset: "minimal-2023",
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { execSync } from "child_process"
|
|
2
|
+
|
|
3
|
+
const SKILLS_REPOSITORY = "IngloriousCoderz/forge-skills"
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* The agent skills for the packages a new project uses.
|
|
7
|
+
*
|
|
8
|
+
* @param {{ baseTemplate: string, renderer: string, ui: boolean, languages: string[] }} project
|
|
9
|
+
*/
|
|
10
|
+
export function skillsFor({ baseTemplate, renderer, ui, languages }) {
|
|
11
|
+
const skills = [
|
|
12
|
+
"forge",
|
|
13
|
+
"forge-best-practices",
|
|
14
|
+
"store",
|
|
15
|
+
"web",
|
|
16
|
+
"web-best-practices",
|
|
17
|
+
]
|
|
18
|
+
if (baseTemplate.startsWith("ssx-")) skills.push("ssx")
|
|
19
|
+
if (renderer === "jsx") skills.push("vite-plugin-jsx")
|
|
20
|
+
if (renderer === "vue") skills.push("vite-plugin-vue")
|
|
21
|
+
if (ui) skills.push("ui", "ui-best-practices")
|
|
22
|
+
if (languages.length) skills.push("i18n")
|
|
23
|
+
return skills
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Installs the skills into the project with the skills CLI, which asks which
|
|
28
|
+
* agents to install them for. Returns false when the install fails.
|
|
29
|
+
*
|
|
30
|
+
* @param {string} targetDir
|
|
31
|
+
* @param {string[]} skills
|
|
32
|
+
*/
|
|
33
|
+
export function installSkills(targetDir, skills) {
|
|
34
|
+
try {
|
|
35
|
+
execSync(skillsCommand(skills), { cwd: targetDir, stdio: "inherit" })
|
|
36
|
+
return true
|
|
37
|
+
} catch {
|
|
38
|
+
return false
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function skillsCommand(skills) {
|
|
43
|
+
return `pnpm dlx skills add ${SKILLS_REPOSITORY} --skill ${skills.join(" ")}`
|
|
44
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inglorious/create-app",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"description": "A scaffolding tool to quickly create a new app with Inglorious Web.",
|
|
5
5
|
"author": "Matteo Antony Mistretta <antony.mistretta@gmail.com> (https://ingloriouscoderz.it)",
|
|
6
6
|
"license": "MIT",
|