@aksp/opencrew 1.8.0 → 1.10.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 (58) hide show
  1. package/CHANGELOG.md +127 -0
  2. package/README.md +133 -16
  3. package/package.json +1 -1
  4. package/src/commands/update.js +9 -3
  5. package/src/lib/blocos.js +7 -3
  6. package/src/lib/resumo.js +3 -0
  7. package/templates/AGENTS.md +11 -2
  8. package/templates/_opencrew/.opencrew-version +1 -1
  9. package/templates/_opencrew/core/best-practices/_catalog.yaml +5 -0
  10. package/templates/_opencrew/core/best-practices/documento-oficial.md +144 -0
  11. package/templates/_opencrew/core/modelos/documento-oficial.md +42 -0
  12. package/templates/_opencrew/core/prompts/design.prompt.md +1 -0
  13. package/templates/_opencrew/core/prompts/discovery.prompt.md +1 -1
  14. package/templates/_opencrew/core/prompts/documento.prompt.md +134 -0
  15. package/templates/_opencrew/core/prompts/entrega.prompt.md +93 -18
  16. package/templates/_opencrew/core/prompts/export.prompt.md +5 -81
  17. package/templates/_opencrew/core/runner.pipeline.md +20 -20
  18. package/templates/_opencrew/core/scripts/documento/argumentos.mjs +50 -0
  19. package/templates/_opencrew/core/scripts/documento/corpo.mjs +51 -0
  20. package/templates/_opencrew/core/scripts/documento/estilos.mjs +42 -0
  21. package/templates/_opencrew/core/scripts/documento/gravar.mjs +44 -0
  22. package/templates/_opencrew/core/scripts/documento/linha.mjs +58 -0
  23. package/templates/_opencrew/core/scripts/documento/marcacoes.mjs +55 -0
  24. package/templates/_opencrew/core/scripts/documento/markdown.mjs +92 -0
  25. package/templates/_opencrew/core/scripts/documento/pacote.mjs +82 -0
  26. package/templates/_opencrew/core/scripts/documento/perfil.mjs +70 -0
  27. package/templates/_opencrew/core/scripts/documento/png.mjs +20 -0
  28. package/templates/_opencrew/core/scripts/documento/projeto.mjs +60 -0
  29. package/templates/_opencrew/core/scripts/documento/tabelas.mjs +57 -0
  30. package/templates/_opencrew/core/scripts/documento/timbre.mjs +64 -0
  31. package/templates/_opencrew/core/scripts/documento/xml.mjs +95 -0
  32. package/templates/_opencrew/core/scripts/documento/zip.mjs +86 -0
  33. package/templates/_opencrew/core/scripts/documento.mjs +150 -0
  34. package/templates/_opencrew/core/scripts/entrega/argumentos.mjs +13 -9
  35. package/templates/_opencrew/core/scripts/entrega/canais.mjs +12 -6
  36. package/templates/_opencrew/core/scripts/entrega/comparar.mjs +104 -0
  37. package/templates/_opencrew/core/scripts/entrega/copia.mjs +138 -0
  38. package/templates/_opencrew/core/scripts/entrega/destino.mjs +98 -0
  39. package/templates/_opencrew/core/scripts/entrega/documentos.mjs +104 -0
  40. package/templates/_opencrew/core/scripts/entrega/fora.mjs +4 -3
  41. package/templates/_opencrew/core/scripts/entrega/gravar.mjs +3 -3
  42. package/templates/_opencrew/core/scripts/entrega/guardar.mjs +60 -0
  43. package/templates/_opencrew/core/scripts/entrega/leiame.mjs +54 -17
  44. package/templates/_opencrew/core/scripts/entrega/leitor.mjs +16 -3
  45. package/templates/_opencrew/core/scripts/entrega/lembrar.mjs +65 -0
  46. package/templates/_opencrew/core/scripts/entrega/passos.mjs +21 -6
  47. package/templates/_opencrew/core/scripts/entrega/pendencias.mjs +16 -6
  48. package/templates/_opencrew/core/scripts/entrega/ressalvas.mjs +78 -0
  49. package/templates/_opencrew/core/scripts/entrega/resumo.mjs +29 -0
  50. package/templates/_opencrew/core/scripts/entrega/retrato.mjs +42 -0
  51. package/templates/_opencrew/core/scripts/entrega/separar.mjs +9 -3
  52. package/templates/_opencrew/core/scripts/entregar.mjs +76 -44
  53. package/templates/_opencrew/core/scripts/verificar/argumentos.mjs +4 -4
  54. package/templates/_opencrew/core/scripts/verificar/entradas.mjs +26 -0
  55. package/templates/_opencrew/core/scripts/verificar/gravacao.mjs +41 -0
  56. package/templates/_opencrew/core/scripts/verificar/relatorio.mjs +10 -3
  57. package/templates/_opencrew/core/scripts/verificar.mjs +17 -27
  58. package/templates/gitignore +1 -0
