@aksp/opencrew 1.13.0 → 1.14.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.
Files changed (29) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/README.md +24 -3
  3. package/package.json +1 -1
  4. package/templates/AGENTS.md +1 -0
  5. package/templates/_opencrew/.opencrew-version +1 -1
  6. package/templates/_opencrew/core/prompts/build.prompt.md +2 -0
  7. package/templates/_opencrew/core/prompts/repair.prompt.md +4 -1
  8. package/templates/_opencrew/core/runner/fim-da-execucao.md +15 -26
  9. package/templates/_opencrew/core/runner/memoria.md +3 -0
  10. package/templates/_opencrew/core/runner/retomar.md +51 -0
  11. package/templates/_opencrew/core/runner.pipeline.md +23 -7
  12. package/templates/_opencrew/core/scripts/caminho/argumentos.mjs +7 -4
  13. package/templates/_opencrew/core/scripts/caminho/crew.mjs +20 -0
  14. package/templates/_opencrew/core/scripts/caminho/disco.mjs +4 -3
  15. package/templates/_opencrew/core/scripts/caminho.mjs +62 -29
  16. package/templates/_opencrew/core/scripts/conserto/achados.mjs +2 -0
  17. package/templates/_opencrew/core/scripts/conserto/aplicar.mjs +2 -1
  18. package/templates/_opencrew/core/scripts/conserto/argumentos.mjs +2 -1
  19. package/templates/_opencrew/core/scripts/conserto/crew.mjs +4 -3
  20. package/templates/_opencrew/core/scripts/conserto/historico.mjs +102 -0
  21. package/templates/_opencrew/core/scripts/conserto.mjs +9 -7
  22. package/templates/_opencrew/core/scripts/entrega/leiame.mjs +4 -2
  23. package/templates/_opencrew/core/scripts/entregar.mjs +2 -0
  24. package/templates/_opencrew/core/scripts/estado/arquivo.mjs +17 -10
  25. package/templates/_opencrew/core/scripts/execucao/argumentos.mjs +62 -0
  26. package/templates/_opencrew/core/scripts/execucao/historico.mjs +76 -0
  27. package/templates/_opencrew/core/scripts/execucao/registro.mjs +115 -0
  28. package/templates/_opencrew/core/scripts/execucao/retomar.mjs +123 -0
  29. package/templates/_opencrew/core/scripts/execucao.mjs +123 -0
package/CHANGELOG.md CHANGED
@@ -3,6 +3,46 @@
3
3
  All notable changes to opencrew are documented here.
