rbin-task-flow 1.19.5 → 1.23.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/skills/rbin-coding-standards/SKILL.md +29 -0
- package/.claude/skills/rbin-coding-standards/reference.md +42 -0
- package/.claude/skills/rbin-git/SKILL.md +39 -0
- package/.claude/skills/task-flow-audit/SKILL.md +15 -0
- package/.claude/skills/task-flow-check/SKILL.md +15 -0
- package/.claude/skills/task-flow-estimate/SKILL.md +15 -0
- package/.claude/skills/task-flow-generate-flow/SKILL.md +15 -0
- package/.claude/skills/task-flow-improve-changes/SKILL.md +15 -0
- package/.claude/skills/task-flow-refactor/SKILL.md +14 -0
- package/.claude/skills/task-flow-report/SKILL.md +15 -0
- package/.claude/skills/task-flow-review/SKILL.md +14 -0
- package/.claude/skills/task-flow-run/SKILL.md +28 -0
- package/.claude/skills/task-flow-run/workflow.md +59 -0
- package/.claude/skills/task-flow-status/SKILL.md +13 -0
- package/.claude/skills/task-flow-sync/SKILL.md +30 -0
- package/.claude/skills/task-flow-sync/workflow.md +57 -0
- package/.claude/skills/task-flow-think/SKILL.md +17 -0
- package/.codex/config.toml +10 -0
- package/.cursor/rules/code_comments.mdc +4 -4
- package/.cursor/rules/coding_standards.mdc +57 -810
- package/.cursor/rules/commit_practices.mdc +5 -138
- package/.cursor/rules/cursor_rules.mdc +4 -3
- package/.cursor/rules/git_control.mdc +5 -86
- package/.cursor/rules/graphify-task-flow.mdc +31 -0
- package/.cursor/rules/rbin-git-policy.mdc +47 -0
- package/.cursor/rules/self_improve.mdc +3 -3
- package/.cursor/rules/task-flow-cursor.mdc +51 -0
- package/.cursor/rules/task-flow-sync.mdc +46 -0
- package/.cursor/rules/task_analysis.mdc +31 -179
- package/.cursor/rules/task_audit.mdc +6 -5
- package/.cursor/rules/task_check.mdc +2 -3
- package/.cursor/rules/task_estimate.mdc +3 -4
- package/.cursor/rules/task_execution.mdc +26 -138
- package/.cursor/rules/task_generate_flow.mdc +2 -3
- package/.cursor/rules/task_generation.mdc +22 -140
- package/.cursor/rules/task_improve_changes.mdc +3 -4
- package/.cursor/rules/task_refactor.mdc +4 -5
- package/.cursor/rules/task_report.mdc +3 -4
- package/.cursor/rules/task_review.mdc +4 -5
- package/.cursor/rules/task_status.mdc +4 -4
- package/.cursor/rules/task_work.mdc +23 -210
- package/.task-flow/AI-PLATFORMS.md +104 -0
- package/.task-flow/CODEX.md +141 -0
- package/.task-flow/CURSOR.md +94 -0
- package/.task-flow/GRAPHIFY.md +112 -0
- package/.task-flow/OPTIMIZATION-IMPLEMENTATION-TASKS.md +365 -0
- package/.task-flow/OPTIMIZATION-PLAN.md +264 -0
- package/.task-flow/README.md +19 -4
- package/.task-flow/docs/coding-standards-full.md +851 -0
- package/.task-flow/platforms/claude-code.md +352 -0
- package/.task-flow/platforms/codex.md +379 -0
- package/.task-flow/platforms/cursor.md +333 -0
- package/AGENTS.md +69 -31
- package/CLAUDE.md +56 -48
- package/README.md +78 -10
- package/bin/cli.js +40 -25
- package/lib/codex.js +45 -0
- package/lib/cursor.js +41 -0
- package/lib/gitignore.js +101 -0
- package/lib/graphify.js +118 -0
- package/lib/install.js +83 -47
- package/lib/profiles.js +110 -0
- package/lib/skills.js +34 -0
- package/lib/utils.js +38 -2
- package/package.json +6 -2
package/lib/install.js
CHANGED
|
@@ -3,13 +3,41 @@ const path = require('path');
|
|
|
3
3
|
const chalk = require('chalk');
|
|
4
4
|
const ora = require('ora');
|
|
5
5
|
const { showHeader, showSuccess, showError, showWarning, showInfo, showNextSteps } = require('./utils');
|
|
6
|
+
const { setupGraphifyIntegration } = require('./graphify');
|
|
7
|
+
const { copySkillsToProject } = require('./skills');
|
|
8
|
+
const { setupCodexIntegration } = require('./codex');
|
|
9
|
+
const { setupCursorIntegration } = require('./cursor');
|
|
10
|
+
const {
|
|
11
|
+
PROFILE_MINIMAL,
|
|
12
|
+
PROFILE_STANDARD,
|
|
13
|
+
resolveProfile,
|
|
14
|
+
resolveShareAiConfig,
|
|
15
|
+
writeInstallMeta,
|
|
16
|
+
copyCursorRules,
|
|
17
|
+
} = require('./profiles');
|
|
18
|
+
const { updateGitignore } = require('./gitignore');
|
|
19
|
+
|
|
20
|
+
const PROFILES = { STANDARD: PROFILE_STANDARD, MINIMAL: PROFILE_MINIMAL };
|
|
6
21
|
|
|
7
22
|
const TEMPLATE_DIR = path.join(__dirname, '..');
|
|
23
|
+
const PACKAGE_VERSION = require('../package.json').version;
|
|
8
24
|
|
|
9
25
|
async function installInProject(targetPath, options = {}) {
|
|
10
26
|
const isUpdate = options.update || false;
|
|
11
27
|
const isReset = options.reset || false;
|
|
12
28
|
|
|
29
|
+
let profile;
|
|
30
|
+
let shareAiConfig;
|
|
31
|
+
try {
|
|
32
|
+
profile = await resolveProfile(targetPath, { profile: options.profile });
|
|
33
|
+
shareAiConfig = await resolveShareAiConfig(targetPath, {
|
|
34
|
+
shareAiConfig: options.shareAiConfig,
|
|
35
|
+
});
|
|
36
|
+
} catch (error) {
|
|
37
|
+
showError(error.message);
|
|
38
|
+
process.exit(1);
|
|
39
|
+
}
|
|
40
|
+
|
|
13
41
|
showHeader();
|
|
14
42
|
|
|
15
43
|
if (isReset) {
|
|
@@ -20,7 +48,21 @@ async function installInProject(targetPath, options = {}) {
|
|
|
20
48
|
console.log(chalk.blue('🚀 Installing RBIN Task Flow...'));
|
|
21
49
|
}
|
|
22
50
|
|
|
23
|
-
console.log(chalk.blue('📁 Target:'), targetPath
|
|
51
|
+
console.log(chalk.blue('📁 Target:'), targetPath);
|
|
52
|
+
console.log(
|
|
53
|
+
chalk.blue('📦 Profile:'),
|
|
54
|
+
profile === PROFILES.MINIMAL ? chalk.yellow('minimal') : chalk.green('standard'),
|
|
55
|
+
profile === PROFILES.MINIMAL
|
|
56
|
+
? chalk.gray('(2 always-on rules + skills; workflows via @task-flow-*)')
|
|
57
|
+
: chalk.gray('(all Cursor rules + skills)')
|
|
58
|
+
);
|
|
59
|
+
console.log(
|
|
60
|
+
chalk.blue('🔗 Git:'),
|
|
61
|
+
shareAiConfig
|
|
62
|
+
? chalk.yellow('share-ai-config') + chalk.gray(' (.cursor/skills + .cursor/rules versionáveis)')
|
|
63
|
+
: chalk.gray('local .cursor/ gitignored (default)')
|
|
64
|
+
);
|
|
65
|
+
console.log('');
|
|
24
66
|
|
|
25
67
|
const spinner = ora('Processing...').start();
|
|
26
68
|
|
|
@@ -45,8 +87,11 @@ async function installInProject(targetPath, options = {}) {
|
|
|
45
87
|
|
|
46
88
|
const dirs = [
|
|
47
89
|
'.cursor/rules',
|
|
90
|
+
'.cursor/skills',
|
|
48
91
|
'.claude',
|
|
49
|
-
'.
|
|
92
|
+
'.claude/skills',
|
|
93
|
+
'.task-flow',
|
|
94
|
+
'.codex'
|
|
50
95
|
];
|
|
51
96
|
|
|
52
97
|
for (const dir of dirs) {
|
|
@@ -55,11 +100,33 @@ async function installInProject(targetPath, options = {}) {
|
|
|
55
100
|
|
|
56
101
|
spinner.text = 'Copying configuration files...';
|
|
57
102
|
|
|
58
|
-
await copyConfigs(targetPath, { update: isUpdate, reset: isReset });
|
|
103
|
+
await copyConfigs(targetPath, { update: isUpdate, reset: isReset, profile });
|
|
59
104
|
|
|
60
105
|
spinner.text = 'Updating .gitignore...';
|
|
61
106
|
|
|
62
|
-
await updateGitignore(targetPath);
|
|
107
|
+
await updateGitignore(targetPath, { shareAiConfig });
|
|
108
|
+
showSuccess('.gitignore updated');
|
|
109
|
+
if (shareAiConfig) {
|
|
110
|
+
showInfo('Git: .cursor/skills/ and .cursor/rules/ can be committed (see .gitignore comment)');
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
spinner.text = 'Installing agent skills...';
|
|
114
|
+
await copySkillsToProject(targetPath);
|
|
115
|
+
|
|
116
|
+
spinner.text = 'Configuring Cursor (rules + skills)...';
|
|
117
|
+
await setupCursorIntegration(targetPath, { profile });
|
|
118
|
+
|
|
119
|
+
await writeInstallMeta(targetPath, {
|
|
120
|
+
profile,
|
|
121
|
+
packageVersion: PACKAGE_VERSION,
|
|
122
|
+
shareAiConfig,
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
spinner.text = 'Configuring Codex (AGENTS.md + .codex/config.toml)...';
|
|
126
|
+
await setupCodexIntegration(targetPath);
|
|
127
|
+
|
|
128
|
+
spinner.text = 'Configuring Graphify coexistence...';
|
|
129
|
+
await setupGraphifyIntegration(targetPath, { extract: options.graphify === true });
|
|
63
130
|
|
|
64
131
|
spinner.succeed(chalk.green('Installation completed!'));
|
|
65
132
|
|
|
@@ -79,15 +146,18 @@ async function installInProject(targetPath, options = {}) {
|
|
|
79
146
|
async function copyConfigs(targetPath, options = {}) {
|
|
80
147
|
const isUpdate = options.update || false;
|
|
81
148
|
const isReset = options.reset || false;
|
|
149
|
+
const profile = options.profile;
|
|
82
150
|
|
|
83
|
-
const
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
151
|
+
const rulesResult = await copyCursorRules(targetPath, TEMPLATE_DIR, {
|
|
152
|
+
profile,
|
|
153
|
+
update: isUpdate,
|
|
154
|
+
reset: isReset,
|
|
155
|
+
});
|
|
156
|
+
if (rulesResult?.mode === PROFILE_MINIMAL) {
|
|
157
|
+
showSuccess(`Cursor rules (minimal: ${rulesResult.count} files, always-on only)`);
|
|
158
|
+
showInfo('Use @task-flow-* skills for sync, run, audit — omit heavy .mdc rules to save tokens');
|
|
159
|
+
} else if (rulesResult) {
|
|
160
|
+
showSuccess(`Cursor rules (${rulesResult.count} files)`);
|
|
91
161
|
}
|
|
92
162
|
|
|
93
163
|
const cursorSettingsPath = path.join(TEMPLATE_DIR, '.cursor/settings.json');
|
|
@@ -148,6 +218,7 @@ async function copyTaskFlow(targetPath, options = {}) {
|
|
|
148
218
|
path.join(taskFlowDest, 'tasks.input.txt'),
|
|
149
219
|
path.join(taskFlowDest, 'tasks.status.md'),
|
|
150
220
|
path.join(taskFlowDest, 'tasks.flow.md'),
|
|
221
|
+
path.join(taskFlowDest, 'install-meta.json'),
|
|
151
222
|
];
|
|
152
223
|
|
|
153
224
|
await fs.copy(taskFlowSrc, taskFlowDest, {
|
|
@@ -193,41 +264,6 @@ async function copyTaskFlow(targetPath, options = {}) {
|
|
|
193
264
|
}
|
|
194
265
|
}
|
|
195
266
|
|
|
196
|
-
async function updateGitignore(targetPath) {
|
|
197
|
-
const gitignorePath = path.join(targetPath, '.gitignore');
|
|
198
|
-
|
|
199
|
-
if (!fs.existsSync(gitignorePath)) {
|
|
200
|
-
await fs.writeFile(gitignorePath, '');
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
let content = await fs.readFile(gitignorePath, 'utf8');
|
|
204
|
-
|
|
205
|
-
const entries = [
|
|
206
|
-
'.claude/',
|
|
207
|
-
'.cursor/',
|
|
208
|
-
'.task-flow/',
|
|
209
|
-
'CLAUDE.md',
|
|
210
|
-
'AGENTS.md'
|
|
211
|
-
];
|
|
212
|
-
|
|
213
|
-
for (const entry of entries) {
|
|
214
|
-
const regex = new RegExp(`^${entry.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}$`, 'gm');
|
|
215
|
-
content = content.replace(regex, '');
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
content = content.replace(/\n{3,}/g, '\n\n');
|
|
219
|
-
|
|
220
|
-
if (!content.endsWith('\n')) {
|
|
221
|
-
content += '\n';
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
content += '\n' + entries.join('\n') + '\n';
|
|
225
|
-
|
|
226
|
-
await fs.writeFile(gitignorePath, content);
|
|
227
|
-
|
|
228
|
-
showSuccess('.gitignore updated');
|
|
229
|
-
}
|
|
230
|
-
|
|
231
267
|
async function showModelVersions(targetPath) {
|
|
232
268
|
console.log(chalk.cyan('═'.repeat(60)));
|
|
233
269
|
console.log(chalk.magenta('📋 Model Versions Configured:'));
|
package/lib/profiles.js
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
const fs = require('fs-extra');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
const PROFILE_STANDARD = 'standard';
|
|
5
|
+
const PROFILE_MINIMAL = 'minimal';
|
|
6
|
+
|
|
7
|
+
const MINIMAL_RULE_FILES = ['task-flow-cursor.mdc', 'rbin-git-policy.mdc'];
|
|
8
|
+
|
|
9
|
+
function normalizeProfile(profile) {
|
|
10
|
+
const value = String(profile || PROFILE_STANDARD).trim().toLowerCase();
|
|
11
|
+
if (value !== PROFILE_STANDARD && value !== PROFILE_MINIMAL) {
|
|
12
|
+
throw new Error(`Invalid profile "${profile}". Use "minimal" or "standard".`);
|
|
13
|
+
}
|
|
14
|
+
return value;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function parseProfileOption(value) {
|
|
18
|
+
return normalizeProfile(value || PROFILE_STANDARD);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
async function readInstallMeta(targetPath) {
|
|
22
|
+
const metaPath = path.join(targetPath, '.task-flow', 'install-meta.json');
|
|
23
|
+
if (!fs.existsSync(metaPath)) {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
try {
|
|
27
|
+
return await fs.readJson(metaPath);
|
|
28
|
+
} catch {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
async function writeInstallMeta(targetPath, { profile, packageVersion, shareAiConfig }) {
|
|
34
|
+
const metaPath = path.join(targetPath, '.task-flow', 'install-meta.json');
|
|
35
|
+
await fs.ensureDir(path.dirname(metaPath));
|
|
36
|
+
const existing = (await readInstallMeta(targetPath)) || {};
|
|
37
|
+
const meta = {
|
|
38
|
+
...existing,
|
|
39
|
+
profile: normalizeProfile(profile),
|
|
40
|
+
packageVersion,
|
|
41
|
+
updatedAt: new Date().toISOString(),
|
|
42
|
+
};
|
|
43
|
+
if (shareAiConfig !== undefined) {
|
|
44
|
+
meta.shareAiConfig = Boolean(shareAiConfig);
|
|
45
|
+
}
|
|
46
|
+
await fs.writeJson(metaPath, meta, { spaces: 2 });
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
async function resolveShareAiConfig(targetPath, options = {}) {
|
|
50
|
+
if (options.shareAiConfig !== undefined) {
|
|
51
|
+
return Boolean(options.shareAiConfig);
|
|
52
|
+
}
|
|
53
|
+
const meta = await readInstallMeta(targetPath);
|
|
54
|
+
if (meta && typeof meta.shareAiConfig === 'boolean') {
|
|
55
|
+
return meta.shareAiConfig;
|
|
56
|
+
}
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
async function resolveProfile(targetPath, options = {}) {
|
|
61
|
+
if (options.profile) {
|
|
62
|
+
return normalizeProfile(options.profile);
|
|
63
|
+
}
|
|
64
|
+
const meta = await readInstallMeta(targetPath);
|
|
65
|
+
if (meta?.profile) {
|
|
66
|
+
return normalizeProfile(meta.profile);
|
|
67
|
+
}
|
|
68
|
+
return PROFILE_STANDARD;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
async function copyCursorRules(targetPath, templateDir, { profile, update, reset }) {
|
|
72
|
+
const src = path.join(templateDir, '.cursor', 'rules');
|
|
73
|
+
const dest = path.join(targetPath, '.cursor', 'rules');
|
|
74
|
+
|
|
75
|
+
if (!fs.existsSync(src)) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if ((update || reset) && fs.existsSync(dest)) {
|
|
80
|
+
await fs.emptyDir(dest);
|
|
81
|
+
}
|
|
82
|
+
await fs.ensureDir(dest);
|
|
83
|
+
|
|
84
|
+
if (profile === PROFILE_MINIMAL) {
|
|
85
|
+
for (const file of MINIMAL_RULE_FILES) {
|
|
86
|
+
const from = path.join(src, file);
|
|
87
|
+
if (fs.existsSync(from)) {
|
|
88
|
+
await fs.copy(from, path.join(dest, file), { overwrite: true });
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return { mode: PROFILE_MINIMAL, count: MINIMAL_RULE_FILES.length };
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
await fs.copy(src, dest, { overwrite: true });
|
|
95
|
+
const count = (await fs.readdir(dest)).filter((name) => name.endsWith('.mdc')).length;
|
|
96
|
+
return { mode: PROFILE_STANDARD, count };
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
module.exports = {
|
|
100
|
+
PROFILE_STANDARD,
|
|
101
|
+
PROFILE_MINIMAL,
|
|
102
|
+
MINIMAL_RULE_FILES,
|
|
103
|
+
normalizeProfile,
|
|
104
|
+
parseProfileOption,
|
|
105
|
+
readInstallMeta,
|
|
106
|
+
writeInstallMeta,
|
|
107
|
+
resolveProfile,
|
|
108
|
+
resolveShareAiConfig,
|
|
109
|
+
copyCursorRules,
|
|
110
|
+
};
|
package/lib/skills.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
const fs = require('fs-extra');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const { showSuccess, showInfo } = require('./utils');
|
|
4
|
+
|
|
5
|
+
const TEMPLATE_DIR = path.join(__dirname, '..');
|
|
6
|
+
const SKILLS_SRC = path.join(TEMPLATE_DIR, '.claude', 'skills');
|
|
7
|
+
|
|
8
|
+
async function copySkillsToProject(targetPath) {
|
|
9
|
+
if (!fs.existsSync(SKILLS_SRC)) {
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const destinations = [
|
|
14
|
+
path.join(targetPath, '.claude', 'skills'),
|
|
15
|
+
path.join(targetPath, '.cursor', 'skills'),
|
|
16
|
+
];
|
|
17
|
+
|
|
18
|
+
for (const dest of destinations) {
|
|
19
|
+
await fs.ensureDir(dest);
|
|
20
|
+
await fs.copy(SKILLS_SRC, dest, { overwrite: true });
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const count = (await fs.readdir(SKILLS_SRC)).filter((name) =>
|
|
24
|
+
fs.statSync(path.join(SKILLS_SRC, name)).isDirectory()
|
|
25
|
+
).length;
|
|
26
|
+
|
|
27
|
+
showSuccess(`Agent skills (${count} skills → .claude/skills/ and .cursor/skills/)`);
|
|
28
|
+
showInfo('Claude Code: restart session if .claude/skills/ was created for the first time');
|
|
29
|
+
showInfo('Claude: /task-flow-run · Cursor: @task-flow-run in Agent (or task-flow: run next X)');
|
|
30
|
+
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
module.exports = { copySkillsToProject, SKILLS_SRC };
|
package/lib/utils.js
CHANGED
|
@@ -36,14 +36,49 @@ function showInfo(message) {
|
|
|
36
36
|
console.log(chalk.blue('ℹ️ ' + message));
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
+
function measureAlwaysOnRules(targetPath) {
|
|
40
|
+
const rulesDir = path.join(targetPath, '.cursor', 'rules');
|
|
41
|
+
if (!fs.existsSync(rulesDir)) return null;
|
|
42
|
+
|
|
43
|
+
let totalBytes = 0;
|
|
44
|
+
const files = fs.readdirSync(rulesDir).filter((name) => name.endsWith('.mdc'));
|
|
45
|
+
|
|
46
|
+
for (const name of files) {
|
|
47
|
+
const filePath = path.join(rulesDir, name);
|
|
48
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
49
|
+
if (/alwaysApply:\s*true\b/.test(content)) {
|
|
50
|
+
totalBytes += Buffer.byteLength(content, 'utf8');
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (totalBytes === 0) return null;
|
|
55
|
+
return {
|
|
56
|
+
bytes: totalBytes,
|
|
57
|
+
kb: totalBytes / 1024,
|
|
58
|
+
approxTokens: Math.round(totalBytes / 4),
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
39
62
|
function showNextSteps(targetPath) {
|
|
63
|
+
const alwaysOn = measureAlwaysOnRules(targetPath);
|
|
64
|
+
|
|
40
65
|
console.log('\n' + chalk.cyan('═'.repeat(60)));
|
|
41
66
|
console.log(chalk.magenta.bold(' Next Steps:'));
|
|
42
67
|
console.log(chalk.cyan('═'.repeat(60)));
|
|
68
|
+
if (alwaysOn) {
|
|
69
|
+
const kbLabel = alwaysOn.kb < 10 ? alwaysOn.kb.toFixed(1) : String(Math.round(alwaysOn.kb));
|
|
70
|
+
console.log(
|
|
71
|
+
chalk.gray(' Always-on rules:'),
|
|
72
|
+
chalk.yellow(`~${kbLabel} KB`),
|
|
73
|
+
chalk.gray(`(~${alwaysOn.approxTokens.toLocaleString('en-US')} tokens est.)`)
|
|
74
|
+
);
|
|
75
|
+
}
|
|
43
76
|
console.log(chalk.blue(' 1.'), 'Edit', chalk.yellow('.task-flow/tasks.input.txt'));
|
|
44
|
-
console.log(chalk.blue(' 2.'), '
|
|
45
|
-
console.log(chalk.blue(' 3.'), '
|
|
77
|
+
console.log(chalk.blue(' 2.'), 'Sync:', chalk.cyan('task-flow: sync'), chalk.gray('· Cursor/Claude: @task-flow-sync or /task-flow-sync'));
|
|
78
|
+
console.log(chalk.blue(' 3.'), 'Run:', chalk.cyan('task-flow: run next X'), chalk.gray('· @task-flow-run'));
|
|
46
79
|
console.log(chalk.blue(' 4.'), 'Check status:', chalk.cyan('task-flow: status'));
|
|
80
|
+
console.log(chalk.blue(' 5.'), 'Codex:', chalk.gray('AGENTS.md + .task-flow/CODEX.md on demand'));
|
|
81
|
+
console.log(chalk.blue(' 6.'), 'Optional Graphify:', chalk.yellow('graphify extract .'), chalk.gray('— .task-flow/GRAPHIFY.md'));
|
|
47
82
|
console.log(chalk.cyan('═'.repeat(60)));
|
|
48
83
|
console.log(chalk.blue('\n See'), chalk.yellow('.task-flow/README.md'), chalk.blue('for all available commands\n'));
|
|
49
84
|
}
|
|
@@ -69,5 +104,6 @@ module.exports = {
|
|
|
69
104
|
showWarning,
|
|
70
105
|
showInfo,
|
|
71
106
|
showNextSteps,
|
|
107
|
+
measureAlwaysOnRules,
|
|
72
108
|
parseTaskIds
|
|
73
109
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rbin-task-flow",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.23.0",
|
|
4
4
|
"description": "AI-powered task management for Claude and Cursor",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
},
|
|
10
10
|
"scripts": {
|
|
11
11
|
"test": "echo \"No tests yet\"",
|
|
12
|
-
"
|
|
12
|
+
"measure:rules": "node scripts/measure-rule-bytes.js",
|
|
13
|
+
"prepublishOnly": "npm run measure:rules && chmod +x bin/cli.js scripts/measure-rule-bytes.js"
|
|
13
14
|
},
|
|
14
15
|
"keywords": [
|
|
15
16
|
"task-flow",
|
|
@@ -32,10 +33,13 @@
|
|
|
32
33
|
"bin/",
|
|
33
34
|
".cursor/",
|
|
34
35
|
".claude/",
|
|
36
|
+
".claude/skills/",
|
|
37
|
+
".cursor/skills/",
|
|
35
38
|
".task-flow/",
|
|
36
39
|
".model-versions.json",
|
|
37
40
|
"CLAUDE.md",
|
|
38
41
|
"AGENTS.md",
|
|
42
|
+
".codex/",
|
|
39
43
|
"lib/"
|
|
40
44
|
],
|
|
41
45
|
"preferGlobal": true,
|