@autorag/librarian 2.13.4 → 2.13.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/NOTICE +3 -0
  2. package/README.md +50 -18
  3. package/dist/agent/agent.d.ts +111 -40
  4. package/dist/agent/cloud-release-extension.d.ts +43 -0
  5. package/dist/agent/decision-backends.d.ts +49 -0
  6. package/dist/agent/decision-model-check.d.ts +92 -0
  7. package/dist/agent/dupey-tool.d.ts +2 -0
  8. package/dist/agent/everything-search-tool.d.ts +1 -0
  9. package/dist/agent/fsearch-search-tool.d.ts +1 -0
  10. package/dist/agent/index.d.ts +4 -1
  11. package/dist/agent/jev-extension.d.ts +27 -32
  12. package/dist/agent/jikji-find-tool.d.ts +5 -0
  13. package/dist/agent/name-candidates.d.ts +88 -0
  14. package/dist/agent/permission-gate.d.ts +2 -5
  15. package/dist/agent/query-routing.d.ts +1 -1
  16. package/dist/agent/search-documents.d.ts +1 -1
  17. package/dist/agent/sllm-decision.d.ts +34 -0
  18. package/dist/cli/commands/duplicates.d.ts +3 -2
  19. package/dist/cli/commands/models.d.ts +2 -0
  20. package/dist/cli/commands/search.d.ts +2 -0
  21. package/dist/cli/config.d.ts +49 -30
  22. package/dist/cli/index.js +13522 -10169
  23. package/dist/cli/setup.d.ts +27 -1
  24. package/dist/cloud/jev-backend.d.ts +26 -4
  25. package/dist/core.js +6079 -2840
  26. package/dist/datasource/index.d.ts +2 -2
  27. package/dist/datasource/skills/obsidian/index.d.ts +1 -1
  28. package/dist/datasource/skills/obsidian/methods.d.ts +1 -1
  29. package/dist/datasource/skills/obsidian/skill.d.ts +1 -0
  30. package/dist/datasource/skills/obsidian/vault-index.d.ts +1 -1
  31. package/dist/datasource/skills/wombat/client.d.ts +17 -0
  32. package/dist/datasource/skills/wombat/index.d.ts +4 -0
  33. package/dist/datasource/skills/wombat/methods.d.ts +15 -0
  34. package/dist/datasource/skills/wombat/skill.d.ts +38 -0
  35. package/dist/datasource/skills/wombat/types.d.ts +89 -0
  36. package/dist/dupey/cli.d.ts +21 -1
  37. package/dist/dupey/filter.d.ts +8 -1
  38. package/dist/dupey/index.d.ts +1 -0
  39. package/dist/dupey/scan-plan.d.ts +23 -0
  40. package/dist/embedding/index.d.ts +3 -1
  41. package/dist/everything/client.d.ts +1 -2
  42. package/dist/filesystem/cloud-placeholder.d.ts +313 -21
  43. package/dist/filesystem/shared-exclusive-queue.d.ts +16 -0
  44. package/dist/fsearch/client.d.ts +3 -2
  45. package/dist/index.d.ts +1 -1
  46. package/dist/index.js +6184 -2905
  47. package/dist/jikji/answer-pack.d.ts +7 -1
  48. package/dist/jikji/client.d.ts +28 -14
  49. package/dist/jikji/diagnostics.d.ts +16 -2
  50. package/dist/jikji/index.d.ts +3 -3
  51. package/dist/jikji/installer.d.ts +11 -5
  52. package/dist/jikji/retry-command.d.ts +10 -0
  53. package/dist/jikji/types.d.ts +47 -1
  54. package/dist/jikji/version.d.ts +20 -0
  55. package/dist/mcp/index.js +6154 -2902
  56. package/dist/mcp/server.d.ts +3 -0
  57. package/dist/minsync/binary.d.ts +10 -5
  58. package/dist/minsync/client.d.ts +7 -10
  59. package/dist/minsync/embedder-config.d.ts +11 -10
  60. package/dist/minsync/errors.d.ts +3 -0
  61. package/dist/minsync/index.d.ts +1 -1
  62. package/dist/minsync/installer.d.ts +1 -1
  63. package/dist/minsync/method.d.ts +1 -0
  64. package/dist/minsync/types.d.ts +0 -9
  65. package/dist/minsync/version.d.ts +20 -0
  66. package/dist/mirror/cloud-fingerprints.d.ts +30 -0
  67. package/dist/mirror/cloud.d.ts +79 -0
  68. package/dist/mirror/index.d.ts +4 -0
  69. package/dist/mirror/sync.d.ts +79 -1
  70. package/dist/parser/csv.d.ts +26 -0
  71. package/dist/parser/defaults.d.ts +1 -1
  72. package/dist/parser/index.d.ts +2 -0
  73. package/dist/parser/kordoc.d.ts +6 -3
  74. package/dist/parser/parse-worker.js +668 -28
  75. package/dist/parser/spreadsheet-render.d.ts +53 -0
  76. package/dist/parser/spreadsheet.d.ts +27 -0
  77. package/dist/profiles/loop-guard.d.ts +8 -2
  78. package/dist/profiles/retrieval-tools.d.ts +2 -1
  79. package/dist/profiles.js +13520 -10280
  80. package/dist/retrieval/skip.d.ts +1 -1
  81. package/dist/retrieval/types.d.ts +1 -1
  82. package/package.json +3 -3
  83. package/skills/autorag/SKILL.md +7 -4
  84. package/skills/autorag-doctor/SKILL.md +8 -3
  85. package/skills/autorag-lite-setup/SKILL.md +4 -4
  86. package/skills/autorag-setup/SKILL.md +53 -30
  87. package/dist/datasource/skills/cloud-drive/index.d.ts +0 -2
  88. package/dist/datasource/skills/cloud-drive/rclone-connector.d.ts +0 -49
  89. package/dist/datasource/skills/cloud-drive/skill.d.ts +0 -14
  90. package/dist/minsync/kiwi.d.ts +0 -17
  91. package/dist/minsync/lexical-language.d.ts +0 -18
