deepdoc 2.3.2__tar.gz → 2.3.4__tar.gz

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 (149) hide show
  1. {deepdoc-2.3.2 → deepdoc-2.3.4}/PKG-INFO +5 -5
  2. {deepdoc-2.3.2 → deepdoc-2.3.4}/README.md +4 -4
  3. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/__init__.py +1 -1
  4. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/generator/generation.py +12 -0
  5. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/generator/post_processors.py +132 -2
  6. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/llm/client.py +7 -4
  7. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/site/builder/scaffold_files.py +2 -15
  8. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc.egg-info/PKG-INFO +5 -5
  9. {deepdoc-2.3.2 → deepdoc-2.3.4}/pyproject.toml +1 -4
  10. {deepdoc-2.3.2 → deepdoc-2.3.4}/LICENSE +0 -0
  11. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/__main__.py +0 -0
  12. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/benchmark_v2.py +0 -0
  13. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/call_graph.py +0 -0
  14. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/changelog_writer.py +0 -0
  15. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/chatbot/__init__.py +0 -0
  16. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/chatbot/answer_mixin.py +0 -0
  17. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/chatbot/chunker.py +0 -0
  18. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/chatbot/constants.py +0 -0
  19. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/chatbot/deep_research.py +0 -0
  20. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/chatbot/docs_summary.py +0 -0
  21. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/chatbot/embeddings.py +0 -0
  22. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/chatbot/indexer.py +0 -0
  23. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/chatbot/linking.py +0 -0
  24. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/chatbot/live_fallback_mixin.py +0 -0
  25. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/chatbot/persistence.py +0 -0
  26. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/chatbot/providers.py +0 -0
  27. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/chatbot/retrieval_mixin.py +0 -0
  28. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/chatbot/routes.py +0 -0
  29. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/chatbot/scaffold.py +0 -0
  30. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/chatbot/service.py +0 -0
  31. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/chatbot/settings.py +0 -0
  32. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/chatbot/source_archive.py +0 -0
  33. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/chatbot/symbol_index.py +0 -0
  34. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/chatbot/types.py +0 -0
  35. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/cli.py +0 -0
  36. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/config.py +0 -0
  37. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/generator/__init__.py +0 -0
  38. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/generator/evidence.py +0 -0
  39. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/generator/validation.py +0 -0
  40. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/llm/__init__.py +0 -0
  41. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/llm/json_utils.py +0 -0
  42. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/llm/litellm_compat.py +0 -0
  43. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/manifest.py +0 -0
  44. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/openapi.py +0 -0
  45. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/parser/__init__.py +0 -0
  46. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/parser/api_detector.py +0 -0
  47. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/parser/base.py +0 -0
  48. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/parser/go_parser.py +0 -0
  49. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/parser/js_ts_parser.py +0 -0
  50. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/parser/php_parser.py +0 -0
  51. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/parser/python_parser.py +0 -0
  52. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/parser/registry.py +0 -0
  53. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/parser/routes/__init__.py +0 -0
  54. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/parser/routes/base.py +0 -0
  55. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/parser/routes/common.py +0 -0
  56. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/parser/routes/detector.py +0 -0
  57. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/parser/routes/django.py +0 -0
  58. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/parser/routes/express.py +0 -0
  59. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/parser/routes/falcon.py +0 -0
  60. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/parser/routes/fastify.py +0 -0
  61. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/parser/routes/go.py +0 -0
  62. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/parser/routes/js_shared.py +0 -0
  63. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/parser/routes/laravel.py +0 -0
  64. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/parser/routes/nestjs.py +0 -0
  65. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/parser/routes/python_shared.py +0 -0
  66. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/parser/routes/registry.py +0 -0
  67. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/parser/routes/repo_resolver.py +0 -0
  68. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/parser/vue_parser.py +0 -0
  69. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/persistence_v2.py +0 -0
  70. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/pipeline_v2.py +0 -0
  71. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/planner/__init__.py +0 -0
  72. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/planner/bucket_injection.py +0 -0
  73. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/planner/bucket_refinement.py +0 -0
  74. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/planner/common.py +0 -0
  75. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/planner/endpoint_refs.py +0 -0
  76. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/planner/engine.py +0 -0
  77. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/planner/flow_candidates.py +0 -0
  78. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/planner/heuristics.py +0 -0
  79. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/planner/nav_shaping.py +0 -0
  80. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/planner/specializations.py +0 -0
  81. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/planner/topology.py +0 -0
  82. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/planner/utils.py +0 -0
  83. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/prompts/__init__.py +0 -0
  84. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/prompts/bucket_types.py +0 -0
  85. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/prompts/page_types.py +0 -0
  86. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/prompts/selectors.py +0 -0
  87. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/prompts/system.py +0 -0
  88. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/prompts/update.py +0 -0
  89. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/py.typed +0 -0
  90. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/scanner/__init__.py +0 -0
  91. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/scanner/artifacts.py +0 -0
  92. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/scanner/clustering.py +0 -0
  93. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/scanner/common.py +0 -0
  94. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/scanner/database.py +0 -0
  95. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/scanner/endpoints.py +0 -0
  96. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/scanner/integrations.py +0 -0
  97. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/scanner/runtime.py +0 -0
  98. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/scanner/utils.py +0 -0
  99. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/site/__init__.py +0 -0
  100. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/site/builder/__init__.py +0 -0
  101. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/site/builder/chatbot_components.py +0 -0
  102. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/site/builder/common.py +0 -0
  103. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/site/builder/engine.py +0 -0
  104. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/site/builder/mdx_utils.py +0 -0
  105. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/site/builder/templates.py +0 -0
  106. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/smart_update_v2.py +0 -0
  107. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/source_metadata.py +0 -0
  108. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/updater_v2.py +0 -0
  109. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc/v2_models.py +0 -0
  110. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc.egg-info/SOURCES.txt +0 -0
  111. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc.egg-info/dependency_links.txt +0 -0
  112. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc.egg-info/entry_points.txt +0 -0
  113. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc.egg-info/requires.txt +0 -0
  114. {deepdoc-2.3.2 → deepdoc-2.3.4}/deepdoc.egg-info/top_level.txt +0 -0
  115. {deepdoc-2.3.2 → deepdoc-2.3.4}/setup.cfg +0 -0
  116. {deepdoc-2.3.2 → deepdoc-2.3.4}/tests/test_benchmark_scorecard.py +0 -0
  117. {deepdoc-2.3.2 → deepdoc-2.3.4}/tests/test_call_graph.py +0 -0
  118. {deepdoc-2.3.2 → deepdoc-2.3.4}/tests/test_changelog.py +0 -0
  119. {deepdoc-2.3.2 → deepdoc-2.3.4}/tests/test_chatbot_config.py +0 -0
  120. {deepdoc-2.3.2 → deepdoc-2.3.4}/tests/test_chatbot_embeddings.py +0 -0
  121. {deepdoc-2.3.2 → deepdoc-2.3.4}/tests/test_chatbot_eval.py +0 -0
  122. {deepdoc-2.3.2 → deepdoc-2.3.4}/tests/test_chatbot_index.py +0 -0
  123. {deepdoc-2.3.2 → deepdoc-2.3.4}/tests/test_chatbot_persistence.py +0 -0
  124. {deepdoc-2.3.2 → deepdoc-2.3.4}/tests/test_chatbot_providers.py +0 -0
  125. {deepdoc-2.3.2 → deepdoc-2.3.4}/tests/test_chatbot_query.py +0 -0
  126. {deepdoc-2.3.2 → deepdoc-2.3.4}/tests/test_chatbot_relationship.py +0 -0
  127. {deepdoc-2.3.2 → deepdoc-2.3.4}/tests/test_chatbot_scaffold.py +0 -0
  128. {deepdoc-2.3.2 → deepdoc-2.3.4}/tests/test_chatbot_source_archive.py +0 -0
  129. {deepdoc-2.3.2 → deepdoc-2.3.4}/tests/test_classify.py +0 -0
  130. {deepdoc-2.3.2 → deepdoc-2.3.4}/tests/test_cli_generate.py +0 -0
  131. {deepdoc-2.3.2 → deepdoc-2.3.4}/tests/test_cli_serve.py +0 -0
  132. {deepdoc-2.3.2 → deepdoc-2.3.4}/tests/test_cli_update.py +0 -0
  133. {deepdoc-2.3.2 → deepdoc-2.3.4}/tests/test_flow_candidates.py +0 -0
  134. {deepdoc-2.3.2 → deepdoc-2.3.4}/tests/test_framework_fixtures.py +0 -0
  135. {deepdoc-2.3.2 → deepdoc-2.3.4}/tests/test_framework_support.py +0 -0
  136. {deepdoc-2.3.2 → deepdoc-2.3.4}/tests/test_fumadocs_builder.py +0 -0
  137. {deepdoc-2.3.2 → deepdoc-2.3.4}/tests/test_generation_evidence.py +0 -0
  138. {deepdoc-2.3.2 → deepdoc-2.3.4}/tests/test_internal_docs_metadata.py +0 -0
  139. {deepdoc-2.3.2 → deepdoc-2.3.4}/tests/test_litellm_compat.py +0 -0
  140. {deepdoc-2.3.2 → deepdoc-2.3.4}/tests/test_llm_json_utils.py +0 -0
  141. {deepdoc-2.3.2 → deepdoc-2.3.4}/tests/test_parallel_pipeline.py +0 -0
  142. {deepdoc-2.3.2 → deepdoc-2.3.4}/tests/test_parser_ranges.py +0 -0
  143. {deepdoc-2.3.2 → deepdoc-2.3.4}/tests/test_planner_consolidation.py +0 -0
  144. {deepdoc-2.3.2 → deepdoc-2.3.4}/tests/test_planner_granularity.py +0 -0
  145. {deepdoc-2.3.2 → deepdoc-2.3.4}/tests/test_route_registry.py +0 -0
  146. {deepdoc-2.3.2 → deepdoc-2.3.4}/tests/test_runtime_scan.py +0 -0
  147. {deepdoc-2.3.2 → deepdoc-2.3.4}/tests/test_smart_update.py +0 -0
  148. {deepdoc-2.3.2 → deepdoc-2.3.4}/tests/test_stale.py +0 -0
  149. {deepdoc-2.3.2 → deepdoc-2.3.4}/tests/test_state.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: deepdoc
