@artefact-ci/prototype 0.1.0 → 0.2.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
@@ -1,18 +1,18 @@
1
1
  # @artefact-ci/prototype
2
2
 
3
- Maquettes HTML cliquables d'une fonctionnalité, sorties de `pnpm prototype` du boilerplate (`b30bb7b`). C'est la commande `ui.prototype` de `.specify/stack.yml`, lancée par `/speckit-prototype`.
3
+ Le prototype HTML cliquable du produit, sorties de `pnpm prototype` du boilerplate (`b30bb7b`). C'est la commande `ui.prototype` de `.specify/stack.yml`, lancée par `/speckit-prototype`.
4
4
 
5
5
  ```sh
6
- npx @artefact-ci/prototype specs/004-checkout # compile styles.css depuis le thème, vérifie les liens
7
- npx @artefact-ci/prototype specs/004-checkout --capture # puis remplace captures/ (desktop et mobile)
8
- npx @artefact-ci/prototype specs/004-checkout --theme src/app/globals.css # autre thème que ui.theme
6
+ npx @artefact-ci/prototype # compile styles.css depuis le thème, vérifie les liens
7
+ npx @artefact-ci/prototype --capture # puis remplace captures/ (desktop et mobile)
8
+ npx @artefact-ci/prototype --theme src/app/globals.css # autre thème que ui.theme
9
9
  ```
10
10
 
11
- À lancer à la racine du dépôt (Node 24.11 ou plus récent). Les pages vivent à plat dans `specs/NNN-<nom>/prototypes/`, `index.html` en entrée ; la commande affiche l'URL `file://` de `index.html`, à ouvrir sans serveur.
11
+ À lancer à la racine du dépôt (Node 24.11 ou plus récent). Le prototype est global : les pages de toutes les fonctionnalités vivent à plat dans `specs/prototype/`, `index.html` en entrée (les parcours par epic puis par fonctionnalité), et les parcours dans `specs/prototype/journeys/NNN-<nom>.md`. La commande ne prend pas de dossier : elle refuse un argument (un dossier de spec, comme avant la 0.2.0) ; la commande affiche l'URL `file://` de `index.html`, à ouvrir sans serveur.
12
12
 
13
13
  - **Liens** : un lien vers une page absente fait échouer ; une page vers laquelle rien ne mène est signalée.
14
14
  - **Styles** : `styles.css` est compilé par Tailwind 4 depuis le thème du projet (`ui.theme`) et les classes des pages. Les fichiers des paquets importés par le thème (polices `@fontsource`) sont copiés à côté.
15
- - **Captures** : une par page et par format (1440×900, 390×844) dans `captures/`, pleine page sauf pour une page marquée `data-capture="viewport"` (dialogue, toast). Un échec garde les anciennes.
15
+ - **Captures** : une par page et par format (1440×900, 390×844) dans `specs/prototype/captures/`, pleine page sauf pour une page marquée `data-capture="viewport"` (dialogue, toast). Un échec garde les anciennes.
16
16
 
17
17
  Le CLI Tailwind (`@tailwindcss/cli`) et Playwright sont pris dans le projet s'il les a, sinon dans ce paquet : les styles compilent avec la version de l'app, et les captures trouvent le Chromium déjà installé pour les parcours.
18
18
 
@@ -20,6 +20,8 @@ Le CLI Tailwind (`@tailwindcss/cli`) et Playwright sont pris dans le projet s'il
20
20
  - Quand Chromium manque, la commande affiche celle qui installe le Chromium de la version de Playwright chargée (`npx playwright@<version> install chromium`).
21
21
  - Il faut Node 24.11 ou plus récent, aussi sur un projet Bun.
22
22
 
23
+ Le binaire s'appelle `artefact-prototype`, pas `prototype` : le registre npm retire une clé `prototype` du `bin` de son manifeste (0.1.0 publiée ainsi), et `npx @artefact-ci/prototype` ne trouvait plus rien à lancer. `npx` et `pnpm dlx` lancent le seul binaire du paquet, quel que soit son nom.
24
+
23
25
  ## Développer