package/CHANGELOG.md CHANGED
@@ -3,6 +3,133 @@
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.10.0] — 2026-10-07
7
+
8
+ Fase U3b "Documento Word, com perfil de documento oficial" (`specs/fase-u3b-documento-word.md`).
9
+ Chega a quem já usa com um `npx @aksp/opencrew@latest update`; o papel timbrado é criado só quando
10
+ você pede.
11
+
12
+ Ainda não nesta versão: imagem no corpo do texto, link clicável, sumário, nota de rodapé e
13
+ numeração automática; logotipo em JPEG ou SVG; ler ou regravar um modelo `.dotx`; mais de um
14
+ perfil por projeto na entrega; PDF direto (o Word salva como PDF). O resultado foi conferido no
15
+ Word; no LibreOffice e no Google Docs, não.
16
+
17
+ ### Added
18
+ - **Documento Word.** O texto em markdown (`.md` ou `.txt`) vira um arquivo do Word (`.docx`) com
19
+ as mesmas palavras e os mesmos números, na mesma ordem. No chat: `/opencrew documento <arquivo>`
20
+ (ou "Documento Word" no menu). No terminal:
21
+ `node _opencrew/core/scripts/documento.mjs "<arquivo.md>"`. O Word sai ao lado do texto, com o
22
+ mesmo nome; `--saida` escolhe outra pasta ou outro nome. Antes, quem precisava de um documento
23
+ oficial mantinha um script à parte, com o texto dentro do código.
24
+ - **Papel timbrado (perfil de documento oficial).** Um arquivo de texto do projeto,
25
+ `_opencrew/_memory/documento-oficial.md`, guarda o logotipo (PNG), três linhas de cabeçalho, o
26
+ rodapé com "Página X de Y", as margens, a fonte e o tamanho da letra. Na primeira vez a IA
27
+ pergunta se você quer configurar e preenche o arquivo com as suas respostas; `--criar-perfil`
28
+ cria o arquivo a partir do modelo. O `update` não toca nele, e nenhum comando o sobrescreve.
29
+ - **Três marcações para documento.** `::: titulo` e `::: subtitulo` (centralizados),
30
+ `::: quebra-de-pagina` (o anexo começa em página nova) e `::: assinaturas` … `:::` (as linhas
31
+ de assinatura, duas por linha, com o nome e o cargo). Títulos `#`, `##` e `###`, tabelas, listas,
32
+ negrito e itálico saem como estilos do Word.
33
+ - **O texto oficial não muda.** Número de item escrito por você ("1.", "6.1.", "a)", "§ 1º") vai
34
+ como texto: nada é renumerado, reordenado nem corrigido.
35
+ - **Na entrega, a pasta `documentos/`.** O passo com `format: documento-oficial` sai como
36
+ `entrega/documentos/<nome>.docx`, com o papel timbrado do projeto, e o LEIA-ME ganha a seção
37
+ "Documentos", com o que conferir no Word. Sem papel timbrado configurado, a entrega avisa e
38
+ diz como criar. A cópia para a pasta do projeto leva `documentos/`
39
+ junto.
40
+ - **Guia `documento-oficial`** (o 23º guia de melhores práticas): ensina o redator a escrever um
41
+ texto que vira documento — um parágrafo por linha, número escrito à mão, anexo depois da quebra
42
+ de página, assinaturas no fim. Crews novas recebem esse formato no passo cujo resultado é um
43
+ documento para imprimir, assinar ou protocolar.
44
+ - **Avisos de conversão.** O relatório diz o que ficou como texto (imagem, marcação `:::`
45
+ desconhecida, bloco de assinaturas sem o `:::` final) e quantos caracteres inválidos foram
46
+ removidos. Aviso não impede o documento.
47
+
48
+ ### Changed
49
+ - **Um Word que já existe não é trocado em silêncio.** Se há um `.docx` diferente no destino, nada
50
+ é gravado e a IA pergunta antes de substituir (`--substituir`). Igual, byte a byte: nada a fazer.
51
+ - **Perfil com erro não gera documento.** Chave desconhecida, valor fora da faixa, logotipo que
52
+ não existe, não é PNG ou passa de 2 MB: a mensagem diz a linha, e nada é gravado.
53
+ - O menu "Mais opções" ganha "Documento Word".
54
+
55
+ ### Internal
56
+ - `documento.mjs` e os módulos de `scripts/documento/` (sem dependência, sem `node:zlib`, até 200
57
+ linhas cada): zip sem compressão, com CRC-32 próprio e data fixa — o mesmo texto, com o mesmo
58
+ perfil, dá o mesmo arquivo, byte a byte. `modelos/documento-oficial.md` é o modelo do perfil;
59
+ `prompts/documento.prompt.md`, o prompt da rota. O `src/` não mudou; o runner não cresceu (874
60
+ linhas).
61
+ - `AGENTS.md`: a regra 15 cita o `documento.mjs`; a regra 7 diz que abrir o `.docx` no Word não é
62
+ conferido pela porta.
63
+
64
+ ## [1.9.0] — 2026-10-07
65
+
66
+ Fase U3a, fatia 2 "Entrega no projeto" (`specs/fase-u3a2-entrega-no-projeto.md`). Chega a quem já
67
+ usa com um `npx @aksp/opencrew@latest update`, e funciona nas crews que já existem.
68
+
69
+ Ainda não nesta versão: a crew que publica sozinha continua publicando como na 1.8.0 (o publicador
70
+ ainda não lê a pasta da entrega); legenda, post e tweet continuam medidos sem as hashtags no fim
71
+ (só o alerta); documento Word fica para a 1.10.0.
72
+
73
+ ### Added
74
+ - **A entrega vai para uma pasta do seu projeto.** Na primeira entrega de cada crew, a IA pergunta
75
+ "Quer que eu copie o resultado para uma pasta do projeto?". Com a pasta escolhida (por exemplo,
76
+ `Conteudo/Prontos`), cada execução ganha a sua subpasta, `<pasta>/<execução>/`, com o LEIA-ME e
77
+ as pastas dos canais prontos. Antes, a entrega só existia em `crews/<crew>/output/…/entrega/`,
78
+ fora do git, e quem queria guardar copiava à mão.
79
+ - **A pergunta é feita uma vez.** A resposta — também o "não" — fica na linha `entrega.destino` do
80
+ `crew.yaml` da crew; o arquivo anterior é guardado em `crew.yaml.bak`.
81
+ - **Nada do que foi copiado é sobrescrito.** Entregar de novo sem mudança não cria nada; canal que
82
+ ficou pronto depois entra na mesma pasta; se algo já copiado mudou, a entrega nova vai para
83
+ `<execução>-reentrega-2`, ao lado, e o LEIA-ME da anterior avisa. Arquivo seu dentro da cópia
84
+ nunca é tocado: você pode editar a cópia à vontade, porque a entrega seguinte é comparada com o
85
+ que foi copiado, e não com o que você mudou depois.
86
+ - **"Entregar assim mesmo".** Quando um canal não está pronto, a crew oferece três saídas: corrigir
87
+ agora, entregar assim mesmo ou deixar para depois. Em "entregar assim mesmo", o que falta fica
88
+ escrito como ressalva no começo do LEIA-ME, o canal aparece como "Pronto, com ressalva" e é
89
+ copiado com os outros. Pendência nova depois do aceite pede novo aceite — também a que foi
90
+ resolvida e voltou.
91
+ - **Legenda de Instagram sem marcador.** Arquivo de legenda que é só o texto, pronto para colar,
92
+ sai como `instagram/legenda.txt`, com um aviso para conferir e com o alerta de tamanho. Antes, o
93
+ arquivo ia inteiro, sem ser medido.
94
+ - **Mudar a pasta da cópia depois.** Peça à IA ("muda a pasta de entrega", "não quero mais cópia",
95
+ "volta a copiar"): ela refaz a entrega da última execução e grava a resposta nova.
96
+ - **"Não tenho esse dado".** Na aprovação final, se você não tem a informação de um `[PREENCHER]`,
97
+ a crew não insiste e não inventa: deixa o `[PREENCHER]` no texto e você decide na entrega.
98
+
99
+ ### Changed
100
+ - **PDF e "posts formatados" deixaram de ser gerados.** O PDF era prometido e o método não
101
+ funcionava; o "post formatado" foi substituído pela entrega por canal. Para ter um PDF, abra o
102
+ arquivo e use Imprimir → Salvar como PDF (o LEIA-ME ensina). Crew antiga com um passo de
103
+ `format: pdf` ou `format: formatted-post`: a execução avisa que o formato não é mais gerado e o
104
+ passo grava o texto em markdown (`.md`); nenhum `.pdf` é criado. O CSV continua.
105
+ - **Canal que não está pronto não é copiado para o projeto.** Ele continua em `entrega/`, marcado
106
+ como "Não está pronto", e entra na cópia quando ficar pronto ou quando você aceitar a ressalva.
107
+ - **"Corrigir agora" corrige no arquivo de origem**, verifica o texto de novo e só então monta a
108
+ entrega. Antes, a correção podia ser feita sem nova verificação.
109
+ - **`[PREENCHER]` aparece no relatório como "✏️ A preencher"**, e não mais como "❌ Bloqueio"; o
110
+ resumo conta à parte ("1 a preencher"). O que impede a entrega não mudou: texto com `[PREENCHER]`
111
+ continua "Não está pronto" até você preencher ou aceitar.
112
+ - No LEIA-ME, o aviso de trecho que ficou fora do texto para colar diz em qual arquivo de origem
113
+ ele está.
114
+ - No laço de revisão, "Aceitar assim mesmo" diz que a escolha fica registrada na entrega.
115
+ - **`update` em instalação que não terminou** (`_opencrew/core` sem o registro de versão): não
116
+ altera nada e pede `npx @aksp/opencrew init`, que conclui. Antes, atualizava mostrando a versão
117
+ "unknown".
118
+
119
+ ### Fixed
120
+ - **O relatório de cada ciclo de revisão é gravado pelo verificador**
121
+ (`verificacao-ciclo-N.md`). Antes, a IA copiava a saída à mão e podia truncar.
122
+ - **`.gitignore` com um marcador do bloco sem o par** (só `# opencrew:start` ou só
123
+ `# opencrew:end`): o `update` guarda o arquivo como estava em `.opencrew-backup/<data>/`, põe um
124
+ bloco completo no fim e lista a cópia. Nenhuma linha sua é apagada.
125
+
126
+ ### Internal
127
+ - O bloco do `.gitignore` começa por `# gerenciado pelo OpenCrew: suas linhas ficam fora deste
128
+ bloco` (o primeiro `update` regrava só o bloco).
129
+ - `entregar.mjs` ganha `--destino`, `--lembrar-destino` e `--aceitar-pendencias`; `verificar.mjs`
130
+ ganha `--relatorio`; módulos novos em `scripts/entrega/` e `scripts/verificar/` (sem dependência,
131
+ até 200 linhas cada). `export.prompt.md` fica só com o CSV. O runner não cresceu (874 linhas).
132
+
6
133
  ## [1.8.0] — 2026-10-07