@@ -1,9 +1,12 @@
1
1
  import { McpServer } from "@modelcontextprotocol/server";
2
2
  import type { AutoRAGLite } from "../core.js";
3
+ import { type CloudFileProbe } from "../filesystem/cloud-placeholder.js";
3
4
  export interface AutoRAGMcpServerOptions {
4
5
  readonly readOnly?: boolean;
5
6
  readonly tools?: readonly string[];
6
7
  /** Test/embedded override; defaults to the current Node platform. */
7
8
  readonly platform?: NodeJS.Platform;
9
+ /** Test/embedded override for the cloud probe `autorag.duplicates` uses; defaults to this platform's probe. */
10
+ readonly cloudProbe?: CloudFileProbe;
8
11
  }
9
12
  export declare function createAutoRAGMcpServer(lite: AutoRAGLite, options?: AutoRAGMcpServerOptions): McpServer;
@@ -1,4 +1,5 @@
1
1
  import { type EnsureMinSyncBinaryOptions } from "./installer.js";
2
+ import { type OutdatedMinSyncBinary } from "./version.js";
2
3
  export interface ResolveMinSyncBinaryOptions {
3
4
  /** Workspace project root; the cached binary lives under `<root>/.autorag/bin`. */
4
5
  readonly root: string;
@@ -9,13 +10,17 @@ export interface ResolveMinSyncBinaryOptions {
9
10
  /** False for query paths: they use an existing binary or fail, and never wait on `cargo install`. */
10
11
  readonly install?: boolean;
11
12
  }
12
- /** Resolve the `minsync` executable from PATH directories. Returns the first match or undefined. */
13
- export declare function lookupMinSyncInPath(env: NodeJS.ProcessEnv): string | undefined;
13
+ /**
14
+ * Resolve the `minsync` executable from PATH directories: the first executable that is not older than
15
+ * {@link MINSYNC_MIN_VERSION}. Older ones are skipped and, when `outdated` is given, recorded there.
16
+ */
17
+ export declare function lookupMinSyncInPath(env: NodeJS.ProcessEnv, outdated?: OutdatedMinSyncBinary[]): string | undefined;
14
18
  /**
15
19
  * Resolve the MinSync CLI from the user's global PATH first, then the workspace cache, and finally the
16
- * verified auto-install fallback. Throws {@link MinSyncRequiredError}: MinSync is required, so there is
17
- * no "no binary" value to degrade on.
20
+ * verified auto-install fallback. A binary older than {@link MINSYNC_MIN_VERSION} is never run: it is skipped on
21
+ * PATH, and a cached one is replaced by the install. Throws {@link MinSyncRequiredError}: MinSync is required, so
22
+ * there is no "no binary" value to degrade on. An explicit `binaryPath` is used as given and never probed.
18
23
  */
19
24
  export declare function resolveMinSyncBinary(options: ResolveMinSyncBinaryOptions): Promise<string>;
20
- /** True when no `minsync` is resolvable right now without installing one. */
25
+ /** True when no usable `minsync` is resolvable right now without installing one. */
21
26
  export declare function isMinSyncBinaryMissing(options: Pick<ResolveMinSyncBinaryOptions, "root" | "binaryPath">): boolean;
@@ -5,8 +5,11 @@ export interface MinSyncClientOptions {
5
5
  readonly embedder?: MinSyncEmbedderConfig;
6
6
  readonly maxChunkSize?: number;
7
7
  }
8
- /** MinSync's native query modes: vector, BM25, and hybrid. */
9
- export type MinSyncQueryMode = "vector" | "bm25" | "hybrid";
8
+ /**
9
+ * MinSync's native query modes: dense vector, learned-sparse (SPLADE, which replaced BM25 in MinSync 0.6), and
10
+ * their hybrid fusion.
11
+ */
12
+ export type MinSyncQueryMode = "vector" | "sparse" | "hybrid";
10
13
  export declare class MinSyncQueryError extends Error {
11
14
  readonly code: number | null;
12
15
  readonly stderr: string;
@@ -26,6 +29,8 @@ export declare class MinSyncClient {
26
29
  /**
27
30
  * What MinSync is told to embed with. No `id`, or a `native:` id, is MinSync's own Qwen3 engine, which
28
31
  * MinSync provisions and runs (in-process, or through a `minsync serve` daemon it finds on its own).
32
+ * {@link SPARSE_ONLY_EMBEDDER_ID} is a sparse-only index: only the id is passed on, since a dimension or an
33
+ * endpoint left over from a dense setup would describe vectors MinSync no longer builds.
29
34
  * Anything else is an endpoint the operator configured, passed through untouched.
30
35
  */
31
36
  private effectiveEmbedder;
@@ -33,14 +38,6 @@ export declare class MinSyncClient {
33
38
  private writeIdentity;
34
39
  private identityMismatch;
35
40
  sync(force?: boolean, signal?: AbortSignal, onProgress?: (progress: MinSyncSyncProgress) => void): Promise<MinSyncSyncResult>;
36
- /**
37
- * The tokenizer to run this sync with: always {@link MINSYNC_LEXICAL_LANGUAGE}, which fails every sync when the
38
- * Kiwi native library is missing. A workspace that is new, or tokenized differently, then gets whitespace
39
- * tokenization instead and the sync reports `lexicalFallback`. An index already built with the multilingual
40
- * tokenizer is left alone: switching it would re-embed every chunk, and the probe can miss a library that the OS
41
- * loader finds on its own.
42
- */
43
- private resolveLexicalLanguage;
44
41
  private lockHeldResult;
45
42
  private checkAndSync;
46
43
  query(text: string, topK: number, mode?: MinSyncQueryMode, signal?: AbortSignal): Promise<readonly MinSyncQueryHit[]>;
@@ -1,4 +1,3 @@
1
- import type { MinSyncLexicalLanguage } from "./lexical-language.js";
2
1
  import type { MinSyncEmbedderConfig } from "./types.js";
3
2
  export interface MinSyncEmbeddingIdentity {
4
3
  readonly provider: string;
@@ -13,6 +12,15 @@ export declare const EMBEDDING_IDENTITY_FILE = "autorag-embedding-identity.json"
13
12
  export declare const DEFAULT_MINSYNC_EMBEDDER_ID = "native:Qwen/Qwen3-Embedding-0.6B";
14
13
  export declare const DEFAULT_MINSYNC_EMBEDDER_DIMENSION = 1024;
15
14
  export declare const DEFAULT_MINSYNC_EMBEDDER_CONFIG: MinSyncEmbedderConfig;
15
+ /**
16
+ * `minSync.embedder.id` for a sparse-only index: MinSync builds SPLADE sparse vectors and no dense ones, so nothing
17
+ * downloads or runs a dense embedding model. Every MinSync search is then a sparse search.
18
+ */
19
+ export declare const SPARSE_ONLY_EMBEDDER_ID = "none";
20
+ /** True when the configured embedder asks for a sparse-only MinSync index. */
21
+ export declare function isSparseOnlyEmbedder(embedder: MinSyncEmbedderConfig | undefined): boolean;
22
+ /** The `[embedder].id` an initialized workspace was built with, or undefined when there is no config. */
23
+ export declare function configuredEmbedderId(workspacePath: string): string | undefined;
16
24
  /**
17
25
  * MinSync config.toml lives at `<workspace>/.minsync/config.toml`.
18
26
  * After `minsync init` runs, we rewrite allowlisted embedder fields so
@@ -24,11 +32,6 @@ export declare function minSyncConfigPath(workspacePath: string): string;
24
32
  export declare function minSyncEmbeddingIdentityPath(workspacePath: string): string;
25
33
  export declare function configuredMaxChunkSize(workspacePath: string): number | undefined;
26
34
  export declare function configuredVectorDimension(workspacePath: string): number | undefined;
27
- /**
28
- * The BM25 tokenizer in `[lexical].language`, or undefined when there is no config. A config without the section
29
- * (written before MinSync had one) behaves as MinSync's default, `simple`.
30
- */
31
- export declare function configuredLexicalLanguage(workspacePath: string): string | undefined;
32
35
  /**
33
36
  * Atomically rewrite allowlisted embedder fields in MinSync config.toml.
34
37
  * Reads the existing file, merges the allowlisted fields from `embedder`,
@@ -38,13 +41,11 @@ export declare function configuredLexicalLanguage(workspacePath: string): string
38
41
  * Allowlisted [embedder] fields: id, base_url, query_prefix, passage_prefix,
39
42
  * batch_size, max_retries, max_concurrent, timeout_seconds (from timeoutMs / 1000 ceil).
40
43
  * Dimension is written under [vectorstore.options] as `dimension`.
41
- * `managed.maxChunkSize` goes to [chunker.options] and `managed.lexicalLanguage` to [lexical].language. MinSync
42
- * itself records the tokenizer an index was built with in its cursor and, when [lexical].language differs, deletes
43
- * and re-indexes every chunk on the next sync, so changing it needs no `--full` from the caller.
44
+ * `managed.maxChunkSize` goes to [chunker.options]. The `[lexical]` table of a BM25-era workspace is removed: MinSync
45
+ * 0.6 replaced BM25 with SPLADE sparse retrieval and migrates such an index in place on its next sync.
44
46
  *
45
47
  * Returns true if the file was rewritten, false if the file does not exist.
46
48
  */
47
49
  export declare function rewriteEmbedderConfig(workspacePath: string, embedder: MinSyncEmbedderConfig, managed?: {
48
50
  readonly maxChunkSize?: number;
49
- readonly lexicalLanguage?: MinSyncLexicalLanguage;
50
51
  }): boolean;
@@ -1,3 +1,4 @@
1
+ import { type OutdatedMinSyncBinary } from "./version.js";
1
2
  /**
2
3
  * MinSync is the only retrieval method that searches document content
3
4
  * semantically, so AutoRAG treats it as required: when it cannot be used there
@@ -10,5 +11,7 @@ export declare class MinSyncRequiredError extends Error {
10
11
  }
11
12
  /** Raised when the `minsync` executable cannot be resolved. Path-free on purpose. */
12
13
  export declare function minSyncBinaryMissingError(): MinSyncRequiredError;
14
+ /** Raised when every `minsync` found is older than {@link MINSYNC_MIN_VERSION} and none may be installed now. */
15
+ export declare function minSyncOutdatedError(found: readonly OutdatedMinSyncBinary[]): MinSyncRequiredError;
13
16
  /** Raised when auto-install ran and failed; carries the installer's own message. */
14
17
  export declare function minSyncInstallFailedError(cause: unknown): MinSyncRequiredError;
@@ -1,5 +1,5 @@
1
1
  export { MinSyncClient, type MinSyncClientOptions, MinSyncQueryError, type MinSyncQueryMode, } from "./client.js";
2
- export { configuredVectorDimension, DEFAULT_MINSYNC_EMBEDDER_CONFIG, DEFAULT_MINSYNC_EMBEDDER_DIMENSION, DEFAULT_MINSYNC_EMBEDDER_ID, MINSYNC_CONFIG_DIR, MINSYNC_CONFIG_FILE, type MinSyncEmbeddingIdentity, minSyncConfigPath, minSyncEmbeddingIdentityPath, rewriteEmbedderConfig, } from "./embedder-config.js";
2
+ export { configuredVectorDimension, DEFAULT_MINSYNC_EMBEDDER_CONFIG, DEFAULT_MINSYNC_EMBEDDER_DIMENSION, DEFAULT_MINSYNC_EMBEDDER_ID, isSparseOnlyEmbedder, MINSYNC_CONFIG_DIR, MINSYNC_CONFIG_FILE, type MinSyncEmbeddingIdentity, minSyncConfigPath, minSyncEmbeddingIdentityPath, rewriteEmbedderConfig, SPARSE_ONLY_EMBEDDER_ID, } from "./embedder-config.js";
3
3
  export { MinSyncRequiredError } from "./errors.js";
4
4
  export { type EnsureMinSyncBinaryOptions, ensureMinSyncBinary, executableName, fetchLatestMinSyncRelease, type InstalledMinSyncBinary, MINSYNC_VERSION, type MinSyncRelease, type MinSyncReleaseAsset, MinSyncReleaseError, selectReleaseAsset, } from "./installer.js";
5
5
  export { ensureLocalEmbedder, LocalEmbedderError, type LocalEmbedderPreflightOptions, } from "./local-embedder.js";
@@ -1,4 +1,4 @@
1
- export declare const MINSYNC_VERSION = "0.5.1";
1
+ export declare const MINSYNC_VERSION = "0.6.0";
2
2
  export declare const MINSYNC_CARGO_INSTALL_TIMEOUT_MS: number;
3
3
  export interface MinSyncReleaseAsset {
4
4
  readonly name: string;
@@ -50,6 +50,7 @@ export declare class MinSyncVectorMethod implements RetrievalMethod {
50
50
  }): Promise<string>;
51
51
  }
52
52
  export declare class MinSyncHybridMethod extends MinSyncVectorMethod {
53
+ private readonly sparseOnly;
53
54
  constructor(options: MinSyncHybridMethodOptions);
54
55
  describe(): RetrievalMethodDescriptor;
55
56
  }
@@ -1,5 +1,4 @@
1
1
  /** Embedder configuration for MinSync vector indexing. Shared by config and method layers. */
2
- import type { MinSyncLexicalLanguage } from "./lexical-language.js";
3
2
  export interface MinSyncEmbedderConfig {
4
3
  readonly id?: string;
5
4
  readonly baseUrl?: string;
@@ -44,14 +43,6 @@ export interface MinSyncSyncResult {
44
43
  readonly stagingExcluded?: readonly string[];
45
44
  /** Files MinSync skipped (exit 6, `partial`); the sync itself completed and the next sync retries them. */
46
45
  readonly filesFailed?: readonly MinSyncFileFailure[];
47
- /**
48
- * Set when the multilingual tokenizer needs the Kiwi native library and it was not found, so the index was
49
- * built with whitespace tokenization instead. The sync itself succeeded.
50
- */
51
- readonly lexicalFallback?: {
52
- readonly requested: MinSyncLexicalLanguage;
53
- readonly used: MinSyncLexicalLanguage;
54
- };
55
46
  }
56
47
  export interface MinSyncFileFailure {
57
48
  readonly path: string;
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Oldest `minsync` AutoRAG will run. 0.6.0 replaced the BM25 full-text index with SPLADE sparse retrieval: AutoRAG
3
+ * queries `--mode sparse` and no longer passes `init --language`, which older builds reject.
4
+ */
5
+ export declare const MINSYNC_MIN_VERSION = "0.6.0";
6
+ /** A `minsync` that was found but is older than {@link MINSYNC_MIN_VERSION}, so it is never run. */
7
+ export interface OutdatedMinSyncBinary {
8
+ readonly path: string;
9
+ readonly version: string;
10
+ }
11
+ /** Version from `minsync --version` output, or `undefined` when the output is not a MinSync version line. */
12
+ export declare function parseMinSyncVersion(output: string): string | undefined;
13
+ /** True when `version` is at or above {@link MINSYNC_MIN_VERSION}. Numeric, per component. */
14
+ export declare function isSupportedMinSyncVersion(version: string): boolean;
15
+ /**
16
+ * The version of the `minsync` at `binaryPath` when it is older than {@link MINSYNC_MIN_VERSION}, else undefined.
17
+ * A binary whose `--version` cannot be run or is not a MinSync version line is not called outdated, so a custom
18
+ * build is never locked out; the stage protocol check still guards it.
19
+ */
20
+ export declare function outdatedMinSyncVersion(binaryPath: string): string | undefined;
@@ -0,0 +1,30 @@
1
+ import type { ExactDuplicateFingerprint } from "../dupey/filter.js";
2
+ export declare const CLOUD_FINGERPRINTS_FILE = "cloud-fingerprints.json";
3
+ /**
4
+ * A cloud or network file's dupey identity, taken once while the file was on disk during its single download
5
+ * (or its single read over the network) and reused afterwards. This is what lets the exact-duplicate exclusion
6
+ * group such a file with a scanned copy without reading the released placeholder or the share again.
7
+ */
8
+ export interface CloudFingerprint {
9
+ /** The mirror's own source identity at fingerprint time (`size:mtimeNs`), so an unchanged file is not re-read. */
10
+ readonly sourceVersion: string;
11
+ /** Canonical-text hash; equals `content_hash` from `dupey scan --json`. */
12
+ readonly exact: string;
13
+ /** Characters dupey extracted; `0` means no text, so {@link exact} identifies nothing. */
14
+ readonly chars: number;
15
+ /** The document's own last-modified time, or `null` when dupey records none. */
16
+ readonly modified: string | null;
17
+ readonly revision: string | null;
18
+ }
19
+ /** AutoRAG-owned store of cloud fingerprints, keyed by absolute source path. Not part of the MinSync stage schema. */
20
+ export interface CloudFingerprintStore {
21
+ readonly version: 1;
22
+ readonly entries: Readonly<Record<string, CloudFingerprint>>;
23
+ }
24
+ export declare function cloudFingerprintStorePath(root: string): string;
25
+ export declare function emptyCloudFingerprints(): CloudFingerprintStore;
26
+ /** Load the stored fingerprints; a missing or unreadable store reads as empty, never an error. */
27
+ export declare function loadCloudFingerprints(root: string): CloudFingerprintStore;
28
+ export declare function saveCloudFingerprints(root: string, entries: Readonly<Record<string, CloudFingerprint>>): void;
29
+ /** View the store as the exclusion merge's fingerprint map (absolute path to exact hash and modified time). */
30
+ export declare function cloudFingerprintExclusions(store: CloudFingerprintStore): ReadonlyMap<string, ExactDuplicateFingerprint>;
@@ -0,0 +1,79 @@
1
+ import { type CloudFileProbe, type CloudProvider } from "../filesystem/cloud-placeholder.js";
2
+ /** Placeholders one refresh may download before the rest wait for the next refresh. */
3
+ export declare const DEFAULT_CLOUD_MAX_FILES = 200;
4
+ /** Placeholder bytes one refresh may download. The first file is always allowed so a large one cannot starve. */
5
+ export declare const DEFAULT_CLOUD_MAX_BYTES: number;
6
+ /**
7
+ * Retries after the first failed release. A just-hydrated file is often briefly held by the provider, so the
8
+ * release is refused once and succeeds on a retry; a short doubling wait usually clears it.
9
+ */
10
+ export declare const DEFAULT_CLOUD_EVICT_RETRIES = 3;
11
+ /** First wait before retrying an evict; doubles each retry (500, 1000, 2000 ms by default). */
12
+ export declare const DEFAULT_CLOUD_EVICT_BACKOFF_MS = 500;
13
+ export interface CloudGateOptions {
14
+ readonly probe?: CloudFileProbe;
15
+ readonly maxFiles?: number;
16
+ readonly maxBytes?: number;
17
+ readonly evictAfterParse?: boolean;
18
+ /** Retries after the first failed evict; `0` tries once. Default {@link DEFAULT_CLOUD_EVICT_RETRIES}. */
19
+ readonly evictRetries?: number;
20
+ /** First retry wait in ms, doubled each retry. Default {@link DEFAULT_CLOUD_EVICT_BACKOFF_MS}. */
21
+ readonly evictBackoffMs?: number;
22
+ /** Wait implementation; tests inject one that records instead of sleeping. */
23
+ readonly sleep?: (ms: number) => Promise<void>;
24
+ }
25
+ export type CloudReleaseResult = {
26
+ readonly ok: true;
27
+ } | {
28
+ readonly ok: false;
29
+ readonly message: string;
30
+ };
31
+ /**
32
+ * What a refresh does with one file that needs parsing:
33
+ * - `local`: not a placeholder; read it as always.
34
+ * - `download`: a placeholder the probe can release, inside the budget; read it, then release it again.
35
+ * - `skip`: a placeholder whose provider the probe cannot release; do not read it.
36
+ * - `defer`: a releasable placeholder over this refresh's budget; leave it for the next refresh.
37
+ */
38
+ export type CloudDecision = {
39
+ readonly kind: "local";
40
+ } | {
41
+ readonly kind: "download";
42
+ } | {
43
+ readonly kind: "skip";
44
+ readonly provider: CloudProvider | undefined;
45
+ } | {
46
+ readonly kind: "defer";
47
+ };
48
+ /**
49
+ * One refresh's view of cloud placeholders. Reading a placeholder downloads it, so the refresh asks here
50
+ * before every read; without a probe (a platform AutoRAG has no cloud handling for) every file is `local`.
51
+ */
52
+ export declare class CloudGate {
53
+ private readonly probe;
54
+ private readonly maxFiles;
55
+ private readonly maxBytes;
56
+ private readonly evictRetries;
57
+ private readonly evictBackoffMs;
58
+ private readonly sleep;
59
+ private readonly providerByDirectory;
60
+ private placeholders;
61
+ private downloadedFiles;
62
+ private downloadedBytes;
63
+ /** Whether a downloaded cloud file is released again after it is parsed. */
64
+ readonly evictAfterParse: boolean;
65
+ constructor(options?: CloudGateOptions);
66
+ /** Look up, in one batch, which of the files about to be read are placeholders. */
67
+ classify(paths: readonly string[]): Promise<void>;
68
+ isPlaceholder(path: string): boolean;
69
+ /** Decide, and when the answer is `download`, spend this refresh's budget on `sizeBytes`. */
70
+ decide(path: string, sizeBytes: number, directory: string): Promise<CloudDecision>;
71
+ /**
72
+ * Release the local copy of a file this refresh downloaded. A failed attempt is retried with doubling waits;
73
+ * once the retries are spent the last error is returned and the file is left on disk. Giving up is final for
74
+ * this refresh: the file stays indexed, and an unchanged file is not processed again, so nothing retries it later.
75
+ */
76
+ release(path: string): Promise<CloudReleaseResult>;
77
+ /** Providers are resolved once per directory: a File Provider domain covers the whole subtree. */
78
+ private providerIn;
79
+ }
@@ -1,3 +1,7 @@
1
+ export type { CloudEvictResult, CloudFileProbe, CloudProvider, CloudRoot, CloudRootKind, } from "../filesystem/cloud-placeholder.js";
2
+ export { DEFAULT_CLOUD_MAX_BYTES, DEFAULT_CLOUD_MAX_FILES } from "./cloud.js";
3
+ export type { CloudFingerprint, CloudFingerprintStore } from "./cloud-fingerprints.js";
4
+ export { cloudFingerprintExclusions, cloudFingerprintStorePath, emptyCloudFingerprints, loadCloudFingerprints, saveCloudFingerprints, } from "./cloud-fingerprints.js";
1
5
  export type { ParsedMirrorEntry, ParsedMirrorIndex } from "./index-store.js";
2
6
  export { emptyMirrorIndex, loadMirrorIndex } from "./index-store.js";
3
7
  export { isParsedRefreshComplete, parsedMirrorRoot, parsedOutputPath, refreshReadinessPath, } from "./paths.js";
@@ -1,3 +1,5 @@
1
+ import { type DupeyCliOptions } from "../dupey/cli.js";
2
+ import { type CloudFileProbe } from "../filesystem/cloud-placeholder.js";
1
3
  import { type DefaultParserRegistryOptions } from "../parser/defaults.js";
2
4
  import type { ParserRegistry } from "../parser/registry.js";
3
5
  /** Refuse to fully load/parse sources larger than this. Keeps Node heap stable on home folders. */
@@ -8,6 +10,12 @@ export declare const DEFAULT_MAX_DELETE_RATIO = 0.3;
8
10
  export declare const DEFAULT_MAX_SCANNED_ENTRIES = 2000000;
9
11
  /** Deepest directory level (search root = 0) the walk descends into. */
10
12
  export declare const DEFAULT_MAX_WALK_DEPTH = 64;
13
+ /**
14
+ * Sources parsed and committed per batch before {@link ParsedMirrorSyncOptions.onBatch}
15
+ * runs. Small enough that a corpus becomes searchable after its first slice,
16
+ * large enough to amortize one index sync's startup.
17
+ */
18
+ export declare const DEFAULT_MIRROR_BATCH_SIZE = 25;
11
19
  export interface ParsedMirrorSyncOptions {
12
20
  readonly root: string;
13
21
  readonly searchPaths: readonly string[];
@@ -34,6 +42,20 @@ export interface ParsedMirrorSyncOptions {
34
42
  readonly signal?: AbortSignal;
35
43
  /** Called before each file and once more with `processed === total` when the parse phase ends. */
36
44
  readonly onProgress?: (progress: ParsedMirrorProgress) => void;
45
+ /**
46
+ * Sources parsed and committed per batch before {@link ParsedMirrorSyncOptions.onBatch}
47
+ * runs. Default {@link DEFAULT_MIRROR_BATCH_SIZE}.
48
+ */
49
+ readonly batchSize?: number;
50
+ /**
51
+ * Runs after each batch of sources is parsed and committed to the mirror, and
52
+ * before the next batch is read, so a caller can make the batch's results
53
+ * searchable (stage them and sync the index). A thrown error aborts the
54
+ * refresh; returning `stop` ends the loop after this batch. Deletions of
55
+ * genuinely-removed sources wait for the final batch, so a mid-refresh call
56
+ * never drops a not-yet-reached document from the index.
57
+ */
58
+ readonly onBatch?: (batch: ParsedMirrorBatch) => Promise<ParsedMirrorBatchOutcome | undefined>;
37
59
  /**
38
60
  * Largest share of previously indexed documents one refresh may delete because their source
39
61
  * disappeared. A larger deletion (above 100 documents) is suppressed with `mass-delete-suppressed`
@@ -51,6 +73,36 @@ export interface ParsedMirrorSyncOptions {
51
73
  readonly transientRetries?: number;
52
74
  /** Base delay between transient retries; doubles per retry. Default 50ms. */
53
75
  readonly transientRetryBackoffMs?: number;
76
+ /**
77
+ * Cloud-aware handling of File Provider placeholders (files whose data is not on disk; reading one
78
+ * downloads it) and the roots — cloud or network — that other readers must skip or exclude. `undefined`
79
+ * means the platform default: macOS probes with `stat` and releases through a Foundation call, other
80
+ * platforms read every file as before. Tests inject their own probe.
81
+ */
82
+ readonly cloudProbe?: CloudFileProbe;
83
+ /** Most placeholders one refresh may download. Default {@link DEFAULT_CLOUD_MAX_FILES}. */
84
+ readonly cloudMaxFiles?: number;
85
+ /** Most placeholder bytes one refresh may download; the first file is always allowed. Default {@link DEFAULT_CLOUD_MAX_BYTES}. */
86
+ readonly cloudMaxBytes?: number;
87
+ /** Release a downloaded cloud file again once it is parsed and indexed. Default true. */
88
+ readonly cloudEvictAfterParse?: boolean;
89
+ /** Retries after a failed release (`evictUbiquitousItem`), with doubling waits; `0` tries once. Default 3. */
90
+ readonly cloudEvictRetries?: number;
91
+ /** First wait before retrying a failed release, doubled each retry. Default 500 ms. */
92
+ readonly cloudEvictBackoffMs?: number;
93
+ /** Wait used between release retries. Tests inject a recorder so they never really sleep. */
94
+ readonly cloudSleep?: (ms: number) => Promise<void>;
95
+ /**
96
+ * Record a dupey fingerprint for every cloud or network file parsed in this refresh, while it is on disk,
97
+ * into an AutoRAG-owned store under the workspace. The stored identity lets the next refresh's
98
+ * exact-duplicate exclusion group the file without reading its released placeholder or its share again.
99
+ * Absent keeps no fingerprints. Needs {@link ParsedMirrorSyncOptions.cloudProbe} for the machine's roots.
100
+ */
101
+ readonly cloudFingerprints?: CloudFingerprintSyncOptions;
102
+ }
103
+ /** How a refresh fingerprints cloud and network files: the dupey CLI (or a test double) that reads the exact hash. */
104
+ export interface CloudFingerprintSyncOptions {
105
+ readonly dupey?: DupeyCliOptions;
54
106
  }
55
107
  /** Parse-phase progress. Every scanned file counts as processed, whether parsed, unchanged, skipped or excluded. */
56
108
  export interface ParsedMirrorProgress {
@@ -63,7 +115,7 @@ export interface ParsedMirrorProgress {
63
115
  /** The file about to be processed; absent on the final event. */
64
116
  readonly currentVirtualPath?: string;
65
117
  }
66
- export type ParsedMirrorDiagnosticCode = "unsupported-file" | "parser-skipped" | "parser-failed" | "parser-crashed" | "source-changed" | "source-vanished" | "source-unreadable" | "source-read-failed" | "mirror-write-failed" | "duplicate-excluded" | "deleted-mirror" | "stale-index" | "pdf-extract-thin" | "parser-warning" | "search-root-unavailable" | "mass-delete-suppressed" | "walk-truncated" | "directory-unreadable";
118
+ export type ParsedMirrorDiagnosticCode = "unsupported-file" | "parser-skipped" | "parser-failed" | "parser-crashed" | "source-changed" | "source-vanished" | "source-unreadable" | "source-read-failed" | "mirror-write-failed" | "duplicate-excluded" | "deleted-mirror" | "stale-index" | "pdf-extract-thin" | "parser-warning" | "search-root-unavailable" | "mass-delete-suppressed" | "walk-truncated" | "directory-unreadable" | "cloud-download-deferred" | "cloud-placeholder-skipped" | "cloud-evict-failed" | "cloud-fingerprint-failed";
67
119
  /**
68
120
  * Refresh diagnostic. `source` is an opaque virtual path, never a real filesystem path.
69
121
  * `message` keeps the underlying error text, which may include a filesystem path.
@@ -83,6 +135,32 @@ export interface ParsedMirrorSyncResult {
83
135
  readonly indexPath: string;
84
136
  readonly diagnostics: readonly ParsedMirrorDiagnostic[];
85
137
  }
138
+ /**
139
+ * One batch of the source listing, parsed and committed to the mirror before
140
+ * {@link ParsedMirrorSyncOptions.onBatch} runs. The last batch is the only one
141
+ * whose run reflects deletions of genuinely-removed sources.
142
+ */
143
+ export interface ParsedMirrorBatch {
144
+ /** 1-based index of this batch among the batches handed to `onBatch`. */
145
+ readonly index: number;
146
+ /**
147
+ * Batches the listing was divided into. A batch that wrote and deleted no
148
+ * mirror output is not handed to `onBatch`; the final batch always is.
149
+ */
150
+ readonly total: number;
151
+ /** Virtual paths the refresh attempted in this batch. */
152
+ readonly virtualPaths: readonly string[];
153
+ /** The last batch: genuine deletions have by now been applied to the mirror. */
154
+ readonly final: boolean;
155
+ }
156
+ /**
157
+ * What {@link ParsedMirrorSyncOptions.onBatch} asks the refresh to do next.
158
+ * A thrown error aborts the refresh; `stop` ends the loop after this batch, so a
159
+ * systemic index failure never reads sources it knows it cannot index.
160
+ */
161
+ export interface ParsedMirrorBatchOutcome {
162
+ readonly stop?: boolean;
163
+ }
86
164
  /** Default retries for a transient per-file I/O error. Mirrors the `refresh.transientRetries` config default. */
87
165
  export declare const DEFAULT_TRANSIENT_RETRIES = 3;
88
166
  /**
@@ -0,0 +1,26 @@
1
+ import { type ParseInput, type ParseOutput, Parser } from "./types.js";
2
+ /** Delimited-text extensions the CSV parser owns. */
3
+ export declare const DELIMITED_EXTENSIONS: readonly [".csv", ".tsv"];
4
+ export interface CsvParserOptions {
5
+ /** Rows kept per file, header included. Default 100,000. */
6
+ readonly maxRows?: number;
7
+ }
8
+ /**
9
+ * Parses `.csv` and `.tsv` files into the same row lines as workbooks (see `spreadsheet-render.ts`):
10
+ * the file name stands in for the sheet name, titles above a table become its caption, and each value
11
+ * is paired with its column label when the header is unambiguous.
12
+ *
13
+ * Bytes are decoded like plain text (UTF-8 with or without BOM, or CP949/EUC-KR as Korean Excel saves
14
+ * CSV). Fields follow RFC 4180: quoted fields may hold separators, line breaks and doubled quotes, and
15
+ * rows may have different lengths. `.tsv` is tab-separated; a `.csv` uses Excel's `sep=` line when present,
16
+ * otherwise the separator (`,` `;` tab `|`) that splits the first lines most consistently outside quotes.
17
+ * Values stay exactly as written: no number, date or formula conversion.
18
+ */
19
+ export declare class CsvParser extends Parser {
20
+ #private;
21
+ readonly name = "csv";
22
+ readonly extensions: readonly [".csv", ".tsv"];
23
+ readonly version = "2";
24
+ constructor(options?: CsvParserOptions);
25
+ parse(input: ParseInput): Promise<ParseOutput>;
26
+ }
@@ -8,7 +8,7 @@ export interface DefaultParserRegistryOptions {
8
8
  /** Global document languages; selects the OCR engine when OCR is enabled. */
9
9
  readonly languages?: readonly LanguageTag[];
10
10
  /**
11
- * Hard per-file parse deadline in milliseconds (default 120000). kordoc, pptx and eml parse in a worker
11
+ * Hard per-file parse deadline in milliseconds (default 120000). kordoc, spreadsheet, csv, pptx and eml parse in a worker
12
12
  * thread during a refresh; a parse still running at the deadline has its worker terminated and the file
13
13
  * is skipped as `parser-failed`. A synchronous spin cannot be interrupted any other way.
14
14
  */
@@ -1,3 +1,4 @@
1
+ export { CsvParser, type CsvParserOptions, DELIMITED_EXTENSIONS } from "./csv.js";
1
2
  export { createDefaultParserRegistry, type DefaultParserRegistryOptions, resolveParserOptions, } from "./defaults.js";
2
3
  export { EmlParser } from "./eml.js";
3
4
  export { ParseError } from "./errors.js";
@@ -6,4 +7,5 @@ export { BUILTIN_OCR_LANGUAGES, createTesseractOcrProvider, type OcrOptions, typ
6
7
  export { PptxParser } from "./office.js";
7
8
  export { PlainTextParser } from "./plain-text.js";
8
9
  export { ParserRegistry } from "./registry.js";
10
+ export { SPREADSHEET_EXTENSIONS, SpreadsheetParser, type SpreadsheetParserOptions } from "./spreadsheet.js";
9
11
  export { type ParseDiagnostic, type ParseDiagnosticCode, type ParseInput, type ParseOutput, Parser, } from "./types.js";
@@ -37,15 +37,18 @@ export interface KordocParserOptions {
37
37
  readonly images?: boolean;
38
38
  readonly parse?: KordocParseFn;
39
39
  }
40
- /** Document extensions kordoc parses. `.pptx` and `.eml` stay on their own parsers. */
41
- export declare const KORDOC_EXTENSIONS: readonly [".hwp", ".hwpx", ".hml", ".hwpml", ".pdf", ".docx", ".xlsx", ".xls"];
40
+ /**
41
+ * Document extensions kordoc parses. `.pptx` and `.eml` stay on their own parsers, and workbooks
42
+ * (`.xlsx`, `.xls`, …) go to the spreadsheet parser, which keeps every value next to its labels.
43
+ */
44
+ export declare const KORDOC_EXTENSIONS: readonly [".hwp", ".hwpx", ".hml", ".hwpml", ".pdf", ".docx"];
42
45
  /**
43
46
  * Standalone image formats kordoc OCRs directly. `.bmp` and `.tiff` return
44
47
  * `UNSUPPORTED_FORMAT` from kordoc, so they are deliberately not claimed.
45
48
  */
46
49
  export declare const KORDOC_IMAGE_EXTENSIONS: readonly [".png", ".jpg", ".jpeg", ".webp"];
47
50
  /**
48
- * Parses HWP/HWPX/HWPML, PDF, DOCX and XLSX/XLS through the kordoc library.
51
+ * Parses HWP/HWPX/HWPML, PDF and DOCX through the kordoc library.
49
52
  *
50
53
  * kordoc reports failures as a result object; AutoRAG's contract is a thrown
51
54
  * `ParseError`, so the code and message are forwarded verbatim (AGENTS.md error