Commit Graph

8 Commits

Author SHA1 Message Date
3b251c8174 feat: Add packages/site — landing vitrine (Vue 3 + Tailwind 4)
- Scaffold packages/site with 11 Vue components: hero (animated terminal), features, showcase, work groups, how-it-works, security, FAQ accordion, footer
- i18n EN/FR via vue-i18n with 82+ keys, autodetect navigator.language, toggle without reload
- Animated timeline (terminal, dialog, toast) ported from design, scroll-reveal, copy buttons (2 instances)
- Self-hosted JetBrains Mono fonts (@fontsource), optimized assets (mark 28KB, og-cover 1200×630)
- SEO: canonical, og:image, theme-color, robots.txt, sitemap.xml for git-arboretum.com
- Monorepo integration (decoupled from npm release): build:site / dev:site / preview:site scripts
- CI: add build:site step to ci.yml for early detection; create .gitea/workflows/prod.yml for FTPS deploy (lftp mirror) to git-arboretum.com
- Validated builds ✓ and UI rendering (EN/FR headless test) ✓
2026-06-19 10:02:22 +02:00
073f2cf9ca fix(packaging): inline @arboretum/shared dans dist/ — tarball autonome (abandon de bundleDependencies)
bundleDependencies d'un paquet *workspace* est instable selon l'environnement npm
(mode -w, exécution en root sur un runner CI) : npm voyait shared comme un lien
workspace et n'embarquait AUCUN fichier ("bundled files: 0"), publiant un tarball
cassé — `Cannot find module '@arboretum/shared'` au démarrage chez le consommateur.
C'est ce que détectait (à juste titre) le job pack-smoke.

Nouveau mécanisme, identique sur tout environnement : scripts/inline-shared.mjs
(hook prepack) copie le JS compilé de shared dans dist/_shared/ et réécrit l'import
bare '@arboretum/shared' des .js du serveur vers ce chemin relatif. shared passe en
devDependency (résolu en dev via le symlink workspace, jamais exigé du consommateur).
Plus de node_modules embarqué ni de symlink dans le tarball.

ci.yml (pack-smoke) packe désormais en -w (comme release.yml) et asserte l'autonomie
(dist/_shared présent + zéro import bare) avant le boot smoke.

Validé de bout en bout sur checkout propre : npm ci + build + pack -w + install dans
projet vierge + boot -> HTTP 401, et 263 tests verts.
2026-06-19 09:46:05 +02:00
36bfeb057e ci(release): publish idempotent via tolérance 409 + SBOM non-bloquant
Le pré-check `npm view` était un signal non fiable contre le registre npm de
Gitea (faux négatif masqué par >/dev/null) : le publish s'exécutait malgré une
version déjà présente et échouait en 409 Conflict, faisant rougir la release
alors que l'artefact était bien publié.

On tente désormais toujours `npm publish` et on traite son 409 « already exists »
— le signal faisant autorité — comme un succès idempotent ; tout autre échec
reste fatal. L'étape est isolée dans la condition d'un `if` pour ne pas
déclencher le `set -e` du shell Actions.

Le SBOM passe en continue-on-error : un bonus supply-chain ne doit jamais faire
échouer une release dont le publish a réussi.
2026-06-19 08:58:30 +02:00
7a3c119f36 ci(release): publication idempotente + SBOM via upload-artifact@v3 (Gitea/GHES)
upload-artifact@v4 (@actions/artifact v2+) n'est pas supporté par Gitea Actions.
Le publish skip désormais une version déjà publiée (re-push de tag sans échec).
2026-06-18 17:47:45 +02:00
33295a7aaf feat: clean install (Gitea en dur, scan off) + durcissement sécurité entreprise
Gitea
- lien « Code source » hardcodé (REPO_SOURCE_URL) vers le dépôt, toujours visible
- retrait complet du réglage configurable (api.ts, route+store settings, SettingsView, i18n, help, tests)

Découverte des dépôts
- aucune racine de scan par défaut → pas de scan au premier démarrage (clean install)
- corrige la découverte des dépôts à l'INTÉRIEUR d'une racine qui est elle-même un repo
  (depth 0 = conteneur de scan, on descend ; depth > 0 = feuille)

