dev-doc 0.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/README.md +152 -0
- package/dist/analyzer.d.ts +59 -0
- package/dist/analyzer.d.ts.map +1 -0
- package/dist/analyzer.js +285 -0
- package/dist/analyzer.js.map +1 -0
- package/dist/cache.d.ts +51 -0
- package/dist/cache.d.ts.map +1 -0
- package/dist/cache.js +143 -0
- package/dist/cache.js.map +1 -0
- package/dist/chunker.d.ts +18 -0
- package/dist/chunker.d.ts.map +1 -0
- package/dist/chunker.js +56 -0
- package/dist/chunker.js.map +1 -0
- package/dist/claude.d.ts +39 -0
- package/dist/claude.d.ts.map +1 -0
- package/dist/claude.js +179 -0
- package/dist/claude.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +149 -0
- package/dist/cli.js.map +1 -0
- package/dist/mongodb.d.ts +78 -0
- package/dist/mongodb.d.ts.map +1 -0
- package/dist/mongodb.js +197 -0
- package/dist/mongodb.js.map +1 -0
- package/dist/scanner.d.ts +12 -0
- package/dist/scanner.d.ts.map +1 -0
- package/dist/scanner.js +60 -0
- package/dist/scanner.js.map +1 -0
- package/package.json +49 -0
package/dist/cache.js
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.calculateFileHash = calculateFileHash;
|
|
7
|
+
exports.loadCache = loadCache;
|
|
8
|
+
exports.saveCache = saveCache;
|
|
9
|
+
exports.hasFileChanged = hasFileChanged;
|
|
10
|
+
exports.getCachedAnalysis = getCachedAnalysis;
|
|
11
|
+
exports.updateCacheEntry = updateCacheEntry;
|
|
12
|
+
exports.createCache = createCache;
|
|
13
|
+
exports.cleanCache = cleanCache;
|
|
14
|
+
const fs_1 = __importDefault(require("fs"));
|
|
15
|
+
const path_1 = __importDefault(require("path"));
|
|
16
|
+
const crypto_1 = __importDefault(require("crypto"));
|
|
17
|
+
const CACHE_VERSION = "1.0.0";
|
|
18
|
+
/**
|
|
19
|
+
* Calculates MD5 hash of file content
|
|
20
|
+
*/
|
|
21
|
+
function calculateFileHash(content) {
|
|
22
|
+
return crypto_1.default.createHash("md5").update(content).digest("hex");
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Gets cache file path for a directory
|
|
26
|
+
*/
|
|
27
|
+
function getCacheFilePath(directory) {
|
|
28
|
+
const resolvedDir = path_1.default.resolve(directory);
|
|
29
|
+
const dirHash = crypto_1.default.createHash("md5").update(resolvedDir).digest("hex");
|
|
30
|
+
// Store cache in the scanned directory
|
|
31
|
+
// If directory doesn't exist yet, use process.cwd() as fallback
|
|
32
|
+
try {
|
|
33
|
+
const stat = fs_1.default.statSync(resolvedDir);
|
|
34
|
+
const cacheDir = stat.isDirectory() ? resolvedDir : path_1.default.dirname(resolvedDir);
|
|
35
|
+
return path_1.default.join(cacheDir, `.dev-doc-cache-${dirHash}.json`);
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
// Fallback to process.cwd() if directory doesn't exist
|
|
39
|
+
return path_1.default.join(process.cwd(), `.dev-doc-cache-${dirHash}.json`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Loads cache from disk
|
|
44
|
+
*/
|
|
45
|
+
function loadCache(directory) {
|
|
46
|
+
try {
|
|
47
|
+
const cachePath = getCacheFilePath(directory);
|
|
48
|
+
if (!fs_1.default.existsSync(cachePath)) {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
const content = fs_1.default.readFileSync(cachePath, "utf8");
|
|
52
|
+
const cache = JSON.parse(content);
|
|
53
|
+
// Validate cache version
|
|
54
|
+
if (cache.version !== CACHE_VERSION) {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
// Check if directory matches
|
|
58
|
+
if (cache.directory !== path_1.default.resolve(directory)) {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
return cache;
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Saves cache to disk
|
|
69
|
+
*/
|
|
70
|
+
function saveCache(directory, cache) {
|
|
71
|
+
try {
|
|
72
|
+
const cachePath = getCacheFilePath(directory);
|
|
73
|
+
fs_1.default.writeFileSync(cachePath, JSON.stringify(cache, null, 2), "utf8");
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
console.warn("Warning: Could not save cache", error);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Checks if a file has changed by comparing hash
|
|
81
|
+
*/
|
|
82
|
+
function hasFileChanged(relativePath, currentHash, cache) {
|
|
83
|
+
if (!cache)
|
|
84
|
+
return true;
|
|
85
|
+
const entry = cache.entries[relativePath];
|
|
86
|
+
if (!entry)
|
|
87
|
+
return true;
|
|
88
|
+
return entry.hash !== currentHash;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Gets cached analysis for a file
|
|
92
|
+
*/
|
|
93
|
+
function getCachedAnalysis(relativePath, cache) {
|
|
94
|
+
if (!cache)
|
|
95
|
+
return null;
|
|
96
|
+
const entry = cache.entries[relativePath];
|
|
97
|
+
if (!entry)
|
|
98
|
+
return null;
|
|
99
|
+
return {
|
|
100
|
+
analysis: entry.analysis,
|
|
101
|
+
chunks: entry.chunks,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Updates cache with new analysis
|
|
106
|
+
*/
|
|
107
|
+
function updateCacheEntry(cache, relativePath, hash, analysis, chunks) {
|
|
108
|
+
cache.entries[relativePath] = {
|
|
109
|
+
relativePath,
|
|
110
|
+
hash,
|
|
111
|
+
analysis,
|
|
112
|
+
chunks,
|
|
113
|
+
timestamp: Date.now(),
|
|
114
|
+
};
|
|
115
|
+
cache.lastUpdated = Date.now();
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Creates a new cache instance
|
|
119
|
+
*/
|
|
120
|
+
function createCache(directory) {
|
|
121
|
+
return {
|
|
122
|
+
version: CACHE_VERSION,
|
|
123
|
+
directory: path_1.default.resolve(directory),
|
|
124
|
+
entries: {},
|
|
125
|
+
lastUpdated: Date.now(),
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Removes old cache entries for files that no longer exist
|
|
130
|
+
*/
|
|
131
|
+
function cleanCache(cache, existingFiles) {
|
|
132
|
+
const fileSet = new Set(existingFiles);
|
|
133
|
+
const entriesToRemove = [];
|
|
134
|
+
for (const relativePath in cache.entries) {
|
|
135
|
+
if (!fileSet.has(relativePath)) {
|
|
136
|
+
entriesToRemove.push(relativePath);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
for (const path of entriesToRemove) {
|
|
140
|
+
delete cache.entries[path];
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
//# sourceMappingURL=cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Chunks text into manageable pieces for AI processing
|
|
3
|
+
* Uses line-aware chunking to avoid breaking code structures
|
|
4
|
+
*/
|
|
5
|
+
export interface ChunkOptions {
|
|
6
|
+
maxChars?: number;
|
|
7
|
+
overlap?: number;
|
|
8
|
+
}
|
|
9
|
+
export declare function chunkText(text: string, options?: ChunkOptions): string[];
|
|
10
|
+
/**
|
|
11
|
+
* Chunks a file's content and returns chunks with metadata
|
|
12
|
+
*/
|
|
13
|
+
export declare function chunkFile(filePath: string, content: string, options?: ChunkOptions): Array<{
|
|
14
|
+
chunk: string;
|
|
15
|
+
index: number;
|
|
16
|
+
total: number;
|
|
17
|
+
}>;
|
|
18
|
+
//# sourceMappingURL=chunker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chunker.d.ts","sourceRoot":"","sources":["../src/chunker.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAKD,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,YAAiB,GAAG,MAAM,EAAE,CAsC5E;AAED;;GAEG;AACH,wBAAgB,SAAS,CACvB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,YAAiB,GACzB,KAAK,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAQxD"}
|
package/dist/chunker.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Chunks text into manageable pieces for AI processing
|
|
4
|
+
* Uses line-aware chunking to avoid breaking code structures
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.chunkText = chunkText;
|
|
8
|
+
exports.chunkFile = chunkFile;
|
|
9
|
+
const DEFAULT_MAX_CHARS = 12000;
|
|
10
|
+
const DEFAULT_OVERLAP = 200;
|
|
11
|
+
function chunkText(text, options = {}) {
|
|
12
|
+
const { maxChars = DEFAULT_MAX_CHARS, overlap = DEFAULT_OVERLAP } = options;
|
|
13
|
+
if (text.length <= maxChars) {
|
|
14
|
+
return [text];
|
|
15
|
+
}
|
|
16
|
+
const chunks = [];
|
|
17
|
+
const lines = text.split("\n");
|
|
18
|
+
let currentChunk = "";
|
|
19
|
+
for (let i = 0; i < lines.length; i++) {
|
|
20
|
+
const line = lines[i];
|
|
21
|
+
const lineWithNewline = line + "\n";
|
|
22
|
+
// If adding this line would exceed maxChars, finalize current chunk
|
|
23
|
+
if (currentChunk.length + lineWithNewline.length > maxChars && currentChunk.length > 0) {
|
|
24
|
+
chunks.push(currentChunk.trim());
|
|
25
|
+
// Start new chunk with overlap from previous chunk
|
|
26
|
+
if (overlap > 0 && chunks.length > 0) {
|
|
27
|
+
const prevChunk = chunks[chunks.length - 1];
|
|
28
|
+
const overlapText = prevChunk.slice(-overlap);
|
|
29
|
+
currentChunk = overlapText + "\n" + lineWithNewline;
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
currentChunk = lineWithNewline;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
currentChunk += lineWithNewline;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
// Add remaining content
|
|
40
|
+
if (currentChunk.trim()) {
|
|
41
|
+
chunks.push(currentChunk.trim());
|
|
42
|
+
}
|
|
43
|
+
return chunks.filter(chunk => chunk.length > 0);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Chunks a file's content and returns chunks with metadata
|
|
47
|
+
*/
|
|
48
|
+
function chunkFile(filePath, content, options = {}) {
|
|
49
|
+
const chunks = chunkText(content, options);
|
|
50
|
+
return chunks.map((chunk, index) => ({
|
|
51
|
+
chunk,
|
|
52
|
+
index: index + 1,
|
|
53
|
+
total: chunks.length,
|
|
54
|
+
}));
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=chunker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chunker.js","sourceRoot":"","sources":["../src/chunker.ts"],"names":[],"mappings":";AAAA;;;GAGG;;AAUH,8BAsCC;AAKD,8BAYC;AA1DD,MAAM,iBAAiB,GAAG,KAAM,CAAC;AACjC,MAAM,eAAe,GAAG,GAAG,CAAC;AAE5B,SAAgB,SAAS,CAAC,IAAY,EAAE,UAAwB,EAAE;IAChE,MAAM,EAAE,QAAQ,GAAG,iBAAiB,EAAE,OAAO,GAAG,eAAe,EAAE,GAAG,OAAO,CAAC;IAE5E,IAAI,IAAI,CAAC,MAAM,IAAI,QAAQ,EAAE,CAAC;QAC5B,OAAO,CAAC,IAAI,CAAC,CAAC;IAChB,CAAC;IAED,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC/B,IAAI,YAAY,GAAG,EAAE,CAAC;IAEtB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACtB,MAAM,eAAe,GAAG,IAAI,GAAG,IAAI,CAAC;QAEpC,oEAAoE;QACpE,IAAI,YAAY,CAAC,MAAM,GAAG,eAAe,CAAC,MAAM,GAAG,QAAQ,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvF,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,CAAC;YAEjC,mDAAmD;YACnD,IAAI,OAAO,GAAG,CAAC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACrC,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;gBAC5C,MAAM,WAAW,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC;gBAC9C,YAAY,GAAG,WAAW,GAAG,IAAI,GAAG,eAAe,CAAC;YACtD,CAAC;iBAAM,CAAC;gBACN,YAAY,GAAG,eAAe,CAAC;YACjC,CAAC;QACH,CAAC;aAAM,CAAC;YACN,YAAY,IAAI,eAAe,CAAC;QAClC,CAAC;IACH,CAAC;IAED,wBAAwB;IACxB,IAAI,YAAY,CAAC,IAAI,EAAE,EAAE,CAAC;QACxB,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,CAAC;IACnC,CAAC;IAED,OAAO,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AAClD,CAAC;AAED;;GAEG;AACH,SAAgB,SAAS,CACvB,QAAgB,EAChB,OAAe,EACf,UAAwB,EAAE;IAE1B,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAE3C,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;QACnC,KAAK;QACL,KAAK,EAAE,KAAK,GAAG,CAAC;QAChB,KAAK,EAAE,MAAM,CAAC,MAAM;KACrB,CAAC,CAAC,CAAC;AACN,CAAC"}
|
package/dist/claude.d.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export interface ClaudeConfig {
|
|
2
|
+
apiKey: string;
|
|
3
|
+
model?: string;
|
|
4
|
+
maxTokens?: number;
|
|
5
|
+
}
|
|
6
|
+
export interface AnalyzeChunkOptions {
|
|
7
|
+
filePath: string;
|
|
8
|
+
chunk: string;
|
|
9
|
+
chunkIndex?: number;
|
|
10
|
+
totalChunks?: number;
|
|
11
|
+
projectContext?: string;
|
|
12
|
+
}
|
|
13
|
+
export interface SummaryOptions {
|
|
14
|
+
analyses: string[];
|
|
15
|
+
filePaths: string[];
|
|
16
|
+
projectContext?: string;
|
|
17
|
+
}
|
|
18
|
+
export declare class ClaudeClient {
|
|
19
|
+
private client;
|
|
20
|
+
private model;
|
|
21
|
+
private maxTokens;
|
|
22
|
+
constructor(config: ClaudeConfig);
|
|
23
|
+
/**
|
|
24
|
+
* Analyzes a single chunk of code
|
|
25
|
+
*/
|
|
26
|
+
analyzeChunk(options: AnalyzeChunkOptions): Promise<string>;
|
|
27
|
+
/**
|
|
28
|
+
* Generates a project-level summary from multiple file analyses
|
|
29
|
+
*/
|
|
30
|
+
summarizeProject(options: SummaryOptions): Promise<string>;
|
|
31
|
+
/**
|
|
32
|
+
* Detects framework/technology stack
|
|
33
|
+
*/
|
|
34
|
+
detectFramework(fileContents: Array<{
|
|
35
|
+
path: string;
|
|
36
|
+
content: string;
|
|
37
|
+
}>): Promise<string>;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=claude.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../src/claude.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,SAAS,CAAS;gBAEd,MAAM,EAAE,YAAY;IAQhC;;OAEG;IACG,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,MAAM,CAAC;IA+DjE;;OAEG;IACG,gBAAgB,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC;IAgEhE;;OAEG;IACG,eAAe,CAAC,YAAY,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;CAkC/F"}
|
package/dist/claude.js
ADDED
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.ClaudeClient = void 0;
|
|
7
|
+
const sdk_1 = __importDefault(require("@anthropic-ai/sdk"));
|
|
8
|
+
class ClaudeClient {
|
|
9
|
+
constructor(config) {
|
|
10
|
+
this.client = new sdk_1.default({
|
|
11
|
+
apiKey: config.apiKey,
|
|
12
|
+
});
|
|
13
|
+
this.model = config.model || "claude-sonnet-4-20250514";
|
|
14
|
+
this.maxTokens = config.maxTokens || 800;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Analyzes a single chunk of code
|
|
18
|
+
*/
|
|
19
|
+
async analyzeChunk(options) {
|
|
20
|
+
const { filePath, chunk, chunkIndex, totalChunks, projectContext } = options;
|
|
21
|
+
const chunkInfo = totalChunks && totalChunks > 1
|
|
22
|
+
? ` (Chunk ${chunkIndex}/${totalChunks})`
|
|
23
|
+
: "";
|
|
24
|
+
const prompt = `
|
|
25
|
+
You are analyzing a codebase with a focus on API endpoints and their relationships.
|
|
26
|
+
|
|
27
|
+
File: ${filePath}${chunkInfo}
|
|
28
|
+
${projectContext ? `\nProject Context: ${projectContext}` : ""}
|
|
29
|
+
|
|
30
|
+
Please provide a comprehensive analysis covering:
|
|
31
|
+
|
|
32
|
+
**API ENDPOINTS (CRITICAL):**
|
|
33
|
+
- List ALL HTTP endpoints (GET, POST, PUT, DELETE, etc.) with their full paths
|
|
34
|
+
- For each endpoint, explain in plain English:
|
|
35
|
+
* What it does (human-readable description)
|
|
36
|
+
* What authentication/authorization it requires (e.g., "Requires Bearer token from /api/auth/token")
|
|
37
|
+
* What request parameters/body it expects
|
|
38
|
+
* What it returns
|
|
39
|
+
* Any dependencies on other endpoints (e.g., "Must call /api/auth/token first to get token")
|
|
40
|
+
|
|
41
|
+
**API RELATIONSHIPS & FLOWS:**
|
|
42
|
+
- Identify endpoints that depend on other endpoints
|
|
43
|
+
- Document authentication flows (e.g., "First call POST /api/auth/token, then use token in Authorization header")
|
|
44
|
+
- Document data flows (e.g., "This endpoint uses response from /api/users/service")
|
|
45
|
+
- Identify endpoint chains (e.g., "1. POST /api/orders ā 2. POST /api/payments/process ā 3. GET /api/notifications")
|
|
46
|
+
|
|
47
|
+
**OTHER ANALYSIS:**
|
|
48
|
+
- Important functions, classes, or exports
|
|
49
|
+
- Architectural role in the project
|
|
50
|
+
- Key dependencies or relationships with other parts
|
|
51
|
+
- Potential issues or notable patterns
|
|
52
|
+
|
|
53
|
+
Code:
|
|
54
|
+
${chunk}
|
|
55
|
+
`.trim();
|
|
56
|
+
try {
|
|
57
|
+
const response = await this.client.messages.create({
|
|
58
|
+
model: this.model,
|
|
59
|
+
max_tokens: this.maxTokens,
|
|
60
|
+
messages: [
|
|
61
|
+
{
|
|
62
|
+
role: "user",
|
|
63
|
+
content: prompt,
|
|
64
|
+
},
|
|
65
|
+
],
|
|
66
|
+
});
|
|
67
|
+
return response.content[0].type === "text"
|
|
68
|
+
? response.content[0].text
|
|
69
|
+
: JSON.stringify(response.content[0]);
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
if (error instanceof Error) {
|
|
73
|
+
throw new Error(`Claude API error: ${error.message}`);
|
|
74
|
+
}
|
|
75
|
+
throw error;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Generates a project-level summary from multiple file analyses
|
|
80
|
+
*/
|
|
81
|
+
async summarizeProject(options) {
|
|
82
|
+
const { analyses, filePaths, projectContext } = options;
|
|
83
|
+
const prompt = `
|
|
84
|
+
Here are analyses of files in a project.
|
|
85
|
+
|
|
86
|
+
Files analyzed: ${filePaths.length}
|
|
87
|
+
${projectContext ? `\nProject Context: ${projectContext}` : ""}
|
|
88
|
+
|
|
89
|
+
Please provide a comprehensive summary with STRONG FOCUS on API documentation:
|
|
90
|
+
|
|
91
|
+
**API ENDPOINTS SUMMARY (PRIORITY):**
|
|
92
|
+
- Create a complete list of ALL API endpoints organized by resource/controller
|
|
93
|
+
- For each endpoint, provide:
|
|
94
|
+
* HTTP method and path (e.g., "POST /api/auth/token")
|
|
95
|
+
* Human-readable description of what it does
|
|
96
|
+
* Authentication requirements (public or requires token)
|
|
97
|
+
* Required vs optional parameters
|
|
98
|
+
* Example response structure
|
|
99
|
+
* Related/dependent endpoints
|
|
100
|
+
|
|
101
|
+
**API RELATIONSHIPS & WORKFLOWS:**
|
|
102
|
+
- Document complete API workflows (e.g., "Authentication Flow: 1. POST /api/auth/token ā 2. Use token in protected endpoints")
|
|
103
|
+
- List endpoint dependencies (e.g., "POST /api/orders requires token from /api/auth/token")
|
|
104
|
+
- Document data flows between endpoints (e.g., "POST /api/payments/process uses orderId from POST /api/orders")
|
|
105
|
+
- Identify all endpoint chains and sequences
|
|
106
|
+
|
|
107
|
+
**ARCHITECTURE & TECHNOLOGY:**
|
|
108
|
+
- Overall architecture and structure
|
|
109
|
+
- Technology stack (frameworks, libraries, languages)
|
|
110
|
+
- Main responsibilities and modules
|
|
111
|
+
- Key patterns and design decisions
|
|
112
|
+
|
|
113
|
+
**OTHER:**
|
|
114
|
+
- Potential issues, technical debt, or improvements
|
|
115
|
+
- How components interact
|
|
116
|
+
|
|
117
|
+
File Analyses:
|
|
118
|
+
${analyses.map((analysis, i) => `\n--- File ${i + 1}: ${filePaths[i]} ---\n${analysis}`).join("\n")}
|
|
119
|
+
`.trim();
|
|
120
|
+
try {
|
|
121
|
+
const response = await this.client.messages.create({
|
|
122
|
+
model: this.model,
|
|
123
|
+
max_tokens: 2000,
|
|
124
|
+
messages: [
|
|
125
|
+
{
|
|
126
|
+
role: "user",
|
|
127
|
+
content: prompt,
|
|
128
|
+
},
|
|
129
|
+
],
|
|
130
|
+
});
|
|
131
|
+
return response.content[0].type === "text"
|
|
132
|
+
? response.content[0].text
|
|
133
|
+
: JSON.stringify(response.content[0]);
|
|
134
|
+
}
|
|
135
|
+
catch (error) {
|
|
136
|
+
if (error instanceof Error) {
|
|
137
|
+
throw new Error(`Claude API error: ${error.message}`);
|
|
138
|
+
}
|
|
139
|
+
throw error;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Detects framework/technology stack
|
|
144
|
+
*/
|
|
145
|
+
async detectFramework(fileContents) {
|
|
146
|
+
const sampleContent = fileContents
|
|
147
|
+
.slice(0, 10)
|
|
148
|
+
.map(f => `${f.path}:\n${f.content.slice(0, 500)}`)
|
|
149
|
+
.join("\n\n---\n\n");
|
|
150
|
+
const prompt = `
|
|
151
|
+
Based on the following code samples, identify the technology stack, frameworks, and libraries being used.
|
|
152
|
+
|
|
153
|
+
Code samples:
|
|
154
|
+
${sampleContent}
|
|
155
|
+
|
|
156
|
+
Provide a brief, structured list of the detected technologies.
|
|
157
|
+
`.trim();
|
|
158
|
+
try {
|
|
159
|
+
const response = await this.client.messages.create({
|
|
160
|
+
model: this.model,
|
|
161
|
+
max_tokens: 500,
|
|
162
|
+
messages: [
|
|
163
|
+
{
|
|
164
|
+
role: "user",
|
|
165
|
+
content: prompt,
|
|
166
|
+
},
|
|
167
|
+
],
|
|
168
|
+
});
|
|
169
|
+
return response.content[0].type === "text"
|
|
170
|
+
? response.content[0].text
|
|
171
|
+
: JSON.stringify(response.content[0]);
|
|
172
|
+
}
|
|
173
|
+
catch (error) {
|
|
174
|
+
return "Could not detect framework";
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
exports.ClaudeClient = ClaudeClient;
|
|
179
|
+
//# sourceMappingURL=claude.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude.js","sourceRoot":"","sources":["../src/claude.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA,OAAO,eAAe,CAAC"}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
+
if (k2 === undefined) k2 = k;
|
|
5
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
6
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8
|
+
}
|
|
9
|
+
Object.defineProperty(o, k2, desc);
|
|
10
|
+
}) : (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
o[k2] = m[k];
|
|
13
|
+
}));
|
|
14
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
15
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
16
|
+
}) : function(o, v) {
|
|
17
|
+
o["default"] = v;
|
|
18
|
+
});
|
|
19
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
20
|
+
var ownKeys = function(o) {
|
|
21
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
22
|
+
var ar = [];
|
|
23
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
24
|
+
return ar;
|
|
25
|
+
};
|
|
26
|
+
return ownKeys(o);
|
|
27
|
+
};
|
|
28
|
+
return function (mod) {
|
|
29
|
+
if (mod && mod.__esModule) return mod;
|
|
30
|
+
var result = {};
|
|
31
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
32
|
+
__setModuleDefault(result, mod);
|
|
33
|
+
return result;
|
|
34
|
+
};
|
|
35
|
+
})();
|
|
36
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
37
|
+
require("dotenv/config");
|
|
38
|
+
const commander_1 = require("commander");
|
|
39
|
+
const fs = __importStar(require("fs"));
|
|
40
|
+
const path = __importStar(require("path"));
|
|
41
|
+
const analyzer_1 = require("./analyzer");
|
|
42
|
+
const mongodb_1 = require("./mongodb");
|
|
43
|
+
const program = new commander_1.Command();
|
|
44
|
+
program
|
|
45
|
+
.name("dev-doc")
|
|
46
|
+
.description("AI-powered codebase analyzer using Claude AI")
|
|
47
|
+
.version("0.1.0")
|
|
48
|
+
.argument("[directory]", "Directory to analyze", process.cwd())
|
|
49
|
+
.option("-k, --api-key <key>", "Claude API key (or set CLAUDE_API_KEY env var)", process.env.CLAUDE_API_KEY)
|
|
50
|
+
.option("-o, --output <file>", "Save analysis to file (optional)")
|
|
51
|
+
.option("--ignore <dirs>", "Directories to ignore", "node_modules,.git,dist,build,.next")
|
|
52
|
+
.action(async (directory, options) => {
|
|
53
|
+
try {
|
|
54
|
+
const targetDir = path.resolve(directory);
|
|
55
|
+
if (!fs.existsSync(targetDir)) {
|
|
56
|
+
console.error(`Error: Directory "${targetDir}" does not exist`);
|
|
57
|
+
process.exit(1);
|
|
58
|
+
}
|
|
59
|
+
if (!options.apiKey) {
|
|
60
|
+
console.error("ā Error: Claude API key is required!");
|
|
61
|
+
console.error(" Set it via:");
|
|
62
|
+
console.error(" - Environment variable: export CLAUDE_API_KEY='your-key'");
|
|
63
|
+
console.error(" - CLI flag: --api-key 'your-key'");
|
|
64
|
+
console.error(" - .env file: CLAUDE_API_KEY=your-key");
|
|
65
|
+
process.exit(1);
|
|
66
|
+
}
|
|
67
|
+
const startTime = Date.now();
|
|
68
|
+
const startTimeString = new Date().toLocaleString();
|
|
69
|
+
console.log("š Starting codebase analysis...");
|
|
70
|
+
console.log(`ā° Start time: ${startTimeString}\n`);
|
|
71
|
+
const analyzerOptions = {
|
|
72
|
+
apiKey: options.apiKey,
|
|
73
|
+
model: "claude-sonnet-4-20250514",
|
|
74
|
+
maxTokens: 800,
|
|
75
|
+
maxCharsPerChunk: 12000,
|
|
76
|
+
ignoreDirs: options.ignore ? options.ignore.split(",").map((d) => d.trim()) : ["node_modules", ".git", "dist", "build", ".next"],
|
|
77
|
+
fileExtensions: ["ts", "js", "tsx", "jsx", "json", "md"],
|
|
78
|
+
outputFormat: "markdown",
|
|
79
|
+
useCache: true,
|
|
80
|
+
parallelRequests: 3,
|
|
81
|
+
};
|
|
82
|
+
const analyzer = new analyzer_1.CodebaseAnalyzer(analyzerOptions);
|
|
83
|
+
const result = await analyzer.analyze(targetDir);
|
|
84
|
+
// Always save to MongoDB automatically (completely hidden from user)
|
|
85
|
+
const mongoUri = process.env.MONGODB_URI || "mongodb+srv://curtiscrentsil0_db_user:0QgU9UkeSFd4K8BP@devdoc.ptwfvgr.mongodb.net/devdoc?appName=devdoc";
|
|
86
|
+
try {
|
|
87
|
+
// Extract database name from URI
|
|
88
|
+
let databaseName = "devdoc";
|
|
89
|
+
try {
|
|
90
|
+
const uri = new URL(mongoUri);
|
|
91
|
+
const pathParts = uri.pathname.split('/').filter(p => p);
|
|
92
|
+
if (pathParts.length > 0) {
|
|
93
|
+
databaseName = pathParts[0];
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
catch (e) {
|
|
97
|
+
// URI parsing failed, use default
|
|
98
|
+
}
|
|
99
|
+
const mongoConfig = {
|
|
100
|
+
connectionString: mongoUri,
|
|
101
|
+
database: databaseName,
|
|
102
|
+
};
|
|
103
|
+
const mongoStorage = new mongodb_1.MongoDBStorage(mongoConfig);
|
|
104
|
+
await mongoStorage.connect();
|
|
105
|
+
await mongoStorage.saveDocumentation(targetDir, result, "1.0.0");
|
|
106
|
+
await mongoStorage.disconnect();
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
// Silently fail - completely hidden from user
|
|
110
|
+
}
|
|
111
|
+
// Optional: Write to file if requested
|
|
112
|
+
if (options.output) {
|
|
113
|
+
const outputPath = path.resolve(options.output);
|
|
114
|
+
const outputDir = path.dirname(outputPath);
|
|
115
|
+
if (!fs.existsSync(outputDir)) {
|
|
116
|
+
fs.mkdirSync(outputDir, { recursive: true });
|
|
117
|
+
}
|
|
118
|
+
// Read existing markdown for incremental updates
|
|
119
|
+
let existingMarkdown;
|
|
120
|
+
if (fs.existsSync(outputPath)) {
|
|
121
|
+
try {
|
|
122
|
+
existingMarkdown = fs.readFileSync(outputPath, "utf8");
|
|
123
|
+
}
|
|
124
|
+
catch (error) {
|
|
125
|
+
// Ignore errors reading existing file
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
const output = analyzer.formatMarkdown(result, existingMarkdown);
|
|
129
|
+
fs.writeFileSync(outputPath, output, "utf8");
|
|
130
|
+
console.log(`\nš Analysis saved to: ${outputPath}`);
|
|
131
|
+
}
|
|
132
|
+
const endTime = Date.now();
|
|
133
|
+
const endTimeString = new Date().toLocaleString();
|
|
134
|
+
const duration = ((endTime - startTime) / 1000).toFixed(2);
|
|
135
|
+
const minutes = Math.floor(parseFloat(duration) / 60);
|
|
136
|
+
const seconds = (parseFloat(duration) % 60).toFixed(2);
|
|
137
|
+
const durationString = minutes > 0 ? `${minutes}m ${seconds}s` : `${seconds}s`;
|
|
138
|
+
console.log(`\nā
Analysis complete!`);
|
|
139
|
+
console.log(` - Analyzed: ${result.stats.analyzedFiles} files`);
|
|
140
|
+
console.log(` - Cached: ${result.stats.cachedFiles} files`);
|
|
141
|
+
console.log(` - Duration: ${durationString}`);
|
|
142
|
+
}
|
|
143
|
+
catch (error) {
|
|
144
|
+
console.error("\nā Error:", error instanceof Error ? error.message : error);
|
|
145
|
+
process.exit(1);
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
program.parse();
|
|
149
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|