devmind 1.0.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.
Files changed (141) hide show
  1. package/LICENSE +191 -0
  2. package/README.md +148 -0
  3. package/dist/cli.d.ts +6 -0
  4. package/dist/cli.js +232 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/codebase/generators/architecture.d.ts +4 -0
  7. package/dist/codebase/generators/architecture.js +33 -0
  8. package/dist/codebase/generators/architecture.js.map +1 -0
  9. package/dist/codebase/generators/modules.d.ts +9 -0
  10. package/dist/codebase/generators/modules.js +46 -0
  11. package/dist/codebase/generators/modules.js.map +1 -0
  12. package/dist/codebase/generators/overview.d.ts +5 -0
  13. package/dist/codebase/generators/overview.js +34 -0
  14. package/dist/codebase/generators/overview.js.map +1 -0
  15. package/dist/codebase/generators/skeleton.d.ts +8 -0
  16. package/dist/codebase/generators/skeleton.js +57 -0
  17. package/dist/codebase/generators/skeleton.js.map +1 -0
  18. package/dist/codebase/index.d.ts +24 -0
  19. package/dist/codebase/index.js +50 -0
  20. package/dist/codebase/index.js.map +1 -0
  21. package/dist/codebase/parsers/typescript.d.ts +14 -0
  22. package/dist/codebase/parsers/typescript.js +145 -0
  23. package/dist/codebase/parsers/typescript.js.map +1 -0
  24. package/dist/codebase/scanners/filesystem.d.ts +17 -0
  25. package/dist/codebase/scanners/filesystem.js +152 -0
  26. package/dist/codebase/scanners/filesystem.js.map +1 -0
  27. package/dist/codebase/utils/hashing.d.ts +15 -0
  28. package/dist/codebase/utils/hashing.js +50 -0
  29. package/dist/codebase/utils/hashing.js.map +1 -0
  30. package/dist/codebase/utils/stats.d.ts +12 -0
  31. package/dist/codebase/utils/stats.js +55 -0
  32. package/dist/codebase/utils/stats.js.map +1 -0
  33. package/dist/codebase/utils/tree.d.ts +10 -0
  34. package/dist/codebase/utils/tree.js +22 -0
  35. package/dist/codebase/utils/tree.js.map +1 -0
  36. package/dist/commands/analyze.d.ts +6 -0
  37. package/dist/commands/analyze.js +97 -0
  38. package/dist/commands/analyze.js.map +1 -0
  39. package/dist/commands/context.d.ts +4 -0
  40. package/dist/commands/context.js +54 -0
  41. package/dist/commands/context.js.map +1 -0
  42. package/dist/core/config.d.ts +20 -0
  43. package/dist/core/config.js +40 -0
  44. package/dist/core/config.js.map +1 -0
  45. package/dist/core/errors.d.ts +18 -0
  46. package/dist/core/errors.js +53 -0
  47. package/dist/core/errors.js.map +1 -0
  48. package/dist/core/fileio.d.ts +10 -0
  49. package/dist/core/fileio.js +57 -0
  50. package/dist/core/fileio.js.map +1 -0
  51. package/dist/core/index.d.ts +8 -0
  52. package/dist/core/index.js +9 -0
  53. package/dist/core/index.js.map +1 -0
  54. package/dist/core/logger.d.ts +15 -0
  55. package/dist/core/logger.js +40 -0
  56. package/dist/core/logger.js.map +1 -0
  57. package/dist/core/types.d.ts +106 -0
  58. package/dist/core/types.js +5 -0
  59. package/dist/core/types.js.map +1 -0
  60. package/dist/database/cli.d.ts +7 -0
  61. package/dist/database/cli.js +132 -0
  62. package/dist/database/cli.js.map +1 -0
  63. package/dist/database/commands/checkpoint.d.ts +13 -0
  64. package/dist/database/commands/checkpoint.js +136 -0
  65. package/dist/database/commands/checkpoint.js.map +1 -0
  66. package/dist/database/commands/generate.d.ts +21 -0
  67. package/dist/database/commands/generate.js +269 -0
  68. package/dist/database/commands/generate.js.map +1 -0
  69. package/dist/database/commands/handoff.d.ts +15 -0
  70. package/dist/database/commands/handoff.js +332 -0
  71. package/dist/database/commands/handoff.js.map +1 -0
  72. package/dist/database/commands/history.d.ts +13 -0
  73. package/dist/database/commands/history.js +148 -0
  74. package/dist/database/commands/history.js.map +1 -0
  75. package/dist/database/commands/init.d.ts +10 -0
  76. package/dist/database/commands/init.js +28 -0
  77. package/dist/database/commands/init.js.map +1 -0
  78. package/dist/database/commands/learn.d.ts +12 -0
  79. package/dist/database/commands/learn.js +93 -0
  80. package/dist/database/commands/learn.js.map +1 -0
  81. package/dist/database/commands/memory.d.ts +90 -0
  82. package/dist/database/commands/memory.js +353 -0
  83. package/dist/database/commands/memory.js.map +1 -0
  84. package/dist/database/commands/show.d.ts +9 -0
  85. package/dist/database/commands/show.js +136 -0
  86. package/dist/database/commands/show.js.map +1 -0
  87. package/dist/database/commands/validate.d.ts +9 -0
  88. package/dist/database/commands/validate.js +200 -0
  89. package/dist/database/commands/validate.js.map +1 -0
  90. package/dist/database/commands/watch.d.ts +9 -0
  91. package/dist/database/commands/watch.js +77 -0
  92. package/dist/database/commands/watch.js.map +1 -0
  93. package/dist/database/extractors/drizzle.d.ts +62 -0
  94. package/dist/database/extractors/drizzle.js +251 -0
  95. package/dist/database/extractors/drizzle.js.map +1 -0
  96. package/dist/database/extractors/firebase.d.ts +39 -0
  97. package/dist/database/extractors/firebase.js +192 -0
  98. package/dist/database/extractors/firebase.js.map +1 -0
  99. package/dist/database/extractors/index.d.ts +69 -0
  100. package/dist/database/extractors/index.js +345 -0
  101. package/dist/database/extractors/index.js.map +1 -0
  102. package/dist/database/extractors/mongodb.d.ts +44 -0
  103. package/dist/database/extractors/mongodb.js +198 -0
  104. package/dist/database/extractors/mongodb.js.map +1 -0
  105. package/dist/database/extractors/mysql.d.ts +61 -0
  106. package/dist/database/extractors/mysql.js +173 -0
  107. package/dist/database/extractors/mysql.js.map +1 -0
  108. package/dist/database/extractors/postgres.d.ts +47 -0
  109. package/dist/database/extractors/postgres.js +141 -0
  110. package/dist/database/extractors/postgres.js.map +1 -0
  111. package/dist/database/extractors/prisma.d.ts +71 -0
  112. package/dist/database/extractors/prisma.js +270 -0
  113. package/dist/database/extractors/prisma.js.map +1 -0
  114. package/dist/database/extractors/sqlite.d.ts +50 -0
  115. package/dist/database/extractors/sqlite.js +148 -0
  116. package/dist/database/extractors/sqlite.js.map +1 -0
  117. package/dist/database/generators/learning-generator.d.ts +48 -0
  118. package/dist/database/generators/learning-generator.js +221 -0
  119. package/dist/database/generators/learning-generator.js.map +1 -0
  120. package/dist/database/generators/templates.d.ts +103 -0
  121. package/dist/database/generators/templates.js +1557 -0
  122. package/dist/database/generators/templates.js.map +1 -0
  123. package/dist/database/index.d.ts +15 -0
  124. package/dist/database/index.js +16 -0
  125. package/dist/database/index.js.map +1 -0
  126. package/dist/database/utils/json-output.d.ts +26 -0
  127. package/dist/database/utils/json-output.js +37 -0
  128. package/dist/database/utils/json-output.js.map +1 -0
  129. package/dist/generators/unified.d.ts +1 -0
  130. package/dist/generators/unified.js +173 -0
  131. package/dist/generators/unified.js.map +1 -0
  132. package/dist/index.d.ts +4 -0
  133. package/dist/index.js +5 -0
  134. package/dist/index.js.map +1 -0
  135. package/dist/utils/config-detector.d.ts +1 -0
  136. package/dist/utils/config-detector.js +40 -0
  137. package/dist/utils/config-detector.js.map +1 -0
  138. package/dist/utils/config-loader.d.ts +16 -0
  139. package/dist/utils/config-loader.js +20 -0
  140. package/dist/utils/config-loader.js.map +1 -0
  141. package/package.json +78 -0
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Codebase Hashing Utilities
3
+ */
4
+ import * as crypto from 'crypto';
5
+ /**
6
+ * Calculate a hash of the codebase structure and content (proxied by exports/size)
7
+ */
8
+ export function calculateCodebaseHash(node) {
9
+ const hash = crypto.createHash('sha256');
10
+ updateHash(hash, node);
11
+ return hash.digest('hex').substring(0, 32); // Return first 32 chars
12
+ }
13
+ function updateHash(hash, node) {
14
+ // Hash name and type
15
+ hash.update(`${node.name}:${node.type}`);
16
+ if (node.type === 'file') {
17
+ // Hash size
18
+ hash.update(`:${node.size || 0}`);
19
+ // Hash exports if available
20
+ if (node.exports && node.exports.length > 0) {
21
+ hash.update(`:${JSON.stringify(node.exports)}`);
22
+ }
23
+ }
24
+ // Recurse for directories
25
+ if (node.children) {
26
+ for (const child of node.children) {
27
+ updateHash(hash, child);
28
+ }
29
+ }
30
+ }
31
+ /**
32
+ * Get codebase statistics
33
+ */
34
+ export function getCodebaseStats(node) {
35
+ let files = 0;
36
+ // We don't track LOC directly in FileNode yet, so we'll use size as a rough proxy or just return 0 for now
37
+ // If we want LOC, we'd need to read files or estimate.
38
+ // Let's just track file count for now.
39
+ function traverse(n) {
40
+ if (n.type === 'file') {
41
+ files++;
42
+ }
43
+ if (n.children) {
44
+ n.children.forEach(traverse);
45
+ }
46
+ }
47
+ traverse(node);
48
+ return { files, loc: 0 };
49
+ }
50
+ //# sourceMappingURL=hashing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hashing.js","sourceRoot":"","sources":["../../../src/codebase/utils/hashing.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AAEjC;;GAEG;AACH,MAAM,UAAU,qBAAqB,CAAC,IAAc;IAClD,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;IACzC,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACvB,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,wBAAwB;AACtE,CAAC;AAED,SAAS,UAAU,CAAC,IAAiB,EAAE,IAAc;IACnD,qBAAqB;IACrB,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IAEzC,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QACzB,YAAY;QACZ,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC,EAAE,CAAC,CAAC;QAElC,4BAA4B;QAC5B,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5C,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAClD,CAAC;IACH,CAAC;IAED,0BAA0B;IAC1B,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAClB,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClC,UAAU,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAc;IAC7C,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,2GAA2G;IAC3G,uDAAuD;IACvD,uCAAuC;IAEvC,SAAS,QAAQ,CAAC,CAAW;QAC3B,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YACtB,KAAK,EAAE,CAAC;QACV,CAAC;QACD,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;YACf,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QAC/B,CAAC;IACH,CAAC;IAED,QAAQ,CAAC,IAAI,CAAC,CAAC;IACf,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;AAC3B,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Statistics utility for codebase structure
3
+ */
4
+ import { FileNode } from '../scanners/filesystem.js';
5
+ export interface CodebaseStats {
6
+ files: number;
7
+ dirs: number;
8
+ lines: number;
9
+ languages: string[];
10
+ entryPoints: string[];
11
+ }
12
+ export declare function countFilesAndLines(node: FileNode): CodebaseStats;
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Statistics utility for codebase structure
3
+ */
4
+ export function countFilesAndLines(node) {
5
+ const stats = {
6
+ files: 0,
7
+ dirs: 0,
8
+ lines: 0,
9
+ languages: [],
10
+ entryPoints: [],
11
+ };
12
+ const traverse = (n) => {
13
+ if (n.type === 'file') {
14
+ stats.files++;
15
+ // Estimate lines roughly if not available (file size / 30 bytes per line approx)
16
+ // or set to 0 if unknown.
17
+ // In a real scenario we might read the file, but for scanning we used size.
18
+ // Let's assume 1 line per 30 bytes as a heuristic if we don't have line count.
19
+ if (n.size) {
20
+ stats.lines += Math.ceil(n.size / 30);
21
+ }
22
+ if (n.language) {
23
+ if (!stats.languages.includes(n.language)) {
24
+ stats.languages.push(n.language);
25
+ }
26
+ }
27
+ const name = n.name.toLowerCase();
28
+ if ([
29
+ 'index.tsx',
30
+ 'index.ts',
31
+ 'main.tsx',
32
+ 'main.ts',
33
+ 'app.js',
34
+ 'app.tsx',
35
+ 'index.js',
36
+ 'server.ts',
37
+ 'server.js',
38
+ ].includes(name)) {
39
+ if (n.path)
40
+ stats.entryPoints.push(n.path);
41
+ else
42
+ stats.entryPoints.push(n.name);
43
+ }
44
+ }
45
+ else if (n.type === 'directory') {
46
+ stats.dirs++;
47
+ if (n.children) {
48
+ n.children.forEach(traverse);
49
+ }
50
+ }
51
+ };
52
+ traverse(node);
53
+ return stats;
54
+ }
55
+ //# sourceMappingURL=stats.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stats.js","sourceRoot":"","sources":["../../../src/codebase/utils/stats.ts"],"names":[],"mappings":"AAAA;;GAEG;AAYH,MAAM,UAAU,kBAAkB,CAAC,IAAc;IAC/C,MAAM,KAAK,GAAkB;QAC3B,KAAK,EAAE,CAAC;QACR,IAAI,EAAE,CAAC;QACP,KAAK,EAAE,CAAC;QACR,SAAS,EAAE,EAAE;QACb,WAAW,EAAE,EAAE;KAChB,CAAC;IAEF,MAAM,QAAQ,GAAG,CAAC,CAAW,EAAE,EAAE;QAC/B,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YACtB,KAAK,CAAC,KAAK,EAAE,CAAC;YACd,iFAAiF;YACjF,0BAA0B;YAC1B,4EAA4E;YAC5E,+EAA+E;YAC/E,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;gBACX,KAAK,CAAC,KAAK,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC;YACxC,CAAC;YAED,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;gBACf,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC;oBAC1C,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;gBACnC,CAAC;YACH,CAAC;YAED,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YAClC,IACE;gBACE,WAAW;gBACX,UAAU;gBACV,UAAU;gBACV,SAAS;gBACT,QAAQ;gBACR,SAAS;gBACT,UAAU;gBACV,WAAW;gBACX,WAAW;aACZ,CAAC,QAAQ,CAAC,IAAI,CAAC,EAChB,CAAC;gBACD,IAAI,CAAC,CAAC,IAAI;oBAAE,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;;oBACtC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YACtC,CAAC;QACH,CAAC;aAAM,IAAI,CAAC,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YAClC,KAAK,CAAC,IAAI,EAAE,CAAC;YACb,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;gBACf,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;YAC/B,CAAC;QACH,CAAC;IACH,CAAC,CAAC;IAEF,QAAQ,CAAC,IAAI,CAAC,CAAC;IACf,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Tree generation utility
3
+ */
4
+ export interface TreeNode {
5
+ name: string;
6
+ type: 'file' | 'directory';
7
+ children?: TreeNode[];
8
+ [key: string]: any;
9
+ }
10
+ export declare function generateTree(node: TreeNode, prefix?: string, isLast?: boolean): string;
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Tree generation utility
3
+ */
4
+ export function generateTree(node, prefix = '', isLast = true) {
5
+ const connector = isLast ? '└── ' : '├── ';
6
+ let result = prefix + connector + node.name + (node.type === 'directory' ? '/' : '') + '\n';
7
+ if (node.children && node.children.length > 0) {
8
+ const newPrefix = prefix + (isLast ? ' ' : '│ ');
9
+ node.children.forEach((child, index) => {
10
+ // Sort children: directories first, then files
11
+ // This logic was not in original but is good practice for trees
12
+ // However, to keep strict port, I'll trust input order or sort if needed later.
13
+ // For now, adhering to original logic but adding types.
14
+ if (node.children) {
15
+ // Check again for TS strictness
16
+ result += generateTree(child, newPrefix, index === node.children.length - 1);
17
+ }
18
+ });
19
+ }
20
+ return result;
21
+ }
22
+ //# sourceMappingURL=tree.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tree.js","sourceRoot":"","sources":["../../../src/codebase/utils/tree.ts"],"names":[],"mappings":"AAAA;;GAEG;AASH,MAAM,UAAU,YAAY,CAAC,IAAc,EAAE,SAAiB,EAAE,EAAE,SAAkB,IAAI;IACtF,MAAM,SAAS,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;IAC3C,IAAI,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,KAAK,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC;IAE5F,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9C,MAAM,SAAS,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QACtD,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;YACrC,+CAA+C;YAC/C,gEAAgE;YAChE,gFAAgF;YAChF,wDAAwD;YAExD,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;gBAClB,gCAAgC;gBAChC,MAAM,IAAI,YAAY,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,KAAK,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YAC/E,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,6 @@
1
+ interface AnalyzeOptions {
2
+ output?: string;
3
+ path?: string;
4
+ }
5
+ export declare function analyze(options: AnalyzeOptions): Promise<void>;
6
+ export {};
@@ -0,0 +1,97 @@
1
+ import * as path from 'path';
2
+ import { logger, readFileSafe, writeFileSafe, ensureDir } from '../core/index.js';
3
+ import { glob } from 'glob';
4
+ import * as fs from 'fs';
5
+ export async function analyze(options) {
6
+ const outputDir = options.output || '.devmind';
7
+ const rootPath = options.path || '.';
8
+ logger.info('Starting Cross-Context Analysis...');
9
+ // 1. Load Schema
10
+ const schemaPath = path.join(outputDir, 'database', 'schema.json');
11
+ let schema;
12
+ try {
13
+ const schemaContent = await readFileSafe(schemaPath);
14
+ schema = JSON.parse(schemaContent);
15
+ logger.info(`Loaded schema: ${schema.tables.length} tables found.`);
16
+ }
17
+ catch (error) {
18
+ logger.error('Failed to load schema.json. Run "devmind generate" first.');
19
+ return;
20
+ }
21
+ // 2. Scan Codebase Files
22
+ // We scan actual files instead of relying on structure.json to ensure fresh content
23
+ logger.info(`Scanning files in: ${rootPath}`);
24
+ const files = await glob('**/*.{ts,js,tsx,jsx,py,go,java,rb,php}', {
25
+ cwd: rootPath,
26
+ ignore: ['node_modules/**', '.devmind/**', 'dist/**', 'build/**'],
27
+ });
28
+ logger.info(`Analyzing ${files.length} source files...`);
29
+ // 3. Analyze Usage
30
+ const usage = [];
31
+ const unusedTables = [];
32
+ for (const table of schema.tables) {
33
+ const tableName = table.name;
34
+ const variations = [tableName, toPascalCase(tableName), toCamelCase(tableName)];
35
+ // Remove duplicates
36
+ const searchTerms = [...new Set(variations)];
37
+ const matchedFiles = [];
38
+ for (const file of files) {
39
+ const content = fs.readFileSync(path.join(rootPath, file), 'utf-8');
40
+ if (searchTerms.some((term) => content.includes(term))) {
41
+ matchedFiles.push(file);
42
+ }
43
+ }
44
+ if (matchedFiles.length > 0) {
45
+ usage.push({
46
+ tableName,
47
+ files: matchedFiles,
48
+ count: matchedFiles.length,
49
+ });
50
+ }
51
+ else {
52
+ unusedTables.push(tableName);
53
+ }
54
+ }
55
+ // 4. Generate Reports
56
+ const analysisDir = path.join(outputDir, 'analysis');
57
+ await ensureDir(analysisDir);
58
+ // CODE_DB_MAPPING.md
59
+ let mappingContent = '# Code-to-Database Mapping\n\n';
60
+ mappingContent += `**Generated:** ${new Date().toISOString()}\n\n`;
61
+ // Most used tables first
62
+ usage.sort((a, b) => b.count - a.count);
63
+ for (const item of usage) {
64
+ mappingContent += `### ${item.tableName} (${item.count} files)\n`;
65
+ for (const file of item.files) {
66
+ mappingContent += `- \`${file}\`\n`;
67
+ }
68
+ mappingContent += '\n';
69
+ }
70
+ await writeFileSafe(path.join(analysisDir, 'CODE_DB_MAPPING.md'), mappingContent);
71
+ // UNUSED_TABLES.md
72
+ if (unusedTables.length > 0) {
73
+ let unusedContent = '# Unused Tables Report\n\n';
74
+ unusedContent +=
75
+ '> ⚠️ **Warning:** These tables were not found in the codebase. Verify manually before deleting.\n\n';
76
+ for (const table of unusedTables) {
77
+ unusedContent += `- [ ] ${table}\n`;
78
+ }
79
+ await writeFileSafe(path.join(analysisDir, 'UNUSED_TABLES.md'), unusedContent);
80
+ }
81
+ logger.success('Analysis Complete!');
82
+ logger.info(` - ${path.join(analysisDir, 'CODE_DB_MAPPING.md')}`);
83
+ if (unusedTables.length > 0) {
84
+ logger.info(` - ${path.join(analysisDir, 'UNUSED_TABLES.md')}`);
85
+ }
86
+ }
87
+ // Helpers
88
+ function toPascalCase(str) {
89
+ return str
90
+ .replace(/_(\w)/g, (all, letter) => letter.toUpperCase())
91
+ .replace(/^\w/, (c) => c.toUpperCase());
92
+ }
93
+ function toCamelCase(str) {
94
+ const pascal = toPascalCase(str);
95
+ return pascal.charAt(0).toLowerCase() + pascal.slice(1);
96
+ }
97
+ //# sourceMappingURL=analyze.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyze.js","sourceRoot":"","sources":["../../src/commands/analyze.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export declare function context(options: {
2
+ focus?: string;
3
+ query?: string;
4
+ }): Promise<void>;
@@ -0,0 +1,54 @@
1
+ import * as path from 'path';
2
+ import * as fs from 'fs';
3
+ import { scanDirectory } from '../codebase/index.js';
4
+ import { logger } from '../core/index.js';
5
+ export async function context(options) {
6
+ const cwd = process.cwd();
7
+ if (options.focus) {
8
+ const targetPath = path.resolve(cwd, options.focus);
9
+ if (!fs.existsSync(targetPath)) {
10
+ logger.error(`Path not found: ${options.focus}`);
11
+ return;
12
+ }
13
+ logger.info(`Generating focused context for: ${options.focus}`);
14
+ const structure = scanDirectory(targetPath, 0, 2); // Depth 2 for focused view
15
+ const summary = generateFocusedSummary(structure, options.focus);
16
+ console.log(summary); // Output to stdout for agent to read
17
+ return;
18
+ }
19
+ if (options.query) {
20
+ // Simple keyword search in existing context files (placeholder for now)
21
+ logger.info(`Searching context for: ${options.query}`);
22
+ // TODO: Implement grep/search across .devmind/ files
23
+ console.log(`> Context search for "${options.query}" not yet implemented. Use --focus <path> to see file structure.`);
24
+ }
25
+ // Default: Show high-level map
26
+ logger.info('No focus specified. Showing high-level project map.');
27
+ const rootStructure = scanDirectory(cwd, 0, 1); // Depth 1 for root
28
+ console.log(generateFocusedSummary(rootStructure, '.'));
29
+ }
30
+ function generateFocusedSummary(node, relPath) {
31
+ let output = `# Context: ${relPath}\n\n`;
32
+ function renderNode(n, depth) {
33
+ const indent = ' '.repeat(depth);
34
+ const icon = n.type === 'directory' ? '📁' : '📄';
35
+ const meta = n.type === 'file' && n.size ? ` (${(n.size / 1024).toFixed(1)}KB)` : '';
36
+ output += `${indent}- ${icon} ${n.name}${meta}\n`;
37
+ // Show exports for files if available (Context Slicing magic)
38
+ if (n.type === 'file' && n.exports && n.exports.length > 0) {
39
+ const exports = n.exports.map((e) => (typeof e === 'string' ? e : e.name)).slice(0, 5);
40
+ output += `${indent} - Exports: \`${exports.join(', ')}\`${n.exports.length > 5 ? '...' : ''}\n`;
41
+ }
42
+ if (n.children) {
43
+ n.children.forEach((c) => renderNode(c, depth + 1));
44
+ }
45
+ }
46
+ if (node.children) {
47
+ node.children.forEach((c) => renderNode(c, 0));
48
+ }
49
+ else {
50
+ output += '(Empty directory)\n';
51
+ }
52
+ return output;
53
+ }
54
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/commands/context.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Configuration loading and management
3
+ */
4
+ export interface DevMindConfig {
5
+ outputDir?: string;
6
+ databases?: Record<string, string>;
7
+ codebase?: {
8
+ ignore?: string[];
9
+ maxDepth?: number;
10
+ include?: string[];
11
+ exclude?: string[];
12
+ };
13
+ watch?: {
14
+ enabled?: boolean;
15
+ paths?: string[];
16
+ };
17
+ }
18
+ export declare function loadConfig(configPath?: string): Promise<DevMindConfig>;
19
+ export declare function getOutputDir(config: DevMindConfig): string;
20
+ export declare function resolveOutputPath(config: DevMindConfig, ...parts: string[]): string;
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Configuration loading and management
3
+ */
4
+ import * as path from 'path';
5
+ import { fileExists, readJSON } from './fileio.js';
6
+ import { ConfigError } from './errors.js';
7
+ const DEFAULT_CONFIG = {
8
+ outputDir: '.devmind',
9
+ codebase: {
10
+ ignore: ['node_modules', 'dist', '.git', 'coverage'],
11
+ maxDepth: 10,
12
+ },
13
+ };
14
+ export async function loadConfig(configPath) {
15
+ const paths = [
16
+ configPath,
17
+ '.devmindrc.json',
18
+ '.cohererc.json', // Backward compatibility
19
+ 'devmind.config.json',
20
+ ].filter(Boolean);
21
+ for (const p of paths) {
22
+ if (await fileExists(p)) {
23
+ try {
24
+ const config = await readJSON(p);
25
+ return { ...DEFAULT_CONFIG, ...config };
26
+ }
27
+ catch (error) {
28
+ throw new ConfigError(`Invalid config file: ${p}`);
29
+ }
30
+ }
31
+ }
32
+ return DEFAULT_CONFIG;
33
+ }
34
+ export function getOutputDir(config) {
35
+ return config.outputDir || DEFAULT_CONFIG.outputDir;
36
+ }
37
+ export function resolveOutputPath(config, ...parts) {
38
+ return path.join(process.cwd(), getOutputDir(config), ...parts);
39
+ }
40
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAiB1C,MAAM,cAAc,GAAkB;IACpC,SAAS,EAAE,UAAU;IACrB,QAAQ,EAAE;QACR,MAAM,EAAE,CAAC,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC;QACpD,QAAQ,EAAE,EAAE;KACb;CACF,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,UAAmB;IAClD,MAAM,KAAK,GAAG;QACZ,UAAU;QACV,iBAAiB;QACjB,gBAAgB,EAAE,yBAAyB;QAC3C,qBAAqB;KACtB,CAAC,MAAM,CAAC,OAAO,CAAa,CAAC;IAE9B,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,IAAI,MAAM,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;YACxB,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAgB,CAAC,CAAC,CAAC;gBAChD,OAAO,EAAE,GAAG,cAAc,EAAE,GAAG,MAAM,EAAE,CAAC;YAC1C,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,IAAI,WAAW,CAAC,wBAAwB,CAAC,EAAE,CAAC,CAAC;YACrD,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,cAAc,CAAC;AACxB,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,MAAqB;IAChD,OAAO,MAAM,CAAC,SAAS,IAAI,cAAc,CAAC,SAAU,CAAC;AACvD,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,MAAqB,EAAE,GAAG,KAAe;IACzE,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,YAAY,CAAC,MAAM,CAAC,EAAE,GAAG,KAAK,CAAC,CAAC;AAClE,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Error handling helpers
3
+ */
4
+ export declare class DevMindError extends Error {
5
+ code?: string | undefined;
6
+ constructor(message: string, code?: string | undefined);
7
+ }
8
+ export declare class DatabaseError extends DevMindError {
9
+ constructor(message: string);
10
+ }
11
+ export declare class CodebaseError extends DevMindError {
12
+ constructor(message: string);
13
+ }
14
+ export declare class ConfigError extends DevMindError {
15
+ constructor(message: string);
16
+ }
17
+ export declare function handleError(error: Error, verbose?: boolean): never;
18
+ export declare function wrapAsync<T extends any[], R>(fn: (...args: T) => Promise<R>): (...args: T) => Promise<R>;
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Error handling helpers
3
+ */
4
+ import { logger } from './logger.js';
5
+ export class DevMindError extends Error {
6
+ code;
7
+ constructor(message, code) {
8
+ super(message);
9
+ this.code = code;
10
+ this.name = 'DevMindError';
11
+ }
12
+ }
13
+ export class DatabaseError extends DevMindError {
14
+ constructor(message) {
15
+ super(message, 'DB_ERROR');
16
+ this.name = 'DatabaseError';
17
+ }
18
+ }
19
+ export class CodebaseError extends DevMindError {
20
+ constructor(message) {
21
+ super(message, 'CODEBASE_ERROR');
22
+ this.name = 'CodebaseError';
23
+ }
24
+ }
25
+ export class ConfigError extends DevMindError {
26
+ constructor(message) {
27
+ super(message, 'CONFIG_ERROR');
28
+ this.name = 'ConfigError';
29
+ }
30
+ }
31
+ export function handleError(error, verbose = false) {
32
+ if (error instanceof DevMindError) {
33
+ logger.error(error.message);
34
+ }
35
+ else {
36
+ logger.error(`Unexpected error: ${error.message}`);
37
+ }
38
+ if (verbose) {
39
+ console.error(error.stack);
40
+ }
41
+ process.exit(1);
42
+ }
43
+ export function wrapAsync(fn) {
44
+ return async (...args) => {
45
+ try {
46
+ return await fn(...args);
47
+ }
48
+ catch (error) {
49
+ handleError(error);
50
+ }
51
+ };
52
+ }
53
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/core/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,MAAM,OAAO,YAAa,SAAQ,KAAK;IAG5B;IAFT,YACE,OAAe,EACR,IAAa;QAEpB,KAAK,CAAC,OAAO,CAAC,CAAC;QAFR,SAAI,GAAJ,IAAI,CAAS;QAGpB,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;IAC7B,CAAC;CACF;AAED,MAAM,OAAO,aAAc,SAAQ,YAAY;IAC7C,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;QAC3B,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;IAC9B,CAAC;CACF;AAED,MAAM,OAAO,aAAc,SAAQ,YAAY;IAC7C,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,EAAE,gBAAgB,CAAC,CAAC;QACjC,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;IAC9B,CAAC;CACF;AAED,MAAM,OAAO,WAAY,SAAQ,YAAY;IAC3C,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;QAC/B,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC;IAC5B,CAAC;CACF;AAED,MAAM,UAAU,WAAW,CAAC,KAAY,EAAE,UAAmB,KAAK;IAChE,IAAI,KAAK,YAAY,YAAY,EAAE,CAAC;QAClC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC9B,CAAC;SAAM,CAAC;QACN,MAAM,CAAC,KAAK,CAAC,qBAAqB,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IACrD,CAAC;IAED,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC7B,CAAC;IAED,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,SAAS,CACvB,EAA8B;IAE9B,OAAO,KAAK,EAAE,GAAG,IAAO,EAAc,EAAE;QACtC,IAAI,CAAC;YACH,OAAO,MAAM,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;QAC3B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,WAAW,CAAC,KAAc,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * File I/O utilities with error handling
3
+ */
4
+ export declare function ensureDir(dirPath: string): Promise<void>;
5
+ export declare function writeFileSafe(filePath: string, content: string): Promise<void>;
6
+ export declare function readFileSafe(filePath: string): Promise<string>;
7
+ export declare function fileExists(filePath: string): Promise<boolean>;
8
+ export declare function normalizePath(filePath: string): string;
9
+ export declare function writeJSON<T>(filePath: string, data: T): Promise<void>;
10
+ export declare function readJSON<T>(filePath: string): Promise<T>;
@@ -0,0 +1,57 @@
1
+ /**
2
+ * File I/O utilities with error handling
3
+ */
4
+ import * as fs from 'fs';
5
+ import * as path from 'path';
6
+ import { promisify } from 'util';
7
+ const mkdir = promisify(fs.mkdir);
8
+ const writeFile = promisify(fs.writeFile);
9
+ const readFile = promisify(fs.readFile);
10
+ const access = promisify(fs.access);
11
+ export async function ensureDir(dirPath) {
12
+ try {
13
+ await mkdir(dirPath, { recursive: true });
14
+ }
15
+ catch (error) {
16
+ if (error.code !== 'EEXIST') {
17
+ throw error;
18
+ }
19
+ }
20
+ }
21
+ export async function writeFileSafe(filePath, content) {
22
+ const dir = path.dirname(filePath);
23
+ await ensureDir(dir);
24
+ await writeFile(filePath, content, 'utf-8');
25
+ }
26
+ export async function readFileSafe(filePath) {
27
+ try {
28
+ return await readFile(filePath, 'utf-8');
29
+ }
30
+ catch (error) {
31
+ if (error.code === 'ENOENT') {
32
+ throw new Error(`File not found: ${filePath}`);
33
+ }
34
+ throw error;
35
+ }
36
+ }
37
+ export async function fileExists(filePath) {
38
+ try {
39
+ await access(filePath, fs.constants.F_OK);
40
+ return true;
41
+ }
42
+ catch {
43
+ return false;
44
+ }
45
+ }
46
+ export function normalizePath(filePath) {
47
+ return path.normalize(filePath).replace(/\\/g, '/');
48
+ }
49
+ export async function writeJSON(filePath, data) {
50
+ const content = JSON.stringify(data, null, 2);
51
+ await writeFileSafe(filePath, content);
52
+ }
53
+ export async function readJSON(filePath) {
54
+ const content = await readFileSafe(filePath);
55
+ return JSON.parse(content);
56
+ }
57
+ //# sourceMappingURL=fileio.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fileio.js","sourceRoot":"","sources":["../../src/core/fileio.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AAEjC,MAAM,KAAK,GAAG,SAAS,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;AAClC,MAAM,SAAS,GAAG,SAAS,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC;AAC1C,MAAM,QAAQ,GAAG,SAAS,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC;AACxC,MAAM,MAAM,GAAG,SAAS,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;AAEpC,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,OAAe;IAC7C,IAAI,CAAC;QACH,MAAM,KAAK,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACvD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,QAAgB,EAAE,OAAe;IACnE,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACnC,MAAM,SAAS,CAAC,GAAG,CAAC,CAAC;IACrB,MAAM,SAAS,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;AAC9C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,QAAgB;IACjD,IAAI,CAAC;QACH,OAAO,MAAM,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC3C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACvD,MAAM,IAAI,KAAK,CAAC,mBAAmB,QAAQ,EAAE,CAAC,CAAC;QACjD,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,QAAgB;IAC/C,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QAC1C,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,QAAgB;IAC5C,OAAO,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;AACtD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAAI,QAAgB,EAAE,IAAO;IAC1D,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAC9C,MAAM,aAAa,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;AACzC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAI,QAAgB;IAChD,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC,QAAQ,CAAC,CAAC;IAC7C,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAM,CAAC;AAClC,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Core module exports
3
+ */
4
+ export * from './types.js';
5
+ export * from './logger.js';
6
+ export * from './errors.js';
7
+ export * from './fileio.js';
8
+ export * from './config.js';
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Core module exports
3
+ */
4
+ export * from './types.js';
5
+ export * from './logger.js';
6
+ export * from './errors.js';
7
+ export * from './fileio.js';
8
+ export * from './config.js';
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Logger utilities using chalk for colored output
3
+ */
4
+ export declare class Logger {
5
+ private verbose;
6
+ constructor(verbose?: boolean);
7
+ error(message: string, error?: Error): void;
8
+ success(message: string): void;
9
+ info(message: string): void;
10
+ warn(message: string): void;
11
+ debug(message: string): void;
12
+ log(message: string): void;
13
+ }
14
+ export declare const logger: Logger;
15
+ export declare function createLogger(verbose?: boolean): Logger;
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Logger utilities using chalk for colored output
3
+ */
4
+ import chalk from 'chalk';
5
+ export class Logger {
6
+ verbose;
7
+ constructor(verbose = false) {
8
+ this.verbose = verbose;
9
+ }
10
+ error(message, error) {
11
+ console.error(chalk.red(`✗ ${message}`));
12
+ if (this.verbose && error) {
13
+ console.error(chalk.gray(error.stack || error.message));
14
+ }
15
+ }
16
+ success(message) {
17
+ console.log(chalk.green(`✓ ${message}`));
18
+ }
19
+ info(message) {
20
+ console.log(chalk.blue(`ℹ ${message}`));
21
+ }
22
+ warn(message) {
23
+ console.log(chalk.yellow(`⚠ ${message}`));
24
+ }
25
+ debug(message) {
26
+ if (this.verbose) {
27
+ console.log(chalk.gray(`[DEBUG] ${message}`));
28
+ }
29
+ }
30
+ log(message) {
31
+ console.log(message);
32
+ }
33
+ }
34
+ // Default logger instance
35
+ export const logger = new Logger();
36
+ // Create logger with verbose mode
37
+ export function createLogger(verbose = false) {
38
+ return new Logger(verbose);
39
+ }
40
+ //# sourceMappingURL=logger.js.map