@aksp/opencrew 1.9.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.
- package/CHANGELOG.md +58 -0
- package/README.md +88 -4
- package/package.json +1 -1
- package/templates/AGENTS.md +10 -2
- package/templates/_opencrew/.opencrew-version +1 -1
- package/templates/_opencrew/core/best-practices/_catalog.yaml +5 -0
- package/templates/_opencrew/core/best-practices/documento-oficial.md +144 -0
- package/templates/_opencrew/core/modelos/documento-oficial.md +42 -0
- package/templates/_opencrew/core/prompts/design.prompt.md +1 -0
- package/templates/_opencrew/core/prompts/documento.prompt.md +134 -0
- package/templates/_opencrew/core/prompts/entrega.prompt.md +5 -4
- package/templates/_opencrew/core/scripts/documento/argumentos.mjs +50 -0
- package/templates/_opencrew/core/scripts/documento/corpo.mjs +51 -0
- package/templates/_opencrew/core/scripts/documento/estilos.mjs +42 -0
- package/templates/_opencrew/core/scripts/documento/gravar.mjs +44 -0
- package/templates/_opencrew/core/scripts/documento/linha.mjs +58 -0
- package/templates/_opencrew/core/scripts/documento/marcacoes.mjs +55 -0
- package/templates/_opencrew/core/scripts/documento/markdown.mjs +92 -0
- package/templates/_opencrew/core/scripts/documento/pacote.mjs +82 -0
- package/templates/_opencrew/core/scripts/documento/perfil.mjs +70 -0
- package/templates/_opencrew/core/scripts/documento/png.mjs +20 -0
- package/templates/_opencrew/core/scripts/documento/projeto.mjs +60 -0
- package/templates/_opencrew/core/scripts/documento/tabelas.mjs +57 -0
- package/templates/_opencrew/core/scripts/documento/timbre.mjs +64 -0
- package/templates/_opencrew/core/scripts/documento/xml.mjs +95 -0
- package/templates/_opencrew/core/scripts/documento/zip.mjs +86 -0
- package/templates/_opencrew/core/scripts/documento.mjs +150 -0
- package/templates/_opencrew/core/scripts/entrega/canais.mjs +7 -3
- package/templates/_opencrew/core/scripts/entrega/comparar.mjs +2 -2
- package/templates/_opencrew/core/scripts/entrega/copia.mjs +1 -1
- package/templates/_opencrew/core/scripts/entrega/documentos.mjs +104 -0
- package/templates/_opencrew/core/scripts/entrega/gravar.mjs +3 -3
- package/templates/_opencrew/core/scripts/entrega/leiame.mjs +3 -2
- package/templates/_opencrew/core/scripts/entrega/passos.mjs +12 -2
- package/templates/_opencrew/core/scripts/entrega/separar.mjs +3 -0
- package/templates/_opencrew/core/scripts/entregar.mjs +12 -5
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
// (ressalvas, a cópia e "Sobre esta pasta"), no repositório do OpenCrew.
|
|
6
6
|
import { CANAIS, EDITAVEIS, OUTROS } from './canais.mjs';
|
|
7
7
|
import { frasesDePendencia } from './pendencias.mjs';
|
|
8
|
-
import { passosDe } from './passos.mjs';
|
|
8
|
+
import { NAO_EDITE_O_WORD, passosDe } from './passos.mjs';
|
|
9
9
|
|
|
10
10
|
export const TEXTO = {
|
|
11
11
|
vaiPublicar: 'Esta crew publica este canal sozinha. Antes de postar à mão, confira se já saiu.',
|
|
@@ -64,7 +64,8 @@ function secaoDoCanal(d, pasta) {
|
|
|
64
64
|
// Na cópia, o canal que não foi copiado traz só a situação e o que falta.
|
|
65
65
|
if (d.ehCopia && pendencias.length) return secao(CANAIS[pasta], [situacao, ...bloco('Pendências:', pendencias)]);
|
|
66
66
|
const arquivos = d.arquivos.filter((a) => a.pasta === pasta);
|
|
67
|
-
const
|
|
67
|
+
const daPasta = passosDe(pasta, arquivos, pendencias.length > 0, d.ressalvas.has(pasta));
|
|
68
|
+
const passos = daPasta.filter((p) => !d.ehCopia || p !== NAO_EDITE_O_WORD).map((p, i) => `${i + 1}. ${p}`);
|
|
68
69
|
return secao(CANAIS[pasta], [
|
|
69
70
|
...(d.vaiPublicar.includes(pasta) ? [TEXTO.vaiPublicar] : []),
|
|
70
71
|
situacao,
|
|
@@ -7,7 +7,9 @@
|
|
|
7
7
|
export const ANTES_DE_POSTAR = 'Antes de postar, resolva o que está em Pendências. Corrija no arquivo de origem e peça para montar a entrega de novo: o que você mudar nesta pasta se perde.';
|
|
8
8
|
/** O primeiro passo do canal entregue com ressalva. */
|
|
9
9
|
export const CONFIRA_AS_RESSALVAS = 'Antes de postar, confira as ressalvas em "Antes de usar".';
|
|
10
|
-
|
|
10
|
+
/** O passo de `documentos` que só vale na pasta da entrega (a cópia não é refeita). Spec: fase-u3b-documento-word.md, §6. */
|
|
11
|
+
export const NAO_EDITE_O_WORD = 'Não edite o Word dentro desta pasta: ela é refeita a cada entrega. Para mexer, copie o arquivo para outra pasta do projeto.';
|
|
12
|
+
const MARKDOWN ='Este texto está em markdown: se o seu editor não aceitar, ajuste títulos, negrito e links depois de colar.';
|
|
11
13
|
|
|
12
14
|
// Cada passo: [o que o faz aparecer, o texto]. null = sempre que o canal tem arquivo; um tipo de
|
|
13
15
|
// arquivo = só quando a entrega tem arquivo desse tipo no canal; `tipo:um` e `tipo:varios` = só
|
|
@@ -58,6 +60,12 @@ const PASSOS = {
|
|
|
58
60
|
[null, 'Confira e publique.'],
|
|
59
61
|
],
|
|
60
62
|
youtube: [['roteiro', '`youtube/{arquivo}` é o roteiro para gravar: não é texto para colar.']],
|
|
63
|
+
documentos: [
|
|
64
|
+
['documento', 'Abra `documentos/{arquivo}` no Word e confira: cabeçalho, páginas, tabelas e assinaturas.'],
|
|
65
|
+
['documento', NAO_EDITE_O_WORD],
|
|
66
|
+
['documento', 'Para ter um PDF: abra o documento no Word e use Arquivo → Salvar como → PDF.'],
|
|
67
|
+
['documento', 'O Word é uma cópia do texto. O que você mudar nele não volta sozinho: altere o texto e gere de novo.'],
|
|
68
|
+
],
|
|
61
69
|
};
|
|
62
70
|
// "texto": o roteiro e o arquivo que foi inteiro (carrossel em texto, peça não encontrada).
|
|
63
71
|
const TIPOS = { texto: ['roteiro', 'inteiro'] };
|
|
@@ -100,5 +108,7 @@ function doQuadro(pasta, arquivos) {
|
|
|
100
108
|
export function passosDe(pasta, arquivos, comPendencia = false, comRessalva = false) {
|
|
101
109
|
const passos = doQuadro(pasta, arquivos);
|
|
102
110
|
const antes = comPendencia ? ANTES_DE_POSTAR : comRessalva ? CONFIRA_AS_RESSALVAS : null;
|
|
103
|
-
|
|
111
|
+
// Documento não se posta: imprime-se, assina-se, protocola-se.
|
|
112
|
+
const frase = pasta === 'documentos' ? antes?.replace('Antes de postar', 'Antes de usar') : antes;
|
|
113
|
+
return frase && passos.length ? [frase, ...passos] : passos;
|
|
104
114
|
}
|
|
@@ -6,6 +6,7 @@ import path from 'node:path';
|
|
|
6
6
|
import { lerItem } from '../verificar/arquivos.mjs';
|
|
7
7
|
import { semFrontmatter } from '../verificar/leitura.mjs';
|
|
8
8
|
import { EDITAVEIS, OUTROS } from './canais.mjs';
|
|
9
|
+
import { DOCUMENTOS, tipoDoDocumento } from './documentos.mjs';
|
|
9
10
|
import { avisoDeFora, blocosFora } from './fora.mjs';
|
|
10
11
|
import { PRINCIPAL, hashtagsSoltas, pecasDoLeitor } from './leitor.mjs';
|
|
11
12
|
import { pecasDoBlog, pecasDoEmail, pecasDoWhatsapp, tweetsDaThread } from './longas.mjs';
|
|
@@ -82,6 +83,8 @@ async function separarItem(item, itens, p) {
|
|
|
82
83
|
p.avisos.push({ pasta: OUTROS, tela: MSG.semCanal(item.rel) });
|
|
83
84
|
return p.copias.push(copia(item, OUTROS, 'copia'));
|
|
84
85
|
}
|
|
86
|
+
// Documento oficial: vai inteiro, sem procura de peças; `documentos.mjs` converte o texto em Word.
|
|
87
|
+
if (item.canal === DOCUMENTOS) return p.copias.push(copia(item, DOCUMENTOS, tipoDoDocumento(item.abs)));
|
|
85
88
|
const lido = ['.md', '.txt'].includes(extensao(item)) ? await lerItem(item.abs) : null;
|
|
86
89
|
if (lido?.tipo !== 'texto') return p.copias.push(copia(item, item.canal, ehImagem(item) ? 'imagem' : 'copia'));
|
|
87
90
|
const texto = emLf(lido.texto);
|
|
@@ -11,6 +11,8 @@
|
|
|
11
11
|
// --aceitar-pendencias: as pendências deste momento viram ressalvas ("entregar assim mesmo"); a
|
|
12
12
|
// ressalva vale enquanto a pendência dela existir: a que some sai do `ressalvas.json`.
|
|
13
13
|
// --vai-publicar: canal que a crew publica sozinha (pode repetir); o LEIA-ME avisa.
|
|
14
|
+
// Item de formato com a plataforma `documento` (`.md` ou `.txt`) sai em `entrega/documentos/`, em
|
|
15
|
+
// Word, com o perfil de documento oficial do projeto (fase-u3b-documento-word.md, regra 12).
|
|
14
16
|
// Grava em crews/<crew>/output/<run>/: a pasta `entrega/` (refeita do zero a cada chamada, montada
|
|
15
17
|
// em `entrega.tmp/`), `verificacao-entrega.md`, `ressalvas.json` (as pendências aceitas que ainda
|
|
16
18
|
// existem) e `copia.json` (o retrato do que foi copiado, para a comparação seguinte). Fora
|
|
@@ -29,6 +31,7 @@ import { formatarRelatorio, verificar } from './verificar.mjs';
|
|
|
29
31
|
import { USO, lerArgs, lerLista, limpar, runValido } from './entrega/argumentos.mjs';
|
|
30
32
|
import { CANAIS, canalDoFormato, ehCanal, ehDeServico } from './entrega/canais.mjs';
|
|
31
33
|
import { MSG as DESTINO, escolherDestino, validarDestino } from './entrega/destino.mjs';
|
|
34
|
+
import { DOCUMENTOS, converterDocumentos, naoConferidoDoWord } from './entrega/documentos.mjs';
|
|
32
35
|
import { MSG as COPIA, guardar } from './entrega/guardar.mjs';
|
|
33
36
|
import { gravarEntrega } from './entrega/gravar.mjs';
|
|
34
37
|
import { montarLeiame } from './entrega/leiame.mjs';
|
|
@@ -84,15 +87,18 @@ async function classificar(raiz, pedidos) {
|
|
|
84
87
|
async function montar(raiz, args, itens, aceitas) {
|
|
85
88
|
const arquivosDaLista = itens.map((i) => (i.formato ? { arquivo: i.arquivo, formato: i.formato } : i.arquivo));
|
|
86
89
|
const verificacao = await verificar({ raiz, crew: args.crew, arquivos: arquivosDaLista, semPadraoDeBlog: true });
|
|
87
|
-
const
|
|
90
|
+
const separados = await converterDocumentos(raiz, await separar(itens), args.gerarDocx);
|
|
91
|
+
const { arquivos, avisos } = nomear(separados.produtos);
|
|
88
92
|
const todas = pendenciasPorPasta(raiz, itens, verificacao);
|
|
93
|
+
// O texto que não virou Word é pendência de `documentos` (fase-u3b-documento-word.md, regra 12).
|
|
94
|
+
if (separados.pendencias.length) todas.set(DOCUMENTOS, [...(todas.get(DOCUMENTOS) ?? []), ...separados.pendencias]);
|
|
89
95
|
const presentes = new Set([...arquivos.map((a) => a.pasta), ...todas.keys()]);
|
|
90
96
|
const dados = {
|
|
91
97
|
crew: path.basename(path.resolve(raiz, args.crew)), run: args.run, arquivos, avisos,
|
|
92
98
|
...separarPendencias(todas, aceitas, args.aceitar),
|
|
93
99
|
pastas: Object.keys(CANAIS).filter((c) => presentes.has(c)),
|
|
94
100
|
alertas: await alertasDeTamanho(raiz, itens, arquivos, verificacao),
|
|
95
|
-
naoConferido: naoConferido(raiz, itens, verificacao),
|
|
101
|
+
naoConferido: [...naoConferido(raiz, itens, verificacao), ...naoConferidoDoWord(arquivos)],
|
|
96
102
|
vaiPublicar: args.vaiPublicar,
|
|
97
103
|
};
|
|
98
104
|
return { dados, relatorio: `${formatarRelatorio(verificacao)}\n` };
|
|
@@ -137,12 +143,13 @@ async function entregar(raiz, args, itens, escrever) {
|
|
|
137
143
|
|
|
138
144
|
/**
|
|
139
145
|
* @param {string[]} argv
|
|
140
|
-
* @param {object} [deps] `cwd` (a pasta do projeto) e `
|
|
146
|
+
* @param {object} [deps] `cwd` (a pasta do projeto), `escrever` e `gerarDocx` (quem monta o Word
|
|
147
|
+
* de um documento oficial; sem ele, o do `documento.mjs`)
|
|
141
148
|
* @returns {Promise<number>} 0 = a linha `ENTREGA:` saiu (ou `--ajuda`) · 1 = erro de uso, ou erro
|
|
142
149
|
* que impediu a entrega inteira (uma linha em PT-BR, sem linha `ENTREGA:`, nada escrito)
|
|
143
150
|
*/
|
|
144
|
-
export async function main(argv, { cwd = process.cwd(), escrever = (s) => process.stdout.write(`${s}\n`) } = {}) {
|
|
145
|
-
const args = lerArgs(argv);
|
|
151
|
+
export async function main(argv, { cwd = process.cwd(), escrever = (s) => process.stdout.write(`${s}\n`), gerarDocx } = {}) {
|
|
152
|
+
const args = { ...lerArgs(argv), gerarDocx };
|
|
146
153
|
const sair = (...linhas) => linhas.forEach((l) => escrever(l)) ?? 1;
|
|
147
154
|
if (args.ajuda) return sair(USO) && 0;
|
|
148
155
|
const pedidos = lerLista(args.arquivos);
|