rbin-task-flow 1.2.0 → 1.4.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/lib/install.js CHANGED
@@ -39,7 +39,6 @@ async function installInProject(targetPath, options = {}) {
39
39
  const dirs = [
40
40
  '.cursor/rules',
41
41
  '.claude',
42
- '.gemini',
43
42
  '.task-flow'
44
43
  ];
45
44
 
@@ -111,26 +110,6 @@ async function copyConfigs(targetPath) {
111
110
  showSuccess('Claude instructions');
112
111
  }
113
112
 
114
- const geminiSettingsPath = path.join(TEMPLATE_DIR, '.gemini/settings.json');
115
- if (fs.existsSync(geminiSettingsPath)) {
116
- await fs.copy(
117
- geminiSettingsPath,
118
- path.join(targetPath, '.gemini/settings.json'),
119
- { overwrite: true }
120
- );
121
- showSuccess('Gemini settings');
122
- }
123
-
124
- const geminiInstructionsPath = path.join(TEMPLATE_DIR, 'GEMINI.md');
125
- if (fs.existsSync(geminiInstructionsPath)) {
126
- await fs.copy(
127
- geminiInstructionsPath,
128
- path.join(targetPath, 'GEMINI.md'),
129
- { overwrite: true }
130
- );
131
- showSuccess('Gemini instructions');
132
- }
133
-
134
113
  await copyTaskFlow(targetPath);
135
114
  }
136
115
 
