commentme 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/README.md ADDED
@@ -0,0 +1,55 @@
1
+ # commentme
2
+
3
+ A CLI tool to manage and store your cluttered-code comments and give the codebase a clean look. Extract comments from your code files, store them in a database, visit commentme platform for UI-friendly seek and restore your comments line-wise later.
4
+
5
+ ## Installation
6
+
7
+ npm install -g commentme
8
+
9
+ ## Usage
10
+
11
+ # Show help
12
+ commentme --help
13
+
14
+ # Login/Signup
15
+ commentme --login
16
+ commentme --signup
17
+
18
+ # Get all comments
19
+ commentme --get lines <file>
20
+
21
+ # Get a specific comment
22
+ commentme --get line-7-7 <file>
23
+
24
+
25
+ # Edit a comment
26
+ commentme --edit line-7-7 <file>
27
+
28
+ # Delete a comment
29
+ commentme --delete line-7-7 <file>
30
+
31
+ # Redact comments from a file
32
+ commentme --skim <file>
33
+
34
+ # Restore comments to a file
35
+ commentme --unskim <file>
36
+
37
+ # Logout
38
+ commentme --logout
39
+
40
+ ## Features
41
+
42
+ - Clutter-free and smooth codebase
43
+ - Redact comments from files while keeping references
44
+ - Restore comments back to files whenever required
45
+ - User authentication and session management
46
+ - Per-codebase comment organization
47
+ - Dedicated website for more UI friendly & AI edits on comments
48
+
49
+ ## Requirements
50
+
51
+ - Node.js >= 18.0.0
52
+
53
+ ## License
54
+
55
+ MIT
@@ -0,0 +1,23 @@
1
+ import readline from "readline";
2
+ import { getSession } from "../utils/session.js";
3
+ import { signup } from "./signup.js";
4
+ import { login } from "./login.js";
5
+
6
+ export async function ensureAuth() {
7
+ const session = getSession();
8
+ if (session) return;
9
+
10
+ const rl = readline.createInterface({
11
+ input: process.stdin,
12
+ output: process.stdout
13
+ });
14
+
15
+ const choice = await new Promise(res =>
16
+ rl.question("1. Login\n2. Signup\nChoose: ", res)
17
+ );
18
+ rl.close();
19
+
20
+ if (choice === "1") await login();
21
+ else if (choice === "2") await signup();
22
+ else throw new Error("Invalid choice");
23
+ }
package/auth/login.js ADDED
@@ -0,0 +1,160 @@
1
+ import readline from "readline";
2
+ // import bcrypt from "bcryptjs";
3
+ // import { User } from "../models/User.js";
4
+ import { saveSession } from "../utils/session.js";
5
+ import { promptPassword } from "../utils/passwordPrompt.js";
6
+ import { API_BASE_URL } from "../utils/config.js";
7
+
8
+ async function resetPassword() {
9
+ const rl = readline.createInterface({
10
+ input: process.stdin,
11
+ output: process.stdout
12
+ });
13
+
14
+ const ask = q => new Promise(res => rl.question(q, res));
15
+
16
+ const identifier = await ask("Enter your username or email: ");
17
+ rl.close();
18
+
19
+ /*
20
+ // Try to find user by username or email
21
+ const user = await User.findOne({
22
+ $or: [
23
+ { username: identifier },
24
+ { email: identifier }
25
+ ]
26
+ });
27
+
28
+ if (!user) {
29
+ throw new Error("User not found with that username or email");
30
+ }
31
+ */
32
+
33
+ // console.log("User found. Please enter your new password.");
34
+ const new_password = await promptPassword("New Password: ");
35
+ const confirm_password = await promptPassword("Confirm New Password: ");
36
+
37
+ if (new_password !== confirm_password) {
38
+ throw new Error("Passwords do not match");
39
+ }
40
+
41
+ if (new_password.length === 0) {
42
+ throw new Error("Password cannot be empty");
43
+ }
44
+
45
+ /*
46
+ const hashed = await bcrypt.hash(newPassword, 10);
47
+ user.password = hashed;
48
+ await user.save();
49
+
50
+ console.log("✔ Password reset successful");
51
+ console.log("✔ You can now login with your new password");
52
+ */
53
+
54
+ try {
55
+ const response = await fetch(`${API_BASE_URL}/forgot-password`, {
56
+ method: "POST",
57
+ headers: {
58
+ "Content-Type": "application/json",
59
+ },
60
+ body: JSON.stringify({ "identifier": identifier, "newPassword": new_password, "confirmPassword": confirm_password }),
61
+ });
62
+
63
+ const data = await response.json();
64
+
65
+ if (!response.ok) {
66
+ throw new Error(data.message || "Password reset failed");
67
+ }
68
+
69
+ console.log("✔ Password reset successful");
70
+ console.log("✔ You can now login with your new password");
71
+ } catch (error) {
72
+ if (error.code === 'ECONNREFUSED') {
73
+ console.error("Error: Could not connect to the backend server. Is it running on port 8080?");
74
+ throw new Error("Connection Refused");
75
+ } else {
76
+ throw error;
77
+ }
78
+ }
79
+ }
80
+
81
+ export async function login() {
82
+ const rl = readline.createInterface({
83
+ input: process.stdin,
84
+ output: process.stdout
85
+ });
86
+
87
+ const ask = q => new Promise(res => rl.question(q, res));
88
+
89
+ const choice = await ask("1. Login\n2. Forgot Password\nChoose: ");
90
+ rl.close();
91
+
92
+ if (choice === "2") {
93
+ try {
94
+ await resetPassword();
95
+ return;
96
+ } catch (error) {
97
+ // console.error(`✗ ${error.message}`);
98
+ throw error;
99
+ }
100
+ }
101
+
102
+ if (choice !== "1") {
103
+ throw new Error("Invalid choice");
104
+ }
105
+
106
+ // Create a new readline interface for username input
107
+ const rl2 = readline.createInterface({
108
+ input: process.stdin,
109
+ output: process.stdout
110
+ });
111
+
112
+ const ask2 = q => new Promise(res => rl2.question(q, res));
113
+ const username = await ask2("Username: ");
114
+ rl2.close();
115
+
116
+ const password = await promptPassword("Password: ");
117
+
118
+ /*
119
+ const user = await User.findOne({ username });
120
+ if (!user) throw new Error("User not found");
121
+
122
+ const ok = await bcrypt.compare(password, user.password);
123
+ if (!ok) throw new Error("Invalid password");
124
+
125
+ saveSession(user._id);
126
+ console.log("✔ Login successful");
127
+ console.log("✔ Process ran successful");
128
+ */
129
+
130
+ try {
131
+ const response = await fetch(`${API_BASE_URL}/login`, {
132
+ method: "POST",
133
+ headers: {
134
+ "Content-Type": "application/json",
135
+ },
136
+ body: JSON.stringify({ username, password }),
137
+ });
138
+
139
+ const data = await response.json();
140
+
141
+ if (!response.ok) {
142
+ throw new Error(data.message || "Login failed");
143
+ }
144
+
145
+ saveSession({
146
+ ...data,
147
+ token: data.accessToken
148
+ });
149
+ console.log("✔ Login successful");
150
+ console.log("✔ Process ran successful");
151
+ } catch (error) {
152
+ if (error.code === 'ECONNREFUSED') {
153
+ console.error("Error: Could not connect to the backend server. Is it running on port 8080?");
154
+ throw new Error("Connection Refused");
155
+ } else {
156
+ throw error;
157
+ }
158
+ }
159
+
160
+ }
package/auth/logout.js ADDED
@@ -0,0 +1,6 @@
1
+ import { clearSession } from "../utils/session.js";
2
+
3
+ export function logout() {
4
+ clearSession();
5
+ console.log("✔ Logged out successfully");
6
+ }
package/auth/signup.js ADDED
@@ -0,0 +1,71 @@
1
+ import readline from "readline";
2
+ // import bcrypt from "bcryptjs";
3
+ // import { User } from "../models/User.js";
4
+ import { saveSession } from "../utils/session.js";
5
+ import { promptPassword } from "../utils/passwordPrompt.js";
6
+ import { API_BASE_URL } from "../utils/config.js";
7
+
8
+ //signup function
9
+ export async function signup() {
10
+ const rl = readline.createInterface({
11
+ input: process.stdin,
12
+ output: process.stdout
13
+ });
14
+
15
+ const ask = q => new Promise(res => rl.question(q, res));
16
+
17
+ const username = await ask("Username: ");
18
+ const email = await ask("Email: ");
19
+ if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
20
+ console.log("Invalid email address");
21
+ rl.close();
22
+ return;
23
+ }
24
+
25
+ // const existinguser = await User.findOne({ email });
26
+ // if (existinguser) {
27
+ // console.log("User already exists, Try logging in");
28
+ // rl.close();
29
+ // return;
30
+ // }
31
+ rl.close();
32
+
33
+ const password = await promptPassword("Password: ");
34
+
35
+ try {
36
+ const response = await fetch(`${API_BASE_URL}/signup`, {
37
+ method: "POST",
38
+ headers: {
39
+ "Content-Type": "application/json",
40
+ },
41
+ body: JSON.stringify({ username, email, password }),
42
+ });
43
+
44
+ const data = await response.json();
45
+
46
+ if (!response.ok) {
47
+ throw new Error(data.message || "Signup failed");
48
+ }
49
+
50
+ // saveSession({
51
+ // ...data,
52
+ // token: data.accessToken
53
+ // });
54
+
55
+ console.log("✔ Signup successful");
56
+ console.log("👉 Please run 'commentme --login' to authenticate.");
57
+ } catch (error) {
58
+ if (error.code === 'ECONNREFUSED') {
59
+ console.error("Error: Could not connect to the backend server. Is it running on port 8080?");
60
+ } else {
61
+ console.error("Error:", error.message);
62
+ }
63
+ }
64
+
65
+ // const hashed = await bcrypt.hash(password, 10);
66
+ // const user = await User.create({ username, email, password: hashed });
67
+
68
+ // saveSession(user._id);
69
+ // console.log("✔ Signup successful");
70
+ // console.log("✔ Process ran successful");
71
+ }
@@ -0,0 +1,147 @@
1
+ #!/usr/bin/env node
2
+
3
+
4
+ import readline from "readline";
5
+ import { getAllComments } from "../getcoms.js";
6
+ import { getSpecificComment } from "../getspeccoms.js";
7
+ import { editComment } from "../editcoms.js";
8
+ import { deleteComment } from "../deletecoms.js";
9
+ import { removeCommentsFromFile as skim } from "../skimcoms.js";
10
+ import { unskimComments as unskim } from "../unskimcoms.js";
11
+ // import { connectDB, disconnectDB } from "../config/db.js";
12
+ import { ensureAuth } from "../auth/authGuard.js";
13
+ import { logout } from "../auth/logout.js";
14
+ import dotenv from "dotenv";
15
+ dotenv.config();
16
+
17
+ function promptInput(defaultValue = "") {
18
+ const rl = readline.createInterface({
19
+ input: process.stdin,
20
+ output: process.stdout
21
+ });
22
+
23
+ return new Promise(resolve => {
24
+ rl.question("> ", answer => {
25
+ rl.close();
26
+ resolve(answer || defaultValue);
27
+ });
28
+ });
29
+ }
30
+
31
+ async function main() {
32
+ const args = process.argv.slice(2);
33
+ const command = args[0];
34
+
35
+ try {
36
+ // Show help without connecting to DB or requiring auth
37
+ if (command === "--help" || command === "-h" || !command) {
38
+ console.log(`
39
+ commentme CLI
40
+
41
+ Commands:
42
+ commentme --get line-7-7 <file> Get a specific comment by line range
43
+ commentme --get lines <file> Get all comments
44
+ commentme --edit line-7-7 <file> Edit an existing comment
45
+ commentme --delete line-7-7 <file> Delete a comment
46
+ commentme --skim <file> Redact comments from a file and store them
47
+ commentme --unskim <file> Restore comments to a file
48
+ commentme --logout Log out from your session
49
+ commentme --help Show this help message
50
+ `);
51
+ return;
52
+ }
53
+
54
+ /*
55
+ await connectDB();
56
+ */
57
+
58
+ // 🔐 Skip auth ONLY for logout
59
+ // 🔐 Skip auth for logout, login, and signup
60
+ if (command !== "--logout" && command !== "--login" && command !== "--signup") {
61
+ await ensureAuth();
62
+ }
63
+
64
+ switch (command) {
65
+ case "--login":
66
+ await import("../auth/login.js").then(m => m.login());
67
+ break;
68
+
69
+ case "--signup":
70
+ await import("../auth/signup.js").then(m => m.signup());
71
+ break;
72
+
73
+ case "--logout":
74
+
75
+ case "--get":
76
+ if (args[1] === "lines" && args[2]) {
77
+ await getAllComments(args[2]);
78
+ } else {
79
+ const key = args[1]?.replace("line-", "");
80
+ if (!key) throw new Error("Usage: commentme --get line-1-6");
81
+ await getSpecificComment(key, false, args[2]);
82
+ }
83
+ break;
84
+
85
+
86
+ case "--edit": {
87
+ const key = args[1]?.replace("line-", "");
88
+ if (!key) throw new Error("Usage: commentme --edit line-1-6");
89
+
90
+ const existing = await getSpecificComment(key, true, args[2]);
91
+ console.log("Edit comment:");
92
+ const updated = await promptInput(existing);
93
+ await editComment(key, updated, args[2]);
94
+ break;
95
+ }
96
+
97
+ case "--delete": {
98
+ const key = args[1]?.replace("line-", "");
99
+ if (!key) throw new Error("Usage: commentme --delete line-1-6");
100
+ await deleteComment(key, args[2]);
101
+ break;
102
+ }
103
+
104
+ case "--skim":
105
+ if (!args[1]) throw new Error("Usage: commentme --skim <file>");
106
+ await skim(args[1]);
107
+ break;
108
+
109
+ case "--unskim":
110
+ if (!args[1]) throw new Error("Usage: commentme --unskim <file>");
111
+ await unskim(args[1]);
112
+ break;
113
+
114
+ case "--logout":
115
+ logout();
116
+ break;
117
+
118
+ default:
119
+ console.log(`
120
+ commentme CLI
121
+
122
+ Commands:
123
+ commentme --login
124
+ commentme --signup
125
+ commentme --get line-7-7 <file>
126
+ commentme --get lines <file>
127
+ commentme --edit line-7-7 <file>
128
+ commentme --delete line-7-7 <file>
129
+ commentme --skim <file>
130
+ commentme --unskim <file>
131
+ commentme --logout
132
+ `);
133
+ }
134
+
135
+ } catch (err) {
136
+ console.error("❌", err.message);
137
+ } finally {
138
+ /*
139
+ if (command !== "--help" && command !== "-h" && command) {
140
+ await disconnectDB();
141
+ }
142
+ */
143
+ process.exit(0);
144
+ }
145
+ }
146
+
147
+ main();
package/config/db.js ADDED
@@ -0,0 +1,19 @@
1
+ // import mongoose from "mongoose";
2
+
3
+ // export async function connectDB() {
4
+ // const mongoUri = process.env.MONGODB_URI;
5
+
6
+ // if (!mongoUri) {
7
+ // throw new Error("MONGODB_URI environment variable is not set. Please create a .env file with your MongoDB connection string.");
8
+ // }
9
+
10
+ // await mongoose.connect(mongoUri);
11
+
12
+ // console.log("✔ Connected to MongoDB");
13
+ // }
14
+
15
+ // export async function disconnectDB() {
16
+ // await mongoose.disconnect();
17
+ // console.log("✔ Disconnected from MongoDB");
18
+ // }
19
+
package/deletecoms.js ADDED
@@ -0,0 +1,96 @@
1
+ // import fs from "fs";
2
+
3
+ // export function deleteComment(key) {
4
+ // // Check that output.json exists
5
+ // if (!fs.existsSync("output.json")) {
6
+ // console.error("❌ output.json not found. Run skimcoms.js first.");
7
+ // process.exit(1);
8
+ // }
9
+
10
+ // // Load and parse JSON
11
+ // const raw = fs.readFileSync("output.json", "utf8");
12
+ // const comments = JSON.parse(raw);
13
+
14
+ // // Check if this key exists
15
+ // if (!comments[key]) {
16
+ // console.error(`❌ No comment found for key: ${key}`);
17
+ // process.exit(1);
18
+ // }
19
+
20
+ // // Delete the entry
21
+ // delete comments[key];
22
+
23
+ // // Save updated JSON back to file
24
+ // fs.writeFileSync("output.json", JSON.stringify(comments, null, 2));
25
+
26
+ // console.log(`✔ Comment for key ${key} has been deleted.`);
27
+ // }
28
+
29
+
30
+ // import { CommentStore } from "./models/CommentStore.js";
31
+ import path from "path";
32
+ import { getCurrentUserId } from "./utils/currentUser.js";
33
+ import { getSession } from "./utils/session.js";
34
+ import { API_BASE_URL } from "./utils/config.js";
35
+
36
+ export async function deleteComment(key, filePath = null) {
37
+ const codebase = filePath ? path.basename(filePath) : "default";
38
+
39
+ // Check authentication
40
+ try {
41
+ getCurrentUserId();
42
+ } catch (e) {
43
+ console.error(e.message);
44
+ return;
45
+ }
46
+
47
+ const session = getSession();
48
+ const token = session ? session.token : null;
49
+
50
+ try {
51
+ const response = await fetch(`${API_BASE_URL}/comments/${encodeURIComponent(key)}?codebase=${encodeURIComponent(codebase)}`, {
52
+ method: "DELETE",
53
+ headers: {
54
+ "Content-Type": "application/json",
55
+ "Authorization": token ? `Bearer ${token}` : ""
56
+ }
57
+ });
58
+
59
+ const data = await response.json();
60
+
61
+ if (!response.ok) {
62
+ throw new Error(data.message || `Failed to delete comment for key: ${key}`);
63
+ }
64
+
65
+ console.log(`✔ Comment deleted for ${key}`);
66
+
67
+ } catch (error) {
68
+ if (error.code === 'ECONNREFUSED') {
69
+ console.error("Error: Could not connect to the backend server. Is it running on port 8080?");
70
+ } else {
71
+ console.error("Error:", error.message);
72
+ }
73
+ }
74
+
75
+ /*
76
+ const userId = getCurrentUserId();
77
+
78
+ const store = await CommentStore.findOne({ userId });
79
+
80
+ if (!store) {
81
+ throw new Error("No comments found");
82
+ }
83
+
84
+ const codebaseIndex = store.comments.findIndex(c => c.codebase === codebase);
85
+
86
+ if (codebaseIndex === -1 || !store.comments[codebaseIndex].filecomment) {
87
+ throw new Error(`No comment found for key: ${key}`);
88
+ }
89
+
90
+ const codebaseEntry = store.comments[codebaseIndex];
91
+ codebaseEntry.filecomment.delete(key);
92
+ await store.save();
93
+
94
+ console.log(`✔ Comment deleted for ${key}`);
95
+ */
96
+ }
package/editcoms.js ADDED
@@ -0,0 +1,97 @@
1
+ // import fs from "fs";
2
+
3
+ // export function editComment(key, newText) {
4
+ // // Ensure output.json exists
5
+ // if (!fs.existsSync("output.json")) {
6
+ // console.error("❌ output.json not found. Run skimcoms.js first.");
7
+ // process.exit(1);
8
+ // }
9
+
10
+ // // Read and parse the file
11
+ // const raw = fs.readFileSync("output.json", "utf8");
12
+ // const comments = JSON.parse(raw);
13
+
14
+ // // Check if key exists
15
+ // if (!comments[key]) {
16
+ // console.error(`❌ No comment found for key: ${key}`);
17
+ // process.exit(1);
18
+ // }
19
+
20
+ // // Update the value
21
+ // comments[key] = newText.trim();
22
+
23
+ // // Write updated data back to output.json
24
+ // fs.writeFileSync("output.json", JSON.stringify(comments, null, 2));
25
+
26
+ // console.log(`✔ Comment for key ${key} successfully updated.`);
27
+ // console.log(`🆕 New comment: ${comments[key]}`);
28
+ // }
29
+
30
+
31
+ // import { CommentStore } from "./models/CommentStore.js";
32
+ import path from "path";
33
+ import { getCurrentUserId } from "./utils/currentUser.js";
34
+ import { getSession } from "./utils/session.js";
35
+ import { API_BASE_URL } from "./utils/config.js";
36
+
37
+ export async function editComment(key, value, filePath = null) {
38
+ const codebase = filePath ? path.basename(filePath) : "default";
39
+
40
+ // Check authentication
41
+ try {
42
+ getCurrentUserId();
43
+ } catch (e) {
44
+ console.error(e.message);
45
+ return;
46
+ }
47
+
48
+ const session = getSession();
49
+ const token = session ? session.token : null;
50
+
51
+ try {
52
+ const response = await fetch(`${API_BASE_URL}/comments/${encodeURIComponent(key)}?codebase=${encodeURIComponent(codebase)}`, {
53
+ method: "PUT",
54
+ headers: {
55
+ "Content-Type": "application/json",
56
+ "Authorization": token ? `Bearer ${token}` : ""
57
+ },
58
+ body: JSON.stringify({ value })
59
+ });
60
+
61
+ const data = await response.json();
62
+
63
+ if (!response.ok) {
64
+ throw new Error(data.message || `Failed to update comment for key: ${key}`);
65
+ }
66
+
67
+ console.log(`✔ Comment updated for ${key}`);
68
+
69
+ } catch (error) {
70
+ if (error.code === 'ECONNREFUSED') {
71
+ console.error("Error: Could not connect to the backend server. Is it running on port 8080?");
72
+ } else {
73
+ console.error("Error:", error.message);
74
+ }
75
+ }
76
+
77
+ /*
78
+ const userId = getCurrentUserId();
79
+
80
+ const store = await CommentStore.findOne({ userId });
81
+
82
+ if (!store) {
83
+ throw new Error("No comments found");
84
+ }
85
+
86
+ const codebaseIndex = store.comments.findIndex(c => c.codebase === codebase);
87
+
88
+ if (codebaseIndex === -1 || !store.comments[codebaseIndex].filecomment.has(key)) {
89
+ throw new Error(`No comment found for key: ${key}`);
90
+ }
91
+ const codebaseEntry = store.comments[codebaseIndex];
92
+ codebaseEntry.filecomment.set(key, value);
93
+ await store.save();
94
+
95
+ console.log(`✔ Comment updated for ${key}`);
96
+ */
97
+ }