@fontdata/ai-harness 3.2.2 → 3.2.3
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-plugin/plugin.json +2 -2
- package/README.md +2 -1
- package/dist/doctor/checks.js +10 -4
- package/dist/update/update.js +24 -4
- package/package.json +1 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fontdata",
|
|
3
|
-
"version": "3.2.
|
|
3
|
+
"version": "3.2.3",
|
|
4
4
|
"mcpServers": {
|
|
5
|
-
"banco_dados": { "command": "npx", "args": ["-y", "@fontdata/ai-harness@3.2.
|
|
5
|
+
"banco_dados": { "command": "npx", "args": ["-y", "@fontdata/ai-harness@3.2.3", "banco-dados-mcp"] }
|
|
6
6
|
},
|
|
7
7
|
"description": "Harness de engenharia com IA da Fontdata para Claude Code",
|
|
8
8
|
"author": { "name": "Fontdata" },
|
package/README.md
CHANGED
|
@@ -249,7 +249,8 @@ também acionado pelo modelo quando o pedido combina.
|
|
|
249
249
|
- `/harness` **(skill)** — conduz o setup em etapas (ideia, contexto, ignores, plano do start, scaffold, peças do harness, auto-tag e execução); `/harness <etapa>` roda uma etapa isolada
|
|
250
250
|
|
|
251
251
|
O padrão de comentários não é um comando: a rule, o hook e a catraca do legado vêm do `init` e do `update`. O
|
|
252
|
-
`update` também o instala em projetos cujo lock é anterior a ele
|
|
252
|
+
`update` também o instala em projetos cujo lock é anterior a ele; um hook próprio que já existe, de versão antiga ou
|
|
253
|
+
adaptado, é mantido e só entra no lock. Para recusar, use `--sem-comentarios` no `init` ou
|
|
253
254
|
no `update`: a escolha fica em `comentarios.instalar: false` no `.ai-harness/config.json`, e o `update` a respeita.
|
|
254
255
|
Para reativar, apague a chave e rode `update --yes` (ou `npx @fontdata/ai-harness comentarios --yes`). Sem o padrão
|
|
255
256
|
e sem a recusa, o `doctor` avisa com `comentarios-ausente`.
|
package/dist/doctor/checks.js
CHANGED
|
@@ -4,6 +4,7 @@ import { join } from 'node:path';
|
|
|
4
4
|
import { lerEnvSettingsLocal, lerVariavel, SETTINGS_LOCAL_PATH } from '../banco-dados/ambiente.js';
|
|
5
5
|
import { caminhoCadastro, lerCadastro } from '../banco-dados/cadastro.js';
|
|
6
6
|
import { allCommands, loadCatalog } from '../catalog.js';
|
|
7
|
+
import { COMMENTS_HOOK_PATH } from '../comentarios/instalar.js';
|
|
7
8
|
import { CONFIG_PATH, readConfig } from '../config/config.js';
|
|
8
9
|
import { readArtifact, validateAllWorks, WORKS_DIR } from '../contratos/artefatos.js';
|
|
9
10
|
import { validateEventLog } from '../contratos/eventos.js';
|
|
@@ -390,9 +391,14 @@ function checkOldCommentsBlock(root) {
|
|
|
390
391
|
},
|
|
391
392
|
];
|
|
392
393
|
}
|
|
393
|
-
/**
|
|
394
|
-
|
|
395
|
-
|
|
394
|
+
/**
|
|
395
|
+
* Lock anterior ao padrão de comentários e sem a recusa no config: o update o instala. Hook no disco fora do lock é
|
|
396
|
+
* instalação antiga ou adaptada, que o update só registra no lock.
|
|
397
|
+
*/
|
|
398
|
+
function checkComments(root, lock, config) {
|
|
399
|
+
if (!config.comentarios.instalar || existsSync(join(root, COMMENTS_HOOK_PATH)))
|
|
400
|
+
return [];
|
|
401
|
+
if (lock.itens.some((item) => item.tipo === 'hook' && item.id === 'comentarios'))
|
|
396
402
|
return [];
|
|
397
403
|
return [
|
|
398
404
|
{
|
|
@@ -520,7 +526,7 @@ export function runDoctor(root, options = {}) {
|
|
|
520
526
|
return [
|
|
521
527
|
...checkNode(options.nodeVersion ?? process.versions.node),
|
|
522
528
|
...lockFindings,
|
|
523
|
-
...(lock ? [...checkFiles(root, lock), ...checkRequiredSkills(root, lock), ...checkComments(lock, config)] : []),
|
|
529
|
+
...(lock ? [...checkFiles(root, lock), ...checkRequiredSkills(root, lock), ...checkComments(root, lock, config)] : []),
|
|
524
530
|
...checkShadowedCommands(root),
|
|
525
531
|
...checkOldCommentsBlock(root),
|
|
526
532
|
...checkAgents(root),
|
package/dist/update/update.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { existsSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from 'node:fs';
|
|
2
2
|
import { dirname, join, resolve } from 'node:path';
|
|
3
|
-
import { allCommands, loadCatalog } from '../catalog.js';
|
|
4
|
-
import { commentsHooksConfig, ensureCommentsBaseline } from '../comentarios/instalar.js';
|
|
3
|
+
import { allCommands, loadCatalog, templatesDir } from '../catalog.js';
|
|
4
|
+
import { COMMENTS_HOOK_PATH, commentsHooksConfig, ensureCommentsBaseline } from '../comentarios/instalar.js';
|
|
5
5
|
import { CONFIG_PATH, gravarInstalarComentarios, gravarRegistrarMcp, migrarSecaoBanco, readConfig, syncGitignore, temSecaoBancoLegada, writeDefaultConfig, } from '../config/config.js';
|
|
6
6
|
import { applyAtomically } from '../install/atomic.js';
|
|
7
7
|
import { suggestFlag } from '../install/flags.js';
|
|
@@ -50,6 +50,12 @@ function legacyPath(root, path) {
|
|
|
50
50
|
return candidate;
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
|
+
const COMMENTS_HOOK_TEMPLATE = join(templatesDir, 'hooks', 'comentarios', 'check.mjs');
|
|
54
|
+
/** O hook de comentários existe no projeto com conteúdo diferente do template do pacote. */
|
|
55
|
+
function hookProprio(root) {
|
|
56
|
+
const local = join(root, COMMENTS_HOOK_PATH);
|
|
57
|
+
return existsSync(local) && hashContent(readFileSync(local)) !== hashContent(readFileSync(COMMENTS_HOOK_TEMPLATE));
|
|
58
|
+
}
|
|
53
59
|
export function checkUpdate(root, catalog = loadCatalog(), legacy, home, { semBanco = false, semComentarios = false } = {}) {
|
|
54
60
|
const recorded = readLock(root);
|
|
55
61
|
const lock = recorded ?? adoptLegacyInstall(root, legacy);
|
|
@@ -139,7 +145,10 @@ export function checkUpdate(root, catalog = loadCatalog(), legacy, home, { semBa
|
|
|
139
145
|
}
|
|
140
146
|
// O padrão de comentários também chega ao lock anterior a ele, salvo com a recusa no config ou na flag. O hook é a
|
|
141
147
|
// referência: o comando `comentarios` não registra a rule quando o projeto já tem uma própria.
|
|
142
|
-
const
|
|
148
|
+
const querComentarios = !semComentarios && config.comentarios.instalar;
|
|
149
|
+
const hookNoLock = trackedItems.has('hook:comentarios');
|
|
150
|
+
const registrarHookComentarios = querComentarios && !hookNoLock && hookProprio(root);
|
|
151
|
+
const registrarComentarios = querComentarios && !registrarHookComentarios && (adotada || !hookNoLock);
|
|
143
152
|
if (registrarComentarios) {
|
|
144
153
|
addItem('rule', 'comentarios', true);
|
|
145
154
|
addItem('hook', 'comentarios', true);
|
|
@@ -159,6 +168,7 @@ export function checkUpdate(root, catalog = loadCatalog(), legacy, home, { semBa
|
|
|
159
168
|
adotada,
|
|
160
169
|
registrarHooks: adotada && !pluginHooks,
|
|
161
170
|
registrarComentarios,
|
|
171
|
+
registrarHookComentarios,
|
|
162
172
|
recusarComentarios: semComentarios && config.comentarios.instalar,
|
|
163
173
|
permissaoAusente: permissoesFaltando.length > 0,
|
|
164
174
|
permissoesFaltando,
|
|
@@ -281,6 +291,10 @@ export function applyUpdate(root, report, options, pkg, now = new Date()) {
|
|
|
281
291
|
for (const added of addedItems.values()) {
|
|
282
292
|
itens.push({ ...added, arquivos: added.arquivos.sort((a, b) => a.caminho.localeCompare(b.caminho)) });
|
|
283
293
|
}
|
|
294
|
+
// Com o hash do template, o arquivo do projeto aparece como modificado-local e nunca é regravado sem --forcar.
|
|
295
|
+
if (report.registrarHookComentarios) {
|
|
296
|
+
itens.push({ tipo: 'hook', id: 'comentarios', arquivos: [{ caminho: COMMENTS_HOOK_PATH, sha256: hashContent(readFileSync(COMMENTS_HOOK_TEMPLATE)) }] });
|
|
297
|
+
}
|
|
284
298
|
writeLock(root, { lock_versao: LOCK_VERSION, pacote: pkg, gerado_em: now.toISOString(), itens });
|
|
285
299
|
return { written: write.map((file) => file.path), removed: remove, kept, renamed, avisos, ajustes };
|
|
286
300
|
}
|
|
@@ -321,6 +335,12 @@ export function describeUpdate(report) {
|
|
|
321
335
|
`Para recusar, rode com --sem-comentarios, que grava comentarios.instalar: false em ${CONFIG_PATH}.`,
|
|
322
336
|
]
|
|
323
337
|
: []),
|
|
338
|
+
...(report.registrarHookComentarios
|
|
339
|
+
? [
|
|
340
|
+
`O hook de comentários ${COMMENTS_HOOK_PATH} é do projeto (instalado por versão antiga ou adaptado) e não está no lock: ` +
|
|
341
|
+
'o --yes o deixa registrado no lock como alterado localmente, sem tocar no arquivo.',
|
|
342
|
+
]
|
|
343
|
+
: []),
|
|
324
344
|
...(report.recusarComentarios ? [`--sem-comentarios: o --yes grava comentarios.instalar: false em ${CONFIG_PATH} e não instala o padrão de comentários.`] : []),
|
|
325
345
|
];
|
|
326
346
|
const legadas = report.permissoesLegadas.length
|
|
@@ -386,7 +406,7 @@ export function runUpdateCommand(argv) {
|
|
|
386
406
|
const report = checkUpdate(root, undefined, undefined, undefined, { semBanco: args.semBanco, semComentarios: args.semComentarios });
|
|
387
407
|
console.log(describeUpdate(report));
|
|
388
408
|
// Sem arquivo a atualizar, a adoção ainda grava o lock, e a permissão e o MCP ainda são acrescentados.
|
|
389
|
-
const pendente = report.adotada || report.permissaoAusente || report.permissoesLegadas.length > 0 || report.mudancaMcp !== null || report.recusarMcp || report.recusarComentarios || report.renomearSecaoBanco;
|
|
409
|
+
const pendente = report.adotada || report.permissaoAusente || report.permissoesLegadas.length > 0 || report.mudancaMcp !== null || report.recusarMcp || report.recusarComentarios || report.registrarHookComentarios || report.renomearSecaoBanco;
|
|
390
410
|
if (args.check || (!report.changes.length && !pendente))
|
|
391
411
|
return 0;
|
|
392
412
|
if (!args.yes) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fontdata/ai-harness",
|
|
3
|
-
"version": "3.2.
|
|
3
|
+
"version": "3.2.3",
|
|
4
4
|
"description": "Harness de engenharia com IA da Fontdata para Claude Code: roda os slash commands direto na pasta do projeto via npx, sem instalar nada — ou instala-os em .claude/commands.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|