7
134
 
8
135
  Fase U3a, fatia 1 "Pasta de entrega" (`specs/fase-u3a1-pasta-de-entrega.md`). Chega a quem já usa
package/README.md CHANGED
@@ -30,11 +30,15 @@ dentro da sua IDE.**
30
30
  rejeita o mesmo erro 3 vezes, vira Regra de Ouro automática.
31
31
  - 📦 **Templates prontos** — blog semanal, Instagram carrossel, newsletter
32
32
  mensal, lançamento de produto. Comece em 2 minutos.
33
- - 📤 **Exportação multi-formato** — PDF, CSV e posts formatados por plataforma,
34
- sem abrir editor nenhum.
33
+ - 📤 **Tabelas em CSV** — as tabelas de um resultado saem em CSV, prontas para a planilha.
35
34
  - 📬 **Entrega por canal** — depois de aprovar, você encontra a pasta `entrega/`: uma pasta por
36
35
  canal (Instagram, LinkedIn, blog, e-mail, WhatsApp, X/Twitter, YouTube), o texto pronto para
37
36
  colar, as imagens e um `LEIA-ME.md` com o passo a passo. O que não está pronto fica marcado.
37
+ - 📁 **Entrega no seu projeto** — a crew pergunta uma vez onde guardar e copia a entrega para uma
38
+ pasta do seu projeto, uma subpasta por execução, sem sobrescrever nada.
39
+ - 📄 **Documento Word em papel timbrado** — ata, ofício, declaração: o texto em markdown vira um
40
+ arquivo do Word com as mesmas palavras, o seu logotipo no cabeçalho, "Página X de Y" no rodapé
41
+ e as linhas de assinatura. Um comando: `/opencrew documento <arquivo>`.
38
42
  - 🎛️ **Seleção inteligente de agentes** — o sistema analisa seu pedido e
