@noclaf/cli 0.5.0 → 0.5.2
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/README.md +11 -7
- package/dist/adapters/supabase/task-gateway.js +11 -0
- package/dist/adapters/supabase/task-gateway.js.map +1 -1
- package/dist/cli/commands/init/analyze-step.js +21 -0
- package/dist/cli/commands/init/analyze-step.js.map +1 -0
- package/dist/cli/commands/init/apply-answers.js +105 -0
- package/dist/cli/commands/init/apply-answers.js.map +1 -0
- package/dist/cli/commands/init/apply-step.js +162 -0
- package/dist/cli/commands/init/apply-step.js.map +1 -0
- package/dist/cli/commands/init/clients-step.js +13 -11
- package/dist/cli/commands/init/clients-step.js.map +1 -1
- package/dist/cli/commands/init/context-step.js +17 -9
- package/dist/cli/commands/init/context-step.js.map +1 -1
- package/dist/cli/commands/init/describe-step.js +58 -0
- package/dist/cli/commands/init/describe-step.js.map +1 -0
- package/dist/cli/commands/init/index.js +24 -2
- package/dist/cli/commands/init/index.js.map +1 -1
- package/dist/cli/commands/init/mode.js +18 -0
- package/dist/cli/commands/init/mode.js.map +1 -0
- package/dist/cli/commands/init/progress.js +60 -0
- package/dist/cli/commands/init/progress.js.map +1 -0
- package/dist/cli/commands/init/project-step.js +33 -5
- package/dist/cli/commands/init/project-step.js.map +1 -1
- package/dist/cli/commands/map.js +18 -0
- package/dist/cli/commands/map.js.map +1 -0
- package/dist/cli/commands/sync.js +2 -2
- package/dist/cli/commands/sync.js.map +1 -1
- package/dist/cli/commands/wave.js +57 -0
- package/dist/cli/commands/wave.js.map +1 -0
- package/dist/cli/copy/init.json +1 -0
- package/dist/cli/copy.js.map +1 -1
- package/dist/cli/flows/sections.js +1 -1
- package/dist/cli/flows/sections.js.map +1 -1
- package/dist/cli/ui/render.js +10 -9
- package/dist/cli/ui/render.js.map +1 -1
- package/dist/cli.js +4 -0
- package/dist/cli.js.map +1 -1
- package/dist/config.js +24 -15
- package/dist/config.js.map +1 -1
- package/dist/lib/exec-delegate.js +6 -4
- package/dist/lib/exec-delegate.js.map +1 -1
- package/dist/lib/exec-events.js +8 -1
- package/dist/lib/exec-events.js.map +1 -1
- package/dist/lib/exec-translators.js +25 -2
- package/dist/lib/exec-translators.js.map +1 -1
- package/dist/lib/harness.js +7 -2
- package/dist/lib/harness.js.map +1 -1
- package/dist/lib/patterns.js +4 -40
- package/dist/lib/patterns.js.map +1 -1
- package/dist/lib/repo-map.js +176 -0
- package/dist/lib/repo-map.js.map +1 -0
- package/dist/lib/skill-agent.js +44 -0
- package/dist/lib/skill-agent.js.map +1 -0
- package/dist/lib/wave-scheduler.js +95 -0
- package/dist/lib/wave-scheduler.js.map +1 -0
- package/dist/tools/exec-status.js +3 -1
- package/dist/tools/exec-status.js.map +1 -1
- package/dist/tools/index.js +2 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/set-review.js +132 -0
- package/dist/tools/set-review.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { spawnSync } from 'node:child_process';
|
|
2
|
+
import { existsSync, readFileSync, mkdirSync, writeFileSync } from 'node:fs';
|
|
3
|
+
import { dirname, join } from 'node:path';
|
|
4
|
+
import { ensureGitignored, GITIGNORE_GENERATED_SUFFIX } from '../config.js';
|
|
5
|
+
/**
|
|
6
|
+
* Índice estrutural do repo — irmão do `detect-patterns`, mas **sem IA**: um artefato
|
|
7
|
+
* gerado deterministicamente (mesma entrada → mesma saída) que os agentes **grepam** pra
|
|
8
|
+
* achar onde as coisas vivem, em vez de abrir arquivos inteiros. Regerado no `sync`.
|
|
9
|
+
*/
|
|
10
|
+
export const MAP_REL = 'docs/_map.md';
|
|
11
|
+
/** Símbolos "públicos" por stack. Regex leve — o objetivo é localizar, não parsear. */
|
|
12
|
+
const EXTRACTORS = {
|
|
13
|
+
ts: [
|
|
14
|
+
/^export\s+(?:default\s+)?(?:async\s+)?(?:abstract\s+)?(?:function|class|const|let|type|interface|enum)\s+([A-Za-z_$][\w$]*)/gm,
|
|
15
|
+
],
|
|
16
|
+
py: [/^(?:def|class)\s+([A-Za-z_]\w*)/gm],
|
|
17
|
+
swift: [
|
|
18
|
+
/^(?:public|open)\s+(?:final\s+)?(?:func|class|struct|enum|protocol|actor|var|let)\s+([A-Za-z_]\w*)/gm,
|
|
19
|
+
],
|
|
20
|
+
go: [/^func\s+(?:\([^)]*\)\s*)?([A-Z]\w*)/gm, /^type\s+([A-Z]\w*)/gm],
|
|
21
|
+
rs: [/^pub\s+(?:async\s+)?(?:fn|struct|enum|trait|const|type|mod)\s+([A-Za-z_]\w*)/gm],
|
|
22
|
+
};
|
|
23
|
+
const STACK_BY_EXT = {
|
|
24
|
+
ts: 'ts',
|
|
25
|
+
tsx: 'ts',
|
|
26
|
+
js: 'ts',
|
|
27
|
+
jsx: 'ts',
|
|
28
|
+
mjs: 'ts',
|
|
29
|
+
py: 'py',
|
|
30
|
+
swift: 'swift',
|
|
31
|
+
go: 'go',
|
|
32
|
+
rs: 'rs',
|
|
33
|
+
};
|
|
34
|
+
/** Teto de símbolos por arquivo: o map é índice, não dump — estourar reintroduz o custo. */
|
|
35
|
+
const MAX_SYMBOLS = 12;
|
|
36
|
+
const COMMENT = /^\s*(?:\/\/+|\/\*+|\*+\/?|#+|"""|''')\s*/;
|
|
37
|
+
const SHEBANG = /^#!/;
|
|
38
|
+
// Banner de licença/pragma/TODO não descreve o arquivo — propósito vazio é melhor que errado.
|
|
39
|
+
const NON_PROSE = /^(?:copyright\b|\(c\)|licen[sc]|spdx-|all rights reserved|@ts-|eslint-|prettier-|todo:|fixme:|noqa|-\*-)/i;
|
|
40
|
+
const CLOSER = /(?:\*+\/|"""|''')\s*$/;
|
|
41
|
+
// Só declaração em coluna 0 encerra a busca — o corpo indentado de um `import {` multilinha não.
|
|
42
|
+
const DECL = /^(?:export|declare|def|class|func|fn|pub|type|interface|enum|const|let|var|function|struct|impl|actor|protocol|public|open|extension|private|internal|final|async|@)\b/;
|
|
43
|
+
function isComment(line) {
|
|
44
|
+
return !SHEBANG.test(line) && COMMENT.test(line);
|
|
45
|
+
}
|
|
46
|
+
function stackOf(path) {
|
|
47
|
+
const ext = path.split('.').pop() ?? '';
|
|
48
|
+
return path.includes('.test.') || path.includes('.spec.') ? null : (STACK_BY_EXT[ext] ?? null);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Propósito = o doc de cabeçalho do arquivo, juntado até a 1ª frase. Banner de licença é
|
|
52
|
+
* pulado; bloco colado numa declaração documenta o símbolo, não o arquivo — aí devolve vazio.
|
|
53
|
+
*/
|
|
54
|
+
function purposeOf(source) {
|
|
55
|
+
const lines = source.split('\n', 40);
|
|
56
|
+
for (let i = 0; i < lines.length; i++) {
|
|
57
|
+
if (DECL.test(lines[i]))
|
|
58
|
+
return '';
|
|
59
|
+
if (!isComment(lines[i]))
|
|
60
|
+
continue;
|
|
61
|
+
const prose = [];
|
|
62
|
+
for (; i < lines.length && isComment(lines[i]); i++) {
|
|
63
|
+
const part = lines[i].replace(COMMENT, '').replace(CLOSER, '').trim();
|
|
64
|
+
if (part)
|
|
65
|
+
prose.push(part);
|
|
66
|
+
}
|
|
67
|
+
const text = prose.join(' ');
|
|
68
|
+
// Licença/pragma em bloco próprio: pula e segue procurando o doc de verdade.
|
|
69
|
+
if (NON_PROSE.test(text)) {
|
|
70
|
+
i--;
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
// Bloco colado numa declaração documenta **aquele símbolo**, não o arquivo.
|
|
74
|
+
if ((lines[i] ?? '').trim())
|
|
75
|
+
return '';
|
|
76
|
+
const end = text.indexOf('. ');
|
|
77
|
+
const sentence = end < 0 ? text : text.slice(0, end + 1);
|
|
78
|
+
return sentence.split(/\s+/).length >= 3 ? sentence : '';
|
|
79
|
+
}
|
|
80
|
+
return '';
|
|
81
|
+
}
|
|
82
|
+
function symbolsOf(source, stack) {
|
|
83
|
+
const found = [];
|
|
84
|
+
for (const re of EXTRACTORS[stack] ?? []) {
|
|
85
|
+
for (const match of source.matchAll(re)) {
|
|
86
|
+
const name = match[1];
|
|
87
|
+
if (name && !found.includes(name))
|
|
88
|
+
found.push(name);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return found;
|
|
92
|
+
}
|
|
93
|
+
/** `git ls-files` é a lista de fontes: já respeita o .gitignore e sai ordenada. */
|
|
94
|
+
function trackedFiles(cwd) {
|
|
95
|
+
const r = spawnSync('git', ['ls-files', '-z'], { cwd, encoding: 'utf8' });
|
|
96
|
+
if (r.error || r.status !== 0)
|
|
97
|
+
return null;
|
|
98
|
+
return (r.stdout ?? '').split('\0').filter(Boolean).sort();
|
|
99
|
+
}
|
|
100
|
+
/** `null` = o repo não pôde ser listado (sem git) — diferente de "listou e não achou fonte". */
|
|
101
|
+
export function collectEntries(cwd) {
|
|
102
|
+
const tracked = trackedFiles(cwd);
|
|
103
|
+
if (!tracked)
|
|
104
|
+
return null;
|
|
105
|
+
const entries = [];
|
|
106
|
+
for (const path of tracked) {
|
|
107
|
+
const stack = stackOf(path);
|
|
108
|
+
if (!stack)
|
|
109
|
+
continue;
|
|
110
|
+
let source;
|
|
111
|
+
try {
|
|
112
|
+
source = readFileSync(join(cwd, path), 'utf8');
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
const symbols = symbolsOf(source, stack);
|
|
118
|
+
const purpose = purposeOf(source);
|
|
119
|
+
if (symbols.length || purpose)
|
|
120
|
+
entries.push({ path, purpose, symbols });
|
|
121
|
+
}
|
|
122
|
+
return entries;
|
|
123
|
+
}
|
|
124
|
+
function renderLine(entry) {
|
|
125
|
+
const name = entry.path.split('/').pop() ?? entry.path;
|
|
126
|
+
const parts = [`- \`${name}\``];
|
|
127
|
+
if (entry.purpose)
|
|
128
|
+
parts.push(`— ${entry.purpose}`);
|
|
129
|
+
const shown = entry.symbols.slice(0, MAX_SYMBOLS);
|
|
130
|
+
// Corte explícito: num índice grepado, silêncio no fim da linha lê como "não existe".
|
|
131
|
+
const rest = entry.symbols.length - shown.length;
|
|
132
|
+
const more = rest > 0 ? ` +${rest}` : '';
|
|
133
|
+
if (shown.length)
|
|
134
|
+
parts.push(`· ${shown.map((s) => `\`${s}\``).join(', ')}${more}`);
|
|
135
|
+
return parts.join(' ');
|
|
136
|
+
}
|
|
137
|
+
export function renderMap(entries) {
|
|
138
|
+
const byDir = new Map();
|
|
139
|
+
for (const entry of entries) {
|
|
140
|
+
const dir = dirname(entry.path);
|
|
141
|
+
byDir.set(dir, [...(byDir.get(dir) ?? []), entry]);
|
|
142
|
+
}
|
|
143
|
+
const lines = [
|
|
144
|
+
`<!-- Gerado por \`noclaf map\`/\`sync\`. Determinístico e descartável: NÃO edite à mão. -->`,
|
|
145
|
+
'# Repo map',
|
|
146
|
+
'',
|
|
147
|
+
'Índice `arquivo → símbolos exportados`. **Grepe aqui** pra localizar antes de abrir arquivo.',
|
|
148
|
+
];
|
|
149
|
+
for (const [dir, group] of byDir) {
|
|
150
|
+
lines.push('', `## ${dir}`, ...group.map(renderLine));
|
|
151
|
+
}
|
|
152
|
+
return `${lines.join('\n')}\n`;
|
|
153
|
+
}
|
|
154
|
+
/** Gera/regenera o `docs/_map.md`. Best-effort: nunca lança, nunca bloqueia o loop. */
|
|
155
|
+
export function generateRepoMap(cwd) {
|
|
156
|
+
try {
|
|
157
|
+
const entries = collectEntries(cwd);
|
|
158
|
+
if (!entries)
|
|
159
|
+
return { action: 'empty', entries: 0 };
|
|
160
|
+
const target = join(cwd, MAP_REL);
|
|
161
|
+
const content = renderMap(entries);
|
|
162
|
+
const existed = existsSync(target);
|
|
163
|
+
const same = existed && readFileSync(target, 'utf8') === content;
|
|
164
|
+
if (!same) {
|
|
165
|
+
mkdirSync(dirname(target), { recursive: true });
|
|
166
|
+
writeFileSync(target, content, 'utf8');
|
|
167
|
+
}
|
|
168
|
+
// Artefato gerado: se versionado, apodreceria entre um `sync` e o próximo.
|
|
169
|
+
ensureGitignored(MAP_REL, cwd, GITIGNORE_GENERATED_SUFFIX);
|
|
170
|
+
return { action: same ? 'unchanged' : existed ? 'updated' : 'created', entries: entries.length };
|
|
171
|
+
}
|
|
172
|
+
catch {
|
|
173
|
+
return { action: 'empty', entries: 0 };
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
//# sourceMappingURL=repo-map.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repo-map.js","sourceRoot":"","sources":["../../src/lib/repo-map.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,gBAAgB,EAAE,0BAA0B,EAAE,MAAM,cAAc,CAAC;AAE5E;;;;GAIG;AAEH,MAAM,CAAC,MAAM,OAAO,GAAG,cAAc,CAAC;AAEtC,uFAAuF;AACvF,MAAM,UAAU,GAA6B;IAC3C,EAAE,EAAE;QACF,+HAA+H;KAChI;IACD,EAAE,EAAE,CAAC,mCAAmC,CAAC;IACzC,KAAK,EAAE;QACL,sGAAsG;KACvG;IACD,EAAE,EAAE,CAAC,uCAAuC,EAAE,sBAAsB,CAAC;IACrE,EAAE,EAAE,CAAC,gFAAgF,CAAC;CACvF,CAAC;AAEF,MAAM,YAAY,GAA2B;IAC3C,EAAE,EAAE,IAAI;IACR,GAAG,EAAE,IAAI;IACT,EAAE,EAAE,IAAI;IACR,GAAG,EAAE,IAAI;IACT,GAAG,EAAE,IAAI;IACT,EAAE,EAAE,IAAI;IACR,KAAK,EAAE,OAAO;IACd,EAAE,EAAE,IAAI;IACR,EAAE,EAAE,IAAI;CACT,CAAC;AAEF,4FAA4F;AAC5F,MAAM,WAAW,GAAG,EAAE,CAAC;AACvB,MAAM,OAAO,GAAG,0CAA0C,CAAC;AAC3D,MAAM,OAAO,GAAG,KAAK,CAAC;AACtB,8FAA8F;AAC9F,MAAM,SAAS,GACb,2GAA2G,CAAC;AAC9G,MAAM,MAAM,GAAG,uBAAuB,CAAC;AACvC,iGAAiG;AACjG,MAAM,IAAI,GACR,wKAAwK,CAAC;AAE3K,SAAS,SAAS,CAAC,IAAY;IAC7B,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACnD,CAAC;AAED,SAAS,OAAO,CAAC,IAAY;IAC3B,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC;IACxC,OAAO,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC;AACjG,CAAC;AAED;;;GAGG;AACH,SAAS,SAAS,CAAC,MAAc;IAC/B,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IACrC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAW,CAAC;YAAE,OAAO,EAAE,CAAC;QAC7C,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAW,CAAC;YAAE,SAAS;QAE7C,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,OAAO,CAAC,GAAG,KAAK,CAAC,MAAM,IAAI,SAAS,CAAC,KAAK,CAAC,CAAC,CAAW,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC9D,MAAM,IAAI,GAAI,KAAK,CAAC,CAAC,CAAY,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;YAClF,IAAI,IAAI;gBAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7B,CAAC;QACD,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC7B,6EAA6E;QAC7E,IAAI,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACzB,CAAC,EAAE,CAAC;YACJ,SAAS;QACX,CAAC;QACD,4EAA4E;QAC5E,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE;YAAE,OAAO,EAAE,CAAC;QACvC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC/B,MAAM,QAAQ,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC;QACzD,OAAO,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;IAC3D,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,SAAS,SAAS,CAAC,MAAc,EAAE,KAAa;IAC9C,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,EAAE,IAAI,UAAU,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC;QACzC,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;YACxC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YACtB,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC;gBAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACtD,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,mFAAmF;AACnF,SAAS,YAAY,CAAC,GAAW;IAC/B,MAAM,CAAC,GAAG,SAAS,CAAC,KAAK,EAAE,CAAC,UAAU,EAAE,IAAI,CAAC,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;IAC1E,IAAI,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAC3C,OAAO,CAAC,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;AAC7D,CAAC;AAQD,gGAAgG;AAChG,MAAM,UAAU,cAAc,CAAC,GAAW;IACxC,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;IAClC,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAC1B,MAAM,OAAO,GAAe,EAAE,CAAC;IAC/B,KAAK,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;QAC3B,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAC5B,IAAI,CAAC,KAAK;YAAE,SAAS;QACrB,IAAI,MAAc,CAAC;QACnB,IAAI,CAAC;YACH,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;QACjD,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;QACD,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QACzC,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;QAClC,IAAI,OAAO,CAAC,MAAM,IAAI,OAAO;YAAE,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;IAC1E,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,UAAU,CAAC,KAAe;IACjC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,KAAK,CAAC,IAAI,CAAC;IACvD,MAAM,KAAK,GAAG,CAAC,OAAO,IAAI,IAAI,CAAC,CAAC;IAChC,IAAI,KAAK,CAAC,OAAO;QAAE,KAAK,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IACpD,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC;IAClD,sFAAsF;IACtF,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;IACjD,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACzC,IAAI,KAAK,CAAC,MAAM;QAAE,KAAK,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC;IACpF,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACzB,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,OAAmB;IAC3C,MAAM,KAAK,GAAG,IAAI,GAAG,EAAsB,CAAC;IAC5C,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAChC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;IACrD,CAAC;IACD,MAAM,KAAK,GAAG;QACZ,6FAA6F;QAC7F,YAAY;QACZ,EAAE;QACF,8FAA8F;KAC/F,CAAC;IACF,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,KAAK,EAAE,CAAC;QACjC,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,EAAE,EAAE,GAAG,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC;IACxD,CAAC;IACD,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;AACjC,CAAC;AAKD,uFAAuF;AACvF,MAAM,UAAU,eAAe,CAAC,GAAW;IACzC,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,CAAC,OAAO;YAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;QACrD,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QAClC,MAAM,OAAO,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC;QACnC,MAAM,OAAO,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;QACnC,MAAM,IAAI,GAAG,OAAO,IAAI,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,OAAO,CAAC;QACjE,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAChD,aAAa,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;QACzC,CAAC;QACD,2EAA2E;QAC3E,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE,0BAA0B,CAAC,CAAC;QAC3D,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,EAAE,OAAO,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC;IACnG,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;IACzC,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { spawnSync } from 'node:child_process';
|
|
2
|
+
import { readSkillDocs } from './skills.js';
|
|
3
|
+
/** Corpo da skill como prompt (fonte única); ausente do cache → fallback do caller. */
|
|
4
|
+
export function skillPrompt(id, fallback) {
|
|
5
|
+
try {
|
|
6
|
+
const doc = readSkillDocs().find((d) => d.id === id && d.type === 'skill');
|
|
7
|
+
if (doc?.content.trim())
|
|
8
|
+
return doc.content.trim();
|
|
9
|
+
}
|
|
10
|
+
catch {
|
|
11
|
+
/* skill ausente do cache → fallback */
|
|
12
|
+
}
|
|
13
|
+
return fallback;
|
|
14
|
+
}
|
|
15
|
+
/** Existe um binário no PATH (via `--version`)? */
|
|
16
|
+
function hasBin(bin) {
|
|
17
|
+
try {
|
|
18
|
+
return !spawnSync(bin, ['--version'], { stdio: 'ignore' }).error;
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Roda o prompt num agente headless no `cwd`. Prefere `claude`, cai pro `codex`;
|
|
26
|
+
* sem nenhum no PATH, não roda (`ran:false`).
|
|
27
|
+
*/
|
|
28
|
+
export function runSkillAgent(prompt, opts) {
|
|
29
|
+
// stdin ignorado (o prompt vai por arg) — evita o agente ficar esperando stdin.
|
|
30
|
+
const stdio = ['ignore', opts.stdoutFd ?? 1, 2];
|
|
31
|
+
if (hasBin('claude')) {
|
|
32
|
+
const r = spawnSync('claude', ['-p', prompt, '--permission-mode', 'acceptEdits'], {
|
|
33
|
+
cwd: opts.cwd,
|
|
34
|
+
stdio,
|
|
35
|
+
});
|
|
36
|
+
return { ran: true, ok: !r.error && r.status === 0, agent: 'claude' };
|
|
37
|
+
}
|
|
38
|
+
if (hasBin('codex')) {
|
|
39
|
+
const r = spawnSync('codex', ['exec', prompt], { cwd: opts.cwd, stdio });
|
|
40
|
+
return { ran: true, ok: !r.error && r.status === 0, agent: 'codex' };
|
|
41
|
+
}
|
|
42
|
+
return { ran: false, reason: 'sem `claude` nem `codex` no PATH pra rodar a análise' };
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=skill-agent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-agent.js","sourceRoot":"","sources":["../../src/lib/skill-agent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAgB5C,uFAAuF;AACvF,MAAM,UAAU,WAAW,CAAC,EAAU,EAAE,QAAgB;IACtD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,aAAa,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC;QAC3E,IAAI,GAAG,EAAE,OAAO,CAAC,IAAI,EAAE;YAAE,OAAO,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;IACrD,CAAC;IAAC,MAAM,CAAC;QACP,uCAAuC;IACzC,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,mDAAmD;AACnD,SAAS,MAAM,CAAC,GAAW;IACzB,IAAI,CAAC;QACH,OAAO,CAAC,SAAS,CAAC,GAAG,EAAE,CAAC,WAAW,CAAC,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC;IACnE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAQD;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,MAAc,EAAE,IAAqB;IACjE,gFAAgF;IAChF,MAAM,KAAK,GAAyB,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;IAEtE,IAAI,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;QACrB,MAAM,CAAC,GAAG,SAAS,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,mBAAmB,EAAE,aAAa,CAAC,EAAE;YAChF,GAAG,EAAE,IAAI,CAAC,GAAG;YACb,KAAK;SACN,CAAC,CAAC;QACH,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;IACxE,CAAC;IACD,IAAI,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;QACpB,MAAM,CAAC,GAAG,SAAS,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC;QACzE,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;IACvE,CAAC;IACD,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,sDAAsD,EAAE,CAAC;AACxF,CAAC"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scheduler das waves do `/build`: lê o DAG de um doc de tickets e devolve a próxima leva
|
|
3
|
+
* de tickets que podem rodar em paralelo. Puro — sem I/O, sem git, sem agentes.
|
|
4
|
+
*/
|
|
5
|
+
/** Teto de executores concorrentes quando o usuário não configurou nada. */
|
|
6
|
+
export const DEFAULT_MAX_PARALLELISM = 3;
|
|
7
|
+
const HEADING = /^##\s+(T-\d+)\s*[·\-—]\s*(.+)$/gm;
|
|
8
|
+
const BLOCKED_BY = /\*\*Bloqueado por:\*\*\s*(.+)/;
|
|
9
|
+
const TICKET_REF = /T-\d+/g;
|
|
10
|
+
const CHECKBOX = /^\s*[-*]\s*\[([ xX])\]/gm;
|
|
11
|
+
const BACKTICKED = /`([^`\s]+)`/g;
|
|
12
|
+
function parseBlockers(body) {
|
|
13
|
+
const line = body.match(BLOCKED_BY);
|
|
14
|
+
if (!line)
|
|
15
|
+
return [];
|
|
16
|
+
return [...new Set(line[1].match(TICKET_REF) ?? [])];
|
|
17
|
+
}
|
|
18
|
+
function parseDone(body) {
|
|
19
|
+
const boxes = [...body.matchAll(CHECKBOX)];
|
|
20
|
+
return boxes.length > 0 && boxes.every((b) => b[1] !== ' ');
|
|
21
|
+
}
|
|
22
|
+
/** Heurística: token em crase com `/` ou extensão. Erra pro lado de serializar demais. */
|
|
23
|
+
function parseFiles(body) {
|
|
24
|
+
const files = new Set();
|
|
25
|
+
for (const [, token] of body.matchAll(BACKTICKED)) {
|
|
26
|
+
const path = token.replace(/[.,;:]+$/, '');
|
|
27
|
+
if (path.includes('/') || /\.\w{1,5}$/.test(path))
|
|
28
|
+
files.add(path);
|
|
29
|
+
}
|
|
30
|
+
return [...files];
|
|
31
|
+
}
|
|
32
|
+
/** Extrai os tickets do markdown do doc (`## T-N · título`), na ordem de declaração. */
|
|
33
|
+
export function parseTickets(markdown) {
|
|
34
|
+
const heads = [...markdown.matchAll(HEADING)];
|
|
35
|
+
return heads.map((head, i) => {
|
|
36
|
+
const start = (head.index ?? 0) + head[0].length;
|
|
37
|
+
const body = markdown.slice(start, heads[i + 1]?.index ?? markdown.length);
|
|
38
|
+
return {
|
|
39
|
+
id: head[1],
|
|
40
|
+
title: head[2].trim(),
|
|
41
|
+
blockedBy: parseBlockers(body),
|
|
42
|
+
done: parseDone(body),
|
|
43
|
+
files: parseFiles(body),
|
|
44
|
+
};
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
function doneIdsOf(tickets) {
|
|
48
|
+
return new Set(tickets.filter((t) => t.done).map((t) => t.id));
|
|
49
|
+
}
|
|
50
|
+
/** Teto efetivo: inteiro ≥ 1 — nunca zero executores, nunca fração. */
|
|
51
|
+
export function clampParallelism(maxParallelism) {
|
|
52
|
+
return Number.isFinite(maxParallelism) ? Math.max(1, Math.floor(maxParallelism)) : 1;
|
|
53
|
+
}
|
|
54
|
+
/** Um bloqueador só conta como satisfeito se o ticket existe **e** está done. */
|
|
55
|
+
function isReady(ticket, doneIds) {
|
|
56
|
+
return !ticket.done && ticket.blockedBy.every((id) => doneIds.has(id));
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Próxima wave: o frontier, na ordem do doc. Dois tickets que toquem o mesmo arquivo não
|
|
60
|
+
* entram juntos — o segundo serializa pra wave seguinte.
|
|
61
|
+
*/
|
|
62
|
+
export function nextWave(tickets, maxParallelism = DEFAULT_MAX_PARALLELISM) {
|
|
63
|
+
const doneIds = doneIdsOf(tickets);
|
|
64
|
+
const limit = clampParallelism(maxParallelism);
|
|
65
|
+
const claimed = new Set();
|
|
66
|
+
const wave = [];
|
|
67
|
+
for (const ticket of tickets) {
|
|
68
|
+
if (wave.length >= limit)
|
|
69
|
+
break;
|
|
70
|
+
if (!isReady(ticket, doneIds))
|
|
71
|
+
continue;
|
|
72
|
+
if (ticket.files.some((file) => claimed.has(file)))
|
|
73
|
+
continue;
|
|
74
|
+
for (const file of ticket.files)
|
|
75
|
+
claimed.add(file);
|
|
76
|
+
wave.push(ticket);
|
|
77
|
+
}
|
|
78
|
+
return wave;
|
|
79
|
+
}
|
|
80
|
+
/** Tickets ainda não entregues que **não** entraram na wave, com o motivo da espera. */
|
|
81
|
+
export function waitingTickets(tickets, wave) {
|
|
82
|
+
const doneIds = doneIdsOf(tickets);
|
|
83
|
+
const scheduled = new Set(wave.map((t) => t.id));
|
|
84
|
+
const claimed = new Set(wave.flatMap((t) => t.files));
|
|
85
|
+
return tickets
|
|
86
|
+
.filter((t) => !t.done && !scheduled.has(t.id))
|
|
87
|
+
.map((t) => {
|
|
88
|
+
const blockedBy = t.blockedBy.filter((id) => !doneIds.has(id));
|
|
89
|
+
if (blockedBy.length > 0)
|
|
90
|
+
return { id: t.id, reason: 'blocked', blockedBy };
|
|
91
|
+
const reason = t.files.some((f) => claimed.has(f)) ? 'conflict' : 'cap';
|
|
92
|
+
return { id: t.id, reason, blockedBy };
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=wave-scheduler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wave-scheduler.js","sourceRoot":"","sources":["../../src/lib/wave-scheduler.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,7 +7,8 @@ export const definition = {
|
|
|
7
7
|
name: `${brand.cliToolPrefix}exec_status`,
|
|
8
8
|
description: `Estado de uma execução delegada (\`${brand.cliToolPrefix}delegate_exec\`): running | done | failed, com o ` +
|
|
9
9
|
'resumo do agente, os arquivos alterados e os checks determinísticos (tamanho, lint, build, ' +
|
|
10
|
-
'testes). Use os checks como FATOS na sua revisão — não gaste
|
|
10
|
+
'testes) e os tokens gastos no run. Use os checks como FATOS na sua revisão — não gaste ' +
|
|
11
|
+
'ciclo revisando o mecânico.',
|
|
11
12
|
inputSchema: {
|
|
12
13
|
type: 'object',
|
|
13
14
|
properties: {
|
|
@@ -35,6 +36,7 @@ export async function handler(args, _ctx) {
|
|
|
35
36
|
exit_code: job.exitCode,
|
|
36
37
|
changed: job.changed,
|
|
37
38
|
checks: job.checks,
|
|
39
|
+
tokens: job.tokens,
|
|
38
40
|
failing_checks: failing,
|
|
39
41
|
summary: job.summary,
|
|
40
42
|
error: job.error,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"exec-status.js","sourceRoot":"","sources":["../../src/tools/exec-status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AACjD,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEpC,MAAM,UAAU,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;AAEpE,MAAM,CAAC,MAAM,UAAU,GAAS;IAC9B,IAAI,EAAE,GAAG,KAAK,CAAC,aAAa,aAAa;IACzC,WAAW,EACT,sCAAsC,KAAK,CAAC,aAAa,mDAAmD;QAC5G,6FAA6F;QAC7F,
|
|
1
|
+
{"version":3,"file":"exec-status.js","sourceRoot":"","sources":["../../src/tools/exec-status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AACjD,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEpC,MAAM,UAAU,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;AAEpE,MAAM,CAAC,MAAM,UAAU,GAAS;IAC9B,IAAI,EAAE,GAAG,KAAK,CAAC,aAAa,aAAa;IACzC,WAAW,EACT,sCAAsC,KAAK,CAAC,aAAa,mDAAmD;QAC5G,6FAA6F;QAC7F,yFAAyF;QACzF,6BAA6B;IAC/B,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,sBAAsB,KAAK,CAAC,aAAa,kBAAkB,EAAE;SACrG;QACD,QAAQ,EAAE,CAAC,QAAQ,CAAC;QACpB,oBAAoB,EAAE,KAAK;KAC5B;CACF,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,IAAa,EAAE,IAAiB;IAC5D,MAAM,MAAM,GAAG,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAC1C,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,OAAO,WAAW,CAAC,uBAAuB,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IACpE,CAAC;IAED,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACvC,IAAI,CAAC,GAAG;QAAE,OAAO,WAAW,CAAC,uBAAuB,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IAE1E,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC;SACvC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;SACxB,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC;IAEzB,OAAO,UAAU,CAAC;QAChB,EAAE,EAAE,GAAG,CAAC,EAAE;QACV,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,QAAQ,EAAE,GAAG,CAAC,QAAQ;QACtB,SAAS,EAAE,GAAG,CAAC,QAAQ;QACvB,OAAO,EAAE,GAAG,CAAC,OAAO;QACpB,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,cAAc,EAAE,OAAO;QACvB,OAAO,EAAE,GAAG,CAAC,OAAO;QACpB,KAAK,EAAE,GAAG,CAAC,KAAK;KACjB,CAAC,CAAC;AACL,CAAC"}
|
package/dist/tools/index.js
CHANGED
|
@@ -7,6 +7,7 @@ import * as createTask from './create-task.js';
|
|
|
7
7
|
import * as updateTask from './update-task.js';
|
|
8
8
|
import * as moveTask from './move-task.js';
|
|
9
9
|
import * as attachPr from './attach-pr.js';
|
|
10
|
+
import * as setReview from './set-review.js';
|
|
10
11
|
import * as commentTask from './comment-task.js';
|
|
11
12
|
import * as addChecklist from './add-checklist.js';
|
|
12
13
|
import * as startAllocation from './start-allocation.js';
|
|
@@ -30,6 +31,7 @@ export const tools = {
|
|
|
30
31
|
[updateTask.definition.name]: updateTask,
|
|
31
32
|
[moveTask.definition.name]: moveTask,
|
|
32
33
|
[attachPr.definition.name]: attachPr,
|
|
34
|
+
[setReview.definition.name]: setReview,
|
|
33
35
|
[commentTask.definition.name]: commentTask,
|
|
34
36
|
[addChecklist.definition.name]: addChecklist,
|
|
35
37
|
[startAllocation.definition.name]: startAllocation,
|
package/dist/tools/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { jsonResult, errorResult } from '../lib/tool-result.js';
|
|
3
|
+
import { resolveProjectConfig, isErrorResult } from '../lib/require-config.js';
|
|
4
|
+
import { buildCommentHistoryEntry } from './comment-task.js';
|
|
5
|
+
import { brand, env } from '../brand.js';
|
|
6
|
+
const VERDICTS = ['approved', 'changes_requested'];
|
|
7
|
+
const DEFAULT_REVIEWER = 'internal';
|
|
8
|
+
/** Status pra onde a task vai quando o veredito é `approved` e `advance=true`. */
|
|
9
|
+
const DONE_STATUS = 'done';
|
|
10
|
+
const ArgsSchema = z
|
|
11
|
+
.object({
|
|
12
|
+
task_id: z.uuid(),
|
|
13
|
+
verdict: z.enum(VERDICTS),
|
|
14
|
+
reviewer: z.string().min(1).optional(),
|
|
15
|
+
note: z.string().trim().min(1).max(5000).optional(),
|
|
16
|
+
advance: z.boolean().optional(),
|
|
17
|
+
project_id: z.uuid().optional(),
|
|
18
|
+
})
|
|
19
|
+
.strict();
|
|
20
|
+
export const definition = {
|
|
21
|
+
name: `${brand.toolPrefix}set_review`,
|
|
22
|
+
description: 'Registra o veredito de um review no ticket: seta `tasks.review_state`. ' +
|
|
23
|
+
'Com `verdict=approved` e `advance=true`, também move a task pra `done` e grava a entrega ' +
|
|
24
|
+
'(`nos_record_delivery` com `review_verdict=approved` e o `reviewer`). ' +
|
|
25
|
+
'Com `verdict=changes_requested`, mantém o status atual e, se `note` foi passada, posta o ' +
|
|
26
|
+
'parecer como comentário. Idempotente — rechamar com o mesmo veredito não duplica histórico/entrega. ' +
|
|
27
|
+
'Use depois que um review (interno ou externo) chega a um veredito sobre o PR do ticket.',
|
|
28
|
+
inputSchema: {
|
|
29
|
+
type: 'object',
|
|
30
|
+
properties: {
|
|
31
|
+
task_id: { type: 'string', format: 'uuid' },
|
|
32
|
+
verdict: {
|
|
33
|
+
type: 'string',
|
|
34
|
+
enum: [...VERDICTS],
|
|
35
|
+
description: 'Veredito do review: approved ou changes_requested.',
|
|
36
|
+
},
|
|
37
|
+
reviewer: {
|
|
38
|
+
type: 'string',
|
|
39
|
+
description: `Quem revisou (default "${DEFAULT_REVIEWER}"; ex.: internal, pr-reviewer).`,
|
|
40
|
+
},
|
|
41
|
+
note: {
|
|
42
|
+
type: 'string',
|
|
43
|
+
minLength: 1,
|
|
44
|
+
maxLength: 5000,
|
|
45
|
+
description: 'Parecer do review, postado como comentário quando verdict=changes_requested.',
|
|
46
|
+
},
|
|
47
|
+
advance: {
|
|
48
|
+
type: 'boolean',
|
|
49
|
+
description: `Se true e verdict=approved, move a task pra \`${DONE_STATUS}\` e grava a entrega.`,
|
|
50
|
+
},
|
|
51
|
+
project_id: {
|
|
52
|
+
type: 'string',
|
|
53
|
+
format: 'uuid',
|
|
54
|
+
description: `Override do projeto. Se omitido, usa o projeto ativo (${brand.toolPrefix}set_project) ou o default.`,
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
required: ['task_id', 'verdict'],
|
|
58
|
+
additionalProperties: false,
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* Diff entre o estado atual e o veredito alvo: patch de `review_state` + changes pro histórico
|
|
63
|
+
* + se deve mover pra `done` (só quando `approved` + `advance` + ainda não está lá). Só inclui
|
|
64
|
+
* o que mudou → idempotente. Pura.
|
|
65
|
+
*/
|
|
66
|
+
export function buildSetReviewPatch(current, verdict, advance) {
|
|
67
|
+
const patch = {};
|
|
68
|
+
const changes = [];
|
|
69
|
+
if (current.review_state !== verdict) {
|
|
70
|
+
patch.review_state = verdict;
|
|
71
|
+
changes.push({ field: 'review_state', old_value: current.review_state, new_value: verdict });
|
|
72
|
+
}
|
|
73
|
+
const moveToDone = verdict === 'approved' && advance && current.status !== DONE_STATUS;
|
|
74
|
+
return { patch: patch, changes, moveToDone };
|
|
75
|
+
}
|
|
76
|
+
/** Monta o payload de resposta do set_review a partir do estado atual + o que foi aplicado. Pura. */
|
|
77
|
+
export function buildSetReviewResult(current, taskId, verdict, reviewer, changes, movedToDone) {
|
|
78
|
+
return {
|
|
79
|
+
task_id: taskId,
|
|
80
|
+
key: current.key,
|
|
81
|
+
title: current.title,
|
|
82
|
+
review_state: verdict,
|
|
83
|
+
reviewer,
|
|
84
|
+
status: movedToDone ? DONE_STATUS : current.status,
|
|
85
|
+
previous_status: current.status,
|
|
86
|
+
moved_to_done: movedToDone,
|
|
87
|
+
changed_fields: changes.map((c) => c.field),
|
|
88
|
+
already_set: changes.length === 0 && !movedToDone,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
export async function handler(args, ctx) {
|
|
92
|
+
const parsed = ArgsSchema.safeParse(args);
|
|
93
|
+
if (!parsed.success)
|
|
94
|
+
return errorResult(`Argumento inválido: ${parsed.error.message}`);
|
|
95
|
+
const { task_id, verdict, note } = parsed.data;
|
|
96
|
+
const reviewer = parsed.data.reviewer ?? DEFAULT_REVIEWER;
|
|
97
|
+
const advance = parsed.data.advance ?? false;
|
|
98
|
+
const cfg = resolveProjectConfig(ctx, parsed.data.project_id);
|
|
99
|
+
if (isErrorResult(cfg))
|
|
100
|
+
return cfg;
|
|
101
|
+
try {
|
|
102
|
+
const current = await ctx.gateway.getTaskForSetReview(task_id, cfg.project_id);
|
|
103
|
+
if (!current)
|
|
104
|
+
return errorResult('Tarefa não encontrada ou fora do projeto atual.');
|
|
105
|
+
const { patch, changes, moveToDone } = buildSetReviewPatch(current, verdict, advance);
|
|
106
|
+
if (Object.keys(patch).length > 0) {
|
|
107
|
+
await ctx.gateway.applyTaskPatch(task_id, cfg.project_id, ctx.user.id, patch, changes);
|
|
108
|
+
}
|
|
109
|
+
if (moveToDone) {
|
|
110
|
+
await ctx.gateway.moveTaskStatus(task_id, cfg.project_id, DONE_STATUS, ctx.user.id, current.status);
|
|
111
|
+
await ctx.gateway.recordDelivery({
|
|
112
|
+
user_id: ctx.user.id,
|
|
113
|
+
project_id: cfg.project_id,
|
|
114
|
+
task_id,
|
|
115
|
+
title: current.title,
|
|
116
|
+
pr_url: current.pr_url,
|
|
117
|
+
iterations: null,
|
|
118
|
+
client: env('CLIENT') ?? null,
|
|
119
|
+
review_verdict: 'approved',
|
|
120
|
+
reviewer,
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
if (verdict === 'changes_requested' && note) {
|
|
124
|
+
await ctx.gateway.commentTask(task_id, cfg.project_id, ctx.user.id, note, buildCommentHistoryEntry(task_id, ctx.user.id, note));
|
|
125
|
+
}
|
|
126
|
+
return jsonResult(buildSetReviewResult(current, task_id, verdict, reviewer, changes, moveToDone));
|
|
127
|
+
}
|
|
128
|
+
catch (err) {
|
|
129
|
+
return errorResult(err.message);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=set-review.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"set-review.js","sourceRoot":"","sources":["../../src/tools/set-review.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED