doc3gpp 0.3.2__tar.gz → 0.3.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/AGENTS.md +6 -2
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/PKG-INFO +8 -6
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/README.md +7 -5
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/architecture.md +8 -5
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/cli.md +33 -26
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/code-map.md +1 -1
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/web-server.md +9 -10
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/pyproject.toml +1 -1
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/__init__.py +1 -1
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/cli.py +18 -4
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/cli_auto_sync.py +17 -18
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/cli_filters.py +7 -6
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/cli_url_helpers.py +19 -9
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/data/skills/doc3gpp/SKILL.md +2 -2
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/models/spec_doc.py +5 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/parsers/cr/header.py +3 -2
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/parsers/direct_extractor.py +165 -50
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/parsers/tdoc_parser.py +2 -2
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/scraping/spec_doc_source.py +31 -1
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/scraping/tdoc_zip_source.py +3 -3
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/services/tdoc_cr_service.py +25 -19
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/errors.py +4 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/mcp_server.py +20 -14
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/routes/jobs.py +17 -11
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/static/js/spec_doc_parse.js +1 -1
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/workers/handlers.py +54 -23
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/integration/test_mcp_end_to_end.py +15 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/integration/test_spec_doc_cli.py +61 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/integration/test_spec_doc_web.py +22 -1
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/integration/test_tdoc_parse_direct_sqlite.py +6 -8
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_cli_auto_sync.py +5 -2
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_job_worker.py +65 -17
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_jobs_sql.py +2 -2
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_parse_tdoc_url_route.py +40 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_spec_doc_source.py +17 -1
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_tdoc_cr_service.py +16 -28
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_tdoc_cr_service_ftp_batch.py +19 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_tdoc_parse_direct.py +26 -19
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_tdoc_parse_url_batch.py +23 -5
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_web_routes.py +2 -1
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/web/test_mcp_server.py +87 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/.env.example +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/.github/workflows/publish.yml +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/.gitignore +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/.superpowers/sdd/.gitignore +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/.superpowers/sdd/2026-09-24-spec-doc-metadata-and-portal-fix/final-fix-report.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/.superpowers/sdd/2026-09-24-spec-doc-metadata-and-portal-fix/task-2-report.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/.superpowers/sdd/2026-09-24-spec-doc-web-portal/final-fix-report.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/.superpowers/sdd/2026-09-24-spec-doc-web-portal/task-2-report.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/.superpowers/sdd/2026-09-25-spec-parsed-output/final-fix-report.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/.superpowers/sdd/2026-09-25-spec-parsed-output/task-3-report.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/.superpowers/sdd/2026-09-25-spec-parsed-output/task-4-report.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/.superpowers/sdd/2026-09-25-spec-parsed-output/task-7-report.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/LICENSE +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/doc3gpp.toml.example +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/3gpp-knowledge.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/TODO.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/conventions.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/known-constraints.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/plans/2026-07-28-compact-output.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/plans/2026-07-28-tdoc-size-limit.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/plans/2026-07-29-fts5-search.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/plans/2026-07-29-tdoc-cr-body-changes.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/plans/2026-07-30-fts5-perf.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/plans/2026-07-31-embedding-search.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/plans/2026-08-01-fts5-hit-rename.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/plans/2026-08-01-fts5-semantic-rerank.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/plans/2026-08-01-semantic-search-revision.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/plans/2026-08-02-all-extra.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/plans/2026-08-02-remove-mysql-postgres.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/plans/2026-08-02-web-and-mcp-server.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/plans/2026-08-03-meeting-sync-display.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/plans/2026-08-03-meetings-tdoc-filter.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/plans/2026-08-04-web-ui-enhancements.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/plans/2026-08-05-tdoc-columns-dropdown.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/plans/2026-08-05-web-parse-and-search.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/plans/2026-08-07-mcp-sse-transport.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/plans/2026-08-10-spec-sync-list-show.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/plans/2026-08-11-spec-rapporteurs-comment.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/plans/2026-08-11-spec-rapporteurs-filter.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/plans/2026-08-12-mcp-spec-sync.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/plans/2026-08-12-single-spec-sync.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/plans/2026-08-12-spec-show-version-limit.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/plans/2026-08-12-spec-sync-dynareport-fetch.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/plans/2026-08-13-idempotent-cancel.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/plans/2026-08-13-mcp-parse-tdoc-url.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/plans/2026-08-13-per-spec-skip-rule.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/plans/2026-08-13-spec-per-version-details-flag.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/plans/2026-08-13-web-job-detail-params.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/plans/2026-08-13-web-mcp-meeting-name-filter.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/plans/2026-08-14-cover-page-summary-of-change.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/plans/2026-08-14-job-progress.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/plans/2026-08-14-sync-hub-page.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/plans/2026-08-14-version-display.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/plans/2026-08-14-web-tdoc-extracted-changes.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/plans/2026-08-19-tdocs-xlsx-metadata.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/plans/2026-08-19-web-mcp-tdoc-show-by-url.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/plans/2026-09-11-ran5-testcases.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/plans/2026-09-12-testcase-nested-statuses.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/plans/2026-09-12-testcase-separate-db.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/plans/2026-09-13-resource-schema.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/plans/2026-09-22-remote-embedding-api.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/plans/2026-09-23-spec-doc-parse.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/plans/2026-09-24-spec-doc-fetch-command-removal.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/plans/2026-09-24-spec-doc-metadata-and-portal-fix.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/plans/2026-09-24-tdoc-search-namespace.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/plans/2026-09-25-spec-doc-chunk-context.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/plans/2026-09-25-spec-doc-pagination.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/plans/2026-09-25-spec-parsed-output.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/plans/2026-09-26-unified-search-index.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/plans/2026-09-27-mcp-stdio.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/specs/2026-07-28-compact-output-design.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/specs/2026-07-28-tdoc-size-limit-design.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/specs/2026-07-29-fts5-search-design.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/specs/2026-07-29-tdoc-cr-body-changes-design.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/specs/2026-07-30-fts5-perf.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/specs/2026-07-31-embedding-search-design.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/specs/2026-08-01-fts5-hit-rename-design.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/specs/2026-08-01-fts5-semantic-rerank-design.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/specs/2026-08-01-semantic-search-revision-design.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/specs/2026-08-02-all-extra-design.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/specs/2026-08-02-remove-mysql-postgres-design.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/specs/2026-08-02-web-and-mcp-server-design.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/specs/2026-08-03-meeting-sync-display-design.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/specs/2026-08-03-meetings-tdoc-filter-design.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/specs/2026-08-04-web-ui-enhancements-design.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/specs/2026-08-05-tdoc-columns-dropdown-design.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/specs/2026-08-05-web-parse-and-search-design.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/specs/2026-08-10-spec-sync-list-show-design.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/specs/2026-08-11-spec-rapporteurs-comment-design.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/specs/2026-08-11-spec-rapporteurs-filter-design.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/specs/2026-08-12-mcp-spec-sync-design.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/specs/2026-08-12-single-spec-sync-design.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/specs/2026-08-12-spec-show-version-limit-design.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/specs/2026-08-12-spec-sync-dynareport-fetch-design.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/specs/2026-08-13-docs-review-design.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/specs/2026-08-13-idempotent-cancel-design.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/specs/2026-08-13-mcp-parse-tdoc-url-design.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/specs/2026-08-13-spec-per-version-details-flag-design.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/specs/2026-08-13-web-job-detail-params-design.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/specs/2026-08-13-web-mcp-meeting-name-filter-design.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/specs/2026-08-14-cover-page-summary-of-change-design.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/specs/2026-08-14-sync-hub-page-design.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/specs/2026-08-14-version-display-design.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/specs/2026-08-14-web-jobs-cancel-button-design.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/specs/2026-08-14-web-tdoc-extracted-changes-design.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/specs/2026-08-19-tdocs-xlsx-metadata-design.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/specs/2026-08-19-web-mcp-tdoc-show-by-url-design.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/specs/2026-09-11-ran5-testcases-design.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/specs/2026-09-12-testcase-nested-statuses-design.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/specs/2026-09-12-testcase-separate-db-design.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/specs/2026-09-13-resource-schema-design.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/specs/2026-09-22-remote-embedding-api-design.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/specs/2026-09-23-spec-doc-parse-design.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/specs/2026-09-24-spec-doc-fetch-command-removal-design.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/specs/2026-09-24-spec-doc-metadata-and-portal-fix-design.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/specs/2026-09-24-spec-doc-web-portal-design.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/specs/2026-09-24-tdoc-search-namespace-design.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/specs/2026-09-25-spec-doc-chunk-context-design.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/specs/2026-09-25-spec-doc-pagination-design.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/specs/2026-09-25-spec-parsed-output-design.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/specs/2026-09-26-unified-search-index-design.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/docs/superpowers/specs/2026-09-27-mcp-stdio-design.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/scripts/dev_run.sh +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/scripts/test_sqlite.sh +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/cli_server.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/config.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/data/doc3gpp.toml.example +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/models/__init__.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/models/index.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/models/jobs.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/models/meeting.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/models/schema_info.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/models/search.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/models/semantic_search.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/models/spec.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/models/sync.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/models/tdoc.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/models/tdoc_cr.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/models/tdoc_cr_change_details.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/models/tdoc_file.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/models/tdoc_show.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/models/testcase.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/models/tsg.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/models/unified_search.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/models/wi.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/parsers/__init__.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/parsers/calendar_parser.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/parsers/cr/__init__.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/parsers/cr/body_changes.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/parsers/cr/cover_page.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/parsers/cr/cr_parsers.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/parsers/cr/helpers.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/parsers/cr/ttcn_functions.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/parsers/cr/ttcn_sections.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/parsers/cr_parser.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/parsers/docx_converter.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/parsers/html_parsers.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/parsers/normalizers.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/parsers/spec_doc.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/parsers/spec_doc_chunker.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/parsers/spec_parser.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/parsers/spec_release.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/parsers/tdoc_file_parser.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/parsers/tdoc_parsers.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/parsers/testcase_parser.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/parsers/wi_parser.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/repository/__init__.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/repository/protocols.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/scraping/__init__.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/scraping/cache.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/scraping/cache_keys.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/scraping/calendar_source.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/scraping/client.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/scraping/ftp_source.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/scraping/portal_source.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/scraping/spec_source.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/scraping/testcase_source.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/scraping/wi_source.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/services/__init__.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/services/_duration.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/services/embedding/__init__.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/services/embedding/chunker.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/services/embedding/remote_embedder.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/services/factory.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/services/meetings_service.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/services/search_service.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/services/semantic_reranker.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/services/semantic_search_service.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/services/spec_doc_index_service.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/services/spec_doc_search_facade.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/services/spec_doc_search_service.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/services/spec_doc_semantic_service.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/services/spec_doc_service.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/services/spec_service.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/services/tdoc_file_service.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/services/tdoc_index_service.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/services/tdoc_search_facade.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/services/tdoc_service.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/services/tdoc_sync_coordinator.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/services/testcase_service.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/services/tsg_service.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/services/wi_service.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/settings/__init__.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/settings/config_source.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/settings/config_writer.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/settings/loader.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/settings/schema.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/storage/__init__.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/storage/backends/__init__.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/storage/backends/sqlite.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/storage/cache.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/storage/compression.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/storage/db/__init__.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/storage/db/base.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/storage/db/fts5_query.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/storage/db/migrate.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/storage/db/migrations/README.md +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/storage/db/models.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/storage/db/session.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/storage/db/specdata_base.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/storage/db/testcase_base.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/storage/export.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/storage/repositories/__init__.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/storage/repositories/jobs_sql.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/storage/repositories/meeting_sql.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/storage/repositories/rich_filters.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/storage/repositories/search_sql.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/storage/repositories/spec_doc_search_sql.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/storage/repositories/spec_doc_sql.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/storage/repositories/spec_doc_vector_sql.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/storage/repositories/spec_sql.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/storage/repositories/tdoc_cr_change_details_sql.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/storage/repositories/tdoc_cr_sql.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/storage/repositories/tdoc_cr_ttcn_sql.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/storage/repositories/tdoc_file_sql.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/storage/repositories/tdoc_sql.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/storage/repositories/testcase_sql.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/storage/repositories/tsg_sql.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/storage/repositories/vector_sql.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/storage/repositories/wi_sql.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/__init__.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/app.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/deps.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/filters.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/install.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/mcp_stdio.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/render.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/routes/__init__.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/routes/landing.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/routes/meetings.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/routes/search.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/routes/spec_docs.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/routes/specs.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/routes/sync.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/routes/tdocs.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/routes/testcases.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/routes/tsgs.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/routes/wis.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/state.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/static/htmx.min.js +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/static/js/job_poller.js +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/static/js/meeting_sync.js +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/static/js/search.js +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/static/js/spec_clipboard.js +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/static/js/spec_sync.js +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/static/js/sync_hub.js +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/static/js/tdoc_columns.js +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/static/js/tdoc_parse.js +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/static/style.css +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/templates/base.html +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/templates/job_status.html +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/templates/landing.html +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/templates/meeting_list.html +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/templates/meeting_show.html +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/templates/partials/_job_row.html +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/templates/partials/job_status.html +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/templates/partials/meeting_filters.html +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/templates/partials/meeting_results.html +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/templates/partials/pagination.html +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/templates/partials/schema_results.html +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/templates/partials/search_form.html +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/templates/partials/search_resource_tabs.html +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/templates/partials/search_results.html +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/templates/partials/search_results_table.html +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/templates/partials/spec_doc_chunks.html +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/templates/partials/spec_doc_search_form.html +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/templates/partials/spec_doc_search_results.html +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/templates/partials/spec_doc_search_results_table.html +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/templates/partials/spec_doc_show_results.html +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/templates/partials/spec_doc_toc_results.html +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/templates/partials/spec_filters.html +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/templates/partials/spec_results.html +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/templates/partials/sync_recent_jobs.html +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/templates/partials/tdoc_filters.html +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/templates/partials/tdoc_results.html +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/templates/partials/testcase_filters.html +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/templates/partials/testcase_results.html +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/templates/partials/wi_filters.html +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/templates/partials/wi_results.html +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/templates/schema.html +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/templates/search_results.html +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/templates/spec_doc_show.html +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/templates/spec_doc_toc.html +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/templates/spec_docs_search.html +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/templates/spec_list.html +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/templates/spec_show.html +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/templates/sync.html +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/templates/tdoc_content.html +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/templates/tdoc_list.html +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/templates/tdoc_show.html +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/templates/testcase_list.html +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/templates/testcase_show.html +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/templates/tsg_list.html +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/templates/tsg_show.html +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/templates/wi_list.html +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/templates_setup.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/workers/__init__.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/src/doc3gpp/web/workers/job_worker.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/conftest.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/fixtures/sample_pages/3GPP-meeting-R5.html +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/fixtures/search_corpus.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/fixtures/semantic_search_corpus.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/fixtures/spec_pages/R5_crs.html +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/fixtures/spec_pages/R5_detail.html +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/fixtures/spec_pages/R5_detail_portal.html +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/fixtures/spec_pages/R5_etsi.html +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/fixtures/spec_pages/R5_list.html +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/fixtures/tdoc_cr_doc/C6-250028.zip +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/fixtures/tdoc_cr_doc/R5-227476.zip +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/fixtures/tdoc_cr_doc/R5-253079.zip +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/fixtures/tdoc_cr_doc/R5s260009.zip +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/fixtures/tdoc_cr_doc/R5s260051.zip +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/fixtures/tdoc_cr_doc/R5s260135.zip +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/fixtures/tdoc_cr_doc/R5s260176.zip +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/fixtures/tdoc_xlsx/TDoc_List_Meeting_85434_portal.xlsx +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/fixtures/tdoc_xlsx/TDoc_List_Meeting_RAN5#111.xlsx +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/fixtures/wi_pages/R5.html +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/integration/test_auto_sync_sqlite.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/integration/test_cli_server.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/integration/test_cli_sqlite.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/integration/test_config_init_cli_sqlite.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/integration/test_config_set_cli_sqlite.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/integration/test_db_reset_sqlite.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/integration/test_embed_after_parse.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/integration/test_meeting_service_sqlite.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/integration/test_migrate_tsg_spec_last_sync_drop.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/integration/test_online_3gpp_calendar.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/integration/test_online_spec_doc_sync.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/integration/test_online_spec_sync.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/integration/test_online_tdoc_fetch_r5.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/integration/test_online_tdoc_parse.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/integration/test_online_testcase_sync.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/integration/test_parse_tdoc_url_job_sqlite.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/integration/test_schema_parity.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/integration/test_sdk_integration.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/integration/test_search_after_parse.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/integration/test_search_extras_disabled.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/integration/test_search_filters.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/integration/test_search_index_lifecycle.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/integration/test_search_indexes.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/integration/test_search_previews_per_column.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/integration/test_search_query_sem_rerank.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/integration/test_search_schema.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/integration/test_search_sem_end_to_end.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/integration/test_search_snippet_column.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/integration/test_search_weighted_bm25.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/integration/test_semantic_extras_disabled.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/integration/test_spec_cli.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/integration/test_spec_doc_repo.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/integration/test_spec_doc_search_repo.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/integration/test_spec_doc_search_service.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/integration/test_spec_doc_service.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/integration/test_spec_migration.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/integration/test_spec_parsed_output.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/integration/test_spec_sql.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/integration/test_sqlite_backend.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/integration/test_sync_hub_end_to_end.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/integration/test_tdoc_cr_change_details_sqlite.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/integration/test_tdoc_cr_rename_migration.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/integration/test_tdoc_cr_sqlite.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/integration/test_tdoc_cr_ttcn_sqlite.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/integration/test_tdoc_file_sqlite.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/integration/test_tdoc_parse_ftp_batch_sqlite.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/integration/test_tdoc_parse_local_batch_sqlite.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/integration/test_tdoc_sqlite.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/integration/test_tdocs_xlsx_metadata_migration_sqlite.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/integration/test_tdocs_xlsx_metadata_sqlite.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/integration/test_testcase_cli.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/integration/test_testcase_sql.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/integration/test_tsg_sqlite.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/integration/test_vector_index_lifecycle.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/integration/test_vector_repo_get_min_distance.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/integration/test_vector_schema_migration.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/integration/test_web_end_to_end.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/integration/test_web_search_end_to_end.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/integration/test_wi_sqlite.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/_job_polling_smoke.js +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_bind_job_polling_on_terminal.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_body_changes_extractor.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_cache_cli.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_cache_keys.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_calendar_parser.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_calendar_parser_defensive.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_chunker.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_cli_filters.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_cli_search.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_cli_search_sem.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_cli_server_start.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_cli_server_stubs.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_cli_version.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_compact_helpers.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_config_init_cli.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_config_set_cli.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_config_writer.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_cr_parser.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_db_reset_cli.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_docx_converter.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_factory_semantic.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_ftp_listing.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_fts5_query.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_index_services.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_job_row_partial.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_list_output_format.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_meeting_cli.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_meeting_cli_filters_combined.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_meeting_cli_invalid_fields.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_meeting_cli_location_filter.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_meeting_repository_combined_filters.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_meeting_repository_filters.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_meeting_repository_location_filter.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_meeting_repository_upsert.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_meeting_sync_tsg_validation.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_packaging_semantic.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_parsers_utils.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_portal_source.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_protocols_semantic.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_remote_embedder.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_remote_embedding_settings.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_rrf.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_schema_info.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_scraper_client.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_search_query_builder.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_search_service.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_search_settings.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_semantic_models.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_semantic_reranker.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_semantic_search_service.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_semantic_settings.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_server_settings.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_services_factory.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_settings.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_settings_config_file.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_spec_doc_blocks.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_spec_doc_chunker.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_spec_doc_models.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_spec_doc_parser.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_spec_doc_search_facade.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_spec_doc_service_reads.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_spec_doc_settings.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_spec_doc_vector_metadata.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_spec_model.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_spec_orm.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_spec_parser.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_spec_release.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_spec_service.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_spec_source.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_storage_utils.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_sync_hub_page.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_tdoc_cache.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_tdoc_cli_fields.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_tdoc_cr_change_details_model.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_tdoc_cr_model.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_tdoc_cr_service_body_changes.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_tdoc_file_parser.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_tdoc_file_service.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_tdoc_file_source.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_tdoc_parse_cli.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_tdoc_parse_settings.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_tdoc_parser.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_tdoc_repository_crud.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_tdoc_repository_filters.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_tdoc_search_facade.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_tdoc_service_sync.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_tdoc_show_record.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_tdoc_sync_cli.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_tdoc_sync_coordinator.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_tdoc_url_not_found.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_tdoc_zip_source.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_testcase_db_url.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_testcase_model.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_testcase_parser.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_testcase_service.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_testcase_source.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_tsg_cli.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_tsg_repository.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_tsg_service.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_tsg_url_pattern.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_ttcn_functions.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_unified_search_models.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_web_app.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_web_errors.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_web_filters.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_web_install.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_web_jobs_routes.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_web_template_filters.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_wi_cli.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_wi_parser.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/test_wi_repository_filters.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/web/test_landing_version.py +0 -0
- {doc3gpp-0.3.2 → doc3gpp-0.3.4}/tests/unit/web/test_mcp_stdio.py +0 -0
|
@@ -275,6 +275,10 @@ Workflows in one line (full prose in `docs/architecture.md`):
|
|
|
275
275
|
the result is still emitted with a warning). The zip cache is
|
|
276
276
|
keyed on the **original (sanitized) filename** (D10 fix) so
|
|
277
277
|
multiple revisions of the same tdoc_id never collide. When
|
|
278
|
+
the URL targets the canonical 3GPP FTP site, HTTPS is required (the
|
|
279
|
+
bare `www.3gpp.org/ftp/...` form is normalized), `.docx`/`.zip` files
|
|
280
|
+
must have a TDoc-shaped basename including `RP-...` plenary ids, and
|
|
281
|
+
any other canonical path is a folder with an optional trailing slash.
|
|
278
282
|
`Settings.sync.auto_sync` is enabled, `tdoc parse --from-url`
|
|
279
283
|
on a 3GPP FTP URL extracts tdoc_id candidates from the URL
|
|
280
284
|
(basename for file URLs; BFS up to `--max-depth` / `--recursive`
|
|
@@ -356,8 +360,8 @@ Workflows in one line (full prose in `docs/architecture.md`):
|
|
|
356
360
|
with `--resume`, `--stale-only`, and `--batch`, or `IndexStatus` with no
|
|
357
361
|
rebuild flag. Hybrid weighting comes from
|
|
358
362
|
`Settings.semantic_search.fts5_weight`.
|
|
359
|
-
|
|
360
|
-
|
|
363
|
+
- `doc3gpp spec doc parse --spec <id> [--release R] [--version V] [--force]` accepts exactly one spec and calls `SpecDocService.parse_many` with a one-item list → resolve the numeric-newest `SpecVersion` with a non-empty `.zip` URL via `resolve_spec_doc_version` (after optional release filtering); when both `--release` and `--version` are given, their release numbers must align (for example, `Rel-18` with `18.5.0`); explicit `--version` is strict and fails clearly when its ZIP link is missing. Fetch the ZIP with internal `fetch_spec_doc_zip` when absent (or use the zip cache at `{spec_doc.cache_dir}/zips/<spec_id>/<version>.zip`), and record the download. `--force` re-downloads before re-parsing, including pairs that already carry `parsed_at`.
|
|
364
|
+
- `doc3gpp spec doc parse --spec <id> [--release R] [--version V] [--force]` → immutable-skip when `(spec_id, version)` already carries `parsed_at` (unless `--force`) → `parse` = fetch-if-missing + `list_spec_docx` + `convert_document_to_blocks` + `order_spec_files` + `extract_spec_toc` + `chunk_blocks` → `upsert_toc` + `replace_chunks` + per-file markdown cache (`{spec_doc.cache_dir}/markdown/<spec_id>/<version>/`) + `record_parsed` + best-effort auto-index (`upsert_for_version`) / auto-embed (`index_for_version`). Oversized zips → skip bucket; unknown spec/version or empty (no-docx) zips → failure bucket. Prints `ok/skipped/failed` buckets only (`--format/--output/--compact` accepted but ignored). Background `parse_spec_docs` jobs use scalar `spec_id` / optional `release` / `version` / `force`, log and store the result in `result.failure_details`. Chunk/search metadata uses newline-delimited combined `sections` and `tables`; TOC entries retain `section_no` / `title`.
|
|
361
365
|
- `doc3gpp spec doc toc show --spec <id> --version <v> [--fields] [--format/--output/--compact]` → `SpecDocService.get_toc` (stored `(spec_id, version)` rows; miss → `BadParameter`). Default fields `section_no, title, level, source_file` (`[output.fields] spec_doc_toc`).
|
|
362
366
|
- `doc3gpp spec doc search [--text TEXT] [--semantic TEXT] [filters]` →
|
|
363
367
|
`SpecDocSearchFacade.search` with the same four mode-selection rules and
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: doc3gpp
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.4
|
|
4
4
|
Summary: Provide 3GPP TDoc information with full text search capability — a Python CLI/library, a local web UI, and an MCP server for AI clients.
|
|
5
5
|
Project-URL: Homepage, https://github.com/jerrywang121/doc3gpp
|
|
6
6
|
Project-URL: Repository, https://github.com/jerrywang121/doc3gpp
|
|
@@ -296,6 +296,8 @@ doc3gpp tdoc parse --from-url https://www.3gpp.org/ftp/.../R5s260009.zip # 3GPP
|
|
|
296
296
|
doc3gpp tdoc parse --from-url https://example.com/some.zip --format json -o /tmp/out.json # non-3GPP URL → in-memory only
|
|
297
297
|
doc3gpp tdoc parse --from-path ./tdocs --output ./parsed --recursive --format json # local batch
|
|
298
298
|
doc3gpp tdoc parse --from-url https://www.3gpp.org/ftp/.../Docs/ --recursive --output ./parsed # online batch
|
|
299
|
+
# 3GPP URLs also accept bare www.3gpp.org/ftp/...; HTTPS is required,
|
|
300
|
+
# and .docx/.zip basenames must contain a TDoc id (including RP-... plenary ids).
|
|
299
301
|
|
|
300
302
|
# show — --tdoc and --ftp-url are mutually exclusive
|
|
301
303
|
doc3gpp tdoc show --tdoc R5s260009 --format json -o r5s260009.json
|
|
@@ -366,7 +368,7 @@ values on every version row.
|
|
|
366
368
|
|
|
367
369
|
```bash
|
|
368
370
|
# use newest version with a published .zip, fetch-if-missing, convert every .docx, chunk, and auto-index
|
|
369
|
-
doc3gpp spec doc parse --spec 38.331 --
|
|
371
|
+
doc3gpp spec doc parse --spec 38.331 --release Rel-18 --version 18.5.0
|
|
370
372
|
doc3gpp spec doc parse --spec 38.331 --force # re-download and re-parse
|
|
371
373
|
|
|
372
374
|
# inspect the stored TOC and search chunk text/combined metadata
|
|
@@ -377,10 +379,10 @@ doc3gpp spec doc index --rebuild
|
|
|
377
379
|
doc3gpp spec doc schema --format json
|
|
378
380
|
```
|
|
379
381
|
|
|
380
|
-
Background `parse_spec_docs` jobs retain
|
|
381
|
-
result (`failure_details`) and log.
|
|
382
|
-
|
|
383
|
-
|
|
382
|
+
Background `parse_spec_docs` jobs retain the selected spec's failure reason in
|
|
383
|
+
the job result (`failure_details`) and log. Each job targets one spec; when
|
|
384
|
+
both release and version are supplied, their release numbers must align (for
|
|
385
|
+
example, `Rel-18` with `18.5.0`).
|
|
384
386
|
|
|
385
387
|
Spec-document rows live in a separate sibling database, normally
|
|
386
388
|
`<main-stem>_specdata.db`, and are cached below the dedicated
|
|
@@ -213,6 +213,8 @@ doc3gpp tdoc parse --from-url https://www.3gpp.org/ftp/.../R5s260009.zip # 3GPP
|
|
|
213
213
|
doc3gpp tdoc parse --from-url https://example.com/some.zip --format json -o /tmp/out.json # non-3GPP URL → in-memory only
|
|
214
214
|
doc3gpp tdoc parse --from-path ./tdocs --output ./parsed --recursive --format json # local batch
|
|
215
215
|
doc3gpp tdoc parse --from-url https://www.3gpp.org/ftp/.../Docs/ --recursive --output ./parsed # online batch
|
|
216
|
+
# 3GPP URLs also accept bare www.3gpp.org/ftp/...; HTTPS is required,
|
|
217
|
+
# and .docx/.zip basenames must contain a TDoc id (including RP-... plenary ids).
|
|
216
218
|
|
|
217
219
|
# show — --tdoc and --ftp-url are mutually exclusive
|
|
218
220
|
doc3gpp tdoc show --tdoc R5s260009 --format json -o r5s260009.json
|
|
@@ -283,7 +285,7 @@ values on every version row.
|
|
|
283
285
|
|
|
284
286
|
```bash
|
|
285
287
|
# use newest version with a published .zip, fetch-if-missing, convert every .docx, chunk, and auto-index
|
|
286
|
-
doc3gpp spec doc parse --spec 38.331 --
|
|
288
|
+
doc3gpp spec doc parse --spec 38.331 --release Rel-18 --version 18.5.0
|
|
287
289
|
doc3gpp spec doc parse --spec 38.331 --force # re-download and re-parse
|
|
288
290
|
|
|
289
291
|
# inspect the stored TOC and search chunk text/combined metadata
|
|
@@ -294,10 +296,10 @@ doc3gpp spec doc index --rebuild
|
|
|
294
296
|
doc3gpp spec doc schema --format json
|
|
295
297
|
```
|
|
296
298
|
|
|
297
|
-
Background `parse_spec_docs` jobs retain
|
|
298
|
-
result (`failure_details`) and log.
|
|
299
|
-
|
|
300
|
-
|
|
299
|
+
Background `parse_spec_docs` jobs retain the selected spec's failure reason in
|
|
300
|
+
the job result (`failure_details`) and log. Each job targets one spec; when
|
|
301
|
+
both release and version are supplied, their release numbers must align (for
|
|
302
|
+
example, `Rel-18` with `18.5.0`).
|
|
301
303
|
|
|
302
304
|
Spec-document rows live in a separate sibling database, normally
|
|
303
305
|
`<main-stem>_specdata.db`, and are cached below the dedicated
|
|
@@ -622,12 +622,15 @@ and syncs each through the `--tsg` path below.
|
|
|
622
622
|
|
|
623
623
|
### Spec-document corpus (parse → TOC → search)
|
|
624
624
|
|
|
625
|
-
1. `doc3gpp spec doc parse --spec <id
|
|
626
|
-
[--force]` calls `SpecDocService.parse_many
|
|
625
|
+
1. `doc3gpp spec doc parse --spec <id> [--release R] [--version V]
|
|
626
|
+
[--force]` accepts exactly one spec and calls `SpecDocService.parse_many`
|
|
627
|
+
with a one-item list. The version resolves via
|
|
627
628
|
`resolve_spec_doc_version` — for automatic selection, filters to rows with
|
|
628
629
|
a non-empty `.zip` URL, then applies numeric sort on `SpecVersion.version`
|
|
629
630
|
(segment-wise ints, non-numeric → 0); optional `release` filters before
|
|
630
|
-
|
|
631
|
+
selection. When both `release` and `version` are supplied, their release
|
|
632
|
+
numbers must agree (for example, `Rel-18` with `18.5.0`). An explicit
|
|
633
|
+
`version` is strict and raises
|
|
631
634
|
`SpecDocUnknownVersionError` if its ZIP link is missing. A miss raises
|
|
632
635
|
`SpecDocUnknownSpecError` (no
|
|
633
636
|
`spec_versions` rows — run `spec sync --spec-id` first) or
|
|
@@ -1093,8 +1096,8 @@ the `spec doc` / `toc` / `search` triplet, 40 commands) plus the `server` group
|
|
|
1093
1096
|
- `sync` — `--tsg`
|
|
1094
1097
|
- `list` — filters by `--tsg`, `--name`, `--acronym`, `--release`
|
|
1095
1098
|
- `spec doc` (nested under `spec` as `spec doc ...`):
|
|
1096
|
-
- `parse` —
|
|
1097
|
-
|
|
1099
|
+
- `parse` — exactly one `--spec` (required), `--release`, `--version`,
|
|
1100
|
+
`--force/-f`; resolves the numeric-newest or pinned
|
|
1098
1101
|
version, fetches the ZIP when missing, and records the download;
|
|
1099
1102
|
`--force` re-downloads and re-parses, including already-parsed pairs.
|
|
1100
1103
|
Also accepts `--format/--output/--compact` (currently ignored); prints
|
|
@@ -1269,18 +1269,23 @@ Options:
|
|
|
1269
1269
|
detected: a file is parsed as a single source, a directory is
|
|
1270
1270
|
processed as a batch. The cache and database are never touched for
|
|
1271
1271
|
local files.
|
|
1272
|
-
- `--from-url URL`: download the URL
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1272
|
+
- `--from-url URL`: download the URL and parse it. For the canonical
|
|
1273
|
+
3GPP FTP site, only HTTPS URLs under
|
|
1274
|
+
`https://www.3gpp.org/ftp/...` are accepted; the bare form
|
|
1275
|
+
`www.3gpp.org/ftp/...` is also accepted and normalized to HTTPS,
|
|
1276
|
+
while an explicit `http://www.3gpp.org/ftp/...` URL is rejected.
|
|
1277
|
+
A canonical `.docx` or `.zip` file must have a TDoc-shaped basename
|
|
1278
|
+
(including plenary ids such as `RP-2601234`); a spec archive such as
|
|
1279
|
+
`36508-j31.zip` is rejected. Every other canonical 3GPP path is
|
|
1280
|
+
treated as a folder, and its trailing slash is optional. Canonical
|
|
1281
|
+
single files are parsed directly; folders are processed as batches.
|
|
1282
|
+
Canonical 3GPP results are cached on disk and written to
|
|
1283
|
+
`tdoc_extracts` + `tdoc_cr_cover_page` (and to
|
|
1276
1284
|
`tdoc_cr_ttcn_details` when the parser produced a TTCN sidecar —
|
|
1277
|
-
subject to the FK matrix below)
|
|
1278
|
-
in-memory
|
|
1279
|
-
`file://`) are rejected — download out of band and
|
|
1280
|
-
`--from-path` instead.
|
|
1281
|
-
FTP folder and processed as a batch; URLs ending in `.docx`/`.zip`
|
|
1282
|
-
are treated as single files;
|
|
1283
|
-
ambiguous URLs are probed once and routed accordingly.
|
|
1285
|
+
subject to the FK matrix below). Other HTTP(S) URLs retain the
|
|
1286
|
+
existing in-memory parsing behavior. Schemes other than `http(s)`
|
|
1287
|
+
(e.g. `ftp://`, `file://`) are rejected — download out of band and
|
|
1288
|
+
use `--from-path` instead.
|
|
1284
1289
|
- `--format {table,markdown,json,raw}`: output format. Default
|
|
1285
1290
|
`table` (tab-separated header + single data row, matching
|
|
1286
1291
|
`tdoc list --format table`). `markdown` writes a single-row GFM
|
|
@@ -1379,7 +1384,7 @@ FK-aware behaviour matrix (3GPP URL):
|
|
|
1379
1384
|
|---|---|---|---|---|---|---|
|
|
1380
1385
|
| `tdoc_id ∈ tdocs` (extracted from filename) | yes | yes | yes (skipped when `--format raw`) | yes — only when the parser emitted a TTCN sidecar (i.e. `is_ttcn_tdoc(tdoc_id)` and the document contained a TTCN overview / corrections section) | always | no |
|
|
1381
1386
|
| `tdoc_id ∉ tdocs` (extracted but no FK target) | no | no | no | no | always | yes — actionable `meeting sync --tsg R5` recipe |
|
|
1382
|
-
|
|
|
1387
|
+
| Canonical `.docx`/`.zip` basename has no `tdoc_id` pattern | no | no | no | no | no — rejected at the URL boundary | yes — validation error mentioning TDoc |
|
|
1383
1388
|
|
|
1384
1389
|
Local files and non-3GPP URLs always emit output and never touch
|
|
1385
1390
|
the cache or the database.
|
|
@@ -1390,13 +1395,14 @@ the URL **before** dispatching to the parse helpers, then fires
|
|
|
1390
1395
|
`trigger_auto_sync(...)` with the candidate set:
|
|
1391
1396
|
|
|
1392
1397
|
- **3GPP FTP file URL** (`.docx` / `.zip` suffix) → one candidate parsed
|
|
1393
|
-
out of the basename via
|
|
1394
|
-
|
|
1395
|
-
- **3GPP FTP folder URL** (trailing `/`) → BFS via
|
|
1398
|
+
out of the TDoc-shaped basename via
|
|
1399
|
+
`extract_tdoc_id_from_filename()`.
|
|
1400
|
+
- **3GPP FTP folder URL** (trailing `/` optional) → BFS via
|
|
1396
1401
|
`TDocCrService.collect_3gpp_file_urls()` (up to `--max-depth` /
|
|
1397
1402
|
`--recursive`), then extract `tdoc_id`s per file. Empty when BFS
|
|
1398
1403
|
fails (warning only — the parse still proceeds).
|
|
1399
|
-
- **
|
|
1404
|
+
- **Other canonical 3GPP paths** → treated as folders, including paths
|
|
1405
|
+
without a trailing `/`.
|
|
1400
1406
|
- **Non-3GPP URL** → empty. The CLI gates the call on
|
|
1401
1407
|
`is_3gpp_ftp_url()` so non-3GPP URLs never trigger the candidate
|
|
1402
1408
|
helper.
|
|
@@ -2415,12 +2421,12 @@ strict and fails clearly if that version has no ZIP link. Run
|
|
|
2415
2421
|
|
|
2416
2422
|
Purpose:
|
|
2417
2423
|
|
|
2418
|
-
- Fetch-if-missing, convert, chunk, and index one
|
|
2419
|
-
`
|
|
2424
|
+
- Fetch-if-missing, convert, chunk, and index one spec; prints one `ok`,
|
|
2425
|
+
`skipped <reason>`, or `failed <reason>` (stderr) line.
|
|
2420
2426
|
|
|
2421
2427
|
Options:
|
|
2422
2428
|
|
|
2423
|
-
- --spec: spec id to parse;
|
|
2429
|
+
- --spec: spec id to parse; exactly one is required.
|
|
2424
2430
|
- --release: release marker, e.g. `Rel-18`. Optional pin.
|
|
2425
2431
|
- --version: exact version, e.g. `18.5.0`. Optional pin.
|
|
2426
2432
|
- --force, -f: re-download and re-parse the resolved version, including
|
|
@@ -2439,11 +2445,12 @@ Behavior:
|
|
|
2439
2445
|
`spec_doc_sources.downloaded_at` before conversion.
|
|
2440
2446
|
- `--force` re-downloads the resolved ZIP and then re-parses it, including when
|
|
2441
2447
|
the `(spec_id, version)` pair already has `parsed_at`.
|
|
2442
|
-
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
(`
|
|
2448
|
+
- The `(spec_id, version)` source row is skipped when it already carries
|
|
2449
|
+
`parsed_at` (unless `--force`); oversized zips land in the `skipped` bucket;
|
|
2450
|
+
unknown spec/version, empty (no-`.docx`) zips, and every other error land in
|
|
2451
|
+
the `failures` bucket. When both `--release` and `--version` are supplied,
|
|
2452
|
+
their release numbers must agree (for example, `Rel-18` requires a version
|
|
2453
|
+
beginning with `18.`).
|
|
2447
2454
|
- `parse` = fetch-if-missing + `list_spec_docx` (`.doc` entries warn-skip) +
|
|
2448
2455
|
`convert_document_to_blocks` + `order_spec_files` (front-matter TOC file first,
|
|
2449
2456
|
then section-tuple sort, TOC tiebreak, unnumbered lexicographic tail) +
|
|
@@ -2468,8 +2475,8 @@ Examples:
|
|
|
2468
2475
|
# Parse the newest version of 38.331 with a published ZIP download link.
|
|
2469
2476
|
doc3gpp spec doc parse --spec 38.331
|
|
2470
2477
|
|
|
2471
|
-
# Parse
|
|
2472
|
-
doc3gpp spec doc parse --spec 38.331 --
|
|
2478
|
+
# Parse one spec at a pinned release and version.
|
|
2479
|
+
doc3gpp spec doc parse --spec 38.331 --release Rel-18 --version 18.5.0
|
|
2473
2480
|
|
|
2474
2481
|
# Re-parse even when already parsed.
|
|
2475
2482
|
doc3gpp spec doc parse --spec 38.331 --force
|
|
@@ -115,7 +115,7 @@ table below is for navigation only.
|
|
|
115
115
|
| `list_spec_docx` / `order_spec_files` / `extract_spec_toc` | functions | `parsers/spec_doc.py` | List `.docx` zip members, order split spec files by first section/TOC rules while preserving alphanumeric identifiers such as `7.2A.3A`, and build the ordered TOC/file map. |
|
|
116
116
|
| `chunk_blocks` | function | `parsers/spec_doc_chunker.py` | Pure paragraph/sentence/table-row chunker using semantic token budgets plus the spec-doc character ceiling; carries newline-delimited combined `sections` / `tables` and source-file metadata. |
|
|
117
117
|
| `parse_cr_details` | function | `parsers/cr_parser.py` | Markdown → `TDocCRDetails` (cover-page, optional TTCN overview, optional corrections). |
|
|
118
|
-
| `is_3gpp_ftp_url` / `direct_parse_bytes` / `derive_zip_cache_key` / `extract_tdoc_id_from_filename` | functions | `parsers/direct_extractor.py` | Helpers for the `tdoc parse --from-path/--from-url` direct path.
|
|
118
|
+
| `is_3gpp_ftp_url` / `normalize_3gpp_ftp_url` / `validate_tdoc_ftp_url` / `direct_parse_bytes` / `derive_zip_cache_key` / `extract_tdoc_id_from_filename` | functions | `parsers/direct_extractor.py` | Helpers for the `tdoc parse --from-path/--from-url` direct path. The URL normalizer/validator is the shared HTTPS canonical-site, file-vs-folder, and TDoc-basename policy; `direct_parse_bytes` glues docx conversion + cover-page parsing. |
|
|
119
119
|
| `TDocParser` Protocol / `TDocParserRegistry` / `build_default_registry` | Protocol / class / function | `parsers/tdoc_parsers.py` | `TDocParser.parse()` returns a `TDocCRParseResult` (cover + optional TTCN sidecar). `build_default_registry` registers `TTCNCRParser` before the generic `CRParser` so TTCN CRs route to the overview + corrections parser and everything else falls through. |
|
|
120
120
|
| `CRParserBase` / `CRParser` / `TTCNCRParser` | classes | `parsers/cr/cr_parsers.py` | Concrete parser implementations. `CRParserBase.parse()` returns `TDocCRParseResult`; `TTCNCRParser` populates the sidecar from the TTCN overview + corrections section payloads; `CRParser` always emits `ttcn=None`. |
|
|
121
121
|
| `ttcn_functions` module | module | `parsers/cr/ttcn_functions.py` | Regex-driven helpers for the `tdoc_cr_ttcn_details.changed_functions` aggregate: `extract_module_basename` (handles Unix paths, Windows paths, bare basenames), `extract_function_name` (matches `f_`/`fl_`/`fx_`/`a_`/`tsc_`/`cs_`/`cr_`/`crs_`/`cas_`/`car_`/`cds_`/`cdr_`/`cms_`/`cmr_`/`cads_` prefixes with a `*_type` fallback), and the thin aggregator `extract_changed_functions` that returns a sorted, deduplicated `list[str]` of `"<module_basename>.<function_name>"` entries derived from `required_changes`. Partial-extraction markers (`"<module>."` trailing-dot, `".<function>"` leading-dot) cover the cases where one regex returns `None`; entries where both regexes return `None` are dropped. Consumed by `CRParserBase.parse()` when building the `TDocCRTTCNDetails` sidecar. |
|
|
@@ -206,17 +206,16 @@ the target is missing or not `X-Doc3gpp-Managed` by doc3gpp.
|
|
|
206
206
|
| POST | `/jobs/tdocs/index` | Enqueue unified TDoc FTS5/vector index maintenance. |
|
|
207
207
|
| POST | `/jobs/spec-docs/index` | Enqueue unified spec-doc FTS5/vector index maintenance. |
|
|
208
208
|
| POST | `/jobs/cache/purge` | Enqueue `cache_purge` (requires `yes: true`). |
|
|
209
|
-
| POST | `/jobs/parse/tdoc-url` | Enqueue `parse_tdoc_url` (a single
|
|
210
|
-
| POST | `/jobs/parse/spec-docs` | Enqueue `parse_spec_docs` for one
|
|
209
|
+
| POST | `/jobs/parse/tdoc-url` | Enqueue `parse_tdoc_url` (a single TDoc file or folder on the canonical 3GPP FTP site; accepts HTTPS `https://www.3gpp.org/ftp/...` or bare `www.3gpp.org/ftp/...`, normalizes the latter, rejects explicit HTTP and non-TDoc spec archives, and permits an optional folder trailing slash; `recursive` XOR `max_depth`). |
|
|
210
|
+
| POST | `/jobs/parse/spec-docs` | Enqueue `parse_spec_docs` for one spec id (`spec_id`, optional `release`, `version`, and `force`); progress is streamed through the normal job SSE endpoint. This job is intentionally not a panel on the eleven-form `/sync` hub. |
|
|
211
211
|
| POST | `/jobs/{id}/cancel` | Cancel a queued/running job. Accepts `?format=html` to return the refreshed job row as an `outerHTML` swap target for the list page's per-row Cancel button. JSON otherwise. |
|
|
212
212
|
| POST | `/jobs/sync_tdocs` | Flat alias for `sync_tdocs` (form or JSON). |
|
|
213
213
|
| GET | `/sync` | Sync hub page: eleven enqueue forms (meetings, tdocs, all-tdocs, specs-by-tsg, specs-by-id, parse-tdocs, parse-tdoc-url, TDoc index maintenance, spec-document index maintenance, cache-purge, testcases) + a "Recent sync jobs" table. |
|
|
214
214
|
| GET | `/sync?format=fragment` | Recent-jobs table fragment (wrapped in `<div id="recent-jobs">`) for HTMX `outerHTML` swap. |
|
|
215
215
|
|
|
216
|
-
`parse_spec_docs` records
|
|
217
|
-
job log.
|
|
218
|
-
|
|
219
|
-
in the result.
|
|
216
|
+
`parse_spec_docs` records the spec error in `result.failure_details` and the
|
|
217
|
+
job log. A failed parse job has a populated `error` and result; a successful or
|
|
218
|
+
skipped parse reports its corresponding one-spec result.
|
|
220
219
|
|
|
221
220
|
Append `?format=json` to any list/detail route to get the CLI-equivalent
|
|
222
221
|
JSON. Append `?format=html` (or omit) for the browsable HTML view.
|
|
@@ -279,8 +278,8 @@ specdata source row has not been downloaded or parsed; a downloaded source is
|
|
|
279
278
|
waiting for parsing; and a parsed source shows its parse timestamp, DOCX and
|
|
280
279
|
chunk counts. The only document action is `Parse document` (or `Force
|
|
281
280
|
re-parse`, available only for a parsed source. It enqueues the existing
|
|
282
|
-
`POST /jobs/parse/spec-docs` job with `
|
|
283
|
-
and `force`, then
|
|
281
|
+
`POST /jobs/parse/spec-docs` job with scalar `spec_id`, the selected exact
|
|
282
|
+
`version`, and `force`, then
|
|
284
283
|
polls the normal job status. The parser downloads a missing ZIP internally;
|
|
285
284
|
there is intentionally no standalone spec-document fetch route or fetch
|
|
286
285
|
control.
|
|
@@ -530,8 +529,8 @@ The spec-document tools use the separate specdata database. `get_spec_toc`
|
|
|
530
529
|
reads one parsed `(spec_id, version)` TOC, `search_spec_docs` selects among
|
|
531
530
|
FTS5, vector, hybrid, and filter-only chunk search, and `get_spec_doc_index`
|
|
532
531
|
reports index status. `parse_spec_docs` enqueues the same
|
|
533
|
-
`PARSE_SPEC_DOCS` job as `POST /jobs/parse/spec-docs`; it accepts
|
|
534
|
-
`
|
|
532
|
+
`PARSE_SPEC_DOCS` job as `POST /jobs/parse/spec-docs`; it accepts one
|
|
533
|
+
`spec_id`, optional `release`/`version`, and `force`.
|
|
535
534
|
|
|
536
535
|
The MCP `serverInfo` block returned on every `initialize` handshake carries `name` ("doc3gpp"), `version` (from `importlib.metadata.version("doc3gpp")`, falling back to `doc3gpp.__version__`), `title`, `description`, and `website_url`. Clients do not need a tool call to read the version.
|
|
537
536
|
|
|
@@ -7,7 +7,7 @@ allow-direct-references = true
|
|
|
7
7
|
|
|
8
8
|
[project]
|
|
9
9
|
name = "doc3gpp"
|
|
10
|
-
version = "0.3.
|
|
10
|
+
version = "0.3.4"
|
|
11
11
|
description = "Provide 3GPP TDoc information with full text search capability — a Python CLI/library, a local web UI, and an MCP server for AI clients."
|
|
12
12
|
readme = "README.md"
|
|
13
13
|
requires-python = ">=3.10"
|
|
@@ -30,13 +30,15 @@ from doc3gpp.cli_server import server_app
|
|
|
30
30
|
from doc3gpp.cli_url_helpers import (
|
|
31
31
|
_looks_like_3gpp_file_url,
|
|
32
32
|
_looks_like_3gpp_folder_url,
|
|
33
|
+
is_3gpp_ftp_candidate_url,
|
|
33
34
|
is_3gpp_ftp_url,
|
|
35
|
+
validate_tdoc_ftp_url,
|
|
34
36
|
)
|
|
35
37
|
from doc3gpp.config import get_settings
|
|
36
38
|
from doc3gpp.models.meeting import Meeting
|
|
37
39
|
from doc3gpp.models.schema_info import SCHEMA_FIELDS, schema_payload
|
|
38
40
|
from doc3gpp.models.spec import Spec, SpecVersion
|
|
39
|
-
from doc3gpp.models.spec_doc import SpecDocSearchFilters
|
|
41
|
+
from doc3gpp.models.spec_doc import SpecDocSearchFilters, SpecDocSelectionError
|
|
40
42
|
from doc3gpp.models.sync import BulkSyncOutcome, SyncOutcome
|
|
41
43
|
from doc3gpp.models.tdoc import TDoc, TDocWithMeeting
|
|
42
44
|
from doc3gpp.models.tdoc_cr import (
|
|
@@ -55,6 +57,7 @@ from doc3gpp.parsers.docx_converter import PythonDocxNotInstalledError
|
|
|
55
57
|
from doc3gpp.parsers.normalizers import normalize_ftp_path
|
|
56
58
|
from doc3gpp.scraping.cache import CacheStatus, TDocCache
|
|
57
59
|
from doc3gpp.scraping.cache_keys import derive_cache_file
|
|
60
|
+
from doc3gpp.scraping.spec_doc_source import validate_release_version_alignment
|
|
58
61
|
from doc3gpp.scraping.tdoc_zip_source import canonicalise_tdoc_id
|
|
59
62
|
from doc3gpp.services.factory import (
|
|
60
63
|
build_meeting_service,
|
|
@@ -2237,6 +2240,11 @@ def tdoc_parse(
|
|
|
2237
2240
|
f"--from-path is neither a file nor a directory: {from_path}"
|
|
2238
2241
|
)
|
|
2239
2242
|
else:
|
|
2243
|
+
if is_3gpp_ftp_candidate_url(from_url):
|
|
2244
|
+
try:
|
|
2245
|
+
from_url = validate_tdoc_ftp_url(from_url)
|
|
2246
|
+
except ValueError as exc:
|
|
2247
|
+
raise typer.BadParameter(str(exc)) from exc
|
|
2240
2248
|
effective_depth = _resolve_url_batch_depth(
|
|
2241
2249
|
recursive=recursive,
|
|
2242
2250
|
max_depth=max_depth,
|
|
@@ -5132,7 +5140,7 @@ def spec_doc_parse(
|
|
|
5132
5140
|
spec: list[str] | None = typer.Option( # noqa: B008 - Typer option declaration
|
|
5133
5141
|
None,
|
|
5134
5142
|
"--spec",
|
|
5135
|
-
help="Spec id to parse
|
|
5143
|
+
help="Spec id to parse (exactly one required).",
|
|
5136
5144
|
),
|
|
5137
5145
|
release: str | None = typer.Option(
|
|
5138
5146
|
None, "--release", help="Release marker, e.g. Rel-18.",
|
|
@@ -5160,10 +5168,16 @@ def spec_doc_parse(
|
|
|
5160
5168
|
help="Strip output formatting: JSON drops indent and operator-space. No-op for ``table``.",
|
|
5161
5169
|
),
|
|
5162
5170
|
) -> None:
|
|
5163
|
-
"""
|
|
5171
|
+
"""Parse one spec; print its success/skip/failure result."""
|
|
5164
5172
|
create_schema("all")
|
|
5165
5173
|
if not spec:
|
|
5166
|
-
raise typer.BadParameter("pass
|
|
5174
|
+
raise typer.BadParameter("pass exactly one --spec <id>")
|
|
5175
|
+
if len(spec) != 1:
|
|
5176
|
+
raise typer.BadParameter("--spec may be provided only once")
|
|
5177
|
+
try:
|
|
5178
|
+
validate_release_version_alignment(release, version)
|
|
5179
|
+
except SpecDocSelectionError as exc:
|
|
5180
|
+
raise typer.BadParameter(str(exc)) from exc
|
|
5167
5181
|
svc = build_spec_doc_service()
|
|
5168
5182
|
result = svc.parse_many(spec, release=release, version=version, force=force)
|
|
5169
5183
|
for sid in result.successes:
|
|
@@ -19,8 +19,8 @@ from typing import TYPE_CHECKING
|
|
|
19
19
|
from doc3gpp.cli_filters import parse_tdoc_id
|
|
20
20
|
from doc3gpp.cli_url_helpers import (
|
|
21
21
|
_looks_like_3gpp_file_url,
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
is_3gpp_ftp_candidate_url,
|
|
23
|
+
validate_tdoc_ftp_url,
|
|
24
24
|
)
|
|
25
25
|
from doc3gpp.models.meeting import Meeting
|
|
26
26
|
from doc3gpp.parsers.direct_extractor import (
|
|
@@ -38,7 +38,7 @@ if TYPE_CHECKING:
|
|
|
38
38
|
|
|
39
39
|
logger = logging.getLogger(__name__)
|
|
40
40
|
|
|
41
|
-
_TSG_PREFIX_RE = re.compile(r"^([RSC][1-
|
|
41
|
+
_TSG_PREFIX_RE = re.compile(r"^([RSC][1-9P])", re.IGNORECASE)
|
|
42
42
|
|
|
43
43
|
|
|
44
44
|
def _build_meeting_url(tsg: str, ext: str = "htm") -> str:
|
|
@@ -176,7 +176,7 @@ def sync_meeting_internal(
|
|
|
176
176
|
def collect_tdoc_candidates_for_url(
|
|
177
177
|
url: str,
|
|
178
178
|
*,
|
|
179
|
-
tdoc_service:
|
|
179
|
+
tdoc_service: TDocCrService | None = None,
|
|
180
180
|
max_depth: int = 0,
|
|
181
181
|
) -> set[str]:
|
|
182
182
|
"""Return distinct tdoc_ids implied by ``url``.
|
|
@@ -188,12 +188,12 @@ def collect_tdoc_candidates_for_url(
|
|
|
188
188
|
- 3GPP FTP file URL (ends with ``.docx`` / ``.zip``) → the tdoc_id
|
|
189
189
|
parsed out of the basename, or empty if the basename has no
|
|
190
190
|
recognised TDoc-id pattern.
|
|
191
|
-
- 3GPP FTP folder URL (
|
|
192
|
-
``max_depth`` via the supplied service and extract tdoc_ids
|
|
193
|
-
each file's basename. Returns empty when ``tdoc_service`` is
|
|
191
|
+
- 3GPP FTP folder URL (trailing ``/`` optional) → BFS over the folder
|
|
192
|
+
up to ``max_depth`` via the supplied service and extract tdoc_ids
|
|
193
|
+
from each file's basename. Returns empty when ``tdoc_service`` is
|
|
194
194
|
``None`` (the helper is a pure no-op in that case).
|
|
195
|
-
-
|
|
196
|
-
|
|
195
|
+
- Any other canonical 3GPP FTP path → treat it as a folder and scan
|
|
196
|
+
breadth-first using the supplied service.
|
|
197
197
|
|
|
198
198
|
Network or BFS failures are logged at ``WARNING`` and the helper
|
|
199
199
|
returns whatever candidates were already collected — it never raises
|
|
@@ -215,7 +215,12 @@ def collect_tdoc_candidates_for_url(
|
|
|
215
215
|
failure mode.
|
|
216
216
|
"""
|
|
217
217
|
candidates: set[str] = set()
|
|
218
|
-
if not
|
|
218
|
+
if not is_3gpp_ftp_candidate_url(url):
|
|
219
|
+
return candidates
|
|
220
|
+
try:
|
|
221
|
+
url = validate_tdoc_ftp_url(url)
|
|
222
|
+
except ValueError as exc:
|
|
223
|
+
logger.warning("Auto-sync candidate collection rejected %s: %s", url, exc)
|
|
219
224
|
return candidates
|
|
220
225
|
|
|
221
226
|
if _looks_like_3gpp_file_url(url):
|
|
@@ -224,18 +229,12 @@ def collect_tdoc_candidates_for_url(
|
|
|
224
229
|
candidates.add(extracted)
|
|
225
230
|
return candidates
|
|
226
231
|
|
|
227
|
-
|
|
228
|
-
return _collect_from_3gpp_folder(url, tdoc_service, max_depth)
|
|
229
|
-
|
|
230
|
-
extracted = extract_tdoc_id_from_filename(url)
|
|
231
|
-
if extracted is not None:
|
|
232
|
-
candidates.add(extracted)
|
|
233
|
-
return candidates
|
|
232
|
+
return _collect_from_3gpp_folder(url, tdoc_service, max_depth)
|
|
234
233
|
|
|
235
234
|
|
|
236
235
|
def _collect_from_3gpp_folder(
|
|
237
236
|
url: str,
|
|
238
|
-
tdoc_service:
|
|
237
|
+
tdoc_service: TDocCrService | None,
|
|
239
238
|
max_depth: int,
|
|
240
239
|
) -> set[str]:
|
|
241
240
|
"""BFS-collect tdoc_ids from a 3GPP FTP folder URL; empty on any failure."""
|
|
@@ -67,13 +67,13 @@ DATE_FILTER_RE = re.compile(
|
|
|
67
67
|
)
|
|
68
68
|
|
|
69
69
|
|
|
70
|
-
# CR-shape TDoc identifier: ``[RSC][1-
|
|
71
|
-
# initial (R/S/C), non-zero TSG digit, shape marker (- / s / w for
|
|
70
|
+
# CR-shape TDoc identifier: ``[RSC][1-9P][-sw]\d{6,7}`` — TSG group
|
|
71
|
+
# initial (R/S/C), non-zero TSG digit or plenary marker P, shape marker (- / s / w for
|
|
72
72
|
# canonical / TTCN / workshop), 6- or 7-digit sequence number.
|
|
73
73
|
# 3GPP RAN4 has used 7-digit numbers since 2016 (e.g. ``R4-2607922``);
|
|
74
74
|
# every other working group is still on 6 digits. Do not narrow without
|
|
75
75
|
# re-checking the RAN4 DynaReport.
|
|
76
|
-
TDOC_ID_RE = re.compile(r"[RSC][1-
|
|
76
|
+
TDOC_ID_RE = re.compile(r"[RSC][1-9P][-sw]\d{6,7}", re.IGNORECASE)
|
|
77
77
|
|
|
78
78
|
|
|
79
79
|
def is_null_token(value: str) -> bool:
|
|
@@ -142,8 +142,9 @@ def parse_tdoc_id(value: str) -> tuple[str, int]:
|
|
|
142
142
|
raise ValueError(
|
|
143
143
|
f"Invalid TDoc id {value!r}. Expected a 9- or 10-character "
|
|
144
144
|
f"CR-shape id like 'R5-260013', 'R5s260009', 'R5w260013', or "
|
|
145
|
-
f"'R4-2607922' — TSG group initial (R/S/C),
|
|
146
|
-
f"
|
|
145
|
+
f"'R4-2607922' or 'RP-2601234' — TSG group initial (R/S/C), "
|
|
146
|
+
f"non-zero TSG digit or plenary marker P, shape marker "
|
|
147
|
+
f"(-/s/w), then 6 or 7 decimal digits."
|
|
147
148
|
)
|
|
148
149
|
return stripped[:3], int(stripped[3:])
|
|
149
150
|
|
|
@@ -360,4 +361,4 @@ class SearchQueryBuilder:
|
|
|
360
361
|
out.append("\\" + ch)
|
|
361
362
|
else:
|
|
362
363
|
out.append(ch)
|
|
363
|
-
return "".join(out)
|
|
364
|
+
return "".join(out)
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
The CLI's ``--from-url`` direct-parse path needs a tiny set of
|
|
4
4
|
predicate functions to decide whether a URL points at a 3GPP FTP
|
|
5
|
-
asset, whether it ends in a known file extension, and whether it
|
|
6
|
-
|
|
5
|
+
asset, whether it ends in a known file extension, and whether it is a
|
|
6
|
+
folder path (with or without a trailing slash). The same predicates are
|
|
7
7
|
needed from :mod:`doc3gpp.cli_auto_sync` so the auto-sync helper can
|
|
8
8
|
derive TDoc-id candidates from a URL without dragging the full
|
|
9
9
|
parser module into its import surface.
|
|
@@ -16,26 +16,36 @@ import one consistent set of names:
|
|
|
16
16
|
parser implementation stays in one place.
|
|
17
17
|
* :func:`_looks_like_3gpp_file_url` — true when the URL ends with a
|
|
18
18
|
known document extension.
|
|
19
|
-
* :func:`_looks_like_3gpp_folder_url` — true
|
|
20
|
-
|
|
19
|
+
* :func:`_looks_like_3gpp_folder_url` — true for any other canonical
|
|
20
|
+
3GPP FTP path.
|
|
21
21
|
"""
|
|
22
22
|
|
|
23
23
|
from __future__ import annotations
|
|
24
24
|
|
|
25
|
-
from doc3gpp.parsers.direct_extractor import
|
|
25
|
+
from doc3gpp.parsers.direct_extractor import (
|
|
26
|
+
is_3gpp_file_url,
|
|
27
|
+
is_3gpp_ftp_candidate_url,
|
|
28
|
+
is_3gpp_ftp_url,
|
|
29
|
+
normalize_3gpp_ftp_url,
|
|
30
|
+
validate_tdoc_ftp_url,
|
|
31
|
+
)
|
|
26
32
|
|
|
27
33
|
__all__ = [
|
|
28
34
|
"_looks_like_3gpp_file_url",
|
|
29
35
|
"_looks_like_3gpp_folder_url",
|
|
36
|
+
"is_3gpp_file_url",
|
|
37
|
+
"is_3gpp_ftp_candidate_url",
|
|
30
38
|
"is_3gpp_ftp_url",
|
|
39
|
+
"normalize_3gpp_ftp_url",
|
|
40
|
+
"validate_tdoc_ftp_url",
|
|
31
41
|
]
|
|
32
42
|
|
|
33
43
|
|
|
34
44
|
def _looks_like_3gpp_folder_url(url: str) -> bool:
|
|
35
|
-
"""Return ``True``
|
|
36
|
-
return url
|
|
45
|
+
"""Return ``True`` for a canonical non-file FTP path."""
|
|
46
|
+
return is_3gpp_ftp_url(url) and not is_3gpp_file_url(url)
|
|
37
47
|
|
|
38
48
|
|
|
39
49
|
def _looks_like_3gpp_file_url(url: str) -> bool:
|
|
40
|
-
"""Return ``True`` when
|
|
41
|
-
return url
|
|
50
|
+
"""Return ``True`` when a canonical URL ends with a known extension."""
|
|
51
|
+
return is_3gpp_file_url(url)
|
|
@@ -20,7 +20,7 @@ Read tools return a single text item containing JSON (except `get_tdoc_content`,
|
|
|
20
20
|
| Meeting calendar | `list_meetings` with `tsg`, `name`, or `year`; `get_meeting` with numeric `meeting_id` | `sync_meetings({"tsg":"R5"})` fetches and parses that TSG's calendar | Re-list, then use `get_meeting` to obtain its meeting ID and FTP URL. There is no separate meeting-parse tool. |
|
|
21
21
|
| Meeting TDocs | `list_tdocs` with `meeting_id`, `tdoc_id`, `title`, `spec`, etc.; `get_tdoc` with `tdoc_id` or `ftp_url` | `sync_tdocs({"meeting_id":260013})` after the meeting exists; alternatively `sync_tdocs_by_meeting({"meeting":"RAN5#106"})`. For document extraction, `parse_tdocs({"filter":{"tdoc_id":"R5-260013"}})`; for a direct 3GPP FTP URL use `parse_tdoc_url({"url":"https://www.3gpp.org/ftp/..."})`. | `get_tdoc` for cover/extract metadata; `get_tdoc_content({"tdoc_id":"R5-260013"})` for cached markdown if available; `search_tdoc` for indexed content and filters. |
|
|
22
22
|
| Specifications | `list_specs` with `tsg`, `spec_id`, `title`, or `parsed`; `get_spec` with dotted `spec_id` | `sync_specs({"tsg":"R5"})` or `sync_specs({"spec_id":"38.331"})` (exactly one selector). `force` bypasses the sync interval; `per_version_details` fetches extra PDF/CR-list details. | `get_spec` returns versions, release markers, ZIP URLs, and per-version `parsed` state. Paginate versions with `limit`/`offset` if needed. |
|
|
23
|
-
| Specification documents | Start with `get_spec` to identify a version with a ZIP URL; `get_spec_toc` needs an already parsed exact `(spec_id, version)` | `parse_spec_docs({"
|
|
23
|
+
| Specification documents | Start with `get_spec` to identify a version with a ZIP URL; `get_spec_toc` needs an already parsed exact `(spec_id, version)` | `parse_spec_docs({"spec_id":"38.331","version":"18.5.0"})` downloads if needed and parses one spec; omit `version` to resolve a suitable stored version (optionally constrain with `release`). When both `release` and `version` are supplied, their release numbers must align, e.g. `Rel-18` with `18.5.0`. `force` re-downloads and re-parses. | `get_spec_toc({"spec_id":"38.331","version":"18.5.0"})`; `search_spec_docs` with `spec_id`, `version`, `text` or `semantic`, `sections`, `tables`. Note '%' wildcards to match section / table titles to improve search. If search section numbers or table numbers, use '%' at the end to match sub-sections or sub-tables. e.g. `"section":"5.3.2%"` or `"table":"6.1.1.2.3-%"`. |
|
|
24
24
|
| RAN5 testcases | `list_testcases` with `testcase` (ID pattern), `title`, `spec`, `group`, `status` (TTCN), or `gcf_status` (GCF/PTCRB) | `sync_testcases({})` fetches and parses the latest RAN5 status snapshot in one job; `{"force":true}` re-downloads and re-parses a snapshot already recorded. No separate testcase parse tool. | `get_testcase({"testcase_id":"<id>"})` returns all stored groups; pass `group` for one group. Each result has nested `statuses` entries containing `path`, `gcf_ptcrb`, and `ttcn_status`. |
|
|
25
25
|
|
|
26
26
|
Filters on list/search tools generally accept SQL-LIKE `%` wildcards (for example `title:"%handover%"`); plain values match exactly. Testcase `group` is an exact match: `5G`, `LTE`, `IMS`, `UTRA`, `POS`, or `MCX`. `list_meetings`, `list_tdocs`, `list_specs`, and `list_testcases` default to 50 rows: use `limit` and `offset` to page. `search_tdoc` and `search_spec_docs` select FTS5 with `text`, vector search with `semantic`, hybrid with both, and filter-only with neither. Semantic search requires its configured embedding service. If text search reports an unavailable or corrupt index, inspect `get_tdoc_index` or `get_spec_doc_index`; use `index_tdocs({"rebuild":true})` or `index_spec_docs({"rebuild":true})` when rebuilding is needed, then poll that job. Parse normally attempts automatic indexing, but indexing can fail independently.
|
|
@@ -44,7 +44,7 @@ search_tdoc {"text":"handover","meeting_id":<meeting_id>}
|
|
|
44
44
|
sync_specs {"spec_id":"38.331"}
|
|
45
45
|
get_job {"job_id":"<spec-sync job_id>"} # poll until terminal
|
|
46
46
|
get_spec {"spec_id":"38.331"}
|
|
47
|
-
parse_spec_docs {"
|
|
47
|
+
parse_spec_docs {"spec_id":"38.331","version":"<ZIP-backed version from get_spec>"}
|
|
48
48
|
get_job {"job_id":"<spec-doc-parse job_id>"} # poll until terminal
|
|
49
49
|
get_spec_toc {"spec_id":"38.331","version":"<parsed version>"}
|
|
50
50
|
search_spec_docs {"text":"handover","spec_id":"38.331","version":"<parsed version>", "sections":"5.2.2.3%"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"""DTOs for the spec-document corpus (separate specdata sqlite file)."""
|
|
2
2
|
from __future__ import annotations
|
|
3
|
+
|
|
3
4
|
from dataclasses import dataclass, field
|
|
4
5
|
from datetime import datetime
|
|
5
6
|
|
|
@@ -18,6 +19,10 @@ class SpecDocUnknownVersionError(SpecDocError):
|
|
|
18
19
|
self.available = available or []
|
|
19
20
|
|
|
20
21
|
|
|
22
|
+
class SpecDocSelectionError(SpecDocError):
|
|
23
|
+
"""Raised when a release/version selection is internally inconsistent."""
|
|
24
|
+
|
|
25
|
+
|
|
21
26
|
class SpecDocNoDocxError(SpecDocError):
|
|
22
27
|
pass
|
|
23
28
|
|
|
@@ -21,9 +21,10 @@ class CRHeaderMissingError(ValueError):
|
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
# Union: ``R5-227476`` (dash) AND ``R5s260009`` / ``R5w260176`` (single
|
|
24
|
-
# letter) AND ``C6-250028`` (dash)
|
|
24
|
+
# letter) AND ``C6-250028`` (dash), plenary ``RP-2601234`` IDs, and
|
|
25
|
+
# RAN4's 7-digit ``R4-2607922``.
|
|
25
26
|
# Matches in the document header near the top of the markdown.
|
|
26
|
-
_TDOC_HEADER_PATTERN = re.compile(r"([RSC][1-
|
|
27
|
+
_TDOC_HEADER_PATTERN = re.compile(r"([RSC][1-6P](?:[-sw])\d{6,7})", re.IGNORECASE)
|
|
27
28
|
# Email-meeting TTCN pattern. Overview / corrections are only parsed
|
|
28
29
|
# for TDocs matching this shape.
|
|
29
30
|
_TTCN_TDOC_PATTERN = re.compile(r"R5s\d{6}", re.IGNORECASE)
|