@milo4jo/contextkit 0.3.0 → 0.5.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.
- package/README.md +43 -11
- package/dist/commands/cache.d.ts +3 -0
- package/dist/commands/cache.d.ts.map +1 -0
- package/dist/commands/cache.js +50 -0
- package/dist/commands/cache.js.map +1 -0
- package/dist/commands/select.d.ts.map +1 -1
- package/dist/commands/select.js +17 -9
- package/dist/commands/select.js.map +1 -1
- package/dist/config/index.d.ts +11 -0
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +11 -0
- package/dist/config/index.js.map +1 -1
- package/dist/config/validation.d.ts +33 -0
- package/dist/config/validation.d.ts.map +1 -0
- package/dist/config/validation.js +241 -0
- package/dist/config/validation.js.map +1 -0
- package/dist/db/index.d.ts +47 -0
- package/dist/db/index.d.ts.map +1 -1
- package/dist/db/index.js +98 -0
- package/dist/db/index.js.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/indexer/chunker.d.ts +15 -2
- package/dist/indexer/chunker.d.ts.map +1 -1
- package/dist/indexer/chunker.js +222 -3
- package/dist/indexer/chunker.js.map +1 -1
- package/dist/parsers/index.d.ts +45 -0
- package/dist/parsers/index.d.ts.map +1 -0
- package/dist/parsers/index.js +71 -0
- package/dist/parsers/index.js.map +1 -0
- package/dist/parsers/typescript.d.ts +43 -0
- package/dist/parsers/typescript.d.ts.map +1 -0
- package/dist/parsers/typescript.js +306 -0
- package/dist/parsers/typescript.js.map +1 -0
- package/dist/retrieval/imports.d.ts +76 -0
- package/dist/retrieval/imports.d.ts.map +1 -0
- package/dist/retrieval/imports.js +258 -0
- package/dist/retrieval/imports.js.map +1 -0
- package/dist/selector/formatter.d.ts +15 -0
- package/dist/selector/formatter.d.ts.map +1 -1
- package/dist/selector/formatter.js +132 -0
- package/dist/selector/formatter.js.map +1 -1
- package/dist/selector/index.d.ts +15 -4
- package/dist/selector/index.d.ts.map +1 -1
- package/dist/selector/index.js +100 -12
- package/dist/selector/index.js.map +1 -1
- package/dist/selector/scoring.d.ts +20 -0
- package/dist/selector/scoring.d.ts.map +1 -1
- package/dist/selector/scoring.js +103 -10
- package/dist/selector/scoring.js.map +1 -1
- package/package.json +1 -1
- package/dist/commands/source.d.ts +0 -3
- package/dist/commands/source.d.ts.map +0 -1
- package/dist/commands/source.js +0 -153
- package/dist/commands/source.js.map +0 -1
- package/dist/utils/output.d.ts +0 -42
- package/dist/utils/output.d.ts.map +0 -1
- package/dist/utils/output.js +0 -62
- package/dist/utils/output.js.map +0 -1
package/README.md
CHANGED
|
@@ -4,8 +4,11 @@
|
|
|
4
4
|
> ContextKit selects the *right* context for any query — saving tokens and improving answers.
|
|
5
5
|
|
|
6
6
|
[](https://www.npmjs.com/package/@milo4jo/contextkit)
|
|
7
|
+
[](https://www.npmjs.com/package/@milo4jo/contextkit)
|
|
7
8
|
[](https://opensource.org/licenses/MIT)
|
|
8
9
|
|
|
10
|
+
**🆕 v0.5:** Import-aware scoring — files that import your selected code get boosted automatically!
|
|
11
|
+
|
|
9
12
|
---
|
|
10
13
|
|
|
11
14
|
## The Problem
|
|
@@ -86,12 +89,24 @@ export function validateToken(token: string): User | null {
|
|
|
86
89
|
|
|
87
90
|
## Why ContextKit?
|
|
88
91
|
|
|
92
|
+
**Real example:** A 50k line codebase needs ~200k tokens to include everything. ContextKit gives you the **relevant 3-8k tokens** for any query. That's **96% token savings** and better answers.
|
|
93
|
+
|
|
89
94
|
| Approach | Problem |
|
|
90
95
|
|----------|---------|
|
|
91
|
-
| **Dump everything** | Expensive, hits token limits,
|
|
92
|
-
| **Basic RAG** | Returns "similar"
|
|
93
|
-
| **Manual selection** | Tedious, doesn't scale |
|
|
94
|
-
| **ContextKit** | ✅
|
|
96
|
+
| **Dump everything** | 💸 Expensive, hits token limits, dilutes focus |
|
|
97
|
+
| **Basic RAG** | Returns "similar" chunks, misses dependencies |
|
|
98
|
+
| **Manual selection** | Tedious, inconsistent, doesn't scale |
|
|
99
|
+
| **ContextKit** | ✅ Smart selection, import-aware, local-first |
|
|
100
|
+
|
|
101
|
+
### Why Not LSP-Based Tools?
|
|
102
|
+
|
|
103
|
+
Tools like [Serena](https://github.com/oramasearch/serena) use Language Server Protocol for deep code understanding. Great for complex refactoring, but:
|
|
104
|
+
|
|
105
|
+
- **Heavy setup** — requires language servers per language
|
|
106
|
+
- **Slow startup** — LSP initialization takes seconds
|
|
107
|
+
- **Complex** — more moving parts to configure
|
|
108
|
+
|
|
109
|
+
**ContextKit takes a different approach:** Semantic search + import graph analysis. Works instantly on any codebase, any language. No language servers needed.
|
|
95
110
|
|
|
96
111
|
### vs. LangChain / LlamaIndex
|
|
97
112
|
|
|
@@ -99,7 +114,7 @@ Those are full frameworks. ContextKit does **one thing well**: context selection
|
|
|
99
114
|
|
|
100
115
|
### vs. Vector Databases (Pinecone, Chroma)
|
|
101
116
|
|
|
102
|
-
They're storage. ContextKit adds the **intelligence layer** — scoring, budgeting, formatting.
|
|
117
|
+
They're storage. ContextKit adds the **intelligence layer** — scoring, budgeting, code-aware formatting.
|
|
103
118
|
|
|
104
119
|
---
|
|
105
120
|
|
|
@@ -161,8 +176,17 @@ contextkit select "database queries" --sources src,lib
|
|
|
161
176
|
# Show scoring details
|
|
162
177
|
contextkit select "user validation" --explain
|
|
163
178
|
|
|
164
|
-
#
|
|
165
|
-
contextkit select "
|
|
179
|
+
# Output formats
|
|
180
|
+
contextkit select "query" --format markdown # Default, with code blocks
|
|
181
|
+
contextkit select "query" --format xml # XML structure (Claude prefers this)
|
|
182
|
+
contextkit select "query" --format json # JSON for scripts/integrations
|
|
183
|
+
contextkit select "query" --format plain # Plain text, no formatting
|
|
184
|
+
|
|
185
|
+
# Include imported files (follows dependency graph)
|
|
186
|
+
contextkit select "query" --include-imports
|
|
187
|
+
|
|
188
|
+
# Pipe to clipboard (macOS)
|
|
189
|
+
contextkit select "query" --format plain | pbcopy
|
|
166
190
|
```
|
|
167
191
|
|
|
168
192
|
---
|
|
@@ -277,8 +301,14 @@ settings:
|
|
|
277
301
|
1. **Chunking** — Files split into ~500 token chunks with overlap
|
|
278
302
|
2. **Embedding** — Each chunk embedded with [gte-small](https://huggingface.co/thenlper/gte-small) (runs locally)
|
|
279
303
|
3. **Similarity** — Query embedded and compared via cosine similarity
|
|
280
|
-
4. **
|
|
281
|
-
5. **
|
|
304
|
+
4. **Import Analysis** — Parses ES6/CommonJS/dynamic imports to build dependency graph
|
|
305
|
+
5. **Multi-Factor Scoring** — Chunks ranked by:
|
|
306
|
+
- Semantic similarity (40%)
|
|
307
|
+
- Query term matches (25%)
|
|
308
|
+
- Path relevance (20%)
|
|
309
|
+
- Recency (10%)
|
|
310
|
+
- **Import boost** (5%) — files imported by selected code get boosted
|
|
311
|
+
6. **Budgeting** — Top chunks selected until token budget filled
|
|
282
312
|
|
|
283
313
|
### Requirements
|
|
284
314
|
|
|
@@ -305,13 +335,15 @@ contextkit select "How does authentication work?"
|
|
|
305
335
|
|
|
306
336
|
- [x] CLI with init, source, index, select
|
|
307
337
|
- [x] MCP server for Claude Desktop
|
|
308
|
-
- [x] Demo project for testing
|
|
309
338
|
- [x] Incremental indexing (only changed files)
|
|
310
339
|
- [x] Watch mode (auto-reindex on save)
|
|
311
340
|
- [x] Multi-factor scoring algorithm
|
|
341
|
+
- [x] Multiple output formats (markdown, XML, JSON, plain)
|
|
342
|
+
- [x] **Import-aware scoring** — understands code dependencies
|
|
343
|
+
- [ ] Function/class boundary awareness
|
|
312
344
|
- [ ] VS Code extension
|
|
313
345
|
- [ ] Cursor integration
|
|
314
|
-
- [ ]
|
|
346
|
+
- [ ] Neovim plugin
|
|
315
347
|
|
|
316
348
|
---
|
|
317
349
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/commands/cache.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,eAAO,MAAM,YAAY,SACW,CAAC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { ensureInitialized } from '../config/index.js';
|
|
3
|
+
import { openDatabase, clearCache, getCacheStats } from '../db/index.js';
|
|
4
|
+
import { writeData, writeMessage, writeSuccess } from '../utils/streams.js';
|
|
5
|
+
import { getGlobalOpts } from '../utils/cli.js';
|
|
6
|
+
export const cacheCommand = new Command('cache')
|
|
7
|
+
.description('Manage query cache');
|
|
8
|
+
cacheCommand
|
|
9
|
+
.command('clear')
|
|
10
|
+
.description('Clear all cached query results')
|
|
11
|
+
.action(() => {
|
|
12
|
+
ensureInitialized();
|
|
13
|
+
const db = openDatabase();
|
|
14
|
+
try {
|
|
15
|
+
const cleared = clearCache(db);
|
|
16
|
+
writeSuccess(`Cleared ${cleared} cached ${cleared === 1 ? 'entry' : 'entries'}`);
|
|
17
|
+
}
|
|
18
|
+
finally {
|
|
19
|
+
db.close();
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
cacheCommand
|
|
23
|
+
.command('stats')
|
|
24
|
+
.description('Show cache statistics')
|
|
25
|
+
.action(() => {
|
|
26
|
+
ensureInitialized();
|
|
27
|
+
const opts = getGlobalOpts(cacheCommand);
|
|
28
|
+
const db = openDatabase();
|
|
29
|
+
try {
|
|
30
|
+
const stats = getCacheStats(db);
|
|
31
|
+
if (opts.json) {
|
|
32
|
+
writeData(JSON.stringify(stats, null, 2));
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
writeMessage('');
|
|
36
|
+
writeMessage(`📊 Cache Statistics`);
|
|
37
|
+
writeMessage(` Entries: ${stats.entryCount}`);
|
|
38
|
+
writeMessage(` Total hits: ${stats.totalHits}`);
|
|
39
|
+
if (stats.oldestEntry) {
|
|
40
|
+
writeMessage(` Oldest: ${stats.oldestEntry}`);
|
|
41
|
+
writeMessage(` Newest: ${stats.newestEntry}`);
|
|
42
|
+
}
|
|
43
|
+
writeMessage('');
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
finally {
|
|
47
|
+
db.close();
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
//# sourceMappingURL=cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/commands/cache.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACzE,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAC5E,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC;KAC7C,WAAW,CAAC,oBAAoB,CAAC,CAAC;AAErC,YAAY;KACT,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,gCAAgC,CAAC;KAC7C,MAAM,CAAC,GAAG,EAAE;IACX,iBAAiB,EAAE,CAAC;IAEpB,MAAM,EAAE,GAAG,YAAY,EAAE,CAAC;IAC1B,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,UAAU,CAAC,EAAE,CAAC,CAAC;QAC/B,YAAY,CAAC,WAAW,OAAO,WAAW,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC;IACnF,CAAC;YAAS,CAAC;QACT,EAAE,CAAC,KAAK,EAAE,CAAC;IACb,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,YAAY;KACT,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,uBAAuB,CAAC;KACpC,MAAM,CAAC,GAAG,EAAE;IACX,iBAAiB,EAAE,CAAC;IAEpB,MAAM,IAAI,GAAG,aAAa,CAAC,YAAY,CAAC,CAAC;IACzC,MAAM,EAAE,GAAG,YAAY,EAAE,CAAC;IAE1B,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,aAAa,CAAC,EAAE,CAAC,CAAC;QAEhC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAC5C,CAAC;aAAM,CAAC;YACN,YAAY,CAAC,EAAE,CAAC,CAAC;YACjB,YAAY,CAAC,qBAAqB,CAAC,CAAC;YACpC,YAAY,CAAC,mBAAmB,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC;YACpD,YAAY,CAAC,mBAAmB,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC;YACnD,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC;gBACtB,YAAY,CAAC,mBAAmB,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;gBACrD,YAAY,CAAC,mBAAmB,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;YACvD,CAAC;YACD,YAAY,CAAC,EAAE,CAAC,CAAC;QACnB,CAAC;IACH,CAAC;YAAS,CAAC;QACT,EAAE,CAAC,KAAK,EAAE,CAAC;IACb,CAAC;AACH,CAAC,CAAC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"select.d.ts","sourceRoot":"","sources":["../../src/commands/select.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"select.d.ts","sourceRoot":"","sources":["../../src/commands/select.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAYpC,eAAO,MAAM,aAAa,SAuEtB,CAAC"}
|
package/dist/commands/select.js
CHANGED
|
@@ -6,13 +6,17 @@ import { writeData, writeMessage, writeWarning } from '../utils/streams.js';
|
|
|
6
6
|
import { formatCommand, formatDim } from '../utils/format.js';
|
|
7
7
|
import { getGlobalOpts } from '../utils/cli.js';
|
|
8
8
|
import { InvalidUsageError } from '../errors/index.js';
|
|
9
|
+
/** Valid output formats */
|
|
10
|
+
const VALID_FORMATS = ['markdown', 'xml', 'json', 'plain'];
|
|
9
11
|
export const selectCommand = new Command('select')
|
|
10
12
|
.description('Select context for a query')
|
|
11
13
|
.argument('<query>', 'The query to find context for')
|
|
12
14
|
.option('-b, --budget <tokens>', 'Maximum tokens to include', '8000')
|
|
13
|
-
.option('-f, --format <format>', 'Output format:
|
|
15
|
+
.option('-f, --format <format>', 'Output format: markdown, xml, json, plain', 'markdown')
|
|
14
16
|
.option('-s, --sources <sources>', 'Filter sources (comma-separated)')
|
|
15
17
|
.option('--explain', 'Show scoring details')
|
|
18
|
+
.option('--include-imports', 'Include files imported by selected chunks')
|
|
19
|
+
.option('--no-cache', 'Skip cache lookup')
|
|
16
20
|
.action(async (query, options) => {
|
|
17
21
|
ensureInitialized();
|
|
18
22
|
const opts = getGlobalOpts(selectCommand);
|
|
@@ -20,6 +24,11 @@ export const selectCommand = new Command('select')
|
|
|
20
24
|
if (isNaN(budget) || budget <= 0) {
|
|
21
25
|
throw new InvalidUsageError('Budget must be a positive number.');
|
|
22
26
|
}
|
|
27
|
+
// Validate format
|
|
28
|
+
const format = options.format.toLowerCase();
|
|
29
|
+
if (!VALID_FORMATS.includes(format)) {
|
|
30
|
+
throw new InvalidUsageError(`Invalid format "${options.format}". Valid formats: ${VALID_FORMATS.join(', ')}`);
|
|
31
|
+
}
|
|
23
32
|
// Parse sources filter
|
|
24
33
|
const sources = options.sources
|
|
25
34
|
? options.sources.split(',').map((s) => s.trim())
|
|
@@ -27,12 +36,17 @@ export const selectCommand = new Command('select')
|
|
|
27
36
|
// Open database
|
|
28
37
|
const db = openDatabase();
|
|
29
38
|
try {
|
|
39
|
+
// Determine effective format (--json flag overrides -f)
|
|
40
|
+
const effectiveFormat = opts.json ? 'json' : format;
|
|
30
41
|
// Run selection
|
|
31
42
|
const result = await selectContext(db, {
|
|
32
43
|
query,
|
|
33
44
|
budget,
|
|
34
45
|
sources,
|
|
35
46
|
explain: options.explain,
|
|
47
|
+
format: effectiveFormat,
|
|
48
|
+
includeImports: options.includeImports,
|
|
49
|
+
noCache: options.cache === false,
|
|
36
50
|
});
|
|
37
51
|
// Handle empty index
|
|
38
52
|
if (result.isEmpty) {
|
|
@@ -48,14 +62,8 @@ export const selectCommand = new Command('select')
|
|
|
48
62
|
writeMessage('');
|
|
49
63
|
return;
|
|
50
64
|
}
|
|
51
|
-
// Output
|
|
52
|
-
|
|
53
|
-
writeData(JSON.stringify(result.output.data, null, 2));
|
|
54
|
-
}
|
|
55
|
-
else {
|
|
56
|
-
// Text output goes to stdout (it's the data)
|
|
57
|
-
writeData(result.output.text);
|
|
58
|
-
}
|
|
65
|
+
// Output the formatted text
|
|
66
|
+
writeData(result.output.text);
|
|
59
67
|
}
|
|
60
68
|
finally {
|
|
61
69
|
db.close();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"select.js","sourceRoot":"","sources":["../../src/commands/select.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,aAAa,
|
|
1
|
+
{"version":3,"file":"select.js","sourceRoot":"","sources":["../../src/commands/select.ts"],"names":[],"mappings":"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"}
|
package/dist/config/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Config } from './types.js';
|
|
2
|
+
import { type ValidationResult } from './validation.js';
|
|
2
3
|
export declare const CONFIG_FILE = "config.yaml";
|
|
3
4
|
export declare const INDEX_DB = "index.db";
|
|
4
5
|
export declare const CONTEXTKIT_DIR = ".contextkit";
|
|
@@ -34,5 +35,15 @@ export declare function saveConfig(config: Config): void;
|
|
|
34
35
|
* Get the default configuration as YAML string
|
|
35
36
|
*/
|
|
36
37
|
export declare function getDefaultConfig(): string;
|
|
38
|
+
/**
|
|
39
|
+
* Load and validate the configuration file
|
|
40
|
+
* Returns both the config and validation result
|
|
41
|
+
*/
|
|
42
|
+
export declare function loadAndValidateConfig(): {
|
|
43
|
+
config: Config;
|
|
44
|
+
validation: ValidationResult;
|
|
45
|
+
};
|
|
37
46
|
export type { Config, Source, Settings } from './types.js';
|
|
47
|
+
export { validateConfig, formatValidationResults } from './validation.js';
|
|
48
|
+
export type { ValidationResult, ValidationError, ValidationWarning } from './validation.js';
|
|
38
49
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAkB,KAAK,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAExE,eAAO,MAAM,WAAW,gBAAgB,CAAC;AACzC,eAAO,MAAM,QAAQ,aAAa,CAAC;AACnC,eAAO,MAAM,cAAc,gBAAgB,CAAC;AAE5C;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED;;GAEG;AACH,wBAAgB,SAAS,IAAI,MAAM,CAElC;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,OAAO,CAEvC;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAIxC;AAED;;GAEG;AACH,wBAAgB,UAAU,IAAI,MAAM,CAgBnC;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAI/C;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAiCzC;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,IAAI;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,gBAAgB,CAAA;CAAE,CAIxF;AAED,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAC1E,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC"}
|
package/dist/config/index.js
CHANGED
|
@@ -2,6 +2,7 @@ import { existsSync, readFileSync, writeFileSync } from 'fs';
|
|
|
2
2
|
import { join } from 'path';
|
|
3
3
|
import { parse, stringify } from 'yaml';
|
|
4
4
|
import { NotInitializedError } from '../errors/index.js';
|
|
5
|
+
import { validateConfig } from './validation.js';
|
|
5
6
|
export const CONFIG_FILE = 'config.yaml';
|
|
6
7
|
export const INDEX_DB = 'index.db';
|
|
7
8
|
export const CONTEXTKIT_DIR = '.contextkit';
|
|
@@ -97,4 +98,14 @@ settings:
|
|
|
97
98
|
chunk_overlap: ${config.settings.chunk_overlap}
|
|
98
99
|
`;
|
|
99
100
|
}
|
|
101
|
+
/**
|
|
102
|
+
* Load and validate the configuration file
|
|
103
|
+
* Returns both the config and validation result
|
|
104
|
+
*/
|
|
105
|
+
export function loadAndValidateConfig() {
|
|
106
|
+
const config = loadConfig();
|
|
107
|
+
const validation = validateConfig(config, process.cwd());
|
|
108
|
+
return { config, validation };
|
|
109
|
+
}
|
|
110
|
+
export { validateConfig, formatValidationResults } from './validation.js';
|
|
100
111
|
//# sourceMappingURL=index.js.map
|
package/dist/config/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AAC7D,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AACxC,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AAC7D,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AACxC,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAEzD,OAAO,EAAE,cAAc,EAAyB,MAAM,iBAAiB,CAAC;AAExE,MAAM,CAAC,MAAM,WAAW,GAAG,aAAa,CAAC;AACzC,MAAM,CAAC,MAAM,QAAQ,GAAG,UAAU,CAAC;AACnC,MAAM,CAAC,MAAM,cAAc,GAAG,aAAa,CAAC;AAE5C;;GAEG;AACH,MAAM,UAAU,gBAAgB;IAC9B,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,cAAc,CAAC,CAAC;AAC7C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa;IAC3B,OAAO,IAAI,CAAC,gBAAgB,EAAE,EAAE,WAAW,CAAC,CAAC;AAC/C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,SAAS;IACvB,OAAO,IAAI,CAAC,gBAAgB,EAAE,EAAE,QAAQ,CAAC,CAAC;AAC5C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa;IAC3B,OAAO,UAAU,CAAC,gBAAgB,EAAE,CAAC,IAAI,UAAU,CAAC,aAAa,EAAE,CAAC,CAAC;AACvE,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB;IAC/B,IAAI,CAAC,aAAa,EAAE,EAAE,CAAC;QACrB,MAAM,IAAI,mBAAmB,EAAE,CAAC;IAClC,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU;IACxB,MAAM,UAAU,GAAG,aAAa,EAAE,CAAC;IAEnC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CAAC,0BAA0B,UAAU,EAAE,CAAC,CAAC;IAC1D,CAAC;IAED,MAAM,OAAO,GAAG,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IAClD,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAW,CAAC;IAExC,8BAA8B;IAC9B,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,CAAC,OAAO,GAAG,EAAE,CAAC;IACtB,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,MAAc;IACvC,MAAM,UAAU,GAAG,aAAa,EAAE,CAAC;IACnC,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC,CAAC;IACpD,aAAa,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;AACrC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB;IAC9B,MAAM,MAAM,GAAW;QACrB,OAAO,EAAE,CAAC;QACV,OAAO,EAAE,EAAE;QACX,QAAQ,EAAE;YACR,UAAU,EAAE,GAAG;YACf,aAAa,EAAE,EAAE;SAClB;KACF,CAAC;IAEF,OAAO;;;WAGE,MAAM,CAAC,OAAO;;;;;;;;;;;;;;;;;gBAiBT,MAAM,CAAC,QAAQ,CAAC,UAAU;mBACvB,MAAM,CAAC,QAAQ,CAAC,aAAa;CAC/C,CAAC;AACF,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,qBAAqB;IACnC,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,MAAM,UAAU,GAAG,cAAc,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IACzD,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;AAChC,CAAC;AAGD,OAAO,EAAE,cAAc,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Config Validation Module
|
|
3
|
+
*
|
|
4
|
+
* Validates config.yaml and provides helpful error messages.
|
|
5
|
+
*/
|
|
6
|
+
import type { Config } from './types.js';
|
|
7
|
+
/** Validation result */
|
|
8
|
+
export interface ValidationResult {
|
|
9
|
+
valid: boolean;
|
|
10
|
+
errors: ValidationError[];
|
|
11
|
+
warnings: ValidationWarning[];
|
|
12
|
+
}
|
|
13
|
+
/** Validation error (config won't work) */
|
|
14
|
+
export interface ValidationError {
|
|
15
|
+
path: string;
|
|
16
|
+
message: string;
|
|
17
|
+
suggestion?: string;
|
|
18
|
+
}
|
|
19
|
+
/** Validation warning (config might have issues) */
|
|
20
|
+
export interface ValidationWarning {
|
|
21
|
+
path: string;
|
|
22
|
+
message: string;
|
|
23
|
+
suggestion?: string;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Validate the entire config
|
|
27
|
+
*/
|
|
28
|
+
export declare function validateConfig(config: Config, baseDir: string): ValidationResult;
|
|
29
|
+
/**
|
|
30
|
+
* Format validation results for display
|
|
31
|
+
*/
|
|
32
|
+
export declare function formatValidationResults(result: ValidationResult): string;
|
|
33
|
+
//# sourceMappingURL=validation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/config/validation.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAoB,MAAM,YAAY,CAAC;AAE3D,wBAAwB;AACxB,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,QAAQ,EAAE,iBAAiB,EAAE,CAAC;CAC/B;AAED,2CAA2C;AAC3C,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,oDAAoD;AACpD,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,gBAAgB,CAwDhF;AA2JD;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,gBAAgB,GAAG,MAAM,CA6BxE"}
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Config Validation Module
|
|
3
|
+
*
|
|
4
|
+
* Validates config.yaml and provides helpful error messages.
|
|
5
|
+
*/
|
|
6
|
+
import { existsSync } from 'fs';
|
|
7
|
+
import { resolve } from 'path';
|
|
8
|
+
/**
|
|
9
|
+
* Validate the entire config
|
|
10
|
+
*/
|
|
11
|
+
export function validateConfig(config, baseDir) {
|
|
12
|
+
const errors = [];
|
|
13
|
+
const warnings = [];
|
|
14
|
+
// Validate version
|
|
15
|
+
if (typeof config.version !== 'number') {
|
|
16
|
+
errors.push({
|
|
17
|
+
path: 'version',
|
|
18
|
+
message: 'Version must be a number',
|
|
19
|
+
suggestion: 'Set version: 1',
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
// Validate sources
|
|
23
|
+
if (!Array.isArray(config.sources)) {
|
|
24
|
+
errors.push({
|
|
25
|
+
path: 'sources',
|
|
26
|
+
message: 'Sources must be an array',
|
|
27
|
+
suggestion: 'Add sources: [] to your config',
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
// Validate each source
|
|
32
|
+
const sourceIds = new Set();
|
|
33
|
+
for (let i = 0; i < config.sources.length; i++) {
|
|
34
|
+
const source = config.sources[i];
|
|
35
|
+
const sourcePath = `sources[${i}]`;
|
|
36
|
+
const sourceResult = validateSource(source, sourcePath, baseDir, sourceIds);
|
|
37
|
+
errors.push(...sourceResult.errors);
|
|
38
|
+
warnings.push(...sourceResult.warnings);
|
|
39
|
+
if (source.id) {
|
|
40
|
+
sourceIds.add(source.id);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
// Validate settings
|
|
45
|
+
if (config.settings) {
|
|
46
|
+
const settingsResult = validateSettings(config.settings);
|
|
47
|
+
errors.push(...settingsResult.errors);
|
|
48
|
+
warnings.push(...settingsResult.warnings);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
warnings.push({
|
|
52
|
+
path: 'settings',
|
|
53
|
+
message: 'Settings not specified, using defaults',
|
|
54
|
+
suggestion: 'Add settings: { chunk_size: 500, chunk_overlap: 50 }',
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
return {
|
|
58
|
+
valid: errors.length === 0,
|
|
59
|
+
errors,
|
|
60
|
+
warnings,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Validate a source configuration
|
|
65
|
+
*/
|
|
66
|
+
function validateSource(source, path, baseDir, existingIds) {
|
|
67
|
+
const errors = [];
|
|
68
|
+
const warnings = [];
|
|
69
|
+
// Validate id
|
|
70
|
+
if (!source.id || typeof source.id !== 'string') {
|
|
71
|
+
errors.push({
|
|
72
|
+
path: `${path}.id`,
|
|
73
|
+
message: 'Source must have a string id',
|
|
74
|
+
suggestion: 'Add id: "src" or similar',
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
else if (existingIds.has(source.id)) {
|
|
78
|
+
errors.push({
|
|
79
|
+
path: `${path}.id`,
|
|
80
|
+
message: `Duplicate source id "${source.id}"`,
|
|
81
|
+
suggestion: 'Each source must have a unique id',
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
else if (!/^[a-zA-Z0-9_-]+$/.test(source.id)) {
|
|
85
|
+
warnings.push({
|
|
86
|
+
path: `${path}.id`,
|
|
87
|
+
message: `Source id "${source.id}" contains special characters`,
|
|
88
|
+
suggestion: 'Use only letters, numbers, dashes, and underscores',
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
// Validate path
|
|
92
|
+
if (!source.path || typeof source.path !== 'string') {
|
|
93
|
+
errors.push({
|
|
94
|
+
path: `${path}.path`,
|
|
95
|
+
message: 'Source must have a path',
|
|
96
|
+
suggestion: 'Add path: "./src"',
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
// Check if path exists
|
|
101
|
+
const absolutePath = resolve(baseDir, source.path);
|
|
102
|
+
if (!existsSync(absolutePath)) {
|
|
103
|
+
errors.push({
|
|
104
|
+
path: `${path}.path`,
|
|
105
|
+
message: `Path "${source.path}" does not exist`,
|
|
106
|
+
suggestion: `Create the directory or fix the path. Looking for: ${absolutePath}`,
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
// Validate patterns
|
|
111
|
+
if (!source.patterns) {
|
|
112
|
+
errors.push({
|
|
113
|
+
path: `${path}.patterns`,
|
|
114
|
+
message: 'Source must have patterns',
|
|
115
|
+
suggestion: 'Add patterns: { include: ["**/*.ts"], exclude: ["**/node_modules/**"] }',
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
// Validate include patterns
|
|
120
|
+
if (!Array.isArray(source.patterns.include) || source.patterns.include.length === 0) {
|
|
121
|
+
errors.push({
|
|
122
|
+
path: `${path}.patterns.include`,
|
|
123
|
+
message: 'Include patterns must be a non-empty array',
|
|
124
|
+
suggestion: 'Add include: ["**/*.ts", "**/*.js"]',
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
for (const pattern of source.patterns.include) {
|
|
129
|
+
if (typeof pattern !== 'string') {
|
|
130
|
+
errors.push({
|
|
131
|
+
path: `${path}.patterns.include`,
|
|
132
|
+
message: 'Include patterns must be strings',
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
// Validate exclude patterns
|
|
138
|
+
if (!Array.isArray(source.patterns.exclude)) {
|
|
139
|
+
warnings.push({
|
|
140
|
+
path: `${path}.patterns.exclude`,
|
|
141
|
+
message: 'Exclude patterns should be an array',
|
|
142
|
+
suggestion: 'Add exclude: ["**/node_modules/**"]',
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
// Check for common mistakes
|
|
147
|
+
const hasNodeModules = source.patterns.exclude.some(p => p.includes('node_modules'));
|
|
148
|
+
if (!hasNodeModules) {
|
|
149
|
+
warnings.push({
|
|
150
|
+
path: `${path}.patterns.exclude`,
|
|
151
|
+
message: 'node_modules is not excluded',
|
|
152
|
+
suggestion: 'Add "**/node_modules/**" to exclude patterns',
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
return { valid: errors.length === 0, errors, warnings };
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Validate settings
|
|
161
|
+
*/
|
|
162
|
+
function validateSettings(settings) {
|
|
163
|
+
const errors = [];
|
|
164
|
+
const warnings = [];
|
|
165
|
+
// Validate chunk_size
|
|
166
|
+
if (typeof settings.chunk_size !== 'number') {
|
|
167
|
+
errors.push({
|
|
168
|
+
path: 'settings.chunk_size',
|
|
169
|
+
message: 'chunk_size must be a number',
|
|
170
|
+
suggestion: 'Set chunk_size: 500',
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
else if (settings.chunk_size < 50) {
|
|
174
|
+
warnings.push({
|
|
175
|
+
path: 'settings.chunk_size',
|
|
176
|
+
message: `chunk_size ${settings.chunk_size} is very small`,
|
|
177
|
+
suggestion: 'Recommended: 300-800 tokens',
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
else if (settings.chunk_size > 2000) {
|
|
181
|
+
warnings.push({
|
|
182
|
+
path: 'settings.chunk_size',
|
|
183
|
+
message: `chunk_size ${settings.chunk_size} is very large`,
|
|
184
|
+
suggestion: 'Recommended: 300-800 tokens',
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
// Validate chunk_overlap
|
|
188
|
+
if (typeof settings.chunk_overlap !== 'number') {
|
|
189
|
+
errors.push({
|
|
190
|
+
path: 'settings.chunk_overlap',
|
|
191
|
+
message: 'chunk_overlap must be a number',
|
|
192
|
+
suggestion: 'Set chunk_overlap: 50',
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
else if (settings.chunk_overlap < 0) {
|
|
196
|
+
errors.push({
|
|
197
|
+
path: 'settings.chunk_overlap',
|
|
198
|
+
message: 'chunk_overlap cannot be negative',
|
|
199
|
+
suggestion: 'Set chunk_overlap: 50',
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
else if (settings.chunk_overlap >= settings.chunk_size) {
|
|
203
|
+
errors.push({
|
|
204
|
+
path: 'settings.chunk_overlap',
|
|
205
|
+
message: 'chunk_overlap must be less than chunk_size',
|
|
206
|
+
suggestion: `Set chunk_overlap to less than ${settings.chunk_size}`,
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
return { valid: errors.length === 0, errors, warnings };
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Format validation results for display
|
|
213
|
+
*/
|
|
214
|
+
export function formatValidationResults(result) {
|
|
215
|
+
const lines = [];
|
|
216
|
+
if (result.errors.length > 0) {
|
|
217
|
+
lines.push('❌ Configuration Errors:');
|
|
218
|
+
for (const error of result.errors) {
|
|
219
|
+
lines.push(` • ${error.path}: ${error.message}`);
|
|
220
|
+
if (error.suggestion) {
|
|
221
|
+
lines.push(` → ${error.suggestion}`);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
if (result.warnings.length > 0) {
|
|
226
|
+
if (lines.length > 0)
|
|
227
|
+
lines.push('');
|
|
228
|
+
lines.push('⚠️ Warnings:');
|
|
229
|
+
for (const warning of result.warnings) {
|
|
230
|
+
lines.push(` • ${warning.path}: ${warning.message}`);
|
|
231
|
+
if (warning.suggestion) {
|
|
232
|
+
lines.push(` → ${warning.suggestion}`);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
if (result.valid && result.warnings.length === 0) {
|
|
237
|
+
lines.push('✅ Configuration is valid');
|
|
238
|
+
}
|
|
239
|
+
return lines.join('\n');
|
|
240
|
+
}
|
|
241
|
+
//# sourceMappingURL=validation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/config/validation.ts"],"names":[],"mappings":"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"}
|