kibi-cli 2.0.0 → 2.2.0
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/dist/cli-protocol.d.ts.map +1 -1
- package/dist/cli-protocol.js +3 -2
- package/dist/cli-register-proof.d.ts.map +1 -1
- package/dist/cli-register-proof.js +25 -1
- package/dist/cli-register-reporting.d.ts.map +1 -1
- package/dist/cli-register-reporting.js +6 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +2 -0
- package/dist/commands/aggregated-checks.d.ts +7 -0
- package/dist/commands/aggregated-checks.d.ts.map +1 -1
- package/dist/commands/aggregated-checks.js +25 -1
- package/dist/commands/check-generated.d.ts +7 -0
- package/dist/commands/check-generated.d.ts.map +1 -0
- package/dist/commands/check-generated.js +192 -0
- package/dist/commands/check.d.ts.map +1 -1
- package/dist/commands/check.js +24 -15
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +227 -25
- package/dist/commands/engine.d.ts.map +1 -1
- package/dist/commands/engine.js +3 -1
- package/dist/commands/github-init.d.ts +1 -1
- package/dist/commands/github-init.d.ts.map +1 -1
- package/dist/commands/github-init.js +1 -1
- package/dist/commands/init-helpers.d.ts +17 -2
- package/dist/commands/init-helpers.d.ts.map +1 -1
- package/dist/commands/init-helpers.js +136 -30
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +110 -15
- package/dist/commands/proof-explain.d.ts +10 -0
- package/dist/commands/proof-explain.d.ts.map +1 -0
- package/dist/commands/proof-explain.js +45 -0
- package/dist/commands/proof-impact.d.ts +7 -0
- package/dist/commands/proof-impact.d.ts.map +1 -0
- package/dist/commands/proof-impact.js +39 -0
- package/dist/commands/proof-migrate-legacy.js +1 -1
- package/dist/commands/proof-prune.js +1 -1
- package/dist/commands/prove.d.ts.map +1 -1
- package/dist/commands/prove.js +14 -22
- package/dist/commands/report.d.ts.map +1 -1
- package/dist/commands/report.js +17 -2
- package/dist/commands/sync/cache.d.ts +20 -1
- package/dist/commands/sync/cache.d.ts.map +1 -1
- package/dist/commands/sync/cache.js +51 -2
- package/dist/commands/sync/discovery.d.ts.map +1 -1
- package/dist/commands/sync/discovery.js +1 -1
- package/dist/commands/sync/manifest.d.ts +1 -0
- package/dist/commands/sync/manifest.d.ts.map +1 -1
- package/dist/commands/sync/manifest.js +18 -16
- package/dist/commands/sync/persistence.d.ts.map +1 -1
- package/dist/commands/sync/persistence.js +14 -0
- package/dist/commands/sync.d.ts.map +1 -1
- package/dist/commands/sync.js +11 -3
- package/dist/engine.d.ts +29 -1
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +259 -89
- package/dist/env/bootstrap.d.ts +84 -0
- package/dist/env/bootstrap.d.ts.map +1 -0
- package/dist/env/bootstrap.js +310 -0
- package/dist/extractors/manifest.d.ts.map +1 -1
- package/dist/extractors/manifest.js +67 -29
- package/dist/extractors/markdown.d.ts +4 -0
- package/dist/extractors/markdown.d.ts.map +1 -1
- package/dist/extractors/markdown.js +33 -3
- package/dist/extractors/relationships.d.ts.map +1 -1
- package/dist/extractors/relationships.js +1 -0
- package/dist/extractors/symbols-coordinator.d.ts +8 -0
- package/dist/extractors/symbols-coordinator.d.ts.map +1 -1
- package/dist/extractors/symbols-coordinator.js +40 -0
- package/dist/extractors/symbols-ts.d.ts +8 -19
- package/dist/extractors/symbols-ts.d.ts.map +1 -1
- package/dist/extractors/symbols-ts.js +33 -503
- package/dist/intent-search.d.ts.map +1 -1
- package/dist/intent-search.js +68 -30
- package/dist/operations/bootstrap/generate.d.ts.map +1 -1
- package/dist/operations/bootstrap/generate.js +4 -3
- package/dist/operations/modeling/model-requirement.d.ts +1 -1
- package/dist/operations/modeling/model-requirement.d.ts.map +1 -1
- package/dist/operations/modeling/model-requirement.js +179 -9
- package/dist/operations/modeling/predicate-applyplan.d.ts.map +1 -1
- package/dist/operations/modeling/predicate-applyplan.js +14 -2
- package/dist/operations/modeling/predicate-loader.d.ts.map +1 -1
- package/dist/operations/modeling/predicate-loader.js +24 -0
- package/dist/operations/modeling/predicate-types.d.ts +4 -0
- package/dist/operations/modeling/predicate-types.d.ts.map +1 -1
- package/dist/operations/modeling/predicate-vocabulary.d.ts +54 -0
- package/dist/operations/modeling/predicate-vocabulary.d.ts.map +1 -0
- package/dist/operations/modeling/predicate-vocabulary.js +169 -0
- package/dist/operations/modeling/requirement-types.d.ts +5 -0
- package/dist/operations/modeling/requirement-types.d.ts.map +1 -1
- package/dist/operations/modeling/suggest-predicates.d.ts +1 -1
- package/dist/operations/modeling/suggest-predicates.d.ts.map +1 -1
- package/dist/operations/modeling/suggest-predicates.js +30 -3
- package/dist/operations/modeling/vocabulary-alignment.d.ts +60 -0
- package/dist/operations/modeling/vocabulary-alignment.d.ts.map +1 -0
- package/dist/operations/modeling/vocabulary-alignment.js +178 -0
- package/dist/operations/mutation/contradictions.d.ts +3 -0
- package/dist/operations/mutation/contradictions.d.ts.map +1 -1
- package/dist/operations/mutation/contradictions.js +29 -0
- package/dist/operations/mutation/delete.d.ts.map +1 -1
- package/dist/operations/mutation/delete.js +33 -1
- package/dist/operations/mutation/predicate-vocabulary-guard.d.ts +8 -0
- package/dist/operations/mutation/predicate-vocabulary-guard.d.ts.map +1 -0
- package/dist/operations/mutation/predicate-vocabulary-guard.js +64 -0
- package/dist/operations/mutation/relationships.d.ts +1 -1
- package/dist/operations/mutation/relationships.d.ts.map +1 -1
- package/dist/operations/mutation/relationships.js +1 -0
- package/dist/operations/mutation/saga.d.ts +5 -0
- package/dist/operations/mutation/saga.d.ts.map +1 -1
- package/dist/operations/mutation/saga.js +10 -0
- package/dist/operations/mutation/serialization.d.ts.map +1 -1
- package/dist/operations/mutation/serialization.js +2 -0
- package/dist/operations/mutation/source-authoring.d.ts +6 -0
- package/dist/operations/mutation/source-authoring.d.ts.map +1 -1
- package/dist/operations/mutation/source-authoring.js +65 -26
- package/dist/operations/mutation/strict-fact.d.ts.map +1 -1
- package/dist/operations/mutation/strict-fact.js +5 -0
- package/dist/operations/mutation/symbol-granularity.d.ts.map +1 -1
- package/dist/operations/mutation/symbol-granularity.js +9 -87
- package/dist/operations/mutation/types.d.ts +17 -0
- package/dist/operations/mutation/types.d.ts.map +1 -1
- package/dist/operations/mutation/upsert.d.ts +6 -0
- package/dist/operations/mutation/upsert.d.ts.map +1 -1
- package/dist/operations/mutation/upsert.js +72 -4
- package/dist/operations/mutation/validate-upsert.d.ts.map +1 -1
- package/dist/operations/mutation/validate-upsert.js +24 -1
- package/dist/operations/mutation/validation.d.ts.map +1 -1
- package/dist/operations/mutation/validation.js +16 -3
- package/dist/operations/planning/apply-plan.d.ts.map +1 -1
- package/dist/operations/planning/apply-plan.js +61 -17
- package/dist/operations/planning/compile-intent.d.ts +49 -0
- package/dist/operations/planning/compile-intent.d.ts.map +1 -1
- package/dist/operations/planning/compile-intent.js +66 -4
- package/dist/operations/proof/baseline-diff.d.ts +41 -0
- package/dist/operations/proof/baseline-diff.d.ts.map +1 -0
- package/dist/operations/proof/baseline-diff.js +153 -0
- package/dist/operations/proof/code-scope.d.ts +17 -0
- package/dist/operations/proof/code-scope.d.ts.map +1 -0
- package/dist/operations/proof/code-scope.js +60 -0
- package/dist/operations/proof/explain.d.ts +75 -0
- package/dist/operations/proof/explain.d.ts.map +1 -0
- package/dist/operations/proof/explain.js +294 -0
- package/dist/operations/proof/impact.d.ts +45 -0
- package/dist/operations/proof/impact.d.ts.map +1 -0
- package/dist/operations/proof/impact.js +118 -0
- package/dist/operations/proof/ingest-proof.d.ts +4 -2
- package/dist/operations/proof/ingest-proof.d.ts.map +1 -1
- package/dist/operations/proof/ingest-proof.js +251 -77
- package/dist/operations/proof/migrate-legacy-receipts.d.ts.map +1 -1
- package/dist/operations/proof/migrate-legacy-receipts.js +28 -22
- package/dist/operations/proof/prune-receipts.d.ts.map +1 -1
- package/dist/operations/proof/prune-receipts.js +8 -6
- package/dist/operations/proof/receipt-document.js +2 -2
- package/dist/operations/semantic-advisor/analysis-receipt.d.ts.map +1 -1
- package/dist/operations/semantic-advisor/analysis-receipt.js +3 -9
- package/dist/operations/semantic-advisor/analyze-prose.d.ts.map +1 -1
- package/dist/operations/semantic-advisor/analyze-prose.js +18 -67
- package/dist/operations/semantic-advisor/plugin-orchestration.d.ts +63 -0
- package/dist/operations/semantic-advisor/plugin-orchestration.d.ts.map +1 -0
- package/dist/operations/semantic-advisor/plugin-orchestration.js +489 -0
- package/dist/operations/semantic-advisor/predicate-rules-core.d.ts +15 -2
- package/dist/operations/semantic-advisor/predicate-rules-core.d.ts.map +1 -1
- package/dist/operations/semantic-advisor/predicate-rules-core.js +7 -140
- package/dist/operations/semantic-advisor/predicate-rules-launcher.d.ts +11 -12
- package/dist/operations/semantic-advisor/predicate-rules-launcher.d.ts.map +1 -1
- package/dist/operations/semantic-advisor/predicate-rules-launcher.js +6 -94
- package/dist/operations/semantic-advisor/predicate-rules-policy.d.ts +16 -0
- package/dist/operations/semantic-advisor/predicate-rules-policy.d.ts.map +1 -1
- package/dist/operations/semantic-advisor/predicate-rules-policy.js +7 -150
- package/dist/operations/semantic-advisor/predicate-rules-product-tail.d.ts +9 -0
- package/dist/operations/semantic-advisor/predicate-rules-product-tail.d.ts.map +1 -1
- package/dist/operations/semantic-advisor/predicate-rules-product-tail.js +7 -102
- package/dist/operations/semantic-advisor/predicate-rules-product.d.ts +13 -0
- package/dist/operations/semantic-advisor/predicate-rules-product.d.ts.map +1 -1
- package/dist/operations/semantic-advisor/predicate-rules-product.js +7 -133
- package/dist/operations/semantic-advisor/types.d.ts +1 -0
- package/dist/operations/semantic-advisor/types.d.ts.map +1 -1
- package/dist/plugins/compose-ontology-packs.d.ts +51 -0
- package/dist/plugins/compose-ontology-packs.d.ts.map +1 -0
- package/dist/plugins/compose-ontology-packs.js +257 -0
- package/dist/plugins/compose-semantic-classifier.d.ts +47 -0
- package/dist/plugins/compose-semantic-classifier.d.ts.map +1 -0
- package/dist/plugins/compose-semantic-classifier.js +216 -0
- package/dist/plugins/compose-vocabulary-alignment.d.ts +23 -0
- package/dist/plugins/compose-vocabulary-alignment.d.ts.map +1 -0
- package/dist/plugins/compose-vocabulary-alignment.js +141 -0
- package/dist/plugins/external-allowlist.d.ts +17 -0
- package/dist/plugins/external-allowlist.d.ts.map +1 -0
- package/dist/plugins/external-allowlist.js +29 -0
- package/dist/plugins/index.d.ts +11 -0
- package/dist/plugins/index.d.ts.map +1 -0
- package/dist/plugins/index.js +37 -0
- package/dist/plugins/load-plugin.d.ts +19 -0
- package/dist/plugins/load-plugin.d.ts.map +1 -0
- package/dist/plugins/load-plugin.js +59 -0
- package/dist/plugins/project-config.d.ts +28 -0
- package/dist/plugins/project-config.d.ts.map +1 -0
- package/dist/plugins/project-config.js +90 -0
- package/dist/plugins/registry.d.ts +94 -0
- package/dist/plugins/registry.d.ts.map +1 -0
- package/dist/plugins/registry.js +359 -0
- package/dist/plugins/resolve-package.d.ts +47 -0
- package/dist/plugins/resolve-package.d.ts.map +1 -0
- package/dist/plugins/resolve-package.js +262 -0
- package/dist/plugins/source-analysis-service.d.ts +44 -0
- package/dist/plugins/source-analysis-service.d.ts.map +1 -0
- package/dist/plugins/source-analysis-service.js +232 -0
- package/dist/prolog/codec.d.ts.map +1 -1
- package/dist/prolog/codec.js +2 -0
- package/dist/prolog/janitor.d.ts.map +1 -1
- package/dist/prolog/janitor.js +1 -1
- package/dist/prolog/store-lock.d.ts +1 -1
- package/dist/prolog/store-lock.d.ts.map +1 -1
- package/dist/prolog.d.ts +36 -0
- package/dist/prolog.d.ts.map +1 -1
- package/dist/prolog.js +78 -9
- package/dist/proof/inspect.js +1 -1
- package/dist/proof/producers/playwright-case-id.js +2 -2
- package/dist/proof/producers/playwright-reporter.js +4 -4
- package/dist/public/diagnostic-usage.d.ts.map +1 -1
- package/dist/public/diagnostic-usage.js +7 -25
- package/dist/public/extractors/symbols-coordinator.d.ts +1 -1
- package/dist/public/extractors/symbols-coordinator.d.ts.map +1 -1
- package/dist/public/extractors/symbols-coordinator.js +1 -1
- package/dist/public/impact/analyzer.d.ts +1 -1
- package/dist/public/impact/analyzer.d.ts.map +1 -1
- package/dist/public/impact/analyzer.js +6 -4
- package/dist/public/impact/full-kb-quality.d.ts.map +1 -1
- package/dist/public/impact/full-kb-quality.js +4 -12
- package/dist/public/operations/catalog.d.ts +39 -7
- package/dist/public/operations/catalog.d.ts.map +1 -1
- package/dist/public/operations/check-executor.d.ts.map +1 -1
- package/dist/public/operations/check-executor.js +11 -3
- package/dist/public/operations/check-helpers.d.ts +7 -1
- package/dist/public/operations/check-helpers.d.ts.map +1 -1
- package/dist/public/operations/check-helpers.js +22 -2
- package/dist/public/operations/contracts.d.ts.map +1 -1
- package/dist/public/operations/contracts.js +51 -12
- package/dist/public/operations/discovery-entities.d.ts +53 -1
- package/dist/public/operations/discovery-entities.d.ts.map +1 -1
- package/dist/public/operations/discovery-entities.js +219 -12
- package/dist/public/operations/discovery-executors.d.ts +1 -0
- package/dist/public/operations/discovery-executors.d.ts.map +1 -1
- package/dist/public/operations/discovery-executors.js +93 -59
- package/dist/public/operations/migration-plan.d.ts +2 -0
- package/dist/public/operations/migration-plan.d.ts.map +1 -1
- package/dist/public/operations/migration-plan.js +50 -0
- package/dist/public/operations/predicate-schema-conformance.d.ts +41 -0
- package/dist/public/operations/predicate-schema-conformance.d.ts.map +1 -0
- package/dist/public/operations/predicate-schema-conformance.js +242 -0
- package/dist/public/operations/prolog-json.d.ts +1 -1
- package/dist/public/operations/prolog-json.d.ts.map +1 -1
- package/dist/public/operations/prolog-json.js +16 -10
- package/dist/public/operations/result-envelope.d.ts +34 -1
- package/dist/public/operations/result-envelope.d.ts.map +1 -1
- package/dist/public/operations/result-envelope.js +78 -2
- package/dist/public/operations/runtime-types.d.ts +17 -2
- package/dist/public/operations/runtime-types.d.ts.map +1 -1
- package/dist/public/operations/specs/check-rules.generated.d.ts +1 -1
- package/dist/public/operations/specs/check-rules.generated.d.ts.map +1 -1
- package/dist/public/operations/specs/check-rules.generated.js +9 -1
- package/dist/public/operations/specs/check.d.ts +1 -1
- package/dist/public/operations/specs/discovery.d.ts +10 -1
- package/dist/public/operations/specs/discovery.d.ts.map +1 -1
- package/dist/public/operations/specs/discovery.js +10 -1
- package/dist/public/operations/specs/mutation-schemas.d.ts +27 -4
- package/dist/public/operations/specs/mutation-schemas.d.ts.map +1 -1
- package/dist/public/operations/specs/mutation-schemas.js +21 -3
- package/dist/public/operations/specs/proof.js +1 -1
- package/dist/public/operations/specs/reporting.d.ts +9 -0
- package/dist/public/operations/specs/reporting.d.ts.map +1 -1
- package/dist/public/operations/specs/reporting.js +48 -17
- package/dist/public/operations/specs/semantic.d.ts +1 -1
- package/dist/public/operations/specs/semantic.d.ts.map +1 -1
- package/dist/public/operations/specs/semantic.js +54 -4
- package/dist/public/operations/specs/upsert.d.ts +28 -5
- package/dist/public/operations/specs/upsert.d.ts.map +1 -1
- package/dist/public/operations/specs/upsert.js +1 -1
- package/dist/public/operations/symbol-repair-plan.d.ts.map +1 -1
- package/dist/public/operations/symbol-repair-plan.js +11 -4
- package/dist/public/operations/types.d.ts +5 -0
- package/dist/public/operations/types.d.ts.map +1 -1
- package/dist/public/proof-protocol.js +4 -4
- package/dist/public/schemas/entity.d.ts.map +1 -1
- package/dist/public/schemas/entity.js +22 -0
- package/dist/public/schemas/relationship.d.ts.map +1 -1
- package/dist/public/schemas/relationship.js +1 -0
- package/dist/public/skills/kibi-usage/SKILL.md +10 -3
- package/dist/public/skills/kibi-usage/resources/fact-lanes.md +4 -0
- package/dist/public/skills/kibi-usage/resources/proof.md +45 -0
- package/dist/public/skills/kibi-usage/resources/relationship-directions.md +35 -17
- package/dist/public/skills/kibi-usage/resources/source-authoring.md +36 -0
- package/dist/public/skills/kibi-usage/resources/workflows.md +52 -1
- package/dist/public/symbol-granularity.d.ts +1 -1
- package/dist/public/symbol-granularity.d.ts.map +1 -1
- package/dist/public/symbol-granularity.generated.d.ts.map +1 -1
- package/dist/public/symbol-granularity.generated.js +38 -5
- package/dist/public/telemetry-acceptance.d.ts.map +1 -1
- package/dist/public/telemetry-acceptance.js +21 -5
- package/dist/relationships/shards.d.ts +6 -0
- package/dist/relationships/shards.d.ts.map +1 -1
- package/dist/relationships/shards.js +26 -19
- package/dist/report/html-report.css +1239 -281
- package/dist/runtime/cli-runtime.d.ts.map +1 -1
- package/dist/runtime/cli-runtime.js +18 -0
- package/dist/schemas/entity.schema.json +32 -0
- package/dist/traceability/staged-diagnostics.d.ts +1 -1
- package/dist/traceability/staged-diagnostics.d.ts.map +1 -1
- package/dist/traceability/staged-entity-id-style.d.ts +12 -0
- package/dist/traceability/staged-entity-id-style.d.ts.map +1 -0
- package/dist/traceability/staged-entity-id-style.js +68 -0
- package/dist/traceability/symbol-extract.d.ts +24 -7
- package/dist/traceability/symbol-extract.d.ts.map +1 -1
- package/dist/traceability/symbol-extract.js +64 -208
- package/dist/traceability/temp-kb.d.ts.map +1 -1
- package/dist/traceability/temp-kb.js +8 -0
- package/dist/traceability/validate.js +1 -1
- package/dist/types/entities.d.ts +2 -0
- package/dist/types/entities.d.ts.map +1 -1
- package/dist/types/relationships.d.ts +1 -1
- package/dist/types/relationships.d.ts.map +1 -1
- package/dist/utils/entity-id-style.d.ts +27 -0
- package/dist/utils/entity-id-style.d.ts.map +1 -0
- package/dist/utils/entity-id-style.js +81 -0
- package/dist/utils/git-repository-context.d.ts +50 -0
- package/dist/utils/git-repository-context.d.ts.map +1 -0
- package/dist/utils/git-repository-context.js +259 -0
- package/dist/utils/rule-registry.d.ts +5 -0
- package/dist/utils/rule-registry.d.ts.map +1 -1
- package/dist/utils/rule-registry.generated.d.ts +42 -0
- package/dist/utils/rule-registry.generated.d.ts.map +1 -1
- package/dist/utils/rule-registry.generated.js +50 -0
- package/dist/utils/strict-modeling.d.ts +7 -0
- package/dist/utils/strict-modeling.d.ts.map +1 -1
- package/dist/utils/strict-modeling.js +11 -0
- package/package.json +14 -11
- package/schema/entities.pl +60 -1
- package/schema/relationships.pl +17 -4
- package/schema/validation.pl +118 -20
- package/src/public/diagnostic-usage.ts +16 -24
- package/src/public/extractors/symbols-coordinator.ts +1 -0
- package/src/public/impact/analyzer.ts +15 -12
- package/src/public/impact/full-kb-quality.ts +4 -16
- package/src/public/operations/check-executor.ts +13 -2
- package/src/public/operations/check-helpers.ts +29 -3
- package/src/public/operations/contracts.ts +59 -12
- package/src/public/operations/discovery-entities.ts +327 -12
- package/src/public/operations/discovery-executors.ts +110 -61
- package/src/public/operations/migration-plan.ts +57 -0
- package/src/public/operations/predicate-schema-conformance.ts +362 -0
- package/src/public/operations/prolog-json.ts +22 -8
- package/src/public/operations/result-envelope.ts +114 -2
- package/src/public/operations/runtime-types.ts +22 -3
- package/src/public/operations/specs/check-rules.generated.ts +9 -1
- package/src/public/operations/specs/discovery.ts +11 -1
- package/src/public/operations/specs/mutation-schemas.ts +23 -3
- package/src/public/operations/specs/proof.ts +1 -1
- package/src/public/operations/specs/reporting.ts +71 -24
- package/src/public/operations/specs/semantic.ts +79 -17
- package/src/public/operations/specs/upsert.ts +1 -1
- package/src/public/operations/symbol-repair-plan.ts +16 -7
- package/src/public/operations/types.ts +5 -0
- package/src/public/proof-fingerprint.ts +1 -1
- package/src/public/proof-protocol-types.d.ts +1 -1
- package/src/public/proof-protocol.ts +4 -4
- package/src/public/schemas/entity.ts +22 -0
- package/src/public/schemas/relationship.ts +1 -0
- package/src/public/skills/kibi-usage/SKILL.md +10 -3
- package/src/public/skills/kibi-usage/resources/fact-lanes.md +4 -0
- package/src/public/skills/kibi-usage/resources/proof.md +45 -0
- package/src/public/skills/kibi-usage/resources/relationship-directions.md +35 -17
- package/src/public/skills/kibi-usage/resources/source-authoring.md +36 -0
- package/src/public/skills/kibi-usage/resources/workflows.md +52 -1
- package/src/public/symbol-granularity.generated.ts +45 -12
- package/src/public/symbol-granularity.ts +3 -3
- package/src/public/telemetry-acceptance.ts +37 -6
- package/src/schemas/entity.schema.json +32 -0
- package/src/schemas/relationship.schema.json +1 -0
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { execSync } from "node:child_process";
|
|
1
2
|
import { readFileSync } from "node:fs";
|
|
2
3
|
import { readFile } from "node:fs/promises";
|
|
3
4
|
import path from "node:path";
|
|
@@ -20,6 +21,8 @@ import path from "node:path";
|
|
|
20
21
|
*/
|
|
21
22
|
import { getKbPlPathOverride } from "../../env.js";
|
|
22
23
|
import { resolveKbPlPath } from "../../prolog.js";
|
|
24
|
+
import { getStagedFiles } from "../../traceability/git-staged.js";
|
|
25
|
+
import { createStagedEntityIdStyleDiagnostics } from "../../traceability/staged-entity-id-style.js";
|
|
23
26
|
import { analyzePrologQueryPlanSafety } from "../../utils/prolog-query-plan-safety.js";
|
|
24
27
|
import {
|
|
25
28
|
RULE_NAMES,
|
|
@@ -63,7 +66,7 @@ export function partitionCheckFindings(findings: readonly Violation[]): {
|
|
|
63
66
|
const definition = getRuleDefinition(finding.rule);
|
|
64
67
|
qualityDiagnostics.push({
|
|
65
68
|
id: `rule.${finding.rule}`,
|
|
66
|
-
severity: "warning",
|
|
69
|
+
severity: definition?.diagnosticSeverity ?? "warning",
|
|
67
70
|
blocking: false,
|
|
68
71
|
category: definition?.category ?? "integrity",
|
|
69
72
|
...(finding.entityId !== undefined ? { entityId: finding.entityId } : {}),
|
|
@@ -144,10 +147,10 @@ export function hasImpactOptions(args: CheckInput): boolean {
|
|
|
144
147
|
}
|
|
145
148
|
|
|
146
149
|
// implements REQ-mcp-tool-check
|
|
147
|
-
export function analyzeKbCheckImpact(
|
|
150
|
+
export async function analyzeKbCheckImpact(
|
|
148
151
|
workspaceRoot: string,
|
|
149
152
|
args: CheckInput,
|
|
150
|
-
): ChangedFileImpactResult | undefined {
|
|
153
|
+
): Promise<ChangedFileImpactResult | undefined> {
|
|
151
154
|
if (!hasImpactOptions(args)) {
|
|
152
155
|
return undefined;
|
|
153
156
|
}
|
|
@@ -169,6 +172,29 @@ export function analyzeKbCheckImpact(
|
|
|
169
172
|
});
|
|
170
173
|
}
|
|
171
174
|
|
|
175
|
+
/**
|
|
176
|
+
* Advisory naming-style review for entity Markdown staged as new. Runs only
|
|
177
|
+
* for `staged: true`, the creation boundary where a purely numeric ID can
|
|
178
|
+
* still be renamed cheaply; committed legacy entities are never evaluated.
|
|
179
|
+
*/
|
|
180
|
+
// implements REQ-kibi-entity-id-style
|
|
181
|
+
export function stagedEntityIdStyleDiagnostics(
|
|
182
|
+
workspaceRoot: string,
|
|
183
|
+
args: Pick<CheckInput, "staged">,
|
|
184
|
+
): readonly QualityDiagnostic[] {
|
|
185
|
+
if (args.staged !== true) return [];
|
|
186
|
+
try {
|
|
187
|
+
return createStagedEntityIdStyleDiagnostics(
|
|
188
|
+
getStagedFiles((command, options) =>
|
|
189
|
+
execSync(command, { ...options, cwd: workspaceRoot }),
|
|
190
|
+
),
|
|
191
|
+
);
|
|
192
|
+
} catch {
|
|
193
|
+
// Outside a Git work tree there is no staged creation boundary.
|
|
194
|
+
return [];
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
|
|
172
198
|
// implements REQ-mcp-tool-check
|
|
173
199
|
export function qualityDiagnosticsFromImpact(
|
|
174
200
|
impactResult: ChangedFileImpactResult | undefined,
|
|
@@ -33,6 +33,25 @@ function objectData(
|
|
|
33
33
|
};
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
/**
|
|
37
|
+
* kibi.job.v1 receipt returned by async-mode operations (kb_check with
|
|
38
|
+
* `async: true`) instead of the synchronous payload. Agents poll
|
|
39
|
+
* kb_job_status with the jobId. Declared as a union member of the operation
|
|
40
|
+
* data contract so hosts validating tool output against the declared schema
|
|
41
|
+
* accept the receipt without weakening the synchronous payload contract.
|
|
42
|
+
*/
|
|
43
|
+
const jobReceiptData: OperationJsonSchema = objectData(
|
|
44
|
+
{
|
|
45
|
+
kibiProtocol: { const: 1 },
|
|
46
|
+
jobVersion: { const: "kibi.job.v1" },
|
|
47
|
+
jobId: { type: "string" },
|
|
48
|
+
tool: { type: "string" },
|
|
49
|
+
status: { type: "string" },
|
|
50
|
+
pollWith: { const: "kb_job_status" },
|
|
51
|
+
},
|
|
52
|
+
["kibiProtocol", "jobVersion", "jobId", "tool", "status", "pollWith"],
|
|
53
|
+
);
|
|
54
|
+
|
|
36
55
|
const stringValue: OperationJsonSchema = { type: "string" };
|
|
37
56
|
const integerValue: OperationJsonSchema = { type: "integer" };
|
|
38
57
|
const numberValue: OperationJsonSchema = { type: "number" };
|
|
@@ -135,6 +154,7 @@ export const OPERATION_DATA_SCHEMAS: Readonly<
|
|
|
135
154
|
kb_semantic_advisor: objectData({
|
|
136
155
|
receipt: recordValue,
|
|
137
156
|
warnings: stringArray,
|
|
157
|
+
capabilityPlugins: recordValue,
|
|
138
158
|
}),
|
|
139
159
|
kb_model_requirement: objectData({
|
|
140
160
|
statement: stringValue,
|
|
@@ -152,6 +172,24 @@ export const OPERATION_DATA_SCHEMAS: Readonly<
|
|
|
152
172
|
warnings: recordArray,
|
|
153
173
|
migrationWarning: { type: ["string", "null"] },
|
|
154
174
|
logic: recordValue,
|
|
175
|
+
vocabularyAlignment: objectData(
|
|
176
|
+
{
|
|
177
|
+
subject: recordValue,
|
|
178
|
+
redundancyCandidates: recordArray,
|
|
179
|
+
reviewPlan: recordArray,
|
|
180
|
+
stamps: recordArray,
|
|
181
|
+
fallbackUsed: booleanValue,
|
|
182
|
+
diagnostics: recordArray,
|
|
183
|
+
},
|
|
184
|
+
[
|
|
185
|
+
"subject",
|
|
186
|
+
"redundancyCandidates",
|
|
187
|
+
"reviewPlan",
|
|
188
|
+
"stamps",
|
|
189
|
+
"fallbackUsed",
|
|
190
|
+
"diagnostics",
|
|
191
|
+
],
|
|
192
|
+
),
|
|
155
193
|
}),
|
|
156
194
|
kb_suggest_predicates: objectData({
|
|
157
195
|
text: stringValue,
|
|
@@ -236,22 +274,30 @@ export const OPERATION_DATA_SCHEMAS: Readonly<
|
|
|
236
274
|
sourceWrites: recordArray,
|
|
237
275
|
deletionPlan: recordValue,
|
|
238
276
|
supersessionPlan: recordValue,
|
|
277
|
+
skippedEffects: stringArray,
|
|
239
278
|
status: stringValue,
|
|
240
279
|
effectFailures: recordArray,
|
|
241
280
|
nextActions: recordArray,
|
|
242
281
|
}),
|
|
243
|
-
kb_check:
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
282
|
+
kb_check: {
|
|
283
|
+
description:
|
|
284
|
+
"Synchronous check payload, or a kibi.job.v1 receipt when async:true detached the check into a background job (poll kb_job_status with the jobId).",
|
|
285
|
+
anyOf: [
|
|
286
|
+
objectData({
|
|
287
|
+
violations: valueArray,
|
|
288
|
+
count: integerValue,
|
|
289
|
+
diagnostics: recordArray,
|
|
290
|
+
qualityDiagnostics: recordArray,
|
|
291
|
+
impactDiagnostics: recordArray,
|
|
292
|
+
sourceFiles: stringArray,
|
|
293
|
+
extractedSymbols: recordArray,
|
|
294
|
+
linkedEntities: recordArray,
|
|
295
|
+
nextActions: valueArray,
|
|
296
|
+
migrationPlan: recordValue,
|
|
297
|
+
}),
|
|
298
|
+
jobReceiptData,
|
|
299
|
+
],
|
|
300
|
+
},
|
|
255
301
|
kb_compile_intent: objectData({
|
|
256
302
|
version: stringValue,
|
|
257
303
|
planHash: stringValue,
|
|
@@ -265,6 +311,7 @@ export const OPERATION_DATA_SCHEMAS: Readonly<
|
|
|
265
311
|
steps: valueArray,
|
|
266
312
|
sourceWrites: recordArray,
|
|
267
313
|
diagnostics: stringArray,
|
|
314
|
+
capabilityPlugins: recordValue,
|
|
268
315
|
}),
|
|
269
316
|
kb_apply_plan: objectData({
|
|
270
317
|
version: stringValue,
|
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
import {
|
|
2
2
|
escapeAtomContent,
|
|
3
|
+
normalizeEntityId,
|
|
4
|
+
parseAtomList,
|
|
3
5
|
parseEntityFromBinding,
|
|
4
6
|
parseEntityFromList,
|
|
5
7
|
parseListOfLists,
|
|
6
8
|
} from "../../prolog/codec.js";
|
|
7
|
-
import type {
|
|
9
|
+
import type {
|
|
10
|
+
PrologEntityQueryInput,
|
|
11
|
+
PrologEntityQueryResult,
|
|
12
|
+
PrologPort,
|
|
13
|
+
PrologSearchQueryInput,
|
|
14
|
+
PrologSearchQueryResult,
|
|
15
|
+
} from "./runtime-types.js";
|
|
8
16
|
|
|
9
17
|
export type EntityQueryInput = {
|
|
10
18
|
readonly type?: string;
|
|
@@ -14,6 +22,11 @@ export type EntityQueryInput = {
|
|
|
14
22
|
/** Page size for index-backed queries; bounds each query's output. */
|
|
15
23
|
readonly limit?: number;
|
|
16
24
|
readonly offset?: number;
|
|
25
|
+
/**
|
|
26
|
+
* Proof selection only needs the contract. Omit receipt histories so a
|
|
27
|
+
* campaign does not page every full test entity.
|
|
28
|
+
*/
|
|
29
|
+
readonly projection?: "proof_contract";
|
|
17
30
|
};
|
|
18
31
|
|
|
19
32
|
export const VALID_ENTITY_TYPES = [
|
|
@@ -36,9 +49,22 @@ export function validateEntityType(type?: string): void {
|
|
|
36
49
|
}
|
|
37
50
|
}
|
|
38
51
|
|
|
52
|
+
/**
|
|
53
|
+
* Proof campaign selection must not materialize every contracted test in a
|
|
54
|
+
* single Prolog result. The specialized projection excludes receipt histories
|
|
55
|
+
* and returns one bounded page at a time.
|
|
56
|
+
*/
|
|
57
|
+
export const PROOF_CONTRACT_PAGE_SIZE = 100;
|
|
58
|
+
|
|
39
59
|
// implements REQ-002, REQ-013
|
|
40
60
|
export function buildEntityGoal(input: EntityQueryInput): string {
|
|
41
61
|
const { type, id, tags, sourceFile } = input;
|
|
62
|
+
if (type === "test" && input.projection === "proof_contract") {
|
|
63
|
+
const idTerm = id ? `some('${escapeAtomContent(id)}')` : "none";
|
|
64
|
+
const limit = input.limit ?? PROOF_CONTRACT_PAGE_SIZE;
|
|
65
|
+
const offset = input.offset ?? 0;
|
|
66
|
+
return `kb_query_proof_contracts(${idTerm},${limit},${offset},Results)`;
|
|
67
|
+
}
|
|
42
68
|
if (sourceFile) {
|
|
43
69
|
const safeSource = escapeAtomContent(sourceFile);
|
|
44
70
|
if (type) {
|
|
@@ -75,24 +101,72 @@ export function buildEntityGoal(input: EntityQueryInput): string {
|
|
|
75
101
|
return "findall([Id,Type,Props], kb_entity(Id, Type, Props), Results)";
|
|
76
102
|
}
|
|
77
103
|
|
|
104
|
+
/**
|
|
105
|
+
* Full test entities carry their receipt histories, which only grow. Callers
|
|
106
|
+
* that must see every full entity of a type page through the indexed query so
|
|
107
|
+
* no single Prolog answer can approach the bounded output capacity.
|
|
108
|
+
*/
|
|
109
|
+
const FULL_ENTITY_PAGE_SIZE = 25;
|
|
110
|
+
|
|
111
|
+
// implements REQ-002, REQ-013
|
|
112
|
+
export async function loadEntitiesPaged(
|
|
113
|
+
prolog: Pick<PrologPort, "query">,
|
|
114
|
+
type: (typeof VALID_ENTITY_TYPES)[number],
|
|
115
|
+
pageSize: number = FULL_ENTITY_PAGE_SIZE,
|
|
116
|
+
): Promise<Record<string, unknown>[]> {
|
|
117
|
+
if (!Number.isInteger(pageSize) || pageSize <= 0) {
|
|
118
|
+
throw new Error("loadEntitiesPaged pageSize must be a positive integer");
|
|
119
|
+
}
|
|
120
|
+
const entities: Record<string, unknown>[] = [];
|
|
121
|
+
for (let offset = 0; ; offset += pageSize) {
|
|
122
|
+
const page = await loadEntities(prolog, { type, limit: pageSize, offset });
|
|
123
|
+
entities.push(...page);
|
|
124
|
+
if (page.length < pageSize) break;
|
|
125
|
+
}
|
|
126
|
+
return dedupeEntities(entities);
|
|
127
|
+
}
|
|
128
|
+
|
|
78
129
|
// implements REQ-002, REQ-013
|
|
79
130
|
export async function loadEntities(
|
|
80
131
|
prolog: Pick<PrologPort, "query">,
|
|
81
132
|
input: EntityQueryInput,
|
|
82
133
|
): Promise<Record<string, unknown>[]> {
|
|
83
134
|
validateEntityType(input.type);
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
135
|
+
const readPage = async (
|
|
136
|
+
pageInput: EntityQueryInput,
|
|
137
|
+
): Promise<Record<string, unknown>[]> => {
|
|
138
|
+
const queryResult = await prolog.query(buildEntityGoal(pageInput));
|
|
139
|
+
if (!queryResult.success) {
|
|
140
|
+
throw new Error(queryResult.error || "Query failed with unknown error");
|
|
141
|
+
}
|
|
142
|
+
const resultsBinding = queryResult.bindings.Results;
|
|
143
|
+
const resultBinding = queryResult.bindings.Result;
|
|
144
|
+
if (resultsBinding) {
|
|
145
|
+
return parseListOfLists(resultsBinding).map(parseEntityFromList);
|
|
146
|
+
}
|
|
147
|
+
return resultBinding ? [parseEntityFromBinding(resultBinding)] : [];
|
|
148
|
+
};
|
|
88
149
|
|
|
89
|
-
let entities: Record<string, unknown>[]
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
150
|
+
let entities: Record<string, unknown>[];
|
|
151
|
+
if (
|
|
152
|
+
input.type === "test" &&
|
|
153
|
+
input.projection === "proof_contract" &&
|
|
154
|
+
input.id === undefined &&
|
|
155
|
+
input.limit === undefined &&
|
|
156
|
+
input.offset === undefined
|
|
157
|
+
) {
|
|
158
|
+
entities = [];
|
|
159
|
+
for (let offset = 0; ; offset += PROOF_CONTRACT_PAGE_SIZE) {
|
|
160
|
+
const page = await readPage({
|
|
161
|
+
...input,
|
|
162
|
+
limit: PROOF_CONTRACT_PAGE_SIZE,
|
|
163
|
+
offset,
|
|
164
|
+
});
|
|
165
|
+
entities.push(...page);
|
|
166
|
+
if (page.length < PROOF_CONTRACT_PAGE_SIZE) break;
|
|
167
|
+
}
|
|
168
|
+
} else {
|
|
169
|
+
entities = await readPage(input);
|
|
96
170
|
}
|
|
97
171
|
if (input.tags && input.tags.length > 0) {
|
|
98
172
|
const requested = new Set(input.tags.map((tag) => tag.trim()));
|
|
@@ -116,6 +190,247 @@ export function paginateResults<T>(
|
|
|
116
190
|
return results.slice(offset, offset + limit);
|
|
117
191
|
}
|
|
118
192
|
|
|
193
|
+
/**
|
|
194
|
+
* Page size for index-backed search candidate fetches. Each page is one
|
|
195
|
+
* Prolog query, so a fixed page size substantially bounds each response and
|
|
196
|
+
* fixes the observed large-KB output overflow; it is a practical bound, not
|
|
197
|
+
* a byte-size guarantee for arbitrarily large individual entity payloads.
|
|
198
|
+
*/
|
|
199
|
+
// implements REQ-kibi-operation-interface-parity, REQ-mcp-search-discovery
|
|
200
|
+
export const SEARCH_CANDIDATE_PAGE_SIZE = 500;
|
|
201
|
+
|
|
202
|
+
function isPrologOutputOverflow(error: unknown): boolean {
|
|
203
|
+
return error instanceof Error && error.message.includes("ENOBUFS");
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// implements REQ-kibi-operation-interface-parity, REQ-mcp-search-discovery
|
|
207
|
+
export async function loadSearchCandidates(
|
|
208
|
+
prolog: Pick<PrologPort, "searchEntities"> &
|
|
209
|
+
Partial<Pick<PrologPort, "query">>,
|
|
210
|
+
input: {
|
|
211
|
+
readonly query: string;
|
|
212
|
+
readonly type?: string;
|
|
213
|
+
readonly maxCandidates?: number;
|
|
214
|
+
},
|
|
215
|
+
signal?: AbortSignal,
|
|
216
|
+
): Promise<Record<string, unknown>[]> {
|
|
217
|
+
// Call through the port property, never via a detached local: EngineClient
|
|
218
|
+
// searchEntities depends on `this` (this.command), and the PrologPort
|
|
219
|
+
// contract does not promise a pre-bound method. Ports without the indexed
|
|
220
|
+
// engine method run the same bounded Prolog search through `query`.
|
|
221
|
+
const readPage = (
|
|
222
|
+
page: PrologSearchQueryInput,
|
|
223
|
+
): Promise<PrologSearchQueryResult> => {
|
|
224
|
+
if (prolog.searchEntities) return prolog.searchEntities(page, signal);
|
|
225
|
+
const query = prolog.query;
|
|
226
|
+
if (query === undefined) return Promise.resolve({ entities: [], count: 0 });
|
|
227
|
+
return searchEntitiesViaQuery(
|
|
228
|
+
{ query: (goal, querySignal) => query.call(prolog, goal, querySignal) },
|
|
229
|
+
page,
|
|
230
|
+
signal,
|
|
231
|
+
);
|
|
232
|
+
};
|
|
233
|
+
return readCandidatePages(readPage, input);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Projected candidate rows for every entity (optionally of one type), in id
|
|
238
|
+
* order, bounded by `maxCandidates`. For semantic discovery that has no
|
|
239
|
+
* lexical token to pre-filter candidates.
|
|
240
|
+
*/
|
|
241
|
+
// implements REQ-kibi-operation-interface-parity, REQ-mcp-search-discovery
|
|
242
|
+
export async function listSearchCandidates(
|
|
243
|
+
prolog: Pick<PrologPort, "query">,
|
|
244
|
+
input: { readonly type?: string; readonly maxCandidates: number },
|
|
245
|
+
signal?: AbortSignal,
|
|
246
|
+
): Promise<Record<string, unknown>[]> {
|
|
247
|
+
const type = input.type ? `'${escapeAtomContent(input.type)}'` : "none";
|
|
248
|
+
return readCandidatePages(
|
|
249
|
+
(page) =>
|
|
250
|
+
readRowsAndCount(
|
|
251
|
+
prolog,
|
|
252
|
+
`kb_list_search_candidates(${type}, ${page.limit}, ${page.offset}, Rows, Count)`,
|
|
253
|
+
"Search candidate listing failed",
|
|
254
|
+
signal,
|
|
255
|
+
),
|
|
256
|
+
{ query: "", maxCandidates: input.maxCandidates },
|
|
257
|
+
);
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
async function readCandidatePages(
|
|
261
|
+
readPage: (page: PrologSearchQueryInput) => Promise<PrologSearchQueryResult>,
|
|
262
|
+
input: {
|
|
263
|
+
readonly query: string;
|
|
264
|
+
readonly type?: string;
|
|
265
|
+
readonly maxCandidates?: number;
|
|
266
|
+
},
|
|
267
|
+
): Promise<Record<string, unknown>[]> {
|
|
268
|
+
const maxCandidates = input.maxCandidates ?? Number.POSITIVE_INFINITY;
|
|
269
|
+
const candidates: Record<string, unknown>[] = [];
|
|
270
|
+
let offset = 0;
|
|
271
|
+
let total = Number.POSITIVE_INFINITY;
|
|
272
|
+
let pageSize = SEARCH_CANDIDATE_PAGE_SIZE;
|
|
273
|
+
while (offset < total && candidates.length < maxCandidates) {
|
|
274
|
+
let page: PrologSearchQueryResult;
|
|
275
|
+
try {
|
|
276
|
+
page = await readPage({
|
|
277
|
+
query: input.query,
|
|
278
|
+
...(input.type !== undefined ? { type: input.type } : {}),
|
|
279
|
+
limit: pageSize,
|
|
280
|
+
offset,
|
|
281
|
+
});
|
|
282
|
+
} catch (error) {
|
|
283
|
+
// A page of unusually large rows can still exceed the bounded Prolog
|
|
284
|
+
// output. Halve the page and retry the same offset; the smaller size is
|
|
285
|
+
// kept for the rest of the scan. Only a single row that overflows on its
|
|
286
|
+
// own is a real failure.
|
|
287
|
+
if (pageSize > 1 && isPrologOutputOverflow(error)) {
|
|
288
|
+
pageSize = Math.max(1, Math.floor(pageSize / 2));
|
|
289
|
+
continue;
|
|
290
|
+
}
|
|
291
|
+
throw error;
|
|
292
|
+
}
|
|
293
|
+
if (page.entities.length === 0) break;
|
|
294
|
+
candidates.push(...page.entities);
|
|
295
|
+
total = page.count;
|
|
296
|
+
offset += page.entities.length;
|
|
297
|
+
}
|
|
298
|
+
return Number.isFinite(maxCandidates)
|
|
299
|
+
? candidates.slice(0, maxCandidates)
|
|
300
|
+
: candidates;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
function searchEntitiesViaQuery(
|
|
304
|
+
prolog: Pick<PrologPort, "query">,
|
|
305
|
+
input: PrologSearchQueryInput,
|
|
306
|
+
signal?: AbortSignal,
|
|
307
|
+
): Promise<PrologSearchQueryResult> {
|
|
308
|
+
const type = input.type ? `'${escapeAtomContent(input.type)}'` : "none";
|
|
309
|
+
return readRowsAndCount(
|
|
310
|
+
prolog,
|
|
311
|
+
`kb_search_entities(${type}, '${escapeAtomContent(input.query)}', ${input.limit}, ${input.offset}, Rows, Count)`,
|
|
312
|
+
"Indexed search candidate query failed",
|
|
313
|
+
signal,
|
|
314
|
+
);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
async function readRowsAndCount(
|
|
318
|
+
prolog: Pick<PrologPort, "query">,
|
|
319
|
+
goal: string,
|
|
320
|
+
errorLabel: string,
|
|
321
|
+
signal?: AbortSignal,
|
|
322
|
+
): Promise<PrologEntityQueryResult> {
|
|
323
|
+
const result = await prolog.query(goal, signal);
|
|
324
|
+
if (!result.success) {
|
|
325
|
+
// Same message as the engine client's indexed methods, so both surfaces
|
|
326
|
+
// report a failure identically.
|
|
327
|
+
throw new Error(result.error ?? errorLabel);
|
|
328
|
+
}
|
|
329
|
+
const entities = result.bindings.Rows
|
|
330
|
+
? parseListOfLists(result.bindings.Rows).map(parseEntityFromList)
|
|
331
|
+
: [];
|
|
332
|
+
const count = Number.parseInt(result.bindings.Count ?? "0", 10);
|
|
333
|
+
return { entities, count: Number.isFinite(count) ? count : entities.length };
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* Rows per `kb_query_entities` request. Full entities carry receipt
|
|
338
|
+
* histories, so a caller-sized page (up to 100k rows) is split into bounded
|
|
339
|
+
* requests and concatenated; the reported count is the total match count.
|
|
340
|
+
*/
|
|
341
|
+
export const ENTITY_QUERY_CHUNK_SIZE = 25;
|
|
342
|
+
|
|
343
|
+
// implements REQ-kibi-operation-interface-parity
|
|
344
|
+
export async function queryEntityChunks(
|
|
345
|
+
readChunk: (
|
|
346
|
+
input: PrologEntityQueryInput,
|
|
347
|
+
) => Promise<PrologEntityQueryResult>,
|
|
348
|
+
input: PrologEntityQueryInput,
|
|
349
|
+
): Promise<PrologEntityQueryResult> {
|
|
350
|
+
const entities: Record<string, unknown>[] = [];
|
|
351
|
+
let count = 0;
|
|
352
|
+
let first = true;
|
|
353
|
+
while (first || entities.length < input.limit) {
|
|
354
|
+
const chunkLimit = Math.min(
|
|
355
|
+
ENTITY_QUERY_CHUNK_SIZE,
|
|
356
|
+
input.limit - entities.length,
|
|
357
|
+
);
|
|
358
|
+
const chunk = await readChunk({
|
|
359
|
+
...input,
|
|
360
|
+
limit: chunkLimit,
|
|
361
|
+
offset: input.offset + entities.length,
|
|
362
|
+
});
|
|
363
|
+
if (first) count = chunk.count;
|
|
364
|
+
first = false;
|
|
365
|
+
entities.push(...chunk.entities);
|
|
366
|
+
if (chunk.entities.length < chunkLimit || chunkLimit === 0) break;
|
|
367
|
+
}
|
|
368
|
+
return { entities, count };
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
/** Bounded `kb_query_entities` paging for ports without the engine method. */
|
|
372
|
+
// implements REQ-kibi-operation-interface-parity
|
|
373
|
+
export function queryEntitiesViaQuery(
|
|
374
|
+
prolog: Pick<PrologPort, "query">,
|
|
375
|
+
input: PrologEntityQueryInput,
|
|
376
|
+
signal?: AbortSignal,
|
|
377
|
+
): Promise<PrologEntityQueryResult> {
|
|
378
|
+
const atom = (value: string | undefined) =>
|
|
379
|
+
value === undefined ? "none" : `'${escapeAtomContent(value)}'`;
|
|
380
|
+
const tags = `[${(input.tags ?? []).map((tag) => `'${escapeAtomContent(tag)}'`).join(",")}]`;
|
|
381
|
+
return queryEntityChunks(
|
|
382
|
+
(chunk) =>
|
|
383
|
+
readRowsAndCount(
|
|
384
|
+
prolog,
|
|
385
|
+
`kb_query_entities(${atom(chunk.type)}, ${atom(chunk.id)}, ${tags}, ${atom(chunk.sourceFile)}, ${chunk.limit}, ${chunk.offset}, Rows, Count)`,
|
|
386
|
+
"Indexed entity query failed",
|
|
387
|
+
signal,
|
|
388
|
+
),
|
|
389
|
+
input,
|
|
390
|
+
);
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
/** Every entity id, without materializing entity properties. */
|
|
394
|
+
// implements REQ-002
|
|
395
|
+
export async function loadEntityIds(
|
|
396
|
+
prolog: Pick<PrologPort, "query">,
|
|
397
|
+
): Promise<string[]> {
|
|
398
|
+
const result = await prolog.query("kb_entity_ids(Ids)");
|
|
399
|
+
if (!result.success) {
|
|
400
|
+
throw new Error(
|
|
401
|
+
`Entity id enumeration failed: ${result.error ?? "Unknown error"}`,
|
|
402
|
+
);
|
|
403
|
+
}
|
|
404
|
+
return parseAtomList(result.bindings.Ids ?? "[]").map(normalizeEntityId);
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
/**
|
|
408
|
+
* Replace projected search candidates with complete entities, one bounded
|
|
409
|
+
* query per entity. Used only for the final result page when a caller asks
|
|
410
|
+
* for full entity bodies.
|
|
411
|
+
*/
|
|
412
|
+
// implements REQ-mcp-search-discovery
|
|
413
|
+
export async function reloadFullEntities<
|
|
414
|
+
TMatch extends { readonly entity: Record<string, unknown> },
|
|
415
|
+
>(
|
|
416
|
+
prolog: Pick<PrologPort, "query">,
|
|
417
|
+
matches: readonly TMatch[],
|
|
418
|
+
): Promise<TMatch[]> {
|
|
419
|
+
const reloaded: TMatch[] = [];
|
|
420
|
+
for (const match of matches) {
|
|
421
|
+
const id = String(match.entity.id ?? "");
|
|
422
|
+
const type = match.entity.type;
|
|
423
|
+
const [full] = id
|
|
424
|
+
? await loadEntities(prolog, {
|
|
425
|
+
id,
|
|
426
|
+
...(typeof type === "string" ? { type } : {}),
|
|
427
|
+
})
|
|
428
|
+
: [];
|
|
429
|
+
reloaded.push(full ? { ...match, entity: full } : match);
|
|
430
|
+
}
|
|
431
|
+
return reloaded;
|
|
432
|
+
}
|
|
433
|
+
|
|
119
434
|
// implements REQ-002
|
|
120
435
|
export function dedupeEntities(
|
|
121
436
|
entities: readonly Record<string, unknown>[],
|