@adithya-naik/cmd-tracker 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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Jatoth Adithya Naik
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,187 @@
1
+ <div align="center">
2
+
3
+ # šŸ“Ÿ cmd-tracker
4
+
5
+ ### A developer tool that auto-captures, categorizes and saves terminal commands per project for easy revision
6
+
7
+ [![npm version](https://img.shields.io/npm/v/@adithya-naik/cmd-tracker.svg)](https://www.npmjs.com/package/@adithya-naik/cmd-tracker)
8
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
9
+ [![Node.js](https://img.shields.io/badge/Node.js-v14%2B-green.svg)](https://nodejs.org)
10
+
11
+ </div>
12
+
13
+ ---
14
+
15
+ ## šŸŽÆ What is cmd-tracker?
16
+
17
+ **cmd-tracker** is an npm package that automatically captures, categorizes and saves every terminal command you type in a project.
18
+
19
+ Perfect for:
20
+ - šŸŽ“ **Students** learning Linux, Git, Docker, Angular etc.
21
+ - šŸ‘Øā€šŸ’» **Developers** who want to track commands used in a project
22
+ - šŸ“ **Anyone** who wants to revise terminal commands they've used
23
+
24
+ ### How it works
25
+
26
+ ```
27
+ You work normally in terminal
28
+ ↓
29
+ Commands auto-captured in background
30
+ ↓
31
+ Saved to .tracker/commands.json in your project
32
+ ↓
33
+ Run tracker list → see entire command history
34
+ ```
35
+
36
+ ---
37
+
38
+ ## šŸ“¦ Installation
39
+
40
+ Install in your learning/project repo:
41
+
42
+ ```bash
43
+ npm install @adithya-naik/cmd-tracker
44
+ ```
45
+
46
+ ---
47
+
48
+ ## šŸš€ Quick Start
49
+
50
+ **Step 1 — Initialize in your repo:**
51
+ ```bash
52
+ npx tracker init
53
+ ```
54
+
55
+ **Step 2 — Enable automatic capture:**
56
+ ```bash
57
+ npx tracker hook
58
+ source ~/.bashrc # or source ~/.zshrc on Mac
59
+ ```
60
+
61
+ **Step 3 — Work normally! Then revise:**
62
+ ```bash
63
+ npx tracker list
64
+ ```
65
+
66
+ That's it! Every command you type is now saved automatically šŸŖ„
67
+
68
+ ---
69
+
70
+ ## šŸ“‹ All Commands
71
+
72
+ | Command | Description |
73
+ |---|---|
74
+ | `tracker init` | Initialize tracker in your project |
75
+ | `tracker hook` | Enable automatic command capture |
76
+ | `tracker unhook` | Disable automatic command capture |
77
+ | `tracker list` | Show all saved commands |
78
+ | `tracker list <category>` | Filter by category |
79
+ | `tracker search <query>` | Search through commands |
80
+ | `tracker stats` | Show statistics by category |
81
+ | `tracker favorite <cmd>` | Toggle command as favorite |
82
+ | `tracker favorites` | Show all favorites |
83
+ | `tracker export` | Export as JSON |
84
+ | `tracker export --csv` | Export as CSV (opens in Excel) |
85
+ | `tracker clear` | Clear all commands |
86
+ | `tracker clear <category>` | Clear specific category |
87
+
88
+ ---
89
+
90
+ ## šŸ—‚ļø Categories
91
+
92
+ Commands are automatically categorized into:
93
+
94
+ | Category | Commands |
95
+ |---|---|
96
+ | šŸ”€ `git` | git status, git push, git commit... |
97
+ | šŸ“¦ `npm` | npm install, npx, npm run... |
98
+ | 🐳 `docker` | docker ps, docker build... |
99
+ | 🐧 `linux` | ls, cd, mkdir, chmod... |
100
+ | 🟢 `node` | node, nodemon... |
101
+ | šŸ”“ `angular` | ng new, ng serve, ng generate... |
102
+ | šŸ `python` | python, pip install... |
103
+ | šŸ“Œ `others` | everything else |
104
+
105
+ ---
106
+
107
+ ## šŸ’” Usage Examples
108
+
109
+ **Filter by category:**
110
+ ```bash
111
+ tracker list git # see all git commands
112
+ tracker list linux # see all linux commands
113
+ tracker list npm # see all npm commands
114
+ ```
115
+
116
+ **Search commands:**
117
+ ```bash
118
+ tracker search "install" # find all install commands
119
+ tracker search "git" # find all git related commands
120
+ ```
121
+
122
+ **Save favorites for quick revision:**
123
+ ```bash
124
+ tracker favorite "git rebase -i HEAD~3"
125
+ tracker favorites # see all starred commands
126
+ ```
127
+
128
+ **Export for sharing/backup:**
129
+ ```bash
130
+ tracker export # creates tracker-export.json
131
+ tracker export --csv # creates tracker-export.csv (opens in Excel!)
132
+ ```
133
+
134
+ ---
135
+
136
+ ## šŸ“ Project Structure
137
+
138
+ After running `tracker init`, a `.tracker` folder is created:
139
+
140
+ ```
141
+ your-project/
142
+ ā”œā”€ā”€ .tracker/
143
+ │ └── commands.json ← your personal command history
144
+ ā”œā”€ā”€ your-files...
145
+ └── package.json
146
+ ```
147
+
148
+ > āœ… `.tracker/` is automatically added to `.gitignore`
149
+ > Your command history stays local — never pushed to GitHub
150
+
151
+ ---
152
+
153
+ ## šŸ–„ļø Platform Support
154
+
155
+ | Platform | Support |
156
+ |---|---|
157
+ | Mac (zsh) | āœ… Full support |
158
+ | Linux (bash) | āœ… Full support |
159
+ | Windows (Git Bash) | āœ… Supported |
160
+ | Windows (PowerShell) | āš ļø Manual save only |
161
+
162
+ > Windows CMD/PowerShell users: use `tracker save "command"` manually
163
+ > or use Git Bash / WSL for automatic capture
164
+
165
+ ---
166
+
167
+ ## šŸ¤ Contributing
168
+
169
+ Contributions are welcome! Feel free to:
170
+ - Open an issue for bugs or feature requests
171
+ - Submit a pull request
172
+
173
+ ---
174
+
175
+ ## šŸ“„ License
176
+
177
+ MIT Ā© [Jatoth Adithya Naik](https://github.com/adithya-naik)
178
+
179
+ ---
180
+
181
+ <div align="center">
182
+
183
+ ⭐ **Star this repo if you find it useful!**
184
+
185
+ [GitHub](https://github.com/adithya-naik/cmd-tracker) • [npm](https://www.npmjs.com/package/@adithya-naik/cmd-tracker) • [Issues](https://github.com/adithya-naik/cmd-tracker/issues)
186
+
187
+ </div
package/bin/tracker.js ADDED
@@ -0,0 +1,271 @@
1
+ #!/usr/bin/env node
2
+ // "Hey! Run this file using Node.js"
3
+
4
+ /*
5
+ * This is the ENTRY POINT of our CLI tool
6
+ * When user types "tracker" in terminal, this file runs first
7
+ * Think of it like the main gate of our entire application
8
+ */
9
+
10
+ /*Current commands:
11
+ * tracker init → sets up .tracker folder in user's repo
12
+ * tracker save <cmd> → saves a command (called by shell hook)
13
+ *
14
+ * Coming soon:
15
+ * tracker list → show all saved commands
16
+ * tracker stats → show command statistics
17
+ * tracker search → search saved commands
18
+ */
19
+
20
+ // Import commander - this package helps us build CLI commands easily
21
+ // Like "list", "stats", "search" etc.
22
+ const { program } = require("commander");
23
+
24
+ // Import package.json to read our version number
25
+ // __dirname = current folder path (bin/)
26
+ // ../ = go one level up (to root of project)
27
+ const packageJson = require("../package.json");
28
+
29
+ /*
30
+ * Import our init command function
31
+ * This is the function that runs when user types: tracker init
32
+ *
33
+ * We import FROM src/commands/init.js
34
+ * bin/ → go up one level → ../
35
+ * then into src/commands/init.js
36
+ */
37
+ const { initCommand } = require("../src/commands/init");
38
+
39
+ /*
40
+ * Import our save command function
41
+ * This runs automatically via shell hook every time
42
+ * user types a command in terminal
43
+ */
44
+ const { saveCommandAction } = require("../src/commands/save");
45
+ // Import list command function
46
+ const { listCommand } = require("../src/commands/list");
47
+ // Import search command function
48
+ const { searchCommand } = require("../src/commands/search");
49
+ const { statsCommand } = require("../src/commands/stats");
50
+ const { clearCommand } = require("../src/commands/clear");
51
+ const { exportCommand } = require("../src/commands/export");
52
+ const { hookCommand, unhookCommand } = require("../src/commands/hook");
53
+ const { favoriteCommand, favoritesCommand } = require("../src/commands/favorite");
54
+ /*
55
+ * .name() → sets the name of our CLI tool
56
+ * This shows up when user types: tracker --help
57
+ */
58
+ program.name("tracker");
59
+
60
+ /*
61
+ * .description() → explains what our tool does
62
+ * This also shows up in: tracker --help
63
+ */
64
+ program.description("šŸ“Ÿ A developer tool that auto-captures, categorizes and saves terminal commands per project for easy revision");
65
+
66
+ /*
67
+ * .version() → sets the version of our CLI tool
68
+ * packageJson.version reads "1.0.0" from package.json
69
+ * So we never have to update version in two places
70
+ * User can check version by typing: tracker --version
71
+ */
72
+ program.version(packageJson.version);
73
+
74
+ // FIRST COMMAND
75
+
76
+ /*
77
+ * .command() → defines a new CLI command
78
+ * "hello" → this is what user types after tracker
79
+ * So user runs: tracker hello
80
+ */
81
+ program
82
+ .command("hello")
83
+
84
+ /*
85
+ * .description() → explains what this command does
86
+ * Shows up when user types: tracker --help
87
+ */
88
+ .description("A test command to check if CLI is working")
89
+
90
+ /*
91
+ * .action() → this function runs when user types: tracker hello
92
+ * Whatever code you write inside here — runs when command is called
93
+ */
94
+ .action(() => {
95
+ console.log("šŸ‘‹ Hey! tracker CLI is working perfectly!");
96
+ console.log("šŸš€ Let's start tracking your commands!");
97
+ });
98
+
99
+
100
+ /*
101
+ * Register the INIT command
102
+ *
103
+ * .command("init") → user types: tracker init
104
+ * .description() → shows in tracker --help
105
+ * .action() → runs initCommand() when user types tracker init
106
+ *
107
+ * initCommand is imported from src/commands/init.js
108
+ * We just CALL it here — all logic lives in init.js
109
+ * This keeps bin/tracker.js clean and simple
110
+ */
111
+ program
112
+ .command("init")
113
+ .description("Initialize cmd-tracker in your current project")
114
+ .action(() => {
115
+ initCommand();
116
+ });
117
+
118
+ /*
119
+ * Register the SAVE command
120
+ *
121
+ * This command is special — users never type it manually
122
+ * It gets called automatically by the shell hook
123
+ *
124
+ * .argument("<command>") → accepts everything after "tracker save"
125
+ * as a single string argument
126
+ *
127
+ * Example:
128
+ * tracker save git status origin main
129
+ * → command = "git status origin main"
130
+ *
131
+ * "<command>" → angle brackets mean this argument is REQUIRED
132
+ * "[command]" → square brackets mean OPTIONAL
133
+ */
134
+ program
135
+ .command("save")
136
+ .description("Save a command to tracker (called automatically by shell hook)")
137
+ .argument("<command>", "the terminal command to save")
138
+ .action((command) => {
139
+ saveCommandAction(command);
140
+ });
141
+
142
+ /*
143
+ * Register LIST command
144
+ *
145
+ * tracker list → shows all commands
146
+ * tracker list git → shows only git commands
147
+ *
148
+ * [category] → square brackets = OPTIONAL argument
149
+ */
150
+ program
151
+ .command("list")
152
+ .description("List all saved commands or filter by category")
153
+ .argument("[category]", "optional category filter (git/npm/docker/linux/node/angular/python/others)")
154
+ .action((category) => {
155
+ listCommand(category);
156
+ });
157
+
158
+ /*
159
+ * Register SEARCH command
160
+ *
161
+ * tracker search "git" → finds commands containing "git"
162
+ * tracker search "install" → finds commands containing "install"
163
+ *
164
+ * <query> → required argument
165
+ */
166
+ program
167
+ .command("search")
168
+ .description("Search through all saved commands")
169
+ .argument("<query>", "search term to look for in saved commands")
170
+ .action((query) => {
171
+ searchCommand(query);
172
+ });
173
+
174
+ /*
175
+ * STATS command
176
+ * tracker stats → shows category breakdown with percentages
177
+ */
178
+ program
179
+ .command("stats")
180
+ .description("Show statistics of saved commands by category")
181
+ .action(() => {
182
+ statsCommand();
183
+ });
184
+
185
+ /*
186
+ * CLEAR command
187
+ * tracker clear → clears ALL commands (asks confirmation)
188
+ * tracker clear git → clears only git commands (asks confirmation)
189
+ *
190
+ * [category] → optional argument
191
+ */
192
+ program
193
+ .command("clear")
194
+ .description("Clear all saved commands or a specific category")
195
+ .argument("[category]", "optional category to clear")
196
+ .action((category) => {
197
+ clearCommand(category);
198
+ });
199
+
200
+ /*
201
+ * EXPORT command
202
+ * tracker export → exports as JSON file
203
+ * tracker export --csv → exports as CSV file
204
+ *
205
+ * .option() → adds an optional flag to a command
206
+ * "--csv" → user types --csv to trigger CSV export
207
+ */
208
+ program
209
+ .command("export")
210
+ .description("Export saved commands as JSON or CSV file")
211
+ .option("--csv", "export as CSV instead of JSON")
212
+ .action((options) => {
213
+ exportCommand(options);
214
+ });
215
+
216
+ /*
217
+ * HOOK command
218
+ * tracker hook → installs shell hook for auto capture
219
+ */
220
+ program
221
+ .command("hook")
222
+ .description("Enable automatic command capture via shell hook")
223
+ .action(() => {
224
+ hookCommand();
225
+ });
226
+
227
+ /*
228
+ * UNHOOK command
229
+ * tracker unhook → removes shell hook
230
+ */
231
+ program
232
+ .command("unhook")
233
+ .description("Disable automatic command capture")
234
+ .action(() => {
235
+ unhookCommand();
236
+ });
237
+
238
+
239
+ /*
240
+ * FAVORITE command
241
+ * tracker favorite "git status" → toggles favorite
242
+ */
243
+ program
244
+ .command("favorite")
245
+ .description("Toggle a command as favorite")
246
+ .argument("<command>", "command to mark as favorite")
247
+ .action((command) => {
248
+ favoriteCommand(command);
249
+ });
250
+
251
+ /*
252
+ * FAVORITES command
253
+ * tracker favorites → lists all favorites
254
+ */
255
+ program
256
+ .command("favorites")
257
+ .description("List all favorited commands")
258
+ .action(() => {
259
+ favoritesCommand();
260
+ });
261
+ /*
262
+ * This line is VERY important
263
+ * It tells commander to start reading what the user typed
264
+ * Without this line - nothing works
265
+ * Always keep this at the BOTTOM of this file *
266
+ * process.argv contains everything user typed:
267
+ * ["node", "tracker.js", "init"] → runs init command
268
+ * ["node", "tracker.js", "list"] → runs list command (coming soon)
269
+ */
270
+
271
+ program.parse(process.argv);
package/package.json ADDED
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "@adithya-naik/cmd-tracker",
3
+ "version": "1.0.0",
4
+ "description": "šŸ“Ÿ A developer tool that auto-captures, categorizes and saves terminal commands per project for easy revision",
5
+ "main": "src/index.js",
6
+ "bin": {
7
+ "tracker": "bin/tracker.js"
8
+ },
9
+ "scripts": {
10
+ "test": "echo \"No tests yet\""
11
+ },
12
+ "repository": {
13
+ "type": "git",
14
+ "url": "git+https://github.com/adithya-naik/cmd-tracker.git"
15
+ },
16
+ "keywords": [
17
+ "terminal",
18
+ "commands",
19
+ "tracker",
20
+ "cli",
21
+ "developer-tool",
22
+ "learning",
23
+ "revision",
24
+ "shell-hook",
25
+ "history",
26
+ "productivity"
27
+ ],
28
+ "author": "Jatoth Adithya Naik <jatothadithyanaik@gmail.com>",
29
+ "license": "MIT",
30
+ "bugs": {
31
+ "url": "https://github.com/adithya-naik/cmd-tracker/issues"
32
+ },
33
+ "homepage": "https://github.com/adithya-naik/cmd-tracker#readme",
34
+ "engines": {
35
+ "node": ">=14.0.0"
36
+ },
37
+ "dependencies": {
38
+ "commander": "^11.0.0",
39
+ "chalk": "^4.1.2"
40
+ }
41
+ }
@@ -0,0 +1,109 @@
1
+ /*
2
+ * clear.js
3
+ * Now with proper error handling using validator.js
4
+ */
5
+
6
+ const fs = require("fs");
7
+ const path = require("path");
8
+ const readline = require("readline");
9
+ const { readCommands } = require("../utils/storage");
10
+ const {
11
+ isInitialized,
12
+ showInitError,
13
+ isValidCategory,
14
+ showCategoryError
15
+ } = require("../utils/validator");
16
+
17
+ const COMMANDS_FILE = path.join(process.cwd(), ".tracker", "commands.json");
18
+
19
+ function ask(question) {
20
+ const rl = readline.createInterface({
21
+ input: process.stdin,
22
+ output: process.stdout
23
+ });
24
+
25
+ return new Promise((resolve) => {
26
+ rl.question(question, (answer) => {
27
+ rl.close();
28
+ resolve(answer);
29
+ });
30
+ });
31
+ }
32
+
33
+ async function clearCommand(category) {
34
+
35
+ /*
36
+ * Check initialization first
37
+ */
38
+ if (!isInitialized()) {
39
+ showInitError();
40
+ return;
41
+ }
42
+
43
+ /*
44
+ * Validate category if provided
45
+ */
46
+ if (category && !isValidCategory(category)) {
47
+ showCategoryError(category);
48
+ return;
49
+ }
50
+
51
+ try {
52
+ const data = readCommands();
53
+
54
+ if (category) {
55
+ const cat = category.toLowerCase();
56
+
57
+ if (data[cat].length === 0) {
58
+ console.log(`\nšŸ“­ No commands saved in ${cat}\n`);
59
+ return;
60
+ }
61
+
62
+ const answer = await ask(
63
+ `\nāš ļø Clear all ${data[cat].length} ${cat} commands? (yes/no): `
64
+ );
65
+
66
+ if (answer.toLowerCase() !== "yes") {
67
+ console.log("āŒ Cancelled\n");
68
+ return;
69
+ }
70
+
71
+ data[cat] = [];
72
+ fs.writeFileSync(COMMANDS_FILE, JSON.stringify(data, null, 2));
73
+ console.log(`\nāœ… Cleared all ${cat} commands\n`);
74
+ return;
75
+ }
76
+
77
+ const total = Object.values(data).reduce(
78
+ (sum, commands) => sum + commands.length, 0
79
+ );
80
+
81
+ if (total === 0) {
82
+ console.log("\nšŸ“­ No commands saved yet\n");
83
+ return;
84
+ }
85
+
86
+ const answer = await ask(
87
+ `\nāš ļø Clear ALL ${total} saved commands? This cannot be undone! (yes/no): `
88
+ );
89
+
90
+ if (answer.toLowerCase() !== "yes") {
91
+ console.log("āŒ Cancelled\n");
92
+ return;
93
+ }
94
+
95
+ const emptyData = {
96
+ git: [], npm: [], docker: [], linux: [],
97
+ node: [], angular: [], python: [], others: []
98
+ };
99
+
100
+ fs.writeFileSync(COMMANDS_FILE, JSON.stringify(emptyData, null, 2));
101
+ console.log(`\nāœ… Cleared all ${total} saved commands\n`);
102
+
103
+ } catch (error) {
104
+ console.log("\nāŒ Error clearing commands");
105
+ console.log("šŸ’” Try running tracker init again\n");
106
+ }
107
+ }
108
+
109
+ module.exports = { clearCommand };