@ninjaxtools/slopdex 0.3.0 → 0.8.0

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.
@@ -1,22 +1,23 @@
1
1
  ---
2
2
  name: slopdex
3
- description: Use when indexing TypeScript or JavaScript code, running semantic function search, or finding duplicate function candidates with the slopdex command-line tool.
3
+ description: Use when indexing Python, JavaScript, JSX, TypeScript, TSX, Rust, Go, Java, or C code, running semantic function search, finding duplicate function candidates, or analyzing physical code cohesion with the slopdex command-line tool.
4
4
  ---
5
5
 
6
6
  # Slopdex CLI
7
7
 
8
- Use `slopdex` to index named JavaScript and TypeScript callables, search them by meaning, and identify similar or duplicated functions.
8
+ Use `slopdex` to index named Python, JavaScript, JSX, TypeScript, TSX, Rust, Go, Java, and C callables with Tree-sitter, search them by meaning, identify similar or duplicated functions, and find related functions scattered across a repository. Languages are detected by extension and can coexist in one index.
9
9
 
10
10
  ## Default Workflow
11
11
 
12
12
  Run the command that satisfies the user's request immediately. Do not begin with `slopdex status`, `slopdex --help`, executable lookup, API-key probes, or version probes. Slopdex performs its own validation and reports missing credentials or incompatible state.
13
13
 
14
14
  - For semantic search, run `slopdex search "<query>" --format summary --limit 10`.
15
- - For duplicate candidates, run `slopdex cross-search --format summary --threshold 0.9 --limit 5`.
16
- - For an explicit request to refresh the committed index, run `slopdex update-git`.
15
+ - For duplicate-code clusters, run `slopdex cross-search --cross-file-only --min-lines 4 --threshold 0.9 --limit 5`.
16
+ - For related functions that are physically separated, run `slopdex cohesion --format summary --threshold 0.8 --neighbors 20 --limit 50`.
17
+ - For an explicit request to refresh the current index, run `slopdex update-git`.
17
18
  - Use `slopdex status` only when the user asks for index metadata or checkpoint information.
18
19
 
19
- Any command that needs a missing index automatically creates and populates it from committed `HEAD`. Let the requested command do this; do not initialize separately. In particular, `slopdex update-git --target HEAD` uses the same initialization path and cannot bypass an automatic-initialization failure.
20
+ Every command refreshes its index from committed `HEAD`, then overlays working-tree changes. A missing index is created automatically; let the requested command perform the refresh rather than initializing separately. Without Git or a Git repository, every command warns on stderr and fully re-indexes the working tree. Use `--no-reindex` only when explicitly asked to skip Git working-tree overlays or reuse an existing non-empty index without Git.
20
21
 
21
22
  ## Prerequisites
22
23
 
@@ -38,15 +39,19 @@ Do not expose API keys in commands, output, configuration files, or commits.
38
39
 
39
40
  ## Indexing
40
41
 
41
- If a CLI command cannot find its source index, Slopdex prints a notice to stderr and automatically creates and populates it from committed `HEAD`. Missing cross-search target indexes are initialized from the target repository's `HEAD` as well. Automatic initialization requires a clean Git worktree.
42
+ Root and nested `.gitignore` files restrict indexing, including tracked files. Working-tree updates use current ignore files; historical or committed-only Git updates use ignore files from the selected commit. A normal refresh removes newly ignored files from the index. Explicit updates reject ignored paths.
42
43
 
43
- Index the current committed snapshot:
44
+ Indexing records parse, callable-extraction, file-read, and file-size failures in SQLite while retaining healthy callables. Commands warn on stderr when unresolved diagnostics remain. Inspect them with `slopdex index-errors --format summary` (or JSON by default); this reads saved errors without refreshing the index or calling providers. Records include paths, source locations, recoverable function names, messages, and available source text. `status` reports `indexingErrorCount` and `failedFileCount`. Failed files are retried during updates; fixes, deletions, and exclusions clear their diagnostics. `--ignore-errors` silences diagnostic warnings without discarding the records.
45
+
46
+ If a CLI command cannot find its source index, Slopdex prints a notice to stderr and automatically creates and populates it from committed `HEAD`, then overlays working-tree changes. Missing cross-search target indexes are initialized from the target repository's `HEAD` and working tree as well.
47
+
48
+ Index the current committed snapshot and working-tree overlay:
44
49
 
