@ninjaxtools/slopdex 0.3.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.
- package/.agents/skills/slopdex/SKILL.md +178 -0
- package/LICENSE +21 -0
- package/README.md +181 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +1691 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +213 -0
- package/dist/index.js +1413 -0
- package/dist/index.js.map +1 -0
- package/package.json +54 -0
- package/scripts/install-opencode-skill.mjs +11 -0
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
---
|
|
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.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Slopdex CLI
|
|
7
|
+
|
|
8
|
+
Use `slopdex` to index named JavaScript and TypeScript callables, search them by meaning, and identify similar or duplicated functions.
|
|
9
|
+
|
|
10
|
+
## Default Workflow
|
|
11
|
+
|
|
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
|
+
|
|
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`.
|
|
17
|
+
- Use `slopdex status` only when the user asks for index metadata or checkpoint information.
|
|
18
|
+
|
|
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
|
+
|
|
21
|
+
## Prerequisites
|
|
22
|
+
|
|
23
|
+
- Run commands from the repository root or pass `--root <path>`.
|
|
24
|
+
- Set `OPENAI_API_KEY` or `JINA_API_KEY` for the configured embedding provider.
|
|
25
|
+
- Use Node.js 24 or newer.
|
|
26
|
+
- Store optional configuration in `.slopdex/config.json`:
|
|
27
|
+
|
|
28
|
+
```json
|
|
29
|
+
{
|
|
30
|
+
"provider": "jina",
|
|
31
|
+
"model": "jina-embeddings-v4",
|
|
32
|
+
"dimensions": 1024,
|
|
33
|
+
"exclude": ["**/fixtures/**"]
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Do not expose API keys in commands, output, configuration files, or commits.
|
|
38
|
+
|
|
39
|
+
## Indexing
|
|
40
|
+
|
|
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
|
+
|
|
43
|
+
Index the current committed snapshot:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
slopdex update-git
|
|
47
|
+
```
|
|
48
|
+
|
|
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:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
slopdex update-files src/service.ts src/model.ts
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Remove deleted files from the index when using explicit updates:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
slopdex delete-files src/removed.ts
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Index another commit or recover after changing to a divergent branch:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
slopdex update-git --target HEAD
|
|
65
|
+
slopdex update-git --target HEAD --rebuild-on-divergence
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Check index metadata and its Git checkpoint:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
slopdex status
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Git updates read committed blobs, not working-tree contents. Explicit file updates do not advance the Git checkpoint.
|
|
75
|
+
|
|
76
|
+
## Failure Handling
|
|
77
|
+
|
|
78
|
+
- 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
|
+
- 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
|
+
- 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
|
+
- `slopdex --help` is the supported capability reference. There is no `slopdex --version` option; never invoke it.
|
|
83
|
+
|
|
84
|
+
## Semantic Search
|
|
85
|
+
|
|
86
|
+
Search indexed functions by intent:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
slopdex search "validate an authenticated session" --limit 10
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
Use compact human-readable output and filter weak results:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
slopdex search "validate an authenticated session" \
|
|
96
|
+
--format summary \
|
|
97
|
+
--threshold 0.8 \
|
|
98
|
+
--limit 10
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
`--threshold` is the minimum raw cosine similarity. `--min-similarity` is an equivalent legacy option; never pass both.
|
|
102
|
+
|
|
103
|
+
## Duplicate Discovery
|
|
104
|
+
|
|
105
|
+
Find similar functions within the current index:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
slopdex cross-search --format summary --threshold 0.9 --limit 5
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Summary output groups matches beneath each source:
|
|
112
|
+
|
|
113
|
+
```text
|
|
114
|
+
src/users.ts :: Users.authenticate
|
|
115
|
+
0.9321 src/session.ts :: validateSession
|
|
116
|
+
0.8475 src/auth.ts :: authenticate
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
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
|
+
|
|
121
|
+
Use `--threshold <minimum>-<maximum>` for an inclusive similarity range, such as `--threshold 0.85-0.95`. The range is applied before `--limit`.
|
|
122
|
+
|
|
123
|
+
Same-index search reports each unordered pair once by default. Include both `A -> B` and `B -> A` only when explicitly needed:
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
slopdex cross-search --include-symmetric-duplicates
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Restrict source functions to a file or recursive directory while still matching them against the whole codebase:
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
slopdex cross-search --source-path src/services --format summary --threshold 0.9
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
`--source-path` restricts only source functions. It can be combined with `--added-since`.
|
|
136
|
+
|
|
137
|
+
Restrict source functions to additions relative to a commit:
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
slopdex cross-search --added-since origin/main --format summary --threshold 0.9
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Search against another compatible index:
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
slopdex cross-search \
|
|
147
|
+
--target-root /path/to/other/repository \
|
|
148
|
+
--target-index /path/to/other/repository/.slopdex/index.sqlite \
|
|
149
|
+
--format summary \
|
|
150
|
+
--threshold 0.8
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Cross-index searches require identical provider, model, dimensions, and embedding strategy profiles.
|
|
154
|
+
|
|
155
|
+
## Output Formats
|
|
156
|
+
|
|
157
|
+
- `--format summary` is intended for human review and includes file and qualified function names.
|
|
158
|
+
- 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.
|
|
160
|
+
- Functions with no matches after threshold filtering are omitted from cross-search output.
|
|
161
|
+
|
|
162
|
+
Prefer JSON or JSONL when another command will consume the results. Prefer summary output when presenting candidates to a user.
|
|
163
|
+
|
|
164
|
+
## Common Options
|
|
165
|
+
|
|
166
|
+
```text
|
|
167
|
+
--root <path> Repository root
|
|
168
|
+
--config <path> Configuration file
|
|
169
|
+
--index <path> SQLite index path
|
|
170
|
+
--provider <openai|jina> Embedding provider
|
|
171
|
+
--model <name> Embedding model
|
|
172
|
+
--dimensions <number> Embedding dimensions
|
|
173
|
+
--limit <number> Result limit
|
|
174
|
+
--threshold <number> Minimum raw cosine similarity
|
|
175
|
+
--format <json|summary> Output format
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Run `slopdex --help` for the complete current option list.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 ninjaxtools
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
# slopdex
|
|
2
|
+
|
|
3
|
+
Callable-level embedding index, semantic search, and duplicate discovery for TypeScript and JavaScript repositories.
|
|
4
|
+
|
|
5
|
+
The index extracts named functions with tree-sitter, stores metadata and float32 embeddings in SQLite, and uses `sqlite-vec` for exact cosine search. It supports explicit working-tree updates, transactional Git-delta updates, and function-to-function cross-search within one codebase or between compatible indexes.
|
|
6
|
+
|
|
7
|
+
## Requirements
|
|
8
|
+
|
|
9
|
+
- Node.js 24 or newer
|
|
10
|
+
- Git for Git-tracked updates and `added-since` searches
|
|
11
|
+
- An OpenAI or Jina AI API key
|
|
12
|
+
|
|
13
|
+
## Install
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install
|
|
17
|
+
npm run build
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Install the bundled Slopdex skill for OpenCode:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npm run install:skill:opencode
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
This copies the skill to `~/.config/opencode/skills/slopdex/SKILL.md`, creating the destination directories when needed.
|
|
27
|
+
|
|
28
|
+
## Configuration
|
|
29
|
+
|
|
30
|
+
Create `.slopdex/config.json` in the repository being indexed:
|
|
31
|
+
|
|
32
|
+
```json
|
|
33
|
+
{
|
|
34
|
+
"provider": "jina",
|
|
35
|
+
"model": "jina-embeddings-v4",
|
|
36
|
+
"dimensions": 1024,
|
|
37
|
+
"exclude": ["**/fixtures/**"]
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Use `JINA_API_KEY` for Jina AI or `OPENAI_API_KEY` for OpenAI. The OpenAI default is `text-embedding-3-small` with 1536 dimensions. Provider, model, dimensions, and embedding strategy form an immutable index profile; changing one requires a new or rebuilt index.
|
|
42
|
+
|
|
43
|
+
## CLI
|
|
44
|
+
|
|
45
|
+
When a command needs an index and none exists, Slopdex prints a notice to stderr and automatically indexes committed `HEAD`. Automatic initialization requires a clean Git worktree, just like `update-git`.
|
|
46
|
+
|
|
47
|
+
Index an exact committed snapshot and record its commit:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
slopdex update-git --root /path/to/repository
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Later Git updates read only files changed between the recorded commit and `HEAD`:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
slopdex update-git --root /path/to/repository --target HEAD
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Update or delete specific working-tree files without advancing the Git checkpoint:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
slopdex update-files src/service.ts src/model.ts
|
|
63
|
+
slopdex delete-files src/removed.ts
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Search by meaning:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
slopdex search "validate an authenticated session" --limit 10
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Find the nearest functions for each indexed function that has at least one match. Results are emitted as JSONL:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
slopdex cross-search --limit 5 > similarities.jsonl
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
For a human-readable summary with each match indented beneath its source function:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
slopdex cross-search --limit 5 --format summary
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
```text
|
|
85
|
+
src/users.ts :: Users.authenticate
|
|
86
|
+
0.9321 src/session.ts :: validateSession
|
|
87
|
+
0.8475 src/auth.ts :: authenticate
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
`--format summary` also produces compact file and function names for `search`. JSON remains the default format.
|
|
91
|
+
|
|
92
|
+
Use `--threshold` to omit weaker matches. The threshold is a raw cosine similarity and is applied before `--limit`:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
slopdex cross-search --format summary --threshold 0.8 --limit 5
|
|
96
|
+
slopdex search "validate session" --format summary --threshold 0.8
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Use an inclusive range to omit matches that are either weaker or stronger than the desired band:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
slopdex cross-search --format summary --threshold 0.85-0.95 --limit 5
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
`--min-similarity` remains available as an equivalent option; do not specify both.
|
|
106
|
+
Source functions with no matches at the selected threshold are omitted.
|
|
107
|
+
For same-index searches, each function pair is shown only in its first direction by default. Use
|
|
108
|
+
`--include-symmetric-duplicates` to include both `A -> B` and `B -> A` results.
|
|
109
|
+
|
|
110
|
+
Restrict source functions to a file or every indexed file recursively under a directory. Matches are still selected from the whole target index:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
slopdex cross-search --source-path src/services --format summary
|
|
114
|
+
slopdex cross-search --source-path src/service.ts --format summary
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Restrict source functions to functions currently present but absent at a historical commit:
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
slopdex cross-search --added-since origin/main --limit 5
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Search one index against another. Both indexes must use exactly the same embedding profile:
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
slopdex cross-search \
|
|
127
|
+
--target-root /path/to/other-repository \
|
|
128
|
+
--target-index /path/to/other-repository/.slopdex/index.sqlite
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## Library
|
|
132
|
+
|
|
133
|
+
```ts
|
|
134
|
+
import {
|
|
135
|
+
JinaEmbeddingProvider,
|
|
136
|
+
crossSearch,
|
|
137
|
+
openCodeIndex,
|
|
138
|
+
} from "@ninjaxtools/slopdex";
|
|
139
|
+
|
|
140
|
+
const index = openCodeIndex({
|
|
141
|
+
rootDir: "/path/to/repository",
|
|
142
|
+
provider: new JinaEmbeddingProvider(),
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
await index.updateFromGit();
|
|
146
|
+
|
|
147
|
+
const results = await index.similaritySearch({
|
|
148
|
+
query: "validate an authenticated session",
|
|
149
|
+
limit: 10,
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
for await (const result of crossSearch({
|
|
153
|
+
source: index,
|
|
154
|
+
sourceFilter: { type: "added-since", commit: "origin/main", path: "src/services" },
|
|
155
|
+
limitPerFunction: 5,
|
|
156
|
+
})) {
|
|
157
|
+
console.log(result);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
index.close();
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Standalone functions `updateFiles`, `updateFromGit`, `similaritySearch`, and `crossSearchFunctions` are also exported.
|
|
164
|
+
|
|
165
|
+
## Semantics
|
|
166
|
+
|
|
167
|
+
- Git updates read blobs from the target commit, not dirty working-tree contents.
|
|
168
|
+
- Git updates abort when the worktree contains staged, unstaged, or untracked changes; commit or stash them first.
|
|
169
|
+
- The Git checkpoint advances only after every changed file has parsed and embedded successfully.
|
|
170
|
+
- Explicit updates mark files as working-tree sourced and do not move the checkpoint.
|
|
171
|
+
- The next Git update after those changes are committed reconciles working-tree-sourced files to the commit.
|
|
172
|
+
- `added-since X` means a current function whose logical callable identity was absent at X. It does not rely only on `firstSeenCommit`.
|
|
173
|
+
- Search output is ordered by raw cosine similarity descending, then function ID ascending.
|
|
174
|
+
- Threshold ranges are inclusive and are applied before the result limit.
|
|
175
|
+
- Same-index cross-search excludes the source function itself and lists each unordered function pair once by default.
|
|
176
|
+
|
|
177
|
+
## Development
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
npm run check
|
|
181
|
+
```
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#!/usr/bin/env node
|