codewiki-plus 5.2.2__tar.gz → 5.3.0__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 (164) hide show
  1. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/PKG-INFO +10 -1
  2. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/README.md +9 -0
  3. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/__init__.py +1 -1
  4. codewiki_plus-5.3.0/codewiki/hooks/task_session_start.py +272 -0
  5. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/mcp/_ide_hook.py +16 -1
  6. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/mcp/cache.py +5 -3
  7. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/mcp/prompts.py +191 -57
  8. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/mcp/registry.py +431 -3
  9. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/mcp/tools/capture_conversation.py +170 -20
  10. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/mcp/tools/close_session.py +50 -2
  11. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/mcp/tools/distill_conversation.py +195 -15
  12. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/mcp/tools/doc_writer.py +79 -32
  13. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/mcp/tools/knowledge_loop.py +253 -43
  14. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/mcp/tools/prompt_server.py +2 -2
  15. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/mcp/tools/schema_generator.py +3 -1
  16. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/mcp/tools/source_ingest.py +14 -18
  17. codewiki_plus-5.3.0/codewiki/mcp/tools/task_manager.py +761 -0
  18. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/mcp/tools/wiki_index.py +1 -1
  19. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/mcp/tools/wiki_lint.py +61 -12
  20. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/config.py +10 -4
  21. codewiki_plus-5.3.0/codewiki/src/frontmatter.py +181 -0
  22. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/templates/ontology.yaml +1 -3
  23. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki_plus.egg-info/PKG-INFO +10 -1
  24. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki_plus.egg-info/SOURCES.txt +7 -1
  25. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/pyproject.toml +1 -1
  26. codewiki_plus-5.3.0/tests/test_distill_cleanup.py +216 -0
  27. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/tests/test_ontology_graph.py +13 -1
  28. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/tests/test_strip_system_injection.py +25 -0
  29. codewiki_plus-5.3.0/tests/test_task_manager.py +484 -0
  30. codewiki_plus-5.3.0/tests/test_task_session_start.py +125 -0
  31. codewiki_plus-5.3.0/tests/test_transcript_filters.py +106 -0
  32. codewiki_plus-5.2.2/tests/test_distill_cleanup.py +0 -101
  33. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/__main__.py +0 -0
  34. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/cli/__init__.py +0 -0
  35. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/cli/adapters/__init__.py +0 -0
  36. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/cli/adapters/doc_generator.py +0 -0
  37. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/cli/commands/__init__.py +0 -0
  38. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/cli/commands/config.py +0 -0
  39. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/cli/commands/generate.py +0 -0
  40. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/cli/config_manager.py +0 -0
  41. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/cli/git_manager.py +0 -0
  42. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/cli/html_generator.py +0 -0
  43. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/cli/main.py +0 -0
  44. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/cli/models/__init__.py +0 -0
  45. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/cli/models/config.py +0 -0
  46. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/cli/models/job.py +0 -0
  47. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/cli/utils/__init__.py +0 -0
  48. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/cli/utils/api_errors.py +0 -0
  49. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/cli/utils/errors.py +0 -0
  50. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/cli/utils/fs.py +0 -0
  51. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/cli/utils/instructions.py +0 -0
  52. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/cli/utils/logging.py +0 -0
  53. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/cli/utils/progress.py +0 -0
  54. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/cli/utils/repo_validator.py +0 -0
  55. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/cli/utils/validation.py +0 -0
  56. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/hooks/__init__.py +0 -0
  57. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/hooks/capture_session_end.py +0 -0
  58. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/mcp/__init__.py +0 -0
  59. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/mcp/cbm_client.py +0 -0
  60. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/mcp/resources.py +0 -0
  61. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/mcp/server.py +0 -0
  62. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/mcp/session.py +0 -0
  63. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/mcp/tools/__init__.py +0 -0
  64. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/mcp/tools/agents_md.py +0 -0
  65. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/mcp/tools/analysis.py +0 -0
  66. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/mcp/tools/batch_ingest.py +0 -0
  67. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/mcp/tools/cbm_integration.py +0 -0
  68. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/mcp/tools/code_reader.py +0 -0
  69. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/mcp/tools/component_list.py +0 -0
  70. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/mcp/tools/cross_service.py +0 -0
  71. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/mcp/tools/crosslink.py +0 -0
  72. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/mcp/tools/file_param.py +0 -0
  73. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/mcp/tools/file_viewer.py +0 -0
  74. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/mcp/tools/html_export.py +0 -0
  75. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/mcp/tools/impact.py +0 -0
  76. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/mcp/tools/init_wiki.py +0 -0
  77. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/mcp/tools/issue_tracker.py +0 -0
  78. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/mcp/tools/legacy_tools.py +0 -0
  79. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/mcp/tools/module_tree.py +0 -0
  80. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/mcp/tools/page_router.py +0 -0
  81. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/mcp/tools/reading_guide.py +0 -0
  82. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/mcp/tools/wiki_search.py +0 -0
  83. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/mcp/tools/workspace_analyzer.py +0 -0
  84. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/mcp/tools/workspace_result.py +0 -0
  85. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/mcp/workspace.py +0 -0
  86. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/py.typed +0 -0
  87. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/run_web_app.py +0 -0
  88. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/__init__.py +0 -0
  89. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/be/__init__.py +0 -0
  90. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/be/agent_tools/__init__.py +0 -0
  91. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/be/agent_tools/deps.py +0 -0
  92. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/be/agent_tools/generate_sub_module_documentations.py +0 -0
  93. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/be/agent_tools/read_code_components.py +0 -0
  94. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/be/agent_tools/str_replace_editor.py +0 -0
  95. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/be/backend.py +0 -0
  96. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/be/caw_backend.py +0 -0
  97. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/be/caw_toolkit.py +0 -0
  98. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/be/cluster_modules.py +0 -0
  99. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/be/dependency_analyzer/__init__.py +0 -0
  100. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/be/dependency_analyzer/analysis/__init__.py +0 -0
  101. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/be/dependency_analyzer/analysis/analysis_service.py +0 -0
  102. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/be/dependency_analyzer/analysis/call_graph_analyzer.py +0 -0
  103. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/be/dependency_analyzer/analysis/cloning.py +0 -0
  104. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/be/dependency_analyzer/analysis/cross_service_matcher.py +0 -0
  105. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/be/dependency_analyzer/analysis/infra_scanner.py +0 -0
  106. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/be/dependency_analyzer/analysis/repo_analyzer.py +0 -0
  107. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/be/dependency_analyzer/analysis/service_detector.py +0 -0
  108. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/be/dependency_analyzer/analysis/topology_visualizer.py +0 -0
  109. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/be/dependency_analyzer/analyzers/__init__.py +0 -0
  110. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/be/dependency_analyzer/analyzers/c.py +0 -0
  111. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/be/dependency_analyzer/analyzers/cpp.py +0 -0
  112. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/be/dependency_analyzer/analyzers/csharp.py +0 -0
  113. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/be/dependency_analyzer/analyzers/go.py +0 -0
  114. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/be/dependency_analyzer/analyzers/java.py +0 -0
  115. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/be/dependency_analyzer/analyzers/javascript.py +0 -0
  116. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/be/dependency_analyzer/analyzers/kotlin.py +0 -0
  117. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/be/dependency_analyzer/analyzers/php.py +0 -0
  118. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/be/dependency_analyzer/analyzers/python.py +0 -0
  119. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/be/dependency_analyzer/analyzers/route_extractors/__init__.py +0 -0
  120. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/be/dependency_analyzer/analyzers/route_extractors/go_routes.py +0 -0
  121. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/be/dependency_analyzer/analyzers/route_extractors/java_routes.py +0 -0
  122. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/be/dependency_analyzer/analyzers/route_extractors/js_routes.py +0 -0
  123. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/be/dependency_analyzer/analyzers/route_extractors/mq_patterns.py +0 -0
  124. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/be/dependency_analyzer/analyzers/route_extractors/python_routes.py +0 -0
  125. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/be/dependency_analyzer/analyzers/typescript.py +0 -0
  126. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/be/dependency_analyzer/ast_parser.py +0 -0
  127. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/be/dependency_analyzer/dependency_graphs_builder.py +0 -0
  128. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/be/dependency_analyzer/models/__init__.py +0 -0
  129. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/be/dependency_analyzer/models/analysis.py +0 -0
  130. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/be/dependency_analyzer/models/core.py +0 -0
  131. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/be/dependency_analyzer/models/cross_service.py +0 -0
  132. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/be/dependency_analyzer/topo_sort.py +0 -0
  133. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/be/dependency_analyzer/utils/__init__.py +0 -0
  134. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/be/dependency_analyzer/utils/external_symbols.py +0 -0
  135. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/be/dependency_analyzer/utils/logging_config.py +0 -0
  136. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/be/dependency_analyzer/utils/path_canonicalizer.py +0 -0
  137. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/be/dependency_analyzer/utils/patterns.py +0 -0
  138. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/be/dependency_analyzer/utils/security.py +0 -0
  139. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/be/documentation_generator.py +0 -0
  140. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/be/llm_services.py +0 -0
  141. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/be/main.py +0 -0
  142. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/be/prompt_template.py +0 -0
  143. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/be/pydantic_ai_backend.py +0 -0
  144. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/be/utils.py +0 -0
  145. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/fe/__init__.py +0 -0
  146. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/fe/background_worker.py +0 -0
  147. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/fe/cache_manager.py +0 -0
  148. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/fe/config.py +0 -0
  149. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/fe/github_processor.py +0 -0
  150. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/fe/models.py +0 -0
  151. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/fe/routes.py +0 -0
  152. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/fe/template_utils.py +0 -0
  153. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/fe/templates.py +0 -0
  154. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/fe/visualise_docs.py +0 -0
  155. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/fe/web_app.py +0 -0
  156. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/src/utils.py +0 -0
  157. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/templates/github_pages/viewer_template.html +0 -0
  158. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki/templates/schema.yaml +0 -0
  159. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki_plus.egg-info/dependency_links.txt +0 -0
  160. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki_plus.egg-info/entry_points.txt +0 -0
  161. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki_plus.egg-info/requires.txt +0 -0
  162. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/codewiki_plus.egg-info/top_level.txt +0 -0
  163. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/setup.cfg +0 -0
  164. {codewiki_plus-5.2.2 → codewiki_plus-5.3.0}/tests/test_ide_hook_capture.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codewiki-plus