24
26
 
25
27
  ```sh
package/dist/cli.mjs CHANGED
@@ -8,10 +8,10 @@ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExte
8
8
  return path;
9
9
  };
10
10
  /**
11
- * Prototype d'une fonctionnalité (/speckit-prototype), pages HTML dans specs/NNN-<nom>/prototypes/,
12
- * à lancer à la racine du dépôt :
13
- * prototype specs/004-checkout → compile styles.css depuis le thème (ui.theme)
14
- * prototype specs/004-checkout --capture → puis remplace captures/ (desktop et mobile)
11
+ * Prototype global du produit (/speckit-prototype), pages HTML dans specs/prototype/, que chaque
12
+ * fonctionnalité complète, à lancer à la racine du dépôt :
13
+ * artefact-prototype → vérifie les liens, compile styles.css depuis le thème (ui.theme)
14
+ * artefact-prototype --capture → puis remplace captures/ (desktop et mobile, toutes les pages)
15
15
  * Affiche l'URL de index.html, à ouvrir dans le navigateur : aucun serveur.
16
16
  * Tailwind (`@tailwindcss/cli`) et Playwright sont pris dans le projet s'il les a, sinon dans ce
17
17
  * paquet : la maquette compile avec la même version que l'app, et les captures trouvent le Chromium
@@ -22,10 +22,10 @@ import { copyFileSync, existsSync, mkdirSync, readFileSync, readdirSync, renameS
22
22
  import { createRequire } from 'node:module';
23
23
  import { basename, dirname, join, relative, resolve } from 'node:path';
24
24
  import { pathToFileURL } from 'node:url';
25
- import { VIEWPORTS, captureTargets, capturesViewportOnly, entryCss, linkProblems, localUrls, packageImports, pageFiles, prototypesDir, } from "./core.mjs";
25
+ import { VIEWPORTS, captureTargets, capturesViewportOnly, entryCss, linkProblems, localUrls, packageImports, pageFiles, PROTOTYPE_DIR, prototypeArgs, } from "./core.mjs";
26
26
  import { binOf, chromiumInstallHint, themeOf } from "./stack.mjs";
27
27
  const STACK_FILE = join('.specify', 'stack.yml');
28
- const USAGE = 'Usage : prototype <specs/NNN-nom> [--capture] [--theme <fichier css>]';
28
+ const USAGE = 'Usage : artefact-prototype [--capture] [--theme <fichier css>]';
29
29
  const args = process.argv.slice(2);
30
30
  if (args.includes('--help') || args.includes('-h')) {
31
31
  console.log(USAGE);
@@ -37,23 +37,16 @@ if (themeAt >= 0 && (!themeArg || themeArg.startsWith('--'))) {
37
37
  console.error(`--theme attend le fichier de thème du projet.\n${USAGE}`);
38
38
  process.exit(1);
39
39
  }
40
- const capture = args.includes('--capture');
41
- const unknownOption = args.find((arg) => arg.startsWith('--') && arg !== '--capture');
42
- if (unknownOption) {
43
- console.error(`Option inconnue : ${unknownOption}\n${USAGE}`);
44
- process.exit(1);
45
- }
46
- const featurePath = args.find((arg) => !arg.startsWith('--')) ?? '';
47
- // Le dossier de la feature d'abord : sans argument, l'usage s'affiche avant tout le reste.
48
- let dir;
40
+ const dir = PROTOTYPE_DIR;
41
+ let capture;
49
42
  let pages;
50
43
  try {
51
- dir = prototypesDir(featurePath);
44
+ ({ capture } = prototypeArgs(args));
52
45
  pages = pageFiles(readdirSync(dir));
53
46
  }
54
47
  catch (error) {
55
48
  const message = error.code === 'ENOENT'
56
- ? `${featurePath} n'a pas de dossier prototypes/.`
49
+ ? `${dir}/ n'existe pas : /speckit-prototype le crée.`
57
50
  : error.message;
