@veewo/gitnexus 1.4.10-rc → 1.4.11-rc
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/benchmark/u2-e2e/live-evidence-validator.d.ts +19 -0
- package/dist/benchmark/u2-e2e/live-evidence-validator.js +87 -0
- package/dist/benchmark/u2-e2e/live-evidence-validator.test.d.ts +1 -0
- package/dist/benchmark/u2-e2e/live-evidence-validator.test.js +33 -0
- package/dist/benchmark/u2-e2e/neonspark-full-e2e.js +23 -4
- package/dist/benchmark/u2-e2e/reload-v1-acceptance-runner.d.ts +38 -0
- package/dist/benchmark/u2-e2e/reload-v1-acceptance-runner.js +206 -0
- package/dist/benchmark/u2-e2e/reload-v1-acceptance-runner.test.d.ts +1 -0
- package/dist/benchmark/u2-e2e/reload-v1-acceptance-runner.test.js +72 -0
- package/dist/benchmark/u2-e2e/report.d.ts +1 -0
- package/dist/benchmark/u2-e2e/report.js +2 -0
- package/dist/benchmark/u2-e2e/retrieval-runner.d.ts +34 -0
- package/dist/benchmark/u2-e2e/retrieval-runner.js +95 -5
- package/dist/benchmark/u2-e2e/retrieval-runner.test.js +161 -2
- package/dist/cli/ai-context.js +31 -1
- package/dist/cli/ai-context.test.js +10 -0
- package/dist/cli/analyze-summary.d.ts +1 -0
- package/dist/cli/analyze-summary.js +21 -0
- package/dist/cli/analyze-summary.test.js +7 -1
- package/dist/cli/analyze.js +3 -10
- package/dist/cli/eval-server.js +1 -1
- package/dist/cli/index.js +2 -0
- package/dist/cli/setup.js +9 -0
- package/dist/cli/setup.test.js +2 -0
- package/dist/cli/tool.d.ts +2 -0
- package/dist/cli/tool.js +2 -0
- package/dist/core/ingestion/pipeline.js +24 -3
- package/dist/core/ingestion/process-processor.d.ts +6 -0
- package/dist/core/ingestion/process-processor.js +188 -7
- package/dist/core/ingestion/unity-lifecycle-config.d.ts +5 -0
- package/dist/core/ingestion/unity-lifecycle-config.js +25 -0
- package/dist/core/ingestion/unity-lifecycle-synthetic-calls.d.ts +26 -0
- package/dist/core/ingestion/unity-lifecycle-synthetic-calls.js +384 -0
- package/dist/core/ingestion/unity-lifecycle-synthetic-calls.test.d.ts +1 -0
- package/dist/core/ingestion/unity-lifecycle-synthetic-calls.test.js +541 -0
- package/dist/core/ingestion/unity-resource-processor.test.js +81 -0
- package/dist/core/lbug/csv-generator.js +11 -1
- package/dist/core/lbug/fallback-relationship-replay.d.ts +21 -0
- package/dist/core/lbug/fallback-relationship-replay.js +39 -0
- package/dist/core/lbug/fallback-relationship-replay.test.d.ts +1 -0
- package/dist/core/lbug/fallback-relationship-replay.test.js +25 -0
- package/dist/core/lbug/lbug-adapter.d.ts +5 -0
- package/dist/core/lbug/lbug-adapter.js +22 -23
- package/dist/core/lbug/schema.d.ts +2 -2
- package/dist/core/lbug/schema.js +9 -0
- package/dist/core/lbug/schema.test.js +1 -0
- package/dist/mcp/local/local-backend.d.ts +1 -1
- package/dist/mcp/local/local-backend.js +339 -50
- package/dist/mcp/local/local-backend.unity-merge.test.js +1 -1
- package/dist/mcp/local/process-confidence.d.ts +19 -0
- package/dist/mcp/local/process-confidence.js +29 -0
- package/dist/mcp/local/process-confidence.test.d.ts +1 -0
- package/dist/mcp/local/process-confidence.test.js +36 -0
- package/dist/mcp/local/process-evidence.d.ts +28 -0
- package/dist/mcp/local/process-evidence.js +65 -0
- package/dist/mcp/local/process-evidence.test.d.ts +1 -0
- package/dist/mcp/local/process-evidence.test.js +56 -0
- package/dist/mcp/local/runtime-chain-evidence.d.ts +7 -0
- package/dist/mcp/local/runtime-chain-evidence.js +13 -0
- package/dist/mcp/local/runtime-chain-evidence.test.d.ts +1 -0
- package/dist/mcp/local/runtime-chain-evidence.test.js +24 -0
- package/dist/mcp/local/runtime-chain-verify.d.ts +37 -0
- package/dist/mcp/local/runtime-chain-verify.js +221 -0
- package/dist/mcp/local/runtime-chain-verify.test.d.ts +1 -0
- package/dist/mcp/local/runtime-chain-verify.test.js +56 -0
- package/dist/mcp/local/unity-process-confidence-config.d.ts +1 -0
- package/dist/mcp/local/unity-process-confidence-config.js +4 -0
- package/dist/mcp/local/unity-runtime-chain-verify-config.d.ts +1 -0
- package/dist/mcp/local/unity-runtime-chain-verify-config.js +10 -0
- package/dist/mcp/local/unity-runtime-hydration.d.ts +50 -0
- package/dist/mcp/local/unity-runtime-hydration.js +323 -0
- package/dist/mcp/local/unity-runtime-hydration.test.d.ts +1 -0
- package/dist/mcp/local/unity-runtime-hydration.test.js +108 -0
- package/dist/mcp/resources.js +12 -2
- package/dist/mcp/tools.js +32 -0
- package/package.json +1 -1
- package/skills/_shared/unity-runtime-process-contract.md +38 -0
- package/skills/gitnexus-cli.md +16 -0
- package/skills/gitnexus-debugging.md +6 -0
- package/skills/gitnexus-exploring.md +6 -0
- package/skills/gitnexus-guide.md +4 -0
- package/skills/gitnexus-impact-analysis.md +6 -0
- package/skills/gitnexus-pr-review.md +5 -0
- package/skills/gitnexus-refactoring.md +4 -0
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
import { calculateEntryPointScore, isTestFile } from './entry-point-scoring.js';
|
|
13
13
|
import { SupportedLanguages } from '../../config/supported-languages.js';
|
|
14
14
|
const isDev = process.env.NODE_ENV === 'development';
|
|
15
|
+
const SYNTHETIC_RUNTIME_ROOT_MARKER = 'unity-runtime-root';
|
|
16
|
+
const SYNTHETIC_RUNTIME_ROOT_TRACE_LIMIT = 8;
|
|
15
17
|
const DEFAULT_CONFIG = {
|
|
16
18
|
maxTraceDepth: 10,
|
|
17
19
|
maxBranching: 4,
|
|
@@ -33,6 +35,7 @@ export const processProcesses = async (knowledgeGraph, memberships, onProgress,
|
|
|
33
35
|
const membershipMap = new Map();
|
|
34
36
|
memberships.forEach(m => membershipMap.set(m.nodeId, m.communityId));
|
|
35
37
|
const callsEdges = buildCallsGraph(knowledgeGraph);
|
|
38
|
+
const callsEvidenceMap = buildCallsEvidenceMap(knowledgeGraph);
|
|
36
39
|
const reverseCallsEdges = buildReverseCallsGraph(knowledgeGraph);
|
|
37
40
|
const nodeMap = new Map();
|
|
38
41
|
for (const n of knowledgeGraph.iterNodes())
|
|
@@ -57,11 +60,23 @@ export const processProcesses = async (knowledgeGraph, memberships, onProgress,
|
|
|
57
60
|
const uniqueTraces = deduplicateTraces(allTraces);
|
|
58
61
|
// Step 3b: Deduplicate by entry+terminal pair (keep longest path per pair)
|
|
59
62
|
const endpointDeduped = deduplicateByEndpoints(uniqueTraces);
|
|
60
|
-
|
|
63
|
+
const syntheticRootBounded = capSyntheticRuntimeRootTraces(endpointDeduped);
|
|
64
|
+
onProgress?.(`Deduped ${uniqueTraces.length} → ${syntheticRootBounded.length} unique endpoint pairs`, 70);
|
|
61
65
|
// Step 4: Limit to max processes (prioritize longer traces)
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
|
|
66
|
+
const sortedTraces = syntheticRootBounded.sort((a, b) => {
|
|
67
|
+
const runtimeScore = scoreSyntheticRuntimeTrace(b) - scoreSyntheticRuntimeTrace(a);
|
|
68
|
+
if (runtimeScore !== 0)
|
|
69
|
+
return runtimeScore;
|
|
70
|
+
return b.length - a.length;
|
|
71
|
+
});
|
|
72
|
+
const prioritizedRuntimeTraces = sortedTraces
|
|
73
|
+
.filter(isSyntheticRuntimeRootTrace)
|
|
74
|
+
.slice(0, SYNTHETIC_RUNTIME_ROOT_TRACE_LIMIT);
|
|
75
|
+
const prioritizedRuntimeKeys = new Set(prioritizedRuntimeTraces.map((trace) => trace.join('->')));
|
|
76
|
+
const limitedTraces = [
|
|
77
|
+
...prioritizedRuntimeTraces,
|
|
78
|
+
...sortedTraces.filter((trace) => !prioritizedRuntimeKeys.has(trace.join('->'))),
|
|
79
|
+
].slice(0, cfg.maxProcesses);
|
|
65
80
|
onProgress?.(`Creating ${limitedTraces.length} process nodes...`, 80);
|
|
66
81
|
// Step 5: Create process nodes
|
|
67
82
|
const processes = [];
|
|
@@ -69,6 +84,7 @@ export const processProcesses = async (knowledgeGraph, memberships, onProgress,
|
|
|
69
84
|
limitedTraces.forEach((trace, idx) => {
|
|
70
85
|
const entryPointId = trace[0];
|
|
71
86
|
const terminalId = trace[trace.length - 1];
|
|
87
|
+
const traceEvidence = collectTraceEvidence(trace, callsEvidenceMap);
|
|
72
88
|
// Get communities touched
|
|
73
89
|
const communitiesSet = new Set();
|
|
74
90
|
trace.forEach(nodeId => {
|
|
@@ -79,6 +95,14 @@ export const processProcesses = async (knowledgeGraph, memberships, onProgress,
|
|
|
79
95
|
const communities = Array.from(communitiesSet);
|
|
80
96
|
// Determine process type
|
|
81
97
|
const processType = communities.length > 1 ? 'cross_community' : 'intra_community';
|
|
98
|
+
const processSubtype = isSyntheticRuntimeRootTrace(trace) ? 'unity_lifecycle' : 'static_calls';
|
|
99
|
+
const sourceReasons = Array.from(new Set(traceEvidence
|
|
100
|
+
.map((edge) => edge.reason?.trim())
|
|
101
|
+
.filter((reason) => Boolean(reason) && !/TODO|TBD|placeholder/i.test(reason))));
|
|
102
|
+
const sourceConfidences = Array.from(new Set(traceEvidence
|
|
103
|
+
.map((edge) => edge.confidence)
|
|
104
|
+
.filter((confidence) => Number.isFinite(confidence))));
|
|
105
|
+
const runtimeChainConfidence = sourceReasons.some(isSyntheticLifecycleReason) ? 'medium' : 'high';
|
|
82
106
|
// Generate label
|
|
83
107
|
const entryNode = nodeMap.get(entryPointId);
|
|
84
108
|
const terminalNode = nodeMap.get(terminalId);
|
|
@@ -91,6 +115,10 @@ export const processProcesses = async (knowledgeGraph, memberships, onProgress,
|
|
|
91
115
|
label: heuristicLabel,
|
|
92
116
|
heuristicLabel,
|
|
93
117
|
processType,
|
|
118
|
+
processSubtype,
|
|
119
|
+
runtimeChainConfidence,
|
|
120
|
+
sourceReasons,
|
|
121
|
+
sourceConfidences,
|
|
94
122
|
stepCount: trace.length,
|
|
95
123
|
communities,
|
|
96
124
|
entryPointId,
|
|
@@ -99,10 +127,13 @@ export const processProcesses = async (knowledgeGraph, memberships, onProgress,
|
|
|
99
127
|
});
|
|
100
128
|
// Create step relationships
|
|
101
129
|
trace.forEach((nodeId, stepIdx) => {
|
|
130
|
+
const edgeEvidence = resolveStepEvidence(trace, stepIdx, callsEvidenceMap);
|
|
102
131
|
steps.push({
|
|
103
132
|
nodeId,
|
|
104
133
|
processId,
|
|
105
134
|
step: stepIdx + 1, // 1-indexed
|
|
135
|
+
reason: edgeEvidence?.reason,
|
|
136
|
+
confidence: edgeEvidence?.confidence,
|
|
106
137
|
});
|
|
107
138
|
});
|
|
108
139
|
});
|
|
@@ -153,6 +184,45 @@ const buildReverseCallsGraph = (graph) => {
|
|
|
153
184
|
}
|
|
154
185
|
return adj;
|
|
155
186
|
};
|
|
187
|
+
const buildCallsEvidenceMap = (graph) => {
|
|
188
|
+
const evidenceMap = new Map();
|
|
189
|
+
for (const rel of graph.iterRelationships()) {
|
|
190
|
+
if (rel.type !== 'CALLS' || rel.confidence < MIN_TRACE_CONFIDENCE)
|
|
191
|
+
continue;
|
|
192
|
+
const key = `${rel.sourceId}->${rel.targetId}`;
|
|
193
|
+
const existing = evidenceMap.get(key);
|
|
194
|
+
if (!existing || rel.confidence >= existing.confidence) {
|
|
195
|
+
evidenceMap.set(key, {
|
|
196
|
+
reason: rel.reason,
|
|
197
|
+
confidence: rel.confidence,
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
return evidenceMap;
|
|
202
|
+
};
|
|
203
|
+
const collectTraceEvidence = (trace, callsEvidenceMap) => {
|
|
204
|
+
const evidence = [];
|
|
205
|
+
for (let i = 0; i < trace.length - 1; i++) {
|
|
206
|
+
const edge = callsEvidenceMap.get(`${trace[i]}->${trace[i + 1]}`);
|
|
207
|
+
if (edge)
|
|
208
|
+
evidence.push(edge);
|
|
209
|
+
}
|
|
210
|
+
return evidence;
|
|
211
|
+
};
|
|
212
|
+
const resolveStepEvidence = (trace, stepIdx, callsEvidenceMap) => {
|
|
213
|
+
const current = trace[stepIdx];
|
|
214
|
+
const next = trace[stepIdx + 1];
|
|
215
|
+
if (next) {
|
|
216
|
+
const outgoing = callsEvidenceMap.get(`${current}->${next}`);
|
|
217
|
+
if (outgoing)
|
|
218
|
+
return outgoing;
|
|
219
|
+
}
|
|
220
|
+
const prev = trace[stepIdx - 1];
|
|
221
|
+
if (!prev)
|
|
222
|
+
return undefined;
|
|
223
|
+
return callsEvidenceMap.get(`${prev}->${current}`);
|
|
224
|
+
};
|
|
225
|
+
const isSyntheticLifecycleReason = (reason) => reason.includes('unity-lifecycle-synthetic') || reason.includes('unity-runtime-loader-synthetic');
|
|
156
226
|
/**
|
|
157
227
|
* Find functions/methods that are good entry points for tracing.
|
|
158
228
|
*
|
|
@@ -178,6 +248,14 @@ const findEntryPoints = (graph, reverseCallsEdges, callsEdges) => {
|
|
|
178
248
|
// Must have at least 1 outgoing call to trace forward
|
|
179
249
|
if (callees.length === 0)
|
|
180
250
|
continue;
|
|
251
|
+
if (node.id.includes(SYNTHETIC_RUNTIME_ROOT_MARKER) || String(node.properties.name || '').includes(SYNTHETIC_RUNTIME_ROOT_MARKER)) {
|
|
252
|
+
entryPointCandidates.push({
|
|
253
|
+
id: node.id,
|
|
254
|
+
score: 10_000 + callees.length,
|
|
255
|
+
reasons: ['synthetic-runtime-root'],
|
|
256
|
+
});
|
|
257
|
+
continue;
|
|
258
|
+
}
|
|
181
259
|
// Calculate entry point score using new scoring system
|
|
182
260
|
const { score: baseScore, reasons } = calculateEntryPointScore(node.properties.name, node.properties.language ?? SupportedLanguages.JavaScript, node.properties.isExported ?? false, callers.length, callees.length, filePath // Pass filePath for framework detection
|
|
183
261
|
);
|
|
@@ -217,10 +295,12 @@ const findEntryPoints = (graph, reverseCallsEdges, callsEdges) => {
|
|
|
217
295
|
*/
|
|
218
296
|
const traceFromEntryPoint = (entryId, callsEdges, config) => {
|
|
219
297
|
const traces = [];
|
|
298
|
+
const isRuntimeRootEntry = entryId.includes(SYNTHETIC_RUNTIME_ROOT_MARKER);
|
|
299
|
+
const maxTraceCount = isRuntimeRootEntry ? SYNTHETIC_RUNTIME_ROOT_TRACE_LIMIT * 6 : config.maxBranching * 3;
|
|
220
300
|
// BFS with path tracking
|
|
221
301
|
// Each queue item: [currentNodeId, pathSoFar]
|
|
222
302
|
const queue = [[entryId, [entryId]]];
|
|
223
|
-
while (queue.length > 0 && traces.length <
|
|
303
|
+
while (queue.length > 0 && traces.length < maxTraceCount) {
|
|
224
304
|
const [currentId, path] = queue.shift();
|
|
225
305
|
// Get outgoing calls
|
|
226
306
|
const callees = callsEdges.get(currentId) || [];
|
|
@@ -238,7 +318,13 @@ const traceFromEntryPoint = (entryId, callsEdges, config) => {
|
|
|
238
318
|
}
|
|
239
319
|
else {
|
|
240
320
|
// Continue tracing - limit branching
|
|
241
|
-
const
|
|
321
|
+
const branchingLimit = path.length === 1 && currentId.includes(SYNTHETIC_RUNTIME_ROOT_MARKER)
|
|
322
|
+
? Math.min(callees.length, Math.max(config.maxBranching * 8, SYNTHETIC_RUNTIME_ROOT_TRACE_LIMIT * 4))
|
|
323
|
+
: config.maxBranching;
|
|
324
|
+
const orderedCallees = isRuntimeRootEntry
|
|
325
|
+
? [...callees].sort((left, right) => scoreRuntimeTraceTarget(right) - scoreRuntimeTraceTarget(left))
|
|
326
|
+
: callees;
|
|
327
|
+
const limitedCallees = orderedCallees.slice(0, branchingLimit);
|
|
242
328
|
let addedBranch = false;
|
|
243
329
|
for (const calleeId of limitedCallees) {
|
|
244
330
|
// Avoid cycles
|
|
@@ -295,13 +381,108 @@ const deduplicateByEndpoints = (traces) => {
|
|
|
295
381
|
// Sort longest first so the first seen per key is the longest
|
|
296
382
|
const sorted = [...traces].sort((a, b) => b.length - a.length);
|
|
297
383
|
for (const trace of sorted) {
|
|
298
|
-
const key =
|
|
384
|
+
const key = isSyntheticRuntimeRootTrace(trace)
|
|
385
|
+
? `${trace[0]}::${trace[1] ?? ''}::${trace[trace.length - 1]}`
|
|
386
|
+
: `${trace[0]}::${trace[trace.length - 1]}`;
|
|
299
387
|
if (!byEndpoints.has(key)) {
|
|
300
388
|
byEndpoints.set(key, trace);
|
|
301
389
|
}
|
|
302
390
|
}
|
|
303
391
|
return Array.from(byEndpoints.values());
|
|
304
392
|
};
|
|
393
|
+
/**
|
|
394
|
+
* Keep synthetic runtime-root traces useful but bounded.
|
|
395
|
+
* Preserve a small set of distinct lifecycle/runtime traces instead of collapsing to one.
|
|
396
|
+
*/
|
|
397
|
+
const capSyntheticRuntimeRootTraces = (traces) => {
|
|
398
|
+
if (traces.length === 0)
|
|
399
|
+
return [];
|
|
400
|
+
const runtimeRootTraces = traces
|
|
401
|
+
.filter(isSyntheticRuntimeRootTrace)
|
|
402
|
+
.sort((a, b) => scoreSyntheticRuntimeTrace(b) - scoreSyntheticRuntimeTrace(a));
|
|
403
|
+
if (runtimeRootTraces.length <= SYNTHETIC_RUNTIME_ROOT_TRACE_LIMIT)
|
|
404
|
+
return traces;
|
|
405
|
+
const keep = runtimeRootTraces.slice(0, SYNTHETIC_RUNTIME_ROOT_TRACE_LIMIT);
|
|
406
|
+
const filtered = traces.filter((trace) => !isSyntheticRuntimeRootTrace(trace));
|
|
407
|
+
filtered.push(...keep);
|
|
408
|
+
return filtered;
|
|
409
|
+
};
|
|
410
|
+
const isSyntheticRuntimeRootTrace = (trace) => Boolean(trace[0]?.includes(SYNTHETIC_RUNTIME_ROOT_MARKER));
|
|
411
|
+
const scoreSyntheticRuntimeTrace = (trace) => {
|
|
412
|
+
let score = trace.length * 100;
|
|
413
|
+
const joined = trace.join(' ');
|
|
414
|
+
if (joined.includes('RegisterGraphEvents'))
|
|
415
|
+
score += 80;
|
|
416
|
+
if (joined.includes('RegisterEvents'))
|
|
417
|
+
score += 60;
|
|
418
|
+
if (joined.includes('StartRoutineWithEvents'))
|
|
419
|
+
score += 60;
|
|
420
|
+
if (joined.includes('GetValue'))
|
|
421
|
+
score += 70;
|
|
422
|
+
if (joined.includes('CheckReload'))
|
|
423
|
+
score += 60;
|
|
424
|
+
if (joined.includes('ReloadRoutine'))
|
|
425
|
+
score += 60;
|
|
426
|
+
if (joined.includes('EquipWithEvent'))
|
|
427
|
+
score += 40;
|
|
428
|
+
if (joined.includes('Equip'))
|
|
429
|
+
score += 30;
|
|
430
|
+
return score;
|
|
431
|
+
};
|
|
432
|
+
const scoreRuntimeRootTarget = (nodeId) => {
|
|
433
|
+
let score = 0;
|
|
434
|
+
const text = String(nodeId || '');
|
|
435
|
+
if (text.includes('GunGraphMB'))
|
|
436
|
+
score += 200;
|
|
437
|
+
if (text.includes('MeleeGraphMB'))
|
|
438
|
+
score += 120;
|
|
439
|
+
if (text.includes('/Reload'))
|
|
440
|
+
score += 180;
|
|
441
|
+
if (text.includes('/Graph/'))
|
|
442
|
+
score += 100;
|
|
443
|
+
if (text.includes('/PowerUps/'))
|
|
444
|
+
score += 70;
|
|
445
|
+
if (text.includes('/Core/'))
|
|
446
|
+
score += 40;
|
|
447
|
+
if (text.includes(':OnEnable'))
|
|
448
|
+
score += 30;
|
|
449
|
+
if (text.includes(':Awake'))
|
|
450
|
+
score += 20;
|
|
451
|
+
if (text.includes(':Start'))
|
|
452
|
+
score += 10;
|
|
453
|
+
return score;
|
|
454
|
+
};
|
|
455
|
+
const scoreRuntimeTraceTarget = (nodeId) => {
|
|
456
|
+
const text = String(nodeId || '');
|
|
457
|
+
let score = scoreRuntimeRootTarget(text);
|
|
458
|
+
if (text.includes('RegisterGraphEvents'))
|
|
459
|
+
score += 220;
|
|
460
|
+
if (text.includes('RegisterEvents'))
|
|
461
|
+
score += 180;
|
|
462
|
+
if (text.includes('StartRoutineWithEvents'))
|
|
463
|
+
score += 260;
|
|
464
|
+
if (text.includes('GetValue'))
|
|
465
|
+
score += 200;
|
|
466
|
+
if (text.includes('CheckReload'))
|
|
467
|
+
score += 180;
|
|
468
|
+
if (text.includes('ReloadRoutine'))
|
|
469
|
+
score += 170;
|
|
470
|
+
if (text.includes('AttackRoutineWithEvents'))
|
|
471
|
+
score -= 80;
|
|
472
|
+
if (text.includes('IGraphEvent.cs:Register'))
|
|
473
|
+
score -= 140;
|
|
474
|
+
if (text.includes('WaitForHelper.cs:EndOfFrame'))
|
|
475
|
+
score -= 160;
|
|
476
|
+
if (text.includes('/Graph/Graphs/GunGraph.cs'))
|
|
477
|
+
score += 120;
|
|
478
|
+
if (text.includes('/Graph/Nodes/Reloads/ReloadBase.cs'))
|
|
479
|
+
score += 220;
|
|
480
|
+
if (text.includes('/Graph/Nodes/Reloads/Reload.cs'))
|
|
481
|
+
score += 180;
|
|
482
|
+
if (text.includes('/Graph/Nodes/Reloads/'))
|
|
483
|
+
score += 120;
|
|
484
|
+
return score;
|
|
485
|
+
};
|
|
305
486
|
// ============================================================================
|
|
306
487
|
// HELPER: String utilities
|
|
307
488
|
// ============================================================================
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type UnityLifecycleSyntheticConfig } from './unity-lifecycle-synthetic-calls.js';
|
|
2
|
+
export interface UnityLifecycleConfig extends UnityLifecycleSyntheticConfig {
|
|
3
|
+
persistLifecycleProcessMetadata: boolean;
|
|
4
|
+
}
|
|
5
|
+
export declare const resolveUnityLifecycleConfig: (env: NodeJS.ProcessEnv) => UnityLifecycleConfig;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { DEFAULT_UNITY_LIFECYCLE_SYNTHETIC_CONFIG, } from './unity-lifecycle-synthetic-calls.js';
|
|
2
|
+
const TRUE_VALUES = new Set(['1', 'true', 'on', 'yes']);
|
|
3
|
+
const parsePositiveInt = (raw, fallback) => {
|
|
4
|
+
const value = Number.parseInt(String(raw || '').trim(), 10);
|
|
5
|
+
if (!Number.isFinite(value) || value <= 0)
|
|
6
|
+
return fallback;
|
|
7
|
+
return value;
|
|
8
|
+
};
|
|
9
|
+
const parseBool = (raw) => {
|
|
10
|
+
const normalized = String(raw || '').trim().toLowerCase();
|
|
11
|
+
return TRUE_VALUES.has(normalized);
|
|
12
|
+
};
|
|
13
|
+
export const resolveUnityLifecycleConfig = (env) => {
|
|
14
|
+
const enabled = parseBool(env.GITNEXUS_UNITY_LIFECYCLE_SYNTHETIC_CALLS);
|
|
15
|
+
const persistLifecycleProcessMetadata = parseBool(env.GITNEXUS_UNITY_LIFECYCLE_PROCESS_PERSIST);
|
|
16
|
+
const maxSyntheticEdgesPerClass = parsePositiveInt(env.GITNEXUS_UNITY_LIFECYCLE_SYNTHETIC_MAX_PER_CLASS, DEFAULT_UNITY_LIFECYCLE_SYNTHETIC_CONFIG.maxSyntheticEdgesPerClass);
|
|
17
|
+
const maxSyntheticEdgesTotal = parsePositiveInt(env.GITNEXUS_UNITY_LIFECYCLE_SYNTHETIC_MAX_TOTAL, DEFAULT_UNITY_LIFECYCLE_SYNTHETIC_CONFIG.maxSyntheticEdgesTotal);
|
|
18
|
+
return {
|
|
19
|
+
...DEFAULT_UNITY_LIFECYCLE_SYNTHETIC_CONFIG,
|
|
20
|
+
enabled,
|
|
21
|
+
persistLifecycleProcessMetadata,
|
|
22
|
+
maxSyntheticEdgesPerClass,
|
|
23
|
+
maxSyntheticEdgesTotal,
|
|
24
|
+
};
|
|
25
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { GraphNode, KnowledgeGraph } from '../graph/types.js';
|
|
2
|
+
export interface UnityLifecycleSyntheticConfig {
|
|
3
|
+
enabled: boolean;
|
|
4
|
+
maxSyntheticEdgesPerClass: number;
|
|
5
|
+
maxSyntheticEdgesTotal: number;
|
|
6
|
+
lifecycleEdgeConfidence: number;
|
|
7
|
+
loaderEdgeConfidence: number;
|
|
8
|
+
}
|
|
9
|
+
export declare const DEFAULT_UNITY_LIFECYCLE_SYNTHETIC_CONFIG: UnityLifecycleSyntheticConfig;
|
|
10
|
+
export interface UnityLifecycleHost {
|
|
11
|
+
classNode: GraphNode;
|
|
12
|
+
baseType: 'MonoBehaviour' | 'ScriptableObject';
|
|
13
|
+
lifecycleCallbacks: GraphNode[];
|
|
14
|
+
loaderAnchors: GraphNode[];
|
|
15
|
+
methods: GraphNode[];
|
|
16
|
+
}
|
|
17
|
+
export interface UnityLifecycleSyntheticResult {
|
|
18
|
+
syntheticEdgeCount: number;
|
|
19
|
+
lifecycleEdgeCount: number;
|
|
20
|
+
loaderEdgeCount: number;
|
|
21
|
+
hostCount: number;
|
|
22
|
+
rejectedHostCount: number;
|
|
23
|
+
runtimeRootNodeId?: string;
|
|
24
|
+
}
|
|
25
|
+
export declare const detectUnityLifecycleHosts: (graph: KnowledgeGraph) => UnityLifecycleHost[];
|
|
26
|
+
export declare const applyUnityLifecycleSyntheticCalls: (graph: KnowledgeGraph, config?: Partial<UnityLifecycleSyntheticConfig>) => UnityLifecycleSyntheticResult;
|