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/README.md
CHANGED
|
@@ -33,6 +33,8 @@
|
|
|
33
33
|
<a id="português"></a>
|
|
34
34
|
# 🇧🇷 Português
|
|
35
35
|
|
|
36
|
+
> **v1.23.0** — Menos tokens no Cursor (2 regras always-on, checklist de standards, skills). De **1.22**: `npm install -g rbin-task-flow@1.23` e `rbin-task-flow update`. [CHANGELOG](CHANGELOG.md) · [Publicação](RELEASE-1.23.0.md).
|
|
37
|
+
|
|
36
38
|
## O Que É Este Projeto?
|
|
37
39
|
|
|
38
40
|
RBIN Task Flow é um sistema de gerenciamento de tarefas alimentado por IA que configura automaticamente Claude Code e Cursor IDE em qualquer projeto. Você define tarefas em texto simples e a IA gera subtarefas detalhadas e acionáveis automaticamente.
|
|
@@ -70,8 +72,12 @@ rbin-task-flow init
|
|
|
70
72
|
|
|
71
73
|
```bash
|
|
72
74
|
rbin-task-flow init # Inicializa no projeto atual
|
|
73
|
-
rbin-task-flow
|
|
75
|
+
rbin-task-flow init --profile minimal # Só 2 regras always-on + skills (menos tokens no Cursor)
|
|
76
|
+
rbin-task-flow init --share-ai-config # Versiona .cursor/skills/ e .cursor/rules/ no git (time)
|
|
77
|
+
rbin-task-flow update # Atualiza configurações (mantém profile em install-meta.json)
|
|
78
|
+
rbin-task-flow update --profile standard # Passa a copiar todas as regras .mdc
|
|
74
79
|
rbin-task-flow reset # Reinstala o Task Flow do zero
|
|
80
|
+
rbin-task-flow reset --graphify # Reset + graphify extract (CLI Graphify no PATH)
|
|
75
81
|
rbin-task-flow version-check # Verifica atualizações de modelos
|
|
76
82
|
rbin-task-flow info # Mostra informações
|
|
77
83
|
rbin-task-flow check # Roda lint/fix e build quando existirem
|
|
@@ -81,7 +87,21 @@ rbin-task-flow report <ids> # Gera relatório (ex: "1" ou "1,2" ou "all")
|
|
|
81
87
|
|
|
82
88
|
### Comandos da IA - Por Que Usar?
|
|
83
89
|
|
|
84
|
-
Após inicializar, use estes comandos na IA (Cursor/Claude) para gerenciar tarefas automaticamente
|
|
90
|
+
Após inicializar, use estes comandos na IA (Cursor/Claude/Codex) para gerenciar tarefas automaticamente.
|
|
91
|
+
|
|
92
|
+
**Otimizar por plataforma:** [.task-flow/AI-PLATFORMS.md](.task-flow/AI-PLATFORMS.md) · [Claude](.task-flow/platforms/claude-code.md) · [Cursor](.task-flow/platforms/cursor.md) · [Codex](.task-flow/platforms/codex.md) · [Graphify](.task-flow/GRAPHIFY.md)
|
|
93
|
+
|
|
94
|
+
**Graphify (opcional):** `rbin-task-flow init --graphify` configura coexistência e pode rodar `graphify extract` (CLI via `rbin-install-dev`).
|
|
95
|
+
|
|
96
|
+
**Claude Code / Cursor skills (v1.20+):** `init` copia 14 skills para `.claude/skills/` e `.cursor/skills/` — use `/task-flow-sync`, `/task-flow-run`, etc.
|
|
97
|
+
|
|
98
|
+
**Codex (v1.21+):** `AGENTS.md` com sync/run embutidos, `.task-flow/CODEX.md` sob demanda, `.codex/config.toml` (64 KiB).
|
|
99
|
+
|
|
100
|
+
**Cursor (v1.23+):** `task-flow-cursor.mdc` + `rbin-git-policy.mdc` (2 always-on) + skills — ver `.task-flow/CURSOR.md`.
|
|
101
|
+
|
|
102
|
+
**Perfil minimal:** `init --profile minimal` instala só as 2 regras always-on e as 14 skills; workflows via `@task-flow-*` (sem `task_work`, `coding_standards` glob, etc.). `standard` (padrão) copia todas as regras `.cursor/rules/`.
|
|
103
|
+
|
|
104
|
+
**Compartilhar com o time:** `init --share-ai-config` não ignora `.cursor/skills/` nem `.cursor/rules/` no `.gitignore` (só `.cursor/settings.json` e overrides locais). Padrão: `.cursor/` inteiro ignorado — menos ruído no repo, config local por dev.
|
|
85
105
|
|
|
86
106
|
| Comando | Por Que Usar | Feature Principal |
|
|
87
107
|
|---------|--------------|-------------------|
|
|
@@ -161,9 +181,10 @@ seu-projeto/
|
|
|
161
181
|
│ │ ├── cursor_rules.mdc
|
|
162
182
|
│ │ ├── self_improve.mdc
|
|
163
183
|
│ │ ├── code_comments.mdc
|
|
164
|
-
│ │ ├──
|
|
165
|
-
│ │ ├── git_control.mdc
|
|
166
|
-
│ │
|
|
184
|
+
│ │ ├── rbin-git-policy.mdc # always-on (git + commits)
|
|
185
|
+
│ │ ├── git_control.mdc # legacy pointer
|
|
186
|
+
│ │ ├── commit_practices.mdc # legacy pointer
|
|
187
|
+
│ │ └── task_execution.mdc # command index stub
|
|
167
188
|
│ └── settings.json # Configurações do modelo Cursor
|
|
168
189
|
│
|
|
169
190
|
├── .claude/
|
|
@@ -256,6 +277,8 @@ rbin-task-flow update
|
|
|
256
277
|
|
|
257
278
|
# Para reiniciar o Task Flow do zero, incluindo .task-flow/.internal
|
|
258
279
|
rbin-task-flow reset
|
|
280
|
+
# Com grafo de código (requer graphify no PATH):
|
|
281
|
+
rbin-task-flow reset --graphify
|
|
259
282
|
|
|
260
283
|
# Ou usando método legacy
|
|
261
284
|
~/.rbin-task-flow/install.sh
|
|
@@ -299,6 +322,17 @@ rbin-task-flow/
|
|
|
299
322
|
└── README.md # Este arquivo
|
|
300
323
|
```
|
|
301
324
|
|
|
325
|
+
## Desenvolvimento (template / CI)
|
|
326
|
+
|
|
327
|
+
Regressão de tamanho das regras always-on (meta P0: ≤ ~5 KB):
|
|
328
|
+
|
|
329
|
+
```bash
|
|
330
|
+
npm run measure:rules
|
|
331
|
+
# ou: node scripts/measure-rule-bytes.js --max-kb 5
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
Lista cada `.cursor/rules/*.mdc` (bytes, linhas, `alwaysApply`), soma always-on vs demais e sai com código **1** se always-on exceder o limite (`--max-kb` ou `RBIN_MAX_ALWAYS_ON_KB`).
|
|
335
|
+
|
|
302
336
|
## Notas Importantes
|
|
303
337
|
|
|
304
338
|
- ⚠️ Este é um **repositório template** - não use RBIN Task Flow aqui
|
|
@@ -384,6 +418,8 @@ Para problemas ou perguntas:
|
|
|
384
418
|
<a id="english"></a>
|
|
385
419
|
# 🇬🇧 English
|
|
386
420
|
|
|
421
|
+
> **v1.23.0** — Lower Cursor token use (2 always-on rules, standards checklist, skills). From **1.22**: `npm install -g rbin-task-flow@1.23` then `rbin-task-flow update`. [CHANGELOG](CHANGELOG.md) · [Release guide](RELEASE-1.23.0.md).
|
|
422
|
+
|
|
387
423
|
## What Is This Project?
|
|
388
424
|
|
|
389
425
|
RBIN Task Flow is an AI-powered task management system that automatically configures Claude Code and Cursor IDE in any project. You define tasks in plain text and the AI automatically generates detailed, actionable subtasks.
|
|
@@ -421,8 +457,12 @@ rbin-task-flow init
|
|
|
421
457
|
|
|
422
458
|
```bash
|
|
423
459
|
rbin-task-flow init # Initialize in current project
|
|
424
|
-
rbin-task-flow
|
|
460
|
+
rbin-task-flow init --profile minimal # 2 always-on rules + skills only (lower Cursor token cost)
|
|
461
|
+
rbin-task-flow init --share-ai-config # Commit .cursor/skills and rules with the team
|
|
462
|
+
rbin-task-flow update # Update configs (keeps profile from .task-flow/install-meta.json)
|
|
463
|
+
rbin-task-flow update --profile standard # Install all .cursor/rules/*.mdc
|
|
425
464
|
rbin-task-flow reset # Reinstall Task Flow from scratch
|
|
465
|
+
rbin-task-flow reset --graphify # Reset + graphify extract (Graphify CLI on PATH)
|
|
426
466
|
rbin-task-flow version-check # Check for model updates
|
|
427
467
|
rbin-task-flow info # Show information
|
|
428
468
|
rbin-task-flow check # Run lint/fix and build when available
|
|
@@ -432,7 +472,21 @@ rbin-task-flow report <ids> # Generate report (e.g., "1" or "1,2" or "all")
|
|
|
432
472
|
|
|
433
473
|
### AI Commands - Why Use Them?
|
|
434
474
|
|
|
435
|
-
After initializing, use these commands in your AI (Cursor/Claude) to automatically manage tasks
|
|
475
|
+
After initializing, use these commands in your AI (Cursor/Claude/Codex) to automatically manage tasks.
|
|
476
|
+
|
|
477
|
+
**Per-platform optimization:** [index](.task-flow/AI-PLATFORMS.md) · [Claude](.task-flow/platforms/claude-code.md) · [Cursor](.task-flow/platforms/cursor.md) · [Codex](.task-flow/platforms/codex.md) · [Graphify](.task-flow/GRAPHIFY.md)
|
|
478
|
+
|
|
479
|
+
**Graphify (optional):** `rbin-task-flow init --graphify` — cooperative setup + optional `graphify extract` (CLI from `rbin-install-dev`).
|
|
480
|
+
|
|
481
|
+
**Claude / Cursor skills (v1.20+):** installs 14 skills — use `/task-flow-sync`, `/task-flow-run`, etc.
|
|
482
|
+
|
|
483
|
+
**Codex (v1.21+):** optimized `AGENTS.md`, `.task-flow/CODEX.md`, `.codex/config.toml`.
|
|
484
|
+
|
|
485
|
+
**Cursor (v1.23+):** 2 always-on rules + 14 skills — `@task-flow-sync`, `@task-flow-run`.
|
|
486
|
+
|
|
487
|
+
**Minimal profile:** `init --profile minimal` copies only `task-flow-cursor.mdc` and `rbin-git-policy.mdc` plus skills; use `@task-flow-*` for workflows. `standard` (default) copies all rules under `.cursor/rules/`.
|
|
488
|
+
|
|
489
|
+
**Share with team:** `init --share-ai-config` leaves `.cursor/skills/` and `.cursor/rules/` out of `.gitignore` (see comment block in `.gitignore` for token vs team trade-off). Default ignores all of `.cursor/`.
|
|
436
490
|
|
|
437
491
|
| Command | Why Use It | Key Feature |
|
|
438
492
|
|---------|------------|-------------|
|
|
@@ -512,9 +566,10 @@ your-project/
|
|
|
512
566
|
│ │ ├── cursor_rules.mdc
|
|
513
567
|
│ │ ├── self_improve.mdc
|
|
514
568
|
│ │ ├── code_comments.mdc
|
|
515
|
-
│ │ ├──
|
|
516
|
-
│ │ ├── git_control.mdc
|
|
517
|
-
│ │
|
|
569
|
+
│ │ ├── rbin-git-policy.mdc # always-on (git + commits)
|
|
570
|
+
│ │ ├── git_control.mdc # legacy pointer
|
|
571
|
+
│ │ ├── commit_practices.mdc # legacy pointer
|
|
572
|
+
│ │ └── task_execution.mdc # command index stub
|
|
518
573
|
│ └── settings.json # Cursor model settings
|
|
519
574
|
│
|
|
520
575
|
├── .claude/
|
|
@@ -607,6 +662,8 @@ rbin-task-flow update
|
|
|
607
662
|
|
|
608
663
|
# To reset Task Flow from scratch, including .task-flow/.internal
|
|
609
664
|
rbin-task-flow reset
|
|
665
|
+
# With code knowledge graph (requires graphify on PATH):
|
|
666
|
+
rbin-task-flow reset --graphify
|
|
610
667
|
|
|
611
668
|
# Or using legacy method
|
|
612
669
|
~/.rbin-task-flow/install.sh
|
|
@@ -650,6 +707,17 @@ rbin-task-flow/
|
|
|
650
707
|
└── README.md # This file
|
|
651
708
|
```
|
|
652
709
|
|
|
710
|
+
## Development (template / CI)
|
|
711
|
+
|
|
712
|
+
Always-on rule size regression (P0 target: ≤ ~5 KB):
|
|
713
|
+
|
|
714
|
+
```bash
|
|
715
|
+
npm run measure:rules
|
|
716
|
+
# or: node scripts/measure-rule-bytes.js --max-kb 5
|
|
717
|
+
```
|
|
718
|
+
|
|
719
|
+
Prints each `.cursor/rules/*.mdc` (bytes, lines, `alwaysApply`), totals always-on vs other, exits **1** if always-on exceeds the limit (`--max-kb` or `RBIN_MAX_ALWAYS_ON_KB`).
|
|
720
|
+
|
|
653
721
|
## Important Notes
|
|
654
722
|
|
|
655
723
|
- ⚠️ This is a **template repository** - don't use RBIN Task Flow here
|
package/bin/cli.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
const { program } = require('commander');
|
|
4
4
|
const path = require('path');
|
|
5
5
|
const { installInProject } = require('../lib/install');
|
|
6
|
+
const { parseProfileOption } = require('../lib/profiles');
|
|
6
7
|
const { checkVersionUpdates } = require('../lib/version');
|
|
7
8
|
const { estimateTask } = require('../lib/estimate');
|
|
8
9
|
const { generateReport } = require('../lib/report');
|
|
@@ -15,32 +16,42 @@ program
|
|
|
15
16
|
.description('AI-powered task management for Claude and Cursor')
|
|
16
17
|
.version(require('../package.json').version);
|
|
17
18
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
19
|
+
function addInstallCommand(name, description, extra = {}) {
|
|
20
|
+
program
|
|
21
|
+
.command(name)
|
|
22
|
+
.description(description)
|
|
23
|
+
.option('-p, --path <path>', 'Target directory (default: current directory)')
|
|
24
|
+
.option('-g, --graphify', 'Run graphify extract after install (requires graphify CLI)')
|
|
25
|
+
.option(
|
|
26
|
+
'--profile <profile>',
|
|
27
|
+
'Cursor rules: minimal (2 always-on + skills) or standard (all rules); update without flag keeps .task-flow/install-meta.json'
|
|
28
|
+
)
|
|
29
|
+
.option(
|
|
30
|
+
'--share-ai-config',
|
|
31
|
+
'Do not gitignore .cursor/skills/ or .cursor/rules/ (team can commit shared AI config; see .gitignore comment)'
|
|
32
|
+
)
|
|
33
|
+
.action(async (options) => {
|
|
34
|
+
const targetPath = options.path || process.cwd();
|
|
35
|
+
try {
|
|
36
|
+
const profile =
|
|
37
|
+
options.profile !== undefined ? parseProfileOption(options.profile) : undefined;
|
|
38
|
+
const shareAiConfig = options.shareAiConfig ? true : undefined;
|
|
39
|
+
await installInProject(targetPath, {
|
|
40
|
+
...extra,
|
|
41
|
+
graphify: options.graphify,
|
|
42
|
+
profile,
|
|
43
|
+
shareAiConfig,
|
|
44
|
+
});
|
|
45
|
+
} catch (error) {
|
|
46
|
+
console.error(chalk.red('\n' + error.message + '\n'));
|
|
47
|
+
process.exit(1);
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
}
|
|
35
51
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
.option('-p, --path <path>', 'Target directory (default: current directory)')
|
|
40
|
-
.action(async (options) => {
|
|
41
|
-
const targetPath = options.path || process.cwd();
|
|
42
|
-
await installInProject(targetPath, { reset: true });
|
|
43
|
-
});
|
|
52
|
+
addInstallCommand('init', 'Initialize RBIN Task Flow in current directory');
|
|
53
|
+
addInstallCommand('update', 'Update RBIN Task Flow in current directory', { update: true });
|
|
54
|
+
addInstallCommand('reset', 'Reset RBIN Task Flow in current directory', { reset: true });
|
|
44
55
|
|
|
45
56
|
program
|
|
46
57
|
.command('version-check')
|
|
@@ -99,8 +110,12 @@ program
|
|
|
99
110
|
console.log(chalk.yellow('Repository:'), 'https://github.com/rbinoliveira/rbin-task-flow');
|
|
100
111
|
console.log(chalk.yellow('\nCommands:'));
|
|
101
112
|
console.log(chalk.cyan(' rbin-task-flow init') + ' - Initialize in current directory');
|
|
113
|
+
console.log(chalk.cyan(' rbin-task-flow init --profile minimal') + ' - Low-token install (2 always-on rules + skills)');
|
|
114
|
+
console.log(chalk.cyan(' rbin-task-flow init --share-ai-config') + ' - Version .cursor/skills and rules in git');
|
|
115
|
+
console.log(chalk.cyan(' rbin-task-flow init --graphify') + ' - Init + graphify extract (if CLI installed)');
|
|
102
116
|
console.log(chalk.cyan(' rbin-task-flow update') + ' - Update configurations');
|
|
103
117
|
console.log(chalk.cyan(' rbin-task-flow reset') + ' - Reset task flow files from scratch');
|
|
118
|
+
console.log(chalk.cyan(' rbin-task-flow reset --graphify') + ' - Reset + graphify extract (if CLI installed)');
|
|
104
119
|
console.log(chalk.cyan(' rbin-task-flow version-check') + ' - Check for model updates');
|
|
105
120
|
console.log(chalk.cyan(' rbin-task-flow estimate <ids>') + ' - Estimate time (e.g., "1" or "1,2" or "all")');
|
|
106
121
|
console.log(chalk.cyan(' rbin-task-flow report <ids>') + ' - Generate report (e.g., "1" or "1,2" or "all")');
|
package/lib/codex.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
const fs = require('fs-extra');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const { showSuccess, showInfo, showWarning } = require('./utils');
|
|
4
|
+
|
|
5
|
+
const TEMPLATE_DIR = path.join(__dirname, '..');
|
|
6
|
+
const CODEX_CONFIG_SRC = path.join(TEMPLATE_DIR, '.codex', 'config.toml');
|
|
7
|
+
|
|
8
|
+
async function setupCodexIntegration(targetPath, options = {}) {
|
|
9
|
+
const codexDir = path.join(targetPath, '.codex');
|
|
10
|
+
const configDest = path.join(codexDir, 'config.toml');
|
|
11
|
+
|
|
12
|
+
await fs.ensureDir(codexDir);
|
|
13
|
+
|
|
14
|
+
const force = options.forceCodexConfig === true;
|
|
15
|
+
if (!fs.existsSync(configDest) || force) {
|
|
16
|
+
if (fs.existsSync(CODEX_CONFIG_SRC)) {
|
|
17
|
+
await fs.copy(CODEX_CONFIG_SRC, configDest, { overwrite: force });
|
|
18
|
+
showSuccess('Codex config (.codex/config.toml — project_doc_max_bytes)');
|
|
19
|
+
}
|
|
20
|
+
} else {
|
|
21
|
+
showInfo('Codex config preserved (.codex/config.toml already exists)');
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const codexWorkflows = path.join(targetPath, '.task-flow', 'CODEX.md');
|
|
25
|
+
if (fs.existsSync(codexWorkflows)) {
|
|
26
|
+
showInfo('Codex workflows: .task-flow/CODEX.md (read on demand)');
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
showInfo('Codex entry: AGENTS.md — embedded sync/run + command table');
|
|
30
|
+
showInfo('Verify: codex --ask-for-approval never "Summarize RBIN Task Flow instructions."');
|
|
31
|
+
|
|
32
|
+
const agentsPath = path.join(targetPath, 'AGENTS.md');
|
|
33
|
+
if (fs.existsSync(agentsPath)) {
|
|
34
|
+
const size = fs.statSync(agentsPath).size;
|
|
35
|
+
if (size > 28 * 1024) {
|
|
36
|
+
showWarning(
|
|
37
|
+
`AGENTS.md is ${Math.round(size / 1024)} KiB — may truncate with default 32 KiB; .codex/config.toml raises limit`
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
module.exports = { setupCodexIntegration };
|
package/lib/cursor.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
const fs = require('fs-extra');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const { showSuccess, showInfo } = require('./utils');
|
|
4
|
+
|
|
5
|
+
async function setupCursorIntegration(targetPath, options = {}) {
|
|
6
|
+
const profile = options.profile || 'standard';
|
|
7
|
+
const skillsDir = path.join(targetPath, '.cursor', 'skills');
|
|
8
|
+
const cursorMd = path.join(targetPath, '.task-flow', 'CURSOR.md');
|
|
9
|
+
const coreRule = path.join(targetPath, '.cursor', 'rules', 'task-flow-cursor.mdc');
|
|
10
|
+
|
|
11
|
+
if (fs.existsSync(coreRule)) {
|
|
12
|
+
showSuccess('Cursor bootstrap rule (task-flow-cursor.mdc — always on)');
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
if (fs.existsSync(skillsDir)) {
|
|
16
|
+
const count = (await fs.readdir(skillsDir)).filter((name) =>
|
|
17
|
+
fs.statSync(path.join(skillsDir, name)).isDirectory()
|
|
18
|
+
).length;
|
|
19
|
+
showInfo(`Cursor skills: ${count} in .cursor/skills/ — use @task-flow-run, @task-flow-sync, …`);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (fs.existsSync(cursorMd)) {
|
|
23
|
+
showInfo('Cursor guide: .task-flow/CURSOR.md');
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const gitPolicy = path.join(targetPath, '.cursor', 'rules', 'rbin-git-policy.mdc');
|
|
27
|
+
if (fs.existsSync(gitPolicy)) {
|
|
28
|
+
showSuccess('Git policy (rbin-git-policy.mdc — always on)');
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (profile === 'minimal') {
|
|
32
|
+
showInfo('Minimal profile: 2 always-on rules; workflows via @task-flow-* skills only');
|
|
33
|
+
showInfo('Full rules: rbin-task-flow update --profile standard');
|
|
34
|
+
} else {
|
|
35
|
+
showInfo('Rules: 2 always-on + intelligent/glob rules; prefer @task-flow-* skills for workflows');
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
module.exports = { setupCursorIntegration };
|
package/lib/gitignore.js
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
const fs = require('fs-extra');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
const MARKER_START = '# RBIN Task Flow (rbin-task-flow)';
|
|
5
|
+
const MARKER_END = '# END RBIN Task Flow (rbin-task-flow)';
|
|
6
|
+
|
|
7
|
+
const ENTRIES_DEFAULT = [
|
|
8
|
+
'.claude/',
|
|
9
|
+
'.cursor/',
|
|
10
|
+
'.task-flow/',
|
|
11
|
+
'graphify-out/',
|
|
12
|
+
'CLAUDE.md',
|
|
13
|
+
'AGENTS.md',
|
|
14
|
+
];
|
|
15
|
+
|
|
16
|
+
const ENTRIES_SHARE_AI_CONFIG = [
|
|
17
|
+
'.claude/',
|
|
18
|
+
'.cursor/settings.json',
|
|
19
|
+
'.cursor/rules/*.local.mdc',
|
|
20
|
+
'.task-flow/',
|
|
21
|
+
'graphify-out/',
|
|
22
|
+
'CLAUDE.md',
|
|
23
|
+
'AGENTS.md',
|
|
24
|
+
];
|
|
25
|
+
|
|
26
|
+
const STRIP_PATTERNS = [
|
|
27
|
+
...ENTRIES_DEFAULT,
|
|
28
|
+
...ENTRIES_SHARE_AI_CONFIG,
|
|
29
|
+
MARKER_START,
|
|
30
|
+
MARKER_END,
|
|
31
|
+
'# share-ai-config:',
|
|
32
|
+
'# Trade-off:',
|
|
33
|
+
'# Default (no flag):',
|
|
34
|
+
];
|
|
35
|
+
|
|
36
|
+
function escapeRegExp(value) {
|
|
37
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function stripRbinGitignoreBlock(content) {
|
|
41
|
+
let next = content;
|
|
42
|
+
|
|
43
|
+
const blockRegex = new RegExp(
|
|
44
|
+
`\\n?${escapeRegExp(MARKER_START)}[\\s\\S]*?${escapeRegExp(MARKER_END)}\\n?`,
|
|
45
|
+
'g'
|
|
46
|
+
);
|
|
47
|
+
next = next.replace(blockRegex, '\n');
|
|
48
|
+
|
|
49
|
+
for (const entry of STRIP_PATTERNS) {
|
|
50
|
+
const lineRegex = new RegExp(`^${escapeRegExp(entry)}\\s*$`, 'gm');
|
|
51
|
+
next = next.replace(lineRegex, '');
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return next.replace(/\n{3,}/g, '\n\n');
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function buildRbinGitignoreBlock(shareAiConfig) {
|
|
58
|
+
const lines = ['', MARKER_START, ''];
|
|
59
|
+
|
|
60
|
+
if (shareAiConfig) {
|
|
61
|
+
lines.push(
|
|
62
|
+
'# share-ai-config: .cursor/skills/ and .cursor/rules/ are NOT ignored — commit them for team consistency.',
|
|
63
|
+
'# Trade-off: shared AI config improves workflow parity; each developer still pays token cost when the Agent loads rules/skills.',
|
|
64
|
+
'# Default (no flag): entire .cursor/ stays local and gitignored — lower repo noise, no team sync of rules.',
|
|
65
|
+
''
|
|
66
|
+
);
|
|
67
|
+
lines.push(...ENTRIES_SHARE_AI_CONFIG);
|
|
68
|
+
} else {
|
|
69
|
+
lines.push(...ENTRIES_DEFAULT);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
lines.push(MARKER_END, '');
|
|
73
|
+
return lines.join('\n');
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
async function updateGitignore(targetPath, { shareAiConfig = false } = {}) {
|
|
77
|
+
const gitignorePath = path.join(targetPath, '.gitignore');
|
|
78
|
+
|
|
79
|
+
if (!fs.existsSync(gitignorePath)) {
|
|
80
|
+
await fs.writeFile(gitignorePath, '');
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
let content = await fs.readFile(gitignorePath, 'utf8');
|
|
84
|
+
content = stripRbinGitignoreBlock(content);
|
|
85
|
+
|
|
86
|
+
if (!content.endsWith('\n')) {
|
|
87
|
+
content += '\n';
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
content += buildRbinGitignoreBlock(shareAiConfig);
|
|
91
|
+
await fs.writeFile(gitignorePath, content);
|
|
92
|
+
|
|
93
|
+
return { shareAiConfig };
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
module.exports = {
|
|
97
|
+
MARKER_START,
|
|
98
|
+
buildRbinGitignoreBlock,
|
|
99
|
+
stripRbinGitignoreBlock,
|
|
100
|
+
updateGitignore,
|
|
101
|
+
};
|
package/lib/graphify.js
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
const fs = require('fs-extra');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const { spawnSync } = require('child_process');
|
|
4
|
+
const { showSuccess, showWarning, showInfo } = require('./utils');
|
|
5
|
+
|
|
6
|
+
const GRAPHIFY_OUT = 'graphify-out/';
|
|
7
|
+
const UPSTREAM_GRAPHIFY_RULE = 'graphify.mdc';
|
|
8
|
+
|
|
9
|
+
function graphifyCliAvailable() {
|
|
10
|
+
const result = spawnSync('graphify', ['--help'], {
|
|
11
|
+
encoding: 'utf8',
|
|
12
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
13
|
+
});
|
|
14
|
+
return result.status === 0 || result.status === 1;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function demoteUpstreamGraphifyRule(targetPath) {
|
|
18
|
+
const rulePath = path.join(targetPath, '.cursor', 'rules', UPSTREAM_GRAPHIFY_RULE);
|
|
19
|
+
if (!fs.existsSync(rulePath)) {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
let content = fs.readFileSync(rulePath, 'utf8');
|
|
24
|
+
const hadAlwaysApply = /alwaysApply:\s*true/i.test(content);
|
|
25
|
+
|
|
26
|
+
if (!hadAlwaysApply) {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
content = content.replace(/alwaysApply:\s*true/gi, 'alwaysApply: false');
|
|
31
|
+
|
|
32
|
+
if (!content.includes('RBIN Task Flow')) {
|
|
33
|
+
const notice = [
|
|
34
|
+
'',
|
|
35
|
+
'- **RBIN Task Flow:** This file was set to `alwaysApply: false` by `rbin-task-flow` to avoid competing with Task Flow rules. Use [.cursor/rules/graphify-task-flow.mdc](mdc:.cursor/rules/graphify-task-flow.mdc) and [.task-flow/GRAPHIFY.md](mdc:.task-flow/GRAPHIFY.md) instead.',
|
|
36
|
+
'',
|
|
37
|
+
].join('\n');
|
|
38
|
+
content = content.trimEnd() + notice;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
fs.writeFileSync(rulePath, content);
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function ensureGraphifyGitignore(targetPath) {
|
|
46
|
+
const gitignorePath = path.join(targetPath, '.gitignore');
|
|
47
|
+
if (!fs.existsSync(gitignorePath)) {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
let content = fs.readFileSync(gitignorePath, 'utf8');
|
|
52
|
+
const entry = GRAPHIFY_OUT.replace(/\/$/, '');
|
|
53
|
+
const linePattern = new RegExp(`^${entry}\\/?$`, 'm');
|
|
54
|
+
|
|
55
|
+
if (linePattern.test(content)) {
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (!content.endsWith('\n')) {
|
|
60
|
+
content += '\n';
|
|
61
|
+
}
|
|
62
|
+
content += `\n${entry}/\n`;
|
|
63
|
+
fs.writeFileSync(gitignorePath, content);
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function runGraphifyExtract(targetPath) {
|
|
68
|
+
if (!graphifyCliAvailable()) {
|
|
69
|
+
showWarning('Graphify CLI not found — skip extract (install via rbin-install-dev Graphify module)');
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
showInfo('Running graphify extract (may take a few minutes)...');
|
|
74
|
+
const result = spawnSync('graphify', ['extract', '.'], {
|
|
75
|
+
cwd: targetPath,
|
|
76
|
+
encoding: 'utf8',
|
|
77
|
+
stdio: 'inherit',
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
if (result.status !== 0) {
|
|
81
|
+
showWarning('graphify extract failed — you can run it later: graphify extract .');
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
showSuccess('Graphify knowledge graph (graphify-out/)');
|
|
86
|
+
return true;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
async function setupGraphifyIntegration(targetPath, options = {}) {
|
|
90
|
+
const demoted = demoteUpstreamGraphifyRule(targetPath);
|
|
91
|
+
if (demoted) {
|
|
92
|
+
showSuccess('Graphify upstream rule demoted (alwaysApply: false) — Task Flow keeps priority');
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const gitignoreUpdated = ensureGraphifyGitignore(targetPath);
|
|
96
|
+
if (gitignoreUpdated) {
|
|
97
|
+
showSuccess('graphify-out/ added to .gitignore');
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (options.extract) {
|
|
101
|
+
runGraphifyExtract(targetPath);
|
|
102
|
+
} else if (graphifyCliAvailable()) {
|
|
103
|
+
const graphJson = path.join(targetPath, 'graphify-out', 'graph.json');
|
|
104
|
+
if (!fs.existsSync(graphJson)) {
|
|
105
|
+
showInfo('Graphify CLI detected — run: graphify extract . (or: rbin-task-flow init --graphify)');
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
showInfo('Graphify + Task Flow guide: .task-flow/GRAPHIFY.md');
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
module.exports = {
|
|
113
|
+
setupGraphifyIntegration,
|
|
114
|
+
demoteUpstreamGraphifyRule,
|
|
115
|
+
ensureGraphifyGitignore,
|
|
116
|
+
runGraphifyExtract,
|
|
117
|
+
graphifyCliAvailable,
|
|
118
|
+
};
|