3
- Version: 2.3.2
3
+ Version: 2.3.4
4
4
  Summary: Auto-generate beautiful docs from any codebase
5
5
  Author: Pranav Kumar
6
6
  License: MIT
@@ -82,7 +82,7 @@ DeepDoc scans your repo, builds a bucket-based documentation plan, generates ric
82
82
  - **Bucket-based documentation architecture** — system, feature, endpoint, integration, and database buckets instead of one-file-per-page noise.
83
83
  - **Multi-step AI planner** — classifies the repo, proposes buckets, then assigns files, symbols, artifacts, and dependencies into a final reader-first plan.
84
84
  - **Giant-file handling** — large files are decomposed into feature-aligned clusters so a single controller can feed multiple doc pages.
85
- - **MDX compile gate** — every page is compile-checked before being written; broken MDX is auto-fixed via LLM retry or degraded to safe Markdown rather than shipped.
85
+ - **MDX-safe generation** — generated pages are repaired and validated in Python before being written; deploy-time quality gates block failed, invalid, or stub pages before the Fumadocs build.
86
86
  - **Evidence-first chatbot answers** — final code proof is hydrated from archived source snippets with exact file paths and line ranges, not just retrieval guesses.
87
87
  - **Incremental updates** — `deepdoc update` regenerates only stale or structurally affected docs against the last synced commit.