45
50
  ```bash
46
51
  slopdex update-git
47
52
  ```
48
53
 
49
- `update-git` requires a clean Git worktree. It aborts for staged, unstaged, or untracked files. Do not commit or stash user changes without permission. Either ask the user to resolve the changes or explicitly index selected working-tree files:
54
+ `update-git` reconciles the committed snapshot and, when the target is the checked-out `HEAD`, indexes staged, unstaged, and untracked changes. Historical or other-branch targets remain exact committed snapshots. The Git checkpoint remains the committed base hash. After the mandatory automatic refresh, explicitly re-index selected working-tree files with:
50
55
 
51
56
  ```bash
52
57
  slopdex update-files src/service.ts src/model.ts
@@ -65,22 +70,112 @@ slopdex update-git --target HEAD
65
70
  slopdex update-git --target HEAD --rebuild-on-divergence
66
71
  ```
67
72
 
73
+ Rebuild automatically when an existing index is incompatible with the current provider, model, dimensions, strategy, schema, or repository:
74
+
75
+ ```bash
76
+ slopdex update-git --force-rebuild
77
+ ```
78
+
79
+ This removes the incompatible index and prints a warning before rebuilding it.
80
+
81
+ Skip the otherwise mandatory full working-tree refresh when Git is unavailable and a non-empty index already exists:
82
+
83
+ ```bash
84
+ slopdex search "query" --no-reindex
85
+ ```
86
+
68
87
  Check index metadata and its Git checkpoint:
69
88
 
70
89
  ```bash
71
90
  slopdex status
72
91
  ```
73
92
 
74
- Git updates read committed blobs, not working-tree contents. Explicit file updates do not advance the Git checkpoint.
93
+ Git updates reconcile committed blobs first, then overlay working-tree contents. Explicit file updates do not advance the Git checkpoint.
75
94
 
76
95
  ## Failure Handling
77
96
 
78
97
  - Preserve and report the exact failure from the requested command. Do not retry equivalent initialization commands.
79
- - A dirty-worktree error on first use means automatic Git initialization cannot proceed. Do not commit or stash changes; ask the user to clean the worktree, or use `update-files` only when indexing selected working-tree files actually satisfies the request.
80
98
  - Provider authentication and configuration failures are actionable as printed. Never display key values, and do not probe whether keys are set unless the error specifically indicates missing credentials and the user asks for diagnosis.
81
99
  - A bare system error such as `Invalid argument` is a Slopdex/runtime failure, not evidence that a different indexing command is needed. Stop retrying, report the command and error, and recommend diagnosing or updating Slopdex.
82
100
  - `slopdex --help` is the supported capability reference. There is no `slopdex --version` option; never invoke it.
83
101
 
