@aigne/doc-smith 0.2.11 → 0.3.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/CHANGELOG.md +19 -0
- package/agents/batch-docs-detail-generator.yaml +1 -1
- package/agents/batch-translate.yaml +3 -1
- package/agents/check-structure-plan.mjs +1 -1
- package/agents/detail-generator-and-translate.yaml +3 -0
- package/agents/detail-regenerator.yaml +3 -6
- package/agents/docs-generator.yaml +2 -5
- package/agents/find-item-by-path.mjs +1 -1
- package/agents/format-structure-plan.mjs +2 -0
- package/agents/input-generator.mjs +220 -52
- package/agents/load-config.mjs +8 -1
- package/agents/load-sources.mjs +2 -0
- package/agents/publish-docs.mjs +11 -4
- package/agents/reflective-structure-planner.yaml +2 -1
- package/agents/save-output.mjs +2 -0
- package/agents/save-single-doc.mjs +2 -0
- package/agents/structure-planning.yaml +1 -1
- package/agents/transform-detail-datasources.mjs +2 -0
- package/package.json +7 -7
- package/prompts/content-detail-generator.md +3 -1
- package/tests/test-all-validation-cases.mjs +22 -0
- package/utils/auth-utils.mjs +34 -10
- package/utils/blocklet.mjs +46 -12
- package/utils/conflict-detector.mjs +131 -0
- package/utils/constants.mjs +388 -27
- package/utils/markdown-checker.mjs +14 -0
- package/utils/utils.mjs +150 -4
package/utils/constants.mjs
CHANGED
|
@@ -9,6 +9,8 @@ export const DEFAULT_INCLUDE_PATTERNS = [
|
|
|
9
9
|
"*.jsx",
|
|
10
10
|
"*.ts",
|
|
11
11
|
"*.tsx",
|
|
12
|
+
"*.mjs",
|
|
13
|
+
"*.mts",
|
|
12
14
|
// C/C++
|
|
13
15
|
"*.c",
|
|
14
16
|
"*.cc",
|
|
@@ -87,16 +89,16 @@ export const DEFAULT_INCLUDE_PATTERNS = [
|
|
|
87
89
|
];
|
|
88
90
|
|
|
89
91
|
export const DEFAULT_EXCLUDE_PATTERNS = [
|
|
90
|
-
"aigne-docs/**",
|
|
91
|
-
"doc-smith/**",
|
|
92
|
-
"
|
|
93
|
-
"assets/**",
|
|
94
|
-
"data/**",
|
|
95
|
-
"images/**",
|
|
96
|
-
"public/**",
|
|
97
|
-
"static/**",
|
|
92
|
+
"**/aigne-docs/**",
|
|
93
|
+
"**/doc-smith/**",
|
|
94
|
+
"**/.aigne/**",
|
|
95
|
+
"**/assets/**",
|
|
96
|
+
"**/data/**",
|
|
97
|
+
"**/images/**",
|
|
98
|
+
"**/public/**",
|
|
99
|
+
"**/static/**",
|
|
98
100
|
"**/vendor/**",
|
|
99
|
-
"temp/**",
|
|
101
|
+
"**/temp/**",
|
|
100
102
|
"**/*docs/**",
|
|
101
103
|
"**/*doc/**",
|
|
102
104
|
"**/*venv/**",
|
|
@@ -122,6 +124,13 @@ export const DEFAULT_EXCLUDE_PATTERNS = [
|
|
|
122
124
|
"**/*node_modules/**",
|
|
123
125
|
"*.log",
|
|
124
126
|
"**/*test.*",
|
|
127
|
+
"**/pnpm-lock.yaml",
|
|
128
|
+
"**/yarn.lock",
|
|
129
|
+
"**/package-lock.json",
|
|
130
|
+
"**/pnpm-lock.json",
|
|
131
|
+
"**/bun.lockb",
|
|
132
|
+
"**/bun.lock",
|
|
133
|
+
"**/bun.lockb",
|
|
125
134
|
];
|
|
126
135
|
|
|
127
136
|
// Supported languages for documentation
|
|
@@ -140,33 +149,385 @@ export const SUPPORTED_LANGUAGES = [
|
|
|
140
149
|
{ code: "ar", label: "العربية (ar)", sample: "مرحبا" },
|
|
141
150
|
];
|
|
142
151
|
|
|
143
|
-
// Predefined document generation styles
|
|
152
|
+
// Predefined document generation styles based on primary purpose
|
|
144
153
|
export const DOCUMENT_STYLES = {
|
|
145
|
-
|
|
146
|
-
name: "
|
|
147
|
-
|
|
154
|
+
getStarted: {
|
|
155
|
+
name: "Get started quickly",
|
|
156
|
+
description: "Help new users go from zero to working in <30 minutes",
|
|
157
|
+
content:
|
|
158
|
+
"Optimizes for: Speed, essential steps, working examples.\nSkips: Complex edge cases, theoretical background.",
|
|
148
159
|
},
|
|
149
|
-
|
|
150
|
-
name: "
|
|
151
|
-
|
|
160
|
+
completeTasks: {
|
|
161
|
+
name: "Complete specific tasks",
|
|
162
|
+
description: "Guide users through common workflows and use cases",
|
|
163
|
+
content:
|
|
164
|
+
"Optimizes for: Step-by-step instructions, practical scenarios.\nSkips: Deep technical internals, getting started basics.",
|
|
152
165
|
},
|
|
153
|
-
|
|
154
|
-
name: "
|
|
155
|
-
|
|
166
|
+
findAnswers: {
|
|
167
|
+
name: "Find answers fast",
|
|
168
|
+
description: "Provide searchable reference for all features and APIs",
|
|
169
|
+
content:
|
|
170
|
+
"Optimizes for: Comprehensive coverage, searchability, examples.\n Skips: Narrative flow, beginner explanations.",
|
|
156
171
|
},
|
|
157
|
-
|
|
158
|
-
name: "
|
|
159
|
-
|
|
172
|
+
understandSystem: {
|
|
173
|
+
name: "Understand the system",
|
|
174
|
+
description: "Explain how it works, why design decisions were made",
|
|
175
|
+
content:
|
|
176
|
+
"Optimizes for: Architecture, concepts, decision rationale.\nSkips: Quick wins, copy-paste solutions.",
|
|
177
|
+
},
|
|
178
|
+
solveProblems: {
|
|
179
|
+
name: "Solve problems",
|
|
180
|
+
description: "Help users troubleshoot and fix issues",
|
|
181
|
+
content:
|
|
182
|
+
"Optimizes for: Error scenarios, diagnostics, solutions.\nSkips: Happy path tutorials, feature overviews.",
|
|
183
|
+
},
|
|
184
|
+
mixedPurpose: {
|
|
185
|
+
name: "Mix of above",
|
|
186
|
+
description: "Comprehensive documentation covering multiple needs",
|
|
187
|
+
content:
|
|
188
|
+
"Optimizes for: Balanced coverage, multiple entry points.\nTrade-off: Longer, requires good navigation.",
|
|
160
189
|
},
|
|
161
190
|
};
|
|
162
191
|
|
|
163
|
-
// Predefined target audiences
|
|
192
|
+
// Predefined target audiences based on who will read the documentation most often
|
|
164
193
|
export const TARGET_AUDIENCES = {
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
194
|
+
endUsers: {
|
|
195
|
+
name: "End users (non-technical)",
|
|
196
|
+
description: "People who use the product but don't code",
|
|
197
|
+
content:
|
|
198
|
+
"Writing: Plain language, UI-focused, avoid technical terms.\nExamples: Screenshots, step-by-step clicks, business outcomes.",
|
|
199
|
+
},
|
|
200
|
+
developers: {
|
|
201
|
+
name: "Developers integrating",
|
|
202
|
+
description: "Engineers adding this to their projects",
|
|
203
|
+
content:
|
|
204
|
+
"Writing: Code-first, copy-paste ready, technical accuracy.\nExamples: SDK usage, API calls, configuration snippets.",
|
|
205
|
+
},
|
|
206
|
+
devops: {
|
|
207
|
+
name: "DevOps/Infrastructure",
|
|
208
|
+
description: "Teams deploying, monitoring, maintaining systems",
|
|
209
|
+
content:
|
|
210
|
+
"Writing: Operations-focused, troubleshooting emphasis.\nExamples: Deployment configs, monitoring setup, scaling guides.",
|
|
211
|
+
},
|
|
212
|
+
decisionMakers: {
|
|
213
|
+
name: "Technical decision makers",
|
|
214
|
+
description: "Architects, leads evaluating or planning implementation",
|
|
215
|
+
content:
|
|
216
|
+
"Writing: High-level first, drill-down details available.\nExamples: Architecture diagrams, comparison tables, trade-offs.",
|
|
217
|
+
},
|
|
218
|
+
supportTeams: {
|
|
219
|
+
name: "Support teams",
|
|
220
|
+
description: "People helping others use the product",
|
|
221
|
+
content:
|
|
222
|
+
"Writing: Diagnostic-focused, common issues prominent.\nExamples: Troubleshooting flows, FAQ format, escalation paths.",
|
|
223
|
+
},
|
|
224
|
+
mixedTechnical: {
|
|
225
|
+
name: "Mixed technical audience",
|
|
226
|
+
description: "Developers, DevOps, and technical users",
|
|
227
|
+
content:
|
|
228
|
+
"Writing: Layered complexity, multiple entry points.\nExamples: Progressive disclosure, role-based navigation.",
|
|
229
|
+
},
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
// Reader knowledge level - what do readers typically know when they arrive?
|
|
233
|
+
export const READER_KNOWLEDGE_LEVELS = {
|
|
234
|
+
completeBeginners: {
|
|
235
|
+
name: "Complete beginners",
|
|
236
|
+
description: "New to this domain/technology entirely",
|
|
237
|
+
content:
|
|
238
|
+
"Content: Define terms, explain concepts, assume nothing.\nStructure: Linear progression, prerequisite checks.\nTone: Patient, educational, confidence-building.",
|
|
239
|
+
},
|
|
240
|
+
domainFamiliar: {
|
|
241
|
+
name: "Domain-familiar, tool-new",
|
|
242
|
+
description: "Know the problem space, new to this specific solution",
|
|
243
|
+
content:
|
|
244
|
+
'Content: Focus on differences, migration, unique features.\nStructure: Comparison-heavy, "coming from X" sections.\nTone: Efficient, highlight advantages, skip basics.',
|
|
245
|
+
},
|
|
246
|
+
experiencedUsers: {
|
|
247
|
+
name: "Experienced users",
|
|
248
|
+
description: "Regular users needing reference/advanced topics",
|
|
249
|
+
content:
|
|
250
|
+
"Content: Dense information, edge cases, performance tips.\nStructure: Reference-style, searchable, task-oriented.\nTone: Concise, technical precision, assume competence.",
|
|
251
|
+
},
|
|
252
|
+
emergencyTroubleshooting: {
|
|
253
|
+
name: "Emergency/troubleshooting",
|
|
254
|
+
description: "Something's broken, need to fix it quickly",
|
|
255
|
+
content:
|
|
256
|
+
"Content: Symptom → diagnosis → solution format.\nStructure: Problem-first, solution-prominent, escalation paths.\nTone: Clear, actionable, confidence-inspiring.",
|
|
257
|
+
},
|
|
258
|
+
exploringEvaluating: {
|
|
259
|
+
name: "Exploring/evaluating",
|
|
260
|
+
description: "Trying to understand if this fits their needs",
|
|
261
|
+
content:
|
|
262
|
+
"Content: Use cases, comparisons, getting started quickly.\nStructure: Multiple entry points, progressive commitment.\nTone: Persuasive but honest, show value quickly.",
|
|
263
|
+
},
|
|
264
|
+
};
|
|
265
|
+
|
|
266
|
+
// Documentation depth - how comprehensive should the documentation be?
|
|
267
|
+
export const DOCUMENTATION_DEPTH = {
|
|
268
|
+
essentialOnly: {
|
|
269
|
+
name: "Essential only",
|
|
270
|
+
description: "Cover the 80% use cases, keep it concise",
|
|
271
|
+
content:
|
|
272
|
+
"Scope: Core features, happy paths, common patterns.\nLength: Shorter sections, key examples only.\nMaintenance: Easier to keep current.",
|
|
273
|
+
},
|
|
274
|
+
balancedCoverage: {
|
|
275
|
+
name: "Balanced coverage",
|
|
276
|
+
description: "Good depth with practical examples [RECOMMENDED]",
|
|
277
|
+
content:
|
|
278
|
+
"Scope: Most features, some edge cases, multiple examples.\nLength: Moderate sections, varied example types.\nMaintenance: Reasonable update burden.",
|
|
279
|
+
},
|
|
280
|
+
comprehensive: {
|
|
281
|
+
name: "Comprehensive",
|
|
282
|
+
description: "Cover all features, edge cases, and advanced scenarios",
|
|
283
|
+
content:
|
|
284
|
+
"Scope: Everything, all parameters, extensive examples.\nLength: Detailed sections, comprehensive coverage.\nMaintenance: Higher update complexity.",
|
|
285
|
+
},
|
|
286
|
+
aiDecide: {
|
|
287
|
+
name: "Let AI decide",
|
|
288
|
+
description: "Analyze code complexity and suggest appropriate depth",
|
|
289
|
+
content:
|
|
290
|
+
"Scope: Adaptive based on codebase analysis.\nAI considers: API surface area, complexity, existing patterns.",
|
|
291
|
+
},
|
|
292
|
+
};
|
|
293
|
+
|
|
294
|
+
// Purpose to Knowledge Level mapping for default suggestions
|
|
295
|
+
export const PURPOSE_TO_KNOWLEDGE_MAPPING = {
|
|
296
|
+
getStarted: "completeBeginners", // Get started → Complete beginners
|
|
297
|
+
findAnswers: "experiencedUsers", // Find answers → Experienced users
|
|
298
|
+
solveProblems: "emergencyTroubleshooting", // Solve problems → Emergency/troubleshooting
|
|
299
|
+
exploringEvaluating: "exploringEvaluating", // Exploring → Exploring/evaluating
|
|
300
|
+
};
|
|
301
|
+
|
|
302
|
+
// Documentation Depth recommendation logic
|
|
303
|
+
export const DEPTH_RECOMMENDATION_LOGIC = {
|
|
304
|
+
// Purpose-based recommendations (highest priority)
|
|
305
|
+
purposes: {
|
|
306
|
+
getStarted: "essentialOnly", // Get started → Essential
|
|
307
|
+
},
|
|
308
|
+
// Audience-based recommendations (medium priority)
|
|
309
|
+
audiences: {
|
|
310
|
+
decisionMakers: "balancedCoverage", // Decision makers → Balanced
|
|
311
|
+
},
|
|
312
|
+
// Knowledge level-based recommendations (lowest priority)
|
|
313
|
+
knowledgeLevels: {
|
|
314
|
+
experiencedUsers: "comprehensive", // Experienced users → Comprehensive
|
|
315
|
+
},
|
|
169
316
|
};
|
|
170
317
|
|
|
171
318
|
// Component mount point ID for Discuss Kit
|
|
172
319
|
export const DISCUSS_KIT_DID = "z8ia1WEiBZ7hxURf6LwH21Wpg99vophFwSJdu";
|
|
320
|
+
|
|
321
|
+
// Discuss Kit related URLs
|
|
322
|
+
export const DISCUSS_KIT_STORE_URL =
|
|
323
|
+
"https://store.blocklet.dev/blocklets/z8ia1WEiBZ7hxURf6LwH21Wpg99vophFwSJdu";
|
|
324
|
+
export const BLOCKLET_ADD_COMPONENT_DOCS =
|
|
325
|
+
"https://www.arcblock.io/docs/blocklet-developer/en/7zbw0GQXgcD6sCcjVfwqqT2s";
|
|
326
|
+
|
|
327
|
+
// Conflict rules configuration for documentation generation
|
|
328
|
+
export const CONFLICT_RULES = {
|
|
329
|
+
// Internal conflicts within the same question (multi-select conflicts)
|
|
330
|
+
internalConflicts: {
|
|
331
|
+
documentPurpose: [
|
|
332
|
+
{
|
|
333
|
+
conflictItems: ["getStarted", "findAnswers"],
|
|
334
|
+
severity: "severe",
|
|
335
|
+
reason:
|
|
336
|
+
"Quick start guide (skips complex cases) conflicts with comprehensive API reference (skips beginner explanations)",
|
|
337
|
+
suggestion: "Choose one as primary goal, or consider creating layered documentation",
|
|
338
|
+
},
|
|
339
|
+
{
|
|
340
|
+
conflictItems: ["getStarted", "understandSystem"],
|
|
341
|
+
severity: "severe",
|
|
342
|
+
reason: "30-minute quick start conflicts with deep architectural concept explanations",
|
|
343
|
+
suggestion: "Consider creating separate quick start and architecture design docs",
|
|
344
|
+
},
|
|
345
|
+
{
|
|
346
|
+
conflictItems: ["completeTasks", "understandSystem"],
|
|
347
|
+
severity: "moderate",
|
|
348
|
+
reason:
|
|
349
|
+
"Practical task guidance and theoretical concept explanation have different focuses",
|
|
350
|
+
suggestion:
|
|
351
|
+
"Can be handled through layered document structure: concepts first, then practice",
|
|
352
|
+
},
|
|
353
|
+
{
|
|
354
|
+
conflictItems: ["getStarted", "solveProblems"],
|
|
355
|
+
severity: "moderate",
|
|
356
|
+
reason:
|
|
357
|
+
"Quick start (success cases) and troubleshooting (error scenarios) have different focuses",
|
|
358
|
+
suggestion: "Create separate tutorial and troubleshooting guides",
|
|
359
|
+
},
|
|
360
|
+
{
|
|
361
|
+
conflictItems: ["findAnswers", "solveProblems"],
|
|
362
|
+
severity: "moderate",
|
|
363
|
+
reason: "API reference and diagnostic documentation have different organizational logic",
|
|
364
|
+
suggestion: "Add troubleshooting section to reference documentation",
|
|
365
|
+
},
|
|
366
|
+
],
|
|
367
|
+
targetAudienceTypes: [
|
|
368
|
+
{
|
|
369
|
+
conflictItems: ["endUsers", "developers"],
|
|
370
|
+
severity: "severe",
|
|
371
|
+
reason:
|
|
372
|
+
"Non-technical users (avoid technical terms) conflict with developers (code-first approach)",
|
|
373
|
+
suggestion:
|
|
374
|
+
"Create separate documentation for different audiences or use layered content design",
|
|
375
|
+
},
|
|
376
|
+
{
|
|
377
|
+
conflictItems: ["endUsers", "devops"],
|
|
378
|
+
severity: "severe",
|
|
379
|
+
reason: "Non-technical users and operations technical personnel have very different needs",
|
|
380
|
+
suggestion: "Consider creating separate user guides and operations documentation",
|
|
381
|
+
},
|
|
382
|
+
{
|
|
383
|
+
conflictItems: ["endUsers", "decisionMakers"],
|
|
384
|
+
severity: "severe",
|
|
385
|
+
reason:
|
|
386
|
+
"Non-technical users (simple language) and decision makers (architecture diagrams) have different needs",
|
|
387
|
+
suggestion: "Create high-level overview for management and user operation manuals",
|
|
388
|
+
},
|
|
389
|
+
{
|
|
390
|
+
conflictItems: ["developers", "decisionMakers"],
|
|
391
|
+
severity: "moderate",
|
|
392
|
+
reason:
|
|
393
|
+
"Developers (code details) and decision makers (high-level overview) have different focus areas",
|
|
394
|
+
suggestion: "Use progressive disclosure: high-level first, then details",
|
|
395
|
+
},
|
|
396
|
+
{
|
|
397
|
+
conflictItems: ["supportTeams", "decisionMakers"],
|
|
398
|
+
severity: "moderate",
|
|
399
|
+
reason:
|
|
400
|
+
"Support teams (problem diagnosis) and decision makers (architecture decisions) have different focus areas",
|
|
401
|
+
suggestion: "Include operational considerations in decision documentation",
|
|
402
|
+
},
|
|
403
|
+
],
|
|
404
|
+
},
|
|
405
|
+
|
|
406
|
+
// Cross-question conflicts (conflicts between different questions)
|
|
407
|
+
crossConflicts: [
|
|
408
|
+
{
|
|
409
|
+
conditions: {
|
|
410
|
+
documentPurpose: ["getStarted"],
|
|
411
|
+
readerKnowledgeLevel: ["experiencedUsers"],
|
|
412
|
+
},
|
|
413
|
+
severity: "severe",
|
|
414
|
+
reason:
|
|
415
|
+
"Quick start tutorials are not suitable for experienced users who need advanced features and best practices",
|
|
416
|
+
action: "filter",
|
|
417
|
+
conflictingOptions: {
|
|
418
|
+
readerKnowledgeLevel: ["experiencedUsers"],
|
|
419
|
+
},
|
|
420
|
+
},
|
|
421
|
+
{
|
|
422
|
+
conditions: {
|
|
423
|
+
documentPurpose: ["findAnswers"],
|
|
424
|
+
readerKnowledgeLevel: ["completeBeginners"],
|
|
425
|
+
},
|
|
426
|
+
severity: "severe",
|
|
427
|
+
reason:
|
|
428
|
+
"API reference documentation skips beginner explanations and is not suitable for complete beginners",
|
|
429
|
+
action: "filter",
|
|
430
|
+
conflictingOptions: {
|
|
431
|
+
readerKnowledgeLevel: ["completeBeginners"],
|
|
432
|
+
},
|
|
433
|
+
},
|
|
434
|
+
{
|
|
435
|
+
conditions: {
|
|
436
|
+
documentPurpose: ["understandSystem"],
|
|
437
|
+
readerKnowledgeLevel: ["emergencyTroubleshooting"],
|
|
438
|
+
},
|
|
439
|
+
severity: "severe",
|
|
440
|
+
reason:
|
|
441
|
+
"System architecture explanations are not suitable for emergency troubleshooting scenarios",
|
|
442
|
+
action: "filter",
|
|
443
|
+
conflictingOptions: {
|
|
444
|
+
readerKnowledgeLevel: ["emergencyTroubleshooting"],
|
|
445
|
+
},
|
|
446
|
+
},
|
|
447
|
+
{
|
|
448
|
+
conditions: {
|
|
449
|
+
targetAudienceTypes: ["endUsers"],
|
|
450
|
+
readerKnowledgeLevel: ["experiencedUsers"],
|
|
451
|
+
},
|
|
452
|
+
severity: "severe",
|
|
453
|
+
reason: "Non-technical users are typically not experienced technical users",
|
|
454
|
+
action: "filter",
|
|
455
|
+
conflictingOptions: {
|
|
456
|
+
readerKnowledgeLevel: ["experiencedUsers"],
|
|
457
|
+
},
|
|
458
|
+
},
|
|
459
|
+
{
|
|
460
|
+
conditions: {
|
|
461
|
+
targetAudienceTypes: ["decisionMakers"],
|
|
462
|
+
readerKnowledgeLevel: ["emergencyTroubleshooting"],
|
|
463
|
+
},
|
|
464
|
+
severity: "severe",
|
|
465
|
+
reason: "Decision makers typically do not directly handle emergency technical failures",
|
|
466
|
+
action: "filter",
|
|
467
|
+
conflictingOptions: {
|
|
468
|
+
readerKnowledgeLevel: ["emergencyTroubleshooting"],
|
|
469
|
+
},
|
|
470
|
+
},
|
|
471
|
+
{
|
|
472
|
+
conditions: {
|
|
473
|
+
documentPurpose: ["getStarted"],
|
|
474
|
+
documentationDepth: ["comprehensive"],
|
|
475
|
+
},
|
|
476
|
+
severity: "severe",
|
|
477
|
+
reason: "Quick start tutorials contradict comprehensive coverage documentation",
|
|
478
|
+
action: "filter",
|
|
479
|
+
conflictingOptions: {
|
|
480
|
+
documentationDepth: ["comprehensive"],
|
|
481
|
+
},
|
|
482
|
+
},
|
|
483
|
+
{
|
|
484
|
+
conditions: {
|
|
485
|
+
documentPurpose: ["solveProblems"],
|
|
486
|
+
documentationDepth: ["essentialOnly"],
|
|
487
|
+
},
|
|
488
|
+
severity: "moderate",
|
|
489
|
+
reason:
|
|
490
|
+
"Troubleshooting usually needs to cover edge cases, basic content alone may not be sufficient",
|
|
491
|
+
action: "filter",
|
|
492
|
+
conflictingOptions: {
|
|
493
|
+
documentationDepth: ["essentialOnly"],
|
|
494
|
+
},
|
|
495
|
+
},
|
|
496
|
+
{
|
|
497
|
+
conditions: {
|
|
498
|
+
targetAudienceTypes: ["endUsers"],
|
|
499
|
+
documentationDepth: ["comprehensive"],
|
|
500
|
+
},
|
|
501
|
+
severity: "moderate",
|
|
502
|
+
reason: "Non-technical users typically do not need comprehensive technical coverage",
|
|
503
|
+
action: "filter",
|
|
504
|
+
conflictingOptions: {
|
|
505
|
+
documentationDepth: ["comprehensive"],
|
|
506
|
+
},
|
|
507
|
+
},
|
|
508
|
+
{
|
|
509
|
+
conditions: {
|
|
510
|
+
targetAudienceTypes: ["decisionMakers"],
|
|
511
|
+
documentationDepth: ["essentialOnly"],
|
|
512
|
+
},
|
|
513
|
+
severity: "moderate",
|
|
514
|
+
reason: "Decision makers may need more comprehensive information to make decisions",
|
|
515
|
+
action: "filter",
|
|
516
|
+
conflictingOptions: {
|
|
517
|
+
documentationDepth: ["essentialOnly"],
|
|
518
|
+
},
|
|
519
|
+
},
|
|
520
|
+
{
|
|
521
|
+
conditions: {
|
|
522
|
+
readerKnowledgeLevel: ["completeBeginners"],
|
|
523
|
+
documentationDepth: ["essentialOnly"],
|
|
524
|
+
},
|
|
525
|
+
severity: "moderate",
|
|
526
|
+
reason: "Complete beginners may need more explanations, not just core content",
|
|
527
|
+
action: "filter",
|
|
528
|
+
conflictingOptions: {
|
|
529
|
+
documentationDepth: ["essentialOnly"],
|
|
530
|
+
},
|
|
531
|
+
},
|
|
532
|
+
],
|
|
533
|
+
};
|
|
@@ -335,6 +335,20 @@ export async function checkMarkdown(markdown, source = "content", options = {})
|
|
|
335
335
|
}
|
|
336
336
|
}
|
|
337
337
|
|
|
338
|
+
// Check for numbered list format in node labels (for both [] and {} syntax)
|
|
339
|
+
const nodeLabelWithNumberRegex =
|
|
340
|
+
/[A-Za-z0-9_]+\["([^"]*\d+\.\s[^"]*)"\]|[A-Za-z0-9_]+{"([^}]*\d+\.\s[^}]*)"}/g;
|
|
341
|
+
let numberMatch;
|
|
342
|
+
while ((numberMatch = nodeLabelWithNumberRegex.exec(mermaidContent)) !== null) {
|
|
343
|
+
const label = numberMatch[1] || numberMatch[2];
|
|
344
|
+
// Check if the label contains numbered list format
|
|
345
|
+
if (/\d+\.\s/.test(label)) {
|
|
346
|
+
errorMessages.push(
|
|
347
|
+
`Unsupported markdown: list - Found numbered list format in Mermaid node label in ${source} at line ${line}: "${label}" - numbered lists in node labels cause rendering issues`,
|
|
348
|
+
);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
|
|
338
352
|
// Check for special characters in node labels that should be quoted
|
|
339
353
|
const nodeWithSpecialCharsRegex = /([A-Za-z0-9_]+)\[([^\]]*[(){}:;,\-\s.][^\]]*)\]/g;
|
|
340
354
|
let specialCharMatch;
|
package/utils/utils.mjs
CHANGED
|
@@ -2,9 +2,16 @@ import { execSync } from "node:child_process";
|
|
|
2
2
|
import { accessSync, constants, existsSync, mkdirSync, readdirSync, statSync } from "node:fs";
|
|
3
3
|
import fs from "node:fs/promises";
|
|
4
4
|
import path from "node:path";
|
|
5
|
-
import chalk from "chalk";
|
|
6
5
|
import { parse } from "yaml";
|
|
7
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
DEFAULT_EXCLUDE_PATTERNS,
|
|
8
|
+
DEFAULT_INCLUDE_PATTERNS,
|
|
9
|
+
DOCUMENT_STYLES,
|
|
10
|
+
TARGET_AUDIENCES,
|
|
11
|
+
READER_KNOWLEDGE_LEVELS,
|
|
12
|
+
DOCUMENTATION_DEPTH,
|
|
13
|
+
SUPPORTED_LANGUAGES,
|
|
14
|
+
} from "./constants.mjs";
|
|
8
15
|
|
|
9
16
|
/**
|
|
10
17
|
* Normalize path to absolute path for consistent comparison
|
|
@@ -94,7 +101,6 @@ export async function saveDocWithTranslations({
|
|
|
94
101
|
|
|
95
102
|
await fs.writeFile(mainFilePath, finalContent, "utf8");
|
|
96
103
|
results.push({ path: mainFilePath, success: true });
|
|
97
|
-
console.log(chalk.green(`Saved: ${chalk.cyan(mainFilePath)}`));
|
|
98
104
|
}
|
|
99
105
|
|
|
100
106
|
// Process all translations
|
|
@@ -113,7 +119,6 @@ export async function saveDocWithTranslations({
|
|
|
113
119
|
|
|
114
120
|
await fs.writeFile(translatePath, finalTranslationContent, "utf8");
|
|
115
121
|
results.push({ path: translatePath, success: true });
|
|
116
|
-
console.log(chalk.green(`Saved: ${chalk.cyan(translatePath)}`));
|
|
117
122
|
}
|
|
118
123
|
} catch (err) {
|
|
119
124
|
results.push({ path: docPath, success: false, error: err.message });
|
|
@@ -703,3 +708,144 @@ export async function getProjectInfo() {
|
|
|
703
708
|
fromGitHub,
|
|
704
709
|
};
|
|
705
710
|
}
|
|
711
|
+
|
|
712
|
+
/**
|
|
713
|
+
* Process configuration fields - convert keys to actual content
|
|
714
|
+
* @param {Object} config - Parsed configuration
|
|
715
|
+
* @returns {Object} Processed configuration with content fields
|
|
716
|
+
*/
|
|
717
|
+
export function processConfigFields(config) {
|
|
718
|
+
const processed = {};
|
|
719
|
+
const allRulesContent = [];
|
|
720
|
+
|
|
721
|
+
// Check if original rules field has content
|
|
722
|
+
const existingRules = config.rules?.trim();
|
|
723
|
+
if (existingRules) {
|
|
724
|
+
allRulesContent.push(existingRules);
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
// Process document purpose (array)
|
|
728
|
+
let purposeContents = "";
|
|
729
|
+
if (config.documentPurpose && Array.isArray(config.documentPurpose)) {
|
|
730
|
+
purposeContents = config.documentPurpose
|
|
731
|
+
.map((key) => DOCUMENT_STYLES[key]?.content)
|
|
732
|
+
.filter(Boolean)
|
|
733
|
+
.join("\n\n");
|
|
734
|
+
|
|
735
|
+
if (purposeContents) {
|
|
736
|
+
allRulesContent.push(purposeContents);
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
// Process target audience types (array)
|
|
741
|
+
let audienceContents = "";
|
|
742
|
+
let audienceNames = "";
|
|
743
|
+
if (config.targetAudienceTypes && Array.isArray(config.targetAudienceTypes)) {
|
|
744
|
+
// Get content for rules
|
|
745
|
+
audienceContents = config.targetAudienceTypes
|
|
746
|
+
.map((key) => TARGET_AUDIENCES[key]?.content)
|
|
747
|
+
.filter(Boolean)
|
|
748
|
+
.join("\n\n");
|
|
749
|
+
|
|
750
|
+
// Get names for targetAudience field
|
|
751
|
+
audienceNames = config.targetAudienceTypes
|
|
752
|
+
.map((key) => TARGET_AUDIENCES[key]?.name)
|
|
753
|
+
.filter(Boolean)
|
|
754
|
+
.join(", ");
|
|
755
|
+
|
|
756
|
+
if (audienceContents) {
|
|
757
|
+
allRulesContent.push(audienceContents);
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
if (audienceNames) {
|
|
761
|
+
// Check if original targetAudience field has content
|
|
762
|
+
const existingTargetAudience = config.targetAudience?.trim();
|
|
763
|
+
const newAudienceNames = audienceNames;
|
|
764
|
+
|
|
765
|
+
if (existingTargetAudience) {
|
|
766
|
+
processed.targetAudience = `${existingTargetAudience}\n\n${newAudienceNames}`;
|
|
767
|
+
} else {
|
|
768
|
+
processed.targetAudience = newAudienceNames;
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
// Process reader knowledge level (single value)
|
|
774
|
+
let knowledgeContent = "";
|
|
775
|
+
if (config.readerKnowledgeLevel) {
|
|
776
|
+
knowledgeContent = READER_KNOWLEDGE_LEVELS[config.readerKnowledgeLevel]?.content;
|
|
777
|
+
if (knowledgeContent) {
|
|
778
|
+
processed.readerKnowledgeContent = knowledgeContent;
|
|
779
|
+
allRulesContent.push(`Reader Knowledge Level:\n${knowledgeContent}`);
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
// Process documentation depth (single value)
|
|
784
|
+
let depthContent = "";
|
|
785
|
+
if (config.documentationDepth) {
|
|
786
|
+
depthContent = DOCUMENTATION_DEPTH[config.documentationDepth]?.content;
|
|
787
|
+
if (depthContent) {
|
|
788
|
+
processed.documentationDepthContent = depthContent;
|
|
789
|
+
allRulesContent.push(`Documentation Depth:\n${depthContent}`);
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
// Combine all content into rules field
|
|
794
|
+
if (allRulesContent.length > 0) {
|
|
795
|
+
processed.rules = allRulesContent.join("\n\n");
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
return processed;
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
/**
|
|
802
|
+
* Detect system language and map to supported language code
|
|
803
|
+
* @returns {string} - Supported language code (defaults to 'en' if detection fails or unsupported)
|
|
804
|
+
*/
|
|
805
|
+
export function detectSystemLanguage() {
|
|
806
|
+
try {
|
|
807
|
+
// Try multiple methods to detect system language
|
|
808
|
+
let systemLocale = null;
|
|
809
|
+
|
|
810
|
+
// Method 1: Environment variables (most reliable on Unix systems)
|
|
811
|
+
systemLocale = process.env.LANG || process.env.LANGUAGE || process.env.LC_ALL;
|
|
812
|
+
|
|
813
|
+
// Method 2: Node.js Intl API (fallback)
|
|
814
|
+
if (!systemLocale) {
|
|
815
|
+
try {
|
|
816
|
+
systemLocale = Intl.DateTimeFormat().resolvedOptions().locale;
|
|
817
|
+
} catch (_error) {
|
|
818
|
+
// Intl API failed, continue to fallback
|
|
819
|
+
}
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
if (!systemLocale) {
|
|
823
|
+
return "en"; // Default fallback
|
|
824
|
+
}
|
|
825
|
+
|
|
826
|
+
// Extract language code from locale (e.g., 'zh_CN' -> 'zh', 'en_US' -> 'en')
|
|
827
|
+
const langCode = systemLocale.split(/[-_]/)[0].toLowerCase();
|
|
828
|
+
|
|
829
|
+
// Map to supported language codes
|
|
830
|
+
const supportedLang = SUPPORTED_LANGUAGES.find((lang) => lang.code === langCode);
|
|
831
|
+
if (supportedLang) {
|
|
832
|
+
return supportedLang.code;
|
|
833
|
+
}
|
|
834
|
+
|
|
835
|
+
// Handle special cases for Chinese variants
|
|
836
|
+
if (langCode === "zh") {
|
|
837
|
+
// Check for Traditional Chinese indicators
|
|
838
|
+
const fullLocale = systemLocale.toLowerCase();
|
|
839
|
+
if (fullLocale.includes("tw") || fullLocale.includes("hk") || fullLocale.includes("mo")) {
|
|
840
|
+
return "zh-TW";
|
|
841
|
+
}
|
|
842
|
+
return "zh"; // Default to Simplified Chinese
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
// Return default if no match found
|
|
846
|
+
return "en";
|
|
847
|
+
} catch (_error) {
|
|
848
|
+
// Any error in detection, return default
|
|
849
|
+
return "en";
|
|
850
|
+
}
|
|
851
|
+
}
|