3gpp-crawler 2026.11.10__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 (275) hide show
  1. 3gpp_crawler-2026.11.10/.agents/FILES.md +43 -0
  2. 3gpp_crawler-2026.11.10/.agents/HISTORY.md +80 -0
  3. 3gpp_crawler-2026.11.10/.agents/MAINTENANCE.md +37 -0
  4. 3gpp_crawler-2026.11.10/.agents/ONBOARDING.md +70 -0
  5. 3gpp_crawler-2026.11.10/.agents/POLICIES.md +228 -0
  6. 3gpp_crawler-2026.11.10/.agents/TOOLS.md +52 -0
  7. 3gpp_crawler-2026.11.10/.agents/history/2025-10-20_SUMMARY_01_targeted_fetch_documentation.md +5 -0
  8. 3gpp_crawler-2026.11.10/.agents/history/2025-10-20_SUMMARY_02_git_repository_setup.md +168 -0
  9. 3gpp_crawler-2026.11.10/.agents/history/2025-10-20_SUMMARY_03_env_example_setup.md +215 -0
  10. 3gpp_crawler-2026.11.10/.agents/history/2025-10-20_SUMMARY_04_SUBGROUP_FILTERING.md +234 -0
  11. 3gpp_crawler-2026.11.10/.agents/history/2025-10-21_SUMMARY_01_TDOC_CRAWLER_REFACTORING.md +451 -0
  12. 3gpp_crawler-2026.11.10/.agents/history/2025-10-21_SUMMARY_02_DATABASE_SCHEMA_UPDATES.md +229 -0
  13. 3gpp_crawler-2026.11.10/.agents/history/2025-10-21_SUMMARY_03_REMOVE_REDUNDANT_FILES.md +80 -0
  14. 3gpp_crawler-2026.11.10/.agents/history/2025-10-21_SUMMARY_04_ADD_SUBGROUP_FILTERING_TO_CRAWL.md +175 -0
  15. 3gpp_crawler-2026.11.10/.agents/history/2025-10-21_SUMMARY_05_crawler_http_migration_and_refactoring.md +725 -0
  16. 3gpp_crawler-2026.11.10/.agents/history/2025-10-22_SUMMARY_01_CLI_REFACTORING_AND_COMMAND_RENAMING.md +337 -0
  17. 3gpp_crawler-2026.11.10/.agents/history/2025-10-22_SUMMARY_02_DATABASE_REFACTORING.md +148 -0
  18. 3gpp_crawler-2026.11.10/.agents/history/2025-10-22_SUMMARY_03_TEST_FIXTURES_AND_CRITICAL_PATTERN_FIX.md +461 -0
  19. 3gpp_crawler-2026.11.10/.agents/history/2025-10-22_SUMMARY_05_PORTAL_METADATA_PARSING.md +354 -0
  20. 3gpp_crawler-2026.11.10/.agents/history/2025-10-22_SUMMARY_06_STATUS_FIELD_UPDATE.md +281 -0
  21. 3gpp_crawler-2026.11.10/.agents/history/2025-10-23_SUMMARY_01_AGENTS_MD_REVIEW_AND_IMPROVEMENTS.md +295 -0
  22. 3gpp_crawler-2026.11.10/.agents/history/2025-10-23_SUMMARY_01_PROGRESS_BAR_AND_CLEAR_FLAGS.md +406 -0
  23. 3gpp_crawler-2026.11.10/.agents/history/2025-10-23_SUMMARY_02_FIX_SUBGROUP_INFERENCE.md +305 -0
  24. 3gpp_crawler-2026.11.10/.agents/history/2025-10-24_SUMMARY_01_CONSTANTS_EXTRACTION_AND_PARALLEL_WORKER_REFACTORING.md +381 -0
  25. 3gpp_crawler-2026.11.10/.agents/history/2025-10-24_SUMMARY_02_TDOC_COUNT_DATABASE_OPTIMIZATION.md +644 -0
  26. 3gpp_crawler-2026.11.10/.agents/history/2025-10-30_SUMMARY_01_HTTP_CACHING_FEATURE.md +331 -0
  27. 3gpp_crawler-2026.11.10/.agents/history/2025-11-01_SUMMARY_01_CLI_REFACTORING_BEADS_DEPENDENCIES.md +88 -0
  28. 3gpp_crawler-2026.11.10/.agents/history/2025-11-01_SUMMARY_02_CLI_REFACTORING_PLAN.md +178 -0
  29. 3gpp_crawler-2026.11.10/.agents/history/2025-11-11_SUMMARY_01_CRAWL_TDOC_LIST.md +108 -0
  30. 3gpp_crawler-2026.11.10/.agents/history/2026-02-02_SUMMARY_01_CLI_COMMAND_DOCUMENTATION.md +102 -0
  31. 3gpp_crawler-2026.11.10/.agents/history/2026-02-03_SUMMARY_02_TDOC_URL_EXTRACTION.md +191 -0
  32. 3gpp_crawler-2026.11.10/.agents/history/2026-02-03_SUMMARY_03_LAZY_CREDENTIAL_RESOLUTION.md +373 -0
  33. 3gpp_crawler-2026.11.10/.agents/history/2026-02-07_SUMMARY_01_SPEC_DOWNLOAD_AUTO_CRAWL_AND_BUG_FIXES.md +39 -0
  34. 3gpp_crawler-2026.11.10/.agents/history/2026-02-09_SUMMARY_01_ALIGN_CLI_OPTIONS_ACROSS_COMMANDS.md +41 -0
  35. 3gpp_crawler-2026.11.10/.agents/history/2026-02-26_SUMMARY_AI_FEATURE_VALIDATION.md +55 -0
  36. 3gpp_crawler-2026.11.10/.agents/history/2026-03-06_SUMMARY_01_AI_EMBEDDINGS_ACCELERATE_BACKEND.md +27 -0
  37. 3gpp_crawler-2026.11.10/.agents/history/2026-03-23_SUMMARY_LightRAG_migration_plan.md +854 -0
  38. 3gpp_crawler-2026.11.10/.agents/history/2026-03-24_SUMMARY_convert_summarize_commands_implementation.md +493 -0
  39. 3gpp_crawler-2026.11.10/.agents/history/2026-03-25_SUMMARY_enhanced_rag_pipeline_tables_figures_equations.md +109 -0
  40. 3gpp_crawler-2026.11.10/.agents/history/2026-03-25_SUMMARY_list_providers_cli_command.md +47 -0
  41. 3gpp_crawler-2026.11.10/.agents/history/2026-03-27_SUMMARY_cli_rag_subcommand_removal.md +65 -0
  42. 3gpp_crawler-2026.11.10/.agents/history/2026-04-22_ANALYSIS_phase1-critical-fixes-complete.md +250 -0
  43. 3gpp_crawler-2026.11.10/.agents/history/2026-04-22_ANALYSIS_source-code-analysis.md +289 -0
  44. 3gpp_crawler-2026.11.10/.agents/history/2026-04-22_PLAN_config-consolidation.md +939 -0
  45. 3gpp_crawler-2026.11.10/.agents/history/2026-04-22_PLAN_test-migration.md +135 -0
  46. 3gpp_crawler-2026.11.10/.agents/history/2026-05-02_SUMMARY_01_SPEC_RELEASE_RESOLUTION.md +48 -0
  47. 3gpp_crawler-2026.11.10/.agents/history/2026-08-18_PLAN_scope_refocus.md +143 -0
  48. 3gpp_crawler-2026.11.10/.agents/history/2026-08-18_SUMMARY_scope_refocus.md +30 -0
  49. 3gpp_crawler-2026.11.10/.agents/history/2026-11-10_PLAN_pdf-conversion-removal.md +99 -0
  50. 3gpp_crawler-2026.11.10/.beads/.gitignore +81 -0
  51. 3gpp_crawler-2026.11.10/.beads/README.md +85 -0
  52. 3gpp_crawler-2026.11.10/.beads/config.yaml +77 -0
  53. 3gpp_crawler-2026.11.10/.beads/hooks/post-checkout +24 -0
  54. 3gpp_crawler-2026.11.10/.beads/hooks/post-merge +24 -0
  55. 3gpp_crawler-2026.11.10/.beads/hooks/pre-commit +24 -0
  56. 3gpp_crawler-2026.11.10/.beads/hooks/pre-push +24 -0
  57. 3gpp_crawler-2026.11.10/.beads/hooks/prepare-commit-msg +24 -0
  58. 3gpp_crawler-2026.11.10/.beads/interactions.jsonl +0 -0
  59. 3gpp_crawler-2026.11.10/.beads/issues.jsonl +0 -0
  60. 3gpp_crawler-2026.11.10/.beads/metadata.json +8 -0
  61. 3gpp_crawler-2026.11.10/.config/mise/conf.d/docs.toml +18 -0
  62. 3gpp_crawler-2026.11.10/.config/mise/conf.d/format.toml +11 -0
  63. 3gpp_crawler-2026.11.10/.config/mise/conf.d/lint.toml +11 -0
  64. 3gpp_crawler-2026.11.10/.config/mise/conf.d/mcp.toml +8 -0
  65. 3gpp_crawler-2026.11.10/.config/mise/conf.d/quality.toml +24 -0
  66. 3gpp_crawler-2026.11.10/.config/mise/conf.d/skills.toml +5 -0
  67. 3gpp_crawler-2026.11.10/.config/mise/conf.d/tasks.toml +14 -0
  68. 3gpp_crawler-2026.11.10/.config/mise/config.toml +38 -0
  69. 3gpp_crawler-2026.11.10/.config/mise/data/dev-features.csv +8 -0
  70. 3gpp_crawler-2026.11.10/.config/mise/data/skills.csv +12 -0
  71. 3gpp_crawler-2026.11.10/.config/mise/scripts/install_dev_features.py +230 -0
  72. 3gpp_crawler-2026.11.10/.config/pyreorder.toml +49 -0
  73. 3gpp_crawler-2026.11.10/.config/rumdl.toml +72 -0
  74. 3gpp_crawler-2026.11.10/.env.example +111 -0
  75. 3gpp_crawler-2026.11.10/.gitattributes +35 -0
  76. 3gpp_crawler-2026.11.10/.githooks/pre-commit +33 -0
  77. 3gpp_crawler-2026.11.10/.github/workflows/docs.yml +39 -0
  78. 3gpp_crawler-2026.11.10/.github/workflows/release.yml +104 -0
  79. 3gpp_crawler-2026.11.10/.gitignore +303 -0
  80. 3gpp_crawler-2026.11.10/.pre-commit-config.yaml +31 -0
  81. 3gpp_crawler-2026.11.10/AGENTS.md +158 -0
  82. 3gpp_crawler-2026.11.10/LICENSE +21 -0
  83. 3gpp_crawler-2026.11.10/PKG-INFO +224 -0
  84. 3gpp_crawler-2026.11.10/README.md +187 -0
  85. 3gpp_crawler-2026.11.10/codecov.yaml +9 -0
  86. 3gpp_crawler-2026.11.10/demo.bat +13 -0
  87. 3gpp_crawler-2026.11.10/docs/code_of_conduct.md +43 -0
  88. 3gpp_crawler-2026.11.10/docs/config.md +265 -0
  89. 3gpp_crawler-2026.11.10/docs/contributing.md +46 -0
  90. 3gpp_crawler-2026.11.10/docs/crawl.md +80 -0
  91. 3gpp_crawler-2026.11.10/docs/credits.md +9 -0
  92. 3gpp_crawler-2026.11.10/docs/development.md +234 -0
  93. 3gpp_crawler-2026.11.10/docs/images/logo.jpg +0 -0
  94. 3gpp_crawler-2026.11.10/docs/index.md +51 -0
  95. 3gpp_crawler-2026.11.10/docs/license.md +11 -0
  96. 3gpp_crawler-2026.11.10/docs/mcp.md +79 -0
  97. 3gpp_crawler-2026.11.10/docs/misc.md +56 -0
  98. 3gpp_crawler-2026.11.10/docs/query.md +87 -0
  99. 3gpp_crawler-2026.11.10/docs/reference/api.md +23 -0
  100. 3gpp_crawler-2026.11.10/docs/tags.md +96 -0
  101. 3gpp_crawler-2026.11.10/docs/utils.md +83 -0
  102. 3gpp_crawler-2026.11.10/docs/whatthespec.md +22 -0
  103. 3gpp_crawler-2026.11.10/mkdocs.yml +131 -0
  104. 3gpp_crawler-2026.11.10/packages/pool_executors/LICENSE +21 -0
  105. 3gpp_crawler-2026.11.10/packages/pool_executors/README.md +284 -0
  106. 3gpp_crawler-2026.11.10/packages/pool_executors/pool_executors/__init__.py +10 -0
  107. 3gpp_crawler-2026.11.10/packages/pool_executors/pool_executors/factory.py +68 -0
  108. 3gpp_crawler-2026.11.10/packages/pool_executors/pool_executors/py.typed +0 -0
  109. 3gpp_crawler-2026.11.10/packages/pool_executors/pool_executors/runner.py +101 -0
  110. 3gpp_crawler-2026.11.10/packages/pool_executors/pool_executors/serial.py +133 -0
  111. 3gpp_crawler-2026.11.10/packages/pool_executors/pool_executors/types.py +48 -0
  112. 3gpp_crawler-2026.11.10/packages/pool_executors/pyproject.toml +22 -0
  113. 3gpp_crawler-2026.11.10/pyproject.toml +113 -0
  114. 3gpp_crawler-2026.11.10/ruff.toml +80 -0
  115. 3gpp_crawler-2026.11.10/scripts/demo.py +69 -0
  116. 3gpp_crawler-2026.11.10/scripts/gen_credits.py +29 -0
  117. 3gpp_crawler-2026.11.10/scripts/release_notes.py +116 -0
  118. 3gpp_crawler-2026.11.10/skills/3gpp-crawler/SKILL.md +106 -0
  119. 3gpp_crawler-2026.11.10/skills/3gpp-crawler/references/cli-quick-ref.md +140 -0
  120. 3gpp_crawler-2026.11.10/src/tdoc_crawler/AGENTS.md +126 -0
  121. 3gpp_crawler-2026.11.10/src/tdoc_crawler/__init__.py +5 -0
  122. 3gpp_crawler-2026.11.10/src/tdoc_crawler/__main__.py +6 -0
  123. 3gpp_crawler-2026.11.10/src/tdoc_crawler/cli/AGENTS.md +82 -0
  124. 3gpp_crawler-2026.11.10/src/tdoc_crawler/cli/__init__.py +11 -0
  125. 3gpp_crawler-2026.11.10/src/tdoc_crawler/cli/_shared.py +67 -0
  126. 3gpp_crawler-2026.11.10/src/tdoc_crawler/cli/args.py +237 -0
  127. 3gpp_crawler-2026.11.10/src/tdoc_crawler/cli/checkout.py +180 -0
  128. 3gpp_crawler-2026.11.10/src/tdoc_crawler/cli/config.py +52 -0
  129. 3gpp_crawler-2026.11.10/src/tdoc_crawler/cli/config_app.py +321 -0
  130. 3gpp_crawler-2026.11.10/src/tdoc_crawler/cli/constants.py +14 -0
  131. 3gpp_crawler-2026.11.10/src/tdoc_crawler/cli/crawl/__init__.py +14 -0
  132. 3gpp_crawler-2026.11.10/src/tdoc_crawler/cli/crawl/_helpers.py +57 -0
  133. 3gpp_crawler-2026.11.10/src/tdoc_crawler/cli/crawl/meetings.py +145 -0
  134. 3gpp_crawler-2026.11.10/src/tdoc_crawler/cli/crawl/specs.py +76 -0
  135. 3gpp_crawler-2026.11.10/src/tdoc_crawler/cli/crawl/tdocs.py +196 -0
  136. 3gpp_crawler-2026.11.10/src/tdoc_crawler/cli/database_app.py +226 -0
  137. 3gpp_crawler-2026.11.10/src/tdoc_crawler/cli/formatting.py +182 -0
  138. 3gpp_crawler-2026.11.10/src/tdoc_crawler/cli/mcp_app.py +26 -0
  139. 3gpp_crawler-2026.11.10/src/tdoc_crawler/cli/mgmt_app.py +79 -0
  140. 3gpp_crawler-2026.11.10/src/tdoc_crawler/cli/printing.py +349 -0
  141. 3gpp_crawler-2026.11.10/src/tdoc_crawler/cli/query/__init__.py +14 -0
  142. 3gpp_crawler-2026.11.10/src/tdoc_crawler/cli/query/_helpers.py +24 -0
  143. 3gpp_crawler-2026.11.10/src/tdoc_crawler/cli/query/meetings.py +77 -0
  144. 3gpp_crawler-2026.11.10/src/tdoc_crawler/cli/query/specs.py +89 -0
  145. 3gpp_crawler-2026.11.10/src/tdoc_crawler/cli/query/tdocs.py +175 -0
  146. 3gpp_crawler-2026.11.10/src/tdoc_crawler/cli/spec_app.py +64 -0
  147. 3gpp_crawler-2026.11.10/src/tdoc_crawler/cli/specs.py +128 -0
  148. 3gpp_crawler-2026.11.10/src/tdoc_crawler/cli/tag_app.py +145 -0
  149. 3gpp_crawler-2026.11.10/src/tdoc_crawler/cli/tdoc_app.py +221 -0
  150. 3gpp_crawler-2026.11.10/src/tdoc_crawler/cli/utils.py +41 -0
  151. 3gpp_crawler-2026.11.10/src/tdoc_crawler/clients/__init__.py +14 -0
  152. 3gpp_crawler-2026.11.10/src/tdoc_crawler/clients/portal.py +325 -0
  153. 3gpp_crawler-2026.11.10/src/tdoc_crawler/config/AGENTS.md +71 -0
  154. 3gpp_crawler-2026.11.10/src/tdoc_crawler/config/__init__.py +49 -0
  155. 3gpp_crawler-2026.11.10/src/tdoc_crawler/config/cache_manager.py +118 -0
  156. 3gpp_crawler-2026.11.10/src/tdoc_crawler/config/env_vars.py +83 -0
  157. 3gpp_crawler-2026.11.10/src/tdoc_crawler/config/export.py +210 -0
  158. 3gpp_crawler-2026.11.10/src/tdoc_crawler/config/settings.py +309 -0
  159. 3gpp_crawler-2026.11.10/src/tdoc_crawler/config/sources.py +258 -0
  160. 3gpp_crawler-2026.11.10/src/tdoc_crawler/constants/__init__.py +7 -0
  161. 3gpp_crawler-2026.11.10/src/tdoc_crawler/constants/patterns.py +27 -0
  162. 3gpp_crawler-2026.11.10/src/tdoc_crawler/constants/urls.py +46 -0
  163. 3gpp_crawler-2026.11.10/src/tdoc_crawler/credentials.py +95 -0
  164. 3gpp_crawler-2026.11.10/src/tdoc_crawler/database/AGENTS.md +104 -0
  165. 3gpp_crawler-2026.11.10/src/tdoc_crawler/database/__init__.py +17 -0
  166. 3gpp_crawler-2026.11.10/src/tdoc_crawler/database/archives.py +77 -0
  167. 3gpp_crawler-2026.11.10/src/tdoc_crawler/database/base.py +216 -0
  168. 3gpp_crawler-2026.11.10/src/tdoc_crawler/database/errors.py +15 -0
  169. 3gpp_crawler-2026.11.10/src/tdoc_crawler/database/meetings.py +370 -0
  170. 3gpp_crawler-2026.11.10/src/tdoc_crawler/database/oxyde_models.py +240 -0
  171. 3gpp_crawler-2026.11.10/src/tdoc_crawler/database/protocols.py +67 -0
  172. 3gpp_crawler-2026.11.10/src/tdoc_crawler/database/specs.py +566 -0
  173. 3gpp_crawler-2026.11.10/src/tdoc_crawler/database/tag_transfer.py +136 -0
  174. 3gpp_crawler-2026.11.10/src/tdoc_crawler/database/tags.py +114 -0
  175. 3gpp_crawler-2026.11.10/src/tdoc_crawler/database/tdocs.py +412 -0
  176. 3gpp_crawler-2026.11.10/src/tdoc_crawler/http_client/__init__.py +23 -0
  177. 3gpp_crawler-2026.11.10/src/tdoc_crawler/http_client/protocols.py +33 -0
  178. 3gpp_crawler-2026.11.10/src/tdoc_crawler/http_client/session.py +386 -0
  179. 3gpp_crawler-2026.11.10/src/tdoc_crawler/logging/__init__.py +101 -0
  180. 3gpp_crawler-2026.11.10/src/tdoc_crawler/mcp_server.py +405 -0
  181. 3gpp_crawler-2026.11.10/src/tdoc_crawler/meetings/__init__.py +5 -0
  182. 3gpp_crawler-2026.11.10/src/tdoc_crawler/meetings/models.py +92 -0
  183. 3gpp_crawler-2026.11.10/src/tdoc_crawler/meetings/operations/__init__.py +10 -0
  184. 3gpp_crawler-2026.11.10/src/tdoc_crawler/meetings/operations/crawl.py +170 -0
  185. 3gpp_crawler-2026.11.10/src/tdoc_crawler/meetings/sources/__init__.py +5 -0
  186. 3gpp_crawler-2026.11.10/src/tdoc_crawler/meetings/sources/portal.py +181 -0
  187. 3gpp_crawler-2026.11.10/src/tdoc_crawler/meetings/utils.py +24 -0
  188. 3gpp_crawler-2026.11.10/src/tdoc_crawler/models/__init__.py +41 -0
  189. 3gpp_crawler-2026.11.10/src/tdoc_crawler/models/archives.py +31 -0
  190. 3gpp_crawler-2026.11.10/src/tdoc_crawler/models/base.py +71 -0
  191. 3gpp_crawler-2026.11.10/src/tdoc_crawler/models/crawl_log.py +35 -0
  192. 3gpp_crawler-2026.11.10/src/tdoc_crawler/models/subworking_groups.py +127 -0
  193. 3gpp_crawler-2026.11.10/src/tdoc_crawler/models/working_groups.py +49 -0
  194. 3gpp_crawler-2026.11.10/src/tdoc_crawler/parsers/__init__.py +11 -0
  195. 3gpp_crawler-2026.11.10/src/tdoc_crawler/parsers/portal.py +202 -0
  196. 3gpp_crawler-2026.11.10/src/tdoc_crawler/parsers/protocols.py +43 -0
  197. 3gpp_crawler-2026.11.10/src/tdoc_crawler/specs/__init__.py +7 -0
  198. 3gpp_crawler-2026.11.10/src/tdoc_crawler/specs/downloads.py +310 -0
  199. 3gpp_crawler-2026.11.10/src/tdoc_crawler/specs/models.py +45 -0
  200. 3gpp_crawler-2026.11.10/src/tdoc_crawler/specs/operations/__init__.py +15 -0
  201. 3gpp_crawler-2026.11.10/src/tdoc_crawler/specs/operations/checkout.py +96 -0
  202. 3gpp_crawler-2026.11.10/src/tdoc_crawler/specs/sources/__init__.py +6 -0
  203. 3gpp_crawler-2026.11.10/src/tdoc_crawler/specs/sources/base.py +41 -0
  204. 3gpp_crawler-2026.11.10/src/tdoc_crawler/specs/sources/threegpp.py +68 -0
  205. 3gpp_crawler-2026.11.10/src/tdoc_crawler/specs/sources/whatthespec.py +38 -0
  206. 3gpp_crawler-2026.11.10/src/tdoc_crawler/tdocs/__init__.py +11 -0
  207. 3gpp_crawler-2026.11.10/src/tdoc_crawler/tdocs/models.py +198 -0
  208. 3gpp_crawler-2026.11.10/src/tdoc_crawler/tdocs/operations/__init__.py +45 -0
  209. 3gpp_crawler-2026.11.10/src/tdoc_crawler/tdocs/operations/checkout.py +587 -0
  210. 3gpp_crawler-2026.11.10/src/tdoc_crawler/tdocs/operations/crawl.py +425 -0
  211. 3gpp_crawler-2026.11.10/src/tdoc_crawler/tdocs/operations/fetch.py +532 -0
  212. 3gpp_crawler-2026.11.10/src/tdoc_crawler/tdocs/sources/__init__.py +22 -0
  213. 3gpp_crawler-2026.11.10/src/tdoc_crawler/tdocs/sources/base.py +101 -0
  214. 3gpp_crawler-2026.11.10/src/tdoc_crawler/tdocs/sources/doclist.py +482 -0
  215. 3gpp_crawler-2026.11.10/src/tdoc_crawler/tdocs/sources/portal.py +139 -0
  216. 3gpp_crawler-2026.11.10/src/tdoc_crawler/tdocs/sources/whatthespec.py +196 -0
  217. 3gpp_crawler-2026.11.10/src/tdoc_crawler/tdocs/utils.py +9 -0
  218. 3gpp_crawler-2026.11.10/src/tdoc_crawler/utils/__init__.py +0 -0
  219. 3gpp_crawler-2026.11.10/src/tdoc_crawler/utils/archive.py +26 -0
  220. 3gpp_crawler-2026.11.10/src/tdoc_crawler/utils/async_helpers.py +37 -0
  221. 3gpp_crawler-2026.11.10/src/tdoc_crawler/utils/clutter-ignore +20 -0
  222. 3gpp_crawler-2026.11.10/src/tdoc_crawler/utils/clutter.py +68 -0
  223. 3gpp_crawler-2026.11.10/src/tdoc_crawler/utils/date_parser.py +45 -0
  224. 3gpp_crawler-2026.11.10/src/tdoc_crawler/utils/misc.py +14 -0
  225. 3gpp_crawler-2026.11.10/src/tdoc_crawler/utils/normalization.py +485 -0
  226. 3gpp_crawler-2026.11.10/src/tdoc_crawler/utils/parse.py +140 -0
  227. 3gpp_crawler-2026.11.10/src/tdoc_crawler/utils/security.py +92 -0
  228. 3gpp_crawler-2026.11.10/src/tdoc_crawler/utils/version_types.py +65 -0
  229. 3gpp_crawler-2026.11.10/src/tdoc_crawler/workers/__init__.py +9 -0
  230. 3gpp_crawler-2026.11.10/src/tdoc_crawler/workers/tdoc_worker.py +62 -0
  231. 3gpp_crawler-2026.11.10/tests/.gitignore +24 -0
  232. 3gpp_crawler-2026.11.10/tests/AGENTS.md +49 -0
  233. 3gpp_crawler-2026.11.10/tests/__init__.py +1 -0
  234. 3gpp_crawler-2026.11.10/tests/config/test_export.py +93 -0
  235. 3gpp_crawler-2026.11.10/tests/config/test_sources.py +295 -0
  236. 3gpp_crawler-2026.11.10/tests/conftest.py +260 -0
  237. 3gpp_crawler-2026.11.10/tests/data/README.md +5 -0
  238. 3gpp_crawler-2026.11.10/tests/data/TDoc_List_Meeting_SA4#134.xlsx +0 -0
  239. 3gpp_crawler-2026.11.10/tests/pool_executor/test_executor_adapter.py +142 -0
  240. 3gpp_crawler-2026.11.10/tests/pool_executor/test_serial_executor.py +448 -0
  241. 3gpp_crawler-2026.11.10/tests/test_archives.py +84 -0
  242. 3gpp_crawler-2026.11.10/tests/test_cache_manager.py +96 -0
  243. 3gpp_crawler-2026.11.10/tests/test_checkout.py +847 -0
  244. 3gpp_crawler-2026.11.10/tests/test_cli.py +1142 -0
  245. 3gpp_crawler-2026.11.10/tests/test_cli_dotenv.py +100 -0
  246. 3gpp_crawler-2026.11.10/tests/test_config_export.py +80 -0
  247. 3gpp_crawler-2026.11.10/tests/test_credentials.py +153 -0
  248. 3gpp_crawler-2026.11.10/tests/test_database.py +328 -0
  249. 3gpp_crawler-2026.11.10/tests/test_executor_selection.py +52 -0
  250. 3gpp_crawler-2026.11.10/tests/test_formatting.py +70 -0
  251. 3gpp_crawler-2026.11.10/tests/test_glob_safe_cli.py +101 -0
  252. 3gpp_crawler-2026.11.10/tests/test_graph_errors.py +51 -0
  253. 3gpp_crawler-2026.11.10/tests/test_http_client.py +394 -0
  254. 3gpp_crawler-2026.11.10/tests/test_mcp.py +50 -0
  255. 3gpp_crawler-2026.11.10/tests/test_meeting_document_list.py +215 -0
  256. 3gpp_crawler-2026.11.10/tests/test_models.py +393 -0
  257. 3gpp_crawler-2026.11.10/tests/test_new_cli_flags.py +331 -0
  258. 3gpp_crawler-2026.11.10/tests/test_normalization.py +292 -0
  259. 3gpp_crawler-2026.11.10/tests/test_portal_auth.py +109 -0
  260. 3gpp_crawler-2026.11.10/tests/test_portal_client.py +312 -0
  261. 3gpp_crawler-2026.11.10/tests/test_specs_cli.py +39 -0
  262. 3gpp_crawler-2026.11.10/tests/test_specs_database.py +161 -0
  263. 3gpp_crawler-2026.11.10/tests/test_specs_downloads.py +53 -0
  264. 3gpp_crawler-2026.11.10/tests/test_specs_normalization.py +331 -0
  265. 3gpp_crawler-2026.11.10/tests/test_tag_query_filter.py +93 -0
  266. 3gpp_crawler-2026.11.10/tests/test_tag_transfer.py +118 -0
  267. 3gpp_crawler-2026.11.10/tests/test_tags.py +89 -0
  268. 3gpp_crawler-2026.11.10/tests/test_targeted_fetch.py +589 -0
  269. 3gpp_crawler-2026.11.10/tests/test_tdoc_pattern_filter.py +26 -0
  270. 3gpp_crawler-2026.11.10/tests/test_tdoc_sort_keys.py +125 -0
  271. 3gpp_crawler-2026.11.10/tests/test_template_validation.py +77 -0
  272. 3gpp_crawler-2026.11.10/tests/test_whatthespec.py +455 -0
  273. 3gpp_crawler-2026.11.10/tox.ini +19 -0
  274. 3gpp_crawler-2026.11.10/ty.toml +19 -0
  275. 3gpp_crawler-2026.11.10/zensical.toml +170 -0
