kibi-cli 2.36.0 → 2.39.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-json-command.d.ts.map +1 -1
- package/dist/cli-json-command.js +4 -0
- package/dist/cli-operation-metadata.d.ts +1 -1
- package/dist/cli-operation-metadata.js +1 -1
- package/dist/cli-register-foundation.d.ts.map +1 -1
- package/dist/cli-register-foundation.js +2 -1
- package/dist/cli-register-maintenance.d.ts.map +1 -1
- package/dist/cli-register-maintenance.js +5 -0
- package/dist/cli-register-reporting.d.ts.map +1 -1
- package/dist/cli-register-reporting.js +1 -0
- package/dist/cli-validate.d.ts.map +1 -1
- package/dist/cli-validate.js +21 -2
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +19 -1
- package/dist/commands/aggregated-checks.d.ts.map +1 -1
- package/dist/commands/aggregated-checks.js +89 -16
- package/dist/commands/coverage.d.ts +1 -0
- package/dist/commands/coverage.d.ts.map +1 -1
- package/dist/commands/coverage.js +40 -0
- package/dist/commands/doctor.d.ts +5 -0
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +70 -35
- package/dist/commands/github-init.d.ts.map +1 -1
- package/dist/commands/github-init.js +4 -2
- package/dist/commands/hook-managers.d.ts +43 -0
- package/dist/commands/hook-managers.d.ts.map +1 -0
- package/dist/commands/hook-managers.js +426 -0
- package/dist/commands/init.d.ts +1 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +40 -5
- package/dist/commands/migrate.d.ts.map +1 -1
- package/dist/commands/migrate.js +9 -3
- package/dist/commands/sync/persistence.d.ts.map +1 -1
- package/dist/commands/sync/persistence.js +49 -1
- package/dist/commands/telemetry.d.ts +7 -0
- package/dist/commands/telemetry.d.ts.map +1 -0
- package/dist/commands/telemetry.js +23 -0
- package/dist/decision-firmness.d.ts.map +1 -1
- package/dist/decision-firmness.js +11 -14
- package/dist/engine-limits.d.ts.map +1 -1
- package/dist/engine-limits.js +8 -10
- package/dist/entity-body-context.d.ts.map +1 -1
- package/dist/entity-body-context.js +39 -36
- package/dist/extractors/markdown.d.ts +6 -0
- package/dist/extractors/markdown.d.ts.map +1 -1
- package/dist/extractors/markdown.js +21 -0
- package/dist/extractors/symbol-coordinates.d.ts.map +1 -1
- package/dist/extractors/symbol-coordinates.js +23 -4
- package/dist/firm-decision-edit.d.ts.map +1 -1
- package/dist/firm-decision-edit.js +1 -3
- package/dist/intent-search.d.ts +5 -1
- package/dist/intent-search.d.ts.map +1 -1
- package/dist/intent-search.js +118 -33
- package/dist/logic/ir.d.ts.map +1 -1
- package/dist/logic/ir.js +82 -108
- package/dist/operations/bootstrap/discovery-evidence.d.ts.map +1 -1
- package/dist/operations/bootstrap/discovery-evidence.js +44 -2
- package/dist/operations/bootstrap/discovery.d.ts.map +1 -1
- package/dist/operations/bootstrap/discovery.js +1 -0
- package/dist/operations/bootstrap/guidance-actions.d.ts.map +1 -1
- package/dist/operations/bootstrap/guidance-actions.js +2 -1
- package/dist/operations/bootstrap/plugin-offers.d.ts +11 -2
- package/dist/operations/bootstrap/plugin-offers.d.ts.map +1 -1
- package/dist/operations/bootstrap/plugin-offers.js +48 -9
- package/dist/operations/proof/claim-bindings.d.ts.map +1 -1
- package/dist/operations/proof/claim-bindings.js +1 -0
- package/dist/operations/proof/code-certificates.d.ts +2 -0
- package/dist/operations/proof/code-certificates.d.ts.map +1 -1
- package/dist/operations/proof/code-certificates.js +34 -14
- package/dist/operations/proof/code-models.d.ts.map +1 -1
- package/dist/operations/proof/code-models.js +19 -5
- package/dist/operations/proof/code-runner.d.ts +16 -0
- package/dist/operations/proof/code-runner.d.ts.map +1 -1
- package/dist/operations/proof/code-runner.js +42 -6
- package/dist/operations/proof/explain.d.ts +63 -0
- package/dist/operations/proof/explain.d.ts.map +1 -1
- package/dist/operations/proof/explain.js +162 -0
- package/dist/operations/semantic-advisor/analyze-prose.d.ts +9 -1
- package/dist/operations/semantic-advisor/analyze-prose.d.ts.map +1 -1
- package/dist/operations/semantic-advisor/analyze-prose.js +21 -0
- package/dist/operations/semantic-advisor/case-preview.d.ts +24 -0
- package/dist/operations/semantic-advisor/case-preview.d.ts.map +1 -0
- package/dist/operations/semantic-advisor/case-preview.js +216 -0
- package/dist/operations/semantic-advisor/shared.d.ts.map +1 -1
- package/dist/operations/semantic-advisor/shared.js +3 -0
- package/dist/operations/semantic-advisor/types.d.ts +23 -0
- package/dist/operations/semantic-advisor/types.d.ts.map +1 -1
- package/dist/plugins/approved-source-analyzers.generated.d.ts +11 -8
- package/dist/plugins/approved-source-analyzers.generated.d.ts.map +1 -1
- package/dist/plugins/approved-source-analyzers.generated.js +11 -8
- package/dist/plugins/compose-search-hints.d.ts +29 -0
- package/dist/plugins/compose-search-hints.d.ts.map +1 -0
- package/dist/plugins/compose-search-hints.js +94 -0
- package/dist/plugins/external-allowlist.d.ts +7 -0
- package/dist/plugins/external-allowlist.d.ts.map +1 -1
- package/dist/plugins/external-allowlist.js +11 -0
- package/dist/plugins/registry.d.ts +8 -1
- package/dist/plugins/registry.d.ts.map +1 -1
- package/dist/plugins/registry.js +22 -3
- package/dist/plugins/source-classification.d.ts +2 -2
- package/dist/plugins/source-classification.d.ts.map +1 -1
- package/dist/plugins/source-classification.js +25 -1
- package/dist/prolog/codec.d.ts.map +1 -1
- package/dist/prolog/codec.js +10 -20
- package/dist/public/impact/coverage-depth-quality.d.ts.map +1 -1
- package/dist/public/impact/coverage-depth-quality.js +32 -16
- package/dist/public/impact/full-kb-quality.d.ts +6 -0
- package/dist/public/impact/full-kb-quality.d.ts.map +1 -1
- package/dist/public/impact/full-kb-quality.js +8 -3
- package/dist/public/impact/requirement-quality.d.ts.map +1 -1
- package/dist/public/impact/requirement-quality.js +56 -29
- package/dist/public/operations/catalog.d.ts +44 -4
- package/dist/public/operations/catalog.d.ts.map +1 -1
- package/dist/public/operations/check-executor.d.ts +6 -0
- package/dist/public/operations/check-executor.d.ts.map +1 -1
- package/dist/public/operations/check-executor.js +34 -2
- package/dist/public/operations/discovery-executors.d.ts +5 -1
- package/dist/public/operations/discovery-executors.d.ts.map +1 -1
- package/dist/public/operations/discovery-executors.js +65 -4
- package/dist/public/operations/evidence-floor.d.ts +8 -1
- package/dist/public/operations/evidence-floor.d.ts.map +1 -1
- package/dist/public/operations/evidence-floor.js +3 -4
- package/dist/public/operations/migration-plan.d.ts.map +1 -1
- package/dist/public/operations/migration-plan.js +41 -10
- package/dist/public/operations/node-ports.d.ts.map +1 -1
- package/dist/public/operations/node-ports.js +3 -1
- package/dist/public/operations/repair-plan.d.ts +46 -0
- package/dist/public/operations/repair-plan.d.ts.map +1 -1
- package/dist/public/operations/repair-plan.js +110 -1
- package/dist/public/operations/schema6-check-actions.js +1 -1
- package/dist/public/operations/source-analysis-cache.d.ts +22 -0
- package/dist/public/operations/source-analysis-cache.d.ts.map +1 -0
- package/dist/public/operations/source-analysis-cache.js +157 -0
- 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 +2 -1
- package/dist/public/operations/specs/check.d.ts +1 -1
- package/dist/public/operations/specs/discovery.d.ts +7 -2
- package/dist/public/operations/specs/discovery.d.ts.map +1 -1
- package/dist/public/operations/specs/discovery.js +7 -2
- package/dist/public/operations/specs/mutation-schemas.d.ts +36 -1
- package/dist/public/operations/specs/mutation-schemas.d.ts.map +1 -1
- package/dist/public/operations/specs/mutation-schemas.js +30 -0
- package/dist/public/operations/specs/upsert.d.ts +36 -1
- package/dist/public/operations/specs/upsert.d.ts.map +1 -1
- package/dist/public/operations/symbol-granularity-check.d.ts +3 -1
- package/dist/public/operations/symbol-granularity-check.d.ts.map +1 -1
- package/dist/public/operations/symbol-granularity-check.js +21 -7
- package/dist/public/proof-protocol.d.ts +6 -1
- package/dist/public/proof-protocol.d.ts.map +1 -1
- package/dist/public/proof-protocol.js +12 -3
- package/dist/public/proof-sources.d.ts +2 -0
- package/dist/public/proof-sources.d.ts.map +1 -1
- package/dist/public/proof-sources.js +32 -6
- package/dist/public/schemas/entity.d.ts.map +1 -1
- package/dist/public/schemas/entity.js +59 -0
- package/dist/public/skills/kibi-bootstrap/SKILL.md +2 -2
- package/dist/public/skills/kibi-commit-review/SKILL.md +6 -2
- package/dist/public/skills/kibi-decisions/SKILL.md +7 -2
- package/dist/public/skills/kibi-decisions/resources/signoff-views.md +3 -1
- package/dist/public/skills/kibi-usage/SKILL.md +50 -3
- package/dist/public/skills/kibi-usage/resources/fact-lanes.md +34 -0
- package/dist/public/skills/kibi-usage/resources/proof.md +13 -5
- package/dist/public/skills/kibi-usage/resources/workflows.md +10 -0
- package/dist/relationships/shards.d.ts +2 -0
- package/dist/relationships/shards.d.ts.map +1 -1
- package/dist/relationships/shards.js +25 -1
- package/dist/schemas/entity.schema.json +98 -1
- package/dist/search-answer.d.ts +3 -2
- package/dist/search-answer.d.ts.map +1 -1
- package/dist/search-answer.js +57 -4
- package/dist/search-hints.d.ts +58 -0
- package/dist/search-hints.d.ts.map +1 -0
- package/dist/search-hints.js +187 -0
- package/dist/search-ranking.d.ts +7 -0
- package/dist/search-ranking.d.ts.map +1 -1
- package/dist/search-ranking.js +54 -56
- package/dist/search-token-cache.d.ts +30 -0
- package/dist/search-token-cache.d.ts.map +1 -0
- package/dist/search-token-cache.js +86 -0
- package/dist/traceability/impact-knowledge.d.ts.map +1 -1
- package/dist/traceability/impact-knowledge.js +2 -0
- package/dist/traceability/temp-kb.d.ts.map +1 -1
- package/dist/traceability/temp-kb.js +11 -1
- package/dist/types/entities.d.ts +12 -0
- package/dist/types/entities.d.ts.map +1 -1
- package/dist/usage-telemetry.d.ts +20 -0
- package/dist/usage-telemetry.d.ts.map +1 -0
- package/dist/usage-telemetry.js +93 -0
- package/dist/utils/branch-resolver.d.ts.map +1 -1
- package/dist/utils/branch-resolver.js +1 -0
- package/dist/utils/rule-registry.generated.d.ts +5 -0
- package/dist/utils/rule-registry.generated.d.ts.map +1 -1
- package/dist/utils/rule-registry.generated.js +6 -0
- package/package.json +5 -4
- package/schema/entities.pl +12 -0
- package/src/public/impact/coverage-depth-quality.ts +59 -21
- package/src/public/impact/full-kb-quality.ts +15 -1
- package/src/public/impact/requirement-quality.ts +95 -38
- package/src/public/operations/check-executor.ts +41 -1
- package/src/public/operations/discovery-executors.ts +92 -4
- package/src/public/operations/evidence-floor.ts +15 -3
- package/src/public/operations/migration-plan.ts +41 -9
- package/src/public/operations/node-ports.ts +3 -1
- package/src/public/operations/repair-plan.ts +152 -1
- package/src/public/operations/schema6-check-actions.ts +1 -1
- package/src/public/operations/source-analysis-cache.ts +196 -0
- package/src/public/operations/specs/check-rules.generated.ts +2 -1
- package/src/public/operations/specs/discovery.ts +8 -2
- package/src/public/operations/specs/mutation-schemas.ts +34 -0
- package/src/public/operations/symbol-granularity-check.ts +25 -5
- package/src/public/proof-protocol-types.d.ts +1 -1
- package/src/public/proof-protocol.ts +18 -4
- package/src/public/proof-sources.ts +37 -6
- package/src/public/schemas/entity.ts +65 -0
- package/src/public/skills/kibi-bootstrap/SKILL.md +2 -2
- package/src/public/skills/kibi-commit-review/SKILL.md +6 -2
- package/src/public/skills/kibi-decisions/SKILL.md +7 -2
- package/src/public/skills/kibi-decisions/resources/signoff-views.md +3 -1
- package/src/public/skills/kibi-usage/SKILL.md +50 -3
- package/src/public/skills/kibi-usage/resources/fact-lanes.md +34 -0
- package/src/public/skills/kibi-usage/resources/proof.md +13 -5
- package/src/public/skills/kibi-usage/resources/workflows.md +10 -0
- package/src/schemas/entity.schema.json +98 -1
|
@@ -14,4 +14,11 @@ export declare function allowsExternalSemanticClassifier(operationName: string):
|
|
|
14
14
|
*/
|
|
15
15
|
export declare const EXTERNAL_VOCABULARY_ALIGNMENT_OPERATIONS: readonly ["kb_model_requirement"];
|
|
16
16
|
export declare function allowsExternalVocabularyAlignment(operationName: string): boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Operations that may call external kibi.search-hints.v1 providers. Hints are
|
|
19
|
+
* advice next to a search answer; checks, proofs and every write stay
|
|
20
|
+
* builtin-only.
|
|
21
|
+
*/
|
|
22
|
+
export declare const EXTERNAL_SEARCH_HINTS_OPERATIONS: readonly ["kb_search"];
|
|
23
|
+
export declare function allowsExternalSearchHints(operationName: string): boolean;
|
|
17
24
|
//# sourceMappingURL=external-allowlist.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"external-allowlist.d.ts","sourceRoot":"","sources":["../../src/plugins/external-allowlist.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,uCAAuC,uDAG1C,CAAC;AAGX,MAAM,MAAM,mCAAmC,GAC7C,CAAC,OAAO,uCAAuC,CAAC,CAAC,MAAM,CAAC,CAAC;AAK3D,wBAAgB,gCAAgC,CAC9C,aAAa,EAAE,MAAM,GACpB,OAAO,CAET;AAED;;;;GAIG;AAEH,eAAO,MAAM,wCAAwC,mCAE3C,CAAC;AAGX,wBAAgB,iCAAiC,CAC/C,aAAa,EAAE,MAAM,GACpB,OAAO,CAIT"}
|
|
1
|
+
{"version":3,"file":"external-allowlist.d.ts","sourceRoot":"","sources":["../../src/plugins/external-allowlist.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,uCAAuC,uDAG1C,CAAC;AAGX,MAAM,MAAM,mCAAmC,GAC7C,CAAC,OAAO,uCAAuC,CAAC,CAAC,MAAM,CAAC,CAAC;AAK3D,wBAAgB,gCAAgC,CAC9C,aAAa,EAAE,MAAM,GACpB,OAAO,CAET;AAED;;;;GAIG;AAEH,eAAO,MAAM,wCAAwC,mCAE3C,CAAC;AAGX,wBAAgB,iCAAiC,CAC/C,aAAa,EAAE,MAAM,GACpB,OAAO,CAIT;AAED;;;;GAIG;AAEH,eAAO,MAAM,gCAAgC,wBAAyB,CAAC;AAGvE,wBAAgB,yBAAyB,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAIxE"}
|
|
@@ -27,3 +27,14 @@ export const EXTERNAL_VOCABULARY_ALIGNMENT_OPERATIONS = [
|
|
|
27
27
|
export function allowsExternalVocabularyAlignment(operationName) {
|
|
28
28
|
return EXTERNAL_VOCABULARY_ALIGNMENT_OPERATIONS.includes(operationName);
|
|
29
29
|
}
|
|
30
|
+
/**
|
|
31
|
+
* Operations that may call external kibi.search-hints.v1 providers. Hints are
|
|
32
|
+
* advice next to a search answer; checks, proofs and every write stay
|
|
33
|
+
* builtin-only.
|
|
34
|
+
*/
|
|
35
|
+
// implements REQ-kibi-search-hints-host
|
|
36
|
+
export const EXTERNAL_SEARCH_HINTS_OPERATIONS = ["kb_search"];
|
|
37
|
+
// implements REQ-kibi-search-hints-host
|
|
38
|
+
export function allowsExternalSearchHints(operationName) {
|
|
39
|
+
return EXTERNAL_SEARCH_HINTS_OPERATIONS.includes(operationName);
|
|
40
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type CapabilityId, type KibiPluginV1, type OntologyPackV1, type PluginMode, type PluginPermissions, type PluginProviderStamp, type ProjectKibiConfig, type SemanticClassifierV1, type SymbolExtractorV1, type SymbolExtractorV2, type VocabularyAlignmentV1 } from "kibi-plugin-sdk";
|
|
1
|
+
import { type CapabilityId, type KibiPluginV1, type OntologyPackV1, type PluginMode, type PluginPermissions, type PluginProviderStamp, type ProjectKibiConfig, type SearchHintsV1, type SemanticClassifierV1, type SymbolExtractorV1, type SymbolExtractorV2, type VocabularyAlignmentV1 } from "kibi-plugin-sdk";
|
|
2
2
|
import { type LoadPluginOptions, loadPluginPackage } from "./load-plugin.js";
|
|
3
3
|
export type BuiltinPluginFactory = () => KibiPluginV1 | Promise<KibiPluginV1>;
|
|
4
4
|
export type CapabilityProviderBinding<T> = Readonly<{
|
|
@@ -32,6 +32,12 @@ export type CapabilityRegistryOptions = Readonly<{
|
|
|
32
32
|
loadPlugin?: (workspaceRoot: string, packageName: string, options?: LoadPluginOptions) => Promise<Awaited<ReturnType<typeof loadPluginPackage>>>;
|
|
33
33
|
loadPluginOptions?: LoadPluginOptions;
|
|
34
34
|
}>;
|
|
35
|
+
/**
|
|
36
|
+
* Search hints have no builtin answer: without a configured provider there
|
|
37
|
+
* are no hints. A builtin package that predates the capability resolves to
|
|
38
|
+
* this host no-op instead of failing the search.
|
|
39
|
+
*/
|
|
40
|
+
export declare const NO_SEARCH_HINTS: SearchHintsV1;
|
|
35
41
|
/**
|
|
36
42
|
* Minimal builtin used when no factory is injected and the builtin package is
|
|
37
43
|
* not yet wired. Satisfies kibi.plugin.v1 validation.
|
|
@@ -61,6 +67,7 @@ export declare class CapabilityRegistry {
|
|
|
61
67
|
resolveSymbolExtractors(): Promise<CapabilityModeResolution<SymbolExtractorV1>>;
|
|
62
68
|
resolveSymbolExtractorsV2(): Promise<CapabilityModeResolution<SymbolExtractorV2>>;
|
|
63
69
|
resolveVocabularyAlignment(): Promise<CapabilityModeResolution<VocabularyAlignmentV1>>;
|
|
70
|
+
resolveSearchHints(): Promise<CapabilityModeResolution<SearchHintsV1>>;
|
|
64
71
|
resolveCapability(capabilityId: CapabilityId): Promise<CapabilityModeResolution<unknown>>;
|
|
65
72
|
/**
|
|
66
73
|
* Canonical providers only (builtin + optional replace + augment).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/plugins/registry.ts"],"names":[],"mappings":"AAkBA,OAAO,EAGL,KAAK,YAAY,EAGjB,KAAK,YAAY,EAEjB,KAAK,cAAc,EACnB,KAAK,UAAU,EACf,KAAK,iBAAiB,EACtB,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/plugins/registry.ts"],"names":[],"mappings":"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"}
|
package/dist/plugins/registry.js
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
You should have received a copy of the GNU Affero General Public License
|
|
16
16
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
17
|
*/
|
|
18
|
-
import { CHECK_POLICY_CAPABILITY_ID, CHECK_POLICY_CONTRACT_VERSION, KIBI_PLUGIN_API_VERSION, ONTOLOGY_PACK_CAPABILITY_ID, SEMANTIC_CLASSIFIER_CAPABILITY_ID, SYMBOL_EXTRACTOR_CAPABILITY_ID, SYMBOL_EXTRACTOR_V2_CAPABILITY_ID, VOCABULARY_ALIGNMENT_CAPABILITY_ID, defineKibiPlugin, validateKibiPlugin, } from "kibi-plugin-sdk";
|
|
18
|
+
import { CHECK_POLICY_CAPABILITY_ID, CHECK_POLICY_CONTRACT_VERSION, KIBI_PLUGIN_API_VERSION, ONTOLOGY_PACK_CAPABILITY_ID, SEARCH_HINTS_CAPABILITY_ID, SEMANTIC_CLASSIFIER_CAPABILITY_ID, SYMBOL_EXTRACTOR_CAPABILITY_ID, SYMBOL_EXTRACTOR_V2_CAPABILITY_ID, VOCABULARY_ALIGNMENT_CAPABILITY_ID, defineKibiPlugin, validateKibiPlugin, } from "kibi-plugin-sdk";
|
|
19
19
|
import { loadPluginPackage } from "./load-plugin.js";
|
|
20
20
|
import { readProjectKibiConfig } from "./project-config.js";
|
|
21
21
|
import { PluginResolutionError } from "./resolve-package.js";
|
|
@@ -26,6 +26,18 @@ const CAPABILITY_SLOT = {
|
|
|
26
26
|
[SYMBOL_EXTRACTOR_V2_CAPABILITY_ID]: "symbolExtractorV2",
|
|
27
27
|
[VOCABULARY_ALIGNMENT_CAPABILITY_ID]: "vocabularyAlignment",
|
|
28
28
|
[CHECK_POLICY_CAPABILITY_ID]: "checkPolicy",
|
|
29
|
+
[SEARCH_HINTS_CAPABILITY_ID]: "searchHints",
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Search hints have no builtin answer: without a configured provider there
|
|
33
|
+
* are no hints. A builtin package that predates the capability resolves to
|
|
34
|
+
* this host no-op instead of failing the search.
|
|
35
|
+
*/
|
|
36
|
+
// implements REQ-kibi-search-hints-host
|
|
37
|
+
export const NO_SEARCH_HINTS = {
|
|
38
|
+
id: "kibi-host.search-hints.none",
|
|
39
|
+
model: "none",
|
|
40
|
+
hint: () => ({ hints: [] }),
|
|
29
41
|
};
|
|
30
42
|
/**
|
|
31
43
|
* Minimal builtin used when no factory is injected and the builtin package is
|
|
@@ -214,6 +226,10 @@ export class CapabilityRegistry {
|
|
|
214
226
|
async resolveVocabularyAlignment() {
|
|
215
227
|
return this.resolveCapability(VOCABULARY_ALIGNMENT_CAPABILITY_ID);
|
|
216
228
|
}
|
|
229
|
+
// implements REQ-kibi-search-hints-host
|
|
230
|
+
async resolveSearchHints() {
|
|
231
|
+
return this.resolveCapability(SEARCH_HINTS_CAPABILITY_ID);
|
|
232
|
+
}
|
|
217
233
|
async resolveCapability(capabilityId) {
|
|
218
234
|
const cached = this.capabilityCache.get(capabilityId);
|
|
219
235
|
if (cached)
|
|
@@ -240,7 +256,10 @@ export class CapabilityRegistry {
|
|
|
240
256
|
}
|
|
241
257
|
async buildCapabilityResolution(capabilityId) {
|
|
242
258
|
const builtinPlugin = await this.getBuiltinPlugin();
|
|
243
|
-
const builtinCapability = capabilityFromPlugin(builtinPlugin, capabilityId)
|
|
259
|
+
const builtinCapability = capabilityFromPlugin(builtinPlugin, capabilityId) ??
|
|
260
|
+
(capabilityId === SEARCH_HINTS_CAPABILITY_ID
|
|
261
|
+
? NO_SEARCH_HINTS
|
|
262
|
+
: undefined);
|
|
244
263
|
if (!builtinCapability) {
|
|
245
264
|
throw new PluginResolutionError("BUILTIN_MISSING_CAPABILITY", `Builtin plugin '${builtinPlugin.id}' does not provide ${capabilityId}`);
|
|
246
265
|
}
|
|
@@ -255,7 +274,7 @@ export class CapabilityRegistry {
|
|
|
255
274
|
[builtinPlugin.id, "kibi-plugin-builtin"],
|
|
256
275
|
]);
|
|
257
276
|
const providerIds = new Set([
|
|
258
|
-
|
|
277
|
+
builtinCapability.id ?? builtinPlugin.id,
|
|
259
278
|
]);
|
|
260
279
|
for (const entry of relevant) {
|
|
261
280
|
const modeConfig = entry.capabilities[capabilityId];
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
export type SourceClassification = Readonly<{
|
|
2
2
|
kind: "language";
|
|
3
3
|
language: string;
|
|
4
|
-
source: "extension" | "shebang" | "explicit";
|
|
4
|
+
source: "extension" | "shebang" | "explicit" | "content";
|
|
5
5
|
}> | Readonly<{
|
|
6
6
|
kind: "file-level";
|
|
7
7
|
language: string;
|
|
8
|
-
source: "extension" | "shebang" | "explicit";
|
|
8
|
+
source: "extension" | "shebang" | "explicit" | "content";
|
|
9
9
|
reason: string;
|
|
10
10
|
}> | Readonly<{
|
|
11
11
|
kind: "ambiguous";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"source-classification.d.ts","sourceRoot":"","sources":["../../src/plugins/source-classification.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,oBAAoB,GAC5B,QAAQ,CAAC;IACP,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,WAAW,GAAG,SAAS,GAAG,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"source-classification.d.ts","sourceRoot":"","sources":["../../src/plugins/source-classification.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,oBAAoB,GAC5B,QAAQ,CAAC;IACP,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,WAAW,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,CAAC;CAC1D,CAAC,GACF,QAAQ,CAAC;IACP,IAAI,EAAE,YAAY,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,WAAW,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,CAAC;IACzD,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC,GACF,QAAQ,CAAC;IACP,IAAI,EAAE,WAAW,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9B,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC,GACF,QAAQ,CAAC;IACP,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE,SAAS,CAAC;IACpB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC,GACF,QAAQ,CAAC;IACP,IAAI,EAAE,SAAS,CAAC;IAChB,QAAQ,EAAE,SAAS,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC,CAAC;AAwGP;;;;GAIG;AAEH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,6EAA6E;AAE7E,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAG1D;AAED,wEAAwE;AAExE,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAM/D;AAED,+EAA+E;AAE/E,wBAAgB,oBAAoB,IAAI,SAAS,MAAM,EAAE,CAExD;AA2RD,qGAAqG;AACrG,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,oBAAoB,CAAC,EAAE,MAAM,GAC5B,oBAAoB,CAiKtB"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const MAX_SHEBANG_LENGTH = 512;
|
|
2
|
+
const MAX_CONTENT_SNIFF_LENGTH = 65_536;
|
|
2
3
|
const MAX_SHEBANG_TOKENS = 16;
|
|
3
4
|
const MAX_TOKEN_LENGTH = 128;
|
|
4
5
|
const EXTENSIONS = {
|
|
@@ -33,6 +34,7 @@ const EXTENSIONS = {
|
|
|
33
34
|
".mjs": { kind: "language", language: "javascript" },
|
|
34
35
|
".mts": { kind: "language", language: "typescript" },
|
|
35
36
|
".php": { kind: "language", language: "php" },
|
|
37
|
+
".plt": { kind: "language", language: "prolog" },
|
|
36
38
|
".pl": {
|
|
37
39
|
kind: "ambiguous",
|
|
38
40
|
language: "perl-or-prolog",
|
|
@@ -112,7 +114,6 @@ const FILE_LEVEL_LANGUAGES = new Set([
|
|
|
112
114
|
"html",
|
|
113
115
|
"json",
|
|
114
116
|
"perl",
|
|
115
|
-
"prolog",
|
|
116
117
|
"shell",
|
|
117
118
|
"sql",
|
|
118
119
|
"yaml",
|
|
@@ -341,6 +342,24 @@ function shebangFor(content) {
|
|
|
341
342
|
}
|
|
342
343
|
return interpreterFor(words[0]);
|
|
343
344
|
}
|
|
345
|
+
// Lines only Prolog source starts with: a directive, a clause or DCG rule
|
|
346
|
+
// whose head is an atom or compound term, or a one-line fact.
|
|
347
|
+
const PROLOG_LINE = /^(?::-\s|[a-z][A-Za-z0-9_]*(?:\([^\n]*\))?\s*(?::-|-->)(?:\s|$)|[a-z][A-Za-z0-9_]*\([^\n;]*\)\.[ \t]*(?:%[^\n]*)?$)/m;
|
|
348
|
+
// Lines only Perl source starts with.
|
|
349
|
+
const PERL_LINE = /^(?:\s*use\s+(?:strict|warnings|utf8|[A-Z][\w:]*)\b[^\n]*;|\s*package\s+[A-Za-z_][\w:]*\s*;|\s*sub\s+[A-Za-z_]\w*\s*\{|\s*my\s+[$@%]|=(?:pod|head1)\b|__(?:END|DATA)__$)/m;
|
|
350
|
+
/**
|
|
351
|
+
* Resolves a `.pl` file without a shebang to Prolog or Perl when only one of
|
|
352
|
+
* them matches its leading content. Both or neither leaves it ambiguous.
|
|
353
|
+
*/
|
|
354
|
+
// implements REQ-multilingual-language-catalog
|
|
355
|
+
function perlOrPrologByContent(content) {
|
|
356
|
+
const prefix = content.slice(0, MAX_CONTENT_SNIFF_LENGTH);
|
|
357
|
+
const prolog = PROLOG_LINE.test(prefix);
|
|
358
|
+
const perl = PERL_LINE.test(prefix);
|
|
359
|
+
if (prolog === perl)
|
|
360
|
+
return undefined;
|
|
361
|
+
return prolog ? "prolog" : "perl";
|
|
362
|
+
}
|
|
344
363
|
function classificationForLanguage(language, source) {
|
|
345
364
|
if (FILE_LEVEL_LANGUAGES.has(language)) {
|
|
346
365
|
return {
|
|
@@ -398,6 +417,11 @@ export function classifySource(filePath, content, explicitLanguageHint) {
|
|
|
398
417
|
return classificationForLanguage(explicit, "explicit");
|
|
399
418
|
}
|
|
400
419
|
if (extension?.kind === "ambiguous") {
|
|
420
|
+
const contentLanguage = shebang === undefined && extension.language === "perl-or-prolog"
|
|
421
|
+
? perlOrPrologByContent(content)
|
|
422
|
+
: undefined;
|
|
423
|
+
if (contentLanguage !== undefined)
|
|
424
|
+
return classificationForLanguage(contentLanguage, "content");
|
|
401
425
|
if (shebang === undefined) {
|
|
402
426
|
return {
|
|
403
427
|
kind: "ambiguous",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codec.d.ts","sourceRoot":"","sources":["../../src/prolog/codec.ts"],"names":[],"mappings":"AAUA;;;GAGG;AAEH;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAYhD;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAIlD;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CASpD;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGvD;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,CAU5D;AAED,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,GACrC,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAO9B;AAED,wBAAgB,uBAAuB,CAAC,CAAC,EACvC,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,EAClC,QAAQ,EAAE,CAAC,GACV,CAAC,GAAG,IAAI,CAEV;AAID,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,EACtC,QAAQ,EAAE,MAAM,GACf,OAAO,CAoCT;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAMjD;AAED,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,GACrC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAiBzB;AAED,wBAAgB,sBAAsB,CAEpC,UAAU,EAAE,MAAM,GACjB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAGzB;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAqB3E;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAuD3E;AAED,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CA6D5D;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,CAG7E;
|
|
1
|
+
{"version":3,"file":"codec.d.ts","sourceRoot":"","sources":["../../src/prolog/codec.ts"],"names":[],"mappings":"AAUA;;;GAGG;AAEH;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAYhD;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAIlD;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CASpD;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGvD;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,CAU5D;AAED,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,GACrC,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAO9B;AAED,wBAAgB,uBAAuB,CAAC,CAAC,EACvC,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,EAClC,QAAQ,EAAE,CAAC,GACV,CAAC,GAAG,IAAI,CAEV;AAID,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,EACtC,QAAQ,EAAE,MAAM,GACf,OAAO,CAoCT;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAMjD;AAED,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,GACrC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAiBzB;AAED,wBAAgB,sBAAsB,CAEpC,UAAU,EAAE,MAAM,GACjB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAGzB;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAqB3E;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAuD3E;AAED,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CA6D5D;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,CAG7E;AA2ED,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,CAGtE;AAYD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAUvD;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAenD;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAmBlE;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAoBzE;AAyCD;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,EAAE,CA6DjE"}
|
package/dist/prolog/codec.js
CHANGED
|
@@ -274,27 +274,25 @@ export function splitTopLevelGeneral(str, delimiter) {
|
|
|
274
274
|
// implements REQ-009
|
|
275
275
|
return scanTopLevelGeneral(str, delimiter).parts;
|
|
276
276
|
}
|
|
277
|
+
// Parts are sliced from the input rather than built a character at a time:
|
|
278
|
+
// candidate pages run to megabytes, and per-character concatenation made
|
|
279
|
+
// scanning them most of a search's parsing time.
|
|
277
280
|
function scanTopLevelGeneral(str, delimiter) {
|
|
278
281
|
const results = [];
|
|
279
|
-
let
|
|
282
|
+
let partStart = 0;
|
|
280
283
|
let quote = null;
|
|
281
284
|
const delimiters = [];
|
|
282
285
|
let balanced = true;
|
|
283
286
|
for (let i = 0; i < str.length; i++) {
|
|
284
287
|
const char = str[i];
|
|
285
288
|
if (quote !== null) {
|
|
286
|
-
current += char;
|
|
287
289
|
if (char === "\\") {
|
|
288
|
-
|
|
289
|
-
if (escaped !== undefined) {
|
|
290
|
-
current += escaped;
|
|
290
|
+
if (i + 1 < str.length)
|
|
291
291
|
i++;
|
|
292
|
-
}
|
|
293
292
|
}
|
|
294
293
|
else if (char === quote) {
|
|
295
294
|
const doubledPrologQuote = quote === "'" && str[i + 1] === "'";
|
|
296
295
|
if (doubledPrologQuote) {
|
|
297
|
-
current += str[i + 1] ?? "";
|
|
298
296
|
i++;
|
|
299
297
|
}
|
|
300
298
|
else {
|
|
@@ -305,12 +303,10 @@ function scanTopLevelGeneral(str, delimiter) {
|
|
|
305
303
|
}
|
|
306
304
|
if (char === "'" || char === '"') {
|
|
307
305
|
quote = char;
|
|
308
|
-
current += char;
|
|
309
306
|
continue;
|
|
310
307
|
}
|
|
311
308
|
if (char === "[" || char === "(" || char === "{") {
|
|
312
309
|
delimiters.push(char);
|
|
313
|
-
current += char;
|
|
314
310
|
continue;
|
|
315
311
|
}
|
|
316
312
|
if (char === "]" || char === ")" || char === "}") {
|
|
@@ -321,25 +317,19 @@ function scanTopLevelGeneral(str, delimiter) {
|
|
|
321
317
|
else {
|
|
322
318
|
delimiters.pop();
|
|
323
319
|
}
|
|
324
|
-
current += char;
|
|
325
320
|
continue;
|
|
326
321
|
}
|
|
327
322
|
if (delimiters.length === 0 &&
|
|
328
323
|
delimiter.length > 0 &&
|
|
329
324
|
str.startsWith(delimiter, i)) {
|
|
330
|
-
if (
|
|
331
|
-
results.push(
|
|
332
|
-
current = "";
|
|
333
|
-
}
|
|
325
|
+
if (i > partStart)
|
|
326
|
+
results.push(str.slice(partStart, i));
|
|
334
327
|
i += delimiter.length - 1;
|
|
328
|
+
partStart = i + 1;
|
|
335
329
|
}
|
|
336
|
-
else {
|
|
337
|
-
current += char;
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
if (current) {
|
|
341
|
-
results.push(current);
|
|
342
330
|
}
|
|
331
|
+
if (str.length > partStart)
|
|
332
|
+
results.push(str.slice(partStart));
|
|
343
333
|
return {
|
|
344
334
|
parts: results,
|
|
345
335
|
balanced: balanced && quote === null && delimiters.length === 0,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"coverage-depth-quality.d.ts","sourceRoot":"","sources":["../../../src/public/impact/coverage-depth-quality.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,gBAAgB,EACjB,MAAM,8BAA8B,CAAC;AAEtC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"coverage-depth-quality.d.ts","sourceRoot":"","sources":["../../../src/public/impact/coverage-depth-quality.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,gBAAgB,EACjB,MAAM,8BAA8B,CAAC;AAEtC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAgLpD,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,MAAM,EAAE,CAI1E;AA2KD,wBAAgB,qCAAqC,CACnD,eAAe,EAAE,SAAS,gBAAgB,EAAE,EAC5C,kBAAkB,GAAE,WAAW,CAC7B,MAAM,EACN,QAAQ,CAAC;IACP,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,eAAe,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7C,QAAQ,CAAC,eAAe,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC9C,CAAC,CACS,GACZ,SAAS,iBAAiB,EAAE,CAoB9B;AAID;;;;;GAKG;AAEH,wBAAgB,oCAAoC,CAClD,eAAe,EAAE,SAAS,gBAAgB,EAAE,GAC3C,SAAS,iBAAiB,EAAE,CA2D9B"}
|
|
@@ -1,4 +1,29 @@
|
|
|
1
1
|
import { COARSE_GRANULARITY_REASONS } from "../symbol-granularity.generated.js";
|
|
2
|
+
function incomingKey(type, relationshipType, targetId) {
|
|
3
|
+
return `${type}\0${relationshipType}\0${targetId}`;
|
|
4
|
+
}
|
|
5
|
+
function coverageIndex(manifestResults) {
|
|
6
|
+
const incomingByTarget = new Map();
|
|
7
|
+
// A result linking the same target twice is listed twice; every reader
|
|
8
|
+
// dedupes by entity id.
|
|
9
|
+
for (const result of manifestResults) {
|
|
10
|
+
for (const relationship of result.relationships) {
|
|
11
|
+
const key = incomingKey(result.entity.type, relationship.type, relationship.to);
|
|
12
|
+
const list = incomingByTarget.get(key);
|
|
13
|
+
if (list === undefined)
|
|
14
|
+
incomingByTarget.set(key, [result.entity]);
|
|
15
|
+
else
|
|
16
|
+
list.push(result.entity);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return {
|
|
20
|
+
resultsById: new Map(manifestResults.map((manifestResult) => [
|
|
21
|
+
manifestResult.entity.id,
|
|
22
|
+
manifestResult,
|
|
23
|
+
])),
|
|
24
|
+
incomingByTarget,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
2
27
|
function entitiesById(manifestResults) {
|
|
3
28
|
return new Map(manifestResults.map((result) => [result.entity.id, result.entity]));
|
|
4
29
|
}
|
|
@@ -11,14 +36,7 @@ function outgoingTargets(lookup) {
|
|
|
11
36
|
});
|
|
12
37
|
}
|
|
13
38
|
function incomingSources(lookup) {
|
|
14
|
-
return lookup.
|
|
15
|
-
if (result.entity.type !== lookup.type)
|
|
16
|
-
return [];
|
|
17
|
-
return result.relationships.some((relationship) => relationship.type === lookup.relationshipType &&
|
|
18
|
-
relationship.to === lookup.targetId)
|
|
19
|
-
? [result.entity]
|
|
20
|
-
: [];
|
|
21
|
-
});
|
|
39
|
+
return (lookup.index.incomingByTarget.get(incomingKey(lookup.type, lookup.relationshipType, lookup.targetId)) ?? []);
|
|
22
40
|
}
|
|
23
41
|
function uniqueEntities(entities) {
|
|
24
42
|
return [
|
|
@@ -129,11 +147,8 @@ function createDiagnostic(coverage, proofEvidence) {
|
|
|
129
147
|
},
|
|
130
148
|
};
|
|
131
149
|
}
|
|
132
|
-
function coverageForRequirement(result,
|
|
133
|
-
const resultsById =
|
|
134
|
-
manifestResult.entity.id,
|
|
135
|
-
manifestResult,
|
|
136
|
-
]));
|
|
150
|
+
function coverageForRequirement(result, index, entities) {
|
|
151
|
+
const resultsById = index.resultsById;
|
|
137
152
|
const scenarios = outgoingTargets({
|
|
138
153
|
result,
|
|
139
154
|
relationshipType: "specified_by",
|
|
@@ -154,7 +169,7 @@ function coverageForRequirement(result, manifestResults, entities) {
|
|
|
154
169
|
entities,
|
|
155
170
|
}),
|
|
156
171
|
...incomingSources({
|
|
157
|
-
|
|
172
|
+
index,
|
|
158
173
|
targetId: result.entity.id,
|
|
159
174
|
relationshipType: "validates",
|
|
160
175
|
type: "test",
|
|
@@ -164,7 +179,7 @@ function coverageForRequirement(result, manifestResults, entities) {
|
|
|
164
179
|
const scenarioResult = resultsById.get(scenario.id);
|
|
165
180
|
return [
|
|
166
181
|
...incomingSources({
|
|
167
|
-
|
|
182
|
+
index,
|
|
168
183
|
targetId: scenario.id,
|
|
169
184
|
relationshipType: "validates",
|
|
170
185
|
type: "test",
|
|
@@ -215,11 +230,12 @@ function isReviewableRequirement(requirement, superseded) {
|
|
|
215
230
|
export function createCoverageDepthQualityDiagnostics(manifestResults, proofByRequirement = new Map()) {
|
|
216
231
|
const entities = entitiesById(manifestResults);
|
|
217
232
|
const superseded = supersededRequirementIds(manifestResults);
|
|
233
|
+
const index = coverageIndex(manifestResults);
|
|
218
234
|
return manifestResults
|
|
219
235
|
.filter((result) => result.entity.type === "req" &&
|
|
220
236
|
isReviewableRequirement(result.entity, superseded))
|
|
221
237
|
.flatMap((result) => {
|
|
222
|
-
const diagnostic = createDiagnostic(coverageForRequirement(result,
|
|
238
|
+
const diagnostic = createDiagnostic(coverageForRequirement(result, index, entities), proofByRequirement.get(result.entity.id));
|
|
223
239
|
return diagnostic === undefined ? [] : [diagnostic];
|
|
224
240
|
})
|
|
225
241
|
.toSorted((left, right) => (left.entityId ?? "").localeCompare(right.entityId ?? ""));
|
|
@@ -9,6 +9,12 @@ type FullKbQualityDiagnosticsOptions = {
|
|
|
9
9
|
readonly now?: Date;
|
|
10
10
|
readonly proofSnapshot?: string;
|
|
11
11
|
readonly checkedAt?: string;
|
|
12
|
+
/**
|
|
13
|
+
* The per-contract receipt bindings kb_coverage uses (a Prolog
|
|
14
|
+
* TestId -> binding hash dict), or null for strict snapshot binding. Read
|
|
15
|
+
* lazily so a check without proof evidence never pays for it.
|
|
16
|
+
*/
|
|
17
|
+
readonly proofTestBindings?: () => Promise<string | null>;
|
|
12
18
|
};
|
|
13
19
|
export declare function loadKbExtractionResults(prolog: Pick<PrologPort, "query" | "queryEntities">): Promise<ExtractionResult[]>;
|
|
14
20
|
export declare function passingE2eStage(passingE2e: unknown): Readonly<Record<string, unknown>> | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"full-kb-quality.d.ts","sourceRoot":"","sources":["../../../src/public/impact/full-kb-quality.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAEV,gBAAgB,EACjB,MAAM,8BAA8B,CAAC;AAatC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAcjE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AASpD,KAAK,+BAA+B,GAAG;IACrC,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,OAAO,GAAG,eAAe,CAAC,CAAC;IAC7D,QAAQ,CAAC,sBAAsB,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACtD,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC;IACpB,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"full-kb-quality.d.ts","sourceRoot":"","sources":["../../../src/public/impact/full-kb-quality.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAEV,gBAAgB,EACjB,MAAM,8BAA8B,CAAC;AAatC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAcjE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AASpD,KAAK,+BAA+B,GAAG;IACrC,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,OAAO,GAAG,eAAe,CAAC,CAAC;IAC7D,QAAQ,CAAC,sBAAsB,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACtD,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC;IACpB,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;OAIG;IACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CAC3D,CAAC;AAqgBF,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,OAAO,GAAG,eAAe,CAAC,GAClD,OAAO,CAAC,gBAAgB,EAAE,CAAC,CA8C7B;AAED,wBAAgB,eAAe,CAC7B,UAAU,EAAE,OAAO,GAClB,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,SAAS,CAM/C;AAkJD,wBAAsB,+BAA+B,CACnD,OAAO,EAAE,+BAA+B,GACvC,OAAO,CAAC,SAAS,iBAAiB,EAAE,CAAC,CAoCvC"}
|
|
@@ -450,7 +450,7 @@ export function passingE2eStage(passingE2e) {
|
|
|
450
450
|
function stringArrayField(value) {
|
|
451
451
|
return Array.isArray(value) ? value.map(String) : undefined;
|
|
452
452
|
}
|
|
453
|
-
async function loadCoverageProofEvidence(prolog, requirementCount, proofSnapshot, checkedAt) {
|
|
453
|
+
async function loadCoverageProofEvidence(prolog, requirementCount, proofSnapshot, checkedAt, proofTestBindings) {
|
|
454
454
|
if (proofSnapshot === undefined ||
|
|
455
455
|
checkedAt === undefined ||
|
|
456
456
|
requirementCount === 0) {
|
|
@@ -458,11 +458,16 @@ async function loadCoverageProofEvidence(prolog, requirementCount, proofSnapshot
|
|
|
458
458
|
}
|
|
459
459
|
let payload;
|
|
460
460
|
try {
|
|
461
|
+
// Judge receipts with the binding kb_coverage uses; under strict snapshot
|
|
462
|
+
// binding any unrelated change since kibi prove would read every receipt
|
|
463
|
+
// as stale and bring back the weak-depth review.
|
|
464
|
+
const bindings = (await proofTestBindings?.()) ?? null;
|
|
465
|
+
const binding = bindings === null ? "strict_snapshot, _{}" : `per_contract, ${bindings}`;
|
|
461
466
|
// W1 push-down: the slim evidence projection returns only the fields the
|
|
462
467
|
// quality diagnostics consume, keeping the response far below the output
|
|
463
468
|
// capacity limit on large KBs (the full coverage report rows were the
|
|
464
469
|
// original ENOBUFS offender).
|
|
465
|
-
payload = await runOperationJsonQuery(prolog, "discovery.pl", `discovery:coverage_evidence_json(${toPrologList([])}, ${toPrologAtom(proofSnapshot)}, ${toPrologAtom(checkedAt)}, ${PROOF_RECEIPT_MAX_AGE_SECONDS}, JsonString)`, "Quality diagnostic coverage evidence");
|
|
470
|
+
payload = await runOperationJsonQuery(prolog, "discovery.pl", `discovery:coverage_evidence_json(${toPrologList([])}, ${binding}, ${toPrologAtom(proofSnapshot)}, ${toPrologAtom(checkedAt)}, ${PROOF_RECEIPT_MAX_AGE_SECONDS}, JsonString)`, "Quality diagnostic coverage evidence");
|
|
466
471
|
}
|
|
467
472
|
catch {
|
|
468
473
|
// Quality diagnostics must fail closed when the optional proof readback is
|
|
@@ -542,7 +547,7 @@ export async function collectFullKbQualityDiagnostics(options) {
|
|
|
542
547
|
loadKbExtractionResults(options.prolog),
|
|
543
548
|
collectTelemetryDiagnostics(options.workspaceRoot, options.now ?? new Date()),
|
|
544
549
|
]);
|
|
545
|
-
const proofEvidence = await loadCoverageProofEvidence(options.prolog, manifestResults.filter((result) => result.entity.type === "req").length, options.proofSnapshot, options.checkedAt);
|
|
550
|
+
const proofEvidence = await loadCoverageProofEvidence(options.prolog, manifestResults.filter((result) => result.entity.type === "req").length, options.proofSnapshot, options.checkedAt, options.proofTestBindings);
|
|
546
551
|
const coverageDepthDiagnostics = createCoverageDepthQualityDiagnostics(manifestResults, proofEvidence);
|
|
547
552
|
const diagnostics = [
|
|
548
553
|
...telemetryDiagnostics,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"requirement-quality.d.ts","sourceRoot":"","sources":["../../../src/public/impact/requirement-quality.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,0CAA0C,CAAC;AACrF,OAAO,KAAK,EAAE,oCAAoC,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"requirement-quality.d.ts","sourceRoot":"","sources":["../../../src/public/impact/requirement-quality.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,0CAA0C,CAAC;AACrF,OAAO,KAAK,EAAE,oCAAoC,EAAE,MAAM,YAAY,CAAC;AAoTvE,wBAAgB,mCAAmC,CACjD,OAAO,EAAE,oCAAoC,GAC5C,oBAAoB,EAAE,CAMxB"}
|
|
@@ -42,41 +42,67 @@ function targetHasType(targetId, type, typesByEntityId) {
|
|
|
42
42
|
const targetType = typesByEntityId.get(targetId);
|
|
43
43
|
return targetType === undefined || targetType === type;
|
|
44
44
|
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
const
|
|
48
|
-
const
|
|
49
|
-
const
|
|
45
|
+
/** One pass over every relationship, so each requirement's fanout is a lookup. */
|
|
46
|
+
function fanoutIndex(results) {
|
|
47
|
+
const relationshipsByEntityId = new Map();
|
|
48
|
+
const implementerIdsByRequirementId = new Map();
|
|
49
|
+
const dependentRequirementIdsByRequirementId = new Map();
|
|
50
|
+
const append = (index, key, value) => {
|
|
51
|
+
const list = index.get(key);
|
|
52
|
+
if (list === undefined)
|
|
53
|
+
index.set(key, [value]);
|
|
54
|
+
else
|
|
55
|
+
list.push(value);
|
|
56
|
+
};
|
|
50
57
|
for (const result of results) {
|
|
58
|
+
const relationships = relationshipsByEntityId.get(result.entity.id);
|
|
59
|
+
if (relationships === undefined) {
|
|
60
|
+
relationshipsByEntityId.set(result.entity.id, [...result.relationships]);
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
relationships.push(...result.relationships);
|
|
64
|
+
}
|
|
51
65
|
for (const relationship of result.relationships) {
|
|
52
|
-
if (relationship.type === "implements"
|
|
53
|
-
relationship.to
|
|
54
|
-
implementingSymbolIds.push(result.entity.id);
|
|
55
|
-
}
|
|
56
|
-
if (result.entity.id === requirementId &&
|
|
57
|
-
relationship.type === "specified_by" &&
|
|
58
|
-
targetHasType(relationship.to, "scenario", typesByEntityId)) {
|
|
59
|
-
scenarioIds.push(relationship.to);
|
|
66
|
+
if (relationship.type === "implements") {
|
|
67
|
+
append(implementerIdsByRequirementId, relationship.to, result.entity.id);
|
|
60
68
|
}
|
|
61
|
-
if (result.entity.
|
|
62
|
-
(relationship.
|
|
63
|
-
relationship.type === "covered_by") &&
|
|
64
|
-
targetHasType(relationship.to, "test", typesByEntityId)) {
|
|
65
|
-
testIds.push(relationship.to);
|
|
66
|
-
}
|
|
67
|
-
if (relationship.type === "depends_on") {
|
|
68
|
-
if (result.entity.id === requirementId &&
|
|
69
|
-
targetHasType(relationship.to, "req", typesByEntityId)) {
|
|
70
|
-
dependentRequirementIds.push(relationship.to);
|
|
71
|
-
}
|
|
72
|
-
if (relationship.to === requirementId && result.entity.type === "req") {
|
|
73
|
-
dependentRequirementIds.push(result.entity.id);
|
|
74
|
-
}
|
|
69
|
+
if (relationship.type === "depends_on" && result.entity.type === "req") {
|
|
70
|
+
append(dependentRequirementIdsByRequirementId, relationship.to, result.entity.id);
|
|
75
71
|
}
|
|
76
72
|
}
|
|
77
73
|
}
|
|
78
74
|
return {
|
|
79
|
-
|
|
75
|
+
relationshipsByEntityId,
|
|
76
|
+
implementerIdsByRequirementId,
|
|
77
|
+
dependentRequirementIdsByRequirementId,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
function collectFanout(requirementId, index, typesByEntityId) {
|
|
81
|
+
const scenarioIds = [];
|
|
82
|
+
const testIds = [];
|
|
83
|
+
const dependentRequirementIds = [];
|
|
84
|
+
// rationale: every requirement this is called for is in the index, so the
|
|
85
|
+
// fallback list is never read.
|
|
86
|
+
// Stryker disable next-line ArrayDeclaration
|
|
87
|
+
const relationships = index.relationshipsByEntityId.get(requirementId) ?? [];
|
|
88
|
+
for (const relationship of relationships) {
|
|
89
|
+
if (relationship.type === "specified_by" &&
|
|
90
|
+
targetHasType(relationship.to, "scenario", typesByEntityId)) {
|
|
91
|
+
scenarioIds.push(relationship.to);
|
|
92
|
+
}
|
|
93
|
+
if ((relationship.type === "verified_by" ||
|
|
94
|
+
relationship.type === "covered_by") &&
|
|
95
|
+
targetHasType(relationship.to, "test", typesByEntityId)) {
|
|
96
|
+
testIds.push(relationship.to);
|
|
97
|
+
}
|
|
98
|
+
if (relationship.type === "depends_on" &&
|
|
99
|
+
targetHasType(relationship.to, "req", typesByEntityId)) {
|
|
100
|
+
dependentRequirementIds.push(relationship.to);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
dependentRequirementIds.push(...(index.dependentRequirementIdsByRequirementId.get(requirementId) ?? []));
|
|
104
|
+
return {
|
|
105
|
+
implementingSymbolIds: sortedUnique(index.implementerIdsByRequirementId.get(requirementId) ?? []),
|
|
80
106
|
scenarioIds: sortedUnique(scenarioIds),
|
|
81
107
|
testIds: sortedUnique(testIds),
|
|
82
108
|
dependentRequirementIds: sortedUnique(dependentRequirementIds),
|
|
@@ -96,10 +122,11 @@ function isUmbrellaRequirement(result) {
|
|
|
96
122
|
}
|
|
97
123
|
function createBroadRequirementDiagnostics(results) {
|
|
98
124
|
const typesByEntityId = entityTypeById(results);
|
|
125
|
+
const index = fanoutIndex(results);
|
|
99
126
|
return results.flatMap((result) => {
|
|
100
127
|
if (!isCurrentRequirement(result))
|
|
101
128
|
return [];
|
|
102
|
-
const fanout = collectFanout(result.entity.id,
|
|
129
|
+
const fanout = collectFanout(result.entity.id, index, typesByEntityId);
|
|
103
130
|
if (!exceedsBroadThreshold(fanout))
|
|
104
131
|
return [];
|
|
105
132
|
if (isUmbrellaRequirement(result))
|