rbin-task-flow 1.19.4 → 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 +86 -10
- package/bin/cli.js +41 -16
- 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 +106 -52
- 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,7 +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
|
|
79
|
+
rbin-task-flow reset # Reinstala o Task Flow do zero
|
|
80
|
+
rbin-task-flow reset --graphify # Reset + graphify extract (CLI Graphify no PATH)
|
|
74
81
|
rbin-task-flow version-check # Verifica atualizações de modelos
|
|
75
82
|
rbin-task-flow info # Mostra informações
|
|
76
83
|
rbin-task-flow check # Roda lint/fix e build quando existirem
|
|
@@ -80,7 +87,21 @@ rbin-task-flow report <ids> # Gera relatório (ex: "1" ou "1,2" ou "all")
|
|
|
80
87
|
|
|
81
88
|
### Comandos da IA - Por Que Usar?
|
|
82
89
|
|
|
83
|
-
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.
|
|
84
105
|
|
|
85
106
|
| Comando | Por Que Usar | Feature Principal |
|
|
86
107
|
|---------|--------------|-------------------|
|
|
@@ -160,9 +181,10 @@ seu-projeto/
|
|
|
160
181
|
│ │ ├── cursor_rules.mdc
|
|
161
182
|
│ │ ├── self_improve.mdc
|
|
162
183
|
│ │ ├── code_comments.mdc
|
|
163
|
-
│ │ ├──
|
|
164
|
-
│ │ ├── git_control.mdc
|
|
165
|
-
│ │
|
|
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
|
|
166
188
|
│ └── settings.json # Configurações do modelo Cursor
|
|
167
189
|
│
|
|
168
190
|
├── .claude/
|
|
@@ -253,6 +275,11 @@ Para atualizar configurações em um projeto existente:
|
|
|
253
275
|
cd /caminho/para/seu/projeto
|
|
254
276
|
rbin-task-flow update
|
|
255
277
|
|
|
278
|
+
# Para reiniciar o Task Flow do zero, incluindo .task-flow/.internal
|
|
279
|
+
rbin-task-flow reset
|
|
280
|
+
# Com grafo de código (requer graphify no PATH):
|
|
281
|
+
rbin-task-flow reset --graphify
|
|
282
|
+
|
|
256
283
|
# Ou usando método legacy
|
|
257
284
|
~/.rbin-task-flow/install.sh
|
|
258
285
|
# Digite o caminho do projeto
|
|
@@ -295,6 +322,17 @@ rbin-task-flow/
|
|
|
295
322
|
└── README.md # Este arquivo
|
|
296
323
|
```
|
|
297
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
|
+
|
|
298
336
|
## Notas Importantes
|
|
299
337
|
|
|
300
338
|
- ⚠️ Este é um **repositório template** - não use RBIN Task Flow aqui
|
|
@@ -380,6 +418,8 @@ Para problemas ou perguntas:
|
|
|
380
418
|
<a id="english"></a>
|
|
381
419
|
# 🇬🇧 English
|
|
382
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
|
+
|
|
383
423
|
## What Is This Project?
|
|
384
424
|
|
|
385
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.
|
|
@@ -417,7 +457,12 @@ rbin-task-flow init
|
|
|
417
457
|
|
|
418
458
|
```bash
|
|
419
459
|
rbin-task-flow init # Initialize in current project
|
|
420
|
-
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
|
|
464
|
+
rbin-task-flow reset # Reinstall Task Flow from scratch
|
|
465
|
+
rbin-task-flow reset --graphify # Reset + graphify extract (Graphify CLI on PATH)
|
|
421
466
|
rbin-task-flow version-check # Check for model updates
|
|
422
467
|
rbin-task-flow info # Show information
|
|
423
468
|
rbin-task-flow check # Run lint/fix and build when available
|
|
@@ -427,7 +472,21 @@ rbin-task-flow report <ids> # Generate report (e.g., "1" or "1,2" or "all")
|
|
|
427
472
|
|
|
428
473
|
### AI Commands - Why Use Them?
|
|
429
474
|
|
|
430
|
-
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/`.
|
|
431
490
|
|
|
432
491
|
| Command | Why Use It | Key Feature |
|
|
433
492
|
|---------|------------|-------------|
|
|
@@ -507,9 +566,10 @@ your-project/
|
|
|
507
566
|
│ │ ├── cursor_rules.mdc
|
|
508
567
|
│ │ ├── self_improve.mdc
|
|
509
568
|
│ │ ├── code_comments.mdc
|
|
510
|
-
│ │ ├──
|
|
511
|
-
│ │ ├── git_control.mdc
|
|
512
|
-
│ │
|
|
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
|
|
513
573
|
│ └── settings.json # Cursor model settings
|
|
514
574
|
│
|
|
515
575
|
├── .claude/
|
|
@@ -600,6 +660,11 @@ To update configs in an existing project:
|
|
|
600
660
|
cd /path/to/your/project
|
|
601
661
|
rbin-task-flow update
|
|
602
662
|
|
|
663
|
+
# To reset Task Flow from scratch, including .task-flow/.internal
|
|
664
|
+
rbin-task-flow reset
|
|
665
|
+
# With code knowledge graph (requires graphify on PATH):
|
|
666
|
+
rbin-task-flow reset --graphify
|
|
667
|
+
|
|
603
668
|
# Or using legacy method
|
|
604
669
|
~/.rbin-task-flow/install.sh
|
|
605
670
|
# Enter the project path
|
|
@@ -642,6 +707,17 @@ rbin-task-flow/
|
|
|
642
707
|
└── README.md # This file
|
|
643
708
|
```
|
|
644
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
|
+
|
|
645
721
|
## Important Notes
|
|
646
722
|
|
|
647
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,23 +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
|
-
|
|
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
|
+
}
|
|
26
51
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
.option('-p, --path <path>', 'Target directory (default: current directory)')
|
|
31
|
-
.action(async (options) => {
|
|
32
|
-
const targetPath = options.path || process.cwd();
|
|
33
|
-
await installInProject(targetPath, { update: true });
|
|
34
|
-
});
|
|
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 });
|
|
35
55
|
|
|
36
56
|
program
|
|
37
57
|
.command('version-check')
|
|
@@ -90,7 +110,12 @@ program
|
|
|
90
110
|
console.log(chalk.yellow('Repository:'), 'https://github.com/rbinoliveira/rbin-task-flow');
|
|
91
111
|
console.log(chalk.yellow('\nCommands:'));
|
|
92
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)');
|
|
93
116
|
console.log(chalk.cyan(' rbin-task-flow update') + ' - Update configurations');
|
|
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)');
|
|
94
119
|
console.log(chalk.cyan(' rbin-task-flow version-check') + ' - Check for model updates');
|
|
95
120
|
console.log(chalk.cyan(' rbin-task-flow estimate <ids>') + ' - Estimate time (e.g., "1" or "1,2" or "all")');
|
|
96
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
|
+
};
|