scaffold-doc-cli 1.0.6 → 1.0.8

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.
Files changed (2) hide show
  1. package/index.js +89 -53
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -69,25 +69,25 @@ async function init() {
69
69
  -->
70
70
  # ${answers.projectName} Documentation
71
71
 
72
- ## Overview
72
+ ## Vue d'ensemble
73
73
  <!-- AI_CONTENT_START -->
74
- Documentation initialized.
74
+ Documentation initialisée.
75
75
  <!-- AI_CONTENT_END -->
76
76
 
77
- ## Quick Links
78
- - [Getting Started](./getting-started.md)
77
+ ## Liens Rapides
78
+ - [Démarrage](./getting-started.md)
79
79
  - [Architecture](./architecture.md)
80
80
  `;
81
81
  await fs.writeFile(path.join(docsDir, 'index.md'), indexContent);
82
82
 
83
83
  // getting-started.md
84
- const gettingStartedContent = `# Getting Started
84
+ const gettingStartedContent = `# Démarrage
85
85
 
86
86
  <!--
87
- INSTRUCTION: Document the installation and setup steps.
87
+ INSTRUCTION: Documentez les étapes d'installation et de configuration.
88
88
  -->
89
89
 
90
- ## Prerequisites
90
+ ## Prérequis
91
91
  <!-- AI_CONTENT_START -->
92
92
  <!-- AI_CONTENT_END -->
93
93
 
@@ -137,10 +137,10 @@ docs_dir: .docs
137
137
  theme: readthedocs
138
138
 
139
139
  nav:
140
- - Home: index.md
141
- - Getting Started: getting-started.md
140
+ - Accueil: index.md
141
+ - Démarrage: getting-started.md
142
142
  - Architecture: architecture.md
143
- - Reference:
143
+ - Référence:
144
144
  ${referenceNav}
145
145
  `;
146
146
  await fs.writeFile(path.join(process.cwd(), 'mkdocs.yml'), mkdocsContent);
@@ -189,7 +189,8 @@ jobs:
189
189
  run: node .github/scripts/doc-sync.mjs
190
190
 
191
191
  - name: Create Pull Request
192
- uses: peter-evans/create-pull-request@v5
192
+ id: cpr
193
+ uses: peter-evans/create-pull-request@v7
193
194
  with:
194
195
  token: \${{ secrets.GITHUB_TOKEN }}
195
196
  commit-message: "docs: auto-generated documentation updates"
@@ -202,6 +203,12 @@ jobs:
202
203
  base: \${{ github.head_ref || github.ref_name }}
203
204
  delete-branch: true
204
205
  add-paths: .docs
206
+
207
+ - name: Check outputs
208
+ if: \${{ steps.cpr.outputs.pull-request-number }}
209
+ run: |
210
+ echo "Pull Request Number - \${{ steps.cpr.outputs.pull-request-number }}"
211
+ echo "Pull Request URL - \${{ steps.cpr.outputs.pull-request-url }}"
205
212
  `;
206
213
  await fs.writeFile(path.join(workflowDir, 'ai-doc-sync.yml'), workflowContent);
207
214
  console.log(chalk.green('✔ .github/workflows/ai-doc-sync.yml created'));
@@ -217,13 +224,22 @@ const genAI = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });
217
224
  async function main() {
218
225
  console.log("Starting AI Doc Sync...");
219
226
 
227
+ // 1. Detect Changed Files
220
228
  // 1. Detect Changed Files
221
229
  let changedFiles = [];
230
+ let forceRegenerate = false;
231
+
222
232
  try {
223
- const output = execSync('git diff --name-only HEAD~1 HEAD').toString();
224
- changedFiles = output.split('\\n').filter(f => f && !f.startsWith('.docs') && !f.startsWith('.github'));
233
+ const commitMsg = execSync('git log -1 --pretty=%B').toString();
234
+ if (commitMsg.includes('regenerate-doc')) {
235
+ console.log('Trigger "regenerate-doc" détecté. Synchronisation de tous les fichiers...');
236
+ forceRegenerate = true;
237
+ }
225
238
  } catch (e) {
226
- console.warn("HEAD~1 not found (likely first commit). Syncing all tracked files...");
239
+ // Ignore error
240
+ }
241
+
242
+ if (forceRegenerate) {
227
243
  try {
228
244
  const output = execSync('git ls-tree -r HEAD --name-only').toString();
229
245
  changedFiles = output.split('\\n').filter(f => f && !f.startsWith('.docs') && !f.startsWith('.github'));
@@ -231,6 +247,20 @@ async function main() {
231
247
  console.error("Failed to list files:", err.message);
232
248
  return;
233
249
  }
250
+ } else {
251
+ try {
252
+ const output = execSync('git diff --name-only HEAD~1 HEAD 2>/dev/null').toString();
253
+ changedFiles = output.split('\\n').filter(f => f && !f.startsWith('.docs') && !f.startsWith('.github'));
254
+ } catch (e) {
255
+ console.warn("HEAD~1 not found (likely first commit). Syncing all tracked files...");
256
+ try {
257
+ const output = execSync('git ls-tree -r HEAD --name-only').toString();
258
+ changedFiles = output.split('\\n').filter(f => f && !f.startsWith('.docs') && !f.startsWith('.github'));
259
+ } catch (err) {
260
+ console.error("Failed to list files:", err.message);
261
+ return;
262
+ }
263
+ }
234
264
  }
235
265
 
236
266
  if (changedFiles.length === 0) {
@@ -250,27 +280,33 @@ async function main() {
250
280
  }
251
281
 
252
282
  // 3. Prompt Gemini
253
- const model = genAI.getGenerativeModel({ model: "gemini-2.5-flash" });
254
-
283
+ // 3. Prompt Gemini (using @google/genai SDK)
284
+ // No need to get model instance first in this SDK version based on user snippet
285
+
286
+
255
287
  const prompt = \`
256
- You are a technical documentation assistant.
257
- Analyze the following code changes and update the documentation in the .docs/ directory.
288
+ Tu es un assistant de documentation technique expert.
289
+ Analyse les modifications de code suivantes et mets à jour la documentation dans le dossier .docs/.
258
290
 
259
- Rules:
260
- 1. Output MUST be a valid JSON object where keys are file paths (relative to .docs/, e.g., "reference/controllers.md") and values are the NEW content of that file.
261
- 2. You can create new files if necessary.
262
- 3. You can update existing files (e.g., getting-started.md, architecture.md).
263
- 4. Focus on accuracy and clarity.
264
- 5. Do not include markdown code fence blocks in your response, just the raw JSON string.
265
-
266
- Code Context:
291
+ Règles:
292
+ 1. La langue de sortie DOIT être le FRANÇAIS.
293
+ 2. La sortie DOIT être un objet JSON valide où les clés sont les chemins de fichiers (relatifs à .docs/, ex: "reference/controllers.md") et les valeurs sont le NOUVEAU contenu de ce fichier.
294
+ 3. Tu peux créer de nouveaux fichiers si nécessaire.
295
+ 4. Tu peux mettre à jour les fichiers existants (ex: getting-started.md, architecture.md).
296
+ 5. Concentre-toi sur la précision et la clarté.
297
+ 6. N'inclus PAS de blocs de code markdown dans ta réponse, juste la chaîne JSON brute.
298
+
299
+ Contexte du code:
267
300
  \${context}
268
301
  \`;
269
302
 
270
303
  try {
271
- const result = await model.generateContent(prompt);
272
- const text = result.response.text();
273
-
304
+ const result = await genAI.models.generateContent({
305
+ model: "gemini-2.5-flash",
306
+ contents: prompt
307
+ });
308
+ const text = result.text;
309
+
274
310
  // Simple cleanup if model adds code blocks
275
311
  const jsonStr = text.replace(/\\\`\\\`\\\`json/g, '').replace(/\\\`\\\`\\\`/g, '').trim();
276
312
  const updates = JSON.parse(jsonStr);
@@ -279,11 +315,11 @@ async function main() {
279
315
  for (const [relativePath, content] of Object.entries(updates)) {
280
316
  const fullPath = path.join(process.cwd(), '.docs', relativePath);
281
317
  const dir = path.dirname(fullPath);
282
-
318
+
283
319
  if (!fs.existsSync(dir)) {
284
320
  fs.mkdirSync(dir, { recursive: true });
285
321
  }
286
-
322
+
287
323
  fs.writeFileSync(fullPath, content);
288
324
  console.log(\`Updated: .docs/\${relativePath}\`);
289
325
  }
@@ -322,9 +358,9 @@ function getStackConfig(stack) {
322
358
  if (stack.includes('Symfony')) {
323
359
  return {
324
360
  files: {
325
- 'controllers.md': () => `${commonHeader('Controllers')}# Controllers\n\n<!-- INSTRUCTION: Document all Symfony Controllers found in /src/Controller -->\n\n## List\n<!-- AI_CONTENT_START -->\n<!-- AI_CONTENT_END -->`,
326
- 'entities.md': () => `${commonHeader('Entities')}# Entities\n\n<!-- INSTRUCTION: Document all Doctrine Entities found in /src/Entity -->\n\n## List\n<!-- AI_CONTENT_START -->\n<!-- AI_CONTENT_END -->`,
327
- 'services.md': () => `${commonHeader('Services')}# Services\n\n<!-- INSTRUCTION: Document core application services found in /src/Service -->\n\n## List\n<!-- AI_CONTENT_START -->\n<!-- AI_CONTENT_END -->`,
361
+ 'controllers.md': () => `${commonHeader('Controllers')}# Contrôleurs\n\n<!-- INSTRUCTION: Documentez tous les contrôleurs Symfony trouvés dans /src/Controller -->\n\n## Liste\n<!-- AI_CONTENT_START -->\n<!-- AI_CONTENT_END -->`,
362
+ 'entities.md': () => `${commonHeader('Entities')}# Entités\n\n<!-- INSTRUCTION: Documentez toutes les entités Doctrine trouvées dans /src/Entity -->\n\n## Liste\n<!-- AI_CONTENT_START -->\n<!-- AI_CONTENT_END -->`,
363
+ 'services.md': () => `${commonHeader('Services')}# Services\n\n<!-- INSTRUCTION: Documentez les services principaux trouvés dans /src/Service -->\n\n## Liste\n<!-- AI_CONTENT_START -->\n<!-- AI_CONTENT_END -->`,
328
364
  }