39
43
  sugere quais agentes são necessários para aquela tarefa. Você confirma ou
40
44
  ajusta com um clique. Agentes pulados não gastam tokens naquele run.
@@ -180,10 +184,11 @@ meu-projeto/
180
184
  │ │ ├── runner.pipeline.md ← executor de pipeline
181
185
  │ │ ├── skills.engine.md ← gerenciador de skills
182
186
  │ │ ├── architect.agent.yaml ← definição do Arquiteto
183
- │ │ ├── best-practices/ ← 22 guias de melhores práticas + _catalog.yaml
184
- │ │ ├── scripts/ ← verificador, conferência de fontes, caminhos, entrega e os scripts do Escritório
187
+ │ │ ├── best-practices/ ← 23 guias de melhores práticas + _catalog.yaml
188
+ │ │ ├── scripts/ ← verificador, conferência de fontes, caminhos, entrega, documento Word e os scripts do Escritório
189
+ │ │ ├── modelos/ ← modelo do perfil de documento oficial (papel timbrado)
185
190
  │ │ ├── escritorio/ ← página do Escritório ao vivo (abre com /opencrew dashboard)
186
- │ │ └── prompts/ ← 14 prompts de fase (discovery, design, build, entrega, etc.)
191
+ │ │ └── prompts/ ← 15 prompts de fase (discovery, design, build, entrega, documento, etc.)
187
192
  │ ├── agents/ ← 5 agentes base compartilhados
188
193
  │ │ ├── researcher.agent.md
189
194
  │ │ ├── copywriter.agent.md
@@ -192,14 +197,15 @@ meu-projeto/
192
197
  │ │ └── strategist.agent.md
193
198
  │ ├── _memory/
194
199
  │ │ ├── company.md ← perfil da sua empresa (onboarding)
195
- │ │ └── preferences.md ← idioma, tier padrão, Escritório ligado ou desligado
200
+ │ │ ├── preferences.md ← idioma, tier padrão, Escritório ligado ou desligado
201
+ │ │ └── documento-oficial.md ← seu papel timbrado (só existe depois que você pede; veja "Documento Word")
196
202
  │ └── .opencrew-version
197
203
  │
198
204
  ├── crews/ ← suas crews vivem aqui
199
205
  │ ├── blog-semanal/ ← template: blog semanal
200
206
  │ │ └── output/<execução>/ ← criada a cada execução
201
207
  │ │ ├── v1/ v2/ … ← o que cada passo gravou
202
- │ │ └── entrega/ ← o que você usa: LEIA-ME.md + uma pasta por canal
208
+ │ │ └── entrega/ ← o que você usa: LEIA-ME.md + uma pasta por canal (copiada para a pasta do projeto que você escolher)
203
209
  │ ├── instagram-carrossel/ ← template: Instagram carrossel
204
210
  │ ├── newsletter-mensal/ ← template: newsletter
205
211
  │ └── lancamento-produto/ ← template: lançamento
@@ -230,6 +236,7 @@ entrega/
230
236
  ├── whatsapp/ ← mensagem.txt
231
237
  ├── twitter/ ← tweet.txt (na thread: tweet-1.txt, tweet-2.txt…)
232
238
  ├── youtube/ ← o roteiro
239
+ ├── documentos/ ← o Word (.docx) de cada texto de formato documento-oficial
233
240
  ├── outros/ ← arquivo sem canal (proposta, minuta, relatório), como está
234
241
  └── editaveis/ ← o HTML dos slides, para quem quiser ajustar
235
242
  ```
@@ -239,26 +246,129 @@ Só aparecem as pastas que a execução tem.
239
246
  - **Texto pronto para colar.** Os `.txt` saem sem `#`, `**`, rótulos nem recados internos, com as
240
247
  hashtags no fim. Com mais de uma peça do mesmo tipo, os arquivos são numerados (`post-1.txt`,
241
248
  `post-2.txt`).