4
4
  The format is based on [Keep a Changelog](https://keepachangelog.com/).
5
5
 
6
+ ## [1.14.0] — 2026-10-08
7
+
8
+ Fase U5, fatia 3: "Execução registrada" (`specs/fase-u5c-execucao-registrada.md`). Chega a quem já
9
+ usa com um `npx @aksp/opencrew@latest update`; as crews e as execuções antigas ficam como estão.
10
+
11
+ Ainda não nesta versão: o pedido avulso à crew (1.15.0).
12
+
13
+ ### Added
14
+ - **`/opencrew retomar <nome>`.** A execução que parou no meio — a conversa caiu, o contexto
15
+ acabou — continua de onde parou, em qualquer conversa nova. A IA mostra o tema, o que já está
16
+ pronto e de que passo vai seguir, e espera o seu sim. O que foi gravado e conferido não é
17
+ refeito; o passo que estava no meio é refeito inteiro.
18
+ - **Registro da execução.** Cada execução deixa na pasta dela um `execucao.json`, gravado por
19
+ script a cada passo: o tema, os passos conferidos, as suas respostas nas aprovações e os
20
+ vereditos da revisão. A IA não escreve nesse arquivo. Não há comando a mais por passo: o
21
+ registro pega carona no que a execução já rodava.
22
+ - **`/opencrew repair` olha o histórico.** Pasta de execução sem linha no `runs.md` vira um ponto
23
+ do conserto: ele pergunta o tema e grava a linha como `Registrada depois`, com cópia
24
+ `runs.md.bak`. Linha sem pasta e pasta vazia são só apontadas: nada é apagado.
25
+
26
+ ### Changed
27
+ - **O histórico (`runs.md`) é gravado pelo script, não pela IA** — também quando a execução é
28
+ abortada ou rejeitada, que antes ficavam de fora. As colunas são as mesmas, e as linhas que já
29
+ existem não mudam.
30
+ - **O Score tem uma definição só:** aprovações suas sem pedido de correção, sobre as aprovações
31
+ que você respondeu (`2/3`). Quem conta é o script. Antes o texto dava duas contas diferentes, e
32
+ numa crew real saiu uma nota.
33
+ - **Regra de Ouro contada de verdade.** As correções ficam no registro de cada execução; no fim, o
34
+ script mostra as das 10 últimas e a IA procura ali o que se repetiu em 3 ou mais. Antes ela
35
+ procurava na memória da crew, que não guarda dado de execução. A seção se chama
36
+ `## Regras de Ouro`, um nome só.
37
+ - O `LEIA-ME.md` da entrega abre com o tema da execução, quando o registro tem um.
38
+
39
+ ### Limites
40
+ - O registro só sabe o que os comandos contam: se a IA pular o aviso de uma aprovação, o score
41
+ sai errado para menos.
42
+ - Execução feita antes desta versão não tem registro: não dá para retomar, e só entra no
43
+ histórico pelo conserto.
44
+ - Ao retomar, o que foi combinado só na conversa anterior, sem ter sido gravado, não volta.
45
+
6
46
  ## [1.13.0] — 2026-10-07
7
47
 
8
48
  Fase U5, fatia 2: "Runner dividido" (`specs/fase-u5b-runner-dividido.md`). Chega a quem já usa
package/README.md CHANGED
@@ -182,12 +182,12 @@ meu-projeto/
182
182
  │ ├── core/
183
183
  │ │ ├── system.md ← 🧠 sistema completo do OpenCrew
184
184
  │ │ ├── runner.pipeline.md ← executor de pipeline (o que toda execução usa)
185
- │ │ ├── runner/ ← 7 partes do executor, lidas só quando é o caso (painel, fim da execução…)
185
+ │ │ ├── runner/ ← 8 partes do executor, lidas só quando é o caso (painel, fim da execução, retomar…)
186
186
  │ │ ├── skills.engine.md ← gerenciador de skills
187
187
  │ │ ├── architect.agent.yaml ← definição do Arquiteto
188
188
  │ │ ├── formato-da-crew.md ← o formato dos arquivos de uma crew (crew.yaml, pipeline.yaml, passos)
189
189
  │ │ ├── best-practices/ ← 24 guias de melhores práticas + _catalog.yaml
190
- │ │ ├── scripts/ ← verificador, conferência de fontes, caminhos, entrega, documento Word, conserto de crews e os scripts do Escritório
190
+ │ │ ├── scripts/ ← verificador, conferência de fontes, caminhos, registro da execução, entrega, documento Word, conserto de crews e os scripts do Escritório
191
191
  │ │ ├── modelos/ ← modelo do perfil de documento oficial (papel timbrado)
192
192
  │ │ ├── escritorio/ ← página do Escritório ao vivo (abre com /opencrew dashboard)
193
193
  │ │ └── prompts/ ← 15 prompts de fase (discovery, design, build, entrega, documento, etc.)
@@ -206,6 +206,7 @@ meu-projeto/
206
206
  ├── crews/ ← suas crews vivem aqui
207
207
  │ ├── blog-semanal/ ← template: blog semanal
208
208
  │ │ └── output/<execução>/ ← criada a cada execução
209
+ │ │ ├── execucao.json ← registro da execução, gravado por script (é o que o `/opencrew retomar` lê)
209
210
  │ │ ├── v1/ v2/ … ← o que cada passo gravou
210
211
  │ │ └── entrega/ ← o que você usa: LEIA-ME.md + uma pasta por canal (copiada para a pasta do projeto que você escolher)
211
212
  │ ├── instagram-carrossel/ ← template: Instagram carrossel
@@ -294,6 +295,25 @@ são sempre em português.
294
295
 
295
296
  ---
296
297
 
298
+ ## Histórico e execução interrompida
299
+
300
+ Cada execução deixa um registro na pasta dela (`crews/<crew>/output/<execução>/execucao.json`):
301
+ o tema, os passos já gravados e conferidos, o que você respondeu em cada aprovação. Quem grava é
302
+ um script, a cada passo — a IA não escreve nesse arquivo.
303
+
304
+ - **O histórico da crew** (`crews/<crew>/_memory/runs.md`) ganha uma linha por execução, também
305
+ gravada pelo script: a que terminou, a que você abortou e a que a revisão rejeitou. A coluna
306
+ Score tem um significado só: aprovações suas sem pedido de correção, sobre as aprovações que você
307
+ respondeu (`2/3`).
308
+ - **A conversa caiu no meio?** Em qualquer conversa nova, peça `/opencrew retomar <nome>`. A IA
309
+ mostra o tema, o que já está pronto e de que passo vai continuar, e espera o seu sim. O que já
310
+ foi gravado e conferido não é refeito; o passo que estava no meio é refeito inteiro. O que foi
311
+ combinado só na conversa anterior, sem ter sido gravado, não volta.
312
+ - **Execução antiga fora do histórico?** O `/opencrew repair <nome>` mostra as pastas de execução
313
+ sem linha no histórico, pergunta o tema de cada uma e grava a linha como `Registrada depois`,
314
+ com cópia `runs.md.bak`. Linha sem pasta e pasta vazia são só apontadas: nada é apagado.
315
+ - Execução feita antes da 1.14.0 não tem registro: não dá para retomar.
316
+
297
317
  ## Documento Word
298
318
 
299
319
  Ata, ofício, declaração, contrato: quando o resultado é um documento para imprimir, assinar ou
@@ -499,9 +519,10 @@ npx @aksp/opencrew update --check
499
519
  | `/opencrew` | Abre o menu principal |
500
520
  | `/opencrew create <descrição>` | Cria uma nova crew a partir da sua descrição |
501
521
  | `/opencrew run <nome>` | Executa o pipeline de uma crew |
522
+ | `/opencrew retomar <nome>` | Continua a execução que parou no meio (a conversa caiu, o contexto acabou): mostra o que já está pronto e segue do passo seguinte, sem refazer o que foi gravado |
502
523
  | `/opencrew list` | Lista todas as suas crews |
503
524
  | `/opencrew edit <nome>` | Modifica uma crew existente |
504
- | `/opencrew repair <nome>` | Mostra o que falta numa crew que você já tem (formato de cada texto, arquivos do projeto que ela deve ler, proibições que o verificador consegue barrar, nomes dos agentes) e conserta um ponto por vez, com o seu sim e uma cópia `.bak` |
525
+ | `/opencrew repair <nome>` | Mostra o que falta numa crew que você já tem (formato de cada texto, arquivos do projeto que ela deve ler, proibições que o verificador consegue barrar, nomes dos agentes, execuções que ficaram fora do histórico) e conserta um ponto por vez, com o seu sim e uma cópia `.bak` |
505
526
  | `/opencrew delete <nome>` | Remove uma crew |
506
527
  | `/opencrew skills` | Navega, instala ou remove skills |
507
528
  | `/opencrew install <skill>` | Instala uma skill do catálogo |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aksp/opencrew",
3
- "version": "1.13.0",
3
+ "version": "1.14.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -59,6 +59,7 @@ Route input to the matching action:
59
59
  | `/opencrew create <description>` | Load the Architect (`_opencrew/core/architect.agent.yaml`) → Create Crew flow: one prompt per phase, listed there |
60
60
  | `/opencrew list` | List all crews in `crews/` (a folder without `crew.yaml` is not a crew) |
61
61
  | `/opencrew run <name>` | Load Pipeline Runner → Execute crew |
62
+ | `/opencrew retomar <name>` | Load Pipeline Runner → resume the run of that crew that stopped in the middle (`_opencrew/core/runner/retomar.md`) |
62
63
  | `/opencrew edit <name> <changes>` | Load the Architect → Edit Crew flow |
63
64
  | `/opencrew repair <name>` | Load `_opencrew/core/prompts/repair.prompt.md` → show what an existing crew is missing and fix one point at a time, each with a `.bak` copy |
64
65
  | `/opencrew skills` | Load Skills Engine → Show skills menu |
@@ -1 +1 @@
1
- 1.13.0
1
+ 1.14.0
@@ -36,6 +36,8 @@ Generate these files directly — they are compilations of data already gathered
36
36
 
37
37
  ## Proibições Explícitas
38
38
 
39
+ ## Regras de Ouro
40
+
39
41
  ## Técnico (específico do crew)
40
42
  ```
41
43
  - `crews/{code}/_memory/runs.md` — empty run history log:
@@ -2,7 +2,7 @@
2
2
 
3
3
  You are the opencrew Repair agent. A crew built by an older version misses what later versions
4
4
  added: the format of each text, the project sources, bans the checker can enforce, the persona
5
- names. Your job is to show the user what is missing in **one crew that already exists** and fix
5
+ names, the runs that never reached the history. Your job is to show the user what is missing in **one crew that already exists** and fix
6
6
  one point at a time, each with the user's yes.
7
7
 
8
8
  **You never write inside `crews/` yourself.** Every change is one command of the script below,
@@ -33,6 +33,8 @@ It only reads. Its last line is the status:
33
33
 
34
34
  - `CONSERTO:OK` — say "A crew {nome} está em dia: não há o que consertar." and stop.
35
35
  - `CONSERTO:PENDENTE` — one block per finding, each starting with `[código]`. Go to Step 3.
36
+ - A line starting with `Nota:` (with any status) is information, not a finding: show it to the
37
+ user once, in plain words; there is nothing to fix and nothing is deleted.
36
38
  - `CONSERTO:ERRO`, or the script did not run (no Node, an error) — show the user the message as
37
39
  it came and stop. Do not repair by hand.
38
40
 
@@ -60,6 +62,7 @@ codes between brackets, the `--aplicar` lines or the `CONSERTO:` status line.
60
62
  | `sem-aprovacao-final` | "Depois da revisão não há um ponto de aprovação seu. Isso se resolve editando a crew: /opencrew edit {nome}." | none |
61
63
  | `publica-antes` | "O passo {n} publica ou envia antes da revisão e da sua aprovação final. Enquanto estiver assim, o que sai não passou pela revisão. Isso se resolve editando a crew: /opencrew edit {nome}." | none |
62
64
  | `passo-faltando` | Show the lines the script printed and say that it is solved by editing the crew: `/opencrew edit {nome}` | none |
65
+ | `historico` | For each listed run folder: "A pasta {run} tem arquivos de uma execução que não está no histórico: {arquivos}. Qual foi o tema dela? (Se não lembrar, responda 'não sei'.)" With 'não sei', the theme is `não informado`. A folder the script marks as `interrompida` can still be resumed: say so (`/opencrew retomar {nome}`) and register it only if the user prefers. An empty folder (`execução abandonada`) and a row with no folder are only shown: nothing is deleted | `--aplicar "historico:{run}={tema}"` — the theme on one line, with only letters, digits, spaces and `. , : ; - ( ) / ?` |
63
66
 
64
67
  The command is always the same line, with the item between double quotes:
65
68
 
@@ -31,46 +31,35 @@ After applying all candidates, write the updated `memories.md`.
31
31
 
32
32
  If no candidates are found (the run had no explicit user feedback), skip writing `memories.md` entirely — do not write an unmodified copy. Always proceed to step 2b regardless.
33
33
 
34
- ### 2b. Prepend to `runs.md` (reverse-chronological log — newest run first)
34
+ ### 2b. Prepend to `runs.md` — the script writes the row
35
35
 
36
- If `crews/{name}/_memory/runs.md` does not exist, create it first with:
37
- ```markdown
38
- # Run History: {crew-name}
36
+ Never write `crews/{name}/_memory/runs.md` yourself. Close the run with the `fechar` command of the runner ("Run record"): `--resultado` is `aprovado` (the final approval was given), `publicado` (an irreversible step published or sent) or `rejeitado` (the review rejected at the last cycle and the user aborted); `--saida` is a brief description of what was generated (e.g. "Carrossel 9 slides", "Thread 7 posts"); add `--tema "{tema}"` (1 sentence max) if no command of this run carried the topic yet.
39
37
 
40
- | Data | Run ID | Tema | Output | Score | Resultado |
41
- |------|--------|------|--------|-------|-----------|
42
- ```
43
- Then proceed to prepend the new row.
44
-
45
- Read `crews/{name}/_memory/runs.md`. Prepend one new row to the table (immediately after the header row), with:
46
- - `Data`: the date of this run (the first 10 characters of the `run_id`)
47
- - `Run ID`: the `run_id` for this execution
48
- - `Tema`: the topic or user request from this run (1 sentence max)
49
- - `Output`: brief description of what was generated (e.g., "Carrossel 9 slides", "Thread 7 posts")
50
- - `Score`: `{approved}/{total}` agent outputs approved without corrections (e.g., `4/5`)
51
- - `Resultado`: one of — `Aprovado` / `Rejeitado` / `Publicado` / `Abortado`
38
+ The script writes the row of this run right below the header — `Data | Run ID | Tema | Output | Score | Resultado`, newest run first; a row this run already had is replaced — and prints it. No other data.
52
39
 
53
- No other data.
40
+ `Score` has one definition, and the script counts it from the recorded checkpoints: the checkpoints the user approved without corrections ÷ the checkpoints the user answered (approved + corrected; a skipped one does not count), e.g. `2/3`; `—` when none was answered. Never compute it yourself.
54
41
 
55
- The `Score` column tracks how many agent outputs were approved by the user without corrections in this run. Count only explicit checkpoint approvals (not "skip" or "continue"). Format: `{approved}/{total checkpoints}` (e.g., `4/5` means 4 of 5 agent outputs were approved as-is).
42
+ - Last line `EXECUCAO:FECHADA {resultado} {score}` → go on to 2c. A line `Não consegui gravar o histórico desta execução: {motivo}` before it → show it to the user as it came.
43
+ - The script did not run (no Node, an error, no `EXECUCAO:` line) → tell the user `⚠️ Não consegui gravar o histórico desta execução: {motivo}` and go on. Do not write the row by hand.
56
44
 
57
45
  ### 2c. Post-Run Reflection (pattern detection)
58
46
 
59
- After updating `memories.md` and `runs.md`, run a reflection pass. This is a lightweight analysis — not a full agent execution, just pattern matching on the run's feedback and past memory.
47
+ After updating `memories.md` and closing the run, run a reflection pass. This is a lightweight analysis — not a full agent execution, just pattern matching on the corrections of this run and of the last runs.
60
48
 
61
49
  1. **Collect this run's corrections**: From checkpoint responses, gather every user rejection or correction. A correction is:
62
50
  - A rejected output with a reason ("tom muito informal", "cor não combina", "fonte sem data")
63
51
  - A modification request during checkpoint ("muda o título para X", "usa azul em vez de verde")
64
52
 
65
- 2. **Look for recurrence**: Compare each correction against past runs recorded in `memories.md`:
66
- - Search `memories.md` for similar patterns (same category, same agent, same type of correction)
67
- - Count: how many past runs have a correction matching this pattern?
68
- - A "match" means the same agent + same type of error (e.g., "redator + tom informal", "designer + cores saturadas")
53
+ 2. **Look for recurrence**: use the list the `fechar` command printed under `Correções das últimas execuções:` — one line per correction recorded in the last 10 closed runs of this crew, this one included (`- {run_id} · passo {N} · {nota}`).
54
+ - Do not search `memories.md` for past runs: by rule it keeps no run data.
55
+ - Count: in how many different runs of that list does the same pattern appear?
56
+ - A "match" means the same step (so the same agent) + the same type of error (e.g. "redator + tom informal", "designer + cores saturadas")
57
+ - No list was printed → there is nothing to compare: skip items 3 and 4.
69
58
 
70
59
  3. **Promote to Regra de Ouro**: If the SAME pattern appears in **3 or more runs** (including this one):
71
- a. Add a new entry under `## Regras de Ouro` in `memories.md`:
60
+ a. Add a new entry under `## Regras de Ouro` in `memories.md` (the header is exactly this, fixed PT-BR; create the section if the file does not have it):
72
61
  ```markdown
73
- ## Regras de Ouro (promovidas após 3+ ocorrências)
62
+ ## Regras de Ouro
74
63
 
75
64
  - **{Agent role}**: SEMPRE {correct behavior}. {Why — grounded in user feedback}.
76
65
  (Runs: #{run1}, #{run2}, #{run3})
@@ -94,7 +83,7 @@ After updating `memories.md` and `runs.md`, run a reflection pass. This is a lig
94
83
 
95
84
  5. **Bail out early**: If this run had zero corrections (all checkpoints approved), skip the entire reflection — nothing to learn.
96
85
 
97
- 6. **Reflection budget**: Maximum 30 seconds of analysis. If the crew has a long history (>20 past runs), sample the most recent 10 runs for pattern matching. This is a quick scan, not an exhaustive audit.
86
+ 6. **Reflection budget**: Maximum 30 seconds of analysis: the list of the script is all the history you read. This is a quick scan, not an exhaustive audit.
98
87
 
99
88
  3. Present completion summary:
100
89
  ```
@@ -13,6 +13,7 @@ preferred language.
13
13
  | `## Design Visual` | `memories.md` | Visual design preferences per crew |
14
14
  | `## Estrutura de Conteúdo` | `memories.md` | Content structure rules per crew |
15
15
  | `## Proibições Explícitas` | `memories.md` | User bans and hard blocks per crew |
16
+ | `## Regras de Ouro` | `memories.md` | Corrections repeated in 3 or more runs, promoted at the end of a run |
16
17
  | `## Técnico (específico do crew)` | `memories.md` | Technical crew-specific settings |
17
18
  | `Data \| Run ID \| Tema \| Output \| Score \| Resultado` | `runs.md` | Run history table columns |
18
19
 
@@ -41,6 +42,8 @@ unless the user base expands beyond PT-BR — at that point, discuss a migration
41
42
 
42
43
  ## Proibições Explícitas
43
44
 
45
+ ## Regras de Ouro
46
+
44
47
  ## Técnico (específico do crew)
45
48
  ```
46
49
  (Use the crew's display name for `{crew-name}`, and the crew code for `{name}` in file paths — they refer to the same crew.)
@@ -0,0 +1,51 @@
1
+ # Resuming a run (retomar)
2
+
3
+ > Part of the Pipeline Runner (`_opencrew/core/runner.pipeline.md`). Read it only on `/opencrew retomar {name}`.
4
+
5
+ A run that stopped in the middle — the conversation ended, the context ran out — left its record on
6
+ disk. Resuming is going on from the step after the last one that was done, with the same `run_id`:
7
+ what was written and checked is not redone; the step that was in the middle is done again, whole.
8
+
9
+ 1. From the project root, with the crew code between double quotes (safe-name rule of the runner):
10
+ ```
11
+ node _opencrew/core/scripts/execucao.mjs "{name}" retomar
12
+ ```
13
+ 2. Read the last line:
14
+ - `EXECUCAO:NADA` → say `Não há execução interrompida da crew {nome}.` and stop (to start a new
15
+ run: `/opencrew run {name}`).
16
+ - `EXECUCAO:RETOMAR {run_id} {N}` → the lines before it are the theme, the steps already checked
17
+ (each with its file), the checkpoints already answered and the verdicts of the review. Go to 3.
18
+ - The output starts with `Execuções abertas` → more than one run is open: show the list and ask
19
+ which one. For one that is not the newest, run the command again with `--run "{run_id}"`.
20
+ - A line `Não consegui ler na crew para qual passo a revisão … volta` → show it and confirm the
21
+ step with the user before going on.
22
+ - No `EXECUCAO:` line (no Node, an error) → show the message as it came and stop. Never rebuild
23
+ the state of a run by looking at its folder, and never read `execucao.json` yourself.
24
+ 3. Ask, and wait for the answer:
25
+ `A execução {run} ({tema}) parou depois do passo {k}. Já estão prontos: {lista}. Continuo do passo {N}?`
26
+ (`{run}`: the `run_id`; `{k}`: the step of the line `Parou depois do passo`; `{lista}`: the files
27
+ under `Passos conferidos` — not the ones under `Já gravados, mas serão feitos de novo`; a run
28
+ with no theme goes without the parentheses.)
29
+ - No → change nothing. Ask `Quer que eu encerre essa execução como abortada?`; after a yes, run
30
+ the `fechar` command of the runner ("Run record") with `--resultado abortado`, so it is no
31
+ longer offered. Then stop.
32
+ 4. Only now, after the yes (nothing of the runner's Initialization runs before the question): do the Initialization of the runner in full (memory format, source check, project
33
+ sources, pipeline, skills, tiers, agent selection, the header) **except step 5b**: do not run
34
+ `pasta` — the `run_id` is the one of the `EXECUCAO:RETOMAR` line.
35
+ Step 6 (the Escritório) happens as in a new run.
36
+ 5. Go on at step `{N}` of "For each pipeline step", with that `run_id`:
37
+ - Every input comes from the `entrada` command, as always: it finds what the earlier steps wrote.
38
+ - The paths under `Passos conferidos` are the stored paths of those steps: use them to show a
39
+ file at a checkpoint and to build the list of the delivery.
40
+ - Do not ask again a checkpoint the script listed as answered: its answer is in the file the
41
+ checkpoint saved (the `inputFile` of the step after it), or in the note the script printed.
42
+ - Step `{N}` is done whole, even when a file of it is already there (`saida` opens a new version).
43
+ - A review cycle the script listed counts: the cycles left are `max_review_cycles` minus the
44
+ verdicts under `Revisões:` for that review step (no such section: none), and the next
45
+ `verificacao-ciclo-{N}.md` is that number plus 1.
46
+ - The `Tema:` line says whether the record has a topic: `(sem tema)` → send `--tema` with the
47
+ next `marcar` or with `fechar`.
48
+ - `{N}` is after the last step of the pipeline (the script says `Todos os passos já foram feitos`)
49
+ → go straight to "After Pipeline Completion".
50
+ 6. Say once, before the first step: `Retomei pelo que está gravado. O que foi combinado só na conversa anterior não veio junto.`
51
+ A resumed run is recorded and closed like any other (`conferir --passo`, `marcar`, `fechar`).
@@ -24,6 +24,7 @@ included), digits, space and `. _ - / \ : ( )`. With any other character (`$`, b
24
24
 
25
25
  ## Initialization
26
26
 
27
+ **Resuming** — only on `/opencrew retomar {name}`: before any step below, read `_opencrew/core/runner/retomar.md` completely and follow it — it asks the user first, then says when to do this Initialization, with no step 5b (no new folder: the run goes on with its `run_id`).
27
28
  Before starting execution:
28
29
 
29
30
  1. You have already loaded:
@@ -90,7 +91,7 @@ Before starting execution:
90
91
  When the selection step was skipped (no `agent_dependencies:` in crew.yaml), this is
91
92
  identical to today: all agents listed, no Skipped line.
92
93
  5b. **Initialize run folder**: the script names the run — never build the date or the time yourself:
93
- - Run the `pasta` command (see "Output Path Transformation" below). It creates the folder of this run and answers `CAMINHO:OK crews/{name}/output/{run_id}`
94
+ - Run the `pasta` command (see "Output Path Transformation" below). It creates the folder of this run and its record, and answers `CAMINHO:OK crews/{name}/output/{run_id}`
94
95
  - The `run_id` is the last segment of that path: `YYYY-MM-DD-HHmmss` from the computer's clock (e.g. `2026-03-03-143022`; `-2`, `-3` when that folder already exists)
95
96
  - The date of this run, wherever one is asked below, is the first 10 characters of the `run_id`
96
97
  - Never create a folder by command yourself
@@ -265,10 +266,10 @@ root the one-line command of each moment and read the last line (`CAMINHO:OK {pa
265
266
 
266
267
  | Moment | Command |
267
268
  |---|---|
268
- | Start of the run (Initialization, step 5b) | `node _opencrew/core/scripts/caminho.mjs "{name}" pasta` (no `--run`: the script creates the `run_id`) |
269
+ | Start of the run (Initialization, step 5b) | `node _opencrew/core/scripts/caminho.mjs "{name}" pasta --tema "{tema}" --passos {N}` (no `--run`: the script creates the `run_id`) |
269
270
  | Before a step, for its `inputFile` | `node _opencrew/core/scripts/caminho.mjs "{name}" entrada --run "{run_id}" --arquivo "{inputFile}"` |
270
271
  | Before a step writes, for the first `outputFile` of each group | `node _opencrew/core/scripts/caminho.mjs "{name}" saida --run "{run_id}" --arquivo "{outputFile}"` |
271
- | After a step wrote, for each output file | `node _opencrew/core/scripts/caminho.mjs "{name}" conferir --arquivo "{path}"` |
272
+ | After a step wrote, for each output file | `node _opencrew/core/scripts/caminho.mjs "{name}" conferir --arquivo "{path}" --passo {step}` |
272
273
 
273
274
  - **Values** — `{name}`: the crew code. `{inputFile}` / `{outputFile}`: the path as the step
274
275
  declares it (raw, without the run_id). `{path}`: the path `saida` returned. The safe-name rule
@@ -297,6 +298,20 @@ root the one-line command of each moment and read the last line (`CAMINHO:OK {pa
297
298
  this way skips its gate and is listed at the final approval:
298
299
  `{arquivo} — não verificado: a conferência de caminhos não rodou`.
299
300
 
301
+ ### Run record (registro da execução)
302
+
303
+ The scripts keep the record of the run on disk (`crews/{name}/output/{run_id}/execucao.json`): `/opencrew retomar` and the history (`runs.md`) are read from it. `pasta` and `conferir` feed it; you add one command at three moments:
304
+
305
+ | Moment | Command |
306
+ |---|---|
307
+ | A checkpoint was answered and its answer saved | `node _opencrew/core/scripts/execucao.mjs "{name}" marcar --run "{run_id}" --passo {step} --evento checkpoint --resultado {resultado} --nota "{nota}"` |
308
+ | The reviewer gave the verdict (each cycle) | `node _opencrew/core/scripts/execucao.mjs "{name}" marcar --run "{run_id}" --passo {step} --evento revisao --resultado {resultado} --nota "{nota}"` |
309
+ | End of the run, and whenever it is aborted | `node _opencrew/core/scripts/execucao.mjs "{name}" fechar --run "{run_id}" --resultado {resultado} --saida "{saída}"` |
310
+
311
+ - **Values** — `{step}`: the step's number in `pipeline.yaml` (`step:`; without it, its position, from 1) — the same in `conferir --passo`. `{resultado}`: checkpoint → `aprovado` (the user judged something the crew produced and accepted it as it is), `corrigido` (the answer asked for any change) or `pulado` (no judgement: the checkpoint only collected an answer — a topic, a choice — or was skipped); revisao → `aprovado` or `rejeitado`; fechar → `aprovado`, `publicado` (an irreversible step published or sent), `rejeitado` (the review rejected at the last cycle and the user aborted) or `abortado`. `{nota}`: the correction asked or the reason of the rejection — no `--nota` on an approval. `{tema}`: the topic of this run, in a few words; when only a checkpoint reveals it, start with no `--tema` and add `--tema "{tema}"` to that checkpoint's `marcar`. `{N}`: how many steps will run, checkpoints included. `{saída}`: what was produced ("Carrossel 9 slides").
312
+ - **Text on the command line** (`{tema}`, `{nota}`, `{saída}`) — one line between double quotes, only letters (accents included), digits, spaces and `. , : ; - ( ) / ?`; drop every other sign, and omit the option when no text is left.
313
+ - The scripts are the only writers: never read, write or describe `execucao.json` yourself, and never write `runs.md`. A warning `Não consegui gravar o registro desta execução`, or one of these commands not running, never stops the run: tell the user once and go on.
314
+
300
315
  ### For each pipeline step:
301
316
 
302
317
  0. **Agent deselection check** — Read the step's `agent:` frontmatter field.
@@ -365,6 +380,7 @@ root the one-line command of each moment and read the last line (`CAMINHO:OK {pa
365
380
  - **Always include the file path** of any generated content the user needs to review. Example: "Review the content at `crews/{name}/output/{run_id}/v2/content.md` and let me know if it looks good." (the path the script returned)
366
381
  - Wait for user input before proceeding
367
382
  - Save the user's choice/response for the next step
383
+ - Record the answer with the `marcar` command (`--evento checkpoint`, see "Run record") — last thing of the checkpoint, after the memory and the `outputFile` below are written
368
384
  - **Correction → memory, right away**: if the answer corrects something (tone, audience, a term,
369
385
  a fact, a format), write it to `crews/{name}/_memory/memories.md` in the matching section
370
386
  **before the next step** (antes do próximo passo) — not only at the end of the run, which may
@@ -470,7 +486,7 @@ When a step has `on_reject: {step-id}` (a review step):
470
486
  final approval below collects the missing data from the user.
471
487
  3. Track the review cycle count: a **cycle** is one pass of the reviewer. The maximum is
472
488
  `max_review_cycles`, an integer from 1: the one declared where the step declares `on_reject` (the
473
- step frontmatter or its `pipeline.yaml` entry); without it, the one in `crew.yaml`; absent or invalid in both: 3. On every rejection, with or
489
+ step frontmatter or its `pipeline.yaml` entry); without it, the one in `crew.yaml`; absent or invalid in both: 3. After each verdict — once the review file passed `conferir` — run `marcar` (`--evento revisao`, see "Run record"). On every rejection, with or
474
490
  without a block, send the reviewer's feedback to the writer and go back to the referenced step.
475
491
  4. If the last allowed pass also rejects, stop; the status of the last report picks the message, as
476
492
  in item 2 — `VERIFICACAO:BLOQUEADA`: the blocks; any other status: the reviewer's feedback, also
@@ -512,7 +528,7 @@ One script turns the approved files into `crews/{name}/output/{run_id}/entrega/`
512
528
  1b. **Escritório** — if it is on, run `concluir` (see "Escritório" above).
513
529
 
514
530
  2. **Close the run** — read `_opencrew/core/runner/fim-da-execucao.md` completely and follow it, in its
515
- order: update `memories.md`, add the line to `runs.md`, the post-run reflection and the completion
531
+ order: update `memories.md`, close the run with the `fechar` command (the script writes the line of `runs.md`), the post-run reflection and the completion
516
532
  summary with the final menu. Never skip it, and never write the memory or the history from what you
517
533
  remember of it.
518
534
 
@@ -525,7 +541,7 @@ One script turns the approved files into `crews/{name}/output/{run_id}/entrega/`
525
541
  - If a step file is missing, inform the user and suggest running `/opencrew edit {crew}` to fix.
526
542
  - If company.md is empty, stop and redirect to onboarding.
527
543
  - Never continue past a checkpoint without user input.
528
- - When the run is aborted: if the Escritório is on, run `falhar` (see "Escritório" above).
544
+ - When the run is aborted (by the user, by an error, or rejected at the last review cycle): run `fechar` with `abortado` or `rejeitado` (see "Run record") and, if the Escritório is on, run `falhar` (see "Escritório" above). A run that just stopped (the conversation ended) stays open: `/opencrew retomar` finds it.
529
545
 
530
546
  ## Pipeline State
531
547
 
@@ -540,4 +556,4 @@ Track pipeline state in memory during execution:
540
556
  - filtered_steps — the ordered steps that will actually run this execution
541
557
  - missing_dependency — true if the user knowingly ran with a broken dependency
542
558
 
543
- This state does NOT persist to disk — it exists only during the current run.
559
+ This state lives in memory; what `/opencrew retomar` needs is on disk, in the run record (see "Run record").
@@ -6,15 +6,16 @@ import { ACOES } from './nucleo.mjs';
6
6
  export const USO = 'Uso: node _opencrew/core/scripts/caminho.mjs <crew> <ação> --run <id> [opções]';
7
7
 
8
8
  const LISTA = ACOES.join(', ');
9
- const OPCAO = /^--(run|arquivo|secoes|tldr)(?:=(.*))?$/s;
10
- const RUN = /^(?!\.+$)[A-Za-z0-9._-]+$/;
9
+ const OPCAO = /^--(run|arquivo|secoes|tldr|tema|passos|passo)(?:=(.*))?$/s;
10
+ /** O nome de uma execução: letras, dígitos, ponto, sublinhado e hífen (nunca só pontos). */
11
+ export const RUN = /^(?!\.+$)[A-Za-z0-9._-]+$/;
11
12
  const INTEIRO = /^[1-9]\d{0,8}$/;
12
13
 
13
14
  /** Texto que veio da linha de comando e volta numa mensagem: uma linha só, até 200 caracteres. */
14
15
  export const limpar = (valor) => String(valor).replace(/\s+/g, ' ').trim().slice(0, 200);
15
16
 
16
17
  /**
17
- * `argv` → `{ crew, acao, run, arquivo, secoes, tldr }`. Os dois primeiros argumentos soltos são
18
+ * `argv` → `{ crew, acao, run, arquivo, secoes, tldr, tema, passos, passo }`. Os dois primeiros argumentos soltos são
18
19
  * a crew e a ação. Opção vale como `--nome valor` e `--nome=valor`; `--tldr` não leva valor.
19
20
  * Opção ausente fica `undefined`.
20
21
  */
@@ -37,7 +38,7 @@ export function lerArgs(argv) {
37
38
  * caminho já resolvido: é a única ação que não precisa de `--run`.
38
39
  * @returns {string|null} o motivo em PT-BR, ou `null`
39
40
  */
40
- export function erroDeArgumentos({ crew, acao, run, arquivo, secoes }) {
41
+ export function erroDeArgumentos({ crew, acao, run, arquivo, secoes, passos, passo }) {
41
42
  if (!crew) return 'Falta o nome da crew.';
42
43
  if (!acao) return `Falta a ação. Ações: ${LISTA}.`;
43
44
  if (!ACOES.includes(acao)) return `Ação desconhecida: ${limpar(acao)}. Ações: ${LISTA}.`;
@@ -47,5 +48,7 @@ export function erroDeArgumentos({ crew, acao, run, arquivo, secoes }) {
47
48
  if (run !== undefined && !RUN.test(run)) return 'O --run só aceita letras, dígitos, ponto, sublinhado e hífen.';
48
49
  if (acao !== 'pasta' && !arquivo) return MSG.faltaOpcao('--arquivo');
49
50
  if (secoes !== undefined && !INTEIRO.test(secoes)) return 'O --secoes é um número inteiro a partir de 1.';
51
+ if (passos !== undefined && !INTEIRO.test(passos)) return 'O --passos é um número inteiro a partir de 1.';
52
+ if (passo !== undefined && !INTEIRO.test(passo)) return 'O --passo é um número inteiro a partir de 1.';
50
53
  return null;
51
54
  }
@@ -0,0 +1,20 @@
1
+ // Onde fica a crew de um comando (`caminho.mjs`, `execucao.mjs`): uma pasta direta de `crews/`.
2
+ // Spec: fase-r3-runner-em-uso-real.md, §3 (repositório do OpenCrew).
3
+ import path from 'node:path';
4
+ import { MSG, dentroDoProjeto } from '../comum.mjs';
5
+ import { limpar } from './argumentos.mjs';
6
+ import { ehPasta } from './disco.mjs';
7
+
8
+ /**
9
+ * @param {string} raiz a pasta do projeto · @param {string} escrito o nome da crew (`crews/<nome>` também vale)
10
+ * @returns {{ erro: string } | { crew: string }} o erro de uso, ou o nome da pasta da crew
11
+ */
12
+ export function acharCrew(raiz, escrito) {
13
+ if (!ehPasta(path.join(raiz, '_opencrew'))) return { erro: MSG.semRaiz };
14
+ const base = path.resolve(raiz, 'crews');
15
+ const nome = escrito.replace(/^crews[\\/]+/, '');
16
+ if (!dentroDoProjeto(base, nome)) return { erro: MSG.foraDoProjeto(limpar(escrito)) };
17
+ const pasta = path.resolve(base, nome);
18
+ if (path.dirname(pasta) !== base || !ehPasta(pasta)) return { erro: MSG.crewNaoEncontrada(limpar(escrito)) };
19
+ return { crew: path.basename(pasta) };
20
+ }
@@ -1,5 +1,6 @@
1
1
  // O que o `caminho.mjs` faz no disco: lê nomes de pastas, confere se um arquivo tem conteúdo, lê
2
- // um arquivo e cria pastas. Nunca cria, altera nem apaga arquivo.
2
+ // um arquivo e cria pastas. Nunca cria, altera nem apaga arquivo (o registro da execução é gravado
3
+ // por `execucao/registro.mjs`).
3
4
  // Spec: fase-r3-runner-em-uso-real.md, regra 6 (repositório do OpenCrew).
4
5
  import { mkdirSync, readFileSync, readdirSync, statSync } from 'node:fs';
5
6
 
@@ -32,5 +33,5 @@ export function temConteudo(arquivo) {
32
33
 
33
34
  export const lerTexto = (arquivo) => readFileSync(arquivo, 'utf8');
34
35
 
35
- /** Cria a pasta com as pastas-mãe; pasta que já existe não é erro. */
36
- export const criarPasta = (pasta) => { mkdirSync(pasta, { recursive: true }); };
36
+ /** Cria a pasta com as pastas-mãe; pasta que já existe não é erro. @returns {boolean} criou alguma pasta? */
37
+ export const criarPasta = (pasta) => mkdirSync(pasta, { recursive: true }) !== undefined;