@adithya-naik/cmd-tracker 1.0.2 β 1.0.3
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/.github/workflows/ci.yml +19 -1
- package/.husky/pre-commit +1 -0
- package/bin/tracker.js +45 -45
- package/eslint.config.js +30 -0
- package/package.json +19 -4
- package/src/commands/clear.js +13 -13
- package/src/commands/export.js +16 -16
- package/src/commands/favorite.js +16 -16
- package/src/commands/hook.js +26 -26
- package/src/commands/init.js +43 -43
- package/src/commands/list.js +32 -32
- package/src/commands/save.js +2 -2
- package/src/commands/search.js +18 -18
- package/src/commands/stats.js +55 -55
- package/src/index.js +2 -2
- package/src/utils/categorizer.js +71 -71
- package/src/utils/hook.js +70 -69
- package/src/utils/storage.js +14 -14
- package/src/utils/validator.js +27 -27
package/src/commands/init.js
CHANGED
|
@@ -8,14 +8,14 @@
|
|
|
8
8
|
* β Any unexpected file system errors
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
const fs = require(
|
|
12
|
-
const path = require(
|
|
13
|
-
const { initStorage } = require(
|
|
14
|
-
const { isInitialized } = require(
|
|
11
|
+
const fs = require('fs');
|
|
12
|
+
const path = require('path');
|
|
13
|
+
const { initStorage } = require('../utils/storage');
|
|
14
|
+
const { isInitialized } = require('../utils/validator');
|
|
15
15
|
|
|
16
16
|
function initCommand() {
|
|
17
17
|
|
|
18
|
-
console.log(
|
|
18
|
+
console.log('π Initializing cmd-tracker in your project...\n');
|
|
19
19
|
|
|
20
20
|
try {
|
|
21
21
|
|
|
@@ -25,9 +25,9 @@ function initCommand() {
|
|
|
25
25
|
* but still continue in case files are corrupted
|
|
26
26
|
*/
|
|
27
27
|
if (isInitialized()) {
|
|
28
|
-
console.log(
|
|
29
|
-
console.log(
|
|
30
|
-
console.log(
|
|
28
|
+
console.log('β οΈ cmd-tracker is already initialized in this project!');
|
|
29
|
+
console.log('π‘ Your existing commands are safe');
|
|
30
|
+
console.log('π‘ Running init again will not delete your saved commands\n');
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
/*
|
|
@@ -41,15 +41,15 @@ function initCommand() {
|
|
|
41
41
|
*/
|
|
42
42
|
updateGitignore();
|
|
43
43
|
|
|
44
|
-
console.log(
|
|
45
|
-
console.log(
|
|
46
|
-
console.log(
|
|
47
|
-
console.log(
|
|
48
|
-
console.log(
|
|
49
|
-
console.log(
|
|
50
|
-
console.log(
|
|
51
|
-
console.log(
|
|
52
|
-
console.log(
|
|
44
|
+
console.log('\nβ
cmd-tracker initialized successfully!');
|
|
45
|
+
console.log('π Created .tracker/commands.json in your project');
|
|
46
|
+
console.log('\nπ― You can now use:');
|
|
47
|
+
console.log(' tracker list β see all saved commands');
|
|
48
|
+
console.log(' tracker stats β see command statistics');
|
|
49
|
+
console.log(' tracker search β search your commands');
|
|
50
|
+
console.log(' tracker export β export your commands');
|
|
51
|
+
console.log('\nπ‘ Start using your terminal normally');
|
|
52
|
+
console.log(' Commands will be saved automatically!\n');
|
|
53
53
|
|
|
54
54
|
} catch (error) {
|
|
55
55
|
|
|
@@ -60,83 +60,83 @@ function initCommand() {
|
|
|
60
60
|
* This happens when user doesn't have write access
|
|
61
61
|
* to the current folder
|
|
62
62
|
*/
|
|
63
|
-
if (error.code ===
|
|
64
|
-
console.error(
|
|
65
|
-
console.error(
|
|
66
|
-
console.error(
|
|
63
|
+
if (error.code === 'EACCES') {
|
|
64
|
+
console.error('β Permission denied!');
|
|
65
|
+
console.error('π‘ Try running with admin permissions');
|
|
66
|
+
console.error('π‘ Or check folder write permissions\n');
|
|
67
67
|
return;
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
/*
|
|
71
71
|
* Handle no space left on disk
|
|
72
72
|
*/
|
|
73
|
-
if (error.code ===
|
|
74
|
-
console.error(
|
|
75
|
-
console.error(
|
|
73
|
+
if (error.code === 'ENOSPC') {
|
|
74
|
+
console.error('β No space left on disk!');
|
|
75
|
+
console.error('π‘ Free up some disk space and try again\n');
|
|
76
76
|
return;
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
/*
|
|
80
80
|
* Any other unexpected error
|
|
81
81
|
*/
|
|
82
|
-
console.error(
|
|
82
|
+
console.error('β Failed to initialize cmd-tracker');
|
|
83
83
|
console.error(`Error: ${error.message}\n`);
|
|
84
84
|
}
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
function updateGitignore() {
|
|
88
88
|
|
|
89
|
-
const gitignorePath = path.join(process.cwd(),
|
|
89
|
+
const gitignorePath = path.join(process.cwd(), '.gitignore');
|
|
90
90
|
/*
|
|
91
91
|
* Added tracker-export files to gitignore too
|
|
92
92
|
* Users should not push their exported files to GitHub
|
|
93
93
|
* These are personal revision files β local only
|
|
94
94
|
*/
|
|
95
|
-
const trackerEntry =
|
|
95
|
+
const trackerEntry = '\n# cmd-tracker personal data\n.tracker/\ntracker-export.json\ntracker-export.csv\n';
|
|
96
96
|
|
|
97
97
|
try {
|
|
98
98
|
|
|
99
99
|
if (fs.existsSync(gitignorePath)) {
|
|
100
|
-
const gitignoreContent = fs.readFileSync(gitignorePath,
|
|
100
|
+
const gitignoreContent = fs.readFileSync(gitignorePath, 'utf-8');
|
|
101
101
|
|
|
102
102
|
/*
|
|
103
103
|
* Check each entry separately
|
|
104
104
|
* So we can add missing entries without touching existing ones
|
|
105
105
|
*/
|
|
106
|
-
let entriesToAdd =
|
|
106
|
+
let entriesToAdd = '';
|
|
107
107
|
|
|
108
|
-
if (!gitignoreContent.includes(
|
|
109
|
-
entriesToAdd +=
|
|
108
|
+
if (!gitignoreContent.includes('.tracker/')) {
|
|
109
|
+
entriesToAdd += '.tracker/\n';
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
-
if (!gitignoreContent.includes(
|
|
113
|
-
entriesToAdd +=
|
|
112
|
+
if (!gitignoreContent.includes('tracker-export.json')) {
|
|
113
|
+
entriesToAdd += 'tracker-export.json\n';
|
|
114
114
|
}
|
|
115
115
|
|
|
116
|
-
if (!gitignoreContent.includes(
|
|
117
|
-
entriesToAdd +=
|
|
116
|
+
if (!gitignoreContent.includes('tracker-export.csv')) {
|
|
117
|
+
entriesToAdd += 'tracker-export.csv\n';
|
|
118
118
|
}
|
|
119
119
|
|
|
120
120
|
/*
|
|
121
121
|
* Only write if there's something new to add
|
|
122
122
|
*/
|
|
123
|
-
if (entriesToAdd ===
|
|
124
|
-
console.log(
|
|
123
|
+
if (entriesToAdd === '') {
|
|
124
|
+
console.log('β
.gitignore already up to date');
|
|
125
125
|
return;
|
|
126
126
|
}
|
|
127
127
|
|
|
128
128
|
fs.appendFileSync(
|
|
129
129
|
gitignorePath,
|
|
130
|
-
|
|
130
|
+
'\n# cmd-tracker personal data\n' + entriesToAdd
|
|
131
131
|
);
|
|
132
|
-
console.log(
|
|
132
|
+
console.log('β
Updated .gitignore with cmd-tracker entries');
|
|
133
133
|
|
|
134
134
|
fs.appendFileSync(gitignorePath, trackerEntry);
|
|
135
|
-
console.log(
|
|
135
|
+
console.log('β
Added .tracker/ to your .gitignore');
|
|
136
136
|
|
|
137
137
|
} else {
|
|
138
138
|
fs.writeFileSync(gitignorePath, trackerEntry);
|
|
139
|
-
console.log(
|
|
139
|
+
console.log('β
Created .gitignore with .tracker/ entry');
|
|
140
140
|
}
|
|
141
141
|
|
|
142
142
|
} catch (error) {
|
|
@@ -145,8 +145,8 @@ function updateGitignore() {
|
|
|
145
145
|
* .gitignore update failed β not critical
|
|
146
146
|
* tracker still works, just warn the user
|
|
147
147
|
*/
|
|
148
|
-
console.log(
|
|
149
|
-
console.log(
|
|
148
|
+
console.log('β οΈ Could not update .gitignore automatically');
|
|
149
|
+
console.log('π‘ Manually add .tracker/ to your .gitignore\n');
|
|
150
150
|
}
|
|
151
151
|
}
|
|
152
152
|
|
package/src/commands/list.js
CHANGED
|
@@ -5,13 +5,13 @@
|
|
|
5
5
|
* Now with proper error handling using validator.js
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
const { readCommands } = require(
|
|
8
|
+
const { readCommands } = require('../utils/storage');
|
|
9
9
|
const {
|
|
10
10
|
isInitialized,
|
|
11
11
|
showInitError,
|
|
12
12
|
isValidCategory,
|
|
13
13
|
showCategoryError
|
|
14
|
-
} = require(
|
|
14
|
+
} = require('../utils/validator');
|
|
15
15
|
|
|
16
16
|
function listCommand(category) {
|
|
17
17
|
|
|
@@ -46,8 +46,8 @@ function listCommand(category) {
|
|
|
46
46
|
const data = readCommands();
|
|
47
47
|
let totalCommands = 0;
|
|
48
48
|
|
|
49
|
-
console.log(
|
|
50
|
-
console.log(
|
|
49
|
+
console.log('\nπ CMD-TRACKER β Your Command History\n');
|
|
50
|
+
console.log('β'.repeat(50));
|
|
51
51
|
|
|
52
52
|
for (const [cat, commands] of Object.entries(data)) {
|
|
53
53
|
if (commands.length === 0) continue;
|
|
@@ -56,13 +56,13 @@ function listCommand(category) {
|
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
if (totalCommands === 0) {
|
|
59
|
-
console.log(
|
|
60
|
-
console.log(
|
|
61
|
-
console.log(
|
|
59
|
+
console.log('\nπ No commands saved yet!');
|
|
60
|
+
console.log('π‘ Use: tracker save "your command"');
|
|
61
|
+
console.log('π‘ Or run commands normally if shell hook is set up\n');
|
|
62
62
|
return;
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
-
console.log(
|
|
65
|
+
console.log('β'.repeat(50));
|
|
66
66
|
console.log(`\nβ
Total: ${totalCommands} commands saved\n`);
|
|
67
67
|
|
|
68
68
|
} catch (error) {
|
|
@@ -70,47 +70,47 @@ function listCommand(category) {
|
|
|
70
70
|
* Something went wrong reading the file
|
|
71
71
|
* Show clear error instead of crashing
|
|
72
72
|
*/
|
|
73
|
-
console.log(
|
|
74
|
-
console.log(
|
|
73
|
+
console.log('\nβ Error reading commands');
|
|
74
|
+
console.log('π‘ Try running tracker init again\n');
|
|
75
75
|
}
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
function displayCategory(categoryName, commands) {
|
|
79
79
|
|
|
80
80
|
const icons = {
|
|
81
|
-
git:
|
|
82
|
-
npm:
|
|
83
|
-
docker:
|
|
84
|
-
linux:
|
|
85
|
-
node:
|
|
86
|
-
angular:
|
|
87
|
-
python:
|
|
88
|
-
go:
|
|
89
|
-
java:
|
|
90
|
-
rust:
|
|
91
|
-
dotnet:
|
|
92
|
-
kubernetes:
|
|
93
|
-
database:
|
|
94
|
-
cloud:
|
|
95
|
-
packagemanagers:
|
|
96
|
-
testing:
|
|
97
|
-
ai:
|
|
98
|
-
others:
|
|
81
|
+
git: 'π',
|
|
82
|
+
npm: 'π¦',
|
|
83
|
+
docker: 'π³',
|
|
84
|
+
linux: 'π§',
|
|
85
|
+
node: 'π’',
|
|
86
|
+
angular: 'π΄',
|
|
87
|
+
python: 'π',
|
|
88
|
+
go: 'π·',
|
|
89
|
+
java: 'β',
|
|
90
|
+
rust: 'π¦',
|
|
91
|
+
dotnet: 'π·',
|
|
92
|
+
kubernetes: 'βΈοΈ',
|
|
93
|
+
database: 'ποΈ',
|
|
94
|
+
cloud: 'βοΈ',
|
|
95
|
+
packagemanagers: 'π₯',
|
|
96
|
+
testing: 'π§ͺ',
|
|
97
|
+
ai: 'π€',
|
|
98
|
+
others: 'π'
|
|
99
99
|
};
|
|
100
100
|
|
|
101
|
-
const icon = icons[categoryName] ||
|
|
101
|
+
const icon = icons[categoryName] || 'π';
|
|
102
102
|
|
|
103
103
|
console.log(`\n${icon} ${categoryName.toUpperCase()} (${commands.length})`);
|
|
104
|
-
console.log(
|
|
104
|
+
console.log('β'.repeat(30));
|
|
105
105
|
|
|
106
106
|
if (commands.length === 0) {
|
|
107
|
-
console.log(
|
|
107
|
+
console.log(' π No commands saved yet');
|
|
108
108
|
return;
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
commands.forEach((item, index) => {
|
|
112
112
|
const date = new Date(item.time).toLocaleDateString();
|
|
113
|
-
console.log(` ${String(index + 1).padStart(2,
|
|
113
|
+
console.log(` ${String(index + 1).padStart(2, ' ')}. ${item.command} (${date})`);
|
|
114
114
|
});
|
|
115
115
|
}
|
|
116
116
|
|
package/src/commands/save.js
CHANGED
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
* We NEVER want it to interrupt user's workflow
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
|
-
const { saveCommand } = require(
|
|
17
|
-
const { isInitialized } = require(
|
|
16
|
+
const { saveCommand } = require('../utils/storage');
|
|
17
|
+
const { isInitialized } = require('../utils/validator');
|
|
18
18
|
|
|
19
19
|
function saveCommandAction(command) {
|
|
20
20
|
|
package/src/commands/search.js
CHANGED
|
@@ -10,12 +10,12 @@
|
|
|
10
10
|
* Returns matching commands with their category
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
const { readCommands } = require(
|
|
13
|
+
const { readCommands } = require('../utils/storage');
|
|
14
14
|
const {
|
|
15
15
|
isInitialized,
|
|
16
16
|
showInitError,
|
|
17
17
|
isValidQuery
|
|
18
|
-
} = require(
|
|
18
|
+
} = require('../utils/validator');
|
|
19
19
|
|
|
20
20
|
/*
|
|
21
21
|
* searchCommand() β main function
|
|
@@ -37,8 +37,8 @@ function searchCommand(query) {
|
|
|
37
37
|
* Validate query
|
|
38
38
|
*/
|
|
39
39
|
if (!isValidQuery(query)) {
|
|
40
|
-
console.log(
|
|
41
|
-
console.log(
|
|
40
|
+
console.log('\nβ Please provide a search query');
|
|
41
|
+
console.log('π‘ Usage: tracker search "git"\n');
|
|
42
42
|
return;
|
|
43
43
|
}
|
|
44
44
|
|
|
@@ -65,32 +65,32 @@ function searchCommand(query) {
|
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
console.log(`\nπ Search results for: "${query}"`);
|
|
68
|
-
console.log(
|
|
68
|
+
console.log('β'.repeat(50));
|
|
69
69
|
|
|
70
|
-
|
|
70
|
+
results.forEach((item, index) => {
|
|
71
71
|
|
|
72
|
-
|
|
72
|
+
const date = new Date(item.time).toLocaleDateString();
|
|
73
73
|
|
|
74
|
-
|
|
74
|
+
/*
|
|
75
75
|
* Highlight the search term in results
|
|
76
76
|
* Replace matched part with uppercase version
|
|
77
77
|
* So user can easily spot what matched
|
|
78
78
|
*/
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
79
|
+
const highlighted = item.command.replace(
|
|
80
|
+
new RegExp(searchTerm, 'gi'),
|
|
81
|
+
(match) => `[${match.toUpperCase()}]`
|
|
82
|
+
);
|
|
83
83
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
84
|
+
console.log(`\n ${index + 1}. ${highlighted}`);
|
|
85
|
+
console.log(` π Category: ${item.category} π
${date}`);
|
|
86
|
+
});
|
|
87
87
|
|
|
88
|
-
console.log(
|
|
88
|
+
console.log('\n' + 'β'.repeat(50));
|
|
89
89
|
console.log(`β
Found ${results.length} matching command(s)\n`);
|
|
90
90
|
|
|
91
91
|
} catch (error) {
|
|
92
|
-
console.log(
|
|
93
|
-
console.log(
|
|
92
|
+
console.log('\nβ Error searching commands');
|
|
93
|
+
console.log('π‘ Try running tracker init again\n');
|
|
94
94
|
}
|
|
95
95
|
}
|
|
96
96
|
|
package/src/commands/stats.js
CHANGED
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
* β Most used category
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
const { readCommands } = require(
|
|
14
|
-
const { isInitialized, showInitError } = require(
|
|
13
|
+
const { readCommands } = require('../utils/storage');
|
|
14
|
+
const { isInitialized, showInitError } = require('../utils/validator');
|
|
15
15
|
|
|
16
16
|
function statsCommand() {
|
|
17
17
|
|
|
@@ -23,7 +23,7 @@ function statsCommand() {
|
|
|
23
23
|
try {
|
|
24
24
|
const data = readCommands();
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
/*
|
|
27
27
|
* Calculate total commands across all categories
|
|
28
28
|
* Object.values() β gets all arrays from data object
|
|
29
29
|
* .reduce() β adds up all lengths
|
|
@@ -33,97 +33,97 @@ function statsCommand() {
|
|
|
33
33
|
* β values β [[1,2], [1]]
|
|
34
34
|
* β reduce β 2 + 1 = 3
|
|
35
35
|
*/
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
36
|
+
const total = Object.values(data).reduce(
|
|
37
|
+
(sum, commands) => sum + commands.length, 0
|
|
38
|
+
);
|
|
39
39
|
|
|
40
40
|
if (total === 0) {
|
|
41
|
-
console.log(
|
|
42
|
-
console.log(
|
|
41
|
+
console.log('\nπ No commands saved yet!');
|
|
42
|
+
console.log('π‘ Use: tracker save "your command"\n');
|
|
43
43
|
return;
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
console.log(
|
|
47
|
-
console.log(
|
|
46
|
+
console.log('\nπ CMD-TRACKER β Statistics\n');
|
|
47
|
+
console.log('β'.repeat(50));
|
|
48
48
|
|
|
49
|
-
|
|
49
|
+
/*
|
|
50
50
|
* Category icons β same as list.js for consistency
|
|
51
51
|
*/
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
52
|
+
const icons = {
|
|
53
|
+
git: 'π',
|
|
54
|
+
npm: 'π¦',
|
|
55
|
+
docker: 'π³',
|
|
56
|
+
linux: 'π§',
|
|
57
|
+
node: 'π’',
|
|
58
|
+
angular: 'π΄',
|
|
59
|
+
python: 'π',
|
|
60
|
+
go: 'π·',
|
|
61
|
+
java: 'β',
|
|
62
|
+
rust: 'π¦',
|
|
63
|
+
dotnet: 'π·',
|
|
64
|
+
kubernetes: 'βΈοΈ',
|
|
65
|
+
database: 'ποΈ',
|
|
66
|
+
cloud: 'βοΈ',
|
|
67
|
+
packageManagers: 'π₯',
|
|
68
|
+
testing: 'π§ͺ',
|
|
69
|
+
ai: 'π€',
|
|
70
|
+
others: 'π'
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
/*
|
|
74
74
|
* Track which category has most commands
|
|
75
75
|
*/
|
|
76
|
-
|
|
77
|
-
|
|
76
|
+
let topCategory = '';
|
|
77
|
+
let topCount = 0;
|
|
78
78
|
|
|
79
|
-
|
|
79
|
+
/*
|
|
80
80
|
* Loop through each category and show stats
|
|
81
81
|
*/
|
|
82
|
-
|
|
82
|
+
for (const [category, commands] of Object.entries(data)) {
|
|
83
83
|
|
|
84
|
-
|
|
84
|
+
/*
|
|
85
85
|
* Skip empty categories
|
|
86
86
|
*/
|
|
87
|
-
|
|
87
|
+
if (commands.length === 0) continue;
|
|
88
88
|
|
|
89
|
-
|
|
89
|
+
/*
|
|
90
90
|
* Calculate percentage
|
|
91
91
|
* Math.round() β rounds to nearest whole number
|
|
92
92
|
* 2.7 β 3, 2.3 β 2
|
|
93
93
|
*/
|
|
94
|
-
|
|
94
|
+
const percentage = Math.round((commands.length / total) * 100);
|
|
95
95
|
|
|
96
|
-
|
|
96
|
+
/*
|
|
97
97
|
* Build a simple visual bar
|
|
98
98
|
* "β".repeat(percentage/5) β each block = 5%
|
|
99
99
|
* So 50% β 10 blocks, 100% β 20 blocks
|
|
100
100
|
*/
|
|
101
|
-
|
|
101
|
+
const bar = 'β'.repeat(Math.round(percentage / 5));
|
|
102
102
|
|
|
103
|
-
|
|
103
|
+
const icon = icons[category] || 'π';
|
|
104
104
|
|
|
105
|
-
|
|
106
|
-
|
|
105
|
+
console.log(
|
|
106
|
+
`\n${icon} ${category.toUpperCase().padEnd(10)} ` +
|
|
107
107
|
`${String(commands.length).padStart(3)} commands ` +
|
|
108
108
|
`${String(percentage).padStart(3)}% ${bar}`
|
|
109
|
-
|
|
109
|
+
);
|
|
110
110
|
|
|
111
|
-
|
|
111
|
+
/*
|
|
112
112
|
* Track top category
|
|
113
113
|
*/
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
114
|
+
if (commands.length > topCount) {
|
|
115
|
+
topCount = commands.length;
|
|
116
|
+
topCategory = category;
|
|
117
|
+
}
|
|
117
118
|
}
|
|
118
|
-
}
|
|
119
119
|
|
|
120
|
-
console.log(
|
|
120
|
+
console.log('\n' + 'β'.repeat(50));
|
|
121
121
|
console.log(`π¦ Total commands : ${total}`);
|
|
122
122
|
console.log(`π Most used : ${topCategory} (${topCount} commands)\n`);
|
|
123
123
|
|
|
124
124
|
} catch (error) {
|
|
125
|
-
console.log(
|
|
126
|
-
console.log(
|
|
125
|
+
console.log('\nβ Error reading statistics');
|
|
126
|
+
console.log('π‘ Try running tracker init again\n');
|
|
127
127
|
}
|
|
128
128
|
}
|
|
129
129
|
|
package/src/index.js
CHANGED
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
* use them programmatically in their own code
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
const { saveCommand, readCommands, initStorage } = require(
|
|
12
|
-
const { categorize } = require(
|
|
11
|
+
const { saveCommand, readCommands, initStorage } = require('./utils/storage');
|
|
12
|
+
const { categorize } = require('./utils/categorizer');
|
|
13
13
|
|
|
14
14
|
module.exports = {
|
|
15
15
|
saveCommand,
|