rbin-task-flow 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/.claude/settings.json +3 -0
- package/.claude/settings.local.json +8 -0
- package/.cursor/rules/code_comments.mdc +138 -0
- package/.cursor/rules/commit_practices.mdc +141 -0
- package/.cursor/rules/cursor_rules.mdc +53 -0
- package/.cursor/rules/git_control.mdc +88 -0
- package/.cursor/rules/self_improve.mdc +72 -0
- package/.cursor/rules/task_analysis.mdc +190 -0
- package/.cursor/rules/task_execution.mdc +124 -0
- package/.cursor/rules/task_generation.mdc +118 -0
- package/.cursor/rules/task_refactor.mdc +84 -0
- package/.cursor/rules/task_review.mdc +75 -0
- package/.cursor/rules/task_status.mdc +45 -0
- package/.cursor/rules/task_work.mdc +205 -0
- package/.cursor/settings.json +3 -0
- package/.gemini/settings.json +5 -0
- package/.model-versions.json +17 -0
- package/.task-flow/README.md +66 -0
- package/.task-flow/tasks.input.txt +14 -0
- package/.task-flow/tasks.status.md +21 -0
- package/CLAUDE.md +30 -0
- package/GEMINI.md +30 -0
- package/README.md +381 -0
- package/bin/cli.js +56 -0
- package/lib/install.js +280 -0
- package/lib/utils.js +45 -0
- package/lib/version.js +114 -0
- package/package.json +51 -0
package/lib/install.js
ADDED
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
const fs = require('fs-extra');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const chalk = require('chalk');
|
|
4
|
+
const ora = require('ora');
|
|
5
|
+
const { showHeader, showSuccess, showError, showWarning, showInfo, showNextSteps } = require('./utils');
|
|
6
|
+
|
|
7
|
+
// DiretΓ³rio onde o pacote npm estΓ‘ instalado globalmente
|
|
8
|
+
const TEMPLATE_DIR = path.join(__dirname, '..');
|
|
9
|
+
|
|
10
|
+
async function installInProject(targetPath, options = {}) {
|
|
11
|
+
const isUpdate = options.update || false;
|
|
12
|
+
|
|
13
|
+
showHeader();
|
|
14
|
+
|
|
15
|
+
if (isUpdate) {
|
|
16
|
+
console.log(chalk.blue('π Updating RBIN Task Flow...'));
|
|
17
|
+
} else {
|
|
18
|
+
console.log(chalk.blue('π Installing RBIN Task Flow...'));
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
console.log(chalk.blue('π Target:'), targetPath, '\n');
|
|
22
|
+
|
|
23
|
+
const spinner = ora('Processing...').start();
|
|
24
|
+
|
|
25
|
+
try {
|
|
26
|
+
// Verificar se diretΓ³rio existe
|
|
27
|
+
if (!fs.existsSync(targetPath)) {
|
|
28
|
+
spinner.fail(chalk.red(`Directory not found: ${targetPath}`));
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Verificar permissΓ΅es de escrita
|
|
33
|
+
try {
|
|
34
|
+
fs.accessSync(targetPath, fs.constants.W_OK);
|
|
35
|
+
} catch (error) {
|
|
36
|
+
spinner.fail(chalk.red('No write permission in target directory'));
|
|
37
|
+
process.exit(1);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
spinner.text = 'Creating directories...';
|
|
41
|
+
|
|
42
|
+
// Criar diretΓ³rios necessΓ‘rios
|
|
43
|
+
const dirs = [
|
|
44
|
+
'.cursor/rules',
|
|
45
|
+
'.claude',
|
|
46
|
+
'.gemini',
|
|
47
|
+
'.task-flow'
|
|
48
|
+
];
|
|
49
|
+
|
|
50
|
+
for (const dir of dirs) {
|
|
51
|
+
await fs.ensureDir(path.join(targetPath, dir));
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
spinner.text = 'Copying configuration files...';
|
|
55
|
+
|
|
56
|
+
// Copiar arquivos de configuraΓ§Γ£o
|
|
57
|
+
await copyConfigs(targetPath);
|
|
58
|
+
|
|
59
|
+
spinner.text = 'Updating .gitignore...';
|
|
60
|
+
|
|
61
|
+
// Atualizar .gitignore
|
|
62
|
+
await updateGitignore(targetPath);
|
|
63
|
+
|
|
64
|
+
spinner.succeed(chalk.green('Installation completed!'));
|
|
65
|
+
|
|
66
|
+
console.log('');
|
|
67
|
+
|
|
68
|
+
// Mostrar versΓ΅es configuradas
|
|
69
|
+
await showModelVersions(targetPath);
|
|
70
|
+
|
|
71
|
+
showNextSteps(targetPath);
|
|
72
|
+
|
|
73
|
+
} catch (error) {
|
|
74
|
+
spinner.fail(chalk.red('Installation failed'));
|
|
75
|
+
console.error(chalk.red('\nError:'), error.message);
|
|
76
|
+
process.exit(1);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
async function copyConfigs(targetPath) {
|
|
81
|
+
// Copiar regras do Cursor
|
|
82
|
+
const cursorRulesPath = path.join(TEMPLATE_DIR, '.cursor/rules');
|
|
83
|
+
if (fs.existsSync(cursorRulesPath)) {
|
|
84
|
+
await fs.copy(
|
|
85
|
+
cursorRulesPath,
|
|
86
|
+
path.join(targetPath, '.cursor/rules'),
|
|
87
|
+
{ overwrite: true }
|
|
88
|
+
);
|
|
89
|
+
showSuccess('Cursor rules');
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Copiar settings do Cursor
|
|
93
|
+
const cursorSettingsPath = path.join(TEMPLATE_DIR, '.cursor/settings.json');
|
|
94
|
+
if (fs.existsSync(cursorSettingsPath)) {
|
|
95
|
+
await fs.copy(
|
|
96
|
+
cursorSettingsPath,
|
|
97
|
+
path.join(targetPath, '.cursor/settings.json'),
|
|
98
|
+
{ overwrite: true }
|
|
99
|
+
);
|
|
100
|
+
showSuccess('Cursor settings');
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Copiar settings do Claude
|
|
104
|
+
const claudeSettingsPath = path.join(TEMPLATE_DIR, '.claude/settings.json');
|
|
105
|
+
if (fs.existsSync(claudeSettingsPath)) {
|
|
106
|
+
await fs.copy(
|
|
107
|
+
claudeSettingsPath,
|
|
108
|
+
path.join(targetPath, '.claude/settings.json'),
|
|
109
|
+
{ overwrite: true }
|
|
110
|
+
);
|
|
111
|
+
showSuccess('Claude settings');
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Copiar instruΓ§Γ΅es do Claude
|
|
115
|
+
const claudeInstructionsPath = path.join(TEMPLATE_DIR, 'CLAUDE.md');
|
|
116
|
+
if (fs.existsSync(claudeInstructionsPath)) {
|
|
117
|
+
await fs.copy(
|
|
118
|
+
claudeInstructionsPath,
|
|
119
|
+
path.join(targetPath, 'CLAUDE.md'),
|
|
120
|
+
{ overwrite: true }
|
|
121
|
+
);
|
|
122
|
+
showSuccess('Claude instructions');
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Copiar settings do Gemini
|
|
126
|
+
const geminiSettingsPath = path.join(TEMPLATE_DIR, '.gemini/settings.json');
|
|
127
|
+
if (fs.existsSync(geminiSettingsPath)) {
|
|
128
|
+
await fs.copy(
|
|
129
|
+
geminiSettingsPath,
|
|
130
|
+
path.join(targetPath, '.gemini/settings.json'),
|
|
131
|
+
{ overwrite: true }
|
|
132
|
+
);
|
|
133
|
+
showSuccess('Gemini settings');
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// Copiar instruΓ§Γ΅es do Gemini
|
|
137
|
+
const geminiInstructionsPath = path.join(TEMPLATE_DIR, 'GEMINI.md');
|
|
138
|
+
if (fs.existsSync(geminiInstructionsPath)) {
|
|
139
|
+
await fs.copy(
|
|
140
|
+
geminiInstructionsPath,
|
|
141
|
+
path.join(targetPath, 'GEMINI.md'),
|
|
142
|
+
{ overwrite: true }
|
|
143
|
+
);
|
|
144
|
+
showSuccess('Gemini instructions');
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Copiar Task Flow (preservando dados internos)
|
|
148
|
+
await copyTaskFlow(targetPath);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
async function copyTaskFlow(targetPath) {
|
|
152
|
+
const taskFlowSrc = path.join(TEMPLATE_DIR, '.task-flow');
|
|
153
|
+
const taskFlowDest = path.join(targetPath, '.task-flow');
|
|
154
|
+
|
|
155
|
+
await fs.ensureDir(taskFlowDest);
|
|
156
|
+
|
|
157
|
+
showSuccess('Task Flow directory');
|
|
158
|
+
showInfo('Note: .internal/tasks.json and .internal/status.json are NOT overwritten (your data is safe)');
|
|
159
|
+
|
|
160
|
+
// Copiar apenas templates, nΓ£o sobrescrever dados do usuΓ‘rio
|
|
161
|
+
const files = [
|
|
162
|
+
{ name: 'README.md', overwrite: true },
|
|
163
|
+
{ name: 'tasks.input.txt', overwrite: false },
|
|
164
|
+
{ name: 'tasks.status.md', overwrite: false }
|
|
165
|
+
];
|
|
166
|
+
|
|
167
|
+
for (const file of files) {
|
|
168
|
+
const src = path.join(taskFlowSrc, file.name);
|
|
169
|
+
const dest = path.join(taskFlowDest, file.name);
|
|
170
|
+
|
|
171
|
+
if (fs.existsSync(src)) {
|
|
172
|
+
// Sempre sobrescrever README, outros arquivos sΓ³ se nΓ£o existirem
|
|
173
|
+
if (file.overwrite || !fs.existsSync(dest)) {
|
|
174
|
+
await fs.copy(src, dest, { overwrite: file.overwrite });
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// NΓ£o copiar .internal - deixar que seja criado pela IA
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
async function updateGitignore(targetPath) {
|
|
183
|
+
const gitignorePath = path.join(targetPath, '.gitignore');
|
|
184
|
+
|
|
185
|
+
// Criar se nΓ£o existe
|
|
186
|
+
if (!fs.existsSync(gitignorePath)) {
|
|
187
|
+
await fs.writeFile(gitignorePath, '');
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
let content = await fs.readFile(gitignorePath, 'utf8');
|
|
191
|
+
|
|
192
|
+
// Entradas a adicionar
|
|
193
|
+
const entries = [
|
|
194
|
+
'.claude/',
|
|
195
|
+
'.gemini/',
|
|
196
|
+
'.cursor/',
|
|
197
|
+
'.task-flow/',
|
|
198
|
+
'CLAUDE.md',
|
|
199
|
+
'GEMINI.md'
|
|
200
|
+
];
|
|
201
|
+
|
|
202
|
+
// Remover entradas antigas (caso existam)
|
|
203
|
+
for (const entry of entries) {
|
|
204
|
+
const regex = new RegExp(`^${entry.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}$`, 'gm');
|
|
205
|
+
content = content.replace(regex, '');
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// Remover linhas vazias consecutivas
|
|
209
|
+
content = content.replace(/\n{3,}/g, '\n\n');
|
|
210
|
+
|
|
211
|
+
// Adicionar novas entradas
|
|
212
|
+
if (!content.endsWith('\n')) {
|
|
213
|
+
content += '\n';
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
content += '\n' + entries.join('\n') + '\n';
|
|
217
|
+
|
|
218
|
+
await fs.writeFile(gitignorePath, content);
|
|
219
|
+
|
|
220
|
+
showSuccess('.gitignore updated');
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
async function showModelVersions(targetPath) {
|
|
224
|
+
console.log(chalk.cyan('β'.repeat(60)));
|
|
225
|
+
console.log(chalk.magenta('π Model Versions Configured:'));
|
|
226
|
+
console.log(chalk.cyan('β'.repeat(60)));
|
|
227
|
+
console.log('');
|
|
228
|
+
|
|
229
|
+
let hasModels = false;
|
|
230
|
+
|
|
231
|
+
// Claude
|
|
232
|
+
const claudeSettingsPath = path.join(targetPath, '.claude/settings.json');
|
|
233
|
+
if (fs.existsSync(claudeSettingsPath)) {
|
|
234
|
+
try {
|
|
235
|
+
const settings = await fs.readJSON(claudeSettingsPath);
|
|
236
|
+
if (settings.model) {
|
|
237
|
+
console.log(chalk.blue('Claude:'), chalk.yellow(settings.model));
|
|
238
|
+
hasModels = true;
|
|
239
|
+
}
|
|
240
|
+
} catch (error) {
|
|
241
|
+
// Ignorar erros de parsing
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// Cursor
|
|
246
|
+
const cursorSettingsPath = path.join(targetPath, '.cursor/settings.json');
|
|
247
|
+
if (fs.existsSync(cursorSettingsPath)) {
|
|
248
|
+
try {
|
|
249
|
+
const settings = await fs.readJSON(cursorSettingsPath);
|
|
250
|
+
if (settings.model) {
|
|
251
|
+
console.log(chalk.blue('Cursor:'), chalk.yellow(settings.model));
|
|
252
|
+
hasModels = true;
|
|
253
|
+
}
|
|
254
|
+
} catch (error) {
|
|
255
|
+
// Ignorar erros de parsing
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// Gemini
|
|
260
|
+
const geminiSettingsPath = path.join(targetPath, '.gemini/settings.json');
|
|
261
|
+
if (fs.existsSync(geminiSettingsPath)) {
|
|
262
|
+
try {
|
|
263
|
+
const settings = await fs.readJSON(geminiSettingsPath);
|
|
264
|
+
if (settings.model) {
|
|
265
|
+
console.log(chalk.blue('Gemini:'), chalk.yellow(settings.model));
|
|
266
|
+
hasModels = true;
|
|
267
|
+
}
|
|
268
|
+
} catch (error) {
|
|
269
|
+
// Ignorar erros de parsing
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
if (!hasModels) {
|
|
274
|
+
console.log(chalk.yellow('No model versions configured yet'));
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
console.log('');
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
module.exports = { installInProject };
|
package/lib/utils.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
const chalk = require('chalk');
|
|
2
|
+
|
|
3
|
+
function showHeader() {
|
|
4
|
+
console.clear();
|
|
5
|
+
console.log(chalk.cyan('ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ'));
|
|
6
|
+
console.log(chalk.cyan('β') + ' ' + chalk.magenta('β¨ RBIN Task Flow - Installation β¨') + ' ' + chalk.cyan('β'));
|
|
7
|
+
console.log(chalk.cyan('ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ') + '\n');
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function showSuccess(message) {
|
|
11
|
+
console.log(chalk.green('β
' + message));
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function showError(message) {
|
|
15
|
+
console.log(chalk.red('β ' + message));
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function showWarning(message) {
|
|
19
|
+
console.log(chalk.yellow('β οΈ ' + message));
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function showInfo(message) {
|
|
23
|
+
console.log(chalk.blue('βΉοΈ ' + message));
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function showNextSteps(targetPath) {
|
|
27
|
+
console.log('\n' + chalk.cyan('β'.repeat(60)));
|
|
28
|
+
console.log(chalk.magenta.bold(' Next Steps:'));
|
|
29
|
+
console.log(chalk.cyan('β'.repeat(60)));
|
|
30
|
+
console.log(chalk.blue(' 1.'), 'Edit', chalk.yellow('.task-flow/tasks.input.txt'));
|
|
31
|
+
console.log(chalk.blue(' 2.'), 'Use AI command:', chalk.cyan('task-flow: sync'));
|
|
32
|
+
console.log(chalk.blue(' 3.'), 'Work on tasks:', chalk.cyan('task-flow: run next X'));
|
|
33
|
+
console.log(chalk.blue(' 4.'), 'Check status:', chalk.cyan('task-flow: status'));
|
|
34
|
+
console.log(chalk.cyan('β'.repeat(60)));
|
|
35
|
+
console.log(chalk.blue('\n See'), chalk.yellow('.task-flow/README.md'), chalk.blue('for all available commands\n'));
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
module.exports = {
|
|
39
|
+
showHeader,
|
|
40
|
+
showSuccess,
|
|
41
|
+
showError,
|
|
42
|
+
showWarning,
|
|
43
|
+
showInfo,
|
|
44
|
+
showNextSteps
|
|
45
|
+
};
|
package/lib/version.js
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
const fs = require('fs-extra');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const chalk = require('chalk');
|
|
4
|
+
const readline = require('readline');
|
|
5
|
+
|
|
6
|
+
const TEMPLATE_DIR = path.join(__dirname, '..');
|
|
7
|
+
|
|
8
|
+
function createInterface() {
|
|
9
|
+
return readline.createInterface({
|
|
10
|
+
input: process.stdin,
|
|
11
|
+
output: process.stdout
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function question(rl, query) {
|
|
16
|
+
return new Promise((resolve) => {
|
|
17
|
+
rl.question(query, resolve);
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
async function checkVersionUpdates() {
|
|
22
|
+
const versionsFilePath = path.join(TEMPLATE_DIR, '.model-versions.json');
|
|
23
|
+
|
|
24
|
+
if (!fs.existsSync(versionsFilePath)) {
|
|
25
|
+
console.log(chalk.yellow('β οΈ No version file found'));
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
try {
|
|
30
|
+
const versions = await fs.readJSON(versionsFilePath);
|
|
31
|
+
|
|
32
|
+
console.log('\n' + chalk.cyan('ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ'));
|
|
33
|
+
console.log(chalk.cyan('β') + ' ' + chalk.magenta('π Model Version Check') + ' ' + chalk.cyan('β'));
|
|
34
|
+
console.log(chalk.cyan('ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ') + '\n');
|
|
35
|
+
|
|
36
|
+
const rl = createInterface();
|
|
37
|
+
|
|
38
|
+
// Check Claude
|
|
39
|
+
if (versions.claude) {
|
|
40
|
+
await checkModelVersion('Claude', versions.claude, '.claude/settings.json', rl);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Check Cursor
|
|
44
|
+
if (versions.cursor) {
|
|
45
|
+
await checkModelVersion('Cursor', versions.cursor, '.cursor/settings.json', rl);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Check Gemini
|
|
49
|
+
if (versions.gemini) {
|
|
50
|
+
await checkModelVersion('Gemini', versions.gemini, '.gemini/settings.json', rl);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
rl.close();
|
|
54
|
+
|
|
55
|
+
console.log(chalk.green('\nβ
Version check completed!\n'));
|
|
56
|
+
|
|
57
|
+
} catch (error) {
|
|
58
|
+
console.error(chalk.red('Error reading version file:'), error.message);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
async function checkModelVersion(modelName, versionInfo, settingsPath, rl) {
|
|
63
|
+
const fullSettingsPath = path.join(TEMPLATE_DIR, settingsPath);
|
|
64
|
+
|
|
65
|
+
if (!fs.existsSync(fullSettingsPath)) {
|
|
66
|
+
console.log(chalk.gray(`${modelName}: Settings file not found`));
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
try {
|
|
71
|
+
const settings = await fs.readJSON(fullSettingsPath);
|
|
72
|
+
const currentVersion = settings.model;
|
|
73
|
+
|
|
74
|
+
if (!currentVersion) {
|
|
75
|
+
console.log(chalk.gray(`${modelName}: No model configured`));
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
console.log('');
|
|
80
|
+
console.log(chalk.blue('β'.repeat(60)));
|
|
81
|
+
console.log(chalk.blue.bold(`${modelName}:`));
|
|
82
|
+
console.log(chalk.cyan(' Current:'), chalk.yellow(currentVersion));
|
|
83
|
+
console.log(chalk.cyan(' Latest:'), chalk.yellow(versionInfo.latest));
|
|
84
|
+
|
|
85
|
+
if (versionInfo.checkUrl) {
|
|
86
|
+
console.log(chalk.cyan(' Info:'), chalk.gray(versionInfo.checkUrl));
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (currentVersion !== versionInfo.latest) {
|
|
90
|
+
console.log(chalk.yellow('\n β οΈ New version available!'));
|
|
91
|
+
|
|
92
|
+
const answer = await question(
|
|
93
|
+
rl,
|
|
94
|
+
chalk.blue(` Update ${modelName} to ${versionInfo.latest}? [y/N]: `)
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
if (answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes') {
|
|
98
|
+
settings.model = versionInfo.latest;
|
|
99
|
+
await fs.writeJSON(fullSettingsPath, settings, { spaces: 2 });
|
|
100
|
+
console.log(chalk.green(` β
${modelName} updated to ${versionInfo.latest}`));
|
|
101
|
+
console.log(chalk.cyan(' (Repository template updated - run init/update on projects to apply)'));
|
|
102
|
+
} else {
|
|
103
|
+
console.log(chalk.cyan(' Skipped update'));
|
|
104
|
+
}
|
|
105
|
+
} else {
|
|
106
|
+
console.log(chalk.green(' β
Up to date'));
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
} catch (error) {
|
|
110
|
+
console.log(chalk.red(`${modelName}: Error reading settings -`), error.message);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
module.exports = { checkVersionUpdates };
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "rbin-task-flow",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "AI-powered task management for Claude, Cursor, and Gemini",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"rbin-task-flow": "./bin/cli.js",
|
|
8
|
+
"task-flow": "./bin/cli.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"test": "echo \"No tests yet\"",
|
|
12
|
+
"prepublishOnly": "chmod +x bin/cli.js"
|
|
13
|
+
},
|
|
14
|
+
"keywords": [
|
|
15
|
+
"task-flow",
|
|
16
|
+
"ai",
|
|
17
|
+
"claude",
|
|
18
|
+
"cursor",
|
|
19
|
+
"gemini",
|
|
20
|
+
"cli",
|
|
21
|
+
"task-management",
|
|
22
|
+
"ai-powered"
|
|
23
|
+
],
|
|
24
|
+
"author": "Rubens de Oliveira",
|
|
25
|
+
"license": "MIT",
|
|
26
|
+
"repository": {
|
|
27
|
+
"type": "git",
|
|
28
|
+
"url": "https://github.com/rubensdeoliveira/rbin-task-flow.git"
|
|
29
|
+
},
|
|
30
|
+
"files": [
|
|
31
|
+
"bin/",
|
|
32
|
+
".cursor/",
|
|
33
|
+
".claude/",
|
|
34
|
+
".gemini/",
|
|
35
|
+
".task-flow/",
|
|
36
|
+
".model-versions.json",
|
|
37
|
+
"CLAUDE.md",
|
|
38
|
+
"GEMINI.md",
|
|
39
|
+
"lib/"
|
|
40
|
+
],
|
|
41
|
+
"preferGlobal": true,
|
|
42
|
+
"engines": {
|
|
43
|
+
"node": ">=14.0.0"
|
|
44
|
+
},
|
|
45
|
+
"dependencies": {
|
|
46
|
+
"chalk": "^4.1.2",
|
|
47
|
+
"commander": "^11.0.0",
|
|
48
|
+
"fs-extra": "^11.0.0",
|
|
49
|
+
"ora": "^5.4.1"
|
|
50
|
+
}
|
|
51
|
+
}
|