sincron-plan 1.0.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/LICENSE +20 -0
- package/README.md +192 -0
- package/agents/mapeador.md +232 -0
- package/agents/pesquisador.md +198 -0
- package/agents/planejador.md +230 -0
- package/agents/questionador.md +156 -0
- package/bin/install.js +423 -0
- package/commands/sincron-map.md +190 -0
- package/commands/sincron-plan.md +412 -0
- package/docs/arquitetura.md +106 -0
- package/docs/fluxo.md +166 -0
- package/package.json +42 -0
- package/templates/PRD.md +101 -0
- package/templates/ROADMAP.md +101 -0
- package/templates/codebase/ARCHITECTURE.md +45 -0
- package/templates/codebase/CONCERNS.md +53 -0
- package/templates/codebase/STACK.md +34 -0
- package/templates/codebase/STRUCTURE.md +46 -0
package/bin/install.js
ADDED
|
@@ -0,0 +1,423 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const os = require('os');
|
|
6
|
+
const readline = require('readline');
|
|
7
|
+
|
|
8
|
+
// Colors
|
|
9
|
+
const cyan = '\x1b[36m';
|
|
10
|
+
const green = '\x1b[32m';
|
|
11
|
+
const yellow = '\x1b[33m';
|
|
12
|
+
const dim = '\x1b[2m';
|
|
13
|
+
const reset = '\x1b[0m';
|
|
14
|
+
|
|
15
|
+
// Get version from package.json
|
|
16
|
+
const pkg = require('../package.json');
|
|
17
|
+
|
|
18
|
+
// Parse args
|
|
19
|
+
const args = process.argv.slice(2);
|
|
20
|
+
const hasGlobal = args.includes('--global') || args.includes('-g');
|
|
21
|
+
const hasLocal = args.includes('--local') || args.includes('-l');
|
|
22
|
+
const hasUninstall = args.includes('--uninstall') || args.includes('-u');
|
|
23
|
+
const hasHelp = args.includes('--help') || args.includes('-h');
|
|
24
|
+
|
|
25
|
+
// Parse --config-dir argument
|
|
26
|
+
function parseConfigDirArg() {
|
|
27
|
+
const configDirIndex = args.findIndex(arg => arg === '--config-dir' || arg === '-c');
|
|
28
|
+
if (configDirIndex !== -1) {
|
|
29
|
+
const nextArg = args[configDirIndex + 1];
|
|
30
|
+
if (!nextArg || nextArg.startsWith('-')) {
|
|
31
|
+
console.error(` ${yellow}--config-dir requires a path argument${reset}`);
|
|
32
|
+
process.exit(1);
|
|
33
|
+
}
|
|
34
|
+
return nextArg;
|
|
35
|
+
}
|
|
36
|
+
const configDirArg = args.find(arg => arg.startsWith('--config-dir=') || arg.startsWith('-c='));
|
|
37
|
+
if (configDirArg) {
|
|
38
|
+
const value = configDirArg.split('=')[1];
|
|
39
|
+
if (!value) {
|
|
40
|
+
console.error(` ${yellow}--config-dir requires a non-empty path${reset}`);
|
|
41
|
+
process.exit(1);
|
|
42
|
+
}
|
|
43
|
+
return value;
|
|
44
|
+
}
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
const explicitConfigDir = parseConfigDirArg();
|
|
48
|
+
|
|
49
|
+
const banner = `
|
|
50
|
+
${cyan} ███████╗ ██╗ ███╗ ██╗ ██████╗ ██████╗ ██████╗ ███╗ ██╗
|
|
51
|
+
██╔════╝ ██║ ████╗ ██║ ██╔════╝ ██╔══██╗ ██╔═══██╗ ████╗ ██║
|
|
52
|
+
███████╗ ██║ ██╔██╗ ██║ ██║ ██████╔╝ ██║ ██║ ██╔██╗ ██║
|
|
53
|
+
╚════██║ ██║ ██║╚██╗██║ ██║ ██╔══██╗ ██║ ██║ ██║╚██╗██║
|
|
54
|
+
███████║ ██║ ██║ ╚████║ ╚██████╗ ██║ ██║ ╚██████╔╝ ██║ ╚████║
|
|
55
|
+
╚══════╝ ╚═╝ ╚═╝ ╚═══╝ ╚═════╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═══╝${reset}
|
|
56
|
+
|
|
57
|
+
${green}Sincron-Plan${reset} ${dim}v${pkg.version}${reset}
|
|
58
|
+
Plugin de planejamento estruturado para Claude Code.
|
|
59
|
+
Do requisito ao PRD, com questionamento inteligente.
|
|
60
|
+
`;
|
|
61
|
+
|
|
62
|
+
console.log(banner);
|
|
63
|
+
|
|
64
|
+
// Show help if requested
|
|
65
|
+
if (hasHelp) {
|
|
66
|
+
console.log(` ${yellow}Uso:${reset} npx sincron-plan [opções]
|
|
67
|
+
|
|
68
|
+
${yellow}Opções:${reset}
|
|
69
|
+
${cyan}-g, --global${reset} Instalar globalmente (~/.claude)
|
|
70
|
+
${cyan}-l, --local${reset} Instalar localmente (./.claude)
|
|
71
|
+
${cyan}-u, --uninstall${reset} Desinstalar Sincron-Plan
|
|
72
|
+
${cyan}-c, --config-dir <path>${reset} Especificar diretório de config
|
|
73
|
+
${cyan}-h, --help${reset} Mostrar esta ajuda
|
|
74
|
+
|
|
75
|
+
${yellow}Exemplos:${reset}
|
|
76
|
+
${dim}# Instalação interativa${reset}
|
|
77
|
+
npx sincron-plan
|
|
78
|
+
|
|
79
|
+
${dim}# Instalar globalmente${reset}
|
|
80
|
+
npx sincron-plan --global
|
|
81
|
+
|
|
82
|
+
${dim}# Instalar apenas no projeto atual${reset}
|
|
83
|
+
npx sincron-plan --local
|
|
84
|
+
|
|
85
|
+
${dim}# Desinstalar globalmente${reset}
|
|
86
|
+
npx sincron-plan --global --uninstall
|
|
87
|
+
|
|
88
|
+
${yellow}Comandos disponíveis após instalação:${reset}
|
|
89
|
+
${cyan}/sincron-plan${reset} [descrição] - Planejamento estruturado com PRD
|
|
90
|
+
${cyan}/sincron-map${reset} - Mapear codebase existente
|
|
91
|
+
`);
|
|
92
|
+
process.exit(0);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Expand ~ to home directory
|
|
97
|
+
*/
|
|
98
|
+
function expandTilde(filePath) {
|
|
99
|
+
if (filePath && filePath.startsWith('~/')) {
|
|
100
|
+
return path.join(os.homedir(), filePath.slice(2));
|
|
101
|
+
}
|
|
102
|
+
return filePath;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Get the global config directory for Claude Code
|
|
107
|
+
*/
|
|
108
|
+
function getGlobalDir(explicitDir = null) {
|
|
109
|
+
if (explicitDir) {
|
|
110
|
+
return expandTilde(explicitDir);
|
|
111
|
+
}
|
|
112
|
+
if (process.env.CLAUDE_CONFIG_DIR) {
|
|
113
|
+
return expandTilde(process.env.CLAUDE_CONFIG_DIR);
|
|
114
|
+
}
|
|
115
|
+
return path.join(os.homedir(), '.claude');
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Read and parse settings.json
|
|
120
|
+
*/
|
|
121
|
+
function readSettings(settingsPath) {
|
|
122
|
+
if (fs.existsSync(settingsPath)) {
|
|
123
|
+
try {
|
|
124
|
+
return JSON.parse(fs.readFileSync(settingsPath, 'utf8'));
|
|
125
|
+
} catch (e) {
|
|
126
|
+
return {};
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return {};
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Write settings.json with proper formatting
|
|
134
|
+
*/
|
|
135
|
+
function writeSettings(settingsPath, settings) {
|
|
136
|
+
fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + '\n');
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Recursively copy directory, replacing paths in .md files
|
|
141
|
+
*/
|
|
142
|
+
function copyWithPathReplacement(srcDir, destDir, pathPrefix) {
|
|
143
|
+
if (fs.existsSync(destDir)) {
|
|
144
|
+
fs.rmSync(destDir, { recursive: true });
|
|
145
|
+
}
|
|
146
|
+
fs.mkdirSync(destDir, { recursive: true });
|
|
147
|
+
|
|
148
|
+
const entries = fs.readdirSync(srcDir, { withFileTypes: true });
|
|
149
|
+
|
|
150
|
+
for (const entry of entries) {
|
|
151
|
+
const srcPath = path.join(srcDir, entry.name);
|
|
152
|
+
const destPath = path.join(destDir, entry.name);
|
|
153
|
+
|
|
154
|
+
if (entry.isDirectory()) {
|
|
155
|
+
copyWithPathReplacement(srcPath, destPath, pathPrefix);
|
|
156
|
+
} else if (entry.name.endsWith('.md')) {
|
|
157
|
+
let content = fs.readFileSync(srcPath, 'utf8');
|
|
158
|
+
content = content.replace(/~\/\.claude\//g, pathPrefix);
|
|
159
|
+
fs.writeFileSync(destPath, content);
|
|
160
|
+
} else {
|
|
161
|
+
fs.copyFileSync(srcPath, destPath);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Verify a directory exists and contains files
|
|
168
|
+
*/
|
|
169
|
+
function verifyInstalled(dirPath, description) {
|
|
170
|
+
if (!fs.existsSync(dirPath)) {
|
|
171
|
+
console.error(` ${yellow}✗${reset} Falha ao instalar ${description}: diretório não criado`);
|
|
172
|
+
return false;
|
|
173
|
+
}
|
|
174
|
+
try {
|
|
175
|
+
const entries = fs.readdirSync(dirPath);
|
|
176
|
+
if (entries.length === 0) {
|
|
177
|
+
console.error(` ${yellow}✗${reset} Falha ao instalar ${description}: diretório vazio`);
|
|
178
|
+
return false;
|
|
179
|
+
}
|
|
180
|
+
} catch (e) {
|
|
181
|
+
console.error(` ${yellow}✗${reset} Falha ao instalar ${description}: ${e.message}`);
|
|
182
|
+
return false;
|
|
183
|
+
}
|
|
184
|
+
return true;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Uninstall Sincron-Plan from the specified directory
|
|
189
|
+
*/
|
|
190
|
+
function uninstall(isGlobal) {
|
|
191
|
+
const targetDir = isGlobal
|
|
192
|
+
? getGlobalDir(explicitConfigDir)
|
|
193
|
+
: path.join(process.cwd(), '.claude');
|
|
194
|
+
|
|
195
|
+
const locationLabel = isGlobal
|
|
196
|
+
? targetDir.replace(os.homedir(), '~')
|
|
197
|
+
: targetDir.replace(process.cwd(), '.');
|
|
198
|
+
|
|
199
|
+
console.log(` Desinstalando Sincron-Plan de ${cyan}${locationLabel}${reset}\n`);
|
|
200
|
+
|
|
201
|
+
if (!fs.existsSync(targetDir)) {
|
|
202
|
+
console.log(` ${yellow}⚠${reset} Diretório não existe: ${locationLabel}`);
|
|
203
|
+
console.log(` Nada para desinstalar.\n`);
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
let removedCount = 0;
|
|
208
|
+
|
|
209
|
+
// 1. Remove sincron-plan commands
|
|
210
|
+
const commandsToRemove = ['sincron-plan.md', 'sincron-map.md'];
|
|
211
|
+
const commandsDir = path.join(targetDir, 'commands');
|
|
212
|
+
if (fs.existsSync(commandsDir)) {
|
|
213
|
+
for (const cmd of commandsToRemove) {
|
|
214
|
+
const cmdPath = path.join(commandsDir, cmd);
|
|
215
|
+
if (fs.existsSync(cmdPath)) {
|
|
216
|
+
fs.unlinkSync(cmdPath);
|
|
217
|
+
removedCount++;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
if (removedCount > 0) {
|
|
221
|
+
console.log(` ${green}✓${reset} Removidos ${removedCount} comandos`);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// 2. Remove sincron-plan agents
|
|
226
|
+
const agentsDir = path.join(targetDir, 'agents');
|
|
227
|
+
if (fs.existsSync(agentsDir)) {
|
|
228
|
+
const agentsToRemove = ['questionador.md', 'pesquisador.md', 'mapeador.md', 'planejador.md'];
|
|
229
|
+
let agentCount = 0;
|
|
230
|
+
for (const agent of agentsToRemove) {
|
|
231
|
+
const agentPath = path.join(agentsDir, agent);
|
|
232
|
+
if (fs.existsSync(agentPath)) {
|
|
233
|
+
fs.unlinkSync(agentPath);
|
|
234
|
+
agentCount++;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
if (agentCount > 0) {
|
|
238
|
+
removedCount++;
|
|
239
|
+
console.log(` ${green}✓${reset} Removidos ${agentCount} agentes`);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// 3. Remove sincron-plan templates
|
|
244
|
+
const templatesDir = path.join(targetDir, 'sincron-plan');
|
|
245
|
+
if (fs.existsSync(templatesDir)) {
|
|
246
|
+
fs.rmSync(templatesDir, { recursive: true });
|
|
247
|
+
removedCount++;
|
|
248
|
+
console.log(` ${green}✓${reset} Removido sincron-plan/`);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
if (removedCount === 0) {
|
|
252
|
+
console.log(` ${yellow}⚠${reset} Nenhum arquivo do Sincron-Plan encontrado.`);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
console.log(`
|
|
256
|
+
${green}Pronto!${reset} Sincron-Plan foi desinstalado.
|
|
257
|
+
Seus outros arquivos e configurações foram preservados.
|
|
258
|
+
`);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Install Sincron-Plan to the specified directory
|
|
263
|
+
*/
|
|
264
|
+
function install(isGlobal) {
|
|
265
|
+
const src = path.join(__dirname, '..');
|
|
266
|
+
const targetDir = isGlobal
|
|
267
|
+
? getGlobalDir(explicitConfigDir)
|
|
268
|
+
: path.join(process.cwd(), '.claude');
|
|
269
|
+
|
|
270
|
+
const locationLabel = isGlobal
|
|
271
|
+
? targetDir.replace(os.homedir(), '~')
|
|
272
|
+
: targetDir.replace(process.cwd(), '.');
|
|
273
|
+
|
|
274
|
+
const pathPrefix = isGlobal
|
|
275
|
+
? `${targetDir}/`
|
|
276
|
+
: './.claude/';
|
|
277
|
+
|
|
278
|
+
console.log(` Instalando em ${cyan}${locationLabel}${reset}\n`);
|
|
279
|
+
|
|
280
|
+
const failures = [];
|
|
281
|
+
|
|
282
|
+
// 1. Create directories
|
|
283
|
+
fs.mkdirSync(path.join(targetDir, 'commands'), { recursive: true });
|
|
284
|
+
fs.mkdirSync(path.join(targetDir, 'agents'), { recursive: true });
|
|
285
|
+
|
|
286
|
+
// 2. Copy commands
|
|
287
|
+
const commandsSrc = path.join(src, 'commands');
|
|
288
|
+
if (fs.existsSync(commandsSrc)) {
|
|
289
|
+
const commandFiles = fs.readdirSync(commandsSrc).filter(f => f.endsWith('.md'));
|
|
290
|
+
for (const file of commandFiles) {
|
|
291
|
+
let content = fs.readFileSync(path.join(commandsSrc, file), 'utf8');
|
|
292
|
+
content = content.replace(/~\/\.claude\//g, pathPrefix);
|
|
293
|
+
fs.writeFileSync(path.join(targetDir, 'commands', file), content);
|
|
294
|
+
}
|
|
295
|
+
console.log(` ${green}✓${reset} Instalados ${commandFiles.length} comandos`);
|
|
296
|
+
} else {
|
|
297
|
+
failures.push('commands');
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
// 3. Copy agents
|
|
301
|
+
const agentsSrc = path.join(src, 'agents');
|
|
302
|
+
if (fs.existsSync(agentsSrc)) {
|
|
303
|
+
const agentFiles = fs.readdirSync(agentsSrc).filter(f => f.endsWith('.md'));
|
|
304
|
+
for (const file of agentFiles) {
|
|
305
|
+
let content = fs.readFileSync(path.join(agentsSrc, file), 'utf8');
|
|
306
|
+
content = content.replace(/~\/\.claude\//g, pathPrefix);
|
|
307
|
+
fs.writeFileSync(path.join(targetDir, 'agents', file), content);
|
|
308
|
+
}
|
|
309
|
+
console.log(` ${green}✓${reset} Instalados ${agentFiles.length} agentes`);
|
|
310
|
+
} else {
|
|
311
|
+
failures.push('agents');
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
// 4. Copy templates to sincron-plan directory
|
|
315
|
+
const templatesSrc = path.join(src, 'templates');
|
|
316
|
+
const templatesDest = path.join(targetDir, 'sincron-plan', 'templates');
|
|
317
|
+
if (fs.existsSync(templatesSrc)) {
|
|
318
|
+
copyWithPathReplacement(templatesSrc, templatesDest, pathPrefix);
|
|
319
|
+
if (verifyInstalled(templatesDest, 'templates')) {
|
|
320
|
+
console.log(` ${green}✓${reset} Instalados templates`);
|
|
321
|
+
} else {
|
|
322
|
+
failures.push('templates');
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
// 5. Copy docs
|
|
327
|
+
const docsSrc = path.join(src, 'docs');
|
|
328
|
+
const docsDest = path.join(targetDir, 'sincron-plan', 'docs');
|
|
329
|
+
if (fs.existsSync(docsSrc)) {
|
|
330
|
+
copyWithPathReplacement(docsSrc, docsDest, pathPrefix);
|
|
331
|
+
if (verifyInstalled(docsDest, 'docs')) {
|
|
332
|
+
console.log(` ${green}✓${reset} Instalada documentação`);
|
|
333
|
+
} else {
|
|
334
|
+
failures.push('docs');
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
// 6. Write VERSION file
|
|
339
|
+
const versionDest = path.join(targetDir, 'sincron-plan', 'VERSION');
|
|
340
|
+
fs.mkdirSync(path.dirname(versionDest), { recursive: true });
|
|
341
|
+
fs.writeFileSync(versionDest, pkg.version);
|
|
342
|
+
console.log(` ${green}✓${reset} Escrito VERSION (${pkg.version})`);
|
|
343
|
+
|
|
344
|
+
if (failures.length > 0) {
|
|
345
|
+
console.error(`\n ${yellow}Instalação incompleta!${reset} Falhou: ${failures.join(', ')}`);
|
|
346
|
+
process.exit(1);
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
console.log(`
|
|
350
|
+
${green}Pronto!${reset} Abra o Claude Code e execute ${cyan}/sincron-plan${reset} ou ${cyan}/sincron-map${reset}.
|
|
351
|
+
|
|
352
|
+
${cyan}Comandos disponíveis:${reset}
|
|
353
|
+
/sincron-plan [descrição] - Planejamento estruturado com PRD
|
|
354
|
+
/sincron-map - Mapear codebase existente
|
|
355
|
+
|
|
356
|
+
${cyan}Dica:${reset} Sincron-Plan funciona junto com Sincron-Auto!
|
|
357
|
+
Use /sincron-plan para planejar e /sincron-auto para executar.
|
|
358
|
+
|
|
359
|
+
${cyan}Documentação:${reset} https://github.com/MLTCorp/sincron-auto/tree/sincron-plan
|
|
360
|
+
`);
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
/**
|
|
364
|
+
* Prompt for install location
|
|
365
|
+
*/
|
|
366
|
+
function promptLocation() {
|
|
367
|
+
if (!process.stdin.isTTY) {
|
|
368
|
+
console.log(` ${yellow}Terminal não-interativo detectado, usando instalação global${reset}\n`);
|
|
369
|
+
install(true);
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
const rl = readline.createInterface({
|
|
374
|
+
input: process.stdin,
|
|
375
|
+
output: process.stdout
|
|
376
|
+
});
|
|
377
|
+
|
|
378
|
+
let answered = false;
|
|
379
|
+
|
|
380
|
+
rl.on('close', () => {
|
|
381
|
+
if (!answered) {
|
|
382
|
+
answered = true;
|
|
383
|
+
console.log(`\n ${yellow}Instalação cancelada${reset}\n`);
|
|
384
|
+
process.exit(0);
|
|
385
|
+
}
|
|
386
|
+
});
|
|
387
|
+
|
|
388
|
+
const globalPath = getGlobalDir(explicitConfigDir).replace(os.homedir(), '~');
|
|
389
|
+
|
|
390
|
+
console.log(` ${yellow}Onde você quer instalar?${reset}
|
|
391
|
+
|
|
392
|
+
${cyan}1${reset}) Global ${dim}(${globalPath})${reset} - disponível em todos os projetos
|
|
393
|
+
${cyan}2${reset}) Local ${dim}(./.claude)${reset} - apenas neste projeto
|
|
394
|
+
`);
|
|
395
|
+
|
|
396
|
+
rl.question(` Escolha ${dim}[1]${reset}: `, (answer) => {
|
|
397
|
+
answered = true;
|
|
398
|
+
rl.close();
|
|
399
|
+
const choice = answer.trim() || '1';
|
|
400
|
+
const isGlobal = choice !== '2';
|
|
401
|
+
install(isGlobal);
|
|
402
|
+
});
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
// Main
|
|
406
|
+
if (hasGlobal && hasLocal) {
|
|
407
|
+
console.error(` ${yellow}Não é possível especificar --global e --local juntos${reset}`);
|
|
408
|
+
process.exit(1);
|
|
409
|
+
} else if (explicitConfigDir && hasLocal) {
|
|
410
|
+
console.error(` ${yellow}Não é possível usar --config-dir com --local${reset}`);
|
|
411
|
+
process.exit(1);
|
|
412
|
+
} else if (hasUninstall) {
|
|
413
|
+
if (!hasGlobal && !hasLocal) {
|
|
414
|
+
console.error(` ${yellow}--uninstall requer --global ou --local${reset}`);
|
|
415
|
+
console.error(` Exemplo: npx sincron-plan --global --uninstall`);
|
|
416
|
+
process.exit(1);
|
|
417
|
+
}
|
|
418
|
+
uninstall(hasGlobal);
|
|
419
|
+
} else if (hasGlobal || hasLocal) {
|
|
420
|
+
install(hasGlobal);
|
|
421
|
+
} else {
|
|
422
|
+
promptLocation();
|
|
423
|
+
}
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sincron-map
|
|
3
|
+
description: Mapeia codebase existente gerando documentação estruturada
|
|
4
|
+
allowed-tools:
|
|
5
|
+
- Read
|
|
6
|
+
- Write
|
|
7
|
+
- Glob
|
|
8
|
+
- Grep
|
|
9
|
+
- Bash
|
|
10
|
+
- Task
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# /sincron-map - Mapeamento de Codebase
|
|
14
|
+
|
|
15
|
+
## Propósito
|
|
16
|
+
Analisar codebase existente e gerar documentação estruturada em `.sincron-plan/codebase/`.
|
|
17
|
+
|
|
18
|
+
## Quando Usar
|
|
19
|
+
- Projetos brownfield (código existente)
|
|
20
|
+
- Antes de planejar trabalho em código desconhecido
|
|
21
|
+
- Onboarding em projeto novo
|
|
22
|
+
|
|
23
|
+
## Instruções de Execução
|
|
24
|
+
|
|
25
|
+
### FASE 1: Verificar Mapeamento Existente
|
|
26
|
+
|
|
27
|
+
Verificar se `.sincron-plan/codebase/` existe e contém os 4 documentos.
|
|
28
|
+
|
|
29
|
+
**SE existe mapeamento completo:**
|
|
30
|
+
Perguntar ao usuário usando AskUserQuestion:
|
|
31
|
+
```
|
|
32
|
+
"Encontrei mapeamento existente em .sincron-plan/codebase/. O que deseja fazer?"
|
|
33
|
+
Opções:
|
|
34
|
+
- "Atualizar" - Refazer o mapeamento
|
|
35
|
+
- "Usar existente" - Manter o atual
|
|
36
|
+
- "Ignorar" - Começar do zero
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
**SE não existe ou está incompleto:**
|
|
40
|
+
Continuar para Fase 2.
|
|
41
|
+
|
|
42
|
+
### FASE 2: Criar Diretório de Output
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
mkdir -p .sincron-plan/codebase
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### FASE 3: Spawnar Agentes Mapeadores em Paralelo
|
|
49
|
+
|
|
50
|
+
**IMPORTANTE**: Spawnar exatamente 2 agentes em paralelo para arquitetura anti-OOM.
|
|
51
|
+
|
|
52
|
+
**Agente 1 - Tech/Arch:**
|
|
53
|
+
```
|
|
54
|
+
Task(
|
|
55
|
+
subagent_type: "general-purpose",
|
|
56
|
+
prompt: "Você é o Mapeador (Instância Tech/Arch).
|
|
57
|
+
|
|
58
|
+
Sua missão: Analisar o codebase neste diretório e gerar 2 documentos:
|
|
59
|
+
1. .sincron-plan/codebase/STACK.md
|
|
60
|
+
2. .sincron-plan/codebase/ARCHITECTURE.md
|
|
61
|
+
|
|
62
|
+
Siga as instruções detalhadas em sincron-plan/agents/mapeador.md.
|
|
63
|
+
Use os templates em sincron-plan/templates/codebase/.
|
|
64
|
+
|
|
65
|
+
Processo:
|
|
66
|
+
1. Glob para encontrar arquivos de configuração (package.json, tsconfig.json, etc)
|
|
67
|
+
2. Read arquivos de configuração para identificar stack
|
|
68
|
+
3. Glob para mapear estrutura de diretórios
|
|
69
|
+
4. Grep para identificar patterns de arquitetura
|
|
70
|
+
5. Escrever STACK.md com tecnologias e dependências
|
|
71
|
+
6. Escrever ARCHITECTURE.md com padrões e fluxos
|
|
72
|
+
|
|
73
|
+
Retorne APENAS:
|
|
74
|
+
mapping_complete
|
|
75
|
+
Files:
|
|
76
|
+
- .sincron-plan/codebase/STACK.md ([N] lines)
|
|
77
|
+
- .sincron-plan/codebase/ARCHITECTURE.md ([N] lines)"
|
|
78
|
+
)
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
**Agente 2 - Quality/Risk:**
|
|
82
|
+
```
|
|
83
|
+
Task(
|
|
84
|
+
subagent_type: "general-purpose",
|
|
85
|
+
prompt: "Você é o Mapeador (Instância Quality/Risk).
|
|
86
|
+
|
|
87
|
+
Sua missão: Analisar o codebase neste diretório e gerar 2 documentos:
|
|
88
|
+
1. .sincron-plan/codebase/STRUCTURE.md
|
|
89
|
+
2. .sincron-plan/codebase/CONCERNS.md
|
|
90
|
+
|
|
91
|
+
Siga as instruções detalhadas em sincron-plan/agents/mapeador.md.
|
|
92
|
+
Use os templates em sincron-plan/templates/codebase/.
|
|
93
|
+
|
|
94
|
+
Processo:
|
|
95
|
+
1. Glob/Bash para mapear estrutura de diretórios
|
|
96
|
+
2. Read arquivos índice e principais
|
|
97
|
+
3. Grep para TODO, FIXME, HACK, @deprecated
|
|
98
|
+
4. Identificar convenções de nomenclatura
|
|
99
|
+
5. Escrever STRUCTURE.md com organização e guias
|
|
100
|
+
6. Escrever CONCERNS.md com débitos e riscos
|
|
101
|
+
|
|
102
|
+
Retorne APENAS:
|
|
103
|
+
mapping_complete
|
|
104
|
+
Files:
|
|
105
|
+
- .sincron-plan/codebase/STRUCTURE.md ([N] lines)
|
|
106
|
+
- .sincron-plan/codebase/CONCERNS.md ([N] lines)"
|
|
107
|
+
)
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### FASE 4: Aguardar e Verificar
|
|
111
|
+
|
|
112
|
+
Aguardar ambos agentes retornarem.
|
|
113
|
+
|
|
114
|
+
**Verificação de qualidade:**
|
|
115
|
+
- Todos 4 documentos existem em `.sincron-plan/codebase/`
|
|
116
|
+
- Cada documento tem >20 linhas
|
|
117
|
+
- Nenhum documento tem placeholders `[TBD]` ou `[TODO]`
|
|
118
|
+
|
|
119
|
+
**SE verificação falhar:**
|
|
120
|
+
Informar qual documento está incompleto e oferecer re-executar.
|
|
121
|
+
|
|
122
|
+
### FASE 5: Atualizar State
|
|
123
|
+
|
|
124
|
+
Criar ou atualizar `.sincron-plan/state.json`:
|
|
125
|
+
```json
|
|
126
|
+
{
|
|
127
|
+
"status": "mapped",
|
|
128
|
+
"project_name": "[detectar do package.json ou diretório]",
|
|
129
|
+
"has_codebase_map": true,
|
|
130
|
+
"mapping_date": "[YYYY-MM-DD]",
|
|
131
|
+
"files": {
|
|
132
|
+
"STACK.md": "[N] lines",
|
|
133
|
+
"ARCHITECTURE.md": "[N] lines",
|
|
134
|
+
"STRUCTURE.md": "[N] lines",
|
|
135
|
+
"CONCERNS.md": "[N] lines"
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### FASE 6: Exibir Resumo
|
|
141
|
+
|
|
142
|
+
```markdown
|
|
143
|
+
## ✅ Mapeamento Completo
|
|
144
|
+
|
|
145
|
+
Documentação gerada em `.sincron-plan/codebase/`:
|
|
146
|
+
|
|
147
|
+
| Documento | Linhas | Conteúdo |
|
|
148
|
+
|-----------|--------|----------|
|
|
149
|
+
| STACK.md | [N] | Tecnologias e dependências |
|
|
150
|
+
| ARCHITECTURE.md | [N] | Padrões e fluxos de dados |
|
|
151
|
+
| STRUCTURE.md | [N] | Organização e convenções |
|
|
152
|
+
| CONCERNS.md | [N] | Débitos técnicos e riscos |
|
|
153
|
+
|
|
154
|
+
### Próximo Passo
|
|
155
|
+
Execute `/sincron-plan` para iniciar o planejamento estruturado.
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## Tratamento de Erros
|
|
159
|
+
|
|
160
|
+
### Diretório Vazio
|
|
161
|
+
```
|
|
162
|
+
"Este diretório parece estar vazio ou não contém código fonte.
|
|
163
|
+
O mapeamento requer um projeto existente.
|
|
164
|
+
|
|
165
|
+
Para projetos novos (greenfield), use diretamente /sincron-plan."
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### Linguagem Não Identificada
|
|
169
|
+
```
|
|
170
|
+
"Não consegui identificar a linguagem/stack principal.
|
|
171
|
+
Arquivos encontrados: [lista]
|
|
172
|
+
|
|
173
|
+
Deseja continuar mesmo assim? O mapeamento pode estar incompleto."
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### Agente Falhou
|
|
177
|
+
```
|
|
178
|
+
"O mapeamento de [STACK/ARCHITECTURE/STRUCTURE/CONCERNS] falhou.
|
|
179
|
+
Erro: [mensagem]
|
|
180
|
+
|
|
181
|
+
Deseja tentar novamente apenas este documento?"
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
## Output Final
|
|
185
|
+
|
|
186
|
+
Diretório `.sincron-plan/codebase/` com:
|
|
187
|
+
- `STACK.md` - Stack tecnológico
|
|
188
|
+
- `ARCHITECTURE.md` - Padrões arquiteturais
|
|
189
|
+
- `STRUCTURE.md` - Organização do código
|
|
190
|
+
- `CONCERNS.md` - Débitos e riscos
|