@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 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 registration |
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
@@ -12,6 +12,7 @@ export function parseCliOptions(args) {
12
12
  icons: readListFlag(args, "icons"),
13
13
  i18n: readBooleanFlag(args, "i18n"),
14
14
  languages: readListFlag(args, "languages"),
15
+ skills: readBooleanFlag(args, "skills"),
15
16
  }
16
17
  }
17
18
 
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
- if (extension === ".ts") {
96
- return `// Only the framework-free helpers: "client" also loads React's and Preact's
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
- return `import { isNative } from "@inglorious/web/mobile"
109
- import { registerSW } from "virtual:pwa-register"
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
- if (!isNative()) {
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: "autoUpdate",
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.4.2",
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",