@veewo/gitnexus 1.5.5 → 1.5.7
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/analyze-runner.d.ts +0 -2
- package/dist/benchmark/analyze-runner.js +0 -6
- package/dist/benchmark/analyze-runner.test.js +1 -10
- package/dist/benchmark/runner.d.ts +0 -2
- package/dist/benchmark/runner.js +0 -2
- package/dist/benchmark/u2-e2e/neonspark-full-e2e.js +0 -11
- package/dist/benchmark/u2-performance-sampler.js +3 -16
- package/dist/cli/analyze-options.d.ts +19 -6
- package/dist/cli/analyze-options.js +76 -71
- package/dist/cli/analyze-options.test.js +78 -73
- package/dist/cli/analyze.d.ts +2 -4
- package/dist/cli/analyze.js +13 -25
- package/dist/cli/analyze.test.js +9 -15
- package/dist/cli/benchmark-agent-context.d.ts +0 -2
- package/dist/cli/benchmark-agent-context.js +0 -2
- package/dist/cli/benchmark-agent-safe-query-context.d.ts +0 -2
- package/dist/cli/benchmark-agent-safe-query-context.js +0 -2
- package/dist/cli/benchmark-unity.d.ts +0 -2
- package/dist/cli/benchmark-unity.js +0 -2
- package/dist/cli/clean.d.ts +2 -3
- package/dist/cli/clean.js +4 -25
- package/dist/cli/index.js +1 -10
- package/dist/core/ingestion/pipeline.js +1 -1
- package/dist/storage/repo-manager.d.ts +1 -0
- package/package.json +2 -2
- package/skills/gitnexus-cli.md +62 -38
- package/vendor/node_modules/node-addon-api/node_addon_api.Makefile +6 -0
- package/vendor/node_modules/node-addon-api/node_addon_api.target.mk +122 -0
- package/vendor/node_modules/node-addon-api/node_addon_api_except.target.mk +126 -0
- package/vendor/node_modules/node-addon-api/node_addon_api_except_all.target.mk +122 -0
- package/vendor/node_modules/node-addon-api/node_addon_api_maybe.target.mk +122 -0
- package/vendor/tree-sitter-dart/build/Release/.deps/node_modules/node-addon-api/node_addon_api_except.stamp.d +1 -0
- package/vendor/tree-sitter-dart/build/node_modules/node-addon-api/node_addon_api_except.stamp +0 -0
- package/vendor/tree-sitter-proto/build/Release/.deps/node_modules/node-addon-api/node_addon_api_except.stamp.d +1 -0
- package/vendor/tree-sitter-proto/build/node_modules/node-addon-api/node_addon_api_except.stamp +0 -0
- package/dist/cli/scope-manifest-config.d.ts +0 -9
- package/dist/cli/scope-manifest-config.js +0 -37
- package/dist/cli/sync-manifest.d.ts +0 -27
- package/dist/cli/sync-manifest.js +0 -200
- package/dist/cli/sync-manifest.test.d.ts +0 -1
- package/dist/cli/sync-manifest.test.js +0 -88
|
@@ -21,12 +21,6 @@ export function buildAnalyzeArgs(repoPath, options) {
|
|
|
21
21
|
if (options.repoAlias) {
|
|
22
22
|
args.push('--repo-alias', options.repoAlias);
|
|
23
23
|
}
|
|
24
|
-
if (options.scopeManifest) {
|
|
25
|
-
args.push('--scope-manifest', options.scopeManifest);
|
|
26
|
-
}
|
|
27
|
-
for (const prefix of options.scopePrefix || []) {
|
|
28
|
-
args.push('--scope-prefix', prefix);
|
|
29
|
-
}
|
|
30
24
|
return args;
|
|
31
25
|
}
|
|
32
26
|
export async function runAnalyze(repoPath, options) {
|
|
@@ -11,12 +11,10 @@ Repository indexed successfully (42.3s)
|
|
|
11
11
|
assert.equal(parsed.nodes, 51172);
|
|
12
12
|
assert.equal(parsed.edges, 108578);
|
|
13
13
|
});
|
|
14
|
-
test('buildAnalyzeArgs forwards alias and
|
|
14
|
+
test('buildAnalyzeArgs forwards alias and extensions', () => {
|
|
15
15
|
const args = buildAnalyzeArgs('/repo/path', {
|
|
16
16
|
extensions: '.cs,.ts',
|
|
17
17
|
repoAlias: 'neonspark-v1-subset',
|
|
18
|
-
scopeManifest: '/tmp/scope-manifest.txt',
|
|
19
|
-
scopePrefix: ['Assets/NEON/Code', 'Packages/com.veewo.*'],
|
|
20
18
|
});
|
|
21
19
|
assert.deepEqual(args, [
|
|
22
20
|
'dist/cli/index.js',
|
|
@@ -27,18 +25,11 @@ test('buildAnalyzeArgs forwards alias and scope options', () => {
|
|
|
27
25
|
'/repo/path',
|
|
28
26
|
'--repo-alias',
|
|
29
27
|
'neonspark-v1-subset',
|
|
30
|
-
'--scope-manifest',
|
|
31
|
-
'/tmp/scope-manifest.txt',
|
|
32
|
-
'--scope-prefix',
|
|
33
|
-
'Assets/NEON/Code',
|
|
34
|
-
'--scope-prefix',
|
|
35
|
-
'Packages/com.veewo.*',
|
|
36
28
|
]);
|
|
37
29
|
});
|
|
38
30
|
test('buildAnalyzeArgs omits --extensions when not explicitly provided', () => {
|
|
39
31
|
const args = buildAnalyzeArgs('/repo/path', {
|
|
40
32
|
repoAlias: 'neonspark-v1-subset',
|
|
41
|
-
scopeManifest: '/tmp/scope-manifest.txt',
|
|
42
33
|
});
|
|
43
34
|
assert.equal(args.includes('--extensions'), false);
|
|
44
35
|
});
|
package/dist/benchmark/runner.js
CHANGED
|
@@ -198,8 +198,6 @@ export async function runBenchmark(ds, options) {
|
|
|
198
198
|
const analyze = await runAnalyze(path.resolve(options.targetPath), {
|
|
199
199
|
extensions: options.extensions,
|
|
200
200
|
repoAlias: options.repoAlias,
|
|
201
|
-
scopeManifest: options.scopeManifest,
|
|
202
|
-
scopePrefix: options.scopePrefix,
|
|
203
201
|
});
|
|
204
202
|
analyzeSummary = parseAnalyzeSummary(`${analyze.stdout}\n${analyze.stderr}`);
|
|
205
203
|
}
|
|
@@ -79,13 +79,6 @@ async function execCommand(command, args, cwd) {
|
|
|
79
79
|
});
|
|
80
80
|
});
|
|
81
81
|
}
|
|
82
|
-
function scopePrefixArgs(prefixes) {
|
|
83
|
-
const out = [];
|
|
84
|
-
for (const prefix of prefixes) {
|
|
85
|
-
out.push('--scope-prefix', prefix);
|
|
86
|
-
}
|
|
87
|
-
return out;
|
|
88
|
-
}
|
|
89
82
|
async function runRequiredCommand(command, args, cwd) {
|
|
90
83
|
const result = await execCommand(command, args, cwd);
|
|
91
84
|
if (result.code !== 0) {
|
|
@@ -282,7 +275,6 @@ export async function runNeonsparkU2E2E(options) {
|
|
|
282
275
|
},
|
|
283
276
|
'pipeline-profile': async () => {
|
|
284
277
|
const reportPath = path.join(reportDir, 'pipeline-profile.json');
|
|
285
|
-
const scopeArgs = scopePrefixArgs(config.scope.scriptPrefixes || []);
|
|
286
278
|
await runRequiredCommand('npm', [
|
|
287
279
|
'--prefix',
|
|
288
280
|
'gitnexus',
|
|
@@ -295,14 +287,12 @@ export async function runNeonsparkU2E2E(options) {
|
|
|
295
287
|
'1',
|
|
296
288
|
'--report',
|
|
297
289
|
reportPath,
|
|
298
|
-
...scopeArgs,
|
|
299
290
|
], repoRoot);
|
|
300
291
|
const raw = await fs.readFile(reportPath, 'utf-8');
|
|
301
292
|
state.pipelineProfile = JSON.parse(raw);
|
|
302
293
|
return state.pipelineProfile;
|
|
303
294
|
},
|
|
304
295
|
analyze: async () => {
|
|
305
|
-
const scopeArgs = scopePrefixArgs(config.scope.scriptPrefixes || []);
|
|
306
296
|
const analyze = await runRequiredCommand('/usr/bin/time', [
|
|
307
297
|
'-p',
|
|
308
298
|
'node',
|
|
@@ -313,7 +303,6 @@ export async function runNeonsparkU2E2E(options) {
|
|
|
313
303
|
'.cs',
|
|
314
304
|
'--repo-alias',
|
|
315
305
|
repoAlias,
|
|
316
|
-
...scopeArgs,
|
|
317
306
|
config.targetPath,
|
|
318
307
|
], gitnexusRoot);
|
|
319
308
|
const logPath = path.join(reportDir, 'analyze.log');
|
|
@@ -2,7 +2,6 @@ import fs from 'node:fs/promises';
|
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { performance } from 'node:perf_hooks';
|
|
4
4
|
import { runPipelineFromRepo } from '../core/ingestion/pipeline.js';
|
|
5
|
-
import { resolveAnalyzeScopeRules } from '../cli/analyze-options.js';
|
|
6
5
|
export function computeNumericStats(values) {
|
|
7
6
|
if (values.length === 0) {
|
|
8
7
|
return { mean: 0, median: 0, min: 0, max: 0, spread: 0 };
|
|
@@ -96,32 +95,22 @@ function parseArgs(argv) {
|
|
|
96
95
|
const targetPath = get('--target-path');
|
|
97
96
|
const reportPath = get('--report');
|
|
98
97
|
const thresholdsPath = get('--thresholds');
|
|
99
|
-
const scopeManifest = get('--scope-manifest');
|
|
100
98
|
const runs = Number(get('--runs') || '3');
|
|
101
|
-
const scopePrefix = [];
|
|
102
|
-
for (let i = 0; i < argv.length; i += 1) {
|
|
103
|
-
if (argv[i] === '--scope-prefix' && i + 1 < argv.length) {
|
|
104
|
-
scopePrefix.push(argv[i + 1]);
|
|
105
|
-
i += 1;
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
99
|
if (!targetPath)
|
|
109
100
|
throw new Error('Missing required arg: --target-path <path>');
|
|
110
101
|
if (!reportPath)
|
|
111
102
|
throw new Error('Missing required arg: --report <path>');
|
|
112
103
|
if (!Number.isFinite(runs) || runs <= 0)
|
|
113
104
|
throw new Error('Invalid --runs, must be positive integer');
|
|
114
|
-
return { targetPath: path.resolve(targetPath), runs: Math.floor(runs), reportPath: path.resolve(reportPath), thresholdsPath: thresholdsPath ? path.resolve(thresholdsPath) : undefined
|
|
105
|
+
return { targetPath: path.resolve(targetPath), runs: Math.floor(runs), reportPath: path.resolve(reportPath), thresholdsPath: thresholdsPath ? path.resolve(thresholdsPath) : undefined };
|
|
115
106
|
}
|
|
116
107
|
function round1(value) {
|
|
117
108
|
return Number(value.toFixed(1));
|
|
118
109
|
}
|
|
119
110
|
async function main() {
|
|
120
111
|
const args = parseArgs(process.argv.slice(2));
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
scopePrefix: args.scopePrefix,
|
|
124
|
-
});
|
|
112
|
+
// No scope rules — full repo scan
|
|
113
|
+
const scopeRules = [];
|
|
125
114
|
const runs = [];
|
|
126
115
|
for (let run = 1; run <= args.runs; run += 1) {
|
|
127
116
|
console.log(`[u2-sampler] run ${run}/${args.runs} ...`);
|
|
@@ -145,8 +134,6 @@ async function main() {
|
|
|
145
134
|
targetPath: args.targetPath,
|
|
146
135
|
runs: args.runs,
|
|
147
136
|
scope: {
|
|
148
|
-
scopeManifest: args.scopeManifest || null,
|
|
149
|
-
scopePrefix: args.scopePrefix,
|
|
150
137
|
scopeRuleCount: scopeRules.length,
|
|
151
138
|
},
|
|
152
139
|
samples: runs,
|
|
@@ -1,26 +1,39 @@
|
|
|
1
|
-
export interface AnalyzeScopeOptions {
|
|
2
|
-
scopeManifest?: string;
|
|
3
|
-
scopePrefix?: string[] | string;
|
|
4
|
-
}
|
|
5
1
|
export interface StoredAnalyzeOptions {
|
|
6
2
|
includeExtensions?: string[];
|
|
7
3
|
scopeRules?: string[];
|
|
8
4
|
repoAlias?: string;
|
|
9
5
|
embeddings?: boolean;
|
|
6
|
+
csharpDefineCsproj?: string;
|
|
10
7
|
}
|
|
11
|
-
export interface ResolveAnalyzeOptionsInput
|
|
8
|
+
export interface ResolveAnalyzeOptionsInput {
|
|
12
9
|
extensions?: string;
|
|
10
|
+
scope?: string;
|
|
13
11
|
repoAlias?: string;
|
|
14
12
|
embeddings?: boolean;
|
|
15
13
|
reuseOptions?: boolean;
|
|
14
|
+
csharpDefineCsproj?: string;
|
|
16
15
|
}
|
|
17
16
|
export interface EffectiveAnalyzeOptions {
|
|
18
17
|
includeExtensions: string[];
|
|
19
18
|
scopeRules: string[];
|
|
20
19
|
repoAlias?: string;
|
|
21
20
|
embeddings: boolean;
|
|
21
|
+
csharpDefineCsproj?: string;
|
|
22
22
|
}
|
|
23
23
|
export declare function parseExtensionList(rawExtensions?: string): string[];
|
|
24
|
+
/** Parse comma-separated scope rules (e.g. "Assets/,Packages/com.veewo.*"). */
|
|
25
|
+
export declare function parseScopeList(rawScope?: string): string[];
|
|
24
26
|
export declare function normalizeRepoAlias(repoAlias?: string): string | undefined;
|
|
25
|
-
export
|
|
27
|
+
export interface ValidatedStoredOptions {
|
|
28
|
+
includeExtensions: string[];
|
|
29
|
+
scopeRules: string[];
|
|
30
|
+
repoAlias?: string;
|
|
31
|
+
embeddings: boolean;
|
|
32
|
+
csharpDefineCsproj?: string;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Validate stored options from meta.json.analyzeOptions before reusing them.
|
|
36
|
+
* Invalid fields are filtered out or set to undefined, with console.warn output.
|
|
37
|
+
*/
|
|
38
|
+
export declare function validateStoredOptions(stored: StoredAnalyzeOptions | undefined, repoPath: string): Promise<ValidatedStoredOptions>;
|
|
26
39
|
export declare function resolveEffectiveAnalyzeOptions(options?: ResolveAnalyzeOptionsInput, stored?: StoredAnalyzeOptions): Promise<EffectiveAnalyzeOptions>;
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import fs from 'node:fs/promises';
|
|
2
|
-
import path from 'node:path';
|
|
3
2
|
import { normalizeScopeRules } from '../core/ingestion/scope-filter.js';
|
|
4
|
-
import { parseScopeManifestConfig } from './scope-manifest-config.js';
|
|
5
3
|
const REPO_ALIAS_REGEX = /^[a-zA-Z0-9._-]{3,64}$/;
|
|
6
4
|
export function parseExtensionList(rawExtensions) {
|
|
7
5
|
return (rawExtensions || '')
|
|
@@ -10,6 +8,16 @@ export function parseExtensionList(rawExtensions) {
|
|
|
10
8
|
.filter(Boolean)
|
|
11
9
|
.map((ext) => (ext.startsWith('.') ? ext : `.${ext}`));
|
|
12
10
|
}
|
|
11
|
+
/** Parse comma-separated scope rules (e.g. "Assets/,Packages/com.veewo.*"). */
|
|
12
|
+
export function parseScopeList(rawScope) {
|
|
13
|
+
if (!rawScope)
|
|
14
|
+
return [];
|
|
15
|
+
const rules = rawScope
|
|
16
|
+
.split(',')
|
|
17
|
+
.map((rule) => rule.trim())
|
|
18
|
+
.filter(Boolean);
|
|
19
|
+
return normalizeScopeRules(rules);
|
|
20
|
+
}
|
|
13
21
|
export function normalizeRepoAlias(repoAlias) {
|
|
14
22
|
if (!repoAlias)
|
|
15
23
|
return undefined;
|
|
@@ -21,95 +29,92 @@ export function normalizeRepoAlias(repoAlias) {
|
|
|
21
29
|
}
|
|
22
30
|
return normalized;
|
|
23
31
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
+
/**
|
|
33
|
+
* Validate stored options from meta.json.analyzeOptions before reusing them.
|
|
34
|
+
* Invalid fields are filtered out or set to undefined, with console.warn output.
|
|
35
|
+
*/
|
|
36
|
+
export async function validateStoredOptions(stored, repoPath) {
|
|
37
|
+
if (!stored) {
|
|
38
|
+
return { includeExtensions: [], scopeRules: [], repoAlias: undefined, embeddings: false, csharpDefineCsproj: undefined };
|
|
39
|
+
}
|
|
40
|
+
// Validate repoAlias
|
|
41
|
+
let repoAlias;
|
|
42
|
+
if (stored.repoAlias) {
|
|
43
|
+
const trimmed = stored.repoAlias.trim();
|
|
44
|
+
if (trimmed && REPO_ALIAS_REGEX.test(trimmed)) {
|
|
45
|
+
repoAlias = trimmed;
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
console.warn(` Warning: stored repoAlias "${stored.repoAlias}" is invalid, resetting to undefined.`);
|
|
32
49
|
}
|
|
33
50
|
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
51
|
+
// Validate includeExtensions (must start with '.')
|
|
52
|
+
let includeExtensions = [];
|
|
53
|
+
if (stored.includeExtensions) {
|
|
54
|
+
const valid = [];
|
|
55
|
+
for (const ext of stored.includeExtensions) {
|
|
56
|
+
if (typeof ext === 'string' && ext.startsWith('.')) {
|
|
57
|
+
valid.push(ext);
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
console.warn(` Warning: stored includeExtensions entry "${ext}" does not start with '.', filtering out.`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
includeExtensions = valid;
|
|
64
|
+
}
|
|
65
|
+
// Validate scopeRules (filter empty/whitespace-only)
|
|
66
|
+
let scopeRules = [];
|
|
67
|
+
if (stored.scopeRules) {
|
|
68
|
+
scopeRules = stored.scopeRules.filter((rule) => typeof rule === 'string' && rule.trim().length > 0);
|
|
69
|
+
}
|
|
70
|
+
// Validate csharpDefineCsproj (file must exist)
|
|
71
|
+
let csharpDefineCsproj;
|
|
72
|
+
if (stored.csharpDefineCsproj) {
|
|
73
|
+
try {
|
|
74
|
+
await fs.stat(stored.csharpDefineCsproj);
|
|
75
|
+
csharpDefineCsproj = stored.csharpDefineCsproj;
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
console.warn(` Warning: stored csharpDefineCsproj "${stored.csharpDefineCsproj}" not found on disk, resetting to undefined.`);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return {
|
|
82
|
+
includeExtensions,
|
|
83
|
+
scopeRules,
|
|
84
|
+
repoAlias,
|
|
85
|
+
embeddings: Boolean(stored.embeddings),
|
|
86
|
+
csharpDefineCsproj,
|
|
87
|
+
};
|
|
42
88
|
}
|
|
43
89
|
export async function resolveEffectiveAnalyzeOptions(options, stored) {
|
|
44
|
-
const manifestConfig = options?.scopeManifest
|
|
45
|
-
? await readScopeManifestConfig(path.resolve(options.scopeManifest))
|
|
46
|
-
: undefined;
|
|
47
90
|
const includeExtensionsFromCli = parseExtensionList(options?.extensions);
|
|
48
|
-
const scopeRulesFromCli =
|
|
91
|
+
const scopeRulesFromCli = parseScopeList(options?.scope);
|
|
49
92
|
const repoAliasFromCli = normalizeRepoAlias(options?.repoAlias);
|
|
50
|
-
const manifestExtensions = manifestConfig?.directives.extensions;
|
|
51
|
-
const manifestRepoAlias = manifestConfig?.directives.repoAlias;
|
|
52
|
-
const manifestEmbeddings = manifestConfig?.directives.embeddings;
|
|
53
93
|
const hasCliExtensions = options?.extensions !== undefined;
|
|
54
|
-
const hasCliScope =
|
|
94
|
+
const hasCliScope = options?.scope !== undefined;
|
|
55
95
|
const hasCliRepoAlias = options?.repoAlias !== undefined;
|
|
96
|
+
const hasCliCsproj = options?.csharpDefineCsproj !== undefined;
|
|
56
97
|
const canReuse = options?.reuseOptions !== false;
|
|
57
98
|
const includeExtensions = hasCliExtensions
|
|
58
99
|
? includeExtensionsFromCli
|
|
59
|
-
: (
|
|
60
|
-
? parseExtensionList(manifestExtensions)
|
|
61
|
-
: (canReuse ? (stored?.includeExtensions || []) : []));
|
|
100
|
+
: (canReuse ? (stored?.includeExtensions || []) : []);
|
|
62
101
|
const scopeRules = hasCliScope
|
|
63
102
|
? scopeRulesFromCli
|
|
64
103
|
: (canReuse ? (stored?.scopeRules || []) : []);
|
|
65
104
|
const repoAlias = hasCliRepoAlias
|
|
66
105
|
? repoAliasFromCli
|
|
67
|
-
: (
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
106
|
+
: (canReuse ? normalizeRepoAlias(stored?.repoAlias) : undefined);
|
|
107
|
+
const embeddings = options?.embeddings !== undefined
|
|
108
|
+
? options.embeddings
|
|
109
|
+
: (canReuse ? Boolean(stored?.embeddings) : false);
|
|
110
|
+
const csharpDefineCsproj = hasCliCsproj
|
|
111
|
+
? options.csharpDefineCsproj
|
|
112
|
+
: (canReuse ? stored?.csharpDefineCsproj : undefined);
|
|
74
113
|
return {
|
|
75
114
|
includeExtensions: [...includeExtensions],
|
|
76
115
|
scopeRules: [...scopeRules],
|
|
77
116
|
repoAlias,
|
|
78
117
|
embeddings,
|
|
118
|
+
csharpDefineCsproj,
|
|
79
119
|
};
|
|
80
120
|
}
|
|
81
|
-
function normalizeScopePrefixes(scopePrefix) {
|
|
82
|
-
const prefixesRaw = Array.isArray(scopePrefix)
|
|
83
|
-
? scopePrefix || []
|
|
84
|
-
: scopePrefix
|
|
85
|
-
? [scopePrefix]
|
|
86
|
-
: [];
|
|
87
|
-
return prefixesRaw
|
|
88
|
-
.map((prefix) => prefix.trim())
|
|
89
|
-
.filter(Boolean);
|
|
90
|
-
}
|
|
91
|
-
function resolveScopeRulesFromInput(manifestRules, prefixes, hasScopeManifest) {
|
|
92
|
-
const normalizedRules = normalizeScopeRules([...manifestRules, ...prefixes]);
|
|
93
|
-
if ((hasScopeManifest || prefixes.length > 0) && normalizedRules.length === 0) {
|
|
94
|
-
throw new Error('No valid scope rules provided.');
|
|
95
|
-
}
|
|
96
|
-
return normalizedRules;
|
|
97
|
-
}
|
|
98
|
-
async function readScopeManifestConfig(manifestPath) {
|
|
99
|
-
let content;
|
|
100
|
-
try {
|
|
101
|
-
content = await fs.readFile(manifestPath, 'utf-8');
|
|
102
|
-
}
|
|
103
|
-
catch {
|
|
104
|
-
throw new Error(`Scope manifest not found: ${manifestPath}`);
|
|
105
|
-
}
|
|
106
|
-
return parseScopeManifestConfig(content);
|
|
107
|
-
}
|
|
108
|
-
function parseManifestEmbeddings(raw) {
|
|
109
|
-
const normalized = raw.trim().toLowerCase();
|
|
110
|
-
if (normalized === 'true')
|
|
111
|
-
return true;
|
|
112
|
-
if (normalized === 'false')
|
|
113
|
-
return false;
|
|
114
|
-
throw new Error(`Invalid @embeddings directive value: ${raw}. Expected true or false.`);
|
|
115
|
-
}
|
|
@@ -3,8 +3,7 @@ import assert from 'node:assert/strict';
|
|
|
3
3
|
import fs from 'node:fs/promises';
|
|
4
4
|
import os from 'node:os';
|
|
5
5
|
import path from 'node:path';
|
|
6
|
-
import { normalizeRepoAlias, parseExtensionList,
|
|
7
|
-
import { parseScopeManifestConfig } from './scope-manifest-config.js';
|
|
6
|
+
import { normalizeRepoAlias, parseExtensionList, resolveEffectiveAnalyzeOptions, validateStoredOptions, } from './analyze-options.js';
|
|
8
7
|
test('parseExtensionList normalizes dot prefixes', () => {
|
|
9
8
|
const exts = parseExtensionList('cs,.ts, go ');
|
|
10
9
|
assert.deepEqual(exts, ['.cs', '.ts', '.go']);
|
|
@@ -15,26 +14,6 @@ test('normalizeRepoAlias validates format', () => {
|
|
|
15
14
|
assert.throws(() => normalizeRepoAlias('ab'), /repo alias/i);
|
|
16
15
|
assert.throws(() => normalizeRepoAlias('bad alias'), /repo alias/i);
|
|
17
16
|
});
|
|
18
|
-
test('resolveAnalyzeScopeRules combines manifest and repeated prefixes', async () => {
|
|
19
|
-
const tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), 'gitnexus-scope-test-'));
|
|
20
|
-
const manifestPath = path.join(tmpDir, 'scope.txt');
|
|
21
|
-
await fs.writeFile(manifestPath, '# comment\nAssets/NEON/Code\n\nPackages/com.veewo.*\n', 'utf-8');
|
|
22
|
-
const rules = await resolveAnalyzeScopeRules({
|
|
23
|
-
scopeManifest: manifestPath,
|
|
24
|
-
scopePrefix: ['Packages/com.neonspark.*'],
|
|
25
|
-
});
|
|
26
|
-
assert.deepEqual(rules, [
|
|
27
|
-
'Assets/NEON/Code',
|
|
28
|
-
'Packages/com.veewo.*',
|
|
29
|
-
'Packages/com.neonspark.*',
|
|
30
|
-
]);
|
|
31
|
-
});
|
|
32
|
-
test('resolveAnalyzeScopeRules fails when manifest has no usable rule', async () => {
|
|
33
|
-
const tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), 'gitnexus-scope-test-'));
|
|
34
|
-
const manifestPath = path.join(tmpDir, 'empty-scope.txt');
|
|
35
|
-
await fs.writeFile(manifestPath, '# only comments\n\n', 'utf-8');
|
|
36
|
-
await assert.rejects(resolveAnalyzeScopeRules({ scopeManifest: manifestPath }), /no valid scope rules/i);
|
|
37
|
-
});
|
|
38
17
|
test('resolveEffectiveAnalyzeOptions reuses stored settings when CLI omits them', async () => {
|
|
39
18
|
const resolved = await resolveEffectiveAnalyzeOptions({}, {
|
|
40
19
|
includeExtensions: ['.cs'],
|
|
@@ -53,16 +32,18 @@ test('resolveEffectiveAnalyzeOptions disables reuse via reuseOptions=false', asy
|
|
|
53
32
|
scopeRules: ['Assets/NEON/Code'],
|
|
54
33
|
repoAlias: 'neonspark-v1-subset',
|
|
55
34
|
embeddings: true,
|
|
35
|
+
csharpDefineCsproj: '/tmp/Assembly-CSharp.csproj',
|
|
56
36
|
});
|
|
57
37
|
assert.deepEqual(resolved.includeExtensions, []);
|
|
58
38
|
assert.deepEqual(resolved.scopeRules, []);
|
|
59
39
|
assert.equal(resolved.repoAlias, undefined);
|
|
60
40
|
assert.equal(resolved.embeddings, false);
|
|
41
|
+
assert.equal(resolved.csharpDefineCsproj, undefined);
|
|
61
42
|
});
|
|
62
43
|
test('resolveEffectiveAnalyzeOptions prefers explicit CLI values over stored settings', async () => {
|
|
63
44
|
const resolved = await resolveEffectiveAnalyzeOptions({
|
|
64
45
|
extensions: '.ts',
|
|
65
|
-
|
|
46
|
+
scope: 'src/',
|
|
66
47
|
repoAlias: 'new-alias',
|
|
67
48
|
embeddings: false,
|
|
68
49
|
}, {
|
|
@@ -76,59 +57,83 @@ test('resolveEffectiveAnalyzeOptions prefers explicit CLI values over stored set
|
|
|
76
57
|
assert.equal(resolved.repoAlias, 'new-alias');
|
|
77
58
|
assert.equal(resolved.embeddings, false);
|
|
78
59
|
});
|
|
79
|
-
test('resolveEffectiveAnalyzeOptions
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
includeExtensions: ['.ts'],
|
|
85
|
-
scopeRules: ['src'],
|
|
86
|
-
repoAlias: 'stored-alias',
|
|
87
|
-
embeddings: true,
|
|
88
|
-
});
|
|
89
|
-
assert.deepEqual(resolved.scopeRules, ['Assets']);
|
|
90
|
-
assert.deepEqual(resolved.includeExtensions, ['.cs', '.meta']);
|
|
91
|
-
assert.equal(resolved.repoAlias, 'neonspark-core');
|
|
60
|
+
test('resolveEffectiveAnalyzeOptions no stored uses defaults', async () => {
|
|
61
|
+
const resolved = await resolveEffectiveAnalyzeOptions({}, undefined);
|
|
62
|
+
assert.deepEqual(resolved.includeExtensions, []);
|
|
63
|
+
assert.deepEqual(resolved.scopeRules, []);
|
|
64
|
+
assert.equal(resolved.repoAlias, undefined);
|
|
92
65
|
assert.equal(resolved.embeddings, false);
|
|
66
|
+
assert.equal(resolved.csharpDefineCsproj, undefined);
|
|
93
67
|
});
|
|
94
|
-
test('resolveEffectiveAnalyzeOptions
|
|
95
|
-
const
|
|
96
|
-
|
|
97
|
-
await fs.writeFile(manifestPath, ['Assets/', '@extensions=.cs,.meta', '@repoAlias=manifest-alias', '@embeddings=false'].join('\n'), 'utf-8');
|
|
98
|
-
const resolved = await resolveEffectiveAnalyzeOptions({
|
|
99
|
-
scopeManifest: manifestPath,
|
|
100
|
-
extensions: '.ts',
|
|
101
|
-
}, {
|
|
102
|
-
includeExtensions: ['.js'],
|
|
103
|
-
scopeRules: ['tools'],
|
|
104
|
-
repoAlias: 'meta-alias',
|
|
105
|
-
embeddings: true,
|
|
68
|
+
test('resolveEffectiveAnalyzeOptions reuses stored scopeRules when CLI scope is omitted', async () => {
|
|
69
|
+
const resolved = await resolveEffectiveAnalyzeOptions({ extensions: '.ts' }, {
|
|
70
|
+
scopeRules: ['Assets/', 'Packages/com.veewo.*'],
|
|
106
71
|
});
|
|
107
|
-
assert.deepEqual(resolved.scopeRules, ['Assets']);
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
72
|
+
assert.deepEqual(resolved.scopeRules, ['Assets/', 'Packages/com.veewo.*']);
|
|
73
|
+
});
|
|
74
|
+
test('resolveEffectiveAnalyzeOptions parses --scope comma-separated rules', async () => {
|
|
75
|
+
const resolved = await resolveEffectiveAnalyzeOptions({ scope: 'Assets/,Packages/com.veewo.*' }, undefined);
|
|
76
|
+
assert.deepEqual(resolved.scopeRules, ['Assets/', 'Packages/com.veewo.*']);
|
|
77
|
+
});
|
|
78
|
+
test('resolveEffectiveAnalyzeOptions reuses stored csharpDefineCsproj', async () => {
|
|
79
|
+
const resolved = await resolveEffectiveAnalyzeOptions({}, {
|
|
80
|
+
csharpDefineCsproj: '/path/to/Assembly-CSharp.csproj',
|
|
81
|
+
});
|
|
82
|
+
assert.equal(resolved.csharpDefineCsproj, '/path/to/Assembly-CSharp.csproj');
|
|
111
83
|
});
|
|
112
|
-
test('resolveEffectiveAnalyzeOptions
|
|
113
|
-
const
|
|
114
|
-
|
|
115
|
-
await fs.writeFile(manifestPath, ['Assets/', '@foo=bar'].join('\n'), 'utf-8');
|
|
116
|
-
await assert.rejects(resolveEffectiveAnalyzeOptions({ scopeManifest: manifestPath }), /unknown manifest directive/i);
|
|
117
|
-
});
|
|
118
|
-
test('parseScopeManifestConfig splits scope rules and directives', () => {
|
|
119
|
-
const parsed = parseScopeManifestConfig([
|
|
120
|
-
'# comment',
|
|
121
|
-
'Assets/',
|
|
122
|
-
'Packages/com.veewo.*',
|
|
123
|
-
'',
|
|
124
|
-
'@extensions=.cs,.meta',
|
|
125
|
-
'@repoAlias=demo-repo',
|
|
126
|
-
'@embeddings=false',
|
|
127
|
-
].join('\n'));
|
|
128
|
-
assert.deepEqual(parsed.scopeRules, ['Assets', 'Packages/com.veewo.*']);
|
|
129
|
-
assert.deepEqual(parsed.directives, {
|
|
130
|
-
extensions: '.cs,.meta',
|
|
131
|
-
repoAlias: 'demo-repo',
|
|
132
|
-
embeddings: 'false',
|
|
84
|
+
test('resolveEffectiveAnalyzeOptions CLI csharpDefineCsproj overrides stored', async () => {
|
|
85
|
+
const resolved = await resolveEffectiveAnalyzeOptions({ csharpDefineCsproj: '/new/path.csproj' }, {
|
|
86
|
+
csharpDefineCsproj: '/old/path.csproj',
|
|
133
87
|
});
|
|
88
|
+
assert.equal(resolved.csharpDefineCsproj, '/new/path.csproj');
|
|
89
|
+
});
|
|
90
|
+
// ─── validateStoredOptions tests ────────────────────────────────────
|
|
91
|
+
test('validateStoredOptions returns defaults when stored is undefined', async () => {
|
|
92
|
+
const result = await validateStoredOptions(undefined, '/tmp');
|
|
93
|
+
assert.deepEqual(result.includeExtensions, []);
|
|
94
|
+
assert.deepEqual(result.scopeRules, []);
|
|
95
|
+
assert.equal(result.repoAlias, undefined);
|
|
96
|
+
assert.equal(result.embeddings, false);
|
|
97
|
+
assert.equal(result.csharpDefineCsproj, undefined);
|
|
98
|
+
});
|
|
99
|
+
test('validateStoredOptions passes valid options unchanged', async () => {
|
|
100
|
+
const tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), 'gitnexus-validate-'));
|
|
101
|
+
const csprojPath = path.join(tmpDir, 'Assembly-CSharp.csproj');
|
|
102
|
+
await fs.writeFile(csprojPath, '<Project />', 'utf-8');
|
|
103
|
+
const result = await validateStoredOptions({
|
|
104
|
+
includeExtensions: ['.cs', '.ts'],
|
|
105
|
+
scopeRules: ['Assets/'],
|
|
106
|
+
repoAlias: 'my-repo',
|
|
107
|
+
csharpDefineCsproj: csprojPath,
|
|
108
|
+
embeddings: true,
|
|
109
|
+
}, tmpDir);
|
|
110
|
+
assert.deepEqual(result.includeExtensions, ['.cs', '.ts']);
|
|
111
|
+
assert.deepEqual(result.scopeRules, ['Assets/']);
|
|
112
|
+
assert.equal(result.repoAlias, 'my-repo');
|
|
113
|
+
assert.equal(result.csharpDefineCsproj, csprojPath);
|
|
114
|
+
assert.equal(result.embeddings, true);
|
|
115
|
+
});
|
|
116
|
+
test('validateStoredOptions warns on invalid repoAlias and falls back', async () => {
|
|
117
|
+
const result = await validateStoredOptions({
|
|
118
|
+
repoAlias: 'bad alias!',
|
|
119
|
+
}, '/tmp');
|
|
120
|
+
assert.equal(result.repoAlias, undefined);
|
|
121
|
+
});
|
|
122
|
+
test('validateStoredOptions filters invalid extensions', async () => {
|
|
123
|
+
const result = await validateStoredOptions({
|
|
124
|
+
includeExtensions: ['cs', '.ts', '', '.go'],
|
|
125
|
+
}, '/tmp');
|
|
126
|
+
assert.deepEqual(result.includeExtensions, ['.ts', '.go']);
|
|
127
|
+
});
|
|
128
|
+
test('validateStoredOptions filters empty scopeRules', async () => {
|
|
129
|
+
const result = await validateStoredOptions({
|
|
130
|
+
scopeRules: ['', ' ', 'Assets/', 'Packages/com.veewo.*'],
|
|
131
|
+
}, '/tmp');
|
|
132
|
+
assert.deepEqual(result.scopeRules, ['Assets/', 'Packages/com.veewo.*']);
|
|
133
|
+
});
|
|
134
|
+
test('validateStoredOptions warns on missing csharpDefineCsproj file', async () => {
|
|
135
|
+
const result = await validateStoredOptions({
|
|
136
|
+
csharpDefineCsproj: '/nonexistent/path.csproj',
|
|
137
|
+
}, '/tmp');
|
|
138
|
+
assert.equal(result.csharpDefineCsproj, undefined);
|
|
134
139
|
});
|
package/dist/cli/analyze.d.ts
CHANGED
|
@@ -3,16 +3,13 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Indexes a repository and stores the knowledge graph in .gitnexus/
|
|
5
5
|
*/
|
|
6
|
-
import { type SyncManifestPolicy } from './sync-manifest.js';
|
|
7
6
|
export interface AnalyzeOptions {
|
|
8
7
|
force?: boolean;
|
|
9
8
|
embeddings?: boolean;
|
|
10
9
|
extensions?: string;
|
|
10
|
+
scope?: string;
|
|
11
11
|
repoAlias?: string;
|
|
12
12
|
csharpDefineCsproj?: string;
|
|
13
|
-
scopeManifest?: string;
|
|
14
|
-
scopePrefix?: string[];
|
|
15
|
-
syncManifestPolicy?: SyncManifestPolicy;
|
|
16
13
|
reuseOptions?: boolean;
|
|
17
14
|
skills?: boolean;
|
|
18
15
|
verbose?: boolean;
|
|
@@ -21,6 +18,7 @@ export declare const analyzeCommand: (inputPath?: string, options?: AnalyzeOptio
|
|
|
21
18
|
export declare function buildPipelineRunOptionsForAnalyze(resolvedOptions: {
|
|
22
19
|
includeExtensions: string[];
|
|
23
20
|
scopeRules: string[];
|
|
21
|
+
csharpDefineCsproj?: string;
|
|
24
22
|
}, options?: AnalyzeOptions): {
|
|
25
23
|
includeExtensions: string[];
|
|
26
24
|
scopeRules: string[];
|