agent-mp 0.5.38 → 0.5.40
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/dist/commands/repl.js +97 -45
- package/dist/commands/setup.js +51 -10
- package/dist/core/engine.js +144 -290
- package/dist/ui/theme.d.ts +1 -0
- package/dist/ui/theme.js +4 -1
- package/package.json +1 -1
package/dist/commands/repl.js
CHANGED
|
@@ -190,7 +190,7 @@ function detectInstalledClis() {
|
|
|
190
190
|
}
|
|
191
191
|
return installed;
|
|
192
192
|
}
|
|
193
|
-
function detectModels(cliName) {
|
|
193
|
+
async function detectModels(cliName) {
|
|
194
194
|
try {
|
|
195
195
|
switch (cliName) {
|
|
196
196
|
case 'claude': {
|
|
@@ -225,17 +225,61 @@ function detectModels(cliName) {
|
|
|
225
225
|
case 'agent-impl':
|
|
226
226
|
case 'agent-rev':
|
|
227
227
|
case 'agent-explorer': {
|
|
228
|
+
const found = [];
|
|
229
|
+
const add = (m) => { if (m && !found.includes(m))
|
|
230
|
+
found.push(m); };
|
|
231
|
+
// For each sub-agent home dir, read each provider's key file
|
|
232
|
+
// and live-fetch the available models from that provider's API.
|
|
228
233
|
for (const dir of [`.${cliName}`, '.agent-mp']) {
|
|
234
|
+
const homeDir = path.join(os.homedir(), dir);
|
|
235
|
+
// Qwen / OpenAI-compatible
|
|
229
236
|
try {
|
|
230
|
-
const cfg = JSON.parse(fsSync.readFileSync(path.join(
|
|
231
|
-
if (cfg
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
237
|
+
const cfg = JSON.parse(fsSync.readFileSync(path.join(homeDir, 'api_key.json'), 'utf-8'));
|
|
238
|
+
if (cfg?.api_key) {
|
|
239
|
+
const remote = await fetchApiKeyModels(cfg);
|
|
240
|
+
if (remote.length)
|
|
241
|
+
remote.forEach(add);
|
|
242
|
+
else
|
|
243
|
+
add(cfg.model);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
catch { }
|
|
247
|
+
// Gemini
|
|
248
|
+
try {
|
|
249
|
+
const cfg = JSON.parse(fsSync.readFileSync(path.join(homeDir, 'gemini_key.json'), 'utf-8'));
|
|
250
|
+
if (cfg?.api_key) {
|
|
251
|
+
const remote = await fetchGeminiModels(cfg);
|
|
252
|
+
if (remote.length)
|
|
253
|
+
remote.forEach(add);
|
|
254
|
+
else
|
|
255
|
+
add(cfg.model);
|
|
256
|
+
}
|
|
235
257
|
}
|
|
236
258
|
catch { }
|
|
259
|
+
// DeepSeek
|
|
260
|
+
try {
|
|
261
|
+
const cfg = JSON.parse(fsSync.readFileSync(path.join(homeDir, 'deepseek_key.json'), 'utf-8'));
|
|
262
|
+
if (cfg?.api_key) {
|
|
263
|
+
const remote = await fetchDeepSeekModels(cfg);
|
|
264
|
+
if (remote.length)
|
|
265
|
+
remote.forEach(add);
|
|
266
|
+
else
|
|
267
|
+
add(cfg.model);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
catch { }
|
|
271
|
+
// Legacy fallback fields in config.json
|
|
272
|
+
try {
|
|
273
|
+
const cfg = JSON.parse(fsSync.readFileSync(path.join(homeDir, 'config.json'), 'utf-8'));
|
|
274
|
+
if (Array.isArray(cfg.availableModels))
|
|
275
|
+
cfg.availableModels.forEach(add);
|
|
276
|
+
add(cfg.coordinatorModel);
|
|
277
|
+
}
|
|
278
|
+
catch { }
|
|
279
|
+
if (found.length)
|
|
280
|
+
break;
|
|
237
281
|
}
|
|
238
|
-
return ['coder-model'];
|
|
282
|
+
return found.length ? found : ['coder-model'];
|
|
239
283
|
}
|
|
240
284
|
default: return ['default'];
|
|
241
285
|
}
|
|
@@ -411,7 +455,7 @@ async function cmdSetup(rl) {
|
|
|
411
455
|
log.cliList(c.name, c.path);
|
|
412
456
|
console.log(chalk.bold('\n Multi-CLI Configuration'));
|
|
413
457
|
const cliConfig = await loadCliConfig();
|
|
414
|
-
const roles = ['orchestrator', 'implementor', 'reviewer'];
|
|
458
|
+
const roles = ['orchestrator', 'implementor', 'reviewer', 'explorer'];
|
|
415
459
|
for (const role of roles) {
|
|
416
460
|
console.log(chalk.yellow(`\n ${role.toUpperCase()}`));
|
|
417
461
|
const cliName = await selectOption(rl, `CLI for ${role}:`, installed.map((c) => c.name));
|
|
@@ -419,22 +463,24 @@ async function cmdSetup(rl) {
|
|
|
419
463
|
console.log(chalk.red(` Unknown CLI: ${cliName}`));
|
|
420
464
|
return;
|
|
421
465
|
}
|
|
422
|
-
const models = detectModels(cliName);
|
|
466
|
+
const models = await detectModels(cliName);
|
|
423
467
|
const model = await selectOption(rl, `Model for ${cliName}:`, models);
|
|
424
468
|
cliConfig.roles[role] = { cli: cliName, model };
|
|
425
|
-
// Ask about fallback for this role
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
469
|
+
// Ask about fallback for this role (skip explorer — single CLI is enough)
|
|
470
|
+
if (role !== 'explorer') {
|
|
471
|
+
const fbAnswer = await ask(rl, ` Configure fallback for ${role}? (y/N): `);
|
|
472
|
+
if (fbAnswer.toLowerCase() === 'y') {
|
|
473
|
+
const otherClis = installed.filter((c) => c.name !== cliName);
|
|
474
|
+
if (otherClis.length === 0) {
|
|
475
|
+
console.log(chalk.dim(' No other CLIs available for fallback.'));
|
|
476
|
+
}
|
|
477
|
+
else {
|
|
478
|
+
const fbCliName = await selectOption(rl, `Fallback CLI for ${role}:`, otherClis.map((c) => c.name));
|
|
479
|
+
const fbModels = await detectModels(fbCliName);
|
|
480
|
+
const fbModel = await selectOption(rl, `Fallback model for ${fbCliName}:`, fbModels);
|
|
481
|
+
cliConfig.roles[role].fallbackCli = fbCliName;
|
|
482
|
+
cliConfig.roles[role].fallbackModel = fbModel;
|
|
483
|
+
}
|
|
438
484
|
}
|
|
439
485
|
}
|
|
440
486
|
}
|
|
@@ -454,7 +500,7 @@ async function cmdSetup(rl) {
|
|
|
454
500
|
const globalFbAnswer = await ask(rl, ' Configurar fallback global? (y/N): ');
|
|
455
501
|
if (globalFbAnswer.toLowerCase() === 'y') {
|
|
456
502
|
const fbCliName = await selectOption(rl, 'Fallback global CLI:', installed.map((c) => c.name));
|
|
457
|
-
const fbModels = detectModels(fbCliName);
|
|
503
|
+
const fbModels = await detectModels(fbCliName);
|
|
458
504
|
const fbModel = await selectOption(rl, `Fallback global model for ${fbCliName}:`, fbModels);
|
|
459
505
|
cliConfig.fallback_global = { cli: fbCliName, model: fbModel };
|
|
460
506
|
}
|
|
@@ -483,6 +529,7 @@ async function cmdSetup(rl) {
|
|
|
483
529
|
orchestrator: buildRoleWithFallback('orchestrator'),
|
|
484
530
|
implementor: buildRoleWithFallback('implementor'),
|
|
485
531
|
reviewer: buildRoleWithFallback('reviewer'),
|
|
532
|
+
...(cliConfig.roles.explorer?.cli ? { explorer: { cli: cliConfig.roles.explorer.cli, model: cliConfig.roles.explorer.model, cmd: buildCmd(cliConfig.roles.explorer.cli, cliConfig.roles.explorer.model) } } : {}),
|
|
486
533
|
},
|
|
487
534
|
deliberation: cliConfig.deliberation.enabled ? {
|
|
488
535
|
proposer: { cli: cliConfig.roles.proposer?.cli || '', model: cliConfig.roles.proposer?.model || '', cmd: buildCmd(cliConfig.roles.proposer?.cli || '', cliConfig.roles.proposer?.model || '') },
|
|
@@ -526,34 +573,36 @@ async function cmdConfigMulti(rl) {
|
|
|
526
573
|
for (const c of installed)
|
|
527
574
|
log.cliList(c.name, c.path);
|
|
528
575
|
const cliConfig = await loadCliConfig();
|
|
529
|
-
const roles = ['orchestrator', 'implementor', 'reviewer'];
|
|
576
|
+
const roles = ['orchestrator', 'implementor', 'reviewer', 'explorer'];
|
|
530
577
|
for (const role of roles) {
|
|
531
578
|
const current = cliConfig.roles[role];
|
|
532
579
|
const fbInfo = current?.fallbackCli ? ` | fb: ${current.fallbackCli}/${current.fallbackModel}` : '';
|
|
533
580
|
console.log(chalk.yellow(`\n ${role.toUpperCase()}${current ? ` [current: ${current.cli}/${current.model}${fbInfo}]` : ''}`));
|
|
534
581
|
const cliName = await selectOption(rl, `CLI for ${role}:`, installed.map((c) => c.name));
|
|
535
|
-
const models = detectModels(cliName);
|
|
582
|
+
const models = await detectModels(cliName);
|
|
536
583
|
const model = await selectOption(rl, `Model for ${cliName}:`, models);
|
|
537
584
|
cliConfig.roles[role] = { cli: cliName, model };
|
|
538
|
-
// Ask about fallback for this role
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
585
|
+
// Ask about fallback for this role (skip explorer — single CLI is enough)
|
|
586
|
+
if (role !== 'explorer') {
|
|
587
|
+
const fbAnswer = await ask(rl, ` Configure fallback for ${role}? (y/N): `);
|
|
588
|
+
if (fbAnswer.toLowerCase() === 'y') {
|
|
589
|
+
const otherClis = installed.filter((c) => c.name !== cliName);
|
|
590
|
+
if (otherClis.length === 0) {
|
|
591
|
+
console.log(chalk.dim(' No other CLIs available for fallback.'));
|
|
592
|
+
}
|
|
593
|
+
else {
|
|
594
|
+
const fbCliName = await selectOption(rl, `Fallback CLI for ${role}:`, otherClis.map((c) => c.name));
|
|
595
|
+
const fbModels = await detectModels(fbCliName);
|
|
596
|
+
const fbModel = await selectOption(rl, `Fallback model for ${fbCliName}:`, fbModels);
|
|
597
|
+
cliConfig.roles[role].fallbackCli = fbCliName;
|
|
598
|
+
cliConfig.roles[role].fallbackModel = fbModel;
|
|
599
|
+
}
|
|
544
600
|
}
|
|
545
601
|
else {
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
const fbModel = await selectOption(rl, `Fallback model for ${fbCliName}:`, fbModels);
|
|
549
|
-
cliConfig.roles[role].fallbackCli = fbCliName;
|
|
550
|
-
cliConfig.roles[role].fallbackModel = fbModel;
|
|
602
|
+
delete cliConfig.roles[role].fallbackCli;
|
|
603
|
+
delete cliConfig.roles[role].fallbackModel;
|
|
551
604
|
}
|
|
552
605
|
}
|
|
553
|
-
else {
|
|
554
|
-
delete cliConfig.roles[role].fallbackCli;
|
|
555
|
-
delete cliConfig.roles[role].fallbackModel;
|
|
556
|
-
}
|
|
557
606
|
}
|
|
558
607
|
// Global fallback
|
|
559
608
|
const currentGlobalFb = cliConfig.fallback_global;
|
|
@@ -562,7 +611,7 @@ async function cmdConfigMulti(rl) {
|
|
|
562
611
|
const globalFbAnswer = await ask(rl, ' Configurar fallback global? (y/N): ');
|
|
563
612
|
if (globalFbAnswer.toLowerCase() === 'y') {
|
|
564
613
|
const fbCliName = await selectOption(rl, 'Fallback global CLI:', installed.map((c) => c.name));
|
|
565
|
-
const fbModels = detectModels(fbCliName);
|
|
614
|
+
const fbModels = await detectModels(fbCliName);
|
|
566
615
|
const fbModel = await selectOption(rl, `Fallback global model for ${fbCliName}:`, fbModels);
|
|
567
616
|
cliConfig.fallback_global = { cli: fbCliName, model: fbModel };
|
|
568
617
|
}
|
|
@@ -591,6 +640,7 @@ async function cmdConfigMulti(rl) {
|
|
|
591
640
|
orchestrator: buildRoleWithFallback('orchestrator'),
|
|
592
641
|
implementor: buildRoleWithFallback('implementor'),
|
|
593
642
|
reviewer: buildRoleWithFallback('reviewer'),
|
|
643
|
+
...(cliConfig.roles.explorer?.cli ? { explorer: { cli: cliConfig.roles.explorer.cli, model: cliConfig.roles.explorer.model, cmd: buildCmd(cliConfig.roles.explorer.cli, cliConfig.roles.explorer.model) } } : {}),
|
|
594
644
|
},
|
|
595
645
|
deliberation: cliConfig.deliberation?.enabled ? {
|
|
596
646
|
proposer: { cli: cliConfig.roles.proposer?.cli || '', model: cliConfig.roles.proposer?.model || '', cmd: buildCmd(cliConfig.roles.proposer?.cli || '', cliConfig.roles.proposer?.model || '') },
|
|
@@ -616,7 +666,7 @@ async function cmdConfigOneRole(rl, role) {
|
|
|
616
666
|
const current = cliConfig.roles[role];
|
|
617
667
|
console.log(chalk.yellow(`\n ${role.toUpperCase()}${current ? ` [current: ${current.cli}/${current.model}]` : ''}`));
|
|
618
668
|
const cliName = await selectOption(rl, `CLI for ${role}:`, installed.map((c) => c.name));
|
|
619
|
-
const models = detectModels(cliName);
|
|
669
|
+
const models = await detectModels(cliName);
|
|
620
670
|
const model = await selectOption(rl, `Model for ${cliName}:`, models);
|
|
621
671
|
cliConfig.roles[role] = { cli: cliName, model };
|
|
622
672
|
await saveCliConfig(cliConfig);
|
|
@@ -761,15 +811,15 @@ async function cmdModels(roleArg, fi, rl) {
|
|
|
761
811
|
console.log(chalk.dim(' Fetching Qwen models...'));
|
|
762
812
|
models = await fetchQwenModels();
|
|
763
813
|
if (!models.length)
|
|
764
|
-
models = detectModels('qwen');
|
|
814
|
+
models = await detectModels('qwen');
|
|
765
815
|
}
|
|
766
816
|
else if (apiKeyCfg?.api_key) {
|
|
767
817
|
models = await fetchApiKeyModels(apiKeyCfg);
|
|
768
818
|
if (!models.length)
|
|
769
|
-
models = detectModels(activeProvider);
|
|
819
|
+
models = await detectModels(activeProvider);
|
|
770
820
|
}
|
|
771
821
|
else {
|
|
772
|
-
models = activeProvider ? detectModels(activeProvider) : [];
|
|
822
|
+
models = activeProvider ? await detectModels(activeProvider) : [];
|
|
773
823
|
}
|
|
774
824
|
if (!models.length) {
|
|
775
825
|
resume();
|
|
@@ -1148,6 +1198,7 @@ export async function runRepl(resumeSession) {
|
|
|
1148
1198
|
orchestrator: `${config.roles.orchestrator.cli}/${config.roles.orchestrator.model}`,
|
|
1149
1199
|
implementor: `${config.roles.implementor.cli}/${config.roles.implementor.model}`,
|
|
1150
1200
|
reviewer: `${config.roles.reviewer.cli}/${config.roles.reviewer.model}`,
|
|
1201
|
+
...(config.roles.explorer?.cli ? { explorer: `${config.roles.explorer.cli}/${config.roles.explorer.model}` } : {}),
|
|
1151
1202
|
};
|
|
1152
1203
|
}
|
|
1153
1204
|
}
|
|
@@ -1205,6 +1256,7 @@ export async function runRepl(resumeSession) {
|
|
|
1205
1256
|
orchestrator: `${config.roles.orchestrator.cli}/${config.roles.orchestrator.model}`,
|
|
1206
1257
|
implementor: `${config.roles.implementor.cli}/${config.roles.implementor.model}`,
|
|
1207
1258
|
reviewer: `${config.roles.reviewer.cli}/${config.roles.reviewer.model}`,
|
|
1259
|
+
...(config.roles.explorer?.cli ? { explorer: `${config.roles.explorer.cli}/${config.roles.explorer.model}` } : {}),
|
|
1208
1260
|
};
|
|
1209
1261
|
}
|
|
1210
1262
|
}
|
package/dist/commands/setup.js
CHANGED
|
@@ -25,7 +25,7 @@ function detectInstalledClis() {
|
|
|
25
25
|
}
|
|
26
26
|
return installed;
|
|
27
27
|
}
|
|
28
|
-
function detectModels(cliName) {
|
|
28
|
+
async function detectModels(cliName) {
|
|
29
29
|
try {
|
|
30
30
|
switch (cliName) {
|
|
31
31
|
case 'claude': {
|
|
@@ -63,17 +63,58 @@ function detectModels(cliName) {
|
|
|
63
63
|
case 'agent-impl':
|
|
64
64
|
case 'agent-rev':
|
|
65
65
|
case 'agent-explorer': {
|
|
66
|
+
const { fetchApiKeyModels } = await import('../utils/qwen-auth.js');
|
|
67
|
+
const { fetchGeminiModels } = await import('../utils/gemini.js');
|
|
68
|
+
const { fetchDeepSeekModels } = await import('../utils/deepseek.js');
|
|
69
|
+
const found = [];
|
|
70
|
+
const add = (m) => { if (m && !found.includes(m))
|
|
71
|
+
found.push(m); };
|
|
66
72
|
for (const dir of [`.${cliName}`, '.agent-mp']) {
|
|
73
|
+
const homeDir = path.join(os.homedir(), dir);
|
|
67
74
|
try {
|
|
68
|
-
const cfg = JSON.parse(fsSync.readFileSync(path.join(
|
|
69
|
-
if (cfg
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
75
|
+
const cfg = JSON.parse(fsSync.readFileSync(path.join(homeDir, 'api_key.json'), 'utf-8'));
|
|
76
|
+
if (cfg?.api_key) {
|
|
77
|
+
const remote = await fetchApiKeyModels(cfg);
|
|
78
|
+
if (remote.length)
|
|
79
|
+
remote.forEach(add);
|
|
80
|
+
else
|
|
81
|
+
add(cfg.model);
|
|
82
|
+
}
|
|
73
83
|
}
|
|
74
84
|
catch { }
|
|
85
|
+
try {
|
|
86
|
+
const cfg = JSON.parse(fsSync.readFileSync(path.join(homeDir, 'gemini_key.json'), 'utf-8'));
|
|
87
|
+
if (cfg?.api_key) {
|
|
88
|
+
const remote = await fetchGeminiModels(cfg);
|
|
89
|
+
if (remote.length)
|
|
90
|
+
remote.forEach(add);
|
|
91
|
+
else
|
|
92
|
+
add(cfg.model);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
catch { }
|
|
96
|
+
try {
|
|
97
|
+
const cfg = JSON.parse(fsSync.readFileSync(path.join(homeDir, 'deepseek_key.json'), 'utf-8'));
|
|
98
|
+
if (cfg?.api_key) {
|
|
99
|
+
const remote = await fetchDeepSeekModels(cfg);
|
|
100
|
+
if (remote.length)
|
|
101
|
+
remote.forEach(add);
|
|
102
|
+
else
|
|
103
|
+
add(cfg.model);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
catch { }
|
|
107
|
+
try {
|
|
108
|
+
const cfg = JSON.parse(fsSync.readFileSync(path.join(homeDir, 'config.json'), 'utf-8'));
|
|
109
|
+
if (Array.isArray(cfg.availableModels))
|
|
110
|
+
cfg.availableModels.forEach(add);
|
|
111
|
+
add(cfg.coordinatorModel);
|
|
112
|
+
}
|
|
113
|
+
catch { }
|
|
114
|
+
if (found.length)
|
|
115
|
+
break;
|
|
75
116
|
}
|
|
76
|
-
return ['coder-model'];
|
|
117
|
+
return found.length ? found : ['coder-model'];
|
|
77
118
|
}
|
|
78
119
|
default:
|
|
79
120
|
return ['default'];
|
|
@@ -126,7 +167,7 @@ async function configureOneRole(rl, role, installed, cliConfig) {
|
|
|
126
167
|
console.log(chalk.red(` Unknown CLI: ${cliName}`));
|
|
127
168
|
return false;
|
|
128
169
|
}
|
|
129
|
-
const models = detectModels(cliName);
|
|
170
|
+
const models = await detectModels(cliName);
|
|
130
171
|
const modelOptions = numberedSelect(`Models for ${cliName}:`, models);
|
|
131
172
|
const modelChoice = await ask(rl, ` Model: `);
|
|
132
173
|
cliConfig.roles[role] = {
|
|
@@ -244,7 +285,7 @@ export function setupCommand(program) {
|
|
|
244
285
|
rl.close();
|
|
245
286
|
return;
|
|
246
287
|
}
|
|
247
|
-
const models = detectModels(cliName);
|
|
288
|
+
const models = await detectModels(cliName);
|
|
248
289
|
const modelOptions = numberedSelect(`Models for ${cliName}:`, models);
|
|
249
290
|
const modelChoice = await ask(rl, ` Model: `);
|
|
250
291
|
const model = resolveChoice(modelChoice, modelOptions);
|
|
@@ -338,7 +379,7 @@ export function setupCommand(program) {
|
|
|
338
379
|
continue;
|
|
339
380
|
}
|
|
340
381
|
const cliName = resolveChoice(cliChoice, cliOptions);
|
|
341
|
-
const models = detectModels(cliName);
|
|
382
|
+
const models = await detectModels(cliName);
|
|
342
383
|
const modelOptions = numberedSelect(`Models for ${cliName}:`, models);
|
|
343
384
|
const modelChoice = await ask(rl, ` Model: `);
|
|
344
385
|
cliConfig.roles[role] = { cli: cliName, model: resolveChoice(modelChoice, modelOptions) };
|
package/dist/core/engine.js
CHANGED
|
@@ -1667,358 +1667,212 @@ INSTRUCCIONES:
|
|
|
1667
1667
|
}
|
|
1668
1668
|
catch { /* ignore */ }
|
|
1669
1669
|
const effectiveTask = task || 'Explorar y documentar todas las aplicaciones y servicios del proyecto';
|
|
1670
|
-
const prompt = `TAREA
|
|
1670
|
+
const prompt = `TAREA: ${effectiveTask}
|
|
1671
1671
|
DIRECTORIO_TRABAJO: ${this.projectDir}
|
|
1672
1672
|
PROYECTO: ${this.config.project}
|
|
1673
|
-
STACK: ${this.config.stack}
|
|
1674
1673
|
|
|
1675
|
-
ESTRUCTURA
|
|
1674
|
+
ESTRUCTURA DEL PROYECTO:
|
|
1676
1675
|
${fsSnapshot}
|
|
1677
1676
|
|
|
1678
|
-
${prefetched ?
|
|
1677
|
+
${prefetched ? `==== ARCHIVOS REALES LEIDOS (tu unica fuente de verdad) ====\n${prefetched}\n` : ''}
|
|
1678
|
+
${existingMainArch ? `==== DOC EXISTENTE: architecture.md (raiz) — preservar y solo actualizar lo que cambio ====\n${existingMainArch.slice(0, 6000)}\n` : ''}
|
|
1679
|
+
${existingComponentDocs ? `==== DOC EXISTENTE por componente ====\n${existingComponentDocs.slice(0, 4000)}\n` : ''}
|
|
1679
1680
|
|
|
1680
|
-
|
|
1681
|
-
|
|
1681
|
+
==================================================================
|
|
1682
|
+
TU TRABAJO — leelo entero antes de escribir
|
|
1683
|
+
==================================================================
|
|
1682
1684
|
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1685
|
+
1. IDENTIFICAR COMPONENTES
|
|
1686
|
+
Un "componente" = cada CARPETA HIJA del DIRECTORIO_TRABAJO que tenga un manifest propio:
|
|
1687
|
+
package.json, pom.xml, build.gradle(.kts), requirements.txt / pyproject.toml,
|
|
1688
|
+
go.mod, Cargo.toml, composer.json, Gemfile, *.csproj, *.sln, mix.exs, Dockerfile.
|
|
1689
|
+
Backend, frontend, worker, batch, mobile — todos cuentan. Si tiene manifest, es componente.
|
|
1688
1690
|
|
|
1689
|
-
|
|
1691
|
+
2. PARA CADA COMPONENTE, GENERAR EXACTAMENTE UN ARCHIVO:
|
|
1692
|
+
=== .agent/context/<carpeta-del-componente>/architecture.md ===
|
|
1693
|
+
|
|
1694
|
+
El nombre de carpeta DEBE coincidir con el nombre real del directorio en el proyecto.
|
|
1695
|
+
Si hay 3 carpetas/componentes en la raiz, hay que generar 3 archivos NIVEL 1.
|
|
1696
|
+
No omitas ninguno. Frontends incluidos.
|
|
1697
|
+
|
|
1698
|
+
3. ADEMAS, GENERAR EL DOC RAIZ:
|
|
1699
|
+
=== .agent/context/architecture.md === (NIVEL 0 — vista global)
|
|
1700
|
+
|
|
1701
|
+
4. OPCIONAL — modulos por feature dentro de un componente:
|
|
1702
|
+
=== .agent/context/<componente>/modules/<feature>.md === (NIVEL 2)
|
|
1703
|
+
Solo si el componente tiene features de negocio claras (clients, sales, auth, products...).
|
|
1704
|
+
No crees modulos por capa tecnica (security, db, web). Si no hay features claras, omiti NIVEL 2.
|
|
1705
|
+
|
|
1706
|
+
==================================================================
|
|
1690
1707
|
REGLA DE ORO — PROHIBIDO INVENTAR
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
NO devuelvas
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
- BIEN: modulos llamados "clients", "sales", "products", "auth", "orders" — eso es hablar de features reales
|
|
1716
|
-
- Para identificar los modulos, MIRA los CONTROLLER/ROUTER pre-leidos: el nombre del modulo = lo que maneja ese controller
|
|
1717
|
-
* ClientController o clients.controller → modulo "clients"
|
|
1718
|
-
* SaleController o sale.routes → modulo "sales"
|
|
1719
|
-
* AuthController o auth.handler → modulo "auth"
|
|
1720
|
-
- "Archivos clave" en cada modulo DEBE listar los archivos FUENTE REALES que leiste, NO solo el manifest.
|
|
1721
|
-
Ejemplo correcto:
|
|
1722
|
-
| Archivo (ruta relativa al componente) | Rol |
|
|
1723
|
-
| controller/ClientController.java | Endpoints REST /clients |
|
|
1724
|
-
| domain/Client.java | Entidad mapeada a tabla CLIENTS |
|
|
1725
|
-
| repository/ClientRepository.java | Acceso a base de datos |
|
|
1726
|
-
| src/clients/clients.controller.ts | Endpoints /clients |
|
|
1727
|
-
| src/clients/client.schema.ts | Modelo de datos Client |
|
|
1728
|
-
|
|
1729
|
-
NO inventes datos. Si un componente no tiene una de esas piezas en los archivos leidos, simplemente omiti esa seccion en su documentacion.
|
|
1730
|
-
|
|
1731
|
-
================================================================
|
|
1732
|
-
LENGUAJE DUAL (regla critica)
|
|
1733
|
-
================================================================
|
|
1734
|
-
Cada seccion abre con UNA linea en lenguaje simple (que entienda un PM/negocio), DESPUES viene el detalle tecnico.
|
|
1735
|
-
- MAL: "El microservicio orquesta la persistencia mediante un repositorio."
|
|
1736
|
-
- BIEN: "Guarda la informacion del usuario en la base. Internamente usa un repositorio que abstrae la conexion a MongoDB."
|
|
1737
|
-
|
|
1738
|
-
================================================================
|
|
1739
|
-
ESTRUCTURA DE LOS 3 NIVELES
|
|
1740
|
-
================================================================
|
|
1741
|
-
|
|
1742
|
-
────────────────────────────────────────────────────────────────
|
|
1743
|
-
────────────────────────────────────────────────────────────────
|
|
1744
|
-
NIVEL 0 — architecture.md (raiz de .agent/context/)
|
|
1745
|
-
Objetivo: 80-150 lineas. Panorama global real, no generico.
|
|
1746
|
-
────────────────────────────────────────────────────────────────
|
|
1747
|
-
|
|
1748
|
-
# [Nombre del proyecto] — Arquitectura Global (NIVEL 0)
|
|
1708
|
+
==================================================================
|
|
1709
|
+
- Si un dato (puerto, version, endpoint, env var, ruta, clase) no aparece en los ARCHIVOS REALES → OMITILO.
|
|
1710
|
+
- NO uses "inferido", "probablemente", "asumido", "(quizas)", "parece ser".
|
|
1711
|
+
- Mejor doc corta y veraz que larga llena de suposiciones.
|
|
1712
|
+
- NO devuelvas "tool_call", "function_call" ni invocaciones — devolves MARKDOWN, nada mas.
|
|
1713
|
+
|
|
1714
|
+
==================================================================
|
|
1715
|
+
PLANTILLAS — usa lo que aplique al stack real, omite lo que no
|
|
1716
|
+
==================================================================
|
|
1717
|
+
|
|
1718
|
+
────── NIVEL 0 (.agent/context/architecture.md, 80-180 lineas) ──────
|
|
1719
|
+
|
|
1720
|
+
REGLA CRITICA PARA NIVEL 0 — UPDATE INCREMENTAL, NO REESCRIBIR:
|
|
1721
|
+
Si arriba aparece "DOC EXISTENTE: architecture.md (raiz)", USALA COMO BASE.
|
|
1722
|
+
- Mantene su estructura, sus secciones y su redaccion tal cual.
|
|
1723
|
+
- Cambia UNICAMENTE las celdas/lineas donde el dato real (puerto, version, endpoint, dependencia) cambio.
|
|
1724
|
+
- Si un componente seguia listado en la doc previa pero su carpeta YA NO EXISTE en el filesystem actual:
|
|
1725
|
+
NO LO BORRES. Conservalo en su fila y agrega el sufijo " — (archivado, fuera del workspace actual)".
|
|
1726
|
+
Si tiene seccion propia (flujos, relaciones), preservala igual y marca el componente como archivado.
|
|
1727
|
+
- Si hay un componente NUEVO (carpeta presente ahora que antes no estaba), agregalo como fila/seccion nueva.
|
|
1728
|
+
- No reescribas overview/diagrama/flujos a menos que el cambio real lo requiera.
|
|
1729
|
+
- Si NO hay doc previa, generala con la plantilla de abajo.
|
|
1730
|
+
|
|
1731
|
+
# ${this.config.project} — Arquitectura Global
|
|
1749
1732
|
|
|
1750
1733
|
> Lectura escalonada:
|
|
1751
|
-
> NIVEL 0: este archivo
|
|
1752
|
-
> NIVEL 1: .agent/context
|
|
1753
|
-
> NIVEL 2: .agent/context
|
|
1754
|
-
|
|
1755
|
-
## 1.
|
|
1756
|
-
2-4 lineas.
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
| Origen | Destino | Tipo | Proposito |
|
|
1734
|
+
> NIVEL 0: este archivo (vista global)
|
|
1735
|
+
> NIVEL 1: .agent/context/<componente>/architecture.md
|
|
1736
|
+
> NIVEL 2: .agent/context/<componente>/modules/<feature>.md
|
|
1737
|
+
|
|
1738
|
+
## 1. Que es el sistema
|
|
1739
|
+
2-4 lineas. Para quien sirve, que problema resuelve. Si hay multiples componentes, contrastalos.
|
|
1740
|
+
|
|
1741
|
+
## 2. Componentes
|
|
1742
|
+
| Componente | Estado | Tipo (api / web / worker / mobile) | Stack + version | Puerto | Rol |
|
|
1743
|
+
|---|---|---|---|---|---|
|
|
1744
|
+
(Estado: "activo" si la carpeta existe ahora; "archivado" si estaba en la doc previa pero ya no esta en el filesystem.)
|
|
1745
|
+
(Datos REALES del manifest. Componentes archivados conservan sus datos previos.)
|
|
1746
|
+
|
|
1747
|
+
## 3. Como se conectan
|
|
1748
|
+
| Origen | Destino | Tipo (HTTP, DB, mensaje) | Detalle |
|
|
1767
1749
|
|---|---|---|---|
|
|
1768
|
-
(
|
|
1750
|
+
(URLs/hosts reales de .env / config. Si una relacion involucra un componente archivado, mantenerla y marcarla con "(archivado)".)
|
|
1769
1751
|
|
|
1770
|
-
## 4. Diagrama
|
|
1771
|
-
|
|
1772
|
-
Incluir endpoints clave inline en los componentes cuando se conocen.
|
|
1752
|
+
## 4. Diagrama
|
|
1753
|
+
Box-drawing y flechas. Mostrar puertos REALES y endpoints clave si se conocen.
|
|
1773
1754
|
\`\`\`text
|
|
1774
|
-
|
|
1775
|
-
│
|
|
1776
|
-
|
|
1777
|
-
│
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
│ SQL Server │ │ Auth Service│
|
|
1783
|
-
│ :31434 │ │ :8000 │
|
|
1784
|
-
└──────────────┘ └──────────────┘
|
|
1755
|
+
┌──────────────┐ HTTP ┌──────────────┐
|
|
1756
|
+
│ frontend :3000│──────────>│ api :8080 │
|
|
1757
|
+
└──────────────┘ └──────┬───────┘
|
|
1758
|
+
│ JDBC
|
|
1759
|
+
▼
|
|
1760
|
+
┌──────────┐
|
|
1761
|
+
│ DB :5432 │
|
|
1762
|
+
└──────────┘
|
|
1785
1763
|
\`\`\`
|
|
1786
1764
|
|
|
1787
|
-
## 5. Flujos end-to-end
|
|
1788
|
-
|
|
1789
|
-
- **"Nombre del flujo":** Actor → POST /endpoint (componente-a) → valida JWT con auth-service → escribe en SQL Server → responde 201.
|
|
1765
|
+
## 5. Flujos end-to-end (2-5)
|
|
1766
|
+
- **<nombre>:** Actor → endpoint/componente → valida X → escribe Y → responde Z.
|
|
1790
1767
|
|
|
1791
|
-
## 6. Prerequisitos
|
|
1792
|
-
|
|
1768
|
+
## 6. Prerequisitos
|
|
1769
|
+
Lo concreto: acceso a hosts externos, herramientas requeridas, secrets esperados. Sin frases genericas.
|
|
1793
1770
|
|
|
1794
|
-
## 7. Comandos
|
|
1771
|
+
## 7. Comandos
|
|
1795
1772
|
| Comando | Descripcion | Directorio |
|
|
1796
1773
|
|---|---|---|
|
|
1797
|
-
(
|
|
1774
|
+
(scripts reales: package.json scripts, Makefile targets, run.sh, mvnw, gradlew, etc.)
|
|
1798
1775
|
|
|
1799
|
-
────────────────────────────────────────────────────────────────
|
|
1800
|
-
NIVEL 1 — [componente]/architecture.md
|
|
1801
|
-
Objetivo: 120-250 lineas. Un archivo por cada componente no trivial.
|
|
1802
|
-
────────────────────────────────────────────────────────────────
|
|
1803
1776
|
|
|
1804
|
-
|
|
1777
|
+
────── NIVEL 1 (.agent/context/<componente>/architecture.md, 100-220 lineas) ──────
|
|
1778
|
+
|
|
1779
|
+
# <componente> — Arquitectura
|
|
1805
1780
|
|
|
1806
1781
|
## Que hace
|
|
1807
|
-
Parrafo 1:
|
|
1808
|
-
Parrafo 2 (si
|
|
1782
|
+
Parrafo 1: rol funcional + quien lo consume (en lenguaje de negocio).
|
|
1783
|
+
Parrafo 2 (si aplica): que lo diferencia de los otros componentes hermanos.
|
|
1809
1784
|
|
|
1810
1785
|
## Casos de uso principales
|
|
1811
|
-
|
|
1812
|
-
| Caso de uso | Actor | Descripcion |
|
|
1786
|
+
| Caso de uso | Quien lo dispara | Detalle |
|
|
1813
1787
|
|---|---|---|
|
|
1814
|
-
| Ingesta de ventas | Proceso batch BAT | POST /api/sales — upsert bulk de ventas finales |
|
|
1815
|
-
| Consulta de productos | Portal Nexus | GET /api/products?eanCode=XXX |
|
|
1816
1788
|
|
|
1817
|
-
## Stack
|
|
1789
|
+
## Stack
|
|
1818
1790
|
| Item | Valor |
|
|
1819
1791
|
|---|---|
|
|
1820
|
-
| Lenguaje |
|
|
1821
|
-
| Framework |
|
|
1822
|
-
|
|
|
1823
|
-
| Seguridad | Spring Security 6 + JJWT |
|
|
1824
|
-
(versiones REALES del manifest. Si hay librerias clave como POI, MapStruct, HikariCP: incluirlas)
|
|
1792
|
+
| Lenguaje | (real, version del manifest) |
|
|
1793
|
+
| Framework | (real) |
|
|
1794
|
+
| Librerias clave | (las relevantes con version) |
|
|
1825
1795
|
|
|
1826
|
-
##
|
|
1796
|
+
## URLs y puertos (si aplica)
|
|
1827
1797
|
| Recurso | URL |
|
|
1828
1798
|
|---|---|
|
|
1829
|
-
|
|
|
1830
|
-
| Swagger /
|
|
1831
|
-
| Perfil activo | development (application-development.properties) |
|
|
1799
|
+
| Base | http://localhost:<puerto-real> |
|
|
1800
|
+
| Docs / Swagger / Storybook | (si existe) |
|
|
1832
1801
|
|
|
1833
|
-
## Estructura
|
|
1834
|
-
Arbol con
|
|
1802
|
+
## Estructura
|
|
1803
|
+
Arbol con DIRECTORIOS y archivos REALES leidos, anotados con → que rol cumple cada uno.
|
|
1835
1804
|
\`\`\`text
|
|
1836
|
-
|
|
1837
|
-
├──
|
|
1838
|
-
│ ├── ClientController → CRUD /api/clients
|
|
1839
|
-
│ ├── SaleController → POST /api/sales, /api/sales/interim-sales
|
|
1840
|
-
│ └── ExportController → GET /api/export/combos (genera .xlsx)
|
|
1841
|
-
├── service/ → interfaces de logica de negocio
|
|
1842
|
-
│ └── impl/ → implementaciones (@Transactional aqui)
|
|
1843
|
-
├── repository/ → Spring Data JPA Repositories
|
|
1844
|
-
├── domain/ → Entidades JPA (@Entity)
|
|
1845
|
-
│ ├── Client, InterimClient → clientes finales y en staging
|
|
1846
|
-
│ ├── Sale, InterimSale → ventas finales y en staging
|
|
1847
|
-
│ └── compositekeys/ → @IdClass para PKs compuestas
|
|
1848
|
-
├── dto/ → contratos de API (Request/Response DTOs)
|
|
1849
|
-
├── mapper/ → MapStruct: Entity ↔ DTO
|
|
1850
|
-
├── security/ → filtros JWT, validacion, handler 401
|
|
1851
|
-
└── configuration/ → CORS, Swagger, SecurityConfig
|
|
1852
|
-
\`\`\`
|
|
1853
|
-
(Adaptar a la estructura real del proyecto: puede ser src/, app/, pkg/, etc.)
|
|
1854
|
-
|
|
1855
|
-
## Endpoints reales
|
|
1856
|
-
SOLO los que se leyeron en los CONTROLLER/ROUTER files. Incluir columna Auth si se conoce.
|
|
1857
|
-
| Metodo | Ruta | Auth | Funcion |
|
|
1858
|
-
|---|---|---|---|
|
|
1859
|
-
| GET | /api/clients | JWT | Lista clientes (paginado, filtrable) |
|
|
1860
|
-
| POST | /api/sales | JWT | Upsert bulk de ventas finales |
|
|
1861
|
-
| GET | /api/export/combos | JWT/Azure | Descarga Excel con combos |
|
|
1862
|
-
(querystring params relevantes en la ruta, ej. ?eanCode= , ?page=&size= )
|
|
1863
|
-
|
|
1864
|
-
## Formato de respuesta (si hay wrapper estandar)
|
|
1865
|
-
Si el codigo muestra un wrapper comun para todas las respuestas, documentarlo:
|
|
1866
|
-
\`\`\`json
|
|
1867
|
-
{
|
|
1868
|
-
"status": 200,
|
|
1869
|
-
"message": "Operacion exitosa",
|
|
1870
|
-
"data": [...],
|
|
1871
|
-
"pagination": { "page": 1, "size": 15, "totalElements": 120, "totalPages": 8 }
|
|
1872
|
-
}
|
|
1805
|
+
src/
|
|
1806
|
+
├── ... → ...
|
|
1873
1807
|
\`\`\`
|
|
1874
|
-
Si no hay wrapper, omitir esta seccion.
|
|
1875
1808
|
|
|
1876
|
-
##
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
| api-web | Controladores, DTOs, validacion, exportacion | modules/web-api.md |
|
|
1882
|
-
(Agrupar por responsabilidad tecnica real, no inventar modulos)
|
|
1809
|
+
## Endpoints / Rutas / Pantallas
|
|
1810
|
+
- Backend (api): tabla con metodo, ruta, auth, proposito.
|
|
1811
|
+
- Frontend (web): tabla con ruta de pagina, proposito, datos que consume.
|
|
1812
|
+
- Worker / batch: tabla con job, trigger, proposito.
|
|
1813
|
+
Solo lo leido en archivos reales.
|
|
1883
1814
|
|
|
1884
|
-
##
|
|
1885
|
-
|
|
|
1815
|
+
## Configuracion clave
|
|
1816
|
+
| Variable / Propiedad | Valor real | Proposito |
|
|
1886
1817
|
|---|---|---|
|
|
1887
|
-
|
|
1888
|
-
| spring.datasource.url | jdbc:sqlserver://... | Conexion SQL Server |
|
|
1889
|
-
| auth.url | http://57.151.96.13:8000/v1/validate | Servicio externo de validacion JWT |
|
|
1890
|
-
(Valores REALES del archivo de config/env leido. Si no se leyo el archivo, omitir la tabla)
|
|
1818
|
+
(de .env / application*.properties / config files leidos)
|
|
1891
1819
|
|
|
1892
1820
|
## Como levantar
|
|
1893
|
-
Comando principal primero. Luego paso a paso si existe.
|
|
1894
1821
|
\`\`\`bash
|
|
1895
|
-
|
|
1896
|
-
\`\`\`
|
|
1897
|
-
O paso a paso:
|
|
1898
|
-
\`\`\`bash
|
|
1899
|
-
source ./scripts/env.sh
|
|
1900
|
-
npm install && npm run dev
|
|
1822
|
+
# comando real del manifest / scripts
|
|
1901
1823
|
\`\`\`
|
|
1902
1824
|
|
|
1903
|
-
##
|
|
1904
|
-
Frameworks
|
|
1905
|
-
\`\`\`bash
|
|
1906
|
-
npm test # todos los tests
|
|
1907
|
-
npm test -- --watch # modo watch
|
|
1908
|
-
\`\`\`
|
|
1825
|
+
## Tests (si los hay)
|
|
1826
|
+
Frameworks + comando para correr.
|
|
1909
1827
|
|
|
1910
|
-
────────────────────────────────────────────────────────────────
|
|
1911
|
-
NIVEL 2 — [componente]/modules/[modulo].md
|
|
1912
|
-
Objetivo: 50-120 lineas. Un archivo por modulo significativo.
|
|
1913
|
-
────────────────────────────────────────────────────────────────
|
|
1914
1828
|
|
|
1915
|
-
|
|
1829
|
+
────── NIVEL 2 (.agent/context/<componente>/modules/<feature>.md, 40-100 lineas) ──────
|
|
1830
|
+
Solo si el componente tiene features de negocio claras (no crees modulos por capa tecnica).
|
|
1916
1831
|
|
|
1917
|
-
|
|
1918
|
-
1-2 lineas: "Protege todos los endpoints /api/**. Cada request debe llevar un token JWT valido."
|
|
1832
|
+
# <feature> — <componente>
|
|
1919
1833
|
|
|
1920
|
-
##
|
|
1921
|
-
1-2 lineas: como esta implementado. ej. "Filtro OncePerRequestFilter que extrae el JWT del header Authorization, lo valida contra el servicio externo auth.url, y si es valido establece el SecurityContext."
|
|
1834
|
+
## Que hace (negocio, 1-2 lineas)
|
|
1922
1835
|
|
|
1923
|
-
##
|
|
1924
|
-
Para modulos de seguridad, acceso a datos, o cualquiera con logica de decision/secuencia:
|
|
1925
|
-
mostrar el flujo con ASCII art y nombres REALES de clases/metodos.
|
|
1926
|
-
\`\`\`text
|
|
1927
|
-
HTTP Request
|
|
1928
|
-
│
|
|
1929
|
-
▼
|
|
1930
|
-
AuthFilter (OncePerRequestFilter)
|
|
1931
|
-
│
|
|
1932
|
-
├── X-User-Source == "Azure"?
|
|
1933
|
-
│ ▼ SI
|
|
1934
|
-
│ AzureHeaderValidator → construye usuario virtual desde headers
|
|
1935
|
-
│
|
|
1936
|
-
└── NO
|
|
1937
|
-
▼
|
|
1938
|
-
JwtValidator → POST http://auth-service/validate → carga usuario de BD
|
|
1939
|
-
│
|
|
1940
|
-
▼
|
|
1941
|
-
SecurityContextHolder.setAuthentication(...)
|
|
1942
|
-
│
|
|
1943
|
-
▼
|
|
1944
|
-
@PreAuthorize("hasAnyAuthority('ROLE_A','ROLE_B')") en el controller
|
|
1945
|
-
\`\`\`
|
|
1836
|
+
## Como esta implementado (tecnico, 1-2 lineas)
|
|
1946
1837
|
|
|
1947
|
-
##
|
|
1948
|
-
|
|
1838
|
+
## Flujo principal
|
|
1839
|
+
Diagrama ASCII si hay logica de decision, con nombres REALES de clases/funciones.
|
|
1840
|
+
|
|
1841
|
+
## Entidades / modelos (si aplica)
|
|
1949
1842
|
| Entidad | Proposito | Notas |
|
|
1950
1843
|
|---|---|---|
|
|
1951
|
-
| Client | Clientes finales | Clave compuesta: ClientId |
|
|
1952
|
-
| InterimClient | Clientes en staging | Tabla intermedia antes de procesar |
|
|
1953
|
-
|
|
1954
|
-
## Reglas del modulo
|
|
1955
|
-
- Rutas protegidas: /api/** → autenticacion obligatoria
|
|
1956
|
-
- Rutas publicas: OPTIONS /**, /swagger-ui/**, /*
|
|
1957
|
-
- Sin sesion: STATELESS — sin cookies
|
|
1958
|
-
- ddl-auto=validate → el schema nunca se auto-modifica
|
|
1959
1844
|
|
|
1960
1845
|
## Archivos clave
|
|
1961
|
-
|
|
1962
|
-
| Archivo | Rol |
|
|
1846
|
+
| Archivo (ruta relativa al componente) | Rol |
|
|
1963
1847
|
|---|---|
|
|
1964
|
-
| security/AuthFilter.java | Filtro principal — intercepta y valida cada request |
|
|
1965
|
-
| security/JwtValidator.java | Extrae username del JWT, verifica firma y expiracion |
|
|
1966
|
-
| configuration/SecurityConfig.java | Define SecurityFilterChain, rutas publicas/protegidas |
|
|
1967
|
-
| application-development.properties | auth.url, security.token.secret, security.token.expiration |
|
|
1968
|
-
|
|
1969
|
-
## Dependencias
|
|
1970
|
-
- Librerias clave con version si se conoce: io.jsonwebtoken:jjwt:0.9.1, spring-boot-starter-security
|
|
1971
|
-
- Cross-component si corresponde: "llama a http://auth-service:8000/v1/validate para validar tokens"
|
|
1972
|
-
|
|
1973
|
-
================================================================
|
|
1974
|
-
CALIBRACION DE DETALLE
|
|
1975
|
-
================================================================
|
|
1976
|
-
- NIVEL 0: 80-150 lineas
|
|
1977
|
-
- NIVEL 1: 120-250 lineas por componente
|
|
1978
|
-
- NIVEL 2: 50-120 lineas por modulo
|
|
1979
|
-
- Si te queda corto → incluir mas endpoints reales, mas clases en el arbol, mas config values
|
|
1980
|
-
- Si te queda largo → estas repitiendo entre niveles o agregando relleno; recorta
|
|
1981
|
-
|
|
1982
|
-
================================================================
|
|
1983
|
-
QUE NO HACER
|
|
1984
|
-
================================================================
|
|
1985
|
-
- NO usar "Inferido", "Probablemente", "(asumido)", "(quizas)", "parece"
|
|
1986
|
-
- NO repetir lo mismo entre niveles sin agregar valor (cada nivel zoomea mas)
|
|
1987
|
-
- NO dejar tablas vacias ni con placeholders tipo "..." o "ver manifest"
|
|
1988
|
-
- NO escribir overview que podria aplicar a cualquier proyecto (tiene que ser especifico de ESTE proyecto)
|
|
1989
|
-
- NO documentar componentes triviales (scripts sueltos, configs simples) con carpeta propia — mencionalos en NIVEL 0 y listo
|
|
1990
|
-
- NO inventar endpoints, env vars, puertos, hosts, clases o schemas que no leiste en los archivos reales
|
|
1991
|
-
|
|
1992
|
-
================================================================
|
|
1993
|
-
FORMATO DE SALIDA — OBLIGATORIO
|
|
1994
|
-
================================================================
|
|
1995
|
-
Devolve UNICAMENTE bloques de archivos separados por marcadores ===. Nada de explicaciones extra fuera de los bloques.
|
|
1996
1848
|
|
|
1997
|
-
IMPORTANTE: TODAS las rutas son RELATIVAS al directorio del proyecto.
|
|
1998
1849
|
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
=== .agent/context/nexus-core-api/modules/clients.md ===
|
|
1850
|
+
==================================================================
|
|
1851
|
+
FORMATO DE SALIDA — OBLIGATORIO
|
|
1852
|
+
==================================================================
|
|
1853
|
+
Devolve UNICAMENTE bloques separados por marcadores ===. Sin texto extra fuera de los bloques.
|
|
1854
|
+
TODAS las rutas son RELATIVAS al directorio del proyecto.
|
|
2005
1855
|
|
|
2006
1856
|
=== .agent/context/architecture.md ===
|
|
2007
|
-
[
|
|
1857
|
+
[NIVEL 0]
|
|
1858
|
+
|
|
1859
|
+
=== .agent/context/<componente-A>/architecture.md ===
|
|
1860
|
+
[NIVEL 1 del componente A]
|
|
1861
|
+
|
|
1862
|
+
=== .agent/context/<componente-B>/architecture.md ===
|
|
1863
|
+
[NIVEL 1 del componente B]
|
|
2008
1864
|
|
|
2009
|
-
|
|
2010
|
-
[contenido NIVEL 1]
|
|
1865
|
+
(... un bloque NIVEL 1 por cada componente identificado en paso 1)
|
|
2011
1866
|
|
|
2012
|
-
=== .agent/context
|
|
2013
|
-
[
|
|
1867
|
+
=== .agent/context/<componente-A>/modules/<feature>.md ===
|
|
1868
|
+
[NIVEL 2 — opcional]
|
|
2014
1869
|
|
|
2015
|
-
REGLAS
|
|
2016
|
-
-
|
|
2017
|
-
-
|
|
2018
|
-
-
|
|
2019
|
-
-
|
|
2020
|
-
-
|
|
2021
|
-
- Si existe documentacion previa, ACTUALIZALA preservando lo que sigue siendo valido y agregando lo nuevo`;
|
|
1870
|
+
REGLAS FINALES:
|
|
1871
|
+
- Un archivo NIVEL 1 por cada carpeta-componente que EXISTE HOY en el filesystem (no saltes ninguna, incluye frontends).
|
|
1872
|
+
- NO regeneres NIVEL 1 de componentes archivados (carpetas que ya no existen): no los incluyas en tu output. La doc previa de esos componentes queda intacta en disco.
|
|
1873
|
+
- NIVEL 0: update incremental. Si la doc previa lista componentes archivados, conservalos marcados como tal — no los borres.
|
|
1874
|
+
- NO escribir bajo .agent/docs/.
|
|
1875
|
+
- Los nombres de carpeta en los marcadores DEBEN coincidir con los nombres reales del proyecto (los activos).`;
|
|
2022
1876
|
const res = await this.runWithFallback('explorer', prompt, 'Exploracion');
|
|
2023
1877
|
const text = extractCliText(res);
|
|
2024
1878
|
// Always overwrite the single last-run report so we have a debug trail
|
package/dist/ui/theme.d.ts
CHANGED
package/dist/ui/theme.js
CHANGED
|
@@ -90,7 +90,7 @@ export function renderWelcomePanel(opts) {
|
|
|
90
90
|
"",
|
|
91
91
|
];
|
|
92
92
|
if (opts.roles &&
|
|
93
|
-
(opts.roles.orchestrator || opts.roles.implementor || opts.roles.reviewer)) {
|
|
93
|
+
(opts.roles.orchestrator || opts.roles.implementor || opts.roles.reviewer || opts.roles.explorer)) {
|
|
94
94
|
right.push(` ${accent("Current roles")}`);
|
|
95
95
|
right.push(` ${rSep}`);
|
|
96
96
|
if (opts.roles.orchestrator) {
|
|
@@ -102,6 +102,9 @@ export function renderWelcomePanel(opts) {
|
|
|
102
102
|
if (opts.roles.reviewer) {
|
|
103
103
|
right.push(` ${chalk.dim("Rev ")}${chalk.rgb(0, 185, 180)(opts.roles.reviewer)}`);
|
|
104
104
|
}
|
|
105
|
+
if (opts.roles.explorer) {
|
|
106
|
+
right.push(` ${chalk.dim("Expl ")}${chalk.rgb(0, 185, 180)(opts.roles.explorer)}`);
|
|
107
|
+
}
|
|
105
108
|
right.push("");
|
|
106
109
|
}
|
|
107
110
|
else {
|