kibi-cli 2.2.0 → 2.3.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-operation-loader.d.ts.map +1 -1
- package/dist/cli-operation-loader.js +3 -0
- package/dist/cli-operation-metadata.d.ts +4 -0
- package/dist/cli-operation-metadata.d.ts.map +1 -1
- package/dist/cli-operation-metadata.js +5 -0
- package/dist/cli-register-reporting.d.ts.map +1 -1
- package/dist/cli-register-reporting.js +4 -0
- package/dist/commands/check-diff.d.ts +5 -0
- package/dist/commands/check-diff.d.ts.map +1 -0
- package/dist/commands/check-diff.js +62 -0
- package/dist/commands/check-generated.d.ts.map +1 -1
- package/dist/commands/check-generated.js +41 -18
- package/dist/commands/check.d.ts.map +1 -1
- package/dist/commands/check.js +210 -73
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +63 -29
- package/dist/commands/github-init.d.ts.map +1 -1
- package/dist/commands/github-init.js +9 -2
- package/dist/commands/sync/manifest.d.ts.map +1 -1
- package/dist/commands/sync/manifest.js +3 -1
- package/dist/engine.d.ts +15 -1
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +252 -52
- package/dist/extractors/symbols-coordinator.d.ts +7 -0
- package/dist/extractors/symbols-coordinator.d.ts.map +1 -1
- package/dist/extractors/symbols-coordinator.js +75 -39
- package/dist/operations/modeling/predicate-inference-1.js +1 -1
- package/dist/operations/mutation/source-authoring.d.ts.map +1 -1
- package/dist/operations/mutation/source-authoring.js +175 -53
- package/dist/operations/mutation/upsert.d.ts.map +1 -1
- package/dist/operations/mutation/upsert.js +5 -7
- package/dist/operations/planning/apply-plan.d.ts.map +1 -1
- package/dist/operations/planning/apply-plan.js +5 -9
- package/dist/operations/proof/ingest-proof.d.ts.map +1 -1
- package/dist/operations/proof/ingest-proof.js +1 -0
- package/dist/operations/semantic-advisor/analysis-receipt.d.ts.map +1 -1
- package/dist/operations/semantic-advisor/analysis-receipt.js +7 -1
- package/dist/operations/semantic-advisor/analyze-prose.d.ts.map +1 -1
- package/dist/operations/semantic-advisor/analyze-prose.js +26 -4
- package/dist/operations/semantic-advisor/clauses.d.ts +1 -0
- package/dist/operations/semantic-advisor/clauses.d.ts.map +1 -1
- package/dist/operations/semantic-advisor/clauses.js +7 -1
- package/dist/performance-trace.d.ts +17 -0
- package/dist/performance-trace.d.ts.map +1 -0
- package/dist/performance-trace.js +134 -0
- package/dist/plugins/approved-source-analyzers.d.ts +13 -0
- package/dist/plugins/approved-source-analyzers.d.ts.map +1 -0
- package/dist/plugins/approved-source-analyzers.generated.d.ts +71 -0
- package/dist/plugins/approved-source-analyzers.generated.d.ts.map +1 -0
- package/dist/plugins/approved-source-analyzers.generated.js +77 -0
- package/dist/plugins/approved-source-analyzers.js +3 -0
- package/dist/plugins/maintenance-source-analysis.d.ts +14 -0
- package/dist/plugins/maintenance-source-analysis.d.ts.map +1 -0
- package/dist/plugins/maintenance-source-analysis.js +191 -0
- package/dist/plugins/registry.d.ts +2 -1
- package/dist/plugins/registry.d.ts.map +1 -1
- package/dist/plugins/registry.js +6 -1
- package/dist/plugins/source-analysis-service.d.ts +36 -1
- package/dist/plugins/source-analysis-service.d.ts.map +1 -1
- package/dist/plugins/source-analysis-service.js +184 -27
- package/dist/plugins/source-change-analysis.d.ts +15 -0
- package/dist/plugins/source-change-analysis.d.ts.map +1 -0
- package/dist/plugins/source-change-analysis.js +54 -0
- package/dist/plugins/source-classification.d.ts +41 -0
- package/dist/plugins/source-classification.d.ts.map +1 -0
- package/dist/plugins/source-classification.js +490 -0
- package/dist/prolog/swipl-resolver.d.ts +88 -0
- package/dist/prolog/swipl-resolver.d.ts.map +1 -0
- package/dist/prolog/swipl-resolver.js +446 -0
- package/dist/prolog.d.ts +15 -1
- package/dist/prolog.d.ts.map +1 -1
- package/dist/prolog.js +67 -6
- package/dist/public/impact/analyzer.d.ts.map +1 -1
- package/dist/public/impact/analyzer.js +56 -5
- package/dist/public/impact/diagnostics.d.ts.map +1 -1
- package/dist/public/impact/diagnostics.js +3 -1
- package/dist/public/impact/manifest.d.ts.map +1 -1
- package/dist/public/impact/manifest.js +15 -1
- package/dist/public/impact/source-changes.d.ts.map +1 -1
- package/dist/public/impact/source-changes.js +35 -27
- package/dist/public/impact/types.d.ts +2 -0
- package/dist/public/impact/types.d.ts.map +1 -1
- package/dist/public/operations/catalog.d.ts +44 -0
- package/dist/public/operations/catalog.d.ts.map +1 -1
- package/dist/public/operations/catalog.js +2 -0
- package/dist/public/operations/contracts.d.ts.map +1 -1
- package/dist/public/operations/contracts.js +309 -8
- package/dist/public/operations/impact-review-preparation.d.ts +14 -0
- package/dist/public/operations/impact-review-preparation.d.ts.map +1 -0
- package/dist/public/operations/impact-review-preparation.js +379 -0
- package/dist/public/operations/index.d.ts +2 -0
- package/dist/public/operations/index.d.ts.map +1 -1
- package/dist/public/operations/index.js +2 -0
- package/dist/public/operations/node-ports.d.ts.map +1 -1
- package/dist/public/operations/node-ports.js +1 -35
- package/dist/public/operations/proof-receipt-projection.d.ts +5 -0
- package/dist/public/operations/proof-receipt-projection.d.ts.map +1 -0
- package/dist/public/operations/proof-receipt-projection.js +36 -0
- package/dist/public/operations/specs/impact-review-preparation.d.ts +47 -0
- package/dist/public/operations/specs/impact-review-preparation.d.ts.map +1 -0
- package/dist/public/operations/specs/impact-review-preparation.js +43 -0
- package/dist/public/operations/types.d.ts +1 -1
- package/dist/public/operations/types.d.ts.map +1 -1
- package/dist/public/skills/kibi-usage/resources/operation-access.md +1 -0
- package/dist/traceability/analysis-gate.d.ts +39 -0
- package/dist/traceability/analysis-gate.d.ts.map +1 -0
- package/dist/traceability/analysis-gate.js +51 -0
- package/dist/traceability/git-change-snapshot.d.ts +27 -0
- package/dist/traceability/git-change-snapshot.d.ts.map +1 -0
- package/dist/traceability/git-change-snapshot.js +411 -0
- package/dist/traceability/git-staged.d.ts +5 -1
- package/dist/traceability/git-staged.d.ts.map +1 -1
- package/dist/traceability/git-staged.js +16 -11
- package/dist/traceability/impact-evaluator.d.ts +54 -0
- package/dist/traceability/impact-evaluator.d.ts.map +1 -0
- package/dist/traceability/impact-evaluator.js +270 -0
- package/dist/traceability/impact-git-tree.d.ts +12 -0
- package/dist/traceability/impact-git-tree.d.ts.map +1 -0
- package/dist/traceability/impact-git-tree.js +46 -0
- package/dist/traceability/impact-knowledge.d.ts +16 -0
- package/dist/traceability/impact-knowledge.d.ts.map +1 -0
- package/dist/traceability/impact-knowledge.js +165 -0
- package/dist/traceability/impact-policy.d.ts +15 -0
- package/dist/traceability/impact-policy.d.ts.map +1 -0
- package/dist/traceability/impact-policy.js +48 -0
- package/dist/traceability/impact-policy.v1.schema.json +48 -0
- package/dist/traceability/impact-pr-diff.d.ts +5 -0
- package/dist/traceability/impact-pr-diff.d.ts.map +1 -0
- package/dist/traceability/impact-pr-diff.js +83 -0
- package/dist/traceability/impact-record-validation.d.ts +9 -0
- package/dist/traceability/impact-record-validation.d.ts.map +1 -0
- package/dist/traceability/impact-record-validation.js +113 -0
- package/dist/traceability/impact-review.d.ts +148 -0
- package/dist/traceability/impact-review.d.ts.map +1 -0
- package/dist/traceability/impact-review.js +494 -0
- package/dist/traceability/impact-review.schema.json +365 -0
- package/dist/traceability/impact-side-evidence.d.ts +13 -0
- package/dist/traceability/impact-side-evidence.d.ts.map +1 -0
- package/dist/traceability/impact-side-evidence.js +240 -0
- package/dist/traceability/reviewed-coordinate-refresh.d.ts +10 -0
- package/dist/traceability/reviewed-coordinate-refresh.d.ts.map +1 -0
- package/dist/traceability/reviewed-coordinate-refresh.js +49 -0
- package/dist/traceability/snapshot-knowledge.d.ts +4 -0
- package/dist/traceability/snapshot-knowledge.d.ts.map +1 -0
- package/dist/traceability/snapshot-knowledge.js +98 -0
- package/dist/traceability/staged-file-coverage.d.ts +23 -0
- package/dist/traceability/staged-file-coverage.d.ts.map +1 -1
- package/dist/traceability/staged-impact-contract.d.ts.map +1 -1
- package/dist/traceability/staged-impact-contract.js +2 -16
- package/dist/traceability/staged-symbols-manifest.d.ts +4 -0
- package/dist/traceability/staged-symbols-manifest.d.ts.map +1 -1
- package/dist/traceability/staged-symbols-manifest.js +17 -6
- package/dist/traceability/symbol-extract.d.ts +3 -5
- package/dist/traceability/symbol-extract.d.ts.map +1 -1
- package/dist/traceability/symbol-extract.js +49 -34
- package/dist/traceability/temp-kb.d.ts +1 -1
- package/dist/traceability/temp-kb.d.ts.map +1 -1
- package/dist/traceability/temp-kb.js +49 -13
- package/dist/traceability/trusted-pr-event.d.ts +13 -0
- package/dist/traceability/trusted-pr-event.d.ts.map +1 -0
- package/dist/traceability/trusted-pr-event.js +105 -0
- package/dist/utils/canonical-path.d.ts +3 -0
- package/dist/utils/canonical-path.d.ts.map +1 -0
- package/dist/utils/canonical-path.js +33 -0
- package/package.json +14 -5
- package/src/public/impact/analyzer.ts +88 -5
- package/src/public/impact/diagnostics.ts +7 -5
- package/src/public/impact/manifest.ts +14 -1
- package/src/public/impact/source-changes.ts +39 -34
- package/src/public/impact/types.ts +5 -0
- package/src/public/operations/catalog.ts +2 -0
- package/src/public/operations/contracts.ts +385 -9
- package/src/public/operations/impact-review-preparation.ts +548 -0
- package/src/public/operations/index.ts +2 -0
- package/src/public/operations/node-ports.ts +1 -39
- package/src/public/operations/proof-receipt-projection.ts +39 -0
- package/src/public/operations/specs/impact-review-preparation.ts +46 -0
- package/src/public/operations/types.ts +1 -0
- package/src/public/skills/kibi-usage/resources/operation-access.md +1 -0
- package/src/traceability/impact-policy.v1.schema.json +48 -0
- package/src/traceability/impact-review.schema.json +365 -0
- package/templates/github/kibi-badge.yml +0 -4
- package/templates/github/kibi-report.yml +0 -4
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 { KIBI_PLUGIN_API_VERSION, ONTOLOGY_PACK_CAPABILITY_ID, SEMANTIC_CLASSIFIER_CAPABILITY_ID, SYMBOL_EXTRACTOR_CAPABILITY_ID, VOCABULARY_ALIGNMENT_CAPABILITY_ID, defineKibiPlugin, validateKibiPlugin, } from "kibi-plugin-sdk";
|
|
18
|
+
import { 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";
|
|
19
19
|
import { loadPluginPackage } from "./load-plugin.js";
|
|
20
20
|
import { readProjectKibiConfig } from "./project-config.js";
|
|
21
21
|
import { PluginResolutionError } from "./resolve-package.js";
|
|
@@ -23,6 +23,7 @@ const CAPABILITY_SLOT = {
|
|
|
23
23
|
[SEMANTIC_CLASSIFIER_CAPABILITY_ID]: "semanticClassifier",
|
|
24
24
|
[ONTOLOGY_PACK_CAPABILITY_ID]: "ontologyPack",
|
|
25
25
|
[SYMBOL_EXTRACTOR_CAPABILITY_ID]: "symbolExtractor",
|
|
26
|
+
[SYMBOL_EXTRACTOR_V2_CAPABILITY_ID]: "symbolExtractorV2",
|
|
26
27
|
[VOCABULARY_ALIGNMENT_CAPABILITY_ID]: "vocabularyAlignment",
|
|
27
28
|
};
|
|
28
29
|
/**
|
|
@@ -197,6 +198,10 @@ export class CapabilityRegistry {
|
|
|
197
198
|
async resolveSymbolExtractors() {
|
|
198
199
|
return this.resolveCapability(SYMBOL_EXTRACTOR_CAPABILITY_ID);
|
|
199
200
|
}
|
|
201
|
+
// implements REQ-capability-plugin-activation-disclosure-v1
|
|
202
|
+
async resolveSymbolExtractorsV2() {
|
|
203
|
+
return this.resolveCapability(SYMBOL_EXTRACTOR_V2_CAPABILITY_ID);
|
|
204
|
+
}
|
|
200
205
|
async resolveVocabularyAlignment() {
|
|
201
206
|
return this.resolveCapability(VOCABULARY_ALIGNMENT_CAPABILITY_ID);
|
|
202
207
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type PluginProviderStamp, type SourceAnalysisResult, type SymbolExtractorV1 } from "kibi-plugin-sdk";
|
|
1
|
+
import { type PluginProviderStamp, type SourceAnalysisResult, type SourceAnalysisResultV2, type SymbolExtractorV1, type SymbolExtractorV2 } from "kibi-plugin-sdk";
|
|
2
2
|
import type { CapabilityModeResolution, CapabilityRegistry } from "./registry.js";
|
|
3
3
|
export type HostSourceAnalysisShadowComparison = Readonly<{
|
|
4
4
|
pluginId: string;
|
|
@@ -18,9 +18,21 @@ export type HostSourceAnalysisResult = SourceAnalysisResult & Readonly<{
|
|
|
18
18
|
}>;
|
|
19
19
|
export type SourceAnalysisServiceOptions = Readonly<{
|
|
20
20
|
registry: CapabilityRegistry;
|
|
21
|
+
/** Explicit v2 resolution; maintenance callers supply only approved providers. */
|
|
22
|
+
resolveExtractorsV2?: () => Promise<CapabilityModeResolution<SymbolExtractorV2>>;
|
|
23
|
+
/** Wall-clock deadline for async providers; CPU-bound plugins need their own terminable worker. */
|
|
24
|
+
analysisTimeoutMs?: number;
|
|
25
|
+
/** Host-verified package/asset fingerprint, never accepted from result data. */
|
|
26
|
+
providerFingerprints?: Readonly<Record<string, string>>;
|
|
21
27
|
/** Injectable resolution for tests. */
|
|
22
28
|
resolveExtractors?: () => Promise<CapabilityModeResolution<SymbolExtractorV1>>;
|
|
23
29
|
}>;
|
|
30
|
+
/**
|
|
31
|
+
* The host owns the analysis deadline. Providers get a slightly smaller budget
|
|
32
|
+
* so a cooperative provider reports its own timeout diagnostic before the host
|
|
33
|
+
* abandons the call.
|
|
34
|
+
*/
|
|
35
|
+
export declare function providerBudgetMs(hostTimeoutMs: number): number;
|
|
24
36
|
export declare function createConservativeFallbackAnalysis(filePath: string, fallbackReason: string): HostSourceAnalysisResult;
|
|
25
37
|
/**
|
|
26
38
|
* Host-validated symbol analysis over registry providers with conservative
|
|
@@ -32,8 +44,23 @@ export declare function createConservativeFallbackAnalysis(filePath: string, fal
|
|
|
32
44
|
*/
|
|
33
45
|
export declare class SourceAnalysisService {
|
|
34
46
|
private readonly registry;
|
|
47
|
+
private readonly options;
|
|
35
48
|
private readonly resolveExtractors;
|
|
36
49
|
constructor(options: SourceAnalysisServiceOptions);
|
|
50
|
+
/**
|
|
51
|
+
* Analyze supplied snapshot bytes with explicit completeness and host provenance.
|
|
52
|
+
* An explicit language hint selects an ambiguous extension only when it agrees
|
|
53
|
+
* with any shebang; conflicting signals return unsupported without dispatch.
|
|
54
|
+
*
|
|
55
|
+
* Classify, bound the input, resolve providers, take the first claiming
|
|
56
|
+
* provider's result as canonical, then record shadow comparisons.
|
|
57
|
+
*/
|
|
58
|
+
analyzeTextV2(filePath: string, content: string, explicitLanguageHint?: string): Promise<HostSourceAnalysisResultV2>;
|
|
59
|
+
/**
|
|
60
|
+
* Run one provider under the host-owned deadline. Returns null when the
|
|
61
|
+
* provider does not claim the input; a claimed failure is a failed result.
|
|
62
|
+
*/
|
|
63
|
+
private runV2Extractor;
|
|
37
64
|
analyzeText(filePath: string, content: string): Promise<HostSourceAnalysisResult>;
|
|
38
65
|
}
|
|
39
66
|
/**
|
|
@@ -41,4 +68,12 @@ export declare class SourceAnalysisService {
|
|
|
41
68
|
*/
|
|
42
69
|
export declare function analyzeWithResolution(resolution: CapabilityModeResolution<SymbolExtractorV1>, filePath: string, content: string): Promise<HostSourceAnalysisResult>;
|
|
43
70
|
export declare function createSourceAnalysisService(options: SourceAnalysisServiceOptions): SourceAnalysisService;
|
|
71
|
+
/** V2 results preserve failure/completeness; provenance is always assigned by the host. */
|
|
72
|
+
export type HostSourceAnalysisResultV2 = SourceAnalysisResultV2 & Readonly<{
|
|
73
|
+
providerId: string | null;
|
|
74
|
+
stamp: PluginProviderStamp | null;
|
|
75
|
+
inputFingerprint: string;
|
|
76
|
+
providerFingerprint: string | null;
|
|
77
|
+
shadowComparisons: readonly HostSourceAnalysisShadowComparison[];
|
|
78
|
+
}>;
|
|
44
79
|
//# sourceMappingURL=source-analysis-service.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"source-analysis-service.d.ts","sourceRoot":"","sources":["../../src/plugins/source-analysis-service.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"source-analysis-service.d.ts","sourceRoot":"","sources":["../../src/plugins/source-analysis-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -15,35 +15,73 @@
|
|
|
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 { createHash } from "node:crypto";
|
|
18
19
|
import * as path from "node:path";
|
|
19
|
-
import { toSourceAnalysisProvider, validateSourceAnalysisResultForPath, } from "kibi-plugin-sdk";
|
|
20
|
-
|
|
21
|
-
".c": "c",
|
|
22
|
-
".cc": "cpp",
|
|
23
|
-
".cjs": "javascript",
|
|
24
|
-
".cpp": "cpp",
|
|
25
|
-
".cs": "csharp",
|
|
26
|
-
".cts": "typescript",
|
|
27
|
-
".go": "go",
|
|
28
|
-
".h": "c",
|
|
29
|
-
".hpp": "cpp",
|
|
30
|
-
".java": "java",
|
|
31
|
-
".js": "javascript",
|
|
32
|
-
".jsx": "javascript",
|
|
33
|
-
".kt": "kotlin",
|
|
34
|
-
".mjs": "javascript",
|
|
35
|
-
".mts": "typescript",
|
|
36
|
-
".php": "php",
|
|
37
|
-
".py": "python",
|
|
38
|
-
".rb": "ruby",
|
|
39
|
-
".rs": "rust",
|
|
40
|
-
".swift": "swift",
|
|
41
|
-
".ts": "typescript",
|
|
42
|
-
".tsx": "typescript",
|
|
43
|
-
};
|
|
20
|
+
import { SOURCE_ANALYSIS_V2_MAX_INPUT_CODE_UNITS, SYMBOL_EXTRACTOR_V2_CAPABILITY_ID, toSourceAnalysisProvider, validateSourceAnalysisResultForPath, validateSourceAnalysisResultV2, } from "kibi-plugin-sdk";
|
|
21
|
+
import { classifySource, extensionLanguage } from "./source-classification.js";
|
|
44
22
|
function detectSourceLanguage(filePath) {
|
|
45
|
-
return (
|
|
46
|
-
|
|
23
|
+
return extensionLanguage(filePath);
|
|
24
|
+
}
|
|
25
|
+
/** Classify once and bind every result for this input to one fingerprint. */
|
|
26
|
+
function createV2Request(filePath, content, explicitLanguageHint) {
|
|
27
|
+
const classification = classifySource(filePath, content, explicitLanguageHint);
|
|
28
|
+
const language = classification.language;
|
|
29
|
+
const inputFingerprint = createHash("sha256")
|
|
30
|
+
.update(filePath)
|
|
31
|
+
.update("\0")
|
|
32
|
+
.update(content)
|
|
33
|
+
.update("\0")
|
|
34
|
+
.update(classification.kind)
|
|
35
|
+
.update("\0")
|
|
36
|
+
.update(classification.language)
|
|
37
|
+
.update("\0")
|
|
38
|
+
.update(explicitLanguageHint?.trim().toLowerCase() ?? "")
|
|
39
|
+
.digest("hex");
|
|
40
|
+
return {
|
|
41
|
+
classification,
|
|
42
|
+
input: {
|
|
43
|
+
path: filePath,
|
|
44
|
+
content,
|
|
45
|
+
...(classification.kind === "language"
|
|
46
|
+
? { language: classification.language }
|
|
47
|
+
: {}),
|
|
48
|
+
},
|
|
49
|
+
inputFingerprint,
|
|
50
|
+
fallback: (status, code, message) => ({
|
|
51
|
+
contractVersion: SYMBOL_EXTRACTOR_V2_CAPABILITY_ID,
|
|
52
|
+
status,
|
|
53
|
+
sourceFile: filePath,
|
|
54
|
+
language,
|
|
55
|
+
module: {
|
|
56
|
+
title: inferModuleTitle(filePath),
|
|
57
|
+
language,
|
|
58
|
+
analysisMode: "fallback",
|
|
59
|
+
fallbackReason: code,
|
|
60
|
+
},
|
|
61
|
+
symbols: [],
|
|
62
|
+
diagnostics: [{ code, message }],
|
|
63
|
+
uncoveredRanges: [],
|
|
64
|
+
providerId: null,
|
|
65
|
+
stamp: null,
|
|
66
|
+
inputFingerprint,
|
|
67
|
+
providerFingerprint: null,
|
|
68
|
+
shadowComparisons: [],
|
|
69
|
+
}),
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
function hostDeadlineMs(requested) {
|
|
73
|
+
const value = requested ?? 10000;
|
|
74
|
+
return Number.isFinite(value) && value > 0 ? Math.min(value, 60000) : 10000;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* The host owns the analysis deadline. Providers get a slightly smaller budget
|
|
78
|
+
* so a cooperative provider reports its own timeout diagnostic before the host
|
|
79
|
+
* abandons the call.
|
|
80
|
+
*/
|
|
81
|
+
// implements REQ-source-analysis-v2
|
|
82
|
+
export function providerBudgetMs(hostTimeoutMs) {
|
|
83
|
+
const grace = Math.min(1000, Math.floor(hostTimeoutMs / 10));
|
|
84
|
+
return Math.max(1, hostTimeoutMs - grace);
|
|
47
85
|
}
|
|
48
86
|
function inferModuleTitle(filePath) {
|
|
49
87
|
const extension = path.extname(filePath);
|
|
@@ -100,13 +138,132 @@ function dedupeSymbols(symbols) {
|
|
|
100
138
|
// implements REQ-capability-plugin-activation-disclosure-v1
|
|
101
139
|
export class SourceAnalysisService {
|
|
102
140
|
registry;
|
|
141
|
+
options;
|
|
103
142
|
resolveExtractors;
|
|
104
143
|
constructor(options) {
|
|
105
144
|
this.registry = options.registry;
|
|
145
|
+
this.options = options;
|
|
106
146
|
this.resolveExtractors =
|
|
107
147
|
options.resolveExtractors ??
|
|
108
148
|
(() => this.registry.resolveSymbolExtractors());
|
|
109
149
|
}
|
|
150
|
+
/**
|
|
151
|
+
* Analyze supplied snapshot bytes with explicit completeness and host provenance.
|
|
152
|
+
* An explicit language hint selects an ambiguous extension only when it agrees
|
|
153
|
+
* with any shebang; conflicting signals return unsupported without dispatch.
|
|
154
|
+
*
|
|
155
|
+
* Classify, bound the input, resolve providers, take the first claiming
|
|
156
|
+
* provider's result as canonical, then record shadow comparisons.
|
|
157
|
+
*/
|
|
158
|
+
// implements REQ-capability-plugin-activation-disclosure-v1
|
|
159
|
+
async analyzeTextV2(filePath, content, explicitLanguageHint) {
|
|
160
|
+
const request = createV2Request(filePath, content, explicitLanguageHint);
|
|
161
|
+
const { classification } = request;
|
|
162
|
+
if (content.length > SOURCE_ANALYSIS_V2_MAX_INPUT_CODE_UNITS ||
|
|
163
|
+
Buffer.byteLength(content, "utf8") > 8 * 1024 * 1024)
|
|
164
|
+
return request.fallback("failed", "input_limit", `Source input exceeds the ${SOURCE_ANALYSIS_V2_MAX_INPUT_CODE_UNITS} UTF-16 code unit or 8 MiB UTF-8 analysis limit`);
|
|
165
|
+
let resolution;
|
|
166
|
+
try {
|
|
167
|
+
resolution = await (this.options.resolveExtractorsV2?.() ??
|
|
168
|
+
this.registry.resolveSymbolExtractorsV2());
|
|
169
|
+
}
|
|
170
|
+
catch (error) {
|
|
171
|
+
return request.fallback("failed", "provider_resolution_failed", String(error));
|
|
172
|
+
}
|
|
173
|
+
if (classification.kind !== "language" &&
|
|
174
|
+
classification.kind !== "unknown") {
|
|
175
|
+
const code = classification.kind === "ambiguous"
|
|
176
|
+
? "source_language_ambiguous"
|
|
177
|
+
: classification.kind === "conflict"
|
|
178
|
+
? "source_classification_conflict"
|
|
179
|
+
: classification.kind === "file-level"
|
|
180
|
+
? "source_file_level_only"
|
|
181
|
+
: "unsupported_language";
|
|
182
|
+
return request.fallback("unsupported", code, classification.reason);
|
|
183
|
+
}
|
|
184
|
+
const entries = resolution.replace
|
|
185
|
+
? [resolution.replace, resolution.builtin, ...resolution.augment]
|
|
186
|
+
: [resolution.builtin, ...resolution.augment];
|
|
187
|
+
let canonical = null;
|
|
188
|
+
for (const entry of entries) {
|
|
189
|
+
const result = await this.runV2Extractor(entry, request);
|
|
190
|
+
if (result === null)
|
|
191
|
+
continue;
|
|
192
|
+
// A claimed file's incomplete/failed result is authoritative uncertainty.
|
|
193
|
+
// Never turn a required provider failure into empty symbols or success.
|
|
194
|
+
canonical = result;
|
|
195
|
+
break;
|
|
196
|
+
}
|
|
197
|
+
canonical ??= request.fallback("unsupported", "unsupported_language", "No configured source analyzer claims this file; file-level review remains required.");
|
|
198
|
+
const shadowComparisons = [];
|
|
199
|
+
for (const entry of resolution.shadow) {
|
|
200
|
+
const result = await this.runV2Extractor(entry, request);
|
|
201
|
+
if (!result)
|
|
202
|
+
continue;
|
|
203
|
+
shadowComparisons.push({
|
|
204
|
+
pluginId: entry.pluginId,
|
|
205
|
+
stamp: entry.stamp,
|
|
206
|
+
symbolCount: result.symbols.length,
|
|
207
|
+
language: result.language,
|
|
208
|
+
ok: result.status === "ok",
|
|
209
|
+
...(result.status !== "ok"
|
|
210
|
+
? { error: result.diagnostics.map((d) => d.message).join("; ") }
|
|
211
|
+
: {}),
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
return { ...canonical, shadowComparisons };
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Run one provider under the host-owned deadline. Returns null when the
|
|
218
|
+
* provider does not claim the input; a claimed failure is a failed result.
|
|
219
|
+
*/
|
|
220
|
+
async runV2Extractor(entry, request) {
|
|
221
|
+
const { classification, input } = request;
|
|
222
|
+
try {
|
|
223
|
+
const supportsInput = classification.kind === "language"
|
|
224
|
+
? { path: input.path, language: classification.language }
|
|
225
|
+
: { path: input.path };
|
|
226
|
+
if (!entry.capability.supports(supportsInput))
|
|
227
|
+
return null;
|
|
228
|
+
const timeout = hostDeadlineMs(this.options.analysisTimeoutMs);
|
|
229
|
+
let timer;
|
|
230
|
+
let raw;
|
|
231
|
+
try {
|
|
232
|
+
raw = await Promise.race([
|
|
233
|
+
entry.capability.analyze({
|
|
234
|
+
...input,
|
|
235
|
+
timeoutMs: providerBudgetMs(timeout),
|
|
236
|
+
}),
|
|
237
|
+
new Promise((_, reject) => {
|
|
238
|
+
timer = setTimeout(() => reject(new Error("Source analysis deadline exceeded")), timeout);
|
|
239
|
+
}),
|
|
240
|
+
]);
|
|
241
|
+
}
|
|
242
|
+
finally {
|
|
243
|
+
if (timer !== undefined)
|
|
244
|
+
clearTimeout(timer);
|
|
245
|
+
}
|
|
246
|
+
const validated = validateSourceAnalysisResultV2(raw, input);
|
|
247
|
+
return {
|
|
248
|
+
...validated,
|
|
249
|
+
providerId: entry.capability.id,
|
|
250
|
+
stamp: entry.stamp,
|
|
251
|
+
inputFingerprint: request.inputFingerprint,
|
|
252
|
+
providerFingerprint: this.options.providerFingerprints?.[entry.pluginId] ??
|
|
253
|
+
createHash("sha256")
|
|
254
|
+
.update(`${entry.pluginId}\0${entry.pluginVersion}\0${entry.stamp.capability}`)
|
|
255
|
+
.digest("hex"),
|
|
256
|
+
shadowComparisons: [],
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
catch (error) {
|
|
260
|
+
return {
|
|
261
|
+
...request.fallback("failed", "provider_failed", `Extractor '${entry.capability.id}' failed: ${String(error)}`),
|
|
262
|
+
providerId: entry.capability.id,
|
|
263
|
+
stamp: entry.stamp,
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
}
|
|
110
267
|
async analyzeText(filePath, content) {
|
|
111
268
|
const resolution = await this.resolveExtractors();
|
|
112
269
|
const diagnostics = [];
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type GateAnalysis } from "../traceability/analysis-gate.js";
|
|
2
|
+
import type { StagedPath } from "../traceability/git-staged.js";
|
|
3
|
+
import type { HostSourceAnalysisResultV2, SourceAnalysisService } from "./source-analysis-service.js";
|
|
4
|
+
export interface SourceChangeAnalysis {
|
|
5
|
+
path: string;
|
|
6
|
+
before: HostSourceAnalysisResultV2 | null;
|
|
7
|
+
after: HostSourceAnalysisResultV2 | null;
|
|
8
|
+
}
|
|
9
|
+
/** Analyze both versions without changing the complete inventory or assigning proof. */
|
|
10
|
+
export declare function analyzeSourceChanges(inventory: readonly StagedPath[], service: SourceAnalysisService): Promise<Map<string, SourceChangeAnalysis>>;
|
|
11
|
+
/** Adapt a host result to the shared analysis gate. */
|
|
12
|
+
export declare function gateAnalysis(result: HostSourceAnalysisResultV2 | null): GateAnalysis<HostSourceAnalysisResultV2["uncoveredRanges"][number]> | null;
|
|
13
|
+
/** Enforce the shared analysis gate when no impact policy accepts reviews. */
|
|
14
|
+
export declare function assertSourceAnalysisGate(inventory: readonly StagedPath[], analyses: ReadonlyMap<string, SourceChangeAnalysis>): void;
|
|
15
|
+
//# sourceMappingURL=source-change-analysis.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"source-change-analysis.d.ts","sourceRoot":"","sources":["../../src/plugins/source-change-analysis.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,YAAY,EAElB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,KAAK,EACV,0BAA0B,EAC1B,qBAAqB,EACtB,MAAM,8BAA8B,CAAC;AAGtC,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,0BAA0B,GAAG,IAAI,CAAC;IAC1C,KAAK,EAAE,0BAA0B,GAAG,IAAI,CAAC;CAC1C;AAKD,wFAAwF;AAExF,wBAAsB,oBAAoB,CACxC,SAAS,EAAE,SAAS,UAAU,EAAE,EAChC,OAAO,EAAE,qBAAqB,GAC7B,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC,CAgC5C;AAED,uDAAuD;AAEvD,wBAAgB,YAAY,CAC1B,MAAM,EAAE,0BAA0B,GAAG,IAAI,GACxC,YAAY,CAAC,0BAA0B,CAAC,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,IAAI,CAQ5E;AAED,8EAA8E;AAE9E,wBAAgB,wBAAwB,CACtC,SAAS,EAAE,SAAS,UAAU,EAAE,EAChC,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,oBAAoB,CAAC,GAClD,IAAI,CAkBN"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { analysisObligation, } from "../traceability/analysis-gate.js";
|
|
2
|
+
/** Files analyzed at once; pooled providers bound their own worker count. */
|
|
3
|
+
const SOURCE_ANALYSIS_CONCURRENCY = 4;
|
|
4
|
+
/** Analyze both versions without changing the complete inventory or assigning proof. */
|
|
5
|
+
// implements REQ-014
|
|
6
|
+
export async function analyzeSourceChanges(inventory, service) {
|
|
7
|
+
const files = inventory.filter((file) => file.analysisDepth !== "metadata" && !file.skipReason);
|
|
8
|
+
const results = new Array(files.length);
|
|
9
|
+
let next = 0;
|
|
10
|
+
const worker = async () => {
|
|
11
|
+
while (next < files.length) {
|
|
12
|
+
const index = next++;
|
|
13
|
+
const file = files[index];
|
|
14
|
+
const [before, after] = await Promise.all([
|
|
15
|
+
file.previousContent === undefined
|
|
16
|
+
? null
|
|
17
|
+
: service.analyzeTextV2(file.oldPath ?? file.copyFromPath ?? file.path, file.previousContent),
|
|
18
|
+
file.content === undefined
|
|
19
|
+
? null
|
|
20
|
+
: service.analyzeTextV2(file.path, file.content),
|
|
21
|
+
]);
|
|
22
|
+
results[index] = { path: file.path, before, after };
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
await Promise.all(Array.from({ length: Math.min(SOURCE_ANALYSIS_CONCURRENCY, files.length) }, worker));
|
|
26
|
+
// Map order follows the inventory, independent of completion order.
|
|
27
|
+
return new Map(results.map((change) => [change.path, change]));
|
|
28
|
+
}
|
|
29
|
+
/** Adapt a host result to the shared analysis gate. */
|
|
30
|
+
// implements REQ-source-analysis-v2
|
|
31
|
+
export function gateAnalysis(result) {
|
|
32
|
+
return result
|
|
33
|
+
? {
|
|
34
|
+
status: result.status,
|
|
35
|
+
diagnosticCodes: result.diagnostics.map((item) => item.code),
|
|
36
|
+
uncoveredRanges: result.uncoveredRanges,
|
|
37
|
+
}
|
|
38
|
+
: null;
|
|
39
|
+
}
|
|
40
|
+
/** Enforce the shared analysis gate when no impact policy accepts reviews. */
|
|
41
|
+
// implements REQ-source-analysis-v2
|
|
42
|
+
export function assertSourceAnalysisGate(inventory, analyses) {
|
|
43
|
+
for (const file of inventory) {
|
|
44
|
+
const analysis = analyses.get(file.path);
|
|
45
|
+
const after = analysis?.after ?? null;
|
|
46
|
+
const obligation = analysisObligation("after", gateAnalysis(after), file.hunkRanges);
|
|
47
|
+
if (obligation.kind !== "blocked" && obligation.kind !== "partial_review")
|
|
48
|
+
continue;
|
|
49
|
+
const detail = after?.diagnostics.map((d) => d.message).join("; ") ?? "";
|
|
50
|
+
throw new Error(obligation.kind === "blocked"
|
|
51
|
+
? `Source analysis ${after?.status} for ${file.path}: ${detail}`
|
|
52
|
+
: `Source analysis partial for ${file.path} where the staged change touches uncovered lines (${obligation.ranges.map((range) => `${range.startLine}-${range.endLine}`).join(", ")}): ${detail}`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export type SourceClassification = Readonly<{
|
|
2
|
+
kind: "language";
|
|
3
|
+
language: string;
|
|
4
|
+
source: "extension" | "shebang" | "explicit";
|
|
5
|
+
}> | Readonly<{
|
|
6
|
+
kind: "file-level";
|
|
7
|
+
language: string;
|
|
8
|
+
source: "extension" | "shebang" | "explicit";
|
|
9
|
+
reason: string;
|
|
10
|
+
}> | Readonly<{
|
|
11
|
+
kind: "ambiguous";
|
|
12
|
+
language: string;
|
|
13
|
+
candidates: readonly string[];
|
|
14
|
+
reason: string;
|
|
15
|
+
}> | Readonly<{
|
|
16
|
+
kind: "conflict";
|
|
17
|
+
language: "unknown";
|
|
18
|
+
extensionLanguage?: string;
|
|
19
|
+
shebangLanguage?: string;
|
|
20
|
+
explicitLanguage?: string;
|
|
21
|
+
reason: string;
|
|
22
|
+
}> | Readonly<{
|
|
23
|
+
kind: "unknown";
|
|
24
|
+
language: "unknown";
|
|
25
|
+
reason: string;
|
|
26
|
+
}>;
|
|
27
|
+
/**
|
|
28
|
+
* Extension-only language label for a path, or "unknown". This is the single
|
|
29
|
+
* extension table; callers that need content-aware classification (shebangs,
|
|
30
|
+
* explicit hints, ambiguity) must use classifySource instead.
|
|
31
|
+
*/
|
|
32
|
+
export declare function extensionLanguage(filePath: string): string;
|
|
33
|
+
/** True for TypeScript/JavaScript paths handled by the ts-morph analyzer. */
|
|
34
|
+
export declare function isTsJsSourcePath(filePath: string): boolean;
|
|
35
|
+
/** True for paths whose language has qualified declaration analysis. */
|
|
36
|
+
export declare function isQualifiedSourcePath(filePath: string): boolean;
|
|
37
|
+
/** Every classified extension, for parity checks against provider catalogs. */
|
|
38
|
+
export declare function classifiedExtensions(): readonly string[];
|
|
39
|
+
/** Classifies a path and bounded snapshot prefix without executing the source or its interpreter. */
|
|
40
|
+
export declare function classifySource(filePath: string, content: string, explicitLanguageHint?: string): SourceClassification;
|
|
41
|
+
//# sourceMappingURL=source-classification.d.ts.map
|
|
@@ -0,0 +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;CAC9C,CAAC,GACF,QAAQ,CAAC;IACP,IAAI,EAAE,YAAY,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,WAAW,GAAG,SAAS,GAAG,UAAU,CAAC;IAC7C,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;AAsGP;;;;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;AAuQD,qGAAqG;AACrG,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,oBAAoB,CAAC,EAAE,MAAM,GAC5B,oBAAoB,CA2JtB"}
|