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.
Files changed (64) hide show
  1. package/README.md +1 -1
  2. package/dist/cli/ai-context.js +11 -3
  3. package/dist/cli/analyze-options.d.ts +4 -0
  4. package/dist/cli/analyze.js +2 -0
  5. package/dist/cli/auto-sync.js +2 -0
  6. package/dist/cli/clean.d.ts +2 -0
  7. package/dist/cli/clean.js +95 -5
  8. package/dist/cli/doctor.js +7 -0
  9. package/dist/cli/embeddings-sync.js +9 -1
  10. package/dist/cli/help-i18n.js +4 -0
  11. package/dist/cli/i18n/en.d.ts +20 -1
  12. package/dist/cli/i18n/en.js +20 -1
  13. package/dist/cli/i18n/resources.d.ts +39 -1
  14. package/dist/cli/i18n/zh-CN.d.ts +19 -0
  15. package/dist/cli/i18n/zh-CN.js +20 -1
  16. package/dist/cli/index.js +8 -0
  17. package/dist/cli/remove.js +3 -3
  18. package/dist/cli/status.js +46 -0
  19. package/dist/core/augmentation/engine.js +4 -1
  20. package/dist/core/auto-sync/config.d.ts +6 -0
  21. package/dist/core/auto-sync/config.js +31 -6
  22. package/dist/core/auto-sync/index.d.ts +1 -1
  23. package/dist/core/auto-sync/index.js +1 -1
  24. package/dist/core/auto-sync/runner.d.ts +1 -1
  25. package/dist/core/auto-sync/runner.js +5 -6
  26. package/dist/core/gitnexus-rc-embeddings.d.ts +11 -0
  27. package/dist/core/gitnexus-rc-embeddings.js +51 -0
  28. package/dist/core/group/sync.js +2 -2
  29. package/dist/core/ingestion/class-extractors/configs/ruby.d.ts +13 -1
  30. package/dist/core/ingestion/class-extractors/configs/ruby.js +50 -2
  31. package/dist/core/ingestion/languages/ruby.js +17 -2
  32. package/dist/core/ingestion/tree-sitter-queries.d.ts +1 -1
  33. package/dist/core/ingestion/tree-sitter-queries.js +74 -0
  34. package/dist/core/ingestion/utils/ast-helpers.js +16 -0
  35. package/dist/core/run-analyze.d.ts +7 -0
  36. package/dist/core/run-analyze.js +127 -13
  37. package/dist/core/shared-store-analyze.d.ts +89 -0
  38. package/dist/core/shared-store-analyze.js +570 -0
  39. package/dist/mcp/local/local-backend.d.ts +14 -0
  40. package/dist/mcp/local/local-backend.js +38 -6
  41. package/dist/server/analyze-launch.js +27 -8
  42. package/dist/server/analyze-worker-ipc.d.ts +1 -1
  43. package/dist/server/analyze-worker-ipc.js +3 -0
  44. package/dist/server/api.js +39 -10
  45. package/dist/server/git-clone.d.ts +4 -5
  46. package/dist/server/git-clone.js +44 -11
  47. package/dist/storage/git.d.ts +13 -0
  48. package/dist/storage/git.js +55 -0
  49. package/dist/storage/index-lock.d.ts +5 -0
  50. package/dist/storage/index-lock.js +1 -1
  51. package/dist/storage/repo-manager.d.ts +21 -3
  52. package/dist/storage/repo-manager.js +27 -5
  53. package/dist/storage/repo-meta.d.ts +6 -0
  54. package/dist/storage/shared-store-lifecycle.d.ts +95 -0
  55. package/dist/storage/shared-store-lifecycle.js +393 -0
  56. package/dist/storage/shared-store.d.ts +65 -0
  57. package/dist/storage/shared-store.js +297 -0
  58. package/dist/storage/storage-resolver.d.ts +2 -2
  59. package/dist/storage/storage-resolver.js +27 -32
  60. package/dist/storage/storage-slot.d.ts +17 -0
  61. package/dist/storage/storage-slot.js +48 -0
  62. package/hooks/claude/registry-query.cjs +43 -6
  63. package/package.json +1 -1
  64. 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` must use SSH SCP form for github.com, gitlab.com, or gitee.com. `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. 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.
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
 
@@ -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
- const runnerPath = path.relative(repoPath, path.join(storagePath, 'run.cjs')).replace(/\\/g, '/');
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(storagePath, { recursive: true });
477
- await fs.copyFile(runnerSrc, path.join(storagePath, 'run.cjs'));
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
@@ -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.
@@ -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
  }
@@ -10,4 +10,6 @@ export declare const cleanCommand: (options?: {
10
10
  lbugSidecars?: boolean;
11
11
  stale?: boolean;
12
12
  branch?: string;
13
+ gc?: boolean;
14
+ localIndex?: boolean;
13
15
  }) => Promise<void>;
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
- await fs.rm(storagePath, { recursive: true, force: true });
250
- await unregisterRepo(entry.path);
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 fs.rm(storagePath, { recursive: true, force: true });
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:');
@@ -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 { lbugPath, metaPath } = getStoragePaths(repoPath);
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.`);
@@ -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',
@@ -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: only SSH URLs on github.com, gitlab.com, and gitee.com are allowed.\nRuns once immediately, then repeats on sync_interval_minutes.';
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)';
@@ -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: only SSH URLs on github.com, gitlab.com, and gitee.com are allowed.\nRuns once immediately, then repeats on sync_interval_minutes.',
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: only SSH URLs on github.com, gitlab.com, and gitee.com are allowed.\nRuns once immediately, then repeats on sync_interval_minutes.';
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;
@@ -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;