3
- Version: 5.2.2
3
+ Version: 5.3.0
4
4
  Summary: Transform codebases into comprehensive documentation using AI-powered analysis
5
5
  Author: CodeWiki Contributors
6
6
  License: MIT
@@ -93,6 +93,15 @@ Requires-Dist: ruff>=0.1.0; extra == "dev"
93
93
 
94
94
  ## 中文
95
95
 
96
+ ### 专栏文章
97
+
98
+ 「迎风追日 / WanderingBug」公众号发布的本项目系列技术专栏,欢迎阅读:
99
+
100
+ - [专栏开篇词:从代码文档到 AI 知识引擎](https://mp.weixin.qq.com/s/WpjiDAs62_81mytBWUsDQw)(2026-07-26)
101
+ - [第 2 篇:双层 Prompt 架构同时服务人和模型](https://mp.weixin.qq.com/s/1lNjR_SsrU5Fw2NKnkxnMA)(2026-08-01)
102
+ - [第 3 篇:零依赖检索设计](https://mp.weixin.qq.com/s/T7r-ojyWC-YOpM_U5BNbEw)(2026-08-06)
103
+ - [第 4 篇:知识写入方式全景](https://mp.weixin.qq.com/s/V90mghqB5wttKd25eXA-Pw)(2026-08-09)
104
+
96
105
  ### 这个项目是什么?
97
106
 
98
107
  CodeWiki-Plus 是 [FSoft-AI4Code/CodeWiki](https://github.com/FSoft-AI4Code/CodeWiki) 的增强分支,核心改动是**让 CodeWiki 无需配置任何大模型 API,直接由 AI IDE(CodeBuddy、Cursor、Claude Desktop 等)自身的模型驱动 Wiki 文档生成**,并在此基础上构建了完整的知识管理引擎。
@@ -26,6 +26,15 @@
26
26
 
27
27
  ## 中文
28
28
 
29
+ ### 专栏文章
30
+
31
+ 「迎风追日 / WanderingBug」公众号发布的本项目系列技术专栏,欢迎阅读:
32
+
33
+ - [专栏开篇词:从代码文档到 AI 知识引擎](https://mp.weixin.qq.com/s/WpjiDAs62_81mytBWUsDQw)(2026-07-26)
34
+ - [第 2 篇:双层 Prompt 架构同时服务人和模型](https://mp.weixin.qq.com/s/1lNjR_SsrU5Fw2NKnkxnMA)(2026-08-01)
35
+ - [第 3 篇:零依赖检索设计](https://mp.weixin.qq.com/s/T7r-ojyWC-YOpM_U5BNbEw)(2026-08-06)
36
+ - [第 4 篇:知识写入方式全景](https://mp.weixin.qq.com/s/V90mghqB5wttKd25eXA-Pw)(2026-08-09)
37
+
29
38
  ### 这个项目是什么?
30
39
 
31
40
  CodeWiki-Plus 是 [FSoft-AI4Code/CodeWiki](https://github.com/FSoft-AI4Code/CodeWiki) 的增强分支,核心改动是**让 CodeWiki 无需配置任何大模型 API,直接由 AI IDE(CodeBuddy、Cursor、Claude Desktop 等)自身的模型驱动 Wiki 文档生成**,并在此基础上构建了完整的知识管理引擎。
@@ -5,7 +5,7 @@ This package provides a CLI tool for generating documentation from code reposito
5
5
  and an MCP server for IDE-driven documentation generation.
6
6
  """
7
7
 
8
- __version__ = "5.2.2"
8
+ __version__ = "5.3.0"
9
9
  __author__ = "CodeWiki Contributors"
10
10
  __license__ = "MIT"
11
11
 
@@ -0,0 +1,272 @@
1
+ #!/usr/bin/env python3
2
+ """CodeBuddy SessionStart hook: inject active-task guidance into a new session.
3
+
4
+ The task-memory layer lets long-running work span sessions. This hook makes the
5
+ "pick (or create) a task" prompt *deterministic* at session start: it reads
6
+ ``repowiki/tasks/.index.json`` and emits a ``hookSpecificOutput.additionalContext``
7
+ instructing the agent to ask the user which task to bind (or to create a new
8
+ one) before work begins.
9
+
10
+ This is the **source** copy of the hook, shipped inside the ``codewiki``
11
+ package. When a user enables task management, the ``team-memory-hook`` MCP
12
+ prompt copies this file into the project's ``.codebuddy/hooks/task_session_start.py``
13
+ and registers it for the ``SessionStart`` event. CodeBuddy runs the *copied*
14
+ file, not this one.
15
+
16
+ Why a SessionStart hook (not just AGENTS.md guidance):
17
+ AGENTS.md guidance is a *soft* constraint — an agent may or may not honor
18
+ "at session start, list tasks and ask the user". A SessionStart hook is a
19
+ *hard* trigger: the IDE waits for this script's stdout and injects the
20
+ returned ``additionalContext`` into the agent's context, so the task prompt is
21
+ guaranteed to surface every time.
22
+
23
+ Unlike the SessionEnd capture hook (which fires-and-forgets via a detached
24
+ subprocess), this hook MUST return its ``systemMessage`` synchronously — the IDE
25
+ is waiting on stdout. It is therefore deliberately lightweight: it reads at
26
+ most two small JSON files (task index + raw capture index) and prints one JSON
27
+ line, and never imports the ``codewiki`` package (no import-path dance, fast
28
+ startup, no risk of a slow import blocking the IDE).
29
+
30
+ CodeBuddy invokes it with the event as JSON on stdin, e.g.:
31
+
32
+ {
33
+ "session_id": "abc123",
34
+ "transcript_path": "/path/to/transcript.txt",
35
+ "cwd": "/project/path",
36
+ "hook_event_name": "SessionStart",
37
+ "source": "startup"
38
+ }
39
+
40
+ Stdout is emitted in the CodeBuddy-expected ``{continue, systemMessage}`` shape.
41
+ """
42
+
43
+ from __future__ import annotations
44
+
45
+ import json
46
+ import os
47
+ import sys
48
+ from pathlib import Path
49
+
50
+ REPO = Path(__file__).resolve().parents[2] # <repo>/.codebuddy/hooks/ -> <repo>
51
+
52
+
53
+ def _read_event() -> dict:
54
+ """Read the hook event JSON from stdin ({} when absent/unparseable)."""
55
+ if sys.stdin.isatty():
56
+ return {}
57
+ try:
58
+ # Read raw bytes and decode leniently: PowerShell pipes may prepend one
59
+ # or more UTF-8 BOMs, which would break json.loads.
60
+ raw = sys.stdin.buffer.read().decode("utf-8-sig", errors="replace")
61
+ raw = raw.lstrip("\ufeff").strip()
62
+ except Exception:
63
+ return {}
64
+ if not raw:
65
+ return {}
66
+ try:
67
+ data = json.loads(raw)
68
+ except json.JSONDecodeError:
69
+ return {}
70
+ return data if isinstance(data, dict) else {}
71
+
72
+
73
+ def _resolve_repo_path(event: dict) -> str:
74
+ """Resolve the repo root, preferring authoritative sources.
75
+
76
+ Priority: CODEBUDDY_PROJECT_DIR env var (CodeBuddy-specific) >
77
+ CLAUDE_PROJECT_DIR (compat) > event's cwd > this script's repo location.
78
+ Candidates that don't exist on disk are skipped.
79
+ """
80
+ candidates = [
81
+ os.environ.get("CODEBUDDY_PROJECT_DIR"),
82
+ os.environ.get("CLAUDE_PROJECT_DIR"),
83
+ event.get("cwd"),
84
+ str(REPO),
85
+ ]
86
+ for c in candidates:
87
+ if c and os.path.isdir(c):
88
+ return c
89
+ return str(REPO)
90
+
91
+
92
+ def _load_active_tasks(repo_path: str) -> list:
93
+ """Read repowiki/tasks/.index.json and return active (non-completed) tasks.
94
+
95
+ Returns [] when the index is absent/corrupt (the task layer has never been
96
+ initialized) — the caller then prompts the user to create a task instead.
97
+ """
98
+ idx = Path(repo_path) / "repowiki" / "tasks" / ".index.json"
99
+ if not idx.is_file():
100
+ return []
101
+ try:
102
+ data = json.loads(idx.read_text(encoding="utf-8-sig", errors="replace"))
103
+ except (OSError, json.JSONDecodeError):
104
+ return []
105
+ tasks = data.get("tasks", []) if isinstance(data, dict) else []
106
+ return [t for t in tasks if isinstance(t, dict) and t.get("status") == "active"]
107
+
108
+
109
+ def _count_pending_raws(repo_path: str) -> dict:
110
+ """Count un-distilled raw captures grouped by task_id.
111
+
112
+ Reads ``repowiki/raw/.index.json`` (maintained by capture_conversation,
113
+ shape ``{"files": [{"relpath", "status", "task_id", ...}]}``): entries
114
+ whose status is not "distilled" form the distillation backlog. If the index
115
+ is missing, falls back to a lightweight frontmatter peek of conv-*.md.
116
+ Any failure returns {} so the hook degrades silently to its previous
117
+ behaviour (never breaks task binding). Stays stdlib-only and O(entries).
118
+ """
119
+ counts: dict = {}
120
+ try:
121
+ raw_dir = Path(repo_path) / "repowiki" / "raw"
122
+ idx_path = raw_dir / ".index.json"
123
+ if idx_path.is_file():
124
+ data = json.loads(idx_path.read_text(encoding="utf-8-sig", errors="replace"))
125
+ files = data.get("files", []) if isinstance(data, dict) else []
126
+ for e in files:
127
+ if not isinstance(e, dict):
128
+ continue
129
+ if str(e.get("status") or "pending") == "distilled":
130
+ continue
131
+ rel = str(e.get("relpath") or "")
132
+ if not rel or not (raw_dir / rel).is_file():
133
+ continue # stale index entry — the file is gone
134
+ task_id = str(e.get("task_id") or "")
135
+ counts[task_id] = counts.get(task_id, 0) + 1
136
+ return counts
137
+ # Fallback: no index — peek frontmatter of each raw capture.
138
+ for p in sorted(raw_dir.glob("conv-*.md")):
139
+ try:
140
+ text = p.read_text(encoding="utf-8-sig", errors="replace")
141
+ except OSError:
142
+ continue
143
+ status, task_id = "pending", ""
144
+ for line in text.splitlines():
145
+ if line.startswith("status:"):
146
+ status = line[len("status:"):].strip().strip("\"'")
147
+ elif line.startswith("task_id:"):
148
+ task_id = line[len("task_id:"):].strip().strip("\"'")
149
+ if status != "distilled":
150
+ counts[task_id] = counts.get(task_id, 0) + 1
151
+ except Exception:
152
+ return {}
153
+ return counts
154
+
155
+
156
+ def _build_message(event: dict, repo_path: str) -> str:
157
+ """Build the guidance injected into the fresh session.
158
+
159
+ IMPORTANT: the user expects an interactive chooser, NOT a text paragraph.
160
+ The message below must instruct the agent to surface the choice through the
161
+ ``ask_followup_question`` tool (the IDE's structured-question UI), so the
162
+ user can click an option or type a task name, exactly like a native dialog.
163
+ """
164
+ session_id = str(event.get("session_id") or "").strip()
165
+ active = _load_active_tasks(repo_path)
166
+
167
+ lines = ["[task-memory] 本会话开始前,请先处理「任务关联」(跨会话任务记忆)。"]
168
+ lines.append("")
169
+ lines.append(
170
+ "【硬性执行顺序】无论用户第一条消息问什么(哪怕是关于代码、文件、bug 的具体问题),"
171
+ "本会话的第一个动作都必须是下面这个任务关联弹框流程;弹框、绑定、拉取上下文"
172
+ "(以及有积压时的补蒸馏)全部完成后,才允许开始读文件/搜索代码/回答用户提问。"
173
+ "严禁先探索代码或直接回答,事后再补弹任务关联框。"
174
+ )
175
+ lines.append("")
176
+ lines.append(
177
+ "【必须弹框】请立即调用 ask_followup_question 工具弹出结构化选择框"
178
+ "(这是 IDE 的原生弹框 UI,用户可以直接点击选项),不要用纯文本输出一段话让用户自行回复。"
179
+ "弹框标题用「任务关联」,提供以下选项:"
180
+ )
181
+ if active:
182
+ lines.append("- 关联已有任务:把下面每个进行中任务的标题作为弹框选项,用户选中后调用 "
183
+ f"set_session_task(source_session_id={session_id or '<当前会话id>'}, task_id=<选中任务>) 建立绑定")
184
+ lines.append(" 当前进行中的任务:")
185
+ for t in active:
186
+ lines.append(f" - {t.get('title') or t.get('id')}(task_id={t.get('id')})")
187
+ else:
188
+ lines.append("- 新建任务:选择后会再弹一个输入框让用户输入任务名(可补一句描述),调用 "
189
+ "create_task(title=<任务名>, description=<可选>) 创建后即关联该新任务")
190
+ lines.append("- 跳过:本次会话不做任务关联,直接开始干活")
191
+ lines.append("")
192
+ lines.append(
193
+ "【新建任务两步弹框】当用户选择「新建任务」后,必须再次调用 ask_followup_question "
194
+ "弹出第二个输入框:标题用「新建任务」,问题写「请输入新任务名称」,提供 2 个占位示例选项"
195
+ "(如「临时任务」「在输入框直接输入名称后回车」)。该弹框自带输入框,用户可自由输入任务名后回车;"
196
+ "以用户输入的文字为准,立即调用 create_task(title=<任务名>, description=<可选>) 创建并关联该新任务。"
197
+ "若用户只点击了占位选项,则用文字追问确认真实任务名。"
198
+ )
199
+ lines.append("")
200
+ lines.append(
201
+ "关联完成后调用 get_task_context(task_id=<选中任务>) 拉取该任务上下文继续工作。"
202
+ "返回中的 pending_raw_count 是本任务尚未蒸馏的历史对话数:若大于 0,必须先按下方"
203
+ "「补蒸馏」流程处理完积压,再开始回答用户提问。"
204
+ "若用户明确表示本次会话与任何任务无关,可跳过本提示。"
205
+ )
206
+
207
+ # Catch-up distillation backlog: deterministic trigger so agents that never
208
+ # "think to" distill still clear the backlog at session start.
209
+ pending_counts = _count_pending_raws(repo_path)
210
+ if pending_counts:
211
+ total = sum(pending_counts.values())
212
+ lines.append("")
213
+ lines.append(f"【补蒸馏】检测到 {total} 条未蒸馏的历史对话积压:")
214
+ for tid, n in sorted(pending_counts.items()):
215
+ label = f"任务 {tid}" if tid else "未关联任务"
216
+ lines.append(f" - {label}: {n} 条")
217
+ lines.append(
218
+ "绑定任务之后、开始回答用户提问之前,对已绑定任务执行补蒸馏:"
219
+ )
220
+ lines.append(
221
+ " 1. distill_conversation(mode=\"prepare\", task_id=<绑定的任务id>) "
222
+ "获取该任务的积压对话清单"
223
+ )
224
+ lines.append(
225
+ " 2. 按清单逐条 read_file 阅读 raw 文件,提取 notes(通用经验)与 memories(任务进度)"
226
+ )
227
+ lines.append(
228
+ " 3. distill_conversation(mode=\"submit\", distilled=<提取结果>) 提交;"
229
+ "产出为草稿笔记与待确认记忆"
230
+ )
231
+ lines.append(
232
+ " 4. 重新 get_task_context 拉取最新上下文(新产出的待确认记忆/草稿笔记会一并注入)"
233
+ )
234
+ lines.append(
235
+ " 5. 向用户展示待确认项,经 confirm_task_memories / confirm_note 确认后才正式落盘"
236
+ )
237
+ lines.append(
238
+ "若用户明确表示紧急,可先回答提问,但必须在会话结束前完成补蒸馏。"
239
+ "注意:pending 记忆与 draft 笔记在确认前只能作为只读参考,不得当作已定论的结论引用。"
240
+ )
241
+
242
+ return "\n".join(lines)
243
+
244
+
245
+ def main() -> int:
246
+ event = _read_event()
247
+ repo_path = _resolve_repo_path(event)
248
+ message = _build_message(event, repo_path)
249
+
250
+ # Ensure CJK task titles survive the Windows console encoding (cp936) when
251
+ # the IDE reads our stdout.
252
+ try:
253
+ sys.stdout.reconfigure(encoding="utf-8")
254
+ except (AttributeError, ValueError, OSError):
255
+ pass
256
+
257
+ # SessionStart injects extra context to the *agent* via
258
+ # hookSpecificOutput.additionalContext. (systemMessage only surfaces to the
259
+ # user and never reaches the agent — see the CodeBuddy hooks reference.)
260
+ output = {
261
+ "continue": True,
262
+ "hookSpecificOutput": {
263
+ "hookEventName": "SessionStart",
264
+ "additionalContext": message,
265
+ },
266
+ }
267
+ print(json.dumps(output, ensure_ascii=False))
268
+ return 0
269
+
270
+
271
+ if __name__ == "__main__":
272
+ sys.exit(main())
@@ -363,6 +363,8 @@ def main(argv: Optional[list] = None) -> int:
363
363
  "(used to resolve repowiki/raw/).")
364
364
  parser.add_argument("--session-id", help="Active session id (optional).")
365
365
  parser.add_argument("--link-to", help="Wiki object id this conversation relates to.")
366
+ parser.add_argument("--task-id", help="Task id this conversation is bound to "
367
+ "(stamped into raw frontmatter so distillation routes memories back).")
366
368
  parser.add_argument("--keep-raw", action="store_true",
367
369
  help="Hint distill_conversation to retain the raw file.")
368
370
  args = parser.parse_args(argv)
@@ -405,9 +407,14 @@ def main(argv: Optional[list] = None) -> int:
405
407
  "usable transcript_path; capturing the event envelope only "
406
408
  "(the IDE did not provide an inline transcript).")
407
409
  # Fall through: capture the event envelope as a minimal record.
410
+ # NOTE: role must be "user" (not "system") -- capture_conversation
411
+ # drops every role outside {user, assistant} in _extract_transcript,
412
+ # so a system-role envelope would be silently discarded (see
413
+ # test_envelope_does_not_supersede_full_transcript). The envelope
414
+ # body carries no system-injection tags, so stripping is a no-op.
408
415
  is_envelope = True
409
416
  conversation = [{
410
- "role": "system",
417
+ "role": "user",
411
418
  "content": (f"[team-memory] {hook_event} hook fired but the IDE "
412
419
  "provided no inline transcript and no readable "
413
420
  "transcript_path. Raw event envelope preserved for "
@@ -438,6 +445,14 @@ def main(argv: Optional[list] = None) -> int:
438
445
  "" if is_envelope
439
446
  else (_pick("session_id", args.session_id) or "")
440
447
  ),
448
+ # Task binding, stamped into raw frontmatter so distill_conversation can
449
+ # route distilled memories back to the task. Like source_session_id, the
450
+ # envelope (no real transcript) must NOT carry task_id — it is not a real
451
+ # conversation and would otherwise pollute per-task memory routing.
452
+ "task_id": (
453
+ "" if is_envelope
454
+ else (_pick("task_id", args.task_id) or "")
455
+ ),
441
456
  }
442
457
  if not arguments["repo_path"]:
443
458
  print("ide-hook: repo_path is required to resolve repowiki/raw/.", file=sys.stderr)
@@ -266,14 +266,16 @@ def _build_indexable_text(content: str, page_type: Optional[str] = None) -> str:
266
266
  parts.append(aliases_text)
267
267
  parts.append(aliases_text)
268
268
 
269
- # LLM Wiki: severity boost (for pitfall/known_issue notes)
270
- severity = fm.get("severity", "")
269
+ # LLM Wiki: severity boost (for pitfall/known_issue notes) — may be folded
270
+ # under metadata: (OKF §4/§5)
271
+ _meta = fm.get("metadata") or {}
272
+ severity = fm.get("severity", "") or _meta.get("severity", "")
271
273
  if isinstance(severity, str) and severity:
272
274
  parts.append(severity)
273
275
  parts.append(severity)
274
276
 
275
277
  # LLM Wiki: related_modules 2x boost (module names for cross-reference discovery)
276
- related = fm.get("related_modules", [])
278
+ related = fm.get("related_modules", []) or _meta.get("related_modules", [])
277
279
  if isinstance(related, list):
278
280
  related_text = " ".join(str(r) for r in related)
279
281
  elif isinstance(related, str):