@kernel.chat/kbot 3.36.0 → 3.37.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/dist/codebase-guardian.d.ts +64 -0
- package/dist/codebase-guardian.d.ts.map +1 -0
- package/dist/codebase-guardian.js +486 -0
- package/dist/codebase-guardian.js.map +1 -0
- package/dist/dream-mode.d.ts +23 -0
- package/dist/dream-mode.d.ts.map +1 -0
- package/dist/dream-mode.js +352 -0
- package/dist/dream-mode.js.map +1 -0
- package/dist/meta-agent.d.ts +62 -0
- package/dist/meta-agent.d.ts.map +1 -0
- package/dist/meta-agent.js +288 -0
- package/dist/meta-agent.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
export type FindingType = 'duplicate-pattern' | 'co-change' | 'complexity';
|
|
2
|
+
export interface GuardianFinding {
|
|
3
|
+
type: FindingType;
|
|
4
|
+
severity: 'info' | 'warn' | 'critical';
|
|
5
|
+
title: string;
|
|
6
|
+
description: string;
|
|
7
|
+
files: string[];
|
|
8
|
+
/** The repeated code snippet (for duplicate-pattern findings) */
|
|
9
|
+
pattern?: string;
|
|
10
|
+
/** Occurrence count (for duplicate-pattern findings) */
|
|
11
|
+
occurrences?: number;
|
|
12
|
+
/** Metric value (for complexity findings — e.g., function length) */
|
|
13
|
+
metric?: number;
|
|
14
|
+
/** Suggested action */
|
|
15
|
+
suggestion: string;
|
|
16
|
+
foundAt: string;
|
|
17
|
+
}
|
|
18
|
+
export interface GuardianReport {
|
|
19
|
+
analyzedAt: string;
|
|
20
|
+
rootDir: string;
|
|
21
|
+
filesScanned: number;
|
|
22
|
+
findings: GuardianFinding[];
|
|
23
|
+
summary: {
|
|
24
|
+
duplicates: number;
|
|
25
|
+
coChanges: number;
|
|
26
|
+
complexityWarnings: number;
|
|
27
|
+
totalFindings: number;
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
export interface ForgedGuardianTool {
|
|
31
|
+
name: string;
|
|
32
|
+
description: string;
|
|
33
|
+
finding: GuardianFinding;
|
|
34
|
+
detectPattern: string;
|
|
35
|
+
createdAt: string;
|
|
36
|
+
}
|
|
37
|
+
interface HistoryEntry {
|
|
38
|
+
report: GuardianReport;
|
|
39
|
+
forgedTools: string[];
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Run the Codebase Guardian on a directory.
|
|
43
|
+
*
|
|
44
|
+
* Scans for:
|
|
45
|
+
* - Duplicate code patterns (3+ occurrences across files)
|
|
46
|
+
* - Files that always change together (from git history)
|
|
47
|
+
* - Growing complexity (function length, nesting depth)
|
|
48
|
+
*
|
|
49
|
+
* Returns a structured report with all findings.
|
|
50
|
+
*/
|
|
51
|
+
export declare function runGuardian(path: string): Promise<GuardianReport>;
|
|
52
|
+
/**
|
|
53
|
+
* When the guardian finds a recurring pattern, forge a tool to detect (and
|
|
54
|
+
* optionally fix) that specific pattern in the future.
|
|
55
|
+
*
|
|
56
|
+
* The forged tool is saved to ~/.kbot/forge/guardian-{name}.json.
|
|
57
|
+
*/
|
|
58
|
+
export declare function forgeGuardianTool(finding: GuardianFinding): ForgedGuardianTool;
|
|
59
|
+
/**
|
|
60
|
+
* Get history of guardian reports and forged tools.
|
|
61
|
+
*/
|
|
62
|
+
export declare function getGuardianHistory(): HistoryEntry[];
|
|
63
|
+
export {};
|
|
64
|
+
//# sourceMappingURL=codebase-guardian.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codebase-guardian.d.ts","sourceRoot":"","sources":["../src/codebase-guardian.ts"],"names":[],"mappings":"AAsBA,MAAM,MAAM,WAAW,GAAG,mBAAmB,GAAG,WAAW,GAAG,YAAY,CAAA;AAE1E,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,WAAW,CAAA;IACjB,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,UAAU,CAAA;IACtC,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;IACnB,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,iEAAiE;IACjE,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,wDAAwD;IACxD,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,qEAAqE;IACrE,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,uBAAuB;IACvB,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;IACf,YAAY,EAAE,MAAM,CAAA;IACpB,QAAQ,EAAE,eAAe,EAAE,CAAA;IAC3B,OAAO,EAAE;QACP,UAAU,EAAE,MAAM,CAAA;QAClB,SAAS,EAAE,MAAM,CAAA;QACjB,kBAAkB,EAAE,MAAM,CAAA;QAC1B,aAAa,EAAE,MAAM,CAAA;KACtB,CAAA;CACF;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE,eAAe,CAAA;IACxB,aAAa,EAAE,MAAM,CAAA;IACrB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,UAAU,YAAY;IACpB,MAAM,EAAE,cAAc,CAAA;IACtB,WAAW,EAAE,MAAM,EAAE,CAAA;CACtB;AA2ZD;;;;;;;;;GASG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CA8CvE;AAID;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,eAAe,GAAG,kBAAkB,CA8D9E;AAID;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,YAAY,EAAE,CAEnD"}
|
|
@@ -0,0 +1,486 @@
|
|
|
1
|
+
// kbot Codebase Guardian — Self-evolving code quality system
|
|
2
|
+
//
|
|
3
|
+
// Watches a codebase for:
|
|
4
|
+
// - Repeated code patterns (3+ occurrences) → suggests extraction
|
|
5
|
+
// - Files that always change together → suggests co-location
|
|
6
|
+
// - Growing complexity (long functions, deep nesting) → suggests refactoring
|
|
7
|
+
//
|
|
8
|
+
// When the guardian finds a recurring pattern, it forges a tool to detect/fix
|
|
9
|
+
// that specific pattern in the future. Tools are saved to ~/.kbot/forge/.
|
|
10
|
+
//
|
|
11
|
+
// Usage:
|
|
12
|
+
// import { runGuardian, forgeGuardianTool, getGuardianHistory } from './codebase-guardian.js'
|
|
13
|
+
// const report = await runGuardian('/path/to/project')
|
|
14
|
+
// forgeGuardianTool(report.findings[0])
|
|
15
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync, readdirSync, statSync } from 'node:fs';
|
|
16
|
+
import { join, relative, extname } from 'node:path';
|
|
17
|
+
import { homedir } from 'node:os';
|
|
18
|
+
import { execSync } from 'node:child_process';
|
|
19
|
+
// ── Paths ──
|
|
20
|
+
const FORGE_DIR = join(homedir(), '.kbot', 'forge');
|
|
21
|
+
const HISTORY_PATH = join(homedir(), '.kbot', 'guardian-history.json');
|
|
22
|
+
function ensureDir(dir) {
|
|
23
|
+
if (!existsSync(dir))
|
|
24
|
+
mkdirSync(dir, { recursive: true });
|
|
25
|
+
}
|
|
26
|
+
// ── JSON helpers ──
|
|
27
|
+
function loadJsonSafe(path, fallback) {
|
|
28
|
+
if (!existsSync(path))
|
|
29
|
+
return fallback;
|
|
30
|
+
try {
|
|
31
|
+
return JSON.parse(readFileSync(path, 'utf-8'));
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return fallback;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
function saveJson(path, data) {
|
|
38
|
+
const dir = path.replace(/\/[^/]+$/, '');
|
|
39
|
+
ensureDir(dir);
|
|
40
|
+
writeFileSync(path, JSON.stringify(data, null, 2), 'utf-8');
|
|
41
|
+
}
|
|
42
|
+
// ── File walking ──
|
|
43
|
+
const IGNORED_DIRS = new Set([
|
|
44
|
+
'node_modules', '.git', 'dist', 'build', 'out', '.next', '.nuxt',
|
|
45
|
+
'coverage', '.cache', '.turbo', '.parcel-cache', '__pycache__',
|
|
46
|
+
'vendor', 'target', '.output', '.vercel',
|
|
47
|
+
]);
|
|
48
|
+
const CODE_EXTENSIONS = new Set([
|
|
49
|
+
'.ts', '.tsx', '.js', '.jsx', '.mts', '.mjs', '.py', '.rs',
|
|
50
|
+
'.go', '.java', '.rb', '.php', '.swift', '.kt', '.c', '.cpp', '.h',
|
|
51
|
+
]);
|
|
52
|
+
function walkCodeFiles(dir, maxFiles, files = []) {
|
|
53
|
+
if (files.length >= maxFiles)
|
|
54
|
+
return files;
|
|
55
|
+
let entries;
|
|
56
|
+
try {
|
|
57
|
+
entries = readdirSync(dir);
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
return files;
|
|
61
|
+
}
|
|
62
|
+
for (const entry of entries) {
|
|
63
|
+
if (files.length >= maxFiles)
|
|
64
|
+
break;
|
|
65
|
+
const fullPath = join(dir, entry);
|
|
66
|
+
let stats;
|
|
67
|
+
try {
|
|
68
|
+
stats = statSync(fullPath);
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
if (stats.isDirectory()) {
|
|
74
|
+
if (!IGNORED_DIRS.has(entry) && !entry.startsWith('.')) {
|
|
75
|
+
walkCodeFiles(fullPath, maxFiles, files);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
else if (stats.isFile()) {
|
|
79
|
+
const ext = extname(entry).toLowerCase();
|
|
80
|
+
if (CODE_EXTENSIONS.has(ext) && stats.size < 500_000) {
|
|
81
|
+
files.push(fullPath);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return files;
|
|
86
|
+
}
|
|
87
|
+
// ── Duplicate Pattern Detection ──
|
|
88
|
+
/** Normalize a code line for comparison (strip whitespace, comments) */
|
|
89
|
+
function normalizeLine(line) {
|
|
90
|
+
return line
|
|
91
|
+
.replace(/\/\/.*$/, '') // single-line comments
|
|
92
|
+
.replace(/\/\*[\s\S]*?\*\//g, '') // block comments
|
|
93
|
+
.replace(/#.*$/, '') // Python/Ruby comments
|
|
94
|
+
.replace(/\s+/g, ' ') // collapse whitespace
|
|
95
|
+
.trim();
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Extract "chunks" of 3+ consecutive non-trivial lines from a file.
|
|
99
|
+
* Each chunk is normalized for comparison.
|
|
100
|
+
*/
|
|
101
|
+
function extractChunks(source, chunkSize) {
|
|
102
|
+
const lines = source.split('\n').map(normalizeLine).filter(l => l.length > 10);
|
|
103
|
+
const chunks = [];
|
|
104
|
+
for (let i = 0; i <= lines.length - chunkSize; i++) {
|
|
105
|
+
const chunk = lines.slice(i, i + chunkSize).join('\n');
|
|
106
|
+
if (chunk.length > 30) {
|
|
107
|
+
chunks.push(chunk);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return chunks;
|
|
111
|
+
}
|
|
112
|
+
function detectDuplicatePatterns(files, rootDir) {
|
|
113
|
+
const findings = [];
|
|
114
|
+
// Map: normalized chunk → list of files it appears in
|
|
115
|
+
const chunkMap = new Map();
|
|
116
|
+
const chunkOriginals = new Map();
|
|
117
|
+
const CHUNK_SIZE = 4;
|
|
118
|
+
for (const file of files) {
|
|
119
|
+
let source;
|
|
120
|
+
try {
|
|
121
|
+
source = readFileSync(file, 'utf-8');
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
const chunks = extractChunks(source, CHUNK_SIZE);
|
|
127
|
+
const relPath = relative(rootDir, file);
|
|
128
|
+
for (const chunk of chunks) {
|
|
129
|
+
if (!chunkMap.has(chunk)) {
|
|
130
|
+
chunkMap.set(chunk, new Set());
|
|
131
|
+
// Store one original (unnormalized) version for reporting
|
|
132
|
+
const rawLines = source.split('\n');
|
|
133
|
+
for (let i = 0; i < rawLines.length - CHUNK_SIZE; i++) {
|
|
134
|
+
const raw = rawLines.slice(i, i + CHUNK_SIZE).join('\n');
|
|
135
|
+
const normalized = rawLines.slice(i, i + CHUNK_SIZE).map(normalizeLine).filter(l => l.length > 10).join('\n');
|
|
136
|
+
if (normalized === chunk) {
|
|
137
|
+
chunkOriginals.set(chunk, raw);
|
|
138
|
+
break;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
chunkMap.get(chunk).add(relPath);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
// Find chunks that appear in 3+ files
|
|
146
|
+
for (const [chunk, fileSet] of chunkMap) {
|
|
147
|
+
if (fileSet.size >= 3) {
|
|
148
|
+
const fileList = Array.from(fileSet);
|
|
149
|
+
const original = chunkOriginals.get(chunk) || chunk;
|
|
150
|
+
findings.push({
|
|
151
|
+
type: 'duplicate-pattern',
|
|
152
|
+
severity: fileSet.size >= 5 ? 'critical' : 'warn',
|
|
153
|
+
title: `Repeated code block in ${fileSet.size} files`,
|
|
154
|
+
description: `A ${CHUNK_SIZE}-line code block appears in ${fileSet.size} files. Consider extracting into a shared utility.`,
|
|
155
|
+
files: fileList,
|
|
156
|
+
pattern: original.slice(0, 200),
|
|
157
|
+
occurrences: fileSet.size,
|
|
158
|
+
suggestion: `Extract this repeated pattern into a shared utility function and import it from a common module.`,
|
|
159
|
+
foundAt: new Date().toISOString(),
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
// Limit to top 10 most duplicated
|
|
164
|
+
findings.sort((a, b) => (b.occurrences || 0) - (a.occurrences || 0));
|
|
165
|
+
return findings.slice(0, 10);
|
|
166
|
+
}
|
|
167
|
+
// ── Co-Change Detection ──
|
|
168
|
+
/**
|
|
169
|
+
* Analyze git log to find files that always change together.
|
|
170
|
+
* Two files that appear in 3+ commits together are flagged.
|
|
171
|
+
*/
|
|
172
|
+
function detectCoChanges(rootDir) {
|
|
173
|
+
const findings = [];
|
|
174
|
+
let gitLog;
|
|
175
|
+
try {
|
|
176
|
+
// Get last 100 commits with changed files
|
|
177
|
+
gitLog = execSync('git log --name-only --format="%H" -100', { cwd: rootDir, encoding: 'utf-8', timeout: 10000, stdio: ['pipe', 'pipe', 'pipe'] });
|
|
178
|
+
}
|
|
179
|
+
catch {
|
|
180
|
+
// Not a git repo or git not available
|
|
181
|
+
return findings;
|
|
182
|
+
}
|
|
183
|
+
// Parse commits: each commit is separated by a blank line, starts with hash
|
|
184
|
+
const commits = [];
|
|
185
|
+
let currentFiles = [];
|
|
186
|
+
for (const line of gitLog.split('\n')) {
|
|
187
|
+
const trimmed = line.trim();
|
|
188
|
+
if (!trimmed) {
|
|
189
|
+
if (currentFiles.length > 0) {
|
|
190
|
+
commits.push(currentFiles);
|
|
191
|
+
currentFiles = [];
|
|
192
|
+
}
|
|
193
|
+
continue;
|
|
194
|
+
}
|
|
195
|
+
// Skip commit hashes (40 hex chars)
|
|
196
|
+
if (/^[a-f0-9]{40}$/.test(trimmed)) {
|
|
197
|
+
if (currentFiles.length > 0) {
|
|
198
|
+
commits.push(currentFiles);
|
|
199
|
+
currentFiles = [];
|
|
200
|
+
}
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
// Only track code files
|
|
204
|
+
const ext = extname(trimmed).toLowerCase();
|
|
205
|
+
if (CODE_EXTENSIONS.has(ext)) {
|
|
206
|
+
currentFiles.push(trimmed);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
if (currentFiles.length > 0) {
|
|
210
|
+
commits.push(currentFiles);
|
|
211
|
+
}
|
|
212
|
+
// Count co-occurrences: pair → count
|
|
213
|
+
const pairCounts = new Map();
|
|
214
|
+
const pairCommits = new Map();
|
|
215
|
+
for (const files of commits) {
|
|
216
|
+
if (files.length < 2 || files.length > 20)
|
|
217
|
+
continue; // Skip too-large commits
|
|
218
|
+
const sorted = files.sort();
|
|
219
|
+
for (let i = 0; i < sorted.length; i++) {
|
|
220
|
+
for (let j = i + 1; j < sorted.length; j++) {
|
|
221
|
+
const key = `${sorted[i]}|||${sorted[j]}`;
|
|
222
|
+
pairCounts.set(key, (pairCounts.get(key) || 0) + 1);
|
|
223
|
+
pairCommits.set(key, commits.length);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
// Find pairs that co-change in 3+ commits
|
|
228
|
+
for (const [key, count] of pairCounts) {
|
|
229
|
+
if (count >= 3) {
|
|
230
|
+
const [fileA, fileB] = key.split('|||');
|
|
231
|
+
const dirA = fileA.split('/').slice(0, -1).join('/');
|
|
232
|
+
const dirB = fileB.split('/').slice(0, -1).join('/');
|
|
233
|
+
// Only flag if they're in different directories
|
|
234
|
+
if (dirA !== dirB) {
|
|
235
|
+
findings.push({
|
|
236
|
+
type: 'co-change',
|
|
237
|
+
severity: count >= 6 ? 'warn' : 'info',
|
|
238
|
+
title: `Files frequently change together (${count} commits)`,
|
|
239
|
+
description: `${fileA} and ${fileB} were modified in the same commit ${count} times. They may belong in the same module.`,
|
|
240
|
+
files: [fileA, fileB],
|
|
241
|
+
occurrences: count,
|
|
242
|
+
suggestion: `Consider co-locating these files in the same directory, or extracting the shared concern into a common module.`,
|
|
243
|
+
foundAt: new Date().toISOString(),
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
// Limit to top 10 most coupled pairs
|
|
249
|
+
findings.sort((a, b) => (b.occurrences || 0) - (a.occurrences || 0));
|
|
250
|
+
return findings.slice(0, 10);
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Detect functions/methods that are too long or deeply nested.
|
|
254
|
+
* Thresholds: >50 lines = warn, >100 lines = critical, >4 nesting = warn.
|
|
255
|
+
*/
|
|
256
|
+
function measureComplexity(source, filePath) {
|
|
257
|
+
const metrics = [];
|
|
258
|
+
const lines = source.split('\n');
|
|
259
|
+
// Simple function detection: look for function/method declarations
|
|
260
|
+
const funcPattern = /(?:export\s+)?(?:async\s+)?(?:function\s+(\w+)|(?:const|let|var)\s+(\w+)\s*=\s*(?:async\s+)?(?:\([^)]*\)|[a-zA-Z_]\w*)\s*=>|(\w+)\s*\([^)]*\)\s*(?::\s*\w[^{]*)?\s*\{)/;
|
|
261
|
+
let i = 0;
|
|
262
|
+
while (i < lines.length) {
|
|
263
|
+
const line = lines[i];
|
|
264
|
+
const match = funcPattern.exec(line);
|
|
265
|
+
if (match) {
|
|
266
|
+
const funcName = match[1] || match[2] || match[3] || 'anonymous';
|
|
267
|
+
const startLine = i + 1;
|
|
268
|
+
// Count the function body: track brace depth
|
|
269
|
+
let braceDepth = 0;
|
|
270
|
+
let maxNesting = 0;
|
|
271
|
+
let funcStarted = false;
|
|
272
|
+
let bodyLines = 0;
|
|
273
|
+
let j = i;
|
|
274
|
+
while (j < lines.length) {
|
|
275
|
+
const currentLine = lines[j];
|
|
276
|
+
for (const ch of currentLine) {
|
|
277
|
+
if (ch === '{') {
|
|
278
|
+
braceDepth++;
|
|
279
|
+
if (!funcStarted)
|
|
280
|
+
funcStarted = true;
|
|
281
|
+
if (braceDepth > maxNesting)
|
|
282
|
+
maxNesting = braceDepth;
|
|
283
|
+
}
|
|
284
|
+
else if (ch === '}') {
|
|
285
|
+
braceDepth--;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
if (funcStarted)
|
|
289
|
+
bodyLines++;
|
|
290
|
+
if (funcStarted && braceDepth === 0) {
|
|
291
|
+
break;
|
|
292
|
+
}
|
|
293
|
+
j++;
|
|
294
|
+
}
|
|
295
|
+
// Subtract 1 for the initial nesting level of the function body itself
|
|
296
|
+
const effectiveNesting = Math.max(0, maxNesting - 1);
|
|
297
|
+
if (bodyLines > 50 || effectiveNesting > 4) {
|
|
298
|
+
metrics.push({
|
|
299
|
+
file: filePath,
|
|
300
|
+
functionName: funcName,
|
|
301
|
+
lineCount: bodyLines,
|
|
302
|
+
maxNesting: effectiveNesting,
|
|
303
|
+
startLine,
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
i = j + 1;
|
|
307
|
+
}
|
|
308
|
+
else {
|
|
309
|
+
i++;
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
return metrics;
|
|
313
|
+
}
|
|
314
|
+
function detectComplexity(files, rootDir) {
|
|
315
|
+
const findings = [];
|
|
316
|
+
for (const file of files) {
|
|
317
|
+
let source;
|
|
318
|
+
try {
|
|
319
|
+
source = readFileSync(file, 'utf-8');
|
|
320
|
+
}
|
|
321
|
+
catch {
|
|
322
|
+
continue;
|
|
323
|
+
}
|
|
324
|
+
const relPath = relative(rootDir, file);
|
|
325
|
+
const metrics = measureComplexity(source, relPath);
|
|
326
|
+
for (const m of metrics) {
|
|
327
|
+
if (m.lineCount > 100) {
|
|
328
|
+
findings.push({
|
|
329
|
+
type: 'complexity',
|
|
330
|
+
severity: 'critical',
|
|
331
|
+
title: `Very long function: ${m.functionName} (${m.lineCount} lines)`,
|
|
332
|
+
description: `${m.file}:${m.startLine} — function \`${m.functionName}\` is ${m.lineCount} lines long. Functions over 100 lines are hard to maintain.`,
|
|
333
|
+
files: [m.file],
|
|
334
|
+
metric: m.lineCount,
|
|
335
|
+
suggestion: `Break this function into smaller, focused helper functions. Each should do one thing well.`,
|
|
336
|
+
foundAt: new Date().toISOString(),
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
else if (m.lineCount > 50) {
|
|
340
|
+
findings.push({
|
|
341
|
+
type: 'complexity',
|
|
342
|
+
severity: 'warn',
|
|
343
|
+
title: `Long function: ${m.functionName} (${m.lineCount} lines)`,
|
|
344
|
+
description: `${m.file}:${m.startLine} — function \`${m.functionName}\` is ${m.lineCount} lines long. Consider refactoring.`,
|
|
345
|
+
files: [m.file],
|
|
346
|
+
metric: m.lineCount,
|
|
347
|
+
suggestion: `Look for logical sections within this function that could be extracted into helper functions.`,
|
|
348
|
+
foundAt: new Date().toISOString(),
|
|
349
|
+
});
|
|
350
|
+
}
|
|
351
|
+
if (m.maxNesting > 4) {
|
|
352
|
+
findings.push({
|
|
353
|
+
type: 'complexity',
|
|
354
|
+
severity: m.maxNesting > 6 ? 'critical' : 'warn',
|
|
355
|
+
title: `Deep nesting: ${m.functionName} (depth ${m.maxNesting})`,
|
|
356
|
+
description: `${m.file}:${m.startLine} — function \`${m.functionName}\` has nesting depth ${m.maxNesting}. Deep nesting makes code hard to follow.`,
|
|
357
|
+
files: [m.file],
|
|
358
|
+
metric: m.maxNesting,
|
|
359
|
+
suggestion: `Use early returns, guard clauses, or extract nested blocks into separate functions to reduce nesting.`,
|
|
360
|
+
foundAt: new Date().toISOString(),
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
// Limit to top 15 most complex
|
|
366
|
+
findings.sort((a, b) => (b.metric || 0) - (a.metric || 0));
|
|
367
|
+
return findings.slice(0, 15);
|
|
368
|
+
}
|
|
369
|
+
// ── Main Guardian ──
|
|
370
|
+
/**
|
|
371
|
+
* Run the Codebase Guardian on a directory.
|
|
372
|
+
*
|
|
373
|
+
* Scans for:
|
|
374
|
+
* - Duplicate code patterns (3+ occurrences across files)
|
|
375
|
+
* - Files that always change together (from git history)
|
|
376
|
+
* - Growing complexity (function length, nesting depth)
|
|
377
|
+
*
|
|
378
|
+
* Returns a structured report with all findings.
|
|
379
|
+
*/
|
|
380
|
+
export async function runGuardian(path) {
|
|
381
|
+
const rootDir = path;
|
|
382
|
+
const startTime = Date.now();
|
|
383
|
+
// Collect all code files
|
|
384
|
+
const files = walkCodeFiles(rootDir, 1000);
|
|
385
|
+
// Run all analyses
|
|
386
|
+
const duplicateFindings = detectDuplicatePatterns(files, rootDir);
|
|
387
|
+
const coChangeFindings = detectCoChanges(rootDir);
|
|
388
|
+
const complexityFindings = detectComplexity(files, rootDir);
|
|
389
|
+
const allFindings = [
|
|
390
|
+
...duplicateFindings,
|
|
391
|
+
...coChangeFindings,
|
|
392
|
+
...complexityFindings,
|
|
393
|
+
];
|
|
394
|
+
const report = {
|
|
395
|
+
analyzedAt: new Date().toISOString(),
|
|
396
|
+
rootDir,
|
|
397
|
+
filesScanned: files.length,
|
|
398
|
+
findings: allFindings,
|
|
399
|
+
summary: {
|
|
400
|
+
duplicates: duplicateFindings.length,
|
|
401
|
+
coChanges: coChangeFindings.length,
|
|
402
|
+
complexityWarnings: complexityFindings.length,
|
|
403
|
+
totalFindings: allFindings.length,
|
|
404
|
+
},
|
|
405
|
+
};
|
|
406
|
+
// Save to history
|
|
407
|
+
const history = loadJsonSafe(HISTORY_PATH, []);
|
|
408
|
+
history.push({ report, forgedTools: [] });
|
|
409
|
+
// Keep last 50 reports
|
|
410
|
+
if (history.length > 50)
|
|
411
|
+
history.splice(0, history.length - 50);
|
|
412
|
+
saveJson(HISTORY_PATH, history);
|
|
413
|
+
const elapsed = Date.now() - startTime;
|
|
414
|
+
console.log(`Guardian scanned ${files.length} files in ${elapsed}ms — ` +
|
|
415
|
+
`${allFindings.length} findings (${duplicateFindings.length} duplicates, ` +
|
|
416
|
+
`${coChangeFindings.length} co-changes, ${complexityFindings.length} complexity)`);
|
|
417
|
+
return report;
|
|
418
|
+
}
|
|
419
|
+
// ── Forge Guardian Tool ──
|
|
420
|
+
/**
|
|
421
|
+
* When the guardian finds a recurring pattern, forge a tool to detect (and
|
|
422
|
+
* optionally fix) that specific pattern in the future.
|
|
423
|
+
*
|
|
424
|
+
* The forged tool is saved to ~/.kbot/forge/guardian-{name}.json.
|
|
425
|
+
*/
|
|
426
|
+
export function forgeGuardianTool(finding) {
|
|
427
|
+
ensureDir(FORGE_DIR);
|
|
428
|
+
// Generate a tool name from the finding
|
|
429
|
+
const slug = finding.title
|
|
430
|
+
.toLowerCase()
|
|
431
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
432
|
+
.replace(/^-|-$/g, '')
|
|
433
|
+
.slice(0, 40);
|
|
434
|
+
const name = `guardian-${slug}`;
|
|
435
|
+
// Build a detection pattern based on the finding type
|
|
436
|
+
let detectPattern;
|
|
437
|
+
switch (finding.type) {
|
|
438
|
+
case 'duplicate-pattern':
|
|
439
|
+
// Create a regex-safe version of the pattern's first meaningful line
|
|
440
|
+
if (finding.pattern) {
|
|
441
|
+
const firstLine = finding.pattern.split('\n')[0].trim();
|
|
442
|
+
const escaped = firstLine.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
443
|
+
detectPattern = escaped;
|
|
444
|
+
}
|
|
445
|
+
else {
|
|
446
|
+
detectPattern = '.*';
|
|
447
|
+
}
|
|
448
|
+
break;
|
|
449
|
+
case 'co-change':
|
|
450
|
+
// Store the file pair for future monitoring
|
|
451
|
+
detectPattern = finding.files.join('|');
|
|
452
|
+
break;
|
|
453
|
+
case 'complexity':
|
|
454
|
+
// Store a pattern to detect the function signature
|
|
455
|
+
detectPattern = finding.files[0] + ':' + finding.title;
|
|
456
|
+
break;
|
|
457
|
+
default:
|
|
458
|
+
detectPattern = '.*';
|
|
459
|
+
}
|
|
460
|
+
const tool = {
|
|
461
|
+
name,
|
|
462
|
+
description: `Auto-forged by Codebase Guardian: ${finding.title}`,
|
|
463
|
+
finding,
|
|
464
|
+
detectPattern,
|
|
465
|
+
createdAt: new Date().toISOString(),
|
|
466
|
+
};
|
|
467
|
+
// Save to forge directory
|
|
468
|
+
const toolPath = join(FORGE_DIR, `${name}.json`);
|
|
469
|
+
writeFileSync(toolPath, JSON.stringify(tool, null, 2), 'utf-8');
|
|
470
|
+
// Update history to record the forged tool
|
|
471
|
+
const history = loadJsonSafe(HISTORY_PATH, []);
|
|
472
|
+
if (history.length > 0) {
|
|
473
|
+
history[history.length - 1].forgedTools.push(name);
|
|
474
|
+
saveJson(HISTORY_PATH, history);
|
|
475
|
+
}
|
|
476
|
+
console.log(`Forged guardian tool: ${name} → ${toolPath}`);
|
|
477
|
+
return tool;
|
|
478
|
+
}
|
|
479
|
+
// ── History ──
|
|
480
|
+
/**
|
|
481
|
+
* Get history of guardian reports and forged tools.
|
|
482
|
+
*/
|
|
483
|
+
export function getGuardianHistory() {
|
|
484
|
+
return loadJsonSafe(HISTORY_PATH, []);
|
|
485
|
+
}
|
|
486
|
+
//# sourceMappingURL=codebase-guardian.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codebase-guardian.js","sourceRoot":"","sources":["../src/codebase-guardian.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAC7D,EAAE;AACF,0BAA0B;AAC1B,oEAAoE;AACpE,+DAA+D;AAC/D,+EAA+E;AAC/E,EAAE;AACF,8EAA8E;AAC9E,0EAA0E;AAC1E,EAAE;AACF,SAAS;AACT,gGAAgG;AAChG,yDAAyD;AACzD,0CAA0C;AAE1C,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AACnG,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAY,MAAM,WAAW,CAAA;AAC7D,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AACjC,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAiD7C,cAAc;AAEd,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,OAAO,CAAC,CAAA;AACnD,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,uBAAuB,CAAC,CAAA;AAEtE,SAAS,SAAS,CAAC,GAAW;IAC5B,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;AAC3D,CAAC;AAED,qBAAqB;AAErB,SAAS,YAAY,CAAI,IAAY,EAAE,QAAW;IAChD,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,QAAQ,CAAA;IACtC,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAM,CAAA;IACrD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,QAAQ,CAAA;IACjB,CAAC;AACH,CAAC;AAED,SAAS,QAAQ,CAAC,IAAY,EAAE,IAAa;IAC3C,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAA;IACxC,SAAS,CAAC,GAAG,CAAC,CAAA;IACd,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAA;AAC7D,CAAC;AAED,qBAAqB;AAErB,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC;IAC3B,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO;IAChE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,eAAe,EAAE,aAAa;IAC9D,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS;CACzC,CAAC,CAAA;AAEF,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC;IAC9B,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK;IAC1D,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI;CACnE,CAAC,CAAA;AAEF,SAAS,aAAa,CAAC,GAAW,EAAE,QAAgB,EAAE,QAAkB,EAAE;IACxE,IAAI,KAAK,CAAC,MAAM,IAAI,QAAQ;QAAE,OAAO,KAAK,CAAA;IAE1C,IAAI,OAAiB,CAAA;IACrB,IAAI,CAAC;QACH,OAAO,GAAG,WAAW,CAAC,GAAG,CAAC,CAAA;IAC5B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAA;IACd,CAAC;IAED,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,KAAK,CAAC,MAAM,IAAI,QAAQ;YAAE,MAAK;QAEnC,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;QACjC,IAAI,KAAK,CAAA;QACT,IAAI,CAAC;YACH,KAAK,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAA;QAC5B,CAAC;QAAC,MAAM,CAAC;YACP,SAAQ;QACV,CAAC;QAED,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;gBACvD,aAAa,CAAC,QAAQ,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAA;YAC1C,CAAC;QACH,CAAC;aAAM,IAAI,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;YAC1B,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAA;YACxC,IAAI,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,IAAI,GAAG,OAAO,EAAE,CAAC;gBACrD,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;YACtB,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAA;AACd,CAAC;AAED,oCAAoC;AAEpC,wEAAwE;AACxE,SAAS,aAAa,CAAC,IAAY;IACjC,OAAO,IAAI;SACR,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAO,uBAAuB;SACpD,OAAO,CAAC,mBAAmB,EAAE,EAAE,CAAC,CAAC,iBAAiB;SAClD,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAW,uBAAuB;SACrD,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAS,sBAAsB;SACnD,IAAI,EAAE,CAAA;AACX,CAAC;AAED;;;GAGG;AACH,SAAS,aAAa,CAAC,MAAc,EAAE,SAAiB;IACtD,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,EAAE,CAAC,CAAA;IAC9E,MAAM,MAAM,GAAa,EAAE,CAAA;IAE3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,SAAS,EAAE,CAAC,EAAE,EAAE,CAAC;QACnD,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACtD,IAAI,KAAK,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;YACtB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QACpB,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAA;AACf,CAAC;AAED,SAAS,uBAAuB,CAC9B,KAAe,EACf,OAAe;IAEf,MAAM,QAAQ,GAAsB,EAAE,CAAA;IAEtC,sDAAsD;IACtD,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAuB,CAAA;IAC/C,MAAM,cAAc,GAAG,IAAI,GAAG,EAAkB,CAAA;IAChD,MAAM,UAAU,GAAG,CAAC,CAAA;IAEpB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,MAAc,CAAA;QAClB,IAAI,CAAC;YACH,MAAM,GAAG,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;QACtC,CAAC;QAAC,MAAM,CAAC;YACP,SAAQ;QACV,CAAC;QAED,MAAM,MAAM,GAAG,aAAa,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;QAChD,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA;QAEvC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;gBACzB,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,GAAG,EAAE,CAAC,CAAA;gBAC9B,0DAA0D;gBAC1D,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;gBACnC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,GAAG,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC;oBACtD,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;oBACxD,MAAM,UAAU,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;oBAC7G,IAAI,UAAU,KAAK,KAAK,EAAE,CAAC;wBACzB,cAAc,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;wBAC9B,MAAK;oBACP,CAAC;gBACH,CAAC;YACH,CAAC;YACD,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;QACnC,CAAC;IACH,CAAC;IAED,sCAAsC;IACtC,KAAK,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,QAAQ,EAAE,CAAC;QACxC,IAAI,OAAO,CAAC,IAAI,IAAI,CAAC,EAAE,CAAC;YACtB,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;YACpC,MAAM,QAAQ,GAAG,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,KAAK,CAAA;YACnD,QAAQ,CAAC,IAAI,CAAC;gBACZ,IAAI,EAAE,mBAAmB;gBACzB,QAAQ,EAAE,OAAO,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM;gBACjD,KAAK,EAAE,0BAA0B,OAAO,CAAC,IAAI,QAAQ;gBACrD,WAAW,EAAE,KAAK,UAAU,+BAA+B,OAAO,CAAC,IAAI,oDAAoD;gBAC3H,KAAK,EAAE,QAAQ;gBACf,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC;gBAC/B,WAAW,EAAE,OAAO,CAAC,IAAI;gBACzB,UAAU,EAAE,kGAAkG;gBAC9G,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;aAClC,CAAC,CAAA;QACJ,CAAC;IACH,CAAC;IAED,kCAAkC;IAClC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,CAAC,CAAA;IACpE,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;AAC9B,CAAC;AAED,4BAA4B;AAE5B;;;GAGG;AACH,SAAS,eAAe,CAAC,OAAe;IACtC,MAAM,QAAQ,GAAsB,EAAE,CAAA;IAEtC,IAAI,MAAc,CAAA;IAClB,IAAI,CAAC;QACH,0CAA0C;QAC1C,MAAM,GAAG,QAAQ,CACf,wCAAwC,EACxC,EAAE,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,CACrF,CAAA;IACH,CAAC;IAAC,MAAM,CAAC;QACP,sCAAsC;QACtC,OAAO,QAAQ,CAAA;IACjB,CAAC;IAED,4EAA4E;IAC5E,MAAM,OAAO,GAAe,EAAE,CAAA;IAC9B,IAAI,YAAY,GAAa,EAAE,CAAA;IAE/B,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACtC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAA;QAC3B,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC5B,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA;gBAC1B,YAAY,GAAG,EAAE,CAAA;YACnB,CAAC;YACD,SAAQ;QACV,CAAC;QACD,oCAAoC;QACpC,IAAI,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YACnC,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC5B,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA;gBAC1B,YAAY,GAAG,EAAE,CAAA;YACnB,CAAC;YACD,SAAQ;QACV,CAAC;QACD,wBAAwB;QACxB,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,CAAA;QAC1C,IAAI,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YAC7B,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QAC5B,CAAC;IACH,CAAC;IACD,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5B,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA;IAC5B,CAAC;IAED,qCAAqC;IACrC,MAAM,UAAU,GAAG,IAAI,GAAG,EAAkB,CAAA;IAC5C,MAAM,WAAW,GAAG,IAAI,GAAG,EAAkB,CAAA;IAE7C,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,EAAE;YAAE,SAAQ,CAAC,yBAAyB;QAE7E,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,EAAE,CAAA;QAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACvC,KAAK,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC3C,MAAM,GAAG,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,MAAM,CAAC,CAAC,CAAC,EAAE,CAAA;gBACzC,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;gBACnD,WAAW,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,MAAM,CAAC,CAAA;YACtC,CAAC;QACH,CAAC;IACH,CAAC;IAED,0CAA0C;IAC1C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,UAAU,EAAE,CAAC;QACtC,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;YACvC,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;YACpD,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;YAEpD,gDAAgD;YAChD,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;gBAClB,QAAQ,CAAC,IAAI,CAAC;oBACZ,IAAI,EAAE,WAAW;oBACjB,QAAQ,EAAE,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM;oBACtC,KAAK,EAAE,qCAAqC,KAAK,WAAW;oBAC5D,WAAW,EAAE,GAAG,KAAK,QAAQ,KAAK,qCAAqC,KAAK,6CAA6C;oBACzH,KAAK,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC;oBACrB,WAAW,EAAE,KAAK;oBAClB,UAAU,EAAE,gHAAgH;oBAC5H,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;iBAClC,CAAC,CAAA;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAED,qCAAqC;IACrC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,CAAC,CAAA;IACpE,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;AAC9B,CAAC;AAYD;;;GAGG;AACH,SAAS,iBAAiB,CAAC,MAAc,EAAE,QAAgB;IACzD,MAAM,OAAO,GAAwB,EAAE,CAAA;IACvC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IAEhC,mEAAmE;IACnE,MAAM,WAAW,GAAG,wKAAwK,CAAA;IAE5L,IAAI,CAAC,GAAG,CAAC,CAAA;IACT,OAAO,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;QACxB,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAA;QACrB,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAEpC,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,IAAI,WAAW,CAAA;YAChE,MAAM,SAAS,GAAG,CAAC,GAAG,CAAC,CAAA;YAEvB,6CAA6C;YAC7C,IAAI,UAAU,GAAG,CAAC,CAAA;YAClB,IAAI,UAAU,GAAG,CAAC,CAAA;YAClB,IAAI,WAAW,GAAG,KAAK,CAAA;YACvB,IAAI,SAAS,GAAG,CAAC,CAAA;YACjB,IAAI,CAAC,GAAG,CAAC,CAAA;YAET,OAAO,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;gBACxB,MAAM,WAAW,GAAG,KAAK,CAAC,CAAC,CAAC,CAAA;gBAC5B,KAAK,MAAM,EAAE,IAAI,WAAW,EAAE,CAAC;oBAC7B,IAAI,EAAE,KAAK,GAAG,EAAE,CAAC;wBACf,UAAU,EAAE,CAAA;wBACZ,IAAI,CAAC,WAAW;4BAAE,WAAW,GAAG,IAAI,CAAA;wBACpC,IAAI,UAAU,GAAG,UAAU;4BAAE,UAAU,GAAG,UAAU,CAAA;oBACtD,CAAC;yBAAM,IAAI,EAAE,KAAK,GAAG,EAAE,CAAC;wBACtB,UAAU,EAAE,CAAA;oBACd,CAAC;gBACH,CAAC;gBAED,IAAI,WAAW;oBAAE,SAAS,EAAE,CAAA;gBAE5B,IAAI,WAAW,IAAI,UAAU,KAAK,CAAC,EAAE,CAAC;oBACpC,MAAK;gBACP,CAAC;gBACD,CAAC,EAAE,CAAA;YACL,CAAC;YAED,uEAAuE;YACvE,MAAM,gBAAgB,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,UAAU,GAAG,CAAC,CAAC,CAAA;YAEpD,IAAI,SAAS,GAAG,EAAE,IAAI,gBAAgB,GAAG,CAAC,EAAE,CAAC;gBAC3C,OAAO,CAAC,IAAI,CAAC;oBACX,IAAI,EAAE,QAAQ;oBACd,YAAY,EAAE,QAAQ;oBACtB,SAAS,EAAE,SAAS;oBACpB,UAAU,EAAE,gBAAgB;oBAC5B,SAAS;iBACV,CAAC,CAAA;YACJ,CAAC;YAED,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;QACX,CAAC;aAAM,CAAC;YACN,CAAC,EAAE,CAAA;QACL,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAA;AAChB,CAAC;AAED,SAAS,gBAAgB,CACvB,KAAe,EACf,OAAe;IAEf,MAAM,QAAQ,GAAsB,EAAE,CAAA;IAEtC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,MAAc,CAAA;QAClB,IAAI,CAAC;YACH,MAAM,GAAG,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;QACtC,CAAC;QAAC,MAAM,CAAC;YACP,SAAQ;QACV,CAAC;QAED,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA;QACvC,MAAM,OAAO,GAAG,iBAAiB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;QAElD,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;YACxB,IAAI,CAAC,CAAC,SAAS,GAAG,GAAG,EAAE,CAAC;gBACtB,QAAQ,CAAC,IAAI,CAAC;oBACZ,IAAI,EAAE,YAAY;oBAClB,QAAQ,EAAE,UAAU;oBACpB,KAAK,EAAE,uBAAuB,CAAC,CAAC,YAAY,KAAK,CAAC,CAAC,SAAS,SAAS;oBACrE,WAAW,EAAE,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,SAAS,iBAAiB,CAAC,CAAC,YAAY,SAAS,CAAC,CAAC,SAAS,6DAA6D;oBACrJ,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;oBACf,MAAM,EAAE,CAAC,CAAC,SAAS;oBACnB,UAAU,EAAE,4FAA4F;oBACxG,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;iBAClC,CAAC,CAAA;YACJ,CAAC;iBAAM,IAAI,CAAC,CAAC,SAAS,GAAG,EAAE,EAAE,CAAC;gBAC5B,QAAQ,CAAC,IAAI,CAAC;oBACZ,IAAI,EAAE,YAAY;oBAClB,QAAQ,EAAE,MAAM;oBAChB,KAAK,EAAE,kBAAkB,CAAC,CAAC,YAAY,KAAK,CAAC,CAAC,SAAS,SAAS;oBAChE,WAAW,EAAE,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,SAAS,iBAAiB,CAAC,CAAC,YAAY,SAAS,CAAC,CAAC,SAAS,oCAAoC;oBAC5H,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;oBACf,MAAM,EAAE,CAAC,CAAC,SAAS;oBACnB,UAAU,EAAE,+FAA+F;oBAC3G,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;iBAClC,CAAC,CAAA;YACJ,CAAC;YAED,IAAI,CAAC,CAAC,UAAU,GAAG,CAAC,EAAE,CAAC;gBACrB,QAAQ,CAAC,IAAI,CAAC;oBACZ,IAAI,EAAE,YAAY;oBAClB,QAAQ,EAAE,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM;oBAChD,KAAK,EAAE,iBAAiB,CAAC,CAAC,YAAY,WAAW,CAAC,CAAC,UAAU,GAAG;oBAChE,WAAW,EAAE,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,SAAS,iBAAiB,CAAC,CAAC,YAAY,wBAAwB,CAAC,CAAC,UAAU,2CAA2C;oBACnJ,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;oBACf,MAAM,EAAE,CAAC,CAAC,UAAU;oBACpB,UAAU,EAAE,uGAAuG;oBACnH,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;iBAClC,CAAC,CAAA;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAED,+BAA+B;IAC/B,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAA;IAC1D,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;AAC9B,CAAC;AAED,sBAAsB;AAEtB;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,IAAY;IAC5C,MAAM,OAAO,GAAG,IAAI,CAAA;IACpB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;IAE5B,yBAAyB;IACzB,MAAM,KAAK,GAAG,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA;IAE1C,mBAAmB;IACnB,MAAM,iBAAiB,GAAG,uBAAuB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAA;IACjE,MAAM,gBAAgB,GAAG,eAAe,CAAC,OAAO,CAAC,CAAA;IACjD,MAAM,kBAAkB,GAAG,gBAAgB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAA;IAE3D,MAAM,WAAW,GAAG;QAClB,GAAG,iBAAiB;QACpB,GAAG,gBAAgB;QACnB,GAAG,kBAAkB;KACtB,CAAA;IAED,MAAM,MAAM,GAAmB;QAC7B,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACpC,OAAO;QACP,YAAY,EAAE,KAAK,CAAC,MAAM;QAC1B,QAAQ,EAAE,WAAW;QACrB,OAAO,EAAE;YACP,UAAU,EAAE,iBAAiB,CAAC,MAAM;YACpC,SAAS,EAAE,gBAAgB,CAAC,MAAM;YAClC,kBAAkB,EAAE,kBAAkB,CAAC,MAAM;YAC7C,aAAa,EAAE,WAAW,CAAC,MAAM;SAClC;KACF,CAAA;IAED,kBAAkB;IAClB,MAAM,OAAO,GAAG,YAAY,CAAiB,YAAY,EAAE,EAAE,CAAC,CAAA;IAC9D,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC,CAAA;IACzC,uBAAuB;IACvB,IAAI,OAAO,CAAC,MAAM,GAAG,EAAE;QAAE,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC,MAAM,GAAG,EAAE,CAAC,CAAA;IAC/D,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC,CAAA;IAE/B,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAA;IACtC,OAAO,CAAC,GAAG,CACT,oBAAoB,KAAK,CAAC,MAAM,aAAa,OAAO,OAAO;QAC3D,GAAG,WAAW,CAAC,MAAM,cAAc,iBAAiB,CAAC,MAAM,eAAe;QAC1E,GAAG,gBAAgB,CAAC,MAAM,gBAAgB,kBAAkB,CAAC,MAAM,cAAc,CAClF,CAAA;IAED,OAAO,MAAM,CAAA;AACf,CAAC;AAED,4BAA4B;AAE5B;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAAwB;IACxD,SAAS,CAAC,SAAS,CAAC,CAAA;IAEpB,wCAAwC;IACxC,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK;SACvB,WAAW,EAAE;SACb,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;SAC3B,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC;SACrB,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;IACf,MAAM,IAAI,GAAG,YAAY,IAAI,EAAE,CAAA;IAE/B,sDAAsD;IACtD,IAAI,aAAqB,CAAA;IAEzB,QAAQ,OAAO,CAAC,IAAI,EAAE,CAAC;QACrB,KAAK,mBAAmB;YACtB,qEAAqE;YACrE,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;gBACpB,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;gBACvD,MAAM,OAAO,GAAG,SAAS,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAA;gBAChE,aAAa,GAAG,OAAO,CAAA;YACzB,CAAC;iBAAM,CAAC;gBACN,aAAa,GAAG,IAAI,CAAA;YACtB,CAAC;YACD,MAAK;QAEP,KAAK,WAAW;YACd,4CAA4C;YAC5C,aAAa,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;YACvC,MAAK;QAEP,KAAK,YAAY;YACf,mDAAmD;YACnD,aAAa,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,OAAO,CAAC,KAAK,CAAA;YACtD,MAAK;QAEP;YACE,aAAa,GAAG,IAAI,CAAA;IACxB,CAAC;IAED,MAAM,IAAI,GAAuB;QAC/B,IAAI;QACJ,WAAW,EAAE,qCAAqC,OAAO,CAAC,KAAK,EAAE;QACjE,OAAO;QACP,aAAa;QACb,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACpC,CAAA;IAED,0BAA0B;IAC1B,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,EAAE,GAAG,IAAI,OAAO,CAAC,CAAA;IAChD,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAA;IAE/D,2CAA2C;IAC3C,MAAM,OAAO,GAAG,YAAY,CAAiB,YAAY,EAAE,EAAE,CAAC,CAAA;IAC9D,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAClD,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC,CAAA;IACjC,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,yBAAyB,IAAI,MAAM,QAAQ,EAAE,CAAC,CAAA;IAE1D,OAAO,IAAI,CAAA;AACb,CAAC;AAED,gBAAgB;AAEhB;;GAEG;AACH,MAAM,UAAU,kBAAkB;IAChC,OAAO,YAAY,CAAiB,YAAY,EAAE,EAAE,CAAC,CAAA;AACvD,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
interface DreamResult {
|
|
2
|
+
phase: string;
|
|
3
|
+
duration_ms: number;
|
|
4
|
+
findings: string[];
|
|
5
|
+
actions_taken: string[];
|
|
6
|
+
improvements: number;
|
|
7
|
+
}
|
|
8
|
+
interface DreamReport {
|
|
9
|
+
timestamp: string;
|
|
10
|
+
duration_ms: number;
|
|
11
|
+
phases_completed: number;
|
|
12
|
+
total_findings: number;
|
|
13
|
+
total_actions: number;
|
|
14
|
+
total_improvements: number;
|
|
15
|
+
results: DreamResult[];
|
|
16
|
+
}
|
|
17
|
+
export declare function runDreamMode(verbose?: boolean): Promise<DreamReport>;
|
|
18
|
+
export declare function getDreamHistory(): Array<{
|
|
19
|
+
date: string;
|
|
20
|
+
summary: Record<string, number>;
|
|
21
|
+
}>;
|
|
22
|
+
export {};
|
|
23
|
+
//# sourceMappingURL=dream-mode.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dream-mode.d.ts","sourceRoot":"","sources":["../src/dream-mode.ts"],"names":[],"mappings":"AA8BA,UAAU,WAAW;IACnB,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,aAAa,EAAE,MAAM,EAAE,CAAA;IACvB,YAAY,EAAE,MAAM,CAAA;CACrB;AAED,UAAU,WAAW;IACnB,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,MAAM,CAAA;IACnB,gBAAgB,EAAE,MAAM,CAAA;IACxB,cAAc,EAAE,MAAM,CAAA;IACtB,aAAa,EAAE,MAAM,CAAA;IACrB,kBAAkB,EAAE,MAAM,CAAA;IAC1B,OAAO,EAAE,WAAW,EAAE,CAAA;CACvB;AAwSD,wBAAsB,YAAY,CAAC,OAAO,UAAO,GAAG,OAAO,CAAC,WAAW,CAAC,CA2EvE;AAID,wBAAgB,eAAe,IAAI,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,CAAC,CAO1F"}
|