329
365
  };
330
366
  }
@@ -333,9 +369,9 @@ function getStackConfig(stack) {
333
369
  if (stack.includes('Laravel')) {
334
370
  return {
335
371
  files: {
336
- 'controllers.md': () => `${commonHeader('Controllers')}# Controllers\n\n<!-- INSTRUCTION: Document Http Controllers found in /app/Http/Controllers -->\n\n## List\n<!-- AI_CONTENT_START -->\n<!-- AI_CONTENT_END -->`,
337
- 'models.md': () => `${commonHeader('Models')}# Models\n\n<!-- INSTRUCTION: Document Eloquent Models found in /app/Models -->\n\n## List\n<!-- AI_CONTENT_START -->\n<!-- AI_CONTENT_END -->`,
338
- 'routes.md': () => `${commonHeader('Routes')}# Routes\n\n<!-- INSTRUCTION: Document application routes found in /routes -->\n\n## List\n<!-- AI_CONTENT_START -->\n<!-- AI_CONTENT_END -->`,
372
+ 'controllers.md': () => `${commonHeader('Controllers')}# Contrôleurs\n\n<!-- INSTRUCTION: Documentez les contrôleurs Http trouvés dans /app/Http/Controllers -->\n\n## Liste\n<!-- AI_CONTENT_START -->\n<!-- AI_CONTENT_END -->`,
373
+ 'models.md': () => `${commonHeader('Models')}# Modèles\n\n<!-- INSTRUCTION: Documentez les modèles Eloquent trouvés dans /app/Models -->\n\n## Liste\n<!-- AI_CONTENT_START -->\n<!-- AI_CONTENT_END -->`,
374
+ 'routes.md': () => `${commonHeader('Routes')}# Routes\n\n<!-- INSTRUCTION: Documentez les routes trouvées dans /routes -->\n\n## Liste\n<!-- AI_CONTENT_START -->\n<!-- AI_CONTENT_END -->`,
339
375
  }
340
376
  };
341
377
  }
@@ -344,9 +380,9 @@ function getStackConfig(stack) {
344
380
  if (stack.includes('Nuxt')) {
345
381
  return {
346
382
  files: {
347
- 'components.md': () => `${commonHeader('Components')}# Components\n\n<!-- INSTRUCTION: Document Vue components in /components -->\n\n## List\n<!-- AI_CONTENT_START -->\n<!-- AI_CONTENT_END -->`,
348
- 'composables.md': () => `${commonHeader('Composables')}# Composables\n\n<!-- INSTRUCTION: Document auto-imported composables in /composables -->\n\n## List\n<!-- AI_CONTENT_START -->\n<!-- AI_CONTENT_END -->`,
349
- 'server-routes.md': () => `${commonHeader('Server Routes')}# Server Routes\n\n<!-- INSTRUCTION: Document Nitro server routes in /server/api -->\n\n## List\n<!-- AI_CONTENT_START -->\n<!-- AI_CONTENT_END -->`,
383
+ 'components.md': () => `${commonHeader('Components')}# Composants\n\n<!-- INSTRUCTION: Documentez les composants Vue dans /components -->\n\n## Liste\n<!-- AI_CONTENT_START -->\n<!-- AI_CONTENT_END -->`,
384
+ 'composables.md': () => `${commonHeader('Composables')}# Composables\n\n<!-- INSTRUCTION: Documentez les composables auto-importés dans /composables -->\n\n## Liste\n<!-- AI_CONTENT_START -->\n<!-- AI_CONTENT_END -->`,
385
+ 'server-routes.md': () => `${commonHeader('Server Routes')}# Routes Serveur\n\n<!-- INSTRUCTION: Documentez les routes serveur Nitro dans /server/api -->\n\n## Liste\n<!-- AI_CONTENT_START -->\n<!-- AI_CONTENT_END -->`,
350
386
  }
351
387
  };
352
388
  }
@@ -355,9 +391,9 @@ function getStackConfig(stack) {
355
391
  if (stack.includes('React') || stack.includes('Next') || stack.includes('Vue') || stack.includes('Angular') || stack.includes('Svelte')) {
356
392
  return {
357
393
  files: {
358
- 'components.md': () => `${commonHeader('Components')}# Components\n\n<!-- INSTRUCTION: Document UI components -->\n\n## List\n<!-- AI_CONTENT_START -->\n<!-- AI_CONTENT_END -->`,
359
- 'hooks.md': () => `${commonHeader('Hooks')}# Hooks\n\n<!-- INSTRUCTION: Document custom hooks/composables -->\n\n## List\n<!-- AI_CONTENT_START -->\n<!-- AI_CONTENT_END -->`,
360
- 'api.md': () => `${commonHeader('API')}# API Integration\n\n<!-- INSTRUCTION: Document API clients or fetch wrappers -->\n\n## List\n<!-- AI_CONTENT_START -->\n<!-- AI_CONTENT_END -->`,
394
+ 'components.md': () => `${commonHeader('Components')}# Composants\n\n<!-- INSTRUCTION: Documentez les composants UI -->\n\n## Liste\n<!-- AI_CONTENT_START -->\n<!-- AI_CONTENT_END -->`,
395
+ 'hooks.md': () => `${commonHeader('Hooks')}# Hooks\n\n<!-- INSTRUCTION: Documentez les hooks personnalisés -->\n\n## Liste\n<!-- AI_CONTENT_START -->\n<!-- AI_CONTENT_END -->`,
396
+ 'api.md': () => `${commonHeader('API')}# Intégration API\n\n<!-- INSTRUCTION: Documentez les clients API -->\n\n## Liste\n<!-- AI_CONTENT_START -->\n<!-- AI_CONTENT_END -->`,
361
397
  }
362
398
  };
363
399
  }
@@ -366,9 +402,9 @@ function getStackConfig(stack) {
366
402
  if (stack.includes('Django')) {
367
403
  return {
368
404
  files: {
369
- 'models.md': () => `${commonHeader('Models')}# Models\n\n<!-- INSTRUCTION: Document Django Models -->\n\n## List\n<!-- AI_CONTENT_START -->\n<!-- AI_CONTENT_END -->`,
370
- 'views.md': () => `${commonHeader('Views')}# Views\n\n<!-- INSTRUCTION: Document Django Views/ViewSets -->\n\n## List\n<!-- AI_CONTENT_START -->\n<!-- AI_CONTENT_END -->`,
371
- 'admin.md': () => `${commonHeader('Admin')}# Admin Customization\n\n<!-- INSTRUCTION: Document Admin classes -->\n\n## List\n<!-- AI_CONTENT_START -->\n<!-- AI_CONTENT_END -->`,
405
+ 'models.md': () => `${commonHeader('Models')}# Modèles\n\n<!-- INSTRUCTION: Documentez les modèles Django -->\n\n## Liste\n<!-- AI_CONTENT_START -->\n<!-- AI_CONTENT_END -->`,
406
+ 'views.md': () => `${commonHeader('Views')}# Vues\n\n<!-- INSTRUCTION: Documentez les Vues/ViewSets Django -->\n\n## Liste\n<!-- AI_CONTENT_START -->\n<!-- AI_CONTENT_END -->`,
407
+ 'admin.md': () => `${commonHeader('Admin')}# Administration\n\n<!-- INSTRUCTION: Documentez les classes d'administration -->\n\n## Liste\n<!-- AI_CONTENT_START -->\n<!-- AI_CONTENT_END -->`,
372
408
  }
373
409
  };
374
410
  }
@@ -377,8 +413,8 @@ function getStackConfig(stack) {
377
413
  if (stack.includes('FastAPI')) {
378
414
  return {
379
415
  files: {
380
- 'endpoints.md': () => `${commonHeader('Endpoints')}# Endpoints\n\n<!-- INSTRUCTION: Document FastAPI routes and decorators -->\n\n## List\n<!-- AI_CONTENT_START -->\n<!-- AI_CONTENT_END -->`,
381
- 'models.md': () => `${commonHeader('Models')}# Pydantic Models\n\n<!-- INSTRUCTION: Document Pydantic models -->\n\n## List\n<!-- AI_CONTENT_START -->\n<!-- AI_CONTENT_END -->`,
416
+ 'endpoints.md': () => `${commonHeader('Endpoints')}# Endpoints\n\n<!-- INSTRUCTION: Documentez les routes et décorateurs FastAPI -->\n\n## Liste\n<!-- AI_CONTENT_START -->\n<!-- AI_CONTENT_END -->`,
417
+ 'models.md': () => `${commonHeader('Models')}# Modèles Pydantic\n\n<!-- INSTRUCTION: Documentez les modèles Pydantic -->\n\n## Liste\n<!-- AI_CONTENT_START -->\n<!-- AI_CONTENT_END -->`,
382
418
  }
383
419
  };
384
420
  }
@@ -387,9 +423,9 @@ function getStackConfig(stack) {
387
423
  if (stack.includes('Spring') || stack.includes('Java')) {
388
424
  return {
389
425
  files: {
390
- 'controllers.md': () => `${commonHeader('Controllers')}# Controllers\n\n<!-- INSTRUCTION: Document REST Controllers -->\n\n## List\n<!-- AI_CONTENT_START -->\n<!-- AI_CONTENT_END -->`,
391
- 'services.md': () => `${commonHeader('Services')}# Services\n\n<!-- INSTRUCTION: Document Service beans -->\n\n## List\n<!-- AI_CONTENT_START -->\n<!-- AI_CONTENT_END -->`,
392
- 'domain.md': () => `${commonHeader('Domain')}# Domain Models\n\n<!-- INSTRUCTION: Document Entity classes -->\n\n## List\n<!-- AI_CONTENT_START -->\n<!-- AI_CONTENT_END -->`,
426
+ 'controllers.md': () => `${commonHeader('Controllers')}# Contrôleurs\n\n<!-- INSTRUCTION: Documentez les contrôleurs REST -->\n\n## Liste\n<!-- AI_CONTENT_START -->\n<!-- AI_CONTENT_END -->`,
427
+ 'services.md': () => `${commonHeader('Services')}# Services\n\n<!-- INSTRUCTION: Documentez les beans Service -->\n\n## Liste\n<!-- AI_CONTENT_START -->\n<!-- AI_CONTENT_END -->`,
428
+ 'domain.md': () => `${commonHeader('Domain')}# Modèles de Domaine\n\n<!-- INSTRUCTION: Documentez les classes d'Entité -->\n\n## Liste\n<!-- AI_CONTENT_START -->\n<!-- AI_CONTENT_END -->`,
393
429
  }
394
430
  };
395
431
  }
@@ -397,8 +433,8 @@ function getStackConfig(stack) {
397
433
  // --- Default Fallback ---
398
434
  return {
399
435
  files: {
400
- 'api.md': () => `${commonHeader('API')}# API Reference\n\n<!-- INSTRUCTION: Document public API endpoints -->\n\n## List\n<!-- AI_CONTENT_START -->\n<!-- AI_CONTENT_END -->`,
401
- 'modules.md': () => `${commonHeader('Modules')}# Core Modules\n\n<!-- INSTRUCTION: Document core logical modules -->\n\n## List\n<!-- AI_CONTENT_START -->\n<!-- AI_CONTENT_END -->`,
436
+ 'api.md': () => `${commonHeader('API')}# Référence API\n\n<!-- INSTRUCTION: Documentez les endpoints API publics -->\n\n## Liste\n<!-- AI_CONTENT_START -->\n<!-- AI_CONTENT_END -->`,
437
+ 'modules.md': () => `${commonHeader('Modules')}# Modules principaux\n\n<!-- INSTRUCTION: Documentez les modules logiques principaux -->\n\n## Liste\n<!-- AI_CONTENT_START -->\n<!-- AI_CONTENT_END -->`,
402
438
  }
403
439
  };
404
440
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "scaffold-doc-cli",
3
- "version": "1.0.6",
3
+ "version": "1.0.8",
4
4
  "description": "CLI tool to scaffold standardized documentation structure for projects.",
5
5
  "main": "index.js",
6
6
  "type": "module",