242
- - **O `LEIA-ME.md` diz o que fazer.** Cada canal tem a situação ("Pronto" ou "Não está pronto"),
243
- os arquivos, de onde cada um veio e os passos, numerados. "Antes de usar" junta o que falta;
244
- "O que não foi conferido" lembra o que ninguém mediu (links e fatos, texto dentro das imagens,
245
- aparência final em cada rede).
246
- - **O que não está pronto fica marcado.** Sobrou um `[PREENCHER]` ou um texto acima do limite? O
247
- canal aparece como "Não está pronto" e a crew pergunta se você quer corrigir agora ou seguir
248
- assim.
249
+ - **O `LEIA-ME.md` diz o que fazer.** Cada canal tem a situação ("Pronto", "Pronto, com ressalva"
250
+ ou "Não está pronto"), os arquivos, de onde cada um veio e os passos, numerados. "Antes de usar"
251
+ junta o que falta e o que foi entregue com ressalva; "O que não foi conferido" lembra o que
252
+ ninguém mediu (links e fatos, texto dentro das imagens, aparência final em cada rede).
253
+ - **O que não está pronto fica marcado, e você escolhe.** Sobrou um `[PREENCHER]` ou um texto
254
+ acima do limite? O canal aparece como "Não está pronto" e a crew oferece três saídas:
255
+ 1. **Corrigir agora** — ela ajusta no arquivo de origem, verifica e monta a entrega de novo.
256
+ 2. **Entregar assim mesmo** — o que falta fica escrito como ressalva no começo do LEIA-ME, e o
257
+ canal passa a "Pronto, com ressalva".
258
+ 3. **Deixar para depois** — o canal fica como "Não está pronto" e não é copiado para o projeto.
259
+ Quando o dado existir, peça a entrega dessa execução de novo.
260
+ - **Não tem o dado na hora?** Na aprovação final, diga "não tenho esse dado": a crew não insiste e
261
+ não inventa — o `[PREENCHER]` fica no texto e você decide na entrega.
249
262
  - **Arquivo sem canal vai para `outros/`**, inteiro e com o nome original: nada some.
250
- - **A pasta é refeita a cada entrega e fica fora do git.** O que você editar ali se perde; para
251
- guardar, copie a pasta para outro lugar do projeto.
263
+ - **A pasta `entrega/` é refeita a cada entrega e fica fora do git.** O que você editar ali se
264
+ perde: o que é para guardar está na cópia do seu projeto (abaixo).
252
265
  - **Execução antiga?** Peça à IA: "monte a entrega da execução X da crew Y". Ela lista os
253
266
  arquivos, pede o seu "sim" e monta a pasta. Funciona em crews criadas antes da 1.8.0, depois
254
267
  do `update`.
255
268
 
269
+ ### A cópia no seu projeto
270
+
271
+ Na primeira entrega de cada crew, a IA pergunta: "Quer que eu copie o resultado para uma pasta do
272
+ projeto?". Se você disser uma pasta (por exemplo, `Conteudo/Prontos`), a crew copia a entrega para
273
+ uma pasta do seu projeto, uma subpasta por execução: `<pasta>/<execução>/`, com o `LEIA-ME.md` e
274
+ as pastas dos canais prontos.
275
+
276
+ - **A pergunta é feita uma vez por crew.** A resposta — também o "não" — fica na linha
277
+ `entrega.destino` do `crew.yaml` da crew (o arquivo anterior fica em `crew.yaml.bak`). Para
278
+ mudar depois, peça à IA ou edite essa linha.
279
+ - **Nada é sobrescrito.** Entregar de novo sem mudança não cria nada. Canal que ficou pronto
280
+ depois entra na mesma pasta. Se algo que já foi copiado mudou, a entrega nova vai para
281
+ `<execução>-reentrega-2` (depois `-3`…), ao lado, e a anterior fica como estava, com um aviso no
282
+ LEIA-ME dela. O que você editar ou guardar na cópia continua lá, e editar a cópia não faz a
283
+ entrega seguinte virar reentrega.
284
+ - **Só vai o que está pronto.** Canal "Não está pronto" fica fora da cópia, a menos que você
285
+ escolha "Entregar assim mesmo".
286
+ - **A pasta fica dentro do projeto**, fora de `_opencrew/`, `crews/`, `skills/`, `.git/` e
287
+ `node_modules/`; se não existe, é criada. Se ela entra no git, a escolha é sua.
288
+
256
289
  A entrega não gera PDF nem imagem: `artigo.md`, `corpo.md` e os roteiros saem em markdown, e o
257
290
  LEIA-ME ensina a salvar como PDF pelo "Imprimir" do seu editor. O LEIA-ME e os nomes dos arquivos
258
291
  são sempre em português.
259
292
 
260
293
  ---
261
294
 