Sécurité « enterprise-deployable »
- en-têtes HTTP durcis (CSP, X-Frame-Options, nosniff, Referrer-Policy, HSTS conditionnel, no-store API), header Server retiré
- permissions DB 0o600 / dossier de données 0o700 ; error handler sanitisé ; garde Content-Type sur les mutations
- chiffrement au repos AES-256-GCM des secrets (server_secret, clé privée VAPID) via SecretBox
- journal d'audit (migration #7) + endpoint /audit-logs + RGPD export/effacement + UI Réglages
- SECURITY.md, docs/ENTERPRISE_DEPLOYMENT.md, sections README EN/FR, SBOM CycloneDX en CI

CI
- pack-smoke packe depuis le contexte du package (cd packages/server) au lieu de « npm pack -w » :
  corrige l'embarquement de @arboretum/shared dans le tarball

Purge des données personnelles du dépôt public
- suppression de spikes/s4-discovery/result.json, reformulation du VERDICT
- chemin de test générique, anonymisation des 5 fixtures de dialogues
2026-06-18 16:44:25 +02:00
5c1c2a8591 fix(ci): exécuter prepack explicitement avant npm pack (embarquement @arboretum/shared)
Le job pack-smoke échouait sur le runner Gitea : « npm pack -w » n'y déclenche
pas le hook prepack (contrairement à « npm publish -w », d'où la 1.2.0 publiée
intacte). vendor-shared ne matérialisait donc pas @arboretum/shared, et npm
retombait sur le symlink workspace (non bundlé) → tarball sans le runtime partagé.

On lance désormais prepack explicitement, on vérifie la matérialisation de
@arboretum/shared/dist/index.js, puis on packe en --ignore-scripts. On nettoie
aussi /tmp/tarballs (runner persistant). Validé en repro locale (npm 10 et 11).
2026-06-18 13:13:48 +02:00
08166c108b release: @johanleroy/git-arboretum 1.0.0 — publication sur le registre Gitea
Some checks failed
Release / Publish to Gitea npm registry (push) Has been cancelled
- renomme le paquet en @johanleroy/git-arboretum (scope routé vers le registre npm Gitea privé)
- embarque @arboretum/shared via bundleDependencies (scripts/vendor-shared.mjs au prepack)
- joint README/LICENSE au tarball (scripts/copy-meta.mjs) + metadata, keywords, publishConfig
- CI pack-smoke en mono-tarball avec assertion bundleDep ; nouveau workflow release.yml (publish sur tag v*)
- version 1.0.0 ; README mis à jour (install scopé + service systemd)
2026-06-17 13:53:30 +02:00
e9404cb567 P1 complete: web front, test suite, CI — acceptance ALL GREEN
Fan-out integration + fixes found by the test/acceptance pass:
- FIX ring-buffer: chunks >= capacity skipped bytes now count into the
  monotonic offset (invariant: stream byte k lives at k % capacity) —
  window order was corrupted on unaligned big chunks
- FIX auth: non-numeric cookie expiry no longer bypasses expiration
- FIX protocol: safe-integer validation on ack.bytes / hello.protocol
- FIX @fastify/websocket v11: websocket route must be registered in an
  encapsulated context after plugin load (handler got REST signature)
- FIX flow-control deadlock found by e2e acceptance: client only ACKs
  on data receipt, so pausing with an unACKed residue in (LOW,
  ACK_EVERY] stalled both sides at 0.9 MB. ACK_EVERY now 64 KiB (<=
  LOW invariant, tested) + trailing debounced ACK in the web client
- Web: Vue 3 + Vite + Pinia + Tailwind 4 + vue-i18n (EN/FR) + xterm 6
  (fit + webgl fallback), multiplexed ws-client with reconnect/backoff
  and resync epochs
- Tests: 100 vitest (protocol fuzz, ring edges, auth, pty-manager flow
  control with mocked pty, REST e2e) ; CI Node 22/24 + pack-smoke
- scripts/acceptance-p1.mjs: real daemon + real WS client — boot,
  login, attach, stdin, 10 MB flood w/ ACK (13.7 MB/1.9s, RSS bounded),
  brutal disconnect + replay resync, kill broadcast, SIGTERM drain
2026-06-11 22:29:58 +02:00