thinkncollab-shell 0.0.7 → 0.0.9

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.
@@ -1,101 +1,101 @@
1
- /**
2
- * src/commands/tasks/create-task.js — Create a new task interactively
3
- */
4
- const chalk = require('chalk');
5
-
6
- module.exports = {
7
- name: 'create-task',
8
- description: 'Create a new task in current room',
9
- aliases: ['newtask', 'addtask'],
10
- requiresAuth: true,
11
- requiresRoom: true,
12
-
13
- async execute(args, shell) {
14
- const { input, select, confirm } = require('@inquirer/prompts');
15
- const roomId = shell.ws.getCurrentRoom();
16
-
17
- try {
18
- // Fetch columns of current room's board
19
- const { columns } = await shell.api._request('GET', `/rooms/${roomId}/cli/columns`);
20
- if (!columns?.length) {
21
- console.log(chalk.red('❌ No columns found in this room\'s board'));
22
- return;
23
- }
24
-
25
- console.log(chalk.cyan('\n // create-task\n'));
26
-
27
- const title = await input({
28
- message: 'Task title:',
29
- validate: v => v.trim().length >= 3 || 'Min 3 characters'
30
- });
31
-
32
- const description = await input({ message: 'Description (optional):' });
33
-
34
- const columnId = await select({
35
- message: 'Column:',
36
- choices: columns.map(c => ({ name: c.title, value: c._id }))
37
- });
38
-
39
- const priority = await select({
40
- message: 'Priority:',
41
- choices: [
42
- { name: 'low', value: 'low' },
43
- { name: 'medium', value: 'medium' },
44
- { name: 'high', value: 'high' },
45
- ],
46
- default: 'medium'
47
- });
48
-
49
- const categories = [
50
- 'Bugs', 'Feature Requests', 'Improvements / Enhancements',
51
- 'Production Critical Issues', 'Security Issues', 'Performance Issues',
52
- 'UI/UX Issues', 'Testing & QA', 'DevOps & Infrastructure',
53
- 'Refactoring & Code Quality', 'Documentation', 'Other'
54
- ];
55
- const category = await select({
56
- message: 'Category:',
57
- choices: categories.map(c => ({ name: c, value: c }))
58
- });
59
-
60
- const dueDateStr = await input({
61
- message: 'Due date (YYYY-MM-DD, optional):',
62
- validate: v => {
63
- if (!v) return true;
64
- return !isNaN(Date.parse(v)) || 'Invalid date format';
65
- }
66
- });
67
-
68
- const confirmed = await confirm({ message: 'Create task?', default: true });
69
- if (!confirmed) { console.log(chalk.dim(' Cancelled.')); return; }
70
-
71
- const payload = {
72
- title: title.trim(),
73
- description: description.trim() || undefined,
74
- columnId,
75
- priority,
76
- category: category === 'Other' ? undefined : category,
77
- dueDate: dueDateStr ? new Date(dueDateStr).toISOString() : undefined,
78
- source: 'cli',
79
- };
80
-
81
- const result = await shell.api._request('POST', `/${roomId}/cli/tasks`, payload);
82
-
83
- console.log(chalk.green(`\n✅ Task created: "${result.task.title}"`));
84
- console.log(chalk.dim(` ID: ${result.task._id}`));
85
- console.log(chalk.dim(` Column: ${result.task.columnId?.title || columnId}\n`));
86
-
87
- shell.pushNotification({
88
- type: 'notification',
89
- level: 'success',
90
- title: 'Task Created',
91
- message: result.task.title,
92
- });
93
-
94
- } catch (err) {
95
- if (err.message?.includes('403'))
96
- console.log(chalk.red('❌ You are not a member of this room'));
97
- else
98
- console.log(chalk.red(`❌ ${err.message}`));
99
- }
100
- }
1
+ /*
2
+ src/commands/tasks/create-task.js — Create a new task interactively
3
+ */
4
+ const chalk = require('chalk');
5
+
6
+ module.exports = {
7
+ name: 'create-task',
8
+ description: 'Create a new task in current room',
9
+ aliases: ['newtask', 'addtask'],
10
+ requiresAuth: true,
11
+ requiresRoom: true,
12
+
13
+ async execute(args, shell) {
14
+ const { input, select, confirm } = require('@inquirer/prompts');
15
+ const roomId = shell.ws.getCurrentRoom();
16
+
17
+ try {
18
+ // Fetch columns of current room's board
19
+ const { columns } = await shell.api._request('GET', `/rooms/${roomId}/cli/columns`);
20
+ if (!columns?.length) {
21
+ console.log(chalk.red('❌ No columns found in this room\'s board'));
22
+ return;
23
+ }
24
+
25
+ console.log(chalk.cyan('\n // create-task\n'));
26
+
27
+ const title = await input({
28
+ message: 'Task title:',
29
+ validate: v => v.trim().length >= 3 || 'Min 3 characters'
30
+ });
31
+
32
+ const description = await input({ message: 'Description (optional):' });
33
+
34
+ const columnId = await select({
35
+ message: 'Column:',
36
+ choices: columns.map(c => ({ name: c.title, value: c._id }))
37
+ });
38
+
39
+ const priority = await select({
40
+ message: 'Priority:',
41
+ choices: [
42
+ { name: 'low', value: 'low' },
43
+ { name: 'medium', value: 'medium' },
44
+ { name: 'high', value: 'high' },
45
+ ],
46
+ default: 'medium'
47
+ });
48
+
49
+ const categories = [
50
+ 'Bugs', 'Feature Requests', 'Improvements / Enhancements',
51
+ 'Production Critical Issues', 'Security Issues', 'Performance Issues',
52
+ 'UI/UX Issues', 'Testing & QA', 'DevOps & Infrastructure',
53
+ 'Refactoring & Code Quality', 'Documentation', 'Other'
54
+ ];
55
+ const category = await select({
56
+ message: 'Category:',
57
+ choices: categories.map(c => ({ name: c, value: c }))
58
+ });
59
+
60
+ const dueDateStr = await input({
61
+ message: 'Due date (YYYY-MM-DD, optional):',
62
+ validate: v => {
63
+ if (!v) return true;
64
+ return !isNaN(Date.parse(v)) || 'Invalid date format';
65
+ }
66
+ });
67
+
68
+ const confirmed = await confirm({ message: 'Create task?', default: true });
69
+ if (!confirmed) { console.log(chalk.dim(' Cancelled.')); return; }
70
+
71
+ const payload = {
72
+ title: title.trim(),
73
+ description: description.trim() || undefined,
74
+ columnId,
75
+ priority,
76
+ category: category === 'Other' ? undefined : category,
77
+ dueDate: dueDateStr ? new Date(dueDateStr).toISOString() : undefined,
78
+ source: 'cli',
79
+ };
80
+
81
+ const result = await shell.api._request('POST', `/${roomId}/cli/tasks`, payload);
82
+
83
+ console.log(chalk.green(`\n✅ Task created: "${result.task.title}"`));
84
+ console.log(chalk.dim(` ID: ${result.task._id}`));
85
+ console.log(chalk.dim(` Column: ${result.task.columnId?.title || columnId}\n`));
86
+
87
+ shell.pushNotification({
88
+ type: 'notification',
89
+ level: 'success',
90
+ title: 'Task Created',
91
+ message: result.task.title,
92
+ });
93
+
94
+ } catch (err) {
95
+ if (err.message?.includes('403'))
96
+ console.log(chalk.red('❌ You are not a member of this room'));
97
+ else
98
+ console.log(chalk.red(`❌ ${err.message}`));
99
+ }
100
+ }
101
101
  };
@@ -1,61 +1,61 @@
1
- // src/commands/tasks/task-status.js
2
- const chalk = require('chalk');
3
-
4
- const STATUS_MAP = {
5
- accept: 'accepted',
6
- start: 'inprogress',
7
- complete: 'completed',
8
- reject: 'rejected',
9
- done: 'completed',
10
- };
11
-
12
- module.exports = {
13
- name: 'task-status',
14
- description: 'Update your task status',
15
- aliases: ['accept', 'start', 'complete', 'reject', 'done'],
16
- requiresAuth: true,
17
- requiresRoom: true,
18
-
19
- async execute(args, shell) {
20
- const roomId = shell.ws.getCurrentRoom();
21
- const taskId = args[0];
22
- // invoked as 'accept <id>', 'start <id>', etc.
23
- const verb = shell._lastCommand || 'task-status';
24
- const status = STATUS_MAP[verb] || args[1];
25
-
26
- if (!taskId) {
27
- console.log(chalk.yellow(' Usage: accept <taskId> | start <taskId> | complete <taskId>'));
28
- return;
29
- }
30
- if (!status) {
31
- console.log(chalk.yellow(' Usage: task-status <taskId> <accepted|inprogress|completed|rejected>'));
32
- return;
33
- }
34
-
35
- const statusColors = {
36
- accepted: chalk.green,
37
- inprogress: chalk.blue,
38
- completed: chalk.green,
39
- rejected: chalk.red,
40
- };
41
- const col = statusColors[status] || chalk.white;
42
-
43
- try {
44
- const result = await shell.api._request(
45
- 'POST',
46
- `/thinknsh/${roomId}/tasks/${taskId}/status`,
47
- { status }
48
- );
49
-
50
- console.log(col(`\n ✓ Task "${result.taskTitle}" → ${status}`));
51
- if (result.allCompleted) {
52
- console.log(chalk.green(' 🎉 All assignees done — task fully completed!\n'));
53
- } else {
54
- console.log('');
55
- }
56
-
57
- } catch (err) {
58
- console.log(chalk.red(`\n ❌ ${err.message}\n`));
59
- }
60
- }
1
+ // src/commands/tasks/task-status.js
2
+ const chalk = require('chalk');
3
+
4
+ const STATUS_MAP = {
5
+ accept: 'accepted',
6
+ start: 'inprogress',
7
+ complete: 'completed',
8
+ reject: 'rejected',
9
+ done: 'completed',
10
+ };
11
+
12
+ module.exports = {
13
+ name: 'task-status',
14
+ description: 'Update your task status',
15
+ aliases: ['accept', 'start', 'complete', 'reject', 'done'],
16
+ requiresAuth: true,
17
+ requiresRoom: true,
18
+
19
+ async execute(args, shell) {
20
+ const roomId = shell.ws.getCurrentRoom();
21
+ const taskId = args[0];
22
+ // invoked as 'accept <id>', 'start <id>', etc.
23
+ const verb = shell._lastCommand || 'task-status';
24
+ const status = STATUS_MAP[verb] || args[1];
25
+
26
+ if (!taskId) {
27
+ console.log(chalk.yellow(' Usage: accept <taskId> | start <taskId> | complete <taskId>'));
28
+ return;
29
+ }
30
+ if (!status) {
31
+ console.log(chalk.yellow(' Usage: task-status <taskId> <accepted|inprogress|completed|rejected>'));
32
+ return;
33
+ }
34
+
35
+ const statusColors = {
36
+ accepted: chalk.green,
37
+ inprogress: chalk.blue,
38
+ completed: chalk.green,
39
+ rejected: chalk.red,
40
+ };
41
+ const col = statusColors[status] || chalk.white;
42
+
43
+ try {
44
+ const result = await shell.api._request(
45
+ 'POST',
46
+ `/thinknsh/${roomId}/tasks/${taskId}/status`,
47
+ { status }
48
+ );
49
+
50
+ console.log(col(`\n ✓ Task "${result.taskTitle}" → ${status}`));
51
+ if (result.allCompleted) {
52
+ console.log(chalk.green(' 🎉 All assignees done — task fully completed!\n'));
53
+ } else {
54
+ console.log('');
55
+ }
56
+
57
+ } catch (err) {
58
+ console.log(chalk.red(`\n ❌ ${err.message}\n`));
59
+ }
60
+ }
61
61
  };
@@ -1,75 +1,75 @@
1
- /**
2
- * src/commands/tasks/task.js — View single task detail
3
- */
4
- const chalk = require('chalk');
5
-
6
- module.exports = {
7
- name: 'task',
8
- description: 'View task details by ID',
9
- aliases: ['t'],
10
- requiresAuth: true,
11
-
12
- async execute(args, shell) {
13
- if (!args[0]) {
14
- console.log(chalk.red('Usage: task <task-id>'));
15
- return;
16
- }
17
-
18
- const taskId = args[0];
19
-
20
- try {
21
- const task = await shell.api._request('GET', `/thinknsh/${taskId}/cli`);
22
-
23
- const stColors = {
24
- pending: chalk.yellow,
25
- inprogress: chalk.blue,
26
- review: chalk.magenta,
27
- completed: chalk.green,
28
- reopened: chalk.cyan,
29
- };
30
- const prColors = { high: chalk.red, medium: chalk.yellow, low: chalk.green };
31
- const stColor = stColors[task.status] || chalk.white;
32
- const prColor = prColors[task.priority] || chalk.white;
33
-
34
- console.log(chalk.cyan('\n ─── Task ────────────────────────────────────────'));
35
- console.log(` ${chalk.dim('id')} ${chalk.dim(task._id)}`);
36
- console.log(` ${chalk.dim('title')} ${chalk.bold(task.title)}`);
37
- console.log(` ${chalk.dim('status')} ${stColor(task.status)}`);
38
- console.log(` ${chalk.dim('priority')} ${prColor(task.priority)}`);
39
- if (task.category)
40
- console.log(` ${chalk.dim('category')} ${chalk.dim(task.category)}`);
41
- if (task.dueDate)
42
- console.log(` ${chalk.dim('due')} ${chalk.yellow(new Date(task.dueDate).toLocaleDateString())}`);
43
- if (task.description) {
44
- console.log(chalk.dim('\n description:'));
45
- task.description.split('\n').forEach(l => console.log(` ${chalk.white(l)}`));
46
- }
47
-
48
- if (task.assignedTo?.length) {
49
- console.log(chalk.dim('\n assignees:'));
50
- task.assignedTo.forEach(a => {
51
- const name = a.userId?.name || 'Unknown';
52
- const stBadge = a.status === 'completed' ? chalk.green('✓') :
53
- a.status === 'accepted' ? chalk.blue('●') :
54
- a.status === 'rejected' ? chalk.red('✗') : chalk.dim('○');
55
- console.log(` ${stBadge} ${name} ${chalk.dim(`[${a.status}]`)}`);
56
- });
57
- }
58
-
59
- if (task.columnId?.name || task.columnName)
60
- console.log(`\n ${chalk.dim('column')} ${task.columnId?.name || task.columnName}`);
61
- if (task.boardName)
62
- console.log(` ${chalk.dim('board')} ${task.boardName}`);
63
-
64
- console.log(chalk.cyan(' ─────────────────────────────────────────────────\n'));
65
-
66
- } catch (err) {
67
- if (err.message?.includes('403'))
68
- console.log(chalk.red('❌ Access denied — you are not a member of this room'));
69
- else if (err.message?.includes('404'))
70
- console.log(chalk.red('❌ Task not found'));
71
- else
72
- console.log(chalk.red(`❌ ${err.message}`));
73
- }
74
- }
1
+ /*
2
+ src/commands/tasks/task.js — View single task detail
3
+ */
4
+ const chalk = require('chalk');
5
+
6
+ module.exports = {
7
+ name: 'task',
8
+ description: 'View task details by ID',
9
+ aliases: ['t'],
10
+ requiresAuth: true,
11
+
12
+ async execute(args, shell) {
13
+ if (!args[0]) {
14
+ console.log(chalk.red('Usage: task <task-id>'));
15
+ return;
16
+ }
17
+
18
+
19
+
20
+ const taskId = args[0];
21
+ try {
22
+ const task = await shell.api._request('GET', `/thinknsh/${taskId}/cli`);
23
+ const stColors = {
24
+ pending: chalk.yellow,
25
+ inprogress: chalk.blue,
26
+ review: chalk.magenta,
27
+ completed: chalk.green,
28
+ reopened: chalk.cyan,
29
+ };
30
+ const prColors = { high: chalk.red, medium: chalk.yellow, low: chalk.green };
31
+ const stColor = stColors[task.status] || chalk.white;
32
+ const prColor = prColors[task.priority] || chalk.white;
33
+
34
+ console.log(chalk.cyan('\n ─── Task ────────────────────────────────────────'));
35
+ console.log(` ${chalk.dim('id')} ${chalk.dim(task._id)}`);
36
+ console.log(` ${chalk.dim('title')} ${chalk.bold(task.title)}`);
37
+ console.log(` ${chalk.dim('status')} ${stColor(task.status)}`);
38
+ console.log(` ${chalk.dim('priority')} ${prColor(task.priority)}`);
39
+ if (task.category)
40
+ console.log(` ${chalk.dim('category')} ${chalk.dim(task.category)}`);
41
+ if (task.dueDate)
42
+ console.log(` ${chalk.dim('due')} ${chalk.yellow(new Date(task.dueDate).toLocaleDateString())}`);
43
+ if (task.description) {
44
+ console.log(chalk.dim('\n description:'));
45
+ task.description.split('\n').forEach(l => console.log(` ${chalk.white(l)}`));
46
+ }
47
+
48
+ if (task.assignedTo?.length) {
49
+ console.log(chalk.dim('\n assignees:'));
50
+ task.assignedTo.forEach(a => {
51
+ const name = a.userId?.name || 'Unknown';
52
+ const stBadge = a.status === 'completed' ? chalk.green('✓') :
53
+ a.status === 'accepted' ? chalk.blue('●') :
54
+ a.status === 'rejected' ? chalk.red('✗') : chalk.dim('○');
55
+ console.log(` ${stBadge} ${name} ${chalk.dim(`[${a.status}]`)}`);
56
+ });
57
+ }
58
+
59
+ if (task.columnId?.name || task.columnName)
60
+ console.log(`\n ${chalk.dim('column')} ${task.columnId?.name || task.columnName}`);
61
+ if (task.boardName)
62
+ console.log(` ${chalk.dim('board')} ${task.boardName}`);
63
+
64
+ console.log(chalk.cyan(' ─────────────────────────────────────────────────\n'));
65
+
66
+ } catch (err) {
67
+ if (err.message?.includes('403'))
68
+ console.log(chalk.red('❌ Access denied — you are not a member of this room'));
69
+ else if (err.message?.includes('404'))
70
+ console.log(chalk.red('❌ Task not found'));
71
+ else
72
+ console.log(chalk.red(`❌ ${err.message}`));
73
+ }
74
+ }
75
75
  };