@veewo/gitnexus 1.4.11-rc.2 → 1.5.0-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/hydration-policy-repeatability-runner.d.ts +55 -0
- package/dist/benchmark/u2-e2e/hydration-policy-repeatability-runner.js +190 -0
- package/dist/benchmark/u2-e2e/hydration-policy-repeatability-runner.test.js +13 -0
- package/dist/benchmark/u2-e2e/phase1-process-ref-acceptance-runner.d.ts +22 -0
- package/dist/benchmark/u2-e2e/phase1-process-ref-acceptance-runner.js +100 -0
- package/dist/benchmark/u2-e2e/phase1-process-ref-acceptance-runner.test.d.ts +1 -0
- package/dist/benchmark/u2-e2e/phase1-process-ref-acceptance-runner.test.js +13 -0
- package/dist/benchmark/u2-e2e/phase2-runtime-claim-acceptance-runner.d.ts +27 -0
- package/dist/benchmark/u2-e2e/phase2-runtime-claim-acceptance-runner.js +118 -0
- package/dist/benchmark/u2-e2e/phase2-runtime-claim-acceptance-runner.test.d.ts +1 -0
- package/dist/benchmark/u2-e2e/phase2-runtime-claim-acceptance-runner.test.js +16 -0
- package/dist/benchmark/u2-e2e/phase5-rule-lab-acceptance-runner.d.ts +60 -0
- package/dist/benchmark/u2-e2e/phase5-rule-lab-acceptance-runner.js +331 -0
- package/dist/benchmark/u2-e2e/phase5-rule-lab-acceptance-runner.test.d.ts +1 -0
- package/dist/benchmark/u2-e2e/phase5-rule-lab-acceptance-runner.test.js +42 -0
- package/dist/benchmark/u2-e2e/reload-v1-acceptance-runner.js +4 -4
- package/dist/benchmark/unity-lazy-context-sampler.d.ts +6 -0
- package/dist/benchmark/unity-lazy-context-sampler.js +49 -13
- package/dist/benchmark/unity-lazy-context-sampler.test.js +4 -0
- package/dist/cli/ai-context.js +6 -1
- package/dist/cli/eval-server.js +0 -3
- package/dist/cli/index.js +8 -0
- package/dist/cli/mcp.js +0 -3
- package/dist/cli/rule-lab.d.ts +42 -0
- package/dist/cli/rule-lab.js +157 -0
- package/dist/cli/rule-lab.test.d.ts +1 -0
- package/dist/cli/rule-lab.test.js +11 -0
- package/dist/cli/tool.d.ts +7 -1
- package/dist/cli/tool.js +6 -0
- package/dist/core/config/unity-config.d.ts +20 -0
- package/dist/core/config/unity-config.js +46 -0
- package/dist/core/graph/types.d.ts +1 -1
- package/dist/core/ingestion/pipeline.js +38 -13
- package/dist/core/ingestion/unity-lifecycle-synthetic-calls.d.ts +0 -2
- package/dist/core/ingestion/unity-lifecycle-synthetic-calls.js +26 -213
- package/dist/core/ingestion/unity-lifecycle-synthetic-calls.test.js +1 -1
- package/dist/core/ingestion/unity-resource-processor.js +87 -22
- package/dist/core/ingestion/unity-resource-processor.test.js +67 -2
- package/dist/core/ingestion/unity-runtime-binding-rules.d.ts +11 -0
- package/dist/core/ingestion/unity-runtime-binding-rules.js +179 -0
- package/dist/core/unity/options.d.ts +4 -0
- package/dist/core/unity/options.js +18 -0
- package/dist/core/unity/options.test.js +11 -1
- package/dist/core/unity/resolver.js +11 -1
- package/dist/core/unity/resolver.test.js +62 -0
- package/dist/core/unity/yaml-object-graph.js +1 -1
- package/dist/core/unity/yaml-object-graph.test.js +16 -0
- package/dist/mcp/local/derived-process-reader.d.ts +2 -0
- package/dist/mcp/local/derived-process-reader.js +15 -0
- package/dist/mcp/local/local-backend.d.ts +56 -0
- package/dist/mcp/local/local-backend.js +1003 -53
- package/dist/mcp/local/local-backend.unity-merge.test.js +1 -1
- package/dist/mcp/local/process-confidence.js +1 -1
- package/dist/mcp/local/process-evidence.d.ts +1 -0
- package/dist/mcp/local/process-evidence.js +22 -0
- package/dist/mcp/local/process-evidence.test.js +11 -1
- package/dist/mcp/local/process-ref.d.ts +24 -0
- package/dist/mcp/local/process-ref.js +33 -0
- package/dist/mcp/local/process-ref.test.d.ts +1 -0
- package/dist/mcp/local/process-ref.test.js +24 -0
- package/dist/mcp/local/runtime-chain-verify.d.ts +15 -1
- package/dist/mcp/local/runtime-chain-verify.js +191 -187
- package/dist/mcp/local/runtime-chain-verify.test.js +546 -19
- package/dist/mcp/local/runtime-claim-rule-registry.d.ts +63 -0
- package/dist/mcp/local/runtime-claim-rule-registry.js +308 -0
- package/dist/mcp/local/runtime-claim-rule-registry.test.d.ts +1 -0
- package/dist/mcp/local/runtime-claim-rule-registry.test.js +215 -0
- package/dist/mcp/local/runtime-claim.d.ts +38 -0
- package/dist/mcp/local/runtime-claim.js +54 -0
- package/dist/mcp/local/runtime-claim.test.d.ts +1 -0
- package/dist/mcp/local/runtime-claim.test.js +27 -0
- package/dist/mcp/local/unity-enrichment.d.ts +1 -0
- package/dist/mcp/local/unity-enrichment.js +1 -1
- package/dist/mcp/local/unity-evidence-view.d.ts +26 -0
- package/dist/mcp/local/unity-evidence-view.js +96 -0
- package/dist/mcp/local/unity-evidence-view.test.d.ts +1 -0
- package/dist/mcp/local/unity-evidence-view.test.js +39 -0
- package/dist/mcp/local/unity-lazy-hydrator.d.ts +2 -2
- package/dist/mcp/local/unity-lazy-hydrator.js +3 -3
- package/dist/mcp/local/unity-lazy-hydrator.test.js +4 -4
- package/dist/mcp/local/unity-parity-cache.js +2 -6
- package/dist/mcp/local/unity-parity-seed-loader.d.ts +1 -0
- package/dist/mcp/local/unity-parity-seed-loader.js +10 -16
- package/dist/mcp/local/unity-parity-seed-loader.test.js +3 -12
- package/dist/mcp/local/unity-runtime-hydration.d.ts +3 -2
- package/dist/mcp/local/unity-runtime-hydration.js +13 -16
- package/dist/mcp/local/unity-runtime-hydration.test.js +15 -1
- package/dist/mcp/resources.js +13 -0
- package/dist/mcp/tools.js +166 -13
- package/dist/rule-lab/analyze.d.ts +12 -0
- package/dist/rule-lab/analyze.js +90 -0
- package/dist/rule-lab/analyze.test.d.ts +1 -0
- package/dist/rule-lab/analyze.test.js +28 -0
- package/dist/rule-lab/compile.d.ts +5 -0
- package/dist/rule-lab/compile.js +51 -0
- package/dist/rule-lab/compiled-bundles.d.ts +30 -0
- package/dist/rule-lab/compiled-bundles.js +36 -0
- package/dist/rule-lab/curate.d.ts +32 -0
- package/dist/rule-lab/curate.js +134 -0
- package/dist/rule-lab/curate.test.d.ts +1 -0
- package/dist/rule-lab/curate.test.js +72 -0
- package/dist/rule-lab/discover.d.ts +13 -0
- package/dist/rule-lab/discover.js +74 -0
- package/dist/rule-lab/discover.test.d.ts +1 -0
- package/dist/rule-lab/discover.test.js +42 -0
- package/dist/rule-lab/paths.d.ts +21 -0
- package/dist/rule-lab/paths.js +37 -0
- package/dist/rule-lab/paths.test.d.ts +1 -0
- package/dist/rule-lab/paths.test.js +46 -0
- package/dist/rule-lab/promote.d.ts +26 -0
- package/dist/rule-lab/promote.js +314 -0
- package/dist/rule-lab/promote.test.d.ts +1 -0
- package/dist/rule-lab/promote.test.js +164 -0
- package/dist/rule-lab/regress.d.ts +60 -0
- package/dist/rule-lab/regress.js +122 -0
- package/dist/rule-lab/regress.test.d.ts +1 -0
- package/dist/rule-lab/regress.test.js +68 -0
- package/dist/rule-lab/review-pack.d.ts +31 -0
- package/dist/rule-lab/review-pack.js +125 -0
- package/dist/rule-lab/review-pack.test.d.ts +1 -0
- package/dist/rule-lab/review-pack.test.js +49 -0
- package/dist/rule-lab/types.d.ts +99 -0
- package/dist/rule-lab/types.js +1 -0
- package/package.json +1 -1
- package/skills/_shared/unity-hydration-contract.md +11 -0
- package/skills/_shared/unity-ui-trace-contract.md +33 -0
- package/skills/gitnexus-cli.md +11 -25
- package/skills/gitnexus-guide.md +2 -0
- package/skills/gitnexus-unity-rule-gen.md +318 -0
- package/dist/core/ingestion/unity-lifecycle-config.d.ts +0 -5
- package/dist/core/ingestion/unity-lifecycle-config.js +0 -25
- package/dist/mcp/local/unity-lazy-config.d.ts +0 -6
- package/dist/mcp/local/unity-lazy-config.js +0 -7
- package/dist/mcp/local/unity-lazy-config.test.js +0 -9
- package/dist/mcp/local/unity-process-confidence-config.d.ts +0 -1
- package/dist/mcp/local/unity-process-confidence-config.js +0 -4
- package/dist/mcp/local/unity-runtime-chain-verify-config.d.ts +0 -1
- package/dist/mcp/local/unity-runtime-chain-verify-config.js +0 -10
- /package/dist/{mcp/local/unity-lazy-config.test.d.ts → benchmark/u2-e2e/hydration-policy-repeatability-runner.test.d.ts} +0 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { Command } from 'commander';
|
|
2
|
+
declare const RULE_LAB_COMMANDS: readonly ["discover", "analyze", "review-pack", "curate", "promote", "regress"];
|
|
3
|
+
type RuleLabHandlerName = 'ruleLabDiscoverCommand' | 'ruleLabAnalyzeCommand' | 'ruleLabReviewPackCommand' | 'ruleLabCurateCommand' | 'ruleLabPromoteCommand' | 'ruleLabRegressCommand';
|
|
4
|
+
type LazyFactory = (handlerName: RuleLabHandlerName) => (...args: any[]) => void | Promise<void>;
|
|
5
|
+
export declare function getRuleLabCommandNames(program: Command): string[];
|
|
6
|
+
export declare function attachRuleLabCommands(program: Command, lazyFactory?: LazyFactory): void;
|
|
7
|
+
export declare function ruleLabDiscoverCommand(options: {
|
|
8
|
+
repoPath?: string;
|
|
9
|
+
scope?: 'full' | 'diff';
|
|
10
|
+
seed?: string;
|
|
11
|
+
}): Promise<void>;
|
|
12
|
+
export declare function ruleLabAnalyzeCommand(options: {
|
|
13
|
+
repoPath?: string;
|
|
14
|
+
runId: string;
|
|
15
|
+
sliceId: string;
|
|
16
|
+
}): Promise<void>;
|
|
17
|
+
export declare function ruleLabReviewPackCommand(options: {
|
|
18
|
+
repoPath?: string;
|
|
19
|
+
runId: string;
|
|
20
|
+
sliceId: string;
|
|
21
|
+
maxTokens?: string | number;
|
|
22
|
+
}): Promise<void>;
|
|
23
|
+
export declare function ruleLabCurateCommand(options: {
|
|
24
|
+
repoPath?: string;
|
|
25
|
+
runId: string;
|
|
26
|
+
sliceId: string;
|
|
27
|
+
inputPath: string;
|
|
28
|
+
}): Promise<void>;
|
|
29
|
+
export declare function ruleLabPromoteCommand(options: {
|
|
30
|
+
repoPath?: string;
|
|
31
|
+
runId: string;
|
|
32
|
+
sliceId: string;
|
|
33
|
+
version?: string;
|
|
34
|
+
}): Promise<void>;
|
|
35
|
+
export declare function ruleLabRegressCommand(options: {
|
|
36
|
+
precision: string | number;
|
|
37
|
+
coverage: string | number;
|
|
38
|
+
repoPath?: string;
|
|
39
|
+
runId?: string;
|
|
40
|
+
probesPath?: string;
|
|
41
|
+
}): Promise<void>;
|
|
42
|
+
export { RULE_LAB_COMMANDS };
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { writeSync } from 'node:fs';
|
|
2
|
+
import fs from 'node:fs/promises';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { discoverRuleLabRun } from '../rule-lab/discover.js';
|
|
5
|
+
import { analyzeRuleLabSlice } from '../rule-lab/analyze.js';
|
|
6
|
+
import { buildReviewPack } from '../rule-lab/review-pack.js';
|
|
7
|
+
import { curateRuleLabSlice } from '../rule-lab/curate.js';
|
|
8
|
+
import { promoteCuratedRules } from '../rule-lab/promote.js';
|
|
9
|
+
import { runRuleLabRegress } from '../rule-lab/regress.js';
|
|
10
|
+
import { compileRules } from '../rule-lab/compile.js';
|
|
11
|
+
const RULE_LAB_COMMANDS = ['discover', 'analyze', 'review-pack', 'curate', 'promote', 'regress'];
|
|
12
|
+
function output(data) {
|
|
13
|
+
const text = typeof data === 'string' ? data : JSON.stringify(data, null, 2);
|
|
14
|
+
writeSync(1, `${text}\n`);
|
|
15
|
+
}
|
|
16
|
+
function resolveRepoPath(repoPath) {
|
|
17
|
+
return path.resolve(repoPath || process.cwd());
|
|
18
|
+
}
|
|
19
|
+
export function getRuleLabCommandNames(program) {
|
|
20
|
+
const root = program.commands.find((command) => command.name() === 'rule-lab');
|
|
21
|
+
if (!root)
|
|
22
|
+
return [];
|
|
23
|
+
return root.commands.map((command) => command.name());
|
|
24
|
+
}
|
|
25
|
+
export function attachRuleLabCommands(program, lazyFactory) {
|
|
26
|
+
const action = (handlerName) => {
|
|
27
|
+
if (lazyFactory)
|
|
28
|
+
return lazyFactory(handlerName);
|
|
29
|
+
switch (handlerName) {
|
|
30
|
+
case 'ruleLabDiscoverCommand':
|
|
31
|
+
return (options) => ruleLabDiscoverCommand(options);
|
|
32
|
+
case 'ruleLabAnalyzeCommand':
|
|
33
|
+
return (options) => ruleLabAnalyzeCommand(options);
|
|
34
|
+
case 'ruleLabReviewPackCommand':
|
|
35
|
+
return (options) => ruleLabReviewPackCommand(options);
|
|
36
|
+
case 'ruleLabCurateCommand':
|
|
37
|
+
return (options) => ruleLabCurateCommand(options);
|
|
38
|
+
case 'ruleLabPromoteCommand':
|
|
39
|
+
return (options) => ruleLabPromoteCommand(options);
|
|
40
|
+
case 'ruleLabRegressCommand':
|
|
41
|
+
return (options) => ruleLabRegressCommand(options);
|
|
42
|
+
default:
|
|
43
|
+
return () => {
|
|
44
|
+
throw new Error(`Unknown rule lab handler: ${handlerName}`);
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
const root = program
|
|
49
|
+
.command('rule-lab')
|
|
50
|
+
.description('Offline rule-lab workflow for discover/analyze/review-pack/curate/promote/regress');
|
|
51
|
+
root
|
|
52
|
+
.command('discover')
|
|
53
|
+
.option('--repo-path <path>', 'Repository path (default: cwd)')
|
|
54
|
+
.option('--scope <scope>', 'Discovery scope: full|diff', 'full')
|
|
55
|
+
.option('--seed <seed>', 'Optional deterministic seed')
|
|
56
|
+
.action(action('ruleLabDiscoverCommand'));
|
|
57
|
+
root
|
|
58
|
+
.command('analyze')
|
|
59
|
+
.requiredOption('--run-id <id>', 'Rule-lab run id')
|
|
60
|
+
.requiredOption('--slice-id <id>', 'Slice id')
|
|
61
|
+
.option('--repo-path <path>', 'Repository path (default: cwd)')
|
|
62
|
+
.action(action('ruleLabAnalyzeCommand'));
|
|
63
|
+
root
|
|
64
|
+
.command('review-pack')
|
|
65
|
+
.requiredOption('--run-id <id>', 'Rule-lab run id')
|
|
66
|
+
.requiredOption('--slice-id <id>', 'Slice id')
|
|
67
|
+
.option('--repo-path <path>', 'Repository path (default: cwd)')
|
|
68
|
+
.option('--max-tokens <n>', 'Token budget', '6000')
|
|
69
|
+
.action(action('ruleLabReviewPackCommand'));
|
|
70
|
+
root
|
|
71
|
+
.command('curate')
|
|
72
|
+
.requiredOption('--run-id <id>', 'Rule-lab run id')
|
|
73
|
+
.requiredOption('--slice-id <id>', 'Slice id')
|
|
74
|
+
.requiredOption('--input-path <path>', 'Path to curation input JSON')
|
|
75
|
+
.option('--repo-path <path>', 'Repository path (default: cwd)')
|
|
76
|
+
.action(action('ruleLabCurateCommand'));
|
|
77
|
+
root
|
|
78
|
+
.command('promote')
|
|
79
|
+
.requiredOption('--run-id <id>', 'Rule-lab run id')
|
|
80
|
+
.requiredOption('--slice-id <id>', 'Slice id')
|
|
81
|
+
.option('--repo-path <path>', 'Repository path (default: cwd)')
|
|
82
|
+
.option('--version <version>', 'Promoted rule version', '1.0.0')
|
|
83
|
+
.action(action('ruleLabPromoteCommand'));
|
|
84
|
+
root
|
|
85
|
+
.command('regress')
|
|
86
|
+
.requiredOption('--precision <n>', 'Precision metric')
|
|
87
|
+
.requiredOption('--coverage <n>', 'Coverage metric')
|
|
88
|
+
.option('--repo-path <path>', 'Repository path (default: cwd)')
|
|
89
|
+
.option('--run-id <id>', 'Run id (if provided, write report to .gitnexus/rules/reports)')
|
|
90
|
+
.option('--probes-path <path>', 'Optional JSON file containing regress probes')
|
|
91
|
+
.action(action('ruleLabRegressCommand'));
|
|
92
|
+
root
|
|
93
|
+
.command('compile')
|
|
94
|
+
.description('Compile approved YAML rules into a JSON bundle')
|
|
95
|
+
.option('--repo-path <path>', 'Repository path (default: cwd)')
|
|
96
|
+
.option('--family <family>', 'Rule family to compile', 'analyze_rules')
|
|
97
|
+
.action((options) => compileRules({ repoPath: options.repoPath, family: options.family }));
|
|
98
|
+
}
|
|
99
|
+
export async function ruleLabDiscoverCommand(options) {
|
|
100
|
+
const result = await discoverRuleLabRun({
|
|
101
|
+
repoPath: resolveRepoPath(options?.repoPath),
|
|
102
|
+
scope: options?.scope || 'full',
|
|
103
|
+
seed: options?.seed,
|
|
104
|
+
});
|
|
105
|
+
output(result);
|
|
106
|
+
}
|
|
107
|
+
export async function ruleLabAnalyzeCommand(options) {
|
|
108
|
+
const result = await analyzeRuleLabSlice({
|
|
109
|
+
repoPath: resolveRepoPath(options?.repoPath),
|
|
110
|
+
runId: options.runId,
|
|
111
|
+
sliceId: options.sliceId,
|
|
112
|
+
});
|
|
113
|
+
output(result);
|
|
114
|
+
}
|
|
115
|
+
export async function ruleLabReviewPackCommand(options) {
|
|
116
|
+
const result = await buildReviewPack({
|
|
117
|
+
repoPath: resolveRepoPath(options?.repoPath),
|
|
118
|
+
runId: options.runId,
|
|
119
|
+
sliceId: options.sliceId,
|
|
120
|
+
maxTokens: Number(options.maxTokens || 6000),
|
|
121
|
+
});
|
|
122
|
+
output(result);
|
|
123
|
+
}
|
|
124
|
+
export async function ruleLabCurateCommand(options) {
|
|
125
|
+
const result = await curateRuleLabSlice({
|
|
126
|
+
repoPath: resolveRepoPath(options?.repoPath),
|
|
127
|
+
runId: options.runId,
|
|
128
|
+
sliceId: options.sliceId,
|
|
129
|
+
inputPath: path.resolve(options.inputPath),
|
|
130
|
+
});
|
|
131
|
+
output(result);
|
|
132
|
+
}
|
|
133
|
+
export async function ruleLabPromoteCommand(options) {
|
|
134
|
+
const result = await promoteCuratedRules({
|
|
135
|
+
repoPath: resolveRepoPath(options?.repoPath),
|
|
136
|
+
runId: options.runId,
|
|
137
|
+
sliceId: options.sliceId,
|
|
138
|
+
version: options.version,
|
|
139
|
+
});
|
|
140
|
+
output(result);
|
|
141
|
+
}
|
|
142
|
+
export async function ruleLabRegressCommand(options) {
|
|
143
|
+
let probes;
|
|
144
|
+
if (options.probesPath) {
|
|
145
|
+
const raw = await fs.readFile(path.resolve(options.probesPath), 'utf-8');
|
|
146
|
+
probes = JSON.parse(raw);
|
|
147
|
+
}
|
|
148
|
+
const result = await runRuleLabRegress({
|
|
149
|
+
precision: Number(options.precision),
|
|
150
|
+
coverage: Number(options.coverage),
|
|
151
|
+
repoPath: options.repoPath ? resolveRepoPath(options.repoPath) : undefined,
|
|
152
|
+
runId: options.runId,
|
|
153
|
+
probes,
|
|
154
|
+
});
|
|
155
|
+
output(result);
|
|
156
|
+
}
|
|
157
|
+
export { RULE_LAB_COMMANDS };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
import { attachRuleLabCommands, getRuleLabCommandNames } from './rule-lab.js';
|
|
4
|
+
describe('rule-lab cli', () => {
|
|
5
|
+
it('registers all six rule-lab subcommands', async () => {
|
|
6
|
+
const program = new Command();
|
|
7
|
+
attachRuleLabCommands(program);
|
|
8
|
+
const cmds = getRuleLabCommandNames(program);
|
|
9
|
+
expect(cmds).toEqual(['discover', 'analyze', 'review-pack', 'curate', 'promote', 'regress']);
|
|
10
|
+
});
|
|
11
|
+
});
|
package/dist/cli/tool.d.ts
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* native module which captures the Node.js process.stdout stream during init.
|
|
15
15
|
* See the output() function for details (#324).
|
|
16
16
|
*/
|
|
17
|
-
import type { UnityHydrationMode, UnityResourcesMode } from '../core/unity/options.js';
|
|
17
|
+
import type { UnityEvidenceMode, UnityHydrationMode, UnityResourcesMode } from '../core/unity/options.js';
|
|
18
18
|
export declare function queryCommand(queryText: string, options?: {
|
|
19
19
|
repo?: string;
|
|
20
20
|
context?: string;
|
|
@@ -24,6 +24,9 @@ export declare function queryCommand(queryText: string, options?: {
|
|
|
24
24
|
scopePreset?: 'unity-gameplay' | 'unity-all';
|
|
25
25
|
unityResources?: UnityResourcesMode;
|
|
26
26
|
unityHydration?: UnityHydrationMode;
|
|
27
|
+
unityEvidence?: UnityEvidenceMode;
|
|
28
|
+
resourcePathPrefix?: string;
|
|
29
|
+
resourceSeedMode?: 'strict' | 'balanced';
|
|
27
30
|
runtimeChainVerify?: 'off' | 'on-demand';
|
|
28
31
|
}): Promise<void>;
|
|
29
32
|
export declare function contextCommand(name: string, options?: {
|
|
@@ -33,6 +36,9 @@ export declare function contextCommand(name: string, options?: {
|
|
|
33
36
|
content?: boolean;
|
|
34
37
|
unityResources?: UnityResourcesMode;
|
|
35
38
|
unityHydration?: UnityHydrationMode;
|
|
39
|
+
unityEvidence?: UnityEvidenceMode;
|
|
40
|
+
resourcePathPrefix?: string;
|
|
41
|
+
resourceSeedMode?: 'strict' | 'balanced';
|
|
36
42
|
runtimeChainVerify?: 'off' | 'on-demand';
|
|
37
43
|
}): Promise<void>;
|
|
38
44
|
export declare function impactCommand(target: string, options?: {
|
package/dist/cli/tool.js
CHANGED
|
@@ -94,6 +94,9 @@ export async function queryCommand(queryText, options) {
|
|
|
94
94
|
scope_preset: options?.scopePreset,
|
|
95
95
|
unity_resources: options?.unityResources,
|
|
96
96
|
unity_hydration_mode: options?.unityHydration,
|
|
97
|
+
unity_evidence_mode: options?.unityEvidence,
|
|
98
|
+
resource_path_prefix: options?.resourcePathPrefix,
|
|
99
|
+
resource_seed_mode: options?.resourceSeedMode,
|
|
97
100
|
runtime_chain_verify: options?.runtimeChainVerify,
|
|
98
101
|
repo,
|
|
99
102
|
});
|
|
@@ -113,6 +116,9 @@ export async function contextCommand(name, options) {
|
|
|
113
116
|
include_content: options?.content ?? false,
|
|
114
117
|
unity_resources: options?.unityResources,
|
|
115
118
|
unity_hydration_mode: options?.unityHydration,
|
|
119
|
+
unity_evidence_mode: options?.unityEvidence,
|
|
120
|
+
resource_path_prefix: options?.resourcePathPrefix,
|
|
121
|
+
resource_seed_mode: options?.resourceSeedMode,
|
|
116
122
|
runtime_chain_verify: options?.runtimeChainVerify,
|
|
117
123
|
repo,
|
|
118
124
|
});
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export interface UnityConfig {
|
|
2
|
+
maxSyntheticEdgesPerClass: number;
|
|
3
|
+
maxSyntheticEdgesTotal: number;
|
|
4
|
+
lazyMaxPaths: number;
|
|
5
|
+
lazyBatchSize: number;
|
|
6
|
+
lazyMaxMs: number;
|
|
7
|
+
payloadMode: 'compact' | 'full';
|
|
8
|
+
persistLifecycleProcessMetadata: boolean;
|
|
9
|
+
parityWarmup: boolean;
|
|
10
|
+
parityWarmupMaxParallel: number;
|
|
11
|
+
paritySeedCacheIdleMs: number;
|
|
12
|
+
paritySeedCacheMaxEntries: number;
|
|
13
|
+
parityCacheMaxEntries: number;
|
|
14
|
+
}
|
|
15
|
+
export type ConfigSourceMap = Record<keyof UnityConfig, 'cli' | 'config_file' | 'default'>;
|
|
16
|
+
export interface ResolvedUnityConfig {
|
|
17
|
+
config: UnityConfig;
|
|
18
|
+
configSource: ConfigSourceMap;
|
|
19
|
+
}
|
|
20
|
+
export declare function resolveUnityConfig(cliArgs?: Partial<UnityConfig>, configPath?: string): ResolvedUnityConfig;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
const DEFAULTS = {
|
|
4
|
+
maxSyntheticEdgesPerClass: 12,
|
|
5
|
+
maxSyntheticEdgesTotal: 256,
|
|
6
|
+
lazyMaxPaths: 120,
|
|
7
|
+
lazyBatchSize: 30,
|
|
8
|
+
lazyMaxMs: 5000,
|
|
9
|
+
payloadMode: 'compact',
|
|
10
|
+
persistLifecycleProcessMetadata: false,
|
|
11
|
+
parityWarmup: false,
|
|
12
|
+
parityWarmupMaxParallel: 4,
|
|
13
|
+
paritySeedCacheIdleMs: 60000,
|
|
14
|
+
paritySeedCacheMaxEntries: 100,
|
|
15
|
+
parityCacheMaxEntries: 500,
|
|
16
|
+
};
|
|
17
|
+
export function resolveUnityConfig(cliArgs, configPath) {
|
|
18
|
+
let fileValues = {};
|
|
19
|
+
try {
|
|
20
|
+
const path = configPath ?? join(process.cwd(), '.gitnexus', 'config.json');
|
|
21
|
+
const raw = JSON.parse(readFileSync(path, 'utf-8'));
|
|
22
|
+
if (raw?.unity && typeof raw.unity === 'object') {
|
|
23
|
+
fileValues = raw.unity;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
// missing or invalid config file — skip
|
|
28
|
+
}
|
|
29
|
+
const config = {};
|
|
30
|
+
const configSource = {};
|
|
31
|
+
for (const key of Object.keys(DEFAULTS)) {
|
|
32
|
+
if (cliArgs?.[key] !== undefined) {
|
|
33
|
+
config[key] = cliArgs[key];
|
|
34
|
+
configSource[key] = 'cli';
|
|
35
|
+
}
|
|
36
|
+
else if (fileValues[key] !== undefined) {
|
|
37
|
+
config[key] = fileValues[key];
|
|
38
|
+
configSource[key] = 'config_file';
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
config[key] = DEFAULTS[key];
|
|
42
|
+
configSource[key] = 'default';
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return { config, configSource };
|
|
46
|
+
}
|
|
@@ -25,7 +25,7 @@ export type NodeProperties = {
|
|
|
25
25
|
parameterCount?: number;
|
|
26
26
|
returnType?: string;
|
|
27
27
|
};
|
|
28
|
-
export type RelationshipType = 'CONTAINS' | 'CALLS' | 'INHERITS' | 'OVERRIDES' | 'IMPORTS' | 'USES' | 'DEFINES' | 'DECORATES' | 'IMPLEMENTS' | 'EXTENDS' | 'HAS_METHOD' | 'MEMBER_OF' | 'STEP_IN_PROCESS' | 'UNITY_COMPONENT_IN' | 'UNITY_COMPONENT_INSTANCE' | 'UNITY_RESOURCE_SUMMARY' | 'UNITY_SERIALIZED_TYPE_IN';
|
|
28
|
+
export type RelationshipType = 'CONTAINS' | 'CALLS' | 'INHERITS' | 'OVERRIDES' | 'IMPORTS' | 'USES' | 'DEFINES' | 'DECORATES' | 'IMPLEMENTS' | 'EXTENDS' | 'HAS_METHOD' | 'MEMBER_OF' | 'STEP_IN_PROCESS' | 'UNITY_COMPONENT_IN' | 'UNITY_COMPONENT_INSTANCE' | 'UNITY_RESOURCE_SUMMARY' | 'UNITY_SERIALIZED_TYPE_IN' | 'UNITY_ASSET_GUID_REF' | 'UNITY_GRAPH_NODE_SCRIPT_REF';
|
|
29
29
|
export interface GraphNode {
|
|
30
30
|
id: string;
|
|
31
31
|
label: NodeLabel;
|
|
@@ -9,7 +9,9 @@ import { processCommunities } from './community-processor.js';
|
|
|
9
9
|
import { processProcesses } from './process-processor.js';
|
|
10
10
|
import { processUnityResources } from './unity-resource-processor.js';
|
|
11
11
|
import { applyUnityLifecycleSyntheticCalls } from './unity-lifecycle-synthetic-calls.js';
|
|
12
|
-
import {
|
|
12
|
+
import { applyUnityRuntimeBindingRules } from './unity-runtime-binding-rules.js';
|
|
13
|
+
import { resolveUnityConfig } from '../config/unity-config.js';
|
|
14
|
+
import { loadAnalyzeRules } from '../../mcp/local/runtime-claim-rule-registry.js';
|
|
13
15
|
import { createResolutionContext } from './resolution-context.js';
|
|
14
16
|
import { createASTCache } from './ast-cache.js';
|
|
15
17
|
import { walkRepositoryPaths, readFileContents, walkUnityResourcePaths } from './filesystem-walker.js';
|
|
@@ -290,6 +292,7 @@ export const runPipelineFromRepo = async (repoPath, onProgress, options) => {
|
|
|
290
292
|
importCtx.normalizedFileList = null;
|
|
291
293
|
let communityResult;
|
|
292
294
|
let processResult;
|
|
295
|
+
let unityResult;
|
|
293
296
|
if (!options?.skipGraphPhases) {
|
|
294
297
|
// ── Phase 4.5: Method Resolution Order ──────────────────────────────
|
|
295
298
|
onProgress({
|
|
@@ -344,14 +347,43 @@ export const runPipelineFromRepo = async (repoPath, onProgress, options) => {
|
|
|
344
347
|
reason: 'leiden-algorithm',
|
|
345
348
|
});
|
|
346
349
|
});
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
+
// ── Phase 5.5: Unity resource bindings (before lifecycle injection) ─
|
|
351
|
+
onProgress({
|
|
352
|
+
phase: 'enriching',
|
|
353
|
+
percent: 93,
|
|
354
|
+
message: 'Extracting Unity resource bindings...',
|
|
355
|
+
stats: { filesProcessed: totalFiles, totalFiles, nodesCreated: graph.nodeCount },
|
|
356
|
+
});
|
|
357
|
+
unityResult = await processUnityResources(graph, { repoPath, scopedPaths: unityScopedPaths });
|
|
358
|
+
// ── Phase 5.6: Unity lifecycle synthetic calls (auto-detect) ────────
|
|
359
|
+
const isUnityProject = allPaths.some(p => p.startsWith('Assets/') && p.endsWith('.cs'));
|
|
360
|
+
const unityConfig = resolveUnityConfig();
|
|
361
|
+
const persistLifecycleProcessMetadata = unityConfig.config.persistLifecycleProcessMetadata ?? false;
|
|
362
|
+
const unityLifecycleSyntheticResult = isUnityProject
|
|
363
|
+
? applyUnityLifecycleSyntheticCalls(graph, {
|
|
364
|
+
maxSyntheticEdgesPerClass: unityConfig.config.maxSyntheticEdgesPerClass,
|
|
365
|
+
maxSyntheticEdgesTotal: unityConfig.config.maxSyntheticEdgesTotal,
|
|
366
|
+
})
|
|
367
|
+
: { syntheticEdgeCount: 0, lifecycleEdgeCount: 0, loaderEdgeCount: 0, hostCount: 0, rejectedHostCount: 0 };
|
|
350
368
|
const syntheticEdgeDetail = unityLifecycleSyntheticResult.syntheticEdgeCount > 0
|
|
351
369
|
? ` (Unity synthetic edges: ${unityLifecycleSyntheticResult.syntheticEdgeCount})`
|
|
352
370
|
: '';
|
|
353
|
-
if (isDev &&
|
|
354
|
-
console.log(`[UnityLifecycle]
|
|
371
|
+
if (isDev && isUnityProject) {
|
|
372
|
+
console.log(`[UnityLifecycle] auto-detected hosts=${unityLifecycleSyntheticResult.hostCount} syntheticEdges=${unityLifecycleSyntheticResult.syntheticEdgeCount} rejectedHosts=${unityLifecycleSyntheticResult.rejectedHostCount}`);
|
|
373
|
+
}
|
|
374
|
+
// Phase 5.7: rule-driven binding injection (Phase 3)
|
|
375
|
+
try {
|
|
376
|
+
const analyzeRules = await loadAnalyzeRules(repoPath);
|
|
377
|
+
if (analyzeRules.length > 0) {
|
|
378
|
+
const bindingResult = applyUnityRuntimeBindingRules(graph, analyzeRules, unityConfig.config);
|
|
379
|
+
if (isDev && bindingResult.edgesInjected > 0) {
|
|
380
|
+
console.log(`[UnityRuleBinding] injected ${bindingResult.edgesInjected} edges from ${analyzeRules.length} rule(s)`);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
catch (err) {
|
|
385
|
+
// rule catalog missing or invalid — skip silently
|
|
386
|
+
console.warn(`[UnityRuleBinding] failed to load or apply analyze rules: ${err instanceof Error ? err.message : String(err)}`);
|
|
355
387
|
}
|
|
356
388
|
// ── Phase 6: Processes ─────────────────────────────────────────────
|
|
357
389
|
onProgress({
|
|
@@ -414,13 +446,6 @@ export const runPipelineFromRepo = async (repoPath, onProgress, options) => {
|
|
|
414
446
|
});
|
|
415
447
|
});
|
|
416
448
|
}
|
|
417
|
-
onProgress({
|
|
418
|
-
phase: 'enriching',
|
|
419
|
-
percent: 99,
|
|
420
|
-
message: 'Extracting Unity resource bindings...',
|
|
421
|
-
stats: { filesProcessed: totalFiles, totalFiles, nodesCreated: graph.nodeCount },
|
|
422
|
-
});
|
|
423
|
-
const unityResult = await processUnityResources(graph, { repoPath, scopedPaths: unityScopedPaths });
|
|
424
449
|
onProgress({
|
|
425
450
|
phase: 'complete',
|
|
426
451
|
percent: 100,
|
|
@@ -4,14 +4,12 @@ export interface UnityLifecycleSyntheticConfig {
|
|
|
4
4
|
maxSyntheticEdgesPerClass: number;
|
|
5
5
|
maxSyntheticEdgesTotal: number;
|
|
6
6
|
lifecycleEdgeConfidence: number;
|
|
7
|
-
loaderEdgeConfidence: number;
|
|
8
7
|
}
|
|
9
8
|
export declare const DEFAULT_UNITY_LIFECYCLE_SYNTHETIC_CONFIG: UnityLifecycleSyntheticConfig;
|
|
10
9
|
export interface UnityLifecycleHost {
|
|
11
10
|
classNode: GraphNode;
|
|
12
11
|
baseType: 'MonoBehaviour' | 'ScriptableObject';
|
|
13
12
|
lifecycleCallbacks: GraphNode[];
|
|
14
|
-
loaderAnchors: GraphNode[];
|
|
15
13
|
methods: GraphNode[];
|
|
16
14
|
}
|
|
17
15
|
export interface UnityLifecycleSyntheticResult {
|