@getmikk/ai-context 1.2.0 → 1.3.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 +327 -0
- package/package.json +31 -27
- package/src/claude-md-generator.ts +265 -265
- package/src/context-builder.ts +398 -398
- package/src/index.ts +4 -4
- package/src/providers.ts +154 -154
- package/src/types.ts +69 -69
- package/tests/claude-md.test.ts +137 -137
- package/tests/smoke.test.ts +5 -5
- package/tsconfig.json +15 -15
package/src/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { ContextBuilder } from './context-builder.js'
|
|
2
|
-
export { ClaudeMdGenerator } from './claude-md-generator.js'
|
|
3
|
-
export { ClaudeProvider, GenericProvider, getProvider } from './providers.js'
|
|
4
|
-
export type { AIContext, ContextModule, ContextFunction, ContextQuery, ContextProvider } from './types.js'
|
|
1
|
+
export { ContextBuilder } from './context-builder.js'
|
|
2
|
+
export { ClaudeMdGenerator } from './claude-md-generator.js'
|
|
3
|
+
export { ClaudeProvider, GenericProvider, getProvider } from './providers.js'
|
|
4
|
+
export type { AIContext, ContextModule, ContextFunction, ContextQuery, ContextProvider } from './types.js'
|
package/src/providers.ts
CHANGED
|
@@ -1,155 +1,155 @@
|
|
|
1
|
-
import type { AIContext, ContextProvider } from './types.js'
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* ClaudeProvider — formats context for Anthropic Claude models.
|
|
5
|
-
*
|
|
6
|
-
* Uses structured XML tags so Claude can parse boundaries clearly.
|
|
7
|
-
* Includes meta block so the model knows how much context was trimmed.
|
|
8
|
-
*/
|
|
9
|
-
export class ClaudeProvider implements ContextProvider {
|
|
10
|
-
name = 'claude'
|
|
11
|
-
maxTokens = 200000
|
|
12
|
-
|
|
13
|
-
formatContext(context: AIContext): string {
|
|
14
|
-
const lines: string[] = []
|
|
15
|
-
|
|
16
|
-
lines.push('<mikk_context>')
|
|
17
|
-
|
|
18
|
-
// ── Project ────────────────────────────────────────────────────────
|
|
19
|
-
lines.push(`<project name="${esc(context.project.name)}" language="${esc(context.project.language)}">`)
|
|
20
|
-
lines.push(` <description>${esc(context.project.description)}</description>`)
|
|
21
|
-
lines.push(` <stats modules="${context.project.moduleCount}" functions="${context.project.functionCount}"/>`)
|
|
22
|
-
lines.push('</project>')
|
|
23
|
-
lines.push('')
|
|
24
|
-
|
|
25
|
-
// ── Context quality meta ───────────────────────────────────────────
|
|
26
|
-
lines.push('<context_meta>')
|
|
27
|
-
lines.push(` <task>${esc(context.meta?.keywords?.join(', ') ?? '')}</task>`)
|
|
28
|
-
lines.push(` <seeds_found>${context.meta?.seedCount ?? 0}</seeds_found>`)
|
|
29
|
-
lines.push(` <functions_selected>${context.meta?.selectedFunctions ?? 0} of ${context.meta?.totalFunctionsConsidered ?? 0}</functions_selected>`)
|
|
30
|
-
lines.push(` <estimated_tokens>${context.meta?.estimatedTokens ?? 0}</estimated_tokens>`)
|
|
31
|
-
lines.push('</context_meta>')
|
|
32
|
-
lines.push('')
|
|
33
|
-
|
|
34
|
-
// ── Modules ────────────────────────────────────────────────────────
|
|
35
|
-
for (const mod of context.modules) {
|
|
36
|
-
lines.push(`<module id="${esc(mod.id)}" name="${esc(mod.name)}">`)
|
|
37
|
-
lines.push(` <description>${esc(mod.description)}</description>`)
|
|
38
|
-
if (mod.intent) lines.push(` <intent>${esc(mod.intent)}</intent>`)
|
|
39
|
-
lines.push(` <files count="${mod.files.length}">`)
|
|
40
|
-
for (const f of mod.files) {
|
|
41
|
-
lines.push(` <file>${esc(f)}</file>`)
|
|
42
|
-
}
|
|
43
|
-
lines.push(' </files>')
|
|
44
|
-
|
|
45
|
-
if (mod.functions.length > 0) {
|
|
46
|
-
lines.push(' <functions>')
|
|
47
|
-
for (const fn of mod.functions) {
|
|
48
|
-
const calls = fn.calls.length > 0
|
|
49
|
-
? ` calls="${esc(fn.calls.join(','))}"`
|
|
50
|
-
: ''
|
|
51
|
-
const calledBy = fn.calledBy.length > 0
|
|
52
|
-
? ` calledBy="${esc(fn.calledBy.join(','))}"`
|
|
53
|
-
: ''
|
|
54
|
-
lines.push(` <fn name="${esc(fn.name)}" file="${esc(fn.file)}" lines="${fn.startLine}-${fn.endLine}"${calls}${calledBy}>`)
|
|
55
|
-
if (fn.purpose) lines.push(` <purpose>${esc(fn.purpose)}</purpose>`)
|
|
56
|
-
if (fn.edgeCases && fn.edgeCases.length > 0) {
|
|
57
|
-
lines.push(` <edge_cases>${esc(fn.edgeCases.join('; '))}</edge_cases>`)
|
|
58
|
-
}
|
|
59
|
-
if (fn.errorHandling && fn.errorHandling.length > 0) {
|
|
60
|
-
lines.push(` <error_handling>${esc(fn.errorHandling.join('; '))}</error_handling>`)
|
|
61
|
-
}
|
|
62
|
-
lines.push(' </fn>')
|
|
63
|
-
}
|
|
64
|
-
lines.push(' </functions>')
|
|
65
|
-
}
|
|
66
|
-
lines.push('</module>')
|
|
67
|
-
lines.push('')
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
// ── Constraints ────────────────────────────────────────────────────
|
|
71
|
-
if (context.constraints.length > 0) {
|
|
72
|
-
lines.push('<constraints>')
|
|
73
|
-
for (const c of context.constraints) {
|
|
74
|
-
lines.push(` <constraint>${esc(c)}</constraint>`)
|
|
75
|
-
}
|
|
76
|
-
lines.push('</constraints>')
|
|
77
|
-
lines.push('')
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
// ── Decisions ─────────────────────────────────────────────────────
|
|
81
|
-
if (context.decisions.length > 0) {
|
|
82
|
-
lines.push('<architectural_decisions>')
|
|
83
|
-
for (const d of context.decisions) {
|
|
84
|
-
lines.push(` <decision title="${esc(d.title)}">${esc(d.reason)}</decision>`)
|
|
85
|
-
}
|
|
86
|
-
lines.push('</architectural_decisions>')
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
lines.push('</mikk_context>')
|
|
90
|
-
return lines.join('\n')
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* GenericProvider — clean plain-text format for any model.
|
|
96
|
-
* Identical to the natural-language prompt generated by ContextBuilder.
|
|
97
|
-
*/
|
|
98
|
-
export class GenericProvider implements ContextProvider {
|
|
99
|
-
name = 'generic'
|
|
100
|
-
maxTokens = 128000
|
|
101
|
-
|
|
102
|
-
formatContext(context: AIContext): string {
|
|
103
|
-
return context.prompt
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
* CompactProvider — ultra-minimal format for small context windows.
|
|
109
|
-
* One line per function, no XML, no prose.
|
|
110
|
-
*/
|
|
111
|
-
export class CompactProvider implements ContextProvider {
|
|
112
|
-
name = 'compact'
|
|
113
|
-
maxTokens = 16000
|
|
114
|
-
|
|
115
|
-
formatContext(context: AIContext): string {
|
|
116
|
-
const lines: string[] = [
|
|
117
|
-
`# ${context.project.name} (${context.project.language})`,
|
|
118
|
-
`Task keywords: ${context.meta?.keywords?.join(', ') ?? ''}`,
|
|
119
|
-
'',
|
|
120
|
-
]
|
|
121
|
-
for (const mod of context.modules) {
|
|
122
|
-
lines.push(`## ${mod.name}`)
|
|
123
|
-
for (const fn of mod.functions) {
|
|
124
|
-
const calls = fn.calls.length > 0 ? ` → ${fn.calls.join(',')}` : ''
|
|
125
|
-
lines.push(` ${fn.name} [${fn.file}:${fn.startLine}]${calls}`)
|
|
126
|
-
}
|
|
127
|
-
lines.push('')
|
|
128
|
-
}
|
|
129
|
-
if (context.constraints.length > 0) {
|
|
130
|
-
lines.push('CONSTRAINTS: ' + context.constraints.join(' | '))
|
|
131
|
-
}
|
|
132
|
-
return lines.join('\n')
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
export function getProvider(name: string): ContextProvider {
|
|
137
|
-
switch (name.toLowerCase()) {
|
|
138
|
-
case 'claude':
|
|
139
|
-
case 'anthropic':
|
|
140
|
-
return new ClaudeProvider()
|
|
141
|
-
case 'compact':
|
|
142
|
-
return new CompactProvider()
|
|
143
|
-
default:
|
|
144
|
-
return new GenericProvider()
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
/** Minimal XML attribute escaping */
|
|
149
|
-
function esc(s: string): string {
|
|
150
|
-
return s
|
|
151
|
-
.replace(/&/g, '&')
|
|
152
|
-
.replace(/</g, '<')
|
|
153
|
-
.replace(/>/g, '>')
|
|
154
|
-
.replace(/"/g, '"')
|
|
1
|
+
import type { AIContext, ContextProvider } from './types.js'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* ClaudeProvider — formats context for Anthropic Claude models.
|
|
5
|
+
*
|
|
6
|
+
* Uses structured XML tags so Claude can parse boundaries clearly.
|
|
7
|
+
* Includes meta block so the model knows how much context was trimmed.
|
|
8
|
+
*/
|
|
9
|
+
export class ClaudeProvider implements ContextProvider {
|
|
10
|
+
name = 'claude'
|
|
11
|
+
maxTokens = 200000
|
|
12
|
+
|
|
13
|
+
formatContext(context: AIContext): string {
|
|
14
|
+
const lines: string[] = []
|
|
15
|
+
|
|
16
|
+
lines.push('<mikk_context>')
|
|
17
|
+
|
|
18
|
+
// ── Project ────────────────────────────────────────────────────────
|
|
19
|
+
lines.push(`<project name="${esc(context.project.name)}" language="${esc(context.project.language)}">`)
|
|
20
|
+
lines.push(` <description>${esc(context.project.description)}</description>`)
|
|
21
|
+
lines.push(` <stats modules="${context.project.moduleCount}" functions="${context.project.functionCount}"/>`)
|
|
22
|
+
lines.push('</project>')
|
|
23
|
+
lines.push('')
|
|
24
|
+
|
|
25
|
+
// ── Context quality meta ───────────────────────────────────────────
|
|
26
|
+
lines.push('<context_meta>')
|
|
27
|
+
lines.push(` <task>${esc(context.meta?.keywords?.join(', ') ?? '')}</task>`)
|
|
28
|
+
lines.push(` <seeds_found>${context.meta?.seedCount ?? 0}</seeds_found>`)
|
|
29
|
+
lines.push(` <functions_selected>${context.meta?.selectedFunctions ?? 0} of ${context.meta?.totalFunctionsConsidered ?? 0}</functions_selected>`)
|
|
30
|
+
lines.push(` <estimated_tokens>${context.meta?.estimatedTokens ?? 0}</estimated_tokens>`)
|
|
31
|
+
lines.push('</context_meta>')
|
|
32
|
+
lines.push('')
|
|
33
|
+
|
|
34
|
+
// ── Modules ────────────────────────────────────────────────────────
|
|
35
|
+
for (const mod of context.modules) {
|
|
36
|
+
lines.push(`<module id="${esc(mod.id)}" name="${esc(mod.name)}">`)
|
|
37
|
+
lines.push(` <description>${esc(mod.description)}</description>`)
|
|
38
|
+
if (mod.intent) lines.push(` <intent>${esc(mod.intent)}</intent>`)
|
|
39
|
+
lines.push(` <files count="${mod.files.length}">`)
|
|
40
|
+
for (const f of mod.files) {
|
|
41
|
+
lines.push(` <file>${esc(f)}</file>`)
|
|
42
|
+
}
|
|
43
|
+
lines.push(' </files>')
|
|
44
|
+
|
|
45
|
+
if (mod.functions.length > 0) {
|
|
46
|
+
lines.push(' <functions>')
|
|
47
|
+
for (const fn of mod.functions) {
|
|
48
|
+
const calls = fn.calls.length > 0
|
|
49
|
+
? ` calls="${esc(fn.calls.join(','))}"`
|
|
50
|
+
: ''
|
|
51
|
+
const calledBy = fn.calledBy.length > 0
|
|
52
|
+
? ` calledBy="${esc(fn.calledBy.join(','))}"`
|
|
53
|
+
: ''
|
|
54
|
+
lines.push(` <fn name="${esc(fn.name)}" file="${esc(fn.file)}" lines="${fn.startLine}-${fn.endLine}"${calls}${calledBy}>`)
|
|
55
|
+
if (fn.purpose) lines.push(` <purpose>${esc(fn.purpose)}</purpose>`)
|
|
56
|
+
if (fn.edgeCases && fn.edgeCases.length > 0) {
|
|
57
|
+
lines.push(` <edge_cases>${esc(fn.edgeCases.join('; '))}</edge_cases>`)
|
|
58
|
+
}
|
|
59
|
+
if (fn.errorHandling && fn.errorHandling.length > 0) {
|
|
60
|
+
lines.push(` <error_handling>${esc(fn.errorHandling.join('; '))}</error_handling>`)
|
|
61
|
+
}
|
|
62
|
+
lines.push(' </fn>')
|
|
63
|
+
}
|
|
64
|
+
lines.push(' </functions>')
|
|
65
|
+
}
|
|
66
|
+
lines.push('</module>')
|
|
67
|
+
lines.push('')
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// ── Constraints ────────────────────────────────────────────────────
|
|
71
|
+
if (context.constraints.length > 0) {
|
|
72
|
+
lines.push('<constraints>')
|
|
73
|
+
for (const c of context.constraints) {
|
|
74
|
+
lines.push(` <constraint>${esc(c)}</constraint>`)
|
|
75
|
+
}
|
|
76
|
+
lines.push('</constraints>')
|
|
77
|
+
lines.push('')
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// ── Decisions ─────────────────────────────────────────────────────
|
|
81
|
+
if (context.decisions.length > 0) {
|
|
82
|
+
lines.push('<architectural_decisions>')
|
|
83
|
+
for (const d of context.decisions) {
|
|
84
|
+
lines.push(` <decision title="${esc(d.title)}">${esc(d.reason)}</decision>`)
|
|
85
|
+
}
|
|
86
|
+
lines.push('</architectural_decisions>')
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
lines.push('</mikk_context>')
|
|
90
|
+
return lines.join('\n')
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* GenericProvider — clean plain-text format for any model.
|
|
96
|
+
* Identical to the natural-language prompt generated by ContextBuilder.
|
|
97
|
+
*/
|
|
98
|
+
export class GenericProvider implements ContextProvider {
|
|
99
|
+
name = 'generic'
|
|
100
|
+
maxTokens = 128000
|
|
101
|
+
|
|
102
|
+
formatContext(context: AIContext): string {
|
|
103
|
+
return context.prompt
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* CompactProvider — ultra-minimal format for small context windows.
|
|
109
|
+
* One line per function, no XML, no prose.
|
|
110
|
+
*/
|
|
111
|
+
export class CompactProvider implements ContextProvider {
|
|
112
|
+
name = 'compact'
|
|
113
|
+
maxTokens = 16000
|
|
114
|
+
|
|
115
|
+
formatContext(context: AIContext): string {
|
|
116
|
+
const lines: string[] = [
|
|
117
|
+
`# ${context.project.name} (${context.project.language})`,
|
|
118
|
+
`Task keywords: ${context.meta?.keywords?.join(', ') ?? ''}`,
|
|
119
|
+
'',
|
|
120
|
+
]
|
|
121
|
+
for (const mod of context.modules) {
|
|
122
|
+
lines.push(`## ${mod.name}`)
|
|
123
|
+
for (const fn of mod.functions) {
|
|
124
|
+
const calls = fn.calls.length > 0 ? ` → ${fn.calls.join(',')}` : ''
|
|
125
|
+
lines.push(` ${fn.name} [${fn.file}:${fn.startLine}]${calls}`)
|
|
126
|
+
}
|
|
127
|
+
lines.push('')
|
|
128
|
+
}
|
|
129
|
+
if (context.constraints.length > 0) {
|
|
130
|
+
lines.push('CONSTRAINTS: ' + context.constraints.join(' | '))
|
|
131
|
+
}
|
|
132
|
+
return lines.join('\n')
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export function getProvider(name: string): ContextProvider {
|
|
137
|
+
switch (name.toLowerCase()) {
|
|
138
|
+
case 'claude':
|
|
139
|
+
case 'anthropic':
|
|
140
|
+
return new ClaudeProvider()
|
|
141
|
+
case 'compact':
|
|
142
|
+
return new CompactProvider()
|
|
143
|
+
default:
|
|
144
|
+
return new GenericProvider()
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/** Minimal XML attribute escaping */
|
|
149
|
+
function esc(s: string): string {
|
|
150
|
+
return s
|
|
151
|
+
.replace(/&/g, '&')
|
|
152
|
+
.replace(/</g, '<')
|
|
153
|
+
.replace(/>/g, '>')
|
|
154
|
+
.replace(/"/g, '"')
|
|
155
155
|
}
|
package/src/types.ts
CHANGED
|
@@ -1,70 +1,70 @@
|
|
|
1
|
-
import type { MikkContract, MikkLock, MikkLockFunction } from '@getmikk/core'
|
|
2
|
-
|
|
3
|
-
/** The structured context object passed to AI models */
|
|
4
|
-
export interface AIContext {
|
|
5
|
-
project: {
|
|
6
|
-
name: string
|
|
7
|
-
language: string
|
|
8
|
-
description: string
|
|
9
|
-
moduleCount: number
|
|
10
|
-
functionCount: number
|
|
11
|
-
}
|
|
12
|
-
modules: ContextModule[]
|
|
13
|
-
constraints: string[]
|
|
14
|
-
decisions: { title: string; reason: string }[]
|
|
15
|
-
prompt: string
|
|
16
|
-
/** Diagnostic info — helpful for debugging context quality */
|
|
17
|
-
meta: {
|
|
18
|
-
seedCount: number
|
|
19
|
-
totalFunctionsConsidered: number
|
|
20
|
-
selectedFunctions: number
|
|
21
|
-
estimatedTokens: number
|
|
22
|
-
keywords: string[]
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export interface ContextModule {
|
|
27
|
-
id: string
|
|
28
|
-
name: string
|
|
29
|
-
description: string
|
|
30
|
-
intent?: string
|
|
31
|
-
functions: ContextFunction[]
|
|
32
|
-
files: string[]
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export interface ContextFunction {
|
|
36
|
-
name: string
|
|
37
|
-
file: string
|
|
38
|
-
startLine: number
|
|
39
|
-
endLine: number
|
|
40
|
-
calls: string[]
|
|
41
|
-
calledBy: string[]
|
|
42
|
-
purpose?: string
|
|
43
|
-
errorHandling?: string[]
|
|
44
|
-
edgeCases?: string[]
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/** Query options for context generation */
|
|
48
|
-
export interface ContextQuery {
|
|
49
|
-
/** The user's task description — the primary relevance signal */
|
|
50
|
-
task: string
|
|
51
|
-
/** Specific files to anchor the graph traversal from */
|
|
52
|
-
focusFiles?: string[]
|
|
53
|
-
/** Specific modules to include */
|
|
54
|
-
focusModules?: string[]
|
|
55
|
-
/** Max functions to include in output (hard cap) */
|
|
56
|
-
maxFunctions?: number
|
|
57
|
-
/** Max BFS hops from seed nodes (default 4) */
|
|
58
|
-
maxHops?: number
|
|
59
|
-
/** Approximate token budget for function listings (default 6000) */
|
|
60
|
-
tokenBudget?: number
|
|
61
|
-
/** Include call graph arrows (default true) */
|
|
62
|
-
includeCallGraph?: boolean
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/** Context provider interface for different AI platforms */
|
|
66
|
-
export interface ContextProvider {
|
|
67
|
-
name: string
|
|
68
|
-
formatContext(context: AIContext): string
|
|
69
|
-
maxTokens: number
|
|
1
|
+
import type { MikkContract, MikkLock, MikkLockFunction } from '@getmikk/core'
|
|
2
|
+
|
|
3
|
+
/** The structured context object passed to AI models */
|
|
4
|
+
export interface AIContext {
|
|
5
|
+
project: {
|
|
6
|
+
name: string
|
|
7
|
+
language: string
|
|
8
|
+
description: string
|
|
9
|
+
moduleCount: number
|
|
10
|
+
functionCount: number
|
|
11
|
+
}
|
|
12
|
+
modules: ContextModule[]
|
|
13
|
+
constraints: string[]
|
|
14
|
+
decisions: { title: string; reason: string }[]
|
|
15
|
+
prompt: string
|
|
16
|
+
/** Diagnostic info — helpful for debugging context quality */
|
|
17
|
+
meta: {
|
|
18
|
+
seedCount: number
|
|
19
|
+
totalFunctionsConsidered: number
|
|
20
|
+
selectedFunctions: number
|
|
21
|
+
estimatedTokens: number
|
|
22
|
+
keywords: string[]
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface ContextModule {
|
|
27
|
+
id: string
|
|
28
|
+
name: string
|
|
29
|
+
description: string
|
|
30
|
+
intent?: string
|
|
31
|
+
functions: ContextFunction[]
|
|
32
|
+
files: string[]
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface ContextFunction {
|
|
36
|
+
name: string
|
|
37
|
+
file: string
|
|
38
|
+
startLine: number
|
|
39
|
+
endLine: number
|
|
40
|
+
calls: string[]
|
|
41
|
+
calledBy: string[]
|
|
42
|
+
purpose?: string
|
|
43
|
+
errorHandling?: string[]
|
|
44
|
+
edgeCases?: string[]
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** Query options for context generation */
|
|
48
|
+
export interface ContextQuery {
|
|
49
|
+
/** The user's task description — the primary relevance signal */
|
|
50
|
+
task: string
|
|
51
|
+
/** Specific files to anchor the graph traversal from */
|
|
52
|
+
focusFiles?: string[]
|
|
53
|
+
/** Specific modules to include */
|
|
54
|
+
focusModules?: string[]
|
|
55
|
+
/** Max functions to include in output (hard cap) */
|
|
56
|
+
maxFunctions?: number
|
|
57
|
+
/** Max BFS hops from seed nodes (default 4) */
|
|
58
|
+
maxHops?: number
|
|
59
|
+
/** Approximate token budget for function listings (default 6000) */
|
|
60
|
+
tokenBudget?: number
|
|
61
|
+
/** Include call graph arrows (default true) */
|
|
62
|
+
includeCallGraph?: boolean
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** Context provider interface for different AI platforms */
|
|
66
|
+
export interface ContextProvider {
|
|
67
|
+
name: string
|
|
68
|
+
formatContext(context: AIContext): string
|
|
69
|
+
maxTokens: number
|
|
70
70
|
}
|