295
+ ## Documento Word
296
+
297
+ Ata, ofício, declaração, contrato: quando o resultado é um documento para imprimir, assinar ou
298
+ protocolar, o OpenCrew transforma o texto em markdown num arquivo do Word (`.docx`) com **as
299
+ mesmas palavras e os mesmos números, na mesma ordem**. Você escreve (ou a crew escreve) o texto;
300
+ um comando gera o documento.
301
+
302
+ **Como gerar:** no chat da sua IDE, digite `/opencrew documento Atas/ata.md` — ou escolha
303
+ "Documento Word" em "Mais opções" do menu. O Word sai ao lado do texto, com o mesmo nome
304
+ (`Atas/ata.docx`), e a IA mostra o relatório: onde gravou, qual papel timbrado usou e os avisos.
305
+ Também funciona direto no terminal, na pasta do projeto:
306
+
307
+ ```bash
308
+ node _opencrew/core/scripts/documento.mjs "Atas/ata.md"
309
+ node _opencrew/core/scripts/documento.mjs "Atas/ata.md" --saida "Documentos/Prontos"
310
+ node _opencrew/core/scripts/documento.mjs --criar-perfil # cria o arquivo do papel timbrado
311
+ ```
312
+
313
+ **Papel timbrado.** Na primeira vez, a IA pergunta se você quer configurar o papel timbrado do
314
+ projeto. Com o "sim", ela cria o perfil de documento oficial em
315
+ `_opencrew/_memory/documento-oficial.md`, pergunta o logotipo, as linhas do cabeçalho e o rodapé
316
+ e preenche o arquivo. É um arquivo de texto, seu, que o `update` nunca toca. Nele ficam:
317
+
318
+ - o logotipo (um PNG de até 2 MB, dentro do projeto) e a largura dele;
319
+ - três linhas de cabeçalho (nome da organização, registro, site e contato);
320
+ - o texto do rodapé e o "Página X de Y";
321
+ - as margens, a fonte e o tamanho da letra.
322
+
323
+ Com o "não", o documento sai sem timbre, com as margens padrão e "Página X de Y" no rodapé. É um
324
+ perfil por projeto; mudar o perfil não muda os documentos já gerados.
325
+
326
+ **Como escrever o texto.** Markdown comum, um parágrafo por linha, com três marcações a mais:
327
+
328
+ ```
329
+ ::: titulo ATA DA REUNIÃO DA DIRETORIA
330
+ ::: subtitulo Realizada em 5 de maio de 2026
331
+
332
+ # I. Abertura
333
+ Aos 5 dias do mês de maio de 2026, reuniu-se a diretoria.
334
+
335
+ ::: assinaturas
336
+ Ana Lima | Presidente
337
+ Rui Sá | Secretário
338
+ :::
339
+
340
+ ::: quebra-de-pagina
341
+ ::: titulo ANEXO I — CALENDÁRIO
342
+ ```
343
+
344
+ - `::: titulo` e `::: subtitulo` saem centralizados; `#`, `##` e `###` viram os títulos das
345
+ seções; tabela vira tabela; `- item` vira lista com marcador.
346
+ - `::: quebra-de-pagina` começa uma página nova (para o anexo); `::: assinaturas`, uma linha
347
+ `Nome | Cargo` por pessoa e `:::` para fechar montam as linhas de assinatura.
348
+ - **Os números são os seus.** "1.", "6.1.", "a)" e "§ 1º" vão como texto, do jeito que você
349
+ escreveu: nada é renumerado, reordenado nem corrigido.
350
+ - **Nada é trocado sem você saber.** Se já existe um Word diferente com esse nome (você pode tê-lo
351
+ editado), nada é gravado: a IA pergunta antes de substituir.
352
+ - **Avisos de conversão.** O relatório diz o que não coube no documento e ficou como texto: imagem,
353
+ marcação `:::` desconhecida, bloco de assinaturas sem o `:::` final. Perfil com erro (chave
354
+ desconhecida, logotipo que não existe) não gera documento: a mensagem diz a linha.
355
+ - **O Word é uma cópia do texto.** O que você mudar no Word não volta para o texto: altere o texto
356
+ e gere de novo. Para ter um PDF, abra o documento no Word e use Salvar como PDF.
357
+
358
+ **Dentro de uma crew.** O passo cujo resultado é um documento usa `format: documento-oficial` (o
359
+ guia que ensina o redator a escrever assim). Na entrega, esse texto vira
360
+ `entrega/documentos/<nome>.docx`, com o papel timbrado do projeto, e o LEIA-ME diz o que conferir.
361
+ Crews novas já nascem assim; numa crew antiga, acrescente `format: documento-oficial` ao passo.
362
+
363
+ **O que não faz.** Não põe imagem no corpo do texto, link clicável, sumário, nota de rodapé nem
364
+ numeração automática; o logotipo é só PNG; tamanhos e cores dos títulos são fixos; não lê nem
365
+ regrava um modelo `.dotx`. Os testes conferem a estrutura do arquivo; como ele fica na página,
366
+ você confere no Word. No LibreOffice e no Google Docs o resultado não foi conferido.
367
+
368
+ Quem já usa o OpenCrew recebe o documento Word com um `npx @aksp/opencrew@latest update`.
369
+
370
+ ---
371
+
262
372
  ## Escritório ao vivo
263
373
 
264
374
  Quer ver a equipe trabalhando? O **Escritório** é uma página em pixel-art, aberta no navegador,
@@ -323,6 +433,12 @@ o que você fez:
323
433
  copiou. Essa pasta fica fora do git (entra no bloco do `.gitignore`). No primeiro `update` para
324
434
  a 1.6.3 há cópia do `.gitignore` mesmo sem edição sua: as versões anteriores não registravam o
325
435
  bloco.
436
+ - **O `.gitignore` tem um marcador do bloco sem o par** (só `# opencrew:start` ou só
437
+ `# opencrew:end`)? Nenhuma linha sua é apagada: o `update` guarda o arquivo como estava e põe
438
+ um bloco completo no fim. O bloco começa por um comentário que diz que ele é do OpenCrew: as
439
+ suas linhas ficam fora dele.
440
+ - **A instalação anterior parou no meio?** O `update` não altera nada e pede para você rodar
441
+ `npx @aksp/opencrew init`, que conclui a instalação sem apagar o que já existe.
326
442
  - **Apagou um modelo de crew ou um skill do catálogo?** Ele volta no `update`, e a saída diz o
