@dynamik-dev/refdocs 0.1.1

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 (46) hide show
  1. package/README.md +109 -0
  2. package/dist/src/chunker.d.ts +9 -0
  3. package/dist/src/chunker.d.ts.map +1 -0
  4. package/dist/src/chunker.js +205 -0
  5. package/dist/src/chunker.js.map +1 -0
  6. package/dist/src/config.d.ts +8 -0
  7. package/dist/src/config.d.ts.map +1 -0
  8. package/dist/src/config.js +77 -0
  9. package/dist/src/config.js.map +1 -0
  10. package/dist/src/index.d.ts +3 -0
  11. package/dist/src/index.d.ts.map +1 -0
  12. package/dist/src/index.js +124 -0
  13. package/dist/src/index.js.map +1 -0
  14. package/dist/src/indexer.d.ts +9 -0
  15. package/dist/src/indexer.d.ts.map +1 -0
  16. package/dist/src/indexer.js +58 -0
  17. package/dist/src/indexer.js.map +1 -0
  18. package/dist/src/search.d.ts +11 -0
  19. package/dist/src/search.d.ts.map +1 -0
  20. package/dist/src/search.js +63 -0
  21. package/dist/src/search.js.map +1 -0
  22. package/dist/src/types.d.ts +39 -0
  23. package/dist/src/types.d.ts.map +1 -0
  24. package/dist/src/types.js +2 -0
  25. package/dist/src/types.js.map +1 -0
  26. package/dist/tests/chunker.test.d.ts +2 -0
  27. package/dist/tests/chunker.test.d.ts.map +1 -0
  28. package/dist/tests/chunker.test.js +245 -0
  29. package/dist/tests/chunker.test.js.map +1 -0
  30. package/dist/tests/cli.test.d.ts +2 -0
  31. package/dist/tests/cli.test.d.ts.map +1 -0
  32. package/dist/tests/cli.test.js +166 -0
  33. package/dist/tests/cli.test.js.map +1 -0
  34. package/dist/tests/config.test.d.ts +2 -0
  35. package/dist/tests/config.test.d.ts.map +1 -0
  36. package/dist/tests/config.test.js +94 -0
  37. package/dist/tests/config.test.js.map +1 -0
  38. package/dist/tests/indexer.test.d.ts +2 -0
  39. package/dist/tests/indexer.test.d.ts.map +1 -0
  40. package/dist/tests/indexer.test.js +109 -0
  41. package/dist/tests/indexer.test.js.map +1 -0
  42. package/dist/tests/search.test.d.ts +2 -0
  43. package/dist/tests/search.test.d.ts.map +1 -0
  44. package/dist/tests/search.test.js +160 -0
  45. package/dist/tests/search.test.js.map +1 -0
  46. package/package.json +39 -0