58
51
  console.error(`${USAGE}\n${message}`);
59
52
  process.exit(1);
@@ -193,6 +186,8 @@ if (capture) {
193
186
  await page.screenshot({
194
187
  path: join(fresh, basename(target.file)),
195
188
  fullPage: !capturesViewportOnly(html[target.page]),
189
+ // Une animation (spinner) figée : une page inchangée donne la même capture d'une fois à l'autre.
190
+ animations: 'disabled',
196
191
  });
197
192
  await page.close();
198
193
  }
package/dist/core.mjs CHANGED
@@ -1,21 +1,28 @@
1
1
  /**
2
- * Prototype d'une fonctionnalité (/speckit-prototype) : pages HTML statiques à plat dans
3
- * specs/NNN-<nom>/prototypes/, index.html en entrée, styles.css compilé depuis le vrai thème du
4
- * projet (`ui.theme` de .specify/stack.yml), captures par page et par format dans captures/.
5
- * Logique pure ; les fichiers, la compilation et les captures sont dans cli.mts.
2
+ * Prototype du produit (/speckit-prototype) : un seul, global, que chaque fonctionnalité complète.
3
+ * Pages HTML statiques à plat dans specs/prototype/, index.html en entrée (par epic et parcours),
4
+ * parcours de chaque fonctionnalité dans journeys/NNN-<nom>.md, styles.css compilé depuis le vrai
5
+ * thème du projet (`ui.theme` de .specify/stack.yml), captures par page et par format dans
6
+ * captures/. Logique pure ; les fichiers, la compilation et les captures sont dans cli.mts.
6
7
  */
7
8
  /** Formats des captures : un écran de bureau courant et un téléphone courant. */
8
9
  export const VIEWPORTS = {
9
10
  desktop: { width: 1440, height: 900 },
10
11
  mobile: { width: 390, height: 844 },
11
12
  };
12
- /** Dossier des prototypes d'une fonctionnalité, à partir de son dossier ou de celui des prototypes. */
13
- export function prototypesDir(featurePath) {
14
- const match = /^(specs\/\d{3}-[a-z0-9-]+?)(?:\/prototypes)?\/?$/.exec(featurePath);
15
- if (!match) {
16
- throw new Error(`« ${featurePath} » n'est pas le dossier d'une fonctionnalité : specs/NNN-<name> attendu.`);
13
+ /** Arguments de `pnpm prototype` : `--capture` seulement, le prototype n'a qu'un dossier. */
14
+ /** Dossier du prototype global. */
15
+ export const PROTOTYPE_DIR = 'specs/prototype';
16
+ /** Arguments hors `--theme` : `--capture` seulement, le prototype n'a qu'un dossier. */
17
+ export function prototypeArgs(args) {
18
+ for (const arg of args) {
19
+ if (arg === '--capture')
20
+ continue;
21
+ throw new Error(arg.startsWith('--')
22
+ ? `Option inconnue : ${arg}.`
23
+ : `« ${arg} » : le prototype est global, dans ${PROTOTYPE_DIR}/ ; la commande ne prend plus de dossier.`);
17
24
  }
18
- return `${match[1]}/prototypes`;
25
+ return { capture: args.includes('--capture') };
19
26
  }
20
27
  /** Feuille d'entrée de Tailwind : le thème de l'app, et les classes des pages du prototype. */
21
28
  export function entryCss(themeRelativePath) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@artefact-ci/prototype",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Maquettes HTML cliquables d'une spec, compilées depuis le thème du projet (méthode artefact-sdd)",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -14,7 +14,7 @@
14
14
  },
15
15
  "type": "module",
16
16
  "bin": {
17
- "prototype": "dist/cli.mjs"
17
+ "artefact-prototype": "dist/cli.mjs"
18
18
  },
19
19
  "files": [
20
20
  "dist"