@@ -143,16 +122,16 @@ async function copyTaskFlow(targetPath) {
143
122
  showSuccess('Task Flow directory');
144
123
  showInfo('Note: .internal/tasks.json and .internal/status.json are NOT overwritten (your data is safe)');
145
124
 
146
- const screensDest = path.join(taskFlowDest, 'screens');
147
- await fs.ensureDir(screensDest);
148
- showSuccess('Screenshots directory (.task-flow/screens/)');
125
+ const contextsDest = path.join(taskFlowDest, 'contexts');
126
+ await fs.ensureDir(contextsDest);
127
+ showSuccess('Contexts directory (.task-flow/contexts/)');
149
128
 
150
129
  const docsDest = path.join(taskFlowDest, 'docs');
151
130
  await fs.ensureDir(docsDest);
152
131
  showSuccess('Documentation directory (.task-flow/docs/)');
153
132
 
154
- const exampleSrc = path.join(taskFlowSrc, 'screens/example.png.txt');
155
- const exampleDest = path.join(screensDest, 'example.png.txt');
133
+ const exampleSrc = path.join(taskFlowSrc, 'contexts/example.png.txt');
134
+ const exampleDest = path.join(contextsDest, 'example.png.txt');
156
135
  if (fs.existsSync(exampleSrc) && !fs.existsSync(exampleDest)) {
157
136
  await fs.copy(exampleSrc, exampleDest);
158
137
  }
@@ -186,11 +165,9 @@ async function updateGitignore(targetPath) {
186
165
 
187
166
  const entries = [
188
167
  '.claude/',
189
- '.gemini/',
190
168
  '.cursor/',
191
169
  '.task-flow/',
192
- 'CLAUDE.md',
193
- 'GEMINI.md'
170
+ 'CLAUDE.md'
194
171
  ];
195
172
 
196
173
  for (const entry of entries) {
@@ -246,24 +223,6 @@ async function showModelVersions(targetPath) {
246
223
  }
247
224
  }
248
225
 
249
- const geminiSettingsPath = path.join(targetPath, '.gemini/settings.json');
250
- if (fs.existsSync(geminiSettingsPath)) {
251
- try {
252
- const settings = await fs.readJSON(geminiSettingsPath);
253
- if (settings.model) {
254
- const modelName = typeof settings.model === 'string'
255
- ? settings.model
256
- : settings.model.name || 'Default (recommended)';
257
- console.log(chalk.blue('Gemini:'), chalk.yellow(modelName));
258
- hasModels = true;
259
- } else {
260
- console.log(chalk.blue('Gemini:'), chalk.yellow('Default (recommended)'));
261
- hasModels = true;
262
- }
263
- } catch (error) {
264
- }
265
- }
266
-
267
226
  if (!hasModels) {
268
227
  console.log(chalk.yellow('No model versions configured yet'));
269
228
  }
package/lib/report.js CHANGED
@@ -2,8 +2,9 @@ const fs = require('fs-extra');
2
2
  const path = require('path');
3
3
  const chalk = require('chalk');
4
4
  const { execSync } = require('child_process');
5
+ const { parseTaskIds } = require('./utils');
5
6
 
6
- async function generateReport(taskId, targetPath = process.cwd()) {
7
+ async function generateReport(taskIdsInput, targetPath = process.cwd()) {
7
8
  const tasksPath = path.join(targetPath, '.task-flow/.internal/tasks.json');
8
9
  const statusPath = path.join(targetPath, '.task-flow/.internal/status.json');
9
10
  const docsDir = path.join(targetPath, '.task-flow/docs');
@@ -22,36 +23,54 @@ async function generateReport(taskId, targetPath = process.cwd()) {
22
23
  const tasksData = await fs.readJSON(tasksPath);
23
24
  const statusData = await fs.readJSON(statusPath);
24
25
 
25
- const task = tasksData.tasks.find(t => t.id === parseInt(taskId));
26
-
27
- if (!task) {
28
- console.log(chalk.red(`❌ Task ${taskId} not found.`));
26
+ const taskIds = parseTaskIds(taskIdsInput, tasksData.tasks);
27
+
28
+ if (taskIds.length === 0) {
29
+ console.log(chalk.red('❌ No valid task IDs provided.'));
29
30
  return;
30
31
  }
31
32
 
32
- const taskStatus = statusData.tasks[taskId.toString()];
33
-
34
- if (!taskStatus) {
35
- console.log(chalk.yellow(`⚠️ Task ${taskId} has no status information.`));
36
- }
33
+ await fs.ensureDir(docsDir);
37
34
 
38
- const isCompleted = taskStatus && taskStatus.status === 'done';
39
- const allSubtasksDone = taskStatus && taskStatus.subtasks
40
- ? Object.values(taskStatus.subtasks).every(status => status === 'done')
41
- : false;
35
+ let successCount = 0;
36
+ let errorCount = 0;
42
37
 
43
- if (!isCompleted && !allSubtasksDone) {
44
- console.log(chalk.yellow(`⚠️ Task ${taskId} is not completed. Generating partial report...`));
45
- }
38
+ for (const taskId of taskIds) {
39
+ const task = tasksData.tasks.find(t => t.id === taskId);
46
40
 
47
- await fs.ensureDir(docsDir);
41
+ if (!task) {
42
+ console.log(chalk.red(`❌ Task ${taskId} not found.`));
43
+ errorCount++;
44
+ continue;
45
+ }
48
46
 
49
- const reportContent = await buildReport(task, taskStatus, targetPath);
50
- const reportPath = path.join(docsDir, `task-${taskId}-implementation.md`);
47
+ const taskStatus = statusData.tasks[taskId.toString()];
48
+
49
+ if (!taskStatus) {
50
+ console.log(chalk.yellow(`⚠️ Task ${taskId} has no status information.`));
51
+ }
52
+
53
+ const isCompleted = taskStatus && taskStatus.status === 'done';
54
+ const allSubtasksDone = taskStatus && taskStatus.subtasks
55
+ ? Object.values(taskStatus.subtasks).every(status => status === 'done')
56
+ : false;
57
+
58
+ if (!isCompleted && !allSubtasksDone) {
59
+ console.log(chalk.yellow(`⚠️ Task ${taskId} is not completed. Generating partial report...`));
60
+ }
51
61
 
52
- await fs.writeFile(reportPath, reportContent, 'utf8');
62
+ const reportContent = await buildReport(task, taskStatus, targetPath);
63
+ const reportPath = path.join(docsDir, `task-${taskId}-implementation.md`);
53
64
 
54
- console.log(chalk.green(`✅ Report generated: ${reportPath}`));
65
+ await fs.writeFile(reportPath, reportContent, 'utf8');
66
+
67
+ console.log(chalk.green(`✅ Report generated: ${reportPath}`));
68
+ successCount++;
69
+ }
70
+
71
+ if (taskIds.length > 1) {
72
+ console.log(chalk.cyan(`\n📊 Generated ${successCount} report(s), ${errorCount} error(s)`));
73
+ }
55
74
 
56
75
  } catch (error) {
57
76
  console.error(chalk.red('Error generating report:'), error.message);
package/lib/utils.js CHANGED
@@ -35,11 +35,26 @@ function showNextSteps(targetPath) {
35
35
  console.log(chalk.blue('\n See'), chalk.yellow('.task-flow/README.md'), chalk.blue('for all available commands\n'));
36
36
  }
37
37
 
38
+ function parseTaskIds(input, allTasks = []) {
39
+ if (!input || input.trim().toLowerCase() === 'all') {
40
+ return allTasks.map(t => t.id);
41
+ }
42
+
43
+ const ids = input.split(',')
44
+ .map(id => id.trim())
45
+ .filter(id => id.length > 0)
46
+ .map(id => parseInt(id))
47
+ .filter(id => !isNaN(id));
48
+
49
+ return ids;
50
+ }
51
+
38
52
  module.exports = {
39
53
  showHeader,
40
54
  showSuccess,
41
55
  showError,
42
56
  showWarning,
43
57
  showInfo,
44
- showNextSteps
58
+ showNextSteps,
59
+ parseTaskIds
45
60
  };
package/lib/version.js CHANGED
@@ -43,10 +43,6 @@ async function checkVersionUpdates() {
43
43
  await checkModelVersion('Cursor', versions.cursor, '.cursor/settings.json', rl);
44
44
  }
45
45
 
46
- if (versions.gemini) {
47
- await checkModelVersion('Gemini', versions.gemini, '.gemini/settings.json', rl);
48
- }
49
-
50
46
  rl.close();
51
47
 
52
48
  console.log(chalk.green('\n✅ Version check completed!\n'));
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "rbin-task-flow",
3
- "version": "1.2.0",
4
- "description": "AI-powered task management for Claude, Cursor, and Gemini",
3
+ "version": "1.4.0",
4
+ "description": "AI-powered task management for Claude and Cursor",
5
5
  "main": "index.js",
6
6
  "bin": {
7
- "rbin-task-flow": "./bin/cli.js",
8
- "task-flow": "./bin/cli.js"
7
+ "rbin-task-flow": "bin/cli.js",
8
+ "task-flow": "bin/cli.js"
9
9
  },
10
10
  "scripts": {
11
11
  "test": "echo \"No tests yet\"",
@@ -16,7 +16,6 @@
16
16
  "ai",
17
17
  "claude",
18
18
  "cursor",
19
- "gemini",
20
19
  "cli",
21
20
  "task-management",
22
21
  "ai-powered"
@@ -25,17 +24,15 @@
25
24
  "license": "MIT",
26
25
  "repository": {
27
26
  "type": "git",
28
- "url": "https://github.com/rbinoliveira/rbin-task-flow.git"
27
+ "url": "git+https://github.com/rbinoliveira/rbin-task-flow.git"
29
28
  },
30
29
  "files": [
31
30
  "bin/",
32
31
  ".cursor/",
33
32
  ".claude/",
34
- ".gemini/",
35
33
  ".task-flow/",
36
34
  ".model-versions.json",
37
35
  "CLAUDE.md",
38
- "GEMINI.md",
39
36
  "lib/"
40
37
  ],
41
38
  "preferGlobal": true,
@@ -1,5 +0,0 @@
1
- {
2
- "model": {
3
- "name": "gemini-3-flash"
4
- }
5
- }
@@ -1,23 +0,0 @@
1
- # Example Screenshot
2
-
3
- This is a placeholder file. Replace this file with a real screenshot (PNG or JPG).
4
-
5
- ## How to add screenshots:
6
-
7
- 1. Add your image files (.png or .jpg) to this folder
8
- 2. Use descriptive names in kebab-case
9
- 3. RBIN Task Flow will automatically detect and reference the screenshots
10
-
11
- ## Example names:
12
-
13
- - `login_recover_signup.png`
14
- - `dashboard.png`
15
- - `patient.png`
16
- - `patient_profile.png`
17
- - `prescriptions.png`
18
- - `medicine.png`
19
-
20
- ## Reference in tasks:
21
-
22
- To reference a specific screenshot in a task, use:
23
- `task-flow-screen filename.png`
package/GEMINI.md DELETED
@@ -1,32 +0,0 @@
1
- # Gemini Instructions
2
-
3
- ## Development Rules
4
-
5
- All development rules are automatically loaded from `.cursor/rules/` directory. These rules include:
6
- - Cursor rules formatting guidelines
7
- - Self-improvement processes
8
- - Code commenting standards
9
- - Commit practices
10
- - Git command control
11
- - Task execution management with RBIN Task Flow
12
-
13
- ## RBIN Task Flow
14
-
15
- This project uses RBIN Task Flow for task management:
16
- - **Task Definition**: Edit `.task-flow/tasks.input.txt` using simple format: `- Task description`
17
- - **AI Commands**: Use AI-powered commands for task management:
18
- - `task-flow: sync` - Synchronize tasks from tasks.input.txt
19
- - `task-flow: run next X` - Work on next X subtasks
20
- - `task-flow: run task X` - Execute all pending subtasks of task X
21
- - `task-flow: status` - View current task status
22
- - `task-flow: review` - Review completed tasks
23
- - `task-flow: think` - Analyze code and suggest new tasks
24
- - `task-flow: refactor` - Refactor code from current commit
25
- - `task-flow: estimate task X` - Estimate time for task X based on subtasks and experience level
26
- - `task-flow: report task X` - Generate implementation report for completed task X
27
- - **Files**:
28
- - `.task-flow/tasks.input.txt` - Define your tasks here
29
- - `.task-flow/tasks.status.md` - Auto-generated status (DO NOT EDIT manually)
30
- - `.task-flow/.internal/` - Internal system files (ignore)
31
-
32
- Follow all rules defined in `.cursor/rules/` for consistent development practices.