thinkncollab-cli 0.0.76 → 0.0.78

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/bin/index.js CHANGED
@@ -4,8 +4,6 @@ import axios from "axios";
4
4
  import fs from "fs";
5
5
  import os from "os";
6
6
  import path from "path";
7
- import crypto from "crypto";
8
- import FormData from "form-data";
9
7
  import projectInit from "../commands/init.js";
10
8
  import Status from "../commands/status.js";
11
9
  import pull from "../commands/pull.js";
@@ -16,12 +14,16 @@ import createBranch from "../commands/branch.js"
16
14
  import myTask from "../commands/myTask.js"
17
15
  import sendInvite from '../commands/sendInvite.js'
18
16
  import connect from '../commands/connect.js'
17
+ import machine from "node-machine-id";
18
+ import push from "../commands/push.js";
19
+ import taskCompletion from "../commands/taskCompletion.js";
20
+
19
21
 
20
22
 
21
23
 
22
24
  const RC_FILE = path.join(os.homedir(), ".tncrc");
23
25
  const VERSION_FILE = path.join(process.cwd(), ".tncversions");
24
- const BASE_URL = "http://localhost:3001/rooms";
26
+ const BASE_URL = "https://thinkncollab.com/rooms";
25
27
  const CWD = process.cwd();
26
28
 
27
29
  /** ------------------ LOGIN ------------------ **/
