ctxman 3.0.0 → 3.1.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/.ctxman/llm-profiles.json +1067 -39
- package/.ctxman/profiles/backend-team.json +13 -0
- package/.ctxman/profiles/default.json +12 -0
- package/.ctxman/profiles/devops-team.json +21 -0
- package/.ctxman/profiles/frontend-team.json +20 -0
- package/.ctxman/templates/bug-fix.json +17 -0
- package/.ctxman/templates/code-review.json +9 -0
- package/.ctxman/templates/documentation.json +9 -0
- package/.ctxman/templates/feature.json +9 -0
- package/.ctxman/templates/full-context.json +9 -0
- package/.ctxman/templates/refactoring.json +18 -0
- package/.ctxman/templates/testing.json +9 -0
- package/.ctxman/wizard-profiles/security-audit/profile.json +7 -1
- package/LICENSE +21 -0
- package/README.md +380 -136
- package/bin/cli.js +1880 -529
- package/bin/cm-ask.js +18 -13
- package/bin/cm-audit.js +124 -0
- package/bin/cm-count.js +151 -0
- package/bin/cm-gitingest.js +128 -115
- package/bin/cm-map.js +242 -0
- package/bin/cm-mcp.js +293 -0
- package/bin/cm-pack.js +405 -0
- package/bin/cm-policy.js +170 -0
- package/bin/cm-pr.js +248 -0
- package/bin/cm-search.js +178 -0
- package/bin/cm-update.js +128 -128
- package/bin/cm-why.js +197 -0
- package/bin/mcp-server.js +8 -24
- package/ctxman.js +237 -183
- package/examples/README.md +19 -4
- package/examples/github-actions/ctxman-check.yml +49 -0
- package/examples/wizard-profiles/security-audit/profile.json +7 -1
- package/index.d.ts +1422 -0
- package/index.js +55 -31
- package/lib/agents/pr-failure-agent.js +48 -45
- package/lib/analyzers/ai-suggester.js +451 -0
- package/lib/analyzers/dependency-scanner.js +505 -0
- package/lib/analyzers/duplicate-detector.js +264 -0
- package/lib/analyzers/go-method-analyzer.js +151 -110
- package/lib/analyzers/import-tracker.js +431 -0
- package/lib/analyzers/method-analyzer.js +1055 -434
- package/lib/analyzers/performance-dashboard.js +683 -0
- package/lib/analyzers/token-calculator.js +895 -504
- package/lib/analyzers/unused-exports-detector.js +336 -0
- package/lib/api/mcp/install.js +424 -0
- package/lib/api/mcp/prompts.js +281 -281
- package/lib/api/mcp/resources.js +300 -241
- package/lib/api/mcp/sandbox.js +89 -0
- package/lib/api/mcp/server.js +675 -312
- package/lib/api/mcp/start.js +125 -0
- package/lib/api/mcp/transports/HttpSseTransport.js +60 -52
- package/lib/api/rest/server.js +105 -28
- package/lib/cache/CacheManager.js +9 -17
- package/lib/core/Analyzer.js +16 -10
- package/lib/core/ContextBuilder.js +19 -28
- package/lib/core/Reporter.js +15 -14
- package/lib/core/Scanner.js +81 -12
- package/lib/count/index.js +100 -0
- package/lib/formatters/format-registry.js +394 -372
- package/lib/formatters/gitingest-formatter.js +656 -621
- package/lib/formatters/toon-formatter-v1.3.js +637 -632
- package/lib/formatters/toon-formatter.js +239 -240
- package/lib/integrations/git/BlameTracker.js +4 -4
- package/lib/integrations/git/DiffAnalyzer.js +38 -31
- package/lib/integrations/git/GitClient.js +71 -53
- package/lib/lsp/server.js +311 -0
- package/lib/map/graph.js +299 -0
- package/lib/map/imports.js +233 -0
- package/lib/map/index.js +33 -0
- package/lib/map/rank.js +253 -0
- package/lib/map/render.js +346 -0
- package/lib/map/resolver.js +574 -0
- package/lib/pack/budget.js +111 -0
- package/lib/pack/code-lexer.js +360 -0
- package/lib/pack/compress.js +414 -0
- package/lib/pack/index.js +354 -0
- package/lib/pack/renderers/common.js +134 -0
- package/lib/pack/renderers/index.js +24 -0
- package/lib/pack/renderers/json.js +47 -0
- package/lib/pack/renderers/markdown.js +54 -0
- package/lib/pack/renderers/plain.js +38 -0
- package/lib/pack/renderers/xml.js +85 -0
- package/lib/pack/select.js +177 -0
- package/lib/pack/split.js +182 -0
- package/lib/pack/tree.js +35 -0
- package/lib/parsers/gitignore-parser.js +113 -107
- package/lib/parsers/method-filter-parser.js +50 -33
- package/lib/plugins/ExporterPlugin.js +3 -3
- package/lib/plugins/LanguagePlugin.js +3 -3
- package/lib/plugins/PluginManager.js +7 -13
- package/lib/policy/audit.js +294 -0
- package/lib/policy/enforce.js +125 -0
- package/lib/policy/ignore-files.js +169 -0
- package/lib/policy/index.js +52 -0
- package/lib/policy/policy.js +489 -0
- package/lib/pr/diff-parser.js +267 -0
- package/lib/pr/method-mapper.js +148 -0
- package/lib/pr/pr-context.js +829 -0
- package/lib/pr/pr-git.js +149 -0
- package/lib/pr/pr-renderer.js +644 -0
- package/lib/pr/related-tests.js +296 -0
- package/lib/rag/DataSourcePlugin.js +5 -5
- package/lib/rag/EmbeddingProvider.js +19 -8
- package/lib/rag/Indexer.js +14 -5
- package/lib/rag/VectorStoreFactory.js +3 -3
- package/lib/rag/sources/FileDataSource.js +6 -6
- package/lib/rag/stores/BaseVectorStore.js +5 -5
- package/lib/rag/stores/ChromaDBStore.js +10 -10
- package/lib/rag/stores/LanceDBStore.js +29 -19
- package/lib/rag/stores/PineconeStore.js +11 -9
- package/lib/search/bm25.js +433 -0
- package/lib/search/code-units.js +201 -0
- package/lib/search/symbols.js +189 -0
- package/lib/ui/dashboard.js +120 -89
- package/lib/ui/index.js +1 -6
- package/lib/ui/init-wizard-ui.js +550 -0
- package/lib/ui/progress-bar.js +94 -88
- package/lib/ui/select-input.js +40 -32
- package/lib/ui/template-selector.js +99 -0
- package/lib/ui/wizard.js +374 -329
- package/lib/utils/claude-token-counter.js +151 -0
- package/lib/utils/cli-output.js +17 -0
- package/lib/utils/clipboard-utils.js +49 -50
- package/lib/utils/config-utils.js +81 -66
- package/lib/utils/context-versioning.js +532 -0
- package/lib/utils/error-handler.js +112 -112
- package/lib/utils/file-utils.js +153 -69
- package/lib/utils/format-converter.js +356 -283
- package/lib/utils/git-utils.js +366 -294
- package/lib/utils/llm-cost-estimator.js +281 -0
- package/lib/utils/llm-detector.js +242 -78
- package/lib/utils/logger.js +243 -237
- package/lib/utils/messages.js +355 -0
- package/lib/utils/multi-repo-manager.js +364 -0
- package/lib/utils/profile-manager.js +380 -0
- package/lib/utils/safe-read.js +61 -0
- package/lib/utils/secret-redactor.js +61 -0
- package/lib/utils/snapshot-manager.js +679 -0
- package/lib/utils/template-manager.js +378 -0
- package/lib/utils/token-utils.js +201 -170
- package/lib/utils/tokenizer-adapter.js +421 -377
- package/lib/utils/updater.js +539 -506
- package/lib/watch/FileWatcher.js +12 -8
- package/lib/watch/IncrementalAnalyzer.js +7 -7
- package/lib/why/coupling.js +81 -0
- package/lib/why/errors.js +23 -0
- package/lib/why/git.js +169 -0
- package/lib/why/history.js +108 -0
- package/lib/why/index.js +720 -0
- package/lib/why/ownership.js +79 -0
- package/lib/why/paths.js +207 -0
- package/lib/why/references.js +259 -0
- package/lib/why/render.js +722 -0
- package/lib/why/search.js +358 -0
- package/lib/why/target.js +389 -0
- package/lib/wizards/config-generator.js +255 -0
- package/lib/wizards/project-detector.js +571 -0
- package/package.json +44 -10
- package/.ctxman/logs/ctxman-2026-07-02.log +0 -156
- package/.ctxman/self-knowledge/documents.lance/_transactions/0-b3dd1558-f95b-44b9-a154-18e8c330ae7a.txn +0 -0
- package/.ctxman/self-knowledge/documents.lance/_transactions/1-44bff6d4-e552-4010-a769-e09ad822698d.txn +0 -0
- package/.ctxman/self-knowledge/documents.lance/_transactions/10-37260794-5947-4ecb-b4c8-d732f58f40f1.txn +0 -0
- package/.ctxman/self-knowledge/documents.lance/_transactions/11-0d52a883-5518-463c-9b6d-986c3af89dfd.txn +0 -0
- package/.ctxman/self-knowledge/documents.lance/_transactions/12-ae354646-52f2-49c9-90fb-2e6ed8932663.txn +0 -0
- package/.ctxman/self-knowledge/documents.lance/_transactions/13-5d7d5e57-27da-498b-b734-091b9d38da13.txn +0 -0
- package/.ctxman/self-knowledge/documents.lance/_transactions/14-558ce928-810b-4252-a364-fdd1ee6f8a25.txn +0 -0
- package/.ctxman/self-knowledge/documents.lance/_transactions/15-27e3a58f-8b64-43b8-a9f4-e3369446968b.txn +0 -0
- package/.ctxman/self-knowledge/documents.lance/_transactions/16-a110c390-e5c8-4464-b976-bc7f5195fa15.txn +0 -0
- package/.ctxman/self-knowledge/documents.lance/_transactions/17-97513225-53de-4216-b61a-6337bd0cc4ad.txn +0 -0
- package/.ctxman/self-knowledge/documents.lance/_transactions/18-5ba450f0-c527-459c-bf4f-6d79b5e4285f.txn +0 -0
- package/.ctxman/self-knowledge/documents.lance/_transactions/19-600d3a63-5225-49e9-b8b7-30e037b564ab.txn +0 -0
- package/.ctxman/self-knowledge/documents.lance/_transactions/2-48a61b4e-92cf-4342-8376-914c1b99a9f9.txn +0 -0
- package/.ctxman/self-knowledge/documents.lance/_transactions/20-121dd912-5410-410e-84ff-82c7a23604a0.txn +0 -0
- package/.ctxman/self-knowledge/documents.lance/_transactions/3-bc6844ab-7ea3-4bb3-9ee1-538ce5664a9c.txn +0 -0
- package/.ctxman/self-knowledge/documents.lance/_transactions/4-d5e1754f-dbb5-454e-a9be-2a7da8d7bcf9.txn +0 -0
- package/.ctxman/self-knowledge/documents.lance/_transactions/5-4fae93df-0568-4b6f-8acf-8bef4bba6047.txn +0 -0
- package/.ctxman/self-knowledge/documents.lance/_transactions/6-4b1b8b87-068e-49a3-ba2b-d8dae628b252.txn +0 -0
- package/.ctxman/self-knowledge/documents.lance/_transactions/7-63d040fb-d2fa-4c0f-bed0-53411918a7b0.txn +0 -0
- package/.ctxman/self-knowledge/documents.lance/_transactions/8-c5628cf6-264c-420f-aab8-bc96a9083591.txn +0 -0
- package/.ctxman/self-knowledge/documents.lance/_transactions/9-c94570aa-5e53-4fcb-971f-cecc1d1d5492.txn +0 -0
- package/.ctxman/self-knowledge/documents.lance/_versions/1.manifest +0 -0
- package/.ctxman/self-knowledge/documents.lance/_versions/10.manifest +0 -0
- package/.ctxman/self-knowledge/documents.lance/_versions/11.manifest +0 -0
- package/.ctxman/self-knowledge/documents.lance/_versions/12.manifest +0 -0
- package/.ctxman/self-knowledge/documents.lance/_versions/13.manifest +0 -0
- package/.ctxman/self-knowledge/documents.lance/_versions/14.manifest +0 -0
- package/.ctxman/self-knowledge/documents.lance/_versions/15.manifest +0 -0
- package/.ctxman/self-knowledge/documents.lance/_versions/16.manifest +0 -0
- package/.ctxman/self-knowledge/documents.lance/_versions/17.manifest +0 -0
- package/.ctxman/self-knowledge/documents.lance/_versions/18.manifest +0 -0
- package/.ctxman/self-knowledge/documents.lance/_versions/19.manifest +0 -0
- package/.ctxman/self-knowledge/documents.lance/_versions/2.manifest +0 -0
- package/.ctxman/self-knowledge/documents.lance/_versions/20.manifest +0 -0
- package/.ctxman/self-knowledge/documents.lance/_versions/21.manifest +0 -0
- package/.ctxman/self-knowledge/documents.lance/_versions/3.manifest +0 -0
- package/.ctxman/self-knowledge/documents.lance/_versions/4.manifest +0 -0
- package/.ctxman/self-knowledge/documents.lance/_versions/5.manifest +0 -0
- package/.ctxman/self-knowledge/documents.lance/_versions/6.manifest +0 -0
- package/.ctxman/self-knowledge/documents.lance/_versions/7.manifest +0 -0
- package/.ctxman/self-knowledge/documents.lance/_versions/8.manifest +0 -0
- package/.ctxman/self-knowledge/documents.lance/_versions/9.manifest +0 -0
- package/.ctxman/self-knowledge/documents.lance/data/000010010011011101000010de8621405d9d5cb06540dbf02c.lance +0 -0
- package/.ctxman/self-knowledge/documents.lance/data/0000101001011100011000003fb62a4aa8978974075c144f1c.lance +0 -0
- package/.ctxman/self-knowledge/documents.lance/data/000011010000100111001011c6cc824d628f3bb1f4e04cd5d0.lance +0 -0
- package/.ctxman/self-knowledge/documents.lance/data/001000001000011001011100d8f74349ada090b332cd1df669.lance +0 -0
- package/.ctxman/self-knowledge/documents.lance/data/01000001111010001000010045ab44467bb1e7e4d8ae06bd58.lance +0 -0
- package/.ctxman/self-knowledge/documents.lance/data/01000101101110111110011131ef904241a89e1ffb6ddaf8e3.lance +0 -0
- package/.ctxman/self-knowledge/documents.lance/data/010010110000010000011010fbfcc145c6a8a827b28057a07e.lance +0 -0
- package/.ctxman/self-knowledge/documents.lance/data/1000011000101010001110003fb4f045c3835982efa1405324.lance +0 -0
- package/.ctxman/self-knowledge/documents.lance/data/100111011101110111101011f4396b410fa06af3b028d204e6.lance +0 -0
- package/.ctxman/self-knowledge/documents.lance/data/100111100111101000001100596b174e00995d6cc2969cc8dc.lance +0 -0
- package/.ctxman/self-knowledge/documents.lance/data/1010001100011000110010102ea16b484d887c7c9725feffd6.lance +0 -0
- package/.ctxman/self-knowledge/documents.lance/data/101101100010101111110111c5230944d9b3af7301b6392dda.lance +0 -0
- package/.ctxman/self-knowledge/documents.lance/data/1011011100100111111110105892bf41b5a530fedd7cf516f1.lance +0 -0
- package/.ctxman/self-knowledge/documents.lance/data/10111110000010001011110164e8774742bade87b483c10f36.lance +0 -0
- package/.ctxman/self-knowledge/documents.lance/data/1100000100010110001110103ffaca40a2a42c85067ebaf9ae.lance +0 -0
- package/.ctxman/self-knowledge/documents.lance/data/110000010001110110101110664bde4c76a78dfc14b05e83b8.lance +0 -0
- package/.ctxman/self-knowledge/documents.lance/data/11001100111000010100110050645c4281b1f35b2022234f7f.lance +0 -0
- package/.ctxman/self-knowledge/documents.lance/data/1101111011001100110111017214924a368f5719eab2246619.lance +0 -0
- package/.ctxman/self-knowledge/documents.lance/data/1110000111001010001000002150c24dcab653d39d07032e63.lance +0 -0
- package/.ctxman/self-knowledge/documents.lance/data/1110100000000100000011014d20534967a18b5c87721659ff.lance +0 -0
- package/.ctxman/self-knowledge/documents.lance/data/11110101111010000101011135a0114ef2b35dc6f1297a3381.lance +0 -0
package/index.d.ts
ADDED
|
@@ -0,0 +1,1422 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ctxman - AI Development Platform
|
|
3
|
+
* TypeScript definitions for programmatic API
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// ============================================
|
|
7
|
+
// Analyzers
|
|
8
|
+
// ============================================
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Token Calculator Options
|
|
12
|
+
*/
|
|
13
|
+
export interface TokenCalculatorOptions {
|
|
14
|
+
verbose?: boolean;
|
|
15
|
+
compactContext?: boolean;
|
|
16
|
+
methodLevel?: boolean;
|
|
17
|
+
saveReport?: boolean;
|
|
18
|
+
contextExport?: boolean;
|
|
19
|
+
contextToClipboard?: boolean;
|
|
20
|
+
gitingest?: boolean;
|
|
21
|
+
targetModel?: string;
|
|
22
|
+
dashboard?: boolean;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* File analysis result
|
|
27
|
+
*/
|
|
28
|
+
export interface FileInfo {
|
|
29
|
+
path: string;
|
|
30
|
+
relativePath: string;
|
|
31
|
+
sizeBytes: number;
|
|
32
|
+
tokens: number;
|
|
33
|
+
lines: number;
|
|
34
|
+
extension: string;
|
|
35
|
+
error?: string;
|
|
36
|
+
methods?: MethodInfo[];
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Method information
|
|
41
|
+
*/
|
|
42
|
+
export interface MethodInfo {
|
|
43
|
+
name: string;
|
|
44
|
+
line: number;
|
|
45
|
+
file: string;
|
|
46
|
+
tokens?: number;
|
|
47
|
+
content?: string;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Extension statistics
|
|
52
|
+
*/
|
|
53
|
+
export interface ExtensionStats {
|
|
54
|
+
count: number;
|
|
55
|
+
tokens: number;
|
|
56
|
+
bytes: number;
|
|
57
|
+
lines: number;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Directory statistics
|
|
62
|
+
*/
|
|
63
|
+
export interface DirectoryStats {
|
|
64
|
+
count: number;
|
|
65
|
+
tokens: number;
|
|
66
|
+
bytes: number;
|
|
67
|
+
lines: number;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Analysis statistics
|
|
72
|
+
*/
|
|
73
|
+
export interface AnalysisStats {
|
|
74
|
+
totalFiles: number;
|
|
75
|
+
totalTokens: number;
|
|
76
|
+
totalBytes: number;
|
|
77
|
+
totalLines: number;
|
|
78
|
+
ignoredFiles: number;
|
|
79
|
+
calculatorIgnoredFiles: number;
|
|
80
|
+
byExtension: Record<string, ExtensionStats>;
|
|
81
|
+
byDirectory: Record<string, DirectoryStats>;
|
|
82
|
+
largestFiles: FileInfo[];
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Method statistics
|
|
87
|
+
*/
|
|
88
|
+
export interface MethodStats {
|
|
89
|
+
totalMethods: number;
|
|
90
|
+
includedMethods: number;
|
|
91
|
+
methodTokens: Record<string, number>;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* LLM Context
|
|
96
|
+
*/
|
|
97
|
+
export interface LLMContext {
|
|
98
|
+
project: {
|
|
99
|
+
root: string;
|
|
100
|
+
totalFiles: number;
|
|
101
|
+
totalTokens: number;
|
|
102
|
+
};
|
|
103
|
+
paths?: Record<string, string[]>;
|
|
104
|
+
methods?: Record<string, MethodInfo[]>;
|
|
105
|
+
methodStats?: MethodStats;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Token Calculator class
|
|
110
|
+
* Main class for analyzing projects and calculating tokens
|
|
111
|
+
*/
|
|
112
|
+
export class TokenCalculator {
|
|
113
|
+
constructor(projectRoot: string, options?: TokenCalculatorOptions);
|
|
114
|
+
|
|
115
|
+
projectRoot: string;
|
|
116
|
+
options: TokenCalculatorOptions;
|
|
117
|
+
stats: AnalysisStats;
|
|
118
|
+
methodStats: MethodStats;
|
|
119
|
+
|
|
120
|
+
calculateTokens(content: string, filePath: string): number;
|
|
121
|
+
isTextFile(filePath: string): boolean;
|
|
122
|
+
isCodeFile(filePath: string): boolean;
|
|
123
|
+
analyzeFile(filePath: string): FileInfo;
|
|
124
|
+
scanDirectory(dir: string): string[];
|
|
125
|
+
analyze(): FileInfo[];
|
|
126
|
+
analyzeFiles(files: string[]): FileInfo[];
|
|
127
|
+
updateStats(fileInfo: FileInfo): void;
|
|
128
|
+
generateLLMContext(analysisResults: FileInfo[] | { files: FileInfo[] }): LLMContext;
|
|
129
|
+
exportContextToClipboard(context: LLMContext): void;
|
|
130
|
+
saveContextToFile(context: LLMContext): void;
|
|
131
|
+
saveDetailedReport(analysisResults: FileInfo[]): void;
|
|
132
|
+
saveGitIngestDigest(analysisResults: FileInfo[]): void;
|
|
133
|
+
run(): AnalysisStats;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* @deprecated Use TokenCalculator instead
|
|
138
|
+
*/
|
|
139
|
+
export class TokenAnalyzer extends TokenCalculator {}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Method Analyzer class
|
|
143
|
+
* Extracts methods from multiple programming languages
|
|
144
|
+
*/
|
|
145
|
+
export class MethodAnalyzer {
|
|
146
|
+
extractMethods(content: string, filePath: string): MethodInfo[];
|
|
147
|
+
extractMethodContent(content: string, methodName: string): string | null;
|
|
148
|
+
extractJavaScriptMethods(content: string, filePath: string): MethodInfo[];
|
|
149
|
+
extractRustMethods(content: string, filePath: string): MethodInfo[];
|
|
150
|
+
extractJavaMethods(content: string, filePath: string): MethodInfo[];
|
|
151
|
+
extractCSharpMethods(content: string, filePath: string): MethodInfo[];
|
|
152
|
+
extractPythonMethods(content: string, filePath: string): MethodInfo[];
|
|
153
|
+
extractPHPMethods(content: string, filePath: string): MethodInfo[];
|
|
154
|
+
extractRubyMethods(content: string, filePath: string): MethodInfo[];
|
|
155
|
+
extractKotlinMethods(content: string, filePath: string): MethodInfo[];
|
|
156
|
+
extractSwiftMethods(content: string, filePath: string): MethodInfo[];
|
|
157
|
+
extractCPlusPlusMethods(content: string, filePath: string): MethodInfo[];
|
|
158
|
+
extractScalaMethods(content: string, filePath: string): MethodInfo[];
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// ============================================
|
|
162
|
+
// Parsers
|
|
163
|
+
// ============================================
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* GitIgnore Pattern
|
|
167
|
+
*/
|
|
168
|
+
export interface GitIgnorePattern {
|
|
169
|
+
regex: RegExp;
|
|
170
|
+
isNegation: boolean;
|
|
171
|
+
original: string;
|
|
172
|
+
isDirectory: boolean;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* GitIgnore Parser class
|
|
177
|
+
* Parses .gitignore, .contextignore, and .contextinclude files
|
|
178
|
+
*/
|
|
179
|
+
export class GitIgnoreParser {
|
|
180
|
+
constructor(gitignorePath?: string, contextIgnorePath?: string, contextIncludePath?: string);
|
|
181
|
+
|
|
182
|
+
patterns: GitIgnorePattern[];
|
|
183
|
+
contextPatterns: GitIgnorePattern[];
|
|
184
|
+
hasIncludeFile: boolean;
|
|
185
|
+
_lastIgnoreReason: string | null;
|
|
186
|
+
|
|
187
|
+
loadPatterns(
|
|
188
|
+
gitignorePath: string,
|
|
189
|
+
contextIgnorePath?: string,
|
|
190
|
+
contextIncludePath?: string
|
|
191
|
+
): void;
|
|
192
|
+
parsePatternFile(filePath: string): GitIgnorePattern[];
|
|
193
|
+
convertToRegex(pattern: string): GitIgnorePattern;
|
|
194
|
+
isIgnored(filePath: string, relativePath: string): boolean;
|
|
195
|
+
testPatterns(patterns: GitIgnorePattern[], relativePath: string, reason: string): boolean;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Method Filter Pattern
|
|
200
|
+
*/
|
|
201
|
+
export interface MethodFilterPattern {
|
|
202
|
+
pattern: string;
|
|
203
|
+
regex: RegExp;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Method Filter Parser class
|
|
208
|
+
* Parses .methodinclude and .methodignore files
|
|
209
|
+
*/
|
|
210
|
+
export class MethodFilterParser {
|
|
211
|
+
constructor(methodIncludePath?: string, methodIgnorePath?: string);
|
|
212
|
+
|
|
213
|
+
includePatterns: MethodFilterPattern[];
|
|
214
|
+
ignorePatterns: MethodFilterPattern[];
|
|
215
|
+
hasIncludeFile: boolean;
|
|
216
|
+
|
|
217
|
+
parseMethodFile(filePath: string): MethodFilterPattern[];
|
|
218
|
+
shouldIncludeMethod(methodName: string, fileName: string): boolean;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// ============================================
|
|
222
|
+
// Formatters
|
|
223
|
+
// ============================================
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* GitIngest Formatter Options
|
|
227
|
+
*/
|
|
228
|
+
export interface GitIngestFormatterOptions {
|
|
229
|
+
chunking?: {
|
|
230
|
+
enabled?: boolean;
|
|
231
|
+
strategy?: 'smart' | 'size' | 'file' | 'directory' | 'dependency';
|
|
232
|
+
maxTokensPerChunk?: number;
|
|
233
|
+
overlap?: number;
|
|
234
|
+
preserveContext?: boolean;
|
|
235
|
+
includeMetadata?: boolean;
|
|
236
|
+
crossReferences?: boolean;
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Chunk data for large repositories
|
|
242
|
+
*/
|
|
243
|
+
export interface ChunkData {
|
|
244
|
+
id: string;
|
|
245
|
+
index: number;
|
|
246
|
+
total: number;
|
|
247
|
+
content: string;
|
|
248
|
+
files: string[];
|
|
249
|
+
tokens: number;
|
|
250
|
+
metadata: Record<string, unknown>;
|
|
251
|
+
hasOverlap?: boolean;
|
|
252
|
+
overlapFiles?: string[];
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* GitIngest Formatter class
|
|
257
|
+
* Formats analyzed code into a single prompt-friendly text file
|
|
258
|
+
*/
|
|
259
|
+
export class GitIngestFormatter {
|
|
260
|
+
constructor(
|
|
261
|
+
projectRoot: string,
|
|
262
|
+
stats: AnalysisStats,
|
|
263
|
+
analysisResults: FileInfo[],
|
|
264
|
+
options?: GitIngestFormatterOptions
|
|
265
|
+
);
|
|
266
|
+
|
|
267
|
+
projectRoot: string;
|
|
268
|
+
stats: AnalysisStats;
|
|
269
|
+
analysisResults: FileInfo[];
|
|
270
|
+
options: GitIngestFormatterOptions;
|
|
271
|
+
chunking: GitIngestFormatterOptions['chunking'] & {
|
|
272
|
+
enabled: boolean;
|
|
273
|
+
strategy: string;
|
|
274
|
+
maxTokensPerChunk: number;
|
|
275
|
+
overlap: number;
|
|
276
|
+
preserveContext: boolean;
|
|
277
|
+
includeMetadata: boolean;
|
|
278
|
+
crossReferences: boolean;
|
|
279
|
+
};
|
|
280
|
+
methodFilterEnabled: boolean;
|
|
281
|
+
methodAnalyzer?: MethodAnalyzer;
|
|
282
|
+
methodFilter?: MethodFilterParser | null;
|
|
283
|
+
|
|
284
|
+
generateDigest(): string;
|
|
285
|
+
generateChunkedDigest(): ChunkData[];
|
|
286
|
+
createChunks(): Array<{
|
|
287
|
+
files: FileInfo[];
|
|
288
|
+
tokens: number;
|
|
289
|
+
directories?: Set<string>;
|
|
290
|
+
metadata?: Record<string, unknown>;
|
|
291
|
+
}>;
|
|
292
|
+
saveToFile(outputPath: string): number;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* Toon Formatter Options
|
|
297
|
+
*/
|
|
298
|
+
export interface ToonFormatterOptions {
|
|
299
|
+
indent?: number;
|
|
300
|
+
delimiter?: ',' | '\t' | '|';
|
|
301
|
+
lengthMarker?: boolean;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* Toon Formatter class
|
|
306
|
+
* Tabular Object Oriented Notation formatter (40-50% token reduction)
|
|
307
|
+
*/
|
|
308
|
+
export class ToonFormatter {
|
|
309
|
+
constructor(options?: ToonFormatterOptions);
|
|
310
|
+
|
|
311
|
+
options: ToonFormatterOptions & {
|
|
312
|
+
indent: number;
|
|
313
|
+
delimiter: string;
|
|
314
|
+
lengthMarker: boolean;
|
|
315
|
+
};
|
|
316
|
+
indentChar: string;
|
|
317
|
+
|
|
318
|
+
encode(data: unknown, options?: ToonFormatterOptions): string;
|
|
319
|
+
encodeAsync(data: unknown, options?: ToonFormatterOptions): Promise<string>;
|
|
320
|
+
encodeSync(data: unknown, options?: ToonFormatterOptions): string;
|
|
321
|
+
decode(toonString: string, options?: ToonFormatterOptions): unknown;
|
|
322
|
+
decodeAsync(toonString: string, options?: ToonFormatterOptions): Promise<unknown>;
|
|
323
|
+
validate(toonString: string): { valid: boolean; errors: string[] };
|
|
324
|
+
estimateTokens(toonString: string): number;
|
|
325
|
+
optimize(toonString: string): string;
|
|
326
|
+
minify(toonString: string): string;
|
|
327
|
+
compareWithJSON(data: unknown): {
|
|
328
|
+
toon: string;
|
|
329
|
+
json: string;
|
|
330
|
+
toonSize: number;
|
|
331
|
+
jsonSize: number;
|
|
332
|
+
savings: number;
|
|
333
|
+
savingsPercentage: number;
|
|
334
|
+
toonTokens: number;
|
|
335
|
+
jsonTokens: number;
|
|
336
|
+
};
|
|
337
|
+
compareWithOfficial(
|
|
338
|
+
data: unknown,
|
|
339
|
+
options?: ToonFormatterOptions
|
|
340
|
+
): Promise<{
|
|
341
|
+
custom: string;
|
|
342
|
+
official: string;
|
|
343
|
+
customSize: number;
|
|
344
|
+
officialSize: number;
|
|
345
|
+
difference: number;
|
|
346
|
+
officialIsBetter: boolean;
|
|
347
|
+
}>;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
/**
|
|
351
|
+
* Format Info
|
|
352
|
+
*/
|
|
353
|
+
export interface FormatInfo {
|
|
354
|
+
name: string;
|
|
355
|
+
description: string;
|
|
356
|
+
extension: string;
|
|
357
|
+
mimeType: string;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
/**
|
|
361
|
+
* Format Encoder Function
|
|
362
|
+
*/
|
|
363
|
+
export type FormatEncoder = (data: unknown, options?: Record<string, unknown>) => string;
|
|
364
|
+
|
|
365
|
+
/**
|
|
366
|
+
* Format Registration
|
|
367
|
+
*/
|
|
368
|
+
export interface FormatRegistration {
|
|
369
|
+
name: string;
|
|
370
|
+
description: string;
|
|
371
|
+
extension: string;
|
|
372
|
+
mimeType: string;
|
|
373
|
+
encoder: FormatEncoder;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
/**
|
|
377
|
+
* Format Registry class
|
|
378
|
+
* Central registry for all output format exporters
|
|
379
|
+
*/
|
|
380
|
+
export class FormatRegistry {
|
|
381
|
+
constructor();
|
|
382
|
+
|
|
383
|
+
formatters: Map<string, FormatRegistration>;
|
|
384
|
+
|
|
385
|
+
register(name: string, formatter: FormatRegistration): void;
|
|
386
|
+
get(name: string): FormatRegistration;
|
|
387
|
+
has(name: string): boolean;
|
|
388
|
+
listFormats(): string[];
|
|
389
|
+
getInfo(name: string): FormatInfo;
|
|
390
|
+
getAllInfo(): Record<string, FormatInfo>;
|
|
391
|
+
encode(name: string, data: unknown, options?: Record<string, unknown>): string;
|
|
392
|
+
encodeYAML(data: unknown, indent?: number): string;
|
|
393
|
+
encodeMarkdown(data: unknown): string;
|
|
394
|
+
encodeCSV(data: unknown): string;
|
|
395
|
+
encodeXML(data: unknown, indent?: number): string;
|
|
396
|
+
suggestFormat(data: unknown): string;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
// ============================================
|
|
400
|
+
// Utils
|
|
401
|
+
// ============================================
|
|
402
|
+
|
|
403
|
+
/**
|
|
404
|
+
* Token Utils class
|
|
405
|
+
* Token counting and formatting utilities
|
|
406
|
+
*/
|
|
407
|
+
export class TokenUtils {
|
|
408
|
+
static calculateForModel(content: string, modelName: string): Promise<number>;
|
|
409
|
+
static calculate(content: string, filePath: string): number;
|
|
410
|
+
static estimate(content: string, filePath: string): number;
|
|
411
|
+
static format(tokens: number): string;
|
|
412
|
+
static getMethodForModel(modelName: string): Promise<string>;
|
|
413
|
+
static getMethod(): string;
|
|
414
|
+
static isExact(): boolean;
|
|
415
|
+
static hasExactCounting(): boolean;
|
|
416
|
+
static getAvailableTokenizers(): Promise<Array<{ name: string; available: boolean }>>;
|
|
417
|
+
static detectTokenizer(modelName: string): Promise<string>;
|
|
418
|
+
static getTelemetry(): Promise<Record<string, unknown>>;
|
|
419
|
+
static resetTelemetry(): Promise<void>;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
/**
|
|
423
|
+
* File Utils class
|
|
424
|
+
* File type detection and utilities
|
|
425
|
+
*/
|
|
426
|
+
export class FileUtils {
|
|
427
|
+
static isText(filePath: string): boolean;
|
|
428
|
+
static isCode(filePath: string): boolean;
|
|
429
|
+
static getType(filePath: string): 'code' | 'config' | 'doc' | 'style' | 'other';
|
|
430
|
+
static getExtension(filePath: string): string;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
/**
|
|
434
|
+
* Clipboard Utils class
|
|
435
|
+
* Cross-platform clipboard utilities
|
|
436
|
+
*/
|
|
437
|
+
export class ClipboardUtils {
|
|
438
|
+
static copy(text: string): boolean;
|
|
439
|
+
static isAvailable(): boolean;
|
|
440
|
+
static getCommand(): string;
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
/**
|
|
444
|
+
* Config Utils class
|
|
445
|
+
* Configuration file utilities
|
|
446
|
+
*/
|
|
447
|
+
export class ConfigUtils {
|
|
448
|
+
static findConfigFile(projectRoot: string, filename: string): string | undefined;
|
|
449
|
+
static initMethodFilter(projectRoot: string): MethodFilterParser | null;
|
|
450
|
+
static detectMethodFilters(projectRoot: string): boolean;
|
|
451
|
+
static initGitIgnore(projectRoot: string): GitIgnoreParser;
|
|
452
|
+
static getConfigPaths(projectRoot: string): {
|
|
453
|
+
gitignore: string;
|
|
454
|
+
contextIgnore: string | undefined;
|
|
455
|
+
contextInclude: string | undefined;
|
|
456
|
+
methodInclude: string | undefined;
|
|
457
|
+
methodIgnore: string | undefined;
|
|
458
|
+
};
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
/**
|
|
462
|
+
* Conversion Result
|
|
463
|
+
*/
|
|
464
|
+
export interface ConversionResult {
|
|
465
|
+
output: string;
|
|
466
|
+
metadata: {
|
|
467
|
+
inputSize: number;
|
|
468
|
+
outputSize: number;
|
|
469
|
+
savings: number;
|
|
470
|
+
savingsPercentage: number;
|
|
471
|
+
fromFormat: string;
|
|
472
|
+
toFormat: string;
|
|
473
|
+
};
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
/**
|
|
477
|
+
* File Conversion Result
|
|
478
|
+
*/
|
|
479
|
+
export interface FileConversionResult {
|
|
480
|
+
inputFile: string;
|
|
481
|
+
outputFile: string;
|
|
482
|
+
fromFormat: string;
|
|
483
|
+
toFormat: string;
|
|
484
|
+
inputSize: number;
|
|
485
|
+
outputSize: number;
|
|
486
|
+
savings: number;
|
|
487
|
+
savingsPercent: string;
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
/**
|
|
491
|
+
* Batch Conversion Item
|
|
492
|
+
*/
|
|
493
|
+
export interface BatchConversionItem {
|
|
494
|
+
input: string;
|
|
495
|
+
output: string;
|
|
496
|
+
from?: string;
|
|
497
|
+
to?: string;
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
/**
|
|
501
|
+
* Batch Conversion Result
|
|
502
|
+
*/
|
|
503
|
+
export interface BatchConversionResult {
|
|
504
|
+
success: boolean;
|
|
505
|
+
inputFile?: string;
|
|
506
|
+
outputFile?: string;
|
|
507
|
+
error?: string;
|
|
508
|
+
fromFormat?: string;
|
|
509
|
+
toFormat?: string;
|
|
510
|
+
inputSize?: number;
|
|
511
|
+
outputSize?: number;
|
|
512
|
+
savings?: number;
|
|
513
|
+
savingsPercent?: string;
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
/**
|
|
517
|
+
* Format Converter class
|
|
518
|
+
* Convert between different output formats
|
|
519
|
+
*/
|
|
520
|
+
export class FormatConverter {
|
|
521
|
+
constructor();
|
|
522
|
+
|
|
523
|
+
registry: FormatRegistry;
|
|
524
|
+
toonFormatter: ToonFormatter;
|
|
525
|
+
|
|
526
|
+
convert(input: string, fromFormat: string, toFormat: string): ConversionResult;
|
|
527
|
+
parse(input: string, format: string): unknown;
|
|
528
|
+
encode(data: unknown, format: string): string;
|
|
529
|
+
parseYAML(yamlString: string): Record<string, unknown>;
|
|
530
|
+
parseCSV(csvString: string): { headers: string[]; rows: Record<string, string>[] };
|
|
531
|
+
convertFile(
|
|
532
|
+
inputFile: string,
|
|
533
|
+
outputFile: string,
|
|
534
|
+
fromFormat?: string | null,
|
|
535
|
+
toFormat?: string | null
|
|
536
|
+
): FileConversionResult;
|
|
537
|
+
extensionToFormat(ext: string): string;
|
|
538
|
+
batchConvert(files: BatchConversionItem[]): BatchConversionResult[];
|
|
539
|
+
getSupportedConversions(): {
|
|
540
|
+
fullySupported: string[];
|
|
541
|
+
partialSupport: string[];
|
|
542
|
+
planned: string[];
|
|
543
|
+
};
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
/**
|
|
547
|
+
* Error Handler Options
|
|
548
|
+
*/
|
|
549
|
+
export interface ErrorHandlerOptions {
|
|
550
|
+
verbose?: boolean;
|
|
551
|
+
logFile?: string | null;
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
/**
|
|
555
|
+
* Error Handler class
|
|
556
|
+
* Enhanced error handling and user-friendly messages
|
|
557
|
+
*/
|
|
558
|
+
export class ErrorHandler {
|
|
559
|
+
constructor(options?: ErrorHandlerOptions);
|
|
560
|
+
|
|
561
|
+
verbose: boolean;
|
|
562
|
+
logFile: string | null;
|
|
563
|
+
|
|
564
|
+
handleFormatError(error: Error, format: string): void;
|
|
565
|
+
handleFileError(error: Error & { code?: string }, filePath: string): void;
|
|
566
|
+
handleParseError(error: Error, format: string, content?: string): void;
|
|
567
|
+
handleValidationError(errors: string[], context: string): void;
|
|
568
|
+
logError(message: string, error: Error | { errors?: string[] }): void;
|
|
569
|
+
wrapAsync<T extends (...args: unknown[]) => Promise<unknown>>(fn: T, context: string): T;
|
|
570
|
+
validateFormat(format: string, supportedFormats: string[]): void;
|
|
571
|
+
createUserMessage(error: Error & { code?: string }, context?: string): string;
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
/**
|
|
575
|
+
* Logger Options
|
|
576
|
+
*/
|
|
577
|
+
export interface LoggerOptions {
|
|
578
|
+
level?: 'error' | 'warn' | 'info' | 'debug' | 'trace';
|
|
579
|
+
logToFile?: boolean;
|
|
580
|
+
logDir?: string;
|
|
581
|
+
logFile?: string;
|
|
582
|
+
silent?: boolean;
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
/**
|
|
586
|
+
* Logger class
|
|
587
|
+
* Centralized logging with multiple levels and file output
|
|
588
|
+
*/
|
|
589
|
+
export class Logger {
|
|
590
|
+
constructor(options?: LoggerOptions);
|
|
591
|
+
|
|
592
|
+
level: string;
|
|
593
|
+
logToFile: boolean;
|
|
594
|
+
logDir: string;
|
|
595
|
+
logFile: string;
|
|
596
|
+
silent: boolean;
|
|
597
|
+
levels: Record<string, number>;
|
|
598
|
+
colors: Record<string, string>;
|
|
599
|
+
icons: Record<string, string>;
|
|
600
|
+
|
|
601
|
+
initializeLogDirectory(): void;
|
|
602
|
+
getDateString(): string;
|
|
603
|
+
getTimestamp(): string;
|
|
604
|
+
shouldLog(level: string): boolean;
|
|
605
|
+
formatMessage(
|
|
606
|
+
level: string,
|
|
607
|
+
message: string,
|
|
608
|
+
meta?: Record<string, unknown>
|
|
609
|
+
): {
|
|
610
|
+
consoleMessage: string;
|
|
611
|
+
fileMessage: string;
|
|
612
|
+
};
|
|
613
|
+
writeToFile(message: string): void;
|
|
614
|
+
log(level: string, message: string, meta?: Record<string, unknown>): void;
|
|
615
|
+
error(message: string, meta?: Record<string, unknown>): void;
|
|
616
|
+
warn(message: string, meta?: Record<string, unknown>): void;
|
|
617
|
+
info(message: string, meta?: Record<string, unknown>): void;
|
|
618
|
+
debug(message: string, meta?: Record<string, unknown>): void;
|
|
619
|
+
trace(message: string, meta?: Record<string, unknown>): void;
|
|
620
|
+
custom(icon: string, level: string, message: string, meta?: Record<string, unknown>): void;
|
|
621
|
+
group(title: string): void;
|
|
622
|
+
groupEnd(): void;
|
|
623
|
+
time(label: string): void;
|
|
624
|
+
timeEnd(label: string): void;
|
|
625
|
+
clearOldLogs(daysToKeep?: number): void;
|
|
626
|
+
getLogFilePath(): string;
|
|
627
|
+
getRecentLogs(lines?: number): string[];
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
/**
|
|
631
|
+
* Get or create default logger instance
|
|
632
|
+
*/
|
|
633
|
+
export function getLogger(options?: LoggerOptions): Logger;
|
|
634
|
+
|
|
635
|
+
/**
|
|
636
|
+
* Create a new logger instance
|
|
637
|
+
*/
|
|
638
|
+
export function createLogger(options?: LoggerOptions): Logger;
|
|
639
|
+
|
|
640
|
+
/**
|
|
641
|
+
* Updater Options
|
|
642
|
+
*/
|
|
643
|
+
export interface UpdaterOptions {
|
|
644
|
+
channel?: 'stable' | 'insider';
|
|
645
|
+
autoUpdate?: boolean;
|
|
646
|
+
checkInterval?: number;
|
|
647
|
+
configDir?: string;
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
/**
|
|
651
|
+
* Update Info
|
|
652
|
+
*/
|
|
653
|
+
export interface UpdateInfo {
|
|
654
|
+
available: boolean;
|
|
655
|
+
currentVersion?: string;
|
|
656
|
+
latestVersion?: string;
|
|
657
|
+
channel?: string;
|
|
658
|
+
releaseNotes?: string;
|
|
659
|
+
downloadUrl?: string;
|
|
660
|
+
publishedAt?: string;
|
|
661
|
+
message?: string;
|
|
662
|
+
error?: string;
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
/**
|
|
666
|
+
* Install Result
|
|
667
|
+
*/
|
|
668
|
+
export interface InstallResult {
|
|
669
|
+
success: boolean;
|
|
670
|
+
oldVersion?: string;
|
|
671
|
+
newVersion?: string;
|
|
672
|
+
backupPath?: string;
|
|
673
|
+
error?: string;
|
|
674
|
+
manualUpdateRequired?: boolean;
|
|
675
|
+
instructions?: string;
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
/**
|
|
679
|
+
* Rollback Result
|
|
680
|
+
*/
|
|
681
|
+
export interface RollbackResult {
|
|
682
|
+
success: boolean;
|
|
683
|
+
restoredVersion?: string;
|
|
684
|
+
error?: string;
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
/**
|
|
688
|
+
* Updater class
|
|
689
|
+
* Auto-update system with version channels
|
|
690
|
+
*/
|
|
691
|
+
export class Updater {
|
|
692
|
+
constructor(options?: UpdaterOptions);
|
|
693
|
+
|
|
694
|
+
currentVersion: string;
|
|
695
|
+
channel: 'stable' | 'insider';
|
|
696
|
+
autoUpdate: boolean;
|
|
697
|
+
checkInterval: number;
|
|
698
|
+
configDir: string;
|
|
699
|
+
updateCacheFile: string;
|
|
700
|
+
endpoints: {
|
|
701
|
+
stable: string;
|
|
702
|
+
insider: string;
|
|
703
|
+
version: string;
|
|
704
|
+
};
|
|
705
|
+
|
|
706
|
+
getCurrentVersion(): string;
|
|
707
|
+
fetchJSON(url: string): Promise<unknown>;
|
|
708
|
+
compareVersions(v1: string, v2: string): -1 | 0 | 1;
|
|
709
|
+
checkForUpdates(): Promise<UpdateInfo>;
|
|
710
|
+
getLatestVersion(): Promise<{
|
|
711
|
+
version: string;
|
|
712
|
+
releaseNotes: string;
|
|
713
|
+
downloadUrl: string;
|
|
714
|
+
publishedAt: string;
|
|
715
|
+
assets: unknown[];
|
|
716
|
+
} | null>;
|
|
717
|
+
installUpdate(updateInfo: UpdateInfo): Promise<InstallResult>;
|
|
718
|
+
detectInstallationType(): 'global' | 'local' | 'source' | 'unknown';
|
|
719
|
+
getInstallDir(): string | null;
|
|
720
|
+
createBackup(): string;
|
|
721
|
+
rollback(): Promise<RollbackResult>;
|
|
722
|
+
switchChannel(newChannel: 'stable' | 'insider'): Promise<UpdateInfo>;
|
|
723
|
+
saveConfig(config: { channel?: string; autoUpdate?: boolean }): void;
|
|
724
|
+
getUpdateCache(): Record<string, unknown> | null;
|
|
725
|
+
saveUpdateCache(data: Record<string, unknown>): void;
|
|
726
|
+
shouldCheckForUpdates(): boolean;
|
|
727
|
+
checkAndNotify(): Promise<UpdateInfo>;
|
|
728
|
+
showUpdateNotification(updateInfo: UpdateInfo): void;
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
/**
|
|
732
|
+
* Git Utils Options
|
|
733
|
+
*/
|
|
734
|
+
export interface GitUtilsOptions {
|
|
735
|
+
tempDir?: string;
|
|
736
|
+
outputDir?: string;
|
|
737
|
+
verbose?: boolean;
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
/**
|
|
741
|
+
* GitHub Repository Info
|
|
742
|
+
*/
|
|
743
|
+
export interface GitHubRepoInfo {
|
|
744
|
+
owner: string;
|
|
745
|
+
repo: string;
|
|
746
|
+
branch: string;
|
|
747
|
+
fullName: string;
|
|
748
|
+
cloneUrl: string;
|
|
749
|
+
apiUrl: string;
|
|
750
|
+
rawUrl: string;
|
|
751
|
+
originalUrl: string;
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
/**
|
|
755
|
+
* Repository Generation Stats
|
|
756
|
+
*/
|
|
757
|
+
export interface RepoGenerationStats {
|
|
758
|
+
repository: string;
|
|
759
|
+
branch: string;
|
|
760
|
+
url: string;
|
|
761
|
+
localPath: string;
|
|
762
|
+
outputFile: string;
|
|
763
|
+
digestSize: number;
|
|
764
|
+
digestSizeKB: string;
|
|
765
|
+
files: number;
|
|
766
|
+
tokens: number;
|
|
767
|
+
lines: number;
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
/**
|
|
771
|
+
* Repository Info from API
|
|
772
|
+
*/
|
|
773
|
+
export interface RepositoryAPIInfo {
|
|
774
|
+
name: string;
|
|
775
|
+
fullName: string;
|
|
776
|
+
description: string;
|
|
777
|
+
stars: number;
|
|
778
|
+
forks: number;
|
|
779
|
+
defaultBranch: string;
|
|
780
|
+
size: number;
|
|
781
|
+
language: string;
|
|
782
|
+
updatedAt: string;
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
/**
|
|
786
|
+
* Cached Repository
|
|
787
|
+
*/
|
|
788
|
+
export interface CachedRepo {
|
|
789
|
+
name: string;
|
|
790
|
+
path: string;
|
|
791
|
+
size: number;
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
/**
|
|
795
|
+
* Git Utils class
|
|
796
|
+
* GitHub URL parsing, repository cloning, and GitIngest generation
|
|
797
|
+
*/
|
|
798
|
+
export class GitUtils {
|
|
799
|
+
constructor(options?: GitUtilsOptions);
|
|
800
|
+
|
|
801
|
+
tempDir: string;
|
|
802
|
+
outputDir: string;
|
|
803
|
+
verbose: boolean;
|
|
804
|
+
|
|
805
|
+
parseGitHubURL(url: string): GitHubRepoInfo;
|
|
806
|
+
isGitInstalled(): boolean;
|
|
807
|
+
cloneRepository(
|
|
808
|
+
repoInfo: GitHubRepoInfo,
|
|
809
|
+
options?: { shallow?: boolean; depth?: number }
|
|
810
|
+
): string;
|
|
811
|
+
generateFromGitHub(
|
|
812
|
+
url: string,
|
|
813
|
+
options?: {
|
|
814
|
+
outputFile?: string;
|
|
815
|
+
cleanup?: boolean;
|
|
816
|
+
shallow?: boolean;
|
|
817
|
+
analyzerOptions?: TokenCalculatorOptions;
|
|
818
|
+
formatterOptions?: GitIngestFormatterOptions;
|
|
819
|
+
}
|
|
820
|
+
): Promise<RepoGenerationStats>;
|
|
821
|
+
fetchFileFromGitHub(url: string): Promise<string>;
|
|
822
|
+
getRepositoryInfo(repoInfo: GitHubRepoInfo): Promise<RepositoryAPIInfo>;
|
|
823
|
+
cleanupTemp(): void;
|
|
824
|
+
listCachedRepos(): CachedRepo[];
|
|
825
|
+
getDirectorySize(dir: string): number;
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
// ============================================
|
|
829
|
+
// Orchestrator Functions
|
|
830
|
+
// ============================================
|
|
831
|
+
|
|
832
|
+
/**
|
|
833
|
+
* Generate GitIngest digest from token-analysis-report.json
|
|
834
|
+
*/
|
|
835
|
+
export function generateDigestFromReport(reportPath: string): void;
|
|
836
|
+
|
|
837
|
+
/**
|
|
838
|
+
* Generate GitIngest digest from llm-context.json
|
|
839
|
+
*/
|
|
840
|
+
export function generateDigestFromContext(contextPath: string): void;
|
|
841
|
+
|
|
842
|
+
// ============================================
|
|
843
|
+
// Repository Map (ctxman map)
|
|
844
|
+
// ============================================
|
|
845
|
+
|
|
846
|
+
/**
|
|
847
|
+
* A function or method of a mapped file
|
|
848
|
+
*/
|
|
849
|
+
export interface RepoMapMethod {
|
|
850
|
+
name: string;
|
|
851
|
+
/** 1-based line of the declaration */
|
|
852
|
+
line: number;
|
|
853
|
+
/** Declaration on one line, secrets redacted unless `redact: false` */
|
|
854
|
+
signature: string;
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
/**
|
|
858
|
+
* A source file of the repository graph
|
|
859
|
+
*/
|
|
860
|
+
export interface RepoGraphNode {
|
|
861
|
+
/** Project-relative path with forward slashes */
|
|
862
|
+
path: string;
|
|
863
|
+
language: string;
|
|
864
|
+
bytes: number;
|
|
865
|
+
methods: RepoMapMethod[];
|
|
866
|
+
/** Mentions of this file's function names in other files (shared between definers) */
|
|
867
|
+
symbolRefs: number;
|
|
868
|
+
/** Imports that named no file of the project (packages, standard library) */
|
|
869
|
+
unresolvedImports: number;
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
/**
|
|
873
|
+
* Import edge, importer -> imported. A package-wide import (Go, Java wildcard, C# using)
|
|
874
|
+
* spreads weight 1 over the files of the package.
|
|
875
|
+
*/
|
|
876
|
+
export interface RepoGraphEdge {
|
|
877
|
+
from: string;
|
|
878
|
+
to: string;
|
|
879
|
+
weight: number;
|
|
880
|
+
}
|
|
881
|
+
|
|
882
|
+
export interface RepoGraph {
|
|
883
|
+
/** Absolute project root */
|
|
884
|
+
root: string;
|
|
885
|
+
nodes: RepoGraphNode[];
|
|
886
|
+
edges: RepoGraphEdge[];
|
|
887
|
+
history: {
|
|
888
|
+
available: boolean;
|
|
889
|
+
requested: number;
|
|
890
|
+
commits: number;
|
|
891
|
+
/** Commits touching each file */
|
|
892
|
+
counts: Record<string, number>;
|
|
893
|
+
reason?: string;
|
|
894
|
+
};
|
|
895
|
+
stats: {
|
|
896
|
+
scannedFiles: number;
|
|
897
|
+
files: number;
|
|
898
|
+
edges: number;
|
|
899
|
+
unresolvedImports: number;
|
|
900
|
+
skipped: Array<{ path: string; reason: string }>;
|
|
901
|
+
redactions: Record<string, number>;
|
|
902
|
+
timings: Record<string, number>;
|
|
903
|
+
};
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
export interface RepoGraphOptions {
|
|
907
|
+
/** Commits of git history to mine for change frequency (default 300, 0 disables) */
|
|
908
|
+
history?: number;
|
|
909
|
+
/** Mask secrets in signatures (default true) */
|
|
910
|
+
redact?: boolean;
|
|
911
|
+
/** Leave out larger files (default 512 KiB) */
|
|
912
|
+
maxFileBytes?: number;
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
export interface RankWeights {
|
|
916
|
+
pagerank?: number;
|
|
917
|
+
history?: number;
|
|
918
|
+
symbols?: number;
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
export interface RankOptions {
|
|
922
|
+
/** Files or folders (project-relative or absolute) to personalise PageRank toward */
|
|
923
|
+
focus?: string[];
|
|
924
|
+
/** Blend of the normalised components (default 0.70 / 0.25 / 0.05) */
|
|
925
|
+
weights?: RankWeights;
|
|
926
|
+
/** PageRank damping (default 0.85) */
|
|
927
|
+
damping?: number;
|
|
928
|
+
}
|
|
929
|
+
|
|
930
|
+
export interface RankedFile {
|
|
931
|
+
path: string;
|
|
932
|
+
/** 1 = best */
|
|
933
|
+
rank: number;
|
|
934
|
+
/** Blended score in [0, 1] */
|
|
935
|
+
score: number;
|
|
936
|
+
/** Raw PageRank (all files sum to 1) */
|
|
937
|
+
pagerank: number;
|
|
938
|
+
/** Commits touching the file among the mined history */
|
|
939
|
+
changes: number;
|
|
940
|
+
symbolRefs: number;
|
|
941
|
+
focus: boolean;
|
|
942
|
+
/** Each component scaled to [0, 1] */
|
|
943
|
+
components: { pagerank: number; history: number; symbols: number };
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
export interface RepoMapOptions extends RepoGraphOptions, RankOptions {
|
|
947
|
+
/** Token budget of the rendered map (default 2048) */
|
|
948
|
+
tokens?: number;
|
|
949
|
+
/** Order of the files in the output (default 'rank') */
|
|
950
|
+
order?: 'rank' | 'path';
|
|
951
|
+
/** Highest-ranked file last (rank order only) */
|
|
952
|
+
importantLast?: boolean;
|
|
953
|
+
style?: 'text' | 'markdown' | 'json' | 'dot';
|
|
954
|
+
/** Render the dependency edges instead of the map */
|
|
955
|
+
graph?: boolean;
|
|
956
|
+
}
|
|
957
|
+
|
|
958
|
+
export interface RepoMapFile {
|
|
959
|
+
path: string;
|
|
960
|
+
rank: number;
|
|
961
|
+
score: number;
|
|
962
|
+
/** Tokens of the whole file */
|
|
963
|
+
tokens: number;
|
|
964
|
+
methods: Array<RepoMapMethod & { tokens: number }>;
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
export interface RepoMapResult {
|
|
968
|
+
output: string;
|
|
969
|
+
style: string;
|
|
970
|
+
budget: number;
|
|
971
|
+
/** Tokens of the rendered map (for json: of the same map rendered as text) */
|
|
972
|
+
tokens: number;
|
|
973
|
+
/** Files in the map, in output order */
|
|
974
|
+
files: RepoMapFile[];
|
|
975
|
+
/** Every file, best first */
|
|
976
|
+
ranked: RankedFile[];
|
|
977
|
+
graph: RepoGraph;
|
|
978
|
+
/** Files that did not fit the budget */
|
|
979
|
+
skipped: number;
|
|
980
|
+
warnings: string[];
|
|
981
|
+
stats: RepoGraph['stats'];
|
|
982
|
+
}
|
|
983
|
+
|
|
984
|
+
/**
|
|
985
|
+
* Scan a project (respecting .gitignore/.contextignore/.contextinclude) and build its
|
|
986
|
+
* file dependency graph from imports
|
|
987
|
+
*/
|
|
988
|
+
export function buildRepoGraph(root: string, options?: RepoGraphOptions): RepoGraph;
|
|
989
|
+
|
|
990
|
+
/**
|
|
991
|
+
* Rank the files of a graph, best first: PageRank blended with git change frequency and
|
|
992
|
+
* symbol references
|
|
993
|
+
*/
|
|
994
|
+
export function rankFiles(graph: RepoGraph, options?: RankOptions): RankedFile[];
|
|
995
|
+
|
|
996
|
+
/**
|
|
997
|
+
* Build, rank and render the repository map of a project within a token budget
|
|
998
|
+
*/
|
|
999
|
+
export function renderRepoMap(root: string, options?: RepoMapOptions): RepoMapResult;
|
|
1000
|
+
|
|
1001
|
+
// ============================================
|
|
1002
|
+
// Pull-request review context
|
|
1003
|
+
// ============================================
|
|
1004
|
+
|
|
1005
|
+
export type PrContextStyle = 'markdown' | 'xml' | 'json';
|
|
1006
|
+
|
|
1007
|
+
export interface PrContextOptions {
|
|
1008
|
+
/** Base revision (default: origin/HEAD, else main, else master; HEAD with staged/working) */
|
|
1009
|
+
base?: string;
|
|
1010
|
+
/** Head revision (default: HEAD) */
|
|
1011
|
+
head?: string;
|
|
1012
|
+
/** Compare the index instead of a head commit */
|
|
1013
|
+
staged?: boolean;
|
|
1014
|
+
/** Compare the working tree (untracked files included) instead of a head commit */
|
|
1015
|
+
working?: boolean;
|
|
1016
|
+
/** Context lines in the diff (default: 3) */
|
|
1017
|
+
unified?: number;
|
|
1018
|
+
/** Include the unified diff (default: true) */
|
|
1019
|
+
diff?: boolean;
|
|
1020
|
+
/** Include the related tests' contents */
|
|
1021
|
+
withTests?: boolean;
|
|
1022
|
+
/** Include the changed files' full contents */
|
|
1023
|
+
withFiles?: boolean;
|
|
1024
|
+
/** Question appended at the end */
|
|
1025
|
+
ask?: string;
|
|
1026
|
+
/** Instructions appended at the end */
|
|
1027
|
+
instructions?: string;
|
|
1028
|
+
/** Maximum tokens of the output; lower-priority material is dropped first */
|
|
1029
|
+
budget?: number;
|
|
1030
|
+
/** Output style (default: markdown) */
|
|
1031
|
+
style?: PrContextStyle;
|
|
1032
|
+
/** Mask secrets in contents, diff and commit messages (default: true) */
|
|
1033
|
+
redact?: boolean;
|
|
1034
|
+
/** Skip file contents larger than this for methods and full contents (default: 1 MiB) */
|
|
1035
|
+
maxFileBytes?: number;
|
|
1036
|
+
/** Most related tests to list (default: 50) */
|
|
1037
|
+
maxRelatedTests?: number;
|
|
1038
|
+
}
|
|
1039
|
+
|
|
1040
|
+
export interface PrRevision {
|
|
1041
|
+
ref: string;
|
|
1042
|
+
sha: string | null;
|
|
1043
|
+
short: string | null;
|
|
1044
|
+
}
|
|
1045
|
+
|
|
1046
|
+
export interface PrChangedFile {
|
|
1047
|
+
/** A, M, D, R, C or T */
|
|
1048
|
+
status: string;
|
|
1049
|
+
path: string;
|
|
1050
|
+
oldPath: string | null;
|
|
1051
|
+
similarity: number | null;
|
|
1052
|
+
additions: number;
|
|
1053
|
+
deletions: number;
|
|
1054
|
+
binary: boolean;
|
|
1055
|
+
untracked: boolean;
|
|
1056
|
+
/** Filter that keeps the file's content out (.contextignore, ...), or null */
|
|
1057
|
+
excluded: string | null;
|
|
1058
|
+
}
|
|
1059
|
+
|
|
1060
|
+
export interface PrMethod {
|
|
1061
|
+
file: string;
|
|
1062
|
+
name: string;
|
|
1063
|
+
start: number;
|
|
1064
|
+
end: number;
|
|
1065
|
+
}
|
|
1066
|
+
|
|
1067
|
+
export interface PrChangedMethod extends PrMethod {
|
|
1068
|
+
change: 'added' | 'modified';
|
|
1069
|
+
changedLines: number;
|
|
1070
|
+
source: string;
|
|
1071
|
+
sourceDropped: boolean;
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
export interface PrCommit {
|
|
1075
|
+
sha: string;
|
|
1076
|
+
short: string;
|
|
1077
|
+
author: string;
|
|
1078
|
+
date: string;
|
|
1079
|
+
subject: string;
|
|
1080
|
+
body: string;
|
|
1081
|
+
}
|
|
1082
|
+
|
|
1083
|
+
export interface PrRelatedTest {
|
|
1084
|
+
path: string;
|
|
1085
|
+
reasons: string[];
|
|
1086
|
+
changed: boolean;
|
|
1087
|
+
excluded: string | null;
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1090
|
+
export interface PrContextResult {
|
|
1091
|
+
/** The rendered context */
|
|
1092
|
+
output: string;
|
|
1093
|
+
/** Tokens of `output` */
|
|
1094
|
+
tokens: number;
|
|
1095
|
+
style: PrContextStyle;
|
|
1096
|
+
mode: 'range' | 'staged' | 'working';
|
|
1097
|
+
base: PrRevision;
|
|
1098
|
+
head: PrRevision;
|
|
1099
|
+
mergeBase: { sha: string; short: string };
|
|
1100
|
+
/** Directory the change was limited to ('' for the whole repository) */
|
|
1101
|
+
scope: string;
|
|
1102
|
+
stats: {
|
|
1103
|
+
commits: number;
|
|
1104
|
+
files: number;
|
|
1105
|
+
byStatus: Record<string, number>;
|
|
1106
|
+
additions: number;
|
|
1107
|
+
deletions: number;
|
|
1108
|
+
excluded: number;
|
|
1109
|
+
changedMethods: number;
|
|
1110
|
+
addedMethods: number;
|
|
1111
|
+
deletedMethods: number;
|
|
1112
|
+
relatedTests: number;
|
|
1113
|
+
};
|
|
1114
|
+
/** Tokens per rendered section */
|
|
1115
|
+
sections: Record<string, number>;
|
|
1116
|
+
budget: { limit: number; dropped: string[]; over: boolean } | null;
|
|
1117
|
+
commits: PrCommit[];
|
|
1118
|
+
files: PrChangedFile[];
|
|
1119
|
+
methods: { changed: PrChangedMethod[]; deleted: PrMethod[] };
|
|
1120
|
+
relatedTests: PrRelatedTest[];
|
|
1121
|
+
/** Redacted matches per secret type */
|
|
1122
|
+
redactions: Record<string, number>;
|
|
1123
|
+
warnings: string[];
|
|
1124
|
+
}
|
|
1125
|
+
|
|
1126
|
+
/**
|
|
1127
|
+
* Build review context for a branch (merge base of base and head up to head), the staged
|
|
1128
|
+
* changes or the working tree
|
|
1129
|
+
*/
|
|
1130
|
+
export function buildPrContext(root?: string, options?: PrContextOptions): Promise<PrContextResult>;
|
|
1131
|
+
|
|
1132
|
+
// ============================================
|
|
1133
|
+
// ctxman why
|
|
1134
|
+
// ============================================
|
|
1135
|
+
|
|
1136
|
+
/**
|
|
1137
|
+
* Target of explainHistory() given as an object instead of "file:symbol" / "file#L1-L9"
|
|
1138
|
+
*/
|
|
1139
|
+
export interface ExplainHistoryTarget {
|
|
1140
|
+
file: string;
|
|
1141
|
+
/** Function, method or class: "total", "Cart.total", "Cart::total" */
|
|
1142
|
+
symbol?: string;
|
|
1143
|
+
startLine?: number;
|
|
1144
|
+
endLine?: number;
|
|
1145
|
+
}
|
|
1146
|
+
|
|
1147
|
+
export interface ExplainHistoryOptions {
|
|
1148
|
+
/** Commits to include (default 20) */
|
|
1149
|
+
limit?: number;
|
|
1150
|
+
/** Only commits after this date, in git's date syntax */
|
|
1151
|
+
since?: string;
|
|
1152
|
+
/** Explain the code as of this revision instead of the working tree */
|
|
1153
|
+
rev?: string;
|
|
1154
|
+
/** Include each commit's diff of the target */
|
|
1155
|
+
patches?: boolean;
|
|
1156
|
+
/** Commits of the file examined for co-changes (default 500, 0 = off) */
|
|
1157
|
+
couplingWindow?: number;
|
|
1158
|
+
/** Co-changed files listed (default 10) */
|
|
1159
|
+
couplingTop?: number;
|
|
1160
|
+
/** Commits touching more files are ignored for coupling (default 50) */
|
|
1161
|
+
maxFilesPerCommit?: number;
|
|
1162
|
+
/** Related text snippets listed (default 20) */
|
|
1163
|
+
maxRelated?: number;
|
|
1164
|
+
/** Test files listed (default 10) */
|
|
1165
|
+
maxTests?: number;
|
|
1166
|
+
style?: 'markdown' | 'xml' | 'json';
|
|
1167
|
+
/** Maximum tokens of the output */
|
|
1168
|
+
budget?: number;
|
|
1169
|
+
/** Question appended at the end of the document */
|
|
1170
|
+
ask?: string;
|
|
1171
|
+
/** Mask secrets (default true) */
|
|
1172
|
+
redact?: boolean;
|
|
1173
|
+
/** Directory relative target paths start from (default: root) */
|
|
1174
|
+
cwd?: string;
|
|
1175
|
+
}
|
|
1176
|
+
|
|
1177
|
+
export interface WhyCommit {
|
|
1178
|
+
sha: string;
|
|
1179
|
+
shortSha: string;
|
|
1180
|
+
/** Author date, ISO 8601 in UTC: 2024-01-02T10:00:00Z */
|
|
1181
|
+
date: string;
|
|
1182
|
+
author: string;
|
|
1183
|
+
email: string;
|
|
1184
|
+
merge: boolean;
|
|
1185
|
+
subject: string;
|
|
1186
|
+
body: string;
|
|
1187
|
+
/** Issue / ticket ids this commit mentions */
|
|
1188
|
+
refs: string[];
|
|
1189
|
+
patch?: string;
|
|
1190
|
+
/** Oldest commit a shallow clone has: its parents were not fetched */
|
|
1191
|
+
shallowBoundary?: boolean;
|
|
1192
|
+
}
|
|
1193
|
+
|
|
1194
|
+
export interface WhyIssueReference {
|
|
1195
|
+
/** "#12", or "owner/repo#12" for another repository */
|
|
1196
|
+
id: string;
|
|
1197
|
+
number: number;
|
|
1198
|
+
repo: string | null;
|
|
1199
|
+
kind: 'issue' | 'pr' | 'mr';
|
|
1200
|
+
/** Referred to with fixes / closes / resolves */
|
|
1201
|
+
closes: boolean;
|
|
1202
|
+
url: string | null;
|
|
1203
|
+
commits: string[];
|
|
1204
|
+
}
|
|
1205
|
+
|
|
1206
|
+
export interface ExplainHistoryData {
|
|
1207
|
+
target: {
|
|
1208
|
+
path: string;
|
|
1209
|
+
symbol: string | null;
|
|
1210
|
+
kind: string | null;
|
|
1211
|
+
line: number | null;
|
|
1212
|
+
resolvedBy: string | null;
|
|
1213
|
+
startLine: number | null;
|
|
1214
|
+
endLine: number | null;
|
|
1215
|
+
totalLines: number;
|
|
1216
|
+
wholeFile: boolean;
|
|
1217
|
+
binary: boolean;
|
|
1218
|
+
revision: string;
|
|
1219
|
+
symbolsInRange: string[];
|
|
1220
|
+
contentOmitted: string | null;
|
|
1221
|
+
source: string | null;
|
|
1222
|
+
};
|
|
1223
|
+
repository: { remote: string | null; provider: string | null; shallow: boolean };
|
|
1224
|
+
history: {
|
|
1225
|
+
mode: 'range' | 'funcname' | 'file' | 'none';
|
|
1226
|
+
startLine: number | null;
|
|
1227
|
+
endLine: number | null;
|
|
1228
|
+
funcname?: string;
|
|
1229
|
+
since: string | null;
|
|
1230
|
+
limit: number;
|
|
1231
|
+
limitReached: boolean;
|
|
1232
|
+
reason?: string;
|
|
1233
|
+
commits: WhyCommit[];
|
|
1234
|
+
};
|
|
1235
|
+
references: {
|
|
1236
|
+
issues: WhyIssueReference[];
|
|
1237
|
+
tickets: Array<{ id: string; commits: string[] }>;
|
|
1238
|
+
cves: Array<{ id: string; commits: string[] }>;
|
|
1239
|
+
urls: Array<{ url: string; commits: string[] }>;
|
|
1240
|
+
coAuthors: Array<{ value: string; commits: string[] }>;
|
|
1241
|
+
reviewers: Array<{ value: string; commits: string[] }>;
|
|
1242
|
+
};
|
|
1243
|
+
ownership: {
|
|
1244
|
+
startLine: number | null;
|
|
1245
|
+
endLine: number | null;
|
|
1246
|
+
totalLines: number;
|
|
1247
|
+
/** ISO 8601 in UTC, like the dates below */
|
|
1248
|
+
lastChanged: string | null;
|
|
1249
|
+
authors: Array<{
|
|
1250
|
+
name: string;
|
|
1251
|
+
lines: number;
|
|
1252
|
+
share: number;
|
|
1253
|
+
commits: number;
|
|
1254
|
+
lastTouched: string | null;
|
|
1255
|
+
}>;
|
|
1256
|
+
} | null;
|
|
1257
|
+
coupling: {
|
|
1258
|
+
window: number;
|
|
1259
|
+
targetChanges: number;
|
|
1260
|
+
skippedLargeCommits: number;
|
|
1261
|
+
maxFilesPerCommit: number;
|
|
1262
|
+
totalFiles: number;
|
|
1263
|
+
files: Array<{ path: string; count: number; confidence: number; exists: boolean }>;
|
|
1264
|
+
} | null;
|
|
1265
|
+
related: Array<{
|
|
1266
|
+
path: string;
|
|
1267
|
+
line: number;
|
|
1268
|
+
kind: 'adr' | 'changelog' | 'doc' | 'comment';
|
|
1269
|
+
mentions: 'symbol' | 'file';
|
|
1270
|
+
heading: string | null;
|
|
1271
|
+
snippet: string;
|
|
1272
|
+
}>;
|
|
1273
|
+
notes: Array<{ line: number; tag: string; text: string; author?: string }>;
|
|
1274
|
+
tests: Array<{
|
|
1275
|
+
path: string;
|
|
1276
|
+
references: 'symbol' | 'file';
|
|
1277
|
+
matches: Array<{ line: number; text: string }>;
|
|
1278
|
+
totalMatches: number;
|
|
1279
|
+
}>;
|
|
1280
|
+
warnings: string[];
|
|
1281
|
+
question: string | null;
|
|
1282
|
+
}
|
|
1283
|
+
|
|
1284
|
+
export interface ExplainHistoryResult {
|
|
1285
|
+
/** The rendered document */
|
|
1286
|
+
text: string;
|
|
1287
|
+
style: 'markdown' | 'xml' | 'json';
|
|
1288
|
+
tokens: number;
|
|
1289
|
+
budget: number | null;
|
|
1290
|
+
/** Items dropped to fit the budget, per section */
|
|
1291
|
+
omitted: Record<string, number>;
|
|
1292
|
+
warnings: string[];
|
|
1293
|
+
/** Everything collected (before budget trimming, after redaction) */
|
|
1294
|
+
data: ExplainHistoryData;
|
|
1295
|
+
}
|
|
1296
|
+
|
|
1297
|
+
/**
|
|
1298
|
+
* Explain why code looks the way it does, from the local git history: commits, referenced
|
|
1299
|
+
* issues and tickets, ownership, co-changed files, related docs, notes and tests.
|
|
1300
|
+
* Errors carry a `code` (NOT_A_GIT_REPO, PATH_OUTSIDE_ROOT, FILE_NOT_FOUND, NOT_TRACKED,
|
|
1301
|
+
* SYMBOL_NOT_FOUND, INVALID_RANGE, INVALID_REF, BUDGET_TOO_SMALL, ...)
|
|
1302
|
+
* @param root - Project directory inside a git work tree
|
|
1303
|
+
* @param target - "file", "file:symbol", "file#L10-L40" or an object
|
|
1304
|
+
*/
|
|
1305
|
+
export function explainHistory(
|
|
1306
|
+
root: string,
|
|
1307
|
+
target: string | ExplainHistoryTarget,
|
|
1308
|
+
options?: ExplainHistoryOptions
|
|
1309
|
+
): Promise<ExplainHistoryResult>;
|
|
1310
|
+
// Packed file contents (`ctxman pack`)
|
|
1311
|
+
// ============================================
|
|
1312
|
+
|
|
1313
|
+
export type PackStyle = 'xml' | 'markdown' | 'plain' | 'json';
|
|
1314
|
+
|
|
1315
|
+
export interface PackOptions {
|
|
1316
|
+
/** Output style (default: xml, Anthropic's `<documents>` long-context format) */
|
|
1317
|
+
style?: PackStyle;
|
|
1318
|
+
/** Gitignore-style globs: keep only matching files */
|
|
1319
|
+
include?: string[];
|
|
1320
|
+
/** Gitignore-style globs: leave matching files out */
|
|
1321
|
+
exclude?: string[];
|
|
1322
|
+
/**
|
|
1323
|
+
* Explicit file list instead of scanning the root. Entries must lie inside the root
|
|
1324
|
+
* (PATH_OUTSIDE_ROOT otherwise); .gitignore/.contextignore/.contextinclude still apply.
|
|
1325
|
+
*/
|
|
1326
|
+
files?: string[];
|
|
1327
|
+
/** Base directory for relative `files` entries (default: the root) */
|
|
1328
|
+
cwd?: string;
|
|
1329
|
+
/** Absolute paths to leave out (e.g. the output file) */
|
|
1330
|
+
excludeFiles?: string[];
|
|
1331
|
+
/** Skip files larger than this many bytes (default: 1 MiB) */
|
|
1332
|
+
maxFileSize?: number;
|
|
1333
|
+
/** Directory tree at the top (default: true) */
|
|
1334
|
+
tree?: boolean;
|
|
1335
|
+
/** Text at the top */
|
|
1336
|
+
header?: string;
|
|
1337
|
+
/** Text at the end, after the files (long documents first, the query last) */
|
|
1338
|
+
instructions?: string;
|
|
1339
|
+
/** Number every line with its original line number */
|
|
1340
|
+
lineNumbers?: boolean;
|
|
1341
|
+
/** Keep signatures, replace function bodies with a one-line placeholder */
|
|
1342
|
+
compress?: boolean;
|
|
1343
|
+
/** Mask secrets (default: true) */
|
|
1344
|
+
redact?: boolean;
|
|
1345
|
+
/**
|
|
1346
|
+
* Token limit for the whole rendered document: the highest-ranked files (ranking of
|
|
1347
|
+
* `ctxman map`) are packed first, the others are listed as omitted
|
|
1348
|
+
*/
|
|
1349
|
+
budget?: number;
|
|
1350
|
+
/** Token limit per part: adds `parts` to the result */
|
|
1351
|
+
split?: number;
|
|
1352
|
+
/** Count with this model's tiktoken encoding and report the fit in `model` */
|
|
1353
|
+
targetModel?: string;
|
|
1354
|
+
}
|
|
1355
|
+
|
|
1356
|
+
export interface PackedFile {
|
|
1357
|
+
/** Project-relative path with `/` separators */
|
|
1358
|
+
path: string;
|
|
1359
|
+
/** Tokens of the file's content as packed (after compression, numbering, redaction) */
|
|
1360
|
+
tokens: number;
|
|
1361
|
+
/** Lines of the original file */
|
|
1362
|
+
lines: number;
|
|
1363
|
+
compressed: boolean;
|
|
1364
|
+
}
|
|
1365
|
+
|
|
1366
|
+
export interface PackPart {
|
|
1367
|
+
/** 1-based part number */
|
|
1368
|
+
index: number;
|
|
1369
|
+
text: string;
|
|
1370
|
+
tokens: number;
|
|
1371
|
+
/** Files in the part; pieces of a file split by lines read "path (lines a-b)" */
|
|
1372
|
+
files: string[];
|
|
1373
|
+
}
|
|
1374
|
+
|
|
1375
|
+
export interface PackModelFit {
|
|
1376
|
+
id: string;
|
|
1377
|
+
name: string;
|
|
1378
|
+
vendor: string;
|
|
1379
|
+
/** tiktoken encoding used ('estimate' without tiktoken) */
|
|
1380
|
+
encoding: string;
|
|
1381
|
+
/** Whether the encoding is the model's own tokenizer */
|
|
1382
|
+
exact: boolean;
|
|
1383
|
+
contextWindow: number;
|
|
1384
|
+
maxRecommendedInput: number | null;
|
|
1385
|
+
fits: boolean;
|
|
1386
|
+
percentOfWindow: number;
|
|
1387
|
+
}
|
|
1388
|
+
|
|
1389
|
+
export interface PackResult {
|
|
1390
|
+
/** The whole document (also when it is split) */
|
|
1391
|
+
text: string;
|
|
1392
|
+
style: PackStyle;
|
|
1393
|
+
/** tiktoken encoding of every count ('estimate' without tiktoken) */
|
|
1394
|
+
encoding: string;
|
|
1395
|
+
/** Tokens of `text` */
|
|
1396
|
+
totalTokens: number;
|
|
1397
|
+
files: PackedFile[];
|
|
1398
|
+
/** Files left out by the budget, most important first */
|
|
1399
|
+
omitted: Array<{ path: string; tokens: number }>;
|
|
1400
|
+
/** Files not packed: binary, too-large, unreadable, missing, not-a-file, ignored */
|
|
1401
|
+
skipped: Array<{ path: string; reason: string }>;
|
|
1402
|
+
redactions: { total: number; byType: Record<string, number> };
|
|
1403
|
+
compression: {
|
|
1404
|
+
files: number;
|
|
1405
|
+
bodies: number;
|
|
1406
|
+
originalTokens: number;
|
|
1407
|
+
compressedTokens: number;
|
|
1408
|
+
savedTokens: number;
|
|
1409
|
+
} | null;
|
|
1410
|
+
budget: { limit: number; used: number } | null;
|
|
1411
|
+
model: PackModelFit | null;
|
|
1412
|
+
parts: PackPart[] | null;
|
|
1413
|
+
/** Files larger than a part on their own, split by lines */
|
|
1414
|
+
splitFiles: Array<{ path: string; pieces: number }>;
|
|
1415
|
+
}
|
|
1416
|
+
|
|
1417
|
+
/**
|
|
1418
|
+
* Pack the contents of a project's files into one document. Rejects with a PackError
|
|
1419
|
+
* (`code`: ROOT_NOT_FOUND, PATH_OUTSIDE_ROOT, INVALID_OPTION, UNKNOWN_MODEL,
|
|
1420
|
+
* BUDGET_TOO_SMALL, SPLIT_TOO_SMALL).
|
|
1421
|
+
*/
|
|
1422
|
+
export function packContext(root: string, options?: PackOptions): Promise<PackResult>;
|