@@ -0,0 +1,43 @@
1
+ # AGENTS.md — FILES
2
+
3
+ Single source of truth for paths, config keys, and naming conventions.
4
+ Kept compact — agents hallucinate less when they know where definitions live.
5
+
6
+ ## Pattern
7
+
8
+ - One file owns each class of definition (paths, config defaults, enums).
9
+ - Import from that file. Never hard-code values in other modules.
10
+ - Variables that address files get `_file` suffix; directories get `_dir`.
11
+
12
+ ## Project-specific sources of truth
13
+
14
+ | What | Where | Key names |
15
+ |------|-------|-----------|
16
+ | Runtime paths | `src/tdoc_crawler/config/cache_manager.py` | `CacheManager`, `resolve_cache_manager()`, `DEFAULT_*` constants |
17
+ | Config settings | `src/tdoc_crawler/config/settings.py` | `ThreeGPPConfig` (alias `TDocCrawlerConfig`), `PathConfig`, `HttpConfig`, `CredentialsConfig`, `CrawlConfig` |
18
+ | Env vars | `.env.example` | `TDC_*`, `HTTP_CACHE_*`, `TDC_EOL_*`, `TDC_CRAWL_*` |
19
+ | Domain constants | `src/tdoc_crawler/constants/` | `patterns.py` (regexes), `urls.py` |
20
+ | Domain enums | `src/tdoc_crawler/models/base.py` | StrEnum: `TDocStatus`, `SourceKind`, `TagKind`, `OutputFormat`, `SortOrder` |
21
+ | DB models | `src/tdoc_crawler/database/oxyde_models.py` | Oxyde models, one per table |
22
+ | HTTP session | `src/tdoc_crawler/http_client/session.py` | `create_cached_session()`, `download_to_file()`, `PoolConfig` |
23
+ | Docs config | `zensical.toml` (default builder; `mise run docs`) + `mkdocs.yml` (GitHub Pages workflow; `mise run docs:mkdocs`) | nav, theme, plugins - update BOTH navs when adding/removing pages |
24
+ | Mise tasks/tools | `.config/mise/config.toml` + `conf.d/*.toml` | task definitions split by category; dev-feature tools/MCP/skills driven by `data/dev-features.csv` + `data/skills.csv` via `scripts/install_dev_features.py` (`mise run add-mcp-servers`, `mise run add-skills`) |
25
+ | CI / release / docs / mirror | `.github/workflows/release.yml` (CalVer tag, GitHub release with LLM-drafted notes from `scripts/release_notes.py` falling back to `--generate-notes`, mirror push to forge), `.github/workflows/pypi.yml` (PyPI trusted publishing on published GitHub releases only, tag must match package version), `.github/workflows/docs.yml` (GitHub Pages) | Default branch `main` on GitHub; forge is a mirror only |
26
+ | CLI commands | `src/tdoc_crawler/cli/` | Typer apps: `tdoc_app`, `spec_app`, `mgmt_app`, `config_app`, `tag_app`, `mcp_app` |
27
+ | Credentials | `src/tdoc_crawler/credentials.py` | `set_credentials()`, EOL auth |
28
+
29
+ ## Naming conventions
30
+
31
+ - **Archived plans** (`.agents/history/`, version-controlled):
32
+ `YYYY-MM-DD_<TYPE>_<summary>.md` — date = **completion date** of the
33
+ work, `TYPE` ∈ `SUMMARY` | `ANALYSIS` | `PLAN`. Example:
34
+ `2026-08-10_SUMMARY_feature1.md`.
35
+ - **Active plans** (`.agents/plans/`, gitignored): no date prefix, but the
36
+ plan **must embed a date** (creation timestamp) in its content — e.g.
37
+ `Created: YYYY-MM-DD` line or a front-matter `date:` field. Filename
38
+ stays descriptive (`01-sub-feature.md`), order = implementation order.
39
+
40
+ ## Subdirectory
41
+
42
+ If this file grows past its size budget, split detail into
43
+ `.agents/files/<name>.md` — every file there MUST be listed above.
@@ -0,0 +1,80 @@
1
+ # AGENTS.md — HISTORY
2
+
3
+ Recorded decisions with git references. Read when relevant to current task.
4
+ Acts as simple long-term memory for the project.
5
+
6
+ Detailed change history: `.agents/history/` (committed summaries, chronological).
7
+
8
+ ## Format
9
+
10
+ | Date | Decision | Rationale | Git ref |
11
+ |------|----------|-----------|---------|
12
+ | YYYY-MM-DD | [description] | [why] | [commit hash/tag] |
13
+
14
+ ## Record
15
+
16
+ - High-level architectural decisions and breaking changes.
17
+ - Dependency, tooling, and platform choices — including the alternative that lost.
18
+ - False turns and rejected approaches, with the reason.
19
+ - Completion of an implementation plan (link to its archive below).
20
+
21
+ ## Do not record
22
+
23
+ - Routine commits, refactor logs, session activity, release notes.
24
+ - Anything obvious from git, the code, or current AGENTS.md/state files.
25
+
26
+ ## Guidance
27
+
28
+ - Record decisions that would be costly to rediscover.
29
+ - Note false turns and why they were rejected.
30
+ - Link to relevant commits.
31
+ - Keep entries brief — enough to reconstruct reasoning.
32
+ - If this file grows large, move older entries to `.agents/history/` and keep
33
+ a pointer here.
34
+
35
+ ## Archive a plan
36
+
37
+ Archive when a plan's work lands — not at a later maintenance pass:
38
+
39
+ 1. Consolidate `.agents/plans/<feature>/` into a single file
40
+ `.agents/history/<YYYY-MM-DD>_<TYPE>_<summary>.md` (completion date;
41
+ naming schema in `.agents/FILES.md`).
42
+ 2. Delete the plan directory.
43
+ 3. Add an entry to `.agents/HISTORY.md` referencing the archive and its
44
+ commit.
45
+
46
+ ## Entries
47
+
48
+ | Date | Decision | Rationale | Git ref |
49
+ |------|----------|-----------|---------|
50
+ | 2026-08-14 | Adopted agents-scaffold DOX hierarchy: lean root AGENTS.md (rules + index only), non-essential rules moved to `.agents/` (POLICIES, ONBOARDING, FILES), ⛔ No Patching guard | Always-injected AGENTS.md was bloated; every redundant byte dilutes every LLM call | (uncommitted) |
51
+ | 2026-08-14 | `.agents/` DOX `.md` files now git-tracked (un-ignored); `/.agents/plans/` explicitly ignored | DOX files are durable records, plans are mutable working artifacts | (uncommitted) |
52
+ | 2026-08-14 | Migrated tooling onto copier-uv-plus template: mise conf.d task layout, ty.toml + ty dev dep, zensical docs (replaces mkdocs), codespell/rumdl, template meta files, .copier-answers.yml adopted | Align tool set with template for future `copier update`; uv.lock stays untracked until stable v1 | (uncommitted) |
53
+ | 2026-08-14 | zensical build panics on this machine (watcher.rs:299 "invariant", upstream #743 closed as not reproducible) — docs build deferred until fixed upstream or workaround found | Minimal repro at `%LOCALAPPDATA%\Temp\ztest` | (uncommitted) |
54
+ | 2026-08-14 | forge.3gpp.org is GitLab EE mounted at `/rep` (relative URL root). glab works via: `GITLAB_TOKEN=` + `GITLAB_HOST=forge.3gpp.org` + `subfolder: rep` in glab config + running the glab binary directly (`mise which glab`) | mise re-injects GITLAB_TOKEN (gitlab.com token) into the env, which overrides the forge token and breaks API calls | (uncommitted) |
55
+ | 2026-08-14 | Token split: `GITLAB_TOKEN` = gitlab.com (mise gitlab backend, glab-cli downloads); `MISE_GITLAB_ENTERPRISE_TOKEN` = forge.3gpp.org | Per mise docs token priority | (uncommitted) |
56
+ | 2026-08-14 | Added `.gitlab-ci.yml`: on every push to default branch, compute next CalVer (vYYYY.MM.N from existing tags), create annotated tag + GitLab release with commit-log notes | Automatic versioning without CI runners was not possible (0 project runners); shared runners enabled on forge. `resource_group` serializes racing pushes; `RELEASE_TOKEN` variable overrides CI_JOB_TOKEN if 403 | (uncommitted) |
57
+ | 2026-08-14 | **Replaced GitLab CI with pre-push hook** — forge has NO active shared runners (job stuck: "no active runners"). Other forge projects use group/project runners (e.g. `ivas-linux`); user-namespace project has none. `.gitlab-ci.yml` removed; `.githooks/pre-push` (installed via `git config core.hooksPath .githooks`) schedules `scripts/auto-release.sh` detached after the push lands; curl + `MISE_GITLAB_ENTERPRISE_TOKEN`, no glab/jq deps. First release v2026.08.1 created & verified | CI needs a registered runner to work; hook uses the already-verified forge API path | (uncommitted) |
58
+ | 2026-08-14 | Moved detailed change history from `docs/history/` to `.agents/history/` (40 files, git-mv preserves history). Archive naming schema: `YYYY-MM-DD_<TYPE>_<summary>.md` (date = completion); active plans embed a date instead of a prefix. Schema lives in `.agents/FILES.md` | History is durable decision records — belongs under `.agents/`, not user docs; POLICIES previously suggested `.agents/history/<feature>/` subdirs, reconciled to the flat date-prefixed layout already in use | (uncommitted) |
59
+ | 2026-08-14 | Enabled template dev-features (`include_mcp_tasks: True`): adopted `.config/mise/conf.d/{mcp,skills}.toml` + `data/{dev-features,skills}.csv` + `scripts/install_dev_features.py`; deleted hand-rolled `conf.d/ai.toml`; CSVs curated to project stack (grepai, teddi, cytoscnpy, beads; python-ultimate/ty/pydantic/etc. skills) | The CSV manifests are the template's designed extension point — the hand-written ai.toml was exactly what the skill forbids; project-specific rows (teddi, 3GPP skills) now live in the CSVs | (uncommitted) |
60
+ | 2026-08-14 | Fixed `crawllogentry.created_at` NOT NULL violation on crawl start: oxyde 0.7.x `create()` uses `exclude_unset=True`, dropping `default_factory` fields from INSERTs; such fields have no SQL DEFAULT. `log_crawl_start` now sets `created_at` explicitly (other insert sites already set theirs; `_prepare_tdoc` normalizes TDocMetadata) | oxyde upgraded from 0.4.x floor to 0.7.1 by `uv sync`; documented in `database/AGENTS.md` Key Rules | (uncommitted) |
61
+ | 2026-08-15 | auto-release.sh hardening: sed instead of python (bare `python` not on PATH in hook env), `LC_ALL=C.UTF-8`, description via `--data-urlencode description@file` with `cygpath -w` | git-bash → native curl.exe argv conversion mangles non-ASCII to `?`; `"\\n"` in double quotes stays literal so GitLab rendered it as text; MSYS `/tmp` paths unreadable for curl | (uncommitted) |
62
+ | 2026-08-18 | Scope refocus: dropped workspace subsystem + all AI/extraction (docling, pymupdf, profiles, metrics). Added tags (polymorphic `TagEntry` model), `--pdf` flag on checkout, MCP server (fastmcp stdio, 14 grouped tools). Tags replace workspace membership as the lightweight grouping mechanism | Workspaces stalled; AI pipeline not needed here; MCP enables agent integration | 46c5b63 → f375f61 |
63
+ | 2026-08-18 | Docs restructured for mkdocs (default builder; `mkdocs build --strict` clean): stale workspace/history/skills pages deleted, tags+mcp pages added, flags verified against real CLI, zensical.toml nav kept in sync (zensical still broken on Windows) | docs/ was a mix of historical paraphrase, broken nav (workspace.md), and stale flags; history belongs to `.agents/history/` | (this commit) |
64
+ | 2026-08-19 | Added `reservation_date` + `uploaded_at` columns to TDocMetadata (issue #5), sourced from doc-list Excel `Reservation date` / `Uploaded` columns; added `--sort-by` (meeting_date/reservation_date/uploaded_at/tdoc_id) to query_tdocs CLI/MCP | TDoc numbers reflect reservation-slot order, not real upload order; callers need true submission time to sort. None values normalized to crawl time in `_prepare_tdoc` to avoid oxyde bulk "Missing column" | (uncommitted) |
65
+ | 2026-08-20 | Fixed doubled `/Docs/Docs/` path in TDoc URLs (issue #6): `_construct_tdoc_url` now only appends `/Docs` when `files_url` (portal MtgDocURL) doesn't already end with it. Previously every crawled URL was a dead 403 link | `MtgDocURL` points at the meeting Docs dir; appending `/Docs/` again produced `.../Docs/Docs/<tdoc>.zip`. Checkout's `_resolve_corrected_url` stays as a safety net for legacy bad rows | (uncommitted) |
66
+ | 2026-08-20 | Removed dead `.gitlab-ci.yml`. forge has no active runners on this project namespace (only group-level ones from `ivas-linux`), so every push triggered a pending→failed pipeline with empty trace and an email notification. Releases are already produced by `.githooks/pre-push` → `scripts/auto-release.sh` (CalVer tag + GitLab release + wheel upload), which is the entire purpose the CI served | Hook covers what CI would have done; CI cost was just the email noise | (uncommitted) |
67
+ | 2026-08-24 | Rewrote `_run_migrations` in `database/base.py` to be model-driven: diff `extract_current_schema()` (the same source of truth that creates tables) against `PRAGMA table_info` introspected via `oxyde.execute_raw()`, and emit `ALTER TABLE ADD COLUMN` for every missing column. Replaces the hand-maintained hard-coded migration list that silently failed (the old code passed msgpack-encoded bytes from `raw` IR to a `for row in result` loop, throwing inside the catch-all `except` block). Fixes ``no such column: tdocmetadata.reservation_date`` on every query for any DB created before #5 landed | Migration code should be data-driven, not hand-maintained. Using `execute_raw` keeps the introspection on oxyde’s own connection (no stdlib sqlite3 side-channel). Type is inferred from `python_type`: `int` → INTEGER, everything else → TEXT (sqlite is dynamically typed anyway) | (this commit) |
68
+ | 2026-08-24 | **Audit pass on `database/`** per user feedback: dropped `_ensure_tables_exist` / `_run_migrations` / `_PYTHON_TO_SQLITE_TYPE` / `_build_column_defs` / `_build_column_sql` (60+ lines of hand-rolled DDL) in favour of Oxyde's own `oxyde.db.schema.create_tables()` (dialect-aware, uses `migration_compute_diff` + `migration_to_sql` under the hood). Replaced the `table_to_model: dict[str, type[Model]]` with a typed `_clear_tables(models: Iterable[type])` that derives table names from `Model.get_table_name()`. **Killed migrations entirely** — on schema mismatch the DB raises `DatabaseError("schema-mismatch")` pointing at regeneration; no ALTER TABLE guessing. Live DB lost 31617 rows from the audit (test invocation of `clear_tdocs`) — user must re-crawl | Oxyde already knows how to create tables correctly; building our own DDL on top is over-engineering. The hardcoded `"tdocs"` / `"specs"` / `...` strings in `_clear_tables` were also drift magnets — one rename in `oxyde_models.py` and the clear silently no-op'd | (this commit) |
69
+ | 2026-11-10 | Updated agents-scaffold to the 2026-10-17 template: new `.agents/TOOLS.md` state file (tool inventory moved from AGENTS.md + ONBOARDING), Hierarchy/Child Doc Shape sections, state-file subdirectory concept, plan-completion archive trigger | Framework update (INSTALL.md); project plan/archive naming kept deliberately (`.agents/plans/<feature>/` + `YYYY-MM-DD_<TYPE>_<summary>.md`) — upstream dated-dir naming NOT adopted | (this commit) |
70
+ | 2026-11-10 | **Rebuilt beads tracking**: bd 0.49.6 server-mode Dolt store was broken (database `tdc` missing; stale `dolt sql-server` running against an empty `.beads/dolt/`). Re-initialized with bd 1.3.4 **embedded** Dolt (`.beads/embeddeddolt/`), re-imported all 45 issues from git-tracked `.beads/issues.jsonl`, removed legacy 0.49 state (`.beads/dolt/`, `dolt-server-*`, legacy config). Issues now sync to a NEW **private** repo `forge.3gpp.org/rep/reimes/3gpp-crawler-beads` (`refs/dolt/data`; `sync.remote` + `export.auto` in `.beads/config.yaml`; push auth `DOLT_REMOTE_USER=oauth2 DOLT_REMOTE_PASSWORD=$GITLAB_TOKEN`). Main code repo is publicly readable — never push beads data there | Upstream guidance: embedded is default for single-writer, Dolt remotes replaced the removed `sync-branch` workflow, "use private repos" (SECURITY.md); issues.jsonl is export-only, not a backup | (this commit) |
71
+ | 2026-11-10 | **Moved primary hosting to GitHub** `github.com/jr2804/3gpp-crawler` (public). `forge.3gpp.org/rep/reimes/3gpp-crawler` is now a mirror: `.github/workflows/release.yml` pushes `main` + tags via project token `github-mirror-maintainer` (id 179, write_repository, Maintainer because forge `main` is protected for Maintainers-only push; expires 2027-11-10) stored as GitHub secret `FORGE_MIRROR_TOKEN`. Releases: CalVer tag + GitHub release created by workflow on each `main` push version change. PyPI publish gated by repo variable `PYPI_PUBLISH=true` (trusted publishing, env `pypi`). Docs: `.github/workflows/docs.yml` deploys MkDocs to GitHub Pages (`https://jr2804.github.io/3gpp-crawler/`). Removed `.githooks/pre-push`, `scripts/auto-release.sh`, `scripts/ci-release.sh` (forge-API release path). Local `branch.main.remote` = `github` (CalVer pre-commit reads tags there). Beads sync stays on forge private repo; beads data must never go to the public GitHub/forge code repos | Forge has no runners, so GitLab CI/Pages cannot run; GitHub Actions + Pages + PyPI trusted publishing need no self-hosted runner; forge kept for mirroring per user decision | (this commit) |
72
+ | 2026-11-10 | **Removed PDF conversion**: deleted `src/tdoc_crawler/extraction/` (conversion + unused fetch helpers), `packages/convert-lo/`, `tests/convert_lo/`, `docs/convert-lo-usage.md`; `--pdf` removed from `tdoc checkout`, `spec checkout` and MCP `checkout_tdocs`/`checkout_specs` (breaking CLI/MCP change); pdf-remote-converter dependency and git source dropped; `OFFICE_FORMATS` moved to new `constants/` module (kept for planned archive classification) | Office->PDF existed only to feed knowledge/AI tooling, out of scope since the 2026-08-18 refocus; newer tools (parsecraft, docling, docling-rs) handle doc/docx themselves; pdf-remote-converter came from a non-PyPI git source, so PyPI installs failed on import | (this commit) |
73
+ | 2026-11-10 | **Dependency bump + hishel 2 port**: hishel>=2.0.0 (hishel 2 dropped SyncSqliteStorage/SyncBaseStorage and the hishel.requests adapter for niquests). _NiquetsCacheAdapter now subclasses niquests HTTPAdapter and runs hishel's sync RFC 9111 state machine (hishel._sync_rfc.handle_request_with_rfc, private, no public sync equivalent) with SqliteStorage; cache key sha256(url). Cache file renamed http-cache.sqlite3 -> http-cache-v2.sqlite3 (hishel 2 refuses 1.x schema). Runtime lower bounds raised to the lock's resolved versions. LogLevel StrEnum (DEBUG..CRITICAL, uppercase values) now types all --verbosity options; numeric/lowercase levels are rejected by Typer | Blocker: hishel 2.0.0 was already installed by the lock, so the old SyncSqliteStorage import broke every CLI start; porting keeps RFC caching behaviour of hishel 1 default policy | (this commit) |
74
+ | 2026-11-10 | **Cherry-pick migration copier-uv-plus 2026.8.5 → HEAD** (manual path-by-path, no `copier update`): installer upgraded (`enabled` CSV column, inline `tool_value` tables → `mise use --tool-option`, best-effort removal of disabled rows); CSVs reschema'd — repowise row deleted, beads/beads-mcp rows tool-stripped (tools live in `config.toml`), dormant rows added (dolt, desktop-commander, sequential-thinking, rust — all `enabled=0`); lint consolidated to upstream `ruff check src/ tests/ --fix --unsafe-fixes` (lint-fix/-unsafe tasks dropped); format paths `src/ tests/ scripts/`; **docs switched to zensical default via `--link-mode=copy` — this FIXES the 2026-08-14 Windows watcher panic** (build passes, 3.3s); mkdocs kept as `docs:mkdocs` for the Pages workflow; template `.config/pyreorder.toml` adopted (`runtime_setup` bucket); dead `[tool.undersort]` removed from pyproject; gen_credits no-`__file__` fallback; `.gitignore` +site//native binaries/agent dirs | Align with template HEAD for future template syncs; deviations kept deliberately: Typer CLI (real code, not the template's Cyclopts demo), static version in `__init__.py` (CalVer hook sed target), our `test_template_validation.py`, `uv.lock` untracked, `.copier-answers.yml` stays at 2026.8.5 (honest - cherry-pick, not render) | (uncommitted) |
75
+ | 2026-11-10 | **Archive member tracking**: new `ArchiveMember` table (`database/archives.py`, `utils/archive.py`) records zip member listings of TDoc and spec archives, written on checkout and on explicit `tdoc files` / `spec files` (MCP `list_tdoc_files` / `list_spec_files`) requests; `--keep-zip` / MCP `keep_zip` keeps the TDoc zip (default: deleted, as before); `SpecificationDownload` (never written) removed | Users asked to browse attachments of tdocs/specs without a full download; storing listings avoids re-reading zips and keeps crawl free of eager archive reads | (uncommitted) |
76
+ | 2026-11-10 | **Tag export/import + clear-db keeps tags + --output everywhere**: new `tag export` / `tag import` (natural keys kind/item_id/tag; JSON/YAML; `-f` file) in `database/tag_transfer.py`; `--clear-db` saves tags to `tags-backup.json` next to the DB and restores them after recreation (raw sqlite read works on stale schemas); `--output` on tag add/remove/list, `tdoc stats`, `tdoc checkout` (per-TDoc rows), `spec checkout`, `tdoc files`, `spec files` | Tags are user data that `--clear-db` used to destroy; natural keys survive PK changes and rebuilds; machine output must be pipeable (no progress bar on stdout) | (uncommitted) |
77
+ | 2026-11-10 | **CLI structure cleanup — `tag` and `mcp` unmounted from the tdoc app**: `tdoc-crawler tag` / `tdoc-crawler mcp` (and `3gpp-crawler tdoc tag` / `tdoc-crawler tdoc mcp`) removed; both live once at the `3gpp-crawler` umbrella level. `tdoc-crawler` is now pure tdoc domain (crawl, crawl-meetings, query, query-meetings, open, files, stats, checkout, version + ct/cm/qt/qm aliases) | `mcp` was reachable under three names while missing under `spec` (infrastructure, not a tdoc concern); `tag` is cross-domain (TagKind includes SPEC) so nesting it under `tdoc` was conceptually wrong | (uncommitted) |
78
+ | 2026-11-10 | **`database` command group (alias `db`) replaces scattered clear flags**: new `cli/database_app.py` mounted on `3gpp-crawler` with `clear-tdocs`, `clear-specs`, `clear-meetings` (new `MeetingDatabase.clear_meetings()`), `clear-all` (former `--clear-db`: delete DB file, save/restore tags via `tags-backup.json`, clear TDoc checkouts, `--yes` for scripts), `export-tags`, `import-tags` (moved from `tag export`/`tag import`); `--clear-db`/`--clear-tdocs`/`--clear-specs` removed from all `crawl`/`query` commands, `handle_clear_options()` deleted from `cli/_shared.py`; `schema-mismatch` message now names `3gpp-crawler database clear-all`; all six commands also exposed as MCP tools `database_*`, destructive ones gated on an explicit `confirm=true` parameter (no interactive prompt over MCP stdio); fixed latent circular import by importing `run_mcp` lazily in `cli/mcp_app.py` (`pytest tests/test_mcp.py` standalone used to fail) | Clear flags appeared on arbitrary crawl/query subcommands ("randomly"), and the schema-mismatch error pointed at a removed flag; destructive operations belong in one place that can grow (`database` = home for future DB tasks); agents may recover from schema-mismatch via MCP, but must opt in per call | (uncommitted) |
79
+ | 2026-11-10 | **Config CLI: `config init PATH` positional, `config show -o FORMAT` (was `--format`)**: `config show` now prints the active config (was a stub); `config init` target is a positional argument, its `--format` stays; `ConfigFormat` StrEnum (toml/yaml/json) replaces the bare `Literal`; `tags-backup.json` is deleted after a successful `--clear-db` restore | Every data output takes `--output` and the `--output` option is no longer a mandatory option on `config init`; StrEnum rule covers config formats | (uncommitted) |
80
+ | 2026-11-10 | **PyPI publish moved into the Release workflow**: `pypi` job added to `.github/workflows/release.yml` (downloads the `dist` artifact, trusted publishing via `id-token: write` + `pypi` environment), `pypi.yml` deleted; the PyPI trusted-publisher entry must point at workflow `release.yml` + environment `pypi` (registered as a pending publisher for project `3gpp-crawler`) | `pypi.yml` (`on: release: [published]`) never fired — releases are created with `GITHUB_TOKEN`, and GitHub suppresses events raised by `GITHUB_TOKEN`, so no other workflow triggers; consolidating the publish avoids the PAT that fixing `release.yml`'s token would require | (this commit) |
@@ -0,0 +1,37 @@
1
+ # AGENTS.md — MAINTENANCE
2
+
3
+ How to keep `.agents/` files current.
4
+
5
+ ## Process
6
+
7
+ 1. When a rule changes, update the owning file — never another file.
8
+ 2. When adding a new state file or directory under `.agents/`, add it to the
9
+ index table in root `AGENTS.md` and to **File update triggers** below.
10
+ 3. After any `.agents/` change, check the index for stale entries.
11
+
12
+ ## Principles
13
+
14
+ - **Single source of truth.** Each rule lives in exactly one file. The tier,
15
+ pointer, rationale, and size rules are in **DOX authoring**
16
+ (`.agents/POLICIES.md`) — consult it on every DOX change.
17
+ - **AGENTS.md is an index.** It points to `.agents/` files, does not replace them.
18
+ - **No logbooks.** State files describe current contracts; git owns history —
19
+ see `.agents/POLICIES.md`.
20
+ - **State files stay lean.** When a file approaches its size budget, split
21
+ detail into the matching subdirectory (`.agents/files/`, `.agents/policies/`,
22
+ `.agents/tools/`, `.agents/maintenance/`) — every file there MUST be listed
23
+ in its state file.
24
+
25
+ ## File update triggers
26
+
27
+ | File / Dir | Update when |
28
+ | ------------ | ------------- |
29
+ | `ONBOARDING.md` | Project structure, tooling, or entry points change |
30
+ | `POLICIES.md` | Boundaries, priorities, or verification change |
31
+ | `FILES.md` | Path constants, config keys, or naming conventions change |
32
+ | `TOOLS.md` | Tools, MCP servers, skills, or CLIs added, removed, or changed |
33
+ | `HISTORY.md` | Notable decision made or resolved |
34
+ | `MAINTENANCE.md` | Maintenance procedures, triggers, or principles change |
35
+ | `plans/` | New feature implementation starts |
36
+ | `history/` | HISTORY.md overflow or completed plans archived (rename per naming schema in `FILES.md`) |
37
+ | `files/`, `policies/`, `tools/`, `maintenance/` | State files split into subdirectories |
@@ -0,0 +1,70 @@
1
+ # AGENTS.md — ONBOARDING
2
+
3
+ Read this when starting a new session. After first read, only revisit when
4
+ project structure or tooling changes significantly.
5
+
6
+ ## Project
7
+
8
+ CLI tool for querying structured 3GPP document data (TDocs, Specs,
9
+ Meetings). Full docs at `docs/` (see `docs/index.md`) and `README.md`.
10
+
11
+ ## Quick start
12
+
13
+ ```bash
14
+ # Lint
15
+ uv run ruff check src/ tests/
16
+
17
+ # Test (all / single)
18
+ uv run pytest -v
19
+ uv run pytest tests/test_file.py -v
20
+
21
+ # Coverage
22
+ uv run pytest --cov=src --cov-report=term-missing
23
+
24
+ # Add dependency
25
+ uv add <package>
26
+ ```
27
+
28
+ ## Entry points (read these first)
29
+
30
+ | File | Why |
31
+ |------|-----|
32
+ | `AGENTS.md` | Root rail — rules + `.agents/` index |
33
+ | `.agents/POLICIES.md` | Boundaries, priorities, verification |
34
+ | `.agents/FILES.md` | Source-of-truth locations |
35
+ | `docs/development.md` | Setup, workflow, architecture |
36
+ | `docs/index.md` | Documentation index |
37
+
38
+ ## Where to dig deeper
39
+
40
+ - `docs/` — user-facing documentation (crawl, query, tags, config)
41
+ - `.agents/TOOLS.md` — tools, MCP servers, skills, CLIs in use
42
+ - `.agents/history/` — detailed change history
43
+ - `.agents/HISTORY.md` — past decisions and rationale
44
+ - Source-tree AGENTS.md files — local contracts per area
45
+ - `.agents/skills/3gpp-*/SKILL.md` — 3GPP domain context
46
+
47
+ ## Terminology
48
+
49
+ | Term | Means |
50
+ |------|-------|
51
+ | TDoc | 3GPP Temporary Document (e.g., `S4-250638`) |
52
+ | Spec | 3GPP Technical Specification (TS/TR, e.g., `TS 26.444`) |
53
+ | WG | Working Group (e.g., S4, RAN1, CT3) |
54
+ | TSG | Technical Specification Group (SA, RAN, CT) |
55
+ | Portal | 3GPP EOL authenticated portal |
56
+
57
+ ## Architecture
58
+
59
+ - `tdocs/`, `specs/`, `meetings/` — domain packages; operations via
60
+ explicit submodule imports (no re-exports, circular import prevention)
61
+ - `database/` — Oxyde ORM, one model per table in `oxyde_models.py`
62
+ - `cli/` — thin Typer/Rich wrappers only
63
+ - `config/` — `ThreeGPPConfig` (settings) + `CacheManager` (runtime paths)
64
+ - `http_client/` — cached sessions (`create_cached_session()`)
65
+
66
+ ## Available tools
67
+
68
+ Development tools, MCP servers, skills, and CLIs are inventoried in the
69
+ state file `.agents/TOOLS.md` — read it before assuming a tool, update it
70
+ when tooling changes.
@@ -0,0 +1,228 @@
1
+ # AGENTS.md — POLICIES
2
+
3
+ Always applicable. Boundaries, priorities, verification, checklist.
4
+
5
+ ## Priorities
6
+
7
+ 1. Correctness
8
+ 2. Evidence
9
+ 3. Safety
10
+ 4. Minimal changes
11
+ 5. Consistency
12
+ 6. Performance
13
+
14
+ ## Boundaries
15
+
16
+ - NEVER fabricate paths, commits, APIs, config keys, env vars, test results,
17
+ or benchmark numbers. State gaps explicitly.
18
+ - NEVER guess at command names, flags, or paths. Read source or run `--help`.
19
+ - NEVER game verification by weakening assertions, narrowing scope, reducing
20
+ coverage, or skipping checks.
21
+ - NEVER add secrets, API keys, or tokens to files or logs. If encountered,
22
+ note the location and stop.
23
+ - NEVER run destructive commands (`rm -rf`, `git reset --hard`,
24
+ `git push --force`) without explicit confirmation.
25
+ - NEVER delete or move files without explicit instruction.
26
+ - NEVER create temp files in project root. Use a dedicated temp dir.
27
+ - Be direct. Avoid flattery, filler, and agreeing with incorrect premises.
28
+
29
+ ## Change constraints
30
+
31
+ - Minimal, surgical edits. Preserve existing style.
32
+ - No new dependencies without explicit instruction. Prefer existing deps.
33
+ - No unrelated refactoring while fixing a bug. Note adjacent issues separately.
34
+ - Propagate failures with existing error patterns; never swallow silently.
35
+ - Check injection, path traversal, unvalidated input, auth bypass, and
36
+ secret leakage risks on every change.
37
+
38
+ ## Uncertainty
39
+
40
+ - Ask before acting when intent is materially ambiguous, or when a choice
41
+ changes behavior, API/UX, naming, persistence, auth, dependencies, config,
42
+ or compatibility. Prefer one targeted question; bundle only independently
43
+ answerable ones. Proceed when ambiguity is low-risk and conventions
44
+ decide — state the assumption briefly.
45
+
46
+ ## Evidence
47
+
48
+ Gather evidence proportional to risk: trivial edits → target file + adjacent
49
+ context; behavioral/API/dependency/infra changes → trace execution path,
50
+ call sites, constraints, regression surface first. Check local code, imports,
51
+ config, types, tests before assuming behavior. If local dependency code is
52
+ unreadable, check upstream docs or source. Prefer external verification
53
+ (fresh test) over self-review; state uncertainty when unconfirmed.
54
+
55
+ ## Workflow
56
+
57
+ 1. Explore in the main agent first — read files, trace execution paths,
58
+ search patterns. Never delegate before you have seen the data.
59
+ 2. Scan skills for direct and adjacent matches before choosing the path.
60
+ 3. Single-track or dependent steps stay in the main agent; 2+ independent
61
+ tracks → launch all subagents in the same response. Use 2+ or none,
62
+ NEVER exactly 1.
63
+ 4. Implement the smallest correct change; run the narrowest relevant check.
64
+
65
+ ## Subagents
66
+
67
+ Subagent calls block the main agent — launch all in one batch. Each prompt
68
+ requires a concrete return format (specific answer, list, or summary),
69
+ never "report findings". Tracks must not depend on each other's results.
70
+ Don't hand off data already in main-agent context for formatting or
71
+ transformation.
72
+
73
+ ## Testing
74
+
75
+ - Preserve existing tests; update them when behavior changes. Never silently
76
+ change tested behavior.
77
+ - Scope validation proportionally: docs → readback; types → typecheck;
78
+ runtime/UI → targeted test, lint, or build.
79
+ - State pre-existing failures without attributing them to your work. One
80
+ targeted fix if a post-change failure cause is clear, else stop and report.
81
+ - Non-trivial logic (branch, loop, parser, money/security path) leaves ONE
82
+ runnable check: assert-based `demo()`/`__main__` or one small `test_*.py`.
83
+ Trivial one-liners need no test.
84
+
85
+ ## Git & PRs
86
+
87
+ Commit only when explicitly requested; message states the change and why.
88
+ PRs small, one concern. No force-push to main/master; no `--no-verify` or
89
+ `--no-gpg-sign`.
90
+
91
+ ## Code quality
92
+
93
+ Universal defaults. Project-specific standards live in child AGENTS.md.
94
+
95
+ - **SRP** — one reason to change per module/function.
96
+ - **DRY** — check before adding. Extract on third occurrence (Rule of Three).
97
+ - **Redundant code** — remove dead branches, unreachable conditions, unused
98
+ params/imports before finishing.
99
+ - **Duplication vs. abstraction** — prefer duplication over wrong premature
100
+ abstraction.
101
+ - No new code-quality tooling by default — opt in per project.
102
+
103
+ ## Completion checklist
104
+
105
+ - Change solves the stated problem.
106
+ - Relevant validation ran (or gaps stated).
107
+ - No known unintended side effects; no secrets added or exposed.
108
+
109
+ ## Verification
110
+
111
+ ```bash
112
+ # Lint
113
+ uv run ruff check src/ tests/
114
+
115
+ # Test (all / single)
116
+ uv run pytest -v
117
+ uv run pytest tests/test_file.py -v
118
+
119
+ # Coverage
120
+ uv run pytest --cov=src --cov-report=term-missing
121
+
122
+ # Add dependency
123
+ uv add <package>
124
+ ```
125
+
126
+ Note: `ty` is not installed — do not run `uv run ty check` unless added.
127
+
128
+ ## Response format
129
+
130
+ Concise and specific. No filler, intros, or restated requirements.
131
+ Answer direct questions directly.
132
+
133
+ For review/debugging/analysis: findings with references, conclusion,
134
+ approach. Mention caveats and unverified risks.
135
+
136
+ ## DOX authoring (keep AGENTS.md lean)
137
+
138
+ AGENTS.md and `.agents/` files share limited context. Bloat and duplication
139
+ are the failure mode.
140
+
141
+ ### Where a rule lives
142
+
143
+ A rule goes in the **highest (most general) tier that fully applies**:
144
+
145
+ - Applies to **all code in the project** → `.agents/POLICIES.md` (default).
146
+ - Meaningful **only inside one subtree** → that subtree's `AGENTS.md`.
147
+ - Just helps navigation → the parent's Child DOX Index, nothing else.
148
+
149
+ ### Reference, don't restate
150
+
151
+ A rule appears in **exactly one file**. Other files use a pointer line:
152
+ `<topic> — see <file>`. Never copy the rule, rationale, or example.
153
+
154
+ ### Rule first, rationale second, never third
155
+
156
+ A DOX line is the rule. If a rationale is costly to rediscover, add one
157
+ short clause. No multi-paragraph explanations or code pairs — those belong
158
+ in a skill or `docs/`, linked once.
159
+
160
+ ### Content rules
161
+
162
+ - **No tree views.** Generate on demand with `rg --files | tree-cli --fromfile`.
163
+ - **No history in AGENTS.md files.** Git log has routine history. Record only
164
+ decisions costly to rediscover — in `.agents/HISTORY.md` (or
165
+ `.agents/history/` for overflow archives).
166
+ - **Lean state files, optional subdirectories.** State files stay brief entry
167
+ points (index-style, not sprawling documents). A state file that grows past
168
+ its size budget (≤ **120 lines**) must be split into
169
+ `.agents/<topic>/<name>.md` subdirectories — not stuffed longer. Every file
170
+ in an optional subdirectory **MUST** be mentioned in the state file that
171
+ owns it. See **State file subdirectories** below for the naming map.
172
+ - **No TODO lists.** Use issue trackers or beads.
173
+ - Prefer direct bullets with explicit names.
174
+ - Trim obvious statements, repeated rules, and detail that no longer applies.
175
+
176
+ ## Implementation Plans
177
+
178
+ - Plans, refactoring plans, and design docs go in `.agents/plans/<feature>/`
179
+ — NOT under version control (gitignored).
180
+ - Name descriptively with phase-number prefixes so file order matches
181
+ implementation order, e.g. `01-sub-feature.md`, `02-next-sub-feature.md`.
182
+ - NEVER commit plans to git. They are mutable working artifacts.
183
+ - The archive trigger is **plan completion**: archive the moment the work
184
+ lands — don't wait for the next maintenance pass (see **Documentation**).
185
+ - Shipped docs (user-facing guides, API references) go in `docs/` and
186
+ ARE committed.
187
+
188
+ ## State file subdirectories
189
+
190
+ Each state file has a matching optional subdirectory for growth — the file
191
+ stays a lean index and the subdirectory carries the detail:
192
+
193
+ | State file | Optional subdirectory |
194
+ | ---------- | --------------------- |
195
+ | `FILES.md` | `.agents/files/` |
196
+ | `POLICIES.md` | `.agents/policies/` |
197
+ | `TOOLS.md` | `.agents/tools/` |
198
+ | `MAINTENANCE.md` | `.agents/maintenance/` |
199
+
200
+ - Only create a subdirectory when its state file approaches its size budget.
201
+ - Every file in a subdirectory MUST be listed in its state file (name + one
202
+ line of what it covers).
203
+ - `ONBOARDING.md` and `HISTORY.md` have no subdirectories: entry points stay
204
+ a single file, and history growth goes to `.agents/history/`.
205
+
206
+ ## Documentation
207
+
208
+ - When `.agents/HISTORY.md` grows too large, archive older entries to
209
+ `.agents/history/`. Reference them from `.agents/HISTORY.md`.
210
+ - Completed plans (`.agents/plans/<feature>/`) are archived to
211
+ `.agents/history/` for long-term reference — rename with completion-date
212
+ prefix per the naming schema in `.agents/FILES.md`.
213
+ - `.agents/history/` IS version-controlled (durable decision records).
214
+ - AGENTS.md and state files describe the project's current contracts — never
215
+ append session notes, iteration logs, or changelogs; delete stale text
216
+ instead. `.agents/HISTORY.md` is the only permitted exception and holds
217
+ high-level decisions only.
218
+
219
+ ## Size budget
220
+
221
+ - `.agents/` files: ≤ **120 lines** (always-injected context).
222
+ - Subtree `AGENTS.md`: ≤ **250 lines** (loaded cumulatively with parents).
223
+
224
+ Exceeding the budget signals restating instead of pointing, or hoarding
225
+ rationale. Cut first; split the subtree only as a last resort.
226
+
227
+ When a state file exceeds its budget, split detail into its matching
228
+ subdirectory — see **State file subdirectories** above.
@@ -0,0 +1,52 @@
1
+ # AGENTS.md — TOOLS
2
+
3
+ State file: inventory of tools used in development — CLIs, MCP servers,
4
+ skills, runtimes, and project scripts. Demand-loaded like all state files;
5
+ keep it current (see `.agents/MAINTENANCE.md`).
6
+
7
+ ## Rules
8
+
9
+ - Use an existing tool before adding a new one. No new tools, MCP servers,
10
+ skills, or dependencies without explicit instruction (`.agents/POLICIES.md`).
11
+ - Each tool appears exactly once, in its primary table.
12
+ - Tables describe current usage — delete rows when tools leave; this is not a
13
+ historical log.
14
+
15
+ ## Subdirectory
16
+
17
+ If this file grows past its size budget, split detail into
18
+ `.agents/tools/<name>.md` — every file there MUST be listed above.
19
+
20
+ ## CLI tools & runtimes
21
+
22
+ | Tool | When | Purpose |
23
+ | ---- | ---- | ------- |
24
+ | `uv` | Python deps & scripts | Package manager: `uv run`, `uv add` |
25
+ | `mise` | Running tasks | Task runner; definitions in `.config/mise/conf.d/*.toml` |
26
+ | `bd` / beads | Issue tracking | Task lifecycle, dependencies, session persistence; embedded Dolt store synced to private repo `3gpp-crawler-beads` (push: `DOLT_REMOTE_USER=oauth2 DOLT_REMOTE_PASSWORD=$GITLAB_TOKEN bd dolt push`) |
27
+ | `glab` | GitLab (forge.3gpp.org) | Forge mirror admin (tokens, mirror checks); primary repo is GitHub |
28
+ | `gh` | GitHub (github.com/jr2804/3gpp-crawler) | Primary repo, releases, Pages, secrets (`FORGE_MIRROR_TOKEN`) |
29
+
30
+ ## MCP servers
31
+
32
+ | Server | When | Purpose |
33
+ | ------ | ---- | ------- |
34
+ | `grepai` | Finding code | Semantic search by meaning, not text; call graphs |
35
+ | `teddi-mcp` | Terms/definitions | ETSI TEDDI queries, technical body codes |
36
+
37
+ ## Skills
38
+
39
+ | Skill | When | Purpose |
40
+ | ----- | ---- | ------- |
41
+ | `3gpp-*` | Any 3GPP work | Domain context: tdocs, specs, meetings, releases, WGs, portal auth |
42
+ | `python-ultimate` / `pydantic` / `ty-skills` | Python work | Coding standards, pydantic, type checking |
43
+ | `ponytail` / `caveman` | Code / prose | Minimal code / terse communication modes |
44
+
45
+ ## Project scripts & tasks
46
+
47
+ | Command | Purpose |
48
+ | ------- | ------- |
49
+ | `mise run lint` / `typecheck` / `test` | Ruff / ty / pytest+coverage |
50
+ | `mise run format-md` | rumdl markdown lint+fmt |
51
+ | `mise run docs` | zensical build (`docs:mkdocs` = mkdocs for the Pages workflow) |
52
+ | `mise run add-mcp-servers` / `add-skills` | Install from `data/dev-features.csv` / `data/skills.csv` |
@@ -0,0 +1,5 @@
1
+ # Summary – 2025-10-20
2
+
3
+ - Added `docs/QUICK_REFERENCE.md` as the authoritative CLI reference.
4
+ - Documented targeted TDoc fetch behaviour triggered by `query` and `open` commands.
5
+ - Described the end-to-end `open` workflow, including download, extraction, and launch details.