@@ -29,13 +31,15 @@ async function login() {
29
31
  const answers = await inquirer.prompt([
30
32
  { type: "input", name: "email", message: "Email:" },
31
33
  { type: "password", name: "password", message: "Password:" }
34
+
32
35
  ]);
33
36
 
34
37
  try {
35
38
  console.log("🔐 Logging in...");
36
39
  const res = await axios.post("https://thinkncollab.com/login", {
37
40
  email: answers.email,
38
- password: answers.password
41
+ password: answers.password,
42
+ machineId: await machine.machineIdSync()
39
43
  });
40
44
 
41
45
  const { token, email } = res.data;
@@ -60,377 +64,6 @@ async function logout() {
60
64
  }
61
65
  }
62
66
 
63
- /** ------------------ TOKEN UTILS ------------------ **/
64
- function readToken() {
65
- if (!fs.existsSync(RC_FILE)) {
66
- console.error("❌ Not logged in. Run 'tnc login' first.");
67
- process.exit(1);
68
- }
69
- const data = JSON.parse(fs.readFileSync(RC_FILE));
70
- return { token: data.token, email: data.email };
71
- }
72
-
73
- /** ------------------ IGNORE HANDLING ------------------ **/
74
- function loadIgnore(folderPath) {
75
- const ignoreFile = path.join(folderPath, ".ignoretnc");
76
- if (!fs.existsSync(ignoreFile)) return [];
77
- return fs
78
- .readFileSync(ignoreFile, "utf-8")
79
- .split("\n")
80
- .map(line => line.trim())
81
- .filter(line => line && !line.startsWith("#"));
82
- }
83
-
84
- function shouldIgnore(relativePath, ignoreList) {
85
- return ignoreList.some(pattern => {
86
- if (pattern.endsWith("/**")) {
87
- const folder = pattern.slice(0, -3);
88
- return relativePath === folder || relativePath.startsWith(folder + path.sep);
89
- }
90
- if (pattern.startsWith("*.")) {
91
- return relativePath.endsWith(pattern.slice(1));
92
- }
93
- return relativePath === pattern;
94
- });
95
- }
96
-
97
- /** ------------------ SCAN FOLDER - FIXED ------------------ **/
98
- function scanFolder(folderPath, ignoreList, rootPath = folderPath) {
99
- const items = fs.readdirSync(folderPath, { withFileTypes: true });
100
- const result = [];
101
-
102
- for (const item of items) {
103
- const fullPath = path.join(folderPath, item.name);
104
- const relativePath = path.relative(rootPath, fullPath);
105
-
106
- if (shouldIgnore(relativePath, ignoreList)) {
107
- console.log("⚠️ Ignored:", relativePath);
108
- continue;
109
- }
110
-
111
- if (item.isDirectory()) {
112
- result.push({
113
- name: item.name,
114
- type: "folder",
115
- children: scanFolder(fullPath, ignoreList, rootPath), // ✅ Keep same rootPath
116
- path: item.name // ✅ Only store folder name, not full path
117
- });
118
- } else {
119
- const stats = fs.statSync(fullPath);
120
- result.push({
121
- name: item.name,
122
- type: "file",
123
- path: relativePath, // ✅ Keep relative path for files
124
- size: stats.size
125
- });
126
- }
127
- }
128
- return result;
129
- }
130
-
131
- /** ------------------ VERSIONING ------------------ **/
132
- function loadVersions() {
133
- if (!fs.existsSync(VERSION_FILE)) return {};
134
- const data = JSON.parse(fs.readFileSync(VERSION_FILE, "utf-8"));
135
-
136
- // Backward compatibility: if old format (just strings), convert to new format
137
- const converted = {};
138
- for (const [path, value] of Object.entries(data)) {
139
- if (typeof value === 'string') {
140
- converted[path] = { hash: value, url: '', version: 1 };
141
- } else {
142
- converted[path] = value;
143
- }
144
- }
145
- return converted;
146
- }
147
-
148
- function saveVersions(versionMap) {
149
- fs.writeFileSync(VERSION_FILE, JSON.stringify(versionMap, null, 2));
150
- }
151
-
152
- function computeFileHash(filePath) {
153
- try {
154
- if (!fs.existsSync(filePath)) return null;
155
-
156
- const stats = fs.statSync(filePath);
157
- if (stats.isDirectory()) {
158
- // For folders: hash of sorted file names + their hashes
159
- const items = fs.readdirSync(filePath).sort();
160
- const childrenHashes = items.map(name =>
161
- computeFileHash(path.join(filePath, name))
162
- ).filter(Boolean).join('|');
163
-
164
- return crypto.createHash("sha256")
165
- .update(`folder:${filePath}|${childrenHashes}`)
166
- .digest("hex");
167
- } else {
168
- // For files: hash of content + file metadata
169
- const content = fs.readFileSync(filePath);
170
- const stats = fs.statSync(filePath);
171
-
172
- return crypto.createHash("sha256")
173
- .update(content)
174
- .update(`size:${stats.size}|mtime:${stats.mtimeMs}`)
175
- .digest("hex");
176
- }
177
- } catch (err) {
178
- console.error(`❌ Error computing hash for ${filePath}:`, err.message);
179
- return null;
180
- }
181
- }
182
-
183
- function checkChanges(fileTree, versionMap, rootPath = CWD) {
184
- return fileTree.map(item => {
185
- const fullPath = path.join(rootPath, item.path || item.name);
186
- const relativePath = item.path || item.name;
187
-
188
- let hash = null;
189
- let changed = true;
190
-
191
- try {
192
- if (fs.existsSync(fullPath)) {
193
- hash = computeFileHash(fullPath);
194
-
195
- // Check against previous version
196
- const prevVersion = versionMap[relativePath];
197
- if (prevVersion && prevVersion.hash === hash) {
198
- changed = false;
199
- }
200
- }
201
- } catch (err) {
202
- console.error(`❌ Error checking changes for ${relativePath}:`, err.message);
203
- }
204
-
205
- const newItem = {
206
- ...item,
207
- changed,
208
- hash,
209
- path: relativePath // Ensure consistent path
210
- };
211
-
212
- // Recursively check children for folders
213
- if (item.type === "folder" && item.children && item.children.length > 0) {
214
- newItem.children = checkChanges(item.children, versionMap, rootPath);
215
- newItem.changed = newItem.changed || newItem.children.some(c => c.changed);
216
- }
217
-
218
- return newItem;
219
- });
220
- }
221
-
222
- /** ------------------ CLOUDINARY UPLOAD ------------------ **/
223
- async function uploadFileSigned(filePath, folder, roomId, token, email) {
224
- const filename = path.basename(filePath);
225
-
226
- const sigRes = await axios.post(
227
- `${BASE_URL}/${roomId}/get-upload-signature`,
228
- { filename, folder, roomId },
229
- { headers: { authorization: `Bearer ${token}`, email } }
230
- );
231
-
232
- const { signature, timestamp, api_key, cloud_name } = sigRes.data;
233
-
234
- const formData = new FormData();
235
- formData.append("file", fs.createReadStream(filePath));
236
- formData.append("folder", folder);
237
- formData.append("public_id", filename);
238
- formData.append("timestamp", timestamp);
239
- formData.append("signature", signature);
240
- formData.append("api_key", api_key);
241
-
242
- const cloudRes = await axios.post(
243
- `https://api.cloudinary.com/v1_1/${cloud_name}/auto/upload`,
244
- formData,
245
- { headers: formData.getHeaders() }
246
- );
247
-
248
- return cloudRes.data.secure_url;
249
- }
250
-
251
- /** ------------------ UPLOAD TREE - FIXED PATH CONSTRUCTION ------------------ **/
252
- async function uploadTree(fileTree, folderHex, roomId, token, email, previousVersions, parentPath = "") {
253
- const uploaded = [];
254
-
255
- for (const node of fileTree) {
256
- // ✅ FIXED: Correct path construction without duplication
257
- let relativePath;
258
- if (parentPath) {
259
- relativePath = path.join(parentPath, node.name).replace(/\\/g, "/");
260
- } else {
261
- relativePath = node.path || node.name;
262
- }
263
-
264
- if (node.type === "folder") {
265
- const children = await uploadTree(node.children, folderHex, roomId, token, email, previousVersions, relativePath);
266
-
267
- uploaded.push({
268
- ...node,
269
- children,
270
- hash: node.hash,
271
- path: relativePath
272
- });
273
- } else {
274
- const prevFile = previousVersions[relativePath];
275
-
276
- if (node.changed) {
277
- try {
278
- console.log(`📤 Uploading changed file: ${relativePath}`);
279
- const url = await uploadFileSigned(path.join(CWD, node.path), `tnc_uploads/${folderHex}`, roomId, token, email);
280
- console.log(`✅ Uploaded: ${relativePath}`);
281
-
282
- uploaded.push({
283
- ...node,
284
- url,
285
- hash: node.hash,
286
- path: relativePath,
287
- version: prevFile ? prevFile.version + 1 : 1
288
- });
289
- } catch (err) {
290
- console.error(`❌ Failed to upload ${relativePath}:`, err.message);
291
- // Fallback to previous version if upload fails
292
- uploaded.push({
293
- ...node,
294
- url: prevFile?.url,
295
- hash: node.hash,
296
- path: relativePath,
297
- version: prevFile?.version || 1
298
- });
299
- }
300
- } else {
301
- // Unchanged file - use previous URL and version
302
- console.log(`📋 Using previous version for: ${relativePath}`);
303
- uploaded.push({
304
- ...node,
305
- url: prevFile?.url,
306
- hash: node.hash,
307
- path: relativePath,
308
- version: prevFile?.version || 1
309
- });
310
- }
311
- }
312
- }
313
-
314
- return uploaded;
315
- }
316
-
317
- /** ------------------ PUSH FUNCTION ------------------ **/
318
- async function push(roomId, targetPath) {
319
- const { token, email } = readToken();
320
- const tncMetaPath = path.join(process.cwd(), ".tnc", ".tncmeta.json");
321
- if (!fs.existsSync(tncMetaPath)) {
322
- console.error("❌ Project not initialized. Run 'tnc init' first.");
323
- process.exit(1);
324
- }
325
- const meta = JSON.parse(fs.readFileSync(tncMetaPath, "utf-8"));
326
- const projectId = meta.projectId;
327
-
328
-
329
- const tncPushInfo = path.join(process.cwd(), ".tnc", ".tncpush.json");
330
- if (!fs.existsSync(tncMetaPath)) {
331
- console.error("❌ Project not initialized. Run 'tnc init' first.");
332
- process.exit(1);
333
- }
334
- const lastFolderId = JSON.parse(fs.readFileSync(tncPushInfo, "utf-8")).folderId;
335
-
336
-
337
-
338
- const stats = fs.statSync(targetPath);
339
- const rootFolder = stats.isDirectory() ? targetPath : path.dirname(targetPath);
340
- const ignoreList = loadIgnore(rootFolder);
341
-
342
- let content;
343
- if (stats.isDirectory()) {
344
- content = scanFolder(targetPath, ignoreList);
345
- } else {
346
- const relativePath = path.basename(targetPath);
347
- content = shouldIgnore(relativePath, ignoreList)
348
- ? []
349
- : [{ name: relativePath, type: "file", path: relativePath, size: stats.size }];
350
- }
351
-
352
- if (!content.length) {
353
- console.log("⚠️ Nothing to upload (all ignored).");
354
- return;
355
- }
356
-
357
- const previousVersions = loadVersions();
358
- console.log('📁 Previous versions:', Object.keys(previousVersions).length);
359
-
360
- const contentWithChanges = checkChanges(content, previousVersions);
361
-
362
- // Debug: Show what changed
363
- const changedFiles = contentWithChanges.flatMap(item =>
364
- item.changed ? [item.path] : []
365
- );
366
- console.log('🔄 Changed files:', changedFiles.length, changedFiles);
367
-
368
- const hasChanges = contentWithChanges.some(item => item.changed || (item.children && item.children.some(c => c.changed)));
369
-
370
- if (!hasChanges) {
371
- console.log("ℹ️ No changes detected since last push.");
372
- return;
373
- }
374
-
375
- try {
376
- const folderHex = crypto.createHash("md5").update(path.basename(targetPath) + Date.now()).digest("hex");
377
-
378
- console.log("🚀 Uploading to Cloudinary...");
379
- const uploadedTree = await uploadTree(contentWithChanges, folderHex, roomId, token, email, previousVersions);
380
-
381
- console.log("🗂️ Sending metadata...");
382
- const res = await axios.post(
383
- `${BASE_URL}/${roomId}/upload`,
384
- { folderId: folderHex, content: uploadedTree, uploadedBy: email, projectId, latestFolderId: lastFolderId},
385
- { headers: { authorization: `Bearer ${token}`, email } }
386
- );
387
-
388
- console.log("✅ Upload complete! Metadata stored successfully.");
389
-
390
- // Save version hashes WITH URLs
391
- const newVersionMap = {};
392
- const flattenAndStore = (items) => {
393
- for (const item of items) {
394
- if (item.type === "file") {
395
- newVersionMap[item.path] = {
396
- hash: item.hash,
397
- url: item.url, // ✅ Store URL locally
398
- version: item.version || 1
399
- };
400
- }
401
- if (item.children) flattenAndStore(item.children);
402
- }
403
- };
404
- flattenAndStore(uploadedTree);
405
- saveVersions(newVersionMap);
406
-
407
- // Determine latest version number from uploaded files
408
- const versionNumbers = Object.values(newVersionMap).map(f => f.version || 1);
409
- const latestVersion = versionNumbers.length > 0 ? Math.max(...versionNumbers) : 1;
410
-
411
- const newPushRecord = {
412
- version: latestVersion,
413
- pushedAt: new Date().toISOString(),
414
- roomId: roomId,
415
- pushedBy: email,
416
- projectId: projectId,
417
- folderId: res.data.folderId
418
- };
419
-
420
-
421
-
422
- const pushFilePath = path.join(CWD, ".tnc", ".tncpush.json");
423
- fs.writeFileSync(
424
- pushFilePath,
425
- JSON.stringify(newPushRecord, null, 2)
426
- );
427
-
428
- console.log(`💾 Saved ${Object.keys(newVersionMap).length} files to .tncversions`);
429
-
430
- } catch (err) {
431
- console.error("❌ Upload failed:", err.response?.data || err.message);
432
- }
433
- }
434
67
 
435
68
  /** ------------------ CLI HANDLER ------------------ **/
436
69
  async function main() {
@@ -443,7 +76,7 @@ async function main() {
443
76
 
444
77
  case "logout":
445
78
  await logout();
446
- break;
79
+ break;
447
80
 
448
81
  case "push": {
449
82
  const roomIndex = args.indexOf("--room");
@@ -452,7 +85,7 @@ async function main() {
452
85
  process.exit(1);
453
86
  }
454
87
  const roomId = args[roomIndex + 1];
455
- const targetPath = args[roomIndex + 3];
88
+ const targetPath = args[roomIndex + 2];
456
89
  await push(roomId, targetPath);
457
90
  break;
458
91
  }
@@ -461,7 +94,10 @@ async function main() {
461
94
  break;
462
95
 
463
96
  case "init":
464
- await projectInit();
97
+ const roomIndex = args.indexOf("init");
98
+ const roomid = args[roomIndex + 1];
99
+ if (!roomid) console.log("Usage: tnc-cli init <roomId>");
100
+ await projectInit(roomid);
465
101
  break;
466
102
 
467
103
  case "create":
@@ -485,13 +121,19 @@ async function main() {
485
121
 
486
122
  case "connect": {
487
123
  const idx = args.indexOf("connect");
124
+ if(idx === -1 || !args[idx+1]){
125
+ console.log(" Usage: tnc-cli connect <roomId> ");
126
+ process.exit(1);
127
+ }
488
128
  const link = args[idx+1];
489
-
490
129
  await connect(link);
491
130
  break;
131
+ }
492
132
 
493
-
494
-
133
+ case "task-complete": {
134
+ const idx = args.indexOf("task-complete");
135
+ await taskCompletion();
136
+ break;
495
137
  }
496
138
 
497
139
  case "pull": {
@@ -528,14 +170,18 @@ async function main() {
528
170
 
529
171
  case "my-tasks": {
530
172
  const roomIdx = args.indexOf("my-tasks");
531
- const roomId = args[roomIdx + 1]; // fixed typo
173
+ const roomId = args[roomIdx + 1];
532
174
 
533
- await myTask(roomId);
175
+ await myTask();
534
176
  break;
535
177
  }
536
178
  case "invite": {
537
179
  const roomIdx = args.indexOf("invite");
538
- const email = args[roomIdx + 1]; // fixed typo
180
+ if (roomIdx === -1 || !args[roomIdx + 1]) {
181
+ console.log("Usage: tnc-cli invite <invitee-email>");
182
+ process.exit(1);
183
+ }
184
+ const email = args[roomIdx + 1];
539
185
 
540
186
  await sendInvite(email);
541
187
  break;
@@ -557,6 +203,7 @@ case "invite": {
557
203
  console.log(" tnc-cli logout");
558
204
  console.log(" tnc-cli help");
559
205
  console.log(" tnc-cli version");
206
+ console.log(" tnc-cli task-complete <task-Id>")
560
207
 
561
208
  }
562
209
  }
@@ -3,6 +3,7 @@ import path from "path";
3
3
  import axios from "axios";
4
4
  import os from "os";
5
5
  import inquirer from "inquirer";
6
+ import getUserInfo from "../lib/getVerify.js";
6
7
 
7
8
 
8
9
  async function updateBranch(branchName, branchId) {
@@ -29,7 +30,7 @@ async function updateBranch(branchName, branchId) {
29
30
  }
30
31
 
31
32
  // Update the current branch
32
- meta.currentBranch = branchName;
33
+ meta.branch = branchName;
33
34
  Object.assign(meta, {branchId: `${branchId}`});
34
35
 
35
36
  // Write updated data
@@ -58,25 +59,27 @@ async function createBranch(roomId) {
58
59
  },
59
60
  ]);
60
61
 
61
- const homeDir = os.homedir();
62
- const tncfilepath = path.join(homeDir, ".tncrc");
62
+ const userInfo = await getUserInfo(); // FIXED
63
63
 
64
- if (!fs.existsSync(tncfilepath)) {
65
- throw new Error("Configuration file not found. Please login first.");
66
- }
64
+ if (!userInfo) {
65
+ throw new Error("User info could not be loaded. Please login first.");
66
+ }
67
67
 
68
- const doc = fs.readFileSync(tncfilepath, "utf-8");
69
- const obj = JSON.parse(doc);
70
- const email = obj.email;
68
+ const email = userInfo.email;
69
+ const token = userInfo.token;
70
+
71
+ if (!email || !token) {
72
+ throw new Error("User email or token missing. Please login again.");
73
+ }
74
+
75
+ console.log(email, token);
71
76
 
72
- if (!email) {
73
- throw new Error("User email not found in configuration. Please login again.");
74
- }
75
77
 
76
78
  const res = await axios.post("https://thinkncollab.com/cli/createBranch", {
77
79
  branchName: branchName.trim(),
78
- roomId,
79
- email,
80
+ roomId : roomId,
81
+ email: email,
82
+ token:token
80
83
  });
81
84
 
82
85
  const {
@@ -1,13 +1,66 @@
1
- import fs from "fs";
2
- import path from "path";
3
1
  import axios from "axios";
2
+ import machine from "node-machine-id";
3
+ import fs from "fs";
4
4
  import os from "os";
5
- import inquirer from "inquirer";
5
+ import path from "path";
6
+
7
+ const tncrcPath = path.join(os.homedir(), ".tncrc");
8
+
9
+ async function connect(roomId) {
10
+ if (!fs.existsSync(tncrcPath)) {
11
+ console.error("❌ You are not logged in. Run 'tnc login' first.");
12
+ process.exit(1);
13
+ }
14
+ const answer = await inquirer.prompt([
15
+ { type: "input", name: "BranchName", message: "Enter Branch Name to create a branch:" }
16
+ ]);
17
+
18
+ const data = fs.readFileSync(tncrcPath, "utf-8");
19
+ const { email, token } = JSON.parse(data);
20
+
21
+ try {
22
+ const response = await axios.post(`https://thinkncollab.com/cli/connect/${roomId}`, {
23
+ email: email,
24
+ token: token,
25
+ machineId: await machine.machineIdSync(),
26
+ branchName: answer.BranchName,
27
+ });
28
+ const CWD= process.cwd();
29
+ const tncFolderPath = path.join(CWD, ".tnc");
30
+ if (!fs.existsSync(tncFolderPath)) fs.mkdirSync(tncFolderPath, { recursive: true });
31
+
32
+ // Write metadata file
33
+ const metaFilePath = path.join(tncFolderPath, ".tncmeta.json");
34
+ const pushFilePath = path.join(tncFolderPath, ".tncpush.json");
35
+
36
+ const metaFileInfo = JSON.stringify({
37
+ "projectId": response.data.project._id,
38
+ "projectName": response.data.project.name,
39
+ "roomId": response.data.project.roomId,
40
+ "branch": null
41
+ });
42
+ fs.writeFileSync(metaFilePath, metaFileInfo);
43
+ fs.writeFileSync(
44
+ pushFilePath,
45
+ " {} "
46
+ )
47
+
48
+ console.log(response.data);
49
+
50
+
51
+
6
52
 
7
53
 
8
- export async function connect(link) {
54
+ // console.log("✅ Connected to project:", response.data.project.name);
55
+ // console.log("Members connected:", response.data.project.membersConnected);
9
56
 
10
- const res = await axios.get("http://localhost:12/cli/connect/roomId");
57
+ } catch (err) {
58
+ if (err.response) {
59
+ console.error(" Error:", err.response.data.error);
60
+ } else {
61
+ console.error(" Error:", err.message);
62
+ }
63
+ }
64
+ }
11
65
 
12
- console.log(res.data);
13
- }
66
+ export default connect;
package/commands/init.js CHANGED
@@ -3,10 +3,11 @@ import os from "os";
3
3
  import path from "path";
4
4
  import inquirer from "inquirer";
5
5
  import axios from "axios";
6
+ import machine from "node-machine-id";
6
7
 
7
8
  const CWD = process.cwd();
8
9
 
9
- async function projectInit() {
10
+ async function projectInit(roomId) {
10
11
  const answer = await inquirer.prompt([
11
12
  { type: "input", name: "projectName", message: "Enter Project Name:" }
12
13
  ]);
@@ -21,11 +22,15 @@ async function projectInit() {
21
22
 
22
23
  const data = fs.readFileSync(tncrcPath, "utf-8");
23
24
  const currentUser = JSON.parse(data).email;
25
+ const userToken = JSON.parse(data).token;
24
26
 
25
27
  // Initialize project via backend
26
28
  const response = await axios.post("https://thinkncollab.com/cli/init", {
27
29
  projectName: answer.projectName,
28
- owner: currentUser
30
+ owner: currentUser,
31
+ token: userToken,
32
+ machineId: await machine.machineIdSync(),
33
+ roomId: roomId
29
34
  });
30
35
 
31
36
  const projectId = response.data.project._id;
@@ -44,6 +49,7 @@ async function projectInit() {
44
49
  projectId,
45
50
  projectName: answer.projectName,
46
51
  currentBranch: "main",
52
+ roomId: roomId,
47
53
  lastCommit: null,
48
54
  files: {}
49
55
  },
File without changes
@@ -4,7 +4,7 @@ import axios from "axios";
4
4
  import os from "os";
5
5
 
6
6
  const homeDir = os.homedir();
7
- const url = "https://thinkncollab.in/cli/mytasks"; // backend endpoint
7
+ const url = "https://thinkncollab.com/cli/mytasks"; // backend endpoint
8
8
 
9
9
  // Get saved email from ~/.tncrc
10
10
  async function getEmail() {
@@ -32,10 +32,14 @@ async function getToken() {
32
32
  }
33
33
 
34
34
  // Fetch tasks for a given room
35
- async function myTask(roomId) {
35
+ async function myTask() {
36
36
  try {
37
37
  const email = await getEmail();
38
38
  const token = await getToken();
39
+ const CWD = process.cwd();
40
+ const metaDataPath = path.join(".tnc", '.tncmeta.json'); // assuming room ID is the current directory name
41
+ const metaData = JSON.parse(fs.readFileSync(path.join(CWD, metaDataPath), 'utf-8'));
42
+ const roomId = metaData.roomId;
39
43
 
40
44
  const res = await axios.get(`${url}/${roomId}`, {
41
45
  params: { email, token } // since backend uses req.query
@@ -50,7 +54,7 @@ async function myTask(roomId) {
50
54
 
51
55
  console.log("📋 Your Tasks:");
52
56
  tasks.forEach((task, i) => {
53
- console.log(`${i + 1}. ${task.title} — ${task.status}`);
57
+ console.log(`${i + 1}. ${task.title} — ${task.status} ${task._id}`);
54
58
  });
55
59
 
56
60
  } catch (error) {