@hyperdrive.bot/gut 0.1.3 → 0.1.6
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 +1 -779
- package/bin/run.js +5 -0
- package/package.json +10 -10
- package/bin/run +0 -5
- package/dist/base-command.d.ts +0 -21
- package/dist/base-command.js +0 -110
- package/dist/commands/add.d.ts +0 -13
- package/dist/commands/add.js +0 -73
- package/dist/commands/affected.d.ts +0 -23
- package/dist/commands/affected.js +0 -326
- package/dist/commands/audit.d.ts +0 -33
- package/dist/commands/audit.js +0 -593
- package/dist/commands/back.d.ts +0 -6
- package/dist/commands/back.js +0 -29
- package/dist/commands/commit.d.ts +0 -11
- package/dist/commands/commit.js +0 -113
- package/dist/commands/context.d.ts +0 -6
- package/dist/commands/context.js +0 -36
- package/dist/commands/contexts.d.ts +0 -7
- package/dist/commands/contexts.js +0 -92
- package/dist/commands/deps.d.ts +0 -10
- package/dist/commands/deps.js +0 -104
- package/dist/commands/entity/add.d.ts +0 -16
- package/dist/commands/entity/add.js +0 -105
- package/dist/commands/entity/clone-all.d.ts +0 -17
- package/dist/commands/entity/clone-all.js +0 -135
- package/dist/commands/entity/clone.d.ts +0 -15
- package/dist/commands/entity/clone.js +0 -109
- package/dist/commands/entity/list.d.ts +0 -11
- package/dist/commands/entity/list.js +0 -82
- package/dist/commands/entity/remove.d.ts +0 -12
- package/dist/commands/entity/remove.js +0 -58
- package/dist/commands/focus.d.ts +0 -19
- package/dist/commands/focus.js +0 -139
- package/dist/commands/graph.d.ts +0 -18
- package/dist/commands/graph.js +0 -238
- package/dist/commands/init.d.ts +0 -11
- package/dist/commands/init.js +0 -84
- package/dist/commands/insights.d.ts +0 -21
- package/dist/commands/insights.js +0 -434
- package/dist/commands/patterns.d.ts +0 -40
- package/dist/commands/patterns.js +0 -412
- package/dist/commands/pull.d.ts +0 -11
- package/dist/commands/pull.js +0 -121
- package/dist/commands/push.d.ts +0 -11
- package/dist/commands/push.js +0 -101
- package/dist/commands/quick-setup.d.ts +0 -20
- package/dist/commands/quick-setup.js +0 -422
- package/dist/commands/recent.d.ts +0 -9
- package/dist/commands/recent.js +0 -55
- package/dist/commands/related.d.ts +0 -23
- package/dist/commands/related.js +0 -257
- package/dist/commands/repos.d.ts +0 -14
- package/dist/commands/repos.js +0 -185
- package/dist/commands/stack.d.ts +0 -10
- package/dist/commands/stack.js +0 -83
- package/dist/commands/status.d.ts +0 -14
- package/dist/commands/status.js +0 -246
- package/dist/commands/sync.d.ts +0 -11
- package/dist/commands/sync.js +0 -142
- package/dist/commands/unfocus.d.ts +0 -6
- package/dist/commands/unfocus.js +0 -23
- package/dist/commands/used-by.d.ts +0 -10
- package/dist/commands/used-by.js +0 -111
- package/dist/commands/workspace.d.ts +0 -20
- package/dist/commands/workspace.js +0 -365
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -5
- package/dist/models/entity.model.d.ts +0 -81
- package/dist/models/entity.model.js +0 -2
- package/dist/services/config.service.d.ts +0 -34
- package/dist/services/config.service.js +0 -230
- package/dist/services/entity.service.d.ts +0 -19
- package/dist/services/entity.service.js +0 -130
- package/dist/services/focus.service.d.ts +0 -70
- package/dist/services/focus.service.js +0 -587
- package/dist/services/git.service.d.ts +0 -37
- package/dist/services/git.service.js +0 -180
- package/dist/utils/display.d.ts +0 -25
- package/dist/utils/display.js +0 -150
- package/dist/utils/filesystem.d.ts +0 -32
- package/dist/utils/filesystem.js +0 -220
- package/dist/utils/index.d.ts +0 -13
- package/dist/utils/index.js +0 -18
- package/dist/utils/validation.d.ts +0 -22
- package/dist/utils/validation.js +0 -196
- package/oclif.manifest.json +0 -1463
|
@@ -1,434 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const tslib_1 = require("tslib");
|
|
4
|
-
const core_1 = require("@oclif/core");
|
|
5
|
-
const base_command_1 = tslib_1.__importDefault(require("../base-command"));
|
|
6
|
-
const fs = tslib_1.__importStar(require("fs"));
|
|
7
|
-
const path = tslib_1.__importStar(require("path"));
|
|
8
|
-
const child_process_1 = require("child_process");
|
|
9
|
-
const chalk_1 = tslib_1.__importDefault(require("chalk"));
|
|
10
|
-
const ora_1 = tslib_1.__importDefault(require("ora"));
|
|
11
|
-
const cli_table3_1 = tslib_1.__importDefault(require("cli-table3"));
|
|
12
|
-
class Insights extends base_command_1.default {
|
|
13
|
-
static description = 'Display analytics and insights about the workspace';
|
|
14
|
-
static examples = [
|
|
15
|
-
'<%= config.bin %> <%= command.id %>',
|
|
16
|
-
'<%= config.bin %> <%= command.id %> --detailed',
|
|
17
|
-
'<%= config.bin %> <%= command.id %> --format json',
|
|
18
|
-
];
|
|
19
|
-
static flags = {
|
|
20
|
-
detailed: core_1.Flags.boolean({
|
|
21
|
-
char: 'd',
|
|
22
|
-
description: 'Show detailed statistics for each entity',
|
|
23
|
-
default: false,
|
|
24
|
-
}),
|
|
25
|
-
format: core_1.Flags.string({
|
|
26
|
-
char: 'f',
|
|
27
|
-
description: 'Output format',
|
|
28
|
-
options: ['table', 'json', 'summary'],
|
|
29
|
-
default: 'table',
|
|
30
|
-
}),
|
|
31
|
-
'include-ignored': core_1.Flags.boolean({
|
|
32
|
-
description: 'Include gitignored files in statistics',
|
|
33
|
-
default: false,
|
|
34
|
-
}),
|
|
35
|
-
};
|
|
36
|
-
async run() {
|
|
37
|
-
const { flags } = await this.parse(Insights);
|
|
38
|
-
const { detailed, format, 'include-ignored': includeIgnored } = flags;
|
|
39
|
-
const spinner = (0, ora_1.default)('Analyzing workspace').start();
|
|
40
|
-
try {
|
|
41
|
-
const entities = await this.entityService.listEntities();
|
|
42
|
-
if (entities.length === 0) {
|
|
43
|
-
spinner.fail('No entities found in workspace');
|
|
44
|
-
this.log(chalk_1.default.yellow('Initialize your workspace with: gut init'));
|
|
45
|
-
return;
|
|
46
|
-
}
|
|
47
|
-
const entityStats = [];
|
|
48
|
-
for (const entity of entities) {
|
|
49
|
-
const stats = await this.analyzeEntity(entity, includeIgnored);
|
|
50
|
-
entityStats.push({ entity, stats });
|
|
51
|
-
}
|
|
52
|
-
const workspaceStats = this.calculateWorkspaceStats(entityStats);
|
|
53
|
-
spinner.succeed('Analysis complete');
|
|
54
|
-
switch (format) {
|
|
55
|
-
case 'json':
|
|
56
|
-
this.printJSON(workspaceStats, entityStats);
|
|
57
|
-
break;
|
|
58
|
-
case 'summary':
|
|
59
|
-
this.printSummary(workspaceStats);
|
|
60
|
-
break;
|
|
61
|
-
case 'table':
|
|
62
|
-
default:
|
|
63
|
-
this.printTable(workspaceStats, entityStats, detailed);
|
|
64
|
-
break;
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
catch (error) {
|
|
68
|
-
spinner.fail();
|
|
69
|
-
this.error(error.message);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
async analyzeEntity(entity, includeIgnored) {
|
|
73
|
-
const stats = {
|
|
74
|
-
files: 0,
|
|
75
|
-
lines: 0,
|
|
76
|
-
size: '0B',
|
|
77
|
-
languages: new Map(),
|
|
78
|
-
lastCommit: 'N/A',
|
|
79
|
-
contributors: 0,
|
|
80
|
-
branches: 0,
|
|
81
|
-
uncommitted: 0,
|
|
82
|
-
};
|
|
83
|
-
const entityPath = path.resolve(entity.path);
|
|
84
|
-
if (!fs.existsSync(entityPath)) {
|
|
85
|
-
return stats;
|
|
86
|
-
}
|
|
87
|
-
// Count files and lines
|
|
88
|
-
const fileStats = this.countFiles(entityPath, includeIgnored);
|
|
89
|
-
stats.files = fileStats.files;
|
|
90
|
-
stats.lines = fileStats.lines;
|
|
91
|
-
stats.size = this.formatSize(fileStats.size);
|
|
92
|
-
stats.languages = fileStats.languages;
|
|
93
|
-
// Git statistics
|
|
94
|
-
if (fs.existsSync(path.join(entityPath, '.git'))) {
|
|
95
|
-
try {
|
|
96
|
-
// Last commit
|
|
97
|
-
const lastCommit = (0, child_process_1.execSync)('git log -1 --format=%ar', {
|
|
98
|
-
cwd: entityPath,
|
|
99
|
-
encoding: 'utf-8',
|
|
100
|
-
stdio: 'pipe',
|
|
101
|
-
}).trim();
|
|
102
|
-
stats.lastCommit = lastCommit;
|
|
103
|
-
// Contributors
|
|
104
|
-
const contributors = (0, child_process_1.execSync)('git shortlog -sn', {
|
|
105
|
-
cwd: entityPath,
|
|
106
|
-
encoding: 'utf-8',
|
|
107
|
-
stdio: 'pipe',
|
|
108
|
-
}).split('\n').filter(l => l.trim()).length;
|
|
109
|
-
stats.contributors = contributors;
|
|
110
|
-
// Branches
|
|
111
|
-
const branches = (0, child_process_1.execSync)('git branch -a', {
|
|
112
|
-
cwd: entityPath,
|
|
113
|
-
encoding: 'utf-8',
|
|
114
|
-
stdio: 'pipe',
|
|
115
|
-
}).split('\n').filter(l => l.trim()).length;
|
|
116
|
-
stats.branches = branches;
|
|
117
|
-
// Uncommitted changes
|
|
118
|
-
const status = (0, child_process_1.execSync)('git status --porcelain', {
|
|
119
|
-
cwd: entityPath,
|
|
120
|
-
encoding: 'utf-8',
|
|
121
|
-
stdio: 'pipe',
|
|
122
|
-
}).split('\n').filter(l => l.trim()).length;
|
|
123
|
-
stats.uncommitted = status;
|
|
124
|
-
}
|
|
125
|
-
catch (error) {
|
|
126
|
-
// Ignore git errors
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
return stats;
|
|
130
|
-
}
|
|
131
|
-
countFiles(dir, includeIgnored) {
|
|
132
|
-
const result = {
|
|
133
|
-
files: 0,
|
|
134
|
-
lines: 0,
|
|
135
|
-
size: 0,
|
|
136
|
-
languages: new Map(),
|
|
137
|
-
};
|
|
138
|
-
const shouldIgnore = (file) => {
|
|
139
|
-
if (includeIgnored)
|
|
140
|
-
return false;
|
|
141
|
-
const ignoredPatterns = ['node_modules', '.git', 'dist', 'build', '.next', 'coverage'];
|
|
142
|
-
return ignoredPatterns.some(pattern => file.includes(pattern));
|
|
143
|
-
};
|
|
144
|
-
const walkDir = (currentDir) => {
|
|
145
|
-
try {
|
|
146
|
-
const entries = fs.readdirSync(currentDir, { withFileTypes: true });
|
|
147
|
-
for (const entry of entries) {
|
|
148
|
-
const fullPath = path.join(currentDir, entry.name);
|
|
149
|
-
if (shouldIgnore(fullPath))
|
|
150
|
-
continue;
|
|
151
|
-
if (entry.isDirectory()) {
|
|
152
|
-
walkDir(fullPath);
|
|
153
|
-
}
|
|
154
|
-
else if (entry.isFile()) {
|
|
155
|
-
result.files++;
|
|
156
|
-
const stats = fs.statSync(fullPath);
|
|
157
|
-
result.size += stats.size;
|
|
158
|
-
const ext = path.extname(fullPath).toLowerCase();
|
|
159
|
-
const lang = this.getLanguageFromExt(ext);
|
|
160
|
-
if (lang) {
|
|
161
|
-
result.languages.set(lang, (result.languages.get(lang) || 0) + 1);
|
|
162
|
-
}
|
|
163
|
-
// Count lines for text files
|
|
164
|
-
if (this.isTextFile(fullPath)) {
|
|
165
|
-
try {
|
|
166
|
-
const content = fs.readFileSync(fullPath, 'utf-8');
|
|
167
|
-
result.lines += content.split('\n').length;
|
|
168
|
-
}
|
|
169
|
-
catch (error) {
|
|
170
|
-
// Ignore read errors
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
catch (error) {
|
|
177
|
-
// Ignore permission errors
|
|
178
|
-
}
|
|
179
|
-
};
|
|
180
|
-
walkDir(dir);
|
|
181
|
-
return result;
|
|
182
|
-
}
|
|
183
|
-
getLanguageFromExt(ext) {
|
|
184
|
-
const langMap = {
|
|
185
|
-
'.js': 'JavaScript',
|
|
186
|
-
'.jsx': 'JavaScript',
|
|
187
|
-
'.ts': 'TypeScript',
|
|
188
|
-
'.tsx': 'TypeScript',
|
|
189
|
-
'.py': 'Python',
|
|
190
|
-
'.java': 'Java',
|
|
191
|
-
'.go': 'Go',
|
|
192
|
-
'.rs': 'Rust',
|
|
193
|
-
'.rb': 'Ruby',
|
|
194
|
-
'.php': 'PHP',
|
|
195
|
-
'.c': 'C',
|
|
196
|
-
'.cpp': 'C++',
|
|
197
|
-
'.cs': 'C#',
|
|
198
|
-
'.swift': 'Swift',
|
|
199
|
-
'.kt': 'Kotlin',
|
|
200
|
-
'.scala': 'Scala',
|
|
201
|
-
'.r': 'R',
|
|
202
|
-
'.m': 'Objective-C',
|
|
203
|
-
'.dart': 'Dart',
|
|
204
|
-
'.vue': 'Vue',
|
|
205
|
-
'.svelte': 'Svelte',
|
|
206
|
-
'.json': 'JSON',
|
|
207
|
-
'.yml': 'YAML',
|
|
208
|
-
'.yaml': 'YAML',
|
|
209
|
-
'.xml': 'XML',
|
|
210
|
-
'.html': 'HTML',
|
|
211
|
-
'.css': 'CSS',
|
|
212
|
-
'.scss': 'SCSS',
|
|
213
|
-
'.sass': 'Sass',
|
|
214
|
-
'.less': 'Less',
|
|
215
|
-
'.sql': 'SQL',
|
|
216
|
-
'.sh': 'Shell',
|
|
217
|
-
'.bash': 'Shell',
|
|
218
|
-
'.md': 'Markdown',
|
|
219
|
-
};
|
|
220
|
-
return langMap[ext] || null;
|
|
221
|
-
}
|
|
222
|
-
isTextFile(filePath) {
|
|
223
|
-
const textExts = [
|
|
224
|
-
'.js', '.jsx', '.ts', '.tsx', '.json', '.md', '.txt',
|
|
225
|
-
'.yml', '.yaml', '.xml', '.html', '.css', '.scss', '.sass',
|
|
226
|
-
'.py', '.rb', '.go', '.rs', '.java', '.c', '.cpp', '.h',
|
|
227
|
-
'.php', '.sql', '.sh', '.bash', '.env', '.gitignore'
|
|
228
|
-
];
|
|
229
|
-
const ext = path.extname(filePath).toLowerCase();
|
|
230
|
-
return textExts.includes(ext);
|
|
231
|
-
}
|
|
232
|
-
formatSize(bytes) {
|
|
233
|
-
const units = ['B', 'KB', 'MB', 'GB'];
|
|
234
|
-
let size = bytes;
|
|
235
|
-
let unitIndex = 0;
|
|
236
|
-
while (size >= 1024 && unitIndex < units.length - 1) {
|
|
237
|
-
size /= 1024;
|
|
238
|
-
unitIndex++;
|
|
239
|
-
}
|
|
240
|
-
return `${size.toFixed(1)}${units[unitIndex]}`;
|
|
241
|
-
}
|
|
242
|
-
calculateWorkspaceStats(entityStats) {
|
|
243
|
-
let totalFiles = 0;
|
|
244
|
-
let totalLines = 0;
|
|
245
|
-
let totalSize = 0;
|
|
246
|
-
const allLanguages = new Map();
|
|
247
|
-
let mostActive = '';
|
|
248
|
-
let mostActiveCommit = new Date(0);
|
|
249
|
-
let leastActive = '';
|
|
250
|
-
let leastActiveCommit = new Date();
|
|
251
|
-
let largestEntity = '';
|
|
252
|
-
let largestSize = 0;
|
|
253
|
-
let smallestEntity = '';
|
|
254
|
-
let smallestSize = Infinity;
|
|
255
|
-
for (const { entity, stats } of entityStats) {
|
|
256
|
-
totalFiles += stats.files;
|
|
257
|
-
totalLines += stats.lines;
|
|
258
|
-
// Parse size back to bytes for total
|
|
259
|
-
const sizeMatch = stats.size.match(/(\d+\.?\d*)([BKMG])/);
|
|
260
|
-
if (sizeMatch) {
|
|
261
|
-
const value = parseFloat(sizeMatch[1]);
|
|
262
|
-
const unit = sizeMatch[2];
|
|
263
|
-
const multipliers = { B: 1, K: 1024, M: 1024 * 1024, G: 1024 * 1024 * 1024 };
|
|
264
|
-
totalSize += value * multipliers[unit];
|
|
265
|
-
}
|
|
266
|
-
// Merge languages
|
|
267
|
-
stats.languages.forEach((count, lang) => {
|
|
268
|
-
allLanguages.set(lang, (allLanguages.get(lang) || 0) + count);
|
|
269
|
-
});
|
|
270
|
-
// Track most/least active
|
|
271
|
-
if (stats.lastCommit !== 'N/A') {
|
|
272
|
-
const commitDate = this.parseRelativeDate(stats.lastCommit);
|
|
273
|
-
if (commitDate > mostActiveCommit) {
|
|
274
|
-
mostActiveCommit = commitDate;
|
|
275
|
-
mostActive = entity.name;
|
|
276
|
-
}
|
|
277
|
-
if (commitDate < leastActiveCommit) {
|
|
278
|
-
leastActiveCommit = commitDate;
|
|
279
|
-
leastActive = entity.name;
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
// Track largest/smallest
|
|
283
|
-
const entitySize = stats.files;
|
|
284
|
-
if (entitySize > largestSize) {
|
|
285
|
-
largestSize = entitySize;
|
|
286
|
-
largestEntity = entity.name;
|
|
287
|
-
}
|
|
288
|
-
if (entitySize < smallestSize && entitySize > 0) {
|
|
289
|
-
smallestSize = entitySize;
|
|
290
|
-
smallestEntity = entity.name;
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
return {
|
|
294
|
-
totalEntities: entityStats.length,
|
|
295
|
-
totalFiles,
|
|
296
|
-
totalLines,
|
|
297
|
-
totalSize: this.formatSize(totalSize),
|
|
298
|
-
languages: allLanguages,
|
|
299
|
-
mostActive,
|
|
300
|
-
leastActive,
|
|
301
|
-
largestEntity,
|
|
302
|
-
smallestEntity,
|
|
303
|
-
};
|
|
304
|
-
}
|
|
305
|
-
parseRelativeDate(relativeDate) {
|
|
306
|
-
const now = new Date();
|
|
307
|
-
const match = relativeDate.match(/(\d+)\s+(\w+)\s+ago/);
|
|
308
|
-
if (!match)
|
|
309
|
-
return now;
|
|
310
|
-
const value = parseInt(match[1]);
|
|
311
|
-
const unit = match[2];
|
|
312
|
-
const date = new Date(now);
|
|
313
|
-
switch (unit) {
|
|
314
|
-
case 'second':
|
|
315
|
-
case 'seconds':
|
|
316
|
-
date.setSeconds(date.getSeconds() - value);
|
|
317
|
-
break;
|
|
318
|
-
case 'minute':
|
|
319
|
-
case 'minutes':
|
|
320
|
-
date.setMinutes(date.getMinutes() - value);
|
|
321
|
-
break;
|
|
322
|
-
case 'hour':
|
|
323
|
-
case 'hours':
|
|
324
|
-
date.setHours(date.getHours() - value);
|
|
325
|
-
break;
|
|
326
|
-
case 'day':
|
|
327
|
-
case 'days':
|
|
328
|
-
date.setDate(date.getDate() - value);
|
|
329
|
-
break;
|
|
330
|
-
case 'week':
|
|
331
|
-
case 'weeks':
|
|
332
|
-
date.setDate(date.getDate() - value * 7);
|
|
333
|
-
break;
|
|
334
|
-
case 'month':
|
|
335
|
-
case 'months':
|
|
336
|
-
date.setMonth(date.getMonth() - value);
|
|
337
|
-
break;
|
|
338
|
-
case 'year':
|
|
339
|
-
case 'years':
|
|
340
|
-
date.setFullYear(date.getFullYear() - value);
|
|
341
|
-
break;
|
|
342
|
-
}
|
|
343
|
-
return date;
|
|
344
|
-
}
|
|
345
|
-
printTable(workspaceStats, entityStats, detailed) {
|
|
346
|
-
// Workspace summary
|
|
347
|
-
this.log('');
|
|
348
|
-
this.log(chalk_1.default.bold.blue('📊 Workspace Insights'));
|
|
349
|
-
this.log('');
|
|
350
|
-
const summaryTable = new cli_table3_1.default({
|
|
351
|
-
head: [chalk_1.default.cyan('Metric'), chalk_1.default.cyan('Value')],
|
|
352
|
-
style: { head: [], border: [] }
|
|
353
|
-
});
|
|
354
|
-
summaryTable.push(['Total Entities', workspaceStats.totalEntities.toString()], ['Total Files', workspaceStats.totalFiles.toLocaleString()], ['Total Lines', workspaceStats.totalLines.toLocaleString()], ['Total Size', workspaceStats.totalSize], ['Most Active', workspaceStats.mostActive || 'N/A'], ['Largest Entity', workspaceStats.largestEntity || 'N/A']);
|
|
355
|
-
this.log(summaryTable.toString());
|
|
356
|
-
// Language distribution
|
|
357
|
-
if (workspaceStats.languages.size > 0) {
|
|
358
|
-
this.log('');
|
|
359
|
-
this.log(chalk_1.default.bold('Language Distribution:'));
|
|
360
|
-
const sortedLangs = Array.from(workspaceStats.languages.entries())
|
|
361
|
-
.sort((a, b) => b[1] - a[1])
|
|
362
|
-
.slice(0, 5);
|
|
363
|
-
sortedLangs.forEach(([lang, count]) => {
|
|
364
|
-
const percentage = ((count / workspaceStats.totalFiles) * 100).toFixed(1);
|
|
365
|
-
const bar = '█'.repeat(Math.floor(parseFloat(percentage) / 2));
|
|
366
|
-
this.log(` ${lang.padEnd(12)} ${bar} ${percentage}%`);
|
|
367
|
-
});
|
|
368
|
-
}
|
|
369
|
-
// Entity details
|
|
370
|
-
if (detailed) {
|
|
371
|
-
this.log('');
|
|
372
|
-
this.log(chalk_1.default.bold('Entity Details:'));
|
|
373
|
-
const entityTable = new cli_table3_1.default({
|
|
374
|
-
head: [
|
|
375
|
-
chalk_1.default.cyan('Entity'),
|
|
376
|
-
chalk_1.default.cyan('Files'),
|
|
377
|
-
chalk_1.default.cyan('Lines'),
|
|
378
|
-
chalk_1.default.cyan('Size'),
|
|
379
|
-
chalk_1.default.cyan('Last Commit'),
|
|
380
|
-
chalk_1.default.cyan('Changes'),
|
|
381
|
-
],
|
|
382
|
-
style: { head: [], border: [] }
|
|
383
|
-
});
|
|
384
|
-
entityStats.forEach(({ entity, stats }) => {
|
|
385
|
-
entityTable.push([
|
|
386
|
-
entity.name,
|
|
387
|
-
stats.files.toString(),
|
|
388
|
-
stats.lines.toLocaleString(),
|
|
389
|
-
stats.size,
|
|
390
|
-
stats.lastCommit,
|
|
391
|
-
stats.uncommitted > 0 ? chalk_1.default.yellow(stats.uncommitted.toString()) : '0',
|
|
392
|
-
]);
|
|
393
|
-
});
|
|
394
|
-
this.log(entityTable.toString());
|
|
395
|
-
}
|
|
396
|
-
this.log('');
|
|
397
|
-
this.log(chalk_1.default.dim('Tip: Use --detailed flag for per-entity statistics'));
|
|
398
|
-
}
|
|
399
|
-
printSummary(workspaceStats) {
|
|
400
|
-
this.log('');
|
|
401
|
-
this.log(chalk_1.default.bold.blue('Workspace Summary'));
|
|
402
|
-
this.log(chalk_1.default.dim('─'.repeat(40)));
|
|
403
|
-
this.log(`Entities: ${workspaceStats.totalEntities}`);
|
|
404
|
-
this.log(`Files: ${workspaceStats.totalFiles.toLocaleString()}`);
|
|
405
|
-
this.log(`Lines: ${workspaceStats.totalLines.toLocaleString()}`);
|
|
406
|
-
this.log(`Size: ${workspaceStats.totalSize}`);
|
|
407
|
-
if (workspaceStats.languages.size > 0) {
|
|
408
|
-
const topLang = Array.from(workspaceStats.languages.entries())
|
|
409
|
-
.sort((a, b) => b[1] - a[1])[0];
|
|
410
|
-
this.log(`Primary Language: ${topLang[0]}`);
|
|
411
|
-
}
|
|
412
|
-
this.log(`Most Active: ${workspaceStats.mostActive || 'N/A'}`);
|
|
413
|
-
this.log(`Largest: ${workspaceStats.largestEntity || 'N/A'}`);
|
|
414
|
-
}
|
|
415
|
-
printJSON(workspaceStats, entityStats) {
|
|
416
|
-
const output = {
|
|
417
|
-
workspace: {
|
|
418
|
-
...workspaceStats,
|
|
419
|
-
languages: Object.fromEntries(workspaceStats.languages),
|
|
420
|
-
},
|
|
421
|
-
entities: entityStats.map(({ entity, stats }) => ({
|
|
422
|
-
name: entity.name,
|
|
423
|
-
type: entity.type,
|
|
424
|
-
path: entity.path,
|
|
425
|
-
stats: {
|
|
426
|
-
...stats,
|
|
427
|
-
languages: Object.fromEntries(stats.languages),
|
|
428
|
-
},
|
|
429
|
-
})),
|
|
430
|
-
};
|
|
431
|
-
this.log(JSON.stringify(output, null, 2));
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
exports.default = Insights;
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import { BaseCommand } from '../base-command';
|
|
2
|
-
export default class Patterns extends BaseCommand {
|
|
3
|
-
static description: string;
|
|
4
|
-
static examples: string[];
|
|
5
|
-
static flags: {
|
|
6
|
-
entity: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
7
|
-
type: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
8
|
-
mode: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
9
|
-
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
10
|
-
};
|
|
11
|
-
run(): Promise<void>;
|
|
12
|
-
private analyzePatterns;
|
|
13
|
-
private analyzeEntityPatterns;
|
|
14
|
-
private analyzeTypePatterns;
|
|
15
|
-
private analyzeModePatterns;
|
|
16
|
-
private analyzeCrossEntityPatterns;
|
|
17
|
-
private generateTemporalPatterns;
|
|
18
|
-
private generateProductivityPatterns;
|
|
19
|
-
private displayPatterns;
|
|
20
|
-
private displayEntityPatterns;
|
|
21
|
-
private displayTypePatterns;
|
|
22
|
-
private displayModePatterns;
|
|
23
|
-
private displayProductivityPatterns;
|
|
24
|
-
private displayTemporalPatterns;
|
|
25
|
-
private analyzeFilePatterns;
|
|
26
|
-
private analyzeCollaborationPatterns;
|
|
27
|
-
private calculateTypicalDuration;
|
|
28
|
-
private getCommonModes;
|
|
29
|
-
private analyzeRelationshipPatterns;
|
|
30
|
-
private getSuccessMetrics;
|
|
31
|
-
private getTypicalActivities;
|
|
32
|
-
private getOptimalDuration;
|
|
33
|
-
private getCommonTools;
|
|
34
|
-
private getSuccessIndicators;
|
|
35
|
-
private getTransitionPatterns;
|
|
36
|
-
private findDependencyChains;
|
|
37
|
-
private findSimilarClusters;
|
|
38
|
-
private findSharedSystems;
|
|
39
|
-
private findWorkflowSimilarities;
|
|
40
|
-
}
|