gitnexus 1.6.11-rc.4 → 1.6.11-rc.6
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/README.md +26 -0
- package/dist/_shared/impact-risk.d.ts +35 -0
- package/dist/_shared/impact-risk.d.ts.map +1 -0
- package/dist/_shared/impact-risk.js +78 -0
- package/dist/_shared/impact-risk.js.map +1 -0
- package/dist/_shared/index.d.ts +2 -0
- package/dist/_shared/index.d.ts.map +1 -1
- package/dist/_shared/index.js +2 -0
- package/dist/_shared/index.js.map +1 -1
- package/dist/cli/analyze-config.d.ts +2 -0
- package/dist/cli/analyze-config.js +16 -0
- package/dist/cli/analyze-options.d.ts +4 -0
- package/dist/cli/analyze.d.ts +17 -0
- package/dist/cli/analyze.js +40 -7
- package/dist/cli/help-i18n.js +2 -0
- package/dist/cli/i18n/en.d.ts +2 -0
- package/dist/cli/i18n/en.js +2 -0
- package/dist/cli/i18n/resources.d.ts +4 -0
- package/dist/cli/i18n/zh-CN.d.ts +2 -0
- package/dist/cli/i18n/zh-CN.js +2 -0
- package/dist/cli/index.js +9 -2
- package/dist/cli/watch-queue.d.ts +41 -0
- package/dist/cli/watch-queue.js +184 -0
- package/dist/cli/watch.d.ts +20 -0
- package/dist/cli/watch.js +372 -0
- package/dist/config/ignore-service.d.ts +11 -0
- package/dist/config/ignore-service.js +41 -4
- package/dist/config/repo-control-file.d.ts +3 -0
- package/dist/config/repo-control-file.js +115 -0
- package/dist/core/ingestion/pipeline-phases/parse-impl.d.ts +2 -0
- package/dist/core/ingestion/pipeline-phases/parse-impl.js +7 -0
- package/dist/core/ingestion/pipeline-phases/parse.d.ts +2 -0
- package/dist/core/ingestion/pipeline.js +2 -1
- package/dist/core/run-analyze.d.ts +17 -0
- package/dist/core/run-analyze.js +72 -10
- package/dist/storage/parse-cache.js +13 -1
- package/dist/types/pipeline.d.ts +2 -0
- package/package.json +2 -1
- package/scripts/cross-platform-shard.ts +4 -2
- package/scripts/cross-platform-tests.ts +2 -1
- package/skills/gitnexus-cli.md +5 -1
package/README.md
CHANGED
|
@@ -234,6 +234,7 @@ Your AI agent gets **17 tools** (15 per-repo + 2 group) automatically:
|
|
|
234
234
|
gitnexus setup # Configure MCP for detected editors (one-time; use -c to select)
|
|
235
235
|
gitnexus uninstall # Preview removal of GitNexus MCP/skills/hooks (add --force to apply)
|
|
236
236
|
gitnexus analyze [path] # Index a repository (or update stale index)
|
|
237
|
+
gitnexus analyze [path] --watch # Watch local files and serialize incremental refreshes
|
|
237
238
|
gitnexus analyze --repair-fts # Fast path: rebuild/verify only FTS indexes on existing index data
|
|
238
239
|
gitnexus analyze --force # Full rebuild: re-parse + graph rebuild + FTS rebuild
|
|
239
240
|
gitnexus analyze --embeddings # Enable embedding generation (slower, better search)
|
|
@@ -282,6 +283,31 @@ gitnexus group status <name> # Check staleness of repos in a group
|
|
|
282
283
|
gitnexus group impact <name> --target <symbol> --repo <groupPath> # Cross-repo blast radius
|
|
283
284
|
```
|
|
284
285
|
|
|
286
|
+
`gitnexus analyze --watch` requires a Git repository. It performs an initial
|
|
287
|
+
analysis and then debounces scanner-admitted working-tree changes for 300 ms by
|
|
288
|
+
default into serialized incremental refreshes. Events arriving during a run
|
|
289
|
+
remain queued, and retryable failures retain the same batch with bounded
|
|
290
|
+
backoff. Invalid `.gitnexusrc` or ignore-file reloads pause ordinary refreshes
|
|
291
|
+
until the control file is fixed. Watch refreshes update only the graph: they
|
|
292
|
+
intentionally skip AGENTS.md / CLAUDE.md injection and standard skill
|
|
293
|
+
installation. Run a one-shot `gitnexus analyze` when those generated files need
|
|
294
|
+
updating. Stop watch mode with Ctrl+C.
|
|
295
|
+
|
|
296
|
+
Watch mode accepts `--debounce`, `--workers`, `--worker-timeout`,
|
|
297
|
+
`--max-file-size`, `--branch`, `--pdg`, `--name`, `--allow-duplicate-name`, and
|
|
298
|
+
`--verbose`. Explicit one-shot options such as `--force`, `--repair-fts`,
|
|
299
|
+
embedding flags, `--skills`, `--default-branch`, `--skip-agents-md`,
|
|
300
|
+
`--skip-skills`, `--no-stats`, `--self-commit`, `--index-only`, and `--skip-git`
|
|
301
|
+
are rejected. Unsupported defaults from `.gitnexusrc` are ignored with a warning.
|
|
302
|
+
|
|
303
|
+
POSIX requests clone-first copy-and-swap publication when the live index has no
|
|
304
|
+
orphan sidecars. Windows and sidecar fallback runs update in place: failures
|
|
305
|
+
known to occur before writes are retried, while a failure that may have mutated
|
|
306
|
+
the live index stops the watcher. Watch mode does not pull remotes. Running MCP
|
|
307
|
+
and `serve` processes periodically check for a newly published index and reopen
|
|
308
|
+
it without a restart. MCP checks are throttled to once every five seconds, so a
|
|
309
|
+
tool call before the next check can briefly use the previous index.
|
|
310
|
+
|
|
285
311
|
GraphQL contract matching is opt-in in the group's `group.yaml`:
|
|
286
312
|
|
|
287
313
|
```yaml
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export type ImpactRisk = 'LOW' | 'MEDIUM' | 'HIGH' | 'CRITICAL' | 'UNKNOWN';
|
|
2
|
+
export type ImpactRiskAxis = 'processes' | 'modules';
|
|
3
|
+
export type UnusedImpactRiskReason = 'file-nodes-have-no-process-or-community-membership' | 'enrichment-skipped' | 'enrichment-budget-exhausted' | 'enrichment-query-failed';
|
|
4
|
+
export interface UnusedImpactRiskAxis {
|
|
5
|
+
axis: ImpactRiskAxis;
|
|
6
|
+
reason: UnusedImpactRiskReason;
|
|
7
|
+
}
|
|
8
|
+
export interface ImpactRiskInput {
|
|
9
|
+
direction: 'upstream' | 'downstream';
|
|
10
|
+
directCount: number;
|
|
11
|
+
processCount: number;
|
|
12
|
+
moduleCount: number;
|
|
13
|
+
impactedCount: number;
|
|
14
|
+
unusedAxes?: readonly UnusedImpactRiskAxis[];
|
|
15
|
+
}
|
|
16
|
+
export interface ImpactRiskResult {
|
|
17
|
+
risk: ImpactRisk;
|
|
18
|
+
riskSharedAxes: ImpactRisk;
|
|
19
|
+
riskScale: {
|
|
20
|
+
comparableAcrossKinds: boolean;
|
|
21
|
+
unusedAxes: readonly UnusedImpactRiskAxis[];
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
/** Map walk outcomes to unused process/module axes so comparability matches what was sampled. */
|
|
25
|
+
export declare function unusedAxesForImpactWalk(input: {
|
|
26
|
+
isFileTarget: boolean;
|
|
27
|
+
skipEnrichment: boolean;
|
|
28
|
+
maxChunks: number;
|
|
29
|
+
processQueryFailed: boolean;
|
|
30
|
+
moduleQueryFailed: boolean;
|
|
31
|
+
/** When 0, a zero chunk budget is not an unused-axis event — there was nothing to enrich. */
|
|
32
|
+
impactedCount?: number;
|
|
33
|
+
}): UnusedImpactRiskAxis[];
|
|
34
|
+
export declare function scoreImpactRisk(input: ImpactRiskInput): ImpactRiskResult;
|
|
35
|
+
//# sourceMappingURL=impact-risk.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"impact-risk.d.ts","sourceRoot":"","sources":["../src/impact-risk.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,UAAU,GAAG,SAAS,CAAC;AAE5E,MAAM,MAAM,cAAc,GAAG,WAAW,GAAG,SAAS,CAAC;AAErD,MAAM,MAAM,sBAAsB,GAC9B,oDAAoD,GACpD,oBAAoB,GACpB,6BAA6B,GAC7B,yBAAyB,CAAC;AAE9B,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,cAAc,CAAC;IACrB,MAAM,EAAE,sBAAsB,CAAC;CAChC;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,UAAU,GAAG,YAAY,CAAC;IACrC,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,SAAS,oBAAoB,EAAE,CAAC;CAC9C;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,UAAU,CAAC;IACjB,cAAc,EAAE,UAAU,CAAC;IAC3B,SAAS,EAAE;QACT,qBAAqB,EAAE,OAAO,CAAC;QAC/B,UAAU,EAAE,SAAS,oBAAoB,EAAE,CAAC;KAC7C,CAAC;CACH;AA0CD,iGAAiG;AACjG,wBAAgB,uBAAuB,CAAC,KAAK,EAAE;IAC7C,YAAY,EAAE,OAAO,CAAC;IACtB,cAAc,EAAE,OAAO,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,iBAAiB,EAAE,OAAO,CAAC;IAC3B,6FAA6F;IAC7F,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,GAAG,oBAAoB,EAAE,CAiCzB;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,eAAe,GAAG,gBAAgB,CAWxE"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
function score(input) {
|
|
2
|
+
const { direction, directCount, processCount, moduleCount, impactedCount } = input;
|
|
3
|
+
if (direction === 'upstream' && impactedCount === 0)
|
|
4
|
+
return 'UNKNOWN';
|
|
5
|
+
if (directCount >= 30 || processCount >= 5 || moduleCount >= 5 || impactedCount >= 200) {
|
|
6
|
+
return 'CRITICAL';
|
|
7
|
+
}
|
|
8
|
+
if (directCount >= 15 || processCount >= 3 || moduleCount >= 3 || impactedCount >= 100) {
|
|
9
|
+
return 'HIGH';
|
|
10
|
+
}
|
|
11
|
+
if (directCount >= 5 || impactedCount >= 30)
|
|
12
|
+
return 'MEDIUM';
|
|
13
|
+
return 'LOW';
|
|
14
|
+
}
|
|
15
|
+
function countsWithUnusedAxesZeroed(input) {
|
|
16
|
+
let processCount = input.processCount;
|
|
17
|
+
let moduleCount = input.moduleCount;
|
|
18
|
+
for (const unused of input.unusedAxes ?? []) {
|
|
19
|
+
if (unused.axis === 'processes')
|
|
20
|
+
processCount = 0;
|
|
21
|
+
if (unused.axis === 'modules')
|
|
22
|
+
moduleCount = 0;
|
|
23
|
+
}
|
|
24
|
+
return {
|
|
25
|
+
direction: input.direction,
|
|
26
|
+
directCount: input.directCount,
|
|
27
|
+
processCount,
|
|
28
|
+
moduleCount,
|
|
29
|
+
impactedCount: input.impactedCount,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
/** Map walk outcomes to unused process/module axes so comparability matches what was sampled. */
|
|
33
|
+
export function unusedAxesForImpactWalk(input) {
|
|
34
|
+
if (input.isFileTarget) {
|
|
35
|
+
return [
|
|
36
|
+
{
|
|
37
|
+
axis: 'processes',
|
|
38
|
+
reason: 'file-nodes-have-no-process-or-community-membership',
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
axis: 'modules',
|
|
42
|
+
reason: 'file-nodes-have-no-process-or-community-membership',
|
|
43
|
+
},
|
|
44
|
+
];
|
|
45
|
+
}
|
|
46
|
+
if (input.skipEnrichment) {
|
|
47
|
+
return [
|
|
48
|
+
{ axis: 'processes', reason: 'enrichment-skipped' },
|
|
49
|
+
{ axis: 'modules', reason: 'enrichment-skipped' },
|
|
50
|
+
];
|
|
51
|
+
}
|
|
52
|
+
if (input.maxChunks === 0 && (input.impactedCount ?? 1) > 0) {
|
|
53
|
+
return [
|
|
54
|
+
{ axis: 'processes', reason: 'enrichment-budget-exhausted' },
|
|
55
|
+
{ axis: 'modules', reason: 'enrichment-budget-exhausted' },
|
|
56
|
+
];
|
|
57
|
+
}
|
|
58
|
+
const unused = [];
|
|
59
|
+
if (input.processQueryFailed) {
|
|
60
|
+
unused.push({ axis: 'processes', reason: 'enrichment-query-failed' });
|
|
61
|
+
}
|
|
62
|
+
if (input.moduleQueryFailed) {
|
|
63
|
+
unused.push({ axis: 'modules', reason: 'enrichment-query-failed' });
|
|
64
|
+
}
|
|
65
|
+
return unused;
|
|
66
|
+
}
|
|
67
|
+
export function scoreImpactRisk(input) {
|
|
68
|
+
const unusedAxes = input.unusedAxes ?? [];
|
|
69
|
+
return {
|
|
70
|
+
risk: score(countsWithUnusedAxesZeroed(input)),
|
|
71
|
+
riskSharedAxes: score({ ...input, processCount: 0, moduleCount: 0 }),
|
|
72
|
+
riskScale: {
|
|
73
|
+
comparableAcrossKinds: unusedAxes.length === 0,
|
|
74
|
+
unusedAxes,
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=impact-risk.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"impact-risk.js","sourceRoot":"","sources":["../src/impact-risk.ts"],"names":[],"mappings":"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"}
|
package/dist/_shared/index.d.ts
CHANGED
|
@@ -4,6 +4,8 @@ export type { NodeTableName, RelType } from './lbug/schema-constants.js';
|
|
|
4
4
|
export { SupportedLanguages } from './languages.js';
|
|
5
5
|
export { getLanguageFromFilename, getSyntaxLanguageFromFilename, isBladeTemplateFilename, } from './language-detection.js';
|
|
6
6
|
export type { MroStrategy } from './mro-strategy.js';
|
|
7
|
+
export { scoreImpactRisk, unusedAxesForImpactWalk } from './impact-risk.js';
|
|
8
|
+
export type { ImpactRisk, ImpactRiskAxis, ImpactRiskInput, ImpactRiskResult, UnusedImpactRiskAxis, UnusedImpactRiskReason, } from './impact-risk.js';
|
|
7
9
|
export type { PipelinePhase, PipelineProgress } from './pipeline.js';
|
|
8
10
|
export type { ParameterTypeClass, SymbolDefinition, TypeParameter, } from './scope-resolution/symbol-definition.js';
|
|
9
11
|
export type { ScopeId, DefId, ScopeKind, Range, Capture, CaptureMatch, BindingRef, ImportEdge, TypeRef, Scope, ResolutionEvidence, Resolution, Reference, ReferenceIndex, LookupParams, RegistryContributor, ParsedImport, ParsedTypeBinding, WorkspaceIndex, Callsite, ScopeLookup, } from './scope-resolution/types.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/_shared/index.js
CHANGED
|
@@ -3,6 +3,8 @@ export { NODE_TABLES, REL_TABLE_NAME, REL_TYPES, EMBEDDING_TABLE_NAME, } from '.
|
|
|
3
3
|
// Language support
|
|
4
4
|
export { SupportedLanguages } from './languages.js';
|
|
5
5
|
export { getLanguageFromFilename, getSyntaxLanguageFromFilename, isBladeTemplateFilename, } from './language-detection.js';
|
|
6
|
+
// Impact risk scoring
|
|
7
|
+
export { scoreImpactRisk, unusedAxesForImpactWalk } from './impact-risk.js';
|
|
6
8
|
// Evidence + tie-break constants (RFC Appendix A, Appendix B)
|
|
7
9
|
export { EvidenceWeights, typeBindingWeightAtDepth } from './scope-resolution/evidence-weights.js';
|
|
8
10
|
export { ORIGIN_PRIORITY } from './scope-resolution/origin-priority.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AASA,mBAAmB;AACnB,OAAO,EACL,WAAW,EACX,cAAc,EACd,SAAS,EACT,oBAAoB,GACrB,MAAM,4BAA4B,CAAC;AAGpC,mBAAmB;AACnB,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EACL,uBAAuB,EACvB,6BAA6B,EAC7B,uBAAuB,GACxB,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AASA,mBAAmB;AACnB,OAAO,EACL,WAAW,EACX,cAAc,EACd,SAAS,EACT,oBAAoB,GACrB,MAAM,4BAA4B,CAAC;AAGpC,mBAAmB;AACnB,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EACL,uBAAuB,EACvB,6BAA6B,EAC7B,uBAAuB,GACxB,MAAM,yBAAyB,CAAC;AAGjC,sBAAsB;AACtB,OAAO,EAAE,eAAe,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AA4C5E,8DAA8D;AAC9D,OAAO,EAAE,eAAe,EAAE,wBAAwB,EAAE,MAAM,wCAAwC,CAAC;AACnG,OAAO,EAAE,eAAe,EAAE,MAAM,uCAAuC,CAAC;AAGxE,yDAAyD;AACzD,OAAO,EACL,uBAAuB,EACvB,oBAAoB,GACrB,MAAM,+CAA+C,CAAC;AAGvD,sEAAsE;AACtE,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAEhE,OAAO,EAAE,qBAAqB,EAAE,MAAM,0CAA0C,CAAC;AAEjF,OAAO,EAAE,uBAAuB,EAAE,MAAM,4CAA4C,CAAC;AAGrF,gEAAgE;AAChE,yEAAyE;AACzE,2DAA2D;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,wCAAwC,CAAC;AA4BxE,oFAAoF;AACpF,OAAO,EAAE,wBAAwB,EAAE,MAAM,6CAA6C,CAAC;AAMvF,uEAAuE;AACvE,OAAO,EAAE,QAAQ,EAAE,MAAM,0CAA0C,CAAC;AAUpE,sEAAsE;AACtE,OAAO,EAAE,kBAAkB,EAAE,MAAM,iDAAiD,CAAC;AAErF,OAAO,EAAE,mBAAmB,EAAE,MAAM,kDAAkD,CAAC;AAKvF,OAAO,EAAE,kBAAkB,EAAE,MAAM,iDAAiD,CAAC;AAKrF,OAAO,EAAE,kBAAkB,EAAE,MAAM,iDAAiD,CAAC;AAErF,OAAO,EAAE,UAAU,EAAE,MAAM,8CAA8C,CAAC;AAE1E,OAAO,EAAE,eAAe,EAAE,MAAM,mDAAmD,CAAC;AAEpF,OAAO,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,2CAA2C,CAAC;AAEpG,OAAO,EACL,gCAAgC,EAChC,kBAAkB,GACnB,MAAM,6CAA6C,CAAC;AAErD,OAAO,EACL,WAAW,EACX,YAAY,EACZ,WAAW,EACX,WAAW,GACZ,MAAM,0CAA0C,CAAC;AAUlD,2EAA2E;AAC3E,OAAO,EAAE,WAAW,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AAErF,OAAO,EACL,cAAc,EACd,cAAc,EACd,uBAAuB,GACxB,MAAM,kCAAkC,CAAC;AAE1C,OAAO,EAAE,kBAAkB,EAAE,MAAM,sCAAsC,CAAC;AAG1E,8EAA8E;AAC9E,wEAAwE;AACxE,wEAAwE;AACxE,8DAA8D;AAC9D,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAEtE,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,mCAAmC,CAAC;AAEjG,OAAO,EACL,cAAc,EACd,4BAA4B,EAC5B,kBAAkB,EAClB,eAAe,EACf,sBAAsB,GACvB,MAAM,mCAAmC,CAAC;AAG3C,mDAAmD;AACnD,OAAO,EACL,+BAA+B,EAC/B,6BAA6B,EAC7B,4BAA4B,EAC5B,sBAAsB,EACtB,gBAAgB,EAChB,wBAAwB,EACxB,cAAc,GACf,MAAM,sCAAsC,CAAC"}
|
|
@@ -58,6 +58,8 @@ export declare function sanitizeDetectedBranch(value: string | null | undefined)
|
|
|
58
58
|
* (the normal case). Throws {@link GitNexusRcError} on any problem.
|
|
59
59
|
*/
|
|
60
60
|
export declare function loadAnalyzeConfig(repoRoot: string): Partial<AnalyzeOptions> | undefined;
|
|
61
|
+
/** Load `.gitnexusrc` through the strict bounded reader used by watch mode. */
|
|
62
|
+
export declare function loadAnalyzeConfigStrict(repoRoot: string): Promise<Partial<AnalyzeOptions> | undefined>;
|
|
61
63
|
/**
|
|
62
64
|
* Merge CLI options over `.gitnexusrc` defaults. CLI wins whenever it provides a
|
|
63
65
|
* value — including an explicit `false` (so an explicit CLI off-switch beats a
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
*/
|
|
30
30
|
import fs from 'node:fs';
|
|
31
31
|
import path from 'node:path';
|
|
32
|
+
import { readRepoControlFile } from '../config/repo-control-file.js';
|
|
32
33
|
export const GITNEXUS_RC_FILENAME = '.gitnexusrc';
|
|
33
34
|
/** Final fallback when no branch is configured or detectable. */
|
|
34
35
|
export const DEFAULT_BRANCH_FALLBACK = 'main';
|
|
@@ -328,6 +329,21 @@ export function loadAnalyzeConfig(repoRoot) {
|
|
|
328
329
|
return undefined;
|
|
329
330
|
throw new GitNexusRcError(`Could not read ${GITNEXUS_RC_FILENAME}: ${err.message}`);
|
|
330
331
|
}
|
|
332
|
+
return parseAnalyzeConfig(raw);
|
|
333
|
+
}
|
|
334
|
+
/** Load `.gitnexusrc` through the strict bounded reader used by watch mode. */
|
|
335
|
+
export async function loadAnalyzeConfigStrict(repoRoot) {
|
|
336
|
+
let raw;
|
|
337
|
+
try {
|
|
338
|
+
raw = await readRepoControlFile(repoRoot, GITNEXUS_RC_FILENAME);
|
|
339
|
+
}
|
|
340
|
+
catch (err) {
|
|
341
|
+
throw new GitNexusRcError(`Could not read ${GITNEXUS_RC_FILENAME}: ${err.message}`);
|
|
342
|
+
}
|
|
343
|
+
return raw === null ? undefined : parseAnalyzeConfig(raw);
|
|
344
|
+
}
|
|
345
|
+
function parseAnalyzeConfig(rawInput) {
|
|
346
|
+
let raw = rawInput;
|
|
331
347
|
// Strip a leading UTF-8 BOM: Node's 'utf-8' decode keeps it, and JSON.parse
|
|
332
348
|
// then fails with a confusing "Unexpected token" on an otherwise-valid file
|
|
333
349
|
// (#1996 tri-review). Only one leading BOM is stripped; in-string control
|
|
@@ -15,6 +15,10 @@
|
|
|
15
15
|
* import cycle. `analyze.ts` re-exports the type for existing importers.
|
|
16
16
|
*/
|
|
17
17
|
export interface AnalyzeOptions {
|
|
18
|
+
/** Keep this repository current with serialized incremental refreshes. */
|
|
19
|
+
watch?: boolean;
|
|
20
|
+
/** Watch quiet period in milliseconds. */
|
|
21
|
+
debounce?: string;
|
|
18
22
|
force?: boolean;
|
|
19
23
|
repairFts?: boolean;
|
|
20
24
|
/**
|
package/dist/cli/analyze.d.ts
CHANGED
|
@@ -25,6 +25,22 @@ export declare function computeHeapCapMb(totalBytes: number, constrainedBytes: n
|
|
|
25
25
|
* later-flag-wins semantics when NODE_OPTIONS repeats a flag.
|
|
26
26
|
*/
|
|
27
27
|
export declare function parseMaxOldSpaceMb(nodeOptions: string): number | null;
|
|
28
|
+
/** Re-exec the process with the RAM-aware auto heap cap + larger semi-space/stack
|
|
29
|
+
* if we're currently below that.
|
|
30
|
+
*
|
|
31
|
+
* Heap-source precedence (#2649):
|
|
32
|
+
* - an explicit per-invocation `--max-old-space-size` (execArgv) always wins;
|
|
33
|
+
* - `GITNEXUS_MEMORY=off` declines the memory autopilot entirely;
|
|
34
|
+
* - an ambient NODE_OPTIONS heap >= the auto cap is honored as-is;
|
|
35
|
+
* - an ambient NODE_OPTIONS heap BELOW the auto cap is treated as an
|
|
36
|
+
* inherited environment default (devcontainers/CI export one for other
|
|
37
|
+
* tooling), not a deliberate per-run choice: warn and respawn with the
|
|
38
|
+
* auto cap. Pre-#2649 this returned early and large repos then OOM'd on
|
|
39
|
+
* whatever heap the environment happened to specify. */
|
|
40
|
+
export declare function forwardedSignalExitCode(signal: NodeJS.Signals, cleanTermination: boolean): number;
|
|
41
|
+
export declare function ensureHeap(options?: {
|
|
42
|
+
cleanForwardedTermination?: boolean;
|
|
43
|
+
}): Promise<boolean>;
|
|
28
44
|
/**
|
|
29
45
|
* CLI `analyze` flag shape. Defined in `./analyze-options.js` so
|
|
30
46
|
* `analyze-config.ts` can reference it without importing this module back —
|
|
@@ -50,3 +66,4 @@ export declare const shouldGenerateCommunitySkillFiles: (options: Pick<AnalyzeOp
|
|
|
50
66
|
export declare const analyzeCommand: (inputPath?: string, options?: AnalyzeOptions, runnerIdentityAtBootstrap?: AnalyzerRunnerIdentity) => Promise<void>;
|
|
51
67
|
/** Commander entrypoint used only by the capture-before-import lazy bootstrap. */
|
|
52
68
|
export declare const analyzeCommandWithRunnerIdentity: (runnerIdentityAtBootstrap: AnalyzerRunnerIdentity, inputPath?: string, options?: AnalyzeOptions) => Promise<void>;
|
|
69
|
+
export declare function analyzeOrWatchCommandWithRunnerIdentity(runnerIdentityAtBootstrap: AnalyzerRunnerIdentity, inputPath?: string, options?: AnalyzeOptions): Promise<void>;
|
package/dist/cli/analyze.js
CHANGED
|
@@ -282,17 +282,29 @@ const runRespawnedAnalyze = (args, env) => new Promise((resolve) => {
|
|
|
282
282
|
let stdout = '';
|
|
283
283
|
let stderr = '';
|
|
284
284
|
let settled = false;
|
|
285
|
-
|
|
286
|
-
if (settled)
|
|
287
|
-
return;
|
|
288
|
-
settled = true;
|
|
289
|
-
resolve(exit);
|
|
290
|
-
};
|
|
285
|
+
let forwardedSignal;
|
|
291
286
|
const child = spawn(process.execPath, [...args], {
|
|
292
287
|
stdio: ['inherit', 'pipe', 'pipe'],
|
|
293
288
|
windowsHide: true,
|
|
294
289
|
env,
|
|
295
290
|
});
|
|
291
|
+
const forwardSignal = (signal) => {
|
|
292
|
+
forwardedSignal ??= signal;
|
|
293
|
+
if (child.exitCode === null && child.signalCode === null)
|
|
294
|
+
child.kill(signal);
|
|
295
|
+
};
|
|
296
|
+
const forwardSigint = () => forwardSignal('SIGINT');
|
|
297
|
+
const forwardSigterm = () => forwardSignal('SIGTERM');
|
|
298
|
+
const finish = (exit) => {
|
|
299
|
+
if (settled)
|
|
300
|
+
return;
|
|
301
|
+
settled = true;
|
|
302
|
+
process.removeListener('SIGINT', forwardSigint);
|
|
303
|
+
process.removeListener('SIGTERM', forwardSigterm);
|
|
304
|
+
resolve({ ...exit, forwardedSignal });
|
|
305
|
+
};
|
|
306
|
+
process.once('SIGINT', forwardSigint);
|
|
307
|
+
process.once('SIGTERM', forwardSigterm);
|
|
296
308
|
child.stdout?.on('data', (chunk) => {
|
|
297
309
|
stdout = appendOutputTail(stdout, chunk);
|
|
298
310
|
realStdoutWrite(chunk);
|
|
@@ -412,7 +424,16 @@ export function parseMaxOldSpaceMb(nodeOptions) {
|
|
|
412
424
|
* tooling), not a deliberate per-run choice: warn and respawn with the
|
|
413
425
|
* auto cap. Pre-#2649 this returned early and large repos then OOM'd on
|
|
414
426
|
* whatever heap the environment happened to specify. */
|
|
415
|
-
|
|
427
|
+
export function forwardedSignalExitCode(signal, cleanTermination) {
|
|
428
|
+
if (cleanTermination)
|
|
429
|
+
return 0;
|
|
430
|
+
if (signal === 'SIGINT')
|
|
431
|
+
return 130;
|
|
432
|
+
if (signal === 'SIGTERM')
|
|
433
|
+
return 143;
|
|
434
|
+
return 1;
|
|
435
|
+
}
|
|
436
|
+
export async function ensureHeap(options = {}) {
|
|
416
437
|
// Explicit opt-out disables auto-sizing ENTIRELY — both the ambient-pin
|
|
417
438
|
// override and the default v8-limit respawn — and is honored SILENTLY:
|
|
418
439
|
// the operator already made the call, and stderr-sensitive consumers
|
|
@@ -456,6 +477,10 @@ async function ensureHeap() {
|
|
|
456
477
|
if (shouldBridgeRespawnProgressTty())
|
|
457
478
|
childEnv[RESPAWN_PROGRESS_ENV] = '1';
|
|
458
479
|
const childExit = await runRespawnedAnalyze(childArgs, childEnv);
|
|
480
|
+
if (childExit.forwardedSignal !== undefined) {
|
|
481
|
+
process.exitCode = forwardedSignalExitCode(childExit.forwardedSignal, options.cleanForwardedTermination === true);
|
|
482
|
+
return true;
|
|
483
|
+
}
|
|
459
484
|
if (childExit.status !== 0 || childExit.signal) {
|
|
460
485
|
if (childProcessLikelyOom(childExit)) {
|
|
461
486
|
cliError(` Analysis likely ran out of memory (heap cap auto-sized to ${RESPAWN_HEAP_MB}MB ≈ 0.75x RAM).\n` +
|
|
@@ -573,6 +598,14 @@ export const analyzeCommand = async (inputPath, options, runnerIdentityAtBootstr
|
|
|
573
598
|
};
|
|
574
599
|
/** Commander entrypoint used only by the capture-before-import lazy bootstrap. */
|
|
575
600
|
export const analyzeCommandWithRunnerIdentity = async (runnerIdentityAtBootstrap, inputPath, options) => analyzeCommand(inputPath, options, runnerIdentityAtBootstrap);
|
|
601
|
+
export async function analyzeOrWatchCommandWithRunnerIdentity(runnerIdentityAtBootstrap, inputPath, options = {}) {
|
|
602
|
+
if (options.watch) {
|
|
603
|
+
const { watchCommandWithRunnerIdentity } = await import('./watch.js');
|
|
604
|
+
await watchCommandWithRunnerIdentity(runnerIdentityAtBootstrap, inputPath, options);
|
|
605
|
+
return;
|
|
606
|
+
}
|
|
607
|
+
await analyzeCommandWithRunnerIdentity(runnerIdentityAtBootstrap, inputPath, options);
|
|
608
|
+
}
|
|
576
609
|
const analyzeCommandImpl = async (inputPath, cliOptions, runnerIdentityAtBootstrap) => {
|
|
577
610
|
console.log('\n GitNexus Analyzer\n');
|
|
578
611
|
// ── Resolve the target repo root ──────────────────────────────────
|
package/dist/cli/help-i18n.js
CHANGED
|
@@ -68,6 +68,8 @@ const OPTION_DESCRIPTION_KEYS = {
|
|
|
68
68
|
'analyze|--embedding-batch-size <n>': 'help.option.analyze.embeddingBatchSize',
|
|
69
69
|
'analyze|--embedding-sub-batch-size <n>': 'help.option.analyze.embeddingSubBatchSize',
|
|
70
70
|
'analyze|--embedding-device <device>': 'help.option.analyze.embeddingDevice',
|
|
71
|
+
'analyze|--watch': 'help.option.analyze.watch',
|
|
72
|
+
'analyze|--debounce <ms>': 'help.option.analyze.debounce',
|
|
71
73
|
'index|-f, --force': 'help.option.index.force',
|
|
72
74
|
'index|--allow-non-git': 'help.option.index.allowNonGit',
|
|
73
75
|
'mcp|--http': 'help.option.mcp.http',
|
package/dist/cli/i18n/en.d.ts
CHANGED
|
@@ -171,6 +171,8 @@ export declare const en: {
|
|
|
171
171
|
readonly 'help.option.analyze.embeddingBatchSize': "Number of nodes per embedding batch";
|
|
172
172
|
readonly 'help.option.analyze.embeddingSubBatchSize': "Number of chunks per embedding model call";
|
|
173
173
|
readonly 'help.option.analyze.embeddingDevice': "Embedding device: auto, cpu, dml, cuda, or wasm";
|
|
174
|
+
readonly 'help.option.analyze.watch': "Keep the index current with serialized incremental refreshes";
|
|
175
|
+
readonly 'help.option.analyze.debounce': "Watch quiet period before refreshing (milliseconds)";
|
|
174
176
|
readonly 'help.option.index.force': "Register even if index metadata is missing (stats will be empty)";
|
|
175
177
|
readonly 'help.option.index.allowNonGit': "Allow registering folders that are not Git repositories";
|
|
176
178
|
readonly 'help.option.port': "Port number";
|
package/dist/cli/i18n/en.js
CHANGED
|
@@ -173,6 +173,8 @@ export const en = {
|
|
|
173
173
|
'help.option.analyze.embeddingBatchSize': 'Number of nodes per embedding batch',
|
|
174
174
|
'help.option.analyze.embeddingSubBatchSize': 'Number of chunks per embedding model call',
|
|
175
175
|
'help.option.analyze.embeddingDevice': 'Embedding device: auto, cpu, dml, cuda, or wasm',
|
|
176
|
+
'help.option.analyze.watch': 'Keep the index current with serialized incremental refreshes',
|
|
177
|
+
'help.option.analyze.debounce': 'Watch quiet period before refreshing (milliseconds)',
|
|
176
178
|
'help.option.index.force': 'Register even if index metadata is missing (stats will be empty)',
|
|
177
179
|
'help.option.index.allowNonGit': 'Allow registering folders that are not Git repositories',
|
|
178
180
|
'help.option.port': 'Port number',
|
|
@@ -172,6 +172,8 @@ export declare const cliResources: {
|
|
|
172
172
|
readonly 'help.option.analyze.embeddingBatchSize': "Number of nodes per embedding batch";
|
|
173
173
|
readonly 'help.option.analyze.embeddingSubBatchSize': "Number of chunks per embedding model call";
|
|
174
174
|
readonly 'help.option.analyze.embeddingDevice': "Embedding device: auto, cpu, dml, cuda, or wasm";
|
|
175
|
+
readonly 'help.option.analyze.watch': "Keep the index current with serialized incremental refreshes";
|
|
176
|
+
readonly 'help.option.analyze.debounce': "Watch quiet period before refreshing (milliseconds)";
|
|
175
177
|
readonly 'help.option.index.force': "Register even if index metadata is missing (stats will be empty)";
|
|
176
178
|
readonly 'help.option.index.allowNonGit': "Allow registering folders that are not Git repositories";
|
|
177
179
|
readonly 'help.option.port': "Port number";
|
|
@@ -426,6 +428,8 @@ export declare const cliResources: {
|
|
|
426
428
|
'help.option.analyze.embeddingBatchSize': string;
|
|
427
429
|
'help.option.analyze.embeddingSubBatchSize': string;
|
|
428
430
|
'help.option.analyze.embeddingDevice': string;
|
|
431
|
+
'help.option.analyze.watch': string;
|
|
432
|
+
'help.option.analyze.debounce': string;
|
|
429
433
|
'help.option.index.force': string;
|
|
430
434
|
'help.option.index.allowNonGit': string;
|
|
431
435
|
'help.option.port': string;
|
package/dist/cli/i18n/zh-CN.d.ts
CHANGED
|
@@ -171,6 +171,8 @@ export declare const zhCN: {
|
|
|
171
171
|
'help.option.analyze.embeddingBatchSize': string;
|
|
172
172
|
'help.option.analyze.embeddingSubBatchSize': string;
|
|
173
173
|
'help.option.analyze.embeddingDevice': string;
|
|
174
|
+
'help.option.analyze.watch': string;
|
|
175
|
+
'help.option.analyze.debounce': string;
|
|
174
176
|
'help.option.index.force': string;
|
|
175
177
|
'help.option.index.allowNonGit': string;
|
|
176
178
|
'help.option.port': string;
|
package/dist/cli/i18n/zh-CN.js
CHANGED
|
@@ -171,6 +171,8 @@ export const zhCN = {
|
|
|
171
171
|
'help.option.analyze.embeddingBatchSize': '每个嵌入批次的节点数',
|
|
172
172
|
'help.option.analyze.embeddingSubBatchSize': '每次嵌入模型调用的分块数',
|
|
173
173
|
'help.option.analyze.embeddingDevice': '嵌入设备:auto、cpu、dml、cuda 或 wasm',
|
|
174
|
+
'help.option.analyze.watch': '监视本地源文件变更并串行执行增量刷新',
|
|
175
|
+
'help.option.analyze.debounce': '刷新前的静默等待时间(毫秒)',
|
|
174
176
|
'help.option.index.force': '即使缺少索引元数据也注册(统计为空)',
|
|
175
177
|
'help.option.index.allowNonGit': '允许注册非 Git 仓库文件夹',
|
|
176
178
|
'help.option.port': '端口号',
|
package/dist/cli/index.js
CHANGED
|
@@ -36,6 +36,8 @@ let dimsEnvCaptured = false;
|
|
|
36
36
|
program
|
|
37
37
|
.command('analyze [path]')
|
|
38
38
|
.description('Index a repository (full analysis)')
|
|
39
|
+
.option('--watch', 'Keep the index current with serialized incremental refreshes')
|
|
40
|
+
.option('--debounce <ms>', 'Watch quiet period before refreshing (default: 300 milliseconds)')
|
|
39
41
|
.option('-f, --force', 'Force full re-index even if up to date')
|
|
40
42
|
.option('--repair-fts', 'Repair/rebuild search FTS indexes without full re-analysis')
|
|
41
43
|
.option('--embeddings [limit]', 'Enable embedding generation for semantic search (off by default). ' +
|
|
@@ -84,6 +86,11 @@ program
|
|
|
84
86
|
'Must match what the index was built with. Overrides GITNEXUS_EMBEDDING_DIMS.')
|
|
85
87
|
.addHelpText('after', () => t('help.analyze.environment'))
|
|
86
88
|
.hook('preAction', (thisCommand) => {
|
|
89
|
+
const analyzeOpts = thisCommand.opts();
|
|
90
|
+
if (analyzeOpts['debounce'] !== undefined && analyzeOpts['watch'] !== true) {
|
|
91
|
+
process.stderr.write('\n --debounce requires --watch\n\n');
|
|
92
|
+
process.exit(1);
|
|
93
|
+
}
|
|
87
94
|
// ONLY GITNEXUS_EMBEDDING_DIMS must be set here: schema.ts reads it at
|
|
88
95
|
// module-load time during the lazy import('./analyze.js') below (via the
|
|
89
96
|
// static chain analyze.ts → run-analyze.ts → schema.ts), so deferring to
|
|
@@ -91,7 +98,7 @@ program
|
|
|
91
98
|
// lazily at runtime (readConfig), so analyzeCommandImpl is their sole
|
|
92
99
|
// setter — keeping them out of this hook means they fall under the impl's
|
|
93
100
|
// env snapshot/restore and don't leak across in-process invocations.
|
|
94
|
-
const dimsOpt =
|
|
101
|
+
const dimsOpt = analyzeOpts['embeddingDims'];
|
|
95
102
|
if (dimsOpt !== undefined) {
|
|
96
103
|
// Validate + normalize BEFORE writing the env var: schema.ts throws on a
|
|
97
104
|
// bad value at module-load, which — on the synchronous program.parse()
|
|
@@ -122,7 +129,7 @@ program
|
|
|
122
129
|
process.env.GITNEXUS_EMBEDDING_DIMS = dimsEnvBaseline;
|
|
123
130
|
}
|
|
124
131
|
})
|
|
125
|
-
.action(createAnalyzerLbugLazyAction(() => import('../core/analyzer-identity.js'), () => import('./analyze.js'), '
|
|
132
|
+
.action(createAnalyzerLbugLazyAction(() => import('../core/analyzer-identity.js'), () => import('./analyze.js'), 'analyzeOrWatchCommandWithRunnerIdentity', import.meta.url));
|
|
126
133
|
program
|
|
127
134
|
.command('index [path...]')
|
|
128
135
|
.description('Register an existing .gitnexus/ folder into the global registry (no re-analysis needed)')
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export type WatchRefresh = (paths: readonly string[]) => Promise<void>;
|
|
2
|
+
export type WatchRefreshError = (error: unknown, paths: readonly string[]) => void;
|
|
3
|
+
export declare const WATCH_FULL_REFRESH_PATH = "*";
|
|
4
|
+
export interface WatchRefreshQueueOptions {
|
|
5
|
+
readonly maxWaitMs?: number;
|
|
6
|
+
readonly maxPendingPaths?: number;
|
|
7
|
+
readonly retryBaseDelayMs?: number;
|
|
8
|
+
readonly retryMaxDelayMs?: number;
|
|
9
|
+
readonly holdEventsUntilInitialRefresh?: boolean;
|
|
10
|
+
readonly isPriorityPath?: (filePath: string) => boolean;
|
|
11
|
+
}
|
|
12
|
+
/** Debounces filesystem events and guarantees that refreshes never overlap. */
|
|
13
|
+
export declare class WatchRefreshQueue {
|
|
14
|
+
private readonly refresh;
|
|
15
|
+
private readonly onError;
|
|
16
|
+
private readonly debounceMs;
|
|
17
|
+
private readonly options;
|
|
18
|
+
private readonly pending;
|
|
19
|
+
private readonly idleWaiters;
|
|
20
|
+
private timer;
|
|
21
|
+
private active;
|
|
22
|
+
private closed;
|
|
23
|
+
private initialPending;
|
|
24
|
+
private firstPendingAt;
|
|
25
|
+
private overflowed;
|
|
26
|
+
private consecutiveFailures;
|
|
27
|
+
private retryNotBefore;
|
|
28
|
+
constructor(refresh: WatchRefresh, onError: WatchRefreshError, debounceMs: number, options?: WatchRefreshQueueOptions);
|
|
29
|
+
enqueue(filePath: string): void;
|
|
30
|
+
private addPendingPath;
|
|
31
|
+
/** Run the initial refresh while still queueing events that arrive during it. */
|
|
32
|
+
runInitial(): Promise<void>;
|
|
33
|
+
waitForIdle(): Promise<void>;
|
|
34
|
+
close(): Promise<void>;
|
|
35
|
+
private schedule;
|
|
36
|
+
private drain;
|
|
37
|
+
private runBatch;
|
|
38
|
+
private hasPendingWork;
|
|
39
|
+
private isIdle;
|
|
40
|
+
private resolveIdleWaiters;
|
|
41
|
+
}
|