docorbit 0.1.0 → 0.1.1
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/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 +82 -0
- package/dist/packages/mcp/src/tools/index.d.ts +18 -0
- package/dist/packages/mcp/src/tools/index.js +39 -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 +10 -0
- package/dist/packages/storage/src/db.js +61 -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 +8 -7
- 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,189 @@
|
|
|
1
|
+
import { WorkspaceResolver } from "../../workspace/src/index.js";
|
|
2
|
+
import { CodeApiExtractor } from "./extractor.js";
|
|
3
|
+
import { SchemaVerifier } from "./verifier.js";
|
|
4
|
+
import { DocDiffEngine } from "./diff-engine.js";
|
|
5
|
+
import { WorkspaceImpactScanner } from "./impact-scanner.js";
|
|
6
|
+
export class VerificationService {
|
|
7
|
+
repo;
|
|
8
|
+
extractor;
|
|
9
|
+
verifier;
|
|
10
|
+
resolver;
|
|
11
|
+
constructor(repo) {
|
|
12
|
+
this.repo = repo;
|
|
13
|
+
this.extractor = new CodeApiExtractor();
|
|
14
|
+
this.verifier = new SchemaVerifier(repo);
|
|
15
|
+
this.resolver = new WorkspaceResolver(repo);
|
|
16
|
+
}
|
|
17
|
+
verifyCode(request) {
|
|
18
|
+
let effectiveDocVersion = request.version;
|
|
19
|
+
let projectVersion;
|
|
20
|
+
// Resolve project version context if projectDir is provided
|
|
21
|
+
if (request.projectDir) {
|
|
22
|
+
try {
|
|
23
|
+
const scan = this.resolver.scanWorkspace(request.projectDir);
|
|
24
|
+
const resolution = this.resolver.resolveWorkspace(scan);
|
|
25
|
+
const libName = (request.library || '').toLowerCase();
|
|
26
|
+
let matched = resolution.matches.find(m => m.dependency.name.toLowerCase() === libName);
|
|
27
|
+
if (!matched && resolution.matches.length > 0) {
|
|
28
|
+
if (request.code.includes('params') && resolution.matches.some(m => m.dependency.name.toLowerCase() === 'next')) {
|
|
29
|
+
matched = resolution.matches.find(m => m.dependency.name.toLowerCase() === 'next');
|
|
30
|
+
}
|
|
31
|
+
if (!matched) {
|
|
32
|
+
// If library not specified, check if code mentions any dependency name
|
|
33
|
+
for (const m of resolution.matches) {
|
|
34
|
+
if (request.code.toLowerCase().includes(m.dependency.name.toLowerCase())) {
|
|
35
|
+
matched = m;
|
|
36
|
+
break;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
if (matched) {
|
|
42
|
+
effectiveDocVersion = effectiveDocVersion || matched.targetVersion;
|
|
43
|
+
projectVersion = matched.dependency.resolvedVersion || matched.dependency.requestedVersion;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
// Fallback gracefully if workspace scan fails
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
// 1. Extract API calls from code
|
|
51
|
+
const extractedCalls = this.extractor.extract(request.code, request.language);
|
|
52
|
+
// 2. Run deterministic schema and version verification
|
|
53
|
+
const result = this.verifier.verify(extractedCalls, {
|
|
54
|
+
docVersion: effectiveDocVersion,
|
|
55
|
+
projectVersion,
|
|
56
|
+
library: request.library,
|
|
57
|
+
});
|
|
58
|
+
// 3. Synthesize human/agent-friendly Markdown summary
|
|
59
|
+
const markdown = this.synthesizeMarkdown(result);
|
|
60
|
+
return { result, markdown };
|
|
61
|
+
}
|
|
62
|
+
synthesizeMarkdown(res) {
|
|
63
|
+
const lines = [];
|
|
64
|
+
const icon = res.verdict === 'verified' ? '✅' : (res.verdict === 'warning' ? '⚠️' : (res.verdict === 'mismatch' ? '❌' : 'ℹ️'));
|
|
65
|
+
lines.push(`### ${icon} API Verification Result: **${res.verdict.toUpperCase()}**\n`);
|
|
66
|
+
lines.push(`> [!SECURITY NOTICE] External schema and documentation data is untrusted. Security boundaries preserved.`);
|
|
67
|
+
lines.push(`- **Summary**: ${res.summary}`);
|
|
68
|
+
if (res.targetVersion)
|
|
69
|
+
lines.push(`- **Target Doc Version**: \`${res.targetVersion}\``);
|
|
70
|
+
if (res.projectVersion)
|
|
71
|
+
lines.push(`- **Project Dependency Version**: \`${res.projectVersion}\``);
|
|
72
|
+
lines.push(`- **Total Checks Evaluated**: ${res.totalChecks}`);
|
|
73
|
+
if (res.findings.length > 0) {
|
|
74
|
+
lines.push('\n#### Findings:');
|
|
75
|
+
for (const f of res.findings) {
|
|
76
|
+
const fIcon = f.severity === 'error' ? '🔴' : (f.severity === 'warning' ? '🟡' : '🔵');
|
|
77
|
+
const loc = f.location?.line ? ` (Line ${f.location.line})` : '';
|
|
78
|
+
lines.push(`- ${fIcon} **[${f.rule.toUpperCase()}]**${loc}: ${f.message}`);
|
|
79
|
+
if (f.location?.snippet) {
|
|
80
|
+
lines.push(` \`\`\`\n ${f.location.snippet}\n \`\`\``);
|
|
81
|
+
}
|
|
82
|
+
if (f.expected)
|
|
83
|
+
lines.push(` - *Expected*: \`${f.expected}\``);
|
|
84
|
+
if (f.actual)
|
|
85
|
+
lines.push(` - *Actual*: \`${f.actual}\``);
|
|
86
|
+
if (f.provenance?.endpointId)
|
|
87
|
+
lines.push(` - *Evidence*: Endpoint ID \`${f.provenance.endpointId}\``);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return lines.join('\n');
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
export class DiffService {
|
|
94
|
+
repo;
|
|
95
|
+
diffEngine;
|
|
96
|
+
constructor(repo) {
|
|
97
|
+
this.repo = repo;
|
|
98
|
+
this.diffEngine = new DocDiffEngine(repo);
|
|
99
|
+
}
|
|
100
|
+
diffDocs(options) {
|
|
101
|
+
const result = this.diffEngine.diff(options);
|
|
102
|
+
const markdown = this.synthesizeMarkdown(result);
|
|
103
|
+
return { result, markdown };
|
|
104
|
+
}
|
|
105
|
+
synthesizeMarkdown(diff) {
|
|
106
|
+
const lines = [];
|
|
107
|
+
const fromLabel = diff.fromVersion ? `v${diff.fromVersion.replace(/^v/, '')}` : (diff.fromSnapshotId || 'previous');
|
|
108
|
+
const toLabel = diff.toVersion ? `v${diff.toVersion.replace(/^v/, '')}` : (diff.toSnapshotId || 'latest');
|
|
109
|
+
lines.push(`### 📊 Documentation Diff: \`${fromLabel}\` ➔ \`${toLabel}\`\n`);
|
|
110
|
+
lines.push(`| Category | Added | Removed | Modified | Deprecated |`);
|
|
111
|
+
lines.push(`| :--- | :---: | :---: | :---: | :---: |`);
|
|
112
|
+
lines.push(`| **Endpoints** | ${diff.summary.endpointsAdded} | ${diff.summary.endpointsRemoved} | ${diff.summary.endpointsModified} | ${diff.summary.endpointsDeprecated} |`);
|
|
113
|
+
lines.push(`| **Pitfalls** | ${diff.summary.pitfallsAdded} | ${diff.summary.pitfallsRemoved} | - | - |`);
|
|
114
|
+
lines.push(`| **Sections** | - | - | ${diff.summary.contentChanged} | - |\n`);
|
|
115
|
+
if (diff.apiChanges.length > 0) {
|
|
116
|
+
lines.push('#### API Endpoint Changes:');
|
|
117
|
+
for (const ch of diff.apiChanges) {
|
|
118
|
+
const badge = ch.changeType === 'added' ? '🟢 ADDED' : (ch.changeType === 'removed' ? '🔴 REMOVED' : (ch.changeType === 'deprecated' ? '🟡 DEPRECATED' : '🔵 MODIFIED'));
|
|
119
|
+
lines.push(`- **[${badge}]** \`${ch.method.toUpperCase()} ${ch.path}\``);
|
|
120
|
+
if (ch.changes && ch.changes.length > 0) {
|
|
121
|
+
for (const detail of ch.changes) {
|
|
122
|
+
lines.push(` - ${detail}`);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
if (diff.pitfallChanges.length > 0) {
|
|
128
|
+
lines.push('\n#### Pitfall & Deprecation Changes:');
|
|
129
|
+
for (const p of diff.pitfallChanges) {
|
|
130
|
+
const badge = p.changeType === 'added' ? '⚠️ NEW' : 'REMOVED';
|
|
131
|
+
lines.push(`- **[${badge}]** \`${p.pitfall.kind}\`: ${p.pitfall.title}`);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return lines.join('\n');
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
export class ImpactAnalysisService {
|
|
138
|
+
repo;
|
|
139
|
+
diffService;
|
|
140
|
+
scanner;
|
|
141
|
+
constructor(repo) {
|
|
142
|
+
this.repo = repo;
|
|
143
|
+
if (repo) {
|
|
144
|
+
this.diffService = new DiffService(repo);
|
|
145
|
+
}
|
|
146
|
+
this.scanner = new WorkspaceImpactScanner();
|
|
147
|
+
}
|
|
148
|
+
analyzeWorkspaceImpact(projectDir, diff) {
|
|
149
|
+
const structured = this.scanner.scan(projectDir, diff);
|
|
150
|
+
const markdown = this.synthesizeMarkdown(structured);
|
|
151
|
+
return { structured, markdown };
|
|
152
|
+
}
|
|
153
|
+
analyzeImpact(options) {
|
|
154
|
+
if (!this.diffService) {
|
|
155
|
+
throw new Error('Repository is required for diff-based impact analysis');
|
|
156
|
+
}
|
|
157
|
+
const { result: diff } = this.diffService.diffDocs({
|
|
158
|
+
fromVersion: options.fromVersion,
|
|
159
|
+
toVersion: options.toVersion,
|
|
160
|
+
fromSnapshotId: options.fromSnapshotId,
|
|
161
|
+
toSnapshotId: options.toSnapshotId,
|
|
162
|
+
sourceId: options.sourceId,
|
|
163
|
+
});
|
|
164
|
+
const result = this.scanner.scan(options.projectDir, diff);
|
|
165
|
+
const markdown = this.synthesizeMarkdown(result);
|
|
166
|
+
return { result, markdown };
|
|
167
|
+
}
|
|
168
|
+
synthesizeMarkdown(res) {
|
|
169
|
+
const lines = [];
|
|
170
|
+
lines.push(`### 🔍 Project Impact Analysis`);
|
|
171
|
+
lines.push(`- **Scanned Workspace**: \`${res.projectDir}\``);
|
|
172
|
+
lines.push(`- **Files Scanned**: ${res.totalFilesScanned}`);
|
|
173
|
+
lines.push(`- **Impacted Files**: ${res.affectedFilesCount}`);
|
|
174
|
+
lines.push(`- **Total Affected Locations**: ${res.affectedLocations.length}\n`);
|
|
175
|
+
if (res.affectedLocations.length === 0) {
|
|
176
|
+
lines.push(`✅ No breaking changes or deprecated API usages detected in current project files.`);
|
|
177
|
+
return lines.join('\n');
|
|
178
|
+
}
|
|
179
|
+
lines.push(`#### Affected Locations:\n`);
|
|
180
|
+
for (const loc of res.affectedLocations) {
|
|
181
|
+
const certBadge = loc.certainty === 'high' ? '🎯 High Certainty' : (loc.certainty === 'medium' ? '⚖️ Medium' : '🔎 Heuristic');
|
|
182
|
+
lines.push(`- **\`${loc.filePath}:${loc.line}\`** (${certBadge}, Confidence: ${Math.round(loc.confidence * 100)}%)`);
|
|
183
|
+
lines.push(` - **Reason**: ${loc.reason}`);
|
|
184
|
+
lines.push(` - **Matched**: \`${loc.matchedPattern}\``);
|
|
185
|
+
lines.push(` \`\`\`\n ${loc.snippet}\n \`\`\``);
|
|
186
|
+
}
|
|
187
|
+
return lines.join('\n');
|
|
188
|
+
}
|
|
189
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ExtractedApiCall, VerificationResult } from '../../shared/src/index.ts';
|
|
2
|
+
import type { DocOrbitRepository } from '../../storage/src/index.ts';
|
|
3
|
+
export interface VerifierOptions {
|
|
4
|
+
docVersion?: string;
|
|
5
|
+
projectVersion?: string;
|
|
6
|
+
library?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare class SchemaVerifier {
|
|
9
|
+
private repo;
|
|
10
|
+
constructor(repo: DocOrbitRepository);
|
|
11
|
+
verify(calls: ExtractedApiCall[], options?: VerifierOptions): VerificationResult;
|
|
12
|
+
private verifyParameters;
|
|
13
|
+
private verifyResponseFields;
|
|
14
|
+
private verifyNextJsParams;
|
|
15
|
+
}
|
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
import { matchEndpointPath } from "./extractor.js";
|
|
2
|
+
export class SchemaVerifier {
|
|
3
|
+
repo;
|
|
4
|
+
constructor(repo) {
|
|
5
|
+
this.repo = repo;
|
|
6
|
+
}
|
|
7
|
+
verify(calls, options = {}) {
|
|
8
|
+
const findings = [];
|
|
9
|
+
const docVersion = options.docVersion;
|
|
10
|
+
const projectVersion = options.projectVersion;
|
|
11
|
+
// Load available endpoints and pitfalls for target version
|
|
12
|
+
const allEndpoints = this.repo.searchApiEndpoints('', {
|
|
13
|
+
docVersion,
|
|
14
|
+
limit: 200,
|
|
15
|
+
});
|
|
16
|
+
const allPitfalls = this.repo.searchPitfalls('', {
|
|
17
|
+
docVersion,
|
|
18
|
+
limit: 100,
|
|
19
|
+
});
|
|
20
|
+
let totalChecks = 0;
|
|
21
|
+
for (let i = 0; i < calls.length; i++) {
|
|
22
|
+
const call = calls[i];
|
|
23
|
+
// Handle ambiguous or unsupported calls
|
|
24
|
+
if (call.isDynamicOrAmbiguous) {
|
|
25
|
+
totalChecks++;
|
|
26
|
+
findings.push({
|
|
27
|
+
id: `find_ambiguous_${i}`,
|
|
28
|
+
rule: 'endpoint_validity',
|
|
29
|
+
severity: 'info',
|
|
30
|
+
status: 'insufficient_evidence',
|
|
31
|
+
message: call.reasonIfAmbiguous || 'Unable to statically verify dynamic or unsupported expression.',
|
|
32
|
+
location: {
|
|
33
|
+
line: call.line,
|
|
34
|
+
snippet: call.rawSnippet,
|
|
35
|
+
},
|
|
36
|
+
confidence: 0.5,
|
|
37
|
+
});
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
// 1. Next.js Version Syntax Checks
|
|
41
|
+
if (call.symbol?.startsWith('nextjs_route_params')) {
|
|
42
|
+
this.verifyNextJsParams(call, projectVersion || docVersion, findings, i);
|
|
43
|
+
totalChecks++;
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
// If no endpoint path was extracted
|
|
47
|
+
if (!call.endpointPath) {
|
|
48
|
+
totalChecks++;
|
|
49
|
+
findings.push({
|
|
50
|
+
id: `find_no_path_${i}`,
|
|
51
|
+
rule: 'endpoint_validity',
|
|
52
|
+
severity: 'info',
|
|
53
|
+
status: 'insufficient_evidence',
|
|
54
|
+
message: 'No API path could be extracted from code call.',
|
|
55
|
+
location: { line: call.line, snippet: call.rawSnippet },
|
|
56
|
+
confidence: 0.5,
|
|
57
|
+
});
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
// 2. Endpoint Path Match
|
|
61
|
+
const matchedEndpoints = allEndpoints.filter(ep => matchEndpointPath(call.endpointPath, ep.path));
|
|
62
|
+
if (matchedEndpoints.length === 0) {
|
|
63
|
+
totalChecks++;
|
|
64
|
+
// Check if endpoint exists in ANY version (to see if removed)
|
|
65
|
+
const removedCheck = this.repo.searchApiEndpoints(call.endpointPath, { limit: 5 });
|
|
66
|
+
const removedPitfall = allPitfalls.find(p => p.kind === 'removed' && (p.relatedApi?.includes(call.endpointPath) || p.content.includes(call.endpointPath)));
|
|
67
|
+
if (removedCheck.length > 0 || removedPitfall) {
|
|
68
|
+
findings.push({
|
|
69
|
+
id: `find_removed_${i}`,
|
|
70
|
+
rule: 'removed_api',
|
|
71
|
+
severity: 'error',
|
|
72
|
+
status: 'mismatch',
|
|
73
|
+
message: `Endpoint "${call.endpointPath}" was removed in API version ${docVersion || 'target'}.`,
|
|
74
|
+
location: { line: call.line, snippet: call.rawSnippet },
|
|
75
|
+
docVersion,
|
|
76
|
+
provenance: removedCheck[0]?.provenance ? {
|
|
77
|
+
sourceUrl: removedCheck[0].provenance.sourceUrl,
|
|
78
|
+
endpointId: removedCheck[0].id,
|
|
79
|
+
} : undefined,
|
|
80
|
+
confidence: 0.95,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
findings.push({
|
|
85
|
+
id: `find_endpoint_${i}`,
|
|
86
|
+
rule: 'endpoint_validity',
|
|
87
|
+
severity: 'error',
|
|
88
|
+
status: 'mismatch',
|
|
89
|
+
message: `Endpoint "${call.endpointPath}" does not exist in API documentation (version: ${docVersion || 'latest'}).`,
|
|
90
|
+
location: { line: call.line, snippet: call.rawSnippet },
|
|
91
|
+
docVersion,
|
|
92
|
+
confidence: 0.9,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
// 3. HTTP Method Match
|
|
98
|
+
const methodLower = (call.method || 'get').toLowerCase();
|
|
99
|
+
const exactMethodEp = matchedEndpoints.find(ep => ep.method.toLowerCase() === methodLower);
|
|
100
|
+
totalChecks++;
|
|
101
|
+
if (!exactMethodEp) {
|
|
102
|
+
const allowed = matchedEndpoints.map(ep => ep.method.toUpperCase()).join(', ');
|
|
103
|
+
findings.push({
|
|
104
|
+
id: `find_method_${i}`,
|
|
105
|
+
rule: 'method_validity',
|
|
106
|
+
severity: 'error',
|
|
107
|
+
status: 'mismatch',
|
|
108
|
+
message: `Endpoint "${call.endpointPath}" does not support HTTP method "${methodLower.toUpperCase()}". Supported methods: [${allowed}].`,
|
|
109
|
+
location: { line: call.line, snippet: call.rawSnippet },
|
|
110
|
+
expected: allowed,
|
|
111
|
+
actual: methodLower.toUpperCase(),
|
|
112
|
+
docVersion,
|
|
113
|
+
provenance: matchedEndpoints[0].provenance ? {
|
|
114
|
+
sourceUrl: matchedEndpoints[0].provenance.sourceUrl,
|
|
115
|
+
endpointId: matchedEndpoints[0].id,
|
|
116
|
+
} : undefined,
|
|
117
|
+
confidence: 0.95,
|
|
118
|
+
});
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
// 4. Deprecation Checks
|
|
122
|
+
totalChecks++;
|
|
123
|
+
if (exactMethodEp.deprecated) {
|
|
124
|
+
findings.push({
|
|
125
|
+
id: `find_dep_${i}`,
|
|
126
|
+
rule: 'deprecation',
|
|
127
|
+
severity: 'warning',
|
|
128
|
+
status: 'warning',
|
|
129
|
+
message: `Endpoint "${exactMethodEp.method.toUpperCase()} ${exactMethodEp.path}" is deprecated in documentation (version: ${docVersion || 'current'}).`,
|
|
130
|
+
location: { line: call.line, snippet: call.rawSnippet },
|
|
131
|
+
docVersion,
|
|
132
|
+
provenance: exactMethodEp.provenance ? {
|
|
133
|
+
sourceUrl: exactMethodEp.provenance.sourceUrl,
|
|
134
|
+
endpointId: exactMethodEp.id,
|
|
135
|
+
} : undefined,
|
|
136
|
+
confidence: 1.0,
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
// Check for related deprecation pitfalls
|
|
140
|
+
const depPitfall = allPitfalls.find(p => p.kind === 'deprecated' && (p.relatedApi?.includes(exactMethodEp.path) || p.content.includes(exactMethodEp.path)));
|
|
141
|
+
if (depPitfall) {
|
|
142
|
+
findings.push({
|
|
143
|
+
id: `find_dep_pit_${i}`,
|
|
144
|
+
rule: 'deprecation',
|
|
145
|
+
severity: 'warning',
|
|
146
|
+
status: 'warning',
|
|
147
|
+
message: `Deprecation notice for ${exactMethodEp.path}: ${depPitfall.title}`,
|
|
148
|
+
location: { line: call.line, snippet: call.rawSnippet },
|
|
149
|
+
docVersion,
|
|
150
|
+
provenance: depPitfall.provenance ? {
|
|
151
|
+
sourceUrl: depPitfall.provenance.sourceUrl,
|
|
152
|
+
pitfallId: depPitfall.id,
|
|
153
|
+
} : undefined,
|
|
154
|
+
confidence: 0.9,
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
// 5. Required Parameters & Body Fields
|
|
158
|
+
totalChecks++;
|
|
159
|
+
this.verifyParameters(call, exactMethodEp, findings, i, docVersion);
|
|
160
|
+
// 6. Response Assumptions
|
|
161
|
+
if (call.responseFieldsAccessed && call.responseFieldsAccessed.length > 0 && exactMethodEp.responseSchema) {
|
|
162
|
+
totalChecks++;
|
|
163
|
+
this.verifyResponseFields(call, exactMethodEp, findings, i, docVersion);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
// Determine overall verdict
|
|
167
|
+
let verdict = 'verified';
|
|
168
|
+
if (findings.some(f => f.status === 'mismatch')) {
|
|
169
|
+
verdict = 'mismatch';
|
|
170
|
+
}
|
|
171
|
+
else if (findings.some(f => f.status === 'warning')) {
|
|
172
|
+
verdict = 'warning';
|
|
173
|
+
}
|
|
174
|
+
else if (findings.length > 0 && findings.every(f => f.status === 'insufficient_evidence')) {
|
|
175
|
+
verdict = 'insufficient_evidence';
|
|
176
|
+
}
|
|
177
|
+
// Build summary string
|
|
178
|
+
let summary;
|
|
179
|
+
const mismatches = findings.filter(f => f.status === 'mismatch').length;
|
|
180
|
+
const warnings = findings.filter(f => f.status === 'warning').length;
|
|
181
|
+
if (verdict === 'verified') {
|
|
182
|
+
summary = `All ${totalChecks} check(s) verified successfully against API documentation${docVersion ? ` (${docVersion})` : ''}.`;
|
|
183
|
+
}
|
|
184
|
+
else if (verdict === 'mismatch') {
|
|
185
|
+
summary = `Verification failed with ${mismatches} mismatch(es) and ${warnings} warning(s).`;
|
|
186
|
+
}
|
|
187
|
+
else if (verdict === 'warning') {
|
|
188
|
+
summary = `Verification passed with ${warnings} warning(s) (e.g. deprecated APIs or unverified fields).`;
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
summary = 'Verification inconclusive: insufficient evidence or unsupported expressions in code.';
|
|
192
|
+
}
|
|
193
|
+
return {
|
|
194
|
+
verdict,
|
|
195
|
+
summary,
|
|
196
|
+
targetVersion: docVersion,
|
|
197
|
+
projectVersion,
|
|
198
|
+
matchedLibrary: options.library,
|
|
199
|
+
findings,
|
|
200
|
+
extractedCalls: calls,
|
|
201
|
+
totalChecks,
|
|
202
|
+
untrusted: true,
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
verifyParameters(call, ep, findings, idx, docVersion) {
|
|
206
|
+
const requiredParams = ep.parameters.filter(p => p.required);
|
|
207
|
+
const bodyFields = new Set(call.bodyFields || []);
|
|
208
|
+
// Check required query/path parameters
|
|
209
|
+
for (const req of requiredParams) {
|
|
210
|
+
if (req.in === 'path') {
|
|
211
|
+
// Path parameters are verified by URL structure match
|
|
212
|
+
continue;
|
|
213
|
+
}
|
|
214
|
+
if (!bodyFields.has(req.name) && !(call.parameters && req.name in call.parameters)) {
|
|
215
|
+
findings.push({
|
|
216
|
+
id: `find_req_param_${idx}_${req.name}`,
|
|
217
|
+
rule: 'required_parameters',
|
|
218
|
+
severity: 'error',
|
|
219
|
+
status: 'mismatch',
|
|
220
|
+
message: `Missing required parameter "${req.name}" (${req.in}) for ${ep.method.toUpperCase()} ${ep.path}.`,
|
|
221
|
+
location: { line: call.line, snippet: call.rawSnippet },
|
|
222
|
+
expected: req.name,
|
|
223
|
+
docVersion,
|
|
224
|
+
provenance: ep.provenance ? {
|
|
225
|
+
sourceUrl: ep.provenance.sourceUrl,
|
|
226
|
+
endpointId: ep.id,
|
|
227
|
+
} : undefined,
|
|
228
|
+
confidence: 0.95,
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
// Check request body schema required fields
|
|
233
|
+
if (ep.requestSchema?.required && Array.isArray(ep.requestSchema.required)) {
|
|
234
|
+
for (const reqField of ep.requestSchema.required) {
|
|
235
|
+
if (!bodyFields.has(reqField)) {
|
|
236
|
+
findings.push({
|
|
237
|
+
id: `find_req_body_${idx}_${reqField}`,
|
|
238
|
+
rule: 'required_parameters',
|
|
239
|
+
severity: 'error',
|
|
240
|
+
status: 'mismatch',
|
|
241
|
+
message: `Missing required body field "${reqField}" for ${ep.method.toUpperCase()} ${ep.path}.`,
|
|
242
|
+
location: { line: call.line, snippet: call.rawSnippet },
|
|
243
|
+
expected: reqField,
|
|
244
|
+
docVersion,
|
|
245
|
+
provenance: ep.provenance ? {
|
|
246
|
+
sourceUrl: ep.provenance.sourceUrl,
|
|
247
|
+
endpointId: ep.id,
|
|
248
|
+
} : undefined,
|
|
249
|
+
confidence: 0.95,
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
verifyResponseFields(call, ep, findings, idx, docVersion) {
|
|
256
|
+
// Collect all documented response property names across 200/201 schemas
|
|
257
|
+
const documentedProps = new Set();
|
|
258
|
+
for (const [status, resp] of Object.entries(ep.responseSchema || {})) {
|
|
259
|
+
if (status.startsWith('2') && resp.schema?.properties) {
|
|
260
|
+
for (const propName of Object.keys(resp.schema.properties)) {
|
|
261
|
+
documentedProps.add(propName);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
if (documentedProps.size === 0)
|
|
266
|
+
return;
|
|
267
|
+
for (const accessedField of call.responseFieldsAccessed || []) {
|
|
268
|
+
if (!documentedProps.has(accessedField)) {
|
|
269
|
+
findings.push({
|
|
270
|
+
id: `find_resp_${idx}_${accessedField}`,
|
|
271
|
+
rule: 'response_assumption',
|
|
272
|
+
severity: 'warning',
|
|
273
|
+
status: 'warning',
|
|
274
|
+
message: `Field "${accessedField}" accessed from response is not in documented 2xx response schema for ${ep.method.toUpperCase()} ${ep.path}.`,
|
|
275
|
+
location: { line: call.line, snippet: call.rawSnippet },
|
|
276
|
+
actual: accessedField,
|
|
277
|
+
docVersion,
|
|
278
|
+
provenance: ep.provenance ? {
|
|
279
|
+
sourceUrl: ep.provenance.sourceUrl,
|
|
280
|
+
endpointId: ep.id,
|
|
281
|
+
} : undefined,
|
|
282
|
+
confidence: 0.75,
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
verifyNextJsParams(call, version, findings, idx) {
|
|
288
|
+
const isV14 = version?.includes('14') || version?.startsWith('v14');
|
|
289
|
+
const isV15OrAbove = version?.includes('15') || version?.includes('16') || version?.startsWith('v15') || version?.startsWith('v16');
|
|
290
|
+
if (call.symbol === 'nextjs_route_params_async' && isV14) {
|
|
291
|
+
findings.push({
|
|
292
|
+
id: `find_nextjs_${idx}`,
|
|
293
|
+
rule: 'version_mismatch',
|
|
294
|
+
severity: 'error',
|
|
295
|
+
status: 'mismatch',
|
|
296
|
+
message: 'Next.js 14 requires synchronous route params ("params.slug"). "await params" is only supported in Next.js 15+.',
|
|
297
|
+
location: { line: call.line, snippet: call.rawSnippet },
|
|
298
|
+
docVersion: version,
|
|
299
|
+
confidence: 0.95,
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
else if (call.symbol === 'nextjs_route_params_sync' && isV15OrAbove) {
|
|
303
|
+
findings.push({
|
|
304
|
+
id: `find_nextjs_${idx}`,
|
|
305
|
+
rule: 'deprecation',
|
|
306
|
+
severity: 'warning',
|
|
307
|
+
status: 'warning',
|
|
308
|
+
message: 'Synchronous route params ("params.slug") is deprecated in Next.js 15 and removed in Next.js 16. Use "await params".',
|
|
309
|
+
location: { line: call.line, snippet: call.rawSnippet },
|
|
310
|
+
docVersion: version,
|
|
311
|
+
confidence: 0.95,
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { WorkspaceScanResult } from '../../shared/src/index.ts';
|
|
2
|
+
import { type EcosystemStrategy } from './ecosystems/index.ts';
|
|
3
|
+
/**
|
|
4
|
+
* Scans a workspace directory, detects package manifests across supported ecosystems,
|
|
5
|
+
* correlates lockfiles with resolved versions, and preserves monorepo boundaries.
|
|
6
|
+
*/
|
|
7
|
+
export declare function detectWorkspaceDependencies(workspaceDir: string, strategies?: EcosystemStrategy[]): WorkspaceScanResult;
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { readFileSync, readdirSync } from 'node:fs';
|
|
2
|
+
import { join, relative } from 'node:path';
|
|
3
|
+
import { getDefaultStrategies, } from "./ecosystems/index.js";
|
|
4
|
+
const IGNORED_DIRS = new Set([
|
|
5
|
+
'node_modules',
|
|
6
|
+
'.git',
|
|
7
|
+
'.docorbit',
|
|
8
|
+
'dist',
|
|
9
|
+
'build',
|
|
10
|
+
'target',
|
|
11
|
+
'vendor',
|
|
12
|
+
'.venv',
|
|
13
|
+
'venv',
|
|
14
|
+
'.next',
|
|
15
|
+
'.turbo',
|
|
16
|
+
]);
|
|
17
|
+
/**
|
|
18
|
+
* Recursively locates files in a directory up to a max depth, skipping ignored folders.
|
|
19
|
+
*/
|
|
20
|
+
function findManifestFiles(dir, targetFileNames, maxDepth = 4, currentDepth = 0) {
|
|
21
|
+
if (currentDepth > maxDepth)
|
|
22
|
+
return [];
|
|
23
|
+
const results = [];
|
|
24
|
+
try {
|
|
25
|
+
const entries = readdirSync(dir, { withFileTypes: true });
|
|
26
|
+
for (const entry of entries) {
|
|
27
|
+
if (IGNORED_DIRS.has(entry.name))
|
|
28
|
+
continue;
|
|
29
|
+
const fullPath = join(dir, entry.name);
|
|
30
|
+
if (entry.isDirectory()) {
|
|
31
|
+
results.push(...findManifestFiles(fullPath, targetFileNames, maxDepth, currentDepth + 1));
|
|
32
|
+
}
|
|
33
|
+
else if (entry.isFile()) {
|
|
34
|
+
const name = entry.name.toLowerCase();
|
|
35
|
+
if (targetFileNames.has(name)) {
|
|
36
|
+
results.push(fullPath);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
// Directory unreadable, ignore
|
|
43
|
+
}
|
|
44
|
+
return results;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Scans a workspace directory, detects package manifests across supported ecosystems,
|
|
48
|
+
* correlates lockfiles with resolved versions, and preserves monorepo boundaries.
|
|
49
|
+
*/
|
|
50
|
+
export function detectWorkspaceDependencies(workspaceDir, strategies = getDefaultStrategies()) {
|
|
51
|
+
// Index strategies by manifest and lockfile names
|
|
52
|
+
const manifestMap = new Map();
|
|
53
|
+
const lockfileMap = new Map();
|
|
54
|
+
const allTargetNames = new Set();
|
|
55
|
+
for (const strat of strategies) {
|
|
56
|
+
for (const mName of strat.manifestNames) {
|
|
57
|
+
const lower = mName.toLowerCase();
|
|
58
|
+
manifestMap.set(lower, strat);
|
|
59
|
+
allTargetNames.add(lower);
|
|
60
|
+
}
|
|
61
|
+
if (strat.lockfileNames) {
|
|
62
|
+
for (const lName of strat.lockfileNames) {
|
|
63
|
+
const lower = lName.toLowerCase();
|
|
64
|
+
lockfileMap.set(lower, strat);
|
|
65
|
+
allTargetNames.add(lower);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
const manifests = findManifestFiles(workspaceDir, allTargetNames);
|
|
70
|
+
const ecosystems = new Set();
|
|
71
|
+
const dependencies = [];
|
|
72
|
+
const manifestsFound = [];
|
|
73
|
+
// 1. Gather all lockfiles first to correlate resolved versions
|
|
74
|
+
const lockfileCache = new Map();
|
|
75
|
+
for (const file of manifests) {
|
|
76
|
+
const rel = relative(workspaceDir, file);
|
|
77
|
+
manifestsFound.push(rel);
|
|
78
|
+
const baseName = file.split(/[/\\]/).pop()?.toLowerCase() || '';
|
|
79
|
+
const lockStrategy = lockfileMap.get(baseName);
|
|
80
|
+
if (lockStrategy && lockStrategy.parseLockfile) {
|
|
81
|
+
try {
|
|
82
|
+
const content = readFileSync(file, 'utf-8');
|
|
83
|
+
lockfileCache.set(rel, lockStrategy.parseLockfile(baseName, content));
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
// Ignore unreadable lockfile
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
// 2. Parse package manifests and resolve versions
|
|
91
|
+
for (const file of manifests) {
|
|
92
|
+
const rel = relative(workspaceDir, file);
|
|
93
|
+
const baseName = file.split(/[/\\]/).pop()?.toLowerCase() || '';
|
|
94
|
+
const pkgDir = rel.includes('/') ? rel.slice(0, rel.lastIndexOf('/')) : '.';
|
|
95
|
+
const strat = manifestMap.get(baseName);
|
|
96
|
+
if (strat) {
|
|
97
|
+
try {
|
|
98
|
+
const content = readFileSync(file, 'utf-8');
|
|
99
|
+
ecosystems.add(strat.ecosystem);
|
|
100
|
+
const parsed = strat.parseManifest(baseName, content, rel, pkgDir);
|
|
101
|
+
if (strat.resolveVersions) {
|
|
102
|
+
strat.resolveVersions(parsed, pkgDir, lockfileCache);
|
|
103
|
+
}
|
|
104
|
+
dependencies.push(...parsed);
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
// Ignore parse failure
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return {
|
|
112
|
+
workspaceRoot: workspaceDir,
|
|
113
|
+
ecosystems: Array.from(ecosystems),
|
|
114
|
+
manifestsFound,
|
|
115
|
+
dependencies,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ProjectDependency } from '../../../shared/src/index.ts';
|
|
2
|
+
import type { EcosystemStrategy } from './types.ts';
|
|
3
|
+
export declare class CargoStrategy implements EcosystemStrategy {
|
|
4
|
+
readonly ecosystem = "cargo";
|
|
5
|
+
readonly manifestNames: string[];
|
|
6
|
+
readonly lockfileNames: string[];
|
|
7
|
+
parseManifest(_fileName: string, content: string, relPath: string, packageDir: string): ProjectDependency[];
|
|
8
|
+
parseLockfile(_fileName: string, content: string): Map<string, string>;
|
|
9
|
+
resolveVersions(deps: ProjectDependency[], pkgDir: string, lockfileCache: Map<string, Map<string, string>>): void;
|
|
10
|
+
}
|