rbin-task-flow 1.25.0 → 1.26.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 +4 -3
- package/.claude/skills/rbin-coding-standards/reference.md +2 -0
- package/.claude/skills/task-flow-estimate/SKILL.md +8 -5
- package/.claude/skills/task-flow-from-contexts/SKILL.md +16 -0
- package/.claude/skills/task-flow-run/SKILL.md +1 -1
- package/.claude/skills/task-flow-sync/SKILL.md +0 -1
- package/.claude/skills/task-flow-sync/workflow.md +1 -1
- package/.claude/skills/task-flow-validate/SKILL.md +2 -2
- package/.cursor/rules/coding_standards.mdc +13 -0
- package/.cursor/rules/graphify-task-flow.mdc +7 -8
- package/.cursor/rules/task-flow-cursor.mdc +3 -8
- package/.cursor/rules/task-flow-sync.mdc +1 -1
- package/.cursor/rules/task_execution.mdc +2 -7
- package/.cursor/rules/task_from_contexts.mdc +93 -0
- package/.cursor/rules/task_validate.mdc +1 -7
- package/.cursor/rules/task_work.mdc +1 -1
- package/.task-flow/README.md +72 -55
- package/.task-flow/guides/AI-PLATFORMS.md +6 -7
- package/.task-flow/guides/CODEX.md +16 -63
- package/.task-flow/guides/CURSOR.md +4 -5
- package/.task-flow/guides/GRAPHIFY.md +12 -13
- package/.task-flow/guides/coding-standards-full.md +145 -0
- package/.task-flow/guides/platforms/claude-code.md +13 -23
- package/.task-flow/guides/platforms/codex.md +9 -22
- package/.task-flow/guides/platforms/cursor.md +14 -35
- package/.task-flow/tasks.input.txt +3 -4
- package/AGENTS.md +3 -13
- package/CLAUDE.md +3 -8
- package/README.md +16 -24
- package/bin/cli.js +3 -24
- package/lib/gitignore.js +0 -2
- package/lib/graphify.js +50 -18
- package/lib/install.js +1 -14
- package/package.json +1 -2
- package/.claude/skills/task-flow-check/SKILL.md +0 -15
- package/.claude/skills/task-flow-generate-flow/SKILL.md +0 -15
- package/.claude/skills/task-flow-improve-changes/SKILL.md +0 -15
- package/.claude/skills/task-flow-refactor/SKILL.md +0 -14
- package/.claude/skills/task-flow-review/SKILL.md +0 -14
- package/.claude/skills/task-flow-think/SKILL.md +0 -19
- package/.cursor/rules/task_analysis.mdc +0 -45
- package/.cursor/rules/task_check.mdc +0 -37
- package/.cursor/rules/task_generate_flow.mdc +0 -90
- package/.cursor/rules/task_improve_changes.mdc +0 -50
- package/.cursor/rules/task_refactor.mdc +0 -94
- package/.cursor/rules/task_review.mdc +0 -88
- package/lib/audit.js +0 -44
- package/lib/check.js +0 -113
|
@@ -13,9 +13,19 @@ Codex loads **AGENTS.md** at session start (32 KiB default cap). This file holds
|
|
|
13
13
|
3. New tasks: generate 3–8 subtasks, `createdAt` ISO, contexts from `.task-flow/contexts/`.
|
|
14
14
|
4. Write/update `tasks.json`, `status.json`, `tasks.status.md` with Summary.
|
|
15
15
|
5. Preserve status on modified tasks when subtasks still align.
|
|
16
|
-
6. Do not populate `tasks.flow.md`.
|
|
17
16
|
|
|
18
|
-
Sync: `.cursor/rules/task-flow-sync.mdc`
|
|
17
|
+
Sync: `.cursor/rules/task-flow-sync.mdc`
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## task-flow: from contexts
|
|
22
|
+
|
|
23
|
+
1. List `.task-flow/contexts/` (or specific `file.png`, `a.md,b.png`).
|
|
24
|
+
2. Read each file; skip already linked via `task-flow-screen` in `tasks.input.txt`.
|
|
25
|
+
3. Append `- Description task-flow-screen filename.ext` under `## Tasks:`.
|
|
26
|
+
4. Report added/skipped; suggest `task-flow: sync` — do not sync here.
|
|
27
|
+
|
|
28
|
+
Rule: `.cursor/rules/task_from_contexts.mdc`
|
|
19
29
|
|
|
20
30
|
---
|
|
21
31
|
|
|
@@ -37,26 +47,6 @@ Display `.task-flow/tasks.status.md`. If missing, run sync first.
|
|
|
37
47
|
|
|
38
48
|
---
|
|
39
49
|
|
|
40
|
-
## task-flow: think
|
|
41
|
-
|
|
42
|
-
1. Read `tasks.input.txt`.
|
|
43
|
-
2. Scan repo for TODOs, gaps, tests, incomplete features.
|
|
44
|
-
3. Propose new `- task` lines.
|
|
45
|
-
4. **Ask** before appending to `tasks.input.txt`.
|
|
46
|
-
5. If confirmed, append and suggest `task-flow: sync`.
|
|
47
|
-
|
|
48
|
-
---
|
|
49
|
-
|
|
50
|
-
## task-flow: check
|
|
51
|
-
|
|
52
|
-
1. `package.json` scripts: lint fix variant, then `build`.
|
|
53
|
-
2. Fix until pass.
|
|
54
|
-
3. Does not edit task files.
|
|
55
|
-
|
|
56
|
-
Rule: `.cursor/rules/task_check.mdc`
|
|
57
|
-
|
|
58
|
-
---
|
|
59
|
-
|
|
60
50
|
## task-flow: audit
|
|
61
51
|
|
|
62
52
|
1. Score project vs the checklist in `.cursor/rules/coding_standards.mdc` (not the full doc unless user wants depth).
|
|
@@ -67,27 +57,6 @@ Rule: `.cursor/rules/task_audit.mdc`
|
|
|
67
57
|
|
|
68
58
|
---
|
|
69
59
|
|
|
70
|
-
## task-flow: improve changes
|
|
71
|
-
|
|
72
|
-
1. `git diff --name-only HEAD` (read-only).
|
|
73
|
-
2. If empty, stop.
|
|
74
|
-
3. Audit only those paths vs coding standards.
|
|
75
|
-
4. Ask before edits.
|
|
76
|
-
|
|
77
|
-
Rule: `.cursor/rules/task_improve_changes.mdc`
|
|
78
|
-
|
|
79
|
-
---
|
|
80
|
-
|
|
81
|
-
## task-flow: review X
|
|
82
|
-
|
|
83
|
-
1. Load done subtasks for task X from `status.json`.
|
|
84
|
-
2. Verify implementation in codebase.
|
|
85
|
-
3. Report false positives; ask to revert status if needed.
|
|
86
|
-
|
|
87
|
-
Rule: `.cursor/rules/task_review.mdc`
|
|
88
|
-
|
|
89
|
-
---
|
|
90
|
-
|
|
91
60
|
## task-flow: validate
|
|
92
61
|
|
|
93
62
|
1. Read `tasks.input.txt`, `tasks.json`, `status.json` — scope `all` or task ID(s).
|
|
@@ -98,21 +67,13 @@ Rule: `.cursor/rules/task_review.mdc`
|
|
|
98
67
|
|
|
99
68
|
Rule: `.cursor/rules/task_validate.mdc`
|
|
100
69
|
|
|
101
|
-
Unlike `think` (asks before add) or `review` (done only, asks before revert).
|
|
102
|
-
|
|
103
|
-
---
|
|
104
|
-
|
|
105
|
-
## task-flow: refactor X
|
|
106
|
-
|
|
107
|
-
Refactor task-related files: no behavior change, remove explanatory comments, keep section separators.
|
|
108
|
-
|
|
109
|
-
Rule: `.cursor/rules/task_refactor.mdc`
|
|
110
|
-
|
|
111
70
|
---
|
|
112
71
|
|
|
113
72
|
## task-flow: estimate X
|
|
114
73
|
|
|
115
|
-
|
|
74
|
+
1. Parse: `estimate X` | `estimate X,Y` | `estimate all`.
|
|
75
|
+
2. Read `tasks.json` for matching task ID(s).
|
|
76
|
+
3. One hour range per task; average developer, average pace, no AI acceleration.
|
|
116
77
|
|
|
117
78
|
Rule: `.cursor/rules/task_estimate.mdc`
|
|
118
79
|
|
|
@@ -126,14 +87,6 @@ Rule: `.cursor/rules/task_report.mdc`
|
|
|
126
87
|
|
|
127
88
|
---
|
|
128
89
|
|
|
129
|
-
## task-flow: generate flow
|
|
130
|
-
|
|
131
|
-
Populate `.task-flow/tasks.flow.md` with deps, hours, model hints (no Opus).
|
|
132
|
-
|
|
133
|
-
Rule: `.cursor/rules/task_generate_flow.mdc`
|
|
134
|
-
|
|
135
|
-
---
|
|
136
|
-
|
|
137
90
|
## Implementing code (any subtask)
|
|
138
91
|
|
|
139
92
|
Follow the checklist in `.cursor/rules/coding_standards.mdc`. For examples/Nest: read sections of `.task-flow/guides/coding-standards-full.md` only.
|
|
@@ -142,7 +95,7 @@ Follow the checklist in `.cursor/rules/coding_standards.mdc`. For examples/Nest:
|
|
|
142
95
|
|
|
143
96
|
## Graphify (optional)
|
|
144
97
|
|
|
145
|
-
Only during `run` / `
|
|
98
|
+
Only during `run` / `validate` when `.task-flow/guides/graphify-out/` exists. See `.task-flow/guides/GRAPHIFY.md`. Does not replace status updates.
|
|
146
99
|
|
|
147
100
|
---
|
|
148
101
|
|
|
@@ -21,11 +21,10 @@ Verify: `rg 'alwaysApply: true' .cursor/rules` → only the two files above.
|
|
|
21
21
|
|
|
22
22
|
| Say in Agent / Chat | Best invoke |
|
|
23
23
|
|---------------------|-------------|
|
|
24
|
+
| `task-flow: from contexts` | `@task-flow-from-contexts` |
|
|
24
25
|
| `task-flow: sync` | `@task-flow-sync` |
|
|
25
26
|
| `task-flow: run next 4` | `@task-flow-run` |
|
|
26
27
|
| `task-flow: status` | `@task-flow-status` |
|
|
27
|
-
| `task-flow: check` | `@task-flow-check` |
|
|
28
|
-
| `task-flow: improve changes` | `@task-flow-improve-changes` |
|
|
29
28
|
| `task-flow: validate` | `@task-flow-validate` |
|
|
30
29
|
| Implement feature code | `@rbin-coding-standards` (explicit; checklist glob on `src/**`) |
|
|
31
30
|
|
|
@@ -39,7 +38,7 @@ Verify: `rg 'alwaysApply: true' .cursor/rules` → only the two files above.
|
|
|
39
38
|
|-------|----------|-------------|
|
|
40
39
|
| **Always** | `task-flow-cursor`, `rbin-git-policy` | Every chat (~0,9k tokens) |
|
|
41
40
|
| **Skills** | `@task-flow-run`, `@task-flow-sync`, … | You invoke (recommended for run/sync/audit) |
|
|
42
|
-
| **Intelligent** | `task_work`, `task_audit`, `
|
|
41
|
+
| **Intelligent** | `task_work`, `task_audit`, `task_validate`, … | Agent matches `description` |
|
|
43
42
|
| **Glob** | `task-flow-sync`, `task_generation` (`.task-flow/**`), `coding_standards` (`src/**`, `app/**`), `code_comments` | Matching paths in chat |
|
|
44
43
|
| **Manual** | `@cursor_rules`, `@self_improve`, `@task_report`, legacy `git_control` | You `@`-mention only (no `description` auto-match) |
|
|
45
44
|
|
|
@@ -54,7 +53,7 @@ If a command fails to trigger, use **`@task-flow-*`** explicitly.
|
|
|
54
53
|
| Surface | Best for |
|
|
55
54
|
|---------|----------|
|
|
56
55
|
| **Agent** (Composer) | `@task-flow-run`, multi-file implementation |
|
|
57
|
-
| **Chat** | `sync`, `status`, `
|
|
56
|
+
| **Chat** | `sync`, `status`, `estimate` |
|
|
58
57
|
| **@ files** | `@tasks.input.txt`, `@.task-flow/contexts/mockup.png` |
|
|
59
58
|
|
|
60
59
|
---
|
|
@@ -70,7 +69,7 @@ After each subtask:
|
|
|
70
69
|
|
|
71
70
|
## Graphify
|
|
72
71
|
|
|
73
|
-
Only during `run` / `
|
|
72
|
+
Only during `run` / `validate` when `.task-flow/guides/graphify-out/` exists. Does not replace Task Flow status. See [GRAPHIFY.md](GRAPHIFY.md).
|
|
74
73
|
|
|
75
74
|
---
|
|
76
75
|
|
|
@@ -9,7 +9,7 @@ Graphify ([graphifyy](https://pypi.org/project/graphifyyy/)) cria um **grafo de
|
|
|
9
9
|
## Token discipline
|
|
10
10
|
|
|
11
11
|
- Use **summarized** `graphify query` output (symbols, paths, short lists) — not full graph dumps in chat.
|
|
12
|
-
- **Do not paste**
|
|
12
|
+
- **Do not paste** `.task-flow/guides/graphify-out/GRAPH_REPORT.md` (or entire report files) into the model context unless the user **explicitly** `@`-mentions that file.
|
|
13
13
|
- Prefer one targeted query per subtask over loading `graph.json` or large exports.
|
|
14
14
|
- Task Flow status files (`.task-flow/`) always win over Graphify for workflow and git.
|
|
15
15
|
|
|
@@ -20,7 +20,7 @@ Graphify ([graphifyy](https://pypi.org/project/graphifyyy/)) cria um **grafo de
|
|
|
20
20
|
| | Task Flow | Graphify |
|
|
21
21
|
|---|-----------|----------|
|
|
22
22
|
| **Pergunta** | O que fazer agora? | Onde está X no código? |
|
|
23
|
-
| **Dados** | `.task-flow/` |
|
|
23
|
+
| **Dados** | `.task-flow/` | `.task-flow/guides/graphify-out/` |
|
|
24
24
|
| **Comandos** | `task-flow: sync`, `run`, `status`, … | `graphify extract`, `query`, `affected` |
|
|
25
25
|
| **Regra Cursor** | Várias `.mdc` (workflow) | `graphify-task-flow.mdc` (**sob demanda**) |
|
|
26
26
|
|
|
@@ -29,9 +29,9 @@ Graphify ([graphifyy](https://pypi.org/project/graphifyyy/)) cria um **grafo de
|
|
|
29
29
|
## O que o `rbin-task-flow init` já faz por você
|
|
30
30
|
|
|
31
31
|
1. Copia **`.cursor/rules/graphify-task-flow.mdc`** — `alwaysApply: false` (não compete com `task_work`, etc.).
|
|
32
|
-
2.
|
|
32
|
+
2. Grafo em **`.task-flow/guides/graphify-out/`** (já coberto pelo `.task-flow/` no `.gitignore`; remove entrada legada `graphify-out/` na raiz).
|
|
33
33
|
3. Se existir **`.cursor/rules/graphify.mdc`** do `graphify cursor install` (upstream com `alwaysApply: true`), o instalador **desativa** `alwaysApply` para economizar contexto.
|
|
34
|
-
4. Com **`--graphify`** em `init`, `update` ou **`reset`**, roda `graphify extract . --backend claude-cli` se o CLI estiver no PATH (usa assinatura Claude Code — sem API key separada).
|
|
34
|
+
4. Com **`--graphify`** em `init`, `update` ou **`reset`**, roda `graphify extract . --backend claude-cli --out .task-flow/guides` se o CLI estiver no PATH (usa assinatura Claude Code — sem API key separada).
|
|
35
35
|
|
|
36
36
|
**Não** rodamos `graphify claude install` / `graphify cursor install` automaticamente — o install upstream força `graphify.mdc` always-on e incham `CLAUDE.md` / `AGENTS.md`.
|
|
37
37
|
|
|
@@ -44,7 +44,6 @@ cd seu-projeto
|
|
|
44
44
|
rbin-task-flow reset --graphify # ou init/update --graphify; recria .task-flow + grafo
|
|
45
45
|
task-flow: sync
|
|
46
46
|
task-flow: run next 3 # IA usa grafo só ao implementar
|
|
47
|
-
task-flow: check
|
|
48
47
|
# você: git commit
|
|
49
48
|
```
|
|
50
49
|
|
|
@@ -52,16 +51,16 @@ task-flow: check
|
|
|
52
51
|
|
|
53
52
|
| Comando Task Flow | Usar Graphify? |
|
|
54
53
|
|-------------------|----------------|
|
|
55
|
-
| `sync`, `status`, `estimate`, `report
|
|
56
|
-
| `run next X`, `run N` | Sim, se
|
|
57
|
-
| `
|
|
58
|
-
| `audit
|
|
54
|
+
| `sync`, `status`, `estimate`, `report` | Não |
|
|
55
|
+
| `run next X`, `run N` | Sim, se `.task-flow/guides/graphify-out/` existir |
|
|
56
|
+
| `validate` | Opcional |
|
|
57
|
+
| `audit` | Opcional (estrutura); padrões = checklist `coding_standards.mdc` |
|
|
59
58
|
| `check` | Não |
|
|
60
59
|
|
|
61
60
|
**Prompt exemplo:**
|
|
62
61
|
|
|
63
62
|
```text
|
|
64
|
-
task-flow: run next 2 — se graphify-out existir, graphify query "<módulo
|
|
63
|
+
task-flow: run next 2 — se .task-flow/guides/graphify-out/ existir, graphify query "<módulo>" --graph .task-flow/guides/graphify-out/graph.json antes de editar.
|
|
65
64
|
```
|
|
66
65
|
|
|
67
66
|
---
|
|
@@ -87,9 +86,9 @@ task-flow: run next 2 — se graphify-out existir, graphify query "<módulo da s
|
|
|
87
86
|
|
|
88
87
|
| Evento | Ação |
|
|
89
88
|
|--------|------|
|
|
90
|
-
| Primeiro setup | `rbin-task-flow init --graphify` ou `graphify extract . --backend claude-cli` |
|
|
89
|
+
| Primeiro setup | `rbin-task-flow init --graphify` ou `graphify extract . --backend claude-cli --out .task-flow/guides` |
|
|
91
90
|
| Reset completo (tasks + template + grafo) | `rbin-task-flow reset --graphify` |
|
|
92
|
-
| Refactor grande após vários `run` | `graphify update .` ou `graphify extract . --backend claude-cli` |
|
|
91
|
+
| Refactor grande após vários `run` | `graphify update .` ou `graphify extract . --backend claude-cli --out .task-flow/guides` |
|
|
93
92
|
| `task-flow: update` | Reaplica `graphify-task-flow.mdc` e pode rebaixar `graphify.mdc` |
|
|
94
93
|
|
|
95
94
|
---
|
|
@@ -102,7 +101,7 @@ task-flow: run next 2 — se graphify-out existir, graphify query "<módulo da s
|
|
|
102
101
|
| Contexto cheio no Cursor | Confirme `graphify.mdc` não está `alwaysApply: true` |
|
|
103
102
|
| `graphify: command not found` | Rode `rbin-install-dev` (módulo Graphify) |
|
|
104
103
|
| `no LLM API key found` ao rodar `graphify extract .` manual | Use `rbin-task-flow init --graphify` (roda `--backend claude-cli`) ou exporte uma API key / `--backend ollama` |
|
|
105
|
-
| Grafo desatualizado | `graphify extract . --backend claude-cli` de novo |
|
|
104
|
+
| Grafo desatualizado | `graphify extract . --backend claude-cli --out .task-flow/guides` de novo |
|
|
106
105
|
|
|
107
106
|
---
|
|
108
107
|
|
|
@@ -8,6 +8,151 @@ These rules define how code MUST be written when implementing tasks. Always foll
|
|
|
8
8
|
|
|
9
9
|
---
|
|
10
10
|
|
|
11
|
+
## Vercel — environment variables
|
|
12
|
+
|
|
13
|
+
**When the project deploys on Vercel** (Next.js, etc.), follow this section for `.env` files.
|
|
14
|
+
|
|
15
|
+
### Instruções para a IA (executar nesta ordem)
|
|
16
|
+
|
|
17
|
+
1. **Antes de tudo — auditar variáveis sem uso** [§0]: para cada variável dos `.env*`, verifique se ela é realmente referenciada no código/configuração. **Liste as órfãs e confirme com o usuário antes de remover** — não apague sozinha (algumas são usadas só em runtime/CI/infra). Só depois de limpar é que se alinham os 3 arquivos.
|
|
18
|
+
2. Crie `scripts/env-files-check.sh` e `scripts/vercel-env-sync.sh` com **exatamente** o conteúdo das seções [§5] e [§6]. Marque ambos como executáveis (`chmod +x`).
|
|
19
|
+
3. Garanta os **3 arquivos de ambiente** seguindo a convenção [§1]: mesma sequência de chaves nos 3, **ordem alfabética**, uma variável por linha, sem comentários de seção no meio. Crie `.env.example` (commitado, valores vazios). **Nunca** coloque valores reais no `.env.example`.
|
|
20
|
+
4. Ajuste o `.gitignore` conforme [§2].
|
|
21
|
+
5. Ajuste a `PLAINTEXT_REGEX` do `vercel-env-sync.sh` ao stack do projeto [§3].
|
|
22
|
+
6. Rode `./scripts/env-files-check.sh` e mostre a saída. Não rode o sync da Vercel sem credenciais do usuário — explique os comandos de [§4].
|
|
23
|
+
7. Confirme os **critérios de aceite** [§7].
|
|
24
|
+
|
|
25
|
+
### §0 — Auditoria (variáveis sem uso)
|
|
26
|
+
|
|
27
|
+
Para cada chave dos `.env*`, procure referências: `process.env.NOME`, `import.meta.env.NOME`, `env("NOME")`, configs/CI (`vercel.json`, `*.yml`, `Dockerfile`).
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
for k in $(grep -hE '^[A-Za-z_][A-Za-z0-9_]*=' .env.example .env.local .env.production 2>/dev/null \
|
|
31
|
+
| sed -E 's/=.*//' | sort -u); do
|
|
32
|
+
n=$(grep -rIn --exclude-dir=node_modules --exclude-dir=.git --exclude='.env*' \
|
|
33
|
+
-e "$k" . 2>/dev/null | wc -l | tr -d ' ')
|
|
34
|
+
printf '%-32s %s ref(s)\n' "$k" "$n"
|
|
35
|
+
done
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
**Trate `0 ref` como candidata, não certeza.** Confirme com o usuário antes de remover.
|
|
39
|
+
|
|
40
|
+
### §1 — Convenção dos 3 arquivos
|
|
41
|
+
|
|
42
|
+
| Arquivo | Commitado? | Papel | Valores |
|
|
43
|
+
|---|---|---|---|
|
|
44
|
+
| `.env.example` | ✅ sim | Lista canônica (doc) | vazios/placeholder |
|
|
45
|
+
| `.env.local` | ❌ não | Desenvolvimento local | reais de dev |
|
|
46
|
+
| `.env.production` | ❌ não | **Sincronizado com a Vercel** | reais de produção |
|
|
47
|
+
|
|
48
|
+
Mesma sequência de chaves, **ordem alfabética**. Sem comentários de seção no meio.
|
|
49
|
+
|
|
50
|
+
### §2 — `.gitignore`
|
|
51
|
+
|
|
52
|
+
```gitignore
|
|
53
|
+
.env
|
|
54
|
+
.env.*
|
|
55
|
+
!.env.example
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### §3 — Classificação secret × plaintext (Vercel)
|
|
59
|
+
|
|
60
|
+
| Classe | Exemplos | Tipo |
|
|
61
|
+
|---|---|---|
|
|
62
|
+
| `NEXT_PUBLIC_*` | `NEXT_PUBLIC_API_URL` | **plaintext** |
|
|
63
|
+
| Flags / URLs públicas | `*_ENABLED`, `*_PUBLIC_URL`, `NODE_ENV` | **plaintext** |
|
|
64
|
+
| Todo o resto | `*_API_KEY`, `*_SECRET`, `*_TOKEN` | **secret** (`--sensitive`) |
|
|
65
|
+
|
|
66
|
+
### §4 — Comandos
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
npm i -g vercel && vercel login && vercel link
|
|
70
|
+
./scripts/env-files-check.sh
|
|
71
|
+
DRY_RUN=1 ./scripts/vercel-env-sync.sh
|
|
72
|
+
./scripts/vercel-env-sync.sh
|
|
73
|
+
vercel env pull .env.vercel.check --environment=production
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### §5 — `scripts/env-files-check.sh`
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
#!/usr/bin/env bash
|
|
80
|
+
set -euo pipefail
|
|
81
|
+
if [ "$#" -gt 0 ]; then FILES=("$@"); else FILES=(".env.example" ".env.local" ".env.production"); fi
|
|
82
|
+
keys_of() { grep -E '^[A-Za-z_][A-Za-z0-9_]*=' "$1" | sed -E 's/=.*//'; }
|
|
83
|
+
fail=0; ref=""; ref_file=""
|
|
84
|
+
for f in "${FILES[@]}"; do
|
|
85
|
+
if [ ! -f "$f" ]; then echo "❌ faltando: $f"; fail=1; continue; fi
|
|
86
|
+
keys="$(keys_of "$f")"
|
|
87
|
+
sorted="$(printf '%s\n' "$keys" | LC_ALL=C sort)"
|
|
88
|
+
if [ "$keys" != "$sorted" ]; then
|
|
89
|
+
echo "❌ $f não está em ordem alfabética."
|
|
90
|
+
diff <(printf '%s\n' "$keys") <(printf '%s\n' "$sorted") | head -6
|
|
91
|
+
fail=1
|
|
92
|
+
fi
|
|
93
|
+
count="$(printf '%s\n' "$keys" | grep -c . || true)"
|
|
94
|
+
echo "• $f — $count variáveis"
|
|
95
|
+
if [ -z "$ref" ]; then ref="$sorted"; ref_file="$f"
|
|
96
|
+
elif [ "$sorted" != "$ref" ]; then
|
|
97
|
+
echo "❌ $f difere de $ref_file:"
|
|
98
|
+
diff <(printf '%s\n' "$ref") <(printf '%s\n' "$sorted") || true
|
|
99
|
+
fail=1
|
|
100
|
+
fi
|
|
101
|
+
done
|
|
102
|
+
if [ "$fail" -eq 0 ]; then echo "✅ Arquivos alinhados, mesma sequência e em ordem alfabética."
|
|
103
|
+
else echo "→ Corrija as divergências acima."; fi
|
|
104
|
+
exit "$fail"
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### §6 — `scripts/vercel-env-sync.sh`
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
#!/usr/bin/env bash
|
|
111
|
+
set -euo pipefail
|
|
112
|
+
ENV_FILE="${1:-.env.production}"
|
|
113
|
+
TARGET="${2:-production}"
|
|
114
|
+
DRY_RUN="${DRY_RUN:-0}"
|
|
115
|
+
PLAINTEXT_REGEX="${PLAINTEXT_REGEX:-^(NEXT_PUBLIC_|NODE_ENV$|.*_ENABLED$|.*_URL_STRATEGY$|.*_PUBLIC_URL$|.*_REGION$)}"
|
|
116
|
+
command -v vercel >/dev/null 2>&1 || { echo "❌ vercel CLI não encontrado. Instale: npm i -g vercel"; exit 1; }
|
|
117
|
+
[ -f "$ENV_FILE" ] || { echo "❌ arquivo não encontrado: $ENV_FILE"; exit 1; }
|
|
118
|
+
[ -d ".vercel" ] || echo "⚠️ projeto não vinculado — rode 'vercel link' antes (continuando…)"
|
|
119
|
+
secret_count=0; plain_count=0
|
|
120
|
+
while IFS= read -r line <&3 || [ -n "$line" ]; do
|
|
121
|
+
case "$line" in ''|\#*) continue ;; esac
|
|
122
|
+
case "$line" in *=*) ;; *) continue ;; esac
|
|
123
|
+
key="${line%%=*}"; val="${line#*=}"
|
|
124
|
+
key="$(printf '%s' "$key" | tr -d '[:space:]')"
|
|
125
|
+
val="${val%\"}"; val="${val#\"}"; val="${val%\'}"; val="${val#\'}"
|
|
126
|
+
[ -z "$key" ] && continue
|
|
127
|
+
if [ -z "$val" ]; then echo "⏭️ $key (valor vazio — pulado)"; continue; fi
|
|
128
|
+
if printf '%s' "$key" | grep -Eq "$PLAINTEXT_REGEX"; then
|
|
129
|
+
flag=""; kind="plaintext"; plain_count=$((plain_count+1))
|
|
130
|
+
else
|
|
131
|
+
flag="--sensitive"; kind="secret "; secret_count=$((secret_count+1))
|
|
132
|
+
fi
|
|
133
|
+
echo "→ [$kind] $key ($TARGET)"
|
|
134
|
+
[ "$DRY_RUN" = "1" ] && continue
|
|
135
|
+
vercel env rm "$key" "$TARGET" -y </dev/null >/dev/null 2>&1 || true
|
|
136
|
+
printf '%s' "$val" | vercel env add "$key" "$TARGET" $flag >/dev/null
|
|
137
|
+
done 3< "$ENV_FILE"
|
|
138
|
+
echo "✅ $secret_count secret(s), $plain_count plaintext em '$TARGET'."
|
|
139
|
+
[ "$DRY_RUN" = "1" ] && echo "(DRY_RUN — nada foi enviado)"
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### §7 — Critérios de aceite
|
|
143
|
+
|
|
144
|
+
- Auditoria [§0] feita; órfãs removidas após confirmação do usuário.
|
|
145
|
+
- Scripts executáveis; 3 arquivos com mesma sequência alfabética.
|
|
146
|
+
- `./scripts/env-files-check.sh` retorna exit 0.
|
|
147
|
+
- `.gitignore` ignora `.env*` exceto `.env.example`.
|
|
148
|
+
- Nenhum valor real no `.env.example` nem no git.
|
|
149
|
+
|
|
150
|
+
### §8 — Limitações
|
|
151
|
+
|
|
152
|
+
Valores multilinha (PEM/JSON) → base64 numa linha ou cadastro manual na Vercel. `NEXT_PUBLIC_*` no target do **build**.
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
11
156
|
## Project Structure
|
|
12
157
|
|
|
13
158
|
All projects use TypeScript and follow this structure:
|
|
@@ -29,7 +29,7 @@ projeto/
|
|
|
29
29
|
├── CLAUDE.md # Índice enxuto + tabela de skills
|
|
30
30
|
├── .claude/
|
|
31
31
|
│ ├── settings.json
|
|
32
|
-
│ └── skills/ #
|
|
32
|
+
│ └── skills/ # 10 skills (task-flow-*, rbin-*)
|
|
33
33
|
├── .cursor/
|
|
34
34
|
│ ├── rules/ # Referência + Cursor alwaysApply
|
|
35
35
|
│ └── skills/ # Espelho das mesmas skills
|
|
@@ -53,9 +53,7 @@ CLAUDE.md # ≤ 150 linhas: índice + invariantes
|
|
|
53
53
|
├── task-flow-run/
|
|
54
54
|
│ ├── SKILL.md
|
|
55
55
|
│ └── workflow.md
|
|
56
|
-
├── task-flow-check/
|
|
57
56
|
├── task-flow-audit/
|
|
58
|
-
├── task-flow-improve-changes/
|
|
59
57
|
└── rbin-git/
|
|
60
58
|
.task-flow/ # tasks, status, contexts (inalterado)
|
|
61
59
|
```
|
|
@@ -89,7 +87,7 @@ task-flow-run/
|
|
|
89
87
|
|-------|-------------------|
|
|
90
88
|
| `description` | **Obrigatório para descoberta.** Terceira pessoa, WHAT + WHEN, termos `task-flow`, `run next`, `sync`, `RBIN`. Limite ~1536 caracteres na listagem. |
|
|
91
89
|
| `name` | Opcional; comando `/` vem do **nome da pasta** (`task-flow-run` → `/task-flow-run`). |
|
|
92
|
-
| `disable-model-invocation: true` | Workflows com efeito colateral: `run`, `sync`,
|
|
90
|
+
| `disable-model-invocation: true` | Workflows com efeito colateral: `run`, `sync`, deploy. Você dispara; Claude não “decide” sozinho. |
|
|
93
91
|
| `user-invocable: false` | Conhecimento de fundo (ex.: legado) — raro no Task Flow. |
|
|
94
92
|
| `allowed-tools` | Restringir ferramentas em skills sensíveis (ex.: só `Read`, `Grep` para audit read-only). |
|
|
95
93
|
| `paths` | Ex.: `[".task-flow/**"]` — auto-carregar skill ao editar arquivos de task. |
|
|
@@ -122,7 +120,7 @@ Inclua estado real **antes** das instruções:
|
|
|
122
120
|
1. ...
|
|
123
121
|
```
|
|
124
122
|
|
|
125
|
-
O prefixo `` !`comando` `` executa o comando e substitui a linha pelo output. Ideal para `run
|
|
123
|
+
O prefixo `` !`comando` `` executa o comando e substitui a linha pelo output. Ideal para `run` e `validate`.
|
|
126
124
|
|
|
127
125
|
### 4.5 Descoberta e monorepos
|
|
128
126
|
|
|
@@ -142,18 +140,13 @@ Para Task Flow em equipe: prefira **skills de projeto** versionadas (ajuste o `.
|
|
|
142
140
|
|
|
143
141
|
| Comando usuário | Skill sugerida | `/` | Regra fonte |
|
|
144
142
|
|-----------------|----------------|-----|-------------|
|
|
143
|
+
| `task-flow: from contexts` | `task-flow-from-contexts` | `/task-flow-from-contexts` | `task_from_contexts.mdc` |
|
|
145
144
|
| `task-flow: sync` | `task-flow-sync` | `/task-flow-sync` | `task-flow-sync.mdc` · `task_generation.mdc` (subtasks) |
|
|
146
145
|
| `task-flow: run next X` / `run X` | `task-flow-run` | `/task-flow-run` | `workflow.md` · stub `task_work.mdc` |
|
|
147
146
|
| `task-flow: status` | `task-flow-status` | `/task-flow-status` | `task_status.mdc` |
|
|
148
|
-
| `task-flow: think` | `task-flow-think` | `/task-flow-think` | `task_analysis.mdc` |
|
|
149
147
|
| `task-flow: audit` | `task-flow-audit` | `/task-flow-audit` | `task_audit.mdc` |
|
|
150
|
-
| `task-flow:
|
|
151
|
-
| `task-flow: check` | `task-flow-check` | `/task-flow-check` | `task_check.mdc` |
|
|
152
|
-
| `task-flow: review X` | `task-flow-review` | `/task-flow-review` | `task_review.mdc` |
|
|
153
|
-
| `task-flow: refactor X` | `task-flow-refactor` | `/task-flow-refactor` | `task_refactor.mdc` |
|
|
154
|
-
| `task-flow: estimate X` | `task-flow-estimate` | `/task-flow-estimate` | `task_estimate.mdc` |
|
|
148
|
+
| `task-flow: estimate X` / `X,Y` / `all` | `task-flow-estimate` | `/task-flow-estimate` | `task_estimate.mdc` |
|
|
155
149
|
| `task-flow: report X` | `task-flow-report` | `/task-flow-report` | `task_report.mdc` |
|
|
156
|
-
| `task-flow: generate flow` | `task-flow-generate-flow` | `/task-flow-generate-flow` | `task_generate_flow.mdc` |
|
|
157
150
|
| Implementar código | `rbin-coding-standards` | `/rbin-coding-standards` | checklist `coding_standards.mdc` + `docs/coding-standards-full.md` on demand |
|
|
158
151
|
| Após concluir subtarefa | `rbin-git` | `/rbin-git` | `rbin-git-policy.mdc` (always) |
|
|
159
152
|
|
|
@@ -205,23 +198,21 @@ Copie o corpo longo de `.cursor/rules/task_work.mdc` para `workflow.md`.
|
|
|
205
198
|
2. /task-flow-sync (ou: task-flow: sync)
|
|
206
199
|
3. /task-flow-status
|
|
207
200
|
4. /task-flow-run run next 3
|
|
208
|
-
5.
|
|
209
|
-
6. Você: git add && git commit (mensagem sugerida pela IA)
|
|
201
|
+
5. Você: git add && git commit (mensagem sugerida pela IA)
|
|
210
202
|
```
|
|
211
203
|
|
|
212
204
|
### 7.2 Antes do PR
|
|
213
205
|
|
|
214
206
|
```text
|
|
215
|
-
/task-flow-
|
|
216
|
-
/task-flow-check
|
|
217
|
-
/task-flow-review 1,2
|
|
207
|
+
/task-flow-validate
|
|
218
208
|
```
|
|
219
209
|
|
|
220
210
|
### 7.3 Planejamento / cobrança
|
|
221
211
|
|
|
222
212
|
```text
|
|
223
|
-
/task-flow-generate-flow
|
|
224
213
|
/task-flow-estimate 3
|
|
214
|
+
/task-flow-estimate 1,2,3
|
|
215
|
+
/task-flow-estimate all
|
|
225
216
|
```
|
|
226
217
|
|
|
227
218
|
### 7.4 Múltiplos agentes no mesmo repo
|
|
@@ -239,11 +230,11 @@ Skills nativas úteis **junto** com Task Flow ([docs](https://code.claude.com/do
|
|
|
239
230
|
|-------|-------------------|
|
|
240
231
|
| `/code-review` | Após `task-flow: run`, antes do commit |
|
|
241
232
|
| `/debug` | Subtarefa travada em bug |
|
|
242
|
-
| `/verify` | Validar app rodando
|
|
233
|
+
| `/verify` | Validar app rodando em runtime |
|
|
243
234
|
| `/run` | Subir app para testar UI de subtarefa |
|
|
244
235
|
| `/run-skill-generator` | Uma vez por repo — grava receita de build em `.claude/skills/run-*/` |
|
|
245
236
|
|
|
246
|
-
|
|
237
|
+
`/verify` cobre comportamento em runtime quando testes não bastam.
|
|
247
238
|
|
|
248
239
|
---
|
|
249
240
|
|
|
@@ -268,7 +259,6 @@ Stack: …
|
|
|
268
259
|
| Sync | `/task-flow-sync` |
|
|
269
260
|
| Executar | `/task-flow-run` |
|
|
270
261
|
| Status | `/task-flow-status` |
|
|
271
|
-
| Lint/build | `/task-flow-check` |
|
|
272
262
|
| Padrões de código | `/rbin-coding-standards` |
|
|
273
263
|
|
|
274
264
|
Comandos naturais `task-flow: …` também valem.
|
|
@@ -325,8 +315,8 @@ Ou use `AGENTS.override.md` / settings locais fora do git e commite `.claude/ski
|
|
|
325
315
|
## 13. Checklist de maturidade Claude + Task Flow
|
|
326
316
|
|
|
327
317
|
- [x] `CLAUDE.md` enxuto com índice de skills
|
|
328
|
-
- [x] Skills instaladas via `rbin-task-flow init` (
|
|
329
|
-
- [x] `paths: [".task-flow/**"]` em `task-flow-run`, `sync`, `estimate`, `report
|
|
318
|
+
- [x] Skills instaladas via `rbin-task-flow init` (10 skills)
|
|
319
|
+
- [x] `paths: [".task-flow/**"]` em `task-flow-run`, `sync`, `estimate`, `report`
|
|
330
320
|
- [x] Injeção `` !`head tasks.status.md` `` em `task-flow-run`
|
|
331
321
|
- [ ] `.claude/skills/` versionado no git (ajustar `.gitignore` se o time quiser)
|
|
332
322
|
- [ ] `.task-flow/contexts/` populado para tasks de UI
|
|
@@ -119,8 +119,6 @@ src/AGENTS.md # Opcional: só para subtree (monorepo)
|
|
|
119
119
|
| `task-flow: sync` | `.cursor/rules/task-flow-sync.mdc` |
|
|
120
120
|
| `task-flow: run next X` / `run N` | `.claude/skills/task-flow-run/workflow.md` (fallback: `task_work.mdc`) |
|
|
121
121
|
| `task-flow: status` | `.task-flow/tasks.status.md` |
|
|
122
|
-
| `task-flow: improve changes` | `.cursor/rules/task_improve_changes.mdc` + `git diff --name-only HEAD` |
|
|
123
|
-
| `task-flow: check` | `.cursor/rules/task_check.mdc` + `package.json` scripts |
|
|
124
122
|
| `task-flow: audit` | `.cursor/rules/task_audit.mdc` + checklist `coding_standards.mdc` (full doc seções se necessário) |
|
|
125
123
|
|
|
126
124
|
Após cada subtarefa: atualizar `status.json` e `tasks.status.md` (resumo no topo).
|
|
@@ -155,18 +153,16 @@ Codex prefere `AGENTS.override.md` sobre `AGENTS.md` **no mesmo nível**.
|
|
|
155
153
|
|
|
156
154
|
| Comando | Prompt mínimo eficaz |
|
|
157
155
|
|---------|---------------------|
|
|
156
|
+
| `task-flow: from contexts` | `task_from_contexts.mdc — leia contexts/, append tasks em tasks.input.txt` |
|
|
158
157
|
| `task-flow: sync` | `Leia AGENTS.md e task-flow-sync.mdc. Execute task-flow: sync em tasks.input.txt.` |
|
|
159
158
|
| `task-flow: run next 3` | `Siga task-flow-run workflow.md. task-flow: run next 3. Atualize status.json e tasks.status.md.` |
|
|
160
159
|
| `task-flow: run 2` | Idem + respeitar dependências tasks 1..X-1 |
|
|
161
160
|
| `task-flow: status` | `Mostre o conteúdo de .task-flow/tasks.status.md` |
|
|
162
|
-
| `task-flow: think` | `task-flow: think — sugira tasks; pergunte antes de gravar em tasks.input.txt` |
|
|
163
|
-
| `task-flow: improve changes` | `git diff --name-only HEAD` · checklist `coding_standards.mdc` nos paths alterados |
|
|
164
|
-
| `task-flow: check` | `Rode lint:fix e build do package.json; corrija até passar` |
|
|
165
|
-
| `task-flow: review 1` | `task_review.mdc — verifique se task 1 done está realmente implementada` |
|
|
166
161
|
| `task-flow: validate` | `task_validate.mdc — valide todas as tasks, reverta false done, adicione lacunas em tasks.input.txt e sync` |
|
|
167
162
|
| `task-flow: estimate 1` | `task_estimate.mdc para task 1` |
|
|
163
|
+
| `task-flow: estimate 1,2` | `task_estimate.mdc para tasks 1 e 2` |
|
|
164
|
+
| `task-flow: estimate all` | `task_estimate.mdc para todas as tasks` |
|
|
168
165
|
| `task-flow: report 1` | `task_report.mdc — task 1 deve estar done` |
|
|
169
|
-
| `task-flow: generate flow` | `task_generate_flow.mdc — preencher tasks.flow.md` |
|
|
170
166
|
|
|
171
167
|
**Padrão universal:**
|
|
172
168
|
|
|
@@ -193,10 +189,6 @@ Leia AGENTS.md. task-flow: sync.
|
|
|
193
189
|
task-flow: run next 2 — leia .claude/skills/task-flow-run/workflow.md e .task-flow/.internal/tasks.json.
|
|
194
190
|
```
|
|
195
191
|
|
|
196
|
-
```text
|
|
197
|
-
task-flow: check
|
|
198
|
-
```
|
|
199
|
-
|
|
200
192
|
Você executa git manualmente.
|
|
201
193
|
|
|
202
194
|
### 6.2 Codex em subpasta (monorepo)
|
|
@@ -213,11 +205,7 @@ Codex mescla: `AGENTS.md` (raiz) + `packages/frontend/AGENTS.md` se existir.
|
|
|
213
205
|
### 6.3 Antes do PR
|
|
214
206
|
|
|
215
207
|
```text
|
|
216
|
-
task-flow:
|
|
217
|
-
```
|
|
218
|
-
|
|
219
|
-
```text
|
|
220
|
-
task-flow: review 2,3
|
|
208
|
+
task-flow: validate
|
|
221
209
|
```
|
|
222
210
|
|
|
223
211
|
### 6.4 Sem project doc (debug)
|
|
@@ -290,8 +278,7 @@ Config mais específica (perto do CWD) **sobrescreve** a da raiz.
|
|
|
290
278
|
| Ferramenta | Papel |
|
|
291
279
|
|------------|-------|
|
|
292
280
|
| `rbin-task-flow init` | Instala `AGENTS.md` + `.task-flow/` + `.cursor/rules/` |
|
|
293
|
-
|
|
|
294
|
-
| Codex | Executa lógica descrita nas regras |
|
|
281
|
+
| Codex | Executa lógica descrita nas regras (`task-flow: audit`, `task-flow: run`, etc.) |
|
|
295
282
|
|
|
296
283
|
Codex **não** substitui `task-flow: sync` — isso é trabalho do agente lendo as regras.
|
|
297
284
|
|
|
@@ -303,7 +290,7 @@ Codex **não** substitui `task-flow: sync` — isso é trabalho do agente lendo
|
|
|
303
290
|
|-------|---------|
|
|
304
291
|
| AGENTS.md com 40 KiB de standards | Truncamento silencioso |
|
|
305
292
|
| Assumir que Codex “sabe” task-flow | Sem `.mdc` no prompt, comportamento genérico |
|
|
306
|
-
| `task-flow: audit` em todo commit pequeno | Use `
|
|
293
|
+
| `task-flow: audit` em todo commit pequeno | Use `task-flow: validate` ou escopo manual nos paths alterados |
|
|
307
294
|
| Duplicar git rules em 3 arquivos sem necessidade | Desperdício do orçamento 32 KiB |
|
|
308
295
|
| `CODEX_DISABLE_PROJECT_DOC=1` esquecido no env | AGENTS.md ignorado |
|
|
309
296
|
|
|
@@ -316,7 +303,7 @@ Codex **não** substitui `task-flow: sync` — isso é trabalho do agente lendo
|
|
|
316
303
|
| Ignora “nunca commit” | AGENTS truncado ou não carregado | `Summarize current instructions`; reduzir AGENTS |
|
|
317
304
|
| Não atualiza status | Procedimento não no prompt | Citir `task-flow-run/workflow.md` ou resumo embutido |
|
|
318
305
|
| Comportamento diferente na subpasta | AGENTS local sobrescreve | Revisar `packages/*/AGENTS.md` |
|
|
319
|
-
| Muito contexto em standards | audit puxou arquivo inteiro |
|
|
306
|
+
| Muito contexto em standards | audit puxou arquivo inteiro | Limite paths no prompt ou use checklist só nos arquivos alterados |
|
|
320
307
|
| Conflito global vs repo | `~/.codex/AGENTS.md` | Simplificar global; detalhe no repo |
|
|
321
308
|
|
|
322
309
|
---
|
|
@@ -328,7 +315,7 @@ Codex **não** substitui `task-flow: sync` — isso é trabalho do agente lendo
|
|
|
328
315
|
- [x] `.codex/config.toml` com `project_doc_max_bytes = 65536`
|
|
329
316
|
- [ ] Tamanho `AGENTS.md` < ~28 KiB se não usar config.toml
|
|
330
317
|
- [ ] Prompts citam `AGENTS.md` + `.task-flow/guides/CODEX.md` para `run`
|
|
331
|
-
- [ ] `
|
|
318
|
+
- [ ] `task-flow: validate` antes de PR quando relevante
|
|
332
319
|
- [ ] `AGENTS.md` em subpastas de monorepo se necessário
|
|
333
320
|
|
|
334
321
|
---
|
|
@@ -362,7 +349,7 @@ Ao implementar código, seguir o checklist em `.cursor/rules/coding_standards.md
|
|
|
362
349
|
|
|
363
350
|
## 15. Graphify (opcional)
|
|
364
351
|
|
|
365
|
-
Não adicionamos Graphify ao `AGENTS.md` (limite 32 KiB). Em **`task-flow: run`**, peça no prompt: `graphify query "…"` se
|
|
352
|
+
Não adicionamos Graphify ao `AGENTS.md` (limite 32 KiB). Em **`task-flow: run`**, peça no prompt: `graphify query "…"` se `.task-flow/guides/graphify-out/` existir. Ver [GRAPHIFY.md](../GRAPHIFY.md).
|
|
366
353
|
|
|
367
354
|
---
|
|
368
355
|
|