mirror of
https://github.com/giancarloerra/socraticode.git
synced 2026-07-03 14:05:21 +02:00
Merge pull request #10 from midweste/midweste-dotfiles
feat: add env support for controlling indexing of dotfiles
This commit is contained in:
@@ -163,7 +163,7 @@ I built SocratiCode because I regularly work on existing, large, and complex cod
|
||||
- **Live file watching** — Optionally watch for file changes and keep the index updated in real time (debounced 2s). Watcher also invalidates the code graph cache.
|
||||
- **Parallel processing** — Files are scanned and chunked in parallel batches (50 at a time) for fast I/O, while embedding generation and upserts are batched separately for optimal throughput.
|
||||
- **Multi-project** — Index multiple projects simultaneously. Each gets its own isolated collection with full project path tracking.
|
||||
- **Respects ignore rules** — Honors all `.gitignore` files (root + nested), plus an optional `.socraticodeignore` for additional exclusions. Includes sensible built-in defaults. `.gitignore` processing can be disabled via `RESPECT_GITIGNORE=false`.
|
||||
- **Respects ignore rules** — Honors all `.gitignore` files (root + nested), plus an optional `.socraticodeignore` for additional exclusions. Includes sensible built-in defaults. `.gitignore` processing can be disabled via `RESPECT_GITIGNORE=false`. Dot-directories (e.g. `.agent`) can be included via `INCLUDE_DOT_FILES=true`.
|
||||
- **Custom file extensions** — Projects with non-standard extensions (e.g. `.tpl`, `.blade`) can be included via `EXTRA_EXTENSIONS` env var or `extraExtensions` tool parameter. Works for both indexing and code graph.
|
||||
- **Configurable infrastructure** — All ports, hosts, and API keys are configurable via environment variables. Qdrant API key support for enterprise deployments.
|
||||
- **Auto-setup** — On first use, automatically checks Docker, pulls images, starts containers, and pulls the embedding model. Only prerequisite: Docker.
|
||||
@@ -725,6 +725,7 @@ Artifacts are chunked and embedded into Qdrant using the same hybrid dense + BM2
|
||||
| Variable | Default | Description |
|
||||
|----------|---------|-------------|
|
||||
| `RESPECT_GITIGNORE` | `true` | Set to `false` to skip `.gitignore` processing. Built-in defaults and `.socraticodeignore` still apply. |
|
||||
| `INCLUDE_DOT_FILES` | `false` | Set to `true` to include dot-directories (e.g. `.agent`, `.config`) in indexing. By default, directories and files starting with `.` are excluded. Useful for projects where important code lives in dot-directories. |
|
||||
| `EXTRA_EXTENSIONS` | *(none)* | Comma-separated list of additional file extensions to scan (e.g. `.tpl,.blade,.hbs`). Applies to both indexing and code graph. Files with extra extensions are indexed as plaintext and appear as leaf nodes in the code graph. Can also be passed per-operation via the `extraExtensions` tool parameter. |
|
||||
| `MAX_FILE_SIZE_MB` | `5` | Maximum file size in MB. Files larger than this are skipped during indexing. Increase for repos with large generated or data files you want indexed. |
|
||||
| `SEARCH_DEFAULT_LIMIT` | `10` | Default number of results returned by `codebase_search` (1-50). Each result is a ranked code chunk with file path, line range, and content. Higher values give broader coverage but produce more output. Can still be overridden per-query via the `limit` tool parameter. |
|
||||
|
||||
@@ -615,7 +615,7 @@ export async function getIndexableFiles(
|
||||
const allFiles = await glob("**/*", {
|
||||
cwd: projectPath,
|
||||
nodir: true,
|
||||
dot: false,
|
||||
dot: (process.env.INCLUDE_DOT_FILES ?? "false").toLowerCase() === "true",
|
||||
absolute: false,
|
||||
});
|
||||
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
// Copyright (C) 2026 Giancarlo Erra - Altaire Limited
|
||||
import { beforeAll, describe, expect, it } from "vitest";
|
||||
import fs from "node:fs";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import { afterAll, beforeAll, describe, expect, it, vi } from "vitest";
|
||||
import { CHUNK_SIZE, MAX_CHUNK_CHARS } from "../../src/constants.js";
|
||||
import { ensureDynamicLanguages } from "../../src/services/code-graph.js";
|
||||
import { chunkFileContent, chunkId, hashContent, isIndexableFile } from "../../src/services/indexer.js";
|
||||
import { chunkFileContent, chunkId, getIndexableFiles, hashContent, isIndexableFile } from "../../src/services/indexer.js";
|
||||
|
||||
// Register dynamic language grammars once for AST-aware chunking tests
|
||||
beforeAll(() => {
|
||||
@@ -286,4 +289,69 @@ describe("indexer utilities", () => {
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// ── getIndexableFiles (INCLUDE_DOT_FILES) ─────────────────────────────
|
||||
|
||||
describe("getIndexableFiles", () => {
|
||||
let tmpDir: string;
|
||||
|
||||
beforeAll(() => {
|
||||
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "socraticode-dotfiles-test-"));
|
||||
|
||||
// Regular file
|
||||
fs.mkdirSync(path.join(tmpDir, "src"), { recursive: true });
|
||||
fs.writeFileSync(path.join(tmpDir, "src", "index.ts"), "export const x = 1;\n");
|
||||
|
||||
// Dot-directory with an indexable file
|
||||
fs.mkdirSync(path.join(tmpDir, ".agent", "rules"), { recursive: true });
|
||||
fs.writeFileSync(path.join(tmpDir, ".agent", "rules", "config.ts"), "export const rule = true;\n");
|
||||
|
||||
// Dot-file at root (e.g. .gitignore)
|
||||
fs.writeFileSync(path.join(tmpDir, ".gitignore"), "node_modules/\n");
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
fs.rmSync(tmpDir, { recursive: true, force: true });
|
||||
});
|
||||
|
||||
it("excludes dot-directory files by default", async () => {
|
||||
const files = await getIndexableFiles(tmpDir);
|
||||
const hasDotDir = files.some((f) => f.includes(".agent"));
|
||||
expect(hasDotDir).toBe(false);
|
||||
});
|
||||
|
||||
it("includes dot-directory files when INCLUDE_DOT_FILES=true", async () => {
|
||||
vi.stubEnv("INCLUDE_DOT_FILES", "true");
|
||||
try {
|
||||
const files = await getIndexableFiles(tmpDir);
|
||||
const dotFiles = files.filter((f) => f.includes(".agent"));
|
||||
expect(dotFiles.length).toBeGreaterThan(0);
|
||||
expect(dotFiles.some((f) => f.includes("config.ts"))).toBe(true);
|
||||
} finally {
|
||||
vi.unstubAllEnvs();
|
||||
}
|
||||
});
|
||||
|
||||
it("treats INCLUDE_DOT_FILES case-insensitively", async () => {
|
||||
vi.stubEnv("INCLUDE_DOT_FILES", "True");
|
||||
try {
|
||||
const files = await getIndexableFiles(tmpDir);
|
||||
const hasDotDir = files.some((f) => f.includes(".agent"));
|
||||
expect(hasDotDir).toBe(true);
|
||||
} finally {
|
||||
vi.unstubAllEnvs();
|
||||
}
|
||||
});
|
||||
|
||||
it("excludes dot-directory files for non-true values", async () => {
|
||||
vi.stubEnv("INCLUDE_DOT_FILES", "yes");
|
||||
try {
|
||||
const files = await getIndexableFiles(tmpDir);
|
||||
const hasDotDir = files.some((f) => f.includes(".agent"));
|
||||
expect(hasDotDir).toBe(false);
|
||||
} finally {
|
||||
vi.unstubAllEnvs();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user