@rubix0270/arboris 1.0.0 → 1.0.1
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/dist/cli.mjs +20 -14
- package/{cli/manifest.json → manifest.json} +1 -1
- package/package.json +21 -66
- package/README.md +0 -151
package/dist/cli.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
// cli/main.ts
|
|
2
|
+
// ../../cli/main.ts
|
|
3
3
|
import { resolve as resolve2 } from "node:path";
|
|
4
4
|
|
|
5
|
-
// src/lib/agents.ts
|
|
5
|
+
// ../../src/lib/agents.ts
|
|
6
6
|
var AGENT_SKILL_PATH = {
|
|
7
7
|
Cursor: (id) => `.cursor/skills/${id}/SKILL.md`,
|
|
8
8
|
Claude: (id) => `.claude/skills/${id}/SKILL.md`,
|
|
@@ -16,16 +16,18 @@ function agentSkillPath(agent, skillId) {
|
|
|
16
16
|
return AGENT_SKILL_PATH[agent](skillId);
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
// src/lib/package-root.ts
|
|
19
|
+
// ../../src/lib/package-root.ts
|
|
20
20
|
import { existsSync } from "node:fs";
|
|
21
21
|
import { dirname, join } from "node:path";
|
|
22
22
|
import { fileURLToPath } from "node:url";
|
|
23
|
+
function hasPackageAssets(dir) {
|
|
24
|
+
if (!existsSync(join(dir, "package.json"))) return false;
|
|
25
|
+
return existsSync(join(dir, "prisma", "skills")) || existsSync(join(dir, "manifest.json"));
|
|
26
|
+
}
|
|
23
27
|
function resolvePackageRoot(fromModuleUrl) {
|
|
24
28
|
let dir = dirname(fileURLToPath(fromModuleUrl));
|
|
25
|
-
for (let i = 0; i <
|
|
26
|
-
if (
|
|
27
|
-
return dir;
|
|
28
|
-
}
|
|
29
|
+
for (let i = 0; i < 10; i++) {
|
|
30
|
+
if (hasPackageAssets(dir)) return dir;
|
|
29
31
|
const parent = dirname(dir);
|
|
30
32
|
if (parent === dir) break;
|
|
31
33
|
dir = parent;
|
|
@@ -35,13 +37,18 @@ function resolvePackageRoot(fromModuleUrl) {
|
|
|
35
37
|
function defaultSkillsDir(packageRoot) {
|
|
36
38
|
return join(packageRoot, "prisma", "skills");
|
|
37
39
|
}
|
|
40
|
+
function defaultManifestPath(packageRoot) {
|
|
41
|
+
const atRoot = join(packageRoot, "manifest.json");
|
|
42
|
+
if (existsSync(atRoot)) return atRoot;
|
|
43
|
+
return join(packageRoot, "cli", "manifest.json");
|
|
44
|
+
}
|
|
38
45
|
|
|
39
|
-
// src/lib/skill-install-core.ts
|
|
46
|
+
// ../../src/lib/skill-install-core.ts
|
|
40
47
|
import { access, mkdir, writeFile } from "node:fs/promises";
|
|
41
48
|
import { constants } from "node:fs";
|
|
42
49
|
import { dirname as dirname2, resolve } from "node:path";
|
|
43
50
|
|
|
44
|
-
// src/lib/skill-file.ts
|
|
51
|
+
// ../../src/lib/skill-file.ts
|
|
45
52
|
import { readFile } from "node:fs/promises";
|
|
46
53
|
import { join as join2 } from "node:path";
|
|
47
54
|
function parseDependsOn(frontmatter) {
|
|
@@ -103,7 +110,7 @@ async function loadSkillFileContent(skillsDir, id) {
|
|
|
103
110
|
return compileSkillFile(skillsDir, id);
|
|
104
111
|
}
|
|
105
112
|
|
|
106
|
-
// src/lib/skill-install-core.ts
|
|
113
|
+
// ../../src/lib/skill-install-core.ts
|
|
107
114
|
function assertInsideWorkspace(root, target) {
|
|
108
115
|
const normalizedRoot = resolve(root);
|
|
109
116
|
const normalizedTarget = resolve(target);
|
|
@@ -167,11 +174,10 @@ async function installStackToWorkspace(input) {
|
|
|
167
174
|
return summary;
|
|
168
175
|
}
|
|
169
176
|
|
|
170
|
-
// cli/stack-resolve.ts
|
|
177
|
+
// ../../cli/stack-resolve.ts
|
|
171
178
|
import { readFile as readFile2 } from "node:fs/promises";
|
|
172
|
-
import { join as join3 } from "node:path";
|
|
173
179
|
var PACKAGE_ROOT = resolvePackageRoot(import.meta.url);
|
|
174
|
-
var MANIFEST_PATH =
|
|
180
|
+
var MANIFEST_PATH = defaultManifestPath(PACKAGE_ROOT);
|
|
175
181
|
var cached = null;
|
|
176
182
|
async function loadCliManifest() {
|
|
177
183
|
if (cached) return cached;
|
|
@@ -224,7 +230,7 @@ function formatStackList(manifest) {
|
|
|
224
230
|
}).join("\n");
|
|
225
231
|
}
|
|
226
232
|
|
|
227
|
-
// cli/main.ts
|
|
233
|
+
// ../../cli/main.ts
|
|
228
234
|
var PACKAGE_ROOT2 = resolvePackageRoot(import.meta.url);
|
|
229
235
|
var SKILLS_DIR = defaultSkillsDir(PACKAGE_ROOT2);
|
|
230
236
|
function printHelp() {
|
package/package.json
CHANGED
|
@@ -1,81 +1,36 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rubix0270/arboris",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "
|
|
5
|
-
"private": false,
|
|
6
|
-
"publishConfig": {
|
|
7
|
-
"access": "public"
|
|
8
|
-
},
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "Installe les skills IA recommandés pour ta stack (Node, React, TypeScript…).",
|
|
9
5
|
"type": "module",
|
|
10
6
|
"bin": {
|
|
11
7
|
"arboris": "dist/cli.mjs"
|
|
12
8
|
},
|
|
13
9
|
"files": [
|
|
14
10
|
"dist/cli.mjs",
|
|
15
|
-
"
|
|
11
|
+
"manifest.json",
|
|
16
12
|
"prisma/skills"
|
|
17
13
|
],
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
},
|
|
21
|
-
"scripts": {
|
|
22
|
-
"dev": "vite dev --port 3000",
|
|
23
|
-
"build": "vite build",
|
|
24
|
-
"start": "node .output/server/index.mjs",
|
|
25
|
-
"preview": "vite preview",
|
|
26
|
-
"generate-routes": "tsr generate",
|
|
27
|
-
"test": "vitest run",
|
|
28
|
-
"typecheck": "tsc --noEmit",
|
|
29
|
-
"cli:manifest": "tsx scripts/generate-cli-manifest.ts",
|
|
30
|
-
"build:cli": "npm run cli:manifest && node scripts/build-cli.mjs",
|
|
31
|
-
"prepack": "npm run build:cli",
|
|
32
|
-
"db:generate": "prisma generate",
|
|
33
|
-
"db:up": "docker compose up -d",
|
|
34
|
-
"db:down": "docker compose down",
|
|
35
|
-
"db:setup": "docker compose up -d && prisma migrate deploy && prisma db seed",
|
|
36
|
-
"db:push": "prisma db push",
|
|
37
|
-
"db:migrate": "prisma migrate dev",
|
|
38
|
-
"db:seed": "prisma db seed",
|
|
39
|
-
"db:studio": "prisma studio",
|
|
40
|
-
"db:reset": "prisma migrate reset --force"
|
|
14
|
+
"engines": {
|
|
15
|
+
"node": ">=20"
|
|
41
16
|
},
|
|
42
|
-
"
|
|
43
|
-
"
|
|
17
|
+
"publishConfig": {
|
|
18
|
+
"access": "public"
|
|
44
19
|
},
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
"@tailwindcss/vite": "^4.1.18",
|
|
48
|
-
"@tanstack/react-devtools": "latest",
|
|
49
|
-
"@tanstack/react-router": "latest",
|
|
50
|
-
"@tanstack/react-router-devtools": "latest",
|
|
51
|
-
"@tanstack/react-router-ssr-query": "latest",
|
|
52
|
-
"@tanstack/react-start": "latest",
|
|
53
|
-
"@tanstack/router-plugin": "^1.132.0",
|
|
54
|
-
"react": "^19.2.0",
|
|
55
|
-
"react-dom": "^19.2.0",
|
|
56
|
-
"tailwindcss": "^4.1.18"
|
|
20
|
+
"scripts": {
|
|
21
|
+
"prepack": "node ../../scripts/build-cli.mjs"
|
|
57
22
|
},
|
|
58
|
-
"
|
|
59
|
-
"
|
|
60
|
-
"
|
|
61
|
-
"
|
|
62
|
-
"
|
|
63
|
-
"
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
"
|
|
67
|
-
"
|
|
68
|
-
"
|
|
69
|
-
"vite": "^8.0.0",
|
|
70
|
-
"vitest": "^4.1.5"
|
|
23
|
+
"keywords": [
|
|
24
|
+
"skills",
|
|
25
|
+
"cursor",
|
|
26
|
+
"claude",
|
|
27
|
+
"ai",
|
|
28
|
+
"cli"
|
|
29
|
+
],
|
|
30
|
+
"repository": {
|
|
31
|
+
"type": "git",
|
|
32
|
+
"url": "git+https://github.com/ThePheniX974/arboris.git",
|
|
33
|
+
"directory": "packages/arboris-cli"
|
|
71
34
|
},
|
|
72
|
-
"
|
|
73
|
-
"onlyBuiltDependencies": [
|
|
74
|
-
"esbuild",
|
|
75
|
-
"lightningcss",
|
|
76
|
-
"@prisma/client",
|
|
77
|
-
"@prisma/engines",
|
|
78
|
-
"prisma"
|
|
79
|
-
]
|
|
80
|
-
}
|
|
35
|
+
"license": "MIT"
|
|
81
36
|
}
|
package/README.md
DELETED
|
@@ -1,151 +0,0 @@
|
|
|
1
|
-
# 🌳 Arboris
|
|
2
|
-
|
|
3
|
-
**Catalogue de skills IA prêts à l'emploi.** Copie le prompt d'un skill, ton agent
|
|
4
|
-
(Cursor, Claude, Codex, Copilot…) l'ajoute au codebase et applique les bonnes
|
|
5
|
-
pratiques. Zéro config.
|
|
6
|
-
|
|
7
|
-
Application full-stack construite avec **TanStack Start** (React 19), **Prisma**
|
|
8
|
-
(PostgreSQL) et **Tailwind CSS v4**, entièrement typée en **TypeScript**.
|
|
9
|
-
|
|
10
|
-
## ✨ Fonctionnalités
|
|
11
|
-
|
|
12
|
-
- **Catalogue filtrable** — recherche, filtres par catégorie, compatibilité et technologie, tri par score ou nom.
|
|
13
|
-
- **Fiches détaillées** — prompt à copier, « ce que fait le skill », étapes, déclencheurs, skills liés.
|
|
14
|
-
- **Premier pas** — choisis ta stack (Node, TypeScript, React, Next.js…) et copie tous les skills recommandés d'un coup.
|
|
15
|
-
- **Authentification** — connexion / inscription (e-mail + mot de passe, sessions HTTP-only).
|
|
16
|
-
- **Bilingue FR / EN** — bascule instantanée, mémorisée.
|
|
17
|
-
- **Thème clair / sombre** — bascule animée (View Transitions API), sans flash au chargement.
|
|
18
|
-
- **Rendu côté serveur (SSR)** — les données viennent de la base via des *server functions* TanStack Start adossées à Prisma.
|
|
19
|
-
|
|
20
|
-
## 🧱 Stack technique
|
|
21
|
-
|
|
22
|
-
| Domaine | Choix |
|
|
23
|
-
| -------------- | ---------------------------------------------------------- |
|
|
24
|
-
| Framework | TanStack Start (React 19, routing fichiers, SSR) |
|
|
25
|
-
| Server / RPC | `createServerFn` (server functions, exécutées sur Node) |
|
|
26
|
-
| ORM / Base | Prisma 6 + PostgreSQL 16 (Docker) |
|
|
27
|
-
| Styles | Tailwind CSS v4 + tokens de design (variables CSS) |
|
|
28
|
-
| Icônes/Polices | Phosphor Icons, Space Grotesk / Hanken Grotesk / JetBrains Mono |
|
|
29
|
-
| Langage | TypeScript |
|
|
30
|
-
|
|
31
|
-
## 🚀 Démarrage
|
|
32
|
-
|
|
33
|
-
> **Prérequis** : Node.js (recommandé **≥ 22.12**, fonctionne aussi en 20.19+), npm et **Docker**.
|
|
34
|
-
|
|
35
|
-
```bash
|
|
36
|
-
# 1. Installer les dépendances
|
|
37
|
-
npm install
|
|
38
|
-
|
|
39
|
-
# 2. Copier la config d'environnement
|
|
40
|
-
cp .env.example .env
|
|
41
|
-
|
|
42
|
-
# 3. Démarrer PostgreSQL (Docker) + migrations + seed
|
|
43
|
-
npm run db:up
|
|
44
|
-
npm run db:migrate # applique les migrations et lance le seed
|
|
45
|
-
|
|
46
|
-
# 4. Lancer le serveur de développement
|
|
47
|
-
npm run dev
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
L'application démarre sur **http://localhost:3000** (bascule sur un autre port
|
|
51
|
-
si 3000 est occupé).
|
|
52
|
-
|
|
53
|
-
### PostgreSQL (Docker)
|
|
54
|
-
|
|
55
|
-
Le fichier `docker-compose.yml` lance Postgres sur le port **5433** (évite les
|
|
56
|
-
conflits avec une instance locale sur 5432) :
|
|
57
|
-
|
|
58
|
-
| Variable | Valeur par défaut |
|
|
59
|
-
| -------- | ----------------- |
|
|
60
|
-
| Utilisateur | `arboris` |
|
|
61
|
-
| Mot de passe | `arboris` |
|
|
62
|
-
| Base | `arboris` |
|
|
63
|
-
| Port hôte | `5433` |
|
|
64
|
-
|
|
65
|
-
Format `DATABASE_URL` dans `.env` :
|
|
66
|
-
|
|
67
|
-
```
|
|
68
|
-
postgresql://arboris:arboris@localhost:5433/arboris
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
Commandes utiles :
|
|
72
|
-
|
|
73
|
-
```bash
|
|
74
|
-
npm run db:up # docker compose up -d
|
|
75
|
-
npm run db:down # docker compose down
|
|
76
|
-
npm run db:studio # explorateur Prisma Studio
|
|
77
|
-
npm run db:reset # réinitialise la base + reseed
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
> `SESSION_SECRET` (min. 32 caractères) est requis pour l'authentification.
|
|
81
|
-
|
|
82
|
-
## 📜 Scripts npm
|
|
83
|
-
|
|
84
|
-
| Script | Description |
|
|
85
|
-
| ----------------------- | ------------------------------------------------------ |
|
|
86
|
-
| `npm run dev` | Serveur de développement (SSR + HMR) |
|
|
87
|
-
| `npm run build` | Build de production |
|
|
88
|
-
| `npm run start` | Sert le build de production |
|
|
89
|
-
| `npm run typecheck` | Vérification des types TypeScript |
|
|
90
|
-
| `npm run generate-routes` | Régénère l'arbre de routes TanStack (`routeTree.gen.ts`) |
|
|
91
|
-
| `npm run db:up` | Démarre PostgreSQL via Docker Compose |
|
|
92
|
-
| `npm run db:down` | Arrête le conteneur PostgreSQL |
|
|
93
|
-
| `npm run db:migrate` | Crée/applique les migrations Prisma (puis seed) |
|
|
94
|
-
| `npm run db:push` | Synchronise le schéma sans migration (prototypage) |
|
|
95
|
-
| `npm run db:seed` | (Re)remplit la base avec le catalogue |
|
|
96
|
-
| `npm run db:studio` | Ouvre Prisma Studio (explorateur de données) |
|
|
97
|
-
| `npm run db:reset` | Réinitialise la base puis reseed |
|
|
98
|
-
|
|
99
|
-
## 🗂️ Structure du projet
|
|
100
|
-
|
|
101
|
-
```
|
|
102
|
-
arboris/
|
|
103
|
-
├── docker-compose.yml # PostgreSQL 16 (port 5433)
|
|
104
|
-
├── prisma/
|
|
105
|
-
│ ├── schema.prisma # Modèles Category, Stack, Skill, User
|
|
106
|
-
│ ├── catalog-data.ts # Données source du catalogue (pour le seed)
|
|
107
|
-
│ ├── seed.ts # Script de seed (prisma db seed)
|
|
108
|
-
│ └── migrations/ # Historique des migrations PostgreSQL
|
|
109
|
-
├── src/
|
|
110
|
-
│ ├── routes/
|
|
111
|
-
│ │ ├── __root.tsx # Shell HTML (head, providers, Header/Footer)
|
|
112
|
-
│ │ ├── index.tsx # Accueil (hero + index rapide)
|
|
113
|
-
│ │ ├── auth.tsx # Connexion / inscription
|
|
114
|
-
│ │ ├── skills.index.tsx # /skills — catalogue filtrable
|
|
115
|
-
│ │ ├── skills.$id.tsx # /skills/:id — fiche d'un skill
|
|
116
|
-
│ │ └── getting-started.tsx # /getting-started — premier pas par stack
|
|
117
|
-
│ ├── server/
|
|
118
|
-
│ │ ├── db.ts # Singleton PrismaClient (serveur uniquement)
|
|
119
|
-
│ │ ├── catalog.server.ts # Requêtes Prisma → objets UI
|
|
120
|
-
│ │ ├── auth.functions.ts # Login, register, logout, session
|
|
121
|
-
│ │ └── functions.ts # Server functions (getCatalog, getSkill)
|
|
122
|
-
│ ├── components/ # Header, Footer, ThemeToggle, LangSwitch, Icon
|
|
123
|
-
│ ├── lib/
|
|
124
|
-
│ │ ├── catalog.ts # Types partagés + helpers (prompts, couleurs)
|
|
125
|
-
│ │ ├── i18n.tsx # Contexte FR/EN + dictionnaires
|
|
126
|
-
│ │ ├── theme.ts # Thème clair/sombre (View Transitions)
|
|
127
|
-
│ │ └── useCopy.ts # Hook copie presse-papiers
|
|
128
|
-
│ └── styles.css # Tailwind + tokens de design Arboris
|
|
129
|
-
└── vite.config.ts # Plugins TanStack Start + Tailwind
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
## 🧠 Notes d'architecture
|
|
133
|
-
|
|
134
|
-
- **Accès base côté serveur uniquement.** Prisma n'est jamais importé côté client :
|
|
135
|
-
`src/server/db.ts` est chargé *dynamiquement* à l'intérieur des handlers de
|
|
136
|
-
server functions, donc il ne finit jamais dans le bundle navigateur. Les pages
|
|
137
|
-
appellent ces fonctions via leur `loader`.
|
|
138
|
-
- **Modèle de données.** `Category (1) — (N) Skill`, `Skill (N) — (N) Stack`
|
|
139
|
-
(relation many-to-many implicite), `User` pour l'authentification. Les listes
|
|
140
|
-
bilingues et les tableaux (`tech`, `compat`, `does`, `triggers`) sont stockés
|
|
141
|
-
en JSON sérialisé (colonnes `*Json`) et désérialisés dans `catalog.server.ts`.
|
|
142
|
-
- **Sessions.** Cookies HTTP-only chiffrés via `@tanstack/react-start/server`
|
|
143
|
-
(`useSession`), secret `SESSION_SECRET` dans `.env`.
|
|
144
|
-
- **i18n sans flash de contenu.** Le serveur rend le français par défaut ; la
|
|
145
|
-
langue mémorisée (localStorage) est appliquée au montage côté client.
|
|
146
|
-
- **Thème sans flash.** Un court script inline (`THEME_INIT_SCRIPT`) applique
|
|
147
|
-
`data-theme` avant le premier paint.
|
|
148
|
-
|
|
149
|
-
---
|
|
150
|
-
|
|
151
|
-
Généré à partir du prototype « Catalogue de skills IA ».
|