@autorag/librarian 2.6.1 → 2.6.2
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/dist/agent/agent.d.ts +2 -0
- package/dist/cli/config.d.ts +2 -0
- package/dist/cli/index.js +59 -16
- package/dist/core.js +55 -13
- package/dist/dupey/filter.d.ts +1 -1
- package/dist/index.js +56 -13
- package/dist/mirror/index-store.d.ts +1 -1
- package/dist/mirror/index.d.ts +1 -1
- package/dist/mirror/sync.d.ts +3 -0
- package/package.json +1 -1
- package/skills/autorag/SKILL.md +8 -0
package/dist/agent/agent.d.ts
CHANGED
|
@@ -158,6 +158,7 @@ export interface AutoRAGAgentOptions {
|
|
|
158
158
|
parserOptions?: DefaultParserRegistryOptions;
|
|
159
159
|
dupey?: DupeyCliOptions | false;
|
|
160
160
|
excludeExactDuplicates?: boolean;
|
|
161
|
+
excludePaths?: readonly string[];
|
|
161
162
|
datasourceSkills?: readonly DatasourceSkill[];
|
|
162
163
|
datasourceAccess?: DatasourceAccessContextOptions;
|
|
163
164
|
/** Non-fatal diagnostics from config/agent construction (e.g. skipped unknown datasources). */
|
|
@@ -242,6 +243,7 @@ export declare class AutoRAGAgent {
|
|
|
242
243
|
private readonly parserOptions;
|
|
243
244
|
private readonly dupeyOptions;
|
|
244
245
|
private readonly excludeExactDuplicates;
|
|
246
|
+
private readonly excludePaths;
|
|
245
247
|
private readonly baseSystemPromptConfig;
|
|
246
248
|
private readonly droppedCallerToolNames;
|
|
247
249
|
private readonly searchTimeoutMs;
|
package/dist/cli/config.d.ts
CHANGED
|
@@ -111,6 +111,8 @@ export interface CliConfig {
|
|
|
111
111
|
timeoutMs?: number;
|
|
112
112
|
};
|
|
113
113
|
excludeExactDuplicates?: boolean;
|
|
114
|
+
/** Absolute or workspace-relative files/directories omitted from local indexing. */
|
|
115
|
+
excludePaths?: string[];
|
|
114
116
|
/** Trusted datasource skill configuration (skill name → config). */
|
|
115
117
|
datasources?: DatasourcesConfig;
|
|
116
118
|
/** Trusted datasource allow-tags/allow-scopes. Absent ⇒ default-deny. */
|
package/dist/cli/index.js
CHANGED
|
@@ -2301,7 +2301,7 @@ function isParsedMirrorSkipEntry(value) {
|
|
|
2301
2301
|
return isRecord2(value) && typeof value.virtualPath === "string" && typeof value.sourcePath === "string" && isParsedMirrorSkipReason(value.reason) && typeof value.sourceMtimeNs === "number" && typeof value.sourceSizeBytes === "number" && typeof value.updatedAt === "string";
|
|
2302
2302
|
}
|
|
2303
2303
|
function isParsedMirrorSkipReason(value) {
|
|
2304
|
-
return value === "duplicate-excluded" || value === "parser-skipped" || value === "parser-failed";
|
|
2304
|
+
return value === "duplicate-excluded" || value === "user-excluded" || value === "parser-skipped" || value === "parser-failed";
|
|
2305
2305
|
}
|
|
2306
2306
|
function isParsedMirrorEntry(value) {
|
|
2307
2307
|
return isRecord2(value) && typeof value.virtualPath === "string" && typeof value.sourcePath === "string" && typeof value.outputPath === "string" && typeof value.parserName === "string" && typeof value.sourceMtimeNs === "number" && typeof value.sourceSizeBytes === "number" && typeof value.updatedAt === "string";
|
|
@@ -11043,6 +11043,10 @@ function resolveConfig(input) {
|
|
|
11043
11043
|
const configOrigin = dirname10(resolve6(configPath));
|
|
11044
11044
|
const fileWorkspacePath = typeof file.workspacePath === "string" ? resolvePersistedPath(file.workspacePath, configOrigin) : undefined;
|
|
11045
11045
|
const fileSearchPaths = file.searchPaths ? resolveSearchPaths(file.searchPaths, fileWorkspacePath ?? configOrigin) : undefined;
|
|
11046
|
+
if (file.excludePaths !== undefined && (!Array.isArray(file.excludePaths) || file.excludePaths.some((path) => typeof path !== "string" || path.length === 0))) {
|
|
11047
|
+
throw new ConfigError("Config field 'excludePaths' must be a non-empty string array");
|
|
11048
|
+
}
|
|
11049
|
+
const fileExcludePaths = file.excludePaths ? resolveSearchPaths(file.excludePaths, fileWorkspacePath ?? configOrigin) : undefined;
|
|
11046
11050
|
const searchPaths = flagSearchPaths ?? envSearchPaths ?? fileSearchPaths ?? defaultSearchPaths;
|
|
11047
11051
|
const flagWorkspacePath = flagString(flags, "workspace");
|
|
11048
11052
|
const envWorkspacePath = envString(env, "AUTORAG_WORKSPACE");
|
|
@@ -11066,6 +11070,8 @@ function resolveConfig(input) {
|
|
|
11066
11070
|
};
|
|
11067
11071
|
if (model)
|
|
11068
11072
|
config.model = model;
|
|
11073
|
+
if (fileExcludePaths !== undefined)
|
|
11074
|
+
config.excludePaths = fileExcludePaths;
|
|
11069
11075
|
const normalized = normalizeIndexingConfig({
|
|
11070
11076
|
minSync: file.minSync
|
|
11071
11077
|
});
|
|
@@ -11182,6 +11188,8 @@ function buildAgentOptions(config) {
|
|
|
11182
11188
|
};
|
|
11183
11189
|
}
|
|
11184
11190
|
opts.excludeExactDuplicates = config.excludeExactDuplicates ?? true;
|
|
11191
|
+
if (config.excludePaths !== undefined)
|
|
11192
|
+
opts.excludePaths = config.excludePaths;
|
|
11185
11193
|
if (config.datasources !== undefined) {
|
|
11186
11194
|
const { skills, unknown } = buildDatasourceSkills(config.datasources, config.workspacePath);
|
|
11187
11195
|
if (skills.length > 0)
|
|
@@ -11437,6 +11445,8 @@ function writeDefaultConfig(path, partial, opts = {}) {
|
|
|
11437
11445
|
full.jikji = partial.jikji ?? {};
|
|
11438
11446
|
full.dupey = partial.dupey ?? { enabled: true };
|
|
11439
11447
|
full.excludeExactDuplicates = partial.excludeExactDuplicates ?? true;
|
|
11448
|
+
if (partial.excludePaths !== undefined)
|
|
11449
|
+
full.excludePaths = resolveSearchPaths(partial.excludePaths, workspacePath);
|
|
11440
11450
|
if (partial.parserOptions)
|
|
11441
11451
|
full.parserOptions = partial.parserOptions;
|
|
11442
11452
|
if (partial.p2p !== undefined)
|
|
@@ -12234,7 +12244,7 @@ var init_cli = __esm(() => {
|
|
|
12234
12244
|
// src/dupey/filter.ts
|
|
12235
12245
|
import { stat as stat5 } from "node:fs/promises";
|
|
12236
12246
|
import { resolve as resolve8 } from "node:path";
|
|
12237
|
-
async function selectExactDuplicateExclusions(root, scan) {
|
|
12247
|
+
async function selectExactDuplicateExclusions(root, scan, isUnavailable) {
|
|
12238
12248
|
const byHash = new Map;
|
|
12239
12249
|
for (const file of scan.files) {
|
|
12240
12250
|
if (typeof file.content_hash !== "string" || file.content_hash.length === 0)
|
|
@@ -12260,11 +12270,12 @@ async function selectExactDuplicateExclusions(root, scan) {
|
|
|
12260
12270
|
}
|
|
12261
12271
|
}));
|
|
12262
12272
|
ranked.sort((a, b) => b.mtimeMs - a.mtimeMs || a.path.localeCompare(b.path));
|
|
12263
|
-
const
|
|
12273
|
+
const candidates = isUnavailable === undefined ? ranked : ranked.filter(({ path }) => !isUnavailable(path));
|
|
12274
|
+
const keeper = candidates[0]?.path;
|
|
12264
12275
|
if (!keeper)
|
|
12265
12276
|
continue;
|
|
12266
12277
|
keepers.add(keeper);
|
|
12267
|
-
for (const candidate of
|
|
12278
|
+
for (const candidate of candidates.slice(1))
|
|
12268
12279
|
excluded.add(candidate.path);
|
|
12269
12280
|
}
|
|
12270
12281
|
return { excluded, keepers, errors };
|
|
@@ -14939,7 +14950,7 @@ var init_minsync = __esm(() => {
|
|
|
14939
14950
|
import { randomUUID as randomUUID6 } from "node:crypto";
|
|
14940
14951
|
import { existsSync as existsSync21, mkdirSync as mkdirSync14, renameSync as renameSync7, rmSync as rmSync4, writeFileSync as writeFileSync13 } from "node:fs";
|
|
14941
14952
|
import { opendir, readFile as readFile5, stat as stat6 } from "node:fs/promises";
|
|
14942
|
-
import { dirname as dirname15, extname as extname6, resolve as resolve11 } from "node:path";
|
|
14953
|
+
import { dirname as dirname15, extname as extname6, resolve as resolve11, sep as sep4 } from "node:path";
|
|
14943
14954
|
async function syncParsedMirrors(options) {
|
|
14944
14955
|
const registry = options.registry ?? createDefaultParserRegistry(options.parserOptions);
|
|
14945
14956
|
const maxSourceBytes = options.maxSourceBytes ?? DEFAULT_MAX_SOURCE_BYTES;
|
|
@@ -14978,6 +14989,13 @@ async function syncParsedMirrors(options) {
|
|
|
14978
14989
|
sinceCheckpoint = 0;
|
|
14979
14990
|
};
|
|
14980
14991
|
for (const entry of current) {
|
|
14992
|
+
if (isPathExcluded(entry.sourcePath, options.userExcludedSourcePaths)) {
|
|
14993
|
+
deleted += removePrevious(options.root, previous, entry.virtualPath);
|
|
14994
|
+
handledPrevious.add(entry.virtualPath);
|
|
14995
|
+
skipped += 1;
|
|
14996
|
+
recordSkip(entry, "user-excluded");
|
|
14997
|
+
continue;
|
|
14998
|
+
}
|
|
14981
14999
|
if (options.excludeSourcePaths?.has(entry.sourcePath)) {
|
|
14982
15000
|
deleted += removePrevious(options.root, previous, entry.virtualPath);
|
|
14983
15001
|
handledPrevious.add(entry.virtualPath);
|
|
@@ -15098,7 +15116,7 @@ async function detectMirrorStaleness(options) {
|
|
|
15098
15116
|
const previous = loadMirrorIndex(options.root);
|
|
15099
15117
|
const diagnostics = [];
|
|
15100
15118
|
for (const entry of current) {
|
|
15101
|
-
if (options.excludeSourcePaths?.has(entry.sourcePath))
|
|
15119
|
+
if (options.excludeSourcePaths?.has(entry.sourcePath) || isPathExcluded(entry.sourcePath, options.userExcludedSourcePaths))
|
|
15102
15120
|
continue;
|
|
15103
15121
|
if (!registry.getForVirtualPath(entry.virtualPath))
|
|
15104
15122
|
continue;
|
|
@@ -15106,9 +15124,10 @@ async function detectMirrorStaleness(options) {
|
|
|
15106
15124
|
if (prev !== undefined && prev.sourceMtimeNs === entry.mtimeNs && prev.sourceSizeBytes === entry.sizeBytes)
|
|
15107
15125
|
continue;
|
|
15108
15126
|
const prevSkip = previous.skipped?.[entry.virtualPath];
|
|
15109
|
-
|
|
15127
|
+
const honoredSkip = prevSkip?.reason === "user-excluded" ? undefined : prevSkip;
|
|
15128
|
+
if (honoredSkip !== undefined && honoredSkip.sourceMtimeNs === entry.mtimeNs && honoredSkip.sourceSizeBytes === entry.sizeBytes)
|
|
15110
15129
|
continue;
|
|
15111
|
-
const known = prev ??
|
|
15130
|
+
const known = prev ?? honoredSkip;
|
|
15112
15131
|
const reason = known === undefined ? "source-added" : known.sourceMtimeNs !== entry.mtimeNs && known.sourceSizeBytes !== entry.sizeBytes ? "mtime-and-size-changed" : known.sourceMtimeNs !== entry.mtimeNs ? "mtime-changed" : "size-changed";
|
|
15113
15132
|
diagnostics.push({
|
|
15114
15133
|
code: "stale-index",
|
|
@@ -15133,6 +15152,15 @@ function normalizeExtension2(extension) {
|
|
|
15133
15152
|
const lower = extension.toLowerCase();
|
|
15134
15153
|
return lower.startsWith(".") ? lower : `.${lower}`;
|
|
15135
15154
|
}
|
|
15155
|
+
function isPathExcluded(sourcePath, excluded) {
|
|
15156
|
+
if (excluded === undefined)
|
|
15157
|
+
return false;
|
|
15158
|
+
for (const excludedPath of excluded) {
|
|
15159
|
+
if (sourcePath === excludedPath || sourcePath.startsWith(`${excludedPath}${sep4}`))
|
|
15160
|
+
return true;
|
|
15161
|
+
}
|
|
15162
|
+
return false;
|
|
15163
|
+
}
|
|
15136
15164
|
async function listCurrentFiles(searchPaths, supportedExtensions) {
|
|
15137
15165
|
const entries = [];
|
|
15138
15166
|
for (const sourceRoot of planSourceRoots(searchPaths)) {
|
|
@@ -16225,7 +16253,7 @@ var init_model_auth = __esm(() => {
|
|
|
16225
16253
|
// src/filesystem/cloud-placeholder.ts
|
|
16226
16254
|
import { execFile as execFile3 } from "node:child_process";
|
|
16227
16255
|
import { lstat } from "node:fs/promises";
|
|
16228
|
-
import { dirname as dirname17, relative as relative6, sep as
|
|
16256
|
+
import { dirname as dirname17, relative as relative6, sep as sep5 } from "node:path";
|
|
16229
16257
|
import { promisify as promisify2 } from "node:util";
|
|
16230
16258
|
function pathLooksLikeCloudRoot(target) {
|
|
16231
16259
|
const normalized = target.replaceAll("\\", "/");
|
|
@@ -24922,6 +24950,7 @@ class AutoRAGAgent {
|
|
|
24922
24950
|
parserOptions;
|
|
24923
24951
|
dupeyOptions;
|
|
24924
24952
|
excludeExactDuplicates;
|
|
24953
|
+
excludePaths;
|
|
24925
24954
|
baseSystemPromptConfig;
|
|
24926
24955
|
droppedCallerToolNames;
|
|
24927
24956
|
searchTimeoutMs;
|
|
@@ -24960,6 +24989,7 @@ class AutoRAGAgent {
|
|
|
24960
24989
|
this.parserOptions = resolveParserOptions(options.parserOptions, this.languages);
|
|
24961
24990
|
this.dupeyOptions = options.dupey ?? {};
|
|
24962
24991
|
this.excludeExactDuplicates = options.excludeExactDuplicates ?? true;
|
|
24992
|
+
this.excludePaths = (options.excludePaths ?? []).map(pinExcludedPath);
|
|
24963
24993
|
if (options.minSync !== false) {
|
|
24964
24994
|
const minSyncOpts = options.minSync ?? { autoInstall: true };
|
|
24965
24995
|
this.minSyncMethod = new MinSyncVectorMethod({
|
|
@@ -25894,7 +25924,8 @@ ${initialRetrievalContext ?? "Pending; continue only with a brief progress state
|
|
|
25894
25924
|
const staleDiagnostics = await detectMirrorStaleness({
|
|
25895
25925
|
root: this.workspaceProjectRoot,
|
|
25896
25926
|
searchPaths: this.searchPaths,
|
|
25897
|
-
parserOptions: this.parserOptions
|
|
25927
|
+
parserOptions: this.parserOptions,
|
|
25928
|
+
userExcludedSourcePaths: new Set(this.excludePaths)
|
|
25898
25929
|
});
|
|
25899
25930
|
const diagnostics = [
|
|
25900
25931
|
...this.startupDiagnostics,
|
|
@@ -26017,7 +26048,8 @@ ${initialRetrievalContext ?? "Pending; continue only with a brief progress state
|
|
|
26017
26048
|
searchPaths: this.searchPaths,
|
|
26018
26049
|
force,
|
|
26019
26050
|
parserOptions: this.parserOptions,
|
|
26020
|
-
excludeSourcePaths: duplicateFilter.excluded
|
|
26051
|
+
excludeSourcePaths: duplicateFilter.excluded,
|
|
26052
|
+
userExcludedSourcePaths: new Set(this.excludePaths)
|
|
26021
26053
|
});
|
|
26022
26054
|
}
|
|
26023
26055
|
async scanMirrorStaleness() {
|
|
@@ -26026,7 +26058,8 @@ ${initialRetrievalContext ?? "Pending; continue only with a brief progress state
|
|
|
26026
26058
|
root: this.workspaceProjectRoot,
|
|
26027
26059
|
searchPaths: this.searchPaths,
|
|
26028
26060
|
parserOptions: this.parserOptions,
|
|
26029
|
-
excludeSourcePaths: duplicateFilter.excluded
|
|
26061
|
+
excludeSourcePaths: duplicateFilter.excluded,
|
|
26062
|
+
userExcludedSourcePaths: new Set(this.excludePaths)
|
|
26030
26063
|
});
|
|
26031
26064
|
return {
|
|
26032
26065
|
scanned: 0,
|
|
@@ -26041,10 +26074,11 @@ ${initialRetrievalContext ?? "Pending; continue only with a brief progress state
|
|
|
26041
26074
|
if (!this.excludeExactDuplicates || this.dupeyOptions === false)
|
|
26042
26075
|
return { excluded: new Set };
|
|
26043
26076
|
const excluded = new Set;
|
|
26077
|
+
const userExcluded = new Set(this.excludePaths);
|
|
26044
26078
|
for (const searchPath of this.searchPaths) {
|
|
26045
26079
|
try {
|
|
26046
26080
|
const scan = await scanWithDupey(searchPath, this.dupeyOptions || {});
|
|
26047
|
-
const selected = await selectExactDuplicateExclusions(searchPath, scan);
|
|
26081
|
+
const selected = await selectExactDuplicateExclusions(searchPath, scan, (path) => isPathExcluded(path, userExcluded));
|
|
26048
26082
|
for (const path of selected.excluded)
|
|
26049
26083
|
excluded.add(path);
|
|
26050
26084
|
} catch (error) {
|
|
@@ -26459,6 +26493,14 @@ function toMinSyncReasonDiagnostic(reason) {
|
|
|
26459
26493
|
source: "minsync"
|
|
26460
26494
|
};
|
|
26461
26495
|
}
|
|
26496
|
+
function pinExcludedPath(path) {
|
|
26497
|
+
const resolvedPath = resolve13(path);
|
|
26498
|
+
try {
|
|
26499
|
+
return join30(realpathSync4(dirname22(resolvedPath)), basename12(resolvedPath));
|
|
26500
|
+
} catch {
|
|
26501
|
+
return resolvedPath;
|
|
26502
|
+
}
|
|
26503
|
+
}
|
|
26462
26504
|
function pinSearchRoot(searchPath) {
|
|
26463
26505
|
const resolvedPath = resolve13(searchPath);
|
|
26464
26506
|
let canonicalPath;
|
|
@@ -26948,7 +26990,7 @@ var init_memory2 = __esm(() => {
|
|
|
26948
26990
|
|
|
26949
26991
|
// src/cli/commands/index.ts
|
|
26950
26992
|
import { existsSync as existsSync28, lstatSync as lstatSync3, rmSync as rmSync6 } from "node:fs";
|
|
26951
|
-
import { join as join31, resolve as resolve14, sep as
|
|
26993
|
+
import { join as join31, resolve as resolve14, sep as sep6 } from "node:path";
|
|
26952
26994
|
async function runIndex(ctx) {
|
|
26953
26995
|
const sub = ctx.positionals[0];
|
|
26954
26996
|
if (sub !== "reset" && sub !== "rebuild") {
|
|
@@ -27046,7 +27088,7 @@ function resolveResetScope(methods) {
|
|
|
27046
27088
|
};
|
|
27047
27089
|
}
|
|
27048
27090
|
function isWithin(target, base) {
|
|
27049
|
-
const prefix = base.endsWith(
|
|
27091
|
+
const prefix = base.endsWith(sep6) ? base : `${base}${sep6}`;
|
|
27050
27092
|
return target === base || target.startsWith(prefix);
|
|
27051
27093
|
}
|
|
27052
27094
|
var ALL_RESET_TARGETS, ALL_RESET_TARGET_NAMES;
|
|
@@ -28965,7 +29007,8 @@ async function runLiteRetrieve(ctx) {
|
|
|
28965
29007
|
const staleDiagnostics = await detectMirrorStaleness({
|
|
28966
29008
|
root: workspacePath,
|
|
28967
29009
|
searchPaths: lite.config.searchPaths,
|
|
28968
|
-
parserOptions: resolveParserOptions(lite.config.parserOptions, normalizeLanguages(lite.config.languages))
|
|
29010
|
+
parserOptions: resolveParserOptions(lite.config.parserOptions, normalizeLanguages(lite.config.languages)),
|
|
29011
|
+
userExcludedSourcePaths: new Set(lite.config.excludePaths ?? [])
|
|
28969
29012
|
});
|
|
28970
29013
|
if (staleDiagnostics.length > 0 && ctx.flags.strict === true) {
|
|
28971
29014
|
const envelope = {
|
package/dist/core.js
CHANGED
|
@@ -192,7 +192,7 @@ function isParsedMirrorSkipEntry(value) {
|
|
|
192
192
|
return isRecord(value) && typeof value.virtualPath === "string" && typeof value.sourcePath === "string" && isParsedMirrorSkipReason(value.reason) && typeof value.sourceMtimeNs === "number" && typeof value.sourceSizeBytes === "number" && typeof value.updatedAt === "string";
|
|
193
193
|
}
|
|
194
194
|
function isParsedMirrorSkipReason(value) {
|
|
195
|
-
return value === "duplicate-excluded" || value === "parser-skipped" || value === "parser-failed";
|
|
195
|
+
return value === "duplicate-excluded" || value === "user-excluded" || value === "parser-skipped" || value === "parser-failed";
|
|
196
196
|
}
|
|
197
197
|
function isParsedMirrorEntry(value) {
|
|
198
198
|
return isRecord(value) && typeof value.virtualPath === "string" && typeof value.sourcePath === "string" && typeof value.outputPath === "string" && typeof value.parserName === "string" && typeof value.sourceMtimeNs === "number" && typeof value.sourceSizeBytes === "number" && typeof value.updatedAt === "string";
|
|
@@ -548,7 +548,7 @@ var init_cli = __esm(() => {
|
|
|
548
548
|
// src/dupey/filter.ts
|
|
549
549
|
import { stat } from "node:fs/promises";
|
|
550
550
|
import { resolve as resolve5 } from "node:path";
|
|
551
|
-
async function selectExactDuplicateExclusions(root, scan) {
|
|
551
|
+
async function selectExactDuplicateExclusions(root, scan, isUnavailable) {
|
|
552
552
|
const byHash = new Map;
|
|
553
553
|
for (const file of scan.files) {
|
|
554
554
|
if (typeof file.content_hash !== "string" || file.content_hash.length === 0)
|
|
@@ -574,11 +574,12 @@ async function selectExactDuplicateExclusions(root, scan) {
|
|
|
574
574
|
}
|
|
575
575
|
}));
|
|
576
576
|
ranked.sort((a, b) => b.mtimeMs - a.mtimeMs || a.path.localeCompare(b.path));
|
|
577
|
-
const
|
|
577
|
+
const candidates = isUnavailable === undefined ? ranked : ranked.filter(({ path }) => !isUnavailable(path));
|
|
578
|
+
const keeper = candidates[0]?.path;
|
|
578
579
|
if (!keeper)
|
|
579
580
|
continue;
|
|
580
581
|
keepers.add(keeper);
|
|
581
|
-
for (const candidate of
|
|
582
|
+
for (const candidate of candidates.slice(1))
|
|
582
583
|
excluded.add(candidate.path);
|
|
583
584
|
}
|
|
584
585
|
return { excluded, keepers, errors };
|
|
@@ -5475,7 +5476,7 @@ var init_defaults = __esm(() => {
|
|
|
5475
5476
|
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
5476
5477
|
import { existsSync as existsSync12, mkdirSync as mkdirSync6, renameSync as renameSync5, rmSync as rmSync3, writeFileSync as writeFileSync6 } from "node:fs";
|
|
5477
5478
|
import { opendir, readFile as readFile3, stat as stat4 } from "node:fs/promises";
|
|
5478
|
-
import { dirname as dirname7, extname as extname4, resolve as resolve9 } from "node:path";
|
|
5479
|
+
import { dirname as dirname7, extname as extname4, resolve as resolve9, sep as sep4 } from "node:path";
|
|
5479
5480
|
async function syncParsedMirrors(options) {
|
|
5480
5481
|
const registry = options.registry ?? createDefaultParserRegistry(options.parserOptions);
|
|
5481
5482
|
const maxSourceBytes = options.maxSourceBytes ?? DEFAULT_MAX_SOURCE_BYTES;
|
|
@@ -5514,6 +5515,13 @@ async function syncParsedMirrors(options) {
|
|
|
5514
5515
|
sinceCheckpoint = 0;
|
|
5515
5516
|
};
|
|
5516
5517
|
for (const entry of current) {
|
|
5518
|
+
if (isPathExcluded(entry.sourcePath, options.userExcludedSourcePaths)) {
|
|
5519
|
+
deleted += removePrevious(options.root, previous, entry.virtualPath);
|
|
5520
|
+
handledPrevious.add(entry.virtualPath);
|
|
5521
|
+
skipped += 1;
|
|
5522
|
+
recordSkip(entry, "user-excluded");
|
|
5523
|
+
continue;
|
|
5524
|
+
}
|
|
5517
5525
|
if (options.excludeSourcePaths?.has(entry.sourcePath)) {
|
|
5518
5526
|
deleted += removePrevious(options.root, previous, entry.virtualPath);
|
|
5519
5527
|
handledPrevious.add(entry.virtualPath);
|
|
@@ -5634,7 +5642,7 @@ async function detectMirrorStaleness(options) {
|
|
|
5634
5642
|
const previous = loadMirrorIndex(options.root);
|
|
5635
5643
|
const diagnostics = [];
|
|
5636
5644
|
for (const entry of current) {
|
|
5637
|
-
if (options.excludeSourcePaths?.has(entry.sourcePath))
|
|
5645
|
+
if (options.excludeSourcePaths?.has(entry.sourcePath) || isPathExcluded(entry.sourcePath, options.userExcludedSourcePaths))
|
|
5638
5646
|
continue;
|
|
5639
5647
|
if (!registry.getForVirtualPath(entry.virtualPath))
|
|
5640
5648
|
continue;
|
|
@@ -5642,9 +5650,10 @@ async function detectMirrorStaleness(options) {
|
|
|
5642
5650
|
if (prev !== undefined && prev.sourceMtimeNs === entry.mtimeNs && prev.sourceSizeBytes === entry.sizeBytes)
|
|
5643
5651
|
continue;
|
|
5644
5652
|
const prevSkip = previous.skipped?.[entry.virtualPath];
|
|
5645
|
-
|
|
5653
|
+
const honoredSkip = prevSkip?.reason === "user-excluded" ? undefined : prevSkip;
|
|
5654
|
+
if (honoredSkip !== undefined && honoredSkip.sourceMtimeNs === entry.mtimeNs && honoredSkip.sourceSizeBytes === entry.sizeBytes)
|
|
5646
5655
|
continue;
|
|
5647
|
-
const known = prev ??
|
|
5656
|
+
const known = prev ?? honoredSkip;
|
|
5648
5657
|
const reason = known === undefined ? "source-added" : known.sourceMtimeNs !== entry.mtimeNs && known.sourceSizeBytes !== entry.sizeBytes ? "mtime-and-size-changed" : known.sourceMtimeNs !== entry.mtimeNs ? "mtime-changed" : "size-changed";
|
|
5649
5658
|
diagnostics.push({
|
|
5650
5659
|
code: "stale-index",
|
|
@@ -5669,6 +5678,15 @@ function normalizeExtension2(extension) {
|
|
|
5669
5678
|
const lower = extension.toLowerCase();
|
|
5670
5679
|
return lower.startsWith(".") ? lower : `.${lower}`;
|
|
5671
5680
|
}
|
|
5681
|
+
function isPathExcluded(sourcePath, excluded) {
|
|
5682
|
+
if (excluded === undefined)
|
|
5683
|
+
return false;
|
|
5684
|
+
for (const excludedPath of excluded) {
|
|
5685
|
+
if (sourcePath === excludedPath || sourcePath.startsWith(`${excludedPath}${sep4}`))
|
|
5686
|
+
return true;
|
|
5687
|
+
}
|
|
5688
|
+
return false;
|
|
5689
|
+
}
|
|
5672
5690
|
async function listCurrentFiles(searchPaths, supportedExtensions) {
|
|
5673
5691
|
const entries = [];
|
|
5674
5692
|
for (const sourceRoot of planSourceRoots(searchPaths)) {
|
|
@@ -6802,7 +6820,7 @@ var init_model_auth = __esm(() => {
|
|
|
6802
6820
|
// src/filesystem/cloud-placeholder.ts
|
|
6803
6821
|
import { execFile as execFile2 } from "node:child_process";
|
|
6804
6822
|
import { lstat } from "node:fs/promises";
|
|
6805
|
-
import { dirname as dirname9, relative as relative6, sep as
|
|
6823
|
+
import { dirname as dirname9, relative as relative6, sep as sep5 } from "node:path";
|
|
6806
6824
|
import { promisify as promisify2 } from "node:util";
|
|
6807
6825
|
function pathLooksLikeCloudRoot(target) {
|
|
6808
6826
|
const normalized = target.replaceAll("\\", "/");
|
|
@@ -15653,6 +15671,7 @@ class AutoRAGAgent {
|
|
|
15653
15671
|
parserOptions;
|
|
15654
15672
|
dupeyOptions;
|
|
15655
15673
|
excludeExactDuplicates;
|
|
15674
|
+
excludePaths;
|
|
15656
15675
|
baseSystemPromptConfig;
|
|
15657
15676
|
droppedCallerToolNames;
|
|
15658
15677
|
searchTimeoutMs;
|
|
@@ -15691,6 +15710,7 @@ class AutoRAGAgent {
|
|
|
15691
15710
|
this.parserOptions = resolveParserOptions(options.parserOptions, this.languages);
|
|
15692
15711
|
this.dupeyOptions = options.dupey ?? {};
|
|
15693
15712
|
this.excludeExactDuplicates = options.excludeExactDuplicates ?? true;
|
|
15713
|
+
this.excludePaths = (options.excludePaths ?? []).map(pinExcludedPath);
|
|
15694
15714
|
if (options.minSync !== false) {
|
|
15695
15715
|
const minSyncOpts = options.minSync ?? { autoInstall: true };
|
|
15696
15716
|
this.minSyncMethod = new MinSyncVectorMethod({
|
|
@@ -16625,7 +16645,8 @@ ${initialRetrievalContext ?? "Pending; continue only with a brief progress state
|
|
|
16625
16645
|
const staleDiagnostics = await detectMirrorStaleness({
|
|
16626
16646
|
root: this.workspaceProjectRoot,
|
|
16627
16647
|
searchPaths: this.searchPaths,
|
|
16628
|
-
parserOptions: this.parserOptions
|
|
16648
|
+
parserOptions: this.parserOptions,
|
|
16649
|
+
userExcludedSourcePaths: new Set(this.excludePaths)
|
|
16629
16650
|
});
|
|
16630
16651
|
const diagnostics = [
|
|
16631
16652
|
...this.startupDiagnostics,
|
|
@@ -16748,7 +16769,8 @@ ${initialRetrievalContext ?? "Pending; continue only with a brief progress state
|
|
|
16748
16769
|
searchPaths: this.searchPaths,
|
|
16749
16770
|
force,
|
|
16750
16771
|
parserOptions: this.parserOptions,
|
|
16751
|
-
excludeSourcePaths: duplicateFilter.excluded
|
|
16772
|
+
excludeSourcePaths: duplicateFilter.excluded,
|
|
16773
|
+
userExcludedSourcePaths: new Set(this.excludePaths)
|
|
16752
16774
|
});
|
|
16753
16775
|
}
|
|
16754
16776
|
async scanMirrorStaleness() {
|
|
@@ -16757,7 +16779,8 @@ ${initialRetrievalContext ?? "Pending; continue only with a brief progress state
|
|
|
16757
16779
|
root: this.workspaceProjectRoot,
|
|
16758
16780
|
searchPaths: this.searchPaths,
|
|
16759
16781
|
parserOptions: this.parserOptions,
|
|
16760
|
-
excludeSourcePaths: duplicateFilter.excluded
|
|
16782
|
+
excludeSourcePaths: duplicateFilter.excluded,
|
|
16783
|
+
userExcludedSourcePaths: new Set(this.excludePaths)
|
|
16761
16784
|
});
|
|
16762
16785
|
return {
|
|
16763
16786
|
scanned: 0,
|
|
@@ -16772,10 +16795,11 @@ ${initialRetrievalContext ?? "Pending; continue only with a brief progress state
|
|
|
16772
16795
|
if (!this.excludeExactDuplicates || this.dupeyOptions === false)
|
|
16773
16796
|
return { excluded: new Set };
|
|
16774
16797
|
const excluded = new Set;
|
|
16798
|
+
const userExcluded = new Set(this.excludePaths);
|
|
16775
16799
|
for (const searchPath of this.searchPaths) {
|
|
16776
16800
|
try {
|
|
16777
16801
|
const scan = await scanWithDupey(searchPath, this.dupeyOptions || {});
|
|
16778
|
-
const selected = await selectExactDuplicateExclusions(searchPath, scan);
|
|
16802
|
+
const selected = await selectExactDuplicateExclusions(searchPath, scan, (path) => isPathExcluded(path, userExcluded));
|
|
16779
16803
|
for (const path of selected.excluded)
|
|
16780
16804
|
excluded.add(path);
|
|
16781
16805
|
} catch (error) {
|
|
@@ -17190,6 +17214,14 @@ function toMinSyncReasonDiagnostic(reason) {
|
|
|
17190
17214
|
source: "minsync"
|
|
17191
17215
|
};
|
|
17192
17216
|
}
|
|
17217
|
+
function pinExcludedPath(path) {
|
|
17218
|
+
const resolvedPath = resolve11(path);
|
|
17219
|
+
try {
|
|
17220
|
+
return join22(realpathSync4(dirname14(resolvedPath)), basename9(resolvedPath));
|
|
17221
|
+
} catch {
|
|
17222
|
+
return resolvedPath;
|
|
17223
|
+
}
|
|
17224
|
+
}
|
|
17193
17225
|
function pinSearchRoot(searchPath) {
|
|
17194
17226
|
const resolvedPath = resolve11(searchPath);
|
|
17195
17227
|
let canonicalPath;
|
|
@@ -25283,6 +25315,10 @@ function resolveConfig(input) {
|
|
|
25283
25315
|
const configOrigin = dirname21(resolve13(configPath));
|
|
25284
25316
|
const fileWorkspacePath = typeof file.workspacePath === "string" ? resolvePersistedPath(file.workspacePath, configOrigin) : undefined;
|
|
25285
25317
|
const fileSearchPaths = file.searchPaths ? resolveSearchPaths(file.searchPaths, fileWorkspacePath ?? configOrigin) : undefined;
|
|
25318
|
+
if (file.excludePaths !== undefined && (!Array.isArray(file.excludePaths) || file.excludePaths.some((path) => typeof path !== "string" || path.length === 0))) {
|
|
25319
|
+
throw new ConfigError("Config field 'excludePaths' must be a non-empty string array");
|
|
25320
|
+
}
|
|
25321
|
+
const fileExcludePaths = file.excludePaths ? resolveSearchPaths(file.excludePaths, fileWorkspacePath ?? configOrigin) : undefined;
|
|
25286
25322
|
const searchPaths = flagSearchPaths ?? envSearchPaths ?? fileSearchPaths ?? defaultSearchPaths;
|
|
25287
25323
|
const flagWorkspacePath = flagString(flags, "workspace");
|
|
25288
25324
|
const envWorkspacePath = envString(env, "AUTORAG_WORKSPACE");
|
|
@@ -25306,6 +25342,8 @@ function resolveConfig(input) {
|
|
|
25306
25342
|
};
|
|
25307
25343
|
if (model)
|
|
25308
25344
|
config.model = model;
|
|
25345
|
+
if (fileExcludePaths !== undefined)
|
|
25346
|
+
config.excludePaths = fileExcludePaths;
|
|
25309
25347
|
const normalized = normalizeIndexingConfig({
|
|
25310
25348
|
minSync: file.minSync
|
|
25311
25349
|
});
|
|
@@ -25422,6 +25460,8 @@ function buildAgentOptions(config) {
|
|
|
25422
25460
|
};
|
|
25423
25461
|
}
|
|
25424
25462
|
opts.excludeExactDuplicates = config.excludeExactDuplicates ?? true;
|
|
25463
|
+
if (config.excludePaths !== undefined)
|
|
25464
|
+
opts.excludePaths = config.excludePaths;
|
|
25425
25465
|
if (config.datasources !== undefined) {
|
|
25426
25466
|
const { skills, unknown } = buildDatasourceSkills(config.datasources, config.workspacePath);
|
|
25427
25467
|
if (skills.length > 0)
|
|
@@ -25677,6 +25717,8 @@ function writeDefaultConfig(path, partial, opts = {}) {
|
|
|
25677
25717
|
full.jikji = partial.jikji ?? {};
|
|
25678
25718
|
full.dupey = partial.dupey ?? { enabled: true };
|
|
25679
25719
|
full.excludeExactDuplicates = partial.excludeExactDuplicates ?? true;
|
|
25720
|
+
if (partial.excludePaths !== undefined)
|
|
25721
|
+
full.excludePaths = resolveSearchPaths(partial.excludePaths, workspacePath);
|
|
25680
25722
|
if (partial.parserOptions)
|
|
25681
25723
|
full.parserOptions = partial.parserOptions;
|
|
25682
25724
|
if (partial.p2p !== undefined)
|
package/dist/dupey/filter.d.ts
CHANGED
|
@@ -5,4 +5,4 @@ export interface ExactDuplicateFilterResult {
|
|
|
5
5
|
readonly errors: readonly string[];
|
|
6
6
|
}
|
|
7
7
|
/** Selects the newest filesystem copy for each exact canonical-text hash. */
|
|
8
|
-
export declare function selectExactDuplicateExclusions(root: string, scan: DupeyScanResult): Promise<ExactDuplicateFilterResult>;
|
|
8
|
+
export declare function selectExactDuplicateExclusions(root: string, scan: DupeyScanResult, isUnavailable?: (path: string) => boolean): Promise<ExactDuplicateFilterResult>;
|
package/dist/index.js
CHANGED
|
@@ -192,7 +192,7 @@ function isParsedMirrorSkipEntry(value) {
|
|
|
192
192
|
return isRecord(value) && typeof value.virtualPath === "string" && typeof value.sourcePath === "string" && isParsedMirrorSkipReason(value.reason) && typeof value.sourceMtimeNs === "number" && typeof value.sourceSizeBytes === "number" && typeof value.updatedAt === "string";
|
|
193
193
|
}
|
|
194
194
|
function isParsedMirrorSkipReason(value) {
|
|
195
|
-
return value === "duplicate-excluded" || value === "parser-skipped" || value === "parser-failed";
|
|
195
|
+
return value === "duplicate-excluded" || value === "user-excluded" || value === "parser-skipped" || value === "parser-failed";
|
|
196
196
|
}
|
|
197
197
|
function isParsedMirrorEntry(value) {
|
|
198
198
|
return isRecord(value) && typeof value.virtualPath === "string" && typeof value.sourcePath === "string" && typeof value.outputPath === "string" && typeof value.parserName === "string" && typeof value.sourceMtimeNs === "number" && typeof value.sourceSizeBytes === "number" && typeof value.updatedAt === "string";
|
|
@@ -548,7 +548,7 @@ var init_cli = __esm(() => {
|
|
|
548
548
|
// src/dupey/filter.ts
|
|
549
549
|
import { stat } from "node:fs/promises";
|
|
550
550
|
import { resolve as resolve5 } from "node:path";
|
|
551
|
-
async function selectExactDuplicateExclusions(root, scan) {
|
|
551
|
+
async function selectExactDuplicateExclusions(root, scan, isUnavailable) {
|
|
552
552
|
const byHash = new Map;
|
|
553
553
|
for (const file of scan.files) {
|
|
554
554
|
if (typeof file.content_hash !== "string" || file.content_hash.length === 0)
|
|
@@ -574,11 +574,12 @@ async function selectExactDuplicateExclusions(root, scan) {
|
|
|
574
574
|
}
|
|
575
575
|
}));
|
|
576
576
|
ranked.sort((a, b) => b.mtimeMs - a.mtimeMs || a.path.localeCompare(b.path));
|
|
577
|
-
const
|
|
577
|
+
const candidates = isUnavailable === undefined ? ranked : ranked.filter(({ path }) => !isUnavailable(path));
|
|
578
|
+
const keeper = candidates[0]?.path;
|
|
578
579
|
if (!keeper)
|
|
579
580
|
continue;
|
|
580
581
|
keepers.add(keeper);
|
|
581
|
-
for (const candidate of
|
|
582
|
+
for (const candidate of candidates.slice(1))
|
|
582
583
|
excluded.add(candidate.path);
|
|
583
584
|
}
|
|
584
585
|
return { excluded, keepers, errors };
|
|
@@ -5475,7 +5476,7 @@ var init_defaults = __esm(() => {
|
|
|
5475
5476
|
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
5476
5477
|
import { existsSync as existsSync12, mkdirSync as mkdirSync6, renameSync as renameSync5, rmSync as rmSync3, writeFileSync as writeFileSync6 } from "node:fs";
|
|
5477
5478
|
import { opendir, readFile as readFile3, stat as stat4 } from "node:fs/promises";
|
|
5478
|
-
import { dirname as dirname7, extname as extname4, resolve as resolve9 } from "node:path";
|
|
5479
|
+
import { dirname as dirname7, extname as extname4, resolve as resolve9, sep as sep4 } from "node:path";
|
|
5479
5480
|
async function syncParsedMirrors(options) {
|
|
5480
5481
|
const registry = options.registry ?? createDefaultParserRegistry(options.parserOptions);
|
|
5481
5482
|
const maxSourceBytes = options.maxSourceBytes ?? DEFAULT_MAX_SOURCE_BYTES;
|
|
@@ -5514,6 +5515,13 @@ async function syncParsedMirrors(options) {
|
|
|
5514
5515
|
sinceCheckpoint = 0;
|
|
5515
5516
|
};
|
|
5516
5517
|
for (const entry of current) {
|
|
5518
|
+
if (isPathExcluded(entry.sourcePath, options.userExcludedSourcePaths)) {
|
|
5519
|
+
deleted += removePrevious(options.root, previous, entry.virtualPath);
|
|
5520
|
+
handledPrevious.add(entry.virtualPath);
|
|
5521
|
+
skipped += 1;
|
|
5522
|
+
recordSkip(entry, "user-excluded");
|
|
5523
|
+
continue;
|
|
5524
|
+
}
|
|
5517
5525
|
if (options.excludeSourcePaths?.has(entry.sourcePath)) {
|
|
5518
5526
|
deleted += removePrevious(options.root, previous, entry.virtualPath);
|
|
5519
5527
|
handledPrevious.add(entry.virtualPath);
|
|
@@ -5634,7 +5642,7 @@ async function detectMirrorStaleness(options) {
|
|
|
5634
5642
|
const previous = loadMirrorIndex(options.root);
|
|
5635
5643
|
const diagnostics = [];
|
|
5636
5644
|
for (const entry of current) {
|
|
5637
|
-
if (options.excludeSourcePaths?.has(entry.sourcePath))
|
|
5645
|
+
if (options.excludeSourcePaths?.has(entry.sourcePath) || isPathExcluded(entry.sourcePath, options.userExcludedSourcePaths))
|
|
5638
5646
|
continue;
|
|
5639
5647
|
if (!registry.getForVirtualPath(entry.virtualPath))
|
|
5640
5648
|
continue;
|
|
@@ -5642,9 +5650,10 @@ async function detectMirrorStaleness(options) {
|
|
|
5642
5650
|
if (prev !== undefined && prev.sourceMtimeNs === entry.mtimeNs && prev.sourceSizeBytes === entry.sizeBytes)
|
|
5643
5651
|
continue;
|
|
5644
5652
|
const prevSkip = previous.skipped?.[entry.virtualPath];
|
|
5645
|
-
|
|
5653
|
+
const honoredSkip = prevSkip?.reason === "user-excluded" ? undefined : prevSkip;
|
|
5654
|
+
if (honoredSkip !== undefined && honoredSkip.sourceMtimeNs === entry.mtimeNs && honoredSkip.sourceSizeBytes === entry.sizeBytes)
|
|
5646
5655
|
continue;
|
|
5647
|
-
const known = prev ??
|
|
5656
|
+
const known = prev ?? honoredSkip;
|
|
5648
5657
|
const reason = known === undefined ? "source-added" : known.sourceMtimeNs !== entry.mtimeNs && known.sourceSizeBytes !== entry.sizeBytes ? "mtime-and-size-changed" : known.sourceMtimeNs !== entry.mtimeNs ? "mtime-changed" : "size-changed";
|
|
5649
5658
|
diagnostics.push({
|
|
5650
5659
|
code: "stale-index",
|
|
@@ -5669,6 +5678,15 @@ function normalizeExtension2(extension) {
|
|
|
5669
5678
|
const lower = extension.toLowerCase();
|
|
5670
5679
|
return lower.startsWith(".") ? lower : `.${lower}`;
|
|
5671
5680
|
}
|
|
5681
|
+
function isPathExcluded(sourcePath, excluded) {
|
|
5682
|
+
if (excluded === undefined)
|
|
5683
|
+
return false;
|
|
5684
|
+
for (const excludedPath of excluded) {
|
|
5685
|
+
if (sourcePath === excludedPath || sourcePath.startsWith(`${excludedPath}${sep4}`))
|
|
5686
|
+
return true;
|
|
5687
|
+
}
|
|
5688
|
+
return false;
|
|
5689
|
+
}
|
|
5672
5690
|
async function listCurrentFiles(searchPaths, supportedExtensions) {
|
|
5673
5691
|
const entries = [];
|
|
5674
5692
|
for (const sourceRoot of planSourceRoots(searchPaths)) {
|
|
@@ -6802,7 +6820,7 @@ var init_model_auth = __esm(() => {
|
|
|
6802
6820
|
// src/filesystem/cloud-placeholder.ts
|
|
6803
6821
|
import { execFile as execFile2 } from "node:child_process";
|
|
6804
6822
|
import { lstat } from "node:fs/promises";
|
|
6805
|
-
import { dirname as dirname9, relative as relative6, sep as
|
|
6823
|
+
import { dirname as dirname9, relative as relative6, sep as sep5 } from "node:path";
|
|
6806
6824
|
import { promisify as promisify2 } from "node:util";
|
|
6807
6825
|
function pathLooksLikeCloudRoot(target) {
|
|
6808
6826
|
const normalized = target.replaceAll("\\", "/");
|
|
@@ -15653,6 +15671,7 @@ class AutoRAGAgent {
|
|
|
15653
15671
|
parserOptions;
|
|
15654
15672
|
dupeyOptions;
|
|
15655
15673
|
excludeExactDuplicates;
|
|
15674
|
+
excludePaths;
|
|
15656
15675
|
baseSystemPromptConfig;
|
|
15657
15676
|
droppedCallerToolNames;
|
|
15658
15677
|
searchTimeoutMs;
|
|
@@ -15691,6 +15710,7 @@ class AutoRAGAgent {
|
|
|
15691
15710
|
this.parserOptions = resolveParserOptions(options.parserOptions, this.languages);
|
|
15692
15711
|
this.dupeyOptions = options.dupey ?? {};
|
|
15693
15712
|
this.excludeExactDuplicates = options.excludeExactDuplicates ?? true;
|
|
15713
|
+
this.excludePaths = (options.excludePaths ?? []).map(pinExcludedPath);
|
|
15694
15714
|
if (options.minSync !== false) {
|
|
15695
15715
|
const minSyncOpts = options.minSync ?? { autoInstall: true };
|
|
15696
15716
|
this.minSyncMethod = new MinSyncVectorMethod({
|
|
@@ -16625,7 +16645,8 @@ ${initialRetrievalContext ?? "Pending; continue only with a brief progress state
|
|
|
16625
16645
|
const staleDiagnostics = await detectMirrorStaleness({
|
|
16626
16646
|
root: this.workspaceProjectRoot,
|
|
16627
16647
|
searchPaths: this.searchPaths,
|
|
16628
|
-
parserOptions: this.parserOptions
|
|
16648
|
+
parserOptions: this.parserOptions,
|
|
16649
|
+
userExcludedSourcePaths: new Set(this.excludePaths)
|
|
16629
16650
|
});
|
|
16630
16651
|
const diagnostics = [
|
|
16631
16652
|
...this.startupDiagnostics,
|
|
@@ -16748,7 +16769,8 @@ ${initialRetrievalContext ?? "Pending; continue only with a brief progress state
|
|
|
16748
16769
|
searchPaths: this.searchPaths,
|
|
16749
16770
|
force,
|
|
16750
16771
|
parserOptions: this.parserOptions,
|
|
16751
|
-
excludeSourcePaths: duplicateFilter.excluded
|
|
16772
|
+
excludeSourcePaths: duplicateFilter.excluded,
|
|
16773
|
+
userExcludedSourcePaths: new Set(this.excludePaths)
|
|
16752
16774
|
});
|
|
16753
16775
|
}
|
|
16754
16776
|
async scanMirrorStaleness() {
|
|
@@ -16757,7 +16779,8 @@ ${initialRetrievalContext ?? "Pending; continue only with a brief progress state
|
|
|
16757
16779
|
root: this.workspaceProjectRoot,
|
|
16758
16780
|
searchPaths: this.searchPaths,
|
|
16759
16781
|
parserOptions: this.parserOptions,
|
|
16760
|
-
excludeSourcePaths: duplicateFilter.excluded
|
|
16782
|
+
excludeSourcePaths: duplicateFilter.excluded,
|
|
16783
|
+
userExcludedSourcePaths: new Set(this.excludePaths)
|
|
16761
16784
|
});
|
|
16762
16785
|
return {
|
|
16763
16786
|
scanned: 0,
|
|
@@ -16772,10 +16795,11 @@ ${initialRetrievalContext ?? "Pending; continue only with a brief progress state
|
|
|
16772
16795
|
if (!this.excludeExactDuplicates || this.dupeyOptions === false)
|
|
16773
16796
|
return { excluded: new Set };
|
|
16774
16797
|
const excluded = new Set;
|
|
16798
|
+
const userExcluded = new Set(this.excludePaths);
|
|
16775
16799
|
for (const searchPath of this.searchPaths) {
|
|
16776
16800
|
try {
|
|
16777
16801
|
const scan = await scanWithDupey(searchPath, this.dupeyOptions || {});
|
|
16778
|
-
const selected = await selectExactDuplicateExclusions(searchPath, scan);
|
|
16802
|
+
const selected = await selectExactDuplicateExclusions(searchPath, scan, (path) => isPathExcluded(path, userExcluded));
|
|
16779
16803
|
for (const path of selected.excluded)
|
|
16780
16804
|
excluded.add(path);
|
|
16781
16805
|
} catch (error) {
|
|
@@ -17190,6 +17214,14 @@ function toMinSyncReasonDiagnostic(reason) {
|
|
|
17190
17214
|
source: "minsync"
|
|
17191
17215
|
};
|
|
17192
17216
|
}
|
|
17217
|
+
function pinExcludedPath(path) {
|
|
17218
|
+
const resolvedPath = resolve11(path);
|
|
17219
|
+
try {
|
|
17220
|
+
return join22(realpathSync4(dirname14(resolvedPath)), basename9(resolvedPath));
|
|
17221
|
+
} catch {
|
|
17222
|
+
return resolvedPath;
|
|
17223
|
+
}
|
|
17224
|
+
}
|
|
17193
17225
|
function pinSearchRoot(searchPath) {
|
|
17194
17226
|
const resolvedPath = resolve11(searchPath);
|
|
17195
17227
|
let canonicalPath;
|
|
@@ -25283,6 +25315,10 @@ function resolveConfig(input) {
|
|
|
25283
25315
|
const configOrigin = dirname21(resolve13(configPath));
|
|
25284
25316
|
const fileWorkspacePath = typeof file.workspacePath === "string" ? resolvePersistedPath(file.workspacePath, configOrigin) : undefined;
|
|
25285
25317
|
const fileSearchPaths = file.searchPaths ? resolveSearchPaths(file.searchPaths, fileWorkspacePath ?? configOrigin) : undefined;
|
|
25318
|
+
if (file.excludePaths !== undefined && (!Array.isArray(file.excludePaths) || file.excludePaths.some((path) => typeof path !== "string" || path.length === 0))) {
|
|
25319
|
+
throw new ConfigError("Config field 'excludePaths' must be a non-empty string array");
|
|
25320
|
+
}
|
|
25321
|
+
const fileExcludePaths = file.excludePaths ? resolveSearchPaths(file.excludePaths, fileWorkspacePath ?? configOrigin) : undefined;
|
|
25286
25322
|
const searchPaths = flagSearchPaths ?? envSearchPaths ?? fileSearchPaths ?? defaultSearchPaths;
|
|
25287
25323
|
const flagWorkspacePath = flagString(flags, "workspace");
|
|
25288
25324
|
const envWorkspacePath = envString(env, "AUTORAG_WORKSPACE");
|
|
@@ -25306,6 +25342,8 @@ function resolveConfig(input) {
|
|
|
25306
25342
|
};
|
|
25307
25343
|
if (model)
|
|
25308
25344
|
config.model = model;
|
|
25345
|
+
if (fileExcludePaths !== undefined)
|
|
25346
|
+
config.excludePaths = fileExcludePaths;
|
|
25309
25347
|
const normalized = normalizeIndexingConfig({
|
|
25310
25348
|
minSync: file.minSync
|
|
25311
25349
|
});
|
|
@@ -25422,6 +25460,8 @@ function buildAgentOptions(config) {
|
|
|
25422
25460
|
};
|
|
25423
25461
|
}
|
|
25424
25462
|
opts.excludeExactDuplicates = config.excludeExactDuplicates ?? true;
|
|
25463
|
+
if (config.excludePaths !== undefined)
|
|
25464
|
+
opts.excludePaths = config.excludePaths;
|
|
25425
25465
|
if (config.datasources !== undefined) {
|
|
25426
25466
|
const { skills, unknown } = buildDatasourceSkills(config.datasources, config.workspacePath);
|
|
25427
25467
|
if (skills.length > 0)
|
|
@@ -25677,6 +25717,8 @@ function writeDefaultConfig(path, partial, opts = {}) {
|
|
|
25677
25717
|
full.jikji = partial.jikji ?? {};
|
|
25678
25718
|
full.dupey = partial.dupey ?? { enabled: true };
|
|
25679
25719
|
full.excludeExactDuplicates = partial.excludeExactDuplicates ?? true;
|
|
25720
|
+
if (partial.excludePaths !== undefined)
|
|
25721
|
+
full.excludePaths = resolveSearchPaths(partial.excludePaths, workspacePath);
|
|
25680
25722
|
if (partial.parserOptions)
|
|
25681
25723
|
full.parserOptions = partial.parserOptions;
|
|
25682
25724
|
if (partial.p2p !== undefined)
|
|
@@ -26211,6 +26253,7 @@ export {
|
|
|
26211
26253
|
groupUnsearchedSurfaces,
|
|
26212
26254
|
isDatasourceSource,
|
|
26213
26255
|
isDue,
|
|
26256
|
+
isPathExcluded,
|
|
26214
26257
|
jikjiExecutableName,
|
|
26215
26258
|
jikjiFindDiagnostic,
|
|
26216
26259
|
jikjiPrepareDiagnostic,
|
|
@@ -8,7 +8,7 @@ export interface ParsedMirrorEntry {
|
|
|
8
8
|
readonly updatedAt: string;
|
|
9
9
|
}
|
|
10
10
|
/** Why refresh deliberately left a source out of the parsed mirror. */
|
|
11
|
-
export type ParsedMirrorSkipReason = "duplicate-excluded" | "parser-skipped" | "parser-failed";
|
|
11
|
+
export type ParsedMirrorSkipReason = "duplicate-excluded" | "user-excluded" | "parser-skipped" | "parser-failed";
|
|
12
12
|
/**
|
|
13
13
|
* A source the last refresh decided not to mirror, pinned to the exact version it
|
|
14
14
|
* decided on. Staleness checks compare against this record instead of re-deriving
|
package/dist/mirror/index.d.ts
CHANGED
|
@@ -2,4 +2,4 @@ export type { ParsedMirrorEntry, ParsedMirrorIndex } from "./index-store.js";
|
|
|
2
2
|
export { emptyMirrorIndex, loadMirrorIndex, saveMirrorIndex } from "./index-store.js";
|
|
3
3
|
export { parsedMirrorIndexPath, parsedMirrorRoot, parsedOutputPath, refreshReadinessPath } from "./paths.js";
|
|
4
4
|
export type { ParsedMirrorDiagnostic, ParsedMirrorDiagnosticCode, ParsedMirrorSyncOptions, ParsedMirrorSyncResult, } from "./sync.js";
|
|
5
|
-
export { DEFAULT_MAX_SOURCE_BYTES, detectMirrorStaleness, syncParsedMirrors } from "./sync.js";
|
|
5
|
+
export { DEFAULT_MAX_SOURCE_BYTES, detectMirrorStaleness, isPathExcluded, syncParsedMirrors } from "./sync.js";
|
package/dist/mirror/sync.d.ts
CHANGED
|
@@ -12,6 +12,8 @@ export interface ParsedMirrorSyncOptions {
|
|
|
12
12
|
readonly maxSourceBytes?: number;
|
|
13
13
|
/** Absolute source paths omitted from parsed mirrors (for example exact duplicate copies). */
|
|
14
14
|
readonly excludeSourcePaths?: ReadonlySet<string>;
|
|
15
|
+
/** Absolute source paths or directories omitted by the user. */
|
|
16
|
+
readonly userExcludedSourcePaths?: ReadonlySet<string>;
|
|
15
17
|
}
|
|
16
18
|
export type ParsedMirrorDiagnosticCode = "unsupported-file" | "parser-skipped" | "parser-failed" | "duplicate-excluded" | "deleted-mirror" | "stale-index" | "pdf-extract-thin" | "parser-warning";
|
|
17
19
|
/** Path-opaque refresh diagnostic. `source` is an opaque virtual path, never a real fs path. */
|
|
@@ -42,3 +44,4 @@ export declare function syncParsedMirrors(options: ParsedMirrorSyncOptions): Pro
|
|
|
42
44
|
* getRefreshStatus).
|
|
43
45
|
*/
|
|
44
46
|
export declare function detectMirrorStaleness(options: ParsedMirrorSyncOptions): Promise<ParsedMirrorDiagnostic[]>;
|
|
47
|
+
export declare function isPathExcluded(sourcePath: string, excluded: ReadonlySet<string> | undefined): boolean;
|
package/package.json
CHANGED
package/skills/autorag/SKILL.md
CHANGED
|
@@ -41,6 +41,14 @@ near/contains families require human review. Exact duplicate exclusion during
|
|
|
41
41
|
refresh is enabled by default and can be disabled with
|
|
42
42
|
`"excludeExactDuplicates": false` in `config.json`.
|
|
43
43
|
|
|
44
|
+
### Excluding local files from the index
|
|
45
|
+
|
|
46
|
+
`"excludePaths"` in `config.json` lists files or folders (absolute, or relative
|
|
47
|
+
to `workspacePath`) that refresh keeps out of the parsed mirror and MinSync.
|
|
48
|
+
A folder entry excludes everything under it. Removing an entry and running
|
|
49
|
+
`autorag refresh --method minsync` indexes the file again. Excluded sources are
|
|
50
|
+
recorded as `user-excluded` skips, so they are not reported as stale.
|
|
51
|
+
|
|
44
52
|
`status` is model-free and path-opaque. `health` resolves the single model,
|
|
45
53
|
checks credential presence, and normally probes one live completion. If the
|
|
46
54
|
model, authentication, configuration, or indexes are unhealthy, use
|