gitnexus 1.6.13-rc.35 → 1.6.13-rc.37
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 +1 -1
- package/dist/cli/ai-context.js +11 -3
- package/dist/cli/analyze-options.d.ts +4 -0
- package/dist/cli/analyze.js +2 -0
- package/dist/cli/auto-sync.js +2 -0
- package/dist/cli/clean.d.ts +2 -0
- package/dist/cli/clean.js +95 -5
- package/dist/cli/doctor.js +7 -0
- package/dist/cli/embeddings-sync.js +9 -1
- package/dist/cli/help-i18n.js +4 -0
- package/dist/cli/i18n/en.d.ts +20 -1
- package/dist/cli/i18n/en.js +20 -1
- package/dist/cli/i18n/resources.d.ts +39 -1
- package/dist/cli/i18n/zh-CN.d.ts +19 -0
- package/dist/cli/i18n/zh-CN.js +20 -1
- package/dist/cli/index.js +8 -0
- package/dist/cli/remove.js +3 -3
- package/dist/cli/status.js +46 -0
- package/dist/core/augmentation/engine.js +4 -1
- package/dist/core/auto-sync/config.d.ts +6 -0
- package/dist/core/auto-sync/config.js +31 -6
- package/dist/core/auto-sync/index.d.ts +1 -1
- package/dist/core/auto-sync/index.js +1 -1
- package/dist/core/auto-sync/runner.d.ts +1 -1
- package/dist/core/auto-sync/runner.js +5 -6
- package/dist/core/gitnexus-rc-embeddings.d.ts +11 -0
- package/dist/core/gitnexus-rc-embeddings.js +51 -0
- package/dist/core/group/sync.js +2 -2
- package/dist/core/ingestion/class-extractors/configs/ruby.d.ts +13 -1
- package/dist/core/ingestion/class-extractors/configs/ruby.js +50 -2
- package/dist/core/ingestion/languages/ruby.js +17 -2
- package/dist/core/ingestion/tree-sitter-queries.d.ts +1 -1
- package/dist/core/ingestion/tree-sitter-queries.js +74 -0
- package/dist/core/ingestion/utils/ast-helpers.js +16 -0
- package/dist/core/run-analyze.d.ts +7 -0
- package/dist/core/run-analyze.js +127 -13
- package/dist/core/shared-store-analyze.d.ts +89 -0
- package/dist/core/shared-store-analyze.js +570 -0
- package/dist/mcp/local/local-backend.d.ts +14 -0
- package/dist/mcp/local/local-backend.js +38 -6
- package/dist/server/analyze-launch.js +27 -8
- package/dist/server/analyze-worker-ipc.d.ts +1 -1
- package/dist/server/analyze-worker-ipc.js +3 -0
- package/dist/server/api.js +39 -10
- package/dist/server/git-clone.d.ts +4 -5
- package/dist/server/git-clone.js +44 -11
- package/dist/storage/git.d.ts +13 -0
- package/dist/storage/git.js +55 -0
- package/dist/storage/index-lock.d.ts +5 -0
- package/dist/storage/index-lock.js +1 -1
- package/dist/storage/repo-manager.d.ts +21 -3
- package/dist/storage/repo-manager.js +27 -5
- package/dist/storage/repo-meta.d.ts +6 -0
- package/dist/storage/shared-store-lifecycle.d.ts +95 -0
- package/dist/storage/shared-store-lifecycle.js +393 -0
- package/dist/storage/shared-store.d.ts +65 -0
- package/dist/storage/shared-store.js +297 -0
- package/dist/storage/storage-resolver.d.ts +2 -2
- package/dist/storage/storage-resolver.js +27 -32
- package/dist/storage/storage-slot.d.ts +17 -0
- package/dist/storage/storage-slot.js +48 -0
- package/hooks/claude/registry-query.cjs +43 -6
- package/package.json +1 -1
- package/scripts/cross-platform-tests.ts +6 -0
package/README.md
CHANGED
|
@@ -367,7 +367,7 @@ projects:
|
|
|
367
367
|
- git@gitee.com:owner/repo.git
|
|
368
368
|
```
|
|
369
369
|
|
|
370
|
-
`sync_interval_minutes` must be an integer of at least `5`. `local_path` must be an absolute path without traversal; each remote is cloned below it as `host/namespace/repo`, preventing same-basename repositories from colliding. `remote_urls`
|
|
370
|
+
`sync_interval_minutes` must be an integer of at least `5`. `local_path` must be an absolute path without traversal; each remote is cloned below it as `host/namespace/repo`, preventing same-basename repositories from colliding. `remote_urls` may use SSH SCP form (`git@host:owner/repo.git`) or HTTPS (`https://host/owner/repo.git`) for github.com, gitlab.com, or gitee.com. The published CLI image includes `openssh-client` so SSH remotes can clone; mount keys and `known_hosts` yourself. An invalid `watch_config.yml` skips auto-sync immediately with the validation error. `repo_git_timeout` applies to each repo clone/pull and defaults to `10s`; a bare number such as `10` is interpreted as seconds, while `10000ms`, `10s`, and `1m` keep their explicit units. It must not exceed one hour or `sync_interval_minutes`, whichever is smaller — so a bare `600000` is rejected, because it means 600000 seconds rather than milliseconds. `analyze_timeout` applies to each isolated analysis worker and defaults to half of `sync_interval_minutes`, but it is independent of polling and may be longer, up to Node's timer limit (`2147483647ms`). A `5` minute poll with `analyze_timeout: 30m` is valid. Auto-sync analysis honors the cloned repo's `.gitnexusrc` embeddings settings; the CLI image still needs `GITNEXUS_EMBEDDING_URL` or a bind-mounted embedding stack because npm is stripped. A tick that arrives while the previous loop is active never overlaps it: ticks coalesce into one immediate follow-up run, which pulls and analyzes the newest commit. If the parent times out and leaves that worker running, the follow-up is deferred to the next interval so a leftover lock holder is not counted as a hard analyze failure. Timeout and `auto-sync stop` request safe cancellation; a worker already in native work exits after it returns to a JS-visible safe point. While waiting, auto-sync reports `cancelling` or `stopping` and keeps its ownership files so another auto-sync cannot take over. The parent waits up to 5 seconds for the worker to exit; after that it stops waiting, releases its ownership files, and leaves the worker to finish and exit on its own rather than killing it mid-write. `auto-sync stop` uses this same control path on macOS and Windows.
|
|
371
371
|
|
|
372
372
|
`pdg` is configured per project. `pdg: true` builds and maintains the full CFG, control-dependence, reaching-definition, and taint layers on both initial and incremental analyses. Auto-sync requests staged atomic incremental publication where the analyzer supports it: the old graph remains available to readers until the replacement succeeds, and analysis errors are recorded while the old graph remains intact. Unsupported paths retain the analyzer's existing in-place behavior. Untouched configs that omit `pdg` preserve the existing index mode and cannot silently strip PDG data. Do not paste `pdg: false` from this example onto an existing watch file unless you intend to drop PDG. An explicit `pdg: false` disables PDG and emits a warning before a successful rebuild removes those layers. `overwrite_local_changes` defaults to `false`; a dirty local clone is skipped with an error log, while `true` allows branch fallback to replace local changes and additionally discards untracked files and directories in the clone after checkout — ignored paths, including GitNexus's own `.gitnexus/` storage, are preserved. `max_concurrency` defaults to `1` and is capped at runtime by `floor(availableMemoryGB / 2)` with a minimum of `1`; the effective value is printed at the start of each loop. Each analysis worker's heap cap is the machine-wide cap divided by the number of repositories analyzed in parallel, so concurrent workers share one memory budget instead of each claiming the whole machine. `analyze_failure_threshold` defaults to `3`, must be at least `2`, and pauses repeated failures only for the same repo branch, commit, and requested PDG mode; a new commit, a PDG mode change, or `gitnexus auto-sync reset` clears the block and allows analysis again. Repositories are registered and added to groups by their full remote identity (`host/namespace/repo`), so repositories with the same basename remain distinct. Use `branches` to try branches in order; legacy `branch` remains supported, but the two fields cannot be set together. If all branches are unavailable or time out, watch logs an error, records the repo status, and skips that repo for the loop. Leave `group_name` empty or omit it to skip group add/sync for that project; otherwise create the group first with `gitnexus group create <name>`. `$GITNEXUS_HOME/watch/project_commit_info.txt` is for inspection only; GitNexus stores machine state separately in `$GITNEXUS_HOME/watch/auto-sync-state.json`.
|
|
373
373
|
|
package/dist/cli/ai-context.js
CHANGED
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
* AGENTS.md is the standard read by Cursor, Windsurf, OpenCode, Codex, Cline, CodeBuddy, Qoder, etc.
|
|
6
6
|
* CLAUDE.md is for Claude Code which only reads that file.
|
|
7
7
|
*/
|
|
8
|
+
import { GITNEXUS_DIR } from '../storage/storage-constants.js';
|
|
9
|
+
import { storeRootOfCheckoutSlot } from '../storage/shared-store.js';
|
|
8
10
|
import fs from 'fs/promises';
|
|
9
11
|
import path from 'path';
|
|
10
12
|
import { fileURLToPath } from 'url';
|
|
@@ -470,11 +472,17 @@ export async function generateAIContextFiles(repoPath, storagePath, projectName,
|
|
|
470
472
|
// CLI and hooks already share; failure to copy is non-fatal (docs carry a
|
|
471
473
|
// bootstrap fallback). `runnerPath` is project-relative with POSIX separators
|
|
472
474
|
// so the emitted command is identical across platforms.
|
|
473
|
-
|
|
475
|
+
// A shared-store slot (#3352) lives under the GitNexus home, so its path
|
|
476
|
+
// would be machine- and worktree-specific in committed docs; the runner goes
|
|
477
|
+
// next to the checkout's store pointer instead.
|
|
478
|
+
const runnerDir = storeRootOfCheckoutSlot(storagePath)
|
|
479
|
+
? path.join(repoPath, GITNEXUS_DIR)
|
|
480
|
+
: storagePath;
|
|
481
|
+
const runnerPath = path.relative(repoPath, path.join(runnerDir, 'run.cjs')).replace(/\\/g, '/');
|
|
474
482
|
try {
|
|
475
483
|
const runnerSrc = path.join(__dirname, '..', '..', 'hooks', 'claude', 'resolve-analyze-cmd.cjs');
|
|
476
|
-
await fs.mkdir(
|
|
477
|
-
await fs.copyFile(runnerSrc, path.join(
|
|
484
|
+
await fs.mkdir(runnerDir, { recursive: true });
|
|
485
|
+
await fs.copyFile(runnerSrc, path.join(runnerDir, 'run.cjs'));
|
|
478
486
|
}
|
|
479
487
|
catch (err) {
|
|
480
488
|
logger.warn(`Could not write GitNexus runner to ${runnerPath}: ${String(err)}`);
|
|
@@ -103,6 +103,10 @@ export interface AnalyzeOptions {
|
|
|
103
103
|
* `allowDuplicateName` option end-to-end.
|
|
104
104
|
*/
|
|
105
105
|
allowDuplicateName?: boolean;
|
|
106
|
+
/** `--share-with <repo>`: join that checkout's shared store (#3352). */
|
|
107
|
+
shareWith?: string;
|
|
108
|
+
/** `--no-share` sets this to false: leave the shared store (#3352). */
|
|
109
|
+
share?: boolean;
|
|
106
110
|
/**
|
|
107
111
|
* Override the walker's large-file skip threshold (#991). Value in KB;
|
|
108
112
|
* clamped downstream to the tree-sitter 32 MB ceiling. Sets
|
package/dist/cli/analyze.js
CHANGED
|
@@ -1128,6 +1128,8 @@ const analyzeCommandImpl = async (inputPath, cliOptions, runnerIdentityAtBootstr
|
|
|
1128
1128
|
// be able to accept the duplicate name without also paying the
|
|
1129
1129
|
// cost of a full pipeline re-index. See #829 review round 2.
|
|
1130
1130
|
allowDuplicateName: options.allowDuplicateName,
|
|
1131
|
+
shareWith: options.shareWith,
|
|
1132
|
+
noShare: options.share === false,
|
|
1131
1133
|
// Worker pool size threaded from --workers, replacing the previous
|
|
1132
1134
|
// GITNEXUS_WORKER_POOL_SIZE env mutation. `undefined` defers to the
|
|
1133
1135
|
// env / auto-formula fallback inside the pipeline.
|
package/dist/cli/auto-sync.js
CHANGED
|
@@ -106,6 +106,8 @@ function defaultSyncConfig(localPath) {
|
|
|
106
106
|
' overwrite_local_changes: false',
|
|
107
107
|
' remote_urls:',
|
|
108
108
|
' - git@github.com:owner/repo.git',
|
|
109
|
+
' # HTTPS remotes on github.com, gitlab.com, or gitee.com are also allowed',
|
|
110
|
+
' # - https://github.com/owner/public-repo.git',
|
|
109
111
|
'',
|
|
110
112
|
].join('\n');
|
|
111
113
|
}
|
package/dist/cli/clean.d.ts
CHANGED
package/dist/cli/clean.js
CHANGED
|
@@ -9,11 +9,14 @@ import path from 'path';
|
|
|
9
9
|
import { logger } from '../core/logger.js';
|
|
10
10
|
import { findRegistryEntryByRepoPath, findRepo, unregisterRepo, listRegisteredRepos, getStoragePaths, } from '../storage/repo-manager.js';
|
|
11
11
|
import { requireDeletableStoragePath, StorageDeletionError } from '../storage/storage-resolver.js';
|
|
12
|
-
import { formatStaleSlotLine } from './stale-branch-format.js';
|
|
12
|
+
import { formatSlotSize, formatStaleSlotLine } from './stale-branch-format.js';
|
|
13
13
|
import { listLocalHeads } from '../storage/git.js';
|
|
14
14
|
import { isContainedBranchDir, isDeleteCandidate, listStaleBranchSlots, removeBranchSlot, staleListingBlock, } from '../storage/stale-branch-slots.js';
|
|
15
15
|
import { cleanParkedLbugSidecars, inspectLbugSidecars, listParkedLbugSidecars, } from '../core/lbug/sidecar-recovery.js';
|
|
16
16
|
import { t } from './i18n/index.js';
|
|
17
|
+
import { getGlobalDir } from '../storage/global-dir.js';
|
|
18
|
+
import { STORES_DIR } from '../storage/shared-store.js';
|
|
19
|
+
import { findLegacyLocalIndex, reclaimAfterSlotRemoval, reclaimSharedStore, removeLegacyLocalIndex, removeCheckoutStorage, } from '../storage/shared-store-lifecycle.js';
|
|
17
20
|
const resolveOwnedCwdStorage = async (refusePrefix) => {
|
|
18
21
|
const repo = await findRepo(process.cwd());
|
|
19
22
|
if (!repo) {
|
|
@@ -115,7 +118,91 @@ const cleanStaleBranchSlots = async (force) => {
|
|
|
115
118
|
printStaleSlotLines(t('clean.stale.probeFailed'), probeFailed);
|
|
116
119
|
}
|
|
117
120
|
};
|
|
121
|
+
const reportReclaim = (result) => {
|
|
122
|
+
if (!result)
|
|
123
|
+
return;
|
|
124
|
+
if (result.removed.length > 0) {
|
|
125
|
+
console.log(t('clean.shared.reclaimed', { count: result.removed.length }));
|
|
126
|
+
}
|
|
127
|
+
if (result.kept.length > 0)
|
|
128
|
+
console.log(t('clean.shared.kept', { count: result.kept.length }));
|
|
129
|
+
};
|
|
130
|
+
/** `clean --gc`: collect every shared store under GITNEXUS_HOME (#3352). */
|
|
131
|
+
const collectSharedStores = async (force) => {
|
|
132
|
+
const storesDir = path.join(getGlobalDir(), STORES_DIR);
|
|
133
|
+
// Only a missing stores root means "nothing to collect"; an unreadable one
|
|
134
|
+
// must fail loudly rather than report success.
|
|
135
|
+
const names = await fs.readdir(storesDir).catch((err) => {
|
|
136
|
+
if (err.code === 'ENOENT')
|
|
137
|
+
return [];
|
|
138
|
+
throw err;
|
|
139
|
+
});
|
|
140
|
+
// Stray files (`.DS_Store`) are not stores, and a symlink is not followed:
|
|
141
|
+
// reclaim deletes under the root it is given. A store another collector
|
|
142
|
+
// removed meanwhile is simply gone. The lstat skips a stray link; it is not
|
|
143
|
+
// a race guard, since stores/ belongs to the user running clean and anyone
|
|
144
|
+
// able to swap an entry there can already delete the store itself.
|
|
145
|
+
const roots = [];
|
|
146
|
+
for (const name of names) {
|
|
147
|
+
const root = path.join(storesDir, name);
|
|
148
|
+
const stat = await fs.lstat(root).catch((err) => {
|
|
149
|
+
if (err.code === 'ENOENT')
|
|
150
|
+
return null;
|
|
151
|
+
throw err;
|
|
152
|
+
});
|
|
153
|
+
if (stat?.isDirectory())
|
|
154
|
+
roots.push(root);
|
|
155
|
+
}
|
|
156
|
+
if (roots.length === 0) {
|
|
157
|
+
console.log(t('clean.gc.none'));
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
for (const root of roots) {
|
|
161
|
+
// Without --force this is a preview: same selection, nothing deleted.
|
|
162
|
+
const result = await reclaimSharedStore(root, { gc: true, dryRun: !force });
|
|
163
|
+
console.log(t(force ? 'clean.gc.store' : 'clean.gc.preview', {
|
|
164
|
+
path: root,
|
|
165
|
+
members: result.droppedMembers.length,
|
|
166
|
+
graphs: result.removed.length,
|
|
167
|
+
}));
|
|
168
|
+
if (result.keptMembers.length > 0) {
|
|
169
|
+
console.log(t('clean.gc.keptMembers', { count: result.keptMembers.length }));
|
|
170
|
+
}
|
|
171
|
+
if (result.kept.length > 0)
|
|
172
|
+
console.log(t('clean.shared.kept', { count: result.kept.length }));
|
|
173
|
+
if (result.storeRemoved)
|
|
174
|
+
console.log(t('clean.shared.storeRemoved', { path: root }));
|
|
175
|
+
}
|
|
176
|
+
if (!force)
|
|
177
|
+
console.log(`\n${t('common.runForceConfirm')}`);
|
|
178
|
+
};
|
|
118
179
|
export const cleanCommand = async (options) => {
|
|
180
|
+
if (options?.gc) {
|
|
181
|
+
await collectSharedStores(options.force === true);
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
// --local-index: delete a pre-adoption index left in <checkout>/.gitnexus
|
|
185
|
+
// after the checkout moved into a shared store (#3352). Keeps the pointer.
|
|
186
|
+
if (options?.localIndex) {
|
|
187
|
+
const repo = await findRepo(process.cwd());
|
|
188
|
+
if (!repo) {
|
|
189
|
+
console.log(t('clean.notFoundHere'));
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
const legacy = await findLegacyLocalIndex(repo.repoPath, repo.storagePath);
|
|
193
|
+
if (!legacy) {
|
|
194
|
+
console.log(t('clean.localIndex.none'));
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
if (!options.force) {
|
|
198
|
+
console.log(t('clean.localIndex.preview', { path: legacy.dir, size: formatSlotSize(legacy.bytes) }));
|
|
199
|
+
console.log(`\n${t('common.runForceConfirm')}`);
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
await removeLegacyLocalIndex(repo.repoPath, repo.storagePath);
|
|
203
|
+
console.log(t('clean.localIndex.deleted', { path: legacy.dir, size: formatSlotSize(legacy.bytes) }));
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
119
206
|
// --stale: reclaim leftover per-branch slots whose recorded branch is not
|
|
120
207
|
// a live local head (#3331). Exclusive arm before --branch.
|
|
121
208
|
if (options?.stale) {
|
|
@@ -246,9 +333,12 @@ export const cleanCommand = async (options) => {
|
|
|
246
333
|
for (const entry of entries) {
|
|
247
334
|
try {
|
|
248
335
|
const storagePath = await requireDeletableStoragePath(entry);
|
|
249
|
-
|
|
250
|
-
|
|
336
|
+
// A shared slot is unregistered before it is deleted: its lock file
|
|
337
|
+
// lives inside it, so it must go last. A failed delete throws with the
|
|
338
|
+
// `clean --gc --force` recovery (shared-store-clean.test.ts).
|
|
339
|
+
await removeCheckoutStorage(storagePath, () => unregisterRepo(entry.path), entry.path);
|
|
251
340
|
console.log(t('clean.deletedRepo', { name: entry.name, storagePath }));
|
|
341
|
+
reportReclaim(await reclaimAfterSlotRemoval(storagePath));
|
|
252
342
|
}
|
|
253
343
|
catch (err) {
|
|
254
344
|
if (err instanceof StorageDeletionError) {
|
|
@@ -289,9 +379,9 @@ export const cleanCommand = async (options) => {
|
|
|
289
379
|
return;
|
|
290
380
|
}
|
|
291
381
|
try {
|
|
292
|
-
await
|
|
293
|
-
await unregisterRepo(repo.repoPath);
|
|
382
|
+
await removeCheckoutStorage(storagePath, () => unregisterRepo(repo.repoPath), repo.repoPath);
|
|
294
383
|
console.log(t('common.deleted', { target: storagePath }));
|
|
384
|
+
reportReclaim(await reclaimAfterSlotRemoval(storagePath));
|
|
295
385
|
}
|
|
296
386
|
catch (err) {
|
|
297
387
|
logger.error({ err }, 'Failed to delete:');
|
package/dist/cli/doctor.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { getRuntimeCapabilities, getRuntimeFingerprint } from '../core/platform/capabilities.js';
|
|
2
|
+
import { findLegacyLocalIndex } from '../storage/shared-store-lifecycle.js';
|
|
2
3
|
import { resolveEmbeddingConfig } from '../core/embeddings/config.js';
|
|
3
4
|
import { isHttpMode } from '../core/embeddings/http-client.js';
|
|
4
5
|
import { getLocalEmbeddingRuntimeBlocker, localEmbeddingPrefixUnloadableMessage, localEmbeddingStackMissingMessage, } from '../core/embeddings/runtime-support.js';
|
|
@@ -327,6 +328,12 @@ export const doctorCommand = async () => {
|
|
|
327
328
|
branches: entry?.branches,
|
|
328
329
|
});
|
|
329
330
|
const leftoverLines = leftoverBranchSlotDoctorLines(slots);
|
|
331
|
+
// A pre-adoption index left in <repo>/.gitnexus after this checkout moved
|
|
332
|
+
// into a shared store (#3352).
|
|
333
|
+
const legacy = await findLegacyLocalIndex(cwdRepo.repoPath, cwdRepo.storagePath);
|
|
334
|
+
if (legacy) {
|
|
335
|
+
leftoverLines.push(t('status.legacyLocalIndex', { path: legacy.dir, size: formatSlotSize(legacy.bytes) }));
|
|
336
|
+
}
|
|
330
337
|
if (leftoverLines.length === 0)
|
|
331
338
|
return;
|
|
332
339
|
console.log('');
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { lstat } from 'node:fs/promises';
|
|
2
|
+
import { ensurePrivateSharedGraph } from '../core/shared-store-analyze.js';
|
|
3
|
+
import { LBUG_DIRECTORY } from '../storage/storage-constants.js';
|
|
2
4
|
import path from 'node:path';
|
|
3
5
|
import { cliInfo } from './cli-message.js';
|
|
4
6
|
import { getGitRoot } from '../storage/git.js';
|
|
@@ -17,11 +19,17 @@ export const embeddingsSyncCommand = async (inputPath) => {
|
|
|
17
19
|
const repoPath = inputPath ? path.resolve(inputPath) : getGitRoot(process.cwd());
|
|
18
20
|
if (!repoPath)
|
|
19
21
|
throw new Error('Not inside a git repository. Pass a repository path.');
|
|
20
|
-
const {
|
|
22
|
+
const { metaPath } = getStoragePaths(repoPath);
|
|
21
23
|
const metaDir = path.dirname(metaPath);
|
|
24
|
+
// Writes go to the slot's own graph. A shared-store checkout that reads an
|
|
25
|
+
// immutable commit graph (#3352) takes a private copy first.
|
|
26
|
+
const lbugPath = path.join(metaDir, LBUG_DIRECTORY);
|
|
22
27
|
const lock = await acquireIndexLock(metaDir);
|
|
23
28
|
try {
|
|
24
29
|
requireExclusiveIndexLock(lock, `Cannot acquire the index lock at ${metaDir}; refusing an unlocked embeddings sync.`);
|
|
30
|
+
if (!(await ensurePrivateSharedGraph(metaDir, (m) => console.log(` ${m}`)))) {
|
|
31
|
+
throw new Error('The shared graph this checkout reads is gone. Run gitnexus analyze first.');
|
|
32
|
+
}
|
|
25
33
|
const meta = await loadMeta(metaDir);
|
|
26
34
|
if (!meta)
|
|
27
35
|
throw new Error(`No GitNexus index found for ${repoPath}. Run gitnexus analyze first.`);
|
package/dist/cli/help-i18n.js
CHANGED
|
@@ -63,6 +63,8 @@ const OPTION_DESCRIPTION_KEYS = {
|
|
|
63
63
|
'analyze|--skip-git': 'help.option.skipGit',
|
|
64
64
|
'analyze|--name <alias>': 'help.option.analyze.name',
|
|
65
65
|
'analyze|--allow-duplicate-name': 'help.option.analyze.allowDuplicateName',
|
|
66
|
+
'analyze|--share-with <repo>': 'help.option.analyze.shareWith',
|
|
67
|
+
'analyze|--no-share': 'help.option.analyze.noShare',
|
|
66
68
|
'analyze|-v, --verbose': 'help.option.verbose',
|
|
67
69
|
'analyze|--max-file-size <kb>': 'help.option.analyze.maxFileSize',
|
|
68
70
|
'analyze|--worker-timeout <seconds>': 'help.option.analyze.workerTimeout',
|
|
@@ -93,6 +95,8 @@ const OPTION_DESCRIPTION_KEYS = {
|
|
|
93
95
|
'clean|--branch <name>': 'help.option.clean.branch',
|
|
94
96
|
'clean|--lbug-sidecars': 'help.option.clean.lbugSidecars',
|
|
95
97
|
'clean|--stale': 'help.option.clean.stale',
|
|
98
|
+
'clean|--gc': 'help.option.clean.gc',
|
|
99
|
+
'clean|--local-index': 'help.option.clean.localIndex',
|
|
96
100
|
'remove|-f, --force': 'help.option.force.confirmation',
|
|
97
101
|
'wiki|-f, --force': 'help.option.wiki.force',
|
|
98
102
|
'wiki|--provider <provider>': 'help.option.wiki.provider',
|
package/dist/cli/i18n/en.d.ts
CHANGED
|
@@ -25,6 +25,11 @@ export declare const en: {
|
|
|
25
25
|
readonly 'list.clusters': 'Clusters';
|
|
26
26
|
readonly 'list.processes': 'Processes';
|
|
27
27
|
readonly 'list.unknown': 'unknown';
|
|
28
|
+
readonly 'status.sharedStoreShared': 'Shared index: store {{key}}, shared graph for commit {{commit}}';
|
|
29
|
+
readonly 'status.sharedStorePrivate': 'Shared index: store {{key}}, private graph (local changes or a pinned branch index)';
|
|
30
|
+
readonly 'status.sharedStoreCloneCow': ' Copied copy-on-write: unchanged pages are shared with the commit graph on disk';
|
|
31
|
+
readonly 'status.sharedStoreCloneCopy': ' Full copy: this filesystem cannot clone copy-on-write (APFS, btrfs and XFS can)';
|
|
32
|
+
readonly 'status.legacyLocalIndex': 'Leftover local index: {{path}} ({{size}}); remove it with `gitnexus clean --local-index --force`';
|
|
28
33
|
readonly 'status.notGitRepo': 'Not a git repository.';
|
|
29
34
|
readonly 'status.staleKuzu': 'Repository has a stale KuzuDB index from a previous version.';
|
|
30
35
|
readonly 'status.rebuildLadybug': 'Run: gitnexus analyze (rebuilds the index with LadybugDB)';
|
|
@@ -52,6 +57,16 @@ export declare const en: {
|
|
|
52
57
|
readonly 'clean.deleteAll': 'This will delete GitNexus indexes for {{count}} repo(s):';
|
|
53
58
|
readonly 'clean.deletedRepo': 'Deleted: {{name}} ({{storagePath}})';
|
|
54
59
|
readonly 'clean.notFoundHere': 'No indexed repository found in this directory.';
|
|
60
|
+
readonly 'clean.shared.reclaimed': 'Shared store: removed {{count}} commit graph(s) no checkout references.';
|
|
61
|
+
readonly 'clean.shared.kept': 'Shared store: kept {{count}} unreferenced commit graph(s) that could not be removed (in use or not writable); run `gitnexus clean --gc` later.';
|
|
62
|
+
readonly 'clean.shared.storeRemoved': 'Shared store: removed {{path}} (no checkouts remain).';
|
|
63
|
+
readonly 'clean.gc.none': 'No shared stores to collect.';
|
|
64
|
+
readonly 'clean.gc.keptMembers': 'Shared store: kept {{count}} checkout(s) it could not delete; run `gitnexus clean --gc --force` later.';
|
|
65
|
+
readonly 'clean.gc.store': 'Shared store {{path}}: dropped {{members}} checkout(s), removed {{graphs}} commit graph(s).';
|
|
66
|
+
readonly 'clean.gc.preview': 'Shared store {{path}}: would drop {{members}} checkout(s) and remove {{graphs}} commit graph(s).';
|
|
67
|
+
readonly 'clean.localIndex.none': 'No leftover local index in this checkout.';
|
|
68
|
+
readonly 'clean.localIndex.preview': 'This will delete the leftover local index at {{path}} ({{size}}). The shared index is not affected.';
|
|
69
|
+
readonly 'clean.localIndex.deleted': 'Deleted the leftover local index at {{path}} ({{size}}).';
|
|
55
70
|
readonly 'clean.deleteCurrent': 'This will delete the GitNexus index for: {{repoName}}';
|
|
56
71
|
readonly 'clean.branchNotIndexed': 'No indexed branch named "{{branch}}" for this repository. Use `gitnexus clean --stale` to reclaim leftover branch indexes, or `gitnexus list` to see recorded names.';
|
|
57
72
|
readonly 'clean.stale.none': 'No leftover branch indexes to reclaim.';
|
|
@@ -155,7 +170,7 @@ export declare const en: {
|
|
|
155
170
|
readonly 'help.command.setup.description': 'One-time setup: configure MCP for Cursor, Claude Code, Antigravity, OpenCode, CodeBuddy, Qoder, Codex, Factory Droid';
|
|
156
171
|
readonly 'help.command.uninstall.description': 'Reverse `setup`: remove GitNexus MCP entries, skills, and hooks from all detected editors';
|
|
157
172
|
readonly 'help.command.autoSync.description': 'Control scheduled repository clone/pull and analysis from GITNEXUS_HOME/watch_config.yml';
|
|
158
|
-
readonly 'help.autoSync.details': '\nActions: init, start (default), restart, stop, status, reset\nConfiguration: GITNEXUS_HOME/watch_config.yml\nRuntime files: GITNEXUS_HOME/watch/watch.pid, watch.mutex, watch.owner.json, watch.status.json, auto-sync-state.json\nRecovery: mutexes with verified dead owners are reclaimed automatically; invalid or legacy mutexes fail closed and require manual removal after confirming no watch process is running.\nWrites: GITNEXUS_HOME/watch/project_commit_info.txt\nRemote URLs:
|
|
173
|
+
readonly 'help.autoSync.details': '\nActions: init, start (default), restart, stop, status, reset\nConfiguration: GITNEXUS_HOME/watch_config.yml\nRuntime files: GITNEXUS_HOME/watch/watch.pid, watch.mutex, watch.owner.json, watch.status.json, auto-sync-state.json\nRecovery: mutexes with verified dead owners are reclaimed automatically; invalid or legacy mutexes fail closed and require manual removal after confirming no watch process is running.\nWrites: GITNEXUS_HOME/watch/project_commit_info.txt\nRemote URLs: SSH or HTTPS URLs on github.com, gitlab.com, and gitee.com are allowed. Invalid watch_config.yml skips auto-sync immediately.\nRuns once immediately, then repeats on sync_interval_minutes.';
|
|
159
174
|
readonly 'help.command.watch.description': 'Ambiguous: use `analyze --watch` for local files, or `auto-sync` for scheduled remotes';
|
|
160
175
|
readonly 'help.watch.details': '\n`gitnexus watch` does not start a watcher.\n Local working-tree incremental index: gitnexus analyze --watch\n Scheduled remote clone/pull + analyze: gitnexus auto-sync start\n';
|
|
161
176
|
readonly 'error.watch.ambiguous': '`gitnexus watch` is ambiguous.\n Local working-tree incremental index: gitnexus analyze --watch\n Scheduled remote clone/pull + analyze: gitnexus auto-sync start\n';
|
|
@@ -208,6 +223,8 @@ export declare const en: {
|
|
|
208
223
|
readonly 'help.option.skipGit': 'Treat the provided path/cwd as the index root and skip parent git-root discovery';
|
|
209
224
|
readonly 'help.option.analyze.name': 'Register this repo under a custom name in ~/.gitnexus/registry.json (disambiguates repos whose paths share a basename, e.g. two different .../app folders)';
|
|
210
225
|
readonly 'help.option.analyze.allowDuplicateName': 'Register this repo even if another path already uses the same --name alias. Leaves `-r <name>` ambiguous for the two paths; use -r <path> to disambiguate.';
|
|
226
|
+
readonly 'help.option.analyze.shareWith': 'Join the shared index store of a registered checkout of the same repository (name or path); the remote URL must match. Clones join a sibling clone’s store automatically; this names one explicitly and clears a --no-share opt-out.';
|
|
227
|
+
readonly 'help.option.analyze.noShare': 'Clones only: leave the shared index store, index into <repo>/.gitnexus again, and stop joining sibling clones automatically until --share-with (linked worktrees always share; set GITNEXUS_SHARED_STORE=off instead)';
|
|
211
228
|
readonly 'help.option.verbose': 'Enable verbose output';
|
|
212
229
|
readonly 'help.option.analyze.maxFileSize': 'Skip files larger than this (KB). Default: 512. Hard cap: 32768 (tree-sitter limit).';
|
|
213
230
|
readonly 'help.option.analyze.workerTimeout': 'Worker sub-batch idle timeout before retry/fallback. Default: 30.';
|
|
@@ -236,6 +253,8 @@ export declare const en: {
|
|
|
236
253
|
readonly 'help.option.clean.branch': 'Delete only the named branch index (not the workspace index)';
|
|
237
254
|
readonly 'help.option.clean.lbugSidecars': 'Clean parked LadybugDB recovery sidecars (missing-shadow WAL quarantines and dirty-recovery parks)';
|
|
238
255
|
readonly 'help.option.clean.stale': 'Reclaim leftover branch indexes that are not a live local head';
|
|
256
|
+
readonly 'help.option.clean.gc': 'Drop shared-store checkouts no registry entry uses and delete commit graphs nothing references';
|
|
257
|
+
readonly 'help.option.clean.localIndex': 'Delete the index left in <repo>/.gitnexus after this checkout moved into a shared store';
|
|
239
258
|
readonly 'help.option.wiki.force': 'Force full regeneration even if up to date';
|
|
240
259
|
readonly 'help.option.wiki.provider': 'LLM provider: minimax, openai, openrouter, azure, custom, cursor, claude, codex, opencode, or grok (default: minimax)';
|
|
241
260
|
readonly 'help.option.wiki.model': 'LLM model or deployment name (default: MiniMax-M3)';
|
package/dist/cli/i18n/en.js
CHANGED
|
@@ -25,6 +25,11 @@ export const en = {
|
|
|
25
25
|
'list.clusters': 'Clusters',
|
|
26
26
|
'list.processes': 'Processes',
|
|
27
27
|
'list.unknown': 'unknown',
|
|
28
|
+
'status.sharedStoreShared': 'Shared index: store {{key}}, shared graph for commit {{commit}}',
|
|
29
|
+
'status.sharedStorePrivate': 'Shared index: store {{key}}, private graph (local changes or a pinned branch index)',
|
|
30
|
+
'status.sharedStoreCloneCow': ' Copied copy-on-write: unchanged pages are shared with the commit graph on disk',
|
|
31
|
+
'status.sharedStoreCloneCopy': ' Full copy: this filesystem cannot clone copy-on-write (APFS, btrfs and XFS can)',
|
|
32
|
+
'status.legacyLocalIndex': 'Leftover local index: {{path}} ({{size}}); remove it with `gitnexus clean --local-index --force`',
|
|
28
33
|
'status.notGitRepo': 'Not a git repository.',
|
|
29
34
|
'status.staleKuzu': 'Repository has a stale KuzuDB index from a previous version.',
|
|
30
35
|
'status.rebuildLadybug': 'Run: gitnexus analyze (rebuilds the index with LadybugDB)',
|
|
@@ -52,6 +57,16 @@ export const en = {
|
|
|
52
57
|
'clean.deleteAll': 'This will delete GitNexus indexes for {{count}} repo(s):',
|
|
53
58
|
'clean.deletedRepo': 'Deleted: {{name}} ({{storagePath}})',
|
|
54
59
|
'clean.notFoundHere': 'No indexed repository found in this directory.',
|
|
60
|
+
'clean.shared.reclaimed': 'Shared store: removed {{count}} commit graph(s) no checkout references.',
|
|
61
|
+
'clean.shared.kept': 'Shared store: kept {{count}} unreferenced commit graph(s) that could not be removed (in use or not writable); run `gitnexus clean --gc` later.',
|
|
62
|
+
'clean.shared.storeRemoved': 'Shared store: removed {{path}} (no checkouts remain).',
|
|
63
|
+
'clean.gc.none': 'No shared stores to collect.',
|
|
64
|
+
'clean.gc.keptMembers': 'Shared store: kept {{count}} checkout(s) it could not delete; run `gitnexus clean --gc --force` later.',
|
|
65
|
+
'clean.gc.store': 'Shared store {{path}}: dropped {{members}} checkout(s), removed {{graphs}} commit graph(s).',
|
|
66
|
+
'clean.gc.preview': 'Shared store {{path}}: would drop {{members}} checkout(s) and remove {{graphs}} commit graph(s).',
|
|
67
|
+
'clean.localIndex.none': 'No leftover local index in this checkout.',
|
|
68
|
+
'clean.localIndex.preview': 'This will delete the leftover local index at {{path}} ({{size}}). The shared index is not affected.',
|
|
69
|
+
'clean.localIndex.deleted': 'Deleted the leftover local index at {{path}} ({{size}}).',
|
|
55
70
|
'clean.deleteCurrent': 'This will delete the GitNexus index for: {{repoName}}',
|
|
56
71
|
'clean.branchNotIndexed': 'No indexed branch named "{{branch}}" for this repository. Use `gitnexus clean --stale` to reclaim leftover branch indexes, or `gitnexus list` to see recorded names.',
|
|
57
72
|
'clean.stale.none': 'No leftover branch indexes to reclaim.',
|
|
@@ -157,7 +172,7 @@ export const en = {
|
|
|
157
172
|
'help.command.setup.description': 'One-time setup: configure MCP for Cursor, Claude Code, Antigravity, OpenCode, CodeBuddy, Qoder, Codex, Factory Droid',
|
|
158
173
|
'help.command.uninstall.description': 'Reverse `setup`: remove GitNexus MCP entries, skills, and hooks from all detected editors',
|
|
159
174
|
'help.command.autoSync.description': 'Control scheduled repository clone/pull and analysis from GITNEXUS_HOME/watch_config.yml',
|
|
160
|
-
'help.autoSync.details': '\nActions: init, start (default), restart, stop, status, reset\nConfiguration: GITNEXUS_HOME/watch_config.yml\nRuntime files: GITNEXUS_HOME/watch/watch.pid, watch.mutex, watch.owner.json, watch.status.json, auto-sync-state.json\nRecovery: mutexes with verified dead owners are reclaimed automatically; invalid or legacy mutexes fail closed and require manual removal after confirming no watch process is running.\nWrites: GITNEXUS_HOME/watch/project_commit_info.txt\nRemote URLs:
|
|
175
|
+
'help.autoSync.details': '\nActions: init, start (default), restart, stop, status, reset\nConfiguration: GITNEXUS_HOME/watch_config.yml\nRuntime files: GITNEXUS_HOME/watch/watch.pid, watch.mutex, watch.owner.json, watch.status.json, auto-sync-state.json\nRecovery: mutexes with verified dead owners are reclaimed automatically; invalid or legacy mutexes fail closed and require manual removal after confirming no watch process is running.\nWrites: GITNEXUS_HOME/watch/project_commit_info.txt\nRemote URLs: SSH or HTTPS URLs on github.com, gitlab.com, and gitee.com are allowed. Invalid watch_config.yml skips auto-sync immediately.\nRuns once immediately, then repeats on sync_interval_minutes.',
|
|
161
176
|
'help.command.watch.description': 'Ambiguous: use `analyze --watch` for local files, or `auto-sync` for scheduled remotes',
|
|
162
177
|
'help.watch.details': '\n`gitnexus watch` does not start a watcher.\n Local working-tree incremental index: gitnexus analyze --watch\n Scheduled remote clone/pull + analyze: gitnexus auto-sync start\n',
|
|
163
178
|
'error.watch.ambiguous': '`gitnexus watch` is ambiguous.\n Local working-tree incremental index: gitnexus analyze --watch\n Scheduled remote clone/pull + analyze: gitnexus auto-sync start\n',
|
|
@@ -210,6 +225,8 @@ export const en = {
|
|
|
210
225
|
'help.option.skipGit': 'Treat the provided path/cwd as the index root and skip parent git-root discovery',
|
|
211
226
|
'help.option.analyze.name': 'Register this repo under a custom name in ~/.gitnexus/registry.json (disambiguates repos whose paths share a basename, e.g. two different .../app folders)',
|
|
212
227
|
'help.option.analyze.allowDuplicateName': 'Register this repo even if another path already uses the same --name alias. Leaves `-r <name>` ambiguous for the two paths; use -r <path> to disambiguate.',
|
|
228
|
+
'help.option.analyze.shareWith': 'Join the shared index store of a registered checkout of the same repository (name or path); the remote URL must match. Clones join a sibling clone’s store automatically; this names one explicitly and clears a --no-share opt-out.',
|
|
229
|
+
'help.option.analyze.noShare': 'Clones only: leave the shared index store, index into <repo>/.gitnexus again, and stop joining sibling clones automatically until --share-with (linked worktrees always share; set GITNEXUS_SHARED_STORE=off instead)',
|
|
213
230
|
'help.option.verbose': 'Enable verbose output',
|
|
214
231
|
'help.option.analyze.maxFileSize': 'Skip files larger than this (KB). Default: 512. Hard cap: 32768 (tree-sitter limit).',
|
|
215
232
|
'help.option.analyze.workerTimeout': 'Worker sub-batch idle timeout before retry/fallback. Default: 30.',
|
|
@@ -238,6 +255,8 @@ export const en = {
|
|
|
238
255
|
'help.option.clean.branch': 'Delete only the named branch index (not the workspace index)',
|
|
239
256
|
'help.option.clean.lbugSidecars': 'Clean parked LadybugDB recovery sidecars (missing-shadow WAL quarantines and dirty-recovery parks)',
|
|
240
257
|
'help.option.clean.stale': 'Reclaim leftover branch indexes that are not a live local head',
|
|
258
|
+
'help.option.clean.gc': 'Drop shared-store checkouts no registry entry uses and delete commit graphs nothing references',
|
|
259
|
+
'help.option.clean.localIndex': 'Delete the index left in <repo>/.gitnexus after this checkout moved into a shared store',
|
|
241
260
|
'help.option.wiki.force': 'Force full regeneration even if up to date',
|
|
242
261
|
'help.option.wiki.provider': 'LLM provider: minimax, openai, openrouter, azure, custom, cursor, claude, codex, opencode, or grok (default: minimax)',
|
|
243
262
|
'help.option.wiki.model': 'LLM model or deployment name (default: MiniMax-M3)',
|
|
@@ -26,6 +26,11 @@ export declare const cliResources: {
|
|
|
26
26
|
readonly 'list.clusters': 'Clusters';
|
|
27
27
|
readonly 'list.processes': 'Processes';
|
|
28
28
|
readonly 'list.unknown': 'unknown';
|
|
29
|
+
readonly 'status.sharedStoreShared': 'Shared index: store {{key}}, shared graph for commit {{commit}}';
|
|
30
|
+
readonly 'status.sharedStorePrivate': 'Shared index: store {{key}}, private graph (local changes or a pinned branch index)';
|
|
31
|
+
readonly 'status.sharedStoreCloneCow': ' Copied copy-on-write: unchanged pages are shared with the commit graph on disk';
|
|
32
|
+
readonly 'status.sharedStoreCloneCopy': ' Full copy: this filesystem cannot clone copy-on-write (APFS, btrfs and XFS can)';
|
|
33
|
+
readonly 'status.legacyLocalIndex': 'Leftover local index: {{path}} ({{size}}); remove it with `gitnexus clean --local-index --force`';
|
|
29
34
|
readonly 'status.notGitRepo': 'Not a git repository.';
|
|
30
35
|
readonly 'status.staleKuzu': 'Repository has a stale KuzuDB index from a previous version.';
|
|
31
36
|
readonly 'status.rebuildLadybug': 'Run: gitnexus analyze (rebuilds the index with LadybugDB)';
|
|
@@ -53,6 +58,16 @@ export declare const cliResources: {
|
|
|
53
58
|
readonly 'clean.deleteAll': 'This will delete GitNexus indexes for {{count}} repo(s):';
|
|
54
59
|
readonly 'clean.deletedRepo': 'Deleted: {{name}} ({{storagePath}})';
|
|
55
60
|
readonly 'clean.notFoundHere': 'No indexed repository found in this directory.';
|
|
61
|
+
readonly 'clean.shared.reclaimed': 'Shared store: removed {{count}} commit graph(s) no checkout references.';
|
|
62
|
+
readonly 'clean.shared.kept': 'Shared store: kept {{count}} unreferenced commit graph(s) that could not be removed (in use or not writable); run `gitnexus clean --gc` later.';
|
|
63
|
+
readonly 'clean.shared.storeRemoved': 'Shared store: removed {{path}} (no checkouts remain).';
|
|
64
|
+
readonly 'clean.gc.none': 'No shared stores to collect.';
|
|
65
|
+
readonly 'clean.gc.keptMembers': 'Shared store: kept {{count}} checkout(s) it could not delete; run `gitnexus clean --gc --force` later.';
|
|
66
|
+
readonly 'clean.gc.store': 'Shared store {{path}}: dropped {{members}} checkout(s), removed {{graphs}} commit graph(s).';
|
|
67
|
+
readonly 'clean.gc.preview': 'Shared store {{path}}: would drop {{members}} checkout(s) and remove {{graphs}} commit graph(s).';
|
|
68
|
+
readonly 'clean.localIndex.none': 'No leftover local index in this checkout.';
|
|
69
|
+
readonly 'clean.localIndex.preview': 'This will delete the leftover local index at {{path}} ({{size}}). The shared index is not affected.';
|
|
70
|
+
readonly 'clean.localIndex.deleted': 'Deleted the leftover local index at {{path}} ({{size}}).';
|
|
56
71
|
readonly 'clean.deleteCurrent': 'This will delete the GitNexus index for: {{repoName}}';
|
|
57
72
|
readonly 'clean.branchNotIndexed': 'No indexed branch named "{{branch}}" for this repository. Use `gitnexus clean --stale` to reclaim leftover branch indexes, or `gitnexus list` to see recorded names.';
|
|
58
73
|
readonly 'clean.stale.none': 'No leftover branch indexes to reclaim.';
|
|
@@ -156,7 +171,7 @@ export declare const cliResources: {
|
|
|
156
171
|
readonly 'help.command.setup.description': 'One-time setup: configure MCP for Cursor, Claude Code, Antigravity, OpenCode, CodeBuddy, Qoder, Codex, Factory Droid';
|
|
157
172
|
readonly 'help.command.uninstall.description': 'Reverse `setup`: remove GitNexus MCP entries, skills, and hooks from all detected editors';
|
|
158
173
|
readonly 'help.command.autoSync.description': 'Control scheduled repository clone/pull and analysis from GITNEXUS_HOME/watch_config.yml';
|
|
159
|
-
readonly 'help.autoSync.details': '\nActions: init, start (default), restart, stop, status, reset\nConfiguration: GITNEXUS_HOME/watch_config.yml\nRuntime files: GITNEXUS_HOME/watch/watch.pid, watch.mutex, watch.owner.json, watch.status.json, auto-sync-state.json\nRecovery: mutexes with verified dead owners are reclaimed automatically; invalid or legacy mutexes fail closed and require manual removal after confirming no watch process is running.\nWrites: GITNEXUS_HOME/watch/project_commit_info.txt\nRemote URLs:
|
|
174
|
+
readonly 'help.autoSync.details': '\nActions: init, start (default), restart, stop, status, reset\nConfiguration: GITNEXUS_HOME/watch_config.yml\nRuntime files: GITNEXUS_HOME/watch/watch.pid, watch.mutex, watch.owner.json, watch.status.json, auto-sync-state.json\nRecovery: mutexes with verified dead owners are reclaimed automatically; invalid or legacy mutexes fail closed and require manual removal after confirming no watch process is running.\nWrites: GITNEXUS_HOME/watch/project_commit_info.txt\nRemote URLs: SSH or HTTPS URLs on github.com, gitlab.com, and gitee.com are allowed. Invalid watch_config.yml skips auto-sync immediately.\nRuns once immediately, then repeats on sync_interval_minutes.';
|
|
160
175
|
readonly 'help.command.watch.description': 'Ambiguous: use `analyze --watch` for local files, or `auto-sync` for scheduled remotes';
|
|
161
176
|
readonly 'help.watch.details': '\n`gitnexus watch` does not start a watcher.\n Local working-tree incremental index: gitnexus analyze --watch\n Scheduled remote clone/pull + analyze: gitnexus auto-sync start\n';
|
|
162
177
|
readonly 'error.watch.ambiguous': '`gitnexus watch` is ambiguous.\n Local working-tree incremental index: gitnexus analyze --watch\n Scheduled remote clone/pull + analyze: gitnexus auto-sync start\n';
|
|
@@ -209,6 +224,8 @@ export declare const cliResources: {
|
|
|
209
224
|
readonly 'help.option.skipGit': 'Treat the provided path/cwd as the index root and skip parent git-root discovery';
|
|
210
225
|
readonly 'help.option.analyze.name': 'Register this repo under a custom name in ~/.gitnexus/registry.json (disambiguates repos whose paths share a basename, e.g. two different .../app folders)';
|
|
211
226
|
readonly 'help.option.analyze.allowDuplicateName': 'Register this repo even if another path already uses the same --name alias. Leaves `-r <name>` ambiguous for the two paths; use -r <path> to disambiguate.';
|
|
227
|
+
readonly 'help.option.analyze.shareWith': 'Join the shared index store of a registered checkout of the same repository (name or path); the remote URL must match. Clones join a sibling clone’s store automatically; this names one explicitly and clears a --no-share opt-out.';
|
|
228
|
+
readonly 'help.option.analyze.noShare': 'Clones only: leave the shared index store, index into <repo>/.gitnexus again, and stop joining sibling clones automatically until --share-with (linked worktrees always share; set GITNEXUS_SHARED_STORE=off instead)';
|
|
212
229
|
readonly 'help.option.verbose': 'Enable verbose output';
|
|
213
230
|
readonly 'help.option.analyze.maxFileSize': 'Skip files larger than this (KB). Default: 512. Hard cap: 32768 (tree-sitter limit).';
|
|
214
231
|
readonly 'help.option.analyze.workerTimeout': 'Worker sub-batch idle timeout before retry/fallback. Default: 30.';
|
|
@@ -237,6 +254,8 @@ export declare const cliResources: {
|
|
|
237
254
|
readonly 'help.option.clean.branch': 'Delete only the named branch index (not the workspace index)';
|
|
238
255
|
readonly 'help.option.clean.lbugSidecars': 'Clean parked LadybugDB recovery sidecars (missing-shadow WAL quarantines and dirty-recovery parks)';
|
|
239
256
|
readonly 'help.option.clean.stale': 'Reclaim leftover branch indexes that are not a live local head';
|
|
257
|
+
readonly 'help.option.clean.gc': 'Drop shared-store checkouts no registry entry uses and delete commit graphs nothing references';
|
|
258
|
+
readonly 'help.option.clean.localIndex': 'Delete the index left in <repo>/.gitnexus after this checkout moved into a shared store';
|
|
240
259
|
readonly 'help.option.wiki.force': 'Force full regeneration even if up to date';
|
|
241
260
|
readonly 'help.option.wiki.provider': 'LLM provider: minimax, openai, openrouter, azure, custom, cursor, claude, codex, opencode, or grok (default: minimax)';
|
|
242
261
|
readonly 'help.option.wiki.model': 'LLM model or deployment name (default: MiniMax-M3)';
|
|
@@ -333,6 +352,11 @@ export declare const cliResources: {
|
|
|
333
352
|
'list.clusters': string;
|
|
334
353
|
'list.processes': string;
|
|
335
354
|
'list.unknown': string;
|
|
355
|
+
'status.sharedStoreShared': string;
|
|
356
|
+
'status.sharedStorePrivate': string;
|
|
357
|
+
'status.sharedStoreCloneCow': string;
|
|
358
|
+
'status.sharedStoreCloneCopy': string;
|
|
359
|
+
'status.legacyLocalIndex': string;
|
|
336
360
|
'status.notGitRepo': string;
|
|
337
361
|
'status.staleKuzu': string;
|
|
338
362
|
'status.rebuildLadybug': string;
|
|
@@ -360,6 +384,16 @@ export declare const cliResources: {
|
|
|
360
384
|
'clean.deleteAll': string;
|
|
361
385
|
'clean.deletedRepo': string;
|
|
362
386
|
'clean.notFoundHere': string;
|
|
387
|
+
'clean.shared.reclaimed': string;
|
|
388
|
+
'clean.shared.kept': string;
|
|
389
|
+
'clean.shared.storeRemoved': string;
|
|
390
|
+
'clean.gc.none': string;
|
|
391
|
+
'clean.gc.keptMembers': string;
|
|
392
|
+
'clean.gc.store': string;
|
|
393
|
+
'clean.gc.preview': string;
|
|
394
|
+
'clean.localIndex.none': string;
|
|
395
|
+
'clean.localIndex.preview': string;
|
|
396
|
+
'clean.localIndex.deleted': string;
|
|
363
397
|
'clean.deleteCurrent': string;
|
|
364
398
|
'clean.branchNotIndexed': string;
|
|
365
399
|
'clean.stale.none': string;
|
|
@@ -516,6 +550,8 @@ export declare const cliResources: {
|
|
|
516
550
|
'help.option.skipGit': string;
|
|
517
551
|
'help.option.analyze.name': string;
|
|
518
552
|
'help.option.analyze.allowDuplicateName': string;
|
|
553
|
+
'help.option.analyze.shareWith': string;
|
|
554
|
+
'help.option.analyze.noShare': string;
|
|
519
555
|
'help.option.verbose': string;
|
|
520
556
|
'help.option.analyze.maxFileSize': string;
|
|
521
557
|
'help.option.analyze.workerTimeout': string;
|
|
@@ -544,6 +580,8 @@ export declare const cliResources: {
|
|
|
544
580
|
'help.option.clean.branch': string;
|
|
545
581
|
'help.option.clean.lbugSidecars': string;
|
|
546
582
|
'help.option.clean.stale': string;
|
|
583
|
+
'help.option.clean.gc': string;
|
|
584
|
+
'help.option.clean.localIndex': string;
|
|
547
585
|
'help.option.wiki.force': string;
|
|
548
586
|
'help.option.wiki.provider': string;
|
|
549
587
|
'help.option.wiki.model': string;
|
package/dist/cli/i18n/zh-CN.d.ts
CHANGED
|
@@ -25,6 +25,11 @@ export declare const zhCN: {
|
|
|
25
25
|
'list.clusters': string;
|
|
26
26
|
'list.processes': string;
|
|
27
27
|
'list.unknown': string;
|
|
28
|
+
'status.sharedStoreShared': string;
|
|
29
|
+
'status.sharedStorePrivate': string;
|
|
30
|
+
'status.sharedStoreCloneCow': string;
|
|
31
|
+
'status.sharedStoreCloneCopy': string;
|
|
32
|
+
'status.legacyLocalIndex': string;
|
|
28
33
|
'status.notGitRepo': string;
|
|
29
34
|
'status.staleKuzu': string;
|
|
30
35
|
'status.rebuildLadybug': string;
|
|
@@ -52,6 +57,16 @@ export declare const zhCN: {
|
|
|
52
57
|
'clean.deleteAll': string;
|
|
53
58
|
'clean.deletedRepo': string;
|
|
54
59
|
'clean.notFoundHere': string;
|
|
60
|
+
'clean.shared.reclaimed': string;
|
|
61
|
+
'clean.shared.kept': string;
|
|
62
|
+
'clean.shared.storeRemoved': string;
|
|
63
|
+
'clean.gc.none': string;
|
|
64
|
+
'clean.gc.keptMembers': string;
|
|
65
|
+
'clean.gc.store': string;
|
|
66
|
+
'clean.gc.preview': string;
|
|
67
|
+
'clean.localIndex.none': string;
|
|
68
|
+
'clean.localIndex.preview': string;
|
|
69
|
+
'clean.localIndex.deleted': string;
|
|
55
70
|
'clean.deleteCurrent': string;
|
|
56
71
|
'clean.branchNotIndexed': string;
|
|
57
72
|
'clean.stale.none': string;
|
|
@@ -208,6 +223,8 @@ export declare const zhCN: {
|
|
|
208
223
|
'help.option.skipGit': string;
|
|
209
224
|
'help.option.analyze.name': string;
|
|
210
225
|
'help.option.analyze.allowDuplicateName': string;
|
|
226
|
+
'help.option.analyze.shareWith': string;
|
|
227
|
+
'help.option.analyze.noShare': string;
|
|
211
228
|
'help.option.verbose': string;
|
|
212
229
|
'help.option.analyze.maxFileSize': string;
|
|
213
230
|
'help.option.analyze.workerTimeout': string;
|
|
@@ -236,6 +253,8 @@ export declare const zhCN: {
|
|
|
236
253
|
'help.option.clean.branch': string;
|
|
237
254
|
'help.option.clean.lbugSidecars': string;
|
|
238
255
|
'help.option.clean.stale': string;
|
|
256
|
+
'help.option.clean.gc': string;
|
|
257
|
+
'help.option.clean.localIndex': string;
|
|
239
258
|
'help.option.wiki.force': string;
|
|
240
259
|
'help.option.wiki.provider': string;
|
|
241
260
|
'help.option.wiki.model': string;
|