@saptools/service-flow 0.1.45 → 0.1.46
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/CHANGELOG.md +7 -0
- package/dist/{chunk-BXSCE5CR.js → chunk-EGY2A4AT.js} +175 -114
- package/dist/chunk-EGY2A4AT.js.map +1 -0
- package/dist/cli.js +30 -4
- package/dist/cli.js.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/src/cli/doctor.ts +18 -1
- package/src/linker/cross-repo-linker.ts +4 -2
- package/src/output/table-output.ts +16 -1
- package/src/trace/implementation-hints.ts +73 -1
- package/src/trace/trace-engine.ts +4 -4
- package/dist/chunk-BXSCE5CR.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.1.46
|
|
4
|
+
|
|
5
|
+
- Improved ambiguous implementation diagnostics with ready-to-copy scoped hint suggestions for each blocked helper hop.
|
|
6
|
+
- Persisted deterministic service-client ownership across helper boundaries, object and tuple destructuring, returned clients, and transaction aliases while preserving dynamic evidence for ambiguous flows.
|
|
7
|
+
- Tightened OData operation-invocation normalization and dynamic wrapper-path evidence without promoting entity addressing paths to operation calls.
|
|
8
|
+
- Kept strict doctor output concise by default with actionable categories and detail-mode evidence expansion.
|
|
9
|
+
|
|
3
10
|
## 0.1.45
|
|
4
11
|
|
|
5
12
|
- Added repeatable scoped implementation hints with explicit selection and mismatch evidence while preserving conservative automatic and legacy repository selection.
|
|
@@ -2316,6 +2316,171 @@ function substituteVariables(template, vars) {
|
|
|
2316
2316
|
};
|
|
2317
2317
|
}
|
|
2318
2318
|
|
|
2319
|
+
// src/trace/implementation-hints.ts
|
|
2320
|
+
function parseImplementationHint(value) {
|
|
2321
|
+
const hint = {};
|
|
2322
|
+
for (const part of value.split(",")) {
|
|
2323
|
+
const separator = part.indexOf("=");
|
|
2324
|
+
if (separator <= 0 || separator === part.length - 1) throw new Error(`Invalid implementation hint field: ${part}`);
|
|
2325
|
+
assignHintField(hint, part.slice(0, separator).trim(), part.slice(separator + 1).trim());
|
|
2326
|
+
}
|
|
2327
|
+
if (!hint.implementationRepo) throw new Error("Scoped implementation hint requires an implementation repo selection");
|
|
2328
|
+
return { ...hint, implementationRepo: hint.implementationRepo };
|
|
2329
|
+
}
|
|
2330
|
+
function selectImplementation(rawEvidence, hints, legacyRepo) {
|
|
2331
|
+
const evidence = asEvidence(rawEvidence);
|
|
2332
|
+
const scoped = hints ?? [];
|
|
2333
|
+
const matchingHints = scoped.filter((hint2) => hintMatchesEdge(hint2, evidence));
|
|
2334
|
+
if (matchingHints.length === 0) {
|
|
2335
|
+
if (legacyRepo) return selectCandidate(evidence, legacyHint(legacyRepo), "implementation_repo_hint");
|
|
2336
|
+
const reason = scoped.length > 0 ? "no_scoped_hint_matched_edge" : "no_implementation_hint_supplied";
|
|
2337
|
+
return { blocksAutomatic: false, evidence: { status: "not_matched", reason, strategy: "scoped_implementation_hint" } };
|
|
2338
|
+
}
|
|
2339
|
+
if (matchingHints.length > 1) {
|
|
2340
|
+
return {
|
|
2341
|
+
blocksAutomatic: true,
|
|
2342
|
+
evidence: {
|
|
2343
|
+
status: "tied",
|
|
2344
|
+
reason: "multiple_scoped_hints_matched_edge",
|
|
2345
|
+
strategy: "scoped_implementation_hint",
|
|
2346
|
+
matchedHints: matchingHints,
|
|
2347
|
+
candidateCount: matchingHints.length
|
|
2348
|
+
}
|
|
2349
|
+
};
|
|
2350
|
+
}
|
|
2351
|
+
const hint = matchingHints[0];
|
|
2352
|
+
return hint ? selectCandidate(evidence, hint, "scoped_implementation_hint") : { blocksAutomatic: false, evidence: { status: "not_matched" } };
|
|
2353
|
+
}
|
|
2354
|
+
function implementationHintDiagnostic(selection, suggestions) {
|
|
2355
|
+
if (!selection.blocksAutomatic || selection.methodId) return void 0;
|
|
2356
|
+
return {
|
|
2357
|
+
severity: "warning",
|
|
2358
|
+
code: "implementation_hint_mismatch",
|
|
2359
|
+
message: "Implementation hint did not select exactly one viable candidate",
|
|
2360
|
+
hintStatus: selection.evidence.status,
|
|
2361
|
+
candidateCount: selection.evidence.candidateCount,
|
|
2362
|
+
implementationHintSuggestions: Array.isArray(suggestions) && suggestions.length > 0 ? suggestions : void 0,
|
|
2363
|
+
implementationSelection: selection.evidence
|
|
2364
|
+
};
|
|
2365
|
+
}
|
|
2366
|
+
function implementationHintSuggestions(rawEvidence) {
|
|
2367
|
+
const evidence = asEvidence(rawEvidence);
|
|
2368
|
+
const accepted = (evidence.candidates ?? []).filter((candidate) => candidate.accepted);
|
|
2369
|
+
if (accepted.length < 2) return [];
|
|
2370
|
+
const repos = selectableRepositories(accepted);
|
|
2371
|
+
return accepted.flatMap((candidate) => {
|
|
2372
|
+
const repo = candidate.handlerPackage?.name;
|
|
2373
|
+
if (!repo || !repos.includes(repo)) return [];
|
|
2374
|
+
const hint = suggestionHint(evidence, candidate, repo);
|
|
2375
|
+
return [{
|
|
2376
|
+
servicePath: hint.servicePath,
|
|
2377
|
+
operationPath: hint.operationPath,
|
|
2378
|
+
ambiguityReason: evidence.ambiguityReasons?.[0],
|
|
2379
|
+
candidateFamily: hint.candidateFamily,
|
|
2380
|
+
selectableImplementationRepositories: repos,
|
|
2381
|
+
implementationRepo: repo,
|
|
2382
|
+
hint,
|
|
2383
|
+
cli: `--implementation-hint ${hintString(hint)}`
|
|
2384
|
+
}];
|
|
2385
|
+
});
|
|
2386
|
+
}
|
|
2387
|
+
function selectableRepositories(candidates) {
|
|
2388
|
+
const repos = new Set(candidates.flatMap((candidate) => candidate.handlerPackage?.name ? [candidate.handlerPackage.name] : []));
|
|
2389
|
+
return [...repos].filter((repo) => candidates.filter((candidate) => candidateMatchesRepo(candidate, repo)).length === 1).sort();
|
|
2390
|
+
}
|
|
2391
|
+
function assignHintField(hint, key, value) {
|
|
2392
|
+
if (key === "service" || key === "servicePath") hint.servicePath = value;
|
|
2393
|
+
else if (key === "operation" || key === "operationPath") hint.operationPath = value;
|
|
2394
|
+
else if (key === "package" || key === "packageName") hint.packageName = value;
|
|
2395
|
+
else if (key === "repository" || key === "repositoryName") hint.repositoryName = value;
|
|
2396
|
+
else if (key === "family" || key === "candidateFamily") hint.candidateFamily = value;
|
|
2397
|
+
else if (key === "repo" || key === "implementationRepo" || key === "select") hint.implementationRepo = value;
|
|
2398
|
+
else throw new Error(`Unknown implementation hint field: ${key}`);
|
|
2399
|
+
}
|
|
2400
|
+
function selectCandidate(evidence, hint, strategy) {
|
|
2401
|
+
const matches2 = (evidence.candidates ?? []).filter((candidate) => candidate.accepted && candidateMatchesRepo(candidate, hint.implementationRepo));
|
|
2402
|
+
const selected = matches2.length === 1 ? matches2[0] : void 0;
|
|
2403
|
+
if (!selected || selected.methodId === void 0) {
|
|
2404
|
+
return {
|
|
2405
|
+
blocksAutomatic: true,
|
|
2406
|
+
evidence: {
|
|
2407
|
+
status: matches2.length > 1 ? "tied" : "not_matched",
|
|
2408
|
+
reason: matches2.length > 1 ? "hint_matched_multiple_candidates" : "hint_matched_zero_candidates",
|
|
2409
|
+
strategy,
|
|
2410
|
+
matchedHint: hint,
|
|
2411
|
+
selectedRepo: hint.implementationRepo,
|
|
2412
|
+
candidateCount: matches2.length
|
|
2413
|
+
}
|
|
2414
|
+
};
|
|
2415
|
+
}
|
|
2416
|
+
return {
|
|
2417
|
+
methodId: String(selected.methodId),
|
|
2418
|
+
blocksAutomatic: false,
|
|
2419
|
+
evidence: {
|
|
2420
|
+
status: "selected",
|
|
2421
|
+
guided: true,
|
|
2422
|
+
strategy,
|
|
2423
|
+
matchedHint: hint,
|
|
2424
|
+
selectedRepo: hint.implementationRepo,
|
|
2425
|
+
selectedMethodId: selected.methodId,
|
|
2426
|
+
ambiguityReason: evidence.ambiguityReasons?.[0]
|
|
2427
|
+
}
|
|
2428
|
+
};
|
|
2429
|
+
}
|
|
2430
|
+
function suggestionHint(evidence, candidate, repo) {
|
|
2431
|
+
const servicePath = evidence.servicePath ?? candidate.servicePath;
|
|
2432
|
+
const operationPath = evidence.operationPath ?? candidate.operationPath;
|
|
2433
|
+
const family = usefulCandidateFamily(evidence, candidate);
|
|
2434
|
+
return {
|
|
2435
|
+
...servicePath ? { servicePath } : {},
|
|
2436
|
+
...operationPath ? { operationPath } : {},
|
|
2437
|
+
...evidence.modelPackage?.packageName ? { packageName: evidence.modelPackage.packageName } : {},
|
|
2438
|
+
...evidence.modelPackage?.name ? { repositoryName: evidence.modelPackage.name } : {},
|
|
2439
|
+
...family ? { candidateFamily: family } : {},
|
|
2440
|
+
implementationRepo: repo
|
|
2441
|
+
};
|
|
2442
|
+
}
|
|
2443
|
+
function usefulCandidateFamily(evidence, candidate) {
|
|
2444
|
+
const family = candidate.handlerPackage?.packageName;
|
|
2445
|
+
if (!family) return void 0;
|
|
2446
|
+
if ((evidence.candidateFamilies ?? []).some((item) => item.packageName === family)) return family;
|
|
2447
|
+
const acceptedFamilies = new Set(
|
|
2448
|
+
(evidence.candidates ?? []).filter((item) => item.accepted).flatMap((item) => item.handlerPackage?.packageName ? [item.handlerPackage.packageName] : [])
|
|
2449
|
+
);
|
|
2450
|
+
return acceptedFamilies.size > 1 ? family : void 0;
|
|
2451
|
+
}
|
|
2452
|
+
function hintString(hint) {
|
|
2453
|
+
const fields = [
|
|
2454
|
+
["service", hint.servicePath],
|
|
2455
|
+
["operation", hint.operationPath],
|
|
2456
|
+
["package", hint.packageName],
|
|
2457
|
+
["repository", hint.repositoryName],
|
|
2458
|
+
["family", hint.candidateFamily],
|
|
2459
|
+
["repo", hint.implementationRepo]
|
|
2460
|
+
];
|
|
2461
|
+
return fields.flatMap(([key, value]) => value ? [`${key}=${value}`] : []).join(",");
|
|
2462
|
+
}
|
|
2463
|
+
function hintMatchesEdge(hint, evidence) {
|
|
2464
|
+
const model = evidence.modelPackage ?? evidence.candidates?.[0]?.modelPackage;
|
|
2465
|
+
const familyNames = /* @__PURE__ */ new Set([
|
|
2466
|
+
...(evidence.candidateFamilies ?? []).flatMap((family) => family.packageName ? [family.packageName] : []),
|
|
2467
|
+
...(evidence.candidates ?? []).flatMap((candidate) => candidate.handlerPackage?.packageName ? [candidate.handlerPackage.packageName] : [])
|
|
2468
|
+
]);
|
|
2469
|
+
return matches(hint.servicePath, evidence.servicePath ?? evidence.candidates?.[0]?.servicePath) && matches(hint.operationPath, evidence.operationPath ?? evidence.candidates?.[0]?.operationPath) && matches(hint.packageName, model?.packageName) && matches(hint.repositoryName, model?.name) && (!hint.candidateFamily || familyNames.has(hint.candidateFamily));
|
|
2470
|
+
}
|
|
2471
|
+
function candidateMatchesRepo(candidate, value) {
|
|
2472
|
+
return candidate.handlerPackage?.name === value || candidate.handlerPackage?.packageName === value || candidate.sourceFile?.startsWith(value) === true;
|
|
2473
|
+
}
|
|
2474
|
+
function matches(expected, actual) {
|
|
2475
|
+
return expected === void 0 || expected === actual;
|
|
2476
|
+
}
|
|
2477
|
+
function legacyHint(implementationRepo) {
|
|
2478
|
+
return { implementationRepo };
|
|
2479
|
+
}
|
|
2480
|
+
function asEvidence(value) {
|
|
2481
|
+
return value;
|
|
2482
|
+
}
|
|
2483
|
+
|
|
2319
2484
|
// src/linker/remote-query-target.ts
|
|
2320
2485
|
function buildRemoteQueryTarget(input) {
|
|
2321
2486
|
const entity = typeof input.queryEntity === "string" && input.queryEntity.trim() ? input.queryEntity.trim() : void 0;
|
|
@@ -2760,13 +2925,14 @@ function linkImplementations(db, workspaceId, generation) {
|
|
|
2760
2925
|
candidateFamilies: duplicateFamilies,
|
|
2761
2926
|
candidates: candidates.map((candidate, index) => candidateEvidence(candidate, index + 1))
|
|
2762
2927
|
};
|
|
2928
|
+
const evidenceWithHints = unique ? evidence : { ...evidence, implementationHintSuggestions: implementationHintSuggestions(evidence) };
|
|
2763
2929
|
if (accepted.length === 0) {
|
|
2764
|
-
db.prepare("INSERT INTO graph_edges(workspace_id,edge_type,status,from_kind,from_id,to_kind,to_id,confidence,evidence_json,is_dynamic,unresolved_reason,generation) VALUES(?,?,?,?,?,?,?,?,?,?,?,?)").run(workspaceId, "OPERATION_IMPLEMENTED_BY_HANDLER", "unresolved", "operation", graphId(operation.operationId), "handler_method_candidates", candidates.map((row) => graphId(row.methodId)).join(","), 0, JSON.stringify(
|
|
2930
|
+
db.prepare("INSERT INTO graph_edges(workspace_id,edge_type,status,from_kind,from_id,to_kind,to_id,confidence,evidence_json,is_dynamic,unresolved_reason,generation) VALUES(?,?,?,?,?,?,?,?,?,?,?,?)").run(workspaceId, "OPERATION_IMPLEMENTED_BY_HANDLER", "unresolved", "operation", graphId(operation.operationId), "handler_method_candidates", candidates.map((row) => graphId(row.methodId)).join(","), 0, JSON.stringify(evidenceWithHints), 0, "No implementation candidate passed policy", generation);
|
|
2765
2931
|
edgeCount += 1;
|
|
2766
2932
|
unresolvedCount += 1;
|
|
2767
2933
|
continue;
|
|
2768
2934
|
}
|
|
2769
|
-
db.prepare("INSERT INTO graph_edges(workspace_id,edge_type,status,from_kind,from_id,to_kind,to_id,confidence,evidence_json,is_dynamic,unresolved_reason,generation) VALUES(?,?,?,?,?,?,?,?,?,?,?,?)").run(workspaceId, "OPERATION_IMPLEMENTED_BY_HANDLER", unique ? "resolved" : "ambiguous", "operation", graphId(operation.operationId), unique ? "handler_method" : "handler_method_candidates", unique ? graphId(unique.methodId) : selected.map((row) => graphId(row.methodId)).join(","), unique ? 0.95 : 0.5, JSON.stringify(
|
|
2935
|
+
db.prepare("INSERT INTO graph_edges(workspace_id,edge_type,status,from_kind,from_id,to_kind,to_id,confidence,evidence_json,is_dynamic,unresolved_reason,generation) VALUES(?,?,?,?,?,?,?,?,?,?,?,?)").run(workspaceId, "OPERATION_IMPLEMENTED_BY_HANDLER", unique ? "resolved" : "ambiguous", "operation", graphId(operation.operationId), unique ? "handler_method" : "handler_method_candidates", unique ? graphId(unique.methodId) : selected.map((row) => graphId(row.methodId)).join(","), unique ? 0.95 : 0.5, JSON.stringify(evidenceWithHints), 0, unique ? null : "Ambiguous registered handler implementation candidates", generation);
|
|
2770
2936
|
edgeCount += 1;
|
|
2771
2937
|
if (unique) resolvedCount += 1;
|
|
2772
2938
|
else ambiguousCount += 1;
|
|
@@ -3005,112 +3171,6 @@ function normalizedOperation(value) {
|
|
|
3005
3171
|
return value.startsWith("/") ? value.slice(1) : value;
|
|
3006
3172
|
}
|
|
3007
3173
|
|
|
3008
|
-
// src/trace/implementation-hints.ts
|
|
3009
|
-
function parseImplementationHint(value) {
|
|
3010
|
-
const hint = {};
|
|
3011
|
-
for (const part of value.split(",")) {
|
|
3012
|
-
const separator = part.indexOf("=");
|
|
3013
|
-
if (separator <= 0 || separator === part.length - 1) throw new Error(`Invalid implementation hint field: ${part}`);
|
|
3014
|
-
assignHintField(hint, part.slice(0, separator).trim(), part.slice(separator + 1).trim());
|
|
3015
|
-
}
|
|
3016
|
-
if (!hint.implementationRepo) throw new Error("Scoped implementation hint requires an implementation repo selection");
|
|
3017
|
-
return { ...hint, implementationRepo: hint.implementationRepo };
|
|
3018
|
-
}
|
|
3019
|
-
function selectImplementation(rawEvidence, hints, legacyRepo) {
|
|
3020
|
-
const evidence = asEvidence(rawEvidence);
|
|
3021
|
-
const scoped = hints ?? [];
|
|
3022
|
-
const matchingHints = scoped.filter((hint2) => hintMatchesEdge(hint2, evidence));
|
|
3023
|
-
if (matchingHints.length === 0) {
|
|
3024
|
-
if (legacyRepo) return selectCandidate(evidence, legacyHint(legacyRepo), "implementation_repo_hint");
|
|
3025
|
-
const reason = scoped.length > 0 ? "no_scoped_hint_matched_edge" : "no_implementation_hint_supplied";
|
|
3026
|
-
return { blocksAutomatic: false, evidence: { status: "not_matched", reason, strategy: "scoped_implementation_hint" } };
|
|
3027
|
-
}
|
|
3028
|
-
if (matchingHints.length > 1) {
|
|
3029
|
-
return {
|
|
3030
|
-
blocksAutomatic: true,
|
|
3031
|
-
evidence: {
|
|
3032
|
-
status: "tied",
|
|
3033
|
-
reason: "multiple_scoped_hints_matched_edge",
|
|
3034
|
-
strategy: "scoped_implementation_hint",
|
|
3035
|
-
matchedHints: matchingHints,
|
|
3036
|
-
candidateCount: matchingHints.length
|
|
3037
|
-
}
|
|
3038
|
-
};
|
|
3039
|
-
}
|
|
3040
|
-
const hint = matchingHints[0];
|
|
3041
|
-
return hint ? selectCandidate(evidence, hint, "scoped_implementation_hint") : { blocksAutomatic: false, evidence: { status: "not_matched" } };
|
|
3042
|
-
}
|
|
3043
|
-
function implementationHintDiagnostic(selection) {
|
|
3044
|
-
if (!selection.blocksAutomatic || selection.methodId) return void 0;
|
|
3045
|
-
return {
|
|
3046
|
-
severity: "warning",
|
|
3047
|
-
code: "implementation_hint_mismatch",
|
|
3048
|
-
message: "Implementation hint did not select exactly one viable candidate",
|
|
3049
|
-
hintStatus: selection.evidence.status,
|
|
3050
|
-
candidateCount: selection.evidence.candidateCount,
|
|
3051
|
-
implementationSelection: selection.evidence
|
|
3052
|
-
};
|
|
3053
|
-
}
|
|
3054
|
-
function assignHintField(hint, key, value) {
|
|
3055
|
-
if (key === "service" || key === "servicePath") hint.servicePath = value;
|
|
3056
|
-
else if (key === "operation" || key === "operationPath") hint.operationPath = value;
|
|
3057
|
-
else if (key === "package" || key === "packageName") hint.packageName = value;
|
|
3058
|
-
else if (key === "repository" || key === "repositoryName") hint.repositoryName = value;
|
|
3059
|
-
else if (key === "family" || key === "candidateFamily") hint.candidateFamily = value;
|
|
3060
|
-
else if (key === "repo" || key === "implementationRepo" || key === "select") hint.implementationRepo = value;
|
|
3061
|
-
else throw new Error(`Unknown implementation hint field: ${key}`);
|
|
3062
|
-
}
|
|
3063
|
-
function selectCandidate(evidence, hint, strategy) {
|
|
3064
|
-
const matches2 = (evidence.candidates ?? []).filter((candidate) => candidate.accepted && candidateMatchesRepo(candidate, hint.implementationRepo));
|
|
3065
|
-
const selected = matches2.length === 1 ? matches2[0] : void 0;
|
|
3066
|
-
if (!selected || selected.methodId === void 0) {
|
|
3067
|
-
return {
|
|
3068
|
-
blocksAutomatic: true,
|
|
3069
|
-
evidence: {
|
|
3070
|
-
status: matches2.length > 1 ? "tied" : "not_matched",
|
|
3071
|
-
reason: matches2.length > 1 ? "hint_matched_multiple_candidates" : "hint_matched_zero_candidates",
|
|
3072
|
-
strategy,
|
|
3073
|
-
matchedHint: hint,
|
|
3074
|
-
selectedRepo: hint.implementationRepo,
|
|
3075
|
-
candidateCount: matches2.length
|
|
3076
|
-
}
|
|
3077
|
-
};
|
|
3078
|
-
}
|
|
3079
|
-
return {
|
|
3080
|
-
methodId: String(selected.methodId),
|
|
3081
|
-
blocksAutomatic: false,
|
|
3082
|
-
evidence: {
|
|
3083
|
-
status: "selected",
|
|
3084
|
-
guided: true,
|
|
3085
|
-
strategy,
|
|
3086
|
-
matchedHint: hint,
|
|
3087
|
-
selectedRepo: hint.implementationRepo,
|
|
3088
|
-
selectedMethodId: selected.methodId,
|
|
3089
|
-
ambiguityReason: evidence.ambiguityReasons?.[0]
|
|
3090
|
-
}
|
|
3091
|
-
};
|
|
3092
|
-
}
|
|
3093
|
-
function hintMatchesEdge(hint, evidence) {
|
|
3094
|
-
const model = evidence.modelPackage ?? evidence.candidates?.[0]?.modelPackage;
|
|
3095
|
-
const familyNames = /* @__PURE__ */ new Set([
|
|
3096
|
-
...(evidence.candidateFamilies ?? []).flatMap((family) => family.packageName ? [family.packageName] : []),
|
|
3097
|
-
...(evidence.candidates ?? []).flatMap((candidate) => candidate.handlerPackage?.packageName ? [candidate.handlerPackage.packageName] : [])
|
|
3098
|
-
]);
|
|
3099
|
-
return matches(hint.servicePath, evidence.servicePath ?? evidence.candidates?.[0]?.servicePath) && matches(hint.operationPath, evidence.operationPath ?? evidence.candidates?.[0]?.operationPath) && matches(hint.packageName, model?.packageName) && matches(hint.repositoryName, model?.name) && (!hint.candidateFamily || familyNames.has(hint.candidateFamily));
|
|
3100
|
-
}
|
|
3101
|
-
function candidateMatchesRepo(candidate, value) {
|
|
3102
|
-
return candidate.handlerPackage?.name === value || candidate.handlerPackage?.packageName === value || candidate.sourceFile?.startsWith(value) === true;
|
|
3103
|
-
}
|
|
3104
|
-
function matches(expected, actual) {
|
|
3105
|
-
return expected === void 0 || expected === actual;
|
|
3106
|
-
}
|
|
3107
|
-
function legacyHint(implementationRepo) {
|
|
3108
|
-
return { implementationRepo };
|
|
3109
|
-
}
|
|
3110
|
-
function asEvidence(value) {
|
|
3111
|
-
return value;
|
|
3112
|
-
}
|
|
3113
|
-
|
|
3114
3174
|
// src/trace/evidence.ts
|
|
3115
3175
|
function baseTraceEvidence(row, call, persistedEvidence, contextualEvidence) {
|
|
3116
3176
|
const evidence = { ...persistedEvidence, ...contextualEvidence ?? {} };
|
|
@@ -3292,8 +3352,8 @@ function operationStartScope(db, repoId, start, hintOptions) {
|
|
|
3292
3352
|
}
|
|
3293
3353
|
if (impl.edge) {
|
|
3294
3354
|
const evidence = parseEvidence(impl.edge.evidence_json);
|
|
3295
|
-
const hintDiagnostic = implementationHintDiagnostic(hinted);
|
|
3296
|
-
const diagnostics = [{ severity: "warning", code: impl.edge.status === "ambiguous" ? "trace_start_ambiguous" : "trace_start_implementation_unresolved", message: `Indexed operation matched but implementation edge is ${String(impl.edge.status ?? "unresolved")}`, resolutionStage: "implementation", resolutionStatus: impl.edge.status === "ambiguous" ? "ambiguous_implementation" : "rejected_implementation", implementationEdgeId: impl.edge.id, implementationStatus: impl.edge.status, implementationAmbiguityReasons: evidence.ambiguityReasons, candidates: evidence.candidates }];
|
|
3355
|
+
const hintDiagnostic = implementationHintDiagnostic(hinted, evidence.implementationHintSuggestions);
|
|
3356
|
+
const diagnostics = [{ severity: "warning", code: impl.edge.status === "ambiguous" ? "trace_start_ambiguous" : "trace_start_implementation_unresolved", message: `Indexed operation matched but implementation edge is ${String(impl.edge.status ?? "unresolved")}`, resolutionStage: "implementation", resolutionStatus: impl.edge.status === "ambiguous" ? "ambiguous_implementation" : "rejected_implementation", implementationEdgeId: impl.edge.id, implementationStatus: impl.edge.status, implementationAmbiguityReasons: evidence.ambiguityReasons, implementationHintSuggestions: evidence.implementationHintSuggestions, candidates: evidence.candidates }];
|
|
3297
3357
|
return { operationId, diagnostics: hintDiagnostic ? [hintDiagnostic, ...diagnostics] : diagnostics };
|
|
3298
3358
|
}
|
|
3299
3359
|
return { operationId, diagnostics: [{ severity: "warning", code: "trace_start_implementation_unresolved", message: "Indexed operation matched but no implementation candidate exists", resolutionStage: "implementation", resolutionStatus: "operation_without_implementation" }] };
|
|
@@ -3691,9 +3751,9 @@ function trace(db, start, options) {
|
|
|
3691
3751
|
const contextMethodId = contextSelection.methodId;
|
|
3692
3752
|
const contextNode = contextMethodId ? handlerMethodNode(db, contextMethodId) : void 0;
|
|
3693
3753
|
if (implementation.edge) {
|
|
3694
|
-
const hintDiagnostic = implementationHintDiagnostic(contextSelection);
|
|
3695
|
-
if (hintDiagnostic) diagnostics.unshift(hintDiagnostic);
|
|
3696
3754
|
const implEvidence = JSON.parse(String(implementation.edge.evidence_json || "{}"));
|
|
3755
|
+
const hintDiagnostic = implementationHintDiagnostic(contextSelection, implEvidence.implementationHintSuggestions);
|
|
3756
|
+
if (hintDiagnostic) diagnostics.unshift(hintDiagnostic);
|
|
3697
3757
|
const handlerNode = implementation.edge.status === "resolved" ? handlerMethodNode(db, implementation.edge.to_id) : contextNode;
|
|
3698
3758
|
const implTo = handlerNode?.label ? String(handlerNode.label) : `${implementation.edge.to_kind}:${implementation.edge.to_id}`;
|
|
3699
3759
|
if (handlerNode) nodes.set(String(handlerNode.id), handlerNode);
|
|
@@ -3761,8 +3821,9 @@ export {
|
|
|
3761
3821
|
applyVariables,
|
|
3762
3822
|
extractPlaceholders,
|
|
3763
3823
|
substituteVariables,
|
|
3764
|
-
linkWorkspace,
|
|
3765
3824
|
parseImplementationHint,
|
|
3825
|
+
implementationHintSuggestions,
|
|
3826
|
+
linkWorkspace,
|
|
3766
3827
|
trace
|
|
3767
3828
|
};
|
|
3768
|
-
//# sourceMappingURL=chunk-
|
|
3829
|
+
//# sourceMappingURL=chunk-EGY2A4AT.js.map
|