102
+ ## Analysis Examples
103
+
104
+ ### Duplicate Analysis
105
+
106
+ ```bash
107
+ slopdex cross-search \
108
+ --cross-file-only \
109
+ --min-lines 4 \
110
+ --threshold 0.9 \
111
+ --limit 5
112
+ ```
113
+
114
+ ```text
115
+ Cluster 1 (3 functions, similarity 0.9124-0.9568)
116
+ src/auth/session.ts:18:1 :: validateSession
117
+ src/http/middleware.ts:42:1 :: authenticate
118
+ src/users/user-service.ts:27:3 :: UserService.authenticate
119
+ ```
120
+
121
+ This result found three substantial authentication functions in three files with very high similarity. Review them for repeated validation or session-handling logic that could move into one shared implementation. The middleware and service locations may represent intentional architectural layers, so treat the result as evidence to inspect rather than proof that the functions should be merged. The range describes observed links in a connected component; transitive clustering means every function is not necessarily directly similar to every other function.
122
+
123
+ ### Cohesion Analysis
124
+
125
+ ```bash
126
+ slopdex cohesion --format summary --threshold 0.8 --neighbors 20 --limit 50
127
+ ```
128
+
129
+ ```text
130
+ Cohesion: 184 functions analyzed, 37 semantic edges
131
+ same file 35.1% same folder 29.7% remote 35.2% mean distance 1.84
132
+
133
+ 1. gap 0.6053 similarity 0.9400 distance 4 reciprocal
134
+ src/auth/session.ts:18:1 :: validateSession
135
+ packages/http/middleware.ts:42:1 :: authenticate
136
+ ```
137
+
138
+ There is no universal pass/fail cutoff for cohesion, but this example has several warning signs. More than a third of weighted semantic affinity crosses folder boundaries, and the mean distance of 1.84 is above the same-folder distance of one. The top pair is strongly related at 0.94 similarity yet four distance units apart, producing a relatively high gap of 0.6053; the reciprocal match strengthens that signal. A more cohesive result under the same settings would concentrate affinity in the same-file and same-folder percentages, have a lower mean distance, and contain few high-gap remote pairs. Inspect whether shared authentication behavior belongs in one module, while accounting for the possibility that session and middleware responsibilities are intentionally separated. Compare modules or repository history rather than treating one percentage as a fixed quality threshold.
139
+
140
+ ## Reading Analysis Output
141
+
142
+ Interpret values only within the same embedding profile and similar command settings. Changing the model, threshold, neighbor count, source scope, or minimum line count changes the candidate graph and makes direct comparisons unreliable.
143
+
144
+ ### Duplicate Clusters
145
+
146
+ For `Cluster 1 (3 functions, similarity 0.9124-0.9568)`:
147
+
148
+ - `Cluster 1` is the display identifier. Clusters are ordered by function count and then name, not severity, so a lower number is not inherently worse.
149
+ - `3 functions` counts unique callables connected by observed edges. Higher can indicate a larger duplicate family, but may also result from generic helpers or transitive links.
150
+ - `similarity 0.9124-0.9568` is the weakest-to-strongest raw cosine similarity among observed edges. Higher means greater semantic resemblance according to the configured model. A high minimum means every observed link is strong; a wide range can identify a weaker bridge.
151
+ - Callable lines use `path:line:column :: qualifiedFunctionName`. Location is contextual rather than scored; inspect architectural roles before consolidating code.
152
+
153
+ ### Cohesion Summary
154
+
155
+ For `Cohesion: 184 functions analyzed, 37 semantic edges`:
156
+
157
+ - `functions analyzed` is coverage after filters, not a quality value.
158
+ - `semantic edges` counts unique top-neighbor pairs meeting the threshold before output limiting. Higher can reflect more overlapping responsibilities, but also increases with more neighbors or a lower threshold.
159
+
160
+ For `same file 35.1% same folder 29.7% remote 35.2% mean distance 1.84`:
161
+
162
+ - Higher `same file` generally means stronger co-location, though very high values can indicate oversized files.
163
+ - Higher `same folder` means related code is split into nearby modules but remains locally grouped.
164
+ - Higher `remote` means more semantic affinity crosses folder boundaries and indicates weaker physical cohesion.
165
+ - Lower `mean distance` generally means stronger physical cohesion. Zero is entirely within files, one reaches only other files in the same folder, and larger values indicate greater dispersion.
166
+
167
+ ### Cohesion Findings
168
+
169
+ For `1. gap 0.6053 similarity 0.9400 distance 4 reciprocal`:
170
+
171
+ - A lower rank number is a higher review priority.
172
+ - Higher `gap` means stronger semantic affinity combined with greater physical separation; same-file pairs have zero gap.
173
+ - Higher `similarity` means stronger model-assessed resemblance, but does not prove duplication and is not comparable across embedding profiles.
174
+ - Higher `distance` means more file and directory-tree separation: zero is the same file and one is different files in the same folder.
175
+ - `reciprocal` strengthens confidence because both functions rank each other as neighbors. Its absence means one-directional or unevaluated under a source filter.
176
+
177
+ In JSON, higher `semanticWeight` means similarity lies farther above the threshold, and higher `separationWeight` means greater path distance. `sourceTestPair: true` flags an often-intentional source/test relationship. Higher file `externalAffinityRatio` means more observed related-function affinity lies outside that file's folder; lower means relationships are primarily internal or local.
178
+
84
179
  ## Semantic Search