327
443
  que foi entregue de novo.
328
444
  - **Removeu o servidor Playwright do `.mcp.json`?** O `update` o entrega uma única vez; se você
@@ -380,6 +496,7 @@ npx @aksp/opencrew update --check
380
496
  | `/opencrew settings` | Altera preferências (idioma, tier, Escritório) |
381
497
  | `/opencrew dashboard` | Liga e abre o Escritório ao vivo (a equipe trabalhando, no navegador) |
382
498
  | `/opencrew dashboard off` | Desliga o Escritório |
499
+ | `/opencrew documento <arquivo>` | Transforma um texto (`.md` ou `.txt`) em documento Word, com o papel timbrado do projeto |
383
500
  | `/opencrew show-company` | Mostra o perfil da empresa |
384
501
  | `/opencrew edit-company` | Reconfigura o perfil da empresa |
385
502
  | `/opencrew help` | Mostra a lista de comandos |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aksp/opencrew",
3
- "version": "1.8.0",
3
+ "version": "1.10.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -9,7 +9,7 @@ import { detectInstalledIdes } from '../lib/deteccao.js';
9
9
  import { withoutLegacy } from '../lib/legado.js';
10
10
  import { updateMcp } from '../lib/mcp.js';
11
11
  import { compareVersions, installedVersion, findLeftovers } from '../lib/migrations.js';
12
- import { say, recreatedLines, updateSummary, UNTOUCHED } from '../lib/resumo.js';
12
+ import { say, recreatedLines, updateSummary, UNTOUCHED, INTERRUPTED } from '../lib/resumo.js';
13
13
  import { c, log, info, ok, warn, err, step } from '../lib/ui.js';
14
14
 
15
15
  const tpl = (...p) => path.join(templatesDir, ...p);
@@ -39,7 +39,13 @@ export async function update(opts = {}) {
39
39
  return;
40
40
  }
41
41
 
42
- const current = (await installedVersion(target)) ?? 'unknown';
42
+ // No stamp = an install that did not finish: nothing is written or stamped (rule 31).
43
+ const current = await installedVersion(target);
44
+ if (!current) {
45
+ err(INTERRUPTED);
46
+ process.exitCode = 1;
47
+ return;
48
+ }
43
49
  log(`\n${c.bold(c.cyan('opencrew update'))}`);
44
50
  log(c.dim(`Installed: ${current} → Package: ${version}\n`));
45
51
  if (canApply(opts, current, version)) await apply(target, version);