88
88
  - **OpenAPI-aware API docs** — auto-detects OpenAPI/Swagger specs and stages interactive `/api/*` pages in the generated site.
@@ -129,7 +129,7 @@ pip install click litellm gitpython rich pyyaml jinja2
129
129
  pip install -e . --no-deps
130
130
  ```
131
131
 
132
- You will also need **Node 18+** on `PATH`. DeepDoc uses Node at generate time to compile-check each MDX page before writing it, and at `serve`/`deploy` time for the Fumadocs site. The small set of MDX validation dependencies installs into `deepdoc/generator/mdx_validator/node_modules/` automatically on first `deepdoc generate`.
132
+ You will also need **Node 18+** on `PATH` when you run `deepdoc serve` or `deepdoc deploy`. DeepDoc generation itself uses Python-side repair and validation; Node is only needed for the generated Fumadocs site.
133
133
 
134
134
  ### Verify installation
135
135
 
@@ -346,7 +346,7 @@ deepdoc generate --exclude "tests/**"
346
346
 
347
347
  1. **Phase 1: Scan** — Walk the repo, parse supported languages, detect endpoints, config/setup artifacts, runtime surfaces, integration signals, and OpenAPI specs.
348
348
  2. **Phase 2: Plan** — Run the multi-step bucket planner. It classifies the repo, proposes bucket candidates, and assigns files/symbols/artifacts to the final doc structure.
349
- 3. **Phase 3: Generate** — Generate bucket pages in batches with parallel workers. High-level buckets are AI-planned; scanned endpoints enrich grouped API-reference pages instead of creating one page per route. Each page passes through an MDX compile-check (with bounded LLM-driven retry on failure) before being written to disk.
349
+ 3. **Phase 3: Generate** — Generate bucket pages in batches with parallel workers. High-level buckets are AI-planned; scanned endpoints enrich grouped API-reference pages instead of creating one page per route. Each page passes through Python-side MDX repair, grounding validation, and bounded quality retries before being written to disk.
350
350
  4. **Phase 4: API Ref** — Stage OpenAPI assets for the generated Fumadocs `/api/*` pages when a spec exists.
351
351
  5. **Phase 5: Build** — Write the generated `site/` Fumadocs scaffold, page tree, search route, and static assets from the generated plan.
352
352
 
@@ -1562,7 +1562,7 @@ deepdoc generate --force # Full regen with new model
1562
1562
  ## Requirements
1563
1563
 
1564
1564
  - Python 3.10+
1565
- - **Node 18+** on `PATH` — used at generate time for MDX compile validation, and at `serve`/`deploy` time for the Fumadocs site
1565
+ - **Node 18+** on `PATH` — used by `deepdoc serve` and `deepdoc deploy` for the generated Fumadocs site
1566
1566
  - Git (for `deepdoc update` and `deepdoc deploy`)
1567
1567
  - An LLM API key (or Ollama running locally)
1568
1568
 
@@ -43,7 +43,7 @@ DeepDoc scans your repo, builds a bucket-based documentation plan, generates ric
43
43
  - **Bucket-based documentation architecture** — system, feature, endpoint, integration, and database buckets instead of one-file-per-page noise.
44
44
  - **Multi-step AI planner** — classifies the repo, proposes buckets, then assigns files, symbols, artifacts, and dependencies into a final reader-first plan.
45
45
  - **Giant-file handling** — large files are decomposed into feature-aligned clusters so a single controller can feed multiple doc pages.
46
- - **MDX compile gate** — every page is compile-checked before being written; broken MDX is auto-fixed via LLM retry or degraded to safe Markdown rather than shipped.
46
+ - **MDX-safe generation** — generated pages are repaired and validated in Python before being written; deploy-time quality gates block failed, invalid, or stub pages before the Fumadocs build.
47
47
  - **Evidence-first chatbot answers** — final code proof is hydrated from archived source snippets with exact file paths and line ranges, not just retrieval guesses.
48
48
  - **Incremental updates** — `deepdoc update` regenerates only stale or structurally affected docs against the last synced commit.
49
49
  - **OpenAPI-aware API docs** — auto-detects OpenAPI/Swagger specs and stages interactive `/api/*` pages in the generated site.
@@ -90,7 +90,7 @@ pip install click litellm gitpython rich pyyaml jinja2
90
90
  pip install -e . --no-deps
91
91
  ```
92
92
 
93
- You will also need **Node 18+** on `PATH`. DeepDoc uses Node at generate time to compile-check each MDX page before writing it, and at `serve`/`deploy` time for the Fumadocs site. The small set of MDX validation dependencies installs into `deepdoc/generator/mdx_validator/node_modules/` automatically on first `deepdoc generate`.
93
+ You will also need **Node 18+** on `PATH` when you run `deepdoc serve` or `deepdoc deploy`. DeepDoc generation itself uses Python-side repair and validation; Node is only needed for the generated Fumadocs site.
94
94
 
95
95
  ### Verify installation
96
96
 
@@ -307,7 +307,7 @@ deepdoc generate --exclude "tests/**"
307
307
 
308
308
  1. **Phase 1: Scan** — Walk the repo, parse supported languages, detect endpoints, config/setup artifacts, runtime surfaces, integration signals, and OpenAPI specs.
309
309
  2. **Phase 2: Plan** — Run the multi-step bucket planner. It classifies the repo, proposes bucket candidates, and assigns files/symbols/artifacts to the final doc structure.
310
- 3. **Phase 3: Generate** — Generate bucket pages in batches with parallel workers. High-level buckets are AI-planned; scanned endpoints enrich grouped API-reference pages instead of creating one page per route. Each page passes through an MDX compile-check (with bounded LLM-driven retry on failure) before being written to disk.
310
+ 3. **Phase 3: Generate** — Generate bucket pages in batches with parallel workers. High-level buckets are AI-planned; scanned endpoints enrich grouped API-reference pages instead of creating one page per route. Each page passes through Python-side MDX repair, grounding validation, and bounded quality retries before being written to disk.
311
311
  4. **Phase 4: API Ref** — Stage OpenAPI assets for the generated Fumadocs `/api/*` pages when a spec exists.
312
312
  5. **Phase 5: Build** — Write the generated `site/` Fumadocs scaffold, page tree, search route, and static assets from the generated plan.
313
313
 
@@ -1523,7 +1523,7 @@ deepdoc generate --force # Full regen with new model
1523
1523
  ## Requirements
1524
1524
 
1525
1525
  - Python 3.10+
1526
- - **Node 18+** on `PATH` — used at generate time for MDX compile validation, and at `serve`/`deploy` time for the Fumadocs site
1526
+ - **Node 18+** on `PATH` — used by `deepdoc serve` and `deepdoc deploy` for the generated Fumadocs site
1527
1527
  - Git (for `deepdoc update` and `deepdoc deploy`)
1528
1528
  - An LLM API key (or Ollama running locally)
1529
1529
 
@@ -1,3 +1,3 @@
1
1
  """DeepDoc — Auto-generate beautiful docs from any codebase."""
2
2
 
3
- __version__ = "2.3.2"
3
+ __version__ = "2.3.4"
@@ -611,6 +611,10 @@ class BucketGenerationEngine:
611
611
  content = repair_unbalanced_code_fences(content)
612
612
  content = normalize_explanatory_lines_outside_fences(content)
613
613
  content = repair_dangling_plain_fences(content)
614
+ content = normalize_fumadocs_directives(content)
615
+ content = fix_frontmatter_description(content)
616
+ content = fix_bare_mermaid_fences(content)
617
+ content = fix_leaf_card_directives(content)
614
618
  content = escape_mdx_angle_hazards(content)
615
619
  content = repair_internal_doc_links(
616
620
  content,
@@ -650,6 +654,10 @@ class BucketGenerationEngine:
650
654
  content = repair_unbalanced_code_fences(content)
651
655
  content = normalize_explanatory_lines_outside_fences(content)
652
656
  content = repair_dangling_plain_fences(content)
657
+ content = normalize_fumadocs_directives(content)
658
+ content = fix_frontmatter_description(content)
659
+ content = fix_bare_mermaid_fences(content)
660
+ content = fix_leaf_card_directives(content)
653
661
  content = escape_mdx_angle_hazards(content)
654
662
  content = repair_internal_doc_links(
655
663
  content,
@@ -692,6 +700,10 @@ class BucketGenerationEngine:
692
700
  content = repair_unbalanced_code_fences(content)
693
701
  content = normalize_explanatory_lines_outside_fences(content)
694
702
  content = repair_dangling_plain_fences(content)
703
+ content = normalize_fumadocs_directives(content)
704
+ content = fix_frontmatter_description(content)
705
+ content = fix_bare_mermaid_fences(content)
706
+ content = fix_leaf_card_directives(content)
695
707
  content = escape_mdx_angle_hazards(content)
696
708
  content = repair_internal_doc_links(
697
709
  content,
@@ -207,9 +207,13 @@ def _fix_mermaid_diagram(diagram: str) -> str:
207
207
  dupes.append(nid)
208
208
  seen.add(nid)
209
209
  if dupes:
210
+ # Insert comment AFTER the diagram type declaration line, not before it
211
+ # (Mermaid requires diagram type as the very first line)
212
+ first_nl = result.index("\n") if "\n" in result else len(result)
210
213
  result = (
211
- f"%% Note: possible duplicate node IDs: {', '.join(set(dupes))}\n"
212
- + result
214
+ result[: first_nl + 1]
215
+ + f"%% Note: possible duplicate node IDs: {', '.join(set(dupes))}\n"
216
+ + result[first_nl + 1 :]
213
217
  )
214
218
 
215
219
  return result
@@ -800,6 +804,132 @@ def inject_source_files_disclosure(content: str, evidence_files: list[str]) -> s
800
804
  return patched if count else content
801
805
 
802
806
 
807
+ def normalize_fumadocs_directives(content: str) -> str:
808
+ """Normalize fumadocs callout directive names to the supported set.
809
+
810
+ Valid fumadocs directive types: note, tip, info, warning, danger, caution.
811
+ The LLM frequently uses shorthands like :::warn, :::error, :::success.
812
+ """
813
+ _alias: dict[str, str] = {
814
+ "warn": "warning",
815
+ "caution": "warning",
816
+ "alert": "warning",
817
+ "error": "danger",
818
+ "success": "tip",
819
+ "check": "tip",
820
+ "hint": "tip",
821
+ "important": "note",
822
+ "notice": "note",
823
+ }
824
+
825
+ def replace_directive(m: re.Match) -> str:
826
+ name = m.group(1).strip().lower()
827
+ canonical = _alias.get(name, name)
828
+ return f":::{canonical}"
829
+
830
+ # Only replace opening directives (:::name), not closing :::
831
+ return re.sub(r":::([a-z]+)", replace_directive, content)
832
+
833
+
834
+ def fix_frontmatter_description(content: str) -> str:
835
+ """Strip directive artefacts (trailing ::, :::) from frontmatter description field.
836
+
837
+ The LLM sometimes writes description values that end with :: or ::: which
838
+ the remark-directive plugin then partially parses, corrupting the nav sidebar.
839
+ """
840
+ def clean_description(m: re.Match) -> str:
841
+ prefix = m.group(1) # "description: "
842
+ value = m.group(2) # the value only
843
+ value = re.sub(r'\s*:{2,3}\s*$', '', value.rstrip())
844
+ return f'{prefix}{value}'
845
+
846
+ return re.sub(
847
+ r'^(description:\s*)(["\']?.*?["\']?)\s*$',
848
+ clean_description,
849
+ content,
850
+ flags=re.MULTILINE,
851
+ )
852
+
853
+
854
+ def fix_bare_mermaid_fences(content: str) -> str:
855
+ """Repair mermaid diagrams where the LLM omitted the opening code fence.
856
+
857
+ The LLM sometimes writes just the word 'mermaid' on its own line followed
858
+ by diagram content and a closing ``` — instead of the correct ```mermaid
859
+ opening fence. This produces a bare 'mermaid' paragraph in MDX and leaves
860
+ the diagram body (including {node} labels) unescaped, causing acorn parse
861
+ errors.
862
+
863
+ Pattern matched:
864
+ <text ending in : or .\n>
865
+ mermaid\n
866
+ <diagram type line, e.g. sequenceDiagram>\n
867
+ ...diagram body...
868
+ ```
869
+ """
870
+ return re.sub(
871
+ r'(?m)^mermaid\n(?=(sequenceDiagram|flowchart|graph|classDiagram|stateDiagram|erDiagram|gantt|pie|gitGraph|mindmap|timeline|journey|quadrantChart|xychart|block|packet|kanban|architecture))',
872
+ '```mermaid\n',
873
+ content,
874
+ )
875
+
876
+
877
+ def fix_leaf_card_directives(content: str) -> str:
878
+ """Convert LLM-invented ::card{...}\\nCONTENT\\n:: to :::card{...}\\nCONTENT\\n:::.
879
+
880
+ The fumadocs remark-directive plugin expects 'card' to be a *container*
881
+ directive (:::card ... :::) so it can carry child content. The LLM
882
+ frequently uses the *leaf* directive form (::card) with a standalone ::
883
+ close marker — which remark-directive does not recognise, rendering both
884
+ the content and the :: as raw text.
885
+ """
886
+ def fix_cards_block(m: re.Match) -> str:
887
+ inner = m.group(1)
888
+ # ::card{...}\nCONTENT\n:: → :::card{...}\nCONTENT\n:::
889
+ inner = re.sub(
890
+ r'^::card(\{[^}]*\})\n(.*?)\n^::$',
891
+ r':::card\1\n\2\n:::',
892
+ inner,
893
+ flags=re.MULTILINE | re.DOTALL,
894
+ )
895
+ return f':::cards\n{inner}\n:::'
896
+
897
+ return re.sub(
898
+ r':::cards\n(.*?)\n:::',
899
+ fix_cards_block,
900
+ content,
901
+ flags=re.DOTALL,
902
+ )
903
+
904
+
905
+ def unwrap_markdown_trapped_in_code_fences(content: str) -> str:
906
+ """Detect code fences that contain markdown content and unwrap them.
907
+
908
+ The LLM sometimes forgets to close a code fence, leaving section headers
909
+ (## ...), callout directives (:::), and horizontal rules (---) trapped
910
+ inside a code block. These render as literal text instead of MDX.
911
+ """
912
+ # Pattern: a fenced block that contains markdown indicators
913
+ MD_INDICATORS = re.compile(
914
+ r"^(?:#{1,6}\s|:::|\-\-\-\s*$|^\*\*\*\s*$)",
915
+ re.MULTILINE,
916
+ )
917
+
918
+ def maybe_unwrap(m: re.Match) -> str:
919
+ lang = m.group(1) # may be empty for plain ```
920
+ body = m.group(2)
921
+ # If body contains markdown indicators, unwrap it
922
+ if MD_INDICATORS.search(body):
923
+ return body
924
+ return m.group(0) # leave intact
925
+
926
+ return re.sub(
927
+ r"```([A-Za-z0-9_+-]*)\n([\s\S]*?)\n```",
928
+ maybe_unwrap,
929
+ content,
930
+ )
931
+
932
+
803
933
  def extract_glossary_terms(glossary_content: str) -> list[tuple[str, str]]:
804
934
  """Parse `### TermName` (h3) headings from glossary MDX → [(term, anchor-slug)].
805
935
 
@@ -19,8 +19,10 @@ class LLMClient:
19
19
  # max_tokens=None means don't cap — let the model use its full output capacity
20
20
  self.max_tokens = llm_cfg.get("max_tokens", None)
21
21
  self.temperature = llm_cfg.get("temperature", 0.2)
22
- self.base_url = llm_cfg.get("base_url")
23
- self.api_version = llm_cfg.get("api_version")
22
+ self.base_url = str(llm_cfg.get("base_url") or "") or None
23
+ # YAML parses bare dates like 2024-12-01 as datetime.date coerce to str
24
+ _api_version = llm_cfg.get("api_version")
25
+ self.api_version = str(_api_version).strip() if _api_version is not None else None
24
26
  self.usage: dict[str, int] = {
25
27
  "calls": 0,
26
28
  "prompt_chars": 0,
@@ -65,8 +67,9 @@ class LLMClient:
65
67
 
66
68
  is_azure = provider.lower() == "azure" or model.lower().startswith("azure/")
67
69
  if is_azure:
68
- base_url = (llm_cfg.get("base_url") or "").strip()
69
- api_version = (llm_cfg.get("api_version") or "").strip()
70
+ base_url = str(llm_cfg.get("base_url") or "").strip()
71
+ # YAML parses bare dates like 2025-07-01 as datetime.date coerce to str
72
+ api_version = str(llm_cfg.get("api_version") or "").strip()
70
73
  missing = []
71
74
  if not base_url:
72
75
  missing.append("llm.base_url (your Azure OpenAI endpoint URL)")
@@ -1670,21 +1670,8 @@ def _mermaid_component_tsx() -> str:
1670
1670
  }
1671
1671
  render() {
1672
1672
  if (this.state.error) {
1673
- return (
1674
- <pre
1675
- style={{
1676
- padding: '0.75rem 1rem',
1677
- background: 'var(--color-fd-muted)',
1678
- borderRadius: '6px',
1679
- fontSize: '0.75rem',
1680
- color: 'var(--color-fd-muted-foreground)',
1681
- whiteSpace: 'pre-wrap',
1682
- wordBreak: 'break-word',
1683
- }}
1684
- >
1685
- {'[diagram parse error] ' + this.state.error}
1686
- </pre>
1687
- );
1673
+ // Silently hide diagrams that fail to parse — noise-free fallback
1674
+ return null;
1688
1675
  }
1689
1676
  return this.props.children;
1690
1677
  }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: deepdoc
3
- Version: 2.3.2
3
+ Version: 2.3.4
4
4
  Summary: Auto-generate beautiful docs from any codebase
5
5
  Author: Pranav Kumar
6
6
  License: MIT
@@ -82,7 +82,7 @@ DeepDoc scans your repo, builds a bucket-based documentation plan, generates ric
82
82
  - **Bucket-based documentation architecture** — system, feature, endpoint, integration, and database buckets instead of one-file-per-page noise.
83
83
  - **Multi-step AI planner** — classifies the repo, proposes buckets, then assigns files, symbols, artifacts, and dependencies into a final reader-first plan.
84
84
  - **Giant-file handling** — large files are decomposed into feature-aligned clusters so a single controller can feed multiple doc pages.
85
- - **MDX compile gate** — every page is compile-checked before being written; broken MDX is auto-fixed via LLM retry or degraded to safe Markdown rather than shipped.
85
+ - **MDX-safe generation** — generated pages are repaired and validated in Python before being written; deploy-time quality gates block failed, invalid, or stub pages before the Fumadocs build.
86
86
  - **Evidence-first chatbot answers** — final code proof is hydrated from archived source snippets with exact file paths and line ranges, not just retrieval guesses.
87
87
  - **Incremental updates** — `deepdoc update` regenerates only stale or structurally affected docs against the last synced commit.
88
88
  - **OpenAPI-aware API docs** — auto-detects OpenAPI/Swagger specs and stages interactive `/api/*` pages in the generated site.
@@ -129,7 +129,7 @@ pip install click litellm gitpython rich pyyaml jinja2
129
129
  pip install -e . --no-deps
130
130
  ```
131
131
 
132
- You will also need **Node 18+** on `PATH`. DeepDoc uses Node at generate time to compile-check each MDX page before writing it, and at `serve`/`deploy` time for the Fumadocs site. The small set of MDX validation dependencies installs into `deepdoc/generator/mdx_validator/node_modules/` automatically on first `deepdoc generate`.
132
+ You will also need **Node 18+** on `PATH` when you run `deepdoc serve` or `deepdoc deploy`. DeepDoc generation itself uses Python-side repair and validation; Node is only needed for the generated Fumadocs site.
133
133
 
134
134
  ### Verify installation
135
135
 
@@ -346,7 +346,7 @@ deepdoc generate --exclude "tests/**"
346
346
 
347
347
  1. **Phase 1: Scan** — Walk the repo, parse supported languages, detect endpoints, config/setup artifacts, runtime surfaces, integration signals, and OpenAPI specs.
348
348
  2. **Phase 2: Plan** — Run the multi-step bucket planner. It classifies the repo, proposes bucket candidates, and assigns files/symbols/artifacts to the final doc structure.
349
- 3. **Phase 3: Generate** — Generate bucket pages in batches with parallel workers. High-level buckets are AI-planned; scanned endpoints enrich grouped API-reference pages instead of creating one page per route. Each page passes through an MDX compile-check (with bounded LLM-driven retry on failure) before being written to disk.
349
+ 3. **Phase 3: Generate** — Generate bucket pages in batches with parallel workers. High-level buckets are AI-planned; scanned endpoints enrich grouped API-reference pages instead of creating one page per route. Each page passes through Python-side MDX repair, grounding validation, and bounded quality retries before being written to disk.
350
350
  4. **Phase 4: API Ref** — Stage OpenAPI assets for the generated Fumadocs `/api/*` pages when a spec exists.
351
351
  5. **Phase 5: Build** — Write the generated `site/` Fumadocs scaffold, page tree, search route, and static assets from the generated plan.
352
352
 
@@ -1562,7 +1562,7 @@ deepdoc generate --force # Full regen with new model
1562
1562
  ## Requirements
1563
1563
 
1564
1564
  - Python 3.10+
1565
- - **Node 18+** on `PATH` — used at generate time for MDX compile validation, and at `serve`/`deploy` time for the Fumadocs site
1565
+ - **Node 18+** on `PATH` — used by `deepdoc serve` and `deepdoc deploy` for the generated Fumadocs site
1566
1566
  - Git (for `deepdoc update` and `deepdoc deploy`)
1567
1567
  - An LLM API key (or Ollama running locally)
1568
1568
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "deepdoc"
7
- version = "2.3.2"
7
+ version = "2.3.4"
8
8
  description = "Auto-generate beautiful docs from any codebase"
9
9
  readme = "README.md"
10
10
  authors = [
@@ -57,9 +57,6 @@ Issues = "https://github.com/tss-pranavkumar/deepdoc/issues"
57
57
  where = ["."]
58
58
  include = ["deepdoc*"]
59
59
 
60
- [tool.setuptools.package-data]
61
- "deepdoc.generator.mdx_validator" = ["validate.mjs", "package.json"]
62
-
63
60
  [tool.pytest.ini_options]
64
61
  testpaths = ["tests"]
65
62
  python_files = ["test_*.py"]
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes