gitnexus 1.6.12-rc.40 → 1.6.12-rc.42
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 +5 -2
- package/dist/cli/analyze-watch.js +9 -0
- package/dist/cli/analyze.js +4 -5
- package/dist/cli/clean.js +75 -33
- package/dist/cli/i18n/en.d.ts +1 -1
- package/dist/cli/i18n/en.js +1 -1
- package/dist/cli/i18n/resources.d.ts +1 -1
- package/dist/cli/i18n/zh-CN.js +1 -1
- package/dist/cli/index-repo.js +50 -32
- package/dist/cli/index.js +4 -3
- package/dist/cli/publish.js +14 -3
- package/dist/cli/remove.js +8 -12
- package/dist/cli/setup.js +1 -0
- package/dist/cli/status.d.ts +2 -0
- package/dist/cli/status.js +150 -11
- package/dist/cli/wiki.js +17 -5
- package/dist/core/augmentation/engine.js +16 -9
- package/dist/core/content-retention.d.ts +18 -0
- package/dist/core/content-retention.js +73 -0
- package/dist/core/group/bridge-db.js +33 -3
- package/dist/core/group/sync.js +23 -11
- package/dist/core/lbug/csv-generator.d.ts +2 -1
- package/dist/core/lbug/csv-generator.js +12 -7
- package/dist/core/lbug/lbug-adapter.d.ts +4 -1
- package/dist/core/lbug/lbug-adapter.js +46 -10
- package/dist/core/lbug/lbug-config.d.ts +4 -0
- package/dist/core/lbug/lbug-config.js +21 -0
- package/dist/core/lbug/pool-adapter.d.ts +7 -4
- package/dist/core/lbug/pool-adapter.js +177 -88
- package/dist/core/run-analyze.d.ts +2 -0
- package/dist/core/run-analyze.js +98 -26
- package/dist/core/search/fts-indexes.d.ts +7 -3
- package/dist/core/search/fts-indexes.js +11 -8
- package/dist/core/search/fts-schema.d.ts +3 -0
- package/dist/core/search/fts-schema.js +10 -0
- package/dist/mcp/local/local-backend.d.ts +3 -0
- package/dist/mcp/local/local-backend.js +62 -17
- package/dist/mcp/resources.js +6 -0
- package/dist/mcp/tools.js +2 -2
- package/dist/server/analyze-launch.d.ts +1 -1
- package/dist/server/analyze-launch.js +116 -53
- package/dist/server/analyze-upload.d.ts +1 -1
- package/dist/server/analyze-upload.js +1 -1
- package/dist/server/analyze-worker-core.js +1 -1
- package/dist/server/api.d.ts +20 -2
- package/dist/server/api.js +143 -31
- package/dist/server/repo-projection.d.ts +14 -3
- package/dist/server/repo-projection.js +8 -2
- package/dist/server/upload-sweep.d.ts +2 -2
- package/dist/server/upload-sweep.js +43 -16
- package/dist/storage/branch-index.d.ts +1 -1
- package/dist/storage/branch-index.js +4 -5
- package/dist/storage/parse-cache.js +1 -1
- package/dist/storage/repo-manager.d.ts +54 -47
- package/dist/storage/repo-manager.js +274 -188
- package/dist/storage/repo-meta.d.ts +17 -8
- package/dist/storage/repo-meta.js +11 -11
- package/dist/storage/storage-constants.d.ts +5 -0
- package/dist/storage/storage-constants.js +6 -0
- package/dist/storage/storage-resolver.d.ts +105 -0
- package/dist/storage/storage-resolver.js +583 -0
- package/hooks/antigravity/gitnexus-antigravity-hook.cjs +41 -105
- package/hooks/claude/gitnexus-hook.cjs +18 -111
- package/hooks/claude/registry-query.cjs +410 -0
- package/package.json +2 -2
- package/skills/gitnexus-cli.md +12 -0
- package/web/assets/{index-CacNO4DK.js → index-K4KOdfVv.js} +3 -3
- package/web/index.html +1 -1
package/README.md
CHANGED
|
@@ -161,7 +161,7 @@ GitNexus builds a complete knowledge graph of your codebase through a multi-phas
|
|
|
161
161
|
5. **Processes** — Traces execution flows from entry points through call chains
|
|
162
162
|
6. **Search** — Builds hybrid search indexes for fast retrieval
|
|
163
163
|
|
|
164
|
-
The result is a **LadybugDB graph database** stored locally in `.gitnexus/` with full-text search and semantic embeddings.
|
|
164
|
+
The result is a **LadybugDB graph database** stored locally in `.gitnexus/` by default, with full-text search and semantic embeddings.
|
|
165
165
|
|
|
166
166
|
### Experimental community detection engine
|
|
167
167
|
|
|
@@ -677,6 +677,9 @@ Configure the behavior with these environment variables:
|
|
|
677
677
|
| `GITNEXUS_LBUG_EXTENSION_INSTALL_TIMEOUT_MS` | positive integer | `15000` | Wall-clock budget for the out-of-process extension-install child before it is killed. |
|
|
678
678
|
| `GITNEXUS_FTS_STEMMER` | supported LadybugDB stemmer | `porter` | Stemmer used when rebuilding BM25/FTS indexes. Use `none` for CJK-heavy repositories, or a language stemmer such as `german`, `french`, or `spanish` when that better matches repository comments and identifiers. Re-run `gitnexus analyze --repair-fts` after changing it. |
|
|
679
679
|
| `GITNEXUS_FTS_CJK_SEGMENTATION` | `none`, `bigram` | `none` | `bigram` inserts overlapping character-bigram boundaries into Chinese/Japanese Han-ideograph spans in `content`/`description` before FTS indexing, so LadybugDB's space-only tokenizer can see sub-phrase word boundaries. Scoped to CJK Unified Ideographs only — Japanese Hiragana/Katakana and Korean Hangul are not currently segmented. Unlike `GITNEXUS_FTS_STEMMER`, this rewrites stored text — enabling it on an already-indexed repo requires a full `gitnexus analyze --force`; neither `--repair-fts` nor a plain incremental `analyze` applies it to previously-indexed files. Set the same value wherever `analyze` and search-serving processes (CLI query, MCP server, web server) run. |
|
|
680
|
+
| `GITNEXUS_STORAGE_PATH` | absolute, non-empty directory | unset (repo-local) | Complete external index directory. This preserves the existing configuration semantics and takes precedence over `GITNEXUS_STORAGE_ROOT` when both are set. |
|
|
681
|
+
| `GITNEXUS_STORAGE_ROOT` | absolute, non-empty directory | unset (repo-local) | Absolute root directory for external indexes. GitNexus creates an isolated `<repo-basename>-<canonical-path-hash>/` slot beneath it for each repository, then registers the resolved slot so `status`, MCP, and `serve` can reopen it later. |
|
|
682
|
+
| `GITNEXUS_CONTENT_RETENTION` | `full`, `symbol`, `none` | `full` | Source-text retention profile: `full` keeps file and symbol text, `symbol` keeps symbol snippets without full file content, and `none` keeps the structural graph without source body text. |
|
|
680
683
|
| `GITNEXUS_STREAM_GRAPH_EMIT` | `0`, `1` | `1` (on) | **On by default** on a full rebuild (`--force`); incremental runs ignore it. Holds structural relationships (CALLS, IMPORTS, ACCESSES, CONTAINS, ...) as CSV-on-disk plus compact in-memory columns instead of as objects in three overlapping indexes, cutting peak in-memory graph heap by ~1.4x at no measurable CPU cost (measured A/B on a synthetic 400k-node / 1.08M-edge graph: 819 MB -> 584 MB, iteration at parity, scaling verified linear from 100k to 800k nodes, with every edge still visible through the graph interface; no end-to-end measurement on a real repository yet). Nothing is traded away — community detection, process extraction, PDG taint summaries and the local-symbol pruner all read a complete relationship set and behave identically. Set to `0` only to bisect a suspected streaming-related fault. |
|
|
681
684
|
| `GITNEXUS_COMMUNITY_ENGINE` | `graphology`, `icebug`, `auto` | `graphology` | Community-detection engine used during analyze. `graphology` is the supported default. `icebug` and `auto` are **experimental** and currently behave identically: both try the optional `@ladybugmem/icebug` native Leiden over a CSR export and fall back to Graphology if it is not installed, cannot load, or lacks the deterministic thread/seed controls. Experimental engines partition differently, so community IDs are not comparable across engines. |
|
|
682
685
|
| `GITNEXUS_WAL_CHECKPOINT_THRESHOLD` | integer `>= -1` | `67108864` (64 MiB) | LadybugDB WAL auto-checkpoint threshold during analyze (bytes). Auto-checkpoint remains enabled; `-1` keeps Ladybug's stock ~16 MiB. Larger thresholds reduce checkpoint frequency but increase the WAL size at rotation time — choose a smaller value on disk-constrained environments. |
|
|
@@ -882,7 +885,7 @@ only — the hook's structured stdout (the JSON the agent consumes) is unaffecte
|
|
|
882
885
|
|
|
883
886
|
- All processing happens locally on your machine
|
|
884
887
|
- No code is sent to any server
|
|
885
|
-
- Index stored in `.gitnexus/` inside your repo (gitignored)
|
|
888
|
+
- Index stored in `.gitnexus/` inside your repo by default (gitignored), in the complete external directory selected by `GITNEXUS_STORAGE_PATH`, or in a repository-specific slot beneath `GITNEXUS_STORAGE_ROOT`
|
|
886
889
|
- Global registry at `~/.gitnexus/` stores only paths and metadata
|
|
887
890
|
|
|
888
891
|
## Web UI
|
|
@@ -6,6 +6,7 @@ import { createWatchIgnorePredicate } from '../config/ignore-service.js';
|
|
|
6
6
|
import { analyzeFailureMayHaveMutatedLiveIndex, runFullAnalysis, } from '../core/run-analyze.js';
|
|
7
7
|
import { isIndexLockGuardTimeout } from '../storage/index-lock.js';
|
|
8
8
|
import { getGitRoot, hasGitDir } from '../storage/git.js';
|
|
9
|
+
import { ANALYZE_STORAGE_REQUIREMENTS, requireStoragePath } from '../storage/storage-resolver.js';
|
|
9
10
|
import { GITNEXUS_DIR } from '../storage/repo-meta.js';
|
|
10
11
|
import { loadAnalyzeConfigStrict, mergeAnalyzeOptions, validateBranchName, } from './analyze-config.js';
|
|
11
12
|
import { ensureHeap } from './analyze.js';
|
|
@@ -324,6 +325,14 @@ export async function watchCommandWithRunnerIdentity(runnerIdentityAtBootstrap,
|
|
|
324
325
|
return;
|
|
325
326
|
}
|
|
326
327
|
const repoPath = await fs.realpath(requestedRepoPath);
|
|
328
|
+
try {
|
|
329
|
+
await requireStoragePath(repoPath, ANALYZE_STORAGE_REQUIREMENTS);
|
|
330
|
+
}
|
|
331
|
+
catch (error) {
|
|
332
|
+
cliError(` ${error instanceof Error ? error.message : String(error)}`);
|
|
333
|
+
process.exitCode = 1;
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
327
336
|
const baselineEnvironment = {
|
|
328
337
|
maxFileSize: process.env.GITNEXUS_MAX_FILE_SIZE,
|
|
329
338
|
workerTimeout: process.env.GITNEXUS_WORKER_SUB_BATCH_TIMEOUT_MS,
|
package/dist/cli/analyze.js
CHANGED
|
@@ -18,7 +18,7 @@ import { boundedCheckpointBeforeExit } from '../core/lbug/shutdown-helpers.js';
|
|
|
18
18
|
import { findUndeclaredRelationPairError } from '../core/lbug/rel-pair-routing.js';
|
|
19
19
|
import { causeChain } from '../lib/utils.js';
|
|
20
20
|
import { getOsPageSize, isLbugCheckpointIoError, isLbugCheckpointBusyError, isLbugPageSizeFrameError, isPageSizeAwareLadybug, isWalCorruptionError, parseWalCheckpointThreshold, WAL_RECOVERY_SUGGESTION, } from '../core/lbug/lbug-config.js';
|
|
21
|
-
import {
|
|
21
|
+
import { getGlobalRegistryPath, RegistryNameCollisionError, AnalysisNotFinalizedError, assertAnalysisFinalized, } from '../storage/repo-manager.js';
|
|
22
22
|
import { getGitRoot, hasGitDir, getDefaultBranch, selfCommitContextFiles, snapshotSelfCommitSafety, } from '../storage/git.js';
|
|
23
23
|
import { IndexLockTimeoutError, isIndexLockGuardTimeout } from '../storage/index-lock.js';
|
|
24
24
|
import { loadAnalyzeConfig, mergeAnalyzeOptions, resolveDefaultBranch, validateBranchName, GitNexusRcError, } from './analyze-config.js';
|
|
@@ -1158,7 +1158,7 @@ const analyzeCommandImpl = async (inputPath, cliOptions, runnerIdentityAtBootstr
|
|
|
1158
1158
|
// run can write meta.json and then fail before registerRepo(); in
|
|
1159
1159
|
// that half-finalized state, runFullAnalysis returns alreadyUpToDate
|
|
1160
1160
|
// on the next invocation unless we check the registry here too.
|
|
1161
|
-
await assertAnalysisFinalized(repoPath);
|
|
1161
|
+
await assertAnalysisFinalized(repoPath, result.storagePath);
|
|
1162
1162
|
// The fast path skips context regeneration, but a changed `.gitnexusrc`
|
|
1163
1163
|
// defaultBranch / `--default-branch` must still take effect. Surgically
|
|
1164
1164
|
// refresh just the `base_ref` line in AGENTS.md/CLAUDE.md in place,
|
|
@@ -1225,7 +1225,7 @@ const analyzeCommandImpl = async (inputPath, cliOptions, runnerIdentityAtBootstr
|
|
|
1225
1225
|
// success so the silent-finalize state surfaces with a non-zero
|
|
1226
1226
|
// exit code and an actionable error instead of being mistaken for
|
|
1227
1227
|
// a healthy index.
|
|
1228
|
-
await assertAnalysisFinalized(repoPath);
|
|
1228
|
+
await assertAnalysisFinalized(repoPath, result.storagePath);
|
|
1229
1229
|
// Skill generation (CLI-only, uses pipeline result from analysis).
|
|
1230
1230
|
// Gated so `--index-only --skills` skips community skill writes too
|
|
1231
1231
|
// (`shouldGenerateCommunitySkillFiles` — see unit test).
|
|
@@ -1249,8 +1249,7 @@ const analyzeCommandImpl = async (inputPath, cliOptions, runnerIdentityAtBootstr
|
|
|
1249
1249
|
}
|
|
1250
1250
|
aggregatedClusterCount = Array.from(groups.values()).filter((count) => count >= 5).length;
|
|
1251
1251
|
}
|
|
1252
|
-
|
|
1253
|
-
await generateAIContextFiles(repoPath, sp, result.repoName, {
|
|
1252
|
+
await generateAIContextFiles(repoPath, result.storagePath, result.repoName, {
|
|
1254
1253
|
files: s.files ?? 0,
|
|
1255
1254
|
nodes: s.nodes ?? 0,
|
|
1256
1255
|
edges: s.edges ?? 0,
|
package/dist/cli/clean.js
CHANGED
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
import fs from 'fs/promises';
|
|
8
8
|
import path from 'path';
|
|
9
9
|
import { logger } from '../core/logger.js';
|
|
10
|
-
import { findRepo, unregisterRepo, listRegisteredRepos,
|
|
10
|
+
import { findRepo, unregisterRepo, listRegisteredRepos, getStoragePaths, removeBranchIndex, } from '../storage/repo-manager.js';
|
|
11
|
+
import { requireDeletableStoragePath, StorageDeletionError } from '../storage/storage-resolver.js';
|
|
11
12
|
import { cleanParkedLbugSidecars, inspectLbugSidecars, listParkedLbugSidecars, } from '../core/lbug/sidecar-recovery.js';
|
|
12
13
|
import { t } from './i18n/index.js';
|
|
13
14
|
export const cleanCommand = async (options) => {
|
|
@@ -28,14 +29,27 @@ export const cleanCommand = async (options) => {
|
|
|
28
29
|
console.log(t('clean.branchNotIndexed', { branch: options.branch }));
|
|
29
30
|
return;
|
|
30
31
|
}
|
|
31
|
-
|
|
32
|
+
let storagePath;
|
|
33
|
+
try {
|
|
34
|
+
storagePath = await requireDeletableStoragePath({
|
|
35
|
+
path: repo.repoPath,
|
|
36
|
+
storagePath: repo.storagePath,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
catch (err) {
|
|
40
|
+
if (err instanceof StorageDeletionError) {
|
|
41
|
+
logger.error(`Refusing to clean branch index: ${err.message}`);
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
throw err;
|
|
45
|
+
}
|
|
46
|
+
const { lbugPath } = getStoragePaths(repo.repoPath, summary.branch, storagePath);
|
|
32
47
|
const branchDir = path.dirname(lbugPath);
|
|
33
|
-
// Safety guard: the target MUST live under
|
|
34
|
-
//
|
|
35
|
-
// is a dedicated branches-sub-dir check before any destructive fs.rm.
|
|
48
|
+
// Safety guard: the target MUST live under the validated
|
|
49
|
+
// storage slot's `branches/` directory before any destructive fs.rm.
|
|
36
50
|
const branchesRoot = path.join(storagePath, 'branches') + path.sep;
|
|
37
51
|
if (!branchDir.startsWith(branchesRoot)) {
|
|
38
|
-
logger.error(`Refusing to clean branch index outside
|
|
52
|
+
logger.error(`Refusing to clean branch index outside the validated storage slot: ${branchDir}`);
|
|
39
53
|
return;
|
|
40
54
|
}
|
|
41
55
|
if (!options.force) {
|
|
@@ -60,7 +74,21 @@ export const cleanCommand = async (options) => {
|
|
|
60
74
|
console.log(t('clean.notFoundHere'));
|
|
61
75
|
return;
|
|
62
76
|
}
|
|
63
|
-
|
|
77
|
+
let storagePath;
|
|
78
|
+
try {
|
|
79
|
+
storagePath = await requireDeletableStoragePath({
|
|
80
|
+
path: repo.repoPath,
|
|
81
|
+
storagePath: repo.storagePath,
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
catch (err) {
|
|
85
|
+
if (err instanceof StorageDeletionError) {
|
|
86
|
+
logger.error(`Refusing to clean sidecars: ${err.message}`);
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
throw err;
|
|
90
|
+
}
|
|
91
|
+
const { lbugPath } = getStoragePaths(repo.repoPath, undefined, storagePath);
|
|
64
92
|
const state = await inspectLbugSidecars(lbugPath);
|
|
65
93
|
// Single roster authority (this shipping review, FIX 5): the aggregate
|
|
66
94
|
// covers both parked-sidecar families — the timestamped missing-shadow
|
|
@@ -96,45 +124,45 @@ export const cleanCommand = async (options) => {
|
|
|
96
124
|
}
|
|
97
125
|
// --all flag: clean all indexed repos
|
|
98
126
|
if (options?.all) {
|
|
127
|
+
const entries = await listRegisteredRepos();
|
|
99
128
|
if (!options?.force) {
|
|
100
|
-
const
|
|
101
|
-
|
|
129
|
+
const deletableEntries = [];
|
|
130
|
+
for (const entry of entries) {
|
|
131
|
+
try {
|
|
132
|
+
await requireDeletableStoragePath(entry);
|
|
133
|
+
deletableEntries.push(entry);
|
|
134
|
+
}
|
|
135
|
+
catch (err) {
|
|
136
|
+
if (err instanceof StorageDeletionError) {
|
|
137
|
+
logger.error(`Refusing to preview ${entry.name}: ${err.message}`);
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
throw err;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
if (deletableEntries.length === 0) {
|
|
102
144
|
console.log(t('common.notIndexed'));
|
|
103
145
|
return;
|
|
104
146
|
}
|
|
105
|
-
console.log(t('clean.deleteAll', { count:
|
|
106
|
-
for (const entry of
|
|
147
|
+
console.log(t('clean.deleteAll', { count: deletableEntries.length }));
|
|
148
|
+
for (const entry of deletableEntries) {
|
|
107
149
|
console.log(` - ${entry.name} (${entry.path})`);
|
|
108
150
|
}
|
|
109
151
|
console.log(`\n${t('common.runForceConfirm')}`);
|
|
110
152
|
return;
|
|
111
153
|
}
|
|
112
|
-
const entries = await listRegisteredRepos();
|
|
113
154
|
for (const entry of entries) {
|
|
114
|
-
// Safety guard (#1003 review — @magyargergo): same rationale as
|
|
115
|
-
// remove.ts. `~/.gitnexus/registry.json` is user-writable, so a
|
|
116
|
-
// corrupted or hand-edited entry could point storagePath at the
|
|
117
|
-
// repo root, an empty string, or anywhere else — and
|
|
118
|
-
// fs.rm(recursive: true) on any of those would be catastrophic.
|
|
119
|
-
// Skip poisoned entries without touching disk, but keep going
|
|
120
|
-
// through the rest of the registry (preserves the existing
|
|
121
|
-
// per-repo error-tolerance semantics of `clean --all`).
|
|
122
155
|
try {
|
|
123
|
-
|
|
156
|
+
const storagePath = await requireDeletableStoragePath(entry);
|
|
157
|
+
await fs.rm(storagePath, { recursive: true, force: true });
|
|
158
|
+
await unregisterRepo(entry.path);
|
|
159
|
+
console.log(t('clean.deletedRepo', { name: entry.name, storagePath }));
|
|
124
160
|
}
|
|
125
161
|
catch (err) {
|
|
126
|
-
if (err instanceof
|
|
162
|
+
if (err instanceof StorageDeletionError) {
|
|
127
163
|
logger.error(`Refusing to clean ${entry.name}: ${err.message}`);
|
|
128
164
|
continue;
|
|
129
165
|
}
|
|
130
|
-
throw err;
|
|
131
|
-
}
|
|
132
|
-
try {
|
|
133
|
-
await fs.rm(entry.storagePath, { recursive: true, force: true });
|
|
134
|
-
await unregisterRepo(entry.path);
|
|
135
|
-
console.log(t('clean.deletedRepo', { name: entry.name, storagePath: entry.storagePath }));
|
|
136
|
-
}
|
|
137
|
-
catch (err) {
|
|
138
166
|
logger.error({ err }, `Failed to delete ${entry.name}:`);
|
|
139
167
|
}
|
|
140
168
|
}
|
|
@@ -148,16 +176,30 @@ export const cleanCommand = async (options) => {
|
|
|
148
176
|
return;
|
|
149
177
|
}
|
|
150
178
|
const repoName = repo.repoPath.split(/[/\\]/).pop() || repo.repoPath;
|
|
179
|
+
let storagePath;
|
|
180
|
+
try {
|
|
181
|
+
storagePath = await requireDeletableStoragePath({
|
|
182
|
+
path: repo.repoPath,
|
|
183
|
+
storagePath: repo.storagePath,
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
catch (err) {
|
|
187
|
+
if (err instanceof StorageDeletionError) {
|
|
188
|
+
logger.error(`Refusing to clean ${repoName}: ${err.message}`);
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
throw err;
|
|
192
|
+
}
|
|
151
193
|
if (!options?.force) {
|
|
152
194
|
console.log(t('clean.deleteCurrent', { repoName }));
|
|
153
|
-
console.log(` ${t('common.path')}: ${
|
|
195
|
+
console.log(` ${t('common.path')}: ${storagePath}`);
|
|
154
196
|
console.log(`\n${t('common.runForceConfirm')}`);
|
|
155
197
|
return;
|
|
156
198
|
}
|
|
157
199
|
try {
|
|
158
|
-
await fs.rm(
|
|
200
|
+
await fs.rm(storagePath, { recursive: true, force: true });
|
|
159
201
|
await unregisterRepo(repo.repoPath);
|
|
160
|
-
console.log(t('common.deleted', { target:
|
|
202
|
+
console.log(t('common.deleted', { target: storagePath }));
|
|
161
203
|
}
|
|
162
204
|
catch (err) {
|
|
163
205
|
logger.error({ err }, 'Failed to delete:');
|
package/dist/cli/i18n/en.d.ts
CHANGED
|
@@ -278,5 +278,5 @@ export declare const en: {
|
|
|
278
278
|
readonly 'help.option.group.contracts.repo': "Filter by repo";
|
|
279
279
|
readonly 'help.option.group.contracts.unmatched': "Show only unmatched contracts";
|
|
280
280
|
readonly 'help.identityCache.environment': "\nAnalyzer identity cache:\n GITNEXUS_ANALYZER_IDENTITY_CACHE_DIR=/absolute/protected/dir\n Operator-trusted persistent cache for warm cross-process status. The directory must pre-exist, be outside the GitNexus package/build roots, and contain no symlink or junction components. Defaults remain fail-closed on platforms without POSIX ownership APIs.";
|
|
281
|
-
readonly 'help.analyze.environment': "\nEnvironment variables:\n GITNEXUS_NO_GITIGNORE=1 Skip .gitignore parsing (still reads .gitnexusignore)\n GITNEXUS_MAX_FILE_SIZE=N Override large-file skip threshold (KB). Default 512, max 32768.\n GITNEXUS_ANALYZER_IDENTITY_CACHE_DIR=/absolute/protected/dir Operator-trusted persistent analyzer identity cache; must pre-exist, be outside package/build roots, and contain no symlink/junction components.\n GITNEXUS_WORKER_SUB_BATCH_TIMEOUT_MS=N Worker idle timeout in milliseconds. Default 30000.\n GITNEXUS_WAL_CHECKPOINT_THRESHOLD=N LadybugDB WAL auto-checkpoint threshold in bytes (default 67108864 = 64 MiB; -1 keeps Ladybug stock ~16 MiB).\n GITNEXUS_WORKER_SUB_BATCH_MAX_BYTES=N Worker job byte budget. Default 8388608.\n GITNEXUS_WORKER_POOL_SIZE=N Parse worker count override. Default cores-1 capped at 16.\n GITNEXUS_PARSE_CHUNK_CONCURRENCY=N Concurrent in-flight parse chunks. Default 2.\n GITNEXUS_WORKER_MAX_RESPAWNS_PER_SLOT=N Max replacement spawns per slot before drop. Default 3.\n GITNEXUS_WORKER_MAX_CUMULATIVE_TIMEOUT_MS=N Total retry wall-time per job. Default 5x sub-batch timeout.\n GITNEXUS_WORKER_CONSECUTIVE_FAILURE_THRESHOLD=N Per-slot deaths to trip circuit breaker. Default max(3, poolSize).\n GITNEXUS_WORKER_SHUTDOWN_DRAIN_MS=N Max wait at pool shutdown for a retired worker still inside native code (terminated at its next safe point instead of aborting the process). Default 30000.\n GITNEXUS_CPP_CAPTURE_BUDGET_MS=N Per-file wall-clock budget for C++ capture extraction; on breach the file keeps partial captures with a warning. Default 20000.\n GITNEXUS_EMBEDDING_THREADS=N Limit local ONNX CPU threads for --embeddings.\n GITNEXUS_EMBEDDING_RETRY_TIMEOUTS=1 Retry per-attempt HTTP embedding timeouts through GITNEXUS_EMBEDDING_MAX_ATTEMPTS (default off; timeouts stay terminal).\n GITNEXUS_SEMANTIC_EXACT_SCAN_LIMIT=N Max embedding chunks for exact-scan fallback. Default 10000.\n GITNEXUS_VECTOR_MAX_DISTANCE=N Max accepted semantic/vector cosine distance (0 < N <= 2; higher values clamp to 2). Default 0.6 for MCP, 0.5 elsewhere.\n\nFlags override the corresponding env vars when both are provided.\n\nTip: `.gitnexusignore` supports `.gitignore`-style negation. Add e.g.\n `!__tests__/` to index a directory that is auto-filtered by default (#771).";
|
|
281
|
+
readonly 'help.analyze.environment': "\nEnvironment variables:\n GITNEXUS_NO_GITIGNORE=1 Skip .gitignore parsing (still reads .gitnexusignore)\n GITNEXUS_MAX_FILE_SIZE=N Override large-file skip threshold (KB). Default 512, max 32768.\n GITNEXUS_STORAGE_PATH=/absolute/index Complete external index directory. Preserves the existing configuration semantics and overrides GITNEXUS_STORAGE_ROOT when both are set.\n GITNEXUS_STORAGE_ROOT=/absolute/root External index root; each repository uses an isolated <repo-basename>-<canonical-path-hash>/ slot.\n GITNEXUS_CONTENT_RETENTION=full Source-text retention profile: full, symbol, or none. Default full.\n GITNEXUS_ANALYZER_IDENTITY_CACHE_DIR=/absolute/protected/dir Operator-trusted persistent analyzer identity cache; must pre-exist, be outside package/build roots, and contain no symlink/junction components.\n GITNEXUS_WORKER_SUB_BATCH_TIMEOUT_MS=N Worker idle timeout in milliseconds. Default 30000.\n GITNEXUS_WAL_CHECKPOINT_THRESHOLD=N LadybugDB WAL auto-checkpoint threshold in bytes (default 67108864 = 64 MiB; -1 keeps Ladybug stock ~16 MiB).\n GITNEXUS_WORKER_SUB_BATCH_MAX_BYTES=N Worker job byte budget. Default 8388608.\n GITNEXUS_WORKER_POOL_SIZE=N Parse worker count override. Default cores-1 capped at 16.\n GITNEXUS_PARSE_CHUNK_CONCURRENCY=N Concurrent in-flight parse chunks. Default 2.\n GITNEXUS_WORKER_MAX_RESPAWNS_PER_SLOT=N Max replacement spawns per slot before drop. Default 3.\n GITNEXUS_WORKER_MAX_CUMULATIVE_TIMEOUT_MS=N Total retry wall-time per job. Default 5x sub-batch timeout.\n GITNEXUS_WORKER_CONSECUTIVE_FAILURE_THRESHOLD=N Per-slot deaths to trip circuit breaker. Default max(3, poolSize).\n GITNEXUS_WORKER_SHUTDOWN_DRAIN_MS=N Max wait at pool shutdown for a retired worker still inside native code (terminated at its next safe point instead of aborting the process). Default 30000.\n GITNEXUS_CPP_CAPTURE_BUDGET_MS=N Per-file wall-clock budget for C++ capture extraction; on breach the file keeps partial captures with a warning. Default 20000.\n GITNEXUS_EMBEDDING_THREADS=N Limit local ONNX CPU threads for --embeddings.\n GITNEXUS_EMBEDDING_RETRY_TIMEOUTS=1 Retry per-attempt HTTP embedding timeouts through GITNEXUS_EMBEDDING_MAX_ATTEMPTS (default off; timeouts stay terminal).\n GITNEXUS_SEMANTIC_EXACT_SCAN_LIMIT=N Max embedding chunks for exact-scan fallback. Default 10000.\n GITNEXUS_VECTOR_MAX_DISTANCE=N Max accepted semantic/vector cosine distance (0 < N <= 2; higher values clamp to 2). Default 0.6 for MCP, 0.5 elsewhere.\n\nFlags override the corresponding env vars when both are provided.\n\nTip: `.gitnexusignore` supports `.gitignore`-style negation. Add e.g.\n `!__tests__/` to index a directory that is auto-filtered by default (#771).";
|
|
282
282
|
};
|
package/dist/cli/i18n/en.js
CHANGED
|
@@ -280,5 +280,5 @@ export const en = {
|
|
|
280
280
|
'help.option.group.contracts.repo': 'Filter by repo',
|
|
281
281
|
'help.option.group.contracts.unmatched': 'Show only unmatched contracts',
|
|
282
282
|
'help.identityCache.environment': '\nAnalyzer identity cache:\n GITNEXUS_ANALYZER_IDENTITY_CACHE_DIR=/absolute/protected/dir\n Operator-trusted persistent cache for warm cross-process status. The directory must pre-exist, be outside the GitNexus package/build roots, and contain no symlink or junction components. Defaults remain fail-closed on platforms without POSIX ownership APIs.',
|
|
283
|
-
'help.analyze.environment': '\nEnvironment variables:\n GITNEXUS_NO_GITIGNORE=1 Skip .gitignore parsing (still reads .gitnexusignore)\n GITNEXUS_MAX_FILE_SIZE=N Override large-file skip threshold (KB). Default 512, max 32768.\n GITNEXUS_ANALYZER_IDENTITY_CACHE_DIR=/absolute/protected/dir Operator-trusted persistent analyzer identity cache; must pre-exist, be outside package/build roots, and contain no symlink/junction components.\n GITNEXUS_WORKER_SUB_BATCH_TIMEOUT_MS=N Worker idle timeout in milliseconds. Default 30000.\n GITNEXUS_WAL_CHECKPOINT_THRESHOLD=N LadybugDB WAL auto-checkpoint threshold in bytes (default 67108864 = 64 MiB; -1 keeps Ladybug stock ~16 MiB).\n GITNEXUS_WORKER_SUB_BATCH_MAX_BYTES=N Worker job byte budget. Default 8388608.\n GITNEXUS_WORKER_POOL_SIZE=N Parse worker count override. Default cores-1 capped at 16.\n GITNEXUS_PARSE_CHUNK_CONCURRENCY=N Concurrent in-flight parse chunks. Default 2.\n GITNEXUS_WORKER_MAX_RESPAWNS_PER_SLOT=N Max replacement spawns per slot before drop. Default 3.\n GITNEXUS_WORKER_MAX_CUMULATIVE_TIMEOUT_MS=N Total retry wall-time per job. Default 5x sub-batch timeout.\n GITNEXUS_WORKER_CONSECUTIVE_FAILURE_THRESHOLD=N Per-slot deaths to trip circuit breaker. Default max(3, poolSize).\n GITNEXUS_WORKER_SHUTDOWN_DRAIN_MS=N Max wait at pool shutdown for a retired worker still inside native code (terminated at its next safe point instead of aborting the process). Default 30000.\n GITNEXUS_CPP_CAPTURE_BUDGET_MS=N Per-file wall-clock budget for C++ capture extraction; on breach the file keeps partial captures with a warning. Default 20000.\n GITNEXUS_EMBEDDING_THREADS=N Limit local ONNX CPU threads for --embeddings.\n GITNEXUS_EMBEDDING_RETRY_TIMEOUTS=1 Retry per-attempt HTTP embedding timeouts through GITNEXUS_EMBEDDING_MAX_ATTEMPTS (default off; timeouts stay terminal).\n GITNEXUS_SEMANTIC_EXACT_SCAN_LIMIT=N Max embedding chunks for exact-scan fallback. Default 10000.\n GITNEXUS_VECTOR_MAX_DISTANCE=N Max accepted semantic/vector cosine distance (0 < N <= 2; higher values clamp to 2). Default 0.6 for MCP, 0.5 elsewhere.\n\nFlags override the corresponding env vars when both are provided.\n\nTip: `.gitnexusignore` supports `.gitignore`-style negation. Add e.g.\n `!__tests__/` to index a directory that is auto-filtered by default (#771).',
|
|
283
|
+
'help.analyze.environment': '\nEnvironment variables:\n GITNEXUS_NO_GITIGNORE=1 Skip .gitignore parsing (still reads .gitnexusignore)\n GITNEXUS_MAX_FILE_SIZE=N Override large-file skip threshold (KB). Default 512, max 32768.\n GITNEXUS_STORAGE_PATH=/absolute/index Complete external index directory. Preserves the existing configuration semantics and overrides GITNEXUS_STORAGE_ROOT when both are set.\n GITNEXUS_STORAGE_ROOT=/absolute/root External index root; each repository uses an isolated <repo-basename>-<canonical-path-hash>/ slot.\n GITNEXUS_CONTENT_RETENTION=full Source-text retention profile: full, symbol, or none. Default full.\n GITNEXUS_ANALYZER_IDENTITY_CACHE_DIR=/absolute/protected/dir Operator-trusted persistent analyzer identity cache; must pre-exist, be outside package/build roots, and contain no symlink/junction components.\n GITNEXUS_WORKER_SUB_BATCH_TIMEOUT_MS=N Worker idle timeout in milliseconds. Default 30000.\n GITNEXUS_WAL_CHECKPOINT_THRESHOLD=N LadybugDB WAL auto-checkpoint threshold in bytes (default 67108864 = 64 MiB; -1 keeps Ladybug stock ~16 MiB).\n GITNEXUS_WORKER_SUB_BATCH_MAX_BYTES=N Worker job byte budget. Default 8388608.\n GITNEXUS_WORKER_POOL_SIZE=N Parse worker count override. Default cores-1 capped at 16.\n GITNEXUS_PARSE_CHUNK_CONCURRENCY=N Concurrent in-flight parse chunks. Default 2.\n GITNEXUS_WORKER_MAX_RESPAWNS_PER_SLOT=N Max replacement spawns per slot before drop. Default 3.\n GITNEXUS_WORKER_MAX_CUMULATIVE_TIMEOUT_MS=N Total retry wall-time per job. Default 5x sub-batch timeout.\n GITNEXUS_WORKER_CONSECUTIVE_FAILURE_THRESHOLD=N Per-slot deaths to trip circuit breaker. Default max(3, poolSize).\n GITNEXUS_WORKER_SHUTDOWN_DRAIN_MS=N Max wait at pool shutdown for a retired worker still inside native code (terminated at its next safe point instead of aborting the process). Default 30000.\n GITNEXUS_CPP_CAPTURE_BUDGET_MS=N Per-file wall-clock budget for C++ capture extraction; on breach the file keeps partial captures with a warning. Default 20000.\n GITNEXUS_EMBEDDING_THREADS=N Limit local ONNX CPU threads for --embeddings.\n GITNEXUS_EMBEDDING_RETRY_TIMEOUTS=1 Retry per-attempt HTTP embedding timeouts through GITNEXUS_EMBEDDING_MAX_ATTEMPTS (default off; timeouts stay terminal).\n GITNEXUS_SEMANTIC_EXACT_SCAN_LIMIT=N Max embedding chunks for exact-scan fallback. Default 10000.\n GITNEXUS_VECTOR_MAX_DISTANCE=N Max accepted semantic/vector cosine distance (0 < N <= 2; higher values clamp to 2). Default 0.6 for MCP, 0.5 elsewhere.\n\nFlags override the corresponding env vars when both are provided.\n\nTip: `.gitnexusignore` supports `.gitignore`-style negation. Add e.g.\n `!__tests__/` to index a directory that is auto-filtered by default (#771).',
|
|
284
284
|
};
|
|
@@ -279,7 +279,7 @@ export declare const cliResources: {
|
|
|
279
279
|
readonly 'help.option.group.contracts.repo': "Filter by repo";
|
|
280
280
|
readonly 'help.option.group.contracts.unmatched': "Show only unmatched contracts";
|
|
281
281
|
readonly 'help.identityCache.environment': "\nAnalyzer identity cache:\n GITNEXUS_ANALYZER_IDENTITY_CACHE_DIR=/absolute/protected/dir\n Operator-trusted persistent cache for warm cross-process status. The directory must pre-exist, be outside the GitNexus package/build roots, and contain no symlink or junction components. Defaults remain fail-closed on platforms without POSIX ownership APIs.";
|
|
282
|
-
readonly 'help.analyze.environment': "\nEnvironment variables:\n GITNEXUS_NO_GITIGNORE=1 Skip .gitignore parsing (still reads .gitnexusignore)\n GITNEXUS_MAX_FILE_SIZE=N Override large-file skip threshold (KB). Default 512, max 32768.\n GITNEXUS_ANALYZER_IDENTITY_CACHE_DIR=/absolute/protected/dir Operator-trusted persistent analyzer identity cache; must pre-exist, be outside package/build roots, and contain no symlink/junction components.\n GITNEXUS_WORKER_SUB_BATCH_TIMEOUT_MS=N Worker idle timeout in milliseconds. Default 30000.\n GITNEXUS_WAL_CHECKPOINT_THRESHOLD=N LadybugDB WAL auto-checkpoint threshold in bytes (default 67108864 = 64 MiB; -1 keeps Ladybug stock ~16 MiB).\n GITNEXUS_WORKER_SUB_BATCH_MAX_BYTES=N Worker job byte budget. Default 8388608.\n GITNEXUS_WORKER_POOL_SIZE=N Parse worker count override. Default cores-1 capped at 16.\n GITNEXUS_PARSE_CHUNK_CONCURRENCY=N Concurrent in-flight parse chunks. Default 2.\n GITNEXUS_WORKER_MAX_RESPAWNS_PER_SLOT=N Max replacement spawns per slot before drop. Default 3.\n GITNEXUS_WORKER_MAX_CUMULATIVE_TIMEOUT_MS=N Total retry wall-time per job. Default 5x sub-batch timeout.\n GITNEXUS_WORKER_CONSECUTIVE_FAILURE_THRESHOLD=N Per-slot deaths to trip circuit breaker. Default max(3, poolSize).\n GITNEXUS_WORKER_SHUTDOWN_DRAIN_MS=N Max wait at pool shutdown for a retired worker still inside native code (terminated at its next safe point instead of aborting the process). Default 30000.\n GITNEXUS_CPP_CAPTURE_BUDGET_MS=N Per-file wall-clock budget for C++ capture extraction; on breach the file keeps partial captures with a warning. Default 20000.\n GITNEXUS_EMBEDDING_THREADS=N Limit local ONNX CPU threads for --embeddings.\n GITNEXUS_EMBEDDING_RETRY_TIMEOUTS=1 Retry per-attempt HTTP embedding timeouts through GITNEXUS_EMBEDDING_MAX_ATTEMPTS (default off; timeouts stay terminal).\n GITNEXUS_SEMANTIC_EXACT_SCAN_LIMIT=N Max embedding chunks for exact-scan fallback. Default 10000.\n GITNEXUS_VECTOR_MAX_DISTANCE=N Max accepted semantic/vector cosine distance (0 < N <= 2; higher values clamp to 2). Default 0.6 for MCP, 0.5 elsewhere.\n\nFlags override the corresponding env vars when both are provided.\n\nTip: `.gitnexusignore` supports `.gitignore`-style negation. Add e.g.\n `!__tests__/` to index a directory that is auto-filtered by default (#771).";
|
|
282
|
+
readonly 'help.analyze.environment': "\nEnvironment variables:\n GITNEXUS_NO_GITIGNORE=1 Skip .gitignore parsing (still reads .gitnexusignore)\n GITNEXUS_MAX_FILE_SIZE=N Override large-file skip threshold (KB). Default 512, max 32768.\n GITNEXUS_STORAGE_PATH=/absolute/index Complete external index directory. Preserves the existing configuration semantics and overrides GITNEXUS_STORAGE_ROOT when both are set.\n GITNEXUS_STORAGE_ROOT=/absolute/root External index root; each repository uses an isolated <repo-basename>-<canonical-path-hash>/ slot.\n GITNEXUS_CONTENT_RETENTION=full Source-text retention profile: full, symbol, or none. Default full.\n GITNEXUS_ANALYZER_IDENTITY_CACHE_DIR=/absolute/protected/dir Operator-trusted persistent analyzer identity cache; must pre-exist, be outside package/build roots, and contain no symlink/junction components.\n GITNEXUS_WORKER_SUB_BATCH_TIMEOUT_MS=N Worker idle timeout in milliseconds. Default 30000.\n GITNEXUS_WAL_CHECKPOINT_THRESHOLD=N LadybugDB WAL auto-checkpoint threshold in bytes (default 67108864 = 64 MiB; -1 keeps Ladybug stock ~16 MiB).\n GITNEXUS_WORKER_SUB_BATCH_MAX_BYTES=N Worker job byte budget. Default 8388608.\n GITNEXUS_WORKER_POOL_SIZE=N Parse worker count override. Default cores-1 capped at 16.\n GITNEXUS_PARSE_CHUNK_CONCURRENCY=N Concurrent in-flight parse chunks. Default 2.\n GITNEXUS_WORKER_MAX_RESPAWNS_PER_SLOT=N Max replacement spawns per slot before drop. Default 3.\n GITNEXUS_WORKER_MAX_CUMULATIVE_TIMEOUT_MS=N Total retry wall-time per job. Default 5x sub-batch timeout.\n GITNEXUS_WORKER_CONSECUTIVE_FAILURE_THRESHOLD=N Per-slot deaths to trip circuit breaker. Default max(3, poolSize).\n GITNEXUS_WORKER_SHUTDOWN_DRAIN_MS=N Max wait at pool shutdown for a retired worker still inside native code (terminated at its next safe point instead of aborting the process). Default 30000.\n GITNEXUS_CPP_CAPTURE_BUDGET_MS=N Per-file wall-clock budget for C++ capture extraction; on breach the file keeps partial captures with a warning. Default 20000.\n GITNEXUS_EMBEDDING_THREADS=N Limit local ONNX CPU threads for --embeddings.\n GITNEXUS_EMBEDDING_RETRY_TIMEOUTS=1 Retry per-attempt HTTP embedding timeouts through GITNEXUS_EMBEDDING_MAX_ATTEMPTS (default off; timeouts stay terminal).\n GITNEXUS_SEMANTIC_EXACT_SCAN_LIMIT=N Max embedding chunks for exact-scan fallback. Default 10000.\n GITNEXUS_VECTOR_MAX_DISTANCE=N Max accepted semantic/vector cosine distance (0 < N <= 2; higher values clamp to 2). Default 0.6 for MCP, 0.5 elsewhere.\n\nFlags override the corresponding env vars when both are provided.\n\nTip: `.gitnexusignore` supports `.gitignore`-style negation. Add e.g.\n `!__tests__/` to index a directory that is auto-filtered by default (#771).";
|
|
283
283
|
};
|
|
284
284
|
readonly 'zh-CN': {
|
|
285
285
|
'common.notIndexed': string;
|
package/dist/cli/i18n/zh-CN.js
CHANGED
|
@@ -278,5 +278,5 @@ export const zhCN = {
|
|
|
278
278
|
'help.option.group.contracts.repo': '按仓库过滤',
|
|
279
279
|
'help.option.group.contracts.unmatched': '仅显示未匹配契约',
|
|
280
280
|
'help.identityCache.environment': '\n分析器身份缓存:\n GITNEXUS_ANALYZER_IDENTITY_CACHE_DIR=/absolute/protected/dir\n 由操作员明确信任的持久缓存,用于跨进程快速查询状态。目录必须预先存在、位于 GitNexus 包/构建根目录之外,且路径中不得包含符号链接或 junction。缺少 POSIX 所有权 API 的平台默认保持故障关闭。',
|
|
281
|
-
'help.analyze.environment': '\n环境变量:\n GITNEXUS_NO_GITIGNORE=1 跳过 .gitignore 解析(仍读取 .gitnexusignore)\n GITNEXUS_MAX_FILE_SIZE=N 覆盖大文件跳过阈值(KB)。默认 512,最大 32768。\n GITNEXUS_ANALYZER_IDENTITY_CACHE_DIR=/absolute/protected/dir 由操作员明确信任的持久分析器身份缓存;目录必须预先存在、位于包/构建根目录之外,且路径中不得包含符号链接或 junction。\n GITNEXUS_WORKER_SUB_BATCH_TIMEOUT_MS=N Worker 空闲超时(毫秒)。默认 30000。\n GITNEXUS_WAL_CHECKPOINT_THRESHOLD=N LadybugDB WAL 自动 checkpoint 阈值(字节,默认 67108864 = 64 MiB;-1 保持 Ladybug 默认约 16 MiB)。\n GITNEXUS_WORKER_SUB_BATCH_MAX_BYTES=N Worker 作业字节预算。默认 8388608。\n GITNEXUS_WORKER_POOL_SIZE=N 解析 worker 数量覆盖值。默认 cores-1,最多 16。\n GITNEXUS_PARSE_CHUNK_CONCURRENCY=N 并发进行中的解析分块数。默认 2。\n GITNEXUS_WORKER_MAX_RESPAWNS_PER_SLOT=N 每个 slot 丢弃前允许的最大替换进程数。默认 3。\n GITNEXUS_WORKER_MAX_CUMULATIVE_TIMEOUT_MS=N 每个作业的总重试墙钟时间。默认 5 倍子批次超时。\n GITNEXUS_WORKER_CONSECUTIVE_FAILURE_THRESHOLD=N 每个 slot 触发熔断的死亡次数。默认 max(3, poolSize)。\n GITNEXUS_WORKER_SHUTDOWN_DRAIN_MS=N 线程池关闭时等待仍在原生代码中的已退役 worker 的最长时间(到达安全点后再终止,避免进程级 abort)。默认 30000。\n GITNEXUS_CPP_CAPTURE_BUDGET_MS=N C++ 捕获提取的每文件墙钟预算;超出后该文件保留部分捕获并输出警告。默认 20000。\n GITNEXUS_EMBEDDING_THREADS=N 限制 --embeddings 的本地 ONNX CPU 线程数。\n GITNEXUS_EMBEDDING_RETRY_TIMEOUTS=1 将单次 HTTP 嵌入超时纳入 GITNEXUS_EMBEDDING_MAX_ATTEMPTS 重试(默认关闭,超时仍为终止错误)。\n GITNEXUS_SEMANTIC_EXACT_SCAN_LIMIT=N exact-scan 回退的最大嵌入分块数。默认 10000。\n GITNEXUS_VECTOR_MAX_DISTANCE=N 语义/向量搜索接受的最大余弦距离(0 < N <= 2;超出则钳制为 2)。MCP 默认 0.6,其他路径默认 0.5。\n\n当参数和对应环境变量同时提供时,参数优先。\n\n提示:`.gitnexusignore` 支持 `.gitignore` 风格的取反。比如添加\n `!__tests__/` 可以索引默认自动过滤的目录(#771)。',
|
|
281
|
+
'help.analyze.environment': '\n环境变量:\n GITNEXUS_NO_GITIGNORE=1 跳过 .gitignore 解析(仍读取 .gitnexusignore)\n GITNEXUS_MAX_FILE_SIZE=N 覆盖大文件跳过阈值(KB)。默认 512,最大 32768。\n GITNEXUS_STORAGE_PATH=/absolute/index 完整外部索引目录。保留既有配置语义;与 GITNEXUS_STORAGE_ROOT 同时设置时优先使用。\n GITNEXUS_STORAGE_ROOT=/absolute/root 外部索引根目录;每个仓库使用独立的 <仓库名>-<规范路径哈希>/ 子目录。\n GITNEXUS_CONTENT_RETENTION=full 源码文本保留策略:full、symbol 或 none。默认 full。\n GITNEXUS_ANALYZER_IDENTITY_CACHE_DIR=/absolute/protected/dir 由操作员明确信任的持久分析器身份缓存;目录必须预先存在、位于包/构建根目录之外,且路径中不得包含符号链接或 junction。\n GITNEXUS_WORKER_SUB_BATCH_TIMEOUT_MS=N Worker 空闲超时(毫秒)。默认 30000。\n GITNEXUS_WAL_CHECKPOINT_THRESHOLD=N LadybugDB WAL 自动 checkpoint 阈值(字节,默认 67108864 = 64 MiB;-1 保持 Ladybug 默认约 16 MiB)。\n GITNEXUS_WORKER_SUB_BATCH_MAX_BYTES=N Worker 作业字节预算。默认 8388608。\n GITNEXUS_WORKER_POOL_SIZE=N 解析 worker 数量覆盖值。默认 cores-1,最多 16。\n GITNEXUS_PARSE_CHUNK_CONCURRENCY=N 并发进行中的解析分块数。默认 2。\n GITNEXUS_WORKER_MAX_RESPAWNS_PER_SLOT=N 每个 slot 丢弃前允许的最大替换进程数。默认 3。\n GITNEXUS_WORKER_MAX_CUMULATIVE_TIMEOUT_MS=N 每个作业的总重试墙钟时间。默认 5 倍子批次超时。\n GITNEXUS_WORKER_CONSECUTIVE_FAILURE_THRESHOLD=N 每个 slot 触发熔断的死亡次数。默认 max(3, poolSize)。\n GITNEXUS_WORKER_SHUTDOWN_DRAIN_MS=N 线程池关闭时等待仍在原生代码中的已退役 worker 的最长时间(到达安全点后再终止,避免进程级 abort)。默认 30000。\n GITNEXUS_CPP_CAPTURE_BUDGET_MS=N C++ 捕获提取的每文件墙钟预算;超出后该文件保留部分捕获并输出警告。默认 20000。\n GITNEXUS_EMBEDDING_THREADS=N 限制 --embeddings 的本地 ONNX CPU 线程数。\n GITNEXUS_EMBEDDING_RETRY_TIMEOUTS=1 将单次 HTTP 嵌入超时纳入 GITNEXUS_EMBEDDING_MAX_ATTEMPTS 重试(默认关闭,超时仍为终止错误)。\n GITNEXUS_SEMANTIC_EXACT_SCAN_LIMIT=N exact-scan 回退的最大嵌入分块数。默认 10000。\n GITNEXUS_VECTOR_MAX_DISTANCE=N 语义/向量搜索接受的最大余弦距离(0 < N <= 2;超出则钳制为 2)。MCP 默认 0.6,其他路径默认 0.5。\n\n当参数和对应环境变量同时提供时,参数优先。\n\n提示:`.gitnexusignore` 支持 `.gitignore` 风格的取反。比如添加\n `!__tests__/` 可以索引默认自动过滤的目录(#771)。',
|
|
282
282
|
};
|
package/dist/cli/index-repo.js
CHANGED
|
@@ -14,8 +14,9 @@
|
|
|
14
14
|
*/
|
|
15
15
|
import path from 'path';
|
|
16
16
|
import fs from 'fs/promises';
|
|
17
|
-
import {
|
|
17
|
+
import { loadMeta, saveMeta, ensureGitNexusIgnored, registerRepo, } from '../storage/repo-manager.js';
|
|
18
18
|
import { getGitRoot, getRemoteUrl, isGitRepo } from '../storage/git.js';
|
|
19
|
+
import { getIndexStorageRequirements, requireStoragePath, StorageRequirementError, } from '../storage/storage-resolver.js';
|
|
19
20
|
export const indexCommand = async (inputPathParts, options) => {
|
|
20
21
|
console.log('\n GitNexus Index\n');
|
|
21
22
|
const inputPath = inputPathParts?.length ? inputPathParts.join(' ') : undefined;
|
|
@@ -53,42 +54,40 @@ export const indexCommand = async (inputPathParts, options) => {
|
|
|
53
54
|
process.exitCode = 1;
|
|
54
55
|
return;
|
|
55
56
|
}
|
|
56
|
-
|
|
57
|
-
// ── Verify index exists (metadata file, legacy metadata, or restorable DB) ─
|
|
58
|
-
let hasMetadataIndex = false;
|
|
59
|
-
let hasLegacyIndex = false;
|
|
60
|
-
let hasLbugIndex = false;
|
|
57
|
+
let storagePath;
|
|
61
58
|
try {
|
|
62
|
-
await
|
|
63
|
-
hasMetadataIndex = true;
|
|
59
|
+
storagePath = await requireStoragePath(repoPath, getIndexStorageRequirements(!!options?.force));
|
|
64
60
|
}
|
|
65
|
-
catch {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
61
|
+
catch (error) {
|
|
62
|
+
if (!(error instanceof StorageRequirementError)) {
|
|
63
|
+
console.log(` ${error instanceof Error ? error.message : String(error)}\n`);
|
|
64
|
+
process.exitCode = 1;
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
const inspection = error.inspection;
|
|
68
|
+
if (inspection.state === 'missing' || inspection.state === 'empty') {
|
|
69
|
+
console.log(` No GitNexus index found.`);
|
|
70
|
+
console.log(` Expected gitnexus.json, .gitnexus/meta.json, or LadybugDB at: ${inspection.storagePath}`);
|
|
71
|
+
console.log(' Run `gitnexus analyze` to build the index first.\n');
|
|
72
|
+
}
|
|
73
|
+
else if (inspection.state === 'unowned' && !options?.force) {
|
|
74
|
+
console.log(` gitnexus.json or .gitnexus/meta.json is missing.`);
|
|
75
|
+
console.log(' Use --force to register anyway (stats will be empty),');
|
|
76
|
+
console.log(' or run `gitnexus analyze` to rebuild properly.\n');
|
|
77
|
+
}
|
|
78
|
+
else if (!inspection.hasCodeIndexDB) {
|
|
79
|
+
console.log(` Index exists but contains no LadybugDB database.`);
|
|
80
|
+
console.log(' Run `gitnexus analyze` to build the index.\n');
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
console.log(` ${error.message}\n`);
|
|
84
|
+
}
|
|
87
85
|
process.exitCode = 1;
|
|
88
86
|
return;
|
|
89
87
|
}
|
|
90
88
|
// ── Load or reconstruct meta ──────────────────────────────────────
|
|
91
89
|
let meta = await loadMeta(storagePath);
|
|
90
|
+
let reconstructedMeta = false;
|
|
92
91
|
if (!meta) {
|
|
93
92
|
if (!options?.force) {
|
|
94
93
|
console.log(` gitnexus.json or .gitnexus/meta.json is missing.`);
|
|
@@ -100,9 +99,25 @@ export const indexCommand = async (inputPathParts, options) => {
|
|
|
100
99
|
// --force: build a minimal meta so the repo can be registered
|
|
101
100
|
meta = {
|
|
102
101
|
repoPath,
|
|
102
|
+
storagePath,
|
|
103
103
|
lastCommit: '',
|
|
104
104
|
indexedAt: new Date().toISOString(),
|
|
105
105
|
};
|
|
106
|
+
reconstructedMeta = true;
|
|
107
|
+
}
|
|
108
|
+
// `index --force` is the explicit adoption path for an existing external
|
|
109
|
+
// database whose legacy metadata predates storagePath binding, and for a
|
|
110
|
+
// repository-local slot whose metadata still names another checkout.
|
|
111
|
+
if (options?.force) {
|
|
112
|
+
const adoptedRepoPath = path.resolve(repoPath);
|
|
113
|
+
const adoptedStoragePath = path.resolve(storagePath);
|
|
114
|
+
const ownershipChanged = path.resolve(meta.repoPath) !== adoptedRepoPath ||
|
|
115
|
+
meta.storagePath === undefined ||
|
|
116
|
+
path.resolve(meta.storagePath) !== adoptedStoragePath;
|
|
117
|
+
if (ownershipChanged) {
|
|
118
|
+
meta = { ...meta, repoPath: adoptedRepoPath, storagePath: adoptedStoragePath };
|
|
119
|
+
reconstructedMeta = true;
|
|
120
|
+
}
|
|
106
121
|
}
|
|
107
122
|
// ── Register in global registry ───────────────────────────────────
|
|
108
123
|
// Refresh the on-disk meta with a freshly captured `remoteUrl` if
|
|
@@ -112,8 +127,11 @@ export const indexCommand = async (inputPathParts, options) => {
|
|
|
112
127
|
if (!meta.remoteUrl && isGitRepo(repoPath)) {
|
|
113
128
|
meta.remoteUrl = getRemoteUrl(repoPath);
|
|
114
129
|
}
|
|
115
|
-
|
|
116
|
-
|
|
130
|
+
if (reconstructedMeta) {
|
|
131
|
+
await saveMeta(storagePath, meta);
|
|
132
|
+
}
|
|
133
|
+
await registerRepo(repoPath, meta, { storagePath });
|
|
134
|
+
await ensureGitNexusIgnored(repoPath, storagePath);
|
|
117
135
|
const projectName = path.basename(repoPath);
|
|
118
136
|
const { stats } = meta;
|
|
119
137
|
console.log(` Repository registered: ${projectName}`);
|
package/dist/cli/index.js
CHANGED
|
@@ -173,7 +173,8 @@ program
|
|
|
173
173
|
.action(createLazyAction(() => import('./list.js'), 'listCommand'));
|
|
174
174
|
program
|
|
175
175
|
.command('status')
|
|
176
|
-
.description('Show index status for current repo')
|
|
176
|
+
.description('Show index status for the current repo or a registered index')
|
|
177
|
+
.option('-r, --repo <name>', 'Registered repository alias or path (works after checkout removal)')
|
|
177
178
|
.option('--json', 'Emit machine-readable index and analyzer provenance')
|
|
178
179
|
.addHelpText('after', () => t('help.identityCache.environment'))
|
|
179
180
|
.action(createLazyAction(() => import('./status.js'), 'statusCommand'));
|
|
@@ -258,7 +259,7 @@ program
|
|
|
258
259
|
.option('-c, --context <text>', 'Task context to improve ranking')
|
|
259
260
|
.option('-g, --goal <text>', 'What you want to find')
|
|
260
261
|
.option('-l, --limit <n>', 'Max processes to return (default: 5)')
|
|
261
|
-
.option('--content', 'Include
|
|
262
|
+
.option('--content', 'Include retained symbol source text (reports availability when disabled by retention)')
|
|
262
263
|
.action(createLbugLazyAction(() => import('./tool.js'), 'queryCommand'));
|
|
263
264
|
program
|
|
264
265
|
.command('context [name]')
|
|
@@ -268,7 +269,7 @@ program
|
|
|
268
269
|
.option('-u, --uid <uid>', 'Direct symbol UID (zero-ambiguity lookup)')
|
|
269
270
|
.option('-f, --file <path>', 'File path to disambiguate common names')
|
|
270
271
|
.option('-l, --limit <n>', 'Max callers/callees/processes to return')
|
|
271
|
-
.option('--content', 'Include
|
|
272
|
+
.option('--content', 'Include retained symbol source text (reports availability when disabled by retention)')
|
|
272
273
|
.action(createLbugLazyAction(() => import('./tool.js'), 'contextCommand'));
|
|
273
274
|
program
|
|
274
275
|
.command('impact [target]')
|
package/dist/cli/publish.js
CHANGED
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
import path from 'path';
|
|
24
24
|
import { UNDERSTAND_QUICKLY_DISPATCH_URL, UNDERSTAND_QUICKLY_TOKEN_ENV, buildUqDispatchPayload, isValidOwnerRepo, parseOwnerRepoFromRemote, } from '../_shared/index.js';
|
|
25
25
|
import { getGitRoot, getRemoteOriginUrl, getCurrentCommit } from '../storage/git.js';
|
|
26
|
-
import {
|
|
26
|
+
import { requireStoragePath, STATUS_STORAGE_REQUIREMENTS, StorageRequirementError, isUnusableIndexInspection, } from '../storage/storage-resolver.js';
|
|
27
27
|
import { cliInfo, cliError } from './cli-message.js';
|
|
28
28
|
const REGISTER_HINT = 'Register your repo once with: npx @understand-quickly/cli add\n' +
|
|
29
29
|
'Or use the wizard: https://looptech-ai.github.io/understand-quickly/add.html';
|
|
@@ -69,8 +69,19 @@ export const publishCommand = async (inputPath, options = {}) => {
|
|
|
69
69
|
// Publishing without an index is almost always a mistake — the
|
|
70
70
|
// registry's nightly sync would fetch a stale or missing graph file
|
|
71
71
|
// and mark the entry `missing`. Refuse loudly with a fix-it hint.
|
|
72
|
-
|
|
73
|
-
|
|
72
|
+
try {
|
|
73
|
+
await requireStoragePath(repoPath, STATUS_STORAGE_REQUIREMENTS);
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
if (!(error instanceof StorageRequirementError))
|
|
77
|
+
throw error;
|
|
78
|
+
const inspection = error.inspection;
|
|
79
|
+
if (!isUnusableIndexInspection(inspection)) {
|
|
80
|
+
cliError(`[understand-quickly] ${error.message}`);
|
|
81
|
+
process.exitCode = 1;
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
cliError(`[understand-quickly] no usable GitNexus index found for ${repoPath}.\n` +
|
|
74
85
|
'Run `gitnexus analyze` first, then re-run `gitnexus publish`.');
|
|
75
86
|
process.exitCode = 1;
|
|
76
87
|
return;
|
package/dist/cli/remove.js
CHANGED
|
@@ -32,7 +32,8 @@ import fs from 'fs/promises';
|
|
|
32
32
|
import { logger } from '../core/logger.js';
|
|
33
33
|
import { cliError } from './cli-message.js';
|
|
34
34
|
import { t } from './i18n/index.js';
|
|
35
|
-
import { readRegistry, resolveRegistryEntry,
|
|
35
|
+
import { readRegistry, resolveRegistryEntry, unregisterRepo, RegistryNotFoundError, RegistryAmbiguousTargetError, } from '../storage/repo-manager.js';
|
|
36
|
+
import { requireDeletableStoragePath, StorageDeletionError } from '../storage/storage-resolver.js';
|
|
36
37
|
export const removeCommand = async (target, options) => {
|
|
37
38
|
// Read the registry snapshot once and pass it to the resolver — this
|
|
38
39
|
// lets us render the "before" state in the dry-run path without a
|
|
@@ -68,19 +69,14 @@ export const removeCommand = async (target, options) => {
|
|
|
68
69
|
console.log(`\n${t('common.runForceConfirm')}`);
|
|
69
70
|
return;
|
|
70
71
|
}
|
|
71
|
-
//
|
|
72
|
-
//
|
|
73
|
-
|
|
74
|
-
// user-writable, so a corrupted or hand-edited entry could point
|
|
75
|
-
// storagePath at the repo root, an empty string (→ cwd), a parent
|
|
76
|
-
// dir, or anywhere else; `fs.rm(recursive: true, force: true)` on
|
|
77
|
-
// any of those would be a runtime disaster. Bail before touching
|
|
78
|
-
// disk, with an actionable hint for recovering a broken registry.
|
|
72
|
+
// Validate immediately before deletion. `--force` skips confirmation only;
|
|
73
|
+
// it does not bypass the ownership and dangerous-path checks.
|
|
74
|
+
let storagePath;
|
|
79
75
|
try {
|
|
80
|
-
|
|
76
|
+
storagePath = await requireDeletableStoragePath(entry);
|
|
81
77
|
}
|
|
82
78
|
catch (err) {
|
|
83
|
-
if (err instanceof
|
|
79
|
+
if (err instanceof StorageDeletionError) {
|
|
84
80
|
cliError(t('common.error', { message: err.message }));
|
|
85
81
|
process.exit(1);
|
|
86
82
|
}
|
|
@@ -92,7 +88,7 @@ export const removeCommand = async (target, options) => {
|
|
|
92
88
|
// orphaned — `listRegisteredRepos({ validate: true })` prunes those on
|
|
93
89
|
// next read, so the failure is self-healing.
|
|
94
90
|
try {
|
|
95
|
-
await fs.rm(
|
|
91
|
+
await fs.rm(storagePath, { recursive: true, force: true });
|
|
96
92
|
await unregisterRepo(entry.path);
|
|
97
93
|
console.log(t('remove.removed', { name: entry.name }));
|
|
98
94
|
console.log(` ${t('common.path')}: ${entry.path}`);
|
package/dist/cli/setup.js
CHANGED
|
@@ -376,6 +376,7 @@ const HOOK_HELPERS = [
|
|
|
376
376
|
'hook-db-lock-probe.cjs',
|
|
377
377
|
'win-rm-list-json.ps1',
|
|
378
378
|
'resolve-analyze-cmd.cjs',
|
|
379
|
+
'registry-query.cjs',
|
|
379
380
|
];
|
|
380
381
|
// win-rm-list-json.ps1 is best-effort: it is read (not require()'d) by
|
|
381
382
|
// hook-db-lock-probe.cjs only on Windows, and that probe fails open when the
|
package/dist/cli/status.d.ts
CHANGED