@@ -47,7 +53,7 @@ export async function update(opts = {}) {
47
53
 
48
54
  /** `--check` only reports, and a package older than the workspace stops: false = write nothing. */
49
55
  function canApply(opts, current, version) {
50
- const newer = current !== 'unknown' && compareVersions(current, version) > 0;
56
+ const newer = compareVersions(current, version) > 0;
51
57
  if (opts.check) {
52
58
  if (current === version) ok(`Up to date (v${version}).`);
53
59
  else if (newer) info(`A versão instalada (v${current}) é mais nova que este pacote (v${version}).`);
package/src/lib/blocos.js CHANGED
@@ -70,11 +70,14 @@ function planBlock(file, text, marked) {
70
70
  const block = bytesOf(marked).replace(/\n/g, eol);
71
71
  const ranges = blockRanges(text, file);
72
72
  if (!ranges.length) {
73
+ // A marker left alone (its pair deleted by hand): the block still goes in whole, and the
74
+ // file as it was is copied first (spec U3a-2, rule 30).
75
+ const orphan = markersOf(file).some((marker) => text.includes(marker));
73
76
  const bom = text.startsWith(BOM) ? BOM : '';
74
77
  const added = AT_END.has(file)
75
78
  ? `${text.replace(/[ \t\r\n]+$/, '')}${eol}${eol}${block}${eol}`
76
79
  : `${bom}${block}${eol}${eol}${text.slice(bom.length).replace(/^[ \t\r\n]+/, '')}`;
77
- return { action: 'added', text: added, hashes: [] };
80
+ return { action: 'added', text: added, hashes: [], orphan };
78
81
  }
79
82
  const hashes = ranges.map(([from, to]) => hashOf(Buffer.from(text.slice(from, to), 'latin1').toString('utf8')));
80
83
  if (hashes.every((h) => h === hashOf(marked))) return { action: 'kept', hashes };
@@ -85,7 +88,8 @@ function planBlock(file, text, marked) {
85
88
  * Put `content` between the opencrew markers of `file` (path relative to the project root,
86
89
  * with `/`) and record the block in `ctx.files`.
87
90
  * - no file → `created`; file with no block → `added` at the top (at the end in .gitignore
88
- * and .env.example), the user's content kept, no copy;
91
+ * and .env.example), the user's content kept, no copy — unless a marker was left alone
92
+ * in it: then the whole file is copied first;
89
93
  * - block equal to the new one → `kept`, nothing written;
90
94
  * - otherwise → `updated`: only the block is rewritten, in the line ending of the file. The
91
95
  * whole file is copied first unless the block is exactly what the manifest recorded.
@@ -102,7 +106,7 @@ export async function deliverBlock(ctx, file, content) {
102
106
  const edited = plan.action === 'updated' && !plan.hashes.every((h) => h === record);
103
107
  // A UTF-16 file cannot take a UTF-8 block without damage: the whole file is copied first.
104
108
  const risky = raw && plan.text !== undefined && isUtf16(raw);
105
- const copied = (edited || risky) && (await backupFile(ctx, file));
109
+ const copied = (edited || risky || plan.orphan) && (await backupFile(ctx, file));
106
110
  if (plan.text !== undefined) {
107
111
  await fs.mkdir(path.dirname(dest), { recursive: true });
108
112
  await fs.writeFile(dest, Buffer.from(plan.text, 'latin1'));
package/src/lib/resumo.js CHANGED
@@ -15,6 +15,9 @@ export const UNTOUCHED = 'Não foram alterados: as crews que você criou, `_open
15
15
  /** `init` in a workspace that is already installed (rule 15). */
16
16
  export const ALREADY_INSTALLED = 'Para atualizar, rode `npx @aksp/opencrew@latest update`. Não apague `_opencrew/` para reinstalar: a pasta guarda a sua memória (`_opencrew/_memory/`) e as suas best-practices (`_opencrew/best-practices.local/`).';
17
17
 
18
+ /** `update` over `_opencrew/core` with no version stamp (spec U3a-2, rule 31). */
19
+ export const INTERRUPTED = 'A instalação anterior não terminou. Rode `npx @aksp/opencrew init` para concluir.';
20
+
18
21
  const NO_BRIDGES = 'Nenhuma ponte de IDE encontrada: nada a atualizar. Para criar a ponte de uma IDE: `npx @aksp/opencrew@latest init --repair-bridges --ide=<id>`.';
19
22
  const LEAK_REMOVED = 'CLAUDE.md: removi a seção de STATUS.md que as versões 1.4.0 e 1.4.1 gravaram por engano.';
20
23
  const FIRST_PROTECTED = 'Primeira atualização com proteção: sem registro anterior, guardamos tudo o que diferia. Daqui em diante, só o que você editar.';
@@ -10,6 +10,7 @@ On activation, perform these steps IN ORDER:
10
10
  1. Read the company context file: `{project-root}/_opencrew/_memory/company.md`
11
11
  2. Read the preferences file: `{project-root}/_opencrew/_memory/preferences.md`
12
12
  3. Check if company.md is empty or contains only the template — if so, trigger ONBOARDING
13
+ (except for `/opencrew documento` and the `
13
14
  4. Otherwise, display the MAIN MENU
14
15
 
15
16
  ## Onboarding Flow (first time only)
@@ -36,7 +37,10 @@ numbered list and ask the user to reply with a number.
36
37
  **Primary menu:** Create a new crew · Run an existing crew · My crews ·
37
38
  More options
38
39
 
39
- **More options:** Skills · Company profile · Settings & Help
40
+ **More options:** Skills · Documento Word · Company profile · Settings & Help
41
+
42
+ "Documento Word" turns a text file of the project into a Word document: load
43
+ `_opencrew/core/prompts/documento.prompt.md`, which asks for the file.
40
44
 
41
45
  ## Command Routing
42
46
 
@@ -60,8 +64,10 @@ Route input to the matching action:
60
64
  | `/opencrew settings` | Show/edit preferences.md |
61
65
  | `/opencrew dashboard` | Turn on and open the Escritório (live view) — see "Dashboard (Optional)" |
62
66
  | `/opencrew dashboard off` | Turn the Escritório off — see "Dashboard (Optional)" |
67
+ | `/opencrew documento <arquivo>` | Load `_opencrew/core/prompts/documento.prompt.md` → turn that text file (`.md` or `.txt`) into a Word document (`.docx`) |
63
68
  | `/opencrew reset` | Confirm and reset all configuration |
64
69
  | Request to deliver a run that already ended ("monte a entrega da execução …") | Load `_opencrew/core/prompts/entrega.prompt.md` → build the `entrega/` folder of that run |
70
+ | Request to change where the delivery is copied ("muda a pasta de entrega", "não quero mais cópia", "volta a copiar") | Load `_opencrew/core/prompts/entrega.prompt.md` → "Changing the folder later" |
65
71
  | Natural language about crews | Infer intent and route accordingly |
66
72
 
67
73
  ## Loading Agents
@@ -123,10 +129,13 @@ and touch nothing else: stop no process, delete no file.
123
129
  see `_opencrew/core/runner.pipeline.md`
124
130
  - Exception: the delivery folder (`entrega/`) — its folder names, file names and the `LEIA-ME.md`
125
131
  are written by a script in fixed PT-BR, whatever the user's language
132
+ - Exception: the report of the Word document script (`documento.mjs`) and the "Página X de Y" of
133
+ the footer it writes are fixed PT-BR too
126
134
 
127
135
  ## Critical Rules
128
136
 
129
- - NEVER skip the onboarding if company.md is not configured
137
+ - NEVER skip the onboarding if company.md is not configured (the Word document route is the only
138
+ exception: it does not use the company context)
130
139
  - ALWAYS load company context before running any crew
131
140
  - ALWAYS present checkpoints to the user — never skip them
132
141
  - ALWAYS save outputs to the crew's output directory
@@ -1 +1 @@
1
- 1.8.0
1
+ 1.10.0
@@ -114,3 +114,8 @@ catalog:
114
114
  name: "WhatsApp Broadcast"
115
115
  whenToUse: "Creating agents that produce WhatsApp broadcast messages or conversational marketing content."
116
116
  file: whatsapp-broadcast.md
117
+
118
+ - id: documento-oficial
119
+ name: "Documento oficial (Word)"
120
+ whenToUse: "Creating agents that produce a document to print, sign or file (minutes, official letter, statement, contract, formal report) that becomes a Word file."
121
+ file: documento-oficial.md