@getmikk/ai-context 1.5.1 → 1.7.0
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 +5 -3
- package/package.json +3 -3
- package/src/claude-md-generator.ts +13 -5
- package/src/context-builder.ts +15 -5
package/README.md
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
# @getmikk/ai-context
|
|
2
2
|
|
|
3
|
-
>
|
|
3
|
+
> Token-budgeted, graph-traced AI context — the difference between an LLM that guesses your architecture and one that actually knows it.
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/@getmikk/ai-context)
|
|
6
6
|
[](../../LICENSE)
|
|
7
7
|
|
|
8
|
-
`@getmikk/ai-context` solves the
|
|
8
|
+
`@getmikk/ai-context` solves the AI context window problem at the architectural level. Instead of dumping your entire codebase into a prompt and hoping the LLM figures it out, it walks the dependency graph from task-relevant seed functions, scores every reachable function by relevance, and packs the highest-signal functions into a token budget — giving your AI exactly what it needs and nothing it doesn't.
|
|
9
9
|
|
|
10
|
-
It also generates
|
|
10
|
+
It also generates `claude.md` and `AGENTS.md` — tiered architecture summaries that let AI agents understand your entire project structure from a single file.
|
|
11
|
+
|
|
12
|
+
> Part of [Mikk](../../README.md) — the codebase nervous system for AI-assisted development.
|
|
11
13
|
|
|
12
14
|
---
|
|
13
15
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@getmikk/ai-context",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.0",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
"dev": "tsc --watch"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@getmikk/core": "^1.
|
|
25
|
-
"@getmikk/intent-engine": "^1.
|
|
24
|
+
"@getmikk/core": "^1.7.0",
|
|
25
|
+
"@getmikk/intent-engine": "^1.7.0"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"typescript": "^5.7.0",
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import type { MikkContract, MikkLock, MikkLockFunction } from '@getmikk/core'
|
|
2
|
+
import * as fs from 'node:fs'
|
|
3
|
+
import * as path from 'node:path'
|
|
2
4
|
|
|
3
5
|
/** Default token budget for claude.md — generous but still bounded */
|
|
4
6
|
const DEFAULT_TOKEN_BUDGET = 12000
|
|
@@ -33,7 +35,8 @@ export class ClaudeMdGenerator {
|
|
|
33
35
|
private contract: MikkContract,
|
|
34
36
|
private lock: MikkLock,
|
|
35
37
|
private tokenBudget: number = DEFAULT_TOKEN_BUDGET,
|
|
36
|
-
meta?: ProjectMeta
|
|
38
|
+
meta?: ProjectMeta,
|
|
39
|
+
private projectRoot?: string
|
|
37
40
|
) {
|
|
38
41
|
this.meta = meta || {}
|
|
39
42
|
}
|
|
@@ -324,13 +327,18 @@ export class ClaudeMdGenerator {
|
|
|
324
327
|
lines.push(`### \`${cf.path}\` (${cf.type})`)
|
|
325
328
|
lines.push('')
|
|
326
329
|
lines.push('```' + lang)
|
|
330
|
+
// Read content from disk on-demand
|
|
331
|
+
let content = ''
|
|
332
|
+
if (this.projectRoot) {
|
|
333
|
+
try { content = fs.readFileSync(path.resolve(this.projectRoot, cf.path), 'utf-8') } catch { }
|
|
334
|
+
}
|
|
327
335
|
// Trim content to avoid blowing up the token budget
|
|
328
336
|
const maxChars = 8000 // ~2000 tokens per file
|
|
329
|
-
if (
|
|
330
|
-
lines.push(
|
|
331
|
-
lines.push(`// ... truncated (${cf.size} bytes total)`)
|
|
337
|
+
if (content.length > maxChars) {
|
|
338
|
+
lines.push(content.slice(0, maxChars))
|
|
339
|
+
lines.push(`// ... truncated (${cf.size ?? content.length} bytes total)`)
|
|
332
340
|
} else {
|
|
333
|
-
lines.push(
|
|
341
|
+
lines.push(content.trimEnd())
|
|
334
342
|
}
|
|
335
343
|
lines.push('```')
|
|
336
344
|
lines.push('')
|
package/src/context-builder.ts
CHANGED
|
@@ -24,6 +24,15 @@ const WEIGHT = {
|
|
|
24
24
|
// Default token budget per context payload
|
|
25
25
|
const DEFAULT_TOKEN_BUDGET = 6000
|
|
26
26
|
|
|
27
|
+
function readContextFile(filePath: string, projectRoot?: string): string {
|
|
28
|
+
if (!projectRoot) return ''
|
|
29
|
+
try {
|
|
30
|
+
return fs.readFileSync(path.resolve(projectRoot, filePath), 'utf-8')
|
|
31
|
+
} catch {
|
|
32
|
+
return ''
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
27
36
|
/**
|
|
28
37
|
* Rough token estimator: 1 token ≈ 4 chars for code/identifiers
|
|
29
38
|
*/
|
|
@@ -305,7 +314,7 @@ export class ContextBuilder {
|
|
|
305
314
|
})),
|
|
306
315
|
contextFiles: this.lock.contextFiles?.map(cf => ({
|
|
307
316
|
path: cf.path,
|
|
308
|
-
content: cf.
|
|
317
|
+
content: readContextFile(cf.path, query.projectRoot),
|
|
309
318
|
type: cf.type,
|
|
310
319
|
})),
|
|
311
320
|
routes: this.lock.routes?.map(r => ({
|
|
@@ -433,11 +442,12 @@ export class ContextBuilder {
|
|
|
433
442
|
lines.push(`--- ${cf.path} (${cf.type}) ---`)
|
|
434
443
|
// Trim to ~2000 chars per file in prompt output
|
|
435
444
|
const maxChars = 2000
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
lines.push(
|
|
445
|
+
const cfContent = readContextFile(cf.path, query.projectRoot)
|
|
446
|
+
if (cfContent.length > maxChars) {
|
|
447
|
+
lines.push(cfContent.slice(0, maxChars))
|
|
448
|
+
lines.push(`... (truncated, ${cf.size ?? cfContent.length} bytes total)`)
|
|
439
449
|
} else {
|
|
440
|
-
lines.push(
|
|
450
|
+
lines.push(cfContent.trimEnd())
|
|
441
451
|
}
|
|
442
452
|
lines.push('')
|
|
443
453
|
}
|