@ninjaxtools/slopdex 0.8.0 → 0.10.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 +150 -270
- package/README.md +159 -211
- package/dist/cli.js +79 -38
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +5 -3
- package/dist/index.js +33 -7
- package/dist/index.js.map +1 -1
- package/docs/implementation.md +163 -0
- package/package.json +2 -1
package/dist/cli.js
CHANGED
|
@@ -346,6 +346,13 @@ function pythonIsMethod(node) {
|
|
|
346
346
|
const definition = node.parent?.type === "decorated_definition" ? node.parent : node;
|
|
347
347
|
return definition.parent?.parent?.type === "class_definition";
|
|
348
348
|
}
|
|
349
|
+
function pythonDocstring(body, content) {
|
|
350
|
+
const statement = body?.namedChildren[0];
|
|
351
|
+
if (statement?.type !== "expression_statement") return null;
|
|
352
|
+
const value = statement.namedChildren[0];
|
|
353
|
+
if (value?.type !== "string" && value?.type !== "concatenated_string") return null;
|
|
354
|
+
return content.slice(value.startIndex, value.endIndex);
|
|
355
|
+
}
|
|
349
356
|
function goReceiver(node) {
|
|
350
357
|
let type = node.childForFieldName("receiver")?.namedChildren[0]?.childForFieldName("type");
|
|
351
358
|
while (type?.type === "pointer_type") type = type.namedChildren[0] ?? null;
|
|
@@ -359,12 +366,14 @@ function collectNativeCallables(root, content, language) {
|
|
|
359
366
|
if ((!body || body.isMissing) && !node.hasError) return false;
|
|
360
367
|
const sourceNode = language === "python" && node.parent?.type === "decorated_definition" ? node.parent : node;
|
|
361
368
|
const header = content.slice(node.startIndex, body?.startIndex ?? node.endIndex).trimEnd();
|
|
369
|
+
const documentation = language === "python" && body ? pythonDocstring(body, content) : null;
|
|
362
370
|
candidates.push({
|
|
363
371
|
node: sourceNode,
|
|
364
372
|
name,
|
|
365
373
|
kind,
|
|
366
374
|
scope,
|
|
367
|
-
signature: bound ? `${name} = ${header}` : header
|
|
375
|
+
signature: bound ? `${name} = ${header}` : header,
|
|
376
|
+
...documentation ? { documentation } : {}
|
|
368
377
|
});
|
|
369
378
|
if (body) walk2(body, [...scope, name]);
|
|
370
379
|
return true;
|
|
@@ -789,7 +798,7 @@ function extractCallables(relativePath, content) {
|
|
|
789
798
|
const errors = parseDiagnostics(tree.rootNode, content, relativePath, language, candidates);
|
|
790
799
|
const occurrences = /* @__PURE__ */ new Map();
|
|
791
800
|
const callables = [];
|
|
792
|
-
for (const { node, name, kind, scope, signature: candidateSignature } of candidates) {
|
|
801
|
+
for (const { node, name, kind, scope, signature: candidateSignature, documentation } of candidates) {
|
|
793
802
|
const qualifiedName = [...scope, name].join(".");
|
|
794
803
|
const baseIdentity = `${relativePath}\0${qualifiedName}\0${kind}`;
|
|
795
804
|
const occurrence = occurrences.get(baseIdentity) ?? 0;
|
|
@@ -804,6 +813,8 @@ function extractCallables(relativePath, content) {
|
|
|
804
813
|
`kind: ${kind}`,
|
|
805
814
|
`symbol: ${qualifiedName}`,
|
|
806
815
|
signature ? `signature: ${signature}` : null,
|
|
816
|
+
documentation ? `documentation:
|
|
817
|
+
${documentation}` : null,
|
|
807
818
|
"source:",
|
|
808
819
|
source
|
|
809
820
|
].filter((value) => value !== null).join("\n");
|
|
@@ -1105,6 +1116,13 @@ var IndexDatabase = class {
|
|
|
1105
1116
|
this.#setMetadata("generation", String(expectedGeneration + 1));
|
|
1106
1117
|
});
|
|
1107
1118
|
}
|
|
1119
|
+
disableSummaries() {
|
|
1120
|
+
if (!this.summariesEnabled()) return;
|
|
1121
|
+
this.#transaction(() => {
|
|
1122
|
+
this.#setMetadata("summaries_enabled", "false");
|
|
1123
|
+
this.#setMetadata("generation", String(this.getGeneration() + 1));
|
|
1124
|
+
});
|
|
1125
|
+
}
|
|
1108
1126
|
getWorkingTreeFiles() {
|
|
1109
1127
|
return this.#db.prepare(`
|
|
1110
1128
|
SELECT path, previous_path AS previousPath
|
|
@@ -1988,7 +2006,7 @@ var CodeIndex = class {
|
|
|
1988
2006
|
async #attachEmbeddings(files, signal) {
|
|
1989
2007
|
if (this.#database.summariesEnabled()) {
|
|
1990
2008
|
if (JSON.stringify(this.#database.summaryProfile()) !== JSON.stringify(this.summaryProvider.profile)) {
|
|
1991
|
-
throw new CodeIndexError("Summary provider or model differs from this index; run
|
|
2009
|
+
throw new CodeIndexError("Summary provider or model differs from this index; run summaries enable (useSummaries() in the library) with the new provider first.");
|
|
1992
2010
|
}
|
|
1993
2011
|
await this.#attachSummaries(files, signal);
|
|
1994
2012
|
}
|
|
@@ -2087,8 +2105,12 @@ var CodeIndex = class {
|
|
|
2087
2105
|
}))), this.summaryProvider.profile, generation);
|
|
2088
2106
|
return { summariesCreated, summariesEnabled: true };
|
|
2089
2107
|
}
|
|
2108
|
+
disableSummaries() {
|
|
2109
|
+
this.#database.disableSummaries();
|
|
2110
|
+
return { summariesCreated: 0, summariesEnabled: false };
|
|
2111
|
+
}
|
|
2090
2112
|
async searchSummary(options) {
|
|
2091
|
-
if (!this.#database.summariesEnabled()) throw new CodeIndexError("Summaries are not enabled; run
|
|
2113
|
+
if (!this.#database.summariesEnabled()) throw new CodeIndexError("Summaries are not enabled; run summaries enable first.");
|
|
2092
2114
|
if (!options.query.trim()) throw new CodeIndexError("query must not be empty.");
|
|
2093
2115
|
const limit = options.limit ?? 10;
|
|
2094
2116
|
assertPositiveInteger(limit, "limit");
|
|
@@ -2225,7 +2247,7 @@ function normalizeProfile(profile) {
|
|
|
2225
2247
|
provider: profile.provider,
|
|
2226
2248
|
model: profile.model,
|
|
2227
2249
|
dimensions: profile.dimensions,
|
|
2228
|
-
strategyVersion: profile.strategyVersion ?? "callable-
|
|
2250
|
+
strategyVersion: profile.strategyVersion ?? "callable-v2"
|
|
2229
2251
|
};
|
|
2230
2252
|
}
|
|
2231
2253
|
function emptyStats(checkpoint) {
|
|
@@ -2602,7 +2624,7 @@ var JinaEmbeddingProvider = class {
|
|
|
2602
2624
|
provider: "jina",
|
|
2603
2625
|
model,
|
|
2604
2626
|
dimensions,
|
|
2605
|
-
strategyVersion: "callable-
|
|
2627
|
+
strategyVersion: "callable-v2:code-query-passage"
|
|
2606
2628
|
};
|
|
2607
2629
|
this.#url = options.baseUrl ?? "https://api.jina.ai/v1/embeddings";
|
|
2608
2630
|
}
|
|
@@ -2652,7 +2674,7 @@ var OpenAIEmbeddingProvider = class {
|
|
|
2652
2674
|
const model = options.model ?? "text-embedding-3-large";
|
|
2653
2675
|
const dimensions = options.dimensions ?? 3072;
|
|
2654
2676
|
if (!Number.isInteger(dimensions) || dimensions < 1) throw new Error("dimensions must be a positive integer.");
|
|
2655
|
-
this.profile = { provider: "openai", model, dimensions, strategyVersion: "callable-
|
|
2677
|
+
this.profile = { provider: "openai", model, dimensions, strategyVersion: "callable-v2" };
|
|
2656
2678
|
this.#url = `${(options.baseUrl ?? "https://api.openai.com/v1").replace(/\/$/, "")}/embeddings`;
|
|
2657
2679
|
}
|
|
2658
2680
|
embedDocuments(inputs, options) {
|
|
@@ -2907,6 +2929,7 @@ var parsed = (() => {
|
|
|
2907
2929
|
"force-reindex": { type: "boolean", default: false },
|
|
2908
2930
|
"no-reindex": { type: "boolean", default: false },
|
|
2909
2931
|
"ignore-errors": { type: "boolean", default: false },
|
|
2932
|
+
version: { type: "boolean", default: false },
|
|
2910
2933
|
help: { type: "boolean", short: "h", default: false }
|
|
2911
2934
|
}
|
|
2912
2935
|
});
|
|
@@ -2917,6 +2940,13 @@ var parsed = (() => {
|
|
|
2917
2940
|
}
|
|
2918
2941
|
})();
|
|
2919
2942
|
var [command, ...positionals] = parsed.positionals;
|
|
2943
|
+
var summariesAction = command === "summaries" ? positionals[0] : void 0;
|
|
2944
|
+
if (parsed.values.version) {
|
|
2945
|
+
const version = true ? "0.10.0" : JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8")).version;
|
|
2946
|
+
process.stdout.write(`${version}
|
|
2947
|
+
`);
|
|
2948
|
+
process.exit(0);
|
|
2949
|
+
}
|
|
2920
2950
|
var diagnosticIndexes = /* @__PURE__ */ new Set();
|
|
2921
2951
|
process.on("exit", () => {
|
|
2922
2952
|
if (parsed.values["ignore-errors"]) return;
|
|
@@ -2955,7 +2985,7 @@ async function main() {
|
|
|
2955
2985
|
if (command === "index-errors") {
|
|
2956
2986
|
const indexPath = path10.resolve(parsed.values.index ?? config.indexPath ?? path10.join(rootDir, ".slopdex/index.sqlite"));
|
|
2957
2987
|
const errors = existsSync(indexPath) ? readIndexErrors(indexPath) : [];
|
|
2958
|
-
if (outputFormat("
|
|
2988
|
+
if (outputFormat("summary") === "summary") {
|
|
2959
2989
|
process.stdout.write(errors.length === 0 ? "No indexing errors.\n" : `${errors.map(
|
|
2960
2990
|
(error) => `${error.path}${error.startLine === null ? "" : `:${error.startLine}:${error.startColumn}`} ${error.qualifiedName ? `:: ${error.qualifiedName} ` : ""}[${error.code}]
|
|
2961
2991
|
${error.message}`
|
|
@@ -2981,12 +3011,15 @@ async function main() {
|
|
|
2981
3011
|
const updateTarget = command === "update-git" ? parsed.values.target ?? "HEAD" : "HEAD";
|
|
2982
3012
|
const { summaryProvider: _summaryProvider, ...refreshOptions } = indexOptions;
|
|
2983
3013
|
const updateStats = await ensureIndexUpdated(
|
|
2984
|
-
command === "
|
|
3014
|
+
command === "summaries" && summariesAction === "enable" ? refreshOptions : indexOptions,
|
|
2985
3015
|
"index",
|
|
2986
3016
|
updateTarget,
|
|
2987
3017
|
parsed.values["rebuild-on-divergence"],
|
|
2988
3018
|
parsed.values["force-reindex"],
|
|
2989
|
-
parsed.values["no-reindex"]
|
|
3019
|
+
parsed.values["no-reindex"],
|
|
3020
|
+
command === "summaries" && summariesAction === "disable" ? (refreshIndex2) => {
|
|
3021
|
+
refreshIndex2.disableSummaries();
|
|
3022
|
+
} : void 0
|
|
2990
3023
|
);
|
|
2991
3024
|
const index = new CodeIndex(indexOptions);
|
|
2992
3025
|
try {
|
|
@@ -3006,22 +3039,23 @@ async function main() {
|
|
|
3006
3039
|
printJson(updateStats);
|
|
3007
3040
|
break;
|
|
3008
3041
|
}
|
|
3009
|
-
case "
|
|
3010
|
-
printJson(await index.useSummaries());
|
|
3042
|
+
case "summaries":
|
|
3043
|
+
printJson(summariesAction === "enable" ? await index.useSummaries() : index.disableSummaries());
|
|
3011
3044
|
break;
|
|
3012
3045
|
case "search":
|
|
3013
3046
|
case "search-summary": {
|
|
3014
3047
|
const query = positionals.join(" ").trim();
|
|
3015
3048
|
if (!query) throw new CodeIndexError(`${command} requires a query.`);
|
|
3016
3049
|
const threshold = similarityThreshold();
|
|
3050
|
+
const nameRegex = qualifiedNameRegex();
|
|
3017
3051
|
const results = await (command === "search-summary" ? index.searchSummary.bind(index) : index.similaritySearch.bind(index))({
|
|
3018
3052
|
query,
|
|
3019
|
-
...
|
|
3053
|
+
...nameRegex !== void 0 ? { nameRegex } : {},
|
|
3020
3054
|
limit: numberOption(parsed.values.limit, 10, "limit"),
|
|
3021
3055
|
minSimilarity: threshold.min,
|
|
3022
3056
|
...threshold.max !== void 0 ? { maxSimilarity: threshold.max } : {}
|
|
3023
3057
|
});
|
|
3024
|
-
const format = outputFormat("
|
|
3058
|
+
const format = outputFormat("summary");
|
|
3025
3059
|
if (format === "clusters") throw new CodeIndexError("clusters format is only available for cross-search.");
|
|
3026
3060
|
if (format === "summary") {
|
|
3027
3061
|
process.stdout.write(`${command === "search-summary" ? results.map((match) => `${formatSimilaritySummary([match])}
|
|
@@ -3042,10 +3076,9 @@ async function main() {
|
|
|
3042
3076
|
limit: positiveIntegerOption(parsed.values.limit, 50, "limit"),
|
|
3043
3077
|
minSimilarity: threshold.min,
|
|
3044
3078
|
...threshold.max !== void 0 ? { maxSimilarity: threshold.max } : {},
|
|
3045
|
-
minLines: minimumLines()
|
|
3046
|
-
...parsed.values.regex !== void 0 ? { nameRegex: parsed.values.regex } : {}
|
|
3079
|
+
minLines: minimumLines()
|
|
3047
3080
|
});
|
|
3048
|
-
const format = outputFormat("
|
|
3081
|
+
const format = outputFormat("summary");
|
|
3049
3082
|
if (format === "clusters") throw new CodeIndexError("clusters format is only available for cross-search.");
|
|
3050
3083
|
if (format === "summary") process.stdout.write(`${formatCohesionSummary(report)}
|
|
3051
3084
|
`);
|
|
@@ -3102,8 +3135,7 @@ async function runCrossSearch(source, sourceOptions, provider) {
|
|
|
3102
3135
|
...threshold.max !== void 0 ? { maxSimilarity: threshold.max } : {},
|
|
3103
3136
|
includeSymmetricDuplicates: parsed.values["include-symmetric-duplicates"],
|
|
3104
3137
|
crossFileOnly: parsed.values["cross-file-only"],
|
|
3105
|
-
minLines: minimumLines()
|
|
3106
|
-
...parsed.values.regex !== void 0 ? { nameRegex: parsed.values.regex } : {}
|
|
3138
|
+
minLines: minimumLines()
|
|
3107
3139
|
};
|
|
3108
3140
|
try {
|
|
3109
3141
|
if (format === "clusters") {
|
|
@@ -3130,13 +3162,14 @@ async function runCrossSearch(source, sourceOptions, provider) {
|
|
|
3130
3162
|
target?.close();
|
|
3131
3163
|
}
|
|
3132
3164
|
}
|
|
3133
|
-
async function ensureIndexUpdated(options, label, target, rebuildOnDivergence, forceRebuild, noReindex) {
|
|
3165
|
+
async function ensureIndexUpdated(options, label, target, rebuildOnDivergence, forceRebuild, noReindex, beforeRefresh) {
|
|
3134
3166
|
diagnosticIndexes.add(resolveIndexPath(options));
|
|
3135
3167
|
const initialized = await initializeMissingIndex(options, label, target, noReindex);
|
|
3136
3168
|
if (initialized) return initialized;
|
|
3137
3169
|
try {
|
|
3138
3170
|
const index = new CodeIndex(options);
|
|
3139
3171
|
try {
|
|
3172
|
+
beforeRefresh?.(index);
|
|
3140
3173
|
return await refreshIndex(index, label, target, rebuildOnDivergence, noReindex);
|
|
3141
3174
|
} finally {
|
|
3142
3175
|
index.close();
|
|
@@ -3267,19 +3300,24 @@ function numberOption(value, defaultValue, name) {
|
|
|
3267
3300
|
return parsedValue;
|
|
3268
3301
|
}
|
|
3269
3302
|
function validateInvocation() {
|
|
3270
|
-
|
|
3303
|
+
const nameRegex = qualifiedNameRegex();
|
|
3304
|
+
if (nameRegex !== void 0) {
|
|
3271
3305
|
if (!["search", "search-summary", "cross-search", "cohesion"].includes(command)) {
|
|
3272
|
-
throw new CodeIndexError("-e/--regexp is only available for search, search-summary, cross-search, and cohesion.");
|
|
3306
|
+
throw new CodeIndexError("-e/--regexp/--regex is only available for search, search-summary, cross-search, and cohesion.");
|
|
3273
3307
|
}
|
|
3274
|
-
compileNameRegex(parsed.values.
|
|
3308
|
+
compileNameRegex(nameRegex, parsed.values.regex !== void 0 ? "--regex value" : "-e/--regexp value");
|
|
3275
3309
|
}
|
|
3276
3310
|
switch (command) {
|
|
3277
3311
|
case "index-errors":
|
|
3278
|
-
if (outputFormat("
|
|
3312
|
+
if (outputFormat("summary") === "clusters") throw new CodeIndexError("clusters format is only available for cross-search.");
|
|
3279
3313
|
return;
|
|
3280
3314
|
case "status":
|
|
3281
3315
|
case "update-git":
|
|
3282
|
-
|
|
3316
|
+
return;
|
|
3317
|
+
case "summaries":
|
|
3318
|
+
if (positionals.length !== 1 || summariesAction !== "enable" && summariesAction !== "disable") {
|
|
3319
|
+
throw new CodeIndexError("summaries requires enable or disable.");
|
|
3320
|
+
}
|
|
3283
3321
|
return;
|
|
3284
3322
|
case "update-files":
|
|
3285
3323
|
if (positionals.length === 0) throw new CodeIndexError("update-files requires at least one path.");
|
|
@@ -3292,7 +3330,7 @@ function validateInvocation() {
|
|
|
3292
3330
|
if (!positionals.join(" ").trim()) throw new CodeIndexError(`${command} requires a query.`);
|
|
3293
3331
|
validateLimit(10);
|
|
3294
3332
|
similarityThreshold();
|
|
3295
|
-
if (outputFormat("
|
|
3333
|
+
if (outputFormat("summary") === "clusters") throw new CodeIndexError("clusters format is only available for cross-search.");
|
|
3296
3334
|
return;
|
|
3297
3335
|
}
|
|
3298
3336
|
case "cross-search":
|
|
@@ -3306,16 +3344,14 @@ function validateInvocation() {
|
|
|
3306
3344
|
similarityThreshold();
|
|
3307
3345
|
outputFormat("clusters");
|
|
3308
3346
|
minimumLines();
|
|
3309
|
-
functionNameRegex();
|
|
3310
3347
|
crossSearchSourceFilter();
|
|
3311
3348
|
return;
|
|
3312
3349
|
case "cohesion":
|
|
3313
3350
|
positiveIntegerOption(parsed.values.limit, 50, "limit");
|
|
3314
3351
|
positiveIntegerOption(parsed.values.neighbors, 20, "neighbors");
|
|
3315
3352
|
cohesionThreshold();
|
|
3316
|
-
if (outputFormat("
|
|
3353
|
+
if (outputFormat("summary") === "clusters") throw new CodeIndexError("clusters format is only available for cross-search.");
|
|
3317
3354
|
minimumLines();
|
|
3318
|
-
functionNameRegex();
|
|
3319
3355
|
crossSearchSourceFilter();
|
|
3320
3356
|
return;
|
|
3321
3357
|
default:
|
|
@@ -3361,15 +3397,19 @@ function minimumLines() {
|
|
|
3361
3397
|
if (!Number.isInteger(value) || value < 1) throw new CodeIndexError("min-lines must be a positive integer.");
|
|
3362
3398
|
return value;
|
|
3363
3399
|
}
|
|
3364
|
-
function
|
|
3365
|
-
|
|
3400
|
+
function qualifiedNameRegex() {
|
|
3401
|
+
if (parsed.values.regexp !== void 0 && parsed.values.regex !== void 0 && parsed.values.regexp !== parsed.values.regex) {
|
|
3402
|
+
throw new CodeIndexError("-e/--regexp and --regex are aliases and cannot use different values.");
|
|
3403
|
+
}
|
|
3404
|
+
return parsed.values.regexp ?? parsed.values.regex;
|
|
3366
3405
|
}
|
|
3367
3406
|
function crossSearchSourceFilter() {
|
|
3368
3407
|
const changedSince = parsed.values["changed-since"];
|
|
3369
3408
|
const uncommitted = parsed.values.uncommitted;
|
|
3409
|
+
const nameRegex = qualifiedNameRegex();
|
|
3370
3410
|
const restrictions = {
|
|
3371
3411
|
...parsed.values["source-path"] ? { path: parsed.values["source-path"] } : {},
|
|
3372
|
-
...
|
|
3412
|
+
...nameRegex !== void 0 ? { nameRegex } : {}
|
|
3373
3413
|
};
|
|
3374
3414
|
if (changedSince) return { type: "changed-since", commit: changedSince, ...uncommitted ? { uncommitted: true } : {}, ...restrictions };
|
|
3375
3415
|
if (uncommitted) return { type: "uncommitted", ...restrictions };
|
|
@@ -3432,7 +3472,7 @@ Commands:
|
|
|
3432
3472
|
delete-files <path...> Remove specific files from the index
|
|
3433
3473
|
update-git Index a Git snapshot plus working-tree changes
|
|
3434
3474
|
search <query> Search functions by semantic similarity
|
|
3435
|
-
|
|
3475
|
+
summaries <enable|disable> Enable or disable automatic purpose summaries
|
|
3436
3476
|
search-summary <query> Search functions using summary embeddings
|
|
3437
3477
|
cross-search Find nearest functions for each source function
|
|
3438
3478
|
cohesion Rank related functions separated across the repository
|
|
@@ -3520,6 +3560,7 @@ Reading Analysis Output:
|
|
|
3520
3560
|
Higher means more of a file's related affinity lies outside its folder
|
|
3521
3561
|
|
|
3522
3562
|
Options:
|
|
3563
|
+
--version Show the package version
|
|
3523
3564
|
--root <path> Repository root (default: current directory)
|
|
3524
3565
|
--config <path> Config file (default: .slopdex/config.json)
|
|
3525
3566
|
--index <path> SQLite index path
|
|
@@ -3535,13 +3576,13 @@ Options:
|
|
|
3535
3576
|
--limit <number> Search result limit
|
|
3536
3577
|
--neighbors <number> Semantic neighbors per function for cohesion (default: 20)
|
|
3537
3578
|
--threshold <number|range> Show similarities at/above a value or within a range
|
|
3538
|
-
--format <json|summary|clusters> Output format (
|
|
3579
|
+
--format <json|summary|clusters> Output format (default: summary; cross-search: clusters)
|
|
3539
3580
|
--include-source Include function source in cohesion JSON
|
|
3540
3581
|
--include-symmetric-duplicates Show both directions of same-index matches
|
|
3541
3582
|
--cross-file-only Exclude matches from the source file
|
|
3542
3583
|
--min-lines <number> Minimum callable length for cross-search (default: 2)
|
|
3543
3584
|
-e, --regexp <regex> Filter qualified symbols (analysis: sources only)
|
|
3544
|
-
--regex <regex>
|
|
3585
|
+
--regex <regex> Alias for -e/--regexp
|
|
3545
3586
|
--changed-since <commit> Search added, modified, or moved functions
|
|
3546
3587
|
--uncommitted Search functions from uncommitted files
|
|
3547
3588
|
--source-path <path> Restrict cross-search sources to a file or directory
|
|
@@ -3569,7 +3610,7 @@ Other Examples:
|
|
|
3569
3610
|
slopdex search "validate an authenticated session" --limit 10
|
|
3570
3611
|
|
|
3571
3612
|
Enable purpose summaries, then search by their meaning:
|
|
3572
|
-
slopdex
|
|
3613
|
+
slopdex summaries enable
|
|
3573
3614
|
slopdex search-summary "maintain the repository index" --format summary
|
|
3574
3615
|
|
|
3575
3616
|
Review functions under a path against the whole codebase:
|
|
@@ -3584,10 +3625,10 @@ Other Examples:
|
|
|
3584
3625
|
Filter semantic search results by qualified symbol before applying the limit:
|
|
3585
3626
|
slopdex search "validate session" -e '^Session\\.' --limit 10
|
|
3586
3627
|
|
|
3587
|
-
-e/--regexp uses a case-sensitive JavaScript regex on qualified names. For cross-search
|
|
3628
|
+
-e/--regexp/--regex uses a case-sensitive JavaScript regex on qualified names. For cross-search
|
|
3588
3629
|
and cohesion it filters sources only; targets keep their normal eligibility rules.
|
|
3589
3630
|
With --changed-since and --uncommitted, sources must be changed since the commit and
|
|
3590
|
-
belong to an uncommitted file. --source-path and
|
|
3631
|
+
belong to an uncommitted file. --source-path and the regex filter further narrow that intersection.
|
|
3591
3632
|
`);
|
|
3592
3633
|
}
|
|
3593
3634
|
//# sourceMappingURL=cli.js.map
|