docorbit 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -15
- package/bin/docorbit.js +2 -2
- package/dist/apps/cli/src/commands/add.d.ts +7 -0
- package/dist/apps/cli/src/commands/add.js +35 -0
- package/dist/apps/cli/src/commands/api.d.ts +2 -0
- package/dist/apps/cli/src/commands/api.js +35 -0
- package/dist/apps/cli/src/commands/context.d.ts +10 -0
- package/dist/apps/cli/src/commands/context.js +36 -0
- package/dist/apps/cli/src/commands/dashboard.d.ts +8 -0
- package/dist/apps/cli/src/commands/dashboard.js +43 -0
- package/dist/apps/cli/src/commands/diff.d.ts +2 -0
- package/dist/apps/cli/src/commands/diff.js +29 -0
- package/dist/apps/cli/src/commands/evaluate.d.ts +11 -0
- package/dist/apps/cli/src/commands/evaluate.js +101 -0
- package/dist/apps/cli/src/commands/examples.d.ts +2 -0
- package/dist/apps/cli/src/commands/examples.js +36 -0
- package/dist/apps/cli/src/commands/export.d.ts +11 -0
- package/dist/apps/cli/src/commands/export.js +72 -0
- package/dist/apps/cli/src/commands/impact.d.ts +2 -0
- package/dist/apps/cli/src/commands/impact.js +30 -0
- package/dist/apps/cli/src/commands/init.d.ts +5 -0
- package/dist/apps/cli/src/commands/init.js +52 -0
- package/dist/apps/cli/src/commands/inspect.d.ts +5 -0
- package/dist/apps/cli/src/commands/inspect.js +24 -0
- package/dist/apps/cli/src/commands/mcp.d.ts +8 -0
- package/dist/apps/cli/src/commands/mcp.js +49 -0
- package/dist/apps/cli/src/commands/pitfalls.d.ts +2 -0
- package/dist/apps/cli/src/commands/pitfalls.js +35 -0
- package/dist/apps/cli/src/commands/recipes.d.ts +2 -0
- package/dist/apps/cli/src/commands/recipes.js +33 -0
- package/dist/apps/cli/src/commands/search.d.ts +11 -0
- package/dist/apps/cli/src/commands/search.js +36 -0
- package/dist/apps/cli/src/commands/update.d.ts +6 -0
- package/dist/apps/cli/src/commands/update.js +53 -0
- package/dist/apps/cli/src/commands/verify.d.ts +2 -0
- package/dist/apps/cli/src/commands/verify.js +44 -0
- package/dist/apps/cli/src/formatters/colors.d.ts +21 -0
- package/dist/apps/cli/src/formatters/colors.js +22 -0
- package/dist/apps/cli/src/formatters/inspection.d.ts +3 -0
- package/dist/apps/cli/src/formatters/inspection.js +88 -0
- package/dist/apps/cli/src/formatters/knowledge.d.ts +5 -0
- package/dist/apps/cli/src/formatters/knowledge.js +229 -0
- package/dist/apps/cli/src/formatters/retrieval.d.ts +3 -0
- package/dist/apps/cli/src/formatters/retrieval.js +61 -0
- package/{apps/cli/src/formatters/terminal.ts → dist/apps/cli/src/formatters/terminal.d.ts} +0 -1
- package/dist/apps/cli/src/formatters/terminal.js +5 -0
- package/dist/apps/cli/src/formatters/verification.d.ts +4 -0
- package/dist/apps/cli/src/formatters/verification.js +102 -0
- package/dist/apps/cli/src/index.d.ts +1 -0
- package/dist/apps/cli/src/index.js +376 -0
- package/dist/packages/core/src/dashboard/server.d.ts +33 -0
- package/dist/packages/core/src/dashboard/server.js +267 -0
- package/dist/packages/core/src/dashboard/ui.d.ts +5 -0
- package/{packages/core/src/dashboard/ui.ts → dist/packages/core/src/dashboard/ui.js} +2 -2
- package/dist/packages/core/src/implementation-service.d.ts +73 -0
- package/dist/packages/core/src/implementation-service.js +325 -0
- package/{packages/core/src/index.ts → dist/packages/core/src/index.d.ts} +0 -1
- package/dist/packages/core/src/index.js +6 -0
- package/dist/packages/core/src/inspector.d.ts +22 -0
- package/dist/packages/core/src/inspector.js +38 -0
- package/dist/packages/core/src/pipeline.d.ts +45 -0
- package/dist/packages/core/src/pipeline.js +246 -0
- package/dist/packages/crawler/src/config.d.ts +2 -0
- package/dist/packages/crawler/src/config.js +10 -0
- package/dist/packages/crawler/src/fetcher.d.ts +31 -0
- package/dist/packages/crawler/src/fetcher.js +139 -0
- package/dist/packages/crawler/src/index.js +2 -0
- package/dist/packages/discovery/src/index.d.ts +11 -0
- package/dist/packages/discovery/src/index.js +29 -0
- package/dist/packages/discovery/src/provider.d.ts +12 -0
- package/dist/packages/discovery/src/provider.js +30 -0
- package/dist/packages/discovery/src/providers/generic.d.ts +7 -0
- package/dist/packages/discovery/src/providers/generic.js +94 -0
- package/dist/packages/discovery/src/providers/github.d.ts +7 -0
- package/dist/packages/discovery/src/providers/github.js +52 -0
- package/dist/packages/discovery/src/providers/llms-txt.d.ts +7 -0
- package/dist/packages/discovery/src/providers/llms-txt.js +60 -0
- package/dist/packages/discovery/src/providers/markdown.d.ts +7 -0
- package/dist/packages/discovery/src/providers/markdown.js +38 -0
- package/dist/packages/discovery/src/providers/openapi.d.ts +7 -0
- package/dist/packages/discovery/src/providers/openapi.js +77 -0
- package/dist/packages/discovery/src/providers/sitemap.d.ts +7 -0
- package/dist/packages/discovery/src/providers/sitemap.js +53 -0
- package/dist/packages/discovery/src/providers/skill.d.ts +7 -0
- package/dist/packages/discovery/src/providers/skill.js +46 -0
- package/dist/packages/discovery/src/ranker.d.ts +6 -0
- package/dist/packages/discovery/src/ranker.js +107 -0
- package/dist/packages/evaluation/src/dataset.d.ts +2 -0
- package/dist/packages/evaluation/src/dataset.js +944 -0
- package/dist/packages/evaluation/src/index.js +8 -0
- package/dist/packages/evaluation/src/runner.d.ts +7 -0
- package/dist/packages/evaluation/src/runner.js +196 -0
- package/dist/packages/evaluation/src/strategies/context7-runner.d.ts +24 -0
- package/dist/packages/evaluation/src/strategies/context7-runner.js +229 -0
- package/dist/packages/evaluation/src/strategies/docorbit-runner.d.ts +5 -0
- package/dist/packages/evaluation/src/strategies/docorbit-runner.js +210 -0
- package/dist/packages/evaluation/src/strategies/firecrawl-runner.d.ts +24 -0
- package/dist/packages/evaluation/src/strategies/firecrawl-runner.js +151 -0
- package/dist/packages/evaluation/src/strategies/web-search-runner.d.ts +32 -0
- package/dist/packages/evaluation/src/strategies/web-search-runner.js +161 -0
- package/dist/packages/evaluation/src/types.d.ts +15 -0
- package/dist/packages/evaluation/src/types.js +1 -0
- package/dist/packages/evaluation/src/version-matcher.d.ts +11 -0
- package/dist/packages/evaluation/src/version-matcher.js +61 -0
- package/dist/packages/export/src/agents-md.d.ts +19 -0
- package/dist/packages/export/src/agents-md.js +170 -0
- package/dist/packages/export/src/claude-md.d.ts +17 -0
- package/dist/packages/export/src/claude-md.js +118 -0
- package/dist/packages/export/src/docs-map.d.ts +14 -0
- package/dist/packages/export/src/docs-map.js +118 -0
- package/dist/packages/export/src/index.js +6 -0
- package/dist/packages/export/src/llms-txt.d.ts +15 -0
- package/dist/packages/export/src/llms-txt.js +73 -0
- package/dist/packages/export/src/service.d.ts +23 -0
- package/dist/packages/export/src/service.js +210 -0
- package/dist/packages/export/src/skill-md.d.ts +14 -0
- package/dist/packages/export/src/skill-md.js +107 -0
- package/{packages/mcp/src/index.ts → dist/packages/mcp/src/index.d.ts} +2 -35
- package/dist/packages/mcp/src/index.js +6 -0
- package/dist/packages/mcp/src/resources/index.d.ts +12 -0
- package/dist/packages/mcp/src/resources/index.js +165 -0
- package/dist/packages/mcp/src/server.d.ts +30 -0
- package/dist/packages/mcp/src/server.js +243 -0
- package/dist/packages/mcp/src/tools/analyze-impact.d.ts +6 -0
- package/dist/packages/mcp/src/tools/analyze-impact.js +64 -0
- package/dist/packages/mcp/src/tools/check-api.d.ts +6 -0
- package/dist/packages/mcp/src/tools/check-api.js +74 -0
- package/dist/packages/mcp/src/tools/diff-docs.d.ts +6 -0
- package/dist/packages/mcp/src/tools/diff-docs.js +58 -0
- package/dist/packages/mcp/src/tools/export-context.d.ts +6 -0
- package/dist/packages/mcp/src/tools/export-context.js +61 -0
- package/dist/packages/mcp/src/tools/find-api.d.ts +6 -0
- package/dist/packages/mcp/src/tools/find-api.js +91 -0
- package/dist/packages/mcp/src/tools/find-example.d.ts +6 -0
- package/dist/packages/mcp/src/tools/find-example.js +92 -0
- package/dist/packages/mcp/src/tools/find-pitfall.d.ts +6 -0
- package/dist/packages/mcp/src/tools/find-pitfall.js +85 -0
- package/dist/packages/mcp/src/tools/find-recipe.d.ts +6 -0
- package/dist/packages/mcp/src/tools/find-recipe.js +89 -0
- package/dist/packages/mcp/src/tools/get-doc.d.ts +6 -0
- package/dist/packages/mcp/src/tools/get-doc.js +118 -0
- package/dist/packages/mcp/src/tools/get-docs-map.d.ts +6 -0
- package/dist/packages/mcp/src/tools/get-docs-map.js +54 -0
- package/dist/packages/mcp/src/tools/get-version.d.ts +6 -0
- package/dist/packages/mcp/src/tools/get-version.js +104 -0
- package/dist/packages/mcp/src/tools/implementation-context.d.ts +6 -0
- package/dist/packages/mcp/src/tools/implementation-context.js +102 -0
- package/dist/packages/mcp/src/tools/index.d.ts +19 -0
- package/dist/packages/mcp/src/tools/index.js +41 -0
- package/dist/packages/mcp/src/tools/ingest-doc.d.ts +6 -0
- package/dist/packages/mcp/src/tools/ingest-doc.js +264 -0
- package/dist/packages/mcp/src/tools/list-sources.d.ts +6 -0
- package/dist/packages/mcp/src/tools/list-sources.js +76 -0
- package/dist/packages/mcp/src/tools/search-docs.d.ts +6 -0
- package/dist/packages/mcp/src/tools/search-docs.js +113 -0
- package/dist/packages/mcp/src/tools/types.d.ts +22 -0
- package/dist/packages/mcp/src/tools/types.js +1 -0
- package/dist/packages/mcp/src/transports/http.d.ts +31 -0
- package/dist/packages/mcp/src/transports/http.js +215 -0
- package/dist/packages/mcp/src/transports/stdio.d.ts +22 -0
- package/dist/packages/mcp/src/transports/stdio.js +86 -0
- package/{packages/mcp/src/transports/types.ts → dist/packages/mcp/src/transports/types.d.ts} +2 -3
- package/dist/packages/mcp/src/transports/types.js +1 -0
- package/dist/packages/mcp/src/types.d.ts +89 -0
- package/dist/packages/mcp/src/types.js +7 -0
- package/dist/packages/normalizer/src/example-indexer.d.ts +5 -0
- package/dist/packages/normalizer/src/example-indexer.js +200 -0
- package/dist/packages/normalizer/src/html.d.ts +13 -0
- package/dist/packages/normalizer/src/html.js +221 -0
- package/{packages/normalizer/src/index.ts → dist/packages/normalizer/src/index.d.ts} +0 -1
- package/dist/packages/normalizer/src/index.js +7 -0
- package/dist/packages/normalizer/src/llms.d.ts +3 -0
- package/dist/packages/normalizer/src/llms.js +71 -0
- package/dist/packages/normalizer/src/openapi/endpoint-parser.d.ts +11 -0
- package/dist/packages/normalizer/src/openapi/endpoint-parser.js +357 -0
- package/dist/packages/normalizer/src/openapi/schema-resolver.d.ts +10 -0
- package/dist/packages/normalizer/src/openapi/schema-resolver.js +82 -0
- package/dist/packages/normalizer/src/openapi.js +2 -0
- package/dist/packages/normalizer/src/page.d.ts +13 -0
- package/dist/packages/normalizer/src/page.js +150 -0
- package/dist/packages/normalizer/src/pitfall-extractor.d.ts +6 -0
- package/dist/packages/normalizer/src/pitfall-extractor.js +153 -0
- package/dist/packages/normalizer/src/slicer.d.ts +30 -0
- package/dist/packages/normalizer/src/slicer.js +360 -0
- package/dist/packages/retrieval/src/engine.d.ts +17 -0
- package/dist/packages/retrieval/src/engine.js +93 -0
- package/{packages/retrieval/src/index.ts → dist/packages/retrieval/src/index.d.ts} +0 -1
- package/dist/packages/retrieval/src/index.js +6 -0
- package/dist/packages/retrieval/src/intent.d.ts +6 -0
- package/dist/packages/retrieval/src/intent.js +39 -0
- package/dist/packages/retrieval/src/packer.d.ts +2 -0
- package/dist/packages/retrieval/src/packer.js +108 -0
- package/dist/packages/retrieval/src/recipe-engine.d.ts +18 -0
- package/dist/packages/retrieval/src/recipe-engine.js +265 -0
- package/dist/packages/retrieval/src/scorer.d.ts +13 -0
- package/dist/packages/retrieval/src/scorer.js +110 -0
- package/dist/packages/retrieval/src/weights.d.ts +3 -0
- package/dist/packages/retrieval/src/weights.js +28 -0
- package/dist/packages/security/src/annotations.d.ts +10 -0
- package/dist/packages/security/src/annotations.js +100 -0
- package/dist/packages/security/src/index.js +2 -0
- package/dist/packages/security/src/ssrf.d.ts +17 -0
- package/dist/packages/security/src/ssrf.js +132 -0
- package/dist/packages/shared/src/errors.d.ts +22 -0
- package/dist/packages/shared/src/errors.js +44 -0
- package/dist/packages/shared/src/hashing.d.ts +3 -0
- package/dist/packages/shared/src/hashing.js +21 -0
- package/dist/packages/shared/src/index.js +3 -0
- package/dist/packages/shared/src/types.d.ts +715 -0
- package/dist/packages/shared/src/types.js +1 -0
- package/dist/packages/storage/src/db.d.ts +11 -0
- package/dist/packages/storage/src/db.js +128 -0
- package/dist/packages/storage/src/index.js +10 -0
- package/dist/packages/storage/src/interfaces.d.ts +83 -0
- package/dist/packages/storage/src/interfaces.js +1 -0
- package/dist/packages/storage/src/repositories/api-repository.d.ts +16 -0
- package/dist/packages/storage/src/repositories/api-repository.js +169 -0
- package/dist/packages/storage/src/repositories/chunk-repository.d.ts +32 -0
- package/dist/packages/storage/src/repositories/chunk-repository.js +250 -0
- package/dist/packages/storage/src/repositories/example-repository.d.ts +16 -0
- package/dist/packages/storage/src/repositories/example-repository.js +158 -0
- package/dist/packages/storage/src/repositories/page-repository.d.ts +16 -0
- package/dist/packages/storage/src/repositories/page-repository.js +161 -0
- package/dist/packages/storage/src/repositories/pitfall-repository.d.ts +15 -0
- package/dist/packages/storage/src/repositories/pitfall-repository.js +144 -0
- package/dist/packages/storage/src/repositories/source-repository.d.ts +33 -0
- package/dist/packages/storage/src/repositories/source-repository.js +153 -0
- package/dist/packages/storage/src/repository.d.ts +92 -0
- package/dist/packages/storage/src/repository.js +157 -0
- package/dist/packages/storage/src/schema.d.ts +2 -0
- package/{packages/storage/src/schema.ts → dist/packages/storage/src/schema.js} +0 -3
- package/dist/packages/storage/src/search-tokens.d.ts +6 -0
- package/dist/packages/storage/src/search-tokens.js +26 -0
- package/dist/packages/verification/src/diff-engine.d.ts +18 -0
- package/dist/packages/verification/src/diff-engine.js +218 -0
- package/dist/packages/verification/src/extractor.d.ts +29 -0
- package/dist/packages/verification/src/extractor.js +302 -0
- package/dist/packages/verification/src/impact-scanner.d.ts +9 -0
- package/dist/packages/verification/src/impact-scanner.js +181 -0
- package/dist/packages/verification/src/index.js +5 -0
- package/dist/packages/verification/src/services.d.ts +55 -0
- package/dist/packages/verification/src/services.js +189 -0
- package/dist/packages/verification/src/verifier.d.ts +15 -0
- package/dist/packages/verification/src/verifier.js +315 -0
- package/dist/packages/workspace/src/detector.d.ts +7 -0
- package/dist/packages/workspace/src/detector.js +117 -0
- package/dist/packages/workspace/src/ecosystems/cargo.d.ts +10 -0
- package/dist/packages/workspace/src/ecosystems/cargo.js +69 -0
- package/dist/packages/workspace/src/ecosystems/composer.d.ts +7 -0
- package/dist/packages/workspace/src/ecosystems/composer.js +40 -0
- package/dist/packages/workspace/src/ecosystems/go.d.ts +7 -0
- package/dist/packages/workspace/src/ecosystems/go.js +49 -0
- package/{packages/workspace/src/ecosystems/index.ts → dist/packages/workspace/src/ecosystems/index.d.ts} +2 -24
- package/dist/packages/workspace/src/ecosystems/index.js +21 -0
- package/dist/packages/workspace/src/ecosystems/maven.d.ts +7 -0
- package/dist/packages/workspace/src/ecosystems/maven.js +28 -0
- package/dist/packages/workspace/src/ecosystems/npm.d.ts +10 -0
- package/dist/packages/workspace/src/ecosystems/npm.js +73 -0
- package/dist/packages/workspace/src/ecosystems/pub.d.ts +7 -0
- package/dist/packages/workspace/src/ecosystems/pub.js +34 -0
- package/dist/packages/workspace/src/ecosystems/pypi.d.ts +9 -0
- package/dist/packages/workspace/src/ecosystems/pypi.js +94 -0
- package/dist/packages/workspace/src/ecosystems/rubygems.d.ts +7 -0
- package/dist/packages/workspace/src/ecosystems/rubygems.js +25 -0
- package/dist/packages/workspace/src/ecosystems/types.d.ts +9 -0
- package/dist/packages/workspace/src/ecosystems/types.js +1 -0
- package/dist/packages/workspace/src/index.js +5 -0
- package/dist/packages/workspace/src/lockfile.d.ts +21 -0
- package/dist/packages/workspace/src/lockfile.js +153 -0
- package/dist/packages/workspace/src/resolver.d.ts +39 -0
- package/dist/packages/workspace/src/resolver.js +164 -0
- package/dist/packages/workspace/src/semver.d.ts +33 -0
- package/dist/packages/workspace/src/semver.js +235 -0
- package/package.json +13 -9
- package/apps/cli/bin/docorbit.js +0 -8
- package/apps/cli/src/commands/add.ts +0 -44
- package/apps/cli/src/commands/api.ts +0 -38
- package/apps/cli/src/commands/context.ts +0 -47
- package/apps/cli/src/commands/dashboard.ts +0 -55
- package/apps/cli/src/commands/diff.ts +0 -30
- package/apps/cli/src/commands/evaluate.ts +0 -133
- package/apps/cli/src/commands/examples.ts +0 -39
- package/apps/cli/src/commands/export.ts +0 -89
- package/apps/cli/src/commands/impact.ts +0 -31
- package/apps/cli/src/commands/init.ts +0 -69
- package/apps/cli/src/commands/inspect.ts +0 -30
- package/apps/cli/src/commands/mcp.ts +0 -72
- package/apps/cli/src/commands/pitfalls.ts +0 -38
- package/apps/cli/src/commands/recipes.ts +0 -35
- package/apps/cli/src/commands/search.ts +0 -48
- package/apps/cli/src/commands/update.ts +0 -73
- package/apps/cli/src/commands/verify.ts +0 -48
- package/apps/cli/src/formatters/colors.ts +0 -23
- package/apps/cli/src/formatters/inspection.ts +0 -102
- package/apps/cli/src/formatters/knowledge.ts +0 -272
- package/apps/cli/src/formatters/retrieval.ts +0 -74
- package/apps/cli/src/formatters/verification.ts +0 -126
- package/apps/cli/src/index.ts +0 -409
- package/packages/core/src/dashboard/server.ts +0 -314
- package/packages/core/src/implementation-service.ts +0 -451
- package/packages/core/src/inspector.ts +0 -71
- package/packages/core/src/pipeline.ts +0 -331
- package/packages/crawler/src/config.ts +0 -12
- package/packages/crawler/src/fetcher.ts +0 -185
- package/packages/discovery/src/index.ts +0 -31
- package/packages/discovery/src/provider.ts +0 -47
- package/packages/discovery/src/providers/generic.ts +0 -98
- package/packages/discovery/src/providers/github.ts +0 -61
- package/packages/discovery/src/providers/llms-txt.ts +0 -73
- package/packages/discovery/src/providers/markdown.ts +0 -48
- package/packages/discovery/src/providers/openapi.ts +0 -91
- package/packages/discovery/src/providers/sitemap.ts +0 -62
- package/packages/discovery/src/providers/skill.ts +0 -54
- package/packages/discovery/src/ranker.ts +0 -123
- package/packages/evaluation/src/dataset.ts +0 -963
- package/packages/evaluation/src/runner.ts +0 -241
- package/packages/evaluation/src/strategies/context7-runner.ts +0 -269
- package/packages/evaluation/src/strategies/docorbit-runner.ts +0 -228
- package/packages/evaluation/src/strategies/firecrawl-runner.ts +0 -172
- package/packages/evaluation/src/strategies/web-search-runner.ts +0 -194
- package/packages/evaluation/src/types.ts +0 -34
- package/packages/evaluation/src/version-matcher.ts +0 -73
- package/packages/export/src/agents-md.ts +0 -200
- package/packages/export/src/claude-md.ts +0 -141
- package/packages/export/src/docs-map.ts +0 -150
- package/packages/export/src/llms-txt.ts +0 -96
- package/packages/export/src/service.ts +0 -250
- package/packages/export/src/skill-md.ts +0 -128
- package/packages/mcp/src/resources/index.ts +0 -189
- package/packages/mcp/src/server.ts +0 -278
- package/packages/mcp/src/tools/analyze-impact.ts +0 -74
- package/packages/mcp/src/tools/check-api.ts +0 -86
- package/packages/mcp/src/tools/diff-docs.ts +0 -68
- package/packages/mcp/src/tools/export-context.ts +0 -73
- package/packages/mcp/src/tools/find-api.ts +0 -99
- package/packages/mcp/src/tools/find-example.ts +0 -100
- package/packages/mcp/src/tools/find-pitfall.ts +0 -94
- package/packages/mcp/src/tools/find-recipe.ts +0 -98
- package/packages/mcp/src/tools/get-doc.ts +0 -130
- package/packages/mcp/src/tools/get-docs-map.ts +0 -64
- package/packages/mcp/src/tools/get-version.ts +0 -118
- package/packages/mcp/src/tools/implementation-context.ts +0 -88
- package/packages/mcp/src/tools/index.ts +0 -59
- package/packages/mcp/src/tools/list-sources.ts +0 -85
- package/packages/mcp/src/tools/search-docs.ts +0 -123
- package/packages/mcp/src/tools/types.ts +0 -28
- package/packages/mcp/src/transports/http.ts +0 -256
- package/packages/mcp/src/transports/stdio.ts +0 -105
- package/packages/mcp/src/types.ts +0 -102
- package/packages/normalizer/src/example-indexer.ts +0 -240
- package/packages/normalizer/src/html.ts +0 -253
- package/packages/normalizer/src/llms.ts +0 -83
- package/packages/normalizer/src/openapi/endpoint-parser.ts +0 -406
- package/packages/normalizer/src/openapi/schema-resolver.ts +0 -111
- package/packages/normalizer/src/page.ts +0 -184
- package/packages/normalizer/src/pitfall-extractor.ts +0 -190
- package/packages/normalizer/src/slicer.ts +0 -455
- package/packages/retrieval/src/engine.ts +0 -120
- package/packages/retrieval/src/intent.ts +0 -43
- package/packages/retrieval/src/packer.ts +0 -145
- package/packages/retrieval/src/recipe-engine.ts +0 -313
- package/packages/retrieval/src/scorer.ts +0 -139
- package/packages/retrieval/src/weights.ts +0 -31
- package/packages/security/src/annotations.ts +0 -112
- package/packages/security/src/ssrf.ts +0 -153
- package/packages/shared/src/errors.ts +0 -53
- package/packages/shared/src/hashing.ts +0 -23
- package/packages/shared/src/types.ts +0 -881
- package/packages/storage/src/db.ts +0 -72
- package/packages/storage/src/interfaces.ts +0 -115
- package/packages/storage/src/repositories/api-repository.ts +0 -219
- package/packages/storage/src/repositories/chunk-repository.ts +0 -316
- package/packages/storage/src/repositories/example-repository.ts +0 -206
- package/packages/storage/src/repositories/page-repository.ts +0 -205
- package/packages/storage/src/repositories/pitfall-repository.ts +0 -188
- package/packages/storage/src/repositories/source-repository.ts +0 -205
- package/packages/storage/src/repository.ts +0 -256
- package/packages/storage/src/search-tokens.ts +0 -28
- package/packages/verification/src/diff-engine.ts +0 -258
- package/packages/verification/src/extractor.ts +0 -339
- package/packages/verification/src/impact-scanner.ts +0 -203
- package/packages/verification/src/services.ts +0 -238
- package/packages/verification/src/verifier.ts +0 -375
- package/packages/workspace/src/detector.ts +0 -143
- package/packages/workspace/src/ecosystems/cargo.ts +0 -84
- package/packages/workspace/src/ecosystems/composer.ts +0 -42
- package/packages/workspace/src/ecosystems/go.ts +0 -54
- package/packages/workspace/src/ecosystems/maven.ts +0 -34
- package/packages/workspace/src/ecosystems/npm.ts +0 -83
- package/packages/workspace/src/ecosystems/pub.ts +0 -40
- package/packages/workspace/src/ecosystems/pypi.ts +0 -100
- package/packages/workspace/src/ecosystems/rubygems.ts +0 -30
- package/packages/workspace/src/ecosystems/types.ts +0 -18
- package/packages/workspace/src/lockfile.ts +0 -194
- package/packages/workspace/src/resolver.ts +0 -234
- package/packages/workspace/src/semver.ts +0 -259
- /package/{packages/crawler/src/index.ts → dist/packages/crawler/src/index.d.ts} +0 -0
- /package/{packages/evaluation/src/index.ts → dist/packages/evaluation/src/index.d.ts} +0 -0
- /package/{packages/export/src/index.ts → dist/packages/export/src/index.d.ts} +0 -0
- /package/{packages/normalizer/src/openapi.ts → dist/packages/normalizer/src/openapi.d.ts} +0 -0
- /package/{packages/security/src/index.ts → dist/packages/security/src/index.d.ts} +0 -0
- /package/{packages/shared/src/index.ts → dist/packages/shared/src/index.d.ts} +0 -0
- /package/{packages/storage/src/index.ts → dist/packages/storage/src/index.d.ts} +0 -0
- /package/{packages/verification/src/index.ts → dist/packages/verification/src/index.d.ts} +0 -0
- /package/{packages/workspace/src/index.ts → dist/packages/workspace/src/index.d.ts} +0 -0
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
import { computeSha256, computeContentHash, estimateTokenCount, } from "../../shared/src/index.js";
|
|
2
|
+
export const DEFAULT_CHUNKING_CONFIG = {
|
|
3
|
+
targetTokens: 500,
|
|
4
|
+
maxTokens: 1000,
|
|
5
|
+
overlapTokens: 50,
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Parses markdown into atomic blocks: headings, code fences, warnings/admonitions, and prose.
|
|
9
|
+
* Guarantees code fences and warnings are kept as atomic units that are never fractured.
|
|
10
|
+
*/
|
|
11
|
+
function parseAtomicBlocks(markdown) {
|
|
12
|
+
const lines = markdown.split('\n');
|
|
13
|
+
const blocks = [];
|
|
14
|
+
let currentProseLines = [];
|
|
15
|
+
const flushProse = () => {
|
|
16
|
+
if (currentProseLines.length > 0) {
|
|
17
|
+
const text = currentProseLines.join('\n').trim();
|
|
18
|
+
if (text) {
|
|
19
|
+
blocks.push({ type: 'prose', content: text });
|
|
20
|
+
}
|
|
21
|
+
currentProseLines = [];
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
let i = 0;
|
|
25
|
+
while (i < lines.length) {
|
|
26
|
+
const line = lines[i];
|
|
27
|
+
// Check for code fence start
|
|
28
|
+
const codeMatch = line.match(/^```([a-zA-Z0-9_-]*)/);
|
|
29
|
+
if (codeMatch) {
|
|
30
|
+
flushProse();
|
|
31
|
+
const lang = codeMatch[1].trim() || 'text';
|
|
32
|
+
const codeLines = [line];
|
|
33
|
+
i++;
|
|
34
|
+
while (i < lines.length) {
|
|
35
|
+
codeLines.push(lines[i]);
|
|
36
|
+
if (lines[i].trim().startsWith('```')) {
|
|
37
|
+
i++;
|
|
38
|
+
break;
|
|
39
|
+
}
|
|
40
|
+
i++;
|
|
41
|
+
}
|
|
42
|
+
blocks.push({
|
|
43
|
+
type: 'code',
|
|
44
|
+
language: lang,
|
|
45
|
+
content: codeLines.join('\n'),
|
|
46
|
+
});
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
// Check for heading outside code fence
|
|
50
|
+
const headingMatch = line.match(/^(#{1,6})\s+(.+)$/);
|
|
51
|
+
if (headingMatch) {
|
|
52
|
+
flushProse();
|
|
53
|
+
const level = headingMatch[1].length;
|
|
54
|
+
const text = headingMatch[2].trim();
|
|
55
|
+
blocks.push({
|
|
56
|
+
type: 'heading',
|
|
57
|
+
headingLevel: level,
|
|
58
|
+
headingText: text,
|
|
59
|
+
content: line,
|
|
60
|
+
});
|
|
61
|
+
i++;
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
// Check for admonition / warning blockquote (> [!NOTE], > [!WARNING], > Note:, > Warning:)
|
|
65
|
+
if (/^>\s*(\[!?(NOTE|WARNING|IMPORTANT|CAUTION|TIP)\]|Note:|Warning:|Caution:|Important:)/i.test(line)) {
|
|
66
|
+
flushProse();
|
|
67
|
+
const warningLines = [line];
|
|
68
|
+
i++;
|
|
69
|
+
while (i < lines.length && (lines[i].startsWith('>') || lines[i].trim() === '')) {
|
|
70
|
+
warningLines.push(lines[i]);
|
|
71
|
+
i++;
|
|
72
|
+
}
|
|
73
|
+
blocks.push({
|
|
74
|
+
type: 'warning',
|
|
75
|
+
content: warningLines.join('\n').trim(),
|
|
76
|
+
});
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
// Empty line separates paragraphs
|
|
80
|
+
if (line.trim() === '') {
|
|
81
|
+
flushProse();
|
|
82
|
+
i++;
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
// Regular prose line within paragraph
|
|
86
|
+
currentProseLines.push(line);
|
|
87
|
+
i++;
|
|
88
|
+
}
|
|
89
|
+
flushProse();
|
|
90
|
+
return blocks;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Groups atomic blocks into hierarchical sections tracking heading breadcrumbs.
|
|
94
|
+
*/
|
|
95
|
+
function groupIntoSections(blocks, defaultTitle) {
|
|
96
|
+
const sections = [];
|
|
97
|
+
const headingStack = [];
|
|
98
|
+
let currentSection = {
|
|
99
|
+
headingLevel: 1,
|
|
100
|
+
headingText: defaultTitle,
|
|
101
|
+
sectionPath: [defaultTitle],
|
|
102
|
+
blocks: [],
|
|
103
|
+
};
|
|
104
|
+
for (const block of blocks) {
|
|
105
|
+
if (block.type === 'heading') {
|
|
106
|
+
if (currentSection.blocks.length > 0) {
|
|
107
|
+
sections.push(currentSection);
|
|
108
|
+
}
|
|
109
|
+
const level = block.headingLevel || 1;
|
|
110
|
+
const text = block.headingText || defaultTitle;
|
|
111
|
+
while (headingStack.length > 0 && headingStack[headingStack.length - 1].level >= level) {
|
|
112
|
+
headingStack.pop();
|
|
113
|
+
}
|
|
114
|
+
headingStack.push({ level, text });
|
|
115
|
+
currentSection = {
|
|
116
|
+
headingLevel: level,
|
|
117
|
+
headingText: text,
|
|
118
|
+
sectionPath: headingStack.map(h => h.text),
|
|
119
|
+
blocks: [],
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
currentSection.blocks.push(block);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
if (currentSection.blocks.length > 0 || sections.length === 0) {
|
|
127
|
+
sections.push(currentSection);
|
|
128
|
+
}
|
|
129
|
+
return sections;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Shallow, deterministic symbol extractor using lightweight regex patterns.
|
|
133
|
+
* No external AST parsers or language runtimes.
|
|
134
|
+
*/
|
|
135
|
+
export function extractSymbols(content, chunkId) {
|
|
136
|
+
const symbols = [];
|
|
137
|
+
const seen = new Set();
|
|
138
|
+
const addSymbol = (name, kind) => {
|
|
139
|
+
const clean = name.trim();
|
|
140
|
+
if (clean && !seen.has(clean) && clean.length > 1 && clean.length < 80) {
|
|
141
|
+
seen.add(clean);
|
|
142
|
+
symbols.push({
|
|
143
|
+
id: `sym_${chunkId}_${symbols.length + 1}`,
|
|
144
|
+
chunkId,
|
|
145
|
+
name: clean,
|
|
146
|
+
kind,
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
// 1. REST API endpoints: (GET|POST|PUT|DELETE|PATCH) /path
|
|
151
|
+
const endpointRegex = /\b(GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD)\s+([/][a-zA-Z0-9_{}/:.-]+)/g;
|
|
152
|
+
let match;
|
|
153
|
+
while ((match = endpointRegex.exec(content)) !== null) {
|
|
154
|
+
addSymbol(`${match[1]} ${match[2]}`, 'endpoint');
|
|
155
|
+
}
|
|
156
|
+
// 2. Functions: function foo(...), def foo(...), fn foo(...), func foo(...)
|
|
157
|
+
const funcRegex = /\b(?:function|def|func|fn)\s+([a-zA-Z0-9_$]+)\s*\(/g;
|
|
158
|
+
while ((match = funcRegex.exec(content)) !== null) {
|
|
159
|
+
addSymbol(match[1], 'function');
|
|
160
|
+
}
|
|
161
|
+
// 3. Arrow function assignments: const foo = (...) => or const foo = async (...) =>
|
|
162
|
+
const arrowRegex = /\b(?:const|let|var)\s+([a-zA-Z0-9_$]+)\s*=\s*(?:async\s*)?\([^)]*\)\s*=>/g;
|
|
163
|
+
while ((match = arrowRegex.exec(content)) !== null) {
|
|
164
|
+
addSymbol(match[1], 'function');
|
|
165
|
+
}
|
|
166
|
+
// 4. Classes and interfaces: class Foo, interface Bar, struct Baz, type Qux =
|
|
167
|
+
const classRegex = /\b(?:class|interface|struct|enum)\s+([a-zA-Z0-9_$]+)/g;
|
|
168
|
+
while ((match = classRegex.exec(content)) !== null) {
|
|
169
|
+
addSymbol(match[1], match[0].startsWith('class') ? 'class' : 'interface');
|
|
170
|
+
}
|
|
171
|
+
const typeRegex = /\btype\s+([A-Z][a-zA-Z0-9_$]*)\s*=/g;
|
|
172
|
+
while ((match = typeRegex.exec(content)) !== null) {
|
|
173
|
+
addSymbol(match[1], 'type');
|
|
174
|
+
}
|
|
175
|
+
// 5. Common config keys (YAML/JSON): key: value or "key":
|
|
176
|
+
const configRegex = /^[ \t]*([a-zA-Z0-9_.-]{3,30})\s*:\s*[^\s]/gm;
|
|
177
|
+
while ((match = configRegex.exec(content)) !== null) {
|
|
178
|
+
if (!['http', 'https', 'note', 'warning', 'tip', 'important', 'version'].includes(match[1].toLowerCase())) {
|
|
179
|
+
addSymbol(match[1], 'config');
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
return symbols;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Detects chunk type based on block composition and content.
|
|
186
|
+
*/
|
|
187
|
+
export function detectChunkType(blocks, content) {
|
|
188
|
+
const hasWarning = blocks.some(b => b.type === 'warning') || />\s*\[!(WARNING|CAUTION|IMPORTANT)\]/i.test(content);
|
|
189
|
+
const codeBlocks = blocks.filter(b => b.type === 'code');
|
|
190
|
+
const hasEndpoint = /\b(GET|POST|PUT|DELETE|PATCH)\s+[/]/.test(content);
|
|
191
|
+
if (hasEndpoint) {
|
|
192
|
+
return 'api';
|
|
193
|
+
}
|
|
194
|
+
if (hasWarning && blocks.length <= 2) {
|
|
195
|
+
return 'warning';
|
|
196
|
+
}
|
|
197
|
+
if (codeBlocks.length > 0 && blocks.every(b => b.type === 'code' || b.type === 'heading')) {
|
|
198
|
+
return 'code';
|
|
199
|
+
}
|
|
200
|
+
if (codeBlocks.length > 0 && content.toLowerCase().includes('example')) {
|
|
201
|
+
return 'example';
|
|
202
|
+
}
|
|
203
|
+
if (codeBlocks.length > 0) {
|
|
204
|
+
return 'mixed';
|
|
205
|
+
}
|
|
206
|
+
return 'prose';
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Slices a NormalizedPage into standalone, context-preserving DocumentChunks,
|
|
210
|
+
* maintaining section breadcrumbs, relationship links, code snippets, and symbols.
|
|
211
|
+
*/
|
|
212
|
+
export function slicePageIntoChunks(page, snapshotId, config = DEFAULT_CHUNKING_CONFIG) {
|
|
213
|
+
const atomicBlocks = parseAtomicBlocks(page.content);
|
|
214
|
+
const sections = groupIntoSections(atomicBlocks, page.title);
|
|
215
|
+
const chunks = [];
|
|
216
|
+
const relationships = [];
|
|
217
|
+
const codeSnippets = [];
|
|
218
|
+
const symbols = [];
|
|
219
|
+
const provenance = page.provenance || {
|
|
220
|
+
sourceUrl: page.url,
|
|
221
|
+
targetUrl: page.url,
|
|
222
|
+
fetchedAt: page.fetchedAt,
|
|
223
|
+
discoveredBy: 'direct',
|
|
224
|
+
contentHash: page.contentHash,
|
|
225
|
+
snapshotId,
|
|
226
|
+
};
|
|
227
|
+
let globalOrdinal = 0;
|
|
228
|
+
const sectionRootChunkIds = new Map();
|
|
229
|
+
for (const section of sections) {
|
|
230
|
+
const sectionTitle = section.headingText;
|
|
231
|
+
const sectionPathKey = section.sectionPath.join(' > ');
|
|
232
|
+
if (section.blocks.length === 0)
|
|
233
|
+
continue;
|
|
234
|
+
const fullSectionText = section.blocks.map(b => b.content).join('\n\n');
|
|
235
|
+
const estimatedTokens = estimateTokenCount(fullSectionText);
|
|
236
|
+
let chunkBlockGroups = [];
|
|
237
|
+
if (estimatedTokens <= config.maxTokens) {
|
|
238
|
+
chunkBlockGroups.push(section.blocks);
|
|
239
|
+
}
|
|
240
|
+
else {
|
|
241
|
+
// Secondary splitting: split on atomic block boundaries
|
|
242
|
+
let currentGroup = [];
|
|
243
|
+
let currentTokens = 0;
|
|
244
|
+
for (let i = 0; i < section.blocks.length; i++) {
|
|
245
|
+
const block = section.blocks[i];
|
|
246
|
+
const blockTokens = estimateTokenCount(block.content);
|
|
247
|
+
const isWarning = block.type === 'warning';
|
|
248
|
+
if (currentGroup.length > 0 && (currentTokens + blockTokens > config.targetTokens) && !isWarning) {
|
|
249
|
+
chunkBlockGroups.push(currentGroup);
|
|
250
|
+
currentGroup = [block];
|
|
251
|
+
currentTokens = blockTokens;
|
|
252
|
+
}
|
|
253
|
+
else {
|
|
254
|
+
currentGroup.push(block);
|
|
255
|
+
currentTokens += blockTokens;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
if (currentGroup.length > 0) {
|
|
259
|
+
chunkBlockGroups.push(currentGroup);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
let parentChunkId;
|
|
263
|
+
for (let gIdx = 0; gIdx < chunkBlockGroups.length; gIdx++) {
|
|
264
|
+
const group = chunkBlockGroups[gIdx];
|
|
265
|
+
const chunkContent = group.map(b => b.content).join('\n\n');
|
|
266
|
+
const chunkType = detectChunkType(group, chunkContent);
|
|
267
|
+
const codeBlock = group.find(b => b.type === 'code');
|
|
268
|
+
const dominantLanguage = codeBlock?.language;
|
|
269
|
+
const chunkHash = computeContentHash(chunkContent);
|
|
270
|
+
const chunkId = `chk_${computeSha256(`${page.id}:${globalOrdinal}:${chunkHash}`).slice(0, 16)}`;
|
|
271
|
+
const tokenEst = estimateTokenCount(chunkContent);
|
|
272
|
+
const chunk = {
|
|
273
|
+
id: chunkId,
|
|
274
|
+
pageId: page.id,
|
|
275
|
+
snapshotId,
|
|
276
|
+
title: sectionTitle,
|
|
277
|
+
sectionPath: [...section.sectionPath],
|
|
278
|
+
content: chunkContent,
|
|
279
|
+
chunkType,
|
|
280
|
+
language: dominantLanguage,
|
|
281
|
+
tokenEstimate: tokenEst,
|
|
282
|
+
ordinal: globalOrdinal,
|
|
283
|
+
contentHash: chunkHash,
|
|
284
|
+
provenance,
|
|
285
|
+
};
|
|
286
|
+
chunks.push(chunk);
|
|
287
|
+
if (gIdx === 0) {
|
|
288
|
+
parentChunkId = chunkId;
|
|
289
|
+
sectionRootChunkIds.set(sectionPathKey, chunkId);
|
|
290
|
+
if (section.sectionPath.length > 1) {
|
|
291
|
+
const parentPathKey = section.sectionPath.slice(0, -1).join(' > ');
|
|
292
|
+
const ancestorId = sectionRootChunkIds.get(parentPathKey);
|
|
293
|
+
if (ancestorId && ancestorId !== chunkId) {
|
|
294
|
+
relationships.push({
|
|
295
|
+
sourceChunkId: chunkId,
|
|
296
|
+
targetChunkId: ancestorId,
|
|
297
|
+
type: 'parent_section',
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
else if (parentChunkId) {
|
|
303
|
+
relationships.push({
|
|
304
|
+
sourceChunkId: chunkId,
|
|
305
|
+
targetChunkId: parentChunkId,
|
|
306
|
+
type: 'parent_section',
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
if (globalOrdinal > 0) {
|
|
310
|
+
const prevChunk = chunks[chunks.length - 2];
|
|
311
|
+
relationships.push({
|
|
312
|
+
sourceChunkId: prevChunk.id,
|
|
313
|
+
targetChunkId: chunkId,
|
|
314
|
+
type: 'next_chunk',
|
|
315
|
+
});
|
|
316
|
+
relationships.push({
|
|
317
|
+
sourceChunkId: chunkId,
|
|
318
|
+
targetChunkId: prevChunk.id,
|
|
319
|
+
type: 'previous_chunk',
|
|
320
|
+
});
|
|
321
|
+
if (prevChunk.chunkType === 'prose' && (chunkType === 'code' || chunkType === 'example')) {
|
|
322
|
+
relationships.push({
|
|
323
|
+
sourceChunkId: prevChunk.id,
|
|
324
|
+
targetChunkId: chunkId,
|
|
325
|
+
type: 'explains_code',
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
// Extract code snippets
|
|
330
|
+
for (const b of group) {
|
|
331
|
+
if (b.type === 'code') {
|
|
332
|
+
const codeSnippetId = `code_${chunkId}_${codeSnippets.length + 1}`;
|
|
333
|
+
codeSnippets.push({
|
|
334
|
+
id: codeSnippetId,
|
|
335
|
+
chunkId,
|
|
336
|
+
language: b.language,
|
|
337
|
+
code: b.content.replace(/^```[a-zA-Z0-9_-]*\n/, '').replace(/\n```$/, ''),
|
|
338
|
+
});
|
|
339
|
+
relationships.push({
|
|
340
|
+
sourceChunkId: chunkId,
|
|
341
|
+
targetChunkId: codeSnippetId,
|
|
342
|
+
type: 'contains_code',
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
// Extract symbols
|
|
347
|
+
const chunkSymbols = extractSymbols(chunkContent, chunkId);
|
|
348
|
+
for (const sym of chunkSymbols) {
|
|
349
|
+
symbols.push(sym);
|
|
350
|
+
}
|
|
351
|
+
globalOrdinal++;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
return {
|
|
355
|
+
chunks,
|
|
356
|
+
relationships,
|
|
357
|
+
codeSnippets,
|
|
358
|
+
symbols,
|
|
359
|
+
};
|
|
360
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { SearchResult, SearchOptions, ContextPackage, ContextOptions, ScoringWeights } from '../../shared/src/index.ts';
|
|
2
|
+
import { DocOrbitRepository } from '../../storage/src/index.ts';
|
|
3
|
+
export declare class RetrievalEngine {
|
|
4
|
+
private repository;
|
|
5
|
+
private defaultWeights;
|
|
6
|
+
constructor(repository: DocOrbitRepository, defaultWeights?: Partial<ScoringWeights>);
|
|
7
|
+
/**
|
|
8
|
+
* Deterministic hybrid search combining FTS5 lexical matching, exact phrases,
|
|
9
|
+
* title/breadcrumb boosts, shallow symbol matches, intent weighting, and authority.
|
|
10
|
+
*/
|
|
11
|
+
search(query: string, options?: SearchOptions): Promise<SearchResult[]>;
|
|
12
|
+
/**
|
|
13
|
+
* Assembles a context package tailored for AI coding agents, optimizing for
|
|
14
|
+
* relevance + coverage - redundancy within a strict token budget.
|
|
15
|
+
*/
|
|
16
|
+
buildContext(task: string, options?: ContextOptions): Promise<ContextPackage>;
|
|
17
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { resolveScoringWeights } from "./weights.js";
|
|
2
|
+
import { detectQueryIntent } from "./intent.js";
|
|
3
|
+
import { scoreChunkCandidate } from "./scorer.js";
|
|
4
|
+
import { packContext } from "./packer.js";
|
|
5
|
+
import { resolveProjectContext } from "../../workspace/src/index.js";
|
|
6
|
+
export class RetrievalEngine {
|
|
7
|
+
repository;
|
|
8
|
+
defaultWeights;
|
|
9
|
+
constructor(repository, defaultWeights) {
|
|
10
|
+
this.repository = repository;
|
|
11
|
+
this.defaultWeights = resolveScoringWeights(defaultWeights);
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Deterministic hybrid search combining FTS5 lexical matching, exact phrases,
|
|
15
|
+
* title/breadcrumb boosts, shallow symbol matches, intent weighting, and authority.
|
|
16
|
+
*/
|
|
17
|
+
async search(query, options = {}) {
|
|
18
|
+
const intent = options.intent || detectQueryIntent(query);
|
|
19
|
+
const weights = resolveScoringWeights(options.weights || this.defaultWeights);
|
|
20
|
+
const limit = options.limit || 10;
|
|
21
|
+
let targetDocVersion = options.docVersion;
|
|
22
|
+
if (options.projectDir) {
|
|
23
|
+
const projContext = resolveProjectContext(options.projectDir, query, this.repository);
|
|
24
|
+
if (projContext.matchedDependency && !targetDocVersion) {
|
|
25
|
+
targetDocVersion = projContext.matchedDependency.targetDocVersion;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
// Fetch candidate pool from FTS5 with extra headroom for re-ranking
|
|
29
|
+
const candidates = this.repository.searchChunksFts(query, {
|
|
30
|
+
limit: Math.max(limit * 3, 30),
|
|
31
|
+
snapshotId: options.snapshotId,
|
|
32
|
+
chunkType: options.chunkType,
|
|
33
|
+
});
|
|
34
|
+
if (candidates.length === 0) {
|
|
35
|
+
return [];
|
|
36
|
+
}
|
|
37
|
+
const scoredResults = [];
|
|
38
|
+
// Cache source authority per page
|
|
39
|
+
const pageAuthorityCache = new Map();
|
|
40
|
+
for (const item of candidates) {
|
|
41
|
+
let authority = 'official';
|
|
42
|
+
const pageId = item.chunk.pageId;
|
|
43
|
+
if (!pageAuthorityCache.has(pageId)) {
|
|
44
|
+
const page = this.repository.getPage(pageId);
|
|
45
|
+
if (page?.sourceId) {
|
|
46
|
+
const src = this.repository.getSource(page.sourceId);
|
|
47
|
+
if (src?.authority) {
|
|
48
|
+
authority = src.authority;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
pageAuthorityCache.set(pageId, authority);
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
authority = pageAuthorityCache.get(pageId);
|
|
55
|
+
}
|
|
56
|
+
const scored = scoreChunkCandidate({
|
|
57
|
+
chunk: item.chunk,
|
|
58
|
+
ftsRank: item.ftsRank,
|
|
59
|
+
symbols: item.symbols,
|
|
60
|
+
codeSnippets: item.codeSnippets,
|
|
61
|
+
query,
|
|
62
|
+
intent,
|
|
63
|
+
authority,
|
|
64
|
+
targetDocVersion,
|
|
65
|
+
weights,
|
|
66
|
+
});
|
|
67
|
+
if (options.minScore !== undefined && scored.score < options.minScore) {
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
scoredResults.push(scored);
|
|
71
|
+
}
|
|
72
|
+
// Sort by score descending
|
|
73
|
+
scoredResults.sort((a, b) => b.score - a.score);
|
|
74
|
+
return scoredResults.slice(0, limit);
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Assembles a context package tailored for AI coding agents, optimizing for
|
|
78
|
+
* relevance + coverage - redundancy within a strict token budget.
|
|
79
|
+
*/
|
|
80
|
+
async buildContext(task, options = {}) {
|
|
81
|
+
const intent = options.intent || detectQueryIntent(task);
|
|
82
|
+
// Retrieve broad candidate set
|
|
83
|
+
const candidates = await this.search(task, {
|
|
84
|
+
limit: (options.maxChunks || 15) * 2,
|
|
85
|
+
snapshotId: options.snapshotId,
|
|
86
|
+
docVersion: options.docVersion,
|
|
87
|
+
projectDir: options.projectDir,
|
|
88
|
+
weights: options.weights,
|
|
89
|
+
intent,
|
|
90
|
+
});
|
|
91
|
+
return packContext(task, candidates, intent, options);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { QueryIntent } from '../../shared/src/index.ts';
|
|
2
|
+
/**
|
|
3
|
+
* Deterministically detects query intent from task or query text.
|
|
4
|
+
* Falls back to 'conceptual' when no specific pattern matches.
|
|
5
|
+
*/
|
|
6
|
+
export declare function detectQueryIntent(query: string): QueryIntent;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
const INTENT_PATTERNS = [
|
|
2
|
+
{
|
|
3
|
+
intent: 'troubleshooting',
|
|
4
|
+
regex: /\b(error|failed|failure|exception|crash|fix|debug|issue|cannot|unable|why does|broken|invalid|429|401|403|404|500)\b/i,
|
|
5
|
+
},
|
|
6
|
+
{
|
|
7
|
+
intent: 'examples',
|
|
8
|
+
regex: /\b(example|examples|sample|samples|snippet|snippets|tutorial|how to|quickstart)\b/i,
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
intent: 'configuration',
|
|
12
|
+
regex: /\b(config|configuration|settings|setup|env|\.env|environment|options|flags?|port|credentials|apikey|api_key)\b/i,
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
intent: 'api',
|
|
16
|
+
regex: /\b(api|endpoint|endpoints|parameters?|request|response|headers?|payload|schema|rest|graphql|status code)\b/i,
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
intent: 'implementation',
|
|
20
|
+
regex: /\b(implement|implementation|build|create|integrate|integration|workflow|handler|webhook|callback|oauth|pipeline)\b/i,
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
intent: 'conceptual',
|
|
24
|
+
regex: /\b(architecture|overview|what is|concept|concepts|design|lifecycle|philosophy|background|understand)\b/i,
|
|
25
|
+
},
|
|
26
|
+
];
|
|
27
|
+
/**
|
|
28
|
+
* Deterministically detects query intent from task or query text.
|
|
29
|
+
* Falls back to 'conceptual' when no specific pattern matches.
|
|
30
|
+
*/
|
|
31
|
+
export function detectQueryIntent(query) {
|
|
32
|
+
const normalized = query.toLowerCase();
|
|
33
|
+
for (const { intent, regex } of INTENT_PATTERNS) {
|
|
34
|
+
if (regex.test(normalized)) {
|
|
35
|
+
return intent;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return 'conceptual';
|
|
39
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
export function packContext(task, candidates, detectedIntent, options = {}) {
|
|
2
|
+
const tokenBudget = options.tokenBudget || 3000;
|
|
3
|
+
const maxChunks = options.maxChunks || 15;
|
|
4
|
+
const redundancyPenalty = options.redundancyPenalty ?? 0.35;
|
|
5
|
+
const selectedChunks = [];
|
|
6
|
+
const selectedChunkIds = new Set();
|
|
7
|
+
const selectedSectionCounts = new Map();
|
|
8
|
+
const selectedPages = new Set();
|
|
9
|
+
const sourcesSet = new Set();
|
|
10
|
+
const warnings = [];
|
|
11
|
+
let totalEstimatedTokens = 0;
|
|
12
|
+
const remainingCandidates = [...candidates];
|
|
13
|
+
while (remainingCandidates.length > 0 && selectedChunks.length < maxChunks) {
|
|
14
|
+
let bestIdx = -1;
|
|
15
|
+
let bestUtility = -Infinity;
|
|
16
|
+
for (let i = 0; i < remainingCandidates.length; i++) {
|
|
17
|
+
const candidate = remainingCandidates[i];
|
|
18
|
+
const chunk = candidate.chunk;
|
|
19
|
+
// Check if it strictly fits within the remaining token budget
|
|
20
|
+
if (totalEstimatedTokens + chunk.tokenEstimate > tokenBudget) {
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
const sectionKey = `${chunk.pageId}:${chunk.sectionPath.join(' > ')}`;
|
|
24
|
+
const sectionOverlap = selectedSectionCounts.get(sectionKey) || 0;
|
|
25
|
+
// Penalize multiple chunks from the exact same section to encourage diversity/coverage
|
|
26
|
+
const redundancyFactor = Math.pow(1 - redundancyPenalty, sectionOverlap);
|
|
27
|
+
// Reward discovering new pages / sections (coverage bonus)
|
|
28
|
+
const coverageMultiplier = selectedPages.has(chunk.pageId) ? 1.0 : 1.25;
|
|
29
|
+
const utility = candidate.score * redundancyFactor * coverageMultiplier;
|
|
30
|
+
if (utility > bestUtility) {
|
|
31
|
+
bestUtility = utility;
|
|
32
|
+
bestIdx = i;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
if (bestIdx === -1) {
|
|
36
|
+
// No remaining candidate fits within the remaining token budget
|
|
37
|
+
break;
|
|
38
|
+
}
|
|
39
|
+
const chosen = remainingCandidates.splice(bestIdx, 1)[0];
|
|
40
|
+
const chunk = chosen.chunk;
|
|
41
|
+
selectedChunks.push(chunk);
|
|
42
|
+
selectedChunkIds.add(chunk.id);
|
|
43
|
+
const sectionKey = `${chunk.pageId}:${chunk.sectionPath.join(' > ')}`;
|
|
44
|
+
selectedSectionCounts.set(sectionKey, (selectedSectionCounts.get(sectionKey) || 0) + 1);
|
|
45
|
+
selectedPages.add(chunk.pageId);
|
|
46
|
+
if (chunk.provenance?.targetUrl) {
|
|
47
|
+
sourcesSet.add(chunk.provenance.targetUrl);
|
|
48
|
+
}
|
|
49
|
+
else if (chunk.provenance?.sourceUrl) {
|
|
50
|
+
sourcesSet.add(chunk.provenance.sourceUrl);
|
|
51
|
+
}
|
|
52
|
+
totalEstimatedTokens += chunk.tokenEstimate;
|
|
53
|
+
// If chunk is a warning, register it in top-level warnings
|
|
54
|
+
if (chunk.chunkType === 'warning') {
|
|
55
|
+
warnings.push(`[${chunk.sectionPath.join(' > ')}]: ${chunk.content.slice(0, 150)}...`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
// Group chunks by page in order of page first appearance in selectedChunks (most relevant page first)
|
|
59
|
+
const pageOrder = new Map();
|
|
60
|
+
for (let i = 0; i < selectedChunks.length; i++) {
|
|
61
|
+
const pId = selectedChunks[i].pageId;
|
|
62
|
+
if (!pageOrder.has(pId)) {
|
|
63
|
+
pageOrder.set(pId, pageOrder.size);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
const sortedChunks = [...selectedChunks].sort((a, b) => {
|
|
67
|
+
const pOrderA = pageOrder.get(a.pageId) ?? 0;
|
|
68
|
+
const pOrderB = pageOrder.get(b.pageId) ?? 0;
|
|
69
|
+
if (pOrderA !== pOrderB)
|
|
70
|
+
return pOrderA - pOrderB;
|
|
71
|
+
return a.ordinal - b.ordinal;
|
|
72
|
+
});
|
|
73
|
+
// Build agent-facing Markdown package
|
|
74
|
+
const lines = [];
|
|
75
|
+
lines.push(`# Context Package: ${task}`);
|
|
76
|
+
lines.push(`- **Detected Intent**: \`${detectedIntent}\``);
|
|
77
|
+
lines.push(`- **Estimated Tokens**: ~${totalEstimatedTokens} / ${tokenBudget} tokens (heuristic estimate)`);
|
|
78
|
+
lines.push(`- **Sources Included**: ${sourcesSet.size > 0 ? Array.from(sourcesSet).map(s => `[${s}](${s})`).join(', ') : 'Local documentation'}`);
|
|
79
|
+
if (warnings.length > 0) {
|
|
80
|
+
lines.push('\n> [!WARNING]');
|
|
81
|
+
lines.push('> **Relevant Advisories & Caveats**:');
|
|
82
|
+
for (const w of warnings) {
|
|
83
|
+
lines.push(`> - ${w}`);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
lines.push('\n---\n');
|
|
87
|
+
for (const chunk of sortedChunks) {
|
|
88
|
+
const breadcrumb = chunk.sectionPath.length > 0 ? chunk.sectionPath.join(' > ') : (chunk.title || 'General');
|
|
89
|
+
lines.push(`### ${breadcrumb}`);
|
|
90
|
+
lines.push(`*Type: \`${chunk.chunkType}\` | Est. Tokens: ~${chunk.tokenEstimate}*`);
|
|
91
|
+
lines.push('\n' + chunk.content.trim() + '\n');
|
|
92
|
+
if (chunk.provenance?.sourceUrl) {
|
|
93
|
+
lines.push(`*Source: ${chunk.provenance.sourceUrl}*\n`);
|
|
94
|
+
}
|
|
95
|
+
lines.push('---\n');
|
|
96
|
+
}
|
|
97
|
+
const markdown = lines.join('\n');
|
|
98
|
+
return {
|
|
99
|
+
task,
|
|
100
|
+
detectedIntent,
|
|
101
|
+
totalEstimatedTokens,
|
|
102
|
+
tokenBudget,
|
|
103
|
+
chunks: sortedChunks,
|
|
104
|
+
markdown,
|
|
105
|
+
sources: Array.from(sourcesSet),
|
|
106
|
+
warnings,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Recipe } from '../../shared/src/index.ts';
|
|
2
|
+
import { DocOrbitRepository } from '../../storage/src/index.ts';
|
|
3
|
+
import { RetrievalEngine } from './engine.ts';
|
|
4
|
+
export interface RecipeOptions {
|
|
5
|
+
docVersion?: string;
|
|
6
|
+
projectDir?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare class RecipeEngine {
|
|
9
|
+
private repository;
|
|
10
|
+
private retrievalEngine;
|
|
11
|
+
constructor(repository: DocOrbitRepository, retrievalEngine?: RetrievalEngine);
|
|
12
|
+
/**
|
|
13
|
+
* Deterministically compiles an implementation recipe grounded strictly in indexed evidence.
|
|
14
|
+
* Distinguishes documented facts, inferred relationships, and missing information.
|
|
15
|
+
* Never invents APIs, steps, prerequisites, or validation steps.
|
|
16
|
+
*/
|
|
17
|
+
assembleRecipe(goal: string, options?: RecipeOptions): Promise<Recipe>;
|
|
18
|
+
}
|