@@ -0,0 +1,94 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from "vitest";
2
+ import { mkdtempSync, writeFileSync, mkdirSync, rmSync } from "node:fs";
3
+ import { join } from "node:path";
4
+ import { tmpdir } from "node:os";
5
+ import { loadConfig, validateConfig } from "../src/config.js";
6
+ describe("validateConfig", () => {
7
+ it("returns no errors for valid config", () => {
8
+ expect(validateConfig({
9
+ paths: ["docs"],
10
+ index: ".index.json",
11
+ chunkMaxTokens: 800,
12
+ chunkMinTokens: 100,
13
+ boostFields: { title: 2, headings: 1.5, body: 1 },
14
+ })).toEqual([]);
15
+ });
16
+ it("returns no errors for empty object (all optional)", () => {
17
+ expect(validateConfig({})).toEqual([]);
18
+ });
19
+ it("rejects non-object config", () => {
20
+ expect(validateConfig("string")).toEqual(["Config must be a JSON object"]);
21
+ expect(validateConfig(null)).toEqual(["Config must be a JSON object"]);
22
+ expect(validateConfig([])).toEqual(["Config must be a JSON object"]);
23
+ });
24
+ it("rejects invalid paths", () => {
25
+ const errors = validateConfig({ paths: "not-array" });
26
+ expect(errors).toContain('"paths" must be an array of strings');
27
+ });
28
+ it("rejects non-string items in paths", () => {
29
+ const errors = validateConfig({ paths: [123] });
30
+ expect(errors).toContain('"paths" must be an array of strings');
31
+ });
32
+ it("rejects non-string index", () => {
33
+ const errors = validateConfig({ index: 123 });
34
+ expect(errors).toContain('"index" must be a string');
35
+ });
36
+ it("rejects non-positive chunkMaxTokens", () => {
37
+ expect(validateConfig({ chunkMaxTokens: -1 })).toContain('"chunkMaxTokens" must be a positive number');
38
+ expect(validateConfig({ chunkMaxTokens: "abc" })).toContain('"chunkMaxTokens" must be a positive number');
39
+ });
40
+ it("rejects non-positive chunkMinTokens", () => {
41
+ expect(validateConfig({ chunkMinTokens: 0 })).toContain('"chunkMinTokens" must be a positive number');
42
+ });
43
+ it("rejects invalid boostFields", () => {
44
+ expect(validateConfig({ boostFields: "not-object" })).toContain('"boostFields" must be an object');
45
+ });
46
+ it("rejects non-number boost field values", () => {
47
+ const errors = validateConfig({ boostFields: { title: "high" } });
48
+ expect(errors).toContain('"boostFields.title" must be a number');
49
+ });
50
+ });
51
+ describe("loadConfig", () => {
52
+ let tmpDir;
53
+ beforeEach(() => {
54
+ tmpDir = mkdtempSync(join(tmpdir(), "refdocs-test-"));
55
+ });
56
+ afterEach(() => {
57
+ rmSync(tmpDir, { recursive: true, force: true });
58
+ });
59
+ it("returns defaults when no config file exists", () => {
60
+ const { config, configDir } = loadConfig(tmpDir);
61
+ expect(config.paths).toEqual(["ref-docs"]);
62
+ expect(config.index).toBe(".refdocs-index.json");
63
+ expect(config.chunkMaxTokens).toBe(800);
64
+ expect(config.chunkMinTokens).toBe(100);
65
+ expect(configDir).toBe(tmpDir);
66
+ });
67
+ it("loads config from given directory", () => {
68
+ writeFileSync(join(tmpDir, ".refdocs.json"), JSON.stringify({ paths: ["docs"], chunkMaxTokens: 500 }));
69
+ const { config } = loadConfig(tmpDir);
70
+ expect(config.paths).toEqual(["docs"]);
71
+ expect(config.chunkMaxTokens).toBe(500);
72
+ expect(config.chunkMinTokens).toBe(100); // default preserved
73
+ });
74
+ it("walks up directories to find config", () => {
75
+ writeFileSync(join(tmpDir, ".refdocs.json"), JSON.stringify({ paths: ["custom-docs"] }));
76
+ const subDir = join(tmpDir, "sub", "deep");
77
+ mkdirSync(subDir, { recursive: true });
78
+ const { config, configDir } = loadConfig(subDir);
79
+ expect(config.paths).toEqual(["custom-docs"]);
80
+ expect(configDir).toBe(tmpDir);
81
+ });
82
+ it("merges boostFields with defaults", () => {
83
+ writeFileSync(join(tmpDir, ".refdocs.json"), JSON.stringify({ boostFields: { title: 5 } }));
84
+ const { config } = loadConfig(tmpDir);
85
+ expect(config.boostFields.title).toBe(5);
86
+ expect(config.boostFields.headings).toBe(1.5);
87
+ expect(config.boostFields.body).toBe(1);
88
+ });
89
+ it("throws on invalid config", () => {
90
+ writeFileSync(join(tmpDir, ".refdocs.json"), JSON.stringify({ paths: "not-an-array" }));
91
+ expect(() => loadConfig(tmpDir)).toThrow("Invalid .refdocs.json");
92
+ });
93
+ });
94
+ //# sourceMappingURL=config.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.test.js","sourceRoot":"","sources":["../../tests/config.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=indexer.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"indexer.test.d.ts","sourceRoot":"","sources":["../../tests/indexer.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,109 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from "vitest";
2
+ import { mkdtempSync, writeFileSync, mkdirSync, rmSync, existsSync } from "node:fs";
3
+ import { join } from "node:path";
4
+ import { tmpdir } from "node:os";
5
+ import { findMarkdownFiles, buildIndex, loadPersistedIndex } from "../src/indexer.js";
6
+ import { search } from "../src/search.js";
7
+ const testConfig = {
8
+ paths: ["docs"],
9
+ index: ".refdocs-index.json",
10
+ chunkMaxTokens: 800,
11
+ chunkMinTokens: 100,
12
+ boostFields: { title: 2, headings: 1.5, body: 1 },
13
+ };
14
+ describe("findMarkdownFiles", () => {
15
+ let tmpDir;
16
+ beforeEach(() => {
17
+ tmpDir = mkdtempSync(join(tmpdir(), "refdocs-idx-"));
18
+ mkdirSync(join(tmpDir, "docs"), { recursive: true });
19
+ });
20
+ afterEach(() => {
21
+ rmSync(tmpDir, { recursive: true, force: true });
22
+ });
23
+ it("finds .md files in configured paths", () => {
24
+ writeFileSync(join(tmpDir, "docs", "readme.md"), "# Hello");
25
+ writeFileSync(join(tmpDir, "docs", "guide.md"), "# Guide");
26
+ const files = findMarkdownFiles(["docs"], tmpDir);
27
+ expect(files).toEqual(["docs/guide.md", "docs/readme.md"]);
28
+ });
29
+ it("finds files recursively", () => {
30
+ mkdirSync(join(tmpDir, "docs", "sub"), { recursive: true });
31
+ writeFileSync(join(tmpDir, "docs", "root.md"), "# Root");
32
+ writeFileSync(join(tmpDir, "docs", "sub", "nested.md"), "# Nested");
33
+ const files = findMarkdownFiles(["docs"], tmpDir);
34
+ expect(files).toContain("docs/root.md");
35
+ expect(files).toContain("docs/sub/nested.md");
36
+ });
37
+ it("ignores non-md files", () => {
38
+ writeFileSync(join(tmpDir, "docs", "readme.md"), "# Hello");
39
+ writeFileSync(join(tmpDir, "docs", "notes.txt"), "not markdown");
40
+ writeFileSync(join(tmpDir, "docs", "data.json"), "{}");
41
+ const files = findMarkdownFiles(["docs"], tmpDir);
42
+ expect(files).toEqual(["docs/readme.md"]);
43
+ });
44
+ it("returns empty array for missing directory", () => {
45
+ const files = findMarkdownFiles(["nonexistent"], tmpDir);
46
+ expect(files).toEqual([]);
47
+ });
48
+ it("returns sorted list", () => {
49
+ writeFileSync(join(tmpDir, "docs", "z-file.md"), "# Z");
50
+ writeFileSync(join(tmpDir, "docs", "a-file.md"), "# A");
51
+ writeFileSync(join(tmpDir, "docs", "m-file.md"), "# M");
52
+ const files = findMarkdownFiles(["docs"], tmpDir);
53
+ expect(files).toEqual(["docs/a-file.md", "docs/m-file.md", "docs/z-file.md"]);
54
+ });
55
+ });
56
+ describe("buildIndex", () => {
57
+ let tmpDir;
58
+ beforeEach(() => {
59
+ tmpDir = mkdtempSync(join(tmpdir(), "refdocs-build-"));
60
+ mkdirSync(join(tmpDir, "docs"), { recursive: true });
61
+ });
62
+ afterEach(() => {
63
+ rmSync(tmpDir, { recursive: true, force: true });
64
+ });
65
+ it("builds index and writes to disk", () => {
66
+ writeFileSync(join(tmpDir, "docs", "api.md"), "# API\n\n## Authentication\n\nUse JWT tokens for auth.\n\n## Rate Limiting\n\nDefault is 100 req/min.\n");
67
+ const summary = buildIndex(testConfig, tmpDir);
68
+ expect(summary.filesIndexed).toBe(1);
69
+ expect(summary.chunksCreated).toBeGreaterThanOrEqual(1);
70
+ expect(summary.indexSizeBytes).toBeGreaterThan(0);
71
+ expect(summary.elapsedMs).toBeGreaterThanOrEqual(0);
72
+ expect(existsSync(join(tmpDir, ".refdocs-index.json"))).toBe(true);
73
+ });
74
+ it("indexes multiple files", () => {
75
+ writeFileSync(join(tmpDir, "docs", "a.md"), "# File A\n\nContent A about authentication and tokens.\n");
76
+ writeFileSync(join(tmpDir, "docs", "b.md"), "# File B\n\nContent B about configuration and setup.\n");
77
+ const summary = buildIndex(testConfig, tmpDir);
78
+ expect(summary.filesIndexed).toBe(2);
79
+ });
80
+ it("produces searchable index", () => {
81
+ writeFileSync(join(tmpDir, "docs", "guide.md"), "# Setup Guide\n\n## Database\n\nConfigure PostgreSQL connection string in your .env file.\n\n## Cache\n\nRedis is used for caching session data.\n");
82
+ buildIndex(testConfig, tmpDir);
83
+ const { index } = loadPersistedIndex(join(tmpDir, ".refdocs-index.json"), testConfig);
84
+ const results = search(index, "PostgreSQL", { maxResults: 3 });
85
+ expect(results.length).toBeGreaterThan(0);
86
+ expect(results[0].body).toContain("PostgreSQL");
87
+ });
88
+ });
89
+ describe("loadPersistedIndex", () => {
90
+ it("throws with actionable error when index does not exist", () => {
91
+ expect(() => loadPersistedIndex("/nonexistent/path.json", testConfig)).toThrow("Index not found. Run `refdocs index` first.");
92
+ });
93
+ it("round-trips build + load successfully", () => {
94
+ const tmpDir = mkdtempSync(join(tmpdir(), "refdocs-rt-"));
95
+ try {
96
+ mkdirSync(join(tmpDir, "docs"), { recursive: true });
97
+ writeFileSync(join(tmpDir, "docs", "test.md"), "# Test Doc\n\nThis is test content about widgets and gadgets.\n");
98
+ buildIndex(testConfig, tmpDir);
99
+ const { index, chunks } = loadPersistedIndex(join(tmpDir, ".refdocs-index.json"), testConfig);
100
+ expect(chunks.length).toBeGreaterThan(0);
101
+ const results = search(index, "widgets", { maxResults: 3 });
102
+ expect(results.length).toBeGreaterThan(0);
103
+ }
104
+ finally {
105
+ rmSync(tmpDir, { recursive: true, force: true });
106
+ }
107
+ });
108
+ });
109
+ //# sourceMappingURL=indexer.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"indexer.test.js","sourceRoot":"","sources":["../../tests/indexer.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=search.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.test.d.ts","sourceRoot":"","sources":["../../tests/search.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,160 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { createSearchIndex, indexChunks, serializeIndex, loadIndex, search, } from "../src/search.js";
3
+ const testConfig = {
4
+ paths: ["docs"],
5
+ index: ".refdocs-index.json",
6
+ chunkMaxTokens: 800,
7
+ chunkMinTokens: 100,
8
+ boostFields: { title: 2, headings: 1.5, body: 1 },
9
+ };
10
+ function makeChunk(overrides) {
11
+ return {
12
+ file: "test.md",
13
+ title: "Test",
14
+ headings: "Test",
15
+ body: "test body",
16
+ startLine: 1,
17
+ endLine: 10,
18
+ tokenEstimate: 10,
19
+ ...overrides,
20
+ };
21
+ }
22
+ const sampleChunks = [
23
+ makeChunk({
24
+ id: "api.md:0",
25
+ file: "api.md",
26
+ title: "Authentication",
27
+ headings: "API > Authentication",
28
+ body: "Use JWT tokens for authentication. Include the token in the Authorization header.",
29
+ startLine: 1,
30
+ endLine: 5,
31
+ }),
32
+ makeChunk({
33
+ id: "api.md:1",
34
+ file: "api.md",
35
+ title: "Rate Limiting",
36
+ headings: "API > Rate Limiting",
37
+ body: "Rate limits are applied per API key. Default limit is 100 requests per minute.",
38
+ startLine: 6,
39
+ endLine: 10,
40
+ }),
41
+ makeChunk({
42
+ id: "guide.md:0",
43
+ file: "guide.md",
44
+ title: "Getting Started",
45
+ headings: "Getting Started",
46
+ body: "Install the package and configure your environment. Run npm install to get started.",
47
+ startLine: 1,
48
+ endLine: 8,
49
+ }),
50
+ makeChunk({
51
+ id: "guide.md:1",
52
+ file: "guide.md",
53
+ title: "Configuration",
54
+ headings: "Getting Started > Configuration",
55
+ body: "Create a .env file with your database URL and API key for authentication.",
56
+ startLine: 9,
57
+ endLine: 15,
58
+ }),
59
+ ];
60
+ describe("createSearchIndex and indexChunks", () => {
61
+ it("creates an index and adds chunks without error", () => {
62
+ const index = createSearchIndex(testConfig);
63
+ indexChunks(index, sampleChunks);
64
+ expect(index.documentCount).toBe(sampleChunks.length);
65
+ });
66
+ });
67
+ describe("search", () => {
68
+ it("finds relevant results for a query", () => {
69
+ const index = createSearchIndex(testConfig);
70
+ indexChunks(index, sampleChunks);
71
+ const results = search(index, "authentication", { maxResults: 3 });
72
+ expect(results.length).toBeGreaterThan(0);
73
+ expect(results[0].file).toBe("api.md");
74
+ expect(results[0].body).toContain("JWT tokens");
75
+ });
76
+ it("respects maxResults", () => {
77
+ const index = createSearchIndex(testConfig);
78
+ indexChunks(index, sampleChunks);
79
+ const results = search(index, "api", { maxResults: 1 });
80
+ expect(results).toHaveLength(1);
81
+ });
82
+ it("returns empty array for no matches", () => {
83
+ const index = createSearchIndex(testConfig);
84
+ indexChunks(index, sampleChunks);
85
+ const results = search(index, "xyznonexistent", { maxResults: 3 });
86
+ expect(results).toHaveLength(0);
87
+ });
88
+ it("includes score, file, lines, headings, body in results", () => {
89
+ const index = createSearchIndex(testConfig);
90
+ indexChunks(index, sampleChunks);
91
+ const results = search(index, "rate limiting", { maxResults: 3 });
92
+ const result = results[0];
93
+ expect(result.score).toBeGreaterThan(0);
94
+ expect(result.file).toBe("api.md");
95
+ expect(result.lines).toEqual([6, 10]);
96
+ expect(result.headings).toEqual(["API", "Rate Limiting"]);
97
+ expect(result.body).toContain("100 requests per minute");
98
+ });
99
+ it("boosts title matches over body matches", () => {
100
+ const index = createSearchIndex(testConfig);
101
+ indexChunks(index, sampleChunks);
102
+ // "Authentication" appears in title of api.md:0 and body of guide.md:1
103
+ const results = search(index, "authentication", { maxResults: 4 });
104
+ expect(results[0].file).toBe("api.md");
105
+ expect(results[0].headings).toContain("Authentication");
106
+ });
107
+ it("supports fuzzy matching", () => {
108
+ const index = createSearchIndex(testConfig);
109
+ indexChunks(index, sampleChunks);
110
+ // Misspelling
111
+ const results = search(index, "authenication", { maxResults: 3 });
112
+ expect(results.length).toBeGreaterThan(0);
113
+ });
114
+ it("supports prefix matching", () => {
115
+ const index = createSearchIndex(testConfig);
116
+ indexChunks(index, sampleChunks);
117
+ const results = search(index, "auth", { maxResults: 3 });
118
+ expect(results.length).toBeGreaterThan(0);
119
+ });
120
+ it("filters by file glob", () => {
121
+ const index = createSearchIndex(testConfig);
122
+ indexChunks(index, sampleChunks);
123
+ const results = search(index, "authentication", {
124
+ maxResults: 10,
125
+ fileFilter: "guide.*",
126
+ });
127
+ for (const r of results) {
128
+ expect(r.file).toMatch(/^guide/);
129
+ }
130
+ });
131
+ });
132
+ describe("serialization", () => {
133
+ it("round-trips through serialize and load", () => {
134
+ const index = createSearchIndex(testConfig);
135
+ indexChunks(index, sampleChunks);
136
+ const json = serializeIndex(index, sampleChunks);
137
+ const { index: loaded, chunks } = loadIndex(json, testConfig);
138
+ expect(chunks).toEqual(sampleChunks);
139
+ const results = search(loaded, "authentication", { maxResults: 3 });
140
+ expect(results.length).toBeGreaterThan(0);
141
+ expect(results[0].body).toContain("JWT");
142
+ });
143
+ it("includes version and createdAt in serialized output", () => {
144
+ const index = createSearchIndex(testConfig);
145
+ indexChunks(index, sampleChunks);
146
+ const json = serializeIndex(index, sampleChunks);
147
+ const parsed = JSON.parse(json);
148
+ expect(parsed.version).toBe(1);
149
+ expect(parsed.createdAt).toBeDefined();
150
+ });
151
+ it("throws on version mismatch", () => {
152
+ const index = createSearchIndex(testConfig);
153
+ indexChunks(index, sampleChunks);
154
+ const json = serializeIndex(index, sampleChunks);
155
+ const parsed = JSON.parse(json);
156
+ parsed.version = 999;
157
+ expect(() => loadIndex(JSON.stringify(parsed), testConfig)).toThrow("Index version mismatch");
158
+ });
159
+ });
160
+ //# sourceMappingURL=search.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.test.js","sourceRoot":"","sources":["../../tests/search.test.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "@dynamik-dev/refdocs",
3
+ "version": "0.1.1",
4
+ "type": "module",
5
+ "description": "Local CLI tool that indexes markdown documentation and exposes fast fuzzy search with intelligent chunking",
6
+ "main": "dist/src/index.js",
7
+ "bin": {
8
+ "refdocs": "dist/src/index.js"
9
+ },
10
+ "files": [
11
+ "dist"
12
+ ],
13
+ "scripts": {
14
+ "test": "vitest run",
15
+ "test:watch": "vitest",
16
+ "build": "bun build --compile src/index.ts --outfile refdocs"
17
+ },
18
+ "publishConfig": {
19
+ "registry": "https://registry.npmjs.org",
20
+ "access": "public"
21
+ },
22
+ "repository": {
23
+ "type": "git",
24
+ "url": "https://github.com/dynamik-dev/refdoc-cli.git"
25
+ },
26
+ "dependencies": {
27
+ "commander": "^13.1.0",
28
+ "mdast-util-from-markdown": "^2.0.2",
29
+ "minisearch": "^7.1.1",
30
+ "picomatch": "^4.0.2"
31
+ },
32
+ "devDependencies": {
33
+ "@types/node": "^22.0.0",
34
+ "@types/picomatch": "^3.0.1",
35
+ "tsx": "^4.19.0",
36
+ "typescript": "^5.7.3",
37
+ "vitest": "^3.0.5"
38
+ }
39
+ }