85
180
 
86
181
  Search indexed functions by intent:
@@ -98,17 +193,13 @@ slopdex search "validate an authenticated session" \
98
193
  --limit 10
99
194
  ```
100
195
 
101
- `--threshold` is the minimum raw cosine similarity. `--min-similarity` is an equivalent legacy option; never pass both.
196
+ `--threshold` is the minimum raw cosine similarity. Use a half-open range such as `--threshold 0.85-0.95` to include the left bound and exclude the right bound.
102
197
 
103
198
  ## Duplicate Discovery
104
199
 
105
- Find similar functions within the current index:
106
-
107
- ```bash
108
- slopdex cross-search --format summary --threshold 0.9 --limit 5
109
- ```
200
+ Cross-search defaults to connected clusters. Treat each cluster as a source-review candidate rather than proof of duplication. Lower `--threshold` to broaden discovery, or lower `--min-lines` when short wrappers are relevant.
110
201
 
111
- Summary output groups matches beneath each source:
202
+ Summary output can instead group matches beneath each source:
112
203
 
113
204
  ```text
114
205
  src/users.ts :: Users.authenticate
@@ -118,7 +209,37 @@ src/users.ts :: Users.authenticate
118
209
 
119
210
  Interpret high similarity as a candidate requiring source review, not proof of duplication. Public facade methods, API wrappers, interface implementations, and test doubles often score highly while serving distinct roles.
120
211
 
121
- Use `--threshold <minimum>-<maximum>` for an inclusive similarity range, such as `--threshold 0.85-0.95`. The range is applied before `--limit`.
212
+ Cross-search excludes one-line callables by default. Raise `--min-lines` for more substantial duplicate candidates, or use `--min-lines 1` when short wrappers are relevant:
213
+
214
+ ```bash
215
+ slopdex cross-search --min-lines 4 --threshold 0.9
216
+ ```
217
+
218
+ Filter source symbols by qualified callable name while searching the whole eligible index:
219
+
220
+ ```bash
221
+ slopdex cross-search -e '^(User|Session)\.' --source-path src --threshold 0.9
222
+ ```
223
+
224
+ `-e` / `--regexp` uses a case-sensitive JavaScript regex. In cross-search and cohesion, it restricts sources only. Combine it with `--source-path`, `--changed-since`, `--uncommitted`, and other analysis options. When both Git filters are present, sources must have changed since the commit and belong to an uncommitted file. In `search` and `search-summary`, `-e` filters result names before applying `--limit`.
225
+
226
+ To filter both source and matching candidates, use `--regex`:
227
+
228
+ ```bash
229
+ slopdex cross-search --regex '^(User|Session)\.' --threshold 0.9
230
+ ```
231
+
232
+ Use `--threshold <minimum>-<maximum>` for a half-open similarity range, such as `--threshold 0.85-0.95`. It includes the minimum, excludes the maximum, and is applied before `--limit`.
233
+
234
+ Review duplicate candidates iteratively from high confidence to lower-confidence bands instead of requesting one broad result set:
235
+
236
+ ```bash
237
+ slopdex cross-search --cross-file-only --min-lines 4 --threshold 0.9 --limit 5
238
+ slopdex cross-search --cross-file-only --min-lines 4 --threshold 0.85-0.9 --limit 5
239
+ slopdex cross-search --cross-file-only --min-lines 4 --threshold 0.8-0.85 --limit 5
240
+ ```
241
+
242
+ Because range upper bounds are exclusive, adjacent passes do not repeat boundary candidates.
122
243
 
123
244
  Same-index search reports each unordered pair once by default. Include both `A -> B` and `B -> A` only when explicitly needed:
124
245
 
@@ -126,18 +247,36 @@ Same-index search reports each unordered pair once by default. Include both `A -
126
247
  slopdex cross-search --include-symmetric-duplicates
127
248
  ```
128
249
 
250
+ Exclude candidates from the source function's file when looking for duplication across files:
251
+
252
+ ```bash
253
+ slopdex cross-search --cross-file-only --format summary --threshold 0.9
254
+ ```
255
+
256
+ Group overlapping pairs into connected components and list each function once:
257
+
258
+ ```bash
259
+ slopdex cross-search --format clusters --threshold 0.9
260
+ ```
261
+
129
262
  Restrict source functions to a file or recursive directory while still matching them against the whole codebase:
130
263
 
131
264
  ```bash
132
265
  slopdex cross-search --source-path src/services --format summary --threshold 0.9
133
266
  ```
134
267
 
135
- `--source-path` restricts only source functions. It can be combined with `--added-since`.
268
+ `--source-path` restricts only source functions. It can be combined with `-e`, `--changed-since`, and `--uncommitted`; all supplied restrictions must match.
136
269
 
137
- Restrict source functions to additions relative to a commit:
270
+ Restrict source functions to additions, modifications, and moves relative to a commit, including current working-tree changes:
138
271
 
139
272
  ```bash
140
- slopdex cross-search --added-since origin/main --format summary --threshold 0.9
273
+ slopdex cross-search --changed-since origin/main --format summary --threshold 0.9
274
+ ```
275
+
276
+ Restrict source functions to uncommitted files:
277
+
278
+ ```bash
279
+ slopdex cross-search --uncommitted --format summary --threshold 0.9
141
280
  ```
142
281
 
143
282
  Search against another compatible index:
@@ -151,12 +290,27 @@ slopdex cross-search \
151
290
  ```
152
291
 
153
292
  Cross-index searches require identical provider, model, dimensions, and embedding strategy profiles.
293
+ Use `--target-config <path>` when the target repository does not use `.slopdex/config.json`.
294
+
295
+ ## Cohesion Analysis
296
+
297
+ Use JSON when passing the report to another tool or an LLM:
298
+
299
+ ```bash
300
+ slopdex cohesion --format json --threshold 0.8 --neighbors 20 --limit 50
301
+ ```
302
+
303
+ The report includes raw similarity, physical path distance, a combined cohesion-gap score, reciprocal-neighbor status, repository metrics, file-level external affinity, and connected groups for navigation. Reciprocity is `null` when the other endpoint was not searched because a source filter is active. Source code is omitted from JSON by default; add `--include-source` only when the consumer needs complete callable bodies.
304
+
305
+ Treat findings as review candidates. Tests, facades, adapters, and intentionally layered implementations can be semantically related while correctly living in separate locations.
154
306
 
155
307
  ## Output Formats
156
308
 
157
309
  - `--format summary` is intended for human review and includes file and qualified function names.
310
+ - `--format clusters` groups overlapping pairs and lists each function once with its source line.
158
311
  - The default `search` output is formatted JSON.
159
- - The default `cross-search` output is JSONL, with one object per source function. Process it as a stream rather than a single JSON array.
312
+ - The default `cross-search` output is connected clusters. Use `--format json` for JSONL with one object per source function.
313
+ - The default `cohesion` output is one compact JSON report. Use `--format summary` for ranked pairs.
160
314
  - Functions with no matches after threshold filtering are omitted from cross-search output.
161
315
 
162
316
  Prefer JSON or JSONL when another command will consume the results. Prefer summary output when presenting candidates to a user.
@@ -170,9 +324,17 @@ Prefer JSON or JSONL when another command will consume the results. Prefer summa
170
324
  --provider <openai|jina> Embedding provider
171
325
  --model <name> Embedding model
172
326
  --dimensions <number> Embedding dimensions
327
+ --force-rebuild Rebuild an incompatible existing index
173
328
  --limit <number> Result limit
174
- --threshold <number> Minimum raw cosine similarity
175
- --format <json|summary> Output format
329
+ --neighbors <number> Semantic neighbors per function for cohesion
330
+ --threshold <number|range> Similarity threshold or half-open range
331
+ --format <json|summary|clusters> Output format
332
+ --include-source Include callable source in cohesion JSON
333
+ --cross-file-only Exclude matches from the source file
334
+ --min-lines <number> Minimum cross-search callable length
335
+ -e, --regexp <regex> Match qualified symbols (analysis: sources only)
336
+ --regex <regex> Match both analysis source and candidate names
337
+ --target-config <path> Target repository configuration file
176
338
  ```
177
339
 
178
340
  Run `slopdex --help` for the complete current option list.